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>]>;
88 def SDT_X86CallSeqEnd : SDCallSeqEnd<[SDTCisVT<0, i32>,
91 def SDT_X86Call : SDTypeProfile<0, -1, [SDTCisVT<0, iPTR>]>;
93 def SDT_X86VASTART_SAVE_XMM_REGS : SDTypeProfile<0, -1, [SDTCisVT<0, i8>,
97 def SDT_X86VAARG_64 : SDTypeProfile<1, -1, [SDTCisPtrTy<0>,
103 def SDTX86RepStr : SDTypeProfile<0, 1, [SDTCisVT<0, OtherVT>]>;
105 def SDTX86Void : SDTypeProfile<0, 0, []>;
107 def SDTX86Wrapper : SDTypeProfile<1, 1, [SDTCisSameAs<0, 1>, SDTCisPtrTy<0>]>;
109 def SDT_X86TLSADDR : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
111 def SDT_X86TLSBASEADDR : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
113 def SDT_X86TLSCALL : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
115 def SDT_X86WIN_ALLOCA : SDTypeProfile<0, 1, [SDTCisVT<0, iPTR>]>;
117 def SDT_X86SEG_ALLOCA : SDTypeProfile<1, 1, [SDTCisVT<0, iPTR>, SDTCisVT<1, iPTR>]>;
119 def SDT_X86EHRET : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
121 def SDT_X86TCRET : SDTypeProfile<0, 2, [SDTCisPtrTy<0>, SDTCisVT<1, i32>]>;
123 def SDT_X86MEMBARRIER : SDTypeProfile<0, 0, []>;
125 def X86MemBarrier : SDNode<"X86ISD::MEMBARRIER", SDT_X86MEMBARRIER,
126 [SDNPHasChain,SDNPSideEffect]>;
127 def X86MFence : SDNode<"X86ISD::MFENCE", SDT_X86MEMBARRIER,
131 def X86bsf : SDNode<"X86ISD::BSF", SDTUnaryArithWithFlags>;
132 def X86bsr : SDNode<"X86ISD::BSR", SDTUnaryArithWithFlags>;
133 def X86shld : SDNode<"X86ISD::SHLD", SDTIntShiftDOp>;
134 def X86shrd : SDNode<"X86ISD::SHRD", SDTIntShiftDOp>;
136 def X86cmp : SDNode<"X86ISD::CMP" , SDTX86CmpTest>;
137 def X86bt : SDNode<"X86ISD::BT", SDTX86CmpTest>;
139 def X86cmov : SDNode<"X86ISD::CMOV", SDTX86Cmov>;
140 def X86brcond : SDNode<"X86ISD::BRCOND", SDTX86BrCond,
142 def X86setcc : SDNode<"X86ISD::SETCC", SDTX86SetCC>;
143 def X86setcc_c : SDNode<"X86ISD::SETCC_CARRY", SDTX86SetCC_C>;
145 def X86sahf : SDNode<"X86ISD::SAHF", SDTX86sahf>;
147 def X86rdrand : SDNode<"X86ISD::RDRAND", SDTX86rdrand,
148 [SDNPHasChain, SDNPSideEffect]>;
150 def X86rdseed : SDNode<"X86ISD::RDSEED", SDTX86rdrand,
151 [SDNPHasChain, SDNPSideEffect]>;
153 def X86cas : SDNode<"X86ISD::LCMPXCHG_DAG", SDTX86cas,
154 [SDNPHasChain, SDNPInGlue, SDNPOutGlue, SDNPMayStore,
155 SDNPMayLoad, SDNPMemOperand]>;
156 def X86cas8 : SDNode<"X86ISD::LCMPXCHG8_DAG", SDTX86caspair,
157 [SDNPHasChain, SDNPInGlue, SDNPOutGlue, SDNPMayStore,
158 SDNPMayLoad, SDNPMemOperand]>;
159 def X86cas16 : SDNode<"X86ISD::LCMPXCHG16_DAG", SDTX86caspair,
160 [SDNPHasChain, SDNPInGlue, SDNPOutGlue, SDNPMayStore,
161 SDNPMayLoad, SDNPMemOperand]>;
162 def X86cas8save_ebx : SDNode<"X86ISD::LCMPXCHG8_SAVE_EBX_DAG",
163 SDTX86caspairSaveEbx8,
164 [SDNPHasChain, SDNPInGlue, SDNPOutGlue,
165 SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
166 def X86cas16save_rbx : SDNode<"X86ISD::LCMPXCHG16_SAVE_RBX_DAG",
167 SDTX86caspairSaveRbx16,
168 [SDNPHasChain, SDNPInGlue, SDNPOutGlue,
169 SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
171 def X86retflag : SDNode<"X86ISD::RET_FLAG", SDTX86Ret,
172 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
173 def X86iret : SDNode<"X86ISD::IRET", SDTX86Ret,
174 [SDNPHasChain, SDNPOptInGlue]>;
176 def X86vastart_save_xmm_regs :
177 SDNode<"X86ISD::VASTART_SAVE_XMM_REGS",
178 SDT_X86VASTART_SAVE_XMM_REGS,
179 [SDNPHasChain, SDNPVariadic]>;
181 SDNode<"X86ISD::VAARG_64", SDT_X86VAARG_64,
182 [SDNPHasChain, SDNPMayLoad, SDNPMayStore,
184 def X86callseq_start :
185 SDNode<"ISD::CALLSEQ_START", SDT_X86CallSeqStart,
186 [SDNPHasChain, SDNPOutGlue]>;
188 SDNode<"ISD::CALLSEQ_END", SDT_X86CallSeqEnd,
189 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
191 def X86call : SDNode<"X86ISD::CALL", SDT_X86Call,
192 [SDNPHasChain, SDNPOutGlue, SDNPOptInGlue,
195 def X86rep_stos: SDNode<"X86ISD::REP_STOS", SDTX86RepStr,
196 [SDNPHasChain, SDNPInGlue, SDNPOutGlue, SDNPMayStore]>;
197 def X86rep_movs: SDNode<"X86ISD::REP_MOVS", SDTX86RepStr,
198 [SDNPHasChain, SDNPInGlue, SDNPOutGlue, SDNPMayStore,
201 def X86rdtsc : SDNode<"X86ISD::RDTSC_DAG", SDTX86Void,
202 [SDNPHasChain, SDNPOutGlue, SDNPSideEffect]>;
203 def X86rdtscp : SDNode<"X86ISD::RDTSCP_DAG", SDTX86Void,
204 [SDNPHasChain, SDNPOutGlue, SDNPSideEffect]>;
205 def X86rdpmc : SDNode<"X86ISD::RDPMC_DAG", SDTX86Void,
206 [SDNPHasChain, SDNPOutGlue, SDNPSideEffect]>;
208 def X86Wrapper : SDNode<"X86ISD::Wrapper", SDTX86Wrapper>;
209 def X86WrapperRIP : SDNode<"X86ISD::WrapperRIP", SDTX86Wrapper>;
211 def X86RecoverFrameAlloc : SDNode<"ISD::LOCAL_RECOVER",
212 SDTypeProfile<1, 1, [SDTCisSameAs<0, 1>,
215 def X86tlsaddr : SDNode<"X86ISD::TLSADDR", SDT_X86TLSADDR,
216 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
218 def X86tlsbaseaddr : SDNode<"X86ISD::TLSBASEADDR", SDT_X86TLSBASEADDR,
219 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
221 def X86ehret : SDNode<"X86ISD::EH_RETURN", SDT_X86EHRET,
224 def X86eh_sjlj_setjmp : SDNode<"X86ISD::EH_SJLJ_SETJMP",
225 SDTypeProfile<1, 1, [SDTCisInt<0>,
227 [SDNPHasChain, SDNPSideEffect]>;
228 def X86eh_sjlj_longjmp : SDNode<"X86ISD::EH_SJLJ_LONGJMP",
229 SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>,
230 [SDNPHasChain, SDNPSideEffect]>;
231 def X86eh_sjlj_setup_dispatch : SDNode<"X86ISD::EH_SJLJ_SETUP_DISPATCH",
232 SDTypeProfile<0, 0, []>,
233 [SDNPHasChain, SDNPSideEffect]>;
235 def X86tcret : SDNode<"X86ISD::TC_RETURN", SDT_X86TCRET,
236 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
238 def X86add_flag : SDNode<"X86ISD::ADD", SDTBinaryArithWithFlags,
240 def X86sub_flag : SDNode<"X86ISD::SUB", SDTBinaryArithWithFlags>;
241 def X86smul_flag : SDNode<"X86ISD::SMUL", SDTBinaryArithWithFlags,
243 def X86umul_flag : SDNode<"X86ISD::UMUL", SDT2ResultBinaryArithWithFlags,
245 def X86adc_flag : SDNode<"X86ISD::ADC", SDTBinaryArithWithFlagsInOut>;
246 def X86sbb_flag : SDNode<"X86ISD::SBB", SDTBinaryArithWithFlagsInOut>;
248 def X86inc_flag : SDNode<"X86ISD::INC", SDTUnaryArithWithFlags>;
249 def X86dec_flag : SDNode<"X86ISD::DEC", SDTUnaryArithWithFlags>;
250 def X86or_flag : SDNode<"X86ISD::OR", SDTBinaryArithWithFlags,
252 def X86xor_flag : SDNode<"X86ISD::XOR", SDTBinaryArithWithFlags,
254 def X86and_flag : SDNode<"X86ISD::AND", SDTBinaryArithWithFlags,
257 def X86lock_add : SDNode<"X86ISD::LADD", SDTLockBinaryArithWithFlags,
258 [SDNPHasChain, SDNPMayStore, SDNPMayLoad,
260 def X86lock_sub : SDNode<"X86ISD::LSUB", SDTLockBinaryArithWithFlags,
261 [SDNPHasChain, SDNPMayStore, SDNPMayLoad,
263 def X86lock_or : SDNode<"X86ISD::LOR", SDTLockBinaryArithWithFlags,
264 [SDNPHasChain, SDNPMayStore, SDNPMayLoad,
266 def X86lock_xor : SDNode<"X86ISD::LXOR", SDTLockBinaryArithWithFlags,
267 [SDNPHasChain, SDNPMayStore, SDNPMayLoad,
269 def X86lock_and : SDNode<"X86ISD::LAND", SDTLockBinaryArithWithFlags,
270 [SDNPHasChain, SDNPMayStore, SDNPMayLoad,
273 def X86bextr : SDNode<"X86ISD::BEXTR", SDTIntBinOp>;
275 def X86mul_imm : SDNode<"X86ISD::MUL_IMM", SDTIntBinOp>;
277 def X86WinAlloca : SDNode<"X86ISD::WIN_ALLOCA", SDT_X86WIN_ALLOCA,
278 [SDNPHasChain, SDNPOutGlue]>;
280 def X86SegAlloca : SDNode<"X86ISD::SEG_ALLOCA", SDT_X86SEG_ALLOCA,
283 def X86TLSCall : SDNode<"X86ISD::TLSCALL", SDT_X86TLSCALL,
284 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
286 def X86lwpins : SDNode<"X86ISD::LWPINS",
287 SDTypeProfile<1, 3, [SDTCisVT<0, i32>, SDTCisInt<1>,
288 SDTCisVT<2, i32>, SDTCisVT<3, i32>]>,
289 [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPSideEffect]>;
291 //===----------------------------------------------------------------------===//
292 // X86 Operand Definitions.
295 // A version of ptr_rc which excludes SP, ESP, and RSP. This is used for
296 // the index operand of an address, to conform to x86 encoding restrictions.
297 def ptr_rc_nosp : PointerLikeRegClass<1>;
299 // *mem - Operand definitions for the funky X86 addressing mode operands.
301 def X86MemAsmOperand : AsmOperandClass {
304 let RenderMethod = "addMemOperands", SuperClasses = [X86MemAsmOperand] in {
305 def X86Mem8AsmOperand : AsmOperandClass { let Name = "Mem8"; }
306 def X86Mem16AsmOperand : AsmOperandClass { let Name = "Mem16"; }
307 def X86Mem32AsmOperand : AsmOperandClass { let Name = "Mem32"; }
308 def X86Mem64AsmOperand : AsmOperandClass { let Name = "Mem64"; }
309 def X86Mem80AsmOperand : AsmOperandClass { let Name = "Mem80"; }
310 def X86Mem128AsmOperand : AsmOperandClass { let Name = "Mem128"; }
311 def X86Mem256AsmOperand : AsmOperandClass { let Name = "Mem256"; }
312 def X86Mem512AsmOperand : AsmOperandClass { let Name = "Mem512"; }
313 // Gather mem operands
314 def X86Mem64_RC128Operand : AsmOperandClass { let Name = "Mem64_RC128"; }
315 def X86Mem128_RC128Operand : AsmOperandClass { let Name = "Mem128_RC128"; }
316 def X86Mem256_RC128Operand : AsmOperandClass { let Name = "Mem256_RC128"; }
317 def X86Mem128_RC256Operand : AsmOperandClass { let Name = "Mem128_RC256"; }
318 def X86Mem256_RC256Operand : AsmOperandClass { let Name = "Mem256_RC256"; }
320 def X86Mem64_RC128XOperand : AsmOperandClass { let Name = "Mem64_RC128X"; }
321 def X86Mem128_RC128XOperand : AsmOperandClass { let Name = "Mem128_RC128X"; }
322 def X86Mem256_RC128XOperand : AsmOperandClass { let Name = "Mem256_RC128X"; }
323 def X86Mem128_RC256XOperand : AsmOperandClass { let Name = "Mem128_RC256X"; }
324 def X86Mem256_RC256XOperand : AsmOperandClass { let Name = "Mem256_RC256X"; }
325 def X86Mem512_RC256XOperand : AsmOperandClass { let Name = "Mem512_RC256X"; }
326 def X86Mem256_RC512Operand : AsmOperandClass { let Name = "Mem256_RC512"; }
327 def X86Mem512_RC512Operand : AsmOperandClass { let Name = "Mem512_RC512"; }
330 def X86AbsMemAsmOperand : AsmOperandClass {
332 let SuperClasses = [X86MemAsmOperand];
335 class X86MemOperand<string printMethod,
336 AsmOperandClass parserMatchClass = X86MemAsmOperand> : Operand<iPTR> {
337 let PrintMethod = printMethod;
338 let MIOperandInfo = (ops ptr_rc, i8imm, ptr_rc_nosp, i32imm, SEGMENT_REG);
339 let ParserMatchClass = parserMatchClass;
340 let OperandType = "OPERAND_MEMORY";
343 // Gather mem operands
344 class X86VMemOperand<RegisterClass RC, string printMethod,
345 AsmOperandClass parserMatchClass>
346 : X86MemOperand<printMethod, parserMatchClass> {
347 let MIOperandInfo = (ops ptr_rc, i8imm, RC, i32imm, SEGMENT_REG);
350 def anymem : X86MemOperand<"printanymem">;
352 def opaque32mem : X86MemOperand<"printopaquemem">;
353 def opaque48mem : X86MemOperand<"printopaquemem">;
354 def opaque80mem : X86MemOperand<"printopaquemem">;
355 def opaque512mem : X86MemOperand<"printopaquemem">;
357 def i8mem : X86MemOperand<"printi8mem", X86Mem8AsmOperand>;
358 def i16mem : X86MemOperand<"printi16mem", X86Mem16AsmOperand>;
359 def i32mem : X86MemOperand<"printi32mem", X86Mem32AsmOperand>;
360 def i64mem : X86MemOperand<"printi64mem", X86Mem64AsmOperand>;
361 def i128mem : X86MemOperand<"printi128mem", X86Mem128AsmOperand>;
362 def i256mem : X86MemOperand<"printi256mem", X86Mem256AsmOperand>;
363 def i512mem : X86MemOperand<"printi512mem", X86Mem512AsmOperand>;
364 def f32mem : X86MemOperand<"printf32mem", X86Mem32AsmOperand>;
365 def f64mem : X86MemOperand<"printf64mem", X86Mem64AsmOperand>;
366 def f80mem : X86MemOperand<"printf80mem", X86Mem80AsmOperand>;
367 def f128mem : X86MemOperand<"printf128mem", X86Mem128AsmOperand>;
368 def f256mem : X86MemOperand<"printf256mem", X86Mem256AsmOperand>;
369 def f512mem : X86MemOperand<"printf512mem", X86Mem512AsmOperand>;
371 def v512mem : X86VMemOperand<VR512, "printf512mem", X86Mem512AsmOperand>;
373 // Gather mem operands
374 def vx64mem : X86VMemOperand<VR128, "printi64mem", X86Mem64_RC128Operand>;
375 def vx128mem : X86VMemOperand<VR128, "printi128mem", X86Mem128_RC128Operand>;
376 def vx256mem : X86VMemOperand<VR128, "printi256mem", X86Mem256_RC128Operand>;
377 def vy128mem : X86VMemOperand<VR256, "printi128mem", X86Mem128_RC256Operand>;
378 def vy256mem : X86VMemOperand<VR256, "printi256mem", X86Mem256_RC256Operand>;
380 def vx64xmem : X86VMemOperand<VR128X, "printi64mem", X86Mem64_RC128XOperand>;
381 def vx128xmem : X86VMemOperand<VR128X, "printi128mem", X86Mem128_RC128XOperand>;
382 def vx256xmem : X86VMemOperand<VR128X, "printi256mem", X86Mem256_RC128XOperand>;
383 def vy128xmem : X86VMemOperand<VR256X, "printi128mem", X86Mem128_RC256XOperand>;
384 def vy256xmem : X86VMemOperand<VR256X, "printi256mem", X86Mem256_RC256XOperand>;
385 def vy512mem : X86VMemOperand<VR256X, "printi512mem", X86Mem512_RC256XOperand>;
386 def vz256xmem : X86VMemOperand<VR512, "printi256mem", X86Mem256_RC512Operand>;
387 def vz512mem : X86VMemOperand<VR512, "printi512mem", X86Mem512_RC512Operand>;
389 // A version of i8mem for use on x86-64 and x32 that uses a NOREX GPR instead
390 // of a plain GPR, so that it doesn't potentially require a REX prefix.
391 def ptr_rc_norex : PointerLikeRegClass<2>;
392 def ptr_rc_norex_nosp : PointerLikeRegClass<3>;
394 def i8mem_NOREX : Operand<iPTR> {
395 let PrintMethod = "printi8mem";
396 let MIOperandInfo = (ops ptr_rc_norex, i8imm, ptr_rc_norex_nosp, i32imm,
398 let ParserMatchClass = X86Mem8AsmOperand;
399 let OperandType = "OPERAND_MEMORY";
402 // GPRs available for tailcall.
403 // It represents GR32_TC, GR64_TC or GR64_TCW64.
404 def ptr_rc_tailcall : PointerLikeRegClass<4>;
406 // Special i32mem for addresses of load folding tail calls. These are not
407 // allowed to use callee-saved registers since they must be scheduled
408 // after callee-saved register are popped.
409 def i32mem_TC : Operand<i32> {
410 let PrintMethod = "printi32mem";
411 let MIOperandInfo = (ops ptr_rc_tailcall, i8imm, ptr_rc_tailcall,
412 i32imm, SEGMENT_REG);
413 let ParserMatchClass = X86Mem32AsmOperand;
414 let OperandType = "OPERAND_MEMORY";
417 // Special i64mem for addresses of load folding tail calls. These are not
418 // allowed to use callee-saved registers since they must be scheduled
419 // after callee-saved register are popped.
420 def i64mem_TC : Operand<i64> {
421 let PrintMethod = "printi64mem";
422 let MIOperandInfo = (ops ptr_rc_tailcall, i8imm,
423 ptr_rc_tailcall, i32imm, SEGMENT_REG);
424 let ParserMatchClass = X86Mem64AsmOperand;
425 let OperandType = "OPERAND_MEMORY";
428 let OperandType = "OPERAND_PCREL",
429 ParserMatchClass = X86AbsMemAsmOperand,
430 PrintMethod = "printPCRelImm" in {
431 def i32imm_pcrel : Operand<i32>;
432 def i16imm_pcrel : Operand<i16>;
434 // Branch targets have OtherVT type and print as pc-relative values.
435 def brtarget : Operand<OtherVT>;
436 def brtarget8 : Operand<OtherVT>;
440 // Special parser to detect 16-bit mode to select 16-bit displacement.
441 def X86AbsMem16AsmOperand : AsmOperandClass {
442 let Name = "AbsMem16";
443 let RenderMethod = "addAbsMemOperands";
444 let SuperClasses = [X86AbsMemAsmOperand];
447 // Branch targets have OtherVT type and print as pc-relative values.
448 let OperandType = "OPERAND_PCREL",
449 PrintMethod = "printPCRelImm" in {
450 let ParserMatchClass = X86AbsMem16AsmOperand in
451 def brtarget16 : Operand<OtherVT>;
452 let ParserMatchClass = X86AbsMemAsmOperand in
453 def brtarget32 : Operand<OtherVT>;
456 let RenderMethod = "addSrcIdxOperands" in {
457 def X86SrcIdx8Operand : AsmOperandClass {
458 let Name = "SrcIdx8";
459 let SuperClasses = [X86Mem8AsmOperand];
461 def X86SrcIdx16Operand : AsmOperandClass {
462 let Name = "SrcIdx16";
463 let SuperClasses = [X86Mem16AsmOperand];
465 def X86SrcIdx32Operand : AsmOperandClass {
466 let Name = "SrcIdx32";
467 let SuperClasses = [X86Mem32AsmOperand];
469 def X86SrcIdx64Operand : AsmOperandClass {
470 let Name = "SrcIdx64";
471 let SuperClasses = [X86Mem64AsmOperand];
473 } // RenderMethod = "addSrcIdxOperands"
475 let RenderMethod = "addDstIdxOperands" in {
476 def X86DstIdx8Operand : AsmOperandClass {
477 let Name = "DstIdx8";
478 let SuperClasses = [X86Mem8AsmOperand];
480 def X86DstIdx16Operand : AsmOperandClass {
481 let Name = "DstIdx16";
482 let SuperClasses = [X86Mem16AsmOperand];
484 def X86DstIdx32Operand : AsmOperandClass {
485 let Name = "DstIdx32";
486 let SuperClasses = [X86Mem32AsmOperand];
488 def X86DstIdx64Operand : AsmOperandClass {
489 let Name = "DstIdx64";
490 let SuperClasses = [X86Mem64AsmOperand];
492 } // RenderMethod = "addDstIdxOperands"
494 let RenderMethod = "addMemOffsOperands" in {
495 def X86MemOffs16_8AsmOperand : AsmOperandClass {
496 let Name = "MemOffs16_8";
497 let SuperClasses = [X86Mem8AsmOperand];
499 def X86MemOffs16_16AsmOperand : AsmOperandClass {
500 let Name = "MemOffs16_16";
501 let SuperClasses = [X86Mem16AsmOperand];
503 def X86MemOffs16_32AsmOperand : AsmOperandClass {
504 let Name = "MemOffs16_32";
505 let SuperClasses = [X86Mem32AsmOperand];
507 def X86MemOffs32_8AsmOperand : AsmOperandClass {
508 let Name = "MemOffs32_8";
509 let SuperClasses = [X86Mem8AsmOperand];
511 def X86MemOffs32_16AsmOperand : AsmOperandClass {
512 let Name = "MemOffs32_16";
513 let SuperClasses = [X86Mem16AsmOperand];
515 def X86MemOffs32_32AsmOperand : AsmOperandClass {
516 let Name = "MemOffs32_32";
517 let SuperClasses = [X86Mem32AsmOperand];
519 def X86MemOffs32_64AsmOperand : AsmOperandClass {
520 let Name = "MemOffs32_64";
521 let SuperClasses = [X86Mem64AsmOperand];
523 def X86MemOffs64_8AsmOperand : AsmOperandClass {
524 let Name = "MemOffs64_8";
525 let SuperClasses = [X86Mem8AsmOperand];
527 def X86MemOffs64_16AsmOperand : AsmOperandClass {
528 let Name = "MemOffs64_16";
529 let SuperClasses = [X86Mem16AsmOperand];
531 def X86MemOffs64_32AsmOperand : AsmOperandClass {
532 let Name = "MemOffs64_32";
533 let SuperClasses = [X86Mem32AsmOperand];
535 def X86MemOffs64_64AsmOperand : AsmOperandClass {
536 let Name = "MemOffs64_64";
537 let SuperClasses = [X86Mem64AsmOperand];
539 } // RenderMethod = "addMemOffsOperands"
541 class X86SrcIdxOperand<string printMethod, AsmOperandClass parserMatchClass>
542 : X86MemOperand<printMethod, parserMatchClass> {
543 let MIOperandInfo = (ops ptr_rc, SEGMENT_REG);
546 class X86DstIdxOperand<string printMethod, AsmOperandClass parserMatchClass>
547 : X86MemOperand<printMethod, parserMatchClass> {
548 let MIOperandInfo = (ops ptr_rc);
551 def srcidx8 : X86SrcIdxOperand<"printSrcIdx8", X86SrcIdx8Operand>;
552 def srcidx16 : X86SrcIdxOperand<"printSrcIdx16", X86SrcIdx16Operand>;
553 def srcidx32 : X86SrcIdxOperand<"printSrcIdx32", X86SrcIdx32Operand>;
554 def srcidx64 : X86SrcIdxOperand<"printSrcIdx64", X86SrcIdx64Operand>;
555 def dstidx8 : X86DstIdxOperand<"printDstIdx8", X86DstIdx8Operand>;
556 def dstidx16 : X86DstIdxOperand<"printDstIdx16", X86DstIdx16Operand>;
557 def dstidx32 : X86DstIdxOperand<"printDstIdx32", X86DstIdx32Operand>;
558 def dstidx64 : X86DstIdxOperand<"printDstIdx64", X86DstIdx64Operand>;
560 class X86MemOffsOperand<Operand immOperand, string printMethod,
561 AsmOperandClass parserMatchClass>
562 : X86MemOperand<printMethod, parserMatchClass> {
563 let MIOperandInfo = (ops immOperand, SEGMENT_REG);
566 def offset16_8 : X86MemOffsOperand<i16imm, "printMemOffs8",
567 X86MemOffs16_8AsmOperand>;
568 def offset16_16 : X86MemOffsOperand<i16imm, "printMemOffs16",
569 X86MemOffs16_16AsmOperand>;
570 def offset16_32 : X86MemOffsOperand<i16imm, "printMemOffs32",
571 X86MemOffs16_32AsmOperand>;
572 def offset32_8 : X86MemOffsOperand<i32imm, "printMemOffs8",
573 X86MemOffs32_8AsmOperand>;
574 def offset32_16 : X86MemOffsOperand<i32imm, "printMemOffs16",
575 X86MemOffs32_16AsmOperand>;
576 def offset32_32 : X86MemOffsOperand<i32imm, "printMemOffs32",
577 X86MemOffs32_32AsmOperand>;
578 def offset32_64 : X86MemOffsOperand<i32imm, "printMemOffs64",
579 X86MemOffs32_64AsmOperand>;
580 def offset64_8 : X86MemOffsOperand<i64imm, "printMemOffs8",
581 X86MemOffs64_8AsmOperand>;
582 def offset64_16 : X86MemOffsOperand<i64imm, "printMemOffs16",
583 X86MemOffs64_16AsmOperand>;
584 def offset64_32 : X86MemOffsOperand<i64imm, "printMemOffs32",
585 X86MemOffs64_32AsmOperand>;
586 def offset64_64 : X86MemOffsOperand<i64imm, "printMemOffs64",
587 X86MemOffs64_64AsmOperand>;
589 def SSECC : Operand<i8> {
590 let PrintMethod = "printSSEAVXCC";
591 let OperandType = "OPERAND_IMMEDIATE";
594 def i8immZExt3 : ImmLeaf<i8, [{
595 return Imm >= 0 && Imm < 8;
598 def AVXCC : Operand<i8> {
599 let PrintMethod = "printSSEAVXCC";
600 let OperandType = "OPERAND_IMMEDIATE";
603 def i8immZExt5 : ImmLeaf<i8, [{
604 return Imm >= 0 && Imm < 32;
607 def AVX512ICC : Operand<i8> {
608 let PrintMethod = "printSSEAVXCC";
609 let OperandType = "OPERAND_IMMEDIATE";
612 def XOPCC : Operand<i8> {
613 let PrintMethod = "printXOPCC";
614 let OperandType = "OPERAND_IMMEDIATE";
617 class ImmSExtAsmOperandClass : AsmOperandClass {
618 let SuperClasses = [ImmAsmOperand];
619 let RenderMethod = "addImmOperands";
622 def X86GR32orGR64AsmOperand : AsmOperandClass {
623 let Name = "GR32orGR64";
626 def GR32orGR64 : RegisterOperand<GR32> {
627 let ParserMatchClass = X86GR32orGR64AsmOperand;
629 def AVX512RCOperand : AsmOperandClass {
630 let Name = "AVX512RC";
632 def AVX512RC : Operand<i32> {
633 let PrintMethod = "printRoundingControl";
634 let OperandType = "OPERAND_IMMEDIATE";
635 let ParserMatchClass = AVX512RCOperand;
638 // Sign-extended immediate classes. We don't need to define the full lattice
639 // here because there is no instruction with an ambiguity between ImmSExti64i32
642 // The strange ranges come from the fact that the assembler always works with
643 // 64-bit immediates, but for a 16-bit target value we want to accept both "-1"
644 // (which will be a -1ULL), and "0xFF" (-1 in 16-bits).
647 // [0xFFFFFFFF80000000, 0xFFFFFFFFFFFFFFFF]
648 def ImmSExti64i32AsmOperand : ImmSExtAsmOperandClass {
649 let Name = "ImmSExti64i32";
652 // [0, 0x0000007F] | [0x000000000000FF80, 0x000000000000FFFF] |
653 // [0xFFFFFFFFFFFFFF80, 0xFFFFFFFFFFFFFFFF]
654 def ImmSExti16i8AsmOperand : ImmSExtAsmOperandClass {
655 let Name = "ImmSExti16i8";
656 let SuperClasses = [ImmSExti64i32AsmOperand];
659 // [0, 0x0000007F] | [0x00000000FFFFFF80, 0x00000000FFFFFFFF] |
660 // [0xFFFFFFFFFFFFFF80, 0xFFFFFFFFFFFFFFFF]
661 def ImmSExti32i8AsmOperand : ImmSExtAsmOperandClass {
662 let Name = "ImmSExti32i8";
666 // [0xFFFFFFFFFFFFFF80, 0xFFFFFFFFFFFFFFFF]
667 def ImmSExti64i8AsmOperand : ImmSExtAsmOperandClass {
668 let Name = "ImmSExti64i8";
669 let SuperClasses = [ImmSExti16i8AsmOperand, ImmSExti32i8AsmOperand,
670 ImmSExti64i32AsmOperand];
673 // Unsigned immediate used by SSE/AVX instructions
675 // [0xFFFFFFFFFFFFFF80, 0xFFFFFFFFFFFFFFFF]
676 def ImmUnsignedi8AsmOperand : AsmOperandClass {
677 let Name = "ImmUnsignedi8";
678 let RenderMethod = "addImmOperands";
681 // A couple of more descriptive operand definitions.
682 // 16-bits but only 8 bits are significant.
683 def i16i8imm : Operand<i16> {
684 let ParserMatchClass = ImmSExti16i8AsmOperand;
685 let OperandType = "OPERAND_IMMEDIATE";
687 // 32-bits but only 8 bits are significant.
688 def i32i8imm : Operand<i32> {
689 let ParserMatchClass = ImmSExti32i8AsmOperand;
690 let OperandType = "OPERAND_IMMEDIATE";
693 // 64-bits but only 32 bits are significant.
694 def i64i32imm : Operand<i64> {
695 let ParserMatchClass = ImmSExti64i32AsmOperand;
696 let OperandType = "OPERAND_IMMEDIATE";
699 // 64-bits but only 8 bits are significant.
700 def i64i8imm : Operand<i64> {
701 let ParserMatchClass = ImmSExti64i8AsmOperand;
702 let OperandType = "OPERAND_IMMEDIATE";
705 // Unsigned 8-bit immediate used by SSE/AVX instructions.
706 def u8imm : Operand<i8> {
707 let PrintMethod = "printU8Imm";
708 let ParserMatchClass = ImmUnsignedi8AsmOperand;
709 let OperandType = "OPERAND_IMMEDIATE";
712 // 32-bit immediate but only 8-bits are significant and they are unsigned.
713 // Used by some SSE/AVX instructions that use intrinsics.
714 def i32u8imm : Operand<i32> {
715 let PrintMethod = "printU8Imm";
716 let ParserMatchClass = ImmUnsignedi8AsmOperand;
717 let OperandType = "OPERAND_IMMEDIATE";
720 // 64-bits but only 32 bits are significant, and those bits are treated as being
722 def i64i32imm_pcrel : Operand<i64> {
723 let PrintMethod = "printPCRelImm";
724 let ParserMatchClass = X86AbsMemAsmOperand;
725 let OperandType = "OPERAND_PCREL";
728 def lea64_32mem : Operand<i32> {
729 let PrintMethod = "printanymem";
730 let MIOperandInfo = (ops GR64, i8imm, GR64_NOSP, i32imm, SEGMENT_REG);
731 let ParserMatchClass = X86MemAsmOperand;
734 // Memory operands that use 64-bit pointers in both ILP32 and LP64.
735 def lea64mem : Operand<i64> {
736 let PrintMethod = "printanymem";
737 let MIOperandInfo = (ops GR64, i8imm, GR64_NOSP, i32imm, SEGMENT_REG);
738 let ParserMatchClass = X86MemAsmOperand;
742 //===----------------------------------------------------------------------===//
743 // X86 Complex Pattern Definitions.
746 // Define X86-specific addressing mode.
747 def addr : ComplexPattern<iPTR, 5, "selectAddr", [], [SDNPWantParent]>;
748 def lea32addr : ComplexPattern<i32, 5, "selectLEAAddr",
749 [add, sub, mul, X86mul_imm, shl, or, frameindex],
751 // In 64-bit mode 32-bit LEAs can use RIP-relative addressing.
752 def lea64_32addr : ComplexPattern<i32, 5, "selectLEA64_32Addr",
753 [add, sub, mul, X86mul_imm, shl, or,
754 frameindex, X86WrapperRIP],
757 def tls32addr : ComplexPattern<i32, 5, "selectTLSADDRAddr",
758 [tglobaltlsaddr], []>;
760 def tls32baseaddr : ComplexPattern<i32, 5, "selectTLSADDRAddr",
761 [tglobaltlsaddr], []>;
763 def lea64addr : ComplexPattern<i64, 5, "selectLEAAddr",
764 [add, sub, mul, X86mul_imm, shl, or, frameindex,
767 def tls64addr : ComplexPattern<i64, 5, "selectTLSADDRAddr",
768 [tglobaltlsaddr], []>;
770 def tls64baseaddr : ComplexPattern<i64, 5, "selectTLSADDRAddr",
771 [tglobaltlsaddr], []>;
773 def vectoraddr : ComplexPattern<iPTR, 5, "selectVectorAddr", [],[SDNPWantParent]>;
775 // A relocatable immediate is either an immediate operand or an operand that can
776 // be relocated by the linker to an immediate, such as a regular symbol in
778 def relocImm : ComplexPattern<iAny, 1, "selectRelocImm", [imm, X86Wrapper], [],
781 //===----------------------------------------------------------------------===//
782 // X86 Instruction Predicate Definitions.
783 def TruePredicate : Predicate<"true">;
785 def HasCMov : Predicate<"Subtarget->hasCMov()">;
786 def NoCMov : Predicate<"!Subtarget->hasCMov()">;
788 def HasMMX : Predicate<"Subtarget->hasMMX()">;
789 def Has3DNow : Predicate<"Subtarget->has3DNow()">;
790 def Has3DNowA : Predicate<"Subtarget->has3DNowA()">;
791 def HasSSE1 : Predicate<"Subtarget->hasSSE1()">;
792 def UseSSE1 : Predicate<"Subtarget->hasSSE1() && !Subtarget->hasAVX()">;
793 def HasSSE2 : Predicate<"Subtarget->hasSSE2()">;
794 def UseSSE2 : Predicate<"Subtarget->hasSSE2() && !Subtarget->hasAVX()">;
795 def HasSSE3 : Predicate<"Subtarget->hasSSE3()">;
796 def UseSSE3 : Predicate<"Subtarget->hasSSE3() && !Subtarget->hasAVX()">;
797 def HasSSSE3 : Predicate<"Subtarget->hasSSSE3()">;
798 def UseSSSE3 : Predicate<"Subtarget->hasSSSE3() && !Subtarget->hasAVX()">;
799 def HasSSE41 : Predicate<"Subtarget->hasSSE41()">;
800 def NoSSE41 : Predicate<"!Subtarget->hasSSE41()">;
801 def UseSSE41 : Predicate<"Subtarget->hasSSE41() && !Subtarget->hasAVX()">;
802 def HasSSE42 : Predicate<"Subtarget->hasSSE42()">;
803 def UseSSE42 : Predicate<"Subtarget->hasSSE42() && !Subtarget->hasAVX()">;
804 def HasSSE4A : Predicate<"Subtarget->hasSSE4A()">;
805 def HasAVX : Predicate<"Subtarget->hasAVX()">;
806 def HasAVX2 : Predicate<"Subtarget->hasAVX2()">;
807 def HasAVX1Only : Predicate<"Subtarget->hasAVX() && !Subtarget->hasAVX2()">;
808 def HasAVX512 : Predicate<"Subtarget->hasAVX512()">,
809 AssemblerPredicate<"FeatureAVX512", "AVX-512 ISA">;
810 def UseAVX : Predicate<"Subtarget->hasAVX() && !Subtarget->hasAVX512()">;
811 def UseAVX2 : Predicate<"Subtarget->hasAVX2() && !Subtarget->hasAVX512()">;
812 def NoAVX512 : Predicate<"!Subtarget->hasAVX512()">;
813 def HasCDI : Predicate<"Subtarget->hasCDI()">,
814 AssemblerPredicate<"FeatureCDI", "AVX-512 CD ISA">;
815 def HasPFI : Predicate<"Subtarget->hasPFI()">,
816 AssemblerPredicate<"FeaturePFI", "AVX-512 PF ISA">;
817 def HasERI : Predicate<"Subtarget->hasERI()">,
818 AssemblerPredicate<"FeatureERI", "AVX-512 ER ISA">;
819 def HasDQI : Predicate<"Subtarget->hasDQI()">,
820 AssemblerPredicate<"FeatureDQI", "AVX-512 DQ ISA">;
821 def NoDQI : Predicate<"!Subtarget->hasDQI()">;
822 def HasBWI : Predicate<"Subtarget->hasBWI()">,
823 AssemblerPredicate<"FeatureBWI", "AVX-512 BW ISA">;
824 def NoBWI : Predicate<"!Subtarget->hasBWI()">;
825 def HasVLX : Predicate<"Subtarget->hasVLX()">,
826 AssemblerPredicate<"FeatureVLX", "AVX-512 VL ISA">;
827 def NoVLX : Predicate<"!Subtarget->hasVLX()">;
828 def NoVLX_Or_NoBWI : Predicate<"!Subtarget->hasVLX() || !Subtarget->hasBWI()">;
829 def NoVLX_Or_NoDQI : Predicate<"!Subtarget->hasVLX() || !Subtarget->hasDQI()">;
830 def PKU : Predicate<"Subtarget->hasPKU()">;
832 def HasPOPCNT : Predicate<"Subtarget->hasPOPCNT()">;
833 def HasAES : Predicate<"Subtarget->hasAES()">;
834 def HasFXSR : Predicate<"Subtarget->hasFXSR()">;
835 def HasXSAVE : Predicate<"Subtarget->hasXSAVE()">;
836 def HasXSAVEOPT : Predicate<"Subtarget->hasXSAVEOPT()">;
837 def HasXSAVEC : Predicate<"Subtarget->hasXSAVEC()">;
838 def HasXSAVES : Predicate<"Subtarget->hasXSAVES()">;
839 def HasPCLMUL : Predicate<"Subtarget->hasPCLMUL()">;
840 def HasFMA : Predicate<"Subtarget->hasFMA()">;
841 def HasFMA4 : Predicate<"Subtarget->hasFMA4()">;
842 def HasXOP : Predicate<"Subtarget->hasXOP()">;
843 def HasTBM : Predicate<"Subtarget->hasTBM()">;
844 def HasLWP : Predicate<"Subtarget->hasLWP()">;
845 def HasMOVBE : Predicate<"Subtarget->hasMOVBE()">;
846 def HasRDRAND : Predicate<"Subtarget->hasRDRAND()">;
847 def HasF16C : Predicate<"Subtarget->hasF16C()">;
848 def NoF16C : Predicate<"!Subtarget->hasF16C()">;
849 def HasFSGSBase : Predicate<"Subtarget->hasFSGSBase()">;
850 def HasLZCNT : Predicate<"Subtarget->hasLZCNT()">;
851 def HasBMI : Predicate<"Subtarget->hasBMI()">;
852 def HasBMI2 : Predicate<"Subtarget->hasBMI2()">;
853 def HasVBMI : Predicate<"Subtarget->hasVBMI()">,
854 AssemblerPredicate<"FeatureVBMI", "AVX-512 VBMI ISA">;
855 def HasIFMA : Predicate<"Subtarget->hasIFMA()">,
856 AssemblerPredicate<"FeatureIFMA", "AVX-512 IFMA ISA">;
857 def HasRTM : Predicate<"Subtarget->hasRTM()">;
858 def HasADX : Predicate<"Subtarget->hasADX()">;
859 def HasSHA : Predicate<"Subtarget->hasSHA()">;
860 def HasPRFCHW : Predicate<"Subtarget->hasPRFCHW()">;
861 def HasRDSEED : Predicate<"Subtarget->hasRDSEED()">;
862 def HasPrefetchW : Predicate<"Subtarget->hasPRFCHW()">;
863 def HasLAHFSAHF : Predicate<"Subtarget->hasLAHFSAHF()">;
864 def HasMWAITX : Predicate<"Subtarget->hasMWAITX()">;
865 def HasCLZERO : Predicate<"Subtarget->hasCLZERO()">;
866 def FPStackf32 : Predicate<"!Subtarget->hasSSE1()">;
867 def FPStackf64 : Predicate<"!Subtarget->hasSSE2()">;
868 def HasMPX : Predicate<"Subtarget->hasMPX()">;
869 def HasCLFLUSHOPT : Predicate<"Subtarget->hasCLFLUSHOPT()">;
870 def HasCmpxchg16b: Predicate<"Subtarget->hasCmpxchg16b()">;
871 def Not64BitMode : Predicate<"!Subtarget->is64Bit()">,
872 AssemblerPredicate<"!Mode64Bit", "Not 64-bit mode">;
873 def In64BitMode : Predicate<"Subtarget->is64Bit()">,
874 AssemblerPredicate<"Mode64Bit", "64-bit mode">;
875 def IsLP64 : Predicate<"Subtarget->isTarget64BitLP64()">;
876 def NotLP64 : Predicate<"!Subtarget->isTarget64BitLP64()">;
877 def In16BitMode : Predicate<"Subtarget->is16Bit()">,
878 AssemblerPredicate<"Mode16Bit", "16-bit mode">;
879 def Not16BitMode : Predicate<"!Subtarget->is16Bit()">,
880 AssemblerPredicate<"!Mode16Bit", "Not 16-bit mode">;
881 def In32BitMode : Predicate<"Subtarget->is32Bit()">,
882 AssemblerPredicate<"Mode32Bit", "32-bit mode">;
883 def IsWin64 : Predicate<"Subtarget->isTargetWin64()">;
884 def NotWin64 : Predicate<"!Subtarget->isTargetWin64()">;
885 def NotWin64WithoutFP : Predicate<"!Subtarget->isTargetWin64() ||"
886 "Subtarget->getFrameLowering()->hasFP(*MF)"> {
887 let RecomputePerFunction = 1;
889 def IsPS4 : Predicate<"Subtarget->isTargetPS4()">;
890 def NotPS4 : Predicate<"!Subtarget->isTargetPS4()">;
891 def IsNaCl : Predicate<"Subtarget->isTargetNaCl()">;
892 def NotNaCl : Predicate<"!Subtarget->isTargetNaCl()">;
893 def SmallCode : Predicate<"TM.getCodeModel() == CodeModel::Small">;
894 def KernelCode : Predicate<"TM.getCodeModel() == CodeModel::Kernel">;
895 def NearData : Predicate<"TM.getCodeModel() == CodeModel::Small ||"
896 "TM.getCodeModel() == CodeModel::Kernel">;
897 def IsNotPIC : Predicate<"!TM.isPositionIndependent()">;
898 def OptForSize : Predicate<"Subtarget->getOptForSize()">;
899 def OptForMinSize : Predicate<"Subtarget->getOptForMinSize()">;
900 def OptForSpeed : Predicate<"!Subtarget->getOptForSize()">;
901 def FastBTMem : Predicate<"!Subtarget->isBTMemSlow()">;
902 def CallImmAddr : Predicate<"Subtarget->isLegalToCallImmediateAddr()">;
903 def FavorMemIndirectCall : Predicate<"!Subtarget->callRegIndirect()">;
904 def NotSlowIncDec : Predicate<"!Subtarget->slowIncDec()">;
905 def HasFastMem32 : Predicate<"!Subtarget->isUnalignedMem32Slow()">;
906 def HasFastLZCNT : Predicate<"Subtarget->hasFastLZCNT()">;
907 def HasFastSHLDRotate : Predicate<"Subtarget->hasFastSHLDRotate()">;
908 def HasERMSB : Predicate<"Subtarget->hasERMSB()">;
909 def HasMFence : Predicate<"Subtarget->hasMFence()">;
911 //===----------------------------------------------------------------------===//
912 // X86 Instruction Format Definitions.
915 include "X86InstrFormats.td"
917 //===----------------------------------------------------------------------===//
918 // Pattern fragments.
921 // X86 specific condition code. These correspond to CondCode in
922 // X86InstrInfo.h. They must be kept in synch.
923 def X86_COND_A : PatLeaf<(i8 0)>; // alt. COND_NBE
924 def X86_COND_AE : PatLeaf<(i8 1)>; // alt. COND_NC
925 def X86_COND_B : PatLeaf<(i8 2)>; // alt. COND_C
926 def X86_COND_BE : PatLeaf<(i8 3)>; // alt. COND_NA
927 def X86_COND_E : PatLeaf<(i8 4)>; // alt. COND_Z
928 def X86_COND_G : PatLeaf<(i8 5)>; // alt. COND_NLE
929 def X86_COND_GE : PatLeaf<(i8 6)>; // alt. COND_NL
930 def X86_COND_L : PatLeaf<(i8 7)>; // alt. COND_NGE
931 def X86_COND_LE : PatLeaf<(i8 8)>; // alt. COND_NG
932 def X86_COND_NE : PatLeaf<(i8 9)>; // alt. COND_NZ
933 def X86_COND_NO : PatLeaf<(i8 10)>;
934 def X86_COND_NP : PatLeaf<(i8 11)>; // alt. COND_PO
935 def X86_COND_NS : PatLeaf<(i8 12)>;
936 def X86_COND_O : PatLeaf<(i8 13)>;
937 def X86_COND_P : PatLeaf<(i8 14)>; // alt. COND_PE
938 def X86_COND_S : PatLeaf<(i8 15)>;
940 def i16immSExt8 : ImmLeaf<i16, [{ return isInt<8>(Imm); }]>;
941 def i32immSExt8 : ImmLeaf<i32, [{ return isInt<8>(Imm); }]>;
942 def i64immSExt8 : ImmLeaf<i64, [{ return isInt<8>(Imm); }]>;
943 def i64immSExt32 : ImmLeaf<i64, [{ return isInt<32>(Imm); }]>;
945 // FIXME: Ideally we would just replace the above i*immSExt* matchers with
946 // relocImm-based matchers, but then FastISel would be unable to use them.
947 def i64relocImmSExt8 : PatLeaf<(i64 relocImm), [{
948 return isSExtRelocImm<8>(N);
950 def i64relocImmSExt32 : PatLeaf<(i64 relocImm), [{
951 return isSExtRelocImm<32>(N);
954 // If we have multiple users of an immediate, it's much smaller to reuse
955 // the register, rather than encode the immediate in every instruction.
956 // This has the risk of increasing register pressure from stretched live
957 // ranges, however, the immediates should be trivial to rematerialize by
958 // the RA in the event of high register pressure.
959 // TODO : This is currently enabled for stores and binary ops. There are more
960 // cases for which this can be enabled, though this catches the bulk of the
962 // TODO2 : This should really also be enabled under O2, but there's currently
963 // an issue with RA where we don't pull the constants into their users
964 // when we rematerialize them. I'll follow-up on enabling O2 after we fix that
966 // TODO3 : This is currently limited to single basic blocks (DAG creation
967 // pulls block immediates to the top and merges them if necessary).
968 // Eventually, it would be nice to allow ConstantHoisting to merge constants
969 // globally for potentially added savings.
971 def imm8_su : PatLeaf<(i8 relocImm), [{
972 return !shouldAvoidImmediateInstFormsForSize(N);
974 def imm16_su : PatLeaf<(i16 relocImm), [{
975 return !shouldAvoidImmediateInstFormsForSize(N);
977 def imm32_su : PatLeaf<(i32 relocImm), [{
978 return !shouldAvoidImmediateInstFormsForSize(N);
980 def i64immSExt32_su : PatLeaf<(i64immSExt32), [{
981 return !shouldAvoidImmediateInstFormsForSize(N);
984 def i16immSExt8_su : PatLeaf<(i16immSExt8), [{
985 return !shouldAvoidImmediateInstFormsForSize(N);
987 def i32immSExt8_su : PatLeaf<(i32immSExt8), [{
988 return !shouldAvoidImmediateInstFormsForSize(N);
990 def i64immSExt8_su : PatLeaf<(i64immSExt8), [{
991 return !shouldAvoidImmediateInstFormsForSize(N);
994 def i64relocImmSExt8_su : PatLeaf<(i64relocImmSExt8), [{
995 return !shouldAvoidImmediateInstFormsForSize(N);
997 def i64relocImmSExt32_su : PatLeaf<(i64relocImmSExt32), [{
998 return !shouldAvoidImmediateInstFormsForSize(N);
1001 // i64immZExt32 predicate - True if the 64-bit immediate fits in a 32-bit
1003 def i64immZExt32 : ImmLeaf<i64, [{ return isUInt<32>(Imm); }]>;
1005 def i64immZExt32SExt8 : ImmLeaf<i64, [{
1006 return isUInt<32>(Imm) && isInt<8>(static_cast<int32_t>(Imm));
1009 // Helper fragments for loads.
1010 // It's always safe to treat a anyext i16 load as a i32 load if the i16 is
1011 // known to be 32-bit aligned or better. Ditto for i8 to i16.
1012 def loadi16 : PatFrag<(ops node:$ptr), (i16 (unindexedload node:$ptr)), [{
1013 LoadSDNode *LD = cast<LoadSDNode>(N);
1014 ISD::LoadExtType ExtType = LD->getExtensionType();
1015 if (ExtType == ISD::NON_EXTLOAD)
1017 if (ExtType == ISD::EXTLOAD)
1018 return LD->getAlignment() >= 2 && !LD->isVolatile();
1022 def loadi16_anyext : PatFrag<(ops node:$ptr), (i32 (unindexedload node:$ptr)),[{
1023 LoadSDNode *LD = cast<LoadSDNode>(N);
1024 ISD::LoadExtType ExtType = LD->getExtensionType();
1025 if (ExtType == ISD::EXTLOAD)
1026 return LD->getAlignment() >= 2 && !LD->isVolatile();
1030 def loadi32 : PatFrag<(ops node:$ptr), (i32 (unindexedload node:$ptr)), [{
1031 LoadSDNode *LD = cast<LoadSDNode>(N);
1032 ISD::LoadExtType ExtType = LD->getExtensionType();
1033 if (ExtType == ISD::NON_EXTLOAD)
1035 if (ExtType == ISD::EXTLOAD)
1036 return LD->getAlignment() >= 4 && !LD->isVolatile();
1040 def loadi8 : PatFrag<(ops node:$ptr), (i8 (load node:$ptr))>;
1041 def loadi64 : PatFrag<(ops node:$ptr), (i64 (load node:$ptr))>;
1042 def loadf32 : PatFrag<(ops node:$ptr), (f32 (load node:$ptr))>;
1043 def loadf64 : PatFrag<(ops node:$ptr), (f64 (load node:$ptr))>;
1044 def loadf80 : PatFrag<(ops node:$ptr), (f80 (load node:$ptr))>;
1045 def loadf128 : PatFrag<(ops node:$ptr), (f128 (load node:$ptr))>;
1047 def sextloadi16i8 : PatFrag<(ops node:$ptr), (i16 (sextloadi8 node:$ptr))>;
1048 def sextloadi32i8 : PatFrag<(ops node:$ptr), (i32 (sextloadi8 node:$ptr))>;
1049 def sextloadi32i16 : PatFrag<(ops node:$ptr), (i32 (sextloadi16 node:$ptr))>;
1050 def sextloadi64i8 : PatFrag<(ops node:$ptr), (i64 (sextloadi8 node:$ptr))>;
1051 def sextloadi64i16 : PatFrag<(ops node:$ptr), (i64 (sextloadi16 node:$ptr))>;
1052 def sextloadi64i32 : PatFrag<(ops node:$ptr), (i64 (sextloadi32 node:$ptr))>;
1054 def zextloadi8i1 : PatFrag<(ops node:$ptr), (i8 (zextloadi1 node:$ptr))>;
1055 def zextloadi16i1 : PatFrag<(ops node:$ptr), (i16 (zextloadi1 node:$ptr))>;
1056 def zextloadi32i1 : PatFrag<(ops node:$ptr), (i32 (zextloadi1 node:$ptr))>;
1057 def zextloadi16i8 : PatFrag<(ops node:$ptr), (i16 (zextloadi8 node:$ptr))>;
1058 def zextloadi32i8 : PatFrag<(ops node:$ptr), (i32 (zextloadi8 node:$ptr))>;
1059 def zextloadi32i16 : PatFrag<(ops node:$ptr), (i32 (zextloadi16 node:$ptr))>;
1060 def zextloadi64i1 : PatFrag<(ops node:$ptr), (i64 (zextloadi1 node:$ptr))>;
1061 def zextloadi64i8 : PatFrag<(ops node:$ptr), (i64 (zextloadi8 node:$ptr))>;
1062 def zextloadi64i16 : PatFrag<(ops node:$ptr), (i64 (zextloadi16 node:$ptr))>;
1063 def zextloadi64i32 : PatFrag<(ops node:$ptr), (i64 (zextloadi32 node:$ptr))>;
1065 def extloadi8i1 : PatFrag<(ops node:$ptr), (i8 (extloadi1 node:$ptr))>;
1066 def extloadi16i1 : PatFrag<(ops node:$ptr), (i16 (extloadi1 node:$ptr))>;
1067 def extloadi32i1 : PatFrag<(ops node:$ptr), (i32 (extloadi1 node:$ptr))>;
1068 def extloadi16i8 : PatFrag<(ops node:$ptr), (i16 (extloadi8 node:$ptr))>;
1069 def extloadi32i8 : PatFrag<(ops node:$ptr), (i32 (extloadi8 node:$ptr))>;
1070 def extloadi32i16 : PatFrag<(ops node:$ptr), (i32 (extloadi16 node:$ptr))>;
1071 def extloadi64i1 : PatFrag<(ops node:$ptr), (i64 (extloadi1 node:$ptr))>;
1072 def extloadi64i8 : PatFrag<(ops node:$ptr), (i64 (extloadi8 node:$ptr))>;
1073 def extloadi64i16 : PatFrag<(ops node:$ptr), (i64 (extloadi16 node:$ptr))>;
1074 def extloadi64i32 : PatFrag<(ops node:$ptr), (i64 (extloadi32 node:$ptr))>;
1077 // An 'and' node with a single use.
1078 def and_su : PatFrag<(ops node:$lhs, node:$rhs), (and node:$lhs, node:$rhs), [{
1079 return N->hasOneUse();
1081 // An 'srl' node with a single use.
1082 def srl_su : PatFrag<(ops node:$lhs, node:$rhs), (srl node:$lhs, node:$rhs), [{
1083 return N->hasOneUse();
1085 // An 'trunc' node with a single use.
1086 def trunc_su : PatFrag<(ops node:$src), (trunc node:$src), [{
1087 return N->hasOneUse();
1090 //===----------------------------------------------------------------------===//
1091 // Instruction list.
1095 let hasSideEffects = 0, SchedRW = [WriteZero] in {
1096 def NOOP : I<0x90, RawFrm, (outs), (ins), "nop", [], IIC_NOP>;
1097 def NOOPW : I<0x1f, MRMXm, (outs), (ins i16mem:$zero),
1098 "nop{w}\t$zero", [], IIC_NOP>, TB, OpSize16;
1099 def NOOPL : I<0x1f, MRMXm, (outs), (ins i32mem:$zero),
1100 "nop{l}\t$zero", [], IIC_NOP>, TB, OpSize32;
1104 // Constructing a stack frame.
1105 def ENTER : Ii16<0xC8, RawFrmImm8, (outs), (ins i16imm:$len, i8imm:$lvl),
1106 "enter\t$len, $lvl", [], IIC_ENTER>, Sched<[WriteMicrocoded]>;
1108 let SchedRW = [WriteALU] in {
1109 let Defs = [EBP, ESP], Uses = [EBP, ESP], mayLoad = 1, hasSideEffects=0 in
1110 def LEAVE : I<0xC9, RawFrm,
1111 (outs), (ins), "leave", [], IIC_LEAVE>,
1112 Requires<[Not64BitMode]>;
1114 let Defs = [RBP,RSP], Uses = [RBP,RSP], mayLoad = 1, hasSideEffects = 0 in
1115 def LEAVE64 : I<0xC9, RawFrm,
1116 (outs), (ins), "leave", [], IIC_LEAVE>,
1117 Requires<[In64BitMode]>;
1120 //===----------------------------------------------------------------------===//
1121 // Miscellaneous Instructions.
1124 let isBarrier = 1, hasSideEffects = 1, usesCustomInserter = 1 in
1125 def Int_eh_sjlj_setup_dispatch
1126 : PseudoI<(outs), (ins), [(X86eh_sjlj_setup_dispatch)]>;
1128 let Defs = [ESP], Uses = [ESP], hasSideEffects=0 in {
1129 let mayLoad = 1, SchedRW = [WriteLoad] in {
1130 def POP16r : I<0x58, AddRegFrm, (outs GR16:$reg), (ins), "pop{w}\t$reg", [],
1131 IIC_POP_REG16>, OpSize16;
1132 def POP32r : I<0x58, AddRegFrm, (outs GR32:$reg), (ins), "pop{l}\t$reg", [],
1133 IIC_POP_REG>, OpSize32, Requires<[Not64BitMode]>;
1134 def POP16rmr: I<0x8F, MRM0r, (outs GR16:$reg), (ins), "pop{w}\t$reg", [],
1135 IIC_POP_REG>, OpSize16;
1136 def POP32rmr: I<0x8F, MRM0r, (outs GR32:$reg), (ins), "pop{l}\t$reg", [],
1137 IIC_POP_REG>, OpSize32, Requires<[Not64BitMode]>;
1138 } // mayLoad, SchedRW
1139 let mayStore = 1, mayLoad = 1, SchedRW = [WriteRMW] in {
1140 def POP16rmm: I<0x8F, MRM0m, (outs), (ins i16mem:$dst), "pop{w}\t$dst", [],
1141 IIC_POP_MEM>, OpSize16;
1142 def POP32rmm: I<0x8F, MRM0m, (outs), (ins i32mem:$dst), "pop{l}\t$dst", [],
1143 IIC_POP_MEM>, OpSize32, Requires<[Not64BitMode]>;
1144 } // mayStore, mayLoad, WriteRMW
1146 let mayStore = 1, SchedRW = [WriteStore] in {
1147 def PUSH16r : I<0x50, AddRegFrm, (outs), (ins GR16:$reg), "push{w}\t$reg",[],
1148 IIC_PUSH_REG>, OpSize16;
1149 def PUSH32r : I<0x50, AddRegFrm, (outs), (ins GR32:$reg), "push{l}\t$reg",[],
1150 IIC_PUSH_REG>, OpSize32, Requires<[Not64BitMode]>;
1151 def PUSH16rmr: I<0xFF, MRM6r, (outs), (ins GR16:$reg), "push{w}\t$reg",[],
1152 IIC_PUSH_REG>, OpSize16;
1153 def PUSH32rmr: I<0xFF, MRM6r, (outs), (ins GR32:$reg), "push{l}\t$reg",[],
1154 IIC_PUSH_REG>, OpSize32, Requires<[Not64BitMode]>;
1156 def PUSH16i8 : Ii8<0x6a, RawFrm, (outs), (ins i16i8imm:$imm),
1157 "push{w}\t$imm", [], IIC_PUSH_IMM>, OpSize16;
1158 def PUSHi16 : Ii16<0x68, RawFrm, (outs), (ins i16imm:$imm),
1159 "push{w}\t$imm", [], IIC_PUSH_IMM>, OpSize16;
1161 def PUSH32i8 : Ii8<0x6a, RawFrm, (outs), (ins i32i8imm:$imm),
1162 "push{l}\t$imm", [], IIC_PUSH_IMM>, OpSize32,
1163 Requires<[Not64BitMode]>;
1164 def PUSHi32 : Ii32<0x68, RawFrm, (outs), (ins i32imm:$imm),
1165 "push{l}\t$imm", [], IIC_PUSH_IMM>, OpSize32,
1166 Requires<[Not64BitMode]>;
1167 } // mayStore, SchedRW
1169 let mayLoad = 1, mayStore = 1, SchedRW = [WriteRMW] in {
1170 def PUSH16rmm: I<0xFF, MRM6m, (outs), (ins i16mem:$src), "push{w}\t$src",[],
1171 IIC_PUSH_MEM>, OpSize16;
1172 def PUSH32rmm: I<0xFF, MRM6m, (outs), (ins i32mem:$src), "push{l}\t$src",[],
1173 IIC_PUSH_MEM>, OpSize32, Requires<[Not64BitMode]>;
1174 } // mayLoad, mayStore, SchedRW
1178 let mayLoad = 1, mayStore = 1, usesCustomInserter = 1,
1179 SchedRW = [WriteRMW], Defs = [ESP] in {
1181 def RDFLAGS32 : PseudoI<(outs GR32:$dst), (ins),
1182 [(set GR32:$dst, (int_x86_flags_read_u32))]>,
1183 Requires<[Not64BitMode]>;
1186 def RDFLAGS64 : PseudoI<(outs GR64:$dst), (ins),
1187 [(set GR64:$dst, (int_x86_flags_read_u64))]>,
1188 Requires<[In64BitMode]>;
1191 let mayLoad = 1, mayStore = 1, usesCustomInserter = 1,
1192 SchedRW = [WriteRMW] in {
1193 let Defs = [ESP, EFLAGS], Uses = [ESP] in
1194 def WRFLAGS32 : PseudoI<(outs), (ins GR32:$src),
1195 [(int_x86_flags_write_u32 GR32:$src)]>,
1196 Requires<[Not64BitMode]>;
1198 let Defs = [RSP, EFLAGS], Uses = [RSP] in
1199 def WRFLAGS64 : PseudoI<(outs), (ins GR64:$src),
1200 [(int_x86_flags_write_u64 GR64:$src)]>,
1201 Requires<[In64BitMode]>;
1204 let Defs = [ESP, EFLAGS], Uses = [ESP], mayLoad = 1, hasSideEffects=0,
1205 SchedRW = [WriteLoad] in {
1206 def POPF16 : I<0x9D, RawFrm, (outs), (ins), "popf{w}", [], IIC_POP_F>,
1208 def POPF32 : I<0x9D, RawFrm, (outs), (ins), "popf{l|d}", [], IIC_POP_FD>,
1209 OpSize32, Requires<[Not64BitMode]>;
1212 let Defs = [ESP], Uses = [ESP, EFLAGS], mayStore = 1, hasSideEffects=0,
1213 SchedRW = [WriteStore] in {
1214 def PUSHF16 : I<0x9C, RawFrm, (outs), (ins), "pushf{w}", [], IIC_PUSH_F>,
1216 def PUSHF32 : I<0x9C, RawFrm, (outs), (ins), "pushf{l|d}", [], IIC_PUSH_F>,
1217 OpSize32, Requires<[Not64BitMode]>;
1220 let Defs = [RSP], Uses = [RSP], hasSideEffects=0 in {
1221 let mayLoad = 1, SchedRW = [WriteLoad] in {
1222 def POP64r : I<0x58, AddRegFrm, (outs GR64:$reg), (ins), "pop{q}\t$reg", [],
1223 IIC_POP_REG>, OpSize32, Requires<[In64BitMode]>;
1224 def POP64rmr: I<0x8F, MRM0r, (outs GR64:$reg), (ins), "pop{q}\t$reg", [],
1225 IIC_POP_REG>, OpSize32, Requires<[In64BitMode]>;
1226 } // mayLoad, SchedRW
1227 let mayLoad = 1, mayStore = 1, SchedRW = [WriteRMW] in
1228 def POP64rmm: I<0x8F, MRM0m, (outs), (ins i64mem:$dst), "pop{q}\t$dst", [],
1229 IIC_POP_MEM>, OpSize32, Requires<[In64BitMode]>;
1230 let mayStore = 1, SchedRW = [WriteStore] in {
1231 def PUSH64r : I<0x50, AddRegFrm, (outs), (ins GR64:$reg), "push{q}\t$reg", [],
1232 IIC_PUSH_REG>, OpSize32, Requires<[In64BitMode]>;
1233 def PUSH64rmr: I<0xFF, MRM6r, (outs), (ins GR64:$reg), "push{q}\t$reg", [],
1234 IIC_PUSH_REG>, OpSize32, Requires<[In64BitMode]>;
1235 } // mayStore, SchedRW
1236 let mayLoad = 1, mayStore = 1, SchedRW = [WriteRMW] in {
1237 def PUSH64rmm: I<0xFF, MRM6m, (outs), (ins i64mem:$src), "push{q}\t$src", [],
1238 IIC_PUSH_MEM>, OpSize32, Requires<[In64BitMode]>;
1239 } // mayLoad, mayStore, SchedRW
1242 let Defs = [RSP], Uses = [RSP], hasSideEffects = 0, mayStore = 1,
1243 SchedRW = [WriteStore] in {
1244 def PUSH64i8 : Ii8<0x6a, RawFrm, (outs), (ins i64i8imm:$imm),
1245 "push{q}\t$imm", [], IIC_PUSH_IMM>, OpSize32,
1246 Requires<[In64BitMode]>;
1247 def PUSH64i32 : Ii32S<0x68, RawFrm, (outs), (ins i64i32imm:$imm),
1248 "push{q}\t$imm", [], IIC_PUSH_IMM>, OpSize32,
1249 Requires<[In64BitMode]>;
1252 let Defs = [RSP, EFLAGS], Uses = [RSP], mayLoad = 1, hasSideEffects=0 in
1253 def POPF64 : I<0x9D, RawFrm, (outs), (ins), "popfq", [], IIC_POP_FD>,
1254 OpSize32, Requires<[In64BitMode]>, Sched<[WriteLoad]>;
1255 let Defs = [RSP], Uses = [RSP, EFLAGS], mayStore = 1, hasSideEffects=0 in
1256 def PUSHF64 : I<0x9C, RawFrm, (outs), (ins), "pushfq", [], IIC_PUSH_F>,
1257 OpSize32, Requires<[In64BitMode]>, Sched<[WriteStore]>;
1259 let Defs = [EDI, ESI, EBP, EBX, EDX, ECX, EAX, ESP], Uses = [ESP],
1260 mayLoad = 1, hasSideEffects = 0, SchedRW = [WriteLoad] in {
1261 def POPA32 : I<0x61, RawFrm, (outs), (ins), "popal", [], IIC_POP_A>,
1262 OpSize32, Requires<[Not64BitMode]>;
1263 def POPA16 : I<0x61, RawFrm, (outs), (ins), "popaw", [], IIC_POP_A>,
1264 OpSize16, Requires<[Not64BitMode]>;
1266 let Defs = [ESP], Uses = [EDI, ESI, EBP, EBX, EDX, ECX, EAX, ESP],
1267 mayStore = 1, hasSideEffects = 0, SchedRW = [WriteStore] in {
1268 def PUSHA32 : I<0x60, RawFrm, (outs), (ins), "pushal", [], IIC_PUSH_A>,
1269 OpSize32, Requires<[Not64BitMode]>;
1270 def PUSHA16 : I<0x60, RawFrm, (outs), (ins), "pushaw", [], IIC_PUSH_A>,
1271 OpSize16, Requires<[Not64BitMode]>;
1274 let Constraints = "$src = $dst", SchedRW = [WriteALU] in {
1275 // GR32 = bswap GR32
1276 def BSWAP32r : I<0xC8, AddRegFrm,
1277 (outs GR32:$dst), (ins GR32:$src),
1279 [(set GR32:$dst, (bswap GR32:$src))], IIC_BSWAP>, OpSize32, TB;
1281 def BSWAP64r : RI<0xC8, AddRegFrm, (outs GR64:$dst), (ins GR64:$src),
1283 [(set GR64:$dst, (bswap GR64:$src))], IIC_BSWAP>, TB;
1284 } // Constraints = "$src = $dst", SchedRW
1286 // Bit scan instructions.
1287 let Defs = [EFLAGS] in {
1288 def BSF16rr : I<0xBC, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
1289 "bsf{w}\t{$src, $dst|$dst, $src}",
1290 [(set GR16:$dst, EFLAGS, (X86bsf GR16:$src))],
1291 IIC_BIT_SCAN_REG>, PS, OpSize16, Sched<[WriteShift]>;
1292 def BSF16rm : I<0xBC, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
1293 "bsf{w}\t{$src, $dst|$dst, $src}",
1294 [(set GR16:$dst, EFLAGS, (X86bsf (loadi16 addr:$src)))],
1295 IIC_BIT_SCAN_MEM>, PS, OpSize16, Sched<[WriteShiftLd]>;
1296 def BSF32rr : I<0xBC, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
1297 "bsf{l}\t{$src, $dst|$dst, $src}",
1298 [(set GR32:$dst, EFLAGS, (X86bsf GR32:$src))],
1299 IIC_BIT_SCAN_REG>, PS, OpSize32, Sched<[WriteShift]>;
1300 def BSF32rm : I<0xBC, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
1301 "bsf{l}\t{$src, $dst|$dst, $src}",
1302 [(set GR32:$dst, EFLAGS, (X86bsf (loadi32 addr:$src)))],
1303 IIC_BIT_SCAN_MEM>, PS, OpSize32, Sched<[WriteShiftLd]>;
1304 def BSF64rr : RI<0xBC, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
1305 "bsf{q}\t{$src, $dst|$dst, $src}",
1306 [(set GR64:$dst, EFLAGS, (X86bsf GR64:$src))],
1307 IIC_BIT_SCAN_REG>, PS, Sched<[WriteShift]>;
1308 def BSF64rm : RI<0xBC, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
1309 "bsf{q}\t{$src, $dst|$dst, $src}",
1310 [(set GR64:$dst, EFLAGS, (X86bsf (loadi64 addr:$src)))],
1311 IIC_BIT_SCAN_MEM>, PS, Sched<[WriteShiftLd]>;
1313 def BSR16rr : I<0xBD, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
1314 "bsr{w}\t{$src, $dst|$dst, $src}",
1315 [(set GR16:$dst, EFLAGS, (X86bsr GR16:$src))],
1316 IIC_BIT_SCAN_REG>, PS, OpSize16, Sched<[WriteShift]>;
1317 def BSR16rm : I<0xBD, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
1318 "bsr{w}\t{$src, $dst|$dst, $src}",
1319 [(set GR16:$dst, EFLAGS, (X86bsr (loadi16 addr:$src)))],
1320 IIC_BIT_SCAN_MEM>, PS, OpSize16, Sched<[WriteShiftLd]>;
1321 def BSR32rr : I<0xBD, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
1322 "bsr{l}\t{$src, $dst|$dst, $src}",
1323 [(set GR32:$dst, EFLAGS, (X86bsr GR32:$src))],
1324 IIC_BIT_SCAN_REG>, PS, OpSize32, Sched<[WriteShift]>;
1325 def BSR32rm : I<0xBD, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
1326 "bsr{l}\t{$src, $dst|$dst, $src}",
1327 [(set GR32:$dst, EFLAGS, (X86bsr (loadi32 addr:$src)))],
1328 IIC_BIT_SCAN_MEM>, PS, OpSize32, Sched<[WriteShiftLd]>;
1329 def BSR64rr : RI<0xBD, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
1330 "bsr{q}\t{$src, $dst|$dst, $src}",
1331 [(set GR64:$dst, EFLAGS, (X86bsr GR64:$src))],
1332 IIC_BIT_SCAN_REG>, PS, Sched<[WriteShift]>;
1333 def BSR64rm : RI<0xBD, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
1334 "bsr{q}\t{$src, $dst|$dst, $src}",
1335 [(set GR64:$dst, EFLAGS, (X86bsr (loadi64 addr:$src)))],
1336 IIC_BIT_SCAN_MEM>, PS, Sched<[WriteShiftLd]>;
1337 } // Defs = [EFLAGS]
1339 let SchedRW = [WriteMicrocoded] in {
1340 // These uses the DF flag in the EFLAGS register to inc or dec EDI and ESI
1341 let Defs = [EDI,ESI], Uses = [EDI,ESI,EFLAGS] in {
1342 def MOVSB : I<0xA4, RawFrmDstSrc, (outs), (ins dstidx8:$dst, srcidx8:$src),
1343 "movsb\t{$src, $dst|$dst, $src}", [], IIC_MOVS>;
1344 def MOVSW : I<0xA5, RawFrmDstSrc, (outs), (ins dstidx16:$dst, srcidx16:$src),
1345 "movsw\t{$src, $dst|$dst, $src}", [], IIC_MOVS>, OpSize16;
1346 def MOVSL : I<0xA5, RawFrmDstSrc, (outs), (ins dstidx32:$dst, srcidx32:$src),
1347 "movs{l|d}\t{$src, $dst|$dst, $src}", [], IIC_MOVS>, OpSize32;
1348 def MOVSQ : RI<0xA5, RawFrmDstSrc, (outs), (ins dstidx64:$dst, srcidx64:$src),
1349 "movsq\t{$src, $dst|$dst, $src}", [], IIC_MOVS>;
1352 // These uses the DF flag in the EFLAGS register to inc or dec EDI and ESI
1353 let Defs = [EDI], Uses = [AL,EDI,EFLAGS] in
1354 def STOSB : I<0xAA, RawFrmDst, (outs), (ins dstidx8:$dst),
1355 "stosb\t{%al, $dst|$dst, al}", [], IIC_STOS>;
1356 let Defs = [EDI], Uses = [AX,EDI,EFLAGS] in
1357 def STOSW : I<0xAB, RawFrmDst, (outs), (ins dstidx16:$dst),
1358 "stosw\t{%ax, $dst|$dst, ax}", [], IIC_STOS>, OpSize16;
1359 let Defs = [EDI], Uses = [EAX,EDI,EFLAGS] in
1360 def STOSL : I<0xAB, RawFrmDst, (outs), (ins dstidx32:$dst),
1361 "stos{l|d}\t{%eax, $dst|$dst, eax}", [], IIC_STOS>, OpSize32;
1362 let Defs = [RDI], Uses = [RAX,RDI,EFLAGS] in
1363 def STOSQ : RI<0xAB, RawFrmDst, (outs), (ins dstidx64:$dst),
1364 "stosq\t{%rax, $dst|$dst, rax}", [], IIC_STOS>;
1366 // These uses the DF flag in the EFLAGS register to inc or dec EDI and ESI
1367 let Defs = [EDI,EFLAGS], Uses = [AL,EDI,EFLAGS] in
1368 def SCASB : I<0xAE, RawFrmDst, (outs), (ins dstidx8:$dst),
1369 "scasb\t{$dst, %al|al, $dst}", [], IIC_SCAS>;
1370 let Defs = [EDI,EFLAGS], Uses = [AX,EDI,EFLAGS] in
1371 def SCASW : I<0xAF, RawFrmDst, (outs), (ins dstidx16:$dst),
1372 "scasw\t{$dst, %ax|ax, $dst}", [], IIC_SCAS>, OpSize16;
1373 let Defs = [EDI,EFLAGS], Uses = [EAX,EDI,EFLAGS] in
1374 def SCASL : I<0xAF, RawFrmDst, (outs), (ins dstidx32:$dst),
1375 "scas{l|d}\t{$dst, %eax|eax, $dst}", [], IIC_SCAS>, OpSize32;
1376 let Defs = [EDI,EFLAGS], Uses = [RAX,EDI,EFLAGS] in
1377 def SCASQ : RI<0xAF, RawFrmDst, (outs), (ins dstidx64:$dst),
1378 "scasq\t{$dst, %rax|rax, $dst}", [], IIC_SCAS>;
1380 // These uses the DF flag in the EFLAGS register to inc or dec EDI and ESI
1381 let Defs = [EDI,ESI,EFLAGS], Uses = [EDI,ESI,EFLAGS] in {
1382 def CMPSB : I<0xA6, RawFrmDstSrc, (outs), (ins dstidx8:$dst, srcidx8:$src),
1383 "cmpsb\t{$dst, $src|$src, $dst}", [], IIC_CMPS>;
1384 def CMPSW : I<0xA7, RawFrmDstSrc, (outs), (ins dstidx16:$dst, srcidx16:$src),
1385 "cmpsw\t{$dst, $src|$src, $dst}", [], IIC_CMPS>, OpSize16;
1386 def CMPSL : I<0xA7, RawFrmDstSrc, (outs), (ins dstidx32:$dst, srcidx32:$src),
1387 "cmps{l|d}\t{$dst, $src|$src, $dst}", [], IIC_CMPS>, OpSize32;
1388 def CMPSQ : RI<0xA7, RawFrmDstSrc, (outs), (ins dstidx64:$dst, srcidx64:$src),
1389 "cmpsq\t{$dst, $src|$src, $dst}", [], IIC_CMPS>;
1393 //===----------------------------------------------------------------------===//
1394 // Move Instructions.
1396 let SchedRW = [WriteMove] in {
1397 let hasSideEffects = 0 in {
1398 def MOV8rr : I<0x88, MRMDestReg, (outs GR8 :$dst), (ins GR8 :$src),
1399 "mov{b}\t{$src, $dst|$dst, $src}", [], IIC_MOV>;
1400 def MOV16rr : I<0x89, MRMDestReg, (outs GR16:$dst), (ins GR16:$src),
1401 "mov{w}\t{$src, $dst|$dst, $src}", [], IIC_MOV>, OpSize16;
1402 def MOV32rr : I<0x89, MRMDestReg, (outs GR32:$dst), (ins GR32:$src),
1403 "mov{l}\t{$src, $dst|$dst, $src}", [], IIC_MOV>, OpSize32;
1404 def MOV64rr : RI<0x89, MRMDestReg, (outs GR64:$dst), (ins GR64:$src),
1405 "mov{q}\t{$src, $dst|$dst, $src}", [], IIC_MOV>;
1408 let isReMaterializable = 1, isAsCheapAsAMove = 1 in {
1409 def MOV8ri : Ii8 <0xB0, AddRegFrm, (outs GR8 :$dst), (ins i8imm :$src),
1410 "mov{b}\t{$src, $dst|$dst, $src}",
1411 [(set GR8:$dst, imm:$src)], IIC_MOV>;
1412 def MOV16ri : Ii16<0xB8, AddRegFrm, (outs GR16:$dst), (ins i16imm:$src),
1413 "mov{w}\t{$src, $dst|$dst, $src}",
1414 [(set GR16:$dst, imm:$src)], IIC_MOV>, OpSize16;
1415 def MOV32ri : Ii32<0xB8, AddRegFrm, (outs GR32:$dst), (ins i32imm:$src),
1416 "mov{l}\t{$src, $dst|$dst, $src}",
1417 [(set GR32:$dst, relocImm:$src)], IIC_MOV>, OpSize32;
1418 def MOV64ri32 : RIi32S<0xC7, MRM0r, (outs GR64:$dst), (ins i64i32imm:$src),
1419 "mov{q}\t{$src, $dst|$dst, $src}",
1420 [(set GR64:$dst, i64immSExt32:$src)], IIC_MOV>;
1422 let isReMaterializable = 1 in {
1423 def MOV64ri : RIi64<0xB8, AddRegFrm, (outs GR64:$dst), (ins i64imm:$src),
1424 "movabs{q}\t{$src, $dst|$dst, $src}",
1425 [(set GR64:$dst, relocImm:$src)], IIC_MOV>;
1428 // Longer forms that use a ModR/M byte. Needed for disassembler
1429 let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0 in {
1430 def MOV8ri_alt : Ii8 <0xC6, MRM0r, (outs GR8 :$dst), (ins i8imm :$src),
1431 "mov{b}\t{$src, $dst|$dst, $src}", [], IIC_MOV>;
1432 def MOV16ri_alt : Ii16<0xC7, MRM0r, (outs GR16:$dst), (ins i16imm:$src),
1433 "mov{w}\t{$src, $dst|$dst, $src}", [], IIC_MOV>, OpSize16;
1434 def MOV32ri_alt : Ii32<0xC7, MRM0r, (outs GR32:$dst), (ins i32imm:$src),
1435 "mov{l}\t{$src, $dst|$dst, $src}", [], IIC_MOV>, OpSize32;
1439 let SchedRW = [WriteStore] in {
1440 def MOV8mi : Ii8 <0xC6, MRM0m, (outs), (ins i8mem :$dst, i8imm :$src),
1441 "mov{b}\t{$src, $dst|$dst, $src}",
1442 [(store (i8 imm8_su:$src), addr:$dst)], IIC_MOV_MEM>;
1443 def MOV16mi : Ii16<0xC7, MRM0m, (outs), (ins i16mem:$dst, i16imm:$src),
1444 "mov{w}\t{$src, $dst|$dst, $src}",
1445 [(store (i16 imm16_su:$src), addr:$dst)], IIC_MOV_MEM>, OpSize16;
1446 def MOV32mi : Ii32<0xC7, MRM0m, (outs), (ins i32mem:$dst, i32imm:$src),
1447 "mov{l}\t{$src, $dst|$dst, $src}",
1448 [(store (i32 imm32_su:$src), addr:$dst)], IIC_MOV_MEM>, OpSize32;
1449 def MOV64mi32 : RIi32S<0xC7, MRM0m, (outs), (ins i64mem:$dst, i64i32imm:$src),
1450 "mov{q}\t{$src, $dst|$dst, $src}",
1451 [(store i64immSExt32_su:$src, addr:$dst)], IIC_MOV_MEM>;
1454 let hasSideEffects = 0 in {
1456 /// Memory offset versions of moves. The immediate is an address mode sized
1457 /// offset from the segment base.
1458 let SchedRW = [WriteALU] in {
1459 let mayLoad = 1 in {
1461 def MOV8ao32 : Ii32<0xA0, RawFrmMemOffs, (outs), (ins offset32_8:$src),
1462 "mov{b}\t{$src, %al|al, $src}", [], IIC_MOV_MEM>,
1465 def MOV16ao32 : Ii32<0xA1, RawFrmMemOffs, (outs), (ins offset32_16:$src),
1466 "mov{w}\t{$src, %ax|ax, $src}", [], IIC_MOV_MEM>,
1469 def MOV32ao32 : Ii32<0xA1, RawFrmMemOffs, (outs), (ins offset32_32:$src),
1470 "mov{l}\t{$src, %eax|eax, $src}", [], IIC_MOV_MEM>,
1473 def MOV64ao32 : RIi32<0xA1, RawFrmMemOffs, (outs), (ins offset32_64:$src),
1474 "mov{q}\t{$src, %rax|rax, $src}", [], IIC_MOV_MEM>,
1478 def MOV8ao16 : Ii16<0xA0, RawFrmMemOffs, (outs), (ins offset16_8:$src),
1479 "mov{b}\t{$src, %al|al, $src}", [], IIC_MOV_MEM>, AdSize16;
1481 def MOV16ao16 : Ii16<0xA1, RawFrmMemOffs, (outs), (ins offset16_16:$src),
1482 "mov{w}\t{$src, %ax|ax, $src}", [], IIC_MOV_MEM>,
1485 def MOV32ao16 : Ii16<0xA1, RawFrmMemOffs, (outs), (ins offset16_32:$src),
1486 "mov{l}\t{$src, %eax|eax, $src}", [], IIC_MOV_MEM>,
1489 let mayStore = 1 in {
1491 def MOV8o32a : Ii32<0xA2, RawFrmMemOffs, (outs), (ins offset32_8:$dst),
1492 "mov{b}\t{%al, $dst|$dst, al}", [], IIC_MOV_MEM>, AdSize32;
1494 def MOV16o32a : Ii32<0xA3, RawFrmMemOffs, (outs), (ins offset32_16:$dst),
1495 "mov{w}\t{%ax, $dst|$dst, ax}", [], IIC_MOV_MEM>,
1498 def MOV32o32a : Ii32<0xA3, RawFrmMemOffs, (outs), (ins offset32_32:$dst),
1499 "mov{l}\t{%eax, $dst|$dst, eax}", [], IIC_MOV_MEM>,
1502 def MOV64o32a : RIi32<0xA3, RawFrmMemOffs, (outs), (ins offset32_64:$dst),
1503 "mov{q}\t{%rax, $dst|$dst, rax}", [], IIC_MOV_MEM>,
1507 def MOV8o16a : Ii16<0xA2, RawFrmMemOffs, (outs), (ins offset16_8:$dst),
1508 "mov{b}\t{%al, $dst|$dst, al}", [], IIC_MOV_MEM>, AdSize16;
1510 def MOV16o16a : Ii16<0xA3, RawFrmMemOffs, (outs), (ins offset16_16:$dst),
1511 "mov{w}\t{%ax, $dst|$dst, ax}", [], IIC_MOV_MEM>,
1514 def MOV32o16a : Ii16<0xA3, RawFrmMemOffs, (outs), (ins offset16_32:$dst),
1515 "mov{l}\t{%eax, $dst|$dst, eax}", [], IIC_MOV_MEM>,
1520 // These forms all have full 64-bit absolute addresses in their instructions
1521 // and use the movabs mnemonic to indicate this specific form.
1522 let mayLoad = 1 in {
1524 def MOV8ao64 : RIi64_NOREX<0xA0, RawFrmMemOffs, (outs), (ins offset64_8:$src),
1525 "movabs{b}\t{$src, %al|al, $src}", []>, AdSize64;
1527 def MOV16ao64 : RIi64_NOREX<0xA1, RawFrmMemOffs, (outs), (ins offset64_16:$src),
1528 "movabs{w}\t{$src, %ax|ax, $src}", []>, OpSize16, AdSize64;
1530 def MOV32ao64 : RIi64_NOREX<0xA1, RawFrmMemOffs, (outs), (ins offset64_32:$src),
1531 "movabs{l}\t{$src, %eax|eax, $src}", []>, OpSize32,
1534 def MOV64ao64 : RIi64<0xA1, RawFrmMemOffs, (outs), (ins offset64_64:$src),
1535 "movabs{q}\t{$src, %rax|rax, $src}", []>, AdSize64;
1538 let mayStore = 1 in {
1540 def MOV8o64a : RIi64_NOREX<0xA2, RawFrmMemOffs, (outs), (ins offset64_8:$dst),
1541 "movabs{b}\t{%al, $dst|$dst, al}", []>, AdSize64;
1543 def MOV16o64a : RIi64_NOREX<0xA3, RawFrmMemOffs, (outs), (ins offset64_16:$dst),
1544 "movabs{w}\t{%ax, $dst|$dst, ax}", []>, OpSize16, AdSize64;
1546 def MOV32o64a : RIi64_NOREX<0xA3, RawFrmMemOffs, (outs), (ins offset64_32:$dst),
1547 "movabs{l}\t{%eax, $dst|$dst, eax}", []>, OpSize32,
1550 def MOV64o64a : RIi64<0xA3, RawFrmMemOffs, (outs), (ins offset64_64:$dst),
1551 "movabs{q}\t{%rax, $dst|$dst, rax}", []>, AdSize64;
1553 } // hasSideEffects = 0
1555 let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0,
1556 SchedRW = [WriteMove] in {
1557 def MOV8rr_REV : I<0x8A, MRMSrcReg, (outs GR8:$dst), (ins GR8:$src),
1558 "mov{b}\t{$src, $dst|$dst, $src}", [], IIC_MOV>;
1559 def MOV16rr_REV : I<0x8B, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
1560 "mov{w}\t{$src, $dst|$dst, $src}", [], IIC_MOV>, OpSize16;
1561 def MOV32rr_REV : I<0x8B, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
1562 "mov{l}\t{$src, $dst|$dst, $src}", [], IIC_MOV>, OpSize32;
1563 def MOV64rr_REV : RI<0x8B, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
1564 "mov{q}\t{$src, $dst|$dst, $src}", [], IIC_MOV>;
1567 let canFoldAsLoad = 1, isReMaterializable = 1, SchedRW = [WriteLoad] in {
1568 def MOV8rm : I<0x8A, MRMSrcMem, (outs GR8 :$dst), (ins i8mem :$src),
1569 "mov{b}\t{$src, $dst|$dst, $src}",
1570 [(set GR8:$dst, (loadi8 addr:$src))], IIC_MOV_MEM>;
1571 def MOV16rm : I<0x8B, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
1572 "mov{w}\t{$src, $dst|$dst, $src}",
1573 [(set GR16:$dst, (loadi16 addr:$src))], IIC_MOV_MEM>, OpSize16;
1574 def MOV32rm : I<0x8B, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
1575 "mov{l}\t{$src, $dst|$dst, $src}",
1576 [(set GR32:$dst, (loadi32 addr:$src))], IIC_MOV_MEM>, OpSize32;
1577 def MOV64rm : RI<0x8B, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
1578 "mov{q}\t{$src, $dst|$dst, $src}",
1579 [(set GR64:$dst, (load addr:$src))], IIC_MOV_MEM>;
1582 let SchedRW = [WriteStore] in {
1583 def MOV8mr : I<0x88, MRMDestMem, (outs), (ins i8mem :$dst, GR8 :$src),
1584 "mov{b}\t{$src, $dst|$dst, $src}",
1585 [(store GR8:$src, addr:$dst)], IIC_MOV_MEM>;
1586 def MOV16mr : I<0x89, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src),
1587 "mov{w}\t{$src, $dst|$dst, $src}",
1588 [(store GR16:$src, addr:$dst)], IIC_MOV_MEM>, OpSize16;
1589 def MOV32mr : I<0x89, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
1590 "mov{l}\t{$src, $dst|$dst, $src}",
1591 [(store GR32:$src, addr:$dst)], IIC_MOV_MEM>, OpSize32;
1592 def MOV64mr : RI<0x89, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
1593 "mov{q}\t{$src, $dst|$dst, $src}",
1594 [(store GR64:$src, addr:$dst)], IIC_MOV_MEM>;
1597 // Versions of MOV8rr, MOV8mr, and MOV8rm that use i8mem_NOREX and GR8_NOREX so
1598 // that they can be used for copying and storing h registers, which can't be
1599 // encoded when a REX prefix is present.
1600 let isCodeGenOnly = 1 in {
1601 let hasSideEffects = 0 in
1602 def MOV8rr_NOREX : I<0x88, MRMDestReg,
1603 (outs GR8_NOREX:$dst), (ins GR8_NOREX:$src),
1604 "mov{b}\t{$src, $dst|$dst, $src} # NOREX", [], IIC_MOV>,
1606 let mayStore = 1, hasSideEffects = 0 in
1607 def MOV8mr_NOREX : I<0x88, MRMDestMem,
1608 (outs), (ins i8mem_NOREX:$dst, GR8_NOREX:$src),
1609 "mov{b}\t{$src, $dst|$dst, $src} # NOREX", [],
1610 IIC_MOV_MEM>, Sched<[WriteStore]>;
1611 let mayLoad = 1, hasSideEffects = 0,
1612 canFoldAsLoad = 1, isReMaterializable = 1 in
1613 def MOV8rm_NOREX : I<0x8A, MRMSrcMem,
1614 (outs GR8_NOREX:$dst), (ins i8mem_NOREX:$src),
1615 "mov{b}\t{$src, $dst|$dst, $src} # NOREX", [],
1616 IIC_MOV_MEM>, Sched<[WriteLoad]>;
1620 // Condition code ops, incl. set if equal/not equal/...
1621 let SchedRW = [WriteALU] in {
1622 let Defs = [EFLAGS], Uses = [AH] in
1623 def SAHF : I<0x9E, RawFrm, (outs), (ins), "sahf",
1624 [(set EFLAGS, (X86sahf AH))], IIC_AHF>,
1625 Requires<[HasLAHFSAHF]>;
1626 let Defs = [AH], Uses = [EFLAGS], hasSideEffects = 0 in
1627 def LAHF : I<0x9F, RawFrm, (outs), (ins), "lahf", [],
1628 IIC_AHF>, // AH = flags
1629 Requires<[HasLAHFSAHF]>;
1632 //===----------------------------------------------------------------------===//
1633 // Bit tests instructions: BT, BTS, BTR, BTC.
1635 let Defs = [EFLAGS] in {
1636 let SchedRW = [WriteALU] in {
1637 def BT16rr : I<0xA3, MRMDestReg, (outs), (ins GR16:$src1, GR16:$src2),
1638 "bt{w}\t{$src2, $src1|$src1, $src2}",
1639 [(set EFLAGS, (X86bt GR16:$src1, GR16:$src2))], IIC_BT_RR>,
1641 def BT32rr : I<0xA3, MRMDestReg, (outs), (ins GR32:$src1, GR32:$src2),
1642 "bt{l}\t{$src2, $src1|$src1, $src2}",
1643 [(set EFLAGS, (X86bt GR32:$src1, GR32:$src2))], IIC_BT_RR>,
1645 def BT64rr : RI<0xA3, MRMDestReg, (outs), (ins GR64:$src1, GR64:$src2),
1646 "bt{q}\t{$src2, $src1|$src1, $src2}",
1647 [(set EFLAGS, (X86bt GR64:$src1, GR64:$src2))], IIC_BT_RR>, TB;
1650 // Unlike with the register+register form, the memory+register form of the
1651 // bt instruction does not ignore the high bits of the index. From ISel's
1652 // perspective, this is pretty bizarre. Make these instructions disassembly
1655 let mayLoad = 1, hasSideEffects = 0, SchedRW = [WriteALULd] in {
1656 def BT16mr : I<0xA3, MRMDestMem, (outs), (ins i16mem:$src1, GR16:$src2),
1657 "bt{w}\t{$src2, $src1|$src1, $src2}",
1658 // [(X86bt (loadi16 addr:$src1), GR16:$src2),
1659 // (implicit EFLAGS)]
1661 >, OpSize16, TB, Requires<[FastBTMem]>;
1662 def BT32mr : I<0xA3, MRMDestMem, (outs), (ins i32mem:$src1, GR32:$src2),
1663 "bt{l}\t{$src2, $src1|$src1, $src2}",
1664 // [(X86bt (loadi32 addr:$src1), GR32:$src2),
1665 // (implicit EFLAGS)]
1667 >, OpSize32, TB, Requires<[FastBTMem]>;
1668 def BT64mr : RI<0xA3, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2),
1669 "bt{q}\t{$src2, $src1|$src1, $src2}",
1670 // [(X86bt (loadi64 addr:$src1), GR64:$src2),
1671 // (implicit EFLAGS)]
1676 let SchedRW = [WriteALU] in {
1677 def BT16ri8 : Ii8<0xBA, MRM4r, (outs), (ins GR16:$src1, i16i8imm:$src2),
1678 "bt{w}\t{$src2, $src1|$src1, $src2}",
1679 [(set EFLAGS, (X86bt GR16:$src1, i16immSExt8:$src2))],
1680 IIC_BT_RI>, OpSize16, TB;
1681 def BT32ri8 : Ii8<0xBA, MRM4r, (outs), (ins GR32:$src1, i32i8imm:$src2),
1682 "bt{l}\t{$src2, $src1|$src1, $src2}",
1683 [(set EFLAGS, (X86bt GR32:$src1, i32immSExt8:$src2))],
1684 IIC_BT_RI>, OpSize32, TB;
1685 def BT64ri8 : RIi8<0xBA, MRM4r, (outs), (ins GR64:$src1, i64i8imm:$src2),
1686 "bt{q}\t{$src2, $src1|$src1, $src2}",
1687 [(set EFLAGS, (X86bt GR64:$src1, i64immSExt8:$src2))],
1691 // Note that these instructions don't need FastBTMem because that
1692 // only applies when the other operand is in a register. When it's
1693 // an immediate, bt is still fast.
1694 let SchedRW = [WriteALU] in {
1695 def BT16mi8 : Ii8<0xBA, MRM4m, (outs), (ins i16mem:$src1, i16i8imm:$src2),
1696 "bt{w}\t{$src2, $src1|$src1, $src2}",
1697 [(set EFLAGS, (X86bt (loadi16 addr:$src1), i16immSExt8:$src2))
1698 ], IIC_BT_MI>, OpSize16, TB;
1699 def BT32mi8 : Ii8<0xBA, MRM4m, (outs), (ins i32mem:$src1, i32i8imm:$src2),
1700 "bt{l}\t{$src2, $src1|$src1, $src2}",
1701 [(set EFLAGS, (X86bt (loadi32 addr:$src1), i32immSExt8:$src2))
1702 ], IIC_BT_MI>, OpSize32, TB;
1703 def BT64mi8 : RIi8<0xBA, MRM4m, (outs), (ins i64mem:$src1, i64i8imm:$src2),
1704 "bt{q}\t{$src2, $src1|$src1, $src2}",
1705 [(set EFLAGS, (X86bt (loadi64 addr:$src1),
1706 i64immSExt8:$src2))], IIC_BT_MI>, TB;
1709 let hasSideEffects = 0 in {
1710 let SchedRW = [WriteALU] in {
1711 def BTC16rr : I<0xBB, MRMDestReg, (outs), (ins GR16:$src1, GR16:$src2),
1712 "btc{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>,
1714 def BTC32rr : I<0xBB, MRMDestReg, (outs), (ins GR32:$src1, GR32:$src2),
1715 "btc{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>,
1717 def BTC64rr : RI<0xBB, MRMDestReg, (outs), (ins GR64:$src1, GR64:$src2),
1718 "btc{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>, TB;
1721 let mayLoad = 1, mayStore = 1, SchedRW = [WriteALULd, WriteRMW] in {
1722 def BTC16mr : I<0xBB, MRMDestMem, (outs), (ins i16mem:$src1, GR16:$src2),
1723 "btc{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>,
1725 def BTC32mr : I<0xBB, MRMDestMem, (outs), (ins i32mem:$src1, GR32:$src2),
1726 "btc{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>,
1728 def BTC64mr : RI<0xBB, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2),
1729 "btc{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>, TB;
1732 let SchedRW = [WriteALU] in {
1733 def BTC16ri8 : Ii8<0xBA, MRM7r, (outs), (ins GR16:$src1, i16i8imm:$src2),
1734 "btc{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>,
1736 def BTC32ri8 : Ii8<0xBA, MRM7r, (outs), (ins GR32:$src1, i32i8imm:$src2),
1737 "btc{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>,
1739 def BTC64ri8 : RIi8<0xBA, MRM7r, (outs), (ins GR64:$src1, i64i8imm:$src2),
1740 "btc{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>, TB;
1743 let mayLoad = 1, mayStore = 1, SchedRW = [WriteALULd, WriteRMW] in {
1744 def BTC16mi8 : Ii8<0xBA, MRM7m, (outs), (ins i16mem:$src1, i16i8imm:$src2),
1745 "btc{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>,
1747 def BTC32mi8 : Ii8<0xBA, MRM7m, (outs), (ins i32mem:$src1, i32i8imm:$src2),
1748 "btc{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>,
1750 def BTC64mi8 : RIi8<0xBA, MRM7m, (outs), (ins i64mem:$src1, i64i8imm:$src2),
1751 "btc{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>, TB;
1754 let SchedRW = [WriteALU] in {
1755 def BTR16rr : I<0xB3, MRMDestReg, (outs), (ins GR16:$src1, GR16:$src2),
1756 "btr{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>,
1758 def BTR32rr : I<0xB3, MRMDestReg, (outs), (ins GR32:$src1, GR32:$src2),
1759 "btr{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>,
1761 def BTR64rr : RI<0xB3, MRMDestReg, (outs), (ins GR64:$src1, GR64:$src2),
1762 "btr{q}\t{$src2, $src1|$src1, $src2}", []>, TB;
1765 let mayLoad = 1, mayStore = 1, SchedRW = [WriteALULd, WriteRMW] in {
1766 def BTR16mr : I<0xB3, MRMDestMem, (outs), (ins i16mem:$src1, GR16:$src2),
1767 "btr{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>,
1769 def BTR32mr : I<0xB3, MRMDestMem, (outs), (ins i32mem:$src1, GR32:$src2),
1770 "btr{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>,
1772 def BTR64mr : RI<0xB3, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2),
1773 "btr{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>, TB;
1776 let SchedRW = [WriteALU] in {
1777 def BTR16ri8 : Ii8<0xBA, MRM6r, (outs), (ins GR16:$src1, i16i8imm:$src2),
1778 "btr{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>,
1780 def BTR32ri8 : Ii8<0xBA, MRM6r, (outs), (ins GR32:$src1, i32i8imm:$src2),
1781 "btr{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>,
1783 def BTR64ri8 : RIi8<0xBA, MRM6r, (outs), (ins GR64:$src1, i64i8imm:$src2),
1784 "btr{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>, TB;
1787 let mayLoad = 1, mayStore = 1, SchedRW = [WriteALULd, WriteRMW] in {
1788 def BTR16mi8 : Ii8<0xBA, MRM6m, (outs), (ins i16mem:$src1, i16i8imm:$src2),
1789 "btr{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>,
1791 def BTR32mi8 : Ii8<0xBA, MRM6m, (outs), (ins i32mem:$src1, i32i8imm:$src2),
1792 "btr{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>,
1794 def BTR64mi8 : RIi8<0xBA, MRM6m, (outs), (ins i64mem:$src1, i64i8imm:$src2),
1795 "btr{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>, TB;
1798 let SchedRW = [WriteALU] in {
1799 def BTS16rr : I<0xAB, MRMDestReg, (outs), (ins GR16:$src1, GR16:$src2),
1800 "bts{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>,
1802 def BTS32rr : I<0xAB, MRMDestReg, (outs), (ins GR32:$src1, GR32:$src2),
1803 "bts{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>,
1805 def BTS64rr : RI<0xAB, MRMDestReg, (outs), (ins GR64:$src1, GR64:$src2),
1806 "bts{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RR>, TB;
1809 let mayLoad = 1, mayStore = 1, SchedRW = [WriteALULd, WriteRMW] in {
1810 def BTS16mr : I<0xAB, MRMDestMem, (outs), (ins i16mem:$src1, GR16:$src2),
1811 "bts{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>,
1813 def BTS32mr : I<0xAB, MRMDestMem, (outs), (ins i32mem:$src1, GR32:$src2),
1814 "bts{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>,
1816 def BTS64mr : RI<0xAB, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2),
1817 "bts{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MR>, TB;
1820 let SchedRW = [WriteALU] in {
1821 def BTS16ri8 : Ii8<0xBA, MRM5r, (outs), (ins GR16:$src1, i16i8imm:$src2),
1822 "bts{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>,
1824 def BTS32ri8 : Ii8<0xBA, MRM5r, (outs), (ins GR32:$src1, i32i8imm:$src2),
1825 "bts{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>,
1827 def BTS64ri8 : RIi8<0xBA, MRM5r, (outs), (ins GR64:$src1, i64i8imm:$src2),
1828 "bts{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_RI>, TB;
1831 let mayLoad = 1, mayStore = 1, SchedRW = [WriteALULd, WriteRMW] in {
1832 def BTS16mi8 : Ii8<0xBA, MRM5m, (outs), (ins i16mem:$src1, i16i8imm:$src2),
1833 "bts{w}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>,
1835 def BTS32mi8 : Ii8<0xBA, MRM5m, (outs), (ins i32mem:$src1, i32i8imm:$src2),
1836 "bts{l}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>,
1838 def BTS64mi8 : RIi8<0xBA, MRM5m, (outs), (ins i64mem:$src1, i64i8imm:$src2),
1839 "bts{q}\t{$src2, $src1|$src1, $src2}", [], IIC_BTX_MI>, TB;
1841 } // hasSideEffects = 0
1842 } // Defs = [EFLAGS]
1845 //===----------------------------------------------------------------------===//
1849 // Atomic swap. These are just normal xchg instructions. But since a memory
1850 // operand is referenced, the atomicity is ensured.
1851 multiclass ATOMIC_SWAP<bits<8> opc8, bits<8> opc, string mnemonic, string frag,
1852 InstrItinClass itin> {
1853 let Constraints = "$val = $dst", SchedRW = [WriteALULd, WriteRMW] in {
1854 def NAME#8rm : I<opc8, MRMSrcMem, (outs GR8:$dst),
1855 (ins GR8:$val, i8mem:$ptr),
1856 !strconcat(mnemonic, "{b}\t{$val, $ptr|$ptr, $val}"),
1859 (!cast<PatFrag>(frag # "_8") addr:$ptr, GR8:$val))],
1861 def NAME#16rm : I<opc, MRMSrcMem, (outs GR16:$dst),
1862 (ins GR16:$val, i16mem:$ptr),
1863 !strconcat(mnemonic, "{w}\t{$val, $ptr|$ptr, $val}"),
1866 (!cast<PatFrag>(frag # "_16") addr:$ptr, GR16:$val))],
1868 def NAME#32rm : I<opc, MRMSrcMem, (outs GR32:$dst),
1869 (ins GR32:$val, i32mem:$ptr),
1870 !strconcat(mnemonic, "{l}\t{$val, $ptr|$ptr, $val}"),
1873 (!cast<PatFrag>(frag # "_32") addr:$ptr, GR32:$val))],
1875 def NAME#64rm : RI<opc, MRMSrcMem, (outs GR64:$dst),
1876 (ins GR64:$val, i64mem:$ptr),
1877 !strconcat(mnemonic, "{q}\t{$val, $ptr|$ptr, $val}"),
1880 (!cast<PatFrag>(frag # "_64") addr:$ptr, GR64:$val))],
1885 defm XCHG : ATOMIC_SWAP<0x86, 0x87, "xchg", "atomic_swap", IIC_XCHG_MEM>;
1887 // Swap between registers.
1888 let SchedRW = [WriteALU] in {
1889 let Constraints = "$val = $dst" in {
1890 def XCHG8rr : I<0x86, MRMSrcReg, (outs GR8:$dst), (ins GR8:$val, GR8:$src),
1891 "xchg{b}\t{$val, $src|$src, $val}", [], IIC_XCHG_REG>;
1892 def XCHG16rr : I<0x87, MRMSrcReg, (outs GR16:$dst), (ins GR16:$val, GR16:$src),
1893 "xchg{w}\t{$val, $src|$src, $val}", [], IIC_XCHG_REG>,
1895 def XCHG32rr : I<0x87, MRMSrcReg, (outs GR32:$dst), (ins GR32:$val, GR32:$src),
1896 "xchg{l}\t{$val, $src|$src, $val}", [], IIC_XCHG_REG>,
1898 def XCHG64rr : RI<0x87, MRMSrcReg, (outs GR64:$dst), (ins GR64:$val,GR64:$src),
1899 "xchg{q}\t{$val, $src|$src, $val}", [], IIC_XCHG_REG>;
1902 // Swap between EAX and other registers.
1903 let Uses = [AX], Defs = [AX] in
1904 def XCHG16ar : I<0x90, AddRegFrm, (outs), (ins GR16:$src),
1905 "xchg{w}\t{$src, %ax|ax, $src}", [], IIC_XCHG_REG>, OpSize16;
1906 let Uses = [EAX], Defs = [EAX] in
1907 def XCHG32ar : I<0x90, AddRegFrm, (outs), (ins GR32:$src),
1908 "xchg{l}\t{$src, %eax|eax, $src}", [], IIC_XCHG_REG>,
1909 OpSize32, Requires<[Not64BitMode]>;
1910 let Uses = [EAX], Defs = [EAX] in
1911 // Uses GR32_NOAX in 64-bit mode to prevent encoding using the 0x90 NOP encoding.
1912 // xchg %eax, %eax needs to clear upper 32-bits of RAX so is not a NOP.
1913 def XCHG32ar64 : I<0x90, AddRegFrm, (outs), (ins GR32_NOAX:$src),
1914 "xchg{l}\t{$src, %eax|eax, $src}", [], IIC_XCHG_REG>,
1915 OpSize32, Requires<[In64BitMode]>;
1916 let Uses = [RAX], Defs = [RAX] in
1917 def XCHG64ar : RI<0x90, AddRegFrm, (outs), (ins GR64:$src),
1918 "xchg{q}\t{$src, %rax|rax, $src}", [], IIC_XCHG_REG>;
1921 let SchedRW = [WriteALU] in {
1922 def XADD8rr : I<0xC0, MRMDestReg, (outs GR8:$dst), (ins GR8:$src),
1923 "xadd{b}\t{$src, $dst|$dst, $src}", [], IIC_XADD_REG>, TB;
1924 def XADD16rr : I<0xC1, MRMDestReg, (outs GR16:$dst), (ins GR16:$src),
1925 "xadd{w}\t{$src, $dst|$dst, $src}", [], IIC_XADD_REG>, TB,
1927 def XADD32rr : I<0xC1, MRMDestReg, (outs GR32:$dst), (ins GR32:$src),
1928 "xadd{l}\t{$src, $dst|$dst, $src}", [], IIC_XADD_REG>, TB,
1930 def XADD64rr : RI<0xC1, MRMDestReg, (outs GR64:$dst), (ins GR64:$src),
1931 "xadd{q}\t{$src, $dst|$dst, $src}", [], IIC_XADD_REG>, TB;
1934 let mayLoad = 1, mayStore = 1, SchedRW = [WriteALULd, WriteRMW] in {
1935 def XADD8rm : I<0xC0, MRMDestMem, (outs), (ins i8mem:$dst, GR8:$src),
1936 "xadd{b}\t{$src, $dst|$dst, $src}", [], IIC_XADD_MEM>, TB;
1937 def XADD16rm : I<0xC1, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src),
1938 "xadd{w}\t{$src, $dst|$dst, $src}", [], IIC_XADD_MEM>, TB,
1940 def XADD32rm : I<0xC1, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
1941 "xadd{l}\t{$src, $dst|$dst, $src}", [], IIC_XADD_MEM>, TB,
1943 def XADD64rm : RI<0xC1, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
1944 "xadd{q}\t{$src, $dst|$dst, $src}", [], IIC_XADD_MEM>, TB;
1948 let SchedRW = [WriteALU] in {
1949 def CMPXCHG8rr : I<0xB0, MRMDestReg, (outs GR8:$dst), (ins GR8:$src),
1950 "cmpxchg{b}\t{$src, $dst|$dst, $src}", [],
1951 IIC_CMPXCHG_REG8>, TB;
1952 def CMPXCHG16rr : I<0xB1, MRMDestReg, (outs GR16:$dst), (ins GR16:$src),
1953 "cmpxchg{w}\t{$src, $dst|$dst, $src}", [],
1954 IIC_CMPXCHG_REG>, TB, OpSize16;
1955 def CMPXCHG32rr : I<0xB1, MRMDestReg, (outs GR32:$dst), (ins GR32:$src),
1956 "cmpxchg{l}\t{$src, $dst|$dst, $src}", [],
1957 IIC_CMPXCHG_REG>, TB, OpSize32;
1958 def CMPXCHG64rr : RI<0xB1, MRMDestReg, (outs GR64:$dst), (ins GR64:$src),
1959 "cmpxchg{q}\t{$src, $dst|$dst, $src}", [],
1960 IIC_CMPXCHG_REG>, TB;
1963 let SchedRW = [WriteALULd, WriteRMW] in {
1964 let mayLoad = 1, mayStore = 1 in {
1965 def CMPXCHG8rm : I<0xB0, MRMDestMem, (outs), (ins i8mem:$dst, GR8:$src),
1966 "cmpxchg{b}\t{$src, $dst|$dst, $src}", [],
1967 IIC_CMPXCHG_MEM8>, TB;
1968 def CMPXCHG16rm : I<0xB1, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src),
1969 "cmpxchg{w}\t{$src, $dst|$dst, $src}", [],
1970 IIC_CMPXCHG_MEM>, TB, OpSize16;
1971 def CMPXCHG32rm : I<0xB1, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
1972 "cmpxchg{l}\t{$src, $dst|$dst, $src}", [],
1973 IIC_CMPXCHG_MEM>, TB, OpSize32;
1974 def CMPXCHG64rm : RI<0xB1, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
1975 "cmpxchg{q}\t{$src, $dst|$dst, $src}", [],
1976 IIC_CMPXCHG_MEM>, TB;
1979 let Defs = [EAX, EDX, EFLAGS], Uses = [EAX, EBX, ECX, EDX] in
1980 def CMPXCHG8B : I<0xC7, MRM1m, (outs), (ins i64mem:$dst),
1981 "cmpxchg8b\t$dst", [], IIC_CMPXCHG_8B>, TB;
1983 let Defs = [RAX, RDX, EFLAGS], Uses = [RAX, RBX, RCX, RDX] in
1984 def CMPXCHG16B : RI<0xC7, MRM1m, (outs), (ins i128mem:$dst),
1985 "cmpxchg16b\t$dst", [], IIC_CMPXCHG_16B>,
1986 TB, Requires<[HasCmpxchg16b]>;
1990 // Lock instruction prefix
1991 def LOCK_PREFIX : I<0xF0, RawFrm, (outs), (ins), "lock", []>;
1993 // Rex64 instruction prefix
1994 def REX64_PREFIX : I<0x48, RawFrm, (outs), (ins), "rex64", []>,
1995 Requires<[In64BitMode]>;
1997 // Data16 instruction prefix
1998 def DATA16_PREFIX : I<0x66, RawFrm, (outs), (ins), "data16", []>,
1999 Requires<[Not16BitMode]>;
2001 // Data instruction prefix
2002 def DATA32_PREFIX : I<0x66, RawFrm, (outs), (ins), "data32", []>,
2003 Requires<[In16BitMode]>;
2005 // Repeat string operation instruction prefixes
2006 // These uses the DF flag in the EFLAGS register to inc or dec ECX
2007 let Defs = [ECX], Uses = [ECX,EFLAGS] in {
2008 // Repeat (used with INS, OUTS, MOVS, LODS and STOS)
2009 def REP_PREFIX : I<0xF3, RawFrm, (outs), (ins), "rep", []>;
2010 // Repeat while not equal (used with CMPS and SCAS)
2011 def REPNE_PREFIX : I<0xF2, RawFrm, (outs), (ins), "repne", []>;
2015 // String manipulation instructions
2016 let SchedRW = [WriteMicrocoded] in {
2017 // These uses the DF flag in the EFLAGS register to inc or dec EDI and ESI
2018 let Defs = [AL,ESI], Uses = [ESI,EFLAGS] in
2019 def LODSB : I<0xAC, RawFrmSrc, (outs), (ins srcidx8:$src),
2020 "lodsb\t{$src, %al|al, $src}", [], IIC_LODS>;
2021 let Defs = [AX,ESI], Uses = [ESI,EFLAGS] in
2022 def LODSW : I<0xAD, RawFrmSrc, (outs), (ins srcidx16:$src),
2023 "lodsw\t{$src, %ax|ax, $src}", [], IIC_LODS>, OpSize16;
2024 let Defs = [EAX,ESI], Uses = [ESI,EFLAGS] in
2025 def LODSL : I<0xAD, RawFrmSrc, (outs), (ins srcidx32:$src),
2026 "lods{l|d}\t{$src, %eax|eax, $src}", [], IIC_LODS>, OpSize32;
2027 let Defs = [RAX,ESI], Uses = [ESI,EFLAGS] in
2028 def LODSQ : RI<0xAD, RawFrmSrc, (outs), (ins srcidx64:$src),
2029 "lodsq\t{$src, %rax|rax, $src}", [], IIC_LODS>;
2032 let SchedRW = [WriteSystem] in {
2033 // These uses the DF flag in the EFLAGS register to inc or dec EDI and ESI
2034 let Defs = [ESI], Uses = [DX,ESI,EFLAGS] in {
2035 def OUTSB : I<0x6E, RawFrmSrc, (outs), (ins srcidx8:$src),
2036 "outsb\t{$src, %dx|dx, $src}", [], IIC_OUTS>;
2037 def OUTSW : I<0x6F, RawFrmSrc, (outs), (ins srcidx16:$src),
2038 "outsw\t{$src, %dx|dx, $src}", [], IIC_OUTS>, OpSize16;
2039 def OUTSL : I<0x6F, RawFrmSrc, (outs), (ins srcidx32:$src),
2040 "outs{l|d}\t{$src, %dx|dx, $src}", [], IIC_OUTS>, OpSize32;
2043 // These uses the DF flag in the EFLAGS register to inc or dec EDI and ESI
2044 let Defs = [EDI], Uses = [DX,EDI,EFLAGS] in {
2045 def INSB : I<0x6C, RawFrmDst, (outs), (ins dstidx8:$dst),
2046 "insb\t{%dx, $dst|$dst, dx}", [], IIC_INS>;
2047 def INSW : I<0x6D, RawFrmDst, (outs), (ins dstidx16:$dst),
2048 "insw\t{%dx, $dst|$dst, dx}", [], IIC_INS>, OpSize16;
2049 def INSL : I<0x6D, RawFrmDst, (outs), (ins dstidx32:$dst),
2050 "ins{l|d}\t{%dx, $dst|$dst, dx}", [], IIC_INS>, OpSize32;
2054 // Flag instructions
2055 let SchedRW = [WriteALU] in {
2056 def CLC : I<0xF8, RawFrm, (outs), (ins), "clc", [], IIC_CLC>;
2057 def STC : I<0xF9, RawFrm, (outs), (ins), "stc", [], IIC_STC>;
2058 def CLI : I<0xFA, RawFrm, (outs), (ins), "cli", [], IIC_CLI>;
2059 def STI : I<0xFB, RawFrm, (outs), (ins), "sti", [], IIC_STI>;
2060 def CLD : I<0xFC, RawFrm, (outs), (ins), "cld", [], IIC_CLD>;
2061 def STD : I<0xFD, RawFrm, (outs), (ins), "std", [], IIC_STD>;
2062 def CMC : I<0xF5, RawFrm, (outs), (ins), "cmc", [], IIC_CMC>;
2064 def CLTS : I<0x06, RawFrm, (outs), (ins), "clts", [], IIC_CLTS>, TB;
2067 // Table lookup instructions
2068 let Uses = [AL,EBX], Defs = [AL], hasSideEffects = 0, mayLoad = 1 in
2069 def XLAT : I<0xD7, RawFrm, (outs), (ins), "xlatb", [], IIC_XLAT>,
2072 let SchedRW = [WriteMicrocoded] in {
2073 // ASCII Adjust After Addition
2074 let Uses = [AL,EFLAGS], Defs = [AX,EFLAGS], hasSideEffects = 0 in
2075 def AAA : I<0x37, RawFrm, (outs), (ins), "aaa", [], IIC_AAA>,
2076 Requires<[Not64BitMode]>;
2078 // ASCII Adjust AX Before Division
2079 let Uses = [AX], Defs = [AX,EFLAGS], hasSideEffects = 0 in
2080 def AAD8i8 : Ii8<0xD5, RawFrm, (outs), (ins i8imm:$src),
2081 "aad\t$src", [], IIC_AAD>, Requires<[Not64BitMode]>;
2083 // ASCII Adjust AX After Multiply
2084 let Uses = [AL], Defs = [AX,EFLAGS], hasSideEffects = 0 in
2085 def AAM8i8 : Ii8<0xD4, RawFrm, (outs), (ins i8imm:$src),
2086 "aam\t$src", [], IIC_AAM>, Requires<[Not64BitMode]>;
2088 // ASCII Adjust AL After Subtraction - sets
2089 let Uses = [AL,EFLAGS], Defs = [AX,EFLAGS], hasSideEffects = 0 in
2090 def AAS : I<0x3F, RawFrm, (outs), (ins), "aas", [], IIC_AAS>,
2091 Requires<[Not64BitMode]>;
2093 // Decimal Adjust AL after Addition
2094 let Uses = [AL,EFLAGS], Defs = [AL,EFLAGS], hasSideEffects = 0 in
2095 def DAA : I<0x27, RawFrm, (outs), (ins), "daa", [], IIC_DAA>,
2096 Requires<[Not64BitMode]>;
2098 // Decimal Adjust AL after Subtraction
2099 let Uses = [AL,EFLAGS], Defs = [AL,EFLAGS], hasSideEffects = 0 in
2100 def DAS : I<0x2F, RawFrm, (outs), (ins), "das", [], IIC_DAS>,
2101 Requires<[Not64BitMode]>;
2104 let SchedRW = [WriteSystem] in {
2105 // Check Array Index Against Bounds
2106 def BOUNDS16rm : I<0x62, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
2107 "bound\t{$src, $dst|$dst, $src}", [], IIC_BOUND>, OpSize16,
2108 Requires<[Not64BitMode]>;
2109 def BOUNDS32rm : I<0x62, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
2110 "bound\t{$src, $dst|$dst, $src}", [], IIC_BOUND>, OpSize32,
2111 Requires<[Not64BitMode]>;
2113 // Adjust RPL Field of Segment Selector
2114 def ARPL16rr : I<0x63, MRMDestReg, (outs GR16:$dst), (ins GR16:$src),
2115 "arpl\t{$src, $dst|$dst, $src}", [], IIC_ARPL_REG>,
2116 Requires<[Not64BitMode]>;
2118 def ARPL16mr : I<0x63, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src),
2119 "arpl\t{$src, $dst|$dst, $src}", [], IIC_ARPL_MEM>,
2120 Requires<[Not64BitMode]>;
2123 //===----------------------------------------------------------------------===//
2124 // MOVBE Instructions
2126 let Predicates = [HasMOVBE] in {
2127 let SchedRW = [WriteALULd] in {
2128 def MOVBE16rm : I<0xF0, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
2129 "movbe{w}\t{$src, $dst|$dst, $src}",
2130 [(set GR16:$dst, (bswap (loadi16 addr:$src)))], IIC_MOVBE>,
2132 def MOVBE32rm : I<0xF0, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
2133 "movbe{l}\t{$src, $dst|$dst, $src}",
2134 [(set GR32:$dst, (bswap (loadi32 addr:$src)))], IIC_MOVBE>,
2136 def MOVBE64rm : RI<0xF0, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
2137 "movbe{q}\t{$src, $dst|$dst, $src}",
2138 [(set GR64:$dst, (bswap (loadi64 addr:$src)))], IIC_MOVBE>,
2141 let SchedRW = [WriteStore] in {
2142 def MOVBE16mr : I<0xF1, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src),
2143 "movbe{w}\t{$src, $dst|$dst, $src}",
2144 [(store (bswap GR16:$src), addr:$dst)], IIC_MOVBE>,
2146 def MOVBE32mr : I<0xF1, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
2147 "movbe{l}\t{$src, $dst|$dst, $src}",
2148 [(store (bswap GR32:$src), addr:$dst)], IIC_MOVBE>,
2150 def MOVBE64mr : RI<0xF1, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
2151 "movbe{q}\t{$src, $dst|$dst, $src}",
2152 [(store (bswap GR64:$src), addr:$dst)], IIC_MOVBE>,
2157 //===----------------------------------------------------------------------===//
2158 // RDRAND Instruction
2160 let Predicates = [HasRDRAND], Defs = [EFLAGS] in {
2161 def RDRAND16r : I<0xC7, MRM6r, (outs GR16:$dst), (ins),
2163 [(set GR16:$dst, EFLAGS, (X86rdrand))]>, OpSize16, TB;
2164 def RDRAND32r : I<0xC7, MRM6r, (outs GR32:$dst), (ins),
2166 [(set GR32:$dst, EFLAGS, (X86rdrand))]>, OpSize32, TB;
2167 def RDRAND64r : RI<0xC7, MRM6r, (outs GR64:$dst), (ins),
2169 [(set GR64:$dst, EFLAGS, (X86rdrand))]>, TB;
2172 //===----------------------------------------------------------------------===//
2173 // RDSEED Instruction
2175 let Predicates = [HasRDSEED], Defs = [EFLAGS] in {
2176 def RDSEED16r : I<0xC7, MRM7r, (outs GR16:$dst), (ins),
2178 [(set GR16:$dst, EFLAGS, (X86rdseed))]>, OpSize16, TB;
2179 def RDSEED32r : I<0xC7, MRM7r, (outs GR32:$dst), (ins),
2181 [(set GR32:$dst, EFLAGS, (X86rdseed))]>, OpSize32, TB;
2182 def RDSEED64r : RI<0xC7, MRM7r, (outs GR64:$dst), (ins),
2184 [(set GR64:$dst, EFLAGS, (X86rdseed))]>, TB;
2187 //===----------------------------------------------------------------------===//
2188 // LZCNT Instruction
2190 let Predicates = [HasLZCNT], Defs = [EFLAGS] in {
2191 def LZCNT16rr : I<0xBD, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
2192 "lzcnt{w}\t{$src, $dst|$dst, $src}",
2193 [(set GR16:$dst, (ctlz GR16:$src)), (implicit EFLAGS)]>, XS,
2195 def LZCNT16rm : I<0xBD, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
2196 "lzcnt{w}\t{$src, $dst|$dst, $src}",
2197 [(set GR16:$dst, (ctlz (loadi16 addr:$src))),
2198 (implicit EFLAGS)]>, XS, OpSize16;
2200 def LZCNT32rr : I<0xBD, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
2201 "lzcnt{l}\t{$src, $dst|$dst, $src}",
2202 [(set GR32:$dst, (ctlz GR32:$src)), (implicit EFLAGS)]>, XS,
2204 def LZCNT32rm : I<0xBD, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
2205 "lzcnt{l}\t{$src, $dst|$dst, $src}",
2206 [(set GR32:$dst, (ctlz (loadi32 addr:$src))),
2207 (implicit EFLAGS)]>, XS, OpSize32;
2209 def LZCNT64rr : RI<0xBD, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
2210 "lzcnt{q}\t{$src, $dst|$dst, $src}",
2211 [(set GR64:$dst, (ctlz GR64:$src)), (implicit EFLAGS)]>,
2213 def LZCNT64rm : RI<0xBD, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
2214 "lzcnt{q}\t{$src, $dst|$dst, $src}",
2215 [(set GR64:$dst, (ctlz (loadi64 addr:$src))),
2216 (implicit EFLAGS)]>, XS;
2219 //===----------------------------------------------------------------------===//
2222 let Predicates = [HasBMI], Defs = [EFLAGS] in {
2223 def TZCNT16rr : I<0xBC, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
2224 "tzcnt{w}\t{$src, $dst|$dst, $src}",
2225 [(set GR16:$dst, (cttz GR16:$src)), (implicit EFLAGS)]>, XS,
2227 def TZCNT16rm : I<0xBC, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
2228 "tzcnt{w}\t{$src, $dst|$dst, $src}",
2229 [(set GR16:$dst, (cttz (loadi16 addr:$src))),
2230 (implicit EFLAGS)]>, XS, OpSize16;
2232 def TZCNT32rr : I<0xBC, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
2233 "tzcnt{l}\t{$src, $dst|$dst, $src}",
2234 [(set GR32:$dst, (cttz GR32:$src)), (implicit EFLAGS)]>, XS,
2236 def TZCNT32rm : I<0xBC, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
2237 "tzcnt{l}\t{$src, $dst|$dst, $src}",
2238 [(set GR32:$dst, (cttz (loadi32 addr:$src))),
2239 (implicit EFLAGS)]>, XS, OpSize32;
2241 def TZCNT64rr : RI<0xBC, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
2242 "tzcnt{q}\t{$src, $dst|$dst, $src}",
2243 [(set GR64:$dst, (cttz GR64:$src)), (implicit EFLAGS)]>,
2245 def TZCNT64rm : RI<0xBC, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
2246 "tzcnt{q}\t{$src, $dst|$dst, $src}",
2247 [(set GR64:$dst, (cttz (loadi64 addr:$src))),
2248 (implicit EFLAGS)]>, XS;
2251 multiclass bmi_bls<string mnemonic, Format RegMRM, Format MemMRM,
2252 RegisterClass RC, X86MemOperand x86memop> {
2253 let hasSideEffects = 0 in {
2254 def rr : I<0xF3, RegMRM, (outs RC:$dst), (ins RC:$src),
2255 !strconcat(mnemonic, "\t{$src, $dst|$dst, $src}"),
2258 def rm : I<0xF3, MemMRM, (outs RC:$dst), (ins x86memop:$src),
2259 !strconcat(mnemonic, "\t{$src, $dst|$dst, $src}"),
2264 let Predicates = [HasBMI], Defs = [EFLAGS] in {
2265 defm BLSR32 : bmi_bls<"blsr{l}", MRM1r, MRM1m, GR32, i32mem>;
2266 defm BLSR64 : bmi_bls<"blsr{q}", MRM1r, MRM1m, GR64, i64mem>, VEX_W;
2267 defm BLSMSK32 : bmi_bls<"blsmsk{l}", MRM2r, MRM2m, GR32, i32mem>;
2268 defm BLSMSK64 : bmi_bls<"blsmsk{q}", MRM2r, MRM2m, GR64, i64mem>, VEX_W;
2269 defm BLSI32 : bmi_bls<"blsi{l}", MRM3r, MRM3m, GR32, i32mem>;
2270 defm BLSI64 : bmi_bls<"blsi{q}", MRM3r, MRM3m, GR64, i64mem>, VEX_W;
2273 //===----------------------------------------------------------------------===//
2274 // Pattern fragments to auto generate BMI instructions.
2275 //===----------------------------------------------------------------------===//
2277 let Predicates = [HasBMI] in {
2278 // FIXME: patterns for the load versions are not implemented
2279 def : Pat<(and GR32:$src, (add GR32:$src, -1)),
2280 (BLSR32rr GR32:$src)>;
2281 def : Pat<(and GR64:$src, (add GR64:$src, -1)),
2282 (BLSR64rr GR64:$src)>;
2284 def : Pat<(xor GR32:$src, (add GR32:$src, -1)),
2285 (BLSMSK32rr GR32:$src)>;
2286 def : Pat<(xor GR64:$src, (add GR64:$src, -1)),
2287 (BLSMSK64rr GR64:$src)>;
2289 def : Pat<(and GR32:$src, (ineg GR32:$src)),
2290 (BLSI32rr GR32:$src)>;
2291 def : Pat<(and GR64:$src, (ineg GR64:$src)),
2292 (BLSI64rr GR64:$src)>;
2296 multiclass bmi_bextr_bzhi<bits<8> opc, string mnemonic, RegisterClass RC,
2297 X86MemOperand x86memop, Intrinsic Int,
2299 def rr : I<opc, MRMSrcReg4VOp3, (outs RC:$dst), (ins RC:$src1, RC:$src2),
2300 !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2301 [(set RC:$dst, (Int RC:$src1, RC:$src2)), (implicit EFLAGS)]>,
2303 def rm : I<opc, MRMSrcMem4VOp3, (outs RC:$dst), (ins x86memop:$src1, RC:$src2),
2304 !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2305 [(set RC:$dst, (Int (ld_frag addr:$src1), RC:$src2)),
2306 (implicit EFLAGS)]>, T8PS, VEX;
2309 let Predicates = [HasBMI], Defs = [EFLAGS] in {
2310 defm BEXTR32 : bmi_bextr_bzhi<0xF7, "bextr{l}", GR32, i32mem,
2311 int_x86_bmi_bextr_32, loadi32>;
2312 defm BEXTR64 : bmi_bextr_bzhi<0xF7, "bextr{q}", GR64, i64mem,
2313 int_x86_bmi_bextr_64, loadi64>, VEX_W;
2316 let Predicates = [HasBMI2], Defs = [EFLAGS] in {
2317 defm BZHI32 : bmi_bextr_bzhi<0xF5, "bzhi{l}", GR32, i32mem,
2318 int_x86_bmi_bzhi_32, loadi32>;
2319 defm BZHI64 : bmi_bextr_bzhi<0xF5, "bzhi{q}", GR64, i64mem,
2320 int_x86_bmi_bzhi_64, loadi64>, VEX_W;
2324 def CountTrailingOnes : SDNodeXForm<imm, [{
2325 // Count the trailing ones in the immediate.
2326 return getI8Imm(countTrailingOnes(N->getZExtValue()), SDLoc(N));
2329 def BZHIMask : ImmLeaf<i64, [{
2330 return isMask_64(Imm) && (countTrailingOnes<uint64_t>(Imm) > 32);
2333 let Predicates = [HasBMI2] in {
2334 def : Pat<(and GR64:$src, BZHIMask:$mask),
2335 (BZHI64rr GR64:$src,
2336 (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
2337 (MOV8ri (CountTrailingOnes imm:$mask)), sub_8bit))>;
2339 def : Pat<(and GR32:$src, (add (shl 1, GR8:$lz), -1)),
2340 (BZHI32rr GR32:$src,
2341 (INSERT_SUBREG (i32 (IMPLICIT_DEF)), GR8:$lz, sub_8bit))>;
2343 def : Pat<(and (loadi32 addr:$src), (add (shl 1, GR8:$lz), -1)),
2344 (BZHI32rm addr:$src,
2345 (INSERT_SUBREG (i32 (IMPLICIT_DEF)), GR8:$lz, sub_8bit))>;
2347 def : Pat<(and GR64:$src, (add (shl 1, GR8:$lz), -1)),
2348 (BZHI64rr GR64:$src,
2349 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR8:$lz, sub_8bit))>;
2351 def : Pat<(and (loadi64 addr:$src), (add (shl 1, GR8:$lz), -1)),
2352 (BZHI64rm addr:$src,
2353 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR8:$lz, sub_8bit))>;
2356 let Predicates = [HasBMI] in {
2357 def : Pat<(X86bextr GR32:$src1, GR32:$src2),
2358 (BEXTR32rr GR32:$src1, GR32:$src2)>;
2359 def : Pat<(X86bextr (loadi32 addr:$src1), GR32:$src2),
2360 (BEXTR32rm addr:$src1, GR32:$src2)>;
2361 def : Pat<(X86bextr GR64:$src1, GR64:$src2),
2362 (BEXTR64rr GR64:$src1, GR64:$src2)>;
2363 def : Pat<(X86bextr (loadi64 addr:$src1), GR64:$src2),
2364 (BEXTR64rm addr:$src1, GR64:$src2)>;
2367 multiclass bmi_pdep_pext<string mnemonic, RegisterClass RC,
2368 X86MemOperand x86memop, Intrinsic Int,
2370 def rr : I<0xF5, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
2371 !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2372 [(set RC:$dst, (Int RC:$src1, RC:$src2))]>,
2374 def rm : I<0xF5, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
2375 !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2376 [(set RC:$dst, (Int RC:$src1, (ld_frag addr:$src2)))]>, VEX_4V;
2379 let Predicates = [HasBMI2] in {
2380 defm PDEP32 : bmi_pdep_pext<"pdep{l}", GR32, i32mem,
2381 int_x86_bmi_pdep_32, loadi32>, T8XD;
2382 defm PDEP64 : bmi_pdep_pext<"pdep{q}", GR64, i64mem,
2383 int_x86_bmi_pdep_64, loadi64>, T8XD, VEX_W;
2384 defm PEXT32 : bmi_pdep_pext<"pext{l}", GR32, i32mem,
2385 int_x86_bmi_pext_32, loadi32>, T8XS;
2386 defm PEXT64 : bmi_pdep_pext<"pext{q}", GR64, i64mem,
2387 int_x86_bmi_pext_64, loadi64>, T8XS, VEX_W;
2390 //===----------------------------------------------------------------------===//
2393 let Predicates = [HasTBM], Defs = [EFLAGS] in {
2395 multiclass tbm_ternary_imm_intr<bits<8> opc, RegisterClass RC, string OpcodeStr,
2396 X86MemOperand x86memop, PatFrag ld_frag,
2397 Intrinsic Int, Operand immtype,
2398 SDPatternOperator immoperator> {
2399 def ri : Ii32<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, immtype:$cntl),
2400 !strconcat(OpcodeStr,
2401 "\t{$cntl, $src1, $dst|$dst, $src1, $cntl}"),
2402 [(set RC:$dst, (Int RC:$src1, immoperator:$cntl))]>,
2404 def mi : Ii32<opc, MRMSrcMem, (outs RC:$dst),
2405 (ins x86memop:$src1, immtype:$cntl),
2406 !strconcat(OpcodeStr,
2407 "\t{$cntl, $src1, $dst|$dst, $src1, $cntl}"),
2408 [(set RC:$dst, (Int (ld_frag addr:$src1), immoperator:$cntl))]>,
2412 defm BEXTRI32 : tbm_ternary_imm_intr<0x10, GR32, "bextr", i32mem, loadi32,
2413 int_x86_tbm_bextri_u32, i32imm, imm>;
2414 let ImmT = Imm32S in
2415 defm BEXTRI64 : tbm_ternary_imm_intr<0x10, GR64, "bextr", i64mem, loadi64,
2416 int_x86_tbm_bextri_u64, i64i32imm,
2417 i64immSExt32>, VEX_W;
2419 multiclass tbm_binary_rm<bits<8> opc, Format FormReg, Format FormMem,
2420 RegisterClass RC, string OpcodeStr,
2421 X86MemOperand x86memop, PatFrag ld_frag> {
2422 let hasSideEffects = 0 in {
2423 def rr : I<opc, FormReg, (outs RC:$dst), (ins RC:$src),
2424 !strconcat(OpcodeStr,"\t{$src, $dst|$dst, $src}"),
2427 def rm : I<opc, FormMem, (outs RC:$dst), (ins x86memop:$src),
2428 !strconcat(OpcodeStr,"\t{$src, $dst|$dst, $src}"),
2433 multiclass tbm_binary_intr<bits<8> opc, string OpcodeStr,
2434 Format FormReg, Format FormMem> {
2435 defm NAME#32 : tbm_binary_rm<opc, FormReg, FormMem, GR32, OpcodeStr, i32mem,
2437 defm NAME#64 : tbm_binary_rm<opc, FormReg, FormMem, GR64, OpcodeStr, i64mem,
2441 defm BLCFILL : tbm_binary_intr<0x01, "blcfill", MRM1r, MRM1m>;
2442 defm BLCI : tbm_binary_intr<0x02, "blci", MRM6r, MRM6m>;
2443 defm BLCIC : tbm_binary_intr<0x01, "blcic", MRM5r, MRM5m>;
2444 defm BLCMSK : tbm_binary_intr<0x02, "blcmsk", MRM1r, MRM1m>;
2445 defm BLCS : tbm_binary_intr<0x01, "blcs", MRM3r, MRM3m>;
2446 defm BLSFILL : tbm_binary_intr<0x01, "blsfill", MRM2r, MRM2m>;
2447 defm BLSIC : tbm_binary_intr<0x01, "blsic", MRM6r, MRM6m>;
2448 defm T1MSKC : tbm_binary_intr<0x01, "t1mskc", MRM7r, MRM7m>;
2449 defm TZMSK : tbm_binary_intr<0x01, "tzmsk", MRM4r, MRM4m>;
2452 //===----------------------------------------------------------------------===//
2453 // Lightweight Profiling Instructions
2455 let Predicates = [HasLWP] in {
2457 def LLWPCB : I<0x12, MRM0r, (outs), (ins GR32:$src), "llwpcb\t$src",
2458 [(int_x86_llwpcb GR32:$src)], IIC_LWP>,
2459 XOP, XOP9, Requires<[Not64BitMode]>;
2460 def SLWPCB : I<0x12, MRM1r, (outs GR32:$dst), (ins), "slwpcb\t$dst",
2461 [(set GR32:$dst, (int_x86_slwpcb))], IIC_LWP>,
2462 XOP, XOP9, Requires<[Not64BitMode]>;
2464 def LLWPCB64 : I<0x12, MRM0r, (outs), (ins GR64:$src), "llwpcb\t$src",
2465 [(int_x86_llwpcb GR64:$src)], IIC_LWP>,
2466 XOP, XOP9, VEX_W, Requires<[In64BitMode]>;
2467 def SLWPCB64 : I<0x12, MRM1r, (outs GR64:$dst), (ins), "slwpcb\t$dst",
2468 [(set GR64:$dst, (int_x86_slwpcb))], IIC_LWP>,
2469 XOP, XOP9, VEX_W, Requires<[In64BitMode]>;
2471 multiclass lwpins_intr<RegisterClass RC> {
2472 def rri : Ii32<0x12, MRM0r, (outs), (ins RC:$src0, GR32:$src1, i32imm:$cntl),
2473 "lwpins\t{$cntl, $src1, $src0|$src0, $src1, $cntl}",
2474 [(set EFLAGS, (X86lwpins RC:$src0, GR32:$src1, imm:$cntl))]>,
2477 def rmi : Ii32<0x12, MRM0m, (outs), (ins RC:$src0, i32mem:$src1, i32imm:$cntl),
2478 "lwpins\t{$cntl, $src1, $src0|$src0, $src1, $cntl}",
2479 [(set EFLAGS, (X86lwpins RC:$src0, (loadi32 addr:$src1), imm:$cntl))]>,
2483 let Defs = [EFLAGS] in {
2484 defm LWPINS32 : lwpins_intr<GR32>;
2485 defm LWPINS64 : lwpins_intr<GR64>, VEX_W;
2488 multiclass lwpval_intr<RegisterClass RC, Intrinsic Int> {
2489 def rri : Ii32<0x12, MRM1r, (outs), (ins RC:$src0, GR32:$src1, i32imm:$cntl),
2490 "lwpval\t{$cntl, $src1, $src0|$src0, $src1, $cntl}",
2491 [(Int RC:$src0, GR32:$src1, imm:$cntl)], IIC_LWP>,
2494 def rmi : Ii32<0x12, MRM1m, (outs), (ins RC:$src0, i32mem:$src1, i32imm:$cntl),
2495 "lwpval\t{$cntl, $src1, $src0|$src0, $src1, $cntl}",
2496 [(Int RC:$src0, (loadi32 addr:$src1), imm:$cntl)], IIC_LWP>,
2500 defm LWPVAL32 : lwpval_intr<GR32, int_x86_lwpval32>;
2501 defm LWPVAL64 : lwpval_intr<GR64, int_x86_lwpval64>, VEX_W;
2505 //===----------------------------------------------------------------------===//
2506 // MONITORX/MWAITX Instructions
2508 let SchedRW = [ WriteSystem ] in {
2509 let usesCustomInserter = 1 in {
2510 def MONITORX : PseudoI<(outs), (ins i32mem:$src1, GR32:$src2, GR32:$src3),
2511 [(int_x86_monitorx addr:$src1, GR32:$src2, GR32:$src3)]>,
2512 Requires<[ HasMWAITX ]>;
2515 let Uses = [ EAX, ECX, EDX ] in {
2516 def MONITORXrrr : I<0x01, MRM_FA, (outs), (ins), "monitorx", [], IIC_SSE_MONITORX>,
2517 TB, Requires<[ HasMWAITX ]>;
2520 let Uses = [ ECX, EAX, EBX ] in {
2521 def MWAITXrrr : I<0x01, MRM_FB, (outs), (ins), "mwaitx",
2522 [(int_x86_mwaitx ECX, EAX, EBX)], IIC_SSE_MWAITX>,
2523 TB, Requires<[ HasMWAITX ]>;
2527 def : InstAlias<"mwaitx\t{%eax, %ecx, %ebx|ebx, ecx, eax}", (MWAITXrrr)>,
2528 Requires<[ Not64BitMode ]>;
2529 def : InstAlias<"mwaitx\t{%rax, %rcx, %rbx|rbx, rcx, rax}", (MWAITXrrr)>,
2530 Requires<[ In64BitMode ]>;
2532 def : InstAlias<"monitorx\t{%eax, %ecx, %edx|edx, ecx, eax}", (MONITORXrrr)>,
2533 Requires<[ Not64BitMode ]>;
2534 def : InstAlias<"monitorx\t{%rax, %rcx, %rdx|rdx, rcx, rax}", (MONITORXrrr)>,
2535 Requires<[ In64BitMode ]>;
2537 //===----------------------------------------------------------------------===//
2538 // CLZERO Instruction
2540 let SchedRW = [WriteSystem] in {
2542 def CLZEROr : I<0x01, MRM_FC, (outs), (ins), "clzero", [], IIC_SSE_CLZERO>,
2543 TB, Requires<[HasCLZERO]>;
2545 let usesCustomInserter = 1 in {
2546 def CLZERO : PseudoI<(outs), (ins i32mem:$src1),
2547 [(int_x86_clzero addr:$src1)]>, Requires<[HasCLZERO]>;
2551 def : InstAlias<"clzero\t{%eax|eax}", (CLZEROr)>, Requires<[Not64BitMode]>;
2552 def : InstAlias<"clzero\t{%rax|rax}", (CLZEROr)>, Requires<[In64BitMode]>;
2554 //===----------------------------------------------------------------------===//
2555 // Pattern fragments to auto generate TBM instructions.
2556 //===----------------------------------------------------------------------===//
2558 let Predicates = [HasTBM] in {
2559 def : Pat<(X86bextr GR32:$src1, (i32 imm:$src2)),
2560 (BEXTRI32ri GR32:$src1, imm:$src2)>;
2561 def : Pat<(X86bextr (loadi32 addr:$src1), (i32 imm:$src2)),
2562 (BEXTRI32mi addr:$src1, imm:$src2)>;
2563 def : Pat<(X86bextr GR64:$src1, i64immSExt32:$src2),
2564 (BEXTRI64ri GR64:$src1, i64immSExt32:$src2)>;
2565 def : Pat<(X86bextr (loadi64 addr:$src1), i64immSExt32:$src2),
2566 (BEXTRI64mi addr:$src1, i64immSExt32:$src2)>;
2568 // FIXME: patterns for the load versions are not implemented
2569 def : Pat<(and GR32:$src, (add GR32:$src, 1)),
2570 (BLCFILL32rr GR32:$src)>;
2571 def : Pat<(and GR64:$src, (add GR64:$src, 1)),
2572 (BLCFILL64rr GR64:$src)>;
2574 def : Pat<(or GR32:$src, (not (add GR32:$src, 1))),
2575 (BLCI32rr GR32:$src)>;
2576 def : Pat<(or GR64:$src, (not (add GR64:$src, 1))),
2577 (BLCI64rr GR64:$src)>;
2579 // Extra patterns because opt can optimize the above patterns to this.
2580 def : Pat<(or GR32:$src, (sub -2, GR32:$src)),
2581 (BLCI32rr GR32:$src)>;
2582 def : Pat<(or GR64:$src, (sub -2, GR64:$src)),
2583 (BLCI64rr GR64:$src)>;
2585 def : Pat<(and (not GR32:$src), (add GR32:$src, 1)),
2586 (BLCIC32rr GR32:$src)>;
2587 def : Pat<(and (not GR64:$src), (add GR64:$src, 1)),
2588 (BLCIC64rr GR64:$src)>;
2590 def : Pat<(xor GR32:$src, (add GR32:$src, 1)),
2591 (BLCMSK32rr GR32:$src)>;
2592 def : Pat<(xor GR64:$src, (add GR64:$src, 1)),
2593 (BLCMSK64rr GR64:$src)>;
2595 def : Pat<(or GR32:$src, (add GR32:$src, 1)),
2596 (BLCS32rr GR32:$src)>;
2597 def : Pat<(or GR64:$src, (add GR64:$src, 1)),
2598 (BLCS64rr GR64:$src)>;
2600 def : Pat<(or GR32:$src, (add GR32:$src, -1)),
2601 (BLSFILL32rr GR32:$src)>;
2602 def : Pat<(or GR64:$src, (add GR64:$src, -1)),
2603 (BLSFILL64rr GR64:$src)>;
2605 def : Pat<(or (not GR32:$src), (add GR32:$src, -1)),
2606 (BLSIC32rr GR32:$src)>;
2607 def : Pat<(or (not GR64:$src), (add GR64:$src, -1)),
2608 (BLSIC64rr GR64:$src)>;
2610 def : Pat<(or (not GR32:$src), (add GR32:$src, 1)),
2611 (T1MSKC32rr GR32:$src)>;
2612 def : Pat<(or (not GR64:$src), (add GR64:$src, 1)),
2613 (T1MSKC64rr GR64:$src)>;
2615 def : Pat<(and (not GR32:$src), (add GR32:$src, -1)),
2616 (TZMSK32rr GR32:$src)>;
2617 def : Pat<(and (not GR64:$src), (add GR64:$src, -1)),
2618 (TZMSK64rr GR64:$src)>;
2621 //===----------------------------------------------------------------------===//
2622 // Memory Instructions
2625 let Predicates = [HasCLFLUSHOPT] in
2626 def CLFLUSHOPT : I<0xAE, MRM7m, (outs), (ins i8mem:$src),
2627 "clflushopt\t$src", [(int_x86_clflushopt addr:$src)]>, PD;
2628 def CLWB : I<0xAE, MRM6m, (outs), (ins i8mem:$src), "clwb\t$src", []>, PD;
2631 //===----------------------------------------------------------------------===//
2633 //===----------------------------------------------------------------------===//
2635 include "X86InstrArithmetic.td"
2636 include "X86InstrCMovSetCC.td"
2637 include "X86InstrExtension.td"
2638 include "X86InstrControl.td"
2639 include "X86InstrShiftRotate.td"
2641 // X87 Floating Point Stack.
2642 include "X86InstrFPStack.td"
2644 // SIMD support (SSE, MMX and AVX)
2645 include "X86InstrFragmentsSIMD.td"
2647 // FMA - Fused Multiply-Add support (requires FMA)
2648 include "X86InstrFMA.td"
2651 include "X86InstrXOP.td"
2653 // SSE, MMX and 3DNow! vector support.
2654 include "X86InstrSSE.td"
2655 include "X86InstrAVX512.td"
2656 include "X86InstrMMX.td"
2657 include "X86Instr3DNow.td"
2660 include "X86InstrMPX.td"
2662 include "X86InstrVMX.td"
2663 include "X86InstrSVM.td"
2665 include "X86InstrTSX.td"
2666 include "X86InstrSGX.td"
2668 // System instructions.
2669 include "X86InstrSystem.td"
2671 // Compiler Pseudo Instructions and Pat Patterns
2672 include "X86InstrCompiler.td"
2674 //===----------------------------------------------------------------------===//
2675 // Assembler Mnemonic Aliases
2676 //===----------------------------------------------------------------------===//
2678 def : MnemonicAlias<"call", "callw", "att">, Requires<[In16BitMode]>;
2679 def : MnemonicAlias<"call", "calll", "att">, Requires<[In32BitMode]>;
2680 def : MnemonicAlias<"call", "callq", "att">, Requires<[In64BitMode]>;
2682 def : MnemonicAlias<"cbw", "cbtw", "att">;
2683 def : MnemonicAlias<"cwde", "cwtl", "att">;
2684 def : MnemonicAlias<"cwd", "cwtd", "att">;
2685 def : MnemonicAlias<"cdq", "cltd", "att">;
2686 def : MnemonicAlias<"cdqe", "cltq", "att">;
2687 def : MnemonicAlias<"cqo", "cqto", "att">;
2689 // In 64-bit mode lret maps to lretl; it is not ambiguous with lretq.
2690 def : MnemonicAlias<"lret", "lretw", "att">, Requires<[In16BitMode]>;
2691 def : MnemonicAlias<"lret", "lretl", "att">, Requires<[Not16BitMode]>;
2693 def : MnemonicAlias<"leavel", "leave", "att">, Requires<[Not64BitMode]>;
2694 def : MnemonicAlias<"leaveq", "leave", "att">, Requires<[In64BitMode]>;
2696 def : MnemonicAlias<"loopz", "loope">;
2697 def : MnemonicAlias<"loopnz", "loopne">;
2699 def : MnemonicAlias<"pop", "popw", "att">, Requires<[In16BitMode]>;
2700 def : MnemonicAlias<"pop", "popl", "att">, Requires<[In32BitMode]>;
2701 def : MnemonicAlias<"pop", "popq", "att">, Requires<[In64BitMode]>;
2702 def : MnemonicAlias<"popf", "popfw", "att">, Requires<[In16BitMode]>;
2703 def : MnemonicAlias<"popf", "popfl", "att">, Requires<[In32BitMode]>;
2704 def : MnemonicAlias<"popf", "popfq", "att">, Requires<[In64BitMode]>;
2705 def : MnemonicAlias<"popfd", "popfl", "att">;
2707 // FIXME: This is wrong for "push reg". "push %bx" should turn into pushw in
2708 // all modes. However: "push (addr)" and "push $42" should default to
2709 // pushl/pushq depending on the current mode. Similar for "pop %bx"
2710 def : MnemonicAlias<"push", "pushw", "att">, Requires<[In16BitMode]>;
2711 def : MnemonicAlias<"push", "pushl", "att">, Requires<[In32BitMode]>;
2712 def : MnemonicAlias<"push", "pushq", "att">, Requires<[In64BitMode]>;
2713 def : MnemonicAlias<"pushf", "pushfw", "att">, Requires<[In16BitMode]>;
2714 def : MnemonicAlias<"pushf", "pushfl", "att">, Requires<[In32BitMode]>;
2715 def : MnemonicAlias<"pushf", "pushfq", "att">, Requires<[In64BitMode]>;
2716 def : MnemonicAlias<"pushfd", "pushfl", "att">;
2718 def : MnemonicAlias<"popad", "popal", "intel">, Requires<[Not64BitMode]>;
2719 def : MnemonicAlias<"pushad", "pushal", "intel">, Requires<[Not64BitMode]>;
2720 def : MnemonicAlias<"popa", "popaw", "intel">, Requires<[In16BitMode]>;
2721 def : MnemonicAlias<"pusha", "pushaw", "intel">, Requires<[In16BitMode]>;
2722 def : MnemonicAlias<"popa", "popal", "intel">, Requires<[In32BitMode]>;
2723 def : MnemonicAlias<"pusha", "pushal", "intel">, Requires<[In32BitMode]>;
2725 def : MnemonicAlias<"popa", "popaw", "att">, Requires<[In16BitMode]>;
2726 def : MnemonicAlias<"pusha", "pushaw", "att">, Requires<[In16BitMode]>;
2727 def : MnemonicAlias<"popa", "popal", "att">, Requires<[In32BitMode]>;
2728 def : MnemonicAlias<"pusha", "pushal", "att">, Requires<[In32BitMode]>;
2730 def : MnemonicAlias<"repe", "rep">;
2731 def : MnemonicAlias<"repz", "rep">;
2732 def : MnemonicAlias<"repnz", "repne">;
2734 def : MnemonicAlias<"ret", "retw", "att">, Requires<[In16BitMode]>;
2735 def : MnemonicAlias<"ret", "retl", "att">, Requires<[In32BitMode]>;
2736 def : MnemonicAlias<"ret", "retq", "att">, Requires<[In64BitMode]>;
2738 // Apply 'ret' behavior to 'retn'
2739 def : MnemonicAlias<"retn", "retw", "att">, Requires<[In16BitMode]>;
2740 def : MnemonicAlias<"retn", "retl", "att">, Requires<[In32BitMode]>;
2741 def : MnemonicAlias<"retn", "retq", "att">, Requires<[In64BitMode]>;
2742 def : MnemonicAlias<"retn", "ret", "intel">;
2744 def : MnemonicAlias<"sal", "shl", "intel">;
2745 def : MnemonicAlias<"salb", "shlb", "att">;
2746 def : MnemonicAlias<"salw", "shlw", "att">;
2747 def : MnemonicAlias<"sall", "shll", "att">;
2748 def : MnemonicAlias<"salq", "shlq", "att">;
2750 def : MnemonicAlias<"smovb", "movsb", "att">;
2751 def : MnemonicAlias<"smovw", "movsw", "att">;
2752 def : MnemonicAlias<"smovl", "movsl", "att">;
2753 def : MnemonicAlias<"smovq", "movsq", "att">;
2755 def : MnemonicAlias<"ud2a", "ud2", "att">;
2756 def : MnemonicAlias<"verrw", "verr", "att">;
2758 // System instruction aliases.
2759 def : MnemonicAlias<"iret", "iretw", "att">, Requires<[In16BitMode]>;
2760 def : MnemonicAlias<"iret", "iretl", "att">, Requires<[Not16BitMode]>;
2761 def : MnemonicAlias<"sysret", "sysretl", "att">;
2762 def : MnemonicAlias<"sysexit", "sysexitl", "att">;
2764 def : MnemonicAlias<"lgdt", "lgdtw", "att">, Requires<[In16BitMode]>;
2765 def : MnemonicAlias<"lgdt", "lgdtl", "att">, Requires<[In32BitMode]>;
2766 def : MnemonicAlias<"lgdt", "lgdtq", "att">, Requires<[In64BitMode]>;
2767 def : MnemonicAlias<"lidt", "lidtw", "att">, Requires<[In16BitMode]>;
2768 def : MnemonicAlias<"lidt", "lidtl", "att">, Requires<[In32BitMode]>;
2769 def : MnemonicAlias<"lidt", "lidtq", "att">, Requires<[In64BitMode]>;
2770 def : MnemonicAlias<"sgdt", "sgdtw", "att">, Requires<[In16BitMode]>;
2771 def : MnemonicAlias<"sgdt", "sgdtl", "att">, Requires<[In32BitMode]>;
2772 def : MnemonicAlias<"sgdt", "sgdtq", "att">, Requires<[In64BitMode]>;
2773 def : MnemonicAlias<"sidt", "sidtw", "att">, Requires<[In16BitMode]>;
2774 def : MnemonicAlias<"sidt", "sidtl", "att">, Requires<[In32BitMode]>;
2775 def : MnemonicAlias<"sidt", "sidtq", "att">, Requires<[In64BitMode]>;
2778 // Floating point stack aliases.
2779 def : MnemonicAlias<"fcmovz", "fcmove", "att">;
2780 def : MnemonicAlias<"fcmova", "fcmovnbe", "att">;
2781 def : MnemonicAlias<"fcmovnae", "fcmovb", "att">;
2782 def : MnemonicAlias<"fcmovna", "fcmovbe", "att">;
2783 def : MnemonicAlias<"fcmovae", "fcmovnb", "att">;
2784 def : MnemonicAlias<"fcomip", "fcompi">;
2785 def : MnemonicAlias<"fildq", "fildll", "att">;
2786 def : MnemonicAlias<"fistpq", "fistpll", "att">;
2787 def : MnemonicAlias<"fisttpq", "fisttpll", "att">;
2788 def : MnemonicAlias<"fldcww", "fldcw", "att">;
2789 def : MnemonicAlias<"fnstcww", "fnstcw", "att">;
2790 def : MnemonicAlias<"fnstsww", "fnstsw", "att">;
2791 def : MnemonicAlias<"fucomip", "fucompi">;
2792 def : MnemonicAlias<"fwait", "wait">;
2794 def : MnemonicAlias<"fxsaveq", "fxsave64", "att">;
2795 def : MnemonicAlias<"fxrstorq", "fxrstor64", "att">;
2796 def : MnemonicAlias<"xsaveq", "xsave64", "att">;
2797 def : MnemonicAlias<"xrstorq", "xrstor64", "att">;
2798 def : MnemonicAlias<"xsaveoptq", "xsaveopt64", "att">;
2799 def : MnemonicAlias<"xrstorsq", "xrstors64", "att">;
2800 def : MnemonicAlias<"xsavecq", "xsavec64", "att">;
2801 def : MnemonicAlias<"xsavesq", "xsaves64", "att">;
2803 class CondCodeAlias<string Prefix,string Suffix, string OldCond, string NewCond,
2805 : MnemonicAlias<!strconcat(Prefix, OldCond, Suffix),
2806 !strconcat(Prefix, NewCond, Suffix), VariantName>;
2808 /// IntegerCondCodeMnemonicAlias - This multiclass defines a bunch of
2809 /// MnemonicAlias's that canonicalize the condition code in a mnemonic, for
2810 /// example "setz" -> "sete".
2811 multiclass IntegerCondCodeMnemonicAlias<string Prefix, string Suffix,
2813 def C : CondCodeAlias<Prefix, Suffix, "c", "b", V>; // setc -> setb
2814 def Z : CondCodeAlias<Prefix, Suffix, "z" , "e", V>; // setz -> sete
2815 def NA : CondCodeAlias<Prefix, Suffix, "na", "be", V>; // setna -> setbe
2816 def NB : CondCodeAlias<Prefix, Suffix, "nb", "ae", V>; // setnb -> setae
2817 def NC : CondCodeAlias<Prefix, Suffix, "nc", "ae", V>; // setnc -> setae
2818 def NG : CondCodeAlias<Prefix, Suffix, "ng", "le", V>; // setng -> setle
2819 def NL : CondCodeAlias<Prefix, Suffix, "nl", "ge", V>; // setnl -> setge
2820 def NZ : CondCodeAlias<Prefix, Suffix, "nz", "ne", V>; // setnz -> setne
2821 def PE : CondCodeAlias<Prefix, Suffix, "pe", "p", V>; // setpe -> setp
2822 def PO : CondCodeAlias<Prefix, Suffix, "po", "np", V>; // setpo -> setnp
2824 def NAE : CondCodeAlias<Prefix, Suffix, "nae", "b", V>; // setnae -> setb
2825 def NBE : CondCodeAlias<Prefix, Suffix, "nbe", "a", V>; // setnbe -> seta
2826 def NGE : CondCodeAlias<Prefix, Suffix, "nge", "l", V>; // setnge -> setl
2827 def NLE : CondCodeAlias<Prefix, Suffix, "nle", "g", V>; // setnle -> setg
2830 // Aliases for set<CC>
2831 defm : IntegerCondCodeMnemonicAlias<"set", "">;
2832 // Aliases for j<CC>
2833 defm : IntegerCondCodeMnemonicAlias<"j", "">;
2834 // Aliases for cmov<CC>{w,l,q}
2835 defm : IntegerCondCodeMnemonicAlias<"cmov", "w", "att">;
2836 defm : IntegerCondCodeMnemonicAlias<"cmov", "l", "att">;
2837 defm : IntegerCondCodeMnemonicAlias<"cmov", "q", "att">;
2838 // No size suffix for intel-style asm.
2839 defm : IntegerCondCodeMnemonicAlias<"cmov", "", "intel">;
2842 //===----------------------------------------------------------------------===//
2843 // Assembler Instruction Aliases
2844 //===----------------------------------------------------------------------===//
2846 // aad/aam default to base 10 if no operand is specified.
2847 def : InstAlias<"aad", (AAD8i8 10)>, Requires<[Not64BitMode]>;
2848 def : InstAlias<"aam", (AAM8i8 10)>, Requires<[Not64BitMode]>;
2850 // Disambiguate the mem/imm form of bt-without-a-suffix as btl.
2851 // Likewise for btc/btr/bts.
2852 def : InstAlias<"bt\t{$imm, $mem|$mem, $imm}",
2853 (BT32mi8 i32mem:$mem, i32i8imm:$imm), 0>;
2854 def : InstAlias<"btc\t{$imm, $mem|$mem, $imm}",
2855 (BTC32mi8 i32mem:$mem, i32i8imm:$imm), 0>;
2856 def : InstAlias<"btr\t{$imm, $mem|$mem, $imm}",
2857 (BTR32mi8 i32mem:$mem, i32i8imm:$imm), 0>;
2858 def : InstAlias<"bts\t{$imm, $mem|$mem, $imm}",
2859 (BTS32mi8 i32mem:$mem, i32i8imm:$imm), 0>;
2862 def : InstAlias<"clrb\t$reg", (XOR8rr GR8 :$reg, GR8 :$reg), 0>;
2863 def : InstAlias<"clrw\t$reg", (XOR16rr GR16:$reg, GR16:$reg), 0>;
2864 def : InstAlias<"clrl\t$reg", (XOR32rr GR32:$reg, GR32:$reg), 0>;
2865 def : InstAlias<"clrq\t$reg", (XOR64rr GR64:$reg, GR64:$reg), 0>;
2867 // lods aliases. Accept the destination being omitted because it's implicit
2868 // in the mnemonic, or the mnemonic suffix being omitted because it's implicit
2869 // in the destination.
2870 def : InstAlias<"lodsb\t$src", (LODSB srcidx8:$src), 0>;
2871 def : InstAlias<"lodsw\t$src", (LODSW srcidx16:$src), 0>;
2872 def : InstAlias<"lods{l|d}\t$src", (LODSL srcidx32:$src), 0>;
2873 def : InstAlias<"lodsq\t$src", (LODSQ srcidx64:$src), 0>, Requires<[In64BitMode]>;
2874 def : InstAlias<"lods\t{$src, %al|al, $src}", (LODSB srcidx8:$src), 0>;
2875 def : InstAlias<"lods\t{$src, %ax|ax, $src}", (LODSW srcidx16:$src), 0>;
2876 def : InstAlias<"lods\t{$src, %eax|eax, $src}", (LODSL srcidx32:$src), 0>;
2877 def : InstAlias<"lods\t{$src, %rax|rax, $src}", (LODSQ srcidx64:$src), 0>, Requires<[In64BitMode]>;
2878 def : InstAlias<"lods\t$src", (LODSB srcidx8:$src), 0>;
2879 def : InstAlias<"lods\t$src", (LODSW srcidx16:$src), 0>;
2880 def : InstAlias<"lods\t$src", (LODSL srcidx32:$src), 0>;
2881 def : InstAlias<"lods\t$src", (LODSQ srcidx64:$src), 0>, Requires<[In64BitMode]>;
2884 // stos aliases. Accept the source being omitted because it's implicit in
2885 // the mnemonic, or the mnemonic suffix being omitted because it's implicit
2887 def : InstAlias<"stosb\t$dst", (STOSB dstidx8:$dst), 0>;
2888 def : InstAlias<"stosw\t$dst", (STOSW dstidx16:$dst), 0>;
2889 def : InstAlias<"stos{l|d}\t$dst", (STOSL dstidx32:$dst), 0>;
2890 def : InstAlias<"stosq\t$dst", (STOSQ dstidx64:$dst), 0>, Requires<[In64BitMode]>;
2891 def : InstAlias<"stos\t{%al, $dst|$dst, al}", (STOSB dstidx8:$dst), 0>;
2892 def : InstAlias<"stos\t{%ax, $dst|$dst, ax}", (STOSW dstidx16:$dst), 0>;
2893 def : InstAlias<"stos\t{%eax, $dst|$dst, eax}", (STOSL dstidx32:$dst), 0>;
2894 def : InstAlias<"stos\t{%rax, $dst|$dst, rax}", (STOSQ dstidx64:$dst), 0>, Requires<[In64BitMode]>;
2895 def : InstAlias<"stos\t$dst", (STOSB dstidx8:$dst), 0>;
2896 def : InstAlias<"stos\t$dst", (STOSW dstidx16:$dst), 0>;
2897 def : InstAlias<"stos\t$dst", (STOSL dstidx32:$dst), 0>;
2898 def : InstAlias<"stos\t$dst", (STOSQ dstidx64:$dst), 0>, Requires<[In64BitMode]>;
2901 // scas aliases. Accept the destination being omitted because it's implicit
2902 // in the mnemonic, or the mnemonic suffix being omitted because it's implicit
2903 // in the destination.
2904 def : InstAlias<"scasb\t$dst", (SCASB dstidx8:$dst), 0>;
2905 def : InstAlias<"scasw\t$dst", (SCASW dstidx16:$dst), 0>;
2906 def : InstAlias<"scas{l|d}\t$dst", (SCASL dstidx32:$dst), 0>;
2907 def : InstAlias<"scasq\t$dst", (SCASQ dstidx64:$dst), 0>, Requires<[In64BitMode]>;
2908 def : InstAlias<"scas\t{$dst, %al|al, $dst}", (SCASB dstidx8:$dst), 0>;
2909 def : InstAlias<"scas\t{$dst, %ax|ax, $dst}", (SCASW dstidx16:$dst), 0>;
2910 def : InstAlias<"scas\t{$dst, %eax|eax, $dst}", (SCASL dstidx32:$dst), 0>;
2911 def : InstAlias<"scas\t{$dst, %rax|rax, $dst}", (SCASQ dstidx64:$dst), 0>, Requires<[In64BitMode]>;
2912 def : InstAlias<"scas\t$dst", (SCASB dstidx8:$dst), 0>;
2913 def : InstAlias<"scas\t$dst", (SCASW dstidx16:$dst), 0>;
2914 def : InstAlias<"scas\t$dst", (SCASL dstidx32:$dst), 0>;
2915 def : InstAlias<"scas\t$dst", (SCASQ dstidx64:$dst), 0>, Requires<[In64BitMode]>;
2917 // cmps aliases. Mnemonic suffix being omitted because it's implicit
2918 // in the destination.
2919 def : InstAlias<"cmps\t{$dst, $src|$src, $dst}", (CMPSB dstidx8:$dst, srcidx8:$src), 0>;
2920 def : InstAlias<"cmps\t{$dst, $src|$src, $dst}", (CMPSW dstidx16:$dst, srcidx16:$src), 0>;
2921 def : InstAlias<"cmps\t{$dst, $src|$src, $dst}", (CMPSL dstidx32:$dst, srcidx32:$src), 0>;
2922 def : InstAlias<"cmps\t{$dst, $src|$src, $dst}", (CMPSQ dstidx64:$dst, srcidx64:$src), 0>, Requires<[In64BitMode]>;
2924 // movs aliases. Mnemonic suffix being omitted because it's implicit
2925 // in the destination.
2926 def : InstAlias<"movs\t{$src, $dst|$dst, $src}", (MOVSB dstidx8:$dst, srcidx8:$src), 0>;
2927 def : InstAlias<"movs\t{$src, $dst|$dst, $src}", (MOVSW dstidx16:$dst, srcidx16:$src), 0>;
2928 def : InstAlias<"movs\t{$src, $dst|$dst, $src}", (MOVSL dstidx32:$dst, srcidx32:$src), 0>;
2929 def : InstAlias<"movs\t{$src, $dst|$dst, $src}", (MOVSQ dstidx64:$dst, srcidx64:$src), 0>, Requires<[In64BitMode]>;
2931 // div and idiv aliases for explicit A register.
2932 def : InstAlias<"div{b}\t{$src, %al|al, $src}", (DIV8r GR8 :$src)>;
2933 def : InstAlias<"div{w}\t{$src, %ax|ax, $src}", (DIV16r GR16:$src)>;
2934 def : InstAlias<"div{l}\t{$src, %eax|eax, $src}", (DIV32r GR32:$src)>;
2935 def : InstAlias<"div{q}\t{$src, %rax|rax, $src}", (DIV64r GR64:$src)>;
2936 def : InstAlias<"div{b}\t{$src, %al|al, $src}", (DIV8m i8mem :$src)>;
2937 def : InstAlias<"div{w}\t{$src, %ax|ax, $src}", (DIV16m i16mem:$src)>;
2938 def : InstAlias<"div{l}\t{$src, %eax|eax, $src}", (DIV32m i32mem:$src)>;
2939 def : InstAlias<"div{q}\t{$src, %rax|rax, $src}", (DIV64m i64mem:$src)>;
2940 def : InstAlias<"idiv{b}\t{$src, %al|al, $src}", (IDIV8r GR8 :$src)>;
2941 def : InstAlias<"idiv{w}\t{$src, %ax|ax, $src}", (IDIV16r GR16:$src)>;
2942 def : InstAlias<"idiv{l}\t{$src, %eax|eax, $src}", (IDIV32r GR32:$src)>;
2943 def : InstAlias<"idiv{q}\t{$src, %rax|rax, $src}", (IDIV64r GR64:$src)>;
2944 def : InstAlias<"idiv{b}\t{$src, %al|al, $src}", (IDIV8m i8mem :$src)>;
2945 def : InstAlias<"idiv{w}\t{$src, %ax|ax, $src}", (IDIV16m i16mem:$src)>;
2946 def : InstAlias<"idiv{l}\t{$src, %eax|eax, $src}", (IDIV32m i32mem:$src)>;
2947 def : InstAlias<"idiv{q}\t{$src, %rax|rax, $src}", (IDIV64m i64mem:$src)>;
2951 // Various unary fpstack operations default to operating on on ST1.
2952 // For example, "fxch" -> "fxch %st(1)"
2953 def : InstAlias<"faddp", (ADD_FPrST0 ST1), 0>;
2954 def: InstAlias<"fadd", (ADD_FPrST0 ST1), 0>;
2955 def : InstAlias<"fsub{|r}p", (SUBR_FPrST0 ST1), 0>;
2956 def : InstAlias<"fsub{r|}p", (SUB_FPrST0 ST1), 0>;
2957 def : InstAlias<"fmul", (MUL_FPrST0 ST1), 0>;
2958 def : InstAlias<"fmulp", (MUL_FPrST0 ST1), 0>;
2959 def : InstAlias<"fdiv{|r}p", (DIVR_FPrST0 ST1), 0>;
2960 def : InstAlias<"fdiv{r|}p", (DIV_FPrST0 ST1), 0>;
2961 def : InstAlias<"fxch", (XCH_F ST1), 0>;
2962 def : InstAlias<"fcom", (COM_FST0r ST1), 0>;
2963 def : InstAlias<"fcomp", (COMP_FST0r ST1), 0>;
2964 def : InstAlias<"fcomi", (COM_FIr ST1), 0>;
2965 def : InstAlias<"fcompi", (COM_FIPr ST1), 0>;
2966 def : InstAlias<"fucom", (UCOM_Fr ST1), 0>;
2967 def : InstAlias<"fucomp", (UCOM_FPr ST1), 0>;
2968 def : InstAlias<"fucomi", (UCOM_FIr ST1), 0>;
2969 def : InstAlias<"fucompi", (UCOM_FIPr ST1), 0>;
2971 // Handle fmul/fadd/fsub/fdiv instructions with explicitly written st(0) op.
2972 // For example, "fadd %st(4), %st(0)" -> "fadd %st(4)". We also disambiguate
2973 // instructions like "fadd %st(0), %st(0)" as "fadd %st(0)" for consistency with
2975 multiclass FpUnaryAlias<string Mnemonic, Instruction Inst, bit EmitAlias = 1> {
2976 def : InstAlias<!strconcat(Mnemonic, "\t{$op, %st(0)|st(0), $op}"),
2977 (Inst RST:$op), EmitAlias>;
2978 def : InstAlias<!strconcat(Mnemonic, "\t{%st(0), %st(0)|st(0), st(0)}"),
2979 (Inst ST0), EmitAlias>;
2982 defm : FpUnaryAlias<"fadd", ADD_FST0r>;
2983 defm : FpUnaryAlias<"faddp", ADD_FPrST0, 0>;
2984 defm : FpUnaryAlias<"fsub", SUB_FST0r>;
2985 defm : FpUnaryAlias<"fsub{|r}p", SUBR_FPrST0>;
2986 defm : FpUnaryAlias<"fsubr", SUBR_FST0r>;
2987 defm : FpUnaryAlias<"fsub{r|}p", SUB_FPrST0>;
2988 defm : FpUnaryAlias<"fmul", MUL_FST0r>;
2989 defm : FpUnaryAlias<"fmulp", MUL_FPrST0>;
2990 defm : FpUnaryAlias<"fdiv", DIV_FST0r>;
2991 defm : FpUnaryAlias<"fdiv{|r}p", DIVR_FPrST0>;
2992 defm : FpUnaryAlias<"fdivr", DIVR_FST0r>;
2993 defm : FpUnaryAlias<"fdiv{r|}p", DIV_FPrST0>;
2994 defm : FpUnaryAlias<"fcomi", COM_FIr, 0>;
2995 defm : FpUnaryAlias<"fucomi", UCOM_FIr, 0>;
2996 defm : FpUnaryAlias<"fcompi", COM_FIPr>;
2997 defm : FpUnaryAlias<"fucompi", UCOM_FIPr>;
3000 // Handle "f{mulp,addp} st(0), $op" the same as "f{mulp,addp} $op", since they
3001 // commute. We also allow fdiv[r]p/fsubrp even though they don't commute,
3002 // solely because gas supports it.
3003 def : InstAlias<"faddp\t{%st(0), $op|$op, st(0)}", (ADD_FPrST0 RST:$op), 0>;
3004 def : InstAlias<"fmulp\t{%st(0), $op|$op, st(0)}", (MUL_FPrST0 RST:$op)>;
3005 def : InstAlias<"fsub{|r}p\t{%st(0), $op|$op, st(0)}", (SUBR_FPrST0 RST:$op)>;
3006 def : InstAlias<"fsub{r|}p\t{%st(0), $op|$op, st(0)}", (SUB_FPrST0 RST:$op)>;
3007 def : InstAlias<"fdiv{|r}p\t{%st(0), $op|$op, st(0)}", (DIVR_FPrST0 RST:$op)>;
3008 def : InstAlias<"fdiv{r|}p\t{%st(0), $op|$op, st(0)}", (DIV_FPrST0 RST:$op)>;
3010 // We accept "fnstsw %eax" even though it only writes %ax.
3011 def : InstAlias<"fnstsw\t{%eax|eax}", (FNSTSW16r)>;
3012 def : InstAlias<"fnstsw\t{%al|al}" , (FNSTSW16r)>;
3013 def : InstAlias<"fnstsw" , (FNSTSW16r)>;
3015 // lcall and ljmp aliases. This seems to be an odd mapping in 64-bit mode, but
3016 // this is compatible with what GAS does.
3017 def : InstAlias<"lcall\t$seg, $off", (FARCALL32i i32imm:$off, i16imm:$seg), 0>, Requires<[In32BitMode]>;
3018 def : InstAlias<"ljmp\t$seg, $off", (FARJMP32i i32imm:$off, i16imm:$seg), 0>, Requires<[In32BitMode]>;
3019 def : InstAlias<"lcall\t{*}$dst", (FARCALL32m opaque48mem:$dst), 0>, Requires<[Not16BitMode]>;
3020 def : InstAlias<"ljmp\t{*}$dst", (FARJMP32m opaque48mem:$dst), 0>, Requires<[Not16BitMode]>;
3021 def : InstAlias<"lcall\t$seg, $off", (FARCALL16i i16imm:$off, i16imm:$seg), 0>, Requires<[In16BitMode]>;
3022 def : InstAlias<"ljmp\t$seg, $off", (FARJMP16i i16imm:$off, i16imm:$seg), 0>, Requires<[In16BitMode]>;
3023 def : InstAlias<"lcall\t{*}$dst", (FARCALL16m opaque32mem:$dst), 0>, Requires<[In16BitMode]>;
3024 def : InstAlias<"ljmp\t{*}$dst", (FARJMP16m opaque32mem:$dst), 0>, Requires<[In16BitMode]>;
3026 def : InstAlias<"call\t{*}$dst", (CALL64m i64mem:$dst), 0>, Requires<[In64BitMode]>;
3027 def : InstAlias<"jmp\t{*}$dst", (JMP64m i64mem:$dst), 0>, Requires<[In64BitMode]>;
3028 def : InstAlias<"call\t{*}$dst", (CALL32m i32mem:$dst), 0>, Requires<[In32BitMode]>;
3029 def : InstAlias<"jmp\t{*}$dst", (JMP32m i32mem:$dst), 0>, Requires<[In32BitMode]>;
3030 def : InstAlias<"call\t{*}$dst", (CALL16m i16mem:$dst), 0>, Requires<[In16BitMode]>;
3031 def : InstAlias<"jmp\t{*}$dst", (JMP16m i16mem:$dst), 0>, Requires<[In16BitMode]>;
3034 // "imul <imm>, B" is an alias for "imul <imm>, B, B".
3035 def : InstAlias<"imul{w}\t{$imm, $r|$r, $imm}", (IMUL16rri GR16:$r, GR16:$r, i16imm:$imm), 0>;
3036 def : InstAlias<"imul{w}\t{$imm, $r|$r, $imm}", (IMUL16rri8 GR16:$r, GR16:$r, i16i8imm:$imm), 0>;
3037 def : InstAlias<"imul{l}\t{$imm, $r|$r, $imm}", (IMUL32rri GR32:$r, GR32:$r, i32imm:$imm), 0>;
3038 def : InstAlias<"imul{l}\t{$imm, $r|$r, $imm}", (IMUL32rri8 GR32:$r, GR32:$r, i32i8imm:$imm), 0>;
3039 def : InstAlias<"imul{q}\t{$imm, $r|$r, $imm}", (IMUL64rri32 GR64:$r, GR64:$r, i64i32imm:$imm), 0>;
3040 def : InstAlias<"imul{q}\t{$imm, $r|$r, $imm}", (IMUL64rri8 GR64:$r, GR64:$r, i64i8imm:$imm), 0>;
3042 // ins aliases. Accept the mnemonic suffix being omitted because it's implicit
3043 // in the destination.
3044 def : InstAlias<"ins\t{%dx, $dst|$dst, dx}", (INSB dstidx8:$dst), 0>;
3045 def : InstAlias<"ins\t{%dx, $dst|$dst, dx}", (INSW dstidx16:$dst), 0>;
3046 def : InstAlias<"ins\t{%dx, $dst|$dst, dx}", (INSL dstidx32:$dst), 0>;
3048 // outs aliases. Accept the mnemonic suffix being omitted because it's implicit
3050 def : InstAlias<"outs\t{$src, %dx|dx, $src}", (OUTSB srcidx8:$src), 0>;
3051 def : InstAlias<"outs\t{$src, %dx|dx, $src}", (OUTSW srcidx16:$src), 0>;
3052 def : InstAlias<"outs\t{$src, %dx|dx, $src}", (OUTSL srcidx32:$src), 0>;
3054 // inb %dx -> inb %al, %dx
3055 def : InstAlias<"inb\t{%dx|dx}", (IN8rr), 0>;
3056 def : InstAlias<"inw\t{%dx|dx}", (IN16rr), 0>;
3057 def : InstAlias<"inl\t{%dx|dx}", (IN32rr), 0>;
3058 def : InstAlias<"inb\t$port", (IN8ri u8imm:$port), 0>;
3059 def : InstAlias<"inw\t$port", (IN16ri u8imm:$port), 0>;
3060 def : InstAlias<"inl\t$port", (IN32ri u8imm:$port), 0>;
3063 // jmp and call aliases for lcall and ljmp. jmp $42,$5 -> ljmp
3064 def : InstAlias<"call\t$seg, $off", (FARCALL16i i16imm:$off, i16imm:$seg)>, Requires<[In16BitMode]>;
3065 def : InstAlias<"jmp\t$seg, $off", (FARJMP16i i16imm:$off, i16imm:$seg)>, Requires<[In16BitMode]>;
3066 def : InstAlias<"call\t$seg, $off", (FARCALL32i i32imm:$off, i16imm:$seg)>, Requires<[In32BitMode]>;
3067 def : InstAlias<"jmp\t$seg, $off", (FARJMP32i i32imm:$off, i16imm:$seg)>, Requires<[In32BitMode]>;
3068 def : InstAlias<"callw\t$seg, $off", (FARCALL16i i16imm:$off, i16imm:$seg)>, Requires<[Not64BitMode]>;
3069 def : InstAlias<"jmpw\t$seg, $off", (FARJMP16i i16imm:$off, i16imm:$seg)>, Requires<[Not64BitMode]>;
3070 def : InstAlias<"calll\t$seg, $off", (FARCALL32i i32imm:$off, i16imm:$seg)>, Requires<[Not64BitMode]>;
3071 def : InstAlias<"jmpl\t$seg, $off", (FARJMP32i i32imm:$off, i16imm:$seg)>, Requires<[Not64BitMode]>;
3073 // Force mov without a suffix with a segment and mem to prefer the 'l' form of
3074 // the move. All segment/mem forms are equivalent, this has the shortest
3076 def : InstAlias<"mov\t{$mem, $seg|$seg, $mem}", (MOV32sm SEGMENT_REG:$seg, i32mem:$mem), 0>;
3077 def : InstAlias<"mov\t{$seg, $mem|$mem, $seg}", (MOV32ms i32mem:$mem, SEGMENT_REG:$seg), 0>;
3079 // Match 'movq <largeimm>, <reg>' as an alias for movabsq.
3080 def : InstAlias<"mov{q}\t{$imm, $reg|$reg, $imm}", (MOV64ri GR64:$reg, i64imm:$imm), 0>;
3082 // Match 'movq GR64, MMX' as an alias for movd.
3083 def : InstAlias<"movq\t{$src, $dst|$dst, $src}",
3084 (MMX_MOVD64to64rr VR64:$dst, GR64:$src), 0>;
3085 def : InstAlias<"movq\t{$src, $dst|$dst, $src}",
3086 (MMX_MOVD64from64rr GR64:$dst, VR64:$src), 0>;
3089 def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX16rr8 GR16:$dst, GR8:$src), 0>;
3090 def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX16rm8 GR16:$dst, i8mem:$src), 0>;
3091 def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX32rr8 GR32:$dst, GR8:$src), 0>;
3092 def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX32rr16 GR32:$dst, GR16:$src), 0>;
3093 def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX64rr8 GR64:$dst, GR8:$src), 0>;
3094 def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX64rr16 GR64:$dst, GR16:$src), 0>;
3095 def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX64rr32 GR64:$dst, GR32:$src), 0>;
3098 def : InstAlias<"movzx\t{$src, $dst|$dst, $src}", (MOVZX16rr8 GR16:$dst, GR8:$src), 0>;
3099 def : InstAlias<"movzx\t{$src, $dst|$dst, $src}", (MOVZX16rm8 GR16:$dst, i8mem:$src), 0>;
3100 def : InstAlias<"movzx\t{$src, $dst|$dst, $src}", (MOVZX32rr8 GR32:$dst, GR8:$src), 0>;
3101 def : InstAlias<"movzx\t{$src, $dst|$dst, $src}", (MOVZX32rr16 GR32:$dst, GR16:$src), 0>;
3102 def : InstAlias<"movzx\t{$src, $dst|$dst, $src}", (MOVZX64rr8 GR64:$dst, GR8:$src), 0>;
3103 def : InstAlias<"movzx\t{$src, $dst|$dst, $src}", (MOVZX64rr16 GR64:$dst, GR16:$src), 0>;
3104 // Note: No GR32->GR64 movzx form.
3106 // outb %dx -> outb %al, %dx
3107 def : InstAlias<"outb\t{%dx|dx}", (OUT8rr), 0>;
3108 def : InstAlias<"outw\t{%dx|dx}", (OUT16rr), 0>;
3109 def : InstAlias<"outl\t{%dx|dx}", (OUT32rr), 0>;
3110 def : InstAlias<"outb\t$port", (OUT8ir u8imm:$port), 0>;
3111 def : InstAlias<"outw\t$port", (OUT16ir u8imm:$port), 0>;
3112 def : InstAlias<"outl\t$port", (OUT32ir u8imm:$port), 0>;
3114 // 'sldt <mem>' can be encoded with either sldtw or sldtq with the same
3115 // effect (both store to a 16-bit mem). Force to sldtw to avoid ambiguity
3116 // errors, since its encoding is the most compact.
3117 def : InstAlias<"sldt $mem", (SLDT16m i16mem:$mem), 0>;
3119 // shld/shrd op,op -> shld op, op, CL
3120 def : InstAlias<"shld{w}\t{$r2, $r1|$r1, $r2}", (SHLD16rrCL GR16:$r1, GR16:$r2), 0>;
3121 def : InstAlias<"shld{l}\t{$r2, $r1|$r1, $r2}", (SHLD32rrCL GR32:$r1, GR32:$r2), 0>;
3122 def : InstAlias<"shld{q}\t{$r2, $r1|$r1, $r2}", (SHLD64rrCL GR64:$r1, GR64:$r2), 0>;
3123 def : InstAlias<"shrd{w}\t{$r2, $r1|$r1, $r2}", (SHRD16rrCL GR16:$r1, GR16:$r2), 0>;
3124 def : InstAlias<"shrd{l}\t{$r2, $r1|$r1, $r2}", (SHRD32rrCL GR32:$r1, GR32:$r2), 0>;
3125 def : InstAlias<"shrd{q}\t{$r2, $r1|$r1, $r2}", (SHRD64rrCL GR64:$r1, GR64:$r2), 0>;
3127 def : InstAlias<"shld{w}\t{$reg, $mem|$mem, $reg}", (SHLD16mrCL i16mem:$mem, GR16:$reg), 0>;
3128 def : InstAlias<"shld{l}\t{$reg, $mem|$mem, $reg}", (SHLD32mrCL i32mem:$mem, GR32:$reg), 0>;
3129 def : InstAlias<"shld{q}\t{$reg, $mem|$mem, $reg}", (SHLD64mrCL i64mem:$mem, GR64:$reg), 0>;
3130 def : InstAlias<"shrd{w}\t{$reg, $mem|$mem, $reg}", (SHRD16mrCL i16mem:$mem, GR16:$reg), 0>;
3131 def : InstAlias<"shrd{l}\t{$reg, $mem|$mem, $reg}", (SHRD32mrCL i32mem:$mem, GR32:$reg), 0>;
3132 def : InstAlias<"shrd{q}\t{$reg, $mem|$mem, $reg}", (SHRD64mrCL i64mem:$mem, GR64:$reg), 0>;
3134 /* FIXME: This is disabled because the asm matcher is currently incapable of
3135 * matching a fixed immediate like $1.
3136 // "shl X, $1" is an alias for "shl X".
3137 multiclass ShiftRotateByOneAlias<string Mnemonic, string Opc> {
3138 def : InstAlias<!strconcat(Mnemonic, "b $op, $$1"),
3139 (!cast<Instruction>(!strconcat(Opc, "8r1")) GR8:$op)>;
3140 def : InstAlias<!strconcat(Mnemonic, "w $op, $$1"),
3141 (!cast<Instruction>(!strconcat(Opc, "16r1")) GR16:$op)>;
3142 def : InstAlias<!strconcat(Mnemonic, "l $op, $$1"),
3143 (!cast<Instruction>(!strconcat(Opc, "32r1")) GR32:$op)>;
3144 def : InstAlias<!strconcat(Mnemonic, "q $op, $$1"),
3145 (!cast<Instruction>(!strconcat(Opc, "64r1")) GR64:$op)>;
3146 def : InstAlias<!strconcat(Mnemonic, "b $op, $$1"),
3147 (!cast<Instruction>(!strconcat(Opc, "8m1")) i8mem:$op)>;
3148 def : InstAlias<!strconcat(Mnemonic, "w $op, $$1"),
3149 (!cast<Instruction>(!strconcat(Opc, "16m1")) i16mem:$op)>;
3150 def : InstAlias<!strconcat(Mnemonic, "l $op, $$1"),
3151 (!cast<Instruction>(!strconcat(Opc, "32m1")) i32mem:$op)>;
3152 def : InstAlias<!strconcat(Mnemonic, "q $op, $$1"),
3153 (!cast<Instruction>(!strconcat(Opc, "64m1")) i64mem:$op)>;
3156 defm : ShiftRotateByOneAlias<"rcl", "RCL">;
3157 defm : ShiftRotateByOneAlias<"rcr", "RCR">;
3158 defm : ShiftRotateByOneAlias<"rol", "ROL">;
3159 defm : ShiftRotateByOneAlias<"ror", "ROR">;
3162 // test: We accept "testX <reg>, <mem>" and "testX <mem>, <reg>" as synonyms.
3163 def : InstAlias<"test{b}\t{$val, $mem|$mem, $val}",
3164 (TEST8rm GR8 :$val, i8mem :$mem), 0>;
3165 def : InstAlias<"test{w}\t{$val, $mem|$mem, $val}",
3166 (TEST16rm GR16:$val, i16mem:$mem), 0>;
3167 def : InstAlias<"test{l}\t{$val, $mem|$mem, $val}",
3168 (TEST32rm GR32:$val, i32mem:$mem), 0>;
3169 def : InstAlias<"test{q}\t{$val, $mem|$mem, $val}",
3170 (TEST64rm GR64:$val, i64mem:$mem), 0>;
3172 // xchg: We accept "xchgX <reg>, <mem>" and "xchgX <mem>, <reg>" as synonyms.
3173 def : InstAlias<"xchg{b}\t{$mem, $val|$val, $mem}",
3174 (XCHG8rm GR8 :$val, i8mem :$mem), 0>;
3175 def : InstAlias<"xchg{w}\t{$mem, $val|$val, $mem}",
3176 (XCHG16rm GR16:$val, i16mem:$mem), 0>;
3177 def : InstAlias<"xchg{l}\t{$mem, $val|$val, $mem}",
3178 (XCHG32rm GR32:$val, i32mem:$mem), 0>;
3179 def : InstAlias<"xchg{q}\t{$mem, $val|$val, $mem}",
3180 (XCHG64rm GR64:$val, i64mem:$mem), 0>;
3182 // xchg: We accept "xchgX <reg>, %eax" and "xchgX %eax, <reg>" as synonyms.
3183 def : InstAlias<"xchg{w}\t{%ax, $src|$src, ax}", (XCHG16ar GR16:$src), 0>;
3184 def : InstAlias<"xchg{l}\t{%eax, $src|$src, eax}",
3185 (XCHG32ar GR32:$src), 0>, Requires<[Not64BitMode]>;
3186 def : InstAlias<"xchg{l}\t{%eax, $src|$src, eax}",
3187 (XCHG32ar64 GR32_NOAX:$src), 0>, Requires<[In64BitMode]>;
3188 def : InstAlias<"xchg{q}\t{%rax, $src|$src, rax}", (XCHG64ar GR64:$src), 0>;
3190 // These aliases exist to get the parser to prioritize matching 8-bit
3191 // immediate encodings over matching the implicit ax/eax/rax encodings. By
3192 // explicitly mentioning the A register here, these entries will be ordered
3193 // first due to the more explicit immediate type.
3194 def : InstAlias<"adc{w}\t{$imm, %ax|ax, $imm}", (ADC16ri8 AX, i16i8imm:$imm), 0>;
3195 def : InstAlias<"add{w}\t{$imm, %ax|ax, $imm}", (ADD16ri8 AX, i16i8imm:$imm), 0>;
3196 def : InstAlias<"and{w}\t{$imm, %ax|ax, $imm}", (AND16ri8 AX, i16i8imm:$imm), 0>;
3197 def : InstAlias<"cmp{w}\t{$imm, %ax|ax, $imm}", (CMP16ri8 AX, i16i8imm:$imm), 0>;
3198 def : InstAlias<"or{w}\t{$imm, %ax|ax, $imm}", (OR16ri8 AX, i16i8imm:$imm), 0>;
3199 def : InstAlias<"sbb{w}\t{$imm, %ax|ax, $imm}", (SBB16ri8 AX, i16i8imm:$imm), 0>;
3200 def : InstAlias<"sub{w}\t{$imm, %ax|ax, $imm}", (SUB16ri8 AX, i16i8imm:$imm), 0>;
3201 def : InstAlias<"xor{w}\t{$imm, %ax|ax, $imm}", (XOR16ri8 AX, i16i8imm:$imm), 0>;
3203 def : InstAlias<"adc{l}\t{$imm, %eax|eax, $imm}", (ADC32ri8 EAX, i32i8imm:$imm), 0>;
3204 def : InstAlias<"add{l}\t{$imm, %eax|eax, $imm}", (ADD32ri8 EAX, i32i8imm:$imm), 0>;
3205 def : InstAlias<"and{l}\t{$imm, %eax|eax, $imm}", (AND32ri8 EAX, i32i8imm:$imm), 0>;
3206 def : InstAlias<"cmp{l}\t{$imm, %eax|eax, $imm}", (CMP32ri8 EAX, i32i8imm:$imm), 0>;
3207 def : InstAlias<"or{l}\t{$imm, %eax|eax, $imm}", (OR32ri8 EAX, i32i8imm:$imm), 0>;
3208 def : InstAlias<"sbb{l}\t{$imm, %eax|eax, $imm}", (SBB32ri8 EAX, i32i8imm:$imm), 0>;
3209 def : InstAlias<"sub{l}\t{$imm, %eax|eax, $imm}", (SUB32ri8 EAX, i32i8imm:$imm), 0>;
3210 def : InstAlias<"xor{l}\t{$imm, %eax|eax, $imm}", (XOR32ri8 EAX, i32i8imm:$imm), 0>;
3212 def : InstAlias<"adc{q}\t{$imm, %rax|rax, $imm}", (ADC64ri8 RAX, i64i8imm:$imm), 0>;
3213 def : InstAlias<"add{q}\t{$imm, %rax|rax, $imm}", (ADD64ri8 RAX, i64i8imm:$imm), 0>;
3214 def : InstAlias<"and{q}\t{$imm, %rax|rax, $imm}", (AND64ri8 RAX, i64i8imm:$imm), 0>;
3215 def : InstAlias<"cmp{q}\t{$imm, %rax|rax, $imm}", (CMP64ri8 RAX, i64i8imm:$imm), 0>;
3216 def : InstAlias<"or{q}\t{$imm, %rax|rax, $imm}", (OR64ri8 RAX, i64i8imm:$imm), 0>;
3217 def : InstAlias<"sbb{q}\t{$imm, %rax|rax, $imm}", (SBB64ri8 RAX, i64i8imm:$imm), 0>;
3218 def : InstAlias<"sub{q}\t{$imm, %rax|rax, $imm}", (SUB64ri8 RAX, i64i8imm:$imm), 0>;
3219 def : InstAlias<"xor{q}\t{$imm, %rax|rax, $imm}", (XOR64ri8 RAX, i64i8imm:$imm), 0>;