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 X86strict_fcmp : SDNode<"X86ISD::STRICT_FCMP", SDTX86CmpTest, [SDNPHasChain]>;
146 def X86strict_fcmps : SDNode<"X86ISD::STRICT_FCMPS", SDTX86CmpTest, [SDNPHasChain]>;
147 def X86bt : SDNode<"X86ISD::BT", SDTX86CmpTest>;
149 def X86cmov : SDNode<"X86ISD::CMOV", SDTX86Cmov>;
150 def X86brcond : SDNode<"X86ISD::BRCOND", SDTX86BrCond,
152 def X86setcc : SDNode<"X86ISD::SETCC", SDTX86SetCC>;
153 def X86setcc_c : SDNode<"X86ISD::SETCC_CARRY", SDTX86SetCC_C>;
155 def X86sahf : SDNode<"X86ISD::SAHF", SDTX86sahf>;
157 def X86rdrand : SDNode<"X86ISD::RDRAND", SDTX86rdrand,
158 [SDNPHasChain, SDNPSideEffect]>;
160 def X86rdseed : SDNode<"X86ISD::RDSEED", SDTX86rdrand,
161 [SDNPHasChain, SDNPSideEffect]>;
163 def X86rdpkru : SDNode<"X86ISD::RDPKRU", SDTX86rdpkru,
164 [SDNPHasChain, SDNPSideEffect]>;
165 def X86wrpkru : SDNode<"X86ISD::WRPKRU", SDTX86wrpkru,
166 [SDNPHasChain, SDNPSideEffect]>;
168 def X86cas : SDNode<"X86ISD::LCMPXCHG_DAG", SDTX86cas,
169 [SDNPHasChain, SDNPInGlue, SDNPOutGlue, SDNPMayStore,
170 SDNPMayLoad, SDNPMemOperand]>;
171 def X86cas8 : SDNode<"X86ISD::LCMPXCHG8_DAG", SDTX86caspair,
172 [SDNPHasChain, SDNPInGlue, SDNPOutGlue, SDNPMayStore,
173 SDNPMayLoad, SDNPMemOperand]>;
174 def X86cas16 : SDNode<"X86ISD::LCMPXCHG16_DAG", SDTX86caspair,
175 [SDNPHasChain, SDNPInGlue, SDNPOutGlue, SDNPMayStore,
176 SDNPMayLoad, SDNPMemOperand]>;
177 def X86cas8save_ebx : SDNode<"X86ISD::LCMPXCHG8_SAVE_EBX_DAG",
178 SDTX86caspairSaveEbx8,
179 [SDNPHasChain, SDNPInGlue, SDNPOutGlue,
180 SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
181 def X86cas16save_rbx : SDNode<"X86ISD::LCMPXCHG16_SAVE_RBX_DAG",
182 SDTX86caspairSaveRbx16,
183 [SDNPHasChain, SDNPInGlue, SDNPOutGlue,
184 SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
186 def X86retflag : SDNode<"X86ISD::RET_FLAG", SDTX86Ret,
187 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
188 def X86iret : SDNode<"X86ISD::IRET", SDTX86Ret,
189 [SDNPHasChain, SDNPOptInGlue]>;
191 def X86vastart_save_xmm_regs :
192 SDNode<"X86ISD::VASTART_SAVE_XMM_REGS",
193 SDT_X86VASTART_SAVE_XMM_REGS,
194 [SDNPHasChain, SDNPVariadic]>;
196 SDNode<"X86ISD::VAARG_64", SDT_X86VAARG_64,
197 [SDNPHasChain, SDNPMayLoad, SDNPMayStore,
199 def X86callseq_start :
200 SDNode<"ISD::CALLSEQ_START", SDT_X86CallSeqStart,
201 [SDNPHasChain, SDNPOutGlue]>;
203 SDNode<"ISD::CALLSEQ_END", SDT_X86CallSeqEnd,
204 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
206 def X86call : SDNode<"X86ISD::CALL", SDT_X86Call,
207 [SDNPHasChain, SDNPOutGlue, SDNPOptInGlue,
210 def X86NoTrackCall : SDNode<"X86ISD::NT_CALL", SDT_X86Call,
211 [SDNPHasChain, SDNPOutGlue, SDNPOptInGlue,
213 def X86NoTrackBrind : SDNode<"X86ISD::NT_BRIND", SDT_X86NtBrind,
216 def X86rep_stos: SDNode<"X86ISD::REP_STOS", SDTX86RepStr,
217 [SDNPHasChain, SDNPInGlue, SDNPOutGlue, SDNPMayStore]>;
218 def X86rep_movs: SDNode<"X86ISD::REP_MOVS", SDTX86RepStr,
219 [SDNPHasChain, SDNPInGlue, SDNPOutGlue, SDNPMayStore,
222 def X86Wrapper : SDNode<"X86ISD::Wrapper", SDTX86Wrapper>;
223 def X86WrapperRIP : SDNode<"X86ISD::WrapperRIP", SDTX86Wrapper>;
225 def X86RecoverFrameAlloc : SDNode<"ISD::LOCAL_RECOVER",
226 SDTypeProfile<1, 1, [SDTCisSameAs<0, 1>,
229 def X86tlsaddr : SDNode<"X86ISD::TLSADDR", SDT_X86TLSADDR,
230 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
232 def X86tlsbaseaddr : SDNode<"X86ISD::TLSBASEADDR", SDT_X86TLSBASEADDR,
233 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
235 def X86ehret : SDNode<"X86ISD::EH_RETURN", SDT_X86EHRET,
238 def X86eh_sjlj_setjmp : SDNode<"X86ISD::EH_SJLJ_SETJMP",
239 SDTypeProfile<1, 1, [SDTCisInt<0>,
241 [SDNPHasChain, SDNPSideEffect]>;
242 def X86eh_sjlj_longjmp : SDNode<"X86ISD::EH_SJLJ_LONGJMP",
243 SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>,
244 [SDNPHasChain, SDNPSideEffect]>;
245 def X86eh_sjlj_setup_dispatch : SDNode<"X86ISD::EH_SJLJ_SETUP_DISPATCH",
246 SDTypeProfile<0, 0, []>,
247 [SDNPHasChain, SDNPSideEffect]>;
249 def X86tcret : SDNode<"X86ISD::TC_RETURN", SDT_X86TCRET,
250 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
252 def X86add_flag : SDNode<"X86ISD::ADD", SDTBinaryArithWithFlags,
254 def X86sub_flag : SDNode<"X86ISD::SUB", SDTBinaryArithWithFlags>;
255 def X86smul_flag : SDNode<"X86ISD::SMUL", SDTBinaryArithWithFlags,
257 def X86umul_flag : SDNode<"X86ISD::UMUL", SDT2ResultBinaryArithWithFlags,
259 def X86adc_flag : SDNode<"X86ISD::ADC", SDTBinaryArithWithFlagsInOut>;
260 def X86sbb_flag : SDNode<"X86ISD::SBB", SDTBinaryArithWithFlagsInOut>;
262 def X86or_flag : SDNode<"X86ISD::OR", SDTBinaryArithWithFlags,
264 def X86xor_flag : SDNode<"X86ISD::XOR", SDTBinaryArithWithFlags,
266 def X86and_flag : SDNode<"X86ISD::AND", SDTBinaryArithWithFlags,
269 def X86lock_add : SDNode<"X86ISD::LADD", SDTLockBinaryArithWithFlags,
270 [SDNPHasChain, SDNPMayStore, SDNPMayLoad,
272 def X86lock_sub : SDNode<"X86ISD::LSUB", SDTLockBinaryArithWithFlags,
273 [SDNPHasChain, SDNPMayStore, SDNPMayLoad,
275 def X86lock_or : SDNode<"X86ISD::LOR", SDTLockBinaryArithWithFlags,
276 [SDNPHasChain, SDNPMayStore, SDNPMayLoad,
278 def X86lock_xor : SDNode<"X86ISD::LXOR", SDTLockBinaryArithWithFlags,
279 [SDNPHasChain, SDNPMayStore, SDNPMayLoad,
281 def X86lock_and : SDNode<"X86ISD::LAND", SDTLockBinaryArithWithFlags,
282 [SDNPHasChain, SDNPMayStore, SDNPMayLoad,
285 def X86bextr : SDNode<"X86ISD::BEXTR", SDTIntBinOp>;
287 def X86bzhi : SDNode<"X86ISD::BZHI", SDTIntBinOp>;
289 def X86mul_imm : SDNode<"X86ISD::MUL_IMM", SDTIntBinOp>;
291 def X86WinAlloca : SDNode<"X86ISD::WIN_ALLOCA", SDT_X86WIN_ALLOCA,
292 [SDNPHasChain, SDNPOutGlue]>;
294 def X86SegAlloca : SDNode<"X86ISD::SEG_ALLOCA", SDT_X86SEG_ALLOCA,
297 def X86TLSCall : SDNode<"X86ISD::TLSCALL", SDT_X86TLSCALL,
298 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
300 def X86lwpins : SDNode<"X86ISD::LWPINS",
301 SDTypeProfile<1, 3, [SDTCisVT<0, i32>, SDTCisInt<1>,
302 SDTCisVT<2, i32>, SDTCisVT<3, i32>]>,
303 [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPSideEffect]>;
305 def X86umwait : SDNode<"X86ISD::UMWAIT",
306 SDTypeProfile<1, 3, [SDTCisVT<0, i32>, SDTCisInt<1>,
307 SDTCisVT<2, i32>, SDTCisVT<3, i32>]>,
308 [SDNPHasChain, SDNPSideEffect]>;
310 def X86tpause : SDNode<"X86ISD::TPAUSE",
311 SDTypeProfile<1, 3, [SDTCisVT<0, i32>, SDTCisInt<1>,
312 SDTCisVT<2, i32>, SDTCisVT<3, i32>]>,
313 [SDNPHasChain, SDNPSideEffect]>;
315 def X86enqcmd : SDNode<"X86ISD::ENQCMD", SDT_X86ENQCMD,
316 [SDNPHasChain, SDNPSideEffect]>;
317 def X86enqcmds : SDNode<"X86ISD::ENQCMDS", SDT_X86ENQCMD,
318 [SDNPHasChain, SDNPSideEffect]>;
320 //===----------------------------------------------------------------------===//
321 // X86 Operand Definitions.
324 // A version of ptr_rc which excludes SP, ESP, and RSP. This is used for
325 // the index operand of an address, to conform to x86 encoding restrictions.
326 def ptr_rc_nosp : PointerLikeRegClass<1>;
328 // *mem - Operand definitions for the funky X86 addressing mode operands.
330 def X86MemAsmOperand : AsmOperandClass {
333 let RenderMethod = "addMemOperands", SuperClasses = [X86MemAsmOperand] in {
334 def X86Mem8AsmOperand : AsmOperandClass { let Name = "Mem8"; }
335 def X86Mem16AsmOperand : AsmOperandClass { let Name = "Mem16"; }
336 def X86Mem32AsmOperand : AsmOperandClass { let Name = "Mem32"; }
337 def X86Mem64AsmOperand : AsmOperandClass { let Name = "Mem64"; }
338 def X86Mem80AsmOperand : AsmOperandClass { let Name = "Mem80"; }
339 def X86Mem128AsmOperand : AsmOperandClass { let Name = "Mem128"; }
340 def X86Mem256AsmOperand : AsmOperandClass { let Name = "Mem256"; }
341 def X86Mem512AsmOperand : AsmOperandClass { let Name = "Mem512"; }
342 // Gather mem operands
343 def X86Mem64_RC128Operand : AsmOperandClass { let Name = "Mem64_RC128"; }
344 def X86Mem128_RC128Operand : AsmOperandClass { let Name = "Mem128_RC128"; }
345 def X86Mem256_RC128Operand : AsmOperandClass { let Name = "Mem256_RC128"; }
346 def X86Mem128_RC256Operand : AsmOperandClass { let Name = "Mem128_RC256"; }
347 def X86Mem256_RC256Operand : AsmOperandClass { let Name = "Mem256_RC256"; }
349 def X86Mem64_RC128XOperand : AsmOperandClass { let Name = "Mem64_RC128X"; }
350 def X86Mem128_RC128XOperand : AsmOperandClass { let Name = "Mem128_RC128X"; }
351 def X86Mem256_RC128XOperand : AsmOperandClass { let Name = "Mem256_RC128X"; }
352 def X86Mem128_RC256XOperand : AsmOperandClass { let Name = "Mem128_RC256X"; }
353 def X86Mem256_RC256XOperand : AsmOperandClass { let Name = "Mem256_RC256X"; }
354 def X86Mem512_RC256XOperand : AsmOperandClass { let Name = "Mem512_RC256X"; }
355 def X86Mem256_RC512Operand : AsmOperandClass { let Name = "Mem256_RC512"; }
356 def X86Mem512_RC512Operand : AsmOperandClass { let Name = "Mem512_RC512"; }
359 def X86AbsMemAsmOperand : AsmOperandClass {
361 let SuperClasses = [X86MemAsmOperand];
364 class X86MemOperand<string printMethod,
365 AsmOperandClass parserMatchClass = X86MemAsmOperand> : Operand<iPTR> {
366 let PrintMethod = printMethod;
367 let MIOperandInfo = (ops ptr_rc, i8imm, ptr_rc_nosp, i32imm, SEGMENT_REG);
368 let ParserMatchClass = parserMatchClass;
369 let OperandType = "OPERAND_MEMORY";
372 // Gather mem operands
373 class X86VMemOperand<RegisterClass RC, string printMethod,
374 AsmOperandClass parserMatchClass>
375 : X86MemOperand<printMethod, parserMatchClass> {
376 let MIOperandInfo = (ops ptr_rc, i8imm, RC, i32imm, SEGMENT_REG);
379 def anymem : X86MemOperand<"printanymem">;
380 def X86any_fcmp : PatFrags<(ops node:$lhs, node:$rhs),
381 [(X86strict_fcmp node:$lhs, node:$rhs),
382 (X86cmp node:$lhs, node:$rhs)]>;
384 // FIXME: Right now we allow any size during parsing, but we might want to
385 // restrict to only unsized memory.
386 def opaquemem : X86MemOperand<"printopaquemem">;
388 def i8mem : X86MemOperand<"printbytemem", X86Mem8AsmOperand>;
389 def i16mem : X86MemOperand<"printwordmem", X86Mem16AsmOperand>;
390 def i32mem : X86MemOperand<"printdwordmem", X86Mem32AsmOperand>;
391 def i64mem : X86MemOperand<"printqwordmem", X86Mem64AsmOperand>;
392 def i128mem : X86MemOperand<"printxmmwordmem", X86Mem128AsmOperand>;
393 def i256mem : X86MemOperand<"printymmwordmem", X86Mem256AsmOperand>;
394 def i512mem : X86MemOperand<"printzmmwordmem", X86Mem512AsmOperand>;
395 def f32mem : X86MemOperand<"printdwordmem", X86Mem32AsmOperand>;
396 def f64mem : X86MemOperand<"printqwordmem", X86Mem64AsmOperand>;
397 def f80mem : X86MemOperand<"printtbytemem", X86Mem80AsmOperand>;
398 def f128mem : X86MemOperand<"printxmmwordmem", X86Mem128AsmOperand>;
399 def f256mem : X86MemOperand<"printymmwordmem", X86Mem256AsmOperand>;
400 def f512mem : X86MemOperand<"printzmmwordmem", X86Mem512AsmOperand>;
402 // Gather mem operands
403 def vx64mem : X86VMemOperand<VR128, "printqwordmem", X86Mem64_RC128Operand>;
404 def vx128mem : X86VMemOperand<VR128, "printxmmwordmem", X86Mem128_RC128Operand>;
405 def vx256mem : X86VMemOperand<VR128, "printymmwordmem", X86Mem256_RC128Operand>;
406 def vy128mem : X86VMemOperand<VR256, "printxmmwordmem", X86Mem128_RC256Operand>;
407 def vy256mem : X86VMemOperand<VR256, "printymmwordmem", X86Mem256_RC256Operand>;
409 def vx64xmem : X86VMemOperand<VR128X, "printqwordmem", X86Mem64_RC128XOperand>;
410 def vx128xmem : X86VMemOperand<VR128X, "printxmmwordmem", X86Mem128_RC128XOperand>;
411 def vx256xmem : X86VMemOperand<VR128X, "printymmwordmem", X86Mem256_RC128XOperand>;
412 def vy128xmem : X86VMemOperand<VR256X, "printxmmwordmem", X86Mem128_RC256XOperand>;
413 def vy256xmem : X86VMemOperand<VR256X, "printymmwordmem", X86Mem256_RC256XOperand>;
414 def vy512xmem : X86VMemOperand<VR256X, "printzmmwordmem", X86Mem512_RC256XOperand>;
415 def vz256mem : X86VMemOperand<VR512, "printymmwordmem", X86Mem256_RC512Operand>;
416 def vz512mem : X86VMemOperand<VR512, "printzmmwordmem", X86Mem512_RC512Operand>;
418 // A version of i8mem for use on x86-64 and x32 that uses a NOREX GPR instead
419 // of a plain GPR, so that it doesn't potentially require a REX prefix.
420 def ptr_rc_norex : PointerLikeRegClass<2>;
421 def ptr_rc_norex_nosp : PointerLikeRegClass<3>;
423 def i8mem_NOREX : Operand<iPTR> {
424 let PrintMethod = "printbytemem";
425 let MIOperandInfo = (ops ptr_rc_norex, i8imm, ptr_rc_norex_nosp, i32imm,
427 let ParserMatchClass = X86Mem8AsmOperand;
428 let OperandType = "OPERAND_MEMORY";
431 // GPRs available for tailcall.
432 // It represents GR32_TC, GR64_TC or GR64_TCW64.
433 def ptr_rc_tailcall : PointerLikeRegClass<4>;
435 // Special i32mem for addresses of load folding tail calls. These are not
436 // allowed to use callee-saved registers since they must be scheduled
437 // after callee-saved register are popped.
438 def i32mem_TC : Operand<i32> {
439 let PrintMethod = "printdwordmem";
440 let MIOperandInfo = (ops ptr_rc_tailcall, i8imm, ptr_rc_tailcall,
441 i32imm, SEGMENT_REG);
442 let ParserMatchClass = X86Mem32AsmOperand;
443 let OperandType = "OPERAND_MEMORY";
446 // Special i64mem for addresses of load folding tail calls. These are not
447 // allowed to use callee-saved registers since they must be scheduled
448 // after callee-saved register are popped.
449 def i64mem_TC : Operand<i64> {
450 let PrintMethod = "printqwordmem";
451 let MIOperandInfo = (ops ptr_rc_tailcall, i8imm,
452 ptr_rc_tailcall, i32imm, SEGMENT_REG);
453 let ParserMatchClass = X86Mem64AsmOperand;
454 let OperandType = "OPERAND_MEMORY";
457 // Special parser to detect 16-bit mode to select 16-bit displacement.
458 def X86AbsMem16AsmOperand : AsmOperandClass {
459 let Name = "AbsMem16";
460 let RenderMethod = "addAbsMemOperands";
461 let SuperClasses = [X86AbsMemAsmOperand];
464 // Branch targets print as pc-relative values.
465 class BranchTargetOperand<ValueType ty> : Operand<ty> {
466 let OperandType = "OPERAND_PCREL";
467 let PrintMethod = "printPCRelImm";
468 let ParserMatchClass = X86AbsMemAsmOperand;
471 def i32imm_brtarget : BranchTargetOperand<i32>;
472 def i16imm_brtarget : BranchTargetOperand<i16>;
474 // 64-bits but only 32 bits are significant, and those bits are treated as being
476 def i64i32imm_brtarget : BranchTargetOperand<i64>;
478 def brtarget : BranchTargetOperand<OtherVT>;
479 def brtarget8 : BranchTargetOperand<OtherVT>;
480 def brtarget16 : BranchTargetOperand<OtherVT> {
481 let ParserMatchClass = X86AbsMem16AsmOperand;
483 def brtarget32 : BranchTargetOperand<OtherVT>;
485 let RenderMethod = "addSrcIdxOperands" in {
486 def X86SrcIdx8Operand : AsmOperandClass {
487 let Name = "SrcIdx8";
488 let SuperClasses = [X86Mem8AsmOperand];
490 def X86SrcIdx16Operand : AsmOperandClass {
491 let Name = "SrcIdx16";
492 let SuperClasses = [X86Mem16AsmOperand];
494 def X86SrcIdx32Operand : AsmOperandClass {
495 let Name = "SrcIdx32";
496 let SuperClasses = [X86Mem32AsmOperand];
498 def X86SrcIdx64Operand : AsmOperandClass {
499 let Name = "SrcIdx64";
500 let SuperClasses = [X86Mem64AsmOperand];
502 } // RenderMethod = "addSrcIdxOperands"
504 let RenderMethod = "addDstIdxOperands" in {
505 def X86DstIdx8Operand : AsmOperandClass {
506 let Name = "DstIdx8";
507 let SuperClasses = [X86Mem8AsmOperand];
509 def X86DstIdx16Operand : AsmOperandClass {
510 let Name = "DstIdx16";
511 let SuperClasses = [X86Mem16AsmOperand];
513 def X86DstIdx32Operand : AsmOperandClass {
514 let Name = "DstIdx32";
515 let SuperClasses = [X86Mem32AsmOperand];
517 def X86DstIdx64Operand : AsmOperandClass {
518 let Name = "DstIdx64";
519 let SuperClasses = [X86Mem64AsmOperand];
521 } // RenderMethod = "addDstIdxOperands"
523 let RenderMethod = "addMemOffsOperands" in {
524 def X86MemOffs16_8AsmOperand : AsmOperandClass {
525 let Name = "MemOffs16_8";
526 let SuperClasses = [X86Mem8AsmOperand];
528 def X86MemOffs16_16AsmOperand : AsmOperandClass {
529 let Name = "MemOffs16_16";
530 let SuperClasses = [X86Mem16AsmOperand];
532 def X86MemOffs16_32AsmOperand : AsmOperandClass {
533 let Name = "MemOffs16_32";
534 let SuperClasses = [X86Mem32AsmOperand];
536 def X86MemOffs32_8AsmOperand : AsmOperandClass {
537 let Name = "MemOffs32_8";
538 let SuperClasses = [X86Mem8AsmOperand];
540 def X86MemOffs32_16AsmOperand : AsmOperandClass {
541 let Name = "MemOffs32_16";
542 let SuperClasses = [X86Mem16AsmOperand];
544 def X86MemOffs32_32AsmOperand : AsmOperandClass {
545 let Name = "MemOffs32_32";
546 let SuperClasses = [X86Mem32AsmOperand];
548 def X86MemOffs32_64AsmOperand : AsmOperandClass {
549 let Name = "MemOffs32_64";
550 let SuperClasses = [X86Mem64AsmOperand];
552 def X86MemOffs64_8AsmOperand : AsmOperandClass {
553 let Name = "MemOffs64_8";
554 let SuperClasses = [X86Mem8AsmOperand];
556 def X86MemOffs64_16AsmOperand : AsmOperandClass {
557 let Name = "MemOffs64_16";
558 let SuperClasses = [X86Mem16AsmOperand];
560 def X86MemOffs64_32AsmOperand : AsmOperandClass {
561 let Name = "MemOffs64_32";
562 let SuperClasses = [X86Mem32AsmOperand];
564 def X86MemOffs64_64AsmOperand : AsmOperandClass {
565 let Name = "MemOffs64_64";
566 let SuperClasses = [X86Mem64AsmOperand];
568 } // RenderMethod = "addMemOffsOperands"
570 class X86SrcIdxOperand<string printMethod, AsmOperandClass parserMatchClass>
571 : X86MemOperand<printMethod, parserMatchClass> {
572 let MIOperandInfo = (ops ptr_rc, SEGMENT_REG);
575 class X86DstIdxOperand<string printMethod, AsmOperandClass parserMatchClass>
576 : X86MemOperand<printMethod, parserMatchClass> {
577 let MIOperandInfo = (ops ptr_rc);
580 def srcidx8 : X86SrcIdxOperand<"printSrcIdx8", X86SrcIdx8Operand>;
581 def srcidx16 : X86SrcIdxOperand<"printSrcIdx16", X86SrcIdx16Operand>;
582 def srcidx32 : X86SrcIdxOperand<"printSrcIdx32", X86SrcIdx32Operand>;
583 def srcidx64 : X86SrcIdxOperand<"printSrcIdx64", X86SrcIdx64Operand>;
584 def dstidx8 : X86DstIdxOperand<"printDstIdx8", X86DstIdx8Operand>;
585 def dstidx16 : X86DstIdxOperand<"printDstIdx16", X86DstIdx16Operand>;
586 def dstidx32 : X86DstIdxOperand<"printDstIdx32", X86DstIdx32Operand>;
587 def dstidx64 : X86DstIdxOperand<"printDstIdx64", X86DstIdx64Operand>;
589 class X86MemOffsOperand<Operand immOperand, string printMethod,
590 AsmOperandClass parserMatchClass>
591 : X86MemOperand<printMethod, parserMatchClass> {
592 let MIOperandInfo = (ops immOperand, SEGMENT_REG);
595 def offset16_8 : X86MemOffsOperand<i16imm, "printMemOffs8",
596 X86MemOffs16_8AsmOperand>;
597 def offset16_16 : X86MemOffsOperand<i16imm, "printMemOffs16",
598 X86MemOffs16_16AsmOperand>;
599 def offset16_32 : X86MemOffsOperand<i16imm, "printMemOffs32",
600 X86MemOffs16_32AsmOperand>;
601 def offset32_8 : X86MemOffsOperand<i32imm, "printMemOffs8",
602 X86MemOffs32_8AsmOperand>;
603 def offset32_16 : X86MemOffsOperand<i32imm, "printMemOffs16",
604 X86MemOffs32_16AsmOperand>;
605 def offset32_32 : X86MemOffsOperand<i32imm, "printMemOffs32",
606 X86MemOffs32_32AsmOperand>;
607 def offset32_64 : X86MemOffsOperand<i32imm, "printMemOffs64",
608 X86MemOffs32_64AsmOperand>;
609 def offset64_8 : X86MemOffsOperand<i64imm, "printMemOffs8",
610 X86MemOffs64_8AsmOperand>;
611 def offset64_16 : X86MemOffsOperand<i64imm, "printMemOffs16",
612 X86MemOffs64_16AsmOperand>;
613 def offset64_32 : X86MemOffsOperand<i64imm, "printMemOffs32",
614 X86MemOffs64_32AsmOperand>;
615 def offset64_64 : X86MemOffsOperand<i64imm, "printMemOffs64",
616 X86MemOffs64_64AsmOperand>;
618 def ccode : Operand<i8> {
619 let PrintMethod = "printCondCode";
620 let OperandNamespace = "X86";
621 let OperandType = "OPERAND_COND_CODE";
624 class ImmSExtAsmOperandClass : AsmOperandClass {
625 let SuperClasses = [ImmAsmOperand];
626 let RenderMethod = "addImmOperands";
629 def X86GR32orGR64AsmOperand : AsmOperandClass {
630 let Name = "GR32orGR64";
633 def GR32orGR64 : RegisterOperand<GR32> {
634 let ParserMatchClass = X86GR32orGR64AsmOperand;
636 def AVX512RCOperand : AsmOperandClass {
637 let Name = "AVX512RC";
639 def AVX512RC : Operand<i32> {
640 let PrintMethod = "printRoundingControl";
641 let OperandNamespace = "X86";
642 let OperandType = "OPERAND_ROUNDING_CONTROL";
643 let ParserMatchClass = AVX512RCOperand;
646 // Sign-extended immediate classes. We don't need to define the full lattice
647 // here because there is no instruction with an ambiguity between ImmSExti64i32
650 // The strange ranges come from the fact that the assembler always works with
651 // 64-bit immediates, but for a 16-bit target value we want to accept both "-1"
652 // (which will be a -1ULL), and "0xFF" (-1 in 16-bits).
655 // [0xFFFFFFFF80000000, 0xFFFFFFFFFFFFFFFF]
656 def ImmSExti64i32AsmOperand : ImmSExtAsmOperandClass {
657 let Name = "ImmSExti64i32";
660 // [0, 0x0000007F] | [0x000000000000FF80, 0x000000000000FFFF] |
661 // [0xFFFFFFFFFFFFFF80, 0xFFFFFFFFFFFFFFFF]
662 def ImmSExti16i8AsmOperand : ImmSExtAsmOperandClass {
663 let Name = "ImmSExti16i8";
664 let SuperClasses = [ImmSExti64i32AsmOperand];
667 // [0, 0x0000007F] | [0x00000000FFFFFF80, 0x00000000FFFFFFFF] |
668 // [0xFFFFFFFFFFFFFF80, 0xFFFFFFFFFFFFFFFF]
669 def ImmSExti32i8AsmOperand : ImmSExtAsmOperandClass {
670 let Name = "ImmSExti32i8";
674 // [0xFFFFFFFFFFFFFF80, 0xFFFFFFFFFFFFFFFF]
675 def ImmSExti64i8AsmOperand : ImmSExtAsmOperandClass {
676 let Name = "ImmSExti64i8";
677 let SuperClasses = [ImmSExti16i8AsmOperand, ImmSExti32i8AsmOperand,
678 ImmSExti64i32AsmOperand];
681 // 4-bit immediate used by some XOP instructions
683 def ImmUnsignedi4AsmOperand : AsmOperandClass {
684 let Name = "ImmUnsignedi4";
685 let RenderMethod = "addImmOperands";
686 let DiagnosticType = "InvalidImmUnsignedi4";
689 // Unsigned immediate used by SSE/AVX instructions
691 // [0xFFFFFFFFFFFFFF80, 0xFFFFFFFFFFFFFFFF]
692 def ImmUnsignedi8AsmOperand : AsmOperandClass {
693 let Name = "ImmUnsignedi8";
694 let RenderMethod = "addImmOperands";
697 // A couple of more descriptive operand definitions.
698 // 16-bits but only 8 bits are significant.
699 def i16i8imm : Operand<i16> {
700 let ParserMatchClass = ImmSExti16i8AsmOperand;
701 let OperandType = "OPERAND_IMMEDIATE";
703 // 32-bits but only 8 bits are significant.
704 def i32i8imm : Operand<i32> {
705 let ParserMatchClass = ImmSExti32i8AsmOperand;
706 let OperandType = "OPERAND_IMMEDIATE";
709 // 64-bits but only 32 bits are significant.
710 def i64i32imm : Operand<i64> {
711 let ParserMatchClass = ImmSExti64i32AsmOperand;
712 let OperandType = "OPERAND_IMMEDIATE";
715 // 64-bits but only 8 bits are significant.
716 def i64i8imm : Operand<i64> {
717 let ParserMatchClass = ImmSExti64i8AsmOperand;
718 let OperandType = "OPERAND_IMMEDIATE";
721 // Unsigned 4-bit immediate used by some XOP instructions.
722 def u4imm : Operand<i8> {
723 let PrintMethod = "printU8Imm";
724 let ParserMatchClass = ImmUnsignedi4AsmOperand;
725 let OperandType = "OPERAND_IMMEDIATE";
728 // Unsigned 8-bit immediate used by SSE/AVX instructions.
729 def u8imm : Operand<i8> {
730 let PrintMethod = "printU8Imm";
731 let ParserMatchClass = ImmUnsignedi8AsmOperand;
732 let OperandType = "OPERAND_IMMEDIATE";
735 // 16-bit immediate but only 8-bits are significant and they are unsigned.
736 // Used by BT instructions.
737 def i16u8imm : Operand<i16> {
738 let PrintMethod = "printU8Imm";
739 let ParserMatchClass = ImmUnsignedi8AsmOperand;
740 let OperandType = "OPERAND_IMMEDIATE";
743 // 32-bit immediate but only 8-bits are significant and they are unsigned.
744 // Used by some SSE/AVX instructions that use intrinsics.
745 def i32u8imm : Operand<i32> {
746 let PrintMethod = "printU8Imm";
747 let ParserMatchClass = ImmUnsignedi8AsmOperand;
748 let OperandType = "OPERAND_IMMEDIATE";
751 // 64-bit immediate but only 8-bits are significant and they are unsigned.
752 // Used by BT instructions.
753 def i64u8imm : Operand<i64> {
754 let PrintMethod = "printU8Imm";
755 let ParserMatchClass = ImmUnsignedi8AsmOperand;
756 let OperandType = "OPERAND_IMMEDIATE";
759 def lea64_32mem : Operand<i32> {
760 let PrintMethod = "printanymem";
761 let MIOperandInfo = (ops GR64, i8imm, GR64_NOSP, i32imm, SEGMENT_REG);
762 let ParserMatchClass = X86MemAsmOperand;
765 // Memory operands that use 64-bit pointers in both ILP32 and LP64.
766 def lea64mem : Operand<i64> {
767 let PrintMethod = "printanymem";
768 let MIOperandInfo = (ops GR64, i8imm, GR64_NOSP, i32imm, SEGMENT_REG);
769 let ParserMatchClass = X86MemAsmOperand;
772 let RenderMethod = "addMaskPairOperands" in {
773 def VK1PairAsmOperand : AsmOperandClass { let Name = "VK1Pair"; }
774 def VK2PairAsmOperand : AsmOperandClass { let Name = "VK2Pair"; }
775 def VK4PairAsmOperand : AsmOperandClass { let Name = "VK4Pair"; }
776 def VK8PairAsmOperand : AsmOperandClass { let Name = "VK8Pair"; }
777 def VK16PairAsmOperand : AsmOperandClass { let Name = "VK16Pair"; }
780 def VK1Pair : RegisterOperand<VK1PAIR, "printVKPair"> {
781 let ParserMatchClass = VK1PairAsmOperand;
784 def VK2Pair : RegisterOperand<VK2PAIR, "printVKPair"> {
785 let ParserMatchClass = VK2PairAsmOperand;
788 def VK4Pair : RegisterOperand<VK4PAIR, "printVKPair"> {
789 let ParserMatchClass = VK4PairAsmOperand;
792 def VK8Pair : RegisterOperand<VK8PAIR, "printVKPair"> {
793 let ParserMatchClass = VK8PairAsmOperand;
796 def VK16Pair : RegisterOperand<VK16PAIR, "printVKPair"> {
797 let ParserMatchClass = VK16PairAsmOperand;
800 //===----------------------------------------------------------------------===//
801 // X86 Complex Pattern Definitions.
804 // Define X86-specific addressing mode.
805 def addr : ComplexPattern<iPTR, 5, "selectAddr", [], [SDNPWantParent]>;
806 def lea32addr : ComplexPattern<i32, 5, "selectLEAAddr",
807 [add, sub, mul, X86mul_imm, shl, or, frameindex],
809 // In 64-bit mode 32-bit LEAs can use RIP-relative addressing.
810 def lea64_32addr : ComplexPattern<i32, 5, "selectLEA64_32Addr",
811 [add, sub, mul, X86mul_imm, shl, or,
812 frameindex, X86WrapperRIP],
815 def tls32addr : ComplexPattern<i32, 5, "selectTLSADDRAddr",
816 [tglobaltlsaddr], []>;
818 def tls32baseaddr : ComplexPattern<i32, 5, "selectTLSADDRAddr",
819 [tglobaltlsaddr], []>;
821 def lea64addr : ComplexPattern<i64, 5, "selectLEAAddr",
822 [add, sub, mul, X86mul_imm, shl, or, frameindex,
825 def tls64addr : ComplexPattern<i64, 5, "selectTLSADDRAddr",
826 [tglobaltlsaddr], []>;
828 def tls64baseaddr : ComplexPattern<i64, 5, "selectTLSADDRAddr",
829 [tglobaltlsaddr], []>;
831 def vectoraddr : ComplexPattern<iPTR, 5, "selectVectorAddr", [],[SDNPWantParent]>;
833 // A relocatable immediate is either an immediate operand or an operand that can
834 // be relocated by the linker to an immediate, such as a regular symbol in
836 def relocImm : ComplexPattern<iAny, 1, "selectRelocImm", [imm, X86Wrapper], [],
839 //===----------------------------------------------------------------------===//
840 // X86 Instruction Predicate Definitions.
841 def TruePredicate : Predicate<"true">;
843 def HasCMov : Predicate<"Subtarget->hasCMov()">;
844 def NoCMov : Predicate<"!Subtarget->hasCMov()">;
846 def HasMMX : Predicate<"Subtarget->hasMMX()">;
847 def Has3DNow : Predicate<"Subtarget->has3DNow()">;
848 def Has3DNowA : Predicate<"Subtarget->has3DNowA()">;
849 def HasSSE1 : Predicate<"Subtarget->hasSSE1()">;
850 def UseSSE1 : Predicate<"Subtarget->hasSSE1() && !Subtarget->hasAVX()">;
851 def HasSSE2 : Predicate<"Subtarget->hasSSE2()">;
852 def UseSSE2 : Predicate<"Subtarget->hasSSE2() && !Subtarget->hasAVX()">;
853 def HasSSE3 : Predicate<"Subtarget->hasSSE3()">;
854 def UseSSE3 : Predicate<"Subtarget->hasSSE3() && !Subtarget->hasAVX()">;
855 def HasSSSE3 : Predicate<"Subtarget->hasSSSE3()">;
856 def UseSSSE3 : Predicate<"Subtarget->hasSSSE3() && !Subtarget->hasAVX()">;
857 def HasSSE41 : Predicate<"Subtarget->hasSSE41()">;
858 def NoSSE41 : Predicate<"!Subtarget->hasSSE41()">;
859 def UseSSE41 : Predicate<"Subtarget->hasSSE41() && !Subtarget->hasAVX()">;
860 def HasSSE42 : Predicate<"Subtarget->hasSSE42()">;
861 def UseSSE42 : Predicate<"Subtarget->hasSSE42() && !Subtarget->hasAVX()">;
862 def HasSSE4A : Predicate<"Subtarget->hasSSE4A()">;
863 def NoAVX : Predicate<"!Subtarget->hasAVX()">;
864 def HasAVX : Predicate<"Subtarget->hasAVX()">;
865 def HasAVX2 : Predicate<"Subtarget->hasAVX2()">;
866 def HasAVX1Only : Predicate<"Subtarget->hasAVX() && !Subtarget->hasAVX2()">;
867 def HasAVX512 : Predicate<"Subtarget->hasAVX512()">;
868 def UseAVX : Predicate<"Subtarget->hasAVX() && !Subtarget->hasAVX512()">;
869 def UseAVX2 : Predicate<"Subtarget->hasAVX2() && !Subtarget->hasAVX512()">;
870 def NoAVX512 : Predicate<"!Subtarget->hasAVX512()">;
871 def HasCDI : Predicate<"Subtarget->hasCDI()">;
872 def HasVPOPCNTDQ : Predicate<"Subtarget->hasVPOPCNTDQ()">;
873 def HasPFI : Predicate<"Subtarget->hasPFI()">;
874 def HasERI : Predicate<"Subtarget->hasERI()">;
875 def HasDQI : Predicate<"Subtarget->hasDQI()">;
876 def NoDQI : Predicate<"!Subtarget->hasDQI()">;
877 def HasBWI : Predicate<"Subtarget->hasBWI()">;
878 def NoBWI : Predicate<"!Subtarget->hasBWI()">;
879 def HasVLX : Predicate<"Subtarget->hasVLX()">;
880 def NoVLX : Predicate<"!Subtarget->hasVLX()">;
881 def NoVLX_Or_NoBWI : Predicate<"!Subtarget->hasVLX() || !Subtarget->hasBWI()">;
882 def NoVLX_Or_NoDQI : Predicate<"!Subtarget->hasVLX() || !Subtarget->hasDQI()">;
883 def PKU : Predicate<"Subtarget->hasPKU()">;
884 def HasVNNI : Predicate<"Subtarget->hasVNNI()">;
885 def HasVP2INTERSECT : Predicate<"Subtarget->hasVP2INTERSECT()">;
886 def HasBF16 : Predicate<"Subtarget->hasBF16()">;
888 def HasBITALG : Predicate<"Subtarget->hasBITALG()">;
889 def HasPOPCNT : Predicate<"Subtarget->hasPOPCNT()">;
890 def HasAES : Predicate<"Subtarget->hasAES()">;
891 def HasVAES : Predicate<"Subtarget->hasVAES()">;
892 def NoVLX_Or_NoVAES : Predicate<"!Subtarget->hasVLX() || !Subtarget->hasVAES()">;
893 def HasFXSR : Predicate<"Subtarget->hasFXSR()">;
894 def HasXSAVE : Predicate<"Subtarget->hasXSAVE()">;
895 def HasXSAVEOPT : Predicate<"Subtarget->hasXSAVEOPT()">;
896 def HasXSAVEC : Predicate<"Subtarget->hasXSAVEC()">;
897 def HasXSAVES : Predicate<"Subtarget->hasXSAVES()">;
898 def HasPCLMUL : Predicate<"Subtarget->hasPCLMUL()">;
899 def NoVLX_Or_NoVPCLMULQDQ :
900 Predicate<"!Subtarget->hasVLX() || !Subtarget->hasVPCLMULQDQ()">;
901 def HasVPCLMULQDQ : Predicate<"Subtarget->hasVPCLMULQDQ()">;
902 def HasGFNI : Predicate<"Subtarget->hasGFNI()">;
903 def HasFMA : Predicate<"Subtarget->hasFMA()">;
904 def HasFMA4 : Predicate<"Subtarget->hasFMA4()">;
905 def NoFMA4 : Predicate<"!Subtarget->hasFMA4()">;
906 def HasXOP : Predicate<"Subtarget->hasXOP()">;
907 def HasTBM : Predicate<"Subtarget->hasTBM()">;
908 def NoTBM : Predicate<"!Subtarget->hasTBM()">;
909 def HasLWP : Predicate<"Subtarget->hasLWP()">;
910 def HasMOVBE : Predicate<"Subtarget->hasMOVBE()">;
911 def HasRDRAND : Predicate<"Subtarget->hasRDRAND()">;
912 def HasF16C : Predicate<"Subtarget->hasF16C()">;
913 def HasFSGSBase : Predicate<"Subtarget->hasFSGSBase()">;
914 def HasLZCNT : Predicate<"Subtarget->hasLZCNT()">;
915 def HasBMI : Predicate<"Subtarget->hasBMI()">;
916 def HasBMI2 : Predicate<"Subtarget->hasBMI2()">;
917 def NoBMI2 : Predicate<"!Subtarget->hasBMI2()">;
918 def HasVBMI : Predicate<"Subtarget->hasVBMI()">;
919 def HasVBMI2 : Predicate<"Subtarget->hasVBMI2()">;
920 def HasIFMA : Predicate<"Subtarget->hasIFMA()">;
921 def HasRTM : Predicate<"Subtarget->hasRTM()">;
922 def HasADX : Predicate<"Subtarget->hasADX()">;
923 def HasSHA : Predicate<"Subtarget->hasSHA()">;
924 def HasSGX : Predicate<"Subtarget->hasSGX()">;
925 def HasPRFCHW : Predicate<"Subtarget->hasPRFCHW()">;
926 def HasRDSEED : Predicate<"Subtarget->hasRDSEED()">;
927 def HasSSEPrefetch : Predicate<"Subtarget->hasSSEPrefetch()">;
928 def NoSSEPrefetch : Predicate<"!Subtarget->hasSSEPrefetch()">;
929 def HasPrefetchW : Predicate<"Subtarget->hasPRFCHW()">;
930 def HasPREFETCHWT1 : Predicate<"Subtarget->hasPREFETCHWT1()">;
931 def HasLAHFSAHF : Predicate<"Subtarget->hasLAHFSAHF()">;
932 def HasMWAITX : Predicate<"Subtarget->hasMWAITX()">;
933 def HasCLZERO : Predicate<"Subtarget->hasCLZERO()">;
934 def HasCLDEMOTE : Predicate<"Subtarget->hasCLDEMOTE()">;
935 def HasMOVDIRI : Predicate<"Subtarget->hasMOVDIRI()">;
936 def HasMOVDIR64B : Predicate<"Subtarget->hasMOVDIR64B()">;
937 def HasPTWRITE : Predicate<"Subtarget->hasPTWRITE()">;
938 def FPStackf32 : Predicate<"!Subtarget->hasSSE1()">;
939 def FPStackf64 : Predicate<"!Subtarget->hasSSE2()">;
940 def HasSHSTK : Predicate<"Subtarget->hasSHSTK()">;
941 def HasCLFLUSHOPT : Predicate<"Subtarget->hasCLFLUSHOPT()">;
942 def HasCLWB : Predicate<"Subtarget->hasCLWB()">;
943 def HasWBNOINVD : Predicate<"Subtarget->hasWBNOINVD()">;
944 def HasRDPID : Predicate<"Subtarget->hasRDPID()">;
945 def HasWAITPKG : Predicate<"Subtarget->hasWAITPKG()">;
946 def HasINVPCID : Predicate<"Subtarget->hasINVPCID()">;
947 def HasCmpxchg8b : Predicate<"Subtarget->hasCmpxchg8b()">;
948 def HasCmpxchg16b: Predicate<"Subtarget->hasCmpxchg16b()">;
949 def HasPCONFIG : Predicate<"Subtarget->hasPCONFIG()">;
950 def HasENQCMD : Predicate<"Subtarget->hasENQCMD()">;
951 def Not64BitMode : Predicate<"!Subtarget->is64Bit()">,
952 AssemblerPredicate<"!Mode64Bit", "Not 64-bit mode">;
953 def In64BitMode : Predicate<"Subtarget->is64Bit()">,
954 AssemblerPredicate<"Mode64Bit", "64-bit mode">;
955 def IsLP64 : Predicate<"Subtarget->isTarget64BitLP64()">;
956 def NotLP64 : Predicate<"!Subtarget->isTarget64BitLP64()">;
957 def In16BitMode : Predicate<"Subtarget->is16Bit()">,
958 AssemblerPredicate<"Mode16Bit", "16-bit mode">;
959 def Not16BitMode : Predicate<"!Subtarget->is16Bit()">,
960 AssemblerPredicate<"!Mode16Bit", "Not 16-bit mode">;
961 def In32BitMode : Predicate<"Subtarget->is32Bit()">,
962 AssemblerPredicate<"Mode32Bit", "32-bit mode">;
963 def IsWin64 : Predicate<"Subtarget->isTargetWin64()">;
964 def NotWin64 : Predicate<"!Subtarget->isTargetWin64()">;
965 def NotWin64WithoutFP : Predicate<"!Subtarget->isTargetWin64() ||"
966 "Subtarget->getFrameLowering()->hasFP(*MF)"> {
967 let RecomputePerFunction = 1;
969 def IsPS4 : Predicate<"Subtarget->isTargetPS4()">;
970 def NotPS4 : Predicate<"!Subtarget->isTargetPS4()">;
971 def IsNaCl : Predicate<"Subtarget->isTargetNaCl()">;
972 def NotNaCl : Predicate<"!Subtarget->isTargetNaCl()">;
973 def SmallCode : Predicate<"TM.getCodeModel() == CodeModel::Small">;
974 def KernelCode : Predicate<"TM.getCodeModel() == CodeModel::Kernel">;
975 def NearData : Predicate<"TM.getCodeModel() == CodeModel::Small ||"
976 "TM.getCodeModel() == CodeModel::Kernel">;
977 def IsNotPIC : Predicate<"!TM.isPositionIndependent()">;
979 // We could compute these on a per-module basis but doing so requires accessing
980 // the Function object through the <Target>Subtarget and objections were raised
981 // to that (see post-commit review comments for r301750).
982 let RecomputePerFunction = 1 in {
983 def OptForSize : Predicate<"shouldOptForSize(MF)">;
984 def OptForMinSize : Predicate<"MF->getFunction().hasMinSize()">;
985 def OptForSpeed : Predicate<"!shouldOptForSize(MF)">;
986 def UseIncDec : Predicate<"!Subtarget->slowIncDec() || "
987 "shouldOptForSize(MF)">;
988 def NoSSE41_Or_OptForSize : Predicate<"shouldOptForSize(MF) || "
989 "!Subtarget->hasSSE41()">;
992 def CallImmAddr : Predicate<"Subtarget->isLegalToCallImmediateAddr()">;
993 def FavorMemIndirectCall : Predicate<"!Subtarget->slowTwoMemOps()">;
994 def HasFastMem32 : Predicate<"!Subtarget->isUnalignedMem32Slow()">;
995 def HasFastLZCNT : Predicate<"Subtarget->hasFastLZCNT()">;
996 def HasFastSHLDRotate : Predicate<"Subtarget->hasFastSHLDRotate()">;
997 def HasERMSB : Predicate<"Subtarget->hasERMSB()">;
998 def HasMFence : Predicate<"Subtarget->hasMFence()">;
999 def UseIndirectThunkCalls : Predicate<"Subtarget->useIndirectThunkCalls()">;
1000 def NotUseIndirectThunkCalls : Predicate<"!Subtarget->useIndirectThunkCalls()">;
1002 //===----------------------------------------------------------------------===//
1003 // X86 Instruction Format Definitions.
1006 include "X86InstrFormats.td"
1008 //===----------------------------------------------------------------------===//
1009 // Pattern fragments.
1012 // X86 specific condition code. These correspond to CondCode in
1013 // X86InstrInfo.h. They must be kept in synch.
1014 def X86_COND_O : PatLeaf<(i8 0)>;
1015 def X86_COND_NO : PatLeaf<(i8 1)>;
1016 def X86_COND_B : PatLeaf<(i8 2)>; // alt. COND_C
1017 def X86_COND_AE : PatLeaf<(i8 3)>; // alt. COND_NC
1018 def X86_COND_E : PatLeaf<(i8 4)>; // alt. COND_Z
1019 def X86_COND_NE : PatLeaf<(i8 5)>; // alt. COND_NZ
1020 def X86_COND_BE : PatLeaf<(i8 6)>; // alt. COND_NA
1021 def X86_COND_A : PatLeaf<(i8 7)>; // alt. COND_NBE
1022 def X86_COND_S : PatLeaf<(i8 8)>;
1023 def X86_COND_NS : PatLeaf<(i8 9)>;
1024 def X86_COND_P : PatLeaf<(i8 10)>; // alt. COND_PE
1025 def X86_COND_NP : PatLeaf<(i8 11)>; // alt. COND_PO
1026 def X86_COND_L : PatLeaf<(i8 12)>; // alt. COND_NGE
1027 def X86_COND_GE : PatLeaf<(i8 13)>; // alt. COND_NL
1028 def X86_COND_LE : PatLeaf<(i8 14)>; // alt. COND_NG
1029 def X86_COND_G : PatLeaf<(i8 15)>; // alt. COND_NLE
1031 def i16immSExt8 : ImmLeaf<i16, [{ return isInt<8>(Imm); }]>;
1032 def i32immSExt8 : ImmLeaf<i32, [{ return isInt<8>(Imm); }]>;
1033 def i64immSExt8 : ImmLeaf<i64, [{ return isInt<8>(Imm); }]>;
1034 def i64immSExt32 : ImmLeaf<i64, [{ return isInt<32>(Imm); }]>;
1036 // FIXME: Ideally we would just replace the above i*immSExt* matchers with
1037 // relocImm-based matchers, but then FastISel would be unable to use them.
1038 def i64relocImmSExt8 : PatLeaf<(i64 relocImm), [{
1039 return isSExtRelocImm<8>(N);
1041 def i64relocImmSExt32 : PatLeaf<(i64 relocImm), [{
1042 return isSExtRelocImm<32>(N);
1045 // If we have multiple users of an immediate, it's much smaller to reuse
1046 // the register, rather than encode the immediate in every instruction.
1047 // This has the risk of increasing register pressure from stretched live
1048 // ranges, however, the immediates should be trivial to rematerialize by
1049 // the RA in the event of high register pressure.
1050 // TODO : This is currently enabled for stores and binary ops. There are more
1051 // cases for which this can be enabled, though this catches the bulk of the
1053 // TODO2 : This should really also be enabled under O2, but there's currently
1054 // an issue with RA where we don't pull the constants into their users
1055 // when we rematerialize them. I'll follow-up on enabling O2 after we fix that
1057 // TODO3 : This is currently limited to single basic blocks (DAG creation
1058 // pulls block immediates to the top and merges them if necessary).
1059 // Eventually, it would be nice to allow ConstantHoisting to merge constants
1060 // globally for potentially added savings.
1062 def relocImm8_su : PatLeaf<(i8 relocImm), [{
1063 return !shouldAvoidImmediateInstFormsForSize(N);
1065 def relocImm16_su : PatLeaf<(i16 relocImm), [{
1066 return !shouldAvoidImmediateInstFormsForSize(N);
1068 def relocImm32_su : PatLeaf<(i32 relocImm), [{
1069 return !shouldAvoidImmediateInstFormsForSize(N);
1072 def i16immSExt8_su : PatLeaf<(i16immSExt8), [{
1073 return !shouldAvoidImmediateInstFormsForSize(N);
1075 def i32immSExt8_su : PatLeaf<(i32immSExt8), [{
1076 return !shouldAvoidImmediateInstFormsForSize(N);
1078 def i64immSExt8_su : PatLeaf<(i64immSExt8), [{
1079 return !shouldAvoidImmediateInstFormsForSize(N);
1082 def i64relocImmSExt8_su : PatLeaf<(i64relocImmSExt8), [{
1083 return !shouldAvoidImmediateInstFormsForSize(N);
1085 def i64relocImmSExt32_su : PatLeaf<(i64relocImmSExt32), [{
1086 return !shouldAvoidImmediateInstFormsForSize(N);
1089 // i64immZExt32 predicate - True if the 64-bit immediate fits in a 32-bit
1091 def i64immZExt32 : ImmLeaf<i64, [{ return isUInt<32>(Imm); }]>;
1093 def i64immZExt32SExt8 : ImmLeaf<i64, [{
1094 return isUInt<32>(Imm) && isInt<8>(static_cast<int32_t>(Imm));
1097 // Helper fragments for loads.
1099 // It's safe to fold a zextload/extload from i1 as a regular i8 load. The
1100 // upper bits are guaranteed to be zero and we were going to emit a MOV8rm
1101 // which might get folded during peephole anyway.
1102 def loadi8 : PatFrag<(ops node:$ptr), (i8 (unindexedload node:$ptr)), [{
1103 LoadSDNode *LD = cast<LoadSDNode>(N);
1104 ISD::LoadExtType ExtType = LD->getExtensionType();
1105 return ExtType == ISD::NON_EXTLOAD || ExtType == ISD::EXTLOAD ||
1106 ExtType == ISD::ZEXTLOAD;
1109 // It's always safe to treat a anyext i16 load as a i32 load if the i16 is
1110 // known to be 32-bit aligned or better. Ditto for i8 to i16.
1111 def loadi16 : PatFrag<(ops node:$ptr), (i16 (unindexedload node:$ptr)), [{
1112 LoadSDNode *LD = cast<LoadSDNode>(N);
1113 ISD::LoadExtType ExtType = LD->getExtensionType();
1114 if (ExtType == ISD::NON_EXTLOAD)
1116 if (ExtType == ISD::EXTLOAD)
1117 return LD->getAlignment() >= 2 && LD->isSimple();
1121 def loadi32 : PatFrag<(ops node:$ptr), (i32 (unindexedload node:$ptr)), [{
1122 LoadSDNode *LD = cast<LoadSDNode>(N);
1123 ISD::LoadExtType ExtType = LD->getExtensionType();
1124 if (ExtType == ISD::NON_EXTLOAD)
1126 if (ExtType == ISD::EXTLOAD)
1127 return LD->getAlignment() >= 4 && LD->isSimple();
1131 def loadi64 : PatFrag<(ops node:$ptr), (i64 (load node:$ptr))>;
1132 def loadf32 : PatFrag<(ops node:$ptr), (f32 (load node:$ptr))>;
1133 def loadf64 : PatFrag<(ops node:$ptr), (f64 (load node:$ptr))>;
1134 def loadf80 : PatFrag<(ops node:$ptr), (f80 (load node:$ptr))>;
1135 def loadf128 : PatFrag<(ops node:$ptr), (f128 (load node:$ptr))>;
1136 def alignedloadf128 : PatFrag<(ops node:$ptr), (f128 (load node:$ptr)), [{
1137 LoadSDNode *Ld = cast<LoadSDNode>(N);
1138 return Ld->getAlignment() >= Ld->getMemoryVT().getStoreSize();
1140 def memopf128 : PatFrag<(ops node:$ptr), (f128 (load node:$ptr)), [{
1141 LoadSDNode *Ld = cast<LoadSDNode>(N);
1142 return Subtarget->hasSSEUnalignedMem() ||
1143 Ld->getAlignment() >= Ld->getMemoryVT().getStoreSize();
1146 def sextloadi16i8 : PatFrag<(ops node:$ptr), (i16 (sextloadi8 node:$ptr))>;
1147 def sextloadi32i8 : PatFrag<(ops node:$ptr), (i32 (sextloadi8 node:$ptr))>;
1148 def sextloadi32i16 : PatFrag<(ops node:$ptr), (i32 (sextloadi16 node:$ptr))>;
1149 def sextloadi64i8 : PatFrag<(ops node:$ptr), (i64 (sextloadi8 node:$ptr))>;
1150 def sextloadi64i16 : PatFrag<(ops node:$ptr), (i64 (sextloadi16 node:$ptr))>;
1151 def sextloadi64i32 : PatFrag<(ops node:$ptr), (i64 (sextloadi32 node:$ptr))>;
1153 def zextloadi8i1 : PatFrag<(ops node:$ptr), (i8 (zextloadi1 node:$ptr))>;
1154 def zextloadi16i1 : PatFrag<(ops node:$ptr), (i16 (zextloadi1 node:$ptr))>;
1155 def zextloadi32i1 : PatFrag<(ops node:$ptr), (i32 (zextloadi1 node:$ptr))>;
1156 def zextloadi16i8 : PatFrag<(ops node:$ptr), (i16 (zextloadi8 node:$ptr))>;
1157 def zextloadi32i8 : PatFrag<(ops node:$ptr), (i32 (zextloadi8 node:$ptr))>;
1158 def zextloadi32i16 : PatFrag<(ops node:$ptr), (i32 (zextloadi16 node:$ptr))>;
1159 def zextloadi64i1 : PatFrag<(ops node:$ptr), (i64 (zextloadi1 node:$ptr))>;
1160 def zextloadi64i8 : PatFrag<(ops node:$ptr), (i64 (zextloadi8 node:$ptr))>;
1161 def zextloadi64i16 : PatFrag<(ops node:$ptr), (i64 (zextloadi16 node:$ptr))>;
1162 def zextloadi64i32 : PatFrag<(ops node:$ptr), (i64 (zextloadi32 node:$ptr))>;
1164 def extloadi8i1 : PatFrag<(ops node:$ptr), (i8 (extloadi1 node:$ptr))>;
1165 def extloadi16i1 : PatFrag<(ops node:$ptr), (i16 (extloadi1 node:$ptr))>;
1166 def extloadi32i1 : PatFrag<(ops node:$ptr), (i32 (extloadi1 node:$ptr))>;
1167 def extloadi16i8 : PatFrag<(ops node:$ptr), (i16 (extloadi8 node:$ptr))>;
1168 def extloadi32i8 : PatFrag<(ops node:$ptr), (i32 (extloadi8 node:$ptr))>;
1169 def extloadi32i16 : PatFrag<(ops node:$ptr), (i32 (extloadi16 node:$ptr))>;
1170 def extloadi64i1 : PatFrag<(ops node:$ptr), (i64 (extloadi1 node:$ptr))>;
1171 def extloadi64i8 : PatFrag<(ops node:$ptr), (i64 (extloadi8 node:$ptr))>;
1172 def extloadi64i16 : PatFrag<(ops node:$ptr), (i64 (extloadi16 node:$ptr))>;
1174 // We can treat an i8/i16 extending load to i64 as a 32 bit load if its known
1175 // to be 4 byte aligned or better.
1176 def extloadi64i32 : PatFrag<(ops node:$ptr), (i64 (unindexedload node:$ptr)), [{
1177 LoadSDNode *LD = cast<LoadSDNode>(N);
1178 ISD::LoadExtType ExtType = LD->getExtensionType();
1179 if (ExtType != ISD::EXTLOAD)
1181 if (LD->getMemoryVT() == MVT::i32)
1184 return LD->getAlignment() >= 4 && LD->isSimple();
1188 // An 'and' node with a single use.
1189 def and_su : PatFrag<(ops node:$lhs, node:$rhs), (and node:$lhs, node:$rhs), [{
1190 return N->hasOneUse();
1192 // An 'srl' node with a single use.
1193 def srl_su : PatFrag<(ops node:$lhs, node:$rhs), (srl node:$lhs, node:$rhs), [{
1194 return N->hasOneUse();
1196 // An 'trunc' node with a single use.
1197 def trunc_su : PatFrag<(ops node:$src), (trunc node:$src), [{
1198 return N->hasOneUse();
1201 //===----------------------------------------------------------------------===//
1202 // Instruction list.
1206 let hasSideEffects = 0, SchedRW = [WriteNop] in {
1207 def NOOP : I<0x90, RawFrm, (outs), (ins), "nop", []>;
1208 def NOOPW : I<0x1f, MRMXm, (outs), (ins i16mem:$zero),
1209 "nop{w}\t$zero", []>, TB, OpSize16, NotMemoryFoldable;
1210 def NOOPL : I<0x1f, MRMXm, (outs), (ins i32mem:$zero),
1211 "nop{l}\t$zero", []>, TB, OpSize32, NotMemoryFoldable;
1212 def NOOPQ : RI<0x1f, MRMXm, (outs), (ins i64mem:$zero),
1213 "nop{q}\t$zero", []>, TB, NotMemoryFoldable,
1214 Requires<[In64BitMode]>;
1215 // Also allow register so we can assemble/disassemble
1216 def NOOPWr : I<0x1f, MRMXr, (outs), (ins GR16:$zero),
1217 "nop{w}\t$zero", []>, TB, OpSize16, NotMemoryFoldable;
1218 def NOOPLr : I<0x1f, MRMXr, (outs), (ins GR32:$zero),
1219 "nop{l}\t$zero", []>, TB, OpSize32, NotMemoryFoldable;
1220 def NOOPQr : RI<0x1f, MRMXr, (outs), (ins GR64:$zero),
1221 "nop{q}\t$zero", []>, TB, NotMemoryFoldable,
1222 Requires<[In64BitMode]>;
1226 // Constructing a stack frame.
1227 def ENTER : Ii16<0xC8, RawFrmImm8, (outs), (ins i16imm:$len, i8imm:$lvl),
1228 "enter\t$len, $lvl", []>, Sched<[WriteMicrocoded]>;
1230 let SchedRW = [WriteALU] in {
1231 let Defs = [EBP, ESP], Uses = [EBP, ESP], mayLoad = 1, hasSideEffects=0 in
1232 def LEAVE : I<0xC9, RawFrm, (outs), (ins), "leave", []>,
1233 Requires<[Not64BitMode]>;
1235 let Defs = [RBP,RSP], Uses = [RBP,RSP], mayLoad = 1, hasSideEffects = 0 in
1236 def LEAVE64 : I<0xC9, RawFrm, (outs), (ins), "leave", []>,
1237 Requires<[In64BitMode]>;
1240 //===----------------------------------------------------------------------===//
1241 // Miscellaneous Instructions.
1244 let isBarrier = 1, hasSideEffects = 1, usesCustomInserter = 1,
1245 SchedRW = [WriteSystem] in
1246 def Int_eh_sjlj_setup_dispatch
1247 : PseudoI<(outs), (ins), [(X86eh_sjlj_setup_dispatch)]>;
1249 let Defs = [ESP], Uses = [ESP], hasSideEffects=0 in {
1250 let mayLoad = 1, SchedRW = [WriteLoad] in {
1251 def POP16r : I<0x58, AddRegFrm, (outs GR16:$reg), (ins), "pop{w}\t$reg", []>,
1253 def POP32r : I<0x58, AddRegFrm, (outs GR32:$reg), (ins), "pop{l}\t$reg", []>,
1254 OpSize32, Requires<[Not64BitMode]>;
1255 // Long form for the disassembler.
1256 let isCodeGenOnly = 1, ForceDisassemble = 1 in {
1257 def POP16rmr: I<0x8F, MRM0r, (outs GR16:$reg), (ins), "pop{w}\t$reg", []>,
1258 OpSize16, NotMemoryFoldable;
1259 def POP32rmr: I<0x8F, MRM0r, (outs GR32:$reg), (ins), "pop{l}\t$reg", []>,
1260 OpSize32, Requires<[Not64BitMode]>, NotMemoryFoldable;
1261 } // isCodeGenOnly = 1, ForceDisassemble = 1
1262 } // mayLoad, SchedRW
1263 let mayStore = 1, mayLoad = 1, SchedRW = [WriteCopy] in {
1264 def POP16rmm: I<0x8F, MRM0m, (outs), (ins i16mem:$dst), "pop{w}\t$dst", []>,
1266 def POP32rmm: I<0x8F, MRM0m, (outs), (ins i32mem:$dst), "pop{l}\t$dst", []>,
1267 OpSize32, Requires<[Not64BitMode]>;
1268 } // mayStore, mayLoad, SchedRW
1270 let mayStore = 1, SchedRW = [WriteStore] in {
1271 def PUSH16r : I<0x50, AddRegFrm, (outs), (ins GR16:$reg), "push{w}\t$reg",[]>,
1273 def PUSH32r : I<0x50, AddRegFrm, (outs), (ins GR32:$reg), "push{l}\t$reg",[]>,
1274 OpSize32, Requires<[Not64BitMode]>;
1275 // Long form for the disassembler.
1276 let isCodeGenOnly = 1, ForceDisassemble = 1 in {
1277 def PUSH16rmr: I<0xFF, MRM6r, (outs), (ins GR16:$reg), "push{w}\t$reg",[]>,
1278 OpSize16, NotMemoryFoldable;
1279 def PUSH32rmr: I<0xFF, MRM6r, (outs), (ins GR32:$reg), "push{l}\t$reg",[]>,
1280 OpSize32, Requires<[Not64BitMode]>, NotMemoryFoldable;
1281 } // isCodeGenOnly = 1, ForceDisassemble = 1
1283 def PUSH16i8 : Ii8<0x6a, RawFrm, (outs), (ins i16i8imm:$imm),
1284 "push{w}\t$imm", []>, OpSize16;
1285 def PUSHi16 : Ii16<0x68, RawFrm, (outs), (ins i16imm:$imm),
1286 "push{w}\t$imm", []>, OpSize16;
1288 def PUSH32i8 : Ii8<0x6a, RawFrm, (outs), (ins i32i8imm:$imm),
1289 "push{l}\t$imm", []>, OpSize32,
1290 Requires<[Not64BitMode]>;
1291 def PUSHi32 : Ii32<0x68, RawFrm, (outs), (ins i32imm:$imm),
1292 "push{l}\t$imm", []>, OpSize32,
1293 Requires<[Not64BitMode]>;
1294 } // mayStore, SchedRW
1296 let mayLoad = 1, mayStore = 1, SchedRW = [WriteCopy] in {
1297 def PUSH16rmm: I<0xFF, MRM6m, (outs), (ins i16mem:$src), "push{w}\t$src", []>,
1299 def PUSH32rmm: I<0xFF, MRM6m, (outs), (ins i32mem:$src), "push{l}\t$src", []>,
1300 OpSize32, Requires<[Not64BitMode]>;
1301 } // mayLoad, mayStore, SchedRW
1305 let mayLoad = 1, mayStore = 1, usesCustomInserter = 1,
1306 SchedRW = [WriteRMW], Defs = [ESP] in {
1308 def RDFLAGS32 : PseudoI<(outs GR32:$dst), (ins),
1309 [(set GR32:$dst, (int_x86_flags_read_u32))]>,
1310 Requires<[Not64BitMode]>;
1313 def RDFLAGS64 : PseudoI<(outs GR64:$dst), (ins),
1314 [(set GR64:$dst, (int_x86_flags_read_u64))]>,
1315 Requires<[In64BitMode]>;
1318 let mayLoad = 1, mayStore = 1, usesCustomInserter = 1,
1319 SchedRW = [WriteRMW] in {
1320 let Defs = [ESP, EFLAGS, DF], Uses = [ESP] in
1321 def WRFLAGS32 : PseudoI<(outs), (ins GR32:$src),
1322 [(int_x86_flags_write_u32 GR32:$src)]>,
1323 Requires<[Not64BitMode]>;
1325 let Defs = [RSP, EFLAGS, DF], Uses = [RSP] in
1326 def WRFLAGS64 : PseudoI<(outs), (ins GR64:$src),
1327 [(int_x86_flags_write_u64 GR64:$src)]>,
1328 Requires<[In64BitMode]>;
1331 let Defs = [ESP, EFLAGS, DF], Uses = [ESP], mayLoad = 1, hasSideEffects=0,
1332 SchedRW = [WriteLoad] in {
1333 def POPF16 : I<0x9D, RawFrm, (outs), (ins), "popf{w}", []>, OpSize16;
1334 def POPF32 : I<0x9D, RawFrm, (outs), (ins), "popf{l|d}", []>, OpSize32,
1335 Requires<[Not64BitMode]>;
1338 let Defs = [ESP], Uses = [ESP, EFLAGS, DF], mayStore = 1, hasSideEffects=0,
1339 SchedRW = [WriteStore] in {
1340 def PUSHF16 : I<0x9C, RawFrm, (outs), (ins), "pushf{w}", []>, OpSize16;
1341 def PUSHF32 : I<0x9C, RawFrm, (outs), (ins), "pushf{l|d}", []>, OpSize32,
1342 Requires<[Not64BitMode]>;
1345 let Defs = [RSP], Uses = [RSP], hasSideEffects=0 in {
1346 let mayLoad = 1, SchedRW = [WriteLoad] in {
1347 def POP64r : I<0x58, AddRegFrm, (outs GR64:$reg), (ins), "pop{q}\t$reg", []>,
1348 OpSize32, Requires<[In64BitMode]>;
1349 // Long form for the disassembler.
1350 let isCodeGenOnly = 1, ForceDisassemble = 1 in {
1351 def POP64rmr: I<0x8F, MRM0r, (outs GR64:$reg), (ins), "pop{q}\t$reg", []>,
1352 OpSize32, Requires<[In64BitMode]>, NotMemoryFoldable;
1353 } // isCodeGenOnly = 1, ForceDisassemble = 1
1354 } // mayLoad, SchedRW
1355 let mayLoad = 1, mayStore = 1, SchedRW = [WriteCopy] in
1356 def POP64rmm: I<0x8F, MRM0m, (outs), (ins i64mem:$dst), "pop{q}\t$dst", []>,
1357 OpSize32, Requires<[In64BitMode]>;
1358 let mayStore = 1, SchedRW = [WriteStore] in {
1359 def PUSH64r : I<0x50, AddRegFrm, (outs), (ins GR64:$reg), "push{q}\t$reg", []>,
1360 OpSize32, Requires<[In64BitMode]>;
1361 // Long form for the disassembler.
1362 let isCodeGenOnly = 1, ForceDisassemble = 1 in {
1363 def PUSH64rmr: I<0xFF, MRM6r, (outs), (ins GR64:$reg), "push{q}\t$reg", []>,
1364 OpSize32, Requires<[In64BitMode]>, NotMemoryFoldable;
1365 } // isCodeGenOnly = 1, ForceDisassemble = 1
1366 } // mayStore, SchedRW
1367 let mayLoad = 1, mayStore = 1, SchedRW = [WriteCopy] in {
1368 def PUSH64rmm: I<0xFF, MRM6m, (outs), (ins i64mem:$src), "push{q}\t$src", []>,
1369 OpSize32, Requires<[In64BitMode]>;
1370 } // mayLoad, mayStore, SchedRW
1373 let Defs = [RSP], Uses = [RSP], hasSideEffects = 0, mayStore = 1,
1374 SchedRW = [WriteStore] in {
1375 def PUSH64i8 : Ii8<0x6a, RawFrm, (outs), (ins i64i8imm:$imm),
1376 "push{q}\t$imm", []>, OpSize32,
1377 Requires<[In64BitMode]>;
1378 def PUSH64i32 : Ii32S<0x68, RawFrm, (outs), (ins i64i32imm:$imm),
1379 "push{q}\t$imm", []>, OpSize32,
1380 Requires<[In64BitMode]>;
1383 let Defs = [RSP, EFLAGS, DF], Uses = [RSP], mayLoad = 1, hasSideEffects=0 in
1384 def POPF64 : I<0x9D, RawFrm, (outs), (ins), "popfq", []>,
1385 OpSize32, Requires<[In64BitMode]>, Sched<[WriteLoad]>;
1386 let Defs = [RSP], Uses = [RSP, EFLAGS, DF], mayStore = 1, hasSideEffects=0 in
1387 def PUSHF64 : I<0x9C, RawFrm, (outs), (ins), "pushfq", []>,
1388 OpSize32, Requires<[In64BitMode]>, Sched<[WriteStore]>;
1390 let Defs = [EDI, ESI, EBP, EBX, EDX, ECX, EAX, ESP], Uses = [ESP],
1391 mayLoad = 1, hasSideEffects = 0, SchedRW = [WriteLoad] in {
1392 def POPA32 : I<0x61, RawFrm, (outs), (ins), "popal", []>,
1393 OpSize32, Requires<[Not64BitMode]>;
1394 def POPA16 : I<0x61, RawFrm, (outs), (ins), "popaw", []>,
1395 OpSize16, Requires<[Not64BitMode]>;
1397 let Defs = [ESP], Uses = [EDI, ESI, EBP, EBX, EDX, ECX, EAX, ESP],
1398 mayStore = 1, hasSideEffects = 0, SchedRW = [WriteStore] in {
1399 def PUSHA32 : I<0x60, RawFrm, (outs), (ins), "pushal", []>,
1400 OpSize32, Requires<[Not64BitMode]>;
1401 def PUSHA16 : I<0x60, RawFrm, (outs), (ins), "pushaw", []>,
1402 OpSize16, Requires<[Not64BitMode]>;
1405 let Constraints = "$src = $dst", SchedRW = [WriteBSWAP32] in {
1406 // This instruction is a consequence of BSWAP32r observing operand size. The
1407 // encoding is valid, but the behavior is undefined.
1408 let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0 in
1409 def BSWAP16r_BAD : I<0xC8, AddRegFrm, (outs GR16:$dst), (ins GR16:$src),
1410 "bswap{w}\t$dst", []>, OpSize16, TB;
1411 // GR32 = bswap GR32
1412 def BSWAP32r : I<0xC8, AddRegFrm, (outs GR32:$dst), (ins GR32:$src),
1414 [(set GR32:$dst, (bswap GR32:$src))]>, OpSize32, TB;
1416 let SchedRW = [WriteBSWAP64] in
1417 def BSWAP64r : RI<0xC8, AddRegFrm, (outs GR64:$dst), (ins GR64:$src),
1419 [(set GR64:$dst, (bswap GR64:$src))]>, TB;
1420 } // Constraints = "$src = $dst", SchedRW
1422 // Bit scan instructions.
1423 let Defs = [EFLAGS] in {
1424 def BSF16rr : I<0xBC, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
1425 "bsf{w}\t{$src, $dst|$dst, $src}",
1426 [(set GR16:$dst, EFLAGS, (X86bsf GR16:$src))]>,
1427 PS, OpSize16, Sched<[WriteBSF]>;
1428 def BSF16rm : I<0xBC, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
1429 "bsf{w}\t{$src, $dst|$dst, $src}",
1430 [(set GR16:$dst, EFLAGS, (X86bsf (loadi16 addr:$src)))]>,
1431 PS, OpSize16, Sched<[WriteBSFLd]>;
1432 def BSF32rr : I<0xBC, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
1433 "bsf{l}\t{$src, $dst|$dst, $src}",
1434 [(set GR32:$dst, EFLAGS, (X86bsf GR32:$src))]>,
1435 PS, OpSize32, Sched<[WriteBSF]>;
1436 def BSF32rm : I<0xBC, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
1437 "bsf{l}\t{$src, $dst|$dst, $src}",
1438 [(set GR32:$dst, EFLAGS, (X86bsf (loadi32 addr:$src)))]>,
1439 PS, OpSize32, Sched<[WriteBSFLd]>;
1440 def BSF64rr : RI<0xBC, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
1441 "bsf{q}\t{$src, $dst|$dst, $src}",
1442 [(set GR64:$dst, EFLAGS, (X86bsf GR64:$src))]>,
1443 PS, Sched<[WriteBSF]>;
1444 def BSF64rm : RI<0xBC, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
1445 "bsf{q}\t{$src, $dst|$dst, $src}",
1446 [(set GR64:$dst, EFLAGS, (X86bsf (loadi64 addr:$src)))]>,
1447 PS, Sched<[WriteBSFLd]>;
1449 def BSR16rr : I<0xBD, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
1450 "bsr{w}\t{$src, $dst|$dst, $src}",
1451 [(set GR16:$dst, EFLAGS, (X86bsr GR16:$src))]>,
1452 PS, OpSize16, Sched<[WriteBSR]>;
1453 def BSR16rm : I<0xBD, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
1454 "bsr{w}\t{$src, $dst|$dst, $src}",
1455 [(set GR16:$dst, EFLAGS, (X86bsr (loadi16 addr:$src)))]>,
1456 PS, OpSize16, Sched<[WriteBSRLd]>;
1457 def BSR32rr : I<0xBD, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
1458 "bsr{l}\t{$src, $dst|$dst, $src}",
1459 [(set GR32:$dst, EFLAGS, (X86bsr GR32:$src))]>,
1460 PS, OpSize32, Sched<[WriteBSR]>;
1461 def BSR32rm : I<0xBD, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
1462 "bsr{l}\t{$src, $dst|$dst, $src}",
1463 [(set GR32:$dst, EFLAGS, (X86bsr (loadi32 addr:$src)))]>,
1464 PS, OpSize32, Sched<[WriteBSRLd]>;
1465 def BSR64rr : RI<0xBD, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
1466 "bsr{q}\t{$src, $dst|$dst, $src}",
1467 [(set GR64:$dst, EFLAGS, (X86bsr GR64:$src))]>,
1468 PS, Sched<[WriteBSR]>;
1469 def BSR64rm : RI<0xBD, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
1470 "bsr{q}\t{$src, $dst|$dst, $src}",
1471 [(set GR64:$dst, EFLAGS, (X86bsr (loadi64 addr:$src)))]>,
1472 PS, Sched<[WriteBSRLd]>;
1473 } // Defs = [EFLAGS]
1475 let SchedRW = [WriteMicrocoded] in {
1476 let Defs = [EDI,ESI], Uses = [EDI,ESI,DF] in {
1477 def MOVSB : I<0xA4, RawFrmDstSrc, (outs), (ins dstidx8:$dst, srcidx8:$src),
1478 "movsb\t{$src, $dst|$dst, $src}", []>;
1479 def MOVSW : I<0xA5, RawFrmDstSrc, (outs), (ins dstidx16:$dst, srcidx16:$src),
1480 "movsw\t{$src, $dst|$dst, $src}", []>, OpSize16;
1481 def MOVSL : I<0xA5, RawFrmDstSrc, (outs), (ins dstidx32:$dst, srcidx32:$src),
1482 "movs{l|d}\t{$src, $dst|$dst, $src}", []>, OpSize32;
1483 def MOVSQ : RI<0xA5, RawFrmDstSrc, (outs), (ins dstidx64:$dst, srcidx64:$src),
1484 "movsq\t{$src, $dst|$dst, $src}", []>,
1485 Requires<[In64BitMode]>;
1488 let Defs = [EDI], Uses = [AL,EDI,DF] in
1489 def STOSB : I<0xAA, RawFrmDst, (outs), (ins dstidx8:$dst),
1490 "stosb\t{%al, $dst|$dst, al}", []>;
1491 let Defs = [EDI], Uses = [AX,EDI,DF] in
1492 def STOSW : I<0xAB, RawFrmDst, (outs), (ins dstidx16:$dst),
1493 "stosw\t{%ax, $dst|$dst, ax}", []>, OpSize16;
1494 let Defs = [EDI], Uses = [EAX,EDI,DF] in
1495 def STOSL : I<0xAB, RawFrmDst, (outs), (ins dstidx32:$dst),
1496 "stos{l|d}\t{%eax, $dst|$dst, eax}", []>, OpSize32;
1497 let Defs = [RDI], Uses = [RAX,RDI,DF] in
1498 def STOSQ : RI<0xAB, RawFrmDst, (outs), (ins dstidx64:$dst),
1499 "stosq\t{%rax, $dst|$dst, rax}", []>,
1500 Requires<[In64BitMode]>;
1502 let Defs = [EDI,EFLAGS], Uses = [AL,EDI,DF] in
1503 def SCASB : I<0xAE, RawFrmDst, (outs), (ins dstidx8:$dst),
1504 "scasb\t{$dst, %al|al, $dst}", []>;
1505 let Defs = [EDI,EFLAGS], Uses = [AX,EDI,DF] in
1506 def SCASW : I<0xAF, RawFrmDst, (outs), (ins dstidx16:$dst),
1507 "scasw\t{$dst, %ax|ax, $dst}", []>, OpSize16;
1508 let Defs = [EDI,EFLAGS], Uses = [EAX,EDI,DF] in
1509 def SCASL : I<0xAF, RawFrmDst, (outs), (ins dstidx32:$dst),
1510 "scas{l|d}\t{$dst, %eax|eax, $dst}", []>, OpSize32;
1511 let Defs = [EDI,EFLAGS], Uses = [RAX,EDI,DF] in
1512 def SCASQ : RI<0xAF, RawFrmDst, (outs), (ins dstidx64:$dst),
1513 "scasq\t{$dst, %rax|rax, $dst}", []>,
1514 Requires<[In64BitMode]>;
1516 let Defs = [EDI,ESI,EFLAGS], Uses = [EDI,ESI,DF] in {
1517 def CMPSB : I<0xA6, RawFrmDstSrc, (outs), (ins dstidx8:$dst, srcidx8:$src),
1518 "cmpsb\t{$dst, $src|$src, $dst}", []>;
1519 def CMPSW : I<0xA7, RawFrmDstSrc, (outs), (ins dstidx16:$dst, srcidx16:$src),
1520 "cmpsw\t{$dst, $src|$src, $dst}", []>, OpSize16;
1521 def CMPSL : I<0xA7, RawFrmDstSrc, (outs), (ins dstidx32:$dst, srcidx32:$src),
1522 "cmps{l|d}\t{$dst, $src|$src, $dst}", []>, OpSize32;
1523 def CMPSQ : RI<0xA7, RawFrmDstSrc, (outs), (ins dstidx64:$dst, srcidx64:$src),
1524 "cmpsq\t{$dst, $src|$src, $dst}", []>,
1525 Requires<[In64BitMode]>;
1529 //===----------------------------------------------------------------------===//
1530 // Move Instructions.
1532 let SchedRW = [WriteMove] in {
1533 let hasSideEffects = 0, isMoveReg = 1 in {
1534 def MOV8rr : I<0x88, MRMDestReg, (outs GR8 :$dst), (ins GR8 :$src),
1535 "mov{b}\t{$src, $dst|$dst, $src}", []>;
1536 def MOV16rr : I<0x89, MRMDestReg, (outs GR16:$dst), (ins GR16:$src),
1537 "mov{w}\t{$src, $dst|$dst, $src}", []>, OpSize16;
1538 def MOV32rr : I<0x89, MRMDestReg, (outs GR32:$dst), (ins GR32:$src),
1539 "mov{l}\t{$src, $dst|$dst, $src}", []>, OpSize32;
1540 def MOV64rr : RI<0x89, MRMDestReg, (outs GR64:$dst), (ins GR64:$src),
1541 "mov{q}\t{$src, $dst|$dst, $src}", []>;
1544 let isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in {
1545 def MOV8ri : Ii8 <0xB0, AddRegFrm, (outs GR8 :$dst), (ins i8imm :$src),
1546 "mov{b}\t{$src, $dst|$dst, $src}",
1547 [(set GR8:$dst, imm:$src)]>;
1548 def MOV16ri : Ii16<0xB8, AddRegFrm, (outs GR16:$dst), (ins i16imm:$src),
1549 "mov{w}\t{$src, $dst|$dst, $src}",
1550 [(set GR16:$dst, imm:$src)]>, OpSize16;
1551 def MOV32ri : Ii32<0xB8, AddRegFrm, (outs GR32:$dst), (ins i32imm:$src),
1552 "mov{l}\t{$src, $dst|$dst, $src}",
1553 [(set GR32:$dst, relocImm:$src)]>, OpSize32;
1554 def MOV64ri32 : RIi32S<0xC7, MRM0r, (outs GR64:$dst), (ins i64i32imm:$src),
1555 "mov{q}\t{$src, $dst|$dst, $src}",
1556 [(set GR64:$dst, i64immSExt32:$src)]>;
1558 let isReMaterializable = 1, isMoveImm = 1 in {
1559 def MOV64ri : RIi64<0xB8, AddRegFrm, (outs GR64:$dst), (ins i64imm:$src),
1560 "movabs{q}\t{$src, $dst|$dst, $src}",
1561 [(set GR64:$dst, relocImm:$src)]>;
1564 // Longer forms that use a ModR/M byte. Needed for disassembler
1565 let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0 in {
1566 def MOV8ri_alt : Ii8 <0xC6, MRM0r, (outs GR8 :$dst), (ins i8imm :$src),
1567 "mov{b}\t{$src, $dst|$dst, $src}", []>,
1568 FoldGenData<"MOV8ri">;
1569 def MOV16ri_alt : Ii16<0xC7, MRM0r, (outs GR16:$dst), (ins i16imm:$src),
1570 "mov{w}\t{$src, $dst|$dst, $src}", []>, OpSize16,
1571 FoldGenData<"MOV16ri">;
1572 def MOV32ri_alt : Ii32<0xC7, MRM0r, (outs GR32:$dst), (ins i32imm:$src),
1573 "mov{l}\t{$src, $dst|$dst, $src}", []>, OpSize32,
1574 FoldGenData<"MOV32ri">;
1578 let SchedRW = [WriteStore] in {
1579 def MOV8mi : Ii8 <0xC6, MRM0m, (outs), (ins i8mem :$dst, i8imm :$src),
1580 "mov{b}\t{$src, $dst|$dst, $src}",
1581 [(store (i8 relocImm8_su:$src), addr:$dst)]>;
1582 def MOV16mi : Ii16<0xC7, MRM0m, (outs), (ins i16mem:$dst, i16imm:$src),
1583 "mov{w}\t{$src, $dst|$dst, $src}",
1584 [(store (i16 relocImm16_su:$src), addr:$dst)]>, OpSize16;
1585 def MOV32mi : Ii32<0xC7, MRM0m, (outs), (ins i32mem:$dst, i32imm:$src),
1586 "mov{l}\t{$src, $dst|$dst, $src}",
1587 [(store (i32 relocImm32_su:$src), addr:$dst)]>, OpSize32;
1588 def MOV64mi32 : RIi32S<0xC7, MRM0m, (outs), (ins i64mem:$dst, i64i32imm:$src),
1589 "mov{q}\t{$src, $dst|$dst, $src}",
1590 [(store i64relocImmSExt32_su:$src, addr:$dst)]>,
1591 Requires<[In64BitMode]>;
1594 let hasSideEffects = 0 in {
1596 /// Memory offset versions of moves. The immediate is an address mode sized
1597 /// offset from the segment base.
1598 let SchedRW = [WriteALU] in {
1599 let mayLoad = 1 in {
1601 def MOV8ao32 : Ii32<0xA0, RawFrmMemOffs, (outs), (ins offset32_8:$src),
1602 "mov{b}\t{$src, %al|al, $src}", []>,
1605 def MOV16ao32 : Ii32<0xA1, RawFrmMemOffs, (outs), (ins offset32_16:$src),
1606 "mov{w}\t{$src, %ax|ax, $src}", []>,
1609 def MOV32ao32 : Ii32<0xA1, RawFrmMemOffs, (outs), (ins offset32_32:$src),
1610 "mov{l}\t{$src, %eax|eax, $src}", []>,
1613 def MOV64ao32 : RIi32<0xA1, RawFrmMemOffs, (outs), (ins offset32_64:$src),
1614 "mov{q}\t{$src, %rax|rax, $src}", []>,
1618 def MOV8ao16 : Ii16<0xA0, RawFrmMemOffs, (outs), (ins offset16_8:$src),
1619 "mov{b}\t{$src, %al|al, $src}", []>, AdSize16;
1621 def MOV16ao16 : Ii16<0xA1, RawFrmMemOffs, (outs), (ins offset16_16:$src),
1622 "mov{w}\t{$src, %ax|ax, $src}", []>,
1625 def MOV32ao16 : Ii16<0xA1, RawFrmMemOffs, (outs), (ins offset16_32:$src),
1626 "mov{l}\t{$src, %eax|eax, $src}", []>,
1629 let mayStore = 1 in {
1631 def MOV8o32a : Ii32<0xA2, RawFrmMemOffs, (outs), (ins offset32_8:$dst),
1632 "mov{b}\t{%al, $dst|$dst, al}", []>, AdSize32;
1634 def MOV16o32a : Ii32<0xA3, RawFrmMemOffs, (outs), (ins offset32_16:$dst),
1635 "mov{w}\t{%ax, $dst|$dst, ax}", []>,
1638 def MOV32o32a : Ii32<0xA3, RawFrmMemOffs, (outs), (ins offset32_32:$dst),
1639 "mov{l}\t{%eax, $dst|$dst, eax}", []>,
1642 def MOV64o32a : RIi32<0xA3, RawFrmMemOffs, (outs), (ins offset32_64:$dst),
1643 "mov{q}\t{%rax, $dst|$dst, rax}", []>,
1647 def MOV8o16a : Ii16<0xA2, RawFrmMemOffs, (outs), (ins offset16_8:$dst),
1648 "mov{b}\t{%al, $dst|$dst, al}", []>, AdSize16;
1650 def MOV16o16a : Ii16<0xA3, RawFrmMemOffs, (outs), (ins offset16_16:$dst),
1651 "mov{w}\t{%ax, $dst|$dst, ax}", []>,
1654 def MOV32o16a : Ii16<0xA3, RawFrmMemOffs, (outs), (ins offset16_32:$dst),
1655 "mov{l}\t{%eax, $dst|$dst, eax}", []>,
1659 // These forms all have full 64-bit absolute addresses in their instructions
1660 // and use the movabs mnemonic to indicate this specific form.
1661 let mayLoad = 1 in {
1663 def MOV8ao64 : Ii64<0xA0, RawFrmMemOffs, (outs), (ins offset64_8:$src),
1664 "movabs{b}\t{$src, %al|al, $src}", []>,
1667 def MOV16ao64 : Ii64<0xA1, RawFrmMemOffs, (outs), (ins offset64_16:$src),
1668 "movabs{w}\t{$src, %ax|ax, $src}", []>,
1671 def MOV32ao64 : Ii64<0xA1, RawFrmMemOffs, (outs), (ins offset64_32:$src),
1672 "movabs{l}\t{$src, %eax|eax, $src}", []>,
1675 def MOV64ao64 : RIi64<0xA1, RawFrmMemOffs, (outs), (ins offset64_64:$src),
1676 "movabs{q}\t{$src, %rax|rax, $src}", []>,
1680 let mayStore = 1 in {
1682 def MOV8o64a : Ii64<0xA2, RawFrmMemOffs, (outs), (ins offset64_8:$dst),
1683 "movabs{b}\t{%al, $dst|$dst, al}", []>,
1686 def MOV16o64a : Ii64<0xA3, RawFrmMemOffs, (outs), (ins offset64_16:$dst),
1687 "movabs{w}\t{%ax, $dst|$dst, ax}", []>,
1690 def MOV32o64a : Ii64<0xA3, RawFrmMemOffs, (outs), (ins offset64_32:$dst),
1691 "movabs{l}\t{%eax, $dst|$dst, eax}", []>,
1694 def MOV64o64a : RIi64<0xA3, RawFrmMemOffs, (outs), (ins offset64_64:$dst),
1695 "movabs{q}\t{%rax, $dst|$dst, rax}", []>,
1699 } // hasSideEffects = 0
1701 let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0,
1702 SchedRW = [WriteMove], isMoveReg = 1 in {
1703 def MOV8rr_REV : I<0x8A, MRMSrcReg, (outs GR8:$dst), (ins GR8:$src),
1704 "mov{b}\t{$src, $dst|$dst, $src}", []>,
1705 FoldGenData<"MOV8rr">;
1706 def MOV16rr_REV : I<0x8B, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
1707 "mov{w}\t{$src, $dst|$dst, $src}", []>, OpSize16,
1708 FoldGenData<"MOV16rr">;
1709 def MOV32rr_REV : I<0x8B, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
1710 "mov{l}\t{$src, $dst|$dst, $src}", []>, OpSize32,
1711 FoldGenData<"MOV32rr">;
1712 def MOV64rr_REV : RI<0x8B, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
1713 "mov{q}\t{$src, $dst|$dst, $src}", []>,
1714 FoldGenData<"MOV64rr">;
1717 // Reversed version with ".s" suffix for GAS compatibility.
1718 def : InstAlias<"mov{b}.s\t{$src, $dst|$dst, $src}",
1719 (MOV8rr_REV GR8:$dst, GR8:$src), 0>;
1720 def : InstAlias<"mov{w}.s\t{$src, $dst|$dst, $src}",
1721 (MOV16rr_REV GR16:$dst, GR16:$src), 0>;
1722 def : InstAlias<"mov{l}.s\t{$src, $dst|$dst, $src}",
1723 (MOV32rr_REV GR32:$dst, GR32:$src), 0>;
1724 def : InstAlias<"mov{q}.s\t{$src, $dst|$dst, $src}",
1725 (MOV64rr_REV GR64:$dst, GR64:$src), 0>;
1726 def : InstAlias<"mov.s\t{$src, $dst|$dst, $src}",
1727 (MOV8rr_REV GR8:$dst, GR8:$src), 0, "att">;
1728 def : InstAlias<"mov.s\t{$src, $dst|$dst, $src}",
1729 (MOV16rr_REV GR16:$dst, GR16:$src), 0, "att">;
1730 def : InstAlias<"mov.s\t{$src, $dst|$dst, $src}",
1731 (MOV32rr_REV GR32:$dst, GR32:$src), 0, "att">;
1732 def : InstAlias<"mov.s\t{$src, $dst|$dst, $src}",
1733 (MOV64rr_REV GR64:$dst, GR64:$src), 0, "att">;
1735 let canFoldAsLoad = 1, isReMaterializable = 1, SchedRW = [WriteLoad] in {
1736 def MOV8rm : I<0x8A, MRMSrcMem, (outs GR8 :$dst), (ins i8mem :$src),
1737 "mov{b}\t{$src, $dst|$dst, $src}",
1738 [(set GR8:$dst, (loadi8 addr:$src))]>;
1739 def MOV16rm : I<0x8B, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
1740 "mov{w}\t{$src, $dst|$dst, $src}",
1741 [(set GR16:$dst, (loadi16 addr:$src))]>, OpSize16;
1742 def MOV32rm : I<0x8B, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
1743 "mov{l}\t{$src, $dst|$dst, $src}",
1744 [(set GR32:$dst, (loadi32 addr:$src))]>, OpSize32;
1745 def MOV64rm : RI<0x8B, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
1746 "mov{q}\t{$src, $dst|$dst, $src}",
1747 [(set GR64:$dst, (load addr:$src))]>;
1750 let SchedRW = [WriteStore] in {
1751 def MOV8mr : I<0x88, MRMDestMem, (outs), (ins i8mem :$dst, GR8 :$src),
1752 "mov{b}\t{$src, $dst|$dst, $src}",
1753 [(store GR8:$src, addr:$dst)]>;
1754 def MOV16mr : I<0x89, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src),
1755 "mov{w}\t{$src, $dst|$dst, $src}",
1756 [(store GR16:$src, addr:$dst)]>, OpSize16;
1757 def MOV32mr : I<0x89, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
1758 "mov{l}\t{$src, $dst|$dst, $src}",
1759 [(store GR32:$src, addr:$dst)]>, OpSize32;
1760 def MOV64mr : RI<0x89, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
1761 "mov{q}\t{$src, $dst|$dst, $src}",
1762 [(store GR64:$src, addr:$dst)]>;
1765 // Versions of MOV8rr, MOV8mr, and MOV8rm that use i8mem_NOREX and GR8_NOREX so
1766 // that they can be used for copying and storing h registers, which can't be
1767 // encoded when a REX prefix is present.
1768 let isCodeGenOnly = 1 in {
1769 let hasSideEffects = 0, isMoveReg = 1 in
1770 def MOV8rr_NOREX : I<0x88, MRMDestReg,
1771 (outs GR8_NOREX:$dst), (ins GR8_NOREX:$src),
1772 "mov{b}\t{$src, $dst|$dst, $src}", []>,
1774 let mayStore = 1, hasSideEffects = 0 in
1775 def MOV8mr_NOREX : I<0x88, MRMDestMem,
1776 (outs), (ins i8mem_NOREX:$dst, GR8_NOREX:$src),
1777 "mov{b}\t{$src, $dst|$dst, $src}", []>,
1778 Sched<[WriteStore]>;
1779 let mayLoad = 1, hasSideEffects = 0,
1780 canFoldAsLoad = 1, isReMaterializable = 1 in
1781 def MOV8rm_NOREX : I<0x8A, MRMSrcMem,
1782 (outs GR8_NOREX:$dst), (ins i8mem_NOREX:$src),
1783 "mov{b}\t{$src, $dst|$dst, $src}", []>,
1788 // Condition code ops, incl. set if equal/not equal/...
1789 let SchedRW = [WriteLAHFSAHF] in {
1790 let Defs = [EFLAGS], Uses = [AH] in
1791 def SAHF : I<0x9E, RawFrm, (outs), (ins), "sahf",
1792 [(set EFLAGS, (X86sahf AH))]>,
1793 Requires<[HasLAHFSAHF]>;
1794 let Defs = [AH], Uses = [EFLAGS], hasSideEffects = 0 in
1795 def LAHF : I<0x9F, RawFrm, (outs), (ins), "lahf", []>, // AH = flags
1796 Requires<[HasLAHFSAHF]>;
1799 //===----------------------------------------------------------------------===//
1800 // Bit tests instructions: BT, BTS, BTR, BTC.
1802 let Defs = [EFLAGS] in {
1803 let SchedRW = [WriteBitTest] in {
1804 def BT16rr : I<0xA3, MRMDestReg, (outs), (ins GR16:$src1, GR16:$src2),
1805 "bt{w}\t{$src2, $src1|$src1, $src2}",
1806 [(set EFLAGS, (X86bt GR16:$src1, GR16:$src2))]>,
1807 OpSize16, TB, NotMemoryFoldable;
1808 def BT32rr : I<0xA3, MRMDestReg, (outs), (ins GR32:$src1, GR32:$src2),
1809 "bt{l}\t{$src2, $src1|$src1, $src2}",
1810 [(set EFLAGS, (X86bt GR32:$src1, GR32:$src2))]>,
1811 OpSize32, TB, NotMemoryFoldable;
1812 def BT64rr : RI<0xA3, MRMDestReg, (outs), (ins GR64:$src1, GR64:$src2),
1813 "bt{q}\t{$src2, $src1|$src1, $src2}",
1814 [(set EFLAGS, (X86bt GR64:$src1, GR64:$src2))]>, TB,
1818 // Unlike with the register+register form, the memory+register form of the
1819 // bt instruction does not ignore the high bits of the index. From ISel's
1820 // perspective, this is pretty bizarre. Make these instructions disassembly
1821 // only for now. These instructions are also slow on modern CPUs so that's
1822 // another reason to avoid generating them.
1824 let mayLoad = 1, hasSideEffects = 0, SchedRW = [WriteBitTestRegLd] in {
1825 def BT16mr : I<0xA3, MRMDestMem, (outs), (ins i16mem:$src1, GR16:$src2),
1826 "bt{w}\t{$src2, $src1|$src1, $src2}",
1827 []>, OpSize16, TB, NotMemoryFoldable;
1828 def BT32mr : I<0xA3, MRMDestMem, (outs), (ins i32mem:$src1, GR32:$src2),
1829 "bt{l}\t{$src2, $src1|$src1, $src2}",
1830 []>, OpSize32, TB, NotMemoryFoldable;
1831 def BT64mr : RI<0xA3, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2),
1832 "bt{q}\t{$src2, $src1|$src1, $src2}",
1833 []>, TB, NotMemoryFoldable;
1836 let SchedRW = [WriteBitTest] in {
1837 def BT16ri8 : Ii8<0xBA, MRM4r, (outs), (ins GR16:$src1, i16u8imm:$src2),
1838 "bt{w}\t{$src2, $src1|$src1, $src2}",
1839 [(set EFLAGS, (X86bt GR16:$src1, imm:$src2))]>,
1841 def BT32ri8 : Ii8<0xBA, MRM4r, (outs), (ins GR32:$src1, i32u8imm:$src2),
1842 "bt{l}\t{$src2, $src1|$src1, $src2}",
1843 [(set EFLAGS, (X86bt GR32:$src1, imm:$src2))]>,
1845 def BT64ri8 : RIi8<0xBA, MRM4r, (outs), (ins GR64:$src1, i64u8imm:$src2),
1846 "bt{q}\t{$src2, $src1|$src1, $src2}",
1847 [(set EFLAGS, (X86bt GR64:$src1, imm:$src2))]>, TB;
1850 // Note that these instructions aren't slow because that only applies when the
1851 // other operand is in a register. When it's an immediate, bt is still fast.
1852 let SchedRW = [WriteBitTestImmLd] in {
1853 def BT16mi8 : Ii8<0xBA, MRM4m, (outs), (ins i16mem:$src1, i16u8imm:$src2),
1854 "bt{w}\t{$src2, $src1|$src1, $src2}",
1855 [(set EFLAGS, (X86bt (loadi16 addr:$src1),
1858 def BT32mi8 : Ii8<0xBA, MRM4m, (outs), (ins i32mem:$src1, i32u8imm:$src2),
1859 "bt{l}\t{$src2, $src1|$src1, $src2}",
1860 [(set EFLAGS, (X86bt (loadi32 addr:$src1),
1863 def BT64mi8 : RIi8<0xBA, MRM4m, (outs), (ins i64mem:$src1, i64u8imm:$src2),
1864 "bt{q}\t{$src2, $src1|$src1, $src2}",
1865 [(set EFLAGS, (X86bt (loadi64 addr:$src1),
1867 Requires<[In64BitMode]>;
1870 let hasSideEffects = 0 in {
1871 let SchedRW = [WriteBitTestSet], Constraints = "$src1 = $dst" in {
1872 def BTC16rr : I<0xBB, MRMDestReg, (outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
1873 "btc{w}\t{$src2, $src1|$src1, $src2}", []>,
1874 OpSize16, TB, NotMemoryFoldable;
1875 def BTC32rr : I<0xBB, MRMDestReg, (outs GR32:$dst), (ins GR32:$src1, GR32:$src2),
1876 "btc{l}\t{$src2, $src1|$src1, $src2}", []>,
1877 OpSize32, TB, NotMemoryFoldable;
1878 def BTC64rr : RI<0xBB, MRMDestReg, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
1879 "btc{q}\t{$src2, $src1|$src1, $src2}", []>, TB,
1883 let mayLoad = 1, mayStore = 1, SchedRW = [WriteBitTestSetRegRMW] in {
1884 def BTC16mr : I<0xBB, MRMDestMem, (outs), (ins i16mem:$src1, GR16:$src2),
1885 "btc{w}\t{$src2, $src1|$src1, $src2}", []>,
1886 OpSize16, TB, NotMemoryFoldable;
1887 def BTC32mr : I<0xBB, MRMDestMem, (outs), (ins i32mem:$src1, GR32:$src2),
1888 "btc{l}\t{$src2, $src1|$src1, $src2}", []>,
1889 OpSize32, TB, NotMemoryFoldable;
1890 def BTC64mr : RI<0xBB, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2),
1891 "btc{q}\t{$src2, $src1|$src1, $src2}", []>, TB,
1895 let SchedRW = [WriteBitTestSet], Constraints = "$src1 = $dst" in {
1896 def BTC16ri8 : Ii8<0xBA, MRM7r, (outs GR16:$dst), (ins GR16:$src1, i16u8imm:$src2),
1897 "btc{w}\t{$src2, $src1|$src1, $src2}", []>, OpSize16, TB;
1898 def BTC32ri8 : Ii8<0xBA, MRM7r, (outs GR32:$dst), (ins GR32:$src1, i32u8imm:$src2),
1899 "btc{l}\t{$src2, $src1|$src1, $src2}", []>, OpSize32, TB;
1900 def BTC64ri8 : RIi8<0xBA, MRM7r, (outs GR64:$dst), (ins GR64:$src1, i64u8imm:$src2),
1901 "btc{q}\t{$src2, $src1|$src1, $src2}", []>, TB;
1904 let mayLoad = 1, mayStore = 1, SchedRW = [WriteBitTestSetImmRMW] in {
1905 def BTC16mi8 : Ii8<0xBA, MRM7m, (outs), (ins i16mem:$src1, i16u8imm:$src2),
1906 "btc{w}\t{$src2, $src1|$src1, $src2}", []>, OpSize16, TB;
1907 def BTC32mi8 : Ii8<0xBA, MRM7m, (outs), (ins i32mem:$src1, i32u8imm:$src2),
1908 "btc{l}\t{$src2, $src1|$src1, $src2}", []>, OpSize32, TB;
1909 def BTC64mi8 : RIi8<0xBA, MRM7m, (outs), (ins i64mem:$src1, i64u8imm:$src2),
1910 "btc{q}\t{$src2, $src1|$src1, $src2}", []>, TB,
1911 Requires<[In64BitMode]>;
1914 let SchedRW = [WriteBitTestSet], Constraints = "$src1 = $dst" in {
1915 def BTR16rr : I<0xB3, MRMDestReg, (outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
1916 "btr{w}\t{$src2, $src1|$src1, $src2}", []>,
1917 OpSize16, TB, NotMemoryFoldable;
1918 def BTR32rr : I<0xB3, MRMDestReg, (outs GR32:$dst), (ins GR32:$src1, GR32:$src2),
1919 "btr{l}\t{$src2, $src1|$src1, $src2}", []>,
1920 OpSize32, TB, NotMemoryFoldable;
1921 def BTR64rr : RI<0xB3, MRMDestReg, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
1922 "btr{q}\t{$src2, $src1|$src1, $src2}", []>, TB,
1926 let mayLoad = 1, mayStore = 1, SchedRW = [WriteBitTestSetRegRMW] in {
1927 def BTR16mr : I<0xB3, MRMDestMem, (outs), (ins i16mem:$src1, GR16:$src2),
1928 "btr{w}\t{$src2, $src1|$src1, $src2}", []>,
1929 OpSize16, TB, NotMemoryFoldable;
1930 def BTR32mr : I<0xB3, MRMDestMem, (outs), (ins i32mem:$src1, GR32:$src2),
1931 "btr{l}\t{$src2, $src1|$src1, $src2}", []>,
1932 OpSize32, TB, NotMemoryFoldable;
1933 def BTR64mr : RI<0xB3, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2),
1934 "btr{q}\t{$src2, $src1|$src1, $src2}", []>, TB,
1938 let SchedRW = [WriteBitTestSet], Constraints = "$src1 = $dst" in {
1939 def BTR16ri8 : Ii8<0xBA, MRM6r, (outs GR16:$dst), (ins GR16:$src1, i16u8imm:$src2),
1940 "btr{w}\t{$src2, $src1|$src1, $src2}", []>,
1942 def BTR32ri8 : Ii8<0xBA, MRM6r, (outs GR32:$dst), (ins GR32:$src1, i32u8imm:$src2),
1943 "btr{l}\t{$src2, $src1|$src1, $src2}", []>,
1945 def BTR64ri8 : RIi8<0xBA, MRM6r, (outs GR64:$dst), (ins GR64:$src1, i64u8imm:$src2),
1946 "btr{q}\t{$src2, $src1|$src1, $src2}", []>, TB;
1949 let mayLoad = 1, mayStore = 1, SchedRW = [WriteBitTestSetImmRMW] in {
1950 def BTR16mi8 : Ii8<0xBA, MRM6m, (outs), (ins i16mem:$src1, i16u8imm:$src2),
1951 "btr{w}\t{$src2, $src1|$src1, $src2}", []>,
1953 def BTR32mi8 : Ii8<0xBA, MRM6m, (outs), (ins i32mem:$src1, i32u8imm:$src2),
1954 "btr{l}\t{$src2, $src1|$src1, $src2}", []>,
1956 def BTR64mi8 : RIi8<0xBA, MRM6m, (outs), (ins i64mem:$src1, i64u8imm:$src2),
1957 "btr{q}\t{$src2, $src1|$src1, $src2}", []>, TB,
1958 Requires<[In64BitMode]>;
1961 let SchedRW = [WriteBitTestSet], Constraints = "$src1 = $dst" in {
1962 def BTS16rr : I<0xAB, MRMDestReg, (outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
1963 "bts{w}\t{$src2, $src1|$src1, $src2}", []>,
1964 OpSize16, TB, NotMemoryFoldable;
1965 def BTS32rr : I<0xAB, MRMDestReg, (outs GR32:$dst), (ins GR32:$src1, GR32:$src2),
1966 "bts{l}\t{$src2, $src1|$src1, $src2}", []>,
1967 OpSize32, TB, NotMemoryFoldable;
1968 def BTS64rr : RI<0xAB, MRMDestReg, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
1969 "bts{q}\t{$src2, $src1|$src1, $src2}", []>, TB,
1973 let mayLoad = 1, mayStore = 1, SchedRW = [WriteBitTestSetRegRMW] in {
1974 def BTS16mr : I<0xAB, MRMDestMem, (outs), (ins i16mem:$src1, GR16:$src2),
1975 "bts{w}\t{$src2, $src1|$src1, $src2}", []>,
1976 OpSize16, TB, NotMemoryFoldable;
1977 def BTS32mr : I<0xAB, MRMDestMem, (outs), (ins i32mem:$src1, GR32:$src2),
1978 "bts{l}\t{$src2, $src1|$src1, $src2}", []>,
1979 OpSize32, TB, NotMemoryFoldable;
1980 def BTS64mr : RI<0xAB, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2),
1981 "bts{q}\t{$src2, $src1|$src1, $src2}", []>, TB,
1985 let SchedRW = [WriteBitTestSet], Constraints = "$src1 = $dst" in {
1986 def BTS16ri8 : Ii8<0xBA, MRM5r, (outs GR16:$dst), (ins GR16:$src1, i16u8imm:$src2),
1987 "bts{w}\t{$src2, $src1|$src1, $src2}", []>, OpSize16, TB;
1988 def BTS32ri8 : Ii8<0xBA, MRM5r, (outs GR32:$dst), (ins GR32:$src1, i32u8imm:$src2),
1989 "bts{l}\t{$src2, $src1|$src1, $src2}", []>, OpSize32, TB;
1990 def BTS64ri8 : RIi8<0xBA, MRM5r, (outs GR64:$dst), (ins GR64:$src1, i64u8imm:$src2),
1991 "bts{q}\t{$src2, $src1|$src1, $src2}", []>, TB;
1994 let mayLoad = 1, mayStore = 1, SchedRW = [WriteBitTestSetImmRMW] in {
1995 def BTS16mi8 : Ii8<0xBA, MRM5m, (outs), (ins i16mem:$src1, i16u8imm:$src2),
1996 "bts{w}\t{$src2, $src1|$src1, $src2}", []>, OpSize16, TB;
1997 def BTS32mi8 : Ii8<0xBA, MRM5m, (outs), (ins i32mem:$src1, i32u8imm:$src2),
1998 "bts{l}\t{$src2, $src1|$src1, $src2}", []>, OpSize32, TB;
1999 def BTS64mi8 : RIi8<0xBA, MRM5m, (outs), (ins i64mem:$src1, i64u8imm:$src2),
2000 "bts{q}\t{$src2, $src1|$src1, $src2}", []>, TB,
2001 Requires<[In64BitMode]>;
2003 } // hasSideEffects = 0
2004 } // Defs = [EFLAGS]
2007 //===----------------------------------------------------------------------===//
2011 // Atomic swap. These are just normal xchg instructions. But since a memory
2012 // operand is referenced, the atomicity is ensured.
2013 multiclass ATOMIC_SWAP<bits<8> opc8, bits<8> opc, string mnemonic, string frag> {
2014 let Constraints = "$val = $dst", SchedRW = [WriteALULd, WriteRMW] in {
2015 def NAME#8rm : I<opc8, MRMSrcMem, (outs GR8:$dst),
2016 (ins GR8:$val, i8mem:$ptr),
2017 !strconcat(mnemonic, "{b}\t{$val, $ptr|$ptr, $val}"),
2020 (!cast<PatFrag>(frag # "_8") addr:$ptr, GR8:$val))]>;
2021 def NAME#16rm : I<opc, MRMSrcMem, (outs GR16:$dst),
2022 (ins GR16:$val, i16mem:$ptr),
2023 !strconcat(mnemonic, "{w}\t{$val, $ptr|$ptr, $val}"),
2026 (!cast<PatFrag>(frag # "_16") addr:$ptr, GR16:$val))]>,
2028 def NAME#32rm : I<opc, MRMSrcMem, (outs GR32:$dst),
2029 (ins GR32:$val, i32mem:$ptr),
2030 !strconcat(mnemonic, "{l}\t{$val, $ptr|$ptr, $val}"),
2033 (!cast<PatFrag>(frag # "_32") addr:$ptr, GR32:$val))]>,
2035 def NAME#64rm : RI<opc, MRMSrcMem, (outs GR64:$dst),
2036 (ins GR64:$val, i64mem:$ptr),
2037 !strconcat(mnemonic, "{q}\t{$val, $ptr|$ptr, $val}"),
2040 (!cast<PatFrag>(frag # "_64") addr:$ptr, GR64:$val))]>;
2044 defm XCHG : ATOMIC_SWAP<0x86, 0x87, "xchg", "atomic_swap">, NotMemoryFoldable;
2046 // Swap between registers.
2047 let SchedRW = [WriteXCHG] in {
2048 let Constraints = "$src1 = $dst1, $src2 = $dst2", hasSideEffects = 0 in {
2049 def XCHG8rr : I<0x86, MRMSrcReg, (outs GR8:$dst1, GR8:$dst2),
2050 (ins GR8:$src1, GR8:$src2),
2051 "xchg{b}\t{$src2, $src1|$src1, $src2}", []>, NotMemoryFoldable;
2052 def XCHG16rr : I<0x87, MRMSrcReg, (outs GR16:$dst1, GR16:$dst2),
2053 (ins GR16:$src1, GR16:$src2),
2054 "xchg{w}\t{$src2, $src1|$src1, $src2}", []>,
2055 OpSize16, NotMemoryFoldable;
2056 def XCHG32rr : I<0x87, MRMSrcReg, (outs GR32:$dst1, GR32:$dst2),
2057 (ins GR32:$src1, GR32:$src2),
2058 "xchg{l}\t{$src2, $src1|$src1, $src2}", []>,
2059 OpSize32, NotMemoryFoldable;
2060 def XCHG64rr : RI<0x87, MRMSrcReg, (outs GR64:$dst1, GR64:$dst2),
2061 (ins GR64:$src1 ,GR64:$src2),
2062 "xchg{q}\t{$src2, $src1|$src1, $src2}", []>, NotMemoryFoldable;
2065 // Swap between EAX and other registers.
2066 let Constraints = "$src = $dst", hasSideEffects = 0 in {
2067 let Uses = [AX], Defs = [AX] in
2068 def XCHG16ar : I<0x90, AddRegFrm, (outs GR16:$dst), (ins GR16:$src),
2069 "xchg{w}\t{$src, %ax|ax, $src}", []>, OpSize16;
2070 let Uses = [EAX], Defs = [EAX] in
2071 def XCHG32ar : I<0x90, AddRegFrm, (outs GR32:$dst), (ins GR32:$src),
2072 "xchg{l}\t{$src, %eax|eax, $src}", []>, OpSize32;
2073 let Uses = [RAX], Defs = [RAX] in
2074 def XCHG64ar : RI<0x90, AddRegFrm, (outs GR64:$dst), (ins GR64:$src),
2075 "xchg{q}\t{$src, %rax|rax, $src}", []>;
2079 let hasSideEffects = 0, Constraints = "$src1 = $dst1, $src2 = $dst2",
2080 Defs = [EFLAGS], SchedRW = [WriteXCHG] in {
2081 def XADD8rr : I<0xC0, MRMDestReg, (outs GR8:$dst1, GR8:$dst2),
2082 (ins GR8:$src1, GR8:$src2),
2083 "xadd{b}\t{$src2, $src1|$src1, $src2}", []>, TB;
2084 def XADD16rr : I<0xC1, MRMDestReg, (outs GR16:$dst1, GR16:$dst2),
2085 (ins GR16:$src1, GR16:$src2),
2086 "xadd{w}\t{$src2, $src1|$src1, $src2}", []>, TB, OpSize16;
2087 def XADD32rr : I<0xC1, MRMDestReg, (outs GR32:$dst1, GR32:$dst2),
2088 (ins GR32:$src1, GR32:$src2),
2089 "xadd{l}\t{$src2, $src1|$src1, $src2}", []>, TB, OpSize32;
2090 def XADD64rr : RI<0xC1, MRMDestReg, (outs GR64:$dst1, GR64:$dst2),
2091 (ins GR64:$src1, GR64:$src2),
2092 "xadd{q}\t{$src2, $src1|$src1, $src2}", []>, TB;
2095 let mayLoad = 1, mayStore = 1, hasSideEffects = 0, Constraints = "$val = $dst",
2096 Defs = [EFLAGS], SchedRW = [WriteALULd, WriteRMW] in {
2097 def XADD8rm : I<0xC0, MRMSrcMem, (outs GR8:$dst),
2098 (ins GR8:$val, i8mem:$ptr),
2099 "xadd{b}\t{$val, $ptr|$ptr, $val}", []>, TB;
2100 def XADD16rm : I<0xC1, MRMSrcMem, (outs GR16:$dst),
2101 (ins GR16:$val, i16mem:$ptr),
2102 "xadd{w}\t{$val, $ptr|$ptr, $val}", []>, TB,
2104 def XADD32rm : I<0xC1, MRMSrcMem, (outs GR32:$dst),
2105 (ins GR32:$val, i32mem:$ptr),
2106 "xadd{l}\t{$val, $ptr|$ptr, $val}", []>, TB,
2108 def XADD64rm : RI<0xC1, MRMSrcMem, (outs GR64:$dst),
2109 (ins GR64:$val, i64mem:$ptr),
2110 "xadd{q}\t{$val, $ptr|$ptr, $val}", []>, TB;
2114 let SchedRW = [WriteCMPXCHG], hasSideEffects = 0 in {
2115 let Defs = [AL, EFLAGS], Uses = [AL] in
2116 def CMPXCHG8rr : I<0xB0, MRMDestReg, (outs GR8:$dst), (ins GR8:$src),
2117 "cmpxchg{b}\t{$src, $dst|$dst, $src}", []>, TB,
2119 let Defs = [AX, EFLAGS], Uses = [AX] in
2120 def CMPXCHG16rr : I<0xB1, MRMDestReg, (outs GR16:$dst), (ins GR16:$src),
2121 "cmpxchg{w}\t{$src, $dst|$dst, $src}", []>, TB, OpSize16,
2123 let Defs = [EAX, EFLAGS], Uses = [EAX] in
2124 def CMPXCHG32rr : I<0xB1, MRMDestReg, (outs GR32:$dst), (ins GR32:$src),
2125 "cmpxchg{l}\t{$src, $dst|$dst, $src}", []>, TB, OpSize32,
2127 let Defs = [RAX, EFLAGS], Uses = [RAX] in
2128 def CMPXCHG64rr : RI<0xB1, MRMDestReg, (outs GR64:$dst), (ins GR64:$src),
2129 "cmpxchg{q}\t{$src, $dst|$dst, $src}", []>, TB,
2131 } // SchedRW, hasSideEffects
2133 let SchedRW = [WriteCMPXCHGRMW], mayLoad = 1, mayStore = 1,
2134 hasSideEffects = 0 in {
2135 let Defs = [AL, EFLAGS], Uses = [AL] in
2136 def CMPXCHG8rm : I<0xB0, MRMDestMem, (outs), (ins i8mem:$dst, GR8:$src),
2137 "cmpxchg{b}\t{$src, $dst|$dst, $src}", []>, TB,
2139 let Defs = [AX, EFLAGS], Uses = [AX] in
2140 def CMPXCHG16rm : I<0xB1, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src),
2141 "cmpxchg{w}\t{$src, $dst|$dst, $src}", []>, TB, OpSize16,
2143 let Defs = [EAX, EFLAGS], Uses = [EAX] in
2144 def CMPXCHG32rm : I<0xB1, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
2145 "cmpxchg{l}\t{$src, $dst|$dst, $src}", []>, TB, OpSize32,
2147 let Defs = [RAX, EFLAGS], Uses = [RAX] in
2148 def CMPXCHG64rm : RI<0xB1, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
2149 "cmpxchg{q}\t{$src, $dst|$dst, $src}", []>, TB,
2152 let Defs = [EAX, EDX, EFLAGS], Uses = [EAX, EBX, ECX, EDX] in
2153 def CMPXCHG8B : I<0xC7, MRM1m, (outs), (ins i64mem:$dst),
2154 "cmpxchg8b\t$dst", []>, TB, Requires<[HasCmpxchg8b]>;
2156 let Defs = [RAX, RDX, EFLAGS], Uses = [RAX, RBX, RCX, RDX] in
2157 // NOTE: In64BitMode check needed for the AssemblerPredicate.
2158 def CMPXCHG16B : RI<0xC7, MRM1m, (outs), (ins i128mem:$dst),
2159 "cmpxchg16b\t$dst", []>,
2160 TB, Requires<[HasCmpxchg16b,In64BitMode]>;
2161 } // SchedRW, mayLoad, mayStore, hasSideEffects
2164 // Lock instruction prefix
2165 let SchedRW = [WriteMicrocoded] in
2166 def LOCK_PREFIX : I<0xF0, RawFrm, (outs), (ins), "lock", []>;
2168 let SchedRW = [WriteNop] in {
2170 // Rex64 instruction prefix
2171 def REX64_PREFIX : I<0x48, RawFrm, (outs), (ins), "rex64", []>,
2172 Requires<[In64BitMode]>;
2174 // Data16 instruction prefix
2175 def DATA16_PREFIX : I<0x66, RawFrm, (outs), (ins), "data16", []>;
2178 // Repeat string operation instruction prefixes
2179 let Defs = [ECX], Uses = [ECX,DF], SchedRW = [WriteMicrocoded] in {
2180 // Repeat (used with INS, OUTS, MOVS, LODS and STOS)
2181 def REP_PREFIX : I<0xF3, RawFrm, (outs), (ins), "rep", []>;
2182 // Repeat while not equal (used with CMPS and SCAS)
2183 def REPNE_PREFIX : I<0xF2, RawFrm, (outs), (ins), "repne", []>;
2186 // String manipulation instructions
2187 let SchedRW = [WriteMicrocoded] in {
2188 let Defs = [AL,ESI], Uses = [ESI,DF] in
2189 def LODSB : I<0xAC, RawFrmSrc, (outs), (ins srcidx8:$src),
2190 "lodsb\t{$src, %al|al, $src}", []>;
2191 let Defs = [AX,ESI], Uses = [ESI,DF] in
2192 def LODSW : I<0xAD, RawFrmSrc, (outs), (ins srcidx16:$src),
2193 "lodsw\t{$src, %ax|ax, $src}", []>, OpSize16;
2194 let Defs = [EAX,ESI], Uses = [ESI,DF] in
2195 def LODSL : I<0xAD, RawFrmSrc, (outs), (ins srcidx32:$src),
2196 "lods{l|d}\t{$src, %eax|eax, $src}", []>, OpSize32;
2197 let Defs = [RAX,ESI], Uses = [ESI,DF] in
2198 def LODSQ : RI<0xAD, RawFrmSrc, (outs), (ins srcidx64:$src),
2199 "lodsq\t{$src, %rax|rax, $src}", []>,
2200 Requires<[In64BitMode]>;
2203 let SchedRW = [WriteSystem] in {
2204 let Defs = [ESI], Uses = [DX,ESI,DF] in {
2205 def OUTSB : I<0x6E, RawFrmSrc, (outs), (ins srcidx8:$src),
2206 "outsb\t{$src, %dx|dx, $src}", []>;
2207 def OUTSW : I<0x6F, RawFrmSrc, (outs), (ins srcidx16:$src),
2208 "outsw\t{$src, %dx|dx, $src}", []>, OpSize16;
2209 def OUTSL : I<0x6F, RawFrmSrc, (outs), (ins srcidx32:$src),
2210 "outs{l|d}\t{$src, %dx|dx, $src}", []>, OpSize32;
2213 let Defs = [EDI], Uses = [DX,EDI,DF] in {
2214 def INSB : I<0x6C, RawFrmDst, (outs), (ins dstidx8:$dst),
2215 "insb\t{%dx, $dst|$dst, dx}", []>;
2216 def INSW : I<0x6D, RawFrmDst, (outs), (ins dstidx16:$dst),
2217 "insw\t{%dx, $dst|$dst, dx}", []>, OpSize16;
2218 def INSL : I<0x6D, RawFrmDst, (outs), (ins dstidx32:$dst),
2219 "ins{l|d}\t{%dx, $dst|$dst, dx}", []>, OpSize32;
2223 // EFLAGS management instructions.
2224 let SchedRW = [WriteALU], Defs = [EFLAGS], Uses = [EFLAGS] in {
2225 def CLC : I<0xF8, RawFrm, (outs), (ins), "clc", []>;
2226 def STC : I<0xF9, RawFrm, (outs), (ins), "stc", []>;
2227 def CMC : I<0xF5, RawFrm, (outs), (ins), "cmc", []>;
2230 // DF management instructions.
2231 let SchedRW = [WriteALU], Defs = [DF] in {
2232 def CLD : I<0xFC, RawFrm, (outs), (ins), "cld", []>;
2233 def STD : I<0xFD, RawFrm, (outs), (ins), "std", []>;
2236 // Table lookup instructions
2237 let Uses = [AL,EBX], Defs = [AL], hasSideEffects = 0, mayLoad = 1 in
2238 def XLAT : I<0xD7, RawFrm, (outs), (ins), "xlatb", []>, Sched<[WriteLoad]>;
2240 let SchedRW = [WriteMicrocoded] in {
2241 // ASCII Adjust After Addition
2242 let Uses = [AL,EFLAGS], Defs = [AX,EFLAGS], hasSideEffects = 0 in
2243 def AAA : I<0x37, RawFrm, (outs), (ins), "aaa", []>,
2244 Requires<[Not64BitMode]>;
2246 // ASCII Adjust AX Before Division
2247 let Uses = [AX], Defs = [AX,EFLAGS], hasSideEffects = 0 in
2248 def AAD8i8 : Ii8<0xD5, RawFrm, (outs), (ins i8imm:$src),
2249 "aad\t$src", []>, Requires<[Not64BitMode]>;
2251 // ASCII Adjust AX After Multiply
2252 let Uses = [AL], Defs = [AX,EFLAGS], hasSideEffects = 0 in
2253 def AAM8i8 : Ii8<0xD4, RawFrm, (outs), (ins i8imm:$src),
2254 "aam\t$src", []>, Requires<[Not64BitMode]>;
2256 // ASCII Adjust AL After Subtraction - sets
2257 let Uses = [AL,EFLAGS], Defs = [AX,EFLAGS], hasSideEffects = 0 in
2258 def AAS : I<0x3F, RawFrm, (outs), (ins), "aas", []>,
2259 Requires<[Not64BitMode]>;
2261 // Decimal Adjust AL after Addition
2262 let Uses = [AL,EFLAGS], Defs = [AL,EFLAGS], hasSideEffects = 0 in
2263 def DAA : I<0x27, RawFrm, (outs), (ins), "daa", []>,
2264 Requires<[Not64BitMode]>;
2266 // Decimal Adjust AL after Subtraction
2267 let Uses = [AL,EFLAGS], Defs = [AL,EFLAGS], hasSideEffects = 0 in
2268 def DAS : I<0x2F, RawFrm, (outs), (ins), "das", []>,
2269 Requires<[Not64BitMode]>;
2272 let SchedRW = [WriteSystem] in {
2273 // Check Array Index Against Bounds
2274 // Note: "bound" does not have reversed operands in at&t syntax.
2275 def BOUNDS16rm : I<0x62, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
2276 "bound\t$dst, $src", []>, OpSize16,
2277 Requires<[Not64BitMode]>;
2278 def BOUNDS32rm : I<0x62, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
2279 "bound\t$dst, $src", []>, OpSize32,
2280 Requires<[Not64BitMode]>;
2282 // Adjust RPL Field of Segment Selector
2283 def ARPL16rr : I<0x63, MRMDestReg, (outs GR16:$dst), (ins GR16:$src),
2284 "arpl\t{$src, $dst|$dst, $src}", []>,
2285 Requires<[Not64BitMode]>, NotMemoryFoldable;
2287 def ARPL16mr : I<0x63, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src),
2288 "arpl\t{$src, $dst|$dst, $src}", []>,
2289 Requires<[Not64BitMode]>, NotMemoryFoldable;
2292 //===----------------------------------------------------------------------===//
2293 // MOVBE Instructions
2295 let Predicates = [HasMOVBE] in {
2296 let SchedRW = [WriteALULd] in {
2297 def MOVBE16rm : I<0xF0, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
2298 "movbe{w}\t{$src, $dst|$dst, $src}",
2299 [(set GR16:$dst, (bswap (loadi16 addr:$src)))]>,
2301 def MOVBE32rm : I<0xF0, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
2302 "movbe{l}\t{$src, $dst|$dst, $src}",
2303 [(set GR32:$dst, (bswap (loadi32 addr:$src)))]>,
2305 def MOVBE64rm : RI<0xF0, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
2306 "movbe{q}\t{$src, $dst|$dst, $src}",
2307 [(set GR64:$dst, (bswap (loadi64 addr:$src)))]>,
2310 let SchedRW = [WriteStore] in {
2311 def MOVBE16mr : I<0xF1, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src),
2312 "movbe{w}\t{$src, $dst|$dst, $src}",
2313 [(store (bswap GR16:$src), addr:$dst)]>,
2315 def MOVBE32mr : I<0xF1, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
2316 "movbe{l}\t{$src, $dst|$dst, $src}",
2317 [(store (bswap GR32:$src), addr:$dst)]>,
2319 def MOVBE64mr : RI<0xF1, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
2320 "movbe{q}\t{$src, $dst|$dst, $src}",
2321 [(store (bswap GR64:$src), addr:$dst)]>,
2326 //===----------------------------------------------------------------------===//
2327 // RDRAND Instruction
2329 let Predicates = [HasRDRAND], Defs = [EFLAGS], SchedRW = [WriteSystem] in {
2330 def RDRAND16r : I<0xC7, MRM6r, (outs GR16:$dst), (ins),
2331 "rdrand{w}\t$dst", [(set GR16:$dst, EFLAGS, (X86rdrand))]>,
2333 def RDRAND32r : I<0xC7, MRM6r, (outs GR32:$dst), (ins),
2334 "rdrand{l}\t$dst", [(set GR32:$dst, EFLAGS, (X86rdrand))]>,
2336 def RDRAND64r : RI<0xC7, MRM6r, (outs GR64:$dst), (ins),
2337 "rdrand{q}\t$dst", [(set GR64:$dst, EFLAGS, (X86rdrand))]>,
2341 //===----------------------------------------------------------------------===//
2342 // RDSEED Instruction
2344 let Predicates = [HasRDSEED], Defs = [EFLAGS], SchedRW = [WriteSystem] in {
2345 def RDSEED16r : I<0xC7, MRM7r, (outs GR16:$dst), (ins), "rdseed{w}\t$dst",
2346 [(set GR16:$dst, EFLAGS, (X86rdseed))]>, OpSize16, PS;
2347 def RDSEED32r : I<0xC7, MRM7r, (outs GR32:$dst), (ins), "rdseed{l}\t$dst",
2348 [(set GR32:$dst, EFLAGS, (X86rdseed))]>, OpSize32, PS;
2349 def RDSEED64r : RI<0xC7, MRM7r, (outs GR64:$dst), (ins), "rdseed{q}\t$dst",
2350 [(set GR64:$dst, EFLAGS, (X86rdseed))]>, PS;
2353 //===----------------------------------------------------------------------===//
2354 // LZCNT Instruction
2356 let Predicates = [HasLZCNT], Defs = [EFLAGS] in {
2357 def LZCNT16rr : I<0xBD, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
2358 "lzcnt{w}\t{$src, $dst|$dst, $src}",
2359 [(set GR16:$dst, (ctlz GR16:$src)), (implicit EFLAGS)]>,
2360 XS, OpSize16, Sched<[WriteLZCNT]>;
2361 def LZCNT16rm : I<0xBD, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
2362 "lzcnt{w}\t{$src, $dst|$dst, $src}",
2363 [(set GR16:$dst, (ctlz (loadi16 addr:$src))),
2364 (implicit EFLAGS)]>, XS, OpSize16, Sched<[WriteLZCNTLd]>;
2366 def LZCNT32rr : I<0xBD, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
2367 "lzcnt{l}\t{$src, $dst|$dst, $src}",
2368 [(set GR32:$dst, (ctlz GR32:$src)), (implicit EFLAGS)]>,
2369 XS, OpSize32, Sched<[WriteLZCNT]>;
2370 def LZCNT32rm : I<0xBD, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
2371 "lzcnt{l}\t{$src, $dst|$dst, $src}",
2372 [(set GR32:$dst, (ctlz (loadi32 addr:$src))),
2373 (implicit EFLAGS)]>, XS, OpSize32, Sched<[WriteLZCNTLd]>;
2375 def LZCNT64rr : RI<0xBD, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
2376 "lzcnt{q}\t{$src, $dst|$dst, $src}",
2377 [(set GR64:$dst, (ctlz GR64:$src)), (implicit EFLAGS)]>,
2378 XS, Sched<[WriteLZCNT]>;
2379 def LZCNT64rm : RI<0xBD, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
2380 "lzcnt{q}\t{$src, $dst|$dst, $src}",
2381 [(set GR64:$dst, (ctlz (loadi64 addr:$src))),
2382 (implicit EFLAGS)]>, XS, Sched<[WriteLZCNTLd]>;
2385 //===----------------------------------------------------------------------===//
2388 let Predicates = [HasBMI], Defs = [EFLAGS] in {
2389 def TZCNT16rr : I<0xBC, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
2390 "tzcnt{w}\t{$src, $dst|$dst, $src}",
2391 [(set GR16:$dst, (cttz GR16:$src)), (implicit EFLAGS)]>,
2392 XS, OpSize16, Sched<[WriteTZCNT]>;
2393 def TZCNT16rm : I<0xBC, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
2394 "tzcnt{w}\t{$src, $dst|$dst, $src}",
2395 [(set GR16:$dst, (cttz (loadi16 addr:$src))),
2396 (implicit EFLAGS)]>, XS, OpSize16, Sched<[WriteTZCNTLd]>;
2398 def TZCNT32rr : I<0xBC, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
2399 "tzcnt{l}\t{$src, $dst|$dst, $src}",
2400 [(set GR32:$dst, (cttz GR32:$src)), (implicit EFLAGS)]>,
2401 XS, OpSize32, Sched<[WriteTZCNT]>;
2402 def TZCNT32rm : I<0xBC, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
2403 "tzcnt{l}\t{$src, $dst|$dst, $src}",
2404 [(set GR32:$dst, (cttz (loadi32 addr:$src))),
2405 (implicit EFLAGS)]>, XS, OpSize32, Sched<[WriteTZCNTLd]>;
2407 def TZCNT64rr : RI<0xBC, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
2408 "tzcnt{q}\t{$src, $dst|$dst, $src}",
2409 [(set GR64:$dst, (cttz GR64:$src)), (implicit EFLAGS)]>,
2410 XS, Sched<[WriteTZCNT]>;
2411 def TZCNT64rm : RI<0xBC, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
2412 "tzcnt{q}\t{$src, $dst|$dst, $src}",
2413 [(set GR64:$dst, (cttz (loadi64 addr:$src))),
2414 (implicit EFLAGS)]>, XS, Sched<[WriteTZCNTLd]>;
2417 multiclass bmi_bls<string mnemonic, Format RegMRM, Format MemMRM,
2418 RegisterClass RC, X86MemOperand x86memop,
2419 X86FoldableSchedWrite sched> {
2420 let hasSideEffects = 0 in {
2421 def rr : I<0xF3, RegMRM, (outs RC:$dst), (ins RC:$src),
2422 !strconcat(mnemonic, "\t{$src, $dst|$dst, $src}"), []>,
2423 T8PS, VEX_4V, Sched<[sched]>;
2425 def rm : I<0xF3, MemMRM, (outs RC:$dst), (ins x86memop:$src),
2426 !strconcat(mnemonic, "\t{$src, $dst|$dst, $src}"), []>,
2427 T8PS, VEX_4V, Sched<[sched.Folded]>;
2431 let Predicates = [HasBMI], Defs = [EFLAGS] in {
2432 defm BLSR32 : bmi_bls<"blsr{l}", MRM1r, MRM1m, GR32, i32mem, WriteBLS>;
2433 defm BLSR64 : bmi_bls<"blsr{q}", MRM1r, MRM1m, GR64, i64mem, WriteBLS>, VEX_W;
2434 defm BLSMSK32 : bmi_bls<"blsmsk{l}", MRM2r, MRM2m, GR32, i32mem, WriteBLS>;
2435 defm BLSMSK64 : bmi_bls<"blsmsk{q}", MRM2r, MRM2m, GR64, i64mem, WriteBLS>, VEX_W;
2436 defm BLSI32 : bmi_bls<"blsi{l}", MRM3r, MRM3m, GR32, i32mem, WriteBLS>;
2437 defm BLSI64 : bmi_bls<"blsi{q}", MRM3r, MRM3m, GR64, i64mem, WriteBLS>, VEX_W;
2440 //===----------------------------------------------------------------------===//
2441 // Pattern fragments to auto generate BMI instructions.
2442 //===----------------------------------------------------------------------===//
2444 def or_flag_nocf : PatFrag<(ops node:$lhs, node:$rhs),
2445 (X86or_flag node:$lhs, node:$rhs), [{
2446 return hasNoCarryFlagUses(SDValue(N, 1));
2449 def xor_flag_nocf : PatFrag<(ops node:$lhs, node:$rhs),
2450 (X86xor_flag node:$lhs, node:$rhs), [{
2451 return hasNoCarryFlagUses(SDValue(N, 1));
2454 def and_flag_nocf : PatFrag<(ops node:$lhs, node:$rhs),
2455 (X86and_flag node:$lhs, node:$rhs), [{
2456 return hasNoCarryFlagUses(SDValue(N, 1));
2459 let Predicates = [HasBMI] in {
2460 // FIXME: patterns for the load versions are not implemented
2461 def : Pat<(and GR32:$src, (add GR32:$src, -1)),
2462 (BLSR32rr GR32:$src)>;
2463 def : Pat<(and GR64:$src, (add GR64:$src, -1)),
2464 (BLSR64rr GR64:$src)>;
2466 def : Pat<(xor GR32:$src, (add GR32:$src, -1)),
2467 (BLSMSK32rr GR32:$src)>;
2468 def : Pat<(xor GR64:$src, (add GR64:$src, -1)),
2469 (BLSMSK64rr GR64:$src)>;
2471 def : Pat<(and GR32:$src, (ineg GR32:$src)),
2472 (BLSI32rr GR32:$src)>;
2473 def : Pat<(and GR64:$src, (ineg GR64:$src)),
2474 (BLSI64rr GR64:$src)>;
2476 // Versions to match flag producing ops.
2477 def : Pat<(and_flag_nocf GR32:$src, (add GR32:$src, -1)),
2478 (BLSR32rr GR32:$src)>;
2479 def : Pat<(and_flag_nocf GR64:$src, (add GR64:$src, -1)),
2480 (BLSR64rr GR64:$src)>;
2482 def : Pat<(xor_flag_nocf GR32:$src, (add GR32:$src, -1)),
2483 (BLSMSK32rr GR32:$src)>;
2484 def : Pat<(xor_flag_nocf GR64:$src, (add GR64:$src, -1)),
2485 (BLSMSK64rr GR64:$src)>;
2487 def : Pat<(and_flag_nocf GR32:$src, (ineg GR32:$src)),
2488 (BLSI32rr GR32:$src)>;
2489 def : Pat<(and_flag_nocf GR64:$src, (ineg GR64:$src)),
2490 (BLSI64rr GR64:$src)>;
2493 multiclass bmi_bextr<bits<8> opc, string mnemonic, RegisterClass RC,
2494 X86MemOperand x86memop, SDNode OpNode,
2495 PatFrag ld_frag, X86FoldableSchedWrite Sched> {
2496 def rr : I<opc, MRMSrcReg4VOp3, (outs RC:$dst), (ins RC:$src1, RC:$src2),
2497 !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2498 [(set RC:$dst, (OpNode RC:$src1, RC:$src2)), (implicit EFLAGS)]>,
2499 T8PS, VEX, Sched<[Sched]>;
2500 def rm : I<opc, MRMSrcMem4VOp3, (outs RC:$dst), (ins x86memop:$src1, RC:$src2),
2501 !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2502 [(set RC:$dst, (OpNode (ld_frag addr:$src1), RC:$src2)),
2503 (implicit EFLAGS)]>, T8PS, VEX,
2504 Sched<[Sched.Folded,
2506 ReadDefault, ReadDefault, ReadDefault, ReadDefault,
2509 Sched.ReadAfterFold]>;
2512 let Predicates = [HasBMI], Defs = [EFLAGS] in {
2513 defm BEXTR32 : bmi_bextr<0xF7, "bextr{l}", GR32, i32mem,
2514 X86bextr, loadi32, WriteBEXTR>;
2515 defm BEXTR64 : bmi_bextr<0xF7, "bextr{q}", GR64, i64mem,
2516 X86bextr, loadi64, WriteBEXTR>, VEX_W;
2519 multiclass bmi_bzhi<bits<8> opc, string mnemonic, RegisterClass RC,
2520 X86MemOperand x86memop, Intrinsic Int,
2521 PatFrag ld_frag, X86FoldableSchedWrite Sched> {
2522 def rr : I<opc, MRMSrcReg4VOp3, (outs RC:$dst), (ins RC:$src1, RC:$src2),
2523 !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2524 [(set RC:$dst, (Int RC:$src1, RC:$src2)), (implicit EFLAGS)]>,
2525 T8PS, VEX, Sched<[Sched]>;
2526 def rm : I<opc, MRMSrcMem4VOp3, (outs RC:$dst), (ins x86memop:$src1, RC:$src2),
2527 !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2528 [(set RC:$dst, (Int (ld_frag addr:$src1), RC:$src2)),
2529 (implicit EFLAGS)]>, T8PS, VEX,
2530 Sched<[Sched.Folded,
2532 ReadDefault, ReadDefault, ReadDefault, ReadDefault,
2535 Sched.ReadAfterFold]>;
2538 let Predicates = [HasBMI2], Defs = [EFLAGS] in {
2539 defm BZHI32 : bmi_bzhi<0xF5, "bzhi{l}", GR32, i32mem,
2540 X86bzhi, loadi32, WriteBZHI>;
2541 defm BZHI64 : bmi_bzhi<0xF5, "bzhi{q}", GR64, i64mem,
2542 X86bzhi, loadi64, WriteBZHI>, VEX_W;
2545 def CountTrailingOnes : SDNodeXForm<imm, [{
2546 // Count the trailing ones in the immediate.
2547 return getI8Imm(countTrailingOnes(N->getZExtValue()), SDLoc(N));
2550 def BEXTRMaskXForm : SDNodeXForm<imm, [{
2551 unsigned Length = countTrailingOnes(N->getZExtValue());
2552 return getI32Imm(Length << 8, SDLoc(N));
2555 def AndMask64 : ImmLeaf<i64, [{
2556 return isMask_64(Imm) && !isUInt<32>(Imm);
2559 // Use BEXTR for 64-bit 'and' with large immediate 'mask'.
2560 let Predicates = [HasBMI, NoBMI2, NoTBM] in {
2561 def : Pat<(and GR64:$src, AndMask64:$mask),
2562 (BEXTR64rr GR64:$src,
2563 (SUBREG_TO_REG (i64 0),
2564 (MOV32ri (BEXTRMaskXForm imm:$mask)), sub_32bit))>;
2565 def : Pat<(and (loadi64 addr:$src), AndMask64:$mask),
2566 (BEXTR64rm addr:$src,
2567 (SUBREG_TO_REG (i64 0),
2568 (MOV32ri (BEXTRMaskXForm imm:$mask)), sub_32bit))>;
2571 // Use BZHI for 64-bit 'and' with large immediate 'mask'.
2572 let Predicates = [HasBMI2, NoTBM] in {
2573 def : Pat<(and GR64:$src, AndMask64:$mask),
2574 (BZHI64rr GR64:$src,
2575 (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
2576 (MOV8ri (CountTrailingOnes imm:$mask)), sub_8bit))>;
2577 def : Pat<(and (loadi64 addr:$src), AndMask64:$mask),
2578 (BZHI64rm addr:$src,
2579 (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
2580 (MOV8ri (CountTrailingOnes imm:$mask)), sub_8bit))>;
2583 multiclass bmi_pdep_pext<string mnemonic, RegisterClass RC,
2584 X86MemOperand x86memop, Intrinsic Int,
2586 def rr : I<0xF5, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
2587 !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2588 [(set RC:$dst, (Int RC:$src1, RC:$src2))]>,
2589 VEX_4V, Sched<[WriteALU]>;
2590 def rm : I<0xF5, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
2591 !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2592 [(set RC:$dst, (Int RC:$src1, (ld_frag addr:$src2)))]>,
2593 VEX_4V, Sched<[WriteALU.Folded, WriteALU.ReadAfterFold]>;
2596 let Predicates = [HasBMI2] in {
2597 defm PDEP32 : bmi_pdep_pext<"pdep{l}", GR32, i32mem,
2598 int_x86_bmi_pdep_32, loadi32>, T8XD;
2599 defm PDEP64 : bmi_pdep_pext<"pdep{q}", GR64, i64mem,
2600 int_x86_bmi_pdep_64, loadi64>, T8XD, VEX_W;
2601 defm PEXT32 : bmi_pdep_pext<"pext{l}", GR32, i32mem,
2602 int_x86_bmi_pext_32, loadi32>, T8XS;
2603 defm PEXT64 : bmi_pdep_pext<"pext{q}", GR64, i64mem,
2604 int_x86_bmi_pext_64, loadi64>, T8XS, VEX_W;
2607 //===----------------------------------------------------------------------===//
2610 let Predicates = [HasTBM], Defs = [EFLAGS] in {
2612 multiclass tbm_ternary_imm<bits<8> opc, RegisterClass RC, string OpcodeStr,
2613 X86MemOperand x86memop, PatFrag ld_frag,
2614 SDNode OpNode, Operand immtype,
2615 SDPatternOperator immoperator,
2616 X86FoldableSchedWrite Sched> {
2617 def ri : Ii32<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, immtype:$cntl),
2618 !strconcat(OpcodeStr,
2619 "\t{$cntl, $src1, $dst|$dst, $src1, $cntl}"),
2620 [(set RC:$dst, (OpNode RC:$src1, immoperator:$cntl))]>,
2621 XOP, XOPA, Sched<[Sched]>;
2622 def mi : Ii32<opc, MRMSrcMem, (outs RC:$dst),
2623 (ins x86memop:$src1, immtype:$cntl),
2624 !strconcat(OpcodeStr,
2625 "\t{$cntl, $src1, $dst|$dst, $src1, $cntl}"),
2626 [(set RC:$dst, (OpNode (ld_frag addr:$src1), immoperator:$cntl))]>,
2627 XOP, XOPA, Sched<[Sched.Folded]>;
2630 defm BEXTRI32 : tbm_ternary_imm<0x10, GR32, "bextr{l}", i32mem, loadi32,
2631 X86bextr, i32imm, imm, WriteBEXTR>;
2632 let ImmT = Imm32S in
2633 defm BEXTRI64 : tbm_ternary_imm<0x10, GR64, "bextr{q}", i64mem, loadi64,
2634 X86bextr, i64i32imm,
2635 i64immSExt32, WriteBEXTR>, VEX_W;
2637 multiclass tbm_binary_rm<bits<8> opc, Format FormReg, Format FormMem,
2638 RegisterClass RC, string OpcodeStr,
2639 X86MemOperand x86memop, X86FoldableSchedWrite Sched> {
2640 let hasSideEffects = 0 in {
2641 def rr : I<opc, FormReg, (outs RC:$dst), (ins RC:$src),
2642 !strconcat(OpcodeStr,"\t{$src, $dst|$dst, $src}"), []>,
2643 XOP_4V, XOP9, Sched<[Sched]>;
2645 def rm : I<opc, FormMem, (outs RC:$dst), (ins x86memop:$src),
2646 !strconcat(OpcodeStr,"\t{$src, $dst|$dst, $src}"), []>,
2647 XOP_4V, XOP9, Sched<[Sched.Folded]>;
2651 multiclass tbm_binary_intr<bits<8> opc, string OpcodeStr,
2652 X86FoldableSchedWrite Sched,
2653 Format FormReg, Format FormMem> {
2654 defm NAME#32 : tbm_binary_rm<opc, FormReg, FormMem, GR32, OpcodeStr#"{l}",
2656 defm NAME#64 : tbm_binary_rm<opc, FormReg, FormMem, GR64, OpcodeStr#"{q}",
2657 i64mem, Sched>, VEX_W;
2660 defm BLCFILL : tbm_binary_intr<0x01, "blcfill", WriteALU, MRM1r, MRM1m>;
2661 defm BLCI : tbm_binary_intr<0x02, "blci", WriteALU, MRM6r, MRM6m>;
2662 defm BLCIC : tbm_binary_intr<0x01, "blcic", WriteALU, MRM5r, MRM5m>;
2663 defm BLCMSK : tbm_binary_intr<0x02, "blcmsk", WriteALU, MRM1r, MRM1m>;
2664 defm BLCS : tbm_binary_intr<0x01, "blcs", WriteALU, MRM3r, MRM3m>;
2665 defm BLSFILL : tbm_binary_intr<0x01, "blsfill", WriteALU, MRM2r, MRM2m>;
2666 defm BLSIC : tbm_binary_intr<0x01, "blsic", WriteALU, MRM6r, MRM6m>;
2667 defm T1MSKC : tbm_binary_intr<0x01, "t1mskc", WriteALU, MRM7r, MRM7m>;
2668 defm TZMSK : tbm_binary_intr<0x01, "tzmsk", WriteALU, MRM4r, MRM4m>;
2671 // Use BEXTRI for 64-bit 'and' with large immediate 'mask'.
2672 let Predicates = [HasTBM] in {
2673 def : Pat<(and GR64:$src, AndMask64:$mask),
2674 (BEXTRI64ri GR64:$src, (BEXTRMaskXForm imm:$mask))>;
2676 def : Pat<(and (loadi64 addr:$src), AndMask64:$mask),
2677 (BEXTRI64mi addr:$src, (BEXTRMaskXForm imm:$mask))>;
2680 //===----------------------------------------------------------------------===//
2681 // Lightweight Profiling Instructions
2683 let Predicates = [HasLWP], SchedRW = [WriteSystem] in {
2685 def LLWPCB : I<0x12, MRM0r, (outs), (ins GR32:$src), "llwpcb\t$src",
2686 [(int_x86_llwpcb GR32:$src)]>, XOP, XOP9;
2687 def SLWPCB : I<0x12, MRM1r, (outs GR32:$dst), (ins), "slwpcb\t$dst",
2688 [(set GR32:$dst, (int_x86_slwpcb))]>, XOP, XOP9;
2690 def LLWPCB64 : I<0x12, MRM0r, (outs), (ins GR64:$src), "llwpcb\t$src",
2691 [(int_x86_llwpcb GR64:$src)]>, XOP, XOP9, VEX_W;
2692 def SLWPCB64 : I<0x12, MRM1r, (outs GR64:$dst), (ins), "slwpcb\t$dst",
2693 [(set GR64:$dst, (int_x86_slwpcb))]>, XOP, XOP9, VEX_W;
2695 multiclass lwpins_intr<RegisterClass RC> {
2696 def rri : Ii32<0x12, MRM0r, (outs), (ins RC:$src0, GR32:$src1, i32imm:$cntl),
2697 "lwpins\t{$cntl, $src1, $src0|$src0, $src1, $cntl}",
2698 [(set EFLAGS, (X86lwpins RC:$src0, GR32:$src1, timm:$cntl))]>,
2701 def rmi : Ii32<0x12, MRM0m, (outs), (ins RC:$src0, i32mem:$src1, i32imm:$cntl),
2702 "lwpins\t{$cntl, $src1, $src0|$src0, $src1, $cntl}",
2703 [(set EFLAGS, (X86lwpins RC:$src0, (loadi32 addr:$src1), timm:$cntl))]>,
2707 let Defs = [EFLAGS] in {
2708 defm LWPINS32 : lwpins_intr<GR32>;
2709 defm LWPINS64 : lwpins_intr<GR64>, VEX_W;
2712 multiclass lwpval_intr<RegisterClass RC, Intrinsic Int> {
2713 def rri : Ii32<0x12, MRM1r, (outs), (ins RC:$src0, GR32:$src1, i32imm:$cntl),
2714 "lwpval\t{$cntl, $src1, $src0|$src0, $src1, $cntl}",
2715 [(Int RC:$src0, GR32:$src1, timm:$cntl)]>, XOP_4V, XOPA;
2717 def rmi : Ii32<0x12, MRM1m, (outs), (ins RC:$src0, i32mem:$src1, i32imm:$cntl),
2718 "lwpval\t{$cntl, $src1, $src0|$src0, $src1, $cntl}",
2719 [(Int RC:$src0, (loadi32 addr:$src1), timm:$cntl)]>,
2723 defm LWPVAL32 : lwpval_intr<GR32, int_x86_lwpval32>;
2724 defm LWPVAL64 : lwpval_intr<GR64, int_x86_lwpval64>, VEX_W;
2726 } // HasLWP, SchedRW
2728 //===----------------------------------------------------------------------===//
2729 // MONITORX/MWAITX Instructions
2731 let SchedRW = [ WriteSystem ] in {
2732 let Uses = [ EAX, ECX, EDX ] in
2733 def MONITORX32rrr : I<0x01, MRM_FA, (outs), (ins), "monitorx", []>,
2734 TB, Requires<[ HasMWAITX, Not64BitMode ]>;
2735 let Uses = [ RAX, ECX, EDX ] in
2736 def MONITORX64rrr : I<0x01, MRM_FA, (outs), (ins), "monitorx", []>,
2737 TB, Requires<[ HasMWAITX, In64BitMode ]>;
2739 let Uses = [ ECX, EAX, EBX ] in {
2740 def MWAITXrrr : I<0x01, MRM_FB, (outs), (ins), "mwaitx",
2741 [(int_x86_mwaitx ECX, EAX, EBX)]>,
2742 TB, Requires<[ HasMWAITX ]>;
2746 def : InstAlias<"mwaitx\t{%eax, %ecx, %ebx|ebx, ecx, eax}", (MWAITXrrr)>,
2747 Requires<[ Not64BitMode ]>;
2748 def : InstAlias<"mwaitx\t{%rax, %rcx, %rbx|rbx, rcx, rax}", (MWAITXrrr)>,
2749 Requires<[ In64BitMode ]>;
2751 def : InstAlias<"monitorx\t{%eax, %ecx, %edx|edx, ecx, eax}", (MONITORX32rrr)>,
2752 Requires<[ Not64BitMode ]>;
2753 def : InstAlias<"monitorx\t{%rax, %rcx, %rdx|rdx, rcx, rax}", (MONITORX64rrr)>,
2754 Requires<[ In64BitMode ]>;
2756 //===----------------------------------------------------------------------===//
2757 // WAITPKG Instructions
2759 let SchedRW = [WriteSystem] in {
2760 def UMONITOR16 : I<0xAE, MRM6r, (outs), (ins GR16:$src),
2761 "umonitor\t$src", [(int_x86_umonitor GR16:$src)]>,
2762 XS, AdSize16, Requires<[HasWAITPKG, Not64BitMode]>;
2763 def UMONITOR32 : I<0xAE, MRM6r, (outs), (ins GR32:$src),
2764 "umonitor\t$src", [(int_x86_umonitor GR32:$src)]>,
2765 XS, AdSize32, Requires<[HasWAITPKG]>;
2766 def UMONITOR64 : I<0xAE, MRM6r, (outs), (ins GR64:$src),
2767 "umonitor\t$src", [(int_x86_umonitor GR64:$src)]>,
2768 XS, AdSize64, Requires<[HasWAITPKG, In64BitMode]>;
2769 let Uses = [EAX, EDX], Defs = [EFLAGS] in {
2770 def UMWAIT : I<0xAE, MRM6r,
2771 (outs), (ins GR32orGR64:$src), "umwait\t$src",
2772 [(set EFLAGS, (X86umwait GR32orGR64:$src, EDX, EAX))]>,
2773 XD, Requires<[HasWAITPKG]>;
2774 def TPAUSE : I<0xAE, MRM6r,
2775 (outs), (ins GR32orGR64:$src), "tpause\t$src",
2776 [(set EFLAGS, (X86tpause GR32orGR64:$src, EDX, EAX))]>,
2777 PD, Requires<[HasWAITPKG]>, NotMemoryFoldable;
2781 //===----------------------------------------------------------------------===//
2782 // MOVDIRI - Move doubleword/quadword as direct store
2784 let SchedRW = [WriteStore] in {
2785 def MOVDIRI32 : I<0xF9, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
2786 "movdiri\t{$src, $dst|$dst, $src}",
2787 [(int_x86_directstore32 addr:$dst, GR32:$src)]>,
2788 T8, Requires<[HasMOVDIRI]>;
2789 def MOVDIRI64 : RI<0xF9, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
2790 "movdiri\t{$src, $dst|$dst, $src}",
2791 [(int_x86_directstore64 addr:$dst, GR64:$src)]>,
2792 T8, Requires<[In64BitMode, HasMOVDIRI]>;
2795 //===----------------------------------------------------------------------===//
2796 // MOVDIR64B - Move 64 bytes as direct store
2798 let SchedRW = [WriteStore] in {
2799 def MOVDIR64B16 : I<0xF8, MRMSrcMem, (outs), (ins GR16:$dst, i512mem:$src),
2800 "movdir64b\t{$src, $dst|$dst, $src}", []>,
2801 T8PD, AdSize16, Requires<[HasMOVDIR64B, Not64BitMode]>;
2802 def MOVDIR64B32 : I<0xF8, MRMSrcMem, (outs), (ins GR32:$dst, i512mem:$src),
2803 "movdir64b\t{$src, $dst|$dst, $src}",
2804 [(int_x86_movdir64b GR32:$dst, addr:$src)]>,
2805 T8PD, AdSize32, Requires<[HasMOVDIR64B]>;
2806 def MOVDIR64B64 : I<0xF8, MRMSrcMem, (outs), (ins GR64:$dst, i512mem:$src),
2807 "movdir64b\t{$src, $dst|$dst, $src}",
2808 [(int_x86_movdir64b GR64:$dst, addr:$src)]>,
2809 T8PD, AdSize64, Requires<[HasMOVDIR64B, In64BitMode]>;
2812 //===----------------------------------------------------------------------===//
2813 // ENQCMD/S - Enqueue 64-byte command as user with 64-byte write atomicity
2815 let SchedRW = [WriteStore], Defs = [EFLAGS] in {
2816 def ENQCMD16 : I<0xF8, MRMSrcMem, (outs), (ins GR16:$dst, i512mem:$src),
2817 "enqcmd\t{$src, $dst|$dst, $src}",
2818 [(set EFLAGS, (X86enqcmd GR16:$dst, addr:$src))]>,
2819 T8XD, AdSize16, Requires<[HasENQCMD, Not64BitMode]>;
2820 def ENQCMD32 : I<0xF8, MRMSrcMem, (outs), (ins GR32:$dst, i512mem:$src),
2821 "enqcmd\t{$src, $dst|$dst, $src}",
2822 [(set EFLAGS, (X86enqcmd GR32:$dst, addr:$src))]>,
2823 T8XD, AdSize32, Requires<[HasENQCMD]>;
2824 def ENQCMD64 : I<0xF8, MRMSrcMem, (outs), (ins GR64:$dst, i512mem:$src),
2825 "enqcmd\t{$src, $dst|$dst, $src}",
2826 [(set EFLAGS, (X86enqcmd GR64:$dst, addr:$src))]>,
2827 T8XD, AdSize64, Requires<[HasENQCMD, In64BitMode]>;
2829 def ENQCMDS16 : I<0xF8, MRMSrcMem, (outs), (ins GR16:$dst, i512mem:$src),
2830 "enqcmds\t{$src, $dst|$dst, $src}",
2831 [(set EFLAGS, (X86enqcmds GR16:$dst, addr:$src))]>,
2832 T8XS, AdSize16, Requires<[HasENQCMD, Not64BitMode]>;
2833 def ENQCMDS32 : I<0xF8, MRMSrcMem, (outs), (ins GR32:$dst, i512mem:$src),
2834 "enqcmds\t{$src, $dst|$dst, $src}",
2835 [(set EFLAGS, (X86enqcmds GR32:$dst, addr:$src))]>,
2836 T8XS, AdSize32, Requires<[HasENQCMD]>;
2837 def ENQCMDS64 : I<0xF8, MRMSrcMem, (outs), (ins GR64:$dst, i512mem:$src),
2838 "enqcmds\t{$src, $dst|$dst, $src}",
2839 [(set EFLAGS, (X86enqcmds GR64:$dst, addr:$src))]>,
2840 T8XS, AdSize64, Requires<[HasENQCMD, In64BitMode]>;
2843 //===----------------------------------------------------------------------===//
2844 // CLZERO Instruction
2846 let SchedRW = [WriteLoad] in {
2848 def CLZERO32r : I<0x01, MRM_FC, (outs), (ins), "clzero", []>,
2849 TB, Requires<[HasCLZERO, Not64BitMode]>;
2851 def CLZERO64r : I<0x01, MRM_FC, (outs), (ins), "clzero", []>,
2852 TB, Requires<[HasCLZERO, In64BitMode]>;
2855 def : InstAlias<"clzero\t{%eax|eax}", (CLZERO32r)>, Requires<[Not64BitMode]>;
2856 def : InstAlias<"clzero\t{%rax|rax}", (CLZERO64r)>, Requires<[In64BitMode]>;
2858 //===----------------------------------------------------------------------===//
2859 // Pattern fragments to auto generate TBM instructions.
2860 //===----------------------------------------------------------------------===//
2862 let Predicates = [HasTBM] in {
2863 // FIXME: patterns for the load versions are not implemented
2864 def : Pat<(and GR32:$src, (add GR32:$src, 1)),
2865 (BLCFILL32rr GR32:$src)>;
2866 def : Pat<(and GR64:$src, (add GR64:$src, 1)),
2867 (BLCFILL64rr GR64:$src)>;
2869 def : Pat<(or GR32:$src, (not (add GR32:$src, 1))),
2870 (BLCI32rr GR32:$src)>;
2871 def : Pat<(or GR64:$src, (not (add GR64:$src, 1))),
2872 (BLCI64rr GR64:$src)>;
2874 // Extra patterns because opt can optimize the above patterns to this.
2875 def : Pat<(or GR32:$src, (sub -2, GR32:$src)),
2876 (BLCI32rr GR32:$src)>;
2877 def : Pat<(or GR64:$src, (sub -2, GR64:$src)),
2878 (BLCI64rr GR64:$src)>;
2880 def : Pat<(and (not GR32:$src), (add GR32:$src, 1)),
2881 (BLCIC32rr GR32:$src)>;
2882 def : Pat<(and (not GR64:$src), (add GR64:$src, 1)),
2883 (BLCIC64rr GR64:$src)>;
2885 def : Pat<(xor GR32:$src, (add GR32:$src, 1)),
2886 (BLCMSK32rr GR32:$src)>;
2887 def : Pat<(xor GR64:$src, (add GR64:$src, 1)),
2888 (BLCMSK64rr GR64:$src)>;
2890 def : Pat<(or GR32:$src, (add GR32:$src, 1)),
2891 (BLCS32rr GR32:$src)>;
2892 def : Pat<(or GR64:$src, (add GR64:$src, 1)),
2893 (BLCS64rr GR64:$src)>;
2895 def : Pat<(or GR32:$src, (add GR32:$src, -1)),
2896 (BLSFILL32rr GR32:$src)>;
2897 def : Pat<(or GR64:$src, (add GR64:$src, -1)),
2898 (BLSFILL64rr GR64:$src)>;
2900 def : Pat<(or (not GR32:$src), (add GR32:$src, -1)),
2901 (BLSIC32rr GR32:$src)>;
2902 def : Pat<(or (not GR64:$src), (add GR64:$src, -1)),
2903 (BLSIC64rr GR64:$src)>;
2905 def : Pat<(or (not GR32:$src), (add GR32:$src, 1)),
2906 (T1MSKC32rr GR32:$src)>;
2907 def : Pat<(or (not GR64:$src), (add GR64:$src, 1)),
2908 (T1MSKC64rr GR64:$src)>;
2910 def : Pat<(and (not GR32:$src), (add GR32:$src, -1)),
2911 (TZMSK32rr GR32:$src)>;
2912 def : Pat<(and (not GR64:$src), (add GR64:$src, -1)),
2913 (TZMSK64rr GR64:$src)>;
2915 // Patterns to match flag producing ops.
2916 def : Pat<(or_flag_nocf GR32:$src, (not (add GR32:$src, 1))),
2917 (BLCI32rr GR32:$src)>;
2918 def : Pat<(or_flag_nocf GR64:$src, (not (add GR64:$src, 1))),
2919 (BLCI64rr GR64:$src)>;
2921 // Extra patterns because opt can optimize the above patterns to this.
2922 def : Pat<(or_flag_nocf GR32:$src, (sub -2, GR32:$src)),
2923 (BLCI32rr GR32:$src)>;
2924 def : Pat<(or_flag_nocf GR64:$src, (sub -2, GR64:$src)),
2925 (BLCI64rr GR64:$src)>;
2927 def : Pat<(and_flag_nocf (not GR32:$src), (add GR32:$src, 1)),
2928 (BLCIC32rr GR32:$src)>;
2929 def : Pat<(and_flag_nocf (not GR64:$src), (add GR64:$src, 1)),
2930 (BLCIC64rr GR64:$src)>;
2932 def : Pat<(xor_flag_nocf GR32:$src, (add GR32:$src, 1)),
2933 (BLCMSK32rr GR32:$src)>;
2934 def : Pat<(xor_flag_nocf GR64:$src, (add GR64:$src, 1)),
2935 (BLCMSK64rr GR64:$src)>;
2937 def : Pat<(or_flag_nocf GR32:$src, (add GR32:$src, 1)),
2938 (BLCS32rr GR32:$src)>;
2939 def : Pat<(or_flag_nocf GR64:$src, (add GR64:$src, 1)),
2940 (BLCS64rr GR64:$src)>;
2942 def : Pat<(or_flag_nocf GR32:$src, (add GR32:$src, -1)),
2943 (BLSFILL32rr GR32:$src)>;
2944 def : Pat<(or_flag_nocf GR64:$src, (add GR64:$src, -1)),
2945 (BLSFILL64rr GR64:$src)>;
2947 def : Pat<(or_flag_nocf (not GR32:$src), (add GR32:$src, -1)),
2948 (BLSIC32rr GR32:$src)>;
2949 def : Pat<(or_flag_nocf (not GR64:$src), (add GR64:$src, -1)),
2950 (BLSIC64rr GR64:$src)>;
2952 def : Pat<(or_flag_nocf (not GR32:$src), (add GR32:$src, 1)),
2953 (T1MSKC32rr GR32:$src)>;
2954 def : Pat<(or_flag_nocf (not GR64:$src), (add GR64:$src, 1)),
2955 (T1MSKC64rr GR64:$src)>;
2957 def : Pat<(and_flag_nocf (not GR32:$src), (add GR32:$src, -1)),
2958 (TZMSK32rr GR32:$src)>;
2959 def : Pat<(and_flag_nocf (not GR64:$src), (add GR64:$src, -1)),
2960 (TZMSK64rr GR64:$src)>;
2963 //===----------------------------------------------------------------------===//
2964 // Memory Instructions
2967 let Predicates = [HasCLFLUSHOPT], SchedRW = [WriteLoad] in
2968 def CLFLUSHOPT : I<0xAE, MRM7m, (outs), (ins i8mem:$src),
2969 "clflushopt\t$src", [(int_x86_clflushopt addr:$src)]>, PD;
2971 let Predicates = [HasCLWB], SchedRW = [WriteLoad] in
2972 def CLWB : I<0xAE, MRM6m, (outs), (ins i8mem:$src), "clwb\t$src",
2973 [(int_x86_clwb addr:$src)]>, PD, NotMemoryFoldable;
2975 let Predicates = [HasCLDEMOTE], SchedRW = [WriteLoad] in
2976 def CLDEMOTE : I<0x1C, MRM0m, (outs), (ins i8mem:$src), "cldemote\t$src",
2977 [(int_x86_cldemote addr:$src)]>, TB;
2979 //===----------------------------------------------------------------------===//
2981 //===----------------------------------------------------------------------===//
2983 include "X86InstrArithmetic.td"
2984 include "X86InstrCMovSetCC.td"
2985 include "X86InstrExtension.td"
2986 include "X86InstrControl.td"
2987 include "X86InstrShiftRotate.td"
2989 // X87 Floating Point Stack.
2990 include "X86InstrFPStack.td"
2992 // SIMD support (SSE, MMX and AVX)
2993 include "X86InstrFragmentsSIMD.td"
2995 // FMA - Fused Multiply-Add support (requires FMA)
2996 include "X86InstrFMA.td"
2999 include "X86InstrXOP.td"
3001 // SSE, MMX and 3DNow! vector support.
3002 include "X86InstrSSE.td"
3003 include "X86InstrAVX512.td"
3004 include "X86InstrMMX.td"
3005 include "X86Instr3DNow.td"
3008 include "X86InstrMPX.td"
3010 include "X86InstrVMX.td"
3011 include "X86InstrSVM.td"
3013 include "X86InstrTSX.td"
3014 include "X86InstrSGX.td"
3016 // System instructions.
3017 include "X86InstrSystem.td"
3019 // Compiler Pseudo Instructions and Pat Patterns
3020 include "X86InstrCompiler.td"
3021 include "X86InstrVecCompiler.td"
3023 //===----------------------------------------------------------------------===//
3024 // Assembler Mnemonic Aliases
3025 //===----------------------------------------------------------------------===//
3027 def : MnemonicAlias<"call", "callw", "att">, Requires<[In16BitMode]>;
3028 def : MnemonicAlias<"call", "calll", "att">, Requires<[In32BitMode]>;
3029 def : MnemonicAlias<"call", "callq", "att">, Requires<[In64BitMode]>;
3031 def : MnemonicAlias<"cbw", "cbtw", "att">;
3032 def : MnemonicAlias<"cwde", "cwtl", "att">;
3033 def : MnemonicAlias<"cwd", "cwtd", "att">;
3034 def : MnemonicAlias<"cdq", "cltd", "att">;
3035 def : MnemonicAlias<"cdqe", "cltq", "att">;
3036 def : MnemonicAlias<"cqo", "cqto", "att">;
3038 // In 64-bit mode lret maps to lretl; it is not ambiguous with lretq.
3039 def : MnemonicAlias<"lret", "lretw", "att">, Requires<[In16BitMode]>;
3040 def : MnemonicAlias<"lret", "lretl", "att">, Requires<[Not16BitMode]>;
3042 def : MnemonicAlias<"leavel", "leave", "att">, Requires<[Not64BitMode]>;
3043 def : MnemonicAlias<"leaveq", "leave", "att">, Requires<[In64BitMode]>;
3045 def : MnemonicAlias<"loopz", "loope">;
3046 def : MnemonicAlias<"loopnz", "loopne">;
3048 def : MnemonicAlias<"pop", "popw", "att">, Requires<[In16BitMode]>;
3049 def : MnemonicAlias<"pop", "popl", "att">, Requires<[In32BitMode]>;
3050 def : MnemonicAlias<"pop", "popq", "att">, Requires<[In64BitMode]>;
3051 def : MnemonicAlias<"popf", "popfw", "att">, Requires<[In16BitMode]>;
3052 def : MnemonicAlias<"popf", "popfl", "att">, Requires<[In32BitMode]>;
3053 def : MnemonicAlias<"popf", "popfq", "att">, Requires<[In64BitMode]>;
3054 def : MnemonicAlias<"popf", "popfq", "intel">, Requires<[In64BitMode]>;
3055 def : MnemonicAlias<"popfd", "popfl", "att">;
3056 def : MnemonicAlias<"popfw", "popf", "intel">, Requires<[In32BitMode]>;
3057 def : MnemonicAlias<"popfw", "popf", "intel">, Requires<[In64BitMode]>;
3059 // FIXME: This is wrong for "push reg". "push %bx" should turn into pushw in
3060 // all modes. However: "push (addr)" and "push $42" should default to
3061 // pushl/pushq depending on the current mode. Similar for "pop %bx"
3062 def : MnemonicAlias<"push", "pushw", "att">, Requires<[In16BitMode]>;
3063 def : MnemonicAlias<"push", "pushl", "att">, Requires<[In32BitMode]>;
3064 def : MnemonicAlias<"push", "pushq", "att">, Requires<[In64BitMode]>;
3065 def : MnemonicAlias<"pushf", "pushfw", "att">, Requires<[In16BitMode]>;
3066 def : MnemonicAlias<"pushf", "pushfl", "att">, Requires<[In32BitMode]>;
3067 def : MnemonicAlias<"pushf", "pushfq", "att">, Requires<[In64BitMode]>;
3068 def : MnemonicAlias<"pushf", "pushfq", "intel">, Requires<[In64BitMode]>;
3069 def : MnemonicAlias<"pushfd", "pushfl", "att">;
3070 def : MnemonicAlias<"pushfw", "pushf", "intel">, Requires<[In32BitMode]>;
3071 def : MnemonicAlias<"pushfw", "pushf", "intel">, Requires<[In64BitMode]>;
3073 def : MnemonicAlias<"popad", "popal", "intel">, Requires<[Not64BitMode]>;
3074 def : MnemonicAlias<"pushad", "pushal", "intel">, Requires<[Not64BitMode]>;
3075 def : MnemonicAlias<"popa", "popaw", "intel">, Requires<[In16BitMode]>;
3076 def : MnemonicAlias<"pusha", "pushaw", "intel">, Requires<[In16BitMode]>;
3077 def : MnemonicAlias<"popa", "popal", "intel">, Requires<[In32BitMode]>;
3078 def : MnemonicAlias<"pusha", "pushal", "intel">, Requires<[In32BitMode]>;
3080 def : MnemonicAlias<"popa", "popaw", "att">, Requires<[In16BitMode]>;
3081 def : MnemonicAlias<"pusha", "pushaw", "att">, Requires<[In16BitMode]>;
3082 def : MnemonicAlias<"popa", "popal", "att">, Requires<[In32BitMode]>;
3083 def : MnemonicAlias<"pusha", "pushal", "att">, Requires<[In32BitMode]>;
3085 def : MnemonicAlias<"repe", "rep">;
3086 def : MnemonicAlias<"repz", "rep">;
3087 def : MnemonicAlias<"repnz", "repne">;
3089 def : MnemonicAlias<"ret", "retw", "att">, Requires<[In16BitMode]>;
3090 def : MnemonicAlias<"ret", "retl", "att">, Requires<[In32BitMode]>;
3091 def : MnemonicAlias<"ret", "retq", "att">, Requires<[In64BitMode]>;
3093 // Apply 'ret' behavior to 'retn'
3094 def : MnemonicAlias<"retn", "retw", "att">, Requires<[In16BitMode]>;
3095 def : MnemonicAlias<"retn", "retl", "att">, Requires<[In32BitMode]>;
3096 def : MnemonicAlias<"retn", "retq", "att">, Requires<[In64BitMode]>;
3097 def : MnemonicAlias<"retn", "ret", "intel">;
3099 def : MnemonicAlias<"sal", "shl", "intel">;
3100 def : MnemonicAlias<"salb", "shlb", "att">;
3101 def : MnemonicAlias<"salw", "shlw", "att">;
3102 def : MnemonicAlias<"sall", "shll", "att">;
3103 def : MnemonicAlias<"salq", "shlq", "att">;
3105 def : MnemonicAlias<"smovb", "movsb", "att">;
3106 def : MnemonicAlias<"smovw", "movsw", "att">;
3107 def : MnemonicAlias<"smovl", "movsl", "att">;
3108 def : MnemonicAlias<"smovq", "movsq", "att">;
3110 def : MnemonicAlias<"ud2a", "ud2", "att">;
3111 def : MnemonicAlias<"verrw", "verr", "att">;
3113 // MS recognizes 'xacquire'/'xrelease' as 'acquire'/'release'
3114 def : MnemonicAlias<"acquire", "xacquire", "intel">;
3115 def : MnemonicAlias<"release", "xrelease", "intel">;
3117 // System instruction aliases.
3118 def : MnemonicAlias<"iret", "iretw", "att">, Requires<[In16BitMode]>;
3119 def : MnemonicAlias<"iret", "iretl", "att">, Requires<[Not16BitMode]>;
3120 def : MnemonicAlias<"sysret", "sysretl", "att">;
3121 def : MnemonicAlias<"sysexit", "sysexitl", "att">;
3123 def : MnemonicAlias<"lgdt", "lgdtw", "att">, Requires<[In16BitMode]>;
3124 def : MnemonicAlias<"lgdt", "lgdtl", "att">, Requires<[In32BitMode]>;
3125 def : MnemonicAlias<"lgdt", "lgdtq", "att">, Requires<[In64BitMode]>;
3126 def : MnemonicAlias<"lidt", "lidtw", "att">, Requires<[In16BitMode]>;
3127 def : MnemonicAlias<"lidt", "lidtl", "att">, Requires<[In32BitMode]>;
3128 def : MnemonicAlias<"lidt", "lidtq", "att">, Requires<[In64BitMode]>;
3129 def : MnemonicAlias<"sgdt", "sgdtw", "att">, Requires<[In16BitMode]>;
3130 def : MnemonicAlias<"sgdt", "sgdtl", "att">, Requires<[In32BitMode]>;
3131 def : MnemonicAlias<"sgdt", "sgdtq", "att">, Requires<[In64BitMode]>;
3132 def : MnemonicAlias<"sidt", "sidtw", "att">, Requires<[In16BitMode]>;
3133 def : MnemonicAlias<"sidt", "sidtl", "att">, Requires<[In32BitMode]>;
3134 def : MnemonicAlias<"sidt", "sidtq", "att">, Requires<[In64BitMode]>;
3135 def : MnemonicAlias<"lgdt", "lgdtw", "intel">, Requires<[In16BitMode]>;
3136 def : MnemonicAlias<"lgdt", "lgdtd", "intel">, Requires<[In32BitMode]>;
3137 def : MnemonicAlias<"lidt", "lidtw", "intel">, Requires<[In16BitMode]>;
3138 def : MnemonicAlias<"lidt", "lidtd", "intel">, Requires<[In32BitMode]>;
3139 def : MnemonicAlias<"sgdt", "sgdtw", "intel">, Requires<[In16BitMode]>;
3140 def : MnemonicAlias<"sgdt", "sgdtd", "intel">, Requires<[In32BitMode]>;
3141 def : MnemonicAlias<"sidt", "sidtw", "intel">, Requires<[In16BitMode]>;
3142 def : MnemonicAlias<"sidt", "sidtd", "intel">, Requires<[In32BitMode]>;
3145 // Floating point stack aliases.
3146 def : MnemonicAlias<"fcmovz", "fcmove", "att">;
3147 def : MnemonicAlias<"fcmova", "fcmovnbe", "att">;
3148 def : MnemonicAlias<"fcmovnae", "fcmovb", "att">;
3149 def : MnemonicAlias<"fcmovna", "fcmovbe", "att">;
3150 def : MnemonicAlias<"fcmovae", "fcmovnb", "att">;
3151 def : MnemonicAlias<"fcomip", "fcompi">;
3152 def : MnemonicAlias<"fildq", "fildll", "att">;
3153 def : MnemonicAlias<"fistpq", "fistpll", "att">;
3154 def : MnemonicAlias<"fisttpq", "fisttpll", "att">;
3155 def : MnemonicAlias<"fldcww", "fldcw", "att">;
3156 def : MnemonicAlias<"fnstcww", "fnstcw", "att">;
3157 def : MnemonicAlias<"fnstsww", "fnstsw", "att">;
3158 def : MnemonicAlias<"fucomip", "fucompi">;
3159 def : MnemonicAlias<"fwait", "wait">;
3161 def : MnemonicAlias<"fxsaveq", "fxsave64", "att">;
3162 def : MnemonicAlias<"fxrstorq", "fxrstor64", "att">;
3163 def : MnemonicAlias<"xsaveq", "xsave64", "att">;
3164 def : MnemonicAlias<"xrstorq", "xrstor64", "att">;
3165 def : MnemonicAlias<"xsaveoptq", "xsaveopt64", "att">;
3166 def : MnemonicAlias<"xrstorsq", "xrstors64", "att">;
3167 def : MnemonicAlias<"xsavecq", "xsavec64", "att">;
3168 def : MnemonicAlias<"xsavesq", "xsaves64", "att">;
3170 class CondCodeAlias<string Prefix,string Suffix, string OldCond, string NewCond,
3172 : MnemonicAlias<!strconcat(Prefix, OldCond, Suffix),
3173 !strconcat(Prefix, NewCond, Suffix), VariantName>;
3175 /// IntegerCondCodeMnemonicAlias - This multiclass defines a bunch of
3176 /// MnemonicAlias's that canonicalize the condition code in a mnemonic, for
3177 /// example "setz" -> "sete".
3178 multiclass IntegerCondCodeMnemonicAlias<string Prefix, string Suffix,
3180 def C : CondCodeAlias<Prefix, Suffix, "c", "b", V>; // setc -> setb
3181 def Z : CondCodeAlias<Prefix, Suffix, "z" , "e", V>; // setz -> sete
3182 def NA : CondCodeAlias<Prefix, Suffix, "na", "be", V>; // setna -> setbe
3183 def NB : CondCodeAlias<Prefix, Suffix, "nb", "ae", V>; // setnb -> setae
3184 def NC : CondCodeAlias<Prefix, Suffix, "nc", "ae", V>; // setnc -> setae
3185 def NG : CondCodeAlias<Prefix, Suffix, "ng", "le", V>; // setng -> setle
3186 def NL : CondCodeAlias<Prefix, Suffix, "nl", "ge", V>; // setnl -> setge
3187 def NZ : CondCodeAlias<Prefix, Suffix, "nz", "ne", V>; // setnz -> setne
3188 def PE : CondCodeAlias<Prefix, Suffix, "pe", "p", V>; // setpe -> setp
3189 def PO : CondCodeAlias<Prefix, Suffix, "po", "np", V>; // setpo -> setnp
3191 def NAE : CondCodeAlias<Prefix, Suffix, "nae", "b", V>; // setnae -> setb
3192 def NBE : CondCodeAlias<Prefix, Suffix, "nbe", "a", V>; // setnbe -> seta
3193 def NGE : CondCodeAlias<Prefix, Suffix, "nge", "l", V>; // setnge -> setl
3194 def NLE : CondCodeAlias<Prefix, Suffix, "nle", "g", V>; // setnle -> setg
3197 // Aliases for set<CC>
3198 defm : IntegerCondCodeMnemonicAlias<"set", "">;
3199 // Aliases for j<CC>
3200 defm : IntegerCondCodeMnemonicAlias<"j", "">;
3201 // Aliases for cmov<CC>{w,l,q}
3202 defm : IntegerCondCodeMnemonicAlias<"cmov", "w", "att">;
3203 defm : IntegerCondCodeMnemonicAlias<"cmov", "l", "att">;
3204 defm : IntegerCondCodeMnemonicAlias<"cmov", "q", "att">;
3205 // No size suffix for intel-style asm.
3206 defm : IntegerCondCodeMnemonicAlias<"cmov", "", "intel">;
3209 //===----------------------------------------------------------------------===//
3210 // Assembler Instruction Aliases
3211 //===----------------------------------------------------------------------===//
3213 // aad/aam default to base 10 if no operand is specified.
3214 def : InstAlias<"aad", (AAD8i8 10)>, Requires<[Not64BitMode]>;
3215 def : InstAlias<"aam", (AAM8i8 10)>, Requires<[Not64BitMode]>;
3217 // Disambiguate the mem/imm form of bt-without-a-suffix as btl.
3218 // Likewise for btc/btr/bts.
3219 def : InstAlias<"bt\t{$imm, $mem|$mem, $imm}",
3220 (BT32mi8 i32mem:$mem, i32u8imm:$imm), 0, "att">;
3221 def : InstAlias<"btc\t{$imm, $mem|$mem, $imm}",
3222 (BTC32mi8 i32mem:$mem, i32u8imm:$imm), 0, "att">;
3223 def : InstAlias<"btr\t{$imm, $mem|$mem, $imm}",
3224 (BTR32mi8 i32mem:$mem, i32u8imm:$imm), 0, "att">;
3225 def : InstAlias<"bts\t{$imm, $mem|$mem, $imm}",
3226 (BTS32mi8 i32mem:$mem, i32u8imm:$imm), 0, "att">;
3229 def : InstAlias<"clr{b}\t$reg", (XOR8rr GR8 :$reg, GR8 :$reg), 0>;
3230 def : InstAlias<"clr{w}\t$reg", (XOR16rr GR16:$reg, GR16:$reg), 0>;
3231 def : InstAlias<"clr{l}\t$reg", (XOR32rr GR32:$reg, GR32:$reg), 0>;
3232 def : InstAlias<"clr{q}\t$reg", (XOR64rr GR64:$reg, GR64:$reg), 0>;
3234 // lods aliases. Accept the destination being omitted because it's implicit
3235 // in the mnemonic, or the mnemonic suffix being omitted because it's implicit
3236 // in the destination.
3237 def : InstAlias<"lodsb\t$src", (LODSB srcidx8:$src), 0>;
3238 def : InstAlias<"lodsw\t$src", (LODSW srcidx16:$src), 0>;
3239 def : InstAlias<"lods{l|d}\t$src", (LODSL srcidx32:$src), 0>;
3240 def : InstAlias<"lodsq\t$src", (LODSQ srcidx64:$src), 0>, Requires<[In64BitMode]>;
3241 def : InstAlias<"lods\t{$src, %al|al, $src}", (LODSB srcidx8:$src), 0>;
3242 def : InstAlias<"lods\t{$src, %ax|ax, $src}", (LODSW srcidx16:$src), 0>;
3243 def : InstAlias<"lods\t{$src, %eax|eax, $src}", (LODSL srcidx32:$src), 0>;
3244 def : InstAlias<"lods\t{$src, %rax|rax, $src}", (LODSQ srcidx64:$src), 0>, Requires<[In64BitMode]>;
3245 def : InstAlias<"lods\t$src", (LODSB srcidx8:$src), 0, "intel">;
3246 def : InstAlias<"lods\t$src", (LODSW srcidx16:$src), 0, "intel">;
3247 def : InstAlias<"lods\t$src", (LODSL srcidx32:$src), 0, "intel">;
3248 def : InstAlias<"lods\t$src", (LODSQ srcidx64:$src), 0, "intel">, Requires<[In64BitMode]>;
3251 // stos aliases. Accept the source being omitted because it's implicit in
3252 // the mnemonic, or the mnemonic suffix being omitted because it's implicit
3254 def : InstAlias<"stosb\t$dst", (STOSB dstidx8:$dst), 0>;
3255 def : InstAlias<"stosw\t$dst", (STOSW dstidx16:$dst), 0>;
3256 def : InstAlias<"stos{l|d}\t$dst", (STOSL dstidx32:$dst), 0>;
3257 def : InstAlias<"stosq\t$dst", (STOSQ dstidx64:$dst), 0>, Requires<[In64BitMode]>;
3258 def : InstAlias<"stos\t{%al, $dst|$dst, al}", (STOSB dstidx8:$dst), 0>;
3259 def : InstAlias<"stos\t{%ax, $dst|$dst, ax}", (STOSW dstidx16:$dst), 0>;
3260 def : InstAlias<"stos\t{%eax, $dst|$dst, eax}", (STOSL dstidx32:$dst), 0>;
3261 def : InstAlias<"stos\t{%rax, $dst|$dst, rax}", (STOSQ dstidx64:$dst), 0>, Requires<[In64BitMode]>;
3262 def : InstAlias<"stos\t$dst", (STOSB dstidx8:$dst), 0, "intel">;
3263 def : InstAlias<"stos\t$dst", (STOSW dstidx16:$dst), 0, "intel">;
3264 def : InstAlias<"stos\t$dst", (STOSL dstidx32:$dst), 0, "intel">;
3265 def : InstAlias<"stos\t$dst", (STOSQ dstidx64:$dst), 0, "intel">, Requires<[In64BitMode]>;
3268 // scas aliases. Accept the destination being omitted because it's implicit
3269 // in the mnemonic, or the mnemonic suffix being omitted because it's implicit
3270 // in the destination.
3271 def : InstAlias<"scasb\t$dst", (SCASB dstidx8:$dst), 0>;
3272 def : InstAlias<"scasw\t$dst", (SCASW dstidx16:$dst), 0>;
3273 def : InstAlias<"scas{l|d}\t$dst", (SCASL dstidx32:$dst), 0>;
3274 def : InstAlias<"scasq\t$dst", (SCASQ dstidx64:$dst), 0>, Requires<[In64BitMode]>;
3275 def : InstAlias<"scas\t{$dst, %al|al, $dst}", (SCASB dstidx8:$dst), 0>;
3276 def : InstAlias<"scas\t{$dst, %ax|ax, $dst}", (SCASW dstidx16:$dst), 0>;
3277 def : InstAlias<"scas\t{$dst, %eax|eax, $dst}", (SCASL dstidx32:$dst), 0>;
3278 def : InstAlias<"scas\t{$dst, %rax|rax, $dst}", (SCASQ dstidx64:$dst), 0>, Requires<[In64BitMode]>;
3279 def : InstAlias<"scas\t$dst", (SCASB dstidx8:$dst), 0, "intel">;
3280 def : InstAlias<"scas\t$dst", (SCASW dstidx16:$dst), 0, "intel">;
3281 def : InstAlias<"scas\t$dst", (SCASL dstidx32:$dst), 0, "intel">;
3282 def : InstAlias<"scas\t$dst", (SCASQ dstidx64:$dst), 0, "intel">, Requires<[In64BitMode]>;
3284 // cmps aliases. Mnemonic suffix being omitted because it's implicit
3285 // in the destination.
3286 def : InstAlias<"cmps\t{$dst, $src|$src, $dst}", (CMPSB dstidx8:$dst, srcidx8:$src), 0, "intel">;
3287 def : InstAlias<"cmps\t{$dst, $src|$src, $dst}", (CMPSW dstidx16:$dst, srcidx16:$src), 0, "intel">;
3288 def : InstAlias<"cmps\t{$dst, $src|$src, $dst}", (CMPSL dstidx32:$dst, srcidx32:$src), 0, "intel">;
3289 def : InstAlias<"cmps\t{$dst, $src|$src, $dst}", (CMPSQ dstidx64:$dst, srcidx64:$src), 0, "intel">, Requires<[In64BitMode]>;
3291 // movs aliases. Mnemonic suffix being omitted because it's implicit
3292 // in the destination.
3293 def : InstAlias<"movs\t{$src, $dst|$dst, $src}", (MOVSB dstidx8:$dst, srcidx8:$src), 0, "intel">;
3294 def : InstAlias<"movs\t{$src, $dst|$dst, $src}", (MOVSW dstidx16:$dst, srcidx16:$src), 0, "intel">;
3295 def : InstAlias<"movs\t{$src, $dst|$dst, $src}", (MOVSL dstidx32:$dst, srcidx32:$src), 0, "intel">;
3296 def : InstAlias<"movs\t{$src, $dst|$dst, $src}", (MOVSQ dstidx64:$dst, srcidx64:$src), 0, "intel">, Requires<[In64BitMode]>;
3298 // div and idiv aliases for explicit A register.
3299 def : InstAlias<"div{b}\t{$src, %al|al, $src}", (DIV8r GR8 :$src)>;
3300 def : InstAlias<"div{w}\t{$src, %ax|ax, $src}", (DIV16r GR16:$src)>;
3301 def : InstAlias<"div{l}\t{$src, %eax|eax, $src}", (DIV32r GR32:$src)>;
3302 def : InstAlias<"div{q}\t{$src, %rax|rax, $src}", (DIV64r GR64:$src)>;
3303 def : InstAlias<"div{b}\t{$src, %al|al, $src}", (DIV8m i8mem :$src)>;
3304 def : InstAlias<"div{w}\t{$src, %ax|ax, $src}", (DIV16m i16mem:$src)>;
3305 def : InstAlias<"div{l}\t{$src, %eax|eax, $src}", (DIV32m i32mem:$src)>;
3306 def : InstAlias<"div{q}\t{$src, %rax|rax, $src}", (DIV64m i64mem:$src)>;
3307 def : InstAlias<"idiv{b}\t{$src, %al|al, $src}", (IDIV8r GR8 :$src)>;
3308 def : InstAlias<"idiv{w}\t{$src, %ax|ax, $src}", (IDIV16r GR16:$src)>;
3309 def : InstAlias<"idiv{l}\t{$src, %eax|eax, $src}", (IDIV32r GR32:$src)>;
3310 def : InstAlias<"idiv{q}\t{$src, %rax|rax, $src}", (IDIV64r GR64:$src)>;
3311 def : InstAlias<"idiv{b}\t{$src, %al|al, $src}", (IDIV8m i8mem :$src)>;
3312 def : InstAlias<"idiv{w}\t{$src, %ax|ax, $src}", (IDIV16m i16mem:$src)>;
3313 def : InstAlias<"idiv{l}\t{$src, %eax|eax, $src}", (IDIV32m i32mem:$src)>;
3314 def : InstAlias<"idiv{q}\t{$src, %rax|rax, $src}", (IDIV64m i64mem:$src)>;
3318 // Various unary fpstack operations default to operating on ST1.
3319 // For example, "fxch" -> "fxch %st(1)"
3320 def : InstAlias<"faddp", (ADD_FPrST0 ST1), 0>;
3321 def: InstAlias<"fadd", (ADD_FPrST0 ST1), 0>;
3322 def : InstAlias<"fsub{|r}p", (SUBR_FPrST0 ST1), 0>;
3323 def : InstAlias<"fsub{r|}p", (SUB_FPrST0 ST1), 0>;
3324 def : InstAlias<"fmul", (MUL_FPrST0 ST1), 0>;
3325 def : InstAlias<"fmulp", (MUL_FPrST0 ST1), 0>;
3326 def : InstAlias<"fdiv{|r}p", (DIVR_FPrST0 ST1), 0>;
3327 def : InstAlias<"fdiv{r|}p", (DIV_FPrST0 ST1), 0>;
3328 def : InstAlias<"fxch", (XCH_F ST1), 0>;
3329 def : InstAlias<"fcom", (COM_FST0r ST1), 0>;
3330 def : InstAlias<"fcomp", (COMP_FST0r ST1), 0>;
3331 def : InstAlias<"fcomi", (COM_FIr ST1), 0>;
3332 def : InstAlias<"fcompi", (COM_FIPr ST1), 0>;
3333 def : InstAlias<"fucom", (UCOM_Fr ST1), 0>;
3334 def : InstAlias<"fucomp", (UCOM_FPr ST1), 0>;
3335 def : InstAlias<"fucomi", (UCOM_FIr ST1), 0>;
3336 def : InstAlias<"fucompi", (UCOM_FIPr ST1), 0>;
3338 // Handle fmul/fadd/fsub/fdiv instructions with explicitly written st(0) op.
3339 // For example, "fadd %st(4), %st(0)" -> "fadd %st(4)". We also disambiguate
3340 // instructions like "fadd %st(0), %st(0)" as "fadd %st(0)" for consistency with
3342 multiclass FpUnaryAlias<string Mnemonic, Instruction Inst, bit EmitAlias = 1> {
3343 def : InstAlias<!strconcat(Mnemonic, "\t$op"),
3344 (Inst RSTi:$op), EmitAlias>;
3345 def : InstAlias<!strconcat(Mnemonic, "\t{%st, %st|st, st}"),
3346 (Inst ST0), EmitAlias>;
3349 defm : FpUnaryAlias<"fadd", ADD_FST0r, 0>;
3350 defm : FpUnaryAlias<"faddp", ADD_FPrST0, 0>;
3351 defm : FpUnaryAlias<"fsub", SUB_FST0r, 0>;
3352 defm : FpUnaryAlias<"fsub{|r}p", SUBR_FPrST0, 0>;
3353 defm : FpUnaryAlias<"fsubr", SUBR_FST0r, 0>;
3354 defm : FpUnaryAlias<"fsub{r|}p", SUB_FPrST0, 0>;
3355 defm : FpUnaryAlias<"fmul", MUL_FST0r, 0>;
3356 defm : FpUnaryAlias<"fmulp", MUL_FPrST0, 0>;
3357 defm : FpUnaryAlias<"fdiv", DIV_FST0r, 0>;
3358 defm : FpUnaryAlias<"fdiv{|r}p", DIVR_FPrST0, 0>;
3359 defm : FpUnaryAlias<"fdivr", DIVR_FST0r, 0>;
3360 defm : FpUnaryAlias<"fdiv{r|}p", DIV_FPrST0, 0>;
3361 defm : FpUnaryAlias<"fcomi", COM_FIr, 0>;
3362 defm : FpUnaryAlias<"fucomi", UCOM_FIr, 0>;
3363 defm : FpUnaryAlias<"fcompi", COM_FIPr, 0>;
3364 defm : FpUnaryAlias<"fucompi", UCOM_FIPr, 0>;
3367 // Handle "f{mulp,addp} $op, %st(0)" the same as "f{mulp,addp} $op", since they
3368 // commute. We also allow fdiv[r]p/fsubrp even though they don't commute,
3369 // solely because gas supports it.
3370 def : InstAlias<"faddp\t{$op, %st|st, $op}", (ADD_FPrST0 RSTi:$op), 0>;
3371 def : InstAlias<"fmulp\t{$op, %st|st, $op}", (MUL_FPrST0 RSTi:$op), 0>;
3372 def : InstAlias<"fsub{|r}p\t{$op, %st|st, $op}", (SUBR_FPrST0 RSTi:$op), 0>;
3373 def : InstAlias<"fsub{r|}p\t{$op, %st|st, $op}", (SUB_FPrST0 RSTi:$op), 0>;
3374 def : InstAlias<"fdiv{|r}p\t{$op, %st|st, $op}", (DIVR_FPrST0 RSTi:$op), 0>;
3375 def : InstAlias<"fdiv{r|}p\t{$op, %st|st, $op}", (DIV_FPrST0 RSTi:$op), 0>;
3377 def : InstAlias<"fnstsw" , (FNSTSW16r), 0>;
3379 // lcall and ljmp aliases. This seems to be an odd mapping in 64-bit mode, but
3380 // this is compatible with what GAS does.
3381 def : InstAlias<"lcall\t$seg, $off", (FARCALL32i i32imm:$off, i16imm:$seg), 0>, Requires<[In32BitMode]>;
3382 def : InstAlias<"ljmp\t$seg, $off", (FARJMP32i i32imm:$off, i16imm:$seg), 0>, Requires<[In32BitMode]>;
3383 def : InstAlias<"lcall\t{*}$dst", (FARCALL32m opaquemem:$dst), 0>, Requires<[Not16BitMode]>;
3384 def : InstAlias<"ljmp\t{*}$dst", (FARJMP32m opaquemem:$dst), 0>, Requires<[Not16BitMode]>;
3385 def : InstAlias<"lcall\t$seg, $off", (FARCALL16i i16imm:$off, i16imm:$seg), 0>, Requires<[In16BitMode]>;
3386 def : InstAlias<"ljmp\t$seg, $off", (FARJMP16i i16imm:$off, i16imm:$seg), 0>, Requires<[In16BitMode]>;
3387 def : InstAlias<"lcall\t{*}$dst", (FARCALL16m opaquemem:$dst), 0>, Requires<[In16BitMode]>;
3388 def : InstAlias<"ljmp\t{*}$dst", (FARJMP16m opaquemem:$dst), 0>, Requires<[In16BitMode]>;
3390 def : InstAlias<"jmp\t{*}$dst", (JMP64m i64mem:$dst), 0, "att">, Requires<[In64BitMode]>;
3391 def : InstAlias<"jmp\t{*}$dst", (JMP32m i32mem:$dst), 0, "att">, Requires<[In32BitMode]>;
3392 def : InstAlias<"jmp\t{*}$dst", (JMP16m i16mem:$dst), 0, "att">, Requires<[In16BitMode]>;
3395 // "imul <imm>, B" is an alias for "imul <imm>, B, B".
3396 def : InstAlias<"imul{w}\t{$imm, $r|$r, $imm}", (IMUL16rri GR16:$r, GR16:$r, i16imm:$imm), 0>;
3397 def : InstAlias<"imul{w}\t{$imm, $r|$r, $imm}", (IMUL16rri8 GR16:$r, GR16:$r, i16i8imm:$imm), 0>;
3398 def : InstAlias<"imul{l}\t{$imm, $r|$r, $imm}", (IMUL32rri GR32:$r, GR32:$r, i32imm:$imm), 0>;
3399 def : InstAlias<"imul{l}\t{$imm, $r|$r, $imm}", (IMUL32rri8 GR32:$r, GR32:$r, i32i8imm:$imm), 0>;
3400 def : InstAlias<"imul{q}\t{$imm, $r|$r, $imm}", (IMUL64rri32 GR64:$r, GR64:$r, i64i32imm:$imm), 0>;
3401 def : InstAlias<"imul{q}\t{$imm, $r|$r, $imm}", (IMUL64rri8 GR64:$r, GR64:$r, i64i8imm:$imm), 0>;
3403 // ins aliases. Accept the mnemonic suffix being omitted because it's implicit
3404 // in the destination.
3405 def : InstAlias<"ins\t{%dx, $dst|$dst, dx}", (INSB dstidx8:$dst), 0, "intel">;
3406 def : InstAlias<"ins\t{%dx, $dst|$dst, dx}", (INSW dstidx16:$dst), 0, "intel">;
3407 def : InstAlias<"ins\t{%dx, $dst|$dst, dx}", (INSL dstidx32:$dst), 0, "intel">;
3409 // outs aliases. Accept the mnemonic suffix being omitted because it's implicit
3411 def : InstAlias<"outs\t{$src, %dx|dx, $src}", (OUTSB srcidx8:$src), 0, "intel">;
3412 def : InstAlias<"outs\t{$src, %dx|dx, $src}", (OUTSW srcidx16:$src), 0, "intel">;
3413 def : InstAlias<"outs\t{$src, %dx|dx, $src}", (OUTSL srcidx32:$src), 0, "intel">;
3415 // inb %dx -> inb %al, %dx
3416 def : InstAlias<"inb\t{%dx|dx}", (IN8rr), 0>;
3417 def : InstAlias<"inw\t{%dx|dx}", (IN16rr), 0>;
3418 def : InstAlias<"inl\t{%dx|dx}", (IN32rr), 0>;
3419 def : InstAlias<"inb\t$port", (IN8ri u8imm:$port), 0>;
3420 def : InstAlias<"inw\t$port", (IN16ri u8imm:$port), 0>;
3421 def : InstAlias<"inl\t$port", (IN32ri u8imm:$port), 0>;
3424 // jmp and call aliases for lcall and ljmp. jmp $42,$5 -> ljmp
3425 def : InstAlias<"call\t$seg, $off", (FARCALL16i i16imm:$off, i16imm:$seg)>, Requires<[In16BitMode]>;
3426 def : InstAlias<"jmp\t$seg, $off", (FARJMP16i i16imm:$off, i16imm:$seg)>, Requires<[In16BitMode]>;
3427 def : InstAlias<"call\t$seg, $off", (FARCALL32i i32imm:$off, i16imm:$seg)>, Requires<[In32BitMode]>;
3428 def : InstAlias<"jmp\t$seg, $off", (FARJMP32i i32imm:$off, i16imm:$seg)>, Requires<[In32BitMode]>;
3429 def : InstAlias<"callw\t$seg, $off", (FARCALL16i i16imm:$off, i16imm:$seg)>, Requires<[Not64BitMode]>;
3430 def : InstAlias<"jmpw\t$seg, $off", (FARJMP16i i16imm:$off, i16imm:$seg)>, Requires<[Not64BitMode]>;
3431 def : InstAlias<"calll\t$seg, $off", (FARCALL32i i32imm:$off, i16imm:$seg)>, Requires<[Not64BitMode]>;
3432 def : InstAlias<"jmpl\t$seg, $off", (FARJMP32i i32imm:$off, i16imm:$seg)>, Requires<[Not64BitMode]>;
3434 // Match 'movq <largeimm>, <reg>' as an alias for movabsq.
3435 def : InstAlias<"mov{q}\t{$imm, $reg|$reg, $imm}", (MOV64ri GR64:$reg, i64imm:$imm), 0>;
3437 // Match 'movd GR64, MMX' as an alias for movq to be compatible with gas,
3438 // which supports this due to an old AMD documentation bug when 64-bit mode was
3440 def : InstAlias<"movd\t{$src, $dst|$dst, $src}",
3441 (MMX_MOVD64to64rr VR64:$dst, GR64:$src), 0>;
3442 def : InstAlias<"movd\t{$src, $dst|$dst, $src}",
3443 (MMX_MOVD64from64rr GR64:$dst, VR64:$src), 0>;
3446 def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX16rr8 GR16:$dst, GR8:$src), 0, "att">;
3447 def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX16rm8 GR16:$dst, i8mem:$src), 0, "att">;
3448 def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX32rr8 GR32:$dst, GR8:$src), 0, "att">;
3449 def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX32rr16 GR32:$dst, GR16:$src), 0, "att">;
3450 def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX64rr8 GR64:$dst, GR8:$src), 0, "att">;
3451 def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX64rr16 GR64:$dst, GR16:$src), 0, "att">;
3452 def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX64rr32 GR64:$dst, GR32:$src), 0, "att">;
3455 def : InstAlias<"movzx\t{$src, $dst|$dst, $src}", (MOVZX16rr8 GR16:$dst, GR8:$src), 0, "att">;
3456 def : InstAlias<"movzx\t{$src, $dst|$dst, $src}", (MOVZX16rm8 GR16:$dst, i8mem:$src), 0, "att">;
3457 def : InstAlias<"movzx\t{$src, $dst|$dst, $src}", (MOVZX32rr8 GR32:$dst, GR8:$src), 0, "att">;
3458 def : InstAlias<"movzx\t{$src, $dst|$dst, $src}", (MOVZX32rr16 GR32:$dst, GR16:$src), 0, "att">;
3459 def : InstAlias<"movzx\t{$src, $dst|$dst, $src}", (MOVZX64rr8 GR64:$dst, GR8:$src), 0, "att">;
3460 def : InstAlias<"movzx\t{$src, $dst|$dst, $src}", (MOVZX64rr16 GR64:$dst, GR16:$src), 0, "att">;
3461 // Note: No GR32->GR64 movzx form.
3463 // outb %dx -> outb %al, %dx
3464 def : InstAlias<"outb\t{%dx|dx}", (OUT8rr), 0>;
3465 def : InstAlias<"outw\t{%dx|dx}", (OUT16rr), 0>;
3466 def : InstAlias<"outl\t{%dx|dx}", (OUT32rr), 0>;
3467 def : InstAlias<"outb\t$port", (OUT8ir u8imm:$port), 0>;
3468 def : InstAlias<"outw\t$port", (OUT16ir u8imm:$port), 0>;
3469 def : InstAlias<"outl\t$port", (OUT32ir u8imm:$port), 0>;
3471 // 'sldt <mem>' can be encoded with either sldtw or sldtq with the same
3472 // effect (both store to a 16-bit mem). Force to sldtw to avoid ambiguity
3473 // errors, since its encoding is the most compact.
3474 def : InstAlias<"sldt $mem", (SLDT16m i16mem:$mem), 0>;
3476 // shld/shrd op,op -> shld op, op, CL
3477 def : InstAlias<"shld{w}\t{$r2, $r1|$r1, $r2}", (SHLD16rrCL GR16:$r1, GR16:$r2), 0>;
3478 def : InstAlias<"shld{l}\t{$r2, $r1|$r1, $r2}", (SHLD32rrCL GR32:$r1, GR32:$r2), 0>;
3479 def : InstAlias<"shld{q}\t{$r2, $r1|$r1, $r2}", (SHLD64rrCL GR64:$r1, GR64:$r2), 0>;
3480 def : InstAlias<"shrd{w}\t{$r2, $r1|$r1, $r2}", (SHRD16rrCL GR16:$r1, GR16:$r2), 0>;
3481 def : InstAlias<"shrd{l}\t{$r2, $r1|$r1, $r2}", (SHRD32rrCL GR32:$r1, GR32:$r2), 0>;
3482 def : InstAlias<"shrd{q}\t{$r2, $r1|$r1, $r2}", (SHRD64rrCL GR64:$r1, GR64:$r2), 0>;
3484 def : InstAlias<"shld{w}\t{$reg, $mem|$mem, $reg}", (SHLD16mrCL i16mem:$mem, GR16:$reg), 0>;
3485 def : InstAlias<"shld{l}\t{$reg, $mem|$mem, $reg}", (SHLD32mrCL i32mem:$mem, GR32:$reg), 0>;
3486 def : InstAlias<"shld{q}\t{$reg, $mem|$mem, $reg}", (SHLD64mrCL i64mem:$mem, GR64:$reg), 0>;
3487 def : InstAlias<"shrd{w}\t{$reg, $mem|$mem, $reg}", (SHRD16mrCL i16mem:$mem, GR16:$reg), 0>;
3488 def : InstAlias<"shrd{l}\t{$reg, $mem|$mem, $reg}", (SHRD32mrCL i32mem:$mem, GR32:$reg), 0>;
3489 def : InstAlias<"shrd{q}\t{$reg, $mem|$mem, $reg}", (SHRD64mrCL i64mem:$mem, GR64:$reg), 0>;
3491 /* FIXME: This is disabled because the asm matcher is currently incapable of
3492 * matching a fixed immediate like $1.
3493 // "shl X, $1" is an alias for "shl X".
3494 multiclass ShiftRotateByOneAlias<string Mnemonic, string Opc> {
3495 def : InstAlias<!strconcat(Mnemonic, "b $op, $$1"),
3496 (!cast<Instruction>(!strconcat(Opc, "8r1")) GR8:$op)>;
3497 def : InstAlias<!strconcat(Mnemonic, "w $op, $$1"),
3498 (!cast<Instruction>(!strconcat(Opc, "16r1")) GR16:$op)>;
3499 def : InstAlias<!strconcat(Mnemonic, "l $op, $$1"),
3500 (!cast<Instruction>(!strconcat(Opc, "32r1")) GR32:$op)>;
3501 def : InstAlias<!strconcat(Mnemonic, "q $op, $$1"),
3502 (!cast<Instruction>(!strconcat(Opc, "64r1")) GR64:$op)>;
3503 def : InstAlias<!strconcat(Mnemonic, "b $op, $$1"),
3504 (!cast<Instruction>(!strconcat(Opc, "8m1")) i8mem:$op)>;
3505 def : InstAlias<!strconcat(Mnemonic, "w $op, $$1"),
3506 (!cast<Instruction>(!strconcat(Opc, "16m1")) i16mem:$op)>;
3507 def : InstAlias<!strconcat(Mnemonic, "l $op, $$1"),
3508 (!cast<Instruction>(!strconcat(Opc, "32m1")) i32mem:$op)>;
3509 def : InstAlias<!strconcat(Mnemonic, "q $op, $$1"),
3510 (!cast<Instruction>(!strconcat(Opc, "64m1")) i64mem:$op)>;
3513 defm : ShiftRotateByOneAlias<"rcl", "RCL">;
3514 defm : ShiftRotateByOneAlias<"rcr", "RCR">;
3515 defm : ShiftRotateByOneAlias<"rol", "ROL">;
3516 defm : ShiftRotateByOneAlias<"ror", "ROR">;
3519 // test: We accept "testX <reg>, <mem>" and "testX <mem>, <reg>" as synonyms.
3520 def : InstAlias<"test{b}\t{$mem, $val|$val, $mem}",
3521 (TEST8mr i8mem :$mem, GR8 :$val), 0>;
3522 def : InstAlias<"test{w}\t{$mem, $val|$val, $mem}",
3523 (TEST16mr i16mem:$mem, GR16:$val), 0>;
3524 def : InstAlias<"test{l}\t{$mem, $val|$val, $mem}",
3525 (TEST32mr i32mem:$mem, GR32:$val), 0>;
3526 def : InstAlias<"test{q}\t{$mem, $val|$val, $mem}",
3527 (TEST64mr i64mem:$mem, GR64:$val), 0>;
3529 // xchg: We accept "xchgX <reg>, <mem>" and "xchgX <mem>, <reg>" as synonyms.
3530 def : InstAlias<"xchg{b}\t{$mem, $val|$val, $mem}",
3531 (XCHG8rm GR8 :$val, i8mem :$mem), 0>;
3532 def : InstAlias<"xchg{w}\t{$mem, $val|$val, $mem}",
3533 (XCHG16rm GR16:$val, i16mem:$mem), 0>;
3534 def : InstAlias<"xchg{l}\t{$mem, $val|$val, $mem}",
3535 (XCHG32rm GR32:$val, i32mem:$mem), 0>;
3536 def : InstAlias<"xchg{q}\t{$mem, $val|$val, $mem}",
3537 (XCHG64rm GR64:$val, i64mem:$mem), 0>;
3539 // xchg: We accept "xchgX <reg>, %eax" and "xchgX %eax, <reg>" as synonyms.
3540 def : InstAlias<"xchg{w}\t{%ax, $src|$src, ax}", (XCHG16ar GR16:$src), 0>;
3541 def : InstAlias<"xchg{l}\t{%eax, $src|$src, eax}", (XCHG32ar GR32:$src), 0>;
3542 def : InstAlias<"xchg{q}\t{%rax, $src|$src, rax}", (XCHG64ar GR64:$src), 0>;
3544 // In 64-bit mode, xchg %eax, %eax can't be encoded with the 0x90 opcode we
3545 // would get by default because it's defined as NOP. But xchg %eax, %eax implies
3546 // implicit zeroing of the upper 32 bits. So alias to the longer encoding.
3547 def : InstAlias<"xchg{l}\t{%eax, %eax|eax, eax}",
3548 (XCHG32rr EAX, EAX), 0>, Requires<[In64BitMode]>;
3550 // xchg %rax, %rax is a nop in x86-64 and can be encoded as such. Without this
3551 // we emit an unneeded REX.w prefix.
3552 def : InstAlias<"xchg{q}\t{%rax, %rax|rax, rax}", (NOOP), 0>;
3554 // These aliases exist to get the parser to prioritize matching 8-bit
3555 // immediate encodings over matching the implicit ax/eax/rax encodings. By
3556 // explicitly mentioning the A register here, these entries will be ordered
3557 // first due to the more explicit immediate type.
3558 def : InstAlias<"adc{w}\t{$imm, %ax|ax, $imm}", (ADC16ri8 AX, i16i8imm:$imm), 0>;
3559 def : InstAlias<"add{w}\t{$imm, %ax|ax, $imm}", (ADD16ri8 AX, i16i8imm:$imm), 0>;
3560 def : InstAlias<"and{w}\t{$imm, %ax|ax, $imm}", (AND16ri8 AX, i16i8imm:$imm), 0>;
3561 def : InstAlias<"cmp{w}\t{$imm, %ax|ax, $imm}", (CMP16ri8 AX, i16i8imm:$imm), 0>;
3562 def : InstAlias<"or{w}\t{$imm, %ax|ax, $imm}", (OR16ri8 AX, i16i8imm:$imm), 0>;
3563 def : InstAlias<"sbb{w}\t{$imm, %ax|ax, $imm}", (SBB16ri8 AX, i16i8imm:$imm), 0>;
3564 def : InstAlias<"sub{w}\t{$imm, %ax|ax, $imm}", (SUB16ri8 AX, i16i8imm:$imm), 0>;
3565 def : InstAlias<"xor{w}\t{$imm, %ax|ax, $imm}", (XOR16ri8 AX, i16i8imm:$imm), 0>;
3567 def : InstAlias<"adc{l}\t{$imm, %eax|eax, $imm}", (ADC32ri8 EAX, i32i8imm:$imm), 0>;
3568 def : InstAlias<"add{l}\t{$imm, %eax|eax, $imm}", (ADD32ri8 EAX, i32i8imm:$imm), 0>;
3569 def : InstAlias<"and{l}\t{$imm, %eax|eax, $imm}", (AND32ri8 EAX, i32i8imm:$imm), 0>;
3570 def : InstAlias<"cmp{l}\t{$imm, %eax|eax, $imm}", (CMP32ri8 EAX, i32i8imm:$imm), 0>;
3571 def : InstAlias<"or{l}\t{$imm, %eax|eax, $imm}", (OR32ri8 EAX, i32i8imm:$imm), 0>;
3572 def : InstAlias<"sbb{l}\t{$imm, %eax|eax, $imm}", (SBB32ri8 EAX, i32i8imm:$imm), 0>;
3573 def : InstAlias<"sub{l}\t{$imm, %eax|eax, $imm}", (SUB32ri8 EAX, i32i8imm:$imm), 0>;
3574 def : InstAlias<"xor{l}\t{$imm, %eax|eax, $imm}", (XOR32ri8 EAX, i32i8imm:$imm), 0>;
3576 def : InstAlias<"adc{q}\t{$imm, %rax|rax, $imm}", (ADC64ri8 RAX, i64i8imm:$imm), 0>;
3577 def : InstAlias<"add{q}\t{$imm, %rax|rax, $imm}", (ADD64ri8 RAX, i64i8imm:$imm), 0>;
3578 def : InstAlias<"and{q}\t{$imm, %rax|rax, $imm}", (AND64ri8 RAX, i64i8imm:$imm), 0>;
3579 def : InstAlias<"cmp{q}\t{$imm, %rax|rax, $imm}", (CMP64ri8 RAX, i64i8imm:$imm), 0>;
3580 def : InstAlias<"or{q}\t{$imm, %rax|rax, $imm}", (OR64ri8 RAX, i64i8imm:$imm), 0>;
3581 def : InstAlias<"sbb{q}\t{$imm, %rax|rax, $imm}", (SBB64ri8 RAX, i64i8imm:$imm), 0>;
3582 def : InstAlias<"sub{q}\t{$imm, %rax|rax, $imm}", (SUB64ri8 RAX, i64i8imm:$imm), 0>;
3583 def : InstAlias<"xor{q}\t{$imm, %rax|rax, $imm}", (XOR64ri8 RAX, i64i8imm:$imm), 0>;