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()">,
836 AssemblerPredicate<"FeatureVNNI", "AVX-512 VNNI ISA">;
838 def HasBITALG : Predicate<"Subtarget->hasBITALG()">,
839 AssemblerPredicate<"FeatureBITALG", "AVX-512 BITALG ISA">;
840 def HasPOPCNT : Predicate<"Subtarget->hasPOPCNT()">;
841 def HasAES : Predicate<"Subtarget->hasAES()">;
842 def HasVAES : Predicate<"Subtarget->hasVAES()">;
843 def NoVLX_Or_NoVAES : Predicate<"!Subtarget->hasVLX() || !Subtarget->hasVAES()">;
844 def HasFXSR : Predicate<"Subtarget->hasFXSR()">;
845 def HasXSAVE : Predicate<"Subtarget->hasXSAVE()">;
846 def HasXSAVEOPT : Predicate<"Subtarget->hasXSAVEOPT()">;
847 def HasXSAVEC : Predicate<"Subtarget->hasXSAVEC()">;
848 def HasXSAVES : Predicate<"Subtarget->hasXSAVES()">;
849 def HasPCLMUL : Predicate<"Subtarget->hasPCLMUL()">;
850 def NoVLX_Or_NoVPCLMULQDQ :
851 Predicate<"!Subtarget->hasVLX() || !Subtarget->hasVPCLMULQDQ()">;
852 def HasVPCLMULQDQ : Predicate<"Subtarget->hasVPCLMULQDQ()">;
853 def HasGFNI : Predicate<"Subtarget->hasGFNI()">;
854 def HasFMA : Predicate<"Subtarget->hasFMA()">;
855 def HasFMA4 : Predicate<"Subtarget->hasFMA4()">;
856 def NoFMA4 : Predicate<"!Subtarget->hasFMA4()">;
857 def HasXOP : Predicate<"Subtarget->hasXOP()">;
858 def HasTBM : Predicate<"Subtarget->hasTBM()">;
859 def NoTBM : Predicate<"!Subtarget->hasTBM()">;
860 def HasLWP : Predicate<"Subtarget->hasLWP()">;
861 def HasMOVBE : Predicate<"Subtarget->hasMOVBE()">;
862 def HasRDRAND : Predicate<"Subtarget->hasRDRAND()">;
863 def HasF16C : Predicate<"Subtarget->hasF16C()">;
864 def HasFSGSBase : Predicate<"Subtarget->hasFSGSBase()">;
865 def HasLZCNT : Predicate<"Subtarget->hasLZCNT()">;
866 def HasBMI : Predicate<"Subtarget->hasBMI()">;
867 def HasBMI2 : Predicate<"Subtarget->hasBMI2()">;
868 def NoBMI2 : Predicate<"!Subtarget->hasBMI2()">;
869 def HasVBMI : Predicate<"Subtarget->hasVBMI()">,
870 AssemblerPredicate<"FeatureVBMI", "AVX-512 VBMI ISA">;
871 def HasVBMI2 : Predicate<"Subtarget->hasVBMI2()">,
872 AssemblerPredicate<"FeatureVBMI2", "AVX-512 VBMI2 ISA">;
873 def HasIFMA : Predicate<"Subtarget->hasIFMA()">,
874 AssemblerPredicate<"FeatureIFMA", "AVX-512 IFMA ISA">;
875 def HasRTM : Predicate<"Subtarget->hasRTM()">;
876 def HasADX : Predicate<"Subtarget->hasADX()">;
877 def HasSHA : Predicate<"Subtarget->hasSHA()">;
878 def HasPRFCHW : Predicate<"Subtarget->hasPRFCHW()">;
879 def HasRDSEED : Predicate<"Subtarget->hasRDSEED()">;
880 def HasSSEPrefetch : Predicate<"Subtarget->hasSSEPrefetch()">;
881 def NoSSEPrefetch : Predicate<"!Subtarget->hasSSEPrefetch()">;
882 def HasPrefetchW : Predicate<"Subtarget->hasPRFCHW()">;
883 def HasPREFETCHWT1 : Predicate<"Subtarget->hasPREFETCHWT1()">;
884 def HasLAHFSAHF : Predicate<"Subtarget->hasLAHFSAHF()">;
885 def HasMWAITX : Predicate<"Subtarget->hasMWAITX()">;
886 def HasCLZERO : Predicate<"Subtarget->hasCLZERO()">;
887 def FPStackf32 : Predicate<"!Subtarget->hasSSE1()">;
888 def FPStackf64 : Predicate<"!Subtarget->hasSSE2()">;
889 def HasMPX : Predicate<"Subtarget->hasMPX()">;
890 def HasSHSTK : Predicate<"Subtarget->hasSHSTK()">;
891 def HasIBT : Predicate<"Subtarget->hasIBT()">;
892 def HasCLFLUSHOPT : Predicate<"Subtarget->hasCLFLUSHOPT()">;
893 def HasCLWB : Predicate<"Subtarget->hasCLWB()">;
894 def HasCmpxchg16b: Predicate<"Subtarget->hasCmpxchg16b()">;
895 def Not64BitMode : Predicate<"!Subtarget->is64Bit()">,
896 AssemblerPredicate<"!Mode64Bit", "Not 64-bit mode">;
897 def In64BitMode : Predicate<"Subtarget->is64Bit()">,
898 AssemblerPredicate<"Mode64Bit", "64-bit mode">;
899 def IsLP64 : Predicate<"Subtarget->isTarget64BitLP64()">;
900 def NotLP64 : Predicate<"!Subtarget->isTarget64BitLP64()">;
901 def In16BitMode : Predicate<"Subtarget->is16Bit()">,
902 AssemblerPredicate<"Mode16Bit", "16-bit mode">;
903 def Not16BitMode : Predicate<"!Subtarget->is16Bit()">,
904 AssemblerPredicate<"!Mode16Bit", "Not 16-bit mode">;
905 def In32BitMode : Predicate<"Subtarget->is32Bit()">,
906 AssemblerPredicate<"Mode32Bit", "32-bit mode">;
907 def IsWin64 : Predicate<"Subtarget->isTargetWin64()">;
908 def NotWin64 : Predicate<"!Subtarget->isTargetWin64()">;
909 def NotWin64WithoutFP : Predicate<"!Subtarget->isTargetWin64() ||"
910 "Subtarget->getFrameLowering()->hasFP(*MF)"> {
911 let RecomputePerFunction = 1;
913 def IsPS4 : Predicate<"Subtarget->isTargetPS4()">;
914 def NotPS4 : Predicate<"!Subtarget->isTargetPS4()">;
915 def IsNaCl : Predicate<"Subtarget->isTargetNaCl()">;
916 def NotNaCl : Predicate<"!Subtarget->isTargetNaCl()">;
917 def SmallCode : Predicate<"TM.getCodeModel() == CodeModel::Small">;
918 def KernelCode : Predicate<"TM.getCodeModel() == CodeModel::Kernel">;
919 def NearData : Predicate<"TM.getCodeModel() == CodeModel::Small ||"
920 "TM.getCodeModel() == CodeModel::Kernel">;
921 def IsNotPIC : Predicate<"!TM.isPositionIndependent()">;
923 // We could compute these on a per-module basis but doing so requires accessing
924 // the Function object through the <Target>Subtarget and objections were raised
925 // to that (see post-commit review comments for r301750).
926 let RecomputePerFunction = 1 in {
927 def OptForSize : Predicate<"MF->getFunction().optForSize()">;
928 def OptForMinSize : Predicate<"MF->getFunction().optForMinSize()">;
929 def OptForSpeed : Predicate<"!MF->getFunction().optForSize()">;
930 def UseIncDec : Predicate<"!Subtarget->slowIncDec() || "
931 "MF->getFunction().optForSize()">;
934 def CallImmAddr : Predicate<"Subtarget->isLegalToCallImmediateAddr()">;
935 def FavorMemIndirectCall : Predicate<"!Subtarget->slowTwoMemOps()">;
936 def HasFastMem32 : Predicate<"!Subtarget->isUnalignedMem32Slow()">;
937 def HasFastLZCNT : Predicate<"Subtarget->hasFastLZCNT()">;
938 def HasFastSHLDRotate : Predicate<"Subtarget->hasFastSHLDRotate()">;
939 def HasERMSB : Predicate<"Subtarget->hasERMSB()">;
940 def HasMFence : Predicate<"Subtarget->hasMFence()">;
942 //===----------------------------------------------------------------------===//
943 // X86 Instruction Format Definitions.
946 include "X86InstrFormats.td"
948 //===----------------------------------------------------------------------===//
949 // Pattern fragments.
952 // X86 specific condition code. These correspond to CondCode in
953 // X86InstrInfo.h. They must be kept in synch.
954 def X86_COND_A : PatLeaf<(i8 0)>; // alt. COND_NBE
955 def X86_COND_AE : PatLeaf<(i8 1)>; // alt. COND_NC
956 def X86_COND_B : PatLeaf<(i8 2)>; // alt. COND_C
957 def X86_COND_BE : PatLeaf<(i8 3)>; // alt. COND_NA
958 def X86_COND_E : PatLeaf<(i8 4)>; // alt. COND_Z
959 def X86_COND_G : PatLeaf<(i8 5)>; // alt. COND_NLE
960 def X86_COND_GE : PatLeaf<(i8 6)>; // alt. COND_NL
961 def X86_COND_L : PatLeaf<(i8 7)>; // alt. COND_NGE
962 def X86_COND_LE : PatLeaf<(i8 8)>; // alt. COND_NG
963 def X86_COND_NE : PatLeaf<(i8 9)>; // alt. COND_NZ
964 def X86_COND_NO : PatLeaf<(i8 10)>;
965 def X86_COND_NP : PatLeaf<(i8 11)>; // alt. COND_PO
966 def X86_COND_NS : PatLeaf<(i8 12)>;
967 def X86_COND_O : PatLeaf<(i8 13)>;
968 def X86_COND_P : PatLeaf<(i8 14)>; // alt. COND_PE
969 def X86_COND_S : PatLeaf<(i8 15)>;
971 def i16immSExt8 : ImmLeaf<i16, [{ return isInt<8>(Imm); }]>;
972 def i32immSExt8 : ImmLeaf<i32, [{ return isInt<8>(Imm); }]>;
973 def i64immSExt8 : ImmLeaf<i64, [{ return isInt<8>(Imm); }]>;
974 def i64immSExt32 : ImmLeaf<i64, [{ return isInt<32>(Imm); }]>;
976 // FIXME: Ideally we would just replace the above i*immSExt* matchers with
977 // relocImm-based matchers, but then FastISel would be unable to use them.
978 def i64relocImmSExt8 : PatLeaf<(i64 relocImm), [{
979 return isSExtRelocImm<8>(N);
981 def i64relocImmSExt32 : PatLeaf<(i64 relocImm), [{
982 return isSExtRelocImm<32>(N);
985 // If we have multiple users of an immediate, it's much smaller to reuse
986 // the register, rather than encode the immediate in every instruction.
987 // This has the risk of increasing register pressure from stretched live
988 // ranges, however, the immediates should be trivial to rematerialize by
989 // the RA in the event of high register pressure.
990 // TODO : This is currently enabled for stores and binary ops. There are more
991 // cases for which this can be enabled, though this catches the bulk of the
993 // TODO2 : This should really also be enabled under O2, but there's currently
994 // an issue with RA where we don't pull the constants into their users
995 // when we rematerialize them. I'll follow-up on enabling O2 after we fix that
997 // TODO3 : This is currently limited to single basic blocks (DAG creation
998 // pulls block immediates to the top and merges them if necessary).
999 // Eventually, it would be nice to allow ConstantHoisting to merge constants
1000 // globally for potentially added savings.
1002 def imm8_su : PatLeaf<(i8 relocImm), [{
1003 return !shouldAvoidImmediateInstFormsForSize(N);
1005 def imm16_su : PatLeaf<(i16 relocImm), [{
1006 return !shouldAvoidImmediateInstFormsForSize(N);
1008 def imm32_su : PatLeaf<(i32 relocImm), [{
1009 return !shouldAvoidImmediateInstFormsForSize(N);
1011 def i64immSExt32_su : PatLeaf<(i64immSExt32), [{
1012 return !shouldAvoidImmediateInstFormsForSize(N);
1015 def i16immSExt8_su : PatLeaf<(i16immSExt8), [{
1016 return !shouldAvoidImmediateInstFormsForSize(N);
1018 def i32immSExt8_su : PatLeaf<(i32immSExt8), [{
1019 return !shouldAvoidImmediateInstFormsForSize(N);
1021 def i64immSExt8_su : PatLeaf<(i64immSExt8), [{
1022 return !shouldAvoidImmediateInstFormsForSize(N);
1025 def i64relocImmSExt8_su : PatLeaf<(i64relocImmSExt8), [{
1026 return !shouldAvoidImmediateInstFormsForSize(N);
1028 def i64relocImmSExt32_su : PatLeaf<(i64relocImmSExt32), [{
1029 return !shouldAvoidImmediateInstFormsForSize(N);
1032 // i64immZExt32 predicate - True if the 64-bit immediate fits in a 32-bit
1034 def i64immZExt32 : ImmLeaf<i64, [{ return isUInt<32>(Imm); }]>;
1036 def i64immZExt32SExt8 : ImmLeaf<i64, [{
1037 return isUInt<32>(Imm) && isInt<8>(static_cast<int32_t>(Imm));
1040 // Helper fragments for loads.
1041 // It's always safe to treat a anyext i16 load as a i32 load if the i16 is
1042 // known to be 32-bit aligned or better. Ditto for i8 to i16.
1043 def loadi16 : PatFrag<(ops node:$ptr), (i16 (unindexedload node:$ptr)), [{
1044 LoadSDNode *LD = cast<LoadSDNode>(N);
1045 ISD::LoadExtType ExtType = LD->getExtensionType();
1046 if (ExtType == ISD::NON_EXTLOAD)
1048 if (ExtType == ISD::EXTLOAD)
1049 return LD->getAlignment() >= 2 && !LD->isVolatile();
1053 def loadi16_anyext : PatFrag<(ops node:$ptr), (i32 (unindexedload node:$ptr)),[{
1054 LoadSDNode *LD = cast<LoadSDNode>(N);
1055 ISD::LoadExtType ExtType = LD->getExtensionType();
1056 if (ExtType == ISD::EXTLOAD)
1057 return LD->getAlignment() >= 2 && !LD->isVolatile();
1061 def loadi32 : PatFrag<(ops node:$ptr), (i32 (unindexedload node:$ptr)), [{
1062 LoadSDNode *LD = cast<LoadSDNode>(N);
1063 ISD::LoadExtType ExtType = LD->getExtensionType();
1064 if (ExtType == ISD::NON_EXTLOAD)
1066 if (ExtType == ISD::EXTLOAD)
1067 return LD->getAlignment() >= 4 && !LD->isVolatile();
1071 def loadi8 : PatFrag<(ops node:$ptr), (i8 (load node:$ptr))>;
1072 def loadi64 : PatFrag<(ops node:$ptr), (i64 (load node:$ptr))>;
1073 def loadf32 : PatFrag<(ops node:$ptr), (f32 (load node:$ptr))>;
1074 def loadf64 : PatFrag<(ops node:$ptr), (f64 (load node:$ptr))>;
1075 def loadf80 : PatFrag<(ops node:$ptr), (f80 (load node:$ptr))>;
1076 def loadf128 : PatFrag<(ops node:$ptr), (f128 (load node:$ptr))>;
1078 def sextloadi16i8 : PatFrag<(ops node:$ptr), (i16 (sextloadi8 node:$ptr))>;
1079 def sextloadi32i8 : PatFrag<(ops node:$ptr), (i32 (sextloadi8 node:$ptr))>;
1080 def sextloadi32i16 : PatFrag<(ops node:$ptr), (i32 (sextloadi16 node:$ptr))>;
1081 def sextloadi64i8 : PatFrag<(ops node:$ptr), (i64 (sextloadi8 node:$ptr))>;
1082 def sextloadi64i16 : PatFrag<(ops node:$ptr), (i64 (sextloadi16 node:$ptr))>;
1083 def sextloadi64i32 : PatFrag<(ops node:$ptr), (i64 (sextloadi32 node:$ptr))>;
1085 def zextloadi8i1 : PatFrag<(ops node:$ptr), (i8 (zextloadi1 node:$ptr))>;
1086 def zextloadi16i1 : PatFrag<(ops node:$ptr), (i16 (zextloadi1 node:$ptr))>;
1087 def zextloadi32i1 : PatFrag<(ops node:$ptr), (i32 (zextloadi1 node:$ptr))>;
1088 def zextloadi16i8 : PatFrag<(ops node:$ptr), (i16 (zextloadi8 node:$ptr))>;
1089 def zextloadi32i8 : PatFrag<(ops node:$ptr), (i32 (zextloadi8 node:$ptr))>;
1090 def zextloadi32i16 : PatFrag<(ops node:$ptr), (i32 (zextloadi16 node:$ptr))>;
1091 def zextloadi64i1 : PatFrag<(ops node:$ptr), (i64 (zextloadi1 node:$ptr))>;
1092 def zextloadi64i8 : PatFrag<(ops node:$ptr), (i64 (zextloadi8 node:$ptr))>;
1093 def zextloadi64i16 : PatFrag<(ops node:$ptr), (i64 (zextloadi16 node:$ptr))>;
1094 def zextloadi64i32 : PatFrag<(ops node:$ptr), (i64 (zextloadi32 node:$ptr))>;
1096 def extloadi8i1 : PatFrag<(ops node:$ptr), (i8 (extloadi1 node:$ptr))>;
1097 def extloadi16i1 : PatFrag<(ops node:$ptr), (i16 (extloadi1 node:$ptr))>;
1098 def extloadi32i1 : PatFrag<(ops node:$ptr), (i32 (extloadi1 node:$ptr))>;
1099 def extloadi16i8 : PatFrag<(ops node:$ptr), (i16 (extloadi8 node:$ptr))>;
1100 def extloadi32i8 : PatFrag<(ops node:$ptr), (i32 (extloadi8 node:$ptr))>;
1101 def extloadi32i16 : PatFrag<(ops node:$ptr), (i32 (extloadi16 node:$ptr))>;
1102 def extloadi64i1 : PatFrag<(ops node:$ptr), (i64 (extloadi1 node:$ptr))>;
1103 def extloadi64i8 : PatFrag<(ops node:$ptr), (i64 (extloadi8 node:$ptr))>;
1104 def extloadi64i16 : PatFrag<(ops node:$ptr), (i64 (extloadi16 node:$ptr))>;
1105 def extloadi64i32 : PatFrag<(ops node:$ptr), (i64 (extloadi32 node:$ptr))>;
1108 // An 'and' node with a single use.
1109 def and_su : PatFrag<(ops node:$lhs, node:$rhs), (and node:$lhs, node:$rhs), [{
1110 return N->hasOneUse();
1112 // An 'srl' node with a single use.
1113 def srl_su : PatFrag<(ops node:$lhs, node:$rhs), (srl node:$lhs, node:$rhs), [{
1114 return N->hasOneUse();
1116 // An 'trunc' node with a single use.
1117 def trunc_su : PatFrag<(ops node:$src), (trunc node:$src), [{
1118 return N->hasOneUse();
1121 //===----------------------------------------------------------------------===//
1122 // Instruction list.
1126 let hasSideEffects = 0, SchedRW = [WriteZero] in {
1127 def NOOP : I<0x90, RawFrm, (outs), (ins), "nop", [], IIC_NOP>;
1128 def NOOPW : I<0x1f, MRMXm, (outs), (ins i16mem:$zero),
1129 "nop{w}\t$zero", [], IIC_NOP>, TB, OpSize16;
1130 def NOOPL : I<0x1f, MRMXm, (outs), (ins i32mem:$zero),
1131 "nop{l}\t$zero", [], IIC_NOP>, TB, OpSize32;
1132 def NOOPQ : RI<0x1f, MRMXm, (outs), (ins i64mem:$zero),
1133 "nop{q}\t$zero", [], IIC_NOP>, TB,
1134 Requires<[In64BitMode]>;
1135 // Also allow register so we can assemble/disassemble
1136 def NOOPWr : I<0x1f, MRMXr, (outs), (ins GR16:$zero),
1137 "nop{w}\t$zero", [], IIC_NOP>, TB, OpSize16;
1138 def NOOPLr : I<0x1f, MRMXr, (outs), (ins GR32:$zero),
1139 "nop{l}\t$zero", [], IIC_NOP>, TB, OpSize32;
1140 def NOOPQr : RI<0x1f, MRMXr, (outs), (ins GR64:$zero),
1141 "nop{q}\t$zero", [], IIC_NOP>, TB,
1142 Requires<[In64BitMode]>;
1146 // Constructing a stack frame.
1147 def ENTER : Ii16<0xC8, RawFrmImm8, (outs), (ins i16imm:$len, i8imm:$lvl),
1148 "enter\t$len, $lvl", [], IIC_ENTER>, Sched<[WriteMicrocoded]>;
1150 let SchedRW = [WriteALU] in {
1151 let Defs = [EBP, ESP], Uses = [EBP, ESP], mayLoad = 1, hasSideEffects=0 in
1152 def LEAVE : I<0xC9, RawFrm,
1153 (outs), (ins), "leave", [], IIC_LEAVE>,
1154 Requires<[Not64BitMode]>;
1156 let Defs = [RBP,RSP], Uses = [RBP,RSP], mayLoad = 1, hasSideEffects = 0 in
1157 def LEAVE64 : I<0xC9, RawFrm,
1158 (outs), (ins), "leave", [], IIC_LEAVE>,
1159 Requires<[In64BitMode]>;
1162 //===----------------------------------------------------------------------===//
1163 // Miscellaneous Instructions.
1166 let isBarrier = 1, hasSideEffects = 1, usesCustomInserter = 1,
1167 SchedRW = [WriteSystem] in
1168 def Int_eh_sjlj_setup_dispatch
1169 : PseudoI<(outs), (ins), [(X86eh_sjlj_setup_dispatch)]>;
1171 let Defs = [ESP], Uses = [ESP], hasSideEffects=0 in {
1172 let mayLoad = 1, SchedRW = [WriteLoad] in {
1173 def POP16r : I<0x58, AddRegFrm, (outs GR16:$reg), (ins), "pop{w}\t$reg", [],
1174 IIC_POP_REG16>, OpSize16;
1175 def POP32r : I<0x58, AddRegFrm, (outs GR32:$reg), (ins), "pop{l}\t$reg", [],
1176 IIC_POP_REG>, OpSize32, Requires<[Not64BitMode]>;
1177 def POP16rmr: I<0x8F, MRM0r, (outs GR16:$reg), (ins), "pop{w}\t$reg", [],
1178 IIC_POP_REG>, OpSize16;
1179 def POP32rmr: I<0x8F, MRM0r, (outs GR32:$reg), (ins), "pop{l}\t$reg", [],
1180 IIC_POP_REG>, OpSize32, Requires<[Not64BitMode]>;
1181 } // mayLoad, SchedRW
1182 let mayStore = 1, mayLoad = 1, SchedRW = [WriteRMW] in {
1183 def POP16rmm: I<0x8F, MRM0m, (outs), (ins i16mem:$dst), "pop{w}\t$dst", [],
1184 IIC_POP_MEM>, OpSize16;
1185 def POP32rmm: I<0x8F, MRM0m, (outs), (ins i32mem:$dst), "pop{l}\t$dst", [],
1186 IIC_POP_MEM>, OpSize32, Requires<[Not64BitMode]>;
1187 } // mayStore, mayLoad, WriteRMW
1189 let mayStore = 1, SchedRW = [WriteStore] in {
1190 def PUSH16r : I<0x50, AddRegFrm, (outs), (ins GR16:$reg), "push{w}\t$reg",[],
1191 IIC_PUSH_REG>, OpSize16;
1192 def PUSH32r : I<0x50, AddRegFrm, (outs), (ins GR32:$reg), "push{l}\t$reg",[],
1193 IIC_PUSH_REG>, OpSize32, Requires<[Not64BitMode]>;
1194 def PUSH16rmr: I<0xFF, MRM6r, (outs), (ins GR16:$reg), "push{w}\t$reg",[],
1195 IIC_PUSH_REG>, OpSize16;
1196 def PUSH32rmr: I<0xFF, MRM6r, (outs), (ins GR32:$reg), "push{l}\t$reg",[],
1197 IIC_PUSH_REG>, OpSize32, Requires<[Not64BitMode]>;
1199 def PUSH16i8 : Ii8<0x6a, RawFrm, (outs), (ins i16i8imm:$imm),
1200 "push{w}\t$imm", [], IIC_PUSH_IMM>, OpSize16;
1201 def PUSHi16 : Ii16<0x68, RawFrm, (outs), (ins i16imm:$imm),
1202 "push{w}\t$imm", [], IIC_PUSH_IMM>, OpSize16;
1204 def PUSH32i8 : Ii8<0x6a, RawFrm, (outs), (ins i32i8imm:$imm),
1205 "push{l}\t$imm", [], IIC_PUSH_IMM>, OpSize32,
1206 Requires<[Not64BitMode]>;
1207 def PUSHi32 : Ii32<0x68, RawFrm, (outs), (ins i32imm:$imm),
1208 "push{l}\t$imm", [], IIC_PUSH_IMM>, OpSize32,
1209 Requires<[Not64BitMode]>;
1210 } // mayStore, SchedRW
1212 let mayLoad = 1, mayStore = 1, SchedRW = [WriteRMW] in {
1213 def PUSH16rmm: I<0xFF, MRM6m, (outs), (ins i16mem:$src), "push{w}\t$src",[],
1214 IIC_PUSH_MEM>, OpSize16;
1215 def PUSH32rmm: I<0xFF, MRM6m, (outs), (ins i32mem:$src), "push{l}\t$src",[],
1216 IIC_PUSH_MEM>, OpSize32, Requires<[Not64BitMode]>;
1217 } // mayLoad, mayStore, SchedRW
1221 let mayLoad = 1, mayStore = 1, usesCustomInserter = 1,
1222 SchedRW = [WriteRMW], Defs = [ESP] in {
1224 def RDFLAGS32 : PseudoI<(outs GR32:$dst), (ins),
1225 [(set GR32:$dst, (int_x86_flags_read_u32))]>,
1226 Requires<[Not64BitMode]>;
1229 def RDFLAGS64 : PseudoI<(outs GR64:$dst), (ins),
1230 [(set GR64:$dst, (int_x86_flags_read_u64))]>,
1231 Requires<[In64BitMode]>;
1234 let mayLoad = 1, mayStore = 1, usesCustomInserter = 1,
1235 SchedRW = [WriteRMW] in {
1236 let Defs = [ESP, EFLAGS], Uses = [ESP] in
1237 def WRFLAGS32 : PseudoI<(outs), (ins GR32:$src),
1238 [(int_x86_flags_write_u32 GR32:$src)]>,
1239 Requires<[Not64BitMode]>;
1241 let Defs = [RSP, EFLAGS], Uses = [RSP] in
1242 def WRFLAGS64 : PseudoI<(outs), (ins GR64:$src),
1243 [(int_x86_flags_write_u64 GR64:$src)]>,
1244 Requires<[In64BitMode]>;
1247 let Defs = [ESP, EFLAGS], Uses = [ESP], mayLoad = 1, hasSideEffects=0,
1248 SchedRW = [WriteLoad] in {
1249 def POPF16 : I<0x9D, RawFrm, (outs), (ins), "popf{w}", [], IIC_POP_F>,
1251 def POPF32 : I<0x9D, RawFrm, (outs), (ins), "popf{l|d}", [], IIC_POP_FD>,
1252 OpSize32, Requires<[Not64BitMode]>;
1255 let Defs = [ESP], Uses = [ESP, EFLAGS], mayStore = 1, hasSideEffects=0,
1256 SchedRW = [WriteStore] in {
1257 def PUSHF16 : I<0x9C, RawFrm, (outs), (ins), "pushf{w}", [], IIC_PUSH_F>,
1259 def PUSHF32 : I<0x9C, RawFrm, (outs), (ins), "pushf{l|d}", [], IIC_PUSH_F>,
1260 OpSize32, Requires<[Not64BitMode]>;
1263 let Defs = [RSP], Uses = [RSP], hasSideEffects=0 in {
1264 let mayLoad = 1, SchedRW = [WriteLoad] in {
1265 def POP64r : I<0x58, AddRegFrm, (outs GR64:$reg), (ins), "pop{q}\t$reg", [],
1266 IIC_POP_REG>, OpSize32, Requires<[In64BitMode]>;
1267 def POP64rmr: I<0x8F, MRM0r, (outs GR64:$reg), (ins), "pop{q}\t$reg", [],
1268 IIC_POP_REG>, OpSize32, Requires<[In64BitMode]>;
1269 } // mayLoad, SchedRW
1270 let mayLoad = 1, mayStore = 1, SchedRW = [WriteRMW] in
1271 def POP64rmm: I<0x8F, MRM0m, (outs), (ins i64mem:$dst), "pop{q}\t$dst", [],
1272 IIC_POP_MEM>, OpSize32, Requires<[In64BitMode]>;
1273 let mayStore = 1, SchedRW = [WriteStore] in {
1274 def PUSH64r : I<0x50, AddRegFrm, (outs), (ins GR64:$reg), "push{q}\t$reg", [],
1275 IIC_PUSH_REG>, OpSize32, Requires<[In64BitMode]>;
1276 def PUSH64rmr: I<0xFF, MRM6r, (outs), (ins GR64:$reg), "push{q}\t$reg", [],
1277 IIC_PUSH_REG>, OpSize32, Requires<[In64BitMode]>;
1278 } // mayStore, SchedRW
1279 let mayLoad = 1, mayStore = 1, SchedRW = [WriteRMW] in {
1280 def PUSH64rmm: I<0xFF, MRM6m, (outs), (ins i64mem:$src), "push{q}\t$src", [],
1281 IIC_PUSH_MEM>, OpSize32, Requires<[In64BitMode]>;
1282 } // mayLoad, mayStore, SchedRW
1285 let Defs = [RSP], Uses = [RSP], hasSideEffects = 0, mayStore = 1,
1286 SchedRW = [WriteStore] in {
1287 def PUSH64i8 : Ii8<0x6a, RawFrm, (outs), (ins i64i8imm:$imm),
1288 "push{q}\t$imm", [], IIC_PUSH_IMM>, OpSize32,
1289 Requires<[In64BitMode]>;
1290 def PUSH64i32 : Ii32S<0x68, RawFrm, (outs), (ins i64i32imm:$imm),
1291 "push{q}\t$imm", [], IIC_PUSH_IMM>, OpSize32,
1292 Requires<[In64BitMode]>;
1295 let Defs = [RSP, EFLAGS], Uses = [RSP], mayLoad = 1, hasSideEffects=0 in
1296 def POPF64 : I<0x9D, RawFrm, (outs), (ins), "popfq", [], IIC_POP_FD>,
1297 OpSize32, Requires<[In64BitMode]>, Sched<[WriteLoad]>;
1298 let Defs = [RSP], Uses = [RSP, EFLAGS], mayStore = 1, hasSideEffects=0 in
1299 def PUSHF64 : I<0x9C, RawFrm, (outs), (ins), "pushfq", [], IIC_PUSH_F>,
1300 OpSize32, Requires<[In64BitMode]>, Sched<[WriteStore]>;
1302 let Defs = [EDI, ESI, EBP, EBX, EDX, ECX, EAX, ESP], Uses = [ESP],
1303 mayLoad = 1, hasSideEffects = 0, SchedRW = [WriteLoad] in {
1304 def POPA32 : I<0x61, RawFrm, (outs), (ins), "popal", [], IIC_POP_A>,
1305 OpSize32, Requires<[Not64BitMode]>;
1306 def POPA16 : I<0x61, RawFrm, (outs), (ins), "popaw", [], IIC_POP_A>,
1307 OpSize16, Requires<[Not64BitMode]>;
1309 let Defs = [ESP], Uses = [EDI, ESI, EBP, EBX, EDX, ECX, EAX, ESP],
1310 mayStore = 1, hasSideEffects = 0, SchedRW = [WriteStore] in {
1311 def PUSHA32 : I<0x60, RawFrm, (outs), (ins), "pushal", [], IIC_PUSH_A>,
1312 OpSize32, Requires<[Not64BitMode]>;
1313 def PUSHA16 : I<0x60, RawFrm, (outs), (ins), "pushaw", [], IIC_PUSH_A>,
1314 OpSize16, Requires<[Not64BitMode]>;
1317 let Constraints = "$src = $dst", SchedRW = [WriteALU] in {
1318 // GR32 = bswap GR32
1319 def BSWAP32r : I<0xC8, AddRegFrm,
1320 (outs GR32:$dst), (ins GR32:$src),
1322 [(set GR32:$dst, (bswap GR32:$src))], IIC_BSWAP>, OpSize32, TB;
1324 def BSWAP64r : RI<0xC8, AddRegFrm, (outs GR64:$dst), (ins GR64:$src),
1326 [(set GR64:$dst, (bswap GR64:$src))], IIC_BSWAP>, TB;
1327 } // Constraints = "$src = $dst", SchedRW
1329 // Bit scan instructions.
1330 let Defs = [EFLAGS] in {
1331 def BSF16rr : I<0xBC, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
1332 "bsf{w}\t{$src, $dst|$dst, $src}",
1333 [(set GR16:$dst, EFLAGS, (X86bsf GR16:$src))],
1334 IIC_BIT_SCAN_REG>, PS, OpSize16, Sched<[WriteShift]>;
1335 def BSF16rm : I<0xBC, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
1336 "bsf{w}\t{$src, $dst|$dst, $src}",
1337 [(set GR16:$dst, EFLAGS, (X86bsf (loadi16 addr:$src)))],
1338 IIC_BIT_SCAN_MEM>, PS, OpSize16, Sched<[WriteShiftLd]>;
1339 def BSF32rr : I<0xBC, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
1340 "bsf{l}\t{$src, $dst|$dst, $src}",
1341 [(set GR32:$dst, EFLAGS, (X86bsf GR32:$src))],
1342 IIC_BIT_SCAN_REG>, PS, OpSize32, Sched<[WriteShift]>;
1343 def BSF32rm : I<0xBC, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
1344 "bsf{l}\t{$src, $dst|$dst, $src}",
1345 [(set GR32:$dst, EFLAGS, (X86bsf (loadi32 addr:$src)))],
1346 IIC_BIT_SCAN_MEM>, PS, OpSize32, Sched<[WriteShiftLd]>;
1347 def BSF64rr : RI<0xBC, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
1348 "bsf{q}\t{$src, $dst|$dst, $src}",
1349 [(set GR64:$dst, EFLAGS, (X86bsf GR64:$src))],
1350 IIC_BIT_SCAN_REG>, PS, Sched<[WriteShift]>;
1351 def BSF64rm : RI<0xBC, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
1352 "bsf{q}\t{$src, $dst|$dst, $src}",
1353 [(set GR64:$dst, EFLAGS, (X86bsf (loadi64 addr:$src)))],
1354 IIC_BIT_SCAN_MEM>, PS, Sched<[WriteShiftLd]>;
1356 def BSR16rr : I<0xBD, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
1357 "bsr{w}\t{$src, $dst|$dst, $src}",
1358 [(set GR16:$dst, EFLAGS, (X86bsr GR16:$src))],
1359 IIC_BIT_SCAN_REG>, PS, OpSize16, Sched<[WriteShift]>;
1360 def BSR16rm : I<0xBD, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
1361 "bsr{w}\t{$src, $dst|$dst, $src}",
1362 [(set GR16:$dst, EFLAGS, (X86bsr (loadi16 addr:$src)))],
1363 IIC_BIT_SCAN_MEM>, PS, OpSize16, Sched<[WriteShiftLd]>;
1364 def BSR32rr : I<0xBD, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
1365 "bsr{l}\t{$src, $dst|$dst, $src}",
1366 [(set GR32:$dst, EFLAGS, (X86bsr GR32:$src))],
1367 IIC_BIT_SCAN_REG>, PS, OpSize32, Sched<[WriteShift]>;
1368 def BSR32rm : I<0xBD, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
1369 "bsr{l}\t{$src, $dst|$dst, $src}",
1370 [(set GR32:$dst, EFLAGS, (X86bsr (loadi32 addr:$src)))],
1371 IIC_BIT_SCAN_MEM>, PS, OpSize32, Sched<[WriteShiftLd]>;
1372 def BSR64rr : RI<0xBD, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
1373 "bsr{q}\t{$src, $dst|$dst, $src}",
1374 [(set GR64:$dst, EFLAGS, (X86bsr GR64:$src))],
1375 IIC_BIT_SCAN_REG>, PS, Sched<[WriteShift]>;
1376 def BSR64rm : RI<0xBD, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
1377 "bsr{q}\t{$src, $dst|$dst, $src}",
1378 [(set GR64:$dst, EFLAGS, (X86bsr (loadi64 addr:$src)))],
1379 IIC_BIT_SCAN_MEM>, PS, Sched<[WriteShiftLd]>;
1380 } // Defs = [EFLAGS]
1382 let SchedRW = [WriteMicrocoded] in {
1383 // These uses the DF flag in the EFLAGS register to inc or dec EDI and ESI
1384 let Defs = [EDI,ESI], Uses = [EDI,ESI,EFLAGS] in {
1385 def MOVSB : I<0xA4, RawFrmDstSrc, (outs), (ins dstidx8:$dst, srcidx8:$src),
1386 "movsb\t{$src, $dst|$dst, $src}", [], IIC_MOVS>;
1387 def MOVSW : I<0xA5, RawFrmDstSrc, (outs), (ins dstidx16:$dst, srcidx16:$src),
1388 "movsw\t{$src, $dst|$dst, $src}", [], IIC_MOVS>, OpSize16;
1389 def MOVSL : I<0xA5, RawFrmDstSrc, (outs), (ins dstidx32:$dst, srcidx32:$src),
1390 "movs{l|d}\t{$src, $dst|$dst, $src}", [], IIC_MOVS>, OpSize32;
1391 def MOVSQ : RI<0xA5, RawFrmDstSrc, (outs), (ins dstidx64:$dst, srcidx64:$src),
1392 "movsq\t{$src, $dst|$dst, $src}", [], IIC_MOVS>;
1395 // These uses the DF flag in the EFLAGS register to inc or dec EDI and ESI
1396 let Defs = [EDI], Uses = [AL,EDI,EFLAGS] in
1397 def STOSB : I<0xAA, RawFrmDst, (outs), (ins dstidx8:$dst),
1398 "stosb\t{%al, $dst|$dst, al}", [], IIC_STOS>;
1399 let Defs = [EDI], Uses = [AX,EDI,EFLAGS] in
1400 def STOSW : I<0xAB, RawFrmDst, (outs), (ins dstidx16:$dst),
1401 "stosw\t{%ax, $dst|$dst, ax}", [], IIC_STOS>, OpSize16;
1402 let Defs = [EDI], Uses = [EAX,EDI,EFLAGS] in
1403 def STOSL : I<0xAB, RawFrmDst, (outs), (ins dstidx32:$dst),
1404 "stos{l|d}\t{%eax, $dst|$dst, eax}", [], IIC_STOS>, OpSize32;
1405 let Defs = [RDI], Uses = [RAX,RDI,EFLAGS] in
1406 def STOSQ : RI<0xAB, RawFrmDst, (outs), (ins dstidx64:$dst),
1407 "stosq\t{%rax, $dst|$dst, rax}", [], IIC_STOS>;
1409 // These uses the DF flag in the EFLAGS register to inc or dec EDI and ESI
1410 let Defs = [EDI,EFLAGS], Uses = [AL,EDI,EFLAGS] in
1411 def SCASB : I<0xAE, RawFrmDst, (outs), (ins dstidx8:$dst),
1412 "scasb\t{$dst, %al|al, $dst}", [], IIC_SCAS>;
1413 let Defs = [EDI,EFLAGS], Uses = [AX,EDI,EFLAGS] in
1414 def SCASW : I<0xAF, RawFrmDst, (outs), (ins dstidx16:$dst),
1415 "scasw\t{$dst, %ax|ax, $dst}", [], IIC_SCAS>, OpSize16;
1416 let Defs = [EDI,EFLAGS], Uses = [EAX,EDI,EFLAGS] in
1417 def SCASL : I<0xAF, RawFrmDst, (outs), (ins dstidx32:$dst),
1418 "scas{l|d}\t{$dst, %eax|eax, $dst}", [], IIC_SCAS>, OpSize32;
1419 let Defs = [EDI,EFLAGS], Uses = [RAX,EDI,EFLAGS] in
1420 def SCASQ : RI<0xAF, RawFrmDst, (outs), (ins dstidx64:$dst),
1421 "scasq\t{$dst, %rax|rax, $dst}", [], IIC_SCAS>;
1423 // These uses the DF flag in the EFLAGS register to inc or dec EDI and ESI
1424 let Defs = [EDI,ESI,EFLAGS], Uses = [EDI,ESI,EFLAGS] in {
1425 def CMPSB : I<0xA6, RawFrmDstSrc, (outs), (ins dstidx8:$dst, srcidx8:$src),
1426 "cmpsb\t{$dst, $src|$src, $dst}", [], IIC_CMPS>;
1427 def CMPSW : I<0xA7, RawFrmDstSrc, (outs), (ins dstidx16:$dst, srcidx16:$src),
1428 "cmpsw\t{$dst, $src|$src, $dst}", [], IIC_CMPS>, OpSize16;
1429 def CMPSL : I<0xA7, RawFrmDstSrc, (outs), (ins dstidx32:$dst, srcidx32:$src),
1430 "cmps{l|d}\t{$dst, $src|$src, $dst}", [], IIC_CMPS>, OpSize32;
1431 def CMPSQ : RI<0xA7, RawFrmDstSrc, (outs), (ins dstidx64:$dst, srcidx64:$src),
1432 "cmpsq\t{$dst, $src|$src, $dst}", [], IIC_CMPS>;
1436 //===----------------------------------------------------------------------===//
1437 // Move Instructions.
1439 let SchedRW = [WriteMove] in {
1440 let hasSideEffects = 0 in {
1441 def MOV8rr : I<0x88, MRMDestReg, (outs GR8 :$dst), (ins GR8 :$src),
1442 "mov{b}\t{$src, $dst|$dst, $src}", [], IIC_MOV>;
1443 def MOV16rr : I<0x89, MRMDestReg, (outs GR16:$dst), (ins GR16:$src),
1444 "mov{w}\t{$src, $dst|$dst, $src}", [], IIC_MOV>, OpSize16;
1445 def MOV32rr : I<0x89, MRMDestReg, (outs GR32:$dst), (ins GR32:$src),
1446 "mov{l}\t{$src, $dst|$dst, $src}", [], IIC_MOV>, OpSize32;
1447 def MOV64rr : RI<0x89, MRMDestReg, (outs GR64:$dst), (ins GR64:$src),
1448 "mov{q}\t{$src, $dst|$dst, $src}", [], IIC_MOV>;
1451 let isReMaterializable = 1, isAsCheapAsAMove = 1 in {
1452 def MOV8ri : Ii8 <0xB0, AddRegFrm, (outs GR8 :$dst), (ins i8imm :$src),
1453 "mov{b}\t{$src, $dst|$dst, $src}",
1454 [(set GR8:$dst, imm:$src)], IIC_MOV>;
1455 def MOV16ri : Ii16<0xB8, AddRegFrm, (outs GR16:$dst), (ins i16imm:$src),
1456 "mov{w}\t{$src, $dst|$dst, $src}",
1457 [(set GR16:$dst, imm:$src)], IIC_MOV>, OpSize16;
1458 def MOV32ri : Ii32<0xB8, AddRegFrm, (outs GR32:$dst), (ins i32imm:$src),
1459 "mov{l}\t{$src, $dst|$dst, $src}",
1460 [(set GR32:$dst, relocImm:$src)], IIC_MOV>, OpSize32;
1461 def MOV64ri32 : RIi32S<0xC7, MRM0r, (outs GR64:$dst), (ins i64i32imm:$src),
1462 "mov{q}\t{$src, $dst|$dst, $src}",
1463 [(set GR64:$dst, i64immSExt32:$src)], IIC_MOV>;
1465 let isReMaterializable = 1 in {
1466 def MOV64ri : RIi64<0xB8, AddRegFrm, (outs GR64:$dst), (ins i64imm:$src),
1467 "movabs{q}\t{$src, $dst|$dst, $src}",
1468 [(set GR64:$dst, relocImm:$src)], IIC_MOV>;
1471 // Longer forms that use a ModR/M byte. Needed for disassembler
1472 let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0 in {
1473 def MOV8ri_alt : Ii8 <0xC6, MRM0r, (outs GR8 :$dst), (ins i8imm :$src),
1474 "mov{b}\t{$src, $dst|$dst, $src}", [], IIC_MOV>,
1475 FoldGenData<"MOV8ri">;
1476 def MOV16ri_alt : Ii16<0xC7, MRM0r, (outs GR16:$dst), (ins i16imm:$src),
1477 "mov{w}\t{$src, $dst|$dst, $src}", [], IIC_MOV>, OpSize16,
1478 FoldGenData<"MOV16ri">;
1479 def MOV32ri_alt : Ii32<0xC7, MRM0r, (outs GR32:$dst), (ins i32imm:$src),
1480 "mov{l}\t{$src, $dst|$dst, $src}", [], IIC_MOV>, OpSize32,
1481 FoldGenData<"MOV32ri">;
1485 let SchedRW = [WriteStore] in {
1486 def MOV8mi : Ii8 <0xC6, MRM0m, (outs), (ins i8mem :$dst, i8imm :$src),
1487 "mov{b}\t{$src, $dst|$dst, $src}",
1488 [(store (i8 imm8_su:$src), addr:$dst)], IIC_MOV_MEM>;
1489 def MOV16mi : Ii16<0xC7, MRM0m, (outs), (ins i16mem:$dst, i16imm:$src),
1490 "mov{w}\t{$src, $dst|$dst, $src}",
1491 [(store (i16 imm16_su:$src), addr:$dst)], IIC_MOV_MEM>, OpSize16;
1492 def MOV32mi : Ii32<0xC7, MRM0m, (outs), (ins i32mem:$dst, i32imm:$src),
1493 "mov{l}\t{$src, $dst|$dst, $src}",
1494 [(store (i32 imm32_su:$src), addr:$dst)], IIC_MOV_MEM>, OpSize32;
1495 def MOV64mi32 : RIi32S<0xC7, MRM0m, (outs), (ins i64mem:$dst, i64i32imm:$src),
1496 "mov{q}\t{$src, $dst|$dst, $src}",
1497 [(store i64immSExt32_su:$src, addr:$dst)], IIC_MOV_MEM>,
1498 Requires<[In64BitMode]>;
1501 let hasSideEffects = 0 in {
1503 /// Memory offset versions of moves. The immediate is an address mode sized
1504 /// offset from the segment base.
1505 let SchedRW = [WriteALU] in {
1506 let mayLoad = 1 in {
1508 def MOV8ao32 : Ii32<0xA0, RawFrmMemOffs, (outs), (ins offset32_8:$src),
1509 "mov{b}\t{$src, %al|al, $src}", [], IIC_MOV_MEM>,
1512 def MOV16ao32 : Ii32<0xA1, RawFrmMemOffs, (outs), (ins offset32_16:$src),
1513 "mov{w}\t{$src, %ax|ax, $src}", [], IIC_MOV_MEM>,
1516 def MOV32ao32 : Ii32<0xA1, RawFrmMemOffs, (outs), (ins offset32_32:$src),
1517 "mov{l}\t{$src, %eax|eax, $src}", [], IIC_MOV_MEM>,
1520 def MOV64ao32 : RIi32<0xA1, RawFrmMemOffs, (outs), (ins offset32_64:$src),
1521 "mov{q}\t{$src, %rax|rax, $src}", [], IIC_MOV_MEM>,
1525 def MOV8ao16 : Ii16<0xA0, RawFrmMemOffs, (outs), (ins offset16_8:$src),
1526 "mov{b}\t{$src, %al|al, $src}", [], IIC_MOV_MEM>, AdSize16;
1528 def MOV16ao16 : Ii16<0xA1, RawFrmMemOffs, (outs), (ins offset16_16:$src),
1529 "mov{w}\t{$src, %ax|ax, $src}", [], IIC_MOV_MEM>,
1532 def MOV32ao16 : Ii16<0xA1, RawFrmMemOffs, (outs), (ins offset16_32:$src),
1533 "mov{l}\t{$src, %eax|eax, $src}", [], IIC_MOV_MEM>,
1536 let mayStore = 1 in {
1538 def MOV8o32a : Ii32<0xA2, RawFrmMemOffs, (outs), (ins offset32_8:$dst),
1539 "mov{b}\t{%al, $dst|$dst, al}", [], IIC_MOV_MEM>, AdSize32;
1541 def MOV16o32a : Ii32<0xA3, RawFrmMemOffs, (outs), (ins offset32_16:$dst),
1542 "mov{w}\t{%ax, $dst|$dst, ax}", [], IIC_MOV_MEM>,
1545 def MOV32o32a : Ii32<0xA3, RawFrmMemOffs, (outs), (ins offset32_32:$dst),
1546 "mov{l}\t{%eax, $dst|$dst, eax}", [], IIC_MOV_MEM>,
1549 def MOV64o32a : RIi32<0xA3, RawFrmMemOffs, (outs), (ins offset32_64:$dst),
1550 "mov{q}\t{%rax, $dst|$dst, rax}", [], IIC_MOV_MEM>,
1554 def MOV8o16a : Ii16<0xA2, RawFrmMemOffs, (outs), (ins offset16_8:$dst),
1555 "mov{b}\t{%al, $dst|$dst, al}", [], IIC_MOV_MEM>, AdSize16;
1557 def MOV16o16a : Ii16<0xA3, RawFrmMemOffs, (outs), (ins offset16_16:$dst),
1558 "mov{w}\t{%ax, $dst|$dst, ax}", [], IIC_MOV_MEM>,
1561 def MOV32o16a : Ii16<0xA3, RawFrmMemOffs, (outs), (ins offset16_32:$dst),
1562 "mov{l}\t{%eax, $dst|$dst, eax}", [], IIC_MOV_MEM>,
1567 // These forms all have full 64-bit absolute addresses in their instructions
1568 // and use the movabs mnemonic to indicate this specific form.
1569 let mayLoad = 1 in {
1571 def MOV8ao64 : RIi64_NOREX<0xA0, RawFrmMemOffs, (outs), (ins offset64_8:$src),
1572 "movabs{b}\t{$src, %al|al, $src}", [], IIC_MOV_MEM>,
1575 def MOV16ao64 : RIi64_NOREX<0xA1, RawFrmMemOffs, (outs), (ins offset64_16:$src),
1576 "movabs{w}\t{$src, %ax|ax, $src}", [], IIC_MOV_MEM>,
1579 def MOV32ao64 : RIi64_NOREX<0xA1, RawFrmMemOffs, (outs), (ins offset64_32:$src),
1580 "movabs{l}\t{$src, %eax|eax, $src}", [], IIC_MOV_MEM>,
1583 def MOV64ao64 : RIi64<0xA1, RawFrmMemOffs, (outs), (ins offset64_64:$src),
1584 "movabs{q}\t{$src, %rax|rax, $src}", [], IIC_MOV_MEM>,
1588 let mayStore = 1 in {
1590 def MOV8o64a : RIi64_NOREX<0xA2, RawFrmMemOffs, (outs), (ins offset64_8:$dst),
1591 "movabs{b}\t{%al, $dst|$dst, al}", [], IIC_MOV_MEM>,
1594 def MOV16o64a : RIi64_NOREX<0xA3, RawFrmMemOffs, (outs), (ins offset64_16:$dst),
1595 "movabs{w}\t{%ax, $dst|$dst, ax}", [], IIC_MOV_MEM>,
1598 def MOV32o64a : RIi64_NOREX<0xA3, RawFrmMemOffs, (outs), (ins offset64_32:$dst),
1599 "movabs{l}\t{%eax, $dst|$dst, eax}", [], IIC_MOV_MEM>,
1602 def MOV64o64a : RIi64<0xA3, RawFrmMemOffs, (outs), (ins offset64_64:$dst),
1603 "movabs{q}\t{%rax, $dst|$dst, rax}", [], IIC_MOV_MEM>,
1606 } // hasSideEffects = 0
1608 let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0,
1609 SchedRW = [WriteMove] in {
1610 def MOV8rr_REV : I<0x8A, MRMSrcReg, (outs GR8:$dst), (ins GR8:$src),
1611 "mov{b}\t{$src, $dst|$dst, $src}", [], IIC_MOV>,
1612 FoldGenData<"MOV8rr">;
1613 def MOV16rr_REV : I<0x8B, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
1614 "mov{w}\t{$src, $dst|$dst, $src}", [], IIC_MOV>, OpSize16,
1615 FoldGenData<"MOV16rr">;
1616 def MOV32rr_REV : I<0x8B, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
1617 "mov{l}\t{$src, $dst|$dst, $src}", [], IIC_MOV>, OpSize32,
1618 FoldGenData<"MOV32rr">;
1619 def MOV64rr_REV : RI<0x8B, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
1620 "mov{q}\t{$src, $dst|$dst, $src}", [], IIC_MOV>,
1621 FoldGenData<"MOV64rr">;
1624 let canFoldAsLoad = 1, isReMaterializable = 1, SchedRW = [WriteLoad] in {
1625 def MOV8rm : I<0x8A, MRMSrcMem, (outs GR8 :$dst), (ins i8mem :$src),
1626 "mov{b}\t{$src, $dst|$dst, $src}",
1627 [(set GR8:$dst, (loadi8 addr:$src))], IIC_MOV_MEM>;
1628 def MOV16rm : I<0x8B, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
1629 "mov{w}\t{$src, $dst|$dst, $src}",
1630 [(set GR16:$dst, (loadi16 addr:$src))], IIC_MOV_MEM>, OpSize16;
1631 def MOV32rm : I<0x8B, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
1632 "mov{l}\t{$src, $dst|$dst, $src}",
1633 [(set GR32:$dst, (loadi32 addr:$src))], IIC_MOV_MEM>, OpSize32;
1634 def MOV64rm : RI<0x8B, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
1635 "mov{q}\t{$src, $dst|$dst, $src}",
1636 [(set GR64:$dst, (load addr:$src))], IIC_MOV_MEM>;
1639 let SchedRW = [WriteStore] in {
1640 def MOV8mr : I<0x88, MRMDestMem, (outs), (ins i8mem :$dst, GR8 :$src),
1641 "mov{b}\t{$src, $dst|$dst, $src}",
1642 [(store GR8:$src, addr:$dst)], IIC_MOV_MEM>;
1643 def MOV16mr : I<0x89, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src),
1644 "mov{w}\t{$src, $dst|$dst, $src}",
1645 [(store GR16:$src, addr:$dst)], IIC_MOV_MEM>, OpSize16;
1646 def MOV32mr : I<0x89, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
1647 "mov{l}\t{$src, $dst|$dst, $src}",
1648 [(store GR32:$src, addr:$dst)], IIC_MOV_MEM>, OpSize32;
1649 def MOV64mr : RI<0x89, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
1650 "mov{q}\t{$src, $dst|$dst, $src}",
1651 [(store GR64:$src, addr:$dst)], IIC_MOV_MEM>;
1654 // Versions of MOV8rr, MOV8mr, and MOV8rm that use i8mem_NOREX and GR8_NOREX so
1655 // that they can be used for copying and storing h registers, which can't be
1656 // encoded when a REX prefix is present.
1657 let isCodeGenOnly = 1 in {
1658 let hasSideEffects = 0 in
1659 def MOV8rr_NOREX : I<0x88, MRMDestReg,
1660 (outs GR8_NOREX:$dst), (ins GR8_NOREX:$src),
1661 "mov{b}\t{$src, $dst|$dst, $src} # NOREX", [], IIC_MOV>,
1663 let mayStore = 1, hasSideEffects = 0 in
1664 def MOV8mr_NOREX : I<0x88, MRMDestMem,
1665 (outs), (ins i8mem_NOREX:$dst, GR8_NOREX:$src),
1666 "mov{b}\t{$src, $dst|$dst, $src} # NOREX", [],
1667 IIC_MOV_MEM>, Sched<[WriteStore]>;
1668 let mayLoad = 1, hasSideEffects = 0,
1669 canFoldAsLoad = 1, isReMaterializable = 1 in
1670 def MOV8rm_NOREX : I<0x8A, MRMSrcMem,
1671 (outs GR8_NOREX:$dst), (ins i8mem_NOREX:$src),
1672 "mov{b}\t{$src, $dst|$dst, $src} # NOREX", [],
1673 IIC_MOV_MEM>, Sched<[WriteLoad]>;
1677 // Condition code ops, incl. set if equal/not equal/...
1678 let SchedRW = [WriteALU] in {
1679 let Defs = [EFLAGS], Uses = [AH] in
1680 def SAHF : I<0x9E, RawFrm, (outs), (ins), "sahf",
1681 [(set EFLAGS, (X86sahf AH))], IIC_AHF>,
1682 Requires<[HasLAHFSAHF]>;
1683 let Defs = [AH], Uses = [EFLAGS], hasSideEffects = 0 in
1684 def LAHF : I<0x9F, RawFrm, (outs), (ins), "lahf", [],
1685 IIC_AHF>, // AH = flags
1686 Requires<[HasLAHFSAHF]>;
1689 //===----------------------------------------------------------------------===//
1690 // Bit tests instructions: BT, BTS, BTR, BTC.
1692 let Defs = [EFLAGS] in {
1693 let SchedRW = [WriteALU] in {
1694 def BT16rr : I<0xA3, MRMDestReg, (outs), (ins GR16:$src1, GR16:$src2),
1695 "bt{w}\t{$src2, $src1|$src1, $src2}",
1696 [(set EFLAGS, (X86bt GR16:$src1, GR16:$src2))], IIC_BT_RR>,
1697 OpSize16, TB, NotMemoryFoldable;
1698 def BT32rr : I<0xA3, MRMDestReg, (outs), (ins GR32:$src1, GR32:$src2),
1699 "bt{l}\t{$src2, $src1|$src1, $src2}",
1700 [(set EFLAGS, (X86bt GR32:$src1, GR32:$src2))], IIC_BT_RR>,
1701 OpSize32, TB, NotMemoryFoldable;
1702 def BT64rr : RI<0xA3, MRMDestReg, (outs), (ins GR64:$src1, GR64:$src2),
1703 "bt{q}\t{$src2, $src1|$src1, $src2}",
1704 [(set EFLAGS, (X86bt GR64:$src1, GR64:$src2))], IIC_BT_RR>, TB,
1708 // Unlike with the register+register form, the memory+register form of the
1709 // bt instruction does not ignore the high bits of the index. From ISel's
1710 // perspective, this is pretty bizarre. Make these instructions disassembly
1711 // only for now. These instructions are also slow on modern CPUs so that's
1712 // another reason to avoid generating them.
1714 let mayLoad = 1, hasSideEffects = 0, SchedRW = [WriteALULd] in {
1715 def BT16mr : I<0xA3, MRMDestMem, (outs), (ins i16mem:$src1, GR16:$src2),
1716 "bt{w}\t{$src2, $src1|$src1, $src2}",
1718 >, OpSize16, TB, NotMemoryFoldable;
1719 def BT32mr : I<0xA3, MRMDestMem, (outs), (ins i32mem:$src1, GR32:$src2),
1720 "bt{l}\t{$src2, $src1|$src1, $src2}",
1722 >, OpSize32, TB, NotMemoryFoldable;
1723 def BT64mr : RI<0xA3, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2),
1724 "bt{q}\t{$src2, $src1|$src1, $src2}",
1726 >, TB, NotMemoryFoldable;
1729 let SchedRW = [WriteALU] in {
1730 def BT16ri8 : Ii8<0xBA, MRM4r, (outs), (ins GR16:$src1, i16i8imm:$src2),
1731 "bt{w}\t{$src2, $src1|$src1, $src2}",
1732 [(set EFLAGS, (X86bt GR16:$src1, i16immSExt8:$src2))],
1733 IIC_BT_RI>, OpSize16, TB;
1734 def BT32ri8 : Ii8<0xBA, MRM4r, (outs), (ins GR32:$src1, i32i8imm:$src2),
1735 "bt{l}\t{$src2, $src1|$src1, $src2}",
1736 [(set EFLAGS, (X86bt GR32:$src1, i32immSExt8:$src2))],
1737 IIC_BT_RI>, OpSize32, TB;
1738 def BT64ri8 : RIi8<0xBA, MRM4r, (outs), (ins GR64:$src1, i64i8imm:$src2),
1739 "bt{q}\t{$src2, $src1|$src1, $src2}",
1740 [(set EFLAGS, (X86bt GR64:$src1, i64immSExt8:$src2))],
1744 // Note that these instructions aren't slow because that only applies when the
1745 // other operand is in a register. When it's an immediate, bt is still fast.
1746 let SchedRW = [WriteALU] in {
1747 def BT16mi8 : Ii8<0xBA, MRM4m, (outs), (ins i16mem:$src1, i16i8imm:$src2),
1748 "bt{w}\t{$src2, $src1|$src1, $src2}",
1749 [(set EFLAGS, (X86bt (loadi16 addr:$src1), i16immSExt8:$src2))
1750 ], IIC_BT_MI>, OpSize16, TB;
1751 def BT32mi8 : Ii8<0xBA, MRM4m, (outs), (ins i32mem:$src1, i32i8imm:$src2),
1752 "bt{l}\t{$src2, $src1|$src1, $src2}",
1753 [(set EFLAGS, (X86bt (loadi32 addr:$src1), i32immSExt8:$src2))
1754 ], IIC_BT_MI>, OpSize32, TB;
1755 def BT64mi8 : RIi8<0xBA, MRM4m, (outs), (ins i64mem:$src1, i64i8imm:$src2),
1756 "bt{q}\t{$src2, $src1|$src1, $src2}",
1757 [(set EFLAGS, (X86bt (loadi64 addr:$src1),
1758 i64immSExt8:$src2))], IIC_BT_MI>, TB,
1759 Requires<[In64BitMode]>;
1762 let hasSideEffects = 0 in {
1763 let SchedRW = [WriteALU], Constraints = "$src1 = $dst" in {
1764 def BTC16rr : I<0xBB, MRMDestReg, (outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
1765 "btc{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>,
1766 OpSize16, TB, NotMemoryFoldable;
1767 def BTC32rr : I<0xBB, MRMDestReg, (outs GR32:$dst), (ins GR32:$src1, GR32:$src2),
1768 "btc{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>,
1769 OpSize32, TB, NotMemoryFoldable;
1770 def BTC64rr : RI<0xBB, MRMDestReg, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
1771 "btc{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>, TB,
1775 let mayLoad = 1, mayStore = 1, SchedRW = [WriteALULd, WriteRMW] in {
1776 def BTC16mr : I<0xBB, MRMDestMem, (outs), (ins i16mem:$src1, GR16:$src2),
1777 "btc{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>,
1778 OpSize16, TB, NotMemoryFoldable;
1779 def BTC32mr : I<0xBB, MRMDestMem, (outs), (ins i32mem:$src1, GR32:$src2),
1780 "btc{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>,
1781 OpSize32, TB, NotMemoryFoldable;
1782 def BTC64mr : RI<0xBB, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2),
1783 "btc{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>, TB,
1787 let SchedRW = [WriteALU], Constraints = "$src1 = $dst" in {
1788 def BTC16ri8 : Ii8<0xBA, MRM7r, (outs GR16:$dst), (ins GR16:$src1, i16i8imm:$src2),
1789 "btc{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>,
1791 def BTC32ri8 : Ii8<0xBA, MRM7r, (outs GR32:$dst), (ins GR32:$src1, i32i8imm:$src2),
1792 "btc{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>,
1794 def BTC64ri8 : RIi8<0xBA, MRM7r, (outs GR64:$dst), (ins GR64:$src1, i64i8imm:$src2),
1795 "btc{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>, TB;
1798 let mayLoad = 1, mayStore = 1, SchedRW = [WriteALULd, WriteRMW] in {
1799 def BTC16mi8 : Ii8<0xBA, MRM7m, (outs), (ins i16mem:$src1, i16i8imm:$src2),
1800 "btc{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>,
1802 def BTC32mi8 : Ii8<0xBA, MRM7m, (outs), (ins i32mem:$src1, i32i8imm:$src2),
1803 "btc{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>,
1805 def BTC64mi8 : RIi8<0xBA, MRM7m, (outs), (ins i64mem:$src1, i64i8imm:$src2),
1806 "btc{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>, TB,
1807 Requires<[In64BitMode]>;
1810 let SchedRW = [WriteALU], Constraints = "$src1 = $dst" in {
1811 def BTR16rr : I<0xB3, MRMDestReg, (outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
1812 "btr{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>,
1813 OpSize16, TB, NotMemoryFoldable;
1814 def BTR32rr : I<0xB3, MRMDestReg, (outs GR32:$dst), (ins GR32:$src1, GR32:$src2),
1815 "btr{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>,
1816 OpSize32, TB, NotMemoryFoldable;
1817 def BTR64rr : RI<0xB3, MRMDestReg, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
1818 "btr{q}\t{$src2, $src1|$src1, $src2}", []>, TB, NotMemoryFoldable;
1821 let mayLoad = 1, mayStore = 1, SchedRW = [WriteALULd, WriteRMW] in {
1822 def BTR16mr : I<0xB3, MRMDestMem, (outs), (ins i16mem:$src1, GR16:$src2),
1823 "btr{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>,
1824 OpSize16, TB, NotMemoryFoldable;
1825 def BTR32mr : I<0xB3, MRMDestMem, (outs), (ins i32mem:$src1, GR32:$src2),
1826 "btr{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>,
1827 OpSize32, TB, NotMemoryFoldable;
1828 def BTR64mr : RI<0xB3, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2),
1829 "btr{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>, TB,
1833 let SchedRW = [WriteALU], Constraints = "$src1 = $dst" in {
1834 def BTR16ri8 : Ii8<0xBA, MRM6r, (outs GR16:$dst), (ins GR16:$src1, i16i8imm:$src2),
1835 "btr{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>,
1837 def BTR32ri8 : Ii8<0xBA, MRM6r, (outs GR32:$dst), (ins GR32:$src1, i32i8imm:$src2),
1838 "btr{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>,
1840 def BTR64ri8 : RIi8<0xBA, MRM6r, (outs GR64:$dst), (ins GR64:$src1, i64i8imm:$src2),
1841 "btr{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>, TB;
1844 let mayLoad = 1, mayStore = 1, SchedRW = [WriteALULd, WriteRMW] in {
1845 def BTR16mi8 : Ii8<0xBA, MRM6m, (outs), (ins i16mem:$src1, i16i8imm:$src2),
1846 "btr{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>,
1848 def BTR32mi8 : Ii8<0xBA, MRM6m, (outs), (ins i32mem:$src1, i32i8imm:$src2),
1849 "btr{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>,
1851 def BTR64mi8 : RIi8<0xBA, MRM6m, (outs), (ins i64mem:$src1, i64i8imm:$src2),
1852 "btr{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>, TB,
1853 Requires<[In64BitMode]>;
1856 let SchedRW = [WriteALU], Constraints = "$src1 = $dst" in {
1857 def BTS16rr : I<0xAB, MRMDestReg, (outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
1858 "bts{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>,
1859 OpSize16, TB, NotMemoryFoldable;
1860 def BTS32rr : I<0xAB, MRMDestReg, (outs GR32:$dst), (ins GR32:$src1, GR32:$src2),
1861 "bts{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>,
1862 OpSize32, TB, NotMemoryFoldable;
1863 def BTS64rr : RI<0xAB, MRMDestReg, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
1864 "bts{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>, TB,
1868 let mayLoad = 1, mayStore = 1, SchedRW = [WriteALULd, WriteRMW] in {
1869 def BTS16mr : I<0xAB, MRMDestMem, (outs), (ins i16mem:$src1, GR16:$src2),
1870 "bts{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>,
1871 OpSize16, TB, NotMemoryFoldable;
1872 def BTS32mr : I<0xAB, MRMDestMem, (outs), (ins i32mem:$src1, GR32:$src2),
1873 "bts{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>,
1874 OpSize32, TB, NotMemoryFoldable;
1875 def BTS64mr : RI<0xAB, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2),
1876 "bts{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>, TB,
1880 let SchedRW = [WriteALU], Constraints = "$src1 = $dst" in {
1881 def BTS16ri8 : Ii8<0xBA, MRM5r, (outs GR16:$dst), (ins GR16:$src1, i16i8imm:$src2),
1882 "bts{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>,
1884 def BTS32ri8 : Ii8<0xBA, MRM5r, (outs GR32:$dst), (ins GR32:$src1, i32i8imm:$src2),
1885 "bts{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>,
1887 def BTS64ri8 : RIi8<0xBA, MRM5r, (outs GR64:$dst), (ins GR64:$src1, i64i8imm:$src2),
1888 "bts{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>, TB;
1891 let mayLoad = 1, mayStore = 1, SchedRW = [WriteALULd, WriteRMW] in {
1892 def BTS16mi8 : Ii8<0xBA, MRM5m, (outs), (ins i16mem:$src1, i16i8imm:$src2),
1893 "bts{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>,
1895 def BTS32mi8 : Ii8<0xBA, MRM5m, (outs), (ins i32mem:$src1, i32i8imm:$src2),
1896 "bts{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>,
1898 def BTS64mi8 : RIi8<0xBA, MRM5m, (outs), (ins i64mem:$src1, i64i8imm:$src2),
1899 "bts{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>, TB,
1900 Requires<[In64BitMode]>;
1902 } // hasSideEffects = 0
1903 } // Defs = [EFLAGS]
1906 //===----------------------------------------------------------------------===//
1910 // Atomic swap. These are just normal xchg instructions. But since a memory
1911 // operand is referenced, the atomicity is ensured.
1912 multiclass ATOMIC_SWAP<bits<8> opc8, bits<8> opc, string mnemonic, string frag,
1913 InstrItinClass itin> {
1914 let Constraints = "$val = $dst", SchedRW = [WriteALULd, WriteRMW] in {
1915 def NAME#8rm : I<opc8, MRMSrcMem, (outs GR8:$dst),
1916 (ins GR8:$val, i8mem:$ptr),
1917 !strconcat(mnemonic, "{b}\t{$val, $ptr|$ptr, $val}"),
1920 (!cast<PatFrag>(frag # "_8") addr:$ptr, GR8:$val))],
1922 def NAME#16rm : I<opc, MRMSrcMem, (outs GR16:$dst),
1923 (ins GR16:$val, i16mem:$ptr),
1924 !strconcat(mnemonic, "{w}\t{$val, $ptr|$ptr, $val}"),
1927 (!cast<PatFrag>(frag # "_16") addr:$ptr, GR16:$val))],
1929 def NAME#32rm : I<opc, MRMSrcMem, (outs GR32:$dst),
1930 (ins GR32:$val, i32mem:$ptr),
1931 !strconcat(mnemonic, "{l}\t{$val, $ptr|$ptr, $val}"),
1934 (!cast<PatFrag>(frag # "_32") addr:$ptr, GR32:$val))],
1936 def NAME#64rm : RI<opc, MRMSrcMem, (outs GR64:$dst),
1937 (ins GR64:$val, i64mem:$ptr),
1938 !strconcat(mnemonic, "{q}\t{$val, $ptr|$ptr, $val}"),
1941 (!cast<PatFrag>(frag # "_64") addr:$ptr, GR64:$val))],
1946 defm XCHG : ATOMIC_SWAP<0x86, 0x87, "xchg", "atomic_swap", IIC_XCHG_MEM>;
1948 // Swap between registers.
1949 let SchedRW = [WriteALU] in {
1950 let Constraints = "$val = $dst" in {
1951 def XCHG8rr : I<0x86, MRMSrcReg, (outs GR8:$dst), (ins GR8:$val, GR8:$src),
1952 "xchg{b}\t{$val, $src|$src, $val}", [], IIC_XCHG_REG>;
1953 def XCHG16rr : I<0x87, MRMSrcReg, (outs GR16:$dst), (ins GR16:$val, GR16:$src),
1954 "xchg{w}\t{$val, $src|$src, $val}", [], IIC_XCHG_REG>,
1956 def XCHG32rr : I<0x87, MRMSrcReg, (outs GR32:$dst), (ins GR32:$val, GR32:$src),
1957 "xchg{l}\t{$val, $src|$src, $val}", [], IIC_XCHG_REG>,
1959 def XCHG64rr : RI<0x87, MRMSrcReg, (outs GR64:$dst), (ins GR64:$val,GR64:$src),
1960 "xchg{q}\t{$val, $src|$src, $val}", [], IIC_XCHG_REG>;
1963 // Swap between EAX and other registers.
1964 let Uses = [AX], Defs = [AX] in
1965 def XCHG16ar : I<0x90, AddRegFrm, (outs), (ins GR16:$src),
1966 "xchg{w}\t{$src, %ax|ax, $src}", [], IIC_XCHG_REG>, OpSize16;
1967 let Uses = [EAX], Defs = [EAX] in
1968 def XCHG32ar : I<0x90, AddRegFrm, (outs), (ins GR32:$src),
1969 "xchg{l}\t{$src, %eax|eax, $src}", [], IIC_XCHG_REG>,
1970 OpSize32, Requires<[Not64BitMode]>;
1971 let Uses = [EAX], Defs = [EAX] in
1972 // Uses GR32_NOAX in 64-bit mode to prevent encoding using the 0x90 NOP encoding.
1973 // xchg %eax, %eax needs to clear upper 32-bits of RAX so is not a NOP.
1974 def XCHG32ar64 : I<0x90, AddRegFrm, (outs), (ins GR32_NOAX:$src),
1975 "xchg{l}\t{$src, %eax|eax, $src}", [], IIC_XCHG_REG>,
1976 OpSize32, Requires<[In64BitMode]>;
1977 let Uses = [RAX], Defs = [RAX] in
1978 def XCHG64ar : RI<0x90, AddRegFrm, (outs), (ins GR64:$src),
1979 "xchg{q}\t{$src, %rax|rax, $src}", [], IIC_XCHG_REG>;
1982 let SchedRW = [WriteALU] in {
1983 def XADD8rr : I<0xC0, MRMDestReg, (outs GR8:$dst), (ins GR8:$src),
1984 "xadd{b}\t{$src, $dst|$dst, $src}", [], IIC_XADD_REG>, TB;
1985 def XADD16rr : I<0xC1, MRMDestReg, (outs GR16:$dst), (ins GR16:$src),
1986 "xadd{w}\t{$src, $dst|$dst, $src}", [], IIC_XADD_REG>, TB,
1988 def XADD32rr : I<0xC1, MRMDestReg, (outs GR32:$dst), (ins GR32:$src),
1989 "xadd{l}\t{$src, $dst|$dst, $src}", [], IIC_XADD_REG>, TB,
1991 def XADD64rr : RI<0xC1, MRMDestReg, (outs GR64:$dst), (ins GR64:$src),
1992 "xadd{q}\t{$src, $dst|$dst, $src}", [], IIC_XADD_REG>, TB;
1995 let mayLoad = 1, mayStore = 1, SchedRW = [WriteALULd, WriteRMW] in {
1996 def XADD8rm : I<0xC0, MRMDestMem, (outs), (ins i8mem:$dst, GR8:$src),
1997 "xadd{b}\t{$src, $dst|$dst, $src}", [], IIC_XADD_MEM>, TB;
1998 def XADD16rm : I<0xC1, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src),
1999 "xadd{w}\t{$src, $dst|$dst, $src}", [], IIC_XADD_MEM>, TB,
2001 def XADD32rm : I<0xC1, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
2002 "xadd{l}\t{$src, $dst|$dst, $src}", [], IIC_XADD_MEM>, TB,
2004 def XADD64rm : RI<0xC1, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
2005 "xadd{q}\t{$src, $dst|$dst, $src}", [], IIC_XADD_MEM>, TB;
2009 let SchedRW = [WriteALU] in {
2010 def CMPXCHG8rr : I<0xB0, MRMDestReg, (outs GR8:$dst), (ins GR8:$src),
2011 "cmpxchg{b}\t{$src, $dst|$dst, $src}", [],
2012 IIC_CMPXCHG_REG8>, TB;
2013 def CMPXCHG16rr : I<0xB1, MRMDestReg, (outs GR16:$dst), (ins GR16:$src),
2014 "cmpxchg{w}\t{$src, $dst|$dst, $src}", [],
2015 IIC_CMPXCHG_REG>, TB, OpSize16;
2016 def CMPXCHG32rr : I<0xB1, MRMDestReg, (outs GR32:$dst), (ins GR32:$src),
2017 "cmpxchg{l}\t{$src, $dst|$dst, $src}", [],
2018 IIC_CMPXCHG_REG>, TB, OpSize32;
2019 def CMPXCHG64rr : RI<0xB1, MRMDestReg, (outs GR64:$dst), (ins GR64:$src),
2020 "cmpxchg{q}\t{$src, $dst|$dst, $src}", [],
2021 IIC_CMPXCHG_REG>, TB;
2024 let SchedRW = [WriteALULd, WriteRMW] in {
2025 let mayLoad = 1, mayStore = 1 in {
2026 def CMPXCHG8rm : I<0xB0, MRMDestMem, (outs), (ins i8mem:$dst, GR8:$src),
2027 "cmpxchg{b}\t{$src, $dst|$dst, $src}", [],
2028 IIC_CMPXCHG_MEM8>, TB;
2029 def CMPXCHG16rm : I<0xB1, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src),
2030 "cmpxchg{w}\t{$src, $dst|$dst, $src}", [],
2031 IIC_CMPXCHG_MEM>, TB, OpSize16;
2032 def CMPXCHG32rm : I<0xB1, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
2033 "cmpxchg{l}\t{$src, $dst|$dst, $src}", [],
2034 IIC_CMPXCHG_MEM>, TB, OpSize32;
2035 def CMPXCHG64rm : RI<0xB1, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
2036 "cmpxchg{q}\t{$src, $dst|$dst, $src}", [],
2037 IIC_CMPXCHG_MEM>, TB;
2040 let Defs = [EAX, EDX, EFLAGS], Uses = [EAX, EBX, ECX, EDX] in
2041 def CMPXCHG8B : I<0xC7, MRM1m, (outs), (ins i64mem:$dst),
2042 "cmpxchg8b\t$dst", [], IIC_CMPXCHG_8B>, TB;
2044 let Defs = [RAX, RDX, EFLAGS], Uses = [RAX, RBX, RCX, RDX] in
2045 def CMPXCHG16B : RI<0xC7, MRM1m, (outs), (ins i128mem:$dst),
2046 "cmpxchg16b\t$dst", [], IIC_CMPXCHG_16B>,
2047 TB, Requires<[HasCmpxchg16b, In64BitMode]>;
2051 // Lock instruction prefix
2052 let SchedRW = [WriteMicrocoded] in
2053 def LOCK_PREFIX : I<0xF0, RawFrm, (outs), (ins), "lock", []>;
2055 let SchedRW = [WriteNop] in {
2057 // Rex64 instruction prefix
2058 def REX64_PREFIX : I<0x48, RawFrm, (outs), (ins), "rex64", [], IIC_NOP>,
2059 Requires<[In64BitMode]>;
2061 // Data16 instruction prefix
2062 def DATA16_PREFIX : I<0x66, RawFrm, (outs), (ins), "data16", [], IIC_NOP>,
2063 Requires<[Not16BitMode]>;
2065 // Data instruction prefix
2066 def DATA32_PREFIX : I<0x66, RawFrm, (outs), (ins), "data32", [], IIC_NOP>,
2067 Requires<[In16BitMode]>;
2070 // Repeat string operation instruction prefixes
2071 // These use the DF flag in the EFLAGS register to inc or dec ECX
2072 let Defs = [ECX], Uses = [ECX,EFLAGS], SchedRW = [WriteMicrocoded] in {
2073 // Repeat (used with INS, OUTS, MOVS, LODS and STOS)
2074 def REP_PREFIX : I<0xF3, RawFrm, (outs), (ins), "rep", []>;
2075 // Repeat while not equal (used with CMPS and SCAS)
2076 def REPNE_PREFIX : I<0xF2, RawFrm, (outs), (ins), "repne", []>;
2079 // String manipulation instructions
2080 let SchedRW = [WriteMicrocoded] in {
2081 // These uses the DF flag in the EFLAGS register to inc or dec EDI and ESI
2082 let Defs = [AL,ESI], Uses = [ESI,EFLAGS] in
2083 def LODSB : I<0xAC, RawFrmSrc, (outs), (ins srcidx8:$src),
2084 "lodsb\t{$src, %al|al, $src}", [], IIC_LODS>;
2085 let Defs = [AX,ESI], Uses = [ESI,EFLAGS] in
2086 def LODSW : I<0xAD, RawFrmSrc, (outs), (ins srcidx16:$src),
2087 "lodsw\t{$src, %ax|ax, $src}", [], IIC_LODS>, OpSize16;
2088 let Defs = [EAX,ESI], Uses = [ESI,EFLAGS] in
2089 def LODSL : I<0xAD, RawFrmSrc, (outs), (ins srcidx32:$src),
2090 "lods{l|d}\t{$src, %eax|eax, $src}", [], IIC_LODS>, OpSize32;
2091 let Defs = [RAX,ESI], Uses = [ESI,EFLAGS] in
2092 def LODSQ : RI<0xAD, RawFrmSrc, (outs), (ins srcidx64:$src),
2093 "lodsq\t{$src, %rax|rax, $src}", [], IIC_LODS>;
2096 let SchedRW = [WriteSystem] in {
2097 // These uses the DF flag in the EFLAGS register to inc or dec EDI and ESI
2098 let Defs = [ESI], Uses = [DX,ESI,EFLAGS] in {
2099 def OUTSB : I<0x6E, RawFrmSrc, (outs), (ins srcidx8:$src),
2100 "outsb\t{$src, %dx|dx, $src}", [], IIC_OUTS>;
2101 def OUTSW : I<0x6F, RawFrmSrc, (outs), (ins srcidx16:$src),
2102 "outsw\t{$src, %dx|dx, $src}", [], IIC_OUTS>, OpSize16;
2103 def OUTSL : I<0x6F, RawFrmSrc, (outs), (ins srcidx32:$src),
2104 "outs{l|d}\t{$src, %dx|dx, $src}", [], IIC_OUTS>, OpSize32;
2107 // These uses the DF flag in the EFLAGS register to inc or dec EDI and ESI
2108 let Defs = [EDI], Uses = [DX,EDI,EFLAGS] in {
2109 def INSB : I<0x6C, RawFrmDst, (outs), (ins dstidx8:$dst),
2110 "insb\t{%dx, $dst|$dst, dx}", [], IIC_INS>;
2111 def INSW : I<0x6D, RawFrmDst, (outs), (ins dstidx16:$dst),
2112 "insw\t{%dx, $dst|$dst, dx}", [], IIC_INS>, OpSize16;
2113 def INSL : I<0x6D, RawFrmDst, (outs), (ins dstidx32:$dst),
2114 "ins{l|d}\t{%dx, $dst|$dst, dx}", [], IIC_INS>, OpSize32;
2118 // Flag instructions
2119 let SchedRW = [WriteALU] in {
2120 def CLC : I<0xF8, RawFrm, (outs), (ins), "clc", [], IIC_CLC>;
2121 def STC : I<0xF9, RawFrm, (outs), (ins), "stc", [], IIC_STC>;
2122 def CLI : I<0xFA, RawFrm, (outs), (ins), "cli", [], IIC_CLI>;
2123 def STI : I<0xFB, RawFrm, (outs), (ins), "sti", [], IIC_STI>;
2124 def CLD : I<0xFC, RawFrm, (outs), (ins), "cld", [], IIC_CLD>;
2125 def STD : I<0xFD, RawFrm, (outs), (ins), "std", [], IIC_STD>;
2126 def CMC : I<0xF5, RawFrm, (outs), (ins), "cmc", [], IIC_CMC>;
2128 def CLTS : I<0x06, RawFrm, (outs), (ins), "clts", [], IIC_CLTS>, TB;
2131 // Table lookup instructions
2132 let Uses = [AL,EBX], Defs = [AL], hasSideEffects = 0, mayLoad = 1 in
2133 def XLAT : I<0xD7, RawFrm, (outs), (ins), "xlatb", [], IIC_XLAT>,
2136 let SchedRW = [WriteMicrocoded] in {
2137 // ASCII Adjust After Addition
2138 let Uses = [AL,EFLAGS], Defs = [AX,EFLAGS], hasSideEffects = 0 in
2139 def AAA : I<0x37, RawFrm, (outs), (ins), "aaa", [], IIC_AAA>,
2140 Requires<[Not64BitMode]>;
2142 // ASCII Adjust AX Before Division
2143 let Uses = [AX], Defs = [AX,EFLAGS], hasSideEffects = 0 in
2144 def AAD8i8 : Ii8<0xD5, RawFrm, (outs), (ins i8imm:$src),
2145 "aad\t$src", [], IIC_AAD>, Requires<[Not64BitMode]>;
2147 // ASCII Adjust AX After Multiply
2148 let Uses = [AL], Defs = [AX,EFLAGS], hasSideEffects = 0 in
2149 def AAM8i8 : Ii8<0xD4, RawFrm, (outs), (ins i8imm:$src),
2150 "aam\t$src", [], IIC_AAM>, Requires<[Not64BitMode]>;
2152 // ASCII Adjust AL After Subtraction - sets
2153 let Uses = [AL,EFLAGS], Defs = [AX,EFLAGS], hasSideEffects = 0 in
2154 def AAS : I<0x3F, RawFrm, (outs), (ins), "aas", [], IIC_AAS>,
2155 Requires<[Not64BitMode]>;
2157 // Decimal Adjust AL after Addition
2158 let Uses = [AL,EFLAGS], Defs = [AL,EFLAGS], hasSideEffects = 0 in
2159 def DAA : I<0x27, RawFrm, (outs), (ins), "daa", [], IIC_DAA>,
2160 Requires<[Not64BitMode]>;
2162 // Decimal Adjust AL after Subtraction
2163 let Uses = [AL,EFLAGS], Defs = [AL,EFLAGS], hasSideEffects = 0 in
2164 def DAS : I<0x2F, RawFrm, (outs), (ins), "das", [], IIC_DAS>,
2165 Requires<[Not64BitMode]>;
2168 let SchedRW = [WriteSystem] in {
2169 // Check Array Index Against Bounds
2170 def BOUNDS16rm : I<0x62, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
2171 "bound\t{$src, $dst|$dst, $src}", [], IIC_BOUND>, OpSize16,
2172 Requires<[Not64BitMode]>;
2173 def BOUNDS32rm : I<0x62, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
2174 "bound\t{$src, $dst|$dst, $src}", [], IIC_BOUND>, OpSize32,
2175 Requires<[Not64BitMode]>;
2177 // Adjust RPL Field of Segment Selector
2178 def ARPL16rr : I<0x63, MRMDestReg, (outs GR16:$dst), (ins GR16:$src),
2179 "arpl\t{$src, $dst|$dst, $src}", [], IIC_ARPL_REG>,
2180 Requires<[Not64BitMode]>;
2182 def ARPL16mr : I<0x63, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src),
2183 "arpl\t{$src, $dst|$dst, $src}", [], IIC_ARPL_MEM>,
2184 Requires<[Not64BitMode]>;
2187 //===----------------------------------------------------------------------===//
2188 // MOVBE Instructions
2190 let Predicates = [HasMOVBE] in {
2191 let SchedRW = [WriteALULd] in {
2192 def MOVBE16rm : I<0xF0, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
2193 "movbe{w}\t{$src, $dst|$dst, $src}",
2194 [(set GR16:$dst, (bswap (loadi16 addr:$src)))], IIC_MOVBE>,
2196 def MOVBE32rm : I<0xF0, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
2197 "movbe{l}\t{$src, $dst|$dst, $src}",
2198 [(set GR32:$dst, (bswap (loadi32 addr:$src)))], IIC_MOVBE>,
2200 def MOVBE64rm : RI<0xF0, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
2201 "movbe{q}\t{$src, $dst|$dst, $src}",
2202 [(set GR64:$dst, (bswap (loadi64 addr:$src)))], IIC_MOVBE>,
2205 let SchedRW = [WriteStore] in {
2206 def MOVBE16mr : I<0xF1, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src),
2207 "movbe{w}\t{$src, $dst|$dst, $src}",
2208 [(store (bswap GR16:$src), addr:$dst)], IIC_MOVBE>,
2210 def MOVBE32mr : I<0xF1, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
2211 "movbe{l}\t{$src, $dst|$dst, $src}",
2212 [(store (bswap GR32:$src), addr:$dst)], IIC_MOVBE>,
2214 def MOVBE64mr : RI<0xF1, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
2215 "movbe{q}\t{$src, $dst|$dst, $src}",
2216 [(store (bswap GR64:$src), addr:$dst)], IIC_MOVBE>,
2221 //===----------------------------------------------------------------------===//
2222 // RDRAND Instruction
2224 let Predicates = [HasRDRAND], Defs = [EFLAGS], SchedRW = [WriteSystem] in {
2225 def RDRAND16r : I<0xC7, MRM6r, (outs GR16:$dst), (ins),
2227 [(set GR16:$dst, EFLAGS, (X86rdrand))], IIC_RDRAND>,
2229 def RDRAND32r : I<0xC7, MRM6r, (outs GR32:$dst), (ins),
2231 [(set GR32:$dst, EFLAGS, (X86rdrand))], IIC_RDRAND>,
2233 def RDRAND64r : RI<0xC7, MRM6r, (outs GR64:$dst), (ins),
2235 [(set GR64:$dst, EFLAGS, (X86rdrand))], IIC_RDRAND>, PS;
2238 //===----------------------------------------------------------------------===//
2239 // RDSEED Instruction
2241 let Predicates = [HasRDSEED], Defs = [EFLAGS], SchedRW = [WriteSystem] in {
2242 def RDSEED16r : I<0xC7, MRM7r, (outs GR16:$dst), (ins),
2244 [(set GR16:$dst, EFLAGS, (X86rdseed))], IIC_RDSEED>,
2246 def RDSEED32r : I<0xC7, MRM7r, (outs GR32:$dst), (ins),
2248 [(set GR32:$dst, EFLAGS, (X86rdseed))], IIC_RDSEED>,
2250 def RDSEED64r : RI<0xC7, MRM7r, (outs GR64:$dst), (ins),
2252 [(set GR64:$dst, EFLAGS, (X86rdseed))], IIC_RDSEED>, PS;
2255 //===----------------------------------------------------------------------===//
2256 // LZCNT Instruction
2258 let Predicates = [HasLZCNT], Defs = [EFLAGS] in {
2259 def LZCNT16rr : I<0xBD, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
2260 "lzcnt{w}\t{$src, $dst|$dst, $src}",
2261 [(set GR16:$dst, (ctlz GR16:$src)), (implicit EFLAGS)],
2262 IIC_LZCNT_RR>, XS, OpSize16, Sched<[WriteIMul]>;
2263 def LZCNT16rm : I<0xBD, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
2264 "lzcnt{w}\t{$src, $dst|$dst, $src}",
2265 [(set GR16:$dst, (ctlz (loadi16 addr:$src))),
2266 (implicit EFLAGS)], IIC_LZCNT_RM>, XS, OpSize16,
2267 Sched<[WriteIMulLd]>;
2269 def LZCNT32rr : I<0xBD, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
2270 "lzcnt{l}\t{$src, $dst|$dst, $src}",
2271 [(set GR32:$dst, (ctlz GR32:$src)), (implicit EFLAGS)],
2272 IIC_LZCNT_RR>, XS, OpSize32, Sched<[WriteIMul]>;
2273 def LZCNT32rm : I<0xBD, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
2274 "lzcnt{l}\t{$src, $dst|$dst, $src}",
2275 [(set GR32:$dst, (ctlz (loadi32 addr:$src))),
2276 (implicit EFLAGS)], IIC_LZCNT_RM>, XS, OpSize32,
2277 Sched<[WriteIMulLd]>;
2279 def LZCNT64rr : RI<0xBD, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
2280 "lzcnt{q}\t{$src, $dst|$dst, $src}",
2281 [(set GR64:$dst, (ctlz GR64:$src)), (implicit EFLAGS)],
2282 IIC_LZCNT_RR>, XS, Sched<[WriteIMul]>;
2283 def LZCNT64rm : RI<0xBD, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
2284 "lzcnt{q}\t{$src, $dst|$dst, $src}",
2285 [(set GR64:$dst, (ctlz (loadi64 addr:$src))),
2286 (implicit EFLAGS)], IIC_LZCNT_RM>, XS,
2287 Sched<[WriteIMulLd]>;
2290 //===----------------------------------------------------------------------===//
2293 let Predicates = [HasBMI], Defs = [EFLAGS] in {
2294 def TZCNT16rr : I<0xBC, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
2295 "tzcnt{w}\t{$src, $dst|$dst, $src}",
2296 [(set GR16:$dst, (cttz GR16:$src)), (implicit EFLAGS)],
2297 IIC_TZCNT_RR>, XS, OpSize16, Sched<[WriteIMul]>;
2298 def TZCNT16rm : I<0xBC, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
2299 "tzcnt{w}\t{$src, $dst|$dst, $src}",
2300 [(set GR16:$dst, (cttz (loadi16 addr:$src))),
2301 (implicit EFLAGS)], IIC_TZCNT_RM>, XS, OpSize16,
2302 Sched<[WriteIMulLd]>;
2304 def TZCNT32rr : I<0xBC, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
2305 "tzcnt{l}\t{$src, $dst|$dst, $src}",
2306 [(set GR32:$dst, (cttz GR32:$src)), (implicit EFLAGS)],
2307 IIC_TZCNT_RR>, XS, OpSize32, Sched<[WriteIMul]>;
2308 def TZCNT32rm : I<0xBC, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
2309 "tzcnt{l}\t{$src, $dst|$dst, $src}",
2310 [(set GR32:$dst, (cttz (loadi32 addr:$src))),
2311 (implicit EFLAGS)], IIC_TZCNT_RM>, XS, OpSize32,
2312 Sched<[WriteIMulLd]>;
2314 def TZCNT64rr : RI<0xBC, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
2315 "tzcnt{q}\t{$src, $dst|$dst, $src}",
2316 [(set GR64:$dst, (cttz GR64:$src)), (implicit EFLAGS)],
2317 IIC_TZCNT_RR>, XS, Sched<[WriteIMul]>;
2318 def TZCNT64rm : RI<0xBC, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
2319 "tzcnt{q}\t{$src, $dst|$dst, $src}",
2320 [(set GR64:$dst, (cttz (loadi64 addr:$src))),
2321 (implicit EFLAGS)], IIC_TZCNT_RM>, XS,
2322 Sched<[WriteIMulLd]>;
2325 multiclass bmi_bls<string mnemonic, Format RegMRM, Format MemMRM,
2326 RegisterClass RC, X86MemOperand x86memop> {
2327 let hasSideEffects = 0 in {
2328 def rr : I<0xF3, RegMRM, (outs RC:$dst), (ins RC:$src),
2329 !strconcat(mnemonic, "\t{$src, $dst|$dst, $src}"),
2330 [], IIC_UNARY_REG>, T8PS, VEX_4V, Sched<[WriteALU]>;
2332 def rm : I<0xF3, MemMRM, (outs RC:$dst), (ins x86memop:$src),
2333 !strconcat(mnemonic, "\t{$src, $dst|$dst, $src}"),
2334 [], IIC_UNARY_MEM>, T8PS, VEX_4V, Sched<[WriteALULd, ReadAfterLd]>;
2338 let Predicates = [HasBMI], Defs = [EFLAGS] in {
2339 defm BLSR32 : bmi_bls<"blsr{l}", MRM1r, MRM1m, GR32, i32mem>;
2340 defm BLSR64 : bmi_bls<"blsr{q}", MRM1r, MRM1m, GR64, i64mem>, VEX_W;
2341 defm BLSMSK32 : bmi_bls<"blsmsk{l}", MRM2r, MRM2m, GR32, i32mem>;
2342 defm BLSMSK64 : bmi_bls<"blsmsk{q}", MRM2r, MRM2m, GR64, i64mem>, VEX_W;
2343 defm BLSI32 : bmi_bls<"blsi{l}", MRM3r, MRM3m, GR32, i32mem>;
2344 defm BLSI64 : bmi_bls<"blsi{q}", MRM3r, MRM3m, GR64, i64mem>, VEX_W;
2347 //===----------------------------------------------------------------------===//
2348 // Pattern fragments to auto generate BMI instructions.
2349 //===----------------------------------------------------------------------===//
2351 let Predicates = [HasBMI] in {
2352 // FIXME: patterns for the load versions are not implemented
2353 def : Pat<(and GR32:$src, (add GR32:$src, -1)),
2354 (BLSR32rr GR32:$src)>;
2355 def : Pat<(and GR64:$src, (add GR64:$src, -1)),
2356 (BLSR64rr GR64:$src)>;
2358 def : Pat<(xor GR32:$src, (add GR32:$src, -1)),
2359 (BLSMSK32rr GR32:$src)>;
2360 def : Pat<(xor GR64:$src, (add GR64:$src, -1)),
2361 (BLSMSK64rr GR64:$src)>;
2363 def : Pat<(and GR32:$src, (ineg GR32:$src)),
2364 (BLSI32rr GR32:$src)>;
2365 def : Pat<(and GR64:$src, (ineg GR64:$src)),
2366 (BLSI64rr GR64:$src)>;
2369 multiclass bmi_bextr_bzhi<bits<8> opc, string mnemonic, RegisterClass RC,
2370 X86MemOperand x86memop, Intrinsic Int,
2372 def rr : I<opc, MRMSrcReg4VOp3, (outs RC:$dst), (ins RC:$src1, RC:$src2),
2373 !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2374 [(set RC:$dst, (Int RC:$src1, RC:$src2)), (implicit EFLAGS)], IIC_BIN_NONMEM>,
2375 T8PS, VEX, Sched<[WriteALU]>;
2376 def rm : I<opc, MRMSrcMem4VOp3, (outs RC:$dst), (ins x86memop:$src1, RC:$src2),
2377 !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2378 [(set RC:$dst, (Int (ld_frag addr:$src1), RC:$src2)),
2379 (implicit EFLAGS)], IIC_BIN_MEM>, T8PS, VEX,
2380 Sched<[WriteALULd, ReadAfterLd]>;
2383 let Predicates = [HasBMI], Defs = [EFLAGS] in {
2384 defm BEXTR32 : bmi_bextr_bzhi<0xF7, "bextr{l}", GR32, i32mem,
2385 int_x86_bmi_bextr_32, loadi32>;
2386 defm BEXTR64 : bmi_bextr_bzhi<0xF7, "bextr{q}", GR64, i64mem,
2387 int_x86_bmi_bextr_64, loadi64>, VEX_W;
2390 let Predicates = [HasBMI2], Defs = [EFLAGS] in {
2391 defm BZHI32 : bmi_bextr_bzhi<0xF5, "bzhi{l}", GR32, i32mem,
2392 int_x86_bmi_bzhi_32, loadi32>;
2393 defm BZHI64 : bmi_bextr_bzhi<0xF5, "bzhi{q}", GR64, i64mem,
2394 int_x86_bmi_bzhi_64, loadi64>, VEX_W;
2397 def CountTrailingOnes : SDNodeXForm<imm, [{
2398 // Count the trailing ones in the immediate.
2399 return getI8Imm(countTrailingOnes(N->getZExtValue()), SDLoc(N));
2402 def BEXTRMaskXForm : SDNodeXForm<imm, [{
2403 unsigned Length = countTrailingOnes(N->getZExtValue());
2404 return getI32Imm(Length << 8, SDLoc(N));
2407 def AndMask64 : ImmLeaf<i64, [{
2408 return isMask_64(Imm) && Imm > UINT32_MAX;
2411 // Use BEXTR for 64-bit 'and' with large immediate 'mask'.
2412 let Predicates = [HasBMI, NoBMI2, NoTBM] in {
2413 def : Pat<(and GR64:$src, AndMask64:$mask),
2414 (BEXTR64rr GR64:$src,
2415 (SUBREG_TO_REG (i64 0),
2416 (MOV32ri (BEXTRMaskXForm imm:$mask)), sub_32bit))>;
2417 def : Pat<(and (loadi64 addr:$src), AndMask64:$mask),
2418 (BEXTR64rm addr:$src,
2419 (SUBREG_TO_REG (i64 0),
2420 (MOV32ri (BEXTRMaskXForm imm:$mask)), sub_32bit))>;
2423 // Use BZHI for 64-bit 'and' with large immediate 'mask'.
2424 let Predicates = [HasBMI2, NoTBM] in {
2425 def : Pat<(and GR64:$src, AndMask64:$mask),
2426 (BZHI64rr GR64:$src,
2427 (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
2428 (MOV8ri (CountTrailingOnes imm:$mask)), sub_8bit))>;
2429 def : Pat<(and (loadi64 addr:$src), AndMask64:$mask),
2430 (BZHI64rm addr:$src,
2431 (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
2432 (MOV8ri (CountTrailingOnes imm:$mask)), sub_8bit))>;
2435 let Predicates = [HasBMI2] in {
2436 def : Pat<(and GR32:$src, (add (shl 1, GR8:$lz), -1)),
2437 (BZHI32rr GR32:$src,
2438 (INSERT_SUBREG (i32 (IMPLICIT_DEF)), GR8:$lz, sub_8bit))>;
2440 def : Pat<(and (loadi32 addr:$src), (add (shl 1, GR8:$lz), -1)),
2441 (BZHI32rm addr:$src,
2442 (INSERT_SUBREG (i32 (IMPLICIT_DEF)), GR8:$lz, sub_8bit))>;
2444 def : Pat<(and GR64:$src, (add (shl 1, GR8:$lz), -1)),
2445 (BZHI64rr GR64:$src,
2446 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR8:$lz, sub_8bit))>;
2448 def : Pat<(and (loadi64 addr:$src), (add (shl 1, GR8:$lz), -1)),
2449 (BZHI64rm addr:$src,
2450 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR8:$lz, sub_8bit))>;
2452 // x & (-1 >> (32 - y))
2453 def : Pat<(and GR32:$src, (srl -1, (i8 (trunc (sub 32, GR32:$lz))))),
2454 (BZHI32rr GR32:$src, GR32:$lz)>;
2455 def : Pat<(and (loadi32 addr:$src), (srl -1, (i8 (trunc (sub 32, GR32:$lz))))),
2456 (BZHI32rm addr:$src, GR32:$lz)>;
2458 // x & (-1 >> (64 - y))
2459 def : Pat<(and GR64:$src, (srl -1, (i8 (trunc (sub 64, GR32:$lz))))),
2460 (BZHI64rr GR64:$src,
2461 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR32:$lz, sub_32bit))>;
2462 def : Pat<(and (loadi64 addr:$src), (srl -1, (i8 (trunc (sub 64, GR32:$lz))))),
2463 (BZHI64rm addr:$src,
2464 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR32:$lz, sub_32bit))>;
2466 // x << (32 - y) >> (32 - y)
2467 def : Pat<(srl (shl GR32:$src, (i8 (trunc (sub 32, GR32:$lz)))),
2468 (i8 (trunc (sub 32, GR32:$lz)))),
2469 (BZHI32rr GR32:$src, GR32:$lz)>;
2470 def : Pat<(srl (shl (loadi32 addr:$src), (i8 (trunc (sub 32, GR32:$lz)))),
2471 (i8 (trunc (sub 32, GR32:$lz)))),
2472 (BZHI32rm addr:$src, GR32:$lz)>;
2474 // x << (64 - y) >> (64 - y)
2475 def : Pat<(srl (shl GR64:$src, (i8 (trunc (sub 64, GR32:$lz)))),
2476 (i8 (trunc (sub 64, GR32:$lz)))),
2477 (BZHI64rr GR64:$src,
2478 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR32:$lz, sub_32bit))>;
2479 def : Pat<(srl (shl (loadi64 addr:$src), (i8 (trunc (sub 64, GR32:$lz)))),
2480 (i8 (trunc (sub 64, GR32:$lz)))),
2481 (BZHI64rm addr:$src,
2482 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR32:$lz, sub_32bit))>;
2485 multiclass bmi_pdep_pext<string mnemonic, RegisterClass RC,
2486 X86MemOperand x86memop, Intrinsic Int,
2488 def rr : I<0xF5, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
2489 !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2490 [(set RC:$dst, (Int RC:$src1, RC:$src2))], IIC_BIN_NONMEM>,
2491 VEX_4V, Sched<[WriteALU]>;
2492 def rm : I<0xF5, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
2493 !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2494 [(set RC:$dst, (Int RC:$src1, (ld_frag addr:$src2)))],
2495 IIC_BIN_MEM>, VEX_4V, Sched<[WriteALULd, ReadAfterLd]>;
2498 let Predicates = [HasBMI2] in {
2499 defm PDEP32 : bmi_pdep_pext<"pdep{l}", GR32, i32mem,
2500 int_x86_bmi_pdep_32, loadi32>, T8XD;
2501 defm PDEP64 : bmi_pdep_pext<"pdep{q}", GR64, i64mem,
2502 int_x86_bmi_pdep_64, loadi64>, T8XD, VEX_W;
2503 defm PEXT32 : bmi_pdep_pext<"pext{l}", GR32, i32mem,
2504 int_x86_bmi_pext_32, loadi32>, T8XS;
2505 defm PEXT64 : bmi_pdep_pext<"pext{q}", GR64, i64mem,
2506 int_x86_bmi_pext_64, loadi64>, T8XS, VEX_W;
2509 //===----------------------------------------------------------------------===//
2512 let Predicates = [HasTBM], Defs = [EFLAGS] in {
2514 multiclass tbm_ternary_imm_intr<bits<8> opc, RegisterClass RC, string OpcodeStr,
2515 X86MemOperand x86memop, PatFrag ld_frag,
2516 Intrinsic Int, Operand immtype,
2517 SDPatternOperator immoperator> {
2518 def ri : Ii32<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, immtype:$cntl),
2519 !strconcat(OpcodeStr,
2520 "\t{$cntl, $src1, $dst|$dst, $src1, $cntl}"),
2521 [(set RC:$dst, (Int RC:$src1, immoperator:$cntl))],
2522 IIC_BIN_NONMEM>, XOP, XOPA, Sched<[WriteALU]>;
2523 def mi : Ii32<opc, MRMSrcMem, (outs RC:$dst),
2524 (ins x86memop:$src1, immtype:$cntl),
2525 !strconcat(OpcodeStr,
2526 "\t{$cntl, $src1, $dst|$dst, $src1, $cntl}"),
2527 [(set RC:$dst, (Int (ld_frag addr:$src1), immoperator:$cntl))],
2528 IIC_BIN_MEM>, XOP, XOPA, Sched<[WriteALULd, ReadAfterLd]>;
2531 defm BEXTRI32 : tbm_ternary_imm_intr<0x10, GR32, "bextr", i32mem, loadi32,
2532 int_x86_tbm_bextri_u32, i32imm, imm>;
2533 let ImmT = Imm32S in
2534 defm BEXTRI64 : tbm_ternary_imm_intr<0x10, GR64, "bextr", i64mem, loadi64,
2535 int_x86_tbm_bextri_u64, i64i32imm,
2536 i64immSExt32>, VEX_W;
2538 multiclass tbm_binary_rm<bits<8> opc, Format FormReg, Format FormMem,
2539 RegisterClass RC, string OpcodeStr,
2540 X86MemOperand x86memop, PatFrag ld_frag> {
2541 let hasSideEffects = 0 in {
2542 def rr : I<opc, FormReg, (outs RC:$dst), (ins RC:$src),
2543 !strconcat(OpcodeStr,"\t{$src, $dst|$dst, $src}"),
2544 [], IIC_BIN_NONMEM>, XOP_4V, XOP9, Sched<[WriteALU]>;
2546 def rm : I<opc, FormMem, (outs RC:$dst), (ins x86memop:$src),
2547 !strconcat(OpcodeStr,"\t{$src, $dst|$dst, $src}"),
2548 [], IIC_BIN_MEM>, XOP_4V, XOP9, Sched<[WriteALULd, ReadAfterLd]>;
2552 multiclass tbm_binary_intr<bits<8> opc, string OpcodeStr,
2553 Format FormReg, Format FormMem> {
2554 defm NAME#32 : tbm_binary_rm<opc, FormReg, FormMem, GR32, OpcodeStr, i32mem,
2556 defm NAME#64 : tbm_binary_rm<opc, FormReg, FormMem, GR64, OpcodeStr, i64mem,
2560 defm BLCFILL : tbm_binary_intr<0x01, "blcfill", MRM1r, MRM1m>;
2561 defm BLCI : tbm_binary_intr<0x02, "blci", MRM6r, MRM6m>;
2562 defm BLCIC : tbm_binary_intr<0x01, "blcic", MRM5r, MRM5m>;
2563 defm BLCMSK : tbm_binary_intr<0x02, "blcmsk", MRM1r, MRM1m>;
2564 defm BLCS : tbm_binary_intr<0x01, "blcs", MRM3r, MRM3m>;
2565 defm BLSFILL : tbm_binary_intr<0x01, "blsfill", MRM2r, MRM2m>;
2566 defm BLSIC : tbm_binary_intr<0x01, "blsic", MRM6r, MRM6m>;
2567 defm T1MSKC : tbm_binary_intr<0x01, "t1mskc", MRM7r, MRM7m>;
2568 defm TZMSK : tbm_binary_intr<0x01, "tzmsk", MRM4r, MRM4m>;
2571 // Use BEXTRI for 64-bit 'and' with large immediate 'mask'.
2572 let Predicates = [HasTBM] in {
2573 def : Pat<(and GR64:$src, AndMask64:$mask),
2574 (BEXTRI64ri GR64:$src, (BEXTRMaskXForm imm:$mask))>;
2576 def : Pat<(and (loadi64 addr:$src), AndMask64:$mask),
2577 (BEXTRI64mi addr:$src, (BEXTRMaskXForm imm:$mask))>;
2580 //===----------------------------------------------------------------------===//
2581 // Lightweight Profiling Instructions
2583 let Predicates = [HasLWP], SchedRW = [WriteSystem] in {
2585 def LLWPCB : I<0x12, MRM0r, (outs), (ins GR32:$src), "llwpcb\t$src",
2586 [(int_x86_llwpcb GR32:$src)], IIC_LWP>,
2588 def SLWPCB : I<0x12, MRM1r, (outs GR32:$dst), (ins), "slwpcb\t$dst",
2589 [(set GR32:$dst, (int_x86_slwpcb))], IIC_LWP>,
2592 def LLWPCB64 : I<0x12, MRM0r, (outs), (ins GR64:$src), "llwpcb\t$src",
2593 [(int_x86_llwpcb GR64:$src)], IIC_LWP>,
2595 def SLWPCB64 : I<0x12, MRM1r, (outs GR64:$dst), (ins), "slwpcb\t$dst",
2596 [(set GR64:$dst, (int_x86_slwpcb))], IIC_LWP>,
2599 multiclass lwpins_intr<RegisterClass RC> {
2600 def rri : Ii32<0x12, MRM0r, (outs), (ins RC:$src0, GR32:$src1, i32imm:$cntl),
2601 "lwpins\t{$cntl, $src1, $src0|$src0, $src1, $cntl}",
2602 [(set EFLAGS, (X86lwpins RC:$src0, GR32:$src1, imm:$cntl))], IIC_LWP>,
2605 def rmi : Ii32<0x12, MRM0m, (outs), (ins RC:$src0, i32mem:$src1, i32imm:$cntl),
2606 "lwpins\t{$cntl, $src1, $src0|$src0, $src1, $cntl}",
2607 [(set EFLAGS, (X86lwpins RC:$src0, (loadi32 addr:$src1), imm:$cntl))], IIC_LWP>,
2611 let Defs = [EFLAGS] in {
2612 defm LWPINS32 : lwpins_intr<GR32>;
2613 defm LWPINS64 : lwpins_intr<GR64>, VEX_W;
2616 multiclass lwpval_intr<RegisterClass RC, Intrinsic Int> {
2617 def rri : Ii32<0x12, MRM1r, (outs), (ins RC:$src0, GR32:$src1, i32imm:$cntl),
2618 "lwpval\t{$cntl, $src1, $src0|$src0, $src1, $cntl}",
2619 [(Int RC:$src0, GR32:$src1, imm:$cntl)], IIC_LWP>,
2622 def rmi : Ii32<0x12, MRM1m, (outs), (ins RC:$src0, i32mem:$src1, i32imm:$cntl),
2623 "lwpval\t{$cntl, $src1, $src0|$src0, $src1, $cntl}",
2624 [(Int RC:$src0, (loadi32 addr:$src1), imm:$cntl)], IIC_LWP>,
2628 defm LWPVAL32 : lwpval_intr<GR32, int_x86_lwpval32>;
2629 defm LWPVAL64 : lwpval_intr<GR64, int_x86_lwpval64>, VEX_W;
2631 } // HasLWP, SchedRW
2633 //===----------------------------------------------------------------------===//
2634 // MONITORX/MWAITX Instructions
2636 let SchedRW = [ WriteSystem ] in {
2637 let usesCustomInserter = 1 in {
2638 def MONITORX : PseudoI<(outs), (ins i32mem:$src1, GR32:$src2, GR32:$src3),
2639 [(int_x86_monitorx addr:$src1, GR32:$src2, GR32:$src3)]>,
2640 Requires<[ HasMWAITX ]>;
2643 let Uses = [ EAX, ECX, EDX ] in {
2644 def MONITORXrrr : I<0x01, MRM_FA, (outs), (ins), "monitorx", [], IIC_SSE_MONITORX>,
2645 TB, Requires<[ HasMWAITX ]>;
2648 let Uses = [ ECX, EAX, EBX ] in {
2649 def MWAITXrrr : I<0x01, MRM_FB, (outs), (ins), "mwaitx",
2650 [(int_x86_mwaitx ECX, EAX, EBX)], IIC_SSE_MWAITX>,
2651 TB, Requires<[ HasMWAITX ]>;
2655 def : InstAlias<"mwaitx\t{%eax, %ecx, %ebx|ebx, ecx, eax}", (MWAITXrrr)>,
2656 Requires<[ Not64BitMode ]>;
2657 def : InstAlias<"mwaitx\t{%rax, %rcx, %rbx|rbx, rcx, rax}", (MWAITXrrr)>,
2658 Requires<[ In64BitMode ]>;
2660 def : InstAlias<"monitorx\t{%eax, %ecx, %edx|edx, ecx, eax}", (MONITORXrrr)>,
2661 Requires<[ Not64BitMode ]>;
2662 def : InstAlias<"monitorx\t{%rax, %rcx, %rdx|rdx, rcx, rax}", (MONITORXrrr)>,
2663 Requires<[ In64BitMode ]>;
2665 //===----------------------------------------------------------------------===//
2666 // CLZERO Instruction
2668 let SchedRW = [WriteSystem] in {
2670 def CLZEROr : I<0x01, MRM_FC, (outs), (ins), "clzero", [], IIC_SSE_CLZERO>,
2671 TB, Requires<[HasCLZERO]>;
2673 let usesCustomInserter = 1 in {
2674 def CLZERO : PseudoI<(outs), (ins i32mem:$src1),
2675 [(int_x86_clzero addr:$src1)]>, Requires<[HasCLZERO]>;
2679 def : InstAlias<"clzero\t{%eax|eax}", (CLZEROr)>, Requires<[Not64BitMode]>;
2680 def : InstAlias<"clzero\t{%rax|rax}", (CLZEROr)>, Requires<[In64BitMode]>;
2682 //===----------------------------------------------------------------------===//
2683 // Pattern fragments to auto generate TBM instructions.
2684 //===----------------------------------------------------------------------===//
2686 let Predicates = [HasTBM] in {
2687 // FIXME: patterns for the load versions are not implemented
2688 def : Pat<(and GR32:$src, (add GR32:$src, 1)),
2689 (BLCFILL32rr GR32:$src)>;
2690 def : Pat<(and GR64:$src, (add GR64:$src, 1)),
2691 (BLCFILL64rr GR64:$src)>;
2693 def : Pat<(or GR32:$src, (not (add GR32:$src, 1))),
2694 (BLCI32rr GR32:$src)>;
2695 def : Pat<(or GR64:$src, (not (add GR64:$src, 1))),
2696 (BLCI64rr GR64:$src)>;
2698 // Extra patterns because opt can optimize the above patterns to this.
2699 def : Pat<(or GR32:$src, (sub -2, GR32:$src)),
2700 (BLCI32rr GR32:$src)>;
2701 def : Pat<(or GR64:$src, (sub -2, GR64:$src)),
2702 (BLCI64rr GR64:$src)>;
2704 def : Pat<(and (not GR32:$src), (add GR32:$src, 1)),
2705 (BLCIC32rr GR32:$src)>;
2706 def : Pat<(and (not GR64:$src), (add GR64:$src, 1)),
2707 (BLCIC64rr GR64:$src)>;
2709 def : Pat<(xor GR32:$src, (add GR32:$src, 1)),
2710 (BLCMSK32rr GR32:$src)>;
2711 def : Pat<(xor GR64:$src, (add GR64:$src, 1)),
2712 (BLCMSK64rr GR64:$src)>;
2714 def : Pat<(or GR32:$src, (add GR32:$src, 1)),
2715 (BLCS32rr GR32:$src)>;
2716 def : Pat<(or GR64:$src, (add GR64:$src, 1)),
2717 (BLCS64rr GR64:$src)>;
2719 def : Pat<(or GR32:$src, (add GR32:$src, -1)),
2720 (BLSFILL32rr GR32:$src)>;
2721 def : Pat<(or GR64:$src, (add GR64:$src, -1)),
2722 (BLSFILL64rr GR64:$src)>;
2724 def : Pat<(or (not GR32:$src), (add GR32:$src, -1)),
2725 (BLSIC32rr GR32:$src)>;
2726 def : Pat<(or (not GR64:$src), (add GR64:$src, -1)),
2727 (BLSIC64rr GR64:$src)>;
2729 def : Pat<(or (not GR32:$src), (add GR32:$src, 1)),
2730 (T1MSKC32rr GR32:$src)>;
2731 def : Pat<(or (not GR64:$src), (add GR64:$src, 1)),
2732 (T1MSKC64rr GR64:$src)>;
2734 def : Pat<(and (not GR32:$src), (add GR32:$src, -1)),
2735 (TZMSK32rr GR32:$src)>;
2736 def : Pat<(and (not GR64:$src), (add GR64:$src, -1)),
2737 (TZMSK64rr GR64:$src)>;
2740 //===----------------------------------------------------------------------===//
2741 // Memory Instructions
2744 let Predicates = [HasCLFLUSHOPT], SchedRW = [WriteLoad] in
2745 def CLFLUSHOPT : I<0xAE, MRM7m, (outs), (ins i8mem:$src),
2746 "clflushopt\t$src", [(int_x86_clflushopt addr:$src)],
2747 IIC_SSE_PREFETCH>, PD;
2749 let Predicates = [HasCLWB], SchedRW = [WriteLoad] in
2750 def CLWB : I<0xAE, MRM6m, (outs), (ins i8mem:$src), "clwb\t$src",
2751 [(int_x86_clwb addr:$src)], IIC_SSE_PREFETCH>, PD;
2753 //===----------------------------------------------------------------------===//
2755 //===----------------------------------------------------------------------===//
2757 include "X86InstrArithmetic.td"
2758 include "X86InstrCMovSetCC.td"
2759 include "X86InstrExtension.td"
2760 include "X86InstrControl.td"
2761 include "X86InstrShiftRotate.td"
2763 // X87 Floating Point Stack.
2764 include "X86InstrFPStack.td"
2766 // SIMD support (SSE, MMX and AVX)
2767 include "X86InstrFragmentsSIMD.td"
2769 // FMA - Fused Multiply-Add support (requires FMA)
2770 include "X86InstrFMA.td"
2773 include "X86InstrXOP.td"
2775 // SSE, MMX and 3DNow! vector support.
2776 include "X86InstrSSE.td"
2777 include "X86InstrAVX512.td"
2778 include "X86InstrMMX.td"
2779 include "X86Instr3DNow.td"
2782 include "X86InstrMPX.td"
2784 include "X86InstrVMX.td"
2785 include "X86InstrSVM.td"
2787 include "X86InstrTSX.td"
2788 include "X86InstrSGX.td"
2790 // System instructions.
2791 include "X86InstrSystem.td"
2793 // Compiler Pseudo Instructions and Pat Patterns
2794 include "X86InstrCompiler.td"
2795 include "X86InstrVecCompiler.td"
2797 //===----------------------------------------------------------------------===//
2798 // Assembler Mnemonic Aliases
2799 //===----------------------------------------------------------------------===//
2801 def : MnemonicAlias<"call", "callw", "att">, Requires<[In16BitMode]>;
2802 def : MnemonicAlias<"call", "calll", "att">, Requires<[In32BitMode]>;
2803 def : MnemonicAlias<"call", "callq", "att">, Requires<[In64BitMode]>;
2805 def : MnemonicAlias<"cbw", "cbtw", "att">;
2806 def : MnemonicAlias<"cwde", "cwtl", "att">;
2807 def : MnemonicAlias<"cwd", "cwtd", "att">;
2808 def : MnemonicAlias<"cdq", "cltd", "att">;
2809 def : MnemonicAlias<"cdqe", "cltq", "att">;
2810 def : MnemonicAlias<"cqo", "cqto", "att">;
2812 // In 64-bit mode lret maps to lretl; it is not ambiguous with lretq.
2813 def : MnemonicAlias<"lret", "lretw", "att">, Requires<[In16BitMode]>;
2814 def : MnemonicAlias<"lret", "lretl", "att">, Requires<[Not16BitMode]>;
2816 def : MnemonicAlias<"leavel", "leave", "att">, Requires<[Not64BitMode]>;
2817 def : MnemonicAlias<"leaveq", "leave", "att">, Requires<[In64BitMode]>;
2819 def : MnemonicAlias<"loopz", "loope">;
2820 def : MnemonicAlias<"loopnz", "loopne">;
2822 def : MnemonicAlias<"pop", "popw", "att">, Requires<[In16BitMode]>;
2823 def : MnemonicAlias<"pop", "popl", "att">, Requires<[In32BitMode]>;
2824 def : MnemonicAlias<"pop", "popq", "att">, Requires<[In64BitMode]>;
2825 def : MnemonicAlias<"popf", "popfw", "att">, Requires<[In16BitMode]>;
2826 def : MnemonicAlias<"popf", "popfl", "att">, Requires<[In32BitMode]>;
2827 def : MnemonicAlias<"popf", "popfq", "att">, Requires<[In64BitMode]>;
2828 def : MnemonicAlias<"popf", "popfq", "intel">, Requires<[In64BitMode]>;
2829 def : MnemonicAlias<"popfd", "popfl", "att">;
2831 // FIXME: This is wrong for "push reg". "push %bx" should turn into pushw in
2832 // all modes. However: "push (addr)" and "push $42" should default to
2833 // pushl/pushq depending on the current mode. Similar for "pop %bx"
2834 def : MnemonicAlias<"push", "pushw", "att">, Requires<[In16BitMode]>;
2835 def : MnemonicAlias<"push", "pushl", "att">, Requires<[In32BitMode]>;
2836 def : MnemonicAlias<"push", "pushq", "att">, Requires<[In64BitMode]>;
2837 def : MnemonicAlias<"pushf", "pushfw", "att">, Requires<[In16BitMode]>;
2838 def : MnemonicAlias<"pushf", "pushfl", "att">, Requires<[In32BitMode]>;
2839 def : MnemonicAlias<"pushf", "pushfq", "att">, Requires<[In64BitMode]>;
2840 def : MnemonicAlias<"pushf", "pushfq", "intel">, Requires<[In64BitMode]>;
2841 def : MnemonicAlias<"pushfd", "pushfl", "att">;
2843 def : MnemonicAlias<"popad", "popal", "intel">, Requires<[Not64BitMode]>;
2844 def : MnemonicAlias<"pushad", "pushal", "intel">, Requires<[Not64BitMode]>;
2845 def : MnemonicAlias<"popa", "popaw", "intel">, Requires<[In16BitMode]>;
2846 def : MnemonicAlias<"pusha", "pushaw", "intel">, Requires<[In16BitMode]>;
2847 def : MnemonicAlias<"popa", "popal", "intel">, Requires<[In32BitMode]>;
2848 def : MnemonicAlias<"pusha", "pushal", "intel">, Requires<[In32BitMode]>;
2850 def : MnemonicAlias<"popa", "popaw", "att">, Requires<[In16BitMode]>;
2851 def : MnemonicAlias<"pusha", "pushaw", "att">, Requires<[In16BitMode]>;
2852 def : MnemonicAlias<"popa", "popal", "att">, Requires<[In32BitMode]>;
2853 def : MnemonicAlias<"pusha", "pushal", "att">, Requires<[In32BitMode]>;
2855 def : MnemonicAlias<"repe", "rep">;
2856 def : MnemonicAlias<"repz", "rep">;
2857 def : MnemonicAlias<"repnz", "repne">;
2859 def : MnemonicAlias<"ret", "retw", "att">, Requires<[In16BitMode]>;
2860 def : MnemonicAlias<"ret", "retl", "att">, Requires<[In32BitMode]>;
2861 def : MnemonicAlias<"ret", "retq", "att">, Requires<[In64BitMode]>;
2863 // Apply 'ret' behavior to 'retn'
2864 def : MnemonicAlias<"retn", "retw", "att">, Requires<[In16BitMode]>;
2865 def : MnemonicAlias<"retn", "retl", "att">, Requires<[In32BitMode]>;
2866 def : MnemonicAlias<"retn", "retq", "att">, Requires<[In64BitMode]>;
2867 def : MnemonicAlias<"retn", "ret", "intel">;
2869 def : MnemonicAlias<"sal", "shl", "intel">;
2870 def : MnemonicAlias<"salb", "shlb", "att">;
2871 def : MnemonicAlias<"salw", "shlw", "att">;
2872 def : MnemonicAlias<"sall", "shll", "att">;
2873 def : MnemonicAlias<"salq", "shlq", "att">;
2875 def : MnemonicAlias<"smovb", "movsb", "att">;
2876 def : MnemonicAlias<"smovw", "movsw", "att">;
2877 def : MnemonicAlias<"smovl", "movsl", "att">;
2878 def : MnemonicAlias<"smovq", "movsq", "att">;
2880 def : MnemonicAlias<"ud2a", "ud2", "att">;
2881 def : MnemonicAlias<"verrw", "verr", "att">;
2883 // MS recognizes 'xacquire'/'xrelease' as 'acquire'/'release'
2884 def : MnemonicAlias<"acquire", "xacquire", "intel">;
2885 def : MnemonicAlias<"release", "xrelease", "intel">;
2887 // System instruction aliases.
2888 def : MnemonicAlias<"iret", "iretw", "att">, Requires<[In16BitMode]>;
2889 def : MnemonicAlias<"iret", "iretl", "att">, Requires<[Not16BitMode]>;
2890 def : MnemonicAlias<"sysret", "sysretl", "att">;
2891 def : MnemonicAlias<"sysexit", "sysexitl", "att">;
2893 def : MnemonicAlias<"lgdt", "lgdtw", "att">, Requires<[In16BitMode]>;
2894 def : MnemonicAlias<"lgdt", "lgdtl", "att">, Requires<[In32BitMode]>;
2895 def : MnemonicAlias<"lgdt", "lgdtq", "att">, Requires<[In64BitMode]>;
2896 def : MnemonicAlias<"lidt", "lidtw", "att">, Requires<[In16BitMode]>;
2897 def : MnemonicAlias<"lidt", "lidtl", "att">, Requires<[In32BitMode]>;
2898 def : MnemonicAlias<"lidt", "lidtq", "att">, Requires<[In64BitMode]>;
2899 def : MnemonicAlias<"sgdt", "sgdtw", "att">, Requires<[In16BitMode]>;
2900 def : MnemonicAlias<"sgdt", "sgdtl", "att">, Requires<[In32BitMode]>;
2901 def : MnemonicAlias<"sgdt", "sgdtq", "att">, Requires<[In64BitMode]>;
2902 def : MnemonicAlias<"sidt", "sidtw", "att">, Requires<[In16BitMode]>;
2903 def : MnemonicAlias<"sidt", "sidtl", "att">, Requires<[In32BitMode]>;
2904 def : MnemonicAlias<"sidt", "sidtq", "att">, Requires<[In64BitMode]>;
2907 // Floating point stack aliases.
2908 def : MnemonicAlias<"fcmovz", "fcmove", "att">;
2909 def : MnemonicAlias<"fcmova", "fcmovnbe", "att">;
2910 def : MnemonicAlias<"fcmovnae", "fcmovb", "att">;
2911 def : MnemonicAlias<"fcmovna", "fcmovbe", "att">;
2912 def : MnemonicAlias<"fcmovae", "fcmovnb", "att">;
2913 def : MnemonicAlias<"fcomip", "fcompi">;
2914 def : MnemonicAlias<"fildq", "fildll", "att">;
2915 def : MnemonicAlias<"fistpq", "fistpll", "att">;
2916 def : MnemonicAlias<"fisttpq", "fisttpll", "att">;
2917 def : MnemonicAlias<"fldcww", "fldcw", "att">;
2918 def : MnemonicAlias<"fnstcww", "fnstcw", "att">;
2919 def : MnemonicAlias<"fnstsww", "fnstsw", "att">;
2920 def : MnemonicAlias<"fucomip", "fucompi">;
2921 def : MnemonicAlias<"fwait", "wait">;
2923 def : MnemonicAlias<"fxsaveq", "fxsave64", "att">;
2924 def : MnemonicAlias<"fxrstorq", "fxrstor64", "att">;
2925 def : MnemonicAlias<"xsaveq", "xsave64", "att">;
2926 def : MnemonicAlias<"xrstorq", "xrstor64", "att">;
2927 def : MnemonicAlias<"xsaveoptq", "xsaveopt64", "att">;
2928 def : MnemonicAlias<"xrstorsq", "xrstors64", "att">;
2929 def : MnemonicAlias<"xsavecq", "xsavec64", "att">;
2930 def : MnemonicAlias<"xsavesq", "xsaves64", "att">;
2932 class CondCodeAlias<string Prefix,string Suffix, string OldCond, string NewCond,
2934 : MnemonicAlias<!strconcat(Prefix, OldCond, Suffix),
2935 !strconcat(Prefix, NewCond, Suffix), VariantName>;
2937 /// IntegerCondCodeMnemonicAlias - This multiclass defines a bunch of
2938 /// MnemonicAlias's that canonicalize the condition code in a mnemonic, for
2939 /// example "setz" -> "sete".
2940 multiclass IntegerCondCodeMnemonicAlias<string Prefix, string Suffix,
2942 def C : CondCodeAlias<Prefix, Suffix, "c", "b", V>; // setc -> setb
2943 def Z : CondCodeAlias<Prefix, Suffix, "z" , "e", V>; // setz -> sete
2944 def NA : CondCodeAlias<Prefix, Suffix, "na", "be", V>; // setna -> setbe
2945 def NB : CondCodeAlias<Prefix, Suffix, "nb", "ae", V>; // setnb -> setae
2946 def NC : CondCodeAlias<Prefix, Suffix, "nc", "ae", V>; // setnc -> setae
2947 def NG : CondCodeAlias<Prefix, Suffix, "ng", "le", V>; // setng -> setle
2948 def NL : CondCodeAlias<Prefix, Suffix, "nl", "ge", V>; // setnl -> setge
2949 def NZ : CondCodeAlias<Prefix, Suffix, "nz", "ne", V>; // setnz -> setne
2950 def PE : CondCodeAlias<Prefix, Suffix, "pe", "p", V>; // setpe -> setp
2951 def PO : CondCodeAlias<Prefix, Suffix, "po", "np", V>; // setpo -> setnp
2953 def NAE : CondCodeAlias<Prefix, Suffix, "nae", "b", V>; // setnae -> setb
2954 def NBE : CondCodeAlias<Prefix, Suffix, "nbe", "a", V>; // setnbe -> seta
2955 def NGE : CondCodeAlias<Prefix, Suffix, "nge", "l", V>; // setnge -> setl
2956 def NLE : CondCodeAlias<Prefix, Suffix, "nle", "g", V>; // setnle -> setg
2959 // Aliases for set<CC>
2960 defm : IntegerCondCodeMnemonicAlias<"set", "">;
2961 // Aliases for j<CC>
2962 defm : IntegerCondCodeMnemonicAlias<"j", "">;
2963 // Aliases for cmov<CC>{w,l,q}
2964 defm : IntegerCondCodeMnemonicAlias<"cmov", "w", "att">;
2965 defm : IntegerCondCodeMnemonicAlias<"cmov", "l", "att">;
2966 defm : IntegerCondCodeMnemonicAlias<"cmov", "q", "att">;
2967 // No size suffix for intel-style asm.
2968 defm : IntegerCondCodeMnemonicAlias<"cmov", "", "intel">;
2971 //===----------------------------------------------------------------------===//
2972 // Assembler Instruction Aliases
2973 //===----------------------------------------------------------------------===//
2975 // aad/aam default to base 10 if no operand is specified.
2976 def : InstAlias<"aad", (AAD8i8 10)>, Requires<[Not64BitMode]>;
2977 def : InstAlias<"aam", (AAM8i8 10)>, Requires<[Not64BitMode]>;
2979 // Disambiguate the mem/imm form of bt-without-a-suffix as btl.
2980 // Likewise for btc/btr/bts.
2981 def : InstAlias<"bt\t{$imm, $mem|$mem, $imm}",
2982 (BT32mi8 i32mem:$mem, i32i8imm:$imm), 0>;
2983 def : InstAlias<"btc\t{$imm, $mem|$mem, $imm}",
2984 (BTC32mi8 i32mem:$mem, i32i8imm:$imm), 0>;
2985 def : InstAlias<"btr\t{$imm, $mem|$mem, $imm}",
2986 (BTR32mi8 i32mem:$mem, i32i8imm:$imm), 0>;
2987 def : InstAlias<"bts\t{$imm, $mem|$mem, $imm}",
2988 (BTS32mi8 i32mem:$mem, i32i8imm:$imm), 0>;
2991 def : InstAlias<"clrb\t$reg", (XOR8rr GR8 :$reg, GR8 :$reg), 0>;
2992 def : InstAlias<"clrw\t$reg", (XOR16rr GR16:$reg, GR16:$reg), 0>;
2993 def : InstAlias<"clrl\t$reg", (XOR32rr GR32:$reg, GR32:$reg), 0>;
2994 def : InstAlias<"clrq\t$reg", (XOR64rr GR64:$reg, GR64:$reg), 0>;
2996 // lods aliases. Accept the destination being omitted because it's implicit
2997 // in the mnemonic, or the mnemonic suffix being omitted because it's implicit
2998 // in the destination.
2999 def : InstAlias<"lodsb\t$src", (LODSB srcidx8:$src), 0>;
3000 def : InstAlias<"lodsw\t$src", (LODSW srcidx16:$src), 0>;
3001 def : InstAlias<"lods{l|d}\t$src", (LODSL srcidx32:$src), 0>;
3002 def : InstAlias<"lodsq\t$src", (LODSQ srcidx64:$src), 0>, Requires<[In64BitMode]>;
3003 def : InstAlias<"lods\t{$src, %al|al, $src}", (LODSB srcidx8:$src), 0>;
3004 def : InstAlias<"lods\t{$src, %ax|ax, $src}", (LODSW srcidx16:$src), 0>;
3005 def : InstAlias<"lods\t{$src, %eax|eax, $src}", (LODSL srcidx32:$src), 0>;
3006 def : InstAlias<"lods\t{$src, %rax|rax, $src}", (LODSQ srcidx64:$src), 0>, Requires<[In64BitMode]>;
3007 def : InstAlias<"lods\t$src", (LODSB srcidx8:$src), 0>;
3008 def : InstAlias<"lods\t$src", (LODSW srcidx16:$src), 0>;
3009 def : InstAlias<"lods\t$src", (LODSL srcidx32:$src), 0>;
3010 def : InstAlias<"lods\t$src", (LODSQ srcidx64:$src), 0>, Requires<[In64BitMode]>;
3013 // stos aliases. Accept the source being omitted because it's implicit in
3014 // the mnemonic, or the mnemonic suffix being omitted because it's implicit
3016 def : InstAlias<"stosb\t$dst", (STOSB dstidx8:$dst), 0>;
3017 def : InstAlias<"stosw\t$dst", (STOSW dstidx16:$dst), 0>;
3018 def : InstAlias<"stos{l|d}\t$dst", (STOSL dstidx32:$dst), 0>;
3019 def : InstAlias<"stosq\t$dst", (STOSQ dstidx64:$dst), 0>, Requires<[In64BitMode]>;
3020 def : InstAlias<"stos\t{%al, $dst|$dst, al}", (STOSB dstidx8:$dst), 0>;
3021 def : InstAlias<"stos\t{%ax, $dst|$dst, ax}", (STOSW dstidx16:$dst), 0>;
3022 def : InstAlias<"stos\t{%eax, $dst|$dst, eax}", (STOSL dstidx32:$dst), 0>;
3023 def : InstAlias<"stos\t{%rax, $dst|$dst, rax}", (STOSQ dstidx64:$dst), 0>, Requires<[In64BitMode]>;
3024 def : InstAlias<"stos\t$dst", (STOSB dstidx8:$dst), 0>;
3025 def : InstAlias<"stos\t$dst", (STOSW dstidx16:$dst), 0>;
3026 def : InstAlias<"stos\t$dst", (STOSL dstidx32:$dst), 0>;
3027 def : InstAlias<"stos\t$dst", (STOSQ dstidx64:$dst), 0>, Requires<[In64BitMode]>;
3030 // scas aliases. Accept the destination being omitted because it's implicit
3031 // in the mnemonic, or the mnemonic suffix being omitted because it's implicit
3032 // in the destination.
3033 def : InstAlias<"scasb\t$dst", (SCASB dstidx8:$dst), 0>;
3034 def : InstAlias<"scasw\t$dst", (SCASW dstidx16:$dst), 0>;
3035 def : InstAlias<"scas{l|d}\t$dst", (SCASL dstidx32:$dst), 0>;
3036 def : InstAlias<"scasq\t$dst", (SCASQ dstidx64:$dst), 0>, Requires<[In64BitMode]>;
3037 def : InstAlias<"scas\t{$dst, %al|al, $dst}", (SCASB dstidx8:$dst), 0>;
3038 def : InstAlias<"scas\t{$dst, %ax|ax, $dst}", (SCASW dstidx16:$dst), 0>;
3039 def : InstAlias<"scas\t{$dst, %eax|eax, $dst}", (SCASL dstidx32:$dst), 0>;
3040 def : InstAlias<"scas\t{$dst, %rax|rax, $dst}", (SCASQ dstidx64:$dst), 0>, Requires<[In64BitMode]>;
3041 def : InstAlias<"scas\t$dst", (SCASB dstidx8:$dst), 0>;
3042 def : InstAlias<"scas\t$dst", (SCASW dstidx16:$dst), 0>;
3043 def : InstAlias<"scas\t$dst", (SCASL dstidx32:$dst), 0>;
3044 def : InstAlias<"scas\t$dst", (SCASQ dstidx64:$dst), 0>, Requires<[In64BitMode]>;
3046 // cmps aliases. Mnemonic suffix being omitted because it's implicit
3047 // in the destination.
3048 def : InstAlias<"cmps\t{$dst, $src|$src, $dst}", (CMPSB dstidx8:$dst, srcidx8:$src), 0>;
3049 def : InstAlias<"cmps\t{$dst, $src|$src, $dst}", (CMPSW dstidx16:$dst, srcidx16:$src), 0>;
3050 def : InstAlias<"cmps\t{$dst, $src|$src, $dst}", (CMPSL dstidx32:$dst, srcidx32:$src), 0>;
3051 def : InstAlias<"cmps\t{$dst, $src|$src, $dst}", (CMPSQ dstidx64:$dst, srcidx64:$src), 0>, Requires<[In64BitMode]>;
3053 // movs aliases. Mnemonic suffix being omitted because it's implicit
3054 // in the destination.
3055 def : InstAlias<"movs\t{$src, $dst|$dst, $src}", (MOVSB dstidx8:$dst, srcidx8:$src), 0>;
3056 def : InstAlias<"movs\t{$src, $dst|$dst, $src}", (MOVSW dstidx16:$dst, srcidx16:$src), 0>;
3057 def : InstAlias<"movs\t{$src, $dst|$dst, $src}", (MOVSL dstidx32:$dst, srcidx32:$src), 0>;
3058 def : InstAlias<"movs\t{$src, $dst|$dst, $src}", (MOVSQ dstidx64:$dst, srcidx64:$src), 0>, Requires<[In64BitMode]>;
3060 // div and idiv aliases for explicit A register.
3061 def : InstAlias<"div{b}\t{$src, %al|al, $src}", (DIV8r GR8 :$src)>;
3062 def : InstAlias<"div{w}\t{$src, %ax|ax, $src}", (DIV16r GR16:$src)>;
3063 def : InstAlias<"div{l}\t{$src, %eax|eax, $src}", (DIV32r GR32:$src)>;
3064 def : InstAlias<"div{q}\t{$src, %rax|rax, $src}", (DIV64r GR64:$src)>;
3065 def : InstAlias<"div{b}\t{$src, %al|al, $src}", (DIV8m i8mem :$src)>;
3066 def : InstAlias<"div{w}\t{$src, %ax|ax, $src}", (DIV16m i16mem:$src)>;
3067 def : InstAlias<"div{l}\t{$src, %eax|eax, $src}", (DIV32m i32mem:$src)>;
3068 def : InstAlias<"div{q}\t{$src, %rax|rax, $src}", (DIV64m i64mem:$src)>;
3069 def : InstAlias<"idiv{b}\t{$src, %al|al, $src}", (IDIV8r GR8 :$src)>;
3070 def : InstAlias<"idiv{w}\t{$src, %ax|ax, $src}", (IDIV16r GR16:$src)>;
3071 def : InstAlias<"idiv{l}\t{$src, %eax|eax, $src}", (IDIV32r GR32:$src)>;
3072 def : InstAlias<"idiv{q}\t{$src, %rax|rax, $src}", (IDIV64r GR64:$src)>;
3073 def : InstAlias<"idiv{b}\t{$src, %al|al, $src}", (IDIV8m i8mem :$src)>;
3074 def : InstAlias<"idiv{w}\t{$src, %ax|ax, $src}", (IDIV16m i16mem:$src)>;
3075 def : InstAlias<"idiv{l}\t{$src, %eax|eax, $src}", (IDIV32m i32mem:$src)>;
3076 def : InstAlias<"idiv{q}\t{$src, %rax|rax, $src}", (IDIV64m i64mem:$src)>;
3080 // Various unary fpstack operations default to operating on on ST1.
3081 // For example, "fxch" -> "fxch %st(1)"
3082 def : InstAlias<"faddp", (ADD_FPrST0 ST1), 0>;
3083 def: InstAlias<"fadd", (ADD_FPrST0 ST1), 0>;
3084 def : InstAlias<"fsub{|r}p", (SUBR_FPrST0 ST1), 0>;
3085 def : InstAlias<"fsub{r|}p", (SUB_FPrST0 ST1), 0>;
3086 def : InstAlias<"fmul", (MUL_FPrST0 ST1), 0>;
3087 def : InstAlias<"fmulp", (MUL_FPrST0 ST1), 0>;
3088 def : InstAlias<"fdiv{|r}p", (DIVR_FPrST0 ST1), 0>;
3089 def : InstAlias<"fdiv{r|}p", (DIV_FPrST0 ST1), 0>;
3090 def : InstAlias<"fxch", (XCH_F ST1), 0>;
3091 def : InstAlias<"fcom", (COM_FST0r ST1), 0>;
3092 def : InstAlias<"fcomp", (COMP_FST0r ST1), 0>;
3093 def : InstAlias<"fcomi", (COM_FIr ST1), 0>;
3094 def : InstAlias<"fcompi", (COM_FIPr ST1), 0>;
3095 def : InstAlias<"fucom", (UCOM_Fr ST1), 0>;
3096 def : InstAlias<"fucomp", (UCOM_FPr ST1), 0>;
3097 def : InstAlias<"fucomi", (UCOM_FIr ST1), 0>;
3098 def : InstAlias<"fucompi", (UCOM_FIPr ST1), 0>;
3100 // Handle fmul/fadd/fsub/fdiv instructions with explicitly written st(0) op.
3101 // For example, "fadd %st(4), %st(0)" -> "fadd %st(4)". We also disambiguate
3102 // instructions like "fadd %st(0), %st(0)" as "fadd %st(0)" for consistency with
3104 multiclass FpUnaryAlias<string Mnemonic, Instruction Inst, bit EmitAlias = 1> {
3105 def : InstAlias<!strconcat(Mnemonic, "\t{$op, %st(0)|st(0), $op}"),
3106 (Inst RST:$op), EmitAlias>;
3107 def : InstAlias<!strconcat(Mnemonic, "\t{%st(0), %st(0)|st(0), st(0)}"),
3108 (Inst ST0), EmitAlias>;
3111 defm : FpUnaryAlias<"fadd", ADD_FST0r>;
3112 defm : FpUnaryAlias<"faddp", ADD_FPrST0, 0>;
3113 defm : FpUnaryAlias<"fsub", SUB_FST0r>;
3114 defm : FpUnaryAlias<"fsub{|r}p", SUBR_FPrST0>;
3115 defm : FpUnaryAlias<"fsubr", SUBR_FST0r>;
3116 defm : FpUnaryAlias<"fsub{r|}p", SUB_FPrST0>;
3117 defm : FpUnaryAlias<"fmul", MUL_FST0r>;
3118 defm : FpUnaryAlias<"fmulp", MUL_FPrST0>;
3119 defm : FpUnaryAlias<"fdiv", DIV_FST0r>;
3120 defm : FpUnaryAlias<"fdiv{|r}p", DIVR_FPrST0>;
3121 defm : FpUnaryAlias<"fdivr", DIVR_FST0r>;
3122 defm : FpUnaryAlias<"fdiv{r|}p", DIV_FPrST0>;
3123 defm : FpUnaryAlias<"fcomi", COM_FIr, 0>;
3124 defm : FpUnaryAlias<"fucomi", UCOM_FIr, 0>;
3125 defm : FpUnaryAlias<"fcompi", COM_FIPr>;
3126 defm : FpUnaryAlias<"fucompi", UCOM_FIPr>;
3129 // Handle "f{mulp,addp} st(0), $op" the same as "f{mulp,addp} $op", since they
3130 // commute. We also allow fdiv[r]p/fsubrp even though they don't commute,
3131 // solely because gas supports it.
3132 def : InstAlias<"faddp\t{%st(0), $op|$op, st(0)}", (ADD_FPrST0 RST:$op), 0>;
3133 def : InstAlias<"fmulp\t{%st(0), $op|$op, st(0)}", (MUL_FPrST0 RST:$op)>;
3134 def : InstAlias<"fsub{|r}p\t{%st(0), $op|$op, st(0)}", (SUBR_FPrST0 RST:$op)>;
3135 def : InstAlias<"fsub{r|}p\t{%st(0), $op|$op, st(0)}", (SUB_FPrST0 RST:$op)>;
3136 def : InstAlias<"fdiv{|r}p\t{%st(0), $op|$op, st(0)}", (DIVR_FPrST0 RST:$op)>;
3137 def : InstAlias<"fdiv{r|}p\t{%st(0), $op|$op, st(0)}", (DIV_FPrST0 RST:$op)>;
3139 // We accept "fnstsw %eax" even though it only writes %ax.
3140 def : InstAlias<"fnstsw\t{%eax|eax}", (FNSTSW16r)>;
3141 def : InstAlias<"fnstsw\t{%al|al}" , (FNSTSW16r)>;
3142 def : InstAlias<"fnstsw" , (FNSTSW16r)>;
3144 // lcall and ljmp aliases. This seems to be an odd mapping in 64-bit mode, but
3145 // this is compatible with what GAS does.
3146 def : InstAlias<"lcall\t$seg, $off", (FARCALL32i i32imm:$off, i16imm:$seg), 0>, Requires<[In32BitMode]>;
3147 def : InstAlias<"ljmp\t$seg, $off", (FARJMP32i i32imm:$off, i16imm:$seg), 0>, Requires<[In32BitMode]>;
3148 def : InstAlias<"lcall\t{*}$dst", (FARCALL32m opaque48mem:$dst), 0>, Requires<[Not16BitMode]>;
3149 def : InstAlias<"ljmp\t{*}$dst", (FARJMP32m opaque48mem:$dst), 0>, Requires<[Not16BitMode]>;
3150 def : InstAlias<"lcall\t$seg, $off", (FARCALL16i i16imm:$off, i16imm:$seg), 0>, Requires<[In16BitMode]>;
3151 def : InstAlias<"ljmp\t$seg, $off", (FARJMP16i i16imm:$off, i16imm:$seg), 0>, Requires<[In16BitMode]>;
3152 def : InstAlias<"lcall\t{*}$dst", (FARCALL16m opaque32mem:$dst), 0>, Requires<[In16BitMode]>;
3153 def : InstAlias<"ljmp\t{*}$dst", (FARJMP16m opaque32mem:$dst), 0>, Requires<[In16BitMode]>;
3155 def : InstAlias<"call\t{*}$dst", (CALL64m i64mem:$dst), 0>, Requires<[In64BitMode]>;
3156 def : InstAlias<"jmp\t{*}$dst", (JMP64m i64mem:$dst), 0>, Requires<[In64BitMode]>;
3157 def : InstAlias<"call\t{*}$dst", (CALL32m i32mem:$dst), 0>, Requires<[In32BitMode]>;
3158 def : InstAlias<"jmp\t{*}$dst", (JMP32m i32mem:$dst), 0>, Requires<[In32BitMode]>;
3159 def : InstAlias<"call\t{*}$dst", (CALL16m i16mem:$dst), 0>, Requires<[In16BitMode]>;
3160 def : InstAlias<"jmp\t{*}$dst", (JMP16m i16mem:$dst), 0>, Requires<[In16BitMode]>;
3163 // "imul <imm>, B" is an alias for "imul <imm>, B, B".
3164 def : InstAlias<"imul{w}\t{$imm, $r|$r, $imm}", (IMUL16rri GR16:$r, GR16:$r, i16imm:$imm), 0>;
3165 def : InstAlias<"imul{w}\t{$imm, $r|$r, $imm}", (IMUL16rri8 GR16:$r, GR16:$r, i16i8imm:$imm), 0>;
3166 def : InstAlias<"imul{l}\t{$imm, $r|$r, $imm}", (IMUL32rri GR32:$r, GR32:$r, i32imm:$imm), 0>;
3167 def : InstAlias<"imul{l}\t{$imm, $r|$r, $imm}", (IMUL32rri8 GR32:$r, GR32:$r, i32i8imm:$imm), 0>;
3168 def : InstAlias<"imul{q}\t{$imm, $r|$r, $imm}", (IMUL64rri32 GR64:$r, GR64:$r, i64i32imm:$imm), 0>;
3169 def : InstAlias<"imul{q}\t{$imm, $r|$r, $imm}", (IMUL64rri8 GR64:$r, GR64:$r, i64i8imm:$imm), 0>;
3171 // ins aliases. Accept the mnemonic suffix being omitted because it's implicit
3172 // in the destination.
3173 def : InstAlias<"ins\t{%dx, $dst|$dst, dx}", (INSB dstidx8:$dst), 0>;
3174 def : InstAlias<"ins\t{%dx, $dst|$dst, dx}", (INSW dstidx16:$dst), 0>;
3175 def : InstAlias<"ins\t{%dx, $dst|$dst, dx}", (INSL dstidx32:$dst), 0>;
3177 // outs aliases. Accept the mnemonic suffix being omitted because it's implicit
3179 def : InstAlias<"outs\t{$src, %dx|dx, $src}", (OUTSB srcidx8:$src), 0>;
3180 def : InstAlias<"outs\t{$src, %dx|dx, $src}", (OUTSW srcidx16:$src), 0>;
3181 def : InstAlias<"outs\t{$src, %dx|dx, $src}", (OUTSL srcidx32:$src), 0>;
3183 // inb %dx -> inb %al, %dx
3184 def : InstAlias<"inb\t{%dx|dx}", (IN8rr), 0>;
3185 def : InstAlias<"inw\t{%dx|dx}", (IN16rr), 0>;
3186 def : InstAlias<"inl\t{%dx|dx}", (IN32rr), 0>;
3187 def : InstAlias<"inb\t$port", (IN8ri u8imm:$port), 0>;
3188 def : InstAlias<"inw\t$port", (IN16ri u8imm:$port), 0>;
3189 def : InstAlias<"inl\t$port", (IN32ri u8imm:$port), 0>;
3192 // jmp and call aliases for lcall and ljmp. jmp $42,$5 -> ljmp
3193 def : InstAlias<"call\t$seg, $off", (FARCALL16i i16imm:$off, i16imm:$seg)>, Requires<[In16BitMode]>;
3194 def : InstAlias<"jmp\t$seg, $off", (FARJMP16i i16imm:$off, i16imm:$seg)>, Requires<[In16BitMode]>;
3195 def : InstAlias<"call\t$seg, $off", (FARCALL32i i32imm:$off, i16imm:$seg)>, Requires<[In32BitMode]>;
3196 def : InstAlias<"jmp\t$seg, $off", (FARJMP32i i32imm:$off, i16imm:$seg)>, Requires<[In32BitMode]>;
3197 def : InstAlias<"callw\t$seg, $off", (FARCALL16i i16imm:$off, i16imm:$seg)>, Requires<[Not64BitMode]>;
3198 def : InstAlias<"jmpw\t$seg, $off", (FARJMP16i i16imm:$off, i16imm:$seg)>, Requires<[Not64BitMode]>;
3199 def : InstAlias<"calll\t$seg, $off", (FARCALL32i i32imm:$off, i16imm:$seg)>, Requires<[Not64BitMode]>;
3200 def : InstAlias<"jmpl\t$seg, $off", (FARJMP32i i32imm:$off, i16imm:$seg)>, Requires<[Not64BitMode]>;
3202 // Force mov without a suffix with a segment and mem to prefer the 'l' form of
3203 // the move. All segment/mem forms are equivalent, this has the shortest
3205 def : InstAlias<"mov\t{$mem, $seg|$seg, $mem}", (MOV16sm SEGMENT_REG:$seg, i16mem:$mem), 0>;
3206 def : InstAlias<"mov\t{$seg, $mem|$mem, $seg}", (MOV16ms i16mem:$mem, SEGMENT_REG:$seg), 0>;
3208 // Match 'movq <largeimm>, <reg>' as an alias for movabsq.
3209 def : InstAlias<"mov{q}\t{$imm, $reg|$reg, $imm}", (MOV64ri GR64:$reg, i64imm:$imm), 0>;
3211 // Match 'movq GR64, MMX' as an alias for movd.
3212 def : InstAlias<"movq\t{$src, $dst|$dst, $src}",
3213 (MMX_MOVD64to64rr VR64:$dst, GR64:$src), 0>;
3214 def : InstAlias<"movq\t{$src, $dst|$dst, $src}",
3215 (MMX_MOVD64from64rr GR64:$dst, VR64:$src), 0>;
3218 def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX16rr8 GR16:$dst, GR8:$src), 0>;
3219 def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX16rm8 GR16:$dst, i8mem:$src), 0>;
3220 def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX32rr8 GR32:$dst, GR8:$src), 0>;
3221 def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX32rr16 GR32:$dst, GR16:$src), 0>;
3222 def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX64rr8 GR64:$dst, GR8:$src), 0>;
3223 def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX64rr16 GR64:$dst, GR16:$src), 0>;
3224 def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX64rr32 GR64:$dst, GR32:$src), 0>;
3227 def : InstAlias<"movzx\t{$src, $dst|$dst, $src}", (MOVZX16rr8 GR16:$dst, GR8:$src), 0>;
3228 def : InstAlias<"movzx\t{$src, $dst|$dst, $src}", (MOVZX16rm8 GR16:$dst, i8mem:$src), 0>;
3229 def : InstAlias<"movzx\t{$src, $dst|$dst, $src}", (MOVZX32rr8 GR32:$dst, GR8:$src), 0>;
3230 def : InstAlias<"movzx\t{$src, $dst|$dst, $src}", (MOVZX32rr16 GR32:$dst, GR16:$src), 0>;
3231 def : InstAlias<"movzx\t{$src, $dst|$dst, $src}", (MOVZX64rr8 GR64:$dst, GR8:$src), 0>;
3232 def : InstAlias<"movzx\t{$src, $dst|$dst, $src}", (MOVZX64rr16 GR64:$dst, GR16:$src), 0>;
3233 // Note: No GR32->GR64 movzx form.
3235 // outb %dx -> outb %al, %dx
3236 def : InstAlias<"outb\t{%dx|dx}", (OUT8rr), 0>;
3237 def : InstAlias<"outw\t{%dx|dx}", (OUT16rr), 0>;
3238 def : InstAlias<"outl\t{%dx|dx}", (OUT32rr), 0>;
3239 def : InstAlias<"outb\t$port", (OUT8ir u8imm:$port), 0>;
3240 def : InstAlias<"outw\t$port", (OUT16ir u8imm:$port), 0>;
3241 def : InstAlias<"outl\t$port", (OUT32ir u8imm:$port), 0>;
3243 // 'sldt <mem>' can be encoded with either sldtw or sldtq with the same
3244 // effect (both store to a 16-bit mem). Force to sldtw to avoid ambiguity
3245 // errors, since its encoding is the most compact.
3246 def : InstAlias<"sldt $mem", (SLDT16m i16mem:$mem), 0>;
3248 // shld/shrd op,op -> shld op, op, CL
3249 def : InstAlias<"shld{w}\t{$r2, $r1|$r1, $r2}", (SHLD16rrCL GR16:$r1, GR16:$r2), 0>;
3250 def : InstAlias<"shld{l}\t{$r2, $r1|$r1, $r2}", (SHLD32rrCL GR32:$r1, GR32:$r2), 0>;
3251 def : InstAlias<"shld{q}\t{$r2, $r1|$r1, $r2}", (SHLD64rrCL GR64:$r1, GR64:$r2), 0>;
3252 def : InstAlias<"shrd{w}\t{$r2, $r1|$r1, $r2}", (SHRD16rrCL GR16:$r1, GR16:$r2), 0>;
3253 def : InstAlias<"shrd{l}\t{$r2, $r1|$r1, $r2}", (SHRD32rrCL GR32:$r1, GR32:$r2), 0>;
3254 def : InstAlias<"shrd{q}\t{$r2, $r1|$r1, $r2}", (SHRD64rrCL GR64:$r1, GR64:$r2), 0>;
3256 def : InstAlias<"shld{w}\t{$reg, $mem|$mem, $reg}", (SHLD16mrCL i16mem:$mem, GR16:$reg), 0>;
3257 def : InstAlias<"shld{l}\t{$reg, $mem|$mem, $reg}", (SHLD32mrCL i32mem:$mem, GR32:$reg), 0>;
3258 def : InstAlias<"shld{q}\t{$reg, $mem|$mem, $reg}", (SHLD64mrCL i64mem:$mem, GR64:$reg), 0>;
3259 def : InstAlias<"shrd{w}\t{$reg, $mem|$mem, $reg}", (SHRD16mrCL i16mem:$mem, GR16:$reg), 0>;
3260 def : InstAlias<"shrd{l}\t{$reg, $mem|$mem, $reg}", (SHRD32mrCL i32mem:$mem, GR32:$reg), 0>;
3261 def : InstAlias<"shrd{q}\t{$reg, $mem|$mem, $reg}", (SHRD64mrCL i64mem:$mem, GR64:$reg), 0>;
3263 /* FIXME: This is disabled because the asm matcher is currently incapable of
3264 * matching a fixed immediate like $1.
3265 // "shl X, $1" is an alias for "shl X".
3266 multiclass ShiftRotateByOneAlias<string Mnemonic, string Opc> {
3267 def : InstAlias<!strconcat(Mnemonic, "b $op, $$1"),
3268 (!cast<Instruction>(!strconcat(Opc, "8r1")) GR8:$op)>;
3269 def : InstAlias<!strconcat(Mnemonic, "w $op, $$1"),
3270 (!cast<Instruction>(!strconcat(Opc, "16r1")) GR16:$op)>;
3271 def : InstAlias<!strconcat(Mnemonic, "l $op, $$1"),
3272 (!cast<Instruction>(!strconcat(Opc, "32r1")) GR32:$op)>;
3273 def : InstAlias<!strconcat(Mnemonic, "q $op, $$1"),
3274 (!cast<Instruction>(!strconcat(Opc, "64r1")) GR64:$op)>;
3275 def : InstAlias<!strconcat(Mnemonic, "b $op, $$1"),
3276 (!cast<Instruction>(!strconcat(Opc, "8m1")) i8mem:$op)>;
3277 def : InstAlias<!strconcat(Mnemonic, "w $op, $$1"),
3278 (!cast<Instruction>(!strconcat(Opc, "16m1")) i16mem:$op)>;
3279 def : InstAlias<!strconcat(Mnemonic, "l $op, $$1"),
3280 (!cast<Instruction>(!strconcat(Opc, "32m1")) i32mem:$op)>;
3281 def : InstAlias<!strconcat(Mnemonic, "q $op, $$1"),
3282 (!cast<Instruction>(!strconcat(Opc, "64m1")) i64mem:$op)>;
3285 defm : ShiftRotateByOneAlias<"rcl", "RCL">;
3286 defm : ShiftRotateByOneAlias<"rcr", "RCR">;
3287 defm : ShiftRotateByOneAlias<"rol", "ROL">;
3288 defm : ShiftRotateByOneAlias<"ror", "ROR">;
3291 // test: We accept "testX <reg>, <mem>" and "testX <mem>, <reg>" as synonyms.
3292 def : InstAlias<"test{b}\t{$mem, $val|$val, $mem}",
3293 (TEST8mr i8mem :$mem, GR8 :$val), 0>;
3294 def : InstAlias<"test{w}\t{$mem, $val|$val, $mem}",
3295 (TEST16mr i16mem:$mem, GR16:$val), 0>;
3296 def : InstAlias<"test{l}\t{$mem, $val|$val, $mem}",
3297 (TEST32mr i32mem:$mem, GR32:$val), 0>;
3298 def : InstAlias<"test{q}\t{$mem, $val|$val, $mem}",
3299 (TEST64mr i64mem:$mem, GR64:$val), 0>;
3301 // xchg: We accept "xchgX <reg>, <mem>" and "xchgX <mem>, <reg>" as synonyms.
3302 def : InstAlias<"xchg{b}\t{$mem, $val|$val, $mem}",
3303 (XCHG8rm GR8 :$val, i8mem :$mem), 0>;
3304 def : InstAlias<"xchg{w}\t{$mem, $val|$val, $mem}",
3305 (XCHG16rm GR16:$val, i16mem:$mem), 0>;
3306 def : InstAlias<"xchg{l}\t{$mem, $val|$val, $mem}",
3307 (XCHG32rm GR32:$val, i32mem:$mem), 0>;
3308 def : InstAlias<"xchg{q}\t{$mem, $val|$val, $mem}",
3309 (XCHG64rm GR64:$val, i64mem:$mem), 0>;
3311 // xchg: We accept "xchgX <reg>, %eax" and "xchgX %eax, <reg>" as synonyms.
3312 def : InstAlias<"xchg{w}\t{%ax, $src|$src, ax}", (XCHG16ar GR16:$src), 0>;
3313 def : InstAlias<"xchg{l}\t{%eax, $src|$src, eax}",
3314 (XCHG32ar GR32:$src), 0>, Requires<[Not64BitMode]>;
3315 def : InstAlias<"xchg{l}\t{%eax, $src|$src, eax}",
3316 (XCHG32ar64 GR32_NOAX:$src), 0>, Requires<[In64BitMode]>;
3317 def : InstAlias<"xchg{q}\t{%rax, $src|$src, rax}", (XCHG64ar GR64:$src), 0>;
3319 // These aliases exist to get the parser to prioritize matching 8-bit
3320 // immediate encodings over matching the implicit ax/eax/rax encodings. By
3321 // explicitly mentioning the A register here, these entries will be ordered
3322 // first due to the more explicit immediate type.
3323 def : InstAlias<"adc{w}\t{$imm, %ax|ax, $imm}", (ADC16ri8 AX, i16i8imm:$imm), 0>;
3324 def : InstAlias<"add{w}\t{$imm, %ax|ax, $imm}", (ADD16ri8 AX, i16i8imm:$imm), 0>;
3325 def : InstAlias<"and{w}\t{$imm, %ax|ax, $imm}", (AND16ri8 AX, i16i8imm:$imm), 0>;
3326 def : InstAlias<"cmp{w}\t{$imm, %ax|ax, $imm}", (CMP16ri8 AX, i16i8imm:$imm), 0>;
3327 def : InstAlias<"or{w}\t{$imm, %ax|ax, $imm}", (OR16ri8 AX, i16i8imm:$imm), 0>;
3328 def : InstAlias<"sbb{w}\t{$imm, %ax|ax, $imm}", (SBB16ri8 AX, i16i8imm:$imm), 0>;
3329 def : InstAlias<"sub{w}\t{$imm, %ax|ax, $imm}", (SUB16ri8 AX, i16i8imm:$imm), 0>;
3330 def : InstAlias<"xor{w}\t{$imm, %ax|ax, $imm}", (XOR16ri8 AX, i16i8imm:$imm), 0>;
3332 def : InstAlias<"adc{l}\t{$imm, %eax|eax, $imm}", (ADC32ri8 EAX, i32i8imm:$imm), 0>;
3333 def : InstAlias<"add{l}\t{$imm, %eax|eax, $imm}", (ADD32ri8 EAX, i32i8imm:$imm), 0>;
3334 def : InstAlias<"and{l}\t{$imm, %eax|eax, $imm}", (AND32ri8 EAX, i32i8imm:$imm), 0>;
3335 def : InstAlias<"cmp{l}\t{$imm, %eax|eax, $imm}", (CMP32ri8 EAX, i32i8imm:$imm), 0>;
3336 def : InstAlias<"or{l}\t{$imm, %eax|eax, $imm}", (OR32ri8 EAX, i32i8imm:$imm), 0>;
3337 def : InstAlias<"sbb{l}\t{$imm, %eax|eax, $imm}", (SBB32ri8 EAX, i32i8imm:$imm), 0>;
3338 def : InstAlias<"sub{l}\t{$imm, %eax|eax, $imm}", (SUB32ri8 EAX, i32i8imm:$imm), 0>;
3339 def : InstAlias<"xor{l}\t{$imm, %eax|eax, $imm}", (XOR32ri8 EAX, i32i8imm:$imm), 0>;
3341 def : InstAlias<"adc{q}\t{$imm, %rax|rax, $imm}", (ADC64ri8 RAX, i64i8imm:$imm), 0>;
3342 def : InstAlias<"add{q}\t{$imm, %rax|rax, $imm}", (ADD64ri8 RAX, i64i8imm:$imm), 0>;
3343 def : InstAlias<"and{q}\t{$imm, %rax|rax, $imm}", (AND64ri8 RAX, i64i8imm:$imm), 0>;
3344 def : InstAlias<"cmp{q}\t{$imm, %rax|rax, $imm}", (CMP64ri8 RAX, i64i8imm:$imm), 0>;
3345 def : InstAlias<"or{q}\t{$imm, %rax|rax, $imm}", (OR64ri8 RAX, i64i8imm:$imm), 0>;
3346 def : InstAlias<"sbb{q}\t{$imm, %rax|rax, $imm}", (SBB64ri8 RAX, i64i8imm:$imm), 0>;
3347 def : InstAlias<"sub{q}\t{$imm, %rax|rax, $imm}", (SUB64ri8 RAX, i64i8imm:$imm), 0>;
3348 def : InstAlias<"xor{q}\t{$imm, %rax|rax, $imm}", (XOR64ri8 RAX, i64i8imm:$imm), 0>;