1 //===-- X86InstrInfo.td - Main X86 Instruction Definition --*- tablegen -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file describes the X86 instruction set, defining the instructions, and
11 // properties of the instructions which are needed for code generation, machine
12 // code emission, and analysis.
14 //===----------------------------------------------------------------------===//
16 //===----------------------------------------------------------------------===//
17 // X86 specific DAG Nodes.
20 def SDTIntShiftDOp: SDTypeProfile<1, 3,
21 [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>,
22 SDTCisInt<0>, SDTCisInt<3>]>;
24 def SDTX86CmpTest : SDTypeProfile<1, 2, [SDTCisVT<0, i32>, SDTCisSameAs<1, 2>]>;
26 def SDTX86Cmps : SDTypeProfile<1, 3, [SDTCisFP<0>, SDTCisSameAs<1, 2>, SDTCisVT<3, i8>]>;
27 //def SDTX86Cmpss : SDTypeProfile<1, 3, [SDTCisVT<0, f32>, SDTCisSameAs<1, 2>, SDTCisVT<3, i8>]>;
29 def SDTX86Cmov : SDTypeProfile<1, 4,
30 [SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>,
31 SDTCisVT<3, i8>, SDTCisVT<4, i32>]>;
33 // Unary and binary operator instructions that set EFLAGS as a side-effect.
34 def SDTUnaryArithWithFlags : SDTypeProfile<2, 1,
36 SDTCisInt<0>, SDTCisVT<1, i32>]>;
38 def SDTBinaryArithWithFlags : SDTypeProfile<2, 2,
41 SDTCisInt<0>, SDTCisVT<1, i32>]>;
43 // SDTBinaryArithWithFlagsInOut - RES1, EFLAGS = op LHS, RHS, EFLAGS
44 def SDTBinaryArithWithFlagsInOut : SDTypeProfile<2, 3,
50 // RES1, RES2, FLAGS = op LHS, RHS
51 def SDT2ResultBinaryArithWithFlags : SDTypeProfile<3, 2,
55 SDTCisInt<0>, SDTCisVT<1, i32>]>;
56 def SDTX86BrCond : SDTypeProfile<0, 3,
57 [SDTCisVT<0, OtherVT>,
58 SDTCisVT<1, i8>, SDTCisVT<2, i32>]>;
60 def SDTX86SetCC : SDTypeProfile<1, 2,
62 SDTCisVT<1, i8>, SDTCisVT<2, i32>]>;
63 def SDTX86SetCC_C : SDTypeProfile<1, 2,
65 SDTCisVT<1, i8>, SDTCisVT<2, i32>]>;
67 def SDTX86sahf : SDTypeProfile<1, 1, [SDTCisVT<0, i32>, SDTCisVT<1, i8>]>;
69 def SDTX86rdrand : SDTypeProfile<2, 0, [SDTCisInt<0>, SDTCisVT<1, i32>]>;
71 def SDTX86cas : SDTypeProfile<0, 3, [SDTCisPtrTy<0>, SDTCisInt<1>,
73 def SDTX86caspair : SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>;
74 def SDTX86caspairSaveEbx8 : SDTypeProfile<1, 3,
75 [SDTCisVT<0, i32>, SDTCisPtrTy<1>,
76 SDTCisVT<2, i32>, SDTCisVT<3, i32>]>;
77 def SDTX86caspairSaveRbx16 : SDTypeProfile<1, 3,
78 [SDTCisVT<0, i64>, SDTCisPtrTy<1>,
79 SDTCisVT<2, i64>, SDTCisVT<3, i64>]>;
81 def SDTLockBinaryArithWithFlags : SDTypeProfile<1, 2, [SDTCisVT<0, i32>,
85 def SDTX86Ret : SDTypeProfile<0, -1, [SDTCisVT<0, i32>]>;
87 def SDT_X86CallSeqStart : SDCallSeqStart<[SDTCisVT<0, i32>,
89 def SDT_X86CallSeqEnd : SDCallSeqEnd<[SDTCisVT<0, i32>,
92 def SDT_X86Call : SDTypeProfile<0, -1, [SDTCisVT<0, iPTR>]>;
94 def SDT_X86VASTART_SAVE_XMM_REGS : SDTypeProfile<0, -1, [SDTCisVT<0, i8>,
98 def SDT_X86VAARG_64 : SDTypeProfile<1, -1, [SDTCisPtrTy<0>,
104 def SDTX86RepStr : SDTypeProfile<0, 1, [SDTCisVT<0, OtherVT>]>;
106 def SDTX86Void : SDTypeProfile<0, 0, []>;
108 def SDTX86Wrapper : SDTypeProfile<1, 1, [SDTCisSameAs<0, 1>, SDTCisPtrTy<0>]>;
110 def SDT_X86TLSADDR : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
112 def SDT_X86TLSBASEADDR : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
114 def SDT_X86TLSCALL : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
116 def SDT_X86WIN_ALLOCA : SDTypeProfile<0, 1, [SDTCisVT<0, iPTR>]>;
118 def SDT_X86SEG_ALLOCA : SDTypeProfile<1, 1, [SDTCisVT<0, iPTR>, SDTCisVT<1, iPTR>]>;
120 def SDT_X86EHRET : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
122 def SDT_X86TCRET : SDTypeProfile<0, 2, [SDTCisPtrTy<0>, SDTCisVT<1, i32>]>;
124 def SDT_X86MEMBARRIER : SDTypeProfile<0, 0, []>;
126 def X86MemBarrier : SDNode<"X86ISD::MEMBARRIER", SDT_X86MEMBARRIER,
127 [SDNPHasChain,SDNPSideEffect]>;
128 def X86MFence : SDNode<"X86ISD::MFENCE", SDT_X86MEMBARRIER,
132 def X86bsf : SDNode<"X86ISD::BSF", SDTUnaryArithWithFlags>;
133 def X86bsr : SDNode<"X86ISD::BSR", SDTUnaryArithWithFlags>;
134 def X86shld : SDNode<"X86ISD::SHLD", SDTIntShiftDOp>;
135 def X86shrd : SDNode<"X86ISD::SHRD", SDTIntShiftDOp>;
137 def X86cmp : SDNode<"X86ISD::CMP" , SDTX86CmpTest>;
138 def X86bt : SDNode<"X86ISD::BT", SDTX86CmpTest>;
140 def X86cmov : SDNode<"X86ISD::CMOV", SDTX86Cmov>;
141 def X86brcond : SDNode<"X86ISD::BRCOND", SDTX86BrCond,
143 def X86setcc : SDNode<"X86ISD::SETCC", SDTX86SetCC>;
144 def X86setcc_c : SDNode<"X86ISD::SETCC_CARRY", SDTX86SetCC_C>;
146 def X86sahf : SDNode<"X86ISD::SAHF", SDTX86sahf>;
148 def X86rdrand : SDNode<"X86ISD::RDRAND", SDTX86rdrand,
149 [SDNPHasChain, SDNPSideEffect]>;
151 def X86rdseed : SDNode<"X86ISD::RDSEED", SDTX86rdrand,
152 [SDNPHasChain, SDNPSideEffect]>;
154 def X86cas : SDNode<"X86ISD::LCMPXCHG_DAG", SDTX86cas,
155 [SDNPHasChain, SDNPInGlue, SDNPOutGlue, SDNPMayStore,
156 SDNPMayLoad, SDNPMemOperand]>;
157 def X86cas8 : SDNode<"X86ISD::LCMPXCHG8_DAG", SDTX86caspair,
158 [SDNPHasChain, SDNPInGlue, SDNPOutGlue, SDNPMayStore,
159 SDNPMayLoad, SDNPMemOperand]>;
160 def X86cas16 : SDNode<"X86ISD::LCMPXCHG16_DAG", SDTX86caspair,
161 [SDNPHasChain, SDNPInGlue, SDNPOutGlue, SDNPMayStore,
162 SDNPMayLoad, SDNPMemOperand]>;
163 def X86cas8save_ebx : SDNode<"X86ISD::LCMPXCHG8_SAVE_EBX_DAG",
164 SDTX86caspairSaveEbx8,
165 [SDNPHasChain, SDNPInGlue, SDNPOutGlue,
166 SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
167 def X86cas16save_rbx : SDNode<"X86ISD::LCMPXCHG16_SAVE_RBX_DAG",
168 SDTX86caspairSaveRbx16,
169 [SDNPHasChain, SDNPInGlue, SDNPOutGlue,
170 SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
172 def X86retflag : SDNode<"X86ISD::RET_FLAG", SDTX86Ret,
173 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
174 def X86iret : SDNode<"X86ISD::IRET", SDTX86Ret,
175 [SDNPHasChain, SDNPOptInGlue]>;
177 def X86vastart_save_xmm_regs :
178 SDNode<"X86ISD::VASTART_SAVE_XMM_REGS",
179 SDT_X86VASTART_SAVE_XMM_REGS,
180 [SDNPHasChain, SDNPVariadic]>;
182 SDNode<"X86ISD::VAARG_64", SDT_X86VAARG_64,
183 [SDNPHasChain, SDNPMayLoad, SDNPMayStore,
185 def X86callseq_start :
186 SDNode<"ISD::CALLSEQ_START", SDT_X86CallSeqStart,
187 [SDNPHasChain, SDNPOutGlue]>;
189 SDNode<"ISD::CALLSEQ_END", SDT_X86CallSeqEnd,
190 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
192 def X86call : SDNode<"X86ISD::CALL", SDT_X86Call,
193 [SDNPHasChain, SDNPOutGlue, SDNPOptInGlue,
196 def X86rep_stos: SDNode<"X86ISD::REP_STOS", SDTX86RepStr,
197 [SDNPHasChain, SDNPInGlue, SDNPOutGlue, SDNPMayStore]>;
198 def X86rep_movs: SDNode<"X86ISD::REP_MOVS", SDTX86RepStr,
199 [SDNPHasChain, SDNPInGlue, SDNPOutGlue, SDNPMayStore,
202 def X86rdtsc : SDNode<"X86ISD::RDTSC_DAG", SDTX86Void,
203 [SDNPHasChain, SDNPOutGlue, SDNPSideEffect]>;
204 def X86rdtscp : SDNode<"X86ISD::RDTSCP_DAG", SDTX86Void,
205 [SDNPHasChain, SDNPOutGlue, SDNPSideEffect]>;
206 def X86rdpmc : SDNode<"X86ISD::RDPMC_DAG", SDTX86Void,
207 [SDNPHasChain, SDNPOutGlue, SDNPSideEffect]>;
209 def X86Wrapper : SDNode<"X86ISD::Wrapper", SDTX86Wrapper>;
210 def X86WrapperRIP : SDNode<"X86ISD::WrapperRIP", SDTX86Wrapper>;
212 def X86RecoverFrameAlloc : SDNode<"ISD::LOCAL_RECOVER",
213 SDTypeProfile<1, 1, [SDTCisSameAs<0, 1>,
216 def X86tlsaddr : SDNode<"X86ISD::TLSADDR", SDT_X86TLSADDR,
217 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
219 def X86tlsbaseaddr : SDNode<"X86ISD::TLSBASEADDR", SDT_X86TLSBASEADDR,
220 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
222 def X86ehret : SDNode<"X86ISD::EH_RETURN", SDT_X86EHRET,
225 def X86eh_sjlj_setjmp : SDNode<"X86ISD::EH_SJLJ_SETJMP",
226 SDTypeProfile<1, 1, [SDTCisInt<0>,
228 [SDNPHasChain, SDNPSideEffect]>;
229 def X86eh_sjlj_longjmp : SDNode<"X86ISD::EH_SJLJ_LONGJMP",
230 SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>,
231 [SDNPHasChain, SDNPSideEffect]>;
232 def X86eh_sjlj_setup_dispatch : SDNode<"X86ISD::EH_SJLJ_SETUP_DISPATCH",
233 SDTypeProfile<0, 0, []>,
234 [SDNPHasChain, SDNPSideEffect]>;
236 def X86tcret : SDNode<"X86ISD::TC_RETURN", SDT_X86TCRET,
237 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
239 def X86add_flag : SDNode<"X86ISD::ADD", SDTBinaryArithWithFlags,
241 def X86sub_flag : SDNode<"X86ISD::SUB", SDTBinaryArithWithFlags>;
242 def X86smul_flag : SDNode<"X86ISD::SMUL", SDTBinaryArithWithFlags,
244 def X86umul_flag : SDNode<"X86ISD::UMUL", SDT2ResultBinaryArithWithFlags,
246 def X86adc_flag : SDNode<"X86ISD::ADC", SDTBinaryArithWithFlagsInOut>;
247 def X86sbb_flag : SDNode<"X86ISD::SBB", SDTBinaryArithWithFlagsInOut>;
249 def X86inc_flag : SDNode<"X86ISD::INC", SDTUnaryArithWithFlags>;
250 def X86dec_flag : SDNode<"X86ISD::DEC", SDTUnaryArithWithFlags>;
251 def X86or_flag : SDNode<"X86ISD::OR", SDTBinaryArithWithFlags,
253 def X86xor_flag : SDNode<"X86ISD::XOR", SDTBinaryArithWithFlags,
255 def X86and_flag : SDNode<"X86ISD::AND", SDTBinaryArithWithFlags,
258 def X86lock_add : SDNode<"X86ISD::LADD", SDTLockBinaryArithWithFlags,
259 [SDNPHasChain, SDNPMayStore, SDNPMayLoad,
261 def X86lock_sub : SDNode<"X86ISD::LSUB", SDTLockBinaryArithWithFlags,
262 [SDNPHasChain, SDNPMayStore, SDNPMayLoad,
264 def X86lock_or : SDNode<"X86ISD::LOR", SDTLockBinaryArithWithFlags,
265 [SDNPHasChain, SDNPMayStore, SDNPMayLoad,
267 def X86lock_xor : SDNode<"X86ISD::LXOR", SDTLockBinaryArithWithFlags,
268 [SDNPHasChain, SDNPMayStore, SDNPMayLoad,
270 def X86lock_and : SDNode<"X86ISD::LAND", SDTLockBinaryArithWithFlags,
271 [SDNPHasChain, SDNPMayStore, SDNPMayLoad,
274 def X86bextr : SDNode<"X86ISD::BEXTR", SDTIntBinOp>;
276 def X86mul_imm : SDNode<"X86ISD::MUL_IMM", SDTIntBinOp>;
278 def X86WinAlloca : SDNode<"X86ISD::WIN_ALLOCA", SDT_X86WIN_ALLOCA,
279 [SDNPHasChain, SDNPOutGlue]>;
281 def X86SegAlloca : SDNode<"X86ISD::SEG_ALLOCA", SDT_X86SEG_ALLOCA,
284 def X86TLSCall : SDNode<"X86ISD::TLSCALL", SDT_X86TLSCALL,
285 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
287 def X86lwpins : SDNode<"X86ISD::LWPINS",
288 SDTypeProfile<1, 3, [SDTCisVT<0, i32>, SDTCisInt<1>,
289 SDTCisVT<2, i32>, SDTCisVT<3, i32>]>,
290 [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPSideEffect]>;
292 //===----------------------------------------------------------------------===//
293 // X86 Operand Definitions.
296 // A version of ptr_rc which excludes SP, ESP, and RSP. This is used for
297 // the index operand of an address, to conform to x86 encoding restrictions.
298 def ptr_rc_nosp : PointerLikeRegClass<1>;
300 // *mem - Operand definitions for the funky X86 addressing mode operands.
302 def X86MemAsmOperand : AsmOperandClass {
305 let RenderMethod = "addMemOperands", SuperClasses = [X86MemAsmOperand] in {
306 def X86Mem8AsmOperand : AsmOperandClass { let Name = "Mem8"; }
307 def X86Mem16AsmOperand : AsmOperandClass { let Name = "Mem16"; }
308 def X86Mem32AsmOperand : AsmOperandClass { let Name = "Mem32"; }
309 def X86Mem64AsmOperand : AsmOperandClass { let Name = "Mem64"; }
310 def X86Mem80AsmOperand : AsmOperandClass { let Name = "Mem80"; }
311 def X86Mem128AsmOperand : AsmOperandClass { let Name = "Mem128"; }
312 def X86Mem256AsmOperand : AsmOperandClass { let Name = "Mem256"; }
313 def X86Mem512AsmOperand : AsmOperandClass { let Name = "Mem512"; }
314 // Gather mem operands
315 def X86Mem64_RC128Operand : AsmOperandClass { let Name = "Mem64_RC128"; }
316 def X86Mem128_RC128Operand : AsmOperandClass { let Name = "Mem128_RC128"; }
317 def X86Mem256_RC128Operand : AsmOperandClass { let Name = "Mem256_RC128"; }
318 def X86Mem128_RC256Operand : AsmOperandClass { let Name = "Mem128_RC256"; }
319 def X86Mem256_RC256Operand : AsmOperandClass { let Name = "Mem256_RC256"; }
321 def X86Mem64_RC128XOperand : AsmOperandClass { let Name = "Mem64_RC128X"; }
322 def X86Mem128_RC128XOperand : AsmOperandClass { let Name = "Mem128_RC128X"; }
323 def X86Mem256_RC128XOperand : AsmOperandClass { let Name = "Mem256_RC128X"; }
324 def X86Mem128_RC256XOperand : AsmOperandClass { let Name = "Mem128_RC256X"; }
325 def X86Mem256_RC256XOperand : AsmOperandClass { let Name = "Mem256_RC256X"; }
326 def X86Mem512_RC256XOperand : AsmOperandClass { let Name = "Mem512_RC256X"; }
327 def X86Mem256_RC512Operand : AsmOperandClass { let Name = "Mem256_RC512"; }
328 def X86Mem512_RC512Operand : AsmOperandClass { let Name = "Mem512_RC512"; }
331 def X86AbsMemAsmOperand : AsmOperandClass {
333 let SuperClasses = [X86MemAsmOperand];
336 class X86MemOperand<string printMethod,
337 AsmOperandClass parserMatchClass = X86MemAsmOperand> : Operand<iPTR> {
338 let PrintMethod = printMethod;
339 let MIOperandInfo = (ops ptr_rc, i8imm, ptr_rc_nosp, i32imm, SEGMENT_REG);
340 let ParserMatchClass = parserMatchClass;
341 let OperandType = "OPERAND_MEMORY";
344 // Gather mem operands
345 class X86VMemOperand<RegisterClass RC, string printMethod,
346 AsmOperandClass parserMatchClass>
347 : X86MemOperand<printMethod, parserMatchClass> {
348 let MIOperandInfo = (ops ptr_rc, i8imm, RC, i32imm, SEGMENT_REG);
351 def anymem : X86MemOperand<"printanymem">;
353 def opaque32mem : X86MemOperand<"printopaquemem">;
354 def opaque48mem : X86MemOperand<"printopaquemem">;
355 def opaque80mem : X86MemOperand<"printopaquemem">;
356 def opaque512mem : X86MemOperand<"printopaquemem">;
358 def i8mem : X86MemOperand<"printi8mem", X86Mem8AsmOperand>;
359 def i16mem : X86MemOperand<"printi16mem", X86Mem16AsmOperand>;
360 def i32mem : X86MemOperand<"printi32mem", X86Mem32AsmOperand>;
361 def i64mem : X86MemOperand<"printi64mem", X86Mem64AsmOperand>;
362 def i128mem : X86MemOperand<"printi128mem", X86Mem128AsmOperand>;
363 def i256mem : X86MemOperand<"printi256mem", X86Mem256AsmOperand>;
364 def i512mem : X86MemOperand<"printi512mem", X86Mem512AsmOperand>;
365 def f32mem : X86MemOperand<"printf32mem", X86Mem32AsmOperand>;
366 def f64mem : X86MemOperand<"printf64mem", X86Mem64AsmOperand>;
367 def f80mem : X86MemOperand<"printf80mem", X86Mem80AsmOperand>;
368 def f128mem : X86MemOperand<"printf128mem", X86Mem128AsmOperand>;
369 def f256mem : X86MemOperand<"printf256mem", X86Mem256AsmOperand>;
370 def f512mem : X86MemOperand<"printf512mem", X86Mem512AsmOperand>;
372 def v512mem : X86VMemOperand<VR512, "printf512mem", X86Mem512AsmOperand>;
374 // Gather mem operands
375 def vx64mem : X86VMemOperand<VR128, "printi64mem", X86Mem64_RC128Operand>;
376 def vx128mem : X86VMemOperand<VR128, "printi128mem", X86Mem128_RC128Operand>;
377 def vx256mem : X86VMemOperand<VR128, "printi256mem", X86Mem256_RC128Operand>;
378 def vy128mem : X86VMemOperand<VR256, "printi128mem", X86Mem128_RC256Operand>;
379 def vy256mem : X86VMemOperand<VR256, "printi256mem", X86Mem256_RC256Operand>;
381 def vx64xmem : X86VMemOperand<VR128X, "printi64mem", X86Mem64_RC128XOperand>;
382 def vx128xmem : X86VMemOperand<VR128X, "printi128mem", X86Mem128_RC128XOperand>;
383 def vx256xmem : X86VMemOperand<VR128X, "printi256mem", X86Mem256_RC128XOperand>;
384 def vy128xmem : X86VMemOperand<VR256X, "printi128mem", X86Mem128_RC256XOperand>;
385 def vy256xmem : X86VMemOperand<VR256X, "printi256mem", X86Mem256_RC256XOperand>;
386 def vy512mem : X86VMemOperand<VR256X, "printi512mem", X86Mem512_RC256XOperand>;
387 def vz256xmem : X86VMemOperand<VR512, "printi256mem", X86Mem256_RC512Operand>;
388 def vz512mem : X86VMemOperand<VR512, "printi512mem", X86Mem512_RC512Operand>;
390 // A version of i8mem for use on x86-64 and x32 that uses a NOREX GPR instead
391 // of a plain GPR, so that it doesn't potentially require a REX prefix.
392 def ptr_rc_norex : PointerLikeRegClass<2>;
393 def ptr_rc_norex_nosp : PointerLikeRegClass<3>;
395 def i8mem_NOREX : Operand<iPTR> {
396 let PrintMethod = "printi8mem";
397 let MIOperandInfo = (ops ptr_rc_norex, i8imm, ptr_rc_norex_nosp, i32imm,
399 let ParserMatchClass = X86Mem8AsmOperand;
400 let OperandType = "OPERAND_MEMORY";
403 // GPRs available for tailcall.
404 // It represents GR32_TC, GR64_TC or GR64_TCW64.
405 def ptr_rc_tailcall : PointerLikeRegClass<4>;
407 // Special i32mem for addresses of load folding tail calls. These are not
408 // allowed to use callee-saved registers since they must be scheduled
409 // after callee-saved register are popped.
410 def i32mem_TC : Operand<i32> {
411 let PrintMethod = "printi32mem";
412 let MIOperandInfo = (ops ptr_rc_tailcall, i8imm, ptr_rc_tailcall,
413 i32imm, SEGMENT_REG);
414 let ParserMatchClass = X86Mem32AsmOperand;
415 let OperandType = "OPERAND_MEMORY";
418 // Special i64mem for addresses of load folding tail calls. These are not
419 // allowed to use callee-saved registers since they must be scheduled
420 // after callee-saved register are popped.
421 def i64mem_TC : Operand<i64> {
422 let PrintMethod = "printi64mem";
423 let MIOperandInfo = (ops ptr_rc_tailcall, i8imm,
424 ptr_rc_tailcall, i32imm, SEGMENT_REG);
425 let ParserMatchClass = X86Mem64AsmOperand;
426 let OperandType = "OPERAND_MEMORY";
429 let OperandType = "OPERAND_PCREL",
430 ParserMatchClass = X86AbsMemAsmOperand,
431 PrintMethod = "printPCRelImm" in {
432 def i32imm_pcrel : Operand<i32>;
433 def i16imm_pcrel : Operand<i16>;
435 // Branch targets have OtherVT type and print as pc-relative values.
436 def brtarget : Operand<OtherVT>;
437 def brtarget8 : Operand<OtherVT>;
441 // Special parser to detect 16-bit mode to select 16-bit displacement.
442 def X86AbsMem16AsmOperand : AsmOperandClass {
443 let Name = "AbsMem16";
444 let RenderMethod = "addAbsMemOperands";
445 let SuperClasses = [X86AbsMemAsmOperand];
448 // Branch targets have OtherVT type and print as pc-relative values.
449 let OperandType = "OPERAND_PCREL",
450 PrintMethod = "printPCRelImm" in {
451 let ParserMatchClass = X86AbsMem16AsmOperand in
452 def brtarget16 : Operand<OtherVT>;
453 let ParserMatchClass = X86AbsMemAsmOperand in
454 def brtarget32 : Operand<OtherVT>;
457 let RenderMethod = "addSrcIdxOperands" in {
458 def X86SrcIdx8Operand : AsmOperandClass {
459 let Name = "SrcIdx8";
460 let SuperClasses = [X86Mem8AsmOperand];
462 def X86SrcIdx16Operand : AsmOperandClass {
463 let Name = "SrcIdx16";
464 let SuperClasses = [X86Mem16AsmOperand];
466 def X86SrcIdx32Operand : AsmOperandClass {
467 let Name = "SrcIdx32";
468 let SuperClasses = [X86Mem32AsmOperand];
470 def X86SrcIdx64Operand : AsmOperandClass {
471 let Name = "SrcIdx64";
472 let SuperClasses = [X86Mem64AsmOperand];
474 } // RenderMethod = "addSrcIdxOperands"
476 let RenderMethod = "addDstIdxOperands" in {
477 def X86DstIdx8Operand : AsmOperandClass {
478 let Name = "DstIdx8";
479 let SuperClasses = [X86Mem8AsmOperand];
481 def X86DstIdx16Operand : AsmOperandClass {
482 let Name = "DstIdx16";
483 let SuperClasses = [X86Mem16AsmOperand];
485 def X86DstIdx32Operand : AsmOperandClass {
486 let Name = "DstIdx32";
487 let SuperClasses = [X86Mem32AsmOperand];
489 def X86DstIdx64Operand : AsmOperandClass {
490 let Name = "DstIdx64";
491 let SuperClasses = [X86Mem64AsmOperand];
493 } // RenderMethod = "addDstIdxOperands"
495 let RenderMethod = "addMemOffsOperands" in {
496 def X86MemOffs16_8AsmOperand : AsmOperandClass {
497 let Name = "MemOffs16_8";
498 let SuperClasses = [X86Mem8AsmOperand];
500 def X86MemOffs16_16AsmOperand : AsmOperandClass {
501 let Name = "MemOffs16_16";
502 let SuperClasses = [X86Mem16AsmOperand];
504 def X86MemOffs16_32AsmOperand : AsmOperandClass {
505 let Name = "MemOffs16_32";
506 let SuperClasses = [X86Mem32AsmOperand];
508 def X86MemOffs32_8AsmOperand : AsmOperandClass {
509 let Name = "MemOffs32_8";
510 let SuperClasses = [X86Mem8AsmOperand];
512 def X86MemOffs32_16AsmOperand : AsmOperandClass {
513 let Name = "MemOffs32_16";
514 let SuperClasses = [X86Mem16AsmOperand];
516 def X86MemOffs32_32AsmOperand : AsmOperandClass {
517 let Name = "MemOffs32_32";
518 let SuperClasses = [X86Mem32AsmOperand];
520 def X86MemOffs32_64AsmOperand : AsmOperandClass {
521 let Name = "MemOffs32_64";
522 let SuperClasses = [X86Mem64AsmOperand];
524 def X86MemOffs64_8AsmOperand : AsmOperandClass {
525 let Name = "MemOffs64_8";
526 let SuperClasses = [X86Mem8AsmOperand];
528 def X86MemOffs64_16AsmOperand : AsmOperandClass {
529 let Name = "MemOffs64_16";
530 let SuperClasses = [X86Mem16AsmOperand];
532 def X86MemOffs64_32AsmOperand : AsmOperandClass {
533 let Name = "MemOffs64_32";
534 let SuperClasses = [X86Mem32AsmOperand];
536 def X86MemOffs64_64AsmOperand : AsmOperandClass {
537 let Name = "MemOffs64_64";
538 let SuperClasses = [X86Mem64AsmOperand];
540 } // RenderMethod = "addMemOffsOperands"
542 class X86SrcIdxOperand<string printMethod, AsmOperandClass parserMatchClass>
543 : X86MemOperand<printMethod, parserMatchClass> {
544 let MIOperandInfo = (ops ptr_rc, SEGMENT_REG);
547 class X86DstIdxOperand<string printMethod, AsmOperandClass parserMatchClass>
548 : X86MemOperand<printMethod, parserMatchClass> {
549 let MIOperandInfo = (ops ptr_rc);
552 def srcidx8 : X86SrcIdxOperand<"printSrcIdx8", X86SrcIdx8Operand>;
553 def srcidx16 : X86SrcIdxOperand<"printSrcIdx16", X86SrcIdx16Operand>;
554 def srcidx32 : X86SrcIdxOperand<"printSrcIdx32", X86SrcIdx32Operand>;
555 def srcidx64 : X86SrcIdxOperand<"printSrcIdx64", X86SrcIdx64Operand>;
556 def dstidx8 : X86DstIdxOperand<"printDstIdx8", X86DstIdx8Operand>;
557 def dstidx16 : X86DstIdxOperand<"printDstIdx16", X86DstIdx16Operand>;
558 def dstidx32 : X86DstIdxOperand<"printDstIdx32", X86DstIdx32Operand>;
559 def dstidx64 : X86DstIdxOperand<"printDstIdx64", X86DstIdx64Operand>;
561 class X86MemOffsOperand<Operand immOperand, string printMethod,
562 AsmOperandClass parserMatchClass>
563 : X86MemOperand<printMethod, parserMatchClass> {
564 let MIOperandInfo = (ops immOperand, SEGMENT_REG);
567 def offset16_8 : X86MemOffsOperand<i16imm, "printMemOffs8",
568 X86MemOffs16_8AsmOperand>;
569 def offset16_16 : X86MemOffsOperand<i16imm, "printMemOffs16",
570 X86MemOffs16_16AsmOperand>;
571 def offset16_32 : X86MemOffsOperand<i16imm, "printMemOffs32",
572 X86MemOffs16_32AsmOperand>;
573 def offset32_8 : X86MemOffsOperand<i32imm, "printMemOffs8",
574 X86MemOffs32_8AsmOperand>;
575 def offset32_16 : X86MemOffsOperand<i32imm, "printMemOffs16",
576 X86MemOffs32_16AsmOperand>;
577 def offset32_32 : X86MemOffsOperand<i32imm, "printMemOffs32",
578 X86MemOffs32_32AsmOperand>;
579 def offset32_64 : X86MemOffsOperand<i32imm, "printMemOffs64",
580 X86MemOffs32_64AsmOperand>;
581 def offset64_8 : X86MemOffsOperand<i64imm, "printMemOffs8",
582 X86MemOffs64_8AsmOperand>;
583 def offset64_16 : X86MemOffsOperand<i64imm, "printMemOffs16",
584 X86MemOffs64_16AsmOperand>;
585 def offset64_32 : X86MemOffsOperand<i64imm, "printMemOffs32",
586 X86MemOffs64_32AsmOperand>;
587 def offset64_64 : X86MemOffsOperand<i64imm, "printMemOffs64",
588 X86MemOffs64_64AsmOperand>;
590 def SSECC : Operand<i8> {
591 let PrintMethod = "printSSEAVXCC";
592 let OperandType = "OPERAND_IMMEDIATE";
595 def i8immZExt3 : ImmLeaf<i8, [{
596 return Imm >= 0 && Imm < 8;
599 def AVXCC : Operand<i8> {
600 let PrintMethod = "printSSEAVXCC";
601 let OperandType = "OPERAND_IMMEDIATE";
604 def i8immZExt5 : ImmLeaf<i8, [{
605 return Imm >= 0 && Imm < 32;
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 HasAVX : Predicate<"Subtarget->hasAVX()">;
807 def HasAVX2 : Predicate<"Subtarget->hasAVX2()">;
808 def HasAVX1Only : Predicate<"Subtarget->hasAVX() && !Subtarget->hasAVX2()">;
809 def HasAVX512 : Predicate<"Subtarget->hasAVX512()">,
810 AssemblerPredicate<"FeatureAVX512", "AVX-512 ISA">;
811 def UseAVX : Predicate<"Subtarget->hasAVX() && !Subtarget->hasAVX512()">;
812 def UseAVX2 : Predicate<"Subtarget->hasAVX2() && !Subtarget->hasAVX512()">;
813 def NoAVX512 : Predicate<"!Subtarget->hasAVX512()">;
814 def HasCDI : Predicate<"Subtarget->hasCDI()">,
815 AssemblerPredicate<"FeatureCDI", "AVX-512 CD ISA">;
816 def HasPFI : Predicate<"Subtarget->hasPFI()">,
817 AssemblerPredicate<"FeaturePFI", "AVX-512 PF ISA">;
818 def HasERI : Predicate<"Subtarget->hasERI()">,
819 AssemblerPredicate<"FeatureERI", "AVX-512 ER ISA">;
820 def HasDQI : Predicate<"Subtarget->hasDQI()">,
821 AssemblerPredicate<"FeatureDQI", "AVX-512 DQ ISA">;
822 def NoDQI : Predicate<"!Subtarget->hasDQI()">;
823 def HasBWI : Predicate<"Subtarget->hasBWI()">,
824 AssemblerPredicate<"FeatureBWI", "AVX-512 BW ISA">;
825 def NoBWI : Predicate<"!Subtarget->hasBWI()">;
826 def HasVLX : Predicate<"Subtarget->hasVLX()">,
827 AssemblerPredicate<"FeatureVLX", "AVX-512 VL ISA">;
828 def NoVLX : Predicate<"!Subtarget->hasVLX()">;
829 def NoVLX_Or_NoBWI : Predicate<"!Subtarget->hasVLX() || !Subtarget->hasBWI()">;
830 def NoVLX_Or_NoDQI : Predicate<"!Subtarget->hasVLX() || !Subtarget->hasDQI()">;
831 def PKU : Predicate<"Subtarget->hasPKU()">;
833 def HasPOPCNT : Predicate<"Subtarget->hasPOPCNT()">;
834 def HasAES : Predicate<"Subtarget->hasAES()">;
835 def HasFXSR : Predicate<"Subtarget->hasFXSR()">;
836 def HasXSAVE : Predicate<"Subtarget->hasXSAVE()">;
837 def HasXSAVEOPT : Predicate<"Subtarget->hasXSAVEOPT()">;
838 def HasXSAVEC : Predicate<"Subtarget->hasXSAVEC()">;
839 def HasXSAVES : Predicate<"Subtarget->hasXSAVES()">;
840 def HasPCLMUL : Predicate<"Subtarget->hasPCLMUL()">;
841 def HasFMA : Predicate<"Subtarget->hasFMA()">;
842 def HasFMA4 : Predicate<"Subtarget->hasFMA4()">;
843 def HasXOP : Predicate<"Subtarget->hasXOP()">;
844 def HasTBM : Predicate<"Subtarget->hasTBM()">;
845 def HasLWP : Predicate<"Subtarget->hasLWP()">;
846 def HasMOVBE : Predicate<"Subtarget->hasMOVBE()">;
847 def HasRDRAND : Predicate<"Subtarget->hasRDRAND()">;
848 def HasF16C : Predicate<"Subtarget->hasF16C()">;
849 def NoF16C : Predicate<"!Subtarget->hasF16C()">;
850 def HasFSGSBase : Predicate<"Subtarget->hasFSGSBase()">;
851 def HasLZCNT : Predicate<"Subtarget->hasLZCNT()">;
852 def HasBMI : Predicate<"Subtarget->hasBMI()">;
853 def HasBMI2 : Predicate<"Subtarget->hasBMI2()">;
854 def HasVBMI : Predicate<"Subtarget->hasVBMI()">,
855 AssemblerPredicate<"FeatureVBMI", "AVX-512 VBMI ISA">;
856 def HasIFMA : Predicate<"Subtarget->hasIFMA()">,
857 AssemblerPredicate<"FeatureIFMA", "AVX-512 IFMA ISA">;
858 def HasRTM : Predicate<"Subtarget->hasRTM()">;
859 def HasADX : Predicate<"Subtarget->hasADX()">;
860 def HasSHA : Predicate<"Subtarget->hasSHA()">;
861 def HasPRFCHW : Predicate<"Subtarget->hasPRFCHW()">;
862 def HasRDSEED : Predicate<"Subtarget->hasRDSEED()">;
863 def HasPrefetchW : Predicate<"Subtarget->hasPRFCHW()">;
864 def HasLAHFSAHF : Predicate<"Subtarget->hasLAHFSAHF()">;
865 def HasMWAITX : Predicate<"Subtarget->hasMWAITX()">;
866 def HasCLZERO : Predicate<"Subtarget->hasCLZERO()">;
867 def FPStackf32 : Predicate<"!Subtarget->hasSSE1()">;
868 def FPStackf64 : Predicate<"!Subtarget->hasSSE2()">;
869 def HasMPX : Predicate<"Subtarget->hasMPX()">;
870 def HasCLFLUSHOPT : Predicate<"Subtarget->hasCLFLUSHOPT()">;
871 def HasCmpxchg16b: Predicate<"Subtarget->hasCmpxchg16b()">;
872 def Not64BitMode : Predicate<"!Subtarget->is64Bit()">,
873 AssemblerPredicate<"!Mode64Bit", "Not 64-bit mode">;
874 def In64BitMode : Predicate<"Subtarget->is64Bit()">,
875 AssemblerPredicate<"Mode64Bit", "64-bit mode">;
876 def IsLP64 : Predicate<"Subtarget->isTarget64BitLP64()">;
877 def NotLP64 : Predicate<"!Subtarget->isTarget64BitLP64()">;
878 def In16BitMode : Predicate<"Subtarget->is16Bit()">,
879 AssemblerPredicate<"Mode16Bit", "16-bit mode">;
880 def Not16BitMode : Predicate<"!Subtarget->is16Bit()">,
881 AssemblerPredicate<"!Mode16Bit", "Not 16-bit mode">;
882 def In32BitMode : Predicate<"Subtarget->is32Bit()">,
883 AssemblerPredicate<"Mode32Bit", "32-bit mode">;
884 def IsWin64 : Predicate<"Subtarget->isTargetWin64()">;
885 def NotWin64 : Predicate<"!Subtarget->isTargetWin64()">;
886 def NotWin64WithoutFP : Predicate<"!Subtarget->isTargetWin64() ||"
887 "Subtarget->getFrameLowering()->hasFP(*MF)"> {
888 let RecomputePerFunction = 1;
890 def IsPS4 : Predicate<"Subtarget->isTargetPS4()">;
891 def NotPS4 : Predicate<"!Subtarget->isTargetPS4()">;
892 def IsNaCl : Predicate<"Subtarget->isTargetNaCl()">;
893 def NotNaCl : Predicate<"!Subtarget->isTargetNaCl()">;
894 def SmallCode : Predicate<"TM.getCodeModel() == CodeModel::Small">;
895 def KernelCode : Predicate<"TM.getCodeModel() == CodeModel::Kernel">;
896 def NearData : Predicate<"TM.getCodeModel() == CodeModel::Small ||"
897 "TM.getCodeModel() == CodeModel::Kernel">;
898 def IsNotPIC : Predicate<"!TM.isPositionIndependent()">;
899 def OptForSize : Predicate<"Subtarget->getOptForSize()">;
900 def OptForMinSize : Predicate<"Subtarget->getOptForMinSize()">;
901 def OptForSpeed : Predicate<"!Subtarget->getOptForSize()">;
902 def FastBTMem : Predicate<"!Subtarget->isBTMemSlow()">;
903 def CallImmAddr : Predicate<"Subtarget->isLegalToCallImmediateAddr()">;
904 def FavorMemIndirectCall : Predicate<"!Subtarget->callRegIndirect()">;
905 def NotSlowIncDec : Predicate<"!Subtarget->slowIncDec()">;
906 def HasFastMem32 : Predicate<"!Subtarget->isUnalignedMem32Slow()">;
907 def HasFastLZCNT : Predicate<"Subtarget->hasFastLZCNT()">;
908 def HasFastSHLDRotate : Predicate<"Subtarget->hasFastSHLDRotate()">;
909 def HasERMSB : Predicate<"Subtarget->hasERMSB()">;
910 def HasMFence : Predicate<"Subtarget->hasMFence()">;
912 //===----------------------------------------------------------------------===//
913 // X86 Instruction Format Definitions.
916 include "X86InstrFormats.td"
918 //===----------------------------------------------------------------------===//
919 // Pattern fragments.
922 // X86 specific condition code. These correspond to CondCode in
923 // X86InstrInfo.h. They must be kept in synch.
924 def X86_COND_A : PatLeaf<(i8 0)>; // alt. COND_NBE
925 def X86_COND_AE : PatLeaf<(i8 1)>; // alt. COND_NC
926 def X86_COND_B : PatLeaf<(i8 2)>; // alt. COND_C
927 def X86_COND_BE : PatLeaf<(i8 3)>; // alt. COND_NA
928 def X86_COND_E : PatLeaf<(i8 4)>; // alt. COND_Z
929 def X86_COND_G : PatLeaf<(i8 5)>; // alt. COND_NLE
930 def X86_COND_GE : PatLeaf<(i8 6)>; // alt. COND_NL
931 def X86_COND_L : PatLeaf<(i8 7)>; // alt. COND_NGE
932 def X86_COND_LE : PatLeaf<(i8 8)>; // alt. COND_NG
933 def X86_COND_NE : PatLeaf<(i8 9)>; // alt. COND_NZ
934 def X86_COND_NO : PatLeaf<(i8 10)>;
935 def X86_COND_NP : PatLeaf<(i8 11)>; // alt. COND_PO
936 def X86_COND_NS : PatLeaf<(i8 12)>;
937 def X86_COND_O : PatLeaf<(i8 13)>;
938 def X86_COND_P : PatLeaf<(i8 14)>; // alt. COND_PE
939 def X86_COND_S : PatLeaf<(i8 15)>;
941 def i16immSExt8 : ImmLeaf<i16, [{ return isInt<8>(Imm); }]>;
942 def i32immSExt8 : ImmLeaf<i32, [{ return isInt<8>(Imm); }]>;
943 def i64immSExt8 : ImmLeaf<i64, [{ return isInt<8>(Imm); }]>;
944 def i64immSExt32 : ImmLeaf<i64, [{ return isInt<32>(Imm); }]>;
946 // FIXME: Ideally we would just replace the above i*immSExt* matchers with
947 // relocImm-based matchers, but then FastISel would be unable to use them.
948 def i64relocImmSExt8 : PatLeaf<(i64 relocImm), [{
949 return isSExtRelocImm<8>(N);
951 def i64relocImmSExt32 : PatLeaf<(i64 relocImm), [{
952 return isSExtRelocImm<32>(N);
955 // If we have multiple users of an immediate, it's much smaller to reuse
956 // the register, rather than encode the immediate in every instruction.
957 // This has the risk of increasing register pressure from stretched live
958 // ranges, however, the immediates should be trivial to rematerialize by
959 // the RA in the event of high register pressure.
960 // TODO : This is currently enabled for stores and binary ops. There are more
961 // cases for which this can be enabled, though this catches the bulk of the
963 // TODO2 : This should really also be enabled under O2, but there's currently
964 // an issue with RA where we don't pull the constants into their users
965 // when we rematerialize them. I'll follow-up on enabling O2 after we fix that
967 // TODO3 : This is currently limited to single basic blocks (DAG creation
968 // pulls block immediates to the top and merges them if necessary).
969 // Eventually, it would be nice to allow ConstantHoisting to merge constants
970 // globally for potentially added savings.
972 def imm8_su : PatLeaf<(i8 relocImm), [{
973 return !shouldAvoidImmediateInstFormsForSize(N);
975 def imm16_su : PatLeaf<(i16 relocImm), [{
976 return !shouldAvoidImmediateInstFormsForSize(N);
978 def imm32_su : PatLeaf<(i32 relocImm), [{
979 return !shouldAvoidImmediateInstFormsForSize(N);
981 def i64immSExt32_su : PatLeaf<(i64immSExt32), [{
982 return !shouldAvoidImmediateInstFormsForSize(N);
985 def i16immSExt8_su : PatLeaf<(i16immSExt8), [{
986 return !shouldAvoidImmediateInstFormsForSize(N);
988 def i32immSExt8_su : PatLeaf<(i32immSExt8), [{
989 return !shouldAvoidImmediateInstFormsForSize(N);
991 def i64immSExt8_su : PatLeaf<(i64immSExt8), [{
992 return !shouldAvoidImmediateInstFormsForSize(N);
995 def i64relocImmSExt8_su : PatLeaf<(i64relocImmSExt8), [{
996 return !shouldAvoidImmediateInstFormsForSize(N);
998 def i64relocImmSExt32_su : PatLeaf<(i64relocImmSExt32), [{
999 return !shouldAvoidImmediateInstFormsForSize(N);
1002 // i64immZExt32 predicate - True if the 64-bit immediate fits in a 32-bit
1004 def i64immZExt32 : ImmLeaf<i64, [{ return isUInt<32>(Imm); }]>;
1006 def i64immZExt32SExt8 : ImmLeaf<i64, [{
1007 return isUInt<32>(Imm) && isInt<8>(static_cast<int32_t>(Imm));
1010 // Helper fragments for loads.
1011 // It's always safe to treat a anyext i16 load as a i32 load if the i16 is
1012 // known to be 32-bit aligned or better. Ditto for i8 to i16.
1013 def loadi16 : PatFrag<(ops node:$ptr), (i16 (unindexedload node:$ptr)), [{
1014 LoadSDNode *LD = cast<LoadSDNode>(N);
1015 ISD::LoadExtType ExtType = LD->getExtensionType();
1016 if (ExtType == ISD::NON_EXTLOAD)
1018 if (ExtType == ISD::EXTLOAD)
1019 return LD->getAlignment() >= 2 && !LD->isVolatile();
1023 def loadi16_anyext : PatFrag<(ops node:$ptr), (i32 (unindexedload node:$ptr)),[{
1024 LoadSDNode *LD = cast<LoadSDNode>(N);
1025 ISD::LoadExtType ExtType = LD->getExtensionType();
1026 if (ExtType == ISD::EXTLOAD)
1027 return LD->getAlignment() >= 2 && !LD->isVolatile();
1031 def loadi32 : PatFrag<(ops node:$ptr), (i32 (unindexedload node:$ptr)), [{
1032 LoadSDNode *LD = cast<LoadSDNode>(N);
1033 ISD::LoadExtType ExtType = LD->getExtensionType();
1034 if (ExtType == ISD::NON_EXTLOAD)
1036 if (ExtType == ISD::EXTLOAD)
1037 return LD->getAlignment() >= 4 && !LD->isVolatile();
1041 def loadi8 : PatFrag<(ops node:$ptr), (i8 (load node:$ptr))>;
1042 def loadi64 : PatFrag<(ops node:$ptr), (i64 (load node:$ptr))>;
1043 def loadf32 : PatFrag<(ops node:$ptr), (f32 (load node:$ptr))>;
1044 def loadf64 : PatFrag<(ops node:$ptr), (f64 (load node:$ptr))>;
1045 def loadf80 : PatFrag<(ops node:$ptr), (f80 (load node:$ptr))>;
1046 def loadf128 : PatFrag<(ops node:$ptr), (f128 (load node:$ptr))>;
1048 def sextloadi16i8 : PatFrag<(ops node:$ptr), (i16 (sextloadi8 node:$ptr))>;
1049 def sextloadi32i8 : PatFrag<(ops node:$ptr), (i32 (sextloadi8 node:$ptr))>;
1050 def sextloadi32i16 : PatFrag<(ops node:$ptr), (i32 (sextloadi16 node:$ptr))>;
1051 def sextloadi64i8 : PatFrag<(ops node:$ptr), (i64 (sextloadi8 node:$ptr))>;
1052 def sextloadi64i16 : PatFrag<(ops node:$ptr), (i64 (sextloadi16 node:$ptr))>;
1053 def sextloadi64i32 : PatFrag<(ops node:$ptr), (i64 (sextloadi32 node:$ptr))>;
1055 def zextloadi8i1 : PatFrag<(ops node:$ptr), (i8 (zextloadi1 node:$ptr))>;
1056 def zextloadi16i1 : PatFrag<(ops node:$ptr), (i16 (zextloadi1 node:$ptr))>;
1057 def zextloadi32i1 : PatFrag<(ops node:$ptr), (i32 (zextloadi1 node:$ptr))>;
1058 def zextloadi16i8 : PatFrag<(ops node:$ptr), (i16 (zextloadi8 node:$ptr))>;
1059 def zextloadi32i8 : PatFrag<(ops node:$ptr), (i32 (zextloadi8 node:$ptr))>;
1060 def zextloadi32i16 : PatFrag<(ops node:$ptr), (i32 (zextloadi16 node:$ptr))>;
1061 def zextloadi64i1 : PatFrag<(ops node:$ptr), (i64 (zextloadi1 node:$ptr))>;
1062 def zextloadi64i8 : PatFrag<(ops node:$ptr), (i64 (zextloadi8 node:$ptr))>;
1063 def zextloadi64i16 : PatFrag<(ops node:$ptr), (i64 (zextloadi16 node:$ptr))>;
1064 def zextloadi64i32 : PatFrag<(ops node:$ptr), (i64 (zextloadi32 node:$ptr))>;
1066 def extloadi8i1 : PatFrag<(ops node:$ptr), (i8 (extloadi1 node:$ptr))>;
1067 def extloadi16i1 : PatFrag<(ops node:$ptr), (i16 (extloadi1 node:$ptr))>;
1068 def extloadi32i1 : PatFrag<(ops node:$ptr), (i32 (extloadi1 node:$ptr))>;
1069 def extloadi16i8 : PatFrag<(ops node:$ptr), (i16 (extloadi8 node:$ptr))>;
1070 def extloadi32i8 : PatFrag<(ops node:$ptr), (i32 (extloadi8 node:$ptr))>;
1071 def extloadi32i16 : PatFrag<(ops node:$ptr), (i32 (extloadi16 node:$ptr))>;
1072 def extloadi64i1 : PatFrag<(ops node:$ptr), (i64 (extloadi1 node:$ptr))>;
1073 def extloadi64i8 : PatFrag<(ops node:$ptr), (i64 (extloadi8 node:$ptr))>;
1074 def extloadi64i16 : PatFrag<(ops node:$ptr), (i64 (extloadi16 node:$ptr))>;
1075 def extloadi64i32 : PatFrag<(ops node:$ptr), (i64 (extloadi32 node:$ptr))>;
1078 // An 'and' node with a single use.
1079 def and_su : PatFrag<(ops node:$lhs, node:$rhs), (and node:$lhs, node:$rhs), [{
1080 return N->hasOneUse();
1082 // An 'srl' node with a single use.
1083 def srl_su : PatFrag<(ops node:$lhs, node:$rhs), (srl node:$lhs, node:$rhs), [{
1084 return N->hasOneUse();
1086 // An 'trunc' node with a single use.
1087 def trunc_su : PatFrag<(ops node:$src), (trunc node:$src), [{
1088 return N->hasOneUse();
1091 //===----------------------------------------------------------------------===//
1092 // Instruction list.
1096 let hasSideEffects = 0, SchedRW = [WriteZero] in {
1097 def NOOP : I<0x90, RawFrm, (outs), (ins), "nop", [], IIC_NOP>;
1098 def NOOPW : I<0x1f, MRMXm, (outs), (ins i16mem:$zero),
1099 "nop{w}\t$zero", [], IIC_NOP>, TB, OpSize16;
1100 def NOOPL : I<0x1f, MRMXm, (outs), (ins i32mem:$zero),
1101 "nop{l}\t$zero", [], IIC_NOP>, TB, OpSize32;
1105 // Constructing a stack frame.
1106 def ENTER : Ii16<0xC8, RawFrmImm8, (outs), (ins i16imm:$len, i8imm:$lvl),
1107 "enter\t$len, $lvl", [], IIC_ENTER>, Sched<[WriteMicrocoded]>;
1109 let SchedRW = [WriteALU] in {
1110 let Defs = [EBP, ESP], Uses = [EBP, ESP], mayLoad = 1, hasSideEffects=0 in
1111 def LEAVE : I<0xC9, RawFrm,
1112 (outs), (ins), "leave", [], IIC_LEAVE>,
1113 Requires<[Not64BitMode]>;
1115 let Defs = [RBP,RSP], Uses = [RBP,RSP], mayLoad = 1, hasSideEffects = 0 in
1116 def LEAVE64 : I<0xC9, RawFrm,
1117 (outs), (ins), "leave", [], IIC_LEAVE>,
1118 Requires<[In64BitMode]>;
1121 //===----------------------------------------------------------------------===//
1122 // Miscellaneous Instructions.
1125 let isBarrier = 1, hasSideEffects = 1, usesCustomInserter = 1 in
1126 def Int_eh_sjlj_setup_dispatch
1127 : PseudoI<(outs), (ins), [(X86eh_sjlj_setup_dispatch)]>;
1129 let Defs = [ESP], Uses = [ESP], hasSideEffects=0 in {
1130 let mayLoad = 1, SchedRW = [WriteLoad] in {
1131 def POP16r : I<0x58, AddRegFrm, (outs GR16:$reg), (ins), "pop{w}\t$reg", [],
1132 IIC_POP_REG16>, OpSize16;
1133 def POP32r : I<0x58, AddRegFrm, (outs GR32:$reg), (ins), "pop{l}\t$reg", [],
1134 IIC_POP_REG>, OpSize32, Requires<[Not64BitMode]>;
1135 def POP16rmr: I<0x8F, MRM0r, (outs GR16:$reg), (ins), "pop{w}\t$reg", [],
1136 IIC_POP_REG>, OpSize16;
1137 def POP32rmr: I<0x8F, MRM0r, (outs GR32:$reg), (ins), "pop{l}\t$reg", [],
1138 IIC_POP_REG>, OpSize32, Requires<[Not64BitMode]>;
1139 } // mayLoad, SchedRW
1140 let mayStore = 1, mayLoad = 1, SchedRW = [WriteRMW] in {
1141 def POP16rmm: I<0x8F, MRM0m, (outs), (ins i16mem:$dst), "pop{w}\t$dst", [],
1142 IIC_POP_MEM>, OpSize16;
1143 def POP32rmm: I<0x8F, MRM0m, (outs), (ins i32mem:$dst), "pop{l}\t$dst", [],
1144 IIC_POP_MEM>, OpSize32, Requires<[Not64BitMode]>;
1145 } // mayStore, mayLoad, WriteRMW
1147 let mayStore = 1, SchedRW = [WriteStore] in {
1148 def PUSH16r : I<0x50, AddRegFrm, (outs), (ins GR16:$reg), "push{w}\t$reg",[],
1149 IIC_PUSH_REG>, OpSize16;
1150 def PUSH32r : I<0x50, AddRegFrm, (outs), (ins GR32:$reg), "push{l}\t$reg",[],
1151 IIC_PUSH_REG>, OpSize32, Requires<[Not64BitMode]>;
1152 def PUSH16rmr: I<0xFF, MRM6r, (outs), (ins GR16:$reg), "push{w}\t$reg",[],
1153 IIC_PUSH_REG>, OpSize16;
1154 def PUSH32rmr: I<0xFF, MRM6r, (outs), (ins GR32:$reg), "push{l}\t$reg",[],
1155 IIC_PUSH_REG>, OpSize32, Requires<[Not64BitMode]>;
1157 def PUSH16i8 : Ii8<0x6a, RawFrm, (outs), (ins i16i8imm:$imm),
1158 "push{w}\t$imm", [], IIC_PUSH_IMM>, OpSize16;
1159 def PUSHi16 : Ii16<0x68, RawFrm, (outs), (ins i16imm:$imm),
1160 "push{w}\t$imm", [], IIC_PUSH_IMM>, OpSize16;
1162 def PUSH32i8 : Ii8<0x6a, RawFrm, (outs), (ins i32i8imm:$imm),
1163 "push{l}\t$imm", [], IIC_PUSH_IMM>, OpSize32,
1164 Requires<[Not64BitMode]>;
1165 def PUSHi32 : Ii32<0x68, RawFrm, (outs), (ins i32imm:$imm),
1166 "push{l}\t$imm", [], IIC_PUSH_IMM>, OpSize32,
1167 Requires<[Not64BitMode]>;
1168 } // mayStore, SchedRW
1170 let mayLoad = 1, mayStore = 1, SchedRW = [WriteRMW] in {
1171 def PUSH16rmm: I<0xFF, MRM6m, (outs), (ins i16mem:$src), "push{w}\t$src",[],
1172 IIC_PUSH_MEM>, OpSize16;
1173 def PUSH32rmm: I<0xFF, MRM6m, (outs), (ins i32mem:$src), "push{l}\t$src",[],
1174 IIC_PUSH_MEM>, OpSize32, Requires<[Not64BitMode]>;
1175 } // mayLoad, mayStore, SchedRW
1179 let mayLoad = 1, mayStore = 1, usesCustomInserter = 1,
1180 SchedRW = [WriteRMW], Defs = [ESP] in {
1182 def RDFLAGS32 : PseudoI<(outs GR32:$dst), (ins),
1183 [(set GR32:$dst, (int_x86_flags_read_u32))]>,
1184 Requires<[Not64BitMode]>;
1187 def RDFLAGS64 : PseudoI<(outs GR64:$dst), (ins),
1188 [(set GR64:$dst, (int_x86_flags_read_u64))]>,
1189 Requires<[In64BitMode]>;
1192 let mayLoad = 1, mayStore = 1, usesCustomInserter = 1,
1193 SchedRW = [WriteRMW] in {
1194 let Defs = [ESP, EFLAGS], Uses = [ESP] in
1195 def WRFLAGS32 : PseudoI<(outs), (ins GR32:$src),
1196 [(int_x86_flags_write_u32 GR32:$src)]>,
1197 Requires<[Not64BitMode]>;
1199 let Defs = [RSP, EFLAGS], Uses = [RSP] in
1200 def WRFLAGS64 : PseudoI<(outs), (ins GR64:$src),
1201 [(int_x86_flags_write_u64 GR64:$src)]>,
1202 Requires<[In64BitMode]>;
1205 let Defs = [ESP, EFLAGS], Uses = [ESP], mayLoad = 1, hasSideEffects=0,
1206 SchedRW = [WriteLoad] in {
1207 def POPF16 : I<0x9D, RawFrm, (outs), (ins), "popf{w}", [], IIC_POP_F>,
1209 def POPF32 : I<0x9D, RawFrm, (outs), (ins), "popf{l|d}", [], IIC_POP_FD>,
1210 OpSize32, Requires<[Not64BitMode]>;
1213 let Defs = [ESP], Uses = [ESP, EFLAGS], mayStore = 1, hasSideEffects=0,
1214 SchedRW = [WriteStore] in {
1215 def PUSHF16 : I<0x9C, RawFrm, (outs), (ins), "pushf{w}", [], IIC_PUSH_F>,
1217 def PUSHF32 : I<0x9C, RawFrm, (outs), (ins), "pushf{l|d}", [], IIC_PUSH_F>,
1218 OpSize32, Requires<[Not64BitMode]>;
1221 let Defs = [RSP], Uses = [RSP], hasSideEffects=0 in {
1222 let mayLoad = 1, SchedRW = [WriteLoad] in {
1223 def POP64r : I<0x58, AddRegFrm, (outs GR64:$reg), (ins), "pop{q}\t$reg", [],
1224 IIC_POP_REG>, OpSize32, Requires<[In64BitMode]>;
1225 def POP64rmr: I<0x8F, MRM0r, (outs GR64:$reg), (ins), "pop{q}\t$reg", [],
1226 IIC_POP_REG>, OpSize32, Requires<[In64BitMode]>;
1227 } // mayLoad, SchedRW
1228 let mayLoad = 1, mayStore = 1, SchedRW = [WriteRMW] in
1229 def POP64rmm: I<0x8F, MRM0m, (outs), (ins i64mem:$dst), "pop{q}\t$dst", [],
1230 IIC_POP_MEM>, OpSize32, Requires<[In64BitMode]>;
1231 let mayStore = 1, SchedRW = [WriteStore] in {
1232 def PUSH64r : I<0x50, AddRegFrm, (outs), (ins GR64:$reg), "push{q}\t$reg", [],
1233 IIC_PUSH_REG>, OpSize32, Requires<[In64BitMode]>;
1234 def PUSH64rmr: I<0xFF, MRM6r, (outs), (ins GR64:$reg), "push{q}\t$reg", [],
1235 IIC_PUSH_REG>, OpSize32, Requires<[In64BitMode]>;
1236 } // mayStore, SchedRW
1237 let mayLoad = 1, mayStore = 1, SchedRW = [WriteRMW] in {
1238 def PUSH64rmm: I<0xFF, MRM6m, (outs), (ins i64mem:$src), "push{q}\t$src", [],
1239 IIC_PUSH_MEM>, OpSize32, Requires<[In64BitMode]>;
1240 } // mayLoad, mayStore, SchedRW
1243 let Defs = [RSP], Uses = [RSP], hasSideEffects = 0, mayStore = 1,
1244 SchedRW = [WriteStore] in {
1245 def PUSH64i8 : Ii8<0x6a, RawFrm, (outs), (ins i64i8imm:$imm),
1246 "push{q}\t$imm", [], IIC_PUSH_IMM>, OpSize32,
1247 Requires<[In64BitMode]>;
1248 def PUSH64i32 : Ii32S<0x68, RawFrm, (outs), (ins i64i32imm:$imm),
1249 "push{q}\t$imm", [], IIC_PUSH_IMM>, OpSize32,
1250 Requires<[In64BitMode]>;
1253 let Defs = [RSP, EFLAGS], Uses = [RSP], mayLoad = 1, hasSideEffects=0 in
1254 def POPF64 : I<0x9D, RawFrm, (outs), (ins), "popfq", [], IIC_POP_FD>,
1255 OpSize32, Requires<[In64BitMode]>, Sched<[WriteLoad]>;
1256 let Defs = [RSP], Uses = [RSP, EFLAGS], mayStore = 1, hasSideEffects=0 in
1257 def PUSHF64 : I<0x9C, RawFrm, (outs), (ins), "pushfq", [], IIC_PUSH_F>,
1258 OpSize32, Requires<[In64BitMode]>, Sched<[WriteStore]>;
1260 let Defs = [EDI, ESI, EBP, EBX, EDX, ECX, EAX, ESP], Uses = [ESP],
1261 mayLoad = 1, hasSideEffects = 0, SchedRW = [WriteLoad] in {
1262 def POPA32 : I<0x61, RawFrm, (outs), (ins), "popal", [], IIC_POP_A>,
1263 OpSize32, Requires<[Not64BitMode]>;
1264 def POPA16 : I<0x61, RawFrm, (outs), (ins), "popaw", [], IIC_POP_A>,
1265 OpSize16, Requires<[Not64BitMode]>;
1267 let Defs = [ESP], Uses = [EDI, ESI, EBP, EBX, EDX, ECX, EAX, ESP],
1268 mayStore = 1, hasSideEffects = 0, SchedRW = [WriteStore] in {
1269 def PUSHA32 : I<0x60, RawFrm, (outs), (ins), "pushal", [], IIC_PUSH_A>,
1270 OpSize32, Requires<[Not64BitMode]>;
1271 def PUSHA16 : I<0x60, RawFrm, (outs), (ins), "pushaw", [], IIC_PUSH_A>,
1272 OpSize16, Requires<[Not64BitMode]>;
1275 let Constraints = "$src = $dst", SchedRW = [WriteALU] in {
1276 // GR32 = bswap GR32
1277 def BSWAP32r : I<0xC8, AddRegFrm,
1278 (outs GR32:$dst), (ins GR32:$src),
1280 [(set GR32:$dst, (bswap GR32:$src))], IIC_BSWAP>, OpSize32, TB;
1282 def BSWAP64r : RI<0xC8, AddRegFrm, (outs GR64:$dst), (ins GR64:$src),
1284 [(set GR64:$dst, (bswap GR64:$src))], IIC_BSWAP>, TB;
1285 } // Constraints = "$src = $dst", SchedRW
1287 // Bit scan instructions.
1288 let Defs = [EFLAGS] in {
1289 def BSF16rr : I<0xBC, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
1290 "bsf{w}\t{$src, $dst|$dst, $src}",
1291 [(set GR16:$dst, EFLAGS, (X86bsf GR16:$src))],
1292 IIC_BIT_SCAN_REG>, PS, OpSize16, Sched<[WriteShift]>;
1293 def BSF16rm : I<0xBC, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
1294 "bsf{w}\t{$src, $dst|$dst, $src}",
1295 [(set GR16:$dst, EFLAGS, (X86bsf (loadi16 addr:$src)))],
1296 IIC_BIT_SCAN_MEM>, PS, OpSize16, Sched<[WriteShiftLd]>;
1297 def BSF32rr : I<0xBC, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
1298 "bsf{l}\t{$src, $dst|$dst, $src}",
1299 [(set GR32:$dst, EFLAGS, (X86bsf GR32:$src))],
1300 IIC_BIT_SCAN_REG>, PS, OpSize32, Sched<[WriteShift]>;
1301 def BSF32rm : I<0xBC, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
1302 "bsf{l}\t{$src, $dst|$dst, $src}",
1303 [(set GR32:$dst, EFLAGS, (X86bsf (loadi32 addr:$src)))],
1304 IIC_BIT_SCAN_MEM>, PS, OpSize32, Sched<[WriteShiftLd]>;
1305 def BSF64rr : RI<0xBC, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
1306 "bsf{q}\t{$src, $dst|$dst, $src}",
1307 [(set GR64:$dst, EFLAGS, (X86bsf GR64:$src))],
1308 IIC_BIT_SCAN_REG>, PS, Sched<[WriteShift]>;
1309 def BSF64rm : RI<0xBC, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
1310 "bsf{q}\t{$src, $dst|$dst, $src}",
1311 [(set GR64:$dst, EFLAGS, (X86bsf (loadi64 addr:$src)))],
1312 IIC_BIT_SCAN_MEM>, PS, Sched<[WriteShiftLd]>;
1314 def BSR16rr : I<0xBD, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
1315 "bsr{w}\t{$src, $dst|$dst, $src}",
1316 [(set GR16:$dst, EFLAGS, (X86bsr GR16:$src))],
1317 IIC_BIT_SCAN_REG>, PS, OpSize16, Sched<[WriteShift]>;
1318 def BSR16rm : I<0xBD, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
1319 "bsr{w}\t{$src, $dst|$dst, $src}",
1320 [(set GR16:$dst, EFLAGS, (X86bsr (loadi16 addr:$src)))],
1321 IIC_BIT_SCAN_MEM>, PS, OpSize16, Sched<[WriteShiftLd]>;
1322 def BSR32rr : I<0xBD, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
1323 "bsr{l}\t{$src, $dst|$dst, $src}",
1324 [(set GR32:$dst, EFLAGS, (X86bsr GR32:$src))],
1325 IIC_BIT_SCAN_REG>, PS, OpSize32, Sched<[WriteShift]>;
1326 def BSR32rm : I<0xBD, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
1327 "bsr{l}\t{$src, $dst|$dst, $src}",
1328 [(set GR32:$dst, EFLAGS, (X86bsr (loadi32 addr:$src)))],
1329 IIC_BIT_SCAN_MEM>, PS, OpSize32, Sched<[WriteShiftLd]>;
1330 def BSR64rr : RI<0xBD, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
1331 "bsr{q}\t{$src, $dst|$dst, $src}",
1332 [(set GR64:$dst, EFLAGS, (X86bsr GR64:$src))],
1333 IIC_BIT_SCAN_REG>, PS, Sched<[WriteShift]>;
1334 def BSR64rm : RI<0xBD, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
1335 "bsr{q}\t{$src, $dst|$dst, $src}",
1336 [(set GR64:$dst, EFLAGS, (X86bsr (loadi64 addr:$src)))],
1337 IIC_BIT_SCAN_MEM>, PS, Sched<[WriteShiftLd]>;
1338 } // Defs = [EFLAGS]
1340 let SchedRW = [WriteMicrocoded] in {
1341 // These uses the DF flag in the EFLAGS register to inc or dec EDI and ESI
1342 let Defs = [EDI,ESI], Uses = [EDI,ESI,EFLAGS] in {
1343 def MOVSB : I<0xA4, RawFrmDstSrc, (outs), (ins dstidx8:$dst, srcidx8:$src),
1344 "movsb\t{$src, $dst|$dst, $src}", [], IIC_MOVS>;
1345 def MOVSW : I<0xA5, RawFrmDstSrc, (outs), (ins dstidx16:$dst, srcidx16:$src),
1346 "movsw\t{$src, $dst|$dst, $src}", [], IIC_MOVS>, OpSize16;
1347 def MOVSL : I<0xA5, RawFrmDstSrc, (outs), (ins dstidx32:$dst, srcidx32:$src),
1348 "movs{l|d}\t{$src, $dst|$dst, $src}", [], IIC_MOVS>, OpSize32;
1349 def MOVSQ : RI<0xA5, RawFrmDstSrc, (outs), (ins dstidx64:$dst, srcidx64:$src),
1350 "movsq\t{$src, $dst|$dst, $src}", [], IIC_MOVS>;
1353 // These uses the DF flag in the EFLAGS register to inc or dec EDI and ESI
1354 let Defs = [EDI], Uses = [AL,EDI,EFLAGS] in
1355 def STOSB : I<0xAA, RawFrmDst, (outs), (ins dstidx8:$dst),
1356 "stosb\t{%al, $dst|$dst, al}", [], IIC_STOS>;
1357 let Defs = [EDI], Uses = [AX,EDI,EFLAGS] in
1358 def STOSW : I<0xAB, RawFrmDst, (outs), (ins dstidx16:$dst),
1359 "stosw\t{%ax, $dst|$dst, ax}", [], IIC_STOS>, OpSize16;
1360 let Defs = [EDI], Uses = [EAX,EDI,EFLAGS] in
1361 def STOSL : I<0xAB, RawFrmDst, (outs), (ins dstidx32:$dst),
1362 "stos{l|d}\t{%eax, $dst|$dst, eax}", [], IIC_STOS>, OpSize32;
1363 let Defs = [RDI], Uses = [RAX,RDI,EFLAGS] in
1364 def STOSQ : RI<0xAB, RawFrmDst, (outs), (ins dstidx64:$dst),
1365 "stosq\t{%rax, $dst|$dst, rax}", [], IIC_STOS>;
1367 // These uses the DF flag in the EFLAGS register to inc or dec EDI and ESI
1368 let Defs = [EDI,EFLAGS], Uses = [AL,EDI,EFLAGS] in
1369 def SCASB : I<0xAE, RawFrmDst, (outs), (ins dstidx8:$dst),
1370 "scasb\t{$dst, %al|al, $dst}", [], IIC_SCAS>;
1371 let Defs = [EDI,EFLAGS], Uses = [AX,EDI,EFLAGS] in
1372 def SCASW : I<0xAF, RawFrmDst, (outs), (ins dstidx16:$dst),
1373 "scasw\t{$dst, %ax|ax, $dst}", [], IIC_SCAS>, OpSize16;
1374 let Defs = [EDI,EFLAGS], Uses = [EAX,EDI,EFLAGS] in
1375 def SCASL : I<0xAF, RawFrmDst, (outs), (ins dstidx32:$dst),
1376 "scas{l|d}\t{$dst, %eax|eax, $dst}", [], IIC_SCAS>, OpSize32;
1377 let Defs = [EDI,EFLAGS], Uses = [RAX,EDI,EFLAGS] in
1378 def SCASQ : RI<0xAF, RawFrmDst, (outs), (ins dstidx64:$dst),
1379 "scasq\t{$dst, %rax|rax, $dst}", [], IIC_SCAS>;
1381 // These uses the DF flag in the EFLAGS register to inc or dec EDI and ESI
1382 let Defs = [EDI,ESI,EFLAGS], Uses = [EDI,ESI,EFLAGS] in {
1383 def CMPSB : I<0xA6, RawFrmDstSrc, (outs), (ins dstidx8:$dst, srcidx8:$src),
1384 "cmpsb\t{$dst, $src|$src, $dst}", [], IIC_CMPS>;
1385 def CMPSW : I<0xA7, RawFrmDstSrc, (outs), (ins dstidx16:$dst, srcidx16:$src),
1386 "cmpsw\t{$dst, $src|$src, $dst}", [], IIC_CMPS>, OpSize16;
1387 def CMPSL : I<0xA7, RawFrmDstSrc, (outs), (ins dstidx32:$dst, srcidx32:$src),
1388 "cmps{l|d}\t{$dst, $src|$src, $dst}", [], IIC_CMPS>, OpSize32;
1389 def CMPSQ : RI<0xA7, RawFrmDstSrc, (outs), (ins dstidx64:$dst, srcidx64:$src),
1390 "cmpsq\t{$dst, $src|$src, $dst}", [], IIC_CMPS>;
1394 //===----------------------------------------------------------------------===//
1395 // Move Instructions.
1397 let SchedRW = [WriteMove] in {
1398 let hasSideEffects = 0 in {
1399 def MOV8rr : I<0x88, MRMDestReg, (outs GR8 :$dst), (ins GR8 :$src),
1400 "mov{b}\t{$src, $dst|$dst, $src}", [], IIC_MOV>;
1401 def MOV16rr : I<0x89, MRMDestReg, (outs GR16:$dst), (ins GR16:$src),
1402 "mov{w}\t{$src, $dst|$dst, $src}", [], IIC_MOV>, OpSize16;
1403 def MOV32rr : I<0x89, MRMDestReg, (outs GR32:$dst), (ins GR32:$src),
1404 "mov{l}\t{$src, $dst|$dst, $src}", [], IIC_MOV>, OpSize32;
1405 def MOV64rr : RI<0x89, MRMDestReg, (outs GR64:$dst), (ins GR64:$src),
1406 "mov{q}\t{$src, $dst|$dst, $src}", [], IIC_MOV>;
1409 let isReMaterializable = 1, isAsCheapAsAMove = 1 in {
1410 def MOV8ri : Ii8 <0xB0, AddRegFrm, (outs GR8 :$dst), (ins i8imm :$src),
1411 "mov{b}\t{$src, $dst|$dst, $src}",
1412 [(set GR8:$dst, imm:$src)], IIC_MOV>;
1413 def MOV16ri : Ii16<0xB8, AddRegFrm, (outs GR16:$dst), (ins i16imm:$src),
1414 "mov{w}\t{$src, $dst|$dst, $src}",
1415 [(set GR16:$dst, imm:$src)], IIC_MOV>, OpSize16;
1416 def MOV32ri : Ii32<0xB8, AddRegFrm, (outs GR32:$dst), (ins i32imm:$src),
1417 "mov{l}\t{$src, $dst|$dst, $src}",
1418 [(set GR32:$dst, relocImm:$src)], IIC_MOV>, OpSize32;
1419 def MOV64ri32 : RIi32S<0xC7, MRM0r, (outs GR64:$dst), (ins i64i32imm:$src),
1420 "mov{q}\t{$src, $dst|$dst, $src}",
1421 [(set GR64:$dst, i64immSExt32:$src)], IIC_MOV>;
1423 let isReMaterializable = 1 in {
1424 def MOV64ri : RIi64<0xB8, AddRegFrm, (outs GR64:$dst), (ins i64imm:$src),
1425 "movabs{q}\t{$src, $dst|$dst, $src}",
1426 [(set GR64:$dst, relocImm:$src)], IIC_MOV>;
1429 // Longer forms that use a ModR/M byte. Needed for disassembler
1430 let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0 in {
1431 def MOV8ri_alt : Ii8 <0xC6, MRM0r, (outs GR8 :$dst), (ins i8imm :$src),
1432 "mov{b}\t{$src, $dst|$dst, $src}", [], IIC_MOV>;
1433 def MOV16ri_alt : Ii16<0xC7, MRM0r, (outs GR16:$dst), (ins i16imm:$src),
1434 "mov{w}\t{$src, $dst|$dst, $src}", [], IIC_MOV>, OpSize16;
1435 def MOV32ri_alt : Ii32<0xC7, MRM0r, (outs GR32:$dst), (ins i32imm:$src),
1436 "mov{l}\t{$src, $dst|$dst, $src}", [], IIC_MOV>, OpSize32;
1440 let SchedRW = [WriteStore] in {
1441 def MOV8mi : Ii8 <0xC6, MRM0m, (outs), (ins i8mem :$dst, i8imm :$src),
1442 "mov{b}\t{$src, $dst|$dst, $src}",
1443 [(store (i8 imm8_su:$src), addr:$dst)], IIC_MOV_MEM>;
1444 def MOV16mi : Ii16<0xC7, MRM0m, (outs), (ins i16mem:$dst, i16imm:$src),
1445 "mov{w}\t{$src, $dst|$dst, $src}",
1446 [(store (i16 imm16_su:$src), addr:$dst)], IIC_MOV_MEM>, OpSize16;
1447 def MOV32mi : Ii32<0xC7, MRM0m, (outs), (ins i32mem:$dst, i32imm:$src),
1448 "mov{l}\t{$src, $dst|$dst, $src}",
1449 [(store (i32 imm32_su:$src), addr:$dst)], IIC_MOV_MEM>, OpSize32;
1450 def MOV64mi32 : RIi32S<0xC7, MRM0m, (outs), (ins i64mem:$dst, i64i32imm:$src),
1451 "mov{q}\t{$src, $dst|$dst, $src}",
1452 [(store i64immSExt32_su:$src, addr:$dst)], IIC_MOV_MEM>;
1455 let hasSideEffects = 0 in {
1457 /// Memory offset versions of moves. The immediate is an address mode sized
1458 /// offset from the segment base.
1459 let SchedRW = [WriteALU] in {
1460 let mayLoad = 1 in {
1462 def MOV8ao32 : Ii32<0xA0, RawFrmMemOffs, (outs), (ins offset32_8:$src),
1463 "mov{b}\t{$src, %al|al, $src}", [], IIC_MOV_MEM>,
1466 def MOV16ao32 : Ii32<0xA1, RawFrmMemOffs, (outs), (ins offset32_16:$src),
1467 "mov{w}\t{$src, %ax|ax, $src}", [], IIC_MOV_MEM>,
1470 def MOV32ao32 : Ii32<0xA1, RawFrmMemOffs, (outs), (ins offset32_32:$src),
1471 "mov{l}\t{$src, %eax|eax, $src}", [], IIC_MOV_MEM>,
1474 def MOV64ao32 : RIi32<0xA1, RawFrmMemOffs, (outs), (ins offset32_64:$src),
1475 "mov{q}\t{$src, %rax|rax, $src}", [], IIC_MOV_MEM>,
1479 def MOV8ao16 : Ii16<0xA0, RawFrmMemOffs, (outs), (ins offset16_8:$src),
1480 "mov{b}\t{$src, %al|al, $src}", [], IIC_MOV_MEM>, AdSize16;
1482 def MOV16ao16 : Ii16<0xA1, RawFrmMemOffs, (outs), (ins offset16_16:$src),
1483 "mov{w}\t{$src, %ax|ax, $src}", [], IIC_MOV_MEM>,
1486 def MOV32ao16 : Ii16<0xA1, RawFrmMemOffs, (outs), (ins offset16_32:$src),
1487 "mov{l}\t{$src, %eax|eax, $src}", [], IIC_MOV_MEM>,
1490 let mayStore = 1 in {
1492 def MOV8o32a : Ii32<0xA2, RawFrmMemOffs, (outs), (ins offset32_8:$dst),
1493 "mov{b}\t{%al, $dst|$dst, al}", [], IIC_MOV_MEM>, AdSize32;
1495 def MOV16o32a : Ii32<0xA3, RawFrmMemOffs, (outs), (ins offset32_16:$dst),
1496 "mov{w}\t{%ax, $dst|$dst, ax}", [], IIC_MOV_MEM>,
1499 def MOV32o32a : Ii32<0xA3, RawFrmMemOffs, (outs), (ins offset32_32:$dst),
1500 "mov{l}\t{%eax, $dst|$dst, eax}", [], IIC_MOV_MEM>,
1503 def MOV64o32a : RIi32<0xA3, RawFrmMemOffs, (outs), (ins offset32_64:$dst),
1504 "mov{q}\t{%rax, $dst|$dst, rax}", [], IIC_MOV_MEM>,
1508 def MOV8o16a : Ii16<0xA2, RawFrmMemOffs, (outs), (ins offset16_8:$dst),
1509 "mov{b}\t{%al, $dst|$dst, al}", [], IIC_MOV_MEM>, AdSize16;
1511 def MOV16o16a : Ii16<0xA3, RawFrmMemOffs, (outs), (ins offset16_16:$dst),
1512 "mov{w}\t{%ax, $dst|$dst, ax}", [], IIC_MOV_MEM>,
1515 def MOV32o16a : Ii16<0xA3, RawFrmMemOffs, (outs), (ins offset16_32:$dst),
1516 "mov{l}\t{%eax, $dst|$dst, eax}", [], IIC_MOV_MEM>,
1521 // These forms all have full 64-bit absolute addresses in their instructions
1522 // and use the movabs mnemonic to indicate this specific form.
1523 let mayLoad = 1 in {
1525 def MOV8ao64 : RIi64_NOREX<0xA0, RawFrmMemOffs, (outs), (ins offset64_8:$src),
1526 "movabs{b}\t{$src, %al|al, $src}", []>, AdSize64;
1528 def MOV16ao64 : RIi64_NOREX<0xA1, RawFrmMemOffs, (outs), (ins offset64_16:$src),
1529 "movabs{w}\t{$src, %ax|ax, $src}", []>, OpSize16, AdSize64;
1531 def MOV32ao64 : RIi64_NOREX<0xA1, RawFrmMemOffs, (outs), (ins offset64_32:$src),
1532 "movabs{l}\t{$src, %eax|eax, $src}", []>, OpSize32,
1535 def MOV64ao64 : RIi64<0xA1, RawFrmMemOffs, (outs), (ins offset64_64:$src),
1536 "movabs{q}\t{$src, %rax|rax, $src}", []>, AdSize64;
1539 let mayStore = 1 in {
1541 def MOV8o64a : RIi64_NOREX<0xA2, RawFrmMemOffs, (outs), (ins offset64_8:$dst),
1542 "movabs{b}\t{%al, $dst|$dst, al}", []>, AdSize64;
1544 def MOV16o64a : RIi64_NOREX<0xA3, RawFrmMemOffs, (outs), (ins offset64_16:$dst),
1545 "movabs{w}\t{%ax, $dst|$dst, ax}", []>, OpSize16, AdSize64;
1547 def MOV32o64a : RIi64_NOREX<0xA3, RawFrmMemOffs, (outs), (ins offset64_32:$dst),
1548 "movabs{l}\t{%eax, $dst|$dst, eax}", []>, OpSize32,
1551 def MOV64o64a : RIi64<0xA3, RawFrmMemOffs, (outs), (ins offset64_64:$dst),
1552 "movabs{q}\t{%rax, $dst|$dst, rax}", []>, AdSize64;
1554 } // hasSideEffects = 0
1556 let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0,
1557 SchedRW = [WriteMove] in {
1558 def MOV8rr_REV : I<0x8A, MRMSrcReg, (outs GR8:$dst), (ins GR8:$src),
1559 "mov{b}\t{$src, $dst|$dst, $src}", [], IIC_MOV>;
1560 def MOV16rr_REV : I<0x8B, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
1561 "mov{w}\t{$src, $dst|$dst, $src}", [], IIC_MOV>, OpSize16;
1562 def MOV32rr_REV : I<0x8B, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
1563 "mov{l}\t{$src, $dst|$dst, $src}", [], IIC_MOV>, OpSize32;
1564 def MOV64rr_REV : RI<0x8B, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
1565 "mov{q}\t{$src, $dst|$dst, $src}", [], IIC_MOV>;
1568 let canFoldAsLoad = 1, isReMaterializable = 1, SchedRW = [WriteLoad] in {
1569 def MOV8rm : I<0x8A, MRMSrcMem, (outs GR8 :$dst), (ins i8mem :$src),
1570 "mov{b}\t{$src, $dst|$dst, $src}",
1571 [(set GR8:$dst, (loadi8 addr:$src))], IIC_MOV_MEM>;
1572 def MOV16rm : I<0x8B, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
1573 "mov{w}\t{$src, $dst|$dst, $src}",
1574 [(set GR16:$dst, (loadi16 addr:$src))], IIC_MOV_MEM>, OpSize16;
1575 def MOV32rm : I<0x8B, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
1576 "mov{l}\t{$src, $dst|$dst, $src}",
1577 [(set GR32:$dst, (loadi32 addr:$src))], IIC_MOV_MEM>, OpSize32;
1578 def MOV64rm : RI<0x8B, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
1579 "mov{q}\t{$src, $dst|$dst, $src}",
1580 [(set GR64:$dst, (load addr:$src))], IIC_MOV_MEM>;
1583 let SchedRW = [WriteStore] in {
1584 def MOV8mr : I<0x88, MRMDestMem, (outs), (ins i8mem :$dst, GR8 :$src),
1585 "mov{b}\t{$src, $dst|$dst, $src}",
1586 [(store GR8:$src, addr:$dst)], IIC_MOV_MEM>;
1587 def MOV16mr : I<0x89, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src),
1588 "mov{w}\t{$src, $dst|$dst, $src}",
1589 [(store GR16:$src, addr:$dst)], IIC_MOV_MEM>, OpSize16;
1590 def MOV32mr : I<0x89, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
1591 "mov{l}\t{$src, $dst|$dst, $src}",
1592 [(store GR32:$src, addr:$dst)], IIC_MOV_MEM>, OpSize32;
1593 def MOV64mr : RI<0x89, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
1594 "mov{q}\t{$src, $dst|$dst, $src}",
1595 [(store GR64:$src, addr:$dst)], IIC_MOV_MEM>;
1598 // Versions of MOV8rr, MOV8mr, and MOV8rm that use i8mem_NOREX and GR8_NOREX so
1599 // that they can be used for copying and storing h registers, which can't be
1600 // encoded when a REX prefix is present.
1601 let isCodeGenOnly = 1 in {
1602 let hasSideEffects = 0 in
1603 def MOV8rr_NOREX : I<0x88, MRMDestReg,
1604 (outs GR8_NOREX:$dst), (ins GR8_NOREX:$src),
1605 "mov{b}\t{$src, $dst|$dst, $src} # NOREX", [], IIC_MOV>,
1607 let mayStore = 1, hasSideEffects = 0 in
1608 def MOV8mr_NOREX : I<0x88, MRMDestMem,
1609 (outs), (ins i8mem_NOREX:$dst, GR8_NOREX:$src),
1610 "mov{b}\t{$src, $dst|$dst, $src} # NOREX", [],
1611 IIC_MOV_MEM>, Sched<[WriteStore]>;
1612 let mayLoad = 1, hasSideEffects = 0,
1613 canFoldAsLoad = 1, isReMaterializable = 1 in
1614 def MOV8rm_NOREX : I<0x8A, MRMSrcMem,
1615 (outs GR8_NOREX:$dst), (ins i8mem_NOREX:$src),
1616 "mov{b}\t{$src, $dst|$dst, $src} # NOREX", [],
1617 IIC_MOV_MEM>, Sched<[WriteLoad]>;
1621 // Condition code ops, incl. set if equal/not equal/...
1622 let SchedRW = [WriteALU] in {
1623 let Defs = [EFLAGS], Uses = [AH] in
1624 def SAHF : I<0x9E, RawFrm, (outs), (ins), "sahf",
1625 [(set EFLAGS, (X86sahf AH))], IIC_AHF>,
1626 Requires<[HasLAHFSAHF]>;
1627 let Defs = [AH], Uses = [EFLAGS], hasSideEffects = 0 in
1628 def LAHF : I<0x9F, RawFrm, (outs), (ins), "lahf", [],
1629 IIC_AHF>, // AH = flags
1630 Requires<[HasLAHFSAHF]>;
1633 //===----------------------------------------------------------------------===//
1634 // Bit tests instructions: BT, BTS, BTR, BTC.
1636 let Defs = [EFLAGS] in {
1637 let SchedRW = [WriteALU] in {
1638 def BT16rr : I<0xA3, MRMDestReg, (outs), (ins GR16:$src1, GR16:$src2),
1639 "bt{w}\t{$src2, $src1|$src1, $src2}",
1640 [(set EFLAGS, (X86bt GR16:$src1, GR16:$src2))], IIC_BT_RR>,
1642 def BT32rr : I<0xA3, MRMDestReg, (outs), (ins GR32:$src1, GR32:$src2),
1643 "bt{l}\t{$src2, $src1|$src1, $src2}",
1644 [(set EFLAGS, (X86bt GR32:$src1, GR32:$src2))], IIC_BT_RR>,
1646 def BT64rr : RI<0xA3, MRMDestReg, (outs), (ins GR64:$src1, GR64:$src2),
1647 "bt{q}\t{$src2, $src1|$src1, $src2}",
1648 [(set EFLAGS, (X86bt GR64:$src1, GR64:$src2))], IIC_BT_RR>, TB;
1651 // Unlike with the register+register form, the memory+register form of the
1652 // bt instruction does not ignore the high bits of the index. From ISel's
1653 // perspective, this is pretty bizarre. Make these instructions disassembly
1656 let mayLoad = 1, hasSideEffects = 0, SchedRW = [WriteALULd] in {
1657 def BT16mr : I<0xA3, MRMDestMem, (outs), (ins i16mem:$src1, GR16:$src2),
1658 "bt{w}\t{$src2, $src1|$src1, $src2}",
1659 // [(X86bt (loadi16 addr:$src1), GR16:$src2),
1660 // (implicit EFLAGS)]
1662 >, OpSize16, TB, Requires<[FastBTMem]>;
1663 def BT32mr : I<0xA3, MRMDestMem, (outs), (ins i32mem:$src1, GR32:$src2),
1664 "bt{l}\t{$src2, $src1|$src1, $src2}",
1665 // [(X86bt (loadi32 addr:$src1), GR32:$src2),
1666 // (implicit EFLAGS)]
1668 >, OpSize32, TB, Requires<[FastBTMem]>;
1669 def BT64mr : RI<0xA3, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2),
1670 "bt{q}\t{$src2, $src1|$src1, $src2}",
1671 // [(X86bt (loadi64 addr:$src1), GR64:$src2),
1672 // (implicit EFLAGS)]
1677 let SchedRW = [WriteALU] in {
1678 def BT16ri8 : Ii8<0xBA, MRM4r, (outs), (ins GR16:$src1, i16i8imm:$src2),
1679 "bt{w}\t{$src2, $src1|$src1, $src2}",
1680 [(set EFLAGS, (X86bt GR16:$src1, i16immSExt8:$src2))],
1681 IIC_BT_RI>, OpSize16, TB;
1682 def BT32ri8 : Ii8<0xBA, MRM4r, (outs), (ins GR32:$src1, i32i8imm:$src2),
1683 "bt{l}\t{$src2, $src1|$src1, $src2}",
1684 [(set EFLAGS, (X86bt GR32:$src1, i32immSExt8:$src2))],
1685 IIC_BT_RI>, OpSize32, TB;
1686 def BT64ri8 : RIi8<0xBA, MRM4r, (outs), (ins GR64:$src1, i64i8imm:$src2),
1687 "bt{q}\t{$src2, $src1|$src1, $src2}",
1688 [(set EFLAGS, (X86bt GR64:$src1, i64immSExt8:$src2))],
1692 // Note that these instructions don't need FastBTMem because that
1693 // only applies when the other operand is in a register. When it's
1694 // an immediate, bt is still fast.
1695 let SchedRW = [WriteALU] in {
1696 def BT16mi8 : Ii8<0xBA, MRM4m, (outs), (ins i16mem:$src1, i16i8imm:$src2),
1697 "bt{w}\t{$src2, $src1|$src1, $src2}",
1698 [(set EFLAGS, (X86bt (loadi16 addr:$src1), i16immSExt8:$src2))
1699 ], IIC_BT_MI>, OpSize16, TB;
1700 def BT32mi8 : Ii8<0xBA, MRM4m, (outs), (ins i32mem:$src1, i32i8imm:$src2),
1701 "bt{l}\t{$src2, $src1|$src1, $src2}",
1702 [(set EFLAGS, (X86bt (loadi32 addr:$src1), i32immSExt8:$src2))
1703 ], IIC_BT_MI>, OpSize32, TB;
1704 def BT64mi8 : RIi8<0xBA, MRM4m, (outs), (ins i64mem:$src1, i64i8imm:$src2),
1705 "bt{q}\t{$src2, $src1|$src1, $src2}",
1706 [(set EFLAGS, (X86bt (loadi64 addr:$src1),
1707 i64immSExt8:$src2))], IIC_BT_MI>, TB;
1710 let hasSideEffects = 0 in {
1711 let SchedRW = [WriteALU] in {
1712 def BTC16rr : I<0xBB, MRMDestReg, (outs), (ins GR16:$src1, GR16:$src2),
1713 "btc{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>,
1715 def BTC32rr : I<0xBB, MRMDestReg, (outs), (ins GR32:$src1, GR32:$src2),
1716 "btc{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>,
1718 def BTC64rr : RI<0xBB, MRMDestReg, (outs), (ins GR64:$src1, GR64:$src2),
1719 "btc{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>, TB;
1722 let mayLoad = 1, mayStore = 1, SchedRW = [WriteALULd, WriteRMW] in {
1723 def BTC16mr : I<0xBB, MRMDestMem, (outs), (ins i16mem:$src1, GR16:$src2),
1724 "btc{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>,
1726 def BTC32mr : I<0xBB, MRMDestMem, (outs), (ins i32mem:$src1, GR32:$src2),
1727 "btc{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>,
1729 def BTC64mr : RI<0xBB, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2),
1730 "btc{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>, TB;
1733 let SchedRW = [WriteALU] in {
1734 def BTC16ri8 : Ii8<0xBA, MRM7r, (outs), (ins GR16:$src1, i16i8imm:$src2),
1735 "btc{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>,
1737 def BTC32ri8 : Ii8<0xBA, MRM7r, (outs), (ins GR32:$src1, i32i8imm:$src2),
1738 "btc{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>,
1740 def BTC64ri8 : RIi8<0xBA, MRM7r, (outs), (ins GR64:$src1, i64i8imm:$src2),
1741 "btc{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>, TB;
1744 let mayLoad = 1, mayStore = 1, SchedRW = [WriteALULd, WriteRMW] in {
1745 def BTC16mi8 : Ii8<0xBA, MRM7m, (outs), (ins i16mem:$src1, i16i8imm:$src2),
1746 "btc{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>,
1748 def BTC32mi8 : Ii8<0xBA, MRM7m, (outs), (ins i32mem:$src1, i32i8imm:$src2),
1749 "btc{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>,
1751 def BTC64mi8 : RIi8<0xBA, MRM7m, (outs), (ins i64mem:$src1, i64i8imm:$src2),
1752 "btc{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>, TB;
1755 let SchedRW = [WriteALU] in {
1756 def BTR16rr : I<0xB3, MRMDestReg, (outs), (ins GR16:$src1, GR16:$src2),
1757 "btr{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>,
1759 def BTR32rr : I<0xB3, MRMDestReg, (outs), (ins GR32:$src1, GR32:$src2),
1760 "btr{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>,
1762 def BTR64rr : RI<0xB3, MRMDestReg, (outs), (ins GR64:$src1, GR64:$src2),
1763 "btr{q}\t{$src2, $src1|$src1, $src2}", []>, TB;
1766 let mayLoad = 1, mayStore = 1, SchedRW = [WriteALULd, WriteRMW] in {
1767 def BTR16mr : I<0xB3, MRMDestMem, (outs), (ins i16mem:$src1, GR16:$src2),
1768 "btr{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>,
1770 def BTR32mr : I<0xB3, MRMDestMem, (outs), (ins i32mem:$src1, GR32:$src2),
1771 "btr{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>,
1773 def BTR64mr : RI<0xB3, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2),
1774 "btr{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>, TB;
1777 let SchedRW = [WriteALU] in {
1778 def BTR16ri8 : Ii8<0xBA, MRM6r, (outs), (ins GR16:$src1, i16i8imm:$src2),
1779 "btr{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>,
1781 def BTR32ri8 : Ii8<0xBA, MRM6r, (outs), (ins GR32:$src1, i32i8imm:$src2),
1782 "btr{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>,
1784 def BTR64ri8 : RIi8<0xBA, MRM6r, (outs), (ins GR64:$src1, i64i8imm:$src2),
1785 "btr{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>, TB;
1788 let mayLoad = 1, mayStore = 1, SchedRW = [WriteALULd, WriteRMW] in {
1789 def BTR16mi8 : Ii8<0xBA, MRM6m, (outs), (ins i16mem:$src1, i16i8imm:$src2),
1790 "btr{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>,
1792 def BTR32mi8 : Ii8<0xBA, MRM6m, (outs), (ins i32mem:$src1, i32i8imm:$src2),
1793 "btr{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>,
1795 def BTR64mi8 : RIi8<0xBA, MRM6m, (outs), (ins i64mem:$src1, i64i8imm:$src2),
1796 "btr{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>, TB;
1799 let SchedRW = [WriteALU] in {
1800 def BTS16rr : I<0xAB, MRMDestReg, (outs), (ins GR16:$src1, GR16:$src2),
1801 "bts{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>,
1803 def BTS32rr : I<0xAB, MRMDestReg, (outs), (ins GR32:$src1, GR32:$src2),
1804 "bts{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>,
1806 def BTS64rr : RI<0xAB, MRMDestReg, (outs), (ins GR64:$src1, GR64:$src2),
1807 "bts{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>, TB;
1810 let mayLoad = 1, mayStore = 1, SchedRW = [WriteALULd, WriteRMW] in {
1811 def BTS16mr : I<0xAB, MRMDestMem, (outs), (ins i16mem:$src1, GR16:$src2),
1812 "bts{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>,
1814 def BTS32mr : I<0xAB, MRMDestMem, (outs), (ins i32mem:$src1, GR32:$src2),
1815 "bts{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>,
1817 def BTS64mr : RI<0xAB, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2),
1818 "bts{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>, TB;
1821 let SchedRW = [WriteALU] in {
1822 def BTS16ri8 : Ii8<0xBA, MRM5r, (outs), (ins GR16:$src1, i16i8imm:$src2),
1823 "bts{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>,
1825 def BTS32ri8 : Ii8<0xBA, MRM5r, (outs), (ins GR32:$src1, i32i8imm:$src2),
1826 "bts{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>,
1828 def BTS64ri8 : RIi8<0xBA, MRM5r, (outs), (ins GR64:$src1, i64i8imm:$src2),
1829 "bts{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>, TB;
1832 let mayLoad = 1, mayStore = 1, SchedRW = [WriteALULd, WriteRMW] in {
1833 def BTS16mi8 : Ii8<0xBA, MRM5m, (outs), (ins i16mem:$src1, i16i8imm:$src2),
1834 "bts{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>,
1836 def BTS32mi8 : Ii8<0xBA, MRM5m, (outs), (ins i32mem:$src1, i32i8imm:$src2),
1837 "bts{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>,
1839 def BTS64mi8 : RIi8<0xBA, MRM5m, (outs), (ins i64mem:$src1, i64i8imm:$src2),
1840 "bts{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>, TB;
1842 } // hasSideEffects = 0
1843 } // Defs = [EFLAGS]
1846 //===----------------------------------------------------------------------===//
1850 // Atomic swap. These are just normal xchg instructions. But since a memory
1851 // operand is referenced, the atomicity is ensured.
1852 multiclass ATOMIC_SWAP<bits<8> opc8, bits<8> opc, string mnemonic, string frag,
1853 InstrItinClass itin> {
1854 let Constraints = "$val = $dst", SchedRW = [WriteALULd, WriteRMW] in {
1855 def NAME#8rm : I<opc8, MRMSrcMem, (outs GR8:$dst),
1856 (ins GR8:$val, i8mem:$ptr),
1857 !strconcat(mnemonic, "{b}\t{$val, $ptr|$ptr, $val}"),
1860 (!cast<PatFrag>(frag # "_8") addr:$ptr, GR8:$val))],
1862 def NAME#16rm : I<opc, MRMSrcMem, (outs GR16:$dst),
1863 (ins GR16:$val, i16mem:$ptr),
1864 !strconcat(mnemonic, "{w}\t{$val, $ptr|$ptr, $val}"),
1867 (!cast<PatFrag>(frag # "_16") addr:$ptr, GR16:$val))],
1869 def NAME#32rm : I<opc, MRMSrcMem, (outs GR32:$dst),
1870 (ins GR32:$val, i32mem:$ptr),
1871 !strconcat(mnemonic, "{l}\t{$val, $ptr|$ptr, $val}"),
1874 (!cast<PatFrag>(frag # "_32") addr:$ptr, GR32:$val))],
1876 def NAME#64rm : RI<opc, MRMSrcMem, (outs GR64:$dst),
1877 (ins GR64:$val, i64mem:$ptr),
1878 !strconcat(mnemonic, "{q}\t{$val, $ptr|$ptr, $val}"),
1881 (!cast<PatFrag>(frag # "_64") addr:$ptr, GR64:$val))],
1886 defm XCHG : ATOMIC_SWAP<0x86, 0x87, "xchg", "atomic_swap", IIC_XCHG_MEM>;
1888 // Swap between registers.
1889 let SchedRW = [WriteALU] in {
1890 let Constraints = "$val = $dst" in {
1891 def XCHG8rr : I<0x86, MRMSrcReg, (outs GR8:$dst), (ins GR8:$val, GR8:$src),
1892 "xchg{b}\t{$val, $src|$src, $val}", [], IIC_XCHG_REG>;
1893 def XCHG16rr : I<0x87, MRMSrcReg, (outs GR16:$dst), (ins GR16:$val, GR16:$src),
1894 "xchg{w}\t{$val, $src|$src, $val}", [], IIC_XCHG_REG>,
1896 def XCHG32rr : I<0x87, MRMSrcReg, (outs GR32:$dst), (ins GR32:$val, GR32:$src),
1897 "xchg{l}\t{$val, $src|$src, $val}", [], IIC_XCHG_REG>,
1899 def XCHG64rr : RI<0x87, MRMSrcReg, (outs GR64:$dst), (ins GR64:$val,GR64:$src),
1900 "xchg{q}\t{$val, $src|$src, $val}", [], IIC_XCHG_REG>;
1903 // Swap between EAX and other registers.
1904 let Uses = [AX], Defs = [AX] in
1905 def XCHG16ar : I<0x90, AddRegFrm, (outs), (ins GR16:$src),
1906 "xchg{w}\t{$src, %ax|ax, $src}", [], IIC_XCHG_REG>, OpSize16;
1907 let Uses = [EAX], Defs = [EAX] in
1908 def XCHG32ar : I<0x90, AddRegFrm, (outs), (ins GR32:$src),
1909 "xchg{l}\t{$src, %eax|eax, $src}", [], IIC_XCHG_REG>,
1910 OpSize32, Requires<[Not64BitMode]>;
1911 let Uses = [EAX], Defs = [EAX] in
1912 // Uses GR32_NOAX in 64-bit mode to prevent encoding using the 0x90 NOP encoding.
1913 // xchg %eax, %eax needs to clear upper 32-bits of RAX so is not a NOP.
1914 def XCHG32ar64 : I<0x90, AddRegFrm, (outs), (ins GR32_NOAX:$src),
1915 "xchg{l}\t{$src, %eax|eax, $src}", [], IIC_XCHG_REG>,
1916 OpSize32, Requires<[In64BitMode]>;
1917 let Uses = [RAX], Defs = [RAX] in
1918 def XCHG64ar : RI<0x90, AddRegFrm, (outs), (ins GR64:$src),
1919 "xchg{q}\t{$src, %rax|rax, $src}", [], IIC_XCHG_REG>;
1922 let SchedRW = [WriteALU] in {
1923 def XADD8rr : I<0xC0, MRMDestReg, (outs GR8:$dst), (ins GR8:$src),
1924 "xadd{b}\t{$src, $dst|$dst, $src}", [], IIC_XADD_REG>, TB;
1925 def XADD16rr : I<0xC1, MRMDestReg, (outs GR16:$dst), (ins GR16:$src),
1926 "xadd{w}\t{$src, $dst|$dst, $src}", [], IIC_XADD_REG>, TB,
1928 def XADD32rr : I<0xC1, MRMDestReg, (outs GR32:$dst), (ins GR32:$src),
1929 "xadd{l}\t{$src, $dst|$dst, $src}", [], IIC_XADD_REG>, TB,
1931 def XADD64rr : RI<0xC1, MRMDestReg, (outs GR64:$dst), (ins GR64:$src),
1932 "xadd{q}\t{$src, $dst|$dst, $src}", [], IIC_XADD_REG>, TB;
1935 let mayLoad = 1, mayStore = 1, SchedRW = [WriteALULd, WriteRMW] in {
1936 def XADD8rm : I<0xC0, MRMDestMem, (outs), (ins i8mem:$dst, GR8:$src),
1937 "xadd{b}\t{$src, $dst|$dst, $src}", [], IIC_XADD_MEM>, TB;
1938 def XADD16rm : I<0xC1, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src),
1939 "xadd{w}\t{$src, $dst|$dst, $src}", [], IIC_XADD_MEM>, TB,
1941 def XADD32rm : I<0xC1, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
1942 "xadd{l}\t{$src, $dst|$dst, $src}", [], IIC_XADD_MEM>, TB,
1944 def XADD64rm : RI<0xC1, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
1945 "xadd{q}\t{$src, $dst|$dst, $src}", [], IIC_XADD_MEM>, TB;
1949 let SchedRW = [WriteALU] in {
1950 def CMPXCHG8rr : I<0xB0, MRMDestReg, (outs GR8:$dst), (ins GR8:$src),
1951 "cmpxchg{b}\t{$src, $dst|$dst, $src}", [],
1952 IIC_CMPXCHG_REG8>, TB;
1953 def CMPXCHG16rr : I<0xB1, MRMDestReg, (outs GR16:$dst), (ins GR16:$src),
1954 "cmpxchg{w}\t{$src, $dst|$dst, $src}", [],
1955 IIC_CMPXCHG_REG>, TB, OpSize16;
1956 def CMPXCHG32rr : I<0xB1, MRMDestReg, (outs GR32:$dst), (ins GR32:$src),
1957 "cmpxchg{l}\t{$src, $dst|$dst, $src}", [],
1958 IIC_CMPXCHG_REG>, TB, OpSize32;
1959 def CMPXCHG64rr : RI<0xB1, MRMDestReg, (outs GR64:$dst), (ins GR64:$src),
1960 "cmpxchg{q}\t{$src, $dst|$dst, $src}", [],
1961 IIC_CMPXCHG_REG>, TB;
1964 let SchedRW = [WriteALULd, WriteRMW] in {
1965 let mayLoad = 1, mayStore = 1 in {
1966 def CMPXCHG8rm : I<0xB0, MRMDestMem, (outs), (ins i8mem:$dst, GR8:$src),
1967 "cmpxchg{b}\t{$src, $dst|$dst, $src}", [],
1968 IIC_CMPXCHG_MEM8>, TB;
1969 def CMPXCHG16rm : I<0xB1, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src),
1970 "cmpxchg{w}\t{$src, $dst|$dst, $src}", [],
1971 IIC_CMPXCHG_MEM>, TB, OpSize16;
1972 def CMPXCHG32rm : I<0xB1, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
1973 "cmpxchg{l}\t{$src, $dst|$dst, $src}", [],
1974 IIC_CMPXCHG_MEM>, TB, OpSize32;
1975 def CMPXCHG64rm : RI<0xB1, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
1976 "cmpxchg{q}\t{$src, $dst|$dst, $src}", [],
1977 IIC_CMPXCHG_MEM>, TB;
1980 let Defs = [EAX, EDX, EFLAGS], Uses = [EAX, EBX, ECX, EDX] in
1981 def CMPXCHG8B : I<0xC7, MRM1m, (outs), (ins i64mem:$dst),
1982 "cmpxchg8b\t$dst", [], IIC_CMPXCHG_8B>, TB;
1984 let Defs = [RAX, RDX, EFLAGS], Uses = [RAX, RBX, RCX, RDX] in
1985 def CMPXCHG16B : RI<0xC7, MRM1m, (outs), (ins i128mem:$dst),
1986 "cmpxchg16b\t$dst", [], IIC_CMPXCHG_16B>,
1987 TB, Requires<[HasCmpxchg16b]>;
1991 // Lock instruction prefix
1992 def LOCK_PREFIX : I<0xF0, RawFrm, (outs), (ins), "lock", []>;
1994 // Rex64 instruction prefix
1995 def REX64_PREFIX : I<0x48, RawFrm, (outs), (ins), "rex64", []>,
1996 Requires<[In64BitMode]>;
1998 // Data16 instruction prefix
1999 def DATA16_PREFIX : I<0x66, RawFrm, (outs), (ins), "data16", []>,
2000 Requires<[Not16BitMode]>;
2002 // Data instruction prefix
2003 def DATA32_PREFIX : I<0x66, RawFrm, (outs), (ins), "data32", []>,
2004 Requires<[In16BitMode]>;
2006 // Repeat string operation instruction prefixes
2007 // These uses the DF flag in the EFLAGS register to inc or dec ECX
2008 let Defs = [ECX], Uses = [ECX,EFLAGS] in {
2009 // Repeat (used with INS, OUTS, MOVS, LODS and STOS)
2010 def REP_PREFIX : I<0xF3, RawFrm, (outs), (ins), "rep", []>;
2011 // Repeat while not equal (used with CMPS and SCAS)
2012 def REPNE_PREFIX : I<0xF2, RawFrm, (outs), (ins), "repne", []>;
2016 // String manipulation instructions
2017 let SchedRW = [WriteMicrocoded] in {
2018 // These uses the DF flag in the EFLAGS register to inc or dec EDI and ESI
2019 let Defs = [AL,ESI], Uses = [ESI,EFLAGS] in
2020 def LODSB : I<0xAC, RawFrmSrc, (outs), (ins srcidx8:$src),
2021 "lodsb\t{$src, %al|al, $src}", [], IIC_LODS>;
2022 let Defs = [AX,ESI], Uses = [ESI,EFLAGS] in
2023 def LODSW : I<0xAD, RawFrmSrc, (outs), (ins srcidx16:$src),
2024 "lodsw\t{$src, %ax|ax, $src}", [], IIC_LODS>, OpSize16;
2025 let Defs = [EAX,ESI], Uses = [ESI,EFLAGS] in
2026 def LODSL : I<0xAD, RawFrmSrc, (outs), (ins srcidx32:$src),
2027 "lods{l|d}\t{$src, %eax|eax, $src}", [], IIC_LODS>, OpSize32;
2028 let Defs = [RAX,ESI], Uses = [ESI,EFLAGS] in
2029 def LODSQ : RI<0xAD, RawFrmSrc, (outs), (ins srcidx64:$src),
2030 "lodsq\t{$src, %rax|rax, $src}", [], IIC_LODS>;
2033 let SchedRW = [WriteSystem] in {
2034 // These uses the DF flag in the EFLAGS register to inc or dec EDI and ESI
2035 let Defs = [ESI], Uses = [DX,ESI,EFLAGS] in {
2036 def OUTSB : I<0x6E, RawFrmSrc, (outs), (ins srcidx8:$src),
2037 "outsb\t{$src, %dx|dx, $src}", [], IIC_OUTS>;
2038 def OUTSW : I<0x6F, RawFrmSrc, (outs), (ins srcidx16:$src),
2039 "outsw\t{$src, %dx|dx, $src}", [], IIC_OUTS>, OpSize16;
2040 def OUTSL : I<0x6F, RawFrmSrc, (outs), (ins srcidx32:$src),
2041 "outs{l|d}\t{$src, %dx|dx, $src}", [], IIC_OUTS>, OpSize32;
2044 // These uses the DF flag in the EFLAGS register to inc or dec EDI and ESI
2045 let Defs = [EDI], Uses = [DX,EDI,EFLAGS] in {
2046 def INSB : I<0x6C, RawFrmDst, (outs), (ins dstidx8:$dst),
2047 "insb\t{%dx, $dst|$dst, dx}", [], IIC_INS>;
2048 def INSW : I<0x6D, RawFrmDst, (outs), (ins dstidx16:$dst),
2049 "insw\t{%dx, $dst|$dst, dx}", [], IIC_INS>, OpSize16;
2050 def INSL : I<0x6D, RawFrmDst, (outs), (ins dstidx32:$dst),
2051 "ins{l|d}\t{%dx, $dst|$dst, dx}", [], IIC_INS>, OpSize32;
2055 // Flag instructions
2056 let SchedRW = [WriteALU] in {
2057 def CLC : I<0xF8, RawFrm, (outs), (ins), "clc", [], IIC_CLC>;
2058 def STC : I<0xF9, RawFrm, (outs), (ins), "stc", [], IIC_STC>;
2059 def CLI : I<0xFA, RawFrm, (outs), (ins), "cli", [], IIC_CLI>;
2060 def STI : I<0xFB, RawFrm, (outs), (ins), "sti", [], IIC_STI>;
2061 def CLD : I<0xFC, RawFrm, (outs), (ins), "cld", [], IIC_CLD>;
2062 def STD : I<0xFD, RawFrm, (outs), (ins), "std", [], IIC_STD>;
2063 def CMC : I<0xF5, RawFrm, (outs), (ins), "cmc", [], IIC_CMC>;
2065 def CLTS : I<0x06, RawFrm, (outs), (ins), "clts", [], IIC_CLTS>, TB;
2068 // Table lookup instructions
2069 let Uses = [AL,EBX], Defs = [AL], hasSideEffects = 0, mayLoad = 1 in
2070 def XLAT : I<0xD7, RawFrm, (outs), (ins), "xlatb", [], IIC_XLAT>,
2073 let SchedRW = [WriteMicrocoded] in {
2074 // ASCII Adjust After Addition
2075 let Uses = [AL,EFLAGS], Defs = [AX,EFLAGS], hasSideEffects = 0 in
2076 def AAA : I<0x37, RawFrm, (outs), (ins), "aaa", [], IIC_AAA>,
2077 Requires<[Not64BitMode]>;
2079 // ASCII Adjust AX Before Division
2080 let Uses = [AX], Defs = [AX,EFLAGS], hasSideEffects = 0 in
2081 def AAD8i8 : Ii8<0xD5, RawFrm, (outs), (ins i8imm:$src),
2082 "aad\t$src", [], IIC_AAD>, Requires<[Not64BitMode]>;
2084 // ASCII Adjust AX After Multiply
2085 let Uses = [AL], Defs = [AX,EFLAGS], hasSideEffects = 0 in
2086 def AAM8i8 : Ii8<0xD4, RawFrm, (outs), (ins i8imm:$src),
2087 "aam\t$src", [], IIC_AAM>, Requires<[Not64BitMode]>;
2089 // ASCII Adjust AL After Subtraction - sets
2090 let Uses = [AL,EFLAGS], Defs = [AX,EFLAGS], hasSideEffects = 0 in
2091 def AAS : I<0x3F, RawFrm, (outs), (ins), "aas", [], IIC_AAS>,
2092 Requires<[Not64BitMode]>;
2094 // Decimal Adjust AL after Addition
2095 let Uses = [AL,EFLAGS], Defs = [AL,EFLAGS], hasSideEffects = 0 in
2096 def DAA : I<0x27, RawFrm, (outs), (ins), "daa", [], IIC_DAA>,
2097 Requires<[Not64BitMode]>;
2099 // Decimal Adjust AL after Subtraction
2100 let Uses = [AL,EFLAGS], Defs = [AL,EFLAGS], hasSideEffects = 0 in
2101 def DAS : I<0x2F, RawFrm, (outs), (ins), "das", [], IIC_DAS>,
2102 Requires<[Not64BitMode]>;
2105 let SchedRW = [WriteSystem] in {
2106 // Check Array Index Against Bounds
2107 def BOUNDS16rm : I<0x62, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
2108 "bound\t{$src, $dst|$dst, $src}", [], IIC_BOUND>, OpSize16,
2109 Requires<[Not64BitMode]>;
2110 def BOUNDS32rm : I<0x62, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
2111 "bound\t{$src, $dst|$dst, $src}", [], IIC_BOUND>, OpSize32,
2112 Requires<[Not64BitMode]>;
2114 // Adjust RPL Field of Segment Selector
2115 def ARPL16rr : I<0x63, MRMDestReg, (outs GR16:$dst), (ins GR16:$src),
2116 "arpl\t{$src, $dst|$dst, $src}", [], IIC_ARPL_REG>,
2117 Requires<[Not64BitMode]>;
2119 def ARPL16mr : I<0x63, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src),
2120 "arpl\t{$src, $dst|$dst, $src}", [], IIC_ARPL_MEM>,
2121 Requires<[Not64BitMode]>;
2124 //===----------------------------------------------------------------------===//
2125 // MOVBE Instructions
2127 let Predicates = [HasMOVBE] in {
2128 let SchedRW = [WriteALULd] in {
2129 def MOVBE16rm : I<0xF0, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
2130 "movbe{w}\t{$src, $dst|$dst, $src}",
2131 [(set GR16:$dst, (bswap (loadi16 addr:$src)))], IIC_MOVBE>,
2133 def MOVBE32rm : I<0xF0, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
2134 "movbe{l}\t{$src, $dst|$dst, $src}",
2135 [(set GR32:$dst, (bswap (loadi32 addr:$src)))], IIC_MOVBE>,
2137 def MOVBE64rm : RI<0xF0, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
2138 "movbe{q}\t{$src, $dst|$dst, $src}",
2139 [(set GR64:$dst, (bswap (loadi64 addr:$src)))], IIC_MOVBE>,
2142 let SchedRW = [WriteStore] in {
2143 def MOVBE16mr : I<0xF1, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src),
2144 "movbe{w}\t{$src, $dst|$dst, $src}",
2145 [(store (bswap GR16:$src), addr:$dst)], IIC_MOVBE>,
2147 def MOVBE32mr : I<0xF1, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
2148 "movbe{l}\t{$src, $dst|$dst, $src}",
2149 [(store (bswap GR32:$src), addr:$dst)], IIC_MOVBE>,
2151 def MOVBE64mr : RI<0xF1, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
2152 "movbe{q}\t{$src, $dst|$dst, $src}",
2153 [(store (bswap GR64:$src), addr:$dst)], IIC_MOVBE>,
2158 //===----------------------------------------------------------------------===//
2159 // RDRAND Instruction
2161 let Predicates = [HasRDRAND], Defs = [EFLAGS] in {
2162 def RDRAND16r : I<0xC7, MRM6r, (outs GR16:$dst), (ins),
2164 [(set GR16:$dst, EFLAGS, (X86rdrand))]>, OpSize16, TB;
2165 def RDRAND32r : I<0xC7, MRM6r, (outs GR32:$dst), (ins),
2167 [(set GR32:$dst, EFLAGS, (X86rdrand))]>, OpSize32, TB;
2168 def RDRAND64r : RI<0xC7, MRM6r, (outs GR64:$dst), (ins),
2170 [(set GR64:$dst, EFLAGS, (X86rdrand))]>, TB;
2173 //===----------------------------------------------------------------------===//
2174 // RDSEED Instruction
2176 let Predicates = [HasRDSEED], Defs = [EFLAGS] in {
2177 def RDSEED16r : I<0xC7, MRM7r, (outs GR16:$dst), (ins),
2179 [(set GR16:$dst, EFLAGS, (X86rdseed))]>, OpSize16, TB;
2180 def RDSEED32r : I<0xC7, MRM7r, (outs GR32:$dst), (ins),
2182 [(set GR32:$dst, EFLAGS, (X86rdseed))]>, OpSize32, TB;
2183 def RDSEED64r : RI<0xC7, MRM7r, (outs GR64:$dst), (ins),
2185 [(set GR64:$dst, EFLAGS, (X86rdseed))]>, TB;
2188 //===----------------------------------------------------------------------===//
2189 // LZCNT Instruction
2191 let Predicates = [HasLZCNT], Defs = [EFLAGS] in {
2192 def LZCNT16rr : I<0xBD, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
2193 "lzcnt{w}\t{$src, $dst|$dst, $src}",
2194 [(set GR16:$dst, (ctlz GR16:$src)), (implicit EFLAGS)]>, XS,
2196 def LZCNT16rm : I<0xBD, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
2197 "lzcnt{w}\t{$src, $dst|$dst, $src}",
2198 [(set GR16:$dst, (ctlz (loadi16 addr:$src))),
2199 (implicit EFLAGS)]>, XS, OpSize16;
2201 def LZCNT32rr : I<0xBD, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
2202 "lzcnt{l}\t{$src, $dst|$dst, $src}",
2203 [(set GR32:$dst, (ctlz GR32:$src)), (implicit EFLAGS)]>, XS,
2205 def LZCNT32rm : I<0xBD, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
2206 "lzcnt{l}\t{$src, $dst|$dst, $src}",
2207 [(set GR32:$dst, (ctlz (loadi32 addr:$src))),
2208 (implicit EFLAGS)]>, XS, OpSize32;
2210 def LZCNT64rr : RI<0xBD, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
2211 "lzcnt{q}\t{$src, $dst|$dst, $src}",
2212 [(set GR64:$dst, (ctlz GR64:$src)), (implicit EFLAGS)]>,
2214 def LZCNT64rm : RI<0xBD, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
2215 "lzcnt{q}\t{$src, $dst|$dst, $src}",
2216 [(set GR64:$dst, (ctlz (loadi64 addr:$src))),
2217 (implicit EFLAGS)]>, XS;
2220 //===----------------------------------------------------------------------===//
2223 let Predicates = [HasBMI], Defs = [EFLAGS] in {
2224 def TZCNT16rr : I<0xBC, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
2225 "tzcnt{w}\t{$src, $dst|$dst, $src}",
2226 [(set GR16:$dst, (cttz GR16:$src)), (implicit EFLAGS)]>, XS,
2228 def TZCNT16rm : I<0xBC, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
2229 "tzcnt{w}\t{$src, $dst|$dst, $src}",
2230 [(set GR16:$dst, (cttz (loadi16 addr:$src))),
2231 (implicit EFLAGS)]>, XS, OpSize16;
2233 def TZCNT32rr : I<0xBC, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
2234 "tzcnt{l}\t{$src, $dst|$dst, $src}",
2235 [(set GR32:$dst, (cttz GR32:$src)), (implicit EFLAGS)]>, XS,
2237 def TZCNT32rm : I<0xBC, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
2238 "tzcnt{l}\t{$src, $dst|$dst, $src}",
2239 [(set GR32:$dst, (cttz (loadi32 addr:$src))),
2240 (implicit EFLAGS)]>, XS, OpSize32;
2242 def TZCNT64rr : RI<0xBC, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
2243 "tzcnt{q}\t{$src, $dst|$dst, $src}",
2244 [(set GR64:$dst, (cttz GR64:$src)), (implicit EFLAGS)]>,
2246 def TZCNT64rm : RI<0xBC, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
2247 "tzcnt{q}\t{$src, $dst|$dst, $src}",
2248 [(set GR64:$dst, (cttz (loadi64 addr:$src))),
2249 (implicit EFLAGS)]>, XS;
2252 multiclass bmi_bls<string mnemonic, Format RegMRM, Format MemMRM,
2253 RegisterClass RC, X86MemOperand x86memop> {
2254 let hasSideEffects = 0 in {
2255 def rr : I<0xF3, RegMRM, (outs RC:$dst), (ins RC:$src),
2256 !strconcat(mnemonic, "\t{$src, $dst|$dst, $src}"),
2259 def rm : I<0xF3, MemMRM, (outs RC:$dst), (ins x86memop:$src),
2260 !strconcat(mnemonic, "\t{$src, $dst|$dst, $src}"),
2265 let Predicates = [HasBMI], Defs = [EFLAGS] in {
2266 defm BLSR32 : bmi_bls<"blsr{l}", MRM1r, MRM1m, GR32, i32mem>;
2267 defm BLSR64 : bmi_bls<"blsr{q}", MRM1r, MRM1m, GR64, i64mem>, VEX_W;
2268 defm BLSMSK32 : bmi_bls<"blsmsk{l}", MRM2r, MRM2m, GR32, i32mem>;
2269 defm BLSMSK64 : bmi_bls<"blsmsk{q}", MRM2r, MRM2m, GR64, i64mem>, VEX_W;
2270 defm BLSI32 : bmi_bls<"blsi{l}", MRM3r, MRM3m, GR32, i32mem>;
2271 defm BLSI64 : bmi_bls<"blsi{q}", MRM3r, MRM3m, GR64, i64mem>, VEX_W;
2274 //===----------------------------------------------------------------------===//
2275 // Pattern fragments to auto generate BMI instructions.
2276 //===----------------------------------------------------------------------===//
2278 let Predicates = [HasBMI] in {
2279 // FIXME: patterns for the load versions are not implemented
2280 def : Pat<(and GR32:$src, (add GR32:$src, -1)),
2281 (BLSR32rr GR32:$src)>;
2282 def : Pat<(and GR64:$src, (add GR64:$src, -1)),
2283 (BLSR64rr GR64:$src)>;
2285 def : Pat<(xor GR32:$src, (add GR32:$src, -1)),
2286 (BLSMSK32rr GR32:$src)>;
2287 def : Pat<(xor GR64:$src, (add GR64:$src, -1)),
2288 (BLSMSK64rr GR64:$src)>;
2290 def : Pat<(and GR32:$src, (ineg GR32:$src)),
2291 (BLSI32rr GR32:$src)>;
2292 def : Pat<(and GR64:$src, (ineg GR64:$src)),
2293 (BLSI64rr GR64:$src)>;
2297 multiclass bmi_bextr_bzhi<bits<8> opc, string mnemonic, RegisterClass RC,
2298 X86MemOperand x86memop, Intrinsic Int,
2300 def rr : I<opc, MRMSrcReg4VOp3, (outs RC:$dst), (ins RC:$src1, RC:$src2),
2301 !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2302 [(set RC:$dst, (Int RC:$src1, RC:$src2)), (implicit EFLAGS)]>,
2304 def rm : I<opc, MRMSrcMem4VOp3, (outs RC:$dst), (ins x86memop:$src1, RC:$src2),
2305 !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2306 [(set RC:$dst, (Int (ld_frag addr:$src1), RC:$src2)),
2307 (implicit EFLAGS)]>, T8PS, VEX;
2310 let Predicates = [HasBMI], Defs = [EFLAGS] in {
2311 defm BEXTR32 : bmi_bextr_bzhi<0xF7, "bextr{l}", GR32, i32mem,
2312 int_x86_bmi_bextr_32, loadi32>;
2313 defm BEXTR64 : bmi_bextr_bzhi<0xF7, "bextr{q}", GR64, i64mem,
2314 int_x86_bmi_bextr_64, loadi64>, VEX_W;
2317 let Predicates = [HasBMI2], Defs = [EFLAGS] in {
2318 defm BZHI32 : bmi_bextr_bzhi<0xF5, "bzhi{l}", GR32, i32mem,
2319 int_x86_bmi_bzhi_32, loadi32>;
2320 defm BZHI64 : bmi_bextr_bzhi<0xF5, "bzhi{q}", GR64, i64mem,
2321 int_x86_bmi_bzhi_64, loadi64>, VEX_W;
2325 def CountTrailingOnes : SDNodeXForm<imm, [{
2326 // Count the trailing ones in the immediate.
2327 return getI8Imm(countTrailingOnes(N->getZExtValue()), SDLoc(N));
2330 def BZHIMask : ImmLeaf<i64, [{
2331 return isMask_64(Imm) && (countTrailingOnes<uint64_t>(Imm) > 32);
2334 let Predicates = [HasBMI2] in {
2335 def : Pat<(and GR64:$src, BZHIMask:$mask),
2336 (BZHI64rr GR64:$src,
2337 (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
2338 (MOV8ri (CountTrailingOnes imm:$mask)), sub_8bit))>;
2340 def : Pat<(and GR32:$src, (add (shl 1, GR8:$lz), -1)),
2341 (BZHI32rr GR32:$src,
2342 (INSERT_SUBREG (i32 (IMPLICIT_DEF)), GR8:$lz, sub_8bit))>;
2344 def : Pat<(and (loadi32 addr:$src), (add (shl 1, GR8:$lz), -1)),
2345 (BZHI32rm addr:$src,
2346 (INSERT_SUBREG (i32 (IMPLICIT_DEF)), GR8:$lz, sub_8bit))>;
2348 def : Pat<(and GR64:$src, (add (shl 1, GR8:$lz), -1)),
2349 (BZHI64rr GR64:$src,
2350 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR8:$lz, sub_8bit))>;
2352 def : Pat<(and (loadi64 addr:$src), (add (shl 1, GR8:$lz), -1)),
2353 (BZHI64rm addr:$src,
2354 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR8:$lz, sub_8bit))>;
2356 // x & (-1 >> (32 - y))
2357 def : Pat<(and GR32:$src, (srl -1, (i8 (trunc (sub 32, GR32:$lz))))),
2358 (BZHI32rr GR32:$src, GR32:$lz)>;
2359 def : Pat<(and (loadi32 addr:$src), (srl -1, (i8 (trunc (sub 32, GR32:$lz))))),
2360 (BZHI32rm addr:$src, GR32:$lz)>;
2362 // x & (-1 >> (64 - y))
2363 def : Pat<(and GR64:$src, (srl -1, (i8 (trunc (sub 64, GR32:$lz))))),
2364 (BZHI64rr GR64:$src,
2365 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR32:$lz, sub_32bit))>;
2366 def : Pat<(and (loadi64 addr:$src), (srl -1, (i8 (trunc (sub 64, GR32:$lz))))),
2367 (BZHI64rm addr:$src,
2368 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR32:$lz, sub_32bit))>;
2370 // x << (32 - y) >> (32 - y)
2371 def : Pat<(srl (shl GR32:$src, (i8 (trunc (sub 32, GR32:$lz)))),
2372 (i8 (trunc (sub 32, GR32:$lz)))),
2373 (BZHI32rr GR32:$src, GR32:$lz)>;
2374 def : Pat<(srl (shl (loadi32 addr:$src), (i8 (trunc (sub 32, GR32:$lz)))),
2375 (i8 (trunc (sub 32, GR32:$lz)))),
2376 (BZHI32rm addr:$src, GR32:$lz)>;
2378 // x << (64 - y) >> (64 - y)
2379 def : Pat<(srl (shl GR64:$src, (i8 (trunc (sub 64, GR32:$lz)))),
2380 (i8 (trunc (sub 64, GR32:$lz)))),
2381 (BZHI64rr GR64:$src,
2382 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR32:$lz, sub_32bit))>;
2383 def : Pat<(srl (shl (loadi64 addr:$src), (i8 (trunc (sub 64, GR32:$lz)))),
2384 (i8 (trunc (sub 64, GR32:$lz)))),
2385 (BZHI64rm addr:$src,
2386 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR32:$lz, sub_32bit))>;
2389 let Predicates = [HasBMI] in {
2390 def : Pat<(X86bextr GR32:$src1, GR32:$src2),
2391 (BEXTR32rr GR32:$src1, GR32:$src2)>;
2392 def : Pat<(X86bextr (loadi32 addr:$src1), GR32:$src2),
2393 (BEXTR32rm addr:$src1, GR32:$src2)>;
2394 def : Pat<(X86bextr GR64:$src1, GR64:$src2),
2395 (BEXTR64rr GR64:$src1, GR64:$src2)>;
2396 def : Pat<(X86bextr (loadi64 addr:$src1), GR64:$src2),
2397 (BEXTR64rm addr:$src1, GR64:$src2)>;
2400 multiclass bmi_pdep_pext<string mnemonic, RegisterClass RC,
2401 X86MemOperand x86memop, Intrinsic Int,
2403 def rr : I<0xF5, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
2404 !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2405 [(set RC:$dst, (Int RC:$src1, RC:$src2))]>,
2407 def rm : I<0xF5, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
2408 !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2409 [(set RC:$dst, (Int RC:$src1, (ld_frag addr:$src2)))]>, VEX_4V;
2412 let Predicates = [HasBMI2] in {
2413 defm PDEP32 : bmi_pdep_pext<"pdep{l}", GR32, i32mem,
2414 int_x86_bmi_pdep_32, loadi32>, T8XD;
2415 defm PDEP64 : bmi_pdep_pext<"pdep{q}", GR64, i64mem,
2416 int_x86_bmi_pdep_64, loadi64>, T8XD, VEX_W;
2417 defm PEXT32 : bmi_pdep_pext<"pext{l}", GR32, i32mem,
2418 int_x86_bmi_pext_32, loadi32>, T8XS;
2419 defm PEXT64 : bmi_pdep_pext<"pext{q}", GR64, i64mem,
2420 int_x86_bmi_pext_64, loadi64>, T8XS, VEX_W;
2423 //===----------------------------------------------------------------------===//
2426 let Predicates = [HasTBM], Defs = [EFLAGS] in {
2428 multiclass tbm_ternary_imm_intr<bits<8> opc, RegisterClass RC, string OpcodeStr,
2429 X86MemOperand x86memop, PatFrag ld_frag,
2430 Intrinsic Int, Operand immtype,
2431 SDPatternOperator immoperator> {
2432 def ri : Ii32<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, immtype:$cntl),
2433 !strconcat(OpcodeStr,
2434 "\t{$cntl, $src1, $dst|$dst, $src1, $cntl}"),
2435 [(set RC:$dst, (Int RC:$src1, immoperator:$cntl))]>,
2437 def mi : Ii32<opc, MRMSrcMem, (outs RC:$dst),
2438 (ins x86memop:$src1, immtype:$cntl),
2439 !strconcat(OpcodeStr,
2440 "\t{$cntl, $src1, $dst|$dst, $src1, $cntl}"),
2441 [(set RC:$dst, (Int (ld_frag addr:$src1), immoperator:$cntl))]>,
2445 defm BEXTRI32 : tbm_ternary_imm_intr<0x10, GR32, "bextr", i32mem, loadi32,
2446 int_x86_tbm_bextri_u32, i32imm, imm>;
2447 let ImmT = Imm32S in
2448 defm BEXTRI64 : tbm_ternary_imm_intr<0x10, GR64, "bextr", i64mem, loadi64,
2449 int_x86_tbm_bextri_u64, i64i32imm,
2450 i64immSExt32>, VEX_W;
2452 multiclass tbm_binary_rm<bits<8> opc, Format FormReg, Format FormMem,
2453 RegisterClass RC, string OpcodeStr,
2454 X86MemOperand x86memop, PatFrag ld_frag> {
2455 let hasSideEffects = 0 in {
2456 def rr : I<opc, FormReg, (outs RC:$dst), (ins RC:$src),
2457 !strconcat(OpcodeStr,"\t{$src, $dst|$dst, $src}"),
2460 def rm : I<opc, FormMem, (outs RC:$dst), (ins x86memop:$src),
2461 !strconcat(OpcodeStr,"\t{$src, $dst|$dst, $src}"),
2466 multiclass tbm_binary_intr<bits<8> opc, string OpcodeStr,
2467 Format FormReg, Format FormMem> {
2468 defm NAME#32 : tbm_binary_rm<opc, FormReg, FormMem, GR32, OpcodeStr, i32mem,
2470 defm NAME#64 : tbm_binary_rm<opc, FormReg, FormMem, GR64, OpcodeStr, i64mem,
2474 defm BLCFILL : tbm_binary_intr<0x01, "blcfill", MRM1r, MRM1m>;
2475 defm BLCI : tbm_binary_intr<0x02, "blci", MRM6r, MRM6m>;
2476 defm BLCIC : tbm_binary_intr<0x01, "blcic", MRM5r, MRM5m>;
2477 defm BLCMSK : tbm_binary_intr<0x02, "blcmsk", MRM1r, MRM1m>;
2478 defm BLCS : tbm_binary_intr<0x01, "blcs", MRM3r, MRM3m>;
2479 defm BLSFILL : tbm_binary_intr<0x01, "blsfill", MRM2r, MRM2m>;
2480 defm BLSIC : tbm_binary_intr<0x01, "blsic", MRM6r, MRM6m>;
2481 defm T1MSKC : tbm_binary_intr<0x01, "t1mskc", MRM7r, MRM7m>;
2482 defm TZMSK : tbm_binary_intr<0x01, "tzmsk", MRM4r, MRM4m>;
2485 //===----------------------------------------------------------------------===//
2486 // Lightweight Profiling Instructions
2488 let Predicates = [HasLWP] in {
2490 def LLWPCB : I<0x12, MRM0r, (outs), (ins GR32:$src), "llwpcb\t$src",
2491 [(int_x86_llwpcb GR32:$src)], IIC_LWP>,
2492 XOP, XOP9, Requires<[Not64BitMode]>;
2493 def SLWPCB : I<0x12, MRM1r, (outs GR32:$dst), (ins), "slwpcb\t$dst",
2494 [(set GR32:$dst, (int_x86_slwpcb))], IIC_LWP>,
2495 XOP, XOP9, Requires<[Not64BitMode]>;
2497 def LLWPCB64 : I<0x12, MRM0r, (outs), (ins GR64:$src), "llwpcb\t$src",
2498 [(int_x86_llwpcb GR64:$src)], IIC_LWP>,
2499 XOP, XOP9, VEX_W, Requires<[In64BitMode]>;
2500 def SLWPCB64 : I<0x12, MRM1r, (outs GR64:$dst), (ins), "slwpcb\t$dst",
2501 [(set GR64:$dst, (int_x86_slwpcb))], IIC_LWP>,
2502 XOP, XOP9, VEX_W, Requires<[In64BitMode]>;
2504 multiclass lwpins_intr<RegisterClass RC> {
2505 def rri : Ii32<0x12, MRM0r, (outs), (ins RC:$src0, GR32:$src1, i32imm:$cntl),
2506 "lwpins\t{$cntl, $src1, $src0|$src0, $src1, $cntl}",
2507 [(set EFLAGS, (X86lwpins RC:$src0, GR32:$src1, imm:$cntl))]>,
2510 def rmi : Ii32<0x12, MRM0m, (outs), (ins RC:$src0, i32mem:$src1, i32imm:$cntl),
2511 "lwpins\t{$cntl, $src1, $src0|$src0, $src1, $cntl}",
2512 [(set EFLAGS, (X86lwpins RC:$src0, (loadi32 addr:$src1), imm:$cntl))]>,
2516 let Defs = [EFLAGS] in {
2517 defm LWPINS32 : lwpins_intr<GR32>;
2518 defm LWPINS64 : lwpins_intr<GR64>, VEX_W;
2521 multiclass lwpval_intr<RegisterClass RC, Intrinsic Int> {
2522 def rri : Ii32<0x12, MRM1r, (outs), (ins RC:$src0, GR32:$src1, i32imm:$cntl),
2523 "lwpval\t{$cntl, $src1, $src0|$src0, $src1, $cntl}",
2524 [(Int RC:$src0, GR32:$src1, imm:$cntl)], IIC_LWP>,
2527 def rmi : Ii32<0x12, MRM1m, (outs), (ins RC:$src0, i32mem:$src1, i32imm:$cntl),
2528 "lwpval\t{$cntl, $src1, $src0|$src0, $src1, $cntl}",
2529 [(Int RC:$src0, (loadi32 addr:$src1), imm:$cntl)], IIC_LWP>,
2533 defm LWPVAL32 : lwpval_intr<GR32, int_x86_lwpval32>;
2534 defm LWPVAL64 : lwpval_intr<GR64, int_x86_lwpval64>, VEX_W;
2538 //===----------------------------------------------------------------------===//
2539 // MONITORX/MWAITX Instructions
2541 let SchedRW = [ WriteSystem ] in {
2542 let usesCustomInserter = 1 in {
2543 def MONITORX : PseudoI<(outs), (ins i32mem:$src1, GR32:$src2, GR32:$src3),
2544 [(int_x86_monitorx addr:$src1, GR32:$src2, GR32:$src3)]>,
2545 Requires<[ HasMWAITX ]>;
2548 let Uses = [ EAX, ECX, EDX ] in {
2549 def MONITORXrrr : I<0x01, MRM_FA, (outs), (ins), "monitorx", [], IIC_SSE_MONITORX>,
2550 TB, Requires<[ HasMWAITX ]>;
2553 let Uses = [ ECX, EAX, EBX ] in {
2554 def MWAITXrrr : I<0x01, MRM_FB, (outs), (ins), "mwaitx",
2555 [(int_x86_mwaitx ECX, EAX, EBX)], IIC_SSE_MWAITX>,
2556 TB, Requires<[ HasMWAITX ]>;
2560 def : InstAlias<"mwaitx\t{%eax, %ecx, %ebx|ebx, ecx, eax}", (MWAITXrrr)>,
2561 Requires<[ Not64BitMode ]>;
2562 def : InstAlias<"mwaitx\t{%rax, %rcx, %rbx|rbx, rcx, rax}", (MWAITXrrr)>,
2563 Requires<[ In64BitMode ]>;
2565 def : InstAlias<"monitorx\t{%eax, %ecx, %edx|edx, ecx, eax}", (MONITORXrrr)>,
2566 Requires<[ Not64BitMode ]>;
2567 def : InstAlias<"monitorx\t{%rax, %rcx, %rdx|rdx, rcx, rax}", (MONITORXrrr)>,
2568 Requires<[ In64BitMode ]>;
2570 //===----------------------------------------------------------------------===//
2571 // CLZERO Instruction
2573 let SchedRW = [WriteSystem] in {
2575 def CLZEROr : I<0x01, MRM_FC, (outs), (ins), "clzero", [], IIC_SSE_CLZERO>,
2576 TB, Requires<[HasCLZERO]>;
2578 let usesCustomInserter = 1 in {
2579 def CLZERO : PseudoI<(outs), (ins i32mem:$src1),
2580 [(int_x86_clzero addr:$src1)]>, Requires<[HasCLZERO]>;
2584 def : InstAlias<"clzero\t{%eax|eax}", (CLZEROr)>, Requires<[Not64BitMode]>;
2585 def : InstAlias<"clzero\t{%rax|rax}", (CLZEROr)>, Requires<[In64BitMode]>;
2587 //===----------------------------------------------------------------------===//
2588 // Pattern fragments to auto generate TBM instructions.
2589 //===----------------------------------------------------------------------===//
2591 let Predicates = [HasTBM] in {
2592 def : Pat<(X86bextr GR32:$src1, (i32 imm:$src2)),
2593 (BEXTRI32ri GR32:$src1, imm:$src2)>;
2594 def : Pat<(X86bextr (loadi32 addr:$src1), (i32 imm:$src2)),
2595 (BEXTRI32mi addr:$src1, imm:$src2)>;
2596 def : Pat<(X86bextr GR64:$src1, i64immSExt32:$src2),
2597 (BEXTRI64ri GR64:$src1, i64immSExt32:$src2)>;
2598 def : Pat<(X86bextr (loadi64 addr:$src1), i64immSExt32:$src2),
2599 (BEXTRI64mi addr:$src1, i64immSExt32:$src2)>;
2601 // FIXME: patterns for the load versions are not implemented
2602 def : Pat<(and GR32:$src, (add GR32:$src, 1)),
2603 (BLCFILL32rr GR32:$src)>;
2604 def : Pat<(and GR64:$src, (add GR64:$src, 1)),
2605 (BLCFILL64rr GR64:$src)>;
2607 def : Pat<(or GR32:$src, (not (add GR32:$src, 1))),
2608 (BLCI32rr GR32:$src)>;
2609 def : Pat<(or GR64:$src, (not (add GR64:$src, 1))),
2610 (BLCI64rr GR64:$src)>;
2612 // Extra patterns because opt can optimize the above patterns to this.
2613 def : Pat<(or GR32:$src, (sub -2, GR32:$src)),
2614 (BLCI32rr GR32:$src)>;
2615 def : Pat<(or GR64:$src, (sub -2, GR64:$src)),
2616 (BLCI64rr GR64:$src)>;
2618 def : Pat<(and (not GR32:$src), (add GR32:$src, 1)),
2619 (BLCIC32rr GR32:$src)>;
2620 def : Pat<(and (not GR64:$src), (add GR64:$src, 1)),
2621 (BLCIC64rr GR64:$src)>;
2623 def : Pat<(xor GR32:$src, (add GR32:$src, 1)),
2624 (BLCMSK32rr GR32:$src)>;
2625 def : Pat<(xor GR64:$src, (add GR64:$src, 1)),
2626 (BLCMSK64rr GR64:$src)>;
2628 def : Pat<(or GR32:$src, (add GR32:$src, 1)),
2629 (BLCS32rr GR32:$src)>;
2630 def : Pat<(or GR64:$src, (add GR64:$src, 1)),
2631 (BLCS64rr GR64:$src)>;
2633 def : Pat<(or GR32:$src, (add GR32:$src, -1)),
2634 (BLSFILL32rr GR32:$src)>;
2635 def : Pat<(or GR64:$src, (add GR64:$src, -1)),
2636 (BLSFILL64rr GR64:$src)>;
2638 def : Pat<(or (not GR32:$src), (add GR32:$src, -1)),
2639 (BLSIC32rr GR32:$src)>;
2640 def : Pat<(or (not GR64:$src), (add GR64:$src, -1)),
2641 (BLSIC64rr GR64:$src)>;
2643 def : Pat<(or (not GR32:$src), (add GR32:$src, 1)),
2644 (T1MSKC32rr GR32:$src)>;
2645 def : Pat<(or (not GR64:$src), (add GR64:$src, 1)),
2646 (T1MSKC64rr GR64:$src)>;
2648 def : Pat<(and (not GR32:$src), (add GR32:$src, -1)),
2649 (TZMSK32rr GR32:$src)>;
2650 def : Pat<(and (not GR64:$src), (add GR64:$src, -1)),
2651 (TZMSK64rr GR64:$src)>;
2654 //===----------------------------------------------------------------------===//
2655 // Memory Instructions
2658 let Predicates = [HasCLFLUSHOPT] in
2659 def CLFLUSHOPT : I<0xAE, MRM7m, (outs), (ins i8mem:$src),
2660 "clflushopt\t$src", [(int_x86_clflushopt addr:$src)]>, PD;
2661 def CLWB : I<0xAE, MRM6m, (outs), (ins i8mem:$src), "clwb\t$src", []>, PD;
2664 //===----------------------------------------------------------------------===//
2666 //===----------------------------------------------------------------------===//
2668 include "X86InstrArithmetic.td"
2669 include "X86InstrCMovSetCC.td"
2670 include "X86InstrExtension.td"
2671 include "X86InstrControl.td"
2672 include "X86InstrShiftRotate.td"
2674 // X87 Floating Point Stack.
2675 include "X86InstrFPStack.td"
2677 // SIMD support (SSE, MMX and AVX)
2678 include "X86InstrFragmentsSIMD.td"
2680 // FMA - Fused Multiply-Add support (requires FMA)
2681 include "X86InstrFMA.td"
2684 include "X86InstrXOP.td"
2686 // SSE, MMX and 3DNow! vector support.
2687 include "X86InstrSSE.td"
2688 include "X86InstrAVX512.td"
2689 include "X86InstrMMX.td"
2690 include "X86Instr3DNow.td"
2693 include "X86InstrMPX.td"
2695 include "X86InstrVMX.td"
2696 include "X86InstrSVM.td"
2698 include "X86InstrTSX.td"
2699 include "X86InstrSGX.td"
2701 // System instructions.
2702 include "X86InstrSystem.td"
2704 // Compiler Pseudo Instructions and Pat Patterns
2705 include "X86InstrCompiler.td"
2707 //===----------------------------------------------------------------------===//
2708 // Assembler Mnemonic Aliases
2709 //===----------------------------------------------------------------------===//
2711 def : MnemonicAlias<"call", "callw", "att">, Requires<[In16BitMode]>;
2712 def : MnemonicAlias<"call", "calll", "att">, Requires<[In32BitMode]>;
2713 def : MnemonicAlias<"call", "callq", "att">, Requires<[In64BitMode]>;
2715 def : MnemonicAlias<"cbw", "cbtw", "att">;
2716 def : MnemonicAlias<"cwde", "cwtl", "att">;
2717 def : MnemonicAlias<"cwd", "cwtd", "att">;
2718 def : MnemonicAlias<"cdq", "cltd", "att">;
2719 def : MnemonicAlias<"cdqe", "cltq", "att">;
2720 def : MnemonicAlias<"cqo", "cqto", "att">;
2722 // In 64-bit mode lret maps to lretl; it is not ambiguous with lretq.
2723 def : MnemonicAlias<"lret", "lretw", "att">, Requires<[In16BitMode]>;
2724 def : MnemonicAlias<"lret", "lretl", "att">, Requires<[Not16BitMode]>;
2726 def : MnemonicAlias<"leavel", "leave", "att">, Requires<[Not64BitMode]>;
2727 def : MnemonicAlias<"leaveq", "leave", "att">, Requires<[In64BitMode]>;
2729 def : MnemonicAlias<"loopz", "loope">;
2730 def : MnemonicAlias<"loopnz", "loopne">;
2732 def : MnemonicAlias<"pop", "popw", "att">, Requires<[In16BitMode]>;
2733 def : MnemonicAlias<"pop", "popl", "att">, Requires<[In32BitMode]>;
2734 def : MnemonicAlias<"pop", "popq", "att">, Requires<[In64BitMode]>;
2735 def : MnemonicAlias<"popf", "popfw", "att">, Requires<[In16BitMode]>;
2736 def : MnemonicAlias<"popf", "popfl", "att">, Requires<[In32BitMode]>;
2737 def : MnemonicAlias<"popf", "popfq", "att">, Requires<[In64BitMode]>;
2738 def : MnemonicAlias<"popfd", "popfl", "att">;
2740 // FIXME: This is wrong for "push reg". "push %bx" should turn into pushw in
2741 // all modes. However: "push (addr)" and "push $42" should default to
2742 // pushl/pushq depending on the current mode. Similar for "pop %bx"
2743 def : MnemonicAlias<"push", "pushw", "att">, Requires<[In16BitMode]>;
2744 def : MnemonicAlias<"push", "pushl", "att">, Requires<[In32BitMode]>;
2745 def : MnemonicAlias<"push", "pushq", "att">, Requires<[In64BitMode]>;
2746 def : MnemonicAlias<"pushf", "pushfw", "att">, Requires<[In16BitMode]>;
2747 def : MnemonicAlias<"pushf", "pushfl", "att">, Requires<[In32BitMode]>;
2748 def : MnemonicAlias<"pushf", "pushfq", "att">, Requires<[In64BitMode]>;
2749 def : MnemonicAlias<"pushfd", "pushfl", "att">;
2751 def : MnemonicAlias<"popad", "popal", "intel">, Requires<[Not64BitMode]>;
2752 def : MnemonicAlias<"pushad", "pushal", "intel">, Requires<[Not64BitMode]>;
2753 def : MnemonicAlias<"popa", "popaw", "intel">, Requires<[In16BitMode]>;
2754 def : MnemonicAlias<"pusha", "pushaw", "intel">, Requires<[In16BitMode]>;
2755 def : MnemonicAlias<"popa", "popal", "intel">, Requires<[In32BitMode]>;
2756 def : MnemonicAlias<"pusha", "pushal", "intel">, Requires<[In32BitMode]>;
2758 def : MnemonicAlias<"popa", "popaw", "att">, Requires<[In16BitMode]>;
2759 def : MnemonicAlias<"pusha", "pushaw", "att">, Requires<[In16BitMode]>;
2760 def : MnemonicAlias<"popa", "popal", "att">, Requires<[In32BitMode]>;
2761 def : MnemonicAlias<"pusha", "pushal", "att">, Requires<[In32BitMode]>;
2763 def : MnemonicAlias<"repe", "rep">;
2764 def : MnemonicAlias<"repz", "rep">;
2765 def : MnemonicAlias<"repnz", "repne">;
2767 def : MnemonicAlias<"ret", "retw", "att">, Requires<[In16BitMode]>;
2768 def : MnemonicAlias<"ret", "retl", "att">, Requires<[In32BitMode]>;
2769 def : MnemonicAlias<"ret", "retq", "att">, Requires<[In64BitMode]>;
2771 // Apply 'ret' behavior to 'retn'
2772 def : MnemonicAlias<"retn", "retw", "att">, Requires<[In16BitMode]>;
2773 def : MnemonicAlias<"retn", "retl", "att">, Requires<[In32BitMode]>;
2774 def : MnemonicAlias<"retn", "retq", "att">, Requires<[In64BitMode]>;
2775 def : MnemonicAlias<"retn", "ret", "intel">;
2777 def : MnemonicAlias<"sal", "shl", "intel">;
2778 def : MnemonicAlias<"salb", "shlb", "att">;
2779 def : MnemonicAlias<"salw", "shlw", "att">;
2780 def : MnemonicAlias<"sall", "shll", "att">;
2781 def : MnemonicAlias<"salq", "shlq", "att">;
2783 def : MnemonicAlias<"smovb", "movsb", "att">;
2784 def : MnemonicAlias<"smovw", "movsw", "att">;
2785 def : MnemonicAlias<"smovl", "movsl", "att">;
2786 def : MnemonicAlias<"smovq", "movsq", "att">;
2788 def : MnemonicAlias<"ud2a", "ud2", "att">;
2789 def : MnemonicAlias<"verrw", "verr", "att">;
2791 // System instruction aliases.
2792 def : MnemonicAlias<"iret", "iretw", "att">, Requires<[In16BitMode]>;
2793 def : MnemonicAlias<"iret", "iretl", "att">, Requires<[Not16BitMode]>;
2794 def : MnemonicAlias<"sysret", "sysretl", "att">;
2795 def : MnemonicAlias<"sysexit", "sysexitl", "att">;
2797 def : MnemonicAlias<"lgdt", "lgdtw", "att">, Requires<[In16BitMode]>;
2798 def : MnemonicAlias<"lgdt", "lgdtl", "att">, Requires<[In32BitMode]>;
2799 def : MnemonicAlias<"lgdt", "lgdtq", "att">, Requires<[In64BitMode]>;
2800 def : MnemonicAlias<"lidt", "lidtw", "att">, Requires<[In16BitMode]>;
2801 def : MnemonicAlias<"lidt", "lidtl", "att">, Requires<[In32BitMode]>;
2802 def : MnemonicAlias<"lidt", "lidtq", "att">, Requires<[In64BitMode]>;
2803 def : MnemonicAlias<"sgdt", "sgdtw", "att">, Requires<[In16BitMode]>;
2804 def : MnemonicAlias<"sgdt", "sgdtl", "att">, Requires<[In32BitMode]>;
2805 def : MnemonicAlias<"sgdt", "sgdtq", "att">, Requires<[In64BitMode]>;
2806 def : MnemonicAlias<"sidt", "sidtw", "att">, Requires<[In16BitMode]>;
2807 def : MnemonicAlias<"sidt", "sidtl", "att">, Requires<[In32BitMode]>;
2808 def : MnemonicAlias<"sidt", "sidtq", "att">, Requires<[In64BitMode]>;
2811 // Floating point stack aliases.
2812 def : MnemonicAlias<"fcmovz", "fcmove", "att">;
2813 def : MnemonicAlias<"fcmova", "fcmovnbe", "att">;
2814 def : MnemonicAlias<"fcmovnae", "fcmovb", "att">;
2815 def : MnemonicAlias<"fcmovna", "fcmovbe", "att">;
2816 def : MnemonicAlias<"fcmovae", "fcmovnb", "att">;
2817 def : MnemonicAlias<"fcomip", "fcompi">;
2818 def : MnemonicAlias<"fildq", "fildll", "att">;
2819 def : MnemonicAlias<"fistpq", "fistpll", "att">;
2820 def : MnemonicAlias<"fisttpq", "fisttpll", "att">;
2821 def : MnemonicAlias<"fldcww", "fldcw", "att">;
2822 def : MnemonicAlias<"fnstcww", "fnstcw", "att">;
2823 def : MnemonicAlias<"fnstsww", "fnstsw", "att">;
2824 def : MnemonicAlias<"fucomip", "fucompi">;
2825 def : MnemonicAlias<"fwait", "wait">;
2827 def : MnemonicAlias<"fxsaveq", "fxsave64", "att">;
2828 def : MnemonicAlias<"fxrstorq", "fxrstor64", "att">;
2829 def : MnemonicAlias<"xsaveq", "xsave64", "att">;
2830 def : MnemonicAlias<"xrstorq", "xrstor64", "att">;
2831 def : MnemonicAlias<"xsaveoptq", "xsaveopt64", "att">;
2832 def : MnemonicAlias<"xrstorsq", "xrstors64", "att">;
2833 def : MnemonicAlias<"xsavecq", "xsavec64", "att">;
2834 def : MnemonicAlias<"xsavesq", "xsaves64", "att">;
2836 class CondCodeAlias<string Prefix,string Suffix, string OldCond, string NewCond,
2838 : MnemonicAlias<!strconcat(Prefix, OldCond, Suffix),
2839 !strconcat(Prefix, NewCond, Suffix), VariantName>;
2841 /// IntegerCondCodeMnemonicAlias - This multiclass defines a bunch of
2842 /// MnemonicAlias's that canonicalize the condition code in a mnemonic, for
2843 /// example "setz" -> "sete".
2844 multiclass IntegerCondCodeMnemonicAlias<string Prefix, string Suffix,
2846 def C : CondCodeAlias<Prefix, Suffix, "c", "b", V>; // setc -> setb
2847 def Z : CondCodeAlias<Prefix, Suffix, "z" , "e", V>; // setz -> sete
2848 def NA : CondCodeAlias<Prefix, Suffix, "na", "be", V>; // setna -> setbe
2849 def NB : CondCodeAlias<Prefix, Suffix, "nb", "ae", V>; // setnb -> setae
2850 def NC : CondCodeAlias<Prefix, Suffix, "nc", "ae", V>; // setnc -> setae
2851 def NG : CondCodeAlias<Prefix, Suffix, "ng", "le", V>; // setng -> setle
2852 def NL : CondCodeAlias<Prefix, Suffix, "nl", "ge", V>; // setnl -> setge
2853 def NZ : CondCodeAlias<Prefix, Suffix, "nz", "ne", V>; // setnz -> setne
2854 def PE : CondCodeAlias<Prefix, Suffix, "pe", "p", V>; // setpe -> setp
2855 def PO : CondCodeAlias<Prefix, Suffix, "po", "np", V>; // setpo -> setnp
2857 def NAE : CondCodeAlias<Prefix, Suffix, "nae", "b", V>; // setnae -> setb
2858 def NBE : CondCodeAlias<Prefix, Suffix, "nbe", "a", V>; // setnbe -> seta
2859 def NGE : CondCodeAlias<Prefix, Suffix, "nge", "l", V>; // setnge -> setl
2860 def NLE : CondCodeAlias<Prefix, Suffix, "nle", "g", V>; // setnle -> setg
2863 // Aliases for set<CC>
2864 defm : IntegerCondCodeMnemonicAlias<"set", "">;
2865 // Aliases for j<CC>
2866 defm : IntegerCondCodeMnemonicAlias<"j", "">;
2867 // Aliases for cmov<CC>{w,l,q}
2868 defm : IntegerCondCodeMnemonicAlias<"cmov", "w", "att">;
2869 defm : IntegerCondCodeMnemonicAlias<"cmov", "l", "att">;
2870 defm : IntegerCondCodeMnemonicAlias<"cmov", "q", "att">;
2871 // No size suffix for intel-style asm.
2872 defm : IntegerCondCodeMnemonicAlias<"cmov", "", "intel">;
2875 //===----------------------------------------------------------------------===//
2876 // Assembler Instruction Aliases
2877 //===----------------------------------------------------------------------===//
2879 // aad/aam default to base 10 if no operand is specified.
2880 def : InstAlias<"aad", (AAD8i8 10)>, Requires<[Not64BitMode]>;
2881 def : InstAlias<"aam", (AAM8i8 10)>, Requires<[Not64BitMode]>;
2883 // Disambiguate the mem/imm form of bt-without-a-suffix as btl.
2884 // Likewise for btc/btr/bts.
2885 def : InstAlias<"bt\t{$imm, $mem|$mem, $imm}",
2886 (BT32mi8 i32mem:$mem, i32i8imm:$imm), 0>;
2887 def : InstAlias<"btc\t{$imm, $mem|$mem, $imm}",
2888 (BTC32mi8 i32mem:$mem, i32i8imm:$imm), 0>;
2889 def : InstAlias<"btr\t{$imm, $mem|$mem, $imm}",
2890 (BTR32mi8 i32mem:$mem, i32i8imm:$imm), 0>;
2891 def : InstAlias<"bts\t{$imm, $mem|$mem, $imm}",
2892 (BTS32mi8 i32mem:$mem, i32i8imm:$imm), 0>;
2895 def : InstAlias<"clrb\t$reg", (XOR8rr GR8 :$reg, GR8 :$reg), 0>;
2896 def : InstAlias<"clrw\t$reg", (XOR16rr GR16:$reg, GR16:$reg), 0>;
2897 def : InstAlias<"clrl\t$reg", (XOR32rr GR32:$reg, GR32:$reg), 0>;
2898 def : InstAlias<"clrq\t$reg", (XOR64rr GR64:$reg, GR64:$reg), 0>;
2900 // lods aliases. Accept the destination being omitted because it's implicit
2901 // in the mnemonic, or the mnemonic suffix being omitted because it's implicit
2902 // in the destination.
2903 def : InstAlias<"lodsb\t$src", (LODSB srcidx8:$src), 0>;
2904 def : InstAlias<"lodsw\t$src", (LODSW srcidx16:$src), 0>;
2905 def : InstAlias<"lods{l|d}\t$src", (LODSL srcidx32:$src), 0>;
2906 def : InstAlias<"lodsq\t$src", (LODSQ srcidx64:$src), 0>, Requires<[In64BitMode]>;
2907 def : InstAlias<"lods\t{$src, %al|al, $src}", (LODSB srcidx8:$src), 0>;
2908 def : InstAlias<"lods\t{$src, %ax|ax, $src}", (LODSW srcidx16:$src), 0>;
2909 def : InstAlias<"lods\t{$src, %eax|eax, $src}", (LODSL srcidx32:$src), 0>;
2910 def : InstAlias<"lods\t{$src, %rax|rax, $src}", (LODSQ srcidx64:$src), 0>, Requires<[In64BitMode]>;
2911 def : InstAlias<"lods\t$src", (LODSB srcidx8:$src), 0>;
2912 def : InstAlias<"lods\t$src", (LODSW srcidx16:$src), 0>;
2913 def : InstAlias<"lods\t$src", (LODSL srcidx32:$src), 0>;
2914 def : InstAlias<"lods\t$src", (LODSQ srcidx64:$src), 0>, Requires<[In64BitMode]>;
2917 // stos aliases. Accept the source being omitted because it's implicit in
2918 // the mnemonic, or the mnemonic suffix being omitted because it's implicit
2920 def : InstAlias<"stosb\t$dst", (STOSB dstidx8:$dst), 0>;
2921 def : InstAlias<"stosw\t$dst", (STOSW dstidx16:$dst), 0>;
2922 def : InstAlias<"stos{l|d}\t$dst", (STOSL dstidx32:$dst), 0>;
2923 def : InstAlias<"stosq\t$dst", (STOSQ dstidx64:$dst), 0>, Requires<[In64BitMode]>;
2924 def : InstAlias<"stos\t{%al, $dst|$dst, al}", (STOSB dstidx8:$dst), 0>;
2925 def : InstAlias<"stos\t{%ax, $dst|$dst, ax}", (STOSW dstidx16:$dst), 0>;
2926 def : InstAlias<"stos\t{%eax, $dst|$dst, eax}", (STOSL dstidx32:$dst), 0>;
2927 def : InstAlias<"stos\t{%rax, $dst|$dst, rax}", (STOSQ dstidx64:$dst), 0>, Requires<[In64BitMode]>;
2928 def : InstAlias<"stos\t$dst", (STOSB dstidx8:$dst), 0>;
2929 def : InstAlias<"stos\t$dst", (STOSW dstidx16:$dst), 0>;
2930 def : InstAlias<"stos\t$dst", (STOSL dstidx32:$dst), 0>;
2931 def : InstAlias<"stos\t$dst", (STOSQ dstidx64:$dst), 0>, Requires<[In64BitMode]>;
2934 // scas aliases. Accept the destination being omitted because it's implicit
2935 // in the mnemonic, or the mnemonic suffix being omitted because it's implicit
2936 // in the destination.
2937 def : InstAlias<"scasb\t$dst", (SCASB dstidx8:$dst), 0>;
2938 def : InstAlias<"scasw\t$dst", (SCASW dstidx16:$dst), 0>;
2939 def : InstAlias<"scas{l|d}\t$dst", (SCASL dstidx32:$dst), 0>;
2940 def : InstAlias<"scasq\t$dst", (SCASQ dstidx64:$dst), 0>, Requires<[In64BitMode]>;
2941 def : InstAlias<"scas\t{$dst, %al|al, $dst}", (SCASB dstidx8:$dst), 0>;
2942 def : InstAlias<"scas\t{$dst, %ax|ax, $dst}", (SCASW dstidx16:$dst), 0>;
2943 def : InstAlias<"scas\t{$dst, %eax|eax, $dst}", (SCASL dstidx32:$dst), 0>;
2944 def : InstAlias<"scas\t{$dst, %rax|rax, $dst}", (SCASQ dstidx64:$dst), 0>, Requires<[In64BitMode]>;
2945 def : InstAlias<"scas\t$dst", (SCASB dstidx8:$dst), 0>;
2946 def : InstAlias<"scas\t$dst", (SCASW dstidx16:$dst), 0>;
2947 def : InstAlias<"scas\t$dst", (SCASL dstidx32:$dst), 0>;
2948 def : InstAlias<"scas\t$dst", (SCASQ dstidx64:$dst), 0>, Requires<[In64BitMode]>;
2950 // cmps aliases. Mnemonic suffix being omitted because it's implicit
2951 // in the destination.
2952 def : InstAlias<"cmps\t{$dst, $src|$src, $dst}", (CMPSB dstidx8:$dst, srcidx8:$src), 0>;
2953 def : InstAlias<"cmps\t{$dst, $src|$src, $dst}", (CMPSW dstidx16:$dst, srcidx16:$src), 0>;
2954 def : InstAlias<"cmps\t{$dst, $src|$src, $dst}", (CMPSL dstidx32:$dst, srcidx32:$src), 0>;
2955 def : InstAlias<"cmps\t{$dst, $src|$src, $dst}", (CMPSQ dstidx64:$dst, srcidx64:$src), 0>, Requires<[In64BitMode]>;
2957 // movs aliases. Mnemonic suffix being omitted because it's implicit
2958 // in the destination.
2959 def : InstAlias<"movs\t{$src, $dst|$dst, $src}", (MOVSB dstidx8:$dst, srcidx8:$src), 0>;
2960 def : InstAlias<"movs\t{$src, $dst|$dst, $src}", (MOVSW dstidx16:$dst, srcidx16:$src), 0>;
2961 def : InstAlias<"movs\t{$src, $dst|$dst, $src}", (MOVSL dstidx32:$dst, srcidx32:$src), 0>;
2962 def : InstAlias<"movs\t{$src, $dst|$dst, $src}", (MOVSQ dstidx64:$dst, srcidx64:$src), 0>, Requires<[In64BitMode]>;
2964 // div and idiv aliases for explicit A register.
2965 def : InstAlias<"div{b}\t{$src, %al|al, $src}", (DIV8r GR8 :$src)>;
2966 def : InstAlias<"div{w}\t{$src, %ax|ax, $src}", (DIV16r GR16:$src)>;
2967 def : InstAlias<"div{l}\t{$src, %eax|eax, $src}", (DIV32r GR32:$src)>;
2968 def : InstAlias<"div{q}\t{$src, %rax|rax, $src}", (DIV64r GR64:$src)>;
2969 def : InstAlias<"div{b}\t{$src, %al|al, $src}", (DIV8m i8mem :$src)>;
2970 def : InstAlias<"div{w}\t{$src, %ax|ax, $src}", (DIV16m i16mem:$src)>;
2971 def : InstAlias<"div{l}\t{$src, %eax|eax, $src}", (DIV32m i32mem:$src)>;
2972 def : InstAlias<"div{q}\t{$src, %rax|rax, $src}", (DIV64m i64mem:$src)>;
2973 def : InstAlias<"idiv{b}\t{$src, %al|al, $src}", (IDIV8r GR8 :$src)>;
2974 def : InstAlias<"idiv{w}\t{$src, %ax|ax, $src}", (IDIV16r GR16:$src)>;
2975 def : InstAlias<"idiv{l}\t{$src, %eax|eax, $src}", (IDIV32r GR32:$src)>;
2976 def : InstAlias<"idiv{q}\t{$src, %rax|rax, $src}", (IDIV64r GR64:$src)>;
2977 def : InstAlias<"idiv{b}\t{$src, %al|al, $src}", (IDIV8m i8mem :$src)>;
2978 def : InstAlias<"idiv{w}\t{$src, %ax|ax, $src}", (IDIV16m i16mem:$src)>;
2979 def : InstAlias<"idiv{l}\t{$src, %eax|eax, $src}", (IDIV32m i32mem:$src)>;
2980 def : InstAlias<"idiv{q}\t{$src, %rax|rax, $src}", (IDIV64m i64mem:$src)>;
2984 // Various unary fpstack operations default to operating on on ST1.
2985 // For example, "fxch" -> "fxch %st(1)"
2986 def : InstAlias<"faddp", (ADD_FPrST0 ST1), 0>;
2987 def: InstAlias<"fadd", (ADD_FPrST0 ST1), 0>;
2988 def : InstAlias<"fsub{|r}p", (SUBR_FPrST0 ST1), 0>;
2989 def : InstAlias<"fsub{r|}p", (SUB_FPrST0 ST1), 0>;
2990 def : InstAlias<"fmul", (MUL_FPrST0 ST1), 0>;
2991 def : InstAlias<"fmulp", (MUL_FPrST0 ST1), 0>;
2992 def : InstAlias<"fdiv{|r}p", (DIVR_FPrST0 ST1), 0>;
2993 def : InstAlias<"fdiv{r|}p", (DIV_FPrST0 ST1), 0>;
2994 def : InstAlias<"fxch", (XCH_F ST1), 0>;
2995 def : InstAlias<"fcom", (COM_FST0r ST1), 0>;
2996 def : InstAlias<"fcomp", (COMP_FST0r ST1), 0>;
2997 def : InstAlias<"fcomi", (COM_FIr ST1), 0>;
2998 def : InstAlias<"fcompi", (COM_FIPr ST1), 0>;
2999 def : InstAlias<"fucom", (UCOM_Fr ST1), 0>;
3000 def : InstAlias<"fucomp", (UCOM_FPr ST1), 0>;
3001 def : InstAlias<"fucomi", (UCOM_FIr ST1), 0>;
3002 def : InstAlias<"fucompi", (UCOM_FIPr ST1), 0>;
3004 // Handle fmul/fadd/fsub/fdiv instructions with explicitly written st(0) op.
3005 // For example, "fadd %st(4), %st(0)" -> "fadd %st(4)". We also disambiguate
3006 // instructions like "fadd %st(0), %st(0)" as "fadd %st(0)" for consistency with
3008 multiclass FpUnaryAlias<string Mnemonic, Instruction Inst, bit EmitAlias = 1> {
3009 def : InstAlias<!strconcat(Mnemonic, "\t{$op, %st(0)|st(0), $op}"),
3010 (Inst RST:$op), EmitAlias>;
3011 def : InstAlias<!strconcat(Mnemonic, "\t{%st(0), %st(0)|st(0), st(0)}"),
3012 (Inst ST0), EmitAlias>;
3015 defm : FpUnaryAlias<"fadd", ADD_FST0r>;
3016 defm : FpUnaryAlias<"faddp", ADD_FPrST0, 0>;
3017 defm : FpUnaryAlias<"fsub", SUB_FST0r>;
3018 defm : FpUnaryAlias<"fsub{|r}p", SUBR_FPrST0>;
3019 defm : FpUnaryAlias<"fsubr", SUBR_FST0r>;
3020 defm : FpUnaryAlias<"fsub{r|}p", SUB_FPrST0>;
3021 defm : FpUnaryAlias<"fmul", MUL_FST0r>;
3022 defm : FpUnaryAlias<"fmulp", MUL_FPrST0>;
3023 defm : FpUnaryAlias<"fdiv", DIV_FST0r>;
3024 defm : FpUnaryAlias<"fdiv{|r}p", DIVR_FPrST0>;
3025 defm : FpUnaryAlias<"fdivr", DIVR_FST0r>;
3026 defm : FpUnaryAlias<"fdiv{r|}p", DIV_FPrST0>;
3027 defm : FpUnaryAlias<"fcomi", COM_FIr, 0>;
3028 defm : FpUnaryAlias<"fucomi", UCOM_FIr, 0>;
3029 defm : FpUnaryAlias<"fcompi", COM_FIPr>;
3030 defm : FpUnaryAlias<"fucompi", UCOM_FIPr>;
3033 // Handle "f{mulp,addp} st(0), $op" the same as "f{mulp,addp} $op", since they
3034 // commute. We also allow fdiv[r]p/fsubrp even though they don't commute,
3035 // solely because gas supports it.
3036 def : InstAlias<"faddp\t{%st(0), $op|$op, st(0)}", (ADD_FPrST0 RST:$op), 0>;
3037 def : InstAlias<"fmulp\t{%st(0), $op|$op, st(0)}", (MUL_FPrST0 RST:$op)>;
3038 def : InstAlias<"fsub{|r}p\t{%st(0), $op|$op, st(0)}", (SUBR_FPrST0 RST:$op)>;
3039 def : InstAlias<"fsub{r|}p\t{%st(0), $op|$op, st(0)}", (SUB_FPrST0 RST:$op)>;
3040 def : InstAlias<"fdiv{|r}p\t{%st(0), $op|$op, st(0)}", (DIVR_FPrST0 RST:$op)>;
3041 def : InstAlias<"fdiv{r|}p\t{%st(0), $op|$op, st(0)}", (DIV_FPrST0 RST:$op)>;
3043 // We accept "fnstsw %eax" even though it only writes %ax.
3044 def : InstAlias<"fnstsw\t{%eax|eax}", (FNSTSW16r)>;
3045 def : InstAlias<"fnstsw\t{%al|al}" , (FNSTSW16r)>;
3046 def : InstAlias<"fnstsw" , (FNSTSW16r)>;
3048 // lcall and ljmp aliases. This seems to be an odd mapping in 64-bit mode, but
3049 // this is compatible with what GAS does.
3050 def : InstAlias<"lcall\t$seg, $off", (FARCALL32i i32imm:$off, i16imm:$seg), 0>, Requires<[In32BitMode]>;
3051 def : InstAlias<"ljmp\t$seg, $off", (FARJMP32i i32imm:$off, i16imm:$seg), 0>, Requires<[In32BitMode]>;
3052 def : InstAlias<"lcall\t{*}$dst", (FARCALL32m opaque48mem:$dst), 0>, Requires<[Not16BitMode]>;
3053 def : InstAlias<"ljmp\t{*}$dst", (FARJMP32m opaque48mem:$dst), 0>, Requires<[Not16BitMode]>;
3054 def : InstAlias<"lcall\t$seg, $off", (FARCALL16i i16imm:$off, i16imm:$seg), 0>, Requires<[In16BitMode]>;
3055 def : InstAlias<"ljmp\t$seg, $off", (FARJMP16i i16imm:$off, i16imm:$seg), 0>, Requires<[In16BitMode]>;
3056 def : InstAlias<"lcall\t{*}$dst", (FARCALL16m opaque32mem:$dst), 0>, Requires<[In16BitMode]>;
3057 def : InstAlias<"ljmp\t{*}$dst", (FARJMP16m opaque32mem:$dst), 0>, Requires<[In16BitMode]>;
3059 def : InstAlias<"call\t{*}$dst", (CALL64m i64mem:$dst), 0>, Requires<[In64BitMode]>;
3060 def : InstAlias<"jmp\t{*}$dst", (JMP64m i64mem:$dst), 0>, Requires<[In64BitMode]>;
3061 def : InstAlias<"call\t{*}$dst", (CALL32m i32mem:$dst), 0>, Requires<[In32BitMode]>;
3062 def : InstAlias<"jmp\t{*}$dst", (JMP32m i32mem:$dst), 0>, Requires<[In32BitMode]>;
3063 def : InstAlias<"call\t{*}$dst", (CALL16m i16mem:$dst), 0>, Requires<[In16BitMode]>;
3064 def : InstAlias<"jmp\t{*}$dst", (JMP16m i16mem:$dst), 0>, Requires<[In16BitMode]>;
3067 // "imul <imm>, B" is an alias for "imul <imm>, B, B".
3068 def : InstAlias<"imul{w}\t{$imm, $r|$r, $imm}", (IMUL16rri GR16:$r, GR16:$r, i16imm:$imm), 0>;
3069 def : InstAlias<"imul{w}\t{$imm, $r|$r, $imm}", (IMUL16rri8 GR16:$r, GR16:$r, i16i8imm:$imm), 0>;
3070 def : InstAlias<"imul{l}\t{$imm, $r|$r, $imm}", (IMUL32rri GR32:$r, GR32:$r, i32imm:$imm), 0>;
3071 def : InstAlias<"imul{l}\t{$imm, $r|$r, $imm}", (IMUL32rri8 GR32:$r, GR32:$r, i32i8imm:$imm), 0>;
3072 def : InstAlias<"imul{q}\t{$imm, $r|$r, $imm}", (IMUL64rri32 GR64:$r, GR64:$r, i64i32imm:$imm), 0>;
3073 def : InstAlias<"imul{q}\t{$imm, $r|$r, $imm}", (IMUL64rri8 GR64:$r, GR64:$r, i64i8imm:$imm), 0>;
3075 // ins aliases. Accept the mnemonic suffix being omitted because it's implicit
3076 // in the destination.
3077 def : InstAlias<"ins\t{%dx, $dst|$dst, dx}", (INSB dstidx8:$dst), 0>;
3078 def : InstAlias<"ins\t{%dx, $dst|$dst, dx}", (INSW dstidx16:$dst), 0>;
3079 def : InstAlias<"ins\t{%dx, $dst|$dst, dx}", (INSL dstidx32:$dst), 0>;
3081 // outs aliases. Accept the mnemonic suffix being omitted because it's implicit
3083 def : InstAlias<"outs\t{$src, %dx|dx, $src}", (OUTSB srcidx8:$src), 0>;
3084 def : InstAlias<"outs\t{$src, %dx|dx, $src}", (OUTSW srcidx16:$src), 0>;
3085 def : InstAlias<"outs\t{$src, %dx|dx, $src}", (OUTSL srcidx32:$src), 0>;
3087 // inb %dx -> inb %al, %dx
3088 def : InstAlias<"inb\t{%dx|dx}", (IN8rr), 0>;
3089 def : InstAlias<"inw\t{%dx|dx}", (IN16rr), 0>;
3090 def : InstAlias<"inl\t{%dx|dx}", (IN32rr), 0>;
3091 def : InstAlias<"inb\t$port", (IN8ri u8imm:$port), 0>;
3092 def : InstAlias<"inw\t$port", (IN16ri u8imm:$port), 0>;
3093 def : InstAlias<"inl\t$port", (IN32ri u8imm:$port), 0>;
3096 // jmp and call aliases for lcall and ljmp. jmp $42,$5 -> ljmp
3097 def : InstAlias<"call\t$seg, $off", (FARCALL16i i16imm:$off, i16imm:$seg)>, Requires<[In16BitMode]>;
3098 def : InstAlias<"jmp\t$seg, $off", (FARJMP16i i16imm:$off, i16imm:$seg)>, Requires<[In16BitMode]>;
3099 def : InstAlias<"call\t$seg, $off", (FARCALL32i i32imm:$off, i16imm:$seg)>, Requires<[In32BitMode]>;
3100 def : InstAlias<"jmp\t$seg, $off", (FARJMP32i i32imm:$off, i16imm:$seg)>, Requires<[In32BitMode]>;
3101 def : InstAlias<"callw\t$seg, $off", (FARCALL16i i16imm:$off, i16imm:$seg)>, Requires<[Not64BitMode]>;
3102 def : InstAlias<"jmpw\t$seg, $off", (FARJMP16i i16imm:$off, i16imm:$seg)>, Requires<[Not64BitMode]>;
3103 def : InstAlias<"calll\t$seg, $off", (FARCALL32i i32imm:$off, i16imm:$seg)>, Requires<[Not64BitMode]>;
3104 def : InstAlias<"jmpl\t$seg, $off", (FARJMP32i i32imm:$off, i16imm:$seg)>, Requires<[Not64BitMode]>;
3106 // Force mov without a suffix with a segment and mem to prefer the 'l' form of
3107 // the move. All segment/mem forms are equivalent, this has the shortest
3109 def : InstAlias<"mov\t{$mem, $seg|$seg, $mem}", (MOV32sm SEGMENT_REG:$seg, i32mem:$mem), 0>;
3110 def : InstAlias<"mov\t{$seg, $mem|$mem, $seg}", (MOV32ms i32mem:$mem, SEGMENT_REG:$seg), 0>;
3112 // Match 'movq <largeimm>, <reg>' as an alias for movabsq.
3113 def : InstAlias<"mov{q}\t{$imm, $reg|$reg, $imm}", (MOV64ri GR64:$reg, i64imm:$imm), 0>;
3115 // Match 'movq GR64, MMX' as an alias for movd.
3116 def : InstAlias<"movq\t{$src, $dst|$dst, $src}",
3117 (MMX_MOVD64to64rr VR64:$dst, GR64:$src), 0>;
3118 def : InstAlias<"movq\t{$src, $dst|$dst, $src}",
3119 (MMX_MOVD64from64rr GR64:$dst, VR64:$src), 0>;
3122 def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX16rr8 GR16:$dst, GR8:$src), 0>;
3123 def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX16rm8 GR16:$dst, i8mem:$src), 0>;
3124 def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX32rr8 GR32:$dst, GR8:$src), 0>;
3125 def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX32rr16 GR32:$dst, GR16:$src), 0>;
3126 def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX64rr8 GR64:$dst, GR8:$src), 0>;
3127 def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX64rr16 GR64:$dst, GR16:$src), 0>;
3128 def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX64rr32 GR64:$dst, GR32:$src), 0>;
3131 def : InstAlias<"movzx\t{$src, $dst|$dst, $src}", (MOVZX16rr8 GR16:$dst, GR8:$src), 0>;
3132 def : InstAlias<"movzx\t{$src, $dst|$dst, $src}", (MOVZX16rm8 GR16:$dst, i8mem:$src), 0>;
3133 def : InstAlias<"movzx\t{$src, $dst|$dst, $src}", (MOVZX32rr8 GR32:$dst, GR8:$src), 0>;
3134 def : InstAlias<"movzx\t{$src, $dst|$dst, $src}", (MOVZX32rr16 GR32:$dst, GR16:$src), 0>;
3135 def : InstAlias<"movzx\t{$src, $dst|$dst, $src}", (MOVZX64rr8 GR64:$dst, GR8:$src), 0>;
3136 def : InstAlias<"movzx\t{$src, $dst|$dst, $src}", (MOVZX64rr16 GR64:$dst, GR16:$src), 0>;
3137 // Note: No GR32->GR64 movzx form.
3139 // outb %dx -> outb %al, %dx
3140 def : InstAlias<"outb\t{%dx|dx}", (OUT8rr), 0>;
3141 def : InstAlias<"outw\t{%dx|dx}", (OUT16rr), 0>;
3142 def : InstAlias<"outl\t{%dx|dx}", (OUT32rr), 0>;
3143 def : InstAlias<"outb\t$port", (OUT8ir u8imm:$port), 0>;
3144 def : InstAlias<"outw\t$port", (OUT16ir u8imm:$port), 0>;
3145 def : InstAlias<"outl\t$port", (OUT32ir u8imm:$port), 0>;
3147 // 'sldt <mem>' can be encoded with either sldtw or sldtq with the same
3148 // effect (both store to a 16-bit mem). Force to sldtw to avoid ambiguity
3149 // errors, since its encoding is the most compact.
3150 def : InstAlias<"sldt $mem", (SLDT16m i16mem:$mem), 0>;
3152 // shld/shrd op,op -> shld op, op, CL
3153 def : InstAlias<"shld{w}\t{$r2, $r1|$r1, $r2}", (SHLD16rrCL GR16:$r1, GR16:$r2), 0>;
3154 def : InstAlias<"shld{l}\t{$r2, $r1|$r1, $r2}", (SHLD32rrCL GR32:$r1, GR32:$r2), 0>;
3155 def : InstAlias<"shld{q}\t{$r2, $r1|$r1, $r2}", (SHLD64rrCL GR64:$r1, GR64:$r2), 0>;
3156 def : InstAlias<"shrd{w}\t{$r2, $r1|$r1, $r2}", (SHRD16rrCL GR16:$r1, GR16:$r2), 0>;
3157 def : InstAlias<"shrd{l}\t{$r2, $r1|$r1, $r2}", (SHRD32rrCL GR32:$r1, GR32:$r2), 0>;
3158 def : InstAlias<"shrd{q}\t{$r2, $r1|$r1, $r2}", (SHRD64rrCL GR64:$r1, GR64:$r2), 0>;
3160 def : InstAlias<"shld{w}\t{$reg, $mem|$mem, $reg}", (SHLD16mrCL i16mem:$mem, GR16:$reg), 0>;
3161 def : InstAlias<"shld{l}\t{$reg, $mem|$mem, $reg}", (SHLD32mrCL i32mem:$mem, GR32:$reg), 0>;
3162 def : InstAlias<"shld{q}\t{$reg, $mem|$mem, $reg}", (SHLD64mrCL i64mem:$mem, GR64:$reg), 0>;
3163 def : InstAlias<"shrd{w}\t{$reg, $mem|$mem, $reg}", (SHRD16mrCL i16mem:$mem, GR16:$reg), 0>;
3164 def : InstAlias<"shrd{l}\t{$reg, $mem|$mem, $reg}", (SHRD32mrCL i32mem:$mem, GR32:$reg), 0>;
3165 def : InstAlias<"shrd{q}\t{$reg, $mem|$mem, $reg}", (SHRD64mrCL i64mem:$mem, GR64:$reg), 0>;
3167 /* FIXME: This is disabled because the asm matcher is currently incapable of
3168 * matching a fixed immediate like $1.
3169 // "shl X, $1" is an alias for "shl X".
3170 multiclass ShiftRotateByOneAlias<string Mnemonic, string Opc> {
3171 def : InstAlias<!strconcat(Mnemonic, "b $op, $$1"),
3172 (!cast<Instruction>(!strconcat(Opc, "8r1")) GR8:$op)>;
3173 def : InstAlias<!strconcat(Mnemonic, "w $op, $$1"),
3174 (!cast<Instruction>(!strconcat(Opc, "16r1")) GR16:$op)>;
3175 def : InstAlias<!strconcat(Mnemonic, "l $op, $$1"),
3176 (!cast<Instruction>(!strconcat(Opc, "32r1")) GR32:$op)>;
3177 def : InstAlias<!strconcat(Mnemonic, "q $op, $$1"),
3178 (!cast<Instruction>(!strconcat(Opc, "64r1")) GR64:$op)>;
3179 def : InstAlias<!strconcat(Mnemonic, "b $op, $$1"),
3180 (!cast<Instruction>(!strconcat(Opc, "8m1")) i8mem:$op)>;
3181 def : InstAlias<!strconcat(Mnemonic, "w $op, $$1"),
3182 (!cast<Instruction>(!strconcat(Opc, "16m1")) i16mem:$op)>;
3183 def : InstAlias<!strconcat(Mnemonic, "l $op, $$1"),
3184 (!cast<Instruction>(!strconcat(Opc, "32m1")) i32mem:$op)>;
3185 def : InstAlias<!strconcat(Mnemonic, "q $op, $$1"),
3186 (!cast<Instruction>(!strconcat(Opc, "64m1")) i64mem:$op)>;
3189 defm : ShiftRotateByOneAlias<"rcl", "RCL">;
3190 defm : ShiftRotateByOneAlias<"rcr", "RCR">;
3191 defm : ShiftRotateByOneAlias<"rol", "ROL">;
3192 defm : ShiftRotateByOneAlias<"ror", "ROR">;
3195 // test: We accept "testX <reg>, <mem>" and "testX <mem>, <reg>" as synonyms.
3196 def : InstAlias<"test{b}\t{$val, $mem|$mem, $val}",
3197 (TEST8rm GR8 :$val, i8mem :$mem), 0>;
3198 def : InstAlias<"test{w}\t{$val, $mem|$mem, $val}",
3199 (TEST16rm GR16:$val, i16mem:$mem), 0>;
3200 def : InstAlias<"test{l}\t{$val, $mem|$mem, $val}",
3201 (TEST32rm GR32:$val, i32mem:$mem), 0>;
3202 def : InstAlias<"test{q}\t{$val, $mem|$mem, $val}",
3203 (TEST64rm GR64:$val, i64mem:$mem), 0>;
3205 // xchg: We accept "xchgX <reg>, <mem>" and "xchgX <mem>, <reg>" as synonyms.
3206 def : InstAlias<"xchg{b}\t{$mem, $val|$val, $mem}",
3207 (XCHG8rm GR8 :$val, i8mem :$mem), 0>;
3208 def : InstAlias<"xchg{w}\t{$mem, $val|$val, $mem}",
3209 (XCHG16rm GR16:$val, i16mem:$mem), 0>;
3210 def : InstAlias<"xchg{l}\t{$mem, $val|$val, $mem}",
3211 (XCHG32rm GR32:$val, i32mem:$mem), 0>;
3212 def : InstAlias<"xchg{q}\t{$mem, $val|$val, $mem}",
3213 (XCHG64rm GR64:$val, i64mem:$mem), 0>;
3215 // xchg: We accept "xchgX <reg>, %eax" and "xchgX %eax, <reg>" as synonyms.
3216 def : InstAlias<"xchg{w}\t{%ax, $src|$src, ax}", (XCHG16ar GR16:$src), 0>;
3217 def : InstAlias<"xchg{l}\t{%eax, $src|$src, eax}",
3218 (XCHG32ar GR32:$src), 0>, Requires<[Not64BitMode]>;
3219 def : InstAlias<"xchg{l}\t{%eax, $src|$src, eax}",
3220 (XCHG32ar64 GR32_NOAX:$src), 0>, Requires<[In64BitMode]>;
3221 def : InstAlias<"xchg{q}\t{%rax, $src|$src, rax}", (XCHG64ar GR64:$src), 0>;
3223 // These aliases exist to get the parser to prioritize matching 8-bit
3224 // immediate encodings over matching the implicit ax/eax/rax encodings. By
3225 // explicitly mentioning the A register here, these entries will be ordered
3226 // first due to the more explicit immediate type.
3227 def : InstAlias<"adc{w}\t{$imm, %ax|ax, $imm}", (ADC16ri8 AX, i16i8imm:$imm), 0>;
3228 def : InstAlias<"add{w}\t{$imm, %ax|ax, $imm}", (ADD16ri8 AX, i16i8imm:$imm), 0>;
3229 def : InstAlias<"and{w}\t{$imm, %ax|ax, $imm}", (AND16ri8 AX, i16i8imm:$imm), 0>;
3230 def : InstAlias<"cmp{w}\t{$imm, %ax|ax, $imm}", (CMP16ri8 AX, i16i8imm:$imm), 0>;
3231 def : InstAlias<"or{w}\t{$imm, %ax|ax, $imm}", (OR16ri8 AX, i16i8imm:$imm), 0>;
3232 def : InstAlias<"sbb{w}\t{$imm, %ax|ax, $imm}", (SBB16ri8 AX, i16i8imm:$imm), 0>;
3233 def : InstAlias<"sub{w}\t{$imm, %ax|ax, $imm}", (SUB16ri8 AX, i16i8imm:$imm), 0>;
3234 def : InstAlias<"xor{w}\t{$imm, %ax|ax, $imm}", (XOR16ri8 AX, i16i8imm:$imm), 0>;
3236 def : InstAlias<"adc{l}\t{$imm, %eax|eax, $imm}", (ADC32ri8 EAX, i32i8imm:$imm), 0>;
3237 def : InstAlias<"add{l}\t{$imm, %eax|eax, $imm}", (ADD32ri8 EAX, i32i8imm:$imm), 0>;
3238 def : InstAlias<"and{l}\t{$imm, %eax|eax, $imm}", (AND32ri8 EAX, i32i8imm:$imm), 0>;
3239 def : InstAlias<"cmp{l}\t{$imm, %eax|eax, $imm}", (CMP32ri8 EAX, i32i8imm:$imm), 0>;
3240 def : InstAlias<"or{l}\t{$imm, %eax|eax, $imm}", (OR32ri8 EAX, i32i8imm:$imm), 0>;
3241 def : InstAlias<"sbb{l}\t{$imm, %eax|eax, $imm}", (SBB32ri8 EAX, i32i8imm:$imm), 0>;
3242 def : InstAlias<"sub{l}\t{$imm, %eax|eax, $imm}", (SUB32ri8 EAX, i32i8imm:$imm), 0>;
3243 def : InstAlias<"xor{l}\t{$imm, %eax|eax, $imm}", (XOR32ri8 EAX, i32i8imm:$imm), 0>;
3245 def : InstAlias<"adc{q}\t{$imm, %rax|rax, $imm}", (ADC64ri8 RAX, i64i8imm:$imm), 0>;
3246 def : InstAlias<"add{q}\t{$imm, %rax|rax, $imm}", (ADD64ri8 RAX, i64i8imm:$imm), 0>;
3247 def : InstAlias<"and{q}\t{$imm, %rax|rax, $imm}", (AND64ri8 RAX, i64i8imm:$imm), 0>;
3248 def : InstAlias<"cmp{q}\t{$imm, %rax|rax, $imm}", (CMP64ri8 RAX, i64i8imm:$imm), 0>;
3249 def : InstAlias<"or{q}\t{$imm, %rax|rax, $imm}", (OR64ri8 RAX, i64i8imm:$imm), 0>;
3250 def : InstAlias<"sbb{q}\t{$imm, %rax|rax, $imm}", (SBB64ri8 RAX, i64i8imm:$imm), 0>;
3251 def : InstAlias<"sub{q}\t{$imm, %rax|rax, $imm}", (SUB64ri8 RAX, i64i8imm:$imm), 0>;
3252 def : InstAlias<"xor{q}\t{$imm, %rax|rax, $imm}", (XOR64ri8 RAX, i64i8imm:$imm), 0>;