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 X86Mem256_RC512Operand : AsmOperandClass { let Name = "Mem256_RC512"; }
322 def X86Mem512_RC512Operand : AsmOperandClass { let Name = "Mem512_RC512"; }
325 def X86AbsMemAsmOperand : AsmOperandClass {
327 let SuperClasses = [X86MemAsmOperand];
330 class X86MemOperand<string printMethod,
331 AsmOperandClass parserMatchClass = X86MemAsmOperand> : Operand<iPTR> {
332 let PrintMethod = printMethod;
333 let MIOperandInfo = (ops ptr_rc, i8imm, ptr_rc_nosp, i32imm, SEGMENT_REG);
334 let ParserMatchClass = parserMatchClass;
335 let OperandType = "OPERAND_MEMORY";
338 // Gather mem operands
339 class X86VMemOperand<RegisterClass RC, string printMethod,
340 AsmOperandClass parserMatchClass>
341 : X86MemOperand<printMethod, parserMatchClass> {
342 let MIOperandInfo = (ops ptr_rc, i8imm, RC, i32imm, SEGMENT_REG);
345 def anymem : X86MemOperand<"printanymem">;
347 def opaque32mem : X86MemOperand<"printopaquemem">;
348 def opaque48mem : X86MemOperand<"printopaquemem">;
349 def opaque80mem : X86MemOperand<"printopaquemem">;
350 def opaque512mem : X86MemOperand<"printopaquemem">;
352 def i8mem : X86MemOperand<"printi8mem", X86Mem8AsmOperand>;
353 def i16mem : X86MemOperand<"printi16mem", X86Mem16AsmOperand>;
354 def i32mem : X86MemOperand<"printi32mem", X86Mem32AsmOperand>;
355 def i64mem : X86MemOperand<"printi64mem", X86Mem64AsmOperand>;
356 def i128mem : X86MemOperand<"printi128mem", X86Mem128AsmOperand>;
357 def i256mem : X86MemOperand<"printi256mem", X86Mem256AsmOperand>;
358 def i512mem : X86MemOperand<"printi512mem", X86Mem512AsmOperand>;
359 def f32mem : X86MemOperand<"printf32mem", X86Mem32AsmOperand>;
360 def f64mem : X86MemOperand<"printf64mem", X86Mem64AsmOperand>;
361 def f80mem : X86MemOperand<"printf80mem", X86Mem80AsmOperand>;
362 def f128mem : X86MemOperand<"printf128mem", X86Mem128AsmOperand>;
363 def f256mem : X86MemOperand<"printf256mem", X86Mem256AsmOperand>;
364 def f512mem : X86MemOperand<"printf512mem", X86Mem512AsmOperand>;
366 def v512mem : X86VMemOperand<VR512, "printf512mem", X86Mem512AsmOperand>;
368 // Gather mem operands
369 def vx64mem : X86VMemOperand<VR128, "printi64mem", X86Mem64_RC128Operand>;
370 def vx128mem : X86VMemOperand<VR128, "printi128mem", X86Mem128_RC128Operand>;
371 def vx256mem : X86VMemOperand<VR128, "printi256mem", X86Mem256_RC128Operand>;
372 def vy128mem : X86VMemOperand<VR256, "printi128mem", X86Mem128_RC256Operand>;
373 def vy256mem : X86VMemOperand<VR256, "printi256mem", X86Mem256_RC256Operand>;
375 def vx64xmem : X86VMemOperand<VR128X, "printi64mem", X86Mem64_RC128XOperand>;
376 def vx128xmem : X86VMemOperand<VR128X, "printi128mem", X86Mem128_RC128XOperand>;
377 def vx256xmem : X86VMemOperand<VR128X, "printi256mem", X86Mem256_RC128XOperand>;
378 def vy128xmem : X86VMemOperand<VR256X, "printi128mem", X86Mem128_RC256XOperand>;
379 def vy256xmem : X86VMemOperand<VR256X, "printi256mem", X86Mem256_RC256XOperand>;
380 def vy512mem : X86VMemOperand<VR256X, "printi512mem", X86Mem512_RC256XOperand>;
381 def vz256xmem : X86VMemOperand<VR512, "printi256mem", X86Mem256_RC512Operand>;
382 def vz512mem : X86VMemOperand<VR512, "printi512mem", X86Mem512_RC512Operand>;
384 // A version of i8mem for use on x86-64 and x32 that uses a NOREX GPR instead
385 // of a plain GPR, so that it doesn't potentially require a REX prefix.
386 def ptr_rc_norex : PointerLikeRegClass<2>;
387 def ptr_rc_norex_nosp : PointerLikeRegClass<3>;
389 def i8mem_NOREX : Operand<iPTR> {
390 let PrintMethod = "printi8mem";
391 let MIOperandInfo = (ops ptr_rc_norex, i8imm, ptr_rc_norex_nosp, i32imm,
393 let ParserMatchClass = X86Mem8AsmOperand;
394 let OperandType = "OPERAND_MEMORY";
397 // GPRs available for tailcall.
398 // It represents GR32_TC, GR64_TC or GR64_TCW64.
399 def ptr_rc_tailcall : PointerLikeRegClass<4>;
401 // Special i32mem for addresses of load folding tail calls. These are not
402 // allowed to use callee-saved registers since they must be scheduled
403 // after callee-saved register are popped.
404 def i32mem_TC : Operand<i32> {
405 let PrintMethod = "printi32mem";
406 let MIOperandInfo = (ops ptr_rc_tailcall, i8imm, ptr_rc_tailcall,
407 i32imm, SEGMENT_REG);
408 let ParserMatchClass = X86Mem32AsmOperand;
409 let OperandType = "OPERAND_MEMORY";
412 // Special i64mem for addresses of load folding tail calls. These are not
413 // allowed to use callee-saved registers since they must be scheduled
414 // after callee-saved register are popped.
415 def i64mem_TC : Operand<i64> {
416 let PrintMethod = "printi64mem";
417 let MIOperandInfo = (ops ptr_rc_tailcall, i8imm,
418 ptr_rc_tailcall, i32imm, SEGMENT_REG);
419 let ParserMatchClass = X86Mem64AsmOperand;
420 let OperandType = "OPERAND_MEMORY";
423 let OperandType = "OPERAND_PCREL",
424 ParserMatchClass = X86AbsMemAsmOperand,
425 PrintMethod = "printPCRelImm" in {
426 def i32imm_pcrel : Operand<i32>;
427 def i16imm_pcrel : Operand<i16>;
429 // Branch targets have OtherVT type and print as pc-relative values.
430 def brtarget : Operand<OtherVT>;
431 def brtarget8 : Operand<OtherVT>;
435 // Special parser to detect 16-bit mode to select 16-bit displacement.
436 def X86AbsMem16AsmOperand : AsmOperandClass {
437 let Name = "AbsMem16";
438 let RenderMethod = "addAbsMemOperands";
439 let SuperClasses = [X86AbsMemAsmOperand];
442 // Branch targets have OtherVT type and print as pc-relative values.
443 let OperandType = "OPERAND_PCREL",
444 PrintMethod = "printPCRelImm" in {
445 let ParserMatchClass = X86AbsMem16AsmOperand in
446 def brtarget16 : Operand<OtherVT>;
447 let ParserMatchClass = X86AbsMemAsmOperand in
448 def brtarget32 : Operand<OtherVT>;
451 let RenderMethod = "addSrcIdxOperands" in {
452 def X86SrcIdx8Operand : AsmOperandClass {
453 let Name = "SrcIdx8";
454 let SuperClasses = [X86Mem8AsmOperand];
456 def X86SrcIdx16Operand : AsmOperandClass {
457 let Name = "SrcIdx16";
458 let SuperClasses = [X86Mem16AsmOperand];
460 def X86SrcIdx32Operand : AsmOperandClass {
461 let Name = "SrcIdx32";
462 let SuperClasses = [X86Mem32AsmOperand];
464 def X86SrcIdx64Operand : AsmOperandClass {
465 let Name = "SrcIdx64";
466 let SuperClasses = [X86Mem64AsmOperand];
468 } // RenderMethod = "addSrcIdxOperands"
470 let RenderMethod = "addDstIdxOperands" in {
471 def X86DstIdx8Operand : AsmOperandClass {
472 let Name = "DstIdx8";
473 let SuperClasses = [X86Mem8AsmOperand];
475 def X86DstIdx16Operand : AsmOperandClass {
476 let Name = "DstIdx16";
477 let SuperClasses = [X86Mem16AsmOperand];
479 def X86DstIdx32Operand : AsmOperandClass {
480 let Name = "DstIdx32";
481 let SuperClasses = [X86Mem32AsmOperand];
483 def X86DstIdx64Operand : AsmOperandClass {
484 let Name = "DstIdx64";
485 let SuperClasses = [X86Mem64AsmOperand];
487 } // RenderMethod = "addDstIdxOperands"
489 let RenderMethod = "addMemOffsOperands" in {
490 def X86MemOffs16_8AsmOperand : AsmOperandClass {
491 let Name = "MemOffs16_8";
492 let SuperClasses = [X86Mem8AsmOperand];
494 def X86MemOffs16_16AsmOperand : AsmOperandClass {
495 let Name = "MemOffs16_16";
496 let SuperClasses = [X86Mem16AsmOperand];
498 def X86MemOffs16_32AsmOperand : AsmOperandClass {
499 let Name = "MemOffs16_32";
500 let SuperClasses = [X86Mem32AsmOperand];
502 def X86MemOffs32_8AsmOperand : AsmOperandClass {
503 let Name = "MemOffs32_8";
504 let SuperClasses = [X86Mem8AsmOperand];
506 def X86MemOffs32_16AsmOperand : AsmOperandClass {
507 let Name = "MemOffs32_16";
508 let SuperClasses = [X86Mem16AsmOperand];
510 def X86MemOffs32_32AsmOperand : AsmOperandClass {
511 let Name = "MemOffs32_32";
512 let SuperClasses = [X86Mem32AsmOperand];
514 def X86MemOffs32_64AsmOperand : AsmOperandClass {
515 let Name = "MemOffs32_64";
516 let SuperClasses = [X86Mem64AsmOperand];
518 def X86MemOffs64_8AsmOperand : AsmOperandClass {
519 let Name = "MemOffs64_8";
520 let SuperClasses = [X86Mem8AsmOperand];
522 def X86MemOffs64_16AsmOperand : AsmOperandClass {
523 let Name = "MemOffs64_16";
524 let SuperClasses = [X86Mem16AsmOperand];
526 def X86MemOffs64_32AsmOperand : AsmOperandClass {
527 let Name = "MemOffs64_32";
528 let SuperClasses = [X86Mem32AsmOperand];
530 def X86MemOffs64_64AsmOperand : AsmOperandClass {
531 let Name = "MemOffs64_64";
532 let SuperClasses = [X86Mem64AsmOperand];
534 } // RenderMethod = "addMemOffsOperands"
536 class X86SrcIdxOperand<string printMethod, AsmOperandClass parserMatchClass>
537 : X86MemOperand<printMethod, parserMatchClass> {
538 let MIOperandInfo = (ops ptr_rc, SEGMENT_REG);
541 class X86DstIdxOperand<string printMethod, AsmOperandClass parserMatchClass>
542 : X86MemOperand<printMethod, parserMatchClass> {
543 let MIOperandInfo = (ops ptr_rc);
546 def srcidx8 : X86SrcIdxOperand<"printSrcIdx8", X86SrcIdx8Operand>;
547 def srcidx16 : X86SrcIdxOperand<"printSrcIdx16", X86SrcIdx16Operand>;
548 def srcidx32 : X86SrcIdxOperand<"printSrcIdx32", X86SrcIdx32Operand>;
549 def srcidx64 : X86SrcIdxOperand<"printSrcIdx64", X86SrcIdx64Operand>;
550 def dstidx8 : X86DstIdxOperand<"printDstIdx8", X86DstIdx8Operand>;
551 def dstidx16 : X86DstIdxOperand<"printDstIdx16", X86DstIdx16Operand>;
552 def dstidx32 : X86DstIdxOperand<"printDstIdx32", X86DstIdx32Operand>;
553 def dstidx64 : X86DstIdxOperand<"printDstIdx64", X86DstIdx64Operand>;
555 class X86MemOffsOperand<Operand immOperand, string printMethod,
556 AsmOperandClass parserMatchClass>
557 : X86MemOperand<printMethod, parserMatchClass> {
558 let MIOperandInfo = (ops immOperand, SEGMENT_REG);
561 def offset16_8 : X86MemOffsOperand<i16imm, "printMemOffs8",
562 X86MemOffs16_8AsmOperand>;
563 def offset16_16 : X86MemOffsOperand<i16imm, "printMemOffs16",
564 X86MemOffs16_16AsmOperand>;
565 def offset16_32 : X86MemOffsOperand<i16imm, "printMemOffs32",
566 X86MemOffs16_32AsmOperand>;
567 def offset32_8 : X86MemOffsOperand<i32imm, "printMemOffs8",
568 X86MemOffs32_8AsmOperand>;
569 def offset32_16 : X86MemOffsOperand<i32imm, "printMemOffs16",
570 X86MemOffs32_16AsmOperand>;
571 def offset32_32 : X86MemOffsOperand<i32imm, "printMemOffs32",
572 X86MemOffs32_32AsmOperand>;
573 def offset32_64 : X86MemOffsOperand<i32imm, "printMemOffs64",
574 X86MemOffs32_64AsmOperand>;
575 def offset64_8 : X86MemOffsOperand<i64imm, "printMemOffs8",
576 X86MemOffs64_8AsmOperand>;
577 def offset64_16 : X86MemOffsOperand<i64imm, "printMemOffs16",
578 X86MemOffs64_16AsmOperand>;
579 def offset64_32 : X86MemOffsOperand<i64imm, "printMemOffs32",
580 X86MemOffs64_32AsmOperand>;
581 def offset64_64 : X86MemOffsOperand<i64imm, "printMemOffs64",
582 X86MemOffs64_64AsmOperand>;
584 def SSECC : Operand<i8> {
585 let PrintMethod = "printSSEAVXCC";
586 let OperandType = "OPERAND_IMMEDIATE";
589 def i8immZExt3 : ImmLeaf<i8, [{
590 return Imm >= 0 && Imm < 8;
593 def AVXCC : Operand<i8> {
594 let PrintMethod = "printSSEAVXCC";
595 let OperandType = "OPERAND_IMMEDIATE";
598 def i8immZExt5 : ImmLeaf<i8, [{
599 return Imm >= 0 && Imm < 32;
602 def AVX512ICC : Operand<i8> {
603 let PrintMethod = "printSSEAVXCC";
604 let OperandType = "OPERAND_IMMEDIATE";
607 def XOPCC : Operand<i8> {
608 let PrintMethod = "printXOPCC";
609 let OperandType = "OPERAND_IMMEDIATE";
612 class ImmSExtAsmOperandClass : AsmOperandClass {
613 let SuperClasses = [ImmAsmOperand];
614 let RenderMethod = "addImmOperands";
617 def X86GR32orGR64AsmOperand : AsmOperandClass {
618 let Name = "GR32orGR64";
621 def GR32orGR64 : RegisterOperand<GR32> {
622 let ParserMatchClass = X86GR32orGR64AsmOperand;
624 def AVX512RCOperand : AsmOperandClass {
625 let Name = "AVX512RC";
627 def AVX512RC : Operand<i32> {
628 let PrintMethod = "printRoundingControl";
629 let OperandType = "OPERAND_IMMEDIATE";
630 let ParserMatchClass = AVX512RCOperand;
633 // Sign-extended immediate classes. We don't need to define the full lattice
634 // here because there is no instruction with an ambiguity between ImmSExti64i32
637 // The strange ranges come from the fact that the assembler always works with
638 // 64-bit immediates, but for a 16-bit target value we want to accept both "-1"
639 // (which will be a -1ULL), and "0xFF" (-1 in 16-bits).
642 // [0xFFFFFFFF80000000, 0xFFFFFFFFFFFFFFFF]
643 def ImmSExti64i32AsmOperand : ImmSExtAsmOperandClass {
644 let Name = "ImmSExti64i32";
647 // [0, 0x0000007F] | [0x000000000000FF80, 0x000000000000FFFF] |
648 // [0xFFFFFFFFFFFFFF80, 0xFFFFFFFFFFFFFFFF]
649 def ImmSExti16i8AsmOperand : ImmSExtAsmOperandClass {
650 let Name = "ImmSExti16i8";
651 let SuperClasses = [ImmSExti64i32AsmOperand];
654 // [0, 0x0000007F] | [0x00000000FFFFFF80, 0x00000000FFFFFFFF] |
655 // [0xFFFFFFFFFFFFFF80, 0xFFFFFFFFFFFFFFFF]
656 def ImmSExti32i8AsmOperand : ImmSExtAsmOperandClass {
657 let Name = "ImmSExti32i8";
661 // [0xFFFFFFFFFFFFFF80, 0xFFFFFFFFFFFFFFFF]
662 def ImmSExti64i8AsmOperand : ImmSExtAsmOperandClass {
663 let Name = "ImmSExti64i8";
664 let SuperClasses = [ImmSExti16i8AsmOperand, ImmSExti32i8AsmOperand,
665 ImmSExti64i32AsmOperand];
668 // Unsigned immediate used by SSE/AVX instructions
670 // [0xFFFFFFFFFFFFFF80, 0xFFFFFFFFFFFFFFFF]
671 def ImmUnsignedi8AsmOperand : AsmOperandClass {
672 let Name = "ImmUnsignedi8";
673 let RenderMethod = "addImmOperands";
676 // A couple of more descriptive operand definitions.
677 // 16-bits but only 8 bits are significant.
678 def i16i8imm : Operand<i16> {
679 let ParserMatchClass = ImmSExti16i8AsmOperand;
680 let OperandType = "OPERAND_IMMEDIATE";
682 // 32-bits but only 8 bits are significant.
683 def i32i8imm : Operand<i32> {
684 let ParserMatchClass = ImmSExti32i8AsmOperand;
685 let OperandType = "OPERAND_IMMEDIATE";
688 // 64-bits but only 32 bits are significant.
689 def i64i32imm : Operand<i64> {
690 let ParserMatchClass = ImmSExti64i32AsmOperand;
691 let OperandType = "OPERAND_IMMEDIATE";
694 // 64-bits but only 8 bits are significant.
695 def i64i8imm : Operand<i64> {
696 let ParserMatchClass = ImmSExti64i8AsmOperand;
697 let OperandType = "OPERAND_IMMEDIATE";
700 // Unsigned 8-bit immediate used by SSE/AVX instructions.
701 def u8imm : Operand<i8> {
702 let PrintMethod = "printU8Imm";
703 let ParserMatchClass = ImmUnsignedi8AsmOperand;
704 let OperandType = "OPERAND_IMMEDIATE";
707 // 32-bit immediate but only 8-bits are significant and they are unsigned.
708 // Used by some SSE/AVX instructions that use intrinsics.
709 def i32u8imm : Operand<i32> {
710 let PrintMethod = "printU8Imm";
711 let ParserMatchClass = ImmUnsignedi8AsmOperand;
712 let OperandType = "OPERAND_IMMEDIATE";
715 // 64-bits but only 32 bits are significant, and those bits are treated as being
717 def i64i32imm_pcrel : Operand<i64> {
718 let PrintMethod = "printPCRelImm";
719 let ParserMatchClass = X86AbsMemAsmOperand;
720 let OperandType = "OPERAND_PCREL";
723 def lea64_32mem : Operand<i32> {
724 let PrintMethod = "printanymem";
725 let MIOperandInfo = (ops GR64, i8imm, GR64_NOSP, i32imm, SEGMENT_REG);
726 let ParserMatchClass = X86MemAsmOperand;
729 // Memory operands that use 64-bit pointers in both ILP32 and LP64.
730 def lea64mem : Operand<i64> {
731 let PrintMethod = "printanymem";
732 let MIOperandInfo = (ops GR64, i8imm, GR64_NOSP, i32imm, SEGMENT_REG);
733 let ParserMatchClass = X86MemAsmOperand;
737 //===----------------------------------------------------------------------===//
738 // X86 Complex Pattern Definitions.
741 // Define X86-specific addressing mode.
742 def addr : ComplexPattern<iPTR, 5, "selectAddr", [], [SDNPWantParent]>;
743 def lea32addr : ComplexPattern<i32, 5, "selectLEAAddr",
744 [add, sub, mul, X86mul_imm, shl, or, frameindex],
746 // In 64-bit mode 32-bit LEAs can use RIP-relative addressing.
747 def lea64_32addr : ComplexPattern<i32, 5, "selectLEA64_32Addr",
748 [add, sub, mul, X86mul_imm, shl, or,
749 frameindex, X86WrapperRIP],
752 def tls32addr : ComplexPattern<i32, 5, "selectTLSADDRAddr",
753 [tglobaltlsaddr], []>;
755 def tls32baseaddr : ComplexPattern<i32, 5, "selectTLSADDRAddr",
756 [tglobaltlsaddr], []>;
758 def lea64addr : ComplexPattern<i64, 5, "selectLEAAddr",
759 [add, sub, mul, X86mul_imm, shl, or, frameindex,
762 def tls64addr : ComplexPattern<i64, 5, "selectTLSADDRAddr",
763 [tglobaltlsaddr], []>;
765 def tls64baseaddr : ComplexPattern<i64, 5, "selectTLSADDRAddr",
766 [tglobaltlsaddr], []>;
768 def vectoraddr : ComplexPattern<iPTR, 5, "selectVectorAddr", [],[SDNPWantParent]>;
770 // A relocatable immediate is either an immediate operand or an operand that can
771 // be relocated by the linker to an immediate, such as a regular symbol in
773 def relocImm : ComplexPattern<iAny, 1, "selectRelocImm", [imm, X86Wrapper], [],
776 //===----------------------------------------------------------------------===//
777 // X86 Instruction Predicate Definitions.
778 def TruePredicate : Predicate<"true">;
780 def HasCMov : Predicate<"Subtarget->hasCMov()">;
781 def NoCMov : Predicate<"!Subtarget->hasCMov()">;
783 def HasMMX : Predicate<"Subtarget->hasMMX()">;
784 def Has3DNow : Predicate<"Subtarget->has3DNow()">;
785 def Has3DNowA : Predicate<"Subtarget->has3DNowA()">;
786 def HasSSE1 : Predicate<"Subtarget->hasSSE1()">;
787 def UseSSE1 : Predicate<"Subtarget->hasSSE1() && !Subtarget->hasAVX()">;
788 def HasSSE2 : Predicate<"Subtarget->hasSSE2()">;
789 def UseSSE2 : Predicate<"Subtarget->hasSSE2() && !Subtarget->hasAVX()">;
790 def HasSSE3 : Predicate<"Subtarget->hasSSE3()">;
791 def UseSSE3 : Predicate<"Subtarget->hasSSE3() && !Subtarget->hasAVX()">;
792 def HasSSSE3 : Predicate<"Subtarget->hasSSSE3()">;
793 def UseSSSE3 : Predicate<"Subtarget->hasSSSE3() && !Subtarget->hasAVX()">;
794 def HasSSE41 : Predicate<"Subtarget->hasSSE41()">;
795 def NoSSE41 : Predicate<"!Subtarget->hasSSE41()">;
796 def UseSSE41 : Predicate<"Subtarget->hasSSE41() && !Subtarget->hasAVX()">;
797 def HasSSE42 : Predicate<"Subtarget->hasSSE42()">;
798 def UseSSE42 : Predicate<"Subtarget->hasSSE42() && !Subtarget->hasAVX()">;
799 def HasSSE4A : Predicate<"Subtarget->hasSSE4A()">;
800 def HasAVX : Predicate<"Subtarget->hasAVX()">;
801 def HasAVX2 : Predicate<"Subtarget->hasAVX2()">;
802 def HasAVX1Only : Predicate<"Subtarget->hasAVX() && !Subtarget->hasAVX2()">;
803 def HasAVX512 : Predicate<"Subtarget->hasAVX512()">,
804 AssemblerPredicate<"FeatureAVX512", "AVX-512 ISA">;
805 def UseAVX : Predicate<"Subtarget->hasAVX() && !Subtarget->hasAVX512()">;
806 def UseAVX2 : Predicate<"Subtarget->hasAVX2() && !Subtarget->hasAVX512()">;
807 def NoAVX512 : Predicate<"!Subtarget->hasAVX512()">;
808 def HasCDI : Predicate<"Subtarget->hasCDI()">,
809 AssemblerPredicate<"FeatureCDI", "AVX-512 CD ISA">;
810 def HasPFI : Predicate<"Subtarget->hasPFI()">,
811 AssemblerPredicate<"FeaturePFI", "AVX-512 PF ISA">;
812 def HasERI : Predicate<"Subtarget->hasERI()">,
813 AssemblerPredicate<"FeatureERI", "AVX-512 ER ISA">;
814 def HasDQI : Predicate<"Subtarget->hasDQI()">,
815 AssemblerPredicate<"FeatureDQI", "AVX-512 DQ ISA">;
816 def NoDQI : Predicate<"!Subtarget->hasDQI()">;
817 def HasBWI : Predicate<"Subtarget->hasBWI()">,
818 AssemblerPredicate<"FeatureBWI", "AVX-512 BW ISA">;
819 def NoBWI : Predicate<"!Subtarget->hasBWI()">;
820 def HasVLX : Predicate<"Subtarget->hasVLX()">,
821 AssemblerPredicate<"FeatureVLX", "AVX-512 VL ISA">;
822 def NoVLX : Predicate<"!Subtarget->hasVLX()">;
823 def NoVLX_Or_NoBWI : Predicate<"!Subtarget->hasVLX() || !Subtarget->hasBWI()">;
824 def NoVLX_Or_NoDQI : Predicate<"!Subtarget->hasVLX() || !Subtarget->hasDQI()">;
825 def PKU : Predicate<"Subtarget->hasPKU()">;
827 def HasPOPCNT : Predicate<"Subtarget->hasPOPCNT()">;
828 def HasAES : Predicate<"Subtarget->hasAES()">;
829 def HasFXSR : Predicate<"Subtarget->hasFXSR()">;
830 def HasXSAVE : Predicate<"Subtarget->hasXSAVE()">;
831 def HasXSAVEOPT : Predicate<"Subtarget->hasXSAVEOPT()">;
832 def HasXSAVEC : Predicate<"Subtarget->hasXSAVEC()">;
833 def HasXSAVES : Predicate<"Subtarget->hasXSAVES()">;
834 def HasPCLMUL : Predicate<"Subtarget->hasPCLMUL()">;
835 def HasFMA : Predicate<"Subtarget->hasFMA()">;
836 def HasFMA4 : Predicate<"Subtarget->hasFMA4()">;
837 def HasXOP : Predicate<"Subtarget->hasXOP()">;
838 def HasTBM : Predicate<"Subtarget->hasTBM()">;
839 def HasMOVBE : Predicate<"Subtarget->hasMOVBE()">;
840 def HasRDRAND : Predicate<"Subtarget->hasRDRAND()">;
841 def HasF16C : Predicate<"Subtarget->hasF16C()">;
842 def NoF16C : Predicate<"!Subtarget->hasF16C()">;
843 def HasFSGSBase : Predicate<"Subtarget->hasFSGSBase()">;
844 def HasLZCNT : Predicate<"Subtarget->hasLZCNT()">;
845 def HasBMI : Predicate<"Subtarget->hasBMI()">;
846 def HasBMI2 : Predicate<"Subtarget->hasBMI2()">;
847 def HasVBMI : Predicate<"Subtarget->hasVBMI()">,
848 AssemblerPredicate<"FeatureVBMI", "AVX-512 VBMI ISA">;
849 def HasIFMA : Predicate<"Subtarget->hasIFMA()">,
850 AssemblerPredicate<"FeatureIFMA", "AVX-512 IFMA ISA">;
851 def HasRTM : Predicate<"Subtarget->hasRTM()">;
852 def HasADX : Predicate<"Subtarget->hasADX()">;
853 def HasSHA : Predicate<"Subtarget->hasSHA()">;
854 def HasPRFCHW : Predicate<"Subtarget->hasPRFCHW()">;
855 def HasRDSEED : Predicate<"Subtarget->hasRDSEED()">;
856 def HasPrefetchW : Predicate<"Subtarget->hasPRFCHW()">;
857 def HasLAHFSAHF : Predicate<"Subtarget->hasLAHFSAHF()">;
858 def HasMWAITX : Predicate<"Subtarget->hasMWAITX()">;
859 def HasCLZERO : Predicate<"Subtarget->hasCLZERO()">;
860 def FPStackf32 : Predicate<"!Subtarget->hasSSE1()">;
861 def FPStackf64 : Predicate<"!Subtarget->hasSSE2()">;
862 def HasMPX : Predicate<"Subtarget->hasMPX()">;
863 def HasCLFLUSHOPT : Predicate<"Subtarget->hasCLFLUSHOPT()">;
864 def HasCmpxchg16b: Predicate<"Subtarget->hasCmpxchg16b()">;
865 def Not64BitMode : Predicate<"!Subtarget->is64Bit()">,
866 AssemblerPredicate<"!Mode64Bit", "Not 64-bit mode">;
867 def In64BitMode : Predicate<"Subtarget->is64Bit()">,
868 AssemblerPredicate<"Mode64Bit", "64-bit mode">;
869 def IsLP64 : Predicate<"Subtarget->isTarget64BitLP64()">;
870 def NotLP64 : Predicate<"!Subtarget->isTarget64BitLP64()">;
871 def In16BitMode : Predicate<"Subtarget->is16Bit()">,
872 AssemblerPredicate<"Mode16Bit", "16-bit mode">;
873 def Not16BitMode : Predicate<"!Subtarget->is16Bit()">,
874 AssemblerPredicate<"!Mode16Bit", "Not 16-bit mode">;
875 def In32BitMode : Predicate<"Subtarget->is32Bit()">,
876 AssemblerPredicate<"Mode32Bit", "32-bit mode">;
877 def IsWin64 : Predicate<"Subtarget->isTargetWin64()">;
878 def NotWin64 : Predicate<"!Subtarget->isTargetWin64()">;
879 def NotWin64WithoutFP : Predicate<"!Subtarget->isTargetWin64() ||"
880 "Subtarget->getFrameLowering()->hasFP(*MF)">;
881 def IsPS4 : Predicate<"Subtarget->isTargetPS4()">;
882 def NotPS4 : Predicate<"!Subtarget->isTargetPS4()">;
883 def IsNaCl : Predicate<"Subtarget->isTargetNaCl()">;
884 def NotNaCl : Predicate<"!Subtarget->isTargetNaCl()">;
885 def SmallCode : Predicate<"TM.getCodeModel() == CodeModel::Small">;
886 def KernelCode : Predicate<"TM.getCodeModel() == CodeModel::Kernel">;
887 def NearData : Predicate<"TM.getCodeModel() == CodeModel::Small ||"
888 "TM.getCodeModel() == CodeModel::Kernel">;
889 def IsNotPIC : Predicate<"!TM.isPositionIndependent()">;
890 def OptForSize : Predicate<"OptForSize">;
891 def OptForMinSize : Predicate<"OptForMinSize">;
892 def OptForSpeed : Predicate<"!OptForSize">;
893 def FastBTMem : Predicate<"!Subtarget->isBTMemSlow()">;
894 def CallImmAddr : Predicate<"Subtarget->isLegalToCallImmediateAddr()">;
895 def FavorMemIndirectCall : Predicate<"!Subtarget->callRegIndirect()">;
896 def NotSlowIncDec : Predicate<"!Subtarget->slowIncDec()">;
897 def HasFastMem32 : Predicate<"!Subtarget->isUnalignedMem32Slow()">;
898 def HasFastLZCNT : Predicate<"Subtarget->hasFastLZCNT()">;
899 def HasFastSHLDRotate : Predicate<"Subtarget->hasFastSHLDRotate()">;
900 def HasMFence : Predicate<"Subtarget->hasMFence()">;
902 //===----------------------------------------------------------------------===//
903 // X86 Instruction Format Definitions.
906 include "X86InstrFormats.td"
908 //===----------------------------------------------------------------------===//
909 // Pattern fragments.
912 // X86 specific condition code. These correspond to CondCode in
913 // X86InstrInfo.h. They must be kept in synch.
914 def X86_COND_A : PatLeaf<(i8 0)>; // alt. COND_NBE
915 def X86_COND_AE : PatLeaf<(i8 1)>; // alt. COND_NC
916 def X86_COND_B : PatLeaf<(i8 2)>; // alt. COND_C
917 def X86_COND_BE : PatLeaf<(i8 3)>; // alt. COND_NA
918 def X86_COND_E : PatLeaf<(i8 4)>; // alt. COND_Z
919 def X86_COND_G : PatLeaf<(i8 5)>; // alt. COND_NLE
920 def X86_COND_GE : PatLeaf<(i8 6)>; // alt. COND_NL
921 def X86_COND_L : PatLeaf<(i8 7)>; // alt. COND_NGE
922 def X86_COND_LE : PatLeaf<(i8 8)>; // alt. COND_NG
923 def X86_COND_NE : PatLeaf<(i8 9)>; // alt. COND_NZ
924 def X86_COND_NO : PatLeaf<(i8 10)>;
925 def X86_COND_NP : PatLeaf<(i8 11)>; // alt. COND_PO
926 def X86_COND_NS : PatLeaf<(i8 12)>;
927 def X86_COND_O : PatLeaf<(i8 13)>;
928 def X86_COND_P : PatLeaf<(i8 14)>; // alt. COND_PE
929 def X86_COND_S : PatLeaf<(i8 15)>;
931 def i16immSExt8 : ImmLeaf<i16, [{ return isInt<8>(Imm); }]>;
932 def i32immSExt8 : ImmLeaf<i32, [{ return isInt<8>(Imm); }]>;
933 def i64immSExt8 : ImmLeaf<i64, [{ return isInt<8>(Imm); }]>;
934 def i64immSExt32 : ImmLeaf<i64, [{ return isInt<32>(Imm); }]>;
936 // FIXME: Ideally we would just replace the above i*immSExt* matchers with
937 // relocImm-based matchers, but then FastISel would be unable to use them.
938 def i64relocImmSExt8 : PatLeaf<(i64 relocImm), [{
939 return isSExtRelocImm<8>(N);
941 def i64relocImmSExt32 : PatLeaf<(i64 relocImm), [{
942 return isSExtRelocImm<32>(N);
945 // If we have multiple users of an immediate, it's much smaller to reuse
946 // the register, rather than encode the immediate in every instruction.
947 // This has the risk of increasing register pressure from stretched live
948 // ranges, however, the immediates should be trivial to rematerialize by
949 // the RA in the event of high register pressure.
950 // TODO : This is currently enabled for stores and binary ops. There are more
951 // cases for which this can be enabled, though this catches the bulk of the
953 // TODO2 : This should really also be enabled under O2, but there's currently
954 // an issue with RA where we don't pull the constants into their users
955 // when we rematerialize them. I'll follow-up on enabling O2 after we fix that
957 // TODO3 : This is currently limited to single basic blocks (DAG creation
958 // pulls block immediates to the top and merges them if necessary).
959 // Eventually, it would be nice to allow ConstantHoisting to merge constants
960 // globally for potentially added savings.
962 def imm8_su : PatLeaf<(i8 relocImm), [{
963 return !shouldAvoidImmediateInstFormsForSize(N);
965 def imm16_su : PatLeaf<(i16 relocImm), [{
966 return !shouldAvoidImmediateInstFormsForSize(N);
968 def imm32_su : PatLeaf<(i32 relocImm), [{
969 return !shouldAvoidImmediateInstFormsForSize(N);
971 def i64immSExt32_su : PatLeaf<(i64immSExt32), [{
972 return !shouldAvoidImmediateInstFormsForSize(N);
975 def i16immSExt8_su : PatLeaf<(i16immSExt8), [{
976 return !shouldAvoidImmediateInstFormsForSize(N);
978 def i32immSExt8_su : PatLeaf<(i32immSExt8), [{
979 return !shouldAvoidImmediateInstFormsForSize(N);
981 def i64immSExt8_su : PatLeaf<(i64immSExt8), [{
982 return !shouldAvoidImmediateInstFormsForSize(N);
985 def i64relocImmSExt8_su : PatLeaf<(i64relocImmSExt8), [{
986 return !shouldAvoidImmediateInstFormsForSize(N);
988 def i64relocImmSExt32_su : PatLeaf<(i64relocImmSExt32), [{
989 return !shouldAvoidImmediateInstFormsForSize(N);
992 // i64immZExt32 predicate - True if the 64-bit immediate fits in a 32-bit
994 def i64immZExt32 : ImmLeaf<i64, [{ return isUInt<32>(Imm); }]>;
996 def i64immZExt32SExt8 : ImmLeaf<i64, [{
997 return isUInt<32>(Imm) && isInt<8>(static_cast<int32_t>(Imm));
1000 // Helper fragments for loads.
1001 // It's always safe to treat a anyext i16 load as a i32 load if the i16 is
1002 // known to be 32-bit aligned or better. Ditto for i8 to i16.
1003 def loadi16 : PatFrag<(ops node:$ptr), (i16 (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() >= 2 && !LD->isVolatile();
1013 def loadi16_anyext : PatFrag<(ops node:$ptr), (i32 (unindexedload node:$ptr)),[{
1014 LoadSDNode *LD = cast<LoadSDNode>(N);
1015 ISD::LoadExtType ExtType = LD->getExtensionType();
1016 if (ExtType == ISD::EXTLOAD)
1017 return LD->getAlignment() >= 2 && !LD->isVolatile();
1021 def loadi32 : PatFrag<(ops node:$ptr), (i32 (unindexedload node:$ptr)), [{
1022 LoadSDNode *LD = cast<LoadSDNode>(N);
1023 ISD::LoadExtType ExtType = LD->getExtensionType();
1024 if (ExtType == ISD::NON_EXTLOAD)
1026 if (ExtType == ISD::EXTLOAD)
1027 return LD->getAlignment() >= 4 && !LD->isVolatile();
1031 def loadi8 : PatFrag<(ops node:$ptr), (i8 (load node:$ptr))>;
1032 def loadi64 : PatFrag<(ops node:$ptr), (i64 (load node:$ptr))>;
1033 def loadf32 : PatFrag<(ops node:$ptr), (f32 (load node:$ptr))>;
1034 def loadf64 : PatFrag<(ops node:$ptr), (f64 (load node:$ptr))>;
1035 def loadf80 : PatFrag<(ops node:$ptr), (f80 (load node:$ptr))>;
1036 def loadf128 : PatFrag<(ops node:$ptr), (f128 (load node:$ptr))>;
1038 def sextloadi16i8 : PatFrag<(ops node:$ptr), (i16 (sextloadi8 node:$ptr))>;
1039 def sextloadi32i8 : PatFrag<(ops node:$ptr), (i32 (sextloadi8 node:$ptr))>;
1040 def sextloadi32i16 : PatFrag<(ops node:$ptr), (i32 (sextloadi16 node:$ptr))>;
1041 def sextloadi64i8 : PatFrag<(ops node:$ptr), (i64 (sextloadi8 node:$ptr))>;
1042 def sextloadi64i16 : PatFrag<(ops node:$ptr), (i64 (sextloadi16 node:$ptr))>;
1043 def sextloadi64i32 : PatFrag<(ops node:$ptr), (i64 (sextloadi32 node:$ptr))>;
1045 def zextloadi8i1 : PatFrag<(ops node:$ptr), (i8 (zextloadi1 node:$ptr))>;
1046 def zextloadi16i1 : PatFrag<(ops node:$ptr), (i16 (zextloadi1 node:$ptr))>;
1047 def zextloadi32i1 : PatFrag<(ops node:$ptr), (i32 (zextloadi1 node:$ptr))>;
1048 def zextloadi16i8 : PatFrag<(ops node:$ptr), (i16 (zextloadi8 node:$ptr))>;
1049 def zextloadi32i8 : PatFrag<(ops node:$ptr), (i32 (zextloadi8 node:$ptr))>;
1050 def zextloadi32i16 : PatFrag<(ops node:$ptr), (i32 (zextloadi16 node:$ptr))>;
1051 def zextloadi64i1 : PatFrag<(ops node:$ptr), (i64 (zextloadi1 node:$ptr))>;
1052 def zextloadi64i8 : PatFrag<(ops node:$ptr), (i64 (zextloadi8 node:$ptr))>;
1053 def zextloadi64i16 : PatFrag<(ops node:$ptr), (i64 (zextloadi16 node:$ptr))>;
1054 def zextloadi64i32 : PatFrag<(ops node:$ptr), (i64 (zextloadi32 node:$ptr))>;
1056 def extloadi8i1 : PatFrag<(ops node:$ptr), (i8 (extloadi1 node:$ptr))>;
1057 def extloadi16i1 : PatFrag<(ops node:$ptr), (i16 (extloadi1 node:$ptr))>;
1058 def extloadi32i1 : PatFrag<(ops node:$ptr), (i32 (extloadi1 node:$ptr))>;
1059 def extloadi16i8 : PatFrag<(ops node:$ptr), (i16 (extloadi8 node:$ptr))>;
1060 def extloadi32i8 : PatFrag<(ops node:$ptr), (i32 (extloadi8 node:$ptr))>;
1061 def extloadi32i16 : PatFrag<(ops node:$ptr), (i32 (extloadi16 node:$ptr))>;
1062 def extloadi64i1 : PatFrag<(ops node:$ptr), (i64 (extloadi1 node:$ptr))>;
1063 def extloadi64i8 : PatFrag<(ops node:$ptr), (i64 (extloadi8 node:$ptr))>;
1064 def extloadi64i16 : PatFrag<(ops node:$ptr), (i64 (extloadi16 node:$ptr))>;
1065 def extloadi64i32 : PatFrag<(ops node:$ptr), (i64 (extloadi32 node:$ptr))>;
1068 // An 'and' node with a single use.
1069 def and_su : PatFrag<(ops node:$lhs, node:$rhs), (and node:$lhs, node:$rhs), [{
1070 return N->hasOneUse();
1072 // An 'srl' node with a single use.
1073 def srl_su : PatFrag<(ops node:$lhs, node:$rhs), (srl node:$lhs, node:$rhs), [{
1074 return N->hasOneUse();
1076 // An 'trunc' node with a single use.
1077 def trunc_su : PatFrag<(ops node:$src), (trunc node:$src), [{
1078 return N->hasOneUse();
1081 //===----------------------------------------------------------------------===//
1082 // Instruction list.
1086 let hasSideEffects = 0, SchedRW = [WriteZero] in {
1087 def NOOP : I<0x90, RawFrm, (outs), (ins), "nop", [], IIC_NOP>;
1088 def NOOPW : I<0x1f, MRMXm, (outs), (ins i16mem:$zero),
1089 "nop{w}\t$zero", [], IIC_NOP>, TB, OpSize16;
1090 def NOOPL : I<0x1f, MRMXm, (outs), (ins i32mem:$zero),
1091 "nop{l}\t$zero", [], IIC_NOP>, TB, OpSize32;
1095 // Constructing a stack frame.
1096 def ENTER : Ii16<0xC8, RawFrmImm8, (outs), (ins i16imm:$len, i8imm:$lvl),
1097 "enter\t$len, $lvl", [], IIC_ENTER>, Sched<[WriteMicrocoded]>;
1099 let SchedRW = [WriteALU] in {
1100 let Defs = [EBP, ESP], Uses = [EBP, ESP], mayLoad = 1, hasSideEffects=0 in
1101 def LEAVE : I<0xC9, RawFrm,
1102 (outs), (ins), "leave", [], IIC_LEAVE>,
1103 Requires<[Not64BitMode]>;
1105 let Defs = [RBP,RSP], Uses = [RBP,RSP], mayLoad = 1, hasSideEffects = 0 in
1106 def LEAVE64 : I<0xC9, RawFrm,
1107 (outs), (ins), "leave", [], IIC_LEAVE>,
1108 Requires<[In64BitMode]>;
1111 //===----------------------------------------------------------------------===//
1112 // Miscellaneous Instructions.
1115 let isBarrier = 1, hasSideEffects = 1, usesCustomInserter = 1 in
1116 def Int_eh_sjlj_setup_dispatch
1117 : PseudoI<(outs), (ins), [(X86eh_sjlj_setup_dispatch)]>;
1119 let Defs = [ESP], Uses = [ESP], hasSideEffects=0 in {
1120 let mayLoad = 1, SchedRW = [WriteLoad] in {
1121 def POP16r : I<0x58, AddRegFrm, (outs GR16:$reg), (ins), "pop{w}\t$reg", [],
1122 IIC_POP_REG16>, OpSize16;
1123 def POP32r : I<0x58, AddRegFrm, (outs GR32:$reg), (ins), "pop{l}\t$reg", [],
1124 IIC_POP_REG>, OpSize32, Requires<[Not64BitMode]>;
1125 def POP16rmr: I<0x8F, MRM0r, (outs GR16:$reg), (ins), "pop{w}\t$reg", [],
1126 IIC_POP_REG>, OpSize16;
1127 def POP32rmr: I<0x8F, MRM0r, (outs GR32:$reg), (ins), "pop{l}\t$reg", [],
1128 IIC_POP_REG>, OpSize32, Requires<[Not64BitMode]>;
1129 } // mayLoad, SchedRW
1130 let mayStore = 1, mayLoad = 1, SchedRW = [WriteRMW] in {
1131 def POP16rmm: I<0x8F, MRM0m, (outs), (ins i16mem:$dst), "pop{w}\t$dst", [],
1132 IIC_POP_MEM>, OpSize16;
1133 def POP32rmm: I<0x8F, MRM0m, (outs), (ins i32mem:$dst), "pop{l}\t$dst", [],
1134 IIC_POP_MEM>, OpSize32, Requires<[Not64BitMode]>;
1135 } // mayStore, mayLoad, WriteRMW
1137 let mayStore = 1, SchedRW = [WriteStore] in {
1138 def PUSH16r : I<0x50, AddRegFrm, (outs), (ins GR16:$reg), "push{w}\t$reg",[],
1139 IIC_PUSH_REG>, OpSize16;
1140 def PUSH32r : I<0x50, AddRegFrm, (outs), (ins GR32:$reg), "push{l}\t$reg",[],
1141 IIC_PUSH_REG>, OpSize32, Requires<[Not64BitMode]>;
1142 def PUSH16rmr: I<0xFF, MRM6r, (outs), (ins GR16:$reg), "push{w}\t$reg",[],
1143 IIC_PUSH_REG>, OpSize16;
1144 def PUSH32rmr: I<0xFF, MRM6r, (outs), (ins GR32:$reg), "push{l}\t$reg",[],
1145 IIC_PUSH_REG>, OpSize32, Requires<[Not64BitMode]>;
1147 def PUSH16i8 : Ii8<0x6a, RawFrm, (outs), (ins i16i8imm:$imm),
1148 "push{w}\t$imm", [], IIC_PUSH_IMM>, OpSize16;
1149 def PUSHi16 : Ii16<0x68, RawFrm, (outs), (ins i16imm:$imm),
1150 "push{w}\t$imm", [], IIC_PUSH_IMM>, OpSize16;
1152 def PUSH32i8 : Ii8<0x6a, RawFrm, (outs), (ins i32i8imm:$imm),
1153 "push{l}\t$imm", [], IIC_PUSH_IMM>, OpSize32,
1154 Requires<[Not64BitMode]>;
1155 def PUSHi32 : Ii32<0x68, RawFrm, (outs), (ins i32imm:$imm),
1156 "push{l}\t$imm", [], IIC_PUSH_IMM>, OpSize32,
1157 Requires<[Not64BitMode]>;
1158 } // mayStore, SchedRW
1160 let mayLoad = 1, mayStore = 1, SchedRW = [WriteRMW] in {
1161 def PUSH16rmm: I<0xFF, MRM6m, (outs), (ins i16mem:$src), "push{w}\t$src",[],
1162 IIC_PUSH_MEM>, OpSize16;
1163 def PUSH32rmm: I<0xFF, MRM6m, (outs), (ins i32mem:$src), "push{l}\t$src",[],
1164 IIC_PUSH_MEM>, OpSize32, Requires<[Not64BitMode]>;
1165 } // mayLoad, mayStore, SchedRW
1169 let mayLoad = 1, mayStore = 1, usesCustomInserter = 1,
1170 SchedRW = [WriteRMW], Defs = [ESP] in {
1172 def RDFLAGS32 : PseudoI<(outs GR32:$dst), (ins),
1173 [(set GR32:$dst, (int_x86_flags_read_u32))]>,
1174 Requires<[Not64BitMode]>;
1177 def RDFLAGS64 : PseudoI<(outs GR64:$dst), (ins),
1178 [(set GR64:$dst, (int_x86_flags_read_u64))]>,
1179 Requires<[In64BitMode]>;
1182 let mayLoad = 1, mayStore = 1, usesCustomInserter = 1,
1183 SchedRW = [WriteRMW] in {
1184 let Defs = [ESP, EFLAGS], Uses = [ESP] in
1185 def WRFLAGS32 : PseudoI<(outs), (ins GR32:$src),
1186 [(int_x86_flags_write_u32 GR32:$src)]>,
1187 Requires<[Not64BitMode]>;
1189 let Defs = [RSP, EFLAGS], Uses = [RSP] in
1190 def WRFLAGS64 : PseudoI<(outs), (ins GR64:$src),
1191 [(int_x86_flags_write_u64 GR64:$src)]>,
1192 Requires<[In64BitMode]>;
1195 let Defs = [ESP, EFLAGS], Uses = [ESP], mayLoad = 1, hasSideEffects=0,
1196 SchedRW = [WriteLoad] in {
1197 def POPF16 : I<0x9D, RawFrm, (outs), (ins), "popf{w}", [], IIC_POP_F>,
1199 def POPF32 : I<0x9D, RawFrm, (outs), (ins), "popf{l|d}", [], IIC_POP_FD>,
1200 OpSize32, Requires<[Not64BitMode]>;
1203 let Defs = [ESP], Uses = [ESP, EFLAGS], mayStore = 1, hasSideEffects=0,
1204 SchedRW = [WriteStore] in {
1205 def PUSHF16 : I<0x9C, RawFrm, (outs), (ins), "pushf{w}", [], IIC_PUSH_F>,
1207 def PUSHF32 : I<0x9C, RawFrm, (outs), (ins), "pushf{l|d}", [], IIC_PUSH_F>,
1208 OpSize32, Requires<[Not64BitMode]>;
1211 let Defs = [RSP], Uses = [RSP], hasSideEffects=0 in {
1212 let mayLoad = 1, SchedRW = [WriteLoad] in {
1213 def POP64r : I<0x58, AddRegFrm, (outs GR64:$reg), (ins), "pop{q}\t$reg", [],
1214 IIC_POP_REG>, OpSize32, Requires<[In64BitMode]>;
1215 def POP64rmr: I<0x8F, MRM0r, (outs GR64:$reg), (ins), "pop{q}\t$reg", [],
1216 IIC_POP_REG>, OpSize32, Requires<[In64BitMode]>;
1217 } // mayLoad, SchedRW
1218 let mayLoad = 1, mayStore = 1, SchedRW = [WriteRMW] in
1219 def POP64rmm: I<0x8F, MRM0m, (outs), (ins i64mem:$dst), "pop{q}\t$dst", [],
1220 IIC_POP_MEM>, OpSize32, Requires<[In64BitMode]>;
1221 let mayStore = 1, SchedRW = [WriteStore] in {
1222 def PUSH64r : I<0x50, AddRegFrm, (outs), (ins GR64:$reg), "push{q}\t$reg", [],
1223 IIC_PUSH_REG>, OpSize32, Requires<[In64BitMode]>;
1224 def PUSH64rmr: I<0xFF, MRM6r, (outs), (ins GR64:$reg), "push{q}\t$reg", [],
1225 IIC_PUSH_REG>, OpSize32, Requires<[In64BitMode]>;
1226 } // mayStore, SchedRW
1227 let mayLoad = 1, mayStore = 1, SchedRW = [WriteRMW] in {
1228 def PUSH64rmm: I<0xFF, MRM6m, (outs), (ins i64mem:$src), "push{q}\t$src", [],
1229 IIC_PUSH_MEM>, OpSize32, Requires<[In64BitMode]>;
1230 } // mayLoad, mayStore, SchedRW
1233 let Defs = [RSP], Uses = [RSP], hasSideEffects = 0, mayStore = 1,
1234 SchedRW = [WriteStore] in {
1235 def PUSH64i8 : Ii8<0x6a, RawFrm, (outs), (ins i64i8imm:$imm),
1236 "push{q}\t$imm", [], IIC_PUSH_IMM>, OpSize32,
1237 Requires<[In64BitMode]>;
1238 def PUSH64i32 : Ii32S<0x68, RawFrm, (outs), (ins i64i32imm:$imm),
1239 "push{q}\t$imm", [], IIC_PUSH_IMM>, OpSize32,
1240 Requires<[In64BitMode]>;
1243 let Defs = [RSP, EFLAGS], Uses = [RSP], mayLoad = 1, hasSideEffects=0 in
1244 def POPF64 : I<0x9D, RawFrm, (outs), (ins), "popfq", [], IIC_POP_FD>,
1245 OpSize32, Requires<[In64BitMode]>, Sched<[WriteLoad]>;
1246 let Defs = [RSP], Uses = [RSP, EFLAGS], mayStore = 1, hasSideEffects=0 in
1247 def PUSHF64 : I<0x9C, RawFrm, (outs), (ins), "pushfq", [], IIC_PUSH_F>,
1248 OpSize32, Requires<[In64BitMode]>, Sched<[WriteStore]>;
1250 let Defs = [EDI, ESI, EBP, EBX, EDX, ECX, EAX, ESP], Uses = [ESP],
1251 mayLoad = 1, hasSideEffects = 0, SchedRW = [WriteLoad] in {
1252 def POPA32 : I<0x61, RawFrm, (outs), (ins), "popal", [], IIC_POP_A>,
1253 OpSize32, Requires<[Not64BitMode]>;
1254 def POPA16 : I<0x61, RawFrm, (outs), (ins), "popaw", [], IIC_POP_A>,
1255 OpSize16, Requires<[Not64BitMode]>;
1257 let Defs = [ESP], Uses = [EDI, ESI, EBP, EBX, EDX, ECX, EAX, ESP],
1258 mayStore = 1, hasSideEffects = 0, SchedRW = [WriteStore] in {
1259 def PUSHA32 : I<0x60, RawFrm, (outs), (ins), "pushal", [], IIC_PUSH_A>,
1260 OpSize32, Requires<[Not64BitMode]>;
1261 def PUSHA16 : I<0x60, RawFrm, (outs), (ins), "pushaw", [], IIC_PUSH_A>,
1262 OpSize16, Requires<[Not64BitMode]>;
1265 let Constraints = "$src = $dst", SchedRW = [WriteALU] in {
1266 // GR32 = bswap GR32
1267 def BSWAP32r : I<0xC8, AddRegFrm,
1268 (outs GR32:$dst), (ins GR32:$src),
1270 [(set GR32:$dst, (bswap GR32:$src))], IIC_BSWAP>, OpSize32, TB;
1272 def BSWAP64r : RI<0xC8, AddRegFrm, (outs GR64:$dst), (ins GR64:$src),
1274 [(set GR64:$dst, (bswap GR64:$src))], IIC_BSWAP>, TB;
1275 } // Constraints = "$src = $dst", SchedRW
1277 // Bit scan instructions.
1278 let Defs = [EFLAGS] in {
1279 def BSF16rr : I<0xBC, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
1280 "bsf{w}\t{$src, $dst|$dst, $src}",
1281 [(set GR16:$dst, EFLAGS, (X86bsf GR16:$src))],
1282 IIC_BIT_SCAN_REG>, PS, OpSize16, Sched<[WriteShift]>;
1283 def BSF16rm : I<0xBC, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
1284 "bsf{w}\t{$src, $dst|$dst, $src}",
1285 [(set GR16:$dst, EFLAGS, (X86bsf (loadi16 addr:$src)))],
1286 IIC_BIT_SCAN_MEM>, PS, OpSize16, Sched<[WriteShiftLd]>;
1287 def BSF32rr : I<0xBC, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
1288 "bsf{l}\t{$src, $dst|$dst, $src}",
1289 [(set GR32:$dst, EFLAGS, (X86bsf GR32:$src))],
1290 IIC_BIT_SCAN_REG>, PS, OpSize32, Sched<[WriteShift]>;
1291 def BSF32rm : I<0xBC, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
1292 "bsf{l}\t{$src, $dst|$dst, $src}",
1293 [(set GR32:$dst, EFLAGS, (X86bsf (loadi32 addr:$src)))],
1294 IIC_BIT_SCAN_MEM>, PS, OpSize32, Sched<[WriteShiftLd]>;
1295 def BSF64rr : RI<0xBC, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
1296 "bsf{q}\t{$src, $dst|$dst, $src}",
1297 [(set GR64:$dst, EFLAGS, (X86bsf GR64:$src))],
1298 IIC_BIT_SCAN_REG>, PS, Sched<[WriteShift]>;
1299 def BSF64rm : RI<0xBC, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
1300 "bsf{q}\t{$src, $dst|$dst, $src}",
1301 [(set GR64:$dst, EFLAGS, (X86bsf (loadi64 addr:$src)))],
1302 IIC_BIT_SCAN_MEM>, PS, Sched<[WriteShiftLd]>;
1304 def BSR16rr : I<0xBD, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
1305 "bsr{w}\t{$src, $dst|$dst, $src}",
1306 [(set GR16:$dst, EFLAGS, (X86bsr GR16:$src))],
1307 IIC_BIT_SCAN_REG>, PS, OpSize16, Sched<[WriteShift]>;
1308 def BSR16rm : I<0xBD, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
1309 "bsr{w}\t{$src, $dst|$dst, $src}",
1310 [(set GR16:$dst, EFLAGS, (X86bsr (loadi16 addr:$src)))],
1311 IIC_BIT_SCAN_MEM>, PS, OpSize16, Sched<[WriteShiftLd]>;
1312 def BSR32rr : I<0xBD, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
1313 "bsr{l}\t{$src, $dst|$dst, $src}",
1314 [(set GR32:$dst, EFLAGS, (X86bsr GR32:$src))],
1315 IIC_BIT_SCAN_REG>, PS, OpSize32, Sched<[WriteShift]>;
1316 def BSR32rm : I<0xBD, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
1317 "bsr{l}\t{$src, $dst|$dst, $src}",
1318 [(set GR32:$dst, EFLAGS, (X86bsr (loadi32 addr:$src)))],
1319 IIC_BIT_SCAN_MEM>, PS, OpSize32, Sched<[WriteShiftLd]>;
1320 def BSR64rr : RI<0xBD, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
1321 "bsr{q}\t{$src, $dst|$dst, $src}",
1322 [(set GR64:$dst, EFLAGS, (X86bsr GR64:$src))],
1323 IIC_BIT_SCAN_REG>, PS, Sched<[WriteShift]>;
1324 def BSR64rm : RI<0xBD, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
1325 "bsr{q}\t{$src, $dst|$dst, $src}",
1326 [(set GR64:$dst, EFLAGS, (X86bsr (loadi64 addr:$src)))],
1327 IIC_BIT_SCAN_MEM>, PS, Sched<[WriteShiftLd]>;
1328 } // Defs = [EFLAGS]
1330 let SchedRW = [WriteMicrocoded] in {
1331 // These uses the DF flag in the EFLAGS register to inc or dec EDI and ESI
1332 let Defs = [EDI,ESI], Uses = [EDI,ESI,EFLAGS] in {
1333 def MOVSB : I<0xA4, RawFrmDstSrc, (outs), (ins dstidx8:$dst, srcidx8:$src),
1334 "movsb\t{$src, $dst|$dst, $src}", [], IIC_MOVS>;
1335 def MOVSW : I<0xA5, RawFrmDstSrc, (outs), (ins dstidx16:$dst, srcidx16:$src),
1336 "movsw\t{$src, $dst|$dst, $src}", [], IIC_MOVS>, OpSize16;
1337 def MOVSL : I<0xA5, RawFrmDstSrc, (outs), (ins dstidx32:$dst, srcidx32:$src),
1338 "movs{l|d}\t{$src, $dst|$dst, $src}", [], IIC_MOVS>, OpSize32;
1339 def MOVSQ : RI<0xA5, RawFrmDstSrc, (outs), (ins dstidx64:$dst, srcidx64:$src),
1340 "movsq\t{$src, $dst|$dst, $src}", [], IIC_MOVS>;
1343 // These uses the DF flag in the EFLAGS register to inc or dec EDI and ESI
1344 let Defs = [EDI], Uses = [AL,EDI,EFLAGS] in
1345 def STOSB : I<0xAA, RawFrmDst, (outs), (ins dstidx8:$dst),
1346 "stosb\t{%al, $dst|$dst, al}", [], IIC_STOS>;
1347 let Defs = [EDI], Uses = [AX,EDI,EFLAGS] in
1348 def STOSW : I<0xAB, RawFrmDst, (outs), (ins dstidx16:$dst),
1349 "stosw\t{%ax, $dst|$dst, ax}", [], IIC_STOS>, OpSize16;
1350 let Defs = [EDI], Uses = [EAX,EDI,EFLAGS] in
1351 def STOSL : I<0xAB, RawFrmDst, (outs), (ins dstidx32:$dst),
1352 "stos{l|d}\t{%eax, $dst|$dst, eax}", [], IIC_STOS>, OpSize32;
1353 let Defs = [RDI], Uses = [RAX,RDI,EFLAGS] in
1354 def STOSQ : RI<0xAB, RawFrmDst, (outs), (ins dstidx64:$dst),
1355 "stosq\t{%rax, $dst|$dst, rax}", [], IIC_STOS>;
1357 // These uses the DF flag in the EFLAGS register to inc or dec EDI and ESI
1358 let Defs = [EDI,EFLAGS], Uses = [AL,EDI,EFLAGS] in
1359 def SCASB : I<0xAE, RawFrmDst, (outs), (ins dstidx8:$dst),
1360 "scasb\t{$dst, %al|al, $dst}", [], IIC_SCAS>;
1361 let Defs = [EDI,EFLAGS], Uses = [AX,EDI,EFLAGS] in
1362 def SCASW : I<0xAF, RawFrmDst, (outs), (ins dstidx16:$dst),
1363 "scasw\t{$dst, %ax|ax, $dst}", [], IIC_SCAS>, OpSize16;
1364 let Defs = [EDI,EFLAGS], Uses = [EAX,EDI,EFLAGS] in
1365 def SCASL : I<0xAF, RawFrmDst, (outs), (ins dstidx32:$dst),
1366 "scas{l|d}\t{$dst, %eax|eax, $dst}", [], IIC_SCAS>, OpSize32;
1367 let Defs = [EDI,EFLAGS], Uses = [RAX,EDI,EFLAGS] in
1368 def SCASQ : RI<0xAF, RawFrmDst, (outs), (ins dstidx64:$dst),
1369 "scasq\t{$dst, %rax|rax, $dst}", [], IIC_SCAS>;
1371 // These uses the DF flag in the EFLAGS register to inc or dec EDI and ESI
1372 let Defs = [EDI,ESI,EFLAGS], Uses = [EDI,ESI,EFLAGS] in {
1373 def CMPSB : I<0xA6, RawFrmDstSrc, (outs), (ins dstidx8:$dst, srcidx8:$src),
1374 "cmpsb\t{$dst, $src|$src, $dst}", [], IIC_CMPS>;
1375 def CMPSW : I<0xA7, RawFrmDstSrc, (outs), (ins dstidx16:$dst, srcidx16:$src),
1376 "cmpsw\t{$dst, $src|$src, $dst}", [], IIC_CMPS>, OpSize16;
1377 def CMPSL : I<0xA7, RawFrmDstSrc, (outs), (ins dstidx32:$dst, srcidx32:$src),
1378 "cmps{l|d}\t{$dst, $src|$src, $dst}", [], IIC_CMPS>, OpSize32;
1379 def CMPSQ : RI<0xA7, RawFrmDstSrc, (outs), (ins dstidx64:$dst, srcidx64:$src),
1380 "cmpsq\t{$dst, $src|$src, $dst}", [], IIC_CMPS>;
1384 //===----------------------------------------------------------------------===//
1385 // Move Instructions.
1387 let SchedRW = [WriteMove] in {
1388 let hasSideEffects = 0 in {
1389 def MOV8rr : I<0x88, MRMDestReg, (outs GR8 :$dst), (ins GR8 :$src),
1390 "mov{b}\t{$src, $dst|$dst, $src}", [], IIC_MOV>;
1391 def MOV16rr : I<0x89, MRMDestReg, (outs GR16:$dst), (ins GR16:$src),
1392 "mov{w}\t{$src, $dst|$dst, $src}", [], IIC_MOV>, OpSize16;
1393 def MOV32rr : I<0x89, MRMDestReg, (outs GR32:$dst), (ins GR32:$src),
1394 "mov{l}\t{$src, $dst|$dst, $src}", [], IIC_MOV>, OpSize32;
1395 def MOV64rr : RI<0x89, MRMDestReg, (outs GR64:$dst), (ins GR64:$src),
1396 "mov{q}\t{$src, $dst|$dst, $src}", [], IIC_MOV>;
1399 let isReMaterializable = 1, isAsCheapAsAMove = 1 in {
1400 def MOV8ri : Ii8 <0xB0, AddRegFrm, (outs GR8 :$dst), (ins i8imm :$src),
1401 "mov{b}\t{$src, $dst|$dst, $src}",
1402 [(set GR8:$dst, imm:$src)], IIC_MOV>;
1403 def MOV16ri : Ii16<0xB8, AddRegFrm, (outs GR16:$dst), (ins i16imm:$src),
1404 "mov{w}\t{$src, $dst|$dst, $src}",
1405 [(set GR16:$dst, imm:$src)], IIC_MOV>, OpSize16;
1406 def MOV32ri : Ii32<0xB8, AddRegFrm, (outs GR32:$dst), (ins i32imm:$src),
1407 "mov{l}\t{$src, $dst|$dst, $src}",
1408 [(set GR32:$dst, relocImm:$src)], IIC_MOV>, OpSize32;
1409 def MOV64ri32 : RIi32S<0xC7, MRM0r, (outs GR64:$dst), (ins i64i32imm:$src),
1410 "mov{q}\t{$src, $dst|$dst, $src}",
1411 [(set GR64:$dst, i64immSExt32:$src)], IIC_MOV>;
1413 let isReMaterializable = 1 in {
1414 def MOV64ri : RIi64<0xB8, AddRegFrm, (outs GR64:$dst), (ins i64imm:$src),
1415 "movabs{q}\t{$src, $dst|$dst, $src}",
1416 [(set GR64:$dst, relocImm:$src)], IIC_MOV>;
1419 // Longer forms that use a ModR/M byte. Needed for disassembler
1420 let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0 in {
1421 def MOV8ri_alt : Ii8 <0xC6, MRM0r, (outs GR8 :$dst), (ins i8imm :$src),
1422 "mov{b}\t{$src, $dst|$dst, $src}", [], IIC_MOV>;
1423 def MOV16ri_alt : Ii16<0xC7, MRM0r, (outs GR16:$dst), (ins i16imm:$src),
1424 "mov{w}\t{$src, $dst|$dst, $src}", [], IIC_MOV>, OpSize16;
1425 def MOV32ri_alt : Ii32<0xC7, MRM0r, (outs GR32:$dst), (ins i32imm:$src),
1426 "mov{l}\t{$src, $dst|$dst, $src}", [], IIC_MOV>, OpSize32;
1430 let SchedRW = [WriteStore] in {
1431 def MOV8mi : Ii8 <0xC6, MRM0m, (outs), (ins i8mem :$dst, i8imm :$src),
1432 "mov{b}\t{$src, $dst|$dst, $src}",
1433 [(store (i8 imm8_su:$src), addr:$dst)], IIC_MOV_MEM>;
1434 def MOV16mi : Ii16<0xC7, MRM0m, (outs), (ins i16mem:$dst, i16imm:$src),
1435 "mov{w}\t{$src, $dst|$dst, $src}",
1436 [(store (i16 imm16_su:$src), addr:$dst)], IIC_MOV_MEM>, OpSize16;
1437 def MOV32mi : Ii32<0xC7, MRM0m, (outs), (ins i32mem:$dst, i32imm:$src),
1438 "mov{l}\t{$src, $dst|$dst, $src}",
1439 [(store (i32 imm32_su:$src), addr:$dst)], IIC_MOV_MEM>, OpSize32;
1440 def MOV64mi32 : RIi32S<0xC7, MRM0m, (outs), (ins i64mem:$dst, i64i32imm:$src),
1441 "mov{q}\t{$src, $dst|$dst, $src}",
1442 [(store i64immSExt32_su:$src, addr:$dst)], IIC_MOV_MEM>;
1445 let hasSideEffects = 0 in {
1447 /// Memory offset versions of moves. The immediate is an address mode sized
1448 /// offset from the segment base.
1449 let SchedRW = [WriteALU] in {
1450 let mayLoad = 1 in {
1452 def MOV8ao32 : Ii32<0xA0, RawFrmMemOffs, (outs), (ins offset32_8:$src),
1453 "mov{b}\t{$src, %al|al, $src}", [], IIC_MOV_MEM>,
1456 def MOV16ao32 : Ii32<0xA1, RawFrmMemOffs, (outs), (ins offset32_16:$src),
1457 "mov{w}\t{$src, %ax|ax, $src}", [], IIC_MOV_MEM>,
1460 def MOV32ao32 : Ii32<0xA1, RawFrmMemOffs, (outs), (ins offset32_32:$src),
1461 "mov{l}\t{$src, %eax|eax, $src}", [], IIC_MOV_MEM>,
1464 def MOV64ao32 : RIi32<0xA1, RawFrmMemOffs, (outs), (ins offset32_64:$src),
1465 "mov{q}\t{$src, %rax|rax, $src}", [], IIC_MOV_MEM>,
1469 def MOV8ao16 : Ii16<0xA0, RawFrmMemOffs, (outs), (ins offset16_8:$src),
1470 "mov{b}\t{$src, %al|al, $src}", [], IIC_MOV_MEM>, AdSize16;
1472 def MOV16ao16 : Ii16<0xA1, RawFrmMemOffs, (outs), (ins offset16_16:$src),
1473 "mov{w}\t{$src, %ax|ax, $src}", [], IIC_MOV_MEM>,
1476 def MOV32ao16 : Ii16<0xA1, RawFrmMemOffs, (outs), (ins offset16_32:$src),
1477 "mov{l}\t{$src, %eax|eax, $src}", [], IIC_MOV_MEM>,
1480 let mayStore = 1 in {
1482 def MOV8o32a : Ii32<0xA2, RawFrmMemOffs, (outs), (ins offset32_8:$dst),
1483 "mov{b}\t{%al, $dst|$dst, al}", [], IIC_MOV_MEM>, AdSize32;
1485 def MOV16o32a : Ii32<0xA3, RawFrmMemOffs, (outs), (ins offset32_16:$dst),
1486 "mov{w}\t{%ax, $dst|$dst, ax}", [], IIC_MOV_MEM>,
1489 def MOV32o32a : Ii32<0xA3, RawFrmMemOffs, (outs), (ins offset32_32:$dst),
1490 "mov{l}\t{%eax, $dst|$dst, eax}", [], IIC_MOV_MEM>,
1493 def MOV64o32a : RIi32<0xA3, RawFrmMemOffs, (outs), (ins offset32_64:$dst),
1494 "mov{q}\t{%rax, $dst|$dst, rax}", [], IIC_MOV_MEM>,
1498 def MOV8o16a : Ii16<0xA2, RawFrmMemOffs, (outs), (ins offset16_8:$dst),
1499 "mov{b}\t{%al, $dst|$dst, al}", [], IIC_MOV_MEM>, AdSize16;
1501 def MOV16o16a : Ii16<0xA3, RawFrmMemOffs, (outs), (ins offset16_16:$dst),
1502 "mov{w}\t{%ax, $dst|$dst, ax}", [], IIC_MOV_MEM>,
1505 def MOV32o16a : Ii16<0xA3, RawFrmMemOffs, (outs), (ins offset16_32:$dst),
1506 "mov{l}\t{%eax, $dst|$dst, eax}", [], IIC_MOV_MEM>,
1511 // These forms all have full 64-bit absolute addresses in their instructions
1512 // and use the movabs mnemonic to indicate this specific form.
1513 let mayLoad = 1 in {
1515 def MOV8ao64 : RIi64_NOREX<0xA0, RawFrmMemOffs, (outs), (ins offset64_8:$src),
1516 "movabs{b}\t{$src, %al|al, $src}", []>, AdSize64;
1518 def MOV16ao64 : RIi64_NOREX<0xA1, RawFrmMemOffs, (outs), (ins offset64_16:$src),
1519 "movabs{w}\t{$src, %ax|ax, $src}", []>, OpSize16, AdSize64;
1521 def MOV32ao64 : RIi64_NOREX<0xA1, RawFrmMemOffs, (outs), (ins offset64_32:$src),
1522 "movabs{l}\t{$src, %eax|eax, $src}", []>, OpSize32,
1525 def MOV64ao64 : RIi64<0xA1, RawFrmMemOffs, (outs), (ins offset64_64:$src),
1526 "movabs{q}\t{$src, %rax|rax, $src}", []>, AdSize64;
1529 let mayStore = 1 in {
1531 def MOV8o64a : RIi64_NOREX<0xA2, RawFrmMemOffs, (outs), (ins offset64_8:$dst),
1532 "movabs{b}\t{%al, $dst|$dst, al}", []>, AdSize64;
1534 def MOV16o64a : RIi64_NOREX<0xA3, RawFrmMemOffs, (outs), (ins offset64_16:$dst),
1535 "movabs{w}\t{%ax, $dst|$dst, ax}", []>, OpSize16, AdSize64;
1537 def MOV32o64a : RIi64_NOREX<0xA3, RawFrmMemOffs, (outs), (ins offset64_32:$dst),
1538 "movabs{l}\t{%eax, $dst|$dst, eax}", []>, OpSize32,
1541 def MOV64o64a : RIi64<0xA3, RawFrmMemOffs, (outs), (ins offset64_64:$dst),
1542 "movabs{q}\t{%rax, $dst|$dst, rax}", []>, AdSize64;
1544 } // hasSideEffects = 0
1546 let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0,
1547 SchedRW = [WriteMove] in {
1548 def MOV8rr_REV : I<0x8A, MRMSrcReg, (outs GR8:$dst), (ins GR8:$src),
1549 "mov{b}\t{$src, $dst|$dst, $src}", [], IIC_MOV>;
1550 def MOV16rr_REV : I<0x8B, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
1551 "mov{w}\t{$src, $dst|$dst, $src}", [], IIC_MOV>, OpSize16;
1552 def MOV32rr_REV : I<0x8B, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
1553 "mov{l}\t{$src, $dst|$dst, $src}", [], IIC_MOV>, OpSize32;
1554 def MOV64rr_REV : RI<0x8B, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
1555 "mov{q}\t{$src, $dst|$dst, $src}", [], IIC_MOV>;
1558 let canFoldAsLoad = 1, isReMaterializable = 1, SchedRW = [WriteLoad] in {
1559 def MOV8rm : I<0x8A, MRMSrcMem, (outs GR8 :$dst), (ins i8mem :$src),
1560 "mov{b}\t{$src, $dst|$dst, $src}",
1561 [(set GR8:$dst, (loadi8 addr:$src))], IIC_MOV_MEM>;
1562 def MOV16rm : I<0x8B, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
1563 "mov{w}\t{$src, $dst|$dst, $src}",
1564 [(set GR16:$dst, (loadi16 addr:$src))], IIC_MOV_MEM>, OpSize16;
1565 def MOV32rm : I<0x8B, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
1566 "mov{l}\t{$src, $dst|$dst, $src}",
1567 [(set GR32:$dst, (loadi32 addr:$src))], IIC_MOV_MEM>, OpSize32;
1568 def MOV64rm : RI<0x8B, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
1569 "mov{q}\t{$src, $dst|$dst, $src}",
1570 [(set GR64:$dst, (load addr:$src))], IIC_MOV_MEM>;
1573 let SchedRW = [WriteStore] in {
1574 def MOV8mr : I<0x88, MRMDestMem, (outs), (ins i8mem :$dst, GR8 :$src),
1575 "mov{b}\t{$src, $dst|$dst, $src}",
1576 [(store GR8:$src, addr:$dst)], IIC_MOV_MEM>;
1577 def MOV16mr : I<0x89, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src),
1578 "mov{w}\t{$src, $dst|$dst, $src}",
1579 [(store GR16:$src, addr:$dst)], IIC_MOV_MEM>, OpSize16;
1580 def MOV32mr : I<0x89, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
1581 "mov{l}\t{$src, $dst|$dst, $src}",
1582 [(store GR32:$src, addr:$dst)], IIC_MOV_MEM>, OpSize32;
1583 def MOV64mr : RI<0x89, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
1584 "mov{q}\t{$src, $dst|$dst, $src}",
1585 [(store GR64:$src, addr:$dst)], IIC_MOV_MEM>;
1588 // Versions of MOV8rr, MOV8mr, and MOV8rm that use i8mem_NOREX and GR8_NOREX so
1589 // that they can be used for copying and storing h registers, which can't be
1590 // encoded when a REX prefix is present.
1591 let isCodeGenOnly = 1 in {
1592 let hasSideEffects = 0 in
1593 def MOV8rr_NOREX : I<0x88, MRMDestReg,
1594 (outs GR8_NOREX:$dst), (ins GR8_NOREX:$src),
1595 "mov{b}\t{$src, $dst|$dst, $src} # NOREX", [], IIC_MOV>,
1597 let mayStore = 1, hasSideEffects = 0 in
1598 def MOV8mr_NOREX : I<0x88, MRMDestMem,
1599 (outs), (ins i8mem_NOREX:$dst, GR8_NOREX:$src),
1600 "mov{b}\t{$src, $dst|$dst, $src} # NOREX", [],
1601 IIC_MOV_MEM>, Sched<[WriteStore]>;
1602 let mayLoad = 1, hasSideEffects = 0,
1603 canFoldAsLoad = 1, isReMaterializable = 1 in
1604 def MOV8rm_NOREX : I<0x8A, MRMSrcMem,
1605 (outs GR8_NOREX:$dst), (ins i8mem_NOREX:$src),
1606 "mov{b}\t{$src, $dst|$dst, $src} # NOREX", [],
1607 IIC_MOV_MEM>, Sched<[WriteLoad]>;
1611 // Condition code ops, incl. set if equal/not equal/...
1612 let SchedRW = [WriteALU] in {
1613 let Defs = [EFLAGS], Uses = [AH] in
1614 def SAHF : I<0x9E, RawFrm, (outs), (ins), "sahf",
1615 [(set EFLAGS, (X86sahf AH))], IIC_AHF>,
1616 Requires<[HasLAHFSAHF]>;
1617 let Defs = [AH], Uses = [EFLAGS], hasSideEffects = 0 in
1618 def LAHF : I<0x9F, RawFrm, (outs), (ins), "lahf", [],
1619 IIC_AHF>, // AH = flags
1620 Requires<[HasLAHFSAHF]>;
1623 //===----------------------------------------------------------------------===//
1624 // Bit tests instructions: BT, BTS, BTR, BTC.
1626 let Defs = [EFLAGS] in {
1627 let SchedRW = [WriteALU] in {
1628 def BT16rr : I<0xA3, MRMDestReg, (outs), (ins GR16:$src1, GR16:$src2),
1629 "bt{w}\t{$src2, $src1|$src1, $src2}",
1630 [(set EFLAGS, (X86bt GR16:$src1, GR16:$src2))], IIC_BT_RR>,
1632 def BT32rr : I<0xA3, MRMDestReg, (outs), (ins GR32:$src1, GR32:$src2),
1633 "bt{l}\t{$src2, $src1|$src1, $src2}",
1634 [(set EFLAGS, (X86bt GR32:$src1, GR32:$src2))], IIC_BT_RR>,
1636 def BT64rr : RI<0xA3, MRMDestReg, (outs), (ins GR64:$src1, GR64:$src2),
1637 "bt{q}\t{$src2, $src1|$src1, $src2}",
1638 [(set EFLAGS, (X86bt GR64:$src1, GR64:$src2))], IIC_BT_RR>, TB;
1641 // Unlike with the register+register form, the memory+register form of the
1642 // bt instruction does not ignore the high bits of the index. From ISel's
1643 // perspective, this is pretty bizarre. Make these instructions disassembly
1646 let mayLoad = 1, hasSideEffects = 0, SchedRW = [WriteALULd] in {
1647 def BT16mr : I<0xA3, MRMDestMem, (outs), (ins i16mem:$src1, GR16:$src2),
1648 "bt{w}\t{$src2, $src1|$src1, $src2}",
1649 // [(X86bt (loadi16 addr:$src1), GR16:$src2),
1650 // (implicit EFLAGS)]
1652 >, OpSize16, TB, Requires<[FastBTMem]>;
1653 def BT32mr : I<0xA3, MRMDestMem, (outs), (ins i32mem:$src1, GR32:$src2),
1654 "bt{l}\t{$src2, $src1|$src1, $src2}",
1655 // [(X86bt (loadi32 addr:$src1), GR32:$src2),
1656 // (implicit EFLAGS)]
1658 >, OpSize32, TB, Requires<[FastBTMem]>;
1659 def BT64mr : RI<0xA3, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2),
1660 "bt{q}\t{$src2, $src1|$src1, $src2}",
1661 // [(X86bt (loadi64 addr:$src1), GR64:$src2),
1662 // (implicit EFLAGS)]
1667 let SchedRW = [WriteALU] in {
1668 def BT16ri8 : Ii8<0xBA, MRM4r, (outs), (ins GR16:$src1, i16i8imm:$src2),
1669 "bt{w}\t{$src2, $src1|$src1, $src2}",
1670 [(set EFLAGS, (X86bt GR16:$src1, i16immSExt8:$src2))],
1671 IIC_BT_RI>, OpSize16, TB;
1672 def BT32ri8 : Ii8<0xBA, MRM4r, (outs), (ins GR32:$src1, i32i8imm:$src2),
1673 "bt{l}\t{$src2, $src1|$src1, $src2}",
1674 [(set EFLAGS, (X86bt GR32:$src1, i32immSExt8:$src2))],
1675 IIC_BT_RI>, OpSize32, TB;
1676 def BT64ri8 : RIi8<0xBA, MRM4r, (outs), (ins GR64:$src1, i64i8imm:$src2),
1677 "bt{q}\t{$src2, $src1|$src1, $src2}",
1678 [(set EFLAGS, (X86bt GR64:$src1, i64immSExt8:$src2))],
1682 // Note that these instructions don't need FastBTMem because that
1683 // only applies when the other operand is in a register. When it's
1684 // an immediate, bt is still fast.
1685 let SchedRW = [WriteALU] in {
1686 def BT16mi8 : Ii8<0xBA, MRM4m, (outs), (ins i16mem:$src1, i16i8imm:$src2),
1687 "bt{w}\t{$src2, $src1|$src1, $src2}",
1688 [(set EFLAGS, (X86bt (loadi16 addr:$src1), i16immSExt8:$src2))
1689 ], IIC_BT_MI>, OpSize16, TB;
1690 def BT32mi8 : Ii8<0xBA, MRM4m, (outs), (ins i32mem:$src1, i32i8imm:$src2),
1691 "bt{l}\t{$src2, $src1|$src1, $src2}",
1692 [(set EFLAGS, (X86bt (loadi32 addr:$src1), i32immSExt8:$src2))
1693 ], IIC_BT_MI>, OpSize32, TB;
1694 def BT64mi8 : RIi8<0xBA, MRM4m, (outs), (ins i64mem:$src1, i64i8imm:$src2),
1695 "bt{q}\t{$src2, $src1|$src1, $src2}",
1696 [(set EFLAGS, (X86bt (loadi64 addr:$src1),
1697 i64immSExt8:$src2))], IIC_BT_MI>, TB;
1700 let hasSideEffects = 0 in {
1701 let SchedRW = [WriteALU] in {
1702 def BTC16rr : I<0xBB, MRMDestReg, (outs), (ins GR16:$src1, GR16:$src2),
1703 "btc{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>,
1705 def BTC32rr : I<0xBB, MRMDestReg, (outs), (ins GR32:$src1, GR32:$src2),
1706 "btc{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>,
1708 def BTC64rr : RI<0xBB, MRMDestReg, (outs), (ins GR64:$src1, GR64:$src2),
1709 "btc{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>, TB;
1712 let mayLoad = 1, mayStore = 1, SchedRW = [WriteALULd, WriteRMW] in {
1713 def BTC16mr : I<0xBB, MRMDestMem, (outs), (ins i16mem:$src1, GR16:$src2),
1714 "btc{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>,
1716 def BTC32mr : I<0xBB, MRMDestMem, (outs), (ins i32mem:$src1, GR32:$src2),
1717 "btc{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>,
1719 def BTC64mr : RI<0xBB, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2),
1720 "btc{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>, TB;
1723 let SchedRW = [WriteALU] in {
1724 def BTC16ri8 : Ii8<0xBA, MRM7r, (outs), (ins GR16:$src1, i16i8imm:$src2),
1725 "btc{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>,
1727 def BTC32ri8 : Ii8<0xBA, MRM7r, (outs), (ins GR32:$src1, i32i8imm:$src2),
1728 "btc{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>,
1730 def BTC64ri8 : RIi8<0xBA, MRM7r, (outs), (ins GR64:$src1, i64i8imm:$src2),
1731 "btc{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>, TB;
1734 let mayLoad = 1, mayStore = 1, SchedRW = [WriteALULd, WriteRMW] in {
1735 def BTC16mi8 : Ii8<0xBA, MRM7m, (outs), (ins i16mem:$src1, i16i8imm:$src2),
1736 "btc{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>,
1738 def BTC32mi8 : Ii8<0xBA, MRM7m, (outs), (ins i32mem:$src1, i32i8imm:$src2),
1739 "btc{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>,
1741 def BTC64mi8 : RIi8<0xBA, MRM7m, (outs), (ins i64mem:$src1, i64i8imm:$src2),
1742 "btc{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>, TB;
1745 let SchedRW = [WriteALU] in {
1746 def BTR16rr : I<0xB3, MRMDestReg, (outs), (ins GR16:$src1, GR16:$src2),
1747 "btr{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>,
1749 def BTR32rr : I<0xB3, MRMDestReg, (outs), (ins GR32:$src1, GR32:$src2),
1750 "btr{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>,
1752 def BTR64rr : RI<0xB3, MRMDestReg, (outs), (ins GR64:$src1, GR64:$src2),
1753 "btr{q}\t{$src2, $src1|$src1, $src2}", []>, TB;
1756 let mayLoad = 1, mayStore = 1, SchedRW = [WriteALULd, WriteRMW] in {
1757 def BTR16mr : I<0xB3, MRMDestMem, (outs), (ins i16mem:$src1, GR16:$src2),
1758 "btr{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>,
1760 def BTR32mr : I<0xB3, MRMDestMem, (outs), (ins i32mem:$src1, GR32:$src2),
1761 "btr{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>,
1763 def BTR64mr : RI<0xB3, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2),
1764 "btr{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>, TB;
1767 let SchedRW = [WriteALU] in {
1768 def BTR16ri8 : Ii8<0xBA, MRM6r, (outs), (ins GR16:$src1, i16i8imm:$src2),
1769 "btr{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>,
1771 def BTR32ri8 : Ii8<0xBA, MRM6r, (outs), (ins GR32:$src1, i32i8imm:$src2),
1772 "btr{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>,
1774 def BTR64ri8 : RIi8<0xBA, MRM6r, (outs), (ins GR64:$src1, i64i8imm:$src2),
1775 "btr{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>, TB;
1778 let mayLoad = 1, mayStore = 1, SchedRW = [WriteALULd, WriteRMW] in {
1779 def BTR16mi8 : Ii8<0xBA, MRM6m, (outs), (ins i16mem:$src1, i16i8imm:$src2),
1780 "btr{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>,
1782 def BTR32mi8 : Ii8<0xBA, MRM6m, (outs), (ins i32mem:$src1, i32i8imm:$src2),
1783 "btr{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>,
1785 def BTR64mi8 : RIi8<0xBA, MRM6m, (outs), (ins i64mem:$src1, i64i8imm:$src2),
1786 "btr{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>, TB;
1789 let SchedRW = [WriteALU] in {
1790 def BTS16rr : I<0xAB, MRMDestReg, (outs), (ins GR16:$src1, GR16:$src2),
1791 "bts{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>,
1793 def BTS32rr : I<0xAB, MRMDestReg, (outs), (ins GR32:$src1, GR32:$src2),
1794 "bts{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>,
1796 def BTS64rr : RI<0xAB, MRMDestReg, (outs), (ins GR64:$src1, GR64:$src2),
1797 "bts{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>, TB;
1800 let mayLoad = 1, mayStore = 1, SchedRW = [WriteALULd, WriteRMW] in {
1801 def BTS16mr : I<0xAB, MRMDestMem, (outs), (ins i16mem:$src1, GR16:$src2),
1802 "bts{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>,
1804 def BTS32mr : I<0xAB, MRMDestMem, (outs), (ins i32mem:$src1, GR32:$src2),
1805 "bts{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>,
1807 def BTS64mr : RI<0xAB, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2),
1808 "bts{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>, TB;
1811 let SchedRW = [WriteALU] in {
1812 def BTS16ri8 : Ii8<0xBA, MRM5r, (outs), (ins GR16:$src1, i16i8imm:$src2),
1813 "bts{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>,
1815 def BTS32ri8 : Ii8<0xBA, MRM5r, (outs), (ins GR32:$src1, i32i8imm:$src2),
1816 "bts{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>,
1818 def BTS64ri8 : RIi8<0xBA, MRM5r, (outs), (ins GR64:$src1, i64i8imm:$src2),
1819 "bts{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>, TB;
1822 let mayLoad = 1, mayStore = 1, SchedRW = [WriteALULd, WriteRMW] in {
1823 def BTS16mi8 : Ii8<0xBA, MRM5m, (outs), (ins i16mem:$src1, i16i8imm:$src2),
1824 "bts{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>,
1826 def BTS32mi8 : Ii8<0xBA, MRM5m, (outs), (ins i32mem:$src1, i32i8imm:$src2),
1827 "bts{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>,
1829 def BTS64mi8 : RIi8<0xBA, MRM5m, (outs), (ins i64mem:$src1, i64i8imm:$src2),
1830 "bts{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>, TB;
1832 } // hasSideEffects = 0
1833 } // Defs = [EFLAGS]
1836 //===----------------------------------------------------------------------===//
1840 // Atomic swap. These are just normal xchg instructions. But since a memory
1841 // operand is referenced, the atomicity is ensured.
1842 multiclass ATOMIC_SWAP<bits<8> opc8, bits<8> opc, string mnemonic, string frag,
1843 InstrItinClass itin> {
1844 let Constraints = "$val = $dst", SchedRW = [WriteALULd, WriteRMW] in {
1845 def NAME#8rm : I<opc8, MRMSrcMem, (outs GR8:$dst),
1846 (ins GR8:$val, i8mem:$ptr),
1847 !strconcat(mnemonic, "{b}\t{$val, $ptr|$ptr, $val}"),
1850 (!cast<PatFrag>(frag # "_8") addr:$ptr, GR8:$val))],
1852 def NAME#16rm : I<opc, MRMSrcMem, (outs GR16:$dst),
1853 (ins GR16:$val, i16mem:$ptr),
1854 !strconcat(mnemonic, "{w}\t{$val, $ptr|$ptr, $val}"),
1857 (!cast<PatFrag>(frag # "_16") addr:$ptr, GR16:$val))],
1859 def NAME#32rm : I<opc, MRMSrcMem, (outs GR32:$dst),
1860 (ins GR32:$val, i32mem:$ptr),
1861 !strconcat(mnemonic, "{l}\t{$val, $ptr|$ptr, $val}"),
1864 (!cast<PatFrag>(frag # "_32") addr:$ptr, GR32:$val))],
1866 def NAME#64rm : RI<opc, MRMSrcMem, (outs GR64:$dst),
1867 (ins GR64:$val, i64mem:$ptr),
1868 !strconcat(mnemonic, "{q}\t{$val, $ptr|$ptr, $val}"),
1871 (!cast<PatFrag>(frag # "_64") addr:$ptr, GR64:$val))],
1876 defm XCHG : ATOMIC_SWAP<0x86, 0x87, "xchg", "atomic_swap", IIC_XCHG_MEM>;
1878 // Swap between registers.
1879 let SchedRW = [WriteALU] in {
1880 let Constraints = "$val = $dst" in {
1881 def XCHG8rr : I<0x86, MRMSrcReg, (outs GR8:$dst), (ins GR8:$val, GR8:$src),
1882 "xchg{b}\t{$val, $src|$src, $val}", [], IIC_XCHG_REG>;
1883 def XCHG16rr : I<0x87, MRMSrcReg, (outs GR16:$dst), (ins GR16:$val, GR16:$src),
1884 "xchg{w}\t{$val, $src|$src, $val}", [], IIC_XCHG_REG>,
1886 def XCHG32rr : I<0x87, MRMSrcReg, (outs GR32:$dst), (ins GR32:$val, GR32:$src),
1887 "xchg{l}\t{$val, $src|$src, $val}", [], IIC_XCHG_REG>,
1889 def XCHG64rr : RI<0x87, MRMSrcReg, (outs GR64:$dst), (ins GR64:$val,GR64:$src),
1890 "xchg{q}\t{$val, $src|$src, $val}", [], IIC_XCHG_REG>;
1893 // Swap between EAX and other registers.
1894 let Uses = [AX], Defs = [AX] in
1895 def XCHG16ar : I<0x90, AddRegFrm, (outs), (ins GR16:$src),
1896 "xchg{w}\t{$src, %ax|ax, $src}", [], IIC_XCHG_REG>, OpSize16;
1897 let Uses = [EAX], Defs = [EAX] in
1898 def XCHG32ar : I<0x90, AddRegFrm, (outs), (ins GR32:$src),
1899 "xchg{l}\t{$src, %eax|eax, $src}", [], IIC_XCHG_REG>,
1900 OpSize32, Requires<[Not64BitMode]>;
1901 let Uses = [EAX], Defs = [EAX] in
1902 // Uses GR32_NOAX in 64-bit mode to prevent encoding using the 0x90 NOP encoding.
1903 // xchg %eax, %eax needs to clear upper 32-bits of RAX so is not a NOP.
1904 def XCHG32ar64 : I<0x90, AddRegFrm, (outs), (ins GR32_NOAX:$src),
1905 "xchg{l}\t{$src, %eax|eax, $src}", [], IIC_XCHG_REG>,
1906 OpSize32, Requires<[In64BitMode]>;
1907 let Uses = [RAX], Defs = [RAX] in
1908 def XCHG64ar : RI<0x90, AddRegFrm, (outs), (ins GR64:$src),
1909 "xchg{q}\t{$src, %rax|rax, $src}", [], IIC_XCHG_REG>;
1912 let SchedRW = [WriteALU] in {
1913 def XADD8rr : I<0xC0, MRMDestReg, (outs GR8:$dst), (ins GR8:$src),
1914 "xadd{b}\t{$src, $dst|$dst, $src}", [], IIC_XADD_REG>, TB;
1915 def XADD16rr : I<0xC1, MRMDestReg, (outs GR16:$dst), (ins GR16:$src),
1916 "xadd{w}\t{$src, $dst|$dst, $src}", [], IIC_XADD_REG>, TB,
1918 def XADD32rr : I<0xC1, MRMDestReg, (outs GR32:$dst), (ins GR32:$src),
1919 "xadd{l}\t{$src, $dst|$dst, $src}", [], IIC_XADD_REG>, TB,
1921 def XADD64rr : RI<0xC1, MRMDestReg, (outs GR64:$dst), (ins GR64:$src),
1922 "xadd{q}\t{$src, $dst|$dst, $src}", [], IIC_XADD_REG>, TB;
1925 let mayLoad = 1, mayStore = 1, SchedRW = [WriteALULd, WriteRMW] in {
1926 def XADD8rm : I<0xC0, MRMDestMem, (outs), (ins i8mem:$dst, GR8:$src),
1927 "xadd{b}\t{$src, $dst|$dst, $src}", [], IIC_XADD_MEM>, TB;
1928 def XADD16rm : I<0xC1, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src),
1929 "xadd{w}\t{$src, $dst|$dst, $src}", [], IIC_XADD_MEM>, TB,
1931 def XADD32rm : I<0xC1, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
1932 "xadd{l}\t{$src, $dst|$dst, $src}", [], IIC_XADD_MEM>, TB,
1934 def XADD64rm : RI<0xC1, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
1935 "xadd{q}\t{$src, $dst|$dst, $src}", [], IIC_XADD_MEM>, TB;
1939 let SchedRW = [WriteALU] in {
1940 def CMPXCHG8rr : I<0xB0, MRMDestReg, (outs GR8:$dst), (ins GR8:$src),
1941 "cmpxchg{b}\t{$src, $dst|$dst, $src}", [],
1942 IIC_CMPXCHG_REG8>, TB;
1943 def CMPXCHG16rr : I<0xB1, MRMDestReg, (outs GR16:$dst), (ins GR16:$src),
1944 "cmpxchg{w}\t{$src, $dst|$dst, $src}", [],
1945 IIC_CMPXCHG_REG>, TB, OpSize16;
1946 def CMPXCHG32rr : I<0xB1, MRMDestReg, (outs GR32:$dst), (ins GR32:$src),
1947 "cmpxchg{l}\t{$src, $dst|$dst, $src}", [],
1948 IIC_CMPXCHG_REG>, TB, OpSize32;
1949 def CMPXCHG64rr : RI<0xB1, MRMDestReg, (outs GR64:$dst), (ins GR64:$src),
1950 "cmpxchg{q}\t{$src, $dst|$dst, $src}", [],
1951 IIC_CMPXCHG_REG>, TB;
1954 let SchedRW = [WriteALULd, WriteRMW] in {
1955 let mayLoad = 1, mayStore = 1 in {
1956 def CMPXCHG8rm : I<0xB0, MRMDestMem, (outs), (ins i8mem:$dst, GR8:$src),
1957 "cmpxchg{b}\t{$src, $dst|$dst, $src}", [],
1958 IIC_CMPXCHG_MEM8>, TB;
1959 def CMPXCHG16rm : I<0xB1, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src),
1960 "cmpxchg{w}\t{$src, $dst|$dst, $src}", [],
1961 IIC_CMPXCHG_MEM>, TB, OpSize16;
1962 def CMPXCHG32rm : I<0xB1, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
1963 "cmpxchg{l}\t{$src, $dst|$dst, $src}", [],
1964 IIC_CMPXCHG_MEM>, TB, OpSize32;
1965 def CMPXCHG64rm : RI<0xB1, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
1966 "cmpxchg{q}\t{$src, $dst|$dst, $src}", [],
1967 IIC_CMPXCHG_MEM>, TB;
1970 let Defs = [EAX, EDX, EFLAGS], Uses = [EAX, EBX, ECX, EDX] in
1971 def CMPXCHG8B : I<0xC7, MRM1m, (outs), (ins i64mem:$dst),
1972 "cmpxchg8b\t$dst", [], IIC_CMPXCHG_8B>, TB;
1974 let Defs = [RAX, RDX, EFLAGS], Uses = [RAX, RBX, RCX, RDX] in
1975 def CMPXCHG16B : RI<0xC7, MRM1m, (outs), (ins i128mem:$dst),
1976 "cmpxchg16b\t$dst", [], IIC_CMPXCHG_16B>,
1977 TB, Requires<[HasCmpxchg16b]>;
1981 // Lock instruction prefix
1982 def LOCK_PREFIX : I<0xF0, RawFrm, (outs), (ins), "lock", []>;
1984 // Rex64 instruction prefix
1985 def REX64_PREFIX : I<0x48, RawFrm, (outs), (ins), "rex64", []>,
1986 Requires<[In64BitMode]>;
1988 // Data16 instruction prefix
1989 def DATA16_PREFIX : I<0x66, RawFrm, (outs), (ins), "data16", []>,
1990 Requires<[Not16BitMode]>;
1992 // Data instruction prefix
1993 def DATA32_PREFIX : I<0x66, RawFrm, (outs), (ins), "data32", []>,
1994 Requires<[In16BitMode]>;
1996 // Repeat string operation instruction prefixes
1997 // These uses the DF flag in the EFLAGS register to inc or dec ECX
1998 let Defs = [ECX], Uses = [ECX,EFLAGS] in {
1999 // Repeat (used with INS, OUTS, MOVS, LODS and STOS)
2000 def REP_PREFIX : I<0xF3, RawFrm, (outs), (ins), "rep", []>;
2001 // Repeat while not equal (used with CMPS and SCAS)
2002 def REPNE_PREFIX : I<0xF2, RawFrm, (outs), (ins), "repne", []>;
2006 // String manipulation instructions
2007 let SchedRW = [WriteMicrocoded] in {
2008 // These uses the DF flag in the EFLAGS register to inc or dec EDI and ESI
2009 let Defs = [AL,ESI], Uses = [ESI,EFLAGS] in
2010 def LODSB : I<0xAC, RawFrmSrc, (outs), (ins srcidx8:$src),
2011 "lodsb\t{$src, %al|al, $src}", [], IIC_LODS>;
2012 let Defs = [AX,ESI], Uses = [ESI,EFLAGS] in
2013 def LODSW : I<0xAD, RawFrmSrc, (outs), (ins srcidx16:$src),
2014 "lodsw\t{$src, %ax|ax, $src}", [], IIC_LODS>, OpSize16;
2015 let Defs = [EAX,ESI], Uses = [ESI,EFLAGS] in
2016 def LODSL : I<0xAD, RawFrmSrc, (outs), (ins srcidx32:$src),
2017 "lods{l|d}\t{$src, %eax|eax, $src}", [], IIC_LODS>, OpSize32;
2018 let Defs = [RAX,ESI], Uses = [ESI,EFLAGS] in
2019 def LODSQ : RI<0xAD, RawFrmSrc, (outs), (ins srcidx64:$src),
2020 "lodsq\t{$src, %rax|rax, $src}", [], IIC_LODS>;
2023 let SchedRW = [WriteSystem] in {
2024 // These uses the DF flag in the EFLAGS register to inc or dec EDI and ESI
2025 let Defs = [ESI], Uses = [DX,ESI,EFLAGS] in {
2026 def OUTSB : I<0x6E, RawFrmSrc, (outs), (ins srcidx8:$src),
2027 "outsb\t{$src, %dx|dx, $src}", [], IIC_OUTS>;
2028 def OUTSW : I<0x6F, RawFrmSrc, (outs), (ins srcidx16:$src),
2029 "outsw\t{$src, %dx|dx, $src}", [], IIC_OUTS>, OpSize16;
2030 def OUTSL : I<0x6F, RawFrmSrc, (outs), (ins srcidx32:$src),
2031 "outs{l|d}\t{$src, %dx|dx, $src}", [], IIC_OUTS>, OpSize32;
2034 // These uses the DF flag in the EFLAGS register to inc or dec EDI and ESI
2035 let Defs = [EDI], Uses = [DX,EDI,EFLAGS] in {
2036 def INSB : I<0x6C, RawFrmDst, (outs), (ins dstidx8:$dst),
2037 "insb\t{%dx, $dst|$dst, dx}", [], IIC_INS>;
2038 def INSW : I<0x6D, RawFrmDst, (outs), (ins dstidx16:$dst),
2039 "insw\t{%dx, $dst|$dst, dx}", [], IIC_INS>, OpSize16;
2040 def INSL : I<0x6D, RawFrmDst, (outs), (ins dstidx32:$dst),
2041 "ins{l|d}\t{%dx, $dst|$dst, dx}", [], IIC_INS>, OpSize32;
2045 // Flag instructions
2046 let SchedRW = [WriteALU] in {
2047 def CLC : I<0xF8, RawFrm, (outs), (ins), "clc", [], IIC_CLC>;
2048 def STC : I<0xF9, RawFrm, (outs), (ins), "stc", [], IIC_STC>;
2049 def CLI : I<0xFA, RawFrm, (outs), (ins), "cli", [], IIC_CLI>;
2050 def STI : I<0xFB, RawFrm, (outs), (ins), "sti", [], IIC_STI>;
2051 def CLD : I<0xFC, RawFrm, (outs), (ins), "cld", [], IIC_CLD>;
2052 def STD : I<0xFD, RawFrm, (outs), (ins), "std", [], IIC_STD>;
2053 def CMC : I<0xF5, RawFrm, (outs), (ins), "cmc", [], IIC_CMC>;
2055 def CLTS : I<0x06, RawFrm, (outs), (ins), "clts", [], IIC_CLTS>, TB;
2058 // Table lookup instructions
2059 let Uses = [AL,EBX], Defs = [AL], hasSideEffects = 0, mayLoad = 1 in
2060 def XLAT : I<0xD7, RawFrm, (outs), (ins), "xlatb", [], IIC_XLAT>,
2063 let SchedRW = [WriteMicrocoded] in {
2064 // ASCII Adjust After Addition
2065 let Uses = [AL,EFLAGS], Defs = [AX,EFLAGS], hasSideEffects = 0 in
2066 def AAA : I<0x37, RawFrm, (outs), (ins), "aaa", [], IIC_AAA>,
2067 Requires<[Not64BitMode]>;
2069 // ASCII Adjust AX Before Division
2070 let Uses = [AX], Defs = [AX,EFLAGS], hasSideEffects = 0 in
2071 def AAD8i8 : Ii8<0xD5, RawFrm, (outs), (ins i8imm:$src),
2072 "aad\t$src", [], IIC_AAD>, Requires<[Not64BitMode]>;
2074 // ASCII Adjust AX After Multiply
2075 let Uses = [AL], Defs = [AX,EFLAGS], hasSideEffects = 0 in
2076 def AAM8i8 : Ii8<0xD4, RawFrm, (outs), (ins i8imm:$src),
2077 "aam\t$src", [], IIC_AAM>, Requires<[Not64BitMode]>;
2079 // ASCII Adjust AL After Subtraction - sets
2080 let Uses = [AL,EFLAGS], Defs = [AX,EFLAGS], hasSideEffects = 0 in
2081 def AAS : I<0x3F, RawFrm, (outs), (ins), "aas", [], IIC_AAS>,
2082 Requires<[Not64BitMode]>;
2084 // Decimal Adjust AL after Addition
2085 let Uses = [AL,EFLAGS], Defs = [AL,EFLAGS], hasSideEffects = 0 in
2086 def DAA : I<0x27, RawFrm, (outs), (ins), "daa", [], IIC_DAA>,
2087 Requires<[Not64BitMode]>;
2089 // Decimal Adjust AL after Subtraction
2090 let Uses = [AL,EFLAGS], Defs = [AL,EFLAGS], hasSideEffects = 0 in
2091 def DAS : I<0x2F, RawFrm, (outs), (ins), "das", [], IIC_DAS>,
2092 Requires<[Not64BitMode]>;
2095 let SchedRW = [WriteSystem] in {
2096 // Check Array Index Against Bounds
2097 def BOUNDS16rm : I<0x62, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
2098 "bound\t{$src, $dst|$dst, $src}", [], IIC_BOUND>, OpSize16,
2099 Requires<[Not64BitMode]>;
2100 def BOUNDS32rm : I<0x62, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
2101 "bound\t{$src, $dst|$dst, $src}", [], IIC_BOUND>, OpSize32,
2102 Requires<[Not64BitMode]>;
2104 // Adjust RPL Field of Segment Selector
2105 def ARPL16rr : I<0x63, MRMDestReg, (outs GR16:$dst), (ins GR16:$src),
2106 "arpl\t{$src, $dst|$dst, $src}", [], IIC_ARPL_REG>,
2107 Requires<[Not64BitMode]>;
2109 def ARPL16mr : I<0x63, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src),
2110 "arpl\t{$src, $dst|$dst, $src}", [], IIC_ARPL_MEM>,
2111 Requires<[Not64BitMode]>;
2114 //===----------------------------------------------------------------------===//
2115 // MOVBE Instructions
2117 let Predicates = [HasMOVBE] in {
2118 let SchedRW = [WriteALULd] in {
2119 def MOVBE16rm : I<0xF0, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
2120 "movbe{w}\t{$src, $dst|$dst, $src}",
2121 [(set GR16:$dst, (bswap (loadi16 addr:$src)))], IIC_MOVBE>,
2123 def MOVBE32rm : I<0xF0, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
2124 "movbe{l}\t{$src, $dst|$dst, $src}",
2125 [(set GR32:$dst, (bswap (loadi32 addr:$src)))], IIC_MOVBE>,
2127 def MOVBE64rm : RI<0xF0, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
2128 "movbe{q}\t{$src, $dst|$dst, $src}",
2129 [(set GR64:$dst, (bswap (loadi64 addr:$src)))], IIC_MOVBE>,
2132 let SchedRW = [WriteStore] in {
2133 def MOVBE16mr : I<0xF1, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src),
2134 "movbe{w}\t{$src, $dst|$dst, $src}",
2135 [(store (bswap GR16:$src), addr:$dst)], IIC_MOVBE>,
2137 def MOVBE32mr : I<0xF1, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
2138 "movbe{l}\t{$src, $dst|$dst, $src}",
2139 [(store (bswap GR32:$src), addr:$dst)], IIC_MOVBE>,
2141 def MOVBE64mr : RI<0xF1, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
2142 "movbe{q}\t{$src, $dst|$dst, $src}",
2143 [(store (bswap GR64:$src), addr:$dst)], IIC_MOVBE>,
2148 //===----------------------------------------------------------------------===//
2149 // RDRAND Instruction
2151 let Predicates = [HasRDRAND], Defs = [EFLAGS] in {
2152 def RDRAND16r : I<0xC7, MRM6r, (outs GR16:$dst), (ins),
2154 [(set GR16:$dst, EFLAGS, (X86rdrand))]>, OpSize16, TB;
2155 def RDRAND32r : I<0xC7, MRM6r, (outs GR32:$dst), (ins),
2157 [(set GR32:$dst, EFLAGS, (X86rdrand))]>, OpSize32, TB;
2158 def RDRAND64r : RI<0xC7, MRM6r, (outs GR64:$dst), (ins),
2160 [(set GR64:$dst, EFLAGS, (X86rdrand))]>, TB;
2163 //===----------------------------------------------------------------------===//
2164 // RDSEED Instruction
2166 let Predicates = [HasRDSEED], Defs = [EFLAGS] in {
2167 def RDSEED16r : I<0xC7, MRM7r, (outs GR16:$dst), (ins),
2169 [(set GR16:$dst, EFLAGS, (X86rdseed))]>, OpSize16, TB;
2170 def RDSEED32r : I<0xC7, MRM7r, (outs GR32:$dst), (ins),
2172 [(set GR32:$dst, EFLAGS, (X86rdseed))]>, OpSize32, TB;
2173 def RDSEED64r : RI<0xC7, MRM7r, (outs GR64:$dst), (ins),
2175 [(set GR64:$dst, EFLAGS, (X86rdseed))]>, TB;
2178 //===----------------------------------------------------------------------===//
2179 // LZCNT Instruction
2181 let Predicates = [HasLZCNT], Defs = [EFLAGS] in {
2182 def LZCNT16rr : I<0xBD, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
2183 "lzcnt{w}\t{$src, $dst|$dst, $src}",
2184 [(set GR16:$dst, (ctlz GR16:$src)), (implicit EFLAGS)]>, XS,
2186 def LZCNT16rm : I<0xBD, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
2187 "lzcnt{w}\t{$src, $dst|$dst, $src}",
2188 [(set GR16:$dst, (ctlz (loadi16 addr:$src))),
2189 (implicit EFLAGS)]>, XS, OpSize16;
2191 def LZCNT32rr : I<0xBD, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
2192 "lzcnt{l}\t{$src, $dst|$dst, $src}",
2193 [(set GR32:$dst, (ctlz GR32:$src)), (implicit EFLAGS)]>, XS,
2195 def LZCNT32rm : I<0xBD, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
2196 "lzcnt{l}\t{$src, $dst|$dst, $src}",
2197 [(set GR32:$dst, (ctlz (loadi32 addr:$src))),
2198 (implicit EFLAGS)]>, XS, OpSize32;
2200 def LZCNT64rr : RI<0xBD, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
2201 "lzcnt{q}\t{$src, $dst|$dst, $src}",
2202 [(set GR64:$dst, (ctlz GR64:$src)), (implicit EFLAGS)]>,
2204 def LZCNT64rm : RI<0xBD, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
2205 "lzcnt{q}\t{$src, $dst|$dst, $src}",
2206 [(set GR64:$dst, (ctlz (loadi64 addr:$src))),
2207 (implicit EFLAGS)]>, XS;
2210 //===----------------------------------------------------------------------===//
2213 let Predicates = [HasBMI], Defs = [EFLAGS] in {
2214 def TZCNT16rr : I<0xBC, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
2215 "tzcnt{w}\t{$src, $dst|$dst, $src}",
2216 [(set GR16:$dst, (cttz GR16:$src)), (implicit EFLAGS)]>, XS,
2218 def TZCNT16rm : I<0xBC, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
2219 "tzcnt{w}\t{$src, $dst|$dst, $src}",
2220 [(set GR16:$dst, (cttz (loadi16 addr:$src))),
2221 (implicit EFLAGS)]>, XS, OpSize16;
2223 def TZCNT32rr : I<0xBC, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
2224 "tzcnt{l}\t{$src, $dst|$dst, $src}",
2225 [(set GR32:$dst, (cttz GR32:$src)), (implicit EFLAGS)]>, XS,
2227 def TZCNT32rm : I<0xBC, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
2228 "tzcnt{l}\t{$src, $dst|$dst, $src}",
2229 [(set GR32:$dst, (cttz (loadi32 addr:$src))),
2230 (implicit EFLAGS)]>, XS, OpSize32;
2232 def TZCNT64rr : RI<0xBC, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
2233 "tzcnt{q}\t{$src, $dst|$dst, $src}",
2234 [(set GR64:$dst, (cttz GR64:$src)), (implicit EFLAGS)]>,
2236 def TZCNT64rm : RI<0xBC, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
2237 "tzcnt{q}\t{$src, $dst|$dst, $src}",
2238 [(set GR64:$dst, (cttz (loadi64 addr:$src))),
2239 (implicit EFLAGS)]>, XS;
2242 multiclass bmi_bls<string mnemonic, Format RegMRM, Format MemMRM,
2243 RegisterClass RC, X86MemOperand x86memop> {
2244 let hasSideEffects = 0 in {
2245 def rr : I<0xF3, RegMRM, (outs RC:$dst), (ins RC:$src),
2246 !strconcat(mnemonic, "\t{$src, $dst|$dst, $src}"),
2249 def rm : I<0xF3, MemMRM, (outs RC:$dst), (ins x86memop:$src),
2250 !strconcat(mnemonic, "\t{$src, $dst|$dst, $src}"),
2255 let Predicates = [HasBMI], Defs = [EFLAGS] in {
2256 defm BLSR32 : bmi_bls<"blsr{l}", MRM1r, MRM1m, GR32, i32mem>;
2257 defm BLSR64 : bmi_bls<"blsr{q}", MRM1r, MRM1m, GR64, i64mem>, VEX_W;
2258 defm BLSMSK32 : bmi_bls<"blsmsk{l}", MRM2r, MRM2m, GR32, i32mem>;
2259 defm BLSMSK64 : bmi_bls<"blsmsk{q}", MRM2r, MRM2m, GR64, i64mem>, VEX_W;
2260 defm BLSI32 : bmi_bls<"blsi{l}", MRM3r, MRM3m, GR32, i32mem>;
2261 defm BLSI64 : bmi_bls<"blsi{q}", MRM3r, MRM3m, GR64, i64mem>, VEX_W;
2264 //===----------------------------------------------------------------------===//
2265 // Pattern fragments to auto generate BMI instructions.
2266 //===----------------------------------------------------------------------===//
2268 let Predicates = [HasBMI] in {
2269 // FIXME: patterns for the load versions are not implemented
2270 def : Pat<(and GR32:$src, (add GR32:$src, -1)),
2271 (BLSR32rr GR32:$src)>;
2272 def : Pat<(and GR64:$src, (add GR64:$src, -1)),
2273 (BLSR64rr GR64:$src)>;
2275 def : Pat<(xor GR32:$src, (add GR32:$src, -1)),
2276 (BLSMSK32rr GR32:$src)>;
2277 def : Pat<(xor GR64:$src, (add GR64:$src, -1)),
2278 (BLSMSK64rr GR64:$src)>;
2280 def : Pat<(and GR32:$src, (ineg GR32:$src)),
2281 (BLSI32rr GR32:$src)>;
2282 def : Pat<(and GR64:$src, (ineg GR64:$src)),
2283 (BLSI64rr GR64:$src)>;
2287 multiclass bmi_bextr_bzhi<bits<8> opc, string mnemonic, RegisterClass RC,
2288 X86MemOperand x86memop, Intrinsic Int,
2290 def rr : I<opc, MRMSrcReg4VOp3, (outs RC:$dst), (ins RC:$src1, RC:$src2),
2291 !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2292 [(set RC:$dst, (Int RC:$src1, RC:$src2)), (implicit EFLAGS)]>,
2294 def rm : I<opc, MRMSrcMem4VOp3, (outs RC:$dst), (ins x86memop:$src1, RC:$src2),
2295 !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2296 [(set RC:$dst, (Int (ld_frag addr:$src1), RC:$src2)),
2297 (implicit EFLAGS)]>, T8PS, VEX;
2300 let Predicates = [HasBMI], Defs = [EFLAGS] in {
2301 defm BEXTR32 : bmi_bextr_bzhi<0xF7, "bextr{l}", GR32, i32mem,
2302 int_x86_bmi_bextr_32, loadi32>;
2303 defm BEXTR64 : bmi_bextr_bzhi<0xF7, "bextr{q}", GR64, i64mem,
2304 int_x86_bmi_bextr_64, loadi64>, VEX_W;
2307 let Predicates = [HasBMI2], Defs = [EFLAGS] in {
2308 defm BZHI32 : bmi_bextr_bzhi<0xF5, "bzhi{l}", GR32, i32mem,
2309 int_x86_bmi_bzhi_32, loadi32>;
2310 defm BZHI64 : bmi_bextr_bzhi<0xF5, "bzhi{q}", GR64, i64mem,
2311 int_x86_bmi_bzhi_64, loadi64>, VEX_W;
2315 def CountTrailingOnes : SDNodeXForm<imm, [{
2316 // Count the trailing ones in the immediate.
2317 return getI8Imm(countTrailingOnes(N->getZExtValue()), SDLoc(N));
2320 def BZHIMask : ImmLeaf<i64, [{
2321 return isMask_64(Imm) && (countTrailingOnes<uint64_t>(Imm) > 32);
2324 let Predicates = [HasBMI2] in {
2325 def : Pat<(and GR64:$src, BZHIMask:$mask),
2326 (BZHI64rr GR64:$src,
2327 (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
2328 (MOV8ri (CountTrailingOnes imm:$mask)), sub_8bit))>;
2330 def : Pat<(and GR32:$src, (add (shl 1, GR8:$lz), -1)),
2331 (BZHI32rr GR32:$src,
2332 (INSERT_SUBREG (i32 (IMPLICIT_DEF)), GR8:$lz, sub_8bit))>;
2334 def : Pat<(and (loadi32 addr:$src), (add (shl 1, GR8:$lz), -1)),
2335 (BZHI32rm addr:$src,
2336 (INSERT_SUBREG (i32 (IMPLICIT_DEF)), GR8:$lz, sub_8bit))>;
2338 def : Pat<(and GR64:$src, (add (shl 1, GR8:$lz), -1)),
2339 (BZHI64rr GR64:$src,
2340 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR8:$lz, sub_8bit))>;
2342 def : Pat<(and (loadi64 addr:$src), (add (shl 1, GR8:$lz), -1)),
2343 (BZHI64rm addr:$src,
2344 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR8:$lz, sub_8bit))>;
2347 let Predicates = [HasBMI] in {
2348 def : Pat<(X86bextr GR32:$src1, GR32:$src2),
2349 (BEXTR32rr GR32:$src1, GR32:$src2)>;
2350 def : Pat<(X86bextr (loadi32 addr:$src1), GR32:$src2),
2351 (BEXTR32rm addr:$src1, GR32:$src2)>;
2352 def : Pat<(X86bextr GR64:$src1, GR64:$src2),
2353 (BEXTR64rr GR64:$src1, GR64:$src2)>;
2354 def : Pat<(X86bextr (loadi64 addr:$src1), GR64:$src2),
2355 (BEXTR64rm addr:$src1, GR64:$src2)>;
2358 multiclass bmi_pdep_pext<string mnemonic, RegisterClass RC,
2359 X86MemOperand x86memop, Intrinsic Int,
2361 def rr : I<0xF5, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
2362 !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2363 [(set RC:$dst, (Int RC:$src1, RC:$src2))]>,
2365 def rm : I<0xF5, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
2366 !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2367 [(set RC:$dst, (Int RC:$src1, (ld_frag addr:$src2)))]>, VEX_4V;
2370 let Predicates = [HasBMI2] in {
2371 defm PDEP32 : bmi_pdep_pext<"pdep{l}", GR32, i32mem,
2372 int_x86_bmi_pdep_32, loadi32>, T8XD;
2373 defm PDEP64 : bmi_pdep_pext<"pdep{q}", GR64, i64mem,
2374 int_x86_bmi_pdep_64, loadi64>, T8XD, VEX_W;
2375 defm PEXT32 : bmi_pdep_pext<"pext{l}", GR32, i32mem,
2376 int_x86_bmi_pext_32, loadi32>, T8XS;
2377 defm PEXT64 : bmi_pdep_pext<"pext{q}", GR64, i64mem,
2378 int_x86_bmi_pext_64, loadi64>, T8XS, VEX_W;
2381 //===----------------------------------------------------------------------===//
2384 let Predicates = [HasTBM], Defs = [EFLAGS] in {
2386 multiclass tbm_ternary_imm_intr<bits<8> opc, RegisterClass RC, string OpcodeStr,
2387 X86MemOperand x86memop, PatFrag ld_frag,
2388 Intrinsic Int, Operand immtype,
2389 SDPatternOperator immoperator> {
2390 def ri : Ii32<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, immtype:$cntl),
2391 !strconcat(OpcodeStr,
2392 "\t{$cntl, $src1, $dst|$dst, $src1, $cntl}"),
2393 [(set RC:$dst, (Int RC:$src1, immoperator:$cntl))]>,
2395 def mi : Ii32<opc, MRMSrcMem, (outs RC:$dst),
2396 (ins x86memop:$src1, immtype:$cntl),
2397 !strconcat(OpcodeStr,
2398 "\t{$cntl, $src1, $dst|$dst, $src1, $cntl}"),
2399 [(set RC:$dst, (Int (ld_frag addr:$src1), immoperator:$cntl))]>,
2403 defm BEXTRI32 : tbm_ternary_imm_intr<0x10, GR32, "bextr", i32mem, loadi32,
2404 int_x86_tbm_bextri_u32, i32imm, imm>;
2405 let ImmT = Imm32S in
2406 defm BEXTRI64 : tbm_ternary_imm_intr<0x10, GR64, "bextr", i64mem, loadi64,
2407 int_x86_tbm_bextri_u64, i64i32imm,
2408 i64immSExt32>, VEX_W;
2410 multiclass tbm_binary_rm<bits<8> opc, Format FormReg, Format FormMem,
2411 RegisterClass RC, string OpcodeStr,
2412 X86MemOperand x86memop, PatFrag ld_frag> {
2413 let hasSideEffects = 0 in {
2414 def rr : I<opc, FormReg, (outs RC:$dst), (ins RC:$src),
2415 !strconcat(OpcodeStr,"\t{$src, $dst|$dst, $src}"),
2418 def rm : I<opc, FormMem, (outs RC:$dst), (ins x86memop:$src),
2419 !strconcat(OpcodeStr,"\t{$src, $dst|$dst, $src}"),
2424 multiclass tbm_binary_intr<bits<8> opc, string OpcodeStr,
2425 Format FormReg, Format FormMem> {
2426 defm NAME#32 : tbm_binary_rm<opc, FormReg, FormMem, GR32, OpcodeStr, i32mem,
2428 defm NAME#64 : tbm_binary_rm<opc, FormReg, FormMem, GR64, OpcodeStr, i64mem,
2432 defm BLCFILL : tbm_binary_intr<0x01, "blcfill", MRM1r, MRM1m>;
2433 defm BLCI : tbm_binary_intr<0x02, "blci", MRM6r, MRM6m>;
2434 defm BLCIC : tbm_binary_intr<0x01, "blcic", MRM5r, MRM5m>;
2435 defm BLCMSK : tbm_binary_intr<0x02, "blcmsk", MRM1r, MRM1m>;
2436 defm BLCS : tbm_binary_intr<0x01, "blcs", MRM3r, MRM3m>;
2437 defm BLSFILL : tbm_binary_intr<0x01, "blsfill", MRM2r, MRM2m>;
2438 defm BLSIC : tbm_binary_intr<0x01, "blsic", MRM6r, MRM6m>;
2439 defm T1MSKC : tbm_binary_intr<0x01, "t1mskc", MRM7r, MRM7m>;
2440 defm TZMSK : tbm_binary_intr<0x01, "tzmsk", MRM4r, MRM4m>;
2443 //===----------------------------------------------------------------------===//
2444 // MONITORX/MWAITX Instructions
2446 let SchedRW = [ WriteSystem ] in {
2447 let usesCustomInserter = 1 in {
2448 def MONITORX : PseudoI<(outs), (ins i32mem:$src1, GR32:$src2, GR32:$src3),
2449 [(int_x86_monitorx addr:$src1, GR32:$src2, GR32:$src3)]>,
2450 Requires<[ HasMWAITX ]>;
2453 let Uses = [ EAX, ECX, EDX ] in {
2454 def MONITORXrrr : I<0x01, MRM_FA, (outs), (ins), "monitorx", [], IIC_SSE_MONITORX>,
2455 TB, Requires<[ HasMWAITX ]>;
2458 let Uses = [ ECX, EAX, EBX ] in {
2459 def MWAITXrrr : I<0x01, MRM_FB, (outs), (ins), "mwaitx",
2460 [(int_x86_mwaitx ECX, EAX, EBX)], IIC_SSE_MWAITX>,
2461 TB, Requires<[ HasMWAITX ]>;
2465 def : InstAlias<"mwaitx\t{%eax, %ecx, %ebx|ebx, ecx, eax}", (MWAITXrrr)>,
2466 Requires<[ Not64BitMode ]>;
2467 def : InstAlias<"mwaitx\t{%rax, %rcx, %rbx|rbx, rcx, rax}", (MWAITXrrr)>,
2468 Requires<[ In64BitMode ]>;
2470 def : InstAlias<"monitorx\t{%eax, %ecx, %edx|edx, ecx, eax}", (MONITORXrrr)>,
2471 Requires<[ Not64BitMode ]>;
2472 def : InstAlias<"monitorx\t{%rax, %rcx, %rdx|rdx, rcx, rax}", (MONITORXrrr)>,
2473 Requires<[ In64BitMode ]>;
2475 //===----------------------------------------------------------------------===//
2476 // CLZERO Instruction
2478 let SchedRW = [WriteSystem] in {
2480 def CLZEROr : I<0x01, MRM_FC, (outs), (ins), "clzero", [], IIC_SSE_CLZERO>,
2481 TB, Requires<[HasCLZERO]>;
2483 let usesCustomInserter = 1 in {
2484 def CLZERO : PseudoI<(outs), (ins i32mem:$src1),
2485 [(int_x86_clzero addr:$src1)]>, Requires<[HasCLZERO]>;
2489 def : InstAlias<"clzero\t{%eax|eax}", (CLZEROr)>, Requires<[Not64BitMode]>;
2490 def : InstAlias<"clzero\t{%rax|rax}", (CLZEROr)>, Requires<[In64BitMode]>;
2492 //===----------------------------------------------------------------------===//
2493 // Pattern fragments to auto generate TBM instructions.
2494 //===----------------------------------------------------------------------===//
2496 let Predicates = [HasTBM] in {
2497 def : Pat<(X86bextr GR32:$src1, (i32 imm:$src2)),
2498 (BEXTRI32ri GR32:$src1, imm:$src2)>;
2499 def : Pat<(X86bextr (loadi32 addr:$src1), (i32 imm:$src2)),
2500 (BEXTRI32mi addr:$src1, imm:$src2)>;
2501 def : Pat<(X86bextr GR64:$src1, i64immSExt32:$src2),
2502 (BEXTRI64ri GR64:$src1, i64immSExt32:$src2)>;
2503 def : Pat<(X86bextr (loadi64 addr:$src1), i64immSExt32:$src2),
2504 (BEXTRI64mi addr:$src1, i64immSExt32:$src2)>;
2506 // FIXME: patterns for the load versions are not implemented
2507 def : Pat<(and GR32:$src, (add GR32:$src, 1)),
2508 (BLCFILL32rr GR32:$src)>;
2509 def : Pat<(and GR64:$src, (add GR64:$src, 1)),
2510 (BLCFILL64rr GR64:$src)>;
2512 def : Pat<(or GR32:$src, (not (add GR32:$src, 1))),
2513 (BLCI32rr GR32:$src)>;
2514 def : Pat<(or GR64:$src, (not (add GR64:$src, 1))),
2515 (BLCI64rr GR64:$src)>;
2517 // Extra patterns because opt can optimize the above patterns to this.
2518 def : Pat<(or GR32:$src, (sub -2, GR32:$src)),
2519 (BLCI32rr GR32:$src)>;
2520 def : Pat<(or GR64:$src, (sub -2, GR64:$src)),
2521 (BLCI64rr GR64:$src)>;
2523 def : Pat<(and (not GR32:$src), (add GR32:$src, 1)),
2524 (BLCIC32rr GR32:$src)>;
2525 def : Pat<(and (not GR64:$src), (add GR64:$src, 1)),
2526 (BLCIC64rr GR64:$src)>;
2528 def : Pat<(xor GR32:$src, (add GR32:$src, 1)),
2529 (BLCMSK32rr GR32:$src)>;
2530 def : Pat<(xor GR64:$src, (add GR64:$src, 1)),
2531 (BLCMSK64rr GR64:$src)>;
2533 def : Pat<(or GR32:$src, (add GR32:$src, 1)),
2534 (BLCS32rr GR32:$src)>;
2535 def : Pat<(or GR64:$src, (add GR64:$src, 1)),
2536 (BLCS64rr GR64:$src)>;
2538 def : Pat<(or GR32:$src, (add GR32:$src, -1)),
2539 (BLSFILL32rr GR32:$src)>;
2540 def : Pat<(or GR64:$src, (add GR64:$src, -1)),
2541 (BLSFILL64rr GR64:$src)>;
2543 def : Pat<(or (not GR32:$src), (add GR32:$src, -1)),
2544 (BLSIC32rr GR32:$src)>;
2545 def : Pat<(or (not GR64:$src), (add GR64:$src, -1)),
2546 (BLSIC64rr GR64:$src)>;
2548 def : Pat<(or (not GR32:$src), (add GR32:$src, 1)),
2549 (T1MSKC32rr GR32:$src)>;
2550 def : Pat<(or (not GR64:$src), (add GR64:$src, 1)),
2551 (T1MSKC64rr GR64:$src)>;
2553 def : Pat<(and (not GR32:$src), (add GR32:$src, -1)),
2554 (TZMSK32rr GR32:$src)>;
2555 def : Pat<(and (not GR64:$src), (add GR64:$src, -1)),
2556 (TZMSK64rr GR64:$src)>;
2559 //===----------------------------------------------------------------------===//
2560 // Memory Instructions
2563 let Predicates = [HasCLFLUSHOPT] in
2564 def CLFLUSHOPT : I<0xAE, MRM7m, (outs), (ins i8mem:$src),
2565 "clflushopt\t$src", [(int_x86_clflushopt addr:$src)]>, PD;
2566 def CLWB : I<0xAE, MRM6m, (outs), (ins i8mem:$src), "clwb\t$src", []>, PD;
2569 //===----------------------------------------------------------------------===//
2571 //===----------------------------------------------------------------------===//
2573 include "X86InstrArithmetic.td"
2574 include "X86InstrCMovSetCC.td"
2575 include "X86InstrExtension.td"
2576 include "X86InstrControl.td"
2577 include "X86InstrShiftRotate.td"
2579 // X87 Floating Point Stack.
2580 include "X86InstrFPStack.td"
2582 // SIMD support (SSE, MMX and AVX)
2583 include "X86InstrFragmentsSIMD.td"
2585 // FMA - Fused Multiply-Add support (requires FMA)
2586 include "X86InstrFMA.td"
2589 include "X86InstrXOP.td"
2591 // SSE, MMX and 3DNow! vector support.
2592 include "X86InstrSSE.td"
2593 include "X86InstrAVX512.td"
2594 include "X86InstrMMX.td"
2595 include "X86Instr3DNow.td"
2598 include "X86InstrMPX.td"
2600 include "X86InstrVMX.td"
2601 include "X86InstrSVM.td"
2603 include "X86InstrTSX.td"
2604 include "X86InstrSGX.td"
2606 // System instructions.
2607 include "X86InstrSystem.td"
2609 // Compiler Pseudo Instructions and Pat Patterns
2610 include "X86InstrCompiler.td"
2612 //===----------------------------------------------------------------------===//
2613 // Assembler Mnemonic Aliases
2614 //===----------------------------------------------------------------------===//
2616 def : MnemonicAlias<"call", "callw", "att">, Requires<[In16BitMode]>;
2617 def : MnemonicAlias<"call", "calll", "att">, Requires<[In32BitMode]>;
2618 def : MnemonicAlias<"call", "callq", "att">, Requires<[In64BitMode]>;
2620 def : MnemonicAlias<"cbw", "cbtw", "att">;
2621 def : MnemonicAlias<"cwde", "cwtl", "att">;
2622 def : MnemonicAlias<"cwd", "cwtd", "att">;
2623 def : MnemonicAlias<"cdq", "cltd", "att">;
2624 def : MnemonicAlias<"cdqe", "cltq", "att">;
2625 def : MnemonicAlias<"cqo", "cqto", "att">;
2627 // In 64-bit mode lret maps to lretl; it is not ambiguous with lretq.
2628 def : MnemonicAlias<"lret", "lretw", "att">, Requires<[In16BitMode]>;
2629 def : MnemonicAlias<"lret", "lretl", "att">, Requires<[Not16BitMode]>;
2631 def : MnemonicAlias<"leavel", "leave", "att">, Requires<[Not64BitMode]>;
2632 def : MnemonicAlias<"leaveq", "leave", "att">, Requires<[In64BitMode]>;
2634 def : MnemonicAlias<"loopz", "loope">;
2635 def : MnemonicAlias<"loopnz", "loopne">;
2637 def : MnemonicAlias<"pop", "popw", "att">, Requires<[In16BitMode]>;
2638 def : MnemonicAlias<"pop", "popl", "att">, Requires<[In32BitMode]>;
2639 def : MnemonicAlias<"pop", "popq", "att">, Requires<[In64BitMode]>;
2640 def : MnemonicAlias<"popf", "popfw", "att">, Requires<[In16BitMode]>;
2641 def : MnemonicAlias<"popf", "popfl", "att">, Requires<[In32BitMode]>;
2642 def : MnemonicAlias<"popf", "popfq", "att">, Requires<[In64BitMode]>;
2643 def : MnemonicAlias<"popfd", "popfl", "att">;
2645 // FIXME: This is wrong for "push reg". "push %bx" should turn into pushw in
2646 // all modes. However: "push (addr)" and "push $42" should default to
2647 // pushl/pushq depending on the current mode. Similar for "pop %bx"
2648 def : MnemonicAlias<"push", "pushw", "att">, Requires<[In16BitMode]>;
2649 def : MnemonicAlias<"push", "pushl", "att">, Requires<[In32BitMode]>;
2650 def : MnemonicAlias<"push", "pushq", "att">, Requires<[In64BitMode]>;
2651 def : MnemonicAlias<"pushf", "pushfw", "att">, Requires<[In16BitMode]>;
2652 def : MnemonicAlias<"pushf", "pushfl", "att">, Requires<[In32BitMode]>;
2653 def : MnemonicAlias<"pushf", "pushfq", "att">, Requires<[In64BitMode]>;
2654 def : MnemonicAlias<"pushfd", "pushfl", "att">;
2656 def : MnemonicAlias<"popad", "popal", "intel">, Requires<[Not64BitMode]>;
2657 def : MnemonicAlias<"pushad", "pushal", "intel">, Requires<[Not64BitMode]>;
2658 def : MnemonicAlias<"popa", "popaw", "intel">, Requires<[In16BitMode]>;
2659 def : MnemonicAlias<"pusha", "pushaw", "intel">, Requires<[In16BitMode]>;
2660 def : MnemonicAlias<"popa", "popal", "intel">, Requires<[In32BitMode]>;
2661 def : MnemonicAlias<"pusha", "pushal", "intel">, Requires<[In32BitMode]>;
2663 def : MnemonicAlias<"popa", "popaw", "att">, Requires<[In16BitMode]>;
2664 def : MnemonicAlias<"pusha", "pushaw", "att">, Requires<[In16BitMode]>;
2665 def : MnemonicAlias<"popa", "popal", "att">, Requires<[In32BitMode]>;
2666 def : MnemonicAlias<"pusha", "pushal", "att">, Requires<[In32BitMode]>;
2668 def : MnemonicAlias<"repe", "rep">;
2669 def : MnemonicAlias<"repz", "rep">;
2670 def : MnemonicAlias<"repnz", "repne">;
2672 def : MnemonicAlias<"ret", "retw", "att">, Requires<[In16BitMode]>;
2673 def : MnemonicAlias<"ret", "retl", "att">, Requires<[In32BitMode]>;
2674 def : MnemonicAlias<"ret", "retq", "att">, Requires<[In64BitMode]>;
2676 // Apply 'ret' behavior to 'retn'
2677 def : MnemonicAlias<"retn", "retw", "att">, Requires<[In16BitMode]>;
2678 def : MnemonicAlias<"retn", "retl", "att">, Requires<[In32BitMode]>;
2679 def : MnemonicAlias<"retn", "retq", "att">, Requires<[In64BitMode]>;
2680 def : MnemonicAlias<"retn", "ret", "intel">;
2682 def : MnemonicAlias<"sal", "shl", "intel">;
2683 def : MnemonicAlias<"salb", "shlb", "att">;
2684 def : MnemonicAlias<"salw", "shlw", "att">;
2685 def : MnemonicAlias<"sall", "shll", "att">;
2686 def : MnemonicAlias<"salq", "shlq", "att">;
2688 def : MnemonicAlias<"smovb", "movsb", "att">;
2689 def : MnemonicAlias<"smovw", "movsw", "att">;
2690 def : MnemonicAlias<"smovl", "movsl", "att">;
2691 def : MnemonicAlias<"smovq", "movsq", "att">;
2693 def : MnemonicAlias<"ud2a", "ud2", "att">;
2694 def : MnemonicAlias<"verrw", "verr", "att">;
2696 // System instruction aliases.
2697 def : MnemonicAlias<"iret", "iretw", "att">, Requires<[In16BitMode]>;
2698 def : MnemonicAlias<"iret", "iretl", "att">, Requires<[Not16BitMode]>;
2699 def : MnemonicAlias<"sysret", "sysretl", "att">;
2700 def : MnemonicAlias<"sysexit", "sysexitl", "att">;
2702 def : MnemonicAlias<"lgdt", "lgdtw", "att">, Requires<[In16BitMode]>;
2703 def : MnemonicAlias<"lgdt", "lgdtl", "att">, Requires<[In32BitMode]>;
2704 def : MnemonicAlias<"lgdt", "lgdtq", "att">, Requires<[In64BitMode]>;
2705 def : MnemonicAlias<"lidt", "lidtw", "att">, Requires<[In16BitMode]>;
2706 def : MnemonicAlias<"lidt", "lidtl", "att">, Requires<[In32BitMode]>;
2707 def : MnemonicAlias<"lidt", "lidtq", "att">, Requires<[In64BitMode]>;
2708 def : MnemonicAlias<"sgdt", "sgdtw", "att">, Requires<[In16BitMode]>;
2709 def : MnemonicAlias<"sgdt", "sgdtl", "att">, Requires<[In32BitMode]>;
2710 def : MnemonicAlias<"sgdt", "sgdtq", "att">, Requires<[In64BitMode]>;
2711 def : MnemonicAlias<"sidt", "sidtw", "att">, Requires<[In16BitMode]>;
2712 def : MnemonicAlias<"sidt", "sidtl", "att">, Requires<[In32BitMode]>;
2713 def : MnemonicAlias<"sidt", "sidtq", "att">, Requires<[In64BitMode]>;
2716 // Floating point stack aliases.
2717 def : MnemonicAlias<"fcmovz", "fcmove", "att">;
2718 def : MnemonicAlias<"fcmova", "fcmovnbe", "att">;
2719 def : MnemonicAlias<"fcmovnae", "fcmovb", "att">;
2720 def : MnemonicAlias<"fcmovna", "fcmovbe", "att">;
2721 def : MnemonicAlias<"fcmovae", "fcmovnb", "att">;
2722 def : MnemonicAlias<"fcomip", "fcompi">;
2723 def : MnemonicAlias<"fildq", "fildll", "att">;
2724 def : MnemonicAlias<"fistpq", "fistpll", "att">;
2725 def : MnemonicAlias<"fisttpq", "fisttpll", "att">;
2726 def : MnemonicAlias<"fldcww", "fldcw", "att">;
2727 def : MnemonicAlias<"fnstcww", "fnstcw", "att">;
2728 def : MnemonicAlias<"fnstsww", "fnstsw", "att">;
2729 def : MnemonicAlias<"fucomip", "fucompi">;
2730 def : MnemonicAlias<"fwait", "wait">;
2732 def : MnemonicAlias<"fxsaveq", "fxsave64", "att">;
2733 def : MnemonicAlias<"fxrstorq", "fxrstor64", "att">;
2734 def : MnemonicAlias<"xsaveq", "xsave64", "att">;
2735 def : MnemonicAlias<"xrstorq", "xrstor64", "att">;
2736 def : MnemonicAlias<"xsaveoptq", "xsaveopt64", "att">;
2737 def : MnemonicAlias<"xrstorsq", "xrstors64", "att">;
2738 def : MnemonicAlias<"xsavecq", "xsavec64", "att">;
2739 def : MnemonicAlias<"xsavesq", "xsaves64", "att">;
2741 class CondCodeAlias<string Prefix,string Suffix, string OldCond, string NewCond,
2743 : MnemonicAlias<!strconcat(Prefix, OldCond, Suffix),
2744 !strconcat(Prefix, NewCond, Suffix), VariantName>;
2746 /// IntegerCondCodeMnemonicAlias - This multiclass defines a bunch of
2747 /// MnemonicAlias's that canonicalize the condition code in a mnemonic, for
2748 /// example "setz" -> "sete".
2749 multiclass IntegerCondCodeMnemonicAlias<string Prefix, string Suffix,
2751 def C : CondCodeAlias<Prefix, Suffix, "c", "b", V>; // setc -> setb
2752 def Z : CondCodeAlias<Prefix, Suffix, "z" , "e", V>; // setz -> sete
2753 def NA : CondCodeAlias<Prefix, Suffix, "na", "be", V>; // setna -> setbe
2754 def NB : CondCodeAlias<Prefix, Suffix, "nb", "ae", V>; // setnb -> setae
2755 def NC : CondCodeAlias<Prefix, Suffix, "nc", "ae", V>; // setnc -> setae
2756 def NG : CondCodeAlias<Prefix, Suffix, "ng", "le", V>; // setng -> setle
2757 def NL : CondCodeAlias<Prefix, Suffix, "nl", "ge", V>; // setnl -> setge
2758 def NZ : CondCodeAlias<Prefix, Suffix, "nz", "ne", V>; // setnz -> setne
2759 def PE : CondCodeAlias<Prefix, Suffix, "pe", "p", V>; // setpe -> setp
2760 def PO : CondCodeAlias<Prefix, Suffix, "po", "np", V>; // setpo -> setnp
2762 def NAE : CondCodeAlias<Prefix, Suffix, "nae", "b", V>; // setnae -> setb
2763 def NBE : CondCodeAlias<Prefix, Suffix, "nbe", "a", V>; // setnbe -> seta
2764 def NGE : CondCodeAlias<Prefix, Suffix, "nge", "l", V>; // setnge -> setl
2765 def NLE : CondCodeAlias<Prefix, Suffix, "nle", "g", V>; // setnle -> setg
2768 // Aliases for set<CC>
2769 defm : IntegerCondCodeMnemonicAlias<"set", "">;
2770 // Aliases for j<CC>
2771 defm : IntegerCondCodeMnemonicAlias<"j", "">;
2772 // Aliases for cmov<CC>{w,l,q}
2773 defm : IntegerCondCodeMnemonicAlias<"cmov", "w", "att">;
2774 defm : IntegerCondCodeMnemonicAlias<"cmov", "l", "att">;
2775 defm : IntegerCondCodeMnemonicAlias<"cmov", "q", "att">;
2776 // No size suffix for intel-style asm.
2777 defm : IntegerCondCodeMnemonicAlias<"cmov", "", "intel">;
2780 //===----------------------------------------------------------------------===//
2781 // Assembler Instruction Aliases
2782 //===----------------------------------------------------------------------===//
2784 // aad/aam default to base 10 if no operand is specified.
2785 def : InstAlias<"aad", (AAD8i8 10)>, Requires<[Not64BitMode]>;
2786 def : InstAlias<"aam", (AAM8i8 10)>, Requires<[Not64BitMode]>;
2788 // Disambiguate the mem/imm form of bt-without-a-suffix as btl.
2789 // Likewise for btc/btr/bts.
2790 def : InstAlias<"bt\t{$imm, $mem|$mem, $imm}",
2791 (BT32mi8 i32mem:$mem, i32i8imm:$imm), 0>;
2792 def : InstAlias<"btc\t{$imm, $mem|$mem, $imm}",
2793 (BTC32mi8 i32mem:$mem, i32i8imm:$imm), 0>;
2794 def : InstAlias<"btr\t{$imm, $mem|$mem, $imm}",
2795 (BTR32mi8 i32mem:$mem, i32i8imm:$imm), 0>;
2796 def : InstAlias<"bts\t{$imm, $mem|$mem, $imm}",
2797 (BTS32mi8 i32mem:$mem, i32i8imm:$imm), 0>;
2800 def : InstAlias<"clrb\t$reg", (XOR8rr GR8 :$reg, GR8 :$reg), 0>;
2801 def : InstAlias<"clrw\t$reg", (XOR16rr GR16:$reg, GR16:$reg), 0>;
2802 def : InstAlias<"clrl\t$reg", (XOR32rr GR32:$reg, GR32:$reg), 0>;
2803 def : InstAlias<"clrq\t$reg", (XOR64rr GR64:$reg, GR64:$reg), 0>;
2805 // lods aliases. Accept the destination being omitted because it's implicit
2806 // in the mnemonic, or the mnemonic suffix being omitted because it's implicit
2807 // in the destination.
2808 def : InstAlias<"lodsb\t$src", (LODSB srcidx8:$src), 0>;
2809 def : InstAlias<"lodsw\t$src", (LODSW srcidx16:$src), 0>;
2810 def : InstAlias<"lods{l|d}\t$src", (LODSL srcidx32:$src), 0>;
2811 def : InstAlias<"lodsq\t$src", (LODSQ srcidx64:$src), 0>, Requires<[In64BitMode]>;
2812 def : InstAlias<"lods\t{$src, %al|al, $src}", (LODSB srcidx8:$src), 0>;
2813 def : InstAlias<"lods\t{$src, %ax|ax, $src}", (LODSW srcidx16:$src), 0>;
2814 def : InstAlias<"lods\t{$src, %eax|eax, $src}", (LODSL srcidx32:$src), 0>;
2815 def : InstAlias<"lods\t{$src, %rax|rax, $src}", (LODSQ srcidx64:$src), 0>, Requires<[In64BitMode]>;
2816 def : InstAlias<"lods\t$src", (LODSB srcidx8:$src), 0>;
2817 def : InstAlias<"lods\t$src", (LODSW srcidx16:$src), 0>;
2818 def : InstAlias<"lods\t$src", (LODSL srcidx32:$src), 0>;
2819 def : InstAlias<"lods\t$src", (LODSQ srcidx64:$src), 0>, Requires<[In64BitMode]>;
2822 // stos aliases. Accept the source being omitted because it's implicit in
2823 // the mnemonic, or the mnemonic suffix being omitted because it's implicit
2825 def : InstAlias<"stosb\t$dst", (STOSB dstidx8:$dst), 0>;
2826 def : InstAlias<"stosw\t$dst", (STOSW dstidx16:$dst), 0>;
2827 def : InstAlias<"stos{l|d}\t$dst", (STOSL dstidx32:$dst), 0>;
2828 def : InstAlias<"stosq\t$dst", (STOSQ dstidx64:$dst), 0>, Requires<[In64BitMode]>;
2829 def : InstAlias<"stos\t{%al, $dst|$dst, al}", (STOSB dstidx8:$dst), 0>;
2830 def : InstAlias<"stos\t{%ax, $dst|$dst, ax}", (STOSW dstidx16:$dst), 0>;
2831 def : InstAlias<"stos\t{%eax, $dst|$dst, eax}", (STOSL dstidx32:$dst), 0>;
2832 def : InstAlias<"stos\t{%rax, $dst|$dst, rax}", (STOSQ dstidx64:$dst), 0>, Requires<[In64BitMode]>;
2833 def : InstAlias<"stos\t$dst", (STOSB dstidx8:$dst), 0>;
2834 def : InstAlias<"stos\t$dst", (STOSW dstidx16:$dst), 0>;
2835 def : InstAlias<"stos\t$dst", (STOSL dstidx32:$dst), 0>;
2836 def : InstAlias<"stos\t$dst", (STOSQ dstidx64:$dst), 0>, Requires<[In64BitMode]>;
2839 // scas aliases. Accept the destination being omitted because it's implicit
2840 // in the mnemonic, or the mnemonic suffix being omitted because it's implicit
2841 // in the destination.
2842 def : InstAlias<"scasb\t$dst", (SCASB dstidx8:$dst), 0>;
2843 def : InstAlias<"scasw\t$dst", (SCASW dstidx16:$dst), 0>;
2844 def : InstAlias<"scas{l|d}\t$dst", (SCASL dstidx32:$dst), 0>;
2845 def : InstAlias<"scasq\t$dst", (SCASQ dstidx64:$dst), 0>, Requires<[In64BitMode]>;
2846 def : InstAlias<"scas\t{$dst, %al|al, $dst}", (SCASB dstidx8:$dst), 0>;
2847 def : InstAlias<"scas\t{$dst, %ax|ax, $dst}", (SCASW dstidx16:$dst), 0>;
2848 def : InstAlias<"scas\t{$dst, %eax|eax, $dst}", (SCASL dstidx32:$dst), 0>;
2849 def : InstAlias<"scas\t{$dst, %rax|rax, $dst}", (SCASQ dstidx64:$dst), 0>, Requires<[In64BitMode]>;
2850 def : InstAlias<"scas\t$dst", (SCASB dstidx8:$dst), 0>;
2851 def : InstAlias<"scas\t$dst", (SCASW dstidx16:$dst), 0>;
2852 def : InstAlias<"scas\t$dst", (SCASL dstidx32:$dst), 0>;
2853 def : InstAlias<"scas\t$dst", (SCASQ dstidx64:$dst), 0>, Requires<[In64BitMode]>;
2855 // cmps aliases. Mnemonic suffix being omitted because it's implicit
2856 // in the destination.
2857 def : InstAlias<"cmps\t{$dst, $src|$src, $dst}", (CMPSB dstidx8:$dst, srcidx8:$src), 0>;
2858 def : InstAlias<"cmps\t{$dst, $src|$src, $dst}", (CMPSW dstidx16:$dst, srcidx16:$src), 0>;
2859 def : InstAlias<"cmps\t{$dst, $src|$src, $dst}", (CMPSL dstidx32:$dst, srcidx32:$src), 0>;
2860 def : InstAlias<"cmps\t{$dst, $src|$src, $dst}", (CMPSQ dstidx64:$dst, srcidx64:$src), 0>, Requires<[In64BitMode]>;
2862 // movs aliases. Mnemonic suffix being omitted because it's implicit
2863 // in the destination.
2864 def : InstAlias<"movs\t{$src, $dst|$dst, $src}", (MOVSB dstidx8:$dst, srcidx8:$src), 0>;
2865 def : InstAlias<"movs\t{$src, $dst|$dst, $src}", (MOVSW dstidx16:$dst, srcidx16:$src), 0>;
2866 def : InstAlias<"movs\t{$src, $dst|$dst, $src}", (MOVSL dstidx32:$dst, srcidx32:$src), 0>;
2867 def : InstAlias<"movs\t{$src, $dst|$dst, $src}", (MOVSQ dstidx64:$dst, srcidx64:$src), 0>, Requires<[In64BitMode]>;
2869 // div and idiv aliases for explicit A register.
2870 def : InstAlias<"div{b}\t{$src, %al|al, $src}", (DIV8r GR8 :$src)>;
2871 def : InstAlias<"div{w}\t{$src, %ax|ax, $src}", (DIV16r GR16:$src)>;
2872 def : InstAlias<"div{l}\t{$src, %eax|eax, $src}", (DIV32r GR32:$src)>;
2873 def : InstAlias<"div{q}\t{$src, %rax|rax, $src}", (DIV64r GR64:$src)>;
2874 def : InstAlias<"div{b}\t{$src, %al|al, $src}", (DIV8m i8mem :$src)>;
2875 def : InstAlias<"div{w}\t{$src, %ax|ax, $src}", (DIV16m i16mem:$src)>;
2876 def : InstAlias<"div{l}\t{$src, %eax|eax, $src}", (DIV32m i32mem:$src)>;
2877 def : InstAlias<"div{q}\t{$src, %rax|rax, $src}", (DIV64m i64mem:$src)>;
2878 def : InstAlias<"idiv{b}\t{$src, %al|al, $src}", (IDIV8r GR8 :$src)>;
2879 def : InstAlias<"idiv{w}\t{$src, %ax|ax, $src}", (IDIV16r GR16:$src)>;
2880 def : InstAlias<"idiv{l}\t{$src, %eax|eax, $src}", (IDIV32r GR32:$src)>;
2881 def : InstAlias<"idiv{q}\t{$src, %rax|rax, $src}", (IDIV64r GR64:$src)>;
2882 def : InstAlias<"idiv{b}\t{$src, %al|al, $src}", (IDIV8m i8mem :$src)>;
2883 def : InstAlias<"idiv{w}\t{$src, %ax|ax, $src}", (IDIV16m i16mem:$src)>;
2884 def : InstAlias<"idiv{l}\t{$src, %eax|eax, $src}", (IDIV32m i32mem:$src)>;
2885 def : InstAlias<"idiv{q}\t{$src, %rax|rax, $src}", (IDIV64m i64mem:$src)>;
2889 // Various unary fpstack operations default to operating on on ST1.
2890 // For example, "fxch" -> "fxch %st(1)"
2891 def : InstAlias<"faddp", (ADD_FPrST0 ST1), 0>;
2892 def: InstAlias<"fadd", (ADD_FPrST0 ST1), 0>;
2893 def : InstAlias<"fsub{|r}p", (SUBR_FPrST0 ST1), 0>;
2894 def : InstAlias<"fsub{r|}p", (SUB_FPrST0 ST1), 0>;
2895 def : InstAlias<"fmul", (MUL_FPrST0 ST1), 0>;
2896 def : InstAlias<"fmulp", (MUL_FPrST0 ST1), 0>;
2897 def : InstAlias<"fdiv{|r}p", (DIVR_FPrST0 ST1), 0>;
2898 def : InstAlias<"fdiv{r|}p", (DIV_FPrST0 ST1), 0>;
2899 def : InstAlias<"fxch", (XCH_F ST1), 0>;
2900 def : InstAlias<"fcom", (COM_FST0r ST1), 0>;
2901 def : InstAlias<"fcomp", (COMP_FST0r ST1), 0>;
2902 def : InstAlias<"fcomi", (COM_FIr ST1), 0>;
2903 def : InstAlias<"fcompi", (COM_FIPr ST1), 0>;
2904 def : InstAlias<"fucom", (UCOM_Fr ST1), 0>;
2905 def : InstAlias<"fucomp", (UCOM_FPr ST1), 0>;
2906 def : InstAlias<"fucomi", (UCOM_FIr ST1), 0>;
2907 def : InstAlias<"fucompi", (UCOM_FIPr ST1), 0>;
2909 // Handle fmul/fadd/fsub/fdiv instructions with explicitly written st(0) op.
2910 // For example, "fadd %st(4), %st(0)" -> "fadd %st(4)". We also disambiguate
2911 // instructions like "fadd %st(0), %st(0)" as "fadd %st(0)" for consistency with
2913 multiclass FpUnaryAlias<string Mnemonic, Instruction Inst, bit EmitAlias = 1> {
2914 def : InstAlias<!strconcat(Mnemonic, "\t{$op, %st(0)|st(0), $op}"),
2915 (Inst RST:$op), EmitAlias>;
2916 def : InstAlias<!strconcat(Mnemonic, "\t{%st(0), %st(0)|st(0), st(0)}"),
2917 (Inst ST0), EmitAlias>;
2920 defm : FpUnaryAlias<"fadd", ADD_FST0r>;
2921 defm : FpUnaryAlias<"faddp", ADD_FPrST0, 0>;
2922 defm : FpUnaryAlias<"fsub", SUB_FST0r>;
2923 defm : FpUnaryAlias<"fsub{|r}p", SUBR_FPrST0>;
2924 defm : FpUnaryAlias<"fsubr", SUBR_FST0r>;
2925 defm : FpUnaryAlias<"fsub{r|}p", SUB_FPrST0>;
2926 defm : FpUnaryAlias<"fmul", MUL_FST0r>;
2927 defm : FpUnaryAlias<"fmulp", MUL_FPrST0>;
2928 defm : FpUnaryAlias<"fdiv", DIV_FST0r>;
2929 defm : FpUnaryAlias<"fdiv{|r}p", DIVR_FPrST0>;
2930 defm : FpUnaryAlias<"fdivr", DIVR_FST0r>;
2931 defm : FpUnaryAlias<"fdiv{r|}p", DIV_FPrST0>;
2932 defm : FpUnaryAlias<"fcomi", COM_FIr, 0>;
2933 defm : FpUnaryAlias<"fucomi", UCOM_FIr, 0>;
2934 defm : FpUnaryAlias<"fcompi", COM_FIPr>;
2935 defm : FpUnaryAlias<"fucompi", UCOM_FIPr>;
2938 // Handle "f{mulp,addp} st(0), $op" the same as "f{mulp,addp} $op", since they
2939 // commute. We also allow fdiv[r]p/fsubrp even though they don't commute,
2940 // solely because gas supports it.
2941 def : InstAlias<"faddp\t{%st(0), $op|$op, st(0)}", (ADD_FPrST0 RST:$op), 0>;
2942 def : InstAlias<"fmulp\t{%st(0), $op|$op, st(0)}", (MUL_FPrST0 RST:$op)>;
2943 def : InstAlias<"fsub{|r}p\t{%st(0), $op|$op, st(0)}", (SUBR_FPrST0 RST:$op)>;
2944 def : InstAlias<"fsub{r|}p\t{%st(0), $op|$op, st(0)}", (SUB_FPrST0 RST:$op)>;
2945 def : InstAlias<"fdiv{|r}p\t{%st(0), $op|$op, st(0)}", (DIVR_FPrST0 RST:$op)>;
2946 def : InstAlias<"fdiv{r|}p\t{%st(0), $op|$op, st(0)}", (DIV_FPrST0 RST:$op)>;
2948 // We accept "fnstsw %eax" even though it only writes %ax.
2949 def : InstAlias<"fnstsw\t{%eax|eax}", (FNSTSW16r)>;
2950 def : InstAlias<"fnstsw\t{%al|al}" , (FNSTSW16r)>;
2951 def : InstAlias<"fnstsw" , (FNSTSW16r)>;
2953 // lcall and ljmp aliases. This seems to be an odd mapping in 64-bit mode, but
2954 // this is compatible with what GAS does.
2955 def : InstAlias<"lcall\t$seg, $off", (FARCALL32i i32imm:$off, i16imm:$seg), 0>, Requires<[In32BitMode]>;
2956 def : InstAlias<"ljmp\t$seg, $off", (FARJMP32i i32imm:$off, i16imm:$seg), 0>, Requires<[In32BitMode]>;
2957 def : InstAlias<"lcall\t{*}$dst", (FARCALL32m opaque48mem:$dst), 0>, Requires<[Not16BitMode]>;
2958 def : InstAlias<"ljmp\t{*}$dst", (FARJMP32m opaque48mem:$dst), 0>, Requires<[Not16BitMode]>;
2959 def : InstAlias<"lcall\t$seg, $off", (FARCALL16i i16imm:$off, i16imm:$seg), 0>, Requires<[In16BitMode]>;
2960 def : InstAlias<"ljmp\t$seg, $off", (FARJMP16i i16imm:$off, i16imm:$seg), 0>, Requires<[In16BitMode]>;
2961 def : InstAlias<"lcall\t{*}$dst", (FARCALL16m opaque32mem:$dst), 0>, Requires<[In16BitMode]>;
2962 def : InstAlias<"ljmp\t{*}$dst", (FARJMP16m opaque32mem:$dst), 0>, Requires<[In16BitMode]>;
2964 def : InstAlias<"call\t{*}$dst", (CALL64m i64mem:$dst), 0>, Requires<[In64BitMode]>;
2965 def : InstAlias<"jmp\t{*}$dst", (JMP64m i64mem:$dst), 0>, Requires<[In64BitMode]>;
2966 def : InstAlias<"call\t{*}$dst", (CALL32m i32mem:$dst), 0>, Requires<[In32BitMode]>;
2967 def : InstAlias<"jmp\t{*}$dst", (JMP32m i32mem:$dst), 0>, Requires<[In32BitMode]>;
2968 def : InstAlias<"call\t{*}$dst", (CALL16m i16mem:$dst), 0>, Requires<[In16BitMode]>;
2969 def : InstAlias<"jmp\t{*}$dst", (JMP16m i16mem:$dst), 0>, Requires<[In16BitMode]>;
2972 // "imul <imm>, B" is an alias for "imul <imm>, B, B".
2973 def : InstAlias<"imul{w}\t{$imm, $r|$r, $imm}", (IMUL16rri GR16:$r, GR16:$r, i16imm:$imm), 0>;
2974 def : InstAlias<"imul{w}\t{$imm, $r|$r, $imm}", (IMUL16rri8 GR16:$r, GR16:$r, i16i8imm:$imm), 0>;
2975 def : InstAlias<"imul{l}\t{$imm, $r|$r, $imm}", (IMUL32rri GR32:$r, GR32:$r, i32imm:$imm), 0>;
2976 def : InstAlias<"imul{l}\t{$imm, $r|$r, $imm}", (IMUL32rri8 GR32:$r, GR32:$r, i32i8imm:$imm), 0>;
2977 def : InstAlias<"imul{q}\t{$imm, $r|$r, $imm}", (IMUL64rri32 GR64:$r, GR64:$r, i64i32imm:$imm), 0>;
2978 def : InstAlias<"imul{q}\t{$imm, $r|$r, $imm}", (IMUL64rri8 GR64:$r, GR64:$r, i64i8imm:$imm), 0>;
2980 // ins aliases. Accept the mnemonic suffix being omitted because it's implicit
2981 // in the destination.
2982 def : InstAlias<"ins\t{%dx, $dst|$dst, dx}", (INSB dstidx8:$dst), 0>;
2983 def : InstAlias<"ins\t{%dx, $dst|$dst, dx}", (INSW dstidx16:$dst), 0>;
2984 def : InstAlias<"ins\t{%dx, $dst|$dst, dx}", (INSL dstidx32:$dst), 0>;
2986 // outs aliases. Accept the mnemonic suffix being omitted because it's implicit
2988 def : InstAlias<"outs\t{$src, %dx|dx, $src}", (OUTSB srcidx8:$src), 0>;
2989 def : InstAlias<"outs\t{$src, %dx|dx, $src}", (OUTSW srcidx16:$src), 0>;
2990 def : InstAlias<"outs\t{$src, %dx|dx, $src}", (OUTSL srcidx32:$src), 0>;
2992 // inb %dx -> inb %al, %dx
2993 def : InstAlias<"inb\t{%dx|dx}", (IN8rr), 0>;
2994 def : InstAlias<"inw\t{%dx|dx}", (IN16rr), 0>;
2995 def : InstAlias<"inl\t{%dx|dx}", (IN32rr), 0>;
2996 def : InstAlias<"inb\t$port", (IN8ri u8imm:$port), 0>;
2997 def : InstAlias<"inw\t$port", (IN16ri u8imm:$port), 0>;
2998 def : InstAlias<"inl\t$port", (IN32ri u8imm:$port), 0>;
3001 // jmp and call aliases for lcall and ljmp. jmp $42,$5 -> ljmp
3002 def : InstAlias<"call\t$seg, $off", (FARCALL16i i16imm:$off, i16imm:$seg)>, Requires<[In16BitMode]>;
3003 def : InstAlias<"jmp\t$seg, $off", (FARJMP16i i16imm:$off, i16imm:$seg)>, Requires<[In16BitMode]>;
3004 def : InstAlias<"call\t$seg, $off", (FARCALL32i i32imm:$off, i16imm:$seg)>, Requires<[In32BitMode]>;
3005 def : InstAlias<"jmp\t$seg, $off", (FARJMP32i i32imm:$off, i16imm:$seg)>, Requires<[In32BitMode]>;
3006 def : InstAlias<"callw\t$seg, $off", (FARCALL16i i16imm:$off, i16imm:$seg)>, Requires<[Not64BitMode]>;
3007 def : InstAlias<"jmpw\t$seg, $off", (FARJMP16i i16imm:$off, i16imm:$seg)>, Requires<[Not64BitMode]>;
3008 def : InstAlias<"calll\t$seg, $off", (FARCALL32i i32imm:$off, i16imm:$seg)>, Requires<[Not64BitMode]>;
3009 def : InstAlias<"jmpl\t$seg, $off", (FARJMP32i i32imm:$off, i16imm:$seg)>, Requires<[Not64BitMode]>;
3011 // Force mov without a suffix with a segment and mem to prefer the 'l' form of
3012 // the move. All segment/mem forms are equivalent, this has the shortest
3014 def : InstAlias<"mov\t{$mem, $seg|$seg, $mem}", (MOV32sm SEGMENT_REG:$seg, i32mem:$mem), 0>;
3015 def : InstAlias<"mov\t{$seg, $mem|$mem, $seg}", (MOV32ms i32mem:$mem, SEGMENT_REG:$seg), 0>;
3017 // Match 'movq <largeimm>, <reg>' as an alias for movabsq.
3018 def : InstAlias<"mov{q}\t{$imm, $reg|$reg, $imm}", (MOV64ri GR64:$reg, i64imm:$imm), 0>;
3020 // Match 'movq GR64, MMX' as an alias for movd.
3021 def : InstAlias<"movq\t{$src, $dst|$dst, $src}",
3022 (MMX_MOVD64to64rr VR64:$dst, GR64:$src), 0>;
3023 def : InstAlias<"movq\t{$src, $dst|$dst, $src}",
3024 (MMX_MOVD64from64rr GR64:$dst, VR64:$src), 0>;
3027 def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX16rr8 GR16:$dst, GR8:$src), 0>;
3028 def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX16rm8 GR16:$dst, i8mem:$src), 0>;
3029 def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX32rr8 GR32:$dst, GR8:$src), 0>;
3030 def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX32rr16 GR32:$dst, GR16:$src), 0>;
3031 def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX64rr8 GR64:$dst, GR8:$src), 0>;
3032 def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX64rr16 GR64:$dst, GR16:$src), 0>;
3033 def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX64rr32 GR64:$dst, GR32:$src), 0>;
3036 def : InstAlias<"movzx\t{$src, $dst|$dst, $src}", (MOVZX16rr8 GR16:$dst, GR8:$src), 0>;
3037 def : InstAlias<"movzx\t{$src, $dst|$dst, $src}", (MOVZX16rm8 GR16:$dst, i8mem:$src), 0>;
3038 def : InstAlias<"movzx\t{$src, $dst|$dst, $src}", (MOVZX32rr8 GR32:$dst, GR8:$src), 0>;
3039 def : InstAlias<"movzx\t{$src, $dst|$dst, $src}", (MOVZX32rr16 GR32:$dst, GR16:$src), 0>;
3040 def : InstAlias<"movzx\t{$src, $dst|$dst, $src}", (MOVZX64rr8 GR64:$dst, GR8:$src), 0>;
3041 def : InstAlias<"movzx\t{$src, $dst|$dst, $src}", (MOVZX64rr16 GR64:$dst, GR16:$src), 0>;
3042 // Note: No GR32->GR64 movzx form.
3044 // outb %dx -> outb %al, %dx
3045 def : InstAlias<"outb\t{%dx|dx}", (OUT8rr), 0>;
3046 def : InstAlias<"outw\t{%dx|dx}", (OUT16rr), 0>;
3047 def : InstAlias<"outl\t{%dx|dx}", (OUT32rr), 0>;
3048 def : InstAlias<"outb\t$port", (OUT8ir u8imm:$port), 0>;
3049 def : InstAlias<"outw\t$port", (OUT16ir u8imm:$port), 0>;
3050 def : InstAlias<"outl\t$port", (OUT32ir u8imm:$port), 0>;
3052 // 'sldt <mem>' can be encoded with either sldtw or sldtq with the same
3053 // effect (both store to a 16-bit mem). Force to sldtw to avoid ambiguity
3054 // errors, since its encoding is the most compact.
3055 def : InstAlias<"sldt $mem", (SLDT16m i16mem:$mem), 0>;
3057 // shld/shrd op,op -> shld op, op, CL
3058 def : InstAlias<"shld{w}\t{$r2, $r1|$r1, $r2}", (SHLD16rrCL GR16:$r1, GR16:$r2), 0>;
3059 def : InstAlias<"shld{l}\t{$r2, $r1|$r1, $r2}", (SHLD32rrCL GR32:$r1, GR32:$r2), 0>;
3060 def : InstAlias<"shld{q}\t{$r2, $r1|$r1, $r2}", (SHLD64rrCL GR64:$r1, GR64:$r2), 0>;
3061 def : InstAlias<"shrd{w}\t{$r2, $r1|$r1, $r2}", (SHRD16rrCL GR16:$r1, GR16:$r2), 0>;
3062 def : InstAlias<"shrd{l}\t{$r2, $r1|$r1, $r2}", (SHRD32rrCL GR32:$r1, GR32:$r2), 0>;
3063 def : InstAlias<"shrd{q}\t{$r2, $r1|$r1, $r2}", (SHRD64rrCL GR64:$r1, GR64:$r2), 0>;
3065 def : InstAlias<"shld{w}\t{$reg, $mem|$mem, $reg}", (SHLD16mrCL i16mem:$mem, GR16:$reg), 0>;
3066 def : InstAlias<"shld{l}\t{$reg, $mem|$mem, $reg}", (SHLD32mrCL i32mem:$mem, GR32:$reg), 0>;
3067 def : InstAlias<"shld{q}\t{$reg, $mem|$mem, $reg}", (SHLD64mrCL i64mem:$mem, GR64:$reg), 0>;
3068 def : InstAlias<"shrd{w}\t{$reg, $mem|$mem, $reg}", (SHRD16mrCL i16mem:$mem, GR16:$reg), 0>;
3069 def : InstAlias<"shrd{l}\t{$reg, $mem|$mem, $reg}", (SHRD32mrCL i32mem:$mem, GR32:$reg), 0>;
3070 def : InstAlias<"shrd{q}\t{$reg, $mem|$mem, $reg}", (SHRD64mrCL i64mem:$mem, GR64:$reg), 0>;
3072 /* FIXME: This is disabled because the asm matcher is currently incapable of
3073 * matching a fixed immediate like $1.
3074 // "shl X, $1" is an alias for "shl X".
3075 multiclass ShiftRotateByOneAlias<string Mnemonic, string Opc> {
3076 def : InstAlias<!strconcat(Mnemonic, "b $op, $$1"),
3077 (!cast<Instruction>(!strconcat(Opc, "8r1")) GR8:$op)>;
3078 def : InstAlias<!strconcat(Mnemonic, "w $op, $$1"),
3079 (!cast<Instruction>(!strconcat(Opc, "16r1")) GR16:$op)>;
3080 def : InstAlias<!strconcat(Mnemonic, "l $op, $$1"),
3081 (!cast<Instruction>(!strconcat(Opc, "32r1")) GR32:$op)>;
3082 def : InstAlias<!strconcat(Mnemonic, "q $op, $$1"),
3083 (!cast<Instruction>(!strconcat(Opc, "64r1")) GR64:$op)>;
3084 def : InstAlias<!strconcat(Mnemonic, "b $op, $$1"),
3085 (!cast<Instruction>(!strconcat(Opc, "8m1")) i8mem:$op)>;
3086 def : InstAlias<!strconcat(Mnemonic, "w $op, $$1"),
3087 (!cast<Instruction>(!strconcat(Opc, "16m1")) i16mem:$op)>;
3088 def : InstAlias<!strconcat(Mnemonic, "l $op, $$1"),
3089 (!cast<Instruction>(!strconcat(Opc, "32m1")) i32mem:$op)>;
3090 def : InstAlias<!strconcat(Mnemonic, "q $op, $$1"),
3091 (!cast<Instruction>(!strconcat(Opc, "64m1")) i64mem:$op)>;
3094 defm : ShiftRotateByOneAlias<"rcl", "RCL">;
3095 defm : ShiftRotateByOneAlias<"rcr", "RCR">;
3096 defm : ShiftRotateByOneAlias<"rol", "ROL">;
3097 defm : ShiftRotateByOneAlias<"ror", "ROR">;
3100 // test: We accept "testX <reg>, <mem>" and "testX <mem>, <reg>" as synonyms.
3101 def : InstAlias<"test{b}\t{$val, $mem|$mem, $val}",
3102 (TEST8rm GR8 :$val, i8mem :$mem), 0>;
3103 def : InstAlias<"test{w}\t{$val, $mem|$mem, $val}",
3104 (TEST16rm GR16:$val, i16mem:$mem), 0>;
3105 def : InstAlias<"test{l}\t{$val, $mem|$mem, $val}",
3106 (TEST32rm GR32:$val, i32mem:$mem), 0>;
3107 def : InstAlias<"test{q}\t{$val, $mem|$mem, $val}",
3108 (TEST64rm GR64:$val, i64mem:$mem), 0>;
3110 // xchg: We accept "xchgX <reg>, <mem>" and "xchgX <mem>, <reg>" as synonyms.
3111 def : InstAlias<"xchg{b}\t{$mem, $val|$val, $mem}",
3112 (XCHG8rm GR8 :$val, i8mem :$mem), 0>;
3113 def : InstAlias<"xchg{w}\t{$mem, $val|$val, $mem}",
3114 (XCHG16rm GR16:$val, i16mem:$mem), 0>;
3115 def : InstAlias<"xchg{l}\t{$mem, $val|$val, $mem}",
3116 (XCHG32rm GR32:$val, i32mem:$mem), 0>;
3117 def : InstAlias<"xchg{q}\t{$mem, $val|$val, $mem}",
3118 (XCHG64rm GR64:$val, i64mem:$mem), 0>;
3120 // xchg: We accept "xchgX <reg>, %eax" and "xchgX %eax, <reg>" as synonyms.
3121 def : InstAlias<"xchg{w}\t{%ax, $src|$src, ax}", (XCHG16ar GR16:$src), 0>;
3122 def : InstAlias<"xchg{l}\t{%eax, $src|$src, eax}",
3123 (XCHG32ar GR32:$src), 0>, Requires<[Not64BitMode]>;
3124 def : InstAlias<"xchg{l}\t{%eax, $src|$src, eax}",
3125 (XCHG32ar64 GR32_NOAX:$src), 0>, Requires<[In64BitMode]>;
3126 def : InstAlias<"xchg{q}\t{%rax, $src|$src, rax}", (XCHG64ar GR64:$src), 0>;
3128 // These aliases exist to get the parser to prioritize matching 8-bit
3129 // immediate encodings over matching the implicit ax/eax/rax encodings. By
3130 // explicitly mentioning the A register here, these entries will be ordered
3131 // first due to the more explicit immediate type.
3132 def : InstAlias<"adc{w}\t{$imm, %ax|ax, $imm}", (ADC16ri8 AX, i16i8imm:$imm), 0>;
3133 def : InstAlias<"add{w}\t{$imm, %ax|ax, $imm}", (ADD16ri8 AX, i16i8imm:$imm), 0>;
3134 def : InstAlias<"and{w}\t{$imm, %ax|ax, $imm}", (AND16ri8 AX, i16i8imm:$imm), 0>;
3135 def : InstAlias<"cmp{w}\t{$imm, %ax|ax, $imm}", (CMP16ri8 AX, i16i8imm:$imm), 0>;
3136 def : InstAlias<"or{w}\t{$imm, %ax|ax, $imm}", (OR16ri8 AX, i16i8imm:$imm), 0>;
3137 def : InstAlias<"sbb{w}\t{$imm, %ax|ax, $imm}", (SBB16ri8 AX, i16i8imm:$imm), 0>;
3138 def : InstAlias<"sub{w}\t{$imm, %ax|ax, $imm}", (SUB16ri8 AX, i16i8imm:$imm), 0>;
3139 def : InstAlias<"xor{w}\t{$imm, %ax|ax, $imm}", (XOR16ri8 AX, i16i8imm:$imm), 0>;
3141 def : InstAlias<"adc{l}\t{$imm, %eax|eax, $imm}", (ADC32ri8 EAX, i32i8imm:$imm), 0>;
3142 def : InstAlias<"add{l}\t{$imm, %eax|eax, $imm}", (ADD32ri8 EAX, i32i8imm:$imm), 0>;
3143 def : InstAlias<"and{l}\t{$imm, %eax|eax, $imm}", (AND32ri8 EAX, i32i8imm:$imm), 0>;
3144 def : InstAlias<"cmp{l}\t{$imm, %eax|eax, $imm}", (CMP32ri8 EAX, i32i8imm:$imm), 0>;
3145 def : InstAlias<"or{l}\t{$imm, %eax|eax, $imm}", (OR32ri8 EAX, i32i8imm:$imm), 0>;
3146 def : InstAlias<"sbb{l}\t{$imm, %eax|eax, $imm}", (SBB32ri8 EAX, i32i8imm:$imm), 0>;
3147 def : InstAlias<"sub{l}\t{$imm, %eax|eax, $imm}", (SUB32ri8 EAX, i32i8imm:$imm), 0>;
3148 def : InstAlias<"xor{l}\t{$imm, %eax|eax, $imm}", (XOR32ri8 EAX, i32i8imm:$imm), 0>;
3150 def : InstAlias<"adc{q}\t{$imm, %rax|rax, $imm}", (ADC64ri8 RAX, i64i8imm:$imm), 0>;
3151 def : InstAlias<"add{q}\t{$imm, %rax|rax, $imm}", (ADD64ri8 RAX, i64i8imm:$imm), 0>;
3152 def : InstAlias<"and{q}\t{$imm, %rax|rax, $imm}", (AND64ri8 RAX, i64i8imm:$imm), 0>;
3153 def : InstAlias<"cmp{q}\t{$imm, %rax|rax, $imm}", (CMP64ri8 RAX, i64i8imm:$imm), 0>;
3154 def : InstAlias<"or{q}\t{$imm, %rax|rax, $imm}", (OR64ri8 RAX, i64i8imm:$imm), 0>;
3155 def : InstAlias<"sbb{q}\t{$imm, %rax|rax, $imm}", (SBB64ri8 RAX, i64i8imm:$imm), 0>;
3156 def : InstAlias<"sub{q}\t{$imm, %rax|rax, $imm}", (SUB64ri8 RAX, i64i8imm:$imm), 0>;
3157 def : InstAlias<"xor{q}\t{$imm, %rax|rax, $imm}", (XOR64ri8 RAX, i64i8imm:$imm), 0>;