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, DF], 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, DF], 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, DF], 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, DF], 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, DF], 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, DF], 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 let Defs = [EDI,ESI], Uses = [EDI,ESI,DF] in {
1386 def MOVSB : I<0xA4, RawFrmDstSrc, (outs), (ins dstidx8:$dst, srcidx8:$src),
1387 "movsb\t{$src, $dst|$dst, $src}", [], IIC_MOVS>;
1388 def MOVSW : I<0xA5, RawFrmDstSrc, (outs), (ins dstidx16:$dst, srcidx16:$src),
1389 "movsw\t{$src, $dst|$dst, $src}", [], IIC_MOVS>, OpSize16;
1390 def MOVSL : I<0xA5, RawFrmDstSrc, (outs), (ins dstidx32:$dst, srcidx32:$src),
1391 "movs{l|d}\t{$src, $dst|$dst, $src}", [], IIC_MOVS>, OpSize32;
1392 def MOVSQ : RI<0xA5, RawFrmDstSrc, (outs), (ins dstidx64:$dst, srcidx64:$src),
1393 "movsq\t{$src, $dst|$dst, $src}", [], IIC_MOVS>;
1396 let Defs = [EDI], Uses = [AL,EDI,DF] in
1397 def STOSB : I<0xAA, RawFrmDst, (outs), (ins dstidx8:$dst),
1398 "stosb\t{%al, $dst|$dst, al}", [], IIC_STOS>;
1399 let Defs = [EDI], Uses = [AX,EDI,DF] in
1400 def STOSW : I<0xAB, RawFrmDst, (outs), (ins dstidx16:$dst),
1401 "stosw\t{%ax, $dst|$dst, ax}", [], IIC_STOS>, OpSize16;
1402 let Defs = [EDI], Uses = [EAX,EDI,DF] in
1403 def STOSL : I<0xAB, RawFrmDst, (outs), (ins dstidx32:$dst),
1404 "stos{l|d}\t{%eax, $dst|$dst, eax}", [], IIC_STOS>, OpSize32;
1405 let Defs = [RDI], Uses = [RAX,RDI,DF] in
1406 def STOSQ : RI<0xAB, RawFrmDst, (outs), (ins dstidx64:$dst),
1407 "stosq\t{%rax, $dst|$dst, rax}", [], IIC_STOS>;
1409 let Defs = [EDI,EFLAGS], Uses = [AL,EDI,DF] in
1410 def SCASB : I<0xAE, RawFrmDst, (outs), (ins dstidx8:$dst),
1411 "scasb\t{$dst, %al|al, $dst}", [], IIC_SCAS>;
1412 let Defs = [EDI,EFLAGS], Uses = [AX,EDI,DF] in
1413 def SCASW : I<0xAF, RawFrmDst, (outs), (ins dstidx16:$dst),
1414 "scasw\t{$dst, %ax|ax, $dst}", [], IIC_SCAS>, OpSize16;
1415 let Defs = [EDI,EFLAGS], Uses = [EAX,EDI,DF] in
1416 def SCASL : I<0xAF, RawFrmDst, (outs), (ins dstidx32:$dst),
1417 "scas{l|d}\t{$dst, %eax|eax, $dst}", [], IIC_SCAS>, OpSize32;
1418 let Defs = [EDI,EFLAGS], Uses = [RAX,EDI,DF] in
1419 def SCASQ : RI<0xAF, RawFrmDst, (outs), (ins dstidx64:$dst),
1420 "scasq\t{$dst, %rax|rax, $dst}", [], IIC_SCAS>;
1422 let Defs = [EDI,ESI,EFLAGS], Uses = [EDI,ESI,DF] in {
1423 def CMPSB : I<0xA6, RawFrmDstSrc, (outs), (ins dstidx8:$dst, srcidx8:$src),
1424 "cmpsb\t{$dst, $src|$src, $dst}", [], IIC_CMPS>;
1425 def CMPSW : I<0xA7, RawFrmDstSrc, (outs), (ins dstidx16:$dst, srcidx16:$src),
1426 "cmpsw\t{$dst, $src|$src, $dst}", [], IIC_CMPS>, OpSize16;
1427 def CMPSL : I<0xA7, RawFrmDstSrc, (outs), (ins dstidx32:$dst, srcidx32:$src),
1428 "cmps{l|d}\t{$dst, $src|$src, $dst}", [], IIC_CMPS>, OpSize32;
1429 def CMPSQ : RI<0xA7, RawFrmDstSrc, (outs), (ins dstidx64:$dst, srcidx64:$src),
1430 "cmpsq\t{$dst, $src|$src, $dst}", [], IIC_CMPS>;
1434 //===----------------------------------------------------------------------===//
1435 // Move Instructions.
1437 let SchedRW = [WriteMove] in {
1438 let hasSideEffects = 0 in {
1439 def MOV8rr : I<0x88, MRMDestReg, (outs GR8 :$dst), (ins GR8 :$src),
1440 "mov{b}\t{$src, $dst|$dst, $src}", [], IIC_MOV>;
1441 def MOV16rr : I<0x89, MRMDestReg, (outs GR16:$dst), (ins GR16:$src),
1442 "mov{w}\t{$src, $dst|$dst, $src}", [], IIC_MOV>, OpSize16;
1443 def MOV32rr : I<0x89, MRMDestReg, (outs GR32:$dst), (ins GR32:$src),
1444 "mov{l}\t{$src, $dst|$dst, $src}", [], IIC_MOV>, OpSize32;
1445 def MOV64rr : RI<0x89, MRMDestReg, (outs GR64:$dst), (ins GR64:$src),
1446 "mov{q}\t{$src, $dst|$dst, $src}", [], IIC_MOV>;
1449 let isReMaterializable = 1, isAsCheapAsAMove = 1 in {
1450 def MOV8ri : Ii8 <0xB0, AddRegFrm, (outs GR8 :$dst), (ins i8imm :$src),
1451 "mov{b}\t{$src, $dst|$dst, $src}",
1452 [(set GR8:$dst, imm:$src)], IIC_MOV>;
1453 def MOV16ri : Ii16<0xB8, AddRegFrm, (outs GR16:$dst), (ins i16imm:$src),
1454 "mov{w}\t{$src, $dst|$dst, $src}",
1455 [(set GR16:$dst, imm:$src)], IIC_MOV>, OpSize16;
1456 def MOV32ri : Ii32<0xB8, AddRegFrm, (outs GR32:$dst), (ins i32imm:$src),
1457 "mov{l}\t{$src, $dst|$dst, $src}",
1458 [(set GR32:$dst, relocImm:$src)], IIC_MOV>, OpSize32;
1459 def MOV64ri32 : RIi32S<0xC7, MRM0r, (outs GR64:$dst), (ins i64i32imm:$src),
1460 "mov{q}\t{$src, $dst|$dst, $src}",
1461 [(set GR64:$dst, i64immSExt32:$src)], IIC_MOV>;
1463 let isReMaterializable = 1 in {
1464 def MOV64ri : RIi64<0xB8, AddRegFrm, (outs GR64:$dst), (ins i64imm:$src),
1465 "movabs{q}\t{$src, $dst|$dst, $src}",
1466 [(set GR64:$dst, relocImm:$src)], IIC_MOV>;
1469 // Longer forms that use a ModR/M byte. Needed for disassembler
1470 let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0 in {
1471 def MOV8ri_alt : Ii8 <0xC6, MRM0r, (outs GR8 :$dst), (ins i8imm :$src),
1472 "mov{b}\t{$src, $dst|$dst, $src}", [], IIC_MOV>,
1473 FoldGenData<"MOV8ri">;
1474 def MOV16ri_alt : Ii16<0xC7, MRM0r, (outs GR16:$dst), (ins i16imm:$src),
1475 "mov{w}\t{$src, $dst|$dst, $src}", [], IIC_MOV>, OpSize16,
1476 FoldGenData<"MOV16ri">;
1477 def MOV32ri_alt : Ii32<0xC7, MRM0r, (outs GR32:$dst), (ins i32imm:$src),
1478 "mov{l}\t{$src, $dst|$dst, $src}", [], IIC_MOV>, OpSize32,
1479 FoldGenData<"MOV32ri">;
1483 let SchedRW = [WriteStore] in {
1484 def MOV8mi : Ii8 <0xC6, MRM0m, (outs), (ins i8mem :$dst, i8imm :$src),
1485 "mov{b}\t{$src, $dst|$dst, $src}",
1486 [(store (i8 imm8_su:$src), addr:$dst)], IIC_MOV_MEM>;
1487 def MOV16mi : Ii16<0xC7, MRM0m, (outs), (ins i16mem:$dst, i16imm:$src),
1488 "mov{w}\t{$src, $dst|$dst, $src}",
1489 [(store (i16 imm16_su:$src), addr:$dst)], IIC_MOV_MEM>, OpSize16;
1490 def MOV32mi : Ii32<0xC7, MRM0m, (outs), (ins i32mem:$dst, i32imm:$src),
1491 "mov{l}\t{$src, $dst|$dst, $src}",
1492 [(store (i32 imm32_su:$src), addr:$dst)], IIC_MOV_MEM>, OpSize32;
1493 def MOV64mi32 : RIi32S<0xC7, MRM0m, (outs), (ins i64mem:$dst, i64i32imm:$src),
1494 "mov{q}\t{$src, $dst|$dst, $src}",
1495 [(store i64immSExt32_su:$src, addr:$dst)], IIC_MOV_MEM>,
1496 Requires<[In64BitMode]>;
1499 let hasSideEffects = 0 in {
1501 /// Memory offset versions of moves. The immediate is an address mode sized
1502 /// offset from the segment base.
1503 let SchedRW = [WriteALU] in {
1504 let mayLoad = 1 in {
1506 def MOV8ao32 : Ii32<0xA0, RawFrmMemOffs, (outs), (ins offset32_8:$src),
1507 "mov{b}\t{$src, %al|al, $src}", [], IIC_MOV_MEM>,
1510 def MOV16ao32 : Ii32<0xA1, RawFrmMemOffs, (outs), (ins offset32_16:$src),
1511 "mov{w}\t{$src, %ax|ax, $src}", [], IIC_MOV_MEM>,
1514 def MOV32ao32 : Ii32<0xA1, RawFrmMemOffs, (outs), (ins offset32_32:$src),
1515 "mov{l}\t{$src, %eax|eax, $src}", [], IIC_MOV_MEM>,
1518 def MOV64ao32 : RIi32<0xA1, RawFrmMemOffs, (outs), (ins offset32_64:$src),
1519 "mov{q}\t{$src, %rax|rax, $src}", [], IIC_MOV_MEM>,
1523 def MOV8ao16 : Ii16<0xA0, RawFrmMemOffs, (outs), (ins offset16_8:$src),
1524 "mov{b}\t{$src, %al|al, $src}", [], IIC_MOV_MEM>, AdSize16;
1526 def MOV16ao16 : Ii16<0xA1, RawFrmMemOffs, (outs), (ins offset16_16:$src),
1527 "mov{w}\t{$src, %ax|ax, $src}", [], IIC_MOV_MEM>,
1530 def MOV32ao16 : Ii16<0xA1, RawFrmMemOffs, (outs), (ins offset16_32:$src),
1531 "mov{l}\t{$src, %eax|eax, $src}", [], IIC_MOV_MEM>,
1534 let mayStore = 1 in {
1536 def MOV8o32a : Ii32<0xA2, RawFrmMemOffs, (outs), (ins offset32_8:$dst),
1537 "mov{b}\t{%al, $dst|$dst, al}", [], IIC_MOV_MEM>, AdSize32;
1539 def MOV16o32a : Ii32<0xA3, RawFrmMemOffs, (outs), (ins offset32_16:$dst),
1540 "mov{w}\t{%ax, $dst|$dst, ax}", [], IIC_MOV_MEM>,
1543 def MOV32o32a : Ii32<0xA3, RawFrmMemOffs, (outs), (ins offset32_32:$dst),
1544 "mov{l}\t{%eax, $dst|$dst, eax}", [], IIC_MOV_MEM>,
1547 def MOV64o32a : RIi32<0xA3, RawFrmMemOffs, (outs), (ins offset32_64:$dst),
1548 "mov{q}\t{%rax, $dst|$dst, rax}", [], IIC_MOV_MEM>,
1552 def MOV8o16a : Ii16<0xA2, RawFrmMemOffs, (outs), (ins offset16_8:$dst),
1553 "mov{b}\t{%al, $dst|$dst, al}", [], IIC_MOV_MEM>, AdSize16;
1555 def MOV16o16a : Ii16<0xA3, RawFrmMemOffs, (outs), (ins offset16_16:$dst),
1556 "mov{w}\t{%ax, $dst|$dst, ax}", [], IIC_MOV_MEM>,
1559 def MOV32o16a : Ii16<0xA3, RawFrmMemOffs, (outs), (ins offset16_32:$dst),
1560 "mov{l}\t{%eax, $dst|$dst, eax}", [], IIC_MOV_MEM>,
1565 // These forms all have full 64-bit absolute addresses in their instructions
1566 // and use the movabs mnemonic to indicate this specific form.
1567 let mayLoad = 1 in {
1569 def MOV8ao64 : RIi64_NOREX<0xA0, RawFrmMemOffs, (outs), (ins offset64_8:$src),
1570 "movabs{b}\t{$src, %al|al, $src}", [], IIC_MOV_MEM>,
1573 def MOV16ao64 : RIi64_NOREX<0xA1, RawFrmMemOffs, (outs), (ins offset64_16:$src),
1574 "movabs{w}\t{$src, %ax|ax, $src}", [], IIC_MOV_MEM>,
1577 def MOV32ao64 : RIi64_NOREX<0xA1, RawFrmMemOffs, (outs), (ins offset64_32:$src),
1578 "movabs{l}\t{$src, %eax|eax, $src}", [], IIC_MOV_MEM>,
1581 def MOV64ao64 : RIi64<0xA1, RawFrmMemOffs, (outs), (ins offset64_64:$src),
1582 "movabs{q}\t{$src, %rax|rax, $src}", [], IIC_MOV_MEM>,
1586 let mayStore = 1 in {
1588 def MOV8o64a : RIi64_NOREX<0xA2, RawFrmMemOffs, (outs), (ins offset64_8:$dst),
1589 "movabs{b}\t{%al, $dst|$dst, al}", [], IIC_MOV_MEM>,
1592 def MOV16o64a : RIi64_NOREX<0xA3, RawFrmMemOffs, (outs), (ins offset64_16:$dst),
1593 "movabs{w}\t{%ax, $dst|$dst, ax}", [], IIC_MOV_MEM>,
1596 def MOV32o64a : RIi64_NOREX<0xA3, RawFrmMemOffs, (outs), (ins offset64_32:$dst),
1597 "movabs{l}\t{%eax, $dst|$dst, eax}", [], IIC_MOV_MEM>,
1600 def MOV64o64a : RIi64<0xA3, RawFrmMemOffs, (outs), (ins offset64_64:$dst),
1601 "movabs{q}\t{%rax, $dst|$dst, rax}", [], IIC_MOV_MEM>,
1604 } // hasSideEffects = 0
1606 let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0,
1607 SchedRW = [WriteMove] in {
1608 def MOV8rr_REV : I<0x8A, MRMSrcReg, (outs GR8:$dst), (ins GR8:$src),
1609 "mov{b}\t{$src, $dst|$dst, $src}", [], IIC_MOV>,
1610 FoldGenData<"MOV8rr">;
1611 def MOV16rr_REV : I<0x8B, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
1612 "mov{w}\t{$src, $dst|$dst, $src}", [], IIC_MOV>, OpSize16,
1613 FoldGenData<"MOV16rr">;
1614 def MOV32rr_REV : I<0x8B, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
1615 "mov{l}\t{$src, $dst|$dst, $src}", [], IIC_MOV>, OpSize32,
1616 FoldGenData<"MOV32rr">;
1617 def MOV64rr_REV : RI<0x8B, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
1618 "mov{q}\t{$src, $dst|$dst, $src}", [], IIC_MOV>,
1619 FoldGenData<"MOV64rr">;
1622 let canFoldAsLoad = 1, isReMaterializable = 1, SchedRW = [WriteLoad] in {
1623 def MOV8rm : I<0x8A, MRMSrcMem, (outs GR8 :$dst), (ins i8mem :$src),
1624 "mov{b}\t{$src, $dst|$dst, $src}",
1625 [(set GR8:$dst, (loadi8 addr:$src))], IIC_MOV_MEM>;
1626 def MOV16rm : I<0x8B, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
1627 "mov{w}\t{$src, $dst|$dst, $src}",
1628 [(set GR16:$dst, (loadi16 addr:$src))], IIC_MOV_MEM>, OpSize16;
1629 def MOV32rm : I<0x8B, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
1630 "mov{l}\t{$src, $dst|$dst, $src}",
1631 [(set GR32:$dst, (loadi32 addr:$src))], IIC_MOV_MEM>, OpSize32;
1632 def MOV64rm : RI<0x8B, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
1633 "mov{q}\t{$src, $dst|$dst, $src}",
1634 [(set GR64:$dst, (load addr:$src))], IIC_MOV_MEM>;
1637 let SchedRW = [WriteStore] in {
1638 def MOV8mr : I<0x88, MRMDestMem, (outs), (ins i8mem :$dst, GR8 :$src),
1639 "mov{b}\t{$src, $dst|$dst, $src}",
1640 [(store GR8:$src, addr:$dst)], IIC_MOV_MEM>;
1641 def MOV16mr : I<0x89, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src),
1642 "mov{w}\t{$src, $dst|$dst, $src}",
1643 [(store GR16:$src, addr:$dst)], IIC_MOV_MEM>, OpSize16;
1644 def MOV32mr : I<0x89, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
1645 "mov{l}\t{$src, $dst|$dst, $src}",
1646 [(store GR32:$src, addr:$dst)], IIC_MOV_MEM>, OpSize32;
1647 def MOV64mr : RI<0x89, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
1648 "mov{q}\t{$src, $dst|$dst, $src}",
1649 [(store GR64:$src, addr:$dst)], IIC_MOV_MEM>;
1652 // Versions of MOV8rr, MOV8mr, and MOV8rm that use i8mem_NOREX and GR8_NOREX so
1653 // that they can be used for copying and storing h registers, which can't be
1654 // encoded when a REX prefix is present.
1655 let isCodeGenOnly = 1 in {
1656 let hasSideEffects = 0 in
1657 def MOV8rr_NOREX : I<0x88, MRMDestReg,
1658 (outs GR8_NOREX:$dst), (ins GR8_NOREX:$src),
1659 "mov{b}\t{$src, $dst|$dst, $src} # NOREX", [], IIC_MOV>,
1661 let mayStore = 1, hasSideEffects = 0 in
1662 def MOV8mr_NOREX : I<0x88, MRMDestMem,
1663 (outs), (ins i8mem_NOREX:$dst, GR8_NOREX:$src),
1664 "mov{b}\t{$src, $dst|$dst, $src} # NOREX", [],
1665 IIC_MOV_MEM>, Sched<[WriteStore]>;
1666 let mayLoad = 1, hasSideEffects = 0,
1667 canFoldAsLoad = 1, isReMaterializable = 1 in
1668 def MOV8rm_NOREX : I<0x8A, MRMSrcMem,
1669 (outs GR8_NOREX:$dst), (ins i8mem_NOREX:$src),
1670 "mov{b}\t{$src, $dst|$dst, $src} # NOREX", [],
1671 IIC_MOV_MEM>, Sched<[WriteLoad]>;
1675 // Condition code ops, incl. set if equal/not equal/...
1676 let SchedRW = [WriteALU] in {
1677 let Defs = [EFLAGS], Uses = [AH] in
1678 def SAHF : I<0x9E, RawFrm, (outs), (ins), "sahf",
1679 [(set EFLAGS, (X86sahf AH))], IIC_AHF>,
1680 Requires<[HasLAHFSAHF]>;
1681 let Defs = [AH], Uses = [EFLAGS], hasSideEffects = 0 in
1682 def LAHF : I<0x9F, RawFrm, (outs), (ins), "lahf", [],
1683 IIC_AHF>, // AH = flags
1684 Requires<[HasLAHFSAHF]>;
1687 //===----------------------------------------------------------------------===//
1688 // Bit tests instructions: BT, BTS, BTR, BTC.
1690 let Defs = [EFLAGS] in {
1691 let SchedRW = [WriteALU] in {
1692 def BT16rr : I<0xA3, MRMDestReg, (outs), (ins GR16:$src1, GR16:$src2),
1693 "bt{w}\t{$src2, $src1|$src1, $src2}",
1694 [(set EFLAGS, (X86bt GR16:$src1, GR16:$src2))], IIC_BT_RR>,
1695 OpSize16, TB, NotMemoryFoldable;
1696 def BT32rr : I<0xA3, MRMDestReg, (outs), (ins GR32:$src1, GR32:$src2),
1697 "bt{l}\t{$src2, $src1|$src1, $src2}",
1698 [(set EFLAGS, (X86bt GR32:$src1, GR32:$src2))], IIC_BT_RR>,
1699 OpSize32, TB, NotMemoryFoldable;
1700 def BT64rr : RI<0xA3, MRMDestReg, (outs), (ins GR64:$src1, GR64:$src2),
1701 "bt{q}\t{$src2, $src1|$src1, $src2}",
1702 [(set EFLAGS, (X86bt GR64:$src1, GR64:$src2))], IIC_BT_RR>, TB,
1706 // Unlike with the register+register form, the memory+register form of the
1707 // bt instruction does not ignore the high bits of the index. From ISel's
1708 // perspective, this is pretty bizarre. Make these instructions disassembly
1709 // only for now. These instructions are also slow on modern CPUs so that's
1710 // another reason to avoid generating them.
1712 let mayLoad = 1, hasSideEffects = 0, SchedRW = [WriteALULd] in {
1713 def BT16mr : I<0xA3, MRMDestMem, (outs), (ins i16mem:$src1, GR16:$src2),
1714 "bt{w}\t{$src2, $src1|$src1, $src2}",
1716 >, OpSize16, TB, NotMemoryFoldable;
1717 def BT32mr : I<0xA3, MRMDestMem, (outs), (ins i32mem:$src1, GR32:$src2),
1718 "bt{l}\t{$src2, $src1|$src1, $src2}",
1720 >, OpSize32, TB, NotMemoryFoldable;
1721 def BT64mr : RI<0xA3, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2),
1722 "bt{q}\t{$src2, $src1|$src1, $src2}",
1724 >, TB, NotMemoryFoldable;
1727 let SchedRW = [WriteALU] in {
1728 def BT16ri8 : Ii8<0xBA, MRM4r, (outs), (ins GR16:$src1, i16i8imm:$src2),
1729 "bt{w}\t{$src2, $src1|$src1, $src2}",
1730 [(set EFLAGS, (X86bt GR16:$src1, i16immSExt8:$src2))],
1731 IIC_BT_RI>, OpSize16, TB;
1732 def BT32ri8 : Ii8<0xBA, MRM4r, (outs), (ins GR32:$src1, i32i8imm:$src2),
1733 "bt{l}\t{$src2, $src1|$src1, $src2}",
1734 [(set EFLAGS, (X86bt GR32:$src1, i32immSExt8:$src2))],
1735 IIC_BT_RI>, OpSize32, TB;
1736 def BT64ri8 : RIi8<0xBA, MRM4r, (outs), (ins GR64:$src1, i64i8imm:$src2),
1737 "bt{q}\t{$src2, $src1|$src1, $src2}",
1738 [(set EFLAGS, (X86bt GR64:$src1, i64immSExt8:$src2))],
1742 // Note that these instructions aren't slow because that only applies when the
1743 // other operand is in a register. When it's an immediate, bt is still fast.
1744 let SchedRW = [WriteALU] in {
1745 def BT16mi8 : Ii8<0xBA, MRM4m, (outs), (ins i16mem:$src1, i16i8imm:$src2),
1746 "bt{w}\t{$src2, $src1|$src1, $src2}",
1747 [(set EFLAGS, (X86bt (loadi16 addr:$src1), i16immSExt8:$src2))
1748 ], IIC_BT_MI>, OpSize16, TB;
1749 def BT32mi8 : Ii8<0xBA, MRM4m, (outs), (ins i32mem:$src1, i32i8imm:$src2),
1750 "bt{l}\t{$src2, $src1|$src1, $src2}",
1751 [(set EFLAGS, (X86bt (loadi32 addr:$src1), i32immSExt8:$src2))
1752 ], IIC_BT_MI>, OpSize32, TB;
1753 def BT64mi8 : RIi8<0xBA, MRM4m, (outs), (ins i64mem:$src1, i64i8imm:$src2),
1754 "bt{q}\t{$src2, $src1|$src1, $src2}",
1755 [(set EFLAGS, (X86bt (loadi64 addr:$src1),
1756 i64immSExt8:$src2))], IIC_BT_MI>, TB,
1757 Requires<[In64BitMode]>;
1760 let hasSideEffects = 0 in {
1761 let SchedRW = [WriteALU], Constraints = "$src1 = $dst" in {
1762 def BTC16rr : I<0xBB, MRMDestReg, (outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
1763 "btc{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>,
1764 OpSize16, TB, NotMemoryFoldable;
1765 def BTC32rr : I<0xBB, MRMDestReg, (outs GR32:$dst), (ins GR32:$src1, GR32:$src2),
1766 "btc{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>,
1767 OpSize32, TB, NotMemoryFoldable;
1768 def BTC64rr : RI<0xBB, MRMDestReg, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
1769 "btc{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>, TB,
1773 let mayLoad = 1, mayStore = 1, SchedRW = [WriteALULd, WriteRMW] in {
1774 def BTC16mr : I<0xBB, MRMDestMem, (outs), (ins i16mem:$src1, GR16:$src2),
1775 "btc{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>,
1776 OpSize16, TB, NotMemoryFoldable;
1777 def BTC32mr : I<0xBB, MRMDestMem, (outs), (ins i32mem:$src1, GR32:$src2),
1778 "btc{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>,
1779 OpSize32, TB, NotMemoryFoldable;
1780 def BTC64mr : RI<0xBB, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2),
1781 "btc{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>, TB,
1785 let SchedRW = [WriteALU], Constraints = "$src1 = $dst" in {
1786 def BTC16ri8 : Ii8<0xBA, MRM7r, (outs GR16:$dst), (ins GR16:$src1, i16i8imm:$src2),
1787 "btc{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>,
1789 def BTC32ri8 : Ii8<0xBA, MRM7r, (outs GR32:$dst), (ins GR32:$src1, i32i8imm:$src2),
1790 "btc{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>,
1792 def BTC64ri8 : RIi8<0xBA, MRM7r, (outs GR64:$dst), (ins GR64:$src1, i64i8imm:$src2),
1793 "btc{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>, TB;
1796 let mayLoad = 1, mayStore = 1, SchedRW = [WriteALULd, WriteRMW] in {
1797 def BTC16mi8 : Ii8<0xBA, MRM7m, (outs), (ins i16mem:$src1, i16i8imm:$src2),
1798 "btc{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>,
1800 def BTC32mi8 : Ii8<0xBA, MRM7m, (outs), (ins i32mem:$src1, i32i8imm:$src2),
1801 "btc{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>,
1803 def BTC64mi8 : RIi8<0xBA, MRM7m, (outs), (ins i64mem:$src1, i64i8imm:$src2),
1804 "btc{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>, TB,
1805 Requires<[In64BitMode]>;
1808 let SchedRW = [WriteALU], Constraints = "$src1 = $dst" in {
1809 def BTR16rr : I<0xB3, MRMDestReg, (outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
1810 "btr{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>,
1811 OpSize16, TB, NotMemoryFoldable;
1812 def BTR32rr : I<0xB3, MRMDestReg, (outs GR32:$dst), (ins GR32:$src1, GR32:$src2),
1813 "btr{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>,
1814 OpSize32, TB, NotMemoryFoldable;
1815 def BTR64rr : RI<0xB3, MRMDestReg, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
1816 "btr{q}\t{$src2, $src1|$src1, $src2}", []>, TB, NotMemoryFoldable;
1819 let mayLoad = 1, mayStore = 1, SchedRW = [WriteALULd, WriteRMW] in {
1820 def BTR16mr : I<0xB3, MRMDestMem, (outs), (ins i16mem:$src1, GR16:$src2),
1821 "btr{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>,
1822 OpSize16, TB, NotMemoryFoldable;
1823 def BTR32mr : I<0xB3, MRMDestMem, (outs), (ins i32mem:$src1, GR32:$src2),
1824 "btr{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>,
1825 OpSize32, TB, NotMemoryFoldable;
1826 def BTR64mr : RI<0xB3, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2),
1827 "btr{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>, TB,
1831 let SchedRW = [WriteALU], Constraints = "$src1 = $dst" in {
1832 def BTR16ri8 : Ii8<0xBA, MRM6r, (outs GR16:$dst), (ins GR16:$src1, i16i8imm:$src2),
1833 "btr{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>,
1835 def BTR32ri8 : Ii8<0xBA, MRM6r, (outs GR32:$dst), (ins GR32:$src1, i32i8imm:$src2),
1836 "btr{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>,
1838 def BTR64ri8 : RIi8<0xBA, MRM6r, (outs GR64:$dst), (ins GR64:$src1, i64i8imm:$src2),
1839 "btr{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>, TB;
1842 let mayLoad = 1, mayStore = 1, SchedRW = [WriteALULd, WriteRMW] in {
1843 def BTR16mi8 : Ii8<0xBA, MRM6m, (outs), (ins i16mem:$src1, i16i8imm:$src2),
1844 "btr{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>,
1846 def BTR32mi8 : Ii8<0xBA, MRM6m, (outs), (ins i32mem:$src1, i32i8imm:$src2),
1847 "btr{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>,
1849 def BTR64mi8 : RIi8<0xBA, MRM6m, (outs), (ins i64mem:$src1, i64i8imm:$src2),
1850 "btr{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>, TB,
1851 Requires<[In64BitMode]>;
1854 let SchedRW = [WriteALU], Constraints = "$src1 = $dst" in {
1855 def BTS16rr : I<0xAB, MRMDestReg, (outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
1856 "bts{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>,
1857 OpSize16, TB, NotMemoryFoldable;
1858 def BTS32rr : I<0xAB, MRMDestReg, (outs GR32:$dst), (ins GR32:$src1, GR32:$src2),
1859 "bts{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>,
1860 OpSize32, TB, NotMemoryFoldable;
1861 def BTS64rr : RI<0xAB, MRMDestReg, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
1862 "bts{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>, TB,
1866 let mayLoad = 1, mayStore = 1, SchedRW = [WriteALULd, WriteRMW] in {
1867 def BTS16mr : I<0xAB, MRMDestMem, (outs), (ins i16mem:$src1, GR16:$src2),
1868 "bts{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>,
1869 OpSize16, TB, NotMemoryFoldable;
1870 def BTS32mr : I<0xAB, MRMDestMem, (outs), (ins i32mem:$src1, GR32:$src2),
1871 "bts{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>,
1872 OpSize32, TB, NotMemoryFoldable;
1873 def BTS64mr : RI<0xAB, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2),
1874 "bts{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>, TB,
1878 let SchedRW = [WriteALU], Constraints = "$src1 = $dst" in {
1879 def BTS16ri8 : Ii8<0xBA, MRM5r, (outs GR16:$dst), (ins GR16:$src1, i16i8imm:$src2),
1880 "bts{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>,
1882 def BTS32ri8 : Ii8<0xBA, MRM5r, (outs GR32:$dst), (ins GR32:$src1, i32i8imm:$src2),
1883 "bts{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>,
1885 def BTS64ri8 : RIi8<0xBA, MRM5r, (outs GR64:$dst), (ins GR64:$src1, i64i8imm:$src2),
1886 "bts{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>, TB;
1889 let mayLoad = 1, mayStore = 1, SchedRW = [WriteALULd, WriteRMW] in {
1890 def BTS16mi8 : Ii8<0xBA, MRM5m, (outs), (ins i16mem:$src1, i16i8imm:$src2),
1891 "bts{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>,
1893 def BTS32mi8 : Ii8<0xBA, MRM5m, (outs), (ins i32mem:$src1, i32i8imm:$src2),
1894 "bts{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>,
1896 def BTS64mi8 : RIi8<0xBA, MRM5m, (outs), (ins i64mem:$src1, i64i8imm:$src2),
1897 "bts{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>, TB,
1898 Requires<[In64BitMode]>;
1900 } // hasSideEffects = 0
1901 } // Defs = [EFLAGS]
1904 //===----------------------------------------------------------------------===//
1908 // Atomic swap. These are just normal xchg instructions. But since a memory
1909 // operand is referenced, the atomicity is ensured.
1910 multiclass ATOMIC_SWAP<bits<8> opc8, bits<8> opc, string mnemonic, string frag,
1911 InstrItinClass itin> {
1912 let Constraints = "$val = $dst", SchedRW = [WriteALULd, WriteRMW] in {
1913 def NAME#8rm : I<opc8, MRMSrcMem, (outs GR8:$dst),
1914 (ins GR8:$val, i8mem:$ptr),
1915 !strconcat(mnemonic, "{b}\t{$val, $ptr|$ptr, $val}"),
1918 (!cast<PatFrag>(frag # "_8") addr:$ptr, GR8:$val))],
1920 def NAME#16rm : I<opc, MRMSrcMem, (outs GR16:$dst),
1921 (ins GR16:$val, i16mem:$ptr),
1922 !strconcat(mnemonic, "{w}\t{$val, $ptr|$ptr, $val}"),
1925 (!cast<PatFrag>(frag # "_16") addr:$ptr, GR16:$val))],
1927 def NAME#32rm : I<opc, MRMSrcMem, (outs GR32:$dst),
1928 (ins GR32:$val, i32mem:$ptr),
1929 !strconcat(mnemonic, "{l}\t{$val, $ptr|$ptr, $val}"),
1932 (!cast<PatFrag>(frag # "_32") addr:$ptr, GR32:$val))],
1934 def NAME#64rm : RI<opc, MRMSrcMem, (outs GR64:$dst),
1935 (ins GR64:$val, i64mem:$ptr),
1936 !strconcat(mnemonic, "{q}\t{$val, $ptr|$ptr, $val}"),
1939 (!cast<PatFrag>(frag # "_64") addr:$ptr, GR64:$val))],
1944 defm XCHG : ATOMIC_SWAP<0x86, 0x87, "xchg", "atomic_swap", IIC_XCHG_MEM>;
1946 // Swap between registers.
1947 let SchedRW = [WriteALU] in {
1948 let Constraints = "$val = $dst" in {
1949 def XCHG8rr : I<0x86, MRMSrcReg, (outs GR8:$dst), (ins GR8:$val, GR8:$src),
1950 "xchg{b}\t{$val, $src|$src, $val}", [], IIC_XCHG_REG>;
1951 def XCHG16rr : I<0x87, MRMSrcReg, (outs GR16:$dst), (ins GR16:$val, GR16:$src),
1952 "xchg{w}\t{$val, $src|$src, $val}", [], IIC_XCHG_REG>,
1954 def XCHG32rr : I<0x87, MRMSrcReg, (outs GR32:$dst), (ins GR32:$val, GR32:$src),
1955 "xchg{l}\t{$val, $src|$src, $val}", [], IIC_XCHG_REG>,
1957 def XCHG64rr : RI<0x87, MRMSrcReg, (outs GR64:$dst), (ins GR64:$val,GR64:$src),
1958 "xchg{q}\t{$val, $src|$src, $val}", [], IIC_XCHG_REG>;
1961 // Swap between EAX and other registers.
1962 let Uses = [AX], Defs = [AX] in
1963 def XCHG16ar : I<0x90, AddRegFrm, (outs), (ins GR16:$src),
1964 "xchg{w}\t{$src, %ax|ax, $src}", [], IIC_XCHG_REG>, OpSize16;
1965 let Uses = [EAX], Defs = [EAX] in
1966 def XCHG32ar : I<0x90, AddRegFrm, (outs), (ins GR32:$src),
1967 "xchg{l}\t{$src, %eax|eax, $src}", [], IIC_XCHG_REG>,
1968 OpSize32, Requires<[Not64BitMode]>;
1969 let Uses = [EAX], Defs = [EAX] in
1970 // Uses GR32_NOAX in 64-bit mode to prevent encoding using the 0x90 NOP encoding.
1971 // xchg %eax, %eax needs to clear upper 32-bits of RAX so is not a NOP.
1972 def XCHG32ar64 : I<0x90, AddRegFrm, (outs), (ins GR32_NOAX:$src),
1973 "xchg{l}\t{$src, %eax|eax, $src}", [], IIC_XCHG_REG>,
1974 OpSize32, Requires<[In64BitMode]>;
1975 let Uses = [RAX], Defs = [RAX] in
1976 def XCHG64ar : RI<0x90, AddRegFrm, (outs), (ins GR64:$src),
1977 "xchg{q}\t{$src, %rax|rax, $src}", [], IIC_XCHG_REG>;
1980 let SchedRW = [WriteALU] in {
1981 def XADD8rr : I<0xC0, MRMDestReg, (outs GR8:$dst), (ins GR8:$src),
1982 "xadd{b}\t{$src, $dst|$dst, $src}", [], IIC_XADD_REG>, TB;
1983 def XADD16rr : I<0xC1, MRMDestReg, (outs GR16:$dst), (ins GR16:$src),
1984 "xadd{w}\t{$src, $dst|$dst, $src}", [], IIC_XADD_REG>, TB,
1986 def XADD32rr : I<0xC1, MRMDestReg, (outs GR32:$dst), (ins GR32:$src),
1987 "xadd{l}\t{$src, $dst|$dst, $src}", [], IIC_XADD_REG>, TB,
1989 def XADD64rr : RI<0xC1, MRMDestReg, (outs GR64:$dst), (ins GR64:$src),
1990 "xadd{q}\t{$src, $dst|$dst, $src}", [], IIC_XADD_REG>, TB;
1993 let mayLoad = 1, mayStore = 1, SchedRW = [WriteALULd, WriteRMW] in {
1994 def XADD8rm : I<0xC0, MRMDestMem, (outs), (ins i8mem:$dst, GR8:$src),
1995 "xadd{b}\t{$src, $dst|$dst, $src}", [], IIC_XADD_MEM>, TB;
1996 def XADD16rm : I<0xC1, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src),
1997 "xadd{w}\t{$src, $dst|$dst, $src}", [], IIC_XADD_MEM>, TB,
1999 def XADD32rm : I<0xC1, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
2000 "xadd{l}\t{$src, $dst|$dst, $src}", [], IIC_XADD_MEM>, TB,
2002 def XADD64rm : RI<0xC1, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
2003 "xadd{q}\t{$src, $dst|$dst, $src}", [], IIC_XADD_MEM>, TB;
2007 let SchedRW = [WriteALU] in {
2008 def CMPXCHG8rr : I<0xB0, MRMDestReg, (outs GR8:$dst), (ins GR8:$src),
2009 "cmpxchg{b}\t{$src, $dst|$dst, $src}", [],
2010 IIC_CMPXCHG_REG8>, TB;
2011 def CMPXCHG16rr : I<0xB1, MRMDestReg, (outs GR16:$dst), (ins GR16:$src),
2012 "cmpxchg{w}\t{$src, $dst|$dst, $src}", [],
2013 IIC_CMPXCHG_REG>, TB, OpSize16;
2014 def CMPXCHG32rr : I<0xB1, MRMDestReg, (outs GR32:$dst), (ins GR32:$src),
2015 "cmpxchg{l}\t{$src, $dst|$dst, $src}", [],
2016 IIC_CMPXCHG_REG>, TB, OpSize32;
2017 def CMPXCHG64rr : RI<0xB1, MRMDestReg, (outs GR64:$dst), (ins GR64:$src),
2018 "cmpxchg{q}\t{$src, $dst|$dst, $src}", [],
2019 IIC_CMPXCHG_REG>, TB;
2022 let SchedRW = [WriteALULd, WriteRMW] in {
2023 let mayLoad = 1, mayStore = 1 in {
2024 def CMPXCHG8rm : I<0xB0, MRMDestMem, (outs), (ins i8mem:$dst, GR8:$src),
2025 "cmpxchg{b}\t{$src, $dst|$dst, $src}", [],
2026 IIC_CMPXCHG_MEM8>, TB;
2027 def CMPXCHG16rm : I<0xB1, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src),
2028 "cmpxchg{w}\t{$src, $dst|$dst, $src}", [],
2029 IIC_CMPXCHG_MEM>, TB, OpSize16;
2030 def CMPXCHG32rm : I<0xB1, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
2031 "cmpxchg{l}\t{$src, $dst|$dst, $src}", [],
2032 IIC_CMPXCHG_MEM>, TB, OpSize32;
2033 def CMPXCHG64rm : RI<0xB1, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
2034 "cmpxchg{q}\t{$src, $dst|$dst, $src}", [],
2035 IIC_CMPXCHG_MEM>, TB;
2038 let Defs = [EAX, EDX, EFLAGS], Uses = [EAX, EBX, ECX, EDX] in
2039 def CMPXCHG8B : I<0xC7, MRM1m, (outs), (ins i64mem:$dst),
2040 "cmpxchg8b\t$dst", [], IIC_CMPXCHG_8B>, TB;
2042 let Defs = [RAX, RDX, EFLAGS], Uses = [RAX, RBX, RCX, RDX] in
2043 def CMPXCHG16B : RI<0xC7, MRM1m, (outs), (ins i128mem:$dst),
2044 "cmpxchg16b\t$dst", [], IIC_CMPXCHG_16B>,
2045 TB, Requires<[HasCmpxchg16b, In64BitMode]>;
2049 // Lock instruction prefix
2050 let SchedRW = [WriteMicrocoded] in
2051 def LOCK_PREFIX : I<0xF0, RawFrm, (outs), (ins), "lock", []>;
2053 let SchedRW = [WriteNop] in {
2055 // Rex64 instruction prefix
2056 def REX64_PREFIX : I<0x48, RawFrm, (outs), (ins), "rex64", [], IIC_NOP>,
2057 Requires<[In64BitMode]>;
2059 // Data16 instruction prefix
2060 def DATA16_PREFIX : I<0x66, RawFrm, (outs), (ins), "data16", [], IIC_NOP>,
2061 Requires<[Not16BitMode]>;
2063 // Data instruction prefix
2064 def DATA32_PREFIX : I<0x66, RawFrm, (outs), (ins), "data32", [], IIC_NOP>,
2065 Requires<[In16BitMode]>;
2068 // Repeat string operation instruction prefixes
2069 let Defs = [ECX], Uses = [ECX,DF], SchedRW = [WriteMicrocoded] in {
2070 // Repeat (used with INS, OUTS, MOVS, LODS and STOS)
2071 def REP_PREFIX : I<0xF3, RawFrm, (outs), (ins), "rep", []>;
2072 // Repeat while not equal (used with CMPS and SCAS)
2073 def REPNE_PREFIX : I<0xF2, RawFrm, (outs), (ins), "repne", []>;
2076 // String manipulation instructions
2077 let SchedRW = [WriteMicrocoded] in {
2078 let Defs = [AL,ESI], Uses = [ESI,DF] in
2079 def LODSB : I<0xAC, RawFrmSrc, (outs), (ins srcidx8:$src),
2080 "lodsb\t{$src, %al|al, $src}", [], IIC_LODS>;
2081 let Defs = [AX,ESI], Uses = [ESI,DF] in
2082 def LODSW : I<0xAD, RawFrmSrc, (outs), (ins srcidx16:$src),
2083 "lodsw\t{$src, %ax|ax, $src}", [], IIC_LODS>, OpSize16;
2084 let Defs = [EAX,ESI], Uses = [ESI,DF] in
2085 def LODSL : I<0xAD, RawFrmSrc, (outs), (ins srcidx32:$src),
2086 "lods{l|d}\t{$src, %eax|eax, $src}", [], IIC_LODS>, OpSize32;
2087 let Defs = [RAX,ESI], Uses = [ESI,DF] in
2088 def LODSQ : RI<0xAD, RawFrmSrc, (outs), (ins srcidx64:$src),
2089 "lodsq\t{$src, %rax|rax, $src}", [], IIC_LODS>;
2092 let SchedRW = [WriteSystem] in {
2093 let Defs = [ESI], Uses = [DX,ESI,DF] in {
2094 def OUTSB : I<0x6E, RawFrmSrc, (outs), (ins srcidx8:$src),
2095 "outsb\t{$src, %dx|dx, $src}", [], IIC_OUTS>;
2096 def OUTSW : I<0x6F, RawFrmSrc, (outs), (ins srcidx16:$src),
2097 "outsw\t{$src, %dx|dx, $src}", [], IIC_OUTS>, OpSize16;
2098 def OUTSL : I<0x6F, RawFrmSrc, (outs), (ins srcidx32:$src),
2099 "outs{l|d}\t{$src, %dx|dx, $src}", [], IIC_OUTS>, OpSize32;
2102 let Defs = [EDI], Uses = [DX,EDI,DF] in {
2103 def INSB : I<0x6C, RawFrmDst, (outs), (ins dstidx8:$dst),
2104 "insb\t{%dx, $dst|$dst, dx}", [], IIC_INS>;
2105 def INSW : I<0x6D, RawFrmDst, (outs), (ins dstidx16:$dst),
2106 "insw\t{%dx, $dst|$dst, dx}", [], IIC_INS>, OpSize16;
2107 def INSL : I<0x6D, RawFrmDst, (outs), (ins dstidx32:$dst),
2108 "ins{l|d}\t{%dx, $dst|$dst, dx}", [], IIC_INS>, OpSize32;
2112 // EFLAGS management instructions.
2113 let SchedRW = [WriteALU], Defs = [EFLAGS], Uses = [EFLAGS] in {
2114 def CLC : I<0xF8, RawFrm, (outs), (ins), "clc", [], IIC_CLC_CMC_STC>;
2115 def STC : I<0xF9, RawFrm, (outs), (ins), "stc", [], IIC_CLC_CMC_STC>;
2116 def CMC : I<0xF5, RawFrm, (outs), (ins), "cmc", [], IIC_CLC_CMC_STC>;
2119 // DF management instructions.
2120 // FIXME: These are a bit more expensive than CLC and STC. We should consider
2121 // adjusting their schedule bucket.
2122 let SchedRW = [WriteALU], Defs = [DF] in {
2123 def CLD : I<0xFC, RawFrm, (outs), (ins), "cld", [], IIC_CLD>;
2124 def STD : I<0xFD, RawFrm, (outs), (ins), "std", [], IIC_STD>;
2128 // Table lookup instructions
2129 let Uses = [AL,EBX], Defs = [AL], hasSideEffects = 0, mayLoad = 1 in
2130 def XLAT : I<0xD7, RawFrm, (outs), (ins), "xlatb", [], IIC_XLAT>,
2133 let SchedRW = [WriteMicrocoded] in {
2134 // ASCII Adjust After Addition
2135 let Uses = [AL,EFLAGS], Defs = [AX,EFLAGS], hasSideEffects = 0 in
2136 def AAA : I<0x37, RawFrm, (outs), (ins), "aaa", [], IIC_AAA>,
2137 Requires<[Not64BitMode]>;
2139 // ASCII Adjust AX Before Division
2140 let Uses = [AX], Defs = [AX,EFLAGS], hasSideEffects = 0 in
2141 def AAD8i8 : Ii8<0xD5, RawFrm, (outs), (ins i8imm:$src),
2142 "aad\t$src", [], IIC_AAD>, Requires<[Not64BitMode]>;
2144 // ASCII Adjust AX After Multiply
2145 let Uses = [AL], Defs = [AX,EFLAGS], hasSideEffects = 0 in
2146 def AAM8i8 : Ii8<0xD4, RawFrm, (outs), (ins i8imm:$src),
2147 "aam\t$src", [], IIC_AAM>, Requires<[Not64BitMode]>;
2149 // ASCII Adjust AL After Subtraction - sets
2150 let Uses = [AL,EFLAGS], Defs = [AX,EFLAGS], hasSideEffects = 0 in
2151 def AAS : I<0x3F, RawFrm, (outs), (ins), "aas", [], IIC_AAS>,
2152 Requires<[Not64BitMode]>;
2154 // Decimal Adjust AL after Addition
2155 let Uses = [AL,EFLAGS], Defs = [AL,EFLAGS], hasSideEffects = 0 in
2156 def DAA : I<0x27, RawFrm, (outs), (ins), "daa", [], IIC_DAA>,
2157 Requires<[Not64BitMode]>;
2159 // Decimal Adjust AL after Subtraction
2160 let Uses = [AL,EFLAGS], Defs = [AL,EFLAGS], hasSideEffects = 0 in
2161 def DAS : I<0x2F, RawFrm, (outs), (ins), "das", [], IIC_DAS>,
2162 Requires<[Not64BitMode]>;
2165 let SchedRW = [WriteSystem] in {
2166 // Check Array Index Against Bounds
2167 def BOUNDS16rm : I<0x62, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
2168 "bound\t{$src, $dst|$dst, $src}", [], IIC_BOUND>, OpSize16,
2169 Requires<[Not64BitMode]>;
2170 def BOUNDS32rm : I<0x62, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
2171 "bound\t{$src, $dst|$dst, $src}", [], IIC_BOUND>, OpSize32,
2172 Requires<[Not64BitMode]>;
2174 // Adjust RPL Field of Segment Selector
2175 def ARPL16rr : I<0x63, MRMDestReg, (outs GR16:$dst), (ins GR16:$src),
2176 "arpl\t{$src, $dst|$dst, $src}", [], IIC_ARPL_REG>,
2177 Requires<[Not64BitMode]>;
2179 def ARPL16mr : I<0x63, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src),
2180 "arpl\t{$src, $dst|$dst, $src}", [], IIC_ARPL_MEM>,
2181 Requires<[Not64BitMode]>;
2184 //===----------------------------------------------------------------------===//
2185 // MOVBE Instructions
2187 let Predicates = [HasMOVBE] in {
2188 let SchedRW = [WriteALULd] in {
2189 def MOVBE16rm : I<0xF0, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
2190 "movbe{w}\t{$src, $dst|$dst, $src}",
2191 [(set GR16:$dst, (bswap (loadi16 addr:$src)))], IIC_MOVBE>,
2193 def MOVBE32rm : I<0xF0, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
2194 "movbe{l}\t{$src, $dst|$dst, $src}",
2195 [(set GR32:$dst, (bswap (loadi32 addr:$src)))], IIC_MOVBE>,
2197 def MOVBE64rm : RI<0xF0, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
2198 "movbe{q}\t{$src, $dst|$dst, $src}",
2199 [(set GR64:$dst, (bswap (loadi64 addr:$src)))], IIC_MOVBE>,
2202 let SchedRW = [WriteStore] in {
2203 def MOVBE16mr : I<0xF1, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src),
2204 "movbe{w}\t{$src, $dst|$dst, $src}",
2205 [(store (bswap GR16:$src), addr:$dst)], IIC_MOVBE>,
2207 def MOVBE32mr : I<0xF1, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
2208 "movbe{l}\t{$src, $dst|$dst, $src}",
2209 [(store (bswap GR32:$src), addr:$dst)], IIC_MOVBE>,
2211 def MOVBE64mr : RI<0xF1, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
2212 "movbe{q}\t{$src, $dst|$dst, $src}",
2213 [(store (bswap GR64:$src), addr:$dst)], IIC_MOVBE>,
2218 //===----------------------------------------------------------------------===//
2219 // RDRAND Instruction
2221 let Predicates = [HasRDRAND], Defs = [EFLAGS], SchedRW = [WriteSystem] in {
2222 def RDRAND16r : I<0xC7, MRM6r, (outs GR16:$dst), (ins),
2224 [(set GR16:$dst, EFLAGS, (X86rdrand))], IIC_RDRAND>,
2226 def RDRAND32r : I<0xC7, MRM6r, (outs GR32:$dst), (ins),
2228 [(set GR32:$dst, EFLAGS, (X86rdrand))], IIC_RDRAND>,
2230 def RDRAND64r : RI<0xC7, MRM6r, (outs GR64:$dst), (ins),
2232 [(set GR64:$dst, EFLAGS, (X86rdrand))], IIC_RDRAND>, PS;
2235 //===----------------------------------------------------------------------===//
2236 // RDSEED Instruction
2238 let Predicates = [HasRDSEED], Defs = [EFLAGS], SchedRW = [WriteSystem] in {
2239 def RDSEED16r : I<0xC7, MRM7r, (outs GR16:$dst), (ins),
2241 [(set GR16:$dst, EFLAGS, (X86rdseed))], IIC_RDSEED>,
2243 def RDSEED32r : I<0xC7, MRM7r, (outs GR32:$dst), (ins),
2245 [(set GR32:$dst, EFLAGS, (X86rdseed))], IIC_RDSEED>,
2247 def RDSEED64r : RI<0xC7, MRM7r, (outs GR64:$dst), (ins),
2249 [(set GR64:$dst, EFLAGS, (X86rdseed))], IIC_RDSEED>, PS;
2252 //===----------------------------------------------------------------------===//
2253 // LZCNT Instruction
2255 let Predicates = [HasLZCNT], Defs = [EFLAGS] in {
2256 def LZCNT16rr : I<0xBD, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
2257 "lzcnt{w}\t{$src, $dst|$dst, $src}",
2258 [(set GR16:$dst, (ctlz GR16:$src)), (implicit EFLAGS)],
2259 IIC_LZCNT_RR>, XS, OpSize16, Sched<[WriteIMul]>;
2260 def LZCNT16rm : I<0xBD, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
2261 "lzcnt{w}\t{$src, $dst|$dst, $src}",
2262 [(set GR16:$dst, (ctlz (loadi16 addr:$src))),
2263 (implicit EFLAGS)], IIC_LZCNT_RM>, XS, OpSize16,
2264 Sched<[WriteIMulLd]>;
2266 def LZCNT32rr : I<0xBD, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
2267 "lzcnt{l}\t{$src, $dst|$dst, $src}",
2268 [(set GR32:$dst, (ctlz GR32:$src)), (implicit EFLAGS)],
2269 IIC_LZCNT_RR>, XS, OpSize32, Sched<[WriteIMul]>;
2270 def LZCNT32rm : I<0xBD, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
2271 "lzcnt{l}\t{$src, $dst|$dst, $src}",
2272 [(set GR32:$dst, (ctlz (loadi32 addr:$src))),
2273 (implicit EFLAGS)], IIC_LZCNT_RM>, XS, OpSize32,
2274 Sched<[WriteIMulLd]>;
2276 def LZCNT64rr : RI<0xBD, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
2277 "lzcnt{q}\t{$src, $dst|$dst, $src}",
2278 [(set GR64:$dst, (ctlz GR64:$src)), (implicit EFLAGS)],
2279 IIC_LZCNT_RR>, XS, Sched<[WriteIMul]>;
2280 def LZCNT64rm : RI<0xBD, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
2281 "lzcnt{q}\t{$src, $dst|$dst, $src}",
2282 [(set GR64:$dst, (ctlz (loadi64 addr:$src))),
2283 (implicit EFLAGS)], IIC_LZCNT_RM>, XS,
2284 Sched<[WriteIMulLd]>;
2287 //===----------------------------------------------------------------------===//
2290 let Predicates = [HasBMI], Defs = [EFLAGS] in {
2291 def TZCNT16rr : I<0xBC, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
2292 "tzcnt{w}\t{$src, $dst|$dst, $src}",
2293 [(set GR16:$dst, (cttz GR16:$src)), (implicit EFLAGS)],
2294 IIC_TZCNT_RR>, XS, OpSize16, Sched<[WriteIMul]>;
2295 def TZCNT16rm : I<0xBC, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
2296 "tzcnt{w}\t{$src, $dst|$dst, $src}",
2297 [(set GR16:$dst, (cttz (loadi16 addr:$src))),
2298 (implicit EFLAGS)], IIC_TZCNT_RM>, XS, OpSize16,
2299 Sched<[WriteIMulLd]>;
2301 def TZCNT32rr : I<0xBC, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
2302 "tzcnt{l}\t{$src, $dst|$dst, $src}",
2303 [(set GR32:$dst, (cttz GR32:$src)), (implicit EFLAGS)],
2304 IIC_TZCNT_RR>, XS, OpSize32, Sched<[WriteIMul]>;
2305 def TZCNT32rm : I<0xBC, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
2306 "tzcnt{l}\t{$src, $dst|$dst, $src}",
2307 [(set GR32:$dst, (cttz (loadi32 addr:$src))),
2308 (implicit EFLAGS)], IIC_TZCNT_RM>, XS, OpSize32,
2309 Sched<[WriteIMulLd]>;
2311 def TZCNT64rr : RI<0xBC, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
2312 "tzcnt{q}\t{$src, $dst|$dst, $src}",
2313 [(set GR64:$dst, (cttz GR64:$src)), (implicit EFLAGS)],
2314 IIC_TZCNT_RR>, XS, Sched<[WriteIMul]>;
2315 def TZCNT64rm : RI<0xBC, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
2316 "tzcnt{q}\t{$src, $dst|$dst, $src}",
2317 [(set GR64:$dst, (cttz (loadi64 addr:$src))),
2318 (implicit EFLAGS)], IIC_TZCNT_RM>, XS,
2319 Sched<[WriteIMulLd]>;
2322 multiclass bmi_bls<string mnemonic, Format RegMRM, Format MemMRM,
2323 RegisterClass RC, X86MemOperand x86memop> {
2324 let hasSideEffects = 0 in {
2325 def rr : I<0xF3, RegMRM, (outs RC:$dst), (ins RC:$src),
2326 !strconcat(mnemonic, "\t{$src, $dst|$dst, $src}"),
2327 [], IIC_UNARY_REG>, T8PS, VEX_4V, Sched<[WriteALU]>;
2329 def rm : I<0xF3, MemMRM, (outs RC:$dst), (ins x86memop:$src),
2330 !strconcat(mnemonic, "\t{$src, $dst|$dst, $src}"),
2331 [], IIC_UNARY_MEM>, T8PS, VEX_4V, Sched<[WriteALULd, ReadAfterLd]>;
2335 let Predicates = [HasBMI], Defs = [EFLAGS] in {
2336 defm BLSR32 : bmi_bls<"blsr{l}", MRM1r, MRM1m, GR32, i32mem>;
2337 defm BLSR64 : bmi_bls<"blsr{q}", MRM1r, MRM1m, GR64, i64mem>, VEX_W;
2338 defm BLSMSK32 : bmi_bls<"blsmsk{l}", MRM2r, MRM2m, GR32, i32mem>;
2339 defm BLSMSK64 : bmi_bls<"blsmsk{q}", MRM2r, MRM2m, GR64, i64mem>, VEX_W;
2340 defm BLSI32 : bmi_bls<"blsi{l}", MRM3r, MRM3m, GR32, i32mem>;
2341 defm BLSI64 : bmi_bls<"blsi{q}", MRM3r, MRM3m, GR64, i64mem>, VEX_W;
2344 //===----------------------------------------------------------------------===//
2345 // Pattern fragments to auto generate BMI instructions.
2346 //===----------------------------------------------------------------------===//
2348 let Predicates = [HasBMI] in {
2349 // FIXME: patterns for the load versions are not implemented
2350 def : Pat<(and GR32:$src, (add GR32:$src, -1)),
2351 (BLSR32rr GR32:$src)>;
2352 def : Pat<(and GR64:$src, (add GR64:$src, -1)),
2353 (BLSR64rr GR64:$src)>;
2355 def : Pat<(xor GR32:$src, (add GR32:$src, -1)),
2356 (BLSMSK32rr GR32:$src)>;
2357 def : Pat<(xor GR64:$src, (add GR64:$src, -1)),
2358 (BLSMSK64rr GR64:$src)>;
2360 def : Pat<(and GR32:$src, (ineg GR32:$src)),
2361 (BLSI32rr GR32:$src)>;
2362 def : Pat<(and GR64:$src, (ineg GR64:$src)),
2363 (BLSI64rr GR64:$src)>;
2366 multiclass bmi_bextr_bzhi<bits<8> opc, string mnemonic, RegisterClass RC,
2367 X86MemOperand x86memop, Intrinsic Int,
2369 def rr : I<opc, MRMSrcReg4VOp3, (outs RC:$dst), (ins RC:$src1, RC:$src2),
2370 !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2371 [(set RC:$dst, (Int RC:$src1, RC:$src2)), (implicit EFLAGS)], IIC_BIN_NONMEM>,
2372 T8PS, VEX, Sched<[WriteALU]>;
2373 def rm : I<opc, MRMSrcMem4VOp3, (outs RC:$dst), (ins x86memop:$src1, RC:$src2),
2374 !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2375 [(set RC:$dst, (Int (ld_frag addr:$src1), RC:$src2)),
2376 (implicit EFLAGS)], IIC_BIN_MEM>, T8PS, VEX,
2377 Sched<[WriteALULd, ReadAfterLd]>;
2380 let Predicates = [HasBMI], Defs = [EFLAGS] in {
2381 defm BEXTR32 : bmi_bextr_bzhi<0xF7, "bextr{l}", GR32, i32mem,
2382 int_x86_bmi_bextr_32, loadi32>;
2383 defm BEXTR64 : bmi_bextr_bzhi<0xF7, "bextr{q}", GR64, i64mem,
2384 int_x86_bmi_bextr_64, loadi64>, VEX_W;
2387 let Predicates = [HasBMI2], Defs = [EFLAGS] in {
2388 defm BZHI32 : bmi_bextr_bzhi<0xF5, "bzhi{l}", GR32, i32mem,
2389 int_x86_bmi_bzhi_32, loadi32>;
2390 defm BZHI64 : bmi_bextr_bzhi<0xF5, "bzhi{q}", GR64, i64mem,
2391 int_x86_bmi_bzhi_64, loadi64>, VEX_W;
2394 def CountTrailingOnes : SDNodeXForm<imm, [{
2395 // Count the trailing ones in the immediate.
2396 return getI8Imm(countTrailingOnes(N->getZExtValue()), SDLoc(N));
2399 def BEXTRMaskXForm : SDNodeXForm<imm, [{
2400 unsigned Length = countTrailingOnes(N->getZExtValue());
2401 return getI32Imm(Length << 8, SDLoc(N));
2404 def AndMask64 : ImmLeaf<i64, [{
2405 return isMask_64(Imm) && Imm > UINT32_MAX;
2408 // Use BEXTR for 64-bit 'and' with large immediate 'mask'.
2409 let Predicates = [HasBMI, NoBMI2, NoTBM] in {
2410 def : Pat<(and GR64:$src, AndMask64:$mask),
2411 (BEXTR64rr GR64:$src,
2412 (SUBREG_TO_REG (i64 0),
2413 (MOV32ri (BEXTRMaskXForm imm:$mask)), sub_32bit))>;
2414 def : Pat<(and (loadi64 addr:$src), AndMask64:$mask),
2415 (BEXTR64rm addr:$src,
2416 (SUBREG_TO_REG (i64 0),
2417 (MOV32ri (BEXTRMaskXForm imm:$mask)), sub_32bit))>;
2420 // Use BZHI for 64-bit 'and' with large immediate 'mask'.
2421 let Predicates = [HasBMI2, NoTBM] in {
2422 def : Pat<(and GR64:$src, AndMask64:$mask),
2423 (BZHI64rr GR64:$src,
2424 (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
2425 (MOV8ri (CountTrailingOnes imm:$mask)), sub_8bit))>;
2426 def : Pat<(and (loadi64 addr:$src), AndMask64:$mask),
2427 (BZHI64rm addr:$src,
2428 (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
2429 (MOV8ri (CountTrailingOnes imm:$mask)), sub_8bit))>;
2432 let Predicates = [HasBMI2] in {
2433 def : Pat<(and GR32:$src, (add (shl 1, GR8:$lz), -1)),
2434 (BZHI32rr GR32:$src,
2435 (INSERT_SUBREG (i32 (IMPLICIT_DEF)), GR8:$lz, sub_8bit))>;
2437 def : Pat<(and (loadi32 addr:$src), (add (shl 1, GR8:$lz), -1)),
2438 (BZHI32rm addr:$src,
2439 (INSERT_SUBREG (i32 (IMPLICIT_DEF)), GR8:$lz, sub_8bit))>;
2441 def : Pat<(and GR64:$src, (add (shl 1, GR8:$lz), -1)),
2442 (BZHI64rr GR64:$src,
2443 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR8:$lz, sub_8bit))>;
2445 def : Pat<(and (loadi64 addr:$src), (add (shl 1, GR8:$lz), -1)),
2446 (BZHI64rm addr:$src,
2447 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR8:$lz, sub_8bit))>;
2449 // x & (-1 >> (32 - y))
2450 def : Pat<(and GR32:$src, (srl -1, (i8 (trunc (sub 32, GR32:$lz))))),
2451 (BZHI32rr GR32:$src, GR32:$lz)>;
2452 def : Pat<(and (loadi32 addr:$src), (srl -1, (i8 (trunc (sub 32, GR32:$lz))))),
2453 (BZHI32rm addr:$src, GR32:$lz)>;
2455 // x & (-1 >> (64 - y))
2456 def : Pat<(and GR64:$src, (srl -1, (i8 (trunc (sub 64, GR32:$lz))))),
2457 (BZHI64rr GR64:$src,
2458 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR32:$lz, sub_32bit))>;
2459 def : Pat<(and (loadi64 addr:$src), (srl -1, (i8 (trunc (sub 64, GR32:$lz))))),
2460 (BZHI64rm addr:$src,
2461 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR32:$lz, sub_32bit))>;
2463 // x << (32 - y) >> (32 - y)
2464 def : Pat<(srl (shl GR32:$src, (i8 (trunc (sub 32, GR32:$lz)))),
2465 (i8 (trunc (sub 32, GR32:$lz)))),
2466 (BZHI32rr GR32:$src, GR32:$lz)>;
2467 def : Pat<(srl (shl (loadi32 addr:$src), (i8 (trunc (sub 32, GR32:$lz)))),
2468 (i8 (trunc (sub 32, GR32:$lz)))),
2469 (BZHI32rm addr:$src, GR32:$lz)>;
2471 // x << (64 - y) >> (64 - y)
2472 def : Pat<(srl (shl GR64:$src, (i8 (trunc (sub 64, GR32:$lz)))),
2473 (i8 (trunc (sub 64, GR32:$lz)))),
2474 (BZHI64rr GR64:$src,
2475 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR32:$lz, sub_32bit))>;
2476 def : Pat<(srl (shl (loadi64 addr:$src), (i8 (trunc (sub 64, GR32:$lz)))),
2477 (i8 (trunc (sub 64, GR32:$lz)))),
2478 (BZHI64rm addr:$src,
2479 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR32:$lz, sub_32bit))>;
2482 multiclass bmi_pdep_pext<string mnemonic, RegisterClass RC,
2483 X86MemOperand x86memop, Intrinsic Int,
2485 def rr : I<0xF5, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
2486 !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2487 [(set RC:$dst, (Int RC:$src1, RC:$src2))], IIC_BIN_NONMEM>,
2488 VEX_4V, Sched<[WriteALU]>;
2489 def rm : I<0xF5, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
2490 !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2491 [(set RC:$dst, (Int RC:$src1, (ld_frag addr:$src2)))],
2492 IIC_BIN_MEM>, VEX_4V, Sched<[WriteALULd, ReadAfterLd]>;
2495 let Predicates = [HasBMI2] in {
2496 defm PDEP32 : bmi_pdep_pext<"pdep{l}", GR32, i32mem,
2497 int_x86_bmi_pdep_32, loadi32>, T8XD;
2498 defm PDEP64 : bmi_pdep_pext<"pdep{q}", GR64, i64mem,
2499 int_x86_bmi_pdep_64, loadi64>, T8XD, VEX_W;
2500 defm PEXT32 : bmi_pdep_pext<"pext{l}", GR32, i32mem,
2501 int_x86_bmi_pext_32, loadi32>, T8XS;
2502 defm PEXT64 : bmi_pdep_pext<"pext{q}", GR64, i64mem,
2503 int_x86_bmi_pext_64, loadi64>, T8XS, VEX_W;
2506 //===----------------------------------------------------------------------===//
2509 let Predicates = [HasTBM], Defs = [EFLAGS] in {
2511 multiclass tbm_ternary_imm_intr<bits<8> opc, RegisterClass RC, string OpcodeStr,
2512 X86MemOperand x86memop, PatFrag ld_frag,
2513 Intrinsic Int, Operand immtype,
2514 SDPatternOperator immoperator> {
2515 def ri : Ii32<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, immtype:$cntl),
2516 !strconcat(OpcodeStr,
2517 "\t{$cntl, $src1, $dst|$dst, $src1, $cntl}"),
2518 [(set RC:$dst, (Int RC:$src1, immoperator:$cntl))],
2519 IIC_BIN_NONMEM>, XOP, XOPA, Sched<[WriteALU]>;
2520 def mi : Ii32<opc, MRMSrcMem, (outs RC:$dst),
2521 (ins x86memop:$src1, immtype:$cntl),
2522 !strconcat(OpcodeStr,
2523 "\t{$cntl, $src1, $dst|$dst, $src1, $cntl}"),
2524 [(set RC:$dst, (Int (ld_frag addr:$src1), immoperator:$cntl))],
2525 IIC_BIN_MEM>, XOP, XOPA, Sched<[WriteALULd, ReadAfterLd]>;
2528 defm BEXTRI32 : tbm_ternary_imm_intr<0x10, GR32, "bextr", i32mem, loadi32,
2529 int_x86_tbm_bextri_u32, i32imm, imm>;
2530 let ImmT = Imm32S in
2531 defm BEXTRI64 : tbm_ternary_imm_intr<0x10, GR64, "bextr", i64mem, loadi64,
2532 int_x86_tbm_bextri_u64, i64i32imm,
2533 i64immSExt32>, VEX_W;
2535 multiclass tbm_binary_rm<bits<8> opc, Format FormReg, Format FormMem,
2536 RegisterClass RC, string OpcodeStr,
2537 X86MemOperand x86memop, PatFrag ld_frag> {
2538 let hasSideEffects = 0 in {
2539 def rr : I<opc, FormReg, (outs RC:$dst), (ins RC:$src),
2540 !strconcat(OpcodeStr,"\t{$src, $dst|$dst, $src}"),
2541 [], IIC_BIN_NONMEM>, XOP_4V, XOP9, Sched<[WriteALU]>;
2543 def rm : I<opc, FormMem, (outs RC:$dst), (ins x86memop:$src),
2544 !strconcat(OpcodeStr,"\t{$src, $dst|$dst, $src}"),
2545 [], IIC_BIN_MEM>, XOP_4V, XOP9, Sched<[WriteALULd, ReadAfterLd]>;
2549 multiclass tbm_binary_intr<bits<8> opc, string OpcodeStr,
2550 Format FormReg, Format FormMem> {
2551 defm NAME#32 : tbm_binary_rm<opc, FormReg, FormMem, GR32, OpcodeStr, i32mem,
2553 defm NAME#64 : tbm_binary_rm<opc, FormReg, FormMem, GR64, OpcodeStr, i64mem,
2557 defm BLCFILL : tbm_binary_intr<0x01, "blcfill", MRM1r, MRM1m>;
2558 defm BLCI : tbm_binary_intr<0x02, "blci", MRM6r, MRM6m>;
2559 defm BLCIC : tbm_binary_intr<0x01, "blcic", MRM5r, MRM5m>;
2560 defm BLCMSK : tbm_binary_intr<0x02, "blcmsk", MRM1r, MRM1m>;
2561 defm BLCS : tbm_binary_intr<0x01, "blcs", MRM3r, MRM3m>;
2562 defm BLSFILL : tbm_binary_intr<0x01, "blsfill", MRM2r, MRM2m>;
2563 defm BLSIC : tbm_binary_intr<0x01, "blsic", MRM6r, MRM6m>;
2564 defm T1MSKC : tbm_binary_intr<0x01, "t1mskc", MRM7r, MRM7m>;
2565 defm TZMSK : tbm_binary_intr<0x01, "tzmsk", MRM4r, MRM4m>;
2568 // Use BEXTRI for 64-bit 'and' with large immediate 'mask'.
2569 let Predicates = [HasTBM] in {
2570 def : Pat<(and GR64:$src, AndMask64:$mask),
2571 (BEXTRI64ri GR64:$src, (BEXTRMaskXForm imm:$mask))>;
2573 def : Pat<(and (loadi64 addr:$src), AndMask64:$mask),
2574 (BEXTRI64mi addr:$src, (BEXTRMaskXForm imm:$mask))>;
2577 //===----------------------------------------------------------------------===//
2578 // Lightweight Profiling Instructions
2580 let Predicates = [HasLWP], SchedRW = [WriteSystem] in {
2582 def LLWPCB : I<0x12, MRM0r, (outs), (ins GR32:$src), "llwpcb\t$src",
2583 [(int_x86_llwpcb GR32:$src)], IIC_LWP>,
2585 def SLWPCB : I<0x12, MRM1r, (outs GR32:$dst), (ins), "slwpcb\t$dst",
2586 [(set GR32:$dst, (int_x86_slwpcb))], IIC_LWP>,
2589 def LLWPCB64 : I<0x12, MRM0r, (outs), (ins GR64:$src), "llwpcb\t$src",
2590 [(int_x86_llwpcb GR64:$src)], IIC_LWP>,
2592 def SLWPCB64 : I<0x12, MRM1r, (outs GR64:$dst), (ins), "slwpcb\t$dst",
2593 [(set GR64:$dst, (int_x86_slwpcb))], IIC_LWP>,
2596 multiclass lwpins_intr<RegisterClass RC> {
2597 def rri : Ii32<0x12, MRM0r, (outs), (ins RC:$src0, GR32:$src1, i32imm:$cntl),
2598 "lwpins\t{$cntl, $src1, $src0|$src0, $src1, $cntl}",
2599 [(set EFLAGS, (X86lwpins RC:$src0, GR32:$src1, imm:$cntl))], IIC_LWP>,
2602 def rmi : Ii32<0x12, MRM0m, (outs), (ins RC:$src0, i32mem:$src1, i32imm:$cntl),
2603 "lwpins\t{$cntl, $src1, $src0|$src0, $src1, $cntl}",
2604 [(set EFLAGS, (X86lwpins RC:$src0, (loadi32 addr:$src1), imm:$cntl))], IIC_LWP>,
2608 let Defs = [EFLAGS] in {
2609 defm LWPINS32 : lwpins_intr<GR32>;
2610 defm LWPINS64 : lwpins_intr<GR64>, VEX_W;
2613 multiclass lwpval_intr<RegisterClass RC, Intrinsic Int> {
2614 def rri : Ii32<0x12, MRM1r, (outs), (ins RC:$src0, GR32:$src1, i32imm:$cntl),
2615 "lwpval\t{$cntl, $src1, $src0|$src0, $src1, $cntl}",
2616 [(Int RC:$src0, GR32:$src1, imm:$cntl)], IIC_LWP>,
2619 def rmi : Ii32<0x12, MRM1m, (outs), (ins RC:$src0, i32mem:$src1, i32imm:$cntl),
2620 "lwpval\t{$cntl, $src1, $src0|$src0, $src1, $cntl}",
2621 [(Int RC:$src0, (loadi32 addr:$src1), imm:$cntl)], IIC_LWP>,
2625 defm LWPVAL32 : lwpval_intr<GR32, int_x86_lwpval32>;
2626 defm LWPVAL64 : lwpval_intr<GR64, int_x86_lwpval64>, VEX_W;
2628 } // HasLWP, SchedRW
2630 //===----------------------------------------------------------------------===//
2631 // MONITORX/MWAITX Instructions
2633 let SchedRW = [ WriteSystem ] in {
2634 let usesCustomInserter = 1 in {
2635 def MONITORX : PseudoI<(outs), (ins i32mem:$src1, GR32:$src2, GR32:$src3),
2636 [(int_x86_monitorx addr:$src1, GR32:$src2, GR32:$src3)]>,
2637 Requires<[ HasMWAITX ]>;
2640 let Uses = [ EAX, ECX, EDX ] in {
2641 def MONITORXrrr : I<0x01, MRM_FA, (outs), (ins), "monitorx", [], IIC_SSE_MONITORX>,
2642 TB, Requires<[ HasMWAITX ]>;
2645 let Uses = [ ECX, EAX, EBX ] in {
2646 def MWAITXrrr : I<0x01, MRM_FB, (outs), (ins), "mwaitx",
2647 [(int_x86_mwaitx ECX, EAX, EBX)], IIC_SSE_MWAITX>,
2648 TB, Requires<[ HasMWAITX ]>;
2652 def : InstAlias<"mwaitx\t{%eax, %ecx, %ebx|ebx, ecx, eax}", (MWAITXrrr)>,
2653 Requires<[ Not64BitMode ]>;
2654 def : InstAlias<"mwaitx\t{%rax, %rcx, %rbx|rbx, rcx, rax}", (MWAITXrrr)>,
2655 Requires<[ In64BitMode ]>;
2657 def : InstAlias<"monitorx\t{%eax, %ecx, %edx|edx, ecx, eax}", (MONITORXrrr)>,
2658 Requires<[ Not64BitMode ]>;
2659 def : InstAlias<"monitorx\t{%rax, %rcx, %rdx|rdx, rcx, rax}", (MONITORXrrr)>,
2660 Requires<[ In64BitMode ]>;
2662 //===----------------------------------------------------------------------===//
2663 // CLZERO Instruction
2665 let SchedRW = [WriteSystem] in {
2667 def CLZEROr : I<0x01, MRM_FC, (outs), (ins), "clzero", [], IIC_SSE_CLZERO>,
2668 TB, Requires<[HasCLZERO]>;
2670 let usesCustomInserter = 1 in {
2671 def CLZERO : PseudoI<(outs), (ins i32mem:$src1),
2672 [(int_x86_clzero addr:$src1)]>, Requires<[HasCLZERO]>;
2676 def : InstAlias<"clzero\t{%eax|eax}", (CLZEROr)>, Requires<[Not64BitMode]>;
2677 def : InstAlias<"clzero\t{%rax|rax}", (CLZEROr)>, Requires<[In64BitMode]>;
2679 //===----------------------------------------------------------------------===//
2680 // Pattern fragments to auto generate TBM instructions.
2681 //===----------------------------------------------------------------------===//
2683 let Predicates = [HasTBM] in {
2684 // FIXME: patterns for the load versions are not implemented
2685 def : Pat<(and GR32:$src, (add GR32:$src, 1)),
2686 (BLCFILL32rr GR32:$src)>;
2687 def : Pat<(and GR64:$src, (add GR64:$src, 1)),
2688 (BLCFILL64rr GR64:$src)>;
2690 def : Pat<(or GR32:$src, (not (add GR32:$src, 1))),
2691 (BLCI32rr GR32:$src)>;
2692 def : Pat<(or GR64:$src, (not (add GR64:$src, 1))),
2693 (BLCI64rr GR64:$src)>;
2695 // Extra patterns because opt can optimize the above patterns to this.
2696 def : Pat<(or GR32:$src, (sub -2, GR32:$src)),
2697 (BLCI32rr GR32:$src)>;
2698 def : Pat<(or GR64:$src, (sub -2, GR64:$src)),
2699 (BLCI64rr GR64:$src)>;
2701 def : Pat<(and (not GR32:$src), (add GR32:$src, 1)),
2702 (BLCIC32rr GR32:$src)>;
2703 def : Pat<(and (not GR64:$src), (add GR64:$src, 1)),
2704 (BLCIC64rr GR64:$src)>;
2706 def : Pat<(xor GR32:$src, (add GR32:$src, 1)),
2707 (BLCMSK32rr GR32:$src)>;
2708 def : Pat<(xor GR64:$src, (add GR64:$src, 1)),
2709 (BLCMSK64rr GR64:$src)>;
2711 def : Pat<(or GR32:$src, (add GR32:$src, 1)),
2712 (BLCS32rr GR32:$src)>;
2713 def : Pat<(or GR64:$src, (add GR64:$src, 1)),
2714 (BLCS64rr GR64:$src)>;
2716 def : Pat<(or GR32:$src, (add GR32:$src, -1)),
2717 (BLSFILL32rr GR32:$src)>;
2718 def : Pat<(or GR64:$src, (add GR64:$src, -1)),
2719 (BLSFILL64rr GR64:$src)>;
2721 def : Pat<(or (not GR32:$src), (add GR32:$src, -1)),
2722 (BLSIC32rr GR32:$src)>;
2723 def : Pat<(or (not GR64:$src), (add GR64:$src, -1)),
2724 (BLSIC64rr GR64:$src)>;
2726 def : Pat<(or (not GR32:$src), (add GR32:$src, 1)),
2727 (T1MSKC32rr GR32:$src)>;
2728 def : Pat<(or (not GR64:$src), (add GR64:$src, 1)),
2729 (T1MSKC64rr GR64:$src)>;
2731 def : Pat<(and (not GR32:$src), (add GR32:$src, -1)),
2732 (TZMSK32rr GR32:$src)>;
2733 def : Pat<(and (not GR64:$src), (add GR64:$src, -1)),
2734 (TZMSK64rr GR64:$src)>;
2737 //===----------------------------------------------------------------------===//
2738 // Memory Instructions
2741 let Predicates = [HasCLFLUSHOPT], SchedRW = [WriteLoad] in
2742 def CLFLUSHOPT : I<0xAE, MRM7m, (outs), (ins i8mem:$src),
2743 "clflushopt\t$src", [(int_x86_clflushopt addr:$src)],
2744 IIC_SSE_PREFETCH>, PD;
2746 let Predicates = [HasCLWB], SchedRW = [WriteLoad] in
2747 def CLWB : I<0xAE, MRM6m, (outs), (ins i8mem:$src), "clwb\t$src",
2748 [(int_x86_clwb addr:$src)], IIC_SSE_PREFETCH>, PD;
2750 //===----------------------------------------------------------------------===//
2752 //===----------------------------------------------------------------------===//
2754 include "X86InstrArithmetic.td"
2755 include "X86InstrCMovSetCC.td"
2756 include "X86InstrExtension.td"
2757 include "X86InstrControl.td"
2758 include "X86InstrShiftRotate.td"
2760 // X87 Floating Point Stack.
2761 include "X86InstrFPStack.td"
2763 // SIMD support (SSE, MMX and AVX)
2764 include "X86InstrFragmentsSIMD.td"
2766 // FMA - Fused Multiply-Add support (requires FMA)
2767 include "X86InstrFMA.td"
2770 include "X86InstrXOP.td"
2772 // SSE, MMX and 3DNow! vector support.
2773 include "X86InstrSSE.td"
2774 include "X86InstrAVX512.td"
2775 include "X86InstrMMX.td"
2776 include "X86Instr3DNow.td"
2779 include "X86InstrMPX.td"
2781 include "X86InstrVMX.td"
2782 include "X86InstrSVM.td"
2784 include "X86InstrTSX.td"
2785 include "X86InstrSGX.td"
2787 // System instructions.
2788 include "X86InstrSystem.td"
2790 // Compiler Pseudo Instructions and Pat Patterns
2791 include "X86InstrCompiler.td"
2792 include "X86InstrVecCompiler.td"
2794 //===----------------------------------------------------------------------===//
2795 // Assembler Mnemonic Aliases
2796 //===----------------------------------------------------------------------===//
2798 def : MnemonicAlias<"call", "callw", "att">, Requires<[In16BitMode]>;
2799 def : MnemonicAlias<"call", "calll", "att">, Requires<[In32BitMode]>;
2800 def : MnemonicAlias<"call", "callq", "att">, Requires<[In64BitMode]>;
2802 def : MnemonicAlias<"cbw", "cbtw", "att">;
2803 def : MnemonicAlias<"cwde", "cwtl", "att">;
2804 def : MnemonicAlias<"cwd", "cwtd", "att">;
2805 def : MnemonicAlias<"cdq", "cltd", "att">;
2806 def : MnemonicAlias<"cdqe", "cltq", "att">;
2807 def : MnemonicAlias<"cqo", "cqto", "att">;
2809 // In 64-bit mode lret maps to lretl; it is not ambiguous with lretq.
2810 def : MnemonicAlias<"lret", "lretw", "att">, Requires<[In16BitMode]>;
2811 def : MnemonicAlias<"lret", "lretl", "att">, Requires<[Not16BitMode]>;
2813 def : MnemonicAlias<"leavel", "leave", "att">, Requires<[Not64BitMode]>;
2814 def : MnemonicAlias<"leaveq", "leave", "att">, Requires<[In64BitMode]>;
2816 def : MnemonicAlias<"loopz", "loope">;
2817 def : MnemonicAlias<"loopnz", "loopne">;
2819 def : MnemonicAlias<"pop", "popw", "att">, Requires<[In16BitMode]>;
2820 def : MnemonicAlias<"pop", "popl", "att">, Requires<[In32BitMode]>;
2821 def : MnemonicAlias<"pop", "popq", "att">, Requires<[In64BitMode]>;
2822 def : MnemonicAlias<"popf", "popfw", "att">, Requires<[In16BitMode]>;
2823 def : MnemonicAlias<"popf", "popfl", "att">, Requires<[In32BitMode]>;
2824 def : MnemonicAlias<"popf", "popfq", "att">, Requires<[In64BitMode]>;
2825 def : MnemonicAlias<"popf", "popfq", "intel">, Requires<[In64BitMode]>;
2826 def : MnemonicAlias<"popfd", "popfl", "att">;
2828 // FIXME: This is wrong for "push reg". "push %bx" should turn into pushw in
2829 // all modes. However: "push (addr)" and "push $42" should default to
2830 // pushl/pushq depending on the current mode. Similar for "pop %bx"
2831 def : MnemonicAlias<"push", "pushw", "att">, Requires<[In16BitMode]>;
2832 def : MnemonicAlias<"push", "pushl", "att">, Requires<[In32BitMode]>;
2833 def : MnemonicAlias<"push", "pushq", "att">, Requires<[In64BitMode]>;
2834 def : MnemonicAlias<"pushf", "pushfw", "att">, Requires<[In16BitMode]>;
2835 def : MnemonicAlias<"pushf", "pushfl", "att">, Requires<[In32BitMode]>;
2836 def : MnemonicAlias<"pushf", "pushfq", "att">, Requires<[In64BitMode]>;
2837 def : MnemonicAlias<"pushf", "pushfq", "intel">, Requires<[In64BitMode]>;
2838 def : MnemonicAlias<"pushfd", "pushfl", "att">;
2840 def : MnemonicAlias<"popad", "popal", "intel">, Requires<[Not64BitMode]>;
2841 def : MnemonicAlias<"pushad", "pushal", "intel">, Requires<[Not64BitMode]>;
2842 def : MnemonicAlias<"popa", "popaw", "intel">, Requires<[In16BitMode]>;
2843 def : MnemonicAlias<"pusha", "pushaw", "intel">, Requires<[In16BitMode]>;
2844 def : MnemonicAlias<"popa", "popal", "intel">, Requires<[In32BitMode]>;
2845 def : MnemonicAlias<"pusha", "pushal", "intel">, Requires<[In32BitMode]>;
2847 def : MnemonicAlias<"popa", "popaw", "att">, Requires<[In16BitMode]>;
2848 def : MnemonicAlias<"pusha", "pushaw", "att">, Requires<[In16BitMode]>;
2849 def : MnemonicAlias<"popa", "popal", "att">, Requires<[In32BitMode]>;
2850 def : MnemonicAlias<"pusha", "pushal", "att">, Requires<[In32BitMode]>;
2852 def : MnemonicAlias<"repe", "rep">;
2853 def : MnemonicAlias<"repz", "rep">;
2854 def : MnemonicAlias<"repnz", "repne">;
2856 def : MnemonicAlias<"ret", "retw", "att">, Requires<[In16BitMode]>;
2857 def : MnemonicAlias<"ret", "retl", "att">, Requires<[In32BitMode]>;
2858 def : MnemonicAlias<"ret", "retq", "att">, Requires<[In64BitMode]>;
2860 // Apply 'ret' behavior to 'retn'
2861 def : MnemonicAlias<"retn", "retw", "att">, Requires<[In16BitMode]>;
2862 def : MnemonicAlias<"retn", "retl", "att">, Requires<[In32BitMode]>;
2863 def : MnemonicAlias<"retn", "retq", "att">, Requires<[In64BitMode]>;
2864 def : MnemonicAlias<"retn", "ret", "intel">;
2866 def : MnemonicAlias<"sal", "shl", "intel">;
2867 def : MnemonicAlias<"salb", "shlb", "att">;
2868 def : MnemonicAlias<"salw", "shlw", "att">;
2869 def : MnemonicAlias<"sall", "shll", "att">;
2870 def : MnemonicAlias<"salq", "shlq", "att">;
2872 def : MnemonicAlias<"smovb", "movsb", "att">;
2873 def : MnemonicAlias<"smovw", "movsw", "att">;
2874 def : MnemonicAlias<"smovl", "movsl", "att">;
2875 def : MnemonicAlias<"smovq", "movsq", "att">;
2877 def : MnemonicAlias<"ud2a", "ud2", "att">;
2878 def : MnemonicAlias<"verrw", "verr", "att">;
2880 // MS recognizes 'xacquire'/'xrelease' as 'acquire'/'release'
2881 def : MnemonicAlias<"acquire", "xacquire", "intel">;
2882 def : MnemonicAlias<"release", "xrelease", "intel">;
2884 // System instruction aliases.
2885 def : MnemonicAlias<"iret", "iretw", "att">, Requires<[In16BitMode]>;
2886 def : MnemonicAlias<"iret", "iretl", "att">, Requires<[Not16BitMode]>;
2887 def : MnemonicAlias<"sysret", "sysretl", "att">;
2888 def : MnemonicAlias<"sysexit", "sysexitl", "att">;
2890 def : MnemonicAlias<"lgdt", "lgdtw", "att">, Requires<[In16BitMode]>;
2891 def : MnemonicAlias<"lgdt", "lgdtl", "att">, Requires<[In32BitMode]>;
2892 def : MnemonicAlias<"lgdt", "lgdtq", "att">, Requires<[In64BitMode]>;
2893 def : MnemonicAlias<"lidt", "lidtw", "att">, Requires<[In16BitMode]>;
2894 def : MnemonicAlias<"lidt", "lidtl", "att">, Requires<[In32BitMode]>;
2895 def : MnemonicAlias<"lidt", "lidtq", "att">, Requires<[In64BitMode]>;
2896 def : MnemonicAlias<"sgdt", "sgdtw", "att">, Requires<[In16BitMode]>;
2897 def : MnemonicAlias<"sgdt", "sgdtl", "att">, Requires<[In32BitMode]>;
2898 def : MnemonicAlias<"sgdt", "sgdtq", "att">, Requires<[In64BitMode]>;
2899 def : MnemonicAlias<"sidt", "sidtw", "att">, Requires<[In16BitMode]>;
2900 def : MnemonicAlias<"sidt", "sidtl", "att">, Requires<[In32BitMode]>;
2901 def : MnemonicAlias<"sidt", "sidtq", "att">, Requires<[In64BitMode]>;
2904 // Floating point stack aliases.
2905 def : MnemonicAlias<"fcmovz", "fcmove", "att">;
2906 def : MnemonicAlias<"fcmova", "fcmovnbe", "att">;
2907 def : MnemonicAlias<"fcmovnae", "fcmovb", "att">;
2908 def : MnemonicAlias<"fcmovna", "fcmovbe", "att">;
2909 def : MnemonicAlias<"fcmovae", "fcmovnb", "att">;
2910 def : MnemonicAlias<"fcomip", "fcompi">;
2911 def : MnemonicAlias<"fildq", "fildll", "att">;
2912 def : MnemonicAlias<"fistpq", "fistpll", "att">;
2913 def : MnemonicAlias<"fisttpq", "fisttpll", "att">;
2914 def : MnemonicAlias<"fldcww", "fldcw", "att">;
2915 def : MnemonicAlias<"fnstcww", "fnstcw", "att">;
2916 def : MnemonicAlias<"fnstsww", "fnstsw", "att">;
2917 def : MnemonicAlias<"fucomip", "fucompi">;
2918 def : MnemonicAlias<"fwait", "wait">;
2920 def : MnemonicAlias<"fxsaveq", "fxsave64", "att">;
2921 def : MnemonicAlias<"fxrstorq", "fxrstor64", "att">;
2922 def : MnemonicAlias<"xsaveq", "xsave64", "att">;
2923 def : MnemonicAlias<"xrstorq", "xrstor64", "att">;
2924 def : MnemonicAlias<"xsaveoptq", "xsaveopt64", "att">;
2925 def : MnemonicAlias<"xrstorsq", "xrstors64", "att">;
2926 def : MnemonicAlias<"xsavecq", "xsavec64", "att">;
2927 def : MnemonicAlias<"xsavesq", "xsaves64", "att">;
2929 class CondCodeAlias<string Prefix,string Suffix, string OldCond, string NewCond,
2931 : MnemonicAlias<!strconcat(Prefix, OldCond, Suffix),
2932 !strconcat(Prefix, NewCond, Suffix), VariantName>;
2934 /// IntegerCondCodeMnemonicAlias - This multiclass defines a bunch of
2935 /// MnemonicAlias's that canonicalize the condition code in a mnemonic, for
2936 /// example "setz" -> "sete".
2937 multiclass IntegerCondCodeMnemonicAlias<string Prefix, string Suffix,
2939 def C : CondCodeAlias<Prefix, Suffix, "c", "b", V>; // setc -> setb
2940 def Z : CondCodeAlias<Prefix, Suffix, "z" , "e", V>; // setz -> sete
2941 def NA : CondCodeAlias<Prefix, Suffix, "na", "be", V>; // setna -> setbe
2942 def NB : CondCodeAlias<Prefix, Suffix, "nb", "ae", V>; // setnb -> setae
2943 def NC : CondCodeAlias<Prefix, Suffix, "nc", "ae", V>; // setnc -> setae
2944 def NG : CondCodeAlias<Prefix, Suffix, "ng", "le", V>; // setng -> setle
2945 def NL : CondCodeAlias<Prefix, Suffix, "nl", "ge", V>; // setnl -> setge
2946 def NZ : CondCodeAlias<Prefix, Suffix, "nz", "ne", V>; // setnz -> setne
2947 def PE : CondCodeAlias<Prefix, Suffix, "pe", "p", V>; // setpe -> setp
2948 def PO : CondCodeAlias<Prefix, Suffix, "po", "np", V>; // setpo -> setnp
2950 def NAE : CondCodeAlias<Prefix, Suffix, "nae", "b", V>; // setnae -> setb
2951 def NBE : CondCodeAlias<Prefix, Suffix, "nbe", "a", V>; // setnbe -> seta
2952 def NGE : CondCodeAlias<Prefix, Suffix, "nge", "l", V>; // setnge -> setl
2953 def NLE : CondCodeAlias<Prefix, Suffix, "nle", "g", V>; // setnle -> setg
2956 // Aliases for set<CC>
2957 defm : IntegerCondCodeMnemonicAlias<"set", "">;
2958 // Aliases for j<CC>
2959 defm : IntegerCondCodeMnemonicAlias<"j", "">;
2960 // Aliases for cmov<CC>{w,l,q}
2961 defm : IntegerCondCodeMnemonicAlias<"cmov", "w", "att">;
2962 defm : IntegerCondCodeMnemonicAlias<"cmov", "l", "att">;
2963 defm : IntegerCondCodeMnemonicAlias<"cmov", "q", "att">;
2964 // No size suffix for intel-style asm.
2965 defm : IntegerCondCodeMnemonicAlias<"cmov", "", "intel">;
2968 //===----------------------------------------------------------------------===//
2969 // Assembler Instruction Aliases
2970 //===----------------------------------------------------------------------===//
2972 // aad/aam default to base 10 if no operand is specified.
2973 def : InstAlias<"aad", (AAD8i8 10)>, Requires<[Not64BitMode]>;
2974 def : InstAlias<"aam", (AAM8i8 10)>, Requires<[Not64BitMode]>;
2976 // Disambiguate the mem/imm form of bt-without-a-suffix as btl.
2977 // Likewise for btc/btr/bts.
2978 def : InstAlias<"bt\t{$imm, $mem|$mem, $imm}",
2979 (BT32mi8 i32mem:$mem, i32i8imm:$imm), 0>;
2980 def : InstAlias<"btc\t{$imm, $mem|$mem, $imm}",
2981 (BTC32mi8 i32mem:$mem, i32i8imm:$imm), 0>;
2982 def : InstAlias<"btr\t{$imm, $mem|$mem, $imm}",
2983 (BTR32mi8 i32mem:$mem, i32i8imm:$imm), 0>;
2984 def : InstAlias<"bts\t{$imm, $mem|$mem, $imm}",
2985 (BTS32mi8 i32mem:$mem, i32i8imm:$imm), 0>;
2988 def : InstAlias<"clrb\t$reg", (XOR8rr GR8 :$reg, GR8 :$reg), 0>;
2989 def : InstAlias<"clrw\t$reg", (XOR16rr GR16:$reg, GR16:$reg), 0>;
2990 def : InstAlias<"clrl\t$reg", (XOR32rr GR32:$reg, GR32:$reg), 0>;
2991 def : InstAlias<"clrq\t$reg", (XOR64rr GR64:$reg, GR64:$reg), 0>;
2993 // lods aliases. Accept the destination being omitted because it's implicit
2994 // in the mnemonic, or the mnemonic suffix being omitted because it's implicit
2995 // in the destination.
2996 def : InstAlias<"lodsb\t$src", (LODSB srcidx8:$src), 0>;
2997 def : InstAlias<"lodsw\t$src", (LODSW srcidx16:$src), 0>;
2998 def : InstAlias<"lods{l|d}\t$src", (LODSL srcidx32:$src), 0>;
2999 def : InstAlias<"lodsq\t$src", (LODSQ srcidx64:$src), 0>, Requires<[In64BitMode]>;
3000 def : InstAlias<"lods\t{$src, %al|al, $src}", (LODSB srcidx8:$src), 0>;
3001 def : InstAlias<"lods\t{$src, %ax|ax, $src}", (LODSW srcidx16:$src), 0>;
3002 def : InstAlias<"lods\t{$src, %eax|eax, $src}", (LODSL srcidx32:$src), 0>;
3003 def : InstAlias<"lods\t{$src, %rax|rax, $src}", (LODSQ srcidx64:$src), 0>, Requires<[In64BitMode]>;
3004 def : InstAlias<"lods\t$src", (LODSB srcidx8:$src), 0>;
3005 def : InstAlias<"lods\t$src", (LODSW srcidx16:$src), 0>;
3006 def : InstAlias<"lods\t$src", (LODSL srcidx32:$src), 0>;
3007 def : InstAlias<"lods\t$src", (LODSQ srcidx64:$src), 0>, Requires<[In64BitMode]>;
3010 // stos aliases. Accept the source being omitted because it's implicit in
3011 // the mnemonic, or the mnemonic suffix being omitted because it's implicit
3013 def : InstAlias<"stosb\t$dst", (STOSB dstidx8:$dst), 0>;
3014 def : InstAlias<"stosw\t$dst", (STOSW dstidx16:$dst), 0>;
3015 def : InstAlias<"stos{l|d}\t$dst", (STOSL dstidx32:$dst), 0>;
3016 def : InstAlias<"stosq\t$dst", (STOSQ dstidx64:$dst), 0>, Requires<[In64BitMode]>;
3017 def : InstAlias<"stos\t{%al, $dst|$dst, al}", (STOSB dstidx8:$dst), 0>;
3018 def : InstAlias<"stos\t{%ax, $dst|$dst, ax}", (STOSW dstidx16:$dst), 0>;
3019 def : InstAlias<"stos\t{%eax, $dst|$dst, eax}", (STOSL dstidx32:$dst), 0>;
3020 def : InstAlias<"stos\t{%rax, $dst|$dst, rax}", (STOSQ dstidx64:$dst), 0>, Requires<[In64BitMode]>;
3021 def : InstAlias<"stos\t$dst", (STOSB dstidx8:$dst), 0>;
3022 def : InstAlias<"stos\t$dst", (STOSW dstidx16:$dst), 0>;
3023 def : InstAlias<"stos\t$dst", (STOSL dstidx32:$dst), 0>;
3024 def : InstAlias<"stos\t$dst", (STOSQ dstidx64:$dst), 0>, Requires<[In64BitMode]>;
3027 // scas aliases. Accept the destination being omitted because it's implicit
3028 // in the mnemonic, or the mnemonic suffix being omitted because it's implicit
3029 // in the destination.
3030 def : InstAlias<"scasb\t$dst", (SCASB dstidx8:$dst), 0>;
3031 def : InstAlias<"scasw\t$dst", (SCASW dstidx16:$dst), 0>;
3032 def : InstAlias<"scas{l|d}\t$dst", (SCASL dstidx32:$dst), 0>;
3033 def : InstAlias<"scasq\t$dst", (SCASQ dstidx64:$dst), 0>, Requires<[In64BitMode]>;
3034 def : InstAlias<"scas\t{$dst, %al|al, $dst}", (SCASB dstidx8:$dst), 0>;
3035 def : InstAlias<"scas\t{$dst, %ax|ax, $dst}", (SCASW dstidx16:$dst), 0>;
3036 def : InstAlias<"scas\t{$dst, %eax|eax, $dst}", (SCASL dstidx32:$dst), 0>;
3037 def : InstAlias<"scas\t{$dst, %rax|rax, $dst}", (SCASQ dstidx64:$dst), 0>, Requires<[In64BitMode]>;
3038 def : InstAlias<"scas\t$dst", (SCASB dstidx8:$dst), 0>;
3039 def : InstAlias<"scas\t$dst", (SCASW dstidx16:$dst), 0>;
3040 def : InstAlias<"scas\t$dst", (SCASL dstidx32:$dst), 0>;
3041 def : InstAlias<"scas\t$dst", (SCASQ dstidx64:$dst), 0>, Requires<[In64BitMode]>;
3043 // cmps aliases. Mnemonic suffix being omitted because it's implicit
3044 // in the destination.
3045 def : InstAlias<"cmps\t{$dst, $src|$src, $dst}", (CMPSB dstidx8:$dst, srcidx8:$src), 0>;
3046 def : InstAlias<"cmps\t{$dst, $src|$src, $dst}", (CMPSW dstidx16:$dst, srcidx16:$src), 0>;
3047 def : InstAlias<"cmps\t{$dst, $src|$src, $dst}", (CMPSL dstidx32:$dst, srcidx32:$src), 0>;
3048 def : InstAlias<"cmps\t{$dst, $src|$src, $dst}", (CMPSQ dstidx64:$dst, srcidx64:$src), 0>, Requires<[In64BitMode]>;
3050 // movs aliases. Mnemonic suffix being omitted because it's implicit
3051 // in the destination.
3052 def : InstAlias<"movs\t{$src, $dst|$dst, $src}", (MOVSB dstidx8:$dst, srcidx8:$src), 0>;
3053 def : InstAlias<"movs\t{$src, $dst|$dst, $src}", (MOVSW dstidx16:$dst, srcidx16:$src), 0>;
3054 def : InstAlias<"movs\t{$src, $dst|$dst, $src}", (MOVSL dstidx32:$dst, srcidx32:$src), 0>;
3055 def : InstAlias<"movs\t{$src, $dst|$dst, $src}", (MOVSQ dstidx64:$dst, srcidx64:$src), 0>, Requires<[In64BitMode]>;
3057 // div and idiv aliases for explicit A register.
3058 def : InstAlias<"div{b}\t{$src, %al|al, $src}", (DIV8r GR8 :$src)>;
3059 def : InstAlias<"div{w}\t{$src, %ax|ax, $src}", (DIV16r GR16:$src)>;
3060 def : InstAlias<"div{l}\t{$src, %eax|eax, $src}", (DIV32r GR32:$src)>;
3061 def : InstAlias<"div{q}\t{$src, %rax|rax, $src}", (DIV64r GR64:$src)>;
3062 def : InstAlias<"div{b}\t{$src, %al|al, $src}", (DIV8m i8mem :$src)>;
3063 def : InstAlias<"div{w}\t{$src, %ax|ax, $src}", (DIV16m i16mem:$src)>;
3064 def : InstAlias<"div{l}\t{$src, %eax|eax, $src}", (DIV32m i32mem:$src)>;
3065 def : InstAlias<"div{q}\t{$src, %rax|rax, $src}", (DIV64m i64mem:$src)>;
3066 def : InstAlias<"idiv{b}\t{$src, %al|al, $src}", (IDIV8r GR8 :$src)>;
3067 def : InstAlias<"idiv{w}\t{$src, %ax|ax, $src}", (IDIV16r GR16:$src)>;
3068 def : InstAlias<"idiv{l}\t{$src, %eax|eax, $src}", (IDIV32r GR32:$src)>;
3069 def : InstAlias<"idiv{q}\t{$src, %rax|rax, $src}", (IDIV64r GR64:$src)>;
3070 def : InstAlias<"idiv{b}\t{$src, %al|al, $src}", (IDIV8m i8mem :$src)>;
3071 def : InstAlias<"idiv{w}\t{$src, %ax|ax, $src}", (IDIV16m i16mem:$src)>;
3072 def : InstAlias<"idiv{l}\t{$src, %eax|eax, $src}", (IDIV32m i32mem:$src)>;
3073 def : InstAlias<"idiv{q}\t{$src, %rax|rax, $src}", (IDIV64m i64mem:$src)>;
3077 // Various unary fpstack operations default to operating on on ST1.
3078 // For example, "fxch" -> "fxch %st(1)"
3079 def : InstAlias<"faddp", (ADD_FPrST0 ST1), 0>;
3080 def: InstAlias<"fadd", (ADD_FPrST0 ST1), 0>;
3081 def : InstAlias<"fsub{|r}p", (SUBR_FPrST0 ST1), 0>;
3082 def : InstAlias<"fsub{r|}p", (SUB_FPrST0 ST1), 0>;
3083 def : InstAlias<"fmul", (MUL_FPrST0 ST1), 0>;
3084 def : InstAlias<"fmulp", (MUL_FPrST0 ST1), 0>;
3085 def : InstAlias<"fdiv{|r}p", (DIVR_FPrST0 ST1), 0>;
3086 def : InstAlias<"fdiv{r|}p", (DIV_FPrST0 ST1), 0>;
3087 def : InstAlias<"fxch", (XCH_F ST1), 0>;
3088 def : InstAlias<"fcom", (COM_FST0r ST1), 0>;
3089 def : InstAlias<"fcomp", (COMP_FST0r ST1), 0>;
3090 def : InstAlias<"fcomi", (COM_FIr ST1), 0>;
3091 def : InstAlias<"fcompi", (COM_FIPr ST1), 0>;
3092 def : InstAlias<"fucom", (UCOM_Fr ST1), 0>;
3093 def : InstAlias<"fucomp", (UCOM_FPr ST1), 0>;
3094 def : InstAlias<"fucomi", (UCOM_FIr ST1), 0>;
3095 def : InstAlias<"fucompi", (UCOM_FIPr ST1), 0>;
3097 // Handle fmul/fadd/fsub/fdiv instructions with explicitly written st(0) op.
3098 // For example, "fadd %st(4), %st(0)" -> "fadd %st(4)". We also disambiguate
3099 // instructions like "fadd %st(0), %st(0)" as "fadd %st(0)" for consistency with
3101 multiclass FpUnaryAlias<string Mnemonic, Instruction Inst, bit EmitAlias = 1> {
3102 def : InstAlias<!strconcat(Mnemonic, "\t{$op, %st(0)|st(0), $op}"),
3103 (Inst RST:$op), EmitAlias>;
3104 def : InstAlias<!strconcat(Mnemonic, "\t{%st(0), %st(0)|st(0), st(0)}"),
3105 (Inst ST0), EmitAlias>;
3108 defm : FpUnaryAlias<"fadd", ADD_FST0r>;
3109 defm : FpUnaryAlias<"faddp", ADD_FPrST0, 0>;
3110 defm : FpUnaryAlias<"fsub", SUB_FST0r>;
3111 defm : FpUnaryAlias<"fsub{|r}p", SUBR_FPrST0>;
3112 defm : FpUnaryAlias<"fsubr", SUBR_FST0r>;
3113 defm : FpUnaryAlias<"fsub{r|}p", SUB_FPrST0>;
3114 defm : FpUnaryAlias<"fmul", MUL_FST0r>;
3115 defm : FpUnaryAlias<"fmulp", MUL_FPrST0>;
3116 defm : FpUnaryAlias<"fdiv", DIV_FST0r>;
3117 defm : FpUnaryAlias<"fdiv{|r}p", DIVR_FPrST0>;
3118 defm : FpUnaryAlias<"fdivr", DIVR_FST0r>;
3119 defm : FpUnaryAlias<"fdiv{r|}p", DIV_FPrST0>;
3120 defm : FpUnaryAlias<"fcomi", COM_FIr, 0>;
3121 defm : FpUnaryAlias<"fucomi", UCOM_FIr, 0>;
3122 defm : FpUnaryAlias<"fcompi", COM_FIPr>;
3123 defm : FpUnaryAlias<"fucompi", UCOM_FIPr>;
3126 // Handle "f{mulp,addp} st(0), $op" the same as "f{mulp,addp} $op", since they
3127 // commute. We also allow fdiv[r]p/fsubrp even though they don't commute,
3128 // solely because gas supports it.
3129 def : InstAlias<"faddp\t{%st(0), $op|$op, st(0)}", (ADD_FPrST0 RST:$op), 0>;
3130 def : InstAlias<"fmulp\t{%st(0), $op|$op, st(0)}", (MUL_FPrST0 RST:$op)>;
3131 def : InstAlias<"fsub{|r}p\t{%st(0), $op|$op, st(0)}", (SUBR_FPrST0 RST:$op)>;
3132 def : InstAlias<"fsub{r|}p\t{%st(0), $op|$op, st(0)}", (SUB_FPrST0 RST:$op)>;
3133 def : InstAlias<"fdiv{|r}p\t{%st(0), $op|$op, st(0)}", (DIVR_FPrST0 RST:$op)>;
3134 def : InstAlias<"fdiv{r|}p\t{%st(0), $op|$op, st(0)}", (DIV_FPrST0 RST:$op)>;
3136 // We accept "fnstsw %eax" even though it only writes %ax.
3137 def : InstAlias<"fnstsw\t{%eax|eax}", (FNSTSW16r)>;
3138 def : InstAlias<"fnstsw\t{%al|al}" , (FNSTSW16r)>;
3139 def : InstAlias<"fnstsw" , (FNSTSW16r)>;
3141 // lcall and ljmp aliases. This seems to be an odd mapping in 64-bit mode, but
3142 // this is compatible with what GAS does.
3143 def : InstAlias<"lcall\t$seg, $off", (FARCALL32i i32imm:$off, i16imm:$seg), 0>, Requires<[In32BitMode]>;
3144 def : InstAlias<"ljmp\t$seg, $off", (FARJMP32i i32imm:$off, i16imm:$seg), 0>, Requires<[In32BitMode]>;
3145 def : InstAlias<"lcall\t{*}$dst", (FARCALL32m opaque48mem:$dst), 0>, Requires<[Not16BitMode]>;
3146 def : InstAlias<"ljmp\t{*}$dst", (FARJMP32m opaque48mem:$dst), 0>, Requires<[Not16BitMode]>;
3147 def : InstAlias<"lcall\t$seg, $off", (FARCALL16i i16imm:$off, i16imm:$seg), 0>, Requires<[In16BitMode]>;
3148 def : InstAlias<"ljmp\t$seg, $off", (FARJMP16i i16imm:$off, i16imm:$seg), 0>, Requires<[In16BitMode]>;
3149 def : InstAlias<"lcall\t{*}$dst", (FARCALL16m opaque32mem:$dst), 0>, Requires<[In16BitMode]>;
3150 def : InstAlias<"ljmp\t{*}$dst", (FARJMP16m opaque32mem:$dst), 0>, Requires<[In16BitMode]>;
3152 def : InstAlias<"call\t{*}$dst", (CALL64m i64mem:$dst), 0>, Requires<[In64BitMode]>;
3153 def : InstAlias<"jmp\t{*}$dst", (JMP64m i64mem:$dst), 0>, Requires<[In64BitMode]>;
3154 def : InstAlias<"call\t{*}$dst", (CALL32m i32mem:$dst), 0>, Requires<[In32BitMode]>;
3155 def : InstAlias<"jmp\t{*}$dst", (JMP32m i32mem:$dst), 0>, Requires<[In32BitMode]>;
3156 def : InstAlias<"call\t{*}$dst", (CALL16m i16mem:$dst), 0>, Requires<[In16BitMode]>;
3157 def : InstAlias<"jmp\t{*}$dst", (JMP16m i16mem:$dst), 0>, Requires<[In16BitMode]>;
3160 // "imul <imm>, B" is an alias for "imul <imm>, B, B".
3161 def : InstAlias<"imul{w}\t{$imm, $r|$r, $imm}", (IMUL16rri GR16:$r, GR16:$r, i16imm:$imm), 0>;
3162 def : InstAlias<"imul{w}\t{$imm, $r|$r, $imm}", (IMUL16rri8 GR16:$r, GR16:$r, i16i8imm:$imm), 0>;
3163 def : InstAlias<"imul{l}\t{$imm, $r|$r, $imm}", (IMUL32rri GR32:$r, GR32:$r, i32imm:$imm), 0>;
3164 def : InstAlias<"imul{l}\t{$imm, $r|$r, $imm}", (IMUL32rri8 GR32:$r, GR32:$r, i32i8imm:$imm), 0>;
3165 def : InstAlias<"imul{q}\t{$imm, $r|$r, $imm}", (IMUL64rri32 GR64:$r, GR64:$r, i64i32imm:$imm), 0>;
3166 def : InstAlias<"imul{q}\t{$imm, $r|$r, $imm}", (IMUL64rri8 GR64:$r, GR64:$r, i64i8imm:$imm), 0>;
3168 // ins aliases. Accept the mnemonic suffix being omitted because it's implicit
3169 // in the destination.
3170 def : InstAlias<"ins\t{%dx, $dst|$dst, dx}", (INSB dstidx8:$dst), 0>;
3171 def : InstAlias<"ins\t{%dx, $dst|$dst, dx}", (INSW dstidx16:$dst), 0>;
3172 def : InstAlias<"ins\t{%dx, $dst|$dst, dx}", (INSL dstidx32:$dst), 0>;
3174 // outs aliases. Accept the mnemonic suffix being omitted because it's implicit
3176 def : InstAlias<"outs\t{$src, %dx|dx, $src}", (OUTSB srcidx8:$src), 0>;
3177 def : InstAlias<"outs\t{$src, %dx|dx, $src}", (OUTSW srcidx16:$src), 0>;
3178 def : InstAlias<"outs\t{$src, %dx|dx, $src}", (OUTSL srcidx32:$src), 0>;
3180 // inb %dx -> inb %al, %dx
3181 def : InstAlias<"inb\t{%dx|dx}", (IN8rr), 0>;
3182 def : InstAlias<"inw\t{%dx|dx}", (IN16rr), 0>;
3183 def : InstAlias<"inl\t{%dx|dx}", (IN32rr), 0>;
3184 def : InstAlias<"inb\t$port", (IN8ri u8imm:$port), 0>;
3185 def : InstAlias<"inw\t$port", (IN16ri u8imm:$port), 0>;
3186 def : InstAlias<"inl\t$port", (IN32ri u8imm:$port), 0>;
3189 // jmp and call aliases for lcall and ljmp. jmp $42,$5 -> ljmp
3190 def : InstAlias<"call\t$seg, $off", (FARCALL16i i16imm:$off, i16imm:$seg)>, Requires<[In16BitMode]>;
3191 def : InstAlias<"jmp\t$seg, $off", (FARJMP16i i16imm:$off, i16imm:$seg)>, Requires<[In16BitMode]>;
3192 def : InstAlias<"call\t$seg, $off", (FARCALL32i i32imm:$off, i16imm:$seg)>, Requires<[In32BitMode]>;
3193 def : InstAlias<"jmp\t$seg, $off", (FARJMP32i i32imm:$off, i16imm:$seg)>, Requires<[In32BitMode]>;
3194 def : InstAlias<"callw\t$seg, $off", (FARCALL16i i16imm:$off, i16imm:$seg)>, Requires<[Not64BitMode]>;
3195 def : InstAlias<"jmpw\t$seg, $off", (FARJMP16i i16imm:$off, i16imm:$seg)>, Requires<[Not64BitMode]>;
3196 def : InstAlias<"calll\t$seg, $off", (FARCALL32i i32imm:$off, i16imm:$seg)>, Requires<[Not64BitMode]>;
3197 def : InstAlias<"jmpl\t$seg, $off", (FARJMP32i i32imm:$off, i16imm:$seg)>, Requires<[Not64BitMode]>;
3199 // Force mov without a suffix with a segment and mem to prefer the 'l' form of
3200 // the move. All segment/mem forms are equivalent, this has the shortest
3202 def : InstAlias<"mov\t{$mem, $seg|$seg, $mem}", (MOV16sm SEGMENT_REG:$seg, i16mem:$mem), 0>;
3203 def : InstAlias<"mov\t{$seg, $mem|$mem, $seg}", (MOV16ms i16mem:$mem, SEGMENT_REG:$seg), 0>;
3205 // Match 'movq <largeimm>, <reg>' as an alias for movabsq.
3206 def : InstAlias<"mov{q}\t{$imm, $reg|$reg, $imm}", (MOV64ri GR64:$reg, i64imm:$imm), 0>;
3208 // Match 'movq GR64, MMX' as an alias for movd.
3209 def : InstAlias<"movq\t{$src, $dst|$dst, $src}",
3210 (MMX_MOVD64to64rr VR64:$dst, GR64:$src), 0>;
3211 def : InstAlias<"movq\t{$src, $dst|$dst, $src}",
3212 (MMX_MOVD64from64rr GR64:$dst, VR64:$src), 0>;
3215 def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX16rr8 GR16:$dst, GR8:$src), 0>;
3216 def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX16rm8 GR16:$dst, i8mem:$src), 0>;
3217 def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX32rr8 GR32:$dst, GR8:$src), 0>;
3218 def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX32rr16 GR32:$dst, GR16:$src), 0>;
3219 def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX64rr8 GR64:$dst, GR8:$src), 0>;
3220 def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX64rr16 GR64:$dst, GR16:$src), 0>;
3221 def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX64rr32 GR64:$dst, GR32:$src), 0>;
3224 def : InstAlias<"movzx\t{$src, $dst|$dst, $src}", (MOVZX16rr8 GR16:$dst, GR8:$src), 0>;
3225 def : InstAlias<"movzx\t{$src, $dst|$dst, $src}", (MOVZX16rm8 GR16:$dst, i8mem:$src), 0>;
3226 def : InstAlias<"movzx\t{$src, $dst|$dst, $src}", (MOVZX32rr8 GR32:$dst, GR8:$src), 0>;
3227 def : InstAlias<"movzx\t{$src, $dst|$dst, $src}", (MOVZX32rr16 GR32:$dst, GR16:$src), 0>;
3228 def : InstAlias<"movzx\t{$src, $dst|$dst, $src}", (MOVZX64rr8 GR64:$dst, GR8:$src), 0>;
3229 def : InstAlias<"movzx\t{$src, $dst|$dst, $src}", (MOVZX64rr16 GR64:$dst, GR16:$src), 0>;
3230 // Note: No GR32->GR64 movzx form.
3232 // outb %dx -> outb %al, %dx
3233 def : InstAlias<"outb\t{%dx|dx}", (OUT8rr), 0>;
3234 def : InstAlias<"outw\t{%dx|dx}", (OUT16rr), 0>;
3235 def : InstAlias<"outl\t{%dx|dx}", (OUT32rr), 0>;
3236 def : InstAlias<"outb\t$port", (OUT8ir u8imm:$port), 0>;
3237 def : InstAlias<"outw\t$port", (OUT16ir u8imm:$port), 0>;
3238 def : InstAlias<"outl\t$port", (OUT32ir u8imm:$port), 0>;
3240 // 'sldt <mem>' can be encoded with either sldtw or sldtq with the same
3241 // effect (both store to a 16-bit mem). Force to sldtw to avoid ambiguity
3242 // errors, since its encoding is the most compact.
3243 def : InstAlias<"sldt $mem", (SLDT16m i16mem:$mem), 0>;
3245 // shld/shrd op,op -> shld op, op, CL
3246 def : InstAlias<"shld{w}\t{$r2, $r1|$r1, $r2}", (SHLD16rrCL GR16:$r1, GR16:$r2), 0>;
3247 def : InstAlias<"shld{l}\t{$r2, $r1|$r1, $r2}", (SHLD32rrCL GR32:$r1, GR32:$r2), 0>;
3248 def : InstAlias<"shld{q}\t{$r2, $r1|$r1, $r2}", (SHLD64rrCL GR64:$r1, GR64:$r2), 0>;
3249 def : InstAlias<"shrd{w}\t{$r2, $r1|$r1, $r2}", (SHRD16rrCL GR16:$r1, GR16:$r2), 0>;
3250 def : InstAlias<"shrd{l}\t{$r2, $r1|$r1, $r2}", (SHRD32rrCL GR32:$r1, GR32:$r2), 0>;
3251 def : InstAlias<"shrd{q}\t{$r2, $r1|$r1, $r2}", (SHRD64rrCL GR64:$r1, GR64:$r2), 0>;
3253 def : InstAlias<"shld{w}\t{$reg, $mem|$mem, $reg}", (SHLD16mrCL i16mem:$mem, GR16:$reg), 0>;
3254 def : InstAlias<"shld{l}\t{$reg, $mem|$mem, $reg}", (SHLD32mrCL i32mem:$mem, GR32:$reg), 0>;
3255 def : InstAlias<"shld{q}\t{$reg, $mem|$mem, $reg}", (SHLD64mrCL i64mem:$mem, GR64:$reg), 0>;
3256 def : InstAlias<"shrd{w}\t{$reg, $mem|$mem, $reg}", (SHRD16mrCL i16mem:$mem, GR16:$reg), 0>;
3257 def : InstAlias<"shrd{l}\t{$reg, $mem|$mem, $reg}", (SHRD32mrCL i32mem:$mem, GR32:$reg), 0>;
3258 def : InstAlias<"shrd{q}\t{$reg, $mem|$mem, $reg}", (SHRD64mrCL i64mem:$mem, GR64:$reg), 0>;
3260 /* FIXME: This is disabled because the asm matcher is currently incapable of
3261 * matching a fixed immediate like $1.
3262 // "shl X, $1" is an alias for "shl X".
3263 multiclass ShiftRotateByOneAlias<string Mnemonic, string Opc> {
3264 def : InstAlias<!strconcat(Mnemonic, "b $op, $$1"),
3265 (!cast<Instruction>(!strconcat(Opc, "8r1")) GR8:$op)>;
3266 def : InstAlias<!strconcat(Mnemonic, "w $op, $$1"),
3267 (!cast<Instruction>(!strconcat(Opc, "16r1")) GR16:$op)>;
3268 def : InstAlias<!strconcat(Mnemonic, "l $op, $$1"),
3269 (!cast<Instruction>(!strconcat(Opc, "32r1")) GR32:$op)>;
3270 def : InstAlias<!strconcat(Mnemonic, "q $op, $$1"),
3271 (!cast<Instruction>(!strconcat(Opc, "64r1")) GR64:$op)>;
3272 def : InstAlias<!strconcat(Mnemonic, "b $op, $$1"),
3273 (!cast<Instruction>(!strconcat(Opc, "8m1")) i8mem:$op)>;
3274 def : InstAlias<!strconcat(Mnemonic, "w $op, $$1"),
3275 (!cast<Instruction>(!strconcat(Opc, "16m1")) i16mem:$op)>;
3276 def : InstAlias<!strconcat(Mnemonic, "l $op, $$1"),
3277 (!cast<Instruction>(!strconcat(Opc, "32m1")) i32mem:$op)>;
3278 def : InstAlias<!strconcat(Mnemonic, "q $op, $$1"),
3279 (!cast<Instruction>(!strconcat(Opc, "64m1")) i64mem:$op)>;
3282 defm : ShiftRotateByOneAlias<"rcl", "RCL">;
3283 defm : ShiftRotateByOneAlias<"rcr", "RCR">;
3284 defm : ShiftRotateByOneAlias<"rol", "ROL">;
3285 defm : ShiftRotateByOneAlias<"ror", "ROR">;
3288 // test: We accept "testX <reg>, <mem>" and "testX <mem>, <reg>" as synonyms.
3289 def : InstAlias<"test{b}\t{$mem, $val|$val, $mem}",
3290 (TEST8mr i8mem :$mem, GR8 :$val), 0>;
3291 def : InstAlias<"test{w}\t{$mem, $val|$val, $mem}",
3292 (TEST16mr i16mem:$mem, GR16:$val), 0>;
3293 def : InstAlias<"test{l}\t{$mem, $val|$val, $mem}",
3294 (TEST32mr i32mem:$mem, GR32:$val), 0>;
3295 def : InstAlias<"test{q}\t{$mem, $val|$val, $mem}",
3296 (TEST64mr i64mem:$mem, GR64:$val), 0>;
3298 // xchg: We accept "xchgX <reg>, <mem>" and "xchgX <mem>, <reg>" as synonyms.
3299 def : InstAlias<"xchg{b}\t{$mem, $val|$val, $mem}",
3300 (XCHG8rm GR8 :$val, i8mem :$mem), 0>;
3301 def : InstAlias<"xchg{w}\t{$mem, $val|$val, $mem}",
3302 (XCHG16rm GR16:$val, i16mem:$mem), 0>;
3303 def : InstAlias<"xchg{l}\t{$mem, $val|$val, $mem}",
3304 (XCHG32rm GR32:$val, i32mem:$mem), 0>;
3305 def : InstAlias<"xchg{q}\t{$mem, $val|$val, $mem}",
3306 (XCHG64rm GR64:$val, i64mem:$mem), 0>;
3308 // xchg: We accept "xchgX <reg>, %eax" and "xchgX %eax, <reg>" as synonyms.
3309 def : InstAlias<"xchg{w}\t{%ax, $src|$src, ax}", (XCHG16ar GR16:$src), 0>;
3310 def : InstAlias<"xchg{l}\t{%eax, $src|$src, eax}",
3311 (XCHG32ar GR32:$src), 0>, Requires<[Not64BitMode]>;
3312 def : InstAlias<"xchg{l}\t{%eax, $src|$src, eax}",
3313 (XCHG32ar64 GR32_NOAX:$src), 0>, Requires<[In64BitMode]>;
3314 def : InstAlias<"xchg{q}\t{%rax, $src|$src, rax}", (XCHG64ar GR64:$src), 0>;
3316 // These aliases exist to get the parser to prioritize matching 8-bit
3317 // immediate encodings over matching the implicit ax/eax/rax encodings. By
3318 // explicitly mentioning the A register here, these entries will be ordered
3319 // first due to the more explicit immediate type.
3320 def : InstAlias<"adc{w}\t{$imm, %ax|ax, $imm}", (ADC16ri8 AX, i16i8imm:$imm), 0>;
3321 def : InstAlias<"add{w}\t{$imm, %ax|ax, $imm}", (ADD16ri8 AX, i16i8imm:$imm), 0>;
3322 def : InstAlias<"and{w}\t{$imm, %ax|ax, $imm}", (AND16ri8 AX, i16i8imm:$imm), 0>;
3323 def : InstAlias<"cmp{w}\t{$imm, %ax|ax, $imm}", (CMP16ri8 AX, i16i8imm:$imm), 0>;
3324 def : InstAlias<"or{w}\t{$imm, %ax|ax, $imm}", (OR16ri8 AX, i16i8imm:$imm), 0>;
3325 def : InstAlias<"sbb{w}\t{$imm, %ax|ax, $imm}", (SBB16ri8 AX, i16i8imm:$imm), 0>;
3326 def : InstAlias<"sub{w}\t{$imm, %ax|ax, $imm}", (SUB16ri8 AX, i16i8imm:$imm), 0>;
3327 def : InstAlias<"xor{w}\t{$imm, %ax|ax, $imm}", (XOR16ri8 AX, i16i8imm:$imm), 0>;
3329 def : InstAlias<"adc{l}\t{$imm, %eax|eax, $imm}", (ADC32ri8 EAX, i32i8imm:$imm), 0>;
3330 def : InstAlias<"add{l}\t{$imm, %eax|eax, $imm}", (ADD32ri8 EAX, i32i8imm:$imm), 0>;
3331 def : InstAlias<"and{l}\t{$imm, %eax|eax, $imm}", (AND32ri8 EAX, i32i8imm:$imm), 0>;
3332 def : InstAlias<"cmp{l}\t{$imm, %eax|eax, $imm}", (CMP32ri8 EAX, i32i8imm:$imm), 0>;
3333 def : InstAlias<"or{l}\t{$imm, %eax|eax, $imm}", (OR32ri8 EAX, i32i8imm:$imm), 0>;
3334 def : InstAlias<"sbb{l}\t{$imm, %eax|eax, $imm}", (SBB32ri8 EAX, i32i8imm:$imm), 0>;
3335 def : InstAlias<"sub{l}\t{$imm, %eax|eax, $imm}", (SUB32ri8 EAX, i32i8imm:$imm), 0>;
3336 def : InstAlias<"xor{l}\t{$imm, %eax|eax, $imm}", (XOR32ri8 EAX, i32i8imm:$imm), 0>;
3338 def : InstAlias<"adc{q}\t{$imm, %rax|rax, $imm}", (ADC64ri8 RAX, i64i8imm:$imm), 0>;
3339 def : InstAlias<"add{q}\t{$imm, %rax|rax, $imm}", (ADD64ri8 RAX, i64i8imm:$imm), 0>;
3340 def : InstAlias<"and{q}\t{$imm, %rax|rax, $imm}", (AND64ri8 RAX, i64i8imm:$imm), 0>;
3341 def : InstAlias<"cmp{q}\t{$imm, %rax|rax, $imm}", (CMP64ri8 RAX, i64i8imm:$imm), 0>;
3342 def : InstAlias<"or{q}\t{$imm, %rax|rax, $imm}", (OR64ri8 RAX, i64i8imm:$imm), 0>;
3343 def : InstAlias<"sbb{q}\t{$imm, %rax|rax, $imm}", (SBB64ri8 RAX, i64i8imm:$imm), 0>;
3344 def : InstAlias<"sub{q}\t{$imm, %rax|rax, $imm}", (SUB64ri8 RAX, i64i8imm:$imm), 0>;
3345 def : InstAlias<"xor{q}\t{$imm, %rax|rax, $imm}", (XOR64ri8 RAX, i64i8imm:$imm), 0>;