1 //====- X86Instr64bit.td - Describe X86-64 Instructions ----*- 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-64 instruction set, defining the instructions,
11 // and properties of the instructions which are needed for code generation,
12 // machine code emission, and analysis.
14 //===----------------------------------------------------------------------===//
16 //===----------------------------------------------------------------------===//
17 // Operand Definitions.
20 // 64-bits but only 32 bits are significant.
21 def i64i32imm : Operand<i64>;
23 // 64-bits but only 32 bits are significant, and those bits are treated as being
25 def i64i32imm_pcrel : Operand<i64> {
26 let PrintMethod = "print_pcrel_imm";
27 let ParserMatchClass = X86AbsMemAsmOperand;
31 // 64-bits but only 8 bits are significant.
32 def i64i8imm : Operand<i64> {
33 let ParserMatchClass = ImmSExt8AsmOperand;
36 // Special i64mem for addresses of load folding tail calls. These are not
37 // allowed to use callee-saved registers since they must be scheduled
38 // after callee-saved register are popped.
39 def i64mem_TC : Operand<i64> {
40 let PrintMethod = "printi64mem";
41 let MIOperandInfo = (ops GR64_TC, i8imm, GR64_TC, i32imm, i8imm);
42 let ParserMatchClass = X86MemAsmOperand;
45 def lea64mem : Operand<i64> {
46 let PrintMethod = "printlea64mem";
47 let MIOperandInfo = (ops GR64, i8imm, GR64_NOSP, i32imm);
48 let ParserMatchClass = X86NoSegMemAsmOperand;
51 def lea64_32mem : Operand<i32> {
52 let PrintMethod = "printlea64_32mem";
53 let AsmOperandLowerMethod = "lower_lea64_32mem";
54 let MIOperandInfo = (ops GR32, i8imm, GR32_NOSP, i32imm);
55 let ParserMatchClass = X86NoSegMemAsmOperand;
58 //===----------------------------------------------------------------------===//
59 // Complex Pattern Definitions.
61 def lea64addr : ComplexPattern<i64, 4, "SelectLEAAddr",
62 [add, sub, mul, X86mul_imm, shl, or, frameindex,
65 def tls64addr : ComplexPattern<i64, 4, "SelectTLSADDRAddr",
66 [tglobaltlsaddr], []>;
68 //===----------------------------------------------------------------------===//
72 def i64immSExt8 : PatLeaf<(i64 immSext8)>;
74 def GetLo32XForm : SDNodeXForm<imm, [{
75 // Transformation function: get the low 32 bits.
76 return getI32Imm((unsigned)N->getZExtValue());
79 def i64immSExt32 : PatLeaf<(i64 imm), [{
80 // i64immSExt32 predicate - True if the 64-bit immediate fits in a 32-bit
81 // sign extended field.
82 return (int64_t)N->getZExtValue() == (int32_t)N->getZExtValue();
86 def i64immZExt32 : PatLeaf<(i64 imm), [{
87 // i64immZExt32 predicate - True if the 64-bit immediate fits in a 32-bit
88 // unsignedsign extended field.
89 return (uint64_t)N->getZExtValue() == (uint32_t)N->getZExtValue();
92 def sextloadi64i8 : PatFrag<(ops node:$ptr), (i64 (sextloadi8 node:$ptr))>;
93 def sextloadi64i16 : PatFrag<(ops node:$ptr), (i64 (sextloadi16 node:$ptr))>;
94 def sextloadi64i32 : PatFrag<(ops node:$ptr), (i64 (sextloadi32 node:$ptr))>;
96 def zextloadi64i1 : PatFrag<(ops node:$ptr), (i64 (zextloadi1 node:$ptr))>;
97 def zextloadi64i8 : PatFrag<(ops node:$ptr), (i64 (zextloadi8 node:$ptr))>;
98 def zextloadi64i16 : PatFrag<(ops node:$ptr), (i64 (zextloadi16 node:$ptr))>;
99 def zextloadi64i32 : PatFrag<(ops node:$ptr), (i64 (zextloadi32 node:$ptr))>;
101 def extloadi64i1 : PatFrag<(ops node:$ptr), (i64 (extloadi1 node:$ptr))>;
102 def extloadi64i8 : PatFrag<(ops node:$ptr), (i64 (extloadi8 node:$ptr))>;
103 def extloadi64i16 : PatFrag<(ops node:$ptr), (i64 (extloadi16 node:$ptr))>;
104 def extloadi64i32 : PatFrag<(ops node:$ptr), (i64 (extloadi32 node:$ptr))>;
106 //===----------------------------------------------------------------------===//
107 // Instruction list...
110 // ADJCALLSTACKDOWN/UP implicitly use/def RSP because they may be expanded into
111 // a stack adjustment and the codegen must know that they may modify the stack
112 // pointer before prolog-epilog rewriting occurs.
113 // Pessimistically assume ADJCALLSTACKDOWN / ADJCALLSTACKUP will become
114 // sub / add which can clobber EFLAGS.
115 let Defs = [RSP, EFLAGS], Uses = [RSP] in {
116 def ADJCALLSTACKDOWN64 : I<0, Pseudo, (outs), (ins i32imm:$amt),
118 [(X86callseq_start timm:$amt)]>,
119 Requires<[In64BitMode]>;
120 def ADJCALLSTACKUP64 : I<0, Pseudo, (outs), (ins i32imm:$amt1, i32imm:$amt2),
122 [(X86callseq_end timm:$amt1, timm:$amt2)]>,
123 Requires<[In64BitMode]>;
126 // Interrupt Instructions
127 def IRET64 : RI<0xcf, RawFrm, (outs), (ins), "iret{q}", []>;
129 //===----------------------------------------------------------------------===//
130 // Call Instructions...
133 // All calls clobber the non-callee saved registers. RSP is marked as
134 // a use to prevent stack-pointer assignments that appear immediately
135 // before calls from potentially appearing dead. Uses for argument
136 // registers are added manually.
137 let Defs = [RAX, RCX, RDX, RSI, RDI, R8, R9, R10, R11,
138 FP0, FP1, FP2, FP3, FP4, FP5, FP6, ST0, ST1,
139 MM0, MM1, MM2, MM3, MM4, MM5, MM6, MM7,
140 XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7,
141 XMM8, XMM9, XMM10, XMM11, XMM12, XMM13, XMM14, XMM15, EFLAGS],
144 // NOTE: this pattern doesn't match "X86call imm", because we do not know
145 // that the offset between an arbitrary immediate and the call will fit in
146 // the 32-bit pcrel field that we have.
147 def CALL64pcrel32 : Ii32PCRel<0xE8, RawFrm,
148 (outs), (ins i64i32imm_pcrel:$dst, variable_ops),
149 "call{q}\t$dst", []>,
150 Requires<[In64BitMode, NotWin64]>;
151 def CALL64r : I<0xFF, MRM2r, (outs), (ins GR64:$dst, variable_ops),
152 "call{q}\t{*}$dst", [(X86call GR64:$dst)]>,
153 Requires<[NotWin64]>;
154 def CALL64m : I<0xFF, MRM2m, (outs), (ins i64mem:$dst, variable_ops),
155 "call{q}\t{*}$dst", [(X86call (loadi64 addr:$dst))]>,
156 Requires<[NotWin64]>;
158 def FARCALL64 : RI<0xFF, MRM3m, (outs), (ins opaque80mem:$dst),
159 "lcall{q}\t{*}$dst", []>;
162 // FIXME: We need to teach codegen about single list of call-clobbered
165 // All calls clobber the non-callee saved registers. RSP is marked as
166 // a use to prevent stack-pointer assignments that appear immediately
167 // before calls from potentially appearing dead. Uses for argument
168 // registers are added manually.
169 let Defs = [RAX, RCX, RDX, R8, R9, R10, R11,
170 FP0, FP1, FP2, FP3, FP4, FP5, FP6, ST0, ST1,
171 MM0, MM1, MM2, MM3, MM4, MM5, MM6, MM7,
172 XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, EFLAGS],
174 def WINCALL64pcrel32 : I<0xE8, RawFrm,
175 (outs), (ins i64i32imm_pcrel:$dst, variable_ops),
178 def WINCALL64r : I<0xFF, MRM2r, (outs), (ins GR64:$dst, variable_ops),
180 [(X86call GR64:$dst)]>, Requires<[IsWin64]>;
181 def WINCALL64m : I<0xFF, MRM2m, (outs),
182 (ins i64mem:$dst, variable_ops), "call\t{*}$dst",
183 [(X86call (loadi64 addr:$dst))]>,
188 let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in
189 let Defs = [RAX, RCX, RDX, RSI, RDI, R8, R9, R10, R11,
190 FP0, FP1, FP2, FP3, FP4, FP5, FP6, ST0, ST1,
191 MM0, MM1, MM2, MM3, MM4, MM5, MM6, MM7,
192 XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7,
193 XMM8, XMM9, XMM10, XMM11, XMM12, XMM13, XMM14, XMM15, EFLAGS],
195 def TCRETURNdi64 : I<0, Pseudo, (outs),
196 (ins i64i32imm_pcrel:$dst, i32imm:$offset, variable_ops),
197 "#TC_RETURN $dst $offset", []>;
198 def TCRETURNri64 : I<0, Pseudo, (outs), (ins GR64_TC:$dst, i32imm:$offset,
200 "#TC_RETURN $dst $offset", []>;
202 def TCRETURNmi64 : I<0, Pseudo, (outs),
203 (ins i64mem_TC:$dst, i32imm:$offset, variable_ops),
204 "#TC_RETURN $dst $offset", []>;
206 def TAILJMPd64 : Ii32PCRel<0xE9, RawFrm, (outs),
207 (ins i64i32imm_pcrel:$dst, variable_ops),
208 "jmp\t$dst # TAILCALL", []>;
209 def TAILJMPr64 : I<0xFF, MRM4r, (outs), (ins GR64_TC:$dst, variable_ops),
210 "jmp{q}\t{*}$dst # TAILCALL", []>;
213 def TAILJMPm64 : I<0xFF, MRM4m, (outs), (ins i64mem_TC:$dst, variable_ops),
214 "jmp{q}\t{*}$dst # TAILCALL", []>;
218 let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in {
219 def JMP64pcrel32 : I<0xE9, RawFrm, (outs), (ins brtarget:$dst),
221 def JMP64r : I<0xFF, MRM4r, (outs), (ins GR64:$dst), "jmp{q}\t{*}$dst",
222 [(brind GR64:$dst)]>;
223 def JMP64m : I<0xFF, MRM4m, (outs), (ins i64mem:$dst), "jmp{q}\t{*}$dst",
224 [(brind (loadi64 addr:$dst))]>;
225 def FARJMP64 : RI<0xFF, MRM5m, (outs), (ins opaque80mem:$dst),
226 "ljmp{q}\t{*}$dst", []>;
229 //===----------------------------------------------------------------------===//
230 // EH Pseudo Instructions
232 let isTerminator = 1, isReturn = 1, isBarrier = 1,
233 hasCtrlDep = 1, isCodeGenOnly = 1 in {
234 def EH_RETURN64 : I<0xC3, RawFrm, (outs), (ins GR64:$addr),
235 "ret\t#eh_return, addr: $addr",
236 [(X86ehret GR64:$addr)]>;
240 //===----------------------------------------------------------------------===//
241 // Miscellaneous Instructions...
244 def POPCNT64rr : RI<0xB8, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
245 "popcnt{q}\t{$src, $dst|$dst, $src}", []>, XS;
247 def POPCNT64rm : RI<0xB8, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
248 "popcnt{q}\t{$src, $dst|$dst, $src}", []>, XS;
250 let Defs = [RBP,RSP], Uses = [RBP,RSP], mayLoad = 1, neverHasSideEffects = 1 in
251 def LEAVE64 : I<0xC9, RawFrm,
252 (outs), (ins), "leave", []>;
253 let Defs = [RSP], Uses = [RSP], neverHasSideEffects=1 in {
255 def POP64r : I<0x58, AddRegFrm,
256 (outs GR64:$reg), (ins), "pop{q}\t$reg", []>;
257 def POP64rmr: I<0x8F, MRM0r, (outs GR64:$reg), (ins), "pop{q}\t$reg", []>;
258 def POP64rmm: I<0x8F, MRM0m, (outs i64mem:$dst), (ins), "pop{q}\t$dst", []>;
260 let mayStore = 1 in {
261 def PUSH64r : I<0x50, AddRegFrm,
262 (outs), (ins GR64:$reg), "push{q}\t$reg", []>;
263 def PUSH64rmr: I<0xFF, MRM6r, (outs), (ins GR64:$reg), "push{q}\t$reg", []>;
264 def PUSH64rmm: I<0xFF, MRM6m, (outs), (ins i64mem:$src), "push{q}\t$src", []>;
268 let Defs = [RSP], Uses = [RSP], neverHasSideEffects = 1, mayStore = 1 in {
269 def PUSH64i8 : Ii8<0x6a, RawFrm, (outs), (ins i8imm:$imm),
270 "push{q}\t$imm", []>;
271 def PUSH64i16 : Ii16<0x68, RawFrm, (outs), (ins i16imm:$imm),
272 "push{q}\t$imm", []>;
273 def PUSH64i32 : Ii32<0x68, RawFrm, (outs), (ins i32imm:$imm),
274 "push{q}\t$imm", []>;
277 let Defs = [RSP, EFLAGS], Uses = [RSP], mayLoad = 1 in
278 def POPFQ : I<0x9D, RawFrm, (outs), (ins), "popf{q}", []>, REX_W;
279 let Defs = [RSP], Uses = [RSP, EFLAGS], mayStore = 1 in
280 def PUSHFQ64 : I<0x9C, RawFrm, (outs), (ins), "pushf{q}", []>;
282 def LEA64_32r : I<0x8D, MRMSrcMem,
283 (outs GR32:$dst), (ins lea64_32mem:$src),
284 "lea{l}\t{$src|$dst}, {$dst|$src}",
285 [(set GR32:$dst, lea32addr:$src)]>, Requires<[In64BitMode]>;
287 let isReMaterializable = 1 in
288 def LEA64r : RI<0x8D, MRMSrcMem, (outs GR64:$dst), (ins lea64mem:$src),
289 "lea{q}\t{$src|$dst}, {$dst|$src}",
290 [(set GR64:$dst, lea64addr:$src)]>;
292 let isTwoAddress = 1 in
293 def BSWAP64r : RI<0xC8, AddRegFrm, (outs GR64:$dst), (ins GR64:$src),
295 [(set GR64:$dst, (bswap GR64:$src))]>, TB;
297 // Bit scan instructions.
298 let Defs = [EFLAGS] in {
299 def BSF64rr : RI<0xBC, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
300 "bsf{q}\t{$src, $dst|$dst, $src}",
301 [(set GR64:$dst, EFLAGS, (X86bsf GR64:$src))]>, TB;
302 def BSF64rm : RI<0xBC, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
303 "bsf{q}\t{$src, $dst|$dst, $src}",
304 [(set GR64:$dst, EFLAGS, (X86bsf (loadi64 addr:$src)))]>, TB;
306 def BSR64rr : RI<0xBD, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
307 "bsr{q}\t{$src, $dst|$dst, $src}",
308 [(set GR64:$dst, EFLAGS, (X86bsr GR64:$src))]>, TB;
309 def BSR64rm : RI<0xBD, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
310 "bsr{q}\t{$src, $dst|$dst, $src}",
311 [(set GR64:$dst, EFLAGS, (X86bsr (loadi64 addr:$src)))]>, TB;
315 let Defs = [RCX,RDI,RSI], Uses = [RCX,RDI,RSI], isCodeGenOnly = 1 in
316 def REP_MOVSQ : RI<0xA5, RawFrm, (outs), (ins), "{rep;movsq|rep movsq}",
317 [(X86rep_movs i64)]>, REP;
318 let Defs = [RCX,RDI], Uses = [RAX,RCX,RDI], isCodeGenOnly = 1 in
319 def REP_STOSQ : RI<0xAB, RawFrm, (outs), (ins), "{rep;stosq|rep stosq}",
320 [(X86rep_stos i64)]>, REP;
322 let Defs = [EDI,ESI], Uses = [EDI,ESI,EFLAGS] in
323 def MOVSQ : RI<0xA5, RawFrm, (outs), (ins), "movsq", []>;
325 let Defs = [RCX,RDI], Uses = [RAX,RCX,RDI,EFLAGS] in
326 def STOSQ : RI<0xAB, RawFrm, (outs), (ins), "stosq", []>;
328 def SCAS64 : RI<0xAF, RawFrm, (outs), (ins), "scasq", []>;
330 def CMPS64 : RI<0xA7, RawFrm, (outs), (ins), "cmpsq", []>;
332 // Fast system-call instructions
333 def SYSEXIT64 : RI<0x35, RawFrm,
334 (outs), (ins), "sysexit", []>, TB;
336 //===----------------------------------------------------------------------===//
337 // Move Instructions...
340 let neverHasSideEffects = 1 in
341 def MOV64rr : RI<0x89, MRMDestReg, (outs GR64:$dst), (ins GR64:$src),
342 "mov{q}\t{$src, $dst|$dst, $src}", []>;
344 let isReMaterializable = 1, isAsCheapAsAMove = 1 in {
345 def MOV64ri : RIi64<0xB8, AddRegFrm, (outs GR64:$dst), (ins i64imm:$src),
346 "movabs{q}\t{$src, $dst|$dst, $src}",
347 [(set GR64:$dst, imm:$src)]>;
348 def MOV64ri32 : RIi32<0xC7, MRM0r, (outs GR64:$dst), (ins i64i32imm:$src),
349 "mov{q}\t{$src, $dst|$dst, $src}",
350 [(set GR64:$dst, i64immSExt32:$src)]>;
353 def MOV64rr_REV : RI<0x8B, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
354 "mov{q}\t{$src, $dst|$dst, $src}", []>;
356 let canFoldAsLoad = 1, isReMaterializable = 1 in
357 def MOV64rm : RI<0x8B, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
358 "mov{q}\t{$src, $dst|$dst, $src}",
359 [(set GR64:$dst, (load addr:$src))]>;
361 def MOV64mr : RI<0x89, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
362 "mov{q}\t{$src, $dst|$dst, $src}",
363 [(store GR64:$src, addr:$dst)]>;
364 def MOV64mi32 : RIi32<0xC7, MRM0m, (outs), (ins i64mem:$dst, i64i32imm:$src),
365 "mov{q}\t{$src, $dst|$dst, $src}",
366 [(store i64immSExt32:$src, addr:$dst)]>;
368 /// Versions of MOV64rr, MOV64rm, and MOV64mr for i64mem_TC and GR64_TC.
369 let neverHasSideEffects = 1 in
370 def MOV64rr_TC : RI<0x89, MRMDestReg, (outs GR64_TC:$dst), (ins GR64_TC:$src),
371 "mov{q}\t{$src, $dst|$dst, $src}", []>;
374 canFoldAsLoad = 1, isReMaterializable = 1 in
375 def MOV64rm_TC : RI<0x8B, MRMSrcMem, (outs GR64_TC:$dst), (ins i64mem_TC:$src),
376 "mov{q}\t{$src, $dst|$dst, $src}",
380 def MOV64mr_TC : RI<0x89, MRMDestMem, (outs), (ins i64mem_TC:$dst, GR64_TC:$src),
381 "mov{q}\t{$src, $dst|$dst, $src}",
384 def MOV64o8a : RIi8<0xA0, RawFrm, (outs), (ins offset8:$src),
385 "mov{q}\t{$src, %rax|%rax, $src}", []>;
386 def MOV64o64a : RIi32<0xA1, RawFrm, (outs), (ins offset64:$src),
387 "mov{q}\t{$src, %rax|%rax, $src}", []>;
388 def MOV64ao8 : RIi8<0xA2, RawFrm, (outs offset8:$dst), (ins),
389 "mov{q}\t{%rax, $dst|$dst, %rax}", []>;
390 def MOV64ao64 : RIi32<0xA3, RawFrm, (outs offset64:$dst), (ins),
391 "mov{q}\t{%rax, $dst|$dst, %rax}", []>;
393 // Moves to and from segment registers
394 def MOV64rs : RI<0x8C, MRMDestReg, (outs GR64:$dst), (ins SEGMENT_REG:$src),
395 "mov{q}\t{$src, $dst|$dst, $src}", []>;
396 def MOV64ms : RI<0x8C, MRMDestMem, (outs i64mem:$dst), (ins SEGMENT_REG:$src),
397 "mov{q}\t{$src, $dst|$dst, $src}", []>;
398 def MOV64sr : RI<0x8E, MRMSrcReg, (outs SEGMENT_REG:$dst), (ins GR64:$src),
399 "mov{q}\t{$src, $dst|$dst, $src}", []>;
400 def MOV64sm : RI<0x8E, MRMSrcMem, (outs SEGMENT_REG:$dst), (ins i64mem:$src),
401 "mov{q}\t{$src, $dst|$dst, $src}", []>;
403 // Moves to and from debug registers
404 def MOV64rd : I<0x21, MRMDestReg, (outs GR64:$dst), (ins DEBUG_REG:$src),
405 "mov{q}\t{$src, $dst|$dst, $src}", []>, TB;
406 def MOV64dr : I<0x23, MRMSrcReg, (outs DEBUG_REG:$dst), (ins GR64:$src),
407 "mov{q}\t{$src, $dst|$dst, $src}", []>, TB;
409 // Moves to and from control registers
410 def MOV64rc : I<0x20, MRMDestReg, (outs GR64:$dst), (ins CONTROL_REG:$src),
411 "mov{q}\t{$src, $dst|$dst, $src}", []>, TB;
412 def MOV64cr : I<0x22, MRMSrcReg, (outs CONTROL_REG:$dst), (ins GR64:$src),
413 "mov{q}\t{$src, $dst|$dst, $src}", []>, TB;
415 // Sign/Zero extenders
417 // MOVSX64rr8 always has a REX prefix and it has an 8-bit register
418 // operand, which makes it a rare instruction with an 8-bit register
419 // operand that can never access an h register. If support for h registers
420 // were generalized, this would require a special register class.
421 def MOVSX64rr8 : RI<0xBE, MRMSrcReg, (outs GR64:$dst), (ins GR8 :$src),
422 "movs{bq|x}\t{$src, $dst|$dst, $src}",
423 [(set GR64:$dst, (sext GR8:$src))]>, TB;
424 def MOVSX64rm8 : RI<0xBE, MRMSrcMem, (outs GR64:$dst), (ins i8mem :$src),
425 "movs{bq|x}\t{$src, $dst|$dst, $src}",
426 [(set GR64:$dst, (sextloadi64i8 addr:$src))]>, TB;
427 def MOVSX64rr16: RI<0xBF, MRMSrcReg, (outs GR64:$dst), (ins GR16:$src),
428 "movs{wq|x}\t{$src, $dst|$dst, $src}",
429 [(set GR64:$dst, (sext GR16:$src))]>, TB;
430 def MOVSX64rm16: RI<0xBF, MRMSrcMem, (outs GR64:$dst), (ins i16mem:$src),
431 "movs{wq|x}\t{$src, $dst|$dst, $src}",
432 [(set GR64:$dst, (sextloadi64i16 addr:$src))]>, TB;
433 def MOVSX64rr32: RI<0x63, MRMSrcReg, (outs GR64:$dst), (ins GR32:$src),
434 "movs{lq|xd}\t{$src, $dst|$dst, $src}",
435 [(set GR64:$dst, (sext GR32:$src))]>;
436 def MOVSX64rm32: RI<0x63, MRMSrcMem, (outs GR64:$dst), (ins i32mem:$src),
437 "movs{lq|xd}\t{$src, $dst|$dst, $src}",
438 [(set GR64:$dst, (sextloadi64i32 addr:$src))]>;
440 // movzbq and movzwq encodings for the disassembler
441 def MOVZX64rr8_Q : RI<0xB6, MRMSrcReg, (outs GR64:$dst), (ins GR8:$src),
442 "movz{bq|x}\t{$src, $dst|$dst, $src}", []>, TB;
443 def MOVZX64rm8_Q : RI<0xB6, MRMSrcMem, (outs GR64:$dst), (ins i8mem:$src),
444 "movz{bq|x}\t{$src, $dst|$dst, $src}", []>, TB;
445 def MOVZX64rr16_Q : RI<0xB7, MRMSrcReg, (outs GR64:$dst), (ins GR16:$src),
446 "movz{wq|x}\t{$src, $dst|$dst, $src}", []>, TB;
447 def MOVZX64rm16_Q : RI<0xB7, MRMSrcMem, (outs GR64:$dst), (ins i16mem:$src),
448 "movz{wq|x}\t{$src, $dst|$dst, $src}", []>, TB;
450 // Use movzbl instead of movzbq when the destination is a register; it's
451 // equivalent due to implicit zero-extending, and it has a smaller encoding.
452 def MOVZX64rr8 : I<0xB6, MRMSrcReg, (outs GR64:$dst), (ins GR8 :$src),
453 "", [(set GR64:$dst, (zext GR8:$src))]>, TB;
454 def MOVZX64rm8 : I<0xB6, MRMSrcMem, (outs GR64:$dst), (ins i8mem :$src),
455 "", [(set GR64:$dst, (zextloadi64i8 addr:$src))]>, TB;
456 // Use movzwl instead of movzwq when the destination is a register; it's
457 // equivalent due to implicit zero-extending, and it has a smaller encoding.
458 def MOVZX64rr16: I<0xB7, MRMSrcReg, (outs GR64:$dst), (ins GR16:$src),
459 "", [(set GR64:$dst, (zext GR16:$src))]>, TB;
460 def MOVZX64rm16: I<0xB7, MRMSrcMem, (outs GR64:$dst), (ins i16mem:$src),
461 "", [(set GR64:$dst, (zextloadi64i16 addr:$src))]>, TB;
463 // There's no movzlq instruction, but movl can be used for this purpose, using
464 // implicit zero-extension. The preferred way to do 32-bit-to-64-bit zero
465 // extension on x86-64 is to use a SUBREG_TO_REG to utilize implicit
466 // zero-extension, however this isn't possible when the 32-bit value is
467 // defined by a truncate or is copied from something where the high bits aren't
468 // necessarily all zero. In such cases, we fall back to these explicit zext
470 def MOVZX64rr32 : I<0x89, MRMDestReg, (outs GR64:$dst), (ins GR32:$src),
471 "", [(set GR64:$dst, (zext GR32:$src))]>;
472 def MOVZX64rm32 : I<0x8B, MRMSrcMem, (outs GR64:$dst), (ins i32mem:$src),
473 "", [(set GR64:$dst, (zextloadi64i32 addr:$src))]>;
475 // Any instruction that defines a 32-bit result leaves the high half of the
476 // register. Truncate can be lowered to EXTRACT_SUBREG. CopyFromReg may
477 // be copying from a truncate. And x86's cmov doesn't do anything if the
478 // condition is false. But any other 32-bit operation will zero-extend
480 def def32 : PatLeaf<(i32 GR32:$src), [{
481 return N->getOpcode() != ISD::TRUNCATE &&
482 N->getOpcode() != TargetOpcode::EXTRACT_SUBREG &&
483 N->getOpcode() != ISD::CopyFromReg &&
484 N->getOpcode() != X86ISD::CMOV;
487 // In the case of a 32-bit def that is known to implicitly zero-extend,
488 // we can use a SUBREG_TO_REG.
489 def : Pat<(i64 (zext def32:$src)),
490 (SUBREG_TO_REG (i64 0), GR32:$src, x86_subreg_32bit)>;
492 let neverHasSideEffects = 1 in {
493 let Defs = [RAX], Uses = [EAX] in
494 def CDQE : RI<0x98, RawFrm, (outs), (ins),
495 "{cltq|cdqe}", []>; // RAX = signext(EAX)
497 let Defs = [RAX,RDX], Uses = [RAX] in
498 def CQO : RI<0x99, RawFrm, (outs), (ins),
499 "{cqto|cqo}", []>; // RDX:RAX = signext(RAX)
502 //===----------------------------------------------------------------------===//
503 // Arithmetic Instructions...
506 let Defs = [EFLAGS] in {
508 def ADD64i32 : RIi32<0x05, RawFrm, (outs), (ins i32imm:$src),
509 "add{q}\t{$src, %rax|%rax, $src}", []>;
511 let isTwoAddress = 1 in {
512 let isConvertibleToThreeAddress = 1 in {
513 let isCommutable = 1 in
514 // Register-Register Addition
515 def ADD64rr : RI<0x01, MRMDestReg, (outs GR64:$dst),
516 (ins GR64:$src1, GR64:$src2),
517 "add{q}\t{$src2, $dst|$dst, $src2}",
518 [(set GR64:$dst, EFLAGS,
519 (X86add_flag GR64:$src1, GR64:$src2))]>;
521 // These are alternate spellings for use by the disassembler, we mark them as
522 // code gen only to ensure they aren't matched by the assembler.
523 let isCodeGenOnly = 1 in {
524 def ADD64rr_alt : RI<0x03, MRMSrcReg, (outs GR64:$dst),
525 (ins GR64:$src1, GR64:$src2),
526 "add{l}\t{$src2, $dst|$dst, $src2}", []>;
529 // Register-Integer Addition
530 def ADD64ri8 : RIi8<0x83, MRM0r, (outs GR64:$dst),
531 (ins GR64:$src1, i64i8imm:$src2),
532 "add{q}\t{$src2, $dst|$dst, $src2}",
533 [(set GR64:$dst, EFLAGS,
534 (X86add_flag GR64:$src1, i64immSExt8:$src2))]>;
535 def ADD64ri32 : RIi32<0x81, MRM0r, (outs GR64:$dst),
536 (ins GR64:$src1, i64i32imm:$src2),
537 "add{q}\t{$src2, $dst|$dst, $src2}",
538 [(set GR64:$dst, EFLAGS,
539 (X86add_flag GR64:$src1, i64immSExt32:$src2))]>;
540 } // isConvertibleToThreeAddress
542 // Register-Memory Addition
543 def ADD64rm : RI<0x03, MRMSrcMem, (outs GR64:$dst),
544 (ins GR64:$src1, i64mem:$src2),
545 "add{q}\t{$src2, $dst|$dst, $src2}",
546 [(set GR64:$dst, EFLAGS,
547 (X86add_flag GR64:$src1, (load addr:$src2)))]>;
551 // Memory-Register Addition
552 def ADD64mr : RI<0x01, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src2),
553 "add{q}\t{$src2, $dst|$dst, $src2}",
554 [(store (add (load addr:$dst), GR64:$src2), addr:$dst),
556 def ADD64mi8 : RIi8<0x83, MRM0m, (outs), (ins i64mem:$dst, i64i8imm :$src2),
557 "add{q}\t{$src2, $dst|$dst, $src2}",
558 [(store (add (load addr:$dst), i64immSExt8:$src2), addr:$dst),
560 def ADD64mi32 : RIi32<0x81, MRM0m, (outs), (ins i64mem:$dst, i64i32imm :$src2),
561 "add{q}\t{$src2, $dst|$dst, $src2}",
562 [(store (add (load addr:$dst), i64immSExt32:$src2), addr:$dst),
565 let Uses = [EFLAGS] in {
567 def ADC64i32 : RIi32<0x15, RawFrm, (outs), (ins i32imm:$src),
568 "adc{q}\t{$src, %rax|%rax, $src}", []>;
570 let isTwoAddress = 1 in {
571 let isCommutable = 1 in
572 def ADC64rr : RI<0x11, MRMDestReg, (outs GR64:$dst),
573 (ins GR64:$src1, GR64:$src2),
574 "adc{q}\t{$src2, $dst|$dst, $src2}",
575 [(set GR64:$dst, (adde GR64:$src1, GR64:$src2))]>;
577 def ADC64rr_REV : RI<0x13, MRMSrcReg , (outs GR32:$dst),
578 (ins GR64:$src1, GR64:$src2),
579 "adc{q}\t{$src2, $dst|$dst, $src2}", []>;
581 def ADC64rm : RI<0x13, MRMSrcMem , (outs GR64:$dst),
582 (ins GR64:$src1, i64mem:$src2),
583 "adc{q}\t{$src2, $dst|$dst, $src2}",
584 [(set GR64:$dst, (adde GR64:$src1, (load addr:$src2)))]>;
586 def ADC64ri8 : RIi8<0x83, MRM2r, (outs GR64:$dst),
587 (ins GR64:$src1, i64i8imm:$src2),
588 "adc{q}\t{$src2, $dst|$dst, $src2}",
589 [(set GR64:$dst, (adde GR64:$src1, i64immSExt8:$src2))]>;
590 def ADC64ri32 : RIi32<0x81, MRM2r, (outs GR64:$dst),
591 (ins GR64:$src1, i64i32imm:$src2),
592 "adc{q}\t{$src2, $dst|$dst, $src2}",
593 [(set GR64:$dst, (adde GR64:$src1, i64immSExt32:$src2))]>;
596 def ADC64mr : RI<0x11, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src2),
597 "adc{q}\t{$src2, $dst|$dst, $src2}",
598 [(store (adde (load addr:$dst), GR64:$src2), addr:$dst)]>;
599 def ADC64mi8 : RIi8<0x83, MRM2m, (outs), (ins i64mem:$dst, i64i8imm :$src2),
600 "adc{q}\t{$src2, $dst|$dst, $src2}",
601 [(store (adde (load addr:$dst), i64immSExt8:$src2),
603 def ADC64mi32 : RIi32<0x81, MRM2m, (outs), (ins i64mem:$dst, i64i32imm:$src2),
604 "adc{q}\t{$src2, $dst|$dst, $src2}",
605 [(store (adde (load addr:$dst), i64immSExt32:$src2),
609 let isTwoAddress = 1 in {
610 // Register-Register Subtraction
611 def SUB64rr : RI<0x29, MRMDestReg, (outs GR64:$dst),
612 (ins GR64:$src1, GR64:$src2),
613 "sub{q}\t{$src2, $dst|$dst, $src2}",
614 [(set GR64:$dst, EFLAGS,
615 (X86sub_flag GR64:$src1, GR64:$src2))]>;
617 def SUB64rr_REV : RI<0x2B, MRMSrcReg, (outs GR64:$dst),
618 (ins GR64:$src1, GR64:$src2),
619 "sub{q}\t{$src2, $dst|$dst, $src2}", []>;
621 // Register-Memory Subtraction
622 def SUB64rm : RI<0x2B, MRMSrcMem, (outs GR64:$dst),
623 (ins GR64:$src1, i64mem:$src2),
624 "sub{q}\t{$src2, $dst|$dst, $src2}",
625 [(set GR64:$dst, EFLAGS,
626 (X86sub_flag GR64:$src1, (load addr:$src2)))]>;
628 // Register-Integer Subtraction
629 def SUB64ri8 : RIi8<0x83, MRM5r, (outs GR64:$dst),
630 (ins GR64:$src1, i64i8imm:$src2),
631 "sub{q}\t{$src2, $dst|$dst, $src2}",
632 [(set GR64:$dst, EFLAGS,
633 (X86sub_flag GR64:$src1, i64immSExt8:$src2))]>;
634 def SUB64ri32 : RIi32<0x81, MRM5r, (outs GR64:$dst),
635 (ins GR64:$src1, i64i32imm:$src2),
636 "sub{q}\t{$src2, $dst|$dst, $src2}",
637 [(set GR64:$dst, EFLAGS,
638 (X86sub_flag GR64:$src1, i64immSExt32:$src2))]>;
641 def SUB64i32 : RIi32<0x2D, RawFrm, (outs), (ins i32imm:$src),
642 "sub{q}\t{$src, %rax|%rax, $src}", []>;
644 // Memory-Register Subtraction
645 def SUB64mr : RI<0x29, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src2),
646 "sub{q}\t{$src2, $dst|$dst, $src2}",
647 [(store (sub (load addr:$dst), GR64:$src2), addr:$dst),
650 // Memory-Integer Subtraction
651 def SUB64mi8 : RIi8<0x83, MRM5m, (outs), (ins i64mem:$dst, i64i8imm :$src2),
652 "sub{q}\t{$src2, $dst|$dst, $src2}",
653 [(store (sub (load addr:$dst), i64immSExt8:$src2),
656 def SUB64mi32 : RIi32<0x81, MRM5m, (outs), (ins i64mem:$dst, i64i32imm:$src2),
657 "sub{q}\t{$src2, $dst|$dst, $src2}",
658 [(store (sub (load addr:$dst), i64immSExt32:$src2),
662 let Uses = [EFLAGS] in {
663 let isTwoAddress = 1 in {
664 def SBB64rr : RI<0x19, MRMDestReg, (outs GR64:$dst),
665 (ins GR64:$src1, GR64:$src2),
666 "sbb{q}\t{$src2, $dst|$dst, $src2}",
667 [(set GR64:$dst, (sube GR64:$src1, GR64:$src2))]>;
669 def SBB64rr_REV : RI<0x1B, MRMSrcReg, (outs GR64:$dst),
670 (ins GR64:$src1, GR64:$src2),
671 "sbb{q}\t{$src2, $dst|$dst, $src2}", []>;
673 def SBB64rm : RI<0x1B, MRMSrcMem, (outs GR64:$dst),
674 (ins GR64:$src1, i64mem:$src2),
675 "sbb{q}\t{$src2, $dst|$dst, $src2}",
676 [(set GR64:$dst, (sube GR64:$src1, (load addr:$src2)))]>;
678 def SBB64ri8 : RIi8<0x83, MRM3r, (outs GR64:$dst),
679 (ins GR64:$src1, i64i8imm:$src2),
680 "sbb{q}\t{$src2, $dst|$dst, $src2}",
681 [(set GR64:$dst, (sube GR64:$src1, i64immSExt8:$src2))]>;
682 def SBB64ri32 : RIi32<0x81, MRM3r, (outs GR64:$dst),
683 (ins GR64:$src1, i64i32imm:$src2),
684 "sbb{q}\t{$src2, $dst|$dst, $src2}",
685 [(set GR64:$dst, (sube GR64:$src1, i64immSExt32:$src2))]>;
688 def SBB64i32 : RIi32<0x1D, RawFrm, (outs), (ins i32imm:$src),
689 "sbb{q}\t{$src, %rax|%rax, $src}", []>;
691 def SBB64mr : RI<0x19, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src2),
692 "sbb{q}\t{$src2, $dst|$dst, $src2}",
693 [(store (sube (load addr:$dst), GR64:$src2), addr:$dst)]>;
694 def SBB64mi8 : RIi8<0x83, MRM3m, (outs), (ins i64mem:$dst, i64i8imm :$src2),
695 "sbb{q}\t{$src2, $dst|$dst, $src2}",
696 [(store (sube (load addr:$dst), i64immSExt8:$src2), addr:$dst)]>;
697 def SBB64mi32 : RIi32<0x81, MRM3m, (outs), (ins i64mem:$dst, i64i32imm:$src2),
698 "sbb{q}\t{$src2, $dst|$dst, $src2}",
699 [(store (sube (load addr:$dst), i64immSExt32:$src2), addr:$dst)]>;
703 // Unsigned multiplication
704 let Defs = [RAX,RDX,EFLAGS], Uses = [RAX], neverHasSideEffects = 1 in {
705 def MUL64r : RI<0xF7, MRM4r, (outs), (ins GR64:$src),
706 "mul{q}\t$src", []>; // RAX,RDX = RAX*GR64
708 def MUL64m : RI<0xF7, MRM4m, (outs), (ins i64mem:$src),
709 "mul{q}\t$src", []>; // RAX,RDX = RAX*[mem64]
711 // Signed multiplication
712 def IMUL64r : RI<0xF7, MRM5r, (outs), (ins GR64:$src),
713 "imul{q}\t$src", []>; // RAX,RDX = RAX*GR64
715 def IMUL64m : RI<0xF7, MRM5m, (outs), (ins i64mem:$src),
716 "imul{q}\t$src", []>; // RAX,RDX = RAX*[mem64]
719 let Defs = [EFLAGS] in {
720 let isTwoAddress = 1 in {
721 let isCommutable = 1 in
722 // Register-Register Signed Integer Multiplication
723 def IMUL64rr : RI<0xAF, MRMSrcReg, (outs GR64:$dst),
724 (ins GR64:$src1, GR64:$src2),
725 "imul{q}\t{$src2, $dst|$dst, $src2}",
726 [(set GR64:$dst, EFLAGS,
727 (X86smul_flag GR64:$src1, GR64:$src2))]>, TB;
729 // Register-Memory Signed Integer Multiplication
730 def IMUL64rm : RI<0xAF, MRMSrcMem, (outs GR64:$dst),
731 (ins GR64:$src1, i64mem:$src2),
732 "imul{q}\t{$src2, $dst|$dst, $src2}",
733 [(set GR64:$dst, EFLAGS,
734 (X86smul_flag GR64:$src1, (load addr:$src2)))]>, TB;
737 // Suprisingly enough, these are not two address instructions!
739 // Register-Integer Signed Integer Multiplication
740 def IMUL64rri8 : RIi8<0x6B, MRMSrcReg, // GR64 = GR64*I8
741 (outs GR64:$dst), (ins GR64:$src1, i64i8imm:$src2),
742 "imul{q}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
743 [(set GR64:$dst, EFLAGS,
744 (X86smul_flag GR64:$src1, i64immSExt8:$src2))]>;
745 def IMUL64rri32 : RIi32<0x69, MRMSrcReg, // GR64 = GR64*I32
746 (outs GR64:$dst), (ins GR64:$src1, i64i32imm:$src2),
747 "imul{q}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
748 [(set GR64:$dst, EFLAGS,
749 (X86smul_flag GR64:$src1, i64immSExt32:$src2))]>;
751 // Memory-Integer Signed Integer Multiplication
752 def IMUL64rmi8 : RIi8<0x6B, MRMSrcMem, // GR64 = [mem64]*I8
753 (outs GR64:$dst), (ins i64mem:$src1, i64i8imm: $src2),
754 "imul{q}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
755 [(set GR64:$dst, EFLAGS,
756 (X86smul_flag (load addr:$src1),
757 i64immSExt8:$src2))]>;
758 def IMUL64rmi32 : RIi32<0x69, MRMSrcMem, // GR64 = [mem64]*I32
759 (outs GR64:$dst), (ins i64mem:$src1, i64i32imm:$src2),
760 "imul{q}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
761 [(set GR64:$dst, EFLAGS,
762 (X86smul_flag (load addr:$src1),
763 i64immSExt32:$src2))]>;
766 // Unsigned division / remainder
767 let Defs = [RAX,RDX,EFLAGS], Uses = [RAX,RDX] in {
768 // RDX:RAX/r64 = RAX,RDX
769 def DIV64r : RI<0xF7, MRM6r, (outs), (ins GR64:$src),
771 // Signed division / remainder
772 // RDX:RAX/r64 = RAX,RDX
773 def IDIV64r: RI<0xF7, MRM7r, (outs), (ins GR64:$src),
774 "idiv{q}\t$src", []>;
776 // RDX:RAX/[mem64] = RAX,RDX
777 def DIV64m : RI<0xF7, MRM6m, (outs), (ins i64mem:$src),
779 // RDX:RAX/[mem64] = RAX,RDX
780 def IDIV64m: RI<0xF7, MRM7m, (outs), (ins i64mem:$src),
781 "idiv{q}\t$src", []>;
785 // Unary instructions
786 let Defs = [EFLAGS], CodeSize = 2 in {
787 let isTwoAddress = 1 in
788 def NEG64r : RI<0xF7, MRM3r, (outs GR64:$dst), (ins GR64:$src), "neg{q}\t$dst",
789 [(set GR64:$dst, (ineg GR64:$src)),
791 def NEG64m : RI<0xF7, MRM3m, (outs), (ins i64mem:$dst), "neg{q}\t$dst",
792 [(store (ineg (loadi64 addr:$dst)), addr:$dst),
795 let isTwoAddress = 1, isConvertibleToThreeAddress = 1 in
796 def INC64r : RI<0xFF, MRM0r, (outs GR64:$dst), (ins GR64:$src), "inc{q}\t$dst",
797 [(set GR64:$dst, EFLAGS, (X86inc_flag GR64:$src))]>;
798 def INC64m : RI<0xFF, MRM0m, (outs), (ins i64mem:$dst), "inc{q}\t$dst",
799 [(store (add (loadi64 addr:$dst), 1), addr:$dst),
802 let isTwoAddress = 1, isConvertibleToThreeAddress = 1 in
803 def DEC64r : RI<0xFF, MRM1r, (outs GR64:$dst), (ins GR64:$src), "dec{q}\t$dst",
804 [(set GR64:$dst, EFLAGS, (X86dec_flag GR64:$src))]>;
805 def DEC64m : RI<0xFF, MRM1m, (outs), (ins i64mem:$dst), "dec{q}\t$dst",
806 [(store (add (loadi64 addr:$dst), -1), addr:$dst),
809 // In 64-bit mode, single byte INC and DEC cannot be encoded.
810 let isTwoAddress = 1, isConvertibleToThreeAddress = 1 in {
811 // Can transform into LEA.
812 def INC64_16r : I<0xFF, MRM0r, (outs GR16:$dst), (ins GR16:$src),
814 [(set GR16:$dst, EFLAGS, (X86inc_flag GR16:$src))]>,
815 OpSize, Requires<[In64BitMode]>;
816 def INC64_32r : I<0xFF, MRM0r, (outs GR32:$dst), (ins GR32:$src),
818 [(set GR32:$dst, EFLAGS, (X86inc_flag GR32:$src))]>,
819 Requires<[In64BitMode]>;
820 def DEC64_16r : I<0xFF, MRM1r, (outs GR16:$dst), (ins GR16:$src),
822 [(set GR16:$dst, EFLAGS, (X86dec_flag GR16:$src))]>,
823 OpSize, Requires<[In64BitMode]>;
824 def DEC64_32r : I<0xFF, MRM1r, (outs GR32:$dst), (ins GR32:$src),
826 [(set GR32:$dst, EFLAGS, (X86dec_flag GR32:$src))]>,
827 Requires<[In64BitMode]>;
828 } // isConvertibleToThreeAddress
830 // These are duplicates of their 32-bit counterparts. Only needed so X86 knows
831 // how to unfold them.
832 let isTwoAddress = 0, CodeSize = 2 in {
833 def INC64_16m : I<0xFF, MRM0m, (outs), (ins i16mem:$dst), "inc{w}\t$dst",
834 [(store (add (loadi16 addr:$dst), 1), addr:$dst),
836 OpSize, Requires<[In64BitMode]>;
837 def INC64_32m : I<0xFF, MRM0m, (outs), (ins i32mem:$dst), "inc{l}\t$dst",
838 [(store (add (loadi32 addr:$dst), 1), addr:$dst),
840 Requires<[In64BitMode]>;
841 def DEC64_16m : I<0xFF, MRM1m, (outs), (ins i16mem:$dst), "dec{w}\t$dst",
842 [(store (add (loadi16 addr:$dst), -1), addr:$dst),
844 OpSize, Requires<[In64BitMode]>;
845 def DEC64_32m : I<0xFF, MRM1m, (outs), (ins i32mem:$dst), "dec{l}\t$dst",
846 [(store (add (loadi32 addr:$dst), -1), addr:$dst),
848 Requires<[In64BitMode]>;
850 } // Defs = [EFLAGS], CodeSize
853 let Defs = [EFLAGS] in {
854 // Shift instructions
855 let isTwoAddress = 1 in {
857 def SHL64rCL : RI<0xD3, MRM4r, (outs GR64:$dst), (ins GR64:$src),
858 "shl{q}\t{%cl, $dst|$dst, %CL}",
859 [(set GR64:$dst, (shl GR64:$src, CL))]>;
860 let isConvertibleToThreeAddress = 1 in // Can transform into LEA.
861 def SHL64ri : RIi8<0xC1, MRM4r, (outs GR64:$dst),
862 (ins GR64:$src1, i8imm:$src2),
863 "shl{q}\t{$src2, $dst|$dst, $src2}",
864 [(set GR64:$dst, (shl GR64:$src1, (i8 imm:$src2)))]>;
865 // NOTE: We don't include patterns for shifts of a register by one, because
866 // 'add reg,reg' is cheaper.
867 def SHL64r1 : RI<0xD1, MRM4r, (outs GR64:$dst), (ins GR64:$src1),
872 def SHL64mCL : RI<0xD3, MRM4m, (outs), (ins i64mem:$dst),
873 "shl{q}\t{%cl, $dst|$dst, %CL}",
874 [(store (shl (loadi64 addr:$dst), CL), addr:$dst)]>;
875 def SHL64mi : RIi8<0xC1, MRM4m, (outs), (ins i64mem:$dst, i8imm:$src),
876 "shl{q}\t{$src, $dst|$dst, $src}",
877 [(store (shl (loadi64 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
878 def SHL64m1 : RI<0xD1, MRM4m, (outs), (ins i64mem:$dst),
880 [(store (shl (loadi64 addr:$dst), (i8 1)), addr:$dst)]>;
882 let isTwoAddress = 1 in {
884 def SHR64rCL : RI<0xD3, MRM5r, (outs GR64:$dst), (ins GR64:$src),
885 "shr{q}\t{%cl, $dst|$dst, %CL}",
886 [(set GR64:$dst, (srl GR64:$src, CL))]>;
887 def SHR64ri : RIi8<0xC1, MRM5r, (outs GR64:$dst), (ins GR64:$src1, i8imm:$src2),
888 "shr{q}\t{$src2, $dst|$dst, $src2}",
889 [(set GR64:$dst, (srl GR64:$src1, (i8 imm:$src2)))]>;
890 def SHR64r1 : RI<0xD1, MRM5r, (outs GR64:$dst), (ins GR64:$src1),
892 [(set GR64:$dst, (srl GR64:$src1, (i8 1)))]>;
896 def SHR64mCL : RI<0xD3, MRM5m, (outs), (ins i64mem:$dst),
897 "shr{q}\t{%cl, $dst|$dst, %CL}",
898 [(store (srl (loadi64 addr:$dst), CL), addr:$dst)]>;
899 def SHR64mi : RIi8<0xC1, MRM5m, (outs), (ins i64mem:$dst, i8imm:$src),
900 "shr{q}\t{$src, $dst|$dst, $src}",
901 [(store (srl (loadi64 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
902 def SHR64m1 : RI<0xD1, MRM5m, (outs), (ins i64mem:$dst),
904 [(store (srl (loadi64 addr:$dst), (i8 1)), addr:$dst)]>;
906 let isTwoAddress = 1 in {
908 def SAR64rCL : RI<0xD3, MRM7r, (outs GR64:$dst), (ins GR64:$src),
909 "sar{q}\t{%cl, $dst|$dst, %CL}",
910 [(set GR64:$dst, (sra GR64:$src, CL))]>;
911 def SAR64ri : RIi8<0xC1, MRM7r, (outs GR64:$dst),
912 (ins GR64:$src1, i8imm:$src2),
913 "sar{q}\t{$src2, $dst|$dst, $src2}",
914 [(set GR64:$dst, (sra GR64:$src1, (i8 imm:$src2)))]>;
915 def SAR64r1 : RI<0xD1, MRM7r, (outs GR64:$dst), (ins GR64:$src1),
917 [(set GR64:$dst, (sra GR64:$src1, (i8 1)))]>;
921 def SAR64mCL : RI<0xD3, MRM7m, (outs), (ins i64mem:$dst),
922 "sar{q}\t{%cl, $dst|$dst, %CL}",
923 [(store (sra (loadi64 addr:$dst), CL), addr:$dst)]>;
924 def SAR64mi : RIi8<0xC1, MRM7m, (outs), (ins i64mem:$dst, i8imm:$src),
925 "sar{q}\t{$src, $dst|$dst, $src}",
926 [(store (sra (loadi64 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
927 def SAR64m1 : RI<0xD1, MRM7m, (outs), (ins i64mem:$dst),
929 [(store (sra (loadi64 addr:$dst), (i8 1)), addr:$dst)]>;
931 // Rotate instructions
933 let isTwoAddress = 1 in {
934 def RCL64r1 : RI<0xD1, MRM2r, (outs GR64:$dst), (ins GR64:$src),
935 "rcl{q}\t{1, $dst|$dst, 1}", []>;
936 def RCL64ri : RIi8<0xC1, MRM2r, (outs GR64:$dst), (ins GR64:$src, i8imm:$cnt),
937 "rcl{q}\t{$cnt, $dst|$dst, $cnt}", []>;
939 def RCR64r1 : RI<0xD1, MRM3r, (outs GR64:$dst), (ins GR64:$src),
940 "rcr{q}\t{1, $dst|$dst, 1}", []>;
941 def RCR64ri : RIi8<0xC1, MRM3r, (outs GR64:$dst), (ins GR64:$src, i8imm:$cnt),
942 "rcr{q}\t{$cnt, $dst|$dst, $cnt}", []>;
945 def RCL64rCL : RI<0xD3, MRM2r, (outs GR64:$dst), (ins GR64:$src),
946 "rcl{q}\t{%cl, $dst|$dst, CL}", []>;
947 def RCR64rCL : RI<0xD3, MRM3r, (outs GR64:$dst), (ins GR64:$src),
948 "rcr{q}\t{%cl, $dst|$dst, CL}", []>;
952 let isTwoAddress = 0 in {
953 def RCL64m1 : RI<0xD1, MRM2m, (outs), (ins i64mem:$dst),
954 "rcl{q}\t{1, $dst|$dst, 1}", []>;
955 def RCL64mi : RIi8<0xC1, MRM2m, (outs), (ins i64mem:$dst, i8imm:$cnt),
956 "rcl{q}\t{$cnt, $dst|$dst, $cnt}", []>;
957 def RCR64m1 : RI<0xD1, MRM3m, (outs), (ins i64mem:$dst),
958 "rcr{q}\t{1, $dst|$dst, 1}", []>;
959 def RCR64mi : RIi8<0xC1, MRM3m, (outs), (ins i64mem:$dst, i8imm:$cnt),
960 "rcr{q}\t{$cnt, $dst|$dst, $cnt}", []>;
963 def RCL64mCL : RI<0xD3, MRM2m, (outs), (ins i64mem:$dst),
964 "rcl{q}\t{%cl, $dst|$dst, CL}", []>;
965 def RCR64mCL : RI<0xD3, MRM3m, (outs), (ins i64mem:$dst),
966 "rcr{q}\t{%cl, $dst|$dst, CL}", []>;
970 let isTwoAddress = 1 in {
972 def ROL64rCL : RI<0xD3, MRM0r, (outs GR64:$dst), (ins GR64:$src),
973 "rol{q}\t{%cl, $dst|$dst, %CL}",
974 [(set GR64:$dst, (rotl GR64:$src, CL))]>;
975 def ROL64ri : RIi8<0xC1, MRM0r, (outs GR64:$dst),
976 (ins GR64:$src1, i8imm:$src2),
977 "rol{q}\t{$src2, $dst|$dst, $src2}",
978 [(set GR64:$dst, (rotl GR64:$src1, (i8 imm:$src2)))]>;
979 def ROL64r1 : RI<0xD1, MRM0r, (outs GR64:$dst), (ins GR64:$src1),
981 [(set GR64:$dst, (rotl GR64:$src1, (i8 1)))]>;
985 def ROL64mCL : RI<0xD3, MRM0m, (outs), (ins i64mem:$dst),
986 "rol{q}\t{%cl, $dst|$dst, %CL}",
987 [(store (rotl (loadi64 addr:$dst), CL), addr:$dst)]>;
988 def ROL64mi : RIi8<0xC1, MRM0m, (outs), (ins i64mem:$dst, i8imm:$src),
989 "rol{q}\t{$src, $dst|$dst, $src}",
990 [(store (rotl (loadi64 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
991 def ROL64m1 : RI<0xD1, MRM0m, (outs), (ins i64mem:$dst),
993 [(store (rotl (loadi64 addr:$dst), (i8 1)), addr:$dst)]>;
995 let isTwoAddress = 1 in {
997 def ROR64rCL : RI<0xD3, MRM1r, (outs GR64:$dst), (ins GR64:$src),
998 "ror{q}\t{%cl, $dst|$dst, %CL}",
999 [(set GR64:$dst, (rotr GR64:$src, CL))]>;
1000 def ROR64ri : RIi8<0xC1, MRM1r, (outs GR64:$dst),
1001 (ins GR64:$src1, i8imm:$src2),
1002 "ror{q}\t{$src2, $dst|$dst, $src2}",
1003 [(set GR64:$dst, (rotr GR64:$src1, (i8 imm:$src2)))]>;
1004 def ROR64r1 : RI<0xD1, MRM1r, (outs GR64:$dst), (ins GR64:$src1),
1006 [(set GR64:$dst, (rotr GR64:$src1, (i8 1)))]>;
1010 def ROR64mCL : RI<0xD3, MRM1m, (outs), (ins i64mem:$dst),
1011 "ror{q}\t{%cl, $dst|$dst, %CL}",
1012 [(store (rotr (loadi64 addr:$dst), CL), addr:$dst)]>;
1013 def ROR64mi : RIi8<0xC1, MRM1m, (outs), (ins i64mem:$dst, i8imm:$src),
1014 "ror{q}\t{$src, $dst|$dst, $src}",
1015 [(store (rotr (loadi64 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
1016 def ROR64m1 : RI<0xD1, MRM1m, (outs), (ins i64mem:$dst),
1018 [(store (rotr (loadi64 addr:$dst), (i8 1)), addr:$dst)]>;
1020 // Double shift instructions (generalizations of rotate)
1021 let isTwoAddress = 1 in {
1022 let Uses = [CL] in {
1023 def SHLD64rrCL : RI<0xA5, MRMDestReg, (outs GR64:$dst),
1024 (ins GR64:$src1, GR64:$src2),
1025 "shld{q}\t{%cl, $src2, $dst|$dst, $src2, %CL}",
1026 [(set GR64:$dst, (X86shld GR64:$src1, GR64:$src2, CL))]>,
1028 def SHRD64rrCL : RI<0xAD, MRMDestReg, (outs GR64:$dst),
1029 (ins GR64:$src1, GR64:$src2),
1030 "shrd{q}\t{%cl, $src2, $dst|$dst, $src2, %CL}",
1031 [(set GR64:$dst, (X86shrd GR64:$src1, GR64:$src2, CL))]>,
1035 let isCommutable = 1 in { // FIXME: Update X86InstrInfo::commuteInstruction
1036 def SHLD64rri8 : RIi8<0xA4, MRMDestReg,
1038 (ins GR64:$src1, GR64:$src2, i8imm:$src3),
1039 "shld{q}\t{$src3, $src2, $dst|$dst, $src2, $src3}",
1040 [(set GR64:$dst, (X86shld GR64:$src1, GR64:$src2,
1043 def SHRD64rri8 : RIi8<0xAC, MRMDestReg,
1045 (ins GR64:$src1, GR64:$src2, i8imm:$src3),
1046 "shrd{q}\t{$src3, $src2, $dst|$dst, $src2, $src3}",
1047 [(set GR64:$dst, (X86shrd GR64:$src1, GR64:$src2,
1053 let Uses = [CL] in {
1054 def SHLD64mrCL : RI<0xA5, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src2),
1055 "shld{q}\t{%cl, $src2, $dst|$dst, $src2, %CL}",
1056 [(store (X86shld (loadi64 addr:$dst), GR64:$src2, CL),
1058 def SHRD64mrCL : RI<0xAD, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src2),
1059 "shrd{q}\t{%cl, $src2, $dst|$dst, $src2, %CL}",
1060 [(store (X86shrd (loadi64 addr:$dst), GR64:$src2, CL),
1063 def SHLD64mri8 : RIi8<0xA4, MRMDestMem,
1064 (outs), (ins i64mem:$dst, GR64:$src2, i8imm:$src3),
1065 "shld{q}\t{$src3, $src2, $dst|$dst, $src2, $src3}",
1066 [(store (X86shld (loadi64 addr:$dst), GR64:$src2,
1067 (i8 imm:$src3)), addr:$dst)]>,
1069 def SHRD64mri8 : RIi8<0xAC, MRMDestMem,
1070 (outs), (ins i64mem:$dst, GR64:$src2, i8imm:$src3),
1071 "shrd{q}\t{$src3, $src2, $dst|$dst, $src2, $src3}",
1072 [(store (X86shrd (loadi64 addr:$dst), GR64:$src2,
1073 (i8 imm:$src3)), addr:$dst)]>,
1075 } // Defs = [EFLAGS]
1077 //===----------------------------------------------------------------------===//
1078 // Logical Instructions...
1081 let isTwoAddress = 1 , AddedComplexity = 15 in
1082 def NOT64r : RI<0xF7, MRM2r, (outs GR64:$dst), (ins GR64:$src), "not{q}\t$dst",
1083 [(set GR64:$dst, (not GR64:$src))]>;
1084 def NOT64m : RI<0xF7, MRM2m, (outs), (ins i64mem:$dst), "not{q}\t$dst",
1085 [(store (not (loadi64 addr:$dst)), addr:$dst)]>;
1087 let Defs = [EFLAGS] in {
1088 def AND64i32 : RIi32<0x25, RawFrm, (outs), (ins i32imm:$src),
1089 "and{q}\t{$src, %rax|%rax, $src}", []>;
1091 let isTwoAddress = 1 in {
1092 let isCommutable = 1 in
1093 def AND64rr : RI<0x21, MRMDestReg,
1094 (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
1095 "and{q}\t{$src2, $dst|$dst, $src2}",
1096 [(set GR64:$dst, EFLAGS,
1097 (X86and_flag GR64:$src1, GR64:$src2))]>;
1098 def AND64rr_REV : RI<0x23, MRMSrcReg, (outs GR64:$dst),
1099 (ins GR64:$src1, GR64:$src2),
1100 "and{q}\t{$src2, $dst|$dst, $src2}", []>;
1101 def AND64rm : RI<0x23, MRMSrcMem,
1102 (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
1103 "and{q}\t{$src2, $dst|$dst, $src2}",
1104 [(set GR64:$dst, EFLAGS,
1105 (X86and_flag GR64:$src1, (load addr:$src2)))]>;
1106 def AND64ri8 : RIi8<0x83, MRM4r,
1107 (outs GR64:$dst), (ins GR64:$src1, i64i8imm:$src2),
1108 "and{q}\t{$src2, $dst|$dst, $src2}",
1109 [(set GR64:$dst, EFLAGS,
1110 (X86and_flag GR64:$src1, i64immSExt8:$src2))]>;
1111 def AND64ri32 : RIi32<0x81, MRM4r,
1112 (outs GR64:$dst), (ins GR64:$src1, i64i32imm:$src2),
1113 "and{q}\t{$src2, $dst|$dst, $src2}",
1114 [(set GR64:$dst, EFLAGS,
1115 (X86and_flag GR64:$src1, i64immSExt32:$src2))]>;
1118 def AND64mr : RI<0x21, MRMDestMem,
1119 (outs), (ins i64mem:$dst, GR64:$src),
1120 "and{q}\t{$src, $dst|$dst, $src}",
1121 [(store (and (load addr:$dst), GR64:$src), addr:$dst),
1122 (implicit EFLAGS)]>;
1123 def AND64mi8 : RIi8<0x83, MRM4m,
1124 (outs), (ins i64mem:$dst, i64i8imm :$src),
1125 "and{q}\t{$src, $dst|$dst, $src}",
1126 [(store (and (load addr:$dst), i64immSExt8:$src), addr:$dst),
1127 (implicit EFLAGS)]>;
1128 def AND64mi32 : RIi32<0x81, MRM4m,
1129 (outs), (ins i64mem:$dst, i64i32imm:$src),
1130 "and{q}\t{$src, $dst|$dst, $src}",
1131 [(store (and (loadi64 addr:$dst), i64immSExt32:$src), addr:$dst),
1132 (implicit EFLAGS)]>;
1134 let isTwoAddress = 1 in {
1135 let isCommutable = 1 in
1136 def OR64rr : RI<0x09, MRMDestReg, (outs GR64:$dst),
1137 (ins GR64:$src1, GR64:$src2),
1138 "or{q}\t{$src2, $dst|$dst, $src2}",
1139 [(set GR64:$dst, EFLAGS,
1140 (X86or_flag GR64:$src1, GR64:$src2))]>;
1141 def OR64rr_REV : RI<0x0B, MRMSrcReg, (outs GR64:$dst),
1142 (ins GR64:$src1, GR64:$src2),
1143 "or{q}\t{$src2, $dst|$dst, $src2}", []>;
1144 def OR64rm : RI<0x0B, MRMSrcMem , (outs GR64:$dst),
1145 (ins GR64:$src1, i64mem:$src2),
1146 "or{q}\t{$src2, $dst|$dst, $src2}",
1147 [(set GR64:$dst, EFLAGS,
1148 (X86or_flag GR64:$src1, (load addr:$src2)))]>;
1149 def OR64ri8 : RIi8<0x83, MRM1r, (outs GR64:$dst),
1150 (ins GR64:$src1, i64i8imm:$src2),
1151 "or{q}\t{$src2, $dst|$dst, $src2}",
1152 [(set GR64:$dst, EFLAGS,
1153 (X86or_flag GR64:$src1, i64immSExt8:$src2))]>;
1154 def OR64ri32 : RIi32<0x81, MRM1r, (outs GR64:$dst),
1155 (ins GR64:$src1, i64i32imm:$src2),
1156 "or{q}\t{$src2, $dst|$dst, $src2}",
1157 [(set GR64:$dst, EFLAGS,
1158 (X86or_flag GR64:$src1, i64immSExt32:$src2))]>;
1161 def OR64mr : RI<0x09, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
1162 "or{q}\t{$src, $dst|$dst, $src}",
1163 [(store (or (load addr:$dst), GR64:$src), addr:$dst),
1164 (implicit EFLAGS)]>;
1165 def OR64mi8 : RIi8<0x83, MRM1m, (outs), (ins i64mem:$dst, i64i8imm:$src),
1166 "or{q}\t{$src, $dst|$dst, $src}",
1167 [(store (or (load addr:$dst), i64immSExt8:$src), addr:$dst),
1168 (implicit EFLAGS)]>;
1169 def OR64mi32 : RIi32<0x81, MRM1m, (outs), (ins i64mem:$dst, i64i32imm:$src),
1170 "or{q}\t{$src, $dst|$dst, $src}",
1171 [(store (or (loadi64 addr:$dst), i64immSExt32:$src), addr:$dst),
1172 (implicit EFLAGS)]>;
1174 def OR64i32 : RIi32<0x0D, RawFrm, (outs), (ins i32imm:$src),
1175 "or{q}\t{$src, %rax|%rax, $src}", []>;
1177 let isTwoAddress = 1 in {
1178 let isCommutable = 1 in
1179 def XOR64rr : RI<0x31, MRMDestReg, (outs GR64:$dst),
1180 (ins GR64:$src1, GR64:$src2),
1181 "xor{q}\t{$src2, $dst|$dst, $src2}",
1182 [(set GR64:$dst, EFLAGS,
1183 (X86xor_flag GR64:$src1, GR64:$src2))]>;
1184 def XOR64rr_REV : RI<0x33, MRMSrcReg, (outs GR64:$dst),
1185 (ins GR64:$src1, GR64:$src2),
1186 "xor{q}\t{$src2, $dst|$dst, $src2}", []>;
1187 def XOR64rm : RI<0x33, MRMSrcMem, (outs GR64:$dst),
1188 (ins GR64:$src1, i64mem:$src2),
1189 "xor{q}\t{$src2, $dst|$dst, $src2}",
1190 [(set GR64:$dst, EFLAGS,
1191 (X86xor_flag GR64:$src1, (load addr:$src2)))]>;
1192 def XOR64ri8 : RIi8<0x83, MRM6r, (outs GR64:$dst),
1193 (ins GR64:$src1, i64i8imm:$src2),
1194 "xor{q}\t{$src2, $dst|$dst, $src2}",
1195 [(set GR64:$dst, EFLAGS,
1196 (X86xor_flag GR64:$src1, i64immSExt8:$src2))]>;
1197 def XOR64ri32 : RIi32<0x81, MRM6r,
1198 (outs GR64:$dst), (ins GR64:$src1, i64i32imm:$src2),
1199 "xor{q}\t{$src2, $dst|$dst, $src2}",
1200 [(set GR64:$dst, EFLAGS,
1201 (X86xor_flag GR64:$src1, i64immSExt32:$src2))]>;
1204 def XOR64mr : RI<0x31, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
1205 "xor{q}\t{$src, $dst|$dst, $src}",
1206 [(store (xor (load addr:$dst), GR64:$src), addr:$dst),
1207 (implicit EFLAGS)]>;
1208 def XOR64mi8 : RIi8<0x83, MRM6m, (outs), (ins i64mem:$dst, i64i8imm :$src),
1209 "xor{q}\t{$src, $dst|$dst, $src}",
1210 [(store (xor (load addr:$dst), i64immSExt8:$src), addr:$dst),
1211 (implicit EFLAGS)]>;
1212 def XOR64mi32 : RIi32<0x81, MRM6m, (outs), (ins i64mem:$dst, i64i32imm:$src),
1213 "xor{q}\t{$src, $dst|$dst, $src}",
1214 [(store (xor (loadi64 addr:$dst), i64immSExt32:$src), addr:$dst),
1215 (implicit EFLAGS)]>;
1217 def XOR64i32 : RIi32<0x35, RawFrm, (outs), (ins i32imm:$src),
1218 "xor{q}\t{$src, %rax|%rax, $src}", []>;
1220 } // Defs = [EFLAGS]
1222 //===----------------------------------------------------------------------===//
1223 // Comparison Instructions...
1226 // Integer comparison
1227 let Defs = [EFLAGS] in {
1228 def TEST64i32 : RIi32<0xa9, RawFrm, (outs), (ins i32imm:$src),
1229 "test{q}\t{$src, %rax|%rax, $src}", []>;
1230 let isCommutable = 1 in
1231 def TEST64rr : RI<0x85, MRMSrcReg, (outs), (ins GR64:$src1, GR64:$src2),
1232 "test{q}\t{$src2, $src1|$src1, $src2}",
1233 [(set EFLAGS, (X86cmp (and GR64:$src1, GR64:$src2), 0))]>;
1234 def TEST64rm : RI<0x85, MRMSrcMem, (outs), (ins GR64:$src1, i64mem:$src2),
1235 "test{q}\t{$src2, $src1|$src1, $src2}",
1236 [(set EFLAGS, (X86cmp (and GR64:$src1, (loadi64 addr:$src2)),
1238 def TEST64ri32 : RIi32<0xF7, MRM0r, (outs),
1239 (ins GR64:$src1, i64i32imm:$src2),
1240 "test{q}\t{$src2, $src1|$src1, $src2}",
1241 [(set EFLAGS, (X86cmp (and GR64:$src1, i64immSExt32:$src2),
1243 def TEST64mi32 : RIi32<0xF7, MRM0m, (outs),
1244 (ins i64mem:$src1, i64i32imm:$src2),
1245 "test{q}\t{$src2, $src1|$src1, $src2}",
1246 [(set EFLAGS, (X86cmp (and (loadi64 addr:$src1),
1247 i64immSExt32:$src2), 0))]>;
1250 def CMP64i32 : RIi32<0x3D, RawFrm, (outs), (ins i32imm:$src),
1251 "cmp{q}\t{$src, %rax|%rax, $src}", []>;
1252 def CMP64rr : RI<0x39, MRMDestReg, (outs), (ins GR64:$src1, GR64:$src2),
1253 "cmp{q}\t{$src2, $src1|$src1, $src2}",
1254 [(set EFLAGS, (X86cmp GR64:$src1, GR64:$src2))]>;
1256 // These are alternate spellings for use by the disassembler, we mark them as
1257 // code gen only to ensure they aren't matched by the assembler.
1258 let isCodeGenOnly = 1 in {
1259 def CMP64mrmrr : RI<0x3B, MRMSrcReg, (outs), (ins GR64:$src1, GR64:$src2),
1260 "cmp{q}\t{$src2, $src1|$src1, $src2}", []>;
1263 def CMP64mr : RI<0x39, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2),
1264 "cmp{q}\t{$src2, $src1|$src1, $src2}",
1265 [(set EFLAGS, (X86cmp (loadi64 addr:$src1), GR64:$src2))]>;
1266 def CMP64rm : RI<0x3B, MRMSrcMem, (outs), (ins GR64:$src1, i64mem:$src2),
1267 "cmp{q}\t{$src2, $src1|$src1, $src2}",
1268 [(set EFLAGS, (X86cmp GR64:$src1, (loadi64 addr:$src2)))]>;
1269 def CMP64ri8 : RIi8<0x83, MRM7r, (outs), (ins GR64:$src1, i64i8imm:$src2),
1270 "cmp{q}\t{$src2, $src1|$src1, $src2}",
1271 [(set EFLAGS, (X86cmp GR64:$src1, i64immSExt8:$src2))]>;
1272 def CMP64ri32 : RIi32<0x81, MRM7r, (outs), (ins GR64:$src1, i64i32imm:$src2),
1273 "cmp{q}\t{$src2, $src1|$src1, $src2}",
1274 [(set EFLAGS, (X86cmp GR64:$src1, i64immSExt32:$src2))]>;
1275 def CMP64mi8 : RIi8<0x83, MRM7m, (outs), (ins i64mem:$src1, i64i8imm:$src2),
1276 "cmp{q}\t{$src2, $src1|$src1, $src2}",
1277 [(set EFLAGS, (X86cmp (loadi64 addr:$src1),
1278 i64immSExt8:$src2))]>;
1279 def CMP64mi32 : RIi32<0x81, MRM7m, (outs),
1280 (ins i64mem:$src1, i64i32imm:$src2),
1281 "cmp{q}\t{$src2, $src1|$src1, $src2}",
1282 [(set EFLAGS, (X86cmp (loadi64 addr:$src1),
1283 i64immSExt32:$src2))]>;
1284 } // Defs = [EFLAGS]
1287 // TODO: BTC, BTR, and BTS
1288 let Defs = [EFLAGS] in {
1289 def BT64rr : RI<0xA3, MRMDestReg, (outs), (ins GR64:$src1, GR64:$src2),
1290 "bt{q}\t{$src2, $src1|$src1, $src2}",
1291 [(set EFLAGS, (X86bt GR64:$src1, GR64:$src2))]>, TB;
1293 // Unlike with the register+register form, the memory+register form of the
1294 // bt instruction does not ignore the high bits of the index. From ISel's
1295 // perspective, this is pretty bizarre. Disable these instructions for now.
1296 def BT64mr : RI<0xA3, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2),
1297 "bt{q}\t{$src2, $src1|$src1, $src2}",
1298 // [(X86bt (loadi64 addr:$src1), GR64:$src2),
1299 // (implicit EFLAGS)]
1303 def BT64ri8 : Ii8<0xBA, MRM4r, (outs), (ins GR64:$src1, i64i8imm:$src2),
1304 "bt{q}\t{$src2, $src1|$src1, $src2}",
1305 [(set EFLAGS, (X86bt GR64:$src1, i64immSExt8:$src2))]>, TB;
1306 // Note that these instructions don't need FastBTMem because that
1307 // only applies when the other operand is in a register. When it's
1308 // an immediate, bt is still fast.
1309 def BT64mi8 : Ii8<0xBA, MRM4m, (outs), (ins i64mem:$src1, i64i8imm:$src2),
1310 "bt{q}\t{$src2, $src1|$src1, $src2}",
1311 [(set EFLAGS, (X86bt (loadi64 addr:$src1),
1312 i64immSExt8:$src2))]>, TB;
1314 def BTC64rr : RI<0xBB, MRMDestReg, (outs), (ins GR64:$src1, GR64:$src2),
1315 "btc{q}\t{$src2, $src1|$src1, $src2}", []>, TB;
1316 def BTC64mr : RI<0xBB, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2),
1317 "btc{q}\t{$src2, $src1|$src1, $src2}", []>, TB;
1318 def BTC64ri8 : RIi8<0xBA, MRM7r, (outs), (ins GR64:$src1, i64i8imm:$src2),
1319 "btc{q}\t{$src2, $src1|$src1, $src2}", []>, TB;
1320 def BTC64mi8 : RIi8<0xBA, MRM7m, (outs), (ins i64mem:$src1, i64i8imm:$src2),
1321 "btc{q}\t{$src2, $src1|$src1, $src2}", []>, TB;
1323 def BTR64rr : RI<0xB3, MRMDestReg, (outs), (ins GR64:$src1, GR64:$src2),
1324 "btr{q}\t{$src2, $src1|$src1, $src2}", []>, TB;
1325 def BTR64mr : RI<0xB3, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2),
1326 "btr{q}\t{$src2, $src1|$src1, $src2}", []>, TB;
1327 def BTR64ri8 : RIi8<0xBA, MRM6r, (outs), (ins GR64:$src1, i64i8imm:$src2),
1328 "btr{q}\t{$src2, $src1|$src1, $src2}", []>, TB;
1329 def BTR64mi8 : RIi8<0xBA, MRM6m, (outs), (ins i64mem:$src1, i64i8imm:$src2),
1330 "btr{q}\t{$src2, $src1|$src1, $src2}", []>, TB;
1332 def BTS64rr : RI<0xAB, MRMDestReg, (outs), (ins GR64:$src1, GR64:$src2),
1333 "bts{q}\t{$src2, $src1|$src1, $src2}", []>, TB;
1334 def BTS64mr : RI<0xAB, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2),
1335 "bts{q}\t{$src2, $src1|$src1, $src2}", []>, TB;
1336 def BTS64ri8 : RIi8<0xBA, MRM5r, (outs), (ins GR64:$src1, i64i8imm:$src2),
1337 "bts{q}\t{$src2, $src1|$src1, $src2}", []>, TB;
1338 def BTS64mi8 : RIi8<0xBA, MRM5m, (outs), (ins i64mem:$src1, i64i8imm:$src2),
1339 "bts{q}\t{$src2, $src1|$src1, $src2}", []>, TB;
1340 } // Defs = [EFLAGS]
1342 // Conditional moves
1343 let Uses = [EFLAGS], isTwoAddress = 1 in {
1344 let isCommutable = 1 in {
1345 def CMOVB64rr : RI<0x42, MRMSrcReg, // if <u, GR64 = GR64
1346 (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
1347 "cmovb{q}\t{$src2, $dst|$dst, $src2}",
1348 [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2,
1349 X86_COND_B, EFLAGS))]>, TB;
1350 def CMOVAE64rr: RI<0x43, MRMSrcReg, // if >=u, GR64 = GR64
1351 (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
1352 "cmovae{q}\t{$src2, $dst|$dst, $src2}",
1353 [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2,
1354 X86_COND_AE, EFLAGS))]>, TB;
1355 def CMOVE64rr : RI<0x44, MRMSrcReg, // if ==, GR64 = GR64
1356 (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
1357 "cmove{q}\t{$src2, $dst|$dst, $src2}",
1358 [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2,
1359 X86_COND_E, EFLAGS))]>, TB;
1360 def CMOVNE64rr: RI<0x45, MRMSrcReg, // if !=, GR64 = GR64
1361 (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
1362 "cmovne{q}\t{$src2, $dst|$dst, $src2}",
1363 [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2,
1364 X86_COND_NE, EFLAGS))]>, TB;
1365 def CMOVBE64rr: RI<0x46, MRMSrcReg, // if <=u, GR64 = GR64
1366 (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
1367 "cmovbe{q}\t{$src2, $dst|$dst, $src2}",
1368 [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2,
1369 X86_COND_BE, EFLAGS))]>, TB;
1370 def CMOVA64rr : RI<0x47, MRMSrcReg, // if >u, GR64 = GR64
1371 (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
1372 "cmova{q}\t{$src2, $dst|$dst, $src2}",
1373 [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2,
1374 X86_COND_A, EFLAGS))]>, TB;
1375 def CMOVL64rr : RI<0x4C, MRMSrcReg, // if <s, GR64 = GR64
1376 (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
1377 "cmovl{q}\t{$src2, $dst|$dst, $src2}",
1378 [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2,
1379 X86_COND_L, EFLAGS))]>, TB;
1380 def CMOVGE64rr: RI<0x4D, MRMSrcReg, // if >=s, GR64 = GR64
1381 (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
1382 "cmovge{q}\t{$src2, $dst|$dst, $src2}",
1383 [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2,
1384 X86_COND_GE, EFLAGS))]>, TB;
1385 def CMOVLE64rr: RI<0x4E, MRMSrcReg, // if <=s, GR64 = GR64
1386 (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
1387 "cmovle{q}\t{$src2, $dst|$dst, $src2}",
1388 [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2,
1389 X86_COND_LE, EFLAGS))]>, TB;
1390 def CMOVG64rr : RI<0x4F, MRMSrcReg, // if >s, GR64 = GR64
1391 (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
1392 "cmovg{q}\t{$src2, $dst|$dst, $src2}",
1393 [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2,
1394 X86_COND_G, EFLAGS))]>, TB;
1395 def CMOVS64rr : RI<0x48, MRMSrcReg, // if signed, GR64 = GR64
1396 (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
1397 "cmovs{q}\t{$src2, $dst|$dst, $src2}",
1398 [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2,
1399 X86_COND_S, EFLAGS))]>, TB;
1400 def CMOVNS64rr: RI<0x49, MRMSrcReg, // if !signed, GR64 = GR64
1401 (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
1402 "cmovns{q}\t{$src2, $dst|$dst, $src2}",
1403 [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2,
1404 X86_COND_NS, EFLAGS))]>, TB;
1405 def CMOVP64rr : RI<0x4A, MRMSrcReg, // if parity, GR64 = GR64
1406 (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
1407 "cmovp{q}\t{$src2, $dst|$dst, $src2}",
1408 [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2,
1409 X86_COND_P, EFLAGS))]>, TB;
1410 def CMOVNP64rr : RI<0x4B, MRMSrcReg, // if !parity, GR64 = GR64
1411 (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
1412 "cmovnp{q}\t{$src2, $dst|$dst, $src2}",
1413 [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2,
1414 X86_COND_NP, EFLAGS))]>, TB;
1415 def CMOVO64rr : RI<0x40, MRMSrcReg, // if overflow, GR64 = GR64
1416 (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
1417 "cmovo{q}\t{$src2, $dst|$dst, $src2}",
1418 [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2,
1419 X86_COND_O, EFLAGS))]>, TB;
1420 def CMOVNO64rr : RI<0x41, MRMSrcReg, // if !overflow, GR64 = GR64
1421 (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
1422 "cmovno{q}\t{$src2, $dst|$dst, $src2}",
1423 [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2,
1424 X86_COND_NO, EFLAGS))]>, TB;
1425 } // isCommutable = 1
1427 def CMOVB64rm : RI<0x42, MRMSrcMem, // if <u, GR64 = [mem64]
1428 (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
1429 "cmovb{q}\t{$src2, $dst|$dst, $src2}",
1430 [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
1431 X86_COND_B, EFLAGS))]>, TB;
1432 def CMOVAE64rm: RI<0x43, MRMSrcMem, // if >=u, GR64 = [mem64]
1433 (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
1434 "cmovae{q}\t{$src2, $dst|$dst, $src2}",
1435 [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
1436 X86_COND_AE, EFLAGS))]>, TB;
1437 def CMOVE64rm : RI<0x44, MRMSrcMem, // if ==, GR64 = [mem64]
1438 (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
1439 "cmove{q}\t{$src2, $dst|$dst, $src2}",
1440 [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
1441 X86_COND_E, EFLAGS))]>, TB;
1442 def CMOVNE64rm: RI<0x45, MRMSrcMem, // if !=, GR64 = [mem64]
1443 (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
1444 "cmovne{q}\t{$src2, $dst|$dst, $src2}",
1445 [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
1446 X86_COND_NE, EFLAGS))]>, TB;
1447 def CMOVBE64rm: RI<0x46, MRMSrcMem, // if <=u, GR64 = [mem64]
1448 (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
1449 "cmovbe{q}\t{$src2, $dst|$dst, $src2}",
1450 [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
1451 X86_COND_BE, EFLAGS))]>, TB;
1452 def CMOVA64rm : RI<0x47, MRMSrcMem, // if >u, GR64 = [mem64]
1453 (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
1454 "cmova{q}\t{$src2, $dst|$dst, $src2}",
1455 [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
1456 X86_COND_A, EFLAGS))]>, TB;
1457 def CMOVL64rm : RI<0x4C, MRMSrcMem, // if <s, GR64 = [mem64]
1458 (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
1459 "cmovl{q}\t{$src2, $dst|$dst, $src2}",
1460 [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
1461 X86_COND_L, EFLAGS))]>, TB;
1462 def CMOVGE64rm: RI<0x4D, MRMSrcMem, // if >=s, GR64 = [mem64]
1463 (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
1464 "cmovge{q}\t{$src2, $dst|$dst, $src2}",
1465 [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
1466 X86_COND_GE, EFLAGS))]>, TB;
1467 def CMOVLE64rm: RI<0x4E, MRMSrcMem, // if <=s, GR64 = [mem64]
1468 (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
1469 "cmovle{q}\t{$src2, $dst|$dst, $src2}",
1470 [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
1471 X86_COND_LE, EFLAGS))]>, TB;
1472 def CMOVG64rm : RI<0x4F, MRMSrcMem, // if >s, GR64 = [mem64]
1473 (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
1474 "cmovg{q}\t{$src2, $dst|$dst, $src2}",
1475 [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
1476 X86_COND_G, EFLAGS))]>, TB;
1477 def CMOVS64rm : RI<0x48, MRMSrcMem, // if signed, GR64 = [mem64]
1478 (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
1479 "cmovs{q}\t{$src2, $dst|$dst, $src2}",
1480 [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
1481 X86_COND_S, EFLAGS))]>, TB;
1482 def CMOVNS64rm: RI<0x49, MRMSrcMem, // if !signed, GR64 = [mem64]
1483 (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
1484 "cmovns{q}\t{$src2, $dst|$dst, $src2}",
1485 [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
1486 X86_COND_NS, EFLAGS))]>, TB;
1487 def CMOVP64rm : RI<0x4A, MRMSrcMem, // if parity, GR64 = [mem64]
1488 (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
1489 "cmovp{q}\t{$src2, $dst|$dst, $src2}",
1490 [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
1491 X86_COND_P, EFLAGS))]>, TB;
1492 def CMOVNP64rm : RI<0x4B, MRMSrcMem, // if !parity, GR64 = [mem64]
1493 (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
1494 "cmovnp{q}\t{$src2, $dst|$dst, $src2}",
1495 [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
1496 X86_COND_NP, EFLAGS))]>, TB;
1497 def CMOVO64rm : RI<0x40, MRMSrcMem, // if overflow, GR64 = [mem64]
1498 (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
1499 "cmovo{q}\t{$src2, $dst|$dst, $src2}",
1500 [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
1501 X86_COND_O, EFLAGS))]>, TB;
1502 def CMOVNO64rm : RI<0x41, MRMSrcMem, // if !overflow, GR64 = [mem64]
1503 (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
1504 "cmovno{q}\t{$src2, $dst|$dst, $src2}",
1505 [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
1506 X86_COND_NO, EFLAGS))]>, TB;
1509 // Use sbb to materialize carry flag into a GPR.
1510 // FIXME: This are pseudo ops that should be replaced with Pat<> patterns.
1511 // However, Pat<> can't replicate the destination reg into the inputs of the
1513 // FIXME: Change this to have encoding Pseudo when X86MCCodeEmitter replaces
1515 let Defs = [EFLAGS], Uses = [EFLAGS], isCodeGenOnly = 1 in
1516 def SETB_C64r : RI<0x19, MRMInitReg, (outs GR64:$dst), (ins), "",
1517 [(set GR64:$dst, (X86setcc_c X86_COND_B, EFLAGS))]>;
1519 def : Pat<(i64 (anyext (i8 (X86setcc_c X86_COND_B, EFLAGS)))),
1522 //===----------------------------------------------------------------------===//
1523 // Conversion Instructions...
1526 // f64 -> signed i64
1527 def CVTSD2SI64rr: RSDI<0x2D, MRMSrcReg, (outs GR64:$dst), (ins FR64:$src),
1528 "cvtsd2si{q}\t{$src, $dst|$dst, $src}", []>;
1529 def CVTSD2SI64rm: RSDI<0x2D, MRMSrcMem, (outs GR64:$dst), (ins f64mem:$src),
1530 "cvtsd2si{q}\t{$src, $dst|$dst, $src}", []>;
1531 def Int_CVTSD2SI64rr: RSDI<0x2D, MRMSrcReg, (outs GR64:$dst), (ins VR128:$src),
1532 "cvtsd2si{q}\t{$src, $dst|$dst, $src}",
1534 (int_x86_sse2_cvtsd2si64 VR128:$src))]>;
1535 def Int_CVTSD2SI64rm: RSDI<0x2D, MRMSrcMem, (outs GR64:$dst),
1537 "cvtsd2si{q}\t{$src, $dst|$dst, $src}",
1538 [(set GR64:$dst, (int_x86_sse2_cvtsd2si64
1539 (load addr:$src)))]>;
1540 def CVTTSD2SI64rr: RSDI<0x2C, MRMSrcReg, (outs GR64:$dst), (ins FR64:$src),
1541 "cvttsd2si{q}\t{$src, $dst|$dst, $src}",
1542 [(set GR64:$dst, (fp_to_sint FR64:$src))]>;
1543 def CVTTSD2SI64rm: RSDI<0x2C, MRMSrcMem, (outs GR64:$dst), (ins f64mem:$src),
1544 "cvttsd2si{q}\t{$src, $dst|$dst, $src}",
1545 [(set GR64:$dst, (fp_to_sint (loadf64 addr:$src)))]>;
1546 def Int_CVTTSD2SI64rr: RSDI<0x2C, MRMSrcReg, (outs GR64:$dst), (ins VR128:$src),
1547 "cvttsd2si{q}\t{$src, $dst|$dst, $src}",
1549 (int_x86_sse2_cvttsd2si64 VR128:$src))]>;
1550 def Int_CVTTSD2SI64rm: RSDI<0x2C, MRMSrcMem, (outs GR64:$dst),
1552 "cvttsd2si{q}\t{$src, $dst|$dst, $src}",
1554 (int_x86_sse2_cvttsd2si64
1555 (load addr:$src)))]>;
1557 // Signed i64 -> f64
1558 def CVTSI2SD64rr: RSDI<0x2A, MRMSrcReg, (outs FR64:$dst), (ins GR64:$src),
1559 "cvtsi2sd{q}\t{$src, $dst|$dst, $src}",
1560 [(set FR64:$dst, (sint_to_fp GR64:$src))]>;
1561 def CVTSI2SD64rm: RSDI<0x2A, MRMSrcMem, (outs FR64:$dst), (ins i64mem:$src),
1562 "cvtsi2sd{q}\t{$src, $dst|$dst, $src}",
1563 [(set FR64:$dst, (sint_to_fp (loadi64 addr:$src)))]>;
1565 let isTwoAddress = 1 in {
1566 def Int_CVTSI2SD64rr: RSDI<0x2A, MRMSrcReg,
1567 (outs VR128:$dst), (ins VR128:$src1, GR64:$src2),
1568 "cvtsi2sd{q}\t{$src2, $dst|$dst, $src2}",
1570 (int_x86_sse2_cvtsi642sd VR128:$src1,
1572 def Int_CVTSI2SD64rm: RSDI<0x2A, MRMSrcMem,
1573 (outs VR128:$dst), (ins VR128:$src1, i64mem:$src2),
1574 "cvtsi2sd{q}\t{$src2, $dst|$dst, $src2}",
1576 (int_x86_sse2_cvtsi642sd VR128:$src1,
1577 (loadi64 addr:$src2)))]>;
1580 // Signed i64 -> f32
1581 def CVTSI2SS64rr: RSSI<0x2A, MRMSrcReg, (outs FR32:$dst), (ins GR64:$src),
1582 "cvtsi2ss{q}\t{$src, $dst|$dst, $src}",
1583 [(set FR32:$dst, (sint_to_fp GR64:$src))]>;
1584 def CVTSI2SS64rm: RSSI<0x2A, MRMSrcMem, (outs FR32:$dst), (ins i64mem:$src),
1585 "cvtsi2ss{q}\t{$src, $dst|$dst, $src}",
1586 [(set FR32:$dst, (sint_to_fp (loadi64 addr:$src)))]>;
1588 let isTwoAddress = 1 in {
1589 def Int_CVTSI2SS64rr : RSSI<0x2A, MRMSrcReg,
1590 (outs VR128:$dst), (ins VR128:$src1, GR64:$src2),
1591 "cvtsi2ss{q}\t{$src2, $dst|$dst, $src2}",
1593 (int_x86_sse_cvtsi642ss VR128:$src1,
1595 def Int_CVTSI2SS64rm : RSSI<0x2A, MRMSrcMem,
1597 (ins VR128:$src1, i64mem:$src2),
1598 "cvtsi2ss{q}\t{$src2, $dst|$dst, $src2}",
1600 (int_x86_sse_cvtsi642ss VR128:$src1,
1601 (loadi64 addr:$src2)))]>;
1604 // f32 -> signed i64
1605 def CVTSS2SI64rr: RSSI<0x2D, MRMSrcReg, (outs GR64:$dst), (ins FR32:$src),
1606 "cvtss2si{q}\t{$src, $dst|$dst, $src}", []>;
1607 def CVTSS2SI64rm: RSSI<0x2D, MRMSrcMem, (outs GR64:$dst), (ins f32mem:$src),
1608 "cvtss2si{q}\t{$src, $dst|$dst, $src}", []>;
1609 def Int_CVTSS2SI64rr: RSSI<0x2D, MRMSrcReg, (outs GR64:$dst), (ins VR128:$src),
1610 "cvtss2si{q}\t{$src, $dst|$dst, $src}",
1612 (int_x86_sse_cvtss2si64 VR128:$src))]>;
1613 def Int_CVTSS2SI64rm: RSSI<0x2D, MRMSrcMem, (outs GR64:$dst), (ins f32mem:$src),
1614 "cvtss2si{q}\t{$src, $dst|$dst, $src}",
1615 [(set GR64:$dst, (int_x86_sse_cvtss2si64
1616 (load addr:$src)))]>;
1617 def CVTTSS2SI64rr: RSSI<0x2C, MRMSrcReg, (outs GR64:$dst), (ins FR32:$src),
1618 "cvttss2si{q}\t{$src, $dst|$dst, $src}",
1619 [(set GR64:$dst, (fp_to_sint FR32:$src))]>;
1620 def CVTTSS2SI64rm: RSSI<0x2C, MRMSrcMem, (outs GR64:$dst), (ins f32mem:$src),
1621 "cvttss2si{q}\t{$src, $dst|$dst, $src}",
1622 [(set GR64:$dst, (fp_to_sint (loadf32 addr:$src)))]>;
1623 def Int_CVTTSS2SI64rr: RSSI<0x2C, MRMSrcReg, (outs GR64:$dst), (ins VR128:$src),
1624 "cvttss2si{q}\t{$src, $dst|$dst, $src}",
1626 (int_x86_sse_cvttss2si64 VR128:$src))]>;
1627 def Int_CVTTSS2SI64rm: RSSI<0x2C, MRMSrcMem, (outs GR64:$dst),
1629 "cvttss2si{q}\t{$src, $dst|$dst, $src}",
1631 (int_x86_sse_cvttss2si64 (load addr:$src)))]>;
1633 // Descriptor-table support instructions
1635 // LLDT is not interpreted specially in 64-bit mode because there is no sign
1637 def SLDT64r : RI<0x00, MRM0r, (outs GR64:$dst), (ins),
1638 "sldt{q}\t$dst", []>, TB;
1639 def SLDT64m : RI<0x00, MRM0m, (outs i16mem:$dst), (ins),
1640 "sldt{q}\t$dst", []>, TB;
1642 //===----------------------------------------------------------------------===//
1643 // Alias Instructions
1644 //===----------------------------------------------------------------------===//
1646 // We want to rewrite MOV64r0 in terms of MOV32r0, because it's sometimes a
1647 // smaller encoding, but doing so at isel time interferes with rematerialization
1648 // in the current register allocator. For now, this is rewritten when the
1649 // instruction is lowered to an MCInst.
1650 // FIXME: AddedComplexity gives this a higher priority than MOV64ri32. Remove
1651 // when we have a better way to specify isel priority.
1652 let Defs = [EFLAGS],
1653 AddedComplexity = 1, isReMaterializable = 1, isAsCheapAsAMove = 1 in
1654 def MOV64r0 : I<0x31, MRMInitReg, (outs GR64:$dst), (ins), "",
1655 [(set GR64:$dst, 0)]>;
1657 // Materialize i64 constant where top 32-bits are zero. This could theoretically
1658 // use MOV32ri with a SUBREG_TO_REG to represent the zero-extension, however
1659 // that would make it more difficult to rematerialize.
1660 let AddedComplexity = 1, isReMaterializable = 1, isAsCheapAsAMove = 1 in
1661 def MOV64ri64i32 : Ii32<0xB8, AddRegFrm, (outs GR64:$dst), (ins i64i32imm:$src),
1662 "", [(set GR64:$dst, i64immZExt32:$src)]>;
1664 //===----------------------------------------------------------------------===//
1665 // Thread Local Storage Instructions
1666 //===----------------------------------------------------------------------===//
1668 // All calls clobber the non-callee saved registers. RSP is marked as
1669 // a use to prevent stack-pointer assignments that appear immediately
1670 // before calls from potentially appearing dead.
1671 let Defs = [RAX, RCX, RDX, RSI, RDI, R8, R9, R10, R11,
1672 FP0, FP1, FP2, FP3, FP4, FP5, FP6, ST0, ST1,
1673 MM0, MM1, MM2, MM3, MM4, MM5, MM6, MM7,
1674 XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7,
1675 XMM8, XMM9, XMM10, XMM11, XMM12, XMM13, XMM14, XMM15, EFLAGS],
1677 def TLS_addr64 : I<0, Pseudo, (outs), (ins lea64mem:$sym),
1679 "leaq\t$sym(%rip), %rdi; "
1682 "call\t__tls_get_addr@PLT",
1683 [(X86tlsaddr tls64addr:$sym)]>,
1684 Requires<[In64BitMode]>;
1686 let AddedComplexity = 5, isCodeGenOnly = 1 in
1687 def MOV64GSrm : RI<0x8B, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
1688 "movq\t%gs:$src, $dst",
1689 [(set GR64:$dst, (gsload addr:$src))]>, SegGS;
1691 let AddedComplexity = 5, isCodeGenOnly = 1 in
1692 def MOV64FSrm : RI<0x8B, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
1693 "movq\t%fs:$src, $dst",
1694 [(set GR64:$dst, (fsload addr:$src))]>, SegFS;
1696 //===----------------------------------------------------------------------===//
1697 // Atomic Instructions
1698 //===----------------------------------------------------------------------===//
1700 let Defs = [RAX, EFLAGS], Uses = [RAX] in {
1701 def LCMPXCHG64 : RI<0xB1, MRMDestMem, (outs), (ins i64mem:$ptr, GR64:$swap),
1703 "cmpxchgq\t$swap,$ptr",
1704 [(X86cas addr:$ptr, GR64:$swap, 8)]>, TB, LOCK;
1707 let Constraints = "$val = $dst" in {
1708 let Defs = [EFLAGS] in
1709 def LXADD64 : RI<0xC1, MRMSrcMem, (outs GR64:$dst), (ins GR64:$val,i64mem:$ptr),
1712 [(set GR64:$dst, (atomic_load_add_64 addr:$ptr, GR64:$val))]>,
1715 def XCHG64rm : RI<0x87, MRMSrcMem, (outs GR64:$dst),
1716 (ins GR64:$val,i64mem:$ptr),
1717 "xchg{q}\t{$val, $ptr|$ptr, $val}",
1718 [(set GR64:$dst, (atomic_swap_64 addr:$ptr, GR64:$val))]>;
1720 def XCHG64rr : RI<0x87, MRMSrcReg, (outs GR64:$dst), (ins GR64:$val,GR64:$src),
1721 "xchg{q}\t{$val, $src|$src, $val}", []>;
1724 def XADD64rr : RI<0xC1, MRMDestReg, (outs GR64:$dst), (ins GR64:$src),
1725 "xadd{q}\t{$src, $dst|$dst, $src}", []>, TB;
1726 let mayLoad = 1, mayStore = 1 in
1727 def XADD64rm : RI<0xC1, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
1728 "xadd{q}\t{$src, $dst|$dst, $src}", []>, TB;
1730 def CMPXCHG64rr : RI<0xB1, MRMDestReg, (outs GR64:$dst), (ins GR64:$src),
1731 "cmpxchg{q}\t{$src, $dst|$dst, $src}", []>, TB;
1732 let mayLoad = 1, mayStore = 1 in
1733 def CMPXCHG64rm : RI<0xB1, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
1734 "cmpxchg{q}\t{$src, $dst|$dst, $src}", []>, TB;
1736 let Defs = [RAX, RDX, EFLAGS], Uses = [RAX, RBX, RCX, RDX] in
1737 def CMPXCHG16B : RI<0xC7, MRM1m, (outs), (ins i128mem:$dst),
1738 "cmpxchg16b\t$dst", []>, TB;
1740 def XCHG64ar : RI<0x90, AddRegFrm, (outs), (ins GR64:$src),
1741 "xchg{q}\t{$src, %rax|%rax, $src}", []>;
1743 // Optimized codegen when the non-memory output is not used.
1744 let Defs = [EFLAGS], mayLoad = 1, mayStore = 1 in {
1745 // FIXME: Use normal add / sub instructions and add lock prefix dynamically.
1746 def LOCK_ADD64mr : RI<0x03, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src2),
1748 "add{q}\t{$src2, $dst|$dst, $src2}", []>, LOCK;
1749 def LOCK_ADD64mi8 : RIi8<0x83, MRM0m, (outs),
1750 (ins i64mem:$dst, i64i8imm :$src2),
1752 "add{q}\t{$src2, $dst|$dst, $src2}", []>, LOCK;
1753 def LOCK_ADD64mi32 : RIi32<0x81, MRM0m, (outs),
1754 (ins i64mem:$dst, i64i32imm :$src2),
1756 "add{q}\t{$src2, $dst|$dst, $src2}", []>, LOCK;
1757 def LOCK_SUB64mr : RI<0x29, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src2),
1759 "sub{q}\t{$src2, $dst|$dst, $src2}", []>, LOCK;
1760 def LOCK_SUB64mi8 : RIi8<0x83, MRM5m, (outs),
1761 (ins i64mem:$dst, i64i8imm :$src2),
1763 "sub{q}\t{$src2, $dst|$dst, $src2}", []>, LOCK;
1764 def LOCK_SUB64mi32 : RIi32<0x81, MRM5m, (outs),
1765 (ins i64mem:$dst, i64i32imm:$src2),
1767 "sub{q}\t{$src2, $dst|$dst, $src2}", []>, LOCK;
1768 def LOCK_INC64m : RI<0xFF, MRM0m, (outs), (ins i64mem:$dst),
1770 "inc{q}\t$dst", []>, LOCK;
1771 def LOCK_DEC64m : RI<0xFF, MRM1m, (outs), (ins i64mem:$dst),
1773 "dec{q}\t$dst", []>, LOCK;
1775 // Atomic exchange, and, or, xor
1776 let Constraints = "$val = $dst", Defs = [EFLAGS],
1777 usesCustomInserter = 1 in {
1778 def ATOMAND64 : I<0, Pseudo, (outs GR64:$dst),(ins i64mem:$ptr, GR64:$val),
1779 "#ATOMAND64 PSEUDO!",
1780 [(set GR64:$dst, (atomic_load_and_64 addr:$ptr, GR64:$val))]>;
1781 def ATOMOR64 : I<0, Pseudo, (outs GR64:$dst),(ins i64mem:$ptr, GR64:$val),
1782 "#ATOMOR64 PSEUDO!",
1783 [(set GR64:$dst, (atomic_load_or_64 addr:$ptr, GR64:$val))]>;
1784 def ATOMXOR64 : I<0, Pseudo,(outs GR64:$dst),(ins i64mem:$ptr, GR64:$val),
1785 "#ATOMXOR64 PSEUDO!",
1786 [(set GR64:$dst, (atomic_load_xor_64 addr:$ptr, GR64:$val))]>;
1787 def ATOMNAND64 : I<0, Pseudo,(outs GR64:$dst),(ins i64mem:$ptr, GR64:$val),
1788 "#ATOMNAND64 PSEUDO!",
1789 [(set GR64:$dst, (atomic_load_nand_64 addr:$ptr, GR64:$val))]>;
1790 def ATOMMIN64: I<0, Pseudo, (outs GR64:$dst), (ins i64mem:$ptr, GR64:$val),
1791 "#ATOMMIN64 PSEUDO!",
1792 [(set GR64:$dst, (atomic_load_min_64 addr:$ptr, GR64:$val))]>;
1793 def ATOMMAX64: I<0, Pseudo, (outs GR64:$dst),(ins i64mem:$ptr, GR64:$val),
1794 "#ATOMMAX64 PSEUDO!",
1795 [(set GR64:$dst, (atomic_load_max_64 addr:$ptr, GR64:$val))]>;
1796 def ATOMUMIN64: I<0, Pseudo, (outs GR64:$dst),(ins i64mem:$ptr, GR64:$val),
1797 "#ATOMUMIN64 PSEUDO!",
1798 [(set GR64:$dst, (atomic_load_umin_64 addr:$ptr, GR64:$val))]>;
1799 def ATOMUMAX64: I<0, Pseudo, (outs GR64:$dst),(ins i64mem:$ptr, GR64:$val),
1800 "#ATOMUMAX64 PSEUDO!",
1801 [(set GR64:$dst, (atomic_load_umax_64 addr:$ptr, GR64:$val))]>;
1804 // Segmentation support instructions
1806 // i16mem operand in LAR64rm and GR32 operand in LAR32rr is not a typo.
1807 def LAR64rm : RI<0x02, MRMSrcMem, (outs GR64:$dst), (ins i16mem:$src),
1808 "lar{q}\t{$src, $dst|$dst, $src}", []>, TB;
1809 def LAR64rr : RI<0x02, MRMSrcReg, (outs GR64:$dst), (ins GR32:$src),
1810 "lar{q}\t{$src, $dst|$dst, $src}", []>, TB;
1812 def LSL64rm : RI<0x03, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
1813 "lsl{q}\t{$src, $dst|$dst, $src}", []>, TB;
1814 def LSL64rr : RI<0x03, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
1815 "lsl{q}\t{$src, $dst|$dst, $src}", []>, TB;
1817 def SWAPGS : I<0x01, MRM_F8, (outs), (ins), "swapgs", []>, TB;
1819 def PUSHFS64 : I<0xa0, RawFrm, (outs), (ins),
1820 "push{q}\t%fs", []>, TB;
1821 def PUSHGS64 : I<0xa8, RawFrm, (outs), (ins),
1822 "push{q}\t%gs", []>, TB;
1824 def POPFS64 : I<0xa1, RawFrm, (outs), (ins),
1825 "pop{q}\t%fs", []>, TB;
1826 def POPGS64 : I<0xa9, RawFrm, (outs), (ins),
1827 "pop{q}\t%gs", []>, TB;
1829 def LSS64rm : RI<0xb2, MRMSrcMem, (outs GR64:$dst), (ins opaque80mem:$src),
1830 "lss{q}\t{$src, $dst|$dst, $src}", []>, TB;
1831 def LFS64rm : RI<0xb4, MRMSrcMem, (outs GR64:$dst), (ins opaque80mem:$src),
1832 "lfs{q}\t{$src, $dst|$dst, $src}", []>, TB;
1833 def LGS64rm : RI<0xb5, MRMSrcMem, (outs GR64:$dst), (ins opaque80mem:$src),
1834 "lgs{q}\t{$src, $dst|$dst, $src}", []>, TB;
1836 // Specialized register support
1838 // no m form encodable; use SMSW16m
1839 def SMSW64r : RI<0x01, MRM4r, (outs GR64:$dst), (ins),
1840 "smsw{q}\t$dst", []>, TB;
1842 // String manipulation instructions
1844 def LODSQ : RI<0xAD, RawFrm, (outs), (ins), "lodsq", []>;
1846 //===----------------------------------------------------------------------===//
1847 // Non-Instruction Patterns
1848 //===----------------------------------------------------------------------===//
1850 // ConstantPool GlobalAddress, ExternalSymbol, and JumpTable when not in small
1851 // code model mode, should use 'movabs'. FIXME: This is really a hack, the
1852 // 'movabs' predicate should handle this sort of thing.
1853 def : Pat<(i64 (X86Wrapper tconstpool :$dst)),
1854 (MOV64ri tconstpool :$dst)>, Requires<[FarData]>;
1855 def : Pat<(i64 (X86Wrapper tjumptable :$dst)),
1856 (MOV64ri tjumptable :$dst)>, Requires<[FarData]>;
1857 def : Pat<(i64 (X86Wrapper tglobaladdr :$dst)),
1858 (MOV64ri tglobaladdr :$dst)>, Requires<[FarData]>;
1859 def : Pat<(i64 (X86Wrapper texternalsym:$dst)),
1860 (MOV64ri texternalsym:$dst)>, Requires<[FarData]>;
1861 def : Pat<(i64 (X86Wrapper tblockaddress:$dst)),
1862 (MOV64ri tblockaddress:$dst)>, Requires<[FarData]>;
1864 // In static codegen with small code model, we can get the address of a label
1865 // into a register with 'movl'. FIXME: This is a hack, the 'imm' predicate of
1866 // the MOV64ri64i32 should accept these.
1867 def : Pat<(i64 (X86Wrapper tconstpool :$dst)),
1868 (MOV64ri64i32 tconstpool :$dst)>, Requires<[SmallCode]>;
1869 def : Pat<(i64 (X86Wrapper tjumptable :$dst)),
1870 (MOV64ri64i32 tjumptable :$dst)>, Requires<[SmallCode]>;
1871 def : Pat<(i64 (X86Wrapper tglobaladdr :$dst)),
1872 (MOV64ri64i32 tglobaladdr :$dst)>, Requires<[SmallCode]>;
1873 def : Pat<(i64 (X86Wrapper texternalsym:$dst)),
1874 (MOV64ri64i32 texternalsym:$dst)>, Requires<[SmallCode]>;
1875 def : Pat<(i64 (X86Wrapper tblockaddress:$dst)),
1876 (MOV64ri64i32 tblockaddress:$dst)>, Requires<[SmallCode]>;
1878 // In kernel code model, we can get the address of a label
1879 // into a register with 'movq'. FIXME: This is a hack, the 'imm' predicate of
1880 // the MOV64ri32 should accept these.
1881 def : Pat<(i64 (X86Wrapper tconstpool :$dst)),
1882 (MOV64ri32 tconstpool :$dst)>, Requires<[KernelCode]>;
1883 def : Pat<(i64 (X86Wrapper tjumptable :$dst)),
1884 (MOV64ri32 tjumptable :$dst)>, Requires<[KernelCode]>;
1885 def : Pat<(i64 (X86Wrapper tglobaladdr :$dst)),
1886 (MOV64ri32 tglobaladdr :$dst)>, Requires<[KernelCode]>;
1887 def : Pat<(i64 (X86Wrapper texternalsym:$dst)),
1888 (MOV64ri32 texternalsym:$dst)>, Requires<[KernelCode]>;
1889 def : Pat<(i64 (X86Wrapper tblockaddress:$dst)),
1890 (MOV64ri32 tblockaddress:$dst)>, Requires<[KernelCode]>;
1892 // If we have small model and -static mode, it is safe to store global addresses
1893 // directly as immediates. FIXME: This is really a hack, the 'imm' predicate
1894 // for MOV64mi32 should handle this sort of thing.
1895 def : Pat<(store (i64 (X86Wrapper tconstpool:$src)), addr:$dst),
1896 (MOV64mi32 addr:$dst, tconstpool:$src)>,
1897 Requires<[NearData, IsStatic]>;
1898 def : Pat<(store (i64 (X86Wrapper tjumptable:$src)), addr:$dst),
1899 (MOV64mi32 addr:$dst, tjumptable:$src)>,
1900 Requires<[NearData, IsStatic]>;
1901 def : Pat<(store (i64 (X86Wrapper tglobaladdr:$src)), addr:$dst),
1902 (MOV64mi32 addr:$dst, tglobaladdr:$src)>,
1903 Requires<[NearData, IsStatic]>;
1904 def : Pat<(store (i64 (X86Wrapper texternalsym:$src)), addr:$dst),
1905 (MOV64mi32 addr:$dst, texternalsym:$src)>,
1906 Requires<[NearData, IsStatic]>;
1907 def : Pat<(store (i64 (X86Wrapper tblockaddress:$src)), addr:$dst),
1908 (MOV64mi32 addr:$dst, tblockaddress:$src)>,
1909 Requires<[NearData, IsStatic]>;
1912 // Direct PC relative function call for small code model. 32-bit displacement
1913 // sign extended to 64-bit.
1914 def : Pat<(X86call (i64 tglobaladdr:$dst)),
1915 (CALL64pcrel32 tglobaladdr:$dst)>, Requires<[NotWin64]>;
1916 def : Pat<(X86call (i64 texternalsym:$dst)),
1917 (CALL64pcrel32 texternalsym:$dst)>, Requires<[NotWin64]>;
1919 def : Pat<(X86call (i64 tglobaladdr:$dst)),
1920 (WINCALL64pcrel32 tglobaladdr:$dst)>, Requires<[IsWin64]>;
1921 def : Pat<(X86call (i64 texternalsym:$dst)),
1922 (WINCALL64pcrel32 texternalsym:$dst)>, Requires<[IsWin64]>;
1925 def : Pat<(X86tcret GR64_TC:$dst, imm:$off),
1926 (TCRETURNri64 GR64_TC:$dst, imm:$off)>,
1927 Requires<[In64BitMode]>;
1929 def : Pat<(X86tcret (load addr:$dst), imm:$off),
1930 (TCRETURNmi64 addr:$dst, imm:$off)>,
1931 Requires<[In64BitMode]>;
1933 def : Pat<(X86tcret (i64 tglobaladdr:$dst), imm:$off),
1934 (TCRETURNdi64 tglobaladdr:$dst, imm:$off)>,
1935 Requires<[In64BitMode]>;
1937 def : Pat<(X86tcret (i64 texternalsym:$dst), imm:$off),
1938 (TCRETURNdi64 texternalsym:$dst, imm:$off)>,
1939 Requires<[In64BitMode]>;
1943 // TEST R,R is smaller than CMP R,0
1944 def : Pat<(X86cmp GR64:$src1, 0),
1945 (TEST64rr GR64:$src1, GR64:$src1)>;
1947 // Conditional moves with folded loads with operands swapped and conditions
1949 def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_B, EFLAGS),
1950 (CMOVAE64rm GR64:$src2, addr:$src1)>;
1951 def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_AE, EFLAGS),
1952 (CMOVB64rm GR64:$src2, addr:$src1)>;
1953 def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_E, EFLAGS),
1954 (CMOVNE64rm GR64:$src2, addr:$src1)>;
1955 def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_NE, EFLAGS),
1956 (CMOVE64rm GR64:$src2, addr:$src1)>;
1957 def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_BE, EFLAGS),
1958 (CMOVA64rm GR64:$src2, addr:$src1)>;
1959 def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_A, EFLAGS),
1960 (CMOVBE64rm GR64:$src2, addr:$src1)>;
1961 def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_L, EFLAGS),
1962 (CMOVGE64rm GR64:$src2, addr:$src1)>;
1963 def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_GE, EFLAGS),
1964 (CMOVL64rm GR64:$src2, addr:$src1)>;
1965 def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_LE, EFLAGS),
1966 (CMOVG64rm GR64:$src2, addr:$src1)>;
1967 def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_G, EFLAGS),
1968 (CMOVLE64rm GR64:$src2, addr:$src1)>;
1969 def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_P, EFLAGS),
1970 (CMOVNP64rm GR64:$src2, addr:$src1)>;
1971 def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_NP, EFLAGS),
1972 (CMOVP64rm GR64:$src2, addr:$src1)>;
1973 def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_S, EFLAGS),
1974 (CMOVNS64rm GR64:$src2, addr:$src1)>;
1975 def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_NS, EFLAGS),
1976 (CMOVS64rm GR64:$src2, addr:$src1)>;
1977 def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_O, EFLAGS),
1978 (CMOVNO64rm GR64:$src2, addr:$src1)>;
1979 def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_NO, EFLAGS),
1980 (CMOVO64rm GR64:$src2, addr:$src1)>;
1982 // zextload bool -> zextload byte
1983 def : Pat<(zextloadi64i1 addr:$src), (MOVZX64rm8 addr:$src)>;
1986 // When extloading from 16-bit and smaller memory locations into 64-bit
1987 // registers, use zero-extending loads so that the entire 64-bit register is
1988 // defined, avoiding partial-register updates.
1989 def : Pat<(extloadi64i1 addr:$src), (MOVZX64rm8 addr:$src)>;
1990 def : Pat<(extloadi64i8 addr:$src), (MOVZX64rm8 addr:$src)>;
1991 def : Pat<(extloadi64i16 addr:$src), (MOVZX64rm16 addr:$src)>;
1992 // For other extloads, use subregs, since the high contents of the register are
1993 // defined after an extload.
1994 def : Pat<(extloadi64i32 addr:$src),
1995 (SUBREG_TO_REG (i64 0), (MOV32rm addr:$src),
1998 // anyext. Define these to do an explicit zero-extend to
1999 // avoid partial-register updates.
2000 def : Pat<(i64 (anyext GR8 :$src)), (MOVZX64rr8 GR8 :$src)>;
2001 def : Pat<(i64 (anyext GR16:$src)), (MOVZX64rr16 GR16 :$src)>;
2002 def : Pat<(i64 (anyext GR32:$src)),
2003 (SUBREG_TO_REG (i64 0), GR32:$src, x86_subreg_32bit)>;
2005 //===----------------------------------------------------------------------===//
2007 //===----------------------------------------------------------------------===//
2009 // Odd encoding trick: -128 fits into an 8-bit immediate field while
2010 // +128 doesn't, so in this special case use a sub instead of an add.
2011 def : Pat<(add GR64:$src1, 128),
2012 (SUB64ri8 GR64:$src1, -128)>;
2013 def : Pat<(store (add (loadi64 addr:$dst), 128), addr:$dst),
2014 (SUB64mi8 addr:$dst, -128)>;
2016 // The same trick applies for 32-bit immediate fields in 64-bit
2018 def : Pat<(add GR64:$src1, 0x0000000080000000),
2019 (SUB64ri32 GR64:$src1, 0xffffffff80000000)>;
2020 def : Pat<(store (add (loadi64 addr:$dst), 0x00000000800000000), addr:$dst),
2021 (SUB64mi32 addr:$dst, 0xffffffff80000000)>;
2023 // Use a 32-bit and with implicit zero-extension instead of a 64-bit and if it
2024 // has an immediate with at least 32 bits of leading zeros, to avoid needing to
2025 // materialize that immediate in a register first.
2026 def : Pat<(and GR64:$src, i64immZExt32:$imm),
2030 (EXTRACT_SUBREG GR64:$src, x86_subreg_32bit),
2031 (i32 (GetLo32XForm imm:$imm))),
2034 // r & (2^32-1) ==> movz
2035 def : Pat<(and GR64:$src, 0x00000000FFFFFFFF),
2036 (MOVZX64rr32 (EXTRACT_SUBREG GR64:$src, x86_subreg_32bit))>;
2037 // r & (2^16-1) ==> movz
2038 def : Pat<(and GR64:$src, 0xffff),
2039 (MOVZX64rr16 (i16 (EXTRACT_SUBREG GR64:$src, x86_subreg_16bit)))>;
2040 // r & (2^8-1) ==> movz
2041 def : Pat<(and GR64:$src, 0xff),
2042 (MOVZX64rr8 (i8 (EXTRACT_SUBREG GR64:$src, x86_subreg_8bit)))>;
2043 // r & (2^8-1) ==> movz
2044 def : Pat<(and GR32:$src1, 0xff),
2045 (MOVZX32rr8 (EXTRACT_SUBREG GR32:$src1, x86_subreg_8bit))>,
2046 Requires<[In64BitMode]>;
2047 // r & (2^8-1) ==> movz
2048 def : Pat<(and GR16:$src1, 0xff),
2049 (MOVZX16rr8 (i8 (EXTRACT_SUBREG GR16:$src1, x86_subreg_8bit)))>,
2050 Requires<[In64BitMode]>;
2052 // sext_inreg patterns
2053 def : Pat<(sext_inreg GR64:$src, i32),
2054 (MOVSX64rr32 (EXTRACT_SUBREG GR64:$src, x86_subreg_32bit))>;
2055 def : Pat<(sext_inreg GR64:$src, i16),
2056 (MOVSX64rr16 (EXTRACT_SUBREG GR64:$src, x86_subreg_16bit))>;
2057 def : Pat<(sext_inreg GR64:$src, i8),
2058 (MOVSX64rr8 (EXTRACT_SUBREG GR64:$src, x86_subreg_8bit))>;
2059 def : Pat<(sext_inreg GR32:$src, i8),
2060 (MOVSX32rr8 (EXTRACT_SUBREG GR32:$src, x86_subreg_8bit))>,
2061 Requires<[In64BitMode]>;
2062 def : Pat<(sext_inreg GR16:$src, i8),
2063 (MOVSX16rr8 (i8 (EXTRACT_SUBREG GR16:$src, x86_subreg_8bit)))>,
2064 Requires<[In64BitMode]>;
2067 def : Pat<(i32 (trunc GR64:$src)),
2068 (EXTRACT_SUBREG GR64:$src, x86_subreg_32bit)>;
2069 def : Pat<(i16 (trunc GR64:$src)),
2070 (EXTRACT_SUBREG GR64:$src, x86_subreg_16bit)>;
2071 def : Pat<(i8 (trunc GR64:$src)),
2072 (EXTRACT_SUBREG GR64:$src, x86_subreg_8bit)>;
2073 def : Pat<(i8 (trunc GR32:$src)),
2074 (EXTRACT_SUBREG GR32:$src, x86_subreg_8bit)>,
2075 Requires<[In64BitMode]>;
2076 def : Pat<(i8 (trunc GR16:$src)),
2077 (EXTRACT_SUBREG GR16:$src, x86_subreg_8bit)>,
2078 Requires<[In64BitMode]>;
2080 // h-register tricks.
2081 // For now, be conservative on x86-64 and use an h-register extract only if the
2082 // value is immediately zero-extended or stored, which are somewhat common
2083 // cases. This uses a bunch of code to prevent a register requiring a REX prefix
2084 // from being allocated in the same instruction as the h register, as there's
2085 // currently no way to describe this requirement to the register allocator.
2087 // h-register extract and zero-extend.
2088 def : Pat<(and (srl_su GR64:$src, (i8 8)), (i64 255)),
2092 (EXTRACT_SUBREG (i64 (COPY_TO_REGCLASS GR64:$src, GR64_ABCD)),
2093 x86_subreg_8bit_hi)),
2095 def : Pat<(and (srl_su GR32:$src, (i8 8)), (i32 255)),
2097 (EXTRACT_SUBREG (i32 (COPY_TO_REGCLASS GR32:$src, GR32_ABCD)),
2098 x86_subreg_8bit_hi))>,
2099 Requires<[In64BitMode]>;
2100 def : Pat<(srl (and_su GR32:$src, 0xff00), (i8 8)),
2101 (MOVZX32_NOREXrr8 (EXTRACT_SUBREG (i32 (COPY_TO_REGCLASS GR32:$src,
2103 x86_subreg_8bit_hi))>,
2104 Requires<[In64BitMode]>;
2105 def : Pat<(srl GR16:$src, (i8 8)),
2108 (EXTRACT_SUBREG (i16 (COPY_TO_REGCLASS GR16:$src, GR16_ABCD)),
2109 x86_subreg_8bit_hi)),
2111 Requires<[In64BitMode]>;
2112 def : Pat<(i32 (zext (srl_su GR16:$src, (i8 8)))),
2114 (EXTRACT_SUBREG (i16 (COPY_TO_REGCLASS GR16:$src, GR16_ABCD)),
2115 x86_subreg_8bit_hi))>,
2116 Requires<[In64BitMode]>;
2117 def : Pat<(i32 (anyext (srl_su GR16:$src, (i8 8)))),
2119 (EXTRACT_SUBREG (i16 (COPY_TO_REGCLASS GR16:$src, GR16_ABCD)),
2120 x86_subreg_8bit_hi))>,
2121 Requires<[In64BitMode]>;
2122 def : Pat<(i64 (zext (srl_su GR16:$src, (i8 8)))),
2126 (EXTRACT_SUBREG (i16 (COPY_TO_REGCLASS GR16:$src, GR16_ABCD)),
2127 x86_subreg_8bit_hi)),
2129 def : Pat<(i64 (anyext (srl_su GR16:$src, (i8 8)))),
2133 (EXTRACT_SUBREG (i16 (COPY_TO_REGCLASS GR16:$src, GR16_ABCD)),
2134 x86_subreg_8bit_hi)),
2137 // h-register extract and store.
2138 def : Pat<(store (i8 (trunc_su (srl_su GR64:$src, (i8 8)))), addr:$dst),
2141 (EXTRACT_SUBREG (i64 (COPY_TO_REGCLASS GR64:$src, GR64_ABCD)),
2142 x86_subreg_8bit_hi))>;
2143 def : Pat<(store (i8 (trunc_su (srl_su GR32:$src, (i8 8)))), addr:$dst),
2146 (EXTRACT_SUBREG (i32 (COPY_TO_REGCLASS GR32:$src, GR32_ABCD)),
2147 x86_subreg_8bit_hi))>,
2148 Requires<[In64BitMode]>;
2149 def : Pat<(store (i8 (trunc_su (srl_su GR16:$src, (i8 8)))), addr:$dst),
2152 (EXTRACT_SUBREG (i16 (COPY_TO_REGCLASS GR16:$src, GR16_ABCD)),
2153 x86_subreg_8bit_hi))>,
2154 Requires<[In64BitMode]>;
2156 // (shl x, 1) ==> (add x, x)
2157 def : Pat<(shl GR64:$src1, (i8 1)), (ADD64rr GR64:$src1, GR64:$src1)>;
2159 // (shl x (and y, 63)) ==> (shl x, y)
2160 def : Pat<(shl GR64:$src1, (and CL, 63)),
2161 (SHL64rCL GR64:$src1)>;
2162 def : Pat<(store (shl (loadi64 addr:$dst), (and CL, 63)), addr:$dst),
2163 (SHL64mCL addr:$dst)>;
2165 def : Pat<(srl GR64:$src1, (and CL, 63)),
2166 (SHR64rCL GR64:$src1)>;
2167 def : Pat<(store (srl (loadi64 addr:$dst), (and CL, 63)), addr:$dst),
2168 (SHR64mCL addr:$dst)>;
2170 def : Pat<(sra GR64:$src1, (and CL, 63)),
2171 (SAR64rCL GR64:$src1)>;
2172 def : Pat<(store (sra (loadi64 addr:$dst), (and CL, 63)), addr:$dst),
2173 (SAR64mCL addr:$dst)>;
2175 // (or x1, x2) -> (add x1, x2) if two operands are known not to share bits.
2176 let AddedComplexity = 5 in { // Try this before the selecting to OR
2177 def : Pat<(or_is_add GR64:$src1, i64immSExt8:$src2),
2178 (ADD64ri8 GR64:$src1, i64immSExt8:$src2)>;
2179 def : Pat<(or_is_add GR64:$src1, i64immSExt32:$src2),
2180 (ADD64ri32 GR64:$src1, i64immSExt32:$src2)>;
2181 def : Pat<(or_is_add GR64:$src1, GR64:$src2),
2182 (ADD64rr GR64:$src1, GR64:$src2)>;
2183 } // AddedComplexity
2185 // X86 specific add which produces a flag.
2186 def : Pat<(addc GR64:$src1, GR64:$src2),
2187 (ADD64rr GR64:$src1, GR64:$src2)>;
2188 def : Pat<(addc GR64:$src1, (load addr:$src2)),
2189 (ADD64rm GR64:$src1, addr:$src2)>;
2190 def : Pat<(addc GR64:$src1, i64immSExt8:$src2),
2191 (ADD64ri8 GR64:$src1, i64immSExt8:$src2)>;
2192 def : Pat<(addc GR64:$src1, i64immSExt32:$src2),
2193 (ADD64ri32 GR64:$src1, imm:$src2)>;
2195 def : Pat<(subc GR64:$src1, GR64:$src2),
2196 (SUB64rr GR64:$src1, GR64:$src2)>;
2197 def : Pat<(subc GR64:$src1, (load addr:$src2)),
2198 (SUB64rm GR64:$src1, addr:$src2)>;
2199 def : Pat<(subc GR64:$src1, i64immSExt8:$src2),
2200 (SUB64ri8 GR64:$src1, i64immSExt8:$src2)>;
2201 def : Pat<(subc GR64:$src1, imm:$src2),
2202 (SUB64ri32 GR64:$src1, i64immSExt32:$src2)>;
2204 //===----------------------------------------------------------------------===//
2205 // EFLAGS-defining Patterns
2206 //===----------------------------------------------------------------------===//
2209 def : Pat<(add GR64:$src1, GR64:$src2),
2210 (ADD64rr GR64:$src1, GR64:$src2)>;
2211 def : Pat<(add GR64:$src1, i64immSExt8:$src2),
2212 (ADD64ri8 GR64:$src1, i64immSExt8:$src2)>;
2213 def : Pat<(add GR64:$src1, i64immSExt32:$src2),
2214 (ADD64ri32 GR64:$src1, i64immSExt32:$src2)>;
2215 def : Pat<(add GR64:$src1, (loadi64 addr:$src2)),
2216 (ADD64rm GR64:$src1, addr:$src2)>;
2219 def : Pat<(sub GR64:$src1, GR64:$src2),
2220 (SUB64rr GR64:$src1, GR64:$src2)>;
2221 def : Pat<(sub GR64:$src1, (loadi64 addr:$src2)),
2222 (SUB64rm GR64:$src1, addr:$src2)>;
2223 def : Pat<(sub GR64:$src1, i64immSExt8:$src2),
2224 (SUB64ri8 GR64:$src1, i64immSExt8:$src2)>;
2225 def : Pat<(sub GR64:$src1, i64immSExt32:$src2),
2226 (SUB64ri32 GR64:$src1, i64immSExt32:$src2)>;
2229 def : Pat<(mul GR64:$src1, GR64:$src2),
2230 (IMUL64rr GR64:$src1, GR64:$src2)>;
2231 def : Pat<(mul GR64:$src1, (loadi64 addr:$src2)),
2232 (IMUL64rm GR64:$src1, addr:$src2)>;
2233 def : Pat<(mul GR64:$src1, i64immSExt8:$src2),
2234 (IMUL64rri8 GR64:$src1, i64immSExt8:$src2)>;
2235 def : Pat<(mul GR64:$src1, i64immSExt32:$src2),
2236 (IMUL64rri32 GR64:$src1, i64immSExt32:$src2)>;
2237 def : Pat<(mul (loadi64 addr:$src1), i64immSExt8:$src2),
2238 (IMUL64rmi8 addr:$src1, i64immSExt8:$src2)>;
2239 def : Pat<(mul (loadi64 addr:$src1), i64immSExt32:$src2),
2240 (IMUL64rmi32 addr:$src1, i64immSExt32:$src2)>;
2243 def : Pat<(add GR16:$src, 1), (INC64_16r GR16:$src)>, Requires<[In64BitMode]>;
2244 def : Pat<(add GR16:$src, -1), (DEC64_16r GR16:$src)>, Requires<[In64BitMode]>;
2245 def : Pat<(add GR32:$src, 1), (INC64_32r GR32:$src)>, Requires<[In64BitMode]>;
2246 def : Pat<(add GR32:$src, -1), (DEC64_32r GR32:$src)>, Requires<[In64BitMode]>;
2247 def : Pat<(add GR64:$src, 1), (INC64r GR64:$src)>;
2248 def : Pat<(add GR64:$src, -1), (DEC64r GR64:$src)>;
2251 def : Pat<(or GR64:$src1, GR64:$src2),
2252 (OR64rr GR64:$src1, GR64:$src2)>;
2253 def : Pat<(or GR64:$src1, i64immSExt8:$src2),
2254 (OR64ri8 GR64:$src1, i64immSExt8:$src2)>;
2255 def : Pat<(or GR64:$src1, i64immSExt32:$src2),
2256 (OR64ri32 GR64:$src1, i64immSExt32:$src2)>;
2257 def : Pat<(or GR64:$src1, (loadi64 addr:$src2)),
2258 (OR64rm GR64:$src1, addr:$src2)>;
2261 def : Pat<(xor GR64:$src1, GR64:$src2),
2262 (XOR64rr GR64:$src1, GR64:$src2)>;
2263 def : Pat<(xor GR64:$src1, i64immSExt8:$src2),
2264 (XOR64ri8 GR64:$src1, i64immSExt8:$src2)>;
2265 def : Pat<(xor GR64:$src1, i64immSExt32:$src2),
2266 (XOR64ri32 GR64:$src1, i64immSExt32:$src2)>;
2267 def : Pat<(xor GR64:$src1, (loadi64 addr:$src2)),
2268 (XOR64rm GR64:$src1, addr:$src2)>;
2271 def : Pat<(and GR64:$src1, GR64:$src2),
2272 (AND64rr GR64:$src1, GR64:$src2)>;
2273 def : Pat<(and GR64:$src1, i64immSExt8:$src2),
2274 (AND64ri8 GR64:$src1, i64immSExt8:$src2)>;
2275 def : Pat<(and GR64:$src1, i64immSExt32:$src2),
2276 (AND64ri32 GR64:$src1, i64immSExt32:$src2)>;
2277 def : Pat<(and GR64:$src1, (loadi64 addr:$src2)),
2278 (AND64rm GR64:$src1, addr:$src2)>;
2280 //===----------------------------------------------------------------------===//
2281 // X86-64 SSE Instructions
2282 //===----------------------------------------------------------------------===//
2284 // Move instructions...
2286 def MOV64toPQIrr : RPDI<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR64:$src),
2287 "mov{d|q}\t{$src, $dst|$dst, $src}",
2289 (v2i64 (scalar_to_vector GR64:$src)))]>;
2290 def MOVPQIto64rr : RPDI<0x7E, MRMDestReg, (outs GR64:$dst), (ins VR128:$src),
2291 "mov{d|q}\t{$src, $dst|$dst, $src}",
2292 [(set GR64:$dst, (vector_extract (v2i64 VR128:$src),
2295 def MOV64toSDrr : RPDI<0x6E, MRMSrcReg, (outs FR64:$dst), (ins GR64:$src),
2296 "mov{d|q}\t{$src, $dst|$dst, $src}",
2297 [(set FR64:$dst, (bitconvert GR64:$src))]>;
2298 def MOV64toSDrm : S3SI<0x7E, MRMSrcMem, (outs FR64:$dst), (ins i64mem:$src),
2299 "movq\t{$src, $dst|$dst, $src}",
2300 [(set FR64:$dst, (bitconvert (loadi64 addr:$src)))]>;
2302 def MOVSDto64rr : RPDI<0x7E, MRMDestReg, (outs GR64:$dst), (ins FR64:$src),
2303 "mov{d|q}\t{$src, $dst|$dst, $src}",
2304 [(set GR64:$dst, (bitconvert FR64:$src))]>;
2305 def MOVSDto64mr : RPDI<0x7E, MRMDestMem, (outs), (ins i64mem:$dst, FR64:$src),
2306 "movq\t{$src, $dst|$dst, $src}",
2307 [(store (i64 (bitconvert FR64:$src)), addr:$dst)]>;
2309 //===----------------------------------------------------------------------===//
2310 // X86-64 SSE4.1 Instructions
2311 //===----------------------------------------------------------------------===//
2313 /// SS41I_extract32 - SSE 4.1 extract 32 bits to int reg or memory destination
2314 multiclass SS41I_extract64<bits<8> opc, string OpcodeStr> {
2315 def rr : SS4AIi8<opc, MRMDestReg, (outs GR64:$dst),
2316 (ins VR128:$src1, i32i8imm:$src2),
2317 !strconcat(OpcodeStr,
2318 "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2320 (extractelt (v2i64 VR128:$src1), imm:$src2))]>, OpSize, REX_W;
2321 def mr : SS4AIi8<opc, MRMDestMem, (outs),
2322 (ins i64mem:$dst, VR128:$src1, i32i8imm:$src2),
2323 !strconcat(OpcodeStr,
2324 "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2325 [(store (extractelt (v2i64 VR128:$src1), imm:$src2),
2326 addr:$dst)]>, OpSize, REX_W;
2329 defm PEXTRQ : SS41I_extract64<0x16, "pextrq">;
2331 let isTwoAddress = 1 in {
2332 multiclass SS41I_insert64<bits<8> opc, string OpcodeStr> {
2333 def rr : SS4AIi8<opc, MRMSrcReg, (outs VR128:$dst),
2334 (ins VR128:$src1, GR64:$src2, i32i8imm:$src3),
2335 !strconcat(OpcodeStr,
2336 "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
2338 (v2i64 (insertelt VR128:$src1, GR64:$src2, imm:$src3)))]>,
2340 def rm : SS4AIi8<opc, MRMSrcMem, (outs VR128:$dst),
2341 (ins VR128:$src1, i64mem:$src2, i32i8imm:$src3),
2342 !strconcat(OpcodeStr,
2343 "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
2345 (v2i64 (insertelt VR128:$src1, (loadi64 addr:$src2),
2346 imm:$src3)))]>, OpSize, REX_W;
2350 defm PINSRQ : SS41I_insert64<0x22, "pinsrq">;