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 // 4-bit immediate used by some XOP instructions
678 def ImmUnsignedi4AsmOperand : AsmOperandClass {
679 let Name = "ImmUnsignedi4";
680 let RenderMethod = "addImmOperands";
681 let DiagnosticType = "InvalidImmUnsignedi4";
684 // Unsigned immediate used by SSE/AVX instructions
686 // [0xFFFFFFFFFFFFFF80, 0xFFFFFFFFFFFFFFFF]
687 def ImmUnsignedi8AsmOperand : AsmOperandClass {
688 let Name = "ImmUnsignedi8";
689 let RenderMethod = "addImmOperands";
692 // A couple of more descriptive operand definitions.
693 // 16-bits but only 8 bits are significant.
694 def i16i8imm : Operand<i16> {
695 let ParserMatchClass = ImmSExti16i8AsmOperand;
696 let OperandType = "OPERAND_IMMEDIATE";
698 // 32-bits but only 8 bits are significant.
699 def i32i8imm : Operand<i32> {
700 let ParserMatchClass = ImmSExti32i8AsmOperand;
701 let OperandType = "OPERAND_IMMEDIATE";
704 // 64-bits but only 32 bits are significant.
705 def i64i32imm : Operand<i64> {
706 let ParserMatchClass = ImmSExti64i32AsmOperand;
707 let OperandType = "OPERAND_IMMEDIATE";
710 // 64-bits but only 8 bits are significant.
711 def i64i8imm : Operand<i64> {
712 let ParserMatchClass = ImmSExti64i8AsmOperand;
713 let OperandType = "OPERAND_IMMEDIATE";
716 // Unsigned 4-bit immediate used by some XOP instructions.
717 def u4imm : Operand<i8> {
718 let PrintMethod = "printU8Imm";
719 let ParserMatchClass = ImmUnsignedi4AsmOperand;
720 let OperandType = "OPERAND_IMMEDIATE";
723 // Unsigned 8-bit immediate used by SSE/AVX instructions.
724 def u8imm : Operand<i8> {
725 let PrintMethod = "printU8Imm";
726 let ParserMatchClass = ImmUnsignedi8AsmOperand;
727 let OperandType = "OPERAND_IMMEDIATE";
730 // 16-bit immediate but only 8-bits are significant and they are unsigned.
731 // Used by BT instructions.
732 def i16u8imm : Operand<i16> {
733 let PrintMethod = "printU8Imm";
734 let ParserMatchClass = ImmUnsignedi8AsmOperand;
735 let OperandType = "OPERAND_IMMEDIATE";
738 // 32-bit immediate but only 8-bits are significant and they are unsigned.
739 // Used by some SSE/AVX instructions that use intrinsics.
740 def i32u8imm : Operand<i32> {
741 let PrintMethod = "printU8Imm";
742 let ParserMatchClass = ImmUnsignedi8AsmOperand;
743 let OperandType = "OPERAND_IMMEDIATE";
746 // 64-bit immediate but only 8-bits are significant and they are unsigned.
747 // Used by BT instructions.
748 def i64u8imm : Operand<i64> {
749 let PrintMethod = "printU8Imm";
750 let ParserMatchClass = ImmUnsignedi8AsmOperand;
751 let OperandType = "OPERAND_IMMEDIATE";
754 // 64-bits but only 32 bits are significant, and those bits are treated as being
756 def i64i32imm_pcrel : Operand<i64> {
757 let PrintMethod = "printPCRelImm";
758 let ParserMatchClass = X86AbsMemAsmOperand;
759 let OperandType = "OPERAND_PCREL";
762 def lea64_32mem : Operand<i32> {
763 let PrintMethod = "printanymem";
764 let MIOperandInfo = (ops GR64, i8imm, GR64_NOSP, i32imm, SEGMENT_REG);
765 let ParserMatchClass = X86MemAsmOperand;
768 // Memory operands that use 64-bit pointers in both ILP32 and LP64.
769 def lea64mem : Operand<i64> {
770 let PrintMethod = "printanymem";
771 let MIOperandInfo = (ops GR64, i8imm, GR64_NOSP, i32imm, SEGMENT_REG);
772 let ParserMatchClass = X86MemAsmOperand;
775 let RenderMethod = "addMaskPairOperands" in {
776 def VK1PairAsmOperand : AsmOperandClass { let Name = "VK1Pair"; }
777 def VK2PairAsmOperand : AsmOperandClass { let Name = "VK2Pair"; }
778 def VK4PairAsmOperand : AsmOperandClass { let Name = "VK4Pair"; }
779 def VK8PairAsmOperand : AsmOperandClass { let Name = "VK8Pair"; }
780 def VK16PairAsmOperand : AsmOperandClass { let Name = "VK16Pair"; }
783 def VK1Pair : RegisterOperand<VK1PAIR, "printVKPair"> {
784 let ParserMatchClass = VK1PairAsmOperand;
787 def VK2Pair : RegisterOperand<VK2PAIR, "printVKPair"> {
788 let ParserMatchClass = VK2PairAsmOperand;
791 def VK4Pair : RegisterOperand<VK4PAIR, "printVKPair"> {
792 let ParserMatchClass = VK4PairAsmOperand;
795 def VK8Pair : RegisterOperand<VK8PAIR, "printVKPair"> {
796 let ParserMatchClass = VK8PairAsmOperand;
799 def VK16Pair : RegisterOperand<VK16PAIR, "printVKPair"> {
800 let ParserMatchClass = VK16PairAsmOperand;
803 //===----------------------------------------------------------------------===//
804 // X86 Complex Pattern Definitions.
807 // Define X86-specific addressing mode.
808 def addr : ComplexPattern<iPTR, 5, "selectAddr", [], [SDNPWantParent]>;
809 def lea32addr : ComplexPattern<i32, 5, "selectLEAAddr",
810 [add, sub, mul, X86mul_imm, shl, or, frameindex],
812 // In 64-bit mode 32-bit LEAs can use RIP-relative addressing.
813 def lea64_32addr : ComplexPattern<i32, 5, "selectLEA64_32Addr",
814 [add, sub, mul, X86mul_imm, shl, or,
815 frameindex, X86WrapperRIP],
818 def tls32addr : ComplexPattern<i32, 5, "selectTLSADDRAddr",
819 [tglobaltlsaddr], []>;
821 def tls32baseaddr : ComplexPattern<i32, 5, "selectTLSADDRAddr",
822 [tglobaltlsaddr], []>;
824 def lea64addr : ComplexPattern<i64, 5, "selectLEAAddr",
825 [add, sub, mul, X86mul_imm, shl, or, frameindex,
828 def tls64addr : ComplexPattern<i64, 5, "selectTLSADDRAddr",
829 [tglobaltlsaddr], []>;
831 def tls64baseaddr : ComplexPattern<i64, 5, "selectTLSADDRAddr",
832 [tglobaltlsaddr], []>;
834 def vectoraddr : ComplexPattern<iPTR, 5, "selectVectorAddr", [],[SDNPWantParent]>;
836 // A relocatable immediate is either an immediate operand or an operand that can
837 // be relocated by the linker to an immediate, such as a regular symbol in
839 def relocImm : ComplexPattern<iAny, 1, "selectRelocImm", [imm, X86Wrapper], [],
842 //===----------------------------------------------------------------------===//
843 // X86 Instruction Predicate Definitions.
844 def TruePredicate : Predicate<"true">;
846 def HasCMov : Predicate<"Subtarget->hasCMov()">;
847 def NoCMov : Predicate<"!Subtarget->hasCMov()">;
849 def HasMMX : Predicate<"Subtarget->hasMMX()">;
850 def Has3DNow : Predicate<"Subtarget->has3DNow()">;
851 def Has3DNowA : Predicate<"Subtarget->has3DNowA()">;
852 def HasSSE1 : Predicate<"Subtarget->hasSSE1()">;
853 def UseSSE1 : Predicate<"Subtarget->hasSSE1() && !Subtarget->hasAVX()">;
854 def HasSSE2 : Predicate<"Subtarget->hasSSE2()">;
855 def UseSSE2 : Predicate<"Subtarget->hasSSE2() && !Subtarget->hasAVX()">;
856 def HasSSE3 : Predicate<"Subtarget->hasSSE3()">;
857 def UseSSE3 : Predicate<"Subtarget->hasSSE3() && !Subtarget->hasAVX()">;
858 def HasSSSE3 : Predicate<"Subtarget->hasSSSE3()">;
859 def UseSSSE3 : Predicate<"Subtarget->hasSSSE3() && !Subtarget->hasAVX()">;
860 def HasSSE41 : Predicate<"Subtarget->hasSSE41()">;
861 def NoSSE41 : Predicate<"!Subtarget->hasSSE41()">;
862 def UseSSE41 : Predicate<"Subtarget->hasSSE41() && !Subtarget->hasAVX()">;
863 def HasSSE42 : Predicate<"Subtarget->hasSSE42()">;
864 def UseSSE42 : Predicate<"Subtarget->hasSSE42() && !Subtarget->hasAVX()">;
865 def HasSSE4A : Predicate<"Subtarget->hasSSE4A()">;
866 def NoAVX : Predicate<"!Subtarget->hasAVX()">;
867 def HasAVX : Predicate<"Subtarget->hasAVX()">;
868 def HasAVX2 : Predicate<"Subtarget->hasAVX2()">;
869 def HasAVX1Only : Predicate<"Subtarget->hasAVX() && !Subtarget->hasAVX2()">;
870 def HasAVX512 : Predicate<"Subtarget->hasAVX512()">;
871 def UseAVX : Predicate<"Subtarget->hasAVX() && !Subtarget->hasAVX512()">;
872 def UseAVX2 : Predicate<"Subtarget->hasAVX2() && !Subtarget->hasAVX512()">;
873 def NoAVX512 : Predicate<"!Subtarget->hasAVX512()">;
874 def HasCDI : Predicate<"Subtarget->hasCDI()">;
875 def HasVPOPCNTDQ : Predicate<"Subtarget->hasVPOPCNTDQ()">;
876 def HasPFI : Predicate<"Subtarget->hasPFI()">;
877 def HasERI : Predicate<"Subtarget->hasERI()">;
878 def HasDQI : Predicate<"Subtarget->hasDQI()">;
879 def NoDQI : Predicate<"!Subtarget->hasDQI()">;
880 def HasBWI : Predicate<"Subtarget->hasBWI()">;
881 def NoBWI : Predicate<"!Subtarget->hasBWI()">;
882 def HasVLX : Predicate<"Subtarget->hasVLX()">;
883 def NoVLX : Predicate<"!Subtarget->hasVLX()">;
884 def NoVLX_Or_NoBWI : Predicate<"!Subtarget->hasVLX() || !Subtarget->hasBWI()">;
885 def NoVLX_Or_NoDQI : Predicate<"!Subtarget->hasVLX() || !Subtarget->hasDQI()">;
886 def PKU : Predicate<"Subtarget->hasPKU()">;
887 def HasVNNI : Predicate<"Subtarget->hasVNNI()">;
888 def HasVP2INTERSECT : Predicate<"Subtarget->hasVP2INTERSECT()">;
889 def HasBF16 : Predicate<"Subtarget->hasBF16()">;
891 def HasBITALG : Predicate<"Subtarget->hasBITALG()">;
892 def HasPOPCNT : Predicate<"Subtarget->hasPOPCNT()">;
893 def HasAES : Predicate<"Subtarget->hasAES()">;
894 def HasVAES : Predicate<"Subtarget->hasVAES()">;
895 def NoVLX_Or_NoVAES : Predicate<"!Subtarget->hasVLX() || !Subtarget->hasVAES()">;
896 def HasFXSR : Predicate<"Subtarget->hasFXSR()">;
897 def HasXSAVE : Predicate<"Subtarget->hasXSAVE()">;
898 def HasXSAVEOPT : Predicate<"Subtarget->hasXSAVEOPT()">;
899 def HasXSAVEC : Predicate<"Subtarget->hasXSAVEC()">;
900 def HasXSAVES : Predicate<"Subtarget->hasXSAVES()">;
901 def HasPCLMUL : Predicate<"Subtarget->hasPCLMUL()">;
902 def NoVLX_Or_NoVPCLMULQDQ :
903 Predicate<"!Subtarget->hasVLX() || !Subtarget->hasVPCLMULQDQ()">;
904 def HasVPCLMULQDQ : Predicate<"Subtarget->hasVPCLMULQDQ()">;
905 def HasGFNI : Predicate<"Subtarget->hasGFNI()">;
906 def HasFMA : Predicate<"Subtarget->hasFMA()">;
907 def HasFMA4 : Predicate<"Subtarget->hasFMA4()">;
908 def NoFMA4 : Predicate<"!Subtarget->hasFMA4()">;
909 def HasXOP : Predicate<"Subtarget->hasXOP()">;
910 def HasTBM : Predicate<"Subtarget->hasTBM()">;
911 def NoTBM : Predicate<"!Subtarget->hasTBM()">;
912 def HasLWP : Predicate<"Subtarget->hasLWP()">;
913 def HasMOVBE : Predicate<"Subtarget->hasMOVBE()">;
914 def HasRDRAND : Predicate<"Subtarget->hasRDRAND()">;
915 def HasF16C : Predicate<"Subtarget->hasF16C()">;
916 def HasFSGSBase : Predicate<"Subtarget->hasFSGSBase()">;
917 def HasLZCNT : Predicate<"Subtarget->hasLZCNT()">;
918 def HasBMI : Predicate<"Subtarget->hasBMI()">;
919 def HasBMI2 : Predicate<"Subtarget->hasBMI2()">;
920 def NoBMI2 : Predicate<"!Subtarget->hasBMI2()">;
921 def HasVBMI : Predicate<"Subtarget->hasVBMI()">;
922 def HasVBMI2 : Predicate<"Subtarget->hasVBMI2()">;
923 def HasIFMA : Predicate<"Subtarget->hasIFMA()">;
924 def HasRTM : Predicate<"Subtarget->hasRTM()">;
925 def HasADX : Predicate<"Subtarget->hasADX()">;
926 def HasSHA : Predicate<"Subtarget->hasSHA()">;
927 def HasSGX : Predicate<"Subtarget->hasSGX()">;
928 def HasPRFCHW : Predicate<"Subtarget->hasPRFCHW()">;
929 def HasRDSEED : Predicate<"Subtarget->hasRDSEED()">;
930 def HasSSEPrefetch : Predicate<"Subtarget->hasSSEPrefetch()">;
931 def NoSSEPrefetch : Predicate<"!Subtarget->hasSSEPrefetch()">;
932 def HasPrefetchW : Predicate<"Subtarget->hasPRFCHW()">;
933 def HasPREFETCHWT1 : Predicate<"Subtarget->hasPREFETCHWT1()">;
934 def HasLAHFSAHF : Predicate<"Subtarget->hasLAHFSAHF()">;
935 def HasMWAITX : Predicate<"Subtarget->hasMWAITX()">;
936 def HasCLZERO : Predicate<"Subtarget->hasCLZERO()">;
937 def HasCLDEMOTE : Predicate<"Subtarget->hasCLDEMOTE()">;
938 def HasMOVDIRI : Predicate<"Subtarget->hasMOVDIRI()">;
939 def HasMOVDIR64B : Predicate<"Subtarget->hasMOVDIR64B()">;
940 def HasPTWRITE : Predicate<"Subtarget->hasPTWRITE()">;
941 def FPStackf32 : Predicate<"!Subtarget->hasSSE1()">;
942 def FPStackf64 : Predicate<"!Subtarget->hasSSE2()">;
943 def HasSHSTK : Predicate<"Subtarget->hasSHSTK()">;
944 def HasCLFLUSHOPT : Predicate<"Subtarget->hasCLFLUSHOPT()">;
945 def HasCLWB : Predicate<"Subtarget->hasCLWB()">;
946 def HasWBNOINVD : Predicate<"Subtarget->hasWBNOINVD()">;
947 def HasRDPID : Predicate<"Subtarget->hasRDPID()">;
948 def HasWAITPKG : Predicate<"Subtarget->hasWAITPKG()">;
949 def HasINVPCID : Predicate<"Subtarget->hasINVPCID()">;
950 def HasCmpxchg8b : Predicate<"Subtarget->hasCmpxchg8b()">;
951 def HasCmpxchg16b: Predicate<"Subtarget->hasCmpxchg16b()">;
952 def HasPCONFIG : Predicate<"Subtarget->hasPCONFIG()">;
953 def HasENQCMD : Predicate<"Subtarget->hasENQCMD()">;
954 def Not64BitMode : Predicate<"!Subtarget->is64Bit()">,
955 AssemblerPredicate<"!Mode64Bit", "Not 64-bit mode">;
956 def In64BitMode : Predicate<"Subtarget->is64Bit()">,
957 AssemblerPredicate<"Mode64Bit", "64-bit mode">;
958 def IsLP64 : Predicate<"Subtarget->isTarget64BitLP64()">;
959 def NotLP64 : Predicate<"!Subtarget->isTarget64BitLP64()">;
960 def In16BitMode : Predicate<"Subtarget->is16Bit()">,
961 AssemblerPredicate<"Mode16Bit", "16-bit mode">;
962 def Not16BitMode : Predicate<"!Subtarget->is16Bit()">,
963 AssemblerPredicate<"!Mode16Bit", "Not 16-bit mode">;
964 def In32BitMode : Predicate<"Subtarget->is32Bit()">,
965 AssemblerPredicate<"Mode32Bit", "32-bit mode">;
966 def IsWin64 : Predicate<"Subtarget->isTargetWin64()">;
967 def NotWin64 : Predicate<"!Subtarget->isTargetWin64()">;
968 def NotWin64WithoutFP : Predicate<"!Subtarget->isTargetWin64() ||"
969 "Subtarget->getFrameLowering()->hasFP(*MF)"> {
970 let RecomputePerFunction = 1;
972 def IsPS4 : Predicate<"Subtarget->isTargetPS4()">;
973 def NotPS4 : Predicate<"!Subtarget->isTargetPS4()">;
974 def IsNaCl : Predicate<"Subtarget->isTargetNaCl()">;
975 def NotNaCl : Predicate<"!Subtarget->isTargetNaCl()">;
976 def SmallCode : Predicate<"TM.getCodeModel() == CodeModel::Small">;
977 def KernelCode : Predicate<"TM.getCodeModel() == CodeModel::Kernel">;
978 def NearData : Predicate<"TM.getCodeModel() == CodeModel::Small ||"
979 "TM.getCodeModel() == CodeModel::Kernel">;
980 def IsNotPIC : Predicate<"!TM.isPositionIndependent()">;
982 // We could compute these on a per-module basis but doing so requires accessing
983 // the Function object through the <Target>Subtarget and objections were raised
984 // to that (see post-commit review comments for r301750).
985 let RecomputePerFunction = 1 in {
986 def OptForSize : Predicate<"MF->getFunction().hasOptSize()">;
987 def OptForMinSize : Predicate<"MF->getFunction().hasMinSize()">;
988 def OptForSpeed : Predicate<"!MF->getFunction().hasOptSize()">;
989 def UseIncDec : Predicate<"!Subtarget->slowIncDec() || "
990 "MF->getFunction().hasOptSize()">;
991 def NoSSE41_Or_OptForSize : Predicate<"MF->getFunction().hasOptSize() || "
992 "!Subtarget->hasSSE41()">;
995 def CallImmAddr : Predicate<"Subtarget->isLegalToCallImmediateAddr()">;
996 def FavorMemIndirectCall : Predicate<"!Subtarget->slowTwoMemOps()">;
997 def HasFastMem32 : Predicate<"!Subtarget->isUnalignedMem32Slow()">;
998 def HasFastLZCNT : Predicate<"Subtarget->hasFastLZCNT()">;
999 def HasFastSHLDRotate : Predicate<"Subtarget->hasFastSHLDRotate()">;
1000 def HasERMSB : Predicate<"Subtarget->hasERMSB()">;
1001 def HasMFence : Predicate<"Subtarget->hasMFence()">;
1002 def UseRetpolineIndirectCalls : Predicate<"Subtarget->useRetpolineIndirectCalls()">;
1003 def NotUseRetpolineIndirectCalls : Predicate<"!Subtarget->useRetpolineIndirectCalls()">;
1005 //===----------------------------------------------------------------------===//
1006 // X86 Instruction Format Definitions.
1009 include "X86InstrFormats.td"
1011 //===----------------------------------------------------------------------===//
1012 // Pattern fragments.
1015 // X86 specific condition code. These correspond to CondCode in
1016 // X86InstrInfo.h. They must be kept in synch.
1017 def X86_COND_O : PatLeaf<(i8 0)>;
1018 def X86_COND_NO : PatLeaf<(i8 1)>;
1019 def X86_COND_B : PatLeaf<(i8 2)>; // alt. COND_C
1020 def X86_COND_AE : PatLeaf<(i8 3)>; // alt. COND_NC
1021 def X86_COND_E : PatLeaf<(i8 4)>; // alt. COND_Z
1022 def X86_COND_NE : PatLeaf<(i8 5)>; // alt. COND_NZ
1023 def X86_COND_BE : PatLeaf<(i8 6)>; // alt. COND_NA
1024 def X86_COND_A : PatLeaf<(i8 7)>; // alt. COND_NBE
1025 def X86_COND_S : PatLeaf<(i8 8)>;
1026 def X86_COND_NS : PatLeaf<(i8 9)>;
1027 def X86_COND_P : PatLeaf<(i8 10)>; // alt. COND_PE
1028 def X86_COND_NP : PatLeaf<(i8 11)>; // alt. COND_PO
1029 def X86_COND_L : PatLeaf<(i8 12)>; // alt. COND_NGE
1030 def X86_COND_GE : PatLeaf<(i8 13)>; // alt. COND_NL
1031 def X86_COND_LE : PatLeaf<(i8 14)>; // alt. COND_NG
1032 def X86_COND_G : PatLeaf<(i8 15)>; // alt. COND_NLE
1034 def i16immSExt8 : ImmLeaf<i16, [{ return isInt<8>(Imm); }]>;
1035 def i32immSExt8 : ImmLeaf<i32, [{ return isInt<8>(Imm); }]>;
1036 def i64immSExt8 : ImmLeaf<i64, [{ return isInt<8>(Imm); }]>;
1037 def i64immSExt32 : ImmLeaf<i64, [{ return isInt<32>(Imm); }]>;
1039 // FIXME: Ideally we would just replace the above i*immSExt* matchers with
1040 // relocImm-based matchers, but then FastISel would be unable to use them.
1041 def i64relocImmSExt8 : PatLeaf<(i64 relocImm), [{
1042 return isSExtRelocImm<8>(N);
1044 def i64relocImmSExt32 : PatLeaf<(i64 relocImm), [{
1045 return isSExtRelocImm<32>(N);
1048 // If we have multiple users of an immediate, it's much smaller to reuse
1049 // the register, rather than encode the immediate in every instruction.
1050 // This has the risk of increasing register pressure from stretched live
1051 // ranges, however, the immediates should be trivial to rematerialize by
1052 // the RA in the event of high register pressure.
1053 // TODO : This is currently enabled for stores and binary ops. There are more
1054 // cases for which this can be enabled, though this catches the bulk of the
1056 // TODO2 : This should really also be enabled under O2, but there's currently
1057 // an issue with RA where we don't pull the constants into their users
1058 // when we rematerialize them. I'll follow-up on enabling O2 after we fix that
1060 // TODO3 : This is currently limited to single basic blocks (DAG creation
1061 // pulls block immediates to the top and merges them if necessary).
1062 // Eventually, it would be nice to allow ConstantHoisting to merge constants
1063 // globally for potentially added savings.
1065 def relocImm8_su : PatLeaf<(i8 relocImm), [{
1066 return !shouldAvoidImmediateInstFormsForSize(N);
1068 def relocImm16_su : PatLeaf<(i16 relocImm), [{
1069 return !shouldAvoidImmediateInstFormsForSize(N);
1071 def relocImm32_su : PatLeaf<(i32 relocImm), [{
1072 return !shouldAvoidImmediateInstFormsForSize(N);
1075 def i16immSExt8_su : PatLeaf<(i16immSExt8), [{
1076 return !shouldAvoidImmediateInstFormsForSize(N);
1078 def i32immSExt8_su : PatLeaf<(i32immSExt8), [{
1079 return !shouldAvoidImmediateInstFormsForSize(N);
1081 def i64immSExt8_su : PatLeaf<(i64immSExt8), [{
1082 return !shouldAvoidImmediateInstFormsForSize(N);
1085 def i64relocImmSExt8_su : PatLeaf<(i64relocImmSExt8), [{
1086 return !shouldAvoidImmediateInstFormsForSize(N);
1088 def i64relocImmSExt32_su : PatLeaf<(i64relocImmSExt32), [{
1089 return !shouldAvoidImmediateInstFormsForSize(N);
1092 // i64immZExt32 predicate - True if the 64-bit immediate fits in a 32-bit
1094 def i64immZExt32 : ImmLeaf<i64, [{ return isUInt<32>(Imm); }]>;
1096 def i64immZExt32SExt8 : ImmLeaf<i64, [{
1097 return isUInt<32>(Imm) && isInt<8>(static_cast<int32_t>(Imm));
1100 // Helper fragments for loads.
1102 // It's safe to fold a zextload/extload from i1 as a regular i8 load. The
1103 // upper bits are guaranteed to be zero and we were going to emit a MOV8rm
1104 // which might get folded during peephole anyway.
1105 def loadi8 : PatFrag<(ops node:$ptr), (i8 (unindexedload node:$ptr)), [{
1106 LoadSDNode *LD = cast<LoadSDNode>(N);
1107 ISD::LoadExtType ExtType = LD->getExtensionType();
1108 return ExtType == ISD::NON_EXTLOAD || ExtType == ISD::EXTLOAD ||
1109 ExtType == ISD::ZEXTLOAD;
1112 // It's always safe to treat a anyext i16 load as a i32 load if the i16 is
1113 // known to be 32-bit aligned or better. Ditto for i8 to i16.
1114 def loadi16 : PatFrag<(ops node:$ptr), (i16 (unindexedload node:$ptr)), [{
1115 LoadSDNode *LD = cast<LoadSDNode>(N);
1116 ISD::LoadExtType ExtType = LD->getExtensionType();
1117 if (ExtType == ISD::NON_EXTLOAD)
1119 if (ExtType == ISD::EXTLOAD)
1120 return LD->getAlignment() >= 2 && LD->isSimple();
1124 def loadi32 : PatFrag<(ops node:$ptr), (i32 (unindexedload node:$ptr)), [{
1125 LoadSDNode *LD = cast<LoadSDNode>(N);
1126 ISD::LoadExtType ExtType = LD->getExtensionType();
1127 if (ExtType == ISD::NON_EXTLOAD)
1129 if (ExtType == ISD::EXTLOAD)
1130 return LD->getAlignment() >= 4 && LD->isSimple();
1134 def loadi64 : PatFrag<(ops node:$ptr), (i64 (load node:$ptr))>;
1135 def loadf32 : PatFrag<(ops node:$ptr), (f32 (load node:$ptr))>;
1136 def loadf64 : PatFrag<(ops node:$ptr), (f64 (load node:$ptr))>;
1137 def loadf80 : PatFrag<(ops node:$ptr), (f80 (load node:$ptr))>;
1138 def loadf128 : PatFrag<(ops node:$ptr), (f128 (load node:$ptr))>;
1139 def alignedloadf128 : PatFrag<(ops node:$ptr), (f128 (load node:$ptr)), [{
1140 LoadSDNode *Ld = cast<LoadSDNode>(N);
1141 return Ld->getAlignment() >= Ld->getMemoryVT().getStoreSize();
1143 def memopf128 : PatFrag<(ops node:$ptr), (f128 (load node:$ptr)), [{
1144 LoadSDNode *Ld = cast<LoadSDNode>(N);
1145 return Subtarget->hasSSEUnalignedMem() ||
1146 Ld->getAlignment() >= Ld->getMemoryVT().getStoreSize();
1149 def sextloadi16i8 : PatFrag<(ops node:$ptr), (i16 (sextloadi8 node:$ptr))>;
1150 def sextloadi32i8 : PatFrag<(ops node:$ptr), (i32 (sextloadi8 node:$ptr))>;
1151 def sextloadi32i16 : PatFrag<(ops node:$ptr), (i32 (sextloadi16 node:$ptr))>;
1152 def sextloadi64i8 : PatFrag<(ops node:$ptr), (i64 (sextloadi8 node:$ptr))>;
1153 def sextloadi64i16 : PatFrag<(ops node:$ptr), (i64 (sextloadi16 node:$ptr))>;
1154 def sextloadi64i32 : PatFrag<(ops node:$ptr), (i64 (sextloadi32 node:$ptr))>;
1156 def zextloadi8i1 : PatFrag<(ops node:$ptr), (i8 (zextloadi1 node:$ptr))>;
1157 def zextloadi16i1 : PatFrag<(ops node:$ptr), (i16 (zextloadi1 node:$ptr))>;
1158 def zextloadi32i1 : PatFrag<(ops node:$ptr), (i32 (zextloadi1 node:$ptr))>;
1159 def zextloadi16i8 : PatFrag<(ops node:$ptr), (i16 (zextloadi8 node:$ptr))>;
1160 def zextloadi32i8 : PatFrag<(ops node:$ptr), (i32 (zextloadi8 node:$ptr))>;
1161 def zextloadi32i16 : PatFrag<(ops node:$ptr), (i32 (zextloadi16 node:$ptr))>;
1162 def zextloadi64i1 : PatFrag<(ops node:$ptr), (i64 (zextloadi1 node:$ptr))>;
1163 def zextloadi64i8 : PatFrag<(ops node:$ptr), (i64 (zextloadi8 node:$ptr))>;
1164 def zextloadi64i16 : PatFrag<(ops node:$ptr), (i64 (zextloadi16 node:$ptr))>;
1165 def zextloadi64i32 : PatFrag<(ops node:$ptr), (i64 (zextloadi32 node:$ptr))>;
1167 def extloadi8i1 : PatFrag<(ops node:$ptr), (i8 (extloadi1 node:$ptr))>;
1168 def extloadi16i1 : PatFrag<(ops node:$ptr), (i16 (extloadi1 node:$ptr))>;
1169 def extloadi32i1 : PatFrag<(ops node:$ptr), (i32 (extloadi1 node:$ptr))>;
1170 def extloadi16i8 : PatFrag<(ops node:$ptr), (i16 (extloadi8 node:$ptr))>;
1171 def extloadi32i8 : PatFrag<(ops node:$ptr), (i32 (extloadi8 node:$ptr))>;
1172 def extloadi32i16 : PatFrag<(ops node:$ptr), (i32 (extloadi16 node:$ptr))>;
1173 def extloadi64i1 : PatFrag<(ops node:$ptr), (i64 (extloadi1 node:$ptr))>;
1174 def extloadi64i8 : PatFrag<(ops node:$ptr), (i64 (extloadi8 node:$ptr))>;
1175 def extloadi64i16 : PatFrag<(ops node:$ptr), (i64 (extloadi16 node:$ptr))>;
1177 // We can treat an i8/i16 extending load to i64 as a 32 bit load if its known
1178 // to be 4 byte aligned or better.
1179 def extloadi64i32 : PatFrag<(ops node:$ptr), (i64 (unindexedload node:$ptr)), [{
1180 LoadSDNode *LD = cast<LoadSDNode>(N);
1181 ISD::LoadExtType ExtType = LD->getExtensionType();
1182 if (ExtType != ISD::EXTLOAD)
1184 if (LD->getMemoryVT() == MVT::i32)
1187 return LD->getAlignment() >= 4 && LD->isSimple();
1191 // An 'and' node with a single use.
1192 def and_su : PatFrag<(ops node:$lhs, node:$rhs), (and node:$lhs, node:$rhs), [{
1193 return N->hasOneUse();
1195 // An 'srl' node with a single use.
1196 def srl_su : PatFrag<(ops node:$lhs, node:$rhs), (srl node:$lhs, node:$rhs), [{
1197 return N->hasOneUse();
1199 // An 'trunc' node with a single use.
1200 def trunc_su : PatFrag<(ops node:$src), (trunc node:$src), [{
1201 return N->hasOneUse();
1204 //===----------------------------------------------------------------------===//
1205 // Instruction list.
1209 let hasSideEffects = 0, SchedRW = [WriteNop] in {
1210 def NOOP : I<0x90, RawFrm, (outs), (ins), "nop", []>;
1211 def NOOPW : I<0x1f, MRMXm, (outs), (ins i16mem:$zero),
1212 "nop{w}\t$zero", []>, TB, OpSize16, NotMemoryFoldable;
1213 def NOOPL : I<0x1f, MRMXm, (outs), (ins i32mem:$zero),
1214 "nop{l}\t$zero", []>, TB, OpSize32, NotMemoryFoldable;
1215 def NOOPQ : RI<0x1f, MRMXm, (outs), (ins i64mem:$zero),
1216 "nop{q}\t$zero", []>, TB, NotMemoryFoldable,
1217 Requires<[In64BitMode]>;
1218 // Also allow register so we can assemble/disassemble
1219 def NOOPWr : I<0x1f, MRMXr, (outs), (ins GR16:$zero),
1220 "nop{w}\t$zero", []>, TB, OpSize16, NotMemoryFoldable;
1221 def NOOPLr : I<0x1f, MRMXr, (outs), (ins GR32:$zero),
1222 "nop{l}\t$zero", []>, TB, OpSize32, NotMemoryFoldable;
1223 def NOOPQr : RI<0x1f, MRMXr, (outs), (ins GR64:$zero),
1224 "nop{q}\t$zero", []>, TB, NotMemoryFoldable,
1225 Requires<[In64BitMode]>;
1229 // Constructing a stack frame.
1230 def ENTER : Ii16<0xC8, RawFrmImm8, (outs), (ins i16imm:$len, i8imm:$lvl),
1231 "enter\t$len, $lvl", []>, Sched<[WriteMicrocoded]>;
1233 let SchedRW = [WriteALU] in {
1234 let Defs = [EBP, ESP], Uses = [EBP, ESP], mayLoad = 1, hasSideEffects=0 in
1235 def LEAVE : I<0xC9, RawFrm, (outs), (ins), "leave", []>,
1236 Requires<[Not64BitMode]>;
1238 let Defs = [RBP,RSP], Uses = [RBP,RSP], mayLoad = 1, hasSideEffects = 0 in
1239 def LEAVE64 : I<0xC9, RawFrm, (outs), (ins), "leave", []>,
1240 Requires<[In64BitMode]>;
1243 //===----------------------------------------------------------------------===//
1244 // Miscellaneous Instructions.
1247 let isBarrier = 1, hasSideEffects = 1, usesCustomInserter = 1,
1248 SchedRW = [WriteSystem] in
1249 def Int_eh_sjlj_setup_dispatch
1250 : PseudoI<(outs), (ins), [(X86eh_sjlj_setup_dispatch)]>;
1252 let Defs = [ESP], Uses = [ESP], hasSideEffects=0 in {
1253 let mayLoad = 1, SchedRW = [WriteLoad] in {
1254 def POP16r : I<0x58, AddRegFrm, (outs GR16:$reg), (ins), "pop{w}\t$reg", []>,
1256 def POP32r : I<0x58, AddRegFrm, (outs GR32:$reg), (ins), "pop{l}\t$reg", []>,
1257 OpSize32, Requires<[Not64BitMode]>;
1258 // Long form for the disassembler.
1259 let isCodeGenOnly = 1, ForceDisassemble = 1 in {
1260 def POP16rmr: I<0x8F, MRM0r, (outs GR16:$reg), (ins), "pop{w}\t$reg", []>,
1261 OpSize16, NotMemoryFoldable;
1262 def POP32rmr: I<0x8F, MRM0r, (outs GR32:$reg), (ins), "pop{l}\t$reg", []>,
1263 OpSize32, Requires<[Not64BitMode]>, NotMemoryFoldable;
1264 } // isCodeGenOnly = 1, ForceDisassemble = 1
1265 } // mayLoad, SchedRW
1266 let mayStore = 1, mayLoad = 1, SchedRW = [WriteCopy] in {
1267 def POP16rmm: I<0x8F, MRM0m, (outs), (ins i16mem:$dst), "pop{w}\t$dst", []>,
1269 def POP32rmm: I<0x8F, MRM0m, (outs), (ins i32mem:$dst), "pop{l}\t$dst", []>,
1270 OpSize32, Requires<[Not64BitMode]>;
1271 } // mayStore, mayLoad, SchedRW
1273 let mayStore = 1, SchedRW = [WriteStore] in {
1274 def PUSH16r : I<0x50, AddRegFrm, (outs), (ins GR16:$reg), "push{w}\t$reg",[]>,
1276 def PUSH32r : I<0x50, AddRegFrm, (outs), (ins GR32:$reg), "push{l}\t$reg",[]>,
1277 OpSize32, Requires<[Not64BitMode]>;
1278 // Long form for the disassembler.
1279 let isCodeGenOnly = 1, ForceDisassemble = 1 in {
1280 def PUSH16rmr: I<0xFF, MRM6r, (outs), (ins GR16:$reg), "push{w}\t$reg",[]>,
1281 OpSize16, NotMemoryFoldable;
1282 def PUSH32rmr: I<0xFF, MRM6r, (outs), (ins GR32:$reg), "push{l}\t$reg",[]>,
1283 OpSize32, Requires<[Not64BitMode]>, NotMemoryFoldable;
1284 } // isCodeGenOnly = 1, ForceDisassemble = 1
1286 def PUSH16i8 : Ii8<0x6a, RawFrm, (outs), (ins i16i8imm:$imm),
1287 "push{w}\t$imm", []>, OpSize16;
1288 def PUSHi16 : Ii16<0x68, RawFrm, (outs), (ins i16imm:$imm),
1289 "push{w}\t$imm", []>, OpSize16;
1291 def PUSH32i8 : Ii8<0x6a, RawFrm, (outs), (ins i32i8imm:$imm),
1292 "push{l}\t$imm", []>, OpSize32,
1293 Requires<[Not64BitMode]>;
1294 def PUSHi32 : Ii32<0x68, RawFrm, (outs), (ins i32imm:$imm),
1295 "push{l}\t$imm", []>, OpSize32,
1296 Requires<[Not64BitMode]>;
1297 } // mayStore, SchedRW
1299 let mayLoad = 1, mayStore = 1, SchedRW = [WriteCopy] in {
1300 def PUSH16rmm: I<0xFF, MRM6m, (outs), (ins i16mem:$src), "push{w}\t$src", []>,
1302 def PUSH32rmm: I<0xFF, MRM6m, (outs), (ins i32mem:$src), "push{l}\t$src", []>,
1303 OpSize32, Requires<[Not64BitMode]>;
1304 } // mayLoad, mayStore, SchedRW
1308 let mayLoad = 1, mayStore = 1, usesCustomInserter = 1,
1309 SchedRW = [WriteRMW], Defs = [ESP] in {
1311 def RDFLAGS32 : PseudoI<(outs GR32:$dst), (ins),
1312 [(set GR32:$dst, (int_x86_flags_read_u32))]>,
1313 Requires<[Not64BitMode]>;
1316 def RDFLAGS64 : PseudoI<(outs GR64:$dst), (ins),
1317 [(set GR64:$dst, (int_x86_flags_read_u64))]>,
1318 Requires<[In64BitMode]>;
1321 let mayLoad = 1, mayStore = 1, usesCustomInserter = 1,
1322 SchedRW = [WriteRMW] in {
1323 let Defs = [ESP, EFLAGS, DF], Uses = [ESP] in
1324 def WRFLAGS32 : PseudoI<(outs), (ins GR32:$src),
1325 [(int_x86_flags_write_u32 GR32:$src)]>,
1326 Requires<[Not64BitMode]>;
1328 let Defs = [RSP, EFLAGS, DF], Uses = [RSP] in
1329 def WRFLAGS64 : PseudoI<(outs), (ins GR64:$src),
1330 [(int_x86_flags_write_u64 GR64:$src)]>,
1331 Requires<[In64BitMode]>;
1334 let Defs = [ESP, EFLAGS, DF], Uses = [ESP], mayLoad = 1, hasSideEffects=0,
1335 SchedRW = [WriteLoad] in {
1336 def POPF16 : I<0x9D, RawFrm, (outs), (ins), "popf{w}", []>, OpSize16;
1337 def POPF32 : I<0x9D, RawFrm, (outs), (ins), "popf{l|d}", []>, OpSize32,
1338 Requires<[Not64BitMode]>;
1341 let Defs = [ESP], Uses = [ESP, EFLAGS, DF], mayStore = 1, hasSideEffects=0,
1342 SchedRW = [WriteStore] in {
1343 def PUSHF16 : I<0x9C, RawFrm, (outs), (ins), "pushf{w}", []>, OpSize16;
1344 def PUSHF32 : I<0x9C, RawFrm, (outs), (ins), "pushf{l|d}", []>, OpSize32,
1345 Requires<[Not64BitMode]>;
1348 let Defs = [RSP], Uses = [RSP], hasSideEffects=0 in {
1349 let mayLoad = 1, SchedRW = [WriteLoad] in {
1350 def POP64r : I<0x58, AddRegFrm, (outs GR64:$reg), (ins), "pop{q}\t$reg", []>,
1351 OpSize32, Requires<[In64BitMode]>;
1352 // Long form for the disassembler.
1353 let isCodeGenOnly = 1, ForceDisassemble = 1 in {
1354 def POP64rmr: I<0x8F, MRM0r, (outs GR64:$reg), (ins), "pop{q}\t$reg", []>,
1355 OpSize32, Requires<[In64BitMode]>, NotMemoryFoldable;
1356 } // isCodeGenOnly = 1, ForceDisassemble = 1
1357 } // mayLoad, SchedRW
1358 let mayLoad = 1, mayStore = 1, SchedRW = [WriteCopy] in
1359 def POP64rmm: I<0x8F, MRM0m, (outs), (ins i64mem:$dst), "pop{q}\t$dst", []>,
1360 OpSize32, Requires<[In64BitMode]>;
1361 let mayStore = 1, SchedRW = [WriteStore] in {
1362 def PUSH64r : I<0x50, AddRegFrm, (outs), (ins GR64:$reg), "push{q}\t$reg", []>,
1363 OpSize32, Requires<[In64BitMode]>;
1364 // Long form for the disassembler.
1365 let isCodeGenOnly = 1, ForceDisassemble = 1 in {
1366 def PUSH64rmr: I<0xFF, MRM6r, (outs), (ins GR64:$reg), "push{q}\t$reg", []>,
1367 OpSize32, Requires<[In64BitMode]>, NotMemoryFoldable;
1368 } // isCodeGenOnly = 1, ForceDisassemble = 1
1369 } // mayStore, SchedRW
1370 let mayLoad = 1, mayStore = 1, SchedRW = [WriteCopy] in {
1371 def PUSH64rmm: I<0xFF, MRM6m, (outs), (ins i64mem:$src), "push{q}\t$src", []>,
1372 OpSize32, Requires<[In64BitMode]>;
1373 } // mayLoad, mayStore, SchedRW
1376 let Defs = [RSP], Uses = [RSP], hasSideEffects = 0, mayStore = 1,
1377 SchedRW = [WriteStore] in {
1378 def PUSH64i8 : Ii8<0x6a, RawFrm, (outs), (ins i64i8imm:$imm),
1379 "push{q}\t$imm", []>, OpSize32,
1380 Requires<[In64BitMode]>;
1381 def PUSH64i32 : Ii32S<0x68, RawFrm, (outs), (ins i64i32imm:$imm),
1382 "push{q}\t$imm", []>, OpSize32,
1383 Requires<[In64BitMode]>;
1386 let Defs = [RSP, EFLAGS, DF], Uses = [RSP], mayLoad = 1, hasSideEffects=0 in
1387 def POPF64 : I<0x9D, RawFrm, (outs), (ins), "popfq", []>,
1388 OpSize32, Requires<[In64BitMode]>, Sched<[WriteLoad]>;
1389 let Defs = [RSP], Uses = [RSP, EFLAGS, DF], mayStore = 1, hasSideEffects=0 in
1390 def PUSHF64 : I<0x9C, RawFrm, (outs), (ins), "pushfq", []>,
1391 OpSize32, Requires<[In64BitMode]>, Sched<[WriteStore]>;
1393 let Defs = [EDI, ESI, EBP, EBX, EDX, ECX, EAX, ESP], Uses = [ESP],
1394 mayLoad = 1, hasSideEffects = 0, SchedRW = [WriteLoad] in {
1395 def POPA32 : I<0x61, RawFrm, (outs), (ins), "popal", []>,
1396 OpSize32, Requires<[Not64BitMode]>;
1397 def POPA16 : I<0x61, RawFrm, (outs), (ins), "popaw", []>,
1398 OpSize16, Requires<[Not64BitMode]>;
1400 let Defs = [ESP], Uses = [EDI, ESI, EBP, EBX, EDX, ECX, EAX, ESP],
1401 mayStore = 1, hasSideEffects = 0, SchedRW = [WriteStore] in {
1402 def PUSHA32 : I<0x60, RawFrm, (outs), (ins), "pushal", []>,
1403 OpSize32, Requires<[Not64BitMode]>;
1404 def PUSHA16 : I<0x60, RawFrm, (outs), (ins), "pushaw", []>,
1405 OpSize16, Requires<[Not64BitMode]>;
1408 let Constraints = "$src = $dst", SchedRW = [WriteBSWAP32] in {
1409 // This instruction is a consequence of BSWAP32r observing operand size. The
1410 // encoding is valid, but the behavior is undefined.
1411 let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0 in
1412 def BSWAP16r_BAD : I<0xC8, AddRegFrm, (outs GR16:$dst), (ins GR16:$src),
1413 "bswap{w}\t$dst", []>, OpSize16, TB;
1414 // GR32 = bswap GR32
1415 def BSWAP32r : I<0xC8, AddRegFrm, (outs GR32:$dst), (ins GR32:$src),
1417 [(set GR32:$dst, (bswap GR32:$src))]>, OpSize32, TB;
1419 let SchedRW = [WriteBSWAP64] in
1420 def BSWAP64r : RI<0xC8, AddRegFrm, (outs GR64:$dst), (ins GR64:$src),
1422 [(set GR64:$dst, (bswap GR64:$src))]>, TB;
1423 } // Constraints = "$src = $dst", SchedRW
1425 // Bit scan instructions.
1426 let Defs = [EFLAGS] in {
1427 def BSF16rr : I<0xBC, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
1428 "bsf{w}\t{$src, $dst|$dst, $src}",
1429 [(set GR16:$dst, EFLAGS, (X86bsf GR16:$src))]>,
1430 PS, OpSize16, Sched<[WriteBSF]>;
1431 def BSF16rm : I<0xBC, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
1432 "bsf{w}\t{$src, $dst|$dst, $src}",
1433 [(set GR16:$dst, EFLAGS, (X86bsf (loadi16 addr:$src)))]>,
1434 PS, OpSize16, Sched<[WriteBSFLd]>;
1435 def BSF32rr : I<0xBC, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
1436 "bsf{l}\t{$src, $dst|$dst, $src}",
1437 [(set GR32:$dst, EFLAGS, (X86bsf GR32:$src))]>,
1438 PS, OpSize32, Sched<[WriteBSF]>;
1439 def BSF32rm : I<0xBC, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
1440 "bsf{l}\t{$src, $dst|$dst, $src}",
1441 [(set GR32:$dst, EFLAGS, (X86bsf (loadi32 addr:$src)))]>,
1442 PS, OpSize32, Sched<[WriteBSFLd]>;
1443 def BSF64rr : RI<0xBC, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
1444 "bsf{q}\t{$src, $dst|$dst, $src}",
1445 [(set GR64:$dst, EFLAGS, (X86bsf GR64:$src))]>,
1446 PS, Sched<[WriteBSF]>;
1447 def BSF64rm : RI<0xBC, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
1448 "bsf{q}\t{$src, $dst|$dst, $src}",
1449 [(set GR64:$dst, EFLAGS, (X86bsf (loadi64 addr:$src)))]>,
1450 PS, Sched<[WriteBSFLd]>;
1452 def BSR16rr : I<0xBD, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
1453 "bsr{w}\t{$src, $dst|$dst, $src}",
1454 [(set GR16:$dst, EFLAGS, (X86bsr GR16:$src))]>,
1455 PS, OpSize16, Sched<[WriteBSR]>;
1456 def BSR16rm : I<0xBD, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
1457 "bsr{w}\t{$src, $dst|$dst, $src}",
1458 [(set GR16:$dst, EFLAGS, (X86bsr (loadi16 addr:$src)))]>,
1459 PS, OpSize16, Sched<[WriteBSRLd]>;
1460 def BSR32rr : I<0xBD, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
1461 "bsr{l}\t{$src, $dst|$dst, $src}",
1462 [(set GR32:$dst, EFLAGS, (X86bsr GR32:$src))]>,
1463 PS, OpSize32, Sched<[WriteBSR]>;
1464 def BSR32rm : I<0xBD, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
1465 "bsr{l}\t{$src, $dst|$dst, $src}",
1466 [(set GR32:$dst, EFLAGS, (X86bsr (loadi32 addr:$src)))]>,
1467 PS, OpSize32, Sched<[WriteBSRLd]>;
1468 def BSR64rr : RI<0xBD, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
1469 "bsr{q}\t{$src, $dst|$dst, $src}",
1470 [(set GR64:$dst, EFLAGS, (X86bsr GR64:$src))]>,
1471 PS, Sched<[WriteBSR]>;
1472 def BSR64rm : RI<0xBD, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
1473 "bsr{q}\t{$src, $dst|$dst, $src}",
1474 [(set GR64:$dst, EFLAGS, (X86bsr (loadi64 addr:$src)))]>,
1475 PS, Sched<[WriteBSRLd]>;
1476 } // Defs = [EFLAGS]
1478 let SchedRW = [WriteMicrocoded] in {
1479 let Defs = [EDI,ESI], Uses = [EDI,ESI,DF] in {
1480 def MOVSB : I<0xA4, RawFrmDstSrc, (outs), (ins dstidx8:$dst, srcidx8:$src),
1481 "movsb\t{$src, $dst|$dst, $src}", []>;
1482 def MOVSW : I<0xA5, RawFrmDstSrc, (outs), (ins dstidx16:$dst, srcidx16:$src),
1483 "movsw\t{$src, $dst|$dst, $src}", []>, OpSize16;
1484 def MOVSL : I<0xA5, RawFrmDstSrc, (outs), (ins dstidx32:$dst, srcidx32:$src),
1485 "movs{l|d}\t{$src, $dst|$dst, $src}", []>, OpSize32;
1486 def MOVSQ : RI<0xA5, RawFrmDstSrc, (outs), (ins dstidx64:$dst, srcidx64:$src),
1487 "movsq\t{$src, $dst|$dst, $src}", []>,
1488 Requires<[In64BitMode]>;
1491 let Defs = [EDI], Uses = [AL,EDI,DF] in
1492 def STOSB : I<0xAA, RawFrmDst, (outs), (ins dstidx8:$dst),
1493 "stosb\t{%al, $dst|$dst, al}", []>;
1494 let Defs = [EDI], Uses = [AX,EDI,DF] in
1495 def STOSW : I<0xAB, RawFrmDst, (outs), (ins dstidx16:$dst),
1496 "stosw\t{%ax, $dst|$dst, ax}", []>, OpSize16;
1497 let Defs = [EDI], Uses = [EAX,EDI,DF] in
1498 def STOSL : I<0xAB, RawFrmDst, (outs), (ins dstidx32:$dst),
1499 "stos{l|d}\t{%eax, $dst|$dst, eax}", []>, OpSize32;
1500 let Defs = [RDI], Uses = [RAX,RDI,DF] in
1501 def STOSQ : RI<0xAB, RawFrmDst, (outs), (ins dstidx64:$dst),
1502 "stosq\t{%rax, $dst|$dst, rax}", []>,
1503 Requires<[In64BitMode]>;
1505 let Defs = [EDI,EFLAGS], Uses = [AL,EDI,DF] in
1506 def SCASB : I<0xAE, RawFrmDst, (outs), (ins dstidx8:$dst),
1507 "scasb\t{$dst, %al|al, $dst}", []>;
1508 let Defs = [EDI,EFLAGS], Uses = [AX,EDI,DF] in
1509 def SCASW : I<0xAF, RawFrmDst, (outs), (ins dstidx16:$dst),
1510 "scasw\t{$dst, %ax|ax, $dst}", []>, OpSize16;
1511 let Defs = [EDI,EFLAGS], Uses = [EAX,EDI,DF] in
1512 def SCASL : I<0xAF, RawFrmDst, (outs), (ins dstidx32:$dst),
1513 "scas{l|d}\t{$dst, %eax|eax, $dst}", []>, OpSize32;
1514 let Defs = [EDI,EFLAGS], Uses = [RAX,EDI,DF] in
1515 def SCASQ : RI<0xAF, RawFrmDst, (outs), (ins dstidx64:$dst),
1516 "scasq\t{$dst, %rax|rax, $dst}", []>,
1517 Requires<[In64BitMode]>;
1519 let Defs = [EDI,ESI,EFLAGS], Uses = [EDI,ESI,DF] in {
1520 def CMPSB : I<0xA6, RawFrmDstSrc, (outs), (ins dstidx8:$dst, srcidx8:$src),
1521 "cmpsb\t{$dst, $src|$src, $dst}", []>;
1522 def CMPSW : I<0xA7, RawFrmDstSrc, (outs), (ins dstidx16:$dst, srcidx16:$src),
1523 "cmpsw\t{$dst, $src|$src, $dst}", []>, OpSize16;
1524 def CMPSL : I<0xA7, RawFrmDstSrc, (outs), (ins dstidx32:$dst, srcidx32:$src),
1525 "cmps{l|d}\t{$dst, $src|$src, $dst}", []>, OpSize32;
1526 def CMPSQ : RI<0xA7, RawFrmDstSrc, (outs), (ins dstidx64:$dst, srcidx64:$src),
1527 "cmpsq\t{$dst, $src|$src, $dst}", []>,
1528 Requires<[In64BitMode]>;
1532 //===----------------------------------------------------------------------===//
1533 // Move Instructions.
1535 let SchedRW = [WriteMove] in {
1536 let hasSideEffects = 0, isMoveReg = 1 in {
1537 def MOV8rr : I<0x88, MRMDestReg, (outs GR8 :$dst), (ins GR8 :$src),
1538 "mov{b}\t{$src, $dst|$dst, $src}", []>;
1539 def MOV16rr : I<0x89, MRMDestReg, (outs GR16:$dst), (ins GR16:$src),
1540 "mov{w}\t{$src, $dst|$dst, $src}", []>, OpSize16;
1541 def MOV32rr : I<0x89, MRMDestReg, (outs GR32:$dst), (ins GR32:$src),
1542 "mov{l}\t{$src, $dst|$dst, $src}", []>, OpSize32;
1543 def MOV64rr : RI<0x89, MRMDestReg, (outs GR64:$dst), (ins GR64:$src),
1544 "mov{q}\t{$src, $dst|$dst, $src}", []>;
1547 let isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in {
1548 def MOV8ri : Ii8 <0xB0, AddRegFrm, (outs GR8 :$dst), (ins i8imm :$src),
1549 "mov{b}\t{$src, $dst|$dst, $src}",
1550 [(set GR8:$dst, imm:$src)]>;
1551 def MOV16ri : Ii16<0xB8, AddRegFrm, (outs GR16:$dst), (ins i16imm:$src),
1552 "mov{w}\t{$src, $dst|$dst, $src}",
1553 [(set GR16:$dst, imm:$src)]>, OpSize16;
1554 def MOV32ri : Ii32<0xB8, AddRegFrm, (outs GR32:$dst), (ins i32imm:$src),
1555 "mov{l}\t{$src, $dst|$dst, $src}",
1556 [(set GR32:$dst, relocImm:$src)]>, OpSize32;
1557 def MOV64ri32 : RIi32S<0xC7, MRM0r, (outs GR64:$dst), (ins i64i32imm:$src),
1558 "mov{q}\t{$src, $dst|$dst, $src}",
1559 [(set GR64:$dst, i64immSExt32:$src)]>;
1561 let isReMaterializable = 1, isMoveImm = 1 in {
1562 def MOV64ri : RIi64<0xB8, AddRegFrm, (outs GR64:$dst), (ins i64imm:$src),
1563 "movabs{q}\t{$src, $dst|$dst, $src}",
1564 [(set GR64:$dst, relocImm:$src)]>;
1567 // Longer forms that use a ModR/M byte. Needed for disassembler
1568 let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0 in {
1569 def MOV8ri_alt : Ii8 <0xC6, MRM0r, (outs GR8 :$dst), (ins i8imm :$src),
1570 "mov{b}\t{$src, $dst|$dst, $src}", []>,
1571 FoldGenData<"MOV8ri">;
1572 def MOV16ri_alt : Ii16<0xC7, MRM0r, (outs GR16:$dst), (ins i16imm:$src),
1573 "mov{w}\t{$src, $dst|$dst, $src}", []>, OpSize16,
1574 FoldGenData<"MOV16ri">;
1575 def MOV32ri_alt : Ii32<0xC7, MRM0r, (outs GR32:$dst), (ins i32imm:$src),
1576 "mov{l}\t{$src, $dst|$dst, $src}", []>, OpSize32,
1577 FoldGenData<"MOV32ri">;
1581 let SchedRW = [WriteStore] in {
1582 def MOV8mi : Ii8 <0xC6, MRM0m, (outs), (ins i8mem :$dst, i8imm :$src),
1583 "mov{b}\t{$src, $dst|$dst, $src}",
1584 [(store (i8 relocImm8_su:$src), addr:$dst)]>;
1585 def MOV16mi : Ii16<0xC7, MRM0m, (outs), (ins i16mem:$dst, i16imm:$src),
1586 "mov{w}\t{$src, $dst|$dst, $src}",
1587 [(store (i16 relocImm16_su:$src), addr:$dst)]>, OpSize16;
1588 def MOV32mi : Ii32<0xC7, MRM0m, (outs), (ins i32mem:$dst, i32imm:$src),
1589 "mov{l}\t{$src, $dst|$dst, $src}",
1590 [(store (i32 relocImm32_su:$src), addr:$dst)]>, OpSize32;
1591 def MOV64mi32 : RIi32S<0xC7, MRM0m, (outs), (ins i64mem:$dst, i64i32imm:$src),
1592 "mov{q}\t{$src, $dst|$dst, $src}",
1593 [(store i64relocImmSExt32_su:$src, addr:$dst)]>,
1594 Requires<[In64BitMode]>;
1597 let hasSideEffects = 0 in {
1599 /// Memory offset versions of moves. The immediate is an address mode sized
1600 /// offset from the segment base.
1601 let SchedRW = [WriteALU] in {
1602 let mayLoad = 1 in {
1604 def MOV8ao32 : Ii32<0xA0, RawFrmMemOffs, (outs), (ins offset32_8:$src),
1605 "mov{b}\t{$src, %al|al, $src}", []>,
1608 def MOV16ao32 : Ii32<0xA1, RawFrmMemOffs, (outs), (ins offset32_16:$src),
1609 "mov{w}\t{$src, %ax|ax, $src}", []>,
1612 def MOV32ao32 : Ii32<0xA1, RawFrmMemOffs, (outs), (ins offset32_32:$src),
1613 "mov{l}\t{$src, %eax|eax, $src}", []>,
1616 def MOV64ao32 : RIi32<0xA1, RawFrmMemOffs, (outs), (ins offset32_64:$src),
1617 "mov{q}\t{$src, %rax|rax, $src}", []>,
1621 def MOV8ao16 : Ii16<0xA0, RawFrmMemOffs, (outs), (ins offset16_8:$src),
1622 "mov{b}\t{$src, %al|al, $src}", []>, AdSize16;
1624 def MOV16ao16 : Ii16<0xA1, RawFrmMemOffs, (outs), (ins offset16_16:$src),
1625 "mov{w}\t{$src, %ax|ax, $src}", []>,
1628 def MOV32ao16 : Ii16<0xA1, RawFrmMemOffs, (outs), (ins offset16_32:$src),
1629 "mov{l}\t{$src, %eax|eax, $src}", []>,
1632 let mayStore = 1 in {
1634 def MOV8o32a : Ii32<0xA2, RawFrmMemOffs, (outs), (ins offset32_8:$dst),
1635 "mov{b}\t{%al, $dst|$dst, al}", []>, AdSize32;
1637 def MOV16o32a : Ii32<0xA3, RawFrmMemOffs, (outs), (ins offset32_16:$dst),
1638 "mov{w}\t{%ax, $dst|$dst, ax}", []>,
1641 def MOV32o32a : Ii32<0xA3, RawFrmMemOffs, (outs), (ins offset32_32:$dst),
1642 "mov{l}\t{%eax, $dst|$dst, eax}", []>,
1645 def MOV64o32a : RIi32<0xA3, RawFrmMemOffs, (outs), (ins offset32_64:$dst),
1646 "mov{q}\t{%rax, $dst|$dst, rax}", []>,
1650 def MOV8o16a : Ii16<0xA2, RawFrmMemOffs, (outs), (ins offset16_8:$dst),
1651 "mov{b}\t{%al, $dst|$dst, al}", []>, AdSize16;
1653 def MOV16o16a : Ii16<0xA3, RawFrmMemOffs, (outs), (ins offset16_16:$dst),
1654 "mov{w}\t{%ax, $dst|$dst, ax}", []>,
1657 def MOV32o16a : Ii16<0xA3, RawFrmMemOffs, (outs), (ins offset16_32:$dst),
1658 "mov{l}\t{%eax, $dst|$dst, eax}", []>,
1662 // These forms all have full 64-bit absolute addresses in their instructions
1663 // and use the movabs mnemonic to indicate this specific form.
1664 let mayLoad = 1 in {
1666 def MOV8ao64 : Ii64<0xA0, RawFrmMemOffs, (outs), (ins offset64_8:$src),
1667 "movabs{b}\t{$src, %al|al, $src}", []>,
1670 def MOV16ao64 : Ii64<0xA1, RawFrmMemOffs, (outs), (ins offset64_16:$src),
1671 "movabs{w}\t{$src, %ax|ax, $src}", []>,
1674 def MOV32ao64 : Ii64<0xA1, RawFrmMemOffs, (outs), (ins offset64_32:$src),
1675 "movabs{l}\t{$src, %eax|eax, $src}", []>,
1678 def MOV64ao64 : RIi64<0xA1, RawFrmMemOffs, (outs), (ins offset64_64:$src),
1679 "movabs{q}\t{$src, %rax|rax, $src}", []>,
1683 let mayStore = 1 in {
1685 def MOV8o64a : Ii64<0xA2, RawFrmMemOffs, (outs), (ins offset64_8:$dst),
1686 "movabs{b}\t{%al, $dst|$dst, al}", []>,
1689 def MOV16o64a : Ii64<0xA3, RawFrmMemOffs, (outs), (ins offset64_16:$dst),
1690 "movabs{w}\t{%ax, $dst|$dst, ax}", []>,
1693 def MOV32o64a : Ii64<0xA3, RawFrmMemOffs, (outs), (ins offset64_32:$dst),
1694 "movabs{l}\t{%eax, $dst|$dst, eax}", []>,
1697 def MOV64o64a : RIi64<0xA3, RawFrmMemOffs, (outs), (ins offset64_64:$dst),
1698 "movabs{q}\t{%rax, $dst|$dst, rax}", []>,
1702 } // hasSideEffects = 0
1704 let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0,
1705 SchedRW = [WriteMove], isMoveReg = 1 in {
1706 def MOV8rr_REV : I<0x8A, MRMSrcReg, (outs GR8:$dst), (ins GR8:$src),
1707 "mov{b}\t{$src, $dst|$dst, $src}", []>,
1708 FoldGenData<"MOV8rr">;
1709 def MOV16rr_REV : I<0x8B, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
1710 "mov{w}\t{$src, $dst|$dst, $src}", []>, OpSize16,
1711 FoldGenData<"MOV16rr">;
1712 def MOV32rr_REV : I<0x8B, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
1713 "mov{l}\t{$src, $dst|$dst, $src}", []>, OpSize32,
1714 FoldGenData<"MOV32rr">;
1715 def MOV64rr_REV : RI<0x8B, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
1716 "mov{q}\t{$src, $dst|$dst, $src}", []>,
1717 FoldGenData<"MOV64rr">;
1720 // Reversed version with ".s" suffix for GAS compatibility.
1721 def : InstAlias<"mov{b}.s\t{$src, $dst|$dst, $src}",
1722 (MOV8rr_REV GR8:$dst, GR8:$src), 0>;
1723 def : InstAlias<"mov{w}.s\t{$src, $dst|$dst, $src}",
1724 (MOV16rr_REV GR16:$dst, GR16:$src), 0>;
1725 def : InstAlias<"mov{l}.s\t{$src, $dst|$dst, $src}",
1726 (MOV32rr_REV GR32:$dst, GR32:$src), 0>;
1727 def : InstAlias<"mov{q}.s\t{$src, $dst|$dst, $src}",
1728 (MOV64rr_REV GR64:$dst, GR64:$src), 0>;
1729 def : InstAlias<"mov.s\t{$src, $dst|$dst, $src}",
1730 (MOV8rr_REV GR8:$dst, GR8:$src), 0, "att">;
1731 def : InstAlias<"mov.s\t{$src, $dst|$dst, $src}",
1732 (MOV16rr_REV GR16:$dst, GR16:$src), 0, "att">;
1733 def : InstAlias<"mov.s\t{$src, $dst|$dst, $src}",
1734 (MOV32rr_REV GR32:$dst, GR32:$src), 0, "att">;
1735 def : InstAlias<"mov.s\t{$src, $dst|$dst, $src}",
1736 (MOV64rr_REV GR64:$dst, GR64:$src), 0, "att">;
1738 let canFoldAsLoad = 1, isReMaterializable = 1, SchedRW = [WriteLoad] in {
1739 def MOV8rm : I<0x8A, MRMSrcMem, (outs GR8 :$dst), (ins i8mem :$src),
1740 "mov{b}\t{$src, $dst|$dst, $src}",
1741 [(set GR8:$dst, (loadi8 addr:$src))]>;
1742 def MOV16rm : I<0x8B, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
1743 "mov{w}\t{$src, $dst|$dst, $src}",
1744 [(set GR16:$dst, (loadi16 addr:$src))]>, OpSize16;
1745 def MOV32rm : I<0x8B, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
1746 "mov{l}\t{$src, $dst|$dst, $src}",
1747 [(set GR32:$dst, (loadi32 addr:$src))]>, OpSize32;
1748 def MOV64rm : RI<0x8B, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
1749 "mov{q}\t{$src, $dst|$dst, $src}",
1750 [(set GR64:$dst, (load addr:$src))]>;
1753 let SchedRW = [WriteStore] in {
1754 def MOV8mr : I<0x88, MRMDestMem, (outs), (ins i8mem :$dst, GR8 :$src),
1755 "mov{b}\t{$src, $dst|$dst, $src}",
1756 [(store GR8:$src, addr:$dst)]>;
1757 def MOV16mr : I<0x89, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src),
1758 "mov{w}\t{$src, $dst|$dst, $src}",
1759 [(store GR16:$src, addr:$dst)]>, OpSize16;
1760 def MOV32mr : I<0x89, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
1761 "mov{l}\t{$src, $dst|$dst, $src}",
1762 [(store GR32:$src, addr:$dst)]>, OpSize32;
1763 def MOV64mr : RI<0x89, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
1764 "mov{q}\t{$src, $dst|$dst, $src}",
1765 [(store GR64:$src, addr:$dst)]>;
1768 // Versions of MOV8rr, MOV8mr, and MOV8rm that use i8mem_NOREX and GR8_NOREX so
1769 // that they can be used for copying and storing h registers, which can't be
1770 // encoded when a REX prefix is present.
1771 let isCodeGenOnly = 1 in {
1772 let hasSideEffects = 0, isMoveReg = 1 in
1773 def MOV8rr_NOREX : I<0x88, MRMDestReg,
1774 (outs GR8_NOREX:$dst), (ins GR8_NOREX:$src),
1775 "mov{b}\t{$src, $dst|$dst, $src}", []>,
1777 let mayStore = 1, hasSideEffects = 0 in
1778 def MOV8mr_NOREX : I<0x88, MRMDestMem,
1779 (outs), (ins i8mem_NOREX:$dst, GR8_NOREX:$src),
1780 "mov{b}\t{$src, $dst|$dst, $src}", []>,
1781 Sched<[WriteStore]>;
1782 let mayLoad = 1, hasSideEffects = 0,
1783 canFoldAsLoad = 1, isReMaterializable = 1 in
1784 def MOV8rm_NOREX : I<0x8A, MRMSrcMem,
1785 (outs GR8_NOREX:$dst), (ins i8mem_NOREX:$src),
1786 "mov{b}\t{$src, $dst|$dst, $src}", []>,
1791 // Condition code ops, incl. set if equal/not equal/...
1792 let SchedRW = [WriteLAHFSAHF] in {
1793 let Defs = [EFLAGS], Uses = [AH] in
1794 def SAHF : I<0x9E, RawFrm, (outs), (ins), "sahf",
1795 [(set EFLAGS, (X86sahf AH))]>,
1796 Requires<[HasLAHFSAHF]>;
1797 let Defs = [AH], Uses = [EFLAGS], hasSideEffects = 0 in
1798 def LAHF : I<0x9F, RawFrm, (outs), (ins), "lahf", []>, // AH = flags
1799 Requires<[HasLAHFSAHF]>;
1802 //===----------------------------------------------------------------------===//
1803 // Bit tests instructions: BT, BTS, BTR, BTC.
1805 let Defs = [EFLAGS] in {
1806 let SchedRW = [WriteBitTest] in {
1807 def BT16rr : I<0xA3, MRMDestReg, (outs), (ins GR16:$src1, GR16:$src2),
1808 "bt{w}\t{$src2, $src1|$src1, $src2}",
1809 [(set EFLAGS, (X86bt GR16:$src1, GR16:$src2))]>,
1810 OpSize16, TB, NotMemoryFoldable;
1811 def BT32rr : I<0xA3, MRMDestReg, (outs), (ins GR32:$src1, GR32:$src2),
1812 "bt{l}\t{$src2, $src1|$src1, $src2}",
1813 [(set EFLAGS, (X86bt GR32:$src1, GR32:$src2))]>,
1814 OpSize32, TB, NotMemoryFoldable;
1815 def BT64rr : RI<0xA3, MRMDestReg, (outs), (ins GR64:$src1, GR64:$src2),
1816 "bt{q}\t{$src2, $src1|$src1, $src2}",
1817 [(set EFLAGS, (X86bt GR64:$src1, GR64:$src2))]>, TB,
1821 // Unlike with the register+register form, the memory+register form of the
1822 // bt instruction does not ignore the high bits of the index. From ISel's
1823 // perspective, this is pretty bizarre. Make these instructions disassembly
1824 // only for now. These instructions are also slow on modern CPUs so that's
1825 // another reason to avoid generating them.
1827 let mayLoad = 1, hasSideEffects = 0, SchedRW = [WriteBitTestRegLd] in {
1828 def BT16mr : I<0xA3, MRMDestMem, (outs), (ins i16mem:$src1, GR16:$src2),
1829 "bt{w}\t{$src2, $src1|$src1, $src2}",
1830 []>, OpSize16, TB, NotMemoryFoldable;
1831 def BT32mr : I<0xA3, MRMDestMem, (outs), (ins i32mem:$src1, GR32:$src2),
1832 "bt{l}\t{$src2, $src1|$src1, $src2}",
1833 []>, OpSize32, TB, NotMemoryFoldable;
1834 def BT64mr : RI<0xA3, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2),
1835 "bt{q}\t{$src2, $src1|$src1, $src2}",
1836 []>, TB, NotMemoryFoldable;
1839 let SchedRW = [WriteBitTest] in {
1840 def BT16ri8 : Ii8<0xBA, MRM4r, (outs), (ins GR16:$src1, i16u8imm:$src2),
1841 "bt{w}\t{$src2, $src1|$src1, $src2}",
1842 [(set EFLAGS, (X86bt GR16:$src1, imm:$src2))]>,
1844 def BT32ri8 : Ii8<0xBA, MRM4r, (outs), (ins GR32:$src1, i32u8imm:$src2),
1845 "bt{l}\t{$src2, $src1|$src1, $src2}",
1846 [(set EFLAGS, (X86bt GR32:$src1, imm:$src2))]>,
1848 def BT64ri8 : RIi8<0xBA, MRM4r, (outs), (ins GR64:$src1, i64u8imm:$src2),
1849 "bt{q}\t{$src2, $src1|$src1, $src2}",
1850 [(set EFLAGS, (X86bt GR64:$src1, imm:$src2))]>, TB;
1853 // Note that these instructions aren't slow because that only applies when the
1854 // other operand is in a register. When it's an immediate, bt is still fast.
1855 let SchedRW = [WriteBitTestImmLd] in {
1856 def BT16mi8 : Ii8<0xBA, MRM4m, (outs), (ins i16mem:$src1, i16u8imm:$src2),
1857 "bt{w}\t{$src2, $src1|$src1, $src2}",
1858 [(set EFLAGS, (X86bt (loadi16 addr:$src1),
1861 def BT32mi8 : Ii8<0xBA, MRM4m, (outs), (ins i32mem:$src1, i32u8imm:$src2),
1862 "bt{l}\t{$src2, $src1|$src1, $src2}",
1863 [(set EFLAGS, (X86bt (loadi32 addr:$src1),
1866 def BT64mi8 : RIi8<0xBA, MRM4m, (outs), (ins i64mem:$src1, i64u8imm:$src2),
1867 "bt{q}\t{$src2, $src1|$src1, $src2}",
1868 [(set EFLAGS, (X86bt (loadi64 addr:$src1),
1870 Requires<[In64BitMode]>;
1873 let hasSideEffects = 0 in {
1874 let SchedRW = [WriteBitTestSet], Constraints = "$src1 = $dst" in {
1875 def BTC16rr : I<0xBB, MRMDestReg, (outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
1876 "btc{w}\t{$src2, $src1|$src1, $src2}", []>,
1877 OpSize16, TB, NotMemoryFoldable;
1878 def BTC32rr : I<0xBB, MRMDestReg, (outs GR32:$dst), (ins GR32:$src1, GR32:$src2),
1879 "btc{l}\t{$src2, $src1|$src1, $src2}", []>,
1880 OpSize32, TB, NotMemoryFoldable;
1881 def BTC64rr : RI<0xBB, MRMDestReg, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
1882 "btc{q}\t{$src2, $src1|$src1, $src2}", []>, TB,
1886 let mayLoad = 1, mayStore = 1, SchedRW = [WriteBitTestSetRegRMW] in {
1887 def BTC16mr : I<0xBB, MRMDestMem, (outs), (ins i16mem:$src1, GR16:$src2),
1888 "btc{w}\t{$src2, $src1|$src1, $src2}", []>,
1889 OpSize16, TB, NotMemoryFoldable;
1890 def BTC32mr : I<0xBB, MRMDestMem, (outs), (ins i32mem:$src1, GR32:$src2),
1891 "btc{l}\t{$src2, $src1|$src1, $src2}", []>,
1892 OpSize32, TB, NotMemoryFoldable;
1893 def BTC64mr : RI<0xBB, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2),
1894 "btc{q}\t{$src2, $src1|$src1, $src2}", []>, TB,
1898 let SchedRW = [WriteBitTestSet], Constraints = "$src1 = $dst" in {
1899 def BTC16ri8 : Ii8<0xBA, MRM7r, (outs GR16:$dst), (ins GR16:$src1, i16u8imm:$src2),
1900 "btc{w}\t{$src2, $src1|$src1, $src2}", []>, OpSize16, TB;
1901 def BTC32ri8 : Ii8<0xBA, MRM7r, (outs GR32:$dst), (ins GR32:$src1, i32u8imm:$src2),
1902 "btc{l}\t{$src2, $src1|$src1, $src2}", []>, OpSize32, TB;
1903 def BTC64ri8 : RIi8<0xBA, MRM7r, (outs GR64:$dst), (ins GR64:$src1, i64u8imm:$src2),
1904 "btc{q}\t{$src2, $src1|$src1, $src2}", []>, TB;
1907 let mayLoad = 1, mayStore = 1, SchedRW = [WriteBitTestSetImmRMW] in {
1908 def BTC16mi8 : Ii8<0xBA, MRM7m, (outs), (ins i16mem:$src1, i16u8imm:$src2),
1909 "btc{w}\t{$src2, $src1|$src1, $src2}", []>, OpSize16, TB;
1910 def BTC32mi8 : Ii8<0xBA, MRM7m, (outs), (ins i32mem:$src1, i32u8imm:$src2),
1911 "btc{l}\t{$src2, $src1|$src1, $src2}", []>, OpSize32, TB;
1912 def BTC64mi8 : RIi8<0xBA, MRM7m, (outs), (ins i64mem:$src1, i64u8imm:$src2),
1913 "btc{q}\t{$src2, $src1|$src1, $src2}", []>, TB,
1914 Requires<[In64BitMode]>;
1917 let SchedRW = [WriteBitTestSet], Constraints = "$src1 = $dst" in {
1918 def BTR16rr : I<0xB3, MRMDestReg, (outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
1919 "btr{w}\t{$src2, $src1|$src1, $src2}", []>,
1920 OpSize16, TB, NotMemoryFoldable;
1921 def BTR32rr : I<0xB3, MRMDestReg, (outs GR32:$dst), (ins GR32:$src1, GR32:$src2),
1922 "btr{l}\t{$src2, $src1|$src1, $src2}", []>,
1923 OpSize32, TB, NotMemoryFoldable;
1924 def BTR64rr : RI<0xB3, MRMDestReg, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
1925 "btr{q}\t{$src2, $src1|$src1, $src2}", []>, TB,
1929 let mayLoad = 1, mayStore = 1, SchedRW = [WriteBitTestSetRegRMW] in {
1930 def BTR16mr : I<0xB3, MRMDestMem, (outs), (ins i16mem:$src1, GR16:$src2),
1931 "btr{w}\t{$src2, $src1|$src1, $src2}", []>,
1932 OpSize16, TB, NotMemoryFoldable;
1933 def BTR32mr : I<0xB3, MRMDestMem, (outs), (ins i32mem:$src1, GR32:$src2),
1934 "btr{l}\t{$src2, $src1|$src1, $src2}", []>,
1935 OpSize32, TB, NotMemoryFoldable;
1936 def BTR64mr : RI<0xB3, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2),
1937 "btr{q}\t{$src2, $src1|$src1, $src2}", []>, TB,
1941 let SchedRW = [WriteBitTestSet], Constraints = "$src1 = $dst" in {
1942 def BTR16ri8 : Ii8<0xBA, MRM6r, (outs GR16:$dst), (ins GR16:$src1, i16u8imm:$src2),
1943 "btr{w}\t{$src2, $src1|$src1, $src2}", []>,
1945 def BTR32ri8 : Ii8<0xBA, MRM6r, (outs GR32:$dst), (ins GR32:$src1, i32u8imm:$src2),
1946 "btr{l}\t{$src2, $src1|$src1, $src2}", []>,
1948 def BTR64ri8 : RIi8<0xBA, MRM6r, (outs GR64:$dst), (ins GR64:$src1, i64u8imm:$src2),
1949 "btr{q}\t{$src2, $src1|$src1, $src2}", []>, TB;
1952 let mayLoad = 1, mayStore = 1, SchedRW = [WriteBitTestSetImmRMW] in {
1953 def BTR16mi8 : Ii8<0xBA, MRM6m, (outs), (ins i16mem:$src1, i16u8imm:$src2),
1954 "btr{w}\t{$src2, $src1|$src1, $src2}", []>,
1956 def BTR32mi8 : Ii8<0xBA, MRM6m, (outs), (ins i32mem:$src1, i32u8imm:$src2),
1957 "btr{l}\t{$src2, $src1|$src1, $src2}", []>,
1959 def BTR64mi8 : RIi8<0xBA, MRM6m, (outs), (ins i64mem:$src1, i64u8imm:$src2),
1960 "btr{q}\t{$src2, $src1|$src1, $src2}", []>, TB,
1961 Requires<[In64BitMode]>;
1964 let SchedRW = [WriteBitTestSet], Constraints = "$src1 = $dst" in {
1965 def BTS16rr : I<0xAB, MRMDestReg, (outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
1966 "bts{w}\t{$src2, $src1|$src1, $src2}", []>,
1967 OpSize16, TB, NotMemoryFoldable;
1968 def BTS32rr : I<0xAB, MRMDestReg, (outs GR32:$dst), (ins GR32:$src1, GR32:$src2),
1969 "bts{l}\t{$src2, $src1|$src1, $src2}", []>,
1970 OpSize32, TB, NotMemoryFoldable;
1971 def BTS64rr : RI<0xAB, MRMDestReg, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
1972 "bts{q}\t{$src2, $src1|$src1, $src2}", []>, TB,
1976 let mayLoad = 1, mayStore = 1, SchedRW = [WriteBitTestSetRegRMW] in {
1977 def BTS16mr : I<0xAB, MRMDestMem, (outs), (ins i16mem:$src1, GR16:$src2),
1978 "bts{w}\t{$src2, $src1|$src1, $src2}", []>,
1979 OpSize16, TB, NotMemoryFoldable;
1980 def BTS32mr : I<0xAB, MRMDestMem, (outs), (ins i32mem:$src1, GR32:$src2),
1981 "bts{l}\t{$src2, $src1|$src1, $src2}", []>,
1982 OpSize32, TB, NotMemoryFoldable;
1983 def BTS64mr : RI<0xAB, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2),
1984 "bts{q}\t{$src2, $src1|$src1, $src2}", []>, TB,
1988 let SchedRW = [WriteBitTestSet], Constraints = "$src1 = $dst" in {
1989 def BTS16ri8 : Ii8<0xBA, MRM5r, (outs GR16:$dst), (ins GR16:$src1, i16u8imm:$src2),
1990 "bts{w}\t{$src2, $src1|$src1, $src2}", []>, OpSize16, TB;
1991 def BTS32ri8 : Ii8<0xBA, MRM5r, (outs GR32:$dst), (ins GR32:$src1, i32u8imm:$src2),
1992 "bts{l}\t{$src2, $src1|$src1, $src2}", []>, OpSize32, TB;
1993 def BTS64ri8 : RIi8<0xBA, MRM5r, (outs GR64:$dst), (ins GR64:$src1, i64u8imm:$src2),
1994 "bts{q}\t{$src2, $src1|$src1, $src2}", []>, TB;
1997 let mayLoad = 1, mayStore = 1, SchedRW = [WriteBitTestSetImmRMW] in {
1998 def BTS16mi8 : Ii8<0xBA, MRM5m, (outs), (ins i16mem:$src1, i16u8imm:$src2),
1999 "bts{w}\t{$src2, $src1|$src1, $src2}", []>, OpSize16, TB;
2000 def BTS32mi8 : Ii8<0xBA, MRM5m, (outs), (ins i32mem:$src1, i32u8imm:$src2),
2001 "bts{l}\t{$src2, $src1|$src1, $src2}", []>, OpSize32, TB;
2002 def BTS64mi8 : RIi8<0xBA, MRM5m, (outs), (ins i64mem:$src1, i64u8imm:$src2),
2003 "bts{q}\t{$src2, $src1|$src1, $src2}", []>, TB,
2004 Requires<[In64BitMode]>;
2006 } // hasSideEffects = 0
2007 } // Defs = [EFLAGS]
2010 //===----------------------------------------------------------------------===//
2014 // Atomic swap. These are just normal xchg instructions. But since a memory
2015 // operand is referenced, the atomicity is ensured.
2016 multiclass ATOMIC_SWAP<bits<8> opc8, bits<8> opc, string mnemonic, string frag> {
2017 let Constraints = "$val = $dst", SchedRW = [WriteALULd, WriteRMW] in {
2018 def NAME#8rm : I<opc8, MRMSrcMem, (outs GR8:$dst),
2019 (ins GR8:$val, i8mem:$ptr),
2020 !strconcat(mnemonic, "{b}\t{$val, $ptr|$ptr, $val}"),
2023 (!cast<PatFrag>(frag # "_8") addr:$ptr, GR8:$val))]>;
2024 def NAME#16rm : I<opc, MRMSrcMem, (outs GR16:$dst),
2025 (ins GR16:$val, i16mem:$ptr),
2026 !strconcat(mnemonic, "{w}\t{$val, $ptr|$ptr, $val}"),
2029 (!cast<PatFrag>(frag # "_16") addr:$ptr, GR16:$val))]>,
2031 def NAME#32rm : I<opc, MRMSrcMem, (outs GR32:$dst),
2032 (ins GR32:$val, i32mem:$ptr),
2033 !strconcat(mnemonic, "{l}\t{$val, $ptr|$ptr, $val}"),
2036 (!cast<PatFrag>(frag # "_32") addr:$ptr, GR32:$val))]>,
2038 def NAME#64rm : RI<opc, MRMSrcMem, (outs GR64:$dst),
2039 (ins GR64:$val, i64mem:$ptr),
2040 !strconcat(mnemonic, "{q}\t{$val, $ptr|$ptr, $val}"),
2043 (!cast<PatFrag>(frag # "_64") addr:$ptr, GR64:$val))]>;
2047 defm XCHG : ATOMIC_SWAP<0x86, 0x87, "xchg", "atomic_swap">, NotMemoryFoldable;
2049 // Swap between registers.
2050 let SchedRW = [WriteXCHG] in {
2051 let Constraints = "$src1 = $dst1, $src2 = $dst2", hasSideEffects = 0 in {
2052 def XCHG8rr : I<0x86, MRMSrcReg, (outs GR8:$dst1, GR8:$dst2),
2053 (ins GR8:$src1, GR8:$src2),
2054 "xchg{b}\t{$src2, $src1|$src1, $src2}", []>, NotMemoryFoldable;
2055 def XCHG16rr : I<0x87, MRMSrcReg, (outs GR16:$dst1, GR16:$dst2),
2056 (ins GR16:$src1, GR16:$src2),
2057 "xchg{w}\t{$src2, $src1|$src1, $src2}", []>,
2058 OpSize16, NotMemoryFoldable;
2059 def XCHG32rr : I<0x87, MRMSrcReg, (outs GR32:$dst1, GR32:$dst2),
2060 (ins GR32:$src1, GR32:$src2),
2061 "xchg{l}\t{$src2, $src1|$src1, $src2}", []>,
2062 OpSize32, NotMemoryFoldable;
2063 def XCHG64rr : RI<0x87, MRMSrcReg, (outs GR64:$dst1, GR64:$dst2),
2064 (ins GR64:$src1 ,GR64:$src2),
2065 "xchg{q}\t{$src2, $src1|$src1, $src2}", []>, NotMemoryFoldable;
2068 // Swap between EAX and other registers.
2069 let Constraints = "$src = $dst", hasSideEffects = 0 in {
2070 let Uses = [AX], Defs = [AX] in
2071 def XCHG16ar : I<0x90, AddRegFrm, (outs GR16:$dst), (ins GR16:$src),
2072 "xchg{w}\t{$src, %ax|ax, $src}", []>, OpSize16;
2073 let Uses = [EAX], Defs = [EAX] in
2074 def XCHG32ar : I<0x90, AddRegFrm, (outs GR32:$dst), (ins GR32:$src),
2075 "xchg{l}\t{$src, %eax|eax, $src}", []>, OpSize32;
2076 let Uses = [RAX], Defs = [RAX] in
2077 def XCHG64ar : RI<0x90, AddRegFrm, (outs GR64:$dst), (ins GR64:$src),
2078 "xchg{q}\t{$src, %rax|rax, $src}", []>;
2082 let hasSideEffects = 0, Constraints = "$src1 = $dst1, $src2 = $dst2",
2083 Defs = [EFLAGS], SchedRW = [WriteXCHG] in {
2084 def XADD8rr : I<0xC0, MRMDestReg, (outs GR8:$dst1, GR8:$dst2),
2085 (ins GR8:$src1, GR8:$src2),
2086 "xadd{b}\t{$src2, $src1|$src1, $src2}", []>, TB;
2087 def XADD16rr : I<0xC1, MRMDestReg, (outs GR16:$dst1, GR16:$dst2),
2088 (ins GR16:$src1, GR16:$src2),
2089 "xadd{w}\t{$src2, $src1|$src1, $src2}", []>, TB, OpSize16;
2090 def XADD32rr : I<0xC1, MRMDestReg, (outs GR32:$dst1, GR32:$dst2),
2091 (ins GR32:$src1, GR32:$src2),
2092 "xadd{l}\t{$src2, $src1|$src1, $src2}", []>, TB, OpSize32;
2093 def XADD64rr : RI<0xC1, MRMDestReg, (outs GR64:$dst1, GR64:$dst2),
2094 (ins GR64:$src1, GR64:$src2),
2095 "xadd{q}\t{$src2, $src1|$src1, $src2}", []>, TB;
2098 let mayLoad = 1, mayStore = 1, hasSideEffects = 0, Constraints = "$val = $dst",
2099 Defs = [EFLAGS], SchedRW = [WriteALULd, WriteRMW] in {
2100 def XADD8rm : I<0xC0, MRMSrcMem, (outs GR8:$dst),
2101 (ins GR8:$val, i8mem:$ptr),
2102 "xadd{b}\t{$val, $ptr|$ptr, $val}", []>, TB;
2103 def XADD16rm : I<0xC1, MRMSrcMem, (outs GR16:$dst),
2104 (ins GR16:$val, i16mem:$ptr),
2105 "xadd{w}\t{$val, $ptr|$ptr, $val}", []>, TB,
2107 def XADD32rm : I<0xC1, MRMSrcMem, (outs GR32:$dst),
2108 (ins GR32:$val, i32mem:$ptr),
2109 "xadd{l}\t{$val, $ptr|$ptr, $val}", []>, TB,
2111 def XADD64rm : RI<0xC1, MRMSrcMem, (outs GR64:$dst),
2112 (ins GR64:$val, i64mem:$ptr),
2113 "xadd{q}\t{$val, $ptr|$ptr, $val}", []>, TB;
2117 let SchedRW = [WriteCMPXCHG], hasSideEffects = 0 in {
2118 let Defs = [AL, EFLAGS], Uses = [AL] in
2119 def CMPXCHG8rr : I<0xB0, MRMDestReg, (outs GR8:$dst), (ins GR8:$src),
2120 "cmpxchg{b}\t{$src, $dst|$dst, $src}", []>, TB,
2122 let Defs = [AX, EFLAGS], Uses = [AX] in
2123 def CMPXCHG16rr : I<0xB1, MRMDestReg, (outs GR16:$dst), (ins GR16:$src),
2124 "cmpxchg{w}\t{$src, $dst|$dst, $src}", []>, TB, OpSize16,
2126 let Defs = [EAX, EFLAGS], Uses = [EAX] in
2127 def CMPXCHG32rr : I<0xB1, MRMDestReg, (outs GR32:$dst), (ins GR32:$src),
2128 "cmpxchg{l}\t{$src, $dst|$dst, $src}", []>, TB, OpSize32,
2130 let Defs = [RAX, EFLAGS], Uses = [RAX] in
2131 def CMPXCHG64rr : RI<0xB1, MRMDestReg, (outs GR64:$dst), (ins GR64:$src),
2132 "cmpxchg{q}\t{$src, $dst|$dst, $src}", []>, TB,
2134 } // SchedRW, hasSideEffects
2136 let SchedRW = [WriteCMPXCHGRMW], mayLoad = 1, mayStore = 1,
2137 hasSideEffects = 0 in {
2138 let Defs = [AL, EFLAGS], Uses = [AL] in
2139 def CMPXCHG8rm : I<0xB0, MRMDestMem, (outs), (ins i8mem:$dst, GR8:$src),
2140 "cmpxchg{b}\t{$src, $dst|$dst, $src}", []>, TB,
2142 let Defs = [AX, EFLAGS], Uses = [AX] in
2143 def CMPXCHG16rm : I<0xB1, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src),
2144 "cmpxchg{w}\t{$src, $dst|$dst, $src}", []>, TB, OpSize16,
2146 let Defs = [EAX, EFLAGS], Uses = [EAX] in
2147 def CMPXCHG32rm : I<0xB1, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
2148 "cmpxchg{l}\t{$src, $dst|$dst, $src}", []>, TB, OpSize32,
2150 let Defs = [RAX, EFLAGS], Uses = [RAX] in
2151 def CMPXCHG64rm : RI<0xB1, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
2152 "cmpxchg{q}\t{$src, $dst|$dst, $src}", []>, TB,
2155 let Defs = [EAX, EDX, EFLAGS], Uses = [EAX, EBX, ECX, EDX] in
2156 def CMPXCHG8B : I<0xC7, MRM1m, (outs), (ins i64mem:$dst),
2157 "cmpxchg8b\t$dst", []>, TB, Requires<[HasCmpxchg8b]>;
2159 let Defs = [RAX, RDX, EFLAGS], Uses = [RAX, RBX, RCX, RDX] in
2160 // NOTE: In64BitMode check needed for the AssemblerPredicate.
2161 def CMPXCHG16B : RI<0xC7, MRM1m, (outs), (ins i128mem:$dst),
2162 "cmpxchg16b\t$dst", []>,
2163 TB, Requires<[HasCmpxchg16b,In64BitMode]>;
2164 } // SchedRW, mayLoad, mayStore, hasSideEffects
2167 // Lock instruction prefix
2168 let SchedRW = [WriteMicrocoded] in
2169 def LOCK_PREFIX : I<0xF0, RawFrm, (outs), (ins), "lock", []>;
2171 let SchedRW = [WriteNop] in {
2173 // Rex64 instruction prefix
2174 def REX64_PREFIX : I<0x48, RawFrm, (outs), (ins), "rex64", []>,
2175 Requires<[In64BitMode]>;
2177 // Data16 instruction prefix
2178 def DATA16_PREFIX : I<0x66, RawFrm, (outs), (ins), "data16", []>;
2181 // Repeat string operation instruction prefixes
2182 let Defs = [ECX], Uses = [ECX,DF], SchedRW = [WriteMicrocoded] in {
2183 // Repeat (used with INS, OUTS, MOVS, LODS and STOS)
2184 def REP_PREFIX : I<0xF3, RawFrm, (outs), (ins), "rep", []>;
2185 // Repeat while not equal (used with CMPS and SCAS)
2186 def REPNE_PREFIX : I<0xF2, RawFrm, (outs), (ins), "repne", []>;
2189 // String manipulation instructions
2190 let SchedRW = [WriteMicrocoded] in {
2191 let Defs = [AL,ESI], Uses = [ESI,DF] in
2192 def LODSB : I<0xAC, RawFrmSrc, (outs), (ins srcidx8:$src),
2193 "lodsb\t{$src, %al|al, $src}", []>;
2194 let Defs = [AX,ESI], Uses = [ESI,DF] in
2195 def LODSW : I<0xAD, RawFrmSrc, (outs), (ins srcidx16:$src),
2196 "lodsw\t{$src, %ax|ax, $src}", []>, OpSize16;
2197 let Defs = [EAX,ESI], Uses = [ESI,DF] in
2198 def LODSL : I<0xAD, RawFrmSrc, (outs), (ins srcidx32:$src),
2199 "lods{l|d}\t{$src, %eax|eax, $src}", []>, OpSize32;
2200 let Defs = [RAX,ESI], Uses = [ESI,DF] in
2201 def LODSQ : RI<0xAD, RawFrmSrc, (outs), (ins srcidx64:$src),
2202 "lodsq\t{$src, %rax|rax, $src}", []>,
2203 Requires<[In64BitMode]>;
2206 let SchedRW = [WriteSystem] in {
2207 let Defs = [ESI], Uses = [DX,ESI,DF] in {
2208 def OUTSB : I<0x6E, RawFrmSrc, (outs), (ins srcidx8:$src),
2209 "outsb\t{$src, %dx|dx, $src}", []>;
2210 def OUTSW : I<0x6F, RawFrmSrc, (outs), (ins srcidx16:$src),
2211 "outsw\t{$src, %dx|dx, $src}", []>, OpSize16;
2212 def OUTSL : I<0x6F, RawFrmSrc, (outs), (ins srcidx32:$src),
2213 "outs{l|d}\t{$src, %dx|dx, $src}", []>, OpSize32;
2216 let Defs = [EDI], Uses = [DX,EDI,DF] in {
2217 def INSB : I<0x6C, RawFrmDst, (outs), (ins dstidx8:$dst),
2218 "insb\t{%dx, $dst|$dst, dx}", []>;
2219 def INSW : I<0x6D, RawFrmDst, (outs), (ins dstidx16:$dst),
2220 "insw\t{%dx, $dst|$dst, dx}", []>, OpSize16;
2221 def INSL : I<0x6D, RawFrmDst, (outs), (ins dstidx32:$dst),
2222 "ins{l|d}\t{%dx, $dst|$dst, dx}", []>, OpSize32;
2226 // EFLAGS management instructions.
2227 let SchedRW = [WriteALU], Defs = [EFLAGS], Uses = [EFLAGS] in {
2228 def CLC : I<0xF8, RawFrm, (outs), (ins), "clc", []>;
2229 def STC : I<0xF9, RawFrm, (outs), (ins), "stc", []>;
2230 def CMC : I<0xF5, RawFrm, (outs), (ins), "cmc", []>;
2233 // DF management instructions.
2234 let SchedRW = [WriteALU], Defs = [DF] in {
2235 def CLD : I<0xFC, RawFrm, (outs), (ins), "cld", []>;
2236 def STD : I<0xFD, RawFrm, (outs), (ins), "std", []>;
2239 // Table lookup instructions
2240 let Uses = [AL,EBX], Defs = [AL], hasSideEffects = 0, mayLoad = 1 in
2241 def XLAT : I<0xD7, RawFrm, (outs), (ins), "xlatb", []>, Sched<[WriteLoad]>;
2243 let SchedRW = [WriteMicrocoded] in {
2244 // ASCII Adjust After Addition
2245 let Uses = [AL,EFLAGS], Defs = [AX,EFLAGS], hasSideEffects = 0 in
2246 def AAA : I<0x37, RawFrm, (outs), (ins), "aaa", []>,
2247 Requires<[Not64BitMode]>;
2249 // ASCII Adjust AX Before Division
2250 let Uses = [AX], Defs = [AX,EFLAGS], hasSideEffects = 0 in
2251 def AAD8i8 : Ii8<0xD5, RawFrm, (outs), (ins i8imm:$src),
2252 "aad\t$src", []>, Requires<[Not64BitMode]>;
2254 // ASCII Adjust AX After Multiply
2255 let Uses = [AL], Defs = [AX,EFLAGS], hasSideEffects = 0 in
2256 def AAM8i8 : Ii8<0xD4, RawFrm, (outs), (ins i8imm:$src),
2257 "aam\t$src", []>, Requires<[Not64BitMode]>;
2259 // ASCII Adjust AL After Subtraction - sets
2260 let Uses = [AL,EFLAGS], Defs = [AX,EFLAGS], hasSideEffects = 0 in
2261 def AAS : I<0x3F, RawFrm, (outs), (ins), "aas", []>,
2262 Requires<[Not64BitMode]>;
2264 // Decimal Adjust AL after Addition
2265 let Uses = [AL,EFLAGS], Defs = [AL,EFLAGS], hasSideEffects = 0 in
2266 def DAA : I<0x27, RawFrm, (outs), (ins), "daa", []>,
2267 Requires<[Not64BitMode]>;
2269 // Decimal Adjust AL after Subtraction
2270 let Uses = [AL,EFLAGS], Defs = [AL,EFLAGS], hasSideEffects = 0 in
2271 def DAS : I<0x2F, RawFrm, (outs), (ins), "das", []>,
2272 Requires<[Not64BitMode]>;
2275 let SchedRW = [WriteSystem] in {
2276 // Check Array Index Against Bounds
2277 // Note: "bound" does not have reversed operands in at&t syntax.
2278 def BOUNDS16rm : I<0x62, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
2279 "bound\t$dst, $src", []>, OpSize16,
2280 Requires<[Not64BitMode]>;
2281 def BOUNDS32rm : I<0x62, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
2282 "bound\t$dst, $src", []>, OpSize32,
2283 Requires<[Not64BitMode]>;
2285 // Adjust RPL Field of Segment Selector
2286 def ARPL16rr : I<0x63, MRMDestReg, (outs GR16:$dst), (ins GR16:$src),
2287 "arpl\t{$src, $dst|$dst, $src}", []>,
2288 Requires<[Not64BitMode]>, NotMemoryFoldable;
2290 def ARPL16mr : I<0x63, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src),
2291 "arpl\t{$src, $dst|$dst, $src}", []>,
2292 Requires<[Not64BitMode]>, NotMemoryFoldable;
2295 //===----------------------------------------------------------------------===//
2296 // MOVBE Instructions
2298 let Predicates = [HasMOVBE] in {
2299 let SchedRW = [WriteALULd] in {
2300 def MOVBE16rm : I<0xF0, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
2301 "movbe{w}\t{$src, $dst|$dst, $src}",
2302 [(set GR16:$dst, (bswap (loadi16 addr:$src)))]>,
2304 def MOVBE32rm : I<0xF0, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
2305 "movbe{l}\t{$src, $dst|$dst, $src}",
2306 [(set GR32:$dst, (bswap (loadi32 addr:$src)))]>,
2308 def MOVBE64rm : RI<0xF0, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
2309 "movbe{q}\t{$src, $dst|$dst, $src}",
2310 [(set GR64:$dst, (bswap (loadi64 addr:$src)))]>,
2313 let SchedRW = [WriteStore] in {
2314 def MOVBE16mr : I<0xF1, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src),
2315 "movbe{w}\t{$src, $dst|$dst, $src}",
2316 [(store (bswap GR16:$src), addr:$dst)]>,
2318 def MOVBE32mr : I<0xF1, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
2319 "movbe{l}\t{$src, $dst|$dst, $src}",
2320 [(store (bswap GR32:$src), addr:$dst)]>,
2322 def MOVBE64mr : RI<0xF1, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
2323 "movbe{q}\t{$src, $dst|$dst, $src}",
2324 [(store (bswap GR64:$src), addr:$dst)]>,
2329 //===----------------------------------------------------------------------===//
2330 // RDRAND Instruction
2332 let Predicates = [HasRDRAND], Defs = [EFLAGS], SchedRW = [WriteSystem] in {
2333 def RDRAND16r : I<0xC7, MRM6r, (outs GR16:$dst), (ins),
2334 "rdrand{w}\t$dst", [(set GR16:$dst, EFLAGS, (X86rdrand))]>,
2336 def RDRAND32r : I<0xC7, MRM6r, (outs GR32:$dst), (ins),
2337 "rdrand{l}\t$dst", [(set GR32:$dst, EFLAGS, (X86rdrand))]>,
2339 def RDRAND64r : RI<0xC7, MRM6r, (outs GR64:$dst), (ins),
2340 "rdrand{q}\t$dst", [(set GR64:$dst, EFLAGS, (X86rdrand))]>,
2344 //===----------------------------------------------------------------------===//
2345 // RDSEED Instruction
2347 let Predicates = [HasRDSEED], Defs = [EFLAGS], SchedRW = [WriteSystem] in {
2348 def RDSEED16r : I<0xC7, MRM7r, (outs GR16:$dst), (ins), "rdseed{w}\t$dst",
2349 [(set GR16:$dst, EFLAGS, (X86rdseed))]>, OpSize16, PS;
2350 def RDSEED32r : I<0xC7, MRM7r, (outs GR32:$dst), (ins), "rdseed{l}\t$dst",
2351 [(set GR32:$dst, EFLAGS, (X86rdseed))]>, OpSize32, PS;
2352 def RDSEED64r : RI<0xC7, MRM7r, (outs GR64:$dst), (ins), "rdseed{q}\t$dst",
2353 [(set GR64:$dst, EFLAGS, (X86rdseed))]>, PS;
2356 //===----------------------------------------------------------------------===//
2357 // LZCNT Instruction
2359 let Predicates = [HasLZCNT], Defs = [EFLAGS] in {
2360 def LZCNT16rr : I<0xBD, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
2361 "lzcnt{w}\t{$src, $dst|$dst, $src}",
2362 [(set GR16:$dst, (ctlz GR16:$src)), (implicit EFLAGS)]>,
2363 XS, OpSize16, Sched<[WriteLZCNT]>;
2364 def LZCNT16rm : I<0xBD, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
2365 "lzcnt{w}\t{$src, $dst|$dst, $src}",
2366 [(set GR16:$dst, (ctlz (loadi16 addr:$src))),
2367 (implicit EFLAGS)]>, XS, OpSize16, Sched<[WriteLZCNTLd]>;
2369 def LZCNT32rr : I<0xBD, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
2370 "lzcnt{l}\t{$src, $dst|$dst, $src}",
2371 [(set GR32:$dst, (ctlz GR32:$src)), (implicit EFLAGS)]>,
2372 XS, OpSize32, Sched<[WriteLZCNT]>;
2373 def LZCNT32rm : I<0xBD, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
2374 "lzcnt{l}\t{$src, $dst|$dst, $src}",
2375 [(set GR32:$dst, (ctlz (loadi32 addr:$src))),
2376 (implicit EFLAGS)]>, XS, OpSize32, Sched<[WriteLZCNTLd]>;
2378 def LZCNT64rr : RI<0xBD, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
2379 "lzcnt{q}\t{$src, $dst|$dst, $src}",
2380 [(set GR64:$dst, (ctlz GR64:$src)), (implicit EFLAGS)]>,
2381 XS, Sched<[WriteLZCNT]>;
2382 def LZCNT64rm : RI<0xBD, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
2383 "lzcnt{q}\t{$src, $dst|$dst, $src}",
2384 [(set GR64:$dst, (ctlz (loadi64 addr:$src))),
2385 (implicit EFLAGS)]>, XS, Sched<[WriteLZCNTLd]>;
2388 //===----------------------------------------------------------------------===//
2391 let Predicates = [HasBMI], Defs = [EFLAGS] in {
2392 def TZCNT16rr : I<0xBC, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
2393 "tzcnt{w}\t{$src, $dst|$dst, $src}",
2394 [(set GR16:$dst, (cttz GR16:$src)), (implicit EFLAGS)]>,
2395 XS, OpSize16, Sched<[WriteTZCNT]>;
2396 def TZCNT16rm : I<0xBC, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
2397 "tzcnt{w}\t{$src, $dst|$dst, $src}",
2398 [(set GR16:$dst, (cttz (loadi16 addr:$src))),
2399 (implicit EFLAGS)]>, XS, OpSize16, Sched<[WriteTZCNTLd]>;
2401 def TZCNT32rr : I<0xBC, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
2402 "tzcnt{l}\t{$src, $dst|$dst, $src}",
2403 [(set GR32:$dst, (cttz GR32:$src)), (implicit EFLAGS)]>,
2404 XS, OpSize32, Sched<[WriteTZCNT]>;
2405 def TZCNT32rm : I<0xBC, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
2406 "tzcnt{l}\t{$src, $dst|$dst, $src}",
2407 [(set GR32:$dst, (cttz (loadi32 addr:$src))),
2408 (implicit EFLAGS)]>, XS, OpSize32, Sched<[WriteTZCNTLd]>;
2410 def TZCNT64rr : RI<0xBC, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
2411 "tzcnt{q}\t{$src, $dst|$dst, $src}",
2412 [(set GR64:$dst, (cttz GR64:$src)), (implicit EFLAGS)]>,
2413 XS, Sched<[WriteTZCNT]>;
2414 def TZCNT64rm : RI<0xBC, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
2415 "tzcnt{q}\t{$src, $dst|$dst, $src}",
2416 [(set GR64:$dst, (cttz (loadi64 addr:$src))),
2417 (implicit EFLAGS)]>, XS, Sched<[WriteTZCNTLd]>;
2420 multiclass bmi_bls<string mnemonic, Format RegMRM, Format MemMRM,
2421 RegisterClass RC, X86MemOperand x86memop> {
2422 let hasSideEffects = 0 in {
2423 def rr : I<0xF3, RegMRM, (outs RC:$dst), (ins RC:$src),
2424 !strconcat(mnemonic, "\t{$src, $dst|$dst, $src}"), []>,
2425 T8PS, VEX_4V, Sched<[WriteBLS]>;
2427 def rm : I<0xF3, MemMRM, (outs RC:$dst), (ins x86memop:$src),
2428 !strconcat(mnemonic, "\t{$src, $dst|$dst, $src}"), []>,
2429 T8PS, VEX_4V, Sched<[WriteBLS.Folded]>;
2433 let Predicates = [HasBMI], Defs = [EFLAGS] in {
2434 defm BLSR32 : bmi_bls<"blsr{l}", MRM1r, MRM1m, GR32, i32mem>;
2435 defm BLSR64 : bmi_bls<"blsr{q}", MRM1r, MRM1m, GR64, i64mem>, VEX_W;
2436 defm BLSMSK32 : bmi_bls<"blsmsk{l}", MRM2r, MRM2m, GR32, i32mem>;
2437 defm BLSMSK64 : bmi_bls<"blsmsk{q}", MRM2r, MRM2m, GR64, i64mem>, VEX_W;
2438 defm BLSI32 : bmi_bls<"blsi{l}", MRM3r, MRM3m, GR32, i32mem>;
2439 defm BLSI64 : bmi_bls<"blsi{q}", MRM3r, MRM3m, GR64, i64mem>, VEX_W;
2442 //===----------------------------------------------------------------------===//
2443 // Pattern fragments to auto generate BMI instructions.
2444 //===----------------------------------------------------------------------===//
2446 def or_flag_nocf : PatFrag<(ops node:$lhs, node:$rhs),
2447 (X86or_flag node:$lhs, node:$rhs), [{
2448 return hasNoCarryFlagUses(SDValue(N, 1));
2451 def xor_flag_nocf : PatFrag<(ops node:$lhs, node:$rhs),
2452 (X86xor_flag node:$lhs, node:$rhs), [{
2453 return hasNoCarryFlagUses(SDValue(N, 1));
2456 def and_flag_nocf : PatFrag<(ops node:$lhs, node:$rhs),
2457 (X86and_flag node:$lhs, node:$rhs), [{
2458 return hasNoCarryFlagUses(SDValue(N, 1));
2461 let Predicates = [HasBMI] in {
2462 // FIXME: patterns for the load versions are not implemented
2463 def : Pat<(and GR32:$src, (add GR32:$src, -1)),
2464 (BLSR32rr GR32:$src)>;
2465 def : Pat<(and GR64:$src, (add GR64:$src, -1)),
2466 (BLSR64rr GR64:$src)>;
2468 def : Pat<(xor GR32:$src, (add GR32:$src, -1)),
2469 (BLSMSK32rr GR32:$src)>;
2470 def : Pat<(xor GR64:$src, (add GR64:$src, -1)),
2471 (BLSMSK64rr GR64:$src)>;
2473 def : Pat<(and GR32:$src, (ineg GR32:$src)),
2474 (BLSI32rr GR32:$src)>;
2475 def : Pat<(and GR64:$src, (ineg GR64:$src)),
2476 (BLSI64rr GR64:$src)>;
2478 // Versions to match flag producing ops.
2479 def : Pat<(and_flag_nocf GR32:$src, (add GR32:$src, -1)),
2480 (BLSR32rr GR32:$src)>;
2481 def : Pat<(and_flag_nocf GR64:$src, (add GR64:$src, -1)),
2482 (BLSR64rr GR64:$src)>;
2484 def : Pat<(xor_flag_nocf GR32:$src, (add GR32:$src, -1)),
2485 (BLSMSK32rr GR32:$src)>;
2486 def : Pat<(xor_flag_nocf GR64:$src, (add GR64:$src, -1)),
2487 (BLSMSK64rr GR64:$src)>;
2489 def : Pat<(and_flag_nocf GR32:$src, (ineg GR32:$src)),
2490 (BLSI32rr GR32:$src)>;
2491 def : Pat<(and_flag_nocf GR64:$src, (ineg GR64:$src)),
2492 (BLSI64rr GR64:$src)>;
2495 multiclass bmi_bextr<bits<8> opc, string mnemonic, RegisterClass RC,
2496 X86MemOperand x86memop, SDNode OpNode,
2497 PatFrag ld_frag, X86FoldableSchedWrite Sched> {
2498 def rr : I<opc, MRMSrcReg4VOp3, (outs RC:$dst), (ins RC:$src1, RC:$src2),
2499 !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2500 [(set RC:$dst, (OpNode RC:$src1, RC:$src2)), (implicit EFLAGS)]>,
2501 T8PS, VEX, Sched<[Sched]>;
2502 def rm : I<opc, MRMSrcMem4VOp3, (outs RC:$dst), (ins x86memop:$src1, RC:$src2),
2503 !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2504 [(set RC:$dst, (OpNode (ld_frag addr:$src1), RC:$src2)),
2505 (implicit EFLAGS)]>, T8PS, VEX,
2506 Sched<[Sched.Folded,
2508 ReadDefault, ReadDefault, ReadDefault, ReadDefault,
2511 Sched.ReadAfterFold]>;
2514 let Predicates = [HasBMI], Defs = [EFLAGS] in {
2515 defm BEXTR32 : bmi_bextr<0xF7, "bextr{l}", GR32, i32mem,
2516 X86bextr, loadi32, WriteBEXTR>;
2517 defm BEXTR64 : bmi_bextr<0xF7, "bextr{q}", GR64, i64mem,
2518 X86bextr, loadi64, WriteBEXTR>, VEX_W;
2521 multiclass bmi_bzhi<bits<8> opc, string mnemonic, RegisterClass RC,
2522 X86MemOperand x86memop, Intrinsic Int,
2523 PatFrag ld_frag, X86FoldableSchedWrite Sched> {
2524 def rr : I<opc, MRMSrcReg4VOp3, (outs RC:$dst), (ins RC:$src1, RC:$src2),
2525 !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2526 [(set RC:$dst, (Int RC:$src1, RC:$src2)), (implicit EFLAGS)]>,
2527 T8PS, VEX, Sched<[Sched]>;
2528 def rm : I<opc, MRMSrcMem4VOp3, (outs RC:$dst), (ins x86memop:$src1, RC:$src2),
2529 !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2530 [(set RC:$dst, (Int (ld_frag addr:$src1), RC:$src2)),
2531 (implicit EFLAGS)]>, T8PS, VEX,
2532 Sched<[Sched.Folded,
2534 ReadDefault, ReadDefault, ReadDefault, ReadDefault,
2537 Sched.ReadAfterFold]>;
2540 let Predicates = [HasBMI2], Defs = [EFLAGS] in {
2541 defm BZHI32 : bmi_bzhi<0xF5, "bzhi{l}", GR32, i32mem,
2542 X86bzhi, loadi32, WriteBZHI>;
2543 defm BZHI64 : bmi_bzhi<0xF5, "bzhi{q}", GR64, i64mem,
2544 X86bzhi, loadi64, WriteBZHI>, VEX_W;
2547 def CountTrailingOnes : SDNodeXForm<imm, [{
2548 // Count the trailing ones in the immediate.
2549 return getI8Imm(countTrailingOnes(N->getZExtValue()), SDLoc(N));
2552 def BEXTRMaskXForm : SDNodeXForm<imm, [{
2553 unsigned Length = countTrailingOnes(N->getZExtValue());
2554 return getI32Imm(Length << 8, SDLoc(N));
2557 def AndMask64 : ImmLeaf<i64, [{
2558 return isMask_64(Imm) && !isUInt<32>(Imm);
2561 // Use BEXTR for 64-bit 'and' with large immediate 'mask'.
2562 let Predicates = [HasBMI, NoBMI2, NoTBM] in {
2563 def : Pat<(and GR64:$src, AndMask64:$mask),
2564 (BEXTR64rr GR64:$src,
2565 (SUBREG_TO_REG (i64 0),
2566 (MOV32ri (BEXTRMaskXForm imm:$mask)), sub_32bit))>;
2567 def : Pat<(and (loadi64 addr:$src), AndMask64:$mask),
2568 (BEXTR64rm addr:$src,
2569 (SUBREG_TO_REG (i64 0),
2570 (MOV32ri (BEXTRMaskXForm imm:$mask)), sub_32bit))>;
2573 // Use BZHI for 64-bit 'and' with large immediate 'mask'.
2574 let Predicates = [HasBMI2, NoTBM] in {
2575 def : Pat<(and GR64:$src, AndMask64:$mask),
2576 (BZHI64rr GR64:$src,
2577 (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
2578 (MOV8ri (CountTrailingOnes imm:$mask)), sub_8bit))>;
2579 def : Pat<(and (loadi64 addr:$src), AndMask64:$mask),
2580 (BZHI64rm addr:$src,
2581 (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
2582 (MOV8ri (CountTrailingOnes imm:$mask)), sub_8bit))>;
2585 multiclass bmi_pdep_pext<string mnemonic, RegisterClass RC,
2586 X86MemOperand x86memop, Intrinsic Int,
2588 def rr : I<0xF5, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
2589 !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2590 [(set RC:$dst, (Int RC:$src1, RC:$src2))]>,
2591 VEX_4V, Sched<[WriteALU]>;
2592 def rm : I<0xF5, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
2593 !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2594 [(set RC:$dst, (Int RC:$src1, (ld_frag addr:$src2)))]>,
2595 VEX_4V, Sched<[WriteALU.Folded, WriteALU.ReadAfterFold]>;
2598 let Predicates = [HasBMI2] in {
2599 defm PDEP32 : bmi_pdep_pext<"pdep{l}", GR32, i32mem,
2600 int_x86_bmi_pdep_32, loadi32>, T8XD;
2601 defm PDEP64 : bmi_pdep_pext<"pdep{q}", GR64, i64mem,
2602 int_x86_bmi_pdep_64, loadi64>, T8XD, VEX_W;
2603 defm PEXT32 : bmi_pdep_pext<"pext{l}", GR32, i32mem,
2604 int_x86_bmi_pext_32, loadi32>, T8XS;
2605 defm PEXT64 : bmi_pdep_pext<"pext{q}", GR64, i64mem,
2606 int_x86_bmi_pext_64, loadi64>, T8XS, VEX_W;
2609 //===----------------------------------------------------------------------===//
2612 let Predicates = [HasTBM], Defs = [EFLAGS] in {
2614 multiclass tbm_ternary_imm<bits<8> opc, RegisterClass RC, string OpcodeStr,
2615 X86MemOperand x86memop, PatFrag ld_frag,
2616 SDNode OpNode, Operand immtype,
2617 SDPatternOperator immoperator,
2618 X86FoldableSchedWrite Sched> {
2619 def ri : Ii32<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, immtype:$cntl),
2620 !strconcat(OpcodeStr,
2621 "\t{$cntl, $src1, $dst|$dst, $src1, $cntl}"),
2622 [(set RC:$dst, (OpNode RC:$src1, immoperator:$cntl))]>,
2623 XOP, XOPA, Sched<[Sched]>;
2624 def mi : Ii32<opc, MRMSrcMem, (outs RC:$dst),
2625 (ins x86memop:$src1, immtype:$cntl),
2626 !strconcat(OpcodeStr,
2627 "\t{$cntl, $src1, $dst|$dst, $src1, $cntl}"),
2628 [(set RC:$dst, (OpNode (ld_frag addr:$src1), immoperator:$cntl))]>,
2629 XOP, XOPA, Sched<[Sched.Folded]>;
2632 defm BEXTRI32 : tbm_ternary_imm<0x10, GR32, "bextr{l}", i32mem, loadi32,
2633 X86bextr, i32imm, imm, WriteBEXTR>;
2634 let ImmT = Imm32S in
2635 defm BEXTRI64 : tbm_ternary_imm<0x10, GR64, "bextr{q}", i64mem, loadi64,
2636 X86bextr, i64i32imm,
2637 i64immSExt32, WriteBEXTR>, VEX_W;
2639 multiclass tbm_binary_rm<bits<8> opc, Format FormReg, Format FormMem,
2640 RegisterClass RC, string OpcodeStr,
2641 X86MemOperand x86memop, X86FoldableSchedWrite Sched> {
2642 let hasSideEffects = 0 in {
2643 def rr : I<opc, FormReg, (outs RC:$dst), (ins RC:$src),
2644 !strconcat(OpcodeStr,"\t{$src, $dst|$dst, $src}"), []>,
2645 XOP_4V, XOP9, Sched<[Sched]>;
2647 def rm : I<opc, FormMem, (outs RC:$dst), (ins x86memop:$src),
2648 !strconcat(OpcodeStr,"\t{$src, $dst|$dst, $src}"), []>,
2649 XOP_4V, XOP9, Sched<[Sched.Folded]>;
2653 multiclass tbm_binary_intr<bits<8> opc, string OpcodeStr,
2654 X86FoldableSchedWrite Sched,
2655 Format FormReg, Format FormMem> {
2656 defm NAME#32 : tbm_binary_rm<opc, FormReg, FormMem, GR32, OpcodeStr#"{l}",
2658 defm NAME#64 : tbm_binary_rm<opc, FormReg, FormMem, GR64, OpcodeStr#"{q}",
2659 i64mem, Sched>, VEX_W;
2662 defm BLCFILL : tbm_binary_intr<0x01, "blcfill", WriteALU, MRM1r, MRM1m>;
2663 defm BLCI : tbm_binary_intr<0x02, "blci", WriteALU, MRM6r, MRM6m>;
2664 defm BLCIC : tbm_binary_intr<0x01, "blcic", WriteALU, MRM5r, MRM5m>;
2665 defm BLCMSK : tbm_binary_intr<0x02, "blcmsk", WriteALU, MRM1r, MRM1m>;
2666 defm BLCS : tbm_binary_intr<0x01, "blcs", WriteALU, MRM3r, MRM3m>;
2667 defm BLSFILL : tbm_binary_intr<0x01, "blsfill", WriteALU, MRM2r, MRM2m>;
2668 defm BLSIC : tbm_binary_intr<0x01, "blsic", WriteALU, MRM6r, MRM6m>;
2669 defm T1MSKC : tbm_binary_intr<0x01, "t1mskc", WriteALU, MRM7r, MRM7m>;
2670 defm TZMSK : tbm_binary_intr<0x01, "tzmsk", WriteALU, MRM4r, MRM4m>;
2673 // Use BEXTRI for 64-bit 'and' with large immediate 'mask'.
2674 let Predicates = [HasTBM] in {
2675 def : Pat<(and GR64:$src, AndMask64:$mask),
2676 (BEXTRI64ri GR64:$src, (BEXTRMaskXForm imm:$mask))>;
2678 def : Pat<(and (loadi64 addr:$src), AndMask64:$mask),
2679 (BEXTRI64mi addr:$src, (BEXTRMaskXForm imm:$mask))>;
2682 //===----------------------------------------------------------------------===//
2683 // Lightweight Profiling Instructions
2685 let Predicates = [HasLWP], SchedRW = [WriteSystem] in {
2687 def LLWPCB : I<0x12, MRM0r, (outs), (ins GR32:$src), "llwpcb\t$src",
2688 [(int_x86_llwpcb GR32:$src)]>, XOP, XOP9;
2689 def SLWPCB : I<0x12, MRM1r, (outs GR32:$dst), (ins), "slwpcb\t$dst",
2690 [(set GR32:$dst, (int_x86_slwpcb))]>, XOP, XOP9;
2692 def LLWPCB64 : I<0x12, MRM0r, (outs), (ins GR64:$src), "llwpcb\t$src",
2693 [(int_x86_llwpcb GR64:$src)]>, XOP, XOP9, VEX_W;
2694 def SLWPCB64 : I<0x12, MRM1r, (outs GR64:$dst), (ins), "slwpcb\t$dst",
2695 [(set GR64:$dst, (int_x86_slwpcb))]>, XOP, XOP9, VEX_W;
2697 multiclass lwpins_intr<RegisterClass RC> {
2698 def rri : Ii32<0x12, MRM0r, (outs), (ins RC:$src0, GR32:$src1, i32imm:$cntl),
2699 "lwpins\t{$cntl, $src1, $src0|$src0, $src1, $cntl}",
2700 [(set EFLAGS, (X86lwpins RC:$src0, GR32:$src1, timm:$cntl))]>,
2703 def rmi : Ii32<0x12, MRM0m, (outs), (ins RC:$src0, i32mem:$src1, i32imm:$cntl),
2704 "lwpins\t{$cntl, $src1, $src0|$src0, $src1, $cntl}",
2705 [(set EFLAGS, (X86lwpins RC:$src0, (loadi32 addr:$src1), timm:$cntl))]>,
2709 let Defs = [EFLAGS] in {
2710 defm LWPINS32 : lwpins_intr<GR32>;
2711 defm LWPINS64 : lwpins_intr<GR64>, VEX_W;
2714 multiclass lwpval_intr<RegisterClass RC, Intrinsic Int> {
2715 def rri : Ii32<0x12, MRM1r, (outs), (ins RC:$src0, GR32:$src1, i32imm:$cntl),
2716 "lwpval\t{$cntl, $src1, $src0|$src0, $src1, $cntl}",
2717 [(Int RC:$src0, GR32:$src1, timm:$cntl)]>, XOP_4V, XOPA;
2719 def rmi : Ii32<0x12, MRM1m, (outs), (ins RC:$src0, i32mem:$src1, i32imm:$cntl),
2720 "lwpval\t{$cntl, $src1, $src0|$src0, $src1, $cntl}",
2721 [(Int RC:$src0, (loadi32 addr:$src1), timm:$cntl)]>,
2725 defm LWPVAL32 : lwpval_intr<GR32, int_x86_lwpval32>;
2726 defm LWPVAL64 : lwpval_intr<GR64, int_x86_lwpval64>, VEX_W;
2728 } // HasLWP, SchedRW
2730 //===----------------------------------------------------------------------===//
2731 // MONITORX/MWAITX Instructions
2733 let SchedRW = [ WriteSystem ] in {
2734 let Uses = [ EAX, ECX, EDX ] in
2735 def MONITORX32rrr : I<0x01, MRM_FA, (outs), (ins), "monitorx", []>,
2736 TB, Requires<[ HasMWAITX, Not64BitMode ]>;
2737 let Uses = [ RAX, ECX, EDX ] in
2738 def MONITORX64rrr : I<0x01, MRM_FA, (outs), (ins), "monitorx", []>,
2739 TB, Requires<[ HasMWAITX, In64BitMode ]>;
2741 let Uses = [ ECX, EAX, EBX ] in {
2742 def MWAITXrrr : I<0x01, MRM_FB, (outs), (ins), "mwaitx",
2743 [(int_x86_mwaitx ECX, EAX, EBX)]>,
2744 TB, Requires<[ HasMWAITX ]>;
2748 def : InstAlias<"mwaitx\t{%eax, %ecx, %ebx|ebx, ecx, eax}", (MWAITXrrr)>,
2749 Requires<[ Not64BitMode ]>;
2750 def : InstAlias<"mwaitx\t{%rax, %rcx, %rbx|rbx, rcx, rax}", (MWAITXrrr)>,
2751 Requires<[ In64BitMode ]>;
2753 def : InstAlias<"monitorx\t{%eax, %ecx, %edx|edx, ecx, eax}", (MONITORX32rrr)>,
2754 Requires<[ Not64BitMode ]>;
2755 def : InstAlias<"monitorx\t{%rax, %rcx, %rdx|rdx, rcx, rax}", (MONITORX64rrr)>,
2756 Requires<[ In64BitMode ]>;
2758 //===----------------------------------------------------------------------===//
2759 // WAITPKG Instructions
2761 let SchedRW = [WriteSystem] in {
2762 def UMONITOR16 : I<0xAE, MRM6r, (outs), (ins GR16:$src),
2763 "umonitor\t$src", [(int_x86_umonitor GR16:$src)]>,
2764 XS, AdSize16, Requires<[HasWAITPKG, Not64BitMode]>;
2765 def UMONITOR32 : I<0xAE, MRM6r, (outs), (ins GR32:$src),
2766 "umonitor\t$src", [(int_x86_umonitor GR32:$src)]>,
2767 XS, AdSize32, Requires<[HasWAITPKG]>;
2768 def UMONITOR64 : I<0xAE, MRM6r, (outs), (ins GR64:$src),
2769 "umonitor\t$src", [(int_x86_umonitor GR64:$src)]>,
2770 XS, AdSize64, Requires<[HasWAITPKG, In64BitMode]>;
2771 let Uses = [EAX, EDX], Defs = [EFLAGS] in {
2772 def UMWAIT : I<0xAE, MRM6r,
2773 (outs), (ins GR32orGR64:$src), "umwait\t$src",
2774 [(set EFLAGS, (X86umwait GR32orGR64:$src, EDX, EAX))]>,
2775 XD, Requires<[HasWAITPKG]>;
2776 def TPAUSE : I<0xAE, MRM6r,
2777 (outs), (ins GR32orGR64:$src), "tpause\t$src",
2778 [(set EFLAGS, (X86tpause GR32orGR64:$src, EDX, EAX))]>,
2779 PD, Requires<[HasWAITPKG]>, NotMemoryFoldable;
2783 //===----------------------------------------------------------------------===//
2784 // MOVDIRI - Move doubleword/quadword as direct store
2786 let SchedRW = [WriteStore] in {
2787 def MOVDIRI32 : I<0xF9, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
2788 "movdiri\t{$src, $dst|$dst, $src}",
2789 [(int_x86_directstore32 addr:$dst, GR32:$src)]>,
2790 T8, Requires<[HasMOVDIRI]>;
2791 def MOVDIRI64 : RI<0xF9, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
2792 "movdiri\t{$src, $dst|$dst, $src}",
2793 [(int_x86_directstore64 addr:$dst, GR64:$src)]>,
2794 T8, Requires<[In64BitMode, HasMOVDIRI]>;
2797 //===----------------------------------------------------------------------===//
2798 // MOVDIR64B - Move 64 bytes as direct store
2800 let SchedRW = [WriteStore] in {
2801 def MOVDIR64B16 : I<0xF8, MRMSrcMem, (outs), (ins GR16:$dst, i512mem:$src),
2802 "movdir64b\t{$src, $dst|$dst, $src}", []>,
2803 T8PD, AdSize16, Requires<[HasMOVDIR64B, Not64BitMode]>;
2804 def MOVDIR64B32 : I<0xF8, MRMSrcMem, (outs), (ins GR32:$dst, i512mem:$src),
2805 "movdir64b\t{$src, $dst|$dst, $src}",
2806 [(int_x86_movdir64b GR32:$dst, addr:$src)]>,
2807 T8PD, AdSize32, Requires<[HasMOVDIR64B]>;
2808 def MOVDIR64B64 : I<0xF8, MRMSrcMem, (outs), (ins GR64:$dst, i512mem:$src),
2809 "movdir64b\t{$src, $dst|$dst, $src}",
2810 [(int_x86_movdir64b GR64:$dst, addr:$src)]>,
2811 T8PD, AdSize64, Requires<[HasMOVDIR64B, In64BitMode]>;
2814 //===----------------------------------------------------------------------===//
2815 // ENQCMD/S - Enqueue 64-byte command as user with 64-byte write atomicity
2817 let SchedRW = [WriteStore], Defs = [EFLAGS] in {
2818 def ENQCMD16 : I<0xF8, MRMSrcMem, (outs), (ins GR16:$dst, i512mem:$src),
2819 "enqcmd\t{$src, $dst|$dst, $src}",
2820 [(set EFLAGS, (X86enqcmd GR16:$dst, addr:$src))]>,
2821 T8XD, AdSize16, Requires<[HasENQCMD, Not64BitMode]>;
2822 def ENQCMD32 : I<0xF8, MRMSrcMem, (outs), (ins GR32:$dst, i512mem:$src),
2823 "enqcmd\t{$src, $dst|$dst, $src}",
2824 [(set EFLAGS, (X86enqcmd GR32:$dst, addr:$src))]>,
2825 T8XD, AdSize32, Requires<[HasENQCMD]>;
2826 def ENQCMD64 : I<0xF8, MRMSrcMem, (outs), (ins GR64:$dst, i512mem:$src),
2827 "enqcmd\t{$src, $dst|$dst, $src}",
2828 [(set EFLAGS, (X86enqcmd GR64:$dst, addr:$src))]>,
2829 T8XD, AdSize64, Requires<[HasENQCMD, In64BitMode]>;
2831 def ENQCMDS16 : I<0xF8, MRMSrcMem, (outs), (ins GR16:$dst, i512mem:$src),
2832 "enqcmds\t{$src, $dst|$dst, $src}",
2833 [(set EFLAGS, (X86enqcmds GR16:$dst, addr:$src))]>,
2834 T8XS, AdSize16, Requires<[HasENQCMD, Not64BitMode]>;
2835 def ENQCMDS32 : I<0xF8, MRMSrcMem, (outs), (ins GR32:$dst, i512mem:$src),
2836 "enqcmds\t{$src, $dst|$dst, $src}",
2837 [(set EFLAGS, (X86enqcmds GR32:$dst, addr:$src))]>,
2838 T8XS, AdSize32, Requires<[HasENQCMD]>;
2839 def ENQCMDS64 : I<0xF8, MRMSrcMem, (outs), (ins GR64:$dst, i512mem:$src),
2840 "enqcmds\t{$src, $dst|$dst, $src}",
2841 [(set EFLAGS, (X86enqcmds GR64:$dst, addr:$src))]>,
2842 T8XS, AdSize64, Requires<[HasENQCMD, In64BitMode]>;
2845 //===----------------------------------------------------------------------===//
2846 // CLZERO Instruction
2848 let SchedRW = [WriteSystem] in {
2850 def CLZERO32r : I<0x01, MRM_FC, (outs), (ins), "clzero", []>,
2851 TB, Requires<[HasCLZERO, Not64BitMode]>;
2853 def CLZERO64r : I<0x01, MRM_FC, (outs), (ins), "clzero", []>,
2854 TB, Requires<[HasCLZERO, In64BitMode]>;
2857 def : InstAlias<"clzero\t{%eax|eax}", (CLZERO32r)>, Requires<[Not64BitMode]>;
2858 def : InstAlias<"clzero\t{%rax|rax}", (CLZERO64r)>, Requires<[In64BitMode]>;
2860 //===----------------------------------------------------------------------===//
2861 // Pattern fragments to auto generate TBM instructions.
2862 //===----------------------------------------------------------------------===//
2864 let Predicates = [HasTBM] in {
2865 // FIXME: patterns for the load versions are not implemented
2866 def : Pat<(and GR32:$src, (add GR32:$src, 1)),
2867 (BLCFILL32rr GR32:$src)>;
2868 def : Pat<(and GR64:$src, (add GR64:$src, 1)),
2869 (BLCFILL64rr GR64:$src)>;
2871 def : Pat<(or GR32:$src, (not (add GR32:$src, 1))),
2872 (BLCI32rr GR32:$src)>;
2873 def : Pat<(or GR64:$src, (not (add GR64:$src, 1))),
2874 (BLCI64rr GR64:$src)>;
2876 // Extra patterns because opt can optimize the above patterns to this.
2877 def : Pat<(or GR32:$src, (sub -2, GR32:$src)),
2878 (BLCI32rr GR32:$src)>;
2879 def : Pat<(or GR64:$src, (sub -2, GR64:$src)),
2880 (BLCI64rr GR64:$src)>;
2882 def : Pat<(and (not GR32:$src), (add GR32:$src, 1)),
2883 (BLCIC32rr GR32:$src)>;
2884 def : Pat<(and (not GR64:$src), (add GR64:$src, 1)),
2885 (BLCIC64rr GR64:$src)>;
2887 def : Pat<(xor GR32:$src, (add GR32:$src, 1)),
2888 (BLCMSK32rr GR32:$src)>;
2889 def : Pat<(xor GR64:$src, (add GR64:$src, 1)),
2890 (BLCMSK64rr GR64:$src)>;
2892 def : Pat<(or GR32:$src, (add GR32:$src, 1)),
2893 (BLCS32rr GR32:$src)>;
2894 def : Pat<(or GR64:$src, (add GR64:$src, 1)),
2895 (BLCS64rr GR64:$src)>;
2897 def : Pat<(or GR32:$src, (add GR32:$src, -1)),
2898 (BLSFILL32rr GR32:$src)>;
2899 def : Pat<(or GR64:$src, (add GR64:$src, -1)),
2900 (BLSFILL64rr GR64:$src)>;
2902 def : Pat<(or (not GR32:$src), (add GR32:$src, -1)),
2903 (BLSIC32rr GR32:$src)>;
2904 def : Pat<(or (not GR64:$src), (add GR64:$src, -1)),
2905 (BLSIC64rr GR64:$src)>;
2907 def : Pat<(or (not GR32:$src), (add GR32:$src, 1)),
2908 (T1MSKC32rr GR32:$src)>;
2909 def : Pat<(or (not GR64:$src), (add GR64:$src, 1)),
2910 (T1MSKC64rr GR64:$src)>;
2912 def : Pat<(and (not GR32:$src), (add GR32:$src, -1)),
2913 (TZMSK32rr GR32:$src)>;
2914 def : Pat<(and (not GR64:$src), (add GR64:$src, -1)),
2915 (TZMSK64rr GR64:$src)>;
2917 // Patterns to match flag producing ops.
2918 def : Pat<(or_flag_nocf GR32:$src, (not (add GR32:$src, 1))),
2919 (BLCI32rr GR32:$src)>;
2920 def : Pat<(or_flag_nocf GR64:$src, (not (add GR64:$src, 1))),
2921 (BLCI64rr GR64:$src)>;
2923 // Extra patterns because opt can optimize the above patterns to this.
2924 def : Pat<(or_flag_nocf GR32:$src, (sub -2, GR32:$src)),
2925 (BLCI32rr GR32:$src)>;
2926 def : Pat<(or_flag_nocf GR64:$src, (sub -2, GR64:$src)),
2927 (BLCI64rr GR64:$src)>;
2929 def : Pat<(and_flag_nocf (not GR32:$src), (add GR32:$src, 1)),
2930 (BLCIC32rr GR32:$src)>;
2931 def : Pat<(and_flag_nocf (not GR64:$src), (add GR64:$src, 1)),
2932 (BLCIC64rr GR64:$src)>;
2934 def : Pat<(xor_flag_nocf GR32:$src, (add GR32:$src, 1)),
2935 (BLCMSK32rr GR32:$src)>;
2936 def : Pat<(xor_flag_nocf GR64:$src, (add GR64:$src, 1)),
2937 (BLCMSK64rr GR64:$src)>;
2939 def : Pat<(or_flag_nocf GR32:$src, (add GR32:$src, 1)),
2940 (BLCS32rr GR32:$src)>;
2941 def : Pat<(or_flag_nocf GR64:$src, (add GR64:$src, 1)),
2942 (BLCS64rr GR64:$src)>;
2944 def : Pat<(or_flag_nocf GR32:$src, (add GR32:$src, -1)),
2945 (BLSFILL32rr GR32:$src)>;
2946 def : Pat<(or_flag_nocf GR64:$src, (add GR64:$src, -1)),
2947 (BLSFILL64rr GR64:$src)>;
2949 def : Pat<(or_flag_nocf (not GR32:$src), (add GR32:$src, -1)),
2950 (BLSIC32rr GR32:$src)>;
2951 def : Pat<(or_flag_nocf (not GR64:$src), (add GR64:$src, -1)),
2952 (BLSIC64rr GR64:$src)>;
2954 def : Pat<(or_flag_nocf (not GR32:$src), (add GR32:$src, 1)),
2955 (T1MSKC32rr GR32:$src)>;
2956 def : Pat<(or_flag_nocf (not GR64:$src), (add GR64:$src, 1)),
2957 (T1MSKC64rr GR64:$src)>;
2959 def : Pat<(and_flag_nocf (not GR32:$src), (add GR32:$src, -1)),
2960 (TZMSK32rr GR32:$src)>;
2961 def : Pat<(and_flag_nocf (not GR64:$src), (add GR64:$src, -1)),
2962 (TZMSK64rr GR64:$src)>;
2965 //===----------------------------------------------------------------------===//
2966 // Memory Instructions
2969 let Predicates = [HasCLFLUSHOPT], SchedRW = [WriteLoad] in
2970 def CLFLUSHOPT : I<0xAE, MRM7m, (outs), (ins i8mem:$src),
2971 "clflushopt\t$src", [(int_x86_clflushopt addr:$src)]>, PD;
2973 let Predicates = [HasCLWB], SchedRW = [WriteLoad] in
2974 def CLWB : I<0xAE, MRM6m, (outs), (ins i8mem:$src), "clwb\t$src",
2975 [(int_x86_clwb addr:$src)]>, PD, NotMemoryFoldable;
2977 let Predicates = [HasCLDEMOTE], SchedRW = [WriteLoad] in
2978 def CLDEMOTE : I<0x1C, MRM0m, (outs), (ins i8mem:$src), "cldemote\t$src",
2979 [(int_x86_cldemote addr:$src)]>, TB;
2981 //===----------------------------------------------------------------------===//
2983 //===----------------------------------------------------------------------===//
2985 include "X86InstrArithmetic.td"
2986 include "X86InstrCMovSetCC.td"
2987 include "X86InstrExtension.td"
2988 include "X86InstrControl.td"
2989 include "X86InstrShiftRotate.td"
2991 // X87 Floating Point Stack.
2992 include "X86InstrFPStack.td"
2994 // SIMD support (SSE, MMX and AVX)
2995 include "X86InstrFragmentsSIMD.td"
2997 // FMA - Fused Multiply-Add support (requires FMA)
2998 include "X86InstrFMA.td"
3001 include "X86InstrXOP.td"
3003 // SSE, MMX and 3DNow! vector support.
3004 include "X86InstrSSE.td"
3005 include "X86InstrAVX512.td"
3006 include "X86InstrMMX.td"
3007 include "X86Instr3DNow.td"
3010 include "X86InstrMPX.td"
3012 include "X86InstrVMX.td"
3013 include "X86InstrSVM.td"
3015 include "X86InstrTSX.td"
3016 include "X86InstrSGX.td"
3018 // System instructions.
3019 include "X86InstrSystem.td"
3021 // Compiler Pseudo Instructions and Pat Patterns
3022 include "X86InstrCompiler.td"
3023 include "X86InstrVecCompiler.td"
3025 //===----------------------------------------------------------------------===//
3026 // Assembler Mnemonic Aliases
3027 //===----------------------------------------------------------------------===//
3029 def : MnemonicAlias<"call", "callw", "att">, Requires<[In16BitMode]>;
3030 def : MnemonicAlias<"call", "calll", "att">, Requires<[In32BitMode]>;
3031 def : MnemonicAlias<"call", "callq", "att">, Requires<[In64BitMode]>;
3033 def : MnemonicAlias<"cbw", "cbtw", "att">;
3034 def : MnemonicAlias<"cwde", "cwtl", "att">;
3035 def : MnemonicAlias<"cwd", "cwtd", "att">;
3036 def : MnemonicAlias<"cdq", "cltd", "att">;
3037 def : MnemonicAlias<"cdqe", "cltq", "att">;
3038 def : MnemonicAlias<"cqo", "cqto", "att">;
3040 // In 64-bit mode lret maps to lretl; it is not ambiguous with lretq.
3041 def : MnemonicAlias<"lret", "lretw", "att">, Requires<[In16BitMode]>;
3042 def : MnemonicAlias<"lret", "lretl", "att">, Requires<[Not16BitMode]>;
3044 def : MnemonicAlias<"leavel", "leave", "att">, Requires<[Not64BitMode]>;
3045 def : MnemonicAlias<"leaveq", "leave", "att">, Requires<[In64BitMode]>;
3047 def : MnemonicAlias<"loopz", "loope">;
3048 def : MnemonicAlias<"loopnz", "loopne">;
3050 def : MnemonicAlias<"pop", "popw", "att">, Requires<[In16BitMode]>;
3051 def : MnemonicAlias<"pop", "popl", "att">, Requires<[In32BitMode]>;
3052 def : MnemonicAlias<"pop", "popq", "att">, Requires<[In64BitMode]>;
3053 def : MnemonicAlias<"popf", "popfw", "att">, Requires<[In16BitMode]>;
3054 def : MnemonicAlias<"popf", "popfl", "att">, Requires<[In32BitMode]>;
3055 def : MnemonicAlias<"popf", "popfq", "att">, Requires<[In64BitMode]>;
3056 def : MnemonicAlias<"popf", "popfq", "intel">, Requires<[In64BitMode]>;
3057 def : MnemonicAlias<"popfd", "popfl", "att">;
3058 def : MnemonicAlias<"popfw", "popf", "intel">, Requires<[In32BitMode]>;
3059 def : MnemonicAlias<"popfw", "popf", "intel">, Requires<[In64BitMode]>;
3061 // FIXME: This is wrong for "push reg". "push %bx" should turn into pushw in
3062 // all modes. However: "push (addr)" and "push $42" should default to
3063 // pushl/pushq depending on the current mode. Similar for "pop %bx"
3064 def : MnemonicAlias<"push", "pushw", "att">, Requires<[In16BitMode]>;
3065 def : MnemonicAlias<"push", "pushl", "att">, Requires<[In32BitMode]>;
3066 def : MnemonicAlias<"push", "pushq", "att">, Requires<[In64BitMode]>;
3067 def : MnemonicAlias<"pushf", "pushfw", "att">, Requires<[In16BitMode]>;
3068 def : MnemonicAlias<"pushf", "pushfl", "att">, Requires<[In32BitMode]>;
3069 def : MnemonicAlias<"pushf", "pushfq", "att">, Requires<[In64BitMode]>;
3070 def : MnemonicAlias<"pushf", "pushfq", "intel">, Requires<[In64BitMode]>;
3071 def : MnemonicAlias<"pushfd", "pushfl", "att">;
3072 def : MnemonicAlias<"pushfw", "pushf", "intel">, Requires<[In32BitMode]>;
3073 def : MnemonicAlias<"pushfw", "pushf", "intel">, Requires<[In64BitMode]>;
3075 def : MnemonicAlias<"popad", "popal", "intel">, Requires<[Not64BitMode]>;
3076 def : MnemonicAlias<"pushad", "pushal", "intel">, Requires<[Not64BitMode]>;
3077 def : MnemonicAlias<"popa", "popaw", "intel">, Requires<[In16BitMode]>;
3078 def : MnemonicAlias<"pusha", "pushaw", "intel">, Requires<[In16BitMode]>;
3079 def : MnemonicAlias<"popa", "popal", "intel">, Requires<[In32BitMode]>;
3080 def : MnemonicAlias<"pusha", "pushal", "intel">, Requires<[In32BitMode]>;
3082 def : MnemonicAlias<"popa", "popaw", "att">, Requires<[In16BitMode]>;
3083 def : MnemonicAlias<"pusha", "pushaw", "att">, Requires<[In16BitMode]>;
3084 def : MnemonicAlias<"popa", "popal", "att">, Requires<[In32BitMode]>;
3085 def : MnemonicAlias<"pusha", "pushal", "att">, Requires<[In32BitMode]>;
3087 def : MnemonicAlias<"repe", "rep">;
3088 def : MnemonicAlias<"repz", "rep">;
3089 def : MnemonicAlias<"repnz", "repne">;
3091 def : MnemonicAlias<"ret", "retw", "att">, Requires<[In16BitMode]>;
3092 def : MnemonicAlias<"ret", "retl", "att">, Requires<[In32BitMode]>;
3093 def : MnemonicAlias<"ret", "retq", "att">, Requires<[In64BitMode]>;
3095 // Apply 'ret' behavior to 'retn'
3096 def : MnemonicAlias<"retn", "retw", "att">, Requires<[In16BitMode]>;
3097 def : MnemonicAlias<"retn", "retl", "att">, Requires<[In32BitMode]>;
3098 def : MnemonicAlias<"retn", "retq", "att">, Requires<[In64BitMode]>;
3099 def : MnemonicAlias<"retn", "ret", "intel">;
3101 def : MnemonicAlias<"sal", "shl", "intel">;
3102 def : MnemonicAlias<"salb", "shlb", "att">;
3103 def : MnemonicAlias<"salw", "shlw", "att">;
3104 def : MnemonicAlias<"sall", "shll", "att">;
3105 def : MnemonicAlias<"salq", "shlq", "att">;
3107 def : MnemonicAlias<"smovb", "movsb", "att">;
3108 def : MnemonicAlias<"smovw", "movsw", "att">;
3109 def : MnemonicAlias<"smovl", "movsl", "att">;
3110 def : MnemonicAlias<"smovq", "movsq", "att">;
3112 def : MnemonicAlias<"ud2a", "ud2", "att">;
3113 def : MnemonicAlias<"verrw", "verr", "att">;
3115 // MS recognizes 'xacquire'/'xrelease' as 'acquire'/'release'
3116 def : MnemonicAlias<"acquire", "xacquire", "intel">;
3117 def : MnemonicAlias<"release", "xrelease", "intel">;
3119 // System instruction aliases.
3120 def : MnemonicAlias<"iret", "iretw", "att">, Requires<[In16BitMode]>;
3121 def : MnemonicAlias<"iret", "iretl", "att">, Requires<[Not16BitMode]>;
3122 def : MnemonicAlias<"sysret", "sysretl", "att">;
3123 def : MnemonicAlias<"sysexit", "sysexitl", "att">;
3125 def : MnemonicAlias<"lgdt", "lgdtw", "att">, Requires<[In16BitMode]>;
3126 def : MnemonicAlias<"lgdt", "lgdtl", "att">, Requires<[In32BitMode]>;
3127 def : MnemonicAlias<"lgdt", "lgdtq", "att">, Requires<[In64BitMode]>;
3128 def : MnemonicAlias<"lidt", "lidtw", "att">, Requires<[In16BitMode]>;
3129 def : MnemonicAlias<"lidt", "lidtl", "att">, Requires<[In32BitMode]>;
3130 def : MnemonicAlias<"lidt", "lidtq", "att">, Requires<[In64BitMode]>;
3131 def : MnemonicAlias<"sgdt", "sgdtw", "att">, Requires<[In16BitMode]>;
3132 def : MnemonicAlias<"sgdt", "sgdtl", "att">, Requires<[In32BitMode]>;
3133 def : MnemonicAlias<"sgdt", "sgdtq", "att">, Requires<[In64BitMode]>;
3134 def : MnemonicAlias<"sidt", "sidtw", "att">, Requires<[In16BitMode]>;
3135 def : MnemonicAlias<"sidt", "sidtl", "att">, Requires<[In32BitMode]>;
3136 def : MnemonicAlias<"sidt", "sidtq", "att">, Requires<[In64BitMode]>;
3137 def : MnemonicAlias<"lgdt", "lgdtw", "intel">, Requires<[In16BitMode]>;
3138 def : MnemonicAlias<"lgdt", "lgdtd", "intel">, Requires<[In32BitMode]>;
3139 def : MnemonicAlias<"lidt", "lidtw", "intel">, Requires<[In16BitMode]>;
3140 def : MnemonicAlias<"lidt", "lidtd", "intel">, Requires<[In32BitMode]>;
3141 def : MnemonicAlias<"sgdt", "sgdtw", "intel">, Requires<[In16BitMode]>;
3142 def : MnemonicAlias<"sgdt", "sgdtd", "intel">, Requires<[In32BitMode]>;
3143 def : MnemonicAlias<"sidt", "sidtw", "intel">, Requires<[In16BitMode]>;
3144 def : MnemonicAlias<"sidt", "sidtd", "intel">, Requires<[In32BitMode]>;
3147 // Floating point stack aliases.
3148 def : MnemonicAlias<"fcmovz", "fcmove", "att">;
3149 def : MnemonicAlias<"fcmova", "fcmovnbe", "att">;
3150 def : MnemonicAlias<"fcmovnae", "fcmovb", "att">;
3151 def : MnemonicAlias<"fcmovna", "fcmovbe", "att">;
3152 def : MnemonicAlias<"fcmovae", "fcmovnb", "att">;
3153 def : MnemonicAlias<"fcomip", "fcompi">;
3154 def : MnemonicAlias<"fildq", "fildll", "att">;
3155 def : MnemonicAlias<"fistpq", "fistpll", "att">;
3156 def : MnemonicAlias<"fisttpq", "fisttpll", "att">;
3157 def : MnemonicAlias<"fldcww", "fldcw", "att">;
3158 def : MnemonicAlias<"fnstcww", "fnstcw", "att">;
3159 def : MnemonicAlias<"fnstsww", "fnstsw", "att">;
3160 def : MnemonicAlias<"fucomip", "fucompi">;
3161 def : MnemonicAlias<"fwait", "wait">;
3163 def : MnemonicAlias<"fxsaveq", "fxsave64", "att">;
3164 def : MnemonicAlias<"fxrstorq", "fxrstor64", "att">;
3165 def : MnemonicAlias<"xsaveq", "xsave64", "att">;
3166 def : MnemonicAlias<"xrstorq", "xrstor64", "att">;
3167 def : MnemonicAlias<"xsaveoptq", "xsaveopt64", "att">;
3168 def : MnemonicAlias<"xrstorsq", "xrstors64", "att">;
3169 def : MnemonicAlias<"xsavecq", "xsavec64", "att">;
3170 def : MnemonicAlias<"xsavesq", "xsaves64", "att">;
3172 class CondCodeAlias<string Prefix,string Suffix, string OldCond, string NewCond,
3174 : MnemonicAlias<!strconcat(Prefix, OldCond, Suffix),
3175 !strconcat(Prefix, NewCond, Suffix), VariantName>;
3177 /// IntegerCondCodeMnemonicAlias - This multiclass defines a bunch of
3178 /// MnemonicAlias's that canonicalize the condition code in a mnemonic, for
3179 /// example "setz" -> "sete".
3180 multiclass IntegerCondCodeMnemonicAlias<string Prefix, string Suffix,
3182 def C : CondCodeAlias<Prefix, Suffix, "c", "b", V>; // setc -> setb
3183 def Z : CondCodeAlias<Prefix, Suffix, "z" , "e", V>; // setz -> sete
3184 def NA : CondCodeAlias<Prefix, Suffix, "na", "be", V>; // setna -> setbe
3185 def NB : CondCodeAlias<Prefix, Suffix, "nb", "ae", V>; // setnb -> setae
3186 def NC : CondCodeAlias<Prefix, Suffix, "nc", "ae", V>; // setnc -> setae
3187 def NG : CondCodeAlias<Prefix, Suffix, "ng", "le", V>; // setng -> setle
3188 def NL : CondCodeAlias<Prefix, Suffix, "nl", "ge", V>; // setnl -> setge
3189 def NZ : CondCodeAlias<Prefix, Suffix, "nz", "ne", V>; // setnz -> setne
3190 def PE : CondCodeAlias<Prefix, Suffix, "pe", "p", V>; // setpe -> setp
3191 def PO : CondCodeAlias<Prefix, Suffix, "po", "np", V>; // setpo -> setnp
3193 def NAE : CondCodeAlias<Prefix, Suffix, "nae", "b", V>; // setnae -> setb
3194 def NBE : CondCodeAlias<Prefix, Suffix, "nbe", "a", V>; // setnbe -> seta
3195 def NGE : CondCodeAlias<Prefix, Suffix, "nge", "l", V>; // setnge -> setl
3196 def NLE : CondCodeAlias<Prefix, Suffix, "nle", "g", V>; // setnle -> setg
3199 // Aliases for set<CC>
3200 defm : IntegerCondCodeMnemonicAlias<"set", "">;
3201 // Aliases for j<CC>
3202 defm : IntegerCondCodeMnemonicAlias<"j", "">;
3203 // Aliases for cmov<CC>{w,l,q}
3204 defm : IntegerCondCodeMnemonicAlias<"cmov", "w", "att">;
3205 defm : IntegerCondCodeMnemonicAlias<"cmov", "l", "att">;
3206 defm : IntegerCondCodeMnemonicAlias<"cmov", "q", "att">;
3207 // No size suffix for intel-style asm.
3208 defm : IntegerCondCodeMnemonicAlias<"cmov", "", "intel">;
3211 //===----------------------------------------------------------------------===//
3212 // Assembler Instruction Aliases
3213 //===----------------------------------------------------------------------===//
3215 // aad/aam default to base 10 if no operand is specified.
3216 def : InstAlias<"aad", (AAD8i8 10)>, Requires<[Not64BitMode]>;
3217 def : InstAlias<"aam", (AAM8i8 10)>, Requires<[Not64BitMode]>;
3219 // Disambiguate the mem/imm form of bt-without-a-suffix as btl.
3220 // Likewise for btc/btr/bts.
3221 def : InstAlias<"bt\t{$imm, $mem|$mem, $imm}",
3222 (BT32mi8 i32mem:$mem, i32u8imm:$imm), 0, "att">;
3223 def : InstAlias<"btc\t{$imm, $mem|$mem, $imm}",
3224 (BTC32mi8 i32mem:$mem, i32u8imm:$imm), 0, "att">;
3225 def : InstAlias<"btr\t{$imm, $mem|$mem, $imm}",
3226 (BTR32mi8 i32mem:$mem, i32u8imm:$imm), 0, "att">;
3227 def : InstAlias<"bts\t{$imm, $mem|$mem, $imm}",
3228 (BTS32mi8 i32mem:$mem, i32u8imm:$imm), 0, "att">;
3231 def : InstAlias<"clr{b}\t$reg", (XOR8rr GR8 :$reg, GR8 :$reg), 0>;
3232 def : InstAlias<"clr{w}\t$reg", (XOR16rr GR16:$reg, GR16:$reg), 0>;
3233 def : InstAlias<"clr{l}\t$reg", (XOR32rr GR32:$reg, GR32:$reg), 0>;
3234 def : InstAlias<"clr{q}\t$reg", (XOR64rr GR64:$reg, GR64:$reg), 0>;
3236 // lods aliases. Accept the destination being omitted because it's implicit
3237 // in the mnemonic, or the mnemonic suffix being omitted because it's implicit
3238 // in the destination.
3239 def : InstAlias<"lodsb\t$src", (LODSB srcidx8:$src), 0>;
3240 def : InstAlias<"lodsw\t$src", (LODSW srcidx16:$src), 0>;
3241 def : InstAlias<"lods{l|d}\t$src", (LODSL srcidx32:$src), 0>;
3242 def : InstAlias<"lodsq\t$src", (LODSQ srcidx64:$src), 0>, Requires<[In64BitMode]>;
3243 def : InstAlias<"lods\t{$src, %al|al, $src}", (LODSB srcidx8:$src), 0>;
3244 def : InstAlias<"lods\t{$src, %ax|ax, $src}", (LODSW srcidx16:$src), 0>;
3245 def : InstAlias<"lods\t{$src, %eax|eax, $src}", (LODSL srcidx32:$src), 0>;
3246 def : InstAlias<"lods\t{$src, %rax|rax, $src}", (LODSQ srcidx64:$src), 0>, Requires<[In64BitMode]>;
3247 def : InstAlias<"lods\t$src", (LODSB srcidx8:$src), 0, "intel">;
3248 def : InstAlias<"lods\t$src", (LODSW srcidx16:$src), 0, "intel">;
3249 def : InstAlias<"lods\t$src", (LODSL srcidx32:$src), 0, "intel">;
3250 def : InstAlias<"lods\t$src", (LODSQ srcidx64:$src), 0, "intel">, Requires<[In64BitMode]>;
3253 // stos aliases. Accept the source being omitted because it's implicit in
3254 // the mnemonic, or the mnemonic suffix being omitted because it's implicit
3256 def : InstAlias<"stosb\t$dst", (STOSB dstidx8:$dst), 0>;
3257 def : InstAlias<"stosw\t$dst", (STOSW dstidx16:$dst), 0>;
3258 def : InstAlias<"stos{l|d}\t$dst", (STOSL dstidx32:$dst), 0>;
3259 def : InstAlias<"stosq\t$dst", (STOSQ dstidx64:$dst), 0>, Requires<[In64BitMode]>;
3260 def : InstAlias<"stos\t{%al, $dst|$dst, al}", (STOSB dstidx8:$dst), 0>;
3261 def : InstAlias<"stos\t{%ax, $dst|$dst, ax}", (STOSW dstidx16:$dst), 0>;
3262 def : InstAlias<"stos\t{%eax, $dst|$dst, eax}", (STOSL dstidx32:$dst), 0>;
3263 def : InstAlias<"stos\t{%rax, $dst|$dst, rax}", (STOSQ dstidx64:$dst), 0>, Requires<[In64BitMode]>;
3264 def : InstAlias<"stos\t$dst", (STOSB dstidx8:$dst), 0, "intel">;
3265 def : InstAlias<"stos\t$dst", (STOSW dstidx16:$dst), 0, "intel">;
3266 def : InstAlias<"stos\t$dst", (STOSL dstidx32:$dst), 0, "intel">;
3267 def : InstAlias<"stos\t$dst", (STOSQ dstidx64:$dst), 0, "intel">, Requires<[In64BitMode]>;
3270 // scas aliases. Accept the destination being omitted because it's implicit
3271 // in the mnemonic, or the mnemonic suffix being omitted because it's implicit
3272 // in the destination.
3273 def : InstAlias<"scasb\t$dst", (SCASB dstidx8:$dst), 0>;
3274 def : InstAlias<"scasw\t$dst", (SCASW dstidx16:$dst), 0>;
3275 def : InstAlias<"scas{l|d}\t$dst", (SCASL dstidx32:$dst), 0>;
3276 def : InstAlias<"scasq\t$dst", (SCASQ dstidx64:$dst), 0>, Requires<[In64BitMode]>;
3277 def : InstAlias<"scas\t{$dst, %al|al, $dst}", (SCASB dstidx8:$dst), 0>;
3278 def : InstAlias<"scas\t{$dst, %ax|ax, $dst}", (SCASW dstidx16:$dst), 0>;
3279 def : InstAlias<"scas\t{$dst, %eax|eax, $dst}", (SCASL dstidx32:$dst), 0>;
3280 def : InstAlias<"scas\t{$dst, %rax|rax, $dst}", (SCASQ dstidx64:$dst), 0>, Requires<[In64BitMode]>;
3281 def : InstAlias<"scas\t$dst", (SCASB dstidx8:$dst), 0, "intel">;
3282 def : InstAlias<"scas\t$dst", (SCASW dstidx16:$dst), 0, "intel">;
3283 def : InstAlias<"scas\t$dst", (SCASL dstidx32:$dst), 0, "intel">;
3284 def : InstAlias<"scas\t$dst", (SCASQ dstidx64:$dst), 0, "intel">, Requires<[In64BitMode]>;
3286 // cmps aliases. Mnemonic suffix being omitted because it's implicit
3287 // in the destination.
3288 def : InstAlias<"cmps\t{$dst, $src|$src, $dst}", (CMPSB dstidx8:$dst, srcidx8:$src), 0, "intel">;
3289 def : InstAlias<"cmps\t{$dst, $src|$src, $dst}", (CMPSW dstidx16:$dst, srcidx16:$src), 0, "intel">;
3290 def : InstAlias<"cmps\t{$dst, $src|$src, $dst}", (CMPSL dstidx32:$dst, srcidx32:$src), 0, "intel">;
3291 def : InstAlias<"cmps\t{$dst, $src|$src, $dst}", (CMPSQ dstidx64:$dst, srcidx64:$src), 0, "intel">, Requires<[In64BitMode]>;
3293 // movs aliases. Mnemonic suffix being omitted because it's implicit
3294 // in the destination.
3295 def : InstAlias<"movs\t{$src, $dst|$dst, $src}", (MOVSB dstidx8:$dst, srcidx8:$src), 0, "intel">;
3296 def : InstAlias<"movs\t{$src, $dst|$dst, $src}", (MOVSW dstidx16:$dst, srcidx16:$src), 0, "intel">;
3297 def : InstAlias<"movs\t{$src, $dst|$dst, $src}", (MOVSL dstidx32:$dst, srcidx32:$src), 0, "intel">;
3298 def : InstAlias<"movs\t{$src, $dst|$dst, $src}", (MOVSQ dstidx64:$dst, srcidx64:$src), 0, "intel">, Requires<[In64BitMode]>;
3300 // div and idiv aliases for explicit A register.
3301 def : InstAlias<"div{b}\t{$src, %al|al, $src}", (DIV8r GR8 :$src)>;
3302 def : InstAlias<"div{w}\t{$src, %ax|ax, $src}", (DIV16r GR16:$src)>;
3303 def : InstAlias<"div{l}\t{$src, %eax|eax, $src}", (DIV32r GR32:$src)>;
3304 def : InstAlias<"div{q}\t{$src, %rax|rax, $src}", (DIV64r GR64:$src)>;
3305 def : InstAlias<"div{b}\t{$src, %al|al, $src}", (DIV8m i8mem :$src)>;
3306 def : InstAlias<"div{w}\t{$src, %ax|ax, $src}", (DIV16m i16mem:$src)>;
3307 def : InstAlias<"div{l}\t{$src, %eax|eax, $src}", (DIV32m i32mem:$src)>;
3308 def : InstAlias<"div{q}\t{$src, %rax|rax, $src}", (DIV64m i64mem:$src)>;
3309 def : InstAlias<"idiv{b}\t{$src, %al|al, $src}", (IDIV8r GR8 :$src)>;
3310 def : InstAlias<"idiv{w}\t{$src, %ax|ax, $src}", (IDIV16r GR16:$src)>;
3311 def : InstAlias<"idiv{l}\t{$src, %eax|eax, $src}", (IDIV32r GR32:$src)>;
3312 def : InstAlias<"idiv{q}\t{$src, %rax|rax, $src}", (IDIV64r GR64:$src)>;
3313 def : InstAlias<"idiv{b}\t{$src, %al|al, $src}", (IDIV8m i8mem :$src)>;
3314 def : InstAlias<"idiv{w}\t{$src, %ax|ax, $src}", (IDIV16m i16mem:$src)>;
3315 def : InstAlias<"idiv{l}\t{$src, %eax|eax, $src}", (IDIV32m i32mem:$src)>;
3316 def : InstAlias<"idiv{q}\t{$src, %rax|rax, $src}", (IDIV64m i64mem:$src)>;
3320 // Various unary fpstack operations default to operating on ST1.
3321 // For example, "fxch" -> "fxch %st(1)"
3322 def : InstAlias<"faddp", (ADD_FPrST0 ST1), 0>;
3323 def: InstAlias<"fadd", (ADD_FPrST0 ST1), 0>;
3324 def : InstAlias<"fsub{|r}p", (SUBR_FPrST0 ST1), 0>;
3325 def : InstAlias<"fsub{r|}p", (SUB_FPrST0 ST1), 0>;
3326 def : InstAlias<"fmul", (MUL_FPrST0 ST1), 0>;
3327 def : InstAlias<"fmulp", (MUL_FPrST0 ST1), 0>;
3328 def : InstAlias<"fdiv{|r}p", (DIVR_FPrST0 ST1), 0>;
3329 def : InstAlias<"fdiv{r|}p", (DIV_FPrST0 ST1), 0>;
3330 def : InstAlias<"fxch", (XCH_F ST1), 0>;
3331 def : InstAlias<"fcom", (COM_FST0r ST1), 0>;
3332 def : InstAlias<"fcomp", (COMP_FST0r ST1), 0>;
3333 def : InstAlias<"fcomi", (COM_FIr ST1), 0>;
3334 def : InstAlias<"fcompi", (COM_FIPr ST1), 0>;
3335 def : InstAlias<"fucom", (UCOM_Fr ST1), 0>;
3336 def : InstAlias<"fucomp", (UCOM_FPr ST1), 0>;
3337 def : InstAlias<"fucomi", (UCOM_FIr ST1), 0>;
3338 def : InstAlias<"fucompi", (UCOM_FIPr ST1), 0>;
3340 // Handle fmul/fadd/fsub/fdiv instructions with explicitly written st(0) op.
3341 // For example, "fadd %st(4), %st(0)" -> "fadd %st(4)". We also disambiguate
3342 // instructions like "fadd %st(0), %st(0)" as "fadd %st(0)" for consistency with
3344 multiclass FpUnaryAlias<string Mnemonic, Instruction Inst, bit EmitAlias = 1> {
3345 def : InstAlias<!strconcat(Mnemonic, "\t$op"),
3346 (Inst RSTi:$op), EmitAlias>;
3347 def : InstAlias<!strconcat(Mnemonic, "\t{%st, %st|st, st}"),
3348 (Inst ST0), EmitAlias>;
3351 defm : FpUnaryAlias<"fadd", ADD_FST0r, 0>;
3352 defm : FpUnaryAlias<"faddp", ADD_FPrST0, 0>;
3353 defm : FpUnaryAlias<"fsub", SUB_FST0r, 0>;
3354 defm : FpUnaryAlias<"fsub{|r}p", SUBR_FPrST0, 0>;
3355 defm : FpUnaryAlias<"fsubr", SUBR_FST0r, 0>;
3356 defm : FpUnaryAlias<"fsub{r|}p", SUB_FPrST0, 0>;
3357 defm : FpUnaryAlias<"fmul", MUL_FST0r, 0>;
3358 defm : FpUnaryAlias<"fmulp", MUL_FPrST0, 0>;
3359 defm : FpUnaryAlias<"fdiv", DIV_FST0r, 0>;
3360 defm : FpUnaryAlias<"fdiv{|r}p", DIVR_FPrST0, 0>;
3361 defm : FpUnaryAlias<"fdivr", DIVR_FST0r, 0>;
3362 defm : FpUnaryAlias<"fdiv{r|}p", DIV_FPrST0, 0>;
3363 defm : FpUnaryAlias<"fcomi", COM_FIr, 0>;
3364 defm : FpUnaryAlias<"fucomi", UCOM_FIr, 0>;
3365 defm : FpUnaryAlias<"fcompi", COM_FIPr, 0>;
3366 defm : FpUnaryAlias<"fucompi", UCOM_FIPr, 0>;
3369 // Handle "f{mulp,addp} $op, %st(0)" the same as "f{mulp,addp} $op", since they
3370 // commute. We also allow fdiv[r]p/fsubrp even though they don't commute,
3371 // solely because gas supports it.
3372 def : InstAlias<"faddp\t{$op, %st|st, $op}", (ADD_FPrST0 RSTi:$op), 0>;
3373 def : InstAlias<"fmulp\t{$op, %st|st, $op}", (MUL_FPrST0 RSTi:$op), 0>;
3374 def : InstAlias<"fsub{|r}p\t{$op, %st|st, $op}", (SUBR_FPrST0 RSTi:$op), 0>;
3375 def : InstAlias<"fsub{r|}p\t{$op, %st|st, $op}", (SUB_FPrST0 RSTi:$op), 0>;
3376 def : InstAlias<"fdiv{|r}p\t{$op, %st|st, $op}", (DIVR_FPrST0 RSTi:$op), 0>;
3377 def : InstAlias<"fdiv{r|}p\t{$op, %st|st, $op}", (DIV_FPrST0 RSTi:$op), 0>;
3379 def : InstAlias<"fnstsw" , (FNSTSW16r), 0>;
3381 // lcall and ljmp aliases. This seems to be an odd mapping in 64-bit mode, but
3382 // this is compatible with what GAS does.
3383 def : InstAlias<"lcall\t$seg, $off", (FARCALL32i i32imm:$off, i16imm:$seg), 0>, Requires<[In32BitMode]>;
3384 def : InstAlias<"ljmp\t$seg, $off", (FARJMP32i i32imm:$off, i16imm:$seg), 0>, Requires<[In32BitMode]>;
3385 def : InstAlias<"lcall\t{*}$dst", (FARCALL32m opaquemem:$dst), 0>, Requires<[Not16BitMode]>;
3386 def : InstAlias<"ljmp\t{*}$dst", (FARJMP32m opaquemem:$dst), 0>, Requires<[Not16BitMode]>;
3387 def : InstAlias<"lcall\t$seg, $off", (FARCALL16i i16imm:$off, i16imm:$seg), 0>, Requires<[In16BitMode]>;
3388 def : InstAlias<"ljmp\t$seg, $off", (FARJMP16i i16imm:$off, i16imm:$seg), 0>, Requires<[In16BitMode]>;
3389 def : InstAlias<"lcall\t{*}$dst", (FARCALL16m opaquemem:$dst), 0>, Requires<[In16BitMode]>;
3390 def : InstAlias<"ljmp\t{*}$dst", (FARJMP16m opaquemem:$dst), 0>, Requires<[In16BitMode]>;
3392 def : InstAlias<"jmp\t{*}$dst", (JMP64m i64mem:$dst), 0, "att">, Requires<[In64BitMode]>;
3393 def : InstAlias<"jmp\t{*}$dst", (JMP32m i32mem:$dst), 0, "att">, Requires<[In32BitMode]>;
3394 def : InstAlias<"jmp\t{*}$dst", (JMP16m i16mem:$dst), 0, "att">, Requires<[In16BitMode]>;
3397 // "imul <imm>, B" is an alias for "imul <imm>, B, B".
3398 def : InstAlias<"imul{w}\t{$imm, $r|$r, $imm}", (IMUL16rri GR16:$r, GR16:$r, i16imm:$imm), 0>;
3399 def : InstAlias<"imul{w}\t{$imm, $r|$r, $imm}", (IMUL16rri8 GR16:$r, GR16:$r, i16i8imm:$imm), 0>;
3400 def : InstAlias<"imul{l}\t{$imm, $r|$r, $imm}", (IMUL32rri GR32:$r, GR32:$r, i32imm:$imm), 0>;
3401 def : InstAlias<"imul{l}\t{$imm, $r|$r, $imm}", (IMUL32rri8 GR32:$r, GR32:$r, i32i8imm:$imm), 0>;
3402 def : InstAlias<"imul{q}\t{$imm, $r|$r, $imm}", (IMUL64rri32 GR64:$r, GR64:$r, i64i32imm:$imm), 0>;
3403 def : InstAlias<"imul{q}\t{$imm, $r|$r, $imm}", (IMUL64rri8 GR64:$r, GR64:$r, i64i8imm:$imm), 0>;
3405 // ins aliases. Accept the mnemonic suffix being omitted because it's implicit
3406 // in the destination.
3407 def : InstAlias<"ins\t{%dx, $dst|$dst, dx}", (INSB dstidx8:$dst), 0, "intel">;
3408 def : InstAlias<"ins\t{%dx, $dst|$dst, dx}", (INSW dstidx16:$dst), 0, "intel">;
3409 def : InstAlias<"ins\t{%dx, $dst|$dst, dx}", (INSL dstidx32:$dst), 0, "intel">;
3411 // outs aliases. Accept the mnemonic suffix being omitted because it's implicit
3413 def : InstAlias<"outs\t{$src, %dx|dx, $src}", (OUTSB srcidx8:$src), 0, "intel">;
3414 def : InstAlias<"outs\t{$src, %dx|dx, $src}", (OUTSW srcidx16:$src), 0, "intel">;
3415 def : InstAlias<"outs\t{$src, %dx|dx, $src}", (OUTSL srcidx32:$src), 0, "intel">;
3417 // inb %dx -> inb %al, %dx
3418 def : InstAlias<"inb\t{%dx|dx}", (IN8rr), 0>;
3419 def : InstAlias<"inw\t{%dx|dx}", (IN16rr), 0>;
3420 def : InstAlias<"inl\t{%dx|dx}", (IN32rr), 0>;
3421 def : InstAlias<"inb\t$port", (IN8ri u8imm:$port), 0>;
3422 def : InstAlias<"inw\t$port", (IN16ri u8imm:$port), 0>;
3423 def : InstAlias<"inl\t$port", (IN32ri u8imm:$port), 0>;
3426 // jmp and call aliases for lcall and ljmp. jmp $42,$5 -> ljmp
3427 def : InstAlias<"call\t$seg, $off", (FARCALL16i i16imm:$off, i16imm:$seg)>, Requires<[In16BitMode]>;
3428 def : InstAlias<"jmp\t$seg, $off", (FARJMP16i i16imm:$off, i16imm:$seg)>, Requires<[In16BitMode]>;
3429 def : InstAlias<"call\t$seg, $off", (FARCALL32i i32imm:$off, i16imm:$seg)>, Requires<[In32BitMode]>;
3430 def : InstAlias<"jmp\t$seg, $off", (FARJMP32i i32imm:$off, i16imm:$seg)>, Requires<[In32BitMode]>;
3431 def : InstAlias<"callw\t$seg, $off", (FARCALL16i i16imm:$off, i16imm:$seg)>, Requires<[Not64BitMode]>;
3432 def : InstAlias<"jmpw\t$seg, $off", (FARJMP16i i16imm:$off, i16imm:$seg)>, Requires<[Not64BitMode]>;
3433 def : InstAlias<"calll\t$seg, $off", (FARCALL32i i32imm:$off, i16imm:$seg)>, Requires<[Not64BitMode]>;
3434 def : InstAlias<"jmpl\t$seg, $off", (FARJMP32i i32imm:$off, i16imm:$seg)>, Requires<[Not64BitMode]>;
3436 // Match 'movq <largeimm>, <reg>' as an alias for movabsq.
3437 def : InstAlias<"mov{q}\t{$imm, $reg|$reg, $imm}", (MOV64ri GR64:$reg, i64imm:$imm), 0>;
3439 // Match 'movd GR64, MMX' as an alias for movq to be compatible with gas,
3440 // which supports this due to an old AMD documentation bug when 64-bit mode was
3442 def : InstAlias<"movd\t{$src, $dst|$dst, $src}",
3443 (MMX_MOVD64to64rr VR64:$dst, GR64:$src), 0>;
3444 def : InstAlias<"movd\t{$src, $dst|$dst, $src}",
3445 (MMX_MOVD64from64rr GR64:$dst, VR64:$src), 0>;
3448 def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX16rr8 GR16:$dst, GR8:$src), 0, "att">;
3449 def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX16rm8 GR16:$dst, i8mem:$src), 0, "att">;
3450 def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX32rr8 GR32:$dst, GR8:$src), 0, "att">;
3451 def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX32rr16 GR32:$dst, GR16:$src), 0, "att">;
3452 def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX64rr8 GR64:$dst, GR8:$src), 0, "att">;
3453 def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX64rr16 GR64:$dst, GR16:$src), 0, "att">;
3454 def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX64rr32 GR64:$dst, GR32:$src), 0, "att">;
3457 def : InstAlias<"movzx\t{$src, $dst|$dst, $src}", (MOVZX16rr8 GR16:$dst, GR8:$src), 0, "att">;
3458 def : InstAlias<"movzx\t{$src, $dst|$dst, $src}", (MOVZX16rm8 GR16:$dst, i8mem:$src), 0, "att">;
3459 def : InstAlias<"movzx\t{$src, $dst|$dst, $src}", (MOVZX32rr8 GR32:$dst, GR8:$src), 0, "att">;
3460 def : InstAlias<"movzx\t{$src, $dst|$dst, $src}", (MOVZX32rr16 GR32:$dst, GR16:$src), 0, "att">;
3461 def : InstAlias<"movzx\t{$src, $dst|$dst, $src}", (MOVZX64rr8 GR64:$dst, GR8:$src), 0, "att">;
3462 def : InstAlias<"movzx\t{$src, $dst|$dst, $src}", (MOVZX64rr16 GR64:$dst, GR16:$src), 0, "att">;
3463 // Note: No GR32->GR64 movzx form.
3465 // outb %dx -> outb %al, %dx
3466 def : InstAlias<"outb\t{%dx|dx}", (OUT8rr), 0>;
3467 def : InstAlias<"outw\t{%dx|dx}", (OUT16rr), 0>;
3468 def : InstAlias<"outl\t{%dx|dx}", (OUT32rr), 0>;
3469 def : InstAlias<"outb\t$port", (OUT8ir u8imm:$port), 0>;
3470 def : InstAlias<"outw\t$port", (OUT16ir u8imm:$port), 0>;
3471 def : InstAlias<"outl\t$port", (OUT32ir u8imm:$port), 0>;
3473 // 'sldt <mem>' can be encoded with either sldtw or sldtq with the same
3474 // effect (both store to a 16-bit mem). Force to sldtw to avoid ambiguity
3475 // errors, since its encoding is the most compact.
3476 def : InstAlias<"sldt $mem", (SLDT16m i16mem:$mem), 0>;
3478 // shld/shrd op,op -> shld op, op, CL
3479 def : InstAlias<"shld{w}\t{$r2, $r1|$r1, $r2}", (SHLD16rrCL GR16:$r1, GR16:$r2), 0>;
3480 def : InstAlias<"shld{l}\t{$r2, $r1|$r1, $r2}", (SHLD32rrCL GR32:$r1, GR32:$r2), 0>;
3481 def : InstAlias<"shld{q}\t{$r2, $r1|$r1, $r2}", (SHLD64rrCL GR64:$r1, GR64:$r2), 0>;
3482 def : InstAlias<"shrd{w}\t{$r2, $r1|$r1, $r2}", (SHRD16rrCL GR16:$r1, GR16:$r2), 0>;
3483 def : InstAlias<"shrd{l}\t{$r2, $r1|$r1, $r2}", (SHRD32rrCL GR32:$r1, GR32:$r2), 0>;
3484 def : InstAlias<"shrd{q}\t{$r2, $r1|$r1, $r2}", (SHRD64rrCL GR64:$r1, GR64:$r2), 0>;
3486 def : InstAlias<"shld{w}\t{$reg, $mem|$mem, $reg}", (SHLD16mrCL i16mem:$mem, GR16:$reg), 0>;
3487 def : InstAlias<"shld{l}\t{$reg, $mem|$mem, $reg}", (SHLD32mrCL i32mem:$mem, GR32:$reg), 0>;
3488 def : InstAlias<"shld{q}\t{$reg, $mem|$mem, $reg}", (SHLD64mrCL i64mem:$mem, GR64:$reg), 0>;
3489 def : InstAlias<"shrd{w}\t{$reg, $mem|$mem, $reg}", (SHRD16mrCL i16mem:$mem, GR16:$reg), 0>;
3490 def : InstAlias<"shrd{l}\t{$reg, $mem|$mem, $reg}", (SHRD32mrCL i32mem:$mem, GR32:$reg), 0>;
3491 def : InstAlias<"shrd{q}\t{$reg, $mem|$mem, $reg}", (SHRD64mrCL i64mem:$mem, GR64:$reg), 0>;
3493 /* FIXME: This is disabled because the asm matcher is currently incapable of
3494 * matching a fixed immediate like $1.
3495 // "shl X, $1" is an alias for "shl X".
3496 multiclass ShiftRotateByOneAlias<string Mnemonic, string Opc> {
3497 def : InstAlias<!strconcat(Mnemonic, "b $op, $$1"),
3498 (!cast<Instruction>(!strconcat(Opc, "8r1")) GR8:$op)>;
3499 def : InstAlias<!strconcat(Mnemonic, "w $op, $$1"),
3500 (!cast<Instruction>(!strconcat(Opc, "16r1")) GR16:$op)>;
3501 def : InstAlias<!strconcat(Mnemonic, "l $op, $$1"),
3502 (!cast<Instruction>(!strconcat(Opc, "32r1")) GR32:$op)>;
3503 def : InstAlias<!strconcat(Mnemonic, "q $op, $$1"),
3504 (!cast<Instruction>(!strconcat(Opc, "64r1")) GR64:$op)>;
3505 def : InstAlias<!strconcat(Mnemonic, "b $op, $$1"),
3506 (!cast<Instruction>(!strconcat(Opc, "8m1")) i8mem:$op)>;
3507 def : InstAlias<!strconcat(Mnemonic, "w $op, $$1"),
3508 (!cast<Instruction>(!strconcat(Opc, "16m1")) i16mem:$op)>;
3509 def : InstAlias<!strconcat(Mnemonic, "l $op, $$1"),
3510 (!cast<Instruction>(!strconcat(Opc, "32m1")) i32mem:$op)>;
3511 def : InstAlias<!strconcat(Mnemonic, "q $op, $$1"),
3512 (!cast<Instruction>(!strconcat(Opc, "64m1")) i64mem:$op)>;
3515 defm : ShiftRotateByOneAlias<"rcl", "RCL">;
3516 defm : ShiftRotateByOneAlias<"rcr", "RCR">;
3517 defm : ShiftRotateByOneAlias<"rol", "ROL">;
3518 defm : ShiftRotateByOneAlias<"ror", "ROR">;
3521 // test: We accept "testX <reg>, <mem>" and "testX <mem>, <reg>" as synonyms.
3522 def : InstAlias<"test{b}\t{$mem, $val|$val, $mem}",
3523 (TEST8mr i8mem :$mem, GR8 :$val), 0>;
3524 def : InstAlias<"test{w}\t{$mem, $val|$val, $mem}",
3525 (TEST16mr i16mem:$mem, GR16:$val), 0>;
3526 def : InstAlias<"test{l}\t{$mem, $val|$val, $mem}",
3527 (TEST32mr i32mem:$mem, GR32:$val), 0>;
3528 def : InstAlias<"test{q}\t{$mem, $val|$val, $mem}",
3529 (TEST64mr i64mem:$mem, GR64:$val), 0>;
3531 // xchg: We accept "xchgX <reg>, <mem>" and "xchgX <mem>, <reg>" as synonyms.
3532 def : InstAlias<"xchg{b}\t{$mem, $val|$val, $mem}",
3533 (XCHG8rm GR8 :$val, i8mem :$mem), 0>;
3534 def : InstAlias<"xchg{w}\t{$mem, $val|$val, $mem}",
3535 (XCHG16rm GR16:$val, i16mem:$mem), 0>;
3536 def : InstAlias<"xchg{l}\t{$mem, $val|$val, $mem}",
3537 (XCHG32rm GR32:$val, i32mem:$mem), 0>;
3538 def : InstAlias<"xchg{q}\t{$mem, $val|$val, $mem}",
3539 (XCHG64rm GR64:$val, i64mem:$mem), 0>;
3541 // xchg: We accept "xchgX <reg>, %eax" and "xchgX %eax, <reg>" as synonyms.
3542 def : InstAlias<"xchg{w}\t{%ax, $src|$src, ax}", (XCHG16ar GR16:$src), 0>;
3543 def : InstAlias<"xchg{l}\t{%eax, $src|$src, eax}", (XCHG32ar GR32:$src), 0>;
3544 def : InstAlias<"xchg{q}\t{%rax, $src|$src, rax}", (XCHG64ar GR64:$src), 0>;
3546 // In 64-bit mode, xchg %eax, %eax can't be encoded with the 0x90 opcode we
3547 // would get by default because it's defined as NOP. But xchg %eax, %eax implies
3548 // implicit zeroing of the upper 32 bits. So alias to the longer encoding.
3549 def : InstAlias<"xchg{l}\t{%eax, %eax|eax, eax}",
3550 (XCHG32rr EAX, EAX), 0>, Requires<[In64BitMode]>;
3552 // xchg %rax, %rax is a nop in x86-64 and can be encoded as such. Without this
3553 // we emit an unneeded REX.w prefix.
3554 def : InstAlias<"xchg{q}\t{%rax, %rax|rax, rax}", (NOOP), 0>;
3556 // These aliases exist to get the parser to prioritize matching 8-bit
3557 // immediate encodings over matching the implicit ax/eax/rax encodings. By
3558 // explicitly mentioning the A register here, these entries will be ordered
3559 // first due to the more explicit immediate type.
3560 def : InstAlias<"adc{w}\t{$imm, %ax|ax, $imm}", (ADC16ri8 AX, i16i8imm:$imm), 0>;
3561 def : InstAlias<"add{w}\t{$imm, %ax|ax, $imm}", (ADD16ri8 AX, i16i8imm:$imm), 0>;
3562 def : InstAlias<"and{w}\t{$imm, %ax|ax, $imm}", (AND16ri8 AX, i16i8imm:$imm), 0>;
3563 def : InstAlias<"cmp{w}\t{$imm, %ax|ax, $imm}", (CMP16ri8 AX, i16i8imm:$imm), 0>;
3564 def : InstAlias<"or{w}\t{$imm, %ax|ax, $imm}", (OR16ri8 AX, i16i8imm:$imm), 0>;
3565 def : InstAlias<"sbb{w}\t{$imm, %ax|ax, $imm}", (SBB16ri8 AX, i16i8imm:$imm), 0>;
3566 def : InstAlias<"sub{w}\t{$imm, %ax|ax, $imm}", (SUB16ri8 AX, i16i8imm:$imm), 0>;
3567 def : InstAlias<"xor{w}\t{$imm, %ax|ax, $imm}", (XOR16ri8 AX, i16i8imm:$imm), 0>;
3569 def : InstAlias<"adc{l}\t{$imm, %eax|eax, $imm}", (ADC32ri8 EAX, i32i8imm:$imm), 0>;
3570 def : InstAlias<"add{l}\t{$imm, %eax|eax, $imm}", (ADD32ri8 EAX, i32i8imm:$imm), 0>;
3571 def : InstAlias<"and{l}\t{$imm, %eax|eax, $imm}", (AND32ri8 EAX, i32i8imm:$imm), 0>;
3572 def : InstAlias<"cmp{l}\t{$imm, %eax|eax, $imm}", (CMP32ri8 EAX, i32i8imm:$imm), 0>;
3573 def : InstAlias<"or{l}\t{$imm, %eax|eax, $imm}", (OR32ri8 EAX, i32i8imm:$imm), 0>;
3574 def : InstAlias<"sbb{l}\t{$imm, %eax|eax, $imm}", (SBB32ri8 EAX, i32i8imm:$imm), 0>;
3575 def : InstAlias<"sub{l}\t{$imm, %eax|eax, $imm}", (SUB32ri8 EAX, i32i8imm:$imm), 0>;
3576 def : InstAlias<"xor{l}\t{$imm, %eax|eax, $imm}", (XOR32ri8 EAX, i32i8imm:$imm), 0>;
3578 def : InstAlias<"adc{q}\t{$imm, %rax|rax, $imm}", (ADC64ri8 RAX, i64i8imm:$imm), 0>;
3579 def : InstAlias<"add{q}\t{$imm, %rax|rax, $imm}", (ADD64ri8 RAX, i64i8imm:$imm), 0>;
3580 def : InstAlias<"and{q}\t{$imm, %rax|rax, $imm}", (AND64ri8 RAX, i64i8imm:$imm), 0>;
3581 def : InstAlias<"cmp{q}\t{$imm, %rax|rax, $imm}", (CMP64ri8 RAX, i64i8imm:$imm), 0>;
3582 def : InstAlias<"or{q}\t{$imm, %rax|rax, $imm}", (OR64ri8 RAX, i64i8imm:$imm), 0>;
3583 def : InstAlias<"sbb{q}\t{$imm, %rax|rax, $imm}", (SBB64ri8 RAX, i64i8imm:$imm), 0>;
3584 def : InstAlias<"sub{q}\t{$imm, %rax|rax, $imm}", (SUB64ri8 RAX, i64i8imm:$imm), 0>;
3585 def : InstAlias<"xor{q}\t{$imm, %rax|rax, $imm}", (XOR64ri8 RAX, i64i8imm:$imm), 0>;