1 //===-- X86InstrInfo.td - Main X86 Instruction Definition --*- tablegen -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file describes the X86 instruction set, defining the instructions, and
11 // properties of the instructions which are needed for code generation, machine
12 // code emission, and analysis.
14 //===----------------------------------------------------------------------===//
16 //===----------------------------------------------------------------------===//
17 // X86 specific DAG Nodes.
20 def SDTIntShiftDOp: SDTypeProfile<1, 3,
21 [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>,
22 SDTCisInt<0>, SDTCisInt<3>]>;
24 def SDTX86CmpTest : SDTypeProfile<1, 2, [SDTCisVT<0, i32>, SDTCisSameAs<1, 2>]>;
26 def SDTX86Cmps : SDTypeProfile<1, 3, [SDTCisFP<0>, SDTCisSameAs<1, 2>, SDTCisVT<3, i8>]>;
27 //def SDTX86Cmpss : SDTypeProfile<1, 3, [SDTCisVT<0, f32>, SDTCisSameAs<1, 2>, SDTCisVT<3, i8>]>;
29 def SDTX86Cmov : SDTypeProfile<1, 4,
30 [SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>,
31 SDTCisVT<3, i8>, SDTCisVT<4, i32>]>;
33 // Unary and binary operator instructions that set EFLAGS as a side-effect.
34 def SDTUnaryArithWithFlags : SDTypeProfile<2, 1,
36 SDTCisInt<0>, SDTCisVT<1, i32>]>;
38 def SDTBinaryArithWithFlags : SDTypeProfile<2, 2,
41 SDTCisInt<0>, SDTCisVT<1, i32>]>;
43 // SDTBinaryArithWithFlagsInOut - RES1, EFLAGS = op LHS, RHS, EFLAGS
44 def SDTBinaryArithWithFlagsInOut : SDTypeProfile<2, 3,
50 // RES1, RES2, FLAGS = op LHS, RHS
51 def SDT2ResultBinaryArithWithFlags : SDTypeProfile<3, 2,
55 SDTCisInt<0>, SDTCisVT<1, i32>]>;
56 def SDTX86BrCond : SDTypeProfile<0, 3,
57 [SDTCisVT<0, OtherVT>,
58 SDTCisVT<1, i8>, SDTCisVT<2, i32>]>;
60 def SDTX86SetCC : SDTypeProfile<1, 2,
62 SDTCisVT<1, i8>, SDTCisVT<2, i32>]>;
63 def SDTX86SetCC_C : SDTypeProfile<1, 2,
65 SDTCisVT<1, i8>, SDTCisVT<2, i32>]>;
67 def SDTX86sahf : SDTypeProfile<1, 1, [SDTCisVT<0, i32>, SDTCisVT<1, i8>]>;
69 def SDTX86rdrand : SDTypeProfile<2, 0, [SDTCisInt<0>, SDTCisVT<1, i32>]>;
71 def SDTX86cas : SDTypeProfile<0, 3, [SDTCisPtrTy<0>, SDTCisInt<1>,
73 def SDTX86caspair : SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>;
75 def SDTX86atomicBinary : SDTypeProfile<2, 3, [SDTCisInt<0>, SDTCisInt<1>,
76 SDTCisPtrTy<2>, SDTCisInt<3>,SDTCisInt<4>]>;
77 def SDTX86Ret : SDTypeProfile<0, -1, [SDTCisVT<0, i16>]>;
79 def SDT_X86CallSeqStart : SDCallSeqStart<[SDTCisVT<0, i32>]>;
80 def SDT_X86CallSeqEnd : SDCallSeqEnd<[SDTCisVT<0, i32>,
83 def SDT_X86Call : SDTypeProfile<0, -1, [SDTCisVT<0, iPTR>]>;
85 def SDT_X86VASTART_SAVE_XMM_REGS : SDTypeProfile<0, -1, [SDTCisVT<0, i8>,
89 def SDT_X86VAARG_64 : SDTypeProfile<1, -1, [SDTCisPtrTy<0>,
95 def SDTX86RepStr : SDTypeProfile<0, 1, [SDTCisVT<0, OtherVT>]>;
97 def SDTX86Void : SDTypeProfile<0, 0, []>;
99 def SDTX86Wrapper : SDTypeProfile<1, 1, [SDTCisSameAs<0, 1>, SDTCisPtrTy<0>]>;
101 def SDT_X86TLSADDR : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
103 def SDT_X86TLSBASEADDR : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
105 def SDT_X86TLSCALL : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
107 def SDT_X86SEG_ALLOCA : SDTypeProfile<1, 1, [SDTCisVT<0, iPTR>, SDTCisVT<1, iPTR>]>;
109 def SDT_X86EHRET : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
111 def SDT_X86TCRET : SDTypeProfile<0, 2, [SDTCisPtrTy<0>, SDTCisVT<1, i32>]>;
113 def SDT_X86MEMBARRIER : SDTypeProfile<0, 0, []>;
115 def X86MemBarrier : SDNode<"X86ISD::MEMBARRIER", SDT_X86MEMBARRIER,
116 [SDNPHasChain,SDNPSideEffect]>;
117 def X86MFence : SDNode<"X86ISD::MFENCE", SDT_X86MEMBARRIER,
119 def X86SFence : SDNode<"X86ISD::SFENCE", SDT_X86MEMBARRIER,
121 def X86LFence : SDNode<"X86ISD::LFENCE", SDT_X86MEMBARRIER,
125 def X86bsf : SDNode<"X86ISD::BSF", SDTUnaryArithWithFlags>;
126 def X86bsr : SDNode<"X86ISD::BSR", SDTUnaryArithWithFlags>;
127 def X86shld : SDNode<"X86ISD::SHLD", SDTIntShiftDOp>;
128 def X86shrd : SDNode<"X86ISD::SHRD", SDTIntShiftDOp>;
130 def X86cmp : SDNode<"X86ISD::CMP" , SDTX86CmpTest>;
131 def X86bt : SDNode<"X86ISD::BT", SDTX86CmpTest>;
133 def X86cmov : SDNode<"X86ISD::CMOV", SDTX86Cmov>;
134 def X86brcond : SDNode<"X86ISD::BRCOND", SDTX86BrCond,
136 def X86setcc : SDNode<"X86ISD::SETCC", SDTX86SetCC>;
137 def X86setcc_c : SDNode<"X86ISD::SETCC_CARRY", SDTX86SetCC_C>;
139 def X86sahf : SDNode<"X86ISD::SAHF", SDTX86sahf>;
141 def X86rdrand : SDNode<"X86ISD::RDRAND", SDTX86rdrand,
142 [SDNPHasChain, SDNPSideEffect]>;
144 def X86rdseed : SDNode<"X86ISD::RDSEED", SDTX86rdrand,
145 [SDNPHasChain, SDNPSideEffect]>;
147 def X86cas : SDNode<"X86ISD::LCMPXCHG_DAG", SDTX86cas,
148 [SDNPHasChain, SDNPInGlue, SDNPOutGlue, SDNPMayStore,
149 SDNPMayLoad, SDNPMemOperand]>;
150 def X86cas8 : SDNode<"X86ISD::LCMPXCHG8_DAG", SDTX86caspair,
151 [SDNPHasChain, SDNPInGlue, SDNPOutGlue, SDNPMayStore,
152 SDNPMayLoad, SDNPMemOperand]>;
153 def X86cas16 : SDNode<"X86ISD::LCMPXCHG16_DAG", SDTX86caspair,
154 [SDNPHasChain, SDNPInGlue, SDNPOutGlue, SDNPMayStore,
155 SDNPMayLoad, SDNPMemOperand]>;
157 def X86retflag : SDNode<"X86ISD::RET_FLAG", SDTX86Ret,
158 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
159 def X86iret : SDNode<"X86ISD::IRET", SDTX86Ret,
160 [SDNPHasChain, SDNPOptInGlue]>;
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 //===----------------------------------------------------------------------===//
254 // X86 Operand Definitions.
257 // A version of ptr_rc which excludes SP, ESP, and RSP. This is used for
258 // the index operand of an address, to conform to x86 encoding restrictions.
259 def ptr_rc_nosp : PointerLikeRegClass<1>;
261 // *mem - Operand definitions for the funky X86 addressing mode operands.
263 def X86MemAsmOperand : AsmOperandClass {
266 let RenderMethod = "addMemOperands" in {
267 def X86Mem8AsmOperand : AsmOperandClass { let Name = "Mem8"; }
268 def X86Mem16AsmOperand : AsmOperandClass { let Name = "Mem16"; }
269 def X86Mem32AsmOperand : AsmOperandClass { let Name = "Mem32"; }
270 def X86Mem64AsmOperand : AsmOperandClass { let Name = "Mem64"; }
271 def X86Mem80AsmOperand : AsmOperandClass { let Name = "Mem80"; }
272 def X86Mem128AsmOperand : AsmOperandClass { let Name = "Mem128"; }
273 def X86Mem256AsmOperand : AsmOperandClass { let Name = "Mem256"; }
274 def X86Mem512AsmOperand : AsmOperandClass { let Name = "Mem512"; }
275 // Gather mem operands
276 def X86MemVX32Operand : AsmOperandClass { let Name = "MemVX32"; }
277 def X86MemVY32Operand : AsmOperandClass { let Name = "MemVY32"; }
278 def X86MemVZ32Operand : AsmOperandClass { let Name = "MemVZ32"; }
279 def X86MemVX64Operand : AsmOperandClass { let Name = "MemVX64"; }
280 def X86MemVY64Operand : AsmOperandClass { let Name = "MemVY64"; }
281 def X86MemVZ64Operand : AsmOperandClass { let Name = "MemVZ64"; }
282 def X86MemVX32XOperand : AsmOperandClass { let Name = "MemVX32X"; }
283 def X86MemVY32XOperand : AsmOperandClass { let Name = "MemVY32X"; }
284 def X86MemVX64XOperand : AsmOperandClass { let Name = "MemVX64X"; }
285 def X86MemVY64XOperand : AsmOperandClass { let Name = "MemVY64X"; }
288 def X86AbsMemAsmOperand : AsmOperandClass {
290 let SuperClasses = [X86MemAsmOperand];
293 class X86MemOperand<string printMethod,
294 AsmOperandClass parserMatchClass = X86MemAsmOperand> : Operand<iPTR> {
295 let PrintMethod = printMethod;
296 let MIOperandInfo = (ops ptr_rc, i8imm, ptr_rc_nosp, i32imm, i8imm);
297 let ParserMatchClass = parserMatchClass;
298 let OperandType = "OPERAND_MEMORY";
301 // Gather mem operands
302 class X86VMemOperand<RegisterClass RC, string printMethod,
303 AsmOperandClass parserMatchClass>
304 : X86MemOperand<printMethod, parserMatchClass> {
305 let MIOperandInfo = (ops ptr_rc, i8imm, RC, i32imm, i8imm);
308 def anymem : X86MemOperand<"printanymem">;
310 def opaque32mem : X86MemOperand<"printopaquemem">;
311 def opaque48mem : X86MemOperand<"printopaquemem">;
312 def opaque80mem : X86MemOperand<"printopaquemem">;
313 def opaque512mem : X86MemOperand<"printopaquemem">;
315 def i8mem : X86MemOperand<"printi8mem", X86Mem8AsmOperand>;
316 def i16mem : X86MemOperand<"printi16mem", X86Mem16AsmOperand>;
317 def i32mem : X86MemOperand<"printi32mem", X86Mem32AsmOperand>;
318 def i64mem : X86MemOperand<"printi64mem", X86Mem64AsmOperand>;
319 def i128mem : X86MemOperand<"printi128mem", X86Mem128AsmOperand>;
320 def i256mem : X86MemOperand<"printi256mem", X86Mem256AsmOperand>;
321 def i512mem : X86MemOperand<"printi512mem", X86Mem512AsmOperand>;
322 def f32mem : X86MemOperand<"printf32mem", X86Mem32AsmOperand>;
323 def f64mem : X86MemOperand<"printf64mem", X86Mem64AsmOperand>;
324 def f80mem : X86MemOperand<"printf80mem", X86Mem80AsmOperand>;
325 def f128mem : X86MemOperand<"printf128mem", X86Mem128AsmOperand>;
326 def f256mem : X86MemOperand<"printf256mem", X86Mem256AsmOperand>;
327 def f512mem : X86MemOperand<"printf512mem", X86Mem512AsmOperand>;
329 def v512mem : X86VMemOperand<VR512, "printf512mem", X86Mem512AsmOperand>;
331 // Gather mem operands
332 def vx32mem : X86VMemOperand<VR128, "printi32mem", X86MemVX32Operand>;
333 def vy32mem : X86VMemOperand<VR256, "printi32mem", X86MemVY32Operand>;
334 def vx64mem : X86VMemOperand<VR128, "printi64mem", X86MemVX64Operand>;
335 def vy64mem : X86VMemOperand<VR256, "printi64mem", X86MemVY64Operand>;
337 def vx32xmem : X86VMemOperand<VR128X, "printi32mem", X86MemVX32XOperand>;
338 def vx64xmem : X86VMemOperand<VR128X, "printi32mem", X86MemVX64XOperand>;
339 def vy32xmem : X86VMemOperand<VR256X, "printi32mem", X86MemVY32XOperand>;
340 def vy64xmem : X86VMemOperand<VR256X, "printi64mem", X86MemVY64XOperand>;
341 def vz32mem : X86VMemOperand<VR512, "printi32mem", X86MemVZ32Operand>;
342 def vz64mem : X86VMemOperand<VR512, "printi64mem", X86MemVZ64Operand>;
344 // A version of i8mem for use on x86-64 and x32 that uses a NOREX GPR instead
345 // of a plain GPR, so that it doesn't potentially require a REX prefix.
346 def ptr_rc_norex : PointerLikeRegClass<2>;
347 def ptr_rc_norex_nosp : PointerLikeRegClass<3>;
349 def i8mem_NOREX : Operand<iPTR> {
350 let PrintMethod = "printi8mem";
351 let MIOperandInfo = (ops ptr_rc_norex, i8imm, ptr_rc_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<4>;
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()">;
775 def NoVLX_Or_NoDQI : Predicate<"!Subtarget->hasVLX() || !Subtarget->hasDQI()">;
776 def PKU : Predicate<"!Subtarget->hasPKU()">;
778 def HasPOPCNT : Predicate<"Subtarget->hasPOPCNT()">;
779 def HasAES : Predicate<"Subtarget->hasAES()">;
780 def HasFXSR : Predicate<"Subtarget->hasFXSR()">;
781 def HasXSAVE : Predicate<"Subtarget->hasXSAVE()">;
782 def HasXSAVEOPT : Predicate<"Subtarget->hasXSAVEOPT()">;
783 def HasXSAVEC : Predicate<"Subtarget->hasXSAVEC()">;
784 def HasXSAVES : Predicate<"Subtarget->hasXSAVES()">;
785 def HasPCLMUL : Predicate<"Subtarget->hasPCLMUL()">;
786 def HasFMA : Predicate<"Subtarget->hasFMA()">;
787 def UseFMAOnAVX : Predicate<"Subtarget->hasFMA() && !Subtarget->hasAVX512()">;
788 def HasFMA4 : Predicate<"Subtarget->hasFMA4()">;
789 def HasXOP : Predicate<"Subtarget->hasXOP()">;
790 def HasTBM : Predicate<"Subtarget->hasTBM()">;
791 def HasMOVBE : Predicate<"Subtarget->hasMOVBE()">;
792 def HasRDRAND : Predicate<"Subtarget->hasRDRAND()">;
793 def HasF16C : Predicate<"Subtarget->hasF16C()">;
794 def HasFSGSBase : Predicate<"Subtarget->hasFSGSBase()">;
795 def HasLZCNT : Predicate<"Subtarget->hasLZCNT()">;
796 def HasBMI : Predicate<"Subtarget->hasBMI()">;
797 def HasBMI2 : Predicate<"Subtarget->hasBMI2()">;
798 def HasRTM : Predicate<"Subtarget->hasRTM()">;
799 def HasHLE : Predicate<"Subtarget->hasHLE()">;
800 def HasTSX : Predicate<"Subtarget->hasRTM() || Subtarget->hasHLE()">;
801 def HasADX : Predicate<"Subtarget->hasADX()">;
802 def HasSHA : Predicate<"Subtarget->hasSHA()">;
803 def HasPRFCHW : Predicate<"Subtarget->hasPRFCHW()">;
804 def HasRDSEED : Predicate<"Subtarget->hasRDSEED()">;
805 def HasPrefetchW : Predicate<"Subtarget->hasPRFCHW()">;
806 def HasLAHFSAHF : Predicate<"Subtarget->hasLAHFSAHF()">;
807 def FPStackf32 : Predicate<"!Subtarget->hasSSE1()">;
808 def FPStackf64 : Predicate<"!Subtarget->hasSSE2()">;
809 def HasMPX : Predicate<"Subtarget->hasMPX()">;
810 def HasCmpxchg16b: Predicate<"Subtarget->hasCmpxchg16b()">;
811 def Not64BitMode : Predicate<"!Subtarget->is64Bit()">,
812 AssemblerPredicate<"!Mode64Bit", "Not 64-bit mode">;
813 def In64BitMode : Predicate<"Subtarget->is64Bit()">,
814 AssemblerPredicate<"Mode64Bit", "64-bit mode">;
815 def IsLP64 : Predicate<"Subtarget->isTarget64BitLP64()">;
816 def NotLP64 : Predicate<"!Subtarget->isTarget64BitLP64()">;
817 def In16BitMode : Predicate<"Subtarget->is16Bit()">,
818 AssemblerPredicate<"Mode16Bit", "16-bit mode">;
819 def Not16BitMode : Predicate<"!Subtarget->is16Bit()">,
820 AssemblerPredicate<"!Mode16Bit", "Not 16-bit mode">;
821 def In32BitMode : Predicate<"Subtarget->is32Bit()">,
822 AssemblerPredicate<"Mode32Bit", "32-bit mode">;
823 def IsWin64 : Predicate<"Subtarget->isTargetWin64()">;
824 def NotWin64 : Predicate<"!Subtarget->isTargetWin64()">;
825 def IsPS4 : Predicate<"Subtarget->isTargetPS4()">;
826 def NotPS4 : Predicate<"!Subtarget->isTargetPS4()">;
827 def IsNaCl : Predicate<"Subtarget->isTargetNaCl()">;
828 def NotNaCl : Predicate<"!Subtarget->isTargetNaCl()">;
829 def SmallCode : Predicate<"TM.getCodeModel() == CodeModel::Small">;
830 def KernelCode : Predicate<"TM.getCodeModel() == CodeModel::Kernel">;
831 def FarData : Predicate<"TM.getCodeModel() != CodeModel::Small &&"
832 "TM.getCodeModel() != CodeModel::Kernel">;
833 def NearData : Predicate<"TM.getCodeModel() == CodeModel::Small ||"
834 "TM.getCodeModel() == CodeModel::Kernel">;
835 def IsStatic : Predicate<"TM.getRelocationModel() == Reloc::Static">;
836 def IsNotPIC : Predicate<"TM.getRelocationModel() != Reloc::PIC_">;
837 def OptForSize : Predicate<"OptForSize">;
838 def OptForSpeed : Predicate<"!OptForSize">;
839 def FastBTMem : Predicate<"!Subtarget->isBTMemSlow()">;
840 def CallImmAddr : Predicate<"Subtarget->IsLegalToCallImmediateAddr(TM)">;
841 def FavorMemIndirectCall : Predicate<"!Subtarget->callRegIndirect()">;
842 def NotSlowIncDec : Predicate<"!Subtarget->slowIncDec()">;
843 def HasFastMem32 : Predicate<"!Subtarget->isUnalignedMem32Slow()">;
845 //===----------------------------------------------------------------------===//
846 // X86 Instruction Format Definitions.
849 include "X86InstrFormats.td"
851 //===----------------------------------------------------------------------===//
852 // Pattern fragments.
855 // X86 specific condition code. These correspond to CondCode in
856 // X86InstrInfo.h. They must be kept in synch.
857 def X86_COND_A : PatLeaf<(i8 0)>; // alt. COND_NBE
858 def X86_COND_AE : PatLeaf<(i8 1)>; // alt. COND_NC
859 def X86_COND_B : PatLeaf<(i8 2)>; // alt. COND_C
860 def X86_COND_BE : PatLeaf<(i8 3)>; // alt. COND_NA
861 def X86_COND_E : PatLeaf<(i8 4)>; // alt. COND_Z
862 def X86_COND_G : PatLeaf<(i8 5)>; // alt. COND_NLE
863 def X86_COND_GE : PatLeaf<(i8 6)>; // alt. COND_NL
864 def X86_COND_L : PatLeaf<(i8 7)>; // alt. COND_NGE
865 def X86_COND_LE : PatLeaf<(i8 8)>; // alt. COND_NG
866 def X86_COND_NE : PatLeaf<(i8 9)>; // alt. COND_NZ
867 def X86_COND_NO : PatLeaf<(i8 10)>;
868 def X86_COND_NP : PatLeaf<(i8 11)>; // alt. COND_PO
869 def X86_COND_NS : PatLeaf<(i8 12)>;
870 def X86_COND_O : PatLeaf<(i8 13)>;
871 def X86_COND_P : PatLeaf<(i8 14)>; // alt. COND_PE
872 def X86_COND_S : PatLeaf<(i8 15)>;
874 // Predicate used to help when pattern matching LZCNT/TZCNT.
875 def X86_COND_E_OR_NE : ImmLeaf<i8, [{
876 return (Imm == X86::COND_E) || (Imm == X86::COND_NE);
880 def i16immSExt8 : ImmLeaf<i16, [{ return isInt<8>(Imm); }]>;
881 def i32immSExt8 : ImmLeaf<i32, [{ return isInt<8>(Imm); }]>;
882 def i64immSExt8 : ImmLeaf<i64, [{ return isInt<8>(Imm); }]>;
884 // If we have multiple users of an immediate, it's much smaller to reuse
885 // the register, rather than encode the immediate in every instruction.
886 // This has the risk of increasing register pressure from stretched live
887 // ranges, however, the immediates should be trivial to rematerialize by
888 // the RA in the event of high register pressure.
889 // TODO : This is currently enabled for stores and binary ops. There are more
890 // cases for which this can be enabled, though this catches the bulk of the
892 // TODO2 : This should really also be enabled under O2, but there's currently
893 // an issue with RA where we don't pull the constants into their users
894 // when we rematerialize them. I'll follow-up on enabling O2 after we fix that
896 // TODO3 : This is currently limited to single basic blocks (DAG creation
897 // pulls block immediates to the top and merges them if necessary).
898 // Eventually, it would be nice to allow ConstantHoisting to merge constants
899 // globally for potentially added savings.
901 def imm8_su : PatLeaf<(i8 imm), [{
902 return !shouldAvoidImmediateInstFormsForSize(N);
904 def imm16_su : PatLeaf<(i16 imm), [{
905 return !shouldAvoidImmediateInstFormsForSize(N);
907 def imm32_su : PatLeaf<(i32 imm), [{
908 return !shouldAvoidImmediateInstFormsForSize(N);
911 def i16immSExt8_su : PatLeaf<(i16immSExt8), [{
912 return !shouldAvoidImmediateInstFormsForSize(N);
914 def i32immSExt8_su : PatLeaf<(i32immSExt8), [{
915 return !shouldAvoidImmediateInstFormsForSize(N);
919 def i64immSExt32 : ImmLeaf<i64, [{ return isInt<32>(Imm); }]>;
922 // i64immZExt32 predicate - True if the 64-bit immediate fits in a 32-bit
924 def i64immZExt32 : ImmLeaf<i64, [{ return isUInt<32>(Imm); }]>;
926 def i64immZExt32SExt8 : ImmLeaf<i64, [{
927 return isUInt<32>(Imm) && isInt<8>(static_cast<int32_t>(Imm));
930 // Helper fragments for loads.
931 // It's always safe to treat a anyext i16 load as a i32 load if the i16 is
932 // known to be 32-bit aligned or better. Ditto for i8 to i16.
933 def loadi16 : PatFrag<(ops node:$ptr), (i16 (unindexedload node:$ptr)), [{
934 LoadSDNode *LD = cast<LoadSDNode>(N);
935 ISD::LoadExtType ExtType = LD->getExtensionType();
936 if (ExtType == ISD::NON_EXTLOAD)
938 if (ExtType == ISD::EXTLOAD)
939 return LD->getAlignment() >= 2 && !LD->isVolatile();
943 def loadi16_anyext : PatFrag<(ops node:$ptr), (i32 (unindexedload node:$ptr)),[{
944 LoadSDNode *LD = cast<LoadSDNode>(N);
945 ISD::LoadExtType ExtType = LD->getExtensionType();
946 if (ExtType == ISD::EXTLOAD)
947 return LD->getAlignment() >= 2 && !LD->isVolatile();
951 def loadi32 : PatFrag<(ops node:$ptr), (i32 (unindexedload node:$ptr)), [{
952 LoadSDNode *LD = cast<LoadSDNode>(N);
953 ISD::LoadExtType ExtType = LD->getExtensionType();
954 if (ExtType == ISD::NON_EXTLOAD)
956 if (ExtType == ISD::EXTLOAD)
957 return LD->getAlignment() >= 4 && !LD->isVolatile();
961 def loadi8 : PatFrag<(ops node:$ptr), (i8 (load node:$ptr))>;
962 def loadi64 : PatFrag<(ops node:$ptr), (i64 (load node:$ptr))>;
963 def loadf32 : PatFrag<(ops node:$ptr), (f32 (load node:$ptr))>;
964 def loadf64 : PatFrag<(ops node:$ptr), (f64 (load node:$ptr))>;
965 def loadf80 : PatFrag<(ops node:$ptr), (f80 (load node:$ptr))>;
966 def loadf128 : PatFrag<(ops node:$ptr), (f128 (load node:$ptr))>;
968 def sextloadi16i8 : PatFrag<(ops node:$ptr), (i16 (sextloadi8 node:$ptr))>;
969 def sextloadi32i8 : PatFrag<(ops node:$ptr), (i32 (sextloadi8 node:$ptr))>;
970 def sextloadi32i16 : PatFrag<(ops node:$ptr), (i32 (sextloadi16 node:$ptr))>;
971 def sextloadi64i8 : PatFrag<(ops node:$ptr), (i64 (sextloadi8 node:$ptr))>;
972 def sextloadi64i16 : PatFrag<(ops node:$ptr), (i64 (sextloadi16 node:$ptr))>;
973 def sextloadi64i32 : PatFrag<(ops node:$ptr), (i64 (sextloadi32 node:$ptr))>;
975 def zextloadi8i1 : PatFrag<(ops node:$ptr), (i8 (zextloadi1 node:$ptr))>;
976 def zextloadi16i1 : PatFrag<(ops node:$ptr), (i16 (zextloadi1 node:$ptr))>;
977 def zextloadi32i1 : PatFrag<(ops node:$ptr), (i32 (zextloadi1 node:$ptr))>;
978 def zextloadi16i8 : PatFrag<(ops node:$ptr), (i16 (zextloadi8 node:$ptr))>;
979 def zextloadi32i8 : PatFrag<(ops node:$ptr), (i32 (zextloadi8 node:$ptr))>;
980 def zextloadi32i16 : PatFrag<(ops node:$ptr), (i32 (zextloadi16 node:$ptr))>;
981 def zextloadi64i1 : PatFrag<(ops node:$ptr), (i64 (zextloadi1 node:$ptr))>;
982 def zextloadi64i8 : PatFrag<(ops node:$ptr), (i64 (zextloadi8 node:$ptr))>;
983 def zextloadi64i16 : PatFrag<(ops node:$ptr), (i64 (zextloadi16 node:$ptr))>;
984 def zextloadi64i32 : PatFrag<(ops node:$ptr), (i64 (zextloadi32 node:$ptr))>;
986 def extloadi8i1 : PatFrag<(ops node:$ptr), (i8 (extloadi1 node:$ptr))>;
987 def extloadi16i1 : PatFrag<(ops node:$ptr), (i16 (extloadi1 node:$ptr))>;
988 def extloadi32i1 : PatFrag<(ops node:$ptr), (i32 (extloadi1 node:$ptr))>;
989 def extloadi16i8 : PatFrag<(ops node:$ptr), (i16 (extloadi8 node:$ptr))>;
990 def extloadi32i8 : PatFrag<(ops node:$ptr), (i32 (extloadi8 node:$ptr))>;
991 def extloadi32i16 : PatFrag<(ops node:$ptr), (i32 (extloadi16 node:$ptr))>;
992 def extloadi64i1 : PatFrag<(ops node:$ptr), (i64 (extloadi1 node:$ptr))>;
993 def extloadi64i8 : PatFrag<(ops node:$ptr), (i64 (extloadi8 node:$ptr))>;
994 def extloadi64i16 : PatFrag<(ops node:$ptr), (i64 (extloadi16 node:$ptr))>;
995 def extloadi64i32 : PatFrag<(ops node:$ptr), (i64 (extloadi32 node:$ptr))>;
998 // An 'and' node with a single use.
999 def and_su : PatFrag<(ops node:$lhs, node:$rhs), (and node:$lhs, node:$rhs), [{
1000 return N->hasOneUse();
1002 // An 'srl' node with a single use.
1003 def srl_su : PatFrag<(ops node:$lhs, node:$rhs), (srl node:$lhs, node:$rhs), [{
1004 return N->hasOneUse();
1006 // An 'trunc' node with a single use.
1007 def trunc_su : PatFrag<(ops node:$src), (trunc node:$src), [{
1008 return N->hasOneUse();
1011 //===----------------------------------------------------------------------===//
1012 // Instruction list.
1016 let hasSideEffects = 0, SchedRW = [WriteZero] in {
1017 def NOOP : I<0x90, RawFrm, (outs), (ins), "nop", [], IIC_NOP>;
1018 def NOOPW : I<0x1f, MRMXm, (outs), (ins i16mem:$zero),
1019 "nop{w}\t$zero", [], IIC_NOP>, TB, OpSize16;
1020 def NOOPL : I<0x1f, MRMXm, (outs), (ins i32mem:$zero),
1021 "nop{l}\t$zero", [], IIC_NOP>, TB, OpSize32;
1025 // Constructing a stack frame.
1026 def ENTER : Ii16<0xC8, RawFrmImm8, (outs), (ins i16imm:$len, i8imm:$lvl),
1027 "enter\t$len, $lvl", [], IIC_ENTER>, Sched<[WriteMicrocoded]>;
1029 let SchedRW = [WriteALU] in {
1030 let Defs = [EBP, ESP], Uses = [EBP, ESP], mayLoad = 1, hasSideEffects=0 in
1031 def LEAVE : I<0xC9, RawFrm,
1032 (outs), (ins), "leave", [], IIC_LEAVE>,
1033 Requires<[Not64BitMode]>;
1035 let Defs = [RBP,RSP], Uses = [RBP,RSP], mayLoad = 1, hasSideEffects = 0 in
1036 def LEAVE64 : I<0xC9, RawFrm,
1037 (outs), (ins), "leave", [], IIC_LEAVE>,
1038 Requires<[In64BitMode]>;
1041 //===----------------------------------------------------------------------===//
1042 // Miscellaneous Instructions.
1045 let Defs = [ESP], Uses = [ESP], hasSideEffects=0 in {
1046 let mayLoad = 1, SchedRW = [WriteLoad] in {
1047 def POP16r : I<0x58, AddRegFrm, (outs GR16:$reg), (ins), "pop{w}\t$reg", [],
1048 IIC_POP_REG16>, OpSize16;
1049 def POP32r : I<0x58, AddRegFrm, (outs GR32:$reg), (ins), "pop{l}\t$reg", [],
1050 IIC_POP_REG>, OpSize32, Requires<[Not64BitMode]>;
1051 def POP16rmr: I<0x8F, MRM0r, (outs GR16:$reg), (ins), "pop{w}\t$reg", [],
1052 IIC_POP_REG>, OpSize16;
1053 def POP16rmm: I<0x8F, MRM0m, (outs), (ins i16mem:$dst), "pop{w}\t$dst", [],
1054 IIC_POP_MEM>, OpSize16;
1055 def POP32rmr: I<0x8F, MRM0r, (outs GR32:$reg), (ins), "pop{l}\t$reg", [],
1056 IIC_POP_REG>, OpSize32, Requires<[Not64BitMode]>;
1057 def POP32rmm: I<0x8F, MRM0m, (outs), (ins i32mem:$dst), "pop{l}\t$dst", [],
1058 IIC_POP_MEM>, OpSize32, Requires<[Not64BitMode]>;
1059 } // mayLoad, SchedRW
1061 let mayStore = 1, SchedRW = [WriteStore] in {
1062 def PUSH16r : I<0x50, AddRegFrm, (outs), (ins GR16:$reg), "push{w}\t$reg",[],
1063 IIC_PUSH_REG>, OpSize16;
1064 def PUSH32r : I<0x50, AddRegFrm, (outs), (ins GR32:$reg), "push{l}\t$reg",[],
1065 IIC_PUSH_REG>, OpSize32, Requires<[Not64BitMode]>;
1066 def PUSH16rmr: I<0xFF, MRM6r, (outs), (ins GR16:$reg), "push{w}\t$reg",[],
1067 IIC_PUSH_REG>, OpSize16;
1068 def PUSH32rmr: I<0xFF, MRM6r, (outs), (ins GR32:$reg), "push{l}\t$reg",[],
1069 IIC_PUSH_REG>, OpSize32, Requires<[Not64BitMode]>;
1071 def PUSH16i8 : Ii8<0x6a, RawFrm, (outs), (ins i16i8imm:$imm),
1072 "push{w}\t$imm", [], IIC_PUSH_IMM>, OpSize16;
1073 def PUSHi16 : Ii16<0x68, RawFrm, (outs), (ins i16imm:$imm),
1074 "push{w}\t$imm", [], IIC_PUSH_IMM>, OpSize16;
1076 def PUSH32i8 : Ii8<0x6a, RawFrm, (outs), (ins i32i8imm:$imm),
1077 "push{l}\t$imm", [], IIC_PUSH_IMM>, OpSize32,
1078 Requires<[Not64BitMode]>;
1079 def PUSHi32 : Ii32<0x68, RawFrm, (outs), (ins i32imm:$imm),
1080 "push{l}\t$imm", [], IIC_PUSH_IMM>, OpSize32,
1081 Requires<[Not64BitMode]>;
1082 } // mayStore, SchedRW
1084 let mayLoad = 1, mayStore = 1, SchedRW = [WriteRMW] in {
1085 def PUSH16rmm: I<0xFF, MRM6m, (outs), (ins i16mem:$src), "push{w}\t$src",[],
1086 IIC_PUSH_MEM>, OpSize16;
1087 def PUSH32rmm: I<0xFF, MRM6m, (outs), (ins i32mem:$src), "push{l}\t$src",[],
1088 IIC_PUSH_MEM>, OpSize32, Requires<[Not64BitMode]>;
1089 } // mayLoad, mayStore, SchedRW
1093 let mayLoad = 1, mayStore = 1, usesCustomInserter = 1,
1094 SchedRW = [WriteRMW], Defs = [ESP] in {
1095 let Uses = [ESP, EFLAGS] in
1096 def RDFLAGS32 : PseudoI<(outs GR32:$dst), (ins),
1097 [(set GR32:$dst, (int_x86_flags_read_u32))]>,
1098 Requires<[Not64BitMode]>;
1100 let Uses = [RSP, EFLAGS] in
1101 def RDFLAGS64 : PseudoI<(outs GR64:$dst), (ins),
1102 [(set GR64:$dst, (int_x86_flags_read_u64))]>,
1103 Requires<[In64BitMode]>;
1106 let mayLoad = 1, mayStore = 1, usesCustomInserter = 1,
1107 SchedRW = [WriteRMW] in {
1108 let Defs = [ESP, EFLAGS], Uses = [ESP] in
1109 def WRFLAGS32 : PseudoI<(outs), (ins GR32:$src),
1110 [(int_x86_flags_write_u32 GR32:$src)]>,
1111 Requires<[Not64BitMode]>;
1113 let Defs = [RSP, EFLAGS], Uses = [RSP] in
1114 def WRFLAGS64 : PseudoI<(outs), (ins GR64:$src),
1115 [(int_x86_flags_write_u64 GR64:$src)]>,
1116 Requires<[In64BitMode]>;
1119 let Defs = [ESP, EFLAGS], Uses = [ESP], mayLoad = 1, hasSideEffects=0,
1120 SchedRW = [WriteLoad] in {
1121 def POPF16 : I<0x9D, RawFrm, (outs), (ins), "popf{w}", [], IIC_POP_F>,
1123 def POPF32 : I<0x9D, RawFrm, (outs), (ins), "popf{l|d}", [], IIC_POP_FD>,
1124 OpSize32, Requires<[Not64BitMode]>;
1127 let Defs = [ESP], Uses = [ESP, EFLAGS], mayStore = 1, hasSideEffects=0,
1128 SchedRW = [WriteStore] in {
1129 def PUSHF16 : I<0x9C, RawFrm, (outs), (ins), "pushf{w}", [], IIC_PUSH_F>,
1131 def PUSHF32 : I<0x9C, RawFrm, (outs), (ins), "pushf{l|d}", [], IIC_PUSH_F>,
1132 OpSize32, Requires<[Not64BitMode]>;
1135 let Defs = [RSP], Uses = [RSP], hasSideEffects=0 in {
1136 let mayLoad = 1, SchedRW = [WriteLoad] in {
1137 def POP64r : I<0x58, AddRegFrm, (outs GR64:$reg), (ins), "pop{q}\t$reg", [],
1138 IIC_POP_REG>, OpSize32, Requires<[In64BitMode]>;
1139 def POP64rmr: I<0x8F, MRM0r, (outs GR64:$reg), (ins), "pop{q}\t$reg", [],
1140 IIC_POP_REG>, OpSize32, Requires<[In64BitMode]>;
1141 def POP64rmm: I<0x8F, MRM0m, (outs), (ins i64mem:$dst), "pop{q}\t$dst", [],
1142 IIC_POP_MEM>, OpSize32, Requires<[In64BitMode]>;
1143 } // mayLoad, SchedRW
1144 let mayStore = 1, SchedRW = [WriteStore] in {
1145 def PUSH64r : I<0x50, AddRegFrm, (outs), (ins GR64:$reg), "push{q}\t$reg", [],
1146 IIC_PUSH_REG>, OpSize32, Requires<[In64BitMode]>;
1147 def PUSH64rmr: I<0xFF, MRM6r, (outs), (ins GR64:$reg), "push{q}\t$reg", [],
1148 IIC_PUSH_REG>, OpSize32, Requires<[In64BitMode]>;
1149 } // mayStore, SchedRW
1150 let mayLoad = 1, mayStore = 1, SchedRW = [WriteRMW] in {
1151 def PUSH64rmm: I<0xFF, MRM6m, (outs), (ins i64mem:$src), "push{q}\t$src", [],
1152 IIC_PUSH_MEM>, OpSize32, Requires<[In64BitMode]>;
1153 } // mayLoad, mayStore, SchedRW
1156 let Defs = [RSP], Uses = [RSP], hasSideEffects = 0, mayStore = 1,
1157 SchedRW = [WriteStore] in {
1158 def PUSH64i8 : Ii8<0x6a, RawFrm, (outs), (ins i64i8imm:$imm),
1159 "push{q}\t$imm", [], IIC_PUSH_IMM>, OpSize32,
1160 Requires<[In64BitMode]>;
1161 def PUSH64i32 : Ii32S<0x68, RawFrm, (outs), (ins i64i32imm:$imm),
1162 "push{q}\t$imm", [], IIC_PUSH_IMM>, OpSize32,
1163 Requires<[In64BitMode]>;
1166 let Defs = [RSP, EFLAGS], Uses = [RSP], mayLoad = 1, hasSideEffects=0 in
1167 def POPF64 : I<0x9D, RawFrm, (outs), (ins), "popfq", [], IIC_POP_FD>,
1168 OpSize32, Requires<[In64BitMode]>, Sched<[WriteLoad]>;
1169 let Defs = [RSP], Uses = [RSP, EFLAGS], mayStore = 1, hasSideEffects=0 in
1170 def PUSHF64 : I<0x9C, RawFrm, (outs), (ins), "pushfq", [], IIC_PUSH_F>,
1171 OpSize32, Requires<[In64BitMode]>, Sched<[WriteStore]>;
1173 let Defs = [EDI, ESI, EBP, EBX, EDX, ECX, EAX, ESP], Uses = [ESP],
1174 mayLoad = 1, hasSideEffects = 0, SchedRW = [WriteLoad] in {
1175 def POPA32 : I<0x61, RawFrm, (outs), (ins), "popal", [], IIC_POP_A>,
1176 OpSize32, Requires<[Not64BitMode]>;
1177 def POPA16 : I<0x61, RawFrm, (outs), (ins), "popaw", [], IIC_POP_A>,
1178 OpSize16, Requires<[Not64BitMode]>;
1180 let Defs = [ESP], Uses = [EDI, ESI, EBP, EBX, EDX, ECX, EAX, ESP],
1181 mayStore = 1, hasSideEffects = 0, SchedRW = [WriteStore] in {
1182 def PUSHA32 : I<0x60, RawFrm, (outs), (ins), "pushal", [], IIC_PUSH_A>,
1183 OpSize32, Requires<[Not64BitMode]>;
1184 def PUSHA16 : I<0x60, RawFrm, (outs), (ins), "pushaw", [], IIC_PUSH_A>,
1185 OpSize16, Requires<[Not64BitMode]>;
1188 let Constraints = "$src = $dst", SchedRW = [WriteALU] in {
1189 // GR32 = bswap GR32
1190 def BSWAP32r : I<0xC8, AddRegFrm,
1191 (outs GR32:$dst), (ins GR32:$src),
1193 [(set GR32:$dst, (bswap GR32:$src))], IIC_BSWAP>, OpSize32, TB;
1195 def BSWAP64r : RI<0xC8, AddRegFrm, (outs GR64:$dst), (ins GR64:$src),
1197 [(set GR64:$dst, (bswap GR64:$src))], IIC_BSWAP>, TB;
1198 } // Constraints = "$src = $dst", SchedRW
1200 // Bit scan instructions.
1201 let Defs = [EFLAGS] in {
1202 def BSF16rr : I<0xBC, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
1203 "bsf{w}\t{$src, $dst|$dst, $src}",
1204 [(set GR16:$dst, EFLAGS, (X86bsf GR16:$src))],
1205 IIC_BIT_SCAN_REG>, PS, OpSize16, Sched<[WriteShift]>;
1206 def BSF16rm : I<0xBC, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
1207 "bsf{w}\t{$src, $dst|$dst, $src}",
1208 [(set GR16:$dst, EFLAGS, (X86bsf (loadi16 addr:$src)))],
1209 IIC_BIT_SCAN_MEM>, PS, OpSize16, Sched<[WriteShiftLd]>;
1210 def BSF32rr : I<0xBC, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
1211 "bsf{l}\t{$src, $dst|$dst, $src}",
1212 [(set GR32:$dst, EFLAGS, (X86bsf GR32:$src))],
1213 IIC_BIT_SCAN_REG>, PS, OpSize32, Sched<[WriteShift]>;
1214 def BSF32rm : I<0xBC, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
1215 "bsf{l}\t{$src, $dst|$dst, $src}",
1216 [(set GR32:$dst, EFLAGS, (X86bsf (loadi32 addr:$src)))],
1217 IIC_BIT_SCAN_MEM>, PS, OpSize32, Sched<[WriteShiftLd]>;
1218 def BSF64rr : RI<0xBC, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
1219 "bsf{q}\t{$src, $dst|$dst, $src}",
1220 [(set GR64:$dst, EFLAGS, (X86bsf GR64:$src))],
1221 IIC_BIT_SCAN_REG>, PS, Sched<[WriteShift]>;
1222 def BSF64rm : RI<0xBC, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
1223 "bsf{q}\t{$src, $dst|$dst, $src}",
1224 [(set GR64:$dst, EFLAGS, (X86bsf (loadi64 addr:$src)))],
1225 IIC_BIT_SCAN_MEM>, PS, Sched<[WriteShiftLd]>;
1227 def BSR16rr : I<0xBD, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
1228 "bsr{w}\t{$src, $dst|$dst, $src}",
1229 [(set GR16:$dst, EFLAGS, (X86bsr GR16:$src))],
1230 IIC_BIT_SCAN_REG>, PS, OpSize16, Sched<[WriteShift]>;
1231 def BSR16rm : I<0xBD, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
1232 "bsr{w}\t{$src, $dst|$dst, $src}",
1233 [(set GR16:$dst, EFLAGS, (X86bsr (loadi16 addr:$src)))],
1234 IIC_BIT_SCAN_MEM>, PS, OpSize16, Sched<[WriteShiftLd]>;
1235 def BSR32rr : I<0xBD, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
1236 "bsr{l}\t{$src, $dst|$dst, $src}",
1237 [(set GR32:$dst, EFLAGS, (X86bsr GR32:$src))],
1238 IIC_BIT_SCAN_REG>, PS, OpSize32, Sched<[WriteShift]>;
1239 def BSR32rm : I<0xBD, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
1240 "bsr{l}\t{$src, $dst|$dst, $src}",
1241 [(set GR32:$dst, EFLAGS, (X86bsr (loadi32 addr:$src)))],
1242 IIC_BIT_SCAN_MEM>, PS, OpSize32, Sched<[WriteShiftLd]>;
1243 def BSR64rr : RI<0xBD, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
1244 "bsr{q}\t{$src, $dst|$dst, $src}",
1245 [(set GR64:$dst, EFLAGS, (X86bsr GR64:$src))],
1246 IIC_BIT_SCAN_REG>, PS, Sched<[WriteShift]>;
1247 def BSR64rm : RI<0xBD, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
1248 "bsr{q}\t{$src, $dst|$dst, $src}",
1249 [(set GR64:$dst, EFLAGS, (X86bsr (loadi64 addr:$src)))],
1250 IIC_BIT_SCAN_MEM>, PS, Sched<[WriteShiftLd]>;
1251 } // Defs = [EFLAGS]
1253 let SchedRW = [WriteMicrocoded] in {
1254 // These uses the DF flag in the EFLAGS register to inc or dec EDI and ESI
1255 let Defs = [EDI,ESI], Uses = [EDI,ESI,EFLAGS] in {
1256 def MOVSB : I<0xA4, RawFrmDstSrc, (outs dstidx8:$dst), (ins srcidx8:$src),
1257 "movsb\t{$src, $dst|$dst, $src}", [], IIC_MOVS>;
1258 def MOVSW : I<0xA5, RawFrmDstSrc, (outs dstidx16:$dst), (ins srcidx16:$src),
1259 "movsw\t{$src, $dst|$dst, $src}", [], IIC_MOVS>, OpSize16;
1260 def MOVSL : I<0xA5, RawFrmDstSrc, (outs dstidx32:$dst), (ins srcidx32:$src),
1261 "movs{l|d}\t{$src, $dst|$dst, $src}", [], IIC_MOVS>, OpSize32;
1262 def MOVSQ : RI<0xA5, RawFrmDstSrc, (outs dstidx64:$dst), (ins srcidx64:$src),
1263 "movsq\t{$src, $dst|$dst, $src}", [], IIC_MOVS>;
1266 // These uses the DF flag in the EFLAGS register to inc or dec EDI and ESI
1267 let Defs = [EDI], Uses = [AL,EDI,EFLAGS] in
1268 def STOSB : I<0xAA, RawFrmDst, (outs dstidx8:$dst), (ins),
1269 "stosb\t{%al, $dst|$dst, al}", [], IIC_STOS>;
1270 let Defs = [EDI], Uses = [AX,EDI,EFLAGS] in
1271 def STOSW : I<0xAB, RawFrmDst, (outs dstidx16:$dst), (ins),
1272 "stosw\t{%ax, $dst|$dst, ax}", [], IIC_STOS>, OpSize16;
1273 let Defs = [EDI], Uses = [EAX,EDI,EFLAGS] in
1274 def STOSL : I<0xAB, RawFrmDst, (outs dstidx32:$dst), (ins),
1275 "stos{l|d}\t{%eax, $dst|$dst, eax}", [], IIC_STOS>, OpSize32;
1276 let Defs = [RDI], Uses = [RAX,RDI,EFLAGS] in
1277 def STOSQ : RI<0xAB, RawFrmDst, (outs dstidx64:$dst), (ins),
1278 "stosq\t{%rax, $dst|$dst, rax}", [], IIC_STOS>;
1280 // These uses the DF flag in the EFLAGS register to inc or dec EDI and ESI
1281 let Defs = [EDI,EFLAGS], Uses = [AL,EDI,EFLAGS] in
1282 def SCASB : I<0xAE, RawFrmDst, (outs), (ins dstidx8:$dst),
1283 "scasb\t{$dst, %al|al, $dst}", [], IIC_SCAS>;
1284 let Defs = [EDI,EFLAGS], Uses = [AX,EDI,EFLAGS] in
1285 def SCASW : I<0xAF, RawFrmDst, (outs), (ins dstidx16:$dst),
1286 "scasw\t{$dst, %ax|ax, $dst}", [], IIC_SCAS>, OpSize16;
1287 let Defs = [EDI,EFLAGS], Uses = [EAX,EDI,EFLAGS] in
1288 def SCASL : I<0xAF, RawFrmDst, (outs), (ins dstidx32:$dst),
1289 "scas{l|d}\t{$dst, %eax|eax, $dst}", [], IIC_SCAS>, OpSize32;
1290 let Defs = [EDI,EFLAGS], Uses = [RAX,EDI,EFLAGS] in
1291 def SCASQ : RI<0xAF, RawFrmDst, (outs), (ins dstidx64:$dst),
1292 "scasq\t{$dst, %rax|rax, $dst}", [], IIC_SCAS>;
1294 // These uses the DF flag in the EFLAGS register to inc or dec EDI and ESI
1295 let Defs = [EDI,ESI,EFLAGS], Uses = [EDI,ESI,EFLAGS] in {
1296 def CMPSB : I<0xA6, RawFrmDstSrc, (outs), (ins dstidx8:$dst, srcidx8:$src),
1297 "cmpsb\t{$dst, $src|$src, $dst}", [], IIC_CMPS>;
1298 def CMPSW : I<0xA7, RawFrmDstSrc, (outs), (ins dstidx16:$dst, srcidx16:$src),
1299 "cmpsw\t{$dst, $src|$src, $dst}", [], IIC_CMPS>, OpSize16;
1300 def CMPSL : I<0xA7, RawFrmDstSrc, (outs), (ins dstidx32:$dst, srcidx32:$src),
1301 "cmps{l|d}\t{$dst, $src|$src, $dst}", [], IIC_CMPS>, OpSize32;
1302 def CMPSQ : RI<0xA7, RawFrmDstSrc, (outs), (ins dstidx64:$dst, srcidx64:$src),
1303 "cmpsq\t{$dst, $src|$src, $dst}", [], IIC_CMPS>;
1307 //===----------------------------------------------------------------------===//
1308 // Move Instructions.
1310 let SchedRW = [WriteMove] in {
1311 let hasSideEffects = 0 in {
1312 def MOV8rr : I<0x88, MRMDestReg, (outs GR8 :$dst), (ins GR8 :$src),
1313 "mov{b}\t{$src, $dst|$dst, $src}", [], IIC_MOV>;
1314 def MOV16rr : I<0x89, MRMDestReg, (outs GR16:$dst), (ins GR16:$src),
1315 "mov{w}\t{$src, $dst|$dst, $src}", [], IIC_MOV>, OpSize16;
1316 def MOV32rr : I<0x89, MRMDestReg, (outs GR32:$dst), (ins GR32:$src),
1317 "mov{l}\t{$src, $dst|$dst, $src}", [], IIC_MOV>, OpSize32;
1318 def MOV64rr : RI<0x89, MRMDestReg, (outs GR64:$dst), (ins GR64:$src),
1319 "mov{q}\t{$src, $dst|$dst, $src}", [], IIC_MOV>;
1322 let isReMaterializable = 1, isAsCheapAsAMove = 1 in {
1323 def MOV8ri : Ii8 <0xB0, AddRegFrm, (outs GR8 :$dst), (ins i8imm :$src),
1324 "mov{b}\t{$src, $dst|$dst, $src}",
1325 [(set GR8:$dst, imm:$src)], IIC_MOV>;
1326 def MOV16ri : Ii16<0xB8, AddRegFrm, (outs GR16:$dst), (ins i16imm:$src),
1327 "mov{w}\t{$src, $dst|$dst, $src}",
1328 [(set GR16:$dst, imm:$src)], IIC_MOV>, OpSize16;
1329 def MOV32ri : Ii32<0xB8, AddRegFrm, (outs GR32:$dst), (ins i32imm:$src),
1330 "mov{l}\t{$src, $dst|$dst, $src}",
1331 [(set GR32:$dst, imm:$src)], IIC_MOV>, OpSize32;
1332 def MOV64ri32 : RIi32S<0xC7, MRM0r, (outs GR64:$dst), (ins i64i32imm:$src),
1333 "mov{q}\t{$src, $dst|$dst, $src}",
1334 [(set GR64:$dst, i64immSExt32:$src)], IIC_MOV>;
1336 let isReMaterializable = 1 in {
1337 def MOV64ri : RIi64<0xB8, AddRegFrm, (outs GR64:$dst), (ins i64imm:$src),
1338 "movabs{q}\t{$src, $dst|$dst, $src}",
1339 [(set GR64:$dst, imm:$src)], IIC_MOV>;
1342 // Longer forms that use a ModR/M byte. Needed for disassembler
1343 let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0 in {
1344 def MOV8ri_alt : Ii8 <0xC6, MRM0r, (outs GR8 :$dst), (ins i8imm :$src),
1345 "mov{b}\t{$src, $dst|$dst, $src}", [], IIC_MOV>;
1346 def MOV16ri_alt : Ii16<0xC7, MRM0r, (outs GR16:$dst), (ins i16imm:$src),
1347 "mov{w}\t{$src, $dst|$dst, $src}", [], IIC_MOV>, OpSize16;
1348 def MOV32ri_alt : Ii32<0xC7, MRM0r, (outs GR32:$dst), (ins i32imm:$src),
1349 "mov{l}\t{$src, $dst|$dst, $src}", [], IIC_MOV>, OpSize32;
1353 let SchedRW = [WriteStore] in {
1354 def MOV8mi : Ii8 <0xC6, MRM0m, (outs), (ins i8mem :$dst, i8imm :$src),
1355 "mov{b}\t{$src, $dst|$dst, $src}",
1356 [(store (i8 imm8_su:$src), addr:$dst)], IIC_MOV_MEM>;
1357 def MOV16mi : Ii16<0xC7, MRM0m, (outs), (ins i16mem:$dst, i16imm:$src),
1358 "mov{w}\t{$src, $dst|$dst, $src}",
1359 [(store (i16 imm16_su:$src), addr:$dst)], IIC_MOV_MEM>, OpSize16;
1360 def MOV32mi : Ii32<0xC7, MRM0m, (outs), (ins i32mem:$dst, i32imm:$src),
1361 "mov{l}\t{$src, $dst|$dst, $src}",
1362 [(store (i32 imm32_su:$src), addr:$dst)], IIC_MOV_MEM>, OpSize32;
1363 def MOV64mi32 : RIi32S<0xC7, MRM0m, (outs), (ins i64mem:$dst, i64i32imm:$src),
1364 "mov{q}\t{$src, $dst|$dst, $src}",
1365 [(store i64immSExt32:$src, addr:$dst)], IIC_MOV_MEM>;
1368 let hasSideEffects = 0 in {
1370 /// Memory offset versions of moves. The immediate is an address mode sized
1371 /// offset from the segment base.
1372 let SchedRW = [WriteALU] in {
1373 let mayLoad = 1 in {
1375 def MOV8ao32 : Ii32<0xA0, RawFrmMemOffs, (outs), (ins offset32_8:$src),
1376 "mov{b}\t{$src, %al|al, $src}", [], IIC_MOV_MEM>,
1379 def MOV16ao32 : Ii32<0xA1, RawFrmMemOffs, (outs), (ins offset32_16:$src),
1380 "mov{w}\t{$src, %ax|ax, $src}", [], IIC_MOV_MEM>,
1383 def MOV32ao32 : Ii32<0xA1, RawFrmMemOffs, (outs), (ins offset32_32:$src),
1384 "mov{l}\t{$src, %eax|eax, $src}", [], IIC_MOV_MEM>,
1387 def MOV64ao32 : RIi32<0xA1, RawFrmMemOffs, (outs), (ins offset32_64:$src),
1388 "mov{q}\t{$src, %rax|rax, $src}", [], IIC_MOV_MEM>,
1392 def MOV8ao16 : Ii16<0xA0, RawFrmMemOffs, (outs), (ins offset16_8:$src),
1393 "mov{b}\t{$src, %al|al, $src}", [], IIC_MOV_MEM>, AdSize16;
1395 def MOV16ao16 : Ii16<0xA1, RawFrmMemOffs, (outs), (ins offset16_16:$src),
1396 "mov{w}\t{$src, %ax|ax, $src}", [], IIC_MOV_MEM>,
1399 def MOV32ao16 : Ii16<0xA1, RawFrmMemOffs, (outs), (ins offset16_32:$src),
1400 "mov{l}\t{$src, %eax|eax, $src}", [], IIC_MOV_MEM>,
1403 let mayStore = 1 in {
1405 def MOV8o32a : Ii32<0xA2, RawFrmMemOffs, (outs offset32_8:$dst), (ins),
1406 "mov{b}\t{%al, $dst|$dst, al}", [], IIC_MOV_MEM>, AdSize32;
1408 def MOV16o32a : Ii32<0xA3, RawFrmMemOffs, (outs offset32_16:$dst), (ins),
1409 "mov{w}\t{%ax, $dst|$dst, ax}", [], IIC_MOV_MEM>,
1412 def MOV32o32a : Ii32<0xA3, RawFrmMemOffs, (outs offset32_32:$dst), (ins),
1413 "mov{l}\t{%eax, $dst|$dst, eax}", [], IIC_MOV_MEM>,
1416 def MOV64o32a : RIi32<0xA3, RawFrmMemOffs, (outs offset32_64:$dst), (ins),
1417 "mov{q}\t{%rax, $dst|$dst, rax}", [], IIC_MOV_MEM>,
1421 def MOV8o16a : Ii16<0xA2, RawFrmMemOffs, (outs offset16_8:$dst), (ins),
1422 "mov{b}\t{%al, $dst|$dst, al}", [], IIC_MOV_MEM>, AdSize16;
1424 def MOV16o16a : Ii16<0xA3, RawFrmMemOffs, (outs offset16_16:$dst), (ins),
1425 "mov{w}\t{%ax, $dst|$dst, ax}", [], IIC_MOV_MEM>,
1428 def MOV32o16a : Ii16<0xA3, RawFrmMemOffs, (outs offset16_32:$dst), (ins),
1429 "mov{l}\t{%eax, $dst|$dst, eax}", [], IIC_MOV_MEM>,
1434 // These forms all have full 64-bit absolute addresses in their instructions
1435 // and use the movabs mnemonic to indicate this specific form.
1436 let mayLoad = 1 in {
1438 def MOV8ao64 : RIi64_NOREX<0xA0, RawFrmMemOffs, (outs), (ins offset64_8:$src),
1439 "movabs{b}\t{$src, %al|al, $src}", []>, AdSize64;
1441 def MOV16ao64 : RIi64_NOREX<0xA1, RawFrmMemOffs, (outs), (ins offset64_16:$src),
1442 "movabs{w}\t{$src, %ax|ax, $src}", []>, OpSize16, AdSize64;
1444 def MOV32ao64 : RIi64_NOREX<0xA1, RawFrmMemOffs, (outs), (ins offset64_32:$src),
1445 "movabs{l}\t{$src, %eax|eax, $src}", []>, OpSize32,
1448 def MOV64ao64 : RIi64<0xA1, RawFrmMemOffs, (outs), (ins offset64_64:$src),
1449 "movabs{q}\t{$src, %rax|rax, $src}", []>, AdSize64;
1452 let mayStore = 1 in {
1454 def MOV8o64a : RIi64_NOREX<0xA2, RawFrmMemOffs, (outs offset64_8:$dst), (ins),
1455 "movabs{b}\t{%al, $dst|$dst, al}", []>, AdSize64;
1457 def MOV16o64a : RIi64_NOREX<0xA3, RawFrmMemOffs, (outs offset64_16:$dst), (ins),
1458 "movabs{w}\t{%ax, $dst|$dst, ax}", []>, OpSize16, AdSize64;
1460 def MOV32o64a : RIi64_NOREX<0xA3, RawFrmMemOffs, (outs offset64_32:$dst), (ins),
1461 "movabs{l}\t{%eax, $dst|$dst, eax}", []>, OpSize32,
1464 def MOV64o64a : RIi64<0xA3, RawFrmMemOffs, (outs offset64_64:$dst), (ins),
1465 "movabs{q}\t{%rax, $dst|$dst, rax}", []>, AdSize64;
1467 } // hasSideEffects = 0
1469 let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0,
1470 SchedRW = [WriteMove] in {
1471 def MOV8rr_REV : I<0x8A, MRMSrcReg, (outs GR8:$dst), (ins GR8:$src),
1472 "mov{b}\t{$src, $dst|$dst, $src}", [], IIC_MOV>;
1473 def MOV16rr_REV : I<0x8B, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
1474 "mov{w}\t{$src, $dst|$dst, $src}", [], IIC_MOV>, OpSize16;
1475 def MOV32rr_REV : I<0x8B, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
1476 "mov{l}\t{$src, $dst|$dst, $src}", [], IIC_MOV>, OpSize32;
1477 def MOV64rr_REV : RI<0x8B, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
1478 "mov{q}\t{$src, $dst|$dst, $src}", [], IIC_MOV>;
1481 let canFoldAsLoad = 1, isReMaterializable = 1, SchedRW = [WriteLoad] in {
1482 def MOV8rm : I<0x8A, MRMSrcMem, (outs GR8 :$dst), (ins i8mem :$src),
1483 "mov{b}\t{$src, $dst|$dst, $src}",
1484 [(set GR8:$dst, (loadi8 addr:$src))], IIC_MOV_MEM>;
1485 def MOV16rm : I<0x8B, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
1486 "mov{w}\t{$src, $dst|$dst, $src}",
1487 [(set GR16:$dst, (loadi16 addr:$src))], IIC_MOV_MEM>, OpSize16;
1488 def MOV32rm : I<0x8B, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
1489 "mov{l}\t{$src, $dst|$dst, $src}",
1490 [(set GR32:$dst, (loadi32 addr:$src))], IIC_MOV_MEM>, OpSize32;
1491 def MOV64rm : RI<0x8B, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
1492 "mov{q}\t{$src, $dst|$dst, $src}",
1493 [(set GR64:$dst, (load addr:$src))], IIC_MOV_MEM>;
1496 let SchedRW = [WriteStore] in {
1497 def MOV8mr : I<0x88, MRMDestMem, (outs), (ins i8mem :$dst, GR8 :$src),
1498 "mov{b}\t{$src, $dst|$dst, $src}",
1499 [(store GR8:$src, addr:$dst)], IIC_MOV_MEM>;
1500 def MOV16mr : I<0x89, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src),
1501 "mov{w}\t{$src, $dst|$dst, $src}",
1502 [(store GR16:$src, addr:$dst)], IIC_MOV_MEM>, OpSize16;
1503 def MOV32mr : I<0x89, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
1504 "mov{l}\t{$src, $dst|$dst, $src}",
1505 [(store GR32:$src, addr:$dst)], IIC_MOV_MEM>, OpSize32;
1506 def MOV64mr : RI<0x89, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
1507 "mov{q}\t{$src, $dst|$dst, $src}",
1508 [(store GR64:$src, addr:$dst)], IIC_MOV_MEM>;
1511 // Versions of MOV8rr, MOV8mr, and MOV8rm that use i8mem_NOREX and GR8_NOREX so
1512 // that they can be used for copying and storing h registers, which can't be
1513 // encoded when a REX prefix is present.
1514 let isCodeGenOnly = 1 in {
1515 let hasSideEffects = 0 in
1516 def MOV8rr_NOREX : I<0x88, MRMDestReg,
1517 (outs GR8_NOREX:$dst), (ins GR8_NOREX:$src),
1518 "mov{b}\t{$src, $dst|$dst, $src} # NOREX", [], IIC_MOV>,
1520 let mayStore = 1, hasSideEffects = 0 in
1521 def MOV8mr_NOREX : I<0x88, MRMDestMem,
1522 (outs), (ins i8mem_NOREX:$dst, GR8_NOREX:$src),
1523 "mov{b}\t{$src, $dst|$dst, $src} # NOREX", [],
1524 IIC_MOV_MEM>, Sched<[WriteStore]>;
1525 let mayLoad = 1, hasSideEffects = 0,
1526 canFoldAsLoad = 1, isReMaterializable = 1 in
1527 def MOV8rm_NOREX : I<0x8A, MRMSrcMem,
1528 (outs GR8_NOREX:$dst), (ins i8mem_NOREX:$src),
1529 "mov{b}\t{$src, $dst|$dst, $src} # NOREX", [],
1530 IIC_MOV_MEM>, Sched<[WriteLoad]>;
1534 // Condition code ops, incl. set if equal/not equal/...
1535 let SchedRW = [WriteALU] in {
1536 let Defs = [EFLAGS], Uses = [AH] in
1537 def SAHF : I<0x9E, RawFrm, (outs), (ins), "sahf",
1538 [(set EFLAGS, (X86sahf AH))], IIC_AHF>,
1539 Requires<[HasLAHFSAHF]>;
1540 let Defs = [AH], Uses = [EFLAGS], hasSideEffects = 0 in
1541 def LAHF : I<0x9F, RawFrm, (outs), (ins), "lahf", [],
1542 IIC_AHF>, // AH = flags
1543 Requires<[HasLAHFSAHF]>;
1546 //===----------------------------------------------------------------------===//
1547 // Bit tests instructions: BT, BTS, BTR, BTC.
1549 let Defs = [EFLAGS] in {
1550 let SchedRW = [WriteALU] in {
1551 def BT16rr : I<0xA3, MRMDestReg, (outs), (ins GR16:$src1, GR16:$src2),
1552 "bt{w}\t{$src2, $src1|$src1, $src2}",
1553 [(set EFLAGS, (X86bt GR16:$src1, GR16:$src2))], IIC_BT_RR>,
1555 def BT32rr : I<0xA3, MRMDestReg, (outs), (ins GR32:$src1, GR32:$src2),
1556 "bt{l}\t{$src2, $src1|$src1, $src2}",
1557 [(set EFLAGS, (X86bt GR32:$src1, GR32:$src2))], IIC_BT_RR>,
1559 def BT64rr : RI<0xA3, MRMDestReg, (outs), (ins GR64:$src1, GR64:$src2),
1560 "bt{q}\t{$src2, $src1|$src1, $src2}",
1561 [(set EFLAGS, (X86bt GR64:$src1, GR64:$src2))], IIC_BT_RR>, TB;
1564 // Unlike with the register+register form, the memory+register form of the
1565 // bt instruction does not ignore the high bits of the index. From ISel's
1566 // perspective, this is pretty bizarre. Make these instructions disassembly
1569 let mayLoad = 1, hasSideEffects = 0, SchedRW = [WriteALULd] in {
1570 def BT16mr : I<0xA3, MRMDestMem, (outs), (ins i16mem:$src1, GR16:$src2),
1571 "bt{w}\t{$src2, $src1|$src1, $src2}",
1572 // [(X86bt (loadi16 addr:$src1), GR16:$src2),
1573 // (implicit EFLAGS)]
1575 >, OpSize16, TB, Requires<[FastBTMem]>;
1576 def BT32mr : I<0xA3, MRMDestMem, (outs), (ins i32mem:$src1, GR32:$src2),
1577 "bt{l}\t{$src2, $src1|$src1, $src2}",
1578 // [(X86bt (loadi32 addr:$src1), GR32:$src2),
1579 // (implicit EFLAGS)]
1581 >, OpSize32, TB, Requires<[FastBTMem]>;
1582 def BT64mr : RI<0xA3, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2),
1583 "bt{q}\t{$src2, $src1|$src1, $src2}",
1584 // [(X86bt (loadi64 addr:$src1), GR64:$src2),
1585 // (implicit EFLAGS)]
1590 let SchedRW = [WriteALU] in {
1591 def BT16ri8 : Ii8<0xBA, MRM4r, (outs), (ins GR16:$src1, i16i8imm:$src2),
1592 "bt{w}\t{$src2, $src1|$src1, $src2}",
1593 [(set EFLAGS, (X86bt GR16:$src1, i16immSExt8:$src2))],
1594 IIC_BT_RI>, OpSize16, TB;
1595 def BT32ri8 : Ii8<0xBA, MRM4r, (outs), (ins GR32:$src1, i32i8imm:$src2),
1596 "bt{l}\t{$src2, $src1|$src1, $src2}",
1597 [(set EFLAGS, (X86bt GR32:$src1, i32immSExt8:$src2))],
1598 IIC_BT_RI>, OpSize32, TB;
1599 def BT64ri8 : RIi8<0xBA, MRM4r, (outs), (ins GR64:$src1, i64i8imm:$src2),
1600 "bt{q}\t{$src2, $src1|$src1, $src2}",
1601 [(set EFLAGS, (X86bt GR64:$src1, i64immSExt8:$src2))],
1605 // Note that these instructions don't need FastBTMem because that
1606 // only applies when the other operand is in a register. When it's
1607 // an immediate, bt is still fast.
1608 let SchedRW = [WriteALU] in {
1609 def BT16mi8 : Ii8<0xBA, MRM4m, (outs), (ins i16mem:$src1, i16i8imm:$src2),
1610 "bt{w}\t{$src2, $src1|$src1, $src2}",
1611 [(set EFLAGS, (X86bt (loadi16 addr:$src1), i16immSExt8:$src2))
1612 ], IIC_BT_MI>, OpSize16, TB;
1613 def BT32mi8 : Ii8<0xBA, MRM4m, (outs), (ins i32mem:$src1, i32i8imm:$src2),
1614 "bt{l}\t{$src2, $src1|$src1, $src2}",
1615 [(set EFLAGS, (X86bt (loadi32 addr:$src1), i32immSExt8:$src2))
1616 ], IIC_BT_MI>, OpSize32, TB;
1617 def BT64mi8 : RIi8<0xBA, MRM4m, (outs), (ins i64mem:$src1, i64i8imm:$src2),
1618 "bt{q}\t{$src2, $src1|$src1, $src2}",
1619 [(set EFLAGS, (X86bt (loadi64 addr:$src1),
1620 i64immSExt8:$src2))], IIC_BT_MI>, TB;
1623 let hasSideEffects = 0 in {
1624 let SchedRW = [WriteALU] in {
1625 def BTC16rr : I<0xBB, MRMDestReg, (outs), (ins GR16:$src1, GR16:$src2),
1626 "btc{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>,
1628 def BTC32rr : I<0xBB, MRMDestReg, (outs), (ins GR32:$src1, GR32:$src2),
1629 "btc{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>,
1631 def BTC64rr : RI<0xBB, MRMDestReg, (outs), (ins GR64:$src1, GR64:$src2),
1632 "btc{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>, TB;
1635 let mayLoad = 1, mayStore = 1, SchedRW = [WriteALULd, WriteRMW] in {
1636 def BTC16mr : I<0xBB, MRMDestMem, (outs), (ins i16mem:$src1, GR16:$src2),
1637 "btc{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>,
1639 def BTC32mr : I<0xBB, MRMDestMem, (outs), (ins i32mem:$src1, GR32:$src2),
1640 "btc{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>,
1642 def BTC64mr : RI<0xBB, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2),
1643 "btc{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>, TB;
1646 let SchedRW = [WriteALU] in {
1647 def BTC16ri8 : Ii8<0xBA, MRM7r, (outs), (ins GR16:$src1, i16i8imm:$src2),
1648 "btc{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>,
1650 def BTC32ri8 : Ii8<0xBA, MRM7r, (outs), (ins GR32:$src1, i32i8imm:$src2),
1651 "btc{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>,
1653 def BTC64ri8 : RIi8<0xBA, MRM7r, (outs), (ins GR64:$src1, i64i8imm:$src2),
1654 "btc{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>, TB;
1657 let mayLoad = 1, mayStore = 1, SchedRW = [WriteALULd, WriteRMW] in {
1658 def BTC16mi8 : Ii8<0xBA, MRM7m, (outs), (ins i16mem:$src1, i16i8imm:$src2),
1659 "btc{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>,
1661 def BTC32mi8 : Ii8<0xBA, MRM7m, (outs), (ins i32mem:$src1, i32i8imm:$src2),
1662 "btc{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>,
1664 def BTC64mi8 : RIi8<0xBA, MRM7m, (outs), (ins i64mem:$src1, i64i8imm:$src2),
1665 "btc{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>, TB;
1668 let SchedRW = [WriteALU] in {
1669 def BTR16rr : I<0xB3, MRMDestReg, (outs), (ins GR16:$src1, GR16:$src2),
1670 "btr{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>,
1672 def BTR32rr : I<0xB3, MRMDestReg, (outs), (ins GR32:$src1, GR32:$src2),
1673 "btr{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>,
1675 def BTR64rr : RI<0xB3, MRMDestReg, (outs), (ins GR64:$src1, GR64:$src2),
1676 "btr{q}\t{$src2, $src1|$src1, $src2}", []>, TB;
1679 let mayLoad = 1, mayStore = 1, SchedRW = [WriteALULd, WriteRMW] in {
1680 def BTR16mr : I<0xB3, MRMDestMem, (outs), (ins i16mem:$src1, GR16:$src2),
1681 "btr{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>,
1683 def BTR32mr : I<0xB3, MRMDestMem, (outs), (ins i32mem:$src1, GR32:$src2),
1684 "btr{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>,
1686 def BTR64mr : RI<0xB3, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2),
1687 "btr{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>, TB;
1690 let SchedRW = [WriteALU] in {
1691 def BTR16ri8 : Ii8<0xBA, MRM6r, (outs), (ins GR16:$src1, i16i8imm:$src2),
1692 "btr{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>,
1694 def BTR32ri8 : Ii8<0xBA, MRM6r, (outs), (ins GR32:$src1, i32i8imm:$src2),
1695 "btr{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>,
1697 def BTR64ri8 : RIi8<0xBA, MRM6r, (outs), (ins GR64:$src1, i64i8imm:$src2),
1698 "btr{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>, TB;
1701 let mayLoad = 1, mayStore = 1, SchedRW = [WriteALULd, WriteRMW] in {
1702 def BTR16mi8 : Ii8<0xBA, MRM6m, (outs), (ins i16mem:$src1, i16i8imm:$src2),
1703 "btr{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>,
1705 def BTR32mi8 : Ii8<0xBA, MRM6m, (outs), (ins i32mem:$src1, i32i8imm:$src2),
1706 "btr{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>,
1708 def BTR64mi8 : RIi8<0xBA, MRM6m, (outs), (ins i64mem:$src1, i64i8imm:$src2),
1709 "btr{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>, TB;
1712 let SchedRW = [WriteALU] in {
1713 def BTS16rr : I<0xAB, MRMDestReg, (outs), (ins GR16:$src1, GR16:$src2),
1714 "bts{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>,
1716 def BTS32rr : I<0xAB, MRMDestReg, (outs), (ins GR32:$src1, GR32:$src2),
1717 "bts{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>,
1719 def BTS64rr : RI<0xAB, MRMDestReg, (outs), (ins GR64:$src1, GR64:$src2),
1720 "bts{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>, TB;
1723 let mayLoad = 1, mayStore = 1, SchedRW = [WriteALULd, WriteRMW] in {
1724 def BTS16mr : I<0xAB, MRMDestMem, (outs), (ins i16mem:$src1, GR16:$src2),
1725 "bts{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>,
1727 def BTS32mr : I<0xAB, MRMDestMem, (outs), (ins i32mem:$src1, GR32:$src2),
1728 "bts{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>,
1730 def BTS64mr : RI<0xAB, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2),
1731 "bts{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>, TB;
1734 let SchedRW = [WriteALU] in {
1735 def BTS16ri8 : Ii8<0xBA, MRM5r, (outs), (ins GR16:$src1, i16i8imm:$src2),
1736 "bts{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>,
1738 def BTS32ri8 : Ii8<0xBA, MRM5r, (outs), (ins GR32:$src1, i32i8imm:$src2),
1739 "bts{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>,
1741 def BTS64ri8 : RIi8<0xBA, MRM5r, (outs), (ins GR64:$src1, i64i8imm:$src2),
1742 "bts{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>, TB;
1745 let mayLoad = 1, mayStore = 1, SchedRW = [WriteALULd, WriteRMW] in {
1746 def BTS16mi8 : Ii8<0xBA, MRM5m, (outs), (ins i16mem:$src1, i16i8imm:$src2),
1747 "bts{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>,
1749 def BTS32mi8 : Ii8<0xBA, MRM5m, (outs), (ins i32mem:$src1, i32i8imm:$src2),
1750 "bts{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>,
1752 def BTS64mi8 : RIi8<0xBA, MRM5m, (outs), (ins i64mem:$src1, i64i8imm:$src2),
1753 "bts{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>, TB;
1755 } // hasSideEffects = 0
1756 } // Defs = [EFLAGS]
1759 //===----------------------------------------------------------------------===//
1763 // Atomic swap. These are just normal xchg instructions. But since a memory
1764 // operand is referenced, the atomicity is ensured.
1765 multiclass ATOMIC_SWAP<bits<8> opc8, bits<8> opc, string mnemonic, string frag,
1766 InstrItinClass itin> {
1767 let Constraints = "$val = $dst", SchedRW = [WriteALULd, WriteRMW] in {
1768 def NAME#8rm : I<opc8, MRMSrcMem, (outs GR8:$dst),
1769 (ins GR8:$val, i8mem:$ptr),
1770 !strconcat(mnemonic, "{b}\t{$val, $ptr|$ptr, $val}"),
1773 (!cast<PatFrag>(frag # "_8") addr:$ptr, GR8:$val))],
1775 def NAME#16rm : I<opc, MRMSrcMem, (outs GR16:$dst),
1776 (ins GR16:$val, i16mem:$ptr),
1777 !strconcat(mnemonic, "{w}\t{$val, $ptr|$ptr, $val}"),
1780 (!cast<PatFrag>(frag # "_16") addr:$ptr, GR16:$val))],
1782 def NAME#32rm : I<opc, MRMSrcMem, (outs GR32:$dst),
1783 (ins GR32:$val, i32mem:$ptr),
1784 !strconcat(mnemonic, "{l}\t{$val, $ptr|$ptr, $val}"),
1787 (!cast<PatFrag>(frag # "_32") addr:$ptr, GR32:$val))],
1789 def NAME#64rm : RI<opc, MRMSrcMem, (outs GR64:$dst),
1790 (ins GR64:$val, i64mem:$ptr),
1791 !strconcat(mnemonic, "{q}\t{$val, $ptr|$ptr, $val}"),
1794 (!cast<PatFrag>(frag # "_64") addr:$ptr, GR64:$val))],
1799 defm XCHG : ATOMIC_SWAP<0x86, 0x87, "xchg", "atomic_swap", IIC_XCHG_MEM>;
1801 // Swap between registers.
1802 let SchedRW = [WriteALU] in {
1803 let Constraints = "$val = $dst" in {
1804 def XCHG8rr : I<0x86, MRMSrcReg, (outs GR8:$dst), (ins GR8:$val, GR8:$src),
1805 "xchg{b}\t{$val, $src|$src, $val}", [], IIC_XCHG_REG>;
1806 def XCHG16rr : I<0x87, MRMSrcReg, (outs GR16:$dst), (ins GR16:$val, GR16:$src),
1807 "xchg{w}\t{$val, $src|$src, $val}", [], IIC_XCHG_REG>,
1809 def XCHG32rr : I<0x87, MRMSrcReg, (outs GR32:$dst), (ins GR32:$val, GR32:$src),
1810 "xchg{l}\t{$val, $src|$src, $val}", [], IIC_XCHG_REG>,
1812 def XCHG64rr : RI<0x87, MRMSrcReg, (outs GR64:$dst), (ins GR64:$val,GR64:$src),
1813 "xchg{q}\t{$val, $src|$src, $val}", [], IIC_XCHG_REG>;
1816 // Swap between EAX and other registers.
1817 let Uses = [AX], Defs = [AX] in
1818 def XCHG16ar : I<0x90, AddRegFrm, (outs), (ins GR16:$src),
1819 "xchg{w}\t{$src, %ax|ax, $src}", [], IIC_XCHG_REG>, OpSize16;
1820 let Uses = [EAX], Defs = [EAX] in
1821 def XCHG32ar : I<0x90, AddRegFrm, (outs), (ins GR32:$src),
1822 "xchg{l}\t{$src, %eax|eax, $src}", [], IIC_XCHG_REG>,
1823 OpSize32, Requires<[Not64BitMode]>;
1824 let Uses = [EAX], Defs = [EAX] in
1825 // Uses GR32_NOAX in 64-bit mode to prevent encoding using the 0x90 NOP encoding.
1826 // xchg %eax, %eax needs to clear upper 32-bits of RAX so is not a NOP.
1827 def XCHG32ar64 : I<0x90, AddRegFrm, (outs), (ins GR32_NOAX:$src),
1828 "xchg{l}\t{$src, %eax|eax, $src}", [], IIC_XCHG_REG>,
1829 OpSize32, Requires<[In64BitMode]>;
1830 let Uses = [RAX], Defs = [RAX] in
1831 def XCHG64ar : RI<0x90, AddRegFrm, (outs), (ins GR64:$src),
1832 "xchg{q}\t{$src, %rax|rax, $src}", [], IIC_XCHG_REG>;
1835 let SchedRW = [WriteALU] in {
1836 def XADD8rr : I<0xC0, MRMDestReg, (outs GR8:$dst), (ins GR8:$src),
1837 "xadd{b}\t{$src, $dst|$dst, $src}", [], IIC_XADD_REG>, TB;
1838 def XADD16rr : I<0xC1, MRMDestReg, (outs GR16:$dst), (ins GR16:$src),
1839 "xadd{w}\t{$src, $dst|$dst, $src}", [], IIC_XADD_REG>, TB,
1841 def XADD32rr : I<0xC1, MRMDestReg, (outs GR32:$dst), (ins GR32:$src),
1842 "xadd{l}\t{$src, $dst|$dst, $src}", [], IIC_XADD_REG>, TB,
1844 def XADD64rr : RI<0xC1, MRMDestReg, (outs GR64:$dst), (ins GR64:$src),
1845 "xadd{q}\t{$src, $dst|$dst, $src}", [], IIC_XADD_REG>, TB;
1848 let mayLoad = 1, mayStore = 1, SchedRW = [WriteALULd, WriteRMW] in {
1849 def XADD8rm : I<0xC0, MRMDestMem, (outs), (ins i8mem:$dst, GR8:$src),
1850 "xadd{b}\t{$src, $dst|$dst, $src}", [], IIC_XADD_MEM>, TB;
1851 def XADD16rm : I<0xC1, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src),
1852 "xadd{w}\t{$src, $dst|$dst, $src}", [], IIC_XADD_MEM>, TB,
1854 def XADD32rm : I<0xC1, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
1855 "xadd{l}\t{$src, $dst|$dst, $src}", [], IIC_XADD_MEM>, TB,
1857 def XADD64rm : RI<0xC1, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
1858 "xadd{q}\t{$src, $dst|$dst, $src}", [], IIC_XADD_MEM>, TB;
1862 let SchedRW = [WriteALU] in {
1863 def CMPXCHG8rr : I<0xB0, MRMDestReg, (outs GR8:$dst), (ins GR8:$src),
1864 "cmpxchg{b}\t{$src, $dst|$dst, $src}", [],
1865 IIC_CMPXCHG_REG8>, TB;
1866 def CMPXCHG16rr : I<0xB1, MRMDestReg, (outs GR16:$dst), (ins GR16:$src),
1867 "cmpxchg{w}\t{$src, $dst|$dst, $src}", [],
1868 IIC_CMPXCHG_REG>, TB, OpSize16;
1869 def CMPXCHG32rr : I<0xB1, MRMDestReg, (outs GR32:$dst), (ins GR32:$src),
1870 "cmpxchg{l}\t{$src, $dst|$dst, $src}", [],
1871 IIC_CMPXCHG_REG>, TB, OpSize32;
1872 def CMPXCHG64rr : RI<0xB1, MRMDestReg, (outs GR64:$dst), (ins GR64:$src),
1873 "cmpxchg{q}\t{$src, $dst|$dst, $src}", [],
1874 IIC_CMPXCHG_REG>, TB;
1877 let SchedRW = [WriteALULd, WriteRMW] in {
1878 let mayLoad = 1, mayStore = 1 in {
1879 def CMPXCHG8rm : I<0xB0, MRMDestMem, (outs), (ins i8mem:$dst, GR8:$src),
1880 "cmpxchg{b}\t{$src, $dst|$dst, $src}", [],
1881 IIC_CMPXCHG_MEM8>, TB;
1882 def CMPXCHG16rm : I<0xB1, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src),
1883 "cmpxchg{w}\t{$src, $dst|$dst, $src}", [],
1884 IIC_CMPXCHG_MEM>, TB, OpSize16;
1885 def CMPXCHG32rm : I<0xB1, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
1886 "cmpxchg{l}\t{$src, $dst|$dst, $src}", [],
1887 IIC_CMPXCHG_MEM>, TB, OpSize32;
1888 def CMPXCHG64rm : RI<0xB1, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
1889 "cmpxchg{q}\t{$src, $dst|$dst, $src}", [],
1890 IIC_CMPXCHG_MEM>, TB;
1893 let Defs = [EAX, EDX, EFLAGS], Uses = [EAX, EBX, ECX, EDX] in
1894 def CMPXCHG8B : I<0xC7, MRM1m, (outs), (ins i64mem:$dst),
1895 "cmpxchg8b\t$dst", [], IIC_CMPXCHG_8B>, TB;
1897 let Defs = [RAX, RDX, EFLAGS], Uses = [RAX, RBX, RCX, RDX] in
1898 def CMPXCHG16B : RI<0xC7, MRM1m, (outs), (ins i128mem:$dst),
1899 "cmpxchg16b\t$dst", [], IIC_CMPXCHG_16B>,
1900 TB, Requires<[HasCmpxchg16b]>;
1904 // Lock instruction prefix
1905 def LOCK_PREFIX : I<0xF0, RawFrm, (outs), (ins), "lock", []>;
1907 // Rex64 instruction prefix
1908 def REX64_PREFIX : I<0x48, RawFrm, (outs), (ins), "rex64", []>,
1909 Requires<[In64BitMode]>;
1911 // Data16 instruction prefix
1912 def DATA16_PREFIX : I<0x66, RawFrm, (outs), (ins), "data16", []>;
1914 // Repeat string operation instruction prefixes
1915 // These uses the DF flag in the EFLAGS register to inc or dec ECX
1916 let Defs = [ECX], Uses = [ECX,EFLAGS] in {
1917 // Repeat (used with INS, OUTS, MOVS, LODS and STOS)
1918 def REP_PREFIX : I<0xF3, RawFrm, (outs), (ins), "rep", []>;
1919 // Repeat while not equal (used with CMPS and SCAS)
1920 def REPNE_PREFIX : I<0xF2, RawFrm, (outs), (ins), "repne", []>;
1924 // String manipulation instructions
1925 let SchedRW = [WriteMicrocoded] in {
1926 // These uses the DF flag in the EFLAGS register to inc or dec EDI and ESI
1927 let Defs = [AL,ESI], Uses = [ESI,EFLAGS] in
1928 def LODSB : I<0xAC, RawFrmSrc, (outs), (ins srcidx8:$src),
1929 "lodsb\t{$src, %al|al, $src}", [], IIC_LODS>;
1930 let Defs = [AX,ESI], Uses = [ESI,EFLAGS] in
1931 def LODSW : I<0xAD, RawFrmSrc, (outs), (ins srcidx16:$src),
1932 "lodsw\t{$src, %ax|ax, $src}", [], IIC_LODS>, OpSize16;
1933 let Defs = [EAX,ESI], Uses = [ESI,EFLAGS] in
1934 def LODSL : I<0xAD, RawFrmSrc, (outs), (ins srcidx32:$src),
1935 "lods{l|d}\t{$src, %eax|eax, $src}", [], IIC_LODS>, OpSize32;
1936 let Defs = [RAX,ESI], Uses = [ESI,EFLAGS] in
1937 def LODSQ : RI<0xAD, RawFrmSrc, (outs), (ins srcidx64:$src),
1938 "lodsq\t{$src, %rax|rax, $src}", [], IIC_LODS>;
1941 let SchedRW = [WriteSystem] in {
1942 // These uses the DF flag in the EFLAGS register to inc or dec EDI and ESI
1943 let Defs = [ESI], Uses = [DX,ESI,EFLAGS] in {
1944 def OUTSB : I<0x6E, RawFrmSrc, (outs), (ins srcidx8:$src),
1945 "outsb\t{$src, %dx|dx, $src}", [], IIC_OUTS>;
1946 def OUTSW : I<0x6F, RawFrmSrc, (outs), (ins srcidx16:$src),
1947 "outsw\t{$src, %dx|dx, $src}", [], IIC_OUTS>, OpSize16;
1948 def OUTSL : I<0x6F, RawFrmSrc, (outs), (ins srcidx32:$src),
1949 "outs{l|d}\t{$src, %dx|dx, $src}", [], IIC_OUTS>, OpSize32;
1952 // These uses the DF flag in the EFLAGS register to inc or dec EDI and ESI
1953 let Defs = [EDI], Uses = [DX,EDI,EFLAGS] in {
1954 def INSB : I<0x6C, RawFrmDst, (outs dstidx8:$dst), (ins),
1955 "insb\t{%dx, $dst|$dst, dx}", [], IIC_INS>;
1956 def INSW : I<0x6D, RawFrmDst, (outs dstidx16:$dst), (ins),
1957 "insw\t{%dx, $dst|$dst, dx}", [], IIC_INS>, OpSize16;
1958 def INSL : I<0x6D, RawFrmDst, (outs dstidx32:$dst), (ins),
1959 "ins{l|d}\t{%dx, $dst|$dst, dx}", [], IIC_INS>, OpSize32;
1963 // Flag instructions
1964 let SchedRW = [WriteALU] in {
1965 def CLC : I<0xF8, RawFrm, (outs), (ins), "clc", [], IIC_CLC>;
1966 def STC : I<0xF9, RawFrm, (outs), (ins), "stc", [], IIC_STC>;
1967 def CLI : I<0xFA, RawFrm, (outs), (ins), "cli", [], IIC_CLI>;
1968 def STI : I<0xFB, RawFrm, (outs), (ins), "sti", [], IIC_STI>;
1969 def CLD : I<0xFC, RawFrm, (outs), (ins), "cld", [], IIC_CLD>;
1970 def STD : I<0xFD, RawFrm, (outs), (ins), "std", [], IIC_STD>;
1971 def CMC : I<0xF5, RawFrm, (outs), (ins), "cmc", [], IIC_CMC>;
1973 def CLTS : I<0x06, RawFrm, (outs), (ins), "clts", [], IIC_CLTS>, TB;
1976 // Table lookup instructions
1977 let Uses = [AL,EBX], Defs = [AL], hasSideEffects = 0, mayLoad = 1 in
1978 def XLAT : I<0xD7, RawFrm, (outs), (ins), "xlatb", [], IIC_XLAT>,
1981 let SchedRW = [WriteMicrocoded] in {
1982 // ASCII Adjust After Addition
1983 let Uses = [AL,EFLAGS], Defs = [AX,EFLAGS], hasSideEffects = 0 in
1984 def AAA : I<0x37, RawFrm, (outs), (ins), "aaa", [], IIC_AAA>,
1985 Requires<[Not64BitMode]>;
1987 // ASCII Adjust AX Before Division
1988 let Uses = [AX], Defs = [AX,EFLAGS], hasSideEffects = 0 in
1989 def AAD8i8 : Ii8<0xD5, RawFrm, (outs), (ins i8imm:$src),
1990 "aad\t$src", [], IIC_AAD>, Requires<[Not64BitMode]>;
1992 // ASCII Adjust AX After Multiply
1993 let Uses = [AL], Defs = [AX,EFLAGS], hasSideEffects = 0 in
1994 def AAM8i8 : Ii8<0xD4, RawFrm, (outs), (ins i8imm:$src),
1995 "aam\t$src", [], IIC_AAM>, Requires<[Not64BitMode]>;
1997 // ASCII Adjust AL After Subtraction - sets
1998 let Uses = [AL,EFLAGS], Defs = [AX,EFLAGS], hasSideEffects = 0 in
1999 def AAS : I<0x3F, RawFrm, (outs), (ins), "aas", [], IIC_AAS>,
2000 Requires<[Not64BitMode]>;
2002 // Decimal Adjust AL after Addition
2003 let Uses = [AL,EFLAGS], Defs = [AL,EFLAGS], hasSideEffects = 0 in
2004 def DAA : I<0x27, RawFrm, (outs), (ins), "daa", [], IIC_DAA>,
2005 Requires<[Not64BitMode]>;
2007 // Decimal Adjust AL after Subtraction
2008 let Uses = [AL,EFLAGS], Defs = [AL,EFLAGS], hasSideEffects = 0 in
2009 def DAS : I<0x2F, RawFrm, (outs), (ins), "das", [], IIC_DAS>,
2010 Requires<[Not64BitMode]>;
2013 let SchedRW = [WriteSystem] in {
2014 // Check Array Index Against Bounds
2015 def BOUNDS16rm : I<0x62, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
2016 "bound\t{$src, $dst|$dst, $src}", [], IIC_BOUND>, OpSize16,
2017 Requires<[Not64BitMode]>;
2018 def BOUNDS32rm : I<0x62, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
2019 "bound\t{$src, $dst|$dst, $src}", [], IIC_BOUND>, OpSize32,
2020 Requires<[Not64BitMode]>;
2022 // Adjust RPL Field of Segment Selector
2023 def ARPL16rr : I<0x63, MRMDestReg, (outs GR16:$dst), (ins GR16:$src),
2024 "arpl\t{$src, $dst|$dst, $src}", [], IIC_ARPL_REG>,
2025 Requires<[Not64BitMode]>;
2026 def ARPL16mr : I<0x63, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src),
2027 "arpl\t{$src, $dst|$dst, $src}", [], IIC_ARPL_MEM>,
2028 Requires<[Not64BitMode]>;
2031 //===----------------------------------------------------------------------===//
2032 // MOVBE Instructions
2034 let Predicates = [HasMOVBE] in {
2035 let SchedRW = [WriteALULd] in {
2036 def MOVBE16rm : I<0xF0, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
2037 "movbe{w}\t{$src, $dst|$dst, $src}",
2038 [(set GR16:$dst, (bswap (loadi16 addr:$src)))], IIC_MOVBE>,
2040 def MOVBE32rm : I<0xF0, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
2041 "movbe{l}\t{$src, $dst|$dst, $src}",
2042 [(set GR32:$dst, (bswap (loadi32 addr:$src)))], IIC_MOVBE>,
2044 def MOVBE64rm : RI<0xF0, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
2045 "movbe{q}\t{$src, $dst|$dst, $src}",
2046 [(set GR64:$dst, (bswap (loadi64 addr:$src)))], IIC_MOVBE>,
2049 let SchedRW = [WriteStore] in {
2050 def MOVBE16mr : I<0xF1, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src),
2051 "movbe{w}\t{$src, $dst|$dst, $src}",
2052 [(store (bswap GR16:$src), addr:$dst)], IIC_MOVBE>,
2054 def MOVBE32mr : I<0xF1, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
2055 "movbe{l}\t{$src, $dst|$dst, $src}",
2056 [(store (bswap GR32:$src), addr:$dst)], IIC_MOVBE>,
2058 def MOVBE64mr : RI<0xF1, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
2059 "movbe{q}\t{$src, $dst|$dst, $src}",
2060 [(store (bswap GR64:$src), addr:$dst)], IIC_MOVBE>,
2065 //===----------------------------------------------------------------------===//
2066 // RDRAND Instruction
2068 let Predicates = [HasRDRAND], Defs = [EFLAGS] in {
2069 def RDRAND16r : I<0xC7, MRM6r, (outs GR16:$dst), (ins),
2071 [(set GR16:$dst, EFLAGS, (X86rdrand))]>, OpSize16, TB;
2072 def RDRAND32r : I<0xC7, MRM6r, (outs GR32:$dst), (ins),
2074 [(set GR32:$dst, EFLAGS, (X86rdrand))]>, OpSize32, TB;
2075 def RDRAND64r : RI<0xC7, MRM6r, (outs GR64:$dst), (ins),
2077 [(set GR64:$dst, EFLAGS, (X86rdrand))]>, TB;
2080 //===----------------------------------------------------------------------===//
2081 // RDSEED Instruction
2083 let Predicates = [HasRDSEED], Defs = [EFLAGS] in {
2084 def RDSEED16r : I<0xC7, MRM7r, (outs GR16:$dst), (ins),
2086 [(set GR16:$dst, EFLAGS, (X86rdseed))]>, OpSize16, TB;
2087 def RDSEED32r : I<0xC7, MRM7r, (outs GR32:$dst), (ins),
2089 [(set GR32:$dst, EFLAGS, (X86rdseed))]>, OpSize32, TB;
2090 def RDSEED64r : RI<0xC7, MRM7r, (outs GR64:$dst), (ins),
2092 [(set GR64:$dst, EFLAGS, (X86rdseed))]>, TB;
2095 //===----------------------------------------------------------------------===//
2096 // LZCNT Instruction
2098 let Predicates = [HasLZCNT], Defs = [EFLAGS] in {
2099 def LZCNT16rr : I<0xBD, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
2100 "lzcnt{w}\t{$src, $dst|$dst, $src}",
2101 [(set GR16:$dst, (ctlz GR16:$src)), (implicit EFLAGS)]>, XS,
2103 def LZCNT16rm : I<0xBD, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
2104 "lzcnt{w}\t{$src, $dst|$dst, $src}",
2105 [(set GR16:$dst, (ctlz (loadi16 addr:$src))),
2106 (implicit EFLAGS)]>, XS, OpSize16;
2108 def LZCNT32rr : I<0xBD, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
2109 "lzcnt{l}\t{$src, $dst|$dst, $src}",
2110 [(set GR32:$dst, (ctlz GR32:$src)), (implicit EFLAGS)]>, XS,
2112 def LZCNT32rm : I<0xBD, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
2113 "lzcnt{l}\t{$src, $dst|$dst, $src}",
2114 [(set GR32:$dst, (ctlz (loadi32 addr:$src))),
2115 (implicit EFLAGS)]>, XS, OpSize32;
2117 def LZCNT64rr : RI<0xBD, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
2118 "lzcnt{q}\t{$src, $dst|$dst, $src}",
2119 [(set GR64:$dst, (ctlz GR64:$src)), (implicit EFLAGS)]>,
2121 def LZCNT64rm : RI<0xBD, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
2122 "lzcnt{q}\t{$src, $dst|$dst, $src}",
2123 [(set GR64:$dst, (ctlz (loadi64 addr:$src))),
2124 (implicit EFLAGS)]>, XS;
2127 let Predicates = [HasLZCNT] in {
2128 def : Pat<(X86cmov (ctlz GR16:$src), (i16 16), (X86_COND_E_OR_NE),
2129 (X86cmp GR16:$src, (i16 0))),
2130 (LZCNT16rr GR16:$src)>;
2131 def : Pat<(X86cmov (ctlz GR32:$src), (i32 32), (X86_COND_E_OR_NE),
2132 (X86cmp GR32:$src, (i32 0))),
2133 (LZCNT32rr GR32:$src)>;
2134 def : Pat<(X86cmov (ctlz GR64:$src), (i64 64), (X86_COND_E_OR_NE),
2135 (X86cmp GR64:$src, (i64 0))),
2136 (LZCNT64rr GR64:$src)>;
2137 def : Pat<(X86cmov (i16 16), (ctlz GR16:$src), (X86_COND_E_OR_NE),
2138 (X86cmp GR16:$src, (i16 0))),
2139 (LZCNT16rr GR16:$src)>;
2140 def : Pat<(X86cmov (i32 32), (ctlz GR32:$src), (X86_COND_E_OR_NE),
2141 (X86cmp GR32:$src, (i32 0))),
2142 (LZCNT32rr GR32:$src)>;
2143 def : Pat<(X86cmov (i64 64), (ctlz GR64:$src), (X86_COND_E_OR_NE),
2144 (X86cmp GR64:$src, (i64 0))),
2145 (LZCNT64rr GR64:$src)>;
2147 def : Pat<(X86cmov (ctlz (loadi16 addr:$src)), (i16 16), (X86_COND_E_OR_NE),
2148 (X86cmp (loadi16 addr:$src), (i16 0))),
2149 (LZCNT16rm addr:$src)>;
2150 def : Pat<(X86cmov (ctlz (loadi32 addr:$src)), (i32 32), (X86_COND_E_OR_NE),
2151 (X86cmp (loadi32 addr:$src), (i32 0))),
2152 (LZCNT32rm addr:$src)>;
2153 def : Pat<(X86cmov (ctlz (loadi64 addr:$src)), (i64 64), (X86_COND_E_OR_NE),
2154 (X86cmp (loadi64 addr:$src), (i64 0))),
2155 (LZCNT64rm addr:$src)>;
2156 def : Pat<(X86cmov (i16 16), (ctlz (loadi16 addr:$src)), (X86_COND_E_OR_NE),
2157 (X86cmp (loadi16 addr:$src), (i16 0))),
2158 (LZCNT16rm addr:$src)>;
2159 def : Pat<(X86cmov (i32 32), (ctlz (loadi32 addr:$src)), (X86_COND_E_OR_NE),
2160 (X86cmp (loadi32 addr:$src), (i32 0))),
2161 (LZCNT32rm addr:$src)>;
2162 def : Pat<(X86cmov (i64 64), (ctlz (loadi64 addr:$src)), (X86_COND_E_OR_NE),
2163 (X86cmp (loadi64 addr:$src), (i64 0))),
2164 (LZCNT64rm addr:$src)>;
2167 //===----------------------------------------------------------------------===//
2170 let Predicates = [HasBMI], Defs = [EFLAGS] in {
2171 def TZCNT16rr : I<0xBC, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
2172 "tzcnt{w}\t{$src, $dst|$dst, $src}",
2173 [(set GR16:$dst, (cttz GR16:$src)), (implicit EFLAGS)]>, XS,
2175 def TZCNT16rm : I<0xBC, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
2176 "tzcnt{w}\t{$src, $dst|$dst, $src}",
2177 [(set GR16:$dst, (cttz (loadi16 addr:$src))),
2178 (implicit EFLAGS)]>, XS, OpSize16;
2180 def TZCNT32rr : I<0xBC, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
2181 "tzcnt{l}\t{$src, $dst|$dst, $src}",
2182 [(set GR32:$dst, (cttz GR32:$src)), (implicit EFLAGS)]>, XS,
2184 def TZCNT32rm : I<0xBC, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
2185 "tzcnt{l}\t{$src, $dst|$dst, $src}",
2186 [(set GR32:$dst, (cttz (loadi32 addr:$src))),
2187 (implicit EFLAGS)]>, XS, OpSize32;
2189 def TZCNT64rr : RI<0xBC, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
2190 "tzcnt{q}\t{$src, $dst|$dst, $src}",
2191 [(set GR64:$dst, (cttz GR64:$src)), (implicit EFLAGS)]>,
2193 def TZCNT64rm : RI<0xBC, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
2194 "tzcnt{q}\t{$src, $dst|$dst, $src}",
2195 [(set GR64:$dst, (cttz (loadi64 addr:$src))),
2196 (implicit EFLAGS)]>, XS;
2199 multiclass bmi_bls<string mnemonic, Format RegMRM, Format MemMRM,
2200 RegisterClass RC, X86MemOperand x86memop> {
2201 let hasSideEffects = 0 in {
2202 def rr : I<0xF3, RegMRM, (outs RC:$dst), (ins RC:$src),
2203 !strconcat(mnemonic, "\t{$src, $dst|$dst, $src}"),
2206 def rm : I<0xF3, MemMRM, (outs RC:$dst), (ins x86memop:$src),
2207 !strconcat(mnemonic, "\t{$src, $dst|$dst, $src}"),
2212 let Predicates = [HasBMI], Defs = [EFLAGS] in {
2213 defm BLSR32 : bmi_bls<"blsr{l}", MRM1r, MRM1m, GR32, i32mem>;
2214 defm BLSR64 : bmi_bls<"blsr{q}", MRM1r, MRM1m, GR64, i64mem>, VEX_W;
2215 defm BLSMSK32 : bmi_bls<"blsmsk{l}", MRM2r, MRM2m, GR32, i32mem>;
2216 defm BLSMSK64 : bmi_bls<"blsmsk{q}", MRM2r, MRM2m, GR64, i64mem>, VEX_W;
2217 defm BLSI32 : bmi_bls<"blsi{l}", MRM3r, MRM3m, GR32, i32mem>;
2218 defm BLSI64 : bmi_bls<"blsi{q}", MRM3r, MRM3m, GR64, i64mem>, VEX_W;
2221 //===----------------------------------------------------------------------===//
2222 // Pattern fragments to auto generate BMI instructions.
2223 //===----------------------------------------------------------------------===//
2225 let Predicates = [HasBMI] in {
2226 // FIXME: patterns for the load versions are not implemented
2227 def : Pat<(and GR32:$src, (add GR32:$src, -1)),
2228 (BLSR32rr GR32:$src)>;
2229 def : Pat<(and GR64:$src, (add GR64:$src, -1)),
2230 (BLSR64rr GR64:$src)>;
2232 def : Pat<(xor GR32:$src, (add GR32:$src, -1)),
2233 (BLSMSK32rr GR32:$src)>;
2234 def : Pat<(xor GR64:$src, (add GR64:$src, -1)),
2235 (BLSMSK64rr GR64:$src)>;
2237 def : Pat<(and GR32:$src, (ineg GR32:$src)),
2238 (BLSI32rr GR32:$src)>;
2239 def : Pat<(and GR64:$src, (ineg GR64:$src)),
2240 (BLSI64rr GR64:$src)>;
2243 let Predicates = [HasBMI] in {
2244 def : Pat<(X86cmov (cttz GR16:$src), (i16 16), (X86_COND_E_OR_NE),
2245 (X86cmp GR16:$src, (i16 0))),
2246 (TZCNT16rr GR16:$src)>;
2247 def : Pat<(X86cmov (cttz GR32:$src), (i32 32), (X86_COND_E_OR_NE),
2248 (X86cmp GR32:$src, (i32 0))),
2249 (TZCNT32rr GR32:$src)>;
2250 def : Pat<(X86cmov (cttz GR64:$src), (i64 64), (X86_COND_E_OR_NE),
2251 (X86cmp GR64:$src, (i64 0))),
2252 (TZCNT64rr GR64:$src)>;
2253 def : Pat<(X86cmov (i16 16), (cttz GR16:$src), (X86_COND_E_OR_NE),
2254 (X86cmp GR16:$src, (i16 0))),
2255 (TZCNT16rr GR16:$src)>;
2256 def : Pat<(X86cmov (i32 32), (cttz GR32:$src), (X86_COND_E_OR_NE),
2257 (X86cmp GR32:$src, (i32 0))),
2258 (TZCNT32rr GR32:$src)>;
2259 def : Pat<(X86cmov (i64 64), (cttz GR64:$src), (X86_COND_E_OR_NE),
2260 (X86cmp GR64:$src, (i64 0))),
2261 (TZCNT64rr GR64:$src)>;
2263 def : Pat<(X86cmov (cttz (loadi16 addr:$src)), (i16 16), (X86_COND_E_OR_NE),
2264 (X86cmp (loadi16 addr:$src), (i16 0))),
2265 (TZCNT16rm addr:$src)>;
2266 def : Pat<(X86cmov (cttz (loadi32 addr:$src)), (i32 32), (X86_COND_E_OR_NE),
2267 (X86cmp (loadi32 addr:$src), (i32 0))),
2268 (TZCNT32rm addr:$src)>;
2269 def : Pat<(X86cmov (cttz (loadi64 addr:$src)), (i64 64), (X86_COND_E_OR_NE),
2270 (X86cmp (loadi64 addr:$src), (i64 0))),
2271 (TZCNT64rm addr:$src)>;
2272 def : Pat<(X86cmov (i16 16), (cttz (loadi16 addr:$src)), (X86_COND_E_OR_NE),
2273 (X86cmp (loadi16 addr:$src), (i16 0))),
2274 (TZCNT16rm addr:$src)>;
2275 def : Pat<(X86cmov (i32 32), (cttz (loadi32 addr:$src)), (X86_COND_E_OR_NE),
2276 (X86cmp (loadi32 addr:$src), (i32 0))),
2277 (TZCNT32rm addr:$src)>;
2278 def : Pat<(X86cmov (i64 64), (cttz (loadi64 addr:$src)), (X86_COND_E_OR_NE),
2279 (X86cmp (loadi64 addr:$src), (i64 0))),
2280 (TZCNT64rm addr:$src)>;
2284 multiclass bmi_bextr_bzhi<bits<8> opc, string mnemonic, RegisterClass RC,
2285 X86MemOperand x86memop, Intrinsic Int,
2287 def rr : I<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
2288 !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2289 [(set RC:$dst, (Int RC:$src1, RC:$src2)), (implicit EFLAGS)]>,
2291 def rm : I<opc, MRMSrcMem, (outs RC:$dst), (ins x86memop:$src1, RC:$src2),
2292 !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2293 [(set RC:$dst, (Int (ld_frag addr:$src1), RC:$src2)),
2294 (implicit EFLAGS)]>, T8PS, VEX_4VOp3;
2297 let Predicates = [HasBMI], Defs = [EFLAGS] in {
2298 defm BEXTR32 : bmi_bextr_bzhi<0xF7, "bextr{l}", GR32, i32mem,
2299 int_x86_bmi_bextr_32, loadi32>;
2300 defm BEXTR64 : bmi_bextr_bzhi<0xF7, "bextr{q}", GR64, i64mem,
2301 int_x86_bmi_bextr_64, loadi64>, VEX_W;
2304 let Predicates = [HasBMI2], Defs = [EFLAGS] in {
2305 defm BZHI32 : bmi_bextr_bzhi<0xF5, "bzhi{l}", GR32, i32mem,
2306 int_x86_bmi_bzhi_32, loadi32>;
2307 defm BZHI64 : bmi_bextr_bzhi<0xF5, "bzhi{q}", GR64, i64mem,
2308 int_x86_bmi_bzhi_64, loadi64>, VEX_W;
2312 def CountTrailingOnes : SDNodeXForm<imm, [{
2313 // Count the trailing ones in the immediate.
2314 return getI8Imm(countTrailingOnes(N->getZExtValue()), SDLoc(N));
2317 def BZHIMask : ImmLeaf<i64, [{
2318 return isMask_64(Imm) && (countTrailingOnes<uint64_t>(Imm) > 32);
2321 let Predicates = [HasBMI2] in {
2322 def : Pat<(and GR64:$src, BZHIMask:$mask),
2323 (BZHI64rr GR64:$src,
2324 (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
2325 (MOV8ri (CountTrailingOnes imm:$mask)), sub_8bit))>;
2327 def : Pat<(and GR32:$src, (add (shl 1, GR8:$lz), -1)),
2328 (BZHI32rr GR32:$src,
2329 (INSERT_SUBREG (i32 (IMPLICIT_DEF)), GR8:$lz, sub_8bit))>;
2331 def : Pat<(and (loadi32 addr:$src), (add (shl 1, GR8:$lz), -1)),
2332 (BZHI32rm addr:$src,
2333 (INSERT_SUBREG (i32 (IMPLICIT_DEF)), GR8:$lz, sub_8bit))>;
2335 def : Pat<(and GR64:$src, (add (shl 1, GR8:$lz), -1)),
2336 (BZHI64rr GR64:$src,
2337 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR8:$lz, sub_8bit))>;
2339 def : Pat<(and (loadi64 addr:$src), (add (shl 1, GR8:$lz), -1)),
2340 (BZHI64rm addr:$src,
2341 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR8:$lz, sub_8bit))>;
2344 let Predicates = [HasBMI] in {
2345 def : Pat<(X86bextr GR32:$src1, GR32:$src2),
2346 (BEXTR32rr GR32:$src1, GR32:$src2)>;
2347 def : Pat<(X86bextr (loadi32 addr:$src1), GR32:$src2),
2348 (BEXTR32rm addr:$src1, GR32:$src2)>;
2349 def : Pat<(X86bextr GR64:$src1, GR64:$src2),
2350 (BEXTR64rr GR64:$src1, GR64:$src2)>;
2351 def : Pat<(X86bextr (loadi64 addr:$src1), GR64:$src2),
2352 (BEXTR64rm addr:$src1, GR64:$src2)>;
2355 multiclass bmi_pdep_pext<string mnemonic, RegisterClass RC,
2356 X86MemOperand x86memop, Intrinsic Int,
2358 def rr : I<0xF5, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
2359 !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2360 [(set RC:$dst, (Int RC:$src1, RC:$src2))]>,
2362 def rm : I<0xF5, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
2363 !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2364 [(set RC:$dst, (Int RC:$src1, (ld_frag addr:$src2)))]>, VEX_4V;
2367 let Predicates = [HasBMI2] in {
2368 defm PDEP32 : bmi_pdep_pext<"pdep{l}", GR32, i32mem,
2369 int_x86_bmi_pdep_32, loadi32>, T8XD;
2370 defm PDEP64 : bmi_pdep_pext<"pdep{q}", GR64, i64mem,
2371 int_x86_bmi_pdep_64, loadi64>, T8XD, VEX_W;
2372 defm PEXT32 : bmi_pdep_pext<"pext{l}", GR32, i32mem,
2373 int_x86_bmi_pext_32, loadi32>, T8XS;
2374 defm PEXT64 : bmi_pdep_pext<"pext{q}", GR64, i64mem,
2375 int_x86_bmi_pext_64, loadi64>, T8XS, VEX_W;
2378 //===----------------------------------------------------------------------===//
2381 let Predicates = [HasTBM], Defs = [EFLAGS] in {
2383 multiclass tbm_ternary_imm_intr<bits<8> opc, RegisterClass RC, string OpcodeStr,
2384 X86MemOperand x86memop, PatFrag ld_frag,
2385 Intrinsic Int, Operand immtype,
2386 SDPatternOperator immoperator> {
2387 def ri : Ii32<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, immtype:$cntl),
2388 !strconcat(OpcodeStr,
2389 "\t{$cntl, $src1, $dst|$dst, $src1, $cntl}"),
2390 [(set RC:$dst, (Int RC:$src1, immoperator:$cntl))]>,
2392 def mi : Ii32<opc, MRMSrcMem, (outs RC:$dst),
2393 (ins x86memop:$src1, immtype:$cntl),
2394 !strconcat(OpcodeStr,
2395 "\t{$cntl, $src1, $dst|$dst, $src1, $cntl}"),
2396 [(set RC:$dst, (Int (ld_frag addr:$src1), immoperator:$cntl))]>,
2400 defm BEXTRI32 : tbm_ternary_imm_intr<0x10, GR32, "bextr", i32mem, loadi32,
2401 int_x86_tbm_bextri_u32, i32imm, imm>;
2402 let ImmT = Imm32S in
2403 defm BEXTRI64 : tbm_ternary_imm_intr<0x10, GR64, "bextr", i64mem, loadi64,
2404 int_x86_tbm_bextri_u64, i64i32imm,
2405 i64immSExt32>, VEX_W;
2407 multiclass tbm_binary_rm<bits<8> opc, Format FormReg, Format FormMem,
2408 RegisterClass RC, string OpcodeStr,
2409 X86MemOperand x86memop, PatFrag ld_frag> {
2410 let hasSideEffects = 0 in {
2411 def rr : I<opc, FormReg, (outs RC:$dst), (ins RC:$src),
2412 !strconcat(OpcodeStr,"\t{$src, $dst|$dst, $src}"),
2415 def rm : I<opc, FormMem, (outs RC:$dst), (ins x86memop:$src),
2416 !strconcat(OpcodeStr,"\t{$src, $dst|$dst, $src}"),
2421 multiclass tbm_binary_intr<bits<8> opc, string OpcodeStr,
2422 Format FormReg, Format FormMem> {
2423 defm NAME#32 : tbm_binary_rm<opc, FormReg, FormMem, GR32, OpcodeStr, i32mem,
2425 defm NAME#64 : tbm_binary_rm<opc, FormReg, FormMem, GR64, OpcodeStr, i64mem,
2429 defm BLCFILL : tbm_binary_intr<0x01, "blcfill", MRM1r, MRM1m>;
2430 defm BLCI : tbm_binary_intr<0x02, "blci", MRM6r, MRM6m>;
2431 defm BLCIC : tbm_binary_intr<0x01, "blcic", MRM5r, MRM5m>;
2432 defm BLCMSK : tbm_binary_intr<0x02, "blcmsk", MRM1r, MRM1m>;
2433 defm BLCS : tbm_binary_intr<0x01, "blcs", MRM3r, MRM3m>;
2434 defm BLSFILL : tbm_binary_intr<0x01, "blsfill", MRM2r, MRM2m>;
2435 defm BLSIC : tbm_binary_intr<0x01, "blsic", MRM6r, MRM6m>;
2436 defm T1MSKC : tbm_binary_intr<0x01, "t1mskc", MRM7r, MRM7m>;
2437 defm TZMSK : tbm_binary_intr<0x01, "tzmsk", MRM4r, MRM4m>;
2440 //===----------------------------------------------------------------------===//
2441 // MONITORX/MWAITX Instructions
2443 let SchedRW = [WriteSystem] in {
2444 let Uses = [EAX, ECX, EDX] in
2445 def MONITORXrrr : I<0x01, MRM_FA, (outs), (ins), "monitorx", [],
2446 IIC_SSE_MONITOR>, TB;
2447 let Uses = [ECX, EAX, EBX] in
2448 def MWAITXrr : I<0x01, MRM_FB, (outs), (ins), "mwaitx", [], IIC_SSE_MWAIT>,
2452 def : InstAlias<"mwaitx\t{%eax, %ecx, %ebx|ebx, ecx, eax}", (MWAITXrr)>, Requires<[Not64BitMode]>;
2453 def : InstAlias<"mwaitx\t{%rax, %rcx, %rbx|rbx, rcx, rax}", (MWAITXrr)>, Requires<[In64BitMode]>;
2455 def : InstAlias<"monitorx\t{%eax, %ecx, %edx|edx, ecx, eax}", (MONITORXrrr)>,
2456 Requires<[Not64BitMode]>;
2457 def : InstAlias<"monitorx\t{%rax, %rcx, %rdx|rdx, rcx, rax}", (MONITORXrrr)>,
2458 Requires<[In64BitMode]>;
2460 //===----------------------------------------------------------------------===//
2461 // CLZERO Instruction
2464 def CLZEROr : I<0x01, MRM_FC, (outs), (ins), "clzero", []>, TB;
2466 //===----------------------------------------------------------------------===//
2467 // Pattern fragments to auto generate TBM instructions.
2468 //===----------------------------------------------------------------------===//
2470 let Predicates = [HasTBM] in {
2471 def : Pat<(X86bextr GR32:$src1, (i32 imm:$src2)),
2472 (BEXTRI32ri GR32:$src1, imm:$src2)>;
2473 def : Pat<(X86bextr (loadi32 addr:$src1), (i32 imm:$src2)),
2474 (BEXTRI32mi addr:$src1, imm:$src2)>;
2475 def : Pat<(X86bextr GR64:$src1, i64immSExt32:$src2),
2476 (BEXTRI64ri GR64:$src1, i64immSExt32:$src2)>;
2477 def : Pat<(X86bextr (loadi64 addr:$src1), i64immSExt32:$src2),
2478 (BEXTRI64mi addr:$src1, i64immSExt32:$src2)>;
2480 // FIXME: patterns for the load versions are not implemented
2481 def : Pat<(and GR32:$src, (add GR32:$src, 1)),
2482 (BLCFILL32rr GR32:$src)>;
2483 def : Pat<(and GR64:$src, (add GR64:$src, 1)),
2484 (BLCFILL64rr GR64:$src)>;
2486 def : Pat<(or GR32:$src, (not (add GR32:$src, 1))),
2487 (BLCI32rr GR32:$src)>;
2488 def : Pat<(or GR64:$src, (not (add GR64:$src, 1))),
2489 (BLCI64rr GR64:$src)>;
2491 // Extra patterns because opt can optimize the above patterns to this.
2492 def : Pat<(or GR32:$src, (sub -2, GR32:$src)),
2493 (BLCI32rr GR32:$src)>;
2494 def : Pat<(or GR64:$src, (sub -2, GR64:$src)),
2495 (BLCI64rr GR64:$src)>;
2497 def : Pat<(and (not GR32:$src), (add GR32:$src, 1)),
2498 (BLCIC32rr GR32:$src)>;
2499 def : Pat<(and (not GR64:$src), (add GR64:$src, 1)),
2500 (BLCIC64rr GR64:$src)>;
2502 def : Pat<(xor GR32:$src, (add GR32:$src, 1)),
2503 (BLCMSK32rr GR32:$src)>;
2504 def : Pat<(xor GR64:$src, (add GR64:$src, 1)),
2505 (BLCMSK64rr GR64:$src)>;
2507 def : Pat<(or GR32:$src, (add GR32:$src, 1)),
2508 (BLCS32rr GR32:$src)>;
2509 def : Pat<(or GR64:$src, (add GR64:$src, 1)),
2510 (BLCS64rr GR64:$src)>;
2512 def : Pat<(or GR32:$src, (add GR32:$src, -1)),
2513 (BLSFILL32rr GR32:$src)>;
2514 def : Pat<(or GR64:$src, (add GR64:$src, -1)),
2515 (BLSFILL64rr GR64:$src)>;
2517 def : Pat<(or (not GR32:$src), (add GR32:$src, -1)),
2518 (BLSIC32rr GR32:$src)>;
2519 def : Pat<(or (not GR64:$src), (add GR64:$src, -1)),
2520 (BLSIC64rr GR64:$src)>;
2522 def : Pat<(or (not GR32:$src), (add GR32:$src, 1)),
2523 (T1MSKC32rr GR32:$src)>;
2524 def : Pat<(or (not GR64:$src), (add GR64:$src, 1)),
2525 (T1MSKC64rr GR64:$src)>;
2527 def : Pat<(and (not GR32:$src), (add GR32:$src, -1)),
2528 (TZMSK32rr GR32:$src)>;
2529 def : Pat<(and (not GR64:$src), (add GR64:$src, -1)),
2530 (TZMSK64rr GR64:$src)>;
2533 //===----------------------------------------------------------------------===//
2534 // Memory Instructions
2537 def CLFLUSHOPT : I<0xAE, MRM7m, (outs), (ins i8mem:$src),
2538 "clflushopt\t$src", []>, PD;
2539 def CLWB : I<0xAE, MRM6m, (outs), (ins i8mem:$src), "clwb\t$src", []>, PD;
2540 def PCOMMIT : I<0xAE, MRM_F8, (outs), (ins), "pcommit", []>, PD;
2543 //===----------------------------------------------------------------------===//
2545 //===----------------------------------------------------------------------===//
2547 include "X86InstrArithmetic.td"
2548 include "X86InstrCMovSetCC.td"
2549 include "X86InstrExtension.td"
2550 include "X86InstrControl.td"
2551 include "X86InstrShiftRotate.td"
2553 // X87 Floating Point Stack.
2554 include "X86InstrFPStack.td"
2556 // SIMD support (SSE, MMX and AVX)
2557 include "X86InstrFragmentsSIMD.td"
2559 // FMA - Fused Multiply-Add support (requires FMA)
2560 include "X86InstrFMA.td"
2563 include "X86InstrXOP.td"
2565 // SSE, MMX and 3DNow! vector support.
2566 include "X86InstrSSE.td"
2567 include "X86InstrAVX512.td"
2568 include "X86InstrMMX.td"
2569 include "X86Instr3DNow.td"
2572 include "X86InstrMPX.td"
2574 include "X86InstrVMX.td"
2575 include "X86InstrSVM.td"
2577 include "X86InstrTSX.td"
2578 include "X86InstrSGX.td"
2580 // System instructions.
2581 include "X86InstrSystem.td"
2583 // Compiler Pseudo Instructions and Pat Patterns
2584 include "X86InstrCompiler.td"
2586 //===----------------------------------------------------------------------===//
2587 // Assembler Mnemonic Aliases
2588 //===----------------------------------------------------------------------===//
2590 def : MnemonicAlias<"call", "callw", "att">, Requires<[In16BitMode]>;
2591 def : MnemonicAlias<"call", "calll", "att">, Requires<[In32BitMode]>;
2592 def : MnemonicAlias<"call", "callq", "att">, Requires<[In64BitMode]>;
2594 def : MnemonicAlias<"cbw", "cbtw", "att">;
2595 def : MnemonicAlias<"cwde", "cwtl", "att">;
2596 def : MnemonicAlias<"cwd", "cwtd", "att">;
2597 def : MnemonicAlias<"cdq", "cltd", "att">;
2598 def : MnemonicAlias<"cdqe", "cltq", "att">;
2599 def : MnemonicAlias<"cqo", "cqto", "att">;
2601 // In 64-bit mode lret maps to lretl; it is not ambiguous with lretq.
2602 def : MnemonicAlias<"lret", "lretw", "att">, Requires<[In16BitMode]>;
2603 def : MnemonicAlias<"lret", "lretl", "att">, Requires<[Not16BitMode]>;
2605 def : MnemonicAlias<"leavel", "leave", "att">, Requires<[Not64BitMode]>;
2606 def : MnemonicAlias<"leaveq", "leave", "att">, Requires<[In64BitMode]>;
2608 def : MnemonicAlias<"loopz", "loope">;
2609 def : MnemonicAlias<"loopnz", "loopne">;
2611 def : MnemonicAlias<"pop", "popw", "att">, Requires<[In16BitMode]>;
2612 def : MnemonicAlias<"pop", "popl", "att">, Requires<[In32BitMode]>;
2613 def : MnemonicAlias<"pop", "popq", "att">, Requires<[In64BitMode]>;
2614 def : MnemonicAlias<"popf", "popfw", "att">, Requires<[In16BitMode]>;
2615 def : MnemonicAlias<"popf", "popfl", "att">, Requires<[In32BitMode]>;
2616 def : MnemonicAlias<"popf", "popfq", "att">, Requires<[In64BitMode]>;
2617 def : MnemonicAlias<"popfd", "popfl", "att">;
2619 // FIXME: This is wrong for "push reg". "push %bx" should turn into pushw in
2620 // all modes. However: "push (addr)" and "push $42" should default to
2621 // pushl/pushq depending on the current mode. Similar for "pop %bx"
2622 def : MnemonicAlias<"push", "pushw", "att">, Requires<[In16BitMode]>;
2623 def : MnemonicAlias<"push", "pushl", "att">, Requires<[In32BitMode]>;
2624 def : MnemonicAlias<"push", "pushq", "att">, Requires<[In64BitMode]>;
2625 def : MnemonicAlias<"pushf", "pushfw", "att">, Requires<[In16BitMode]>;
2626 def : MnemonicAlias<"pushf", "pushfl", "att">, Requires<[In32BitMode]>;
2627 def : MnemonicAlias<"pushf", "pushfq", "att">, Requires<[In64BitMode]>;
2628 def : MnemonicAlias<"pushfd", "pushfl", "att">;
2630 def : MnemonicAlias<"popad", "popal", "intel">, Requires<[Not64BitMode]>;
2631 def : MnemonicAlias<"pushad", "pushal", "intel">, Requires<[Not64BitMode]>;
2632 def : MnemonicAlias<"popa", "popaw", "intel">, Requires<[In16BitMode]>;
2633 def : MnemonicAlias<"pusha", "pushaw", "intel">, Requires<[In16BitMode]>;
2634 def : MnemonicAlias<"popa", "popal", "intel">, Requires<[In32BitMode]>;
2635 def : MnemonicAlias<"pusha", "pushal", "intel">, Requires<[In32BitMode]>;
2637 def : MnemonicAlias<"popa", "popaw", "att">, Requires<[In16BitMode]>;
2638 def : MnemonicAlias<"pusha", "pushaw", "att">, Requires<[In16BitMode]>;
2639 def : MnemonicAlias<"popa", "popal", "att">, Requires<[In32BitMode]>;
2640 def : MnemonicAlias<"pusha", "pushal", "att">, Requires<[In32BitMode]>;
2642 def : MnemonicAlias<"repe", "rep">;
2643 def : MnemonicAlias<"repz", "rep">;
2644 def : MnemonicAlias<"repnz", "repne">;
2646 def : MnemonicAlias<"ret", "retw", "att">, Requires<[In16BitMode]>;
2647 def : MnemonicAlias<"ret", "retl", "att">, Requires<[In32BitMode]>;
2648 def : MnemonicAlias<"ret", "retq", "att">, Requires<[In64BitMode]>;
2650 def : MnemonicAlias<"sal", "shl", "intel">;
2651 def : MnemonicAlias<"salb", "shlb", "att">;
2652 def : MnemonicAlias<"salw", "shlw", "att">;
2653 def : MnemonicAlias<"sall", "shll", "att">;
2654 def : MnemonicAlias<"salq", "shlq", "att">;
2656 def : MnemonicAlias<"smovb", "movsb", "att">;
2657 def : MnemonicAlias<"smovw", "movsw", "att">;
2658 def : MnemonicAlias<"smovl", "movsl", "att">;
2659 def : MnemonicAlias<"smovq", "movsq", "att">;
2661 def : MnemonicAlias<"ud2a", "ud2", "att">;
2662 def : MnemonicAlias<"verrw", "verr", "att">;
2664 // System instruction aliases.
2665 def : MnemonicAlias<"iret", "iretw", "att">, Requires<[In16BitMode]>;
2666 def : MnemonicAlias<"iret", "iretl", "att">, Requires<[Not16BitMode]>;
2667 def : MnemonicAlias<"sysret", "sysretl", "att">;
2668 def : MnemonicAlias<"sysexit", "sysexitl", "att">;
2670 def : MnemonicAlias<"lgdt", "lgdtw", "att">, Requires<[In16BitMode]>;
2671 def : MnemonicAlias<"lgdt", "lgdtl", "att">, Requires<[In32BitMode]>;
2672 def : MnemonicAlias<"lgdt", "lgdtq", "att">, Requires<[In64BitMode]>;
2673 def : MnemonicAlias<"lidt", "lidtw", "att">, Requires<[In16BitMode]>;
2674 def : MnemonicAlias<"lidt", "lidtl", "att">, Requires<[In32BitMode]>;
2675 def : MnemonicAlias<"lidt", "lidtq", "att">, Requires<[In64BitMode]>;
2676 def : MnemonicAlias<"sgdt", "sgdtw", "att">, Requires<[In16BitMode]>;
2677 def : MnemonicAlias<"sgdt", "sgdtl", "att">, Requires<[In32BitMode]>;
2678 def : MnemonicAlias<"sgdt", "sgdtq", "att">, Requires<[In64BitMode]>;
2679 def : MnemonicAlias<"sidt", "sidtw", "att">, Requires<[In16BitMode]>;
2680 def : MnemonicAlias<"sidt", "sidtl", "att">, Requires<[In32BitMode]>;
2681 def : MnemonicAlias<"sidt", "sidtq", "att">, Requires<[In64BitMode]>;
2684 // Floating point stack aliases.
2685 def : MnemonicAlias<"fcmovz", "fcmove", "att">;
2686 def : MnemonicAlias<"fcmova", "fcmovnbe", "att">;
2687 def : MnemonicAlias<"fcmovnae", "fcmovb", "att">;
2688 def : MnemonicAlias<"fcmovna", "fcmovbe", "att">;
2689 def : MnemonicAlias<"fcmovae", "fcmovnb", "att">;
2690 def : MnemonicAlias<"fcomip", "fcompi">;
2691 def : MnemonicAlias<"fildq", "fildll", "att">;
2692 def : MnemonicAlias<"fistpq", "fistpll", "att">;
2693 def : MnemonicAlias<"fisttpq", "fisttpll", "att">;
2694 def : MnemonicAlias<"fldcww", "fldcw", "att">;
2695 def : MnemonicAlias<"fnstcww", "fnstcw", "att">;
2696 def : MnemonicAlias<"fnstsww", "fnstsw", "att">;
2697 def : MnemonicAlias<"fucomip", "fucompi">;
2698 def : MnemonicAlias<"fwait", "wait">;
2700 def : MnemonicAlias<"fxsaveq", "fxsave64", "att">;
2701 def : MnemonicAlias<"fxrstorq", "fxrstor64", "att">;
2702 def : MnemonicAlias<"xsaveq", "xsave64", "att">;
2703 def : MnemonicAlias<"xrstorq", "xrstor64", "att">;
2704 def : MnemonicAlias<"xsaveoptq", "xsaveopt64", "att">;
2705 def : MnemonicAlias<"xrstorsq", "xrstors64", "att">;
2706 def : MnemonicAlias<"xsavecq", "xsavec64", "att">;
2707 def : MnemonicAlias<"xsavesq", "xsaves64", "att">;
2709 class CondCodeAlias<string Prefix,string Suffix, string OldCond, string NewCond,
2711 : MnemonicAlias<!strconcat(Prefix, OldCond, Suffix),
2712 !strconcat(Prefix, NewCond, Suffix), VariantName>;
2714 /// IntegerCondCodeMnemonicAlias - This multiclass defines a bunch of
2715 /// MnemonicAlias's that canonicalize the condition code in a mnemonic, for
2716 /// example "setz" -> "sete".
2717 multiclass IntegerCondCodeMnemonicAlias<string Prefix, string Suffix,
2719 def C : CondCodeAlias<Prefix, Suffix, "c", "b", V>; // setc -> setb
2720 def Z : CondCodeAlias<Prefix, Suffix, "z" , "e", V>; // setz -> sete
2721 def NA : CondCodeAlias<Prefix, Suffix, "na", "be", V>; // setna -> setbe
2722 def NB : CondCodeAlias<Prefix, Suffix, "nb", "ae", V>; // setnb -> setae
2723 def NC : CondCodeAlias<Prefix, Suffix, "nc", "ae", V>; // setnc -> setae
2724 def NG : CondCodeAlias<Prefix, Suffix, "ng", "le", V>; // setng -> setle
2725 def NL : CondCodeAlias<Prefix, Suffix, "nl", "ge", V>; // setnl -> setge
2726 def NZ : CondCodeAlias<Prefix, Suffix, "nz", "ne", V>; // setnz -> setne
2727 def PE : CondCodeAlias<Prefix, Suffix, "pe", "p", V>; // setpe -> setp
2728 def PO : CondCodeAlias<Prefix, Suffix, "po", "np", V>; // setpo -> setnp
2730 def NAE : CondCodeAlias<Prefix, Suffix, "nae", "b", V>; // setnae -> setb
2731 def NBE : CondCodeAlias<Prefix, Suffix, "nbe", "a", V>; // setnbe -> seta
2732 def NGE : CondCodeAlias<Prefix, Suffix, "nge", "l", V>; // setnge -> setl
2733 def NLE : CondCodeAlias<Prefix, Suffix, "nle", "g", V>; // setnle -> setg
2736 // Aliases for set<CC>
2737 defm : IntegerCondCodeMnemonicAlias<"set", "">;
2738 // Aliases for j<CC>
2739 defm : IntegerCondCodeMnemonicAlias<"j", "">;
2740 // Aliases for cmov<CC>{w,l,q}
2741 defm : IntegerCondCodeMnemonicAlias<"cmov", "w", "att">;
2742 defm : IntegerCondCodeMnemonicAlias<"cmov", "l", "att">;
2743 defm : IntegerCondCodeMnemonicAlias<"cmov", "q", "att">;
2744 // No size suffix for intel-style asm.
2745 defm : IntegerCondCodeMnemonicAlias<"cmov", "", "intel">;
2748 //===----------------------------------------------------------------------===//
2749 // Assembler Instruction Aliases
2750 //===----------------------------------------------------------------------===//
2752 // aad/aam default to base 10 if no operand is specified.
2753 def : InstAlias<"aad", (AAD8i8 10)>, Requires<[Not64BitMode]>;
2754 def : InstAlias<"aam", (AAM8i8 10)>, Requires<[Not64BitMode]>;
2756 // Disambiguate the mem/imm form of bt-without-a-suffix as btl.
2757 // Likewise for btc/btr/bts.
2758 def : InstAlias<"bt\t{$imm, $mem|$mem, $imm}",
2759 (BT32mi8 i32mem:$mem, i32i8imm:$imm), 0>;
2760 def : InstAlias<"btc\t{$imm, $mem|$mem, $imm}",
2761 (BTC32mi8 i32mem:$mem, i32i8imm:$imm), 0>;
2762 def : InstAlias<"btr\t{$imm, $mem|$mem, $imm}",
2763 (BTR32mi8 i32mem:$mem, i32i8imm:$imm), 0>;
2764 def : InstAlias<"bts\t{$imm, $mem|$mem, $imm}",
2765 (BTS32mi8 i32mem:$mem, i32i8imm:$imm), 0>;
2768 def : InstAlias<"clrb\t$reg", (XOR8rr GR8 :$reg, GR8 :$reg), 0>;
2769 def : InstAlias<"clrw\t$reg", (XOR16rr GR16:$reg, GR16:$reg), 0>;
2770 def : InstAlias<"clrl\t$reg", (XOR32rr GR32:$reg, GR32:$reg), 0>;
2771 def : InstAlias<"clrq\t$reg", (XOR64rr GR64:$reg, GR64:$reg), 0>;
2773 // lods aliases. Accept the destination being omitted because it's implicit
2774 // in the mnemonic, or the mnemonic suffix being omitted because it's implicit
2775 // in the destination.
2776 def : InstAlias<"lodsb\t$src", (LODSB srcidx8:$src), 0>;
2777 def : InstAlias<"lodsw\t$src", (LODSW srcidx16:$src), 0>;
2778 def : InstAlias<"lods{l|d}\t$src", (LODSL srcidx32:$src), 0>;
2779 def : InstAlias<"lodsq\t$src", (LODSQ srcidx64:$src), 0>, Requires<[In64BitMode]>;
2780 def : InstAlias<"lods\t{$src, %al|al, $src}", (LODSB srcidx8:$src), 0>;
2781 def : InstAlias<"lods\t{$src, %ax|ax, $src}", (LODSW srcidx16:$src), 0>;
2782 def : InstAlias<"lods\t{$src, %eax|eax, $src}", (LODSL srcidx32:$src), 0>;
2783 def : InstAlias<"lods\t{$src, %rax|rax, $src}", (LODSQ srcidx64:$src), 0>, Requires<[In64BitMode]>;
2785 // stos aliases. Accept the source being omitted because it's implicit in
2786 // the mnemonic, or the mnemonic suffix being omitted because it's implicit
2788 def : InstAlias<"stosb\t$dst", (STOSB dstidx8:$dst), 0>;
2789 def : InstAlias<"stosw\t$dst", (STOSW dstidx16:$dst), 0>;
2790 def : InstAlias<"stos{l|d}\t$dst", (STOSL dstidx32:$dst), 0>;
2791 def : InstAlias<"stosq\t$dst", (STOSQ dstidx64:$dst), 0>, Requires<[In64BitMode]>;
2792 def : InstAlias<"stos\t{%al, $dst|$dst, al}", (STOSB dstidx8:$dst), 0>;
2793 def : InstAlias<"stos\t{%ax, $dst|$dst, ax}", (STOSW dstidx16:$dst), 0>;
2794 def : InstAlias<"stos\t{%eax, $dst|$dst, eax}", (STOSL dstidx32:$dst), 0>;
2795 def : InstAlias<"stos\t{%rax, $dst|$dst, rax}", (STOSQ dstidx64:$dst), 0>, Requires<[In64BitMode]>;
2797 // scas aliases. Accept the destination being omitted because it's implicit
2798 // in the mnemonic, or the mnemonic suffix being omitted because it's implicit
2799 // in the destination.
2800 def : InstAlias<"scasb\t$dst", (SCASB dstidx8:$dst), 0>;
2801 def : InstAlias<"scasw\t$dst", (SCASW dstidx16:$dst), 0>;
2802 def : InstAlias<"scas{l|d}\t$dst", (SCASL dstidx32:$dst), 0>;
2803 def : InstAlias<"scasq\t$dst", (SCASQ dstidx64:$dst), 0>, Requires<[In64BitMode]>;
2804 def : InstAlias<"scas\t{$dst, %al|al, $dst}", (SCASB dstidx8:$dst), 0>;
2805 def : InstAlias<"scas\t{$dst, %ax|ax, $dst}", (SCASW dstidx16:$dst), 0>;
2806 def : InstAlias<"scas\t{$dst, %eax|eax, $dst}", (SCASL dstidx32:$dst), 0>;
2807 def : InstAlias<"scas\t{$dst, %rax|rax, $dst}", (SCASQ dstidx64:$dst), 0>, Requires<[In64BitMode]>;
2809 // div and idiv aliases for explicit A register.
2810 def : InstAlias<"div{b}\t{$src, %al|al, $src}", (DIV8r GR8 :$src)>;
2811 def : InstAlias<"div{w}\t{$src, %ax|ax, $src}", (DIV16r GR16:$src)>;
2812 def : InstAlias<"div{l}\t{$src, %eax|eax, $src}", (DIV32r GR32:$src)>;
2813 def : InstAlias<"div{q}\t{$src, %rax|rax, $src}", (DIV64r GR64:$src)>;
2814 def : InstAlias<"div{b}\t{$src, %al|al, $src}", (DIV8m i8mem :$src)>;
2815 def : InstAlias<"div{w}\t{$src, %ax|ax, $src}", (DIV16m i16mem:$src)>;
2816 def : InstAlias<"div{l}\t{$src, %eax|eax, $src}", (DIV32m i32mem:$src)>;
2817 def : InstAlias<"div{q}\t{$src, %rax|rax, $src}", (DIV64m i64mem:$src)>;
2818 def : InstAlias<"idiv{b}\t{$src, %al|al, $src}", (IDIV8r GR8 :$src)>;
2819 def : InstAlias<"idiv{w}\t{$src, %ax|ax, $src}", (IDIV16r GR16:$src)>;
2820 def : InstAlias<"idiv{l}\t{$src, %eax|eax, $src}", (IDIV32r GR32:$src)>;
2821 def : InstAlias<"idiv{q}\t{$src, %rax|rax, $src}", (IDIV64r GR64:$src)>;
2822 def : InstAlias<"idiv{b}\t{$src, %al|al, $src}", (IDIV8m i8mem :$src)>;
2823 def : InstAlias<"idiv{w}\t{$src, %ax|ax, $src}", (IDIV16m i16mem:$src)>;
2824 def : InstAlias<"idiv{l}\t{$src, %eax|eax, $src}", (IDIV32m i32mem:$src)>;
2825 def : InstAlias<"idiv{q}\t{$src, %rax|rax, $src}", (IDIV64m i64mem:$src)>;
2829 // Various unary fpstack operations default to operating on on ST1.
2830 // For example, "fxch" -> "fxch %st(1)"
2831 def : InstAlias<"faddp", (ADD_FPrST0 ST1), 0>;
2832 def: InstAlias<"fadd", (ADD_FPrST0 ST1), 0>;
2833 def : InstAlias<"fsub{|r}p", (SUBR_FPrST0 ST1), 0>;
2834 def : InstAlias<"fsub{r|}p", (SUB_FPrST0 ST1), 0>;
2835 def : InstAlias<"fmul", (MUL_FPrST0 ST1), 0>;
2836 def : InstAlias<"fmulp", (MUL_FPrST0 ST1), 0>;
2837 def : InstAlias<"fdiv{|r}p", (DIVR_FPrST0 ST1), 0>;
2838 def : InstAlias<"fdiv{r|}p", (DIV_FPrST0 ST1), 0>;
2839 def : InstAlias<"fxch", (XCH_F ST1), 0>;
2840 def : InstAlias<"fcom", (COM_FST0r ST1), 0>;
2841 def : InstAlias<"fcomp", (COMP_FST0r ST1), 0>;
2842 def : InstAlias<"fcomi", (COM_FIr ST1), 0>;
2843 def : InstAlias<"fcompi", (COM_FIPr ST1), 0>;
2844 def : InstAlias<"fucom", (UCOM_Fr ST1), 0>;
2845 def : InstAlias<"fucomp", (UCOM_FPr ST1), 0>;
2846 def : InstAlias<"fucomi", (UCOM_FIr ST1), 0>;
2847 def : InstAlias<"fucompi", (UCOM_FIPr ST1), 0>;
2849 // Handle fmul/fadd/fsub/fdiv instructions with explicitly written st(0) op.
2850 // For example, "fadd %st(4), %st(0)" -> "fadd %st(4)". We also disambiguate
2851 // instructions like "fadd %st(0), %st(0)" as "fadd %st(0)" for consistency with
2853 multiclass FpUnaryAlias<string Mnemonic, Instruction Inst, bit EmitAlias = 1> {
2854 def : InstAlias<!strconcat(Mnemonic, "\t{$op, %st(0)|st(0), $op}"),
2855 (Inst RST:$op), EmitAlias>;
2856 def : InstAlias<!strconcat(Mnemonic, "\t{%st(0), %st(0)|st(0), st(0)}"),
2857 (Inst ST0), EmitAlias>;
2860 defm : FpUnaryAlias<"fadd", ADD_FST0r>;
2861 defm : FpUnaryAlias<"faddp", ADD_FPrST0, 0>;
2862 defm : FpUnaryAlias<"fsub", SUB_FST0r>;
2863 defm : FpUnaryAlias<"fsub{|r}p", SUBR_FPrST0>;
2864 defm : FpUnaryAlias<"fsubr", SUBR_FST0r>;
2865 defm : FpUnaryAlias<"fsub{r|}p", SUB_FPrST0>;
2866 defm : FpUnaryAlias<"fmul", MUL_FST0r>;
2867 defm : FpUnaryAlias<"fmulp", MUL_FPrST0>;
2868 defm : FpUnaryAlias<"fdiv", DIV_FST0r>;
2869 defm : FpUnaryAlias<"fdiv{|r}p", DIVR_FPrST0>;
2870 defm : FpUnaryAlias<"fdivr", DIVR_FST0r>;
2871 defm : FpUnaryAlias<"fdiv{r|}p", DIV_FPrST0>;
2872 defm : FpUnaryAlias<"fcomi", COM_FIr, 0>;
2873 defm : FpUnaryAlias<"fucomi", UCOM_FIr, 0>;
2874 defm : FpUnaryAlias<"fcompi", COM_FIPr>;
2875 defm : FpUnaryAlias<"fucompi", UCOM_FIPr>;
2878 // Handle "f{mulp,addp} st(0), $op" the same as "f{mulp,addp} $op", since they
2879 // commute. We also allow fdiv[r]p/fsubrp even though they don't commute,
2880 // solely because gas supports it.
2881 def : InstAlias<"faddp\t{%st(0), $op|$op, st(0)}", (ADD_FPrST0 RST:$op), 0>;
2882 def : InstAlias<"fmulp\t{%st(0), $op|$op, st(0)}", (MUL_FPrST0 RST:$op)>;
2883 def : InstAlias<"fsub{|r}p\t{%st(0), $op|$op, st(0)}", (SUBR_FPrST0 RST:$op)>;
2884 def : InstAlias<"fsub{r|}p\t{%st(0), $op|$op, st(0)}", (SUB_FPrST0 RST:$op)>;
2885 def : InstAlias<"fdiv{|r}p\t{%st(0), $op|$op, st(0)}", (DIVR_FPrST0 RST:$op)>;
2886 def : InstAlias<"fdiv{r|}p\t{%st(0), $op|$op, st(0)}", (DIV_FPrST0 RST:$op)>;
2888 // We accept "fnstsw %eax" even though it only writes %ax.
2889 def : InstAlias<"fnstsw\t{%eax|eax}", (FNSTSW16r)>;
2890 def : InstAlias<"fnstsw\t{%al|al}" , (FNSTSW16r)>;
2891 def : InstAlias<"fnstsw" , (FNSTSW16r)>;
2893 // lcall and ljmp aliases. This seems to be an odd mapping in 64-bit mode, but
2894 // this is compatible with what GAS does.
2895 def : InstAlias<"lcall\t$seg, $off", (FARCALL32i i32imm:$off, i16imm:$seg), 0>, Requires<[Not16BitMode]>;
2896 def : InstAlias<"ljmp\t$seg, $off", (FARJMP32i i32imm:$off, i16imm:$seg), 0>, Requires<[Not16BitMode]>;
2897 def : InstAlias<"lcall\t{*}$dst", (FARCALL32m opaque48mem:$dst), 0>, Requires<[Not16BitMode]>;
2898 def : InstAlias<"ljmp\t{*}$dst", (FARJMP32m opaque48mem:$dst), 0>, Requires<[Not16BitMode]>;
2899 def : InstAlias<"lcall\t$seg, $off", (FARCALL16i i16imm:$off, i16imm:$seg), 0>, Requires<[In16BitMode]>;
2900 def : InstAlias<"ljmp\t$seg, $off", (FARJMP16i i16imm:$off, i16imm:$seg), 0>, Requires<[In16BitMode]>;
2901 def : InstAlias<"lcall\t{*}$dst", (FARCALL16m opaque32mem:$dst), 0>, Requires<[In16BitMode]>;
2902 def : InstAlias<"ljmp\t{*}$dst", (FARJMP16m opaque32mem:$dst), 0>, Requires<[In16BitMode]>;
2904 def : InstAlias<"call\t{*}$dst", (CALL64m i64mem:$dst), 0>, Requires<[In64BitMode]>;
2905 def : InstAlias<"jmp\t{*}$dst", (JMP64m i64mem:$dst), 0>, Requires<[In64BitMode]>;
2906 def : InstAlias<"call\t{*}$dst", (CALL32m i32mem:$dst), 0>, Requires<[In32BitMode]>;
2907 def : InstAlias<"jmp\t{*}$dst", (JMP32m i32mem:$dst), 0>, Requires<[In32BitMode]>;
2908 def : InstAlias<"call\t{*}$dst", (CALL16m i16mem:$dst), 0>, Requires<[In16BitMode]>;
2909 def : InstAlias<"jmp\t{*}$dst", (JMP16m i16mem:$dst), 0>, Requires<[In16BitMode]>;
2912 // "imul <imm>, B" is an alias for "imul <imm>, B, B".
2913 def : InstAlias<"imul{w}\t{$imm, $r|$r, $imm}", (IMUL16rri GR16:$r, GR16:$r, i16imm:$imm), 0>;
2914 def : InstAlias<"imul{w}\t{$imm, $r|$r, $imm}", (IMUL16rri8 GR16:$r, GR16:$r, i16i8imm:$imm), 0>;
2915 def : InstAlias<"imul{l}\t{$imm, $r|$r, $imm}", (IMUL32rri GR32:$r, GR32:$r, i32imm:$imm), 0>;
2916 def : InstAlias<"imul{l}\t{$imm, $r|$r, $imm}", (IMUL32rri8 GR32:$r, GR32:$r, i32i8imm:$imm), 0>;
2917 def : InstAlias<"imul{q}\t{$imm, $r|$r, $imm}", (IMUL64rri32 GR64:$r, GR64:$r, i64i32imm:$imm), 0>;
2918 def : InstAlias<"imul{q}\t{$imm, $r|$r, $imm}", (IMUL64rri8 GR64:$r, GR64:$r, i64i8imm:$imm), 0>;
2920 // inb %dx -> inb %al, %dx
2921 def : InstAlias<"inb\t{%dx|dx}", (IN8rr), 0>;
2922 def : InstAlias<"inw\t{%dx|dx}", (IN16rr), 0>;
2923 def : InstAlias<"inl\t{%dx|dx}", (IN32rr), 0>;
2924 def : InstAlias<"inb\t$port", (IN8ri u8imm:$port), 0>;
2925 def : InstAlias<"inw\t$port", (IN16ri u8imm:$port), 0>;
2926 def : InstAlias<"inl\t$port", (IN32ri u8imm:$port), 0>;
2929 // jmp and call aliases for lcall and ljmp. jmp $42,$5 -> ljmp
2930 def : InstAlias<"call\t$seg, $off", (FARCALL16i i16imm:$off, i16imm:$seg)>, Requires<[In16BitMode]>;
2931 def : InstAlias<"jmp\t$seg, $off", (FARJMP16i i16imm:$off, i16imm:$seg)>, Requires<[In16BitMode]>;
2932 def : InstAlias<"call\t$seg, $off", (FARCALL32i i32imm:$off, i16imm:$seg)>, Requires<[Not16BitMode]>;
2933 def : InstAlias<"jmp\t$seg, $off", (FARJMP32i i32imm:$off, i16imm:$seg)>, Requires<[Not16BitMode]>;
2934 def : InstAlias<"callw\t$seg, $off", (FARCALL16i i16imm:$off, i16imm:$seg)>;
2935 def : InstAlias<"jmpw\t$seg, $off", (FARJMP16i i16imm:$off, i16imm:$seg)>;
2936 def : InstAlias<"calll\t$seg, $off", (FARCALL32i i32imm:$off, i16imm:$seg)>;
2937 def : InstAlias<"jmpl\t$seg, $off", (FARJMP32i i32imm:$off, i16imm:$seg)>;
2939 // Force mov without a suffix with a segment and mem to prefer the 'l' form of
2940 // the move. All segment/mem forms are equivalent, this has the shortest
2942 def : InstAlias<"mov\t{$mem, $seg|$seg, $mem}", (MOV32sm SEGMENT_REG:$seg, i32mem:$mem), 0>;
2943 def : InstAlias<"mov\t{$seg, $mem|$mem, $seg}", (MOV32ms i32mem:$mem, SEGMENT_REG:$seg), 0>;
2945 // Match 'movq <largeimm>, <reg>' as an alias for movabsq.
2946 def : InstAlias<"movq\t{$imm, $reg|$reg, $imm}", (MOV64ri GR64:$reg, i64imm:$imm), 0>;
2948 // Match 'movq GR64, MMX' as an alias for movd.
2949 def : InstAlias<"movq\t{$src, $dst|$dst, $src}",
2950 (MMX_MOVD64to64rr VR64:$dst, GR64:$src), 0>;
2951 def : InstAlias<"movq\t{$src, $dst|$dst, $src}",
2952 (MMX_MOVD64from64rr GR64:$dst, VR64:$src), 0>;
2955 def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX16rr8 GR16:$dst, GR8:$src), 0>;
2956 def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX16rm8 GR16:$dst, i8mem:$src), 0>;
2957 def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX32rr8 GR32:$dst, GR8:$src), 0>;
2958 def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX32rr16 GR32:$dst, GR16:$src), 0>;
2959 def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX64rr8 GR64:$dst, GR8:$src), 0>;
2960 def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX64rr16 GR64:$dst, GR16:$src), 0>;
2961 def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX64rr32 GR64:$dst, GR32:$src), 0>;
2964 def : InstAlias<"movzx\t{$src, $dst|$dst, $src}", (MOVZX16rr8 GR16:$dst, GR8:$src), 0>;
2965 def : InstAlias<"movzx\t{$src, $dst|$dst, $src}", (MOVZX16rm8 GR16:$dst, i8mem:$src), 0>;
2966 def : InstAlias<"movzx\t{$src, $dst|$dst, $src}", (MOVZX32rr8 GR32:$dst, GR8:$src), 0>;
2967 def : InstAlias<"movzx\t{$src, $dst|$dst, $src}", (MOVZX32rr16 GR32:$dst, GR16:$src), 0>;
2968 def : InstAlias<"movzx\t{$src, $dst|$dst, $src}", (MOVZX64rr8 GR64:$dst, GR8:$src), 0>;
2969 def : InstAlias<"movzx\t{$src, $dst|$dst, $src}", (MOVZX64rr16 GR64:$dst, GR16:$src), 0>;
2970 // Note: No GR32->GR64 movzx form.
2972 // outb %dx -> outb %al, %dx
2973 def : InstAlias<"outb\t{%dx|dx}", (OUT8rr), 0>;
2974 def : InstAlias<"outw\t{%dx|dx}", (OUT16rr), 0>;
2975 def : InstAlias<"outl\t{%dx|dx}", (OUT32rr), 0>;
2976 def : InstAlias<"outb\t$port", (OUT8ir u8imm:$port), 0>;
2977 def : InstAlias<"outw\t$port", (OUT16ir u8imm:$port), 0>;
2978 def : InstAlias<"outl\t$port", (OUT32ir u8imm:$port), 0>;
2980 // 'sldt <mem>' can be encoded with either sldtw or sldtq with the same
2981 // effect (both store to a 16-bit mem). Force to sldtw to avoid ambiguity
2982 // errors, since its encoding is the most compact.
2983 def : InstAlias<"sldt $mem", (SLDT16m i16mem:$mem), 0>;
2985 // shld/shrd op,op -> shld op, op, CL
2986 def : InstAlias<"shld{w}\t{$r2, $r1|$r1, $r2}", (SHLD16rrCL GR16:$r1, GR16:$r2), 0>;
2987 def : InstAlias<"shld{l}\t{$r2, $r1|$r1, $r2}", (SHLD32rrCL GR32:$r1, GR32:$r2), 0>;
2988 def : InstAlias<"shld{q}\t{$r2, $r1|$r1, $r2}", (SHLD64rrCL GR64:$r1, GR64:$r2), 0>;
2989 def : InstAlias<"shrd{w}\t{$r2, $r1|$r1, $r2}", (SHRD16rrCL GR16:$r1, GR16:$r2), 0>;
2990 def : InstAlias<"shrd{l}\t{$r2, $r1|$r1, $r2}", (SHRD32rrCL GR32:$r1, GR32:$r2), 0>;
2991 def : InstAlias<"shrd{q}\t{$r2, $r1|$r1, $r2}", (SHRD64rrCL GR64:$r1, GR64:$r2), 0>;
2993 def : InstAlias<"shld{w}\t{$reg, $mem|$mem, $reg}", (SHLD16mrCL i16mem:$mem, GR16:$reg), 0>;
2994 def : InstAlias<"shld{l}\t{$reg, $mem|$mem, $reg}", (SHLD32mrCL i32mem:$mem, GR32:$reg), 0>;
2995 def : InstAlias<"shld{q}\t{$reg, $mem|$mem, $reg}", (SHLD64mrCL i64mem:$mem, GR64:$reg), 0>;
2996 def : InstAlias<"shrd{w}\t{$reg, $mem|$mem, $reg}", (SHRD16mrCL i16mem:$mem, GR16:$reg), 0>;
2997 def : InstAlias<"shrd{l}\t{$reg, $mem|$mem, $reg}", (SHRD32mrCL i32mem:$mem, GR32:$reg), 0>;
2998 def : InstAlias<"shrd{q}\t{$reg, $mem|$mem, $reg}", (SHRD64mrCL i64mem:$mem, GR64:$reg), 0>;
3000 /* FIXME: This is disabled because the asm matcher is currently incapable of
3001 * matching a fixed immediate like $1.
3002 // "shl X, $1" is an alias for "shl X".
3003 multiclass ShiftRotateByOneAlias<string Mnemonic, string Opc> {
3004 def : InstAlias<!strconcat(Mnemonic, "b $op, $$1"),
3005 (!cast<Instruction>(!strconcat(Opc, "8r1")) GR8:$op)>;
3006 def : InstAlias<!strconcat(Mnemonic, "w $op, $$1"),
3007 (!cast<Instruction>(!strconcat(Opc, "16r1")) GR16:$op)>;
3008 def : InstAlias<!strconcat(Mnemonic, "l $op, $$1"),
3009 (!cast<Instruction>(!strconcat(Opc, "32r1")) GR32:$op)>;
3010 def : InstAlias<!strconcat(Mnemonic, "q $op, $$1"),
3011 (!cast<Instruction>(!strconcat(Opc, "64r1")) GR64:$op)>;
3012 def : InstAlias<!strconcat(Mnemonic, "b $op, $$1"),
3013 (!cast<Instruction>(!strconcat(Opc, "8m1")) i8mem:$op)>;
3014 def : InstAlias<!strconcat(Mnemonic, "w $op, $$1"),
3015 (!cast<Instruction>(!strconcat(Opc, "16m1")) i16mem:$op)>;
3016 def : InstAlias<!strconcat(Mnemonic, "l $op, $$1"),
3017 (!cast<Instruction>(!strconcat(Opc, "32m1")) i32mem:$op)>;
3018 def : InstAlias<!strconcat(Mnemonic, "q $op, $$1"),
3019 (!cast<Instruction>(!strconcat(Opc, "64m1")) i64mem:$op)>;
3022 defm : ShiftRotateByOneAlias<"rcl", "RCL">;
3023 defm : ShiftRotateByOneAlias<"rcr", "RCR">;
3024 defm : ShiftRotateByOneAlias<"rol", "ROL">;
3025 defm : ShiftRotateByOneAlias<"ror", "ROR">;
3028 // test: We accept "testX <reg>, <mem>" and "testX <mem>, <reg>" as synonyms.
3029 def : InstAlias<"test{b}\t{$val, $mem|$mem, $val}",
3030 (TEST8rm GR8 :$val, i8mem :$mem), 0>;
3031 def : InstAlias<"test{w}\t{$val, $mem|$mem, $val}",
3032 (TEST16rm GR16:$val, i16mem:$mem), 0>;
3033 def : InstAlias<"test{l}\t{$val, $mem|$mem, $val}",
3034 (TEST32rm GR32:$val, i32mem:$mem), 0>;
3035 def : InstAlias<"test{q}\t{$val, $mem|$mem, $val}",
3036 (TEST64rm GR64:$val, i64mem:$mem), 0>;
3038 // xchg: We accept "xchgX <reg>, <mem>" and "xchgX <mem>, <reg>" as synonyms.
3039 def : InstAlias<"xchg{b}\t{$mem, $val|$val, $mem}",
3040 (XCHG8rm GR8 :$val, i8mem :$mem), 0>;
3041 def : InstAlias<"xchg{w}\t{$mem, $val|$val, $mem}",
3042 (XCHG16rm GR16:$val, i16mem:$mem), 0>;
3043 def : InstAlias<"xchg{l}\t{$mem, $val|$val, $mem}",
3044 (XCHG32rm GR32:$val, i32mem:$mem), 0>;
3045 def : InstAlias<"xchg{q}\t{$mem, $val|$val, $mem}",
3046 (XCHG64rm GR64:$val, i64mem:$mem), 0>;
3048 // xchg: We accept "xchgX <reg>, %eax" and "xchgX %eax, <reg>" as synonyms.
3049 def : InstAlias<"xchg{w}\t{%ax, $src|$src, ax}", (XCHG16ar GR16:$src), 0>;
3050 def : InstAlias<"xchg{l}\t{%eax, $src|$src, eax}",
3051 (XCHG32ar GR32:$src), 0>, Requires<[Not64BitMode]>;
3052 def : InstAlias<"xchg{l}\t{%eax, $src|$src, eax}",
3053 (XCHG32ar64 GR32_NOAX:$src), 0>, Requires<[In64BitMode]>;
3054 def : InstAlias<"xchg{q}\t{%rax, $src|$src, rax}", (XCHG64ar GR64:$src), 0>;
3056 // These aliases exist to get the parser to prioritize matching 8-bit
3057 // immediate encodings over matching the implicit ax/eax/rax encodings. By
3058 // explicitly mentioning the A register here, these entries will be ordered
3059 // first due to the more explicit immediate type.
3060 def : InstAlias<"adc{w}\t{$imm, %ax|ax, $imm}", (ADC16ri8 AX, i16i8imm:$imm), 0>;
3061 def : InstAlias<"add{w}\t{$imm, %ax|ax, $imm}", (ADD16ri8 AX, i16i8imm:$imm), 0>;
3062 def : InstAlias<"and{w}\t{$imm, %ax|ax, $imm}", (AND16ri8 AX, i16i8imm:$imm), 0>;
3063 def : InstAlias<"cmp{w}\t{$imm, %ax|ax, $imm}", (CMP16ri8 AX, i16i8imm:$imm), 0>;
3064 def : InstAlias<"or{w}\t{$imm, %ax|ax, $imm}", (OR16ri8 AX, i16i8imm:$imm), 0>;
3065 def : InstAlias<"sbb{w}\t{$imm, %ax|ax, $imm}", (SBB16ri8 AX, i16i8imm:$imm), 0>;
3066 def : InstAlias<"sub{w}\t{$imm, %ax|ax, $imm}", (SUB16ri8 AX, i16i8imm:$imm), 0>;
3067 def : InstAlias<"xor{w}\t{$imm, %ax|ax, $imm}", (XOR16ri8 AX, i16i8imm:$imm), 0>;
3069 def : InstAlias<"adc{l}\t{$imm, %eax|eax, $imm}", (ADC32ri8 EAX, i32i8imm:$imm), 0>;
3070 def : InstAlias<"add{l}\t{$imm, %eax|eax, $imm}", (ADD32ri8 EAX, i32i8imm:$imm), 0>;
3071 def : InstAlias<"and{l}\t{$imm, %eax|eax, $imm}", (AND32ri8 EAX, i32i8imm:$imm), 0>;
3072 def : InstAlias<"cmp{l}\t{$imm, %eax|eax, $imm}", (CMP32ri8 EAX, i32i8imm:$imm), 0>;
3073 def : InstAlias<"or{l}\t{$imm, %eax|eax, $imm}", (OR32ri8 EAX, i32i8imm:$imm), 0>;
3074 def : InstAlias<"sbb{l}\t{$imm, %eax|eax, $imm}", (SBB32ri8 EAX, i32i8imm:$imm), 0>;
3075 def : InstAlias<"sub{l}\t{$imm, %eax|eax, $imm}", (SUB32ri8 EAX, i32i8imm:$imm), 0>;
3076 def : InstAlias<"xor{l}\t{$imm, %eax|eax, $imm}", (XOR32ri8 EAX, i32i8imm:$imm), 0>;
3078 def : InstAlias<"adc{q}\t{$imm, %rax|rax, $imm}", (ADC64ri8 RAX, i64i8imm:$imm), 0>;
3079 def : InstAlias<"add{q}\t{$imm, %rax|rax, $imm}", (ADD64ri8 RAX, i64i8imm:$imm), 0>;
3080 def : InstAlias<"and{q}\t{$imm, %rax|rax, $imm}", (AND64ri8 RAX, i64i8imm:$imm), 0>;
3081 def : InstAlias<"cmp{q}\t{$imm, %rax|rax, $imm}", (CMP64ri8 RAX, i64i8imm:$imm), 0>;
3082 def : InstAlias<"or{q}\t{$imm, %rax|rax, $imm}", (OR64ri8 RAX, i64i8imm:$imm), 0>;
3083 def : InstAlias<"sbb{q}\t{$imm, %rax|rax, $imm}", (SBB64ri8 RAX, i64i8imm:$imm), 0>;
3084 def : InstAlias<"sub{q}\t{$imm, %rax|rax, $imm}", (SUB64ri8 RAX, i64i8imm:$imm), 0>;
3085 def : InstAlias<"xor{q}\t{$imm, %rax|rax, $imm}", (XOR64ri8 RAX, i64i8imm:$imm), 0>;