blob: ac4384631e574b185ca9af83f8a357bfbdf81dbc [file] [log] [blame]
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001//====- X86InstrX86-64.td - Describe the X86 Instruction Set ----*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file was developed by the Evan Cheng and is distributed under
6// the University of Illinois Open Source License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
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.
13//
14//===----------------------------------------------------------------------===//
15
16//===----------------------------------------------------------------------===//
17// Operand Definitions...
18//
19
20// 64-bits but only 32 bits are significant.
21def i64i32imm : Operand<i64>;
22// 64-bits but only 8 bits are significant.
23def i64i8imm : Operand<i64>;
24
25def lea64mem : Operand<i64> {
26 let PrintMethod = "printi64mem";
27 let MIOperandInfo = (ops GR64, i8imm, GR64, i32imm);
28}
29
30def lea64_32mem : Operand<i32> {
31 let PrintMethod = "printlea64_32mem";
32 let MIOperandInfo = (ops GR32, i8imm, GR32, i32imm);
33}
34
35//===----------------------------------------------------------------------===//
36// Complex Pattern Definitions...
37//
38def lea64addr : ComplexPattern<i64, 4, "SelectLEAAddr",
39 [add, mul, shl, or, frameindex, X86Wrapper],
40 []>;
41
42//===----------------------------------------------------------------------===//
43// Instruction templates...
44//
45
46class RI<bits<8> o, Format F, dag ops, string asm, list<dag> pattern>
47 : I<o, F, ops, asm, pattern>, REX_W;
48class RIi8 <bits<8> o, Format F, dag ops, string asm, list<dag> pattern>
49 : Ii8<o, F, ops, asm, pattern>, REX_W;
50class RIi32 <bits<8> o, Format F, dag ops, string asm, list<dag> pattern>
51 : Ii32<o, F, ops, asm, pattern>, REX_W;
52
53class RIi64<bits<8> o, Format f, dag ops, string asm, list<dag> pattern>
54 : X86Inst<o, f, Imm64, ops, asm>, REX_W {
55 let Pattern = pattern;
56 let CodeSize = 3;
57}
58
59class RSSI<bits<8> o, Format F, dag ops, string asm, list<dag> pattern>
60 : SSI<o, F, ops, asm, pattern>, REX_W;
61class RSDI<bits<8> o, Format F, dag ops, string asm, list<dag> pattern>
62 : SDI<o, F, ops, asm, pattern>, REX_W;
63class RPDI<bits<8> o, Format F, dag ops, string asm, list<dag> pattern>
64 : PDI<o, F, ops, asm, pattern>, REX_W;
65
66//===----------------------------------------------------------------------===//
67// Pattern fragments...
68//
69
70def i64immSExt32 : PatLeaf<(i64 imm), [{
71 // i64immSExt32 predicate - True if the 64-bit immediate fits in a 32-bit
72 // sign extended field.
73 return (int64_t)N->getValue() == (int32_t)N->getValue();
74}]>;
75
76def i64immZExt32 : PatLeaf<(i64 imm), [{
77 // i64immZExt32 predicate - True if the 64-bit immediate fits in a 32-bit
78 // unsignedsign extended field.
79 return (uint64_t)N->getValue() == (uint32_t)N->getValue();
80}]>;
81
82def i64immSExt8 : PatLeaf<(i64 imm), [{
83 // i64immSExt8 predicate - True if the 64-bit immediate fits in a 8-bit
84 // sign extended field.
85 return (int64_t)N->getValue() == (int8_t)N->getValue();
86}]>;
87
88def sextloadi64i1 : PatFrag<(ops node:$ptr), (i64 (sextloadi1 node:$ptr))>;
89def sextloadi64i8 : PatFrag<(ops node:$ptr), (i64 (sextloadi8 node:$ptr))>;
90def sextloadi64i16 : PatFrag<(ops node:$ptr), (i64 (sextloadi16 node:$ptr))>;
91def sextloadi64i32 : PatFrag<(ops node:$ptr), (i64 (sextloadi32 node:$ptr))>;
92
93def zextloadi64i1 : PatFrag<(ops node:$ptr), (i64 (zextloadi1 node:$ptr))>;
94def zextloadi64i8 : PatFrag<(ops node:$ptr), (i64 (zextloadi8 node:$ptr))>;
95def zextloadi64i16 : PatFrag<(ops node:$ptr), (i64 (zextloadi16 node:$ptr))>;
96def zextloadi64i32 : PatFrag<(ops node:$ptr), (i64 (zextloadi32 node:$ptr))>;
97
98def extloadi64i1 : PatFrag<(ops node:$ptr), (i64 (extloadi1 node:$ptr))>;
99def extloadi64i8 : PatFrag<(ops node:$ptr), (i64 (extloadi8 node:$ptr))>;
100def extloadi64i16 : PatFrag<(ops node:$ptr), (i64 (extloadi16 node:$ptr))>;
101def extloadi64i32 : PatFrag<(ops node:$ptr), (i64 (extloadi32 node:$ptr))>;
102
103//===----------------------------------------------------------------------===//
104// Instruction list...
105//
106
107def IMPLICIT_DEF_GR64 : I<0, Pseudo, (ops GR64:$dst),
108 "#IMPLICIT_DEF $dst",
109 [(set GR64:$dst, (undef))]>;
110
111//===----------------------------------------------------------------------===//
112// Call Instructions...
113//
114let isCall = 1, noResults = 1 in
115 // All calls clobber the non-callee saved registers...
116 let Defs = [RAX, RCX, RDX, RSI, RDI, R8, R9, R10, R11,
117 FP0, FP1, FP2, FP3, FP4, FP5, FP6, ST0,
118 MM0, MM1, MM2, MM3, MM4, MM5, MM6, MM7,
119 XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7,
120 XMM8, XMM9, XMM10, XMM11, XMM12, XMM13, XMM14, XMM15] in {
121 def CALL64pcrel32 : I<0xE8, RawFrm, (ops i64imm:$dst, variable_ops),
122 "call ${dst:call}", []>;
123 def CALL64r : I<0xFF, MRM2r, (ops GR64:$dst, variable_ops),
124 "call {*}$dst", [(X86call GR64:$dst)]>;
125 def CALL64m : I<0xFF, MRM2m, (ops i64mem:$dst, variable_ops),
126 "call {*}$dst", []>;
127 }
128
129// Branches
130let isBranch = 1, isTerminator = 1, noResults = 1, isBarrier = 1 in {
131 def JMP64r : I<0xFF, MRM4r, (ops GR64:$dst), "jmp{q} {*}$dst",
132 [(brind GR64:$dst)]>;
133 def JMP64m : I<0xFF, MRM4m, (ops i64mem:$dst), "jmp{q} {*}$dst",
134 [(brind (loadi64 addr:$dst))]>;
135}
136
137//===----------------------------------------------------------------------===//
138// Miscellaneous Instructions...
139//
140def LEAVE64 : I<0xC9, RawFrm,
141 (ops), "leave", []>, Imp<[RBP,RSP],[RBP,RSP]>;
142def POP64r : I<0x58, AddRegFrm,
143 (ops GR64:$reg), "pop{q} $reg", []>, Imp<[RSP],[RSP]>;
144def PUSH64r : I<0x50, AddRegFrm,
145 (ops GR64:$reg), "push{q} $reg", []>, Imp<[RSP],[RSP]>;
146
147def LEA64_32r : I<0x8D, MRMSrcMem,
148 (ops GR32:$dst, lea64_32mem:$src),
149 "lea{l} {$src|$dst}, {$dst|$src}",
150 [(set GR32:$dst, lea32addr:$src)]>, Requires<[In64BitMode]>;
151
152def LEA64r : RI<0x8D, MRMSrcMem, (ops GR64:$dst, lea64mem:$src),
153 "lea{q} {$src|$dst}, {$dst|$src}",
154 [(set GR64:$dst, lea64addr:$src)]>;
155
156let isTwoAddress = 1 in
157def BSWAP64r : RI<0xC8, AddRegFrm, (ops GR64:$dst, GR64:$src),
158 "bswap{q} $dst",
159 [(set GR64:$dst, (bswap GR64:$src))]>, TB;
160// Exchange
161def XCHG64rr : RI<0x87, MRMDestReg, (ops GR64:$src1, GR64:$src2),
162 "xchg{q} {$src2|$src1}, {$src1|$src2}", []>;
163def XCHG64mr : RI<0x87, MRMDestMem, (ops i64mem:$src1, GR64:$src2),
164 "xchg{q} {$src2|$src1}, {$src1|$src2}", []>;
165def XCHG64rm : RI<0x87, MRMSrcMem, (ops GR64:$src1, i64mem:$src2),
166 "xchg{q} {$src2|$src1}, {$src1|$src2}", []>;
167
168// Repeat string ops
169def REP_MOVSQ : RI<0xA5, RawFrm, (ops), "{rep;movsq|rep movsq}",
170 [(X86rep_movs i64)]>,
171 Imp<[RCX,RDI,RSI], [RCX,RDI,RSI]>, REP;
172def REP_STOSQ : RI<0xAB, RawFrm, (ops), "{rep;stosq|rep stosq}",
173 [(X86rep_stos i64)]>,
174 Imp<[RAX,RCX,RDI], [RCX,RDI]>, REP;
175
176//===----------------------------------------------------------------------===//
177// Move Instructions...
178//
179
180def MOV64rr : RI<0x89, MRMDestReg, (ops GR64:$dst, GR64:$src),
181 "mov{q} {$src, $dst|$dst, $src}", []>;
182
183def MOV64ri : RIi64<0xB8, AddRegFrm, (ops GR64:$dst, i64imm:$src),
184 "movabs{q} {$src, $dst|$dst, $src}",
185 [(set GR64:$dst, imm:$src)]>;
186def MOV64ri32 : RIi32<0xC7, MRM0r, (ops GR64:$dst, i64i32imm:$src),
187 "mov{q} {$src, $dst|$dst, $src}",
188 [(set GR64:$dst, i64immSExt32:$src)]>;
189
190def MOV64rm : RI<0x8B, MRMSrcMem, (ops GR64:$dst, i64mem:$src),
191 "mov{q} {$src, $dst|$dst, $src}",
192 [(set GR64:$dst, (load addr:$src))]>;
193
194def MOV64mr : RI<0x89, MRMDestMem, (ops i64mem:$dst, GR64:$src),
195 "mov{q} {$src, $dst|$dst, $src}",
196 [(store GR64:$src, addr:$dst)]>;
197def MOV64mi32 : RIi32<0xC7, MRM0m, (ops i64mem:$dst, i64i32imm:$src),
198 "mov{q} {$src, $dst|$dst, $src}",
199 [(store i64immSExt32:$src, addr:$dst)]>;
200
201// Sign/Zero extenders
202
203def MOVSX64rr8 : RI<0xBE, MRMSrcReg, (ops GR64:$dst, GR8 :$src),
204 "movs{bq|x} {$src, $dst|$dst, $src}",
205 [(set GR64:$dst, (sext GR8:$src))]>, TB;
206def MOVSX64rm8 : RI<0xBE, MRMSrcMem, (ops GR64:$dst, i8mem :$src),
207 "movs{bq|x} {$src, $dst|$dst, $src}",
208 [(set GR64:$dst, (sextloadi64i8 addr:$src))]>, TB;
209def MOVSX64rr16: RI<0xBF, MRMSrcReg, (ops GR64:$dst, GR16:$src),
210 "movs{wq|x} {$src, $dst|$dst, $src}",
211 [(set GR64:$dst, (sext GR16:$src))]>, TB;
212def MOVSX64rm16: RI<0xBF, MRMSrcMem, (ops GR64:$dst, i16mem:$src),
213 "movs{wq|x} {$src, $dst|$dst, $src}",
214 [(set GR64:$dst, (sextloadi64i16 addr:$src))]>, TB;
215def MOVSX64rr32: RI<0x63, MRMSrcReg, (ops GR64:$dst, GR32:$src),
216 "movs{lq|xd} {$src, $dst|$dst, $src}",
217 [(set GR64:$dst, (sext GR32:$src))]>;
218def MOVSX64rm32: RI<0x63, MRMSrcMem, (ops GR64:$dst, i32mem:$src),
219 "movs{lq|xd} {$src, $dst|$dst, $src}",
220 [(set GR64:$dst, (sextloadi64i32 addr:$src))]>;
221
222def MOVZX64rr8 : RI<0xB6, MRMSrcReg, (ops GR64:$dst, GR8 :$src),
223 "movz{bq|x} {$src, $dst|$dst, $src}",
224 [(set GR64:$dst, (zext GR8:$src))]>, TB;
225def MOVZX64rm8 : RI<0xB6, MRMSrcMem, (ops GR64:$dst, i8mem :$src),
226 "movz{bq|x} {$src, $dst|$dst, $src}",
227 [(set GR64:$dst, (zextloadi64i8 addr:$src))]>, TB;
228def MOVZX64rr16: RI<0xB7, MRMSrcReg, (ops GR64:$dst, GR16:$src),
229 "movz{wq|x} {$src, $dst|$dst, $src}",
230 [(set GR64:$dst, (zext GR16:$src))]>, TB;
231def MOVZX64rm16: RI<0xB7, MRMSrcMem, (ops GR64:$dst, i16mem:$src),
232 "movz{wq|x} {$src, $dst|$dst, $src}",
233 [(set GR64:$dst, (zextloadi64i16 addr:$src))]>, TB;
234
235def CDQE : RI<0x98, RawFrm, (ops),
236 "{cltq|cdqe}", []>, Imp<[EAX],[RAX]>; // RAX = signext(EAX)
237
238def CQO : RI<0x99, RawFrm, (ops),
239 "{cqto|cqo}", []>, Imp<[RAX],[RAX,RDX]>; // RDX:RAX = signext(RAX)
240
241//===----------------------------------------------------------------------===//
242// Arithmetic Instructions...
243//
244
245let isTwoAddress = 1 in {
246let isConvertibleToThreeAddress = 1 in {
247let isCommutable = 1 in
248def ADD64rr : RI<0x01, MRMDestReg, (ops GR64:$dst, GR64:$src1, GR64:$src2),
249 "add{q} {$src2, $dst|$dst, $src2}",
250 [(set GR64:$dst, (add GR64:$src1, GR64:$src2))]>;
251
252def ADD64ri32 : RIi32<0x81, MRM0r, (ops GR64:$dst, GR64:$src1, i64i32imm:$src2),
253 "add{q} {$src2, $dst|$dst, $src2}",
254 [(set GR64:$dst, (add GR64:$src1, i64immSExt32:$src2))]>;
255def ADD64ri8 : RIi8<0x83, MRM0r, (ops GR64:$dst, GR64:$src1, i64i8imm:$src2),
256 "add{q} {$src2, $dst|$dst, $src2}",
257 [(set GR64:$dst, (add GR64:$src1, i64immSExt8:$src2))]>;
258} // isConvertibleToThreeAddress
259
260def ADD64rm : RI<0x03, MRMSrcMem, (ops GR64:$dst, GR64:$src1, i64mem:$src2),
261 "add{q} {$src2, $dst|$dst, $src2}",
262 [(set GR64:$dst, (add GR64:$src1, (load addr:$src2)))]>;
263} // isTwoAddress
264
265def ADD64mr : RI<0x01, MRMDestMem, (ops i64mem:$dst, GR64:$src2),
266 "add{q} {$src2, $dst|$dst, $src2}",
267 [(store (add (load addr:$dst), GR64:$src2), addr:$dst)]>;
268def ADD64mi32 : RIi32<0x81, MRM0m, (ops i64mem:$dst, i64i32imm :$src2),
269 "add{q} {$src2, $dst|$dst, $src2}",
270 [(store (add (load addr:$dst), i64immSExt32:$src2), addr:$dst)]>;
271def ADD64mi8 : RIi8<0x83, MRM0m, (ops i64mem:$dst, i64i8imm :$src2),
272 "add{q} {$src2, $dst|$dst, $src2}",
273 [(store (add (load addr:$dst), i64immSExt8:$src2), addr:$dst)]>;
274
275let isTwoAddress = 1 in {
276let isCommutable = 1 in
277def ADC64rr : RI<0x11, MRMDestReg, (ops GR64:$dst, GR64:$src1, GR64:$src2),
278 "adc{q} {$src2, $dst|$dst, $src2}",
279 [(set GR64:$dst, (adde GR64:$src1, GR64:$src2))]>;
280
281def ADC64rm : RI<0x13, MRMSrcMem , (ops GR64:$dst, GR64:$src1, i64mem:$src2),
282 "adc{q} {$src2, $dst|$dst, $src2}",
283 [(set GR64:$dst, (adde GR64:$src1, (load addr:$src2)))]>;
284
285def ADC64ri32 : RIi32<0x81, MRM2r, (ops GR64:$dst, GR64:$src1, i64i32imm:$src2),
286 "adc{q} {$src2, $dst|$dst, $src2}",
287 [(set GR64:$dst, (adde GR64:$src1, i64immSExt32:$src2))]>;
288def ADC64ri8 : RIi8<0x83, MRM2r, (ops GR64:$dst, GR64:$src1, i64i8imm:$src2),
289 "adc{q} {$src2, $dst|$dst, $src2}",
290 [(set GR64:$dst, (adde GR64:$src1, i64immSExt8:$src2))]>;
291} // isTwoAddress
292
293def ADC64mr : RI<0x11, MRMDestMem, (ops i64mem:$dst, GR64:$src2),
294 "adc{q} {$src2, $dst|$dst, $src2}",
295 [(store (adde (load addr:$dst), GR64:$src2), addr:$dst)]>;
296def ADC64mi32 : RIi32<0x81, MRM2m, (ops i64mem:$dst, i64i32imm:$src2),
297 "adc{q} {$src2, $dst|$dst, $src2}",
298 [(store (adde (load addr:$dst), i64immSExt8:$src2), addr:$dst)]>;
299def ADC64mi8 : RIi8<0x83, MRM2m, (ops i64mem:$dst, i64i8imm :$src2),
300 "adc{q} {$src2, $dst|$dst, $src2}",
301 [(store (adde (load addr:$dst), i64immSExt8:$src2), addr:$dst)]>;
302
303let isTwoAddress = 1 in {
304def SUB64rr : RI<0x29, MRMDestReg, (ops GR64:$dst, GR64:$src1, GR64:$src2),
305 "sub{q} {$src2, $dst|$dst, $src2}",
306 [(set GR64:$dst, (sub GR64:$src1, GR64:$src2))]>;
307
308def SUB64rm : RI<0x2B, MRMSrcMem, (ops GR64:$dst, GR64:$src1, i64mem:$src2),
309 "sub{q} {$src2, $dst|$dst, $src2}",
310 [(set GR64:$dst, (sub GR64:$src1, (load addr:$src2)))]>;
311
312def SUB64ri32 : RIi32<0x81, MRM5r, (ops GR64:$dst, GR64:$src1, i64i32imm:$src2),
313 "sub{q} {$src2, $dst|$dst, $src2}",
314 [(set GR64:$dst, (sub GR64:$src1, i64immSExt32:$src2))]>;
315def SUB64ri8 : RIi8<0x83, MRM5r, (ops GR64:$dst, GR64:$src1, i64i8imm:$src2),
316 "sub{q} {$src2, $dst|$dst, $src2}",
317 [(set GR64:$dst, (sub GR64:$src1, i64immSExt8:$src2))]>;
318} // isTwoAddress
319
320def SUB64mr : RI<0x29, MRMDestMem, (ops i64mem:$dst, GR64:$src2),
321 "sub{q} {$src2, $dst|$dst, $src2}",
322 [(store (sub (load addr:$dst), GR64:$src2), addr:$dst)]>;
323def SUB64mi32 : RIi32<0x81, MRM5m, (ops i64mem:$dst, i64i32imm:$src2),
324 "sub{q} {$src2, $dst|$dst, $src2}",
325 [(store (sub (load addr:$dst), i64immSExt32:$src2), addr:$dst)]>;
326def SUB64mi8 : RIi8<0x83, MRM5m, (ops i64mem:$dst, i64i8imm :$src2),
327 "sub{q} {$src2, $dst|$dst, $src2}",
328 [(store (sub (load addr:$dst), i64immSExt8:$src2), addr:$dst)]>;
329
330let isTwoAddress = 1 in {
331def SBB64rr : RI<0x19, MRMDestReg, (ops GR64:$dst, GR64:$src1, GR64:$src2),
332 "sbb{q} {$src2, $dst|$dst, $src2}",
333 [(set GR64:$dst, (sube GR64:$src1, GR64:$src2))]>;
334
335def SBB64rm : RI<0x1B, MRMSrcMem, (ops GR64:$dst, GR64:$src1, i64mem:$src2),
336 "sbb{q} {$src2, $dst|$dst, $src2}",
337 [(set GR64:$dst, (sube GR64:$src1, (load addr:$src2)))]>;
338
339def SBB64ri32 : RIi32<0x81, MRM3r, (ops GR64:$dst, GR64:$src1, i64i32imm:$src2),
340 "sbb{q} {$src2, $dst|$dst, $src2}",
341 [(set GR64:$dst, (sube GR64:$src1, i64immSExt32:$src2))]>;
342def SBB64ri8 : RIi8<0x83, MRM3r, (ops GR64:$dst, GR64:$src1, i64i8imm:$src2),
343 "sbb{q} {$src2, $dst|$dst, $src2}",
344 [(set GR64:$dst, (sube GR64:$src1, i64immSExt8:$src2))]>;
345} // isTwoAddress
346
347def SBB64mr : RI<0x19, MRMDestMem, (ops i64mem:$dst, GR64:$src2),
348 "sbb{q} {$src2, $dst|$dst, $src2}",
349 [(store (sube (load addr:$dst), GR64:$src2), addr:$dst)]>;
350def SBB64mi32 : RIi32<0x81, MRM3m, (ops i64mem:$dst, i64i32imm:$src2),
351 "sbb{q} {$src2, $dst|$dst, $src2}",
352 [(store (sube (load addr:$dst), i64immSExt32:$src2), addr:$dst)]>;
353def SBB64mi8 : RIi8<0x83, MRM3m, (ops i64mem:$dst, i64i8imm :$src2),
354 "sbb{q} {$src2, $dst|$dst, $src2}",
355 [(store (sube (load addr:$dst), i64immSExt8:$src2), addr:$dst)]>;
356
357// Unsigned multiplication
358def MUL64r : RI<0xF7, MRM4r, (ops GR64:$src),
359 "mul{q} $src", []>,
360 Imp<[RAX],[RAX,RDX]>; // RAX,RDX = RAX*GR64
361def MUL64m : RI<0xF7, MRM4m, (ops i64mem:$src),
362 "mul{q} $src", []>,
363 Imp<[RAX],[RAX,RDX]>; // RAX,RDX = RAX*[mem64]
364
365// Signed multiplication
366def IMUL64r : RI<0xF7, MRM5r, (ops GR64:$src),
367 "imul{q} $src", []>,
368 Imp<[RAX],[RAX,RDX]>; // RAX,RDX = RAX*GR64
369def IMUL64m : RI<0xF7, MRM5m, (ops i64mem:$src),
370 "imul{q} $src", []>,
371 Imp<[RAX],[RAX,RDX]>; // RAX,RDX = RAX*[mem64]
372
373let isTwoAddress = 1 in {
374let isCommutable = 1 in
375def IMUL64rr : RI<0xAF, MRMSrcReg, (ops GR64:$dst, GR64:$src1, GR64:$src2),
376 "imul{q} {$src2, $dst|$dst, $src2}",
377 [(set GR64:$dst, (mul GR64:$src1, GR64:$src2))]>, TB;
378
379def IMUL64rm : RI<0xAF, MRMSrcMem, (ops GR64:$dst, GR64:$src1, i64mem:$src2),
380 "imul{q} {$src2, $dst|$dst, $src2}",
381 [(set GR64:$dst, (mul GR64:$src1, (load addr:$src2)))]>, TB;
382} // isTwoAddress
383
384// Suprisingly enough, these are not two address instructions!
385def IMUL64rri32 : RIi32<0x69, MRMSrcReg, // GR64 = GR64*I32
386 (ops GR64:$dst, GR64:$src1, i64i32imm:$src2),
387 "imul{q} {$src2, $src1, $dst|$dst, $src1, $src2}",
388 [(set GR64:$dst, (mul GR64:$src1, i64immSExt32:$src2))]>;
389def IMUL64rri8 : RIi8<0x6B, MRMSrcReg, // GR64 = GR64*I8
390 (ops GR64:$dst, GR64:$src1, i64i8imm:$src2),
391 "imul{q} {$src2, $src1, $dst|$dst, $src1, $src2}",
392 [(set GR64:$dst, (mul GR64:$src1, i64immSExt8:$src2))]>;
393def IMUL64rmi32 : RIi32<0x69, MRMSrcMem, // GR64 = [mem64]*I32
394 (ops GR64:$dst, i64mem:$src1, i64i32imm:$src2),
395 "imul{q} {$src2, $src1, $dst|$dst, $src1, $src2}",
396 [(set GR64:$dst, (mul (load addr:$src1), i64immSExt32:$src2))]>;
397def IMUL64rmi8 : RIi8<0x6B, MRMSrcMem, // GR64 = [mem64]*I8
398 (ops GR64:$dst, i64mem:$src1, i64i8imm: $src2),
399 "imul{q} {$src2, $src1, $dst|$dst, $src1, $src2}",
400 [(set GR64:$dst, (mul (load addr:$src1), i64immSExt8:$src2))]>;
401
402// Unsigned division / remainder
403def DIV64r : RI<0xF7, MRM6r, (ops GR64:$src), // RDX:RAX/r64 = RAX,RDX
404 "div{q} $src", []>, Imp<[RAX,RDX],[RAX,RDX]>;
405def DIV64m : RI<0xF7, MRM6m, (ops i64mem:$src), // RDX:RAX/[mem64] = RAX,RDX
406 "div{q} $src", []>, Imp<[RAX,RDX],[RAX,RDX]>;
407
408// Signed division / remainder
409def IDIV64r: RI<0xF7, MRM7r, (ops GR64:$src), // RDX:RAX/r64 = RAX,RDX
410 "idiv{q} $src", []>, Imp<[RAX,RDX],[RAX,RDX]>;
411def IDIV64m: RI<0xF7, MRM7m, (ops i64mem:$src), // RDX:RAX/[mem64] = RAX,RDX
412 "idiv{q} $src", []>, Imp<[RAX,RDX],[RAX,RDX]>;
413
414// Unary instructions
415let CodeSize = 2 in {
416let isTwoAddress = 1 in
417def NEG64r : RI<0xF7, MRM3r, (ops GR64:$dst, GR64:$src), "neg{q} $dst",
418 [(set GR64:$dst, (ineg GR64:$src))]>;
419def NEG64m : RI<0xF7, MRM3m, (ops i64mem:$dst), "neg{q} $dst",
420 [(store (ineg (loadi64 addr:$dst)), addr:$dst)]>;
421
422let isTwoAddress = 1, isConvertibleToThreeAddress = 1 in
423def INC64r : RI<0xFF, MRM0r, (ops GR64:$dst, GR64:$src), "inc{q} $dst",
424 [(set GR64:$dst, (add GR64:$src, 1))]>;
425def INC64m : RI<0xFF, MRM0m, (ops i64mem:$dst), "inc{q} $dst",
426 [(store (add (loadi64 addr:$dst), 1), addr:$dst)]>;
427
428let isTwoAddress = 1, isConvertibleToThreeAddress = 1 in
429def DEC64r : RI<0xFF, MRM1r, (ops GR64:$dst, GR64:$src), "dec{q} $dst",
430 [(set GR64:$dst, (add GR64:$src, -1))]>;
431def DEC64m : RI<0xFF, MRM1m, (ops i64mem:$dst), "dec{q} $dst",
432 [(store (add (loadi64 addr:$dst), -1), addr:$dst)]>;
433
434// In 64-bit mode, single byte INC and DEC cannot be encoded.
435let isTwoAddress = 1, isConvertibleToThreeAddress = 1 in {
436// Can transform into LEA.
437def INC64_16r : I<0xFF, MRM0r, (ops GR16:$dst, GR16:$src), "inc{w} $dst",
438 [(set GR16:$dst, (add GR16:$src, 1))]>,
439 OpSize, Requires<[In64BitMode]>;
440def INC64_32r : I<0xFF, MRM0r, (ops GR32:$dst, GR32:$src), "inc{l} $dst",
441 [(set GR32:$dst, (add GR32:$src, 1))]>,
442 Requires<[In64BitMode]>;
443def DEC64_16r : I<0xFF, MRM1r, (ops GR16:$dst, GR16:$src), "dec{w} $dst",
444 [(set GR16:$dst, (add GR16:$src, -1))]>,
445 OpSize, Requires<[In64BitMode]>;
446def DEC64_32r : I<0xFF, MRM1r, (ops GR32:$dst, GR32:$src), "dec{l} $dst",
447 [(set GR32:$dst, (add GR32:$src, -1))]>,
448 Requires<[In64BitMode]>;
449} // isConvertibleToThreeAddress
450} // CodeSize
451
452
453// Shift instructions
454let isTwoAddress = 1 in {
455def SHL64rCL : RI<0xD3, MRM4r, (ops GR64:$dst, GR64:$src),
456 "shl{q} {%cl, $dst|$dst, %CL}",
457 [(set GR64:$dst, (shl GR64:$src, CL))]>,
458 Imp<[CL],[]>;
459def SHL64ri : RIi8<0xC1, MRM4r, (ops GR64:$dst, GR64:$src1, i8imm:$src2),
460 "shl{q} {$src2, $dst|$dst, $src2}",
461 [(set GR64:$dst, (shl GR64:$src1, (i8 imm:$src2)))]>;
462def SHL64r1 : RI<0xD1, MRM4r, (ops GR64:$dst, GR64:$src1),
463 "shl{q} $dst", []>;
464} // isTwoAddress
465
466def SHL64mCL : RI<0xD3, MRM4m, (ops i64mem:$dst),
467 "shl{q} {%cl, $dst|$dst, %CL}",
468 [(store (shl (loadi64 addr:$dst), CL), addr:$dst)]>,
469 Imp<[CL],[]>;
470def SHL64mi : RIi8<0xC1, MRM4m, (ops i64mem:$dst, i8imm:$src),
471 "shl{q} {$src, $dst|$dst, $src}",
472 [(store (shl (loadi64 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
473def SHL64m1 : RI<0xD1, MRM4m, (ops i64mem:$dst),
474 "shl{q} $dst",
475 [(store (shl (loadi64 addr:$dst), (i8 1)), addr:$dst)]>;
476
477let isTwoAddress = 1 in {
478def SHR64rCL : RI<0xD3, MRM5r, (ops GR64:$dst, GR64:$src),
479 "shr{q} {%cl, $dst|$dst, %CL}",
480 [(set GR64:$dst, (srl GR64:$src, CL))]>,
481 Imp<[CL],[]>;
482def SHR64ri : RIi8<0xC1, MRM5r, (ops GR64:$dst, GR64:$src1, i8imm:$src2),
483 "shr{q} {$src2, $dst|$dst, $src2}",
484 [(set GR64:$dst, (srl GR64:$src1, (i8 imm:$src2)))]>;
485def SHR64r1 : RI<0xD1, MRM5r, (ops GR64:$dst, GR64:$src1),
486 "shr{q} $dst",
487 [(set GR64:$dst, (srl GR64:$src1, (i8 1)))]>;
488} // isTwoAddress
489
490def SHR64mCL : RI<0xD3, MRM5m, (ops i64mem:$dst),
491 "shr{q} {%cl, $dst|$dst, %CL}",
492 [(store (srl (loadi64 addr:$dst), CL), addr:$dst)]>,
493 Imp<[CL],[]>;
494def SHR64mi : RIi8<0xC1, MRM5m, (ops i64mem:$dst, i8imm:$src),
495 "shr{q} {$src, $dst|$dst, $src}",
496 [(store (srl (loadi64 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
497def SHR64m1 : RI<0xD1, MRM5m, (ops i64mem:$dst),
498 "shr{q} $dst",
499 [(store (srl (loadi64 addr:$dst), (i8 1)), addr:$dst)]>;
500
501let isTwoAddress = 1 in {
502def SAR64rCL : RI<0xD3, MRM7r, (ops GR64:$dst, GR64:$src),
503 "sar{q} {%cl, $dst|$dst, %CL}",
504 [(set GR64:$dst, (sra GR64:$src, CL))]>, Imp<[CL],[]>;
505def SAR64ri : RIi8<0xC1, MRM7r, (ops GR64:$dst, GR64:$src1, i8imm:$src2),
506 "sar{q} {$src2, $dst|$dst, $src2}",
507 [(set GR64:$dst, (sra GR64:$src1, (i8 imm:$src2)))]>;
508def SAR64r1 : RI<0xD1, MRM7r, (ops GR64:$dst, GR64:$src1),
509 "sar{q} $dst",
510 [(set GR64:$dst, (sra GR64:$src1, (i8 1)))]>;
511} // isTwoAddress
512
513def SAR64mCL : RI<0xD3, MRM7m, (ops i64mem:$dst),
514 "sar{q} {%cl, $dst|$dst, %CL}",
515 [(store (sra (loadi64 addr:$dst), CL), addr:$dst)]>,
516 Imp<[CL],[]>;
517def SAR64mi : RIi8<0xC1, MRM7m, (ops i64mem:$dst, i8imm:$src),
518 "sar{q} {$src, $dst|$dst, $src}",
519 [(store (sra (loadi64 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
520def SAR64m1 : RI<0xD1, MRM7m, (ops i64mem:$dst),
521 "sar{q} $dst",
522 [(store (sra (loadi64 addr:$dst), (i8 1)), addr:$dst)]>;
523
524// Rotate instructions
525let isTwoAddress = 1 in {
526def ROL64rCL : RI<0xD3, MRM0r, (ops GR64:$dst, GR64:$src),
527 "rol{q} {%cl, $dst|$dst, %CL}",
528 [(set GR64:$dst, (rotl GR64:$src, CL))]>, Imp<[CL],[]>;
529def ROL64ri : RIi8<0xC1, MRM0r, (ops GR64:$dst, GR64:$src1, i8imm:$src2),
530 "rol{q} {$src2, $dst|$dst, $src2}",
531 [(set GR64:$dst, (rotl GR64:$src1, (i8 imm:$src2)))]>;
532def ROL64r1 : RI<0xD1, MRM0r, (ops GR64:$dst, GR64:$src1),
533 "rol{q} $dst",
534 [(set GR64:$dst, (rotl GR64:$src1, (i8 1)))]>;
535} // isTwoAddress
536
537def ROL64mCL : I<0xD3, MRM0m, (ops i64mem:$dst),
538 "rol{q} {%cl, $dst|$dst, %CL}",
539 [(store (rotl (loadi64 addr:$dst), CL), addr:$dst)]>,
540 Imp<[CL],[]>;
541def ROL64mi : RIi8<0xC1, MRM0m, (ops i64mem:$dst, i8imm:$src),
542 "rol{q} {$src, $dst|$dst, $src}",
543 [(store (rotl (loadi64 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
544def ROL64m1 : RI<0xD1, MRM0m, (ops i64mem:$dst),
545 "rol{q} $dst",
546 [(store (rotl (loadi64 addr:$dst), (i8 1)), addr:$dst)]>;
547
548let isTwoAddress = 1 in {
549def ROR64rCL : RI<0xD3, MRM1r, (ops GR64:$dst, GR64:$src),
550 "ror{q} {%cl, $dst|$dst, %CL}",
551 [(set GR64:$dst, (rotr GR64:$src, CL))]>, Imp<[CL],[]>;
552def ROR64ri : RIi8<0xC1, MRM1r, (ops GR64:$dst, GR64:$src1, i8imm:$src2),
553 "ror{q} {$src2, $dst|$dst, $src2}",
554 [(set GR64:$dst, (rotr GR64:$src1, (i8 imm:$src2)))]>;
555def ROR64r1 : RI<0xD1, MRM1r, (ops GR64:$dst, GR64:$src1),
556 "ror{q} $dst",
557 [(set GR64:$dst, (rotr GR64:$src1, (i8 1)))]>;
558} // isTwoAddress
559
560def ROR64mCL : RI<0xD3, MRM1m, (ops i64mem:$dst),
561 "ror{q} {%cl, $dst|$dst, %CL}",
562 [(store (rotr (loadi64 addr:$dst), CL), addr:$dst)]>,
563 Imp<[CL],[]>;
564def ROR64mi : RIi8<0xC1, MRM1m, (ops i64mem:$dst, i8imm:$src),
565 "ror{q} {$src, $dst|$dst, $src}",
566 [(store (rotr (loadi64 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
567def ROR64m1 : RI<0xD1, MRM1m, (ops i64mem:$dst),
568 "ror{q} $dst",
569 [(store (rotr (loadi64 addr:$dst), (i8 1)), addr:$dst)]>;
570
571// Double shift instructions (generalizations of rotate)
572let isTwoAddress = 1 in {
573def SHLD64rrCL : RI<0xA5, MRMDestReg, (ops GR64:$dst, GR64:$src1, GR64:$src2),
574 "shld{q} {%cl, $src2, $dst|$dst, $src2, %CL}", []>,
575 Imp<[CL],[]>, TB;
576def SHRD64rrCL : RI<0xAD, MRMDestReg, (ops GR64:$dst, GR64:$src1, GR64:$src2),
577 "shrd{q} {%cl, $src2, $dst|$dst, $src2, %CL}", []>,
578 Imp<[CL],[]>, TB;
579
580let isCommutable = 1 in { // FIXME: Update X86InstrInfo::commuteInstruction
581def SHLD64rri8 : RIi8<0xA4, MRMDestReg,
582 (ops GR64:$dst, GR64:$src1, GR64:$src2, i8imm:$src3),
583 "shld{q} {$src3, $src2, $dst|$dst, $src2, $src3}", []>,
584 TB;
585def SHRD64rri8 : RIi8<0xAC, MRMDestReg,
586 (ops GR64:$dst, GR64:$src1, GR64:$src2, i8imm:$src3),
587 "shrd{q} {$src3, $src2, $dst|$dst, $src2, $src3}", []>,
588 TB;
589} // isCommutable
590} // isTwoAddress
591
592// Temporary hack: there is no patterns associated with these instructions
593// so we have to tell tblgen that these do not produce results.
594let noResults = 1 in {
595def SHLD64mrCL : RI<0xA5, MRMDestMem, (ops i64mem:$dst, GR64:$src2),
596 "shld{q} {%cl, $src2, $dst|$dst, $src2, %CL}", []>,
597 Imp<[CL],[]>, TB;
598def SHRD64mrCL : RI<0xAD, MRMDestMem, (ops i64mem:$dst, GR64:$src2),
599 "shrd{q} {%cl, $src2, $dst|$dst, $src2, %CL}", []>,
600 Imp<[CL],[]>, TB;
601def SHLD64mri8 : RIi8<0xA4, MRMDestMem,
602 (ops i64mem:$dst, GR64:$src2, i8imm:$src3),
603 "shld{q} {$src3, $src2, $dst|$dst, $src2, $src3}", []>,
604 TB;
605def SHRD64mri8 : RIi8<0xAC, MRMDestMem,
606 (ops i64mem:$dst, GR64:$src2, i8imm:$src3),
607 "shrd{q} {$src3, $src2, $dst|$dst, $src2, $src3}", []>,
608 TB;
609} // noResults
610
611//===----------------------------------------------------------------------===//
612// Logical Instructions...
613//
614
615let isTwoAddress = 1 in
616def NOT64r : RI<0xF7, MRM2r, (ops GR64:$dst, GR64:$src), "not{q} $dst",
617 [(set GR64:$dst, (not GR64:$src))]>;
618def NOT64m : RI<0xF7, MRM2m, (ops i64mem:$dst), "not{q} $dst",
619 [(store (not (loadi64 addr:$dst)), addr:$dst)]>;
620
621let isTwoAddress = 1 in {
622let isCommutable = 1 in
623def AND64rr : RI<0x21, MRMDestReg,
624 (ops GR64:$dst, GR64:$src1, GR64:$src2),
625 "and{q} {$src2, $dst|$dst, $src2}",
626 [(set GR64:$dst, (and GR64:$src1, GR64:$src2))]>;
627def AND64rm : RI<0x23, MRMSrcMem,
628 (ops GR64:$dst, GR64:$src1, i64mem:$src2),
629 "and{q} {$src2, $dst|$dst, $src2}",
630 [(set GR64:$dst, (and GR64:$src1, (load addr:$src2)))]>;
631def AND64ri32 : RIi32<0x81, MRM4r,
632 (ops GR64:$dst, GR64:$src1, i64i32imm:$src2),
633 "and{q} {$src2, $dst|$dst, $src2}",
634 [(set GR64:$dst, (and GR64:$src1, i64immSExt32:$src2))]>;
635def AND64ri8 : RIi8<0x83, MRM4r,
636 (ops GR64:$dst, GR64:$src1, i64i8imm:$src2),
637 "and{q} {$src2, $dst|$dst, $src2}",
638 [(set GR64:$dst, (and GR64:$src1, i64immSExt8:$src2))]>;
639} // isTwoAddress
640
641def AND64mr : RI<0x21, MRMDestMem,
642 (ops i64mem:$dst, GR64:$src),
643 "and{q} {$src, $dst|$dst, $src}",
644 [(store (and (load addr:$dst), GR64:$src), addr:$dst)]>;
645def AND64mi32 : RIi32<0x81, MRM4m,
646 (ops i64mem:$dst, i64i32imm:$src),
647 "and{q} {$src, $dst|$dst, $src}",
648 [(store (and (loadi64 addr:$dst), i64immSExt32:$src), addr:$dst)]>;
649def AND64mi8 : RIi8<0x83, MRM4m,
650 (ops i64mem:$dst, i64i8imm :$src),
651 "and{q} {$src, $dst|$dst, $src}",
652 [(store (and (load addr:$dst), i64immSExt8:$src), addr:$dst)]>;
653
654let isTwoAddress = 1 in {
655let isCommutable = 1 in
656def OR64rr : RI<0x09, MRMDestReg, (ops GR64:$dst, GR64:$src1, GR64:$src2),
657 "or{q} {$src2, $dst|$dst, $src2}",
658 [(set GR64:$dst, (or GR64:$src1, GR64:$src2))]>;
659def OR64rm : RI<0x0B, MRMSrcMem , (ops GR64:$dst, GR64:$src1, i64mem:$src2),
660 "or{q} {$src2, $dst|$dst, $src2}",
661 [(set GR64:$dst, (or GR64:$src1, (load addr:$src2)))]>;
662def OR64ri32 : RIi32<0x81, MRM1r, (ops GR64:$dst, GR64:$src1, i64i32imm:$src2),
663 "or{q} {$src2, $dst|$dst, $src2}",
664 [(set GR64:$dst, (or GR64:$src1, i64immSExt32:$src2))]>;
665def OR64ri8 : RIi8<0x83, MRM1r, (ops GR64:$dst, GR64:$src1, i64i8imm:$src2),
666 "or{q} {$src2, $dst|$dst, $src2}",
667 [(set GR64:$dst, (or GR64:$src1, i64immSExt8:$src2))]>;
668} // isTwoAddress
669
670def OR64mr : RI<0x09, MRMDestMem, (ops i64mem:$dst, GR64:$src),
671 "or{q} {$src, $dst|$dst, $src}",
672 [(store (or (load addr:$dst), GR64:$src), addr:$dst)]>;
673def OR64mi32 : RIi32<0x81, MRM1m, (ops i64mem:$dst, i64i32imm:$src),
674 "or{q} {$src, $dst|$dst, $src}",
675 [(store (or (loadi64 addr:$dst), i64immSExt32:$src), addr:$dst)]>;
676def OR64mi8 : RIi8<0x83, MRM1m, (ops i64mem:$dst, i64i8imm:$src),
677 "or{q} {$src, $dst|$dst, $src}",
678 [(store (or (load addr:$dst), i64immSExt8:$src), addr:$dst)]>;
679
680let isTwoAddress = 1 in {
681let isCommutable = 1 in
682def XOR64rr : RI<0x31, MRMDestReg, (ops GR64:$dst, GR64:$src1, GR64:$src2),
683 "xor{q} {$src2, $dst|$dst, $src2}",
684 [(set GR64:$dst, (xor GR64:$src1, GR64:$src2))]>;
685def XOR64rm : RI<0x33, MRMSrcMem, (ops GR64:$dst, GR64:$src1, i64mem:$src2),
686 "xor{q} {$src2, $dst|$dst, $src2}",
687 [(set GR64:$dst, (xor GR64:$src1, (load addr:$src2)))]>;
688def XOR64ri32 : RIi32<0x81, MRM6r,
689 (ops GR64:$dst, GR64:$src1, i64i32imm:$src2),
690 "xor{q} {$src2, $dst|$dst, $src2}",
691 [(set GR64:$dst, (xor GR64:$src1, i64immSExt32:$src2))]>;
692def XOR64ri8 : RIi8<0x83, MRM6r, (ops GR64:$dst, GR64:$src1, i64i8imm:$src2),
693 "xor{q} {$src2, $dst|$dst, $src2}",
694 [(set GR64:$dst, (xor GR64:$src1, i64immSExt8:$src2))]>;
695} // isTwoAddress
696
697def XOR64mr : RI<0x31, MRMDestMem, (ops i64mem:$dst, GR64:$src),
698 "xor{q} {$src, $dst|$dst, $src}",
699 [(store (xor (load addr:$dst), GR64:$src), addr:$dst)]>;
700def XOR64mi32 : RIi32<0x81, MRM6m, (ops i64mem:$dst, i64i32imm:$src),
701 "xor{q} {$src, $dst|$dst, $src}",
702 [(store (xor (loadi64 addr:$dst), i64immSExt32:$src), addr:$dst)]>;
703def XOR64mi8 : RIi8<0x83, MRM6m, (ops i64mem:$dst, i64i8imm :$src),
704 "xor{q} {$src, $dst|$dst, $src}",
705 [(store (xor (load addr:$dst), i64immSExt8:$src), addr:$dst)]>;
706
707//===----------------------------------------------------------------------===//
708// Comparison Instructions...
709//
710
711// Integer comparison
712let isCommutable = 1 in
713def TEST64rr : RI<0x85, MRMDestReg, (ops GR64:$src1, GR64:$src2),
714 "test{q} {$src2, $src1|$src1, $src2}",
715 [(X86cmp (and GR64:$src1, GR64:$src2), 0)]>;
716def TEST64rm : RI<0x85, MRMSrcMem, (ops GR64:$src1, i64mem:$src2),
717 "test{q} {$src2, $src1|$src1, $src2}",
718 [(X86cmp (and GR64:$src1, (loadi64 addr:$src2)), 0)]>;
719def TEST64ri32 : RIi32<0xF7, MRM0r, (ops GR64:$src1, i64i32imm:$src2),
720 "test{q} {$src2, $src1|$src1, $src2}",
721 [(X86cmp (and GR64:$src1, i64immSExt32:$src2), 0)]>;
722def TEST64mi32 : RIi32<0xF7, MRM0m, (ops i64mem:$src1, i64i32imm:$src2),
723 "test{q} {$src2, $src1|$src1, $src2}",
724 [(X86cmp (and (loadi64 addr:$src1), i64immSExt32:$src2), 0)]>;
725
726def CMP64rr : RI<0x39, MRMDestReg, (ops GR64:$src1, GR64:$src2),
727 "cmp{q} {$src2, $src1|$src1, $src2}",
728 [(X86cmp GR64:$src1, GR64:$src2)]>;
729def CMP64mr : RI<0x39, MRMDestMem, (ops i64mem:$src1, GR64:$src2),
730 "cmp{q} {$src2, $src1|$src1, $src2}",
731 [(X86cmp (loadi64 addr:$src1), GR64:$src2)]>;
732def CMP64rm : RI<0x3B, MRMSrcMem, (ops GR64:$src1, i64mem:$src2),
733 "cmp{q} {$src2, $src1|$src1, $src2}",
734 [(X86cmp GR64:$src1, (loadi64 addr:$src2))]>;
735def CMP64ri32 : RIi32<0x81, MRM7r, (ops GR64:$src1, i64i32imm:$src2),
736 "cmp{q} {$src2, $src1|$src1, $src2}",
737 [(X86cmp GR64:$src1, i64immSExt32:$src2)]>;
738def CMP64mi32 : RIi32<0x81, MRM7m, (ops i64mem:$src1, i64i32imm:$src2),
739 "cmp{q} {$src2, $src1|$src1, $src2}",
740 [(X86cmp (loadi64 addr:$src1), i64immSExt32:$src2)]>;
741def CMP64mi8 : RIi8<0x83, MRM7m, (ops i64mem:$src1, i64i8imm:$src2),
742 "cmp{q} {$src2, $src1|$src1, $src2}",
743 [(X86cmp (loadi64 addr:$src1), i64immSExt8:$src2)]>;
744def CMP64ri8 : RIi8<0x83, MRM7r, (ops GR64:$src1, i64i8imm:$src2),
745 "cmp{q} {$src2, $src1|$src1, $src2}",
746 [(X86cmp GR64:$src1, i64immSExt8:$src2)]>;
747
748// Conditional moves
749let isTwoAddress = 1 in {
750def CMOVB64rr : RI<0x42, MRMSrcReg, // if <u, GR64 = GR64
751 (ops GR64:$dst, GR64:$src1, GR64:$src2),
752 "cmovb {$src2, $dst|$dst, $src2}",
753 [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2,
754 X86_COND_B))]>, TB;
755def CMOVB64rm : RI<0x42, MRMSrcMem, // if <u, GR64 = [mem64]
756 (ops GR64:$dst, GR64:$src1, i64mem:$src2),
757 "cmovb {$src2, $dst|$dst, $src2}",
758 [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
759 X86_COND_B))]>, TB;
760def CMOVAE64rr: RI<0x43, MRMSrcReg, // if >=u, GR64 = GR64
761 (ops GR64:$dst, GR64:$src1, GR64:$src2),
762 "cmovae {$src2, $dst|$dst, $src2}",
763 [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2,
764 X86_COND_AE))]>, TB;
765def CMOVAE64rm: RI<0x43, MRMSrcMem, // if >=u, GR64 = [mem64]
766 (ops GR64:$dst, GR64:$src1, i64mem:$src2),
767 "cmovae {$src2, $dst|$dst, $src2}",
768 [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
769 X86_COND_AE))]>, TB;
770def CMOVE64rr : RI<0x44, MRMSrcReg, // if ==, GR64 = GR64
771 (ops GR64:$dst, GR64:$src1, GR64:$src2),
772 "cmove {$src2, $dst|$dst, $src2}",
773 [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2,
774 X86_COND_E))]>, TB;
775def CMOVE64rm : RI<0x44, MRMSrcMem, // if ==, GR64 = [mem64]
776 (ops GR64:$dst, GR64:$src1, i64mem:$src2),
777 "cmove {$src2, $dst|$dst, $src2}",
778 [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
779 X86_COND_E))]>, TB;
780def CMOVNE64rr: RI<0x45, MRMSrcReg, // if !=, GR64 = GR64
781 (ops GR64:$dst, GR64:$src1, GR64:$src2),
782 "cmovne {$src2, $dst|$dst, $src2}",
783 [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2,
784 X86_COND_NE))]>, TB;
785def CMOVNE64rm: RI<0x45, MRMSrcMem, // if !=, GR64 = [mem64]
786 (ops GR64:$dst, GR64:$src1, i64mem:$src2),
787 "cmovne {$src2, $dst|$dst, $src2}",
788 [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
789 X86_COND_NE))]>, TB;
790def CMOVBE64rr: RI<0x46, MRMSrcReg, // if <=u, GR64 = GR64
791 (ops GR64:$dst, GR64:$src1, GR64:$src2),
792 "cmovbe {$src2, $dst|$dst, $src2}",
793 [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2,
794 X86_COND_BE))]>, TB;
795def CMOVBE64rm: RI<0x46, MRMSrcMem, // if <=u, GR64 = [mem64]
796 (ops GR64:$dst, GR64:$src1, i64mem:$src2),
797 "cmovbe {$src2, $dst|$dst, $src2}",
798 [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
799 X86_COND_BE))]>, TB;
800def CMOVA64rr : RI<0x47, MRMSrcReg, // if >u, GR64 = GR64
801 (ops GR64:$dst, GR64:$src1, GR64:$src2),
802 "cmova {$src2, $dst|$dst, $src2}",
803 [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2,
804 X86_COND_A))]>, TB;
805def CMOVA64rm : RI<0x47, MRMSrcMem, // if >u, GR64 = [mem64]
806 (ops GR64:$dst, GR64:$src1, i64mem:$src2),
807 "cmova {$src2, $dst|$dst, $src2}",
808 [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
809 X86_COND_A))]>, TB;
810def CMOVL64rr : RI<0x4C, MRMSrcReg, // if <s, GR64 = GR64
811 (ops GR64:$dst, GR64:$src1, GR64:$src2),
812 "cmovl {$src2, $dst|$dst, $src2}",
813 [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2,
814 X86_COND_L))]>, TB;
815def CMOVL64rm : RI<0x4C, MRMSrcMem, // if <s, GR64 = [mem64]
816 (ops GR64:$dst, GR64:$src1, i64mem:$src2),
817 "cmovl {$src2, $dst|$dst, $src2}",
818 [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
819 X86_COND_L))]>, TB;
820def CMOVGE64rr: RI<0x4D, MRMSrcReg, // if >=s, GR64 = GR64
821 (ops GR64:$dst, GR64:$src1, GR64:$src2),
822 "cmovge {$src2, $dst|$dst, $src2}",
823 [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2,
824 X86_COND_GE))]>, TB;
825def CMOVGE64rm: RI<0x4D, MRMSrcMem, // if >=s, GR64 = [mem64]
826 (ops GR64:$dst, GR64:$src1, i64mem:$src2),
827 "cmovge {$src2, $dst|$dst, $src2}",
828 [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
829 X86_COND_GE))]>, TB;
830def CMOVLE64rr: RI<0x4E, MRMSrcReg, // if <=s, GR64 = GR64
831 (ops GR64:$dst, GR64:$src1, GR64:$src2),
832 "cmovle {$src2, $dst|$dst, $src2}",
833 [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2,
834 X86_COND_LE))]>, TB;
835def CMOVLE64rm: RI<0x4E, MRMSrcMem, // if <=s, GR64 = [mem64]
836 (ops GR64:$dst, GR64:$src1, i64mem:$src2),
837 "cmovle {$src2, $dst|$dst, $src2}",
838 [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
839 X86_COND_LE))]>, TB;
840def CMOVG64rr : RI<0x4F, MRMSrcReg, // if >s, GR64 = GR64
841 (ops GR64:$dst, GR64:$src1, GR64:$src2),
842 "cmovg {$src2, $dst|$dst, $src2}",
843 [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2,
844 X86_COND_G))]>, TB;
845def CMOVG64rm : RI<0x4F, MRMSrcMem, // if >s, GR64 = [mem64]
846 (ops GR64:$dst, GR64:$src1, i64mem:$src2),
847 "cmovg {$src2, $dst|$dst, $src2}",
848 [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
849 X86_COND_G))]>, TB;
850def CMOVS64rr : RI<0x48, MRMSrcReg, // if signed, GR64 = GR64
851 (ops GR64:$dst, GR64:$src1, GR64:$src2),
852 "cmovs {$src2, $dst|$dst, $src2}",
853 [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2,
854 X86_COND_S))]>, TB;
855def CMOVS64rm : RI<0x48, MRMSrcMem, // if signed, GR64 = [mem64]
856 (ops GR64:$dst, GR64:$src1, i64mem:$src2),
857 "cmovs {$src2, $dst|$dst, $src2}",
858 [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
859 X86_COND_S))]>, TB;
860def CMOVNS64rr: RI<0x49, MRMSrcReg, // if !signed, GR64 = GR64
861 (ops GR64:$dst, GR64:$src1, GR64:$src2),
862 "cmovns {$src2, $dst|$dst, $src2}",
863 [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2,
864 X86_COND_NS))]>, TB;
865def CMOVNS64rm: RI<0x49, MRMSrcMem, // if !signed, GR64 = [mem64]
866 (ops GR64:$dst, GR64:$src1, i64mem:$src2),
867 "cmovns {$src2, $dst|$dst, $src2}",
868 [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
869 X86_COND_NS))]>, TB;
870def CMOVP64rr : RI<0x4A, MRMSrcReg, // if parity, GR64 = GR64
871 (ops GR64:$dst, GR64:$src1, GR64:$src2),
872 "cmovp {$src2, $dst|$dst, $src2}",
873 [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2,
874 X86_COND_P))]>, TB;
875def CMOVP64rm : RI<0x4A, MRMSrcMem, // if parity, GR64 = [mem64]
876 (ops GR64:$dst, GR64:$src1, i64mem:$src2),
877 "cmovp {$src2, $dst|$dst, $src2}",
878 [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
879 X86_COND_P))]>, TB;
880def CMOVNP64rr : RI<0x4B, MRMSrcReg, // if !parity, GR64 = GR64
881 (ops GR64:$dst, GR64:$src1, GR64:$src2),
882 "cmovnp {$src2, $dst|$dst, $src2}",
883 [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2,
884 X86_COND_NP))]>, TB;
885def CMOVNP64rm : RI<0x4B, MRMSrcMem, // if !parity, GR64 = [mem64]
886 (ops GR64:$dst, GR64:$src1, i64mem:$src2),
887 "cmovnp {$src2, $dst|$dst, $src2}",
888 [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
889 X86_COND_NP))]>, TB;
890} // isTwoAddress
891
892//===----------------------------------------------------------------------===//
893// Conversion Instructions...
894//
895
896// f64 -> signed i64
897def Int_CVTSD2SI64rr: RSDI<0x2D, MRMSrcReg, (ops GR64:$dst, VR128:$src),
898 "cvtsd2si{q} {$src, $dst|$dst, $src}",
899 []>; // TODO: add intrinsic
900def Int_CVTSD2SI64rm: RSDI<0x2D, MRMSrcMem, (ops GR64:$dst, f128mem:$src),
901 "cvtsd2si{q} {$src, $dst|$dst, $src}",
902 []>; // TODO: add intrinsic
903def CVTTSD2SI64rr: RSDI<0x2C, MRMSrcReg, (ops GR64:$dst, FR64:$src),
904 "cvttsd2si{q} {$src, $dst|$dst, $src}",
905 [(set GR64:$dst, (fp_to_sint FR64:$src))]>;
906def CVTTSD2SI64rm: RSDI<0x2C, MRMSrcMem, (ops GR64:$dst, f64mem:$src),
907 "cvttsd2si{q} {$src, $dst|$dst, $src}",
908 [(set GR64:$dst, (fp_to_sint (loadf64 addr:$src)))]>;
909def Int_CVTTSD2SI64rr: RSDI<0x2C, MRMSrcReg, (ops GR64:$dst, VR128:$src),
910 "cvttsd2si{q} {$src, $dst|$dst, $src}",
911 []>; // TODO: add intrinsic
912def Int_CVTTSD2SI64rm: RSDI<0x2C, MRMSrcMem, (ops GR64:$dst, f128mem:$src),
913 "cvttsd2si{q} {$src, $dst|$dst, $src}",
914 []>; // TODO: add intrinsic
915
916// Signed i64 -> f64
917def CVTSI2SD64rr: RSDI<0x2A, MRMSrcReg, (ops FR64:$dst, GR64:$src),
918 "cvtsi2sd{q} {$src, $dst|$dst, $src}",
919 [(set FR64:$dst, (sint_to_fp GR64:$src))]>;
920def CVTSI2SD64rm: RSDI<0x2A, MRMSrcMem, (ops FR64:$dst, i64mem:$src),
921 "cvtsi2sd{q} {$src, $dst|$dst, $src}",
922 [(set FR64:$dst, (sint_to_fp (loadi64 addr:$src)))]>;
923let isTwoAddress = 1 in {
924def Int_CVTSI2SD64rr: RSDI<0x2A, MRMSrcReg,
925 (ops VR128:$dst, VR128:$src1, GR64:$src2),
926 "cvtsi2sd{q} {$src2, $dst|$dst, $src2}",
927 []>; // TODO: add intrinsic
928def Int_CVTSI2SD64rm: RSDI<0x2A, MRMSrcMem,
929 (ops VR128:$dst, VR128:$src1, i64mem:$src2),
930 "cvtsi2sd{q} {$src2, $dst|$dst, $src2}",
931 []>; // TODO: add intrinsic
932} // isTwoAddress
933
934// Signed i64 -> f32
935def CVTSI2SS64rr: RSSI<0x2A, MRMSrcReg, (ops FR32:$dst, GR64:$src),
936 "cvtsi2ss{q} {$src, $dst|$dst, $src}",
937 [(set FR32:$dst, (sint_to_fp GR64:$src))]>;
938def CVTSI2SS64rm: RSSI<0x2A, MRMSrcMem, (ops FR32:$dst, i64mem:$src),
939 "cvtsi2ss{q} {$src, $dst|$dst, $src}",
940 [(set FR32:$dst, (sint_to_fp (loadi64 addr:$src)))]>;
941let isTwoAddress = 1 in {
942def Int_CVTSI2SS64rr: RSSI<0x2A, MRMSrcReg,
943 (ops VR128:$dst, VR128:$src1, GR64:$src2),
944 "cvtsi2ss{q} {$src2, $dst|$dst, $src2}",
945 []>; // TODO: add intrinsic
946def Int_CVTSI2SS64rm: RSSI<0x2A, MRMSrcMem,
947 (ops VR128:$dst, VR128:$src1, i64mem:$src2),
948 "cvtsi2ss{q} {$src2, $dst|$dst, $src2}",
949 []>; // TODO: add intrinsic
950} // isTwoAddress
951
952// f32 -> signed i64
953def Int_CVTSS2SI64rr: RSSI<0x2D, MRMSrcReg, (ops GR64:$dst, VR128:$src),
954 "cvtss2si{q} {$src, $dst|$dst, $src}",
955 []>; // TODO: add intrinsic
956def Int_CVTSS2SI64rm: RSSI<0x2D, MRMSrcMem, (ops GR64:$dst, f32mem:$src),
957 "cvtss2si{q} {$src, $dst|$dst, $src}",
958 []>; // TODO: add intrinsic
959def CVTTSS2SI64rr: RSSI<0x2C, MRMSrcReg, (ops GR64:$dst, FR32:$src),
960 "cvttss2si{q} {$src, $dst|$dst, $src}",
961 [(set GR64:$dst, (fp_to_sint FR32:$src))]>;
962def CVTTSS2SI64rm: RSSI<0x2C, MRMSrcMem, (ops GR64:$dst, f32mem:$src),
963 "cvttss2si{q} {$src, $dst|$dst, $src}",
964 [(set GR64:$dst, (fp_to_sint (loadf32 addr:$src)))]>;
965def Int_CVTTSS2SI64rr: RSSI<0x2C, MRMSrcReg, (ops GR64:$dst, VR128:$src),
966 "cvttss2si{q} {$src, $dst|$dst, $src}",
967 []>; // TODO: add intrinsic
968def Int_CVTTSS2SI64rm: RSSI<0x2C, MRMSrcMem, (ops GR64:$dst, f32mem:$src),
969 "cvttss2si{q} {$src, $dst|$dst, $src}",
970 []>; // TODO: add intrinsic
971
972//===----------------------------------------------------------------------===//
973// Alias Instructions
974//===----------------------------------------------------------------------===//
975
976// Truncate
977// In 64-mode, each 64-bit and 32-bit registers has a low 8-bit sub-register.
978def TRUNC_64to8 : I<0x88, MRMDestReg, (ops GR8:$dst, GR64:$src),
979 "mov{b} {${src:subreg8}, $dst|$dst, ${src:subreg8}",
980 [(set GR8:$dst, (trunc GR64:$src))]>;
981def TRUNC_32to8 : I<0x88, MRMDestReg, (ops GR8:$dst, GR32:$src),
982 "mov{b} {${src:subreg8}, $dst|$dst, ${src:subreg8}",
983 [(set GR8:$dst, (trunc GR32:$src))]>,
984 Requires<[In64BitMode]>;
985def TRUNC_16to8 : I<0x88, MRMDestReg, (ops GR8:$dst, GR16:$src),
986 "mov{b} {${src:subreg8}, $dst|$dst, ${src:subreg8}}",
987 [(set GR8:$dst, (trunc GR16:$src))]>,
988 Requires<[In64BitMode]>;
989
990def TRUNC_64to16 : I<0x89, MRMDestReg, (ops GR16:$dst, GR64:$src),
991 "mov{w} {${src:subreg16}, $dst|$dst, ${src:subreg16}}",
992 [(set GR16:$dst, (trunc GR64:$src))]>;
993
994def TRUNC_64to32 : I<0x89, MRMDestReg, (ops GR32:$dst, GR64:$src),
995 "mov{l} {${src:subreg32}, $dst|$dst, ${src:subreg32}}",
996 [(set GR32:$dst, (trunc GR64:$src))]>;
997
998// Zero-extension
999// TODO: Remove this after proper i32 -> i64 zext support.
1000def PsMOVZX64rr32: I<0x89, MRMDestReg, (ops GR64:$dst, GR32:$src),
1001 "mov{l} {$src, ${dst:subreg32}|${dst:subreg32}, $src}",
1002 [(set GR64:$dst, (zext GR32:$src))]>;
1003def PsMOVZX64rm32: I<0x8B, MRMSrcMem, (ops GR64:$dst, i32mem:$src),
1004 "mov{l} {$src, ${dst:subreg32}|${dst:subreg32}, $src}",
1005 [(set GR64:$dst, (zextloadi64i32 addr:$src))]>;
1006
1007
1008// Alias instructions that map movr0 to xor.
1009// FIXME: remove when we can teach regalloc that xor reg, reg is ok.
1010// FIXME: AddedComplexity gives MOV64r0 a higher priority than MOV64ri32. Remove
1011// when we have a better way to specify isel priority.
1012let AddedComplexity = 1 in
1013def MOV64r0 : RI<0x31, MRMInitReg, (ops GR64:$dst),
1014 "xor{q} $dst, $dst",
1015 [(set GR64:$dst, 0)]>;
1016
1017// Materialize i64 constant where top 32-bits are zero.
1018let AddedComplexity = 1 in
1019def MOV64ri64i32 : Ii32<0xB8, AddRegFrm, (ops GR64:$dst, i64i32imm:$src),
1020 "mov{l} {$src, ${dst:subreg32}|${dst:subreg32}, $src}",
1021 [(set GR64:$dst, i64immZExt32:$src)]>;
1022
1023//===----------------------------------------------------------------------===//
1024// Non-Instruction Patterns
1025//===----------------------------------------------------------------------===//
1026
1027// ConstantPool GlobalAddress, ExternalSymbol, and JumpTable
1028def : Pat<(i64 (X86Wrapper tconstpool :$dst)),
1029 (MOV64ri tconstpool :$dst)>, Requires<[NotSmallCode]>;
1030def : Pat<(i64 (X86Wrapper tjumptable :$dst)),
1031 (MOV64ri tjumptable :$dst)>, Requires<[NotSmallCode]>;
1032def : Pat<(i64 (X86Wrapper tglobaladdr :$dst)),
1033 (MOV64ri tglobaladdr :$dst)>, Requires<[NotSmallCode]>;
1034def : Pat<(i64 (X86Wrapper texternalsym:$dst)),
1035 (MOV64ri texternalsym:$dst)>, Requires<[NotSmallCode]>;
1036
1037def : Pat<(store (i64 (X86Wrapper tconstpool:$src)), addr:$dst),
1038 (MOV64mi32 addr:$dst, tconstpool:$src)>,
1039 Requires<[SmallCode, IsStatic]>;
1040def : Pat<(store (i64 (X86Wrapper tjumptable:$src)), addr:$dst),
1041 (MOV64mi32 addr:$dst, tjumptable:$src)>,
1042 Requires<[SmallCode, IsStatic]>;
1043def : Pat<(store (i64 (X86Wrapper tglobaladdr:$src)), addr:$dst),
1044 (MOV64mi32 addr:$dst, tglobaladdr:$src)>,
1045 Requires<[SmallCode, IsStatic]>;
1046def : Pat<(store (i64 (X86Wrapper texternalsym:$src)), addr:$dst),
1047 (MOV64mi32 addr:$dst, texternalsym:$src)>,
1048 Requires<[SmallCode, IsStatic]>;
1049
1050// Calls
1051// Direct PC relative function call for small code model. 32-bit displacement
1052// sign extended to 64-bit.
1053def : Pat<(X86call (i64 tglobaladdr:$dst)),
1054 (CALL64pcrel32 tglobaladdr:$dst)>;
1055def : Pat<(X86call (i64 texternalsym:$dst)),
1056 (CALL64pcrel32 texternalsym:$dst)>;
1057
1058def : Pat<(X86tailcall (i64 tglobaladdr:$dst)),
1059 (CALL64pcrel32 tglobaladdr:$dst)>;
1060def : Pat<(X86tailcall (i64 texternalsym:$dst)),
1061 (CALL64pcrel32 texternalsym:$dst)>;
1062
1063def : Pat<(X86tailcall GR64:$dst),
1064 (CALL64r GR64:$dst)>;
1065
1066// {s|z}extload bool -> {s|z}extload byte
1067def : Pat<(sextloadi64i1 addr:$src), (MOVSX64rm8 addr:$src)>;
1068def : Pat<(zextloadi64i1 addr:$src), (MOVZX64rm8 addr:$src)>;
1069
1070// extload
1071def : Pat<(extloadi64i1 addr:$src), (MOVZX64rm8 addr:$src)>;
1072def : Pat<(extloadi64i8 addr:$src), (MOVZX64rm8 addr:$src)>;
1073def : Pat<(extloadi64i16 addr:$src), (MOVZX64rm16 addr:$src)>;
1074def : Pat<(extloadi64i32 addr:$src), (PsMOVZX64rm32 addr:$src)>;
1075
1076// anyext -> zext
1077def : Pat<(i64 (anyext GR8 :$src)), (MOVZX64rr8 GR8 :$src)>;
1078def : Pat<(i64 (anyext GR16:$src)), (MOVZX64rr16 GR16:$src)>;
1079def : Pat<(i64 (anyext GR32:$src)), (PsMOVZX64rr32 GR32:$src)>;
1080def : Pat<(i64 (anyext (loadi8 addr:$src))), (MOVZX64rm8 addr:$src)>;
1081def : Pat<(i64 (anyext (loadi16 addr:$src))), (MOVZX64rm16 addr:$src)>;
1082def : Pat<(i64 (anyext (loadi32 addr:$src))), (PsMOVZX64rm32 addr:$src)>;
1083
1084//===----------------------------------------------------------------------===//
1085// Some peepholes
1086//===----------------------------------------------------------------------===//
1087
1088// (shl x, 1) ==> (add x, x)
1089def : Pat<(shl GR64:$src1, (i8 1)), (ADD64rr GR64:$src1, GR64:$src1)>;
1090
1091// (or (x >> c) | (y << (64 - c))) ==> (shrd64 x, y, c)
1092def : Pat<(or (srl GR64:$src1, CL:$amt),
1093 (shl GR64:$src2, (sub 64, CL:$amt))),
1094 (SHRD64rrCL GR64:$src1, GR64:$src2)>;
1095
1096def : Pat<(store (or (srl (loadi64 addr:$dst), CL:$amt),
1097 (shl GR64:$src2, (sub 64, CL:$amt))), addr:$dst),
1098 (SHRD64mrCL addr:$dst, GR64:$src2)>;
1099
1100// (or (x << c) | (y >> (64 - c))) ==> (shld64 x, y, c)
1101def : Pat<(or (shl GR64:$src1, CL:$amt),
1102 (srl GR64:$src2, (sub 64, CL:$amt))),
1103 (SHLD64rrCL GR64:$src1, GR64:$src2)>;
1104
1105def : Pat<(store (or (shl (loadi64 addr:$dst), CL:$amt),
1106 (srl GR64:$src2, (sub 64, CL:$amt))), addr:$dst),
1107 (SHLD64mrCL addr:$dst, GR64:$src2)>;
1108
1109// X86 specific add which produces a flag.
1110def : Pat<(addc GR64:$src1, GR64:$src2),
1111 (ADD64rr GR64:$src1, GR64:$src2)>;
1112def : Pat<(addc GR64:$src1, (load addr:$src2)),
1113 (ADD64rm GR64:$src1, addr:$src2)>;
1114def : Pat<(addc GR64:$src1, i64immSExt32:$src2),
1115 (ADD64ri32 GR64:$src1, imm:$src2)>;
1116def : Pat<(addc GR64:$src1, i64immSExt8:$src2),
1117 (ADD64ri8 GR64:$src1, i64immSExt8:$src2)>;
1118
1119def : Pat<(subc GR64:$src1, GR64:$src2),
1120 (SUB64rr GR64:$src1, GR64:$src2)>;
1121def : Pat<(subc GR64:$src1, (load addr:$src2)),
1122 (SUB64rm GR64:$src1, addr:$src2)>;
1123def : Pat<(subc GR64:$src1, imm:$src2),
1124 (SUB64ri32 GR64:$src1, i64immSExt32:$src2)>;
1125def : Pat<(subc GR64:$src1, i64immSExt8:$src2),
1126 (SUB64ri8 GR64:$src1, i64immSExt8:$src2)>;
1127
1128
1129//===----------------------------------------------------------------------===//
1130// X86-64 SSE Instructions
1131//===----------------------------------------------------------------------===//
1132
1133// Move instructions...
1134
1135def MOV64toPQIrr : RPDI<0x6E, MRMSrcReg, (ops VR128:$dst, GR64:$src),
1136 "mov{d|q} {$src, $dst|$dst, $src}",
1137 [(set VR128:$dst,
1138 (v2i64 (scalar_to_vector GR64:$src)))]>;
1139def MOV64toPQIrm : RPDI<0x6E, MRMSrcMem, (ops VR128:$dst, i64mem:$src),
1140 "mov{d|q} {$src, $dst|$dst, $src}",
1141 [(set VR128:$dst,
1142 (v2i64 (scalar_to_vector (loadi64 addr:$src))))]>;
1143
1144def MOVPQIto64rr : RPDI<0x7E, MRMDestReg, (ops GR64:$dst, VR128:$src),
1145 "mov{d|q} {$src, $dst|$dst, $src}",
1146 [(set GR64:$dst, (vector_extract (v2i64 VR128:$src),
1147 (iPTR 0)))]>;
1148def MOVPQIto64mr : RPDI<0x7E, MRMDestMem, (ops i64mem:$dst, VR128:$src),
1149 "mov{d|q} {$src, $dst|$dst, $src}",
1150 [(store (i64 (vector_extract (v2i64 VR128:$src),
1151 (iPTR 0))), addr:$dst)]>;
1152
1153def MOV64toSDrr : RPDI<0x6E, MRMSrcReg, (ops FR64:$dst, GR64:$src),
1154 "mov{d|q} {$src, $dst|$dst, $src}",
1155 [(set FR64:$dst, (bitconvert GR64:$src))]>;
1156def MOV64toSDrm : RPDI<0x6E, MRMSrcMem, (ops FR64:$dst, i64mem:$src),
1157 "mov{d|q} {$src, $dst|$dst, $src}",
1158 [(set FR64:$dst, (bitconvert (loadi64 addr:$src)))]>;
1159
1160def MOVSDto64rr : RPDI<0x7E, MRMDestReg, (ops GR64:$dst, FR64:$src),
1161 "mov{d|q} {$src, $dst|$dst, $src}",
1162 [(set GR64:$dst, (bitconvert FR64:$src))]>;
1163def MOVSDto64mr : RPDI<0x7E, MRMDestMem, (ops i64mem:$dst, FR64:$src),
1164 "mov{d|q} {$src, $dst|$dst, $src}",
1165 [(store (i64 (bitconvert FR64:$src)), addr:$dst)]>;