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()">;
941 def UseRetpoline : Predicate<"Subtarget->useRetpoline()">;
942 def NotUseRetpoline : Predicate<"!Subtarget->useRetpoline()">;
944 //===----------------------------------------------------------------------===//
945 // X86 Instruction Format Definitions.
948 include "X86InstrFormats.td"
950 //===----------------------------------------------------------------------===//
951 // Pattern fragments.
954 // X86 specific condition code. These correspond to CondCode in
955 // X86InstrInfo.h. They must be kept in synch.
956 def X86_COND_A : PatLeaf<(i8 0)>; // alt. COND_NBE
957 def X86_COND_AE : PatLeaf<(i8 1)>; // alt. COND_NC
958 def X86_COND_B : PatLeaf<(i8 2)>; // alt. COND_C
959 def X86_COND_BE : PatLeaf<(i8 3)>; // alt. COND_NA
960 def X86_COND_E : PatLeaf<(i8 4)>; // alt. COND_Z
961 def X86_COND_G : PatLeaf<(i8 5)>; // alt. COND_NLE
962 def X86_COND_GE : PatLeaf<(i8 6)>; // alt. COND_NL
963 def X86_COND_L : PatLeaf<(i8 7)>; // alt. COND_NGE
964 def X86_COND_LE : PatLeaf<(i8 8)>; // alt. COND_NG
965 def X86_COND_NE : PatLeaf<(i8 9)>; // alt. COND_NZ
966 def X86_COND_NO : PatLeaf<(i8 10)>;
967 def X86_COND_NP : PatLeaf<(i8 11)>; // alt. COND_PO
968 def X86_COND_NS : PatLeaf<(i8 12)>;
969 def X86_COND_O : PatLeaf<(i8 13)>;
970 def X86_COND_P : PatLeaf<(i8 14)>; // alt. COND_PE
971 def X86_COND_S : PatLeaf<(i8 15)>;
973 def i16immSExt8 : ImmLeaf<i16, [{ return isInt<8>(Imm); }]>;
974 def i32immSExt8 : ImmLeaf<i32, [{ return isInt<8>(Imm); }]>;
975 def i64immSExt8 : ImmLeaf<i64, [{ return isInt<8>(Imm); }]>;
976 def i64immSExt32 : ImmLeaf<i64, [{ return isInt<32>(Imm); }]>;
978 // FIXME: Ideally we would just replace the above i*immSExt* matchers with
979 // relocImm-based matchers, but then FastISel would be unable to use them.
980 def i64relocImmSExt8 : PatLeaf<(i64 relocImm), [{
981 return isSExtRelocImm<8>(N);
983 def i64relocImmSExt32 : PatLeaf<(i64 relocImm), [{
984 return isSExtRelocImm<32>(N);
987 // If we have multiple users of an immediate, it's much smaller to reuse
988 // the register, rather than encode the immediate in every instruction.
989 // This has the risk of increasing register pressure from stretched live
990 // ranges, however, the immediates should be trivial to rematerialize by
991 // the RA in the event of high register pressure.
992 // TODO : This is currently enabled for stores and binary ops. There are more
993 // cases for which this can be enabled, though this catches the bulk of the
995 // TODO2 : This should really also be enabled under O2, but there's currently
996 // an issue with RA where we don't pull the constants into their users
997 // when we rematerialize them. I'll follow-up on enabling O2 after we fix that
999 // TODO3 : This is currently limited to single basic blocks (DAG creation
1000 // pulls block immediates to the top and merges them if necessary).
1001 // Eventually, it would be nice to allow ConstantHoisting to merge constants
1002 // globally for potentially added savings.
1004 def imm8_su : PatLeaf<(i8 relocImm), [{
1005 return !shouldAvoidImmediateInstFormsForSize(N);
1007 def imm16_su : PatLeaf<(i16 relocImm), [{
1008 return !shouldAvoidImmediateInstFormsForSize(N);
1010 def imm32_su : PatLeaf<(i32 relocImm), [{
1011 return !shouldAvoidImmediateInstFormsForSize(N);
1013 def i64immSExt32_su : PatLeaf<(i64immSExt32), [{
1014 return !shouldAvoidImmediateInstFormsForSize(N);
1017 def i16immSExt8_su : PatLeaf<(i16immSExt8), [{
1018 return !shouldAvoidImmediateInstFormsForSize(N);
1020 def i32immSExt8_su : PatLeaf<(i32immSExt8), [{
1021 return !shouldAvoidImmediateInstFormsForSize(N);
1023 def i64immSExt8_su : PatLeaf<(i64immSExt8), [{
1024 return !shouldAvoidImmediateInstFormsForSize(N);
1027 def i64relocImmSExt8_su : PatLeaf<(i64relocImmSExt8), [{
1028 return !shouldAvoidImmediateInstFormsForSize(N);
1030 def i64relocImmSExt32_su : PatLeaf<(i64relocImmSExt32), [{
1031 return !shouldAvoidImmediateInstFormsForSize(N);
1034 // i64immZExt32 predicate - True if the 64-bit immediate fits in a 32-bit
1036 def i64immZExt32 : ImmLeaf<i64, [{ return isUInt<32>(Imm); }]>;
1038 def i64immZExt32SExt8 : ImmLeaf<i64, [{
1039 return isUInt<32>(Imm) && isInt<8>(static_cast<int32_t>(Imm));
1042 // Helper fragments for loads.
1043 // It's always safe to treat a anyext i16 load as a i32 load if the i16 is
1044 // known to be 32-bit aligned or better. Ditto for i8 to i16.
1045 def loadi16 : PatFrag<(ops node:$ptr), (i16 (unindexedload node:$ptr)), [{
1046 LoadSDNode *LD = cast<LoadSDNode>(N);
1047 ISD::LoadExtType ExtType = LD->getExtensionType();
1048 if (ExtType == ISD::NON_EXTLOAD)
1050 if (ExtType == ISD::EXTLOAD)
1051 return LD->getAlignment() >= 2 && !LD->isVolatile();
1055 def loadi16_anyext : PatFrag<(ops node:$ptr), (i32 (unindexedload node:$ptr)),[{
1056 LoadSDNode *LD = cast<LoadSDNode>(N);
1057 ISD::LoadExtType ExtType = LD->getExtensionType();
1058 if (ExtType == ISD::EXTLOAD)
1059 return LD->getAlignment() >= 2 && !LD->isVolatile();
1063 def loadi32 : PatFrag<(ops node:$ptr), (i32 (unindexedload node:$ptr)), [{
1064 LoadSDNode *LD = cast<LoadSDNode>(N);
1065 ISD::LoadExtType ExtType = LD->getExtensionType();
1066 if (ExtType == ISD::NON_EXTLOAD)
1068 if (ExtType == ISD::EXTLOAD)
1069 return LD->getAlignment() >= 4 && !LD->isVolatile();
1073 def loadi8 : PatFrag<(ops node:$ptr), (i8 (load node:$ptr))>;
1074 def loadi64 : PatFrag<(ops node:$ptr), (i64 (load node:$ptr))>;
1075 def loadf32 : PatFrag<(ops node:$ptr), (f32 (load node:$ptr))>;
1076 def loadf64 : PatFrag<(ops node:$ptr), (f64 (load node:$ptr))>;
1077 def loadf80 : PatFrag<(ops node:$ptr), (f80 (load node:$ptr))>;
1078 def loadf128 : PatFrag<(ops node:$ptr), (f128 (load node:$ptr))>;
1080 def sextloadi16i8 : PatFrag<(ops node:$ptr), (i16 (sextloadi8 node:$ptr))>;
1081 def sextloadi32i8 : PatFrag<(ops node:$ptr), (i32 (sextloadi8 node:$ptr))>;
1082 def sextloadi32i16 : PatFrag<(ops node:$ptr), (i32 (sextloadi16 node:$ptr))>;
1083 def sextloadi64i8 : PatFrag<(ops node:$ptr), (i64 (sextloadi8 node:$ptr))>;
1084 def sextloadi64i16 : PatFrag<(ops node:$ptr), (i64 (sextloadi16 node:$ptr))>;
1085 def sextloadi64i32 : PatFrag<(ops node:$ptr), (i64 (sextloadi32 node:$ptr))>;
1087 def zextloadi8i1 : PatFrag<(ops node:$ptr), (i8 (zextloadi1 node:$ptr))>;
1088 def zextloadi16i1 : PatFrag<(ops node:$ptr), (i16 (zextloadi1 node:$ptr))>;
1089 def zextloadi32i1 : PatFrag<(ops node:$ptr), (i32 (zextloadi1 node:$ptr))>;
1090 def zextloadi16i8 : PatFrag<(ops node:$ptr), (i16 (zextloadi8 node:$ptr))>;
1091 def zextloadi32i8 : PatFrag<(ops node:$ptr), (i32 (zextloadi8 node:$ptr))>;
1092 def zextloadi32i16 : PatFrag<(ops node:$ptr), (i32 (zextloadi16 node:$ptr))>;
1093 def zextloadi64i1 : PatFrag<(ops node:$ptr), (i64 (zextloadi1 node:$ptr))>;
1094 def zextloadi64i8 : PatFrag<(ops node:$ptr), (i64 (zextloadi8 node:$ptr))>;
1095 def zextloadi64i16 : PatFrag<(ops node:$ptr), (i64 (zextloadi16 node:$ptr))>;
1096 def zextloadi64i32 : PatFrag<(ops node:$ptr), (i64 (zextloadi32 node:$ptr))>;
1098 def extloadi8i1 : PatFrag<(ops node:$ptr), (i8 (extloadi1 node:$ptr))>;
1099 def extloadi16i1 : PatFrag<(ops node:$ptr), (i16 (extloadi1 node:$ptr))>;
1100 def extloadi32i1 : PatFrag<(ops node:$ptr), (i32 (extloadi1 node:$ptr))>;
1101 def extloadi16i8 : PatFrag<(ops node:$ptr), (i16 (extloadi8 node:$ptr))>;
1102 def extloadi32i8 : PatFrag<(ops node:$ptr), (i32 (extloadi8 node:$ptr))>;
1103 def extloadi32i16 : PatFrag<(ops node:$ptr), (i32 (extloadi16 node:$ptr))>;
1104 def extloadi64i1 : PatFrag<(ops node:$ptr), (i64 (extloadi1 node:$ptr))>;
1105 def extloadi64i8 : PatFrag<(ops node:$ptr), (i64 (extloadi8 node:$ptr))>;
1106 def extloadi64i16 : PatFrag<(ops node:$ptr), (i64 (extloadi16 node:$ptr))>;
1107 def extloadi64i32 : PatFrag<(ops node:$ptr), (i64 (extloadi32 node:$ptr))>;
1110 // An 'and' node with a single use.
1111 def and_su : PatFrag<(ops node:$lhs, node:$rhs), (and node:$lhs, node:$rhs), [{
1112 return N->hasOneUse();
1114 // An 'srl' node with a single use.
1115 def srl_su : PatFrag<(ops node:$lhs, node:$rhs), (srl node:$lhs, node:$rhs), [{
1116 return N->hasOneUse();
1118 // An 'trunc' node with a single use.
1119 def trunc_su : PatFrag<(ops node:$src), (trunc node:$src), [{
1120 return N->hasOneUse();
1123 //===----------------------------------------------------------------------===//
1124 // Instruction list.
1128 let hasSideEffects = 0, SchedRW = [WriteZero] in {
1129 def NOOP : I<0x90, RawFrm, (outs), (ins), "nop", [], IIC_NOP>;
1130 def NOOPW : I<0x1f, MRMXm, (outs), (ins i16mem:$zero),
1131 "nop{w}\t$zero", [], IIC_NOP>, TB, OpSize16;
1132 def NOOPL : I<0x1f, MRMXm, (outs), (ins i32mem:$zero),
1133 "nop{l}\t$zero", [], IIC_NOP>, TB, OpSize32;
1134 def NOOPQ : RI<0x1f, MRMXm, (outs), (ins i64mem:$zero),
1135 "nop{q}\t$zero", [], IIC_NOP>, TB,
1136 Requires<[In64BitMode]>;
1137 // Also allow register so we can assemble/disassemble
1138 def NOOPWr : I<0x1f, MRMXr, (outs), (ins GR16:$zero),
1139 "nop{w}\t$zero", [], IIC_NOP>, TB, OpSize16;
1140 def NOOPLr : I<0x1f, MRMXr, (outs), (ins GR32:$zero),
1141 "nop{l}\t$zero", [], IIC_NOP>, TB, OpSize32;
1142 def NOOPQr : RI<0x1f, MRMXr, (outs), (ins GR64:$zero),
1143 "nop{q}\t$zero", [], IIC_NOP>, TB,
1144 Requires<[In64BitMode]>;
1148 // Constructing a stack frame.
1149 def ENTER : Ii16<0xC8, RawFrmImm8, (outs), (ins i16imm:$len, i8imm:$lvl),
1150 "enter\t$len, $lvl", [], IIC_ENTER>, Sched<[WriteMicrocoded]>;
1152 let SchedRW = [WriteALU] in {
1153 let Defs = [EBP, ESP], Uses = [EBP, ESP], mayLoad = 1, hasSideEffects=0 in
1154 def LEAVE : I<0xC9, RawFrm,
1155 (outs), (ins), "leave", [], IIC_LEAVE>,
1156 Requires<[Not64BitMode]>;
1158 let Defs = [RBP,RSP], Uses = [RBP,RSP], mayLoad = 1, hasSideEffects = 0 in
1159 def LEAVE64 : I<0xC9, RawFrm,
1160 (outs), (ins), "leave", [], IIC_LEAVE>,
1161 Requires<[In64BitMode]>;
1164 //===----------------------------------------------------------------------===//
1165 // Miscellaneous Instructions.
1168 let isBarrier = 1, hasSideEffects = 1, usesCustomInserter = 1,
1169 SchedRW = [WriteSystem] in
1170 def Int_eh_sjlj_setup_dispatch
1171 : PseudoI<(outs), (ins), [(X86eh_sjlj_setup_dispatch)]>;
1173 let Defs = [ESP], Uses = [ESP], hasSideEffects=0 in {
1174 let mayLoad = 1, SchedRW = [WriteLoad] in {
1175 def POP16r : I<0x58, AddRegFrm, (outs GR16:$reg), (ins), "pop{w}\t$reg", [],
1176 IIC_POP_REG16>, OpSize16;
1177 def POP32r : I<0x58, AddRegFrm, (outs GR32:$reg), (ins), "pop{l}\t$reg", [],
1178 IIC_POP_REG>, OpSize32, Requires<[Not64BitMode]>;
1179 def POP16rmr: I<0x8F, MRM0r, (outs GR16:$reg), (ins), "pop{w}\t$reg", [],
1180 IIC_POP_REG>, OpSize16;
1181 def POP32rmr: I<0x8F, MRM0r, (outs GR32:$reg), (ins), "pop{l}\t$reg", [],
1182 IIC_POP_REG>, OpSize32, Requires<[Not64BitMode]>;
1183 } // mayLoad, SchedRW
1184 let mayStore = 1, mayLoad = 1, SchedRW = [WriteRMW] in {
1185 def POP16rmm: I<0x8F, MRM0m, (outs), (ins i16mem:$dst), "pop{w}\t$dst", [],
1186 IIC_POP_MEM>, OpSize16;
1187 def POP32rmm: I<0x8F, MRM0m, (outs), (ins i32mem:$dst), "pop{l}\t$dst", [],
1188 IIC_POP_MEM>, OpSize32, Requires<[Not64BitMode]>;
1189 } // mayStore, mayLoad, WriteRMW
1191 let mayStore = 1, SchedRW = [WriteStore] in {
1192 def PUSH16r : I<0x50, AddRegFrm, (outs), (ins GR16:$reg), "push{w}\t$reg",[],
1193 IIC_PUSH_REG>, OpSize16;
1194 def PUSH32r : I<0x50, AddRegFrm, (outs), (ins GR32:$reg), "push{l}\t$reg",[],
1195 IIC_PUSH_REG>, OpSize32, Requires<[Not64BitMode]>;
1196 def PUSH16rmr: I<0xFF, MRM6r, (outs), (ins GR16:$reg), "push{w}\t$reg",[],
1197 IIC_PUSH_REG>, OpSize16;
1198 def PUSH32rmr: I<0xFF, MRM6r, (outs), (ins GR32:$reg), "push{l}\t$reg",[],
1199 IIC_PUSH_REG>, OpSize32, Requires<[Not64BitMode]>;
1201 def PUSH16i8 : Ii8<0x6a, RawFrm, (outs), (ins i16i8imm:$imm),
1202 "push{w}\t$imm", [], IIC_PUSH_IMM>, OpSize16;
1203 def PUSHi16 : Ii16<0x68, RawFrm, (outs), (ins i16imm:$imm),
1204 "push{w}\t$imm", [], IIC_PUSH_IMM>, OpSize16;
1206 def PUSH32i8 : Ii8<0x6a, RawFrm, (outs), (ins i32i8imm:$imm),
1207 "push{l}\t$imm", [], IIC_PUSH_IMM>, OpSize32,
1208 Requires<[Not64BitMode]>;
1209 def PUSHi32 : Ii32<0x68, RawFrm, (outs), (ins i32imm:$imm),
1210 "push{l}\t$imm", [], IIC_PUSH_IMM>, OpSize32,
1211 Requires<[Not64BitMode]>;
1212 } // mayStore, SchedRW
1214 let mayLoad = 1, mayStore = 1, SchedRW = [WriteRMW] in {
1215 def PUSH16rmm: I<0xFF, MRM6m, (outs), (ins i16mem:$src), "push{w}\t$src",[],
1216 IIC_PUSH_MEM>, OpSize16;
1217 def PUSH32rmm: I<0xFF, MRM6m, (outs), (ins i32mem:$src), "push{l}\t$src",[],
1218 IIC_PUSH_MEM>, OpSize32, Requires<[Not64BitMode]>;
1219 } // mayLoad, mayStore, SchedRW
1223 let mayLoad = 1, mayStore = 1, usesCustomInserter = 1,
1224 SchedRW = [WriteRMW], Defs = [ESP] in {
1226 def RDFLAGS32 : PseudoI<(outs GR32:$dst), (ins),
1227 [(set GR32:$dst, (int_x86_flags_read_u32))]>,
1228 Requires<[Not64BitMode]>;
1231 def RDFLAGS64 : PseudoI<(outs GR64:$dst), (ins),
1232 [(set GR64:$dst, (int_x86_flags_read_u64))]>,
1233 Requires<[In64BitMode]>;
1236 let mayLoad = 1, mayStore = 1, usesCustomInserter = 1,
1237 SchedRW = [WriteRMW] in {
1238 let Defs = [ESP, EFLAGS], Uses = [ESP] in
1239 def WRFLAGS32 : PseudoI<(outs), (ins GR32:$src),
1240 [(int_x86_flags_write_u32 GR32:$src)]>,
1241 Requires<[Not64BitMode]>;
1243 let Defs = [RSP, EFLAGS], Uses = [RSP] in
1244 def WRFLAGS64 : PseudoI<(outs), (ins GR64:$src),
1245 [(int_x86_flags_write_u64 GR64:$src)]>,
1246 Requires<[In64BitMode]>;
1249 let Defs = [ESP, EFLAGS], Uses = [ESP], mayLoad = 1, hasSideEffects=0,
1250 SchedRW = [WriteLoad] in {
1251 def POPF16 : I<0x9D, RawFrm, (outs), (ins), "popf{w}", [], IIC_POP_F>,
1253 def POPF32 : I<0x9D, RawFrm, (outs), (ins), "popf{l|d}", [], IIC_POP_FD>,
1254 OpSize32, Requires<[Not64BitMode]>;
1257 let Defs = [ESP], Uses = [ESP, EFLAGS], mayStore = 1, hasSideEffects=0,
1258 SchedRW = [WriteStore] in {
1259 def PUSHF16 : I<0x9C, RawFrm, (outs), (ins), "pushf{w}", [], IIC_PUSH_F>,
1261 def PUSHF32 : I<0x9C, RawFrm, (outs), (ins), "pushf{l|d}", [], IIC_PUSH_F>,
1262 OpSize32, Requires<[Not64BitMode]>;
1265 let Defs = [RSP], Uses = [RSP], hasSideEffects=0 in {
1266 let mayLoad = 1, SchedRW = [WriteLoad] in {
1267 def POP64r : I<0x58, AddRegFrm, (outs GR64:$reg), (ins), "pop{q}\t$reg", [],
1268 IIC_POP_REG>, OpSize32, Requires<[In64BitMode]>;
1269 def POP64rmr: I<0x8F, MRM0r, (outs GR64:$reg), (ins), "pop{q}\t$reg", [],
1270 IIC_POP_REG>, OpSize32, Requires<[In64BitMode]>;
1271 } // mayLoad, SchedRW
1272 let mayLoad = 1, mayStore = 1, SchedRW = [WriteRMW] in
1273 def POP64rmm: I<0x8F, MRM0m, (outs), (ins i64mem:$dst), "pop{q}\t$dst", [],
1274 IIC_POP_MEM>, OpSize32, Requires<[In64BitMode]>;
1275 let mayStore = 1, SchedRW = [WriteStore] in {
1276 def PUSH64r : I<0x50, AddRegFrm, (outs), (ins GR64:$reg), "push{q}\t$reg", [],
1277 IIC_PUSH_REG>, OpSize32, Requires<[In64BitMode]>;
1278 def PUSH64rmr: I<0xFF, MRM6r, (outs), (ins GR64:$reg), "push{q}\t$reg", [],
1279 IIC_PUSH_REG>, OpSize32, Requires<[In64BitMode]>;
1280 } // mayStore, SchedRW
1281 let mayLoad = 1, mayStore = 1, SchedRW = [WriteRMW] in {
1282 def PUSH64rmm: I<0xFF, MRM6m, (outs), (ins i64mem:$src), "push{q}\t$src", [],
1283 IIC_PUSH_MEM>, OpSize32, Requires<[In64BitMode]>;
1284 } // mayLoad, mayStore, SchedRW
1287 let Defs = [RSP], Uses = [RSP], hasSideEffects = 0, mayStore = 1,
1288 SchedRW = [WriteStore] in {
1289 def PUSH64i8 : Ii8<0x6a, RawFrm, (outs), (ins i64i8imm:$imm),
1290 "push{q}\t$imm", [], IIC_PUSH_IMM>, OpSize32,
1291 Requires<[In64BitMode]>;
1292 def PUSH64i32 : Ii32S<0x68, RawFrm, (outs), (ins i64i32imm:$imm),
1293 "push{q}\t$imm", [], IIC_PUSH_IMM>, OpSize32,
1294 Requires<[In64BitMode]>;
1297 let Defs = [RSP, EFLAGS], Uses = [RSP], mayLoad = 1, hasSideEffects=0 in
1298 def POPF64 : I<0x9D, RawFrm, (outs), (ins), "popfq", [], IIC_POP_FD>,
1299 OpSize32, Requires<[In64BitMode]>, Sched<[WriteLoad]>;
1300 let Defs = [RSP], Uses = [RSP, EFLAGS], mayStore = 1, hasSideEffects=0 in
1301 def PUSHF64 : I<0x9C, RawFrm, (outs), (ins), "pushfq", [], IIC_PUSH_F>,
1302 OpSize32, Requires<[In64BitMode]>, Sched<[WriteStore]>;
1304 let Defs = [EDI, ESI, EBP, EBX, EDX, ECX, EAX, ESP], Uses = [ESP],
1305 mayLoad = 1, hasSideEffects = 0, SchedRW = [WriteLoad] in {
1306 def POPA32 : I<0x61, RawFrm, (outs), (ins), "popal", [], IIC_POP_A>,
1307 OpSize32, Requires<[Not64BitMode]>;
1308 def POPA16 : I<0x61, RawFrm, (outs), (ins), "popaw", [], IIC_POP_A>,
1309 OpSize16, Requires<[Not64BitMode]>;
1311 let Defs = [ESP], Uses = [EDI, ESI, EBP, EBX, EDX, ECX, EAX, ESP],
1312 mayStore = 1, hasSideEffects = 0, SchedRW = [WriteStore] in {
1313 def PUSHA32 : I<0x60, RawFrm, (outs), (ins), "pushal", [], IIC_PUSH_A>,
1314 OpSize32, Requires<[Not64BitMode]>;
1315 def PUSHA16 : I<0x60, RawFrm, (outs), (ins), "pushaw", [], IIC_PUSH_A>,
1316 OpSize16, Requires<[Not64BitMode]>;
1319 let Constraints = "$src = $dst", SchedRW = [WriteALU] in {
1320 // GR32 = bswap GR32
1321 def BSWAP32r : I<0xC8, AddRegFrm,
1322 (outs GR32:$dst), (ins GR32:$src),
1324 [(set GR32:$dst, (bswap GR32:$src))], IIC_BSWAP>, OpSize32, TB;
1326 def BSWAP64r : RI<0xC8, AddRegFrm, (outs GR64:$dst), (ins GR64:$src),
1328 [(set GR64:$dst, (bswap GR64:$src))], IIC_BSWAP>, TB;
1329 } // Constraints = "$src = $dst", SchedRW
1331 // Bit scan instructions.
1332 let Defs = [EFLAGS] in {
1333 def BSF16rr : I<0xBC, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
1334 "bsf{w}\t{$src, $dst|$dst, $src}",
1335 [(set GR16:$dst, EFLAGS, (X86bsf GR16:$src))],
1336 IIC_BIT_SCAN_REG>, PS, OpSize16, Sched<[WriteShift]>;
1337 def BSF16rm : I<0xBC, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
1338 "bsf{w}\t{$src, $dst|$dst, $src}",
1339 [(set GR16:$dst, EFLAGS, (X86bsf (loadi16 addr:$src)))],
1340 IIC_BIT_SCAN_MEM>, PS, OpSize16, Sched<[WriteShiftLd]>;
1341 def BSF32rr : I<0xBC, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
1342 "bsf{l}\t{$src, $dst|$dst, $src}",
1343 [(set GR32:$dst, EFLAGS, (X86bsf GR32:$src))],
1344 IIC_BIT_SCAN_REG>, PS, OpSize32, Sched<[WriteShift]>;
1345 def BSF32rm : I<0xBC, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
1346 "bsf{l}\t{$src, $dst|$dst, $src}",
1347 [(set GR32:$dst, EFLAGS, (X86bsf (loadi32 addr:$src)))],
1348 IIC_BIT_SCAN_MEM>, PS, OpSize32, Sched<[WriteShiftLd]>;
1349 def BSF64rr : RI<0xBC, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
1350 "bsf{q}\t{$src, $dst|$dst, $src}",
1351 [(set GR64:$dst, EFLAGS, (X86bsf GR64:$src))],
1352 IIC_BIT_SCAN_REG>, PS, Sched<[WriteShift]>;
1353 def BSF64rm : RI<0xBC, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
1354 "bsf{q}\t{$src, $dst|$dst, $src}",
1355 [(set GR64:$dst, EFLAGS, (X86bsf (loadi64 addr:$src)))],
1356 IIC_BIT_SCAN_MEM>, PS, Sched<[WriteShiftLd]>;
1358 def BSR16rr : I<0xBD, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
1359 "bsr{w}\t{$src, $dst|$dst, $src}",
1360 [(set GR16:$dst, EFLAGS, (X86bsr GR16:$src))],
1361 IIC_BIT_SCAN_REG>, PS, OpSize16, Sched<[WriteShift]>;
1362 def BSR16rm : I<0xBD, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
1363 "bsr{w}\t{$src, $dst|$dst, $src}",
1364 [(set GR16:$dst, EFLAGS, (X86bsr (loadi16 addr:$src)))],
1365 IIC_BIT_SCAN_MEM>, PS, OpSize16, Sched<[WriteShiftLd]>;
1366 def BSR32rr : I<0xBD, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
1367 "bsr{l}\t{$src, $dst|$dst, $src}",
1368 [(set GR32:$dst, EFLAGS, (X86bsr GR32:$src))],
1369 IIC_BIT_SCAN_REG>, PS, OpSize32, Sched<[WriteShift]>;
1370 def BSR32rm : I<0xBD, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
1371 "bsr{l}\t{$src, $dst|$dst, $src}",
1372 [(set GR32:$dst, EFLAGS, (X86bsr (loadi32 addr:$src)))],
1373 IIC_BIT_SCAN_MEM>, PS, OpSize32, Sched<[WriteShiftLd]>;
1374 def BSR64rr : RI<0xBD, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
1375 "bsr{q}\t{$src, $dst|$dst, $src}",
1376 [(set GR64:$dst, EFLAGS, (X86bsr GR64:$src))],
1377 IIC_BIT_SCAN_REG>, PS, Sched<[WriteShift]>;
1378 def BSR64rm : RI<0xBD, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
1379 "bsr{q}\t{$src, $dst|$dst, $src}",
1380 [(set GR64:$dst, EFLAGS, (X86bsr (loadi64 addr:$src)))],
1381 IIC_BIT_SCAN_MEM>, PS, Sched<[WriteShiftLd]>;
1382 } // Defs = [EFLAGS]
1384 let SchedRW = [WriteMicrocoded] in {
1385 // These uses the DF flag in the EFLAGS register to inc or dec EDI and ESI
1386 let Defs = [EDI,ESI], Uses = [EDI,ESI,EFLAGS] in {
1387 def MOVSB : I<0xA4, RawFrmDstSrc, (outs), (ins dstidx8:$dst, srcidx8:$src),
1388 "movsb\t{$src, $dst|$dst, $src}", [], IIC_MOVS>;
1389 def MOVSW : I<0xA5, RawFrmDstSrc, (outs), (ins dstidx16:$dst, srcidx16:$src),
1390 "movsw\t{$src, $dst|$dst, $src}", [], IIC_MOVS>, OpSize16;
1391 def MOVSL : I<0xA5, RawFrmDstSrc, (outs), (ins dstidx32:$dst, srcidx32:$src),
1392 "movs{l|d}\t{$src, $dst|$dst, $src}", [], IIC_MOVS>, OpSize32;
1393 def MOVSQ : RI<0xA5, RawFrmDstSrc, (outs), (ins dstidx64:$dst, srcidx64:$src),
1394 "movsq\t{$src, $dst|$dst, $src}", [], IIC_MOVS>;
1397 // These uses the DF flag in the EFLAGS register to inc or dec EDI and ESI
1398 let Defs = [EDI], Uses = [AL,EDI,EFLAGS] in
1399 def STOSB : I<0xAA, RawFrmDst, (outs), (ins dstidx8:$dst),
1400 "stosb\t{%al, $dst|$dst, al}", [], IIC_STOS>;
1401 let Defs = [EDI], Uses = [AX,EDI,EFLAGS] in
1402 def STOSW : I<0xAB, RawFrmDst, (outs), (ins dstidx16:$dst),
1403 "stosw\t{%ax, $dst|$dst, ax}", [], IIC_STOS>, OpSize16;
1404 let Defs = [EDI], Uses = [EAX,EDI,EFLAGS] in
1405 def STOSL : I<0xAB, RawFrmDst, (outs), (ins dstidx32:$dst),
1406 "stos{l|d}\t{%eax, $dst|$dst, eax}", [], IIC_STOS>, OpSize32;
1407 let Defs = [RDI], Uses = [RAX,RDI,EFLAGS] in
1408 def STOSQ : RI<0xAB, RawFrmDst, (outs), (ins dstidx64:$dst),
1409 "stosq\t{%rax, $dst|$dst, rax}", [], IIC_STOS>;
1411 // These uses the DF flag in the EFLAGS register to inc or dec EDI and ESI
1412 let Defs = [EDI,EFLAGS], Uses = [AL,EDI,EFLAGS] in
1413 def SCASB : I<0xAE, RawFrmDst, (outs), (ins dstidx8:$dst),
1414 "scasb\t{$dst, %al|al, $dst}", [], IIC_SCAS>;
1415 let Defs = [EDI,EFLAGS], Uses = [AX,EDI,EFLAGS] in
1416 def SCASW : I<0xAF, RawFrmDst, (outs), (ins dstidx16:$dst),
1417 "scasw\t{$dst, %ax|ax, $dst}", [], IIC_SCAS>, OpSize16;
1418 let Defs = [EDI,EFLAGS], Uses = [EAX,EDI,EFLAGS] in
1419 def SCASL : I<0xAF, RawFrmDst, (outs), (ins dstidx32:$dst),
1420 "scas{l|d}\t{$dst, %eax|eax, $dst}", [], IIC_SCAS>, OpSize32;
1421 let Defs = [EDI,EFLAGS], Uses = [RAX,EDI,EFLAGS] in
1422 def SCASQ : RI<0xAF, RawFrmDst, (outs), (ins dstidx64:$dst),
1423 "scasq\t{$dst, %rax|rax, $dst}", [], IIC_SCAS>;
1425 // These uses the DF flag in the EFLAGS register to inc or dec EDI and ESI
1426 let Defs = [EDI,ESI,EFLAGS], Uses = [EDI,ESI,EFLAGS] in {
1427 def CMPSB : I<0xA6, RawFrmDstSrc, (outs), (ins dstidx8:$dst, srcidx8:$src),
1428 "cmpsb\t{$dst, $src|$src, $dst}", [], IIC_CMPS>;
1429 def CMPSW : I<0xA7, RawFrmDstSrc, (outs), (ins dstidx16:$dst, srcidx16:$src),
1430 "cmpsw\t{$dst, $src|$src, $dst}", [], IIC_CMPS>, OpSize16;
1431 def CMPSL : I<0xA7, RawFrmDstSrc, (outs), (ins dstidx32:$dst, srcidx32:$src),
1432 "cmps{l|d}\t{$dst, $src|$src, $dst}", [], IIC_CMPS>, OpSize32;
1433 def CMPSQ : RI<0xA7, RawFrmDstSrc, (outs), (ins dstidx64:$dst, srcidx64:$src),
1434 "cmpsq\t{$dst, $src|$src, $dst}", [], IIC_CMPS>;
1438 //===----------------------------------------------------------------------===//
1439 // Move Instructions.
1441 let SchedRW = [WriteMove] in {
1442 let hasSideEffects = 0 in {
1443 def MOV8rr : I<0x88, MRMDestReg, (outs GR8 :$dst), (ins GR8 :$src),
1444 "mov{b}\t{$src, $dst|$dst, $src}", [], IIC_MOV>;
1445 def MOV16rr : I<0x89, MRMDestReg, (outs GR16:$dst), (ins GR16:$src),
1446 "mov{w}\t{$src, $dst|$dst, $src}", [], IIC_MOV>, OpSize16;
1447 def MOV32rr : I<0x89, MRMDestReg, (outs GR32:$dst), (ins GR32:$src),
1448 "mov{l}\t{$src, $dst|$dst, $src}", [], IIC_MOV>, OpSize32;
1449 def MOV64rr : RI<0x89, MRMDestReg, (outs GR64:$dst), (ins GR64:$src),
1450 "mov{q}\t{$src, $dst|$dst, $src}", [], IIC_MOV>;
1453 let isReMaterializable = 1, isAsCheapAsAMove = 1 in {
1454 def MOV8ri : Ii8 <0xB0, AddRegFrm, (outs GR8 :$dst), (ins i8imm :$src),
1455 "mov{b}\t{$src, $dst|$dst, $src}",
1456 [(set GR8:$dst, imm:$src)], IIC_MOV>;
1457 def MOV16ri : Ii16<0xB8, AddRegFrm, (outs GR16:$dst), (ins i16imm:$src),
1458 "mov{w}\t{$src, $dst|$dst, $src}",
1459 [(set GR16:$dst, imm:$src)], IIC_MOV>, OpSize16;
1460 def MOV32ri : Ii32<0xB8, AddRegFrm, (outs GR32:$dst), (ins i32imm:$src),
1461 "mov{l}\t{$src, $dst|$dst, $src}",
1462 [(set GR32:$dst, relocImm:$src)], IIC_MOV>, OpSize32;
1463 def MOV64ri32 : RIi32S<0xC7, MRM0r, (outs GR64:$dst), (ins i64i32imm:$src),
1464 "mov{q}\t{$src, $dst|$dst, $src}",
1465 [(set GR64:$dst, i64immSExt32:$src)], IIC_MOV>;
1467 let isReMaterializable = 1 in {
1468 def MOV64ri : RIi64<0xB8, AddRegFrm, (outs GR64:$dst), (ins i64imm:$src),
1469 "movabs{q}\t{$src, $dst|$dst, $src}",
1470 [(set GR64:$dst, relocImm:$src)], IIC_MOV>;
1473 // Longer forms that use a ModR/M byte. Needed for disassembler
1474 let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0 in {
1475 def MOV8ri_alt : Ii8 <0xC6, MRM0r, (outs GR8 :$dst), (ins i8imm :$src),
1476 "mov{b}\t{$src, $dst|$dst, $src}", [], IIC_MOV>,
1477 FoldGenData<"MOV8ri">;
1478 def MOV16ri_alt : Ii16<0xC7, MRM0r, (outs GR16:$dst), (ins i16imm:$src),
1479 "mov{w}\t{$src, $dst|$dst, $src}", [], IIC_MOV>, OpSize16,
1480 FoldGenData<"MOV16ri">;
1481 def MOV32ri_alt : Ii32<0xC7, MRM0r, (outs GR32:$dst), (ins i32imm:$src),
1482 "mov{l}\t{$src, $dst|$dst, $src}", [], IIC_MOV>, OpSize32,
1483 FoldGenData<"MOV32ri">;
1487 let SchedRW = [WriteStore] in {
1488 def MOV8mi : Ii8 <0xC6, MRM0m, (outs), (ins i8mem :$dst, i8imm :$src),
1489 "mov{b}\t{$src, $dst|$dst, $src}",
1490 [(store (i8 imm8_su:$src), addr:$dst)], IIC_MOV_MEM>;
1491 def MOV16mi : Ii16<0xC7, MRM0m, (outs), (ins i16mem:$dst, i16imm:$src),
1492 "mov{w}\t{$src, $dst|$dst, $src}",
1493 [(store (i16 imm16_su:$src), addr:$dst)], IIC_MOV_MEM>, OpSize16;
1494 def MOV32mi : Ii32<0xC7, MRM0m, (outs), (ins i32mem:$dst, i32imm:$src),
1495 "mov{l}\t{$src, $dst|$dst, $src}",
1496 [(store (i32 imm32_su:$src), addr:$dst)], IIC_MOV_MEM>, OpSize32;
1497 def MOV64mi32 : RIi32S<0xC7, MRM0m, (outs), (ins i64mem:$dst, i64i32imm:$src),
1498 "mov{q}\t{$src, $dst|$dst, $src}",
1499 [(store i64immSExt32_su:$src, addr:$dst)], IIC_MOV_MEM>,
1500 Requires<[In64BitMode]>;
1503 let hasSideEffects = 0 in {
1505 /// Memory offset versions of moves. The immediate is an address mode sized
1506 /// offset from the segment base.
1507 let SchedRW = [WriteALU] in {
1508 let mayLoad = 1 in {
1510 def MOV8ao32 : Ii32<0xA0, RawFrmMemOffs, (outs), (ins offset32_8:$src),
1511 "mov{b}\t{$src, %al|al, $src}", [], IIC_MOV_MEM>,
1514 def MOV16ao32 : Ii32<0xA1, RawFrmMemOffs, (outs), (ins offset32_16:$src),
1515 "mov{w}\t{$src, %ax|ax, $src}", [], IIC_MOV_MEM>,
1518 def MOV32ao32 : Ii32<0xA1, RawFrmMemOffs, (outs), (ins offset32_32:$src),
1519 "mov{l}\t{$src, %eax|eax, $src}", [], IIC_MOV_MEM>,
1522 def MOV64ao32 : RIi32<0xA1, RawFrmMemOffs, (outs), (ins offset32_64:$src),
1523 "mov{q}\t{$src, %rax|rax, $src}", [], IIC_MOV_MEM>,
1527 def MOV8ao16 : Ii16<0xA0, RawFrmMemOffs, (outs), (ins offset16_8:$src),
1528 "mov{b}\t{$src, %al|al, $src}", [], IIC_MOV_MEM>, AdSize16;
1530 def MOV16ao16 : Ii16<0xA1, RawFrmMemOffs, (outs), (ins offset16_16:$src),
1531 "mov{w}\t{$src, %ax|ax, $src}", [], IIC_MOV_MEM>,
1534 def MOV32ao16 : Ii16<0xA1, RawFrmMemOffs, (outs), (ins offset16_32:$src),
1535 "mov{l}\t{$src, %eax|eax, $src}", [], IIC_MOV_MEM>,
1538 let mayStore = 1 in {
1540 def MOV8o32a : Ii32<0xA2, RawFrmMemOffs, (outs), (ins offset32_8:$dst),
1541 "mov{b}\t{%al, $dst|$dst, al}", [], IIC_MOV_MEM>, AdSize32;
1543 def MOV16o32a : Ii32<0xA3, RawFrmMemOffs, (outs), (ins offset32_16:$dst),
1544 "mov{w}\t{%ax, $dst|$dst, ax}", [], IIC_MOV_MEM>,
1547 def MOV32o32a : Ii32<0xA3, RawFrmMemOffs, (outs), (ins offset32_32:$dst),
1548 "mov{l}\t{%eax, $dst|$dst, eax}", [], IIC_MOV_MEM>,
1551 def MOV64o32a : RIi32<0xA3, RawFrmMemOffs, (outs), (ins offset32_64:$dst),
1552 "mov{q}\t{%rax, $dst|$dst, rax}", [], IIC_MOV_MEM>,
1556 def MOV8o16a : Ii16<0xA2, RawFrmMemOffs, (outs), (ins offset16_8:$dst),
1557 "mov{b}\t{%al, $dst|$dst, al}", [], IIC_MOV_MEM>, AdSize16;
1559 def MOV16o16a : Ii16<0xA3, RawFrmMemOffs, (outs), (ins offset16_16:$dst),
1560 "mov{w}\t{%ax, $dst|$dst, ax}", [], IIC_MOV_MEM>,
1563 def MOV32o16a : Ii16<0xA3, RawFrmMemOffs, (outs), (ins offset16_32:$dst),
1564 "mov{l}\t{%eax, $dst|$dst, eax}", [], IIC_MOV_MEM>,
1569 // These forms all have full 64-bit absolute addresses in their instructions
1570 // and use the movabs mnemonic to indicate this specific form.
1571 let mayLoad = 1 in {
1573 def MOV8ao64 : RIi64_NOREX<0xA0, RawFrmMemOffs, (outs), (ins offset64_8:$src),
1574 "movabs{b}\t{$src, %al|al, $src}", [], IIC_MOV_MEM>,
1577 def MOV16ao64 : RIi64_NOREX<0xA1, RawFrmMemOffs, (outs), (ins offset64_16:$src),
1578 "movabs{w}\t{$src, %ax|ax, $src}", [], IIC_MOV_MEM>,
1581 def MOV32ao64 : RIi64_NOREX<0xA1, RawFrmMemOffs, (outs), (ins offset64_32:$src),
1582 "movabs{l}\t{$src, %eax|eax, $src}", [], IIC_MOV_MEM>,
1585 def MOV64ao64 : RIi64<0xA1, RawFrmMemOffs, (outs), (ins offset64_64:$src),
1586 "movabs{q}\t{$src, %rax|rax, $src}", [], IIC_MOV_MEM>,
1590 let mayStore = 1 in {
1592 def MOV8o64a : RIi64_NOREX<0xA2, RawFrmMemOffs, (outs), (ins offset64_8:$dst),
1593 "movabs{b}\t{%al, $dst|$dst, al}", [], IIC_MOV_MEM>,
1596 def MOV16o64a : RIi64_NOREX<0xA3, RawFrmMemOffs, (outs), (ins offset64_16:$dst),
1597 "movabs{w}\t{%ax, $dst|$dst, ax}", [], IIC_MOV_MEM>,
1600 def MOV32o64a : RIi64_NOREX<0xA3, RawFrmMemOffs, (outs), (ins offset64_32:$dst),
1601 "movabs{l}\t{%eax, $dst|$dst, eax}", [], IIC_MOV_MEM>,
1604 def MOV64o64a : RIi64<0xA3, RawFrmMemOffs, (outs), (ins offset64_64:$dst),
1605 "movabs{q}\t{%rax, $dst|$dst, rax}", [], IIC_MOV_MEM>,
1608 } // hasSideEffects = 0
1610 let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0,
1611 SchedRW = [WriteMove] in {
1612 def MOV8rr_REV : I<0x8A, MRMSrcReg, (outs GR8:$dst), (ins GR8:$src),
1613 "mov{b}\t{$src, $dst|$dst, $src}", [], IIC_MOV>,
1614 FoldGenData<"MOV8rr">;
1615 def MOV16rr_REV : I<0x8B, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
1616 "mov{w}\t{$src, $dst|$dst, $src}", [], IIC_MOV>, OpSize16,
1617 FoldGenData<"MOV16rr">;
1618 def MOV32rr_REV : I<0x8B, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
1619 "mov{l}\t{$src, $dst|$dst, $src}", [], IIC_MOV>, OpSize32,
1620 FoldGenData<"MOV32rr">;
1621 def MOV64rr_REV : RI<0x8B, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
1622 "mov{q}\t{$src, $dst|$dst, $src}", [], IIC_MOV>,
1623 FoldGenData<"MOV64rr">;
1626 let canFoldAsLoad = 1, isReMaterializable = 1, SchedRW = [WriteLoad] in {
1627 def MOV8rm : I<0x8A, MRMSrcMem, (outs GR8 :$dst), (ins i8mem :$src),
1628 "mov{b}\t{$src, $dst|$dst, $src}",
1629 [(set GR8:$dst, (loadi8 addr:$src))], IIC_MOV_MEM>;
1630 def MOV16rm : I<0x8B, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
1631 "mov{w}\t{$src, $dst|$dst, $src}",
1632 [(set GR16:$dst, (loadi16 addr:$src))], IIC_MOV_MEM>, OpSize16;
1633 def MOV32rm : I<0x8B, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
1634 "mov{l}\t{$src, $dst|$dst, $src}",
1635 [(set GR32:$dst, (loadi32 addr:$src))], IIC_MOV_MEM>, OpSize32;
1636 def MOV64rm : RI<0x8B, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
1637 "mov{q}\t{$src, $dst|$dst, $src}",
1638 [(set GR64:$dst, (load addr:$src))], IIC_MOV_MEM>;
1641 let SchedRW = [WriteStore] in {
1642 def MOV8mr : I<0x88, MRMDestMem, (outs), (ins i8mem :$dst, GR8 :$src),
1643 "mov{b}\t{$src, $dst|$dst, $src}",
1644 [(store GR8:$src, addr:$dst)], IIC_MOV_MEM>;
1645 def MOV16mr : I<0x89, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src),
1646 "mov{w}\t{$src, $dst|$dst, $src}",
1647 [(store GR16:$src, addr:$dst)], IIC_MOV_MEM>, OpSize16;
1648 def MOV32mr : I<0x89, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
1649 "mov{l}\t{$src, $dst|$dst, $src}",
1650 [(store GR32:$src, addr:$dst)], IIC_MOV_MEM>, OpSize32;
1651 def MOV64mr : RI<0x89, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
1652 "mov{q}\t{$src, $dst|$dst, $src}",
1653 [(store GR64:$src, addr:$dst)], IIC_MOV_MEM>;
1656 // Versions of MOV8rr, MOV8mr, and MOV8rm that use i8mem_NOREX and GR8_NOREX so
1657 // that they can be used for copying and storing h registers, which can't be
1658 // encoded when a REX prefix is present.
1659 let isCodeGenOnly = 1 in {
1660 let hasSideEffects = 0 in
1661 def MOV8rr_NOREX : I<0x88, MRMDestReg,
1662 (outs GR8_NOREX:$dst), (ins GR8_NOREX:$src),
1663 "mov{b}\t{$src, $dst|$dst, $src} # NOREX", [], IIC_MOV>,
1665 let mayStore = 1, hasSideEffects = 0 in
1666 def MOV8mr_NOREX : I<0x88, MRMDestMem,
1667 (outs), (ins i8mem_NOREX:$dst, GR8_NOREX:$src),
1668 "mov{b}\t{$src, $dst|$dst, $src} # NOREX", [],
1669 IIC_MOV_MEM>, Sched<[WriteStore]>;
1670 let mayLoad = 1, hasSideEffects = 0,
1671 canFoldAsLoad = 1, isReMaterializable = 1 in
1672 def MOV8rm_NOREX : I<0x8A, MRMSrcMem,
1673 (outs GR8_NOREX:$dst), (ins i8mem_NOREX:$src),
1674 "mov{b}\t{$src, $dst|$dst, $src} # NOREX", [],
1675 IIC_MOV_MEM>, Sched<[WriteLoad]>;
1679 // Condition code ops, incl. set if equal/not equal/...
1680 let SchedRW = [WriteALU] in {
1681 let Defs = [EFLAGS], Uses = [AH] in
1682 def SAHF : I<0x9E, RawFrm, (outs), (ins), "sahf",
1683 [(set EFLAGS, (X86sahf AH))], IIC_AHF>,
1684 Requires<[HasLAHFSAHF]>;
1685 let Defs = [AH], Uses = [EFLAGS], hasSideEffects = 0 in
1686 def LAHF : I<0x9F, RawFrm, (outs), (ins), "lahf", [],
1687 IIC_AHF>, // AH = flags
1688 Requires<[HasLAHFSAHF]>;
1691 //===----------------------------------------------------------------------===//
1692 // Bit tests instructions: BT, BTS, BTR, BTC.
1694 let Defs = [EFLAGS] in {
1695 let SchedRW = [WriteALU] in {
1696 def BT16rr : I<0xA3, MRMDestReg, (outs), (ins GR16:$src1, GR16:$src2),
1697 "bt{w}\t{$src2, $src1|$src1, $src2}",
1698 [(set EFLAGS, (X86bt GR16:$src1, GR16:$src2))], IIC_BT_RR>,
1699 OpSize16, TB, NotMemoryFoldable;
1700 def BT32rr : I<0xA3, MRMDestReg, (outs), (ins GR32:$src1, GR32:$src2),
1701 "bt{l}\t{$src2, $src1|$src1, $src2}",
1702 [(set EFLAGS, (X86bt GR32:$src1, GR32:$src2))], IIC_BT_RR>,
1703 OpSize32, TB, NotMemoryFoldable;
1704 def BT64rr : RI<0xA3, MRMDestReg, (outs), (ins GR64:$src1, GR64:$src2),
1705 "bt{q}\t{$src2, $src1|$src1, $src2}",
1706 [(set EFLAGS, (X86bt GR64:$src1, GR64:$src2))], IIC_BT_RR>, TB,
1710 // Unlike with the register+register form, the memory+register form of the
1711 // bt instruction does not ignore the high bits of the index. From ISel's
1712 // perspective, this is pretty bizarre. Make these instructions disassembly
1713 // only for now. These instructions are also slow on modern CPUs so that's
1714 // another reason to avoid generating them.
1716 let mayLoad = 1, hasSideEffects = 0, SchedRW = [WriteALULd] in {
1717 def BT16mr : I<0xA3, MRMDestMem, (outs), (ins i16mem:$src1, GR16:$src2),
1718 "bt{w}\t{$src2, $src1|$src1, $src2}",
1720 >, OpSize16, TB, NotMemoryFoldable;
1721 def BT32mr : I<0xA3, MRMDestMem, (outs), (ins i32mem:$src1, GR32:$src2),
1722 "bt{l}\t{$src2, $src1|$src1, $src2}",
1724 >, OpSize32, TB, NotMemoryFoldable;
1725 def BT64mr : RI<0xA3, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2),
1726 "bt{q}\t{$src2, $src1|$src1, $src2}",
1728 >, TB, NotMemoryFoldable;
1731 let SchedRW = [WriteALU] in {
1732 def BT16ri8 : Ii8<0xBA, MRM4r, (outs), (ins GR16:$src1, i16i8imm:$src2),
1733 "bt{w}\t{$src2, $src1|$src1, $src2}",
1734 [(set EFLAGS, (X86bt GR16:$src1, i16immSExt8:$src2))],
1735 IIC_BT_RI>, OpSize16, TB;
1736 def BT32ri8 : Ii8<0xBA, MRM4r, (outs), (ins GR32:$src1, i32i8imm:$src2),
1737 "bt{l}\t{$src2, $src1|$src1, $src2}",
1738 [(set EFLAGS, (X86bt GR32:$src1, i32immSExt8:$src2))],
1739 IIC_BT_RI>, OpSize32, TB;
1740 def BT64ri8 : RIi8<0xBA, MRM4r, (outs), (ins GR64:$src1, i64i8imm:$src2),
1741 "bt{q}\t{$src2, $src1|$src1, $src2}",
1742 [(set EFLAGS, (X86bt GR64:$src1, i64immSExt8:$src2))],
1746 // Note that these instructions aren't slow because that only applies when the
1747 // other operand is in a register. When it's an immediate, bt is still fast.
1748 let SchedRW = [WriteALU] in {
1749 def BT16mi8 : Ii8<0xBA, MRM4m, (outs), (ins i16mem:$src1, i16i8imm:$src2),
1750 "bt{w}\t{$src2, $src1|$src1, $src2}",
1751 [(set EFLAGS, (X86bt (loadi16 addr:$src1), i16immSExt8:$src2))
1752 ], IIC_BT_MI>, OpSize16, TB;
1753 def BT32mi8 : Ii8<0xBA, MRM4m, (outs), (ins i32mem:$src1, i32i8imm:$src2),
1754 "bt{l}\t{$src2, $src1|$src1, $src2}",
1755 [(set EFLAGS, (X86bt (loadi32 addr:$src1), i32immSExt8:$src2))
1756 ], IIC_BT_MI>, OpSize32, TB;
1757 def BT64mi8 : RIi8<0xBA, MRM4m, (outs), (ins i64mem:$src1, i64i8imm:$src2),
1758 "bt{q}\t{$src2, $src1|$src1, $src2}",
1759 [(set EFLAGS, (X86bt (loadi64 addr:$src1),
1760 i64immSExt8:$src2))], IIC_BT_MI>, TB,
1761 Requires<[In64BitMode]>;
1764 let hasSideEffects = 0 in {
1765 let SchedRW = [WriteALU], Constraints = "$src1 = $dst" in {
1766 def BTC16rr : I<0xBB, MRMDestReg, (outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
1767 "btc{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>,
1768 OpSize16, TB, NotMemoryFoldable;
1769 def BTC32rr : I<0xBB, MRMDestReg, (outs GR32:$dst), (ins GR32:$src1, GR32:$src2),
1770 "btc{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>,
1771 OpSize32, TB, NotMemoryFoldable;
1772 def BTC64rr : RI<0xBB, MRMDestReg, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
1773 "btc{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>, TB,
1777 let mayLoad = 1, mayStore = 1, SchedRW = [WriteALULd, WriteRMW] in {
1778 def BTC16mr : I<0xBB, MRMDestMem, (outs), (ins i16mem:$src1, GR16:$src2),
1779 "btc{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>,
1780 OpSize16, TB, NotMemoryFoldable;
1781 def BTC32mr : I<0xBB, MRMDestMem, (outs), (ins i32mem:$src1, GR32:$src2),
1782 "btc{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>,
1783 OpSize32, TB, NotMemoryFoldable;
1784 def BTC64mr : RI<0xBB, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2),
1785 "btc{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>, TB,
1789 let SchedRW = [WriteALU], Constraints = "$src1 = $dst" in {
1790 def BTC16ri8 : Ii8<0xBA, MRM7r, (outs GR16:$dst), (ins GR16:$src1, i16i8imm:$src2),
1791 "btc{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>,
1793 def BTC32ri8 : Ii8<0xBA, MRM7r, (outs GR32:$dst), (ins GR32:$src1, i32i8imm:$src2),
1794 "btc{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>,
1796 def BTC64ri8 : RIi8<0xBA, MRM7r, (outs GR64:$dst), (ins GR64:$src1, i64i8imm:$src2),
1797 "btc{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>, TB;
1800 let mayLoad = 1, mayStore = 1, SchedRW = [WriteALULd, WriteRMW] in {
1801 def BTC16mi8 : Ii8<0xBA, MRM7m, (outs), (ins i16mem:$src1, i16i8imm:$src2),
1802 "btc{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>,
1804 def BTC32mi8 : Ii8<0xBA, MRM7m, (outs), (ins i32mem:$src1, i32i8imm:$src2),
1805 "btc{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>,
1807 def BTC64mi8 : RIi8<0xBA, MRM7m, (outs), (ins i64mem:$src1, i64i8imm:$src2),
1808 "btc{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>, TB,
1809 Requires<[In64BitMode]>;
1812 let SchedRW = [WriteALU], Constraints = "$src1 = $dst" in {
1813 def BTR16rr : I<0xB3, MRMDestReg, (outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
1814 "btr{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>,
1815 OpSize16, TB, NotMemoryFoldable;
1816 def BTR32rr : I<0xB3, MRMDestReg, (outs GR32:$dst), (ins GR32:$src1, GR32:$src2),
1817 "btr{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>,
1818 OpSize32, TB, NotMemoryFoldable;
1819 def BTR64rr : RI<0xB3, MRMDestReg, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
1820 "btr{q}\t{$src2, $src1|$src1, $src2}", []>, TB, NotMemoryFoldable;
1823 let mayLoad = 1, mayStore = 1, SchedRW = [WriteALULd, WriteRMW] in {
1824 def BTR16mr : I<0xB3, MRMDestMem, (outs), (ins i16mem:$src1, GR16:$src2),
1825 "btr{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>,
1826 OpSize16, TB, NotMemoryFoldable;
1827 def BTR32mr : I<0xB3, MRMDestMem, (outs), (ins i32mem:$src1, GR32:$src2),
1828 "btr{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>,
1829 OpSize32, TB, NotMemoryFoldable;
1830 def BTR64mr : RI<0xB3, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2),
1831 "btr{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>, TB,
1835 let SchedRW = [WriteALU], Constraints = "$src1 = $dst" in {
1836 def BTR16ri8 : Ii8<0xBA, MRM6r, (outs GR16:$dst), (ins GR16:$src1, i16i8imm:$src2),
1837 "btr{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>,
1839 def BTR32ri8 : Ii8<0xBA, MRM6r, (outs GR32:$dst), (ins GR32:$src1, i32i8imm:$src2),
1840 "btr{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>,
1842 def BTR64ri8 : RIi8<0xBA, MRM6r, (outs GR64:$dst), (ins GR64:$src1, i64i8imm:$src2),
1843 "btr{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>, TB;
1846 let mayLoad = 1, mayStore = 1, SchedRW = [WriteALULd, WriteRMW] in {
1847 def BTR16mi8 : Ii8<0xBA, MRM6m, (outs), (ins i16mem:$src1, i16i8imm:$src2),
1848 "btr{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>,
1850 def BTR32mi8 : Ii8<0xBA, MRM6m, (outs), (ins i32mem:$src1, i32i8imm:$src2),
1851 "btr{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>,
1853 def BTR64mi8 : RIi8<0xBA, MRM6m, (outs), (ins i64mem:$src1, i64i8imm:$src2),
1854 "btr{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>, TB,
1855 Requires<[In64BitMode]>;
1858 let SchedRW = [WriteALU], Constraints = "$src1 = $dst" in {
1859 def BTS16rr : I<0xAB, MRMDestReg, (outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
1860 "bts{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>,
1861 OpSize16, TB, NotMemoryFoldable;
1862 def BTS32rr : I<0xAB, MRMDestReg, (outs GR32:$dst), (ins GR32:$src1, GR32:$src2),
1863 "bts{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>,
1864 OpSize32, TB, NotMemoryFoldable;
1865 def BTS64rr : RI<0xAB, MRMDestReg, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
1866 "bts{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>, TB,
1870 let mayLoad = 1, mayStore = 1, SchedRW = [WriteALULd, WriteRMW] in {
1871 def BTS16mr : I<0xAB, MRMDestMem, (outs), (ins i16mem:$src1, GR16:$src2),
1872 "bts{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>,
1873 OpSize16, TB, NotMemoryFoldable;
1874 def BTS32mr : I<0xAB, MRMDestMem, (outs), (ins i32mem:$src1, GR32:$src2),
1875 "bts{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>,
1876 OpSize32, TB, NotMemoryFoldable;
1877 def BTS64mr : RI<0xAB, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2),
1878 "bts{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>, TB,
1882 let SchedRW = [WriteALU], Constraints = "$src1 = $dst" in {
1883 def BTS16ri8 : Ii8<0xBA, MRM5r, (outs GR16:$dst), (ins GR16:$src1, i16i8imm:$src2),
1884 "bts{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>,
1886 def BTS32ri8 : Ii8<0xBA, MRM5r, (outs GR32:$dst), (ins GR32:$src1, i32i8imm:$src2),
1887 "bts{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>,
1889 def BTS64ri8 : RIi8<0xBA, MRM5r, (outs GR64:$dst), (ins GR64:$src1, i64i8imm:$src2),
1890 "bts{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>, TB;
1893 let mayLoad = 1, mayStore = 1, SchedRW = [WriteALULd, WriteRMW] in {
1894 def BTS16mi8 : Ii8<0xBA, MRM5m, (outs), (ins i16mem:$src1, i16i8imm:$src2),
1895 "bts{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>,
1897 def BTS32mi8 : Ii8<0xBA, MRM5m, (outs), (ins i32mem:$src1, i32i8imm:$src2),
1898 "bts{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>,
1900 def BTS64mi8 : RIi8<0xBA, MRM5m, (outs), (ins i64mem:$src1, i64i8imm:$src2),
1901 "bts{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>, TB,
1902 Requires<[In64BitMode]>;
1904 } // hasSideEffects = 0
1905 } // Defs = [EFLAGS]
1908 //===----------------------------------------------------------------------===//
1912 // Atomic swap. These are just normal xchg instructions. But since a memory
1913 // operand is referenced, the atomicity is ensured.
1914 multiclass ATOMIC_SWAP<bits<8> opc8, bits<8> opc, string mnemonic, string frag,
1915 InstrItinClass itin> {
1916 let Constraints = "$val = $dst", SchedRW = [WriteALULd, WriteRMW] in {
1917 def NAME#8rm : I<opc8, MRMSrcMem, (outs GR8:$dst),
1918 (ins GR8:$val, i8mem:$ptr),
1919 !strconcat(mnemonic, "{b}\t{$val, $ptr|$ptr, $val}"),
1922 (!cast<PatFrag>(frag # "_8") addr:$ptr, GR8:$val))],
1924 def NAME#16rm : I<opc, MRMSrcMem, (outs GR16:$dst),
1925 (ins GR16:$val, i16mem:$ptr),
1926 !strconcat(mnemonic, "{w}\t{$val, $ptr|$ptr, $val}"),
1929 (!cast<PatFrag>(frag # "_16") addr:$ptr, GR16:$val))],
1931 def NAME#32rm : I<opc, MRMSrcMem, (outs GR32:$dst),
1932 (ins GR32:$val, i32mem:$ptr),
1933 !strconcat(mnemonic, "{l}\t{$val, $ptr|$ptr, $val}"),
1936 (!cast<PatFrag>(frag # "_32") addr:$ptr, GR32:$val))],
1938 def NAME#64rm : RI<opc, MRMSrcMem, (outs GR64:$dst),
1939 (ins GR64:$val, i64mem:$ptr),
1940 !strconcat(mnemonic, "{q}\t{$val, $ptr|$ptr, $val}"),
1943 (!cast<PatFrag>(frag # "_64") addr:$ptr, GR64:$val))],
1948 defm XCHG : ATOMIC_SWAP<0x86, 0x87, "xchg", "atomic_swap", IIC_XCHG_MEM>;
1950 // Swap between registers.
1951 let SchedRW = [WriteALU] in {
1952 let Constraints = "$val = $dst" in {
1953 def XCHG8rr : I<0x86, MRMSrcReg, (outs GR8:$dst), (ins GR8:$val, GR8:$src),
1954 "xchg{b}\t{$val, $src|$src, $val}", [], IIC_XCHG_REG>;
1955 def XCHG16rr : I<0x87, MRMSrcReg, (outs GR16:$dst), (ins GR16:$val, GR16:$src),
1956 "xchg{w}\t{$val, $src|$src, $val}", [], IIC_XCHG_REG>,
1958 def XCHG32rr : I<0x87, MRMSrcReg, (outs GR32:$dst), (ins GR32:$val, GR32:$src),
1959 "xchg{l}\t{$val, $src|$src, $val}", [], IIC_XCHG_REG>,
1961 def XCHG64rr : RI<0x87, MRMSrcReg, (outs GR64:$dst), (ins GR64:$val,GR64:$src),
1962 "xchg{q}\t{$val, $src|$src, $val}", [], IIC_XCHG_REG>;
1965 // Swap between EAX and other registers.
1966 let Uses = [AX], Defs = [AX] in
1967 def XCHG16ar : I<0x90, AddRegFrm, (outs), (ins GR16:$src),
1968 "xchg{w}\t{$src, %ax|ax, $src}", [], IIC_XCHG_REG>, OpSize16;
1969 let Uses = [EAX], Defs = [EAX] in
1970 def XCHG32ar : I<0x90, AddRegFrm, (outs), (ins GR32:$src),
1971 "xchg{l}\t{$src, %eax|eax, $src}", [], IIC_XCHG_REG>,
1972 OpSize32, Requires<[Not64BitMode]>;
1973 let Uses = [EAX], Defs = [EAX] in
1974 // Uses GR32_NOAX in 64-bit mode to prevent encoding using the 0x90 NOP encoding.
1975 // xchg %eax, %eax needs to clear upper 32-bits of RAX so is not a NOP.
1976 def XCHG32ar64 : I<0x90, AddRegFrm, (outs), (ins GR32_NOAX:$src),
1977 "xchg{l}\t{$src, %eax|eax, $src}", [], IIC_XCHG_REG>,
1978 OpSize32, Requires<[In64BitMode]>;
1979 let Uses = [RAX], Defs = [RAX] in
1980 def XCHG64ar : RI<0x90, AddRegFrm, (outs), (ins GR64:$src),
1981 "xchg{q}\t{$src, %rax|rax, $src}", [], IIC_XCHG_REG>;
1984 let SchedRW = [WriteALU] in {
1985 def XADD8rr : I<0xC0, MRMDestReg, (outs GR8:$dst), (ins GR8:$src),
1986 "xadd{b}\t{$src, $dst|$dst, $src}", [], IIC_XADD_REG>, TB;
1987 def XADD16rr : I<0xC1, MRMDestReg, (outs GR16:$dst), (ins GR16:$src),
1988 "xadd{w}\t{$src, $dst|$dst, $src}", [], IIC_XADD_REG>, TB,
1990 def XADD32rr : I<0xC1, MRMDestReg, (outs GR32:$dst), (ins GR32:$src),
1991 "xadd{l}\t{$src, $dst|$dst, $src}", [], IIC_XADD_REG>, TB,
1993 def XADD64rr : RI<0xC1, MRMDestReg, (outs GR64:$dst), (ins GR64:$src),
1994 "xadd{q}\t{$src, $dst|$dst, $src}", [], IIC_XADD_REG>, TB;
1997 let mayLoad = 1, mayStore = 1, SchedRW = [WriteALULd, WriteRMW] in {
1998 def XADD8rm : I<0xC0, MRMDestMem, (outs), (ins i8mem:$dst, GR8:$src),
1999 "xadd{b}\t{$src, $dst|$dst, $src}", [], IIC_XADD_MEM>, TB;
2000 def XADD16rm : I<0xC1, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src),
2001 "xadd{w}\t{$src, $dst|$dst, $src}", [], IIC_XADD_MEM>, TB,
2003 def XADD32rm : I<0xC1, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
2004 "xadd{l}\t{$src, $dst|$dst, $src}", [], IIC_XADD_MEM>, TB,
2006 def XADD64rm : RI<0xC1, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
2007 "xadd{q}\t{$src, $dst|$dst, $src}", [], IIC_XADD_MEM>, TB;
2011 let SchedRW = [WriteALU] in {
2012 def CMPXCHG8rr : I<0xB0, MRMDestReg, (outs GR8:$dst), (ins GR8:$src),
2013 "cmpxchg{b}\t{$src, $dst|$dst, $src}", [],
2014 IIC_CMPXCHG_REG8>, TB;
2015 def CMPXCHG16rr : I<0xB1, MRMDestReg, (outs GR16:$dst), (ins GR16:$src),
2016 "cmpxchg{w}\t{$src, $dst|$dst, $src}", [],
2017 IIC_CMPXCHG_REG>, TB, OpSize16;
2018 def CMPXCHG32rr : I<0xB1, MRMDestReg, (outs GR32:$dst), (ins GR32:$src),
2019 "cmpxchg{l}\t{$src, $dst|$dst, $src}", [],
2020 IIC_CMPXCHG_REG>, TB, OpSize32;
2021 def CMPXCHG64rr : RI<0xB1, MRMDestReg, (outs GR64:$dst), (ins GR64:$src),
2022 "cmpxchg{q}\t{$src, $dst|$dst, $src}", [],
2023 IIC_CMPXCHG_REG>, TB;
2026 let SchedRW = [WriteALULd, WriteRMW] in {
2027 let mayLoad = 1, mayStore = 1 in {
2028 def CMPXCHG8rm : I<0xB0, MRMDestMem, (outs), (ins i8mem:$dst, GR8:$src),
2029 "cmpxchg{b}\t{$src, $dst|$dst, $src}", [],
2030 IIC_CMPXCHG_MEM8>, TB;
2031 def CMPXCHG16rm : I<0xB1, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src),
2032 "cmpxchg{w}\t{$src, $dst|$dst, $src}", [],
2033 IIC_CMPXCHG_MEM>, TB, OpSize16;
2034 def CMPXCHG32rm : I<0xB1, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
2035 "cmpxchg{l}\t{$src, $dst|$dst, $src}", [],
2036 IIC_CMPXCHG_MEM>, TB, OpSize32;
2037 def CMPXCHG64rm : RI<0xB1, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
2038 "cmpxchg{q}\t{$src, $dst|$dst, $src}", [],
2039 IIC_CMPXCHG_MEM>, TB;
2042 let Defs = [EAX, EDX, EFLAGS], Uses = [EAX, EBX, ECX, EDX] in
2043 def CMPXCHG8B : I<0xC7, MRM1m, (outs), (ins i64mem:$dst),
2044 "cmpxchg8b\t$dst", [], IIC_CMPXCHG_8B>, TB;
2046 let Defs = [RAX, RDX, EFLAGS], Uses = [RAX, RBX, RCX, RDX] in
2047 def CMPXCHG16B : RI<0xC7, MRM1m, (outs), (ins i128mem:$dst),
2048 "cmpxchg16b\t$dst", [], IIC_CMPXCHG_16B>,
2049 TB, Requires<[HasCmpxchg16b, In64BitMode]>;
2053 // Lock instruction prefix
2054 let SchedRW = [WriteMicrocoded] in
2055 def LOCK_PREFIX : I<0xF0, RawFrm, (outs), (ins), "lock", []>;
2057 let SchedRW = [WriteNop] in {
2059 // Rex64 instruction prefix
2060 def REX64_PREFIX : I<0x48, RawFrm, (outs), (ins), "rex64", [], IIC_NOP>,
2061 Requires<[In64BitMode]>;
2063 // Data16 instruction prefix
2064 def DATA16_PREFIX : I<0x66, RawFrm, (outs), (ins), "data16", [], IIC_NOP>,
2065 Requires<[Not16BitMode]>;
2067 // Data instruction prefix
2068 def DATA32_PREFIX : I<0x66, RawFrm, (outs), (ins), "data32", [], IIC_NOP>,
2069 Requires<[In16BitMode]>;
2072 // Repeat string operation instruction prefixes
2073 // These use the DF flag in the EFLAGS register to inc or dec ECX
2074 let Defs = [ECX], Uses = [ECX,EFLAGS], SchedRW = [WriteMicrocoded] in {
2075 // Repeat (used with INS, OUTS, MOVS, LODS and STOS)
2076 def REP_PREFIX : I<0xF3, RawFrm, (outs), (ins), "rep", []>;
2077 // Repeat while not equal (used with CMPS and SCAS)
2078 def REPNE_PREFIX : I<0xF2, RawFrm, (outs), (ins), "repne", []>;
2081 // String manipulation instructions
2082 let SchedRW = [WriteMicrocoded] in {
2083 // These uses the DF flag in the EFLAGS register to inc or dec EDI and ESI
2084 let Defs = [AL,ESI], Uses = [ESI,EFLAGS] in
2085 def LODSB : I<0xAC, RawFrmSrc, (outs), (ins srcidx8:$src),
2086 "lodsb\t{$src, %al|al, $src}", [], IIC_LODS>;
2087 let Defs = [AX,ESI], Uses = [ESI,EFLAGS] in
2088 def LODSW : I<0xAD, RawFrmSrc, (outs), (ins srcidx16:$src),
2089 "lodsw\t{$src, %ax|ax, $src}", [], IIC_LODS>, OpSize16;
2090 let Defs = [EAX,ESI], Uses = [ESI,EFLAGS] in
2091 def LODSL : I<0xAD, RawFrmSrc, (outs), (ins srcidx32:$src),
2092 "lods{l|d}\t{$src, %eax|eax, $src}", [], IIC_LODS>, OpSize32;
2093 let Defs = [RAX,ESI], Uses = [ESI,EFLAGS] in
2094 def LODSQ : RI<0xAD, RawFrmSrc, (outs), (ins srcidx64:$src),
2095 "lodsq\t{$src, %rax|rax, $src}", [], IIC_LODS>;
2098 let SchedRW = [WriteSystem] in {
2099 // These uses the DF flag in the EFLAGS register to inc or dec EDI and ESI
2100 let Defs = [ESI], Uses = [DX,ESI,EFLAGS] in {
2101 def OUTSB : I<0x6E, RawFrmSrc, (outs), (ins srcidx8:$src),
2102 "outsb\t{$src, %dx|dx, $src}", [], IIC_OUTS>;
2103 def OUTSW : I<0x6F, RawFrmSrc, (outs), (ins srcidx16:$src),
2104 "outsw\t{$src, %dx|dx, $src}", [], IIC_OUTS>, OpSize16;
2105 def OUTSL : I<0x6F, RawFrmSrc, (outs), (ins srcidx32:$src),
2106 "outs{l|d}\t{$src, %dx|dx, $src}", [], IIC_OUTS>, OpSize32;
2109 // These uses the DF flag in the EFLAGS register to inc or dec EDI and ESI
2110 let Defs = [EDI], Uses = [DX,EDI,EFLAGS] in {
2111 def INSB : I<0x6C, RawFrmDst, (outs), (ins dstidx8:$dst),
2112 "insb\t{%dx, $dst|$dst, dx}", [], IIC_INS>;
2113 def INSW : I<0x6D, RawFrmDst, (outs), (ins dstidx16:$dst),
2114 "insw\t{%dx, $dst|$dst, dx}", [], IIC_INS>, OpSize16;
2115 def INSL : I<0x6D, RawFrmDst, (outs), (ins dstidx32:$dst),
2116 "ins{l|d}\t{%dx, $dst|$dst, dx}", [], IIC_INS>, OpSize32;
2120 // Flag instructions
2121 let SchedRW = [WriteALU] in {
2122 def CLC : I<0xF8, RawFrm, (outs), (ins), "clc", [], IIC_CLC>;
2123 def STC : I<0xF9, RawFrm, (outs), (ins), "stc", [], IIC_STC>;
2124 def CLI : I<0xFA, RawFrm, (outs), (ins), "cli", [], IIC_CLI>;
2125 def STI : I<0xFB, RawFrm, (outs), (ins), "sti", [], IIC_STI>;
2126 def CLD : I<0xFC, RawFrm, (outs), (ins), "cld", [], IIC_CLD>;
2127 def STD : I<0xFD, RawFrm, (outs), (ins), "std", [], IIC_STD>;
2128 def CMC : I<0xF5, RawFrm, (outs), (ins), "cmc", [], IIC_CMC>;
2130 def CLTS : I<0x06, RawFrm, (outs), (ins), "clts", [], IIC_CLTS>, TB;
2133 // Table lookup instructions
2134 let Uses = [AL,EBX], Defs = [AL], hasSideEffects = 0, mayLoad = 1 in
2135 def XLAT : I<0xD7, RawFrm, (outs), (ins), "xlatb", [], IIC_XLAT>,
2138 let SchedRW = [WriteMicrocoded] in {
2139 // ASCII Adjust After Addition
2140 let Uses = [AL,EFLAGS], Defs = [AX,EFLAGS], hasSideEffects = 0 in
2141 def AAA : I<0x37, RawFrm, (outs), (ins), "aaa", [], IIC_AAA>,
2142 Requires<[Not64BitMode]>;
2144 // ASCII Adjust AX Before Division
2145 let Uses = [AX], Defs = [AX,EFLAGS], hasSideEffects = 0 in
2146 def AAD8i8 : Ii8<0xD5, RawFrm, (outs), (ins i8imm:$src),
2147 "aad\t$src", [], IIC_AAD>, Requires<[Not64BitMode]>;
2149 // ASCII Adjust AX After Multiply
2150 let Uses = [AL], Defs = [AX,EFLAGS], hasSideEffects = 0 in
2151 def AAM8i8 : Ii8<0xD4, RawFrm, (outs), (ins i8imm:$src),
2152 "aam\t$src", [], IIC_AAM>, Requires<[Not64BitMode]>;
2154 // ASCII Adjust AL After Subtraction - sets
2155 let Uses = [AL,EFLAGS], Defs = [AX,EFLAGS], hasSideEffects = 0 in
2156 def AAS : I<0x3F, RawFrm, (outs), (ins), "aas", [], IIC_AAS>,
2157 Requires<[Not64BitMode]>;
2159 // Decimal Adjust AL after Addition
2160 let Uses = [AL,EFLAGS], Defs = [AL,EFLAGS], hasSideEffects = 0 in
2161 def DAA : I<0x27, RawFrm, (outs), (ins), "daa", [], IIC_DAA>,
2162 Requires<[Not64BitMode]>;
2164 // Decimal Adjust AL after Subtraction
2165 let Uses = [AL,EFLAGS], Defs = [AL,EFLAGS], hasSideEffects = 0 in
2166 def DAS : I<0x2F, RawFrm, (outs), (ins), "das", [], IIC_DAS>,
2167 Requires<[Not64BitMode]>;
2170 let SchedRW = [WriteSystem] in {
2171 // Check Array Index Against Bounds
2172 def BOUNDS16rm : I<0x62, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
2173 "bound\t{$src, $dst|$dst, $src}", [], IIC_BOUND>, OpSize16,
2174 Requires<[Not64BitMode]>;
2175 def BOUNDS32rm : I<0x62, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
2176 "bound\t{$src, $dst|$dst, $src}", [], IIC_BOUND>, OpSize32,
2177 Requires<[Not64BitMode]>;
2179 // Adjust RPL Field of Segment Selector
2180 def ARPL16rr : I<0x63, MRMDestReg, (outs GR16:$dst), (ins GR16:$src),
2181 "arpl\t{$src, $dst|$dst, $src}", [], IIC_ARPL_REG>,
2182 Requires<[Not64BitMode]>;
2184 def ARPL16mr : I<0x63, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src),
2185 "arpl\t{$src, $dst|$dst, $src}", [], IIC_ARPL_MEM>,
2186 Requires<[Not64BitMode]>;
2189 //===----------------------------------------------------------------------===//
2190 // MOVBE Instructions
2192 let Predicates = [HasMOVBE] in {
2193 let SchedRW = [WriteALULd] in {
2194 def MOVBE16rm : I<0xF0, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
2195 "movbe{w}\t{$src, $dst|$dst, $src}",
2196 [(set GR16:$dst, (bswap (loadi16 addr:$src)))], IIC_MOVBE>,
2198 def MOVBE32rm : I<0xF0, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
2199 "movbe{l}\t{$src, $dst|$dst, $src}",
2200 [(set GR32:$dst, (bswap (loadi32 addr:$src)))], IIC_MOVBE>,
2202 def MOVBE64rm : RI<0xF0, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
2203 "movbe{q}\t{$src, $dst|$dst, $src}",
2204 [(set GR64:$dst, (bswap (loadi64 addr:$src)))], IIC_MOVBE>,
2207 let SchedRW = [WriteStore] in {
2208 def MOVBE16mr : I<0xF1, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src),
2209 "movbe{w}\t{$src, $dst|$dst, $src}",
2210 [(store (bswap GR16:$src), addr:$dst)], IIC_MOVBE>,
2212 def MOVBE32mr : I<0xF1, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
2213 "movbe{l}\t{$src, $dst|$dst, $src}",
2214 [(store (bswap GR32:$src), addr:$dst)], IIC_MOVBE>,
2216 def MOVBE64mr : RI<0xF1, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
2217 "movbe{q}\t{$src, $dst|$dst, $src}",
2218 [(store (bswap GR64:$src), addr:$dst)], IIC_MOVBE>,
2223 //===----------------------------------------------------------------------===//
2224 // RDRAND Instruction
2226 let Predicates = [HasRDRAND], Defs = [EFLAGS], SchedRW = [WriteSystem] in {
2227 def RDRAND16r : I<0xC7, MRM6r, (outs GR16:$dst), (ins),
2229 [(set GR16:$dst, EFLAGS, (X86rdrand))], IIC_RDRAND>,
2231 def RDRAND32r : I<0xC7, MRM6r, (outs GR32:$dst), (ins),
2233 [(set GR32:$dst, EFLAGS, (X86rdrand))], IIC_RDRAND>,
2235 def RDRAND64r : RI<0xC7, MRM6r, (outs GR64:$dst), (ins),
2237 [(set GR64:$dst, EFLAGS, (X86rdrand))], IIC_RDRAND>, PS;
2240 //===----------------------------------------------------------------------===//
2241 // RDSEED Instruction
2243 let Predicates = [HasRDSEED], Defs = [EFLAGS], SchedRW = [WriteSystem] in {
2244 def RDSEED16r : I<0xC7, MRM7r, (outs GR16:$dst), (ins),
2246 [(set GR16:$dst, EFLAGS, (X86rdseed))], IIC_RDSEED>,
2248 def RDSEED32r : I<0xC7, MRM7r, (outs GR32:$dst), (ins),
2250 [(set GR32:$dst, EFLAGS, (X86rdseed))], IIC_RDSEED>,
2252 def RDSEED64r : RI<0xC7, MRM7r, (outs GR64:$dst), (ins),
2254 [(set GR64:$dst, EFLAGS, (X86rdseed))], IIC_RDSEED>, PS;
2257 //===----------------------------------------------------------------------===//
2258 // LZCNT Instruction
2260 let Predicates = [HasLZCNT], Defs = [EFLAGS] in {
2261 def LZCNT16rr : I<0xBD, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
2262 "lzcnt{w}\t{$src, $dst|$dst, $src}",
2263 [(set GR16:$dst, (ctlz GR16:$src)), (implicit EFLAGS)],
2264 IIC_LZCNT_RR>, XS, OpSize16, Sched<[WriteIMul]>;
2265 def LZCNT16rm : I<0xBD, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
2266 "lzcnt{w}\t{$src, $dst|$dst, $src}",
2267 [(set GR16:$dst, (ctlz (loadi16 addr:$src))),
2268 (implicit EFLAGS)], IIC_LZCNT_RM>, XS, OpSize16,
2269 Sched<[WriteIMulLd]>;
2271 def LZCNT32rr : I<0xBD, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
2272 "lzcnt{l}\t{$src, $dst|$dst, $src}",
2273 [(set GR32:$dst, (ctlz GR32:$src)), (implicit EFLAGS)],
2274 IIC_LZCNT_RR>, XS, OpSize32, Sched<[WriteIMul]>;
2275 def LZCNT32rm : I<0xBD, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
2276 "lzcnt{l}\t{$src, $dst|$dst, $src}",
2277 [(set GR32:$dst, (ctlz (loadi32 addr:$src))),
2278 (implicit EFLAGS)], IIC_LZCNT_RM>, XS, OpSize32,
2279 Sched<[WriteIMulLd]>;
2281 def LZCNT64rr : RI<0xBD, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
2282 "lzcnt{q}\t{$src, $dst|$dst, $src}",
2283 [(set GR64:$dst, (ctlz GR64:$src)), (implicit EFLAGS)],
2284 IIC_LZCNT_RR>, XS, Sched<[WriteIMul]>;
2285 def LZCNT64rm : RI<0xBD, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
2286 "lzcnt{q}\t{$src, $dst|$dst, $src}",
2287 [(set GR64:$dst, (ctlz (loadi64 addr:$src))),
2288 (implicit EFLAGS)], IIC_LZCNT_RM>, XS,
2289 Sched<[WriteIMulLd]>;
2292 //===----------------------------------------------------------------------===//
2295 let Predicates = [HasBMI], Defs = [EFLAGS] in {
2296 def TZCNT16rr : I<0xBC, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
2297 "tzcnt{w}\t{$src, $dst|$dst, $src}",
2298 [(set GR16:$dst, (cttz GR16:$src)), (implicit EFLAGS)],
2299 IIC_TZCNT_RR>, XS, OpSize16, Sched<[WriteIMul]>;
2300 def TZCNT16rm : I<0xBC, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
2301 "tzcnt{w}\t{$src, $dst|$dst, $src}",
2302 [(set GR16:$dst, (cttz (loadi16 addr:$src))),
2303 (implicit EFLAGS)], IIC_TZCNT_RM>, XS, OpSize16,
2304 Sched<[WriteIMulLd]>;
2306 def TZCNT32rr : I<0xBC, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
2307 "tzcnt{l}\t{$src, $dst|$dst, $src}",
2308 [(set GR32:$dst, (cttz GR32:$src)), (implicit EFLAGS)],
2309 IIC_TZCNT_RR>, XS, OpSize32, Sched<[WriteIMul]>;
2310 def TZCNT32rm : I<0xBC, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
2311 "tzcnt{l}\t{$src, $dst|$dst, $src}",
2312 [(set GR32:$dst, (cttz (loadi32 addr:$src))),
2313 (implicit EFLAGS)], IIC_TZCNT_RM>, XS, OpSize32,
2314 Sched<[WriteIMulLd]>;
2316 def TZCNT64rr : RI<0xBC, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
2317 "tzcnt{q}\t{$src, $dst|$dst, $src}",
2318 [(set GR64:$dst, (cttz GR64:$src)), (implicit EFLAGS)],
2319 IIC_TZCNT_RR>, XS, Sched<[WriteIMul]>;
2320 def TZCNT64rm : RI<0xBC, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
2321 "tzcnt{q}\t{$src, $dst|$dst, $src}",
2322 [(set GR64:$dst, (cttz (loadi64 addr:$src))),
2323 (implicit EFLAGS)], IIC_TZCNT_RM>, XS,
2324 Sched<[WriteIMulLd]>;
2327 multiclass bmi_bls<string mnemonic, Format RegMRM, Format MemMRM,
2328 RegisterClass RC, X86MemOperand x86memop> {
2329 let hasSideEffects = 0 in {
2330 def rr : I<0xF3, RegMRM, (outs RC:$dst), (ins RC:$src),
2331 !strconcat(mnemonic, "\t{$src, $dst|$dst, $src}"),
2332 [], IIC_UNARY_REG>, T8PS, VEX_4V, Sched<[WriteALU]>;
2334 def rm : I<0xF3, MemMRM, (outs RC:$dst), (ins x86memop:$src),
2335 !strconcat(mnemonic, "\t{$src, $dst|$dst, $src}"),
2336 [], IIC_UNARY_MEM>, T8PS, VEX_4V, Sched<[WriteALULd, ReadAfterLd]>;
2340 let Predicates = [HasBMI], Defs = [EFLAGS] in {
2341 defm BLSR32 : bmi_bls<"blsr{l}", MRM1r, MRM1m, GR32, i32mem>;
2342 defm BLSR64 : bmi_bls<"blsr{q}", MRM1r, MRM1m, GR64, i64mem>, VEX_W;
2343 defm BLSMSK32 : bmi_bls<"blsmsk{l}", MRM2r, MRM2m, GR32, i32mem>;
2344 defm BLSMSK64 : bmi_bls<"blsmsk{q}", MRM2r, MRM2m, GR64, i64mem>, VEX_W;
2345 defm BLSI32 : bmi_bls<"blsi{l}", MRM3r, MRM3m, GR32, i32mem>;
2346 defm BLSI64 : bmi_bls<"blsi{q}", MRM3r, MRM3m, GR64, i64mem>, VEX_W;
2349 //===----------------------------------------------------------------------===//
2350 // Pattern fragments to auto generate BMI instructions.
2351 //===----------------------------------------------------------------------===//
2353 let Predicates = [HasBMI] in {
2354 // FIXME: patterns for the load versions are not implemented
2355 def : Pat<(and GR32:$src, (add GR32:$src, -1)),
2356 (BLSR32rr GR32:$src)>;
2357 def : Pat<(and GR64:$src, (add GR64:$src, -1)),
2358 (BLSR64rr GR64:$src)>;
2360 def : Pat<(xor GR32:$src, (add GR32:$src, -1)),
2361 (BLSMSK32rr GR32:$src)>;
2362 def : Pat<(xor GR64:$src, (add GR64:$src, -1)),
2363 (BLSMSK64rr GR64:$src)>;
2365 def : Pat<(and GR32:$src, (ineg GR32:$src)),
2366 (BLSI32rr GR32:$src)>;
2367 def : Pat<(and GR64:$src, (ineg GR64:$src)),
2368 (BLSI64rr GR64:$src)>;
2371 multiclass bmi_bextr_bzhi<bits<8> opc, string mnemonic, RegisterClass RC,
2372 X86MemOperand x86memop, Intrinsic Int,
2374 def rr : I<opc, MRMSrcReg4VOp3, (outs RC:$dst), (ins RC:$src1, RC:$src2),
2375 !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2376 [(set RC:$dst, (Int RC:$src1, RC:$src2)), (implicit EFLAGS)], IIC_BIN_NONMEM>,
2377 T8PS, VEX, Sched<[WriteALU]>;
2378 def rm : I<opc, MRMSrcMem4VOp3, (outs RC:$dst), (ins x86memop:$src1, RC:$src2),
2379 !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2380 [(set RC:$dst, (Int (ld_frag addr:$src1), RC:$src2)),
2381 (implicit EFLAGS)], IIC_BIN_MEM>, T8PS, VEX,
2382 Sched<[WriteALULd, ReadAfterLd]>;
2385 let Predicates = [HasBMI], Defs = [EFLAGS] in {
2386 defm BEXTR32 : bmi_bextr_bzhi<0xF7, "bextr{l}", GR32, i32mem,
2387 int_x86_bmi_bextr_32, loadi32>;
2388 defm BEXTR64 : bmi_bextr_bzhi<0xF7, "bextr{q}", GR64, i64mem,
2389 int_x86_bmi_bextr_64, loadi64>, VEX_W;
2392 let Predicates = [HasBMI2], Defs = [EFLAGS] in {
2393 defm BZHI32 : bmi_bextr_bzhi<0xF5, "bzhi{l}", GR32, i32mem,
2394 int_x86_bmi_bzhi_32, loadi32>;
2395 defm BZHI64 : bmi_bextr_bzhi<0xF5, "bzhi{q}", GR64, i64mem,
2396 int_x86_bmi_bzhi_64, loadi64>, VEX_W;
2399 def CountTrailingOnes : SDNodeXForm<imm, [{
2400 // Count the trailing ones in the immediate.
2401 return getI8Imm(countTrailingOnes(N->getZExtValue()), SDLoc(N));
2404 def BEXTRMaskXForm : SDNodeXForm<imm, [{
2405 unsigned Length = countTrailingOnes(N->getZExtValue());
2406 return getI32Imm(Length << 8, SDLoc(N));
2409 def AndMask64 : ImmLeaf<i64, [{
2410 return isMask_64(Imm) && Imm > UINT32_MAX;
2413 // Use BEXTR for 64-bit 'and' with large immediate 'mask'.
2414 let Predicates = [HasBMI, NoBMI2, NoTBM] in {
2415 def : Pat<(and GR64:$src, AndMask64:$mask),
2416 (BEXTR64rr GR64:$src,
2417 (SUBREG_TO_REG (i64 0),
2418 (MOV32ri (BEXTRMaskXForm imm:$mask)), sub_32bit))>;
2419 def : Pat<(and (loadi64 addr:$src), AndMask64:$mask),
2420 (BEXTR64rm addr:$src,
2421 (SUBREG_TO_REG (i64 0),
2422 (MOV32ri (BEXTRMaskXForm imm:$mask)), sub_32bit))>;
2425 // Use BZHI for 64-bit 'and' with large immediate 'mask'.
2426 let Predicates = [HasBMI2, NoTBM] in {
2427 def : Pat<(and GR64:$src, AndMask64:$mask),
2428 (BZHI64rr GR64:$src,
2429 (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
2430 (MOV8ri (CountTrailingOnes imm:$mask)), sub_8bit))>;
2431 def : Pat<(and (loadi64 addr:$src), AndMask64:$mask),
2432 (BZHI64rm addr:$src,
2433 (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
2434 (MOV8ri (CountTrailingOnes imm:$mask)), sub_8bit))>;
2437 let Predicates = [HasBMI2] in {
2438 def : Pat<(and GR32:$src, (add (shl 1, GR8:$lz), -1)),
2439 (BZHI32rr GR32:$src,
2440 (INSERT_SUBREG (i32 (IMPLICIT_DEF)), GR8:$lz, sub_8bit))>;
2442 def : Pat<(and (loadi32 addr:$src), (add (shl 1, GR8:$lz), -1)),
2443 (BZHI32rm addr:$src,
2444 (INSERT_SUBREG (i32 (IMPLICIT_DEF)), GR8:$lz, sub_8bit))>;
2446 def : Pat<(and GR64:$src, (add (shl 1, GR8:$lz), -1)),
2447 (BZHI64rr GR64:$src,
2448 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR8:$lz, sub_8bit))>;
2450 def : Pat<(and (loadi64 addr:$src), (add (shl 1, GR8:$lz), -1)),
2451 (BZHI64rm addr:$src,
2452 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR8:$lz, sub_8bit))>;
2454 // x & (-1 >> (32 - y))
2455 def : Pat<(and GR32:$src, (srl -1, (i8 (trunc (sub 32, GR32:$lz))))),
2456 (BZHI32rr GR32:$src, GR32:$lz)>;
2457 def : Pat<(and (loadi32 addr:$src), (srl -1, (i8 (trunc (sub 32, GR32:$lz))))),
2458 (BZHI32rm addr:$src, GR32:$lz)>;
2460 // x & (-1 >> (64 - y))
2461 def : Pat<(and GR64:$src, (srl -1, (i8 (trunc (sub 64, GR32:$lz))))),
2462 (BZHI64rr GR64:$src,
2463 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR32:$lz, sub_32bit))>;
2464 def : Pat<(and (loadi64 addr:$src), (srl -1, (i8 (trunc (sub 64, GR32:$lz))))),
2465 (BZHI64rm addr:$src,
2466 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR32:$lz, sub_32bit))>;
2468 // x << (32 - y) >> (32 - y)
2469 def : Pat<(srl (shl GR32:$src, (i8 (trunc (sub 32, GR32:$lz)))),
2470 (i8 (trunc (sub 32, GR32:$lz)))),
2471 (BZHI32rr GR32:$src, GR32:$lz)>;
2472 def : Pat<(srl (shl (loadi32 addr:$src), (i8 (trunc (sub 32, GR32:$lz)))),
2473 (i8 (trunc (sub 32, GR32:$lz)))),
2474 (BZHI32rm addr:$src, GR32:$lz)>;
2476 // x << (64 - y) >> (64 - y)
2477 def : Pat<(srl (shl GR64:$src, (i8 (trunc (sub 64, GR32:$lz)))),
2478 (i8 (trunc (sub 64, GR32:$lz)))),
2479 (BZHI64rr GR64:$src,
2480 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR32:$lz, sub_32bit))>;
2481 def : Pat<(srl (shl (loadi64 addr:$src), (i8 (trunc (sub 64, GR32:$lz)))),
2482 (i8 (trunc (sub 64, GR32:$lz)))),
2483 (BZHI64rm addr:$src,
2484 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR32:$lz, sub_32bit))>;
2487 multiclass bmi_pdep_pext<string mnemonic, RegisterClass RC,
2488 X86MemOperand x86memop, Intrinsic Int,
2490 def rr : I<0xF5, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
2491 !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2492 [(set RC:$dst, (Int RC:$src1, RC:$src2))], IIC_BIN_NONMEM>,
2493 VEX_4V, Sched<[WriteALU]>;
2494 def rm : I<0xF5, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
2495 !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2496 [(set RC:$dst, (Int RC:$src1, (ld_frag addr:$src2)))],
2497 IIC_BIN_MEM>, VEX_4V, Sched<[WriteALULd, ReadAfterLd]>;
2500 let Predicates = [HasBMI2] in {
2501 defm PDEP32 : bmi_pdep_pext<"pdep{l}", GR32, i32mem,
2502 int_x86_bmi_pdep_32, loadi32>, T8XD;
2503 defm PDEP64 : bmi_pdep_pext<"pdep{q}", GR64, i64mem,
2504 int_x86_bmi_pdep_64, loadi64>, T8XD, VEX_W;
2505 defm PEXT32 : bmi_pdep_pext<"pext{l}", GR32, i32mem,
2506 int_x86_bmi_pext_32, loadi32>, T8XS;
2507 defm PEXT64 : bmi_pdep_pext<"pext{q}", GR64, i64mem,
2508 int_x86_bmi_pext_64, loadi64>, T8XS, VEX_W;
2511 //===----------------------------------------------------------------------===//
2514 let Predicates = [HasTBM], Defs = [EFLAGS] in {
2516 multiclass tbm_ternary_imm_intr<bits<8> opc, RegisterClass RC, string OpcodeStr,
2517 X86MemOperand x86memop, PatFrag ld_frag,
2518 Intrinsic Int, Operand immtype,
2519 SDPatternOperator immoperator> {
2520 def ri : Ii32<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, immtype:$cntl),
2521 !strconcat(OpcodeStr,
2522 "\t{$cntl, $src1, $dst|$dst, $src1, $cntl}"),
2523 [(set RC:$dst, (Int RC:$src1, immoperator:$cntl))],
2524 IIC_BIN_NONMEM>, XOP, XOPA, Sched<[WriteALU]>;
2525 def mi : Ii32<opc, MRMSrcMem, (outs RC:$dst),
2526 (ins x86memop:$src1, immtype:$cntl),
2527 !strconcat(OpcodeStr,
2528 "\t{$cntl, $src1, $dst|$dst, $src1, $cntl}"),
2529 [(set RC:$dst, (Int (ld_frag addr:$src1), immoperator:$cntl))],
2530 IIC_BIN_MEM>, XOP, XOPA, Sched<[WriteALULd, ReadAfterLd]>;
2533 defm BEXTRI32 : tbm_ternary_imm_intr<0x10, GR32, "bextr", i32mem, loadi32,
2534 int_x86_tbm_bextri_u32, i32imm, imm>;
2535 let ImmT = Imm32S in
2536 defm BEXTRI64 : tbm_ternary_imm_intr<0x10, GR64, "bextr", i64mem, loadi64,
2537 int_x86_tbm_bextri_u64, i64i32imm,
2538 i64immSExt32>, VEX_W;
2540 multiclass tbm_binary_rm<bits<8> opc, Format FormReg, Format FormMem,
2541 RegisterClass RC, string OpcodeStr,
2542 X86MemOperand x86memop, PatFrag ld_frag> {
2543 let hasSideEffects = 0 in {
2544 def rr : I<opc, FormReg, (outs RC:$dst), (ins RC:$src),
2545 !strconcat(OpcodeStr,"\t{$src, $dst|$dst, $src}"),
2546 [], IIC_BIN_NONMEM>, XOP_4V, XOP9, Sched<[WriteALU]>;
2548 def rm : I<opc, FormMem, (outs RC:$dst), (ins x86memop:$src),
2549 !strconcat(OpcodeStr,"\t{$src, $dst|$dst, $src}"),
2550 [], IIC_BIN_MEM>, XOP_4V, XOP9, Sched<[WriteALULd, ReadAfterLd]>;
2554 multiclass tbm_binary_intr<bits<8> opc, string OpcodeStr,
2555 Format FormReg, Format FormMem> {
2556 defm NAME#32 : tbm_binary_rm<opc, FormReg, FormMem, GR32, OpcodeStr, i32mem,
2558 defm NAME#64 : tbm_binary_rm<opc, FormReg, FormMem, GR64, OpcodeStr, i64mem,
2562 defm BLCFILL : tbm_binary_intr<0x01, "blcfill", MRM1r, MRM1m>;
2563 defm BLCI : tbm_binary_intr<0x02, "blci", MRM6r, MRM6m>;
2564 defm BLCIC : tbm_binary_intr<0x01, "blcic", MRM5r, MRM5m>;
2565 defm BLCMSK : tbm_binary_intr<0x02, "blcmsk", MRM1r, MRM1m>;
2566 defm BLCS : tbm_binary_intr<0x01, "blcs", MRM3r, MRM3m>;
2567 defm BLSFILL : tbm_binary_intr<0x01, "blsfill", MRM2r, MRM2m>;
2568 defm BLSIC : tbm_binary_intr<0x01, "blsic", MRM6r, MRM6m>;
2569 defm T1MSKC : tbm_binary_intr<0x01, "t1mskc", MRM7r, MRM7m>;
2570 defm TZMSK : tbm_binary_intr<0x01, "tzmsk", MRM4r, MRM4m>;
2573 // Use BEXTRI for 64-bit 'and' with large immediate 'mask'.
2574 let Predicates = [HasTBM] in {
2575 def : Pat<(and GR64:$src, AndMask64:$mask),
2576 (BEXTRI64ri GR64:$src, (BEXTRMaskXForm imm:$mask))>;
2578 def : Pat<(and (loadi64 addr:$src), AndMask64:$mask),
2579 (BEXTRI64mi addr:$src, (BEXTRMaskXForm imm:$mask))>;
2582 //===----------------------------------------------------------------------===//
2583 // Lightweight Profiling Instructions
2585 let Predicates = [HasLWP], SchedRW = [WriteSystem] in {
2587 def LLWPCB : I<0x12, MRM0r, (outs), (ins GR32:$src), "llwpcb\t$src",
2588 [(int_x86_llwpcb GR32:$src)], IIC_LWP>,
2590 def SLWPCB : I<0x12, MRM1r, (outs GR32:$dst), (ins), "slwpcb\t$dst",
2591 [(set GR32:$dst, (int_x86_slwpcb))], IIC_LWP>,
2594 def LLWPCB64 : I<0x12, MRM0r, (outs), (ins GR64:$src), "llwpcb\t$src",
2595 [(int_x86_llwpcb GR64:$src)], IIC_LWP>,
2597 def SLWPCB64 : I<0x12, MRM1r, (outs GR64:$dst), (ins), "slwpcb\t$dst",
2598 [(set GR64:$dst, (int_x86_slwpcb))], IIC_LWP>,
2601 multiclass lwpins_intr<RegisterClass RC> {
2602 def rri : Ii32<0x12, MRM0r, (outs), (ins RC:$src0, GR32:$src1, i32imm:$cntl),
2603 "lwpins\t{$cntl, $src1, $src0|$src0, $src1, $cntl}",
2604 [(set EFLAGS, (X86lwpins RC:$src0, GR32:$src1, imm:$cntl))], IIC_LWP>,
2607 def rmi : Ii32<0x12, MRM0m, (outs), (ins RC:$src0, i32mem:$src1, i32imm:$cntl),
2608 "lwpins\t{$cntl, $src1, $src0|$src0, $src1, $cntl}",
2609 [(set EFLAGS, (X86lwpins RC:$src0, (loadi32 addr:$src1), imm:$cntl))], IIC_LWP>,
2613 let Defs = [EFLAGS] in {
2614 defm LWPINS32 : lwpins_intr<GR32>;
2615 defm LWPINS64 : lwpins_intr<GR64>, VEX_W;
2618 multiclass lwpval_intr<RegisterClass RC, Intrinsic Int> {
2619 def rri : Ii32<0x12, MRM1r, (outs), (ins RC:$src0, GR32:$src1, i32imm:$cntl),
2620 "lwpval\t{$cntl, $src1, $src0|$src0, $src1, $cntl}",
2621 [(Int RC:$src0, GR32:$src1, imm:$cntl)], IIC_LWP>,
2624 def rmi : Ii32<0x12, MRM1m, (outs), (ins RC:$src0, i32mem:$src1, i32imm:$cntl),
2625 "lwpval\t{$cntl, $src1, $src0|$src0, $src1, $cntl}",
2626 [(Int RC:$src0, (loadi32 addr:$src1), imm:$cntl)], IIC_LWP>,
2630 defm LWPVAL32 : lwpval_intr<GR32, int_x86_lwpval32>;
2631 defm LWPVAL64 : lwpval_intr<GR64, int_x86_lwpval64>, VEX_W;
2633 } // HasLWP, SchedRW
2635 //===----------------------------------------------------------------------===//
2636 // MONITORX/MWAITX Instructions
2638 let SchedRW = [ WriteSystem ] in {
2639 let usesCustomInserter = 1 in {
2640 def MONITORX : PseudoI<(outs), (ins i32mem:$src1, GR32:$src2, GR32:$src3),
2641 [(int_x86_monitorx addr:$src1, GR32:$src2, GR32:$src3)]>,
2642 Requires<[ HasMWAITX ]>;
2645 let Uses = [ EAX, ECX, EDX ] in {
2646 def MONITORXrrr : I<0x01, MRM_FA, (outs), (ins), "monitorx", [], IIC_SSE_MONITORX>,
2647 TB, Requires<[ HasMWAITX ]>;
2650 let Uses = [ ECX, EAX, EBX ] in {
2651 def MWAITXrrr : I<0x01, MRM_FB, (outs), (ins), "mwaitx",
2652 [(int_x86_mwaitx ECX, EAX, EBX)], IIC_SSE_MWAITX>,
2653 TB, Requires<[ HasMWAITX ]>;
2657 def : InstAlias<"mwaitx\t{%eax, %ecx, %ebx|ebx, ecx, eax}", (MWAITXrrr)>,
2658 Requires<[ Not64BitMode ]>;
2659 def : InstAlias<"mwaitx\t{%rax, %rcx, %rbx|rbx, rcx, rax}", (MWAITXrrr)>,
2660 Requires<[ In64BitMode ]>;
2662 def : InstAlias<"monitorx\t{%eax, %ecx, %edx|edx, ecx, eax}", (MONITORXrrr)>,
2663 Requires<[ Not64BitMode ]>;
2664 def : InstAlias<"monitorx\t{%rax, %rcx, %rdx|rdx, rcx, rax}", (MONITORXrrr)>,
2665 Requires<[ In64BitMode ]>;
2667 //===----------------------------------------------------------------------===//
2668 // CLZERO Instruction
2670 let SchedRW = [WriteSystem] in {
2672 def CLZEROr : I<0x01, MRM_FC, (outs), (ins), "clzero", [], IIC_SSE_CLZERO>,
2673 TB, Requires<[HasCLZERO]>;
2675 let usesCustomInserter = 1 in {
2676 def CLZERO : PseudoI<(outs), (ins i32mem:$src1),
2677 [(int_x86_clzero addr:$src1)]>, Requires<[HasCLZERO]>;
2681 def : InstAlias<"clzero\t{%eax|eax}", (CLZEROr)>, Requires<[Not64BitMode]>;
2682 def : InstAlias<"clzero\t{%rax|rax}", (CLZEROr)>, Requires<[In64BitMode]>;
2684 //===----------------------------------------------------------------------===//
2685 // Pattern fragments to auto generate TBM instructions.
2686 //===----------------------------------------------------------------------===//
2688 let Predicates = [HasTBM] in {
2689 // FIXME: patterns for the load versions are not implemented
2690 def : Pat<(and GR32:$src, (add GR32:$src, 1)),
2691 (BLCFILL32rr GR32:$src)>;
2692 def : Pat<(and GR64:$src, (add GR64:$src, 1)),
2693 (BLCFILL64rr GR64:$src)>;
2695 def : Pat<(or GR32:$src, (not (add GR32:$src, 1))),
2696 (BLCI32rr GR32:$src)>;
2697 def : Pat<(or GR64:$src, (not (add GR64:$src, 1))),
2698 (BLCI64rr GR64:$src)>;
2700 // Extra patterns because opt can optimize the above patterns to this.
2701 def : Pat<(or GR32:$src, (sub -2, GR32:$src)),
2702 (BLCI32rr GR32:$src)>;
2703 def : Pat<(or GR64:$src, (sub -2, GR64:$src)),
2704 (BLCI64rr GR64:$src)>;
2706 def : Pat<(and (not GR32:$src), (add GR32:$src, 1)),
2707 (BLCIC32rr GR32:$src)>;
2708 def : Pat<(and (not GR64:$src), (add GR64:$src, 1)),
2709 (BLCIC64rr GR64:$src)>;
2711 def : Pat<(xor GR32:$src, (add GR32:$src, 1)),
2712 (BLCMSK32rr GR32:$src)>;
2713 def : Pat<(xor GR64:$src, (add GR64:$src, 1)),
2714 (BLCMSK64rr GR64:$src)>;
2716 def : Pat<(or GR32:$src, (add GR32:$src, 1)),
2717 (BLCS32rr GR32:$src)>;
2718 def : Pat<(or GR64:$src, (add GR64:$src, 1)),
2719 (BLCS64rr GR64:$src)>;
2721 def : Pat<(or GR32:$src, (add GR32:$src, -1)),
2722 (BLSFILL32rr GR32:$src)>;
2723 def : Pat<(or GR64:$src, (add GR64:$src, -1)),
2724 (BLSFILL64rr GR64:$src)>;
2726 def : Pat<(or (not GR32:$src), (add GR32:$src, -1)),
2727 (BLSIC32rr GR32:$src)>;
2728 def : Pat<(or (not GR64:$src), (add GR64:$src, -1)),
2729 (BLSIC64rr GR64:$src)>;
2731 def : Pat<(or (not GR32:$src), (add GR32:$src, 1)),
2732 (T1MSKC32rr GR32:$src)>;
2733 def : Pat<(or (not GR64:$src), (add GR64:$src, 1)),
2734 (T1MSKC64rr GR64:$src)>;
2736 def : Pat<(and (not GR32:$src), (add GR32:$src, -1)),
2737 (TZMSK32rr GR32:$src)>;
2738 def : Pat<(and (not GR64:$src), (add GR64:$src, -1)),
2739 (TZMSK64rr GR64:$src)>;
2742 //===----------------------------------------------------------------------===//
2743 // Memory Instructions
2746 let Predicates = [HasCLFLUSHOPT], SchedRW = [WriteLoad] in
2747 def CLFLUSHOPT : I<0xAE, MRM7m, (outs), (ins i8mem:$src),
2748 "clflushopt\t$src", [(int_x86_clflushopt addr:$src)],
2749 IIC_SSE_PREFETCH>, PD;
2751 let Predicates = [HasCLWB], SchedRW = [WriteLoad] in
2752 def CLWB : I<0xAE, MRM6m, (outs), (ins i8mem:$src), "clwb\t$src",
2753 [(int_x86_clwb addr:$src)], IIC_SSE_PREFETCH>, PD;
2755 //===----------------------------------------------------------------------===//
2757 //===----------------------------------------------------------------------===//
2759 include "X86InstrArithmetic.td"
2760 include "X86InstrCMovSetCC.td"
2761 include "X86InstrExtension.td"
2762 include "X86InstrControl.td"
2763 include "X86InstrShiftRotate.td"
2765 // X87 Floating Point Stack.
2766 include "X86InstrFPStack.td"
2768 // SIMD support (SSE, MMX and AVX)
2769 include "X86InstrFragmentsSIMD.td"
2771 // FMA - Fused Multiply-Add support (requires FMA)
2772 include "X86InstrFMA.td"
2775 include "X86InstrXOP.td"
2777 // SSE, MMX and 3DNow! vector support.
2778 include "X86InstrSSE.td"
2779 include "X86InstrAVX512.td"
2780 include "X86InstrMMX.td"
2781 include "X86Instr3DNow.td"
2784 include "X86InstrMPX.td"
2786 include "X86InstrVMX.td"
2787 include "X86InstrSVM.td"
2789 include "X86InstrTSX.td"
2790 include "X86InstrSGX.td"
2792 // System instructions.
2793 include "X86InstrSystem.td"
2795 // Compiler Pseudo Instructions and Pat Patterns
2796 include "X86InstrCompiler.td"
2797 include "X86InstrVecCompiler.td"
2799 //===----------------------------------------------------------------------===//
2800 // Assembler Mnemonic Aliases
2801 //===----------------------------------------------------------------------===//
2803 def : MnemonicAlias<"call", "callw", "att">, Requires<[In16BitMode]>;
2804 def : MnemonicAlias<"call", "calll", "att">, Requires<[In32BitMode]>;
2805 def : MnemonicAlias<"call", "callq", "att">, Requires<[In64BitMode]>;
2807 def : MnemonicAlias<"cbw", "cbtw", "att">;
2808 def : MnemonicAlias<"cwde", "cwtl", "att">;
2809 def : MnemonicAlias<"cwd", "cwtd", "att">;
2810 def : MnemonicAlias<"cdq", "cltd", "att">;
2811 def : MnemonicAlias<"cdqe", "cltq", "att">;
2812 def : MnemonicAlias<"cqo", "cqto", "att">;
2814 // In 64-bit mode lret maps to lretl; it is not ambiguous with lretq.
2815 def : MnemonicAlias<"lret", "lretw", "att">, Requires<[In16BitMode]>;
2816 def : MnemonicAlias<"lret", "lretl", "att">, Requires<[Not16BitMode]>;
2818 def : MnemonicAlias<"leavel", "leave", "att">, Requires<[Not64BitMode]>;
2819 def : MnemonicAlias<"leaveq", "leave", "att">, Requires<[In64BitMode]>;
2821 def : MnemonicAlias<"loopz", "loope">;
2822 def : MnemonicAlias<"loopnz", "loopne">;
2824 def : MnemonicAlias<"pop", "popw", "att">, Requires<[In16BitMode]>;
2825 def : MnemonicAlias<"pop", "popl", "att">, Requires<[In32BitMode]>;
2826 def : MnemonicAlias<"pop", "popq", "att">, Requires<[In64BitMode]>;
2827 def : MnemonicAlias<"popf", "popfw", "att">, Requires<[In16BitMode]>;
2828 def : MnemonicAlias<"popf", "popfl", "att">, Requires<[In32BitMode]>;
2829 def : MnemonicAlias<"popf", "popfq", "att">, Requires<[In64BitMode]>;
2830 def : MnemonicAlias<"popf", "popfq", "intel">, Requires<[In64BitMode]>;
2831 def : MnemonicAlias<"popfd", "popfl", "att">;
2833 // FIXME: This is wrong for "push reg". "push %bx" should turn into pushw in
2834 // all modes. However: "push (addr)" and "push $42" should default to
2835 // pushl/pushq depending on the current mode. Similar for "pop %bx"
2836 def : MnemonicAlias<"push", "pushw", "att">, Requires<[In16BitMode]>;
2837 def : MnemonicAlias<"push", "pushl", "att">, Requires<[In32BitMode]>;
2838 def : MnemonicAlias<"push", "pushq", "att">, Requires<[In64BitMode]>;
2839 def : MnemonicAlias<"pushf", "pushfw", "att">, Requires<[In16BitMode]>;
2840 def : MnemonicAlias<"pushf", "pushfl", "att">, Requires<[In32BitMode]>;
2841 def : MnemonicAlias<"pushf", "pushfq", "att">, Requires<[In64BitMode]>;
2842 def : MnemonicAlias<"pushf", "pushfq", "intel">, Requires<[In64BitMode]>;
2843 def : MnemonicAlias<"pushfd", "pushfl", "att">;
2845 def : MnemonicAlias<"popad", "popal", "intel">, Requires<[Not64BitMode]>;
2846 def : MnemonicAlias<"pushad", "pushal", "intel">, Requires<[Not64BitMode]>;
2847 def : MnemonicAlias<"popa", "popaw", "intel">, Requires<[In16BitMode]>;
2848 def : MnemonicAlias<"pusha", "pushaw", "intel">, Requires<[In16BitMode]>;
2849 def : MnemonicAlias<"popa", "popal", "intel">, Requires<[In32BitMode]>;
2850 def : MnemonicAlias<"pusha", "pushal", "intel">, Requires<[In32BitMode]>;
2852 def : MnemonicAlias<"popa", "popaw", "att">, Requires<[In16BitMode]>;
2853 def : MnemonicAlias<"pusha", "pushaw", "att">, Requires<[In16BitMode]>;
2854 def : MnemonicAlias<"popa", "popal", "att">, Requires<[In32BitMode]>;
2855 def : MnemonicAlias<"pusha", "pushal", "att">, Requires<[In32BitMode]>;
2857 def : MnemonicAlias<"repe", "rep">;
2858 def : MnemonicAlias<"repz", "rep">;
2859 def : MnemonicAlias<"repnz", "repne">;
2861 def : MnemonicAlias<"ret", "retw", "att">, Requires<[In16BitMode]>;
2862 def : MnemonicAlias<"ret", "retl", "att">, Requires<[In32BitMode]>;
2863 def : MnemonicAlias<"ret", "retq", "att">, Requires<[In64BitMode]>;
2865 // Apply 'ret' behavior to 'retn'
2866 def : MnemonicAlias<"retn", "retw", "att">, Requires<[In16BitMode]>;
2867 def : MnemonicAlias<"retn", "retl", "att">, Requires<[In32BitMode]>;
2868 def : MnemonicAlias<"retn", "retq", "att">, Requires<[In64BitMode]>;
2869 def : MnemonicAlias<"retn", "ret", "intel">;
2871 def : MnemonicAlias<"sal", "shl", "intel">;
2872 def : MnemonicAlias<"salb", "shlb", "att">;
2873 def : MnemonicAlias<"salw", "shlw", "att">;
2874 def : MnemonicAlias<"sall", "shll", "att">;
2875 def : MnemonicAlias<"salq", "shlq", "att">;
2877 def : MnemonicAlias<"smovb", "movsb", "att">;
2878 def : MnemonicAlias<"smovw", "movsw", "att">;
2879 def : MnemonicAlias<"smovl", "movsl", "att">;
2880 def : MnemonicAlias<"smovq", "movsq", "att">;
2882 def : MnemonicAlias<"ud2a", "ud2", "att">;
2883 def : MnemonicAlias<"verrw", "verr", "att">;
2885 // MS recognizes 'xacquire'/'xrelease' as 'acquire'/'release'
2886 def : MnemonicAlias<"acquire", "xacquire", "intel">;
2887 def : MnemonicAlias<"release", "xrelease", "intel">;
2889 // System instruction aliases.
2890 def : MnemonicAlias<"iret", "iretw", "att">, Requires<[In16BitMode]>;
2891 def : MnemonicAlias<"iret", "iretl", "att">, Requires<[Not16BitMode]>;
2892 def : MnemonicAlias<"sysret", "sysretl", "att">;
2893 def : MnemonicAlias<"sysexit", "sysexitl", "att">;
2895 def : MnemonicAlias<"lgdt", "lgdtw", "att">, Requires<[In16BitMode]>;
2896 def : MnemonicAlias<"lgdt", "lgdtl", "att">, Requires<[In32BitMode]>;
2897 def : MnemonicAlias<"lgdt", "lgdtq", "att">, Requires<[In64BitMode]>;
2898 def : MnemonicAlias<"lidt", "lidtw", "att">, Requires<[In16BitMode]>;
2899 def : MnemonicAlias<"lidt", "lidtl", "att">, Requires<[In32BitMode]>;
2900 def : MnemonicAlias<"lidt", "lidtq", "att">, Requires<[In64BitMode]>;
2901 def : MnemonicAlias<"sgdt", "sgdtw", "att">, Requires<[In16BitMode]>;
2902 def : MnemonicAlias<"sgdt", "sgdtl", "att">, Requires<[In32BitMode]>;
2903 def : MnemonicAlias<"sgdt", "sgdtq", "att">, Requires<[In64BitMode]>;
2904 def : MnemonicAlias<"sidt", "sidtw", "att">, Requires<[In16BitMode]>;
2905 def : MnemonicAlias<"sidt", "sidtl", "att">, Requires<[In32BitMode]>;
2906 def : MnemonicAlias<"sidt", "sidtq", "att">, Requires<[In64BitMode]>;
2909 // Floating point stack aliases.
2910 def : MnemonicAlias<"fcmovz", "fcmove", "att">;
2911 def : MnemonicAlias<"fcmova", "fcmovnbe", "att">;
2912 def : MnemonicAlias<"fcmovnae", "fcmovb", "att">;
2913 def : MnemonicAlias<"fcmovna", "fcmovbe", "att">;
2914 def : MnemonicAlias<"fcmovae", "fcmovnb", "att">;
2915 def : MnemonicAlias<"fcomip", "fcompi">;
2916 def : MnemonicAlias<"fildq", "fildll", "att">;
2917 def : MnemonicAlias<"fistpq", "fistpll", "att">;
2918 def : MnemonicAlias<"fisttpq", "fisttpll", "att">;
2919 def : MnemonicAlias<"fldcww", "fldcw", "att">;
2920 def : MnemonicAlias<"fnstcww", "fnstcw", "att">;
2921 def : MnemonicAlias<"fnstsww", "fnstsw", "att">;
2922 def : MnemonicAlias<"fucomip", "fucompi">;
2923 def : MnemonicAlias<"fwait", "wait">;
2925 def : MnemonicAlias<"fxsaveq", "fxsave64", "att">;
2926 def : MnemonicAlias<"fxrstorq", "fxrstor64", "att">;
2927 def : MnemonicAlias<"xsaveq", "xsave64", "att">;
2928 def : MnemonicAlias<"xrstorq", "xrstor64", "att">;
2929 def : MnemonicAlias<"xsaveoptq", "xsaveopt64", "att">;
2930 def : MnemonicAlias<"xrstorsq", "xrstors64", "att">;
2931 def : MnemonicAlias<"xsavecq", "xsavec64", "att">;
2932 def : MnemonicAlias<"xsavesq", "xsaves64", "att">;
2934 class CondCodeAlias<string Prefix,string Suffix, string OldCond, string NewCond,
2936 : MnemonicAlias<!strconcat(Prefix, OldCond, Suffix),
2937 !strconcat(Prefix, NewCond, Suffix), VariantName>;
2939 /// IntegerCondCodeMnemonicAlias - This multiclass defines a bunch of
2940 /// MnemonicAlias's that canonicalize the condition code in a mnemonic, for
2941 /// example "setz" -> "sete".
2942 multiclass IntegerCondCodeMnemonicAlias<string Prefix, string Suffix,
2944 def C : CondCodeAlias<Prefix, Suffix, "c", "b", V>; // setc -> setb
2945 def Z : CondCodeAlias<Prefix, Suffix, "z" , "e", V>; // setz -> sete
2946 def NA : CondCodeAlias<Prefix, Suffix, "na", "be", V>; // setna -> setbe
2947 def NB : CondCodeAlias<Prefix, Suffix, "nb", "ae", V>; // setnb -> setae
2948 def NC : CondCodeAlias<Prefix, Suffix, "nc", "ae", V>; // setnc -> setae
2949 def NG : CondCodeAlias<Prefix, Suffix, "ng", "le", V>; // setng -> setle
2950 def NL : CondCodeAlias<Prefix, Suffix, "nl", "ge", V>; // setnl -> setge
2951 def NZ : CondCodeAlias<Prefix, Suffix, "nz", "ne", V>; // setnz -> setne
2952 def PE : CondCodeAlias<Prefix, Suffix, "pe", "p", V>; // setpe -> setp
2953 def PO : CondCodeAlias<Prefix, Suffix, "po", "np", V>; // setpo -> setnp
2955 def NAE : CondCodeAlias<Prefix, Suffix, "nae", "b", V>; // setnae -> setb
2956 def NBE : CondCodeAlias<Prefix, Suffix, "nbe", "a", V>; // setnbe -> seta
2957 def NGE : CondCodeAlias<Prefix, Suffix, "nge", "l", V>; // setnge -> setl
2958 def NLE : CondCodeAlias<Prefix, Suffix, "nle", "g", V>; // setnle -> setg
2961 // Aliases for set<CC>
2962 defm : IntegerCondCodeMnemonicAlias<"set", "">;
2963 // Aliases for j<CC>
2964 defm : IntegerCondCodeMnemonicAlias<"j", "">;
2965 // Aliases for cmov<CC>{w,l,q}
2966 defm : IntegerCondCodeMnemonicAlias<"cmov", "w", "att">;
2967 defm : IntegerCondCodeMnemonicAlias<"cmov", "l", "att">;
2968 defm : IntegerCondCodeMnemonicAlias<"cmov", "q", "att">;
2969 // No size suffix for intel-style asm.
2970 defm : IntegerCondCodeMnemonicAlias<"cmov", "", "intel">;
2973 //===----------------------------------------------------------------------===//
2974 // Assembler Instruction Aliases
2975 //===----------------------------------------------------------------------===//
2977 // aad/aam default to base 10 if no operand is specified.
2978 def : InstAlias<"aad", (AAD8i8 10)>, Requires<[Not64BitMode]>;
2979 def : InstAlias<"aam", (AAM8i8 10)>, Requires<[Not64BitMode]>;
2981 // Disambiguate the mem/imm form of bt-without-a-suffix as btl.
2982 // Likewise for btc/btr/bts.
2983 def : InstAlias<"bt\t{$imm, $mem|$mem, $imm}",
2984 (BT32mi8 i32mem:$mem, i32i8imm:$imm), 0>;
2985 def : InstAlias<"btc\t{$imm, $mem|$mem, $imm}",
2986 (BTC32mi8 i32mem:$mem, i32i8imm:$imm), 0>;
2987 def : InstAlias<"btr\t{$imm, $mem|$mem, $imm}",
2988 (BTR32mi8 i32mem:$mem, i32i8imm:$imm), 0>;
2989 def : InstAlias<"bts\t{$imm, $mem|$mem, $imm}",
2990 (BTS32mi8 i32mem:$mem, i32i8imm:$imm), 0>;
2993 def : InstAlias<"clrb\t$reg", (XOR8rr GR8 :$reg, GR8 :$reg), 0>;
2994 def : InstAlias<"clrw\t$reg", (XOR16rr GR16:$reg, GR16:$reg), 0>;
2995 def : InstAlias<"clrl\t$reg", (XOR32rr GR32:$reg, GR32:$reg), 0>;
2996 def : InstAlias<"clrq\t$reg", (XOR64rr GR64:$reg, GR64:$reg), 0>;
2998 // lods aliases. Accept the destination being omitted because it's implicit
2999 // in the mnemonic, or the mnemonic suffix being omitted because it's implicit
3000 // in the destination.
3001 def : InstAlias<"lodsb\t$src", (LODSB srcidx8:$src), 0>;
3002 def : InstAlias<"lodsw\t$src", (LODSW srcidx16:$src), 0>;
3003 def : InstAlias<"lods{l|d}\t$src", (LODSL srcidx32:$src), 0>;
3004 def : InstAlias<"lodsq\t$src", (LODSQ srcidx64:$src), 0>, Requires<[In64BitMode]>;
3005 def : InstAlias<"lods\t{$src, %al|al, $src}", (LODSB srcidx8:$src), 0>;
3006 def : InstAlias<"lods\t{$src, %ax|ax, $src}", (LODSW srcidx16:$src), 0>;
3007 def : InstAlias<"lods\t{$src, %eax|eax, $src}", (LODSL srcidx32:$src), 0>;
3008 def : InstAlias<"lods\t{$src, %rax|rax, $src}", (LODSQ srcidx64:$src), 0>, Requires<[In64BitMode]>;
3009 def : InstAlias<"lods\t$src", (LODSB srcidx8:$src), 0>;
3010 def : InstAlias<"lods\t$src", (LODSW srcidx16:$src), 0>;
3011 def : InstAlias<"lods\t$src", (LODSL srcidx32:$src), 0>;
3012 def : InstAlias<"lods\t$src", (LODSQ srcidx64:$src), 0>, Requires<[In64BitMode]>;
3015 // stos aliases. Accept the source being omitted because it's implicit in
3016 // the mnemonic, or the mnemonic suffix being omitted because it's implicit
3018 def : InstAlias<"stosb\t$dst", (STOSB dstidx8:$dst), 0>;
3019 def : InstAlias<"stosw\t$dst", (STOSW dstidx16:$dst), 0>;
3020 def : InstAlias<"stos{l|d}\t$dst", (STOSL dstidx32:$dst), 0>;
3021 def : InstAlias<"stosq\t$dst", (STOSQ dstidx64:$dst), 0>, Requires<[In64BitMode]>;
3022 def : InstAlias<"stos\t{%al, $dst|$dst, al}", (STOSB dstidx8:$dst), 0>;
3023 def : InstAlias<"stos\t{%ax, $dst|$dst, ax}", (STOSW dstidx16:$dst), 0>;
3024 def : InstAlias<"stos\t{%eax, $dst|$dst, eax}", (STOSL dstidx32:$dst), 0>;
3025 def : InstAlias<"stos\t{%rax, $dst|$dst, rax}", (STOSQ dstidx64:$dst), 0>, Requires<[In64BitMode]>;
3026 def : InstAlias<"stos\t$dst", (STOSB dstidx8:$dst), 0>;
3027 def : InstAlias<"stos\t$dst", (STOSW dstidx16:$dst), 0>;
3028 def : InstAlias<"stos\t$dst", (STOSL dstidx32:$dst), 0>;
3029 def : InstAlias<"stos\t$dst", (STOSQ dstidx64:$dst), 0>, Requires<[In64BitMode]>;
3032 // scas aliases. Accept the destination being omitted because it's implicit
3033 // in the mnemonic, or the mnemonic suffix being omitted because it's implicit
3034 // in the destination.
3035 def : InstAlias<"scasb\t$dst", (SCASB dstidx8:$dst), 0>;
3036 def : InstAlias<"scasw\t$dst", (SCASW dstidx16:$dst), 0>;
3037 def : InstAlias<"scas{l|d}\t$dst", (SCASL dstidx32:$dst), 0>;
3038 def : InstAlias<"scasq\t$dst", (SCASQ dstidx64:$dst), 0>, Requires<[In64BitMode]>;
3039 def : InstAlias<"scas\t{$dst, %al|al, $dst}", (SCASB dstidx8:$dst), 0>;
3040 def : InstAlias<"scas\t{$dst, %ax|ax, $dst}", (SCASW dstidx16:$dst), 0>;
3041 def : InstAlias<"scas\t{$dst, %eax|eax, $dst}", (SCASL dstidx32:$dst), 0>;
3042 def : InstAlias<"scas\t{$dst, %rax|rax, $dst}", (SCASQ dstidx64:$dst), 0>, Requires<[In64BitMode]>;
3043 def : InstAlias<"scas\t$dst", (SCASB dstidx8:$dst), 0>;
3044 def : InstAlias<"scas\t$dst", (SCASW dstidx16:$dst), 0>;
3045 def : InstAlias<"scas\t$dst", (SCASL dstidx32:$dst), 0>;
3046 def : InstAlias<"scas\t$dst", (SCASQ dstidx64:$dst), 0>, Requires<[In64BitMode]>;
3048 // cmps aliases. Mnemonic suffix being omitted because it's implicit
3049 // in the destination.
3050 def : InstAlias<"cmps\t{$dst, $src|$src, $dst}", (CMPSB dstidx8:$dst, srcidx8:$src), 0>;
3051 def : InstAlias<"cmps\t{$dst, $src|$src, $dst}", (CMPSW dstidx16:$dst, srcidx16:$src), 0>;
3052 def : InstAlias<"cmps\t{$dst, $src|$src, $dst}", (CMPSL dstidx32:$dst, srcidx32:$src), 0>;
3053 def : InstAlias<"cmps\t{$dst, $src|$src, $dst}", (CMPSQ dstidx64:$dst, srcidx64:$src), 0>, Requires<[In64BitMode]>;
3055 // movs aliases. Mnemonic suffix being omitted because it's implicit
3056 // in the destination.
3057 def : InstAlias<"movs\t{$src, $dst|$dst, $src}", (MOVSB dstidx8:$dst, srcidx8:$src), 0>;
3058 def : InstAlias<"movs\t{$src, $dst|$dst, $src}", (MOVSW dstidx16:$dst, srcidx16:$src), 0>;
3059 def : InstAlias<"movs\t{$src, $dst|$dst, $src}", (MOVSL dstidx32:$dst, srcidx32:$src), 0>;
3060 def : InstAlias<"movs\t{$src, $dst|$dst, $src}", (MOVSQ dstidx64:$dst, srcidx64:$src), 0>, Requires<[In64BitMode]>;
3062 // div and idiv aliases for explicit A register.
3063 def : InstAlias<"div{b}\t{$src, %al|al, $src}", (DIV8r GR8 :$src)>;
3064 def : InstAlias<"div{w}\t{$src, %ax|ax, $src}", (DIV16r GR16:$src)>;
3065 def : InstAlias<"div{l}\t{$src, %eax|eax, $src}", (DIV32r GR32:$src)>;
3066 def : InstAlias<"div{q}\t{$src, %rax|rax, $src}", (DIV64r GR64:$src)>;
3067 def : InstAlias<"div{b}\t{$src, %al|al, $src}", (DIV8m i8mem :$src)>;
3068 def : InstAlias<"div{w}\t{$src, %ax|ax, $src}", (DIV16m i16mem:$src)>;
3069 def : InstAlias<"div{l}\t{$src, %eax|eax, $src}", (DIV32m i32mem:$src)>;
3070 def : InstAlias<"div{q}\t{$src, %rax|rax, $src}", (DIV64m i64mem:$src)>;
3071 def : InstAlias<"idiv{b}\t{$src, %al|al, $src}", (IDIV8r GR8 :$src)>;
3072 def : InstAlias<"idiv{w}\t{$src, %ax|ax, $src}", (IDIV16r GR16:$src)>;
3073 def : InstAlias<"idiv{l}\t{$src, %eax|eax, $src}", (IDIV32r GR32:$src)>;
3074 def : InstAlias<"idiv{q}\t{$src, %rax|rax, $src}", (IDIV64r GR64:$src)>;
3075 def : InstAlias<"idiv{b}\t{$src, %al|al, $src}", (IDIV8m i8mem :$src)>;
3076 def : InstAlias<"idiv{w}\t{$src, %ax|ax, $src}", (IDIV16m i16mem:$src)>;
3077 def : InstAlias<"idiv{l}\t{$src, %eax|eax, $src}", (IDIV32m i32mem:$src)>;
3078 def : InstAlias<"idiv{q}\t{$src, %rax|rax, $src}", (IDIV64m i64mem:$src)>;
3082 // Various unary fpstack operations default to operating on on ST1.
3083 // For example, "fxch" -> "fxch %st(1)"
3084 def : InstAlias<"faddp", (ADD_FPrST0 ST1), 0>;
3085 def: InstAlias<"fadd", (ADD_FPrST0 ST1), 0>;
3086 def : InstAlias<"fsub{|r}p", (SUBR_FPrST0 ST1), 0>;
3087 def : InstAlias<"fsub{r|}p", (SUB_FPrST0 ST1), 0>;
3088 def : InstAlias<"fmul", (MUL_FPrST0 ST1), 0>;
3089 def : InstAlias<"fmulp", (MUL_FPrST0 ST1), 0>;
3090 def : InstAlias<"fdiv{|r}p", (DIVR_FPrST0 ST1), 0>;
3091 def : InstAlias<"fdiv{r|}p", (DIV_FPrST0 ST1), 0>;
3092 def : InstAlias<"fxch", (XCH_F ST1), 0>;
3093 def : InstAlias<"fcom", (COM_FST0r ST1), 0>;
3094 def : InstAlias<"fcomp", (COMP_FST0r ST1), 0>;
3095 def : InstAlias<"fcomi", (COM_FIr ST1), 0>;
3096 def : InstAlias<"fcompi", (COM_FIPr ST1), 0>;
3097 def : InstAlias<"fucom", (UCOM_Fr ST1), 0>;
3098 def : InstAlias<"fucomp", (UCOM_FPr ST1), 0>;
3099 def : InstAlias<"fucomi", (UCOM_FIr ST1), 0>;
3100 def : InstAlias<"fucompi", (UCOM_FIPr ST1), 0>;
3102 // Handle fmul/fadd/fsub/fdiv instructions with explicitly written st(0) op.
3103 // For example, "fadd %st(4), %st(0)" -> "fadd %st(4)". We also disambiguate
3104 // instructions like "fadd %st(0), %st(0)" as "fadd %st(0)" for consistency with
3106 multiclass FpUnaryAlias<string Mnemonic, Instruction Inst, bit EmitAlias = 1> {
3107 def : InstAlias<!strconcat(Mnemonic, "\t{$op, %st(0)|st(0), $op}"),
3108 (Inst RST:$op), EmitAlias>;
3109 def : InstAlias<!strconcat(Mnemonic, "\t{%st(0), %st(0)|st(0), st(0)}"),
3110 (Inst ST0), EmitAlias>;
3113 defm : FpUnaryAlias<"fadd", ADD_FST0r>;
3114 defm : FpUnaryAlias<"faddp", ADD_FPrST0, 0>;
3115 defm : FpUnaryAlias<"fsub", SUB_FST0r>;
3116 defm : FpUnaryAlias<"fsub{|r}p", SUBR_FPrST0>;
3117 defm : FpUnaryAlias<"fsubr", SUBR_FST0r>;
3118 defm : FpUnaryAlias<"fsub{r|}p", SUB_FPrST0>;
3119 defm : FpUnaryAlias<"fmul", MUL_FST0r>;
3120 defm : FpUnaryAlias<"fmulp", MUL_FPrST0>;
3121 defm : FpUnaryAlias<"fdiv", DIV_FST0r>;
3122 defm : FpUnaryAlias<"fdiv{|r}p", DIVR_FPrST0>;
3123 defm : FpUnaryAlias<"fdivr", DIVR_FST0r>;
3124 defm : FpUnaryAlias<"fdiv{r|}p", DIV_FPrST0>;
3125 defm : FpUnaryAlias<"fcomi", COM_FIr, 0>;
3126 defm : FpUnaryAlias<"fucomi", UCOM_FIr, 0>;
3127 defm : FpUnaryAlias<"fcompi", COM_FIPr>;
3128 defm : FpUnaryAlias<"fucompi", UCOM_FIPr>;
3131 // Handle "f{mulp,addp} st(0), $op" the same as "f{mulp,addp} $op", since they
3132 // commute. We also allow fdiv[r]p/fsubrp even though they don't commute,
3133 // solely because gas supports it.
3134 def : InstAlias<"faddp\t{%st(0), $op|$op, st(0)}", (ADD_FPrST0 RST:$op), 0>;
3135 def : InstAlias<"fmulp\t{%st(0), $op|$op, st(0)}", (MUL_FPrST0 RST:$op)>;
3136 def : InstAlias<"fsub{|r}p\t{%st(0), $op|$op, st(0)}", (SUBR_FPrST0 RST:$op)>;
3137 def : InstAlias<"fsub{r|}p\t{%st(0), $op|$op, st(0)}", (SUB_FPrST0 RST:$op)>;
3138 def : InstAlias<"fdiv{|r}p\t{%st(0), $op|$op, st(0)}", (DIVR_FPrST0 RST:$op)>;
3139 def : InstAlias<"fdiv{r|}p\t{%st(0), $op|$op, st(0)}", (DIV_FPrST0 RST:$op)>;
3141 // We accept "fnstsw %eax" even though it only writes %ax.
3142 def : InstAlias<"fnstsw\t{%eax|eax}", (FNSTSW16r)>;
3143 def : InstAlias<"fnstsw\t{%al|al}" , (FNSTSW16r)>;
3144 def : InstAlias<"fnstsw" , (FNSTSW16r)>;
3146 // lcall and ljmp aliases. This seems to be an odd mapping in 64-bit mode, but
3147 // this is compatible with what GAS does.
3148 def : InstAlias<"lcall\t$seg, $off", (FARCALL32i i32imm:$off, i16imm:$seg), 0>, Requires<[In32BitMode]>;
3149 def : InstAlias<"ljmp\t$seg, $off", (FARJMP32i i32imm:$off, i16imm:$seg), 0>, Requires<[In32BitMode]>;
3150 def : InstAlias<"lcall\t{*}$dst", (FARCALL32m opaque48mem:$dst), 0>, Requires<[Not16BitMode]>;
3151 def : InstAlias<"ljmp\t{*}$dst", (FARJMP32m opaque48mem:$dst), 0>, Requires<[Not16BitMode]>;
3152 def : InstAlias<"lcall\t$seg, $off", (FARCALL16i i16imm:$off, i16imm:$seg), 0>, Requires<[In16BitMode]>;
3153 def : InstAlias<"ljmp\t$seg, $off", (FARJMP16i i16imm:$off, i16imm:$seg), 0>, Requires<[In16BitMode]>;
3154 def : InstAlias<"lcall\t{*}$dst", (FARCALL16m opaque32mem:$dst), 0>, Requires<[In16BitMode]>;
3155 def : InstAlias<"ljmp\t{*}$dst", (FARJMP16m opaque32mem:$dst), 0>, Requires<[In16BitMode]>;
3157 def : InstAlias<"call\t{*}$dst", (CALL64m i64mem:$dst), 0>, Requires<[In64BitMode]>;
3158 def : InstAlias<"jmp\t{*}$dst", (JMP64m i64mem:$dst), 0>, Requires<[In64BitMode]>;
3159 def : InstAlias<"call\t{*}$dst", (CALL32m i32mem:$dst), 0>, Requires<[In32BitMode]>;
3160 def : InstAlias<"jmp\t{*}$dst", (JMP32m i32mem:$dst), 0>, Requires<[In32BitMode]>;
3161 def : InstAlias<"call\t{*}$dst", (CALL16m i16mem:$dst), 0>, Requires<[In16BitMode]>;
3162 def : InstAlias<"jmp\t{*}$dst", (JMP16m i16mem:$dst), 0>, Requires<[In16BitMode]>;
3165 // "imul <imm>, B" is an alias for "imul <imm>, B, B".
3166 def : InstAlias<"imul{w}\t{$imm, $r|$r, $imm}", (IMUL16rri GR16:$r, GR16:$r, i16imm:$imm), 0>;
3167 def : InstAlias<"imul{w}\t{$imm, $r|$r, $imm}", (IMUL16rri8 GR16:$r, GR16:$r, i16i8imm:$imm), 0>;
3168 def : InstAlias<"imul{l}\t{$imm, $r|$r, $imm}", (IMUL32rri GR32:$r, GR32:$r, i32imm:$imm), 0>;
3169 def : InstAlias<"imul{l}\t{$imm, $r|$r, $imm}", (IMUL32rri8 GR32:$r, GR32:$r, i32i8imm:$imm), 0>;
3170 def : InstAlias<"imul{q}\t{$imm, $r|$r, $imm}", (IMUL64rri32 GR64:$r, GR64:$r, i64i32imm:$imm), 0>;
3171 def : InstAlias<"imul{q}\t{$imm, $r|$r, $imm}", (IMUL64rri8 GR64:$r, GR64:$r, i64i8imm:$imm), 0>;
3173 // ins aliases. Accept the mnemonic suffix being omitted because it's implicit
3174 // in the destination.
3175 def : InstAlias<"ins\t{%dx, $dst|$dst, dx}", (INSB dstidx8:$dst), 0>;
3176 def : InstAlias<"ins\t{%dx, $dst|$dst, dx}", (INSW dstidx16:$dst), 0>;
3177 def : InstAlias<"ins\t{%dx, $dst|$dst, dx}", (INSL dstidx32:$dst), 0>;
3179 // outs aliases. Accept the mnemonic suffix being omitted because it's implicit
3181 def : InstAlias<"outs\t{$src, %dx|dx, $src}", (OUTSB srcidx8:$src), 0>;
3182 def : InstAlias<"outs\t{$src, %dx|dx, $src}", (OUTSW srcidx16:$src), 0>;
3183 def : InstAlias<"outs\t{$src, %dx|dx, $src}", (OUTSL srcidx32:$src), 0>;
3185 // inb %dx -> inb %al, %dx
3186 def : InstAlias<"inb\t{%dx|dx}", (IN8rr), 0>;
3187 def : InstAlias<"inw\t{%dx|dx}", (IN16rr), 0>;
3188 def : InstAlias<"inl\t{%dx|dx}", (IN32rr), 0>;
3189 def : InstAlias<"inb\t$port", (IN8ri u8imm:$port), 0>;
3190 def : InstAlias<"inw\t$port", (IN16ri u8imm:$port), 0>;
3191 def : InstAlias<"inl\t$port", (IN32ri u8imm:$port), 0>;
3194 // jmp and call aliases for lcall and ljmp. jmp $42,$5 -> ljmp
3195 def : InstAlias<"call\t$seg, $off", (FARCALL16i i16imm:$off, i16imm:$seg)>, Requires<[In16BitMode]>;
3196 def : InstAlias<"jmp\t$seg, $off", (FARJMP16i i16imm:$off, i16imm:$seg)>, Requires<[In16BitMode]>;
3197 def : InstAlias<"call\t$seg, $off", (FARCALL32i i32imm:$off, i16imm:$seg)>, Requires<[In32BitMode]>;
3198 def : InstAlias<"jmp\t$seg, $off", (FARJMP32i i32imm:$off, i16imm:$seg)>, Requires<[In32BitMode]>;
3199 def : InstAlias<"callw\t$seg, $off", (FARCALL16i i16imm:$off, i16imm:$seg)>, Requires<[Not64BitMode]>;
3200 def : InstAlias<"jmpw\t$seg, $off", (FARJMP16i i16imm:$off, i16imm:$seg)>, Requires<[Not64BitMode]>;
3201 def : InstAlias<"calll\t$seg, $off", (FARCALL32i i32imm:$off, i16imm:$seg)>, Requires<[Not64BitMode]>;
3202 def : InstAlias<"jmpl\t$seg, $off", (FARJMP32i i32imm:$off, i16imm:$seg)>, Requires<[Not64BitMode]>;
3204 // Force mov without a suffix with a segment and mem to prefer the 'l' form of
3205 // the move. All segment/mem forms are equivalent, this has the shortest
3207 def : InstAlias<"mov\t{$mem, $seg|$seg, $mem}", (MOV16sm SEGMENT_REG:$seg, i16mem:$mem), 0>;
3208 def : InstAlias<"mov\t{$seg, $mem|$mem, $seg}", (MOV16ms i16mem:$mem, SEGMENT_REG:$seg), 0>;
3210 // Match 'movq <largeimm>, <reg>' as an alias for movabsq.
3211 def : InstAlias<"mov{q}\t{$imm, $reg|$reg, $imm}", (MOV64ri GR64:$reg, i64imm:$imm), 0>;
3213 // Match 'movq GR64, MMX' as an alias for movd.
3214 def : InstAlias<"movq\t{$src, $dst|$dst, $src}",
3215 (MMX_MOVD64to64rr VR64:$dst, GR64:$src), 0>;
3216 def : InstAlias<"movq\t{$src, $dst|$dst, $src}",
3217 (MMX_MOVD64from64rr GR64:$dst, VR64:$src), 0>;
3220 def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX16rr8 GR16:$dst, GR8:$src), 0>;
3221 def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX16rm8 GR16:$dst, i8mem:$src), 0>;
3222 def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX32rr8 GR32:$dst, GR8:$src), 0>;
3223 def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX32rr16 GR32:$dst, GR16:$src), 0>;
3224 def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX64rr8 GR64:$dst, GR8:$src), 0>;
3225 def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX64rr16 GR64:$dst, GR16:$src), 0>;
3226 def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX64rr32 GR64:$dst, GR32:$src), 0>;
3229 def : InstAlias<"movzx\t{$src, $dst|$dst, $src}", (MOVZX16rr8 GR16:$dst, GR8:$src), 0>;
3230 def : InstAlias<"movzx\t{$src, $dst|$dst, $src}", (MOVZX16rm8 GR16:$dst, i8mem:$src), 0>;
3231 def : InstAlias<"movzx\t{$src, $dst|$dst, $src}", (MOVZX32rr8 GR32:$dst, GR8:$src), 0>;
3232 def : InstAlias<"movzx\t{$src, $dst|$dst, $src}", (MOVZX32rr16 GR32:$dst, GR16:$src), 0>;
3233 def : InstAlias<"movzx\t{$src, $dst|$dst, $src}", (MOVZX64rr8 GR64:$dst, GR8:$src), 0>;
3234 def : InstAlias<"movzx\t{$src, $dst|$dst, $src}", (MOVZX64rr16 GR64:$dst, GR16:$src), 0>;
3235 // Note: No GR32->GR64 movzx form.
3237 // outb %dx -> outb %al, %dx
3238 def : InstAlias<"outb\t{%dx|dx}", (OUT8rr), 0>;
3239 def : InstAlias<"outw\t{%dx|dx}", (OUT16rr), 0>;
3240 def : InstAlias<"outl\t{%dx|dx}", (OUT32rr), 0>;
3241 def : InstAlias<"outb\t$port", (OUT8ir u8imm:$port), 0>;
3242 def : InstAlias<"outw\t$port", (OUT16ir u8imm:$port), 0>;
3243 def : InstAlias<"outl\t$port", (OUT32ir u8imm:$port), 0>;
3245 // 'sldt <mem>' can be encoded with either sldtw or sldtq with the same
3246 // effect (both store to a 16-bit mem). Force to sldtw to avoid ambiguity
3247 // errors, since its encoding is the most compact.
3248 def : InstAlias<"sldt $mem", (SLDT16m i16mem:$mem), 0>;
3250 // shld/shrd op,op -> shld op, op, CL
3251 def : InstAlias<"shld{w}\t{$r2, $r1|$r1, $r2}", (SHLD16rrCL GR16:$r1, GR16:$r2), 0>;
3252 def : InstAlias<"shld{l}\t{$r2, $r1|$r1, $r2}", (SHLD32rrCL GR32:$r1, GR32:$r2), 0>;
3253 def : InstAlias<"shld{q}\t{$r2, $r1|$r1, $r2}", (SHLD64rrCL GR64:$r1, GR64:$r2), 0>;
3254 def : InstAlias<"shrd{w}\t{$r2, $r1|$r1, $r2}", (SHRD16rrCL GR16:$r1, GR16:$r2), 0>;
3255 def : InstAlias<"shrd{l}\t{$r2, $r1|$r1, $r2}", (SHRD32rrCL GR32:$r1, GR32:$r2), 0>;
3256 def : InstAlias<"shrd{q}\t{$r2, $r1|$r1, $r2}", (SHRD64rrCL GR64:$r1, GR64:$r2), 0>;
3258 def : InstAlias<"shld{w}\t{$reg, $mem|$mem, $reg}", (SHLD16mrCL i16mem:$mem, GR16:$reg), 0>;
3259 def : InstAlias<"shld{l}\t{$reg, $mem|$mem, $reg}", (SHLD32mrCL i32mem:$mem, GR32:$reg), 0>;
3260 def : InstAlias<"shld{q}\t{$reg, $mem|$mem, $reg}", (SHLD64mrCL i64mem:$mem, GR64:$reg), 0>;
3261 def : InstAlias<"shrd{w}\t{$reg, $mem|$mem, $reg}", (SHRD16mrCL i16mem:$mem, GR16:$reg), 0>;
3262 def : InstAlias<"shrd{l}\t{$reg, $mem|$mem, $reg}", (SHRD32mrCL i32mem:$mem, GR32:$reg), 0>;
3263 def : InstAlias<"shrd{q}\t{$reg, $mem|$mem, $reg}", (SHRD64mrCL i64mem:$mem, GR64:$reg), 0>;
3265 /* FIXME: This is disabled because the asm matcher is currently incapable of
3266 * matching a fixed immediate like $1.
3267 // "shl X, $1" is an alias for "shl X".
3268 multiclass ShiftRotateByOneAlias<string Mnemonic, string Opc> {
3269 def : InstAlias<!strconcat(Mnemonic, "b $op, $$1"),
3270 (!cast<Instruction>(!strconcat(Opc, "8r1")) GR8:$op)>;
3271 def : InstAlias<!strconcat(Mnemonic, "w $op, $$1"),
3272 (!cast<Instruction>(!strconcat(Opc, "16r1")) GR16:$op)>;
3273 def : InstAlias<!strconcat(Mnemonic, "l $op, $$1"),
3274 (!cast<Instruction>(!strconcat(Opc, "32r1")) GR32:$op)>;
3275 def : InstAlias<!strconcat(Mnemonic, "q $op, $$1"),
3276 (!cast<Instruction>(!strconcat(Opc, "64r1")) GR64:$op)>;
3277 def : InstAlias<!strconcat(Mnemonic, "b $op, $$1"),
3278 (!cast<Instruction>(!strconcat(Opc, "8m1")) i8mem:$op)>;
3279 def : InstAlias<!strconcat(Mnemonic, "w $op, $$1"),
3280 (!cast<Instruction>(!strconcat(Opc, "16m1")) i16mem:$op)>;
3281 def : InstAlias<!strconcat(Mnemonic, "l $op, $$1"),
3282 (!cast<Instruction>(!strconcat(Opc, "32m1")) i32mem:$op)>;
3283 def : InstAlias<!strconcat(Mnemonic, "q $op, $$1"),
3284 (!cast<Instruction>(!strconcat(Opc, "64m1")) i64mem:$op)>;
3287 defm : ShiftRotateByOneAlias<"rcl", "RCL">;
3288 defm : ShiftRotateByOneAlias<"rcr", "RCR">;
3289 defm : ShiftRotateByOneAlias<"rol", "ROL">;
3290 defm : ShiftRotateByOneAlias<"ror", "ROR">;
3293 // test: We accept "testX <reg>, <mem>" and "testX <mem>, <reg>" as synonyms.
3294 def : InstAlias<"test{b}\t{$mem, $val|$val, $mem}",
3295 (TEST8mr i8mem :$mem, GR8 :$val), 0>;
3296 def : InstAlias<"test{w}\t{$mem, $val|$val, $mem}",
3297 (TEST16mr i16mem:$mem, GR16:$val), 0>;
3298 def : InstAlias<"test{l}\t{$mem, $val|$val, $mem}",
3299 (TEST32mr i32mem:$mem, GR32:$val), 0>;
3300 def : InstAlias<"test{q}\t{$mem, $val|$val, $mem}",
3301 (TEST64mr i64mem:$mem, GR64:$val), 0>;
3303 // xchg: We accept "xchgX <reg>, <mem>" and "xchgX <mem>, <reg>" as synonyms.
3304 def : InstAlias<"xchg{b}\t{$mem, $val|$val, $mem}",
3305 (XCHG8rm GR8 :$val, i8mem :$mem), 0>;
3306 def : InstAlias<"xchg{w}\t{$mem, $val|$val, $mem}",
3307 (XCHG16rm GR16:$val, i16mem:$mem), 0>;
3308 def : InstAlias<"xchg{l}\t{$mem, $val|$val, $mem}",
3309 (XCHG32rm GR32:$val, i32mem:$mem), 0>;
3310 def : InstAlias<"xchg{q}\t{$mem, $val|$val, $mem}",
3311 (XCHG64rm GR64:$val, i64mem:$mem), 0>;
3313 // xchg: We accept "xchgX <reg>, %eax" and "xchgX %eax, <reg>" as synonyms.
3314 def : InstAlias<"xchg{w}\t{%ax, $src|$src, ax}", (XCHG16ar GR16:$src), 0>;
3315 def : InstAlias<"xchg{l}\t{%eax, $src|$src, eax}",
3316 (XCHG32ar GR32:$src), 0>, Requires<[Not64BitMode]>;
3317 def : InstAlias<"xchg{l}\t{%eax, $src|$src, eax}",
3318 (XCHG32ar64 GR32_NOAX:$src), 0>, Requires<[In64BitMode]>;
3319 def : InstAlias<"xchg{q}\t{%rax, $src|$src, rax}", (XCHG64ar GR64:$src), 0>;
3321 // These aliases exist to get the parser to prioritize matching 8-bit
3322 // immediate encodings over matching the implicit ax/eax/rax encodings. By
3323 // explicitly mentioning the A register here, these entries will be ordered
3324 // first due to the more explicit immediate type.
3325 def : InstAlias<"adc{w}\t{$imm, %ax|ax, $imm}", (ADC16ri8 AX, i16i8imm:$imm), 0>;
3326 def : InstAlias<"add{w}\t{$imm, %ax|ax, $imm}", (ADD16ri8 AX, i16i8imm:$imm), 0>;
3327 def : InstAlias<"and{w}\t{$imm, %ax|ax, $imm}", (AND16ri8 AX, i16i8imm:$imm), 0>;
3328 def : InstAlias<"cmp{w}\t{$imm, %ax|ax, $imm}", (CMP16ri8 AX, i16i8imm:$imm), 0>;
3329 def : InstAlias<"or{w}\t{$imm, %ax|ax, $imm}", (OR16ri8 AX, i16i8imm:$imm), 0>;
3330 def : InstAlias<"sbb{w}\t{$imm, %ax|ax, $imm}", (SBB16ri8 AX, i16i8imm:$imm), 0>;
3331 def : InstAlias<"sub{w}\t{$imm, %ax|ax, $imm}", (SUB16ri8 AX, i16i8imm:$imm), 0>;
3332 def : InstAlias<"xor{w}\t{$imm, %ax|ax, $imm}", (XOR16ri8 AX, i16i8imm:$imm), 0>;
3334 def : InstAlias<"adc{l}\t{$imm, %eax|eax, $imm}", (ADC32ri8 EAX, i32i8imm:$imm), 0>;
3335 def : InstAlias<"add{l}\t{$imm, %eax|eax, $imm}", (ADD32ri8 EAX, i32i8imm:$imm), 0>;
3336 def : InstAlias<"and{l}\t{$imm, %eax|eax, $imm}", (AND32ri8 EAX, i32i8imm:$imm), 0>;
3337 def : InstAlias<"cmp{l}\t{$imm, %eax|eax, $imm}", (CMP32ri8 EAX, i32i8imm:$imm), 0>;
3338 def : InstAlias<"or{l}\t{$imm, %eax|eax, $imm}", (OR32ri8 EAX, i32i8imm:$imm), 0>;
3339 def : InstAlias<"sbb{l}\t{$imm, %eax|eax, $imm}", (SBB32ri8 EAX, i32i8imm:$imm), 0>;
3340 def : InstAlias<"sub{l}\t{$imm, %eax|eax, $imm}", (SUB32ri8 EAX, i32i8imm:$imm), 0>;
3341 def : InstAlias<"xor{l}\t{$imm, %eax|eax, $imm}", (XOR32ri8 EAX, i32i8imm:$imm), 0>;
3343 def : InstAlias<"adc{q}\t{$imm, %rax|rax, $imm}", (ADC64ri8 RAX, i64i8imm:$imm), 0>;
3344 def : InstAlias<"add{q}\t{$imm, %rax|rax, $imm}", (ADD64ri8 RAX, i64i8imm:$imm), 0>;
3345 def : InstAlias<"and{q}\t{$imm, %rax|rax, $imm}", (AND64ri8 RAX, i64i8imm:$imm), 0>;
3346 def : InstAlias<"cmp{q}\t{$imm, %rax|rax, $imm}", (CMP64ri8 RAX, i64i8imm:$imm), 0>;
3347 def : InstAlias<"or{q}\t{$imm, %rax|rax, $imm}", (OR64ri8 RAX, i64i8imm:$imm), 0>;
3348 def : InstAlias<"sbb{q}\t{$imm, %rax|rax, $imm}", (SBB64ri8 RAX, i64i8imm:$imm), 0>;
3349 def : InstAlias<"sub{q}\t{$imm, %rax|rax, $imm}", (SUB64ri8 RAX, i64i8imm:$imm), 0>;
3350 def : InstAlias<"xor{q}\t{$imm, %rax|rax, $imm}", (XOR64ri8 RAX, i64i8imm:$imm), 0>;