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