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_X86WIN_FTOL : SDTypeProfile<0, 1, [SDTCisFP<0>]>;
111 def SDT_X86EHRET : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
113 def SDT_X86TCRET : SDTypeProfile<0, 2, [SDTCisPtrTy<0>, SDTCisVT<1, i32>]>;
115 def SDT_X86MEMBARRIER : SDTypeProfile<0, 0, []>;
117 def X86MemBarrier : SDNode<"X86ISD::MEMBARRIER", SDT_X86MEMBARRIER,
118 [SDNPHasChain,SDNPSideEffect]>;
119 def X86MFence : SDNode<"X86ISD::MFENCE", SDT_X86MEMBARRIER,
121 def X86SFence : SDNode<"X86ISD::SFENCE", SDT_X86MEMBARRIER,
123 def X86LFence : SDNode<"X86ISD::LFENCE", SDT_X86MEMBARRIER,
127 def X86bsf : SDNode<"X86ISD::BSF", SDTUnaryArithWithFlags>;
128 def X86bsr : SDNode<"X86ISD::BSR", SDTUnaryArithWithFlags>;
129 def X86shld : SDNode<"X86ISD::SHLD", SDTIntShiftDOp>;
130 def X86shrd : SDNode<"X86ISD::SHRD", SDTIntShiftDOp>;
132 def X86cmp : SDNode<"X86ISD::CMP" , SDTX86CmpTest>;
133 def X86bt : SDNode<"X86ISD::BT", SDTX86CmpTest>;
135 def X86cmov : SDNode<"X86ISD::CMOV", SDTX86Cmov>;
136 def X86brcond : SDNode<"X86ISD::BRCOND", SDTX86BrCond,
138 def X86setcc : SDNode<"X86ISD::SETCC", SDTX86SetCC>;
139 def X86setcc_c : SDNode<"X86ISD::SETCC_CARRY", SDTX86SetCC_C>;
141 def X86sahf : SDNode<"X86ISD::SAHF", SDTX86sahf>;
143 def X86rdrand : SDNode<"X86ISD::RDRAND", SDTX86rdrand,
144 [SDNPHasChain, SDNPSideEffect]>;
146 def X86rdseed : SDNode<"X86ISD::RDSEED", SDTX86rdrand,
147 [SDNPHasChain, SDNPSideEffect]>;
149 def X86cas : SDNode<"X86ISD::LCMPXCHG_DAG", SDTX86cas,
150 [SDNPHasChain, SDNPInGlue, SDNPOutGlue, SDNPMayStore,
151 SDNPMayLoad, SDNPMemOperand]>;
152 def X86cas8 : SDNode<"X86ISD::LCMPXCHG8_DAG", SDTX86caspair,
153 [SDNPHasChain, SDNPInGlue, SDNPOutGlue, SDNPMayStore,
154 SDNPMayLoad, SDNPMemOperand]>;
155 def X86cas16 : SDNode<"X86ISD::LCMPXCHG16_DAG", SDTX86caspair,
156 [SDNPHasChain, SDNPInGlue, SDNPOutGlue, SDNPMayStore,
157 SDNPMayLoad, SDNPMemOperand]>;
159 def X86retflag : SDNode<"X86ISD::RET_FLAG", SDTX86Ret,
160 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
162 def X86vastart_save_xmm_regs :
163 SDNode<"X86ISD::VASTART_SAVE_XMM_REGS",
164 SDT_X86VASTART_SAVE_XMM_REGS,
165 [SDNPHasChain, SDNPVariadic]>;
167 SDNode<"X86ISD::VAARG_64", SDT_X86VAARG_64,
168 [SDNPHasChain, SDNPMayLoad, SDNPMayStore,
170 def X86callseq_start :
171 SDNode<"ISD::CALLSEQ_START", SDT_X86CallSeqStart,
172 [SDNPHasChain, SDNPOutGlue]>;
174 SDNode<"ISD::CALLSEQ_END", SDT_X86CallSeqEnd,
175 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
177 def X86call : SDNode<"X86ISD::CALL", SDT_X86Call,
178 [SDNPHasChain, SDNPOutGlue, SDNPOptInGlue,
181 def X86rep_stos: SDNode<"X86ISD::REP_STOS", SDTX86RepStr,
182 [SDNPHasChain, SDNPInGlue, SDNPOutGlue, SDNPMayStore]>;
183 def X86rep_movs: SDNode<"X86ISD::REP_MOVS", SDTX86RepStr,
184 [SDNPHasChain, SDNPInGlue, SDNPOutGlue, SDNPMayStore,
187 def X86rdtsc : SDNode<"X86ISD::RDTSC_DAG", SDTX86Void,
188 [SDNPHasChain, SDNPOutGlue, SDNPSideEffect]>;
189 def X86rdtscp : SDNode<"X86ISD::RDTSCP_DAG", SDTX86Void,
190 [SDNPHasChain, SDNPOutGlue, SDNPSideEffect]>;
191 def X86rdpmc : SDNode<"X86ISD::RDPMC_DAG", SDTX86Void,
192 [SDNPHasChain, SDNPOutGlue, SDNPSideEffect]>;
194 def X86Wrapper : SDNode<"X86ISD::Wrapper", SDTX86Wrapper>;
195 def X86WrapperRIP : SDNode<"X86ISD::WrapperRIP", SDTX86Wrapper>;
197 def X86RecoverFrameAlloc : SDNode<"ISD::FRAME_ALLOC_RECOVER",
198 SDTypeProfile<1, 1, [SDTCisSameAs<0, 1>,
201 def X86tlsaddr : SDNode<"X86ISD::TLSADDR", SDT_X86TLSADDR,
202 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
204 def X86tlsbaseaddr : SDNode<"X86ISD::TLSBASEADDR", SDT_X86TLSBASEADDR,
205 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
207 def X86ehret : SDNode<"X86ISD::EH_RETURN", SDT_X86EHRET,
210 def X86eh_sjlj_setjmp : SDNode<"X86ISD::EH_SJLJ_SETJMP",
211 SDTypeProfile<1, 1, [SDTCisInt<0>,
213 [SDNPHasChain, SDNPSideEffect]>;
214 def X86eh_sjlj_longjmp : SDNode<"X86ISD::EH_SJLJ_LONGJMP",
215 SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>,
216 [SDNPHasChain, SDNPSideEffect]>;
218 def X86tcret : SDNode<"X86ISD::TC_RETURN", SDT_X86TCRET,
219 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
221 def X86add_flag : SDNode<"X86ISD::ADD", SDTBinaryArithWithFlags,
223 def X86sub_flag : SDNode<"X86ISD::SUB", SDTBinaryArithWithFlags>;
224 def X86smul_flag : SDNode<"X86ISD::SMUL", SDTBinaryArithWithFlags,
226 def X86umul_flag : SDNode<"X86ISD::UMUL", SDT2ResultBinaryArithWithFlags,
228 def X86adc_flag : SDNode<"X86ISD::ADC", SDTBinaryArithWithFlagsInOut>;
229 def X86sbb_flag : SDNode<"X86ISD::SBB", SDTBinaryArithWithFlagsInOut>;
231 def X86inc_flag : SDNode<"X86ISD::INC", SDTUnaryArithWithFlags>;
232 def X86dec_flag : SDNode<"X86ISD::DEC", SDTUnaryArithWithFlags>;
233 def X86or_flag : SDNode<"X86ISD::OR", SDTBinaryArithWithFlags,
235 def X86xor_flag : SDNode<"X86ISD::XOR", SDTBinaryArithWithFlags,
237 def X86and_flag : SDNode<"X86ISD::AND", SDTBinaryArithWithFlags,
240 def X86bextr : SDNode<"X86ISD::BEXTR", SDTIntBinOp>;
242 def X86mul_imm : SDNode<"X86ISD::MUL_IMM", SDTIntBinOp>;
244 def X86WinAlloca : SDNode<"X86ISD::WIN_ALLOCA", SDTX86Void,
245 [SDNPHasChain, SDNPInGlue, SDNPOutGlue]>;
247 def X86SegAlloca : SDNode<"X86ISD::SEG_ALLOCA", SDT_X86SEG_ALLOCA,
250 def X86TLSCall : SDNode<"X86ISD::TLSCALL", SDT_X86TLSCALL,
251 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
253 def X86WinFTOL : SDNode<"X86ISD::WIN_FTOL", SDT_X86WIN_FTOL,
254 [SDNPHasChain, SDNPOutGlue]>;
256 //===----------------------------------------------------------------------===//
257 // X86 Operand Definitions.
260 // A version of ptr_rc which excludes SP, ESP, and RSP. This is used for
261 // the index operand of an address, to conform to x86 encoding restrictions.
262 def ptr_rc_nosp : PointerLikeRegClass<1>;
264 // *mem - Operand definitions for the funky X86 addressing mode operands.
266 def X86MemAsmOperand : AsmOperandClass {
269 let RenderMethod = "addMemOperands" in {
270 def X86Mem8AsmOperand : AsmOperandClass { let Name = "Mem8"; }
271 def X86Mem16AsmOperand : AsmOperandClass { let Name = "Mem16"; }
272 def X86Mem32AsmOperand : AsmOperandClass { let Name = "Mem32"; }
273 def X86Mem64AsmOperand : AsmOperandClass { let Name = "Mem64"; }
274 def X86Mem80AsmOperand : AsmOperandClass { let Name = "Mem80"; }
275 def X86Mem128AsmOperand : AsmOperandClass { let Name = "Mem128"; }
276 def X86Mem256AsmOperand : AsmOperandClass { let Name = "Mem256"; }
277 def X86Mem512AsmOperand : AsmOperandClass { let Name = "Mem512"; }
278 // Gather mem operands
279 def X86MemVX32Operand : AsmOperandClass { let Name = "MemVX32"; }
280 def X86MemVY32Operand : AsmOperandClass { let Name = "MemVY32"; }
281 def X86MemVZ32Operand : AsmOperandClass { let Name = "MemVZ32"; }
282 def X86MemVX64Operand : AsmOperandClass { let Name = "MemVX64"; }
283 def X86MemVY64Operand : AsmOperandClass { let Name = "MemVY64"; }
284 def X86MemVZ64Operand : AsmOperandClass { let Name = "MemVZ64"; }
287 def X86AbsMemAsmOperand : AsmOperandClass {
289 let SuperClasses = [X86MemAsmOperand];
292 class X86MemOperand<string printMethod,
293 AsmOperandClass parserMatchClass = X86MemAsmOperand> : Operand<iPTR> {
294 let PrintMethod = printMethod;
295 let MIOperandInfo = (ops ptr_rc, i8imm, ptr_rc_nosp, i32imm, i8imm);
296 let ParserMatchClass = parserMatchClass;
297 let OperandType = "OPERAND_MEMORY";
300 // Gather mem operands
301 class X86VMemOperand<RegisterClass RC, string printMethod,
302 AsmOperandClass parserMatchClass>
303 : X86MemOperand<printMethod, parserMatchClass> {
304 let MIOperandInfo = (ops ptr_rc, i8imm, RC, i32imm, i8imm);
307 def anymem : X86MemOperand<"printanymem">;
309 def opaque32mem : X86MemOperand<"printopaquemem">;
310 def opaque48mem : X86MemOperand<"printopaquemem">;
311 def opaque80mem : X86MemOperand<"printopaquemem">;
312 def opaque512mem : X86MemOperand<"printopaquemem">;
314 def i8mem : X86MemOperand<"printi8mem", X86Mem8AsmOperand>;
315 def i16mem : X86MemOperand<"printi16mem", X86Mem16AsmOperand>;
316 def i32mem : X86MemOperand<"printi32mem", X86Mem32AsmOperand>;
317 def i64mem : X86MemOperand<"printi64mem", X86Mem64AsmOperand>;
318 def i128mem : X86MemOperand<"printi128mem", X86Mem128AsmOperand>;
319 def i256mem : X86MemOperand<"printi256mem", X86Mem256AsmOperand>;
320 def i512mem : X86MemOperand<"printi512mem", X86Mem512AsmOperand>;
321 def f32mem : X86MemOperand<"printf32mem", X86Mem32AsmOperand>;
322 def f64mem : X86MemOperand<"printf64mem", X86Mem64AsmOperand>;
323 def f80mem : X86MemOperand<"printf80mem", X86Mem80AsmOperand>;
324 def f128mem : X86MemOperand<"printf128mem", X86Mem128AsmOperand>;
325 def f256mem : X86MemOperand<"printf256mem", X86Mem256AsmOperand>;
326 def f512mem : X86MemOperand<"printf512mem", X86Mem512AsmOperand>;
328 def v512mem : X86VMemOperand<VR512, "printf512mem", X86Mem512AsmOperand>;
330 // Gather mem operands
331 def vx32mem : X86VMemOperand<VR128, "printi32mem", X86MemVX32Operand>;
332 def vy32mem : X86VMemOperand<VR256, "printi32mem", X86MemVY32Operand>;
333 def vx64mem : X86VMemOperand<VR128, "printi64mem", X86MemVX64Operand>;
334 def vy64mem : X86VMemOperand<VR256, "printi64mem", X86MemVY64Operand>;
335 def vy64xmem : X86VMemOperand<VR256X, "printi64mem", X86MemVY64Operand>;
336 def vz32mem : X86VMemOperand<VR512, "printi32mem", X86MemVZ32Operand>;
337 def vz64mem : X86VMemOperand<VR512, "printi64mem", X86MemVZ64Operand>;
339 // A version of i8mem for use on x86-64 that uses GR64_NOREX instead of
340 // plain GR64, so that it doesn't potentially require a REX prefix.
341 def i8mem_NOREX : Operand<i64> {
342 let PrintMethod = "printi8mem";
343 let MIOperandInfo = (ops GR64_NOREX, i8imm, GR64_NOREX_NOSP, i32imm, i8imm);
344 let ParserMatchClass = X86Mem8AsmOperand;
345 let OperandType = "OPERAND_MEMORY";
348 // GPRs available for tailcall.
349 // It represents GR32_TC, GR64_TC or GR64_TCW64.
350 def ptr_rc_tailcall : PointerLikeRegClass<2>;
352 // Special i32mem for addresses of load folding tail calls. These are not
353 // allowed to use callee-saved registers since they must be scheduled
354 // after callee-saved register are popped.
355 def i32mem_TC : Operand<i32> {
356 let PrintMethod = "printi32mem";
357 let MIOperandInfo = (ops ptr_rc_tailcall, i8imm, ptr_rc_tailcall,
359 let ParserMatchClass = X86Mem32AsmOperand;
360 let OperandType = "OPERAND_MEMORY";
363 // Special i64mem for addresses of load folding tail calls. These are not
364 // allowed to use callee-saved registers since they must be scheduled
365 // after callee-saved register are popped.
366 def i64mem_TC : Operand<i64> {
367 let PrintMethod = "printi64mem";
368 let MIOperandInfo = (ops ptr_rc_tailcall, i8imm,
369 ptr_rc_tailcall, i32imm, i8imm);
370 let ParserMatchClass = X86Mem64AsmOperand;
371 let OperandType = "OPERAND_MEMORY";
374 let OperandType = "OPERAND_PCREL",
375 ParserMatchClass = X86AbsMemAsmOperand,
376 PrintMethod = "printPCRelImm" in {
377 def i32imm_pcrel : Operand<i32>;
378 def i16imm_pcrel : Operand<i16>;
380 // Branch targets have OtherVT type and print as pc-relative values.
381 def brtarget : Operand<OtherVT>;
382 def brtarget8 : Operand<OtherVT>;
386 // Special parser to detect 16-bit mode to select 16-bit displacement.
387 def X86AbsMem16AsmOperand : AsmOperandClass {
388 let Name = "AbsMem16";
389 let RenderMethod = "addAbsMemOperands";
390 let SuperClasses = [X86AbsMemAsmOperand];
393 // Branch targets have OtherVT type and print as pc-relative values.
394 let OperandType = "OPERAND_PCREL",
395 PrintMethod = "printPCRelImm" in {
396 let ParserMatchClass = X86AbsMem16AsmOperand in
397 def brtarget16 : Operand<OtherVT>;
398 let ParserMatchClass = X86AbsMemAsmOperand in
399 def brtarget32 : Operand<OtherVT>;
402 let RenderMethod = "addSrcIdxOperands" in {
403 def X86SrcIdx8Operand : AsmOperandClass {
404 let Name = "SrcIdx8";
405 let SuperClasses = [X86Mem8AsmOperand];
407 def X86SrcIdx16Operand : AsmOperandClass {
408 let Name = "SrcIdx16";
409 let SuperClasses = [X86Mem16AsmOperand];
411 def X86SrcIdx32Operand : AsmOperandClass {
412 let Name = "SrcIdx32";
413 let SuperClasses = [X86Mem32AsmOperand];
415 def X86SrcIdx64Operand : AsmOperandClass {
416 let Name = "SrcIdx64";
417 let SuperClasses = [X86Mem64AsmOperand];
419 } // RenderMethod = "addSrcIdxOperands"
421 let RenderMethod = "addDstIdxOperands" in {
422 def X86DstIdx8Operand : AsmOperandClass {
423 let Name = "DstIdx8";
424 let SuperClasses = [X86Mem8AsmOperand];
426 def X86DstIdx16Operand : AsmOperandClass {
427 let Name = "DstIdx16";
428 let SuperClasses = [X86Mem16AsmOperand];
430 def X86DstIdx32Operand : AsmOperandClass {
431 let Name = "DstIdx32";
432 let SuperClasses = [X86Mem32AsmOperand];
434 def X86DstIdx64Operand : AsmOperandClass {
435 let Name = "DstIdx64";
436 let SuperClasses = [X86Mem64AsmOperand];
438 } // RenderMethod = "addDstIdxOperands"
440 let RenderMethod = "addMemOffsOperands" in {
441 def X86MemOffs16_8AsmOperand : AsmOperandClass {
442 let Name = "MemOffs16_8";
443 let SuperClasses = [X86Mem8AsmOperand];
445 def X86MemOffs16_16AsmOperand : AsmOperandClass {
446 let Name = "MemOffs16_16";
447 let SuperClasses = [X86Mem16AsmOperand];
449 def X86MemOffs16_32AsmOperand : AsmOperandClass {
450 let Name = "MemOffs16_32";
451 let SuperClasses = [X86Mem32AsmOperand];
453 def X86MemOffs32_8AsmOperand : AsmOperandClass {
454 let Name = "MemOffs32_8";
455 let SuperClasses = [X86Mem8AsmOperand];
457 def X86MemOffs32_16AsmOperand : AsmOperandClass {
458 let Name = "MemOffs32_16";
459 let SuperClasses = [X86Mem16AsmOperand];
461 def X86MemOffs32_32AsmOperand : AsmOperandClass {
462 let Name = "MemOffs32_32";
463 let SuperClasses = [X86Mem32AsmOperand];
465 def X86MemOffs32_64AsmOperand : AsmOperandClass {
466 let Name = "MemOffs32_64";
467 let SuperClasses = [X86Mem64AsmOperand];
469 def X86MemOffs64_8AsmOperand : AsmOperandClass {
470 let Name = "MemOffs64_8";
471 let SuperClasses = [X86Mem8AsmOperand];
473 def X86MemOffs64_16AsmOperand : AsmOperandClass {
474 let Name = "MemOffs64_16";
475 let SuperClasses = [X86Mem16AsmOperand];
477 def X86MemOffs64_32AsmOperand : AsmOperandClass {
478 let Name = "MemOffs64_32";
479 let SuperClasses = [X86Mem32AsmOperand];
481 def X86MemOffs64_64AsmOperand : AsmOperandClass {
482 let Name = "MemOffs64_64";
483 let SuperClasses = [X86Mem64AsmOperand];
485 } // RenderMethod = "addMemOffsOperands"
487 class X86SrcIdxOperand<string printMethod, AsmOperandClass parserMatchClass>
488 : X86MemOperand<printMethod, parserMatchClass> {
489 let MIOperandInfo = (ops ptr_rc, i8imm);
492 class X86DstIdxOperand<string printMethod, AsmOperandClass parserMatchClass>
493 : X86MemOperand<printMethod, parserMatchClass> {
494 let MIOperandInfo = (ops ptr_rc);
497 def srcidx8 : X86SrcIdxOperand<"printSrcIdx8", X86SrcIdx8Operand>;
498 def srcidx16 : X86SrcIdxOperand<"printSrcIdx16", X86SrcIdx16Operand>;
499 def srcidx32 : X86SrcIdxOperand<"printSrcIdx32", X86SrcIdx32Operand>;
500 def srcidx64 : X86SrcIdxOperand<"printSrcIdx64", X86SrcIdx64Operand>;
501 def dstidx8 : X86DstIdxOperand<"printDstIdx8", X86DstIdx8Operand>;
502 def dstidx16 : X86DstIdxOperand<"printDstIdx16", X86DstIdx16Operand>;
503 def dstidx32 : X86DstIdxOperand<"printDstIdx32", X86DstIdx32Operand>;
504 def dstidx64 : X86DstIdxOperand<"printDstIdx64", X86DstIdx64Operand>;
506 class X86MemOffsOperand<Operand immOperand, string printMethod,
507 AsmOperandClass parserMatchClass>
508 : X86MemOperand<printMethod, parserMatchClass> {
509 let MIOperandInfo = (ops immOperand, i8imm);
512 def offset16_8 : X86MemOffsOperand<i16imm, "printMemOffs8",
513 X86MemOffs16_8AsmOperand>;
514 def offset16_16 : X86MemOffsOperand<i16imm, "printMemOffs16",
515 X86MemOffs16_16AsmOperand>;
516 def offset16_32 : X86MemOffsOperand<i16imm, "printMemOffs32",
517 X86MemOffs16_32AsmOperand>;
518 def offset32_8 : X86MemOffsOperand<i32imm, "printMemOffs8",
519 X86MemOffs32_8AsmOperand>;
520 def offset32_16 : X86MemOffsOperand<i32imm, "printMemOffs16",
521 X86MemOffs32_16AsmOperand>;
522 def offset32_32 : X86MemOffsOperand<i32imm, "printMemOffs32",
523 X86MemOffs32_32AsmOperand>;
524 def offset32_64 : X86MemOffsOperand<i32imm, "printMemOffs64",
525 X86MemOffs32_64AsmOperand>;
526 def offset64_8 : X86MemOffsOperand<i64imm, "printMemOffs8",
527 X86MemOffs64_8AsmOperand>;
528 def offset64_16 : X86MemOffsOperand<i64imm, "printMemOffs16",
529 X86MemOffs64_16AsmOperand>;
530 def offset64_32 : X86MemOffsOperand<i64imm, "printMemOffs32",
531 X86MemOffs64_32AsmOperand>;
532 def offset64_64 : X86MemOffsOperand<i64imm, "printMemOffs64",
533 X86MemOffs64_64AsmOperand>;
535 def SSECC : Operand<i8> {
536 let PrintMethod = "printSSEAVXCC";
537 let OperandType = "OPERAND_IMMEDIATE";
540 def i8immZExt3 : ImmLeaf<i8, [{
541 return Imm >= 0 && Imm < 8;
544 def AVXCC : Operand<i8> {
545 let PrintMethod = "printSSEAVXCC";
546 let OperandType = "OPERAND_IMMEDIATE";
549 def i8immZExt5 : ImmLeaf<i8, [{
550 return Imm >= 0 && Imm < 32;
553 def AVX512ICC : Operand<i8> {
554 let PrintMethod = "printSSEAVXCC";
555 let OperandType = "OPERAND_IMMEDIATE";
558 def XOPCC : Operand<i8> {
559 let PrintMethod = "printXOPCC";
560 let OperandType = "OPERAND_IMMEDIATE";
563 class ImmSExtAsmOperandClass : AsmOperandClass {
564 let SuperClasses = [ImmAsmOperand];
565 let RenderMethod = "addImmOperands";
568 def X86GR32orGR64AsmOperand : AsmOperandClass {
569 let Name = "GR32orGR64";
572 def GR32orGR64 : RegisterOperand<GR32> {
573 let ParserMatchClass = X86GR32orGR64AsmOperand;
575 def AVX512RCOperand : AsmOperandClass {
576 let Name = "AVX512RC";
578 def AVX512RC : Operand<i32> {
579 let PrintMethod = "printRoundingControl";
580 let OperandType = "OPERAND_IMMEDIATE";
581 let ParserMatchClass = AVX512RCOperand;
584 // Sign-extended immediate classes. We don't need to define the full lattice
585 // here because there is no instruction with an ambiguity between ImmSExti64i32
588 // The strange ranges come from the fact that the assembler always works with
589 // 64-bit immediates, but for a 16-bit target value we want to accept both "-1"
590 // (which will be a -1ULL), and "0xFF" (-1 in 16-bits).
593 // [0xFFFFFFFF80000000, 0xFFFFFFFFFFFFFFFF]
594 def ImmSExti64i32AsmOperand : ImmSExtAsmOperandClass {
595 let Name = "ImmSExti64i32";
598 // [0, 0x0000007F] | [0x000000000000FF80, 0x000000000000FFFF] |
599 // [0xFFFFFFFFFFFFFF80, 0xFFFFFFFFFFFFFFFF]
600 def ImmSExti16i8AsmOperand : ImmSExtAsmOperandClass {
601 let Name = "ImmSExti16i8";
602 let SuperClasses = [ImmSExti64i32AsmOperand];
605 // [0, 0x0000007F] | [0x00000000FFFFFF80, 0x00000000FFFFFFFF] |
606 // [0xFFFFFFFFFFFFFF80, 0xFFFFFFFFFFFFFFFF]
607 def ImmSExti32i8AsmOperand : ImmSExtAsmOperandClass {
608 let Name = "ImmSExti32i8";
612 // [0xFFFFFFFFFFFFFF80, 0xFFFFFFFFFFFFFFFF]
613 def ImmSExti64i8AsmOperand : ImmSExtAsmOperandClass {
614 let Name = "ImmSExti64i8";
615 let SuperClasses = [ImmSExti16i8AsmOperand, ImmSExti32i8AsmOperand,
616 ImmSExti64i32AsmOperand];
619 // Unsigned immediate used by SSE/AVX instructions
621 // [0xFFFFFFFFFFFFFF80, 0xFFFFFFFFFFFFFFFF]
622 def ImmUnsignedi8AsmOperand : AsmOperandClass {
623 let Name = "ImmUnsignedi8";
624 let RenderMethod = "addImmOperands";
627 // A couple of more descriptive operand definitions.
628 // 16-bits but only 8 bits are significant.
629 def i16i8imm : Operand<i16> {
630 let ParserMatchClass = ImmSExti16i8AsmOperand;
631 let OperandType = "OPERAND_IMMEDIATE";
633 // 32-bits but only 8 bits are significant.
634 def i32i8imm : Operand<i32> {
635 let ParserMatchClass = ImmSExti32i8AsmOperand;
636 let OperandType = "OPERAND_IMMEDIATE";
639 // 64-bits but only 32 bits are significant.
640 def i64i32imm : Operand<i64> {
641 let ParserMatchClass = ImmSExti64i32AsmOperand;
642 let OperandType = "OPERAND_IMMEDIATE";
645 // 64-bits but only 8 bits are significant.
646 def i64i8imm : Operand<i64> {
647 let ParserMatchClass = ImmSExti64i8AsmOperand;
648 let OperandType = "OPERAND_IMMEDIATE";
651 // Unsigned 8-bit immediate used by SSE/AVX instructions.
652 def u8imm : Operand<i8> {
653 let PrintMethod = "printU8Imm";
654 let ParserMatchClass = ImmUnsignedi8AsmOperand;
655 let OperandType = "OPERAND_IMMEDIATE";
658 // 32-bit immediate but only 8-bits are significant and they are unsigned.
659 // Used by some SSE/AVX instructions that use intrinsics.
660 def i32u8imm : Operand<i32> {
661 let PrintMethod = "printU8Imm";
662 let ParserMatchClass = ImmUnsignedi8AsmOperand;
663 let OperandType = "OPERAND_IMMEDIATE";
666 // 64-bits but only 32 bits are significant, and those bits are treated as being
668 def i64i32imm_pcrel : Operand<i64> {
669 let PrintMethod = "printPCRelImm";
670 let ParserMatchClass = X86AbsMemAsmOperand;
671 let OperandType = "OPERAND_PCREL";
674 def lea64_32mem : Operand<i32> {
675 let PrintMethod = "printanymem";
676 let MIOperandInfo = (ops GR64, i8imm, GR64_NOSP, i32imm, i8imm);
677 let ParserMatchClass = X86MemAsmOperand;
680 // Memory operands that use 64-bit pointers in both ILP32 and LP64.
681 def lea64mem : Operand<i64> {
682 let PrintMethod = "printanymem";
683 let MIOperandInfo = (ops GR64, i8imm, GR64_NOSP, i32imm, i8imm);
684 let ParserMatchClass = X86MemAsmOperand;
688 //===----------------------------------------------------------------------===//
689 // X86 Complex Pattern Definitions.
692 // Define X86 specific addressing mode.
693 def addr : ComplexPattern<iPTR, 5, "SelectAddr", [], [SDNPWantParent]>;
694 def lea32addr : ComplexPattern<i32, 5, "SelectLEAAddr",
695 [add, sub, mul, X86mul_imm, shl, or, frameindex],
697 // In 64-bit mode 32-bit LEAs can use RIP-relative addressing.
698 def lea64_32addr : ComplexPattern<i32, 5, "SelectLEA64_32Addr",
699 [add, sub, mul, X86mul_imm, shl, or,
700 frameindex, X86WrapperRIP],
703 def tls32addr : ComplexPattern<i32, 5, "SelectTLSADDRAddr",
704 [tglobaltlsaddr], []>;
706 def tls32baseaddr : ComplexPattern<i32, 5, "SelectTLSADDRAddr",
707 [tglobaltlsaddr], []>;
709 def lea64addr : ComplexPattern<i64, 5, "SelectLEAAddr",
710 [add, sub, mul, X86mul_imm, shl, or, frameindex,
713 def tls64addr : ComplexPattern<i64, 5, "SelectTLSADDRAddr",
714 [tglobaltlsaddr], []>;
716 def tls64baseaddr : ComplexPattern<i64, 5, "SelectTLSADDRAddr",
717 [tglobaltlsaddr], []>;
719 def vectoraddr : ComplexPattern<iPTR, 5, "SelectVectorAddr", [],[SDNPWantParent]>;
721 //===----------------------------------------------------------------------===//
722 // X86 Instruction Predicate Definitions.
723 def HasCMov : Predicate<"Subtarget->hasCMov()">;
724 def NoCMov : Predicate<"!Subtarget->hasCMov()">;
726 def HasMMX : Predicate<"Subtarget->hasMMX()">;
727 def Has3DNow : Predicate<"Subtarget->has3DNow()">;
728 def Has3DNowA : Predicate<"Subtarget->has3DNowA()">;
729 def HasSSE1 : Predicate<"Subtarget->hasSSE1()">;
730 def UseSSE1 : Predicate<"Subtarget->hasSSE1() && !Subtarget->hasAVX()">;
731 def HasSSE2 : Predicate<"Subtarget->hasSSE2()">;
732 def UseSSE2 : Predicate<"Subtarget->hasSSE2() && !Subtarget->hasAVX()">;
733 def HasSSE3 : Predicate<"Subtarget->hasSSE3()">;
734 def UseSSE3 : Predicate<"Subtarget->hasSSE3() && !Subtarget->hasAVX()">;
735 def HasSSSE3 : Predicate<"Subtarget->hasSSSE3()">;
736 def UseSSSE3 : Predicate<"Subtarget->hasSSSE3() && !Subtarget->hasAVX()">;
737 def HasSSE41 : Predicate<"Subtarget->hasSSE41()">;
738 def NoSSE41 : Predicate<"!Subtarget->hasSSE41()">;
739 def UseSSE41 : Predicate<"Subtarget->hasSSE41() && !Subtarget->hasAVX()">;
740 def HasSSE42 : Predicate<"Subtarget->hasSSE42()">;
741 def UseSSE42 : Predicate<"Subtarget->hasSSE42() && !Subtarget->hasAVX()">;
742 def HasSSE4A : Predicate<"Subtarget->hasSSE4A()">;
743 def HasAVX : Predicate<"Subtarget->hasAVX()">;
744 def HasAVX2 : Predicate<"Subtarget->hasAVX2()">;
745 def HasAVX1Only : Predicate<"Subtarget->hasAVX() && !Subtarget->hasAVX2()">;
746 def HasAVX512 : Predicate<"Subtarget->hasAVX512()">,
747 AssemblerPredicate<"FeatureAVX512", "AVX-512 ISA">;
748 def UseAVX : Predicate<"Subtarget->hasAVX() && !Subtarget->hasAVX512()">;
749 def UseAVX2 : Predicate<"Subtarget->hasAVX2() && !Subtarget->hasAVX512()">;
750 def NoAVX512 : Predicate<"!Subtarget->hasAVX512()">;
751 def HasCDI : Predicate<"Subtarget->hasCDI()">,
752 AssemblerPredicate<"FeatureCDI", "AVX-512 CD ISA">;
753 def HasPFI : Predicate<"Subtarget->hasPFI()">,
754 AssemblerPredicate<"FeaturePFI", "AVX-512 PF ISA">;
755 def HasERI : Predicate<"Subtarget->hasERI()">,
756 AssemblerPredicate<"FeatureERI", "AVX-512 ER ISA">;
757 def HasDQI : Predicate<"Subtarget->hasDQI()">,
758 AssemblerPredicate<"FeatureDQI", "AVX-512 DQ ISA">;
759 def NoDQI : Predicate<"!Subtarget->hasDQI()">;
760 def HasBWI : Predicate<"Subtarget->hasBWI()">,
761 AssemblerPredicate<"FeatureBWI", "AVX-512 BW ISA">;
762 def HasVLX : Predicate<"Subtarget->hasVLX()">,
763 AssemblerPredicate<"FeatureVLX", "AVX-512 VL ISA">;
764 def NoVLX : Predicate<"!Subtarget->hasVLX()">;
766 def HasPOPCNT : Predicate<"Subtarget->hasPOPCNT()">;
767 def HasAES : Predicate<"Subtarget->hasAES()">;
768 def HasPCLMUL : Predicate<"Subtarget->hasPCLMUL()">;
769 def HasFMA : Predicate<"Subtarget->hasFMA()">;
770 def UseFMAOnAVX : Predicate<"Subtarget->hasFMA() && !Subtarget->hasAVX512()">;
771 def HasFMA4 : Predicate<"Subtarget->hasFMA4()">;
772 def HasXOP : Predicate<"Subtarget->hasXOP()">;
773 def HasTBM : Predicate<"Subtarget->hasTBM()">;
774 def HasMOVBE : Predicate<"Subtarget->hasMOVBE()">;
775 def HasRDRAND : Predicate<"Subtarget->hasRDRAND()">;
776 def HasF16C : Predicate<"Subtarget->hasF16C()">;
777 def HasFSGSBase : Predicate<"Subtarget->hasFSGSBase()">;
778 def HasLZCNT : Predicate<"Subtarget->hasLZCNT()">;
779 def HasBMI : Predicate<"Subtarget->hasBMI()">;
780 def HasBMI2 : Predicate<"Subtarget->hasBMI2()">;
781 def HasRTM : Predicate<"Subtarget->hasRTM()">;
782 def HasHLE : Predicate<"Subtarget->hasHLE()">;
783 def HasTSX : Predicate<"Subtarget->hasRTM() || Subtarget->hasHLE()">;
784 def HasADX : Predicate<"Subtarget->hasADX()">;
785 def HasSHA : Predicate<"Subtarget->hasSHA()">;
786 def HasPRFCHW : Predicate<"Subtarget->hasPRFCHW()">;
787 def HasRDSEED : Predicate<"Subtarget->hasRDSEED()">;
788 def HasPrefetchW : Predicate<"Subtarget->hasPRFCHW()">;
789 def FPStackf32 : Predicate<"!Subtarget->hasSSE1()">;
790 def FPStackf64 : Predicate<"!Subtarget->hasSSE2()">;
791 def HasMPX : Predicate<"Subtarget->hasMPX()">;
792 def HasCmpxchg16b: Predicate<"Subtarget->hasCmpxchg16b()">;
793 def Not64BitMode : Predicate<"!Subtarget->is64Bit()">,
794 AssemblerPredicate<"!Mode64Bit", "Not 64-bit mode">;
795 def In64BitMode : Predicate<"Subtarget->is64Bit()">,
796 AssemblerPredicate<"Mode64Bit", "64-bit mode">;
797 def IsLP64 : Predicate<"Subtarget->isTarget64BitLP64()">;
798 def NotLP64 : Predicate<"!Subtarget->isTarget64BitLP64()">;
799 def In16BitMode : Predicate<"Subtarget->is16Bit()">,
800 AssemblerPredicate<"Mode16Bit", "16-bit mode">;
801 def Not16BitMode : Predicate<"!Subtarget->is16Bit()">,
802 AssemblerPredicate<"!Mode16Bit", "Not 16-bit mode">;
803 def In32BitMode : Predicate<"Subtarget->is32Bit()">,
804 AssemblerPredicate<"Mode32Bit", "32-bit mode">;
805 def IsWin64 : Predicate<"Subtarget->isTargetWin64()">;
806 def NotWin64 : Predicate<"!Subtarget->isTargetWin64()">;
807 def IsPS4 : Predicate<"Subtarget->isTargetPS4()">;
808 def NotPS4 : Predicate<"!Subtarget->isTargetPS4()">;
809 def IsNaCl : Predicate<"Subtarget->isTargetNaCl()">;
810 def NotNaCl : Predicate<"!Subtarget->isTargetNaCl()">;
811 def SmallCode : Predicate<"TM.getCodeModel() == CodeModel::Small">;
812 def KernelCode : Predicate<"TM.getCodeModel() == CodeModel::Kernel">;
813 def FarData : Predicate<"TM.getCodeModel() != CodeModel::Small &&"
814 "TM.getCodeModel() != CodeModel::Kernel">;
815 def NearData : Predicate<"TM.getCodeModel() == CodeModel::Small ||"
816 "TM.getCodeModel() == CodeModel::Kernel">;
817 def IsStatic : Predicate<"TM.getRelocationModel() == Reloc::Static">;
818 def IsNotPIC : Predicate<"TM.getRelocationModel() != Reloc::PIC_">;
819 def OptForSize : Predicate<"OptForSize">;
820 def OptForSpeed : Predicate<"!OptForSize">;
821 def FastBTMem : Predicate<"!Subtarget->isBTMemSlow()">;
822 def CallImmAddr : Predicate<"Subtarget->IsLegalToCallImmediateAddr(TM)">;
823 def FavorMemIndirectCall : Predicate<"!Subtarget->callRegIndirect()">;
824 def NotSlowIncDec : Predicate<"!Subtarget->slowIncDec()">;
825 def HasFastMem32 : Predicate<"!Subtarget->isUnalignedMem32Slow()">;
827 //===----------------------------------------------------------------------===//
828 // X86 Instruction Format Definitions.
831 include "X86InstrFormats.td"
833 //===----------------------------------------------------------------------===//
834 // Pattern fragments.
837 // X86 specific condition code. These correspond to CondCode in
838 // X86InstrInfo.h. They must be kept in synch.
839 def X86_COND_A : PatLeaf<(i8 0)>; // alt. COND_NBE
840 def X86_COND_AE : PatLeaf<(i8 1)>; // alt. COND_NC
841 def X86_COND_B : PatLeaf<(i8 2)>; // alt. COND_C
842 def X86_COND_BE : PatLeaf<(i8 3)>; // alt. COND_NA
843 def X86_COND_E : PatLeaf<(i8 4)>; // alt. COND_Z
844 def X86_COND_G : PatLeaf<(i8 5)>; // alt. COND_NLE
845 def X86_COND_GE : PatLeaf<(i8 6)>; // alt. COND_NL
846 def X86_COND_L : PatLeaf<(i8 7)>; // alt. COND_NGE
847 def X86_COND_LE : PatLeaf<(i8 8)>; // alt. COND_NG
848 def X86_COND_NE : PatLeaf<(i8 9)>; // alt. COND_NZ
849 def X86_COND_NO : PatLeaf<(i8 10)>;
850 def X86_COND_NP : PatLeaf<(i8 11)>; // alt. COND_PO
851 def X86_COND_NS : PatLeaf<(i8 12)>;
852 def X86_COND_O : PatLeaf<(i8 13)>;
853 def X86_COND_P : PatLeaf<(i8 14)>; // alt. COND_PE
854 def X86_COND_S : PatLeaf<(i8 15)>;
856 // Predicate used to help when pattern matching LZCNT/TZCNT.
857 def X86_COND_E_OR_NE : ImmLeaf<i8, [{
858 return (Imm == X86::COND_E) || (Imm == X86::COND_NE);
862 def i16immSExt8 : ImmLeaf<i16, [{ return Imm == (int8_t)Imm; }]>;
863 def i32immSExt8 : ImmLeaf<i32, [{ return Imm == (int8_t)Imm; }]>;
864 def i64immSExt8 : ImmLeaf<i64, [{ return Imm == (int8_t)Imm; }]>;
867 def i64immSExt32 : ImmLeaf<i64, [{ return Imm == (int32_t)Imm; }]>;
870 // i64immZExt32 predicate - True if the 64-bit immediate fits in a 32-bit
872 def i64immZExt32 : ImmLeaf<i64, [{ return (uint64_t)Imm == (uint32_t)Imm; }]>;
874 def i64immZExt32SExt8 : ImmLeaf<i64, [{
875 return (uint64_t)Imm == (uint32_t)Imm && (int32_t)Imm == (int8_t)Imm;
878 // Helper fragments for loads.
879 // It's always safe to treat a anyext i16 load as a i32 load if the i16 is
880 // known to be 32-bit aligned or better. Ditto for i8 to i16.
881 def loadi16 : PatFrag<(ops node:$ptr), (i16 (unindexedload node:$ptr)), [{
882 LoadSDNode *LD = cast<LoadSDNode>(N);
883 ISD::LoadExtType ExtType = LD->getExtensionType();
884 if (ExtType == ISD::NON_EXTLOAD)
886 if (ExtType == ISD::EXTLOAD)
887 return LD->getAlignment() >= 2 && !LD->isVolatile();
891 def loadi16_anyext : PatFrag<(ops node:$ptr), (i32 (unindexedload node:$ptr)),[{
892 LoadSDNode *LD = cast<LoadSDNode>(N);
893 ISD::LoadExtType ExtType = LD->getExtensionType();
894 if (ExtType == ISD::EXTLOAD)
895 return LD->getAlignment() >= 2 && !LD->isVolatile();
899 def loadi32 : PatFrag<(ops node:$ptr), (i32 (unindexedload node:$ptr)), [{
900 LoadSDNode *LD = cast<LoadSDNode>(N);
901 ISD::LoadExtType ExtType = LD->getExtensionType();
902 if (ExtType == ISD::NON_EXTLOAD)
904 if (ExtType == ISD::EXTLOAD)
905 return LD->getAlignment() >= 4 && !LD->isVolatile();
909 def loadi8 : PatFrag<(ops node:$ptr), (i8 (load node:$ptr))>;
910 def loadi64 : PatFrag<(ops node:$ptr), (i64 (load node:$ptr))>;
911 def loadf32 : PatFrag<(ops node:$ptr), (f32 (load node:$ptr))>;
912 def loadf64 : PatFrag<(ops node:$ptr), (f64 (load node:$ptr))>;
913 def loadf80 : PatFrag<(ops node:$ptr), (f80 (load node:$ptr))>;
915 def sextloadi16i8 : PatFrag<(ops node:$ptr), (i16 (sextloadi8 node:$ptr))>;
916 def sextloadi32i8 : PatFrag<(ops node:$ptr), (i32 (sextloadi8 node:$ptr))>;
917 def sextloadi32i16 : PatFrag<(ops node:$ptr), (i32 (sextloadi16 node:$ptr))>;
918 def sextloadi64i8 : PatFrag<(ops node:$ptr), (i64 (sextloadi8 node:$ptr))>;
919 def sextloadi64i16 : PatFrag<(ops node:$ptr), (i64 (sextloadi16 node:$ptr))>;
920 def sextloadi64i32 : PatFrag<(ops node:$ptr), (i64 (sextloadi32 node:$ptr))>;
922 def zextloadi8i1 : PatFrag<(ops node:$ptr), (i8 (zextloadi1 node:$ptr))>;
923 def zextloadi16i1 : PatFrag<(ops node:$ptr), (i16 (zextloadi1 node:$ptr))>;
924 def zextloadi32i1 : PatFrag<(ops node:$ptr), (i32 (zextloadi1 node:$ptr))>;
925 def zextloadi16i8 : PatFrag<(ops node:$ptr), (i16 (zextloadi8 node:$ptr))>;
926 def zextloadi32i8 : PatFrag<(ops node:$ptr), (i32 (zextloadi8 node:$ptr))>;
927 def zextloadi32i16 : PatFrag<(ops node:$ptr), (i32 (zextloadi16 node:$ptr))>;
928 def zextloadi64i1 : PatFrag<(ops node:$ptr), (i64 (zextloadi1 node:$ptr))>;
929 def zextloadi64i8 : PatFrag<(ops node:$ptr), (i64 (zextloadi8 node:$ptr))>;
930 def zextloadi64i16 : PatFrag<(ops node:$ptr), (i64 (zextloadi16 node:$ptr))>;
931 def zextloadi64i32 : PatFrag<(ops node:$ptr), (i64 (zextloadi32 node:$ptr))>;
933 def extloadi8i1 : PatFrag<(ops node:$ptr), (i8 (extloadi1 node:$ptr))>;
934 def extloadi16i1 : PatFrag<(ops node:$ptr), (i16 (extloadi1 node:$ptr))>;
935 def extloadi32i1 : PatFrag<(ops node:$ptr), (i32 (extloadi1 node:$ptr))>;
936 def extloadi16i8 : PatFrag<(ops node:$ptr), (i16 (extloadi8 node:$ptr))>;
937 def extloadi32i8 : PatFrag<(ops node:$ptr), (i32 (extloadi8 node:$ptr))>;
938 def extloadi32i16 : PatFrag<(ops node:$ptr), (i32 (extloadi16 node:$ptr))>;
939 def extloadi64i1 : PatFrag<(ops node:$ptr), (i64 (extloadi1 node:$ptr))>;
940 def extloadi64i8 : PatFrag<(ops node:$ptr), (i64 (extloadi8 node:$ptr))>;
941 def extloadi64i16 : PatFrag<(ops node:$ptr), (i64 (extloadi16 node:$ptr))>;
942 def extloadi64i32 : PatFrag<(ops node:$ptr), (i64 (extloadi32 node:$ptr))>;
945 // An 'and' node with a single use.
946 def and_su : PatFrag<(ops node:$lhs, node:$rhs), (and node:$lhs, node:$rhs), [{
947 return N->hasOneUse();
949 // An 'srl' node with a single use.
950 def srl_su : PatFrag<(ops node:$lhs, node:$rhs), (srl node:$lhs, node:$rhs), [{
951 return N->hasOneUse();
953 // An 'trunc' node with a single use.
954 def trunc_su : PatFrag<(ops node:$src), (trunc node:$src), [{
955 return N->hasOneUse();
958 //===----------------------------------------------------------------------===//
963 let hasSideEffects = 0, SchedRW = [WriteZero] in {
964 def NOOP : I<0x90, RawFrm, (outs), (ins), "nop", [], IIC_NOP>;
965 def NOOPW : I<0x1f, MRMXm, (outs), (ins i16mem:$zero),
966 "nop{w}\t$zero", [], IIC_NOP>, TB, OpSize16;
967 def NOOPL : I<0x1f, MRMXm, (outs), (ins i32mem:$zero),
968 "nop{l}\t$zero", [], IIC_NOP>, TB, OpSize32;
972 // Constructing a stack frame.
973 def ENTER : Ii16<0xC8, RawFrmImm8, (outs), (ins i16imm:$len, i8imm:$lvl),
974 "enter\t$len, $lvl", [], IIC_ENTER>, Sched<[WriteMicrocoded]>;
976 let SchedRW = [WriteALU] in {
977 let Defs = [EBP, ESP], Uses = [EBP, ESP], mayLoad = 1, hasSideEffects=0 in
978 def LEAVE : I<0xC9, RawFrm,
979 (outs), (ins), "leave", [], IIC_LEAVE>,
980 Requires<[Not64BitMode]>;
982 let Defs = [RBP,RSP], Uses = [RBP,RSP], mayLoad = 1, hasSideEffects = 0 in
983 def LEAVE64 : I<0xC9, RawFrm,
984 (outs), (ins), "leave", [], IIC_LEAVE>,
985 Requires<[In64BitMode]>;
988 //===----------------------------------------------------------------------===//
989 // Miscellaneous Instructions.
992 let Defs = [ESP], Uses = [ESP], hasSideEffects=0 in {
993 let mayLoad = 1, SchedRW = [WriteLoad] in {
994 def POP16r : I<0x58, AddRegFrm, (outs GR16:$reg), (ins), "pop{w}\t$reg", [],
995 IIC_POP_REG16>, OpSize16;
996 def POP32r : I<0x58, AddRegFrm, (outs GR32:$reg), (ins), "pop{l}\t$reg", [],
997 IIC_POP_REG>, OpSize32, Requires<[Not64BitMode]>;
998 def POP16rmr: I<0x8F, MRM0r, (outs GR16:$reg), (ins), "pop{w}\t$reg", [],
999 IIC_POP_REG>, OpSize16;
1000 def POP16rmm: I<0x8F, MRM0m, (outs), (ins i16mem:$dst), "pop{w}\t$dst", [],
1001 IIC_POP_MEM>, OpSize16;
1002 def POP32rmr: I<0x8F, MRM0r, (outs GR32:$reg), (ins), "pop{l}\t$reg", [],
1003 IIC_POP_REG>, OpSize32, Requires<[Not64BitMode]>;
1004 def POP32rmm: I<0x8F, MRM0m, (outs), (ins i32mem:$dst), "pop{l}\t$dst", [],
1005 IIC_POP_MEM>, OpSize32, Requires<[Not64BitMode]>;
1006 } // mayLoad, SchedRW
1008 let mayStore = 1, SchedRW = [WriteStore] in {
1009 def PUSH16r : I<0x50, AddRegFrm, (outs), (ins GR16:$reg), "push{w}\t$reg",[],
1010 IIC_PUSH_REG>, OpSize16;
1011 def PUSH32r : I<0x50, AddRegFrm, (outs), (ins GR32:$reg), "push{l}\t$reg",[],
1012 IIC_PUSH_REG>, OpSize32, Requires<[Not64BitMode]>;
1013 def PUSH16rmr: I<0xFF, MRM6r, (outs), (ins GR16:$reg), "push{w}\t$reg",[],
1014 IIC_PUSH_REG>, OpSize16;
1015 def PUSH16rmm: I<0xFF, MRM6m, (outs), (ins i16mem:$src), "push{w}\t$src",[],
1016 IIC_PUSH_MEM>, OpSize16;
1017 def PUSH32rmr: I<0xFF, MRM6r, (outs), (ins GR32:$reg), "push{l}\t$reg",[],
1018 IIC_PUSH_REG>, OpSize32, Requires<[Not64BitMode]>;
1019 def PUSH32rmm: I<0xFF, MRM6m, (outs), (ins i32mem:$src), "push{l}\t$src",[],
1020 IIC_PUSH_MEM>, OpSize32, Requires<[Not64BitMode]>;
1022 def PUSH16i8 : Ii8<0x6a, RawFrm, (outs), (ins i16i8imm:$imm),
1023 "push{w}\t$imm", [], IIC_PUSH_IMM>, OpSize16,
1024 Requires<[Not64BitMode]>;
1025 def PUSH32i8 : Ii8<0x6a, RawFrm, (outs), (ins i32i8imm:$imm),
1026 "push{l}\t$imm", [], IIC_PUSH_IMM>, OpSize32,
1027 Requires<[Not64BitMode]>;
1028 def PUSHi16 : Ii16<0x68, RawFrm, (outs), (ins i16imm:$imm),
1029 "push{w}\t$imm", [], IIC_PUSH_IMM>, OpSize16,
1030 Requires<[Not64BitMode]>;
1031 def PUSHi32 : Ii32<0x68, RawFrm, (outs), (ins i32imm:$imm),
1032 "push{l}\t$imm", [], IIC_PUSH_IMM>, OpSize32,
1033 Requires<[Not64BitMode]>;
1034 } // mayStore, SchedRW
1037 let Defs = [ESP, EFLAGS], Uses = [ESP], mayLoad = 1, hasSideEffects=0,
1038 SchedRW = [WriteLoad] in {
1039 def POPF16 : I<0x9D, RawFrm, (outs), (ins), "popf{w}", [], IIC_POP_F>,
1041 def POPF32 : I<0x9D, RawFrm, (outs), (ins), "popf{l|d}", [], IIC_POP_FD>,
1042 OpSize32, Requires<[Not64BitMode]>;
1045 let Defs = [ESP], Uses = [ESP, EFLAGS], mayStore = 1, hasSideEffects=0,
1046 SchedRW = [WriteStore] in {
1047 def PUSHF16 : I<0x9C, RawFrm, (outs), (ins), "pushf{w}", [], IIC_PUSH_F>,
1049 def PUSHF32 : I<0x9C, RawFrm, (outs), (ins), "pushf{l|d}", [], IIC_PUSH_F>,
1050 OpSize32, Requires<[Not64BitMode]>;
1053 let Defs = [RSP], Uses = [RSP], hasSideEffects=0 in {
1054 let mayLoad = 1, SchedRW = [WriteLoad] in {
1055 def POP64r : I<0x58, AddRegFrm, (outs GR64:$reg), (ins), "pop{q}\t$reg", [],
1056 IIC_POP_REG>, OpSize32, Requires<[In64BitMode]>;
1057 def POP64rmr: I<0x8F, MRM0r, (outs GR64:$reg), (ins), "pop{q}\t$reg", [],
1058 IIC_POP_REG>, OpSize32, Requires<[In64BitMode]>;
1059 def POP64rmm: I<0x8F, MRM0m, (outs), (ins i64mem:$dst), "pop{q}\t$dst", [],
1060 IIC_POP_MEM>, OpSize32, Requires<[In64BitMode]>;
1061 } // mayLoad, SchedRW
1062 let mayStore = 1, SchedRW = [WriteStore] in {
1063 def PUSH64r : I<0x50, AddRegFrm, (outs), (ins GR64:$reg), "push{q}\t$reg", [],
1064 IIC_PUSH_REG>, OpSize32, Requires<[In64BitMode]>;
1065 def PUSH64rmr: I<0xFF, MRM6r, (outs), (ins GR64:$reg), "push{q}\t$reg", [],
1066 IIC_PUSH_REG>, OpSize32, Requires<[In64BitMode]>;
1067 def PUSH64rmm: I<0xFF, MRM6m, (outs), (ins i64mem:$src), "push{q}\t$src", [],
1068 IIC_PUSH_MEM>, OpSize32, Requires<[In64BitMode]>;
1069 } // mayStore, SchedRW
1072 let Defs = [RSP], Uses = [RSP], hasSideEffects = 0, mayStore = 1,
1073 SchedRW = [WriteStore] in {
1074 def PUSH64i8 : Ii8<0x6a, RawFrm, (outs), (ins i64i8imm:$imm),
1075 "push{q}\t$imm", [], IIC_PUSH_IMM>, Requires<[In64BitMode]>;
1076 def PUSH64i16 : Ii16<0x68, RawFrm, (outs), (ins i16imm:$imm),
1077 "push{w}\t$imm", [], IIC_PUSH_IMM>, OpSize16,
1078 Requires<[In64BitMode]>;
1079 def PUSH64i32 : Ii32S<0x68, RawFrm, (outs), (ins i64i32imm:$imm),
1080 "push{q}\t$imm", [], IIC_PUSH_IMM>, OpSize32,
1081 Requires<[In64BitMode]>;
1084 let Defs = [RSP, EFLAGS], Uses = [RSP], mayLoad = 1, hasSideEffects=0 in
1085 def POPF64 : I<0x9D, RawFrm, (outs), (ins), "popfq", [], IIC_POP_FD>,
1086 OpSize32, Requires<[In64BitMode]>, Sched<[WriteLoad]>;
1087 let Defs = [RSP], Uses = [RSP, EFLAGS], mayStore = 1, hasSideEffects=0 in
1088 def PUSHF64 : I<0x9C, RawFrm, (outs), (ins), "pushfq", [], IIC_PUSH_F>,
1089 OpSize32, Requires<[In64BitMode]>, Sched<[WriteStore]>;
1091 let Defs = [EDI, ESI, EBP, EBX, EDX, ECX, EAX, ESP], Uses = [ESP],
1092 mayLoad = 1, hasSideEffects = 0, SchedRW = [WriteLoad] in {
1093 def POPA32 : I<0x61, RawFrm, (outs), (ins), "popal", [], IIC_POP_A>,
1094 OpSize32, Requires<[Not64BitMode]>;
1095 def POPA16 : I<0x61, RawFrm, (outs), (ins), "popaw", [], IIC_POP_A>,
1096 OpSize16, Requires<[Not64BitMode]>;
1098 let Defs = [ESP], Uses = [EDI, ESI, EBP, EBX, EDX, ECX, EAX, ESP],
1099 mayStore = 1, hasSideEffects = 0, SchedRW = [WriteStore] in {
1100 def PUSHA32 : I<0x60, RawFrm, (outs), (ins), "pushal", [], IIC_PUSH_A>,
1101 OpSize32, Requires<[Not64BitMode]>;
1102 def PUSHA16 : I<0x60, RawFrm, (outs), (ins), "pushaw", [], IIC_PUSH_A>,
1103 OpSize16, Requires<[Not64BitMode]>;
1106 let Constraints = "$src = $dst", SchedRW = [WriteALU] in {
1107 // GR32 = bswap GR32
1108 def BSWAP32r : I<0xC8, AddRegFrm,
1109 (outs GR32:$dst), (ins GR32:$src),
1111 [(set GR32:$dst, (bswap GR32:$src))], IIC_BSWAP>, OpSize32, TB;
1113 def BSWAP64r : RI<0xC8, AddRegFrm, (outs GR64:$dst), (ins GR64:$src),
1115 [(set GR64:$dst, (bswap GR64:$src))], IIC_BSWAP>, TB;
1116 } // Constraints = "$src = $dst", SchedRW
1118 // Bit scan instructions.
1119 let Defs = [EFLAGS] in {
1120 def BSF16rr : I<0xBC, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
1121 "bsf{w}\t{$src, $dst|$dst, $src}",
1122 [(set GR16:$dst, EFLAGS, (X86bsf GR16:$src))],
1123 IIC_BIT_SCAN_REG>, PS, OpSize16, Sched<[WriteShift]>;
1124 def BSF16rm : I<0xBC, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
1125 "bsf{w}\t{$src, $dst|$dst, $src}",
1126 [(set GR16:$dst, EFLAGS, (X86bsf (loadi16 addr:$src)))],
1127 IIC_BIT_SCAN_MEM>, PS, OpSize16, Sched<[WriteShiftLd]>;
1128 def BSF32rr : I<0xBC, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
1129 "bsf{l}\t{$src, $dst|$dst, $src}",
1130 [(set GR32:$dst, EFLAGS, (X86bsf GR32:$src))],
1131 IIC_BIT_SCAN_REG>, PS, OpSize32, Sched<[WriteShift]>;
1132 def BSF32rm : I<0xBC, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
1133 "bsf{l}\t{$src, $dst|$dst, $src}",
1134 [(set GR32:$dst, EFLAGS, (X86bsf (loadi32 addr:$src)))],
1135 IIC_BIT_SCAN_MEM>, PS, OpSize32, Sched<[WriteShiftLd]>;
1136 def BSF64rr : RI<0xBC, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
1137 "bsf{q}\t{$src, $dst|$dst, $src}",
1138 [(set GR64:$dst, EFLAGS, (X86bsf GR64:$src))],
1139 IIC_BIT_SCAN_REG>, PS, Sched<[WriteShift]>;
1140 def BSF64rm : RI<0xBC, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
1141 "bsf{q}\t{$src, $dst|$dst, $src}",
1142 [(set GR64:$dst, EFLAGS, (X86bsf (loadi64 addr:$src)))],
1143 IIC_BIT_SCAN_MEM>, PS, Sched<[WriteShiftLd]>;
1145 def BSR16rr : I<0xBD, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
1146 "bsr{w}\t{$src, $dst|$dst, $src}",
1147 [(set GR16:$dst, EFLAGS, (X86bsr GR16:$src))],
1148 IIC_BIT_SCAN_REG>, PS, OpSize16, Sched<[WriteShift]>;
1149 def BSR16rm : I<0xBD, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
1150 "bsr{w}\t{$src, $dst|$dst, $src}",
1151 [(set GR16:$dst, EFLAGS, (X86bsr (loadi16 addr:$src)))],
1152 IIC_BIT_SCAN_MEM>, PS, OpSize16, Sched<[WriteShiftLd]>;
1153 def BSR32rr : I<0xBD, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
1154 "bsr{l}\t{$src, $dst|$dst, $src}",
1155 [(set GR32:$dst, EFLAGS, (X86bsr GR32:$src))],
1156 IIC_BIT_SCAN_REG>, PS, OpSize32, Sched<[WriteShift]>;
1157 def BSR32rm : I<0xBD, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
1158 "bsr{l}\t{$src, $dst|$dst, $src}",
1159 [(set GR32:$dst, EFLAGS, (X86bsr (loadi32 addr:$src)))],
1160 IIC_BIT_SCAN_MEM>, PS, OpSize32, Sched<[WriteShiftLd]>;
1161 def BSR64rr : RI<0xBD, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
1162 "bsr{q}\t{$src, $dst|$dst, $src}",
1163 [(set GR64:$dst, EFLAGS, (X86bsr GR64:$src))],
1164 IIC_BIT_SCAN_REG>, PS, Sched<[WriteShift]>;
1165 def BSR64rm : RI<0xBD, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
1166 "bsr{q}\t{$src, $dst|$dst, $src}",
1167 [(set GR64:$dst, EFLAGS, (X86bsr (loadi64 addr:$src)))],
1168 IIC_BIT_SCAN_MEM>, PS, Sched<[WriteShiftLd]>;
1169 } // Defs = [EFLAGS]
1171 let SchedRW = [WriteMicrocoded] in {
1172 // These uses the DF flag in the EFLAGS register to inc or dec EDI and ESI
1173 let Defs = [EDI,ESI], Uses = [EDI,ESI,EFLAGS] in {
1174 def MOVSB : I<0xA4, RawFrmDstSrc, (outs dstidx8:$dst), (ins srcidx8:$src),
1175 "movsb\t{$src, $dst|$dst, $src}", [], IIC_MOVS>;
1176 def MOVSW : I<0xA5, RawFrmDstSrc, (outs dstidx16:$dst), (ins srcidx16:$src),
1177 "movsw\t{$src, $dst|$dst, $src}", [], IIC_MOVS>, OpSize16;
1178 def MOVSL : I<0xA5, RawFrmDstSrc, (outs dstidx32:$dst), (ins srcidx32:$src),
1179 "movs{l|d}\t{$src, $dst|$dst, $src}", [], IIC_MOVS>, OpSize32;
1180 def MOVSQ : RI<0xA5, RawFrmDstSrc, (outs dstidx64:$dst), (ins srcidx64:$src),
1181 "movsq\t{$src, $dst|$dst, $src}", [], IIC_MOVS>;
1184 // These uses the DF flag in the EFLAGS register to inc or dec EDI and ESI
1185 let Defs = [EDI], Uses = [AL,EDI,EFLAGS] in
1186 def STOSB : I<0xAA, RawFrmDst, (outs dstidx8:$dst), (ins),
1187 "stosb\t{%al, $dst|$dst, al}", [], IIC_STOS>;
1188 let Defs = [EDI], Uses = [AX,EDI,EFLAGS] in
1189 def STOSW : I<0xAB, RawFrmDst, (outs dstidx16:$dst), (ins),
1190 "stosw\t{%ax, $dst|$dst, ax}", [], IIC_STOS>, OpSize16;
1191 let Defs = [EDI], Uses = [EAX,EDI,EFLAGS] in
1192 def STOSL : I<0xAB, RawFrmDst, (outs dstidx32:$dst), (ins),
1193 "stos{l|d}\t{%eax, $dst|$dst, eax}", [], IIC_STOS>, OpSize32;
1194 let Defs = [RCX,RDI], Uses = [RAX,RCX,RDI,EFLAGS] in
1195 def STOSQ : RI<0xAB, RawFrmDst, (outs dstidx64:$dst), (ins),
1196 "stosq\t{%rax, $dst|$dst, rax}", [], IIC_STOS>;
1198 // These uses the DF flag in the EFLAGS register to inc or dec EDI and ESI
1199 let Defs = [EDI,EFLAGS], Uses = [AL,EDI,EFLAGS] in
1200 def SCASB : I<0xAE, RawFrmDst, (outs), (ins dstidx8:$dst),
1201 "scasb\t{$dst, %al|al, $dst}", [], IIC_SCAS>;
1202 let Defs = [EDI,EFLAGS], Uses = [AX,EDI,EFLAGS] in
1203 def SCASW : I<0xAF, RawFrmDst, (outs), (ins dstidx16:$dst),
1204 "scasw\t{$dst, %ax|ax, $dst}", [], IIC_SCAS>, OpSize16;
1205 let Defs = [EDI,EFLAGS], Uses = [EAX,EDI,EFLAGS] in
1206 def SCASL : I<0xAF, RawFrmDst, (outs), (ins dstidx32:$dst),
1207 "scas{l|d}\t{$dst, %eax|eax, $dst}", [], IIC_SCAS>, OpSize32;
1208 let Defs = [EDI,EFLAGS], Uses = [RAX,EDI,EFLAGS] in
1209 def SCASQ : RI<0xAF, RawFrmDst, (outs), (ins dstidx64:$dst),
1210 "scasq\t{$dst, %rax|rax, $dst}", [], IIC_SCAS>;
1212 // These uses the DF flag in the EFLAGS register to inc or dec EDI and ESI
1213 let Defs = [EDI,ESI,EFLAGS], Uses = [EDI,ESI,EFLAGS] in {
1214 def CMPSB : I<0xA6, RawFrmDstSrc, (outs), (ins dstidx8:$dst, srcidx8:$src),
1215 "cmpsb\t{$dst, $src|$src, $dst}", [], IIC_CMPS>;
1216 def CMPSW : I<0xA7, RawFrmDstSrc, (outs), (ins dstidx16:$dst, srcidx16:$src),
1217 "cmpsw\t{$dst, $src|$src, $dst}", [], IIC_CMPS>, OpSize16;
1218 def CMPSL : I<0xA7, RawFrmDstSrc, (outs), (ins dstidx32:$dst, srcidx32:$src),
1219 "cmps{l|d}\t{$dst, $src|$src, $dst}", [], IIC_CMPS>, OpSize32;
1220 def CMPSQ : RI<0xA7, RawFrmDstSrc, (outs), (ins dstidx64:$dst, srcidx64:$src),
1221 "cmpsq\t{$dst, $src|$src, $dst}", [], IIC_CMPS>;
1225 //===----------------------------------------------------------------------===//
1226 // Move Instructions.
1228 let SchedRW = [WriteMove] in {
1229 let hasSideEffects = 0 in {
1230 def MOV8rr : I<0x88, MRMDestReg, (outs GR8 :$dst), (ins GR8 :$src),
1231 "mov{b}\t{$src, $dst|$dst, $src}", [], IIC_MOV>;
1232 def MOV16rr : I<0x89, MRMDestReg, (outs GR16:$dst), (ins GR16:$src),
1233 "mov{w}\t{$src, $dst|$dst, $src}", [], IIC_MOV>, OpSize16;
1234 def MOV32rr : I<0x89, MRMDestReg, (outs GR32:$dst), (ins GR32:$src),
1235 "mov{l}\t{$src, $dst|$dst, $src}", [], IIC_MOV>, OpSize32;
1236 def MOV64rr : RI<0x89, MRMDestReg, (outs GR64:$dst), (ins GR64:$src),
1237 "mov{q}\t{$src, $dst|$dst, $src}", [], IIC_MOV>;
1240 let isReMaterializable = 1, isAsCheapAsAMove = 1 in {
1241 def MOV8ri : Ii8 <0xB0, AddRegFrm, (outs GR8 :$dst), (ins i8imm :$src),
1242 "mov{b}\t{$src, $dst|$dst, $src}",
1243 [(set GR8:$dst, imm:$src)], IIC_MOV>;
1244 def MOV16ri : Ii16<0xB8, AddRegFrm, (outs GR16:$dst), (ins i16imm:$src),
1245 "mov{w}\t{$src, $dst|$dst, $src}",
1246 [(set GR16:$dst, imm:$src)], IIC_MOV>, OpSize16;
1247 def MOV32ri : Ii32<0xB8, AddRegFrm, (outs GR32:$dst), (ins i32imm:$src),
1248 "mov{l}\t{$src, $dst|$dst, $src}",
1249 [(set GR32:$dst, imm:$src)], IIC_MOV>, OpSize32;
1250 def MOV64ri32 : RIi32S<0xC7, MRM0r, (outs GR64:$dst), (ins i64i32imm:$src),
1251 "mov{q}\t{$src, $dst|$dst, $src}",
1252 [(set GR64:$dst, i64immSExt32:$src)], IIC_MOV>;
1254 let isReMaterializable = 1 in {
1255 def MOV64ri : RIi64<0xB8, AddRegFrm, (outs GR64:$dst), (ins i64imm:$src),
1256 "movabs{q}\t{$src, $dst|$dst, $src}",
1257 [(set GR64:$dst, imm:$src)], IIC_MOV>;
1260 // Longer forms that use a ModR/M byte. Needed for disassembler
1261 let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0 in {
1262 def MOV8ri_alt : Ii8 <0xC6, MRM0r, (outs GR8 :$dst), (ins i8imm :$src),
1263 "mov{b}\t{$src, $dst|$dst, $src}", [], IIC_MOV>;
1264 def MOV16ri_alt : Ii16<0xC7, MRM0r, (outs GR16:$dst), (ins i16imm:$src),
1265 "mov{w}\t{$src, $dst|$dst, $src}", [], IIC_MOV>, OpSize16;
1266 def MOV32ri_alt : Ii32<0xC7, MRM0r, (outs GR32:$dst), (ins i32imm:$src),
1267 "mov{l}\t{$src, $dst|$dst, $src}", [], IIC_MOV>, OpSize32;
1271 let SchedRW = [WriteStore] in {
1272 def MOV8mi : Ii8 <0xC6, MRM0m, (outs), (ins i8mem :$dst, i8imm :$src),
1273 "mov{b}\t{$src, $dst|$dst, $src}",
1274 [(store (i8 imm:$src), addr:$dst)], IIC_MOV_MEM>;
1275 def MOV16mi : Ii16<0xC7, MRM0m, (outs), (ins i16mem:$dst, i16imm:$src),
1276 "mov{w}\t{$src, $dst|$dst, $src}",
1277 [(store (i16 imm:$src), addr:$dst)], IIC_MOV_MEM>, OpSize16;
1278 def MOV32mi : Ii32<0xC7, MRM0m, (outs), (ins i32mem:$dst, i32imm:$src),
1279 "mov{l}\t{$src, $dst|$dst, $src}",
1280 [(store (i32 imm:$src), addr:$dst)], IIC_MOV_MEM>, OpSize32;
1281 def MOV64mi32 : RIi32S<0xC7, MRM0m, (outs), (ins i64mem:$dst, i64i32imm:$src),
1282 "mov{q}\t{$src, $dst|$dst, $src}",
1283 [(store i64immSExt32:$src, addr:$dst)], IIC_MOV_MEM>;
1286 let hasSideEffects = 0 in {
1288 /// Memory offset versions of moves. The immediate is an address mode sized
1289 /// offset from the segment base.
1290 let SchedRW = [WriteALU] in {
1291 let mayLoad = 1 in {
1293 def MOV8ao32 : Ii32<0xA0, RawFrmMemOffs, (outs), (ins offset32_8:$src),
1294 "mov{b}\t{$src, %al|al, $src}", [], IIC_MOV_MEM>,
1297 def MOV16ao32 : Ii32<0xA1, RawFrmMemOffs, (outs), (ins offset32_16:$src),
1298 "mov{w}\t{$src, %ax|ax, $src}", [], IIC_MOV_MEM>,
1301 def MOV32ao32 : Ii32<0xA1, RawFrmMemOffs, (outs), (ins offset32_32:$src),
1302 "mov{l}\t{$src, %eax|eax, $src}", [], IIC_MOV_MEM>,
1305 def MOV64ao32 : RIi32<0xA1, RawFrmMemOffs, (outs), (ins offset32_64:$src),
1306 "mov{q}\t{$src, %rax|rax, $src}", [], IIC_MOV_MEM>,
1310 def MOV8ao16 : Ii16<0xA0, RawFrmMemOffs, (outs), (ins offset16_8:$src),
1311 "mov{b}\t{$src, %al|al, $src}", [], IIC_MOV_MEM>, AdSize16;
1313 def MOV16ao16 : Ii16<0xA1, RawFrmMemOffs, (outs), (ins offset16_16:$src),
1314 "mov{w}\t{$src, %ax|ax, $src}", [], IIC_MOV_MEM>,
1317 def MOV32ao16 : Ii16<0xA1, RawFrmMemOffs, (outs), (ins offset16_32:$src),
1318 "mov{l}\t{$src, %eax|eax, $src}", [], IIC_MOV_MEM>,
1321 let mayStore = 1 in {
1323 def MOV8o32a : Ii32<0xA2, RawFrmMemOffs, (outs offset32_8:$dst), (ins),
1324 "mov{b}\t{%al, $dst|$dst, al}", [], IIC_MOV_MEM>, AdSize32;
1326 def MOV16o32a : Ii32<0xA3, RawFrmMemOffs, (outs offset32_16:$dst), (ins),
1327 "mov{w}\t{%ax, $dst|$dst, ax}", [], IIC_MOV_MEM>,
1330 def MOV32o32a : Ii32<0xA3, RawFrmMemOffs, (outs offset32_32:$dst), (ins),
1331 "mov{l}\t{%eax, $dst|$dst, eax}", [], IIC_MOV_MEM>,
1334 def MOV64o32a : RIi32<0xA3, RawFrmMemOffs, (outs offset32_64:$dst), (ins),
1335 "mov{q}\t{%rax, $dst|$dst, rax}", [], IIC_MOV_MEM>,
1339 def MOV8o16a : Ii16<0xA2, RawFrmMemOffs, (outs offset16_8:$dst), (ins),
1340 "mov{b}\t{%al, $dst|$dst, al}", [], IIC_MOV_MEM>, AdSize16;
1342 def MOV16o16a : Ii16<0xA3, RawFrmMemOffs, (outs offset16_16:$dst), (ins),
1343 "mov{w}\t{%ax, $dst|$dst, ax}", [], IIC_MOV_MEM>,
1346 def MOV32o16a : Ii16<0xA3, RawFrmMemOffs, (outs offset16_32:$dst), (ins),
1347 "mov{l}\t{%eax, $dst|$dst, eax}", [], IIC_MOV_MEM>,
1352 // These forms all have full 64-bit absolute addresses in their instructions
1353 // and use the movabs mnemonic to indicate this specific form.
1354 let mayLoad = 1 in {
1356 def MOV8ao64 : RIi64_NOREX<0xA0, RawFrmMemOffs, (outs), (ins offset64_8:$src),
1357 "movabs{b}\t{$src, %al|al, $src}", []>, AdSize64;
1359 def MOV16ao64 : RIi64_NOREX<0xA1, RawFrmMemOffs, (outs), (ins offset64_16:$src),
1360 "movabs{w}\t{$src, %ax|ax, $src}", []>, OpSize16, AdSize64;
1362 def MOV32ao64 : RIi64_NOREX<0xA1, RawFrmMemOffs, (outs), (ins offset64_32:$src),
1363 "movabs{l}\t{$src, %eax|eax, $src}", []>, OpSize32,
1366 def MOV64ao64 : RIi64<0xA1, RawFrmMemOffs, (outs), (ins offset64_64:$src),
1367 "movabs{q}\t{$src, %rax|rax, $src}", []>, AdSize64;
1370 let mayStore = 1 in {
1372 def MOV8o64a : RIi64_NOREX<0xA2, RawFrmMemOffs, (outs offset64_8:$dst), (ins),
1373 "movabs{b}\t{%al, $dst|$dst, al}", []>, AdSize64;
1375 def MOV16o64a : RIi64_NOREX<0xA3, RawFrmMemOffs, (outs offset64_16:$dst), (ins),
1376 "movabs{w}\t{%ax, $dst|$dst, ax}", []>, OpSize16, AdSize64;
1378 def MOV32o64a : RIi64_NOREX<0xA3, RawFrmMemOffs, (outs offset64_32:$dst), (ins),
1379 "movabs{l}\t{%eax, $dst|$dst, eax}", []>, OpSize32,
1382 def MOV64o64a : RIi64<0xA3, RawFrmMemOffs, (outs offset64_64:$dst), (ins),
1383 "movabs{q}\t{%rax, $dst|$dst, rax}", []>, AdSize64;
1385 } // hasSideEffects = 0
1387 let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0,
1388 SchedRW = [WriteMove] in {
1389 def MOV8rr_REV : I<0x8A, MRMSrcReg, (outs GR8:$dst), (ins GR8:$src),
1390 "mov{b}\t{$src, $dst|$dst, $src}", [], IIC_MOV>;
1391 def MOV16rr_REV : I<0x8B, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
1392 "mov{w}\t{$src, $dst|$dst, $src}", [], IIC_MOV>, OpSize16;
1393 def MOV32rr_REV : I<0x8B, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
1394 "mov{l}\t{$src, $dst|$dst, $src}", [], IIC_MOV>, OpSize32;
1395 def MOV64rr_REV : RI<0x8B, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
1396 "mov{q}\t{$src, $dst|$dst, $src}", [], IIC_MOV>;
1399 let canFoldAsLoad = 1, isReMaterializable = 1, SchedRW = [WriteLoad] in {
1400 def MOV8rm : I<0x8A, MRMSrcMem, (outs GR8 :$dst), (ins i8mem :$src),
1401 "mov{b}\t{$src, $dst|$dst, $src}",
1402 [(set GR8:$dst, (loadi8 addr:$src))], IIC_MOV_MEM>;
1403 def MOV16rm : I<0x8B, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
1404 "mov{w}\t{$src, $dst|$dst, $src}",
1405 [(set GR16:$dst, (loadi16 addr:$src))], IIC_MOV_MEM>, OpSize16;
1406 def MOV32rm : I<0x8B, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
1407 "mov{l}\t{$src, $dst|$dst, $src}",
1408 [(set GR32:$dst, (loadi32 addr:$src))], IIC_MOV_MEM>, OpSize32;
1409 def MOV64rm : RI<0x8B, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
1410 "mov{q}\t{$src, $dst|$dst, $src}",
1411 [(set GR64:$dst, (load addr:$src))], IIC_MOV_MEM>;
1414 let SchedRW = [WriteStore] in {
1415 def MOV8mr : I<0x88, MRMDestMem, (outs), (ins i8mem :$dst, GR8 :$src),
1416 "mov{b}\t{$src, $dst|$dst, $src}",
1417 [(store GR8:$src, addr:$dst)], IIC_MOV_MEM>;
1418 def MOV16mr : I<0x89, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src),
1419 "mov{w}\t{$src, $dst|$dst, $src}",
1420 [(store GR16:$src, addr:$dst)], IIC_MOV_MEM>, OpSize16;
1421 def MOV32mr : I<0x89, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
1422 "mov{l}\t{$src, $dst|$dst, $src}",
1423 [(store GR32:$src, addr:$dst)], IIC_MOV_MEM>, OpSize32;
1424 def MOV64mr : RI<0x89, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
1425 "mov{q}\t{$src, $dst|$dst, $src}",
1426 [(store GR64:$src, addr:$dst)], IIC_MOV_MEM>;
1429 // Versions of MOV8rr, MOV8mr, and MOV8rm that use i8mem_NOREX and GR8_NOREX so
1430 // that they can be used for copying and storing h registers, which can't be
1431 // encoded when a REX prefix is present.
1432 let isCodeGenOnly = 1 in {
1433 let hasSideEffects = 0 in
1434 def MOV8rr_NOREX : I<0x88, MRMDestReg,
1435 (outs GR8_NOREX:$dst), (ins GR8_NOREX:$src),
1436 "mov{b}\t{$src, $dst|$dst, $src} # NOREX", [], IIC_MOV>,
1438 let mayStore = 1, hasSideEffects = 0 in
1439 def MOV8mr_NOREX : I<0x88, MRMDestMem,
1440 (outs), (ins i8mem_NOREX:$dst, GR8_NOREX:$src),
1441 "mov{b}\t{$src, $dst|$dst, $src} # NOREX", [],
1442 IIC_MOV_MEM>, Sched<[WriteStore]>;
1443 let mayLoad = 1, hasSideEffects = 0,
1444 canFoldAsLoad = 1, isReMaterializable = 1 in
1445 def MOV8rm_NOREX : I<0x8A, MRMSrcMem,
1446 (outs GR8_NOREX:$dst), (ins i8mem_NOREX:$src),
1447 "mov{b}\t{$src, $dst|$dst, $src} # NOREX", [],
1448 IIC_MOV_MEM>, Sched<[WriteLoad]>;
1452 // Condition code ops, incl. set if equal/not equal/...
1453 let SchedRW = [WriteALU] in {
1454 let Defs = [EFLAGS], Uses = [AH] in
1455 def SAHF : I<0x9E, RawFrm, (outs), (ins), "sahf",
1456 [(set EFLAGS, (X86sahf AH))], IIC_AHF>;
1457 let Defs = [AH], Uses = [EFLAGS], hasSideEffects = 0 in
1458 def LAHF : I<0x9F, RawFrm, (outs), (ins), "lahf", [],
1459 IIC_AHF>; // AH = flags
1462 //===----------------------------------------------------------------------===//
1463 // Bit tests instructions: BT, BTS, BTR, BTC.
1465 let Defs = [EFLAGS] in {
1466 let SchedRW = [WriteALU] in {
1467 def BT16rr : I<0xA3, MRMDestReg, (outs), (ins GR16:$src1, GR16:$src2),
1468 "bt{w}\t{$src2, $src1|$src1, $src2}",
1469 [(set EFLAGS, (X86bt GR16:$src1, GR16:$src2))], IIC_BT_RR>,
1471 def BT32rr : I<0xA3, MRMDestReg, (outs), (ins GR32:$src1, GR32:$src2),
1472 "bt{l}\t{$src2, $src1|$src1, $src2}",
1473 [(set EFLAGS, (X86bt GR32:$src1, GR32:$src2))], IIC_BT_RR>,
1475 def BT64rr : RI<0xA3, MRMDestReg, (outs), (ins GR64:$src1, GR64:$src2),
1476 "bt{q}\t{$src2, $src1|$src1, $src2}",
1477 [(set EFLAGS, (X86bt GR64:$src1, GR64:$src2))], IIC_BT_RR>, TB;
1480 // Unlike with the register+register form, the memory+register form of the
1481 // bt instruction does not ignore the high bits of the index. From ISel's
1482 // perspective, this is pretty bizarre. Make these instructions disassembly
1485 let mayLoad = 1, hasSideEffects = 0, SchedRW = [WriteALULd] in {
1486 def BT16mr : I<0xA3, MRMDestMem, (outs), (ins i16mem:$src1, GR16:$src2),
1487 "bt{w}\t{$src2, $src1|$src1, $src2}",
1488 // [(X86bt (loadi16 addr:$src1), GR16:$src2),
1489 // (implicit EFLAGS)]
1491 >, OpSize16, TB, Requires<[FastBTMem]>;
1492 def BT32mr : I<0xA3, MRMDestMem, (outs), (ins i32mem:$src1, GR32:$src2),
1493 "bt{l}\t{$src2, $src1|$src1, $src2}",
1494 // [(X86bt (loadi32 addr:$src1), GR32:$src2),
1495 // (implicit EFLAGS)]
1497 >, OpSize32, TB, Requires<[FastBTMem]>;
1498 def BT64mr : RI<0xA3, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2),
1499 "bt{q}\t{$src2, $src1|$src1, $src2}",
1500 // [(X86bt (loadi64 addr:$src1), GR64:$src2),
1501 // (implicit EFLAGS)]
1506 let SchedRW = [WriteALU] in {
1507 def BT16ri8 : Ii8<0xBA, MRM4r, (outs), (ins GR16:$src1, i16i8imm:$src2),
1508 "bt{w}\t{$src2, $src1|$src1, $src2}",
1509 [(set EFLAGS, (X86bt GR16:$src1, i16immSExt8:$src2))],
1510 IIC_BT_RI>, OpSize16, TB;
1511 def BT32ri8 : Ii8<0xBA, MRM4r, (outs), (ins GR32:$src1, i32i8imm:$src2),
1512 "bt{l}\t{$src2, $src1|$src1, $src2}",
1513 [(set EFLAGS, (X86bt GR32:$src1, i32immSExt8:$src2))],
1514 IIC_BT_RI>, OpSize32, TB;
1515 def BT64ri8 : RIi8<0xBA, MRM4r, (outs), (ins GR64:$src1, i64i8imm:$src2),
1516 "bt{q}\t{$src2, $src1|$src1, $src2}",
1517 [(set EFLAGS, (X86bt GR64:$src1, i64immSExt8:$src2))],
1521 // Note that these instructions don't need FastBTMem because that
1522 // only applies when the other operand is in a register. When it's
1523 // an immediate, bt is still fast.
1524 let SchedRW = [WriteALU] in {
1525 def BT16mi8 : Ii8<0xBA, MRM4m, (outs), (ins i16mem:$src1, i16i8imm:$src2),
1526 "bt{w}\t{$src2, $src1|$src1, $src2}",
1527 [(set EFLAGS, (X86bt (loadi16 addr:$src1), i16immSExt8:$src2))
1528 ], IIC_BT_MI>, OpSize16, TB;
1529 def BT32mi8 : Ii8<0xBA, MRM4m, (outs), (ins i32mem:$src1, i32i8imm:$src2),
1530 "bt{l}\t{$src2, $src1|$src1, $src2}",
1531 [(set EFLAGS, (X86bt (loadi32 addr:$src1), i32immSExt8:$src2))
1532 ], IIC_BT_MI>, OpSize32, TB;
1533 def BT64mi8 : RIi8<0xBA, MRM4m, (outs), (ins i64mem:$src1, i64i8imm:$src2),
1534 "bt{q}\t{$src2, $src1|$src1, $src2}",
1535 [(set EFLAGS, (X86bt (loadi64 addr:$src1),
1536 i64immSExt8:$src2))], IIC_BT_MI>, TB;
1539 let hasSideEffects = 0 in {
1540 let SchedRW = [WriteALU] in {
1541 def BTC16rr : I<0xBB, MRMDestReg, (outs), (ins GR16:$src1, GR16:$src2),
1542 "btc{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>,
1544 def BTC32rr : I<0xBB, MRMDestReg, (outs), (ins GR32:$src1, GR32:$src2),
1545 "btc{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>,
1547 def BTC64rr : RI<0xBB, MRMDestReg, (outs), (ins GR64:$src1, GR64:$src2),
1548 "btc{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>, TB;
1551 let mayLoad = 1, mayStore = 1, SchedRW = [WriteALULd, WriteRMW] in {
1552 def BTC16mr : I<0xBB, MRMDestMem, (outs), (ins i16mem:$src1, GR16:$src2),
1553 "btc{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>,
1555 def BTC32mr : I<0xBB, MRMDestMem, (outs), (ins i32mem:$src1, GR32:$src2),
1556 "btc{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>,
1558 def BTC64mr : RI<0xBB, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2),
1559 "btc{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>, TB;
1562 let SchedRW = [WriteALU] in {
1563 def BTC16ri8 : Ii8<0xBA, MRM7r, (outs), (ins GR16:$src1, i16i8imm:$src2),
1564 "btc{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>,
1566 def BTC32ri8 : Ii8<0xBA, MRM7r, (outs), (ins GR32:$src1, i32i8imm:$src2),
1567 "btc{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>,
1569 def BTC64ri8 : RIi8<0xBA, MRM7r, (outs), (ins GR64:$src1, i64i8imm:$src2),
1570 "btc{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>, TB;
1573 let mayLoad = 1, mayStore = 1, SchedRW = [WriteALULd, WriteRMW] in {
1574 def BTC16mi8 : Ii8<0xBA, MRM7m, (outs), (ins i16mem:$src1, i16i8imm:$src2),
1575 "btc{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>,
1577 def BTC32mi8 : Ii8<0xBA, MRM7m, (outs), (ins i32mem:$src1, i32i8imm:$src2),
1578 "btc{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>,
1580 def BTC64mi8 : RIi8<0xBA, MRM7m, (outs), (ins i64mem:$src1, i64i8imm:$src2),
1581 "btc{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>, TB;
1584 let SchedRW = [WriteALU] in {
1585 def BTR16rr : I<0xB3, MRMDestReg, (outs), (ins GR16:$src1, GR16:$src2),
1586 "btr{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>,
1588 def BTR32rr : I<0xB3, MRMDestReg, (outs), (ins GR32:$src1, GR32:$src2),
1589 "btr{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>,
1591 def BTR64rr : RI<0xB3, MRMDestReg, (outs), (ins GR64:$src1, GR64:$src2),
1592 "btr{q}\t{$src2, $src1|$src1, $src2}", []>, TB;
1595 let mayLoad = 1, mayStore = 1, SchedRW = [WriteALULd, WriteRMW] in {
1596 def BTR16mr : I<0xB3, MRMDestMem, (outs), (ins i16mem:$src1, GR16:$src2),
1597 "btr{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>,
1599 def BTR32mr : I<0xB3, MRMDestMem, (outs), (ins i32mem:$src1, GR32:$src2),
1600 "btr{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>,
1602 def BTR64mr : RI<0xB3, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2),
1603 "btr{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>, TB;
1606 let SchedRW = [WriteALU] in {
1607 def BTR16ri8 : Ii8<0xBA, MRM6r, (outs), (ins GR16:$src1, i16i8imm:$src2),
1608 "btr{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>,
1610 def BTR32ri8 : Ii8<0xBA, MRM6r, (outs), (ins GR32:$src1, i32i8imm:$src2),
1611 "btr{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>,
1613 def BTR64ri8 : RIi8<0xBA, MRM6r, (outs), (ins GR64:$src1, i64i8imm:$src2),
1614 "btr{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>, TB;
1617 let mayLoad = 1, mayStore = 1, SchedRW = [WriteALULd, WriteRMW] in {
1618 def BTR16mi8 : Ii8<0xBA, MRM6m, (outs), (ins i16mem:$src1, i16i8imm:$src2),
1619 "btr{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>,
1621 def BTR32mi8 : Ii8<0xBA, MRM6m, (outs), (ins i32mem:$src1, i32i8imm:$src2),
1622 "btr{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>,
1624 def BTR64mi8 : RIi8<0xBA, MRM6m, (outs), (ins i64mem:$src1, i64i8imm:$src2),
1625 "btr{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>, TB;
1628 let SchedRW = [WriteALU] in {
1629 def BTS16rr : I<0xAB, MRMDestReg, (outs), (ins GR16:$src1, GR16:$src2),
1630 "bts{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>,
1632 def BTS32rr : I<0xAB, MRMDestReg, (outs), (ins GR32:$src1, GR32:$src2),
1633 "bts{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>,
1635 def BTS64rr : RI<0xAB, MRMDestReg, (outs), (ins GR64:$src1, GR64:$src2),
1636 "bts{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>, TB;
1639 let mayLoad = 1, mayStore = 1, SchedRW = [WriteALULd, WriteRMW] in {
1640 def BTS16mr : I<0xAB, MRMDestMem, (outs), (ins i16mem:$src1, GR16:$src2),
1641 "bts{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>,
1643 def BTS32mr : I<0xAB, MRMDestMem, (outs), (ins i32mem:$src1, GR32:$src2),
1644 "bts{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>,
1646 def BTS64mr : RI<0xAB, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2),
1647 "bts{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>, TB;
1650 let SchedRW = [WriteALU] in {
1651 def BTS16ri8 : Ii8<0xBA, MRM5r, (outs), (ins GR16:$src1, i16i8imm:$src2),
1652 "bts{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>,
1654 def BTS32ri8 : Ii8<0xBA, MRM5r, (outs), (ins GR32:$src1, i32i8imm:$src2),
1655 "bts{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>,
1657 def BTS64ri8 : RIi8<0xBA, MRM5r, (outs), (ins GR64:$src1, i64i8imm:$src2),
1658 "bts{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>, TB;
1661 let mayLoad = 1, mayStore = 1, SchedRW = [WriteALULd, WriteRMW] in {
1662 def BTS16mi8 : Ii8<0xBA, MRM5m, (outs), (ins i16mem:$src1, i16i8imm:$src2),
1663 "bts{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>,
1665 def BTS32mi8 : Ii8<0xBA, MRM5m, (outs), (ins i32mem:$src1, i32i8imm:$src2),
1666 "bts{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>,
1668 def BTS64mi8 : RIi8<0xBA, MRM5m, (outs), (ins i64mem:$src1, i64i8imm:$src2),
1669 "bts{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>, TB;
1671 } // hasSideEffects = 0
1672 } // Defs = [EFLAGS]
1675 //===----------------------------------------------------------------------===//
1679 // Atomic swap. These are just normal xchg instructions. But since a memory
1680 // operand is referenced, the atomicity is ensured.
1681 multiclass ATOMIC_SWAP<bits<8> opc8, bits<8> opc, string mnemonic, string frag,
1682 InstrItinClass itin> {
1683 let Constraints = "$val = $dst", SchedRW = [WriteALULd, WriteRMW] in {
1684 def NAME#8rm : I<opc8, MRMSrcMem, (outs GR8:$dst),
1685 (ins GR8:$val, i8mem:$ptr),
1686 !strconcat(mnemonic, "{b}\t{$val, $ptr|$ptr, $val}"),
1689 (!cast<PatFrag>(frag # "_8") addr:$ptr, GR8:$val))],
1691 def NAME#16rm : I<opc, MRMSrcMem, (outs GR16:$dst),
1692 (ins GR16:$val, i16mem:$ptr),
1693 !strconcat(mnemonic, "{w}\t{$val, $ptr|$ptr, $val}"),
1696 (!cast<PatFrag>(frag # "_16") addr:$ptr, GR16:$val))],
1698 def NAME#32rm : I<opc, MRMSrcMem, (outs GR32:$dst),
1699 (ins GR32:$val, i32mem:$ptr),
1700 !strconcat(mnemonic, "{l}\t{$val, $ptr|$ptr, $val}"),
1703 (!cast<PatFrag>(frag # "_32") addr:$ptr, GR32:$val))],
1705 def NAME#64rm : RI<opc, MRMSrcMem, (outs GR64:$dst),
1706 (ins GR64:$val, i64mem:$ptr),
1707 !strconcat(mnemonic, "{q}\t{$val, $ptr|$ptr, $val}"),
1710 (!cast<PatFrag>(frag # "_64") addr:$ptr, GR64:$val))],
1715 defm XCHG : ATOMIC_SWAP<0x86, 0x87, "xchg", "atomic_swap", IIC_XCHG_MEM>;
1717 // Swap between registers.
1718 let SchedRW = [WriteALU] in {
1719 let Constraints = "$val = $dst" in {
1720 def XCHG8rr : I<0x86, MRMSrcReg, (outs GR8:$dst), (ins GR8:$val, GR8:$src),
1721 "xchg{b}\t{$val, $src|$src, $val}", [], IIC_XCHG_REG>;
1722 def XCHG16rr : I<0x87, MRMSrcReg, (outs GR16:$dst), (ins GR16:$val, GR16:$src),
1723 "xchg{w}\t{$val, $src|$src, $val}", [], IIC_XCHG_REG>,
1725 def XCHG32rr : I<0x87, MRMSrcReg, (outs GR32:$dst), (ins GR32:$val, GR32:$src),
1726 "xchg{l}\t{$val, $src|$src, $val}", [], IIC_XCHG_REG>,
1728 def XCHG64rr : RI<0x87, MRMSrcReg, (outs GR64:$dst), (ins GR64:$val,GR64:$src),
1729 "xchg{q}\t{$val, $src|$src, $val}", [], IIC_XCHG_REG>;
1732 // Swap between EAX and other registers.
1733 let Uses = [AX], Defs = [AX] in
1734 def XCHG16ar : I<0x90, AddRegFrm, (outs), (ins GR16:$src),
1735 "xchg{w}\t{$src, %ax|ax, $src}", [], IIC_XCHG_REG>, OpSize16;
1736 let Uses = [EAX], Defs = [EAX] in
1737 def XCHG32ar : I<0x90, AddRegFrm, (outs), (ins GR32:$src),
1738 "xchg{l}\t{$src, %eax|eax, $src}", [], IIC_XCHG_REG>,
1739 OpSize32, Requires<[Not64BitMode]>;
1740 let Uses = [EAX], Defs = [EAX] in
1741 // Uses GR32_NOAX in 64-bit mode to prevent encoding using the 0x90 NOP encoding.
1742 // xchg %eax, %eax needs to clear upper 32-bits of RAX so is not a NOP.
1743 def XCHG32ar64 : I<0x90, AddRegFrm, (outs), (ins GR32_NOAX:$src),
1744 "xchg{l}\t{$src, %eax|eax, $src}", [], IIC_XCHG_REG>,
1745 OpSize32, Requires<[In64BitMode]>;
1746 let Uses = [RAX], Defs = [RAX] in
1747 def XCHG64ar : RI<0x90, AddRegFrm, (outs), (ins GR64:$src),
1748 "xchg{q}\t{$src, %rax|rax, $src}", [], IIC_XCHG_REG>;
1751 let SchedRW = [WriteALU] in {
1752 def XADD8rr : I<0xC0, MRMDestReg, (outs GR8:$dst), (ins GR8:$src),
1753 "xadd{b}\t{$src, $dst|$dst, $src}", [], IIC_XADD_REG>, TB;
1754 def XADD16rr : I<0xC1, MRMDestReg, (outs GR16:$dst), (ins GR16:$src),
1755 "xadd{w}\t{$src, $dst|$dst, $src}", [], IIC_XADD_REG>, TB,
1757 def XADD32rr : I<0xC1, MRMDestReg, (outs GR32:$dst), (ins GR32:$src),
1758 "xadd{l}\t{$src, $dst|$dst, $src}", [], IIC_XADD_REG>, TB,
1760 def XADD64rr : RI<0xC1, MRMDestReg, (outs GR64:$dst), (ins GR64:$src),
1761 "xadd{q}\t{$src, $dst|$dst, $src}", [], IIC_XADD_REG>, TB;
1764 let mayLoad = 1, mayStore = 1, SchedRW = [WriteALULd, WriteRMW] in {
1765 def XADD8rm : I<0xC0, MRMDestMem, (outs), (ins i8mem:$dst, GR8:$src),
1766 "xadd{b}\t{$src, $dst|$dst, $src}", [], IIC_XADD_MEM>, TB;
1767 def XADD16rm : I<0xC1, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src),
1768 "xadd{w}\t{$src, $dst|$dst, $src}", [], IIC_XADD_MEM>, TB,
1770 def XADD32rm : I<0xC1, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
1771 "xadd{l}\t{$src, $dst|$dst, $src}", [], IIC_XADD_MEM>, TB,
1773 def XADD64rm : RI<0xC1, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
1774 "xadd{q}\t{$src, $dst|$dst, $src}", [], IIC_XADD_MEM>, TB;
1778 let SchedRW = [WriteALU] in {
1779 def CMPXCHG8rr : I<0xB0, MRMDestReg, (outs GR8:$dst), (ins GR8:$src),
1780 "cmpxchg{b}\t{$src, $dst|$dst, $src}", [],
1781 IIC_CMPXCHG_REG8>, TB;
1782 def CMPXCHG16rr : I<0xB1, MRMDestReg, (outs GR16:$dst), (ins GR16:$src),
1783 "cmpxchg{w}\t{$src, $dst|$dst, $src}", [],
1784 IIC_CMPXCHG_REG>, TB, OpSize16;
1785 def CMPXCHG32rr : I<0xB1, MRMDestReg, (outs GR32:$dst), (ins GR32:$src),
1786 "cmpxchg{l}\t{$src, $dst|$dst, $src}", [],
1787 IIC_CMPXCHG_REG>, TB, OpSize32;
1788 def CMPXCHG64rr : RI<0xB1, MRMDestReg, (outs GR64:$dst), (ins GR64:$src),
1789 "cmpxchg{q}\t{$src, $dst|$dst, $src}", [],
1790 IIC_CMPXCHG_REG>, TB;
1793 let SchedRW = [WriteALULd, WriteRMW] in {
1794 let mayLoad = 1, mayStore = 1 in {
1795 def CMPXCHG8rm : I<0xB0, MRMDestMem, (outs), (ins i8mem:$dst, GR8:$src),
1796 "cmpxchg{b}\t{$src, $dst|$dst, $src}", [],
1797 IIC_CMPXCHG_MEM8>, TB;
1798 def CMPXCHG16rm : I<0xB1, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src),
1799 "cmpxchg{w}\t{$src, $dst|$dst, $src}", [],
1800 IIC_CMPXCHG_MEM>, TB, OpSize16;
1801 def CMPXCHG32rm : I<0xB1, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
1802 "cmpxchg{l}\t{$src, $dst|$dst, $src}", [],
1803 IIC_CMPXCHG_MEM>, TB, OpSize32;
1804 def CMPXCHG64rm : RI<0xB1, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
1805 "cmpxchg{q}\t{$src, $dst|$dst, $src}", [],
1806 IIC_CMPXCHG_MEM>, TB;
1809 let Defs = [EAX, EDX, EFLAGS], Uses = [EAX, EBX, ECX, EDX] in
1810 def CMPXCHG8B : I<0xC7, MRM1m, (outs), (ins i64mem:$dst),
1811 "cmpxchg8b\t$dst", [], IIC_CMPXCHG_8B>, TB;
1813 let Defs = [RAX, RDX, EFLAGS], Uses = [RAX, RBX, RCX, RDX] in
1814 def CMPXCHG16B : RI<0xC7, MRM1m, (outs), (ins i128mem:$dst),
1815 "cmpxchg16b\t$dst", [], IIC_CMPXCHG_16B>,
1816 TB, Requires<[HasCmpxchg16b]>;
1820 // Lock instruction prefix
1821 def LOCK_PREFIX : I<0xF0, RawFrm, (outs), (ins), "lock", []>;
1823 // Rex64 instruction prefix
1824 def REX64_PREFIX : I<0x48, RawFrm, (outs), (ins), "rex64", []>,
1825 Requires<[In64BitMode]>;
1827 // Data16 instruction prefix
1828 def DATA16_PREFIX : I<0x66, RawFrm, (outs), (ins), "data16", []>;
1830 // Repeat string operation instruction prefixes
1831 // These uses the DF flag in the EFLAGS register to inc or dec ECX
1832 let Defs = [ECX], Uses = [ECX,EFLAGS] in {
1833 // Repeat (used with INS, OUTS, MOVS, LODS and STOS)
1834 def REP_PREFIX : I<0xF3, RawFrm, (outs), (ins), "rep", []>;
1835 // Repeat while not equal (used with CMPS and SCAS)
1836 def REPNE_PREFIX : I<0xF2, RawFrm, (outs), (ins), "repne", []>;
1840 // String manipulation instructions
1841 let SchedRW = [WriteMicrocoded] in {
1842 // These uses the DF flag in the EFLAGS register to inc or dec EDI and ESI
1843 let Defs = [AL,ESI], Uses = [ESI,EFLAGS] in
1844 def LODSB : I<0xAC, RawFrmSrc, (outs), (ins srcidx8:$src),
1845 "lodsb\t{$src, %al|al, $src}", [], IIC_LODS>;
1846 let Defs = [AX,ESI], Uses = [ESI,EFLAGS] in
1847 def LODSW : I<0xAD, RawFrmSrc, (outs), (ins srcidx16:$src),
1848 "lodsw\t{$src, %ax|ax, $src}", [], IIC_LODS>, OpSize16;
1849 let Defs = [EAX,ESI], Uses = [ESI,EFLAGS] in
1850 def LODSL : I<0xAD, RawFrmSrc, (outs), (ins srcidx32:$src),
1851 "lods{l|d}\t{$src, %eax|eax, $src}", [], IIC_LODS>, OpSize32;
1852 let Defs = [RAX,ESI], Uses = [ESI,EFLAGS] in
1853 def LODSQ : RI<0xAD, RawFrmSrc, (outs), (ins srcidx64:$src),
1854 "lodsq\t{$src, %rax|rax, $src}", [], IIC_LODS>;
1857 let SchedRW = [WriteSystem] in {
1858 // These uses the DF flag in the EFLAGS register to inc or dec EDI and ESI
1859 let Defs = [ESI], Uses = [DX,ESI,EFLAGS] in {
1860 def OUTSB : I<0x6E, RawFrmSrc, (outs), (ins srcidx8:$src),
1861 "outsb\t{$src, %dx|dx, $src}", [], IIC_OUTS>;
1862 def OUTSW : I<0x6F, RawFrmSrc, (outs), (ins srcidx16:$src),
1863 "outsw\t{$src, %dx|dx, $src}", [], IIC_OUTS>, OpSize16;
1864 def OUTSL : I<0x6F, RawFrmSrc, (outs), (ins srcidx32:$src),
1865 "outs{l|d}\t{$src, %dx|dx, $src}", [], IIC_OUTS>, OpSize32;
1868 // These uses the DF flag in the EFLAGS register to inc or dec EDI and ESI
1869 let Defs = [EDI], Uses = [DX,EDI,EFLAGS] in {
1870 def INSB : I<0x6C, RawFrmDst, (outs dstidx8:$dst), (ins),
1871 "insb\t{%dx, $dst|$dst, dx}", [], IIC_INS>;
1872 def INSW : I<0x6D, RawFrmDst, (outs dstidx16:$dst), (ins),
1873 "insw\t{%dx, $dst|$dst, dx}", [], IIC_INS>, OpSize16;
1874 def INSL : I<0x6D, RawFrmDst, (outs dstidx32:$dst), (ins),
1875 "ins{l|d}\t{%dx, $dst|$dst, dx}", [], IIC_INS>, OpSize32;
1879 // Flag instructions
1880 let SchedRW = [WriteALU] in {
1881 def CLC : I<0xF8, RawFrm, (outs), (ins), "clc", [], IIC_CLC>;
1882 def STC : I<0xF9, RawFrm, (outs), (ins), "stc", [], IIC_STC>;
1883 def CLI : I<0xFA, RawFrm, (outs), (ins), "cli", [], IIC_CLI>;
1884 def STI : I<0xFB, RawFrm, (outs), (ins), "sti", [], IIC_STI>;
1885 def CLD : I<0xFC, RawFrm, (outs), (ins), "cld", [], IIC_CLD>;
1886 def STD : I<0xFD, RawFrm, (outs), (ins), "std", [], IIC_STD>;
1887 def CMC : I<0xF5, RawFrm, (outs), (ins), "cmc", [], IIC_CMC>;
1889 def CLTS : I<0x06, RawFrm, (outs), (ins), "clts", [], IIC_CLTS>, TB;
1892 // Table lookup instructions
1893 def XLAT : I<0xD7, RawFrm, (outs), (ins), "xlatb", [], IIC_XLAT>,
1896 let SchedRW = [WriteMicrocoded] in {
1897 // ASCII Adjust After Addition
1898 // sets AL, AH and CF and AF of EFLAGS and uses AL and AF of EFLAGS
1899 def AAA : I<0x37, RawFrm, (outs), (ins), "aaa", [], IIC_AAA>,
1900 Requires<[Not64BitMode]>;
1902 // ASCII Adjust AX Before Division
1903 // sets AL, AH and EFLAGS and uses AL and AH
1904 def AAD8i8 : Ii8<0xD5, RawFrm, (outs), (ins i8imm:$src),
1905 "aad\t$src", [], IIC_AAD>, Requires<[Not64BitMode]>;
1907 // ASCII Adjust AX After Multiply
1908 // sets AL, AH and EFLAGS and uses AL
1909 def AAM8i8 : Ii8<0xD4, RawFrm, (outs), (ins i8imm:$src),
1910 "aam\t$src", [], IIC_AAM>, Requires<[Not64BitMode]>;
1912 // ASCII Adjust AL After Subtraction - sets
1913 // sets AL, AH and CF and AF of EFLAGS and uses AL and AF of EFLAGS
1914 def AAS : I<0x3F, RawFrm, (outs), (ins), "aas", [], IIC_AAS>,
1915 Requires<[Not64BitMode]>;
1917 // Decimal Adjust AL after Addition
1918 // sets AL, CF and AF of EFLAGS and uses AL, CF and AF of EFLAGS
1919 def DAA : I<0x27, RawFrm, (outs), (ins), "daa", [], IIC_DAA>,
1920 Requires<[Not64BitMode]>;
1922 // Decimal Adjust AL after Subtraction
1923 // sets AL, CF and AF of EFLAGS and uses AL, CF and AF of EFLAGS
1924 def DAS : I<0x2F, RawFrm, (outs), (ins), "das", [], IIC_DAS>,
1925 Requires<[Not64BitMode]>;
1928 let SchedRW = [WriteSystem] in {
1929 // Check Array Index Against Bounds
1930 def BOUNDS16rm : I<0x62, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
1931 "bound\t{$src, $dst|$dst, $src}", [], IIC_BOUND>, OpSize16,
1932 Requires<[Not64BitMode]>;
1933 def BOUNDS32rm : I<0x62, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
1934 "bound\t{$src, $dst|$dst, $src}", [], IIC_BOUND>, OpSize32,
1935 Requires<[Not64BitMode]>;
1937 // Adjust RPL Field of Segment Selector
1938 def ARPL16rr : I<0x63, MRMDestReg, (outs GR16:$dst), (ins GR16:$src),
1939 "arpl\t{$src, $dst|$dst, $src}", [], IIC_ARPL_REG>,
1940 Requires<[Not64BitMode]>;
1941 def ARPL16mr : I<0x63, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src),
1942 "arpl\t{$src, $dst|$dst, $src}", [], IIC_ARPL_MEM>,
1943 Requires<[Not64BitMode]>;
1946 //===----------------------------------------------------------------------===//
1947 // MOVBE Instructions
1949 let Predicates = [HasMOVBE] in {
1950 let SchedRW = [WriteALULd] in {
1951 def MOVBE16rm : I<0xF0, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
1952 "movbe{w}\t{$src, $dst|$dst, $src}",
1953 [(set GR16:$dst, (bswap (loadi16 addr:$src)))], IIC_MOVBE>,
1955 def MOVBE32rm : I<0xF0, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
1956 "movbe{l}\t{$src, $dst|$dst, $src}",
1957 [(set GR32:$dst, (bswap (loadi32 addr:$src)))], IIC_MOVBE>,
1959 def MOVBE64rm : RI<0xF0, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
1960 "movbe{q}\t{$src, $dst|$dst, $src}",
1961 [(set GR64:$dst, (bswap (loadi64 addr:$src)))], IIC_MOVBE>,
1964 let SchedRW = [WriteStore] in {
1965 def MOVBE16mr : I<0xF1, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src),
1966 "movbe{w}\t{$src, $dst|$dst, $src}",
1967 [(store (bswap GR16:$src), addr:$dst)], IIC_MOVBE>,
1969 def MOVBE32mr : I<0xF1, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
1970 "movbe{l}\t{$src, $dst|$dst, $src}",
1971 [(store (bswap GR32:$src), addr:$dst)], IIC_MOVBE>,
1973 def MOVBE64mr : RI<0xF1, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
1974 "movbe{q}\t{$src, $dst|$dst, $src}",
1975 [(store (bswap GR64:$src), addr:$dst)], IIC_MOVBE>,
1980 //===----------------------------------------------------------------------===//
1981 // RDRAND Instruction
1983 let Predicates = [HasRDRAND], Defs = [EFLAGS] in {
1984 def RDRAND16r : I<0xC7, MRM6r, (outs GR16:$dst), (ins),
1986 [(set GR16:$dst, EFLAGS, (X86rdrand))]>, OpSize16, TB;
1987 def RDRAND32r : I<0xC7, MRM6r, (outs GR32:$dst), (ins),
1989 [(set GR32:$dst, EFLAGS, (X86rdrand))]>, OpSize32, TB;
1990 def RDRAND64r : RI<0xC7, MRM6r, (outs GR64:$dst), (ins),
1992 [(set GR64:$dst, EFLAGS, (X86rdrand))]>, TB;
1995 //===----------------------------------------------------------------------===//
1996 // RDSEED Instruction
1998 let Predicates = [HasRDSEED], Defs = [EFLAGS] in {
1999 def RDSEED16r : I<0xC7, MRM7r, (outs GR16:$dst), (ins),
2001 [(set GR16:$dst, EFLAGS, (X86rdseed))]>, OpSize16, TB;
2002 def RDSEED32r : I<0xC7, MRM7r, (outs GR32:$dst), (ins),
2004 [(set GR32:$dst, EFLAGS, (X86rdseed))]>, OpSize32, TB;
2005 def RDSEED64r : RI<0xC7, MRM7r, (outs GR64:$dst), (ins),
2007 [(set GR64:$dst, EFLAGS, (X86rdseed))]>, TB;
2010 //===----------------------------------------------------------------------===//
2011 // LZCNT Instruction
2013 let Predicates = [HasLZCNT], Defs = [EFLAGS] in {
2014 def LZCNT16rr : I<0xBD, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
2015 "lzcnt{w}\t{$src, $dst|$dst, $src}",
2016 [(set GR16:$dst, (ctlz GR16:$src)), (implicit EFLAGS)]>, XS,
2018 def LZCNT16rm : I<0xBD, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
2019 "lzcnt{w}\t{$src, $dst|$dst, $src}",
2020 [(set GR16:$dst, (ctlz (loadi16 addr:$src))),
2021 (implicit EFLAGS)]>, XS, OpSize16;
2023 def LZCNT32rr : I<0xBD, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
2024 "lzcnt{l}\t{$src, $dst|$dst, $src}",
2025 [(set GR32:$dst, (ctlz GR32:$src)), (implicit EFLAGS)]>, XS,
2027 def LZCNT32rm : I<0xBD, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
2028 "lzcnt{l}\t{$src, $dst|$dst, $src}",
2029 [(set GR32:$dst, (ctlz (loadi32 addr:$src))),
2030 (implicit EFLAGS)]>, XS, OpSize32;
2032 def LZCNT64rr : RI<0xBD, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
2033 "lzcnt{q}\t{$src, $dst|$dst, $src}",
2034 [(set GR64:$dst, (ctlz GR64:$src)), (implicit EFLAGS)]>,
2036 def LZCNT64rm : RI<0xBD, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
2037 "lzcnt{q}\t{$src, $dst|$dst, $src}",
2038 [(set GR64:$dst, (ctlz (loadi64 addr:$src))),
2039 (implicit EFLAGS)]>, XS;
2042 let Predicates = [HasLZCNT] in {
2043 def : Pat<(X86cmov (ctlz GR16:$src), (i16 16), (X86_COND_E_OR_NE),
2044 (X86cmp GR16:$src, (i16 0))),
2045 (LZCNT16rr GR16:$src)>;
2046 def : Pat<(X86cmov (ctlz GR32:$src), (i32 32), (X86_COND_E_OR_NE),
2047 (X86cmp GR32:$src, (i32 0))),
2048 (LZCNT32rr GR32:$src)>;
2049 def : Pat<(X86cmov (ctlz GR64:$src), (i64 64), (X86_COND_E_OR_NE),
2050 (X86cmp GR64:$src, (i64 0))),
2051 (LZCNT64rr GR64:$src)>;
2052 def : Pat<(X86cmov (i16 16), (ctlz GR16:$src), (X86_COND_E_OR_NE),
2053 (X86cmp GR16:$src, (i16 0))),
2054 (LZCNT16rr GR16:$src)>;
2055 def : Pat<(X86cmov (i32 32), (ctlz GR32:$src), (X86_COND_E_OR_NE),
2056 (X86cmp GR32:$src, (i32 0))),
2057 (LZCNT32rr GR32:$src)>;
2058 def : Pat<(X86cmov (i64 64), (ctlz GR64:$src), (X86_COND_E_OR_NE),
2059 (X86cmp GR64:$src, (i64 0))),
2060 (LZCNT64rr GR64:$src)>;
2062 def : Pat<(X86cmov (ctlz (loadi16 addr:$src)), (i16 16), (X86_COND_E_OR_NE),
2063 (X86cmp (loadi16 addr:$src), (i16 0))),
2064 (LZCNT16rm addr:$src)>;
2065 def : Pat<(X86cmov (ctlz (loadi32 addr:$src)), (i32 32), (X86_COND_E_OR_NE),
2066 (X86cmp (loadi32 addr:$src), (i32 0))),
2067 (LZCNT32rm addr:$src)>;
2068 def : Pat<(X86cmov (ctlz (loadi64 addr:$src)), (i64 64), (X86_COND_E_OR_NE),
2069 (X86cmp (loadi64 addr:$src), (i64 0))),
2070 (LZCNT64rm addr:$src)>;
2071 def : Pat<(X86cmov (i16 16), (ctlz (loadi16 addr:$src)), (X86_COND_E_OR_NE),
2072 (X86cmp (loadi16 addr:$src), (i16 0))),
2073 (LZCNT16rm addr:$src)>;
2074 def : Pat<(X86cmov (i32 32), (ctlz (loadi32 addr:$src)), (X86_COND_E_OR_NE),
2075 (X86cmp (loadi32 addr:$src), (i32 0))),
2076 (LZCNT32rm addr:$src)>;
2077 def : Pat<(X86cmov (i64 64), (ctlz (loadi64 addr:$src)), (X86_COND_E_OR_NE),
2078 (X86cmp (loadi64 addr:$src), (i64 0))),
2079 (LZCNT64rm addr:$src)>;
2082 //===----------------------------------------------------------------------===//
2085 let Predicates = [HasBMI], Defs = [EFLAGS] in {
2086 def TZCNT16rr : I<0xBC, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
2087 "tzcnt{w}\t{$src, $dst|$dst, $src}",
2088 [(set GR16:$dst, (cttz GR16:$src)), (implicit EFLAGS)]>, XS,
2090 def TZCNT16rm : I<0xBC, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
2091 "tzcnt{w}\t{$src, $dst|$dst, $src}",
2092 [(set GR16:$dst, (cttz (loadi16 addr:$src))),
2093 (implicit EFLAGS)]>, XS, OpSize16;
2095 def TZCNT32rr : I<0xBC, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
2096 "tzcnt{l}\t{$src, $dst|$dst, $src}",
2097 [(set GR32:$dst, (cttz GR32:$src)), (implicit EFLAGS)]>, XS,
2099 def TZCNT32rm : I<0xBC, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
2100 "tzcnt{l}\t{$src, $dst|$dst, $src}",
2101 [(set GR32:$dst, (cttz (loadi32 addr:$src))),
2102 (implicit EFLAGS)]>, XS, OpSize32;
2104 def TZCNT64rr : RI<0xBC, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
2105 "tzcnt{q}\t{$src, $dst|$dst, $src}",
2106 [(set GR64:$dst, (cttz GR64:$src)), (implicit EFLAGS)]>,
2108 def TZCNT64rm : RI<0xBC, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
2109 "tzcnt{q}\t{$src, $dst|$dst, $src}",
2110 [(set GR64:$dst, (cttz (loadi64 addr:$src))),
2111 (implicit EFLAGS)]>, XS;
2114 multiclass bmi_bls<string mnemonic, Format RegMRM, Format MemMRM,
2115 RegisterClass RC, X86MemOperand x86memop> {
2116 let hasSideEffects = 0 in {
2117 def rr : I<0xF3, RegMRM, (outs RC:$dst), (ins RC:$src),
2118 !strconcat(mnemonic, "\t{$src, $dst|$dst, $src}"),
2121 def rm : I<0xF3, MemMRM, (outs RC:$dst), (ins x86memop:$src),
2122 !strconcat(mnemonic, "\t{$src, $dst|$dst, $src}"),
2127 let Predicates = [HasBMI], Defs = [EFLAGS] in {
2128 defm BLSR32 : bmi_bls<"blsr{l}", MRM1r, MRM1m, GR32, i32mem>;
2129 defm BLSR64 : bmi_bls<"blsr{q}", MRM1r, MRM1m, GR64, i64mem>, VEX_W;
2130 defm BLSMSK32 : bmi_bls<"blsmsk{l}", MRM2r, MRM2m, GR32, i32mem>;
2131 defm BLSMSK64 : bmi_bls<"blsmsk{q}", MRM2r, MRM2m, GR64, i64mem>, VEX_W;
2132 defm BLSI32 : bmi_bls<"blsi{l}", MRM3r, MRM3m, GR32, i32mem>;
2133 defm BLSI64 : bmi_bls<"blsi{q}", MRM3r, MRM3m, GR64, i64mem>, VEX_W;
2136 //===----------------------------------------------------------------------===//
2137 // Pattern fragments to auto generate BMI instructions.
2138 //===----------------------------------------------------------------------===//
2140 let Predicates = [HasBMI] in {
2141 // FIXME: patterns for the load versions are not implemented
2142 def : Pat<(and GR32:$src, (add GR32:$src, -1)),
2143 (BLSR32rr GR32:$src)>;
2144 def : Pat<(and GR64:$src, (add GR64:$src, -1)),
2145 (BLSR64rr GR64:$src)>;
2147 def : Pat<(xor GR32:$src, (add GR32:$src, -1)),
2148 (BLSMSK32rr GR32:$src)>;
2149 def : Pat<(xor GR64:$src, (add GR64:$src, -1)),
2150 (BLSMSK64rr GR64:$src)>;
2152 def : Pat<(and GR32:$src, (ineg GR32:$src)),
2153 (BLSI32rr GR32:$src)>;
2154 def : Pat<(and GR64:$src, (ineg GR64:$src)),
2155 (BLSI64rr GR64:$src)>;
2158 let Predicates = [HasBMI] in {
2159 def : Pat<(X86cmov (cttz GR16:$src), (i16 16), (X86_COND_E_OR_NE),
2160 (X86cmp GR16:$src, (i16 0))),
2161 (TZCNT16rr GR16:$src)>;
2162 def : Pat<(X86cmov (cttz GR32:$src), (i32 32), (X86_COND_E_OR_NE),
2163 (X86cmp GR32:$src, (i32 0))),
2164 (TZCNT32rr GR32:$src)>;
2165 def : Pat<(X86cmov (cttz GR64:$src), (i64 64), (X86_COND_E_OR_NE),
2166 (X86cmp GR64:$src, (i64 0))),
2167 (TZCNT64rr GR64:$src)>;
2168 def : Pat<(X86cmov (i16 16), (cttz GR16:$src), (X86_COND_E_OR_NE),
2169 (X86cmp GR16:$src, (i16 0))),
2170 (TZCNT16rr GR16:$src)>;
2171 def : Pat<(X86cmov (i32 32), (cttz GR32:$src), (X86_COND_E_OR_NE),
2172 (X86cmp GR32:$src, (i32 0))),
2173 (TZCNT32rr GR32:$src)>;
2174 def : Pat<(X86cmov (i64 64), (cttz GR64:$src), (X86_COND_E_OR_NE),
2175 (X86cmp GR64:$src, (i64 0))),
2176 (TZCNT64rr GR64:$src)>;
2178 def : Pat<(X86cmov (cttz (loadi16 addr:$src)), (i16 16), (X86_COND_E_OR_NE),
2179 (X86cmp (loadi16 addr:$src), (i16 0))),
2180 (TZCNT16rm addr:$src)>;
2181 def : Pat<(X86cmov (cttz (loadi32 addr:$src)), (i32 32), (X86_COND_E_OR_NE),
2182 (X86cmp (loadi32 addr:$src), (i32 0))),
2183 (TZCNT32rm addr:$src)>;
2184 def : Pat<(X86cmov (cttz (loadi64 addr:$src)), (i64 64), (X86_COND_E_OR_NE),
2185 (X86cmp (loadi64 addr:$src), (i64 0))),
2186 (TZCNT64rm addr:$src)>;
2187 def : Pat<(X86cmov (i16 16), (cttz (loadi16 addr:$src)), (X86_COND_E_OR_NE),
2188 (X86cmp (loadi16 addr:$src), (i16 0))),
2189 (TZCNT16rm addr:$src)>;
2190 def : Pat<(X86cmov (i32 32), (cttz (loadi32 addr:$src)), (X86_COND_E_OR_NE),
2191 (X86cmp (loadi32 addr:$src), (i32 0))),
2192 (TZCNT32rm addr:$src)>;
2193 def : Pat<(X86cmov (i64 64), (cttz (loadi64 addr:$src)), (X86_COND_E_OR_NE),
2194 (X86cmp (loadi64 addr:$src), (i64 0))),
2195 (TZCNT64rm addr:$src)>;
2199 multiclass bmi_bextr_bzhi<bits<8> opc, string mnemonic, RegisterClass RC,
2200 X86MemOperand x86memop, Intrinsic Int,
2202 def rr : I<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
2203 !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2204 [(set RC:$dst, (Int RC:$src1, RC:$src2)), (implicit EFLAGS)]>,
2206 def rm : I<opc, MRMSrcMem, (outs RC:$dst), (ins x86memop:$src1, RC:$src2),
2207 !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2208 [(set RC:$dst, (Int (ld_frag addr:$src1), RC:$src2)),
2209 (implicit EFLAGS)]>, T8PS, VEX_4VOp3;
2212 let Predicates = [HasBMI], Defs = [EFLAGS] in {
2213 defm BEXTR32 : bmi_bextr_bzhi<0xF7, "bextr{l}", GR32, i32mem,
2214 int_x86_bmi_bextr_32, loadi32>;
2215 defm BEXTR64 : bmi_bextr_bzhi<0xF7, "bextr{q}", GR64, i64mem,
2216 int_x86_bmi_bextr_64, loadi64>, VEX_W;
2219 let Predicates = [HasBMI2], Defs = [EFLAGS] in {
2220 defm BZHI32 : bmi_bextr_bzhi<0xF5, "bzhi{l}", GR32, i32mem,
2221 int_x86_bmi_bzhi_32, loadi32>;
2222 defm BZHI64 : bmi_bextr_bzhi<0xF5, "bzhi{q}", GR64, i64mem,
2223 int_x86_bmi_bzhi_64, loadi64>, VEX_W;
2227 def CountTrailingOnes : SDNodeXForm<imm, [{
2228 // Count the trailing ones in the immediate.
2229 return getI8Imm(countTrailingOnes(N->getZExtValue()), SDLoc(N));
2232 def BZHIMask : ImmLeaf<i64, [{
2233 return isMask_64(Imm) && (countTrailingOnes<uint64_t>(Imm) > 32);
2236 let Predicates = [HasBMI2] in {
2237 def : Pat<(and GR64:$src, BZHIMask:$mask),
2238 (BZHI64rr GR64:$src,
2239 (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
2240 (MOV8ri (CountTrailingOnes imm:$mask)), sub_8bit))>;
2242 def : Pat<(and GR32:$src, (add (shl 1, GR8:$lz), -1)),
2243 (BZHI32rr GR32:$src,
2244 (INSERT_SUBREG (i32 (IMPLICIT_DEF)), GR8:$lz, sub_8bit))>;
2246 def : Pat<(and (loadi32 addr:$src), (add (shl 1, GR8:$lz), -1)),
2247 (BZHI32rm addr:$src,
2248 (INSERT_SUBREG (i32 (IMPLICIT_DEF)), GR8:$lz, sub_8bit))>;
2250 def : Pat<(and GR64:$src, (add (shl 1, GR8:$lz), -1)),
2251 (BZHI64rr GR64:$src,
2252 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR8:$lz, sub_8bit))>;
2254 def : Pat<(and (loadi64 addr:$src), (add (shl 1, GR8:$lz), -1)),
2255 (BZHI64rm addr:$src,
2256 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR8:$lz, sub_8bit))>;
2259 let Predicates = [HasBMI] in {
2260 def : Pat<(X86bextr GR32:$src1, GR32:$src2),
2261 (BEXTR32rr GR32:$src1, GR32:$src2)>;
2262 def : Pat<(X86bextr (loadi32 addr:$src1), GR32:$src2),
2263 (BEXTR32rm addr:$src1, GR32:$src2)>;
2264 def : Pat<(X86bextr GR64:$src1, GR64:$src2),
2265 (BEXTR64rr GR64:$src1, GR64:$src2)>;
2266 def : Pat<(X86bextr (loadi64 addr:$src1), GR64:$src2),
2267 (BEXTR64rm addr:$src1, GR64:$src2)>;
2270 multiclass bmi_pdep_pext<string mnemonic, RegisterClass RC,
2271 X86MemOperand x86memop, Intrinsic Int,
2273 def rr : I<0xF5, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
2274 !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2275 [(set RC:$dst, (Int RC:$src1, RC:$src2))]>,
2277 def rm : I<0xF5, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
2278 !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2279 [(set RC:$dst, (Int RC:$src1, (ld_frag addr:$src2)))]>, VEX_4V;
2282 let Predicates = [HasBMI2] in {
2283 defm PDEP32 : bmi_pdep_pext<"pdep{l}", GR32, i32mem,
2284 int_x86_bmi_pdep_32, loadi32>, T8XD;
2285 defm PDEP64 : bmi_pdep_pext<"pdep{q}", GR64, i64mem,
2286 int_x86_bmi_pdep_64, loadi64>, T8XD, VEX_W;
2287 defm PEXT32 : bmi_pdep_pext<"pext{l}", GR32, i32mem,
2288 int_x86_bmi_pext_32, loadi32>, T8XS;
2289 defm PEXT64 : bmi_pdep_pext<"pext{q}", GR64, i64mem,
2290 int_x86_bmi_pext_64, loadi64>, T8XS, VEX_W;
2293 //===----------------------------------------------------------------------===//
2296 let Predicates = [HasTBM], Defs = [EFLAGS] in {
2298 multiclass tbm_ternary_imm_intr<bits<8> opc, RegisterClass RC, string OpcodeStr,
2299 X86MemOperand x86memop, PatFrag ld_frag,
2300 Intrinsic Int, Operand immtype,
2301 SDPatternOperator immoperator> {
2302 def ri : Ii32<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, immtype:$cntl),
2303 !strconcat(OpcodeStr,
2304 "\t{$cntl, $src1, $dst|$dst, $src1, $cntl}"),
2305 [(set RC:$dst, (Int RC:$src1, immoperator:$cntl))]>,
2307 def mi : Ii32<opc, MRMSrcMem, (outs RC:$dst),
2308 (ins x86memop:$src1, immtype:$cntl),
2309 !strconcat(OpcodeStr,
2310 "\t{$cntl, $src1, $dst|$dst, $src1, $cntl}"),
2311 [(set RC:$dst, (Int (ld_frag addr:$src1), immoperator:$cntl))]>,
2315 defm BEXTRI32 : tbm_ternary_imm_intr<0x10, GR32, "bextr", i32mem, loadi32,
2316 int_x86_tbm_bextri_u32, i32imm, imm>;
2317 let ImmT = Imm32S in
2318 defm BEXTRI64 : tbm_ternary_imm_intr<0x10, GR64, "bextr", i64mem, loadi64,
2319 int_x86_tbm_bextri_u64, i64i32imm,
2320 i64immSExt32>, VEX_W;
2322 multiclass tbm_binary_rm<bits<8> opc, Format FormReg, Format FormMem,
2323 RegisterClass RC, string OpcodeStr,
2324 X86MemOperand x86memop, PatFrag ld_frag> {
2325 let hasSideEffects = 0 in {
2326 def rr : I<opc, FormReg, (outs RC:$dst), (ins RC:$src),
2327 !strconcat(OpcodeStr,"\t{$src, $dst|$dst, $src}"),
2330 def rm : I<opc, FormMem, (outs RC:$dst), (ins x86memop:$src),
2331 !strconcat(OpcodeStr,"\t{$src, $dst|$dst, $src}"),
2336 multiclass tbm_binary_intr<bits<8> opc, string OpcodeStr,
2337 Format FormReg, Format FormMem> {
2338 defm NAME#32 : tbm_binary_rm<opc, FormReg, FormMem, GR32, OpcodeStr, i32mem,
2340 defm NAME#64 : tbm_binary_rm<opc, FormReg, FormMem, GR64, OpcodeStr, i64mem,
2344 defm BLCFILL : tbm_binary_intr<0x01, "blcfill", MRM1r, MRM1m>;
2345 defm BLCI : tbm_binary_intr<0x02, "blci", MRM6r, MRM6m>;
2346 defm BLCIC : tbm_binary_intr<0x01, "blcic", MRM5r, MRM5m>;
2347 defm BLCMSK : tbm_binary_intr<0x02, "blcmsk", MRM1r, MRM1m>;
2348 defm BLCS : tbm_binary_intr<0x01, "blcs", MRM3r, MRM3m>;
2349 defm BLSFILL : tbm_binary_intr<0x01, "blsfill", MRM2r, MRM2m>;
2350 defm BLSIC : tbm_binary_intr<0x01, "blsic", MRM6r, MRM6m>;
2351 defm T1MSKC : tbm_binary_intr<0x01, "t1mskc", MRM7r, MRM7m>;
2352 defm TZMSK : tbm_binary_intr<0x01, "tzmsk", MRM4r, MRM4m>;
2355 //===----------------------------------------------------------------------===//
2356 // Pattern fragments to auto generate TBM instructions.
2357 //===----------------------------------------------------------------------===//
2359 let Predicates = [HasTBM] in {
2360 def : Pat<(X86bextr GR32:$src1, (i32 imm:$src2)),
2361 (BEXTRI32ri GR32:$src1, imm:$src2)>;
2362 def : Pat<(X86bextr (loadi32 addr:$src1), (i32 imm:$src2)),
2363 (BEXTRI32mi addr:$src1, imm:$src2)>;
2364 def : Pat<(X86bextr GR64:$src1, i64immSExt32:$src2),
2365 (BEXTRI64ri GR64:$src1, i64immSExt32:$src2)>;
2366 def : Pat<(X86bextr (loadi64 addr:$src1), i64immSExt32:$src2),
2367 (BEXTRI64mi addr:$src1, i64immSExt32:$src2)>;
2369 // FIXME: patterns for the load versions are not implemented
2370 def : Pat<(and GR32:$src, (add GR32:$src, 1)),
2371 (BLCFILL32rr GR32:$src)>;
2372 def : Pat<(and GR64:$src, (add GR64:$src, 1)),
2373 (BLCFILL64rr GR64:$src)>;
2375 def : Pat<(or GR32:$src, (not (add GR32:$src, 1))),
2376 (BLCI32rr GR32:$src)>;
2377 def : Pat<(or GR64:$src, (not (add GR64:$src, 1))),
2378 (BLCI64rr GR64:$src)>;
2380 // Extra patterns because opt can optimize the above patterns to this.
2381 def : Pat<(or GR32:$src, (sub -2, GR32:$src)),
2382 (BLCI32rr GR32:$src)>;
2383 def : Pat<(or GR64:$src, (sub -2, GR64:$src)),
2384 (BLCI64rr GR64:$src)>;
2386 def : Pat<(and (not GR32:$src), (add GR32:$src, 1)),
2387 (BLCIC32rr GR32:$src)>;
2388 def : Pat<(and (not GR64:$src), (add GR64:$src, 1)),
2389 (BLCIC64rr GR64:$src)>;
2391 def : Pat<(xor GR32:$src, (add GR32:$src, 1)),
2392 (BLCMSK32rr GR32:$src)>;
2393 def : Pat<(xor GR64:$src, (add GR64:$src, 1)),
2394 (BLCMSK64rr GR64:$src)>;
2396 def : Pat<(or GR32:$src, (add GR32:$src, 1)),
2397 (BLCS32rr GR32:$src)>;
2398 def : Pat<(or GR64:$src, (add GR64:$src, 1)),
2399 (BLCS64rr GR64:$src)>;
2401 def : Pat<(or GR32:$src, (add GR32:$src, -1)),
2402 (BLSFILL32rr GR32:$src)>;
2403 def : Pat<(or GR64:$src, (add GR64:$src, -1)),
2404 (BLSFILL64rr GR64:$src)>;
2406 def : Pat<(or (not GR32:$src), (add GR32:$src, -1)),
2407 (BLSIC32rr GR32:$src)>;
2408 def : Pat<(or (not GR64:$src), (add GR64:$src, -1)),
2409 (BLSIC64rr GR64:$src)>;
2411 def : Pat<(or (not GR32:$src), (add GR32:$src, 1)),
2412 (T1MSKC32rr GR32:$src)>;
2413 def : Pat<(or (not GR64:$src), (add GR64:$src, 1)),
2414 (T1MSKC64rr GR64:$src)>;
2416 def : Pat<(and (not GR32:$src), (add GR32:$src, -1)),
2417 (TZMSK32rr GR32:$src)>;
2418 def : Pat<(and (not GR64:$src), (add GR64:$src, -1)),
2419 (TZMSK64rr GR64:$src)>;
2422 //===----------------------------------------------------------------------===//
2423 // Memory Instructions
2426 def CLFLUSHOPT : I<0xAE, MRM7m, (outs), (ins i8mem:$src),
2427 "clflushopt\t$src", []>, PD;
2428 def CLWB : I<0xAE, MRM6m, (outs), (ins i8mem:$src), "clwb\t$src", []>, PD;
2429 def PCOMMIT : I<0xAE, MRM_F8, (outs), (ins), "pcommit", []>, PD;
2432 //===----------------------------------------------------------------------===//
2434 //===----------------------------------------------------------------------===//
2436 include "X86InstrArithmetic.td"
2437 include "X86InstrCMovSetCC.td"
2438 include "X86InstrExtension.td"
2439 include "X86InstrControl.td"
2440 include "X86InstrShiftRotate.td"
2442 // X87 Floating Point Stack.
2443 include "X86InstrFPStack.td"
2445 // SIMD support (SSE, MMX and AVX)
2446 include "X86InstrFragmentsSIMD.td"
2448 // FMA - Fused Multiply-Add support (requires FMA)
2449 include "X86InstrFMA.td"
2452 include "X86InstrXOP.td"
2454 // SSE, MMX and 3DNow! vector support.
2455 include "X86InstrSSE.td"
2456 include "X86InstrAVX512.td"
2457 include "X86InstrMMX.td"
2458 include "X86Instr3DNow.td"
2461 include "X86InstrMPX.td"
2463 include "X86InstrVMX.td"
2464 include "X86InstrSVM.td"
2466 include "X86InstrTSX.td"
2467 include "X86InstrSGX.td"
2469 // System instructions.
2470 include "X86InstrSystem.td"
2472 // Compiler Pseudo Instructions and Pat Patterns
2473 include "X86InstrCompiler.td"
2475 //===----------------------------------------------------------------------===//
2476 // Assembler Mnemonic Aliases
2477 //===----------------------------------------------------------------------===//
2479 def : MnemonicAlias<"call", "callw", "att">, Requires<[In16BitMode]>;
2480 def : MnemonicAlias<"call", "calll", "att">, Requires<[In32BitMode]>;
2481 def : MnemonicAlias<"call", "callq", "att">, Requires<[In64BitMode]>;
2483 def : MnemonicAlias<"cbw", "cbtw", "att">;
2484 def : MnemonicAlias<"cwde", "cwtl", "att">;
2485 def : MnemonicAlias<"cwd", "cwtd", "att">;
2486 def : MnemonicAlias<"cdq", "cltd", "att">;
2487 def : MnemonicAlias<"cdqe", "cltq", "att">;
2488 def : MnemonicAlias<"cqo", "cqto", "att">;
2490 // In 64-bit mode lret maps to lretl; it is not ambiguous with lretq.
2491 def : MnemonicAlias<"lret", "lretw", "att">, Requires<[In16BitMode]>;
2492 def : MnemonicAlias<"lret", "lretl", "att">, Requires<[Not16BitMode]>;
2494 def : MnemonicAlias<"leavel", "leave", "att">, Requires<[Not64BitMode]>;
2495 def : MnemonicAlias<"leaveq", "leave", "att">, Requires<[In64BitMode]>;
2497 def : MnemonicAlias<"loopz", "loope", "att">;
2498 def : MnemonicAlias<"loopnz", "loopne", "att">;
2500 def : MnemonicAlias<"pop", "popw", "att">, Requires<[In16BitMode]>;
2501 def : MnemonicAlias<"pop", "popl", "att">, Requires<[In32BitMode]>;
2502 def : MnemonicAlias<"pop", "popq", "att">, Requires<[In64BitMode]>;
2503 def : MnemonicAlias<"popf", "popfw", "att">, Requires<[In16BitMode]>;
2504 def : MnemonicAlias<"popf", "popfl", "att">, Requires<[In32BitMode]>;
2505 def : MnemonicAlias<"popf", "popfq", "att">, Requires<[In64BitMode]>;
2506 def : MnemonicAlias<"popfd", "popfl", "att">;
2508 // FIXME: This is wrong for "push reg". "push %bx" should turn into pushw in
2509 // all modes. However: "push (addr)" and "push $42" should default to
2510 // pushl/pushq depending on the current mode. Similar for "pop %bx"
2511 def : MnemonicAlias<"push", "pushw", "att">, Requires<[In16BitMode]>;
2512 def : MnemonicAlias<"push", "pushl", "att">, Requires<[In32BitMode]>;
2513 def : MnemonicAlias<"push", "pushq", "att">, Requires<[In64BitMode]>;
2514 def : MnemonicAlias<"pushf", "pushfw", "att">, Requires<[In16BitMode]>;
2515 def : MnemonicAlias<"pushf", "pushfl", "att">, Requires<[In32BitMode]>;
2516 def : MnemonicAlias<"pushf", "pushfq", "att">, Requires<[In64BitMode]>;
2517 def : MnemonicAlias<"pushfd", "pushfl", "att">;
2519 def : MnemonicAlias<"popad", "popal", "intel">, Requires<[Not64BitMode]>;
2520 def : MnemonicAlias<"pushad", "pushal", "intel">, Requires<[Not64BitMode]>;
2521 def : MnemonicAlias<"popa", "popaw", "intel">, Requires<[In16BitMode]>;
2522 def : MnemonicAlias<"pusha", "pushaw", "intel">, Requires<[In16BitMode]>;
2523 def : MnemonicAlias<"popa", "popal", "intel">, Requires<[In32BitMode]>;
2524 def : MnemonicAlias<"pusha", "pushal", "intel">, Requires<[In32BitMode]>;
2526 def : MnemonicAlias<"popa", "popaw", "att">, Requires<[In16BitMode]>;
2527 def : MnemonicAlias<"pusha", "pushaw", "att">, Requires<[In16BitMode]>;
2528 def : MnemonicAlias<"popa", "popal", "att">, Requires<[In32BitMode]>;
2529 def : MnemonicAlias<"pusha", "pushal", "att">, Requires<[In32BitMode]>;
2531 def : MnemonicAlias<"repe", "rep", "att">;
2532 def : MnemonicAlias<"repz", "rep", "att">;
2533 def : MnemonicAlias<"repnz", "repne", "att">;
2535 def : MnemonicAlias<"ret", "retw", "att">, Requires<[In16BitMode]>;
2536 def : MnemonicAlias<"ret", "retl", "att">, Requires<[In32BitMode]>;
2537 def : MnemonicAlias<"ret", "retq", "att">, Requires<[In64BitMode]>;
2539 def : MnemonicAlias<"salb", "shlb", "att">;
2540 def : MnemonicAlias<"salw", "shlw", "att">;
2541 def : MnemonicAlias<"sall", "shll", "att">;
2542 def : MnemonicAlias<"salq", "shlq", "att">;
2544 def : MnemonicAlias<"smovb", "movsb", "att">;
2545 def : MnemonicAlias<"smovw", "movsw", "att">;
2546 def : MnemonicAlias<"smovl", "movsl", "att">;
2547 def : MnemonicAlias<"smovq", "movsq", "att">;
2549 def : MnemonicAlias<"ud2a", "ud2", "att">;
2550 def : MnemonicAlias<"verrw", "verr", "att">;
2552 // System instruction aliases.
2553 def : MnemonicAlias<"iret", "iretw", "att">, Requires<[In16BitMode]>;
2554 def : MnemonicAlias<"iret", "iretl", "att">, Requires<[Not16BitMode]>;
2555 def : MnemonicAlias<"sysret", "sysretl", "att">;
2556 def : MnemonicAlias<"sysexit", "sysexitl", "att">;
2558 def : MnemonicAlias<"lgdt", "lgdtw", "att">, Requires<[In16BitMode]>;
2559 def : MnemonicAlias<"lgdt", "lgdtl", "att">, Requires<[In32BitMode]>;
2560 def : MnemonicAlias<"lgdt", "lgdtq", "att">, Requires<[In64BitMode]>;
2561 def : MnemonicAlias<"lidt", "lidtw", "att">, Requires<[In16BitMode]>;
2562 def : MnemonicAlias<"lidt", "lidtl", "att">, Requires<[In32BitMode]>;
2563 def : MnemonicAlias<"lidt", "lidtq", "att">, Requires<[In64BitMode]>;
2564 def : MnemonicAlias<"sgdt", "sgdtw", "att">, Requires<[In16BitMode]>;
2565 def : MnemonicAlias<"sgdt", "sgdtl", "att">, Requires<[In32BitMode]>;
2566 def : MnemonicAlias<"sgdt", "sgdtq", "att">, Requires<[In64BitMode]>;
2567 def : MnemonicAlias<"sidt", "sidtw", "att">, Requires<[In16BitMode]>;
2568 def : MnemonicAlias<"sidt", "sidtl", "att">, Requires<[In32BitMode]>;
2569 def : MnemonicAlias<"sidt", "sidtq", "att">, Requires<[In64BitMode]>;
2572 // Floating point stack aliases.
2573 def : MnemonicAlias<"fcmovz", "fcmove", "att">;
2574 def : MnemonicAlias<"fcmova", "fcmovnbe", "att">;
2575 def : MnemonicAlias<"fcmovnae", "fcmovb", "att">;
2576 def : MnemonicAlias<"fcmovna", "fcmovbe", "att">;
2577 def : MnemonicAlias<"fcmovae", "fcmovnb", "att">;
2578 def : MnemonicAlias<"fcomip", "fcompi", "att">;
2579 def : MnemonicAlias<"fildq", "fildll", "att">;
2580 def : MnemonicAlias<"fistpq", "fistpll", "att">;
2581 def : MnemonicAlias<"fisttpq", "fisttpll", "att">;
2582 def : MnemonicAlias<"fldcww", "fldcw", "att">;
2583 def : MnemonicAlias<"fnstcww", "fnstcw", "att">;
2584 def : MnemonicAlias<"fnstsww", "fnstsw", "att">;
2585 def : MnemonicAlias<"fucomip", "fucompi", "att">;
2586 def : MnemonicAlias<"fwait", "wait">;
2588 def : MnemonicAlias<"fxsaveq", "fxsave64", "att">;
2589 def : MnemonicAlias<"fxrstorq", "fxrstor64", "att">;
2590 def : MnemonicAlias<"xsaveq", "xsave64", "att">;
2591 def : MnemonicAlias<"xrstorq", "xrstor64", "att">;
2592 def : MnemonicAlias<"xsaveoptq", "xsaveopt64", "att">;
2595 class CondCodeAlias<string Prefix,string Suffix, string OldCond, string NewCond,
2597 : MnemonicAlias<!strconcat(Prefix, OldCond, Suffix),
2598 !strconcat(Prefix, NewCond, Suffix), VariantName>;
2600 /// IntegerCondCodeMnemonicAlias - This multiclass defines a bunch of
2601 /// MnemonicAlias's that canonicalize the condition code in a mnemonic, for
2602 /// example "setz" -> "sete".
2603 multiclass IntegerCondCodeMnemonicAlias<string Prefix, string Suffix,
2605 def C : CondCodeAlias<Prefix, Suffix, "c", "b", V>; // setc -> setb
2606 def Z : CondCodeAlias<Prefix, Suffix, "z" , "e", V>; // setz -> sete
2607 def NA : CondCodeAlias<Prefix, Suffix, "na", "be", V>; // setna -> setbe
2608 def NB : CondCodeAlias<Prefix, Suffix, "nb", "ae", V>; // setnb -> setae
2609 def NC : CondCodeAlias<Prefix, Suffix, "nc", "ae", V>; // setnc -> setae
2610 def NG : CondCodeAlias<Prefix, Suffix, "ng", "le", V>; // setng -> setle
2611 def NL : CondCodeAlias<Prefix, Suffix, "nl", "ge", V>; // setnl -> setge
2612 def NZ : CondCodeAlias<Prefix, Suffix, "nz", "ne", V>; // setnz -> setne
2613 def PE : CondCodeAlias<Prefix, Suffix, "pe", "p", V>; // setpe -> setp
2614 def PO : CondCodeAlias<Prefix, Suffix, "po", "np", V>; // setpo -> setnp
2616 def NAE : CondCodeAlias<Prefix, Suffix, "nae", "b", V>; // setnae -> setb
2617 def NBE : CondCodeAlias<Prefix, Suffix, "nbe", "a", V>; // setnbe -> seta
2618 def NGE : CondCodeAlias<Prefix, Suffix, "nge", "l", V>; // setnge -> setl
2619 def NLE : CondCodeAlias<Prefix, Suffix, "nle", "g", V>; // setnle -> setg
2622 // Aliases for set<CC>
2623 defm : IntegerCondCodeMnemonicAlias<"set", "">;
2624 // Aliases for j<CC>
2625 defm : IntegerCondCodeMnemonicAlias<"j", "">;
2626 // Aliases for cmov<CC>{w,l,q}
2627 defm : IntegerCondCodeMnemonicAlias<"cmov", "w", "att">;
2628 defm : IntegerCondCodeMnemonicAlias<"cmov", "l", "att">;
2629 defm : IntegerCondCodeMnemonicAlias<"cmov", "q", "att">;
2630 // No size suffix for intel-style asm.
2631 defm : IntegerCondCodeMnemonicAlias<"cmov", "", "intel">;
2634 //===----------------------------------------------------------------------===//
2635 // Assembler Instruction Aliases
2636 //===----------------------------------------------------------------------===//
2638 // aad/aam default to base 10 if no operand is specified.
2639 def : InstAlias<"aad", (AAD8i8 10)>;
2640 def : InstAlias<"aam", (AAM8i8 10)>;
2642 // Disambiguate the mem/imm form of bt-without-a-suffix as btl.
2643 // Likewise for btc/btr/bts.
2644 def : InstAlias<"bt {$imm, $mem|$mem, $imm}",
2645 (BT32mi8 i32mem:$mem, i32i8imm:$imm), 0>;
2646 def : InstAlias<"btc {$imm, $mem|$mem, $imm}",
2647 (BTC32mi8 i32mem:$mem, i32i8imm:$imm), 0>;
2648 def : InstAlias<"btr {$imm, $mem|$mem, $imm}",
2649 (BTR32mi8 i32mem:$mem, i32i8imm:$imm), 0>;
2650 def : InstAlias<"bts {$imm, $mem|$mem, $imm}",
2651 (BTS32mi8 i32mem:$mem, i32i8imm:$imm), 0>;
2654 def : InstAlias<"clrb $reg", (XOR8rr GR8 :$reg, GR8 :$reg), 0>;
2655 def : InstAlias<"clrw $reg", (XOR16rr GR16:$reg, GR16:$reg), 0>;
2656 def : InstAlias<"clrl $reg", (XOR32rr GR32:$reg, GR32:$reg), 0>;
2657 def : InstAlias<"clrq $reg", (XOR64rr GR64:$reg, GR64:$reg), 0>;
2659 // lods aliases. Accept the destination being omitted because it's implicit
2660 // in the mnemonic, or the mnemonic suffix being omitted because it's implicit
2661 // in the destination.
2662 def : InstAlias<"lodsb $src", (LODSB srcidx8:$src), 0>;
2663 def : InstAlias<"lodsw $src", (LODSW srcidx16:$src), 0>;
2664 def : InstAlias<"lods{l|d} $src", (LODSL srcidx32:$src), 0>;
2665 def : InstAlias<"lodsq $src", (LODSQ srcidx64:$src), 0>, Requires<[In64BitMode]>;
2666 def : InstAlias<"lods {$src, %al|al, $src}", (LODSB srcidx8:$src), 0>;
2667 def : InstAlias<"lods {$src, %ax|ax, $src}", (LODSW srcidx16:$src), 0>;
2668 def : InstAlias<"lods {$src, %eax|eax, $src}", (LODSL srcidx32:$src), 0>;
2669 def : InstAlias<"lods {$src, %rax|rax, $src}", (LODSQ srcidx64:$src), 0>, Requires<[In64BitMode]>;
2671 // stos aliases. Accept the source being omitted because it's implicit in
2672 // the mnemonic, or the mnemonic suffix being omitted because it's implicit
2674 def : InstAlias<"stosb $dst", (STOSB dstidx8:$dst), 0>;
2675 def : InstAlias<"stosw $dst", (STOSW dstidx16:$dst), 0>;
2676 def : InstAlias<"stos{l|d} $dst", (STOSL dstidx32:$dst), 0>;
2677 def : InstAlias<"stosq $dst", (STOSQ dstidx64:$dst), 0>, Requires<[In64BitMode]>;
2678 def : InstAlias<"stos {%al, $dst|$dst, al}", (STOSB dstidx8:$dst), 0>;
2679 def : InstAlias<"stos {%ax, $dst|$dst, ax}", (STOSW dstidx16:$dst), 0>;
2680 def : InstAlias<"stos {%eax, $dst|$dst, eax}", (STOSL dstidx32:$dst), 0>;
2681 def : InstAlias<"stos {%rax, $dst|$dst, rax}", (STOSQ dstidx64:$dst), 0>, Requires<[In64BitMode]>;
2683 // scas aliases. Accept the destination being omitted because it's implicit
2684 // in the mnemonic, or the mnemonic suffix being omitted because it's implicit
2685 // in the destination.
2686 def : InstAlias<"scasb $dst", (SCASB dstidx8:$dst), 0>;
2687 def : InstAlias<"scasw $dst", (SCASW dstidx16:$dst), 0>;
2688 def : InstAlias<"scas{l|d} $dst", (SCASL dstidx32:$dst), 0>;
2689 def : InstAlias<"scasq $dst", (SCASQ dstidx64:$dst), 0>, Requires<[In64BitMode]>;
2690 def : InstAlias<"scas {$dst, %al|al, $dst}", (SCASB dstidx8:$dst), 0>;
2691 def : InstAlias<"scas {$dst, %ax|ax, $dst}", (SCASW dstidx16:$dst), 0>;
2692 def : InstAlias<"scas {$dst, %eax|eax, $dst}", (SCASL dstidx32:$dst), 0>;
2693 def : InstAlias<"scas {$dst, %rax|rax, $dst}", (SCASQ dstidx64:$dst), 0>, Requires<[In64BitMode]>;
2695 // div and idiv aliases for explicit A register.
2696 def : InstAlias<"div{b}\t{$src, %al|al, $src}", (DIV8r GR8 :$src)>;
2697 def : InstAlias<"div{w}\t{$src, %ax|ax, $src}", (DIV16r GR16:$src)>;
2698 def : InstAlias<"div{l}\t{$src, %eax|eax, $src}", (DIV32r GR32:$src)>;
2699 def : InstAlias<"div{q}\t{$src, %rax|rax, $src}", (DIV64r GR64:$src)>;
2700 def : InstAlias<"div{b}\t{$src, %al|al, $src}", (DIV8m i8mem :$src)>;
2701 def : InstAlias<"div{w}\t{$src, %ax|ax, $src}", (DIV16m i16mem:$src)>;
2702 def : InstAlias<"div{l}\t{$src, %eax|eax, $src}", (DIV32m i32mem:$src)>;
2703 def : InstAlias<"div{q}\t{$src, %rax|rax, $src}", (DIV64m i64mem:$src)>;
2704 def : InstAlias<"idiv{b}\t{$src, %al|al, $src}", (IDIV8r GR8 :$src)>;
2705 def : InstAlias<"idiv{w}\t{$src, %ax|ax, $src}", (IDIV16r GR16:$src)>;
2706 def : InstAlias<"idiv{l}\t{$src, %eax|eax, $src}", (IDIV32r GR32:$src)>;
2707 def : InstAlias<"idiv{q}\t{$src, %rax|rax, $src}", (IDIV64r GR64:$src)>;
2708 def : InstAlias<"idiv{b}\t{$src, %al|al, $src}", (IDIV8m i8mem :$src)>;
2709 def : InstAlias<"idiv{w}\t{$src, %ax|ax, $src}", (IDIV16m i16mem:$src)>;
2710 def : InstAlias<"idiv{l}\t{$src, %eax|eax, $src}", (IDIV32m i32mem:$src)>;
2711 def : InstAlias<"idiv{q}\t{$src, %rax|rax, $src}", (IDIV64m i64mem:$src)>;
2715 // Various unary fpstack operations default to operating on on ST1.
2716 // For example, "fxch" -> "fxch %st(1)"
2717 def : InstAlias<"faddp", (ADD_FPrST0 ST1), 0>;
2718 def : InstAlias<"fsub{|r}p", (SUBR_FPrST0 ST1), 0>;
2719 def : InstAlias<"fsub{r|}p", (SUB_FPrST0 ST1), 0>;
2720 def : InstAlias<"fmulp", (MUL_FPrST0 ST1), 0>;
2721 def : InstAlias<"fdiv{|r}p", (DIVR_FPrST0 ST1), 0>;
2722 def : InstAlias<"fdiv{r|}p", (DIV_FPrST0 ST1), 0>;
2723 def : InstAlias<"fxch", (XCH_F ST1), 0>;
2724 def : InstAlias<"fcom", (COM_FST0r ST1), 0>;
2725 def : InstAlias<"fcomp", (COMP_FST0r ST1), 0>;
2726 def : InstAlias<"fcomi", (COM_FIr ST1), 0>;
2727 def : InstAlias<"fcompi", (COM_FIPr ST1), 0>;
2728 def : InstAlias<"fucom", (UCOM_Fr ST1), 0>;
2729 def : InstAlias<"fucomp", (UCOM_FPr ST1), 0>;
2730 def : InstAlias<"fucomi", (UCOM_FIr ST1), 0>;
2731 def : InstAlias<"fucompi", (UCOM_FIPr ST1), 0>;
2733 // Handle fmul/fadd/fsub/fdiv instructions with explicitly written st(0) op.
2734 // For example, "fadd %st(4), %st(0)" -> "fadd %st(4)". We also disambiguate
2735 // instructions like "fadd %st(0), %st(0)" as "fadd %st(0)" for consistency with
2737 multiclass FpUnaryAlias<string Mnemonic, Instruction Inst, bit EmitAlias = 1> {
2738 def : InstAlias<!strconcat(Mnemonic, "\t{$op, %st(0)|st(0), $op}"),
2739 (Inst RST:$op), EmitAlias>;
2740 def : InstAlias<!strconcat(Mnemonic, "\t{%st(0), %st(0)|st(0), st(0)}"),
2741 (Inst ST0), EmitAlias>;
2744 defm : FpUnaryAlias<"fadd", ADD_FST0r>;
2745 defm : FpUnaryAlias<"faddp", ADD_FPrST0, 0>;
2746 defm : FpUnaryAlias<"fsub", SUB_FST0r>;
2747 defm : FpUnaryAlias<"fsub{|r}p", SUBR_FPrST0>;
2748 defm : FpUnaryAlias<"fsubr", SUBR_FST0r>;
2749 defm : FpUnaryAlias<"fsub{r|}p", SUB_FPrST0>;
2750 defm : FpUnaryAlias<"fmul", MUL_FST0r>;
2751 defm : FpUnaryAlias<"fmulp", MUL_FPrST0>;
2752 defm : FpUnaryAlias<"fdiv", DIV_FST0r>;
2753 defm : FpUnaryAlias<"fdiv{|r}p", DIVR_FPrST0>;
2754 defm : FpUnaryAlias<"fdivr", DIVR_FST0r>;
2755 defm : FpUnaryAlias<"fdiv{r|}p", DIV_FPrST0>;
2756 defm : FpUnaryAlias<"fcomi", COM_FIr, 0>;
2757 defm : FpUnaryAlias<"fucomi", UCOM_FIr, 0>;
2758 defm : FpUnaryAlias<"fcompi", COM_FIPr>;
2759 defm : FpUnaryAlias<"fucompi", UCOM_FIPr>;
2762 // Handle "f{mulp,addp} st(0), $op" the same as "f{mulp,addp} $op", since they
2763 // commute. We also allow fdiv[r]p/fsubrp even though they don't commute,
2764 // solely because gas supports it.
2765 def : InstAlias<"faddp\t{%st(0), $op|$op, st(0)}", (ADD_FPrST0 RST:$op), 0>;
2766 def : InstAlias<"fmulp\t{%st(0), $op|$op, st(0)}", (MUL_FPrST0 RST:$op)>;
2767 def : InstAlias<"fsub{|r}p\t{%st(0), $op|$op, st(0)}", (SUBR_FPrST0 RST:$op)>;
2768 def : InstAlias<"fsub{r|}p\t{%st(0), $op|$op, st(0)}", (SUB_FPrST0 RST:$op)>;
2769 def : InstAlias<"fdiv{|r}p\t{%st(0), $op|$op, st(0)}", (DIVR_FPrST0 RST:$op)>;
2770 def : InstAlias<"fdiv{r|}p\t{%st(0), $op|$op, st(0)}", (DIV_FPrST0 RST:$op)>;
2772 // We accept "fnstsw %eax" even though it only writes %ax.
2773 def : InstAlias<"fnstsw\t{%eax|eax}", (FNSTSW16r)>;
2774 def : InstAlias<"fnstsw\t{%al|al}" , (FNSTSW16r)>;
2775 def : InstAlias<"fnstsw" , (FNSTSW16r)>;
2777 // lcall and ljmp aliases. This seems to be an odd mapping in 64-bit mode, but
2778 // this is compatible with what GAS does.
2779 def : InstAlias<"lcall $seg, $off", (FARCALL32i i32imm:$off, i16imm:$seg), 0>, Requires<[Not16BitMode]>;
2780 def : InstAlias<"ljmp $seg, $off", (FARJMP32i i32imm:$off, i16imm:$seg), 0>, Requires<[Not16BitMode]>;
2781 def : InstAlias<"lcall {*}$dst", (FARCALL32m opaque48mem:$dst), 0>, Requires<[Not16BitMode]>;
2782 def : InstAlias<"ljmp {*}$dst", (FARJMP32m opaque48mem:$dst), 0>, Requires<[Not16BitMode]>;
2783 def : InstAlias<"lcall $seg, $off", (FARCALL16i i16imm:$off, i16imm:$seg), 0>, Requires<[In16BitMode]>;
2784 def : InstAlias<"ljmp $seg, $off", (FARJMP16i i16imm:$off, i16imm:$seg), 0>, Requires<[In16BitMode]>;
2785 def : InstAlias<"lcall {*}$dst", (FARCALL16m opaque32mem:$dst), 0>, Requires<[In16BitMode]>;
2786 def : InstAlias<"ljmp {*}$dst", (FARJMP16m opaque32mem:$dst), 0>, Requires<[In16BitMode]>;
2788 def : InstAlias<"call {*}$dst", (CALL64m i64mem:$dst), 0>, Requires<[In64BitMode]>;
2789 def : InstAlias<"jmp {*}$dst", (JMP64m i64mem:$dst), 0>, Requires<[In64BitMode]>;
2790 def : InstAlias<"call {*}$dst", (CALL32m i32mem:$dst), 0>, Requires<[In32BitMode]>;
2791 def : InstAlias<"jmp {*}$dst", (JMP32m i32mem:$dst), 0>, Requires<[In32BitMode]>;
2792 def : InstAlias<"call {*}$dst", (CALL16m i16mem:$dst), 0>, Requires<[In16BitMode]>;
2793 def : InstAlias<"jmp {*}$dst", (JMP16m i16mem:$dst), 0>, Requires<[In16BitMode]>;
2796 // "imul <imm>, B" is an alias for "imul <imm>, B, B".
2797 def : InstAlias<"imulw {$imm, $r|$r, $imm}", (IMUL16rri GR16:$r, GR16:$r, i16imm:$imm), 0>;
2798 def : InstAlias<"imulw {$imm, $r|$r, $imm}", (IMUL16rri8 GR16:$r, GR16:$r, i16i8imm:$imm), 0>;
2799 def : InstAlias<"imull {$imm, $r|$r, $imm}", (IMUL32rri GR32:$r, GR32:$r, i32imm:$imm), 0>;
2800 def : InstAlias<"imull {$imm, $r|$r, $imm}", (IMUL32rri8 GR32:$r, GR32:$r, i32i8imm:$imm), 0>;
2801 def : InstAlias<"imulq {$imm, $r|$r, $imm}", (IMUL64rri32 GR64:$r, GR64:$r, i64i32imm:$imm), 0>;
2802 def : InstAlias<"imulq {$imm, $r|$r, $imm}", (IMUL64rri8 GR64:$r, GR64:$r, i64i8imm:$imm), 0>;
2804 // inb %dx -> inb %al, %dx
2805 def : InstAlias<"inb\t{%dx|dx}", (IN8rr), 0>;
2806 def : InstAlias<"inw\t{%dx|dx}", (IN16rr), 0>;
2807 def : InstAlias<"inl\t{%dx|dx}", (IN32rr), 0>;
2808 def : InstAlias<"inb\t$port", (IN8ri i8imm:$port), 0>;
2809 def : InstAlias<"inw\t$port", (IN16ri i8imm:$port), 0>;
2810 def : InstAlias<"inl\t$port", (IN32ri i8imm:$port), 0>;
2813 // jmp and call aliases for lcall and ljmp. jmp $42,$5 -> ljmp
2814 def : InstAlias<"call $seg, $off", (FARCALL16i i16imm:$off, i16imm:$seg)>, Requires<[In16BitMode]>;
2815 def : InstAlias<"jmp $seg, $off", (FARJMP16i i16imm:$off, i16imm:$seg)>, Requires<[In16BitMode]>;
2816 def : InstAlias<"call $seg, $off", (FARCALL32i i32imm:$off, i16imm:$seg)>, Requires<[Not16BitMode]>;
2817 def : InstAlias<"jmp $seg, $off", (FARJMP32i i32imm:$off, i16imm:$seg)>, Requires<[Not16BitMode]>;
2818 def : InstAlias<"callw $seg, $off", (FARCALL16i i16imm:$off, i16imm:$seg)>;
2819 def : InstAlias<"jmpw $seg, $off", (FARJMP16i i16imm:$off, i16imm:$seg)>;
2820 def : InstAlias<"calll $seg, $off", (FARCALL32i i32imm:$off, i16imm:$seg)>;
2821 def : InstAlias<"jmpl $seg, $off", (FARJMP32i i32imm:$off, i16imm:$seg)>;
2823 // Force mov without a suffix with a segment and mem to prefer the 'l' form of
2824 // the move. All segment/mem forms are equivalent, this has the shortest
2826 def : InstAlias<"mov {$mem, $seg|$seg, $mem}", (MOV32sm SEGMENT_REG:$seg, i32mem:$mem), 0>;
2827 def : InstAlias<"mov {$seg, $mem|$mem, $seg}", (MOV32ms i32mem:$mem, SEGMENT_REG:$seg), 0>;
2829 // Match 'movq <largeimm>, <reg>' as an alias for movabsq.
2830 def : InstAlias<"movq {$imm, $reg|$reg, $imm}", (MOV64ri GR64:$reg, i64imm:$imm), 0>;
2832 // Match 'movq GR64, MMX' as an alias for movd.
2833 def : InstAlias<"movq {$src, $dst|$dst, $src}",
2834 (MMX_MOVD64to64rr VR64:$dst, GR64:$src), 0>;
2835 def : InstAlias<"movq {$src, $dst|$dst, $src}",
2836 (MMX_MOVD64from64rr GR64:$dst, VR64:$src), 0>;
2839 def : InstAlias<"movsx {$src, $dst|$dst, $src}", (MOVSX16rr8 GR16:$dst, GR8:$src), 0>;
2840 def : InstAlias<"movsx {$src, $dst|$dst, $src}", (MOVSX16rm8 GR16:$dst, i8mem:$src), 0>;
2841 def : InstAlias<"movsx {$src, $dst|$dst, $src}", (MOVSX32rr8 GR32:$dst, GR8:$src), 0>;
2842 def : InstAlias<"movsx {$src, $dst|$dst, $src}", (MOVSX32rr16 GR32:$dst, GR16:$src), 0>;
2843 def : InstAlias<"movsx {$src, $dst|$dst, $src}", (MOVSX64rr8 GR64:$dst, GR8:$src), 0>;
2844 def : InstAlias<"movsx {$src, $dst|$dst, $src}", (MOVSX64rr16 GR64:$dst, GR16:$src), 0>;
2845 def : InstAlias<"movsx {$src, $dst|$dst, $src}", (MOVSX64rr32 GR64:$dst, GR32:$src), 0>;
2848 def : InstAlias<"movzx {$src, $dst|$dst, $src}", (MOVZX16rr8 GR16:$dst, GR8:$src), 0>;
2849 def : InstAlias<"movzx {$src, $dst|$dst, $src}", (MOVZX16rm8 GR16:$dst, i8mem:$src), 0>;
2850 def : InstAlias<"movzx {$src, $dst|$dst, $src}", (MOVZX32rr8 GR32:$dst, GR8:$src), 0>;
2851 def : InstAlias<"movzx {$src, $dst|$dst, $src}", (MOVZX32rr16 GR32:$dst, GR16:$src), 0>;
2852 def : InstAlias<"movzx {$src, $dst|$dst, $src}", (MOVZX64rr8_Q GR64:$dst, GR8:$src), 0>;
2853 def : InstAlias<"movzx {$src, $dst|$dst, $src}", (MOVZX64rr16_Q GR64:$dst, GR16:$src), 0>;
2854 // Note: No GR32->GR64 movzx form.
2856 // outb %dx -> outb %al, %dx
2857 def : InstAlias<"outb\t{%dx|dx}", (OUT8rr), 0>;
2858 def : InstAlias<"outw\t{%dx|dx}", (OUT16rr), 0>;
2859 def : InstAlias<"outl\t{%dx|dx}", (OUT32rr), 0>;
2860 def : InstAlias<"outb\t$port", (OUT8ir i8imm:$port), 0>;
2861 def : InstAlias<"outw\t$port", (OUT16ir i8imm:$port), 0>;
2862 def : InstAlias<"outl\t$port", (OUT32ir i8imm:$port), 0>;
2864 // 'sldt <mem>' can be encoded with either sldtw or sldtq with the same
2865 // effect (both store to a 16-bit mem). Force to sldtw to avoid ambiguity
2866 // errors, since its encoding is the most compact.
2867 def : InstAlias<"sldt $mem", (SLDT16m i16mem:$mem), 0>;
2869 // shld/shrd op,op -> shld op, op, CL
2870 def : InstAlias<"shld{w}\t{$r2, $r1|$r1, $r2}", (SHLD16rrCL GR16:$r1, GR16:$r2), 0>;
2871 def : InstAlias<"shld{l}\t{$r2, $r1|$r1, $r2}", (SHLD32rrCL GR32:$r1, GR32:$r2), 0>;
2872 def : InstAlias<"shld{q}\t{$r2, $r1|$r1, $r2}", (SHLD64rrCL GR64:$r1, GR64:$r2), 0>;
2873 def : InstAlias<"shrd{w}\t{$r2, $r1|$r1, $r2}", (SHRD16rrCL GR16:$r1, GR16:$r2), 0>;
2874 def : InstAlias<"shrd{l}\t{$r2, $r1|$r1, $r2}", (SHRD32rrCL GR32:$r1, GR32:$r2), 0>;
2875 def : InstAlias<"shrd{q}\t{$r2, $r1|$r1, $r2}", (SHRD64rrCL GR64:$r1, GR64:$r2), 0>;
2877 def : InstAlias<"shld{w}\t{$reg, $mem|$mem, $reg}", (SHLD16mrCL i16mem:$mem, GR16:$reg), 0>;
2878 def : InstAlias<"shld{l}\t{$reg, $mem|$mem, $reg}", (SHLD32mrCL i32mem:$mem, GR32:$reg), 0>;
2879 def : InstAlias<"shld{q}\t{$reg, $mem|$mem, $reg}", (SHLD64mrCL i64mem:$mem, GR64:$reg), 0>;
2880 def : InstAlias<"shrd{w}\t{$reg, $mem|$mem, $reg}", (SHRD16mrCL i16mem:$mem, GR16:$reg), 0>;
2881 def : InstAlias<"shrd{l}\t{$reg, $mem|$mem, $reg}", (SHRD32mrCL i32mem:$mem, GR32:$reg), 0>;
2882 def : InstAlias<"shrd{q}\t{$reg, $mem|$mem, $reg}", (SHRD64mrCL i64mem:$mem, GR64:$reg), 0>;
2884 /* FIXME: This is disabled because the asm matcher is currently incapable of
2885 * matching a fixed immediate like $1.
2886 // "shl X, $1" is an alias for "shl X".
2887 multiclass ShiftRotateByOneAlias<string Mnemonic, string Opc> {
2888 def : InstAlias<!strconcat(Mnemonic, "b $op, $$1"),
2889 (!cast<Instruction>(!strconcat(Opc, "8r1")) GR8:$op)>;
2890 def : InstAlias<!strconcat(Mnemonic, "w $op, $$1"),
2891 (!cast<Instruction>(!strconcat(Opc, "16r1")) GR16:$op)>;
2892 def : InstAlias<!strconcat(Mnemonic, "l $op, $$1"),
2893 (!cast<Instruction>(!strconcat(Opc, "32r1")) GR32:$op)>;
2894 def : InstAlias<!strconcat(Mnemonic, "q $op, $$1"),
2895 (!cast<Instruction>(!strconcat(Opc, "64r1")) GR64:$op)>;
2896 def : InstAlias<!strconcat(Mnemonic, "b $op, $$1"),
2897 (!cast<Instruction>(!strconcat(Opc, "8m1")) i8mem:$op)>;
2898 def : InstAlias<!strconcat(Mnemonic, "w $op, $$1"),
2899 (!cast<Instruction>(!strconcat(Opc, "16m1")) i16mem:$op)>;
2900 def : InstAlias<!strconcat(Mnemonic, "l $op, $$1"),
2901 (!cast<Instruction>(!strconcat(Opc, "32m1")) i32mem:$op)>;
2902 def : InstAlias<!strconcat(Mnemonic, "q $op, $$1"),
2903 (!cast<Instruction>(!strconcat(Opc, "64m1")) i64mem:$op)>;
2906 defm : ShiftRotateByOneAlias<"rcl", "RCL">;
2907 defm : ShiftRotateByOneAlias<"rcr", "RCR">;
2908 defm : ShiftRotateByOneAlias<"rol", "ROL">;
2909 defm : ShiftRotateByOneAlias<"ror", "ROR">;
2912 // test: We accept "testX <reg>, <mem>" and "testX <mem>, <reg>" as synonyms.
2913 def : InstAlias<"test{b}\t{$val, $mem|$mem, $val}",
2914 (TEST8rm GR8 :$val, i8mem :$mem), 0>;
2915 def : InstAlias<"test{w}\t{$val, $mem|$mem, $val}",
2916 (TEST16rm GR16:$val, i16mem:$mem), 0>;
2917 def : InstAlias<"test{l}\t{$val, $mem|$mem, $val}",
2918 (TEST32rm GR32:$val, i32mem:$mem), 0>;
2919 def : InstAlias<"test{q}\t{$val, $mem|$mem, $val}",
2920 (TEST64rm GR64:$val, i64mem:$mem), 0>;
2922 // xchg: We accept "xchgX <reg>, <mem>" and "xchgX <mem>, <reg>" as synonyms.
2923 def : InstAlias<"xchg{b}\t{$mem, $val|$val, $mem}",
2924 (XCHG8rm GR8 :$val, i8mem :$mem), 0>;
2925 def : InstAlias<"xchg{w}\t{$mem, $val|$val, $mem}",
2926 (XCHG16rm GR16:$val, i16mem:$mem), 0>;
2927 def : InstAlias<"xchg{l}\t{$mem, $val|$val, $mem}",
2928 (XCHG32rm GR32:$val, i32mem:$mem), 0>;
2929 def : InstAlias<"xchg{q}\t{$mem, $val|$val, $mem}",
2930 (XCHG64rm GR64:$val, i64mem:$mem), 0>;
2932 // xchg: We accept "xchgX <reg>, %eax" and "xchgX %eax, <reg>" as synonyms.
2933 def : InstAlias<"xchg{w}\t{%ax, $src|$src, ax}", (XCHG16ar GR16:$src), 0>;
2934 def : InstAlias<"xchg{l}\t{%eax, $src|$src, eax}",
2935 (XCHG32ar GR32:$src), 0>, Requires<[Not64BitMode]>;
2936 def : InstAlias<"xchg{l}\t{%eax, $src|$src, eax}",
2937 (XCHG32ar64 GR32_NOAX:$src), 0>, Requires<[In64BitMode]>;
2938 def : InstAlias<"xchg{q}\t{%rax, $src|$src, rax}", (XCHG64ar GR64:$src), 0>;