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::LOCAL_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"; }
285 def X86MemVX32XOperand : AsmOperandClass { let Name = "MemVX32X"; }
286 def X86MemVY32XOperand : AsmOperandClass { let Name = "MemVY32X"; }
287 def X86MemVX64XOperand : AsmOperandClass { let Name = "MemVX64X"; }
288 def X86MemVY64XOperand : AsmOperandClass { let Name = "MemVY64X"; }
291 def X86AbsMemAsmOperand : AsmOperandClass {
293 let SuperClasses = [X86MemAsmOperand];
296 class X86MemOperand<string printMethod,
297 AsmOperandClass parserMatchClass = X86MemAsmOperand> : Operand<iPTR> {
298 let PrintMethod = printMethod;
299 let MIOperandInfo = (ops ptr_rc, i8imm, ptr_rc_nosp, i32imm, i8imm);
300 let ParserMatchClass = parserMatchClass;
301 let OperandType = "OPERAND_MEMORY";
304 // Gather mem operands
305 class X86VMemOperand<RegisterClass RC, string printMethod,
306 AsmOperandClass parserMatchClass>
307 : X86MemOperand<printMethod, parserMatchClass> {
308 let MIOperandInfo = (ops ptr_rc, i8imm, RC, i32imm, i8imm);
311 def anymem : X86MemOperand<"printanymem">;
313 def opaque32mem : X86MemOperand<"printopaquemem">;
314 def opaque48mem : X86MemOperand<"printopaquemem">;
315 def opaque80mem : X86MemOperand<"printopaquemem">;
316 def opaque512mem : X86MemOperand<"printopaquemem">;
318 def i8mem : X86MemOperand<"printi8mem", X86Mem8AsmOperand>;
319 def i16mem : X86MemOperand<"printi16mem", X86Mem16AsmOperand>;
320 def i32mem : X86MemOperand<"printi32mem", X86Mem32AsmOperand>;
321 def i64mem : X86MemOperand<"printi64mem", X86Mem64AsmOperand>;
322 def i128mem : X86MemOperand<"printi128mem", X86Mem128AsmOperand>;
323 def i256mem : X86MemOperand<"printi256mem", X86Mem256AsmOperand>;
324 def i512mem : X86MemOperand<"printi512mem", X86Mem512AsmOperand>;
325 def f32mem : X86MemOperand<"printf32mem", X86Mem32AsmOperand>;
326 def f64mem : X86MemOperand<"printf64mem", X86Mem64AsmOperand>;
327 def f80mem : X86MemOperand<"printf80mem", X86Mem80AsmOperand>;
328 def f128mem : X86MemOperand<"printf128mem", X86Mem128AsmOperand>;
329 def f256mem : X86MemOperand<"printf256mem", X86Mem256AsmOperand>;
330 def f512mem : X86MemOperand<"printf512mem", X86Mem512AsmOperand>;
332 def v512mem : X86VMemOperand<VR512, "printf512mem", X86Mem512AsmOperand>;
334 // Gather mem operands
335 def vx32mem : X86VMemOperand<VR128, "printi32mem", X86MemVX32Operand>;
336 def vy32mem : X86VMemOperand<VR256, "printi32mem", X86MemVY32Operand>;
337 def vx64mem : X86VMemOperand<VR128, "printi64mem", X86MemVX64Operand>;
338 def vy64mem : X86VMemOperand<VR256, "printi64mem", X86MemVY64Operand>;
340 def vx32xmem : X86VMemOperand<VR128X, "printi32mem", X86MemVX32XOperand>;
341 def vx64xmem : X86VMemOperand<VR128X, "printi32mem", X86MemVX64XOperand>;
342 def vy32xmem : X86VMemOperand<VR256X, "printi32mem", X86MemVY32XOperand>;
343 def vy64xmem : X86VMemOperand<VR256X, "printi64mem", X86MemVY64XOperand>;
344 def vz32mem : X86VMemOperand<VR512, "printi32mem", X86MemVZ32Operand>;
345 def vz64mem : X86VMemOperand<VR512, "printi64mem", X86MemVZ64Operand>;
347 // A version of i8mem for use on x86-64 that uses GR64_NOREX instead of
348 // plain GR64, so that it doesn't potentially require a REX prefix.
349 def i8mem_NOREX : Operand<i64> {
350 let PrintMethod = "printi8mem";
351 let MIOperandInfo = (ops GR64_NOREX, i8imm, GR64_NOREX_NOSP, i32imm, i8imm);
352 let ParserMatchClass = X86Mem8AsmOperand;
353 let OperandType = "OPERAND_MEMORY";
356 // GPRs available for tailcall.
357 // It represents GR32_TC, GR64_TC or GR64_TCW64.
358 def ptr_rc_tailcall : PointerLikeRegClass<2>;
360 // Special i32mem for addresses of load folding tail calls. These are not
361 // allowed to use callee-saved registers since they must be scheduled
362 // after callee-saved register are popped.
363 def i32mem_TC : Operand<i32> {
364 let PrintMethod = "printi32mem";
365 let MIOperandInfo = (ops ptr_rc_tailcall, i8imm, ptr_rc_tailcall,
367 let ParserMatchClass = X86Mem32AsmOperand;
368 let OperandType = "OPERAND_MEMORY";
371 // Special i64mem for addresses of load folding tail calls. These are not
372 // allowed to use callee-saved registers since they must be scheduled
373 // after callee-saved register are popped.
374 def i64mem_TC : Operand<i64> {
375 let PrintMethod = "printi64mem";
376 let MIOperandInfo = (ops ptr_rc_tailcall, i8imm,
377 ptr_rc_tailcall, i32imm, i8imm);
378 let ParserMatchClass = X86Mem64AsmOperand;
379 let OperandType = "OPERAND_MEMORY";
382 let OperandType = "OPERAND_PCREL",
383 ParserMatchClass = X86AbsMemAsmOperand,
384 PrintMethod = "printPCRelImm" in {
385 def i32imm_pcrel : Operand<i32>;
386 def i16imm_pcrel : Operand<i16>;
388 // Branch targets have OtherVT type and print as pc-relative values.
389 def brtarget : Operand<OtherVT>;
390 def brtarget8 : Operand<OtherVT>;
394 // Special parser to detect 16-bit mode to select 16-bit displacement.
395 def X86AbsMem16AsmOperand : AsmOperandClass {
396 let Name = "AbsMem16";
397 let RenderMethod = "addAbsMemOperands";
398 let SuperClasses = [X86AbsMemAsmOperand];
401 // Branch targets have OtherVT type and print as pc-relative values.
402 let OperandType = "OPERAND_PCREL",
403 PrintMethod = "printPCRelImm" in {
404 let ParserMatchClass = X86AbsMem16AsmOperand in
405 def brtarget16 : Operand<OtherVT>;
406 let ParserMatchClass = X86AbsMemAsmOperand in
407 def brtarget32 : Operand<OtherVT>;
410 let RenderMethod = "addSrcIdxOperands" in {
411 def X86SrcIdx8Operand : AsmOperandClass {
412 let Name = "SrcIdx8";
413 let SuperClasses = [X86Mem8AsmOperand];
415 def X86SrcIdx16Operand : AsmOperandClass {
416 let Name = "SrcIdx16";
417 let SuperClasses = [X86Mem16AsmOperand];
419 def X86SrcIdx32Operand : AsmOperandClass {
420 let Name = "SrcIdx32";
421 let SuperClasses = [X86Mem32AsmOperand];
423 def X86SrcIdx64Operand : AsmOperandClass {
424 let Name = "SrcIdx64";
425 let SuperClasses = [X86Mem64AsmOperand];
427 } // RenderMethod = "addSrcIdxOperands"
429 let RenderMethod = "addDstIdxOperands" in {
430 def X86DstIdx8Operand : AsmOperandClass {
431 let Name = "DstIdx8";
432 let SuperClasses = [X86Mem8AsmOperand];
434 def X86DstIdx16Operand : AsmOperandClass {
435 let Name = "DstIdx16";
436 let SuperClasses = [X86Mem16AsmOperand];
438 def X86DstIdx32Operand : AsmOperandClass {
439 let Name = "DstIdx32";
440 let SuperClasses = [X86Mem32AsmOperand];
442 def X86DstIdx64Operand : AsmOperandClass {
443 let Name = "DstIdx64";
444 let SuperClasses = [X86Mem64AsmOperand];
446 } // RenderMethod = "addDstIdxOperands"
448 let RenderMethod = "addMemOffsOperands" in {
449 def X86MemOffs16_8AsmOperand : AsmOperandClass {
450 let Name = "MemOffs16_8";
451 let SuperClasses = [X86Mem8AsmOperand];
453 def X86MemOffs16_16AsmOperand : AsmOperandClass {
454 let Name = "MemOffs16_16";
455 let SuperClasses = [X86Mem16AsmOperand];
457 def X86MemOffs16_32AsmOperand : AsmOperandClass {
458 let Name = "MemOffs16_32";
459 let SuperClasses = [X86Mem32AsmOperand];
461 def X86MemOffs32_8AsmOperand : AsmOperandClass {
462 let Name = "MemOffs32_8";
463 let SuperClasses = [X86Mem8AsmOperand];
465 def X86MemOffs32_16AsmOperand : AsmOperandClass {
466 let Name = "MemOffs32_16";
467 let SuperClasses = [X86Mem16AsmOperand];
469 def X86MemOffs32_32AsmOperand : AsmOperandClass {
470 let Name = "MemOffs32_32";
471 let SuperClasses = [X86Mem32AsmOperand];
473 def X86MemOffs32_64AsmOperand : AsmOperandClass {
474 let Name = "MemOffs32_64";
475 let SuperClasses = [X86Mem64AsmOperand];
477 def X86MemOffs64_8AsmOperand : AsmOperandClass {
478 let Name = "MemOffs64_8";
479 let SuperClasses = [X86Mem8AsmOperand];
481 def X86MemOffs64_16AsmOperand : AsmOperandClass {
482 let Name = "MemOffs64_16";
483 let SuperClasses = [X86Mem16AsmOperand];
485 def X86MemOffs64_32AsmOperand : AsmOperandClass {
486 let Name = "MemOffs64_32";
487 let SuperClasses = [X86Mem32AsmOperand];
489 def X86MemOffs64_64AsmOperand : AsmOperandClass {
490 let Name = "MemOffs64_64";
491 let SuperClasses = [X86Mem64AsmOperand];
493 } // RenderMethod = "addMemOffsOperands"
495 class X86SrcIdxOperand<string printMethod, AsmOperandClass parserMatchClass>
496 : X86MemOperand<printMethod, parserMatchClass> {
497 let MIOperandInfo = (ops ptr_rc, i8imm);
500 class X86DstIdxOperand<string printMethod, AsmOperandClass parserMatchClass>
501 : X86MemOperand<printMethod, parserMatchClass> {
502 let MIOperandInfo = (ops ptr_rc);
505 def srcidx8 : X86SrcIdxOperand<"printSrcIdx8", X86SrcIdx8Operand>;
506 def srcidx16 : X86SrcIdxOperand<"printSrcIdx16", X86SrcIdx16Operand>;
507 def srcidx32 : X86SrcIdxOperand<"printSrcIdx32", X86SrcIdx32Operand>;
508 def srcidx64 : X86SrcIdxOperand<"printSrcIdx64", X86SrcIdx64Operand>;
509 def dstidx8 : X86DstIdxOperand<"printDstIdx8", X86DstIdx8Operand>;
510 def dstidx16 : X86DstIdxOperand<"printDstIdx16", X86DstIdx16Operand>;
511 def dstidx32 : X86DstIdxOperand<"printDstIdx32", X86DstIdx32Operand>;
512 def dstidx64 : X86DstIdxOperand<"printDstIdx64", X86DstIdx64Operand>;
514 class X86MemOffsOperand<Operand immOperand, string printMethod,
515 AsmOperandClass parserMatchClass>
516 : X86MemOperand<printMethod, parserMatchClass> {
517 let MIOperandInfo = (ops immOperand, i8imm);
520 def offset16_8 : X86MemOffsOperand<i16imm, "printMemOffs8",
521 X86MemOffs16_8AsmOperand>;
522 def offset16_16 : X86MemOffsOperand<i16imm, "printMemOffs16",
523 X86MemOffs16_16AsmOperand>;
524 def offset16_32 : X86MemOffsOperand<i16imm, "printMemOffs32",
525 X86MemOffs16_32AsmOperand>;
526 def offset32_8 : X86MemOffsOperand<i32imm, "printMemOffs8",
527 X86MemOffs32_8AsmOperand>;
528 def offset32_16 : X86MemOffsOperand<i32imm, "printMemOffs16",
529 X86MemOffs32_16AsmOperand>;
530 def offset32_32 : X86MemOffsOperand<i32imm, "printMemOffs32",
531 X86MemOffs32_32AsmOperand>;
532 def offset32_64 : X86MemOffsOperand<i32imm, "printMemOffs64",
533 X86MemOffs32_64AsmOperand>;
534 def offset64_8 : X86MemOffsOperand<i64imm, "printMemOffs8",
535 X86MemOffs64_8AsmOperand>;
536 def offset64_16 : X86MemOffsOperand<i64imm, "printMemOffs16",
537 X86MemOffs64_16AsmOperand>;
538 def offset64_32 : X86MemOffsOperand<i64imm, "printMemOffs32",
539 X86MemOffs64_32AsmOperand>;
540 def offset64_64 : X86MemOffsOperand<i64imm, "printMemOffs64",
541 X86MemOffs64_64AsmOperand>;
543 def SSECC : Operand<i8> {
544 let PrintMethod = "printSSEAVXCC";
545 let OperandType = "OPERAND_IMMEDIATE";
548 def i8immZExt3 : ImmLeaf<i8, [{
549 return Imm >= 0 && Imm < 8;
552 def AVXCC : Operand<i8> {
553 let PrintMethod = "printSSEAVXCC";
554 let OperandType = "OPERAND_IMMEDIATE";
557 def i8immZExt5 : ImmLeaf<i8, [{
558 return Imm >= 0 && Imm < 32;
561 def AVX512ICC : Operand<i8> {
562 let PrintMethod = "printSSEAVXCC";
563 let OperandType = "OPERAND_IMMEDIATE";
566 def XOPCC : Operand<i8> {
567 let PrintMethod = "printXOPCC";
568 let OperandType = "OPERAND_IMMEDIATE";
571 class ImmSExtAsmOperandClass : AsmOperandClass {
572 let SuperClasses = [ImmAsmOperand];
573 let RenderMethod = "addImmOperands";
576 def X86GR32orGR64AsmOperand : AsmOperandClass {
577 let Name = "GR32orGR64";
580 def GR32orGR64 : RegisterOperand<GR32> {
581 let ParserMatchClass = X86GR32orGR64AsmOperand;
583 def AVX512RCOperand : AsmOperandClass {
584 let Name = "AVX512RC";
586 def AVX512RC : Operand<i32> {
587 let PrintMethod = "printRoundingControl";
588 let OperandType = "OPERAND_IMMEDIATE";
589 let ParserMatchClass = AVX512RCOperand;
592 // Sign-extended immediate classes. We don't need to define the full lattice
593 // here because there is no instruction with an ambiguity between ImmSExti64i32
596 // The strange ranges come from the fact that the assembler always works with
597 // 64-bit immediates, but for a 16-bit target value we want to accept both "-1"
598 // (which will be a -1ULL), and "0xFF" (-1 in 16-bits).
601 // [0xFFFFFFFF80000000, 0xFFFFFFFFFFFFFFFF]
602 def ImmSExti64i32AsmOperand : ImmSExtAsmOperandClass {
603 let Name = "ImmSExti64i32";
606 // [0, 0x0000007F] | [0x000000000000FF80, 0x000000000000FFFF] |
607 // [0xFFFFFFFFFFFFFF80, 0xFFFFFFFFFFFFFFFF]
608 def ImmSExti16i8AsmOperand : ImmSExtAsmOperandClass {
609 let Name = "ImmSExti16i8";
610 let SuperClasses = [ImmSExti64i32AsmOperand];
613 // [0, 0x0000007F] | [0x00000000FFFFFF80, 0x00000000FFFFFFFF] |
614 // [0xFFFFFFFFFFFFFF80, 0xFFFFFFFFFFFFFFFF]
615 def ImmSExti32i8AsmOperand : ImmSExtAsmOperandClass {
616 let Name = "ImmSExti32i8";
620 // [0xFFFFFFFFFFFFFF80, 0xFFFFFFFFFFFFFFFF]
621 def ImmSExti64i8AsmOperand : ImmSExtAsmOperandClass {
622 let Name = "ImmSExti64i8";
623 let SuperClasses = [ImmSExti16i8AsmOperand, ImmSExti32i8AsmOperand,
624 ImmSExti64i32AsmOperand];
627 // Unsigned immediate used by SSE/AVX instructions
629 // [0xFFFFFFFFFFFFFF80, 0xFFFFFFFFFFFFFFFF]
630 def ImmUnsignedi8AsmOperand : AsmOperandClass {
631 let Name = "ImmUnsignedi8";
632 let RenderMethod = "addImmOperands";
635 // A couple of more descriptive operand definitions.
636 // 16-bits but only 8 bits are significant.
637 def i16i8imm : Operand<i16> {
638 let ParserMatchClass = ImmSExti16i8AsmOperand;
639 let OperandType = "OPERAND_IMMEDIATE";
641 // 32-bits but only 8 bits are significant.
642 def i32i8imm : Operand<i32> {
643 let ParserMatchClass = ImmSExti32i8AsmOperand;
644 let OperandType = "OPERAND_IMMEDIATE";
647 // 64-bits but only 32 bits are significant.
648 def i64i32imm : Operand<i64> {
649 let ParserMatchClass = ImmSExti64i32AsmOperand;
650 let OperandType = "OPERAND_IMMEDIATE";
653 // 64-bits but only 8 bits are significant.
654 def i64i8imm : Operand<i64> {
655 let ParserMatchClass = ImmSExti64i8AsmOperand;
656 let OperandType = "OPERAND_IMMEDIATE";
659 // Unsigned 8-bit immediate used by SSE/AVX instructions.
660 def u8imm : Operand<i8> {
661 let PrintMethod = "printU8Imm";
662 let ParserMatchClass = ImmUnsignedi8AsmOperand;
663 let OperandType = "OPERAND_IMMEDIATE";
666 // 32-bit immediate but only 8-bits are significant and they are unsigned.
667 // Used by some SSE/AVX instructions that use intrinsics.
668 def i32u8imm : Operand<i32> {
669 let PrintMethod = "printU8Imm";
670 let ParserMatchClass = ImmUnsignedi8AsmOperand;
671 let OperandType = "OPERAND_IMMEDIATE";
674 // 64-bits but only 32 bits are significant, and those bits are treated as being
676 def i64i32imm_pcrel : Operand<i64> {
677 let PrintMethod = "printPCRelImm";
678 let ParserMatchClass = X86AbsMemAsmOperand;
679 let OperandType = "OPERAND_PCREL";
682 def lea64_32mem : Operand<i32> {
683 let PrintMethod = "printanymem";
684 let MIOperandInfo = (ops GR64, i8imm, GR64_NOSP, i32imm, i8imm);
685 let ParserMatchClass = X86MemAsmOperand;
688 // Memory operands that use 64-bit pointers in both ILP32 and LP64.
689 def lea64mem : Operand<i64> {
690 let PrintMethod = "printanymem";
691 let MIOperandInfo = (ops GR64, i8imm, GR64_NOSP, i32imm, i8imm);
692 let ParserMatchClass = X86MemAsmOperand;
696 //===----------------------------------------------------------------------===//
697 // X86 Complex Pattern Definitions.
700 // Define X86 specific addressing mode.
701 def addr : ComplexPattern<iPTR, 5, "SelectAddr", [], [SDNPWantParent]>;
702 def lea32addr : ComplexPattern<i32, 5, "SelectLEAAddr",
703 [add, sub, mul, X86mul_imm, shl, or, frameindex],
705 // In 64-bit mode 32-bit LEAs can use RIP-relative addressing.
706 def lea64_32addr : ComplexPattern<i32, 5, "SelectLEA64_32Addr",
707 [add, sub, mul, X86mul_imm, shl, or,
708 frameindex, X86WrapperRIP],
711 def tls32addr : ComplexPattern<i32, 5, "SelectTLSADDRAddr",
712 [tglobaltlsaddr], []>;
714 def tls32baseaddr : ComplexPattern<i32, 5, "SelectTLSADDRAddr",
715 [tglobaltlsaddr], []>;
717 def lea64addr : ComplexPattern<i64, 5, "SelectLEAAddr",
718 [add, sub, mul, X86mul_imm, shl, or, frameindex,
721 def tls64addr : ComplexPattern<i64, 5, "SelectTLSADDRAddr",
722 [tglobaltlsaddr], []>;
724 def tls64baseaddr : ComplexPattern<i64, 5, "SelectTLSADDRAddr",
725 [tglobaltlsaddr], []>;
727 def vectoraddr : ComplexPattern<iPTR, 5, "SelectVectorAddr", [],[SDNPWantParent]>;
729 //===----------------------------------------------------------------------===//
730 // X86 Instruction Predicate Definitions.
731 def HasCMov : Predicate<"Subtarget->hasCMov()">;
732 def NoCMov : Predicate<"!Subtarget->hasCMov()">;
734 def HasMMX : Predicate<"Subtarget->hasMMX()">;
735 def Has3DNow : Predicate<"Subtarget->has3DNow()">;
736 def Has3DNowA : Predicate<"Subtarget->has3DNowA()">;
737 def HasSSE1 : Predicate<"Subtarget->hasSSE1()">;
738 def UseSSE1 : Predicate<"Subtarget->hasSSE1() && !Subtarget->hasAVX()">;
739 def HasSSE2 : Predicate<"Subtarget->hasSSE2()">;
740 def UseSSE2 : Predicate<"Subtarget->hasSSE2() && !Subtarget->hasAVX()">;
741 def HasSSE3 : Predicate<"Subtarget->hasSSE3()">;
742 def UseSSE3 : Predicate<"Subtarget->hasSSE3() && !Subtarget->hasAVX()">;
743 def HasSSSE3 : Predicate<"Subtarget->hasSSSE3()">;
744 def UseSSSE3 : Predicate<"Subtarget->hasSSSE3() && !Subtarget->hasAVX()">;
745 def HasSSE41 : Predicate<"Subtarget->hasSSE41()">;
746 def NoSSE41 : Predicate<"!Subtarget->hasSSE41()">;
747 def UseSSE41 : Predicate<"Subtarget->hasSSE41() && !Subtarget->hasAVX()">;
748 def HasSSE42 : Predicate<"Subtarget->hasSSE42()">;
749 def UseSSE42 : Predicate<"Subtarget->hasSSE42() && !Subtarget->hasAVX()">;
750 def HasSSE4A : Predicate<"Subtarget->hasSSE4A()">;
751 def HasAVX : Predicate<"Subtarget->hasAVX()">;
752 def HasAVX2 : Predicate<"Subtarget->hasAVX2()">;
753 def HasAVX1Only : Predicate<"Subtarget->hasAVX() && !Subtarget->hasAVX2()">;
754 def HasAVX512 : Predicate<"Subtarget->hasAVX512()">,
755 AssemblerPredicate<"FeatureAVX512", "AVX-512 ISA">;
756 def UseAVX : Predicate<"Subtarget->hasAVX() && !Subtarget->hasAVX512()">;
757 def UseAVX2 : Predicate<"Subtarget->hasAVX2() && !Subtarget->hasAVX512()">;
758 def NoAVX512 : Predicate<"!Subtarget->hasAVX512()">;
759 def HasCDI : Predicate<"Subtarget->hasCDI()">,
760 AssemblerPredicate<"FeatureCDI", "AVX-512 CD ISA">;
761 def HasPFI : Predicate<"Subtarget->hasPFI()">,
762 AssemblerPredicate<"FeaturePFI", "AVX-512 PF ISA">;
763 def HasERI : Predicate<"Subtarget->hasERI()">,
764 AssemblerPredicate<"FeatureERI", "AVX-512 ER ISA">;
765 def HasDQI : Predicate<"Subtarget->hasDQI()">,
766 AssemblerPredicate<"FeatureDQI", "AVX-512 DQ ISA">;
767 def NoDQI : Predicate<"!Subtarget->hasDQI()">;
768 def HasBWI : Predicate<"Subtarget->hasBWI()">,
769 AssemblerPredicate<"FeatureBWI", "AVX-512 BW ISA">;
770 def NoBWI : Predicate<"!Subtarget->hasBWI()">;
771 def HasVLX : Predicate<"Subtarget->hasVLX()">,
772 AssemblerPredicate<"FeatureVLX", "AVX-512 VL ISA">;
773 def NoVLX : Predicate<"!Subtarget->hasVLX()">;
774 def NoVLX_Or_NoBWI : Predicate<"!Subtarget->hasVLX() || !Subtarget->hasBWI()">;
776 def HasPOPCNT : Predicate<"Subtarget->hasPOPCNT()">;
777 def HasAES : Predicate<"Subtarget->hasAES()">;
778 def HasPCLMUL : Predicate<"Subtarget->hasPCLMUL()">;
779 def HasFMA : Predicate<"Subtarget->hasFMA()">;
780 def UseFMAOnAVX : Predicate<"Subtarget->hasFMA() && !Subtarget->hasAVX512()">;
781 def HasFMA4 : Predicate<"Subtarget->hasFMA4()">;
782 def HasXOP : Predicate<"Subtarget->hasXOP()">;
783 def HasTBM : Predicate<"Subtarget->hasTBM()">;
784 def HasMOVBE : Predicate<"Subtarget->hasMOVBE()">;
785 def HasRDRAND : Predicate<"Subtarget->hasRDRAND()">;
786 def HasF16C : Predicate<"Subtarget->hasF16C()">;
787 def HasFSGSBase : Predicate<"Subtarget->hasFSGSBase()">;
788 def HasLZCNT : Predicate<"Subtarget->hasLZCNT()">;
789 def HasBMI : Predicate<"Subtarget->hasBMI()">;
790 def HasBMI2 : Predicate<"Subtarget->hasBMI2()">;
791 def HasRTM : Predicate<"Subtarget->hasRTM()">;
792 def HasHLE : Predicate<"Subtarget->hasHLE()">;
793 def HasTSX : Predicate<"Subtarget->hasRTM() || Subtarget->hasHLE()">;
794 def HasADX : Predicate<"Subtarget->hasADX()">;
795 def HasSHA : Predicate<"Subtarget->hasSHA()">;
796 def HasPRFCHW : Predicate<"Subtarget->hasPRFCHW()">;
797 def HasRDSEED : Predicate<"Subtarget->hasRDSEED()">;
798 def HasPrefetchW : Predicate<"Subtarget->hasPRFCHW()">;
799 def FPStackf32 : Predicate<"!Subtarget->hasSSE1()">;
800 def FPStackf64 : Predicate<"!Subtarget->hasSSE2()">;
801 def HasMPX : Predicate<"Subtarget->hasMPX()">;
802 def HasCmpxchg16b: Predicate<"Subtarget->hasCmpxchg16b()">;
803 def Not64BitMode : Predicate<"!Subtarget->is64Bit()">,
804 AssemblerPredicate<"!Mode64Bit", "Not 64-bit mode">;
805 def In64BitMode : Predicate<"Subtarget->is64Bit()">,
806 AssemblerPredicate<"Mode64Bit", "64-bit mode">;
807 def IsLP64 : Predicate<"Subtarget->isTarget64BitLP64()">;
808 def NotLP64 : Predicate<"!Subtarget->isTarget64BitLP64()">;
809 def In16BitMode : Predicate<"Subtarget->is16Bit()">,
810 AssemblerPredicate<"Mode16Bit", "16-bit mode">;
811 def Not16BitMode : Predicate<"!Subtarget->is16Bit()">,
812 AssemblerPredicate<"!Mode16Bit", "Not 16-bit mode">;
813 def In32BitMode : Predicate<"Subtarget->is32Bit()">,
814 AssemblerPredicate<"Mode32Bit", "32-bit mode">;
815 def IsWin64 : Predicate<"Subtarget->isTargetWin64()">;
816 def NotWin64 : Predicate<"!Subtarget->isTargetWin64()">;
817 def IsPS4 : Predicate<"Subtarget->isTargetPS4()">;
818 def NotPS4 : Predicate<"!Subtarget->isTargetPS4()">;
819 def IsNaCl : Predicate<"Subtarget->isTargetNaCl()">;
820 def NotNaCl : Predicate<"!Subtarget->isTargetNaCl()">;
821 def SmallCode : Predicate<"TM.getCodeModel() == CodeModel::Small">;
822 def KernelCode : Predicate<"TM.getCodeModel() == CodeModel::Kernel">;
823 def FarData : Predicate<"TM.getCodeModel() != CodeModel::Small &&"
824 "TM.getCodeModel() != CodeModel::Kernel">;
825 def NearData : Predicate<"TM.getCodeModel() == CodeModel::Small ||"
826 "TM.getCodeModel() == CodeModel::Kernel">;
827 def IsStatic : Predicate<"TM.getRelocationModel() == Reloc::Static">;
828 def IsNotPIC : Predicate<"TM.getRelocationModel() != Reloc::PIC_">;
829 def OptForSize : Predicate<"OptForSize">;
830 def OptForSpeed : Predicate<"!OptForSize">;
831 def FastBTMem : Predicate<"!Subtarget->isBTMemSlow()">;
832 def CallImmAddr : Predicate<"Subtarget->IsLegalToCallImmediateAddr(TM)">;
833 def FavorMemIndirectCall : Predicate<"!Subtarget->callRegIndirect()">;
834 def NotSlowIncDec : Predicate<"!Subtarget->slowIncDec()">;
835 def HasFastMem32 : Predicate<"!Subtarget->isUnalignedMem32Slow()">;
837 //===----------------------------------------------------------------------===//
838 // X86 Instruction Format Definitions.
841 include "X86InstrFormats.td"
843 //===----------------------------------------------------------------------===//
844 // Pattern fragments.
847 // X86 specific condition code. These correspond to CondCode in
848 // X86InstrInfo.h. They must be kept in synch.
849 def X86_COND_A : PatLeaf<(i8 0)>; // alt. COND_NBE
850 def X86_COND_AE : PatLeaf<(i8 1)>; // alt. COND_NC
851 def X86_COND_B : PatLeaf<(i8 2)>; // alt. COND_C
852 def X86_COND_BE : PatLeaf<(i8 3)>; // alt. COND_NA
853 def X86_COND_E : PatLeaf<(i8 4)>; // alt. COND_Z
854 def X86_COND_G : PatLeaf<(i8 5)>; // alt. COND_NLE
855 def X86_COND_GE : PatLeaf<(i8 6)>; // alt. COND_NL
856 def X86_COND_L : PatLeaf<(i8 7)>; // alt. COND_NGE
857 def X86_COND_LE : PatLeaf<(i8 8)>; // alt. COND_NG
858 def X86_COND_NE : PatLeaf<(i8 9)>; // alt. COND_NZ
859 def X86_COND_NO : PatLeaf<(i8 10)>;
860 def X86_COND_NP : PatLeaf<(i8 11)>; // alt. COND_PO
861 def X86_COND_NS : PatLeaf<(i8 12)>;
862 def X86_COND_O : PatLeaf<(i8 13)>;
863 def X86_COND_P : PatLeaf<(i8 14)>; // alt. COND_PE
864 def X86_COND_S : PatLeaf<(i8 15)>;
866 // Predicate used to help when pattern matching LZCNT/TZCNT.
867 def X86_COND_E_OR_NE : ImmLeaf<i8, [{
868 return (Imm == X86::COND_E) || (Imm == X86::COND_NE);
872 def i16immSExt8 : ImmLeaf<i16, [{ return Imm == (int8_t)Imm; }]>;
873 def i32immSExt8 : ImmLeaf<i32, [{ return Imm == (int8_t)Imm; }]>;
874 def i64immSExt8 : ImmLeaf<i64, [{ return Imm == (int8_t)Imm; }]>;
876 // If we have multiple users of an immediate, it's much smaller to reuse
877 // the register, rather than encode the immediate in every instruction.
878 // This has the risk of increasing register pressure from stretched live
879 // ranges, however, the immediates should be trivial to rematerialize by
880 // the RA in the event of high register pressure.
881 // TODO : This is currently enabled for stores and binary ops. There are more
882 // cases for which this can be enabled, though this catches the bulk of the
884 // TODO2 : This should really also be enabled under O2, but there's currently
885 // an issue with RA where we don't pull the constants into their users
886 // when we rematerialize them. I'll follow-up on enabling O2 after we fix that
888 // TODO3 : This is currently limited to single basic blocks (DAG creation
889 // pulls block immediates to the top and merges them if necessary).
890 // Eventually, it would be nice to allow ConstantHoisting to merge constants
891 // globally for potentially added savings.
893 def imm8_su : PatLeaf<(i8 imm), [{
894 return !shouldAvoidImmediateInstFormsForSize(N);
896 def imm16_su : PatLeaf<(i16 imm), [{
897 return !shouldAvoidImmediateInstFormsForSize(N);
899 def imm32_su : PatLeaf<(i32 imm), [{
900 return !shouldAvoidImmediateInstFormsForSize(N);
903 def i16immSExt8_su : PatLeaf<(i16immSExt8), [{
904 return !shouldAvoidImmediateInstFormsForSize(N);
906 def i32immSExt8_su : PatLeaf<(i32immSExt8), [{
907 return !shouldAvoidImmediateInstFormsForSize(N);
911 def i64immSExt32 : ImmLeaf<i64, [{ return Imm == (int32_t)Imm; }]>;
914 // i64immZExt32 predicate - True if the 64-bit immediate fits in a 32-bit
916 def i64immZExt32 : ImmLeaf<i64, [{ return (uint64_t)Imm == (uint32_t)Imm; }]>;
918 def i64immZExt32SExt8 : ImmLeaf<i64, [{
919 return (uint64_t)Imm == (uint32_t)Imm && (int32_t)Imm == (int8_t)Imm;
922 // Helper fragments for loads.
923 // It's always safe to treat a anyext i16 load as a i32 load if the i16 is
924 // known to be 32-bit aligned or better. Ditto for i8 to i16.
925 def loadi16 : PatFrag<(ops node:$ptr), (i16 (unindexedload node:$ptr)), [{
926 LoadSDNode *LD = cast<LoadSDNode>(N);
927 ISD::LoadExtType ExtType = LD->getExtensionType();
928 if (ExtType == ISD::NON_EXTLOAD)
930 if (ExtType == ISD::EXTLOAD)
931 return LD->getAlignment() >= 2 && !LD->isVolatile();
935 def loadi16_anyext : PatFrag<(ops node:$ptr), (i32 (unindexedload node:$ptr)),[{
936 LoadSDNode *LD = cast<LoadSDNode>(N);
937 ISD::LoadExtType ExtType = LD->getExtensionType();
938 if (ExtType == ISD::EXTLOAD)
939 return LD->getAlignment() >= 2 && !LD->isVolatile();
943 def loadi32 : PatFrag<(ops node:$ptr), (i32 (unindexedload node:$ptr)), [{
944 LoadSDNode *LD = cast<LoadSDNode>(N);
945 ISD::LoadExtType ExtType = LD->getExtensionType();
946 if (ExtType == ISD::NON_EXTLOAD)
948 if (ExtType == ISD::EXTLOAD)
949 return LD->getAlignment() >= 4 && !LD->isVolatile();
953 def loadi8 : PatFrag<(ops node:$ptr), (i8 (load node:$ptr))>;
954 def loadi64 : PatFrag<(ops node:$ptr), (i64 (load node:$ptr))>;
955 def loadf32 : PatFrag<(ops node:$ptr), (f32 (load node:$ptr))>;
956 def loadf64 : PatFrag<(ops node:$ptr), (f64 (load node:$ptr))>;
957 def loadf80 : PatFrag<(ops node:$ptr), (f80 (load node:$ptr))>;
959 def sextloadi16i8 : PatFrag<(ops node:$ptr), (i16 (sextloadi8 node:$ptr))>;
960 def sextloadi32i8 : PatFrag<(ops node:$ptr), (i32 (sextloadi8 node:$ptr))>;
961 def sextloadi32i16 : PatFrag<(ops node:$ptr), (i32 (sextloadi16 node:$ptr))>;
962 def sextloadi64i8 : PatFrag<(ops node:$ptr), (i64 (sextloadi8 node:$ptr))>;
963 def sextloadi64i16 : PatFrag<(ops node:$ptr), (i64 (sextloadi16 node:$ptr))>;
964 def sextloadi64i32 : PatFrag<(ops node:$ptr), (i64 (sextloadi32 node:$ptr))>;
966 def zextloadi8i1 : PatFrag<(ops node:$ptr), (i8 (zextloadi1 node:$ptr))>;
967 def zextloadi16i1 : PatFrag<(ops node:$ptr), (i16 (zextloadi1 node:$ptr))>;
968 def zextloadi32i1 : PatFrag<(ops node:$ptr), (i32 (zextloadi1 node:$ptr))>;
969 def zextloadi16i8 : PatFrag<(ops node:$ptr), (i16 (zextloadi8 node:$ptr))>;
970 def zextloadi32i8 : PatFrag<(ops node:$ptr), (i32 (zextloadi8 node:$ptr))>;
971 def zextloadi32i16 : PatFrag<(ops node:$ptr), (i32 (zextloadi16 node:$ptr))>;
972 def zextloadi64i1 : PatFrag<(ops node:$ptr), (i64 (zextloadi1 node:$ptr))>;
973 def zextloadi64i8 : PatFrag<(ops node:$ptr), (i64 (zextloadi8 node:$ptr))>;
974 def zextloadi64i16 : PatFrag<(ops node:$ptr), (i64 (zextloadi16 node:$ptr))>;
975 def zextloadi64i32 : PatFrag<(ops node:$ptr), (i64 (zextloadi32 node:$ptr))>;
977 def extloadi8i1 : PatFrag<(ops node:$ptr), (i8 (extloadi1 node:$ptr))>;
978 def extloadi16i1 : PatFrag<(ops node:$ptr), (i16 (extloadi1 node:$ptr))>;
979 def extloadi32i1 : PatFrag<(ops node:$ptr), (i32 (extloadi1 node:$ptr))>;
980 def extloadi16i8 : PatFrag<(ops node:$ptr), (i16 (extloadi8 node:$ptr))>;
981 def extloadi32i8 : PatFrag<(ops node:$ptr), (i32 (extloadi8 node:$ptr))>;
982 def extloadi32i16 : PatFrag<(ops node:$ptr), (i32 (extloadi16 node:$ptr))>;
983 def extloadi64i1 : PatFrag<(ops node:$ptr), (i64 (extloadi1 node:$ptr))>;
984 def extloadi64i8 : PatFrag<(ops node:$ptr), (i64 (extloadi8 node:$ptr))>;
985 def extloadi64i16 : PatFrag<(ops node:$ptr), (i64 (extloadi16 node:$ptr))>;
986 def extloadi64i32 : PatFrag<(ops node:$ptr), (i64 (extloadi32 node:$ptr))>;
989 // An 'and' node with a single use.
990 def and_su : PatFrag<(ops node:$lhs, node:$rhs), (and node:$lhs, node:$rhs), [{
991 return N->hasOneUse();
993 // An 'srl' node with a single use.
994 def srl_su : PatFrag<(ops node:$lhs, node:$rhs), (srl node:$lhs, node:$rhs), [{
995 return N->hasOneUse();
997 // An 'trunc' node with a single use.
998 def trunc_su : PatFrag<(ops node:$src), (trunc node:$src), [{
999 return N->hasOneUse();
1002 //===----------------------------------------------------------------------===//
1003 // Instruction list.
1007 let hasSideEffects = 0, SchedRW = [WriteZero] in {
1008 def NOOP : I<0x90, RawFrm, (outs), (ins), "nop", [], IIC_NOP>;
1009 def NOOPW : I<0x1f, MRMXm, (outs), (ins i16mem:$zero),
1010 "nop{w}\t$zero", [], IIC_NOP>, TB, OpSize16;
1011 def NOOPL : I<0x1f, MRMXm, (outs), (ins i32mem:$zero),
1012 "nop{l}\t$zero", [], IIC_NOP>, TB, OpSize32;
1016 // Constructing a stack frame.
1017 def ENTER : Ii16<0xC8, RawFrmImm8, (outs), (ins i16imm:$len, i8imm:$lvl),
1018 "enter\t$len, $lvl", [], IIC_ENTER>, Sched<[WriteMicrocoded]>;
1020 let SchedRW = [WriteALU] in {
1021 let Defs = [EBP, ESP], Uses = [EBP, ESP], mayLoad = 1, hasSideEffects=0 in
1022 def LEAVE : I<0xC9, RawFrm,
1023 (outs), (ins), "leave", [], IIC_LEAVE>,
1024 Requires<[Not64BitMode]>;
1026 let Defs = [RBP,RSP], Uses = [RBP,RSP], mayLoad = 1, hasSideEffects = 0 in
1027 def LEAVE64 : I<0xC9, RawFrm,
1028 (outs), (ins), "leave", [], IIC_LEAVE>,
1029 Requires<[In64BitMode]>;
1032 //===----------------------------------------------------------------------===//
1033 // Miscellaneous Instructions.
1036 let Defs = [ESP], Uses = [ESP], hasSideEffects=0 in {
1037 let mayLoad = 1, SchedRW = [WriteLoad] in {
1038 def POP16r : I<0x58, AddRegFrm, (outs GR16:$reg), (ins), "pop{w}\t$reg", [],
1039 IIC_POP_REG16>, OpSize16;
1040 def POP32r : I<0x58, AddRegFrm, (outs GR32:$reg), (ins), "pop{l}\t$reg", [],
1041 IIC_POP_REG>, OpSize32, Requires<[Not64BitMode]>;
1042 def POP16rmr: I<0x8F, MRM0r, (outs GR16:$reg), (ins), "pop{w}\t$reg", [],
1043 IIC_POP_REG>, OpSize16;
1044 def POP16rmm: I<0x8F, MRM0m, (outs), (ins i16mem:$dst), "pop{w}\t$dst", [],
1045 IIC_POP_MEM>, OpSize16;
1046 def POP32rmr: I<0x8F, MRM0r, (outs GR32:$reg), (ins), "pop{l}\t$reg", [],
1047 IIC_POP_REG>, OpSize32, Requires<[Not64BitMode]>;
1048 def POP32rmm: I<0x8F, MRM0m, (outs), (ins i32mem:$dst), "pop{l}\t$dst", [],
1049 IIC_POP_MEM>, OpSize32, Requires<[Not64BitMode]>;
1050 } // mayLoad, SchedRW
1052 let mayStore = 1, SchedRW = [WriteStore] in {
1053 def PUSH16r : I<0x50, AddRegFrm, (outs), (ins GR16:$reg), "push{w}\t$reg",[],
1054 IIC_PUSH_REG>, OpSize16;
1055 def PUSH32r : I<0x50, AddRegFrm, (outs), (ins GR32:$reg), "push{l}\t$reg",[],
1056 IIC_PUSH_REG>, OpSize32, Requires<[Not64BitMode]>;
1057 def PUSH16rmr: I<0xFF, MRM6r, (outs), (ins GR16:$reg), "push{w}\t$reg",[],
1058 IIC_PUSH_REG>, OpSize16;
1059 def PUSH32rmr: I<0xFF, MRM6r, (outs), (ins GR32:$reg), "push{l}\t$reg",[],
1060 IIC_PUSH_REG>, OpSize32, Requires<[Not64BitMode]>;
1062 def PUSH16i8 : Ii8<0x6a, RawFrm, (outs), (ins i16i8imm:$imm),
1063 "push{w}\t$imm", [], IIC_PUSH_IMM>, OpSize16;
1064 def PUSHi16 : Ii16<0x68, RawFrm, (outs), (ins i16imm:$imm),
1065 "push{w}\t$imm", [], IIC_PUSH_IMM>, OpSize16;
1067 def PUSH32i8 : Ii8<0x6a, RawFrm, (outs), (ins i32i8imm:$imm),
1068 "push{l}\t$imm", [], IIC_PUSH_IMM>, OpSize32,
1069 Requires<[Not64BitMode]>;
1070 def PUSHi32 : Ii32<0x68, RawFrm, (outs), (ins i32imm:$imm),
1071 "push{l}\t$imm", [], IIC_PUSH_IMM>, OpSize32,
1072 Requires<[Not64BitMode]>;
1073 } // mayStore, SchedRW
1075 let mayLoad = 1, mayStore = 1, SchedRW = [WriteRMW] in {
1076 def PUSH16rmm: I<0xFF, MRM6m, (outs), (ins i16mem:$src), "push{w}\t$src",[],
1077 IIC_PUSH_MEM>, OpSize16;
1078 def PUSH32rmm: I<0xFF, MRM6m, (outs), (ins i32mem:$src), "push{l}\t$src",[],
1079 IIC_PUSH_MEM>, OpSize32, Requires<[Not64BitMode]>;
1080 } // mayLoad, mayStore, SchedRW
1084 let Defs = [ESP, EFLAGS], Uses = [ESP], mayLoad = 1, hasSideEffects=0,
1085 SchedRW = [WriteLoad] in {
1086 def POPF16 : I<0x9D, RawFrm, (outs), (ins), "popf{w}", [], IIC_POP_F>,
1088 def POPF32 : I<0x9D, RawFrm, (outs), (ins), "popf{l|d}", [], IIC_POP_FD>,
1089 OpSize32, Requires<[Not64BitMode]>;
1092 let Defs = [ESP], Uses = [ESP, EFLAGS], mayStore = 1, hasSideEffects=0,
1093 SchedRW = [WriteStore] in {
1094 def PUSHF16 : I<0x9C, RawFrm, (outs), (ins), "pushf{w}", [], IIC_PUSH_F>,
1096 def PUSHF32 : I<0x9C, RawFrm, (outs), (ins), "pushf{l|d}", [], IIC_PUSH_F>,
1097 OpSize32, Requires<[Not64BitMode]>;
1100 let Defs = [RSP], Uses = [RSP], hasSideEffects=0 in {
1101 let mayLoad = 1, SchedRW = [WriteLoad] in {
1102 def POP64r : I<0x58, AddRegFrm, (outs GR64:$reg), (ins), "pop{q}\t$reg", [],
1103 IIC_POP_REG>, OpSize32, Requires<[In64BitMode]>;
1104 def POP64rmr: I<0x8F, MRM0r, (outs GR64:$reg), (ins), "pop{q}\t$reg", [],
1105 IIC_POP_REG>, OpSize32, Requires<[In64BitMode]>;
1106 def POP64rmm: I<0x8F, MRM0m, (outs), (ins i64mem:$dst), "pop{q}\t$dst", [],
1107 IIC_POP_MEM>, OpSize32, Requires<[In64BitMode]>;
1108 } // mayLoad, SchedRW
1109 let mayStore = 1, SchedRW = [WriteStore] in {
1110 def PUSH64r : I<0x50, AddRegFrm, (outs), (ins GR64:$reg), "push{q}\t$reg", [],
1111 IIC_PUSH_REG>, OpSize32, Requires<[In64BitMode]>;
1112 def PUSH64rmr: I<0xFF, MRM6r, (outs), (ins GR64:$reg), "push{q}\t$reg", [],
1113 IIC_PUSH_REG>, OpSize32, Requires<[In64BitMode]>;
1114 } // mayStore, SchedRW
1115 let mayLoad = 1, mayStore = 1, SchedRW = [WriteRMW] in {
1116 def PUSH64rmm: I<0xFF, MRM6m, (outs), (ins i64mem:$src), "push{q}\t$src", [],
1117 IIC_PUSH_MEM>, OpSize32, Requires<[In64BitMode]>;
1118 } // mayLoad, mayStore, SchedRW
1121 let Defs = [RSP], Uses = [RSP], hasSideEffects = 0, mayStore = 1,
1122 SchedRW = [WriteStore] in {
1123 def PUSH64i8 : Ii8<0x6a, RawFrm, (outs), (ins i64i8imm:$imm),
1124 "push{q}\t$imm", [], IIC_PUSH_IMM>, Requires<[In64BitMode]>;
1125 def PUSH64i32 : Ii32S<0x68, RawFrm, (outs), (ins i64i32imm:$imm),
1126 "push{q}\t$imm", [], IIC_PUSH_IMM>, OpSize32,
1127 Requires<[In64BitMode]>;
1130 let Defs = [RSP, EFLAGS], Uses = [RSP], mayLoad = 1, hasSideEffects=0 in
1131 def POPF64 : I<0x9D, RawFrm, (outs), (ins), "popfq", [], IIC_POP_FD>,
1132 OpSize32, Requires<[In64BitMode]>, Sched<[WriteLoad]>;
1133 let Defs = [RSP], Uses = [RSP, EFLAGS], mayStore = 1, hasSideEffects=0 in
1134 def PUSHF64 : I<0x9C, RawFrm, (outs), (ins), "pushfq", [], IIC_PUSH_F>,
1135 OpSize32, Requires<[In64BitMode]>, Sched<[WriteStore]>;
1137 let Defs = [EDI, ESI, EBP, EBX, EDX, ECX, EAX, ESP], Uses = [ESP],
1138 mayLoad = 1, hasSideEffects = 0, SchedRW = [WriteLoad] in {
1139 def POPA32 : I<0x61, RawFrm, (outs), (ins), "popal", [], IIC_POP_A>,
1140 OpSize32, Requires<[Not64BitMode]>;
1141 def POPA16 : I<0x61, RawFrm, (outs), (ins), "popaw", [], IIC_POP_A>,
1142 OpSize16, Requires<[Not64BitMode]>;
1144 let Defs = [ESP], Uses = [EDI, ESI, EBP, EBX, EDX, ECX, EAX, ESP],
1145 mayStore = 1, hasSideEffects = 0, SchedRW = [WriteStore] in {
1146 def PUSHA32 : I<0x60, RawFrm, (outs), (ins), "pushal", [], IIC_PUSH_A>,
1147 OpSize32, Requires<[Not64BitMode]>;
1148 def PUSHA16 : I<0x60, RawFrm, (outs), (ins), "pushaw", [], IIC_PUSH_A>,
1149 OpSize16, Requires<[Not64BitMode]>;
1152 let Constraints = "$src = $dst", SchedRW = [WriteALU] in {
1153 // GR32 = bswap GR32
1154 def BSWAP32r : I<0xC8, AddRegFrm,
1155 (outs GR32:$dst), (ins GR32:$src),
1157 [(set GR32:$dst, (bswap GR32:$src))], IIC_BSWAP>, OpSize32, TB;
1159 def BSWAP64r : RI<0xC8, AddRegFrm, (outs GR64:$dst), (ins GR64:$src),
1161 [(set GR64:$dst, (bswap GR64:$src))], IIC_BSWAP>, TB;
1162 } // Constraints = "$src = $dst", SchedRW
1164 // Bit scan instructions.
1165 let Defs = [EFLAGS] in {
1166 def BSF16rr : I<0xBC, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
1167 "bsf{w}\t{$src, $dst|$dst, $src}",
1168 [(set GR16:$dst, EFLAGS, (X86bsf GR16:$src))],
1169 IIC_BIT_SCAN_REG>, PS, OpSize16, Sched<[WriteShift]>;
1170 def BSF16rm : I<0xBC, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
1171 "bsf{w}\t{$src, $dst|$dst, $src}",
1172 [(set GR16:$dst, EFLAGS, (X86bsf (loadi16 addr:$src)))],
1173 IIC_BIT_SCAN_MEM>, PS, OpSize16, Sched<[WriteShiftLd]>;
1174 def BSF32rr : I<0xBC, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
1175 "bsf{l}\t{$src, $dst|$dst, $src}",
1176 [(set GR32:$dst, EFLAGS, (X86bsf GR32:$src))],
1177 IIC_BIT_SCAN_REG>, PS, OpSize32, Sched<[WriteShift]>;
1178 def BSF32rm : I<0xBC, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
1179 "bsf{l}\t{$src, $dst|$dst, $src}",
1180 [(set GR32:$dst, EFLAGS, (X86bsf (loadi32 addr:$src)))],
1181 IIC_BIT_SCAN_MEM>, PS, OpSize32, Sched<[WriteShiftLd]>;
1182 def BSF64rr : RI<0xBC, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
1183 "bsf{q}\t{$src, $dst|$dst, $src}",
1184 [(set GR64:$dst, EFLAGS, (X86bsf GR64:$src))],
1185 IIC_BIT_SCAN_REG>, PS, Sched<[WriteShift]>;
1186 def BSF64rm : RI<0xBC, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
1187 "bsf{q}\t{$src, $dst|$dst, $src}",
1188 [(set GR64:$dst, EFLAGS, (X86bsf (loadi64 addr:$src)))],
1189 IIC_BIT_SCAN_MEM>, PS, Sched<[WriteShiftLd]>;
1191 def BSR16rr : I<0xBD, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
1192 "bsr{w}\t{$src, $dst|$dst, $src}",
1193 [(set GR16:$dst, EFLAGS, (X86bsr GR16:$src))],
1194 IIC_BIT_SCAN_REG>, PS, OpSize16, Sched<[WriteShift]>;
1195 def BSR16rm : I<0xBD, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
1196 "bsr{w}\t{$src, $dst|$dst, $src}",
1197 [(set GR16:$dst, EFLAGS, (X86bsr (loadi16 addr:$src)))],
1198 IIC_BIT_SCAN_MEM>, PS, OpSize16, Sched<[WriteShiftLd]>;
1199 def BSR32rr : I<0xBD, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
1200 "bsr{l}\t{$src, $dst|$dst, $src}",
1201 [(set GR32:$dst, EFLAGS, (X86bsr GR32:$src))],
1202 IIC_BIT_SCAN_REG>, PS, OpSize32, Sched<[WriteShift]>;
1203 def BSR32rm : I<0xBD, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
1204 "bsr{l}\t{$src, $dst|$dst, $src}",
1205 [(set GR32:$dst, EFLAGS, (X86bsr (loadi32 addr:$src)))],
1206 IIC_BIT_SCAN_MEM>, PS, OpSize32, Sched<[WriteShiftLd]>;
1207 def BSR64rr : RI<0xBD, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
1208 "bsr{q}\t{$src, $dst|$dst, $src}",
1209 [(set GR64:$dst, EFLAGS, (X86bsr GR64:$src))],
1210 IIC_BIT_SCAN_REG>, PS, Sched<[WriteShift]>;
1211 def BSR64rm : RI<0xBD, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
1212 "bsr{q}\t{$src, $dst|$dst, $src}",
1213 [(set GR64:$dst, EFLAGS, (X86bsr (loadi64 addr:$src)))],
1214 IIC_BIT_SCAN_MEM>, PS, Sched<[WriteShiftLd]>;
1215 } // Defs = [EFLAGS]
1217 let SchedRW = [WriteMicrocoded] in {
1218 // These uses the DF flag in the EFLAGS register to inc or dec EDI and ESI
1219 let Defs = [EDI,ESI], Uses = [EDI,ESI,EFLAGS] in {
1220 def MOVSB : I<0xA4, RawFrmDstSrc, (outs dstidx8:$dst), (ins srcidx8:$src),
1221 "movsb\t{$src, $dst|$dst, $src}", [], IIC_MOVS>;
1222 def MOVSW : I<0xA5, RawFrmDstSrc, (outs dstidx16:$dst), (ins srcidx16:$src),
1223 "movsw\t{$src, $dst|$dst, $src}", [], IIC_MOVS>, OpSize16;
1224 def MOVSL : I<0xA5, RawFrmDstSrc, (outs dstidx32:$dst), (ins srcidx32:$src),
1225 "movs{l|d}\t{$src, $dst|$dst, $src}", [], IIC_MOVS>, OpSize32;
1226 def MOVSQ : RI<0xA5, RawFrmDstSrc, (outs dstidx64:$dst), (ins srcidx64:$src),
1227 "movsq\t{$src, $dst|$dst, $src}", [], IIC_MOVS>;
1230 // These uses the DF flag in the EFLAGS register to inc or dec EDI and ESI
1231 let Defs = [EDI], Uses = [AL,EDI,EFLAGS] in
1232 def STOSB : I<0xAA, RawFrmDst, (outs dstidx8:$dst), (ins),
1233 "stosb\t{%al, $dst|$dst, al}", [], IIC_STOS>;
1234 let Defs = [EDI], Uses = [AX,EDI,EFLAGS] in
1235 def STOSW : I<0xAB, RawFrmDst, (outs dstidx16:$dst), (ins),
1236 "stosw\t{%ax, $dst|$dst, ax}", [], IIC_STOS>, OpSize16;
1237 let Defs = [EDI], Uses = [EAX,EDI,EFLAGS] in
1238 def STOSL : I<0xAB, RawFrmDst, (outs dstidx32:$dst), (ins),
1239 "stos{l|d}\t{%eax, $dst|$dst, eax}", [], IIC_STOS>, OpSize32;
1240 let Defs = [RCX,RDI], Uses = [RAX,RCX,RDI,EFLAGS] in
1241 def STOSQ : RI<0xAB, RawFrmDst, (outs dstidx64:$dst), (ins),
1242 "stosq\t{%rax, $dst|$dst, rax}", [], IIC_STOS>;
1244 // These uses the DF flag in the EFLAGS register to inc or dec EDI and ESI
1245 let Defs = [EDI,EFLAGS], Uses = [AL,EDI,EFLAGS] in
1246 def SCASB : I<0xAE, RawFrmDst, (outs), (ins dstidx8:$dst),
1247 "scasb\t{$dst, %al|al, $dst}", [], IIC_SCAS>;
1248 let Defs = [EDI,EFLAGS], Uses = [AX,EDI,EFLAGS] in
1249 def SCASW : I<0xAF, RawFrmDst, (outs), (ins dstidx16:$dst),
1250 "scasw\t{$dst, %ax|ax, $dst}", [], IIC_SCAS>, OpSize16;
1251 let Defs = [EDI,EFLAGS], Uses = [EAX,EDI,EFLAGS] in
1252 def SCASL : I<0xAF, RawFrmDst, (outs), (ins dstidx32:$dst),
1253 "scas{l|d}\t{$dst, %eax|eax, $dst}", [], IIC_SCAS>, OpSize32;
1254 let Defs = [EDI,EFLAGS], Uses = [RAX,EDI,EFLAGS] in
1255 def SCASQ : RI<0xAF, RawFrmDst, (outs), (ins dstidx64:$dst),
1256 "scasq\t{$dst, %rax|rax, $dst}", [], IIC_SCAS>;
1258 // These uses the DF flag in the EFLAGS register to inc or dec EDI and ESI
1259 let Defs = [EDI,ESI,EFLAGS], Uses = [EDI,ESI,EFLAGS] in {
1260 def CMPSB : I<0xA6, RawFrmDstSrc, (outs), (ins dstidx8:$dst, srcidx8:$src),
1261 "cmpsb\t{$dst, $src|$src, $dst}", [], IIC_CMPS>;
1262 def CMPSW : I<0xA7, RawFrmDstSrc, (outs), (ins dstidx16:$dst, srcidx16:$src),
1263 "cmpsw\t{$dst, $src|$src, $dst}", [], IIC_CMPS>, OpSize16;
1264 def CMPSL : I<0xA7, RawFrmDstSrc, (outs), (ins dstidx32:$dst, srcidx32:$src),
1265 "cmps{l|d}\t{$dst, $src|$src, $dst}", [], IIC_CMPS>, OpSize32;
1266 def CMPSQ : RI<0xA7, RawFrmDstSrc, (outs), (ins dstidx64:$dst, srcidx64:$src),
1267 "cmpsq\t{$dst, $src|$src, $dst}", [], IIC_CMPS>;
1271 //===----------------------------------------------------------------------===//
1272 // Move Instructions.
1274 let SchedRW = [WriteMove] in {
1275 let hasSideEffects = 0 in {
1276 def MOV8rr : I<0x88, MRMDestReg, (outs GR8 :$dst), (ins GR8 :$src),
1277 "mov{b}\t{$src, $dst|$dst, $src}", [], IIC_MOV>;
1278 def MOV16rr : I<0x89, MRMDestReg, (outs GR16:$dst), (ins GR16:$src),
1279 "mov{w}\t{$src, $dst|$dst, $src}", [], IIC_MOV>, OpSize16;
1280 def MOV32rr : I<0x89, MRMDestReg, (outs GR32:$dst), (ins GR32:$src),
1281 "mov{l}\t{$src, $dst|$dst, $src}", [], IIC_MOV>, OpSize32;
1282 def MOV64rr : RI<0x89, MRMDestReg, (outs GR64:$dst), (ins GR64:$src),
1283 "mov{q}\t{$src, $dst|$dst, $src}", [], IIC_MOV>;
1286 let isReMaterializable = 1, isAsCheapAsAMove = 1 in {
1287 def MOV8ri : Ii8 <0xB0, AddRegFrm, (outs GR8 :$dst), (ins i8imm :$src),
1288 "mov{b}\t{$src, $dst|$dst, $src}",
1289 [(set GR8:$dst, imm:$src)], IIC_MOV>;
1290 def MOV16ri : Ii16<0xB8, AddRegFrm, (outs GR16:$dst), (ins i16imm:$src),
1291 "mov{w}\t{$src, $dst|$dst, $src}",
1292 [(set GR16:$dst, imm:$src)], IIC_MOV>, OpSize16;
1293 def MOV32ri : Ii32<0xB8, AddRegFrm, (outs GR32:$dst), (ins i32imm:$src),
1294 "mov{l}\t{$src, $dst|$dst, $src}",
1295 [(set GR32:$dst, imm:$src)], IIC_MOV>, OpSize32;
1296 def MOV64ri32 : RIi32S<0xC7, MRM0r, (outs GR64:$dst), (ins i64i32imm:$src),
1297 "mov{q}\t{$src, $dst|$dst, $src}",
1298 [(set GR64:$dst, i64immSExt32:$src)], IIC_MOV>;
1300 let isReMaterializable = 1 in {
1301 def MOV64ri : RIi64<0xB8, AddRegFrm, (outs GR64:$dst), (ins i64imm:$src),
1302 "movabs{q}\t{$src, $dst|$dst, $src}",
1303 [(set GR64:$dst, imm:$src)], IIC_MOV>;
1306 // Longer forms that use a ModR/M byte. Needed for disassembler
1307 let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0 in {
1308 def MOV8ri_alt : Ii8 <0xC6, MRM0r, (outs GR8 :$dst), (ins i8imm :$src),
1309 "mov{b}\t{$src, $dst|$dst, $src}", [], IIC_MOV>;
1310 def MOV16ri_alt : Ii16<0xC7, MRM0r, (outs GR16:$dst), (ins i16imm:$src),
1311 "mov{w}\t{$src, $dst|$dst, $src}", [], IIC_MOV>, OpSize16;
1312 def MOV32ri_alt : Ii32<0xC7, MRM0r, (outs GR32:$dst), (ins i32imm:$src),
1313 "mov{l}\t{$src, $dst|$dst, $src}", [], IIC_MOV>, OpSize32;
1317 let SchedRW = [WriteStore] in {
1318 def MOV8mi : Ii8 <0xC6, MRM0m, (outs), (ins i8mem :$dst, i8imm :$src),
1319 "mov{b}\t{$src, $dst|$dst, $src}",
1320 [(store (i8 imm8_su:$src), addr:$dst)], IIC_MOV_MEM>;
1321 def MOV16mi : Ii16<0xC7, MRM0m, (outs), (ins i16mem:$dst, i16imm:$src),
1322 "mov{w}\t{$src, $dst|$dst, $src}",
1323 [(store (i16 imm16_su:$src), addr:$dst)], IIC_MOV_MEM>, OpSize16;
1324 def MOV32mi : Ii32<0xC7, MRM0m, (outs), (ins i32mem:$dst, i32imm:$src),
1325 "mov{l}\t{$src, $dst|$dst, $src}",
1326 [(store (i32 imm32_su:$src), addr:$dst)], IIC_MOV_MEM>, OpSize32;
1327 def MOV64mi32 : RIi32S<0xC7, MRM0m, (outs), (ins i64mem:$dst, i64i32imm:$src),
1328 "mov{q}\t{$src, $dst|$dst, $src}",
1329 [(store i64immSExt32:$src, addr:$dst)], IIC_MOV_MEM>;
1332 let hasSideEffects = 0 in {
1334 /// Memory offset versions of moves. The immediate is an address mode sized
1335 /// offset from the segment base.
1336 let SchedRW = [WriteALU] in {
1337 let mayLoad = 1 in {
1339 def MOV8ao32 : Ii32<0xA0, RawFrmMemOffs, (outs), (ins offset32_8:$src),
1340 "mov{b}\t{$src, %al|al, $src}", [], IIC_MOV_MEM>,
1343 def MOV16ao32 : Ii32<0xA1, RawFrmMemOffs, (outs), (ins offset32_16:$src),
1344 "mov{w}\t{$src, %ax|ax, $src}", [], IIC_MOV_MEM>,
1347 def MOV32ao32 : Ii32<0xA1, RawFrmMemOffs, (outs), (ins offset32_32:$src),
1348 "mov{l}\t{$src, %eax|eax, $src}", [], IIC_MOV_MEM>,
1351 def MOV64ao32 : RIi32<0xA1, RawFrmMemOffs, (outs), (ins offset32_64:$src),
1352 "mov{q}\t{$src, %rax|rax, $src}", [], IIC_MOV_MEM>,
1356 def MOV8ao16 : Ii16<0xA0, RawFrmMemOffs, (outs), (ins offset16_8:$src),
1357 "mov{b}\t{$src, %al|al, $src}", [], IIC_MOV_MEM>, AdSize16;
1359 def MOV16ao16 : Ii16<0xA1, RawFrmMemOffs, (outs), (ins offset16_16:$src),
1360 "mov{w}\t{$src, %ax|ax, $src}", [], IIC_MOV_MEM>,
1363 def MOV32ao16 : Ii16<0xA1, RawFrmMemOffs, (outs), (ins offset16_32:$src),
1364 "mov{l}\t{$src, %eax|eax, $src}", [], IIC_MOV_MEM>,
1367 let mayStore = 1 in {
1369 def MOV8o32a : Ii32<0xA2, RawFrmMemOffs, (outs offset32_8:$dst), (ins),
1370 "mov{b}\t{%al, $dst|$dst, al}", [], IIC_MOV_MEM>, AdSize32;
1372 def MOV16o32a : Ii32<0xA3, RawFrmMemOffs, (outs offset32_16:$dst), (ins),
1373 "mov{w}\t{%ax, $dst|$dst, ax}", [], IIC_MOV_MEM>,
1376 def MOV32o32a : Ii32<0xA3, RawFrmMemOffs, (outs offset32_32:$dst), (ins),
1377 "mov{l}\t{%eax, $dst|$dst, eax}", [], IIC_MOV_MEM>,
1380 def MOV64o32a : RIi32<0xA3, RawFrmMemOffs, (outs offset32_64:$dst), (ins),
1381 "mov{q}\t{%rax, $dst|$dst, rax}", [], IIC_MOV_MEM>,
1385 def MOV8o16a : Ii16<0xA2, RawFrmMemOffs, (outs offset16_8:$dst), (ins),
1386 "mov{b}\t{%al, $dst|$dst, al}", [], IIC_MOV_MEM>, AdSize16;
1388 def MOV16o16a : Ii16<0xA3, RawFrmMemOffs, (outs offset16_16:$dst), (ins),
1389 "mov{w}\t{%ax, $dst|$dst, ax}", [], IIC_MOV_MEM>,
1392 def MOV32o16a : Ii16<0xA3, RawFrmMemOffs, (outs offset16_32:$dst), (ins),
1393 "mov{l}\t{%eax, $dst|$dst, eax}", [], IIC_MOV_MEM>,
1398 // These forms all have full 64-bit absolute addresses in their instructions
1399 // and use the movabs mnemonic to indicate this specific form.
1400 let mayLoad = 1 in {
1402 def MOV8ao64 : RIi64_NOREX<0xA0, RawFrmMemOffs, (outs), (ins offset64_8:$src),
1403 "movabs{b}\t{$src, %al|al, $src}", []>, AdSize64;
1405 def MOV16ao64 : RIi64_NOREX<0xA1, RawFrmMemOffs, (outs), (ins offset64_16:$src),
1406 "movabs{w}\t{$src, %ax|ax, $src}", []>, OpSize16, AdSize64;
1408 def MOV32ao64 : RIi64_NOREX<0xA1, RawFrmMemOffs, (outs), (ins offset64_32:$src),
1409 "movabs{l}\t{$src, %eax|eax, $src}", []>, OpSize32,
1412 def MOV64ao64 : RIi64<0xA1, RawFrmMemOffs, (outs), (ins offset64_64:$src),
1413 "movabs{q}\t{$src, %rax|rax, $src}", []>, AdSize64;
1416 let mayStore = 1 in {
1418 def MOV8o64a : RIi64_NOREX<0xA2, RawFrmMemOffs, (outs offset64_8:$dst), (ins),
1419 "movabs{b}\t{%al, $dst|$dst, al}", []>, AdSize64;
1421 def MOV16o64a : RIi64_NOREX<0xA3, RawFrmMemOffs, (outs offset64_16:$dst), (ins),
1422 "movabs{w}\t{%ax, $dst|$dst, ax}", []>, OpSize16, AdSize64;
1424 def MOV32o64a : RIi64_NOREX<0xA3, RawFrmMemOffs, (outs offset64_32:$dst), (ins),
1425 "movabs{l}\t{%eax, $dst|$dst, eax}", []>, OpSize32,
1428 def MOV64o64a : RIi64<0xA3, RawFrmMemOffs, (outs offset64_64:$dst), (ins),
1429 "movabs{q}\t{%rax, $dst|$dst, rax}", []>, AdSize64;
1431 } // hasSideEffects = 0
1433 let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0,
1434 SchedRW = [WriteMove] in {
1435 def MOV8rr_REV : I<0x8A, MRMSrcReg, (outs GR8:$dst), (ins GR8:$src),
1436 "mov{b}\t{$src, $dst|$dst, $src}", [], IIC_MOV>;
1437 def MOV16rr_REV : I<0x8B, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
1438 "mov{w}\t{$src, $dst|$dst, $src}", [], IIC_MOV>, OpSize16;
1439 def MOV32rr_REV : I<0x8B, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
1440 "mov{l}\t{$src, $dst|$dst, $src}", [], IIC_MOV>, OpSize32;
1441 def MOV64rr_REV : RI<0x8B, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
1442 "mov{q}\t{$src, $dst|$dst, $src}", [], IIC_MOV>;
1445 let canFoldAsLoad = 1, isReMaterializable = 1, SchedRW = [WriteLoad] in {
1446 def MOV8rm : I<0x8A, MRMSrcMem, (outs GR8 :$dst), (ins i8mem :$src),
1447 "mov{b}\t{$src, $dst|$dst, $src}",
1448 [(set GR8:$dst, (loadi8 addr:$src))], IIC_MOV_MEM>;
1449 def MOV16rm : I<0x8B, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
1450 "mov{w}\t{$src, $dst|$dst, $src}",
1451 [(set GR16:$dst, (loadi16 addr:$src))], IIC_MOV_MEM>, OpSize16;
1452 def MOV32rm : I<0x8B, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
1453 "mov{l}\t{$src, $dst|$dst, $src}",
1454 [(set GR32:$dst, (loadi32 addr:$src))], IIC_MOV_MEM>, OpSize32;
1455 def MOV64rm : RI<0x8B, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
1456 "mov{q}\t{$src, $dst|$dst, $src}",
1457 [(set GR64:$dst, (load addr:$src))], IIC_MOV_MEM>;
1460 let SchedRW = [WriteStore] in {
1461 def MOV8mr : I<0x88, MRMDestMem, (outs), (ins i8mem :$dst, GR8 :$src),
1462 "mov{b}\t{$src, $dst|$dst, $src}",
1463 [(store GR8:$src, addr:$dst)], IIC_MOV_MEM>;
1464 def MOV16mr : I<0x89, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src),
1465 "mov{w}\t{$src, $dst|$dst, $src}",
1466 [(store GR16:$src, addr:$dst)], IIC_MOV_MEM>, OpSize16;
1467 def MOV32mr : I<0x89, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
1468 "mov{l}\t{$src, $dst|$dst, $src}",
1469 [(store GR32:$src, addr:$dst)], IIC_MOV_MEM>, OpSize32;
1470 def MOV64mr : RI<0x89, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
1471 "mov{q}\t{$src, $dst|$dst, $src}",
1472 [(store GR64:$src, addr:$dst)], IIC_MOV_MEM>;
1475 // Versions of MOV8rr, MOV8mr, and MOV8rm that use i8mem_NOREX and GR8_NOREX so
1476 // that they can be used for copying and storing h registers, which can't be
1477 // encoded when a REX prefix is present.
1478 let isCodeGenOnly = 1 in {
1479 let hasSideEffects = 0 in
1480 def MOV8rr_NOREX : I<0x88, MRMDestReg,
1481 (outs GR8_NOREX:$dst), (ins GR8_NOREX:$src),
1482 "mov{b}\t{$src, $dst|$dst, $src} # NOREX", [], IIC_MOV>,
1484 let mayStore = 1, hasSideEffects = 0 in
1485 def MOV8mr_NOREX : I<0x88, MRMDestMem,
1486 (outs), (ins i8mem_NOREX:$dst, GR8_NOREX:$src),
1487 "mov{b}\t{$src, $dst|$dst, $src} # NOREX", [],
1488 IIC_MOV_MEM>, Sched<[WriteStore]>;
1489 let mayLoad = 1, hasSideEffects = 0,
1490 canFoldAsLoad = 1, isReMaterializable = 1 in
1491 def MOV8rm_NOREX : I<0x8A, MRMSrcMem,
1492 (outs GR8_NOREX:$dst), (ins i8mem_NOREX:$src),
1493 "mov{b}\t{$src, $dst|$dst, $src} # NOREX", [],
1494 IIC_MOV_MEM>, Sched<[WriteLoad]>;
1498 // Condition code ops, incl. set if equal/not equal/...
1499 let SchedRW = [WriteALU] in {
1500 let Defs = [EFLAGS], Uses = [AH] in
1501 def SAHF : I<0x9E, RawFrm, (outs), (ins), "sahf",
1502 [(set EFLAGS, (X86sahf AH))], IIC_AHF>;
1503 let Defs = [AH], Uses = [EFLAGS], hasSideEffects = 0 in
1504 def LAHF : I<0x9F, RawFrm, (outs), (ins), "lahf", [],
1505 IIC_AHF>; // AH = flags
1508 //===----------------------------------------------------------------------===//
1509 // Bit tests instructions: BT, BTS, BTR, BTC.
1511 let Defs = [EFLAGS] in {
1512 let SchedRW = [WriteALU] in {
1513 def BT16rr : I<0xA3, MRMDestReg, (outs), (ins GR16:$src1, GR16:$src2),
1514 "bt{w}\t{$src2, $src1|$src1, $src2}",
1515 [(set EFLAGS, (X86bt GR16:$src1, GR16:$src2))], IIC_BT_RR>,
1517 def BT32rr : I<0xA3, MRMDestReg, (outs), (ins GR32:$src1, GR32:$src2),
1518 "bt{l}\t{$src2, $src1|$src1, $src2}",
1519 [(set EFLAGS, (X86bt GR32:$src1, GR32:$src2))], IIC_BT_RR>,
1521 def BT64rr : RI<0xA3, MRMDestReg, (outs), (ins GR64:$src1, GR64:$src2),
1522 "bt{q}\t{$src2, $src1|$src1, $src2}",
1523 [(set EFLAGS, (X86bt GR64:$src1, GR64:$src2))], IIC_BT_RR>, TB;
1526 // Unlike with the register+register form, the memory+register form of the
1527 // bt instruction does not ignore the high bits of the index. From ISel's
1528 // perspective, this is pretty bizarre. Make these instructions disassembly
1531 let mayLoad = 1, hasSideEffects = 0, SchedRW = [WriteALULd] in {
1532 def BT16mr : I<0xA3, MRMDestMem, (outs), (ins i16mem:$src1, GR16:$src2),
1533 "bt{w}\t{$src2, $src1|$src1, $src2}",
1534 // [(X86bt (loadi16 addr:$src1), GR16:$src2),
1535 // (implicit EFLAGS)]
1537 >, OpSize16, TB, Requires<[FastBTMem]>;
1538 def BT32mr : I<0xA3, MRMDestMem, (outs), (ins i32mem:$src1, GR32:$src2),
1539 "bt{l}\t{$src2, $src1|$src1, $src2}",
1540 // [(X86bt (loadi32 addr:$src1), GR32:$src2),
1541 // (implicit EFLAGS)]
1543 >, OpSize32, TB, Requires<[FastBTMem]>;
1544 def BT64mr : RI<0xA3, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2),
1545 "bt{q}\t{$src2, $src1|$src1, $src2}",
1546 // [(X86bt (loadi64 addr:$src1), GR64:$src2),
1547 // (implicit EFLAGS)]
1552 let SchedRW = [WriteALU] in {
1553 def BT16ri8 : Ii8<0xBA, MRM4r, (outs), (ins GR16:$src1, i16i8imm:$src2),
1554 "bt{w}\t{$src2, $src1|$src1, $src2}",
1555 [(set EFLAGS, (X86bt GR16:$src1, i16immSExt8:$src2))],
1556 IIC_BT_RI>, OpSize16, TB;
1557 def BT32ri8 : Ii8<0xBA, MRM4r, (outs), (ins GR32:$src1, i32i8imm:$src2),
1558 "bt{l}\t{$src2, $src1|$src1, $src2}",
1559 [(set EFLAGS, (X86bt GR32:$src1, i32immSExt8:$src2))],
1560 IIC_BT_RI>, OpSize32, TB;
1561 def BT64ri8 : RIi8<0xBA, MRM4r, (outs), (ins GR64:$src1, i64i8imm:$src2),
1562 "bt{q}\t{$src2, $src1|$src1, $src2}",
1563 [(set EFLAGS, (X86bt GR64:$src1, i64immSExt8:$src2))],
1567 // Note that these instructions don't need FastBTMem because that
1568 // only applies when the other operand is in a register. When it's
1569 // an immediate, bt is still fast.
1570 let SchedRW = [WriteALU] in {
1571 def BT16mi8 : Ii8<0xBA, MRM4m, (outs), (ins i16mem:$src1, i16i8imm:$src2),
1572 "bt{w}\t{$src2, $src1|$src1, $src2}",
1573 [(set EFLAGS, (X86bt (loadi16 addr:$src1), i16immSExt8:$src2))
1574 ], IIC_BT_MI>, OpSize16, TB;
1575 def BT32mi8 : Ii8<0xBA, MRM4m, (outs), (ins i32mem:$src1, i32i8imm:$src2),
1576 "bt{l}\t{$src2, $src1|$src1, $src2}",
1577 [(set EFLAGS, (X86bt (loadi32 addr:$src1), i32immSExt8:$src2))
1578 ], IIC_BT_MI>, OpSize32, TB;
1579 def BT64mi8 : RIi8<0xBA, MRM4m, (outs), (ins i64mem:$src1, i64i8imm:$src2),
1580 "bt{q}\t{$src2, $src1|$src1, $src2}",
1581 [(set EFLAGS, (X86bt (loadi64 addr:$src1),
1582 i64immSExt8:$src2))], IIC_BT_MI>, TB;
1585 let hasSideEffects = 0 in {
1586 let SchedRW = [WriteALU] in {
1587 def BTC16rr : I<0xBB, MRMDestReg, (outs), (ins GR16:$src1, GR16:$src2),
1588 "btc{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>,
1590 def BTC32rr : I<0xBB, MRMDestReg, (outs), (ins GR32:$src1, GR32:$src2),
1591 "btc{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>,
1593 def BTC64rr : RI<0xBB, MRMDestReg, (outs), (ins GR64:$src1, GR64:$src2),
1594 "btc{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>, TB;
1597 let mayLoad = 1, mayStore = 1, SchedRW = [WriteALULd, WriteRMW] in {
1598 def BTC16mr : I<0xBB, MRMDestMem, (outs), (ins i16mem:$src1, GR16:$src2),
1599 "btc{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>,
1601 def BTC32mr : I<0xBB, MRMDestMem, (outs), (ins i32mem:$src1, GR32:$src2),
1602 "btc{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>,
1604 def BTC64mr : RI<0xBB, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2),
1605 "btc{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>, TB;
1608 let SchedRW = [WriteALU] in {
1609 def BTC16ri8 : Ii8<0xBA, MRM7r, (outs), (ins GR16:$src1, i16i8imm:$src2),
1610 "btc{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>,
1612 def BTC32ri8 : Ii8<0xBA, MRM7r, (outs), (ins GR32:$src1, i32i8imm:$src2),
1613 "btc{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>,
1615 def BTC64ri8 : RIi8<0xBA, MRM7r, (outs), (ins GR64:$src1, i64i8imm:$src2),
1616 "btc{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>, TB;
1619 let mayLoad = 1, mayStore = 1, SchedRW = [WriteALULd, WriteRMW] in {
1620 def BTC16mi8 : Ii8<0xBA, MRM7m, (outs), (ins i16mem:$src1, i16i8imm:$src2),
1621 "btc{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>,
1623 def BTC32mi8 : Ii8<0xBA, MRM7m, (outs), (ins i32mem:$src1, i32i8imm:$src2),
1624 "btc{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>,
1626 def BTC64mi8 : RIi8<0xBA, MRM7m, (outs), (ins i64mem:$src1, i64i8imm:$src2),
1627 "btc{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>, TB;
1630 let SchedRW = [WriteALU] in {
1631 def BTR16rr : I<0xB3, MRMDestReg, (outs), (ins GR16:$src1, GR16:$src2),
1632 "btr{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>,
1634 def BTR32rr : I<0xB3, MRMDestReg, (outs), (ins GR32:$src1, GR32:$src2),
1635 "btr{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>,
1637 def BTR64rr : RI<0xB3, MRMDestReg, (outs), (ins GR64:$src1, GR64:$src2),
1638 "btr{q}\t{$src2, $src1|$src1, $src2}", []>, TB;
1641 let mayLoad = 1, mayStore = 1, SchedRW = [WriteALULd, WriteRMW] in {
1642 def BTR16mr : I<0xB3, MRMDestMem, (outs), (ins i16mem:$src1, GR16:$src2),
1643 "btr{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>,
1645 def BTR32mr : I<0xB3, MRMDestMem, (outs), (ins i32mem:$src1, GR32:$src2),
1646 "btr{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>,
1648 def BTR64mr : RI<0xB3, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2),
1649 "btr{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>, TB;
1652 let SchedRW = [WriteALU] in {
1653 def BTR16ri8 : Ii8<0xBA, MRM6r, (outs), (ins GR16:$src1, i16i8imm:$src2),
1654 "btr{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>,
1656 def BTR32ri8 : Ii8<0xBA, MRM6r, (outs), (ins GR32:$src1, i32i8imm:$src2),
1657 "btr{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>,
1659 def BTR64ri8 : RIi8<0xBA, MRM6r, (outs), (ins GR64:$src1, i64i8imm:$src2),
1660 "btr{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>, TB;
1663 let mayLoad = 1, mayStore = 1, SchedRW = [WriteALULd, WriteRMW] in {
1664 def BTR16mi8 : Ii8<0xBA, MRM6m, (outs), (ins i16mem:$src1, i16i8imm:$src2),
1665 "btr{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>,
1667 def BTR32mi8 : Ii8<0xBA, MRM6m, (outs), (ins i32mem:$src1, i32i8imm:$src2),
1668 "btr{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>,
1670 def BTR64mi8 : RIi8<0xBA, MRM6m, (outs), (ins i64mem:$src1, i64i8imm:$src2),
1671 "btr{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>, TB;
1674 let SchedRW = [WriteALU] in {
1675 def BTS16rr : I<0xAB, MRMDestReg, (outs), (ins GR16:$src1, GR16:$src2),
1676 "bts{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>,
1678 def BTS32rr : I<0xAB, MRMDestReg, (outs), (ins GR32:$src1, GR32:$src2),
1679 "bts{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>,
1681 def BTS64rr : RI<0xAB, MRMDestReg, (outs), (ins GR64:$src1, GR64:$src2),
1682 "bts{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>, TB;
1685 let mayLoad = 1, mayStore = 1, SchedRW = [WriteALULd, WriteRMW] in {
1686 def BTS16mr : I<0xAB, MRMDestMem, (outs), (ins i16mem:$src1, GR16:$src2),
1687 "bts{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>,
1689 def BTS32mr : I<0xAB, MRMDestMem, (outs), (ins i32mem:$src1, GR32:$src2),
1690 "bts{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>,
1692 def BTS64mr : RI<0xAB, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2),
1693 "bts{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>, TB;
1696 let SchedRW = [WriteALU] in {
1697 def BTS16ri8 : Ii8<0xBA, MRM5r, (outs), (ins GR16:$src1, i16i8imm:$src2),
1698 "bts{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>,
1700 def BTS32ri8 : Ii8<0xBA, MRM5r, (outs), (ins GR32:$src1, i32i8imm:$src2),
1701 "bts{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>,
1703 def BTS64ri8 : RIi8<0xBA, MRM5r, (outs), (ins GR64:$src1, i64i8imm:$src2),
1704 "bts{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>, TB;
1707 let mayLoad = 1, mayStore = 1, SchedRW = [WriteALULd, WriteRMW] in {
1708 def BTS16mi8 : Ii8<0xBA, MRM5m, (outs), (ins i16mem:$src1, i16i8imm:$src2),
1709 "bts{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>,
1711 def BTS32mi8 : Ii8<0xBA, MRM5m, (outs), (ins i32mem:$src1, i32i8imm:$src2),
1712 "bts{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>,
1714 def BTS64mi8 : RIi8<0xBA, MRM5m, (outs), (ins i64mem:$src1, i64i8imm:$src2),
1715 "bts{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>, TB;
1717 } // hasSideEffects = 0
1718 } // Defs = [EFLAGS]
1721 //===----------------------------------------------------------------------===//
1725 // Atomic swap. These are just normal xchg instructions. But since a memory
1726 // operand is referenced, the atomicity is ensured.
1727 multiclass ATOMIC_SWAP<bits<8> opc8, bits<8> opc, string mnemonic, string frag,
1728 InstrItinClass itin> {
1729 let Constraints = "$val = $dst", SchedRW = [WriteALULd, WriteRMW] in {
1730 def NAME#8rm : I<opc8, MRMSrcMem, (outs GR8:$dst),
1731 (ins GR8:$val, i8mem:$ptr),
1732 !strconcat(mnemonic, "{b}\t{$val, $ptr|$ptr, $val}"),
1735 (!cast<PatFrag>(frag # "_8") addr:$ptr, GR8:$val))],
1737 def NAME#16rm : I<opc, MRMSrcMem, (outs GR16:$dst),
1738 (ins GR16:$val, i16mem:$ptr),
1739 !strconcat(mnemonic, "{w}\t{$val, $ptr|$ptr, $val}"),
1742 (!cast<PatFrag>(frag # "_16") addr:$ptr, GR16:$val))],
1744 def NAME#32rm : I<opc, MRMSrcMem, (outs GR32:$dst),
1745 (ins GR32:$val, i32mem:$ptr),
1746 !strconcat(mnemonic, "{l}\t{$val, $ptr|$ptr, $val}"),
1749 (!cast<PatFrag>(frag # "_32") addr:$ptr, GR32:$val))],
1751 def NAME#64rm : RI<opc, MRMSrcMem, (outs GR64:$dst),
1752 (ins GR64:$val, i64mem:$ptr),
1753 !strconcat(mnemonic, "{q}\t{$val, $ptr|$ptr, $val}"),
1756 (!cast<PatFrag>(frag # "_64") addr:$ptr, GR64:$val))],
1761 defm XCHG : ATOMIC_SWAP<0x86, 0x87, "xchg", "atomic_swap", IIC_XCHG_MEM>;
1763 // Swap between registers.
1764 let SchedRW = [WriteALU] in {
1765 let Constraints = "$val = $dst" in {
1766 def XCHG8rr : I<0x86, MRMSrcReg, (outs GR8:$dst), (ins GR8:$val, GR8:$src),
1767 "xchg{b}\t{$val, $src|$src, $val}", [], IIC_XCHG_REG>;
1768 def XCHG16rr : I<0x87, MRMSrcReg, (outs GR16:$dst), (ins GR16:$val, GR16:$src),
1769 "xchg{w}\t{$val, $src|$src, $val}", [], IIC_XCHG_REG>,
1771 def XCHG32rr : I<0x87, MRMSrcReg, (outs GR32:$dst), (ins GR32:$val, GR32:$src),
1772 "xchg{l}\t{$val, $src|$src, $val}", [], IIC_XCHG_REG>,
1774 def XCHG64rr : RI<0x87, MRMSrcReg, (outs GR64:$dst), (ins GR64:$val,GR64:$src),
1775 "xchg{q}\t{$val, $src|$src, $val}", [], IIC_XCHG_REG>;
1778 // Swap between EAX and other registers.
1779 let Uses = [AX], Defs = [AX] in
1780 def XCHG16ar : I<0x90, AddRegFrm, (outs), (ins GR16:$src),
1781 "xchg{w}\t{$src, %ax|ax, $src}", [], IIC_XCHG_REG>, OpSize16;
1782 let Uses = [EAX], Defs = [EAX] in
1783 def XCHG32ar : I<0x90, AddRegFrm, (outs), (ins GR32:$src),
1784 "xchg{l}\t{$src, %eax|eax, $src}", [], IIC_XCHG_REG>,
1785 OpSize32, Requires<[Not64BitMode]>;
1786 let Uses = [EAX], Defs = [EAX] in
1787 // Uses GR32_NOAX in 64-bit mode to prevent encoding using the 0x90 NOP encoding.
1788 // xchg %eax, %eax needs to clear upper 32-bits of RAX so is not a NOP.
1789 def XCHG32ar64 : I<0x90, AddRegFrm, (outs), (ins GR32_NOAX:$src),
1790 "xchg{l}\t{$src, %eax|eax, $src}", [], IIC_XCHG_REG>,
1791 OpSize32, Requires<[In64BitMode]>;
1792 let Uses = [RAX], Defs = [RAX] in
1793 def XCHG64ar : RI<0x90, AddRegFrm, (outs), (ins GR64:$src),
1794 "xchg{q}\t{$src, %rax|rax, $src}", [], IIC_XCHG_REG>;
1797 let SchedRW = [WriteALU] in {
1798 def XADD8rr : I<0xC0, MRMDestReg, (outs GR8:$dst), (ins GR8:$src),
1799 "xadd{b}\t{$src, $dst|$dst, $src}", [], IIC_XADD_REG>, TB;
1800 def XADD16rr : I<0xC1, MRMDestReg, (outs GR16:$dst), (ins GR16:$src),
1801 "xadd{w}\t{$src, $dst|$dst, $src}", [], IIC_XADD_REG>, TB,
1803 def XADD32rr : I<0xC1, MRMDestReg, (outs GR32:$dst), (ins GR32:$src),
1804 "xadd{l}\t{$src, $dst|$dst, $src}", [], IIC_XADD_REG>, TB,
1806 def XADD64rr : RI<0xC1, MRMDestReg, (outs GR64:$dst), (ins GR64:$src),
1807 "xadd{q}\t{$src, $dst|$dst, $src}", [], IIC_XADD_REG>, TB;
1810 let mayLoad = 1, mayStore = 1, SchedRW = [WriteALULd, WriteRMW] in {
1811 def XADD8rm : I<0xC0, MRMDestMem, (outs), (ins i8mem:$dst, GR8:$src),
1812 "xadd{b}\t{$src, $dst|$dst, $src}", [], IIC_XADD_MEM>, TB;
1813 def XADD16rm : I<0xC1, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src),
1814 "xadd{w}\t{$src, $dst|$dst, $src}", [], IIC_XADD_MEM>, TB,
1816 def XADD32rm : I<0xC1, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
1817 "xadd{l}\t{$src, $dst|$dst, $src}", [], IIC_XADD_MEM>, TB,
1819 def XADD64rm : RI<0xC1, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
1820 "xadd{q}\t{$src, $dst|$dst, $src}", [], IIC_XADD_MEM>, TB;
1824 let SchedRW = [WriteALU] in {
1825 def CMPXCHG8rr : I<0xB0, MRMDestReg, (outs GR8:$dst), (ins GR8:$src),
1826 "cmpxchg{b}\t{$src, $dst|$dst, $src}", [],
1827 IIC_CMPXCHG_REG8>, TB;
1828 def CMPXCHG16rr : I<0xB1, MRMDestReg, (outs GR16:$dst), (ins GR16:$src),
1829 "cmpxchg{w}\t{$src, $dst|$dst, $src}", [],
1830 IIC_CMPXCHG_REG>, TB, OpSize16;
1831 def CMPXCHG32rr : I<0xB1, MRMDestReg, (outs GR32:$dst), (ins GR32:$src),
1832 "cmpxchg{l}\t{$src, $dst|$dst, $src}", [],
1833 IIC_CMPXCHG_REG>, TB, OpSize32;
1834 def CMPXCHG64rr : RI<0xB1, MRMDestReg, (outs GR64:$dst), (ins GR64:$src),
1835 "cmpxchg{q}\t{$src, $dst|$dst, $src}", [],
1836 IIC_CMPXCHG_REG>, TB;
1839 let SchedRW = [WriteALULd, WriteRMW] in {
1840 let mayLoad = 1, mayStore = 1 in {
1841 def CMPXCHG8rm : I<0xB0, MRMDestMem, (outs), (ins i8mem:$dst, GR8:$src),
1842 "cmpxchg{b}\t{$src, $dst|$dst, $src}", [],
1843 IIC_CMPXCHG_MEM8>, TB;
1844 def CMPXCHG16rm : I<0xB1, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src),
1845 "cmpxchg{w}\t{$src, $dst|$dst, $src}", [],
1846 IIC_CMPXCHG_MEM>, TB, OpSize16;
1847 def CMPXCHG32rm : I<0xB1, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
1848 "cmpxchg{l}\t{$src, $dst|$dst, $src}", [],
1849 IIC_CMPXCHG_MEM>, TB, OpSize32;
1850 def CMPXCHG64rm : RI<0xB1, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
1851 "cmpxchg{q}\t{$src, $dst|$dst, $src}", [],
1852 IIC_CMPXCHG_MEM>, TB;
1855 let Defs = [EAX, EDX, EFLAGS], Uses = [EAX, EBX, ECX, EDX] in
1856 def CMPXCHG8B : I<0xC7, MRM1m, (outs), (ins i64mem:$dst),
1857 "cmpxchg8b\t$dst", [], IIC_CMPXCHG_8B>, TB;
1859 let Defs = [RAX, RDX, EFLAGS], Uses = [RAX, RBX, RCX, RDX] in
1860 def CMPXCHG16B : RI<0xC7, MRM1m, (outs), (ins i128mem:$dst),
1861 "cmpxchg16b\t$dst", [], IIC_CMPXCHG_16B>,
1862 TB, Requires<[HasCmpxchg16b]>;
1866 // Lock instruction prefix
1867 def LOCK_PREFIX : I<0xF0, RawFrm, (outs), (ins), "lock", []>;
1869 // Rex64 instruction prefix
1870 def REX64_PREFIX : I<0x48, RawFrm, (outs), (ins), "rex64", []>,
1871 Requires<[In64BitMode]>;
1873 // Data16 instruction prefix
1874 def DATA16_PREFIX : I<0x66, RawFrm, (outs), (ins), "data16", []>;
1876 // Repeat string operation instruction prefixes
1877 // These uses the DF flag in the EFLAGS register to inc or dec ECX
1878 let Defs = [ECX], Uses = [ECX,EFLAGS] in {
1879 // Repeat (used with INS, OUTS, MOVS, LODS and STOS)
1880 def REP_PREFIX : I<0xF3, RawFrm, (outs), (ins), "rep", []>;
1881 // Repeat while not equal (used with CMPS and SCAS)
1882 def REPNE_PREFIX : I<0xF2, RawFrm, (outs), (ins), "repne", []>;
1886 // String manipulation instructions
1887 let SchedRW = [WriteMicrocoded] in {
1888 // These uses the DF flag in the EFLAGS register to inc or dec EDI and ESI
1889 let Defs = [AL,ESI], Uses = [ESI,EFLAGS] in
1890 def LODSB : I<0xAC, RawFrmSrc, (outs), (ins srcidx8:$src),
1891 "lodsb\t{$src, %al|al, $src}", [], IIC_LODS>;
1892 let Defs = [AX,ESI], Uses = [ESI,EFLAGS] in
1893 def LODSW : I<0xAD, RawFrmSrc, (outs), (ins srcidx16:$src),
1894 "lodsw\t{$src, %ax|ax, $src}", [], IIC_LODS>, OpSize16;
1895 let Defs = [EAX,ESI], Uses = [ESI,EFLAGS] in
1896 def LODSL : I<0xAD, RawFrmSrc, (outs), (ins srcidx32:$src),
1897 "lods{l|d}\t{$src, %eax|eax, $src}", [], IIC_LODS>, OpSize32;
1898 let Defs = [RAX,ESI], Uses = [ESI,EFLAGS] in
1899 def LODSQ : RI<0xAD, RawFrmSrc, (outs), (ins srcidx64:$src),
1900 "lodsq\t{$src, %rax|rax, $src}", [], IIC_LODS>;
1903 let SchedRW = [WriteSystem] in {
1904 // These uses the DF flag in the EFLAGS register to inc or dec EDI and ESI
1905 let Defs = [ESI], Uses = [DX,ESI,EFLAGS] in {
1906 def OUTSB : I<0x6E, RawFrmSrc, (outs), (ins srcidx8:$src),
1907 "outsb\t{$src, %dx|dx, $src}", [], IIC_OUTS>;
1908 def OUTSW : I<0x6F, RawFrmSrc, (outs), (ins srcidx16:$src),
1909 "outsw\t{$src, %dx|dx, $src}", [], IIC_OUTS>, OpSize16;
1910 def OUTSL : I<0x6F, RawFrmSrc, (outs), (ins srcidx32:$src),
1911 "outs{l|d}\t{$src, %dx|dx, $src}", [], IIC_OUTS>, OpSize32;
1914 // These uses the DF flag in the EFLAGS register to inc or dec EDI and ESI
1915 let Defs = [EDI], Uses = [DX,EDI,EFLAGS] in {
1916 def INSB : I<0x6C, RawFrmDst, (outs dstidx8:$dst), (ins),
1917 "insb\t{%dx, $dst|$dst, dx}", [], IIC_INS>;
1918 def INSW : I<0x6D, RawFrmDst, (outs dstidx16:$dst), (ins),
1919 "insw\t{%dx, $dst|$dst, dx}", [], IIC_INS>, OpSize16;
1920 def INSL : I<0x6D, RawFrmDst, (outs dstidx32:$dst), (ins),
1921 "ins{l|d}\t{%dx, $dst|$dst, dx}", [], IIC_INS>, OpSize32;
1925 // Flag instructions
1926 let SchedRW = [WriteALU] in {
1927 def CLC : I<0xF8, RawFrm, (outs), (ins), "clc", [], IIC_CLC>;
1928 def STC : I<0xF9, RawFrm, (outs), (ins), "stc", [], IIC_STC>;
1929 def CLI : I<0xFA, RawFrm, (outs), (ins), "cli", [], IIC_CLI>;
1930 def STI : I<0xFB, RawFrm, (outs), (ins), "sti", [], IIC_STI>;
1931 def CLD : I<0xFC, RawFrm, (outs), (ins), "cld", [], IIC_CLD>;
1932 def STD : I<0xFD, RawFrm, (outs), (ins), "std", [], IIC_STD>;
1933 def CMC : I<0xF5, RawFrm, (outs), (ins), "cmc", [], IIC_CMC>;
1935 def CLTS : I<0x06, RawFrm, (outs), (ins), "clts", [], IIC_CLTS>, TB;
1938 // Table lookup instructions
1939 def XLAT : I<0xD7, RawFrm, (outs), (ins), "xlatb", [], IIC_XLAT>,
1942 let SchedRW = [WriteMicrocoded] in {
1943 // ASCII Adjust After Addition
1944 // sets AL, AH and CF and AF of EFLAGS and uses AL and AF of EFLAGS
1945 def AAA : I<0x37, RawFrm, (outs), (ins), "aaa", [], IIC_AAA>,
1946 Requires<[Not64BitMode]>;
1948 // ASCII Adjust AX Before Division
1949 // sets AL, AH and EFLAGS and uses AL and AH
1950 def AAD8i8 : Ii8<0xD5, RawFrm, (outs), (ins i8imm:$src),
1951 "aad\t$src", [], IIC_AAD>, Requires<[Not64BitMode]>;
1953 // ASCII Adjust AX After Multiply
1954 // sets AL, AH and EFLAGS and uses AL
1955 def AAM8i8 : Ii8<0xD4, RawFrm, (outs), (ins i8imm:$src),
1956 "aam\t$src", [], IIC_AAM>, Requires<[Not64BitMode]>;
1958 // ASCII Adjust AL After Subtraction - sets
1959 // sets AL, AH and CF and AF of EFLAGS and uses AL and AF of EFLAGS
1960 def AAS : I<0x3F, RawFrm, (outs), (ins), "aas", [], IIC_AAS>,
1961 Requires<[Not64BitMode]>;
1963 // Decimal Adjust AL after Addition
1964 // sets AL, CF and AF of EFLAGS and uses AL, CF and AF of EFLAGS
1965 def DAA : I<0x27, RawFrm, (outs), (ins), "daa", [], IIC_DAA>,
1966 Requires<[Not64BitMode]>;
1968 // Decimal Adjust AL after Subtraction
1969 // sets AL, CF and AF of EFLAGS and uses AL, CF and AF of EFLAGS
1970 def DAS : I<0x2F, RawFrm, (outs), (ins), "das", [], IIC_DAS>,
1971 Requires<[Not64BitMode]>;
1974 let SchedRW = [WriteSystem] in {
1975 // Check Array Index Against Bounds
1976 def BOUNDS16rm : I<0x62, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
1977 "bound\t{$src, $dst|$dst, $src}", [], IIC_BOUND>, OpSize16,
1978 Requires<[Not64BitMode]>;
1979 def BOUNDS32rm : I<0x62, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
1980 "bound\t{$src, $dst|$dst, $src}", [], IIC_BOUND>, OpSize32,
1981 Requires<[Not64BitMode]>;
1983 // Adjust RPL Field of Segment Selector
1984 def ARPL16rr : I<0x63, MRMDestReg, (outs GR16:$dst), (ins GR16:$src),
1985 "arpl\t{$src, $dst|$dst, $src}", [], IIC_ARPL_REG>,
1986 Requires<[Not64BitMode]>;
1987 def ARPL16mr : I<0x63, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src),
1988 "arpl\t{$src, $dst|$dst, $src}", [], IIC_ARPL_MEM>,
1989 Requires<[Not64BitMode]>;
1992 //===----------------------------------------------------------------------===//
1993 // MOVBE Instructions
1995 let Predicates = [HasMOVBE] in {
1996 let SchedRW = [WriteALULd] in {
1997 def MOVBE16rm : I<0xF0, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
1998 "movbe{w}\t{$src, $dst|$dst, $src}",
1999 [(set GR16:$dst, (bswap (loadi16 addr:$src)))], IIC_MOVBE>,
2001 def MOVBE32rm : I<0xF0, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
2002 "movbe{l}\t{$src, $dst|$dst, $src}",
2003 [(set GR32:$dst, (bswap (loadi32 addr:$src)))], IIC_MOVBE>,
2005 def MOVBE64rm : RI<0xF0, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
2006 "movbe{q}\t{$src, $dst|$dst, $src}",
2007 [(set GR64:$dst, (bswap (loadi64 addr:$src)))], IIC_MOVBE>,
2010 let SchedRW = [WriteStore] in {
2011 def MOVBE16mr : I<0xF1, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src),
2012 "movbe{w}\t{$src, $dst|$dst, $src}",
2013 [(store (bswap GR16:$src), addr:$dst)], IIC_MOVBE>,
2015 def MOVBE32mr : I<0xF1, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
2016 "movbe{l}\t{$src, $dst|$dst, $src}",
2017 [(store (bswap GR32:$src), addr:$dst)], IIC_MOVBE>,
2019 def MOVBE64mr : RI<0xF1, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
2020 "movbe{q}\t{$src, $dst|$dst, $src}",
2021 [(store (bswap GR64:$src), addr:$dst)], IIC_MOVBE>,
2026 //===----------------------------------------------------------------------===//
2027 // RDRAND Instruction
2029 let Predicates = [HasRDRAND], Defs = [EFLAGS] in {
2030 def RDRAND16r : I<0xC7, MRM6r, (outs GR16:$dst), (ins),
2032 [(set GR16:$dst, EFLAGS, (X86rdrand))]>, OpSize16, TB;
2033 def RDRAND32r : I<0xC7, MRM6r, (outs GR32:$dst), (ins),
2035 [(set GR32:$dst, EFLAGS, (X86rdrand))]>, OpSize32, TB;
2036 def RDRAND64r : RI<0xC7, MRM6r, (outs GR64:$dst), (ins),
2038 [(set GR64:$dst, EFLAGS, (X86rdrand))]>, TB;
2041 //===----------------------------------------------------------------------===//
2042 // RDSEED Instruction
2044 let Predicates = [HasRDSEED], Defs = [EFLAGS] in {
2045 def RDSEED16r : I<0xC7, MRM7r, (outs GR16:$dst), (ins),
2047 [(set GR16:$dst, EFLAGS, (X86rdseed))]>, OpSize16, TB;
2048 def RDSEED32r : I<0xC7, MRM7r, (outs GR32:$dst), (ins),
2050 [(set GR32:$dst, EFLAGS, (X86rdseed))]>, OpSize32, TB;
2051 def RDSEED64r : RI<0xC7, MRM7r, (outs GR64:$dst), (ins),
2053 [(set GR64:$dst, EFLAGS, (X86rdseed))]>, TB;
2056 //===----------------------------------------------------------------------===//
2057 // LZCNT Instruction
2059 let Predicates = [HasLZCNT], Defs = [EFLAGS] in {
2060 def LZCNT16rr : I<0xBD, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
2061 "lzcnt{w}\t{$src, $dst|$dst, $src}",
2062 [(set GR16:$dst, (ctlz GR16:$src)), (implicit EFLAGS)]>, XS,
2064 def LZCNT16rm : I<0xBD, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
2065 "lzcnt{w}\t{$src, $dst|$dst, $src}",
2066 [(set GR16:$dst, (ctlz (loadi16 addr:$src))),
2067 (implicit EFLAGS)]>, XS, OpSize16;
2069 def LZCNT32rr : I<0xBD, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
2070 "lzcnt{l}\t{$src, $dst|$dst, $src}",
2071 [(set GR32:$dst, (ctlz GR32:$src)), (implicit EFLAGS)]>, XS,
2073 def LZCNT32rm : I<0xBD, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
2074 "lzcnt{l}\t{$src, $dst|$dst, $src}",
2075 [(set GR32:$dst, (ctlz (loadi32 addr:$src))),
2076 (implicit EFLAGS)]>, XS, OpSize32;
2078 def LZCNT64rr : RI<0xBD, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
2079 "lzcnt{q}\t{$src, $dst|$dst, $src}",
2080 [(set GR64:$dst, (ctlz GR64:$src)), (implicit EFLAGS)]>,
2082 def LZCNT64rm : RI<0xBD, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
2083 "lzcnt{q}\t{$src, $dst|$dst, $src}",
2084 [(set GR64:$dst, (ctlz (loadi64 addr:$src))),
2085 (implicit EFLAGS)]>, XS;
2088 let Predicates = [HasLZCNT] in {
2089 def : Pat<(X86cmov (ctlz GR16:$src), (i16 16), (X86_COND_E_OR_NE),
2090 (X86cmp GR16:$src, (i16 0))),
2091 (LZCNT16rr GR16:$src)>;
2092 def : Pat<(X86cmov (ctlz GR32:$src), (i32 32), (X86_COND_E_OR_NE),
2093 (X86cmp GR32:$src, (i32 0))),
2094 (LZCNT32rr GR32:$src)>;
2095 def : Pat<(X86cmov (ctlz GR64:$src), (i64 64), (X86_COND_E_OR_NE),
2096 (X86cmp GR64:$src, (i64 0))),
2097 (LZCNT64rr GR64:$src)>;
2098 def : Pat<(X86cmov (i16 16), (ctlz GR16:$src), (X86_COND_E_OR_NE),
2099 (X86cmp GR16:$src, (i16 0))),
2100 (LZCNT16rr GR16:$src)>;
2101 def : Pat<(X86cmov (i32 32), (ctlz GR32:$src), (X86_COND_E_OR_NE),
2102 (X86cmp GR32:$src, (i32 0))),
2103 (LZCNT32rr GR32:$src)>;
2104 def : Pat<(X86cmov (i64 64), (ctlz GR64:$src), (X86_COND_E_OR_NE),
2105 (X86cmp GR64:$src, (i64 0))),
2106 (LZCNT64rr GR64:$src)>;
2108 def : Pat<(X86cmov (ctlz (loadi16 addr:$src)), (i16 16), (X86_COND_E_OR_NE),
2109 (X86cmp (loadi16 addr:$src), (i16 0))),
2110 (LZCNT16rm addr:$src)>;
2111 def : Pat<(X86cmov (ctlz (loadi32 addr:$src)), (i32 32), (X86_COND_E_OR_NE),
2112 (X86cmp (loadi32 addr:$src), (i32 0))),
2113 (LZCNT32rm addr:$src)>;
2114 def : Pat<(X86cmov (ctlz (loadi64 addr:$src)), (i64 64), (X86_COND_E_OR_NE),
2115 (X86cmp (loadi64 addr:$src), (i64 0))),
2116 (LZCNT64rm addr:$src)>;
2117 def : Pat<(X86cmov (i16 16), (ctlz (loadi16 addr:$src)), (X86_COND_E_OR_NE),
2118 (X86cmp (loadi16 addr:$src), (i16 0))),
2119 (LZCNT16rm addr:$src)>;
2120 def : Pat<(X86cmov (i32 32), (ctlz (loadi32 addr:$src)), (X86_COND_E_OR_NE),
2121 (X86cmp (loadi32 addr:$src), (i32 0))),
2122 (LZCNT32rm addr:$src)>;
2123 def : Pat<(X86cmov (i64 64), (ctlz (loadi64 addr:$src)), (X86_COND_E_OR_NE),
2124 (X86cmp (loadi64 addr:$src), (i64 0))),
2125 (LZCNT64rm addr:$src)>;
2128 //===----------------------------------------------------------------------===//
2131 let Predicates = [HasBMI], Defs = [EFLAGS] in {
2132 def TZCNT16rr : I<0xBC, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
2133 "tzcnt{w}\t{$src, $dst|$dst, $src}",
2134 [(set GR16:$dst, (cttz GR16:$src)), (implicit EFLAGS)]>, XS,
2136 def TZCNT16rm : I<0xBC, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
2137 "tzcnt{w}\t{$src, $dst|$dst, $src}",
2138 [(set GR16:$dst, (cttz (loadi16 addr:$src))),
2139 (implicit EFLAGS)]>, XS, OpSize16;
2141 def TZCNT32rr : I<0xBC, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
2142 "tzcnt{l}\t{$src, $dst|$dst, $src}",
2143 [(set GR32:$dst, (cttz GR32:$src)), (implicit EFLAGS)]>, XS,
2145 def TZCNT32rm : I<0xBC, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
2146 "tzcnt{l}\t{$src, $dst|$dst, $src}",
2147 [(set GR32:$dst, (cttz (loadi32 addr:$src))),
2148 (implicit EFLAGS)]>, XS, OpSize32;
2150 def TZCNT64rr : RI<0xBC, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
2151 "tzcnt{q}\t{$src, $dst|$dst, $src}",
2152 [(set GR64:$dst, (cttz GR64:$src)), (implicit EFLAGS)]>,
2154 def TZCNT64rm : RI<0xBC, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
2155 "tzcnt{q}\t{$src, $dst|$dst, $src}",
2156 [(set GR64:$dst, (cttz (loadi64 addr:$src))),
2157 (implicit EFLAGS)]>, XS;
2160 multiclass bmi_bls<string mnemonic, Format RegMRM, Format MemMRM,
2161 RegisterClass RC, X86MemOperand x86memop> {
2162 let hasSideEffects = 0 in {
2163 def rr : I<0xF3, RegMRM, (outs RC:$dst), (ins RC:$src),
2164 !strconcat(mnemonic, "\t{$src, $dst|$dst, $src}"),
2167 def rm : I<0xF3, MemMRM, (outs RC:$dst), (ins x86memop:$src),
2168 !strconcat(mnemonic, "\t{$src, $dst|$dst, $src}"),
2173 let Predicates = [HasBMI], Defs = [EFLAGS] in {
2174 defm BLSR32 : bmi_bls<"blsr{l}", MRM1r, MRM1m, GR32, i32mem>;
2175 defm BLSR64 : bmi_bls<"blsr{q}", MRM1r, MRM1m, GR64, i64mem>, VEX_W;
2176 defm BLSMSK32 : bmi_bls<"blsmsk{l}", MRM2r, MRM2m, GR32, i32mem>;
2177 defm BLSMSK64 : bmi_bls<"blsmsk{q}", MRM2r, MRM2m, GR64, i64mem>, VEX_W;
2178 defm BLSI32 : bmi_bls<"blsi{l}", MRM3r, MRM3m, GR32, i32mem>;
2179 defm BLSI64 : bmi_bls<"blsi{q}", MRM3r, MRM3m, GR64, i64mem>, VEX_W;
2182 //===----------------------------------------------------------------------===//
2183 // Pattern fragments to auto generate BMI instructions.
2184 //===----------------------------------------------------------------------===//
2186 let Predicates = [HasBMI] in {
2187 // FIXME: patterns for the load versions are not implemented
2188 def : Pat<(and GR32:$src, (add GR32:$src, -1)),
2189 (BLSR32rr GR32:$src)>;
2190 def : Pat<(and GR64:$src, (add GR64:$src, -1)),
2191 (BLSR64rr GR64:$src)>;
2193 def : Pat<(xor GR32:$src, (add GR32:$src, -1)),
2194 (BLSMSK32rr GR32:$src)>;
2195 def : Pat<(xor GR64:$src, (add GR64:$src, -1)),
2196 (BLSMSK64rr GR64:$src)>;
2198 def : Pat<(and GR32:$src, (ineg GR32:$src)),
2199 (BLSI32rr GR32:$src)>;
2200 def : Pat<(and GR64:$src, (ineg GR64:$src)),
2201 (BLSI64rr GR64:$src)>;
2204 let Predicates = [HasBMI] in {
2205 def : Pat<(X86cmov (cttz GR16:$src), (i16 16), (X86_COND_E_OR_NE),
2206 (X86cmp GR16:$src, (i16 0))),
2207 (TZCNT16rr GR16:$src)>;
2208 def : Pat<(X86cmov (cttz GR32:$src), (i32 32), (X86_COND_E_OR_NE),
2209 (X86cmp GR32:$src, (i32 0))),
2210 (TZCNT32rr GR32:$src)>;
2211 def : Pat<(X86cmov (cttz GR64:$src), (i64 64), (X86_COND_E_OR_NE),
2212 (X86cmp GR64:$src, (i64 0))),
2213 (TZCNT64rr GR64:$src)>;
2214 def : Pat<(X86cmov (i16 16), (cttz GR16:$src), (X86_COND_E_OR_NE),
2215 (X86cmp GR16:$src, (i16 0))),
2216 (TZCNT16rr GR16:$src)>;
2217 def : Pat<(X86cmov (i32 32), (cttz GR32:$src), (X86_COND_E_OR_NE),
2218 (X86cmp GR32:$src, (i32 0))),
2219 (TZCNT32rr GR32:$src)>;
2220 def : Pat<(X86cmov (i64 64), (cttz GR64:$src), (X86_COND_E_OR_NE),
2221 (X86cmp GR64:$src, (i64 0))),
2222 (TZCNT64rr GR64:$src)>;
2224 def : Pat<(X86cmov (cttz (loadi16 addr:$src)), (i16 16), (X86_COND_E_OR_NE),
2225 (X86cmp (loadi16 addr:$src), (i16 0))),
2226 (TZCNT16rm addr:$src)>;
2227 def : Pat<(X86cmov (cttz (loadi32 addr:$src)), (i32 32), (X86_COND_E_OR_NE),
2228 (X86cmp (loadi32 addr:$src), (i32 0))),
2229 (TZCNT32rm addr:$src)>;
2230 def : Pat<(X86cmov (cttz (loadi64 addr:$src)), (i64 64), (X86_COND_E_OR_NE),
2231 (X86cmp (loadi64 addr:$src), (i64 0))),
2232 (TZCNT64rm addr:$src)>;
2233 def : Pat<(X86cmov (i16 16), (cttz (loadi16 addr:$src)), (X86_COND_E_OR_NE),
2234 (X86cmp (loadi16 addr:$src), (i16 0))),
2235 (TZCNT16rm addr:$src)>;
2236 def : Pat<(X86cmov (i32 32), (cttz (loadi32 addr:$src)), (X86_COND_E_OR_NE),
2237 (X86cmp (loadi32 addr:$src), (i32 0))),
2238 (TZCNT32rm addr:$src)>;
2239 def : Pat<(X86cmov (i64 64), (cttz (loadi64 addr:$src)), (X86_COND_E_OR_NE),
2240 (X86cmp (loadi64 addr:$src), (i64 0))),
2241 (TZCNT64rm addr:$src)>;
2245 multiclass bmi_bextr_bzhi<bits<8> opc, string mnemonic, RegisterClass RC,
2246 X86MemOperand x86memop, Intrinsic Int,
2248 def rr : I<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
2249 !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2250 [(set RC:$dst, (Int RC:$src1, RC:$src2)), (implicit EFLAGS)]>,
2252 def rm : I<opc, MRMSrcMem, (outs RC:$dst), (ins x86memop:$src1, RC:$src2),
2253 !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2254 [(set RC:$dst, (Int (ld_frag addr:$src1), RC:$src2)),
2255 (implicit EFLAGS)]>, T8PS, VEX_4VOp3;
2258 let Predicates = [HasBMI], Defs = [EFLAGS] in {
2259 defm BEXTR32 : bmi_bextr_bzhi<0xF7, "bextr{l}", GR32, i32mem,
2260 int_x86_bmi_bextr_32, loadi32>;
2261 defm BEXTR64 : bmi_bextr_bzhi<0xF7, "bextr{q}", GR64, i64mem,
2262 int_x86_bmi_bextr_64, loadi64>, VEX_W;
2265 let Predicates = [HasBMI2], Defs = [EFLAGS] in {
2266 defm BZHI32 : bmi_bextr_bzhi<0xF5, "bzhi{l}", GR32, i32mem,
2267 int_x86_bmi_bzhi_32, loadi32>;
2268 defm BZHI64 : bmi_bextr_bzhi<0xF5, "bzhi{q}", GR64, i64mem,
2269 int_x86_bmi_bzhi_64, loadi64>, VEX_W;
2273 def CountTrailingOnes : SDNodeXForm<imm, [{
2274 // Count the trailing ones in the immediate.
2275 return getI8Imm(countTrailingOnes(N->getZExtValue()), SDLoc(N));
2278 def BZHIMask : ImmLeaf<i64, [{
2279 return isMask_64(Imm) && (countTrailingOnes<uint64_t>(Imm) > 32);
2282 let Predicates = [HasBMI2] in {
2283 def : Pat<(and GR64:$src, BZHIMask:$mask),
2284 (BZHI64rr GR64:$src,
2285 (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
2286 (MOV8ri (CountTrailingOnes imm:$mask)), sub_8bit))>;
2288 def : Pat<(and GR32:$src, (add (shl 1, GR8:$lz), -1)),
2289 (BZHI32rr GR32:$src,
2290 (INSERT_SUBREG (i32 (IMPLICIT_DEF)), GR8:$lz, sub_8bit))>;
2292 def : Pat<(and (loadi32 addr:$src), (add (shl 1, GR8:$lz), -1)),
2293 (BZHI32rm addr:$src,
2294 (INSERT_SUBREG (i32 (IMPLICIT_DEF)), GR8:$lz, sub_8bit))>;
2296 def : Pat<(and GR64:$src, (add (shl 1, GR8:$lz), -1)),
2297 (BZHI64rr GR64:$src,
2298 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR8:$lz, sub_8bit))>;
2300 def : Pat<(and (loadi64 addr:$src), (add (shl 1, GR8:$lz), -1)),
2301 (BZHI64rm addr:$src,
2302 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR8:$lz, sub_8bit))>;
2305 let Predicates = [HasBMI] in {
2306 def : Pat<(X86bextr GR32:$src1, GR32:$src2),
2307 (BEXTR32rr GR32:$src1, GR32:$src2)>;
2308 def : Pat<(X86bextr (loadi32 addr:$src1), GR32:$src2),
2309 (BEXTR32rm addr:$src1, GR32:$src2)>;
2310 def : Pat<(X86bextr GR64:$src1, GR64:$src2),
2311 (BEXTR64rr GR64:$src1, GR64:$src2)>;
2312 def : Pat<(X86bextr (loadi64 addr:$src1), GR64:$src2),
2313 (BEXTR64rm addr:$src1, GR64:$src2)>;
2316 multiclass bmi_pdep_pext<string mnemonic, RegisterClass RC,
2317 X86MemOperand x86memop, Intrinsic Int,
2319 def rr : I<0xF5, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
2320 !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2321 [(set RC:$dst, (Int RC:$src1, RC:$src2))]>,
2323 def rm : I<0xF5, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
2324 !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2325 [(set RC:$dst, (Int RC:$src1, (ld_frag addr:$src2)))]>, VEX_4V;
2328 let Predicates = [HasBMI2] in {
2329 defm PDEP32 : bmi_pdep_pext<"pdep{l}", GR32, i32mem,
2330 int_x86_bmi_pdep_32, loadi32>, T8XD;
2331 defm PDEP64 : bmi_pdep_pext<"pdep{q}", GR64, i64mem,
2332 int_x86_bmi_pdep_64, loadi64>, T8XD, VEX_W;
2333 defm PEXT32 : bmi_pdep_pext<"pext{l}", GR32, i32mem,
2334 int_x86_bmi_pext_32, loadi32>, T8XS;
2335 defm PEXT64 : bmi_pdep_pext<"pext{q}", GR64, i64mem,
2336 int_x86_bmi_pext_64, loadi64>, T8XS, VEX_W;
2339 //===----------------------------------------------------------------------===//
2342 let Predicates = [HasTBM], Defs = [EFLAGS] in {
2344 multiclass tbm_ternary_imm_intr<bits<8> opc, RegisterClass RC, string OpcodeStr,
2345 X86MemOperand x86memop, PatFrag ld_frag,
2346 Intrinsic Int, Operand immtype,
2347 SDPatternOperator immoperator> {
2348 def ri : Ii32<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, immtype:$cntl),
2349 !strconcat(OpcodeStr,
2350 "\t{$cntl, $src1, $dst|$dst, $src1, $cntl}"),
2351 [(set RC:$dst, (Int RC:$src1, immoperator:$cntl))]>,
2353 def mi : Ii32<opc, MRMSrcMem, (outs RC:$dst),
2354 (ins x86memop:$src1, immtype:$cntl),
2355 !strconcat(OpcodeStr,
2356 "\t{$cntl, $src1, $dst|$dst, $src1, $cntl}"),
2357 [(set RC:$dst, (Int (ld_frag addr:$src1), immoperator:$cntl))]>,
2361 defm BEXTRI32 : tbm_ternary_imm_intr<0x10, GR32, "bextr", i32mem, loadi32,
2362 int_x86_tbm_bextri_u32, i32imm, imm>;
2363 let ImmT = Imm32S in
2364 defm BEXTRI64 : tbm_ternary_imm_intr<0x10, GR64, "bextr", i64mem, loadi64,
2365 int_x86_tbm_bextri_u64, i64i32imm,
2366 i64immSExt32>, VEX_W;
2368 multiclass tbm_binary_rm<bits<8> opc, Format FormReg, Format FormMem,
2369 RegisterClass RC, string OpcodeStr,
2370 X86MemOperand x86memop, PatFrag ld_frag> {
2371 let hasSideEffects = 0 in {
2372 def rr : I<opc, FormReg, (outs RC:$dst), (ins RC:$src),
2373 !strconcat(OpcodeStr,"\t{$src, $dst|$dst, $src}"),
2376 def rm : I<opc, FormMem, (outs RC:$dst), (ins x86memop:$src),
2377 !strconcat(OpcodeStr,"\t{$src, $dst|$dst, $src}"),
2382 multiclass tbm_binary_intr<bits<8> opc, string OpcodeStr,
2383 Format FormReg, Format FormMem> {
2384 defm NAME#32 : tbm_binary_rm<opc, FormReg, FormMem, GR32, OpcodeStr, i32mem,
2386 defm NAME#64 : tbm_binary_rm<opc, FormReg, FormMem, GR64, OpcodeStr, i64mem,
2390 defm BLCFILL : tbm_binary_intr<0x01, "blcfill", MRM1r, MRM1m>;
2391 defm BLCI : tbm_binary_intr<0x02, "blci", MRM6r, MRM6m>;
2392 defm BLCIC : tbm_binary_intr<0x01, "blcic", MRM5r, MRM5m>;
2393 defm BLCMSK : tbm_binary_intr<0x02, "blcmsk", MRM1r, MRM1m>;
2394 defm BLCS : tbm_binary_intr<0x01, "blcs", MRM3r, MRM3m>;
2395 defm BLSFILL : tbm_binary_intr<0x01, "blsfill", MRM2r, MRM2m>;
2396 defm BLSIC : tbm_binary_intr<0x01, "blsic", MRM6r, MRM6m>;
2397 defm T1MSKC : tbm_binary_intr<0x01, "t1mskc", MRM7r, MRM7m>;
2398 defm TZMSK : tbm_binary_intr<0x01, "tzmsk", MRM4r, MRM4m>;
2401 //===----------------------------------------------------------------------===//
2402 // Pattern fragments to auto generate TBM instructions.
2403 //===----------------------------------------------------------------------===//
2405 let Predicates = [HasTBM] in {
2406 def : Pat<(X86bextr GR32:$src1, (i32 imm:$src2)),
2407 (BEXTRI32ri GR32:$src1, imm:$src2)>;
2408 def : Pat<(X86bextr (loadi32 addr:$src1), (i32 imm:$src2)),
2409 (BEXTRI32mi addr:$src1, imm:$src2)>;
2410 def : Pat<(X86bextr GR64:$src1, i64immSExt32:$src2),
2411 (BEXTRI64ri GR64:$src1, i64immSExt32:$src2)>;
2412 def : Pat<(X86bextr (loadi64 addr:$src1), i64immSExt32:$src2),
2413 (BEXTRI64mi addr:$src1, i64immSExt32:$src2)>;
2415 // FIXME: patterns for the load versions are not implemented
2416 def : Pat<(and GR32:$src, (add GR32:$src, 1)),
2417 (BLCFILL32rr GR32:$src)>;
2418 def : Pat<(and GR64:$src, (add GR64:$src, 1)),
2419 (BLCFILL64rr GR64:$src)>;
2421 def : Pat<(or GR32:$src, (not (add GR32:$src, 1))),
2422 (BLCI32rr GR32:$src)>;
2423 def : Pat<(or GR64:$src, (not (add GR64:$src, 1))),
2424 (BLCI64rr GR64:$src)>;
2426 // Extra patterns because opt can optimize the above patterns to this.
2427 def : Pat<(or GR32:$src, (sub -2, GR32:$src)),
2428 (BLCI32rr GR32:$src)>;
2429 def : Pat<(or GR64:$src, (sub -2, GR64:$src)),
2430 (BLCI64rr GR64:$src)>;
2432 def : Pat<(and (not GR32:$src), (add GR32:$src, 1)),
2433 (BLCIC32rr GR32:$src)>;
2434 def : Pat<(and (not GR64:$src), (add GR64:$src, 1)),
2435 (BLCIC64rr GR64:$src)>;
2437 def : Pat<(xor GR32:$src, (add GR32:$src, 1)),
2438 (BLCMSK32rr GR32:$src)>;
2439 def : Pat<(xor GR64:$src, (add GR64:$src, 1)),
2440 (BLCMSK64rr GR64:$src)>;
2442 def : Pat<(or GR32:$src, (add GR32:$src, 1)),
2443 (BLCS32rr GR32:$src)>;
2444 def : Pat<(or GR64:$src, (add GR64:$src, 1)),
2445 (BLCS64rr GR64:$src)>;
2447 def : Pat<(or GR32:$src, (add GR32:$src, -1)),
2448 (BLSFILL32rr GR32:$src)>;
2449 def : Pat<(or GR64:$src, (add GR64:$src, -1)),
2450 (BLSFILL64rr GR64:$src)>;
2452 def : Pat<(or (not GR32:$src), (add GR32:$src, -1)),
2453 (BLSIC32rr GR32:$src)>;
2454 def : Pat<(or (not GR64:$src), (add GR64:$src, -1)),
2455 (BLSIC64rr GR64:$src)>;
2457 def : Pat<(or (not GR32:$src), (add GR32:$src, 1)),
2458 (T1MSKC32rr GR32:$src)>;
2459 def : Pat<(or (not GR64:$src), (add GR64:$src, 1)),
2460 (T1MSKC64rr GR64:$src)>;
2462 def : Pat<(and (not GR32:$src), (add GR32:$src, -1)),
2463 (TZMSK32rr GR32:$src)>;
2464 def : Pat<(and (not GR64:$src), (add GR64:$src, -1)),
2465 (TZMSK64rr GR64:$src)>;
2468 //===----------------------------------------------------------------------===//
2469 // Memory Instructions
2472 def CLFLUSHOPT : I<0xAE, MRM7m, (outs), (ins i8mem:$src),
2473 "clflushopt\t$src", []>, PD;
2474 def CLWB : I<0xAE, MRM6m, (outs), (ins i8mem:$src), "clwb\t$src", []>, PD;
2475 def PCOMMIT : I<0xAE, MRM_F8, (outs), (ins), "pcommit", []>, PD;
2478 //===----------------------------------------------------------------------===//
2480 //===----------------------------------------------------------------------===//
2482 include "X86InstrArithmetic.td"
2483 include "X86InstrCMovSetCC.td"
2484 include "X86InstrExtension.td"
2485 include "X86InstrControl.td"
2486 include "X86InstrShiftRotate.td"
2488 // X87 Floating Point Stack.
2489 include "X86InstrFPStack.td"
2491 // SIMD support (SSE, MMX and AVX)
2492 include "X86InstrFragmentsSIMD.td"
2494 // FMA - Fused Multiply-Add support (requires FMA)
2495 include "X86InstrFMA.td"
2498 include "X86InstrXOP.td"
2500 // SSE, MMX and 3DNow! vector support.
2501 include "X86InstrSSE.td"
2502 include "X86InstrAVX512.td"
2503 include "X86InstrMMX.td"
2504 include "X86Instr3DNow.td"
2507 include "X86InstrMPX.td"
2509 include "X86InstrVMX.td"
2510 include "X86InstrSVM.td"
2512 include "X86InstrTSX.td"
2513 include "X86InstrSGX.td"
2515 // System instructions.
2516 include "X86InstrSystem.td"
2518 // Compiler Pseudo Instructions and Pat Patterns
2519 include "X86InstrCompiler.td"
2521 //===----------------------------------------------------------------------===//
2522 // Assembler Mnemonic Aliases
2523 //===----------------------------------------------------------------------===//
2525 def : MnemonicAlias<"call", "callw", "att">, Requires<[In16BitMode]>;
2526 def : MnemonicAlias<"call", "calll", "att">, Requires<[In32BitMode]>;
2527 def : MnemonicAlias<"call", "callq", "att">, Requires<[In64BitMode]>;
2529 def : MnemonicAlias<"cbw", "cbtw", "att">;
2530 def : MnemonicAlias<"cwde", "cwtl", "att">;
2531 def : MnemonicAlias<"cwd", "cwtd", "att">;
2532 def : MnemonicAlias<"cdq", "cltd", "att">;
2533 def : MnemonicAlias<"cdqe", "cltq", "att">;
2534 def : MnemonicAlias<"cqo", "cqto", "att">;
2536 // In 64-bit mode lret maps to lretl; it is not ambiguous with lretq.
2537 def : MnemonicAlias<"lret", "lretw", "att">, Requires<[In16BitMode]>;
2538 def : MnemonicAlias<"lret", "lretl", "att">, Requires<[Not16BitMode]>;
2540 def : MnemonicAlias<"leavel", "leave", "att">, Requires<[Not64BitMode]>;
2541 def : MnemonicAlias<"leaveq", "leave", "att">, Requires<[In64BitMode]>;
2543 def : MnemonicAlias<"loopz", "loope", "att">;
2544 def : MnemonicAlias<"loopnz", "loopne", "att">;
2546 def : MnemonicAlias<"pop", "popw", "att">, Requires<[In16BitMode]>;
2547 def : MnemonicAlias<"pop", "popl", "att">, Requires<[In32BitMode]>;
2548 def : MnemonicAlias<"pop", "popq", "att">, Requires<[In64BitMode]>;
2549 def : MnemonicAlias<"popf", "popfw", "att">, Requires<[In16BitMode]>;
2550 def : MnemonicAlias<"popf", "popfl", "att">, Requires<[In32BitMode]>;
2551 def : MnemonicAlias<"popf", "popfq", "att">, Requires<[In64BitMode]>;
2552 def : MnemonicAlias<"popfd", "popfl", "att">;
2554 // FIXME: This is wrong for "push reg". "push %bx" should turn into pushw in
2555 // all modes. However: "push (addr)" and "push $42" should default to
2556 // pushl/pushq depending on the current mode. Similar for "pop %bx"
2557 def : MnemonicAlias<"push", "pushw", "att">, Requires<[In16BitMode]>;
2558 def : MnemonicAlias<"push", "pushl", "att">, Requires<[In32BitMode]>;
2559 def : MnemonicAlias<"push", "pushq", "att">, Requires<[In64BitMode]>;
2560 def : MnemonicAlias<"pushf", "pushfw", "att">, Requires<[In16BitMode]>;
2561 def : MnemonicAlias<"pushf", "pushfl", "att">, Requires<[In32BitMode]>;
2562 def : MnemonicAlias<"pushf", "pushfq", "att">, Requires<[In64BitMode]>;
2563 def : MnemonicAlias<"pushfd", "pushfl", "att">;
2565 def : MnemonicAlias<"popad", "popal", "intel">, Requires<[Not64BitMode]>;
2566 def : MnemonicAlias<"pushad", "pushal", "intel">, Requires<[Not64BitMode]>;
2567 def : MnemonicAlias<"popa", "popaw", "intel">, Requires<[In16BitMode]>;
2568 def : MnemonicAlias<"pusha", "pushaw", "intel">, Requires<[In16BitMode]>;
2569 def : MnemonicAlias<"popa", "popal", "intel">, Requires<[In32BitMode]>;
2570 def : MnemonicAlias<"pusha", "pushal", "intel">, Requires<[In32BitMode]>;
2572 def : MnemonicAlias<"popa", "popaw", "att">, Requires<[In16BitMode]>;
2573 def : MnemonicAlias<"pusha", "pushaw", "att">, Requires<[In16BitMode]>;
2574 def : MnemonicAlias<"popa", "popal", "att">, Requires<[In32BitMode]>;
2575 def : MnemonicAlias<"pusha", "pushal", "att">, Requires<[In32BitMode]>;
2577 def : MnemonicAlias<"repe", "rep">;
2578 def : MnemonicAlias<"repz", "rep">;
2579 def : MnemonicAlias<"repnz", "repne">;
2581 def : MnemonicAlias<"ret", "retw", "att">, Requires<[In16BitMode]>;
2582 def : MnemonicAlias<"ret", "retl", "att">, Requires<[In32BitMode]>;
2583 def : MnemonicAlias<"ret", "retq", "att">, Requires<[In64BitMode]>;
2585 def : MnemonicAlias<"sal", "shl", "intel">;
2586 def : MnemonicAlias<"salb", "shlb", "att">;
2587 def : MnemonicAlias<"salw", "shlw", "att">;
2588 def : MnemonicAlias<"sall", "shll", "att">;
2589 def : MnemonicAlias<"salq", "shlq", "att">;
2591 def : MnemonicAlias<"smovb", "movsb", "att">;
2592 def : MnemonicAlias<"smovw", "movsw", "att">;
2593 def : MnemonicAlias<"smovl", "movsl", "att">;
2594 def : MnemonicAlias<"smovq", "movsq", "att">;
2596 def : MnemonicAlias<"ud2a", "ud2", "att">;
2597 def : MnemonicAlias<"verrw", "verr", "att">;
2599 // System instruction aliases.
2600 def : MnemonicAlias<"iret", "iretw", "att">, Requires<[In16BitMode]>;
2601 def : MnemonicAlias<"iret", "iretl", "att">, Requires<[Not16BitMode]>;
2602 def : MnemonicAlias<"sysret", "sysretl", "att">;
2603 def : MnemonicAlias<"sysexit", "sysexitl", "att">;
2605 def : MnemonicAlias<"lgdt", "lgdtw", "att">, Requires<[In16BitMode]>;
2606 def : MnemonicAlias<"lgdt", "lgdtl", "att">, Requires<[In32BitMode]>;
2607 def : MnemonicAlias<"lgdt", "lgdtq", "att">, Requires<[In64BitMode]>;
2608 def : MnemonicAlias<"lidt", "lidtw", "att">, Requires<[In16BitMode]>;
2609 def : MnemonicAlias<"lidt", "lidtl", "att">, Requires<[In32BitMode]>;
2610 def : MnemonicAlias<"lidt", "lidtq", "att">, Requires<[In64BitMode]>;
2611 def : MnemonicAlias<"sgdt", "sgdtw", "att">, Requires<[In16BitMode]>;
2612 def : MnemonicAlias<"sgdt", "sgdtl", "att">, Requires<[In32BitMode]>;
2613 def : MnemonicAlias<"sgdt", "sgdtq", "att">, Requires<[In64BitMode]>;
2614 def : MnemonicAlias<"sidt", "sidtw", "att">, Requires<[In16BitMode]>;
2615 def : MnemonicAlias<"sidt", "sidtl", "att">, Requires<[In32BitMode]>;
2616 def : MnemonicAlias<"sidt", "sidtq", "att">, Requires<[In64BitMode]>;
2619 // Floating point stack aliases.
2620 def : MnemonicAlias<"fcmovz", "fcmove", "att">;
2621 def : MnemonicAlias<"fcmova", "fcmovnbe", "att">;
2622 def : MnemonicAlias<"fcmovnae", "fcmovb", "att">;
2623 def : MnemonicAlias<"fcmovna", "fcmovbe", "att">;
2624 def : MnemonicAlias<"fcmovae", "fcmovnb", "att">;
2625 def : MnemonicAlias<"fcomip", "fcompi", "att">;
2626 def : MnemonicAlias<"fildq", "fildll", "att">;
2627 def : MnemonicAlias<"fistpq", "fistpll", "att">;
2628 def : MnemonicAlias<"fisttpq", "fisttpll", "att">;
2629 def : MnemonicAlias<"fldcww", "fldcw", "att">;
2630 def : MnemonicAlias<"fnstcww", "fnstcw", "att">;
2631 def : MnemonicAlias<"fnstsww", "fnstsw", "att">;
2632 def : MnemonicAlias<"fucomip", "fucompi", "att">;
2633 def : MnemonicAlias<"fwait", "wait">;
2635 def : MnemonicAlias<"fxsaveq", "fxsave64", "att">;
2636 def : MnemonicAlias<"fxrstorq", "fxrstor64", "att">;
2637 def : MnemonicAlias<"xsaveq", "xsave64", "att">;
2638 def : MnemonicAlias<"xrstorq", "xrstor64", "att">;
2639 def : MnemonicAlias<"xsaveoptq", "xsaveopt64", "att">;
2642 class CondCodeAlias<string Prefix,string Suffix, string OldCond, string NewCond,
2644 : MnemonicAlias<!strconcat(Prefix, OldCond, Suffix),
2645 !strconcat(Prefix, NewCond, Suffix), VariantName>;
2647 /// IntegerCondCodeMnemonicAlias - This multiclass defines a bunch of
2648 /// MnemonicAlias's that canonicalize the condition code in a mnemonic, for
2649 /// example "setz" -> "sete".
2650 multiclass IntegerCondCodeMnemonicAlias<string Prefix, string Suffix,
2652 def C : CondCodeAlias<Prefix, Suffix, "c", "b", V>; // setc -> setb
2653 def Z : CondCodeAlias<Prefix, Suffix, "z" , "e", V>; // setz -> sete
2654 def NA : CondCodeAlias<Prefix, Suffix, "na", "be", V>; // setna -> setbe
2655 def NB : CondCodeAlias<Prefix, Suffix, "nb", "ae", V>; // setnb -> setae
2656 def NC : CondCodeAlias<Prefix, Suffix, "nc", "ae", V>; // setnc -> setae
2657 def NG : CondCodeAlias<Prefix, Suffix, "ng", "le", V>; // setng -> setle
2658 def NL : CondCodeAlias<Prefix, Suffix, "nl", "ge", V>; // setnl -> setge
2659 def NZ : CondCodeAlias<Prefix, Suffix, "nz", "ne", V>; // setnz -> setne
2660 def PE : CondCodeAlias<Prefix, Suffix, "pe", "p", V>; // setpe -> setp
2661 def PO : CondCodeAlias<Prefix, Suffix, "po", "np", V>; // setpo -> setnp
2663 def NAE : CondCodeAlias<Prefix, Suffix, "nae", "b", V>; // setnae -> setb
2664 def NBE : CondCodeAlias<Prefix, Suffix, "nbe", "a", V>; // setnbe -> seta
2665 def NGE : CondCodeAlias<Prefix, Suffix, "nge", "l", V>; // setnge -> setl
2666 def NLE : CondCodeAlias<Prefix, Suffix, "nle", "g", V>; // setnle -> setg
2669 // Aliases for set<CC>
2670 defm : IntegerCondCodeMnemonicAlias<"set", "">;
2671 // Aliases for j<CC>
2672 defm : IntegerCondCodeMnemonicAlias<"j", "">;
2673 // Aliases for cmov<CC>{w,l,q}
2674 defm : IntegerCondCodeMnemonicAlias<"cmov", "w", "att">;
2675 defm : IntegerCondCodeMnemonicAlias<"cmov", "l", "att">;
2676 defm : IntegerCondCodeMnemonicAlias<"cmov", "q", "att">;
2677 // No size suffix for intel-style asm.
2678 defm : IntegerCondCodeMnemonicAlias<"cmov", "", "intel">;
2681 //===----------------------------------------------------------------------===//
2682 // Assembler Instruction Aliases
2683 //===----------------------------------------------------------------------===//
2685 // aad/aam default to base 10 if no operand is specified.
2686 def : InstAlias<"aad", (AAD8i8 10)>;
2687 def : InstAlias<"aam", (AAM8i8 10)>;
2689 // Disambiguate the mem/imm form of bt-without-a-suffix as btl.
2690 // Likewise for btc/btr/bts.
2691 def : InstAlias<"bt {$imm, $mem|$mem, $imm}",
2692 (BT32mi8 i32mem:$mem, i32i8imm:$imm), 0>;
2693 def : InstAlias<"btc {$imm, $mem|$mem, $imm}",
2694 (BTC32mi8 i32mem:$mem, i32i8imm:$imm), 0>;
2695 def : InstAlias<"btr {$imm, $mem|$mem, $imm}",
2696 (BTR32mi8 i32mem:$mem, i32i8imm:$imm), 0>;
2697 def : InstAlias<"bts {$imm, $mem|$mem, $imm}",
2698 (BTS32mi8 i32mem:$mem, i32i8imm:$imm), 0>;
2701 def : InstAlias<"clrb $reg", (XOR8rr GR8 :$reg, GR8 :$reg), 0>;
2702 def : InstAlias<"clrw $reg", (XOR16rr GR16:$reg, GR16:$reg), 0>;
2703 def : InstAlias<"clrl $reg", (XOR32rr GR32:$reg, GR32:$reg), 0>;
2704 def : InstAlias<"clrq $reg", (XOR64rr GR64:$reg, GR64:$reg), 0>;
2706 // lods aliases. Accept the destination being omitted because it's implicit
2707 // in the mnemonic, or the mnemonic suffix being omitted because it's implicit
2708 // in the destination.
2709 def : InstAlias<"lodsb $src", (LODSB srcidx8:$src), 0>;
2710 def : InstAlias<"lodsw $src", (LODSW srcidx16:$src), 0>;
2711 def : InstAlias<"lods{l|d} $src", (LODSL srcidx32:$src), 0>;
2712 def : InstAlias<"lodsq $src", (LODSQ srcidx64:$src), 0>, Requires<[In64BitMode]>;
2713 def : InstAlias<"lods {$src, %al|al, $src}", (LODSB srcidx8:$src), 0>;
2714 def : InstAlias<"lods {$src, %ax|ax, $src}", (LODSW srcidx16:$src), 0>;
2715 def : InstAlias<"lods {$src, %eax|eax, $src}", (LODSL srcidx32:$src), 0>;
2716 def : InstAlias<"lods {$src, %rax|rax, $src}", (LODSQ srcidx64:$src), 0>, Requires<[In64BitMode]>;
2718 // stos aliases. Accept the source being omitted because it's implicit in
2719 // the mnemonic, or the mnemonic suffix being omitted because it's implicit
2721 def : InstAlias<"stosb $dst", (STOSB dstidx8:$dst), 0>;
2722 def : InstAlias<"stosw $dst", (STOSW dstidx16:$dst), 0>;
2723 def : InstAlias<"stos{l|d} $dst", (STOSL dstidx32:$dst), 0>;
2724 def : InstAlias<"stosq $dst", (STOSQ dstidx64:$dst), 0>, Requires<[In64BitMode]>;
2725 def : InstAlias<"stos {%al, $dst|$dst, al}", (STOSB dstidx8:$dst), 0>;
2726 def : InstAlias<"stos {%ax, $dst|$dst, ax}", (STOSW dstidx16:$dst), 0>;
2727 def : InstAlias<"stos {%eax, $dst|$dst, eax}", (STOSL dstidx32:$dst), 0>;
2728 def : InstAlias<"stos {%rax, $dst|$dst, rax}", (STOSQ dstidx64:$dst), 0>, Requires<[In64BitMode]>;
2730 // scas aliases. Accept the destination being omitted because it's implicit
2731 // in the mnemonic, or the mnemonic suffix being omitted because it's implicit
2732 // in the destination.
2733 def : InstAlias<"scasb $dst", (SCASB dstidx8:$dst), 0>;
2734 def : InstAlias<"scasw $dst", (SCASW dstidx16:$dst), 0>;
2735 def : InstAlias<"scas{l|d} $dst", (SCASL dstidx32:$dst), 0>;
2736 def : InstAlias<"scasq $dst", (SCASQ dstidx64:$dst), 0>, Requires<[In64BitMode]>;
2737 def : InstAlias<"scas {$dst, %al|al, $dst}", (SCASB dstidx8:$dst), 0>;
2738 def : InstAlias<"scas {$dst, %ax|ax, $dst}", (SCASW dstidx16:$dst), 0>;
2739 def : InstAlias<"scas {$dst, %eax|eax, $dst}", (SCASL dstidx32:$dst), 0>;
2740 def : InstAlias<"scas {$dst, %rax|rax, $dst}", (SCASQ dstidx64:$dst), 0>, Requires<[In64BitMode]>;
2742 // div and idiv aliases for explicit A register.
2743 def : InstAlias<"div{b}\t{$src, %al|al, $src}", (DIV8r GR8 :$src)>;
2744 def : InstAlias<"div{w}\t{$src, %ax|ax, $src}", (DIV16r GR16:$src)>;
2745 def : InstAlias<"div{l}\t{$src, %eax|eax, $src}", (DIV32r GR32:$src)>;
2746 def : InstAlias<"div{q}\t{$src, %rax|rax, $src}", (DIV64r GR64:$src)>;
2747 def : InstAlias<"div{b}\t{$src, %al|al, $src}", (DIV8m i8mem :$src)>;
2748 def : InstAlias<"div{w}\t{$src, %ax|ax, $src}", (DIV16m i16mem:$src)>;
2749 def : InstAlias<"div{l}\t{$src, %eax|eax, $src}", (DIV32m i32mem:$src)>;
2750 def : InstAlias<"div{q}\t{$src, %rax|rax, $src}", (DIV64m i64mem:$src)>;
2751 def : InstAlias<"idiv{b}\t{$src, %al|al, $src}", (IDIV8r GR8 :$src)>;
2752 def : InstAlias<"idiv{w}\t{$src, %ax|ax, $src}", (IDIV16r GR16:$src)>;
2753 def : InstAlias<"idiv{l}\t{$src, %eax|eax, $src}", (IDIV32r GR32:$src)>;
2754 def : InstAlias<"idiv{q}\t{$src, %rax|rax, $src}", (IDIV64r GR64:$src)>;
2755 def : InstAlias<"idiv{b}\t{$src, %al|al, $src}", (IDIV8m i8mem :$src)>;
2756 def : InstAlias<"idiv{w}\t{$src, %ax|ax, $src}", (IDIV16m i16mem:$src)>;
2757 def : InstAlias<"idiv{l}\t{$src, %eax|eax, $src}", (IDIV32m i32mem:$src)>;
2758 def : InstAlias<"idiv{q}\t{$src, %rax|rax, $src}", (IDIV64m i64mem:$src)>;
2762 // Various unary fpstack operations default to operating on on ST1.
2763 // For example, "fxch" -> "fxch %st(1)"
2764 def : InstAlias<"faddp", (ADD_FPrST0 ST1), 0>;
2765 def : InstAlias<"fsub{|r}p", (SUBR_FPrST0 ST1), 0>;
2766 def : InstAlias<"fsub{r|}p", (SUB_FPrST0 ST1), 0>;
2767 def : InstAlias<"fmulp", (MUL_FPrST0 ST1), 0>;
2768 def : InstAlias<"fdiv{|r}p", (DIVR_FPrST0 ST1), 0>;
2769 def : InstAlias<"fdiv{r|}p", (DIV_FPrST0 ST1), 0>;
2770 def : InstAlias<"fxch", (XCH_F ST1), 0>;
2771 def : InstAlias<"fcom", (COM_FST0r ST1), 0>;
2772 def : InstAlias<"fcomp", (COMP_FST0r ST1), 0>;
2773 def : InstAlias<"fcomi", (COM_FIr ST1), 0>;
2774 def : InstAlias<"fcompi", (COM_FIPr ST1), 0>;
2775 def : InstAlias<"fucom", (UCOM_Fr ST1), 0>;
2776 def : InstAlias<"fucomp", (UCOM_FPr ST1), 0>;
2777 def : InstAlias<"fucomi", (UCOM_FIr ST1), 0>;
2778 def : InstAlias<"fucompi", (UCOM_FIPr ST1), 0>;
2780 // Handle fmul/fadd/fsub/fdiv instructions with explicitly written st(0) op.
2781 // For example, "fadd %st(4), %st(0)" -> "fadd %st(4)". We also disambiguate
2782 // instructions like "fadd %st(0), %st(0)" as "fadd %st(0)" for consistency with
2784 multiclass FpUnaryAlias<string Mnemonic, Instruction Inst, bit EmitAlias = 1> {
2785 def : InstAlias<!strconcat(Mnemonic, "\t{$op, %st(0)|st(0), $op}"),
2786 (Inst RST:$op), EmitAlias>;
2787 def : InstAlias<!strconcat(Mnemonic, "\t{%st(0), %st(0)|st(0), st(0)}"),
2788 (Inst ST0), EmitAlias>;
2791 defm : FpUnaryAlias<"fadd", ADD_FST0r>;
2792 defm : FpUnaryAlias<"faddp", ADD_FPrST0, 0>;
2793 defm : FpUnaryAlias<"fsub", SUB_FST0r>;
2794 defm : FpUnaryAlias<"fsub{|r}p", SUBR_FPrST0>;
2795 defm : FpUnaryAlias<"fsubr", SUBR_FST0r>;
2796 defm : FpUnaryAlias<"fsub{r|}p", SUB_FPrST0>;
2797 defm : FpUnaryAlias<"fmul", MUL_FST0r>;
2798 defm : FpUnaryAlias<"fmulp", MUL_FPrST0>;
2799 defm : FpUnaryAlias<"fdiv", DIV_FST0r>;
2800 defm : FpUnaryAlias<"fdiv{|r}p", DIVR_FPrST0>;
2801 defm : FpUnaryAlias<"fdivr", DIVR_FST0r>;
2802 defm : FpUnaryAlias<"fdiv{r|}p", DIV_FPrST0>;
2803 defm : FpUnaryAlias<"fcomi", COM_FIr, 0>;
2804 defm : FpUnaryAlias<"fucomi", UCOM_FIr, 0>;
2805 defm : FpUnaryAlias<"fcompi", COM_FIPr>;
2806 defm : FpUnaryAlias<"fucompi", UCOM_FIPr>;
2809 // Handle "f{mulp,addp} st(0), $op" the same as "f{mulp,addp} $op", since they
2810 // commute. We also allow fdiv[r]p/fsubrp even though they don't commute,
2811 // solely because gas supports it.
2812 def : InstAlias<"faddp\t{%st(0), $op|$op, st(0)}", (ADD_FPrST0 RST:$op), 0>;
2813 def : InstAlias<"fmulp\t{%st(0), $op|$op, st(0)}", (MUL_FPrST0 RST:$op)>;
2814 def : InstAlias<"fsub{|r}p\t{%st(0), $op|$op, st(0)}", (SUBR_FPrST0 RST:$op)>;
2815 def : InstAlias<"fsub{r|}p\t{%st(0), $op|$op, st(0)}", (SUB_FPrST0 RST:$op)>;
2816 def : InstAlias<"fdiv{|r}p\t{%st(0), $op|$op, st(0)}", (DIVR_FPrST0 RST:$op)>;
2817 def : InstAlias<"fdiv{r|}p\t{%st(0), $op|$op, st(0)}", (DIV_FPrST0 RST:$op)>;
2819 // We accept "fnstsw %eax" even though it only writes %ax.
2820 def : InstAlias<"fnstsw\t{%eax|eax}", (FNSTSW16r)>;
2821 def : InstAlias<"fnstsw\t{%al|al}" , (FNSTSW16r)>;
2822 def : InstAlias<"fnstsw" , (FNSTSW16r)>;
2824 // lcall and ljmp aliases. This seems to be an odd mapping in 64-bit mode, but
2825 // this is compatible with what GAS does.
2826 def : InstAlias<"lcall $seg, $off", (FARCALL32i i32imm:$off, i16imm:$seg), 0>, Requires<[Not16BitMode]>;
2827 def : InstAlias<"ljmp $seg, $off", (FARJMP32i i32imm:$off, i16imm:$seg), 0>, Requires<[Not16BitMode]>;
2828 def : InstAlias<"lcall {*}$dst", (FARCALL32m opaque48mem:$dst), 0>, Requires<[Not16BitMode]>;
2829 def : InstAlias<"ljmp {*}$dst", (FARJMP32m opaque48mem:$dst), 0>, Requires<[Not16BitMode]>;
2830 def : InstAlias<"lcall $seg, $off", (FARCALL16i i16imm:$off, i16imm:$seg), 0>, Requires<[In16BitMode]>;
2831 def : InstAlias<"ljmp $seg, $off", (FARJMP16i i16imm:$off, i16imm:$seg), 0>, Requires<[In16BitMode]>;
2832 def : InstAlias<"lcall {*}$dst", (FARCALL16m opaque32mem:$dst), 0>, Requires<[In16BitMode]>;
2833 def : InstAlias<"ljmp {*}$dst", (FARJMP16m opaque32mem:$dst), 0>, Requires<[In16BitMode]>;
2835 def : InstAlias<"call {*}$dst", (CALL64m i64mem:$dst), 0>, Requires<[In64BitMode]>;
2836 def : InstAlias<"jmp {*}$dst", (JMP64m i64mem:$dst), 0>, Requires<[In64BitMode]>;
2837 def : InstAlias<"call {*}$dst", (CALL32m i32mem:$dst), 0>, Requires<[In32BitMode]>;
2838 def : InstAlias<"jmp {*}$dst", (JMP32m i32mem:$dst), 0>, Requires<[In32BitMode]>;
2839 def : InstAlias<"call {*}$dst", (CALL16m i16mem:$dst), 0>, Requires<[In16BitMode]>;
2840 def : InstAlias<"jmp {*}$dst", (JMP16m i16mem:$dst), 0>, Requires<[In16BitMode]>;
2843 // "imul <imm>, B" is an alias for "imul <imm>, B, B".
2844 def : InstAlias<"imul{w} {$imm, $r|$r, $imm}", (IMUL16rri GR16:$r, GR16:$r, i16imm:$imm), 0>;
2845 def : InstAlias<"imul{w} {$imm, $r|$r, $imm}", (IMUL16rri8 GR16:$r, GR16:$r, i16i8imm:$imm), 0>;
2846 def : InstAlias<"imul{l} {$imm, $r|$r, $imm}", (IMUL32rri GR32:$r, GR32:$r, i32imm:$imm), 0>;
2847 def : InstAlias<"imul{l} {$imm, $r|$r, $imm}", (IMUL32rri8 GR32:$r, GR32:$r, i32i8imm:$imm), 0>;
2848 def : InstAlias<"imul{q} {$imm, $r|$r, $imm}", (IMUL64rri32 GR64:$r, GR64:$r, i64i32imm:$imm), 0>;
2849 def : InstAlias<"imul{q} {$imm, $r|$r, $imm}", (IMUL64rri8 GR64:$r, GR64:$r, i64i8imm:$imm), 0>;
2851 // inb %dx -> inb %al, %dx
2852 def : InstAlias<"inb\t{%dx|dx}", (IN8rr), 0>;
2853 def : InstAlias<"inw\t{%dx|dx}", (IN16rr), 0>;
2854 def : InstAlias<"inl\t{%dx|dx}", (IN32rr), 0>;
2855 def : InstAlias<"inb\t$port", (IN8ri i8imm:$port), 0>;
2856 def : InstAlias<"inw\t$port", (IN16ri i8imm:$port), 0>;
2857 def : InstAlias<"inl\t$port", (IN32ri i8imm:$port), 0>;
2860 // jmp and call aliases for lcall and ljmp. jmp $42,$5 -> ljmp
2861 def : InstAlias<"call $seg, $off", (FARCALL16i i16imm:$off, i16imm:$seg)>, Requires<[In16BitMode]>;
2862 def : InstAlias<"jmp $seg, $off", (FARJMP16i i16imm:$off, i16imm:$seg)>, Requires<[In16BitMode]>;
2863 def : InstAlias<"call $seg, $off", (FARCALL32i i32imm:$off, i16imm:$seg)>, Requires<[Not16BitMode]>;
2864 def : InstAlias<"jmp $seg, $off", (FARJMP32i i32imm:$off, i16imm:$seg)>, Requires<[Not16BitMode]>;
2865 def : InstAlias<"callw $seg, $off", (FARCALL16i i16imm:$off, i16imm:$seg)>;
2866 def : InstAlias<"jmpw $seg, $off", (FARJMP16i i16imm:$off, i16imm:$seg)>;
2867 def : InstAlias<"calll $seg, $off", (FARCALL32i i32imm:$off, i16imm:$seg)>;
2868 def : InstAlias<"jmpl $seg, $off", (FARJMP32i i32imm:$off, i16imm:$seg)>;
2870 // Force mov without a suffix with a segment and mem to prefer the 'l' form of
2871 // the move. All segment/mem forms are equivalent, this has the shortest
2873 def : InstAlias<"mov {$mem, $seg|$seg, $mem}", (MOV32sm SEGMENT_REG:$seg, i32mem:$mem), 0>;
2874 def : InstAlias<"mov {$seg, $mem|$mem, $seg}", (MOV32ms i32mem:$mem, SEGMENT_REG:$seg), 0>;
2876 // Match 'movq <largeimm>, <reg>' as an alias for movabsq.
2877 def : InstAlias<"movq {$imm, $reg|$reg, $imm}", (MOV64ri GR64:$reg, i64imm:$imm), 0>;
2879 // Match 'movq GR64, MMX' as an alias for movd.
2880 def : InstAlias<"movq {$src, $dst|$dst, $src}",
2881 (MMX_MOVD64to64rr VR64:$dst, GR64:$src), 0>;
2882 def : InstAlias<"movq {$src, $dst|$dst, $src}",
2883 (MMX_MOVD64from64rr GR64:$dst, VR64:$src), 0>;
2886 def : InstAlias<"movsx {$src, $dst|$dst, $src}", (MOVSX16rr8 GR16:$dst, GR8:$src), 0>;
2887 def : InstAlias<"movsx {$src, $dst|$dst, $src}", (MOVSX16rm8 GR16:$dst, i8mem:$src), 0>;
2888 def : InstAlias<"movsx {$src, $dst|$dst, $src}", (MOVSX32rr8 GR32:$dst, GR8:$src), 0>;
2889 def : InstAlias<"movsx {$src, $dst|$dst, $src}", (MOVSX32rr16 GR32:$dst, GR16:$src), 0>;
2890 def : InstAlias<"movsx {$src, $dst|$dst, $src}", (MOVSX64rr8 GR64:$dst, GR8:$src), 0>;
2891 def : InstAlias<"movsx {$src, $dst|$dst, $src}", (MOVSX64rr16 GR64:$dst, GR16:$src), 0>;
2892 def : InstAlias<"movsx {$src, $dst|$dst, $src}", (MOVSX64rr32 GR64:$dst, GR32:$src), 0>;
2895 def : InstAlias<"movzx {$src, $dst|$dst, $src}", (MOVZX16rr8 GR16:$dst, GR8:$src), 0>;
2896 def : InstAlias<"movzx {$src, $dst|$dst, $src}", (MOVZX16rm8 GR16:$dst, i8mem:$src), 0>;
2897 def : InstAlias<"movzx {$src, $dst|$dst, $src}", (MOVZX32rr8 GR32:$dst, GR8:$src), 0>;
2898 def : InstAlias<"movzx {$src, $dst|$dst, $src}", (MOVZX32rr16 GR32:$dst, GR16:$src), 0>;
2899 def : InstAlias<"movzx {$src, $dst|$dst, $src}", (MOVZX64rr8_Q GR64:$dst, GR8:$src), 0>;
2900 def : InstAlias<"movzx {$src, $dst|$dst, $src}", (MOVZX64rr16_Q GR64:$dst, GR16:$src), 0>;
2901 // Note: No GR32->GR64 movzx form.
2903 // outb %dx -> outb %al, %dx
2904 def : InstAlias<"outb\t{%dx|dx}", (OUT8rr), 0>;
2905 def : InstAlias<"outw\t{%dx|dx}", (OUT16rr), 0>;
2906 def : InstAlias<"outl\t{%dx|dx}", (OUT32rr), 0>;
2907 def : InstAlias<"outb\t$port", (OUT8ir i8imm:$port), 0>;
2908 def : InstAlias<"outw\t$port", (OUT16ir i8imm:$port), 0>;
2909 def : InstAlias<"outl\t$port", (OUT32ir i8imm:$port), 0>;
2911 // 'sldt <mem>' can be encoded with either sldtw or sldtq with the same
2912 // effect (both store to a 16-bit mem). Force to sldtw to avoid ambiguity
2913 // errors, since its encoding is the most compact.
2914 def : InstAlias<"sldt $mem", (SLDT16m i16mem:$mem), 0>;
2916 // shld/shrd op,op -> shld op, op, CL
2917 def : InstAlias<"shld{w}\t{$r2, $r1|$r1, $r2}", (SHLD16rrCL GR16:$r1, GR16:$r2), 0>;
2918 def : InstAlias<"shld{l}\t{$r2, $r1|$r1, $r2}", (SHLD32rrCL GR32:$r1, GR32:$r2), 0>;
2919 def : InstAlias<"shld{q}\t{$r2, $r1|$r1, $r2}", (SHLD64rrCL GR64:$r1, GR64:$r2), 0>;
2920 def : InstAlias<"shrd{w}\t{$r2, $r1|$r1, $r2}", (SHRD16rrCL GR16:$r1, GR16:$r2), 0>;
2921 def : InstAlias<"shrd{l}\t{$r2, $r1|$r1, $r2}", (SHRD32rrCL GR32:$r1, GR32:$r2), 0>;
2922 def : InstAlias<"shrd{q}\t{$r2, $r1|$r1, $r2}", (SHRD64rrCL GR64:$r1, GR64:$r2), 0>;
2924 def : InstAlias<"shld{w}\t{$reg, $mem|$mem, $reg}", (SHLD16mrCL i16mem:$mem, GR16:$reg), 0>;
2925 def : InstAlias<"shld{l}\t{$reg, $mem|$mem, $reg}", (SHLD32mrCL i32mem:$mem, GR32:$reg), 0>;
2926 def : InstAlias<"shld{q}\t{$reg, $mem|$mem, $reg}", (SHLD64mrCL i64mem:$mem, GR64:$reg), 0>;
2927 def : InstAlias<"shrd{w}\t{$reg, $mem|$mem, $reg}", (SHRD16mrCL i16mem:$mem, GR16:$reg), 0>;
2928 def : InstAlias<"shrd{l}\t{$reg, $mem|$mem, $reg}", (SHRD32mrCL i32mem:$mem, GR32:$reg), 0>;
2929 def : InstAlias<"shrd{q}\t{$reg, $mem|$mem, $reg}", (SHRD64mrCL i64mem:$mem, GR64:$reg), 0>;
2931 /* FIXME: This is disabled because the asm matcher is currently incapable of
2932 * matching a fixed immediate like $1.
2933 // "shl X, $1" is an alias for "shl X".
2934 multiclass ShiftRotateByOneAlias<string Mnemonic, string Opc> {
2935 def : InstAlias<!strconcat(Mnemonic, "b $op, $$1"),
2936 (!cast<Instruction>(!strconcat(Opc, "8r1")) GR8:$op)>;
2937 def : InstAlias<!strconcat(Mnemonic, "w $op, $$1"),
2938 (!cast<Instruction>(!strconcat(Opc, "16r1")) GR16:$op)>;
2939 def : InstAlias<!strconcat(Mnemonic, "l $op, $$1"),
2940 (!cast<Instruction>(!strconcat(Opc, "32r1")) GR32:$op)>;
2941 def : InstAlias<!strconcat(Mnemonic, "q $op, $$1"),
2942 (!cast<Instruction>(!strconcat(Opc, "64r1")) GR64:$op)>;
2943 def : InstAlias<!strconcat(Mnemonic, "b $op, $$1"),
2944 (!cast<Instruction>(!strconcat(Opc, "8m1")) i8mem:$op)>;
2945 def : InstAlias<!strconcat(Mnemonic, "w $op, $$1"),
2946 (!cast<Instruction>(!strconcat(Opc, "16m1")) i16mem:$op)>;
2947 def : InstAlias<!strconcat(Mnemonic, "l $op, $$1"),
2948 (!cast<Instruction>(!strconcat(Opc, "32m1")) i32mem:$op)>;
2949 def : InstAlias<!strconcat(Mnemonic, "q $op, $$1"),
2950 (!cast<Instruction>(!strconcat(Opc, "64m1")) i64mem:$op)>;
2953 defm : ShiftRotateByOneAlias<"rcl", "RCL">;
2954 defm : ShiftRotateByOneAlias<"rcr", "RCR">;
2955 defm : ShiftRotateByOneAlias<"rol", "ROL">;
2956 defm : ShiftRotateByOneAlias<"ror", "ROR">;
2959 // test: We accept "testX <reg>, <mem>" and "testX <mem>, <reg>" as synonyms.
2960 def : InstAlias<"test{b}\t{$val, $mem|$mem, $val}",
2961 (TEST8rm GR8 :$val, i8mem :$mem), 0>;
2962 def : InstAlias<"test{w}\t{$val, $mem|$mem, $val}",
2963 (TEST16rm GR16:$val, i16mem:$mem), 0>;
2964 def : InstAlias<"test{l}\t{$val, $mem|$mem, $val}",
2965 (TEST32rm GR32:$val, i32mem:$mem), 0>;
2966 def : InstAlias<"test{q}\t{$val, $mem|$mem, $val}",
2967 (TEST64rm GR64:$val, i64mem:$mem), 0>;
2969 // xchg: We accept "xchgX <reg>, <mem>" and "xchgX <mem>, <reg>" as synonyms.
2970 def : InstAlias<"xchg{b}\t{$mem, $val|$val, $mem}",
2971 (XCHG8rm GR8 :$val, i8mem :$mem), 0>;
2972 def : InstAlias<"xchg{w}\t{$mem, $val|$val, $mem}",
2973 (XCHG16rm GR16:$val, i16mem:$mem), 0>;
2974 def : InstAlias<"xchg{l}\t{$mem, $val|$val, $mem}",
2975 (XCHG32rm GR32:$val, i32mem:$mem), 0>;
2976 def : InstAlias<"xchg{q}\t{$mem, $val|$val, $mem}",
2977 (XCHG64rm GR64:$val, i64mem:$mem), 0>;
2979 // xchg: We accept "xchgX <reg>, %eax" and "xchgX %eax, <reg>" as synonyms.
2980 def : InstAlias<"xchg{w}\t{%ax, $src|$src, ax}", (XCHG16ar GR16:$src), 0>;
2981 def : InstAlias<"xchg{l}\t{%eax, $src|$src, eax}",
2982 (XCHG32ar GR32:$src), 0>, Requires<[Not64BitMode]>;
2983 def : InstAlias<"xchg{l}\t{%eax, $src|$src, eax}",
2984 (XCHG32ar64 GR32_NOAX:$src), 0>, Requires<[In64BitMode]>;
2985 def : InstAlias<"xchg{q}\t{%rax, $src|$src, rax}", (XCHG64ar GR64:$src), 0>;