1 //===-- X86InstrInfo.td - Main X86 Instruction Definition --*- tablegen -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This file describes the X86 instruction set, defining the instructions, and
10 // properties of the instructions which are needed for code generation, machine
11 // code emission, and analysis.
13 //===----------------------------------------------------------------------===//
15 //===----------------------------------------------------------------------===//
16 // X86 specific DAG Nodes.
19 def SDTX86CmpTest : SDTypeProfile<1, 2, [SDTCisVT<0, i32>, SDTCisSameAs<1, 2>]>;
21 def SDTX86Cmps : SDTypeProfile<1, 3, [SDTCisFP<0>, SDTCisSameAs<1, 2>, SDTCisVT<3, i8>]>;
22 //def SDTX86Cmpss : SDTypeProfile<1, 3, [SDTCisVT<0, f32>, SDTCisSameAs<1, 2>, SDTCisVT<3, i8>]>;
24 def SDTX86Cmov : SDTypeProfile<1, 4,
25 [SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>,
26 SDTCisVT<3, i8>, SDTCisVT<4, i32>]>;
28 // Unary and binary operator instructions that set EFLAGS as a side-effect.
29 def SDTUnaryArithWithFlags : SDTypeProfile<2, 1,
31 SDTCisInt<0>, SDTCisVT<1, i32>]>;
33 def SDTBinaryArithWithFlags : SDTypeProfile<2, 2,
36 SDTCisInt<0>, SDTCisVT<1, i32>]>;
38 // SDTBinaryArithWithFlagsInOut - RES1, EFLAGS = op LHS, RHS, EFLAGS
39 def SDTBinaryArithWithFlagsInOut : SDTypeProfile<2, 3,
45 // RES1, RES2, FLAGS = op LHS, RHS
46 def SDT2ResultBinaryArithWithFlags : SDTypeProfile<3, 2,
50 SDTCisInt<0>, SDTCisVT<1, i32>]>;
51 def SDTX86BrCond : SDTypeProfile<0, 3,
52 [SDTCisVT<0, OtherVT>,
53 SDTCisVT<1, i8>, SDTCisVT<2, i32>]>;
55 def SDTX86SetCC : SDTypeProfile<1, 2,
57 SDTCisVT<1, i8>, SDTCisVT<2, i32>]>;
58 def SDTX86SetCC_C : SDTypeProfile<1, 2,
60 SDTCisVT<1, i8>, SDTCisVT<2, i32>]>;
62 def SDTX86sahf : SDTypeProfile<1, 1, [SDTCisVT<0, i32>, SDTCisVT<1, i8>]>;
64 def SDTX86rdrand : SDTypeProfile<2, 0, [SDTCisInt<0>, SDTCisVT<1, i32>]>;
66 def SDTX86rdpkru : SDTypeProfile<1, 1, [SDTCisVT<0, i32>, SDTCisVT<1, i32>]>;
67 def SDTX86wrpkru : SDTypeProfile<0, 3, [SDTCisVT<0, i32>, SDTCisVT<1, i32>,
70 def SDTX86cas : SDTypeProfile<0, 3, [SDTCisPtrTy<0>, SDTCisInt<1>,
72 def SDTX86caspair : SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>;
73 def SDTX86caspairSaveEbx8 : SDTypeProfile<1, 3,
74 [SDTCisVT<0, i32>, SDTCisPtrTy<1>,
75 SDTCisVT<2, i32>, SDTCisVT<3, i32>]>;
76 def SDTX86caspairSaveRbx16 : SDTypeProfile<1, 3,
77 [SDTCisVT<0, i64>, SDTCisPtrTy<1>,
78 SDTCisVT<2, i64>, SDTCisVT<3, i64>]>;
80 def SDTLockBinaryArithWithFlags : SDTypeProfile<1, 2, [SDTCisVT<0, i32>,
84 def SDTLockUnaryArithWithFlags : SDTypeProfile<1, 1, [SDTCisVT<0, i32>,
87 def SDTX86Ret : SDTypeProfile<0, -1, [SDTCisVT<0, i32>]>;
89 def SDT_X86CallSeqStart : SDCallSeqStart<[SDTCisVT<0, i32>,
91 def SDT_X86CallSeqEnd : SDCallSeqEnd<[SDTCisVT<0, i32>,
94 def SDT_X86Call : SDTypeProfile<0, -1, [SDTCisVT<0, iPTR>]>;
96 def SDT_X86NtBrind : SDTypeProfile<0, -1, [SDTCisVT<0, iPTR>]>;
98 def SDT_X86VASTART_SAVE_XMM_REGS : SDTypeProfile<0, -1, [SDTCisVT<0, i8>,
102 def SDT_X86VAARG_64 : SDTypeProfile<1, -1, [SDTCisPtrTy<0>,
108 def SDTX86RepStr : SDTypeProfile<0, 1, [SDTCisVT<0, OtherVT>]>;
110 def SDTX86Void : SDTypeProfile<0, 0, []>;
112 def SDTX86Wrapper : SDTypeProfile<1, 1, [SDTCisSameAs<0, 1>, SDTCisPtrTy<0>]>;
114 def SDT_X86TLSADDR : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
116 def SDT_X86TLSBASEADDR : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
118 def SDT_X86TLSCALL : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
120 def SDT_X86WIN_ALLOCA : SDTypeProfile<0, 1, [SDTCisVT<0, iPTR>]>;
122 def SDT_X86SEG_ALLOCA : SDTypeProfile<1, 1, [SDTCisVT<0, iPTR>, SDTCisVT<1, iPTR>]>;
124 def SDT_X86EHRET : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
126 def SDT_X86TCRET : SDTypeProfile<0, 2, [SDTCisPtrTy<0>, SDTCisVT<1, i32>]>;
128 def SDT_X86MEMBARRIER : SDTypeProfile<0, 0, []>;
130 def SDT_X86ENQCMD : SDTypeProfile<1, 2, [SDTCisVT<0, i32>,
131 SDTCisPtrTy<1>, SDTCisSameAs<1, 2>]>;
133 def X86MemBarrier : SDNode<"X86ISD::MEMBARRIER", SDT_X86MEMBARRIER,
134 [SDNPHasChain,SDNPSideEffect]>;
135 def X86MFence : SDNode<"X86ISD::MFENCE", SDT_X86MEMBARRIER,
139 def X86bsf : SDNode<"X86ISD::BSF", SDTUnaryArithWithFlags>;
140 def X86bsr : SDNode<"X86ISD::BSR", SDTUnaryArithWithFlags>;
141 def X86shld : SDNode<"X86ISD::SHLD", SDTIntShiftDOp>;
142 def X86shrd : SDNode<"X86ISD::SHRD", SDTIntShiftDOp>;
144 def X86cmp : SDNode<"X86ISD::CMP" , SDTX86CmpTest>;
145 def X86bt : SDNode<"X86ISD::BT", SDTX86CmpTest>;
147 def X86cmov : SDNode<"X86ISD::CMOV", SDTX86Cmov>;
148 def X86brcond : SDNode<"X86ISD::BRCOND", SDTX86BrCond,
150 def X86setcc : SDNode<"X86ISD::SETCC", SDTX86SetCC>;
151 def X86setcc_c : SDNode<"X86ISD::SETCC_CARRY", SDTX86SetCC_C>;
153 def X86sahf : SDNode<"X86ISD::SAHF", SDTX86sahf>;
155 def X86rdrand : SDNode<"X86ISD::RDRAND", SDTX86rdrand,
156 [SDNPHasChain, SDNPSideEffect]>;
158 def X86rdseed : SDNode<"X86ISD::RDSEED", SDTX86rdrand,
159 [SDNPHasChain, SDNPSideEffect]>;
161 def X86rdpkru : SDNode<"X86ISD::RDPKRU", SDTX86rdpkru,
162 [SDNPHasChain, SDNPSideEffect]>;
163 def X86wrpkru : SDNode<"X86ISD::WRPKRU", SDTX86wrpkru,
164 [SDNPHasChain, SDNPSideEffect]>;
166 def X86cas : SDNode<"X86ISD::LCMPXCHG_DAG", SDTX86cas,
167 [SDNPHasChain, SDNPInGlue, SDNPOutGlue, SDNPMayStore,
168 SDNPMayLoad, SDNPMemOperand]>;
169 def X86cas8 : SDNode<"X86ISD::LCMPXCHG8_DAG", SDTX86caspair,
170 [SDNPHasChain, SDNPInGlue, SDNPOutGlue, SDNPMayStore,
171 SDNPMayLoad, SDNPMemOperand]>;
172 def X86cas16 : SDNode<"X86ISD::LCMPXCHG16_DAG", SDTX86caspair,
173 [SDNPHasChain, SDNPInGlue, SDNPOutGlue, SDNPMayStore,
174 SDNPMayLoad, SDNPMemOperand]>;
175 def X86cas8save_ebx : SDNode<"X86ISD::LCMPXCHG8_SAVE_EBX_DAG",
176 SDTX86caspairSaveEbx8,
177 [SDNPHasChain, SDNPInGlue, SDNPOutGlue,
178 SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
179 def X86cas16save_rbx : SDNode<"X86ISD::LCMPXCHG16_SAVE_RBX_DAG",
180 SDTX86caspairSaveRbx16,
181 [SDNPHasChain, SDNPInGlue, SDNPOutGlue,
182 SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
184 def X86retflag : SDNode<"X86ISD::RET_FLAG", SDTX86Ret,
185 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
186 def X86iret : SDNode<"X86ISD::IRET", SDTX86Ret,
187 [SDNPHasChain, SDNPOptInGlue]>;
189 def X86vastart_save_xmm_regs :
190 SDNode<"X86ISD::VASTART_SAVE_XMM_REGS",
191 SDT_X86VASTART_SAVE_XMM_REGS,
192 [SDNPHasChain, SDNPVariadic]>;
194 SDNode<"X86ISD::VAARG_64", SDT_X86VAARG_64,
195 [SDNPHasChain, SDNPMayLoad, SDNPMayStore,
197 def X86callseq_start :
198 SDNode<"ISD::CALLSEQ_START", SDT_X86CallSeqStart,
199 [SDNPHasChain, SDNPOutGlue]>;
201 SDNode<"ISD::CALLSEQ_END", SDT_X86CallSeqEnd,
202 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
204 def X86call : SDNode<"X86ISD::CALL", SDT_X86Call,
205 [SDNPHasChain, SDNPOutGlue, SDNPOptInGlue,
208 def X86NoTrackCall : SDNode<"X86ISD::NT_CALL", SDT_X86Call,
209 [SDNPHasChain, SDNPOutGlue, SDNPOptInGlue,
211 def X86NoTrackBrind : SDNode<"X86ISD::NT_BRIND", SDT_X86NtBrind,
214 def X86rep_stos: SDNode<"X86ISD::REP_STOS", SDTX86RepStr,
215 [SDNPHasChain, SDNPInGlue, SDNPOutGlue, SDNPMayStore]>;
216 def X86rep_movs: SDNode<"X86ISD::REP_MOVS", SDTX86RepStr,
217 [SDNPHasChain, SDNPInGlue, SDNPOutGlue, SDNPMayStore,
220 def X86Wrapper : SDNode<"X86ISD::Wrapper", SDTX86Wrapper>;
221 def X86WrapperRIP : SDNode<"X86ISD::WrapperRIP", SDTX86Wrapper>;
223 def X86RecoverFrameAlloc : SDNode<"ISD::LOCAL_RECOVER",
224 SDTypeProfile<1, 1, [SDTCisSameAs<0, 1>,
227 def X86tlsaddr : SDNode<"X86ISD::TLSADDR", SDT_X86TLSADDR,
228 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
230 def X86tlsbaseaddr : SDNode<"X86ISD::TLSBASEADDR", SDT_X86TLSBASEADDR,
231 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
233 def X86ehret : SDNode<"X86ISD::EH_RETURN", SDT_X86EHRET,
236 def X86eh_sjlj_setjmp : SDNode<"X86ISD::EH_SJLJ_SETJMP",
237 SDTypeProfile<1, 1, [SDTCisInt<0>,
239 [SDNPHasChain, SDNPSideEffect]>;
240 def X86eh_sjlj_longjmp : SDNode<"X86ISD::EH_SJLJ_LONGJMP",
241 SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>,
242 [SDNPHasChain, SDNPSideEffect]>;
243 def X86eh_sjlj_setup_dispatch : SDNode<"X86ISD::EH_SJLJ_SETUP_DISPATCH",
244 SDTypeProfile<0, 0, []>,
245 [SDNPHasChain, SDNPSideEffect]>;
247 def X86tcret : SDNode<"X86ISD::TC_RETURN", SDT_X86TCRET,
248 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
250 def X86add_flag : SDNode<"X86ISD::ADD", SDTBinaryArithWithFlags,
252 def X86sub_flag : SDNode<"X86ISD::SUB", SDTBinaryArithWithFlags>;
253 def X86smul_flag : SDNode<"X86ISD::SMUL", SDTBinaryArithWithFlags,
255 def X86umul_flag : SDNode<"X86ISD::UMUL", SDT2ResultBinaryArithWithFlags,
257 def X86adc_flag : SDNode<"X86ISD::ADC", SDTBinaryArithWithFlagsInOut>;
258 def X86sbb_flag : SDNode<"X86ISD::SBB", SDTBinaryArithWithFlagsInOut>;
260 def X86or_flag : SDNode<"X86ISD::OR", SDTBinaryArithWithFlags,
262 def X86xor_flag : SDNode<"X86ISD::XOR", SDTBinaryArithWithFlags,
264 def X86and_flag : SDNode<"X86ISD::AND", SDTBinaryArithWithFlags,
267 def X86lock_add : SDNode<"X86ISD::LADD", SDTLockBinaryArithWithFlags,
268 [SDNPHasChain, SDNPMayStore, SDNPMayLoad,
270 def X86lock_sub : SDNode<"X86ISD::LSUB", SDTLockBinaryArithWithFlags,
271 [SDNPHasChain, SDNPMayStore, SDNPMayLoad,
273 def X86lock_or : SDNode<"X86ISD::LOR", SDTLockBinaryArithWithFlags,
274 [SDNPHasChain, SDNPMayStore, SDNPMayLoad,
276 def X86lock_xor : SDNode<"X86ISD::LXOR", SDTLockBinaryArithWithFlags,
277 [SDNPHasChain, SDNPMayStore, SDNPMayLoad,
279 def X86lock_and : SDNode<"X86ISD::LAND", SDTLockBinaryArithWithFlags,
280 [SDNPHasChain, SDNPMayStore, SDNPMayLoad,
283 def X86bextr : SDNode<"X86ISD::BEXTR", SDTIntBinOp>;
285 def X86bzhi : SDNode<"X86ISD::BZHI", SDTIntBinOp>;
287 def X86mul_imm : SDNode<"X86ISD::MUL_IMM", SDTIntBinOp>;
289 def X86WinAlloca : SDNode<"X86ISD::WIN_ALLOCA", SDT_X86WIN_ALLOCA,
290 [SDNPHasChain, SDNPOutGlue]>;
292 def X86SegAlloca : SDNode<"X86ISD::SEG_ALLOCA", SDT_X86SEG_ALLOCA,
295 def X86TLSCall : SDNode<"X86ISD::TLSCALL", SDT_X86TLSCALL,
296 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
298 def X86lwpins : SDNode<"X86ISD::LWPINS",
299 SDTypeProfile<1, 3, [SDTCisVT<0, i32>, SDTCisInt<1>,
300 SDTCisVT<2, i32>, SDTCisVT<3, i32>]>,
301 [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPSideEffect]>;
303 def X86umwait : SDNode<"X86ISD::UMWAIT",
304 SDTypeProfile<1, 3, [SDTCisVT<0, i32>, SDTCisInt<1>,
305 SDTCisVT<2, i32>, SDTCisVT<3, i32>]>,
306 [SDNPHasChain, SDNPSideEffect]>;
308 def X86tpause : SDNode<"X86ISD::TPAUSE",
309 SDTypeProfile<1, 3, [SDTCisVT<0, i32>, SDTCisInt<1>,
310 SDTCisVT<2, i32>, SDTCisVT<3, i32>]>,
311 [SDNPHasChain, SDNPSideEffect]>;
313 def X86enqcmd : SDNode<"X86ISD::ENQCMD", SDT_X86ENQCMD,
314 [SDNPHasChain, SDNPSideEffect]>;
315 def X86enqcmds : SDNode<"X86ISD::ENQCMDS", SDT_X86ENQCMD,
316 [SDNPHasChain, SDNPSideEffect]>;
318 //===----------------------------------------------------------------------===//
319 // X86 Operand Definitions.
322 // A version of ptr_rc which excludes SP, ESP, and RSP. This is used for
323 // the index operand of an address, to conform to x86 encoding restrictions.
324 def ptr_rc_nosp : PointerLikeRegClass<1>;
326 // *mem - Operand definitions for the funky X86 addressing mode operands.
328 def X86MemAsmOperand : AsmOperandClass {
331 let RenderMethod = "addMemOperands", SuperClasses = [X86MemAsmOperand] in {
332 def X86Mem8AsmOperand : AsmOperandClass { let Name = "Mem8"; }
333 def X86Mem16AsmOperand : AsmOperandClass { let Name = "Mem16"; }
334 def X86Mem32AsmOperand : AsmOperandClass { let Name = "Mem32"; }
335 def X86Mem64AsmOperand : AsmOperandClass { let Name = "Mem64"; }
336 def X86Mem80AsmOperand : AsmOperandClass { let Name = "Mem80"; }
337 def X86Mem128AsmOperand : AsmOperandClass { let Name = "Mem128"; }
338 def X86Mem256AsmOperand : AsmOperandClass { let Name = "Mem256"; }
339 def X86Mem512AsmOperand : AsmOperandClass { let Name = "Mem512"; }
340 // Gather mem operands
341 def X86Mem64_RC128Operand : AsmOperandClass { let Name = "Mem64_RC128"; }
342 def X86Mem128_RC128Operand : AsmOperandClass { let Name = "Mem128_RC128"; }
343 def X86Mem256_RC128Operand : AsmOperandClass { let Name = "Mem256_RC128"; }
344 def X86Mem128_RC256Operand : AsmOperandClass { let Name = "Mem128_RC256"; }
345 def X86Mem256_RC256Operand : AsmOperandClass { let Name = "Mem256_RC256"; }
347 def X86Mem64_RC128XOperand : AsmOperandClass { let Name = "Mem64_RC128X"; }
348 def X86Mem128_RC128XOperand : AsmOperandClass { let Name = "Mem128_RC128X"; }
349 def X86Mem256_RC128XOperand : AsmOperandClass { let Name = "Mem256_RC128X"; }
350 def X86Mem128_RC256XOperand : AsmOperandClass { let Name = "Mem128_RC256X"; }
351 def X86Mem256_RC256XOperand : AsmOperandClass { let Name = "Mem256_RC256X"; }
352 def X86Mem512_RC256XOperand : AsmOperandClass { let Name = "Mem512_RC256X"; }
353 def X86Mem256_RC512Operand : AsmOperandClass { let Name = "Mem256_RC512"; }
354 def X86Mem512_RC512Operand : AsmOperandClass { let Name = "Mem512_RC512"; }
357 def X86AbsMemAsmOperand : AsmOperandClass {
359 let SuperClasses = [X86MemAsmOperand];
362 class X86MemOperand<string printMethod,
363 AsmOperandClass parserMatchClass = X86MemAsmOperand> : Operand<iPTR> {
364 let PrintMethod = printMethod;
365 let MIOperandInfo = (ops ptr_rc, i8imm, ptr_rc_nosp, i32imm, SEGMENT_REG);
366 let ParserMatchClass = parserMatchClass;
367 let OperandType = "OPERAND_MEMORY";
370 // Gather mem operands
371 class X86VMemOperand<RegisterClass RC, string printMethod,
372 AsmOperandClass parserMatchClass>
373 : X86MemOperand<printMethod, parserMatchClass> {
374 let MIOperandInfo = (ops ptr_rc, i8imm, RC, i32imm, SEGMENT_REG);
377 def anymem : X86MemOperand<"printanymem">;
379 // FIXME: Right now we allow any size during parsing, but we might want to
380 // restrict to only unsized memory.
381 def opaquemem : X86MemOperand<"printopaquemem">;
383 def i8mem : X86MemOperand<"printbytemem", X86Mem8AsmOperand>;
384 def i16mem : X86MemOperand<"printwordmem", X86Mem16AsmOperand>;
385 def i32mem : X86MemOperand<"printdwordmem", X86Mem32AsmOperand>;
386 def i64mem : X86MemOperand<"printqwordmem", X86Mem64AsmOperand>;
387 def i128mem : X86MemOperand<"printxmmwordmem", X86Mem128AsmOperand>;
388 def i256mem : X86MemOperand<"printymmwordmem", X86Mem256AsmOperand>;
389 def i512mem : X86MemOperand<"printzmmwordmem", X86Mem512AsmOperand>;
390 def f32mem : X86MemOperand<"printdwordmem", X86Mem32AsmOperand>;
391 def f64mem : X86MemOperand<"printqwordmem", X86Mem64AsmOperand>;
392 def f80mem : X86MemOperand<"printtbytemem", X86Mem80AsmOperand>;
393 def f128mem : X86MemOperand<"printxmmwordmem", X86Mem128AsmOperand>;
394 def f256mem : X86MemOperand<"printymmwordmem", X86Mem256AsmOperand>;
395 def f512mem : X86MemOperand<"printzmmwordmem", X86Mem512AsmOperand>;
397 // Gather mem operands
398 def vx64mem : X86VMemOperand<VR128, "printqwordmem", X86Mem64_RC128Operand>;
399 def vx128mem : X86VMemOperand<VR128, "printxmmwordmem", X86Mem128_RC128Operand>;
400 def vx256mem : X86VMemOperand<VR128, "printymmwordmem", X86Mem256_RC128Operand>;
401 def vy128mem : X86VMemOperand<VR256, "printxmmwordmem", X86Mem128_RC256Operand>;
402 def vy256mem : X86VMemOperand<VR256, "printymmwordmem", X86Mem256_RC256Operand>;
404 def vx64xmem : X86VMemOperand<VR128X, "printqwordmem", X86Mem64_RC128XOperand>;
405 def vx128xmem : X86VMemOperand<VR128X, "printxmmwordmem", X86Mem128_RC128XOperand>;
406 def vx256xmem : X86VMemOperand<VR128X, "printymmwordmem", X86Mem256_RC128XOperand>;
407 def vy128xmem : X86VMemOperand<VR256X, "printxmmwordmem", X86Mem128_RC256XOperand>;
408 def vy256xmem : X86VMemOperand<VR256X, "printymmwordmem", X86Mem256_RC256XOperand>;
409 def vy512xmem : X86VMemOperand<VR256X, "printzmmwordmem", X86Mem512_RC256XOperand>;
410 def vz256mem : X86VMemOperand<VR512, "printymmwordmem", X86Mem256_RC512Operand>;
411 def vz512mem : X86VMemOperand<VR512, "printzmmwordmem", X86Mem512_RC512Operand>;
413 // A version of i8mem for use on x86-64 and x32 that uses a NOREX GPR instead
414 // of a plain GPR, so that it doesn't potentially require a REX prefix.
415 def ptr_rc_norex : PointerLikeRegClass<2>;
416 def ptr_rc_norex_nosp : PointerLikeRegClass<3>;
418 def i8mem_NOREX : Operand<iPTR> {
419 let PrintMethod = "printbytemem";
420 let MIOperandInfo = (ops ptr_rc_norex, i8imm, ptr_rc_norex_nosp, i32imm,
422 let ParserMatchClass = X86Mem8AsmOperand;
423 let OperandType = "OPERAND_MEMORY";
426 // GPRs available for tailcall.
427 // It represents GR32_TC, GR64_TC or GR64_TCW64.
428 def ptr_rc_tailcall : PointerLikeRegClass<4>;
430 // Special i32mem for addresses of load folding tail calls. These are not
431 // allowed to use callee-saved registers since they must be scheduled
432 // after callee-saved register are popped.
433 def i32mem_TC : Operand<i32> {
434 let PrintMethod = "printdwordmem";
435 let MIOperandInfo = (ops ptr_rc_tailcall, i8imm, ptr_rc_tailcall,
436 i32imm, SEGMENT_REG);
437 let ParserMatchClass = X86Mem32AsmOperand;
438 let OperandType = "OPERAND_MEMORY";
441 // Special i64mem for addresses of load folding tail calls. These are not
442 // allowed to use callee-saved registers since they must be scheduled
443 // after callee-saved register are popped.
444 def i64mem_TC : Operand<i64> {
445 let PrintMethod = "printqwordmem";
446 let MIOperandInfo = (ops ptr_rc_tailcall, i8imm,
447 ptr_rc_tailcall, i32imm, SEGMENT_REG);
448 let ParserMatchClass = X86Mem64AsmOperand;
449 let OperandType = "OPERAND_MEMORY";
452 let OperandType = "OPERAND_PCREL",
453 ParserMatchClass = X86AbsMemAsmOperand,
454 PrintMethod = "printPCRelImm" in {
455 def i32imm_pcrel : Operand<i32>;
456 def i16imm_pcrel : Operand<i16>;
458 // Branch targets have OtherVT type and print as pc-relative values.
459 def brtarget : Operand<OtherVT>;
460 def brtarget8 : Operand<OtherVT>;
464 // Special parser to detect 16-bit mode to select 16-bit displacement.
465 def X86AbsMem16AsmOperand : AsmOperandClass {
466 let Name = "AbsMem16";
467 let RenderMethod = "addAbsMemOperands";
468 let SuperClasses = [X86AbsMemAsmOperand];
471 // Branch targets have OtherVT type and print as pc-relative values.
472 let OperandType = "OPERAND_PCREL",
473 PrintMethod = "printPCRelImm" in {
474 let ParserMatchClass = X86AbsMem16AsmOperand in
475 def brtarget16 : Operand<OtherVT>;
476 let ParserMatchClass = X86AbsMemAsmOperand in
477 def brtarget32 : Operand<OtherVT>;
480 let RenderMethod = "addSrcIdxOperands" in {
481 def X86SrcIdx8Operand : AsmOperandClass {
482 let Name = "SrcIdx8";
483 let SuperClasses = [X86Mem8AsmOperand];
485 def X86SrcIdx16Operand : AsmOperandClass {
486 let Name = "SrcIdx16";
487 let SuperClasses = [X86Mem16AsmOperand];
489 def X86SrcIdx32Operand : AsmOperandClass {
490 let Name = "SrcIdx32";
491 let SuperClasses = [X86Mem32AsmOperand];
493 def X86SrcIdx64Operand : AsmOperandClass {
494 let Name = "SrcIdx64";
495 let SuperClasses = [X86Mem64AsmOperand];
497 } // RenderMethod = "addSrcIdxOperands"
499 let RenderMethod = "addDstIdxOperands" in {
500 def X86DstIdx8Operand : AsmOperandClass {
501 let Name = "DstIdx8";
502 let SuperClasses = [X86Mem8AsmOperand];
504 def X86DstIdx16Operand : AsmOperandClass {
505 let Name = "DstIdx16";
506 let SuperClasses = [X86Mem16AsmOperand];
508 def X86DstIdx32Operand : AsmOperandClass {
509 let Name = "DstIdx32";
510 let SuperClasses = [X86Mem32AsmOperand];
512 def X86DstIdx64Operand : AsmOperandClass {
513 let Name = "DstIdx64";
514 let SuperClasses = [X86Mem64AsmOperand];
516 } // RenderMethod = "addDstIdxOperands"
518 let RenderMethod = "addMemOffsOperands" in {
519 def X86MemOffs16_8AsmOperand : AsmOperandClass {
520 let Name = "MemOffs16_8";
521 let SuperClasses = [X86Mem8AsmOperand];
523 def X86MemOffs16_16AsmOperand : AsmOperandClass {
524 let Name = "MemOffs16_16";
525 let SuperClasses = [X86Mem16AsmOperand];
527 def X86MemOffs16_32AsmOperand : AsmOperandClass {
528 let Name = "MemOffs16_32";
529 let SuperClasses = [X86Mem32AsmOperand];
531 def X86MemOffs32_8AsmOperand : AsmOperandClass {
532 let Name = "MemOffs32_8";
533 let SuperClasses = [X86Mem8AsmOperand];
535 def X86MemOffs32_16AsmOperand : AsmOperandClass {
536 let Name = "MemOffs32_16";
537 let SuperClasses = [X86Mem16AsmOperand];
539 def X86MemOffs32_32AsmOperand : AsmOperandClass {
540 let Name = "MemOffs32_32";
541 let SuperClasses = [X86Mem32AsmOperand];
543 def X86MemOffs32_64AsmOperand : AsmOperandClass {
544 let Name = "MemOffs32_64";
545 let SuperClasses = [X86Mem64AsmOperand];
547 def X86MemOffs64_8AsmOperand : AsmOperandClass {
548 let Name = "MemOffs64_8";
549 let SuperClasses = [X86Mem8AsmOperand];
551 def X86MemOffs64_16AsmOperand : AsmOperandClass {
552 let Name = "MemOffs64_16";
553 let SuperClasses = [X86Mem16AsmOperand];
555 def X86MemOffs64_32AsmOperand : AsmOperandClass {
556 let Name = "MemOffs64_32";
557 let SuperClasses = [X86Mem32AsmOperand];
559 def X86MemOffs64_64AsmOperand : AsmOperandClass {
560 let Name = "MemOffs64_64";
561 let SuperClasses = [X86Mem64AsmOperand];
563 } // RenderMethod = "addMemOffsOperands"
565 class X86SrcIdxOperand<string printMethod, AsmOperandClass parserMatchClass>
566 : X86MemOperand<printMethod, parserMatchClass> {
567 let MIOperandInfo = (ops ptr_rc, SEGMENT_REG);
570 class X86DstIdxOperand<string printMethod, AsmOperandClass parserMatchClass>
571 : X86MemOperand<printMethod, parserMatchClass> {
572 let MIOperandInfo = (ops ptr_rc);
575 def srcidx8 : X86SrcIdxOperand<"printSrcIdx8", X86SrcIdx8Operand>;
576 def srcidx16 : X86SrcIdxOperand<"printSrcIdx16", X86SrcIdx16Operand>;
577 def srcidx32 : X86SrcIdxOperand<"printSrcIdx32", X86SrcIdx32Operand>;
578 def srcidx64 : X86SrcIdxOperand<"printSrcIdx64", X86SrcIdx64Operand>;
579 def dstidx8 : X86DstIdxOperand<"printDstIdx8", X86DstIdx8Operand>;
580 def dstidx16 : X86DstIdxOperand<"printDstIdx16", X86DstIdx16Operand>;
581 def dstidx32 : X86DstIdxOperand<"printDstIdx32", X86DstIdx32Operand>;
582 def dstidx64 : X86DstIdxOperand<"printDstIdx64", X86DstIdx64Operand>;
584 class X86MemOffsOperand<Operand immOperand, string printMethod,
585 AsmOperandClass parserMatchClass>
586 : X86MemOperand<printMethod, parserMatchClass> {
587 let MIOperandInfo = (ops immOperand, SEGMENT_REG);
590 def offset16_8 : X86MemOffsOperand<i16imm, "printMemOffs8",
591 X86MemOffs16_8AsmOperand>;
592 def offset16_16 : X86MemOffsOperand<i16imm, "printMemOffs16",
593 X86MemOffs16_16AsmOperand>;
594 def offset16_32 : X86MemOffsOperand<i16imm, "printMemOffs32",
595 X86MemOffs16_32AsmOperand>;
596 def offset32_8 : X86MemOffsOperand<i32imm, "printMemOffs8",
597 X86MemOffs32_8AsmOperand>;
598 def offset32_16 : X86MemOffsOperand<i32imm, "printMemOffs16",
599 X86MemOffs32_16AsmOperand>;
600 def offset32_32 : X86MemOffsOperand<i32imm, "printMemOffs32",
601 X86MemOffs32_32AsmOperand>;
602 def offset32_64 : X86MemOffsOperand<i32imm, "printMemOffs64",
603 X86MemOffs32_64AsmOperand>;
604 def offset64_8 : X86MemOffsOperand<i64imm, "printMemOffs8",
605 X86MemOffs64_8AsmOperand>;
606 def offset64_16 : X86MemOffsOperand<i64imm, "printMemOffs16",
607 X86MemOffs64_16AsmOperand>;
608 def offset64_32 : X86MemOffsOperand<i64imm, "printMemOffs32",
609 X86MemOffs64_32AsmOperand>;
610 def offset64_64 : X86MemOffsOperand<i64imm, "printMemOffs64",
611 X86MemOffs64_64AsmOperand>;
613 def ccode : Operand<i8> {
614 let PrintMethod = "printCondCode";
615 let OperandNamespace = "X86";
616 let OperandType = "OPERAND_COND_CODE";
619 class ImmSExtAsmOperandClass : AsmOperandClass {
620 let SuperClasses = [ImmAsmOperand];
621 let RenderMethod = "addImmOperands";
624 def X86GR32orGR64AsmOperand : AsmOperandClass {
625 let Name = "GR32orGR64";
628 def GR32orGR64 : RegisterOperand<GR32> {
629 let ParserMatchClass = X86GR32orGR64AsmOperand;
631 def AVX512RCOperand : AsmOperandClass {
632 let Name = "AVX512RC";
634 def AVX512RC : Operand<i32> {
635 let PrintMethod = "printRoundingControl";
636 let OperandNamespace = "X86";
637 let OperandType = "OPERAND_ROUNDING_CONTROL";
638 let ParserMatchClass = AVX512RCOperand;
641 // Sign-extended immediate classes. We don't need to define the full lattice
642 // here because there is no instruction with an ambiguity between ImmSExti64i32
645 // The strange ranges come from the fact that the assembler always works with
646 // 64-bit immediates, but for a 16-bit target value we want to accept both "-1"
647 // (which will be a -1ULL), and "0xFF" (-1 in 16-bits).
650 // [0xFFFFFFFF80000000, 0xFFFFFFFFFFFFFFFF]
651 def ImmSExti64i32AsmOperand : ImmSExtAsmOperandClass {
652 let Name = "ImmSExti64i32";
655 // [0, 0x0000007F] | [0x000000000000FF80, 0x000000000000FFFF] |
656 // [0xFFFFFFFFFFFFFF80, 0xFFFFFFFFFFFFFFFF]
657 def ImmSExti16i8AsmOperand : ImmSExtAsmOperandClass {
658 let Name = "ImmSExti16i8";
659 let SuperClasses = [ImmSExti64i32AsmOperand];
662 // [0, 0x0000007F] | [0x00000000FFFFFF80, 0x00000000FFFFFFFF] |
663 // [0xFFFFFFFFFFFFFF80, 0xFFFFFFFFFFFFFFFF]
664 def ImmSExti32i8AsmOperand : ImmSExtAsmOperandClass {
665 let Name = "ImmSExti32i8";
669 // [0xFFFFFFFFFFFFFF80, 0xFFFFFFFFFFFFFFFF]
670 def ImmSExti64i8AsmOperand : ImmSExtAsmOperandClass {
671 let Name = "ImmSExti64i8";
672 let SuperClasses = [ImmSExti16i8AsmOperand, ImmSExti32i8AsmOperand,
673 ImmSExti64i32AsmOperand];
676 // 4-bit immediate used by some XOP instructions
678 def ImmUnsignedi4AsmOperand : AsmOperandClass {
679 let Name = "ImmUnsignedi4";
680 let RenderMethod = "addImmOperands";
681 let DiagnosticType = "InvalidImmUnsignedi4";
684 // Unsigned immediate used by SSE/AVX instructions
686 // [0xFFFFFFFFFFFFFF80, 0xFFFFFFFFFFFFFFFF]
687 def ImmUnsignedi8AsmOperand : AsmOperandClass {
688 let Name = "ImmUnsignedi8";
689 let RenderMethod = "addImmOperands";
692 // A couple of more descriptive operand definitions.
693 // 16-bits but only 8 bits are significant.
694 def i16i8imm : Operand<i16> {
695 let ParserMatchClass = ImmSExti16i8AsmOperand;
696 let OperandType = "OPERAND_IMMEDIATE";
698 // 32-bits but only 8 bits are significant.
699 def i32i8imm : Operand<i32> {
700 let ParserMatchClass = ImmSExti32i8AsmOperand;
701 let OperandType = "OPERAND_IMMEDIATE";
704 // 64-bits but only 32 bits are significant.
705 def i64i32imm : Operand<i64> {
706 let ParserMatchClass = ImmSExti64i32AsmOperand;
707 let OperandType = "OPERAND_IMMEDIATE";
710 // 64-bits but only 8 bits are significant.
711 def i64i8imm : Operand<i64> {
712 let ParserMatchClass = ImmSExti64i8AsmOperand;
713 let OperandType = "OPERAND_IMMEDIATE";
716 // Unsigned 4-bit immediate used by some XOP instructions.
717 def u4imm : Operand<i8> {
718 let PrintMethod = "printU8Imm";
719 let ParserMatchClass = ImmUnsignedi4AsmOperand;
720 let OperandType = "OPERAND_IMMEDIATE";
723 // Unsigned 8-bit immediate used by SSE/AVX instructions.
724 def u8imm : Operand<i8> {
725 let PrintMethod = "printU8Imm";
726 let ParserMatchClass = ImmUnsignedi8AsmOperand;
727 let OperandType = "OPERAND_IMMEDIATE";
730 // 16-bit immediate but only 8-bits are significant and they are unsigned.
731 // Used by BT instructions.
732 def i16u8imm : Operand<i16> {
733 let PrintMethod = "printU8Imm";
734 let ParserMatchClass = ImmUnsignedi8AsmOperand;
735 let OperandType = "OPERAND_IMMEDIATE";
738 // 32-bit immediate but only 8-bits are significant and they are unsigned.
739 // Used by some SSE/AVX instructions that use intrinsics.
740 def i32u8imm : Operand<i32> {
741 let PrintMethod = "printU8Imm";
742 let ParserMatchClass = ImmUnsignedi8AsmOperand;
743 let OperandType = "OPERAND_IMMEDIATE";
746 // 64-bit immediate but only 8-bits are significant and they are unsigned.
747 // Used by BT instructions.
748 def i64u8imm : Operand<i64> {
749 let PrintMethod = "printU8Imm";
750 let ParserMatchClass = ImmUnsignedi8AsmOperand;
751 let OperandType = "OPERAND_IMMEDIATE";
754 // 64-bits but only 32 bits are significant, and those bits are treated as being
756 def i64i32imm_pcrel : Operand<i64> {
757 let PrintMethod = "printPCRelImm";
758 let ParserMatchClass = X86AbsMemAsmOperand;
759 let OperandType = "OPERAND_PCREL";
762 def lea64_32mem : Operand<i32> {
763 let PrintMethod = "printanymem";
764 let MIOperandInfo = (ops GR64, i8imm, GR64_NOSP, i32imm, SEGMENT_REG);
765 let ParserMatchClass = X86MemAsmOperand;
768 // Memory operands that use 64-bit pointers in both ILP32 and LP64.
769 def lea64mem : Operand<i64> {
770 let PrintMethod = "printanymem";
771 let MIOperandInfo = (ops GR64, i8imm, GR64_NOSP, i32imm, SEGMENT_REG);
772 let ParserMatchClass = X86MemAsmOperand;
775 let RenderMethod = "addMaskPairOperands" in {
776 def VK1PairAsmOperand : AsmOperandClass { let Name = "VK1Pair"; }
777 def VK2PairAsmOperand : AsmOperandClass { let Name = "VK2Pair"; }
778 def VK4PairAsmOperand : AsmOperandClass { let Name = "VK4Pair"; }
779 def VK8PairAsmOperand : AsmOperandClass { let Name = "VK8Pair"; }
780 def VK16PairAsmOperand : AsmOperandClass { let Name = "VK16Pair"; }
783 def VK1Pair : RegisterOperand<VK1PAIR, "printVKPair"> {
784 let ParserMatchClass = VK1PairAsmOperand;
787 def VK2Pair : RegisterOperand<VK2PAIR, "printVKPair"> {
788 let ParserMatchClass = VK2PairAsmOperand;
791 def VK4Pair : RegisterOperand<VK4PAIR, "printVKPair"> {
792 let ParserMatchClass = VK4PairAsmOperand;
795 def VK8Pair : RegisterOperand<VK8PAIR, "printVKPair"> {
796 let ParserMatchClass = VK8PairAsmOperand;
799 def VK16Pair : RegisterOperand<VK16PAIR, "printVKPair"> {
800 let ParserMatchClass = VK16PairAsmOperand;
803 //===----------------------------------------------------------------------===//
804 // X86 Complex Pattern Definitions.
807 // Define X86-specific addressing mode.
808 def addr : ComplexPattern<iPTR, 5, "selectAddr", [], [SDNPWantParent]>;
809 def lea32addr : ComplexPattern<i32, 5, "selectLEAAddr",
810 [add, sub, mul, X86mul_imm, shl, or, frameindex],
812 // In 64-bit mode 32-bit LEAs can use RIP-relative addressing.
813 def lea64_32addr : ComplexPattern<i32, 5, "selectLEA64_32Addr",
814 [add, sub, mul, X86mul_imm, shl, or,
815 frameindex, X86WrapperRIP],
818 def tls32addr : ComplexPattern<i32, 5, "selectTLSADDRAddr",
819 [tglobaltlsaddr], []>;
821 def tls32baseaddr : ComplexPattern<i32, 5, "selectTLSADDRAddr",
822 [tglobaltlsaddr], []>;
824 def lea64addr : ComplexPattern<i64, 5, "selectLEAAddr",
825 [add, sub, mul, X86mul_imm, shl, or, frameindex,
828 def tls64addr : ComplexPattern<i64, 5, "selectTLSADDRAddr",
829 [tglobaltlsaddr], []>;
831 def tls64baseaddr : ComplexPattern<i64, 5, "selectTLSADDRAddr",
832 [tglobaltlsaddr], []>;
834 def vectoraddr : ComplexPattern<iPTR, 5, "selectVectorAddr", [],[SDNPWantParent]>;
836 // A relocatable immediate is either an immediate operand or an operand that can
837 // be relocated by the linker to an immediate, such as a regular symbol in
839 def relocImm : ComplexPattern<iAny, 1, "selectRelocImm", [imm, X86Wrapper], [],
842 //===----------------------------------------------------------------------===//
843 // X86 Instruction Predicate Definitions.
844 def TruePredicate : Predicate<"true">;
846 def HasCMov : Predicate<"Subtarget->hasCMov()">;
847 def NoCMov : Predicate<"!Subtarget->hasCMov()">;
849 def HasMMX : Predicate<"Subtarget->hasMMX()">;
850 def Has3DNow : Predicate<"Subtarget->has3DNow()">;
851 def Has3DNowA : Predicate<"Subtarget->has3DNowA()">;
852 def HasSSE1 : Predicate<"Subtarget->hasSSE1()">;
853 def UseSSE1 : Predicate<"Subtarget->hasSSE1() && !Subtarget->hasAVX()">;
854 def HasSSE2 : Predicate<"Subtarget->hasSSE2()">;
855 def UseSSE2 : Predicate<"Subtarget->hasSSE2() && !Subtarget->hasAVX()">;
856 def HasSSE3 : Predicate<"Subtarget->hasSSE3()">;
857 def UseSSE3 : Predicate<"Subtarget->hasSSE3() && !Subtarget->hasAVX()">;
858 def HasSSSE3 : Predicate<"Subtarget->hasSSSE3()">;
859 def UseSSSE3 : Predicate<"Subtarget->hasSSSE3() && !Subtarget->hasAVX()">;
860 def HasSSE41 : Predicate<"Subtarget->hasSSE41()">;
861 def NoSSE41 : Predicate<"!Subtarget->hasSSE41()">;
862 def UseSSE41 : Predicate<"Subtarget->hasSSE41() && !Subtarget->hasAVX()">;
863 def HasSSE42 : Predicate<"Subtarget->hasSSE42()">;
864 def UseSSE42 : Predicate<"Subtarget->hasSSE42() && !Subtarget->hasAVX()">;
865 def HasSSE4A : Predicate<"Subtarget->hasSSE4A()">;
866 def NoAVX : Predicate<"!Subtarget->hasAVX()">;
867 def HasAVX : Predicate<"Subtarget->hasAVX()">;
868 def HasAVX2 : Predicate<"Subtarget->hasAVX2()">;
869 def HasAVX1Only : Predicate<"Subtarget->hasAVX() && !Subtarget->hasAVX2()">;
870 def HasAVX512 : Predicate<"Subtarget->hasAVX512()">;
871 def UseAVX : Predicate<"Subtarget->hasAVX() && !Subtarget->hasAVX512()">;
872 def UseAVX2 : Predicate<"Subtarget->hasAVX2() && !Subtarget->hasAVX512()">;
873 def NoAVX512 : Predicate<"!Subtarget->hasAVX512()">;
874 def HasCDI : Predicate<"Subtarget->hasCDI()">;
875 def HasVPOPCNTDQ : Predicate<"Subtarget->hasVPOPCNTDQ()">;
876 def HasPFI : Predicate<"Subtarget->hasPFI()">;
877 def HasERI : Predicate<"Subtarget->hasERI()">;
878 def HasDQI : Predicate<"Subtarget->hasDQI()">;
879 def NoDQI : Predicate<"!Subtarget->hasDQI()">;
880 def HasBWI : Predicate<"Subtarget->hasBWI()">;
881 def NoBWI : Predicate<"!Subtarget->hasBWI()">;
882 def HasVLX : Predicate<"Subtarget->hasVLX()">;
883 def NoVLX : Predicate<"!Subtarget->hasVLX()">;
884 def NoVLX_Or_NoBWI : Predicate<"!Subtarget->hasVLX() || !Subtarget->hasBWI()">;
885 def NoVLX_Or_NoDQI : Predicate<"!Subtarget->hasVLX() || !Subtarget->hasDQI()">;
886 def PKU : Predicate<"Subtarget->hasPKU()">;
887 def HasVNNI : Predicate<"Subtarget->hasVNNI()">;
888 def HasVP2INTERSECT : Predicate<"Subtarget->hasVP2INTERSECT()">;
889 def HasBF16 : Predicate<"Subtarget->hasBF16()">;
891 def HasBITALG : Predicate<"Subtarget->hasBITALG()">;
892 def HasPOPCNT : Predicate<"Subtarget->hasPOPCNT()">;
893 def HasAES : Predicate<"Subtarget->hasAES()">;
894 def HasVAES : Predicate<"Subtarget->hasVAES()">;
895 def NoVLX_Or_NoVAES : Predicate<"!Subtarget->hasVLX() || !Subtarget->hasVAES()">;
896 def HasFXSR : Predicate<"Subtarget->hasFXSR()">;
897 def HasXSAVE : Predicate<"Subtarget->hasXSAVE()">;
898 def HasXSAVEOPT : Predicate<"Subtarget->hasXSAVEOPT()">;
899 def HasXSAVEC : Predicate<"Subtarget->hasXSAVEC()">;
900 def HasXSAVES : Predicate<"Subtarget->hasXSAVES()">;
901 def HasPCLMUL : Predicate<"Subtarget->hasPCLMUL()">;
902 def NoVLX_Or_NoVPCLMULQDQ :
903 Predicate<"!Subtarget->hasVLX() || !Subtarget->hasVPCLMULQDQ()">;
904 def HasVPCLMULQDQ : Predicate<"Subtarget->hasVPCLMULQDQ()">;
905 def HasGFNI : Predicate<"Subtarget->hasGFNI()">;
906 def HasFMA : Predicate<"Subtarget->hasFMA()">;
907 def HasFMA4 : Predicate<"Subtarget->hasFMA4()">;
908 def NoFMA4 : Predicate<"!Subtarget->hasFMA4()">;
909 def HasXOP : Predicate<"Subtarget->hasXOP()">;
910 def HasTBM : Predicate<"Subtarget->hasTBM()">;
911 def NoTBM : Predicate<"!Subtarget->hasTBM()">;
912 def HasLWP : Predicate<"Subtarget->hasLWP()">;
913 def HasMOVBE : Predicate<"Subtarget->hasMOVBE()">;
914 def HasRDRAND : Predicate<"Subtarget->hasRDRAND()">;
915 def HasF16C : Predicate<"Subtarget->hasF16C()">;
916 def HasFSGSBase : Predicate<"Subtarget->hasFSGSBase()">;
917 def HasLZCNT : Predicate<"Subtarget->hasLZCNT()">;
918 def HasBMI : Predicate<"Subtarget->hasBMI()">;
919 def HasBMI2 : Predicate<"Subtarget->hasBMI2()">;
920 def NoBMI2 : Predicate<"!Subtarget->hasBMI2()">;
921 def HasVBMI : Predicate<"Subtarget->hasVBMI()">;
922 def HasVBMI2 : Predicate<"Subtarget->hasVBMI2()">;
923 def HasIFMA : Predicate<"Subtarget->hasIFMA()">;
924 def HasRTM : Predicate<"Subtarget->hasRTM()">;
925 def HasADX : Predicate<"Subtarget->hasADX()">;
926 def HasSHA : Predicate<"Subtarget->hasSHA()">;
927 def HasSGX : Predicate<"Subtarget->hasSGX()">;
928 def HasPRFCHW : Predicate<"Subtarget->hasPRFCHW()">;
929 def HasRDSEED : Predicate<"Subtarget->hasRDSEED()">;
930 def HasSSEPrefetch : Predicate<"Subtarget->hasSSEPrefetch()">;
931 def NoSSEPrefetch : Predicate<"!Subtarget->hasSSEPrefetch()">;
932 def HasPrefetchW : Predicate<"Subtarget->hasPRFCHW()">;
933 def HasPREFETCHWT1 : Predicate<"Subtarget->hasPREFETCHWT1()">;
934 def HasLAHFSAHF : Predicate<"Subtarget->hasLAHFSAHF()">;
935 def HasMWAITX : Predicate<"Subtarget->hasMWAITX()">;
936 def HasCLZERO : Predicate<"Subtarget->hasCLZERO()">;
937 def HasCLDEMOTE : Predicate<"Subtarget->hasCLDEMOTE()">;
938 def HasMOVDIRI : Predicate<"Subtarget->hasMOVDIRI()">;
939 def HasMOVDIR64B : Predicate<"Subtarget->hasMOVDIR64B()">;
940 def HasPTWRITE : Predicate<"Subtarget->hasPTWRITE()">;
941 def FPStackf32 : Predicate<"!Subtarget->hasSSE1()">;
942 def FPStackf64 : Predicate<"!Subtarget->hasSSE2()">;
943 def HasSHSTK : Predicate<"Subtarget->hasSHSTK()">;
944 def HasCLFLUSHOPT : Predicate<"Subtarget->hasCLFLUSHOPT()">;
945 def HasCLWB : Predicate<"Subtarget->hasCLWB()">;
946 def HasWBNOINVD : Predicate<"Subtarget->hasWBNOINVD()">;
947 def HasRDPID : Predicate<"Subtarget->hasRDPID()">;
948 def HasWAITPKG : Predicate<"Subtarget->hasWAITPKG()">;
949 def HasINVPCID : Predicate<"Subtarget->hasINVPCID()">;
950 def HasCmpxchg8b : Predicate<"Subtarget->hasCmpxchg8b()">;
951 def HasCmpxchg16b: Predicate<"Subtarget->hasCmpxchg16b()">;
952 def HasPCONFIG : Predicate<"Subtarget->hasPCONFIG()">;
953 def HasENQCMD : Predicate<"Subtarget->hasENQCMD()">;
954 def Not64BitMode : Predicate<"!Subtarget->is64Bit()">,
955 AssemblerPredicate<"!Mode64Bit", "Not 64-bit mode">;
956 def In64BitMode : Predicate<"Subtarget->is64Bit()">,
957 AssemblerPredicate<"Mode64Bit", "64-bit mode">;
958 def IsLP64 : Predicate<"Subtarget->isTarget64BitLP64()">;
959 def NotLP64 : Predicate<"!Subtarget->isTarget64BitLP64()">;
960 def In16BitMode : Predicate<"Subtarget->is16Bit()">,
961 AssemblerPredicate<"Mode16Bit", "16-bit mode">;
962 def Not16BitMode : Predicate<"!Subtarget->is16Bit()">,
963 AssemblerPredicate<"!Mode16Bit", "Not 16-bit mode">;
964 def In32BitMode : Predicate<"Subtarget->is32Bit()">,
965 AssemblerPredicate<"Mode32Bit", "32-bit mode">;
966 def IsWin64 : Predicate<"Subtarget->isTargetWin64()">;
967 def NotWin64 : Predicate<"!Subtarget->isTargetWin64()">;
968 def NotWin64WithoutFP : Predicate<"!Subtarget->isTargetWin64() ||"
969 "Subtarget->getFrameLowering()->hasFP(*MF)"> {
970 let RecomputePerFunction = 1;
972 def IsPS4 : Predicate<"Subtarget->isTargetPS4()">;
973 def NotPS4 : Predicate<"!Subtarget->isTargetPS4()">;
974 def IsNaCl : Predicate<"Subtarget->isTargetNaCl()">;
975 def NotNaCl : Predicate<"!Subtarget->isTargetNaCl()">;
976 def SmallCode : Predicate<"TM.getCodeModel() == CodeModel::Small">;
977 def KernelCode : Predicate<"TM.getCodeModel() == CodeModel::Kernel">;
978 def NearData : Predicate<"TM.getCodeModel() == CodeModel::Small ||"
979 "TM.getCodeModel() == CodeModel::Kernel">;
980 def IsNotPIC : Predicate<"!TM.isPositionIndependent()">;
982 // We could compute these on a per-module basis but doing so requires accessing
983 // the Function object through the <Target>Subtarget and objections were raised
984 // to that (see post-commit review comments for r301750).
985 let RecomputePerFunction = 1 in {
986 def OptForSize : Predicate<"MF->getFunction().hasOptSize()">;
987 def OptForMinSize : Predicate<"MF->getFunction().hasMinSize()">;
988 def OptForSpeed : Predicate<"!MF->getFunction().hasOptSize()">;
989 def UseIncDec : Predicate<"!Subtarget->slowIncDec() || "
990 "MF->getFunction().hasOptSize()">;
991 def NoSSE41_Or_OptForSize : Predicate<"MF->getFunction().hasOptSize() || "
992 "!Subtarget->hasSSE41()">;
995 def CallImmAddr : Predicate<"Subtarget->isLegalToCallImmediateAddr()">;
996 def FavorMemIndirectCall : Predicate<"!Subtarget->slowTwoMemOps()">;
997 def HasFastMem32 : Predicate<"!Subtarget->isUnalignedMem32Slow()">;
998 def HasFastLZCNT : Predicate<"Subtarget->hasFastLZCNT()">;
999 def HasFastSHLDRotate : Predicate<"Subtarget->hasFastSHLDRotate()">;
1000 def HasERMSB : Predicate<"Subtarget->hasERMSB()">;
1001 def HasMFence : Predicate<"Subtarget->hasMFence()">;
1002 def UseRetpolineIndirectCalls : Predicate<"Subtarget->useRetpolineIndirectCalls()">;
1003 def NotUseRetpolineIndirectCalls : Predicate<"!Subtarget->useRetpolineIndirectCalls()">;
1005 //===----------------------------------------------------------------------===//
1006 // X86 Instruction Format Definitions.
1009 include "X86InstrFormats.td"
1011 //===----------------------------------------------------------------------===//
1012 // Pattern fragments.
1015 // X86 specific condition code. These correspond to CondCode in
1016 // X86InstrInfo.h. They must be kept in synch.
1017 def X86_COND_O : PatLeaf<(i8 0)>;
1018 def X86_COND_NO : PatLeaf<(i8 1)>;
1019 def X86_COND_B : PatLeaf<(i8 2)>; // alt. COND_C
1020 def X86_COND_AE : PatLeaf<(i8 3)>; // alt. COND_NC
1021 def X86_COND_E : PatLeaf<(i8 4)>; // alt. COND_Z
1022 def X86_COND_NE : PatLeaf<(i8 5)>; // alt. COND_NZ
1023 def X86_COND_BE : PatLeaf<(i8 6)>; // alt. COND_NA
1024 def X86_COND_A : PatLeaf<(i8 7)>; // alt. COND_NBE
1025 def X86_COND_S : PatLeaf<(i8 8)>;
1026 def X86_COND_NS : PatLeaf<(i8 9)>;
1027 def X86_COND_P : PatLeaf<(i8 10)>; // alt. COND_PE
1028 def X86_COND_NP : PatLeaf<(i8 11)>; // alt. COND_PO
1029 def X86_COND_L : PatLeaf<(i8 12)>; // alt. COND_NGE
1030 def X86_COND_GE : PatLeaf<(i8 13)>; // alt. COND_NL
1031 def X86_COND_LE : PatLeaf<(i8 14)>; // alt. COND_NG
1032 def X86_COND_G : PatLeaf<(i8 15)>; // alt. COND_NLE
1034 def i16immSExt8 : ImmLeaf<i16, [{ return isInt<8>(Imm); }]>;
1035 def i32immSExt8 : ImmLeaf<i32, [{ return isInt<8>(Imm); }]>;
1036 def i64immSExt8 : ImmLeaf<i64, [{ return isInt<8>(Imm); }]>;
1037 def i64immSExt32 : ImmLeaf<i64, [{ return isInt<32>(Imm); }]>;
1039 // FIXME: Ideally we would just replace the above i*immSExt* matchers with
1040 // relocImm-based matchers, but then FastISel would be unable to use them.
1041 def i64relocImmSExt8 : PatLeaf<(i64 relocImm), [{
1042 return isSExtRelocImm<8>(N);
1044 def i64relocImmSExt32 : PatLeaf<(i64 relocImm), [{
1045 return isSExtRelocImm<32>(N);
1048 // If we have multiple users of an immediate, it's much smaller to reuse
1049 // the register, rather than encode the immediate in every instruction.
1050 // This has the risk of increasing register pressure from stretched live
1051 // ranges, however, the immediates should be trivial to rematerialize by
1052 // the RA in the event of high register pressure.
1053 // TODO : This is currently enabled for stores and binary ops. There are more
1054 // cases for which this can be enabled, though this catches the bulk of the
1056 // TODO2 : This should really also be enabled under O2, but there's currently
1057 // an issue with RA where we don't pull the constants into their users
1058 // when we rematerialize them. I'll follow-up on enabling O2 after we fix that
1060 // TODO3 : This is currently limited to single basic blocks (DAG creation
1061 // pulls block immediates to the top and merges them if necessary).
1062 // Eventually, it would be nice to allow ConstantHoisting to merge constants
1063 // globally for potentially added savings.
1065 def relocImm8_su : PatLeaf<(i8 relocImm), [{
1066 return !shouldAvoidImmediateInstFormsForSize(N);
1068 def relocImm16_su : PatLeaf<(i16 relocImm), [{
1069 return !shouldAvoidImmediateInstFormsForSize(N);
1071 def relocImm32_su : PatLeaf<(i32 relocImm), [{
1072 return !shouldAvoidImmediateInstFormsForSize(N);
1075 def i16immSExt8_su : PatLeaf<(i16immSExt8), [{
1076 return !shouldAvoidImmediateInstFormsForSize(N);
1078 def i32immSExt8_su : PatLeaf<(i32immSExt8), [{
1079 return !shouldAvoidImmediateInstFormsForSize(N);
1081 def i64immSExt8_su : PatLeaf<(i64immSExt8), [{
1082 return !shouldAvoidImmediateInstFormsForSize(N);
1085 def i64relocImmSExt8_su : PatLeaf<(i64relocImmSExt8), [{
1086 return !shouldAvoidImmediateInstFormsForSize(N);
1088 def i64relocImmSExt32_su : PatLeaf<(i64relocImmSExt32), [{
1089 return !shouldAvoidImmediateInstFormsForSize(N);
1092 // i64immZExt32 predicate - True if the 64-bit immediate fits in a 32-bit
1094 def i64immZExt32 : ImmLeaf<i64, [{ return isUInt<32>(Imm); }]>;
1096 def i64immZExt32SExt8 : ImmLeaf<i64, [{
1097 return isUInt<32>(Imm) && isInt<8>(static_cast<int32_t>(Imm));
1100 // Helper fragments for loads.
1102 // It's safe to fold a zextload/extload from i1 as a regular i8 load. The
1103 // upper bits are guaranteed to be zero and we were going to emit a MOV8rm
1104 // which might get folded during peephole anyway.
1105 def loadi8 : PatFrag<(ops node:$ptr), (i8 (unindexedload node:$ptr)), [{
1106 LoadSDNode *LD = cast<LoadSDNode>(N);
1107 ISD::LoadExtType ExtType = LD->getExtensionType();
1108 return ExtType == ISD::NON_EXTLOAD || ExtType == ISD::EXTLOAD ||
1109 ExtType == ISD::ZEXTLOAD;
1112 // It's always safe to treat a anyext i16 load as a i32 load if the i16 is
1113 // known to be 32-bit aligned or better. Ditto for i8 to i16.
1114 def loadi16 : PatFrag<(ops node:$ptr), (i16 (unindexedload node:$ptr)), [{
1115 LoadSDNode *LD = cast<LoadSDNode>(N);
1116 ISD::LoadExtType ExtType = LD->getExtensionType();
1117 if (ExtType == ISD::NON_EXTLOAD)
1119 if (ExtType == ISD::EXTLOAD)
1120 return LD->getAlignment() >= 2 && LD->isSimple();
1124 def loadi32 : PatFrag<(ops node:$ptr), (i32 (unindexedload node:$ptr)), [{
1125 LoadSDNode *LD = cast<LoadSDNode>(N);
1126 ISD::LoadExtType ExtType = LD->getExtensionType();
1127 if (ExtType == ISD::NON_EXTLOAD)
1129 if (ExtType == ISD::EXTLOAD)
1130 return LD->getAlignment() >= 4 && LD->isSimple();
1134 def loadi64 : PatFrag<(ops node:$ptr), (i64 (load node:$ptr))>;
1135 def loadf32 : PatFrag<(ops node:$ptr), (f32 (load node:$ptr))>;
1136 def loadf64 : PatFrag<(ops node:$ptr), (f64 (load node:$ptr))>;
1137 def loadf80 : PatFrag<(ops node:$ptr), (f80 (load node:$ptr))>;
1138 def loadf128 : PatFrag<(ops node:$ptr), (f128 (load node:$ptr))>;
1139 def alignedloadf128 : PatFrag<(ops node:$ptr), (f128 (load node:$ptr)), [{
1140 LoadSDNode *Ld = cast<LoadSDNode>(N);
1141 return Ld->getAlignment() >= Ld->getMemoryVT().getStoreSize();
1143 def memopf128 : PatFrag<(ops node:$ptr), (f128 (load node:$ptr)), [{
1144 LoadSDNode *Ld = cast<LoadSDNode>(N);
1145 return Subtarget->hasSSEUnalignedMem() ||
1146 Ld->getAlignment() >= Ld->getMemoryVT().getStoreSize();
1149 def sextloadi16i8 : PatFrag<(ops node:$ptr), (i16 (sextloadi8 node:$ptr))>;
1150 def sextloadi32i8 : PatFrag<(ops node:$ptr), (i32 (sextloadi8 node:$ptr))>;
1151 def sextloadi32i16 : PatFrag<(ops node:$ptr), (i32 (sextloadi16 node:$ptr))>;
1152 def sextloadi64i8 : PatFrag<(ops node:$ptr), (i64 (sextloadi8 node:$ptr))>;
1153 def sextloadi64i16 : PatFrag<(ops node:$ptr), (i64 (sextloadi16 node:$ptr))>;
1154 def sextloadi64i32 : PatFrag<(ops node:$ptr), (i64 (sextloadi32 node:$ptr))>;
1156 def zextloadi8i1 : PatFrag<(ops node:$ptr), (i8 (zextloadi1 node:$ptr))>;
1157 def zextloadi16i1 : PatFrag<(ops node:$ptr), (i16 (zextloadi1 node:$ptr))>;
1158 def zextloadi32i1 : PatFrag<(ops node:$ptr), (i32 (zextloadi1 node:$ptr))>;
1159 def zextloadi16i8 : PatFrag<(ops node:$ptr), (i16 (zextloadi8 node:$ptr))>;
1160 def zextloadi32i8 : PatFrag<(ops node:$ptr), (i32 (zextloadi8 node:$ptr))>;
1161 def zextloadi32i16 : PatFrag<(ops node:$ptr), (i32 (zextloadi16 node:$ptr))>;
1162 def zextloadi64i1 : PatFrag<(ops node:$ptr), (i64 (zextloadi1 node:$ptr))>;
1163 def zextloadi64i8 : PatFrag<(ops node:$ptr), (i64 (zextloadi8 node:$ptr))>;
1164 def zextloadi64i16 : PatFrag<(ops node:$ptr), (i64 (zextloadi16 node:$ptr))>;
1165 def zextloadi64i32 : PatFrag<(ops node:$ptr), (i64 (zextloadi32 node:$ptr))>;
1167 def extloadi8i1 : PatFrag<(ops node:$ptr), (i8 (extloadi1 node:$ptr))>;
1168 def extloadi16i1 : PatFrag<(ops node:$ptr), (i16 (extloadi1 node:$ptr))>;
1169 def extloadi32i1 : PatFrag<(ops node:$ptr), (i32 (extloadi1 node:$ptr))>;
1170 def extloadi16i8 : PatFrag<(ops node:$ptr), (i16 (extloadi8 node:$ptr))>;
1171 def extloadi32i8 : PatFrag<(ops node:$ptr), (i32 (extloadi8 node:$ptr))>;
1172 def extloadi32i16 : PatFrag<(ops node:$ptr), (i32 (extloadi16 node:$ptr))>;
1173 def extloadi64i1 : PatFrag<(ops node:$ptr), (i64 (extloadi1 node:$ptr))>;
1174 def extloadi64i8 : PatFrag<(ops node:$ptr), (i64 (extloadi8 node:$ptr))>;
1175 def extloadi64i16 : PatFrag<(ops node:$ptr), (i64 (extloadi16 node:$ptr))>;
1177 // We can treat an i8/i16 extending load to i64 as a 32 bit load if its known
1178 // to be 4 byte aligned or better.
1179 def extloadi64i32 : PatFrag<(ops node:$ptr), (i64 (unindexedload node:$ptr)), [{
1180 LoadSDNode *LD = cast<LoadSDNode>(N);
1181 ISD::LoadExtType ExtType = LD->getExtensionType();
1182 if (ExtType != ISD::EXTLOAD)
1184 if (LD->getMemoryVT() == MVT::i32)
1187 return LD->getAlignment() >= 4 && LD->isSimple();
1191 // An 'and' node with a single use.
1192 def and_su : PatFrag<(ops node:$lhs, node:$rhs), (and node:$lhs, node:$rhs), [{
1193 return N->hasOneUse();
1195 // An 'srl' node with a single use.
1196 def srl_su : PatFrag<(ops node:$lhs, node:$rhs), (srl node:$lhs, node:$rhs), [{
1197 return N->hasOneUse();
1199 // An 'trunc' node with a single use.
1200 def trunc_su : PatFrag<(ops node:$src), (trunc node:$src), [{
1201 return N->hasOneUse();
1204 //===----------------------------------------------------------------------===//
1205 // Instruction list.
1209 let hasSideEffects = 0, SchedRW = [WriteNop] in {
1210 def NOOP : I<0x90, RawFrm, (outs), (ins), "nop", []>;
1211 def NOOPW : I<0x1f, MRMXm, (outs), (ins i16mem:$zero),
1212 "nop{w}\t$zero", []>, TB, OpSize16, NotMemoryFoldable;
1213 def NOOPL : I<0x1f, MRMXm, (outs), (ins i32mem:$zero),
1214 "nop{l}\t$zero", []>, TB, OpSize32, NotMemoryFoldable;
1215 def NOOPQ : RI<0x1f, MRMXm, (outs), (ins i64mem:$zero),
1216 "nop{q}\t$zero", []>, TB, NotMemoryFoldable,
1217 Requires<[In64BitMode]>;
1218 // Also allow register so we can assemble/disassemble
1219 def NOOPWr : I<0x1f, MRMXr, (outs), (ins GR16:$zero),
1220 "nop{w}\t$zero", []>, TB, OpSize16, NotMemoryFoldable;
1221 def NOOPLr : I<0x1f, MRMXr, (outs), (ins GR32:$zero),
1222 "nop{l}\t$zero", []>, TB, OpSize32, NotMemoryFoldable;
1223 def NOOPQr : RI<0x1f, MRMXr, (outs), (ins GR64:$zero),
1224 "nop{q}\t$zero", []>, TB, NotMemoryFoldable,
1225 Requires<[In64BitMode]>;
1229 // Constructing a stack frame.
1230 def ENTER : Ii16<0xC8, RawFrmImm8, (outs), (ins i16imm:$len, i8imm:$lvl),
1231 "enter\t$len, $lvl", []>, Sched<[WriteMicrocoded]>;
1233 let SchedRW = [WriteALU] in {
1234 let Defs = [EBP, ESP], Uses = [EBP, ESP], mayLoad = 1, hasSideEffects=0 in
1235 def LEAVE : I<0xC9, RawFrm, (outs), (ins), "leave", []>,
1236 Requires<[Not64BitMode]>;
1238 let Defs = [RBP,RSP], Uses = [RBP,RSP], mayLoad = 1, hasSideEffects = 0 in
1239 def LEAVE64 : I<0xC9, RawFrm, (outs), (ins), "leave", []>,
1240 Requires<[In64BitMode]>;
1243 //===----------------------------------------------------------------------===//
1244 // Miscellaneous Instructions.
1247 let isBarrier = 1, hasSideEffects = 1, usesCustomInserter = 1,
1248 SchedRW = [WriteSystem] in
1249 def Int_eh_sjlj_setup_dispatch
1250 : PseudoI<(outs), (ins), [(X86eh_sjlj_setup_dispatch)]>;
1252 let Defs = [ESP], Uses = [ESP], hasSideEffects=0 in {
1253 let mayLoad = 1, SchedRW = [WriteLoad] in {
1254 def POP16r : I<0x58, AddRegFrm, (outs GR16:$reg), (ins), "pop{w}\t$reg", []>,
1256 def POP32r : I<0x58, AddRegFrm, (outs GR32:$reg), (ins), "pop{l}\t$reg", []>,
1257 OpSize32, Requires<[Not64BitMode]>;
1258 // Long form for the disassembler.
1259 let isCodeGenOnly = 1, ForceDisassemble = 1 in {
1260 def POP16rmr: I<0x8F, MRM0r, (outs GR16:$reg), (ins), "pop{w}\t$reg", []>,
1261 OpSize16, NotMemoryFoldable;
1262 def POP32rmr: I<0x8F, MRM0r, (outs GR32:$reg), (ins), "pop{l}\t$reg", []>,
1263 OpSize32, Requires<[Not64BitMode]>, NotMemoryFoldable;
1264 } // isCodeGenOnly = 1, ForceDisassemble = 1
1265 } // mayLoad, SchedRW
1266 let mayStore = 1, mayLoad = 1, SchedRW = [WriteCopy] in {
1267 def POP16rmm: I<0x8F, MRM0m, (outs), (ins i16mem:$dst), "pop{w}\t$dst", []>,
1269 def POP32rmm: I<0x8F, MRM0m, (outs), (ins i32mem:$dst), "pop{l}\t$dst", []>,
1270 OpSize32, Requires<[Not64BitMode]>;
1271 } // mayStore, mayLoad, SchedRW
1273 let mayStore = 1, SchedRW = [WriteStore] in {
1274 def PUSH16r : I<0x50, AddRegFrm, (outs), (ins GR16:$reg), "push{w}\t$reg",[]>,
1276 def PUSH32r : I<0x50, AddRegFrm, (outs), (ins GR32:$reg), "push{l}\t$reg",[]>,
1277 OpSize32, Requires<[Not64BitMode]>;
1278 // Long form for the disassembler.
1279 let isCodeGenOnly = 1, ForceDisassemble = 1 in {
1280 def PUSH16rmr: I<0xFF, MRM6r, (outs), (ins GR16:$reg), "push{w}\t$reg",[]>,
1281 OpSize16, NotMemoryFoldable;
1282 def PUSH32rmr: I<0xFF, MRM6r, (outs), (ins GR32:$reg), "push{l}\t$reg",[]>,
1283 OpSize32, Requires<[Not64BitMode]>, NotMemoryFoldable;
1284 } // isCodeGenOnly = 1, ForceDisassemble = 1
1286 def PUSH16i8 : Ii8<0x6a, RawFrm, (outs), (ins i16i8imm:$imm),
1287 "push{w}\t$imm", []>, OpSize16;
1288 def PUSHi16 : Ii16<0x68, RawFrm, (outs), (ins i16imm:$imm),
1289 "push{w}\t$imm", []>, OpSize16;
1291 def PUSH32i8 : Ii8<0x6a, RawFrm, (outs), (ins i32i8imm:$imm),
1292 "push{l}\t$imm", []>, OpSize32,
1293 Requires<[Not64BitMode]>;
1294 def PUSHi32 : Ii32<0x68, RawFrm, (outs), (ins i32imm:$imm),
1295 "push{l}\t$imm", []>, OpSize32,
1296 Requires<[Not64BitMode]>;
1297 } // mayStore, SchedRW
1299 let mayLoad = 1, mayStore = 1, SchedRW = [WriteCopy] in {
1300 def PUSH16rmm: I<0xFF, MRM6m, (outs), (ins i16mem:$src), "push{w}\t$src", []>,
1302 def PUSH32rmm: I<0xFF, MRM6m, (outs), (ins i32mem:$src), "push{l}\t$src", []>,
1303 OpSize32, Requires<[Not64BitMode]>;
1304 } // mayLoad, mayStore, SchedRW
1308 let mayLoad = 1, mayStore = 1, usesCustomInserter = 1,
1309 SchedRW = [WriteRMW], Defs = [ESP] in {
1311 def RDFLAGS32 : PseudoI<(outs GR32:$dst), (ins),
1312 [(set GR32:$dst, (int_x86_flags_read_u32))]>,
1313 Requires<[Not64BitMode]>;
1316 def RDFLAGS64 : PseudoI<(outs GR64:$dst), (ins),
1317 [(set GR64:$dst, (int_x86_flags_read_u64))]>,
1318 Requires<[In64BitMode]>;
1321 let mayLoad = 1, mayStore = 1, usesCustomInserter = 1,
1322 SchedRW = [WriteRMW] in {
1323 let Defs = [ESP, EFLAGS, DF], Uses = [ESP] in
1324 def WRFLAGS32 : PseudoI<(outs), (ins GR32:$src),
1325 [(int_x86_flags_write_u32 GR32:$src)]>,
1326 Requires<[Not64BitMode]>;
1328 let Defs = [RSP, EFLAGS, DF], Uses = [RSP] in
1329 def WRFLAGS64 : PseudoI<(outs), (ins GR64:$src),
1330 [(int_x86_flags_write_u64 GR64:$src)]>,
1331 Requires<[In64BitMode]>;
1334 let Defs = [ESP, EFLAGS, DF], Uses = [ESP], mayLoad = 1, hasSideEffects=0,
1335 SchedRW = [WriteLoad] in {
1336 def POPF16 : I<0x9D, RawFrm, (outs), (ins), "popf{w}", []>, OpSize16;
1337 def POPF32 : I<0x9D, RawFrm, (outs), (ins), "popf{l|d}", []>, OpSize32,
1338 Requires<[Not64BitMode]>;
1341 let Defs = [ESP], Uses = [ESP, EFLAGS, DF], mayStore = 1, hasSideEffects=0,
1342 SchedRW = [WriteStore] in {
1343 def PUSHF16 : I<0x9C, RawFrm, (outs), (ins), "pushf{w}", []>, OpSize16;
1344 def PUSHF32 : I<0x9C, RawFrm, (outs), (ins), "pushf{l|d}", []>, OpSize32,
1345 Requires<[Not64BitMode]>;
1348 let Defs = [RSP], Uses = [RSP], hasSideEffects=0 in {
1349 let mayLoad = 1, SchedRW = [WriteLoad] in {
1350 def POP64r : I<0x58, AddRegFrm, (outs GR64:$reg), (ins), "pop{q}\t$reg", []>,
1351 OpSize32, Requires<[In64BitMode]>;
1352 // Long form for the disassembler.
1353 let isCodeGenOnly = 1, ForceDisassemble = 1 in {
1354 def POP64rmr: I<0x8F, MRM0r, (outs GR64:$reg), (ins), "pop{q}\t$reg", []>,
1355 OpSize32, Requires<[In64BitMode]>, NotMemoryFoldable;
1356 } // isCodeGenOnly = 1, ForceDisassemble = 1
1357 } // mayLoad, SchedRW
1358 let mayLoad = 1, mayStore = 1, SchedRW = [WriteCopy] in
1359 def POP64rmm: I<0x8F, MRM0m, (outs), (ins i64mem:$dst), "pop{q}\t$dst", []>,
1360 OpSize32, Requires<[In64BitMode]>;
1361 let mayStore = 1, SchedRW = [WriteStore] in {
1362 def PUSH64r : I<0x50, AddRegFrm, (outs), (ins GR64:$reg), "push{q}\t$reg", []>,
1363 OpSize32, Requires<[In64BitMode]>;
1364 // Long form for the disassembler.
1365 let isCodeGenOnly = 1, ForceDisassemble = 1 in {
1366 def PUSH64rmr: I<0xFF, MRM6r, (outs), (ins GR64:$reg), "push{q}\t$reg", []>,
1367 OpSize32, Requires<[In64BitMode]>, NotMemoryFoldable;
1368 } // isCodeGenOnly = 1, ForceDisassemble = 1
1369 } // mayStore, SchedRW
1370 let mayLoad = 1, mayStore = 1, SchedRW = [WriteCopy] in {
1371 def PUSH64rmm: I<0xFF, MRM6m, (outs), (ins i64mem:$src), "push{q}\t$src", []>,
1372 OpSize32, Requires<[In64BitMode]>;
1373 } // mayLoad, mayStore, SchedRW
1376 let Defs = [RSP], Uses = [RSP], hasSideEffects = 0, mayStore = 1,
1377 SchedRW = [WriteStore] in {
1378 def PUSH64i8 : Ii8<0x6a, RawFrm, (outs), (ins i64i8imm:$imm),
1379 "push{q}\t$imm", []>, OpSize32,
1380 Requires<[In64BitMode]>;
1381 def PUSH64i32 : Ii32S<0x68, RawFrm, (outs), (ins i64i32imm:$imm),
1382 "push{q}\t$imm", []>, OpSize32,
1383 Requires<[In64BitMode]>;
1386 let Defs = [RSP, EFLAGS, DF], Uses = [RSP], mayLoad = 1, hasSideEffects=0 in
1387 def POPF64 : I<0x9D, RawFrm, (outs), (ins), "popfq", []>,
1388 OpSize32, Requires<[In64BitMode]>, Sched<[WriteLoad]>;
1389 let Defs = [RSP], Uses = [RSP, EFLAGS, DF], mayStore = 1, hasSideEffects=0 in
1390 def PUSHF64 : I<0x9C, RawFrm, (outs), (ins), "pushfq", []>,
1391 OpSize32, Requires<[In64BitMode]>, Sched<[WriteStore]>;
1393 let Defs = [EDI, ESI, EBP, EBX, EDX, ECX, EAX, ESP], Uses = [ESP],
1394 mayLoad = 1, hasSideEffects = 0, SchedRW = [WriteLoad] in {
1395 def POPA32 : I<0x61, RawFrm, (outs), (ins), "popal", []>,
1396 OpSize32, Requires<[Not64BitMode]>;
1397 def POPA16 : I<0x61, RawFrm, (outs), (ins), "popaw", []>,
1398 OpSize16, Requires<[Not64BitMode]>;
1400 let Defs = [ESP], Uses = [EDI, ESI, EBP, EBX, EDX, ECX, EAX, ESP],
1401 mayStore = 1, hasSideEffects = 0, SchedRW = [WriteStore] in {
1402 def PUSHA32 : I<0x60, RawFrm, (outs), (ins), "pushal", []>,
1403 OpSize32, Requires<[Not64BitMode]>;
1404 def PUSHA16 : I<0x60, RawFrm, (outs), (ins), "pushaw", []>,
1405 OpSize16, Requires<[Not64BitMode]>;
1408 let Constraints = "$src = $dst", SchedRW = [WriteBSWAP32] in {
1409 // This instruction is a consequence of BSWAP32r observing operand size. The
1410 // encoding is valid, but the behavior is undefined.
1411 let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0 in
1412 def BSWAP16r_BAD : I<0xC8, AddRegFrm, (outs GR16:$dst), (ins GR16:$src),
1413 "bswap{w}\t$dst", []>, OpSize16, TB;
1414 // GR32 = bswap GR32
1415 def BSWAP32r : I<0xC8, AddRegFrm, (outs GR32:$dst), (ins GR32:$src),
1417 [(set GR32:$dst, (bswap GR32:$src))]>, OpSize32, TB;
1419 let SchedRW = [WriteBSWAP64] in
1420 def BSWAP64r : RI<0xC8, AddRegFrm, (outs GR64:$dst), (ins GR64:$src),
1422 [(set GR64:$dst, (bswap GR64:$src))]>, TB;
1423 } // Constraints = "$src = $dst", SchedRW
1425 // Bit scan instructions.
1426 let Defs = [EFLAGS] in {
1427 def BSF16rr : I<0xBC, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
1428 "bsf{w}\t{$src, $dst|$dst, $src}",
1429 [(set GR16:$dst, EFLAGS, (X86bsf GR16:$src))]>,
1430 PS, OpSize16, Sched<[WriteBSF]>;
1431 def BSF16rm : I<0xBC, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
1432 "bsf{w}\t{$src, $dst|$dst, $src}",
1433 [(set GR16:$dst, EFLAGS, (X86bsf (loadi16 addr:$src)))]>,
1434 PS, OpSize16, Sched<[WriteBSFLd]>;
1435 def BSF32rr : I<0xBC, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
1436 "bsf{l}\t{$src, $dst|$dst, $src}",
1437 [(set GR32:$dst, EFLAGS, (X86bsf GR32:$src))]>,
1438 PS, OpSize32, Sched<[WriteBSF]>;
1439 def BSF32rm : I<0xBC, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
1440 "bsf{l}\t{$src, $dst|$dst, $src}",
1441 [(set GR32:$dst, EFLAGS, (X86bsf (loadi32 addr:$src)))]>,
1442 PS, OpSize32, Sched<[WriteBSFLd]>;
1443 def BSF64rr : RI<0xBC, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
1444 "bsf{q}\t{$src, $dst|$dst, $src}",
1445 [(set GR64:$dst, EFLAGS, (X86bsf GR64:$src))]>,
1446 PS, Sched<[WriteBSF]>;
1447 def BSF64rm : RI<0xBC, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
1448 "bsf{q}\t{$src, $dst|$dst, $src}",
1449 [(set GR64:$dst, EFLAGS, (X86bsf (loadi64 addr:$src)))]>,
1450 PS, Sched<[WriteBSFLd]>;
1452 def BSR16rr : I<0xBD, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
1453 "bsr{w}\t{$src, $dst|$dst, $src}",
1454 [(set GR16:$dst, EFLAGS, (X86bsr GR16:$src))]>,
1455 PS, OpSize16, Sched<[WriteBSR]>;
1456 def BSR16rm : I<0xBD, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
1457 "bsr{w}\t{$src, $dst|$dst, $src}",
1458 [(set GR16:$dst, EFLAGS, (X86bsr (loadi16 addr:$src)))]>,
1459 PS, OpSize16, Sched<[WriteBSRLd]>;
1460 def BSR32rr : I<0xBD, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
1461 "bsr{l}\t{$src, $dst|$dst, $src}",
1462 [(set GR32:$dst, EFLAGS, (X86bsr GR32:$src))]>,
1463 PS, OpSize32, Sched<[WriteBSR]>;
1464 def BSR32rm : I<0xBD, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
1465 "bsr{l}\t{$src, $dst|$dst, $src}",
1466 [(set GR32:$dst, EFLAGS, (X86bsr (loadi32 addr:$src)))]>,
1467 PS, OpSize32, Sched<[WriteBSRLd]>;
1468 def BSR64rr : RI<0xBD, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
1469 "bsr{q}\t{$src, $dst|$dst, $src}",
1470 [(set GR64:$dst, EFLAGS, (X86bsr GR64:$src))]>,
1471 PS, Sched<[WriteBSR]>;
1472 def BSR64rm : RI<0xBD, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
1473 "bsr{q}\t{$src, $dst|$dst, $src}",
1474 [(set GR64:$dst, EFLAGS, (X86bsr (loadi64 addr:$src)))]>,
1475 PS, Sched<[WriteBSRLd]>;
1476 } // Defs = [EFLAGS]
1478 let SchedRW = [WriteMicrocoded] in {
1479 let Defs = [EDI,ESI], Uses = [EDI,ESI,DF] in {
1480 def MOVSB : I<0xA4, RawFrmDstSrc, (outs), (ins dstidx8:$dst, srcidx8:$src),
1481 "movsb\t{$src, $dst|$dst, $src}", []>;
1482 def MOVSW : I<0xA5, RawFrmDstSrc, (outs), (ins dstidx16:$dst, srcidx16:$src),
1483 "movsw\t{$src, $dst|$dst, $src}", []>, OpSize16;
1484 def MOVSL : I<0xA5, RawFrmDstSrc, (outs), (ins dstidx32:$dst, srcidx32:$src),
1485 "movs{l|d}\t{$src, $dst|$dst, $src}", []>, OpSize32;
1486 def MOVSQ : RI<0xA5, RawFrmDstSrc, (outs), (ins dstidx64:$dst, srcidx64:$src),
1487 "movsq\t{$src, $dst|$dst, $src}", []>,
1488 Requires<[In64BitMode]>;
1491 let Defs = [EDI], Uses = [AL,EDI,DF] in
1492 def STOSB : I<0xAA, RawFrmDst, (outs), (ins dstidx8:$dst),
1493 "stosb\t{%al, $dst|$dst, al}", []>;
1494 let Defs = [EDI], Uses = [AX,EDI,DF] in
1495 def STOSW : I<0xAB, RawFrmDst, (outs), (ins dstidx16:$dst),
1496 "stosw\t{%ax, $dst|$dst, ax}", []>, OpSize16;
1497 let Defs = [EDI], Uses = [EAX,EDI,DF] in
1498 def STOSL : I<0xAB, RawFrmDst, (outs), (ins dstidx32:$dst),
1499 "stos{l|d}\t{%eax, $dst|$dst, eax}", []>, OpSize32;
1500 let Defs = [RDI], Uses = [RAX,RDI,DF] in
1501 def STOSQ : RI<0xAB, RawFrmDst, (outs), (ins dstidx64:$dst),
1502 "stosq\t{%rax, $dst|$dst, rax}", []>,
1503 Requires<[In64BitMode]>;
1505 let Defs = [EDI,EFLAGS], Uses = [AL,EDI,DF] in
1506 def SCASB : I<0xAE, RawFrmDst, (outs), (ins dstidx8:$dst),
1507 "scasb\t{$dst, %al|al, $dst}", []>;
1508 let Defs = [EDI,EFLAGS], Uses = [AX,EDI,DF] in
1509 def SCASW : I<0xAF, RawFrmDst, (outs), (ins dstidx16:$dst),
1510 "scasw\t{$dst, %ax|ax, $dst}", []>, OpSize16;
1511 let Defs = [EDI,EFLAGS], Uses = [EAX,EDI,DF] in
1512 def SCASL : I<0xAF, RawFrmDst, (outs), (ins dstidx32:$dst),
1513 "scas{l|d}\t{$dst, %eax|eax, $dst}", []>, OpSize32;
1514 let Defs = [EDI,EFLAGS], Uses = [RAX,EDI,DF] in
1515 def SCASQ : RI<0xAF, RawFrmDst, (outs), (ins dstidx64:$dst),
1516 "scasq\t{$dst, %rax|rax, $dst}", []>,
1517 Requires<[In64BitMode]>;
1519 let Defs = [EDI,ESI,EFLAGS], Uses = [EDI,ESI,DF] in {
1520 def CMPSB : I<0xA6, RawFrmDstSrc, (outs), (ins dstidx8:$dst, srcidx8:$src),
1521 "cmpsb\t{$dst, $src|$src, $dst}", []>;
1522 def CMPSW : I<0xA7, RawFrmDstSrc, (outs), (ins dstidx16:$dst, srcidx16:$src),
1523 "cmpsw\t{$dst, $src|$src, $dst}", []>, OpSize16;
1524 def CMPSL : I<0xA7, RawFrmDstSrc, (outs), (ins dstidx32:$dst, srcidx32:$src),
1525 "cmps{l|d}\t{$dst, $src|$src, $dst}", []>, OpSize32;
1526 def CMPSQ : RI<0xA7, RawFrmDstSrc, (outs), (ins dstidx64:$dst, srcidx64:$src),
1527 "cmpsq\t{$dst, $src|$src, $dst}", []>,
1528 Requires<[In64BitMode]>;
1532 //===----------------------------------------------------------------------===//
1533 // Move Instructions.
1535 let SchedRW = [WriteMove] in {
1536 let hasSideEffects = 0, isMoveReg = 1 in {
1537 def MOV8rr : I<0x88, MRMDestReg, (outs GR8 :$dst), (ins GR8 :$src),
1538 "mov{b}\t{$src, $dst|$dst, $src}", []>;
1539 def MOV16rr : I<0x89, MRMDestReg, (outs GR16:$dst), (ins GR16:$src),
1540 "mov{w}\t{$src, $dst|$dst, $src}", []>, OpSize16;
1541 def MOV32rr : I<0x89, MRMDestReg, (outs GR32:$dst), (ins GR32:$src),
1542 "mov{l}\t{$src, $dst|$dst, $src}", []>, OpSize32;
1543 def MOV64rr : RI<0x89, MRMDestReg, (outs GR64:$dst), (ins GR64:$src),
1544 "mov{q}\t{$src, $dst|$dst, $src}", []>;
1547 let isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in {
1548 def MOV8ri : Ii8 <0xB0, AddRegFrm, (outs GR8 :$dst), (ins i8imm :$src),
1549 "mov{b}\t{$src, $dst|$dst, $src}",
1550 [(set GR8:$dst, imm:$src)]>;
1551 def MOV16ri : Ii16<0xB8, AddRegFrm, (outs GR16:$dst), (ins i16imm:$src),
1552 "mov{w}\t{$src, $dst|$dst, $src}",
1553 [(set GR16:$dst, imm:$src)]>, OpSize16;
1554 def MOV32ri : Ii32<0xB8, AddRegFrm, (outs GR32:$dst), (ins i32imm:$src),
1555 "mov{l}\t{$src, $dst|$dst, $src}",
1556 [(set GR32:$dst, relocImm:$src)]>, OpSize32;
1557 def MOV64ri32 : RIi32S<0xC7, MRM0r, (outs GR64:$dst), (ins i64i32imm:$src),
1558 "mov{q}\t{$src, $dst|$dst, $src}",
1559 [(set GR64:$dst, i64immSExt32:$src)]>;
1561 let isReMaterializable = 1, isMoveImm = 1 in {
1562 def MOV64ri : RIi64<0xB8, AddRegFrm, (outs GR64:$dst), (ins i64imm:$src),
1563 "movabs{q}\t{$src, $dst|$dst, $src}",
1564 [(set GR64:$dst, relocImm:$src)]>;
1567 // Longer forms that use a ModR/M byte. Needed for disassembler
1568 let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0 in {
1569 def MOV8ri_alt : Ii8 <0xC6, MRM0r, (outs GR8 :$dst), (ins i8imm :$src),
1570 "mov{b}\t{$src, $dst|$dst, $src}", []>,
1571 FoldGenData<"MOV8ri">;
1572 def MOV16ri_alt : Ii16<0xC7, MRM0r, (outs GR16:$dst), (ins i16imm:$src),
1573 "mov{w}\t{$src, $dst|$dst, $src}", []>, OpSize16,
1574 FoldGenData<"MOV16ri">;
1575 def MOV32ri_alt : Ii32<0xC7, MRM0r, (outs GR32:$dst), (ins i32imm:$src),
1576 "mov{l}\t{$src, $dst|$dst, $src}", []>, OpSize32,
1577 FoldGenData<"MOV32ri">;
1581 let SchedRW = [WriteStore] in {
1582 def MOV8mi : Ii8 <0xC6, MRM0m, (outs), (ins i8mem :$dst, i8imm :$src),
1583 "mov{b}\t{$src, $dst|$dst, $src}",
1584 [(store (i8 relocImm8_su:$src), addr:$dst)]>;
1585 def MOV16mi : Ii16<0xC7, MRM0m, (outs), (ins i16mem:$dst, i16imm:$src),
1586 "mov{w}\t{$src, $dst|$dst, $src}",
1587 [(store (i16 relocImm16_su:$src), addr:$dst)]>, OpSize16;
1588 def MOV32mi : Ii32<0xC7, MRM0m, (outs), (ins i32mem:$dst, i32imm:$src),
1589 "mov{l}\t{$src, $dst|$dst, $src}",
1590 [(store (i32 relocImm32_su:$src), addr:$dst)]>, OpSize32;
1591 def MOV64mi32 : RIi32S<0xC7, MRM0m, (outs), (ins i64mem:$dst, i64i32imm:$src),
1592 "mov{q}\t{$src, $dst|$dst, $src}",
1593 [(store i64relocImmSExt32_su:$src, addr:$dst)]>,
1594 Requires<[In64BitMode]>;
1597 let hasSideEffects = 0 in {
1599 /// Memory offset versions of moves. The immediate is an address mode sized
1600 /// offset from the segment base.
1601 let SchedRW = [WriteALU] in {
1602 let mayLoad = 1 in {
1604 def MOV8ao32 : Ii32<0xA0, RawFrmMemOffs, (outs), (ins offset32_8:$src),
1605 "mov{b}\t{$src, %al|al, $src}", []>,
1608 def MOV16ao32 : Ii32<0xA1, RawFrmMemOffs, (outs), (ins offset32_16:$src),
1609 "mov{w}\t{$src, %ax|ax, $src}", []>,
1612 def MOV32ao32 : Ii32<0xA1, RawFrmMemOffs, (outs), (ins offset32_32:$src),
1613 "mov{l}\t{$src, %eax|eax, $src}", []>,
1616 def MOV64ao32 : RIi32<0xA1, RawFrmMemOffs, (outs), (ins offset32_64:$src),
1617 "mov{q}\t{$src, %rax|rax, $src}", []>,
1621 def MOV8ao16 : Ii16<0xA0, RawFrmMemOffs, (outs), (ins offset16_8:$src),
1622 "mov{b}\t{$src, %al|al, $src}", []>, AdSize16;
1624 def MOV16ao16 : Ii16<0xA1, RawFrmMemOffs, (outs), (ins offset16_16:$src),
1625 "mov{w}\t{$src, %ax|ax, $src}", []>,
1628 def MOV32ao16 : Ii16<0xA1, RawFrmMemOffs, (outs), (ins offset16_32:$src),
1629 "mov{l}\t{$src, %eax|eax, $src}", []>,
1632 let mayStore = 1 in {
1634 def MOV8o32a : Ii32<0xA2, RawFrmMemOffs, (outs), (ins offset32_8:$dst),
1635 "mov{b}\t{%al, $dst|$dst, al}", []>, AdSize32;
1637 def MOV16o32a : Ii32<0xA3, RawFrmMemOffs, (outs), (ins offset32_16:$dst),
1638 "mov{w}\t{%ax, $dst|$dst, ax}", []>,
1641 def MOV32o32a : Ii32<0xA3, RawFrmMemOffs, (outs), (ins offset32_32:$dst),
1642 "mov{l}\t{%eax, $dst|$dst, eax}", []>,
1645 def MOV64o32a : RIi32<0xA3, RawFrmMemOffs, (outs), (ins offset32_64:$dst),
1646 "mov{q}\t{%rax, $dst|$dst, rax}", []>,
1650 def MOV8o16a : Ii16<0xA2, RawFrmMemOffs, (outs), (ins offset16_8:$dst),
1651 "mov{b}\t{%al, $dst|$dst, al}", []>, AdSize16;
1653 def MOV16o16a : Ii16<0xA3, RawFrmMemOffs, (outs), (ins offset16_16:$dst),
1654 "mov{w}\t{%ax, $dst|$dst, ax}", []>,
1657 def MOV32o16a : Ii16<0xA3, RawFrmMemOffs, (outs), (ins offset16_32:$dst),
1658 "mov{l}\t{%eax, $dst|$dst, eax}", []>,
1662 // These forms all have full 64-bit absolute addresses in their instructions
1663 // and use the movabs mnemonic to indicate this specific form.
1664 let mayLoad = 1 in {
1666 def MOV8ao64 : Ii64<0xA0, RawFrmMemOffs, (outs), (ins offset64_8:$src),
1667 "movabs{b}\t{$src, %al|al, $src}", []>,
1670 def MOV16ao64 : Ii64<0xA1, RawFrmMemOffs, (outs), (ins offset64_16:$src),
1671 "movabs{w}\t{$src, %ax|ax, $src}", []>,
1674 def MOV32ao64 : Ii64<0xA1, RawFrmMemOffs, (outs), (ins offset64_32:$src),
1675 "movabs{l}\t{$src, %eax|eax, $src}", []>,
1678 def MOV64ao64 : RIi64<0xA1, RawFrmMemOffs, (outs), (ins offset64_64:$src),
1679 "movabs{q}\t{$src, %rax|rax, $src}", []>,
1683 let mayStore = 1 in {
1685 def MOV8o64a : Ii64<0xA2, RawFrmMemOffs, (outs), (ins offset64_8:$dst),
1686 "movabs{b}\t{%al, $dst|$dst, al}", []>,
1689 def MOV16o64a : Ii64<0xA3, RawFrmMemOffs, (outs), (ins offset64_16:$dst),
1690 "movabs{w}\t{%ax, $dst|$dst, ax}", []>,
1693 def MOV32o64a : Ii64<0xA3, RawFrmMemOffs, (outs), (ins offset64_32:$dst),
1694 "movabs{l}\t{%eax, $dst|$dst, eax}", []>,
1697 def MOV64o64a : RIi64<0xA3, RawFrmMemOffs, (outs), (ins offset64_64:$dst),
1698 "movabs{q}\t{%rax, $dst|$dst, rax}", []>,
1702 } // hasSideEffects = 0
1704 let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0,
1705 SchedRW = [WriteMove], isMoveReg = 1 in {
1706 def MOV8rr_REV : I<0x8A, MRMSrcReg, (outs GR8:$dst), (ins GR8:$src),
1707 "mov{b}\t{$src, $dst|$dst, $src}", []>,
1708 FoldGenData<"MOV8rr">;
1709 def MOV16rr_REV : I<0x8B, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
1710 "mov{w}\t{$src, $dst|$dst, $src}", []>, OpSize16,
1711 FoldGenData<"MOV16rr">;
1712 def MOV32rr_REV : I<0x8B, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
1713 "mov{l}\t{$src, $dst|$dst, $src}", []>, OpSize32,
1714 FoldGenData<"MOV32rr">;
1715 def MOV64rr_REV : RI<0x8B, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
1716 "mov{q}\t{$src, $dst|$dst, $src}", []>,
1717 FoldGenData<"MOV64rr">;
1720 // Reversed version with ".s" suffix for GAS compatibility.
1721 def : InstAlias<"mov{b}.s\t{$src, $dst|$dst, $src}",
1722 (MOV8rr_REV GR8:$dst, GR8:$src), 0>;
1723 def : InstAlias<"mov{w}.s\t{$src, $dst|$dst, $src}",
1724 (MOV16rr_REV GR16:$dst, GR16:$src), 0>;
1725 def : InstAlias<"mov{l}.s\t{$src, $dst|$dst, $src}",
1726 (MOV32rr_REV GR32:$dst, GR32:$src), 0>;
1727 def : InstAlias<"mov{q}.s\t{$src, $dst|$dst, $src}",
1728 (MOV64rr_REV GR64:$dst, GR64:$src), 0>;
1729 def : InstAlias<"mov.s\t{$src, $dst|$dst, $src}",
1730 (MOV8rr_REV GR8:$dst, GR8:$src), 0, "att">;
1731 def : InstAlias<"mov.s\t{$src, $dst|$dst, $src}",
1732 (MOV16rr_REV GR16:$dst, GR16:$src), 0, "att">;
1733 def : InstAlias<"mov.s\t{$src, $dst|$dst, $src}",
1734 (MOV32rr_REV GR32:$dst, GR32:$src), 0, "att">;
1735 def : InstAlias<"mov.s\t{$src, $dst|$dst, $src}",
1736 (MOV64rr_REV GR64:$dst, GR64:$src), 0, "att">;
1738 let canFoldAsLoad = 1, isReMaterializable = 1, SchedRW = [WriteLoad] in {
1739 def MOV8rm : I<0x8A, MRMSrcMem, (outs GR8 :$dst), (ins i8mem :$src),
1740 "mov{b}\t{$src, $dst|$dst, $src}",
1741 [(set GR8:$dst, (loadi8 addr:$src))]>;
1742 def MOV16rm : I<0x8B, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
1743 "mov{w}\t{$src, $dst|$dst, $src}",
1744 [(set GR16:$dst, (loadi16 addr:$src))]>, OpSize16;
1745 def MOV32rm : I<0x8B, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
1746 "mov{l}\t{$src, $dst|$dst, $src}",
1747 [(set GR32:$dst, (loadi32 addr:$src))]>, OpSize32;
1748 def MOV64rm : RI<0x8B, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
1749 "mov{q}\t{$src, $dst|$dst, $src}",
1750 [(set GR64:$dst, (load addr:$src))]>;
1753 let SchedRW = [WriteStore] in {
1754 def MOV8mr : I<0x88, MRMDestMem, (outs), (ins i8mem :$dst, GR8 :$src),
1755 "mov{b}\t{$src, $dst|$dst, $src}",
1756 [(store GR8:$src, addr:$dst)]>;
1757 def MOV16mr : I<0x89, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src),
1758 "mov{w}\t{$src, $dst|$dst, $src}",
1759 [(store GR16:$src, addr:$dst)]>, OpSize16;
1760 def MOV32mr : I<0x89, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
1761 "mov{l}\t{$src, $dst|$dst, $src}",
1762 [(store GR32:$src, addr:$dst)]>, OpSize32;
1763 def MOV64mr : RI<0x89, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
1764 "mov{q}\t{$src, $dst|$dst, $src}",
1765 [(store GR64:$src, addr:$dst)]>;
1768 // Versions of MOV8rr, MOV8mr, and MOV8rm that use i8mem_NOREX and GR8_NOREX so
1769 // that they can be used for copying and storing h registers, which can't be
1770 // encoded when a REX prefix is present.
1771 let isCodeGenOnly = 1 in {
1772 let hasSideEffects = 0, isMoveReg = 1 in
1773 def MOV8rr_NOREX : I<0x88, MRMDestReg,
1774 (outs GR8_NOREX:$dst), (ins GR8_NOREX:$src),
1775 "mov{b}\t{$src, $dst|$dst, $src}", []>,
1777 let mayStore = 1, hasSideEffects = 0 in
1778 def MOV8mr_NOREX : I<0x88, MRMDestMem,
1779 (outs), (ins i8mem_NOREX:$dst, GR8_NOREX:$src),
1780 "mov{b}\t{$src, $dst|$dst, $src}", []>,
1781 Sched<[WriteStore]>;
1782 let mayLoad = 1, hasSideEffects = 0,
1783 canFoldAsLoad = 1, isReMaterializable = 1 in
1784 def MOV8rm_NOREX : I<0x8A, MRMSrcMem,
1785 (outs GR8_NOREX:$dst), (ins i8mem_NOREX:$src),
1786 "mov{b}\t{$src, $dst|$dst, $src}", []>,
1791 // Condition code ops, incl. set if equal/not equal/...
1792 let SchedRW = [WriteLAHFSAHF] in {
1793 let Defs = [EFLAGS], Uses = [AH] in
1794 def SAHF : I<0x9E, RawFrm, (outs), (ins), "sahf",
1795 [(set EFLAGS, (X86sahf AH))]>,
1796 Requires<[HasLAHFSAHF]>;
1797 let Defs = [AH], Uses = [EFLAGS], hasSideEffects = 0 in
1798 def LAHF : I<0x9F, RawFrm, (outs), (ins), "lahf", []>, // AH = flags
1799 Requires<[HasLAHFSAHF]>;
1802 //===----------------------------------------------------------------------===//
1803 // Bit tests instructions: BT, BTS, BTR, BTC.
1805 let Defs = [EFLAGS] in {
1806 let SchedRW = [WriteBitTest] in {
1807 def BT16rr : I<0xA3, MRMDestReg, (outs), (ins GR16:$src1, GR16:$src2),
1808 "bt{w}\t{$src2, $src1|$src1, $src2}",
1809 [(set EFLAGS, (X86bt GR16:$src1, GR16:$src2))]>,
1810 OpSize16, TB, NotMemoryFoldable;
1811 def BT32rr : I<0xA3, MRMDestReg, (outs), (ins GR32:$src1, GR32:$src2),
1812 "bt{l}\t{$src2, $src1|$src1, $src2}",
1813 [(set EFLAGS, (X86bt GR32:$src1, GR32:$src2))]>,
1814 OpSize32, TB, NotMemoryFoldable;
1815 def BT64rr : RI<0xA3, MRMDestReg, (outs), (ins GR64:$src1, GR64:$src2),
1816 "bt{q}\t{$src2, $src1|$src1, $src2}",
1817 [(set EFLAGS, (X86bt GR64:$src1, GR64:$src2))]>, TB,
1821 // Unlike with the register+register form, the memory+register form of the
1822 // bt instruction does not ignore the high bits of the index. From ISel's
1823 // perspective, this is pretty bizarre. Make these instructions disassembly
1824 // only for now. These instructions are also slow on modern CPUs so that's
1825 // another reason to avoid generating them.
1827 let mayLoad = 1, hasSideEffects = 0, SchedRW = [WriteBitTestRegLd] in {
1828 def BT16mr : I<0xA3, MRMDestMem, (outs), (ins i16mem:$src1, GR16:$src2),
1829 "bt{w}\t{$src2, $src1|$src1, $src2}",
1830 []>, OpSize16, TB, NotMemoryFoldable;
1831 def BT32mr : I<0xA3, MRMDestMem, (outs), (ins i32mem:$src1, GR32:$src2),
1832 "bt{l}\t{$src2, $src1|$src1, $src2}",
1833 []>, OpSize32, TB, NotMemoryFoldable;
1834 def BT64mr : RI<0xA3, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2),
1835 "bt{q}\t{$src2, $src1|$src1, $src2}",
1836 []>, TB, NotMemoryFoldable;
1839 let SchedRW = [WriteBitTest] in {
1840 def BT16ri8 : Ii8<0xBA, MRM4r, (outs), (ins GR16:$src1, i16u8imm:$src2),
1841 "bt{w}\t{$src2, $src1|$src1, $src2}",
1842 [(set EFLAGS, (X86bt GR16:$src1, imm:$src2))]>,
1844 def BT32ri8 : Ii8<0xBA, MRM4r, (outs), (ins GR32:$src1, i32u8imm:$src2),
1845 "bt{l}\t{$src2, $src1|$src1, $src2}",
1846 [(set EFLAGS, (X86bt GR32:$src1, imm:$src2))]>,
1848 def BT64ri8 : RIi8<0xBA, MRM4r, (outs), (ins GR64:$src1, i64u8imm:$src2),
1849 "bt{q}\t{$src2, $src1|$src1, $src2}",
1850 [(set EFLAGS, (X86bt GR64:$src1, imm:$src2))]>, TB;
1853 // Note that these instructions aren't slow because that only applies when the
1854 // other operand is in a register. When it's an immediate, bt is still fast.
1855 let SchedRW = [WriteBitTestImmLd] in {
1856 def BT16mi8 : Ii8<0xBA, MRM4m, (outs), (ins i16mem:$src1, i16u8imm:$src2),
1857 "bt{w}\t{$src2, $src1|$src1, $src2}",
1858 [(set EFLAGS, (X86bt (loadi16 addr:$src1),
1861 def BT32mi8 : Ii8<0xBA, MRM4m, (outs), (ins i32mem:$src1, i32u8imm:$src2),
1862 "bt{l}\t{$src2, $src1|$src1, $src2}",
1863 [(set EFLAGS, (X86bt (loadi32 addr:$src1),
1866 def BT64mi8 : RIi8<0xBA, MRM4m, (outs), (ins i64mem:$src1, i64u8imm:$src2),
1867 "bt{q}\t{$src2, $src1|$src1, $src2}",
1868 [(set EFLAGS, (X86bt (loadi64 addr:$src1),
1870 Requires<[In64BitMode]>;
1873 let hasSideEffects = 0 in {
1874 let SchedRW = [WriteBitTestSet], Constraints = "$src1 = $dst" in {
1875 def BTC16rr : I<0xBB, MRMDestReg, (outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
1876 "btc{w}\t{$src2, $src1|$src1, $src2}", []>,
1877 OpSize16, TB, NotMemoryFoldable;
1878 def BTC32rr : I<0xBB, MRMDestReg, (outs GR32:$dst), (ins GR32:$src1, GR32:$src2),
1879 "btc{l}\t{$src2, $src1|$src1, $src2}", []>,
1880 OpSize32, TB, NotMemoryFoldable;
1881 def BTC64rr : RI<0xBB, MRMDestReg, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
1882 "btc{q}\t{$src2, $src1|$src1, $src2}", []>, TB,
1886 let mayLoad = 1, mayStore = 1, SchedRW = [WriteBitTestSetRegRMW] in {
1887 def BTC16mr : I<0xBB, MRMDestMem, (outs), (ins i16mem:$src1, GR16:$src2),
1888 "btc{w}\t{$src2, $src1|$src1, $src2}", []>,
1889 OpSize16, TB, NotMemoryFoldable;
1890 def BTC32mr : I<0xBB, MRMDestMem, (outs), (ins i32mem:$src1, GR32:$src2),
1891 "btc{l}\t{$src2, $src1|$src1, $src2}", []>,
1892 OpSize32, TB, NotMemoryFoldable;
1893 def BTC64mr : RI<0xBB, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2),
1894 "btc{q}\t{$src2, $src1|$src1, $src2}", []>, TB,
1898 let SchedRW = [WriteBitTestSet], Constraints = "$src1 = $dst" in {
1899 def BTC16ri8 : Ii8<0xBA, MRM7r, (outs GR16:$dst), (ins GR16:$src1, i16u8imm:$src2),
1900 "btc{w}\t{$src2, $src1|$src1, $src2}", []>, OpSize16, TB;
1901 def BTC32ri8 : Ii8<0xBA, MRM7r, (outs GR32:$dst), (ins GR32:$src1, i32u8imm:$src2),
1902 "btc{l}\t{$src2, $src1|$src1, $src2}", []>, OpSize32, TB;
1903 def BTC64ri8 : RIi8<0xBA, MRM7r, (outs GR64:$dst), (ins GR64:$src1, i64u8imm:$src2),
1904 "btc{q}\t{$src2, $src1|$src1, $src2}", []>, TB;
1907 let mayLoad = 1, mayStore = 1, SchedRW = [WriteBitTestSetImmRMW] in {
1908 def BTC16mi8 : Ii8<0xBA, MRM7m, (outs), (ins i16mem:$src1, i16u8imm:$src2),
1909 "btc{w}\t{$src2, $src1|$src1, $src2}", []>, OpSize16, TB;
1910 def BTC32mi8 : Ii8<0xBA, MRM7m, (outs), (ins i32mem:$src1, i32u8imm:$src2),
1911 "btc{l}\t{$src2, $src1|$src1, $src2}", []>, OpSize32, TB;
1912 def BTC64mi8 : RIi8<0xBA, MRM7m, (outs), (ins i64mem:$src1, i64u8imm:$src2),
1913 "btc{q}\t{$src2, $src1|$src1, $src2}", []>, TB,
1914 Requires<[In64BitMode]>;
1917 let SchedRW = [WriteBitTestSet], Constraints = "$src1 = $dst" in {
1918 def BTR16rr : I<0xB3, MRMDestReg, (outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
1919 "btr{w}\t{$src2, $src1|$src1, $src2}", []>,
1920 OpSize16, TB, NotMemoryFoldable;
1921 def BTR32rr : I<0xB3, MRMDestReg, (outs GR32:$dst), (ins GR32:$src1, GR32:$src2),
1922 "btr{l}\t{$src2, $src1|$src1, $src2}", []>,
1923 OpSize32, TB, NotMemoryFoldable;
1924 def BTR64rr : RI<0xB3, MRMDestReg, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
1925 "btr{q}\t{$src2, $src1|$src1, $src2}", []>, TB,
1929 let mayLoad = 1, mayStore = 1, SchedRW = [WriteBitTestSetRegRMW] in {
1930 def BTR16mr : I<0xB3, MRMDestMem, (outs), (ins i16mem:$src1, GR16:$src2),
1931 "btr{w}\t{$src2, $src1|$src1, $src2}", []>,
1932 OpSize16, TB, NotMemoryFoldable;
1933 def BTR32mr : I<0xB3, MRMDestMem, (outs), (ins i32mem:$src1, GR32:$src2),
1934 "btr{l}\t{$src2, $src1|$src1, $src2}", []>,
1935 OpSize32, TB, NotMemoryFoldable;
1936 def BTR64mr : RI<0xB3, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2),
1937 "btr{q}\t{$src2, $src1|$src1, $src2}", []>, TB,
1941 let SchedRW = [WriteBitTestSet], Constraints = "$src1 = $dst" in {
1942 def BTR16ri8 : Ii8<0xBA, MRM6r, (outs GR16:$dst), (ins GR16:$src1, i16u8imm:$src2),
1943 "btr{w}\t{$src2, $src1|$src1, $src2}", []>,
1945 def BTR32ri8 : Ii8<0xBA, MRM6r, (outs GR32:$dst), (ins GR32:$src1, i32u8imm:$src2),
1946 "btr{l}\t{$src2, $src1|$src1, $src2}", []>,
1948 def BTR64ri8 : RIi8<0xBA, MRM6r, (outs GR64:$dst), (ins GR64:$src1, i64u8imm:$src2),
1949 "btr{q}\t{$src2, $src1|$src1, $src2}", []>, TB;
1952 let mayLoad = 1, mayStore = 1, SchedRW = [WriteBitTestSetImmRMW] in {
1953 def BTR16mi8 : Ii8<0xBA, MRM6m, (outs), (ins i16mem:$src1, i16u8imm:$src2),
1954 "btr{w}\t{$src2, $src1|$src1, $src2}", []>,
1956 def BTR32mi8 : Ii8<0xBA, MRM6m, (outs), (ins i32mem:$src1, i32u8imm:$src2),
1957 "btr{l}\t{$src2, $src1|$src1, $src2}", []>,
1959 def BTR64mi8 : RIi8<0xBA, MRM6m, (outs), (ins i64mem:$src1, i64u8imm:$src2),
1960 "btr{q}\t{$src2, $src1|$src1, $src2}", []>, TB,
1961 Requires<[In64BitMode]>;
1964 let SchedRW = [WriteBitTestSet], Constraints = "$src1 = $dst" in {
1965 def BTS16rr : I<0xAB, MRMDestReg, (outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
1966 "bts{w}\t{$src2, $src1|$src1, $src2}", []>,
1967 OpSize16, TB, NotMemoryFoldable;
1968 def BTS32rr : I<0xAB, MRMDestReg, (outs GR32:$dst), (ins GR32:$src1, GR32:$src2),
1969 "bts{l}\t{$src2, $src1|$src1, $src2}", []>,
1970 OpSize32, TB, NotMemoryFoldable;
1971 def BTS64rr : RI<0xAB, MRMDestReg, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
1972 "bts{q}\t{$src2, $src1|$src1, $src2}", []>, TB,
1976 let mayLoad = 1, mayStore = 1, SchedRW = [WriteBitTestSetRegRMW] in {
1977 def BTS16mr : I<0xAB, MRMDestMem, (outs), (ins i16mem:$src1, GR16:$src2),
1978 "bts{w}\t{$src2, $src1|$src1, $src2}", []>,
1979 OpSize16, TB, NotMemoryFoldable;
1980 def BTS32mr : I<0xAB, MRMDestMem, (outs), (ins i32mem:$src1, GR32:$src2),
1981 "bts{l}\t{$src2, $src1|$src1, $src2}", []>,
1982 OpSize32, TB, NotMemoryFoldable;
1983 def BTS64mr : RI<0xAB, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2),
1984 "bts{q}\t{$src2, $src1|$src1, $src2}", []>, TB,
1988 let SchedRW = [WriteBitTestSet], Constraints = "$src1 = $dst" in {
1989 def BTS16ri8 : Ii8<0xBA, MRM5r, (outs GR16:$dst), (ins GR16:$src1, i16u8imm:$src2),
1990 "bts{w}\t{$src2, $src1|$src1, $src2}", []>, OpSize16, TB;
1991 def BTS32ri8 : Ii8<0xBA, MRM5r, (outs GR32:$dst), (ins GR32:$src1, i32u8imm:$src2),
1992 "bts{l}\t{$src2, $src1|$src1, $src2}", []>, OpSize32, TB;
1993 def BTS64ri8 : RIi8<0xBA, MRM5r, (outs GR64:$dst), (ins GR64:$src1, i64u8imm:$src2),
1994 "bts{q}\t{$src2, $src1|$src1, $src2}", []>, TB;
1997 let mayLoad = 1, mayStore = 1, SchedRW = [WriteBitTestSetImmRMW] in {
1998 def BTS16mi8 : Ii8<0xBA, MRM5m, (outs), (ins i16mem:$src1, i16u8imm:$src2),
1999 "bts{w}\t{$src2, $src1|$src1, $src2}", []>, OpSize16, TB;
2000 def BTS32mi8 : Ii8<0xBA, MRM5m, (outs), (ins i32mem:$src1, i32u8imm:$src2),
2001 "bts{l}\t{$src2, $src1|$src1, $src2}", []>, OpSize32, TB;
2002 def BTS64mi8 : RIi8<0xBA, MRM5m, (outs), (ins i64mem:$src1, i64u8imm:$src2),
2003 "bts{q}\t{$src2, $src1|$src1, $src2}", []>, TB,
2004 Requires<[In64BitMode]>;
2006 } // hasSideEffects = 0
2007 } // Defs = [EFLAGS]
2010 //===----------------------------------------------------------------------===//
2014 // Atomic swap. These are just normal xchg instructions. But since a memory
2015 // operand is referenced, the atomicity is ensured.
2016 multiclass ATOMIC_SWAP<bits<8> opc8, bits<8> opc, string mnemonic, string frag> {
2017 let Constraints = "$val = $dst", SchedRW = [WriteALULd, WriteRMW] in {
2018 def NAME#8rm : I<opc8, MRMSrcMem, (outs GR8:$dst),
2019 (ins GR8:$val, i8mem:$ptr),
2020 !strconcat(mnemonic, "{b}\t{$val, $ptr|$ptr, $val}"),
2023 (!cast<PatFrag>(frag # "_8") addr:$ptr, GR8:$val))]>;
2024 def NAME#16rm : I<opc, MRMSrcMem, (outs GR16:$dst),
2025 (ins GR16:$val, i16mem:$ptr),
2026 !strconcat(mnemonic, "{w}\t{$val, $ptr|$ptr, $val}"),
2029 (!cast<PatFrag>(frag # "_16") addr:$ptr, GR16:$val))]>,
2031 def NAME#32rm : I<opc, MRMSrcMem, (outs GR32:$dst),
2032 (ins GR32:$val, i32mem:$ptr),
2033 !strconcat(mnemonic, "{l}\t{$val, $ptr|$ptr, $val}"),
2036 (!cast<PatFrag>(frag # "_32") addr:$ptr, GR32:$val))]>,
2038 def NAME#64rm : RI<opc, MRMSrcMem, (outs GR64:$dst),
2039 (ins GR64:$val, i64mem:$ptr),
2040 !strconcat(mnemonic, "{q}\t{$val, $ptr|$ptr, $val}"),
2043 (!cast<PatFrag>(frag # "_64") addr:$ptr, GR64:$val))]>;
2047 defm XCHG : ATOMIC_SWAP<0x86, 0x87, "xchg", "atomic_swap">, NotMemoryFoldable;
2049 // Swap between registers.
2050 let SchedRW = [WriteXCHG] in {
2051 let Constraints = "$src1 = $dst1, $src2 = $dst2", hasSideEffects = 0 in {
2052 def XCHG8rr : I<0x86, MRMSrcReg, (outs GR8:$dst1, GR8:$dst2),
2053 (ins GR8:$src1, GR8:$src2),
2054 "xchg{b}\t{$src2, $src1|$src1, $src2}", []>, NotMemoryFoldable;
2055 def XCHG16rr : I<0x87, MRMSrcReg, (outs GR16:$dst1, GR16:$dst2),
2056 (ins GR16:$src1, GR16:$src2),
2057 "xchg{w}\t{$src2, $src1|$src1, $src2}", []>,
2058 OpSize16, NotMemoryFoldable;
2059 def XCHG32rr : I<0x87, MRMSrcReg, (outs GR32:$dst1, GR32:$dst2),
2060 (ins GR32:$src1, GR32:$src2),
2061 "xchg{l}\t{$src2, $src1|$src1, $src2}", []>,
2062 OpSize32, NotMemoryFoldable;
2063 def XCHG64rr : RI<0x87, MRMSrcReg, (outs GR64:$dst1, GR64:$dst2),
2064 (ins GR64:$src1 ,GR64:$src2),
2065 "xchg{q}\t{$src2, $src1|$src1, $src2}", []>, NotMemoryFoldable;
2068 // Swap between EAX and other registers.
2069 let Constraints = "$src = $dst", hasSideEffects = 0 in {
2070 let Uses = [AX], Defs = [AX] in
2071 def XCHG16ar : I<0x90, AddRegFrm, (outs GR16:$dst), (ins GR16:$src),
2072 "xchg{w}\t{$src, %ax|ax, $src}", []>, OpSize16;
2073 let Uses = [EAX], Defs = [EAX] in
2074 def XCHG32ar : I<0x90, AddRegFrm, (outs GR32:$dst), (ins GR32:$src),
2075 "xchg{l}\t{$src, %eax|eax, $src}", []>, OpSize32;
2076 let Uses = [RAX], Defs = [RAX] in
2077 def XCHG64ar : RI<0x90, AddRegFrm, (outs GR64:$dst), (ins GR64:$src),
2078 "xchg{q}\t{$src, %rax|rax, $src}", []>;
2082 let hasSideEffects = 0, Constraints = "$src1 = $dst1, $src2 = $dst2",
2083 Defs = [EFLAGS], SchedRW = [WriteXCHG] in {
2084 def XADD8rr : I<0xC0, MRMDestReg, (outs GR8:$dst1, GR8:$dst2),
2085 (ins GR8:$src1, GR8:$src2),
2086 "xadd{b}\t{$src2, $src1|$src1, $src2}", []>, TB;
2087 def XADD16rr : I<0xC1, MRMDestReg, (outs GR16:$dst1, GR16:$dst2),
2088 (ins GR16:$src1, GR16:$src2),
2089 "xadd{w}\t{$src2, $src1|$src1, $src2}", []>, TB, OpSize16;
2090 def XADD32rr : I<0xC1, MRMDestReg, (outs GR32:$dst1, GR32:$dst2),
2091 (ins GR32:$src1, GR32:$src2),
2092 "xadd{l}\t{$src2, $src1|$src1, $src2}", []>, TB, OpSize32;
2093 def XADD64rr : RI<0xC1, MRMDestReg, (outs GR64:$dst1, GR64:$dst2),
2094 (ins GR64:$src1, GR64:$src2),
2095 "xadd{q}\t{$src2, $src1|$src1, $src2}", []>, TB;
2098 let mayLoad = 1, mayStore = 1, hasSideEffects = 0, Constraints = "$val = $dst",
2099 Defs = [EFLAGS], SchedRW = [WriteALULd, WriteRMW] in {
2100 def XADD8rm : I<0xC0, MRMSrcMem, (outs GR8:$dst),
2101 (ins GR8:$val, i8mem:$ptr),
2102 "xadd{b}\t{$val, $ptr|$ptr, $val}", []>, TB;
2103 def XADD16rm : I<0xC1, MRMSrcMem, (outs GR16:$dst),
2104 (ins GR16:$val, i16mem:$ptr),
2105 "xadd{w}\t{$val, $ptr|$ptr, $val}", []>, TB,
2107 def XADD32rm : I<0xC1, MRMSrcMem, (outs GR32:$dst),
2108 (ins GR32:$val, i32mem:$ptr),
2109 "xadd{l}\t{$val, $ptr|$ptr, $val}", []>, TB,
2111 def XADD64rm : RI<0xC1, MRMSrcMem, (outs GR64:$dst),
2112 (ins GR64:$val, i64mem:$ptr),
2113 "xadd{q}\t{$val, $ptr|$ptr, $val}", []>, TB;
2117 let SchedRW = [WriteCMPXCHG], hasSideEffects = 0 in {
2118 let Defs = [AL, EFLAGS], Uses = [AL] in
2119 def CMPXCHG8rr : I<0xB0, MRMDestReg, (outs GR8:$dst), (ins GR8:$src),
2120 "cmpxchg{b}\t{$src, $dst|$dst, $src}", []>, TB,
2122 let Defs = [AX, EFLAGS], Uses = [AX] in
2123 def CMPXCHG16rr : I<0xB1, MRMDestReg, (outs GR16:$dst), (ins GR16:$src),
2124 "cmpxchg{w}\t{$src, $dst|$dst, $src}", []>, TB, OpSize16,
2126 let Defs = [EAX, EFLAGS], Uses = [EAX] in
2127 def CMPXCHG32rr : I<0xB1, MRMDestReg, (outs GR32:$dst), (ins GR32:$src),
2128 "cmpxchg{l}\t{$src, $dst|$dst, $src}", []>, TB, OpSize32,
2130 let Defs = [RAX, EFLAGS], Uses = [RAX] in
2131 def CMPXCHG64rr : RI<0xB1, MRMDestReg, (outs GR64:$dst), (ins GR64:$src),
2132 "cmpxchg{q}\t{$src, $dst|$dst, $src}", []>, TB,
2134 } // SchedRW, hasSideEffects
2136 let SchedRW = [WriteCMPXCHGRMW], mayLoad = 1, mayStore = 1,
2137 hasSideEffects = 0 in {
2138 let Defs = [AL, EFLAGS], Uses = [AL] in
2139 def CMPXCHG8rm : I<0xB0, MRMDestMem, (outs), (ins i8mem:$dst, GR8:$src),
2140 "cmpxchg{b}\t{$src, $dst|$dst, $src}", []>, TB,
2142 let Defs = [AX, EFLAGS], Uses = [AX] in
2143 def CMPXCHG16rm : I<0xB1, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src),
2144 "cmpxchg{w}\t{$src, $dst|$dst, $src}", []>, TB, OpSize16,
2146 let Defs = [EAX, EFLAGS], Uses = [EAX] in
2147 def CMPXCHG32rm : I<0xB1, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
2148 "cmpxchg{l}\t{$src, $dst|$dst, $src}", []>, TB, OpSize32,
2150 let Defs = [RAX, EFLAGS], Uses = [RAX] in
2151 def CMPXCHG64rm : RI<0xB1, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
2152 "cmpxchg{q}\t{$src, $dst|$dst, $src}", []>, TB,
2155 let Defs = [EAX, EDX, EFLAGS], Uses = [EAX, EBX, ECX, EDX] in
2156 def CMPXCHG8B : I<0xC7, MRM1m, (outs), (ins i64mem:$dst),
2157 "cmpxchg8b\t$dst", []>, TB, Requires<[HasCmpxchg8b]>;
2159 let Defs = [RAX, RDX, EFLAGS], Uses = [RAX, RBX, RCX, RDX] in
2160 // NOTE: In64BitMode check needed for the AssemblerPredicate.
2161 def CMPXCHG16B : RI<0xC7, MRM1m, (outs), (ins i128mem:$dst),
2162 "cmpxchg16b\t$dst", []>,
2163 TB, Requires<[HasCmpxchg16b,In64BitMode]>;
2164 } // SchedRW, mayLoad, mayStore, hasSideEffects
2167 // Lock instruction prefix
2168 let SchedRW = [WriteMicrocoded] in
2169 def LOCK_PREFIX : I<0xF0, RawFrm, (outs), (ins), "lock", []>;
2171 let SchedRW = [WriteNop] in {
2173 // Rex64 instruction prefix
2174 def REX64_PREFIX : I<0x48, RawFrm, (outs), (ins), "rex64", []>,
2175 Requires<[In64BitMode]>;
2177 // Data16 instruction prefix
2178 def DATA16_PREFIX : I<0x66, RawFrm, (outs), (ins), "data16", []>;
2181 // Repeat string operation instruction prefixes
2182 let Defs = [ECX], Uses = [ECX,DF], SchedRW = [WriteMicrocoded] in {
2183 // Repeat (used with INS, OUTS, MOVS, LODS and STOS)
2184 def REP_PREFIX : I<0xF3, RawFrm, (outs), (ins), "rep", []>;
2185 // Repeat while not equal (used with CMPS and SCAS)
2186 def REPNE_PREFIX : I<0xF2, RawFrm, (outs), (ins), "repne", []>;
2189 // String manipulation instructions
2190 let SchedRW = [WriteMicrocoded] in {
2191 let Defs = [AL,ESI], Uses = [ESI,DF] in
2192 def LODSB : I<0xAC, RawFrmSrc, (outs), (ins srcidx8:$src),
2193 "lodsb\t{$src, %al|al, $src}", []>;
2194 let Defs = [AX,ESI], Uses = [ESI,DF] in
2195 def LODSW : I<0xAD, RawFrmSrc, (outs), (ins srcidx16:$src),
2196 "lodsw\t{$src, %ax|ax, $src}", []>, OpSize16;
2197 let Defs = [EAX,ESI], Uses = [ESI,DF] in
2198 def LODSL : I<0xAD, RawFrmSrc, (outs), (ins srcidx32:$src),
2199 "lods{l|d}\t{$src, %eax|eax, $src}", []>, OpSize32;
2200 let Defs = [RAX,ESI], Uses = [ESI,DF] in
2201 def LODSQ : RI<0xAD, RawFrmSrc, (outs), (ins srcidx64:$src),
2202 "lodsq\t{$src, %rax|rax, $src}", []>,
2203 Requires<[In64BitMode]>;
2206 let SchedRW = [WriteSystem] in {
2207 let Defs = [ESI], Uses = [DX,ESI,DF] in {
2208 def OUTSB : I<0x6E, RawFrmSrc, (outs), (ins srcidx8:$src),
2209 "outsb\t{$src, %dx|dx, $src}", []>;
2210 def OUTSW : I<0x6F, RawFrmSrc, (outs), (ins srcidx16:$src),
2211 "outsw\t{$src, %dx|dx, $src}", []>, OpSize16;
2212 def OUTSL : I<0x6F, RawFrmSrc, (outs), (ins srcidx32:$src),
2213 "outs{l|d}\t{$src, %dx|dx, $src}", []>, OpSize32;
2216 let Defs = [EDI], Uses = [DX,EDI,DF] in {
2217 def INSB : I<0x6C, RawFrmDst, (outs), (ins dstidx8:$dst),
2218 "insb\t{%dx, $dst|$dst, dx}", []>;
2219 def INSW : I<0x6D, RawFrmDst, (outs), (ins dstidx16:$dst),
2220 "insw\t{%dx, $dst|$dst, dx}", []>, OpSize16;
2221 def INSL : I<0x6D, RawFrmDst, (outs), (ins dstidx32:$dst),
2222 "ins{l|d}\t{%dx, $dst|$dst, dx}", []>, OpSize32;
2226 // EFLAGS management instructions.
2227 let SchedRW = [WriteALU], Defs = [EFLAGS], Uses = [EFLAGS] in {
2228 def CLC : I<0xF8, RawFrm, (outs), (ins), "clc", []>;
2229 def STC : I<0xF9, RawFrm, (outs), (ins), "stc", []>;
2230 def CMC : I<0xF5, RawFrm, (outs), (ins), "cmc", []>;
2233 // DF management instructions.
2234 let SchedRW = [WriteALU], Defs = [DF] in {
2235 def CLD : I<0xFC, RawFrm, (outs), (ins), "cld", []>;
2236 def STD : I<0xFD, RawFrm, (outs), (ins), "std", []>;
2239 // Table lookup instructions
2240 let Uses = [AL,EBX], Defs = [AL], hasSideEffects = 0, mayLoad = 1 in
2241 def XLAT : I<0xD7, RawFrm, (outs), (ins), "xlatb", []>, Sched<[WriteLoad]>;
2243 let SchedRW = [WriteMicrocoded] in {
2244 // ASCII Adjust After Addition
2245 let Uses = [AL,EFLAGS], Defs = [AX,EFLAGS], hasSideEffects = 0 in
2246 def AAA : I<0x37, RawFrm, (outs), (ins), "aaa", []>,
2247 Requires<[Not64BitMode]>;
2249 // ASCII Adjust AX Before Division
2250 let Uses = [AX], Defs = [AX,EFLAGS], hasSideEffects = 0 in
2251 def AAD8i8 : Ii8<0xD5, RawFrm, (outs), (ins i8imm:$src),
2252 "aad\t$src", []>, Requires<[Not64BitMode]>;
2254 // ASCII Adjust AX After Multiply
2255 let Uses = [AL], Defs = [AX,EFLAGS], hasSideEffects = 0 in
2256 def AAM8i8 : Ii8<0xD4, RawFrm, (outs), (ins i8imm:$src),
2257 "aam\t$src", []>, Requires<[Not64BitMode]>;
2259 // ASCII Adjust AL After Subtraction - sets
2260 let Uses = [AL,EFLAGS], Defs = [AX,EFLAGS], hasSideEffects = 0 in
2261 def AAS : I<0x3F, RawFrm, (outs), (ins), "aas", []>,
2262 Requires<[Not64BitMode]>;
2264 // Decimal Adjust AL after Addition
2265 let Uses = [AL,EFLAGS], Defs = [AL,EFLAGS], hasSideEffects = 0 in
2266 def DAA : I<0x27, RawFrm, (outs), (ins), "daa", []>,
2267 Requires<[Not64BitMode]>;
2269 // Decimal Adjust AL after Subtraction
2270 let Uses = [AL,EFLAGS], Defs = [AL,EFLAGS], hasSideEffects = 0 in
2271 def DAS : I<0x2F, RawFrm, (outs), (ins), "das", []>,
2272 Requires<[Not64BitMode]>;
2275 let SchedRW = [WriteSystem] in {
2276 // Check Array Index Against Bounds
2277 // Note: "bound" does not have reversed operands in at&t syntax.
2278 def BOUNDS16rm : I<0x62, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
2279 "bound\t$dst, $src", []>, OpSize16,
2280 Requires<[Not64BitMode]>;
2281 def BOUNDS32rm : I<0x62, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
2282 "bound\t$dst, $src", []>, OpSize32,
2283 Requires<[Not64BitMode]>;
2285 // Adjust RPL Field of Segment Selector
2286 def ARPL16rr : I<0x63, MRMDestReg, (outs GR16:$dst), (ins GR16:$src),
2287 "arpl\t{$src, $dst|$dst, $src}", []>,
2288 Requires<[Not64BitMode]>, NotMemoryFoldable;
2290 def ARPL16mr : I<0x63, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src),
2291 "arpl\t{$src, $dst|$dst, $src}", []>,
2292 Requires<[Not64BitMode]>, NotMemoryFoldable;
2295 //===----------------------------------------------------------------------===//
2296 // MOVBE Instructions
2298 let Predicates = [HasMOVBE] in {
2299 let SchedRW = [WriteALULd] in {
2300 def MOVBE16rm : I<0xF0, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
2301 "movbe{w}\t{$src, $dst|$dst, $src}",
2302 [(set GR16:$dst, (bswap (loadi16 addr:$src)))]>,
2304 def MOVBE32rm : I<0xF0, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
2305 "movbe{l}\t{$src, $dst|$dst, $src}",
2306 [(set GR32:$dst, (bswap (loadi32 addr:$src)))]>,
2308 def MOVBE64rm : RI<0xF0, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
2309 "movbe{q}\t{$src, $dst|$dst, $src}",
2310 [(set GR64:$dst, (bswap (loadi64 addr:$src)))]>,
2313 let SchedRW = [WriteStore] in {
2314 def MOVBE16mr : I<0xF1, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src),
2315 "movbe{w}\t{$src, $dst|$dst, $src}",
2316 [(store (bswap GR16:$src), addr:$dst)]>,
2318 def MOVBE32mr : I<0xF1, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
2319 "movbe{l}\t{$src, $dst|$dst, $src}",
2320 [(store (bswap GR32:$src), addr:$dst)]>,
2322 def MOVBE64mr : RI<0xF1, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
2323 "movbe{q}\t{$src, $dst|$dst, $src}",
2324 [(store (bswap GR64:$src), addr:$dst)]>,
2329 //===----------------------------------------------------------------------===//
2330 // RDRAND Instruction
2332 let Predicates = [HasRDRAND], Defs = [EFLAGS], SchedRW = [WriteSystem] in {
2333 def RDRAND16r : I<0xC7, MRM6r, (outs GR16:$dst), (ins),
2334 "rdrand{w}\t$dst", [(set GR16:$dst, EFLAGS, (X86rdrand))]>,
2336 def RDRAND32r : I<0xC7, MRM6r, (outs GR32:$dst), (ins),
2337 "rdrand{l}\t$dst", [(set GR32:$dst, EFLAGS, (X86rdrand))]>,
2339 def RDRAND64r : RI<0xC7, MRM6r, (outs GR64:$dst), (ins),
2340 "rdrand{q}\t$dst", [(set GR64:$dst, EFLAGS, (X86rdrand))]>,
2344 //===----------------------------------------------------------------------===//
2345 // RDSEED Instruction
2347 let Predicates = [HasRDSEED], Defs = [EFLAGS], SchedRW = [WriteSystem] in {
2348 def RDSEED16r : I<0xC7, MRM7r, (outs GR16:$dst), (ins), "rdseed{w}\t$dst",
2349 [(set GR16:$dst, EFLAGS, (X86rdseed))]>, OpSize16, PS;
2350 def RDSEED32r : I<0xC7, MRM7r, (outs GR32:$dst), (ins), "rdseed{l}\t$dst",
2351 [(set GR32:$dst, EFLAGS, (X86rdseed))]>, OpSize32, PS;
2352 def RDSEED64r : RI<0xC7, MRM7r, (outs GR64:$dst), (ins), "rdseed{q}\t$dst",
2353 [(set GR64:$dst, EFLAGS, (X86rdseed))]>, PS;
2356 //===----------------------------------------------------------------------===//
2357 // LZCNT Instruction
2359 let Predicates = [HasLZCNT], Defs = [EFLAGS] in {
2360 def LZCNT16rr : I<0xBD, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
2361 "lzcnt{w}\t{$src, $dst|$dst, $src}",
2362 [(set GR16:$dst, (ctlz GR16:$src)), (implicit EFLAGS)]>,
2363 XS, OpSize16, Sched<[WriteLZCNT]>;
2364 def LZCNT16rm : I<0xBD, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
2365 "lzcnt{w}\t{$src, $dst|$dst, $src}",
2366 [(set GR16:$dst, (ctlz (loadi16 addr:$src))),
2367 (implicit EFLAGS)]>, XS, OpSize16, Sched<[WriteLZCNTLd]>;
2369 def LZCNT32rr : I<0xBD, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
2370 "lzcnt{l}\t{$src, $dst|$dst, $src}",
2371 [(set GR32:$dst, (ctlz GR32:$src)), (implicit EFLAGS)]>,
2372 XS, OpSize32, Sched<[WriteLZCNT]>;
2373 def LZCNT32rm : I<0xBD, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
2374 "lzcnt{l}\t{$src, $dst|$dst, $src}",
2375 [(set GR32:$dst, (ctlz (loadi32 addr:$src))),
2376 (implicit EFLAGS)]>, XS, OpSize32, Sched<[WriteLZCNTLd]>;
2378 def LZCNT64rr : RI<0xBD, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
2379 "lzcnt{q}\t{$src, $dst|$dst, $src}",
2380 [(set GR64:$dst, (ctlz GR64:$src)), (implicit EFLAGS)]>,
2381 XS, Sched<[WriteLZCNT]>;
2382 def LZCNT64rm : RI<0xBD, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
2383 "lzcnt{q}\t{$src, $dst|$dst, $src}",
2384 [(set GR64:$dst, (ctlz (loadi64 addr:$src))),
2385 (implicit EFLAGS)]>, XS, Sched<[WriteLZCNTLd]>;
2388 //===----------------------------------------------------------------------===//
2391 let Predicates = [HasBMI], Defs = [EFLAGS] in {
2392 def TZCNT16rr : I<0xBC, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
2393 "tzcnt{w}\t{$src, $dst|$dst, $src}",
2394 [(set GR16:$dst, (cttz GR16:$src)), (implicit EFLAGS)]>,
2395 XS, OpSize16, Sched<[WriteTZCNT]>;
2396 def TZCNT16rm : I<0xBC, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
2397 "tzcnt{w}\t{$src, $dst|$dst, $src}",
2398 [(set GR16:$dst, (cttz (loadi16 addr:$src))),
2399 (implicit EFLAGS)]>, XS, OpSize16, Sched<[WriteTZCNTLd]>;
2401 def TZCNT32rr : I<0xBC, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
2402 "tzcnt{l}\t{$src, $dst|$dst, $src}",
2403 [(set GR32:$dst, (cttz GR32:$src)), (implicit EFLAGS)]>,
2404 XS, OpSize32, Sched<[WriteTZCNT]>;
2405 def TZCNT32rm : I<0xBC, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
2406 "tzcnt{l}\t{$src, $dst|$dst, $src}",
2407 [(set GR32:$dst, (cttz (loadi32 addr:$src))),
2408 (implicit EFLAGS)]>, XS, OpSize32, Sched<[WriteTZCNTLd]>;
2410 def TZCNT64rr : RI<0xBC, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
2411 "tzcnt{q}\t{$src, $dst|$dst, $src}",
2412 [(set GR64:$dst, (cttz GR64:$src)), (implicit EFLAGS)]>,
2413 XS, Sched<[WriteTZCNT]>;
2414 def TZCNT64rm : RI<0xBC, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
2415 "tzcnt{q}\t{$src, $dst|$dst, $src}",
2416 [(set GR64:$dst, (cttz (loadi64 addr:$src))),
2417 (implicit EFLAGS)]>, XS, Sched<[WriteTZCNTLd]>;
2420 multiclass bmi_bls<string mnemonic, Format RegMRM, Format MemMRM,
2421 RegisterClass RC, X86MemOperand x86memop,
2422 X86FoldableSchedWrite sched> {
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<[sched]>;
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<[sched.Folded]>;
2434 let Predicates = [HasBMI], Defs = [EFLAGS] in {
2435 defm BLSR32 : bmi_bls<"blsr{l}", MRM1r, MRM1m, GR32, i32mem, WriteBLS>;
2436 defm BLSR64 : bmi_bls<"blsr{q}", MRM1r, MRM1m, GR64, i64mem, WriteBLS>, VEX_W;
2437 defm BLSMSK32 : bmi_bls<"blsmsk{l}", MRM2r, MRM2m, GR32, i32mem, WriteBLS>;
2438 defm BLSMSK64 : bmi_bls<"blsmsk{q}", MRM2r, MRM2m, GR64, i64mem, WriteBLS>, VEX_W;
2439 defm BLSI32 : bmi_bls<"blsi{l}", MRM3r, MRM3m, GR32, i32mem, WriteBLS>;
2440 defm BLSI64 : bmi_bls<"blsi{q}", MRM3r, MRM3m, GR64, i64mem, WriteBLS>, 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, timm:$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), timm:$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, timm:$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), timm:$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>;