1 //===-- X86InstrInfo.td - Main X86 Instruction Definition --*- tablegen -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file describes the X86 instruction set, defining the instructions, and
11 // properties of the instructions which are needed for code generation, machine
12 // code emission, and analysis.
14 //===----------------------------------------------------------------------===//
16 //===----------------------------------------------------------------------===//
17 // X86 specific DAG Nodes.
20 def SDTIntShiftDOp: SDTypeProfile<1, 3,
21 [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>,
22 SDTCisInt<0>, SDTCisInt<3>]>;
24 def SDTX86CmpTest : SDTypeProfile<1, 2, [SDTCisVT<0, i32>, SDTCisSameAs<1, 2>]>;
26 def SDTX86Cmps : SDTypeProfile<1, 3, [SDTCisFP<0>, SDTCisSameAs<1, 2>, SDTCisVT<3, i8>]>;
27 //def SDTX86Cmpss : SDTypeProfile<1, 3, [SDTCisVT<0, f32>, SDTCisSameAs<1, 2>, SDTCisVT<3, i8>]>;
29 def SDTX86Cmov : SDTypeProfile<1, 4,
30 [SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>,
31 SDTCisVT<3, i8>, SDTCisVT<4, i32>]>;
33 // Unary and binary operator instructions that set EFLAGS as a side-effect.
34 def SDTUnaryArithWithFlags : SDTypeProfile<2, 1,
36 SDTCisInt<0>, SDTCisVT<1, i32>]>;
38 def SDTBinaryArithWithFlags : SDTypeProfile<2, 2,
41 SDTCisInt<0>, SDTCisVT<1, i32>]>;
43 // SDTBinaryArithWithFlagsInOut - RES1, EFLAGS = op LHS, RHS, EFLAGS
44 def SDTBinaryArithWithFlagsInOut : SDTypeProfile<2, 3,
50 // RES1, RES2, FLAGS = op LHS, RHS
51 def SDT2ResultBinaryArithWithFlags : SDTypeProfile<3, 2,
55 SDTCisInt<0>, SDTCisVT<1, i32>]>;
56 def SDTX86BrCond : SDTypeProfile<0, 3,
57 [SDTCisVT<0, OtherVT>,
58 SDTCisVT<1, i8>, SDTCisVT<2, i32>]>;
60 def SDTX86SetCC : SDTypeProfile<1, 2,
62 SDTCisVT<1, i8>, SDTCisVT<2, i32>]>;
63 def SDTX86SetCC_C : SDTypeProfile<1, 2,
65 SDTCisVT<1, i8>, SDTCisVT<2, i32>]>;
67 def SDTX86sahf : SDTypeProfile<1, 1, [SDTCisVT<0, i32>, SDTCisVT<1, i8>]>;
69 def SDTX86rdrand : SDTypeProfile<2, 0, [SDTCisInt<0>, SDTCisVT<1, i32>]>;
71 def SDTX86cas : SDTypeProfile<0, 3, [SDTCisPtrTy<0>, SDTCisInt<1>,
73 def SDTX86caspair : SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>;
74 def SDTX86caspairSaveEbx8 : SDTypeProfile<1, 3,
75 [SDTCisVT<0, i32>, SDTCisPtrTy<1>,
76 SDTCisVT<2, i32>, SDTCisVT<3, i32>]>;
77 def SDTX86caspairSaveRbx16 : SDTypeProfile<1, 3,
78 [SDTCisVT<0, i64>, SDTCisPtrTy<1>,
79 SDTCisVT<2, i64>, SDTCisVT<3, i64>]>;
81 def SDTLockBinaryArithWithFlags : SDTypeProfile<1, 2, [SDTCisVT<0, i32>,
85 def SDTX86Ret : SDTypeProfile<0, -1, [SDTCisVT<0, i32>]>;
87 def SDT_X86CallSeqStart : SDCallSeqStart<[SDTCisVT<0, i32>]>;
88 def SDT_X86CallSeqEnd : SDCallSeqEnd<[SDTCisVT<0, i32>,
91 def SDT_X86Call : SDTypeProfile<0, -1, [SDTCisVT<0, iPTR>]>;
93 def SDT_X86VASTART_SAVE_XMM_REGS : SDTypeProfile<0, -1, [SDTCisVT<0, i8>,
97 def SDT_X86VAARG_64 : SDTypeProfile<1, -1, [SDTCisPtrTy<0>,
103 def SDTX86RepStr : SDTypeProfile<0, 1, [SDTCisVT<0, OtherVT>]>;
105 def SDTX86Void : SDTypeProfile<0, 0, []>;
107 def SDTX86Wrapper : SDTypeProfile<1, 1, [SDTCisSameAs<0, 1>, SDTCisPtrTy<0>]>;
109 def SDT_X86TLSADDR : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
111 def SDT_X86TLSBASEADDR : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
113 def SDT_X86TLSCALL : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
115 def SDT_X86WIN_ALLOCA : SDTypeProfile<0, 1, [SDTCisVT<0, iPTR>]>;
117 def SDT_X86SEG_ALLOCA : SDTypeProfile<1, 1, [SDTCisVT<0, iPTR>, SDTCisVT<1, iPTR>]>;
119 def SDT_X86EHRET : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
121 def SDT_X86TCRET : SDTypeProfile<0, 2, [SDTCisPtrTy<0>, SDTCisVT<1, i32>]>;
123 def SDT_X86MEMBARRIER : SDTypeProfile<0, 0, []>;
125 def X86MemBarrier : SDNode<"X86ISD::MEMBARRIER", SDT_X86MEMBARRIER,
126 [SDNPHasChain,SDNPSideEffect]>;
127 def X86MFence : SDNode<"X86ISD::MFENCE", SDT_X86MEMBARRIER,
131 def X86bsf : SDNode<"X86ISD::BSF", SDTUnaryArithWithFlags>;
132 def X86bsr : SDNode<"X86ISD::BSR", SDTUnaryArithWithFlags>;
133 def X86shld : SDNode<"X86ISD::SHLD", SDTIntShiftDOp>;
134 def X86shrd : SDNode<"X86ISD::SHRD", SDTIntShiftDOp>;
136 def X86cmp : SDNode<"X86ISD::CMP" , SDTX86CmpTest>;
137 def X86bt : SDNode<"X86ISD::BT", SDTX86CmpTest>;
139 def X86cmov : SDNode<"X86ISD::CMOV", SDTX86Cmov>;
140 def X86brcond : SDNode<"X86ISD::BRCOND", SDTX86BrCond,
142 def X86setcc : SDNode<"X86ISD::SETCC", SDTX86SetCC>;
143 def X86setcc_c : SDNode<"X86ISD::SETCC_CARRY", SDTX86SetCC_C>;
145 def X86sahf : SDNode<"X86ISD::SAHF", SDTX86sahf>;
147 def X86rdrand : SDNode<"X86ISD::RDRAND", SDTX86rdrand,
148 [SDNPHasChain, SDNPSideEffect]>;
150 def X86rdseed : SDNode<"X86ISD::RDSEED", SDTX86rdrand,
151 [SDNPHasChain, SDNPSideEffect]>;
153 def X86cas : SDNode<"X86ISD::LCMPXCHG_DAG", SDTX86cas,
154 [SDNPHasChain, SDNPInGlue, SDNPOutGlue, SDNPMayStore,
155 SDNPMayLoad, SDNPMemOperand]>;
156 def X86cas8 : SDNode<"X86ISD::LCMPXCHG8_DAG", SDTX86caspair,
157 [SDNPHasChain, SDNPInGlue, SDNPOutGlue, SDNPMayStore,
158 SDNPMayLoad, SDNPMemOperand]>;
159 def X86cas16 : SDNode<"X86ISD::LCMPXCHG16_DAG", SDTX86caspair,
160 [SDNPHasChain, SDNPInGlue, SDNPOutGlue, SDNPMayStore,
161 SDNPMayLoad, SDNPMemOperand]>;
162 def X86cas8save_ebx : SDNode<"X86ISD::LCMPXCHG8_SAVE_EBX_DAG",
163 SDTX86caspairSaveEbx8,
164 [SDNPHasChain, SDNPInGlue, SDNPOutGlue,
165 SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
166 def X86cas16save_rbx : SDNode<"X86ISD::LCMPXCHG16_SAVE_RBX_DAG",
167 SDTX86caspairSaveRbx16,
168 [SDNPHasChain, SDNPInGlue, SDNPOutGlue,
169 SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
171 def X86retflag : SDNode<"X86ISD::RET_FLAG", SDTX86Ret,
172 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
173 def X86iret : SDNode<"X86ISD::IRET", SDTX86Ret,
174 [SDNPHasChain, SDNPOptInGlue]>;
176 def X86vastart_save_xmm_regs :
177 SDNode<"X86ISD::VASTART_SAVE_XMM_REGS",
178 SDT_X86VASTART_SAVE_XMM_REGS,
179 [SDNPHasChain, SDNPVariadic]>;
181 SDNode<"X86ISD::VAARG_64", SDT_X86VAARG_64,
182 [SDNPHasChain, SDNPMayLoad, SDNPMayStore,
184 def X86callseq_start :
185 SDNode<"ISD::CALLSEQ_START", SDT_X86CallSeqStart,
186 [SDNPHasChain, SDNPOutGlue]>;
188 SDNode<"ISD::CALLSEQ_END", SDT_X86CallSeqEnd,
189 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
191 def X86call : SDNode<"X86ISD::CALL", SDT_X86Call,
192 [SDNPHasChain, SDNPOutGlue, SDNPOptInGlue,
195 def X86rep_stos: SDNode<"X86ISD::REP_STOS", SDTX86RepStr,
196 [SDNPHasChain, SDNPInGlue, SDNPOutGlue, SDNPMayStore]>;
197 def X86rep_movs: SDNode<"X86ISD::REP_MOVS", SDTX86RepStr,
198 [SDNPHasChain, SDNPInGlue, SDNPOutGlue, SDNPMayStore,
201 def X86rdtsc : SDNode<"X86ISD::RDTSC_DAG", SDTX86Void,
202 [SDNPHasChain, SDNPOutGlue, SDNPSideEffect]>;
203 def X86rdtscp : SDNode<"X86ISD::RDTSCP_DAG", SDTX86Void,
204 [SDNPHasChain, SDNPOutGlue, SDNPSideEffect]>;
205 def X86rdpmc : SDNode<"X86ISD::RDPMC_DAG", SDTX86Void,
206 [SDNPHasChain, SDNPOutGlue, SDNPSideEffect]>;
208 def X86Wrapper : SDNode<"X86ISD::Wrapper", SDTX86Wrapper>;
209 def X86WrapperRIP : SDNode<"X86ISD::WrapperRIP", SDTX86Wrapper>;
211 def X86RecoverFrameAlloc : SDNode<"ISD::LOCAL_RECOVER",
212 SDTypeProfile<1, 1, [SDTCisSameAs<0, 1>,
215 def X86tlsaddr : SDNode<"X86ISD::TLSADDR", SDT_X86TLSADDR,
216 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
218 def X86tlsbaseaddr : SDNode<"X86ISD::TLSBASEADDR", SDT_X86TLSBASEADDR,
219 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
221 def X86ehret : SDNode<"X86ISD::EH_RETURN", SDT_X86EHRET,
224 def X86eh_sjlj_setjmp : SDNode<"X86ISD::EH_SJLJ_SETJMP",
225 SDTypeProfile<1, 1, [SDTCisInt<0>,
227 [SDNPHasChain, SDNPSideEffect]>;
228 def X86eh_sjlj_longjmp : SDNode<"X86ISD::EH_SJLJ_LONGJMP",
229 SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>,
230 [SDNPHasChain, SDNPSideEffect]>;
231 def X86eh_sjlj_setup_dispatch : SDNode<"X86ISD::EH_SJLJ_SETUP_DISPATCH",
232 SDTypeProfile<0, 0, []>,
233 [SDNPHasChain, SDNPSideEffect]>;
235 def X86tcret : SDNode<"X86ISD::TC_RETURN", SDT_X86TCRET,
236 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
238 def X86add_flag : SDNode<"X86ISD::ADD", SDTBinaryArithWithFlags,
240 def X86sub_flag : SDNode<"X86ISD::SUB", SDTBinaryArithWithFlags>;
241 def X86smul_flag : SDNode<"X86ISD::SMUL", SDTBinaryArithWithFlags,
243 def X86umul_flag : SDNode<"X86ISD::UMUL", SDT2ResultBinaryArithWithFlags,
245 def X86adc_flag : SDNode<"X86ISD::ADC", SDTBinaryArithWithFlagsInOut>;
246 def X86sbb_flag : SDNode<"X86ISD::SBB", SDTBinaryArithWithFlagsInOut>;
248 def X86inc_flag : SDNode<"X86ISD::INC", SDTUnaryArithWithFlags>;
249 def X86dec_flag : SDNode<"X86ISD::DEC", SDTUnaryArithWithFlags>;
250 def X86or_flag : SDNode<"X86ISD::OR", SDTBinaryArithWithFlags,
252 def X86xor_flag : SDNode<"X86ISD::XOR", SDTBinaryArithWithFlags,
254 def X86and_flag : SDNode<"X86ISD::AND", SDTBinaryArithWithFlags,
257 def X86lock_add : SDNode<"X86ISD::LADD", SDTLockBinaryArithWithFlags,
258 [SDNPHasChain, SDNPMayStore, SDNPMayLoad,
260 def X86lock_sub : SDNode<"X86ISD::LSUB", SDTLockBinaryArithWithFlags,
261 [SDNPHasChain, SDNPMayStore, SDNPMayLoad,
263 def X86lock_or : SDNode<"X86ISD::LOR", SDTLockBinaryArithWithFlags,
264 [SDNPHasChain, SDNPMayStore, SDNPMayLoad,
266 def X86lock_xor : SDNode<"X86ISD::LXOR", SDTLockBinaryArithWithFlags,
267 [SDNPHasChain, SDNPMayStore, SDNPMayLoad,
269 def X86lock_and : SDNode<"X86ISD::LAND", SDTLockBinaryArithWithFlags,
270 [SDNPHasChain, SDNPMayStore, SDNPMayLoad,
273 def X86bextr : SDNode<"X86ISD::BEXTR", SDTIntBinOp>;
275 def X86mul_imm : SDNode<"X86ISD::MUL_IMM", SDTIntBinOp>;
277 def X86WinAlloca : SDNode<"X86ISD::WIN_ALLOCA", SDT_X86WIN_ALLOCA,
278 [SDNPHasChain, SDNPOutGlue]>;
280 def X86SegAlloca : SDNode<"X86ISD::SEG_ALLOCA", SDT_X86SEG_ALLOCA,
283 def X86TLSCall : SDNode<"X86ISD::TLSCALL", SDT_X86TLSCALL,
284 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
286 //===----------------------------------------------------------------------===//
287 // X86 Operand Definitions.
290 // A version of ptr_rc which excludes SP, ESP, and RSP. This is used for
291 // the index operand of an address, to conform to x86 encoding restrictions.
292 def ptr_rc_nosp : PointerLikeRegClass<1>;
294 // *mem - Operand definitions for the funky X86 addressing mode operands.
296 def X86MemAsmOperand : AsmOperandClass {
299 let RenderMethod = "addMemOperands", SuperClasses = [X86MemAsmOperand] in {
300 def X86Mem8AsmOperand : AsmOperandClass { let Name = "Mem8"; }
301 def X86Mem16AsmOperand : AsmOperandClass { let Name = "Mem16"; }
302 def X86Mem32AsmOperand : AsmOperandClass { let Name = "Mem32"; }
303 def X86Mem64AsmOperand : AsmOperandClass { let Name = "Mem64"; }
304 def X86Mem80AsmOperand : AsmOperandClass { let Name = "Mem80"; }
305 def X86Mem128AsmOperand : AsmOperandClass { let Name = "Mem128"; }
306 def X86Mem256AsmOperand : AsmOperandClass { let Name = "Mem256"; }
307 def X86Mem512AsmOperand : AsmOperandClass { let Name = "Mem512"; }
308 // Gather mem operands
309 def X86Mem64_RC128Operand : AsmOperandClass { let Name = "Mem64_RC128"; }
310 def X86Mem128_RC128Operand : AsmOperandClass { let Name = "Mem128_RC128"; }
311 def X86Mem256_RC128Operand : AsmOperandClass { let Name = "Mem256_RC128"; }
312 def X86Mem128_RC256Operand : AsmOperandClass { let Name = "Mem128_RC256"; }
313 def X86Mem256_RC256Operand : AsmOperandClass { let Name = "Mem256_RC256"; }
315 def X86Mem64_RC128XOperand : AsmOperandClass { let Name = "Mem64_RC128X"; }
316 def X86Mem128_RC128XOperand : AsmOperandClass { let Name = "Mem128_RC128X"; }
317 def X86Mem256_RC128XOperand : AsmOperandClass { let Name = "Mem256_RC128X"; }
318 def X86Mem128_RC256XOperand : AsmOperandClass { let Name = "Mem128_RC256X"; }
319 def X86Mem256_RC256XOperand : AsmOperandClass { let Name = "Mem256_RC256X"; }
320 def X86Mem512_RC256XOperand : AsmOperandClass { let Name = "Mem512_RC256X"; }
321 def X86Mem512_RC512Operand : AsmOperandClass { let Name = "Mem512_RC512"; }
324 def X86AbsMemAsmOperand : AsmOperandClass {
326 let SuperClasses = [X86MemAsmOperand];
329 class X86MemOperand<string printMethod,
330 AsmOperandClass parserMatchClass = X86MemAsmOperand> : Operand<iPTR> {
331 let PrintMethod = printMethod;
332 let MIOperandInfo = (ops ptr_rc, i8imm, ptr_rc_nosp, i32imm, SEGMENT_REG);
333 let ParserMatchClass = parserMatchClass;
334 let OperandType = "OPERAND_MEMORY";
337 // Gather mem operands
338 class X86VMemOperand<RegisterClass RC, string printMethod,
339 AsmOperandClass parserMatchClass>
340 : X86MemOperand<printMethod, parserMatchClass> {
341 let MIOperandInfo = (ops ptr_rc, i8imm, RC, i32imm, SEGMENT_REG);
344 def anymem : X86MemOperand<"printanymem">;
346 def opaque32mem : X86MemOperand<"printopaquemem">;
347 def opaque48mem : X86MemOperand<"printopaquemem">;
348 def opaque80mem : X86MemOperand<"printopaquemem">;
349 def opaque512mem : X86MemOperand<"printopaquemem">;
351 def i8mem : X86MemOperand<"printi8mem", X86Mem8AsmOperand>;
352 def i16mem : X86MemOperand<"printi16mem", X86Mem16AsmOperand>;
353 def i32mem : X86MemOperand<"printi32mem", X86Mem32AsmOperand>;
354 def i64mem : X86MemOperand<"printi64mem", X86Mem64AsmOperand>;
355 def i128mem : X86MemOperand<"printi128mem", X86Mem128AsmOperand>;
356 def i256mem : X86MemOperand<"printi256mem", X86Mem256AsmOperand>;
357 def i512mem : X86MemOperand<"printi512mem", X86Mem512AsmOperand>;
358 def f32mem : X86MemOperand<"printf32mem", X86Mem32AsmOperand>;
359 def f64mem : X86MemOperand<"printf64mem", X86Mem64AsmOperand>;
360 def f80mem : X86MemOperand<"printf80mem", X86Mem80AsmOperand>;
361 def f128mem : X86MemOperand<"printf128mem", X86Mem128AsmOperand>;
362 def f256mem : X86MemOperand<"printf256mem", X86Mem256AsmOperand>;
363 def f512mem : X86MemOperand<"printf512mem", X86Mem512AsmOperand>;
365 def v512mem : X86VMemOperand<VR512, "printf512mem", X86Mem512AsmOperand>;
367 // Gather mem operands
368 def vx64mem : X86VMemOperand<VR128, "printi64mem", X86Mem64_RC128Operand>;
369 def vx128mem : X86VMemOperand<VR128, "printi128mem", X86Mem128_RC128Operand>;
370 def vx256mem : X86VMemOperand<VR128, "printi256mem", X86Mem256_RC128Operand>;
371 def vy128mem : X86VMemOperand<VR256, "printi128mem", X86Mem128_RC256Operand>;
372 def vy256mem : X86VMemOperand<VR256, "printi256mem", X86Mem256_RC256Operand>;
374 def vx64xmem : X86VMemOperand<VR128X, "printi64mem", X86Mem64_RC128XOperand>;
375 def vx128xmem : X86VMemOperand<VR128X, "printi128mem", X86Mem128_RC128XOperand>;
376 def vx256xmem : X86VMemOperand<VR128X, "printi256mem", X86Mem256_RC128XOperand>;
377 def vy128xmem : X86VMemOperand<VR256, "printi128mem", X86Mem128_RC256XOperand>;
378 def vy256xmem : X86VMemOperand<VR256X, "printi256mem", X86Mem256_RC256XOperand>;
379 def vy512mem : X86VMemOperand<VR256X, "printi512mem", X86Mem512_RC256XOperand>;
380 def vz512mem : X86VMemOperand<VR512, "printi512mem", X86Mem512_RC512Operand>;
382 // A version of i8mem for use on x86-64 and x32 that uses a NOREX GPR instead
383 // of a plain GPR, so that it doesn't potentially require a REX prefix.
384 def ptr_rc_norex : PointerLikeRegClass<2>;
385 def ptr_rc_norex_nosp : PointerLikeRegClass<3>;
387 def i8mem_NOREX : Operand<iPTR> {
388 let PrintMethod = "printi8mem";
389 let MIOperandInfo = (ops ptr_rc_norex, i8imm, ptr_rc_norex_nosp, i32imm,
391 let ParserMatchClass = X86Mem8AsmOperand;
392 let OperandType = "OPERAND_MEMORY";
395 // GPRs available for tailcall.
396 // It represents GR32_TC, GR64_TC or GR64_TCW64.
397 def ptr_rc_tailcall : PointerLikeRegClass<4>;
399 // Special i32mem for addresses of load folding tail calls. These are not
400 // allowed to use callee-saved registers since they must be scheduled
401 // after callee-saved register are popped.
402 def i32mem_TC : Operand<i32> {
403 let PrintMethod = "printi32mem";
404 let MIOperandInfo = (ops ptr_rc_tailcall, i8imm, ptr_rc_tailcall,
405 i32imm, SEGMENT_REG);
406 let ParserMatchClass = X86Mem32AsmOperand;
407 let OperandType = "OPERAND_MEMORY";
410 // Special i64mem for addresses of load folding tail calls. These are not
411 // allowed to use callee-saved registers since they must be scheduled
412 // after callee-saved register are popped.
413 def i64mem_TC : Operand<i64> {
414 let PrintMethod = "printi64mem";
415 let MIOperandInfo = (ops ptr_rc_tailcall, i8imm,
416 ptr_rc_tailcall, i32imm, SEGMENT_REG);
417 let ParserMatchClass = X86Mem64AsmOperand;
418 let OperandType = "OPERAND_MEMORY";
421 let OperandType = "OPERAND_PCREL",
422 ParserMatchClass = X86AbsMemAsmOperand,
423 PrintMethod = "printPCRelImm" in {
424 def i32imm_pcrel : Operand<i32>;
425 def i16imm_pcrel : Operand<i16>;
427 // Branch targets have OtherVT type and print as pc-relative values.
428 def brtarget : Operand<OtherVT>;
429 def brtarget8 : Operand<OtherVT>;
433 // Special parser to detect 16-bit mode to select 16-bit displacement.
434 def X86AbsMem16AsmOperand : AsmOperandClass {
435 let Name = "AbsMem16";
436 let RenderMethod = "addAbsMemOperands";
437 let SuperClasses = [X86AbsMemAsmOperand];
440 // Branch targets have OtherVT type and print as pc-relative values.
441 let OperandType = "OPERAND_PCREL",
442 PrintMethod = "printPCRelImm" in {
443 let ParserMatchClass = X86AbsMem16AsmOperand in
444 def brtarget16 : Operand<OtherVT>;
445 let ParserMatchClass = X86AbsMemAsmOperand in
446 def brtarget32 : Operand<OtherVT>;
449 let RenderMethod = "addSrcIdxOperands" in {
450 def X86SrcIdx8Operand : AsmOperandClass {
451 let Name = "SrcIdx8";
452 let SuperClasses = [X86Mem8AsmOperand];
454 def X86SrcIdx16Operand : AsmOperandClass {
455 let Name = "SrcIdx16";
456 let SuperClasses = [X86Mem16AsmOperand];
458 def X86SrcIdx32Operand : AsmOperandClass {
459 let Name = "SrcIdx32";
460 let SuperClasses = [X86Mem32AsmOperand];
462 def X86SrcIdx64Operand : AsmOperandClass {
463 let Name = "SrcIdx64";
464 let SuperClasses = [X86Mem64AsmOperand];
466 } // RenderMethod = "addSrcIdxOperands"
468 let RenderMethod = "addDstIdxOperands" in {
469 def X86DstIdx8Operand : AsmOperandClass {
470 let Name = "DstIdx8";
471 let SuperClasses = [X86Mem8AsmOperand];
473 def X86DstIdx16Operand : AsmOperandClass {
474 let Name = "DstIdx16";
475 let SuperClasses = [X86Mem16AsmOperand];
477 def X86DstIdx32Operand : AsmOperandClass {
478 let Name = "DstIdx32";
479 let SuperClasses = [X86Mem32AsmOperand];
481 def X86DstIdx64Operand : AsmOperandClass {
482 let Name = "DstIdx64";
483 let SuperClasses = [X86Mem64AsmOperand];
485 } // RenderMethod = "addDstIdxOperands"
487 let RenderMethod = "addMemOffsOperands" in {
488 def X86MemOffs16_8AsmOperand : AsmOperandClass {
489 let Name = "MemOffs16_8";
490 let SuperClasses = [X86Mem8AsmOperand];
492 def X86MemOffs16_16AsmOperand : AsmOperandClass {
493 let Name = "MemOffs16_16";
494 let SuperClasses = [X86Mem16AsmOperand];
496 def X86MemOffs16_32AsmOperand : AsmOperandClass {
497 let Name = "MemOffs16_32";
498 let SuperClasses = [X86Mem32AsmOperand];
500 def X86MemOffs32_8AsmOperand : AsmOperandClass {
501 let Name = "MemOffs32_8";
502 let SuperClasses = [X86Mem8AsmOperand];
504 def X86MemOffs32_16AsmOperand : AsmOperandClass {
505 let Name = "MemOffs32_16";
506 let SuperClasses = [X86Mem16AsmOperand];
508 def X86MemOffs32_32AsmOperand : AsmOperandClass {
509 let Name = "MemOffs32_32";
510 let SuperClasses = [X86Mem32AsmOperand];
512 def X86MemOffs32_64AsmOperand : AsmOperandClass {
513 let Name = "MemOffs32_64";
514 let SuperClasses = [X86Mem64AsmOperand];
516 def X86MemOffs64_8AsmOperand : AsmOperandClass {
517 let Name = "MemOffs64_8";
518 let SuperClasses = [X86Mem8AsmOperand];
520 def X86MemOffs64_16AsmOperand : AsmOperandClass {
521 let Name = "MemOffs64_16";
522 let SuperClasses = [X86Mem16AsmOperand];
524 def X86MemOffs64_32AsmOperand : AsmOperandClass {
525 let Name = "MemOffs64_32";
526 let SuperClasses = [X86Mem32AsmOperand];
528 def X86MemOffs64_64AsmOperand : AsmOperandClass {
529 let Name = "MemOffs64_64";
530 let SuperClasses = [X86Mem64AsmOperand];
532 } // RenderMethod = "addMemOffsOperands"
534 class X86SrcIdxOperand<string printMethod, AsmOperandClass parserMatchClass>
535 : X86MemOperand<printMethod, parserMatchClass> {
536 let MIOperandInfo = (ops ptr_rc, SEGMENT_REG);
539 class X86DstIdxOperand<string printMethod, AsmOperandClass parserMatchClass>
540 : X86MemOperand<printMethod, parserMatchClass> {
541 let MIOperandInfo = (ops ptr_rc);
544 def srcidx8 : X86SrcIdxOperand<"printSrcIdx8", X86SrcIdx8Operand>;
545 def srcidx16 : X86SrcIdxOperand<"printSrcIdx16", X86SrcIdx16Operand>;
546 def srcidx32 : X86SrcIdxOperand<"printSrcIdx32", X86SrcIdx32Operand>;
547 def srcidx64 : X86SrcIdxOperand<"printSrcIdx64", X86SrcIdx64Operand>;
548 def dstidx8 : X86DstIdxOperand<"printDstIdx8", X86DstIdx8Operand>;
549 def dstidx16 : X86DstIdxOperand<"printDstIdx16", X86DstIdx16Operand>;
550 def dstidx32 : X86DstIdxOperand<"printDstIdx32", X86DstIdx32Operand>;
551 def dstidx64 : X86DstIdxOperand<"printDstIdx64", X86DstIdx64Operand>;
553 class X86MemOffsOperand<Operand immOperand, string printMethod,
554 AsmOperandClass parserMatchClass>
555 : X86MemOperand<printMethod, parserMatchClass> {
556 let MIOperandInfo = (ops immOperand, SEGMENT_REG);
559 def offset16_8 : X86MemOffsOperand<i16imm, "printMemOffs8",
560 X86MemOffs16_8AsmOperand>;
561 def offset16_16 : X86MemOffsOperand<i16imm, "printMemOffs16",
562 X86MemOffs16_16AsmOperand>;
563 def offset16_32 : X86MemOffsOperand<i16imm, "printMemOffs32",
564 X86MemOffs16_32AsmOperand>;
565 def offset32_8 : X86MemOffsOperand<i32imm, "printMemOffs8",
566 X86MemOffs32_8AsmOperand>;
567 def offset32_16 : X86MemOffsOperand<i32imm, "printMemOffs16",
568 X86MemOffs32_16AsmOperand>;
569 def offset32_32 : X86MemOffsOperand<i32imm, "printMemOffs32",
570 X86MemOffs32_32AsmOperand>;
571 def offset32_64 : X86MemOffsOperand<i32imm, "printMemOffs64",
572 X86MemOffs32_64AsmOperand>;
573 def offset64_8 : X86MemOffsOperand<i64imm, "printMemOffs8",
574 X86MemOffs64_8AsmOperand>;
575 def offset64_16 : X86MemOffsOperand<i64imm, "printMemOffs16",
576 X86MemOffs64_16AsmOperand>;
577 def offset64_32 : X86MemOffsOperand<i64imm, "printMemOffs32",
578 X86MemOffs64_32AsmOperand>;
579 def offset64_64 : X86MemOffsOperand<i64imm, "printMemOffs64",
580 X86MemOffs64_64AsmOperand>;
582 def SSECC : Operand<i8> {
583 let PrintMethod = "printSSEAVXCC";
584 let OperandType = "OPERAND_IMMEDIATE";
587 def i8immZExt3 : ImmLeaf<i8, [{
588 return Imm >= 0 && Imm < 8;
591 def AVXCC : Operand<i8> {
592 let PrintMethod = "printSSEAVXCC";
593 let OperandType = "OPERAND_IMMEDIATE";
596 def i8immZExt5 : ImmLeaf<i8, [{
597 return Imm >= 0 && Imm < 32;
600 def AVX512ICC : Operand<i8> {
601 let PrintMethod = "printSSEAVXCC";
602 let OperandType = "OPERAND_IMMEDIATE";
605 def XOPCC : Operand<i8> {
606 let PrintMethod = "printXOPCC";
607 let OperandType = "OPERAND_IMMEDIATE";
610 class ImmSExtAsmOperandClass : AsmOperandClass {
611 let SuperClasses = [ImmAsmOperand];
612 let RenderMethod = "addImmOperands";
615 def X86GR32orGR64AsmOperand : AsmOperandClass {
616 let Name = "GR32orGR64";
619 def GR32orGR64 : RegisterOperand<GR32> {
620 let ParserMatchClass = X86GR32orGR64AsmOperand;
622 def AVX512RCOperand : AsmOperandClass {
623 let Name = "AVX512RC";
625 def AVX512RC : Operand<i32> {
626 let PrintMethod = "printRoundingControl";
627 let OperandType = "OPERAND_IMMEDIATE";
628 let ParserMatchClass = AVX512RCOperand;
631 // Sign-extended immediate classes. We don't need to define the full lattice
632 // here because there is no instruction with an ambiguity between ImmSExti64i32
635 // The strange ranges come from the fact that the assembler always works with
636 // 64-bit immediates, but for a 16-bit target value we want to accept both "-1"
637 // (which will be a -1ULL), and "0xFF" (-1 in 16-bits).
640 // [0xFFFFFFFF80000000, 0xFFFFFFFFFFFFFFFF]
641 def ImmSExti64i32AsmOperand : ImmSExtAsmOperandClass {
642 let Name = "ImmSExti64i32";
645 // [0, 0x0000007F] | [0x000000000000FF80, 0x000000000000FFFF] |
646 // [0xFFFFFFFFFFFFFF80, 0xFFFFFFFFFFFFFFFF]
647 def ImmSExti16i8AsmOperand : ImmSExtAsmOperandClass {
648 let Name = "ImmSExti16i8";
649 let SuperClasses = [ImmSExti64i32AsmOperand];
652 // [0, 0x0000007F] | [0x00000000FFFFFF80, 0x00000000FFFFFFFF] |
653 // [0xFFFFFFFFFFFFFF80, 0xFFFFFFFFFFFFFFFF]
654 def ImmSExti32i8AsmOperand : ImmSExtAsmOperandClass {
655 let Name = "ImmSExti32i8";
659 // [0xFFFFFFFFFFFFFF80, 0xFFFFFFFFFFFFFFFF]
660 def ImmSExti64i8AsmOperand : ImmSExtAsmOperandClass {
661 let Name = "ImmSExti64i8";
662 let SuperClasses = [ImmSExti16i8AsmOperand, ImmSExti32i8AsmOperand,
663 ImmSExti64i32AsmOperand];
666 // Unsigned immediate used by SSE/AVX instructions
668 // [0xFFFFFFFFFFFFFF80, 0xFFFFFFFFFFFFFFFF]
669 def ImmUnsignedi8AsmOperand : AsmOperandClass {
670 let Name = "ImmUnsignedi8";
671 let RenderMethod = "addImmOperands";
674 // A couple of more descriptive operand definitions.
675 // 16-bits but only 8 bits are significant.
676 def i16i8imm : Operand<i16> {
677 let ParserMatchClass = ImmSExti16i8AsmOperand;
678 let OperandType = "OPERAND_IMMEDIATE";
680 // 32-bits but only 8 bits are significant.
681 def i32i8imm : Operand<i32> {
682 let ParserMatchClass = ImmSExti32i8AsmOperand;
683 let OperandType = "OPERAND_IMMEDIATE";
686 // 64-bits but only 32 bits are significant.
687 def i64i32imm : Operand<i64> {
688 let ParserMatchClass = ImmSExti64i32AsmOperand;
689 let OperandType = "OPERAND_IMMEDIATE";
692 // 64-bits but only 8 bits are significant.
693 def i64i8imm : Operand<i64> {
694 let ParserMatchClass = ImmSExti64i8AsmOperand;
695 let OperandType = "OPERAND_IMMEDIATE";
698 // Unsigned 8-bit immediate used by SSE/AVX instructions.
699 def u8imm : Operand<i8> {
700 let PrintMethod = "printU8Imm";
701 let ParserMatchClass = ImmUnsignedi8AsmOperand;
702 let OperandType = "OPERAND_IMMEDIATE";
705 // 32-bit immediate but only 8-bits are significant and they are unsigned.
706 // Used by some SSE/AVX instructions that use intrinsics.
707 def i32u8imm : Operand<i32> {
708 let PrintMethod = "printU8Imm";
709 let ParserMatchClass = ImmUnsignedi8AsmOperand;
710 let OperandType = "OPERAND_IMMEDIATE";
713 // 64-bits but only 32 bits are significant, and those bits are treated as being
715 def i64i32imm_pcrel : Operand<i64> {
716 let PrintMethod = "printPCRelImm";
717 let ParserMatchClass = X86AbsMemAsmOperand;
718 let OperandType = "OPERAND_PCREL";
721 def lea64_32mem : Operand<i32> {
722 let PrintMethod = "printanymem";
723 let MIOperandInfo = (ops GR64, i8imm, GR64_NOSP, i32imm, SEGMENT_REG);
724 let ParserMatchClass = X86MemAsmOperand;
727 // Memory operands that use 64-bit pointers in both ILP32 and LP64.
728 def lea64mem : Operand<i64> {
729 let PrintMethod = "printanymem";
730 let MIOperandInfo = (ops GR64, i8imm, GR64_NOSP, i32imm, SEGMENT_REG);
731 let ParserMatchClass = X86MemAsmOperand;
735 //===----------------------------------------------------------------------===//
736 // X86 Complex Pattern Definitions.
739 // Define X86-specific addressing mode.
740 def addr : ComplexPattern<iPTR, 5, "selectAddr", [], [SDNPWantParent]>;
741 def lea32addr : ComplexPattern<i32, 5, "selectLEAAddr",
742 [add, sub, mul, X86mul_imm, shl, or, frameindex],
744 // In 64-bit mode 32-bit LEAs can use RIP-relative addressing.
745 def lea64_32addr : ComplexPattern<i32, 5, "selectLEA64_32Addr",
746 [add, sub, mul, X86mul_imm, shl, or,
747 frameindex, X86WrapperRIP],
750 def tls32addr : ComplexPattern<i32, 5, "selectTLSADDRAddr",
751 [tglobaltlsaddr], []>;
753 def tls32baseaddr : ComplexPattern<i32, 5, "selectTLSADDRAddr",
754 [tglobaltlsaddr], []>;
756 def lea64addr : ComplexPattern<i64, 5, "selectLEAAddr",
757 [add, sub, mul, X86mul_imm, shl, or, frameindex,
760 def tls64addr : ComplexPattern<i64, 5, "selectTLSADDRAddr",
761 [tglobaltlsaddr], []>;
763 def tls64baseaddr : ComplexPattern<i64, 5, "selectTLSADDRAddr",
764 [tglobaltlsaddr], []>;
766 def vectoraddr : ComplexPattern<iPTR, 5, "selectVectorAddr", [],[SDNPWantParent]>;
768 //===----------------------------------------------------------------------===//
769 // X86 Instruction Predicate Definitions.
770 def TruePredicate : Predicate<"true">;
772 def HasCMov : Predicate<"Subtarget->hasCMov()">;
773 def NoCMov : Predicate<"!Subtarget->hasCMov()">;
775 def HasMMX : Predicate<"Subtarget->hasMMX()">;
776 def Has3DNow : Predicate<"Subtarget->has3DNow()">;
777 def Has3DNowA : Predicate<"Subtarget->has3DNowA()">;
778 def HasSSE1 : Predicate<"Subtarget->hasSSE1()">;
779 def UseSSE1 : Predicate<"Subtarget->hasSSE1() && !Subtarget->hasAVX()">;
780 def HasSSE2 : Predicate<"Subtarget->hasSSE2()">;
781 def UseSSE2 : Predicate<"Subtarget->hasSSE2() && !Subtarget->hasAVX()">;
782 def HasSSE3 : Predicate<"Subtarget->hasSSE3()">;
783 def UseSSE3 : Predicate<"Subtarget->hasSSE3() && !Subtarget->hasAVX()">;
784 def HasSSSE3 : Predicate<"Subtarget->hasSSSE3()">;
785 def UseSSSE3 : Predicate<"Subtarget->hasSSSE3() && !Subtarget->hasAVX()">;
786 def HasSSE41 : Predicate<"Subtarget->hasSSE41()">;
787 def NoSSE41 : Predicate<"!Subtarget->hasSSE41()">;
788 def UseSSE41 : Predicate<"Subtarget->hasSSE41() && !Subtarget->hasAVX()">;
789 def HasSSE42 : Predicate<"Subtarget->hasSSE42()">;
790 def UseSSE42 : Predicate<"Subtarget->hasSSE42() && !Subtarget->hasAVX()">;
791 def HasSSE4A : Predicate<"Subtarget->hasSSE4A()">;
792 def HasAVX : Predicate<"Subtarget->hasAVX()">;
793 def HasAVX2 : Predicate<"Subtarget->hasAVX2()">;
794 def HasAVX1Only : Predicate<"Subtarget->hasAVX() && !Subtarget->hasAVX2()">;
795 def HasAVX512 : Predicate<"Subtarget->hasAVX512()">,
796 AssemblerPredicate<"FeatureAVX512", "AVX-512 ISA">;
797 def UseAVX : Predicate<"Subtarget->hasAVX() && !Subtarget->hasAVX512()">;
798 def UseAVX2 : Predicate<"Subtarget->hasAVX2() && !Subtarget->hasAVX512()">;
799 def NoAVX512 : Predicate<"!Subtarget->hasAVX512()">;
800 def HasCDI : Predicate<"Subtarget->hasCDI()">,
801 AssemblerPredicate<"FeatureCDI", "AVX-512 CD ISA">;
802 def HasPFI : Predicate<"Subtarget->hasPFI()">,
803 AssemblerPredicate<"FeaturePFI", "AVX-512 PF ISA">;
804 def HasERI : Predicate<"Subtarget->hasERI()">,
805 AssemblerPredicate<"FeatureERI", "AVX-512 ER ISA">;
806 def HasDQI : Predicate<"Subtarget->hasDQI()">,
807 AssemblerPredicate<"FeatureDQI", "AVX-512 DQ ISA">;
808 def NoDQI : Predicate<"!Subtarget->hasDQI()">;
809 def HasBWI : Predicate<"Subtarget->hasBWI()">,
810 AssemblerPredicate<"FeatureBWI", "AVX-512 BW ISA">;
811 def NoBWI : Predicate<"!Subtarget->hasBWI()">;
812 def HasVLX : Predicate<"Subtarget->hasVLX()">,
813 AssemblerPredicate<"FeatureVLX", "AVX-512 VL ISA">;
814 def NoVLX : Predicate<"!Subtarget->hasVLX()">;
815 def NoVLX_Or_NoBWI : Predicate<"!Subtarget->hasVLX() || !Subtarget->hasBWI()">;
816 def NoVLX_Or_NoDQI : Predicate<"!Subtarget->hasVLX() || !Subtarget->hasDQI()">;
817 def PKU : Predicate<"Subtarget->hasPKU()">;
819 def HasPOPCNT : Predicate<"Subtarget->hasPOPCNT()">;
820 def HasAES : Predicate<"Subtarget->hasAES()">;
821 def HasFXSR : Predicate<"Subtarget->hasFXSR()">;
822 def HasXSAVE : Predicate<"Subtarget->hasXSAVE()">;
823 def HasXSAVEOPT : Predicate<"Subtarget->hasXSAVEOPT()">;
824 def HasXSAVEC : Predicate<"Subtarget->hasXSAVEC()">;
825 def HasXSAVES : Predicate<"Subtarget->hasXSAVES()">;
826 def HasPCLMUL : Predicate<"Subtarget->hasPCLMUL()">;
827 def HasFMA : Predicate<"Subtarget->hasFMA()">;
828 def UseFMAOnAVX : Predicate<"Subtarget->hasFMA() && !Subtarget->hasAVX512()">;
829 def HasFMA4 : Predicate<"Subtarget->hasFMA4()">;
830 def HasXOP : Predicate<"Subtarget->hasXOP()">;
831 def HasTBM : Predicate<"Subtarget->hasTBM()">;
832 def HasMOVBE : Predicate<"Subtarget->hasMOVBE()">;
833 def HasRDRAND : Predicate<"Subtarget->hasRDRAND()">;
834 def HasF16C : Predicate<"Subtarget->hasF16C()">;
835 def HasFSGSBase : Predicate<"Subtarget->hasFSGSBase()">;
836 def HasLZCNT : Predicate<"Subtarget->hasLZCNT()">;
837 def HasBMI : Predicate<"Subtarget->hasBMI()">;
838 def HasBMI2 : Predicate<"Subtarget->hasBMI2()">;
839 def HasVBMI : Predicate<"Subtarget->hasVBMI()">,
840 AssemblerPredicate<"FeatureVBMI", "AVX-512 VBMI ISA">;
841 def HasIFMA : Predicate<"Subtarget->hasIFMA()">,
842 AssemblerPredicate<"FeatureIFMA", "AVX-512 IFMA ISA">;
843 def HasRTM : Predicate<"Subtarget->hasRTM()">;
844 def HasHLE : Predicate<"Subtarget->hasHLE()">;
845 def HasTSX : Predicate<"Subtarget->hasRTM() || Subtarget->hasHLE()">;
846 def HasADX : Predicate<"Subtarget->hasADX()">;
847 def HasSHA : Predicate<"Subtarget->hasSHA()">;
848 def HasPRFCHW : Predicate<"Subtarget->hasPRFCHW()">;
849 def HasRDSEED : Predicate<"Subtarget->hasRDSEED()">;
850 def HasPrefetchW : Predicate<"Subtarget->hasPRFCHW()">;
851 def HasLAHFSAHF : Predicate<"Subtarget->hasLAHFSAHF()">;
852 def HasMWAITX : Predicate<"Subtarget->hasMWAITX()">;
853 def FPStackf32 : Predicate<"!Subtarget->hasSSE1()">;
854 def FPStackf64 : Predicate<"!Subtarget->hasSSE2()">;
855 def HasMPX : Predicate<"Subtarget->hasMPX()">;
856 def HasCmpxchg16b: Predicate<"Subtarget->hasCmpxchg16b()">;
857 def Not64BitMode : Predicate<"!Subtarget->is64Bit()">,
858 AssemblerPredicate<"!Mode64Bit", "Not 64-bit mode">;
859 def In64BitMode : Predicate<"Subtarget->is64Bit()">,
860 AssemblerPredicate<"Mode64Bit", "64-bit mode">;
861 def IsLP64 : Predicate<"Subtarget->isTarget64BitLP64()">;
862 def NotLP64 : Predicate<"!Subtarget->isTarget64BitLP64()">;
863 def In16BitMode : Predicate<"Subtarget->is16Bit()">,
864 AssemblerPredicate<"Mode16Bit", "16-bit mode">;
865 def Not16BitMode : Predicate<"!Subtarget->is16Bit()">,
866 AssemblerPredicate<"!Mode16Bit", "Not 16-bit mode">;
867 def In32BitMode : Predicate<"Subtarget->is32Bit()">,
868 AssemblerPredicate<"Mode32Bit", "32-bit mode">;
869 def IsWin64 : Predicate<"Subtarget->isTargetWin64()">;
870 def NotWin64 : Predicate<"!Subtarget->isTargetWin64()">;
871 def NotWin64WithoutFP : Predicate<"!Subtarget->isTargetWin64() ||"
872 "Subtarget->getFrameLowering()->hasFP(*MF)">;
873 def IsPS4 : Predicate<"Subtarget->isTargetPS4()">;
874 def NotPS4 : Predicate<"!Subtarget->isTargetPS4()">;
875 def IsNaCl : Predicate<"Subtarget->isTargetNaCl()">;
876 def NotNaCl : Predicate<"!Subtarget->isTargetNaCl()">;
877 def SmallCode : Predicate<"TM.getCodeModel() == CodeModel::Small">;
878 def KernelCode : Predicate<"TM.getCodeModel() == CodeModel::Kernel">;
879 def FarData : Predicate<"TM.getCodeModel() != CodeModel::Small &&"
880 "TM.getCodeModel() != CodeModel::Kernel">;
881 def NearData : Predicate<"TM.getCodeModel() == CodeModel::Small ||"
882 "TM.getCodeModel() == CodeModel::Kernel">;
883 def IsNotPIC : Predicate<"!TM.isPositionIndependent()">;
884 def OptForSize : Predicate<"OptForSize">;
885 def OptForMinSize : Predicate<"OptForMinSize">;
886 def OptForSpeed : Predicate<"!OptForSize">;
887 def FastBTMem : Predicate<"!Subtarget->isBTMemSlow()">;
888 def CallImmAddr : Predicate<"Subtarget->isLegalToCallImmediateAddr()">;
889 def FavorMemIndirectCall : Predicate<"!Subtarget->callRegIndirect()">;
890 def NotSlowIncDec : Predicate<"!Subtarget->slowIncDec()">;
891 def HasFastMem32 : Predicate<"!Subtarget->isUnalignedMem32Slow()">;
892 def HasMFence : Predicate<"Subtarget->hasMFence()">;
894 //===----------------------------------------------------------------------===//
895 // X86 Instruction Format Definitions.
898 include "X86InstrFormats.td"
900 //===----------------------------------------------------------------------===//
901 // Pattern fragments.
904 // X86 specific condition code. These correspond to CondCode in
905 // X86InstrInfo.h. They must be kept in synch.
906 def X86_COND_A : PatLeaf<(i8 0)>; // alt. COND_NBE
907 def X86_COND_AE : PatLeaf<(i8 1)>; // alt. COND_NC
908 def X86_COND_B : PatLeaf<(i8 2)>; // alt. COND_C
909 def X86_COND_BE : PatLeaf<(i8 3)>; // alt. COND_NA
910 def X86_COND_E : PatLeaf<(i8 4)>; // alt. COND_Z
911 def X86_COND_G : PatLeaf<(i8 5)>; // alt. COND_NLE
912 def X86_COND_GE : PatLeaf<(i8 6)>; // alt. COND_NL
913 def X86_COND_L : PatLeaf<(i8 7)>; // alt. COND_NGE
914 def X86_COND_LE : PatLeaf<(i8 8)>; // alt. COND_NG
915 def X86_COND_NE : PatLeaf<(i8 9)>; // alt. COND_NZ
916 def X86_COND_NO : PatLeaf<(i8 10)>;
917 def X86_COND_NP : PatLeaf<(i8 11)>; // alt. COND_PO
918 def X86_COND_NS : PatLeaf<(i8 12)>;
919 def X86_COND_O : PatLeaf<(i8 13)>;
920 def X86_COND_P : PatLeaf<(i8 14)>; // alt. COND_PE
921 def X86_COND_S : PatLeaf<(i8 15)>;
923 def i16immSExt8 : ImmLeaf<i16, [{ return isInt<8>(Imm); }]>;
924 def i32immSExt8 : ImmLeaf<i32, [{ return isInt<8>(Imm); }]>;
925 def i64immSExt8 : ImmLeaf<i64, [{ return isInt<8>(Imm); }]>;
927 // If we have multiple users of an immediate, it's much smaller to reuse
928 // the register, rather than encode the immediate in every instruction.
929 // This has the risk of increasing register pressure from stretched live
930 // ranges, however, the immediates should be trivial to rematerialize by
931 // the RA in the event of high register pressure.
932 // TODO : This is currently enabled for stores and binary ops. There are more
933 // cases for which this can be enabled, though this catches the bulk of the
935 // TODO2 : This should really also be enabled under O2, but there's currently
936 // an issue with RA where we don't pull the constants into their users
937 // when we rematerialize them. I'll follow-up on enabling O2 after we fix that
939 // TODO3 : This is currently limited to single basic blocks (DAG creation
940 // pulls block immediates to the top and merges them if necessary).
941 // Eventually, it would be nice to allow ConstantHoisting to merge constants
942 // globally for potentially added savings.
944 def imm8_su : PatLeaf<(i8 imm), [{
945 return !shouldAvoidImmediateInstFormsForSize(N);
947 def imm16_su : PatLeaf<(i16 imm), [{
948 return !shouldAvoidImmediateInstFormsForSize(N);
950 def imm32_su : PatLeaf<(i32 imm), [{
951 return !shouldAvoidImmediateInstFormsForSize(N);
954 def i16immSExt8_su : PatLeaf<(i16immSExt8), [{
955 return !shouldAvoidImmediateInstFormsForSize(N);
957 def i32immSExt8_su : PatLeaf<(i32immSExt8), [{
958 return !shouldAvoidImmediateInstFormsForSize(N);
962 def i64immSExt32 : ImmLeaf<i64, [{ return isInt<32>(Imm); }]>;
965 // i64immZExt32 predicate - True if the 64-bit immediate fits in a 32-bit
967 def i64immZExt32 : ImmLeaf<i64, [{ return isUInt<32>(Imm); }]>;
969 def i64immZExt32SExt8 : ImmLeaf<i64, [{
970 return isUInt<32>(Imm) && isInt<8>(static_cast<int32_t>(Imm));
973 // Helper fragments for loads.
974 // It's always safe to treat a anyext i16 load as a i32 load if the i16 is
975 // known to be 32-bit aligned or better. Ditto for i8 to i16.
976 def loadi16 : PatFrag<(ops node:$ptr), (i16 (unindexedload node:$ptr)), [{
977 LoadSDNode *LD = cast<LoadSDNode>(N);
978 ISD::LoadExtType ExtType = LD->getExtensionType();
979 if (ExtType == ISD::NON_EXTLOAD)
981 if (ExtType == ISD::EXTLOAD)
982 return LD->getAlignment() >= 2 && !LD->isVolatile();
986 def loadi16_anyext : PatFrag<(ops node:$ptr), (i32 (unindexedload node:$ptr)),[{
987 LoadSDNode *LD = cast<LoadSDNode>(N);
988 ISD::LoadExtType ExtType = LD->getExtensionType();
989 if (ExtType == ISD::EXTLOAD)
990 return LD->getAlignment() >= 2 && !LD->isVolatile();
994 def loadi32 : PatFrag<(ops node:$ptr), (i32 (unindexedload node:$ptr)), [{
995 LoadSDNode *LD = cast<LoadSDNode>(N);
996 ISD::LoadExtType ExtType = LD->getExtensionType();
997 if (ExtType == ISD::NON_EXTLOAD)
999 if (ExtType == ISD::EXTLOAD)
1000 return LD->getAlignment() >= 4 && !LD->isVolatile();
1004 def loadi8 : PatFrag<(ops node:$ptr), (i8 (load node:$ptr))>;
1005 def loadi64 : PatFrag<(ops node:$ptr), (i64 (load node:$ptr))>;
1006 def loadf32 : PatFrag<(ops node:$ptr), (f32 (load node:$ptr))>;
1007 def loadf64 : PatFrag<(ops node:$ptr), (f64 (load node:$ptr))>;
1008 def loadf80 : PatFrag<(ops node:$ptr), (f80 (load node:$ptr))>;
1009 def loadf128 : PatFrag<(ops node:$ptr), (f128 (load node:$ptr))>;
1011 def sextloadi16i8 : PatFrag<(ops node:$ptr), (i16 (sextloadi8 node:$ptr))>;
1012 def sextloadi32i8 : PatFrag<(ops node:$ptr), (i32 (sextloadi8 node:$ptr))>;
1013 def sextloadi32i16 : PatFrag<(ops node:$ptr), (i32 (sextloadi16 node:$ptr))>;
1014 def sextloadi64i8 : PatFrag<(ops node:$ptr), (i64 (sextloadi8 node:$ptr))>;
1015 def sextloadi64i16 : PatFrag<(ops node:$ptr), (i64 (sextloadi16 node:$ptr))>;
1016 def sextloadi64i32 : PatFrag<(ops node:$ptr), (i64 (sextloadi32 node:$ptr))>;
1018 def zextloadi8i1 : PatFrag<(ops node:$ptr), (i8 (zextloadi1 node:$ptr))>;
1019 def zextloadi16i1 : PatFrag<(ops node:$ptr), (i16 (zextloadi1 node:$ptr))>;
1020 def zextloadi32i1 : PatFrag<(ops node:$ptr), (i32 (zextloadi1 node:$ptr))>;
1021 def zextloadi16i8 : PatFrag<(ops node:$ptr), (i16 (zextloadi8 node:$ptr))>;
1022 def zextloadi32i8 : PatFrag<(ops node:$ptr), (i32 (zextloadi8 node:$ptr))>;
1023 def zextloadi32i16 : PatFrag<(ops node:$ptr), (i32 (zextloadi16 node:$ptr))>;
1024 def zextloadi64i1 : PatFrag<(ops node:$ptr), (i64 (zextloadi1 node:$ptr))>;
1025 def zextloadi64i8 : PatFrag<(ops node:$ptr), (i64 (zextloadi8 node:$ptr))>;
1026 def zextloadi64i16 : PatFrag<(ops node:$ptr), (i64 (zextloadi16 node:$ptr))>;
1027 def zextloadi64i32 : PatFrag<(ops node:$ptr), (i64 (zextloadi32 node:$ptr))>;
1029 def extloadi8i1 : PatFrag<(ops node:$ptr), (i8 (extloadi1 node:$ptr))>;
1030 def extloadi16i1 : PatFrag<(ops node:$ptr), (i16 (extloadi1 node:$ptr))>;
1031 def extloadi32i1 : PatFrag<(ops node:$ptr), (i32 (extloadi1 node:$ptr))>;
1032 def extloadi16i8 : PatFrag<(ops node:$ptr), (i16 (extloadi8 node:$ptr))>;
1033 def extloadi32i8 : PatFrag<(ops node:$ptr), (i32 (extloadi8 node:$ptr))>;
1034 def extloadi32i16 : PatFrag<(ops node:$ptr), (i32 (extloadi16 node:$ptr))>;
1035 def extloadi64i1 : PatFrag<(ops node:$ptr), (i64 (extloadi1 node:$ptr))>;
1036 def extloadi64i8 : PatFrag<(ops node:$ptr), (i64 (extloadi8 node:$ptr))>;
1037 def extloadi64i16 : PatFrag<(ops node:$ptr), (i64 (extloadi16 node:$ptr))>;
1038 def extloadi64i32 : PatFrag<(ops node:$ptr), (i64 (extloadi32 node:$ptr))>;
1041 // An 'and' node with a single use.
1042 def and_su : PatFrag<(ops node:$lhs, node:$rhs), (and node:$lhs, node:$rhs), [{
1043 return N->hasOneUse();
1045 // An 'srl' node with a single use.
1046 def srl_su : PatFrag<(ops node:$lhs, node:$rhs), (srl node:$lhs, node:$rhs), [{
1047 return N->hasOneUse();
1049 // An 'trunc' node with a single use.
1050 def trunc_su : PatFrag<(ops node:$src), (trunc node:$src), [{
1051 return N->hasOneUse();
1054 //===----------------------------------------------------------------------===//
1055 // Instruction list.
1059 let hasSideEffects = 0, SchedRW = [WriteZero] in {
1060 def NOOP : I<0x90, RawFrm, (outs), (ins), "nop", [], IIC_NOP>;
1061 def NOOPW : I<0x1f, MRMXm, (outs), (ins i16mem:$zero),
1062 "nop{w}\t$zero", [], IIC_NOP>, TB, OpSize16;
1063 def NOOPL : I<0x1f, MRMXm, (outs), (ins i32mem:$zero),
1064 "nop{l}\t$zero", [], IIC_NOP>, TB, OpSize32;
1068 // Constructing a stack frame.
1069 def ENTER : Ii16<0xC8, RawFrmImm8, (outs), (ins i16imm:$len, i8imm:$lvl),
1070 "enter\t$len, $lvl", [], IIC_ENTER>, Sched<[WriteMicrocoded]>;
1072 let SchedRW = [WriteALU] in {
1073 let Defs = [EBP, ESP], Uses = [EBP, ESP], mayLoad = 1, hasSideEffects=0 in
1074 def LEAVE : I<0xC9, RawFrm,
1075 (outs), (ins), "leave", [], IIC_LEAVE>,
1076 Requires<[Not64BitMode]>;
1078 let Defs = [RBP,RSP], Uses = [RBP,RSP], mayLoad = 1, hasSideEffects = 0 in
1079 def LEAVE64 : I<0xC9, RawFrm,
1080 (outs), (ins), "leave", [], IIC_LEAVE>,
1081 Requires<[In64BitMode]>;
1084 //===----------------------------------------------------------------------===//
1085 // Miscellaneous Instructions.
1088 let isBarrier = 1, hasSideEffects = 1, usesCustomInserter = 1 in
1089 def Int_eh_sjlj_setup_dispatch
1090 : PseudoI<(outs), (ins), [(X86eh_sjlj_setup_dispatch)]>;
1092 let Defs = [ESP], Uses = [ESP], hasSideEffects=0 in {
1093 let mayLoad = 1, SchedRW = [WriteLoad] in {
1094 def POP16r : I<0x58, AddRegFrm, (outs GR16:$reg), (ins), "pop{w}\t$reg", [],
1095 IIC_POP_REG16>, OpSize16;
1096 def POP32r : I<0x58, AddRegFrm, (outs GR32:$reg), (ins), "pop{l}\t$reg", [],
1097 IIC_POP_REG>, OpSize32, Requires<[Not64BitMode]>;
1098 def POP16rmr: I<0x8F, MRM0r, (outs GR16:$reg), (ins), "pop{w}\t$reg", [],
1099 IIC_POP_REG>, OpSize16;
1100 def POP16rmm: I<0x8F, MRM0m, (outs), (ins i16mem:$dst), "pop{w}\t$dst", [],
1101 IIC_POP_MEM>, OpSize16;
1102 def POP32rmr: I<0x8F, MRM0r, (outs GR32:$reg), (ins), "pop{l}\t$reg", [],
1103 IIC_POP_REG>, OpSize32, Requires<[Not64BitMode]>;
1104 def POP32rmm: I<0x8F, MRM0m, (outs), (ins i32mem:$dst), "pop{l}\t$dst", [],
1105 IIC_POP_MEM>, OpSize32, Requires<[Not64BitMode]>;
1106 } // mayLoad, SchedRW
1108 let mayStore = 1, SchedRW = [WriteStore] in {
1109 def PUSH16r : I<0x50, AddRegFrm, (outs), (ins GR16:$reg), "push{w}\t$reg",[],
1110 IIC_PUSH_REG>, OpSize16;
1111 def PUSH32r : I<0x50, AddRegFrm, (outs), (ins GR32:$reg), "push{l}\t$reg",[],
1112 IIC_PUSH_REG>, OpSize32, Requires<[Not64BitMode]>;
1113 def PUSH16rmr: I<0xFF, MRM6r, (outs), (ins GR16:$reg), "push{w}\t$reg",[],
1114 IIC_PUSH_REG>, OpSize16;
1115 def PUSH32rmr: I<0xFF, MRM6r, (outs), (ins GR32:$reg), "push{l}\t$reg",[],
1116 IIC_PUSH_REG>, OpSize32, Requires<[Not64BitMode]>;
1118 def PUSH16i8 : Ii8<0x6a, RawFrm, (outs), (ins i16i8imm:$imm),
1119 "push{w}\t$imm", [], IIC_PUSH_IMM>, OpSize16;
1120 def PUSHi16 : Ii16<0x68, RawFrm, (outs), (ins i16imm:$imm),
1121 "push{w}\t$imm", [], IIC_PUSH_IMM>, OpSize16;
1123 def PUSH32i8 : Ii8<0x6a, RawFrm, (outs), (ins i32i8imm:$imm),
1124 "push{l}\t$imm", [], IIC_PUSH_IMM>, OpSize32,
1125 Requires<[Not64BitMode]>;
1126 def PUSHi32 : Ii32<0x68, RawFrm, (outs), (ins i32imm:$imm),
1127 "push{l}\t$imm", [], IIC_PUSH_IMM>, OpSize32,
1128 Requires<[Not64BitMode]>;
1129 } // mayStore, SchedRW
1131 let mayLoad = 1, mayStore = 1, SchedRW = [WriteRMW] in {
1132 def PUSH16rmm: I<0xFF, MRM6m, (outs), (ins i16mem:$src), "push{w}\t$src",[],
1133 IIC_PUSH_MEM>, OpSize16;
1134 def PUSH32rmm: I<0xFF, MRM6m, (outs), (ins i32mem:$src), "push{l}\t$src",[],
1135 IIC_PUSH_MEM>, OpSize32, Requires<[Not64BitMode]>;
1136 } // mayLoad, mayStore, SchedRW
1140 let mayLoad = 1, mayStore = 1, usesCustomInserter = 1,
1141 SchedRW = [WriteRMW], Defs = [ESP] in {
1143 def RDFLAGS32 : PseudoI<(outs GR32:$dst), (ins),
1144 [(set GR32:$dst, (int_x86_flags_read_u32))]>,
1145 Requires<[Not64BitMode]>;
1148 def RDFLAGS64 : PseudoI<(outs GR64:$dst), (ins),
1149 [(set GR64:$dst, (int_x86_flags_read_u64))]>,
1150 Requires<[In64BitMode]>;
1153 let mayLoad = 1, mayStore = 1, usesCustomInserter = 1,
1154 SchedRW = [WriteRMW] in {
1155 let Defs = [ESP, EFLAGS], Uses = [ESP] in
1156 def WRFLAGS32 : PseudoI<(outs), (ins GR32:$src),
1157 [(int_x86_flags_write_u32 GR32:$src)]>,
1158 Requires<[Not64BitMode]>;
1160 let Defs = [RSP, EFLAGS], Uses = [RSP] in
1161 def WRFLAGS64 : PseudoI<(outs), (ins GR64:$src),
1162 [(int_x86_flags_write_u64 GR64:$src)]>,
1163 Requires<[In64BitMode]>;
1166 let Defs = [ESP, EFLAGS], Uses = [ESP], mayLoad = 1, hasSideEffects=0,
1167 SchedRW = [WriteLoad] in {
1168 def POPF16 : I<0x9D, RawFrm, (outs), (ins), "popf{w}", [], IIC_POP_F>,
1170 def POPF32 : I<0x9D, RawFrm, (outs), (ins), "popf{l|d}", [], IIC_POP_FD>,
1171 OpSize32, Requires<[Not64BitMode]>;
1174 let Defs = [ESP], Uses = [ESP, EFLAGS], mayStore = 1, hasSideEffects=0,
1175 SchedRW = [WriteStore] in {
1176 def PUSHF16 : I<0x9C, RawFrm, (outs), (ins), "pushf{w}", [], IIC_PUSH_F>,
1178 def PUSHF32 : I<0x9C, RawFrm, (outs), (ins), "pushf{l|d}", [], IIC_PUSH_F>,
1179 OpSize32, Requires<[Not64BitMode]>;
1182 let Defs = [RSP], Uses = [RSP], hasSideEffects=0 in {
1183 let mayLoad = 1, SchedRW = [WriteLoad] in {
1184 def POP64r : I<0x58, AddRegFrm, (outs GR64:$reg), (ins), "pop{q}\t$reg", [],
1185 IIC_POP_REG>, OpSize32, Requires<[In64BitMode]>;
1186 def POP64rmr: I<0x8F, MRM0r, (outs GR64:$reg), (ins), "pop{q}\t$reg", [],
1187 IIC_POP_REG>, OpSize32, Requires<[In64BitMode]>;
1188 def POP64rmm: I<0x8F, MRM0m, (outs), (ins i64mem:$dst), "pop{q}\t$dst", [],
1189 IIC_POP_MEM>, OpSize32, Requires<[In64BitMode]>;
1190 } // mayLoad, SchedRW
1191 let mayStore = 1, SchedRW = [WriteStore] in {
1192 def PUSH64r : I<0x50, AddRegFrm, (outs), (ins GR64:$reg), "push{q}\t$reg", [],
1193 IIC_PUSH_REG>, OpSize32, Requires<[In64BitMode]>;
1194 def PUSH64rmr: I<0xFF, MRM6r, (outs), (ins GR64:$reg), "push{q}\t$reg", [],
1195 IIC_PUSH_REG>, OpSize32, Requires<[In64BitMode]>;
1196 } // mayStore, SchedRW
1197 let mayLoad = 1, mayStore = 1, SchedRW = [WriteRMW] in {
1198 def PUSH64rmm: I<0xFF, MRM6m, (outs), (ins i64mem:$src), "push{q}\t$src", [],
1199 IIC_PUSH_MEM>, OpSize32, Requires<[In64BitMode]>;
1200 } // mayLoad, mayStore, SchedRW
1203 let Defs = [RSP], Uses = [RSP], hasSideEffects = 0, mayStore = 1,
1204 SchedRW = [WriteStore] in {
1205 def PUSH64i8 : Ii8<0x6a, RawFrm, (outs), (ins i64i8imm:$imm),
1206 "push{q}\t$imm", [], IIC_PUSH_IMM>, OpSize32,
1207 Requires<[In64BitMode]>;
1208 def PUSH64i32 : Ii32S<0x68, RawFrm, (outs), (ins i64i32imm:$imm),
1209 "push{q}\t$imm", [], IIC_PUSH_IMM>, OpSize32,
1210 Requires<[In64BitMode]>;
1213 let Defs = [RSP, EFLAGS], Uses = [RSP], mayLoad = 1, hasSideEffects=0 in
1214 def POPF64 : I<0x9D, RawFrm, (outs), (ins), "popfq", [], IIC_POP_FD>,
1215 OpSize32, Requires<[In64BitMode]>, Sched<[WriteLoad]>;
1216 let Defs = [RSP], Uses = [RSP, EFLAGS], mayStore = 1, hasSideEffects=0 in
1217 def PUSHF64 : I<0x9C, RawFrm, (outs), (ins), "pushfq", [], IIC_PUSH_F>,
1218 OpSize32, Requires<[In64BitMode]>, Sched<[WriteStore]>;
1220 let Defs = [EDI, ESI, EBP, EBX, EDX, ECX, EAX, ESP], Uses = [ESP],
1221 mayLoad = 1, hasSideEffects = 0, SchedRW = [WriteLoad] in {
1222 def POPA32 : I<0x61, RawFrm, (outs), (ins), "popal", [], IIC_POP_A>,
1223 OpSize32, Requires<[Not64BitMode]>;
1224 def POPA16 : I<0x61, RawFrm, (outs), (ins), "popaw", [], IIC_POP_A>,
1225 OpSize16, Requires<[Not64BitMode]>;
1227 let Defs = [ESP], Uses = [EDI, ESI, EBP, EBX, EDX, ECX, EAX, ESP],
1228 mayStore = 1, hasSideEffects = 0, SchedRW = [WriteStore] in {
1229 def PUSHA32 : I<0x60, RawFrm, (outs), (ins), "pushal", [], IIC_PUSH_A>,
1230 OpSize32, Requires<[Not64BitMode]>;
1231 def PUSHA16 : I<0x60, RawFrm, (outs), (ins), "pushaw", [], IIC_PUSH_A>,
1232 OpSize16, Requires<[Not64BitMode]>;
1235 let Constraints = "$src = $dst", SchedRW = [WriteALU] in {
1236 // GR32 = bswap GR32
1237 def BSWAP32r : I<0xC8, AddRegFrm,
1238 (outs GR32:$dst), (ins GR32:$src),
1240 [(set GR32:$dst, (bswap GR32:$src))], IIC_BSWAP>, OpSize32, TB;
1242 def BSWAP64r : RI<0xC8, AddRegFrm, (outs GR64:$dst), (ins GR64:$src),
1244 [(set GR64:$dst, (bswap GR64:$src))], IIC_BSWAP>, TB;
1245 } // Constraints = "$src = $dst", SchedRW
1247 // Bit scan instructions.
1248 let Defs = [EFLAGS] in {
1249 def BSF16rr : I<0xBC, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
1250 "bsf{w}\t{$src, $dst|$dst, $src}",
1251 [(set GR16:$dst, EFLAGS, (X86bsf GR16:$src))],
1252 IIC_BIT_SCAN_REG>, PS, OpSize16, Sched<[WriteShift]>;
1253 def BSF16rm : I<0xBC, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
1254 "bsf{w}\t{$src, $dst|$dst, $src}",
1255 [(set GR16:$dst, EFLAGS, (X86bsf (loadi16 addr:$src)))],
1256 IIC_BIT_SCAN_MEM>, PS, OpSize16, Sched<[WriteShiftLd]>;
1257 def BSF32rr : I<0xBC, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
1258 "bsf{l}\t{$src, $dst|$dst, $src}",
1259 [(set GR32:$dst, EFLAGS, (X86bsf GR32:$src))],
1260 IIC_BIT_SCAN_REG>, PS, OpSize32, Sched<[WriteShift]>;
1261 def BSF32rm : I<0xBC, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
1262 "bsf{l}\t{$src, $dst|$dst, $src}",
1263 [(set GR32:$dst, EFLAGS, (X86bsf (loadi32 addr:$src)))],
1264 IIC_BIT_SCAN_MEM>, PS, OpSize32, Sched<[WriteShiftLd]>;
1265 def BSF64rr : RI<0xBC, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
1266 "bsf{q}\t{$src, $dst|$dst, $src}",
1267 [(set GR64:$dst, EFLAGS, (X86bsf GR64:$src))],
1268 IIC_BIT_SCAN_REG>, PS, Sched<[WriteShift]>;
1269 def BSF64rm : RI<0xBC, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
1270 "bsf{q}\t{$src, $dst|$dst, $src}",
1271 [(set GR64:$dst, EFLAGS, (X86bsf (loadi64 addr:$src)))],
1272 IIC_BIT_SCAN_MEM>, PS, Sched<[WriteShiftLd]>;
1274 def BSR16rr : I<0xBD, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
1275 "bsr{w}\t{$src, $dst|$dst, $src}",
1276 [(set GR16:$dst, EFLAGS, (X86bsr GR16:$src))],
1277 IIC_BIT_SCAN_REG>, PS, OpSize16, Sched<[WriteShift]>;
1278 def BSR16rm : I<0xBD, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
1279 "bsr{w}\t{$src, $dst|$dst, $src}",
1280 [(set GR16:$dst, EFLAGS, (X86bsr (loadi16 addr:$src)))],
1281 IIC_BIT_SCAN_MEM>, PS, OpSize16, Sched<[WriteShiftLd]>;
1282 def BSR32rr : I<0xBD, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
1283 "bsr{l}\t{$src, $dst|$dst, $src}",
1284 [(set GR32:$dst, EFLAGS, (X86bsr GR32:$src))],
1285 IIC_BIT_SCAN_REG>, PS, OpSize32, Sched<[WriteShift]>;
1286 def BSR32rm : I<0xBD, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
1287 "bsr{l}\t{$src, $dst|$dst, $src}",
1288 [(set GR32:$dst, EFLAGS, (X86bsr (loadi32 addr:$src)))],
1289 IIC_BIT_SCAN_MEM>, PS, OpSize32, Sched<[WriteShiftLd]>;
1290 def BSR64rr : RI<0xBD, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
1291 "bsr{q}\t{$src, $dst|$dst, $src}",
1292 [(set GR64:$dst, EFLAGS, (X86bsr GR64:$src))],
1293 IIC_BIT_SCAN_REG>, PS, Sched<[WriteShift]>;
1294 def BSR64rm : RI<0xBD, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
1295 "bsr{q}\t{$src, $dst|$dst, $src}",
1296 [(set GR64:$dst, EFLAGS, (X86bsr (loadi64 addr:$src)))],
1297 IIC_BIT_SCAN_MEM>, PS, Sched<[WriteShiftLd]>;
1298 } // Defs = [EFLAGS]
1300 let SchedRW = [WriteMicrocoded] in {
1301 // These uses the DF flag in the EFLAGS register to inc or dec EDI and ESI
1302 let Defs = [EDI,ESI], Uses = [EDI,ESI,EFLAGS] in {
1303 def MOVSB : I<0xA4, RawFrmDstSrc, (outs), (ins dstidx8:$dst, srcidx8:$src),
1304 "movsb\t{$src, $dst|$dst, $src}", [], IIC_MOVS>;
1305 def MOVSW : I<0xA5, RawFrmDstSrc, (outs), (ins dstidx16:$dst, srcidx16:$src),
1306 "movsw\t{$src, $dst|$dst, $src}", [], IIC_MOVS>, OpSize16;
1307 def MOVSL : I<0xA5, RawFrmDstSrc, (outs), (ins dstidx32:$dst, srcidx32:$src),
1308 "movs{l|d}\t{$src, $dst|$dst, $src}", [], IIC_MOVS>, OpSize32;
1309 def MOVSQ : RI<0xA5, RawFrmDstSrc, (outs), (ins dstidx64:$dst, srcidx64:$src),
1310 "movsq\t{$src, $dst|$dst, $src}", [], IIC_MOVS>;
1313 // These uses the DF flag in the EFLAGS register to inc or dec EDI and ESI
1314 let Defs = [EDI], Uses = [AL,EDI,EFLAGS] in
1315 def STOSB : I<0xAA, RawFrmDst, (outs), (ins dstidx8:$dst),
1316 "stosb\t{%al, $dst|$dst, al}", [], IIC_STOS>;
1317 let Defs = [EDI], Uses = [AX,EDI,EFLAGS] in
1318 def STOSW : I<0xAB, RawFrmDst, (outs), (ins dstidx16:$dst),
1319 "stosw\t{%ax, $dst|$dst, ax}", [], IIC_STOS>, OpSize16;
1320 let Defs = [EDI], Uses = [EAX,EDI,EFLAGS] in
1321 def STOSL : I<0xAB, RawFrmDst, (outs), (ins dstidx32:$dst),
1322 "stos{l|d}\t{%eax, $dst|$dst, eax}", [], IIC_STOS>, OpSize32;
1323 let Defs = [RDI], Uses = [RAX,RDI,EFLAGS] in
1324 def STOSQ : RI<0xAB, RawFrmDst, (outs), (ins dstidx64:$dst),
1325 "stosq\t{%rax, $dst|$dst, rax}", [], IIC_STOS>;
1327 // These uses the DF flag in the EFLAGS register to inc or dec EDI and ESI
1328 let Defs = [EDI,EFLAGS], Uses = [AL,EDI,EFLAGS] in
1329 def SCASB : I<0xAE, RawFrmDst, (outs), (ins dstidx8:$dst),
1330 "scasb\t{$dst, %al|al, $dst}", [], IIC_SCAS>;
1331 let Defs = [EDI,EFLAGS], Uses = [AX,EDI,EFLAGS] in
1332 def SCASW : I<0xAF, RawFrmDst, (outs), (ins dstidx16:$dst),
1333 "scasw\t{$dst, %ax|ax, $dst}", [], IIC_SCAS>, OpSize16;
1334 let Defs = [EDI,EFLAGS], Uses = [EAX,EDI,EFLAGS] in
1335 def SCASL : I<0xAF, RawFrmDst, (outs), (ins dstidx32:$dst),
1336 "scas{l|d}\t{$dst, %eax|eax, $dst}", [], IIC_SCAS>, OpSize32;
1337 let Defs = [EDI,EFLAGS], Uses = [RAX,EDI,EFLAGS] in
1338 def SCASQ : RI<0xAF, RawFrmDst, (outs), (ins dstidx64:$dst),
1339 "scasq\t{$dst, %rax|rax, $dst}", [], IIC_SCAS>;
1341 // These uses the DF flag in the EFLAGS register to inc or dec EDI and ESI
1342 let Defs = [EDI,ESI,EFLAGS], Uses = [EDI,ESI,EFLAGS] in {
1343 def CMPSB : I<0xA6, RawFrmDstSrc, (outs), (ins dstidx8:$dst, srcidx8:$src),
1344 "cmpsb\t{$dst, $src|$src, $dst}", [], IIC_CMPS>;
1345 def CMPSW : I<0xA7, RawFrmDstSrc, (outs), (ins dstidx16:$dst, srcidx16:$src),
1346 "cmpsw\t{$dst, $src|$src, $dst}", [], IIC_CMPS>, OpSize16;
1347 def CMPSL : I<0xA7, RawFrmDstSrc, (outs), (ins dstidx32:$dst, srcidx32:$src),
1348 "cmps{l|d}\t{$dst, $src|$src, $dst}", [], IIC_CMPS>, OpSize32;
1349 def CMPSQ : RI<0xA7, RawFrmDstSrc, (outs), (ins dstidx64:$dst, srcidx64:$src),
1350 "cmpsq\t{$dst, $src|$src, $dst}", [], IIC_CMPS>;
1354 //===----------------------------------------------------------------------===//
1355 // Move Instructions.
1357 let SchedRW = [WriteMove] in {
1358 let hasSideEffects = 0 in {
1359 def MOV8rr : I<0x88, MRMDestReg, (outs GR8 :$dst), (ins GR8 :$src),
1360 "mov{b}\t{$src, $dst|$dst, $src}", [], IIC_MOV>;
1361 def MOV16rr : I<0x89, MRMDestReg, (outs GR16:$dst), (ins GR16:$src),
1362 "mov{w}\t{$src, $dst|$dst, $src}", [], IIC_MOV>, OpSize16;
1363 def MOV32rr : I<0x89, MRMDestReg, (outs GR32:$dst), (ins GR32:$src),
1364 "mov{l}\t{$src, $dst|$dst, $src}", [], IIC_MOV>, OpSize32;
1365 def MOV64rr : RI<0x89, MRMDestReg, (outs GR64:$dst), (ins GR64:$src),
1366 "mov{q}\t{$src, $dst|$dst, $src}", [], IIC_MOV>;
1369 let isReMaterializable = 1, isAsCheapAsAMove = 1 in {
1370 def MOV8ri : Ii8 <0xB0, AddRegFrm, (outs GR8 :$dst), (ins i8imm :$src),
1371 "mov{b}\t{$src, $dst|$dst, $src}",
1372 [(set GR8:$dst, imm:$src)], IIC_MOV>;
1373 def MOV16ri : Ii16<0xB8, AddRegFrm, (outs GR16:$dst), (ins i16imm:$src),
1374 "mov{w}\t{$src, $dst|$dst, $src}",
1375 [(set GR16:$dst, imm:$src)], IIC_MOV>, OpSize16;
1376 def MOV32ri : Ii32<0xB8, AddRegFrm, (outs GR32:$dst), (ins i32imm:$src),
1377 "mov{l}\t{$src, $dst|$dst, $src}",
1378 [(set GR32:$dst, imm:$src)], IIC_MOV>, OpSize32;
1379 def MOV64ri32 : RIi32S<0xC7, MRM0r, (outs GR64:$dst), (ins i64i32imm:$src),
1380 "mov{q}\t{$src, $dst|$dst, $src}",
1381 [(set GR64:$dst, i64immSExt32:$src)], IIC_MOV>;
1383 let isReMaterializable = 1 in {
1384 def MOV64ri : RIi64<0xB8, AddRegFrm, (outs GR64:$dst), (ins i64imm:$src),
1385 "movabs{q}\t{$src, $dst|$dst, $src}",
1386 [(set GR64:$dst, imm:$src)], IIC_MOV>;
1389 // Longer forms that use a ModR/M byte. Needed for disassembler
1390 let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0 in {
1391 def MOV8ri_alt : Ii8 <0xC6, MRM0r, (outs GR8 :$dst), (ins i8imm :$src),
1392 "mov{b}\t{$src, $dst|$dst, $src}", [], IIC_MOV>;
1393 def MOV16ri_alt : Ii16<0xC7, MRM0r, (outs GR16:$dst), (ins i16imm:$src),
1394 "mov{w}\t{$src, $dst|$dst, $src}", [], IIC_MOV>, OpSize16;
1395 def MOV32ri_alt : Ii32<0xC7, MRM0r, (outs GR32:$dst), (ins i32imm:$src),
1396 "mov{l}\t{$src, $dst|$dst, $src}", [], IIC_MOV>, OpSize32;
1400 let SchedRW = [WriteStore] in {
1401 def MOV8mi : Ii8 <0xC6, MRM0m, (outs), (ins i8mem :$dst, i8imm :$src),
1402 "mov{b}\t{$src, $dst|$dst, $src}",
1403 [(store (i8 imm8_su:$src), addr:$dst)], IIC_MOV_MEM>;
1404 def MOV16mi : Ii16<0xC7, MRM0m, (outs), (ins i16mem:$dst, i16imm:$src),
1405 "mov{w}\t{$src, $dst|$dst, $src}",
1406 [(store (i16 imm16_su:$src), addr:$dst)], IIC_MOV_MEM>, OpSize16;
1407 def MOV32mi : Ii32<0xC7, MRM0m, (outs), (ins i32mem:$dst, i32imm:$src),
1408 "mov{l}\t{$src, $dst|$dst, $src}",
1409 [(store (i32 imm32_su:$src), addr:$dst)], IIC_MOV_MEM>, OpSize32;
1410 def MOV64mi32 : RIi32S<0xC7, MRM0m, (outs), (ins i64mem:$dst, i64i32imm:$src),
1411 "mov{q}\t{$src, $dst|$dst, $src}",
1412 [(store i64immSExt32:$src, addr:$dst)], IIC_MOV_MEM>;
1415 let hasSideEffects = 0 in {
1417 /// Memory offset versions of moves. The immediate is an address mode sized
1418 /// offset from the segment base.
1419 let SchedRW = [WriteALU] in {
1420 let mayLoad = 1 in {
1422 def MOV8ao32 : Ii32<0xA0, RawFrmMemOffs, (outs), (ins offset32_8:$src),
1423 "mov{b}\t{$src, %al|al, $src}", [], IIC_MOV_MEM>,
1426 def MOV16ao32 : Ii32<0xA1, RawFrmMemOffs, (outs), (ins offset32_16:$src),
1427 "mov{w}\t{$src, %ax|ax, $src}", [], IIC_MOV_MEM>,
1430 def MOV32ao32 : Ii32<0xA1, RawFrmMemOffs, (outs), (ins offset32_32:$src),
1431 "mov{l}\t{$src, %eax|eax, $src}", [], IIC_MOV_MEM>,
1434 def MOV64ao32 : RIi32<0xA1, RawFrmMemOffs, (outs), (ins offset32_64:$src),
1435 "mov{q}\t{$src, %rax|rax, $src}", [], IIC_MOV_MEM>,
1439 def MOV8ao16 : Ii16<0xA0, RawFrmMemOffs, (outs), (ins offset16_8:$src),
1440 "mov{b}\t{$src, %al|al, $src}", [], IIC_MOV_MEM>, AdSize16;
1442 def MOV16ao16 : Ii16<0xA1, RawFrmMemOffs, (outs), (ins offset16_16:$src),
1443 "mov{w}\t{$src, %ax|ax, $src}", [], IIC_MOV_MEM>,
1446 def MOV32ao16 : Ii16<0xA1, RawFrmMemOffs, (outs), (ins offset16_32:$src),
1447 "mov{l}\t{$src, %eax|eax, $src}", [], IIC_MOV_MEM>,
1450 let mayStore = 1 in {
1452 def MOV8o32a : Ii32<0xA2, RawFrmMemOffs, (outs), (ins offset32_8:$dst),
1453 "mov{b}\t{%al, $dst|$dst, al}", [], IIC_MOV_MEM>, AdSize32;
1455 def MOV16o32a : Ii32<0xA3, RawFrmMemOffs, (outs), (ins offset32_16:$dst),
1456 "mov{w}\t{%ax, $dst|$dst, ax}", [], IIC_MOV_MEM>,
1459 def MOV32o32a : Ii32<0xA3, RawFrmMemOffs, (outs), (ins offset32_32:$dst),
1460 "mov{l}\t{%eax, $dst|$dst, eax}", [], IIC_MOV_MEM>,
1463 def MOV64o32a : RIi32<0xA3, RawFrmMemOffs, (outs), (ins offset32_64:$dst),
1464 "mov{q}\t{%rax, $dst|$dst, rax}", [], IIC_MOV_MEM>,
1468 def MOV8o16a : Ii16<0xA2, RawFrmMemOffs, (outs), (ins offset16_8:$dst),
1469 "mov{b}\t{%al, $dst|$dst, al}", [], IIC_MOV_MEM>, AdSize16;
1471 def MOV16o16a : Ii16<0xA3, RawFrmMemOffs, (outs), (ins offset16_16:$dst),
1472 "mov{w}\t{%ax, $dst|$dst, ax}", [], IIC_MOV_MEM>,
1475 def MOV32o16a : Ii16<0xA3, RawFrmMemOffs, (outs), (ins offset16_32:$dst),
1476 "mov{l}\t{%eax, $dst|$dst, eax}", [], IIC_MOV_MEM>,
1481 // These forms all have full 64-bit absolute addresses in their instructions
1482 // and use the movabs mnemonic to indicate this specific form.
1483 let mayLoad = 1 in {
1485 def MOV8ao64 : RIi64_NOREX<0xA0, RawFrmMemOffs, (outs), (ins offset64_8:$src),
1486 "movabs{b}\t{$src, %al|al, $src}", []>, AdSize64;
1488 def MOV16ao64 : RIi64_NOREX<0xA1, RawFrmMemOffs, (outs), (ins offset64_16:$src),
1489 "movabs{w}\t{$src, %ax|ax, $src}", []>, OpSize16, AdSize64;
1491 def MOV32ao64 : RIi64_NOREX<0xA1, RawFrmMemOffs, (outs), (ins offset64_32:$src),
1492 "movabs{l}\t{$src, %eax|eax, $src}", []>, OpSize32,
1495 def MOV64ao64 : RIi64<0xA1, RawFrmMemOffs, (outs), (ins offset64_64:$src),
1496 "movabs{q}\t{$src, %rax|rax, $src}", []>, AdSize64;
1499 let mayStore = 1 in {
1501 def MOV8o64a : RIi64_NOREX<0xA2, RawFrmMemOffs, (outs), (ins offset64_8:$dst),
1502 "movabs{b}\t{%al, $dst|$dst, al}", []>, AdSize64;
1504 def MOV16o64a : RIi64_NOREX<0xA3, RawFrmMemOffs, (outs), (ins offset64_16:$dst),
1505 "movabs{w}\t{%ax, $dst|$dst, ax}", []>, OpSize16, AdSize64;
1507 def MOV32o64a : RIi64_NOREX<0xA3, RawFrmMemOffs, (outs), (ins offset64_32:$dst),
1508 "movabs{l}\t{%eax, $dst|$dst, eax}", []>, OpSize32,
1511 def MOV64o64a : RIi64<0xA3, RawFrmMemOffs, (outs), (ins offset64_64:$dst),
1512 "movabs{q}\t{%rax, $dst|$dst, rax}", []>, AdSize64;
1514 } // hasSideEffects = 0
1516 let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0,
1517 SchedRW = [WriteMove] in {
1518 def MOV8rr_REV : I<0x8A, MRMSrcReg, (outs GR8:$dst), (ins GR8:$src),
1519 "mov{b}\t{$src, $dst|$dst, $src}", [], IIC_MOV>;
1520 def MOV16rr_REV : I<0x8B, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
1521 "mov{w}\t{$src, $dst|$dst, $src}", [], IIC_MOV>, OpSize16;
1522 def MOV32rr_REV : I<0x8B, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
1523 "mov{l}\t{$src, $dst|$dst, $src}", [], IIC_MOV>, OpSize32;
1524 def MOV64rr_REV : RI<0x8B, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
1525 "mov{q}\t{$src, $dst|$dst, $src}", [], IIC_MOV>;
1528 let canFoldAsLoad = 1, isReMaterializable = 1, SchedRW = [WriteLoad] in {
1529 def MOV8rm : I<0x8A, MRMSrcMem, (outs GR8 :$dst), (ins i8mem :$src),
1530 "mov{b}\t{$src, $dst|$dst, $src}",
1531 [(set GR8:$dst, (loadi8 addr:$src))], IIC_MOV_MEM>;
1532 def MOV16rm : I<0x8B, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
1533 "mov{w}\t{$src, $dst|$dst, $src}",
1534 [(set GR16:$dst, (loadi16 addr:$src))], IIC_MOV_MEM>, OpSize16;
1535 def MOV32rm : I<0x8B, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
1536 "mov{l}\t{$src, $dst|$dst, $src}",
1537 [(set GR32:$dst, (loadi32 addr:$src))], IIC_MOV_MEM>, OpSize32;
1538 def MOV64rm : RI<0x8B, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
1539 "mov{q}\t{$src, $dst|$dst, $src}",
1540 [(set GR64:$dst, (load addr:$src))], IIC_MOV_MEM>;
1543 let SchedRW = [WriteStore] in {
1544 def MOV8mr : I<0x88, MRMDestMem, (outs), (ins i8mem :$dst, GR8 :$src),
1545 "mov{b}\t{$src, $dst|$dst, $src}",
1546 [(store GR8:$src, addr:$dst)], IIC_MOV_MEM>;
1547 def MOV16mr : I<0x89, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src),
1548 "mov{w}\t{$src, $dst|$dst, $src}",
1549 [(store GR16:$src, addr:$dst)], IIC_MOV_MEM>, OpSize16;
1550 def MOV32mr : I<0x89, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
1551 "mov{l}\t{$src, $dst|$dst, $src}",
1552 [(store GR32:$src, addr:$dst)], IIC_MOV_MEM>, OpSize32;
1553 def MOV64mr : RI<0x89, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
1554 "mov{q}\t{$src, $dst|$dst, $src}",
1555 [(store GR64:$src, addr:$dst)], IIC_MOV_MEM>;
1558 // Versions of MOV8rr, MOV8mr, and MOV8rm that use i8mem_NOREX and GR8_NOREX so
1559 // that they can be used for copying and storing h registers, which can't be
1560 // encoded when a REX prefix is present.
1561 let isCodeGenOnly = 1 in {
1562 let hasSideEffects = 0 in
1563 def MOV8rr_NOREX : I<0x88, MRMDestReg,
1564 (outs GR8_NOREX:$dst), (ins GR8_NOREX:$src),
1565 "mov{b}\t{$src, $dst|$dst, $src} # NOREX", [], IIC_MOV>,
1567 let mayStore = 1, hasSideEffects = 0 in
1568 def MOV8mr_NOREX : I<0x88, MRMDestMem,
1569 (outs), (ins i8mem_NOREX:$dst, GR8_NOREX:$src),
1570 "mov{b}\t{$src, $dst|$dst, $src} # NOREX", [],
1571 IIC_MOV_MEM>, Sched<[WriteStore]>;
1572 let mayLoad = 1, hasSideEffects = 0,
1573 canFoldAsLoad = 1, isReMaterializable = 1 in
1574 def MOV8rm_NOREX : I<0x8A, MRMSrcMem,
1575 (outs GR8_NOREX:$dst), (ins i8mem_NOREX:$src),
1576 "mov{b}\t{$src, $dst|$dst, $src} # NOREX", [],
1577 IIC_MOV_MEM>, Sched<[WriteLoad]>;
1581 // Condition code ops, incl. set if equal/not equal/...
1582 let SchedRW = [WriteALU] in {
1583 let Defs = [EFLAGS], Uses = [AH] in
1584 def SAHF : I<0x9E, RawFrm, (outs), (ins), "sahf",
1585 [(set EFLAGS, (X86sahf AH))], IIC_AHF>,
1586 Requires<[HasLAHFSAHF]>;
1587 let Defs = [AH], Uses = [EFLAGS], hasSideEffects = 0 in
1588 def LAHF : I<0x9F, RawFrm, (outs), (ins), "lahf", [],
1589 IIC_AHF>, // AH = flags
1590 Requires<[HasLAHFSAHF]>;
1593 //===----------------------------------------------------------------------===//
1594 // Bit tests instructions: BT, BTS, BTR, BTC.
1596 let Defs = [EFLAGS] in {
1597 let SchedRW = [WriteALU] in {
1598 def BT16rr : I<0xA3, MRMDestReg, (outs), (ins GR16:$src1, GR16:$src2),
1599 "bt{w}\t{$src2, $src1|$src1, $src2}",
1600 [(set EFLAGS, (X86bt GR16:$src1, GR16:$src2))], IIC_BT_RR>,
1602 def BT32rr : I<0xA3, MRMDestReg, (outs), (ins GR32:$src1, GR32:$src2),
1603 "bt{l}\t{$src2, $src1|$src1, $src2}",
1604 [(set EFLAGS, (X86bt GR32:$src1, GR32:$src2))], IIC_BT_RR>,
1606 def BT64rr : RI<0xA3, MRMDestReg, (outs), (ins GR64:$src1, GR64:$src2),
1607 "bt{q}\t{$src2, $src1|$src1, $src2}",
1608 [(set EFLAGS, (X86bt GR64:$src1, GR64:$src2))], IIC_BT_RR>, TB;
1611 // Unlike with the register+register form, the memory+register form of the
1612 // bt instruction does not ignore the high bits of the index. From ISel's
1613 // perspective, this is pretty bizarre. Make these instructions disassembly
1616 let mayLoad = 1, hasSideEffects = 0, SchedRW = [WriteALULd] in {
1617 def BT16mr : I<0xA3, MRMDestMem, (outs), (ins i16mem:$src1, GR16:$src2),
1618 "bt{w}\t{$src2, $src1|$src1, $src2}",
1619 // [(X86bt (loadi16 addr:$src1), GR16:$src2),
1620 // (implicit EFLAGS)]
1622 >, OpSize16, TB, Requires<[FastBTMem]>;
1623 def BT32mr : I<0xA3, MRMDestMem, (outs), (ins i32mem:$src1, GR32:$src2),
1624 "bt{l}\t{$src2, $src1|$src1, $src2}",
1625 // [(X86bt (loadi32 addr:$src1), GR32:$src2),
1626 // (implicit EFLAGS)]
1628 >, OpSize32, TB, Requires<[FastBTMem]>;
1629 def BT64mr : RI<0xA3, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2),
1630 "bt{q}\t{$src2, $src1|$src1, $src2}",
1631 // [(X86bt (loadi64 addr:$src1), GR64:$src2),
1632 // (implicit EFLAGS)]
1637 let SchedRW = [WriteALU] in {
1638 def BT16ri8 : Ii8<0xBA, MRM4r, (outs), (ins GR16:$src1, i16i8imm:$src2),
1639 "bt{w}\t{$src2, $src1|$src1, $src2}",
1640 [(set EFLAGS, (X86bt GR16:$src1, i16immSExt8:$src2))],
1641 IIC_BT_RI>, OpSize16, TB;
1642 def BT32ri8 : Ii8<0xBA, MRM4r, (outs), (ins GR32:$src1, i32i8imm:$src2),
1643 "bt{l}\t{$src2, $src1|$src1, $src2}",
1644 [(set EFLAGS, (X86bt GR32:$src1, i32immSExt8:$src2))],
1645 IIC_BT_RI>, OpSize32, TB;
1646 def BT64ri8 : RIi8<0xBA, MRM4r, (outs), (ins GR64:$src1, i64i8imm:$src2),
1647 "bt{q}\t{$src2, $src1|$src1, $src2}",
1648 [(set EFLAGS, (X86bt GR64:$src1, i64immSExt8:$src2))],
1652 // Note that these instructions don't need FastBTMem because that
1653 // only applies when the other operand is in a register. When it's
1654 // an immediate, bt is still fast.
1655 let SchedRW = [WriteALU] in {
1656 def BT16mi8 : Ii8<0xBA, MRM4m, (outs), (ins i16mem:$src1, i16i8imm:$src2),
1657 "bt{w}\t{$src2, $src1|$src1, $src2}",
1658 [(set EFLAGS, (X86bt (loadi16 addr:$src1), i16immSExt8:$src2))
1659 ], IIC_BT_MI>, OpSize16, TB;
1660 def BT32mi8 : Ii8<0xBA, MRM4m, (outs), (ins i32mem:$src1, i32i8imm:$src2),
1661 "bt{l}\t{$src2, $src1|$src1, $src2}",
1662 [(set EFLAGS, (X86bt (loadi32 addr:$src1), i32immSExt8:$src2))
1663 ], IIC_BT_MI>, OpSize32, TB;
1664 def BT64mi8 : RIi8<0xBA, MRM4m, (outs), (ins i64mem:$src1, i64i8imm:$src2),
1665 "bt{q}\t{$src2, $src1|$src1, $src2}",
1666 [(set EFLAGS, (X86bt (loadi64 addr:$src1),
1667 i64immSExt8:$src2))], IIC_BT_MI>, TB;
1670 let hasSideEffects = 0 in {
1671 let SchedRW = [WriteALU] in {
1672 def BTC16rr : I<0xBB, MRMDestReg, (outs), (ins GR16:$src1, GR16:$src2),
1673 "btc{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>,
1675 def BTC32rr : I<0xBB, MRMDestReg, (outs), (ins GR32:$src1, GR32:$src2),
1676 "btc{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>,
1678 def BTC64rr : RI<0xBB, MRMDestReg, (outs), (ins GR64:$src1, GR64:$src2),
1679 "btc{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>, TB;
1682 let mayLoad = 1, mayStore = 1, SchedRW = [WriteALULd, WriteRMW] in {
1683 def BTC16mr : I<0xBB, MRMDestMem, (outs), (ins i16mem:$src1, GR16:$src2),
1684 "btc{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>,
1686 def BTC32mr : I<0xBB, MRMDestMem, (outs), (ins i32mem:$src1, GR32:$src2),
1687 "btc{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>,
1689 def BTC64mr : RI<0xBB, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2),
1690 "btc{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>, TB;
1693 let SchedRW = [WriteALU] in {
1694 def BTC16ri8 : Ii8<0xBA, MRM7r, (outs), (ins GR16:$src1, i16i8imm:$src2),
1695 "btc{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>,
1697 def BTC32ri8 : Ii8<0xBA, MRM7r, (outs), (ins GR32:$src1, i32i8imm:$src2),
1698 "btc{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>,
1700 def BTC64ri8 : RIi8<0xBA, MRM7r, (outs), (ins GR64:$src1, i64i8imm:$src2),
1701 "btc{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>, TB;
1704 let mayLoad = 1, mayStore = 1, SchedRW = [WriteALULd, WriteRMW] in {
1705 def BTC16mi8 : Ii8<0xBA, MRM7m, (outs), (ins i16mem:$src1, i16i8imm:$src2),
1706 "btc{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>,
1708 def BTC32mi8 : Ii8<0xBA, MRM7m, (outs), (ins i32mem:$src1, i32i8imm:$src2),
1709 "btc{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>,
1711 def BTC64mi8 : RIi8<0xBA, MRM7m, (outs), (ins i64mem:$src1, i64i8imm:$src2),
1712 "btc{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>, TB;
1715 let SchedRW = [WriteALU] in {
1716 def BTR16rr : I<0xB3, MRMDestReg, (outs), (ins GR16:$src1, GR16:$src2),
1717 "btr{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>,
1719 def BTR32rr : I<0xB3, MRMDestReg, (outs), (ins GR32:$src1, GR32:$src2),
1720 "btr{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>,
1722 def BTR64rr : RI<0xB3, MRMDestReg, (outs), (ins GR64:$src1, GR64:$src2),
1723 "btr{q}\t{$src2, $src1|$src1, $src2}", []>, TB;
1726 let mayLoad = 1, mayStore = 1, SchedRW = [WriteALULd, WriteRMW] in {
1727 def BTR16mr : I<0xB3, MRMDestMem, (outs), (ins i16mem:$src1, GR16:$src2),
1728 "btr{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>,
1730 def BTR32mr : I<0xB3, MRMDestMem, (outs), (ins i32mem:$src1, GR32:$src2),
1731 "btr{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>,
1733 def BTR64mr : RI<0xB3, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2),
1734 "btr{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>, TB;
1737 let SchedRW = [WriteALU] in {
1738 def BTR16ri8 : Ii8<0xBA, MRM6r, (outs), (ins GR16:$src1, i16i8imm:$src2),
1739 "btr{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>,
1741 def BTR32ri8 : Ii8<0xBA, MRM6r, (outs), (ins GR32:$src1, i32i8imm:$src2),
1742 "btr{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>,
1744 def BTR64ri8 : RIi8<0xBA, MRM6r, (outs), (ins GR64:$src1, i64i8imm:$src2),
1745 "btr{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>, TB;
1748 let mayLoad = 1, mayStore = 1, SchedRW = [WriteALULd, WriteRMW] in {
1749 def BTR16mi8 : Ii8<0xBA, MRM6m, (outs), (ins i16mem:$src1, i16i8imm:$src2),
1750 "btr{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>,
1752 def BTR32mi8 : Ii8<0xBA, MRM6m, (outs), (ins i32mem:$src1, i32i8imm:$src2),
1753 "btr{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>,
1755 def BTR64mi8 : RIi8<0xBA, MRM6m, (outs), (ins i64mem:$src1, i64i8imm:$src2),
1756 "btr{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>, TB;
1759 let SchedRW = [WriteALU] in {
1760 def BTS16rr : I<0xAB, MRMDestReg, (outs), (ins GR16:$src1, GR16:$src2),
1761 "bts{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>,
1763 def BTS32rr : I<0xAB, MRMDestReg, (outs), (ins GR32:$src1, GR32:$src2),
1764 "bts{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>,
1766 def BTS64rr : RI<0xAB, MRMDestReg, (outs), (ins GR64:$src1, GR64:$src2),
1767 "bts{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>, TB;
1770 let mayLoad = 1, mayStore = 1, SchedRW = [WriteALULd, WriteRMW] in {
1771 def BTS16mr : I<0xAB, MRMDestMem, (outs), (ins i16mem:$src1, GR16:$src2),
1772 "bts{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>,
1774 def BTS32mr : I<0xAB, MRMDestMem, (outs), (ins i32mem:$src1, GR32:$src2),
1775 "bts{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>,
1777 def BTS64mr : RI<0xAB, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2),
1778 "bts{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>, TB;
1781 let SchedRW = [WriteALU] in {
1782 def BTS16ri8 : Ii8<0xBA, MRM5r, (outs), (ins GR16:$src1, i16i8imm:$src2),
1783 "bts{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>,
1785 def BTS32ri8 : Ii8<0xBA, MRM5r, (outs), (ins GR32:$src1, i32i8imm:$src2),
1786 "bts{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>,
1788 def BTS64ri8 : RIi8<0xBA, MRM5r, (outs), (ins GR64:$src1, i64i8imm:$src2),
1789 "bts{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>, TB;
1792 let mayLoad = 1, mayStore = 1, SchedRW = [WriteALULd, WriteRMW] in {
1793 def BTS16mi8 : Ii8<0xBA, MRM5m, (outs), (ins i16mem:$src1, i16i8imm:$src2),
1794 "bts{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>,
1796 def BTS32mi8 : Ii8<0xBA, MRM5m, (outs), (ins i32mem:$src1, i32i8imm:$src2),
1797 "bts{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>,
1799 def BTS64mi8 : RIi8<0xBA, MRM5m, (outs), (ins i64mem:$src1, i64i8imm:$src2),
1800 "bts{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>, TB;
1802 } // hasSideEffects = 0
1803 } // Defs = [EFLAGS]
1806 //===----------------------------------------------------------------------===//
1810 // Atomic swap. These are just normal xchg instructions. But since a memory
1811 // operand is referenced, the atomicity is ensured.
1812 multiclass ATOMIC_SWAP<bits<8> opc8, bits<8> opc, string mnemonic, string frag,
1813 InstrItinClass itin> {
1814 let Constraints = "$val = $dst", SchedRW = [WriteALULd, WriteRMW] in {
1815 def NAME#8rm : I<opc8, MRMSrcMem, (outs GR8:$dst),
1816 (ins GR8:$val, i8mem:$ptr),
1817 !strconcat(mnemonic, "{b}\t{$val, $ptr|$ptr, $val}"),
1820 (!cast<PatFrag>(frag # "_8") addr:$ptr, GR8:$val))],
1822 def NAME#16rm : I<opc, MRMSrcMem, (outs GR16:$dst),
1823 (ins GR16:$val, i16mem:$ptr),
1824 !strconcat(mnemonic, "{w}\t{$val, $ptr|$ptr, $val}"),
1827 (!cast<PatFrag>(frag # "_16") addr:$ptr, GR16:$val))],
1829 def NAME#32rm : I<opc, MRMSrcMem, (outs GR32:$dst),
1830 (ins GR32:$val, i32mem:$ptr),
1831 !strconcat(mnemonic, "{l}\t{$val, $ptr|$ptr, $val}"),
1834 (!cast<PatFrag>(frag # "_32") addr:$ptr, GR32:$val))],
1836 def NAME#64rm : RI<opc, MRMSrcMem, (outs GR64:$dst),
1837 (ins GR64:$val, i64mem:$ptr),
1838 !strconcat(mnemonic, "{q}\t{$val, $ptr|$ptr, $val}"),
1841 (!cast<PatFrag>(frag # "_64") addr:$ptr, GR64:$val))],
1846 defm XCHG : ATOMIC_SWAP<0x86, 0x87, "xchg", "atomic_swap", IIC_XCHG_MEM>;
1848 // Swap between registers.
1849 let SchedRW = [WriteALU] in {
1850 let Constraints = "$val = $dst" in {
1851 def XCHG8rr : I<0x86, MRMSrcReg, (outs GR8:$dst), (ins GR8:$val, GR8:$src),
1852 "xchg{b}\t{$val, $src|$src, $val}", [], IIC_XCHG_REG>;
1853 def XCHG16rr : I<0x87, MRMSrcReg, (outs GR16:$dst), (ins GR16:$val, GR16:$src),
1854 "xchg{w}\t{$val, $src|$src, $val}", [], IIC_XCHG_REG>,
1856 def XCHG32rr : I<0x87, MRMSrcReg, (outs GR32:$dst), (ins GR32:$val, GR32:$src),
1857 "xchg{l}\t{$val, $src|$src, $val}", [], IIC_XCHG_REG>,
1859 def XCHG64rr : RI<0x87, MRMSrcReg, (outs GR64:$dst), (ins GR64:$val,GR64:$src),
1860 "xchg{q}\t{$val, $src|$src, $val}", [], IIC_XCHG_REG>;
1863 // Swap between EAX and other registers.
1864 let Uses = [AX], Defs = [AX] in
1865 def XCHG16ar : I<0x90, AddRegFrm, (outs), (ins GR16:$src),
1866 "xchg{w}\t{$src, %ax|ax, $src}", [], IIC_XCHG_REG>, OpSize16;
1867 let Uses = [EAX], Defs = [EAX] in
1868 def XCHG32ar : I<0x90, AddRegFrm, (outs), (ins GR32:$src),
1869 "xchg{l}\t{$src, %eax|eax, $src}", [], IIC_XCHG_REG>,
1870 OpSize32, Requires<[Not64BitMode]>;
1871 let Uses = [EAX], Defs = [EAX] in
1872 // Uses GR32_NOAX in 64-bit mode to prevent encoding using the 0x90 NOP encoding.
1873 // xchg %eax, %eax needs to clear upper 32-bits of RAX so is not a NOP.
1874 def XCHG32ar64 : I<0x90, AddRegFrm, (outs), (ins GR32_NOAX:$src),
1875 "xchg{l}\t{$src, %eax|eax, $src}", [], IIC_XCHG_REG>,
1876 OpSize32, Requires<[In64BitMode]>;
1877 let Uses = [RAX], Defs = [RAX] in
1878 def XCHG64ar : RI<0x90, AddRegFrm, (outs), (ins GR64:$src),
1879 "xchg{q}\t{$src, %rax|rax, $src}", [], IIC_XCHG_REG>;
1882 let SchedRW = [WriteALU] in {
1883 def XADD8rr : I<0xC0, MRMDestReg, (outs GR8:$dst), (ins GR8:$src),
1884 "xadd{b}\t{$src, $dst|$dst, $src}", [], IIC_XADD_REG>, TB;
1885 def XADD16rr : I<0xC1, MRMDestReg, (outs GR16:$dst), (ins GR16:$src),
1886 "xadd{w}\t{$src, $dst|$dst, $src}", [], IIC_XADD_REG>, TB,
1888 def XADD32rr : I<0xC1, MRMDestReg, (outs GR32:$dst), (ins GR32:$src),
1889 "xadd{l}\t{$src, $dst|$dst, $src}", [], IIC_XADD_REG>, TB,
1891 def XADD64rr : RI<0xC1, MRMDestReg, (outs GR64:$dst), (ins GR64:$src),
1892 "xadd{q}\t{$src, $dst|$dst, $src}", [], IIC_XADD_REG>, TB;
1895 let mayLoad = 1, mayStore = 1, SchedRW = [WriteALULd, WriteRMW] in {
1896 def XADD8rm : I<0xC0, MRMDestMem, (outs), (ins i8mem:$dst, GR8:$src),
1897 "xadd{b}\t{$src, $dst|$dst, $src}", [], IIC_XADD_MEM>, TB;
1898 def XADD16rm : I<0xC1, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src),
1899 "xadd{w}\t{$src, $dst|$dst, $src}", [], IIC_XADD_MEM>, TB,
1901 def XADD32rm : I<0xC1, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
1902 "xadd{l}\t{$src, $dst|$dst, $src}", [], IIC_XADD_MEM>, TB,
1904 def XADD64rm : RI<0xC1, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
1905 "xadd{q}\t{$src, $dst|$dst, $src}", [], IIC_XADD_MEM>, TB;
1909 let SchedRW = [WriteALU] in {
1910 def CMPXCHG8rr : I<0xB0, MRMDestReg, (outs GR8:$dst), (ins GR8:$src),
1911 "cmpxchg{b}\t{$src, $dst|$dst, $src}", [],
1912 IIC_CMPXCHG_REG8>, TB;
1913 def CMPXCHG16rr : I<0xB1, MRMDestReg, (outs GR16:$dst), (ins GR16:$src),
1914 "cmpxchg{w}\t{$src, $dst|$dst, $src}", [],
1915 IIC_CMPXCHG_REG>, TB, OpSize16;
1916 def CMPXCHG32rr : I<0xB1, MRMDestReg, (outs GR32:$dst), (ins GR32:$src),
1917 "cmpxchg{l}\t{$src, $dst|$dst, $src}", [],
1918 IIC_CMPXCHG_REG>, TB, OpSize32;
1919 def CMPXCHG64rr : RI<0xB1, MRMDestReg, (outs GR64:$dst), (ins GR64:$src),
1920 "cmpxchg{q}\t{$src, $dst|$dst, $src}", [],
1921 IIC_CMPXCHG_REG>, TB;
1924 let SchedRW = [WriteALULd, WriteRMW] in {
1925 let mayLoad = 1, mayStore = 1 in {
1926 def CMPXCHG8rm : I<0xB0, MRMDestMem, (outs), (ins i8mem:$dst, GR8:$src),
1927 "cmpxchg{b}\t{$src, $dst|$dst, $src}", [],
1928 IIC_CMPXCHG_MEM8>, TB;
1929 def CMPXCHG16rm : I<0xB1, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src),
1930 "cmpxchg{w}\t{$src, $dst|$dst, $src}", [],
1931 IIC_CMPXCHG_MEM>, TB, OpSize16;
1932 def CMPXCHG32rm : I<0xB1, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
1933 "cmpxchg{l}\t{$src, $dst|$dst, $src}", [],
1934 IIC_CMPXCHG_MEM>, TB, OpSize32;
1935 def CMPXCHG64rm : RI<0xB1, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
1936 "cmpxchg{q}\t{$src, $dst|$dst, $src}", [],
1937 IIC_CMPXCHG_MEM>, TB;
1940 let Defs = [EAX, EDX, EFLAGS], Uses = [EAX, EBX, ECX, EDX] in
1941 def CMPXCHG8B : I<0xC7, MRM1m, (outs), (ins i64mem:$dst),
1942 "cmpxchg8b\t$dst", [], IIC_CMPXCHG_8B>, TB;
1944 let Defs = [RAX, RDX, EFLAGS], Uses = [RAX, RBX, RCX, RDX] in
1945 def CMPXCHG16B : RI<0xC7, MRM1m, (outs), (ins i128mem:$dst),
1946 "cmpxchg16b\t$dst", [], IIC_CMPXCHG_16B>,
1947 TB, Requires<[HasCmpxchg16b]>;
1951 // Lock instruction prefix
1952 def LOCK_PREFIX : I<0xF0, RawFrm, (outs), (ins), "lock", []>;
1954 // Rex64 instruction prefix
1955 def REX64_PREFIX : I<0x48, RawFrm, (outs), (ins), "rex64", []>,
1956 Requires<[In64BitMode]>;
1958 // Data16 instruction prefix
1959 def DATA16_PREFIX : I<0x66, RawFrm, (outs), (ins), "data16", []>;
1961 // Repeat string operation instruction prefixes
1962 // These uses the DF flag in the EFLAGS register to inc or dec ECX
1963 let Defs = [ECX], Uses = [ECX,EFLAGS] in {
1964 // Repeat (used with INS, OUTS, MOVS, LODS and STOS)
1965 def REP_PREFIX : I<0xF3, RawFrm, (outs), (ins), "rep", []>;
1966 // Repeat while not equal (used with CMPS and SCAS)
1967 def REPNE_PREFIX : I<0xF2, RawFrm, (outs), (ins), "repne", []>;
1971 // String manipulation instructions
1972 let SchedRW = [WriteMicrocoded] in {
1973 // These uses the DF flag in the EFLAGS register to inc or dec EDI and ESI
1974 let Defs = [AL,ESI], Uses = [ESI,EFLAGS] in
1975 def LODSB : I<0xAC, RawFrmSrc, (outs), (ins srcidx8:$src),
1976 "lodsb\t{$src, %al|al, $src}", [], IIC_LODS>;
1977 let Defs = [AX,ESI], Uses = [ESI,EFLAGS] in
1978 def LODSW : I<0xAD, RawFrmSrc, (outs), (ins srcidx16:$src),
1979 "lodsw\t{$src, %ax|ax, $src}", [], IIC_LODS>, OpSize16;
1980 let Defs = [EAX,ESI], Uses = [ESI,EFLAGS] in
1981 def LODSL : I<0xAD, RawFrmSrc, (outs), (ins srcidx32:$src),
1982 "lods{l|d}\t{$src, %eax|eax, $src}", [], IIC_LODS>, OpSize32;
1983 let Defs = [RAX,ESI], Uses = [ESI,EFLAGS] in
1984 def LODSQ : RI<0xAD, RawFrmSrc, (outs), (ins srcidx64:$src),
1985 "lodsq\t{$src, %rax|rax, $src}", [], IIC_LODS>;
1988 let SchedRW = [WriteSystem] in {
1989 // These uses the DF flag in the EFLAGS register to inc or dec EDI and ESI
1990 let Defs = [ESI], Uses = [DX,ESI,EFLAGS] in {
1991 def OUTSB : I<0x6E, RawFrmSrc, (outs), (ins srcidx8:$src),
1992 "outsb\t{$src, %dx|dx, $src}", [], IIC_OUTS>;
1993 def OUTSW : I<0x6F, RawFrmSrc, (outs), (ins srcidx16:$src),
1994 "outsw\t{$src, %dx|dx, $src}", [], IIC_OUTS>, OpSize16;
1995 def OUTSL : I<0x6F, RawFrmSrc, (outs), (ins srcidx32:$src),
1996 "outs{l|d}\t{$src, %dx|dx, $src}", [], IIC_OUTS>, OpSize32;
1999 // These uses the DF flag in the EFLAGS register to inc or dec EDI and ESI
2000 let Defs = [EDI], Uses = [DX,EDI,EFLAGS] in {
2001 def INSB : I<0x6C, RawFrmDst, (outs), (ins dstidx8:$dst),
2002 "insb\t{%dx, $dst|$dst, dx}", [], IIC_INS>;
2003 def INSW : I<0x6D, RawFrmDst, (outs), (ins dstidx16:$dst),
2004 "insw\t{%dx, $dst|$dst, dx}", [], IIC_INS>, OpSize16;
2005 def INSL : I<0x6D, RawFrmDst, (outs), (ins dstidx32:$dst),
2006 "ins{l|d}\t{%dx, $dst|$dst, dx}", [], IIC_INS>, OpSize32;
2010 // Flag instructions
2011 let SchedRW = [WriteALU] in {
2012 def CLC : I<0xF8, RawFrm, (outs), (ins), "clc", [], IIC_CLC>;
2013 def STC : I<0xF9, RawFrm, (outs), (ins), "stc", [], IIC_STC>;
2014 def CLI : I<0xFA, RawFrm, (outs), (ins), "cli", [], IIC_CLI>;
2015 def STI : I<0xFB, RawFrm, (outs), (ins), "sti", [], IIC_STI>;
2016 def CLD : I<0xFC, RawFrm, (outs), (ins), "cld", [], IIC_CLD>;
2017 def STD : I<0xFD, RawFrm, (outs), (ins), "std", [], IIC_STD>;
2018 def CMC : I<0xF5, RawFrm, (outs), (ins), "cmc", [], IIC_CMC>;
2020 def CLTS : I<0x06, RawFrm, (outs), (ins), "clts", [], IIC_CLTS>, TB;
2023 // Table lookup instructions
2024 let Uses = [AL,EBX], Defs = [AL], hasSideEffects = 0, mayLoad = 1 in
2025 def XLAT : I<0xD7, RawFrm, (outs), (ins), "xlatb", [], IIC_XLAT>,
2028 let SchedRW = [WriteMicrocoded] in {
2029 // ASCII Adjust After Addition
2030 let Uses = [AL,EFLAGS], Defs = [AX,EFLAGS], hasSideEffects = 0 in
2031 def AAA : I<0x37, RawFrm, (outs), (ins), "aaa", [], IIC_AAA>,
2032 Requires<[Not64BitMode]>;
2034 // ASCII Adjust AX Before Division
2035 let Uses = [AX], Defs = [AX,EFLAGS], hasSideEffects = 0 in
2036 def AAD8i8 : Ii8<0xD5, RawFrm, (outs), (ins i8imm:$src),
2037 "aad\t$src", [], IIC_AAD>, Requires<[Not64BitMode]>;
2039 // ASCII Adjust AX After Multiply
2040 let Uses = [AL], Defs = [AX,EFLAGS], hasSideEffects = 0 in
2041 def AAM8i8 : Ii8<0xD4, RawFrm, (outs), (ins i8imm:$src),
2042 "aam\t$src", [], IIC_AAM>, Requires<[Not64BitMode]>;
2044 // ASCII Adjust AL After Subtraction - sets
2045 let Uses = [AL,EFLAGS], Defs = [AX,EFLAGS], hasSideEffects = 0 in
2046 def AAS : I<0x3F, RawFrm, (outs), (ins), "aas", [], IIC_AAS>,
2047 Requires<[Not64BitMode]>;
2049 // Decimal Adjust AL after Addition
2050 let Uses = [AL,EFLAGS], Defs = [AL,EFLAGS], hasSideEffects = 0 in
2051 def DAA : I<0x27, RawFrm, (outs), (ins), "daa", [], IIC_DAA>,
2052 Requires<[Not64BitMode]>;
2054 // Decimal Adjust AL after Subtraction
2055 let Uses = [AL,EFLAGS], Defs = [AL,EFLAGS], hasSideEffects = 0 in
2056 def DAS : I<0x2F, RawFrm, (outs), (ins), "das", [], IIC_DAS>,
2057 Requires<[Not64BitMode]>;
2060 let SchedRW = [WriteSystem] in {
2061 // Check Array Index Against Bounds
2062 def BOUNDS16rm : I<0x62, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
2063 "bound\t{$src, $dst|$dst, $src}", [], IIC_BOUND>, OpSize16,
2064 Requires<[Not64BitMode]>;
2065 def BOUNDS32rm : I<0x62, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
2066 "bound\t{$src, $dst|$dst, $src}", [], IIC_BOUND>, OpSize32,
2067 Requires<[Not64BitMode]>;
2069 // Adjust RPL Field of Segment Selector
2070 def ARPL16rr : I<0x63, MRMDestReg, (outs GR16:$dst), (ins GR16:$src),
2071 "arpl\t{$src, $dst|$dst, $src}", [], IIC_ARPL_REG>,
2072 Requires<[Not64BitMode]>;
2073 def ARPL16mr : I<0x63, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src),
2074 "arpl\t{$src, $dst|$dst, $src}", [], IIC_ARPL_MEM>,
2075 Requires<[Not64BitMode]>;
2078 //===----------------------------------------------------------------------===//
2079 // MOVBE Instructions
2081 let Predicates = [HasMOVBE] in {
2082 let SchedRW = [WriteALULd] in {
2083 def MOVBE16rm : I<0xF0, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
2084 "movbe{w}\t{$src, $dst|$dst, $src}",
2085 [(set GR16:$dst, (bswap (loadi16 addr:$src)))], IIC_MOVBE>,
2087 def MOVBE32rm : I<0xF0, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
2088 "movbe{l}\t{$src, $dst|$dst, $src}",
2089 [(set GR32:$dst, (bswap (loadi32 addr:$src)))], IIC_MOVBE>,
2091 def MOVBE64rm : RI<0xF0, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
2092 "movbe{q}\t{$src, $dst|$dst, $src}",
2093 [(set GR64:$dst, (bswap (loadi64 addr:$src)))], IIC_MOVBE>,
2096 let SchedRW = [WriteStore] in {
2097 def MOVBE16mr : I<0xF1, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src),
2098 "movbe{w}\t{$src, $dst|$dst, $src}",
2099 [(store (bswap GR16:$src), addr:$dst)], IIC_MOVBE>,
2101 def MOVBE32mr : I<0xF1, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
2102 "movbe{l}\t{$src, $dst|$dst, $src}",
2103 [(store (bswap GR32:$src), addr:$dst)], IIC_MOVBE>,
2105 def MOVBE64mr : RI<0xF1, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
2106 "movbe{q}\t{$src, $dst|$dst, $src}",
2107 [(store (bswap GR64:$src), addr:$dst)], IIC_MOVBE>,
2112 //===----------------------------------------------------------------------===//
2113 // RDRAND Instruction
2115 let Predicates = [HasRDRAND], Defs = [EFLAGS] in {
2116 def RDRAND16r : I<0xC7, MRM6r, (outs GR16:$dst), (ins),
2118 [(set GR16:$dst, EFLAGS, (X86rdrand))]>, OpSize16, TB;
2119 def RDRAND32r : I<0xC7, MRM6r, (outs GR32:$dst), (ins),
2121 [(set GR32:$dst, EFLAGS, (X86rdrand))]>, OpSize32, TB;
2122 def RDRAND64r : RI<0xC7, MRM6r, (outs GR64:$dst), (ins),
2124 [(set GR64:$dst, EFLAGS, (X86rdrand))]>, TB;
2127 //===----------------------------------------------------------------------===//
2128 // RDSEED Instruction
2130 let Predicates = [HasRDSEED], Defs = [EFLAGS] in {
2131 def RDSEED16r : I<0xC7, MRM7r, (outs GR16:$dst), (ins),
2133 [(set GR16:$dst, EFLAGS, (X86rdseed))]>, OpSize16, TB;
2134 def RDSEED32r : I<0xC7, MRM7r, (outs GR32:$dst), (ins),
2136 [(set GR32:$dst, EFLAGS, (X86rdseed))]>, OpSize32, TB;
2137 def RDSEED64r : RI<0xC7, MRM7r, (outs GR64:$dst), (ins),
2139 [(set GR64:$dst, EFLAGS, (X86rdseed))]>, TB;
2142 //===----------------------------------------------------------------------===//
2143 // LZCNT Instruction
2145 let Predicates = [HasLZCNT], Defs = [EFLAGS] in {
2146 def LZCNT16rr : I<0xBD, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
2147 "lzcnt{w}\t{$src, $dst|$dst, $src}",
2148 [(set GR16:$dst, (ctlz GR16:$src)), (implicit EFLAGS)]>, XS,
2150 def LZCNT16rm : I<0xBD, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
2151 "lzcnt{w}\t{$src, $dst|$dst, $src}",
2152 [(set GR16:$dst, (ctlz (loadi16 addr:$src))),
2153 (implicit EFLAGS)]>, XS, OpSize16;
2155 def LZCNT32rr : I<0xBD, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
2156 "lzcnt{l}\t{$src, $dst|$dst, $src}",
2157 [(set GR32:$dst, (ctlz GR32:$src)), (implicit EFLAGS)]>, XS,
2159 def LZCNT32rm : I<0xBD, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
2160 "lzcnt{l}\t{$src, $dst|$dst, $src}",
2161 [(set GR32:$dst, (ctlz (loadi32 addr:$src))),
2162 (implicit EFLAGS)]>, XS, OpSize32;
2164 def LZCNT64rr : RI<0xBD, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
2165 "lzcnt{q}\t{$src, $dst|$dst, $src}",
2166 [(set GR64:$dst, (ctlz GR64:$src)), (implicit EFLAGS)]>,
2168 def LZCNT64rm : RI<0xBD, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
2169 "lzcnt{q}\t{$src, $dst|$dst, $src}",
2170 [(set GR64:$dst, (ctlz (loadi64 addr:$src))),
2171 (implicit EFLAGS)]>, XS;
2174 //===----------------------------------------------------------------------===//
2177 let Predicates = [HasBMI], Defs = [EFLAGS] in {
2178 def TZCNT16rr : I<0xBC, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
2179 "tzcnt{w}\t{$src, $dst|$dst, $src}",
2180 [(set GR16:$dst, (cttz GR16:$src)), (implicit EFLAGS)]>, XS,
2182 def TZCNT16rm : I<0xBC, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
2183 "tzcnt{w}\t{$src, $dst|$dst, $src}",
2184 [(set GR16:$dst, (cttz (loadi16 addr:$src))),
2185 (implicit EFLAGS)]>, XS, OpSize16;
2187 def TZCNT32rr : I<0xBC, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
2188 "tzcnt{l}\t{$src, $dst|$dst, $src}",
2189 [(set GR32:$dst, (cttz GR32:$src)), (implicit EFLAGS)]>, XS,
2191 def TZCNT32rm : I<0xBC, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
2192 "tzcnt{l}\t{$src, $dst|$dst, $src}",
2193 [(set GR32:$dst, (cttz (loadi32 addr:$src))),
2194 (implicit EFLAGS)]>, XS, OpSize32;
2196 def TZCNT64rr : RI<0xBC, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
2197 "tzcnt{q}\t{$src, $dst|$dst, $src}",
2198 [(set GR64:$dst, (cttz GR64:$src)), (implicit EFLAGS)]>,
2200 def TZCNT64rm : RI<0xBC, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
2201 "tzcnt{q}\t{$src, $dst|$dst, $src}",
2202 [(set GR64:$dst, (cttz (loadi64 addr:$src))),
2203 (implicit EFLAGS)]>, XS;
2206 multiclass bmi_bls<string mnemonic, Format RegMRM, Format MemMRM,
2207 RegisterClass RC, X86MemOperand x86memop> {
2208 let hasSideEffects = 0 in {
2209 def rr : I<0xF3, RegMRM, (outs RC:$dst), (ins RC:$src),
2210 !strconcat(mnemonic, "\t{$src, $dst|$dst, $src}"),
2213 def rm : I<0xF3, MemMRM, (outs RC:$dst), (ins x86memop:$src),
2214 !strconcat(mnemonic, "\t{$src, $dst|$dst, $src}"),
2219 let Predicates = [HasBMI], Defs = [EFLAGS] in {
2220 defm BLSR32 : bmi_bls<"blsr{l}", MRM1r, MRM1m, GR32, i32mem>;
2221 defm BLSR64 : bmi_bls<"blsr{q}", MRM1r, MRM1m, GR64, i64mem>, VEX_W;
2222 defm BLSMSK32 : bmi_bls<"blsmsk{l}", MRM2r, MRM2m, GR32, i32mem>;
2223 defm BLSMSK64 : bmi_bls<"blsmsk{q}", MRM2r, MRM2m, GR64, i64mem>, VEX_W;
2224 defm BLSI32 : bmi_bls<"blsi{l}", MRM3r, MRM3m, GR32, i32mem>;
2225 defm BLSI64 : bmi_bls<"blsi{q}", MRM3r, MRM3m, GR64, i64mem>, VEX_W;
2228 //===----------------------------------------------------------------------===//
2229 // Pattern fragments to auto generate BMI instructions.
2230 //===----------------------------------------------------------------------===//
2232 let Predicates = [HasBMI] in {
2233 // FIXME: patterns for the load versions are not implemented
2234 def : Pat<(and GR32:$src, (add GR32:$src, -1)),
2235 (BLSR32rr GR32:$src)>;
2236 def : Pat<(and GR64:$src, (add GR64:$src, -1)),
2237 (BLSR64rr GR64:$src)>;
2239 def : Pat<(xor GR32:$src, (add GR32:$src, -1)),
2240 (BLSMSK32rr GR32:$src)>;
2241 def : Pat<(xor GR64:$src, (add GR64:$src, -1)),
2242 (BLSMSK64rr GR64:$src)>;
2244 def : Pat<(and GR32:$src, (ineg GR32:$src)),
2245 (BLSI32rr GR32:$src)>;
2246 def : Pat<(and GR64:$src, (ineg GR64:$src)),
2247 (BLSI64rr GR64:$src)>;
2251 multiclass bmi_bextr_bzhi<bits<8> opc, string mnemonic, RegisterClass RC,
2252 X86MemOperand x86memop, Intrinsic Int,
2254 def rr : I<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
2255 !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2256 [(set RC:$dst, (Int RC:$src1, RC:$src2)), (implicit EFLAGS)]>,
2258 def rm : I<opc, MRMSrcMem, (outs RC:$dst), (ins x86memop:$src1, RC:$src2),
2259 !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2260 [(set RC:$dst, (Int (ld_frag addr:$src1), RC:$src2)),
2261 (implicit EFLAGS)]>, T8PS, VEX_4VOp3;
2264 let Predicates = [HasBMI], Defs = [EFLAGS] in {
2265 defm BEXTR32 : bmi_bextr_bzhi<0xF7, "bextr{l}", GR32, i32mem,
2266 int_x86_bmi_bextr_32, loadi32>;
2267 defm BEXTR64 : bmi_bextr_bzhi<0xF7, "bextr{q}", GR64, i64mem,
2268 int_x86_bmi_bextr_64, loadi64>, VEX_W;
2271 let Predicates = [HasBMI2], Defs = [EFLAGS] in {
2272 defm BZHI32 : bmi_bextr_bzhi<0xF5, "bzhi{l}", GR32, i32mem,
2273 int_x86_bmi_bzhi_32, loadi32>;
2274 defm BZHI64 : bmi_bextr_bzhi<0xF5, "bzhi{q}", GR64, i64mem,
2275 int_x86_bmi_bzhi_64, loadi64>, VEX_W;
2279 def CountTrailingOnes : SDNodeXForm<imm, [{
2280 // Count the trailing ones in the immediate.
2281 return getI8Imm(countTrailingOnes(N->getZExtValue()), SDLoc(N));
2284 def BZHIMask : ImmLeaf<i64, [{
2285 return isMask_64(Imm) && (countTrailingOnes<uint64_t>(Imm) > 32);
2288 let Predicates = [HasBMI2] in {
2289 def : Pat<(and GR64:$src, BZHIMask:$mask),
2290 (BZHI64rr GR64:$src,
2291 (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
2292 (MOV8ri (CountTrailingOnes imm:$mask)), sub_8bit))>;
2294 def : Pat<(and GR32:$src, (add (shl 1, GR8:$lz), -1)),
2295 (BZHI32rr GR32:$src,
2296 (INSERT_SUBREG (i32 (IMPLICIT_DEF)), GR8:$lz, sub_8bit))>;
2298 def : Pat<(and (loadi32 addr:$src), (add (shl 1, GR8:$lz), -1)),
2299 (BZHI32rm addr:$src,
2300 (INSERT_SUBREG (i32 (IMPLICIT_DEF)), GR8:$lz, sub_8bit))>;
2302 def : Pat<(and GR64:$src, (add (shl 1, GR8:$lz), -1)),
2303 (BZHI64rr GR64:$src,
2304 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR8:$lz, sub_8bit))>;
2306 def : Pat<(and (loadi64 addr:$src), (add (shl 1, GR8:$lz), -1)),
2307 (BZHI64rm addr:$src,
2308 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR8:$lz, sub_8bit))>;
2311 let Predicates = [HasBMI] in {
2312 def : Pat<(X86bextr GR32:$src1, GR32:$src2),
2313 (BEXTR32rr GR32:$src1, GR32:$src2)>;
2314 def : Pat<(X86bextr (loadi32 addr:$src1), GR32:$src2),
2315 (BEXTR32rm addr:$src1, GR32:$src2)>;
2316 def : Pat<(X86bextr GR64:$src1, GR64:$src2),
2317 (BEXTR64rr GR64:$src1, GR64:$src2)>;
2318 def : Pat<(X86bextr (loadi64 addr:$src1), GR64:$src2),
2319 (BEXTR64rm addr:$src1, GR64:$src2)>;
2322 multiclass bmi_pdep_pext<string mnemonic, RegisterClass RC,
2323 X86MemOperand x86memop, Intrinsic Int,
2325 def rr : I<0xF5, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
2326 !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2327 [(set RC:$dst, (Int RC:$src1, RC:$src2))]>,
2329 def rm : I<0xF5, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
2330 !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2331 [(set RC:$dst, (Int RC:$src1, (ld_frag addr:$src2)))]>, VEX_4V;
2334 let Predicates = [HasBMI2] in {
2335 defm PDEP32 : bmi_pdep_pext<"pdep{l}", GR32, i32mem,
2336 int_x86_bmi_pdep_32, loadi32>, T8XD;
2337 defm PDEP64 : bmi_pdep_pext<"pdep{q}", GR64, i64mem,
2338 int_x86_bmi_pdep_64, loadi64>, T8XD, VEX_W;
2339 defm PEXT32 : bmi_pdep_pext<"pext{l}", GR32, i32mem,
2340 int_x86_bmi_pext_32, loadi32>, T8XS;
2341 defm PEXT64 : bmi_pdep_pext<"pext{q}", GR64, i64mem,
2342 int_x86_bmi_pext_64, loadi64>, T8XS, VEX_W;
2345 //===----------------------------------------------------------------------===//
2348 let Predicates = [HasTBM], Defs = [EFLAGS] in {
2350 multiclass tbm_ternary_imm_intr<bits<8> opc, RegisterClass RC, string OpcodeStr,
2351 X86MemOperand x86memop, PatFrag ld_frag,
2352 Intrinsic Int, Operand immtype,
2353 SDPatternOperator immoperator> {
2354 def ri : Ii32<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, immtype:$cntl),
2355 !strconcat(OpcodeStr,
2356 "\t{$cntl, $src1, $dst|$dst, $src1, $cntl}"),
2357 [(set RC:$dst, (Int RC:$src1, immoperator:$cntl))]>,
2359 def mi : Ii32<opc, MRMSrcMem, (outs RC:$dst),
2360 (ins x86memop:$src1, immtype:$cntl),
2361 !strconcat(OpcodeStr,
2362 "\t{$cntl, $src1, $dst|$dst, $src1, $cntl}"),
2363 [(set RC:$dst, (Int (ld_frag addr:$src1), immoperator:$cntl))]>,
2367 defm BEXTRI32 : tbm_ternary_imm_intr<0x10, GR32, "bextr", i32mem, loadi32,
2368 int_x86_tbm_bextri_u32, i32imm, imm>;
2369 let ImmT = Imm32S in
2370 defm BEXTRI64 : tbm_ternary_imm_intr<0x10, GR64, "bextr", i64mem, loadi64,
2371 int_x86_tbm_bextri_u64, i64i32imm,
2372 i64immSExt32>, VEX_W;
2374 multiclass tbm_binary_rm<bits<8> opc, Format FormReg, Format FormMem,
2375 RegisterClass RC, string OpcodeStr,
2376 X86MemOperand x86memop, PatFrag ld_frag> {
2377 let hasSideEffects = 0 in {
2378 def rr : I<opc, FormReg, (outs RC:$dst), (ins RC:$src),
2379 !strconcat(OpcodeStr,"\t{$src, $dst|$dst, $src}"),
2382 def rm : I<opc, FormMem, (outs RC:$dst), (ins x86memop:$src),
2383 !strconcat(OpcodeStr,"\t{$src, $dst|$dst, $src}"),
2388 multiclass tbm_binary_intr<bits<8> opc, string OpcodeStr,
2389 Format FormReg, Format FormMem> {
2390 defm NAME#32 : tbm_binary_rm<opc, FormReg, FormMem, GR32, OpcodeStr, i32mem,
2392 defm NAME#64 : tbm_binary_rm<opc, FormReg, FormMem, GR64, OpcodeStr, i64mem,
2396 defm BLCFILL : tbm_binary_intr<0x01, "blcfill", MRM1r, MRM1m>;
2397 defm BLCI : tbm_binary_intr<0x02, "blci", MRM6r, MRM6m>;
2398 defm BLCIC : tbm_binary_intr<0x01, "blcic", MRM5r, MRM5m>;
2399 defm BLCMSK : tbm_binary_intr<0x02, "blcmsk", MRM1r, MRM1m>;
2400 defm BLCS : tbm_binary_intr<0x01, "blcs", MRM3r, MRM3m>;
2401 defm BLSFILL : tbm_binary_intr<0x01, "blsfill", MRM2r, MRM2m>;
2402 defm BLSIC : tbm_binary_intr<0x01, "blsic", MRM6r, MRM6m>;
2403 defm T1MSKC : tbm_binary_intr<0x01, "t1mskc", MRM7r, MRM7m>;
2404 defm TZMSK : tbm_binary_intr<0x01, "tzmsk", MRM4r, MRM4m>;
2407 //===----------------------------------------------------------------------===//
2408 // MONITORX/MWAITX Instructions
2410 let SchedRW = [ WriteSystem ] in {
2411 let usesCustomInserter = 1 in {
2412 def MONITORX : PseudoI<(outs), (ins i32mem:$src1, GR32:$src2, GR32:$src3),
2413 [(int_x86_monitorx addr:$src1, GR32:$src2, GR32:$src3)]>,
2414 Requires<[ HasMWAITX ]>;
2417 let Uses = [ EAX, ECX, EDX ] in {
2418 def MONITORXrrr : I<0x01, MRM_FA, (outs), (ins), "monitorx", [], IIC_SSE_MONITORX>,
2419 TB, Requires<[ HasMWAITX ]>;
2422 let Uses = [ ECX, EAX, EBX ] in {
2423 def MWAITXrrr : I<0x01, MRM_FB, (outs), (ins), "mwaitx",
2424 [(int_x86_mwaitx ECX, EAX, EBX)], IIC_SSE_MWAITX>,
2425 TB, Requires<[ HasMWAITX ]>;
2429 def : InstAlias<"mwaitx\t{%eax, %ecx, %ebx|ebx, ecx, eax}", (MWAITXrrr)>,
2430 Requires<[ Not64BitMode ]>;
2431 def : InstAlias<"mwaitx\t{%rax, %rcx, %rbx|rbx, rcx, rax}", (MWAITXrrr)>,
2432 Requires<[ In64BitMode ]>;
2434 def : InstAlias<"monitorx\t{%eax, %ecx, %edx|edx, ecx, eax}", (MONITORXrrr)>,
2435 Requires<[ Not64BitMode ]>;
2436 def : InstAlias<"monitorx\t{%rax, %rcx, %rdx|rdx, rcx, rax}", (MONITORXrrr)>,
2437 Requires<[ In64BitMode ]>;
2439 //===----------------------------------------------------------------------===//
2440 // CLZERO Instruction
2443 def CLZEROr : I<0x01, MRM_FC, (outs), (ins), "clzero", []>, TB;
2445 //===----------------------------------------------------------------------===//
2446 // Pattern fragments to auto generate TBM instructions.
2447 //===----------------------------------------------------------------------===//
2449 let Predicates = [HasTBM] in {
2450 def : Pat<(X86bextr GR32:$src1, (i32 imm:$src2)),
2451 (BEXTRI32ri GR32:$src1, imm:$src2)>;
2452 def : Pat<(X86bextr (loadi32 addr:$src1), (i32 imm:$src2)),
2453 (BEXTRI32mi addr:$src1, imm:$src2)>;
2454 def : Pat<(X86bextr GR64:$src1, i64immSExt32:$src2),
2455 (BEXTRI64ri GR64:$src1, i64immSExt32:$src2)>;
2456 def : Pat<(X86bextr (loadi64 addr:$src1), i64immSExt32:$src2),
2457 (BEXTRI64mi addr:$src1, i64immSExt32:$src2)>;
2459 // FIXME: patterns for the load versions are not implemented
2460 def : Pat<(and GR32:$src, (add GR32:$src, 1)),
2461 (BLCFILL32rr GR32:$src)>;
2462 def : Pat<(and GR64:$src, (add GR64:$src, 1)),
2463 (BLCFILL64rr GR64:$src)>;
2465 def : Pat<(or GR32:$src, (not (add GR32:$src, 1))),
2466 (BLCI32rr GR32:$src)>;
2467 def : Pat<(or GR64:$src, (not (add GR64:$src, 1))),
2468 (BLCI64rr GR64:$src)>;
2470 // Extra patterns because opt can optimize the above patterns to this.
2471 def : Pat<(or GR32:$src, (sub -2, GR32:$src)),
2472 (BLCI32rr GR32:$src)>;
2473 def : Pat<(or GR64:$src, (sub -2, GR64:$src)),
2474 (BLCI64rr GR64:$src)>;
2476 def : Pat<(and (not GR32:$src), (add GR32:$src, 1)),
2477 (BLCIC32rr GR32:$src)>;
2478 def : Pat<(and (not GR64:$src), (add GR64:$src, 1)),
2479 (BLCIC64rr GR64:$src)>;
2481 def : Pat<(xor GR32:$src, (add GR32:$src, 1)),
2482 (BLCMSK32rr GR32:$src)>;
2483 def : Pat<(xor GR64:$src, (add GR64:$src, 1)),
2484 (BLCMSK64rr GR64:$src)>;
2486 def : Pat<(or GR32:$src, (add GR32:$src, 1)),
2487 (BLCS32rr GR32:$src)>;
2488 def : Pat<(or GR64:$src, (add GR64:$src, 1)),
2489 (BLCS64rr GR64:$src)>;
2491 def : Pat<(or GR32:$src, (add GR32:$src, -1)),
2492 (BLSFILL32rr GR32:$src)>;
2493 def : Pat<(or GR64:$src, (add GR64:$src, -1)),
2494 (BLSFILL64rr GR64:$src)>;
2496 def : Pat<(or (not GR32:$src), (add GR32:$src, -1)),
2497 (BLSIC32rr GR32:$src)>;
2498 def : Pat<(or (not GR64:$src), (add GR64:$src, -1)),
2499 (BLSIC64rr GR64:$src)>;
2501 def : Pat<(or (not GR32:$src), (add GR32:$src, 1)),
2502 (T1MSKC32rr GR32:$src)>;
2503 def : Pat<(or (not GR64:$src), (add GR64:$src, 1)),
2504 (T1MSKC64rr GR64:$src)>;
2506 def : Pat<(and (not GR32:$src), (add GR32:$src, -1)),
2507 (TZMSK32rr GR32:$src)>;
2508 def : Pat<(and (not GR64:$src), (add GR64:$src, -1)),
2509 (TZMSK64rr GR64:$src)>;
2512 //===----------------------------------------------------------------------===//
2513 // Memory Instructions
2516 def CLFLUSHOPT : I<0xAE, MRM7m, (outs), (ins i8mem:$src),
2517 "clflushopt\t$src", [(int_x86_clflushopt addr:$src)]>, PD;
2518 def CLWB : I<0xAE, MRM6m, (outs), (ins i8mem:$src), "clwb\t$src", []>, PD;
2519 def PCOMMIT : I<0xAE, MRM_F8, (outs), (ins), "pcommit", []>, PD;
2522 //===----------------------------------------------------------------------===//
2524 //===----------------------------------------------------------------------===//
2526 include "X86InstrArithmetic.td"
2527 include "X86InstrCMovSetCC.td"
2528 include "X86InstrExtension.td"
2529 include "X86InstrControl.td"
2530 include "X86InstrShiftRotate.td"
2532 // X87 Floating Point Stack.
2533 include "X86InstrFPStack.td"
2535 // SIMD support (SSE, MMX and AVX)
2536 include "X86InstrFragmentsSIMD.td"
2538 // FMA - Fused Multiply-Add support (requires FMA)
2539 include "X86InstrFMA.td"
2542 include "X86InstrXOP.td"
2544 // SSE, MMX and 3DNow! vector support.
2545 include "X86InstrSSE.td"
2546 include "X86InstrAVX512.td"
2547 include "X86InstrMMX.td"
2548 include "X86Instr3DNow.td"
2551 include "X86InstrMPX.td"
2553 include "X86InstrVMX.td"
2554 include "X86InstrSVM.td"
2556 include "X86InstrTSX.td"
2557 include "X86InstrSGX.td"
2559 // System instructions.
2560 include "X86InstrSystem.td"
2562 // Compiler Pseudo Instructions and Pat Patterns
2563 include "X86InstrCompiler.td"
2565 //===----------------------------------------------------------------------===//
2566 // Assembler Mnemonic Aliases
2567 //===----------------------------------------------------------------------===//
2569 def : MnemonicAlias<"call", "callw", "att">, Requires<[In16BitMode]>;
2570 def : MnemonicAlias<"call", "calll", "att">, Requires<[In32BitMode]>;
2571 def : MnemonicAlias<"call", "callq", "att">, Requires<[In64BitMode]>;
2573 def : MnemonicAlias<"cbw", "cbtw", "att">;
2574 def : MnemonicAlias<"cwde", "cwtl", "att">;
2575 def : MnemonicAlias<"cwd", "cwtd", "att">;
2576 def : MnemonicAlias<"cdq", "cltd", "att">;
2577 def : MnemonicAlias<"cdqe", "cltq", "att">;
2578 def : MnemonicAlias<"cqo", "cqto", "att">;
2580 // In 64-bit mode lret maps to lretl; it is not ambiguous with lretq.
2581 def : MnemonicAlias<"lret", "lretw", "att">, Requires<[In16BitMode]>;
2582 def : MnemonicAlias<"lret", "lretl", "att">, Requires<[Not16BitMode]>;
2584 def : MnemonicAlias<"leavel", "leave", "att">, Requires<[Not64BitMode]>;
2585 def : MnemonicAlias<"leaveq", "leave", "att">, Requires<[In64BitMode]>;
2587 def : MnemonicAlias<"loopz", "loope">;
2588 def : MnemonicAlias<"loopnz", "loopne">;
2590 def : MnemonicAlias<"pop", "popw", "att">, Requires<[In16BitMode]>;
2591 def : MnemonicAlias<"pop", "popl", "att">, Requires<[In32BitMode]>;
2592 def : MnemonicAlias<"pop", "popq", "att">, Requires<[In64BitMode]>;
2593 def : MnemonicAlias<"popf", "popfw", "att">, Requires<[In16BitMode]>;
2594 def : MnemonicAlias<"popf", "popfl", "att">, Requires<[In32BitMode]>;
2595 def : MnemonicAlias<"popf", "popfq", "att">, Requires<[In64BitMode]>;
2596 def : MnemonicAlias<"popfd", "popfl", "att">;
2598 // FIXME: This is wrong for "push reg". "push %bx" should turn into pushw in
2599 // all modes. However: "push (addr)" and "push $42" should default to
2600 // pushl/pushq depending on the current mode. Similar for "pop %bx"
2601 def : MnemonicAlias<"push", "pushw", "att">, Requires<[In16BitMode]>;
2602 def : MnemonicAlias<"push", "pushl", "att">, Requires<[In32BitMode]>;
2603 def : MnemonicAlias<"push", "pushq", "att">, Requires<[In64BitMode]>;
2604 def : MnemonicAlias<"pushf", "pushfw", "att">, Requires<[In16BitMode]>;
2605 def : MnemonicAlias<"pushf", "pushfl", "att">, Requires<[In32BitMode]>;
2606 def : MnemonicAlias<"pushf", "pushfq", "att">, Requires<[In64BitMode]>;
2607 def : MnemonicAlias<"pushfd", "pushfl", "att">;
2609 def : MnemonicAlias<"popad", "popal", "intel">, Requires<[Not64BitMode]>;
2610 def : MnemonicAlias<"pushad", "pushal", "intel">, Requires<[Not64BitMode]>;
2611 def : MnemonicAlias<"popa", "popaw", "intel">, Requires<[In16BitMode]>;
2612 def : MnemonicAlias<"pusha", "pushaw", "intel">, Requires<[In16BitMode]>;
2613 def : MnemonicAlias<"popa", "popal", "intel">, Requires<[In32BitMode]>;
2614 def : MnemonicAlias<"pusha", "pushal", "intel">, Requires<[In32BitMode]>;
2616 def : MnemonicAlias<"popa", "popaw", "att">, Requires<[In16BitMode]>;
2617 def : MnemonicAlias<"pusha", "pushaw", "att">, Requires<[In16BitMode]>;
2618 def : MnemonicAlias<"popa", "popal", "att">, Requires<[In32BitMode]>;
2619 def : MnemonicAlias<"pusha", "pushal", "att">, Requires<[In32BitMode]>;
2621 def : MnemonicAlias<"repe", "rep">;
2622 def : MnemonicAlias<"repz", "rep">;
2623 def : MnemonicAlias<"repnz", "repne">;
2625 def : MnemonicAlias<"ret", "retw", "att">, Requires<[In16BitMode]>;
2626 def : MnemonicAlias<"ret", "retl", "att">, Requires<[In32BitMode]>;
2627 def : MnemonicAlias<"ret", "retq", "att">, Requires<[In64BitMode]>;
2629 def : MnemonicAlias<"sal", "shl", "intel">;
2630 def : MnemonicAlias<"salb", "shlb", "att">;
2631 def : MnemonicAlias<"salw", "shlw", "att">;
2632 def : MnemonicAlias<"sall", "shll", "att">;
2633 def : MnemonicAlias<"salq", "shlq", "att">;
2635 def : MnemonicAlias<"smovb", "movsb", "att">;
2636 def : MnemonicAlias<"smovw", "movsw", "att">;
2637 def : MnemonicAlias<"smovl", "movsl", "att">;
2638 def : MnemonicAlias<"smovq", "movsq", "att">;
2640 def : MnemonicAlias<"ud2a", "ud2", "att">;
2641 def : MnemonicAlias<"verrw", "verr", "att">;
2643 // System instruction aliases.
2644 def : MnemonicAlias<"iret", "iretw", "att">, Requires<[In16BitMode]>;
2645 def : MnemonicAlias<"iret", "iretl", "att">, Requires<[Not16BitMode]>;
2646 def : MnemonicAlias<"sysret", "sysretl", "att">;
2647 def : MnemonicAlias<"sysexit", "sysexitl", "att">;
2649 def : MnemonicAlias<"lgdt", "lgdtw", "att">, Requires<[In16BitMode]>;
2650 def : MnemonicAlias<"lgdt", "lgdtl", "att">, Requires<[In32BitMode]>;
2651 def : MnemonicAlias<"lgdt", "lgdtq", "att">, Requires<[In64BitMode]>;
2652 def : MnemonicAlias<"lidt", "lidtw", "att">, Requires<[In16BitMode]>;
2653 def : MnemonicAlias<"lidt", "lidtl", "att">, Requires<[In32BitMode]>;
2654 def : MnemonicAlias<"lidt", "lidtq", "att">, Requires<[In64BitMode]>;
2655 def : MnemonicAlias<"sgdt", "sgdtw", "att">, Requires<[In16BitMode]>;
2656 def : MnemonicAlias<"sgdt", "sgdtl", "att">, Requires<[In32BitMode]>;
2657 def : MnemonicAlias<"sgdt", "sgdtq", "att">, Requires<[In64BitMode]>;
2658 def : MnemonicAlias<"sidt", "sidtw", "att">, Requires<[In16BitMode]>;
2659 def : MnemonicAlias<"sidt", "sidtl", "att">, Requires<[In32BitMode]>;
2660 def : MnemonicAlias<"sidt", "sidtq", "att">, Requires<[In64BitMode]>;
2663 // Floating point stack aliases.
2664 def : MnemonicAlias<"fcmovz", "fcmove", "att">;
2665 def : MnemonicAlias<"fcmova", "fcmovnbe", "att">;
2666 def : MnemonicAlias<"fcmovnae", "fcmovb", "att">;
2667 def : MnemonicAlias<"fcmovna", "fcmovbe", "att">;
2668 def : MnemonicAlias<"fcmovae", "fcmovnb", "att">;
2669 def : MnemonicAlias<"fcomip", "fcompi">;
2670 def : MnemonicAlias<"fildq", "fildll", "att">;
2671 def : MnemonicAlias<"fistpq", "fistpll", "att">;
2672 def : MnemonicAlias<"fisttpq", "fisttpll", "att">;
2673 def : MnemonicAlias<"fldcww", "fldcw", "att">;
2674 def : MnemonicAlias<"fnstcww", "fnstcw", "att">;
2675 def : MnemonicAlias<"fnstsww", "fnstsw", "att">;
2676 def : MnemonicAlias<"fucomip", "fucompi">;
2677 def : MnemonicAlias<"fwait", "wait">;
2679 def : MnemonicAlias<"fxsaveq", "fxsave64", "att">;
2680 def : MnemonicAlias<"fxrstorq", "fxrstor64", "att">;
2681 def : MnemonicAlias<"xsaveq", "xsave64", "att">;
2682 def : MnemonicAlias<"xrstorq", "xrstor64", "att">;
2683 def : MnemonicAlias<"xsaveoptq", "xsaveopt64", "att">;
2684 def : MnemonicAlias<"xrstorsq", "xrstors64", "att">;
2685 def : MnemonicAlias<"xsavecq", "xsavec64", "att">;
2686 def : MnemonicAlias<"xsavesq", "xsaves64", "att">;
2688 class CondCodeAlias<string Prefix,string Suffix, string OldCond, string NewCond,
2690 : MnemonicAlias<!strconcat(Prefix, OldCond, Suffix),
2691 !strconcat(Prefix, NewCond, Suffix), VariantName>;
2693 /// IntegerCondCodeMnemonicAlias - This multiclass defines a bunch of
2694 /// MnemonicAlias's that canonicalize the condition code in a mnemonic, for
2695 /// example "setz" -> "sete".
2696 multiclass IntegerCondCodeMnemonicAlias<string Prefix, string Suffix,
2698 def C : CondCodeAlias<Prefix, Suffix, "c", "b", V>; // setc -> setb
2699 def Z : CondCodeAlias<Prefix, Suffix, "z" , "e", V>; // setz -> sete
2700 def NA : CondCodeAlias<Prefix, Suffix, "na", "be", V>; // setna -> setbe
2701 def NB : CondCodeAlias<Prefix, Suffix, "nb", "ae", V>; // setnb -> setae
2702 def NC : CondCodeAlias<Prefix, Suffix, "nc", "ae", V>; // setnc -> setae
2703 def NG : CondCodeAlias<Prefix, Suffix, "ng", "le", V>; // setng -> setle
2704 def NL : CondCodeAlias<Prefix, Suffix, "nl", "ge", V>; // setnl -> setge
2705 def NZ : CondCodeAlias<Prefix, Suffix, "nz", "ne", V>; // setnz -> setne
2706 def PE : CondCodeAlias<Prefix, Suffix, "pe", "p", V>; // setpe -> setp
2707 def PO : CondCodeAlias<Prefix, Suffix, "po", "np", V>; // setpo -> setnp
2709 def NAE : CondCodeAlias<Prefix, Suffix, "nae", "b", V>; // setnae -> setb
2710 def NBE : CondCodeAlias<Prefix, Suffix, "nbe", "a", V>; // setnbe -> seta
2711 def NGE : CondCodeAlias<Prefix, Suffix, "nge", "l", V>; // setnge -> setl
2712 def NLE : CondCodeAlias<Prefix, Suffix, "nle", "g", V>; // setnle -> setg
2715 // Aliases for set<CC>
2716 defm : IntegerCondCodeMnemonicAlias<"set", "">;
2717 // Aliases for j<CC>
2718 defm : IntegerCondCodeMnemonicAlias<"j", "">;
2719 // Aliases for cmov<CC>{w,l,q}
2720 defm : IntegerCondCodeMnemonicAlias<"cmov", "w", "att">;
2721 defm : IntegerCondCodeMnemonicAlias<"cmov", "l", "att">;
2722 defm : IntegerCondCodeMnemonicAlias<"cmov", "q", "att">;
2723 // No size suffix for intel-style asm.
2724 defm : IntegerCondCodeMnemonicAlias<"cmov", "", "intel">;
2727 //===----------------------------------------------------------------------===//
2728 // Assembler Instruction Aliases
2729 //===----------------------------------------------------------------------===//
2731 // aad/aam default to base 10 if no operand is specified.
2732 def : InstAlias<"aad", (AAD8i8 10)>, Requires<[Not64BitMode]>;
2733 def : InstAlias<"aam", (AAM8i8 10)>, Requires<[Not64BitMode]>;
2735 // Disambiguate the mem/imm form of bt-without-a-suffix as btl.
2736 // Likewise for btc/btr/bts.
2737 def : InstAlias<"bt\t{$imm, $mem|$mem, $imm}",
2738 (BT32mi8 i32mem:$mem, i32i8imm:$imm), 0>;
2739 def : InstAlias<"btc\t{$imm, $mem|$mem, $imm}",
2740 (BTC32mi8 i32mem:$mem, i32i8imm:$imm), 0>;
2741 def : InstAlias<"btr\t{$imm, $mem|$mem, $imm}",
2742 (BTR32mi8 i32mem:$mem, i32i8imm:$imm), 0>;
2743 def : InstAlias<"bts\t{$imm, $mem|$mem, $imm}",
2744 (BTS32mi8 i32mem:$mem, i32i8imm:$imm), 0>;
2747 def : InstAlias<"clrb\t$reg", (XOR8rr GR8 :$reg, GR8 :$reg), 0>;
2748 def : InstAlias<"clrw\t$reg", (XOR16rr GR16:$reg, GR16:$reg), 0>;
2749 def : InstAlias<"clrl\t$reg", (XOR32rr GR32:$reg, GR32:$reg), 0>;
2750 def : InstAlias<"clrq\t$reg", (XOR64rr GR64:$reg, GR64:$reg), 0>;
2752 // lods aliases. Accept the destination being omitted because it's implicit
2753 // in the mnemonic, or the mnemonic suffix being omitted because it's implicit
2754 // in the destination.
2755 def : InstAlias<"lodsb\t$src", (LODSB srcidx8:$src), 0>;
2756 def : InstAlias<"lodsw\t$src", (LODSW srcidx16:$src), 0>;
2757 def : InstAlias<"lods{l|d}\t$src", (LODSL srcidx32:$src), 0>;
2758 def : InstAlias<"lodsq\t$src", (LODSQ srcidx64:$src), 0>, Requires<[In64BitMode]>;
2759 def : InstAlias<"lods\t{$src, %al|al, $src}", (LODSB srcidx8:$src), 0>;
2760 def : InstAlias<"lods\t{$src, %ax|ax, $src}", (LODSW srcidx16:$src), 0>;
2761 def : InstAlias<"lods\t{$src, %eax|eax, $src}", (LODSL srcidx32:$src), 0>;
2762 def : InstAlias<"lods\t{$src, %rax|rax, $src}", (LODSQ srcidx64:$src), 0>, Requires<[In64BitMode]>;
2763 def : InstAlias<"lods\t$src", (LODSB srcidx8:$src), 0>;
2764 def : InstAlias<"lods\t$src", (LODSW srcidx16:$src), 0>;
2765 def : InstAlias<"lods\t$src", (LODSL srcidx32:$src), 0>;
2766 def : InstAlias<"lods\t$src", (LODSQ srcidx64:$src), 0>, Requires<[In64BitMode]>;
2769 // stos aliases. Accept the source being omitted because it's implicit in
2770 // the mnemonic, or the mnemonic suffix being omitted because it's implicit
2772 def : InstAlias<"stosb\t$dst", (STOSB dstidx8:$dst), 0>;
2773 def : InstAlias<"stosw\t$dst", (STOSW dstidx16:$dst), 0>;
2774 def : InstAlias<"stos{l|d}\t$dst", (STOSL dstidx32:$dst), 0>;
2775 def : InstAlias<"stosq\t$dst", (STOSQ dstidx64:$dst), 0>, Requires<[In64BitMode]>;
2776 def : InstAlias<"stos\t{%al, $dst|$dst, al}", (STOSB dstidx8:$dst), 0>;
2777 def : InstAlias<"stos\t{%ax, $dst|$dst, ax}", (STOSW dstidx16:$dst), 0>;
2778 def : InstAlias<"stos\t{%eax, $dst|$dst, eax}", (STOSL dstidx32:$dst), 0>;
2779 def : InstAlias<"stos\t{%rax, $dst|$dst, rax}", (STOSQ dstidx64:$dst), 0>, Requires<[In64BitMode]>;
2780 def : InstAlias<"stos\t$dst", (STOSB dstidx8:$dst), 0>;
2781 def : InstAlias<"stos\t$dst", (STOSW dstidx16:$dst), 0>;
2782 def : InstAlias<"stos\t$dst", (STOSL dstidx32:$dst), 0>;
2783 def : InstAlias<"stos\t$dst", (STOSQ dstidx64:$dst), 0>, Requires<[In64BitMode]>;
2786 // scas aliases. Accept the destination being omitted because it's implicit
2787 // in the mnemonic, or the mnemonic suffix being omitted because it's implicit
2788 // in the destination.
2789 def : InstAlias<"scasb\t$dst", (SCASB dstidx8:$dst), 0>;
2790 def : InstAlias<"scasw\t$dst", (SCASW dstidx16:$dst), 0>;
2791 def : InstAlias<"scas{l|d}\t$dst", (SCASL dstidx32:$dst), 0>;
2792 def : InstAlias<"scasq\t$dst", (SCASQ dstidx64:$dst), 0>, Requires<[In64BitMode]>;
2793 def : InstAlias<"scas\t{$dst, %al|al, $dst}", (SCASB dstidx8:$dst), 0>;
2794 def : InstAlias<"scas\t{$dst, %ax|ax, $dst}", (SCASW dstidx16:$dst), 0>;
2795 def : InstAlias<"scas\t{$dst, %eax|eax, $dst}", (SCASL dstidx32:$dst), 0>;
2796 def : InstAlias<"scas\t{$dst, %rax|rax, $dst}", (SCASQ dstidx64:$dst), 0>, Requires<[In64BitMode]>;
2797 def : InstAlias<"scas\t$dst", (SCASB dstidx8:$dst), 0>;
2798 def : InstAlias<"scas\t$dst", (SCASW dstidx16:$dst), 0>;
2799 def : InstAlias<"scas\t$dst", (SCASL dstidx32:$dst), 0>;
2800 def : InstAlias<"scas\t$dst", (SCASQ dstidx64:$dst), 0>, Requires<[In64BitMode]>;
2802 // cmps aliases. Mnemonic suffix being omitted because it's implicit
2803 // in the destination.
2804 def : InstAlias<"cmps\t{$dst, $src|$src, $dst}", (CMPSB dstidx8:$dst, srcidx8:$src), 0>;
2805 def : InstAlias<"cmps\t{$dst, $src|$src, $dst}", (CMPSW dstidx16:$dst, srcidx16:$src), 0>;
2806 def : InstAlias<"cmps\t{$dst, $src|$src, $dst}", (CMPSL dstidx32:$dst, srcidx32:$src), 0>;
2807 def : InstAlias<"cmps\t{$dst, $src|$src, $dst}", (CMPSQ dstidx64:$dst, srcidx64:$src), 0>, Requires<[In64BitMode]>;
2809 // movs aliases. Mnemonic suffix being omitted because it's implicit
2810 // in the destination.
2811 def : InstAlias<"movs\t{$src, $dst|$dst, $src}", (MOVSB dstidx8:$dst, srcidx8:$src), 0>;
2812 def : InstAlias<"movs\t{$src, $dst|$dst, $src}", (MOVSW dstidx16:$dst, srcidx16:$src), 0>;
2813 def : InstAlias<"movs\t{$src, $dst|$dst, $src}", (MOVSL dstidx32:$dst, srcidx32:$src), 0>;
2814 def : InstAlias<"movs\t{$src, $dst|$dst, $src}", (MOVSQ dstidx64:$dst, srcidx64:$src), 0>, Requires<[In64BitMode]>;
2816 // div and idiv aliases for explicit A register.
2817 def : InstAlias<"div{b}\t{$src, %al|al, $src}", (DIV8r GR8 :$src)>;
2818 def : InstAlias<"div{w}\t{$src, %ax|ax, $src}", (DIV16r GR16:$src)>;
2819 def : InstAlias<"div{l}\t{$src, %eax|eax, $src}", (DIV32r GR32:$src)>;
2820 def : InstAlias<"div{q}\t{$src, %rax|rax, $src}", (DIV64r GR64:$src)>;
2821 def : InstAlias<"div{b}\t{$src, %al|al, $src}", (DIV8m i8mem :$src)>;
2822 def : InstAlias<"div{w}\t{$src, %ax|ax, $src}", (DIV16m i16mem:$src)>;
2823 def : InstAlias<"div{l}\t{$src, %eax|eax, $src}", (DIV32m i32mem:$src)>;
2824 def : InstAlias<"div{q}\t{$src, %rax|rax, $src}", (DIV64m i64mem:$src)>;
2825 def : InstAlias<"idiv{b}\t{$src, %al|al, $src}", (IDIV8r GR8 :$src)>;
2826 def : InstAlias<"idiv{w}\t{$src, %ax|ax, $src}", (IDIV16r GR16:$src)>;
2827 def : InstAlias<"idiv{l}\t{$src, %eax|eax, $src}", (IDIV32r GR32:$src)>;
2828 def : InstAlias<"idiv{q}\t{$src, %rax|rax, $src}", (IDIV64r GR64:$src)>;
2829 def : InstAlias<"idiv{b}\t{$src, %al|al, $src}", (IDIV8m i8mem :$src)>;
2830 def : InstAlias<"idiv{w}\t{$src, %ax|ax, $src}", (IDIV16m i16mem:$src)>;
2831 def : InstAlias<"idiv{l}\t{$src, %eax|eax, $src}", (IDIV32m i32mem:$src)>;
2832 def : InstAlias<"idiv{q}\t{$src, %rax|rax, $src}", (IDIV64m i64mem:$src)>;
2836 // Various unary fpstack operations default to operating on on ST1.
2837 // For example, "fxch" -> "fxch %st(1)"
2838 def : InstAlias<"faddp", (ADD_FPrST0 ST1), 0>;
2839 def: InstAlias<"fadd", (ADD_FPrST0 ST1), 0>;
2840 def : InstAlias<"fsub{|r}p", (SUBR_FPrST0 ST1), 0>;
2841 def : InstAlias<"fsub{r|}p", (SUB_FPrST0 ST1), 0>;
2842 def : InstAlias<"fmul", (MUL_FPrST0 ST1), 0>;
2843 def : InstAlias<"fmulp", (MUL_FPrST0 ST1), 0>;
2844 def : InstAlias<"fdiv{|r}p", (DIVR_FPrST0 ST1), 0>;
2845 def : InstAlias<"fdiv{r|}p", (DIV_FPrST0 ST1), 0>;
2846 def : InstAlias<"fxch", (XCH_F ST1), 0>;
2847 def : InstAlias<"fcom", (COM_FST0r ST1), 0>;
2848 def : InstAlias<"fcomp", (COMP_FST0r ST1), 0>;
2849 def : InstAlias<"fcomi", (COM_FIr ST1), 0>;
2850 def : InstAlias<"fcompi", (COM_FIPr ST1), 0>;
2851 def : InstAlias<"fucom", (UCOM_Fr ST1), 0>;
2852 def : InstAlias<"fucomp", (UCOM_FPr ST1), 0>;
2853 def : InstAlias<"fucomi", (UCOM_FIr ST1), 0>;
2854 def : InstAlias<"fucompi", (UCOM_FIPr ST1), 0>;
2856 // Handle fmul/fadd/fsub/fdiv instructions with explicitly written st(0) op.
2857 // For example, "fadd %st(4), %st(0)" -> "fadd %st(4)". We also disambiguate
2858 // instructions like "fadd %st(0), %st(0)" as "fadd %st(0)" for consistency with
2860 multiclass FpUnaryAlias<string Mnemonic, Instruction Inst, bit EmitAlias = 1> {
2861 def : InstAlias<!strconcat(Mnemonic, "\t{$op, %st(0)|st(0), $op}"),
2862 (Inst RST:$op), EmitAlias>;
2863 def : InstAlias<!strconcat(Mnemonic, "\t{%st(0), %st(0)|st(0), st(0)}"),
2864 (Inst ST0), EmitAlias>;
2867 defm : FpUnaryAlias<"fadd", ADD_FST0r>;
2868 defm : FpUnaryAlias<"faddp", ADD_FPrST0, 0>;
2869 defm : FpUnaryAlias<"fsub", SUB_FST0r>;
2870 defm : FpUnaryAlias<"fsub{|r}p", SUBR_FPrST0>;
2871 defm : FpUnaryAlias<"fsubr", SUBR_FST0r>;
2872 defm : FpUnaryAlias<"fsub{r|}p", SUB_FPrST0>;
2873 defm : FpUnaryAlias<"fmul", MUL_FST0r>;
2874 defm : FpUnaryAlias<"fmulp", MUL_FPrST0>;
2875 defm : FpUnaryAlias<"fdiv", DIV_FST0r>;
2876 defm : FpUnaryAlias<"fdiv{|r}p", DIVR_FPrST0>;
2877 defm : FpUnaryAlias<"fdivr", DIVR_FST0r>;
2878 defm : FpUnaryAlias<"fdiv{r|}p", DIV_FPrST0>;
2879 defm : FpUnaryAlias<"fcomi", COM_FIr, 0>;
2880 defm : FpUnaryAlias<"fucomi", UCOM_FIr, 0>;
2881 defm : FpUnaryAlias<"fcompi", COM_FIPr>;
2882 defm : FpUnaryAlias<"fucompi", UCOM_FIPr>;
2885 // Handle "f{mulp,addp} st(0), $op" the same as "f{mulp,addp} $op", since they
2886 // commute. We also allow fdiv[r]p/fsubrp even though they don't commute,
2887 // solely because gas supports it.
2888 def : InstAlias<"faddp\t{%st(0), $op|$op, st(0)}", (ADD_FPrST0 RST:$op), 0>;
2889 def : InstAlias<"fmulp\t{%st(0), $op|$op, st(0)}", (MUL_FPrST0 RST:$op)>;
2890 def : InstAlias<"fsub{|r}p\t{%st(0), $op|$op, st(0)}", (SUBR_FPrST0 RST:$op)>;
2891 def : InstAlias<"fsub{r|}p\t{%st(0), $op|$op, st(0)}", (SUB_FPrST0 RST:$op)>;
2892 def : InstAlias<"fdiv{|r}p\t{%st(0), $op|$op, st(0)}", (DIVR_FPrST0 RST:$op)>;
2893 def : InstAlias<"fdiv{r|}p\t{%st(0), $op|$op, st(0)}", (DIV_FPrST0 RST:$op)>;
2895 // We accept "fnstsw %eax" even though it only writes %ax.
2896 def : InstAlias<"fnstsw\t{%eax|eax}", (FNSTSW16r)>;
2897 def : InstAlias<"fnstsw\t{%al|al}" , (FNSTSW16r)>;
2898 def : InstAlias<"fnstsw" , (FNSTSW16r)>;
2900 // lcall and ljmp aliases. This seems to be an odd mapping in 64-bit mode, but
2901 // this is compatible with what GAS does.
2902 def : InstAlias<"lcall\t$seg, $off", (FARCALL32i i32imm:$off, i16imm:$seg), 0>, Requires<[In32BitMode]>;
2903 def : InstAlias<"ljmp\t$seg, $off", (FARJMP32i i32imm:$off, i16imm:$seg), 0>, Requires<[In32BitMode]>;
2904 def : InstAlias<"lcall\t{*}$dst", (FARCALL32m opaque48mem:$dst), 0>, Requires<[Not16BitMode]>;
2905 def : InstAlias<"ljmp\t{*}$dst", (FARJMP32m opaque48mem:$dst), 0>, Requires<[Not16BitMode]>;
2906 def : InstAlias<"lcall\t$seg, $off", (FARCALL16i i16imm:$off, i16imm:$seg), 0>, Requires<[In16BitMode]>;
2907 def : InstAlias<"ljmp\t$seg, $off", (FARJMP16i i16imm:$off, i16imm:$seg), 0>, Requires<[In16BitMode]>;
2908 def : InstAlias<"lcall\t{*}$dst", (FARCALL16m opaque32mem:$dst), 0>, Requires<[In16BitMode]>;
2909 def : InstAlias<"ljmp\t{*}$dst", (FARJMP16m opaque32mem:$dst), 0>, Requires<[In16BitMode]>;
2911 def : InstAlias<"call\t{*}$dst", (CALL64m i64mem:$dst), 0>, Requires<[In64BitMode]>;
2912 def : InstAlias<"jmp\t{*}$dst", (JMP64m i64mem:$dst), 0>, Requires<[In64BitMode]>;
2913 def : InstAlias<"call\t{*}$dst", (CALL32m i32mem:$dst), 0>, Requires<[In32BitMode]>;
2914 def : InstAlias<"jmp\t{*}$dst", (JMP32m i32mem:$dst), 0>, Requires<[In32BitMode]>;
2915 def : InstAlias<"call\t{*}$dst", (CALL16m i16mem:$dst), 0>, Requires<[In16BitMode]>;
2916 def : InstAlias<"jmp\t{*}$dst", (JMP16m i16mem:$dst), 0>, Requires<[In16BitMode]>;
2919 // "imul <imm>, B" is an alias for "imul <imm>, B, B".
2920 def : InstAlias<"imul{w}\t{$imm, $r|$r, $imm}", (IMUL16rri GR16:$r, GR16:$r, i16imm:$imm), 0>;
2921 def : InstAlias<"imul{w}\t{$imm, $r|$r, $imm}", (IMUL16rri8 GR16:$r, GR16:$r, i16i8imm:$imm), 0>;
2922 def : InstAlias<"imul{l}\t{$imm, $r|$r, $imm}", (IMUL32rri GR32:$r, GR32:$r, i32imm:$imm), 0>;
2923 def : InstAlias<"imul{l}\t{$imm, $r|$r, $imm}", (IMUL32rri8 GR32:$r, GR32:$r, i32i8imm:$imm), 0>;
2924 def : InstAlias<"imul{q}\t{$imm, $r|$r, $imm}", (IMUL64rri32 GR64:$r, GR64:$r, i64i32imm:$imm), 0>;
2925 def : InstAlias<"imul{q}\t{$imm, $r|$r, $imm}", (IMUL64rri8 GR64:$r, GR64:$r, i64i8imm:$imm), 0>;
2927 // ins aliases. Accept the mnemonic suffix being omitted because it's implicit
2928 // in the destination.
2929 def : InstAlias<"ins\t{%dx, $dst|$dst, dx}", (INSB dstidx8:$dst), 0>;
2930 def : InstAlias<"ins\t{%dx, $dst|$dst, dx}", (INSW dstidx16:$dst), 0>;
2931 def : InstAlias<"ins\t{%dx, $dst|$dst, dx}", (INSL dstidx32:$dst), 0>;
2933 // outs aliases. Accept the mnemonic suffix being omitted because it's implicit
2935 def : InstAlias<"outs\t{$src, %dx|dx, $src}", (OUTSB srcidx8:$src), 0>;
2936 def : InstAlias<"outs\t{$src, %dx|dx, $src}", (OUTSW srcidx16:$src), 0>;
2937 def : InstAlias<"outs\t{$src, %dx|dx, $src}", (OUTSL srcidx32:$src), 0>;
2939 // inb %dx -> inb %al, %dx
2940 def : InstAlias<"inb\t{%dx|dx}", (IN8rr), 0>;
2941 def : InstAlias<"inw\t{%dx|dx}", (IN16rr), 0>;
2942 def : InstAlias<"inl\t{%dx|dx}", (IN32rr), 0>;
2943 def : InstAlias<"inb\t$port", (IN8ri u8imm:$port), 0>;
2944 def : InstAlias<"inw\t$port", (IN16ri u8imm:$port), 0>;
2945 def : InstAlias<"inl\t$port", (IN32ri u8imm:$port), 0>;
2948 // jmp and call aliases for lcall and ljmp. jmp $42,$5 -> ljmp
2949 def : InstAlias<"call\t$seg, $off", (FARCALL16i i16imm:$off, i16imm:$seg)>, Requires<[In16BitMode]>;
2950 def : InstAlias<"jmp\t$seg, $off", (FARJMP16i i16imm:$off, i16imm:$seg)>, Requires<[In16BitMode]>;
2951 def : InstAlias<"call\t$seg, $off", (FARCALL32i i32imm:$off, i16imm:$seg)>, Requires<[In32BitMode]>;
2952 def : InstAlias<"jmp\t$seg, $off", (FARJMP32i i32imm:$off, i16imm:$seg)>, Requires<[In32BitMode]>;
2953 def : InstAlias<"callw\t$seg, $off", (FARCALL16i i16imm:$off, i16imm:$seg)>, Requires<[Not64BitMode]>;
2954 def : InstAlias<"jmpw\t$seg, $off", (FARJMP16i i16imm:$off, i16imm:$seg)>, Requires<[Not64BitMode]>;
2955 def : InstAlias<"calll\t$seg, $off", (FARCALL32i i32imm:$off, i16imm:$seg)>, Requires<[Not64BitMode]>;
2956 def : InstAlias<"jmpl\t$seg, $off", (FARJMP32i i32imm:$off, i16imm:$seg)>, Requires<[Not64BitMode]>;
2958 // Force mov without a suffix with a segment and mem to prefer the 'l' form of
2959 // the move. All segment/mem forms are equivalent, this has the shortest
2961 def : InstAlias<"mov\t{$mem, $seg|$seg, $mem}", (MOV32sm SEGMENT_REG:$seg, i32mem:$mem), 0>;
2962 def : InstAlias<"mov\t{$seg, $mem|$mem, $seg}", (MOV32ms i32mem:$mem, SEGMENT_REG:$seg), 0>;
2964 // Match 'movq <largeimm>, <reg>' as an alias for movabsq.
2965 def : InstAlias<"movq\t{$imm, $reg|$reg, $imm}", (MOV64ri GR64:$reg, i64imm:$imm), 0>;
2967 // Match 'movq GR64, MMX' as an alias for movd.
2968 def : InstAlias<"movq\t{$src, $dst|$dst, $src}",
2969 (MMX_MOVD64to64rr VR64:$dst, GR64:$src), 0>;
2970 def : InstAlias<"movq\t{$src, $dst|$dst, $src}",
2971 (MMX_MOVD64from64rr GR64:$dst, VR64:$src), 0>;
2974 def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX16rr8 GR16:$dst, GR8:$src), 0>;
2975 def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX16rm8 GR16:$dst, i8mem:$src), 0>;
2976 def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX32rr8 GR32:$dst, GR8:$src), 0>;
2977 def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX32rr16 GR32:$dst, GR16:$src), 0>;
2978 def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX64rr8 GR64:$dst, GR8:$src), 0>;
2979 def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX64rr16 GR64:$dst, GR16:$src), 0>;
2980 def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX64rr32 GR64:$dst, GR32:$src), 0>;
2983 def : InstAlias<"movzx\t{$src, $dst|$dst, $src}", (MOVZX16rr8 GR16:$dst, GR8:$src), 0>;
2984 def : InstAlias<"movzx\t{$src, $dst|$dst, $src}", (MOVZX16rm8 GR16:$dst, i8mem:$src), 0>;
2985 def : InstAlias<"movzx\t{$src, $dst|$dst, $src}", (MOVZX32rr8 GR32:$dst, GR8:$src), 0>;
2986 def : InstAlias<"movzx\t{$src, $dst|$dst, $src}", (MOVZX32rr16 GR32:$dst, GR16:$src), 0>;
2987 def : InstAlias<"movzx\t{$src, $dst|$dst, $src}", (MOVZX64rr8 GR64:$dst, GR8:$src), 0>;
2988 def : InstAlias<"movzx\t{$src, $dst|$dst, $src}", (MOVZX64rr16 GR64:$dst, GR16:$src), 0>;
2989 // Note: No GR32->GR64 movzx form.
2991 // outb %dx -> outb %al, %dx
2992 def : InstAlias<"outb\t{%dx|dx}", (OUT8rr), 0>;
2993 def : InstAlias<"outw\t{%dx|dx}", (OUT16rr), 0>;
2994 def : InstAlias<"outl\t{%dx|dx}", (OUT32rr), 0>;
2995 def : InstAlias<"outb\t$port", (OUT8ir u8imm:$port), 0>;
2996 def : InstAlias<"outw\t$port", (OUT16ir u8imm:$port), 0>;
2997 def : InstAlias<"outl\t$port", (OUT32ir u8imm:$port), 0>;
2999 // 'sldt <mem>' can be encoded with either sldtw or sldtq with the same
3000 // effect (both store to a 16-bit mem). Force to sldtw to avoid ambiguity
3001 // errors, since its encoding is the most compact.
3002 def : InstAlias<"sldt $mem", (SLDT16m i16mem:$mem), 0>;
3004 // shld/shrd op,op -> shld op, op, CL
3005 def : InstAlias<"shld{w}\t{$r2, $r1|$r1, $r2}", (SHLD16rrCL GR16:$r1, GR16:$r2), 0>;
3006 def : InstAlias<"shld{l}\t{$r2, $r1|$r1, $r2}", (SHLD32rrCL GR32:$r1, GR32:$r2), 0>;
3007 def : InstAlias<"shld{q}\t{$r2, $r1|$r1, $r2}", (SHLD64rrCL GR64:$r1, GR64:$r2), 0>;
3008 def : InstAlias<"shrd{w}\t{$r2, $r1|$r1, $r2}", (SHRD16rrCL GR16:$r1, GR16:$r2), 0>;
3009 def : InstAlias<"shrd{l}\t{$r2, $r1|$r1, $r2}", (SHRD32rrCL GR32:$r1, GR32:$r2), 0>;
3010 def : InstAlias<"shrd{q}\t{$r2, $r1|$r1, $r2}", (SHRD64rrCL GR64:$r1, GR64:$r2), 0>;
3012 def : InstAlias<"shld{w}\t{$reg, $mem|$mem, $reg}", (SHLD16mrCL i16mem:$mem, GR16:$reg), 0>;
3013 def : InstAlias<"shld{l}\t{$reg, $mem|$mem, $reg}", (SHLD32mrCL i32mem:$mem, GR32:$reg), 0>;
3014 def : InstAlias<"shld{q}\t{$reg, $mem|$mem, $reg}", (SHLD64mrCL i64mem:$mem, GR64:$reg), 0>;
3015 def : InstAlias<"shrd{w}\t{$reg, $mem|$mem, $reg}", (SHRD16mrCL i16mem:$mem, GR16:$reg), 0>;
3016 def : InstAlias<"shrd{l}\t{$reg, $mem|$mem, $reg}", (SHRD32mrCL i32mem:$mem, GR32:$reg), 0>;
3017 def : InstAlias<"shrd{q}\t{$reg, $mem|$mem, $reg}", (SHRD64mrCL i64mem:$mem, GR64:$reg), 0>;
3019 /* FIXME: This is disabled because the asm matcher is currently incapable of
3020 * matching a fixed immediate like $1.
3021 // "shl X, $1" is an alias for "shl X".
3022 multiclass ShiftRotateByOneAlias<string Mnemonic, string Opc> {
3023 def : InstAlias<!strconcat(Mnemonic, "b $op, $$1"),
3024 (!cast<Instruction>(!strconcat(Opc, "8r1")) GR8:$op)>;
3025 def : InstAlias<!strconcat(Mnemonic, "w $op, $$1"),
3026 (!cast<Instruction>(!strconcat(Opc, "16r1")) GR16:$op)>;
3027 def : InstAlias<!strconcat(Mnemonic, "l $op, $$1"),
3028 (!cast<Instruction>(!strconcat(Opc, "32r1")) GR32:$op)>;
3029 def : InstAlias<!strconcat(Mnemonic, "q $op, $$1"),
3030 (!cast<Instruction>(!strconcat(Opc, "64r1")) GR64:$op)>;
3031 def : InstAlias<!strconcat(Mnemonic, "b $op, $$1"),
3032 (!cast<Instruction>(!strconcat(Opc, "8m1")) i8mem:$op)>;
3033 def : InstAlias<!strconcat(Mnemonic, "w $op, $$1"),
3034 (!cast<Instruction>(!strconcat(Opc, "16m1")) i16mem:$op)>;
3035 def : InstAlias<!strconcat(Mnemonic, "l $op, $$1"),
3036 (!cast<Instruction>(!strconcat(Opc, "32m1")) i32mem:$op)>;
3037 def : InstAlias<!strconcat(Mnemonic, "q $op, $$1"),
3038 (!cast<Instruction>(!strconcat(Opc, "64m1")) i64mem:$op)>;
3041 defm : ShiftRotateByOneAlias<"rcl", "RCL">;
3042 defm : ShiftRotateByOneAlias<"rcr", "RCR">;
3043 defm : ShiftRotateByOneAlias<"rol", "ROL">;
3044 defm : ShiftRotateByOneAlias<"ror", "ROR">;
3047 // test: We accept "testX <reg>, <mem>" and "testX <mem>, <reg>" as synonyms.
3048 def : InstAlias<"test{b}\t{$val, $mem|$mem, $val}",
3049 (TEST8rm GR8 :$val, i8mem :$mem), 0>;
3050 def : InstAlias<"test{w}\t{$val, $mem|$mem, $val}",
3051 (TEST16rm GR16:$val, i16mem:$mem), 0>;
3052 def : InstAlias<"test{l}\t{$val, $mem|$mem, $val}",
3053 (TEST32rm GR32:$val, i32mem:$mem), 0>;
3054 def : InstAlias<"test{q}\t{$val, $mem|$mem, $val}",
3055 (TEST64rm GR64:$val, i64mem:$mem), 0>;
3057 // xchg: We accept "xchgX <reg>, <mem>" and "xchgX <mem>, <reg>" as synonyms.
3058 def : InstAlias<"xchg{b}\t{$mem, $val|$val, $mem}",
3059 (XCHG8rm GR8 :$val, i8mem :$mem), 0>;
3060 def : InstAlias<"xchg{w}\t{$mem, $val|$val, $mem}",
3061 (XCHG16rm GR16:$val, i16mem:$mem), 0>;
3062 def : InstAlias<"xchg{l}\t{$mem, $val|$val, $mem}",
3063 (XCHG32rm GR32:$val, i32mem:$mem), 0>;
3064 def : InstAlias<"xchg{q}\t{$mem, $val|$val, $mem}",
3065 (XCHG64rm GR64:$val, i64mem:$mem), 0>;
3067 // xchg: We accept "xchgX <reg>, %eax" and "xchgX %eax, <reg>" as synonyms.
3068 def : InstAlias<"xchg{w}\t{%ax, $src|$src, ax}", (XCHG16ar GR16:$src), 0>;
3069 def : InstAlias<"xchg{l}\t{%eax, $src|$src, eax}",
3070 (XCHG32ar GR32:$src), 0>, Requires<[Not64BitMode]>;
3071 def : InstAlias<"xchg{l}\t{%eax, $src|$src, eax}",
3072 (XCHG32ar64 GR32_NOAX:$src), 0>, Requires<[In64BitMode]>;
3073 def : InstAlias<"xchg{q}\t{%rax, $src|$src, rax}", (XCHG64ar GR64:$src), 0>;
3075 // These aliases exist to get the parser to prioritize matching 8-bit
3076 // immediate encodings over matching the implicit ax/eax/rax encodings. By
3077 // explicitly mentioning the A register here, these entries will be ordered
3078 // first due to the more explicit immediate type.
3079 def : InstAlias<"adc{w}\t{$imm, %ax|ax, $imm}", (ADC16ri8 AX, i16i8imm:$imm), 0>;
3080 def : InstAlias<"add{w}\t{$imm, %ax|ax, $imm}", (ADD16ri8 AX, i16i8imm:$imm), 0>;
3081 def : InstAlias<"and{w}\t{$imm, %ax|ax, $imm}", (AND16ri8 AX, i16i8imm:$imm), 0>;
3082 def : InstAlias<"cmp{w}\t{$imm, %ax|ax, $imm}", (CMP16ri8 AX, i16i8imm:$imm), 0>;
3083 def : InstAlias<"or{w}\t{$imm, %ax|ax, $imm}", (OR16ri8 AX, i16i8imm:$imm), 0>;
3084 def : InstAlias<"sbb{w}\t{$imm, %ax|ax, $imm}", (SBB16ri8 AX, i16i8imm:$imm), 0>;
3085 def : InstAlias<"sub{w}\t{$imm, %ax|ax, $imm}", (SUB16ri8 AX, i16i8imm:$imm), 0>;
3086 def : InstAlias<"xor{w}\t{$imm, %ax|ax, $imm}", (XOR16ri8 AX, i16i8imm:$imm), 0>;
3088 def : InstAlias<"adc{l}\t{$imm, %eax|eax, $imm}", (ADC32ri8 EAX, i32i8imm:$imm), 0>;
3089 def : InstAlias<"add{l}\t{$imm, %eax|eax, $imm}", (ADD32ri8 EAX, i32i8imm:$imm), 0>;
3090 def : InstAlias<"and{l}\t{$imm, %eax|eax, $imm}", (AND32ri8 EAX, i32i8imm:$imm), 0>;
3091 def : InstAlias<"cmp{l}\t{$imm, %eax|eax, $imm}", (CMP32ri8 EAX, i32i8imm:$imm), 0>;
3092 def : InstAlias<"or{l}\t{$imm, %eax|eax, $imm}", (OR32ri8 EAX, i32i8imm:$imm), 0>;
3093 def : InstAlias<"sbb{l}\t{$imm, %eax|eax, $imm}", (SBB32ri8 EAX, i32i8imm:$imm), 0>;
3094 def : InstAlias<"sub{l}\t{$imm, %eax|eax, $imm}", (SUB32ri8 EAX, i32i8imm:$imm), 0>;
3095 def : InstAlias<"xor{l}\t{$imm, %eax|eax, $imm}", (XOR32ri8 EAX, i32i8imm:$imm), 0>;
3097 def : InstAlias<"adc{q}\t{$imm, %rax|rax, $imm}", (ADC64ri8 RAX, i64i8imm:$imm), 0>;
3098 def : InstAlias<"add{q}\t{$imm, %rax|rax, $imm}", (ADD64ri8 RAX, i64i8imm:$imm), 0>;
3099 def : InstAlias<"and{q}\t{$imm, %rax|rax, $imm}", (AND64ri8 RAX, i64i8imm:$imm), 0>;
3100 def : InstAlias<"cmp{q}\t{$imm, %rax|rax, $imm}", (CMP64ri8 RAX, i64i8imm:$imm), 0>;
3101 def : InstAlias<"or{q}\t{$imm, %rax|rax, $imm}", (OR64ri8 RAX, i64i8imm:$imm), 0>;
3102 def : InstAlias<"sbb{q}\t{$imm, %rax|rax, $imm}", (SBB64ri8 RAX, i64i8imm:$imm), 0>;
3103 def : InstAlias<"sub{q}\t{$imm, %rax|rax, $imm}", (SUB64ri8 RAX, i64i8imm:$imm), 0>;
3104 def : InstAlias<"xor{q}\t{$imm, %rax|rax, $imm}", (XOR64ri8 RAX, i64i8imm:$imm), 0>;