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