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>]>;
75 def SDTX86atomicBinary : SDTypeProfile<2, 3, [SDTCisInt<0>, SDTCisInt<1>,
76 SDTCisPtrTy<2>, SDTCisInt<3>,SDTCisInt<4>]>;
77 def SDTX86Ret : SDTypeProfile<0, -1, [SDTCisVT<0, i16>]>;
79 def SDT_X86CallSeqStart : SDCallSeqStart<[SDTCisVT<0, i32>]>;
80 def SDT_X86CallSeqEnd : SDCallSeqEnd<[SDTCisVT<0, i32>,
83 def SDT_X86Call : SDTypeProfile<0, -1, [SDTCisVT<0, iPTR>]>;
85 def SDT_X86VASTART_SAVE_XMM_REGS : SDTypeProfile<0, -1, [SDTCisVT<0, i8>,
89 def SDT_X86VAARG_64 : SDTypeProfile<1, -1, [SDTCisPtrTy<0>,
95 def SDTX86RepStr : SDTypeProfile<0, 1, [SDTCisVT<0, OtherVT>]>;
97 def SDTX86Void : SDTypeProfile<0, 0, []>;
99 def SDTX86Wrapper : SDTypeProfile<1, 1, [SDTCisSameAs<0, 1>, SDTCisPtrTy<0>]>;
101 def SDT_X86TLSADDR : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
103 def SDT_X86TLSBASEADDR : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
105 def SDT_X86TLSCALL : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
107 def SDT_X86SEG_ALLOCA : SDTypeProfile<1, 1, [SDTCisVT<0, iPTR>, SDTCisVT<1, iPTR>]>;
109 def SDT_X86EHRET : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
111 def SDT_X86TCRET : SDTypeProfile<0, 2, [SDTCisPtrTy<0>, SDTCisVT<1, i32>]>;
113 def SDT_X86MEMBARRIER : SDTypeProfile<0, 0, []>;
115 def X86MemBarrier : SDNode<"X86ISD::MEMBARRIER", SDT_X86MEMBARRIER,
116 [SDNPHasChain,SDNPSideEffect]>;
117 def X86MFence : SDNode<"X86ISD::MFENCE", SDT_X86MEMBARRIER,
119 def X86SFence : SDNode<"X86ISD::SFENCE", SDT_X86MEMBARRIER,
121 def X86LFence : SDNode<"X86ISD::LFENCE", SDT_X86MEMBARRIER,
125 def X86bsf : SDNode<"X86ISD::BSF", SDTUnaryArithWithFlags>;
126 def X86bsr : SDNode<"X86ISD::BSR", SDTUnaryArithWithFlags>;
127 def X86shld : SDNode<"X86ISD::SHLD", SDTIntShiftDOp>;
128 def X86shrd : SDNode<"X86ISD::SHRD", SDTIntShiftDOp>;
130 def X86cmp : SDNode<"X86ISD::CMP" , SDTX86CmpTest>;
131 def X86bt : SDNode<"X86ISD::BT", SDTX86CmpTest>;
133 def X86cmov : SDNode<"X86ISD::CMOV", SDTX86Cmov>;
134 def X86brcond : SDNode<"X86ISD::BRCOND", SDTX86BrCond,
136 def X86setcc : SDNode<"X86ISD::SETCC", SDTX86SetCC>;
137 def X86setcc_c : SDNode<"X86ISD::SETCC_CARRY", SDTX86SetCC_C>;
139 def X86sahf : SDNode<"X86ISD::SAHF", SDTX86sahf>;
141 def X86rdrand : SDNode<"X86ISD::RDRAND", SDTX86rdrand,
142 [SDNPHasChain, SDNPSideEffect]>;
144 def X86rdseed : SDNode<"X86ISD::RDSEED", SDTX86rdrand,
145 [SDNPHasChain, SDNPSideEffect]>;
147 def X86cas : SDNode<"X86ISD::LCMPXCHG_DAG", SDTX86cas,
148 [SDNPHasChain, SDNPInGlue, SDNPOutGlue, SDNPMayStore,
149 SDNPMayLoad, SDNPMemOperand]>;
150 def X86cas8 : SDNode<"X86ISD::LCMPXCHG8_DAG", SDTX86caspair,
151 [SDNPHasChain, SDNPInGlue, SDNPOutGlue, SDNPMayStore,
152 SDNPMayLoad, SDNPMemOperand]>;
153 def X86cas16 : SDNode<"X86ISD::LCMPXCHG16_DAG", SDTX86caspair,
154 [SDNPHasChain, SDNPInGlue, SDNPOutGlue, SDNPMayStore,
155 SDNPMayLoad, SDNPMemOperand]>;
157 def X86retflag : SDNode<"X86ISD::RET_FLAG", SDTX86Ret,
158 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
160 def X86vastart_save_xmm_regs :
161 SDNode<"X86ISD::VASTART_SAVE_XMM_REGS",
162 SDT_X86VASTART_SAVE_XMM_REGS,
163 [SDNPHasChain, SDNPVariadic]>;
165 SDNode<"X86ISD::VAARG_64", SDT_X86VAARG_64,
166 [SDNPHasChain, SDNPMayLoad, SDNPMayStore,
168 def X86callseq_start :
169 SDNode<"ISD::CALLSEQ_START", SDT_X86CallSeqStart,
170 [SDNPHasChain, SDNPOutGlue]>;
172 SDNode<"ISD::CALLSEQ_END", SDT_X86CallSeqEnd,
173 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
175 def X86call : SDNode<"X86ISD::CALL", SDT_X86Call,
176 [SDNPHasChain, SDNPOutGlue, SDNPOptInGlue,
179 def X86rep_stos: SDNode<"X86ISD::REP_STOS", SDTX86RepStr,
180 [SDNPHasChain, SDNPInGlue, SDNPOutGlue, SDNPMayStore]>;
181 def X86rep_movs: SDNode<"X86ISD::REP_MOVS", SDTX86RepStr,
182 [SDNPHasChain, SDNPInGlue, SDNPOutGlue, SDNPMayStore,
185 def X86rdtsc : SDNode<"X86ISD::RDTSC_DAG", SDTX86Void,
186 [SDNPHasChain, SDNPOutGlue, SDNPSideEffect]>;
187 def X86rdtscp : SDNode<"X86ISD::RDTSCP_DAG", SDTX86Void,
188 [SDNPHasChain, SDNPOutGlue, SDNPSideEffect]>;
189 def X86rdpmc : SDNode<"X86ISD::RDPMC_DAG", SDTX86Void,
190 [SDNPHasChain, SDNPOutGlue, SDNPSideEffect]>;
192 def X86Wrapper : SDNode<"X86ISD::Wrapper", SDTX86Wrapper>;
193 def X86WrapperRIP : SDNode<"X86ISD::WrapperRIP", SDTX86Wrapper>;
195 def X86RecoverFrameAlloc : SDNode<"ISD::LOCAL_RECOVER",
196 SDTypeProfile<1, 1, [SDTCisSameAs<0, 1>,
199 def X86tlsaddr : SDNode<"X86ISD::TLSADDR", SDT_X86TLSADDR,
200 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
202 def X86tlsbaseaddr : SDNode<"X86ISD::TLSBASEADDR", SDT_X86TLSBASEADDR,
203 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
205 def X86ehret : SDNode<"X86ISD::EH_RETURN", SDT_X86EHRET,
208 def X86eh_sjlj_setjmp : SDNode<"X86ISD::EH_SJLJ_SETJMP",
209 SDTypeProfile<1, 1, [SDTCisInt<0>,
211 [SDNPHasChain, SDNPSideEffect]>;
212 def X86eh_sjlj_longjmp : SDNode<"X86ISD::EH_SJLJ_LONGJMP",
213 SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>,
214 [SDNPHasChain, SDNPSideEffect]>;
216 def X86tcret : SDNode<"X86ISD::TC_RETURN", SDT_X86TCRET,
217 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
219 def X86add_flag : SDNode<"X86ISD::ADD", SDTBinaryArithWithFlags,
221 def X86sub_flag : SDNode<"X86ISD::SUB", SDTBinaryArithWithFlags>;
222 def X86smul_flag : SDNode<"X86ISD::SMUL", SDTBinaryArithWithFlags,
224 def X86umul_flag : SDNode<"X86ISD::UMUL", SDT2ResultBinaryArithWithFlags,
226 def X86adc_flag : SDNode<"X86ISD::ADC", SDTBinaryArithWithFlagsInOut>;
227 def X86sbb_flag : SDNode<"X86ISD::SBB", SDTBinaryArithWithFlagsInOut>;
229 def X86inc_flag : SDNode<"X86ISD::INC", SDTUnaryArithWithFlags>;
230 def X86dec_flag : SDNode<"X86ISD::DEC", SDTUnaryArithWithFlags>;
231 def X86or_flag : SDNode<"X86ISD::OR", SDTBinaryArithWithFlags,
233 def X86xor_flag : SDNode<"X86ISD::XOR", SDTBinaryArithWithFlags,
235 def X86and_flag : SDNode<"X86ISD::AND", SDTBinaryArithWithFlags,
238 def X86bextr : SDNode<"X86ISD::BEXTR", SDTIntBinOp>;
240 def X86mul_imm : SDNode<"X86ISD::MUL_IMM", SDTIntBinOp>;
242 def X86WinAlloca : SDNode<"X86ISD::WIN_ALLOCA", SDTX86Void,
243 [SDNPHasChain, SDNPInGlue, SDNPOutGlue]>;
245 def X86SegAlloca : SDNode<"X86ISD::SEG_ALLOCA", SDT_X86SEG_ALLOCA,
248 def X86TLSCall : SDNode<"X86ISD::TLSCALL", SDT_X86TLSCALL,
249 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
251 //===----------------------------------------------------------------------===//
252 // X86 Operand Definitions.
255 // A version of ptr_rc which excludes SP, ESP, and RSP. This is used for
256 // the index operand of an address, to conform to x86 encoding restrictions.
257 def ptr_rc_nosp : PointerLikeRegClass<1>;
259 // *mem - Operand definitions for the funky X86 addressing mode operands.
261 def X86MemAsmOperand : AsmOperandClass {
264 let RenderMethod = "addMemOperands" in {
265 def X86Mem8AsmOperand : AsmOperandClass { let Name = "Mem8"; }
266 def X86Mem16AsmOperand : AsmOperandClass { let Name = "Mem16"; }
267 def X86Mem32AsmOperand : AsmOperandClass { let Name = "Mem32"; }
268 def X86Mem64AsmOperand : AsmOperandClass { let Name = "Mem64"; }
269 def X86Mem80AsmOperand : AsmOperandClass { let Name = "Mem80"; }
270 def X86Mem128AsmOperand : AsmOperandClass { let Name = "Mem128"; }
271 def X86Mem256AsmOperand : AsmOperandClass { let Name = "Mem256"; }
272 def X86Mem512AsmOperand : AsmOperandClass { let Name = "Mem512"; }
273 // Gather mem operands
274 def X86MemVX32Operand : AsmOperandClass { let Name = "MemVX32"; }
275 def X86MemVY32Operand : AsmOperandClass { let Name = "MemVY32"; }
276 def X86MemVZ32Operand : AsmOperandClass { let Name = "MemVZ32"; }
277 def X86MemVX64Operand : AsmOperandClass { let Name = "MemVX64"; }
278 def X86MemVY64Operand : AsmOperandClass { let Name = "MemVY64"; }
279 def X86MemVZ64Operand : AsmOperandClass { let Name = "MemVZ64"; }
280 def X86MemVX32XOperand : AsmOperandClass { let Name = "MemVX32X"; }
281 def X86MemVY32XOperand : AsmOperandClass { let Name = "MemVY32X"; }
282 def X86MemVX64XOperand : AsmOperandClass { let Name = "MemVX64X"; }
283 def X86MemVY64XOperand : AsmOperandClass { let Name = "MemVY64X"; }
286 def X86AbsMemAsmOperand : AsmOperandClass {
288 let SuperClasses = [X86MemAsmOperand];
291 class X86MemOperand<string printMethod,
292 AsmOperandClass parserMatchClass = X86MemAsmOperand> : Operand<iPTR> {
293 let PrintMethod = printMethod;
294 let MIOperandInfo = (ops ptr_rc, i8imm, ptr_rc_nosp, i32imm, i8imm);
295 let ParserMatchClass = parserMatchClass;
296 let OperandType = "OPERAND_MEMORY";
299 // Gather mem operands
300 class X86VMemOperand<RegisterClass RC, string printMethod,
301 AsmOperandClass parserMatchClass>
302 : X86MemOperand<printMethod, parserMatchClass> {
303 let MIOperandInfo = (ops ptr_rc, i8imm, RC, i32imm, i8imm);
306 def anymem : X86MemOperand<"printanymem">;
308 def opaque32mem : X86MemOperand<"printopaquemem">;
309 def opaque48mem : X86MemOperand<"printopaquemem">;
310 def opaque80mem : X86MemOperand<"printopaquemem">;
311 def opaque512mem : X86MemOperand<"printopaquemem">;
313 def i8mem : X86MemOperand<"printi8mem", X86Mem8AsmOperand>;
314 def i16mem : X86MemOperand<"printi16mem", X86Mem16AsmOperand>;
315 def i32mem : X86MemOperand<"printi32mem", X86Mem32AsmOperand>;
316 def i64mem : X86MemOperand<"printi64mem", X86Mem64AsmOperand>;
317 def i128mem : X86MemOperand<"printi128mem", X86Mem128AsmOperand>;
318 def i256mem : X86MemOperand<"printi256mem", X86Mem256AsmOperand>;
319 def i512mem : X86MemOperand<"printi512mem", X86Mem512AsmOperand>;
320 def f32mem : X86MemOperand<"printf32mem", X86Mem32AsmOperand>;
321 def f64mem : X86MemOperand<"printf64mem", X86Mem64AsmOperand>;
322 def f80mem : X86MemOperand<"printf80mem", X86Mem80AsmOperand>;
323 def f128mem : X86MemOperand<"printf128mem", X86Mem128AsmOperand>;
324 def f256mem : X86MemOperand<"printf256mem", X86Mem256AsmOperand>;
325 def f512mem : X86MemOperand<"printf512mem", X86Mem512AsmOperand>;
327 def v512mem : X86VMemOperand<VR512, "printf512mem", X86Mem512AsmOperand>;
329 // Gather mem operands
330 def vx32mem : X86VMemOperand<VR128, "printi32mem", X86MemVX32Operand>;
331 def vy32mem : X86VMemOperand<VR256, "printi32mem", X86MemVY32Operand>;
332 def vx64mem : X86VMemOperand<VR128, "printi64mem", X86MemVX64Operand>;
333 def vy64mem : X86VMemOperand<VR256, "printi64mem", X86MemVY64Operand>;
335 def vx32xmem : X86VMemOperand<VR128X, "printi32mem", X86MemVX32XOperand>;
336 def vx64xmem : X86VMemOperand<VR128X, "printi32mem", X86MemVX64XOperand>;
337 def vy32xmem : X86VMemOperand<VR256X, "printi32mem", X86MemVY32XOperand>;
338 def vy64xmem : X86VMemOperand<VR256X, "printi64mem", X86MemVY64XOperand>;
339 def vz32mem : X86VMemOperand<VR512, "printi32mem", X86MemVZ32Operand>;
340 def vz64mem : X86VMemOperand<VR512, "printi64mem", X86MemVZ64Operand>;
342 // A version of i8mem for use on x86-64 that uses GR64_NOREX instead of
343 // plain GR64, so that it doesn't potentially require a REX prefix.
344 def i8mem_NOREX : Operand<i64> {
345 let PrintMethod = "printi8mem";
346 let MIOperandInfo = (ops GR64_NOREX, i8imm, GR64_NOREX_NOSP, i32imm, i8imm);
347 let ParserMatchClass = X86Mem8AsmOperand;
348 let OperandType = "OPERAND_MEMORY";
351 // GPRs available for tailcall.
352 // It represents GR32_TC, GR64_TC or GR64_TCW64.
353 def ptr_rc_tailcall : PointerLikeRegClass<2>;
355 // Special i32mem for addresses of load folding tail calls. These are not
356 // allowed to use callee-saved registers since they must be scheduled
357 // after callee-saved register are popped.
358 def i32mem_TC : Operand<i32> {
359 let PrintMethod = "printi32mem";
360 let MIOperandInfo = (ops ptr_rc_tailcall, i8imm, ptr_rc_tailcall,
362 let ParserMatchClass = X86Mem32AsmOperand;
363 let OperandType = "OPERAND_MEMORY";
366 // Special i64mem for addresses of load folding tail calls. These are not
367 // allowed to use callee-saved registers since they must be scheduled
368 // after callee-saved register are popped.
369 def i64mem_TC : Operand<i64> {
370 let PrintMethod = "printi64mem";
371 let MIOperandInfo = (ops ptr_rc_tailcall, i8imm,
372 ptr_rc_tailcall, i32imm, i8imm);
373 let ParserMatchClass = X86Mem64AsmOperand;
374 let OperandType = "OPERAND_MEMORY";
377 let OperandType = "OPERAND_PCREL",
378 ParserMatchClass = X86AbsMemAsmOperand,
379 PrintMethod = "printPCRelImm" in {
380 def i32imm_pcrel : Operand<i32>;
381 def i16imm_pcrel : Operand<i16>;
383 // Branch targets have OtherVT type and print as pc-relative values.
384 def brtarget : Operand<OtherVT>;
385 def brtarget8 : Operand<OtherVT>;
389 // Special parser to detect 16-bit mode to select 16-bit displacement.
390 def X86AbsMem16AsmOperand : AsmOperandClass {
391 let Name = "AbsMem16";
392 let RenderMethod = "addAbsMemOperands";
393 let SuperClasses = [X86AbsMemAsmOperand];
396 // Branch targets have OtherVT type and print as pc-relative values.
397 let OperandType = "OPERAND_PCREL",
398 PrintMethod = "printPCRelImm" in {
399 let ParserMatchClass = X86AbsMem16AsmOperand in
400 def brtarget16 : Operand<OtherVT>;
401 let ParserMatchClass = X86AbsMemAsmOperand in
402 def brtarget32 : Operand<OtherVT>;
405 let RenderMethod = "addSrcIdxOperands" in {
406 def X86SrcIdx8Operand : AsmOperandClass {
407 let Name = "SrcIdx8";
408 let SuperClasses = [X86Mem8AsmOperand];
410 def X86SrcIdx16Operand : AsmOperandClass {
411 let Name = "SrcIdx16";
412 let SuperClasses = [X86Mem16AsmOperand];
414 def X86SrcIdx32Operand : AsmOperandClass {
415 let Name = "SrcIdx32";
416 let SuperClasses = [X86Mem32AsmOperand];
418 def X86SrcIdx64Operand : AsmOperandClass {
419 let Name = "SrcIdx64";
420 let SuperClasses = [X86Mem64AsmOperand];
422 } // RenderMethod = "addSrcIdxOperands"
424 let RenderMethod = "addDstIdxOperands" in {
425 def X86DstIdx8Operand : AsmOperandClass {
426 let Name = "DstIdx8";
427 let SuperClasses = [X86Mem8AsmOperand];
429 def X86DstIdx16Operand : AsmOperandClass {
430 let Name = "DstIdx16";
431 let SuperClasses = [X86Mem16AsmOperand];
433 def X86DstIdx32Operand : AsmOperandClass {
434 let Name = "DstIdx32";
435 let SuperClasses = [X86Mem32AsmOperand];
437 def X86DstIdx64Operand : AsmOperandClass {
438 let Name = "DstIdx64";
439 let SuperClasses = [X86Mem64AsmOperand];
441 } // RenderMethod = "addDstIdxOperands"
443 let RenderMethod = "addMemOffsOperands" in {
444 def X86MemOffs16_8AsmOperand : AsmOperandClass {
445 let Name = "MemOffs16_8";
446 let SuperClasses = [X86Mem8AsmOperand];
448 def X86MemOffs16_16AsmOperand : AsmOperandClass {
449 let Name = "MemOffs16_16";
450 let SuperClasses = [X86Mem16AsmOperand];
452 def X86MemOffs16_32AsmOperand : AsmOperandClass {
453 let Name = "MemOffs16_32";
454 let SuperClasses = [X86Mem32AsmOperand];
456 def X86MemOffs32_8AsmOperand : AsmOperandClass {
457 let Name = "MemOffs32_8";
458 let SuperClasses = [X86Mem8AsmOperand];
460 def X86MemOffs32_16AsmOperand : AsmOperandClass {
461 let Name = "MemOffs32_16";
462 let SuperClasses = [X86Mem16AsmOperand];
464 def X86MemOffs32_32AsmOperand : AsmOperandClass {
465 let Name = "MemOffs32_32";
466 let SuperClasses = [X86Mem32AsmOperand];
468 def X86MemOffs32_64AsmOperand : AsmOperandClass {
469 let Name = "MemOffs32_64";
470 let SuperClasses = [X86Mem64AsmOperand];
472 def X86MemOffs64_8AsmOperand : AsmOperandClass {
473 let Name = "MemOffs64_8";
474 let SuperClasses = [X86Mem8AsmOperand];
476 def X86MemOffs64_16AsmOperand : AsmOperandClass {
477 let Name = "MemOffs64_16";
478 let SuperClasses = [X86Mem16AsmOperand];
480 def X86MemOffs64_32AsmOperand : AsmOperandClass {
481 let Name = "MemOffs64_32";
482 let SuperClasses = [X86Mem32AsmOperand];
484 def X86MemOffs64_64AsmOperand : AsmOperandClass {
485 let Name = "MemOffs64_64";
486 let SuperClasses = [X86Mem64AsmOperand];
488 } // RenderMethod = "addMemOffsOperands"
490 class X86SrcIdxOperand<string printMethod, AsmOperandClass parserMatchClass>
491 : X86MemOperand<printMethod, parserMatchClass> {
492 let MIOperandInfo = (ops ptr_rc, i8imm);
495 class X86DstIdxOperand<string printMethod, AsmOperandClass parserMatchClass>
496 : X86MemOperand<printMethod, parserMatchClass> {
497 let MIOperandInfo = (ops ptr_rc);
500 def srcidx8 : X86SrcIdxOperand<"printSrcIdx8", X86SrcIdx8Operand>;
501 def srcidx16 : X86SrcIdxOperand<"printSrcIdx16", X86SrcIdx16Operand>;
502 def srcidx32 : X86SrcIdxOperand<"printSrcIdx32", X86SrcIdx32Operand>;
503 def srcidx64 : X86SrcIdxOperand<"printSrcIdx64", X86SrcIdx64Operand>;
504 def dstidx8 : X86DstIdxOperand<"printDstIdx8", X86DstIdx8Operand>;
505 def dstidx16 : X86DstIdxOperand<"printDstIdx16", X86DstIdx16Operand>;
506 def dstidx32 : X86DstIdxOperand<"printDstIdx32", X86DstIdx32Operand>;
507 def dstidx64 : X86DstIdxOperand<"printDstIdx64", X86DstIdx64Operand>;
509 class X86MemOffsOperand<Operand immOperand, string printMethod,
510 AsmOperandClass parserMatchClass>
511 : X86MemOperand<printMethod, parserMatchClass> {
512 let MIOperandInfo = (ops immOperand, i8imm);
515 def offset16_8 : X86MemOffsOperand<i16imm, "printMemOffs8",
516 X86MemOffs16_8AsmOperand>;
517 def offset16_16 : X86MemOffsOperand<i16imm, "printMemOffs16",
518 X86MemOffs16_16AsmOperand>;
519 def offset16_32 : X86MemOffsOperand<i16imm, "printMemOffs32",
520 X86MemOffs16_32AsmOperand>;
521 def offset32_8 : X86MemOffsOperand<i32imm, "printMemOffs8",
522 X86MemOffs32_8AsmOperand>;
523 def offset32_16 : X86MemOffsOperand<i32imm, "printMemOffs16",
524 X86MemOffs32_16AsmOperand>;
525 def offset32_32 : X86MemOffsOperand<i32imm, "printMemOffs32",
526 X86MemOffs32_32AsmOperand>;
527 def offset32_64 : X86MemOffsOperand<i32imm, "printMemOffs64",
528 X86MemOffs32_64AsmOperand>;
529 def offset64_8 : X86MemOffsOperand<i64imm, "printMemOffs8",
530 X86MemOffs64_8AsmOperand>;
531 def offset64_16 : X86MemOffsOperand<i64imm, "printMemOffs16",
532 X86MemOffs64_16AsmOperand>;
533 def offset64_32 : X86MemOffsOperand<i64imm, "printMemOffs32",
534 X86MemOffs64_32AsmOperand>;
535 def offset64_64 : X86MemOffsOperand<i64imm, "printMemOffs64",
536 X86MemOffs64_64AsmOperand>;
538 def SSECC : Operand<i8> {
539 let PrintMethod = "printSSEAVXCC";
540 let OperandType = "OPERAND_IMMEDIATE";
543 def i8immZExt3 : ImmLeaf<i8, [{
544 return Imm >= 0 && Imm < 8;
547 def AVXCC : Operand<i8> {
548 let PrintMethod = "printSSEAVXCC";
549 let OperandType = "OPERAND_IMMEDIATE";
552 def i8immZExt5 : ImmLeaf<i8, [{
553 return Imm >= 0 && Imm < 32;
556 def AVX512ICC : Operand<i8> {
557 let PrintMethod = "printSSEAVXCC";
558 let OperandType = "OPERAND_IMMEDIATE";
561 def XOPCC : Operand<i8> {
562 let PrintMethod = "printXOPCC";
563 let OperandType = "OPERAND_IMMEDIATE";
566 class ImmSExtAsmOperandClass : AsmOperandClass {
567 let SuperClasses = [ImmAsmOperand];
568 let RenderMethod = "addImmOperands";
571 def X86GR32orGR64AsmOperand : AsmOperandClass {
572 let Name = "GR32orGR64";
575 def GR32orGR64 : RegisterOperand<GR32> {
576 let ParserMatchClass = X86GR32orGR64AsmOperand;
578 def AVX512RCOperand : AsmOperandClass {
579 let Name = "AVX512RC";
581 def AVX512RC : Operand<i32> {
582 let PrintMethod = "printRoundingControl";
583 let OperandType = "OPERAND_IMMEDIATE";
584 let ParserMatchClass = AVX512RCOperand;
587 // Sign-extended immediate classes. We don't need to define the full lattice
588 // here because there is no instruction with an ambiguity between ImmSExti64i32
591 // The strange ranges come from the fact that the assembler always works with
592 // 64-bit immediates, but for a 16-bit target value we want to accept both "-1"
593 // (which will be a -1ULL), and "0xFF" (-1 in 16-bits).
596 // [0xFFFFFFFF80000000, 0xFFFFFFFFFFFFFFFF]
597 def ImmSExti64i32AsmOperand : ImmSExtAsmOperandClass {
598 let Name = "ImmSExti64i32";
601 // [0, 0x0000007F] | [0x000000000000FF80, 0x000000000000FFFF] |
602 // [0xFFFFFFFFFFFFFF80, 0xFFFFFFFFFFFFFFFF]
603 def ImmSExti16i8AsmOperand : ImmSExtAsmOperandClass {
604 let Name = "ImmSExti16i8";
605 let SuperClasses = [ImmSExti64i32AsmOperand];
608 // [0, 0x0000007F] | [0x00000000FFFFFF80, 0x00000000FFFFFFFF] |
609 // [0xFFFFFFFFFFFFFF80, 0xFFFFFFFFFFFFFFFF]
610 def ImmSExti32i8AsmOperand : ImmSExtAsmOperandClass {
611 let Name = "ImmSExti32i8";
615 // [0xFFFFFFFFFFFFFF80, 0xFFFFFFFFFFFFFFFF]
616 def ImmSExti64i8AsmOperand : ImmSExtAsmOperandClass {
617 let Name = "ImmSExti64i8";
618 let SuperClasses = [ImmSExti16i8AsmOperand, ImmSExti32i8AsmOperand,
619 ImmSExti64i32AsmOperand];
622 // Unsigned immediate used by SSE/AVX instructions
624 // [0xFFFFFFFFFFFFFF80, 0xFFFFFFFFFFFFFFFF]
625 def ImmUnsignedi8AsmOperand : AsmOperandClass {
626 let Name = "ImmUnsignedi8";
627 let RenderMethod = "addImmOperands";
630 // A couple of more descriptive operand definitions.
631 // 16-bits but only 8 bits are significant.
632 def i16i8imm : Operand<i16> {
633 let ParserMatchClass = ImmSExti16i8AsmOperand;
634 let OperandType = "OPERAND_IMMEDIATE";
636 // 32-bits but only 8 bits are significant.
637 def i32i8imm : Operand<i32> {
638 let ParserMatchClass = ImmSExti32i8AsmOperand;
639 let OperandType = "OPERAND_IMMEDIATE";
642 // 64-bits but only 32 bits are significant.
643 def i64i32imm : Operand<i64> {
644 let ParserMatchClass = ImmSExti64i32AsmOperand;
645 let OperandType = "OPERAND_IMMEDIATE";
648 // 64-bits but only 8 bits are significant.
649 def i64i8imm : Operand<i64> {
650 let ParserMatchClass = ImmSExti64i8AsmOperand;
651 let OperandType = "OPERAND_IMMEDIATE";
654 // Unsigned 8-bit immediate used by SSE/AVX instructions.
655 def u8imm : Operand<i8> {
656 let PrintMethod = "printU8Imm";
657 let ParserMatchClass = ImmUnsignedi8AsmOperand;
658 let OperandType = "OPERAND_IMMEDIATE";
661 // 32-bit immediate but only 8-bits are significant and they are unsigned.
662 // Used by some SSE/AVX instructions that use intrinsics.
663 def i32u8imm : Operand<i32> {
664 let PrintMethod = "printU8Imm";
665 let ParserMatchClass = ImmUnsignedi8AsmOperand;
666 let OperandType = "OPERAND_IMMEDIATE";
669 // 64-bits but only 32 bits are significant, and those bits are treated as being
671 def i64i32imm_pcrel : Operand<i64> {
672 let PrintMethod = "printPCRelImm";
673 let ParserMatchClass = X86AbsMemAsmOperand;
674 let OperandType = "OPERAND_PCREL";
677 def lea64_32mem : Operand<i32> {
678 let PrintMethod = "printanymem";
679 let MIOperandInfo = (ops GR64, i8imm, GR64_NOSP, i32imm, i8imm);
680 let ParserMatchClass = X86MemAsmOperand;
683 // Memory operands that use 64-bit pointers in both ILP32 and LP64.
684 def lea64mem : Operand<i64> {
685 let PrintMethod = "printanymem";
686 let MIOperandInfo = (ops GR64, i8imm, GR64_NOSP, i32imm, i8imm);
687 let ParserMatchClass = X86MemAsmOperand;
691 //===----------------------------------------------------------------------===//
692 // X86 Complex Pattern Definitions.
695 // Define X86 specific addressing mode.
696 def addr : ComplexPattern<iPTR, 5, "SelectAddr", [], [SDNPWantParent]>;
697 def lea32addr : ComplexPattern<i32, 5, "SelectLEAAddr",
698 [add, sub, mul, X86mul_imm, shl, or, frameindex],
700 // In 64-bit mode 32-bit LEAs can use RIP-relative addressing.
701 def lea64_32addr : ComplexPattern<i32, 5, "SelectLEA64_32Addr",
702 [add, sub, mul, X86mul_imm, shl, or,
703 frameindex, X86WrapperRIP],
706 def tls32addr : ComplexPattern<i32, 5, "SelectTLSADDRAddr",
707 [tglobaltlsaddr], []>;
709 def tls32baseaddr : ComplexPattern<i32, 5, "SelectTLSADDRAddr",
710 [tglobaltlsaddr], []>;
712 def lea64addr : ComplexPattern<i64, 5, "SelectLEAAddr",
713 [add, sub, mul, X86mul_imm, shl, or, frameindex,
716 def tls64addr : ComplexPattern<i64, 5, "SelectTLSADDRAddr",
717 [tglobaltlsaddr], []>;
719 def tls64baseaddr : ComplexPattern<i64, 5, "SelectTLSADDRAddr",
720 [tglobaltlsaddr], []>;
722 def vectoraddr : ComplexPattern<iPTR, 5, "SelectVectorAddr", [],[SDNPWantParent]>;
724 //===----------------------------------------------------------------------===//
725 // X86 Instruction Predicate Definitions.
726 def HasCMov : Predicate<"Subtarget->hasCMov()">;
727 def NoCMov : Predicate<"!Subtarget->hasCMov()">;
729 def HasMMX : Predicate<"Subtarget->hasMMX()">;
730 def Has3DNow : Predicate<"Subtarget->has3DNow()">;
731 def Has3DNowA : Predicate<"Subtarget->has3DNowA()">;
732 def HasSSE1 : Predicate<"Subtarget->hasSSE1()">;
733 def UseSSE1 : Predicate<"Subtarget->hasSSE1() && !Subtarget->hasAVX()">;
734 def HasSSE2 : Predicate<"Subtarget->hasSSE2()">;
735 def UseSSE2 : Predicate<"Subtarget->hasSSE2() && !Subtarget->hasAVX()">;
736 def HasSSE3 : Predicate<"Subtarget->hasSSE3()">;
737 def UseSSE3 : Predicate<"Subtarget->hasSSE3() && !Subtarget->hasAVX()">;
738 def HasSSSE3 : Predicate<"Subtarget->hasSSSE3()">;
739 def UseSSSE3 : Predicate<"Subtarget->hasSSSE3() && !Subtarget->hasAVX()">;
740 def HasSSE41 : Predicate<"Subtarget->hasSSE41()">;
741 def NoSSE41 : Predicate<"!Subtarget->hasSSE41()">;
742 def UseSSE41 : Predicate<"Subtarget->hasSSE41() && !Subtarget->hasAVX()">;
743 def HasSSE42 : Predicate<"Subtarget->hasSSE42()">;
744 def UseSSE42 : Predicate<"Subtarget->hasSSE42() && !Subtarget->hasAVX()">;
745 def HasSSE4A : Predicate<"Subtarget->hasSSE4A()">;
746 def HasAVX : Predicate<"Subtarget->hasAVX()">;
747 def HasAVX2 : Predicate<"Subtarget->hasAVX2()">;
748 def HasAVX1Only : Predicate<"Subtarget->hasAVX() && !Subtarget->hasAVX2()">;
749 def HasAVX512 : Predicate<"Subtarget->hasAVX512()">,
750 AssemblerPredicate<"FeatureAVX512", "AVX-512 ISA">;
751 def UseAVX : Predicate<"Subtarget->hasAVX() && !Subtarget->hasAVX512()">;
752 def UseAVX2 : Predicate<"Subtarget->hasAVX2() && !Subtarget->hasAVX512()">;
753 def NoAVX512 : Predicate<"!Subtarget->hasAVX512()">;
754 def HasCDI : Predicate<"Subtarget->hasCDI()">,
755 AssemblerPredicate<"FeatureCDI", "AVX-512 CD ISA">;
756 def HasPFI : Predicate<"Subtarget->hasPFI()">,
757 AssemblerPredicate<"FeaturePFI", "AVX-512 PF ISA">;
758 def HasERI : Predicate<"Subtarget->hasERI()">,
759 AssemblerPredicate<"FeatureERI", "AVX-512 ER ISA">;
760 def HasDQI : Predicate<"Subtarget->hasDQI()">,
761 AssemblerPredicate<"FeatureDQI", "AVX-512 DQ ISA">;
762 def NoDQI : Predicate<"!Subtarget->hasDQI()">;
763 def HasBWI : Predicate<"Subtarget->hasBWI()">,
764 AssemblerPredicate<"FeatureBWI", "AVX-512 BW ISA">;
765 def NoBWI : Predicate<"!Subtarget->hasBWI()">;
766 def HasVLX : Predicate<"Subtarget->hasVLX()">,
767 AssemblerPredicate<"FeatureVLX", "AVX-512 VL ISA">;
768 def NoVLX : Predicate<"!Subtarget->hasVLX()">;
769 def NoVLX_Or_NoBWI : Predicate<"!Subtarget->hasVLX() || !Subtarget->hasBWI()">;
771 def HasPOPCNT : Predicate<"Subtarget->hasPOPCNT()">;
772 def HasAES : Predicate<"Subtarget->hasAES()">;
773 def HasPCLMUL : Predicate<"Subtarget->hasPCLMUL()">;
774 def HasFMA : Predicate<"Subtarget->hasFMA()">;
775 def UseFMAOnAVX : Predicate<"Subtarget->hasFMA() && !Subtarget->hasAVX512()">;
776 def HasFMA4 : Predicate<"Subtarget->hasFMA4()">;
777 def HasXOP : Predicate<"Subtarget->hasXOP()">;
778 def HasTBM : Predicate<"Subtarget->hasTBM()">;
779 def HasMOVBE : Predicate<"Subtarget->hasMOVBE()">;
780 def HasRDRAND : Predicate<"Subtarget->hasRDRAND()">;
781 def HasF16C : Predicate<"Subtarget->hasF16C()">;
782 def HasFSGSBase : Predicate<"Subtarget->hasFSGSBase()">;
783 def HasLZCNT : Predicate<"Subtarget->hasLZCNT()">;
784 def HasBMI : Predicate<"Subtarget->hasBMI()">;
785 def HasBMI2 : Predicate<"Subtarget->hasBMI2()">;
786 def HasRTM : Predicate<"Subtarget->hasRTM()">;
787 def HasHLE : Predicate<"Subtarget->hasHLE()">;
788 def HasTSX : Predicate<"Subtarget->hasRTM() || Subtarget->hasHLE()">;
789 def HasADX : Predicate<"Subtarget->hasADX()">;
790 def HasSHA : Predicate<"Subtarget->hasSHA()">;
791 def HasPRFCHW : Predicate<"Subtarget->hasPRFCHW()">;
792 def HasRDSEED : Predicate<"Subtarget->hasRDSEED()">;
793 def HasPrefetchW : Predicate<"Subtarget->hasPRFCHW()">;
794 def FPStackf32 : Predicate<"!Subtarget->hasSSE1()">;
795 def FPStackf64 : Predicate<"!Subtarget->hasSSE2()">;
796 def HasMPX : Predicate<"Subtarget->hasMPX()">;
797 def HasCmpxchg16b: Predicate<"Subtarget->hasCmpxchg16b()">;
798 def Not64BitMode : Predicate<"!Subtarget->is64Bit()">,
799 AssemblerPredicate<"!Mode64Bit", "Not 64-bit mode">;
800 def In64BitMode : Predicate<"Subtarget->is64Bit()">,
801 AssemblerPredicate<"Mode64Bit", "64-bit mode">;
802 def IsLP64 : Predicate<"Subtarget->isTarget64BitLP64()">;
803 def NotLP64 : Predicate<"!Subtarget->isTarget64BitLP64()">;
804 def In16BitMode : Predicate<"Subtarget->is16Bit()">,
805 AssemblerPredicate<"Mode16Bit", "16-bit mode">;
806 def Not16BitMode : Predicate<"!Subtarget->is16Bit()">,
807 AssemblerPredicate<"!Mode16Bit", "Not 16-bit mode">;
808 def In32BitMode : Predicate<"Subtarget->is32Bit()">,
809 AssemblerPredicate<"Mode32Bit", "32-bit mode">;
810 def IsWin64 : Predicate<"Subtarget->isTargetWin64()">;
811 def NotWin64 : Predicate<"!Subtarget->isTargetWin64()">;
812 def IsPS4 : Predicate<"Subtarget->isTargetPS4()">;
813 def NotPS4 : Predicate<"!Subtarget->isTargetPS4()">;
814 def IsNaCl : Predicate<"Subtarget->isTargetNaCl()">;
815 def NotNaCl : Predicate<"!Subtarget->isTargetNaCl()">;
816 def SmallCode : Predicate<"TM.getCodeModel() == CodeModel::Small">;
817 def KernelCode : Predicate<"TM.getCodeModel() == CodeModel::Kernel">;
818 def FarData : Predicate<"TM.getCodeModel() != CodeModel::Small &&"
819 "TM.getCodeModel() != CodeModel::Kernel">;
820 def NearData : Predicate<"TM.getCodeModel() == CodeModel::Small ||"
821 "TM.getCodeModel() == CodeModel::Kernel">;
822 def IsStatic : Predicate<"TM.getRelocationModel() == Reloc::Static">;
823 def IsNotPIC : Predicate<"TM.getRelocationModel() != Reloc::PIC_">;
824 def OptForSize : Predicate<"OptForSize">;
825 def OptForSpeed : Predicate<"!OptForSize">;
826 def FastBTMem : Predicate<"!Subtarget->isBTMemSlow()">;
827 def CallImmAddr : Predicate<"Subtarget->IsLegalToCallImmediateAddr(TM)">;
828 def FavorMemIndirectCall : Predicate<"!Subtarget->callRegIndirect()">;
829 def NotSlowIncDec : Predicate<"!Subtarget->slowIncDec()">;
830 def HasFastMem32 : Predicate<"!Subtarget->isUnalignedMem32Slow()">;
832 //===----------------------------------------------------------------------===//
833 // X86 Instruction Format Definitions.
836 include "X86InstrFormats.td"
838 //===----------------------------------------------------------------------===//
839 // Pattern fragments.
842 // X86 specific condition code. These correspond to CondCode in
843 // X86InstrInfo.h. They must be kept in synch.
844 def X86_COND_A : PatLeaf<(i8 0)>; // alt. COND_NBE
845 def X86_COND_AE : PatLeaf<(i8 1)>; // alt. COND_NC
846 def X86_COND_B : PatLeaf<(i8 2)>; // alt. COND_C
847 def X86_COND_BE : PatLeaf<(i8 3)>; // alt. COND_NA
848 def X86_COND_E : PatLeaf<(i8 4)>; // alt. COND_Z
849 def X86_COND_G : PatLeaf<(i8 5)>; // alt. COND_NLE
850 def X86_COND_GE : PatLeaf<(i8 6)>; // alt. COND_NL
851 def X86_COND_L : PatLeaf<(i8 7)>; // alt. COND_NGE
852 def X86_COND_LE : PatLeaf<(i8 8)>; // alt. COND_NG
853 def X86_COND_NE : PatLeaf<(i8 9)>; // alt. COND_NZ
854 def X86_COND_NO : PatLeaf<(i8 10)>;
855 def X86_COND_NP : PatLeaf<(i8 11)>; // alt. COND_PO
856 def X86_COND_NS : PatLeaf<(i8 12)>;
857 def X86_COND_O : PatLeaf<(i8 13)>;
858 def X86_COND_P : PatLeaf<(i8 14)>; // alt. COND_PE
859 def X86_COND_S : PatLeaf<(i8 15)>;
861 // Predicate used to help when pattern matching LZCNT/TZCNT.
862 def X86_COND_E_OR_NE : ImmLeaf<i8, [{
863 return (Imm == X86::COND_E) || (Imm == X86::COND_NE);
867 def i16immSExt8 : ImmLeaf<i16, [{ return Imm == (int8_t)Imm; }]>;
868 def i32immSExt8 : ImmLeaf<i32, [{ return Imm == (int8_t)Imm; }]>;
869 def i64immSExt8 : ImmLeaf<i64, [{ return Imm == (int8_t)Imm; }]>;
871 // If we have multiple users of an immediate, it's much smaller to reuse
872 // the register, rather than encode the immediate in every instruction.
873 // This has the risk of increasing register pressure from stretched live
874 // ranges, however, the immediates should be trivial to rematerialize by
875 // the RA in the event of high register pressure.
876 // TODO : This is currently enabled for stores and binary ops. There are more
877 // cases for which this can be enabled, though this catches the bulk of the
879 // TODO2 : This should really also be enabled under O2, but there's currently
880 // an issue with RA where we don't pull the constants into their users
881 // when we rematerialize them. I'll follow-up on enabling O2 after we fix that
883 // TODO3 : This is currently limited to single basic blocks (DAG creation
884 // pulls block immediates to the top and merges them if necessary).
885 // Eventually, it would be nice to allow ConstantHoisting to merge constants
886 // globally for potentially added savings.
888 def imm8_su : PatLeaf<(i8 imm), [{
889 return !shouldAvoidImmediateInstFormsForSize(N);
891 def imm16_su : PatLeaf<(i16 imm), [{
892 return !shouldAvoidImmediateInstFormsForSize(N);
894 def imm32_su : PatLeaf<(i32 imm), [{
895 return !shouldAvoidImmediateInstFormsForSize(N);
898 def i16immSExt8_su : PatLeaf<(i16immSExt8), [{
899 return !shouldAvoidImmediateInstFormsForSize(N);
901 def i32immSExt8_su : PatLeaf<(i32immSExt8), [{
902 return !shouldAvoidImmediateInstFormsForSize(N);
906 def i64immSExt32 : ImmLeaf<i64, [{ return Imm == (int32_t)Imm; }]>;
909 // i64immZExt32 predicate - True if the 64-bit immediate fits in a 32-bit
911 def i64immZExt32 : ImmLeaf<i64, [{ return (uint64_t)Imm == (uint32_t)Imm; }]>;
913 def i64immZExt32SExt8 : ImmLeaf<i64, [{
914 return (uint64_t)Imm == (uint32_t)Imm && (int32_t)Imm == (int8_t)Imm;
917 // Helper fragments for loads.
918 // It's always safe to treat a anyext i16 load as a i32 load if the i16 is
919 // known to be 32-bit aligned or better. Ditto for i8 to i16.
920 def loadi16 : PatFrag<(ops node:$ptr), (i16 (unindexedload node:$ptr)), [{
921 LoadSDNode *LD = cast<LoadSDNode>(N);
922 ISD::LoadExtType ExtType = LD->getExtensionType();
923 if (ExtType == ISD::NON_EXTLOAD)
925 if (ExtType == ISD::EXTLOAD)
926 return LD->getAlignment() >= 2 && !LD->isVolatile();
930 def loadi16_anyext : PatFrag<(ops node:$ptr), (i32 (unindexedload node:$ptr)),[{
931 LoadSDNode *LD = cast<LoadSDNode>(N);
932 ISD::LoadExtType ExtType = LD->getExtensionType();
933 if (ExtType == ISD::EXTLOAD)
934 return LD->getAlignment() >= 2 && !LD->isVolatile();
938 def loadi32 : PatFrag<(ops node:$ptr), (i32 (unindexedload node:$ptr)), [{
939 LoadSDNode *LD = cast<LoadSDNode>(N);
940 ISD::LoadExtType ExtType = LD->getExtensionType();
941 if (ExtType == ISD::NON_EXTLOAD)
943 if (ExtType == ISD::EXTLOAD)
944 return LD->getAlignment() >= 4 && !LD->isVolatile();
948 def loadi8 : PatFrag<(ops node:$ptr), (i8 (load node:$ptr))>;
949 def loadi64 : PatFrag<(ops node:$ptr), (i64 (load node:$ptr))>;
950 def loadf32 : PatFrag<(ops node:$ptr), (f32 (load node:$ptr))>;
951 def loadf64 : PatFrag<(ops node:$ptr), (f64 (load node:$ptr))>;
952 def loadf80 : PatFrag<(ops node:$ptr), (f80 (load node:$ptr))>;
954 def sextloadi16i8 : PatFrag<(ops node:$ptr), (i16 (sextloadi8 node:$ptr))>;
955 def sextloadi32i8 : PatFrag<(ops node:$ptr), (i32 (sextloadi8 node:$ptr))>;
956 def sextloadi32i16 : PatFrag<(ops node:$ptr), (i32 (sextloadi16 node:$ptr))>;
957 def sextloadi64i8 : PatFrag<(ops node:$ptr), (i64 (sextloadi8 node:$ptr))>;
958 def sextloadi64i16 : PatFrag<(ops node:$ptr), (i64 (sextloadi16 node:$ptr))>;
959 def sextloadi64i32 : PatFrag<(ops node:$ptr), (i64 (sextloadi32 node:$ptr))>;
961 def zextloadi8i1 : PatFrag<(ops node:$ptr), (i8 (zextloadi1 node:$ptr))>;
962 def zextloadi16i1 : PatFrag<(ops node:$ptr), (i16 (zextloadi1 node:$ptr))>;
963 def zextloadi32i1 : PatFrag<(ops node:$ptr), (i32 (zextloadi1 node:$ptr))>;
964 def zextloadi16i8 : PatFrag<(ops node:$ptr), (i16 (zextloadi8 node:$ptr))>;
965 def zextloadi32i8 : PatFrag<(ops node:$ptr), (i32 (zextloadi8 node:$ptr))>;
966 def zextloadi32i16 : PatFrag<(ops node:$ptr), (i32 (zextloadi16 node:$ptr))>;
967 def zextloadi64i1 : PatFrag<(ops node:$ptr), (i64 (zextloadi1 node:$ptr))>;
968 def zextloadi64i8 : PatFrag<(ops node:$ptr), (i64 (zextloadi8 node:$ptr))>;
969 def zextloadi64i16 : PatFrag<(ops node:$ptr), (i64 (zextloadi16 node:$ptr))>;
970 def zextloadi64i32 : PatFrag<(ops node:$ptr), (i64 (zextloadi32 node:$ptr))>;
972 def extloadi8i1 : PatFrag<(ops node:$ptr), (i8 (extloadi1 node:$ptr))>;
973 def extloadi16i1 : PatFrag<(ops node:$ptr), (i16 (extloadi1 node:$ptr))>;
974 def extloadi32i1 : PatFrag<(ops node:$ptr), (i32 (extloadi1 node:$ptr))>;
975 def extloadi16i8 : PatFrag<(ops node:$ptr), (i16 (extloadi8 node:$ptr))>;
976 def extloadi32i8 : PatFrag<(ops node:$ptr), (i32 (extloadi8 node:$ptr))>;
977 def extloadi32i16 : PatFrag<(ops node:$ptr), (i32 (extloadi16 node:$ptr))>;
978 def extloadi64i1 : PatFrag<(ops node:$ptr), (i64 (extloadi1 node:$ptr))>;
979 def extloadi64i8 : PatFrag<(ops node:$ptr), (i64 (extloadi8 node:$ptr))>;
980 def extloadi64i16 : PatFrag<(ops node:$ptr), (i64 (extloadi16 node:$ptr))>;
981 def extloadi64i32 : PatFrag<(ops node:$ptr), (i64 (extloadi32 node:$ptr))>;
984 // An 'and' node with a single use.
985 def and_su : PatFrag<(ops node:$lhs, node:$rhs), (and node:$lhs, node:$rhs), [{
986 return N->hasOneUse();
988 // An 'srl' node with a single use.
989 def srl_su : PatFrag<(ops node:$lhs, node:$rhs), (srl node:$lhs, node:$rhs), [{
990 return N->hasOneUse();
992 // An 'trunc' node with a single use.
993 def trunc_su : PatFrag<(ops node:$src), (trunc node:$src), [{
994 return N->hasOneUse();
997 //===----------------------------------------------------------------------===//
1002 let hasSideEffects = 0, SchedRW = [WriteZero] in {
1003 def NOOP : I<0x90, RawFrm, (outs), (ins), "nop", [], IIC_NOP>;
1004 def NOOPW : I<0x1f, MRMXm, (outs), (ins i16mem:$zero),
1005 "nop{w}\t$zero", [], IIC_NOP>, TB, OpSize16;
1006 def NOOPL : I<0x1f, MRMXm, (outs), (ins i32mem:$zero),
1007 "nop{l}\t$zero", [], IIC_NOP>, TB, OpSize32;
1011 // Constructing a stack frame.
1012 def ENTER : Ii16<0xC8, RawFrmImm8, (outs), (ins i16imm:$len, i8imm:$lvl),
1013 "enter\t$len, $lvl", [], IIC_ENTER>, Sched<[WriteMicrocoded]>;
1015 let SchedRW = [WriteALU] in {
1016 let Defs = [EBP, ESP], Uses = [EBP, ESP], mayLoad = 1, hasSideEffects=0 in
1017 def LEAVE : I<0xC9, RawFrm,
1018 (outs), (ins), "leave", [], IIC_LEAVE>,
1019 Requires<[Not64BitMode]>;
1021 let Defs = [RBP,RSP], Uses = [RBP,RSP], mayLoad = 1, hasSideEffects = 0 in
1022 def LEAVE64 : I<0xC9, RawFrm,
1023 (outs), (ins), "leave", [], IIC_LEAVE>,
1024 Requires<[In64BitMode]>;
1027 //===----------------------------------------------------------------------===//
1028 // Miscellaneous Instructions.
1031 let Defs = [ESP], Uses = [ESP], hasSideEffects=0 in {
1032 let mayLoad = 1, SchedRW = [WriteLoad] in {
1033 def POP16r : I<0x58, AddRegFrm, (outs GR16:$reg), (ins), "pop{w}\t$reg", [],
1034 IIC_POP_REG16>, OpSize16;
1035 def POP32r : I<0x58, AddRegFrm, (outs GR32:$reg), (ins), "pop{l}\t$reg", [],
1036 IIC_POP_REG>, OpSize32, Requires<[Not64BitMode]>;
1037 def POP16rmr: I<0x8F, MRM0r, (outs GR16:$reg), (ins), "pop{w}\t$reg", [],
1038 IIC_POP_REG>, OpSize16;
1039 def POP16rmm: I<0x8F, MRM0m, (outs), (ins i16mem:$dst), "pop{w}\t$dst", [],
1040 IIC_POP_MEM>, OpSize16;
1041 def POP32rmr: I<0x8F, MRM0r, (outs GR32:$reg), (ins), "pop{l}\t$reg", [],
1042 IIC_POP_REG>, OpSize32, Requires<[Not64BitMode]>;
1043 def POP32rmm: I<0x8F, MRM0m, (outs), (ins i32mem:$dst), "pop{l}\t$dst", [],
1044 IIC_POP_MEM>, OpSize32, Requires<[Not64BitMode]>;
1045 } // mayLoad, SchedRW
1047 let mayStore = 1, SchedRW = [WriteStore] in {
1048 def PUSH16r : I<0x50, AddRegFrm, (outs), (ins GR16:$reg), "push{w}\t$reg",[],
1049 IIC_PUSH_REG>, OpSize16;
1050 def PUSH32r : I<0x50, AddRegFrm, (outs), (ins GR32:$reg), "push{l}\t$reg",[],
1051 IIC_PUSH_REG>, OpSize32, Requires<[Not64BitMode]>;
1052 def PUSH16rmr: I<0xFF, MRM6r, (outs), (ins GR16:$reg), "push{w}\t$reg",[],
1053 IIC_PUSH_REG>, OpSize16;
1054 def PUSH32rmr: I<0xFF, MRM6r, (outs), (ins GR32:$reg), "push{l}\t$reg",[],
1055 IIC_PUSH_REG>, OpSize32, Requires<[Not64BitMode]>;
1057 def PUSH16i8 : Ii8<0x6a, RawFrm, (outs), (ins i16i8imm:$imm),
1058 "push{w}\t$imm", [], IIC_PUSH_IMM>, OpSize16;
1059 def PUSHi16 : Ii16<0x68, RawFrm, (outs), (ins i16imm:$imm),
1060 "push{w}\t$imm", [], IIC_PUSH_IMM>, OpSize16;
1062 def PUSH32i8 : Ii8<0x6a, RawFrm, (outs), (ins i32i8imm:$imm),
1063 "push{l}\t$imm", [], IIC_PUSH_IMM>, OpSize32,
1064 Requires<[Not64BitMode]>;
1065 def PUSHi32 : Ii32<0x68, RawFrm, (outs), (ins i32imm:$imm),
1066 "push{l}\t$imm", [], IIC_PUSH_IMM>, OpSize32,
1067 Requires<[Not64BitMode]>;
1068 } // mayStore, SchedRW
1070 let mayLoad = 1, mayStore = 1, SchedRW = [WriteRMW] in {
1071 def PUSH16rmm: I<0xFF, MRM6m, (outs), (ins i16mem:$src), "push{w}\t$src",[],
1072 IIC_PUSH_MEM>, OpSize16;
1073 def PUSH32rmm: I<0xFF, MRM6m, (outs), (ins i32mem:$src), "push{l}\t$src",[],
1074 IIC_PUSH_MEM>, OpSize32, Requires<[Not64BitMode]>;
1075 } // mayLoad, mayStore, SchedRW
1079 let Defs = [ESP, EFLAGS], Uses = [ESP], mayLoad = 1, hasSideEffects=0,
1080 SchedRW = [WriteLoad] in {
1081 def POPF16 : I<0x9D, RawFrm, (outs), (ins), "popf{w}", [], IIC_POP_F>,
1083 def POPF32 : I<0x9D, RawFrm, (outs), (ins), "popf{l|d}", [], IIC_POP_FD>,
1084 OpSize32, Requires<[Not64BitMode]>;
1087 let Defs = [ESP], Uses = [ESP, EFLAGS], mayStore = 1, hasSideEffects=0,
1088 SchedRW = [WriteStore] in {
1089 def PUSHF16 : I<0x9C, RawFrm, (outs), (ins), "pushf{w}", [], IIC_PUSH_F>,
1091 def PUSHF32 : I<0x9C, RawFrm, (outs), (ins), "pushf{l|d}", [], IIC_PUSH_F>,
1092 OpSize32, Requires<[Not64BitMode]>;
1095 let Defs = [RSP], Uses = [RSP], hasSideEffects=0 in {
1096 let mayLoad = 1, SchedRW = [WriteLoad] in {
1097 def POP64r : I<0x58, AddRegFrm, (outs GR64:$reg), (ins), "pop{q}\t$reg", [],
1098 IIC_POP_REG>, OpSize32, Requires<[In64BitMode]>;
1099 def POP64rmr: I<0x8F, MRM0r, (outs GR64:$reg), (ins), "pop{q}\t$reg", [],
1100 IIC_POP_REG>, OpSize32, Requires<[In64BitMode]>;
1101 def POP64rmm: I<0x8F, MRM0m, (outs), (ins i64mem:$dst), "pop{q}\t$dst", [],
1102 IIC_POP_MEM>, OpSize32, Requires<[In64BitMode]>;
1103 } // mayLoad, SchedRW
1104 let mayStore = 1, SchedRW = [WriteStore] in {
1105 def PUSH64r : I<0x50, AddRegFrm, (outs), (ins GR64:$reg), "push{q}\t$reg", [],
1106 IIC_PUSH_REG>, OpSize32, Requires<[In64BitMode]>;
1107 def PUSH64rmr: I<0xFF, MRM6r, (outs), (ins GR64:$reg), "push{q}\t$reg", [],
1108 IIC_PUSH_REG>, OpSize32, Requires<[In64BitMode]>;
1109 } // mayStore, SchedRW
1110 let mayLoad = 1, mayStore = 1, SchedRW = [WriteRMW] in {
1111 def PUSH64rmm: I<0xFF, MRM6m, (outs), (ins i64mem:$src), "push{q}\t$src", [],
1112 IIC_PUSH_MEM>, OpSize32, Requires<[In64BitMode]>;
1113 } // mayLoad, mayStore, SchedRW
1116 let Defs = [RSP], Uses = [RSP], hasSideEffects = 0, mayStore = 1,
1117 SchedRW = [WriteStore] in {
1118 def PUSH64i8 : Ii8<0x6a, RawFrm, (outs), (ins i64i8imm:$imm),
1119 "push{q}\t$imm", [], IIC_PUSH_IMM>, Requires<[In64BitMode]>;
1120 def PUSH64i32 : Ii32S<0x68, RawFrm, (outs), (ins i64i32imm:$imm),
1121 "push{q}\t$imm", [], IIC_PUSH_IMM>, OpSize32,
1122 Requires<[In64BitMode]>;
1125 let Defs = [RSP, EFLAGS], Uses = [RSP], mayLoad = 1, hasSideEffects=0 in
1126 def POPF64 : I<0x9D, RawFrm, (outs), (ins), "popfq", [], IIC_POP_FD>,
1127 OpSize32, Requires<[In64BitMode]>, Sched<[WriteLoad]>;
1128 let Defs = [RSP], Uses = [RSP, EFLAGS], mayStore = 1, hasSideEffects=0 in
1129 def PUSHF64 : I<0x9C, RawFrm, (outs), (ins), "pushfq", [], IIC_PUSH_F>,
1130 OpSize32, Requires<[In64BitMode]>, Sched<[WriteStore]>;
1132 let Defs = [EDI, ESI, EBP, EBX, EDX, ECX, EAX, ESP], Uses = [ESP],
1133 mayLoad = 1, hasSideEffects = 0, SchedRW = [WriteLoad] in {
1134 def POPA32 : I<0x61, RawFrm, (outs), (ins), "popal", [], IIC_POP_A>,
1135 OpSize32, Requires<[Not64BitMode]>;
1136 def POPA16 : I<0x61, RawFrm, (outs), (ins), "popaw", [], IIC_POP_A>,
1137 OpSize16, Requires<[Not64BitMode]>;
1139 let Defs = [ESP], Uses = [EDI, ESI, EBP, EBX, EDX, ECX, EAX, ESP],
1140 mayStore = 1, hasSideEffects = 0, SchedRW = [WriteStore] in {
1141 def PUSHA32 : I<0x60, RawFrm, (outs), (ins), "pushal", [], IIC_PUSH_A>,
1142 OpSize32, Requires<[Not64BitMode]>;
1143 def PUSHA16 : I<0x60, RawFrm, (outs), (ins), "pushaw", [], IIC_PUSH_A>,
1144 OpSize16, Requires<[Not64BitMode]>;
1147 let Constraints = "$src = $dst", SchedRW = [WriteALU] in {
1148 // GR32 = bswap GR32
1149 def BSWAP32r : I<0xC8, AddRegFrm,
1150 (outs GR32:$dst), (ins GR32:$src),
1152 [(set GR32:$dst, (bswap GR32:$src))], IIC_BSWAP>, OpSize32, TB;
1154 def BSWAP64r : RI<0xC8, AddRegFrm, (outs GR64:$dst), (ins GR64:$src),
1156 [(set GR64:$dst, (bswap GR64:$src))], IIC_BSWAP>, TB;
1157 } // Constraints = "$src = $dst", SchedRW
1159 // Bit scan instructions.
1160 let Defs = [EFLAGS] in {
1161 def BSF16rr : I<0xBC, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
1162 "bsf{w}\t{$src, $dst|$dst, $src}",
1163 [(set GR16:$dst, EFLAGS, (X86bsf GR16:$src))],
1164 IIC_BIT_SCAN_REG>, PS, OpSize16, Sched<[WriteShift]>;
1165 def BSF16rm : I<0xBC, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
1166 "bsf{w}\t{$src, $dst|$dst, $src}",
1167 [(set GR16:$dst, EFLAGS, (X86bsf (loadi16 addr:$src)))],
1168 IIC_BIT_SCAN_MEM>, PS, OpSize16, Sched<[WriteShiftLd]>;
1169 def BSF32rr : I<0xBC, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
1170 "bsf{l}\t{$src, $dst|$dst, $src}",
1171 [(set GR32:$dst, EFLAGS, (X86bsf GR32:$src))],
1172 IIC_BIT_SCAN_REG>, PS, OpSize32, Sched<[WriteShift]>;
1173 def BSF32rm : I<0xBC, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
1174 "bsf{l}\t{$src, $dst|$dst, $src}",
1175 [(set GR32:$dst, EFLAGS, (X86bsf (loadi32 addr:$src)))],
1176 IIC_BIT_SCAN_MEM>, PS, OpSize32, Sched<[WriteShiftLd]>;
1177 def BSF64rr : RI<0xBC, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
1178 "bsf{q}\t{$src, $dst|$dst, $src}",
1179 [(set GR64:$dst, EFLAGS, (X86bsf GR64:$src))],
1180 IIC_BIT_SCAN_REG>, PS, Sched<[WriteShift]>;
1181 def BSF64rm : RI<0xBC, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
1182 "bsf{q}\t{$src, $dst|$dst, $src}",
1183 [(set GR64:$dst, EFLAGS, (X86bsf (loadi64 addr:$src)))],
1184 IIC_BIT_SCAN_MEM>, PS, Sched<[WriteShiftLd]>;
1186 def BSR16rr : I<0xBD, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
1187 "bsr{w}\t{$src, $dst|$dst, $src}",
1188 [(set GR16:$dst, EFLAGS, (X86bsr GR16:$src))],
1189 IIC_BIT_SCAN_REG>, PS, OpSize16, Sched<[WriteShift]>;
1190 def BSR16rm : I<0xBD, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
1191 "bsr{w}\t{$src, $dst|$dst, $src}",
1192 [(set GR16:$dst, EFLAGS, (X86bsr (loadi16 addr:$src)))],
1193 IIC_BIT_SCAN_MEM>, PS, OpSize16, Sched<[WriteShiftLd]>;
1194 def BSR32rr : I<0xBD, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
1195 "bsr{l}\t{$src, $dst|$dst, $src}",
1196 [(set GR32:$dst, EFLAGS, (X86bsr GR32:$src))],
1197 IIC_BIT_SCAN_REG>, PS, OpSize32, Sched<[WriteShift]>;
1198 def BSR32rm : I<0xBD, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
1199 "bsr{l}\t{$src, $dst|$dst, $src}",
1200 [(set GR32:$dst, EFLAGS, (X86bsr (loadi32 addr:$src)))],
1201 IIC_BIT_SCAN_MEM>, PS, OpSize32, Sched<[WriteShiftLd]>;
1202 def BSR64rr : RI<0xBD, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
1203 "bsr{q}\t{$src, $dst|$dst, $src}",
1204 [(set GR64:$dst, EFLAGS, (X86bsr GR64:$src))],
1205 IIC_BIT_SCAN_REG>, PS, Sched<[WriteShift]>;
1206 def BSR64rm : RI<0xBD, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
1207 "bsr{q}\t{$src, $dst|$dst, $src}",
1208 [(set GR64:$dst, EFLAGS, (X86bsr (loadi64 addr:$src)))],
1209 IIC_BIT_SCAN_MEM>, PS, Sched<[WriteShiftLd]>;
1210 } // Defs = [EFLAGS]
1212 let SchedRW = [WriteMicrocoded] in {
1213 // These uses the DF flag in the EFLAGS register to inc or dec EDI and ESI
1214 let Defs = [EDI,ESI], Uses = [EDI,ESI,EFLAGS] in {
1215 def MOVSB : I<0xA4, RawFrmDstSrc, (outs dstidx8:$dst), (ins srcidx8:$src),
1216 "movsb\t{$src, $dst|$dst, $src}", [], IIC_MOVS>;
1217 def MOVSW : I<0xA5, RawFrmDstSrc, (outs dstidx16:$dst), (ins srcidx16:$src),
1218 "movsw\t{$src, $dst|$dst, $src}", [], IIC_MOVS>, OpSize16;
1219 def MOVSL : I<0xA5, RawFrmDstSrc, (outs dstidx32:$dst), (ins srcidx32:$src),
1220 "movs{l|d}\t{$src, $dst|$dst, $src}", [], IIC_MOVS>, OpSize32;
1221 def MOVSQ : RI<0xA5, RawFrmDstSrc, (outs dstidx64:$dst), (ins srcidx64:$src),
1222 "movsq\t{$src, $dst|$dst, $src}", [], IIC_MOVS>;
1225 // These uses the DF flag in the EFLAGS register to inc or dec EDI and ESI
1226 let Defs = [EDI], Uses = [AL,EDI,EFLAGS] in
1227 def STOSB : I<0xAA, RawFrmDst, (outs dstidx8:$dst), (ins),
1228 "stosb\t{%al, $dst|$dst, al}", [], IIC_STOS>;
1229 let Defs = [EDI], Uses = [AX,EDI,EFLAGS] in
1230 def STOSW : I<0xAB, RawFrmDst, (outs dstidx16:$dst), (ins),
1231 "stosw\t{%ax, $dst|$dst, ax}", [], IIC_STOS>, OpSize16;
1232 let Defs = [EDI], Uses = [EAX,EDI,EFLAGS] in
1233 def STOSL : I<0xAB, RawFrmDst, (outs dstidx32:$dst), (ins),
1234 "stos{l|d}\t{%eax, $dst|$dst, eax}", [], IIC_STOS>, OpSize32;
1235 let Defs = [RCX,RDI], Uses = [RAX,RCX,RDI,EFLAGS] in
1236 def STOSQ : RI<0xAB, RawFrmDst, (outs dstidx64:$dst), (ins),
1237 "stosq\t{%rax, $dst|$dst, rax}", [], IIC_STOS>;
1239 // These uses the DF flag in the EFLAGS register to inc or dec EDI and ESI
1240 let Defs = [EDI,EFLAGS], Uses = [AL,EDI,EFLAGS] in
1241 def SCASB : I<0xAE, RawFrmDst, (outs), (ins dstidx8:$dst),
1242 "scasb\t{$dst, %al|al, $dst}", [], IIC_SCAS>;
1243 let Defs = [EDI,EFLAGS], Uses = [AX,EDI,EFLAGS] in
1244 def SCASW : I<0xAF, RawFrmDst, (outs), (ins dstidx16:$dst),
1245 "scasw\t{$dst, %ax|ax, $dst}", [], IIC_SCAS>, OpSize16;
1246 let Defs = [EDI,EFLAGS], Uses = [EAX,EDI,EFLAGS] in
1247 def SCASL : I<0xAF, RawFrmDst, (outs), (ins dstidx32:$dst),
1248 "scas{l|d}\t{$dst, %eax|eax, $dst}", [], IIC_SCAS>, OpSize32;
1249 let Defs = [EDI,EFLAGS], Uses = [RAX,EDI,EFLAGS] in
1250 def SCASQ : RI<0xAF, RawFrmDst, (outs), (ins dstidx64:$dst),
1251 "scasq\t{$dst, %rax|rax, $dst}", [], IIC_SCAS>;
1253 // These uses the DF flag in the EFLAGS register to inc or dec EDI and ESI
1254 let Defs = [EDI,ESI,EFLAGS], Uses = [EDI,ESI,EFLAGS] in {
1255 def CMPSB : I<0xA6, RawFrmDstSrc, (outs), (ins dstidx8:$dst, srcidx8:$src),
1256 "cmpsb\t{$dst, $src|$src, $dst}", [], IIC_CMPS>;
1257 def CMPSW : I<0xA7, RawFrmDstSrc, (outs), (ins dstidx16:$dst, srcidx16:$src),
1258 "cmpsw\t{$dst, $src|$src, $dst}", [], IIC_CMPS>, OpSize16;
1259 def CMPSL : I<0xA7, RawFrmDstSrc, (outs), (ins dstidx32:$dst, srcidx32:$src),
1260 "cmps{l|d}\t{$dst, $src|$src, $dst}", [], IIC_CMPS>, OpSize32;
1261 def CMPSQ : RI<0xA7, RawFrmDstSrc, (outs), (ins dstidx64:$dst, srcidx64:$src),
1262 "cmpsq\t{$dst, $src|$src, $dst}", [], IIC_CMPS>;
1266 //===----------------------------------------------------------------------===//
1267 // Move Instructions.
1269 let SchedRW = [WriteMove] in {
1270 let hasSideEffects = 0 in {
1271 def MOV8rr : I<0x88, MRMDestReg, (outs GR8 :$dst), (ins GR8 :$src),
1272 "mov{b}\t{$src, $dst|$dst, $src}", [], IIC_MOV>;
1273 def MOV16rr : I<0x89, MRMDestReg, (outs GR16:$dst), (ins GR16:$src),
1274 "mov{w}\t{$src, $dst|$dst, $src}", [], IIC_MOV>, OpSize16;
1275 def MOV32rr : I<0x89, MRMDestReg, (outs GR32:$dst), (ins GR32:$src),
1276 "mov{l}\t{$src, $dst|$dst, $src}", [], IIC_MOV>, OpSize32;
1277 def MOV64rr : RI<0x89, MRMDestReg, (outs GR64:$dst), (ins GR64:$src),
1278 "mov{q}\t{$src, $dst|$dst, $src}", [], IIC_MOV>;
1281 let isReMaterializable = 1, isAsCheapAsAMove = 1 in {
1282 def MOV8ri : Ii8 <0xB0, AddRegFrm, (outs GR8 :$dst), (ins i8imm :$src),
1283 "mov{b}\t{$src, $dst|$dst, $src}",
1284 [(set GR8:$dst, imm:$src)], IIC_MOV>;
1285 def MOV16ri : Ii16<0xB8, AddRegFrm, (outs GR16:$dst), (ins i16imm:$src),
1286 "mov{w}\t{$src, $dst|$dst, $src}",
1287 [(set GR16:$dst, imm:$src)], IIC_MOV>, OpSize16;
1288 def MOV32ri : Ii32<0xB8, AddRegFrm, (outs GR32:$dst), (ins i32imm:$src),
1289 "mov{l}\t{$src, $dst|$dst, $src}",
1290 [(set GR32:$dst, imm:$src)], IIC_MOV>, OpSize32;
1291 def MOV64ri32 : RIi32S<0xC7, MRM0r, (outs GR64:$dst), (ins i64i32imm:$src),
1292 "mov{q}\t{$src, $dst|$dst, $src}",
1293 [(set GR64:$dst, i64immSExt32:$src)], IIC_MOV>;
1295 let isReMaterializable = 1 in {
1296 def MOV64ri : RIi64<0xB8, AddRegFrm, (outs GR64:$dst), (ins i64imm:$src),
1297 "movabs{q}\t{$src, $dst|$dst, $src}",
1298 [(set GR64:$dst, imm:$src)], IIC_MOV>;
1301 // Longer forms that use a ModR/M byte. Needed for disassembler
1302 let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0 in {
1303 def MOV8ri_alt : Ii8 <0xC6, MRM0r, (outs GR8 :$dst), (ins i8imm :$src),
1304 "mov{b}\t{$src, $dst|$dst, $src}", [], IIC_MOV>;
1305 def MOV16ri_alt : Ii16<0xC7, MRM0r, (outs GR16:$dst), (ins i16imm:$src),
1306 "mov{w}\t{$src, $dst|$dst, $src}", [], IIC_MOV>, OpSize16;
1307 def MOV32ri_alt : Ii32<0xC7, MRM0r, (outs GR32:$dst), (ins i32imm:$src),
1308 "mov{l}\t{$src, $dst|$dst, $src}", [], IIC_MOV>, OpSize32;
1312 let SchedRW = [WriteStore] in {
1313 def MOV8mi : Ii8 <0xC6, MRM0m, (outs), (ins i8mem :$dst, i8imm :$src),
1314 "mov{b}\t{$src, $dst|$dst, $src}",
1315 [(store (i8 imm8_su:$src), addr:$dst)], IIC_MOV_MEM>;
1316 def MOV16mi : Ii16<0xC7, MRM0m, (outs), (ins i16mem:$dst, i16imm:$src),
1317 "mov{w}\t{$src, $dst|$dst, $src}",
1318 [(store (i16 imm16_su:$src), addr:$dst)], IIC_MOV_MEM>, OpSize16;
1319 def MOV32mi : Ii32<0xC7, MRM0m, (outs), (ins i32mem:$dst, i32imm:$src),
1320 "mov{l}\t{$src, $dst|$dst, $src}",
1321 [(store (i32 imm32_su:$src), addr:$dst)], IIC_MOV_MEM>, OpSize32;
1322 def MOV64mi32 : RIi32S<0xC7, MRM0m, (outs), (ins i64mem:$dst, i64i32imm:$src),
1323 "mov{q}\t{$src, $dst|$dst, $src}",
1324 [(store i64immSExt32:$src, addr:$dst)], IIC_MOV_MEM>;
1327 let hasSideEffects = 0 in {
1329 /// Memory offset versions of moves. The immediate is an address mode sized
1330 /// offset from the segment base.
1331 let SchedRW = [WriteALU] in {
1332 let mayLoad = 1 in {
1334 def MOV8ao32 : Ii32<0xA0, RawFrmMemOffs, (outs), (ins offset32_8:$src),
1335 "mov{b}\t{$src, %al|al, $src}", [], IIC_MOV_MEM>,
1338 def MOV16ao32 : Ii32<0xA1, RawFrmMemOffs, (outs), (ins offset32_16:$src),
1339 "mov{w}\t{$src, %ax|ax, $src}", [], IIC_MOV_MEM>,
1342 def MOV32ao32 : Ii32<0xA1, RawFrmMemOffs, (outs), (ins offset32_32:$src),
1343 "mov{l}\t{$src, %eax|eax, $src}", [], IIC_MOV_MEM>,
1346 def MOV64ao32 : RIi32<0xA1, RawFrmMemOffs, (outs), (ins offset32_64:$src),
1347 "mov{q}\t{$src, %rax|rax, $src}", [], IIC_MOV_MEM>,
1351 def MOV8ao16 : Ii16<0xA0, RawFrmMemOffs, (outs), (ins offset16_8:$src),
1352 "mov{b}\t{$src, %al|al, $src}", [], IIC_MOV_MEM>, AdSize16;
1354 def MOV16ao16 : Ii16<0xA1, RawFrmMemOffs, (outs), (ins offset16_16:$src),
1355 "mov{w}\t{$src, %ax|ax, $src}", [], IIC_MOV_MEM>,
1358 def MOV32ao16 : Ii16<0xA1, RawFrmMemOffs, (outs), (ins offset16_32:$src),
1359 "mov{l}\t{$src, %eax|eax, $src}", [], IIC_MOV_MEM>,
1362 let mayStore = 1 in {
1364 def MOV8o32a : Ii32<0xA2, RawFrmMemOffs, (outs offset32_8:$dst), (ins),
1365 "mov{b}\t{%al, $dst|$dst, al}", [], IIC_MOV_MEM>, AdSize32;
1367 def MOV16o32a : Ii32<0xA3, RawFrmMemOffs, (outs offset32_16:$dst), (ins),
1368 "mov{w}\t{%ax, $dst|$dst, ax}", [], IIC_MOV_MEM>,
1371 def MOV32o32a : Ii32<0xA3, RawFrmMemOffs, (outs offset32_32:$dst), (ins),
1372 "mov{l}\t{%eax, $dst|$dst, eax}", [], IIC_MOV_MEM>,
1375 def MOV64o32a : RIi32<0xA3, RawFrmMemOffs, (outs offset32_64:$dst), (ins),
1376 "mov{q}\t{%rax, $dst|$dst, rax}", [], IIC_MOV_MEM>,
1380 def MOV8o16a : Ii16<0xA2, RawFrmMemOffs, (outs offset16_8:$dst), (ins),
1381 "mov{b}\t{%al, $dst|$dst, al}", [], IIC_MOV_MEM>, AdSize16;
1383 def MOV16o16a : Ii16<0xA3, RawFrmMemOffs, (outs offset16_16:$dst), (ins),
1384 "mov{w}\t{%ax, $dst|$dst, ax}", [], IIC_MOV_MEM>,
1387 def MOV32o16a : Ii16<0xA3, RawFrmMemOffs, (outs offset16_32:$dst), (ins),
1388 "mov{l}\t{%eax, $dst|$dst, eax}", [], IIC_MOV_MEM>,
1393 // These forms all have full 64-bit absolute addresses in their instructions
1394 // and use the movabs mnemonic to indicate this specific form.
1395 let mayLoad = 1 in {
1397 def MOV8ao64 : RIi64_NOREX<0xA0, RawFrmMemOffs, (outs), (ins offset64_8:$src),
1398 "movabs{b}\t{$src, %al|al, $src}", []>, AdSize64;
1400 def MOV16ao64 : RIi64_NOREX<0xA1, RawFrmMemOffs, (outs), (ins offset64_16:$src),
1401 "movabs{w}\t{$src, %ax|ax, $src}", []>, OpSize16, AdSize64;
1403 def MOV32ao64 : RIi64_NOREX<0xA1, RawFrmMemOffs, (outs), (ins offset64_32:$src),
1404 "movabs{l}\t{$src, %eax|eax, $src}", []>, OpSize32,
1407 def MOV64ao64 : RIi64<0xA1, RawFrmMemOffs, (outs), (ins offset64_64:$src),
1408 "movabs{q}\t{$src, %rax|rax, $src}", []>, AdSize64;
1411 let mayStore = 1 in {
1413 def MOV8o64a : RIi64_NOREX<0xA2, RawFrmMemOffs, (outs offset64_8:$dst), (ins),
1414 "movabs{b}\t{%al, $dst|$dst, al}", []>, AdSize64;
1416 def MOV16o64a : RIi64_NOREX<0xA3, RawFrmMemOffs, (outs offset64_16:$dst), (ins),
1417 "movabs{w}\t{%ax, $dst|$dst, ax}", []>, OpSize16, AdSize64;
1419 def MOV32o64a : RIi64_NOREX<0xA3, RawFrmMemOffs, (outs offset64_32:$dst), (ins),
1420 "movabs{l}\t{%eax, $dst|$dst, eax}", []>, OpSize32,
1423 def MOV64o64a : RIi64<0xA3, RawFrmMemOffs, (outs offset64_64:$dst), (ins),
1424 "movabs{q}\t{%rax, $dst|$dst, rax}", []>, AdSize64;
1426 } // hasSideEffects = 0
1428 let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0,
1429 SchedRW = [WriteMove] in {
1430 def MOV8rr_REV : I<0x8A, MRMSrcReg, (outs GR8:$dst), (ins GR8:$src),
1431 "mov{b}\t{$src, $dst|$dst, $src}", [], IIC_MOV>;
1432 def MOV16rr_REV : I<0x8B, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
1433 "mov{w}\t{$src, $dst|$dst, $src}", [], IIC_MOV>, OpSize16;
1434 def MOV32rr_REV : I<0x8B, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
1435 "mov{l}\t{$src, $dst|$dst, $src}", [], IIC_MOV>, OpSize32;
1436 def MOV64rr_REV : RI<0x8B, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
1437 "mov{q}\t{$src, $dst|$dst, $src}", [], IIC_MOV>;
1440 let canFoldAsLoad = 1, isReMaterializable = 1, SchedRW = [WriteLoad] in {
1441 def MOV8rm : I<0x8A, MRMSrcMem, (outs GR8 :$dst), (ins i8mem :$src),
1442 "mov{b}\t{$src, $dst|$dst, $src}",
1443 [(set GR8:$dst, (loadi8 addr:$src))], IIC_MOV_MEM>;
1444 def MOV16rm : I<0x8B, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
1445 "mov{w}\t{$src, $dst|$dst, $src}",
1446 [(set GR16:$dst, (loadi16 addr:$src))], IIC_MOV_MEM>, OpSize16;
1447 def MOV32rm : I<0x8B, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
1448 "mov{l}\t{$src, $dst|$dst, $src}",
1449 [(set GR32:$dst, (loadi32 addr:$src))], IIC_MOV_MEM>, OpSize32;
1450 def MOV64rm : RI<0x8B, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
1451 "mov{q}\t{$src, $dst|$dst, $src}",
1452 [(set GR64:$dst, (load addr:$src))], IIC_MOV_MEM>;
1455 let SchedRW = [WriteStore] in {
1456 def MOV8mr : I<0x88, MRMDestMem, (outs), (ins i8mem :$dst, GR8 :$src),
1457 "mov{b}\t{$src, $dst|$dst, $src}",
1458 [(store GR8:$src, addr:$dst)], IIC_MOV_MEM>;
1459 def MOV16mr : I<0x89, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src),
1460 "mov{w}\t{$src, $dst|$dst, $src}",
1461 [(store GR16:$src, addr:$dst)], IIC_MOV_MEM>, OpSize16;
1462 def MOV32mr : I<0x89, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
1463 "mov{l}\t{$src, $dst|$dst, $src}",
1464 [(store GR32:$src, addr:$dst)], IIC_MOV_MEM>, OpSize32;
1465 def MOV64mr : RI<0x89, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
1466 "mov{q}\t{$src, $dst|$dst, $src}",
1467 [(store GR64:$src, addr:$dst)], IIC_MOV_MEM>;
1470 // Versions of MOV8rr, MOV8mr, and MOV8rm that use i8mem_NOREX and GR8_NOREX so
1471 // that they can be used for copying and storing h registers, which can't be
1472 // encoded when a REX prefix is present.
1473 let isCodeGenOnly = 1 in {
1474 let hasSideEffects = 0 in
1475 def MOV8rr_NOREX : I<0x88, MRMDestReg,
1476 (outs GR8_NOREX:$dst), (ins GR8_NOREX:$src),
1477 "mov{b}\t{$src, $dst|$dst, $src} # NOREX", [], IIC_MOV>,
1479 let mayStore = 1, hasSideEffects = 0 in
1480 def MOV8mr_NOREX : I<0x88, MRMDestMem,
1481 (outs), (ins i8mem_NOREX:$dst, GR8_NOREX:$src),
1482 "mov{b}\t{$src, $dst|$dst, $src} # NOREX", [],
1483 IIC_MOV_MEM>, Sched<[WriteStore]>;
1484 let mayLoad = 1, hasSideEffects = 0,
1485 canFoldAsLoad = 1, isReMaterializable = 1 in
1486 def MOV8rm_NOREX : I<0x8A, MRMSrcMem,
1487 (outs GR8_NOREX:$dst), (ins i8mem_NOREX:$src),
1488 "mov{b}\t{$src, $dst|$dst, $src} # NOREX", [],
1489 IIC_MOV_MEM>, Sched<[WriteLoad]>;
1493 // Condition code ops, incl. set if equal/not equal/...
1494 let SchedRW = [WriteALU] in {
1495 let Defs = [EFLAGS], Uses = [AH] in
1496 def SAHF : I<0x9E, RawFrm, (outs), (ins), "sahf",
1497 [(set EFLAGS, (X86sahf AH))], IIC_AHF>;
1498 let Defs = [AH], Uses = [EFLAGS], hasSideEffects = 0 in
1499 def LAHF : I<0x9F, RawFrm, (outs), (ins), "lahf", [],
1500 IIC_AHF>; // AH = flags
1503 //===----------------------------------------------------------------------===//
1504 // Bit tests instructions: BT, BTS, BTR, BTC.
1506 let Defs = [EFLAGS] in {
1507 let SchedRW = [WriteALU] in {
1508 def BT16rr : I<0xA3, MRMDestReg, (outs), (ins GR16:$src1, GR16:$src2),
1509 "bt{w}\t{$src2, $src1|$src1, $src2}",
1510 [(set EFLAGS, (X86bt GR16:$src1, GR16:$src2))], IIC_BT_RR>,
1512 def BT32rr : I<0xA3, MRMDestReg, (outs), (ins GR32:$src1, GR32:$src2),
1513 "bt{l}\t{$src2, $src1|$src1, $src2}",
1514 [(set EFLAGS, (X86bt GR32:$src1, GR32:$src2))], IIC_BT_RR>,
1516 def BT64rr : RI<0xA3, MRMDestReg, (outs), (ins GR64:$src1, GR64:$src2),
1517 "bt{q}\t{$src2, $src1|$src1, $src2}",
1518 [(set EFLAGS, (X86bt GR64:$src1, GR64:$src2))], IIC_BT_RR>, TB;
1521 // Unlike with the register+register form, the memory+register form of the
1522 // bt instruction does not ignore the high bits of the index. From ISel's
1523 // perspective, this is pretty bizarre. Make these instructions disassembly
1526 let mayLoad = 1, hasSideEffects = 0, SchedRW = [WriteALULd] in {
1527 def BT16mr : I<0xA3, MRMDestMem, (outs), (ins i16mem:$src1, GR16:$src2),
1528 "bt{w}\t{$src2, $src1|$src1, $src2}",
1529 // [(X86bt (loadi16 addr:$src1), GR16:$src2),
1530 // (implicit EFLAGS)]
1532 >, OpSize16, TB, Requires<[FastBTMem]>;
1533 def BT32mr : I<0xA3, MRMDestMem, (outs), (ins i32mem:$src1, GR32:$src2),
1534 "bt{l}\t{$src2, $src1|$src1, $src2}",
1535 // [(X86bt (loadi32 addr:$src1), GR32:$src2),
1536 // (implicit EFLAGS)]
1538 >, OpSize32, TB, Requires<[FastBTMem]>;
1539 def BT64mr : RI<0xA3, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2),
1540 "bt{q}\t{$src2, $src1|$src1, $src2}",
1541 // [(X86bt (loadi64 addr:$src1), GR64:$src2),
1542 // (implicit EFLAGS)]
1547 let SchedRW = [WriteALU] in {
1548 def BT16ri8 : Ii8<0xBA, MRM4r, (outs), (ins GR16:$src1, i16i8imm:$src2),
1549 "bt{w}\t{$src2, $src1|$src1, $src2}",
1550 [(set EFLAGS, (X86bt GR16:$src1, i16immSExt8:$src2))],
1551 IIC_BT_RI>, OpSize16, TB;
1552 def BT32ri8 : Ii8<0xBA, MRM4r, (outs), (ins GR32:$src1, i32i8imm:$src2),
1553 "bt{l}\t{$src2, $src1|$src1, $src2}",
1554 [(set EFLAGS, (X86bt GR32:$src1, i32immSExt8:$src2))],
1555 IIC_BT_RI>, OpSize32, TB;
1556 def BT64ri8 : RIi8<0xBA, MRM4r, (outs), (ins GR64:$src1, i64i8imm:$src2),
1557 "bt{q}\t{$src2, $src1|$src1, $src2}",
1558 [(set EFLAGS, (X86bt GR64:$src1, i64immSExt8:$src2))],
1562 // Note that these instructions don't need FastBTMem because that
1563 // only applies when the other operand is in a register. When it's
1564 // an immediate, bt is still fast.
1565 let SchedRW = [WriteALU] in {
1566 def BT16mi8 : Ii8<0xBA, MRM4m, (outs), (ins i16mem:$src1, i16i8imm:$src2),
1567 "bt{w}\t{$src2, $src1|$src1, $src2}",
1568 [(set EFLAGS, (X86bt (loadi16 addr:$src1), i16immSExt8:$src2))
1569 ], IIC_BT_MI>, OpSize16, TB;
1570 def BT32mi8 : Ii8<0xBA, MRM4m, (outs), (ins i32mem:$src1, i32i8imm:$src2),
1571 "bt{l}\t{$src2, $src1|$src1, $src2}",
1572 [(set EFLAGS, (X86bt (loadi32 addr:$src1), i32immSExt8:$src2))
1573 ], IIC_BT_MI>, OpSize32, TB;
1574 def BT64mi8 : RIi8<0xBA, MRM4m, (outs), (ins i64mem:$src1, i64i8imm:$src2),
1575 "bt{q}\t{$src2, $src1|$src1, $src2}",
1576 [(set EFLAGS, (X86bt (loadi64 addr:$src1),
1577 i64immSExt8:$src2))], IIC_BT_MI>, TB;
1580 let hasSideEffects = 0 in {
1581 let SchedRW = [WriteALU] in {
1582 def BTC16rr : I<0xBB, MRMDestReg, (outs), (ins GR16:$src1, GR16:$src2),
1583 "btc{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>,
1585 def BTC32rr : I<0xBB, MRMDestReg, (outs), (ins GR32:$src1, GR32:$src2),
1586 "btc{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>,
1588 def BTC64rr : RI<0xBB, MRMDestReg, (outs), (ins GR64:$src1, GR64:$src2),
1589 "btc{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>, TB;
1592 let mayLoad = 1, mayStore = 1, SchedRW = [WriteALULd, WriteRMW] in {
1593 def BTC16mr : I<0xBB, MRMDestMem, (outs), (ins i16mem:$src1, GR16:$src2),
1594 "btc{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>,
1596 def BTC32mr : I<0xBB, MRMDestMem, (outs), (ins i32mem:$src1, GR32:$src2),
1597 "btc{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>,
1599 def BTC64mr : RI<0xBB, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2),
1600 "btc{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>, TB;
1603 let SchedRW = [WriteALU] in {
1604 def BTC16ri8 : Ii8<0xBA, MRM7r, (outs), (ins GR16:$src1, i16i8imm:$src2),
1605 "btc{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>,
1607 def BTC32ri8 : Ii8<0xBA, MRM7r, (outs), (ins GR32:$src1, i32i8imm:$src2),
1608 "btc{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>,
1610 def BTC64ri8 : RIi8<0xBA, MRM7r, (outs), (ins GR64:$src1, i64i8imm:$src2),
1611 "btc{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>, TB;
1614 let mayLoad = 1, mayStore = 1, SchedRW = [WriteALULd, WriteRMW] in {
1615 def BTC16mi8 : Ii8<0xBA, MRM7m, (outs), (ins i16mem:$src1, i16i8imm:$src2),
1616 "btc{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>,
1618 def BTC32mi8 : Ii8<0xBA, MRM7m, (outs), (ins i32mem:$src1, i32i8imm:$src2),
1619 "btc{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>,
1621 def BTC64mi8 : RIi8<0xBA, MRM7m, (outs), (ins i64mem:$src1, i64i8imm:$src2),
1622 "btc{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>, TB;
1625 let SchedRW = [WriteALU] in {
1626 def BTR16rr : I<0xB3, MRMDestReg, (outs), (ins GR16:$src1, GR16:$src2),
1627 "btr{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>,
1629 def BTR32rr : I<0xB3, MRMDestReg, (outs), (ins GR32:$src1, GR32:$src2),
1630 "btr{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>,
1632 def BTR64rr : RI<0xB3, MRMDestReg, (outs), (ins GR64:$src1, GR64:$src2),
1633 "btr{q}\t{$src2, $src1|$src1, $src2}", []>, TB;
1636 let mayLoad = 1, mayStore = 1, SchedRW = [WriteALULd, WriteRMW] in {
1637 def BTR16mr : I<0xB3, MRMDestMem, (outs), (ins i16mem:$src1, GR16:$src2),
1638 "btr{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>,
1640 def BTR32mr : I<0xB3, MRMDestMem, (outs), (ins i32mem:$src1, GR32:$src2),
1641 "btr{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>,
1643 def BTR64mr : RI<0xB3, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2),
1644 "btr{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>, TB;
1647 let SchedRW = [WriteALU] in {
1648 def BTR16ri8 : Ii8<0xBA, MRM6r, (outs), (ins GR16:$src1, i16i8imm:$src2),
1649 "btr{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>,
1651 def BTR32ri8 : Ii8<0xBA, MRM6r, (outs), (ins GR32:$src1, i32i8imm:$src2),
1652 "btr{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>,
1654 def BTR64ri8 : RIi8<0xBA, MRM6r, (outs), (ins GR64:$src1, i64i8imm:$src2),
1655 "btr{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>, TB;
1658 let mayLoad = 1, mayStore = 1, SchedRW = [WriteALULd, WriteRMW] in {
1659 def BTR16mi8 : Ii8<0xBA, MRM6m, (outs), (ins i16mem:$src1, i16i8imm:$src2),
1660 "btr{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>,
1662 def BTR32mi8 : Ii8<0xBA, MRM6m, (outs), (ins i32mem:$src1, i32i8imm:$src2),
1663 "btr{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>,
1665 def BTR64mi8 : RIi8<0xBA, MRM6m, (outs), (ins i64mem:$src1, i64i8imm:$src2),
1666 "btr{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>, TB;
1669 let SchedRW = [WriteALU] in {
1670 def BTS16rr : I<0xAB, MRMDestReg, (outs), (ins GR16:$src1, GR16:$src2),
1671 "bts{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>,
1673 def BTS32rr : I<0xAB, MRMDestReg, (outs), (ins GR32:$src1, GR32:$src2),
1674 "bts{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>,
1676 def BTS64rr : RI<0xAB, MRMDestReg, (outs), (ins GR64:$src1, GR64:$src2),
1677 "bts{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>, TB;
1680 let mayLoad = 1, mayStore = 1, SchedRW = [WriteALULd, WriteRMW] in {
1681 def BTS16mr : I<0xAB, MRMDestMem, (outs), (ins i16mem:$src1, GR16:$src2),
1682 "bts{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>,
1684 def BTS32mr : I<0xAB, MRMDestMem, (outs), (ins i32mem:$src1, GR32:$src2),
1685 "bts{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>,
1687 def BTS64mr : RI<0xAB, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2),
1688 "bts{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>, TB;
1691 let SchedRW = [WriteALU] in {
1692 def BTS16ri8 : Ii8<0xBA, MRM5r, (outs), (ins GR16:$src1, i16i8imm:$src2),
1693 "bts{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>,
1695 def BTS32ri8 : Ii8<0xBA, MRM5r, (outs), (ins GR32:$src1, i32i8imm:$src2),
1696 "bts{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>,
1698 def BTS64ri8 : RIi8<0xBA, MRM5r, (outs), (ins GR64:$src1, i64i8imm:$src2),
1699 "bts{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>, TB;
1702 let mayLoad = 1, mayStore = 1, SchedRW = [WriteALULd, WriteRMW] in {
1703 def BTS16mi8 : Ii8<0xBA, MRM5m, (outs), (ins i16mem:$src1, i16i8imm:$src2),
1704 "bts{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>,
1706 def BTS32mi8 : Ii8<0xBA, MRM5m, (outs), (ins i32mem:$src1, i32i8imm:$src2),
1707 "bts{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>,
1709 def BTS64mi8 : RIi8<0xBA, MRM5m, (outs), (ins i64mem:$src1, i64i8imm:$src2),
1710 "bts{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>, TB;
1712 } // hasSideEffects = 0
1713 } // Defs = [EFLAGS]
1716 //===----------------------------------------------------------------------===//
1720 // Atomic swap. These are just normal xchg instructions. But since a memory
1721 // operand is referenced, the atomicity is ensured.
1722 multiclass ATOMIC_SWAP<bits<8> opc8, bits<8> opc, string mnemonic, string frag,
1723 InstrItinClass itin> {
1724 let Constraints = "$val = $dst", SchedRW = [WriteALULd, WriteRMW] in {
1725 def NAME#8rm : I<opc8, MRMSrcMem, (outs GR8:$dst),
1726 (ins GR8:$val, i8mem:$ptr),
1727 !strconcat(mnemonic, "{b}\t{$val, $ptr|$ptr, $val}"),
1730 (!cast<PatFrag>(frag # "_8") addr:$ptr, GR8:$val))],
1732 def NAME#16rm : I<opc, MRMSrcMem, (outs GR16:$dst),
1733 (ins GR16:$val, i16mem:$ptr),
1734 !strconcat(mnemonic, "{w}\t{$val, $ptr|$ptr, $val}"),
1737 (!cast<PatFrag>(frag # "_16") addr:$ptr, GR16:$val))],
1739 def NAME#32rm : I<opc, MRMSrcMem, (outs GR32:$dst),
1740 (ins GR32:$val, i32mem:$ptr),
1741 !strconcat(mnemonic, "{l}\t{$val, $ptr|$ptr, $val}"),
1744 (!cast<PatFrag>(frag # "_32") addr:$ptr, GR32:$val))],
1746 def NAME#64rm : RI<opc, MRMSrcMem, (outs GR64:$dst),
1747 (ins GR64:$val, i64mem:$ptr),
1748 !strconcat(mnemonic, "{q}\t{$val, $ptr|$ptr, $val}"),
1751 (!cast<PatFrag>(frag # "_64") addr:$ptr, GR64:$val))],
1756 defm XCHG : ATOMIC_SWAP<0x86, 0x87, "xchg", "atomic_swap", IIC_XCHG_MEM>;
1758 // Swap between registers.
1759 let SchedRW = [WriteALU] in {
1760 let Constraints = "$val = $dst" in {
1761 def XCHG8rr : I<0x86, MRMSrcReg, (outs GR8:$dst), (ins GR8:$val, GR8:$src),
1762 "xchg{b}\t{$val, $src|$src, $val}", [], IIC_XCHG_REG>;
1763 def XCHG16rr : I<0x87, MRMSrcReg, (outs GR16:$dst), (ins GR16:$val, GR16:$src),
1764 "xchg{w}\t{$val, $src|$src, $val}", [], IIC_XCHG_REG>,
1766 def XCHG32rr : I<0x87, MRMSrcReg, (outs GR32:$dst), (ins GR32:$val, GR32:$src),
1767 "xchg{l}\t{$val, $src|$src, $val}", [], IIC_XCHG_REG>,
1769 def XCHG64rr : RI<0x87, MRMSrcReg, (outs GR64:$dst), (ins GR64:$val,GR64:$src),
1770 "xchg{q}\t{$val, $src|$src, $val}", [], IIC_XCHG_REG>;
1773 // Swap between EAX and other registers.
1774 let Uses = [AX], Defs = [AX] in
1775 def XCHG16ar : I<0x90, AddRegFrm, (outs), (ins GR16:$src),
1776 "xchg{w}\t{$src, %ax|ax, $src}", [], IIC_XCHG_REG>, OpSize16;
1777 let Uses = [EAX], Defs = [EAX] in
1778 def XCHG32ar : I<0x90, AddRegFrm, (outs), (ins GR32:$src),
1779 "xchg{l}\t{$src, %eax|eax, $src}", [], IIC_XCHG_REG>,
1780 OpSize32, Requires<[Not64BitMode]>;
1781 let Uses = [EAX], Defs = [EAX] in
1782 // Uses GR32_NOAX in 64-bit mode to prevent encoding using the 0x90 NOP encoding.
1783 // xchg %eax, %eax needs to clear upper 32-bits of RAX so is not a NOP.
1784 def XCHG32ar64 : I<0x90, AddRegFrm, (outs), (ins GR32_NOAX:$src),
1785 "xchg{l}\t{$src, %eax|eax, $src}", [], IIC_XCHG_REG>,
1786 OpSize32, Requires<[In64BitMode]>;
1787 let Uses = [RAX], Defs = [RAX] in
1788 def XCHG64ar : RI<0x90, AddRegFrm, (outs), (ins GR64:$src),
1789 "xchg{q}\t{$src, %rax|rax, $src}", [], IIC_XCHG_REG>;
1792 let SchedRW = [WriteALU] in {
1793 def XADD8rr : I<0xC0, MRMDestReg, (outs GR8:$dst), (ins GR8:$src),
1794 "xadd{b}\t{$src, $dst|$dst, $src}", [], IIC_XADD_REG>, TB;
1795 def XADD16rr : I<0xC1, MRMDestReg, (outs GR16:$dst), (ins GR16:$src),
1796 "xadd{w}\t{$src, $dst|$dst, $src}", [], IIC_XADD_REG>, TB,
1798 def XADD32rr : I<0xC1, MRMDestReg, (outs GR32:$dst), (ins GR32:$src),
1799 "xadd{l}\t{$src, $dst|$dst, $src}", [], IIC_XADD_REG>, TB,
1801 def XADD64rr : RI<0xC1, MRMDestReg, (outs GR64:$dst), (ins GR64:$src),
1802 "xadd{q}\t{$src, $dst|$dst, $src}", [], IIC_XADD_REG>, TB;
1805 let mayLoad = 1, mayStore = 1, SchedRW = [WriteALULd, WriteRMW] in {
1806 def XADD8rm : I<0xC0, MRMDestMem, (outs), (ins i8mem:$dst, GR8:$src),
1807 "xadd{b}\t{$src, $dst|$dst, $src}", [], IIC_XADD_MEM>, TB;
1808 def XADD16rm : I<0xC1, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src),
1809 "xadd{w}\t{$src, $dst|$dst, $src}", [], IIC_XADD_MEM>, TB,
1811 def XADD32rm : I<0xC1, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
1812 "xadd{l}\t{$src, $dst|$dst, $src}", [], IIC_XADD_MEM>, TB,
1814 def XADD64rm : RI<0xC1, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
1815 "xadd{q}\t{$src, $dst|$dst, $src}", [], IIC_XADD_MEM>, TB;
1819 let SchedRW = [WriteALU] in {
1820 def CMPXCHG8rr : I<0xB0, MRMDestReg, (outs GR8:$dst), (ins GR8:$src),
1821 "cmpxchg{b}\t{$src, $dst|$dst, $src}", [],
1822 IIC_CMPXCHG_REG8>, TB;
1823 def CMPXCHG16rr : I<0xB1, MRMDestReg, (outs GR16:$dst), (ins GR16:$src),
1824 "cmpxchg{w}\t{$src, $dst|$dst, $src}", [],
1825 IIC_CMPXCHG_REG>, TB, OpSize16;
1826 def CMPXCHG32rr : I<0xB1, MRMDestReg, (outs GR32:$dst), (ins GR32:$src),
1827 "cmpxchg{l}\t{$src, $dst|$dst, $src}", [],
1828 IIC_CMPXCHG_REG>, TB, OpSize32;
1829 def CMPXCHG64rr : RI<0xB1, MRMDestReg, (outs GR64:$dst), (ins GR64:$src),
1830 "cmpxchg{q}\t{$src, $dst|$dst, $src}", [],
1831 IIC_CMPXCHG_REG>, TB;
1834 let SchedRW = [WriteALULd, WriteRMW] in {
1835 let mayLoad = 1, mayStore = 1 in {
1836 def CMPXCHG8rm : I<0xB0, MRMDestMem, (outs), (ins i8mem:$dst, GR8:$src),
1837 "cmpxchg{b}\t{$src, $dst|$dst, $src}", [],
1838 IIC_CMPXCHG_MEM8>, TB;
1839 def CMPXCHG16rm : I<0xB1, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src),
1840 "cmpxchg{w}\t{$src, $dst|$dst, $src}", [],
1841 IIC_CMPXCHG_MEM>, TB, OpSize16;
1842 def CMPXCHG32rm : I<0xB1, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
1843 "cmpxchg{l}\t{$src, $dst|$dst, $src}", [],
1844 IIC_CMPXCHG_MEM>, TB, OpSize32;
1845 def CMPXCHG64rm : RI<0xB1, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
1846 "cmpxchg{q}\t{$src, $dst|$dst, $src}", [],
1847 IIC_CMPXCHG_MEM>, TB;
1850 let Defs = [EAX, EDX, EFLAGS], Uses = [EAX, EBX, ECX, EDX] in
1851 def CMPXCHG8B : I<0xC7, MRM1m, (outs), (ins i64mem:$dst),
1852 "cmpxchg8b\t$dst", [], IIC_CMPXCHG_8B>, TB;
1854 let Defs = [RAX, RDX, EFLAGS], Uses = [RAX, RBX, RCX, RDX] in
1855 def CMPXCHG16B : RI<0xC7, MRM1m, (outs), (ins i128mem:$dst),
1856 "cmpxchg16b\t$dst", [], IIC_CMPXCHG_16B>,
1857 TB, Requires<[HasCmpxchg16b]>;
1861 // Lock instruction prefix
1862 def LOCK_PREFIX : I<0xF0, RawFrm, (outs), (ins), "lock", []>;
1864 // Rex64 instruction prefix
1865 def REX64_PREFIX : I<0x48, RawFrm, (outs), (ins), "rex64", []>,
1866 Requires<[In64BitMode]>;
1868 // Data16 instruction prefix
1869 def DATA16_PREFIX : I<0x66, RawFrm, (outs), (ins), "data16", []>;
1871 // Repeat string operation instruction prefixes
1872 // These uses the DF flag in the EFLAGS register to inc or dec ECX
1873 let Defs = [ECX], Uses = [ECX,EFLAGS] in {
1874 // Repeat (used with INS, OUTS, MOVS, LODS and STOS)
1875 def REP_PREFIX : I<0xF3, RawFrm, (outs), (ins), "rep", []>;
1876 // Repeat while not equal (used with CMPS and SCAS)
1877 def REPNE_PREFIX : I<0xF2, RawFrm, (outs), (ins), "repne", []>;
1881 // String manipulation instructions
1882 let SchedRW = [WriteMicrocoded] in {
1883 // These uses the DF flag in the EFLAGS register to inc or dec EDI and ESI
1884 let Defs = [AL,ESI], Uses = [ESI,EFLAGS] in
1885 def LODSB : I<0xAC, RawFrmSrc, (outs), (ins srcidx8:$src),
1886 "lodsb\t{$src, %al|al, $src}", [], IIC_LODS>;
1887 let Defs = [AX,ESI], Uses = [ESI,EFLAGS] in
1888 def LODSW : I<0xAD, RawFrmSrc, (outs), (ins srcidx16:$src),
1889 "lodsw\t{$src, %ax|ax, $src}", [], IIC_LODS>, OpSize16;
1890 let Defs = [EAX,ESI], Uses = [ESI,EFLAGS] in
1891 def LODSL : I<0xAD, RawFrmSrc, (outs), (ins srcidx32:$src),
1892 "lods{l|d}\t{$src, %eax|eax, $src}", [], IIC_LODS>, OpSize32;
1893 let Defs = [RAX,ESI], Uses = [ESI,EFLAGS] in
1894 def LODSQ : RI<0xAD, RawFrmSrc, (outs), (ins srcidx64:$src),
1895 "lodsq\t{$src, %rax|rax, $src}", [], IIC_LODS>;
1898 let SchedRW = [WriteSystem] in {
1899 // These uses the DF flag in the EFLAGS register to inc or dec EDI and ESI
1900 let Defs = [ESI], Uses = [DX,ESI,EFLAGS] in {
1901 def OUTSB : I<0x6E, RawFrmSrc, (outs), (ins srcidx8:$src),
1902 "outsb\t{$src, %dx|dx, $src}", [], IIC_OUTS>;
1903 def OUTSW : I<0x6F, RawFrmSrc, (outs), (ins srcidx16:$src),
1904 "outsw\t{$src, %dx|dx, $src}", [], IIC_OUTS>, OpSize16;
1905 def OUTSL : I<0x6F, RawFrmSrc, (outs), (ins srcidx32:$src),
1906 "outs{l|d}\t{$src, %dx|dx, $src}", [], IIC_OUTS>, OpSize32;
1909 // These uses the DF flag in the EFLAGS register to inc or dec EDI and ESI
1910 let Defs = [EDI], Uses = [DX,EDI,EFLAGS] in {
1911 def INSB : I<0x6C, RawFrmDst, (outs dstidx8:$dst), (ins),
1912 "insb\t{%dx, $dst|$dst, dx}", [], IIC_INS>;
1913 def INSW : I<0x6D, RawFrmDst, (outs dstidx16:$dst), (ins),
1914 "insw\t{%dx, $dst|$dst, dx}", [], IIC_INS>, OpSize16;
1915 def INSL : I<0x6D, RawFrmDst, (outs dstidx32:$dst), (ins),
1916 "ins{l|d}\t{%dx, $dst|$dst, dx}", [], IIC_INS>, OpSize32;
1920 // Flag instructions
1921 let SchedRW = [WriteALU] in {
1922 def CLC : I<0xF8, RawFrm, (outs), (ins), "clc", [], IIC_CLC>;
1923 def STC : I<0xF9, RawFrm, (outs), (ins), "stc", [], IIC_STC>;
1924 def CLI : I<0xFA, RawFrm, (outs), (ins), "cli", [], IIC_CLI>;
1925 def STI : I<0xFB, RawFrm, (outs), (ins), "sti", [], IIC_STI>;
1926 def CLD : I<0xFC, RawFrm, (outs), (ins), "cld", [], IIC_CLD>;
1927 def STD : I<0xFD, RawFrm, (outs), (ins), "std", [], IIC_STD>;
1928 def CMC : I<0xF5, RawFrm, (outs), (ins), "cmc", [], IIC_CMC>;
1930 def CLTS : I<0x06, RawFrm, (outs), (ins), "clts", [], IIC_CLTS>, TB;
1933 // Table lookup instructions
1934 def XLAT : I<0xD7, RawFrm, (outs), (ins), "xlatb", [], IIC_XLAT>,
1937 let SchedRW = [WriteMicrocoded] in {
1938 // ASCII Adjust After Addition
1939 // sets AL, AH and CF and AF of EFLAGS and uses AL and AF of EFLAGS
1940 def AAA : I<0x37, RawFrm, (outs), (ins), "aaa", [], IIC_AAA>,
1941 Requires<[Not64BitMode]>;
1943 // ASCII Adjust AX Before Division
1944 // sets AL, AH and EFLAGS and uses AL and AH
1945 def AAD8i8 : Ii8<0xD5, RawFrm, (outs), (ins i8imm:$src),
1946 "aad\t$src", [], IIC_AAD>, Requires<[Not64BitMode]>;
1948 // ASCII Adjust AX After Multiply
1949 // sets AL, AH and EFLAGS and uses AL
1950 def AAM8i8 : Ii8<0xD4, RawFrm, (outs), (ins i8imm:$src),
1951 "aam\t$src", [], IIC_AAM>, Requires<[Not64BitMode]>;
1953 // ASCII Adjust AL After Subtraction - sets
1954 // sets AL, AH and CF and AF of EFLAGS and uses AL and AF of EFLAGS
1955 def AAS : I<0x3F, RawFrm, (outs), (ins), "aas", [], IIC_AAS>,
1956 Requires<[Not64BitMode]>;
1958 // Decimal Adjust AL after Addition
1959 // sets AL, CF and AF of EFLAGS and uses AL, CF and AF of EFLAGS
1960 def DAA : I<0x27, RawFrm, (outs), (ins), "daa", [], IIC_DAA>,
1961 Requires<[Not64BitMode]>;
1963 // Decimal Adjust AL after Subtraction
1964 // sets AL, CF and AF of EFLAGS and uses AL, CF and AF of EFLAGS
1965 def DAS : I<0x2F, RawFrm, (outs), (ins), "das", [], IIC_DAS>,
1966 Requires<[Not64BitMode]>;
1969 let SchedRW = [WriteSystem] in {
1970 // Check Array Index Against Bounds
1971 def BOUNDS16rm : I<0x62, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
1972 "bound\t{$src, $dst|$dst, $src}", [], IIC_BOUND>, OpSize16,
1973 Requires<[Not64BitMode]>;
1974 def BOUNDS32rm : I<0x62, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
1975 "bound\t{$src, $dst|$dst, $src}", [], IIC_BOUND>, OpSize32,
1976 Requires<[Not64BitMode]>;
1978 // Adjust RPL Field of Segment Selector
1979 def ARPL16rr : I<0x63, MRMDestReg, (outs GR16:$dst), (ins GR16:$src),
1980 "arpl\t{$src, $dst|$dst, $src}", [], IIC_ARPL_REG>,
1981 Requires<[Not64BitMode]>;
1982 def ARPL16mr : I<0x63, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src),
1983 "arpl\t{$src, $dst|$dst, $src}", [], IIC_ARPL_MEM>,
1984 Requires<[Not64BitMode]>;
1987 //===----------------------------------------------------------------------===//
1988 // MOVBE Instructions
1990 let Predicates = [HasMOVBE] in {
1991 let SchedRW = [WriteALULd] in {
1992 def MOVBE16rm : I<0xF0, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
1993 "movbe{w}\t{$src, $dst|$dst, $src}",
1994 [(set GR16:$dst, (bswap (loadi16 addr:$src)))], IIC_MOVBE>,
1996 def MOVBE32rm : I<0xF0, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
1997 "movbe{l}\t{$src, $dst|$dst, $src}",
1998 [(set GR32:$dst, (bswap (loadi32 addr:$src)))], IIC_MOVBE>,
2000 def MOVBE64rm : RI<0xF0, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
2001 "movbe{q}\t{$src, $dst|$dst, $src}",
2002 [(set GR64:$dst, (bswap (loadi64 addr:$src)))], IIC_MOVBE>,
2005 let SchedRW = [WriteStore] in {
2006 def MOVBE16mr : I<0xF1, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src),
2007 "movbe{w}\t{$src, $dst|$dst, $src}",
2008 [(store (bswap GR16:$src), addr:$dst)], IIC_MOVBE>,
2010 def MOVBE32mr : I<0xF1, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
2011 "movbe{l}\t{$src, $dst|$dst, $src}",
2012 [(store (bswap GR32:$src), addr:$dst)], IIC_MOVBE>,
2014 def MOVBE64mr : RI<0xF1, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
2015 "movbe{q}\t{$src, $dst|$dst, $src}",
2016 [(store (bswap GR64:$src), addr:$dst)], IIC_MOVBE>,
2021 //===----------------------------------------------------------------------===//
2022 // RDRAND Instruction
2024 let Predicates = [HasRDRAND], Defs = [EFLAGS] in {
2025 def RDRAND16r : I<0xC7, MRM6r, (outs GR16:$dst), (ins),
2027 [(set GR16:$dst, EFLAGS, (X86rdrand))]>, OpSize16, TB;
2028 def RDRAND32r : I<0xC7, MRM6r, (outs GR32:$dst), (ins),
2030 [(set GR32:$dst, EFLAGS, (X86rdrand))]>, OpSize32, TB;
2031 def RDRAND64r : RI<0xC7, MRM6r, (outs GR64:$dst), (ins),
2033 [(set GR64:$dst, EFLAGS, (X86rdrand))]>, TB;
2036 //===----------------------------------------------------------------------===//
2037 // RDSEED Instruction
2039 let Predicates = [HasRDSEED], Defs = [EFLAGS] in {
2040 def RDSEED16r : I<0xC7, MRM7r, (outs GR16:$dst), (ins),
2042 [(set GR16:$dst, EFLAGS, (X86rdseed))]>, OpSize16, TB;
2043 def RDSEED32r : I<0xC7, MRM7r, (outs GR32:$dst), (ins),
2045 [(set GR32:$dst, EFLAGS, (X86rdseed))]>, OpSize32, TB;
2046 def RDSEED64r : RI<0xC7, MRM7r, (outs GR64:$dst), (ins),
2048 [(set GR64:$dst, EFLAGS, (X86rdseed))]>, TB;
2051 //===----------------------------------------------------------------------===//
2052 // LZCNT Instruction
2054 let Predicates = [HasLZCNT], Defs = [EFLAGS] in {
2055 def LZCNT16rr : I<0xBD, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
2056 "lzcnt{w}\t{$src, $dst|$dst, $src}",
2057 [(set GR16:$dst, (ctlz GR16:$src)), (implicit EFLAGS)]>, XS,
2059 def LZCNT16rm : I<0xBD, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
2060 "lzcnt{w}\t{$src, $dst|$dst, $src}",
2061 [(set GR16:$dst, (ctlz (loadi16 addr:$src))),
2062 (implicit EFLAGS)]>, XS, OpSize16;
2064 def LZCNT32rr : I<0xBD, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
2065 "lzcnt{l}\t{$src, $dst|$dst, $src}",
2066 [(set GR32:$dst, (ctlz GR32:$src)), (implicit EFLAGS)]>, XS,
2068 def LZCNT32rm : I<0xBD, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
2069 "lzcnt{l}\t{$src, $dst|$dst, $src}",
2070 [(set GR32:$dst, (ctlz (loadi32 addr:$src))),
2071 (implicit EFLAGS)]>, XS, OpSize32;
2073 def LZCNT64rr : RI<0xBD, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
2074 "lzcnt{q}\t{$src, $dst|$dst, $src}",
2075 [(set GR64:$dst, (ctlz GR64:$src)), (implicit EFLAGS)]>,
2077 def LZCNT64rm : RI<0xBD, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
2078 "lzcnt{q}\t{$src, $dst|$dst, $src}",
2079 [(set GR64:$dst, (ctlz (loadi64 addr:$src))),
2080 (implicit EFLAGS)]>, XS;
2083 let Predicates = [HasLZCNT] in {
2084 def : Pat<(X86cmov (ctlz GR16:$src), (i16 16), (X86_COND_E_OR_NE),
2085 (X86cmp GR16:$src, (i16 0))),
2086 (LZCNT16rr GR16:$src)>;
2087 def : Pat<(X86cmov (ctlz GR32:$src), (i32 32), (X86_COND_E_OR_NE),
2088 (X86cmp GR32:$src, (i32 0))),
2089 (LZCNT32rr GR32:$src)>;
2090 def : Pat<(X86cmov (ctlz GR64:$src), (i64 64), (X86_COND_E_OR_NE),
2091 (X86cmp GR64:$src, (i64 0))),
2092 (LZCNT64rr GR64:$src)>;
2093 def : Pat<(X86cmov (i16 16), (ctlz GR16:$src), (X86_COND_E_OR_NE),
2094 (X86cmp GR16:$src, (i16 0))),
2095 (LZCNT16rr GR16:$src)>;
2096 def : Pat<(X86cmov (i32 32), (ctlz GR32:$src), (X86_COND_E_OR_NE),
2097 (X86cmp GR32:$src, (i32 0))),
2098 (LZCNT32rr GR32:$src)>;
2099 def : Pat<(X86cmov (i64 64), (ctlz GR64:$src), (X86_COND_E_OR_NE),
2100 (X86cmp GR64:$src, (i64 0))),
2101 (LZCNT64rr GR64:$src)>;
2103 def : Pat<(X86cmov (ctlz (loadi16 addr:$src)), (i16 16), (X86_COND_E_OR_NE),
2104 (X86cmp (loadi16 addr:$src), (i16 0))),
2105 (LZCNT16rm addr:$src)>;
2106 def : Pat<(X86cmov (ctlz (loadi32 addr:$src)), (i32 32), (X86_COND_E_OR_NE),
2107 (X86cmp (loadi32 addr:$src), (i32 0))),
2108 (LZCNT32rm addr:$src)>;
2109 def : Pat<(X86cmov (ctlz (loadi64 addr:$src)), (i64 64), (X86_COND_E_OR_NE),
2110 (X86cmp (loadi64 addr:$src), (i64 0))),
2111 (LZCNT64rm addr:$src)>;
2112 def : Pat<(X86cmov (i16 16), (ctlz (loadi16 addr:$src)), (X86_COND_E_OR_NE),
2113 (X86cmp (loadi16 addr:$src), (i16 0))),
2114 (LZCNT16rm addr:$src)>;
2115 def : Pat<(X86cmov (i32 32), (ctlz (loadi32 addr:$src)), (X86_COND_E_OR_NE),
2116 (X86cmp (loadi32 addr:$src), (i32 0))),
2117 (LZCNT32rm addr:$src)>;
2118 def : Pat<(X86cmov (i64 64), (ctlz (loadi64 addr:$src)), (X86_COND_E_OR_NE),
2119 (X86cmp (loadi64 addr:$src), (i64 0))),
2120 (LZCNT64rm addr:$src)>;
2123 //===----------------------------------------------------------------------===//
2126 let Predicates = [HasBMI], Defs = [EFLAGS] in {
2127 def TZCNT16rr : I<0xBC, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
2128 "tzcnt{w}\t{$src, $dst|$dst, $src}",
2129 [(set GR16:$dst, (cttz GR16:$src)), (implicit EFLAGS)]>, XS,
2131 def TZCNT16rm : I<0xBC, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
2132 "tzcnt{w}\t{$src, $dst|$dst, $src}",
2133 [(set GR16:$dst, (cttz (loadi16 addr:$src))),
2134 (implicit EFLAGS)]>, XS, OpSize16;
2136 def TZCNT32rr : I<0xBC, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
2137 "tzcnt{l}\t{$src, $dst|$dst, $src}",
2138 [(set GR32:$dst, (cttz GR32:$src)), (implicit EFLAGS)]>, XS,
2140 def TZCNT32rm : I<0xBC, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
2141 "tzcnt{l}\t{$src, $dst|$dst, $src}",
2142 [(set GR32:$dst, (cttz (loadi32 addr:$src))),
2143 (implicit EFLAGS)]>, XS, OpSize32;
2145 def TZCNT64rr : RI<0xBC, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
2146 "tzcnt{q}\t{$src, $dst|$dst, $src}",
2147 [(set GR64:$dst, (cttz GR64:$src)), (implicit EFLAGS)]>,
2149 def TZCNT64rm : RI<0xBC, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
2150 "tzcnt{q}\t{$src, $dst|$dst, $src}",
2151 [(set GR64:$dst, (cttz (loadi64 addr:$src))),
2152 (implicit EFLAGS)]>, XS;
2155 multiclass bmi_bls<string mnemonic, Format RegMRM, Format MemMRM,
2156 RegisterClass RC, X86MemOperand x86memop> {
2157 let hasSideEffects = 0 in {
2158 def rr : I<0xF3, RegMRM, (outs RC:$dst), (ins RC:$src),
2159 !strconcat(mnemonic, "\t{$src, $dst|$dst, $src}"),
2162 def rm : I<0xF3, MemMRM, (outs RC:$dst), (ins x86memop:$src),
2163 !strconcat(mnemonic, "\t{$src, $dst|$dst, $src}"),
2168 let Predicates = [HasBMI], Defs = [EFLAGS] in {
2169 defm BLSR32 : bmi_bls<"blsr{l}", MRM1r, MRM1m, GR32, i32mem>;
2170 defm BLSR64 : bmi_bls<"blsr{q}", MRM1r, MRM1m, GR64, i64mem>, VEX_W;
2171 defm BLSMSK32 : bmi_bls<"blsmsk{l}", MRM2r, MRM2m, GR32, i32mem>;
2172 defm BLSMSK64 : bmi_bls<"blsmsk{q}", MRM2r, MRM2m, GR64, i64mem>, VEX_W;
2173 defm BLSI32 : bmi_bls<"blsi{l}", MRM3r, MRM3m, GR32, i32mem>;
2174 defm BLSI64 : bmi_bls<"blsi{q}", MRM3r, MRM3m, GR64, i64mem>, VEX_W;
2177 //===----------------------------------------------------------------------===//
2178 // Pattern fragments to auto generate BMI instructions.
2179 //===----------------------------------------------------------------------===//
2181 let Predicates = [HasBMI] in {
2182 // FIXME: patterns for the load versions are not implemented
2183 def : Pat<(and GR32:$src, (add GR32:$src, -1)),
2184 (BLSR32rr GR32:$src)>;
2185 def : Pat<(and GR64:$src, (add GR64:$src, -1)),
2186 (BLSR64rr GR64:$src)>;
2188 def : Pat<(xor GR32:$src, (add GR32:$src, -1)),
2189 (BLSMSK32rr GR32:$src)>;
2190 def : Pat<(xor GR64:$src, (add GR64:$src, -1)),
2191 (BLSMSK64rr GR64:$src)>;
2193 def : Pat<(and GR32:$src, (ineg GR32:$src)),
2194 (BLSI32rr GR32:$src)>;
2195 def : Pat<(and GR64:$src, (ineg GR64:$src)),
2196 (BLSI64rr GR64:$src)>;
2199 let Predicates = [HasBMI] in {
2200 def : Pat<(X86cmov (cttz GR16:$src), (i16 16), (X86_COND_E_OR_NE),
2201 (X86cmp GR16:$src, (i16 0))),
2202 (TZCNT16rr GR16:$src)>;
2203 def : Pat<(X86cmov (cttz GR32:$src), (i32 32), (X86_COND_E_OR_NE),
2204 (X86cmp GR32:$src, (i32 0))),
2205 (TZCNT32rr GR32:$src)>;
2206 def : Pat<(X86cmov (cttz GR64:$src), (i64 64), (X86_COND_E_OR_NE),
2207 (X86cmp GR64:$src, (i64 0))),
2208 (TZCNT64rr GR64:$src)>;
2209 def : Pat<(X86cmov (i16 16), (cttz GR16:$src), (X86_COND_E_OR_NE),
2210 (X86cmp GR16:$src, (i16 0))),
2211 (TZCNT16rr GR16:$src)>;
2212 def : Pat<(X86cmov (i32 32), (cttz GR32:$src), (X86_COND_E_OR_NE),
2213 (X86cmp GR32:$src, (i32 0))),
2214 (TZCNT32rr GR32:$src)>;
2215 def : Pat<(X86cmov (i64 64), (cttz GR64:$src), (X86_COND_E_OR_NE),
2216 (X86cmp GR64:$src, (i64 0))),
2217 (TZCNT64rr GR64:$src)>;
2219 def : Pat<(X86cmov (cttz (loadi16 addr:$src)), (i16 16), (X86_COND_E_OR_NE),
2220 (X86cmp (loadi16 addr:$src), (i16 0))),
2221 (TZCNT16rm addr:$src)>;
2222 def : Pat<(X86cmov (cttz (loadi32 addr:$src)), (i32 32), (X86_COND_E_OR_NE),
2223 (X86cmp (loadi32 addr:$src), (i32 0))),
2224 (TZCNT32rm addr:$src)>;
2225 def : Pat<(X86cmov (cttz (loadi64 addr:$src)), (i64 64), (X86_COND_E_OR_NE),
2226 (X86cmp (loadi64 addr:$src), (i64 0))),
2227 (TZCNT64rm addr:$src)>;
2228 def : Pat<(X86cmov (i16 16), (cttz (loadi16 addr:$src)), (X86_COND_E_OR_NE),
2229 (X86cmp (loadi16 addr:$src), (i16 0))),
2230 (TZCNT16rm addr:$src)>;
2231 def : Pat<(X86cmov (i32 32), (cttz (loadi32 addr:$src)), (X86_COND_E_OR_NE),
2232 (X86cmp (loadi32 addr:$src), (i32 0))),
2233 (TZCNT32rm addr:$src)>;
2234 def : Pat<(X86cmov (i64 64), (cttz (loadi64 addr:$src)), (X86_COND_E_OR_NE),
2235 (X86cmp (loadi64 addr:$src), (i64 0))),
2236 (TZCNT64rm addr:$src)>;
2240 multiclass bmi_bextr_bzhi<bits<8> opc, string mnemonic, RegisterClass RC,
2241 X86MemOperand x86memop, Intrinsic Int,
2243 def rr : I<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
2244 !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2245 [(set RC:$dst, (Int RC:$src1, RC:$src2)), (implicit EFLAGS)]>,
2247 def rm : I<opc, MRMSrcMem, (outs RC:$dst), (ins x86memop:$src1, RC:$src2),
2248 !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2249 [(set RC:$dst, (Int (ld_frag addr:$src1), RC:$src2)),
2250 (implicit EFLAGS)]>, T8PS, VEX_4VOp3;
2253 let Predicates = [HasBMI], Defs = [EFLAGS] in {
2254 defm BEXTR32 : bmi_bextr_bzhi<0xF7, "bextr{l}", GR32, i32mem,
2255 int_x86_bmi_bextr_32, loadi32>;
2256 defm BEXTR64 : bmi_bextr_bzhi<0xF7, "bextr{q}", GR64, i64mem,
2257 int_x86_bmi_bextr_64, loadi64>, VEX_W;
2260 let Predicates = [HasBMI2], Defs = [EFLAGS] in {
2261 defm BZHI32 : bmi_bextr_bzhi<0xF5, "bzhi{l}", GR32, i32mem,
2262 int_x86_bmi_bzhi_32, loadi32>;
2263 defm BZHI64 : bmi_bextr_bzhi<0xF5, "bzhi{q}", GR64, i64mem,
2264 int_x86_bmi_bzhi_64, loadi64>, VEX_W;
2268 def CountTrailingOnes : SDNodeXForm<imm, [{
2269 // Count the trailing ones in the immediate.
2270 return getI8Imm(countTrailingOnes(N->getZExtValue()), SDLoc(N));
2273 def BZHIMask : ImmLeaf<i64, [{
2274 return isMask_64(Imm) && (countTrailingOnes<uint64_t>(Imm) > 32);
2277 let Predicates = [HasBMI2] in {
2278 def : Pat<(and GR64:$src, BZHIMask:$mask),
2279 (BZHI64rr GR64:$src,
2280 (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
2281 (MOV8ri (CountTrailingOnes imm:$mask)), sub_8bit))>;
2283 def : Pat<(and GR32:$src, (add (shl 1, GR8:$lz), -1)),
2284 (BZHI32rr GR32:$src,
2285 (INSERT_SUBREG (i32 (IMPLICIT_DEF)), GR8:$lz, sub_8bit))>;
2287 def : Pat<(and (loadi32 addr:$src), (add (shl 1, GR8:$lz), -1)),
2288 (BZHI32rm addr:$src,
2289 (INSERT_SUBREG (i32 (IMPLICIT_DEF)), GR8:$lz, sub_8bit))>;
2291 def : Pat<(and GR64:$src, (add (shl 1, GR8:$lz), -1)),
2292 (BZHI64rr GR64:$src,
2293 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR8:$lz, sub_8bit))>;
2295 def : Pat<(and (loadi64 addr:$src), (add (shl 1, GR8:$lz), -1)),
2296 (BZHI64rm addr:$src,
2297 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR8:$lz, sub_8bit))>;
2300 let Predicates = [HasBMI] in {
2301 def : Pat<(X86bextr GR32:$src1, GR32:$src2),
2302 (BEXTR32rr GR32:$src1, GR32:$src2)>;
2303 def : Pat<(X86bextr (loadi32 addr:$src1), GR32:$src2),
2304 (BEXTR32rm addr:$src1, GR32:$src2)>;
2305 def : Pat<(X86bextr GR64:$src1, GR64:$src2),
2306 (BEXTR64rr GR64:$src1, GR64:$src2)>;
2307 def : Pat<(X86bextr (loadi64 addr:$src1), GR64:$src2),
2308 (BEXTR64rm addr:$src1, GR64:$src2)>;
2311 multiclass bmi_pdep_pext<string mnemonic, RegisterClass RC,
2312 X86MemOperand x86memop, Intrinsic Int,
2314 def rr : I<0xF5, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
2315 !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2316 [(set RC:$dst, (Int RC:$src1, RC:$src2))]>,
2318 def rm : I<0xF5, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
2319 !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2320 [(set RC:$dst, (Int RC:$src1, (ld_frag addr:$src2)))]>, VEX_4V;
2323 let Predicates = [HasBMI2] in {
2324 defm PDEP32 : bmi_pdep_pext<"pdep{l}", GR32, i32mem,
2325 int_x86_bmi_pdep_32, loadi32>, T8XD;
2326 defm PDEP64 : bmi_pdep_pext<"pdep{q}", GR64, i64mem,
2327 int_x86_bmi_pdep_64, loadi64>, T8XD, VEX_W;
2328 defm PEXT32 : bmi_pdep_pext<"pext{l}", GR32, i32mem,
2329 int_x86_bmi_pext_32, loadi32>, T8XS;
2330 defm PEXT64 : bmi_pdep_pext<"pext{q}", GR64, i64mem,
2331 int_x86_bmi_pext_64, loadi64>, T8XS, VEX_W;
2334 //===----------------------------------------------------------------------===//
2337 let Predicates = [HasTBM], Defs = [EFLAGS] in {
2339 multiclass tbm_ternary_imm_intr<bits<8> opc, RegisterClass RC, string OpcodeStr,
2340 X86MemOperand x86memop, PatFrag ld_frag,
2341 Intrinsic Int, Operand immtype,
2342 SDPatternOperator immoperator> {
2343 def ri : Ii32<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, immtype:$cntl),
2344 !strconcat(OpcodeStr,
2345 "\t{$cntl, $src1, $dst|$dst, $src1, $cntl}"),
2346 [(set RC:$dst, (Int RC:$src1, immoperator:$cntl))]>,
2348 def mi : Ii32<opc, MRMSrcMem, (outs RC:$dst),
2349 (ins x86memop:$src1, immtype:$cntl),
2350 !strconcat(OpcodeStr,
2351 "\t{$cntl, $src1, $dst|$dst, $src1, $cntl}"),
2352 [(set RC:$dst, (Int (ld_frag addr:$src1), immoperator:$cntl))]>,
2356 defm BEXTRI32 : tbm_ternary_imm_intr<0x10, GR32, "bextr", i32mem, loadi32,
2357 int_x86_tbm_bextri_u32, i32imm, imm>;
2358 let ImmT = Imm32S in
2359 defm BEXTRI64 : tbm_ternary_imm_intr<0x10, GR64, "bextr", i64mem, loadi64,
2360 int_x86_tbm_bextri_u64, i64i32imm,
2361 i64immSExt32>, VEX_W;
2363 multiclass tbm_binary_rm<bits<8> opc, Format FormReg, Format FormMem,
2364 RegisterClass RC, string OpcodeStr,
2365 X86MemOperand x86memop, PatFrag ld_frag> {
2366 let hasSideEffects = 0 in {
2367 def rr : I<opc, FormReg, (outs RC:$dst), (ins RC:$src),
2368 !strconcat(OpcodeStr,"\t{$src, $dst|$dst, $src}"),
2371 def rm : I<opc, FormMem, (outs RC:$dst), (ins x86memop:$src),
2372 !strconcat(OpcodeStr,"\t{$src, $dst|$dst, $src}"),
2377 multiclass tbm_binary_intr<bits<8> opc, string OpcodeStr,
2378 Format FormReg, Format FormMem> {
2379 defm NAME#32 : tbm_binary_rm<opc, FormReg, FormMem, GR32, OpcodeStr, i32mem,
2381 defm NAME#64 : tbm_binary_rm<opc, FormReg, FormMem, GR64, OpcodeStr, i64mem,
2385 defm BLCFILL : tbm_binary_intr<0x01, "blcfill", MRM1r, MRM1m>;
2386 defm BLCI : tbm_binary_intr<0x02, "blci", MRM6r, MRM6m>;
2387 defm BLCIC : tbm_binary_intr<0x01, "blcic", MRM5r, MRM5m>;
2388 defm BLCMSK : tbm_binary_intr<0x02, "blcmsk", MRM1r, MRM1m>;
2389 defm BLCS : tbm_binary_intr<0x01, "blcs", MRM3r, MRM3m>;
2390 defm BLSFILL : tbm_binary_intr<0x01, "blsfill", MRM2r, MRM2m>;
2391 defm BLSIC : tbm_binary_intr<0x01, "blsic", MRM6r, MRM6m>;
2392 defm T1MSKC : tbm_binary_intr<0x01, "t1mskc", MRM7r, MRM7m>;
2393 defm TZMSK : tbm_binary_intr<0x01, "tzmsk", MRM4r, MRM4m>;
2396 //===----------------------------------------------------------------------===//
2397 // Pattern fragments to auto generate TBM instructions.
2398 //===----------------------------------------------------------------------===//
2400 let Predicates = [HasTBM] in {
2401 def : Pat<(X86bextr GR32:$src1, (i32 imm:$src2)),
2402 (BEXTRI32ri GR32:$src1, imm:$src2)>;
2403 def : Pat<(X86bextr (loadi32 addr:$src1), (i32 imm:$src2)),
2404 (BEXTRI32mi addr:$src1, imm:$src2)>;
2405 def : Pat<(X86bextr GR64:$src1, i64immSExt32:$src2),
2406 (BEXTRI64ri GR64:$src1, i64immSExt32:$src2)>;
2407 def : Pat<(X86bextr (loadi64 addr:$src1), i64immSExt32:$src2),
2408 (BEXTRI64mi addr:$src1, i64immSExt32:$src2)>;
2410 // FIXME: patterns for the load versions are not implemented
2411 def : Pat<(and GR32:$src, (add GR32:$src, 1)),
2412 (BLCFILL32rr GR32:$src)>;
2413 def : Pat<(and GR64:$src, (add GR64:$src, 1)),
2414 (BLCFILL64rr GR64:$src)>;
2416 def : Pat<(or GR32:$src, (not (add GR32:$src, 1))),
2417 (BLCI32rr GR32:$src)>;
2418 def : Pat<(or GR64:$src, (not (add GR64:$src, 1))),
2419 (BLCI64rr GR64:$src)>;
2421 // Extra patterns because opt can optimize the above patterns to this.
2422 def : Pat<(or GR32:$src, (sub -2, GR32:$src)),
2423 (BLCI32rr GR32:$src)>;
2424 def : Pat<(or GR64:$src, (sub -2, GR64:$src)),
2425 (BLCI64rr GR64:$src)>;
2427 def : Pat<(and (not GR32:$src), (add GR32:$src, 1)),
2428 (BLCIC32rr GR32:$src)>;
2429 def : Pat<(and (not GR64:$src), (add GR64:$src, 1)),
2430 (BLCIC64rr GR64:$src)>;
2432 def : Pat<(xor GR32:$src, (add GR32:$src, 1)),
2433 (BLCMSK32rr GR32:$src)>;
2434 def : Pat<(xor GR64:$src, (add GR64:$src, 1)),
2435 (BLCMSK64rr GR64:$src)>;
2437 def : Pat<(or GR32:$src, (add GR32:$src, 1)),
2438 (BLCS32rr GR32:$src)>;
2439 def : Pat<(or GR64:$src, (add GR64:$src, 1)),
2440 (BLCS64rr GR64:$src)>;
2442 def : Pat<(or GR32:$src, (add GR32:$src, -1)),
2443 (BLSFILL32rr GR32:$src)>;
2444 def : Pat<(or GR64:$src, (add GR64:$src, -1)),
2445 (BLSFILL64rr GR64:$src)>;
2447 def : Pat<(or (not GR32:$src), (add GR32:$src, -1)),
2448 (BLSIC32rr GR32:$src)>;
2449 def : Pat<(or (not GR64:$src), (add GR64:$src, -1)),
2450 (BLSIC64rr GR64:$src)>;
2452 def : Pat<(or (not GR32:$src), (add GR32:$src, 1)),
2453 (T1MSKC32rr GR32:$src)>;
2454 def : Pat<(or (not GR64:$src), (add GR64:$src, 1)),
2455 (T1MSKC64rr GR64:$src)>;
2457 def : Pat<(and (not GR32:$src), (add GR32:$src, -1)),
2458 (TZMSK32rr GR32:$src)>;
2459 def : Pat<(and (not GR64:$src), (add GR64:$src, -1)),
2460 (TZMSK64rr GR64:$src)>;
2463 //===----------------------------------------------------------------------===//
2464 // Memory Instructions
2467 def CLFLUSHOPT : I<0xAE, MRM7m, (outs), (ins i8mem:$src),
2468 "clflushopt\t$src", []>, PD;
2469 def CLWB : I<0xAE, MRM6m, (outs), (ins i8mem:$src), "clwb\t$src", []>, PD;
2470 def PCOMMIT : I<0xAE, MRM_F8, (outs), (ins), "pcommit", []>, PD;
2473 //===----------------------------------------------------------------------===//
2475 //===----------------------------------------------------------------------===//
2477 include "X86InstrArithmetic.td"
2478 include "X86InstrCMovSetCC.td"
2479 include "X86InstrExtension.td"
2480 include "X86InstrControl.td"
2481 include "X86InstrShiftRotate.td"
2483 // X87 Floating Point Stack.
2484 include "X86InstrFPStack.td"
2486 // SIMD support (SSE, MMX and AVX)
2487 include "X86InstrFragmentsSIMD.td"
2489 // FMA - Fused Multiply-Add support (requires FMA)
2490 include "X86InstrFMA.td"
2493 include "X86InstrXOP.td"
2495 // SSE, MMX and 3DNow! vector support.
2496 include "X86InstrSSE.td"
2497 include "X86InstrAVX512.td"
2498 include "X86InstrMMX.td"
2499 include "X86Instr3DNow.td"
2502 include "X86InstrMPX.td"
2504 include "X86InstrVMX.td"
2505 include "X86InstrSVM.td"
2507 include "X86InstrTSX.td"
2508 include "X86InstrSGX.td"
2510 // System instructions.
2511 include "X86InstrSystem.td"
2513 // Compiler Pseudo Instructions and Pat Patterns
2514 include "X86InstrCompiler.td"
2516 //===----------------------------------------------------------------------===//
2517 // Assembler Mnemonic Aliases
2518 //===----------------------------------------------------------------------===//
2520 def : MnemonicAlias<"call", "callw", "att">, Requires<[In16BitMode]>;
2521 def : MnemonicAlias<"call", "calll", "att">, Requires<[In32BitMode]>;
2522 def : MnemonicAlias<"call", "callq", "att">, Requires<[In64BitMode]>;
2524 def : MnemonicAlias<"cbw", "cbtw", "att">;
2525 def : MnemonicAlias<"cwde", "cwtl", "att">;
2526 def : MnemonicAlias<"cwd", "cwtd", "att">;
2527 def : MnemonicAlias<"cdq", "cltd", "att">;
2528 def : MnemonicAlias<"cdqe", "cltq", "att">;
2529 def : MnemonicAlias<"cqo", "cqto", "att">;
2531 // In 64-bit mode lret maps to lretl; it is not ambiguous with lretq.
2532 def : MnemonicAlias<"lret", "lretw", "att">, Requires<[In16BitMode]>;
2533 def : MnemonicAlias<"lret", "lretl", "att">, Requires<[Not16BitMode]>;
2535 def : MnemonicAlias<"leavel", "leave", "att">, Requires<[Not64BitMode]>;
2536 def : MnemonicAlias<"leaveq", "leave", "att">, Requires<[In64BitMode]>;
2538 def : MnemonicAlias<"loopz", "loope", "att">;
2539 def : MnemonicAlias<"loopnz", "loopne", "att">;
2541 def : MnemonicAlias<"pop", "popw", "att">, Requires<[In16BitMode]>;
2542 def : MnemonicAlias<"pop", "popl", "att">, Requires<[In32BitMode]>;
2543 def : MnemonicAlias<"pop", "popq", "att">, Requires<[In64BitMode]>;
2544 def : MnemonicAlias<"popf", "popfw", "att">, Requires<[In16BitMode]>;
2545 def : MnemonicAlias<"popf", "popfl", "att">, Requires<[In32BitMode]>;
2546 def : MnemonicAlias<"popf", "popfq", "att">, Requires<[In64BitMode]>;
2547 def : MnemonicAlias<"popfd", "popfl", "att">;
2549 // FIXME: This is wrong for "push reg". "push %bx" should turn into pushw in
2550 // all modes. However: "push (addr)" and "push $42" should default to
2551 // pushl/pushq depending on the current mode. Similar for "pop %bx"
2552 def : MnemonicAlias<"push", "pushw", "att">, Requires<[In16BitMode]>;
2553 def : MnemonicAlias<"push", "pushl", "att">, Requires<[In32BitMode]>;
2554 def : MnemonicAlias<"push", "pushq", "att">, Requires<[In64BitMode]>;
2555 def : MnemonicAlias<"pushf", "pushfw", "att">, Requires<[In16BitMode]>;
2556 def : MnemonicAlias<"pushf", "pushfl", "att">, Requires<[In32BitMode]>;
2557 def : MnemonicAlias<"pushf", "pushfq", "att">, Requires<[In64BitMode]>;
2558 def : MnemonicAlias<"pushfd", "pushfl", "att">;
2560 def : MnemonicAlias<"popad", "popal", "intel">, Requires<[Not64BitMode]>;
2561 def : MnemonicAlias<"pushad", "pushal", "intel">, Requires<[Not64BitMode]>;
2562 def : MnemonicAlias<"popa", "popaw", "intel">, Requires<[In16BitMode]>;
2563 def : MnemonicAlias<"pusha", "pushaw", "intel">, Requires<[In16BitMode]>;
2564 def : MnemonicAlias<"popa", "popal", "intel">, Requires<[In32BitMode]>;
2565 def : MnemonicAlias<"pusha", "pushal", "intel">, Requires<[In32BitMode]>;
2567 def : MnemonicAlias<"popa", "popaw", "att">, Requires<[In16BitMode]>;
2568 def : MnemonicAlias<"pusha", "pushaw", "att">, Requires<[In16BitMode]>;
2569 def : MnemonicAlias<"popa", "popal", "att">, Requires<[In32BitMode]>;
2570 def : MnemonicAlias<"pusha", "pushal", "att">, Requires<[In32BitMode]>;
2572 def : MnemonicAlias<"repe", "rep">;
2573 def : MnemonicAlias<"repz", "rep">;
2574 def : MnemonicAlias<"repnz", "repne">;
2576 def : MnemonicAlias<"ret", "retw", "att">, Requires<[In16BitMode]>;
2577 def : MnemonicAlias<"ret", "retl", "att">, Requires<[In32BitMode]>;
2578 def : MnemonicAlias<"ret", "retq", "att">, Requires<[In64BitMode]>;
2580 def : MnemonicAlias<"sal", "shl", "intel">;
2581 def : MnemonicAlias<"salb", "shlb", "att">;
2582 def : MnemonicAlias<"salw", "shlw", "att">;
2583 def : MnemonicAlias<"sall", "shll", "att">;
2584 def : MnemonicAlias<"salq", "shlq", "att">;
2586 def : MnemonicAlias<"smovb", "movsb", "att">;
2587 def : MnemonicAlias<"smovw", "movsw", "att">;
2588 def : MnemonicAlias<"smovl", "movsl", "att">;
2589 def : MnemonicAlias<"smovq", "movsq", "att">;
2591 def : MnemonicAlias<"ud2a", "ud2", "att">;
2592 def : MnemonicAlias<"verrw", "verr", "att">;
2594 // System instruction aliases.
2595 def : MnemonicAlias<"iret", "iretw", "att">, Requires<[In16BitMode]>;
2596 def : MnemonicAlias<"iret", "iretl", "att">, Requires<[Not16BitMode]>;
2597 def : MnemonicAlias<"sysret", "sysretl", "att">;
2598 def : MnemonicAlias<"sysexit", "sysexitl", "att">;
2600 def : MnemonicAlias<"lgdt", "lgdtw", "att">, Requires<[In16BitMode]>;
2601 def : MnemonicAlias<"lgdt", "lgdtl", "att">, Requires<[In32BitMode]>;
2602 def : MnemonicAlias<"lgdt", "lgdtq", "att">, Requires<[In64BitMode]>;
2603 def : MnemonicAlias<"lidt", "lidtw", "att">, Requires<[In16BitMode]>;
2604 def : MnemonicAlias<"lidt", "lidtl", "att">, Requires<[In32BitMode]>;
2605 def : MnemonicAlias<"lidt", "lidtq", "att">, Requires<[In64BitMode]>;
2606 def : MnemonicAlias<"sgdt", "sgdtw", "att">, Requires<[In16BitMode]>;
2607 def : MnemonicAlias<"sgdt", "sgdtl", "att">, Requires<[In32BitMode]>;
2608 def : MnemonicAlias<"sgdt", "sgdtq", "att">, Requires<[In64BitMode]>;
2609 def : MnemonicAlias<"sidt", "sidtw", "att">, Requires<[In16BitMode]>;
2610 def : MnemonicAlias<"sidt", "sidtl", "att">, Requires<[In32BitMode]>;
2611 def : MnemonicAlias<"sidt", "sidtq", "att">, Requires<[In64BitMode]>;
2614 // Floating point stack aliases.
2615 def : MnemonicAlias<"fcmovz", "fcmove", "att">;
2616 def : MnemonicAlias<"fcmova", "fcmovnbe", "att">;
2617 def : MnemonicAlias<"fcmovnae", "fcmovb", "att">;
2618 def : MnemonicAlias<"fcmovna", "fcmovbe", "att">;
2619 def : MnemonicAlias<"fcmovae", "fcmovnb", "att">;
2620 def : MnemonicAlias<"fcomip", "fcompi", "att">;
2621 def : MnemonicAlias<"fildq", "fildll", "att">;
2622 def : MnemonicAlias<"fistpq", "fistpll", "att">;
2623 def : MnemonicAlias<"fisttpq", "fisttpll", "att">;
2624 def : MnemonicAlias<"fldcww", "fldcw", "att">;
2625 def : MnemonicAlias<"fnstcww", "fnstcw", "att">;
2626 def : MnemonicAlias<"fnstsww", "fnstsw", "att">;
2627 def : MnemonicAlias<"fucomip", "fucompi", "att">;
2628 def : MnemonicAlias<"fwait", "wait">;
2630 def : MnemonicAlias<"fxsaveq", "fxsave64", "att">;
2631 def : MnemonicAlias<"fxrstorq", "fxrstor64", "att">;
2632 def : MnemonicAlias<"xsaveq", "xsave64", "att">;
2633 def : MnemonicAlias<"xrstorq", "xrstor64", "att">;
2634 def : MnemonicAlias<"xsaveoptq", "xsaveopt64", "att">;
2637 class CondCodeAlias<string Prefix,string Suffix, string OldCond, string NewCond,
2639 : MnemonicAlias<!strconcat(Prefix, OldCond, Suffix),
2640 !strconcat(Prefix, NewCond, Suffix), VariantName>;
2642 /// IntegerCondCodeMnemonicAlias - This multiclass defines a bunch of
2643 /// MnemonicAlias's that canonicalize the condition code in a mnemonic, for
2644 /// example "setz" -> "sete".
2645 multiclass IntegerCondCodeMnemonicAlias<string Prefix, string Suffix,
2647 def C : CondCodeAlias<Prefix, Suffix, "c", "b", V>; // setc -> setb
2648 def Z : CondCodeAlias<Prefix, Suffix, "z" , "e", V>; // setz -> sete
2649 def NA : CondCodeAlias<Prefix, Suffix, "na", "be", V>; // setna -> setbe
2650 def NB : CondCodeAlias<Prefix, Suffix, "nb", "ae", V>; // setnb -> setae
2651 def NC : CondCodeAlias<Prefix, Suffix, "nc", "ae", V>; // setnc -> setae
2652 def NG : CondCodeAlias<Prefix, Suffix, "ng", "le", V>; // setng -> setle
2653 def NL : CondCodeAlias<Prefix, Suffix, "nl", "ge", V>; // setnl -> setge
2654 def NZ : CondCodeAlias<Prefix, Suffix, "nz", "ne", V>; // setnz -> setne
2655 def PE : CondCodeAlias<Prefix, Suffix, "pe", "p", V>; // setpe -> setp
2656 def PO : CondCodeAlias<Prefix, Suffix, "po", "np", V>; // setpo -> setnp
2658 def NAE : CondCodeAlias<Prefix, Suffix, "nae", "b", V>; // setnae -> setb
2659 def NBE : CondCodeAlias<Prefix, Suffix, "nbe", "a", V>; // setnbe -> seta
2660 def NGE : CondCodeAlias<Prefix, Suffix, "nge", "l", V>; // setnge -> setl
2661 def NLE : CondCodeAlias<Prefix, Suffix, "nle", "g", V>; // setnle -> setg
2664 // Aliases for set<CC>
2665 defm : IntegerCondCodeMnemonicAlias<"set", "">;
2666 // Aliases for j<CC>
2667 defm : IntegerCondCodeMnemonicAlias<"j", "">;
2668 // Aliases for cmov<CC>{w,l,q}
2669 defm : IntegerCondCodeMnemonicAlias<"cmov", "w", "att">;
2670 defm : IntegerCondCodeMnemonicAlias<"cmov", "l", "att">;
2671 defm : IntegerCondCodeMnemonicAlias<"cmov", "q", "att">;
2672 // No size suffix for intel-style asm.
2673 defm : IntegerCondCodeMnemonicAlias<"cmov", "", "intel">;
2676 //===----------------------------------------------------------------------===//
2677 // Assembler Instruction Aliases
2678 //===----------------------------------------------------------------------===//
2680 // aad/aam default to base 10 if no operand is specified.
2681 def : InstAlias<"aad", (AAD8i8 10)>;
2682 def : InstAlias<"aam", (AAM8i8 10)>;
2684 // Disambiguate the mem/imm form of bt-without-a-suffix as btl.
2685 // Likewise for btc/btr/bts.
2686 def : InstAlias<"bt {$imm, $mem|$mem, $imm}",
2687 (BT32mi8 i32mem:$mem, i32i8imm:$imm), 0>;
2688 def : InstAlias<"btc {$imm, $mem|$mem, $imm}",
2689 (BTC32mi8 i32mem:$mem, i32i8imm:$imm), 0>;
2690 def : InstAlias<"btr {$imm, $mem|$mem, $imm}",
2691 (BTR32mi8 i32mem:$mem, i32i8imm:$imm), 0>;
2692 def : InstAlias<"bts {$imm, $mem|$mem, $imm}",
2693 (BTS32mi8 i32mem:$mem, i32i8imm:$imm), 0>;
2696 def : InstAlias<"clrb $reg", (XOR8rr GR8 :$reg, GR8 :$reg), 0>;
2697 def : InstAlias<"clrw $reg", (XOR16rr GR16:$reg, GR16:$reg), 0>;
2698 def : InstAlias<"clrl $reg", (XOR32rr GR32:$reg, GR32:$reg), 0>;
2699 def : InstAlias<"clrq $reg", (XOR64rr GR64:$reg, GR64:$reg), 0>;
2701 // lods aliases. Accept the destination being omitted because it's implicit
2702 // in the mnemonic, or the mnemonic suffix being omitted because it's implicit
2703 // in the destination.
2704 def : InstAlias<"lodsb $src", (LODSB srcidx8:$src), 0>;
2705 def : InstAlias<"lodsw $src", (LODSW srcidx16:$src), 0>;
2706 def : InstAlias<"lods{l|d} $src", (LODSL srcidx32:$src), 0>;
2707 def : InstAlias<"lodsq $src", (LODSQ srcidx64:$src), 0>, Requires<[In64BitMode]>;
2708 def : InstAlias<"lods {$src, %al|al, $src}", (LODSB srcidx8:$src), 0>;
2709 def : InstAlias<"lods {$src, %ax|ax, $src}", (LODSW srcidx16:$src), 0>;
2710 def : InstAlias<"lods {$src, %eax|eax, $src}", (LODSL srcidx32:$src), 0>;
2711 def : InstAlias<"lods {$src, %rax|rax, $src}", (LODSQ srcidx64:$src), 0>, Requires<[In64BitMode]>;
2713 // stos aliases. Accept the source being omitted because it's implicit in
2714 // the mnemonic, or the mnemonic suffix being omitted because it's implicit
2716 def : InstAlias<"stosb $dst", (STOSB dstidx8:$dst), 0>;
2717 def : InstAlias<"stosw $dst", (STOSW dstidx16:$dst), 0>;
2718 def : InstAlias<"stos{l|d} $dst", (STOSL dstidx32:$dst), 0>;
2719 def : InstAlias<"stosq $dst", (STOSQ dstidx64:$dst), 0>, Requires<[In64BitMode]>;
2720 def : InstAlias<"stos {%al, $dst|$dst, al}", (STOSB dstidx8:$dst), 0>;
2721 def : InstAlias<"stos {%ax, $dst|$dst, ax}", (STOSW dstidx16:$dst), 0>;
2722 def : InstAlias<"stos {%eax, $dst|$dst, eax}", (STOSL dstidx32:$dst), 0>;
2723 def : InstAlias<"stos {%rax, $dst|$dst, rax}", (STOSQ dstidx64:$dst), 0>, Requires<[In64BitMode]>;
2725 // scas aliases. Accept the destination being omitted because it's implicit
2726 // in the mnemonic, or the mnemonic suffix being omitted because it's implicit
2727 // in the destination.
2728 def : InstAlias<"scasb $dst", (SCASB dstidx8:$dst), 0>;
2729 def : InstAlias<"scasw $dst", (SCASW dstidx16:$dst), 0>;
2730 def : InstAlias<"scas{l|d} $dst", (SCASL dstidx32:$dst), 0>;
2731 def : InstAlias<"scasq $dst", (SCASQ dstidx64:$dst), 0>, Requires<[In64BitMode]>;
2732 def : InstAlias<"scas {$dst, %al|al, $dst}", (SCASB dstidx8:$dst), 0>;
2733 def : InstAlias<"scas {$dst, %ax|ax, $dst}", (SCASW dstidx16:$dst), 0>;
2734 def : InstAlias<"scas {$dst, %eax|eax, $dst}", (SCASL dstidx32:$dst), 0>;
2735 def : InstAlias<"scas {$dst, %rax|rax, $dst}", (SCASQ dstidx64:$dst), 0>, Requires<[In64BitMode]>;
2737 // div and idiv aliases for explicit A register.
2738 def : InstAlias<"div{b}\t{$src, %al|al, $src}", (DIV8r GR8 :$src)>;
2739 def : InstAlias<"div{w}\t{$src, %ax|ax, $src}", (DIV16r GR16:$src)>;
2740 def : InstAlias<"div{l}\t{$src, %eax|eax, $src}", (DIV32r GR32:$src)>;
2741 def : InstAlias<"div{q}\t{$src, %rax|rax, $src}", (DIV64r GR64:$src)>;
2742 def : InstAlias<"div{b}\t{$src, %al|al, $src}", (DIV8m i8mem :$src)>;
2743 def : InstAlias<"div{w}\t{$src, %ax|ax, $src}", (DIV16m i16mem:$src)>;
2744 def : InstAlias<"div{l}\t{$src, %eax|eax, $src}", (DIV32m i32mem:$src)>;
2745 def : InstAlias<"div{q}\t{$src, %rax|rax, $src}", (DIV64m i64mem:$src)>;
2746 def : InstAlias<"idiv{b}\t{$src, %al|al, $src}", (IDIV8r GR8 :$src)>;
2747 def : InstAlias<"idiv{w}\t{$src, %ax|ax, $src}", (IDIV16r GR16:$src)>;
2748 def : InstAlias<"idiv{l}\t{$src, %eax|eax, $src}", (IDIV32r GR32:$src)>;
2749 def : InstAlias<"idiv{q}\t{$src, %rax|rax, $src}", (IDIV64r GR64:$src)>;
2750 def : InstAlias<"idiv{b}\t{$src, %al|al, $src}", (IDIV8m i8mem :$src)>;
2751 def : InstAlias<"idiv{w}\t{$src, %ax|ax, $src}", (IDIV16m i16mem:$src)>;
2752 def : InstAlias<"idiv{l}\t{$src, %eax|eax, $src}", (IDIV32m i32mem:$src)>;
2753 def : InstAlias<"idiv{q}\t{$src, %rax|rax, $src}", (IDIV64m i64mem:$src)>;
2757 // Various unary fpstack operations default to operating on on ST1.
2758 // For example, "fxch" -> "fxch %st(1)"
2759 def : InstAlias<"faddp", (ADD_FPrST0 ST1), 0>;
2760 def : InstAlias<"fsub{|r}p", (SUBR_FPrST0 ST1), 0>;
2761 def : InstAlias<"fsub{r|}p", (SUB_FPrST0 ST1), 0>;
2762 def : InstAlias<"fmulp", (MUL_FPrST0 ST1), 0>;
2763 def : InstAlias<"fdiv{|r}p", (DIVR_FPrST0 ST1), 0>;
2764 def : InstAlias<"fdiv{r|}p", (DIV_FPrST0 ST1), 0>;
2765 def : InstAlias<"fxch", (XCH_F ST1), 0>;
2766 def : InstAlias<"fcom", (COM_FST0r ST1), 0>;
2767 def : InstAlias<"fcomp", (COMP_FST0r ST1), 0>;
2768 def : InstAlias<"fcomi", (COM_FIr ST1), 0>;
2769 def : InstAlias<"fcompi", (COM_FIPr ST1), 0>;
2770 def : InstAlias<"fucom", (UCOM_Fr ST1), 0>;
2771 def : InstAlias<"fucomp", (UCOM_FPr ST1), 0>;
2772 def : InstAlias<"fucomi", (UCOM_FIr ST1), 0>;
2773 def : InstAlias<"fucompi", (UCOM_FIPr ST1), 0>;
2775 // Handle fmul/fadd/fsub/fdiv instructions with explicitly written st(0) op.
2776 // For example, "fadd %st(4), %st(0)" -> "fadd %st(4)". We also disambiguate
2777 // instructions like "fadd %st(0), %st(0)" as "fadd %st(0)" for consistency with
2779 multiclass FpUnaryAlias<string Mnemonic, Instruction Inst, bit EmitAlias = 1> {
2780 def : InstAlias<!strconcat(Mnemonic, "\t{$op, %st(0)|st(0), $op}"),
2781 (Inst RST:$op), EmitAlias>;
2782 def : InstAlias<!strconcat(Mnemonic, "\t{%st(0), %st(0)|st(0), st(0)}"),
2783 (Inst ST0), EmitAlias>;
2786 defm : FpUnaryAlias<"fadd", ADD_FST0r>;
2787 defm : FpUnaryAlias<"faddp", ADD_FPrST0, 0>;
2788 defm : FpUnaryAlias<"fsub", SUB_FST0r>;
2789 defm : FpUnaryAlias<"fsub{|r}p", SUBR_FPrST0>;
2790 defm : FpUnaryAlias<"fsubr", SUBR_FST0r>;
2791 defm : FpUnaryAlias<"fsub{r|}p", SUB_FPrST0>;
2792 defm : FpUnaryAlias<"fmul", MUL_FST0r>;
2793 defm : FpUnaryAlias<"fmulp", MUL_FPrST0>;
2794 defm : FpUnaryAlias<"fdiv", DIV_FST0r>;
2795 defm : FpUnaryAlias<"fdiv{|r}p", DIVR_FPrST0>;
2796 defm : FpUnaryAlias<"fdivr", DIVR_FST0r>;
2797 defm : FpUnaryAlias<"fdiv{r|}p", DIV_FPrST0>;
2798 defm : FpUnaryAlias<"fcomi", COM_FIr, 0>;
2799 defm : FpUnaryAlias<"fucomi", UCOM_FIr, 0>;
2800 defm : FpUnaryAlias<"fcompi", COM_FIPr>;
2801 defm : FpUnaryAlias<"fucompi", UCOM_FIPr>;
2804 // Handle "f{mulp,addp} st(0), $op" the same as "f{mulp,addp} $op", since they
2805 // commute. We also allow fdiv[r]p/fsubrp even though they don't commute,
2806 // solely because gas supports it.
2807 def : InstAlias<"faddp\t{%st(0), $op|$op, st(0)}", (ADD_FPrST0 RST:$op), 0>;
2808 def : InstAlias<"fmulp\t{%st(0), $op|$op, st(0)}", (MUL_FPrST0 RST:$op)>;
2809 def : InstAlias<"fsub{|r}p\t{%st(0), $op|$op, st(0)}", (SUBR_FPrST0 RST:$op)>;
2810 def : InstAlias<"fsub{r|}p\t{%st(0), $op|$op, st(0)}", (SUB_FPrST0 RST:$op)>;
2811 def : InstAlias<"fdiv{|r}p\t{%st(0), $op|$op, st(0)}", (DIVR_FPrST0 RST:$op)>;
2812 def : InstAlias<"fdiv{r|}p\t{%st(0), $op|$op, st(0)}", (DIV_FPrST0 RST:$op)>;
2814 // We accept "fnstsw %eax" even though it only writes %ax.
2815 def : InstAlias<"fnstsw\t{%eax|eax}", (FNSTSW16r)>;
2816 def : InstAlias<"fnstsw\t{%al|al}" , (FNSTSW16r)>;
2817 def : InstAlias<"fnstsw" , (FNSTSW16r)>;
2819 // lcall and ljmp aliases. This seems to be an odd mapping in 64-bit mode, but
2820 // this is compatible with what GAS does.
2821 def : InstAlias<"lcall $seg, $off", (FARCALL32i i32imm:$off, i16imm:$seg), 0>, Requires<[Not16BitMode]>;
2822 def : InstAlias<"ljmp $seg, $off", (FARJMP32i i32imm:$off, i16imm:$seg), 0>, Requires<[Not16BitMode]>;
2823 def : InstAlias<"lcall {*}$dst", (FARCALL32m opaque48mem:$dst), 0>, Requires<[Not16BitMode]>;
2824 def : InstAlias<"ljmp {*}$dst", (FARJMP32m opaque48mem:$dst), 0>, Requires<[Not16BitMode]>;
2825 def : InstAlias<"lcall $seg, $off", (FARCALL16i i16imm:$off, i16imm:$seg), 0>, Requires<[In16BitMode]>;
2826 def : InstAlias<"ljmp $seg, $off", (FARJMP16i i16imm:$off, i16imm:$seg), 0>, Requires<[In16BitMode]>;
2827 def : InstAlias<"lcall {*}$dst", (FARCALL16m opaque32mem:$dst), 0>, Requires<[In16BitMode]>;
2828 def : InstAlias<"ljmp {*}$dst", (FARJMP16m opaque32mem:$dst), 0>, Requires<[In16BitMode]>;
2830 def : InstAlias<"call {*}$dst", (CALL64m i64mem:$dst), 0>, Requires<[In64BitMode]>;
2831 def : InstAlias<"jmp {*}$dst", (JMP64m i64mem:$dst), 0>, Requires<[In64BitMode]>;
2832 def : InstAlias<"call {*}$dst", (CALL32m i32mem:$dst), 0>, Requires<[In32BitMode]>;
2833 def : InstAlias<"jmp {*}$dst", (JMP32m i32mem:$dst), 0>, Requires<[In32BitMode]>;
2834 def : InstAlias<"call {*}$dst", (CALL16m i16mem:$dst), 0>, Requires<[In16BitMode]>;
2835 def : InstAlias<"jmp {*}$dst", (JMP16m i16mem:$dst), 0>, Requires<[In16BitMode]>;
2838 // "imul <imm>, B" is an alias for "imul <imm>, B, B".
2839 def : InstAlias<"imul{w} {$imm, $r|$r, $imm}", (IMUL16rri GR16:$r, GR16:$r, i16imm:$imm), 0>;
2840 def : InstAlias<"imul{w} {$imm, $r|$r, $imm}", (IMUL16rri8 GR16:$r, GR16:$r, i16i8imm:$imm), 0>;
2841 def : InstAlias<"imul{l} {$imm, $r|$r, $imm}", (IMUL32rri GR32:$r, GR32:$r, i32imm:$imm), 0>;
2842 def : InstAlias<"imul{l} {$imm, $r|$r, $imm}", (IMUL32rri8 GR32:$r, GR32:$r, i32i8imm:$imm), 0>;
2843 def : InstAlias<"imul{q} {$imm, $r|$r, $imm}", (IMUL64rri32 GR64:$r, GR64:$r, i64i32imm:$imm), 0>;
2844 def : InstAlias<"imul{q} {$imm, $r|$r, $imm}", (IMUL64rri8 GR64:$r, GR64:$r, i64i8imm:$imm), 0>;
2846 // inb %dx -> inb %al, %dx
2847 def : InstAlias<"inb\t{%dx|dx}", (IN8rr), 0>;
2848 def : InstAlias<"inw\t{%dx|dx}", (IN16rr), 0>;
2849 def : InstAlias<"inl\t{%dx|dx}", (IN32rr), 0>;
2850 def : InstAlias<"inb\t$port", (IN8ri i8imm:$port), 0>;
2851 def : InstAlias<"inw\t$port", (IN16ri i8imm:$port), 0>;
2852 def : InstAlias<"inl\t$port", (IN32ri i8imm:$port), 0>;
2855 // jmp and call aliases for lcall and ljmp. jmp $42,$5 -> ljmp
2856 def : InstAlias<"call $seg, $off", (FARCALL16i i16imm:$off, i16imm:$seg)>, Requires<[In16BitMode]>;
2857 def : InstAlias<"jmp $seg, $off", (FARJMP16i i16imm:$off, i16imm:$seg)>, Requires<[In16BitMode]>;
2858 def : InstAlias<"call $seg, $off", (FARCALL32i i32imm:$off, i16imm:$seg)>, Requires<[Not16BitMode]>;
2859 def : InstAlias<"jmp $seg, $off", (FARJMP32i i32imm:$off, i16imm:$seg)>, Requires<[Not16BitMode]>;
2860 def : InstAlias<"callw $seg, $off", (FARCALL16i i16imm:$off, i16imm:$seg)>;
2861 def : InstAlias<"jmpw $seg, $off", (FARJMP16i i16imm:$off, i16imm:$seg)>;
2862 def : InstAlias<"calll $seg, $off", (FARCALL32i i32imm:$off, i16imm:$seg)>;
2863 def : InstAlias<"jmpl $seg, $off", (FARJMP32i i32imm:$off, i16imm:$seg)>;
2865 // Force mov without a suffix with a segment and mem to prefer the 'l' form of
2866 // the move. All segment/mem forms are equivalent, this has the shortest
2868 def : InstAlias<"mov {$mem, $seg|$seg, $mem}", (MOV32sm SEGMENT_REG:$seg, i32mem:$mem), 0>;
2869 def : InstAlias<"mov {$seg, $mem|$mem, $seg}", (MOV32ms i32mem:$mem, SEGMENT_REG:$seg), 0>;
2871 // Match 'movq <largeimm>, <reg>' as an alias for movabsq.
2872 def : InstAlias<"movq {$imm, $reg|$reg, $imm}", (MOV64ri GR64:$reg, i64imm:$imm), 0>;
2874 // Match 'movq GR64, MMX' as an alias for movd.
2875 def : InstAlias<"movq {$src, $dst|$dst, $src}",
2876 (MMX_MOVD64to64rr VR64:$dst, GR64:$src), 0>;
2877 def : InstAlias<"movq {$src, $dst|$dst, $src}",
2878 (MMX_MOVD64from64rr GR64:$dst, VR64:$src), 0>;
2881 def : InstAlias<"movsx {$src, $dst|$dst, $src}", (MOVSX16rr8 GR16:$dst, GR8:$src), 0>;
2882 def : InstAlias<"movsx {$src, $dst|$dst, $src}", (MOVSX16rm8 GR16:$dst, i8mem:$src), 0>;
2883 def : InstAlias<"movsx {$src, $dst|$dst, $src}", (MOVSX32rr8 GR32:$dst, GR8:$src), 0>;
2884 def : InstAlias<"movsx {$src, $dst|$dst, $src}", (MOVSX32rr16 GR32:$dst, GR16:$src), 0>;
2885 def : InstAlias<"movsx {$src, $dst|$dst, $src}", (MOVSX64rr8 GR64:$dst, GR8:$src), 0>;
2886 def : InstAlias<"movsx {$src, $dst|$dst, $src}", (MOVSX64rr16 GR64:$dst, GR16:$src), 0>;
2887 def : InstAlias<"movsx {$src, $dst|$dst, $src}", (MOVSX64rr32 GR64:$dst, GR32:$src), 0>;
2890 def : InstAlias<"movzx {$src, $dst|$dst, $src}", (MOVZX16rr8 GR16:$dst, GR8:$src), 0>;
2891 def : InstAlias<"movzx {$src, $dst|$dst, $src}", (MOVZX16rm8 GR16:$dst, i8mem:$src), 0>;
2892 def : InstAlias<"movzx {$src, $dst|$dst, $src}", (MOVZX32rr8 GR32:$dst, GR8:$src), 0>;
2893 def : InstAlias<"movzx {$src, $dst|$dst, $src}", (MOVZX32rr16 GR32:$dst, GR16:$src), 0>;
2894 def : InstAlias<"movzx {$src, $dst|$dst, $src}", (MOVZX64rr8_Q GR64:$dst, GR8:$src), 0>;
2895 def : InstAlias<"movzx {$src, $dst|$dst, $src}", (MOVZX64rr16_Q GR64:$dst, GR16:$src), 0>;
2896 // Note: No GR32->GR64 movzx form.
2898 // outb %dx -> outb %al, %dx
2899 def : InstAlias<"outb\t{%dx|dx}", (OUT8rr), 0>;
2900 def : InstAlias<"outw\t{%dx|dx}", (OUT16rr), 0>;
2901 def : InstAlias<"outl\t{%dx|dx}", (OUT32rr), 0>;
2902 def : InstAlias<"outb\t$port", (OUT8ir i8imm:$port), 0>;
2903 def : InstAlias<"outw\t$port", (OUT16ir i8imm:$port), 0>;
2904 def : InstAlias<"outl\t$port", (OUT32ir i8imm:$port), 0>;
2906 // 'sldt <mem>' can be encoded with either sldtw or sldtq with the same
2907 // effect (both store to a 16-bit mem). Force to sldtw to avoid ambiguity
2908 // errors, since its encoding is the most compact.
2909 def : InstAlias<"sldt $mem", (SLDT16m i16mem:$mem), 0>;
2911 // shld/shrd op,op -> shld op, op, CL
2912 def : InstAlias<"shld{w}\t{$r2, $r1|$r1, $r2}", (SHLD16rrCL GR16:$r1, GR16:$r2), 0>;
2913 def : InstAlias<"shld{l}\t{$r2, $r1|$r1, $r2}", (SHLD32rrCL GR32:$r1, GR32:$r2), 0>;
2914 def : InstAlias<"shld{q}\t{$r2, $r1|$r1, $r2}", (SHLD64rrCL GR64:$r1, GR64:$r2), 0>;
2915 def : InstAlias<"shrd{w}\t{$r2, $r1|$r1, $r2}", (SHRD16rrCL GR16:$r1, GR16:$r2), 0>;
2916 def : InstAlias<"shrd{l}\t{$r2, $r1|$r1, $r2}", (SHRD32rrCL GR32:$r1, GR32:$r2), 0>;
2917 def : InstAlias<"shrd{q}\t{$r2, $r1|$r1, $r2}", (SHRD64rrCL GR64:$r1, GR64:$r2), 0>;
2919 def : InstAlias<"shld{w}\t{$reg, $mem|$mem, $reg}", (SHLD16mrCL i16mem:$mem, GR16:$reg), 0>;
2920 def : InstAlias<"shld{l}\t{$reg, $mem|$mem, $reg}", (SHLD32mrCL i32mem:$mem, GR32:$reg), 0>;
2921 def : InstAlias<"shld{q}\t{$reg, $mem|$mem, $reg}", (SHLD64mrCL i64mem:$mem, GR64:$reg), 0>;
2922 def : InstAlias<"shrd{w}\t{$reg, $mem|$mem, $reg}", (SHRD16mrCL i16mem:$mem, GR16:$reg), 0>;
2923 def : InstAlias<"shrd{l}\t{$reg, $mem|$mem, $reg}", (SHRD32mrCL i32mem:$mem, GR32:$reg), 0>;
2924 def : InstAlias<"shrd{q}\t{$reg, $mem|$mem, $reg}", (SHRD64mrCL i64mem:$mem, GR64:$reg), 0>;
2926 /* FIXME: This is disabled because the asm matcher is currently incapable of
2927 * matching a fixed immediate like $1.
2928 // "shl X, $1" is an alias for "shl X".
2929 multiclass ShiftRotateByOneAlias<string Mnemonic, string Opc> {
2930 def : InstAlias<!strconcat(Mnemonic, "b $op, $$1"),
2931 (!cast<Instruction>(!strconcat(Opc, "8r1")) GR8:$op)>;
2932 def : InstAlias<!strconcat(Mnemonic, "w $op, $$1"),
2933 (!cast<Instruction>(!strconcat(Opc, "16r1")) GR16:$op)>;
2934 def : InstAlias<!strconcat(Mnemonic, "l $op, $$1"),
2935 (!cast<Instruction>(!strconcat(Opc, "32r1")) GR32:$op)>;
2936 def : InstAlias<!strconcat(Mnemonic, "q $op, $$1"),
2937 (!cast<Instruction>(!strconcat(Opc, "64r1")) GR64:$op)>;
2938 def : InstAlias<!strconcat(Mnemonic, "b $op, $$1"),
2939 (!cast<Instruction>(!strconcat(Opc, "8m1")) i8mem:$op)>;
2940 def : InstAlias<!strconcat(Mnemonic, "w $op, $$1"),
2941 (!cast<Instruction>(!strconcat(Opc, "16m1")) i16mem:$op)>;
2942 def : InstAlias<!strconcat(Mnemonic, "l $op, $$1"),
2943 (!cast<Instruction>(!strconcat(Opc, "32m1")) i32mem:$op)>;
2944 def : InstAlias<!strconcat(Mnemonic, "q $op, $$1"),
2945 (!cast<Instruction>(!strconcat(Opc, "64m1")) i64mem:$op)>;
2948 defm : ShiftRotateByOneAlias<"rcl", "RCL">;
2949 defm : ShiftRotateByOneAlias<"rcr", "RCR">;
2950 defm : ShiftRotateByOneAlias<"rol", "ROL">;
2951 defm : ShiftRotateByOneAlias<"ror", "ROR">;
2954 // test: We accept "testX <reg>, <mem>" and "testX <mem>, <reg>" as synonyms.
2955 def : InstAlias<"test{b}\t{$val, $mem|$mem, $val}",
2956 (TEST8rm GR8 :$val, i8mem :$mem), 0>;
2957 def : InstAlias<"test{w}\t{$val, $mem|$mem, $val}",
2958 (TEST16rm GR16:$val, i16mem:$mem), 0>;
2959 def : InstAlias<"test{l}\t{$val, $mem|$mem, $val}",
2960 (TEST32rm GR32:$val, i32mem:$mem), 0>;
2961 def : InstAlias<"test{q}\t{$val, $mem|$mem, $val}",
2962 (TEST64rm GR64:$val, i64mem:$mem), 0>;
2964 // xchg: We accept "xchgX <reg>, <mem>" and "xchgX <mem>, <reg>" as synonyms.
2965 def : InstAlias<"xchg{b}\t{$mem, $val|$val, $mem}",
2966 (XCHG8rm GR8 :$val, i8mem :$mem), 0>;
2967 def : InstAlias<"xchg{w}\t{$mem, $val|$val, $mem}",
2968 (XCHG16rm GR16:$val, i16mem:$mem), 0>;
2969 def : InstAlias<"xchg{l}\t{$mem, $val|$val, $mem}",
2970 (XCHG32rm GR32:$val, i32mem:$mem), 0>;
2971 def : InstAlias<"xchg{q}\t{$mem, $val|$val, $mem}",
2972 (XCHG64rm GR64:$val, i64mem:$mem), 0>;
2974 // xchg: We accept "xchgX <reg>, %eax" and "xchgX %eax, <reg>" as synonyms.
2975 def : InstAlias<"xchg{w}\t{%ax, $src|$src, ax}", (XCHG16ar GR16:$src), 0>;
2976 def : InstAlias<"xchg{l}\t{%eax, $src|$src, eax}",
2977 (XCHG32ar GR32:$src), 0>, Requires<[Not64BitMode]>;
2978 def : InstAlias<"xchg{l}\t{%eax, $src|$src, eax}",
2979 (XCHG32ar64 GR32_NOAX:$src), 0>, Requires<[In64BitMode]>;
2980 def : InstAlias<"xchg{q}\t{%rax, $src|$src, rax}", (XCHG64ar GR64:$src), 0>;