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 SDTLockUnaryArithWithFlags : SDTypeProfile<1, 1, [SDTCisVT<0, i32>,
88 def SDTX86Ret : SDTypeProfile<0, -1, [SDTCisVT<0, i32>]>;
90 def SDT_X86CallSeqStart : SDCallSeqStart<[SDTCisVT<0, i32>,
92 def SDT_X86CallSeqEnd : SDCallSeqEnd<[SDTCisVT<0, i32>,
95 def SDT_X86Call : SDTypeProfile<0, -1, [SDTCisVT<0, iPTR>]>;
97 def SDT_X86VASTART_SAVE_XMM_REGS : SDTypeProfile<0, -1, [SDTCisVT<0, i8>,
101 def SDT_X86VAARG_64 : SDTypeProfile<1, -1, [SDTCisPtrTy<0>,
107 def SDTX86RepStr : SDTypeProfile<0, 1, [SDTCisVT<0, OtherVT>]>;
109 def SDTX86Void : SDTypeProfile<0, 0, []>;
111 def SDTX86Wrapper : SDTypeProfile<1, 1, [SDTCisSameAs<0, 1>, SDTCisPtrTy<0>]>;
113 def SDT_X86TLSADDR : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
115 def SDT_X86TLSBASEADDR : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
117 def SDT_X86TLSCALL : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
119 def SDT_X86WIN_ALLOCA : SDTypeProfile<0, 1, [SDTCisVT<0, iPTR>]>;
121 def SDT_X86SEG_ALLOCA : SDTypeProfile<1, 1, [SDTCisVT<0, iPTR>, SDTCisVT<1, iPTR>]>;
123 def SDT_X86EHRET : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
125 def SDT_X86TCRET : SDTypeProfile<0, 2, [SDTCisPtrTy<0>, SDTCisVT<1, i32>]>;
127 def SDT_X86MEMBARRIER : SDTypeProfile<0, 0, []>;
129 def X86MemBarrier : SDNode<"X86ISD::MEMBARRIER", SDT_X86MEMBARRIER,
130 [SDNPHasChain,SDNPSideEffect]>;
131 def X86MFence : SDNode<"X86ISD::MFENCE", SDT_X86MEMBARRIER,
135 def X86bsf : SDNode<"X86ISD::BSF", SDTUnaryArithWithFlags>;
136 def X86bsr : SDNode<"X86ISD::BSR", SDTUnaryArithWithFlags>;
137 def X86shld : SDNode<"X86ISD::SHLD", SDTIntShiftDOp>;
138 def X86shrd : SDNode<"X86ISD::SHRD", SDTIntShiftDOp>;
140 def X86cmp : SDNode<"X86ISD::CMP" , SDTX86CmpTest>;
141 def X86bt : SDNode<"X86ISD::BT", SDTX86CmpTest>;
143 def X86cmov : SDNode<"X86ISD::CMOV", SDTX86Cmov>;
144 def X86brcond : SDNode<"X86ISD::BRCOND", SDTX86BrCond,
146 def X86setcc : SDNode<"X86ISD::SETCC", SDTX86SetCC>;
147 def X86setcc_c : SDNode<"X86ISD::SETCC_CARRY", SDTX86SetCC_C>;
149 def X86sahf : SDNode<"X86ISD::SAHF", SDTX86sahf>;
151 def X86rdrand : SDNode<"X86ISD::RDRAND", SDTX86rdrand,
152 [SDNPHasChain, SDNPSideEffect]>;
154 def X86rdseed : SDNode<"X86ISD::RDSEED", SDTX86rdrand,
155 [SDNPHasChain, SDNPSideEffect]>;
157 def X86cas : SDNode<"X86ISD::LCMPXCHG_DAG", SDTX86cas,
158 [SDNPHasChain, SDNPInGlue, SDNPOutGlue, SDNPMayStore,
159 SDNPMayLoad, SDNPMemOperand]>;
160 def X86cas8 : SDNode<"X86ISD::LCMPXCHG8_DAG", SDTX86caspair,
161 [SDNPHasChain, SDNPInGlue, SDNPOutGlue, SDNPMayStore,
162 SDNPMayLoad, SDNPMemOperand]>;
163 def X86cas16 : SDNode<"X86ISD::LCMPXCHG16_DAG", SDTX86caspair,
164 [SDNPHasChain, SDNPInGlue, SDNPOutGlue, SDNPMayStore,
165 SDNPMayLoad, SDNPMemOperand]>;
166 def X86cas8save_ebx : SDNode<"X86ISD::LCMPXCHG8_SAVE_EBX_DAG",
167 SDTX86caspairSaveEbx8,
168 [SDNPHasChain, SDNPInGlue, SDNPOutGlue,
169 SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
170 def X86cas16save_rbx : SDNode<"X86ISD::LCMPXCHG16_SAVE_RBX_DAG",
171 SDTX86caspairSaveRbx16,
172 [SDNPHasChain, SDNPInGlue, SDNPOutGlue,
173 SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
175 def X86retflag : SDNode<"X86ISD::RET_FLAG", SDTX86Ret,
176 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
177 def X86iret : SDNode<"X86ISD::IRET", SDTX86Ret,
178 [SDNPHasChain, SDNPOptInGlue]>;
180 def X86vastart_save_xmm_regs :
181 SDNode<"X86ISD::VASTART_SAVE_XMM_REGS",
182 SDT_X86VASTART_SAVE_XMM_REGS,
183 [SDNPHasChain, SDNPVariadic]>;
185 SDNode<"X86ISD::VAARG_64", SDT_X86VAARG_64,
186 [SDNPHasChain, SDNPMayLoad, SDNPMayStore,
188 def X86callseq_start :
189 SDNode<"ISD::CALLSEQ_START", SDT_X86CallSeqStart,
190 [SDNPHasChain, SDNPOutGlue]>;
192 SDNode<"ISD::CALLSEQ_END", SDT_X86CallSeqEnd,
193 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
195 def X86call : SDNode<"X86ISD::CALL", SDT_X86Call,
196 [SDNPHasChain, SDNPOutGlue, SDNPOptInGlue,
199 def X86rep_stos: SDNode<"X86ISD::REP_STOS", SDTX86RepStr,
200 [SDNPHasChain, SDNPInGlue, SDNPOutGlue, SDNPMayStore]>;
201 def X86rep_movs: SDNode<"X86ISD::REP_MOVS", SDTX86RepStr,
202 [SDNPHasChain, SDNPInGlue, SDNPOutGlue, SDNPMayStore,
205 def X86rdtsc : SDNode<"X86ISD::RDTSC_DAG", SDTX86Void,
206 [SDNPHasChain, SDNPOutGlue, SDNPSideEffect]>;
207 def X86rdtscp : SDNode<"X86ISD::RDTSCP_DAG", SDTX86Void,
208 [SDNPHasChain, SDNPOutGlue, SDNPSideEffect]>;
209 def X86rdpmc : SDNode<"X86ISD::RDPMC_DAG", SDTX86Void,
210 [SDNPHasChain, SDNPOutGlue, SDNPSideEffect]>;
212 def X86Wrapper : SDNode<"X86ISD::Wrapper", SDTX86Wrapper>;
213 def X86WrapperRIP : SDNode<"X86ISD::WrapperRIP", SDTX86Wrapper>;
215 def X86RecoverFrameAlloc : SDNode<"ISD::LOCAL_RECOVER",
216 SDTypeProfile<1, 1, [SDTCisSameAs<0, 1>,
219 def X86tlsaddr : SDNode<"X86ISD::TLSADDR", SDT_X86TLSADDR,
220 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
222 def X86tlsbaseaddr : SDNode<"X86ISD::TLSBASEADDR", SDT_X86TLSBASEADDR,
223 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
225 def X86ehret : SDNode<"X86ISD::EH_RETURN", SDT_X86EHRET,
228 def X86eh_sjlj_setjmp : SDNode<"X86ISD::EH_SJLJ_SETJMP",
229 SDTypeProfile<1, 1, [SDTCisInt<0>,
231 [SDNPHasChain, SDNPSideEffect]>;
232 def X86eh_sjlj_longjmp : SDNode<"X86ISD::EH_SJLJ_LONGJMP",
233 SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>,
234 [SDNPHasChain, SDNPSideEffect]>;
235 def X86eh_sjlj_setup_dispatch : SDNode<"X86ISD::EH_SJLJ_SETUP_DISPATCH",
236 SDTypeProfile<0, 0, []>,
237 [SDNPHasChain, SDNPSideEffect]>;
239 def X86tcret : SDNode<"X86ISD::TC_RETURN", SDT_X86TCRET,
240 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
242 def X86add_flag : SDNode<"X86ISD::ADD", SDTBinaryArithWithFlags,
244 def X86sub_flag : SDNode<"X86ISD::SUB", SDTBinaryArithWithFlags>;
245 def X86smul_flag : SDNode<"X86ISD::SMUL", SDTBinaryArithWithFlags,
247 def X86umul_flag : SDNode<"X86ISD::UMUL", SDT2ResultBinaryArithWithFlags,
249 def X86adc_flag : SDNode<"X86ISD::ADC", SDTBinaryArithWithFlagsInOut>;
250 def X86sbb_flag : SDNode<"X86ISD::SBB", SDTBinaryArithWithFlagsInOut>;
252 def X86inc_flag : SDNode<"X86ISD::INC", SDTUnaryArithWithFlags>;
253 def X86dec_flag : SDNode<"X86ISD::DEC", SDTUnaryArithWithFlags>;
254 def X86or_flag : SDNode<"X86ISD::OR", SDTBinaryArithWithFlags,
256 def X86xor_flag : SDNode<"X86ISD::XOR", SDTBinaryArithWithFlags,
258 def X86and_flag : SDNode<"X86ISD::AND", SDTBinaryArithWithFlags,
261 def X86lock_add : SDNode<"X86ISD::LADD", SDTLockBinaryArithWithFlags,
262 [SDNPHasChain, SDNPMayStore, SDNPMayLoad,
264 def X86lock_sub : SDNode<"X86ISD::LSUB", SDTLockBinaryArithWithFlags,
265 [SDNPHasChain, SDNPMayStore, SDNPMayLoad,
267 def X86lock_or : SDNode<"X86ISD::LOR", SDTLockBinaryArithWithFlags,
268 [SDNPHasChain, SDNPMayStore, SDNPMayLoad,
270 def X86lock_xor : SDNode<"X86ISD::LXOR", SDTLockBinaryArithWithFlags,
271 [SDNPHasChain, SDNPMayStore, SDNPMayLoad,
273 def X86lock_and : SDNode<"X86ISD::LAND", SDTLockBinaryArithWithFlags,
274 [SDNPHasChain, SDNPMayStore, SDNPMayLoad,
277 def X86lock_inc : SDNode<"X86ISD::LINC", SDTLockUnaryArithWithFlags,
278 [SDNPHasChain, SDNPMayStore, SDNPMayLoad,
280 def X86lock_dec : SDNode<"X86ISD::LDEC", SDTLockUnaryArithWithFlags,
281 [SDNPHasChain, SDNPMayStore, SDNPMayLoad,
284 def X86mul_imm : SDNode<"X86ISD::MUL_IMM", SDTIntBinOp>;
286 def X86WinAlloca : SDNode<"X86ISD::WIN_ALLOCA", SDT_X86WIN_ALLOCA,
287 [SDNPHasChain, SDNPOutGlue]>;
289 def X86SegAlloca : SDNode<"X86ISD::SEG_ALLOCA", SDT_X86SEG_ALLOCA,
292 def X86TLSCall : SDNode<"X86ISD::TLSCALL", SDT_X86TLSCALL,
293 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
295 def X86lwpins : SDNode<"X86ISD::LWPINS",
296 SDTypeProfile<1, 3, [SDTCisVT<0, i32>, SDTCisInt<1>,
297 SDTCisVT<2, i32>, SDTCisVT<3, i32>]>,
298 [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPSideEffect]>;
300 //===----------------------------------------------------------------------===//
301 // X86 Operand Definitions.
304 // A version of ptr_rc which excludes SP, ESP, and RSP. This is used for
305 // the index operand of an address, to conform to x86 encoding restrictions.
306 def ptr_rc_nosp : PointerLikeRegClass<1>;
308 // *mem - Operand definitions for the funky X86 addressing mode operands.
310 def X86MemAsmOperand : AsmOperandClass {
313 let RenderMethod = "addMemOperands", SuperClasses = [X86MemAsmOperand] in {
314 def X86Mem8AsmOperand : AsmOperandClass { let Name = "Mem8"; }
315 def X86Mem16AsmOperand : AsmOperandClass { let Name = "Mem16"; }
316 def X86Mem32AsmOperand : AsmOperandClass { let Name = "Mem32"; }
317 def X86Mem64AsmOperand : AsmOperandClass { let Name = "Mem64"; }
318 def X86Mem80AsmOperand : AsmOperandClass { let Name = "Mem80"; }
319 def X86Mem128AsmOperand : AsmOperandClass { let Name = "Mem128"; }
320 def X86Mem256AsmOperand : AsmOperandClass { let Name = "Mem256"; }
321 def X86Mem512AsmOperand : AsmOperandClass { let Name = "Mem512"; }
322 // Gather mem operands
323 def X86Mem64_RC128Operand : AsmOperandClass { let Name = "Mem64_RC128"; }
324 def X86Mem128_RC128Operand : AsmOperandClass { let Name = "Mem128_RC128"; }
325 def X86Mem256_RC128Operand : AsmOperandClass { let Name = "Mem256_RC128"; }
326 def X86Mem128_RC256Operand : AsmOperandClass { let Name = "Mem128_RC256"; }
327 def X86Mem256_RC256Operand : AsmOperandClass { let Name = "Mem256_RC256"; }
329 def X86Mem64_RC128XOperand : AsmOperandClass { let Name = "Mem64_RC128X"; }
330 def X86Mem128_RC128XOperand : AsmOperandClass { let Name = "Mem128_RC128X"; }
331 def X86Mem256_RC128XOperand : AsmOperandClass { let Name = "Mem256_RC128X"; }
332 def X86Mem128_RC256XOperand : AsmOperandClass { let Name = "Mem128_RC256X"; }
333 def X86Mem256_RC256XOperand : AsmOperandClass { let Name = "Mem256_RC256X"; }
334 def X86Mem512_RC256XOperand : AsmOperandClass { let Name = "Mem512_RC256X"; }
335 def X86Mem256_RC512Operand : AsmOperandClass { let Name = "Mem256_RC512"; }
336 def X86Mem512_RC512Operand : AsmOperandClass { let Name = "Mem512_RC512"; }
339 def X86AbsMemAsmOperand : AsmOperandClass {
341 let SuperClasses = [X86MemAsmOperand];
344 class X86MemOperand<string printMethod,
345 AsmOperandClass parserMatchClass = X86MemAsmOperand> : Operand<iPTR> {
346 let PrintMethod = printMethod;
347 let MIOperandInfo = (ops ptr_rc, i8imm, ptr_rc_nosp, i32imm, SEGMENT_REG);
348 let ParserMatchClass = parserMatchClass;
349 let OperandType = "OPERAND_MEMORY";
352 // Gather mem operands
353 class X86VMemOperand<RegisterClass RC, string printMethod,
354 AsmOperandClass parserMatchClass>
355 : X86MemOperand<printMethod, parserMatchClass> {
356 let MIOperandInfo = (ops ptr_rc, i8imm, RC, i32imm, SEGMENT_REG);
359 def anymem : X86MemOperand<"printanymem">;
361 def opaque32mem : X86MemOperand<"printopaquemem">;
362 def opaque48mem : X86MemOperand<"printopaquemem">;
363 def opaque80mem : X86MemOperand<"printopaquemem">;
364 def opaque512mem : X86MemOperand<"printopaquemem">;
366 def i8mem : X86MemOperand<"printi8mem", X86Mem8AsmOperand>;
367 def i16mem : X86MemOperand<"printi16mem", X86Mem16AsmOperand>;
368 def i32mem : X86MemOperand<"printi32mem", X86Mem32AsmOperand>;
369 def i64mem : X86MemOperand<"printi64mem", X86Mem64AsmOperand>;
370 def i128mem : X86MemOperand<"printi128mem", X86Mem128AsmOperand>;
371 def i256mem : X86MemOperand<"printi256mem", X86Mem256AsmOperand>;
372 def i512mem : X86MemOperand<"printi512mem", X86Mem512AsmOperand>;
373 def f32mem : X86MemOperand<"printf32mem", X86Mem32AsmOperand>;
374 def f64mem : X86MemOperand<"printf64mem", X86Mem64AsmOperand>;
375 def f80mem : X86MemOperand<"printf80mem", X86Mem80AsmOperand>;
376 def f128mem : X86MemOperand<"printf128mem", X86Mem128AsmOperand>;
377 def f256mem : X86MemOperand<"printf256mem", X86Mem256AsmOperand>;
378 def f512mem : X86MemOperand<"printf512mem", X86Mem512AsmOperand>;
380 def v512mem : X86VMemOperand<VR512, "printf512mem", X86Mem512AsmOperand>;
382 // Gather mem operands
383 def vx64mem : X86VMemOperand<VR128, "printi64mem", X86Mem64_RC128Operand>;
384 def vx128mem : X86VMemOperand<VR128, "printi128mem", X86Mem128_RC128Operand>;
385 def vx256mem : X86VMemOperand<VR128, "printi256mem", X86Mem256_RC128Operand>;
386 def vy128mem : X86VMemOperand<VR256, "printi128mem", X86Mem128_RC256Operand>;
387 def vy256mem : X86VMemOperand<VR256, "printi256mem", X86Mem256_RC256Operand>;
389 def vx64xmem : X86VMemOperand<VR128X, "printi64mem", X86Mem64_RC128XOperand>;
390 def vx128xmem : X86VMemOperand<VR128X, "printi128mem", X86Mem128_RC128XOperand>;
391 def vx256xmem : X86VMemOperand<VR128X, "printi256mem", X86Mem256_RC128XOperand>;
392 def vy128xmem : X86VMemOperand<VR256X, "printi128mem", X86Mem128_RC256XOperand>;
393 def vy256xmem : X86VMemOperand<VR256X, "printi256mem", X86Mem256_RC256XOperand>;
394 def vy512mem : X86VMemOperand<VR256X, "printi512mem", X86Mem512_RC256XOperand>;
395 def vz256xmem : X86VMemOperand<VR512, "printi256mem", X86Mem256_RC512Operand>;
396 def vz512mem : X86VMemOperand<VR512, "printi512mem", X86Mem512_RC512Operand>;
398 // A version of i8mem for use on x86-64 and x32 that uses a NOREX GPR instead
399 // of a plain GPR, so that it doesn't potentially require a REX prefix.
400 def ptr_rc_norex : PointerLikeRegClass<2>;
401 def ptr_rc_norex_nosp : PointerLikeRegClass<3>;
403 def i8mem_NOREX : Operand<iPTR> {
404 let PrintMethod = "printi8mem";
405 let MIOperandInfo = (ops ptr_rc_norex, i8imm, ptr_rc_norex_nosp, i32imm,
407 let ParserMatchClass = X86Mem8AsmOperand;
408 let OperandType = "OPERAND_MEMORY";
411 // GPRs available for tailcall.
412 // It represents GR32_TC, GR64_TC or GR64_TCW64.
413 def ptr_rc_tailcall : PointerLikeRegClass<4>;
415 // Special i32mem for addresses of load folding tail calls. These are not
416 // allowed to use callee-saved registers since they must be scheduled
417 // after callee-saved register are popped.
418 def i32mem_TC : Operand<i32> {
419 let PrintMethod = "printi32mem";
420 let MIOperandInfo = (ops ptr_rc_tailcall, i8imm, ptr_rc_tailcall,
421 i32imm, SEGMENT_REG);
422 let ParserMatchClass = X86Mem32AsmOperand;
423 let OperandType = "OPERAND_MEMORY";
426 // Special i64mem for addresses of load folding tail calls. These are not
427 // allowed to use callee-saved registers since they must be scheduled
428 // after callee-saved register are popped.
429 def i64mem_TC : Operand<i64> {
430 let PrintMethod = "printi64mem";
431 let MIOperandInfo = (ops ptr_rc_tailcall, i8imm,
432 ptr_rc_tailcall, i32imm, SEGMENT_REG);
433 let ParserMatchClass = X86Mem64AsmOperand;
434 let OperandType = "OPERAND_MEMORY";
437 let OperandType = "OPERAND_PCREL",
438 ParserMatchClass = X86AbsMemAsmOperand,
439 PrintMethod = "printPCRelImm" in {
440 def i32imm_pcrel : Operand<i32>;
441 def i16imm_pcrel : Operand<i16>;
443 // Branch targets have OtherVT type and print as pc-relative values.
444 def brtarget : Operand<OtherVT>;
445 def brtarget8 : Operand<OtherVT>;
449 // Special parser to detect 16-bit mode to select 16-bit displacement.
450 def X86AbsMem16AsmOperand : AsmOperandClass {
451 let Name = "AbsMem16";
452 let RenderMethod = "addAbsMemOperands";
453 let SuperClasses = [X86AbsMemAsmOperand];
456 // Branch targets have OtherVT type and print as pc-relative values.
457 let OperandType = "OPERAND_PCREL",
458 PrintMethod = "printPCRelImm" in {
459 let ParserMatchClass = X86AbsMem16AsmOperand in
460 def brtarget16 : Operand<OtherVT>;
461 let ParserMatchClass = X86AbsMemAsmOperand in
462 def brtarget32 : Operand<OtherVT>;
465 let RenderMethod = "addSrcIdxOperands" in {
466 def X86SrcIdx8Operand : AsmOperandClass {
467 let Name = "SrcIdx8";
468 let SuperClasses = [X86Mem8AsmOperand];
470 def X86SrcIdx16Operand : AsmOperandClass {
471 let Name = "SrcIdx16";
472 let SuperClasses = [X86Mem16AsmOperand];
474 def X86SrcIdx32Operand : AsmOperandClass {
475 let Name = "SrcIdx32";
476 let SuperClasses = [X86Mem32AsmOperand];
478 def X86SrcIdx64Operand : AsmOperandClass {
479 let Name = "SrcIdx64";
480 let SuperClasses = [X86Mem64AsmOperand];
482 } // RenderMethod = "addSrcIdxOperands"
484 let RenderMethod = "addDstIdxOperands" in {
485 def X86DstIdx8Operand : AsmOperandClass {
486 let Name = "DstIdx8";
487 let SuperClasses = [X86Mem8AsmOperand];
489 def X86DstIdx16Operand : AsmOperandClass {
490 let Name = "DstIdx16";
491 let SuperClasses = [X86Mem16AsmOperand];
493 def X86DstIdx32Operand : AsmOperandClass {
494 let Name = "DstIdx32";
495 let SuperClasses = [X86Mem32AsmOperand];
497 def X86DstIdx64Operand : AsmOperandClass {
498 let Name = "DstIdx64";
499 let SuperClasses = [X86Mem64AsmOperand];
501 } // RenderMethod = "addDstIdxOperands"
503 let RenderMethod = "addMemOffsOperands" in {
504 def X86MemOffs16_8AsmOperand : AsmOperandClass {
505 let Name = "MemOffs16_8";
506 let SuperClasses = [X86Mem8AsmOperand];
508 def X86MemOffs16_16AsmOperand : AsmOperandClass {
509 let Name = "MemOffs16_16";
510 let SuperClasses = [X86Mem16AsmOperand];
512 def X86MemOffs16_32AsmOperand : AsmOperandClass {
513 let Name = "MemOffs16_32";
514 let SuperClasses = [X86Mem32AsmOperand];
516 def X86MemOffs32_8AsmOperand : AsmOperandClass {
517 let Name = "MemOffs32_8";
518 let SuperClasses = [X86Mem8AsmOperand];
520 def X86MemOffs32_16AsmOperand : AsmOperandClass {
521 let Name = "MemOffs32_16";
522 let SuperClasses = [X86Mem16AsmOperand];
524 def X86MemOffs32_32AsmOperand : AsmOperandClass {
525 let Name = "MemOffs32_32";
526 let SuperClasses = [X86Mem32AsmOperand];
528 def X86MemOffs32_64AsmOperand : AsmOperandClass {
529 let Name = "MemOffs32_64";
530 let SuperClasses = [X86Mem64AsmOperand];
532 def X86MemOffs64_8AsmOperand : AsmOperandClass {
533 let Name = "MemOffs64_8";
534 let SuperClasses = [X86Mem8AsmOperand];
536 def X86MemOffs64_16AsmOperand : AsmOperandClass {
537 let Name = "MemOffs64_16";
538 let SuperClasses = [X86Mem16AsmOperand];
540 def X86MemOffs64_32AsmOperand : AsmOperandClass {
541 let Name = "MemOffs64_32";
542 let SuperClasses = [X86Mem32AsmOperand];
544 def X86MemOffs64_64AsmOperand : AsmOperandClass {
545 let Name = "MemOffs64_64";
546 let SuperClasses = [X86Mem64AsmOperand];
548 } // RenderMethod = "addMemOffsOperands"
550 class X86SrcIdxOperand<string printMethod, AsmOperandClass parserMatchClass>
551 : X86MemOperand<printMethod, parserMatchClass> {
552 let MIOperandInfo = (ops ptr_rc, SEGMENT_REG);
555 class X86DstIdxOperand<string printMethod, AsmOperandClass parserMatchClass>
556 : X86MemOperand<printMethod, parserMatchClass> {
557 let MIOperandInfo = (ops ptr_rc);
560 def srcidx8 : X86SrcIdxOperand<"printSrcIdx8", X86SrcIdx8Operand>;
561 def srcidx16 : X86SrcIdxOperand<"printSrcIdx16", X86SrcIdx16Operand>;
562 def srcidx32 : X86SrcIdxOperand<"printSrcIdx32", X86SrcIdx32Operand>;
563 def srcidx64 : X86SrcIdxOperand<"printSrcIdx64", X86SrcIdx64Operand>;
564 def dstidx8 : X86DstIdxOperand<"printDstIdx8", X86DstIdx8Operand>;
565 def dstidx16 : X86DstIdxOperand<"printDstIdx16", X86DstIdx16Operand>;
566 def dstidx32 : X86DstIdxOperand<"printDstIdx32", X86DstIdx32Operand>;
567 def dstidx64 : X86DstIdxOperand<"printDstIdx64", X86DstIdx64Operand>;
569 class X86MemOffsOperand<Operand immOperand, string printMethod,
570 AsmOperandClass parserMatchClass>
571 : X86MemOperand<printMethod, parserMatchClass> {
572 let MIOperandInfo = (ops immOperand, SEGMENT_REG);
575 def offset16_8 : X86MemOffsOperand<i16imm, "printMemOffs8",
576 X86MemOffs16_8AsmOperand>;
577 def offset16_16 : X86MemOffsOperand<i16imm, "printMemOffs16",
578 X86MemOffs16_16AsmOperand>;
579 def offset16_32 : X86MemOffsOperand<i16imm, "printMemOffs32",
580 X86MemOffs16_32AsmOperand>;
581 def offset32_8 : X86MemOffsOperand<i32imm, "printMemOffs8",
582 X86MemOffs32_8AsmOperand>;
583 def offset32_16 : X86MemOffsOperand<i32imm, "printMemOffs16",
584 X86MemOffs32_16AsmOperand>;
585 def offset32_32 : X86MemOffsOperand<i32imm, "printMemOffs32",
586 X86MemOffs32_32AsmOperand>;
587 def offset32_64 : X86MemOffsOperand<i32imm, "printMemOffs64",
588 X86MemOffs32_64AsmOperand>;
589 def offset64_8 : X86MemOffsOperand<i64imm, "printMemOffs8",
590 X86MemOffs64_8AsmOperand>;
591 def offset64_16 : X86MemOffsOperand<i64imm, "printMemOffs16",
592 X86MemOffs64_16AsmOperand>;
593 def offset64_32 : X86MemOffsOperand<i64imm, "printMemOffs32",
594 X86MemOffs64_32AsmOperand>;
595 def offset64_64 : X86MemOffsOperand<i64imm, "printMemOffs64",
596 X86MemOffs64_64AsmOperand>;
598 def SSECC : Operand<i8> {
599 let PrintMethod = "printSSEAVXCC";
600 let OperandType = "OPERAND_IMMEDIATE";
603 def AVXCC : Operand<i8> {
604 let PrintMethod = "printSSEAVXCC";
605 let OperandType = "OPERAND_IMMEDIATE";
608 def AVX512ICC : Operand<i8> {
609 let PrintMethod = "printSSEAVXCC";
610 let OperandType = "OPERAND_IMMEDIATE";
613 def XOPCC : Operand<i8> {
614 let PrintMethod = "printXOPCC";
615 let OperandType = "OPERAND_IMMEDIATE";
618 class ImmSExtAsmOperandClass : AsmOperandClass {
619 let SuperClasses = [ImmAsmOperand];
620 let RenderMethod = "addImmOperands";
623 def X86GR32orGR64AsmOperand : AsmOperandClass {
624 let Name = "GR32orGR64";
627 def GR32orGR64 : RegisterOperand<GR32> {
628 let ParserMatchClass = X86GR32orGR64AsmOperand;
630 def AVX512RCOperand : AsmOperandClass {
631 let Name = "AVX512RC";
633 def AVX512RC : Operand<i32> {
634 let PrintMethod = "printRoundingControl";
635 let OperandType = "OPERAND_IMMEDIATE";
636 let ParserMatchClass = AVX512RCOperand;
639 // Sign-extended immediate classes. We don't need to define the full lattice
640 // here because there is no instruction with an ambiguity between ImmSExti64i32
643 // The strange ranges come from the fact that the assembler always works with
644 // 64-bit immediates, but for a 16-bit target value we want to accept both "-1"
645 // (which will be a -1ULL), and "0xFF" (-1 in 16-bits).
648 // [0xFFFFFFFF80000000, 0xFFFFFFFFFFFFFFFF]
649 def ImmSExti64i32AsmOperand : ImmSExtAsmOperandClass {
650 let Name = "ImmSExti64i32";
653 // [0, 0x0000007F] | [0x000000000000FF80, 0x000000000000FFFF] |
654 // [0xFFFFFFFFFFFFFF80, 0xFFFFFFFFFFFFFFFF]
655 def ImmSExti16i8AsmOperand : ImmSExtAsmOperandClass {
656 let Name = "ImmSExti16i8";
657 let SuperClasses = [ImmSExti64i32AsmOperand];
660 // [0, 0x0000007F] | [0x00000000FFFFFF80, 0x00000000FFFFFFFF] |
661 // [0xFFFFFFFFFFFFFF80, 0xFFFFFFFFFFFFFFFF]
662 def ImmSExti32i8AsmOperand : ImmSExtAsmOperandClass {
663 let Name = "ImmSExti32i8";
667 // [0xFFFFFFFFFFFFFF80, 0xFFFFFFFFFFFFFFFF]
668 def ImmSExti64i8AsmOperand : ImmSExtAsmOperandClass {
669 let Name = "ImmSExti64i8";
670 let SuperClasses = [ImmSExti16i8AsmOperand, ImmSExti32i8AsmOperand,
671 ImmSExti64i32AsmOperand];
674 // Unsigned immediate used by SSE/AVX instructions
676 // [0xFFFFFFFFFFFFFF80, 0xFFFFFFFFFFFFFFFF]
677 def ImmUnsignedi8AsmOperand : AsmOperandClass {
678 let Name = "ImmUnsignedi8";
679 let RenderMethod = "addImmOperands";
682 // A couple of more descriptive operand definitions.
683 // 16-bits but only 8 bits are significant.
684 def i16i8imm : Operand<i16> {
685 let ParserMatchClass = ImmSExti16i8AsmOperand;
686 let OperandType = "OPERAND_IMMEDIATE";
688 // 32-bits but only 8 bits are significant.
689 def i32i8imm : Operand<i32> {
690 let ParserMatchClass = ImmSExti32i8AsmOperand;
691 let OperandType = "OPERAND_IMMEDIATE";
694 // 64-bits but only 32 bits are significant.
695 def i64i32imm : Operand<i64> {
696 let ParserMatchClass = ImmSExti64i32AsmOperand;
697 let OperandType = "OPERAND_IMMEDIATE";
700 // 64-bits but only 8 bits are significant.
701 def i64i8imm : Operand<i64> {
702 let ParserMatchClass = ImmSExti64i8AsmOperand;
703 let OperandType = "OPERAND_IMMEDIATE";
706 // Unsigned 8-bit immediate used by SSE/AVX instructions.
707 def u8imm : Operand<i8> {
708 let PrintMethod = "printU8Imm";
709 let ParserMatchClass = ImmUnsignedi8AsmOperand;
710 let OperandType = "OPERAND_IMMEDIATE";
713 // 32-bit immediate but only 8-bits are significant and they are unsigned.
714 // Used by some SSE/AVX instructions that use intrinsics.
715 def i32u8imm : Operand<i32> {
716 let PrintMethod = "printU8Imm";
717 let ParserMatchClass = ImmUnsignedi8AsmOperand;
718 let OperandType = "OPERAND_IMMEDIATE";
721 // 64-bits but only 32 bits are significant, and those bits are treated as being
723 def i64i32imm_pcrel : Operand<i64> {
724 let PrintMethod = "printPCRelImm";
725 let ParserMatchClass = X86AbsMemAsmOperand;
726 let OperandType = "OPERAND_PCREL";
729 def lea64_32mem : Operand<i32> {
730 let PrintMethod = "printanymem";
731 let MIOperandInfo = (ops GR64, i8imm, GR64_NOSP, i32imm, SEGMENT_REG);
732 let ParserMatchClass = X86MemAsmOperand;
735 // Memory operands that use 64-bit pointers in both ILP32 and LP64.
736 def lea64mem : Operand<i64> {
737 let PrintMethod = "printanymem";
738 let MIOperandInfo = (ops GR64, i8imm, GR64_NOSP, i32imm, SEGMENT_REG);
739 let ParserMatchClass = X86MemAsmOperand;
743 //===----------------------------------------------------------------------===//
744 // X86 Complex Pattern Definitions.
747 // Define X86-specific addressing mode.
748 def addr : ComplexPattern<iPTR, 5, "selectAddr", [], [SDNPWantParent]>;
749 def lea32addr : ComplexPattern<i32, 5, "selectLEAAddr",
750 [add, sub, mul, X86mul_imm, shl, or, frameindex],
752 // In 64-bit mode 32-bit LEAs can use RIP-relative addressing.
753 def lea64_32addr : ComplexPattern<i32, 5, "selectLEA64_32Addr",
754 [add, sub, mul, X86mul_imm, shl, or,
755 frameindex, X86WrapperRIP],
758 def tls32addr : ComplexPattern<i32, 5, "selectTLSADDRAddr",
759 [tglobaltlsaddr], []>;
761 def tls32baseaddr : ComplexPattern<i32, 5, "selectTLSADDRAddr",
762 [tglobaltlsaddr], []>;
764 def lea64addr : ComplexPattern<i64, 5, "selectLEAAddr",
765 [add, sub, mul, X86mul_imm, shl, or, frameindex,
768 def tls64addr : ComplexPattern<i64, 5, "selectTLSADDRAddr",
769 [tglobaltlsaddr], []>;
771 def tls64baseaddr : ComplexPattern<i64, 5, "selectTLSADDRAddr",
772 [tglobaltlsaddr], []>;
774 def vectoraddr : ComplexPattern<iPTR, 5, "selectVectorAddr", [],[SDNPWantParent]>;
776 // A relocatable immediate is either an immediate operand or an operand that can
777 // be relocated by the linker to an immediate, such as a regular symbol in
779 def relocImm : ComplexPattern<iAny, 1, "selectRelocImm", [imm, X86Wrapper], [],
782 //===----------------------------------------------------------------------===//
783 // X86 Instruction Predicate Definitions.
784 def TruePredicate : Predicate<"true">;
786 def HasCMov : Predicate<"Subtarget->hasCMov()">;
787 def NoCMov : Predicate<"!Subtarget->hasCMov()">;
789 def HasMMX : Predicate<"Subtarget->hasMMX()">;
790 def Has3DNow : Predicate<"Subtarget->has3DNow()">;
791 def Has3DNowA : Predicate<"Subtarget->has3DNowA()">;
792 def HasSSE1 : Predicate<"Subtarget->hasSSE1()">;
793 def UseSSE1 : Predicate<"Subtarget->hasSSE1() && !Subtarget->hasAVX()">;
794 def HasSSE2 : Predicate<"Subtarget->hasSSE2()">;
795 def UseSSE2 : Predicate<"Subtarget->hasSSE2() && !Subtarget->hasAVX()">;
796 def HasSSE3 : Predicate<"Subtarget->hasSSE3()">;
797 def UseSSE3 : Predicate<"Subtarget->hasSSE3() && !Subtarget->hasAVX()">;
798 def HasSSSE3 : Predicate<"Subtarget->hasSSSE3()">;
799 def UseSSSE3 : Predicate<"Subtarget->hasSSSE3() && !Subtarget->hasAVX()">;
800 def HasSSE41 : Predicate<"Subtarget->hasSSE41()">;
801 def NoSSE41 : Predicate<"!Subtarget->hasSSE41()">;
802 def UseSSE41 : Predicate<"Subtarget->hasSSE41() && !Subtarget->hasAVX()">;
803 def HasSSE42 : Predicate<"Subtarget->hasSSE42()">;
804 def UseSSE42 : Predicate<"Subtarget->hasSSE42() && !Subtarget->hasAVX()">;
805 def HasSSE4A : Predicate<"Subtarget->hasSSE4A()">;
806 def NoAVX : Predicate<"!Subtarget->hasAVX()">;
807 def HasAVX : Predicate<"Subtarget->hasAVX()">;
808 def HasAVX2 : Predicate<"Subtarget->hasAVX2()">;
809 def HasAVX1Only : Predicate<"Subtarget->hasAVX() && !Subtarget->hasAVX2()">;
810 def HasAVX512 : Predicate<"Subtarget->hasAVX512()">,
811 AssemblerPredicate<"FeatureAVX512", "AVX-512 ISA">;
812 def UseAVX : Predicate<"Subtarget->hasAVX() && !Subtarget->hasAVX512()">;
813 def UseAVX2 : Predicate<"Subtarget->hasAVX2() && !Subtarget->hasAVX512()">;
814 def NoAVX512 : Predicate<"!Subtarget->hasAVX512()">;
815 def HasCDI : Predicate<"Subtarget->hasCDI()">,
816 AssemblerPredicate<"FeatureCDI", "AVX-512 CD ISA">;
817 def HasVPOPCNTDQ : Predicate<"Subtarget->hasVPOPCNTDQ()">,
818 AssemblerPredicate<"FeatureVPOPCNTDQ", "AVX-512 VPOPCNTDQ ISA">;
819 def HasPFI : Predicate<"Subtarget->hasPFI()">,
820 AssemblerPredicate<"FeaturePFI", "AVX-512 PF ISA">;
821 def HasERI : Predicate<"Subtarget->hasERI()">,
822 AssemblerPredicate<"FeatureERI", "AVX-512 ER ISA">;
823 def HasDQI : Predicate<"Subtarget->hasDQI()">,
824 AssemblerPredicate<"FeatureDQI", "AVX-512 DQ ISA">;
825 def NoDQI : Predicate<"!Subtarget->hasDQI()">;
826 def HasBWI : Predicate<"Subtarget->hasBWI()">,
827 AssemblerPredicate<"FeatureBWI", "AVX-512 BW ISA">;
828 def NoBWI : Predicate<"!Subtarget->hasBWI()">;
829 def HasVLX : Predicate<"Subtarget->hasVLX()">,
830 AssemblerPredicate<"FeatureVLX", "AVX-512 VL ISA">;
831 def NoVLX : Predicate<"!Subtarget->hasVLX()">;
832 def NoVLX_Or_NoBWI : Predicate<"!Subtarget->hasVLX() || !Subtarget->hasBWI()">;
833 def NoVLX_Or_NoDQI : Predicate<"!Subtarget->hasVLX() || !Subtarget->hasDQI()">;
834 def PKU : Predicate<"Subtarget->hasPKU()">;
835 def HasVNNI : Predicate<"Subtarget->hasVNNI()">;
837 def HasBITALG : Predicate<"Subtarget->hasBITALG()">;
838 def HasPOPCNT : Predicate<"Subtarget->hasPOPCNT()">;
839 def HasAES : Predicate<"Subtarget->hasAES()">;
840 def HasVAES : Predicate<"Subtarget->hasVAES()">;
841 def NoVLX_Or_NoVAES : Predicate<"!Subtarget->hasVLX() || !Subtarget->hasVAES()">;
842 def HasFXSR : Predicate<"Subtarget->hasFXSR()">;
843 def HasXSAVE : Predicate<"Subtarget->hasXSAVE()">;
844 def HasXSAVEOPT : Predicate<"Subtarget->hasXSAVEOPT()">;
845 def HasXSAVEC : Predicate<"Subtarget->hasXSAVEC()">;
846 def HasXSAVES : Predicate<"Subtarget->hasXSAVES()">;
847 def HasPCLMUL : Predicate<"Subtarget->hasPCLMUL()">;
848 def NoVLX_Or_NoVPCLMULQDQ :
849 Predicate<"!Subtarget->hasVLX() || !Subtarget->hasVPCLMULQDQ()">;
850 def HasVPCLMULQDQ : Predicate<"Subtarget->hasVPCLMULQDQ()">;
851 def HasGFNI : Predicate<"Subtarget->hasGFNI()">;
852 def HasFMA : Predicate<"Subtarget->hasFMA()">;
853 def HasFMA4 : Predicate<"Subtarget->hasFMA4()">;
854 def NoFMA4 : Predicate<"!Subtarget->hasFMA4()">;
855 def HasXOP : Predicate<"Subtarget->hasXOP()">;
856 def HasTBM : Predicate<"Subtarget->hasTBM()">;
857 def NoTBM : Predicate<"!Subtarget->hasTBM()">;
858 def HasLWP : Predicate<"Subtarget->hasLWP()">;
859 def HasMOVBE : Predicate<"Subtarget->hasMOVBE()">;
860 def HasRDRAND : Predicate<"Subtarget->hasRDRAND()">;
861 def HasF16C : Predicate<"Subtarget->hasF16C()">;
862 def HasFSGSBase : Predicate<"Subtarget->hasFSGSBase()">;
863 def HasLZCNT : Predicate<"Subtarget->hasLZCNT()">;
864 def HasBMI : Predicate<"Subtarget->hasBMI()">;
865 def HasBMI2 : Predicate<"Subtarget->hasBMI2()">;
866 def NoBMI2 : Predicate<"!Subtarget->hasBMI2()">;
867 def HasVBMI : Predicate<"Subtarget->hasVBMI()">,
868 AssemblerPredicate<"FeatureVBMI", "AVX-512 VBMI ISA">;
869 def HasVBMI2 : Predicate<"Subtarget->hasVBMI2()">;
870 def HasIFMA : Predicate<"Subtarget->hasIFMA()">,
871 AssemblerPredicate<"FeatureIFMA", "AVX-512 IFMA ISA">;
872 def HasRTM : Predicate<"Subtarget->hasRTM()">;
873 def HasADX : Predicate<"Subtarget->hasADX()">;
874 def HasSHA : Predicate<"Subtarget->hasSHA()">;
875 def HasPRFCHW : Predicate<"Subtarget->hasPRFCHW()">;
876 def HasRDSEED : Predicate<"Subtarget->hasRDSEED()">;
877 def HasSSEPrefetch : Predicate<"Subtarget->hasSSEPrefetch()">;
878 def NoSSEPrefetch : Predicate<"!Subtarget->hasSSEPrefetch()">;
879 def HasPrefetchW : Predicate<"Subtarget->hasPRFCHW()">;
880 def HasPREFETCHWT1 : Predicate<"Subtarget->hasPREFETCHWT1()">;
881 def HasLAHFSAHF : Predicate<"Subtarget->hasLAHFSAHF()">;
882 def HasMWAITX : Predicate<"Subtarget->hasMWAITX()">;
883 def HasCLZERO : Predicate<"Subtarget->hasCLZERO()">;
884 def FPStackf32 : Predicate<"!Subtarget->hasSSE1()">;
885 def FPStackf64 : Predicate<"!Subtarget->hasSSE2()">;
886 def HasMPX : Predicate<"Subtarget->hasMPX()">;
887 def HasSHSTK : Predicate<"Subtarget->hasSHSTK()">;
888 def HasIBT : Predicate<"Subtarget->hasIBT()">;
889 def HasCLFLUSHOPT : Predicate<"Subtarget->hasCLFLUSHOPT()">;
890 def HasCLWB : Predicate<"Subtarget->hasCLWB()">;
891 def HasCmpxchg16b: Predicate<"Subtarget->hasCmpxchg16b()">;
892 def Not64BitMode : Predicate<"!Subtarget->is64Bit()">,
893 AssemblerPredicate<"!Mode64Bit", "Not 64-bit mode">;
894 def In64BitMode : Predicate<"Subtarget->is64Bit()">,
895 AssemblerPredicate<"Mode64Bit", "64-bit mode">;
896 def IsLP64 : Predicate<"Subtarget->isTarget64BitLP64()">;
897 def NotLP64 : Predicate<"!Subtarget->isTarget64BitLP64()">;
898 def In16BitMode : Predicate<"Subtarget->is16Bit()">,
899 AssemblerPredicate<"Mode16Bit", "16-bit mode">;
900 def Not16BitMode : Predicate<"!Subtarget->is16Bit()">,
901 AssemblerPredicate<"!Mode16Bit", "Not 16-bit mode">;
902 def In32BitMode : Predicate<"Subtarget->is32Bit()">,
903 AssemblerPredicate<"Mode32Bit", "32-bit mode">;
904 def IsWin64 : Predicate<"Subtarget->isTargetWin64()">;
905 def NotWin64 : Predicate<"!Subtarget->isTargetWin64()">;
906 def NotWin64WithoutFP : Predicate<"!Subtarget->isTargetWin64() ||"
907 "Subtarget->getFrameLowering()->hasFP(*MF)"> {
908 let RecomputePerFunction = 1;
910 def IsPS4 : Predicate<"Subtarget->isTargetPS4()">;
911 def NotPS4 : Predicate<"!Subtarget->isTargetPS4()">;
912 def IsNaCl : Predicate<"Subtarget->isTargetNaCl()">;
913 def NotNaCl : Predicate<"!Subtarget->isTargetNaCl()">;
914 def SmallCode : Predicate<"TM.getCodeModel() == CodeModel::Small">;
915 def KernelCode : Predicate<"TM.getCodeModel() == CodeModel::Kernel">;
916 def NearData : Predicate<"TM.getCodeModel() == CodeModel::Small ||"
917 "TM.getCodeModel() == CodeModel::Kernel">;
918 def IsNotPIC : Predicate<"!TM.isPositionIndependent()">;
920 // We could compute these on a per-module basis but doing so requires accessing
921 // the Function object through the <Target>Subtarget and objections were raised
922 // to that (see post-commit review comments for r301750).
923 let RecomputePerFunction = 1 in {
924 def OptForSize : Predicate<"MF->getFunction().optForSize()">;
925 def OptForMinSize : Predicate<"MF->getFunction().optForMinSize()">;
926 def OptForSpeed : Predicate<"!MF->getFunction().optForSize()">;
927 def UseIncDec : Predicate<"!Subtarget->slowIncDec() || "
928 "MF->getFunction().optForSize()">;
931 def CallImmAddr : Predicate<"Subtarget->isLegalToCallImmediateAddr()">;
932 def FavorMemIndirectCall : Predicate<"!Subtarget->slowTwoMemOps()">;
933 def HasFastMem32 : Predicate<"!Subtarget->isUnalignedMem32Slow()">;
934 def HasFastLZCNT : Predicate<"Subtarget->hasFastLZCNT()">;
935 def HasFastSHLDRotate : Predicate<"Subtarget->hasFastSHLDRotate()">;
936 def HasERMSB : Predicate<"Subtarget->hasERMSB()">;
937 def HasMFence : Predicate<"Subtarget->hasMFence()">;
939 //===----------------------------------------------------------------------===//
940 // X86 Instruction Format Definitions.
943 include "X86InstrFormats.td"
945 //===----------------------------------------------------------------------===//
946 // Pattern fragments.
949 // X86 specific condition code. These correspond to CondCode in
950 // X86InstrInfo.h. They must be kept in synch.
951 def X86_COND_A : PatLeaf<(i8 0)>; // alt. COND_NBE
952 def X86_COND_AE : PatLeaf<(i8 1)>; // alt. COND_NC
953 def X86_COND_B : PatLeaf<(i8 2)>; // alt. COND_C
954 def X86_COND_BE : PatLeaf<(i8 3)>; // alt. COND_NA
955 def X86_COND_E : PatLeaf<(i8 4)>; // alt. COND_Z
956 def X86_COND_G : PatLeaf<(i8 5)>; // alt. COND_NLE
957 def X86_COND_GE : PatLeaf<(i8 6)>; // alt. COND_NL
958 def X86_COND_L : PatLeaf<(i8 7)>; // alt. COND_NGE
959 def X86_COND_LE : PatLeaf<(i8 8)>; // alt. COND_NG
960 def X86_COND_NE : PatLeaf<(i8 9)>; // alt. COND_NZ
961 def X86_COND_NO : PatLeaf<(i8 10)>;
962 def X86_COND_NP : PatLeaf<(i8 11)>; // alt. COND_PO
963 def X86_COND_NS : PatLeaf<(i8 12)>;
964 def X86_COND_O : PatLeaf<(i8 13)>;
965 def X86_COND_P : PatLeaf<(i8 14)>; // alt. COND_PE
966 def X86_COND_S : PatLeaf<(i8 15)>;
968 def i16immSExt8 : ImmLeaf<i16, [{ return isInt<8>(Imm); }]>;
969 def i32immSExt8 : ImmLeaf<i32, [{ return isInt<8>(Imm); }]>;
970 def i64immSExt8 : ImmLeaf<i64, [{ return isInt<8>(Imm); }]>;
971 def i64immSExt32 : ImmLeaf<i64, [{ return isInt<32>(Imm); }]>;
973 // FIXME: Ideally we would just replace the above i*immSExt* matchers with
974 // relocImm-based matchers, but then FastISel would be unable to use them.
975 def i64relocImmSExt8 : PatLeaf<(i64 relocImm), [{
976 return isSExtRelocImm<8>(N);
978 def i64relocImmSExt32 : PatLeaf<(i64 relocImm), [{
979 return isSExtRelocImm<32>(N);
982 // If we have multiple users of an immediate, it's much smaller to reuse
983 // the register, rather than encode the immediate in every instruction.
984 // This has the risk of increasing register pressure from stretched live
985 // ranges, however, the immediates should be trivial to rematerialize by
986 // the RA in the event of high register pressure.
987 // TODO : This is currently enabled for stores and binary ops. There are more
988 // cases for which this can be enabled, though this catches the bulk of the
990 // TODO2 : This should really also be enabled under O2, but there's currently
991 // an issue with RA where we don't pull the constants into their users
992 // when we rematerialize them. I'll follow-up on enabling O2 after we fix that
994 // TODO3 : This is currently limited to single basic blocks (DAG creation
995 // pulls block immediates to the top and merges them if necessary).
996 // Eventually, it would be nice to allow ConstantHoisting to merge constants
997 // globally for potentially added savings.
999 def imm8_su : PatLeaf<(i8 relocImm), [{
1000 return !shouldAvoidImmediateInstFormsForSize(N);
1002 def imm16_su : PatLeaf<(i16 relocImm), [{
1003 return !shouldAvoidImmediateInstFormsForSize(N);
1005 def imm32_su : PatLeaf<(i32 relocImm), [{
1006 return !shouldAvoidImmediateInstFormsForSize(N);
1008 def i64immSExt32_su : PatLeaf<(i64immSExt32), [{
1009 return !shouldAvoidImmediateInstFormsForSize(N);
1012 def i16immSExt8_su : PatLeaf<(i16immSExt8), [{
1013 return !shouldAvoidImmediateInstFormsForSize(N);
1015 def i32immSExt8_su : PatLeaf<(i32immSExt8), [{
1016 return !shouldAvoidImmediateInstFormsForSize(N);
1018 def i64immSExt8_su : PatLeaf<(i64immSExt8), [{
1019 return !shouldAvoidImmediateInstFormsForSize(N);
1022 def i64relocImmSExt8_su : PatLeaf<(i64relocImmSExt8), [{
1023 return !shouldAvoidImmediateInstFormsForSize(N);
1025 def i64relocImmSExt32_su : PatLeaf<(i64relocImmSExt32), [{
1026 return !shouldAvoidImmediateInstFormsForSize(N);
1029 // i64immZExt32 predicate - True if the 64-bit immediate fits in a 32-bit
1031 def i64immZExt32 : ImmLeaf<i64, [{ return isUInt<32>(Imm); }]>;
1033 def i64immZExt32SExt8 : ImmLeaf<i64, [{
1034 return isUInt<32>(Imm) && isInt<8>(static_cast<int32_t>(Imm));
1037 // Helper fragments for loads.
1038 // It's always safe to treat a anyext i16 load as a i32 load if the i16 is
1039 // known to be 32-bit aligned or better. Ditto for i8 to i16.
1040 def loadi16 : PatFrag<(ops node:$ptr), (i16 (unindexedload node:$ptr)), [{
1041 LoadSDNode *LD = cast<LoadSDNode>(N);
1042 ISD::LoadExtType ExtType = LD->getExtensionType();
1043 if (ExtType == ISD::NON_EXTLOAD)
1045 if (ExtType == ISD::EXTLOAD)
1046 return LD->getAlignment() >= 2 && !LD->isVolatile();
1050 def loadi16_anyext : PatFrag<(ops node:$ptr), (i32 (unindexedload node:$ptr)),[{
1051 LoadSDNode *LD = cast<LoadSDNode>(N);
1052 ISD::LoadExtType ExtType = LD->getExtensionType();
1053 if (ExtType == ISD::EXTLOAD)
1054 return LD->getAlignment() >= 2 && !LD->isVolatile();
1058 def loadi32 : PatFrag<(ops node:$ptr), (i32 (unindexedload node:$ptr)), [{
1059 LoadSDNode *LD = cast<LoadSDNode>(N);
1060 ISD::LoadExtType ExtType = LD->getExtensionType();
1061 if (ExtType == ISD::NON_EXTLOAD)
1063 if (ExtType == ISD::EXTLOAD)
1064 return LD->getAlignment() >= 4 && !LD->isVolatile();
1068 def loadi8 : PatFrag<(ops node:$ptr), (i8 (load node:$ptr))>;
1069 def loadi64 : PatFrag<(ops node:$ptr), (i64 (load node:$ptr))>;
1070 def loadf32 : PatFrag<(ops node:$ptr), (f32 (load node:$ptr))>;
1071 def loadf64 : PatFrag<(ops node:$ptr), (f64 (load node:$ptr))>;
1072 def loadf80 : PatFrag<(ops node:$ptr), (f80 (load node:$ptr))>;
1073 def loadf128 : PatFrag<(ops node:$ptr), (f128 (load node:$ptr))>;
1075 def sextloadi16i8 : PatFrag<(ops node:$ptr), (i16 (sextloadi8 node:$ptr))>;
1076 def sextloadi32i8 : PatFrag<(ops node:$ptr), (i32 (sextloadi8 node:$ptr))>;
1077 def sextloadi32i16 : PatFrag<(ops node:$ptr), (i32 (sextloadi16 node:$ptr))>;
1078 def sextloadi64i8 : PatFrag<(ops node:$ptr), (i64 (sextloadi8 node:$ptr))>;
1079 def sextloadi64i16 : PatFrag<(ops node:$ptr), (i64 (sextloadi16 node:$ptr))>;
1080 def sextloadi64i32 : PatFrag<(ops node:$ptr), (i64 (sextloadi32 node:$ptr))>;
1082 def zextloadi8i1 : PatFrag<(ops node:$ptr), (i8 (zextloadi1 node:$ptr))>;
1083 def zextloadi16i1 : PatFrag<(ops node:$ptr), (i16 (zextloadi1 node:$ptr))>;
1084 def zextloadi32i1 : PatFrag<(ops node:$ptr), (i32 (zextloadi1 node:$ptr))>;
1085 def zextloadi16i8 : PatFrag<(ops node:$ptr), (i16 (zextloadi8 node:$ptr))>;
1086 def zextloadi32i8 : PatFrag<(ops node:$ptr), (i32 (zextloadi8 node:$ptr))>;
1087 def zextloadi32i16 : PatFrag<(ops node:$ptr), (i32 (zextloadi16 node:$ptr))>;
1088 def zextloadi64i1 : PatFrag<(ops node:$ptr), (i64 (zextloadi1 node:$ptr))>;
1089 def zextloadi64i8 : PatFrag<(ops node:$ptr), (i64 (zextloadi8 node:$ptr))>;
1090 def zextloadi64i16 : PatFrag<(ops node:$ptr), (i64 (zextloadi16 node:$ptr))>;
1091 def zextloadi64i32 : PatFrag<(ops node:$ptr), (i64 (zextloadi32 node:$ptr))>;
1093 def extloadi8i1 : PatFrag<(ops node:$ptr), (i8 (extloadi1 node:$ptr))>;
1094 def extloadi16i1 : PatFrag<(ops node:$ptr), (i16 (extloadi1 node:$ptr))>;
1095 def extloadi32i1 : PatFrag<(ops node:$ptr), (i32 (extloadi1 node:$ptr))>;
1096 def extloadi16i8 : PatFrag<(ops node:$ptr), (i16 (extloadi8 node:$ptr))>;
1097 def extloadi32i8 : PatFrag<(ops node:$ptr), (i32 (extloadi8 node:$ptr))>;
1098 def extloadi32i16 : PatFrag<(ops node:$ptr), (i32 (extloadi16 node:$ptr))>;
1099 def extloadi64i1 : PatFrag<(ops node:$ptr), (i64 (extloadi1 node:$ptr))>;
1100 def extloadi64i8 : PatFrag<(ops node:$ptr), (i64 (extloadi8 node:$ptr))>;
1101 def extloadi64i16 : PatFrag<(ops node:$ptr), (i64 (extloadi16 node:$ptr))>;
1102 def extloadi64i32 : PatFrag<(ops node:$ptr), (i64 (extloadi32 node:$ptr))>;
1105 // An 'and' node with a single use.
1106 def and_su : PatFrag<(ops node:$lhs, node:$rhs), (and node:$lhs, node:$rhs), [{
1107 return N->hasOneUse();
1109 // An 'srl' node with a single use.
1110 def srl_su : PatFrag<(ops node:$lhs, node:$rhs), (srl node:$lhs, node:$rhs), [{
1111 return N->hasOneUse();
1113 // An 'trunc' node with a single use.
1114 def trunc_su : PatFrag<(ops node:$src), (trunc node:$src), [{
1115 return N->hasOneUse();
1118 //===----------------------------------------------------------------------===//
1119 // Instruction list.
1123 let hasSideEffects = 0, SchedRW = [WriteZero] in {
1124 def NOOP : I<0x90, RawFrm, (outs), (ins), "nop", [], IIC_NOP>;
1125 def NOOPW : I<0x1f, MRMXm, (outs), (ins i16mem:$zero),
1126 "nop{w}\t$zero", [], IIC_NOP>, TB, OpSize16;
1127 def NOOPL : I<0x1f, MRMXm, (outs), (ins i32mem:$zero),
1128 "nop{l}\t$zero", [], IIC_NOP>, TB, OpSize32;
1129 def NOOPQ : RI<0x1f, MRMXm, (outs), (ins i64mem:$zero),
1130 "nop{q}\t$zero", [], IIC_NOP>, TB,
1131 Requires<[In64BitMode]>;
1132 // Also allow register so we can assemble/disassemble
1133 def NOOPWr : I<0x1f, MRMXr, (outs), (ins GR16:$zero),
1134 "nop{w}\t$zero", [], IIC_NOP>, TB, OpSize16;
1135 def NOOPLr : I<0x1f, MRMXr, (outs), (ins GR32:$zero),
1136 "nop{l}\t$zero", [], IIC_NOP>, TB, OpSize32;
1137 def NOOPQr : RI<0x1f, MRMXr, (outs), (ins GR64:$zero),
1138 "nop{q}\t$zero", [], IIC_NOP>, TB,
1139 Requires<[In64BitMode]>;
1143 // Constructing a stack frame.
1144 def ENTER : Ii16<0xC8, RawFrmImm8, (outs), (ins i16imm:$len, i8imm:$lvl),
1145 "enter\t$len, $lvl", [], IIC_ENTER>, Sched<[WriteMicrocoded]>;
1147 let SchedRW = [WriteALU] in {
1148 let Defs = [EBP, ESP], Uses = [EBP, ESP], mayLoad = 1, hasSideEffects=0 in
1149 def LEAVE : I<0xC9, RawFrm,
1150 (outs), (ins), "leave", [], IIC_LEAVE>,
1151 Requires<[Not64BitMode]>;
1153 let Defs = [RBP,RSP], Uses = [RBP,RSP], mayLoad = 1, hasSideEffects = 0 in
1154 def LEAVE64 : I<0xC9, RawFrm,
1155 (outs), (ins), "leave", [], IIC_LEAVE>,
1156 Requires<[In64BitMode]>;
1159 //===----------------------------------------------------------------------===//
1160 // Miscellaneous Instructions.
1163 let isBarrier = 1, hasSideEffects = 1, usesCustomInserter = 1,
1164 SchedRW = [WriteSystem] in
1165 def Int_eh_sjlj_setup_dispatch
1166 : PseudoI<(outs), (ins), [(X86eh_sjlj_setup_dispatch)]>;
1168 let Defs = [ESP], Uses = [ESP], hasSideEffects=0 in {
1169 let mayLoad = 1, SchedRW = [WriteLoad] in {
1170 def POP16r : I<0x58, AddRegFrm, (outs GR16:$reg), (ins), "pop{w}\t$reg", [],
1171 IIC_POP_REG16>, OpSize16;
1172 def POP32r : I<0x58, AddRegFrm, (outs GR32:$reg), (ins), "pop{l}\t$reg", [],
1173 IIC_POP_REG>, OpSize32, Requires<[Not64BitMode]>;
1174 def POP16rmr: I<0x8F, MRM0r, (outs GR16:$reg), (ins), "pop{w}\t$reg", [],
1175 IIC_POP_REG>, OpSize16;
1176 def POP32rmr: I<0x8F, MRM0r, (outs GR32:$reg), (ins), "pop{l}\t$reg", [],
1177 IIC_POP_REG>, OpSize32, Requires<[Not64BitMode]>;
1178 } // mayLoad, SchedRW
1179 let mayStore = 1, mayLoad = 1, SchedRW = [WriteRMW] in {
1180 def POP16rmm: I<0x8F, MRM0m, (outs), (ins i16mem:$dst), "pop{w}\t$dst", [],
1181 IIC_POP_MEM>, OpSize16;
1182 def POP32rmm: I<0x8F, MRM0m, (outs), (ins i32mem:$dst), "pop{l}\t$dst", [],
1183 IIC_POP_MEM>, OpSize32, Requires<[Not64BitMode]>;
1184 } // mayStore, mayLoad, WriteRMW
1186 let mayStore = 1, SchedRW = [WriteStore] in {
1187 def PUSH16r : I<0x50, AddRegFrm, (outs), (ins GR16:$reg), "push{w}\t$reg",[],
1188 IIC_PUSH_REG>, OpSize16;
1189 def PUSH32r : I<0x50, AddRegFrm, (outs), (ins GR32:$reg), "push{l}\t$reg",[],
1190 IIC_PUSH_REG>, OpSize32, Requires<[Not64BitMode]>;
1191 def PUSH16rmr: I<0xFF, MRM6r, (outs), (ins GR16:$reg), "push{w}\t$reg",[],
1192 IIC_PUSH_REG>, OpSize16;
1193 def PUSH32rmr: I<0xFF, MRM6r, (outs), (ins GR32:$reg), "push{l}\t$reg",[],
1194 IIC_PUSH_REG>, OpSize32, Requires<[Not64BitMode]>;
1196 def PUSH16i8 : Ii8<0x6a, RawFrm, (outs), (ins i16i8imm:$imm),
1197 "push{w}\t$imm", [], IIC_PUSH_IMM>, OpSize16;
1198 def PUSHi16 : Ii16<0x68, RawFrm, (outs), (ins i16imm:$imm),
1199 "push{w}\t$imm", [], IIC_PUSH_IMM>, OpSize16;
1201 def PUSH32i8 : Ii8<0x6a, RawFrm, (outs), (ins i32i8imm:$imm),
1202 "push{l}\t$imm", [], IIC_PUSH_IMM>, OpSize32,
1203 Requires<[Not64BitMode]>;
1204 def PUSHi32 : Ii32<0x68, RawFrm, (outs), (ins i32imm:$imm),
1205 "push{l}\t$imm", [], IIC_PUSH_IMM>, OpSize32,
1206 Requires<[Not64BitMode]>;
1207 } // mayStore, SchedRW
1209 let mayLoad = 1, mayStore = 1, SchedRW = [WriteRMW] in {
1210 def PUSH16rmm: I<0xFF, MRM6m, (outs), (ins i16mem:$src), "push{w}\t$src",[],
1211 IIC_PUSH_MEM>, OpSize16;
1212 def PUSH32rmm: I<0xFF, MRM6m, (outs), (ins i32mem:$src), "push{l}\t$src",[],
1213 IIC_PUSH_MEM>, OpSize32, Requires<[Not64BitMode]>;
1214 } // mayLoad, mayStore, SchedRW
1218 let mayLoad = 1, mayStore = 1, usesCustomInserter = 1,
1219 SchedRW = [WriteRMW], Defs = [ESP] in {
1221 def RDFLAGS32 : PseudoI<(outs GR32:$dst), (ins),
1222 [(set GR32:$dst, (int_x86_flags_read_u32))]>,
1223 Requires<[Not64BitMode]>;
1226 def RDFLAGS64 : PseudoI<(outs GR64:$dst), (ins),
1227 [(set GR64:$dst, (int_x86_flags_read_u64))]>,
1228 Requires<[In64BitMode]>;
1231 let mayLoad = 1, mayStore = 1, usesCustomInserter = 1,
1232 SchedRW = [WriteRMW] in {
1233 let Defs = [ESP, EFLAGS], Uses = [ESP] in
1234 def WRFLAGS32 : PseudoI<(outs), (ins GR32:$src),
1235 [(int_x86_flags_write_u32 GR32:$src)]>,
1236 Requires<[Not64BitMode]>;
1238 let Defs = [RSP, EFLAGS], Uses = [RSP] in
1239 def WRFLAGS64 : PseudoI<(outs), (ins GR64:$src),
1240 [(int_x86_flags_write_u64 GR64:$src)]>,
1241 Requires<[In64BitMode]>;
1244 let Defs = [ESP, EFLAGS], Uses = [ESP], mayLoad = 1, hasSideEffects=0,
1245 SchedRW = [WriteLoad] in {
1246 def POPF16 : I<0x9D, RawFrm, (outs), (ins), "popf{w}", [], IIC_POP_F>,
1248 def POPF32 : I<0x9D, RawFrm, (outs), (ins), "popf{l|d}", [], IIC_POP_FD>,
1249 OpSize32, Requires<[Not64BitMode]>;
1252 let Defs = [ESP], Uses = [ESP, EFLAGS], mayStore = 1, hasSideEffects=0,
1253 SchedRW = [WriteStore] in {
1254 def PUSHF16 : I<0x9C, RawFrm, (outs), (ins), "pushf{w}", [], IIC_PUSH_F>,
1256 def PUSHF32 : I<0x9C, RawFrm, (outs), (ins), "pushf{l|d}", [], IIC_PUSH_F>,
1257 OpSize32, Requires<[Not64BitMode]>;
1260 let Defs = [RSP], Uses = [RSP], hasSideEffects=0 in {
1261 let mayLoad = 1, SchedRW = [WriteLoad] in {
1262 def POP64r : I<0x58, AddRegFrm, (outs GR64:$reg), (ins), "pop{q}\t$reg", [],
1263 IIC_POP_REG>, OpSize32, Requires<[In64BitMode]>;
1264 def POP64rmr: I<0x8F, MRM0r, (outs GR64:$reg), (ins), "pop{q}\t$reg", [],
1265 IIC_POP_REG>, OpSize32, Requires<[In64BitMode]>;
1266 } // mayLoad, SchedRW
1267 let mayLoad = 1, mayStore = 1, SchedRW = [WriteRMW] in
1268 def POP64rmm: I<0x8F, MRM0m, (outs), (ins i64mem:$dst), "pop{q}\t$dst", [],
1269 IIC_POP_MEM>, OpSize32, Requires<[In64BitMode]>;
1270 let mayStore = 1, SchedRW = [WriteStore] in {
1271 def PUSH64r : I<0x50, AddRegFrm, (outs), (ins GR64:$reg), "push{q}\t$reg", [],
1272 IIC_PUSH_REG>, OpSize32, Requires<[In64BitMode]>;
1273 def PUSH64rmr: I<0xFF, MRM6r, (outs), (ins GR64:$reg), "push{q}\t$reg", [],
1274 IIC_PUSH_REG>, OpSize32, Requires<[In64BitMode]>;
1275 } // mayStore, SchedRW
1276 let mayLoad = 1, mayStore = 1, SchedRW = [WriteRMW] in {
1277 def PUSH64rmm: I<0xFF, MRM6m, (outs), (ins i64mem:$src), "push{q}\t$src", [],
1278 IIC_PUSH_MEM>, OpSize32, Requires<[In64BitMode]>;
1279 } // mayLoad, mayStore, SchedRW
1282 let Defs = [RSP], Uses = [RSP], hasSideEffects = 0, mayStore = 1,
1283 SchedRW = [WriteStore] in {
1284 def PUSH64i8 : Ii8<0x6a, RawFrm, (outs), (ins i64i8imm:$imm),
1285 "push{q}\t$imm", [], IIC_PUSH_IMM>, OpSize32,
1286 Requires<[In64BitMode]>;
1287 def PUSH64i32 : Ii32S<0x68, RawFrm, (outs), (ins i64i32imm:$imm),
1288 "push{q}\t$imm", [], IIC_PUSH_IMM>, OpSize32,
1289 Requires<[In64BitMode]>;
1292 let Defs = [RSP, EFLAGS], Uses = [RSP], mayLoad = 1, hasSideEffects=0 in
1293 def POPF64 : I<0x9D, RawFrm, (outs), (ins), "popfq", [], IIC_POP_FD>,
1294 OpSize32, Requires<[In64BitMode]>, Sched<[WriteLoad]>;
1295 let Defs = [RSP], Uses = [RSP, EFLAGS], mayStore = 1, hasSideEffects=0 in
1296 def PUSHF64 : I<0x9C, RawFrm, (outs), (ins), "pushfq", [], IIC_PUSH_F>,
1297 OpSize32, Requires<[In64BitMode]>, Sched<[WriteStore]>;
1299 let Defs = [EDI, ESI, EBP, EBX, EDX, ECX, EAX, ESP], Uses = [ESP],
1300 mayLoad = 1, hasSideEffects = 0, SchedRW = [WriteLoad] in {
1301 def POPA32 : I<0x61, RawFrm, (outs), (ins), "popal", [], IIC_POP_A>,
1302 OpSize32, Requires<[Not64BitMode]>;
1303 def POPA16 : I<0x61, RawFrm, (outs), (ins), "popaw", [], IIC_POP_A>,
1304 OpSize16, Requires<[Not64BitMode]>;
1306 let Defs = [ESP], Uses = [EDI, ESI, EBP, EBX, EDX, ECX, EAX, ESP],
1307 mayStore = 1, hasSideEffects = 0, SchedRW = [WriteStore] in {
1308 def PUSHA32 : I<0x60, RawFrm, (outs), (ins), "pushal", [], IIC_PUSH_A>,
1309 OpSize32, Requires<[Not64BitMode]>;
1310 def PUSHA16 : I<0x60, RawFrm, (outs), (ins), "pushaw", [], IIC_PUSH_A>,
1311 OpSize16, Requires<[Not64BitMode]>;
1314 let Constraints = "$src = $dst", SchedRW = [WriteALU] in {
1315 // GR32 = bswap GR32
1316 def BSWAP32r : I<0xC8, AddRegFrm,
1317 (outs GR32:$dst), (ins GR32:$src),
1319 [(set GR32:$dst, (bswap GR32:$src))], IIC_BSWAP>, OpSize32, TB;
1321 def BSWAP64r : RI<0xC8, AddRegFrm, (outs GR64:$dst), (ins GR64:$src),
1323 [(set GR64:$dst, (bswap GR64:$src))], IIC_BSWAP>, TB;
1324 } // Constraints = "$src = $dst", SchedRW
1326 // Bit scan instructions.
1327 let Defs = [EFLAGS] in {
1328 def BSF16rr : I<0xBC, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
1329 "bsf{w}\t{$src, $dst|$dst, $src}",
1330 [(set GR16:$dst, EFLAGS, (X86bsf GR16:$src))],
1331 IIC_BIT_SCAN_REG>, PS, OpSize16, Sched<[WriteShift]>;
1332 def BSF16rm : I<0xBC, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
1333 "bsf{w}\t{$src, $dst|$dst, $src}",
1334 [(set GR16:$dst, EFLAGS, (X86bsf (loadi16 addr:$src)))],
1335 IIC_BIT_SCAN_MEM>, PS, OpSize16, Sched<[WriteShiftLd]>;
1336 def BSF32rr : I<0xBC, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
1337 "bsf{l}\t{$src, $dst|$dst, $src}",
1338 [(set GR32:$dst, EFLAGS, (X86bsf GR32:$src))],
1339 IIC_BIT_SCAN_REG>, PS, OpSize32, Sched<[WriteShift]>;
1340 def BSF32rm : I<0xBC, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
1341 "bsf{l}\t{$src, $dst|$dst, $src}",
1342 [(set GR32:$dst, EFLAGS, (X86bsf (loadi32 addr:$src)))],
1343 IIC_BIT_SCAN_MEM>, PS, OpSize32, Sched<[WriteShiftLd]>;
1344 def BSF64rr : RI<0xBC, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
1345 "bsf{q}\t{$src, $dst|$dst, $src}",
1346 [(set GR64:$dst, EFLAGS, (X86bsf GR64:$src))],
1347 IIC_BIT_SCAN_REG>, PS, Sched<[WriteShift]>;
1348 def BSF64rm : RI<0xBC, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
1349 "bsf{q}\t{$src, $dst|$dst, $src}",
1350 [(set GR64:$dst, EFLAGS, (X86bsf (loadi64 addr:$src)))],
1351 IIC_BIT_SCAN_MEM>, PS, Sched<[WriteShiftLd]>;
1353 def BSR16rr : I<0xBD, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
1354 "bsr{w}\t{$src, $dst|$dst, $src}",
1355 [(set GR16:$dst, EFLAGS, (X86bsr GR16:$src))],
1356 IIC_BIT_SCAN_REG>, PS, OpSize16, Sched<[WriteShift]>;
1357 def BSR16rm : I<0xBD, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
1358 "bsr{w}\t{$src, $dst|$dst, $src}",
1359 [(set GR16:$dst, EFLAGS, (X86bsr (loadi16 addr:$src)))],
1360 IIC_BIT_SCAN_MEM>, PS, OpSize16, Sched<[WriteShiftLd]>;
1361 def BSR32rr : I<0xBD, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
1362 "bsr{l}\t{$src, $dst|$dst, $src}",
1363 [(set GR32:$dst, EFLAGS, (X86bsr GR32:$src))],
1364 IIC_BIT_SCAN_REG>, PS, OpSize32, Sched<[WriteShift]>;
1365 def BSR32rm : I<0xBD, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
1366 "bsr{l}\t{$src, $dst|$dst, $src}",
1367 [(set GR32:$dst, EFLAGS, (X86bsr (loadi32 addr:$src)))],
1368 IIC_BIT_SCAN_MEM>, PS, OpSize32, Sched<[WriteShiftLd]>;
1369 def BSR64rr : RI<0xBD, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
1370 "bsr{q}\t{$src, $dst|$dst, $src}",
1371 [(set GR64:$dst, EFLAGS, (X86bsr GR64:$src))],
1372 IIC_BIT_SCAN_REG>, PS, Sched<[WriteShift]>;
1373 def BSR64rm : RI<0xBD, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
1374 "bsr{q}\t{$src, $dst|$dst, $src}",
1375 [(set GR64:$dst, EFLAGS, (X86bsr (loadi64 addr:$src)))],
1376 IIC_BIT_SCAN_MEM>, PS, Sched<[WriteShiftLd]>;
1377 } // Defs = [EFLAGS]
1379 let SchedRW = [WriteMicrocoded] in {
1380 // These uses the DF flag in the EFLAGS register to inc or dec EDI and ESI
1381 let Defs = [EDI,ESI], Uses = [EDI,ESI,EFLAGS] in {
1382 def MOVSB : I<0xA4, RawFrmDstSrc, (outs), (ins dstidx8:$dst, srcidx8:$src),
1383 "movsb\t{$src, $dst|$dst, $src}", [], IIC_MOVS>;
1384 def MOVSW : I<0xA5, RawFrmDstSrc, (outs), (ins dstidx16:$dst, srcidx16:$src),
1385 "movsw\t{$src, $dst|$dst, $src}", [], IIC_MOVS>, OpSize16;
1386 def MOVSL : I<0xA5, RawFrmDstSrc, (outs), (ins dstidx32:$dst, srcidx32:$src),
1387 "movs{l|d}\t{$src, $dst|$dst, $src}", [], IIC_MOVS>, OpSize32;
1388 def MOVSQ : RI<0xA5, RawFrmDstSrc, (outs), (ins dstidx64:$dst, srcidx64:$src),
1389 "movsq\t{$src, $dst|$dst, $src}", [], IIC_MOVS>;
1392 // These uses the DF flag in the EFLAGS register to inc or dec EDI and ESI
1393 let Defs = [EDI], Uses = [AL,EDI,EFLAGS] in
1394 def STOSB : I<0xAA, RawFrmDst, (outs), (ins dstidx8:$dst),
1395 "stosb\t{%al, $dst|$dst, al}", [], IIC_STOS>;
1396 let Defs = [EDI], Uses = [AX,EDI,EFLAGS] in
1397 def STOSW : I<0xAB, RawFrmDst, (outs), (ins dstidx16:$dst),
1398 "stosw\t{%ax, $dst|$dst, ax}", [], IIC_STOS>, OpSize16;
1399 let Defs = [EDI], Uses = [EAX,EDI,EFLAGS] in
1400 def STOSL : I<0xAB, RawFrmDst, (outs), (ins dstidx32:$dst),
1401 "stos{l|d}\t{%eax, $dst|$dst, eax}", [], IIC_STOS>, OpSize32;
1402 let Defs = [RDI], Uses = [RAX,RDI,EFLAGS] in
1403 def STOSQ : RI<0xAB, RawFrmDst, (outs), (ins dstidx64:$dst),
1404 "stosq\t{%rax, $dst|$dst, rax}", [], IIC_STOS>;
1406 // These uses the DF flag in the EFLAGS register to inc or dec EDI and ESI
1407 let Defs = [EDI,EFLAGS], Uses = [AL,EDI,EFLAGS] in
1408 def SCASB : I<0xAE, RawFrmDst, (outs), (ins dstidx8:$dst),
1409 "scasb\t{$dst, %al|al, $dst}", [], IIC_SCAS>;
1410 let Defs = [EDI,EFLAGS], Uses = [AX,EDI,EFLAGS] in
1411 def SCASW : I<0xAF, RawFrmDst, (outs), (ins dstidx16:$dst),
1412 "scasw\t{$dst, %ax|ax, $dst}", [], IIC_SCAS>, OpSize16;
1413 let Defs = [EDI,EFLAGS], Uses = [EAX,EDI,EFLAGS] in
1414 def SCASL : I<0xAF, RawFrmDst, (outs), (ins dstidx32:$dst),
1415 "scas{l|d}\t{$dst, %eax|eax, $dst}", [], IIC_SCAS>, OpSize32;
1416 let Defs = [EDI,EFLAGS], Uses = [RAX,EDI,EFLAGS] in
1417 def SCASQ : RI<0xAF, RawFrmDst, (outs), (ins dstidx64:$dst),
1418 "scasq\t{$dst, %rax|rax, $dst}", [], IIC_SCAS>;
1420 // These uses the DF flag in the EFLAGS register to inc or dec EDI and ESI
1421 let Defs = [EDI,ESI,EFLAGS], Uses = [EDI,ESI,EFLAGS] in {
1422 def CMPSB : I<0xA6, RawFrmDstSrc, (outs), (ins dstidx8:$dst, srcidx8:$src),
1423 "cmpsb\t{$dst, $src|$src, $dst}", [], IIC_CMPS>;
1424 def CMPSW : I<0xA7, RawFrmDstSrc, (outs), (ins dstidx16:$dst, srcidx16:$src),
1425 "cmpsw\t{$dst, $src|$src, $dst}", [], IIC_CMPS>, OpSize16;
1426 def CMPSL : I<0xA7, RawFrmDstSrc, (outs), (ins dstidx32:$dst, srcidx32:$src),
1427 "cmps{l|d}\t{$dst, $src|$src, $dst}", [], IIC_CMPS>, OpSize32;
1428 def CMPSQ : RI<0xA7, RawFrmDstSrc, (outs), (ins dstidx64:$dst, srcidx64:$src),
1429 "cmpsq\t{$dst, $src|$src, $dst}", [], IIC_CMPS>;
1433 //===----------------------------------------------------------------------===//
1434 // Move Instructions.
1436 let SchedRW = [WriteMove] in {
1437 let hasSideEffects = 0 in {
1438 def MOV8rr : I<0x88, MRMDestReg, (outs GR8 :$dst), (ins GR8 :$src),
1439 "mov{b}\t{$src, $dst|$dst, $src}", [], IIC_MOV>;
1440 def MOV16rr : I<0x89, MRMDestReg, (outs GR16:$dst), (ins GR16:$src),
1441 "mov{w}\t{$src, $dst|$dst, $src}", [], IIC_MOV>, OpSize16;
1442 def MOV32rr : I<0x89, MRMDestReg, (outs GR32:$dst), (ins GR32:$src),
1443 "mov{l}\t{$src, $dst|$dst, $src}", [], IIC_MOV>, OpSize32;
1444 def MOV64rr : RI<0x89, MRMDestReg, (outs GR64:$dst), (ins GR64:$src),
1445 "mov{q}\t{$src, $dst|$dst, $src}", [], IIC_MOV>;
1448 let isReMaterializable = 1, isAsCheapAsAMove = 1 in {
1449 def MOV8ri : Ii8 <0xB0, AddRegFrm, (outs GR8 :$dst), (ins i8imm :$src),
1450 "mov{b}\t{$src, $dst|$dst, $src}",
1451 [(set GR8:$dst, imm:$src)], IIC_MOV>;
1452 def MOV16ri : Ii16<0xB8, AddRegFrm, (outs GR16:$dst), (ins i16imm:$src),
1453 "mov{w}\t{$src, $dst|$dst, $src}",
1454 [(set GR16:$dst, imm:$src)], IIC_MOV>, OpSize16;
1455 def MOV32ri : Ii32<0xB8, AddRegFrm, (outs GR32:$dst), (ins i32imm:$src),
1456 "mov{l}\t{$src, $dst|$dst, $src}",
1457 [(set GR32:$dst, relocImm:$src)], IIC_MOV>, OpSize32;
1458 def MOV64ri32 : RIi32S<0xC7, MRM0r, (outs GR64:$dst), (ins i64i32imm:$src),
1459 "mov{q}\t{$src, $dst|$dst, $src}",
1460 [(set GR64:$dst, i64immSExt32:$src)], IIC_MOV>;
1462 let isReMaterializable = 1 in {
1463 def MOV64ri : RIi64<0xB8, AddRegFrm, (outs GR64:$dst), (ins i64imm:$src),
1464 "movabs{q}\t{$src, $dst|$dst, $src}",
1465 [(set GR64:$dst, relocImm:$src)], IIC_MOV>;
1468 // Longer forms that use a ModR/M byte. Needed for disassembler
1469 let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0 in {
1470 def MOV8ri_alt : Ii8 <0xC6, MRM0r, (outs GR8 :$dst), (ins i8imm :$src),
1471 "mov{b}\t{$src, $dst|$dst, $src}", [], IIC_MOV>,
1472 FoldGenData<"MOV8ri">;
1473 def MOV16ri_alt : Ii16<0xC7, MRM0r, (outs GR16:$dst), (ins i16imm:$src),
1474 "mov{w}\t{$src, $dst|$dst, $src}", [], IIC_MOV>, OpSize16,
1475 FoldGenData<"MOV16ri">;
1476 def MOV32ri_alt : Ii32<0xC7, MRM0r, (outs GR32:$dst), (ins i32imm:$src),
1477 "mov{l}\t{$src, $dst|$dst, $src}", [], IIC_MOV>, OpSize32,
1478 FoldGenData<"MOV32ri">;
1482 let SchedRW = [WriteStore] in {
1483 def MOV8mi : Ii8 <0xC6, MRM0m, (outs), (ins i8mem :$dst, i8imm :$src),
1484 "mov{b}\t{$src, $dst|$dst, $src}",
1485 [(store (i8 imm8_su:$src), addr:$dst)], IIC_MOV_MEM>;
1486 def MOV16mi : Ii16<0xC7, MRM0m, (outs), (ins i16mem:$dst, i16imm:$src),
1487 "mov{w}\t{$src, $dst|$dst, $src}",
1488 [(store (i16 imm16_su:$src), addr:$dst)], IIC_MOV_MEM>, OpSize16;
1489 def MOV32mi : Ii32<0xC7, MRM0m, (outs), (ins i32mem:$dst, i32imm:$src),
1490 "mov{l}\t{$src, $dst|$dst, $src}",
1491 [(store (i32 imm32_su:$src), addr:$dst)], IIC_MOV_MEM>, OpSize32;
1492 def MOV64mi32 : RIi32S<0xC7, MRM0m, (outs), (ins i64mem:$dst, i64i32imm:$src),
1493 "mov{q}\t{$src, $dst|$dst, $src}",
1494 [(store i64immSExt32_su:$src, addr:$dst)], IIC_MOV_MEM>,
1495 Requires<[In64BitMode]>;
1498 let hasSideEffects = 0 in {
1500 /// Memory offset versions of moves. The immediate is an address mode sized
1501 /// offset from the segment base.
1502 let SchedRW = [WriteALU] in {
1503 let mayLoad = 1 in {
1505 def MOV8ao32 : Ii32<0xA0, RawFrmMemOffs, (outs), (ins offset32_8:$src),
1506 "mov{b}\t{$src, %al|al, $src}", [], IIC_MOV_MEM>,
1509 def MOV16ao32 : Ii32<0xA1, RawFrmMemOffs, (outs), (ins offset32_16:$src),
1510 "mov{w}\t{$src, %ax|ax, $src}", [], IIC_MOV_MEM>,
1513 def MOV32ao32 : Ii32<0xA1, RawFrmMemOffs, (outs), (ins offset32_32:$src),
1514 "mov{l}\t{$src, %eax|eax, $src}", [], IIC_MOV_MEM>,
1517 def MOV64ao32 : RIi32<0xA1, RawFrmMemOffs, (outs), (ins offset32_64:$src),
1518 "mov{q}\t{$src, %rax|rax, $src}", [], IIC_MOV_MEM>,
1522 def MOV8ao16 : Ii16<0xA0, RawFrmMemOffs, (outs), (ins offset16_8:$src),
1523 "mov{b}\t{$src, %al|al, $src}", [], IIC_MOV_MEM>, AdSize16;
1525 def MOV16ao16 : Ii16<0xA1, RawFrmMemOffs, (outs), (ins offset16_16:$src),
1526 "mov{w}\t{$src, %ax|ax, $src}", [], IIC_MOV_MEM>,
1529 def MOV32ao16 : Ii16<0xA1, RawFrmMemOffs, (outs), (ins offset16_32:$src),
1530 "mov{l}\t{$src, %eax|eax, $src}", [], IIC_MOV_MEM>,
1533 let mayStore = 1 in {
1535 def MOV8o32a : Ii32<0xA2, RawFrmMemOffs, (outs), (ins offset32_8:$dst),
1536 "mov{b}\t{%al, $dst|$dst, al}", [], IIC_MOV_MEM>, AdSize32;
1538 def MOV16o32a : Ii32<0xA3, RawFrmMemOffs, (outs), (ins offset32_16:$dst),
1539 "mov{w}\t{%ax, $dst|$dst, ax}", [], IIC_MOV_MEM>,
1542 def MOV32o32a : Ii32<0xA3, RawFrmMemOffs, (outs), (ins offset32_32:$dst),
1543 "mov{l}\t{%eax, $dst|$dst, eax}", [], IIC_MOV_MEM>,
1546 def MOV64o32a : RIi32<0xA3, RawFrmMemOffs, (outs), (ins offset32_64:$dst),
1547 "mov{q}\t{%rax, $dst|$dst, rax}", [], IIC_MOV_MEM>,
1551 def MOV8o16a : Ii16<0xA2, RawFrmMemOffs, (outs), (ins offset16_8:$dst),
1552 "mov{b}\t{%al, $dst|$dst, al}", [], IIC_MOV_MEM>, AdSize16;
1554 def MOV16o16a : Ii16<0xA3, RawFrmMemOffs, (outs), (ins offset16_16:$dst),
1555 "mov{w}\t{%ax, $dst|$dst, ax}", [], IIC_MOV_MEM>,
1558 def MOV32o16a : Ii16<0xA3, RawFrmMemOffs, (outs), (ins offset16_32:$dst),
1559 "mov{l}\t{%eax, $dst|$dst, eax}", [], IIC_MOV_MEM>,
1564 // These forms all have full 64-bit absolute addresses in their instructions
1565 // and use the movabs mnemonic to indicate this specific form.
1566 let mayLoad = 1 in {
1568 def MOV8ao64 : RIi64_NOREX<0xA0, RawFrmMemOffs, (outs), (ins offset64_8:$src),
1569 "movabs{b}\t{$src, %al|al, $src}", [], IIC_MOV_MEM>,
1572 def MOV16ao64 : RIi64_NOREX<0xA1, RawFrmMemOffs, (outs), (ins offset64_16:$src),
1573 "movabs{w}\t{$src, %ax|ax, $src}", [], IIC_MOV_MEM>,
1576 def MOV32ao64 : RIi64_NOREX<0xA1, RawFrmMemOffs, (outs), (ins offset64_32:$src),
1577 "movabs{l}\t{$src, %eax|eax, $src}", [], IIC_MOV_MEM>,
1580 def MOV64ao64 : RIi64<0xA1, RawFrmMemOffs, (outs), (ins offset64_64:$src),
1581 "movabs{q}\t{$src, %rax|rax, $src}", [], IIC_MOV_MEM>,
1585 let mayStore = 1 in {
1587 def MOV8o64a : RIi64_NOREX<0xA2, RawFrmMemOffs, (outs), (ins offset64_8:$dst),
1588 "movabs{b}\t{%al, $dst|$dst, al}", [], IIC_MOV_MEM>,
1591 def MOV16o64a : RIi64_NOREX<0xA3, RawFrmMemOffs, (outs), (ins offset64_16:$dst),
1592 "movabs{w}\t{%ax, $dst|$dst, ax}", [], IIC_MOV_MEM>,
1595 def MOV32o64a : RIi64_NOREX<0xA3, RawFrmMemOffs, (outs), (ins offset64_32:$dst),
1596 "movabs{l}\t{%eax, $dst|$dst, eax}", [], IIC_MOV_MEM>,
1599 def MOV64o64a : RIi64<0xA3, RawFrmMemOffs, (outs), (ins offset64_64:$dst),
1600 "movabs{q}\t{%rax, $dst|$dst, rax}", [], IIC_MOV_MEM>,
1603 } // hasSideEffects = 0
1605 let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0,
1606 SchedRW = [WriteMove] in {
1607 def MOV8rr_REV : I<0x8A, MRMSrcReg, (outs GR8:$dst), (ins GR8:$src),
1608 "mov{b}\t{$src, $dst|$dst, $src}", [], IIC_MOV>,
1609 FoldGenData<"MOV8rr">;
1610 def MOV16rr_REV : I<0x8B, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
1611 "mov{w}\t{$src, $dst|$dst, $src}", [], IIC_MOV>, OpSize16,
1612 FoldGenData<"MOV16rr">;
1613 def MOV32rr_REV : I<0x8B, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
1614 "mov{l}\t{$src, $dst|$dst, $src}", [], IIC_MOV>, OpSize32,
1615 FoldGenData<"MOV32rr">;
1616 def MOV64rr_REV : RI<0x8B, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
1617 "mov{q}\t{$src, $dst|$dst, $src}", [], IIC_MOV>,
1618 FoldGenData<"MOV64rr">;
1621 let canFoldAsLoad = 1, isReMaterializable = 1, SchedRW = [WriteLoad] in {
1622 def MOV8rm : I<0x8A, MRMSrcMem, (outs GR8 :$dst), (ins i8mem :$src),
1623 "mov{b}\t{$src, $dst|$dst, $src}",
1624 [(set GR8:$dst, (loadi8 addr:$src))], IIC_MOV_MEM>;
1625 def MOV16rm : I<0x8B, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
1626 "mov{w}\t{$src, $dst|$dst, $src}",
1627 [(set GR16:$dst, (loadi16 addr:$src))], IIC_MOV_MEM>, OpSize16;
1628 def MOV32rm : I<0x8B, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
1629 "mov{l}\t{$src, $dst|$dst, $src}",
1630 [(set GR32:$dst, (loadi32 addr:$src))], IIC_MOV_MEM>, OpSize32;
1631 def MOV64rm : RI<0x8B, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
1632 "mov{q}\t{$src, $dst|$dst, $src}",
1633 [(set GR64:$dst, (load addr:$src))], IIC_MOV_MEM>;
1636 let SchedRW = [WriteStore] in {
1637 def MOV8mr : I<0x88, MRMDestMem, (outs), (ins i8mem :$dst, GR8 :$src),
1638 "mov{b}\t{$src, $dst|$dst, $src}",
1639 [(store GR8:$src, addr:$dst)], IIC_MOV_MEM>;
1640 def MOV16mr : I<0x89, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src),
1641 "mov{w}\t{$src, $dst|$dst, $src}",
1642 [(store GR16:$src, addr:$dst)], IIC_MOV_MEM>, OpSize16;
1643 def MOV32mr : I<0x89, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
1644 "mov{l}\t{$src, $dst|$dst, $src}",
1645 [(store GR32:$src, addr:$dst)], IIC_MOV_MEM>, OpSize32;
1646 def MOV64mr : RI<0x89, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
1647 "mov{q}\t{$src, $dst|$dst, $src}",
1648 [(store GR64:$src, addr:$dst)], IIC_MOV_MEM>;
1651 // Versions of MOV8rr, MOV8mr, and MOV8rm that use i8mem_NOREX and GR8_NOREX so
1652 // that they can be used for copying and storing h registers, which can't be
1653 // encoded when a REX prefix is present.
1654 let isCodeGenOnly = 1 in {
1655 let hasSideEffects = 0 in
1656 def MOV8rr_NOREX : I<0x88, MRMDestReg,
1657 (outs GR8_NOREX:$dst), (ins GR8_NOREX:$src),
1658 "mov{b}\t{$src, $dst|$dst, $src} # NOREX", [], IIC_MOV>,
1660 let mayStore = 1, hasSideEffects = 0 in
1661 def MOV8mr_NOREX : I<0x88, MRMDestMem,
1662 (outs), (ins i8mem_NOREX:$dst, GR8_NOREX:$src),
1663 "mov{b}\t{$src, $dst|$dst, $src} # NOREX", [],
1664 IIC_MOV_MEM>, Sched<[WriteStore]>;
1665 let mayLoad = 1, hasSideEffects = 0,
1666 canFoldAsLoad = 1, isReMaterializable = 1 in
1667 def MOV8rm_NOREX : I<0x8A, MRMSrcMem,
1668 (outs GR8_NOREX:$dst), (ins i8mem_NOREX:$src),
1669 "mov{b}\t{$src, $dst|$dst, $src} # NOREX", [],
1670 IIC_MOV_MEM>, Sched<[WriteLoad]>;
1674 // Condition code ops, incl. set if equal/not equal/...
1675 let SchedRW = [WriteALU] in {
1676 let Defs = [EFLAGS], Uses = [AH] in
1677 def SAHF : I<0x9E, RawFrm, (outs), (ins), "sahf",
1678 [(set EFLAGS, (X86sahf AH))], IIC_AHF>,
1679 Requires<[HasLAHFSAHF]>;
1680 let Defs = [AH], Uses = [EFLAGS], hasSideEffects = 0 in
1681 def LAHF : I<0x9F, RawFrm, (outs), (ins), "lahf", [],
1682 IIC_AHF>, // AH = flags
1683 Requires<[HasLAHFSAHF]>;
1686 //===----------------------------------------------------------------------===//
1687 // Bit tests instructions: BT, BTS, BTR, BTC.
1689 let Defs = [EFLAGS] in {
1690 let SchedRW = [WriteALU] in {
1691 def BT16rr : I<0xA3, MRMDestReg, (outs), (ins GR16:$src1, GR16:$src2),
1692 "bt{w}\t{$src2, $src1|$src1, $src2}",
1693 [(set EFLAGS, (X86bt GR16:$src1, GR16:$src2))], IIC_BT_RR>,
1694 OpSize16, TB, NotMemoryFoldable;
1695 def BT32rr : I<0xA3, MRMDestReg, (outs), (ins GR32:$src1, GR32:$src2),
1696 "bt{l}\t{$src2, $src1|$src1, $src2}",
1697 [(set EFLAGS, (X86bt GR32:$src1, GR32:$src2))], IIC_BT_RR>,
1698 OpSize32, TB, NotMemoryFoldable;
1699 def BT64rr : RI<0xA3, MRMDestReg, (outs), (ins GR64:$src1, GR64:$src2),
1700 "bt{q}\t{$src2, $src1|$src1, $src2}",
1701 [(set EFLAGS, (X86bt GR64:$src1, GR64:$src2))], IIC_BT_RR>, TB,
1705 // Unlike with the register+register form, the memory+register form of the
1706 // bt instruction does not ignore the high bits of the index. From ISel's
1707 // perspective, this is pretty bizarre. Make these instructions disassembly
1708 // only for now. These instructions are also slow on modern CPUs so that's
1709 // another reason to avoid generating them.
1711 let mayLoad = 1, hasSideEffects = 0, SchedRW = [WriteALULd] in {
1712 def BT16mr : I<0xA3, MRMDestMem, (outs), (ins i16mem:$src1, GR16:$src2),
1713 "bt{w}\t{$src2, $src1|$src1, $src2}",
1715 >, OpSize16, TB, NotMemoryFoldable;
1716 def BT32mr : I<0xA3, MRMDestMem, (outs), (ins i32mem:$src1, GR32:$src2),
1717 "bt{l}\t{$src2, $src1|$src1, $src2}",
1719 >, OpSize32, TB, NotMemoryFoldable;
1720 def BT64mr : RI<0xA3, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2),
1721 "bt{q}\t{$src2, $src1|$src1, $src2}",
1723 >, TB, NotMemoryFoldable;
1726 let SchedRW = [WriteALU] in {
1727 def BT16ri8 : Ii8<0xBA, MRM4r, (outs), (ins GR16:$src1, i16i8imm:$src2),
1728 "bt{w}\t{$src2, $src1|$src1, $src2}",
1729 [(set EFLAGS, (X86bt GR16:$src1, i16immSExt8:$src2))],
1730 IIC_BT_RI>, OpSize16, TB;
1731 def BT32ri8 : Ii8<0xBA, MRM4r, (outs), (ins GR32:$src1, i32i8imm:$src2),
1732 "bt{l}\t{$src2, $src1|$src1, $src2}",
1733 [(set EFLAGS, (X86bt GR32:$src1, i32immSExt8:$src2))],
1734 IIC_BT_RI>, OpSize32, TB;
1735 def BT64ri8 : RIi8<0xBA, MRM4r, (outs), (ins GR64:$src1, i64i8imm:$src2),
1736 "bt{q}\t{$src2, $src1|$src1, $src2}",
1737 [(set EFLAGS, (X86bt GR64:$src1, i64immSExt8:$src2))],
1741 // Note that these instructions aren't slow because that only applies when the
1742 // other operand is in a register. When it's an immediate, bt is still fast.
1743 let SchedRW = [WriteALU] in {
1744 def BT16mi8 : Ii8<0xBA, MRM4m, (outs), (ins i16mem:$src1, i16i8imm:$src2),
1745 "bt{w}\t{$src2, $src1|$src1, $src2}",
1746 [(set EFLAGS, (X86bt (loadi16 addr:$src1), i16immSExt8:$src2))
1747 ], IIC_BT_MI>, OpSize16, TB;
1748 def BT32mi8 : Ii8<0xBA, MRM4m, (outs), (ins i32mem:$src1, i32i8imm:$src2),
1749 "bt{l}\t{$src2, $src1|$src1, $src2}",
1750 [(set EFLAGS, (X86bt (loadi32 addr:$src1), i32immSExt8:$src2))
1751 ], IIC_BT_MI>, OpSize32, TB;
1752 def BT64mi8 : RIi8<0xBA, MRM4m, (outs), (ins i64mem:$src1, i64i8imm:$src2),
1753 "bt{q}\t{$src2, $src1|$src1, $src2}",
1754 [(set EFLAGS, (X86bt (loadi64 addr:$src1),
1755 i64immSExt8:$src2))], IIC_BT_MI>, TB,
1756 Requires<[In64BitMode]>;
1759 let hasSideEffects = 0 in {
1760 let SchedRW = [WriteALU], Constraints = "$src1 = $dst" in {
1761 def BTC16rr : I<0xBB, MRMDestReg, (outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
1762 "btc{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>,
1763 OpSize16, TB, NotMemoryFoldable;
1764 def BTC32rr : I<0xBB, MRMDestReg, (outs GR32:$dst), (ins GR32:$src1, GR32:$src2),
1765 "btc{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>,
1766 OpSize32, TB, NotMemoryFoldable;
1767 def BTC64rr : RI<0xBB, MRMDestReg, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
1768 "btc{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>, TB,
1772 let mayLoad = 1, mayStore = 1, SchedRW = [WriteALULd, WriteRMW] in {
1773 def BTC16mr : I<0xBB, MRMDestMem, (outs), (ins i16mem:$src1, GR16:$src2),
1774 "btc{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>,
1775 OpSize16, TB, NotMemoryFoldable;
1776 def BTC32mr : I<0xBB, MRMDestMem, (outs), (ins i32mem:$src1, GR32:$src2),
1777 "btc{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>,
1778 OpSize32, TB, NotMemoryFoldable;
1779 def BTC64mr : RI<0xBB, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2),
1780 "btc{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>, TB,
1784 let SchedRW = [WriteALU], Constraints = "$src1 = $dst" in {
1785 def BTC16ri8 : Ii8<0xBA, MRM7r, (outs GR16:$dst), (ins GR16:$src1, i16i8imm:$src2),
1786 "btc{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>,
1788 def BTC32ri8 : Ii8<0xBA, MRM7r, (outs GR32:$dst), (ins GR32:$src1, i32i8imm:$src2),
1789 "btc{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>,
1791 def BTC64ri8 : RIi8<0xBA, MRM7r, (outs GR64:$dst), (ins GR64:$src1, i64i8imm:$src2),
1792 "btc{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>, TB;
1795 let mayLoad = 1, mayStore = 1, SchedRW = [WriteALULd, WriteRMW] in {
1796 def BTC16mi8 : Ii8<0xBA, MRM7m, (outs), (ins i16mem:$src1, i16i8imm:$src2),
1797 "btc{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>,
1799 def BTC32mi8 : Ii8<0xBA, MRM7m, (outs), (ins i32mem:$src1, i32i8imm:$src2),
1800 "btc{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>,
1802 def BTC64mi8 : RIi8<0xBA, MRM7m, (outs), (ins i64mem:$src1, i64i8imm:$src2),
1803 "btc{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>, TB,
1804 Requires<[In64BitMode]>;
1807 let SchedRW = [WriteALU], Constraints = "$src1 = $dst" in {
1808 def BTR16rr : I<0xB3, MRMDestReg, (outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
1809 "btr{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>,
1810 OpSize16, TB, NotMemoryFoldable;
1811 def BTR32rr : I<0xB3, MRMDestReg, (outs GR32:$dst), (ins GR32:$src1, GR32:$src2),
1812 "btr{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>,
1813 OpSize32, TB, NotMemoryFoldable;
1814 def BTR64rr : RI<0xB3, MRMDestReg, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
1815 "btr{q}\t{$src2, $src1|$src1, $src2}", []>, TB, NotMemoryFoldable;
1818 let mayLoad = 1, mayStore = 1, SchedRW = [WriteALULd, WriteRMW] in {
1819 def BTR16mr : I<0xB3, MRMDestMem, (outs), (ins i16mem:$src1, GR16:$src2),
1820 "btr{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>,
1821 OpSize16, TB, NotMemoryFoldable;
1822 def BTR32mr : I<0xB3, MRMDestMem, (outs), (ins i32mem:$src1, GR32:$src2),
1823 "btr{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>,
1824 OpSize32, TB, NotMemoryFoldable;
1825 def BTR64mr : RI<0xB3, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2),
1826 "btr{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>, TB,
1830 let SchedRW = [WriteALU], Constraints = "$src1 = $dst" in {
1831 def BTR16ri8 : Ii8<0xBA, MRM6r, (outs GR16:$dst), (ins GR16:$src1, i16i8imm:$src2),
1832 "btr{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>,
1834 def BTR32ri8 : Ii8<0xBA, MRM6r, (outs GR32:$dst), (ins GR32:$src1, i32i8imm:$src2),
1835 "btr{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>,
1837 def BTR64ri8 : RIi8<0xBA, MRM6r, (outs GR64:$dst), (ins GR64:$src1, i64i8imm:$src2),
1838 "btr{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>, TB;
1841 let mayLoad = 1, mayStore = 1, SchedRW = [WriteALULd, WriteRMW] in {
1842 def BTR16mi8 : Ii8<0xBA, MRM6m, (outs), (ins i16mem:$src1, i16i8imm:$src2),
1843 "btr{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>,
1845 def BTR32mi8 : Ii8<0xBA, MRM6m, (outs), (ins i32mem:$src1, i32i8imm:$src2),
1846 "btr{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>,
1848 def BTR64mi8 : RIi8<0xBA, MRM6m, (outs), (ins i64mem:$src1, i64i8imm:$src2),
1849 "btr{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>, TB,
1850 Requires<[In64BitMode]>;
1853 let SchedRW = [WriteALU], Constraints = "$src1 = $dst" in {
1854 def BTS16rr : I<0xAB, MRMDestReg, (outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
1855 "bts{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>,
1856 OpSize16, TB, NotMemoryFoldable;
1857 def BTS32rr : I<0xAB, MRMDestReg, (outs GR32:$dst), (ins GR32:$src1, GR32:$src2),
1858 "bts{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>,
1859 OpSize32, TB, NotMemoryFoldable;
1860 def BTS64rr : RI<0xAB, MRMDestReg, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
1861 "bts{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>, TB,
1865 let mayLoad = 1, mayStore = 1, SchedRW = [WriteALULd, WriteRMW] in {
1866 def BTS16mr : I<0xAB, MRMDestMem, (outs), (ins i16mem:$src1, GR16:$src2),
1867 "bts{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>,
1868 OpSize16, TB, NotMemoryFoldable;
1869 def BTS32mr : I<0xAB, MRMDestMem, (outs), (ins i32mem:$src1, GR32:$src2),
1870 "bts{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>,
1871 OpSize32, TB, NotMemoryFoldable;
1872 def BTS64mr : RI<0xAB, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2),
1873 "bts{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>, TB,
1877 let SchedRW = [WriteALU], Constraints = "$src1 = $dst" in {
1878 def BTS16ri8 : Ii8<0xBA, MRM5r, (outs GR16:$dst), (ins GR16:$src1, i16i8imm:$src2),
1879 "bts{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>,
1881 def BTS32ri8 : Ii8<0xBA, MRM5r, (outs GR32:$dst), (ins GR32:$src1, i32i8imm:$src2),
1882 "bts{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>,
1884 def BTS64ri8 : RIi8<0xBA, MRM5r, (outs GR64:$dst), (ins GR64:$src1, i64i8imm:$src2),
1885 "bts{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>, TB;
1888 let mayLoad = 1, mayStore = 1, SchedRW = [WriteALULd, WriteRMW] in {
1889 def BTS16mi8 : Ii8<0xBA, MRM5m, (outs), (ins i16mem:$src1, i16i8imm:$src2),
1890 "bts{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>,
1892 def BTS32mi8 : Ii8<0xBA, MRM5m, (outs), (ins i32mem:$src1, i32i8imm:$src2),
1893 "bts{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>,
1895 def BTS64mi8 : RIi8<0xBA, MRM5m, (outs), (ins i64mem:$src1, i64i8imm:$src2),
1896 "bts{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>, TB,
1897 Requires<[In64BitMode]>;
1899 } // hasSideEffects = 0
1900 } // Defs = [EFLAGS]
1903 //===----------------------------------------------------------------------===//
1907 // Atomic swap. These are just normal xchg instructions. But since a memory
1908 // operand is referenced, the atomicity is ensured.
1909 multiclass ATOMIC_SWAP<bits<8> opc8, bits<8> opc, string mnemonic, string frag,
1910 InstrItinClass itin> {
1911 let Constraints = "$val = $dst", SchedRW = [WriteALULd, WriteRMW] in {
1912 def NAME#8rm : I<opc8, MRMSrcMem, (outs GR8:$dst),
1913 (ins GR8:$val, i8mem:$ptr),
1914 !strconcat(mnemonic, "{b}\t{$val, $ptr|$ptr, $val}"),
1917 (!cast<PatFrag>(frag # "_8") addr:$ptr, GR8:$val))],
1919 def NAME#16rm : I<opc, MRMSrcMem, (outs GR16:$dst),
1920 (ins GR16:$val, i16mem:$ptr),
1921 !strconcat(mnemonic, "{w}\t{$val, $ptr|$ptr, $val}"),
1924 (!cast<PatFrag>(frag # "_16") addr:$ptr, GR16:$val))],
1926 def NAME#32rm : I<opc, MRMSrcMem, (outs GR32:$dst),
1927 (ins GR32:$val, i32mem:$ptr),
1928 !strconcat(mnemonic, "{l}\t{$val, $ptr|$ptr, $val}"),
1931 (!cast<PatFrag>(frag # "_32") addr:$ptr, GR32:$val))],
1933 def NAME#64rm : RI<opc, MRMSrcMem, (outs GR64:$dst),
1934 (ins GR64:$val, i64mem:$ptr),
1935 !strconcat(mnemonic, "{q}\t{$val, $ptr|$ptr, $val}"),
1938 (!cast<PatFrag>(frag # "_64") addr:$ptr, GR64:$val))],
1943 defm XCHG : ATOMIC_SWAP<0x86, 0x87, "xchg", "atomic_swap", IIC_XCHG_MEM>;
1945 // Swap between registers.
1946 let SchedRW = [WriteALU] in {
1947 let Constraints = "$val = $dst" in {
1948 def XCHG8rr : I<0x86, MRMSrcReg, (outs GR8:$dst), (ins GR8:$val, GR8:$src),
1949 "xchg{b}\t{$val, $src|$src, $val}", [], IIC_XCHG_REG>;
1950 def XCHG16rr : I<0x87, MRMSrcReg, (outs GR16:$dst), (ins GR16:$val, GR16:$src),
1951 "xchg{w}\t{$val, $src|$src, $val}", [], IIC_XCHG_REG>,
1953 def XCHG32rr : I<0x87, MRMSrcReg, (outs GR32:$dst), (ins GR32:$val, GR32:$src),
1954 "xchg{l}\t{$val, $src|$src, $val}", [], IIC_XCHG_REG>,
1956 def XCHG64rr : RI<0x87, MRMSrcReg, (outs GR64:$dst), (ins GR64:$val,GR64:$src),
1957 "xchg{q}\t{$val, $src|$src, $val}", [], IIC_XCHG_REG>;
1960 // Swap between EAX and other registers.
1961 let Uses = [AX], Defs = [AX] in
1962 def XCHG16ar : I<0x90, AddRegFrm, (outs), (ins GR16:$src),
1963 "xchg{w}\t{$src, %ax|ax, $src}", [], IIC_XCHG_REG>, OpSize16;
1964 let Uses = [EAX], Defs = [EAX] in
1965 def XCHG32ar : I<0x90, AddRegFrm, (outs), (ins GR32:$src),
1966 "xchg{l}\t{$src, %eax|eax, $src}", [], IIC_XCHG_REG>,
1967 OpSize32, Requires<[Not64BitMode]>;
1968 let Uses = [EAX], Defs = [EAX] in
1969 // Uses GR32_NOAX in 64-bit mode to prevent encoding using the 0x90 NOP encoding.
1970 // xchg %eax, %eax needs to clear upper 32-bits of RAX so is not a NOP.
1971 def XCHG32ar64 : I<0x90, AddRegFrm, (outs), (ins GR32_NOAX:$src),
1972 "xchg{l}\t{$src, %eax|eax, $src}", [], IIC_XCHG_REG>,
1973 OpSize32, Requires<[In64BitMode]>;
1974 let Uses = [RAX], Defs = [RAX] in
1975 def XCHG64ar : RI<0x90, AddRegFrm, (outs), (ins GR64:$src),
1976 "xchg{q}\t{$src, %rax|rax, $src}", [], IIC_XCHG_REG>;
1979 let SchedRW = [WriteALU] in {
1980 def XADD8rr : I<0xC0, MRMDestReg, (outs GR8:$dst), (ins GR8:$src),
1981 "xadd{b}\t{$src, $dst|$dst, $src}", [], IIC_XADD_REG>, TB;
1982 def XADD16rr : I<0xC1, MRMDestReg, (outs GR16:$dst), (ins GR16:$src),
1983 "xadd{w}\t{$src, $dst|$dst, $src}", [], IIC_XADD_REG>, TB,
1985 def XADD32rr : I<0xC1, MRMDestReg, (outs GR32:$dst), (ins GR32:$src),
1986 "xadd{l}\t{$src, $dst|$dst, $src}", [], IIC_XADD_REG>, TB,
1988 def XADD64rr : RI<0xC1, MRMDestReg, (outs GR64:$dst), (ins GR64:$src),
1989 "xadd{q}\t{$src, $dst|$dst, $src}", [], IIC_XADD_REG>, TB;
1992 let mayLoad = 1, mayStore = 1, SchedRW = [WriteALULd, WriteRMW] in {
1993 def XADD8rm : I<0xC0, MRMDestMem, (outs), (ins i8mem:$dst, GR8:$src),
1994 "xadd{b}\t{$src, $dst|$dst, $src}", [], IIC_XADD_MEM>, TB;
1995 def XADD16rm : I<0xC1, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src),
1996 "xadd{w}\t{$src, $dst|$dst, $src}", [], IIC_XADD_MEM>, TB,
1998 def XADD32rm : I<0xC1, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
1999 "xadd{l}\t{$src, $dst|$dst, $src}", [], IIC_XADD_MEM>, TB,
2001 def XADD64rm : RI<0xC1, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
2002 "xadd{q}\t{$src, $dst|$dst, $src}", [], IIC_XADD_MEM>, TB;
2006 let SchedRW = [WriteALU] in {
2007 def CMPXCHG8rr : I<0xB0, MRMDestReg, (outs GR8:$dst), (ins GR8:$src),
2008 "cmpxchg{b}\t{$src, $dst|$dst, $src}", [],
2009 IIC_CMPXCHG_REG8>, TB;
2010 def CMPXCHG16rr : I<0xB1, MRMDestReg, (outs GR16:$dst), (ins GR16:$src),
2011 "cmpxchg{w}\t{$src, $dst|$dst, $src}", [],
2012 IIC_CMPXCHG_REG>, TB, OpSize16;
2013 def CMPXCHG32rr : I<0xB1, MRMDestReg, (outs GR32:$dst), (ins GR32:$src),
2014 "cmpxchg{l}\t{$src, $dst|$dst, $src}", [],
2015 IIC_CMPXCHG_REG>, TB, OpSize32;
2016 def CMPXCHG64rr : RI<0xB1, MRMDestReg, (outs GR64:$dst), (ins GR64:$src),
2017 "cmpxchg{q}\t{$src, $dst|$dst, $src}", [],
2018 IIC_CMPXCHG_REG>, TB;
2021 let SchedRW = [WriteALULd, WriteRMW] in {
2022 let mayLoad = 1, mayStore = 1 in {
2023 def CMPXCHG8rm : I<0xB0, MRMDestMem, (outs), (ins i8mem:$dst, GR8:$src),
2024 "cmpxchg{b}\t{$src, $dst|$dst, $src}", [],
2025 IIC_CMPXCHG_MEM8>, TB;
2026 def CMPXCHG16rm : I<0xB1, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src),
2027 "cmpxchg{w}\t{$src, $dst|$dst, $src}", [],
2028 IIC_CMPXCHG_MEM>, TB, OpSize16;
2029 def CMPXCHG32rm : I<0xB1, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
2030 "cmpxchg{l}\t{$src, $dst|$dst, $src}", [],
2031 IIC_CMPXCHG_MEM>, TB, OpSize32;
2032 def CMPXCHG64rm : RI<0xB1, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
2033 "cmpxchg{q}\t{$src, $dst|$dst, $src}", [],
2034 IIC_CMPXCHG_MEM>, TB;
2037 let Defs = [EAX, EDX, EFLAGS], Uses = [EAX, EBX, ECX, EDX] in
2038 def CMPXCHG8B : I<0xC7, MRM1m, (outs), (ins i64mem:$dst),
2039 "cmpxchg8b\t$dst", [], IIC_CMPXCHG_8B>, TB;
2041 let Defs = [RAX, RDX, EFLAGS], Uses = [RAX, RBX, RCX, RDX] in
2042 def CMPXCHG16B : RI<0xC7, MRM1m, (outs), (ins i128mem:$dst),
2043 "cmpxchg16b\t$dst", [], IIC_CMPXCHG_16B>,
2044 TB, Requires<[HasCmpxchg16b, In64BitMode]>;
2048 // Lock instruction prefix
2049 let SchedRW = [WriteMicrocoded] in
2050 def LOCK_PREFIX : I<0xF0, RawFrm, (outs), (ins), "lock", []>;
2052 let SchedRW = [WriteNop] in {
2054 // Rex64 instruction prefix
2055 def REX64_PREFIX : I<0x48, RawFrm, (outs), (ins), "rex64", [], IIC_NOP>,
2056 Requires<[In64BitMode]>;
2058 // Data16 instruction prefix
2059 def DATA16_PREFIX : I<0x66, RawFrm, (outs), (ins), "data16", [], IIC_NOP>,
2060 Requires<[Not16BitMode]>;
2062 // Data instruction prefix
2063 def DATA32_PREFIX : I<0x66, RawFrm, (outs), (ins), "data32", [], IIC_NOP>,
2064 Requires<[In16BitMode]>;
2067 // Repeat string operation instruction prefixes
2068 // These use the DF flag in the EFLAGS register to inc or dec ECX
2069 let Defs = [ECX], Uses = [ECX,EFLAGS], SchedRW = [WriteMicrocoded] in {
2070 // Repeat (used with INS, OUTS, MOVS, LODS and STOS)
2071 def REP_PREFIX : I<0xF3, RawFrm, (outs), (ins), "rep", []>;
2072 // Repeat while not equal (used with CMPS and SCAS)
2073 def REPNE_PREFIX : I<0xF2, RawFrm, (outs), (ins), "repne", []>;
2076 // String manipulation instructions
2077 let SchedRW = [WriteMicrocoded] in {
2078 // These uses the DF flag in the EFLAGS register to inc or dec EDI and ESI
2079 let Defs = [AL,ESI], Uses = [ESI,EFLAGS] in
2080 def LODSB : I<0xAC, RawFrmSrc, (outs), (ins srcidx8:$src),
2081 "lodsb\t{$src, %al|al, $src}", [], IIC_LODS>;
2082 let Defs = [AX,ESI], Uses = [ESI,EFLAGS] in
2083 def LODSW : I<0xAD, RawFrmSrc, (outs), (ins srcidx16:$src),
2084 "lodsw\t{$src, %ax|ax, $src}", [], IIC_LODS>, OpSize16;
2085 let Defs = [EAX,ESI], Uses = [ESI,EFLAGS] in
2086 def LODSL : I<0xAD, RawFrmSrc, (outs), (ins srcidx32:$src),
2087 "lods{l|d}\t{$src, %eax|eax, $src}", [], IIC_LODS>, OpSize32;
2088 let Defs = [RAX,ESI], Uses = [ESI,EFLAGS] in
2089 def LODSQ : RI<0xAD, RawFrmSrc, (outs), (ins srcidx64:$src),
2090 "lodsq\t{$src, %rax|rax, $src}", [], IIC_LODS>;
2093 let SchedRW = [WriteSystem] in {
2094 // These uses the DF flag in the EFLAGS register to inc or dec EDI and ESI
2095 let Defs = [ESI], Uses = [DX,ESI,EFLAGS] in {
2096 def OUTSB : I<0x6E, RawFrmSrc, (outs), (ins srcidx8:$src),
2097 "outsb\t{$src, %dx|dx, $src}", [], IIC_OUTS>;
2098 def OUTSW : I<0x6F, RawFrmSrc, (outs), (ins srcidx16:$src),
2099 "outsw\t{$src, %dx|dx, $src}", [], IIC_OUTS>, OpSize16;
2100 def OUTSL : I<0x6F, RawFrmSrc, (outs), (ins srcidx32:$src),
2101 "outs{l|d}\t{$src, %dx|dx, $src}", [], IIC_OUTS>, OpSize32;
2104 // These uses the DF flag in the EFLAGS register to inc or dec EDI and ESI
2105 let Defs = [EDI], Uses = [DX,EDI,EFLAGS] in {
2106 def INSB : I<0x6C, RawFrmDst, (outs), (ins dstidx8:$dst),
2107 "insb\t{%dx, $dst|$dst, dx}", [], IIC_INS>;
2108 def INSW : I<0x6D, RawFrmDst, (outs), (ins dstidx16:$dst),
2109 "insw\t{%dx, $dst|$dst, dx}", [], IIC_INS>, OpSize16;
2110 def INSL : I<0x6D, RawFrmDst, (outs), (ins dstidx32:$dst),
2111 "ins{l|d}\t{%dx, $dst|$dst, dx}", [], IIC_INS>, OpSize32;
2115 // Flag instructions
2116 let SchedRW = [WriteALU] in {
2117 def CLC : I<0xF8, RawFrm, (outs), (ins), "clc", [], IIC_CLC>;
2118 def STC : I<0xF9, RawFrm, (outs), (ins), "stc", [], IIC_STC>;
2119 def CLI : I<0xFA, RawFrm, (outs), (ins), "cli", [], IIC_CLI>;
2120 def STI : I<0xFB, RawFrm, (outs), (ins), "sti", [], IIC_STI>;
2121 def CLD : I<0xFC, RawFrm, (outs), (ins), "cld", [], IIC_CLD>;
2122 def STD : I<0xFD, RawFrm, (outs), (ins), "std", [], IIC_STD>;
2123 def CMC : I<0xF5, RawFrm, (outs), (ins), "cmc", [], IIC_CMC>;
2125 def CLTS : I<0x06, RawFrm, (outs), (ins), "clts", [], IIC_CLTS>, TB;
2128 // Table lookup instructions
2129 let Uses = [AL,EBX], Defs = [AL], hasSideEffects = 0, mayLoad = 1 in
2130 def XLAT : I<0xD7, RawFrm, (outs), (ins), "xlatb", [], IIC_XLAT>,
2133 let SchedRW = [WriteMicrocoded] in {
2134 // ASCII Adjust After Addition
2135 let Uses = [AL,EFLAGS], Defs = [AX,EFLAGS], hasSideEffects = 0 in
2136 def AAA : I<0x37, RawFrm, (outs), (ins), "aaa", [], IIC_AAA>,
2137 Requires<[Not64BitMode]>;
2139 // ASCII Adjust AX Before Division
2140 let Uses = [AX], Defs = [AX,EFLAGS], hasSideEffects = 0 in
2141 def AAD8i8 : Ii8<0xD5, RawFrm, (outs), (ins i8imm:$src),
2142 "aad\t$src", [], IIC_AAD>, Requires<[Not64BitMode]>;
2144 // ASCII Adjust AX After Multiply
2145 let Uses = [AL], Defs = [AX,EFLAGS], hasSideEffects = 0 in
2146 def AAM8i8 : Ii8<0xD4, RawFrm, (outs), (ins i8imm:$src),
2147 "aam\t$src", [], IIC_AAM>, Requires<[Not64BitMode]>;
2149 // ASCII Adjust AL After Subtraction - sets
2150 let Uses = [AL,EFLAGS], Defs = [AX,EFLAGS], hasSideEffects = 0 in
2151 def AAS : I<0x3F, RawFrm, (outs), (ins), "aas", [], IIC_AAS>,
2152 Requires<[Not64BitMode]>;
2154 // Decimal Adjust AL after Addition
2155 let Uses = [AL,EFLAGS], Defs = [AL,EFLAGS], hasSideEffects = 0 in
2156 def DAA : I<0x27, RawFrm, (outs), (ins), "daa", [], IIC_DAA>,
2157 Requires<[Not64BitMode]>;
2159 // Decimal Adjust AL after Subtraction
2160 let Uses = [AL,EFLAGS], Defs = [AL,EFLAGS], hasSideEffects = 0 in
2161 def DAS : I<0x2F, RawFrm, (outs), (ins), "das", [], IIC_DAS>,
2162 Requires<[Not64BitMode]>;
2165 let SchedRW = [WriteSystem] in {
2166 // Check Array Index Against Bounds
2167 def BOUNDS16rm : I<0x62, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
2168 "bound\t{$src, $dst|$dst, $src}", [], IIC_BOUND>, OpSize16,
2169 Requires<[Not64BitMode]>;
2170 def BOUNDS32rm : I<0x62, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
2171 "bound\t{$src, $dst|$dst, $src}", [], IIC_BOUND>, OpSize32,
2172 Requires<[Not64BitMode]>;
2174 // Adjust RPL Field of Segment Selector
2175 def ARPL16rr : I<0x63, MRMDestReg, (outs GR16:$dst), (ins GR16:$src),
2176 "arpl\t{$src, $dst|$dst, $src}", [], IIC_ARPL_REG>,
2177 Requires<[Not64BitMode]>;
2179 def ARPL16mr : I<0x63, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src),
2180 "arpl\t{$src, $dst|$dst, $src}", [], IIC_ARPL_MEM>,
2181 Requires<[Not64BitMode]>;
2184 //===----------------------------------------------------------------------===//
2185 // MOVBE Instructions
2187 let Predicates = [HasMOVBE] in {
2188 let SchedRW = [WriteALULd] in {
2189 def MOVBE16rm : I<0xF0, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
2190 "movbe{w}\t{$src, $dst|$dst, $src}",
2191 [(set GR16:$dst, (bswap (loadi16 addr:$src)))], IIC_MOVBE>,
2193 def MOVBE32rm : I<0xF0, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
2194 "movbe{l}\t{$src, $dst|$dst, $src}",
2195 [(set GR32:$dst, (bswap (loadi32 addr:$src)))], IIC_MOVBE>,
2197 def MOVBE64rm : RI<0xF0, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
2198 "movbe{q}\t{$src, $dst|$dst, $src}",
2199 [(set GR64:$dst, (bswap (loadi64 addr:$src)))], IIC_MOVBE>,
2202 let SchedRW = [WriteStore] in {
2203 def MOVBE16mr : I<0xF1, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src),
2204 "movbe{w}\t{$src, $dst|$dst, $src}",
2205 [(store (bswap GR16:$src), addr:$dst)], IIC_MOVBE>,
2207 def MOVBE32mr : I<0xF1, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
2208 "movbe{l}\t{$src, $dst|$dst, $src}",
2209 [(store (bswap GR32:$src), addr:$dst)], IIC_MOVBE>,
2211 def MOVBE64mr : RI<0xF1, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
2212 "movbe{q}\t{$src, $dst|$dst, $src}",
2213 [(store (bswap GR64:$src), addr:$dst)], IIC_MOVBE>,
2218 //===----------------------------------------------------------------------===//
2219 // RDRAND Instruction
2221 let Predicates = [HasRDRAND], Defs = [EFLAGS], SchedRW = [WriteSystem] in {
2222 def RDRAND16r : I<0xC7, MRM6r, (outs GR16:$dst), (ins),
2224 [(set GR16:$dst, EFLAGS, (X86rdrand))], IIC_RDRAND>,
2226 def RDRAND32r : I<0xC7, MRM6r, (outs GR32:$dst), (ins),
2228 [(set GR32:$dst, EFLAGS, (X86rdrand))], IIC_RDRAND>,
2230 def RDRAND64r : RI<0xC7, MRM6r, (outs GR64:$dst), (ins),
2232 [(set GR64:$dst, EFLAGS, (X86rdrand))], IIC_RDRAND>, PS;
2235 //===----------------------------------------------------------------------===//
2236 // RDSEED Instruction
2238 let Predicates = [HasRDSEED], Defs = [EFLAGS], SchedRW = [WriteSystem] in {
2239 def RDSEED16r : I<0xC7, MRM7r, (outs GR16:$dst), (ins),
2241 [(set GR16:$dst, EFLAGS, (X86rdseed))], IIC_RDSEED>,
2243 def RDSEED32r : I<0xC7, MRM7r, (outs GR32:$dst), (ins),
2245 [(set GR32:$dst, EFLAGS, (X86rdseed))], IIC_RDSEED>,
2247 def RDSEED64r : RI<0xC7, MRM7r, (outs GR64:$dst), (ins),
2249 [(set GR64:$dst, EFLAGS, (X86rdseed))], IIC_RDSEED>, PS;
2252 //===----------------------------------------------------------------------===//
2253 // LZCNT Instruction
2255 let Predicates = [HasLZCNT], Defs = [EFLAGS] in {
2256 def LZCNT16rr : I<0xBD, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
2257 "lzcnt{w}\t{$src, $dst|$dst, $src}",
2258 [(set GR16:$dst, (ctlz GR16:$src)), (implicit EFLAGS)],
2259 IIC_LZCNT_RR>, XS, OpSize16, Sched<[WriteIMul]>;
2260 def LZCNT16rm : I<0xBD, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
2261 "lzcnt{w}\t{$src, $dst|$dst, $src}",
2262 [(set GR16:$dst, (ctlz (loadi16 addr:$src))),
2263 (implicit EFLAGS)], IIC_LZCNT_RM>, XS, OpSize16,
2264 Sched<[WriteIMulLd]>;
2266 def LZCNT32rr : I<0xBD, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
2267 "lzcnt{l}\t{$src, $dst|$dst, $src}",
2268 [(set GR32:$dst, (ctlz GR32:$src)), (implicit EFLAGS)],
2269 IIC_LZCNT_RR>, XS, OpSize32, Sched<[WriteIMul]>;
2270 def LZCNT32rm : I<0xBD, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
2271 "lzcnt{l}\t{$src, $dst|$dst, $src}",
2272 [(set GR32:$dst, (ctlz (loadi32 addr:$src))),
2273 (implicit EFLAGS)], IIC_LZCNT_RM>, XS, OpSize32,
2274 Sched<[WriteIMulLd]>;
2276 def LZCNT64rr : RI<0xBD, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
2277 "lzcnt{q}\t{$src, $dst|$dst, $src}",
2278 [(set GR64:$dst, (ctlz GR64:$src)), (implicit EFLAGS)],
2279 IIC_LZCNT_RR>, XS, Sched<[WriteIMul]>;
2280 def LZCNT64rm : RI<0xBD, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
2281 "lzcnt{q}\t{$src, $dst|$dst, $src}",
2282 [(set GR64:$dst, (ctlz (loadi64 addr:$src))),
2283 (implicit EFLAGS)], IIC_LZCNT_RM>, XS,
2284 Sched<[WriteIMulLd]>;
2287 //===----------------------------------------------------------------------===//
2290 let Predicates = [HasBMI], Defs = [EFLAGS] in {
2291 def TZCNT16rr : I<0xBC, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
2292 "tzcnt{w}\t{$src, $dst|$dst, $src}",
2293 [(set GR16:$dst, (cttz GR16:$src)), (implicit EFLAGS)],
2294 IIC_TZCNT_RR>, XS, OpSize16, Sched<[WriteIMul]>;
2295 def TZCNT16rm : I<0xBC, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
2296 "tzcnt{w}\t{$src, $dst|$dst, $src}",
2297 [(set GR16:$dst, (cttz (loadi16 addr:$src))),
2298 (implicit EFLAGS)], IIC_TZCNT_RM>, XS, OpSize16,
2299 Sched<[WriteIMulLd]>;
2301 def TZCNT32rr : I<0xBC, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
2302 "tzcnt{l}\t{$src, $dst|$dst, $src}",
2303 [(set GR32:$dst, (cttz GR32:$src)), (implicit EFLAGS)],
2304 IIC_TZCNT_RR>, XS, OpSize32, Sched<[WriteIMul]>;
2305 def TZCNT32rm : I<0xBC, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
2306 "tzcnt{l}\t{$src, $dst|$dst, $src}",
2307 [(set GR32:$dst, (cttz (loadi32 addr:$src))),
2308 (implicit EFLAGS)], IIC_TZCNT_RM>, XS, OpSize32,
2309 Sched<[WriteIMulLd]>;
2311 def TZCNT64rr : RI<0xBC, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
2312 "tzcnt{q}\t{$src, $dst|$dst, $src}",
2313 [(set GR64:$dst, (cttz GR64:$src)), (implicit EFLAGS)],
2314 IIC_TZCNT_RR>, XS, Sched<[WriteIMul]>;
2315 def TZCNT64rm : RI<0xBC, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
2316 "tzcnt{q}\t{$src, $dst|$dst, $src}",
2317 [(set GR64:$dst, (cttz (loadi64 addr:$src))),
2318 (implicit EFLAGS)], IIC_TZCNT_RM>, XS,
2319 Sched<[WriteIMulLd]>;
2322 multiclass bmi_bls<string mnemonic, Format RegMRM, Format MemMRM,
2323 RegisterClass RC, X86MemOperand x86memop> {
2324 let hasSideEffects = 0 in {
2325 def rr : I<0xF3, RegMRM, (outs RC:$dst), (ins RC:$src),
2326 !strconcat(mnemonic, "\t{$src, $dst|$dst, $src}"),
2327 [], IIC_UNARY_REG>, T8PS, VEX_4V, Sched<[WriteALU]>;
2329 def rm : I<0xF3, MemMRM, (outs RC:$dst), (ins x86memop:$src),
2330 !strconcat(mnemonic, "\t{$src, $dst|$dst, $src}"),
2331 [], IIC_UNARY_MEM>, T8PS, VEX_4V, Sched<[WriteALULd, ReadAfterLd]>;
2335 let Predicates = [HasBMI], Defs = [EFLAGS] in {
2336 defm BLSR32 : bmi_bls<"blsr{l}", MRM1r, MRM1m, GR32, i32mem>;
2337 defm BLSR64 : bmi_bls<"blsr{q}", MRM1r, MRM1m, GR64, i64mem>, VEX_W;
2338 defm BLSMSK32 : bmi_bls<"blsmsk{l}", MRM2r, MRM2m, GR32, i32mem>;
2339 defm BLSMSK64 : bmi_bls<"blsmsk{q}", MRM2r, MRM2m, GR64, i64mem>, VEX_W;
2340 defm BLSI32 : bmi_bls<"blsi{l}", MRM3r, MRM3m, GR32, i32mem>;
2341 defm BLSI64 : bmi_bls<"blsi{q}", MRM3r, MRM3m, GR64, i64mem>, VEX_W;
2344 //===----------------------------------------------------------------------===//
2345 // Pattern fragments to auto generate BMI instructions.
2346 //===----------------------------------------------------------------------===//
2348 let Predicates = [HasBMI] in {
2349 // FIXME: patterns for the load versions are not implemented
2350 def : Pat<(and GR32:$src, (add GR32:$src, -1)),
2351 (BLSR32rr GR32:$src)>;
2352 def : Pat<(and GR64:$src, (add GR64:$src, -1)),
2353 (BLSR64rr GR64:$src)>;
2355 def : Pat<(xor GR32:$src, (add GR32:$src, -1)),
2356 (BLSMSK32rr GR32:$src)>;
2357 def : Pat<(xor GR64:$src, (add GR64:$src, -1)),
2358 (BLSMSK64rr GR64:$src)>;
2360 def : Pat<(and GR32:$src, (ineg GR32:$src)),
2361 (BLSI32rr GR32:$src)>;
2362 def : Pat<(and GR64:$src, (ineg GR64:$src)),
2363 (BLSI64rr GR64:$src)>;
2366 multiclass bmi_bextr_bzhi<bits<8> opc, string mnemonic, RegisterClass RC,
2367 X86MemOperand x86memop, Intrinsic Int,
2369 def rr : I<opc, MRMSrcReg4VOp3, (outs RC:$dst), (ins RC:$src1, RC:$src2),
2370 !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2371 [(set RC:$dst, (Int RC:$src1, RC:$src2)), (implicit EFLAGS)], IIC_BIN_NONMEM>,
2372 T8PS, VEX, Sched<[WriteALU]>;
2373 def rm : I<opc, MRMSrcMem4VOp3, (outs RC:$dst), (ins x86memop:$src1, RC:$src2),
2374 !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2375 [(set RC:$dst, (Int (ld_frag addr:$src1), RC:$src2)),
2376 (implicit EFLAGS)], IIC_BIN_MEM>, T8PS, VEX,
2377 Sched<[WriteALULd, ReadAfterLd]>;
2380 let Predicates = [HasBMI], Defs = [EFLAGS] in {
2381 defm BEXTR32 : bmi_bextr_bzhi<0xF7, "bextr{l}", GR32, i32mem,
2382 int_x86_bmi_bextr_32, loadi32>;
2383 defm BEXTR64 : bmi_bextr_bzhi<0xF7, "bextr{q}", GR64, i64mem,
2384 int_x86_bmi_bextr_64, loadi64>, VEX_W;
2387 let Predicates = [HasBMI2], Defs = [EFLAGS] in {
2388 defm BZHI32 : bmi_bextr_bzhi<0xF5, "bzhi{l}", GR32, i32mem,
2389 int_x86_bmi_bzhi_32, loadi32>;
2390 defm BZHI64 : bmi_bextr_bzhi<0xF5, "bzhi{q}", GR64, i64mem,
2391 int_x86_bmi_bzhi_64, loadi64>, VEX_W;
2394 def CountTrailingOnes : SDNodeXForm<imm, [{
2395 // Count the trailing ones in the immediate.
2396 return getI8Imm(countTrailingOnes(N->getZExtValue()), SDLoc(N));
2399 def BEXTRMaskXForm : SDNodeXForm<imm, [{
2400 unsigned Length = countTrailingOnes(N->getZExtValue());
2401 return getI32Imm(Length << 8, SDLoc(N));
2404 def AndMask64 : ImmLeaf<i64, [{
2405 return isMask_64(Imm) && Imm > UINT32_MAX;
2408 // Use BEXTR for 64-bit 'and' with large immediate 'mask'.
2409 let Predicates = [HasBMI, NoBMI2, NoTBM] in {
2410 def : Pat<(and GR64:$src, AndMask64:$mask),
2411 (BEXTR64rr GR64:$src,
2412 (SUBREG_TO_REG (i64 0),
2413 (MOV32ri (BEXTRMaskXForm imm:$mask)), sub_32bit))>;
2414 def : Pat<(and (loadi64 addr:$src), AndMask64:$mask),
2415 (BEXTR64rm addr:$src,
2416 (SUBREG_TO_REG (i64 0),
2417 (MOV32ri (BEXTRMaskXForm imm:$mask)), sub_32bit))>;
2420 // Use BZHI for 64-bit 'and' with large immediate 'mask'.
2421 let Predicates = [HasBMI2, NoTBM] in {
2422 def : Pat<(and GR64:$src, AndMask64:$mask),
2423 (BZHI64rr GR64:$src,
2424 (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
2425 (MOV8ri (CountTrailingOnes imm:$mask)), sub_8bit))>;
2426 def : Pat<(and (loadi64 addr:$src), AndMask64:$mask),
2427 (BZHI64rm addr:$src,
2428 (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
2429 (MOV8ri (CountTrailingOnes imm:$mask)), sub_8bit))>;
2432 let Predicates = [HasBMI2] in {
2433 def : Pat<(and GR32:$src, (add (shl 1, GR8:$lz), -1)),
2434 (BZHI32rr GR32:$src,
2435 (INSERT_SUBREG (i32 (IMPLICIT_DEF)), GR8:$lz, sub_8bit))>;
2437 def : Pat<(and (loadi32 addr:$src), (add (shl 1, GR8:$lz), -1)),
2438 (BZHI32rm addr:$src,
2439 (INSERT_SUBREG (i32 (IMPLICIT_DEF)), GR8:$lz, sub_8bit))>;
2441 def : Pat<(and GR64:$src, (add (shl 1, GR8:$lz), -1)),
2442 (BZHI64rr GR64:$src,
2443 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR8:$lz, sub_8bit))>;
2445 def : Pat<(and (loadi64 addr:$src), (add (shl 1, GR8:$lz), -1)),
2446 (BZHI64rm addr:$src,
2447 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR8:$lz, sub_8bit))>;
2449 // x & (-1 >> (32 - y))
2450 def : Pat<(and GR32:$src, (srl -1, (i8 (trunc (sub 32, GR32:$lz))))),
2451 (BZHI32rr GR32:$src, GR32:$lz)>;
2452 def : Pat<(and (loadi32 addr:$src), (srl -1, (i8 (trunc (sub 32, GR32:$lz))))),
2453 (BZHI32rm addr:$src, GR32:$lz)>;
2455 // x & (-1 >> (64 - y))
2456 def : Pat<(and GR64:$src, (srl -1, (i8 (trunc (sub 64, GR32:$lz))))),
2457 (BZHI64rr GR64:$src,
2458 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR32:$lz, sub_32bit))>;
2459 def : Pat<(and (loadi64 addr:$src), (srl -1, (i8 (trunc (sub 64, GR32:$lz))))),
2460 (BZHI64rm addr:$src,
2461 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR32:$lz, sub_32bit))>;
2463 // x << (32 - y) >> (32 - y)
2464 def : Pat<(srl (shl GR32:$src, (i8 (trunc (sub 32, GR32:$lz)))),
2465 (i8 (trunc (sub 32, GR32:$lz)))),
2466 (BZHI32rr GR32:$src, GR32:$lz)>;
2467 def : Pat<(srl (shl (loadi32 addr:$src), (i8 (trunc (sub 32, GR32:$lz)))),
2468 (i8 (trunc (sub 32, GR32:$lz)))),
2469 (BZHI32rm addr:$src, GR32:$lz)>;
2471 // x << (64 - y) >> (64 - y)
2472 def : Pat<(srl (shl GR64:$src, (i8 (trunc (sub 64, GR32:$lz)))),
2473 (i8 (trunc (sub 64, GR32:$lz)))),
2474 (BZHI64rr GR64:$src,
2475 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR32:$lz, sub_32bit))>;
2476 def : Pat<(srl (shl (loadi64 addr:$src), (i8 (trunc (sub 64, GR32:$lz)))),
2477 (i8 (trunc (sub 64, GR32:$lz)))),
2478 (BZHI64rm addr:$src,
2479 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR32:$lz, sub_32bit))>;
2482 multiclass bmi_pdep_pext<string mnemonic, RegisterClass RC,
2483 X86MemOperand x86memop, Intrinsic Int,
2485 def rr : I<0xF5, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
2486 !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2487 [(set RC:$dst, (Int RC:$src1, RC:$src2))], IIC_BIN_NONMEM>,
2488 VEX_4V, Sched<[WriteALU]>;
2489 def rm : I<0xF5, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
2490 !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2491 [(set RC:$dst, (Int RC:$src1, (ld_frag addr:$src2)))],
2492 IIC_BIN_MEM>, VEX_4V, Sched<[WriteALULd, ReadAfterLd]>;
2495 let Predicates = [HasBMI2] in {
2496 defm PDEP32 : bmi_pdep_pext<"pdep{l}", GR32, i32mem,
2497 int_x86_bmi_pdep_32, loadi32>, T8XD;
2498 defm PDEP64 : bmi_pdep_pext<"pdep{q}", GR64, i64mem,
2499 int_x86_bmi_pdep_64, loadi64>, T8XD, VEX_W;
2500 defm PEXT32 : bmi_pdep_pext<"pext{l}", GR32, i32mem,
2501 int_x86_bmi_pext_32, loadi32>, T8XS;
2502 defm PEXT64 : bmi_pdep_pext<"pext{q}", GR64, i64mem,
2503 int_x86_bmi_pext_64, loadi64>, T8XS, VEX_W;
2506 //===----------------------------------------------------------------------===//
2509 let Predicates = [HasTBM], Defs = [EFLAGS] in {
2511 multiclass tbm_ternary_imm_intr<bits<8> opc, RegisterClass RC, string OpcodeStr,
2512 X86MemOperand x86memop, PatFrag ld_frag,
2513 Intrinsic Int, Operand immtype,
2514 SDPatternOperator immoperator> {
2515 def ri : Ii32<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, immtype:$cntl),
2516 !strconcat(OpcodeStr,
2517 "\t{$cntl, $src1, $dst|$dst, $src1, $cntl}"),
2518 [(set RC:$dst, (Int RC:$src1, immoperator:$cntl))],
2519 IIC_BIN_NONMEM>, XOP, XOPA, Sched<[WriteALU]>;
2520 def mi : Ii32<opc, MRMSrcMem, (outs RC:$dst),
2521 (ins x86memop:$src1, immtype:$cntl),
2522 !strconcat(OpcodeStr,
2523 "\t{$cntl, $src1, $dst|$dst, $src1, $cntl}"),
2524 [(set RC:$dst, (Int (ld_frag addr:$src1), immoperator:$cntl))],
2525 IIC_BIN_MEM>, XOP, XOPA, Sched<[WriteALULd, ReadAfterLd]>;
2528 defm BEXTRI32 : tbm_ternary_imm_intr<0x10, GR32, "bextr", i32mem, loadi32,
2529 int_x86_tbm_bextri_u32, i32imm, imm>;
2530 let ImmT = Imm32S in
2531 defm BEXTRI64 : tbm_ternary_imm_intr<0x10, GR64, "bextr", i64mem, loadi64,
2532 int_x86_tbm_bextri_u64, i64i32imm,
2533 i64immSExt32>, VEX_W;
2535 multiclass tbm_binary_rm<bits<8> opc, Format FormReg, Format FormMem,
2536 RegisterClass RC, string OpcodeStr,
2537 X86MemOperand x86memop, PatFrag ld_frag> {
2538 let hasSideEffects = 0 in {
2539 def rr : I<opc, FormReg, (outs RC:$dst), (ins RC:$src),
2540 !strconcat(OpcodeStr,"\t{$src, $dst|$dst, $src}"),
2541 [], IIC_BIN_NONMEM>, XOP_4V, XOP9, Sched<[WriteALU]>;
2543 def rm : I<opc, FormMem, (outs RC:$dst), (ins x86memop:$src),
2544 !strconcat(OpcodeStr,"\t{$src, $dst|$dst, $src}"),
2545 [], IIC_BIN_MEM>, XOP_4V, XOP9, Sched<[WriteALULd, ReadAfterLd]>;
2549 multiclass tbm_binary_intr<bits<8> opc, string OpcodeStr,
2550 Format FormReg, Format FormMem> {
2551 defm NAME#32 : tbm_binary_rm<opc, FormReg, FormMem, GR32, OpcodeStr, i32mem,
2553 defm NAME#64 : tbm_binary_rm<opc, FormReg, FormMem, GR64, OpcodeStr, i64mem,
2557 defm BLCFILL : tbm_binary_intr<0x01, "blcfill", MRM1r, MRM1m>;
2558 defm BLCI : tbm_binary_intr<0x02, "blci", MRM6r, MRM6m>;
2559 defm BLCIC : tbm_binary_intr<0x01, "blcic", MRM5r, MRM5m>;
2560 defm BLCMSK : tbm_binary_intr<0x02, "blcmsk", MRM1r, MRM1m>;
2561 defm BLCS : tbm_binary_intr<0x01, "blcs", MRM3r, MRM3m>;
2562 defm BLSFILL : tbm_binary_intr<0x01, "blsfill", MRM2r, MRM2m>;
2563 defm BLSIC : tbm_binary_intr<0x01, "blsic", MRM6r, MRM6m>;
2564 defm T1MSKC : tbm_binary_intr<0x01, "t1mskc", MRM7r, MRM7m>;
2565 defm TZMSK : tbm_binary_intr<0x01, "tzmsk", MRM4r, MRM4m>;
2568 // Use BEXTRI for 64-bit 'and' with large immediate 'mask'.
2569 let Predicates = [HasTBM] in {
2570 def : Pat<(and GR64:$src, AndMask64:$mask),
2571 (BEXTRI64ri GR64:$src, (BEXTRMaskXForm imm:$mask))>;
2573 def : Pat<(and (loadi64 addr:$src), AndMask64:$mask),
2574 (BEXTRI64mi addr:$src, (BEXTRMaskXForm imm:$mask))>;
2577 //===----------------------------------------------------------------------===//
2578 // Lightweight Profiling Instructions
2580 let Predicates = [HasLWP], SchedRW = [WriteSystem] in {
2582 def LLWPCB : I<0x12, MRM0r, (outs), (ins GR32:$src), "llwpcb\t$src",
2583 [(int_x86_llwpcb GR32:$src)], IIC_LWP>,
2585 def SLWPCB : I<0x12, MRM1r, (outs GR32:$dst), (ins), "slwpcb\t$dst",
2586 [(set GR32:$dst, (int_x86_slwpcb))], IIC_LWP>,
2589 def LLWPCB64 : I<0x12, MRM0r, (outs), (ins GR64:$src), "llwpcb\t$src",
2590 [(int_x86_llwpcb GR64:$src)], IIC_LWP>,
2592 def SLWPCB64 : I<0x12, MRM1r, (outs GR64:$dst), (ins), "slwpcb\t$dst",
2593 [(set GR64:$dst, (int_x86_slwpcb))], IIC_LWP>,
2596 multiclass lwpins_intr<RegisterClass RC> {
2597 def rri : Ii32<0x12, MRM0r, (outs), (ins RC:$src0, GR32:$src1, i32imm:$cntl),
2598 "lwpins\t{$cntl, $src1, $src0|$src0, $src1, $cntl}",
2599 [(set EFLAGS, (X86lwpins RC:$src0, GR32:$src1, imm:$cntl))], IIC_LWP>,
2602 def rmi : Ii32<0x12, MRM0m, (outs), (ins RC:$src0, i32mem:$src1, i32imm:$cntl),
2603 "lwpins\t{$cntl, $src1, $src0|$src0, $src1, $cntl}",
2604 [(set EFLAGS, (X86lwpins RC:$src0, (loadi32 addr:$src1), imm:$cntl))], IIC_LWP>,
2608 let Defs = [EFLAGS] in {
2609 defm LWPINS32 : lwpins_intr<GR32>;
2610 defm LWPINS64 : lwpins_intr<GR64>, VEX_W;
2613 multiclass lwpval_intr<RegisterClass RC, Intrinsic Int> {
2614 def rri : Ii32<0x12, MRM1r, (outs), (ins RC:$src0, GR32:$src1, i32imm:$cntl),
2615 "lwpval\t{$cntl, $src1, $src0|$src0, $src1, $cntl}",
2616 [(Int RC:$src0, GR32:$src1, imm:$cntl)], IIC_LWP>,
2619 def rmi : Ii32<0x12, MRM1m, (outs), (ins RC:$src0, i32mem:$src1, i32imm:$cntl),
2620 "lwpval\t{$cntl, $src1, $src0|$src0, $src1, $cntl}",
2621 [(Int RC:$src0, (loadi32 addr:$src1), imm:$cntl)], IIC_LWP>,
2625 defm LWPVAL32 : lwpval_intr<GR32, int_x86_lwpval32>;
2626 defm LWPVAL64 : lwpval_intr<GR64, int_x86_lwpval64>, VEX_W;
2628 } // HasLWP, SchedRW
2630 //===----------------------------------------------------------------------===//
2631 // MONITORX/MWAITX Instructions
2633 let SchedRW = [ WriteSystem ] in {
2634 let usesCustomInserter = 1 in {
2635 def MONITORX : PseudoI<(outs), (ins i32mem:$src1, GR32:$src2, GR32:$src3),
2636 [(int_x86_monitorx addr:$src1, GR32:$src2, GR32:$src3)]>,
2637 Requires<[ HasMWAITX ]>;
2640 let Uses = [ EAX, ECX, EDX ] in {
2641 def MONITORXrrr : I<0x01, MRM_FA, (outs), (ins), "monitorx", [], IIC_SSE_MONITORX>,
2642 TB, Requires<[ HasMWAITX ]>;
2645 let Uses = [ ECX, EAX, EBX ] in {
2646 def MWAITXrrr : I<0x01, MRM_FB, (outs), (ins), "mwaitx",
2647 [(int_x86_mwaitx ECX, EAX, EBX)], IIC_SSE_MWAITX>,
2648 TB, Requires<[ HasMWAITX ]>;
2652 def : InstAlias<"mwaitx\t{%eax, %ecx, %ebx|ebx, ecx, eax}", (MWAITXrrr)>,
2653 Requires<[ Not64BitMode ]>;
2654 def : InstAlias<"mwaitx\t{%rax, %rcx, %rbx|rbx, rcx, rax}", (MWAITXrrr)>,
2655 Requires<[ In64BitMode ]>;
2657 def : InstAlias<"monitorx\t{%eax, %ecx, %edx|edx, ecx, eax}", (MONITORXrrr)>,
2658 Requires<[ Not64BitMode ]>;
2659 def : InstAlias<"monitorx\t{%rax, %rcx, %rdx|rdx, rcx, rax}", (MONITORXrrr)>,
2660 Requires<[ In64BitMode ]>;
2662 //===----------------------------------------------------------------------===//
2663 // CLZERO Instruction
2665 let SchedRW = [WriteSystem] in {
2667 def CLZEROr : I<0x01, MRM_FC, (outs), (ins), "clzero", [], IIC_SSE_CLZERO>,
2668 TB, Requires<[HasCLZERO]>;
2670 let usesCustomInserter = 1 in {
2671 def CLZERO : PseudoI<(outs), (ins i32mem:$src1),
2672 [(int_x86_clzero addr:$src1)]>, Requires<[HasCLZERO]>;
2676 def : InstAlias<"clzero\t{%eax|eax}", (CLZEROr)>, Requires<[Not64BitMode]>;
2677 def : InstAlias<"clzero\t{%rax|rax}", (CLZEROr)>, Requires<[In64BitMode]>;
2679 //===----------------------------------------------------------------------===//
2680 // Pattern fragments to auto generate TBM instructions.
2681 //===----------------------------------------------------------------------===//
2683 let Predicates = [HasTBM] in {
2684 // FIXME: patterns for the load versions are not implemented
2685 def : Pat<(and GR32:$src, (add GR32:$src, 1)),
2686 (BLCFILL32rr GR32:$src)>;
2687 def : Pat<(and GR64:$src, (add GR64:$src, 1)),
2688 (BLCFILL64rr GR64:$src)>;
2690 def : Pat<(or GR32:$src, (not (add GR32:$src, 1))),
2691 (BLCI32rr GR32:$src)>;
2692 def : Pat<(or GR64:$src, (not (add GR64:$src, 1))),
2693 (BLCI64rr GR64:$src)>;
2695 // Extra patterns because opt can optimize the above patterns to this.
2696 def : Pat<(or GR32:$src, (sub -2, GR32:$src)),
2697 (BLCI32rr GR32:$src)>;
2698 def : Pat<(or GR64:$src, (sub -2, GR64:$src)),
2699 (BLCI64rr GR64:$src)>;
2701 def : Pat<(and (not GR32:$src), (add GR32:$src, 1)),
2702 (BLCIC32rr GR32:$src)>;
2703 def : Pat<(and (not GR64:$src), (add GR64:$src, 1)),
2704 (BLCIC64rr GR64:$src)>;
2706 def : Pat<(xor GR32:$src, (add GR32:$src, 1)),
2707 (BLCMSK32rr GR32:$src)>;
2708 def : Pat<(xor GR64:$src, (add GR64:$src, 1)),
2709 (BLCMSK64rr GR64:$src)>;
2711 def : Pat<(or GR32:$src, (add GR32:$src, 1)),
2712 (BLCS32rr GR32:$src)>;
2713 def : Pat<(or GR64:$src, (add GR64:$src, 1)),
2714 (BLCS64rr GR64:$src)>;
2716 def : Pat<(or GR32:$src, (add GR32:$src, -1)),
2717 (BLSFILL32rr GR32:$src)>;
2718 def : Pat<(or GR64:$src, (add GR64:$src, -1)),
2719 (BLSFILL64rr GR64:$src)>;
2721 def : Pat<(or (not GR32:$src), (add GR32:$src, -1)),
2722 (BLSIC32rr GR32:$src)>;
2723 def : Pat<(or (not GR64:$src), (add GR64:$src, -1)),
2724 (BLSIC64rr GR64:$src)>;
2726 def : Pat<(or (not GR32:$src), (add GR32:$src, 1)),
2727 (T1MSKC32rr GR32:$src)>;
2728 def : Pat<(or (not GR64:$src), (add GR64:$src, 1)),
2729 (T1MSKC64rr GR64:$src)>;
2731 def : Pat<(and (not GR32:$src), (add GR32:$src, -1)),
2732 (TZMSK32rr GR32:$src)>;
2733 def : Pat<(and (not GR64:$src), (add GR64:$src, -1)),
2734 (TZMSK64rr GR64:$src)>;
2737 //===----------------------------------------------------------------------===//
2738 // Memory Instructions
2741 let Predicates = [HasCLFLUSHOPT], SchedRW = [WriteLoad] in
2742 def CLFLUSHOPT : I<0xAE, MRM7m, (outs), (ins i8mem:$src),
2743 "clflushopt\t$src", [(int_x86_clflushopt addr:$src)],
2744 IIC_SSE_PREFETCH>, PD;
2746 let Predicates = [HasCLWB], SchedRW = [WriteLoad] in
2747 def CLWB : I<0xAE, MRM6m, (outs), (ins i8mem:$src), "clwb\t$src",
2748 [(int_x86_clwb addr:$src)], IIC_SSE_PREFETCH>, PD;
2750 //===----------------------------------------------------------------------===//
2752 //===----------------------------------------------------------------------===//
2754 include "X86InstrArithmetic.td"
2755 include "X86InstrCMovSetCC.td"
2756 include "X86InstrExtension.td"
2757 include "X86InstrControl.td"
2758 include "X86InstrShiftRotate.td"
2760 // X87 Floating Point Stack.
2761 include "X86InstrFPStack.td"
2763 // SIMD support (SSE, MMX and AVX)
2764 include "X86InstrFragmentsSIMD.td"
2766 // FMA - Fused Multiply-Add support (requires FMA)
2767 include "X86InstrFMA.td"
2770 include "X86InstrXOP.td"
2772 // SSE, MMX and 3DNow! vector support.
2773 include "X86InstrSSE.td"
2774 include "X86InstrAVX512.td"
2775 include "X86InstrMMX.td"
2776 include "X86Instr3DNow.td"
2779 include "X86InstrMPX.td"
2781 include "X86InstrVMX.td"
2782 include "X86InstrSVM.td"
2784 include "X86InstrTSX.td"
2785 include "X86InstrSGX.td"
2787 // System instructions.
2788 include "X86InstrSystem.td"
2790 // Compiler Pseudo Instructions and Pat Patterns
2791 include "X86InstrCompiler.td"
2792 include "X86InstrVecCompiler.td"
2794 //===----------------------------------------------------------------------===//
2795 // Assembler Mnemonic Aliases
2796 //===----------------------------------------------------------------------===//
2798 def : MnemonicAlias<"call", "callw", "att">, Requires<[In16BitMode]>;
2799 def : MnemonicAlias<"call", "calll", "att">, Requires<[In32BitMode]>;
2800 def : MnemonicAlias<"call", "callq", "att">, Requires<[In64BitMode]>;
2802 def : MnemonicAlias<"cbw", "cbtw", "att">;
2803 def : MnemonicAlias<"cwde", "cwtl", "att">;
2804 def : MnemonicAlias<"cwd", "cwtd", "att">;
2805 def : MnemonicAlias<"cdq", "cltd", "att">;
2806 def : MnemonicAlias<"cdqe", "cltq", "att">;
2807 def : MnemonicAlias<"cqo", "cqto", "att">;
2809 // In 64-bit mode lret maps to lretl; it is not ambiguous with lretq.
2810 def : MnemonicAlias<"lret", "lretw", "att">, Requires<[In16BitMode]>;
2811 def : MnemonicAlias<"lret", "lretl", "att">, Requires<[Not16BitMode]>;
2813 def : MnemonicAlias<"leavel", "leave", "att">, Requires<[Not64BitMode]>;
2814 def : MnemonicAlias<"leaveq", "leave", "att">, Requires<[In64BitMode]>;
2816 def : MnemonicAlias<"loopz", "loope">;
2817 def : MnemonicAlias<"loopnz", "loopne">;
2819 def : MnemonicAlias<"pop", "popw", "att">, Requires<[In16BitMode]>;
2820 def : MnemonicAlias<"pop", "popl", "att">, Requires<[In32BitMode]>;
2821 def : MnemonicAlias<"pop", "popq", "att">, Requires<[In64BitMode]>;
2822 def : MnemonicAlias<"popf", "popfw", "att">, Requires<[In16BitMode]>;
2823 def : MnemonicAlias<"popf", "popfl", "att">, Requires<[In32BitMode]>;
2824 def : MnemonicAlias<"popf", "popfq", "att">, Requires<[In64BitMode]>;
2825 def : MnemonicAlias<"popf", "popfq", "intel">, Requires<[In64BitMode]>;
2826 def : MnemonicAlias<"popfd", "popfl", "att">;
2828 // FIXME: This is wrong for "push reg". "push %bx" should turn into pushw in
2829 // all modes. However: "push (addr)" and "push $42" should default to
2830 // pushl/pushq depending on the current mode. Similar for "pop %bx"
2831 def : MnemonicAlias<"push", "pushw", "att">, Requires<[In16BitMode]>;
2832 def : MnemonicAlias<"push", "pushl", "att">, Requires<[In32BitMode]>;
2833 def : MnemonicAlias<"push", "pushq", "att">, Requires<[In64BitMode]>;
2834 def : MnemonicAlias<"pushf", "pushfw", "att">, Requires<[In16BitMode]>;
2835 def : MnemonicAlias<"pushf", "pushfl", "att">, Requires<[In32BitMode]>;
2836 def : MnemonicAlias<"pushf", "pushfq", "att">, Requires<[In64BitMode]>;
2837 def : MnemonicAlias<"pushf", "pushfq", "intel">, Requires<[In64BitMode]>;
2838 def : MnemonicAlias<"pushfd", "pushfl", "att">;
2840 def : MnemonicAlias<"popad", "popal", "intel">, Requires<[Not64BitMode]>;
2841 def : MnemonicAlias<"pushad", "pushal", "intel">, Requires<[Not64BitMode]>;
2842 def : MnemonicAlias<"popa", "popaw", "intel">, Requires<[In16BitMode]>;
2843 def : MnemonicAlias<"pusha", "pushaw", "intel">, Requires<[In16BitMode]>;
2844 def : MnemonicAlias<"popa", "popal", "intel">, Requires<[In32BitMode]>;
2845 def : MnemonicAlias<"pusha", "pushal", "intel">, Requires<[In32BitMode]>;
2847 def : MnemonicAlias<"popa", "popaw", "att">, Requires<[In16BitMode]>;
2848 def : MnemonicAlias<"pusha", "pushaw", "att">, Requires<[In16BitMode]>;
2849 def : MnemonicAlias<"popa", "popal", "att">, Requires<[In32BitMode]>;
2850 def : MnemonicAlias<"pusha", "pushal", "att">, Requires<[In32BitMode]>;
2852 def : MnemonicAlias<"repe", "rep">;
2853 def : MnemonicAlias<"repz", "rep">;
2854 def : MnemonicAlias<"repnz", "repne">;
2856 def : MnemonicAlias<"ret", "retw", "att">, Requires<[In16BitMode]>;
2857 def : MnemonicAlias<"ret", "retl", "att">, Requires<[In32BitMode]>;
2858 def : MnemonicAlias<"ret", "retq", "att">, Requires<[In64BitMode]>;
2860 // Apply 'ret' behavior to 'retn'
2861 def : MnemonicAlias<"retn", "retw", "att">, Requires<[In16BitMode]>;
2862 def : MnemonicAlias<"retn", "retl", "att">, Requires<[In32BitMode]>;
2863 def : MnemonicAlias<"retn", "retq", "att">, Requires<[In64BitMode]>;
2864 def : MnemonicAlias<"retn", "ret", "intel">;
2866 def : MnemonicAlias<"sal", "shl", "intel">;
2867 def : MnemonicAlias<"salb", "shlb", "att">;
2868 def : MnemonicAlias<"salw", "shlw", "att">;
2869 def : MnemonicAlias<"sall", "shll", "att">;
2870 def : MnemonicAlias<"salq", "shlq", "att">;
2872 def : MnemonicAlias<"smovb", "movsb", "att">;
2873 def : MnemonicAlias<"smovw", "movsw", "att">;
2874 def : MnemonicAlias<"smovl", "movsl", "att">;
2875 def : MnemonicAlias<"smovq", "movsq", "att">;
2877 def : MnemonicAlias<"ud2a", "ud2", "att">;
2878 def : MnemonicAlias<"verrw", "verr", "att">;
2880 // MS recognizes 'xacquire'/'xrelease' as 'acquire'/'release'
2881 def : MnemonicAlias<"acquire", "xacquire", "intel">;
2882 def : MnemonicAlias<"release", "xrelease", "intel">;
2884 // System instruction aliases.
2885 def : MnemonicAlias<"iret", "iretw", "att">, Requires<[In16BitMode]>;
2886 def : MnemonicAlias<"iret", "iretl", "att">, Requires<[Not16BitMode]>;
2887 def : MnemonicAlias<"sysret", "sysretl", "att">;
2888 def : MnemonicAlias<"sysexit", "sysexitl", "att">;
2890 def : MnemonicAlias<"lgdt", "lgdtw", "att">, Requires<[In16BitMode]>;
2891 def : MnemonicAlias<"lgdt", "lgdtl", "att">, Requires<[In32BitMode]>;
2892 def : MnemonicAlias<"lgdt", "lgdtq", "att">, Requires<[In64BitMode]>;
2893 def : MnemonicAlias<"lidt", "lidtw", "att">, Requires<[In16BitMode]>;
2894 def : MnemonicAlias<"lidt", "lidtl", "att">, Requires<[In32BitMode]>;
2895 def : MnemonicAlias<"lidt", "lidtq", "att">, Requires<[In64BitMode]>;
2896 def : MnemonicAlias<"sgdt", "sgdtw", "att">, Requires<[In16BitMode]>;
2897 def : MnemonicAlias<"sgdt", "sgdtl", "att">, Requires<[In32BitMode]>;
2898 def : MnemonicAlias<"sgdt", "sgdtq", "att">, Requires<[In64BitMode]>;
2899 def : MnemonicAlias<"sidt", "sidtw", "att">, Requires<[In16BitMode]>;
2900 def : MnemonicAlias<"sidt", "sidtl", "att">, Requires<[In32BitMode]>;
2901 def : MnemonicAlias<"sidt", "sidtq", "att">, Requires<[In64BitMode]>;
2904 // Floating point stack aliases.
2905 def : MnemonicAlias<"fcmovz", "fcmove", "att">;
2906 def : MnemonicAlias<"fcmova", "fcmovnbe", "att">;
2907 def : MnemonicAlias<"fcmovnae", "fcmovb", "att">;
2908 def : MnemonicAlias<"fcmovna", "fcmovbe", "att">;
2909 def : MnemonicAlias<"fcmovae", "fcmovnb", "att">;
2910 def : MnemonicAlias<"fcomip", "fcompi">;
2911 def : MnemonicAlias<"fildq", "fildll", "att">;
2912 def : MnemonicAlias<"fistpq", "fistpll", "att">;
2913 def : MnemonicAlias<"fisttpq", "fisttpll", "att">;
2914 def : MnemonicAlias<"fldcww", "fldcw", "att">;
2915 def : MnemonicAlias<"fnstcww", "fnstcw", "att">;
2916 def : MnemonicAlias<"fnstsww", "fnstsw", "att">;
2917 def : MnemonicAlias<"fucomip", "fucompi">;
2918 def : MnemonicAlias<"fwait", "wait">;
2920 def : MnemonicAlias<"fxsaveq", "fxsave64", "att">;
2921 def : MnemonicAlias<"fxrstorq", "fxrstor64", "att">;
2922 def : MnemonicAlias<"xsaveq", "xsave64", "att">;
2923 def : MnemonicAlias<"xrstorq", "xrstor64", "att">;
2924 def : MnemonicAlias<"xsaveoptq", "xsaveopt64", "att">;
2925 def : MnemonicAlias<"xrstorsq", "xrstors64", "att">;
2926 def : MnemonicAlias<"xsavecq", "xsavec64", "att">;
2927 def : MnemonicAlias<"xsavesq", "xsaves64", "att">;
2929 class CondCodeAlias<string Prefix,string Suffix, string OldCond, string NewCond,
2931 : MnemonicAlias<!strconcat(Prefix, OldCond, Suffix),
2932 !strconcat(Prefix, NewCond, Suffix), VariantName>;
2934 /// IntegerCondCodeMnemonicAlias - This multiclass defines a bunch of
2935 /// MnemonicAlias's that canonicalize the condition code in a mnemonic, for
2936 /// example "setz" -> "sete".
2937 multiclass IntegerCondCodeMnemonicAlias<string Prefix, string Suffix,
2939 def C : CondCodeAlias<Prefix, Suffix, "c", "b", V>; // setc -> setb
2940 def Z : CondCodeAlias<Prefix, Suffix, "z" , "e", V>; // setz -> sete
2941 def NA : CondCodeAlias<Prefix, Suffix, "na", "be", V>; // setna -> setbe
2942 def NB : CondCodeAlias<Prefix, Suffix, "nb", "ae", V>; // setnb -> setae
2943 def NC : CondCodeAlias<Prefix, Suffix, "nc", "ae", V>; // setnc -> setae
2944 def NG : CondCodeAlias<Prefix, Suffix, "ng", "le", V>; // setng -> setle
2945 def NL : CondCodeAlias<Prefix, Suffix, "nl", "ge", V>; // setnl -> setge
2946 def NZ : CondCodeAlias<Prefix, Suffix, "nz", "ne", V>; // setnz -> setne
2947 def PE : CondCodeAlias<Prefix, Suffix, "pe", "p", V>; // setpe -> setp
2948 def PO : CondCodeAlias<Prefix, Suffix, "po", "np", V>; // setpo -> setnp
2950 def NAE : CondCodeAlias<Prefix, Suffix, "nae", "b", V>; // setnae -> setb
2951 def NBE : CondCodeAlias<Prefix, Suffix, "nbe", "a", V>; // setnbe -> seta
2952 def NGE : CondCodeAlias<Prefix, Suffix, "nge", "l", V>; // setnge -> setl
2953 def NLE : CondCodeAlias<Prefix, Suffix, "nle", "g", V>; // setnle -> setg
2956 // Aliases for set<CC>
2957 defm : IntegerCondCodeMnemonicAlias<"set", "">;
2958 // Aliases for j<CC>
2959 defm : IntegerCondCodeMnemonicAlias<"j", "">;
2960 // Aliases for cmov<CC>{w,l,q}
2961 defm : IntegerCondCodeMnemonicAlias<"cmov", "w", "att">;
2962 defm : IntegerCondCodeMnemonicAlias<"cmov", "l", "att">;
2963 defm : IntegerCondCodeMnemonicAlias<"cmov", "q", "att">;
2964 // No size suffix for intel-style asm.
2965 defm : IntegerCondCodeMnemonicAlias<"cmov", "", "intel">;
2968 //===----------------------------------------------------------------------===//
2969 // Assembler Instruction Aliases
2970 //===----------------------------------------------------------------------===//
2972 // aad/aam default to base 10 if no operand is specified.
2973 def : InstAlias<"aad", (AAD8i8 10)>, Requires<[Not64BitMode]>;
2974 def : InstAlias<"aam", (AAM8i8 10)>, Requires<[Not64BitMode]>;
2976 // Disambiguate the mem/imm form of bt-without-a-suffix as btl.
2977 // Likewise for btc/btr/bts.
2978 def : InstAlias<"bt\t{$imm, $mem|$mem, $imm}",
2979 (BT32mi8 i32mem:$mem, i32i8imm:$imm), 0>;
2980 def : InstAlias<"btc\t{$imm, $mem|$mem, $imm}",
2981 (BTC32mi8 i32mem:$mem, i32i8imm:$imm), 0>;
2982 def : InstAlias<"btr\t{$imm, $mem|$mem, $imm}",
2983 (BTR32mi8 i32mem:$mem, i32i8imm:$imm), 0>;
2984 def : InstAlias<"bts\t{$imm, $mem|$mem, $imm}",
2985 (BTS32mi8 i32mem:$mem, i32i8imm:$imm), 0>;
2988 def : InstAlias<"clrb\t$reg", (XOR8rr GR8 :$reg, GR8 :$reg), 0>;
2989 def : InstAlias<"clrw\t$reg", (XOR16rr GR16:$reg, GR16:$reg), 0>;
2990 def : InstAlias<"clrl\t$reg", (XOR32rr GR32:$reg, GR32:$reg), 0>;
2991 def : InstAlias<"clrq\t$reg", (XOR64rr GR64:$reg, GR64:$reg), 0>;
2993 // lods aliases. Accept the destination being omitted because it's implicit
2994 // in the mnemonic, or the mnemonic suffix being omitted because it's implicit
2995 // in the destination.
2996 def : InstAlias<"lodsb\t$src", (LODSB srcidx8:$src), 0>;
2997 def : InstAlias<"lodsw\t$src", (LODSW srcidx16:$src), 0>;
2998 def : InstAlias<"lods{l|d}\t$src", (LODSL srcidx32:$src), 0>;
2999 def : InstAlias<"lodsq\t$src", (LODSQ srcidx64:$src), 0>, Requires<[In64BitMode]>;
3000 def : InstAlias<"lods\t{$src, %al|al, $src}", (LODSB srcidx8:$src), 0>;
3001 def : InstAlias<"lods\t{$src, %ax|ax, $src}", (LODSW srcidx16:$src), 0>;
3002 def : InstAlias<"lods\t{$src, %eax|eax, $src}", (LODSL srcidx32:$src), 0>;
3003 def : InstAlias<"lods\t{$src, %rax|rax, $src}", (LODSQ srcidx64:$src), 0>, Requires<[In64BitMode]>;
3004 def : InstAlias<"lods\t$src", (LODSB srcidx8:$src), 0>;
3005 def : InstAlias<"lods\t$src", (LODSW srcidx16:$src), 0>;
3006 def : InstAlias<"lods\t$src", (LODSL srcidx32:$src), 0>;
3007 def : InstAlias<"lods\t$src", (LODSQ srcidx64:$src), 0>, Requires<[In64BitMode]>;
3010 // stos aliases. Accept the source being omitted because it's implicit in
3011 // the mnemonic, or the mnemonic suffix being omitted because it's implicit
3013 def : InstAlias<"stosb\t$dst", (STOSB dstidx8:$dst), 0>;
3014 def : InstAlias<"stosw\t$dst", (STOSW dstidx16:$dst), 0>;
3015 def : InstAlias<"stos{l|d}\t$dst", (STOSL dstidx32:$dst), 0>;
3016 def : InstAlias<"stosq\t$dst", (STOSQ dstidx64:$dst), 0>, Requires<[In64BitMode]>;
3017 def : InstAlias<"stos\t{%al, $dst|$dst, al}", (STOSB dstidx8:$dst), 0>;
3018 def : InstAlias<"stos\t{%ax, $dst|$dst, ax}", (STOSW dstidx16:$dst), 0>;
3019 def : InstAlias<"stos\t{%eax, $dst|$dst, eax}", (STOSL dstidx32:$dst), 0>;
3020 def : InstAlias<"stos\t{%rax, $dst|$dst, rax}", (STOSQ dstidx64:$dst), 0>, Requires<[In64BitMode]>;
3021 def : InstAlias<"stos\t$dst", (STOSB dstidx8:$dst), 0>;
3022 def : InstAlias<"stos\t$dst", (STOSW dstidx16:$dst), 0>;
3023 def : InstAlias<"stos\t$dst", (STOSL dstidx32:$dst), 0>;
3024 def : InstAlias<"stos\t$dst", (STOSQ dstidx64:$dst), 0>, Requires<[In64BitMode]>;
3027 // scas aliases. Accept the destination being omitted because it's implicit
3028 // in the mnemonic, or the mnemonic suffix being omitted because it's implicit
3029 // in the destination.
3030 def : InstAlias<"scasb\t$dst", (SCASB dstidx8:$dst), 0>;
3031 def : InstAlias<"scasw\t$dst", (SCASW dstidx16:$dst), 0>;
3032 def : InstAlias<"scas{l|d}\t$dst", (SCASL dstidx32:$dst), 0>;
3033 def : InstAlias<"scasq\t$dst", (SCASQ dstidx64:$dst), 0>, Requires<[In64BitMode]>;
3034 def : InstAlias<"scas\t{$dst, %al|al, $dst}", (SCASB dstidx8:$dst), 0>;
3035 def : InstAlias<"scas\t{$dst, %ax|ax, $dst}", (SCASW dstidx16:$dst), 0>;
3036 def : InstAlias<"scas\t{$dst, %eax|eax, $dst}", (SCASL dstidx32:$dst), 0>;
3037 def : InstAlias<"scas\t{$dst, %rax|rax, $dst}", (SCASQ dstidx64:$dst), 0>, Requires<[In64BitMode]>;
3038 def : InstAlias<"scas\t$dst", (SCASB dstidx8:$dst), 0>;
3039 def : InstAlias<"scas\t$dst", (SCASW dstidx16:$dst), 0>;
3040 def : InstAlias<"scas\t$dst", (SCASL dstidx32:$dst), 0>;
3041 def : InstAlias<"scas\t$dst", (SCASQ dstidx64:$dst), 0>, Requires<[In64BitMode]>;
3043 // cmps aliases. Mnemonic suffix being omitted because it's implicit
3044 // in the destination.
3045 def : InstAlias<"cmps\t{$dst, $src|$src, $dst}", (CMPSB dstidx8:$dst, srcidx8:$src), 0>;
3046 def : InstAlias<"cmps\t{$dst, $src|$src, $dst}", (CMPSW dstidx16:$dst, srcidx16:$src), 0>;
3047 def : InstAlias<"cmps\t{$dst, $src|$src, $dst}", (CMPSL dstidx32:$dst, srcidx32:$src), 0>;
3048 def : InstAlias<"cmps\t{$dst, $src|$src, $dst}", (CMPSQ dstidx64:$dst, srcidx64:$src), 0>, Requires<[In64BitMode]>;
3050 // movs aliases. Mnemonic suffix being omitted because it's implicit
3051 // in the destination.
3052 def : InstAlias<"movs\t{$src, $dst|$dst, $src}", (MOVSB dstidx8:$dst, srcidx8:$src), 0>;
3053 def : InstAlias<"movs\t{$src, $dst|$dst, $src}", (MOVSW dstidx16:$dst, srcidx16:$src), 0>;
3054 def : InstAlias<"movs\t{$src, $dst|$dst, $src}", (MOVSL dstidx32:$dst, srcidx32:$src), 0>;
3055 def : InstAlias<"movs\t{$src, $dst|$dst, $src}", (MOVSQ dstidx64:$dst, srcidx64:$src), 0>, Requires<[In64BitMode]>;
3057 // div and idiv aliases for explicit A register.
3058 def : InstAlias<"div{b}\t{$src, %al|al, $src}", (DIV8r GR8 :$src)>;
3059 def : InstAlias<"div{w}\t{$src, %ax|ax, $src}", (DIV16r GR16:$src)>;
3060 def : InstAlias<"div{l}\t{$src, %eax|eax, $src}", (DIV32r GR32:$src)>;
3061 def : InstAlias<"div{q}\t{$src, %rax|rax, $src}", (DIV64r GR64:$src)>;
3062 def : InstAlias<"div{b}\t{$src, %al|al, $src}", (DIV8m i8mem :$src)>;
3063 def : InstAlias<"div{w}\t{$src, %ax|ax, $src}", (DIV16m i16mem:$src)>;
3064 def : InstAlias<"div{l}\t{$src, %eax|eax, $src}", (DIV32m i32mem:$src)>;
3065 def : InstAlias<"div{q}\t{$src, %rax|rax, $src}", (DIV64m i64mem:$src)>;
3066 def : InstAlias<"idiv{b}\t{$src, %al|al, $src}", (IDIV8r GR8 :$src)>;
3067 def : InstAlias<"idiv{w}\t{$src, %ax|ax, $src}", (IDIV16r GR16:$src)>;
3068 def : InstAlias<"idiv{l}\t{$src, %eax|eax, $src}", (IDIV32r GR32:$src)>;
3069 def : InstAlias<"idiv{q}\t{$src, %rax|rax, $src}", (IDIV64r GR64:$src)>;
3070 def : InstAlias<"idiv{b}\t{$src, %al|al, $src}", (IDIV8m i8mem :$src)>;
3071 def : InstAlias<"idiv{w}\t{$src, %ax|ax, $src}", (IDIV16m i16mem:$src)>;
3072 def : InstAlias<"idiv{l}\t{$src, %eax|eax, $src}", (IDIV32m i32mem:$src)>;
3073 def : InstAlias<"idiv{q}\t{$src, %rax|rax, $src}", (IDIV64m i64mem:$src)>;
3077 // Various unary fpstack operations default to operating on on ST1.
3078 // For example, "fxch" -> "fxch %st(1)"
3079 def : InstAlias<"faddp", (ADD_FPrST0 ST1), 0>;
3080 def: InstAlias<"fadd", (ADD_FPrST0 ST1), 0>;
3081 def : InstAlias<"fsub{|r}p", (SUBR_FPrST0 ST1), 0>;
3082 def : InstAlias<"fsub{r|}p", (SUB_FPrST0 ST1), 0>;
3083 def : InstAlias<"fmul", (MUL_FPrST0 ST1), 0>;
3084 def : InstAlias<"fmulp", (MUL_FPrST0 ST1), 0>;
3085 def : InstAlias<"fdiv{|r}p", (DIVR_FPrST0 ST1), 0>;
3086 def : InstAlias<"fdiv{r|}p", (DIV_FPrST0 ST1), 0>;
3087 def : InstAlias<"fxch", (XCH_F ST1), 0>;
3088 def : InstAlias<"fcom", (COM_FST0r ST1), 0>;
3089 def : InstAlias<"fcomp", (COMP_FST0r ST1), 0>;
3090 def : InstAlias<"fcomi", (COM_FIr ST1), 0>;
3091 def : InstAlias<"fcompi", (COM_FIPr ST1), 0>;
3092 def : InstAlias<"fucom", (UCOM_Fr ST1), 0>;
3093 def : InstAlias<"fucomp", (UCOM_FPr ST1), 0>;
3094 def : InstAlias<"fucomi", (UCOM_FIr ST1), 0>;
3095 def : InstAlias<"fucompi", (UCOM_FIPr ST1), 0>;
3097 // Handle fmul/fadd/fsub/fdiv instructions with explicitly written st(0) op.
3098 // For example, "fadd %st(4), %st(0)" -> "fadd %st(4)". We also disambiguate
3099 // instructions like "fadd %st(0), %st(0)" as "fadd %st(0)" for consistency with
3101 multiclass FpUnaryAlias<string Mnemonic, Instruction Inst, bit EmitAlias = 1> {
3102 def : InstAlias<!strconcat(Mnemonic, "\t{$op, %st(0)|st(0), $op}"),
3103 (Inst RST:$op), EmitAlias>;
3104 def : InstAlias<!strconcat(Mnemonic, "\t{%st(0), %st(0)|st(0), st(0)}"),
3105 (Inst ST0), EmitAlias>;
3108 defm : FpUnaryAlias<"fadd", ADD_FST0r>;
3109 defm : FpUnaryAlias<"faddp", ADD_FPrST0, 0>;
3110 defm : FpUnaryAlias<"fsub", SUB_FST0r>;
3111 defm : FpUnaryAlias<"fsub{|r}p", SUBR_FPrST0>;
3112 defm : FpUnaryAlias<"fsubr", SUBR_FST0r>;
3113 defm : FpUnaryAlias<"fsub{r|}p", SUB_FPrST0>;
3114 defm : FpUnaryAlias<"fmul", MUL_FST0r>;
3115 defm : FpUnaryAlias<"fmulp", MUL_FPrST0>;
3116 defm : FpUnaryAlias<"fdiv", DIV_FST0r>;
3117 defm : FpUnaryAlias<"fdiv{|r}p", DIVR_FPrST0>;
3118 defm : FpUnaryAlias<"fdivr", DIVR_FST0r>;
3119 defm : FpUnaryAlias<"fdiv{r|}p", DIV_FPrST0>;
3120 defm : FpUnaryAlias<"fcomi", COM_FIr, 0>;
3121 defm : FpUnaryAlias<"fucomi", UCOM_FIr, 0>;
3122 defm : FpUnaryAlias<"fcompi", COM_FIPr>;
3123 defm : FpUnaryAlias<"fucompi", UCOM_FIPr>;
3126 // Handle "f{mulp,addp} st(0), $op" the same as "f{mulp,addp} $op", since they
3127 // commute. We also allow fdiv[r]p/fsubrp even though they don't commute,
3128 // solely because gas supports it.
3129 def : InstAlias<"faddp\t{%st(0), $op|$op, st(0)}", (ADD_FPrST0 RST:$op), 0>;
3130 def : InstAlias<"fmulp\t{%st(0), $op|$op, st(0)}", (MUL_FPrST0 RST:$op)>;
3131 def : InstAlias<"fsub{|r}p\t{%st(0), $op|$op, st(0)}", (SUBR_FPrST0 RST:$op)>;
3132 def : InstAlias<"fsub{r|}p\t{%st(0), $op|$op, st(0)}", (SUB_FPrST0 RST:$op)>;
3133 def : InstAlias<"fdiv{|r}p\t{%st(0), $op|$op, st(0)}", (DIVR_FPrST0 RST:$op)>;
3134 def : InstAlias<"fdiv{r|}p\t{%st(0), $op|$op, st(0)}", (DIV_FPrST0 RST:$op)>;
3136 // We accept "fnstsw %eax" even though it only writes %ax.
3137 def : InstAlias<"fnstsw\t{%eax|eax}", (FNSTSW16r)>;
3138 def : InstAlias<"fnstsw\t{%al|al}" , (FNSTSW16r)>;
3139 def : InstAlias<"fnstsw" , (FNSTSW16r)>;
3141 // lcall and ljmp aliases. This seems to be an odd mapping in 64-bit mode, but
3142 // this is compatible with what GAS does.
3143 def : InstAlias<"lcall\t$seg, $off", (FARCALL32i i32imm:$off, i16imm:$seg), 0>, Requires<[In32BitMode]>;
3144 def : InstAlias<"ljmp\t$seg, $off", (FARJMP32i i32imm:$off, i16imm:$seg), 0>, Requires<[In32BitMode]>;
3145 def : InstAlias<"lcall\t{*}$dst", (FARCALL32m opaque48mem:$dst), 0>, Requires<[Not16BitMode]>;
3146 def : InstAlias<"ljmp\t{*}$dst", (FARJMP32m opaque48mem:$dst), 0>, Requires<[Not16BitMode]>;
3147 def : InstAlias<"lcall\t$seg, $off", (FARCALL16i i16imm:$off, i16imm:$seg), 0>, Requires<[In16BitMode]>;
3148 def : InstAlias<"ljmp\t$seg, $off", (FARJMP16i i16imm:$off, i16imm:$seg), 0>, Requires<[In16BitMode]>;
3149 def : InstAlias<"lcall\t{*}$dst", (FARCALL16m opaque32mem:$dst), 0>, Requires<[In16BitMode]>;
3150 def : InstAlias<"ljmp\t{*}$dst", (FARJMP16m opaque32mem:$dst), 0>, Requires<[In16BitMode]>;
3152 def : InstAlias<"call\t{*}$dst", (CALL64m i64mem:$dst), 0>, Requires<[In64BitMode]>;
3153 def : InstAlias<"jmp\t{*}$dst", (JMP64m i64mem:$dst), 0>, Requires<[In64BitMode]>;
3154 def : InstAlias<"call\t{*}$dst", (CALL32m i32mem:$dst), 0>, Requires<[In32BitMode]>;
3155 def : InstAlias<"jmp\t{*}$dst", (JMP32m i32mem:$dst), 0>, Requires<[In32BitMode]>;
3156 def : InstAlias<"call\t{*}$dst", (CALL16m i16mem:$dst), 0>, Requires<[In16BitMode]>;
3157 def : InstAlias<"jmp\t{*}$dst", (JMP16m i16mem:$dst), 0>, Requires<[In16BitMode]>;
3160 // "imul <imm>, B" is an alias for "imul <imm>, B, B".
3161 def : InstAlias<"imul{w}\t{$imm, $r|$r, $imm}", (IMUL16rri GR16:$r, GR16:$r, i16imm:$imm), 0>;
3162 def : InstAlias<"imul{w}\t{$imm, $r|$r, $imm}", (IMUL16rri8 GR16:$r, GR16:$r, i16i8imm:$imm), 0>;
3163 def : InstAlias<"imul{l}\t{$imm, $r|$r, $imm}", (IMUL32rri GR32:$r, GR32:$r, i32imm:$imm), 0>;
3164 def : InstAlias<"imul{l}\t{$imm, $r|$r, $imm}", (IMUL32rri8 GR32:$r, GR32:$r, i32i8imm:$imm), 0>;
3165 def : InstAlias<"imul{q}\t{$imm, $r|$r, $imm}", (IMUL64rri32 GR64:$r, GR64:$r, i64i32imm:$imm), 0>;
3166 def : InstAlias<"imul{q}\t{$imm, $r|$r, $imm}", (IMUL64rri8 GR64:$r, GR64:$r, i64i8imm:$imm), 0>;
3168 // ins aliases. Accept the mnemonic suffix being omitted because it's implicit
3169 // in the destination.
3170 def : InstAlias<"ins\t{%dx, $dst|$dst, dx}", (INSB dstidx8:$dst), 0>;
3171 def : InstAlias<"ins\t{%dx, $dst|$dst, dx}", (INSW dstidx16:$dst), 0>;
3172 def : InstAlias<"ins\t{%dx, $dst|$dst, dx}", (INSL dstidx32:$dst), 0>;
3174 // outs aliases. Accept the mnemonic suffix being omitted because it's implicit
3176 def : InstAlias<"outs\t{$src, %dx|dx, $src}", (OUTSB srcidx8:$src), 0>;
3177 def : InstAlias<"outs\t{$src, %dx|dx, $src}", (OUTSW srcidx16:$src), 0>;
3178 def : InstAlias<"outs\t{$src, %dx|dx, $src}", (OUTSL srcidx32:$src), 0>;
3180 // inb %dx -> inb %al, %dx
3181 def : InstAlias<"inb\t{%dx|dx}", (IN8rr), 0>;
3182 def : InstAlias<"inw\t{%dx|dx}", (IN16rr), 0>;
3183 def : InstAlias<"inl\t{%dx|dx}", (IN32rr), 0>;
3184 def : InstAlias<"inb\t$port", (IN8ri u8imm:$port), 0>;
3185 def : InstAlias<"inw\t$port", (IN16ri u8imm:$port), 0>;
3186 def : InstAlias<"inl\t$port", (IN32ri u8imm:$port), 0>;
3189 // jmp and call aliases for lcall and ljmp. jmp $42,$5 -> ljmp
3190 def : InstAlias<"call\t$seg, $off", (FARCALL16i i16imm:$off, i16imm:$seg)>, Requires<[In16BitMode]>;
3191 def : InstAlias<"jmp\t$seg, $off", (FARJMP16i i16imm:$off, i16imm:$seg)>, Requires<[In16BitMode]>;
3192 def : InstAlias<"call\t$seg, $off", (FARCALL32i i32imm:$off, i16imm:$seg)>, Requires<[In32BitMode]>;
3193 def : InstAlias<"jmp\t$seg, $off", (FARJMP32i i32imm:$off, i16imm:$seg)>, Requires<[In32BitMode]>;
3194 def : InstAlias<"callw\t$seg, $off", (FARCALL16i i16imm:$off, i16imm:$seg)>, Requires<[Not64BitMode]>;
3195 def : InstAlias<"jmpw\t$seg, $off", (FARJMP16i i16imm:$off, i16imm:$seg)>, Requires<[Not64BitMode]>;
3196 def : InstAlias<"calll\t$seg, $off", (FARCALL32i i32imm:$off, i16imm:$seg)>, Requires<[Not64BitMode]>;
3197 def : InstAlias<"jmpl\t$seg, $off", (FARJMP32i i32imm:$off, i16imm:$seg)>, Requires<[Not64BitMode]>;
3199 // Force mov without a suffix with a segment and mem to prefer the 'l' form of
3200 // the move. All segment/mem forms are equivalent, this has the shortest
3202 def : InstAlias<"mov\t{$mem, $seg|$seg, $mem}", (MOV16sm SEGMENT_REG:$seg, i16mem:$mem), 0>;
3203 def : InstAlias<"mov\t{$seg, $mem|$mem, $seg}", (MOV16ms i16mem:$mem, SEGMENT_REG:$seg), 0>;
3205 // Match 'movq <largeimm>, <reg>' as an alias for movabsq.
3206 def : InstAlias<"mov{q}\t{$imm, $reg|$reg, $imm}", (MOV64ri GR64:$reg, i64imm:$imm), 0>;
3208 // Match 'movq GR64, MMX' as an alias for movd.
3209 def : InstAlias<"movq\t{$src, $dst|$dst, $src}",
3210 (MMX_MOVD64to64rr VR64:$dst, GR64:$src), 0>;
3211 def : InstAlias<"movq\t{$src, $dst|$dst, $src}",
3212 (MMX_MOVD64from64rr GR64:$dst, VR64:$src), 0>;
3215 def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX16rr8 GR16:$dst, GR8:$src), 0>;
3216 def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX16rm8 GR16:$dst, i8mem:$src), 0>;
3217 def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX32rr8 GR32:$dst, GR8:$src), 0>;
3218 def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX32rr16 GR32:$dst, GR16:$src), 0>;
3219 def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX64rr8 GR64:$dst, GR8:$src), 0>;
3220 def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX64rr16 GR64:$dst, GR16:$src), 0>;
3221 def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX64rr32 GR64:$dst, GR32:$src), 0>;
3224 def : InstAlias<"movzx\t{$src, $dst|$dst, $src}", (MOVZX16rr8 GR16:$dst, GR8:$src), 0>;
3225 def : InstAlias<"movzx\t{$src, $dst|$dst, $src}", (MOVZX16rm8 GR16:$dst, i8mem:$src), 0>;
3226 def : InstAlias<"movzx\t{$src, $dst|$dst, $src}", (MOVZX32rr8 GR32:$dst, GR8:$src), 0>;
3227 def : InstAlias<"movzx\t{$src, $dst|$dst, $src}", (MOVZX32rr16 GR32:$dst, GR16:$src), 0>;
3228 def : InstAlias<"movzx\t{$src, $dst|$dst, $src}", (MOVZX64rr8 GR64:$dst, GR8:$src), 0>;
3229 def : InstAlias<"movzx\t{$src, $dst|$dst, $src}", (MOVZX64rr16 GR64:$dst, GR16:$src), 0>;
3230 // Note: No GR32->GR64 movzx form.
3232 // outb %dx -> outb %al, %dx
3233 def : InstAlias<"outb\t{%dx|dx}", (OUT8rr), 0>;
3234 def : InstAlias<"outw\t{%dx|dx}", (OUT16rr), 0>;
3235 def : InstAlias<"outl\t{%dx|dx}", (OUT32rr), 0>;
3236 def : InstAlias<"outb\t$port", (OUT8ir u8imm:$port), 0>;
3237 def : InstAlias<"outw\t$port", (OUT16ir u8imm:$port), 0>;
3238 def : InstAlias<"outl\t$port", (OUT32ir u8imm:$port), 0>;
3240 // 'sldt <mem>' can be encoded with either sldtw or sldtq with the same
3241 // effect (both store to a 16-bit mem). Force to sldtw to avoid ambiguity
3242 // errors, since its encoding is the most compact.
3243 def : InstAlias<"sldt $mem", (SLDT16m i16mem:$mem), 0>;
3245 // shld/shrd op,op -> shld op, op, CL
3246 def : InstAlias<"shld{w}\t{$r2, $r1|$r1, $r2}", (SHLD16rrCL GR16:$r1, GR16:$r2), 0>;
3247 def : InstAlias<"shld{l}\t{$r2, $r1|$r1, $r2}", (SHLD32rrCL GR32:$r1, GR32:$r2), 0>;
3248 def : InstAlias<"shld{q}\t{$r2, $r1|$r1, $r2}", (SHLD64rrCL GR64:$r1, GR64:$r2), 0>;
3249 def : InstAlias<"shrd{w}\t{$r2, $r1|$r1, $r2}", (SHRD16rrCL GR16:$r1, GR16:$r2), 0>;
3250 def : InstAlias<"shrd{l}\t{$r2, $r1|$r1, $r2}", (SHRD32rrCL GR32:$r1, GR32:$r2), 0>;
3251 def : InstAlias<"shrd{q}\t{$r2, $r1|$r1, $r2}", (SHRD64rrCL GR64:$r1, GR64:$r2), 0>;
3253 def : InstAlias<"shld{w}\t{$reg, $mem|$mem, $reg}", (SHLD16mrCL i16mem:$mem, GR16:$reg), 0>;
3254 def : InstAlias<"shld{l}\t{$reg, $mem|$mem, $reg}", (SHLD32mrCL i32mem:$mem, GR32:$reg), 0>;
3255 def : InstAlias<"shld{q}\t{$reg, $mem|$mem, $reg}", (SHLD64mrCL i64mem:$mem, GR64:$reg), 0>;
3256 def : InstAlias<"shrd{w}\t{$reg, $mem|$mem, $reg}", (SHRD16mrCL i16mem:$mem, GR16:$reg), 0>;
3257 def : InstAlias<"shrd{l}\t{$reg, $mem|$mem, $reg}", (SHRD32mrCL i32mem:$mem, GR32:$reg), 0>;
3258 def : InstAlias<"shrd{q}\t{$reg, $mem|$mem, $reg}", (SHRD64mrCL i64mem:$mem, GR64:$reg), 0>;
3260 /* FIXME: This is disabled because the asm matcher is currently incapable of
3261 * matching a fixed immediate like $1.
3262 // "shl X, $1" is an alias for "shl X".
3263 multiclass ShiftRotateByOneAlias<string Mnemonic, string Opc> {
3264 def : InstAlias<!strconcat(Mnemonic, "b $op, $$1"),
3265 (!cast<Instruction>(!strconcat(Opc, "8r1")) GR8:$op)>;
3266 def : InstAlias<!strconcat(Mnemonic, "w $op, $$1"),
3267 (!cast<Instruction>(!strconcat(Opc, "16r1")) GR16:$op)>;
3268 def : InstAlias<!strconcat(Mnemonic, "l $op, $$1"),
3269 (!cast<Instruction>(!strconcat(Opc, "32r1")) GR32:$op)>;
3270 def : InstAlias<!strconcat(Mnemonic, "q $op, $$1"),
3271 (!cast<Instruction>(!strconcat(Opc, "64r1")) GR64:$op)>;
3272 def : InstAlias<!strconcat(Mnemonic, "b $op, $$1"),
3273 (!cast<Instruction>(!strconcat(Opc, "8m1")) i8mem:$op)>;
3274 def : InstAlias<!strconcat(Mnemonic, "w $op, $$1"),
3275 (!cast<Instruction>(!strconcat(Opc, "16m1")) i16mem:$op)>;
3276 def : InstAlias<!strconcat(Mnemonic, "l $op, $$1"),
3277 (!cast<Instruction>(!strconcat(Opc, "32m1")) i32mem:$op)>;
3278 def : InstAlias<!strconcat(Mnemonic, "q $op, $$1"),
3279 (!cast<Instruction>(!strconcat(Opc, "64m1")) i64mem:$op)>;
3282 defm : ShiftRotateByOneAlias<"rcl", "RCL">;
3283 defm : ShiftRotateByOneAlias<"rcr", "RCR">;
3284 defm : ShiftRotateByOneAlias<"rol", "ROL">;
3285 defm : ShiftRotateByOneAlias<"ror", "ROR">;
3288 // test: We accept "testX <reg>, <mem>" and "testX <mem>, <reg>" as synonyms.
3289 def : InstAlias<"test{b}\t{$mem, $val|$val, $mem}",
3290 (TEST8mr i8mem :$mem, GR8 :$val), 0>;
3291 def : InstAlias<"test{w}\t{$mem, $val|$val, $mem}",
3292 (TEST16mr i16mem:$mem, GR16:$val), 0>;
3293 def : InstAlias<"test{l}\t{$mem, $val|$val, $mem}",
3294 (TEST32mr i32mem:$mem, GR32:$val), 0>;
3295 def : InstAlias<"test{q}\t{$mem, $val|$val, $mem}",
3296 (TEST64mr i64mem:$mem, GR64:$val), 0>;
3298 // xchg: We accept "xchgX <reg>, <mem>" and "xchgX <mem>, <reg>" as synonyms.
3299 def : InstAlias<"xchg{b}\t{$mem, $val|$val, $mem}",
3300 (XCHG8rm GR8 :$val, i8mem :$mem), 0>;
3301 def : InstAlias<"xchg{w}\t{$mem, $val|$val, $mem}",
3302 (XCHG16rm GR16:$val, i16mem:$mem), 0>;
3303 def : InstAlias<"xchg{l}\t{$mem, $val|$val, $mem}",
3304 (XCHG32rm GR32:$val, i32mem:$mem), 0>;
3305 def : InstAlias<"xchg{q}\t{$mem, $val|$val, $mem}",
3306 (XCHG64rm GR64:$val, i64mem:$mem), 0>;
3308 // xchg: We accept "xchgX <reg>, %eax" and "xchgX %eax, <reg>" as synonyms.
3309 def : InstAlias<"xchg{w}\t{%ax, $src|$src, ax}", (XCHG16ar GR16:$src), 0>;
3310 def : InstAlias<"xchg{l}\t{%eax, $src|$src, eax}",
3311 (XCHG32ar GR32:$src), 0>, Requires<[Not64BitMode]>;
3312 def : InstAlias<"xchg{l}\t{%eax, $src|$src, eax}",
3313 (XCHG32ar64 GR32_NOAX:$src), 0>, Requires<[In64BitMode]>;
3314 def : InstAlias<"xchg{q}\t{%rax, $src|$src, rax}", (XCHG64ar GR64:$src), 0>;
3316 // These aliases exist to get the parser to prioritize matching 8-bit
3317 // immediate encodings over matching the implicit ax/eax/rax encodings. By
3318 // explicitly mentioning the A register here, these entries will be ordered
3319 // first due to the more explicit immediate type.
3320 def : InstAlias<"adc{w}\t{$imm, %ax|ax, $imm}", (ADC16ri8 AX, i16i8imm:$imm), 0>;
3321 def : InstAlias<"add{w}\t{$imm, %ax|ax, $imm}", (ADD16ri8 AX, i16i8imm:$imm), 0>;
3322 def : InstAlias<"and{w}\t{$imm, %ax|ax, $imm}", (AND16ri8 AX, i16i8imm:$imm), 0>;
3323 def : InstAlias<"cmp{w}\t{$imm, %ax|ax, $imm}", (CMP16ri8 AX, i16i8imm:$imm), 0>;
3324 def : InstAlias<"or{w}\t{$imm, %ax|ax, $imm}", (OR16ri8 AX, i16i8imm:$imm), 0>;
3325 def : InstAlias<"sbb{w}\t{$imm, %ax|ax, $imm}", (SBB16ri8 AX, i16i8imm:$imm), 0>;
3326 def : InstAlias<"sub{w}\t{$imm, %ax|ax, $imm}", (SUB16ri8 AX, i16i8imm:$imm), 0>;
3327 def : InstAlias<"xor{w}\t{$imm, %ax|ax, $imm}", (XOR16ri8 AX, i16i8imm:$imm), 0>;
3329 def : InstAlias<"adc{l}\t{$imm, %eax|eax, $imm}", (ADC32ri8 EAX, i32i8imm:$imm), 0>;
3330 def : InstAlias<"add{l}\t{$imm, %eax|eax, $imm}", (ADD32ri8 EAX, i32i8imm:$imm), 0>;
3331 def : InstAlias<"and{l}\t{$imm, %eax|eax, $imm}", (AND32ri8 EAX, i32i8imm:$imm), 0>;
3332 def : InstAlias<"cmp{l}\t{$imm, %eax|eax, $imm}", (CMP32ri8 EAX, i32i8imm:$imm), 0>;
3333 def : InstAlias<"or{l}\t{$imm, %eax|eax, $imm}", (OR32ri8 EAX, i32i8imm:$imm), 0>;
3334 def : InstAlias<"sbb{l}\t{$imm, %eax|eax, $imm}", (SBB32ri8 EAX, i32i8imm:$imm), 0>;
3335 def : InstAlias<"sub{l}\t{$imm, %eax|eax, $imm}", (SUB32ri8 EAX, i32i8imm:$imm), 0>;
3336 def : InstAlias<"xor{l}\t{$imm, %eax|eax, $imm}", (XOR32ri8 EAX, i32i8imm:$imm), 0>;
3338 def : InstAlias<"adc{q}\t{$imm, %rax|rax, $imm}", (ADC64ri8 RAX, i64i8imm:$imm), 0>;
3339 def : InstAlias<"add{q}\t{$imm, %rax|rax, $imm}", (ADD64ri8 RAX, i64i8imm:$imm), 0>;
3340 def : InstAlias<"and{q}\t{$imm, %rax|rax, $imm}", (AND64ri8 RAX, i64i8imm:$imm), 0>;
3341 def : InstAlias<"cmp{q}\t{$imm, %rax|rax, $imm}", (CMP64ri8 RAX, i64i8imm:$imm), 0>;
3342 def : InstAlias<"or{q}\t{$imm, %rax|rax, $imm}", (OR64ri8 RAX, i64i8imm:$imm), 0>;
3343 def : InstAlias<"sbb{q}\t{$imm, %rax|rax, $imm}", (SBB64ri8 RAX, i64i8imm:$imm), 0>;
3344 def : InstAlias<"sub{q}\t{$imm, %rax|rax, $imm}", (SUB64ri8 RAX, i64i8imm:$imm), 0>;
3345 def : InstAlias<"xor{q}\t{$imm, %rax|rax, $imm}", (XOR64ri8 RAX, i64i8imm:$imm), 0>;