0544d362c3d82c4f74fb4a6f8bebf4d7b5867f76
[oota-llvm.git] / lib / Target / X86 / X86Instr64bit.td
1 //====- X86Instr64bit.td - Describe X86-64 Instructions ----*- tablegen -*-===//
2 // 
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // 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.
21 def i64i32imm  : Operand<i64>;
22
23 // 64-bits but only 32 bits are significant, and those bits are treated as being
24 // pc relative.
25 def i64i32imm_pcrel : Operand<i64> {
26   let PrintMethod = "print_pcrel_imm";
27 }
28
29
30 // 64-bits but only 8 bits are significant.
31 def i64i8imm   : Operand<i64>;
32
33 def lea64mem : Operand<i64> {
34   let PrintMethod = "printlea64mem";
35   let MIOperandInfo = (ops GR64, i8imm, GR64, i32imm);
36 }
37
38 def lea64_32mem : Operand<i32> {
39   let PrintMethod = "printlea64_32mem";
40   let AsmOperandLowerMethod = "lower_lea64_32mem";
41   let MIOperandInfo = (ops GR32, i8imm, GR32, i32imm);
42 }
43
44 //===----------------------------------------------------------------------===//
45 // Complex Pattern Definitions.
46 //
47 def lea64addr : ComplexPattern<i64, 4, "SelectLEAAddr",
48                         [add, mul, X86mul_imm, shl, or, frameindex, X86Wrapper],
49                         []>;
50
51 //===----------------------------------------------------------------------===//
52 // Pattern fragments.
53 //
54
55 def i64immSExt8  : PatLeaf<(i64 imm), [{
56   // i64immSExt8 predicate - True if the 64-bit immediate fits in a 8-bit
57   // sign extended field.
58   return (int64_t)N->getZExtValue() == (int8_t)N->getZExtValue();
59 }]>;
60
61 def i64immSExt32  : PatLeaf<(i64 imm), [{
62   // i64immSExt32 predicate - True if the 64-bit immediate fits in a 32-bit
63   // sign extended field.
64   return (int64_t)N->getZExtValue() == (int32_t)N->getZExtValue();
65 }]>;
66
67 def i64immZExt32  : PatLeaf<(i64 imm), [{
68   // i64immZExt32 predicate - True if the 64-bit immediate fits in a 32-bit
69   // unsignedsign extended field.
70   return (uint64_t)N->getZExtValue() == (uint32_t)N->getZExtValue();
71 }]>;
72
73 def sextloadi64i8  : PatFrag<(ops node:$ptr), (i64 (sextloadi8 node:$ptr))>;
74 def sextloadi64i16 : PatFrag<(ops node:$ptr), (i64 (sextloadi16 node:$ptr))>;
75 def sextloadi64i32 : PatFrag<(ops node:$ptr), (i64 (sextloadi32 node:$ptr))>;
76
77 def zextloadi64i1  : PatFrag<(ops node:$ptr), (i64 (zextloadi1 node:$ptr))>;
78 def zextloadi64i8  : PatFrag<(ops node:$ptr), (i64 (zextloadi8 node:$ptr))>;
79 def zextloadi64i16 : PatFrag<(ops node:$ptr), (i64 (zextloadi16 node:$ptr))>;
80 def zextloadi64i32 : PatFrag<(ops node:$ptr), (i64 (zextloadi32 node:$ptr))>;
81
82 def extloadi64i1   : PatFrag<(ops node:$ptr), (i64 (extloadi1 node:$ptr))>;
83 def extloadi64i8   : PatFrag<(ops node:$ptr), (i64 (extloadi8 node:$ptr))>;
84 def extloadi64i16  : PatFrag<(ops node:$ptr), (i64 (extloadi16 node:$ptr))>;
85 def extloadi64i32  : PatFrag<(ops node:$ptr), (i64 (extloadi32 node:$ptr))>;
86
87 //===----------------------------------------------------------------------===//
88 // Instruction list...
89 //
90
91 // ADJCALLSTACKDOWN/UP implicitly use/def RSP because they may be expanded into
92 // a stack adjustment and the codegen must know that they may modify the stack
93 // pointer before prolog-epilog rewriting occurs.
94 // Pessimistically assume ADJCALLSTACKDOWN / ADJCALLSTACKUP will become
95 // sub / add which can clobber EFLAGS.
96 let Defs = [RSP, EFLAGS], Uses = [RSP] in {
97 def ADJCALLSTACKDOWN64 : I<0, Pseudo, (outs), (ins i32imm:$amt),
98                            "#ADJCALLSTACKDOWN",
99                            [(X86callseq_start timm:$amt)]>,
100                           Requires<[In64BitMode]>;
101 def ADJCALLSTACKUP64   : I<0, Pseudo, (outs), (ins i32imm:$amt1, i32imm:$amt2),
102                            "#ADJCALLSTACKUP",
103                            [(X86callseq_end timm:$amt1, timm:$amt2)]>,
104                           Requires<[In64BitMode]>;
105 }
106
107 //===----------------------------------------------------------------------===//
108 //  Call Instructions...
109 //
110 let isCall = 1 in
111   // All calls clobber the non-callee saved registers. RSP is marked as
112   // a use to prevent stack-pointer assignments that appear immediately
113   // before calls from potentially appearing dead. Uses for argument
114   // registers are added manually.
115   let Defs = [RAX, RCX, RDX, RSI, RDI, R8, R9, R10, R11,
116               FP0, FP1, FP2, FP3, FP4, FP5, FP6, ST0, ST1,
117               MM0, MM1, MM2, MM3, MM4, MM5, MM6, MM7,
118               XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7,
119               XMM8, XMM9, XMM10, XMM11, XMM12, XMM13, XMM14, XMM15, EFLAGS],
120       Uses = [RSP] in {
121       
122     // NOTE: this pattern doesn't match "X86call imm", because we do not know
123     // that the offset between an arbitrary immediate and the call will fit in
124     // the 32-bit pcrel field that we have.
125     def CALL64pcrel32 : Ii32<0xE8, RawFrm,
126                           (outs), (ins i64i32imm_pcrel:$dst, variable_ops),
127                           "call\t$dst", []>,
128                         Requires<[In64BitMode]>;
129     def CALL64r       : I<0xFF, MRM2r, (outs), (ins GR64:$dst, variable_ops),
130                           "call\t{*}$dst", [(X86call GR64:$dst)]>;
131     def CALL64m       : I<0xFF, MRM2m, (outs), (ins i64mem:$dst, variable_ops),
132                           "call\t{*}$dst", [(X86call (loadi64 addr:$dst))]>;
133   }
134
135
136
137 let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in
138 def TCRETURNdi64 : I<0, Pseudo, (outs), (ins i64imm:$dst, i32imm:$offset,
139                                          variable_ops),
140                  "#TC_RETURN $dst $offset",
141                  []>;
142
143 let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in
144 def TCRETURNri64 : I<0, Pseudo, (outs), (ins GR64:$dst, i32imm:$offset,
145                                          variable_ops),
146                  "#TC_RETURN $dst $offset",
147                  []>;
148
149
150 let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in
151   def TAILJMPr64 : I<0xFF, MRM4r, (outs), (ins GR64:$dst),
152                    "jmp{q}\t{*}$dst  # TAILCALL",
153                    []>;     
154
155 // Branches
156 let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in {
157   def JMP64r     : I<0xFF, MRM4r, (outs), (ins GR64:$dst), "jmp{q}\t{*}$dst",
158                      [(brind GR64:$dst)]>;
159   def JMP64m     : I<0xFF, MRM4m, (outs), (ins i64mem:$dst), "jmp{q}\t{*}$dst",
160                      [(brind (loadi64 addr:$dst))]>;
161 }
162
163 //===----------------------------------------------------------------------===//
164 // EH Pseudo Instructions
165 //
166 let isTerminator = 1, isReturn = 1, isBarrier = 1,
167     hasCtrlDep = 1 in {
168 def EH_RETURN64   : I<0xC3, RawFrm, (outs), (ins GR64:$addr),
169                      "ret\t#eh_return, addr: $addr",
170                      [(X86ehret GR64:$addr)]>;
171
172 }
173
174 //===----------------------------------------------------------------------===//
175 //  Miscellaneous Instructions...
176 //
177 let Defs = [RBP,RSP], Uses = [RBP,RSP], mayLoad = 1, neverHasSideEffects = 1 in
178 def LEAVE64  : I<0xC9, RawFrm,
179                  (outs), (ins), "leave", []>;
180 let Defs = [RSP], Uses = [RSP], neverHasSideEffects=1 in {
181 let mayLoad = 1 in
182 def POP64r   : I<0x58, AddRegFrm,
183                  (outs GR64:$reg), (ins), "pop{q}\t$reg", []>;
184 let mayStore = 1 in
185 def PUSH64r  : I<0x50, AddRegFrm,
186                  (outs), (ins GR64:$reg), "push{q}\t$reg", []>;
187 }
188
189 let Defs = [RSP], Uses = [RSP], neverHasSideEffects = 1, mayStore = 1 in {
190 def PUSH64i8   : Ii8<0x6a, RawFrm, (outs), (ins i8imm:$imm), 
191                      "push{q}\t$imm", []>;
192 def PUSH64i16  : Ii16<0x68, RawFrm, (outs), (ins i16imm:$imm), 
193                       "push{q}\t$imm", []>;
194 def PUSH64i32  : Ii32<0x68, RawFrm, (outs), (ins i32imm:$imm), 
195                       "push{q}\t$imm", []>;
196 }
197
198 let Defs = [RSP, EFLAGS], Uses = [RSP], mayLoad = 1 in
199 def POPFQ    : I<0x9D, RawFrm, (outs), (ins), "popf", []>, REX_W;
200 let Defs = [RSP], Uses = [RSP, EFLAGS], mayStore = 1 in
201 def PUSHFQ   : I<0x9C, RawFrm, (outs), (ins), "pushf", []>;
202
203 def LEA64_32r : I<0x8D, MRMSrcMem,
204                   (outs GR32:$dst), (ins lea64_32mem:$src),
205                   "lea{l}\t{$src|$dst}, {$dst|$src}",
206                   [(set GR32:$dst, lea32addr:$src)]>, Requires<[In64BitMode]>;
207
208 let isReMaterializable = 1 in
209 def LEA64r   : RI<0x8D, MRMSrcMem, (outs GR64:$dst), (ins lea64mem:$src),
210                   "lea{q}\t{$src|$dst}, {$dst|$src}",
211                   [(set GR64:$dst, lea64addr:$src)]>;
212
213 let isTwoAddress = 1 in
214 def BSWAP64r : RI<0xC8, AddRegFrm, (outs GR64:$dst), (ins GR64:$src),
215                   "bswap{q}\t$dst", 
216                   [(set GR64:$dst, (bswap GR64:$src))]>, TB;
217
218 // Bit scan instructions.
219 let Defs = [EFLAGS] in {
220 def BSF64rr  : RI<0xBC, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
221                   "bsf{q}\t{$src, $dst|$dst, $src}",
222                   [(set GR64:$dst, (X86bsf GR64:$src)), (implicit EFLAGS)]>, TB;
223 def BSF64rm  : RI<0xBC, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
224                   "bsf{q}\t{$src, $dst|$dst, $src}",
225                   [(set GR64:$dst, (X86bsf (loadi64 addr:$src))),
226                    (implicit EFLAGS)]>, TB;
227
228 def BSR64rr  : RI<0xBD, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
229                   "bsr{q}\t{$src, $dst|$dst, $src}",
230                   [(set GR64:$dst, (X86bsr GR64:$src)), (implicit EFLAGS)]>, TB;
231 def BSR64rm  : RI<0xBD, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
232                   "bsr{q}\t{$src, $dst|$dst, $src}",
233                   [(set GR64:$dst, (X86bsr (loadi64 addr:$src))),
234                    (implicit EFLAGS)]>, TB;
235 } // Defs = [EFLAGS]
236
237 // Repeat string ops
238 let Defs = [RCX,RDI,RSI], Uses = [RCX,RDI,RSI] in
239 def REP_MOVSQ : RI<0xA5, RawFrm, (outs), (ins), "{rep;movsq|rep movsq}",
240                    [(X86rep_movs i64)]>, REP;
241 let Defs = [RCX,RDI], Uses = [RAX,RCX,RDI] in
242 def REP_STOSQ : RI<0xAB, RawFrm, (outs), (ins), "{rep;stosq|rep stosq}",
243                    [(X86rep_stos i64)]>, REP;
244
245 //===----------------------------------------------------------------------===//
246 //  Move Instructions...
247 //
248
249 let neverHasSideEffects = 1 in
250 def MOV64rr : RI<0x89, MRMDestReg, (outs GR64:$dst), (ins GR64:$src),
251                  "mov{q}\t{$src, $dst|$dst, $src}", []>;
252
253 let isReMaterializable = 1, isAsCheapAsAMove = 1  in {
254 def MOV64ri : RIi64<0xB8, AddRegFrm, (outs GR64:$dst), (ins i64imm:$src),
255                     "movabs{q}\t{$src, $dst|$dst, $src}",
256                     [(set GR64:$dst, imm:$src)]>;
257 def MOV64ri32 : RIi32<0xC7, MRM0r, (outs GR64:$dst), (ins i64i32imm:$src),
258                       "mov{q}\t{$src, $dst|$dst, $src}",
259                       [(set GR64:$dst, i64immSExt32:$src)]>;
260 }
261
262 let canFoldAsLoad = 1 in
263 def MOV64rm : RI<0x8B, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
264                  "mov{q}\t{$src, $dst|$dst, $src}",
265                  [(set GR64:$dst, (load addr:$src))]>;
266
267 def MOV64mr : RI<0x89, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
268                  "mov{q}\t{$src, $dst|$dst, $src}",
269                  [(store GR64:$src, addr:$dst)]>;
270 def MOV64mi32 : RIi32<0xC7, MRM0m, (outs), (ins i64mem:$dst, i64i32imm:$src),
271                       "mov{q}\t{$src, $dst|$dst, $src}",
272                       [(store i64immSExt32:$src, addr:$dst)]>;
273
274 // Sign/Zero extenders
275
276 // MOVSX64rr8 always has a REX prefix and it has an 8-bit register
277 // operand, which makes it a rare instruction with an 8-bit register
278 // operand that can never access an h register. If support for h registers
279 // were generalized, this would require a special register class.
280 def MOVSX64rr8 : RI<0xBE, MRMSrcReg, (outs GR64:$dst), (ins GR8 :$src),
281                     "movs{bq|x}\t{$src, $dst|$dst, $src}",
282                     [(set GR64:$dst, (sext GR8:$src))]>, TB;
283 def MOVSX64rm8 : RI<0xBE, MRMSrcMem, (outs GR64:$dst), (ins i8mem :$src),
284                     "movs{bq|x}\t{$src, $dst|$dst, $src}",
285                     [(set GR64:$dst, (sextloadi64i8 addr:$src))]>, TB;
286 def MOVSX64rr16: RI<0xBF, MRMSrcReg, (outs GR64:$dst), (ins GR16:$src),
287                     "movs{wq|x}\t{$src, $dst|$dst, $src}",
288                     [(set GR64:$dst, (sext GR16:$src))]>, TB;
289 def MOVSX64rm16: RI<0xBF, MRMSrcMem, (outs GR64:$dst), (ins i16mem:$src),
290                     "movs{wq|x}\t{$src, $dst|$dst, $src}",
291                     [(set GR64:$dst, (sextloadi64i16 addr:$src))]>, TB;
292 def MOVSX64rr32: RI<0x63, MRMSrcReg, (outs GR64:$dst), (ins GR32:$src),
293                     "movs{lq|xd}\t{$src, $dst|$dst, $src}",
294                     [(set GR64:$dst, (sext GR32:$src))]>;
295 def MOVSX64rm32: RI<0x63, MRMSrcMem, (outs GR64:$dst), (ins i32mem:$src),
296                     "movs{lq|xd}\t{$src, $dst|$dst, $src}",
297                     [(set GR64:$dst, (sextloadi64i32 addr:$src))]>;
298
299 // Use movzbl instead of movzbq when the destination is a register; it's
300 // equivalent due to implicit zero-extending, and it has a smaller encoding.
301 def MOVZX64rr8 : I<0xB6, MRMSrcReg, (outs GR64:$dst), (ins GR8 :$src),
302                    "movz{bl|x}\t{$src, ${dst:subreg32}|${dst:subreg32}, $src}",
303                    [(set GR64:$dst, (zext GR8:$src))]>, TB;
304 def MOVZX64rm8 : I<0xB6, MRMSrcMem, (outs GR64:$dst), (ins i8mem :$src),
305                    "movz{bl|x}\t{$src, ${dst:subreg32}|${dst:subreg32}, $src}",
306                    [(set GR64:$dst, (zextloadi64i8 addr:$src))]>, TB;
307 // Use movzwl instead of movzwq when the destination is a register; it's
308 // equivalent due to implicit zero-extending, and it has a smaller encoding.
309 def MOVZX64rr16: I<0xB7, MRMSrcReg, (outs GR64:$dst), (ins GR16:$src),
310                    "movz{wl|x}\t{$src, ${dst:subreg32}|${dst:subreg32}, $src}",
311                    [(set GR64:$dst, (zext GR16:$src))]>, TB;
312 def MOVZX64rm16: I<0xB7, MRMSrcMem, (outs GR64:$dst), (ins i16mem:$src),
313                    "movz{wl|x}\t{$src, ${dst:subreg32}|${dst:subreg32}, $src}",
314                    [(set GR64:$dst, (zextloadi64i16 addr:$src))]>, TB;
315
316 // There's no movzlq instruction, but movl can be used for this purpose, using
317 // implicit zero-extension. The preferred way to do 32-bit-to-64-bit zero
318 // extension on x86-64 is to use a SUBREG_TO_REG to utilize implicit
319 // zero-extension, however this isn't possible when the 32-bit value is
320 // defined by a truncate or is copied from something where the high bits aren't
321 // necessarily all zero. In such cases, we fall back to these explicit zext
322 // instructions.
323 def MOVZX64rr32 : I<0x89, MRMDestReg, (outs GR64:$dst), (ins GR32:$src),
324                     "mov{l}\t{$src, ${dst:subreg32}|${dst:subreg32}, $src}",
325                     [(set GR64:$dst, (zext GR32:$src))]>;
326 def MOVZX64rm32 : I<0x8B, MRMSrcMem, (outs GR64:$dst), (ins i32mem:$src),
327                     "mov{l}\t{$src, ${dst:subreg32}|${dst:subreg32}, $src}",
328                     [(set GR64:$dst, (zextloadi64i32 addr:$src))]>;
329
330 // Any instruction that defines a 32-bit result leaves the high half of the
331 // register. Truncate can be lowered to EXTRACT_SUBREG, and CopyFromReg may
332 // be copying from a truncate, but any other 32-bit operation will zero-extend
333 // up to 64 bits.
334 def def32 : PatLeaf<(i32 GR32:$src), [{
335   return N->getOpcode() != ISD::TRUNCATE &&
336          N->getOpcode() != TargetInstrInfo::EXTRACT_SUBREG &&
337          N->getOpcode() != ISD::CopyFromReg;
338 }]>;
339
340 // In the case of a 32-bit def that is known to implicitly zero-extend,
341 // we can use a SUBREG_TO_REG.
342 def : Pat<(i64 (zext def32:$src)),
343           (SUBREG_TO_REG (i64 0), GR32:$src, x86_subreg_32bit)>;
344
345 let neverHasSideEffects = 1 in {
346   let Defs = [RAX], Uses = [EAX] in
347   def CDQE : RI<0x98, RawFrm, (outs), (ins),
348                "{cltq|cdqe}", []>;     // RAX = signext(EAX)
349
350   let Defs = [RAX,RDX], Uses = [RAX] in
351   def CQO  : RI<0x99, RawFrm, (outs), (ins),
352                 "{cqto|cqo}", []>; // RDX:RAX = signext(RAX)
353 }
354
355 //===----------------------------------------------------------------------===//
356 //  Arithmetic Instructions...
357 //
358
359 let Defs = [EFLAGS] in {
360 let isTwoAddress = 1 in {
361 let isConvertibleToThreeAddress = 1 in {
362 let isCommutable = 1 in
363 // Register-Register Addition
364 def ADD64rr    : RI<0x01, MRMDestReg, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
365                     "add{q}\t{$src2, $dst|$dst, $src2}",
366                     [(set GR64:$dst, (add GR64:$src1, GR64:$src2)),
367                      (implicit EFLAGS)]>;
368
369 // Register-Integer Addition
370 def ADD64ri8  : RIi8<0x83, MRM0r, (outs GR64:$dst), (ins GR64:$src1, i64i8imm:$src2),
371                      "add{q}\t{$src2, $dst|$dst, $src2}",
372                      [(set GR64:$dst, (add GR64:$src1, i64immSExt8:$src2)),
373                       (implicit EFLAGS)]>;
374 def ADD64ri32 : RIi32<0x81, MRM0r, (outs GR64:$dst), (ins GR64:$src1, i64i32imm:$src2),
375                       "add{q}\t{$src2, $dst|$dst, $src2}",
376                       [(set GR64:$dst, (add GR64:$src1, i64immSExt32:$src2)),
377                        (implicit EFLAGS)]>;
378 } // isConvertibleToThreeAddress
379
380 // Register-Memory Addition
381 def ADD64rm     : RI<0x03, MRMSrcMem, (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
382                      "add{q}\t{$src2, $dst|$dst, $src2}",
383                      [(set GR64:$dst, (add GR64:$src1, (load addr:$src2))),
384                       (implicit EFLAGS)]>;
385 } // isTwoAddress
386
387 // Memory-Register Addition
388 def ADD64mr  : RI<0x01, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src2),
389                   "add{q}\t{$src2, $dst|$dst, $src2}",
390                   [(store (add (load addr:$dst), GR64:$src2), addr:$dst),
391                    (implicit EFLAGS)]>;
392 def ADD64mi8 : RIi8<0x83, MRM0m, (outs), (ins i64mem:$dst, i64i8imm :$src2),
393                     "add{q}\t{$src2, $dst|$dst, $src2}",
394                 [(store (add (load addr:$dst), i64immSExt8:$src2), addr:$dst),
395                  (implicit EFLAGS)]>;
396 def ADD64mi32 : RIi32<0x81, MRM0m, (outs), (ins i64mem:$dst, i64i32imm :$src2),
397                       "add{q}\t{$src2, $dst|$dst, $src2}",
398                [(store (add (load addr:$dst), i64immSExt32:$src2), addr:$dst),
399                 (implicit EFLAGS)]>;
400
401 let Uses = [EFLAGS] in {
402 let isTwoAddress = 1 in {
403 let isCommutable = 1 in
404 def ADC64rr  : RI<0x11, MRMDestReg, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
405                   "adc{q}\t{$src2, $dst|$dst, $src2}",
406                   [(set GR64:$dst, (adde GR64:$src1, GR64:$src2))]>;
407
408 def ADC64rm  : RI<0x13, MRMSrcMem , (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
409                   "adc{q}\t{$src2, $dst|$dst, $src2}",
410                   [(set GR64:$dst, (adde GR64:$src1, (load addr:$src2)))]>;
411
412 def ADC64ri8 : RIi8<0x83, MRM2r, (outs GR64:$dst), (ins GR64:$src1, i64i8imm:$src2),
413                     "adc{q}\t{$src2, $dst|$dst, $src2}",
414                     [(set GR64:$dst, (adde GR64:$src1, i64immSExt8:$src2))]>;
415 def ADC64ri32 : RIi32<0x81, MRM2r, (outs GR64:$dst), (ins GR64:$src1, i64i32imm:$src2),
416                       "adc{q}\t{$src2, $dst|$dst, $src2}",
417                       [(set GR64:$dst, (adde GR64:$src1, i64immSExt32:$src2))]>;
418 } // isTwoAddress
419
420 def ADC64mr  : RI<0x11, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src2),
421                   "adc{q}\t{$src2, $dst|$dst, $src2}",
422                   [(store (adde (load addr:$dst), GR64:$src2), addr:$dst)]>;
423 def ADC64mi8 : RIi8<0x83, MRM2m, (outs), (ins i64mem:$dst, i64i8imm :$src2),
424                     "adc{q}\t{$src2, $dst|$dst, $src2}",
425                  [(store (adde (load addr:$dst), i64immSExt8:$src2), addr:$dst)]>;
426 def ADC64mi32 : RIi32<0x81, MRM2m, (outs), (ins i64mem:$dst, i64i32imm:$src2),
427                       "adc{q}\t{$src2, $dst|$dst, $src2}",
428                  [(store (adde (load addr:$dst), i64immSExt8:$src2), addr:$dst)]>;
429 } // Uses = [EFLAGS]
430
431 let isTwoAddress = 1 in {
432 // Register-Register Subtraction
433 def SUB64rr  : RI<0x29, MRMDestReg, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
434                   "sub{q}\t{$src2, $dst|$dst, $src2}",
435                   [(set GR64:$dst, (sub GR64:$src1, GR64:$src2)),
436                    (implicit EFLAGS)]>;
437
438 // Register-Memory Subtraction
439 def SUB64rm  : RI<0x2B, MRMSrcMem, (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
440                   "sub{q}\t{$src2, $dst|$dst, $src2}",
441                   [(set GR64:$dst, (sub GR64:$src1, (load addr:$src2))),
442                    (implicit EFLAGS)]>;
443
444 // Register-Integer Subtraction
445 def SUB64ri8 : RIi8<0x83, MRM5r, (outs GR64:$dst),
446                                  (ins GR64:$src1, i64i8imm:$src2),
447                     "sub{q}\t{$src2, $dst|$dst, $src2}",
448                     [(set GR64:$dst, (sub GR64:$src1, i64immSExt8:$src2)),
449                      (implicit EFLAGS)]>;
450 def SUB64ri32 : RIi32<0x81, MRM5r, (outs GR64:$dst),
451                                    (ins GR64:$src1, i64i32imm:$src2),
452                       "sub{q}\t{$src2, $dst|$dst, $src2}",
453                       [(set GR64:$dst, (sub GR64:$src1, i64immSExt32:$src2)),
454                        (implicit EFLAGS)]>;
455 } // isTwoAddress
456
457 // Memory-Register Subtraction
458 def SUB64mr  : RI<0x29, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src2), 
459                   "sub{q}\t{$src2, $dst|$dst, $src2}",
460                   [(store (sub (load addr:$dst), GR64:$src2), addr:$dst),
461                    (implicit EFLAGS)]>;
462
463 // Memory-Integer Subtraction
464 def SUB64mi8 : RIi8<0x83, MRM5m, (outs), (ins i64mem:$dst, i64i8imm :$src2), 
465                     "sub{q}\t{$src2, $dst|$dst, $src2}",
466                     [(store (sub (load addr:$dst), i64immSExt8:$src2),
467                             addr:$dst),
468                      (implicit EFLAGS)]>;
469 def SUB64mi32 : RIi32<0x81, MRM5m, (outs), (ins i64mem:$dst, i64i32imm:$src2),
470                       "sub{q}\t{$src2, $dst|$dst, $src2}",
471                       [(store (sub (load addr:$dst), i64immSExt32:$src2),
472                               addr:$dst),
473                        (implicit EFLAGS)]>;
474
475 let Uses = [EFLAGS] in {
476 let isTwoAddress = 1 in {
477 def SBB64rr    : RI<0x19, MRMDestReg, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
478                     "sbb{q}\t{$src2, $dst|$dst, $src2}",
479                     [(set GR64:$dst, (sube GR64:$src1, GR64:$src2))]>;
480
481 def SBB64rm  : RI<0x1B, MRMSrcMem, (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
482                   "sbb{q}\t{$src2, $dst|$dst, $src2}",
483                   [(set GR64:$dst, (sube GR64:$src1, (load addr:$src2)))]>;
484
485 def SBB64ri8 : RIi8<0x83, MRM3r, (outs GR64:$dst), (ins GR64:$src1, i64i8imm:$src2),
486                     "sbb{q}\t{$src2, $dst|$dst, $src2}",
487                     [(set GR64:$dst, (sube GR64:$src1, i64immSExt8:$src2))]>;
488 def SBB64ri32 : RIi32<0x81, MRM3r, (outs GR64:$dst), (ins GR64:$src1, i64i32imm:$src2),
489                       "sbb{q}\t{$src2, $dst|$dst, $src2}",
490                       [(set GR64:$dst, (sube GR64:$src1, i64immSExt32:$src2))]>;
491 } // isTwoAddress
492
493 def SBB64mr  : RI<0x19, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src2), 
494                   "sbb{q}\t{$src2, $dst|$dst, $src2}",
495                   [(store (sube (load addr:$dst), GR64:$src2), addr:$dst)]>;
496 def SBB64mi8 : RIi8<0x83, MRM3m, (outs), (ins i64mem:$dst, i64i8imm :$src2), 
497                     "sbb{q}\t{$src2, $dst|$dst, $src2}",
498                [(store (sube (load addr:$dst), i64immSExt8:$src2), addr:$dst)]>;
499 def SBB64mi32 : RIi32<0x81, MRM3m, (outs), (ins i64mem:$dst, i64i32imm:$src2), 
500                       "sbb{q}\t{$src2, $dst|$dst, $src2}",
501               [(store (sube (load addr:$dst), i64immSExt32:$src2), addr:$dst)]>;
502 } // Uses = [EFLAGS]
503 } // Defs = [EFLAGS]
504
505 // Unsigned multiplication
506 let Defs = [RAX,RDX,EFLAGS], Uses = [RAX], neverHasSideEffects = 1 in {
507 def MUL64r : RI<0xF7, MRM4r, (outs), (ins GR64:$src),
508                 "mul{q}\t$src", []>;         // RAX,RDX = RAX*GR64
509 let mayLoad = 1 in
510 def MUL64m : RI<0xF7, MRM4m, (outs), (ins i64mem:$src),
511                 "mul{q}\t$src", []>;         // RAX,RDX = RAX*[mem64]
512
513 // Signed multiplication
514 def IMUL64r : RI<0xF7, MRM5r, (outs), (ins GR64:$src),
515                  "imul{q}\t$src", []>;         // RAX,RDX = RAX*GR64
516 let mayLoad = 1 in
517 def IMUL64m : RI<0xF7, MRM5m, (outs), (ins i64mem:$src),
518                  "imul{q}\t$src", []>;         // RAX,RDX = RAX*[mem64]
519 }
520
521 let Defs = [EFLAGS] in {
522 let isTwoAddress = 1 in {
523 let isCommutable = 1 in
524 // Register-Register Signed Integer Multiplication
525 def IMUL64rr : RI<0xAF, MRMSrcReg, (outs GR64:$dst),
526                                    (ins GR64:$src1, GR64:$src2),
527                   "imul{q}\t{$src2, $dst|$dst, $src2}",
528                   [(set GR64:$dst, (mul GR64:$src1, GR64:$src2)),
529                    (implicit EFLAGS)]>, TB;
530
531 // Register-Memory Signed Integer Multiplication
532 def IMUL64rm : RI<0xAF, MRMSrcMem, (outs GR64:$dst),
533                                    (ins GR64:$src1, i64mem:$src2),
534                   "imul{q}\t{$src2, $dst|$dst, $src2}",
535                   [(set GR64:$dst, (mul GR64:$src1, (load addr:$src2))),
536                    (implicit EFLAGS)]>, TB;
537 } // isTwoAddress
538
539 // Suprisingly enough, these are not two address instructions!
540
541 // Register-Integer Signed Integer Multiplication
542 def IMUL64rri8 : RIi8<0x6B, MRMSrcReg,                      // GR64 = GR64*I8
543                       (outs GR64:$dst), (ins GR64:$src1, i64i8imm:$src2),
544                       "imul{q}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
545                       [(set GR64:$dst, (mul GR64:$src1, i64immSExt8:$src2)),
546                        (implicit EFLAGS)]>;
547 def IMUL64rri32 : RIi32<0x69, MRMSrcReg,                    // GR64 = GR64*I32
548                         (outs GR64:$dst), (ins GR64:$src1, i64i32imm:$src2),
549                         "imul{q}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
550                        [(set GR64:$dst, (mul GR64:$src1, i64immSExt32:$src2)),
551                         (implicit EFLAGS)]>;
552
553 // Memory-Integer Signed Integer Multiplication
554 def IMUL64rmi8 : RIi8<0x6B, MRMSrcMem,                      // GR64 = [mem64]*I8
555                       (outs GR64:$dst), (ins i64mem:$src1, i64i8imm: $src2),
556                       "imul{q}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
557                       [(set GR64:$dst, (mul (load addr:$src1),
558                                             i64immSExt8:$src2)),
559                        (implicit EFLAGS)]>;
560 def IMUL64rmi32 : RIi32<0x69, MRMSrcMem,                   // GR64 = [mem64]*I32
561                         (outs GR64:$dst), (ins i64mem:$src1, i64i32imm:$src2),
562                         "imul{q}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
563                         [(set GR64:$dst, (mul (load addr:$src1),
564                                               i64immSExt32:$src2)),
565                          (implicit EFLAGS)]>;
566 } // Defs = [EFLAGS]
567
568 // Unsigned division / remainder
569 let Defs = [RAX,RDX,EFLAGS], Uses = [RAX,RDX] in {
570 def DIV64r : RI<0xF7, MRM6r, (outs), (ins GR64:$src),        // RDX:RAX/r64 = RAX,RDX
571                 "div{q}\t$src", []>;
572 // Signed division / remainder
573 def IDIV64r: RI<0xF7, MRM7r, (outs), (ins GR64:$src),        // RDX:RAX/r64 = RAX,RDX
574                 "idiv{q}\t$src", []>;
575 let mayLoad = 1 in {
576 def DIV64m : RI<0xF7, MRM6m, (outs), (ins i64mem:$src),      // RDX:RAX/[mem64] = RAX,RDX
577                 "div{q}\t$src", []>;
578 def IDIV64m: RI<0xF7, MRM7m, (outs), (ins i64mem:$src),      // RDX:RAX/[mem64] = RAX,RDX
579                 "idiv{q}\t$src", []>;
580 }
581 }
582
583 // Unary instructions
584 let Defs = [EFLAGS], CodeSize = 2 in {
585 let isTwoAddress = 1 in
586 def NEG64r : RI<0xF7, MRM3r, (outs GR64:$dst), (ins GR64:$src), "neg{q}\t$dst",
587                 [(set GR64:$dst, (ineg GR64:$src)),
588                  (implicit EFLAGS)]>;
589 def NEG64m : RI<0xF7, MRM3m, (outs), (ins i64mem:$dst), "neg{q}\t$dst",
590                 [(store (ineg (loadi64 addr:$dst)), addr:$dst),
591                  (implicit EFLAGS)]>;
592
593 let isTwoAddress = 1, isConvertibleToThreeAddress = 1 in
594 def INC64r : RI<0xFF, MRM0r, (outs GR64:$dst), (ins GR64:$src), "inc{q}\t$dst",
595                 [(set GR64:$dst, (add GR64:$src, 1)),
596                  (implicit EFLAGS)]>;
597 def INC64m : RI<0xFF, MRM0m, (outs), (ins i64mem:$dst), "inc{q}\t$dst",
598                 [(store (add (loadi64 addr:$dst), 1), addr:$dst),
599                  (implicit EFLAGS)]>;
600
601 let isTwoAddress = 1, isConvertibleToThreeAddress = 1 in
602 def DEC64r : RI<0xFF, MRM1r, (outs GR64:$dst), (ins GR64:$src), "dec{q}\t$dst",
603                 [(set GR64:$dst, (add GR64:$src, -1)),
604                  (implicit EFLAGS)]>;
605 def DEC64m : RI<0xFF, MRM1m, (outs), (ins i64mem:$dst), "dec{q}\t$dst",
606                 [(store (add (loadi64 addr:$dst), -1), addr:$dst),
607                  (implicit EFLAGS)]>;
608
609 // In 64-bit mode, single byte INC and DEC cannot be encoded.
610 let isTwoAddress = 1, isConvertibleToThreeAddress = 1 in {
611 // Can transform into LEA.
612 def INC64_16r : I<0xFF, MRM0r, (outs GR16:$dst), (ins GR16:$src), "inc{w}\t$dst",
613                   [(set GR16:$dst, (add GR16:$src, 1)),
614                    (implicit EFLAGS)]>,
615                 OpSize, Requires<[In64BitMode]>;
616 def INC64_32r : I<0xFF, MRM0r, (outs GR32:$dst), (ins GR32:$src), "inc{l}\t$dst",
617                   [(set GR32:$dst, (add GR32:$src, 1)),
618                    (implicit EFLAGS)]>,
619                 Requires<[In64BitMode]>;
620 def DEC64_16r : I<0xFF, MRM1r, (outs GR16:$dst), (ins GR16:$src), "dec{w}\t$dst",
621                   [(set GR16:$dst, (add GR16:$src, -1)),
622                    (implicit EFLAGS)]>,
623                 OpSize, Requires<[In64BitMode]>;
624 def DEC64_32r : I<0xFF, MRM1r, (outs GR32:$dst), (ins GR32:$src), "dec{l}\t$dst",
625                   [(set GR32:$dst, (add GR32:$src, -1)),
626                    (implicit EFLAGS)]>,
627                 Requires<[In64BitMode]>;
628 } // isConvertibleToThreeAddress
629
630 // These are duplicates of their 32-bit counterparts. Only needed so X86 knows
631 // how to unfold them.
632 let isTwoAddress = 0, CodeSize = 2 in {
633   def INC64_16m : I<0xFF, MRM0m, (outs), (ins i16mem:$dst), "inc{w}\t$dst",
634                     [(store (add (loadi16 addr:$dst), 1), addr:$dst),
635                      (implicit EFLAGS)]>,
636                   OpSize, Requires<[In64BitMode]>;
637   def INC64_32m : I<0xFF, MRM0m, (outs), (ins i32mem:$dst), "inc{l}\t$dst",
638                     [(store (add (loadi32 addr:$dst), 1), addr:$dst),
639                      (implicit EFLAGS)]>,
640                   Requires<[In64BitMode]>;
641   def DEC64_16m : I<0xFF, MRM1m, (outs), (ins i16mem:$dst), "dec{w}\t$dst",
642                     [(store (add (loadi16 addr:$dst), -1), addr:$dst),
643                      (implicit EFLAGS)]>,
644                   OpSize, Requires<[In64BitMode]>;
645   def DEC64_32m : I<0xFF, MRM1m, (outs), (ins i32mem:$dst), "dec{l}\t$dst",
646                     [(store (add (loadi32 addr:$dst), -1), addr:$dst),
647                      (implicit EFLAGS)]>,
648                   Requires<[In64BitMode]>;
649 }
650 } // Defs = [EFLAGS], CodeSize
651
652
653 let Defs = [EFLAGS] in {
654 // Shift instructions
655 let isTwoAddress = 1 in {
656 let Uses = [CL] in
657 def SHL64rCL : RI<0xD3, MRM4r, (outs GR64:$dst), (ins GR64:$src),
658                   "shl{q}\t{%cl, $dst|$dst, %CL}",
659                   [(set GR64:$dst, (shl GR64:$src, CL))]>;
660 let isConvertibleToThreeAddress = 1 in   // Can transform into LEA.
661 def SHL64ri  : RIi8<0xC1, MRM4r, (outs GR64:$dst), (ins GR64:$src1, i8imm:$src2),
662                     "shl{q}\t{$src2, $dst|$dst, $src2}",
663                     [(set GR64:$dst, (shl GR64:$src1, (i8 imm:$src2)))]>;
664 // NOTE: We don't use shifts of a register by one, because 'add reg,reg' is
665 // cheaper.
666 } // isTwoAddress
667
668 let Uses = [CL] in
669 def SHL64mCL : RI<0xD3, MRM4m, (outs), (ins i64mem:$dst),
670                   "shl{q}\t{%cl, $dst|$dst, %CL}",
671                   [(store (shl (loadi64 addr:$dst), CL), addr:$dst)]>;
672 def SHL64mi : RIi8<0xC1, MRM4m, (outs), (ins i64mem:$dst, i8imm:$src),
673                   "shl{q}\t{$src, $dst|$dst, $src}",
674                  [(store (shl (loadi64 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
675 def SHL64m1 : RI<0xD1, MRM4m, (outs), (ins i64mem:$dst),
676                   "shl{q}\t$dst",
677                  [(store (shl (loadi64 addr:$dst), (i8 1)), addr:$dst)]>;
678
679 let isTwoAddress = 1 in {
680 let Uses = [CL] in
681 def SHR64rCL : RI<0xD3, MRM5r, (outs GR64:$dst), (ins GR64:$src),
682                   "shr{q}\t{%cl, $dst|$dst, %CL}",
683                   [(set GR64:$dst, (srl GR64:$src, CL))]>;
684 def SHR64ri : RIi8<0xC1, MRM5r, (outs GR64:$dst), (ins GR64:$src1, i8imm:$src2),
685                   "shr{q}\t{$src2, $dst|$dst, $src2}",
686                   [(set GR64:$dst, (srl GR64:$src1, (i8 imm:$src2)))]>;
687 def SHR64r1  : RI<0xD1, MRM5r, (outs GR64:$dst), (ins GR64:$src1),
688                  "shr{q}\t$dst",
689                  [(set GR64:$dst, (srl GR64:$src1, (i8 1)))]>;
690 } // isTwoAddress
691
692 let Uses = [CL] in
693 def SHR64mCL : RI<0xD3, MRM5m, (outs), (ins i64mem:$dst),
694                   "shr{q}\t{%cl, $dst|$dst, %CL}",
695                   [(store (srl (loadi64 addr:$dst), CL), addr:$dst)]>;
696 def SHR64mi : RIi8<0xC1, MRM5m, (outs), (ins i64mem:$dst, i8imm:$src),
697                   "shr{q}\t{$src, $dst|$dst, $src}",
698                  [(store (srl (loadi64 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
699 def SHR64m1 : RI<0xD1, MRM5m, (outs), (ins i64mem:$dst),
700                   "shr{q}\t$dst",
701                  [(store (srl (loadi64 addr:$dst), (i8 1)), addr:$dst)]>;
702
703 let isTwoAddress = 1 in {
704 let Uses = [CL] in
705 def SAR64rCL : RI<0xD3, MRM7r, (outs GR64:$dst), (ins GR64:$src),
706                  "sar{q}\t{%cl, $dst|$dst, %CL}",
707                  [(set GR64:$dst, (sra GR64:$src, CL))]>;
708 def SAR64ri  : RIi8<0xC1, MRM7r, (outs GR64:$dst), (ins GR64:$src1, i8imm:$src2),
709                    "sar{q}\t{$src2, $dst|$dst, $src2}",
710                    [(set GR64:$dst, (sra GR64:$src1, (i8 imm:$src2)))]>;
711 def SAR64r1  : RI<0xD1, MRM7r, (outs GR64:$dst), (ins GR64:$src1),
712                  "sar{q}\t$dst",
713                  [(set GR64:$dst, (sra GR64:$src1, (i8 1)))]>;
714 } // isTwoAddress
715
716 let Uses = [CL] in
717 def SAR64mCL : RI<0xD3, MRM7m, (outs), (ins i64mem:$dst), 
718                  "sar{q}\t{%cl, $dst|$dst, %CL}",
719                  [(store (sra (loadi64 addr:$dst), CL), addr:$dst)]>;
720 def SAR64mi  : RIi8<0xC1, MRM7m, (outs), (ins i64mem:$dst, i8imm:$src),
721                     "sar{q}\t{$src, $dst|$dst, $src}",
722                  [(store (sra (loadi64 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
723 def SAR64m1 : RI<0xD1, MRM7m, (outs), (ins i64mem:$dst),
724                   "sar{q}\t$dst",
725                  [(store (sra (loadi64 addr:$dst), (i8 1)), addr:$dst)]>;
726
727 // Rotate instructions
728 let isTwoAddress = 1 in {
729 let Uses = [CL] in
730 def ROL64rCL : RI<0xD3, MRM0r, (outs GR64:$dst), (ins GR64:$src),
731                   "rol{q}\t{%cl, $dst|$dst, %CL}",
732                   [(set GR64:$dst, (rotl GR64:$src, CL))]>;
733 def ROL64ri  : RIi8<0xC1, MRM0r, (outs GR64:$dst), (ins GR64:$src1, i8imm:$src2),
734                     "rol{q}\t{$src2, $dst|$dst, $src2}",
735                     [(set GR64:$dst, (rotl GR64:$src1, (i8 imm:$src2)))]>;
736 def ROL64r1  : RI<0xD1, MRM0r, (outs GR64:$dst), (ins GR64:$src1),
737                   "rol{q}\t$dst",
738                   [(set GR64:$dst, (rotl GR64:$src1, (i8 1)))]>;
739 } // isTwoAddress
740
741 let Uses = [CL] in
742 def ROL64mCL :  I<0xD3, MRM0m, (outs), (ins i64mem:$dst),
743                   "rol{q}\t{%cl, $dst|$dst, %CL}",
744                   [(store (rotl (loadi64 addr:$dst), CL), addr:$dst)]>;
745 def ROL64mi  : RIi8<0xC1, MRM0m, (outs), (ins i64mem:$dst, i8imm:$src),
746                     "rol{q}\t{$src, $dst|$dst, $src}",
747                 [(store (rotl (loadi64 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
748 def ROL64m1  : RI<0xD1, MRM0m, (outs), (ins i64mem:$dst),
749                  "rol{q}\t$dst",
750                [(store (rotl (loadi64 addr:$dst), (i8 1)), addr:$dst)]>;
751
752 let isTwoAddress = 1 in {
753 let Uses = [CL] in
754 def ROR64rCL : RI<0xD3, MRM1r, (outs GR64:$dst), (ins GR64:$src),
755                   "ror{q}\t{%cl, $dst|$dst, %CL}",
756                   [(set GR64:$dst, (rotr GR64:$src, CL))]>;
757 def ROR64ri  : RIi8<0xC1, MRM1r, (outs GR64:$dst), (ins GR64:$src1, i8imm:$src2),
758                     "ror{q}\t{$src2, $dst|$dst, $src2}",
759                     [(set GR64:$dst, (rotr GR64:$src1, (i8 imm:$src2)))]>;
760 def ROR64r1  : RI<0xD1, MRM1r, (outs GR64:$dst), (ins GR64:$src1),
761                   "ror{q}\t$dst",
762                   [(set GR64:$dst, (rotr GR64:$src1, (i8 1)))]>;
763 } // isTwoAddress
764
765 let Uses = [CL] in
766 def ROR64mCL : RI<0xD3, MRM1m, (outs), (ins i64mem:$dst), 
767                   "ror{q}\t{%cl, $dst|$dst, %CL}",
768                   [(store (rotr (loadi64 addr:$dst), CL), addr:$dst)]>;
769 def ROR64mi  : RIi8<0xC1, MRM1m, (outs), (ins i64mem:$dst, i8imm:$src),
770                     "ror{q}\t{$src, $dst|$dst, $src}",
771                 [(store (rotr (loadi64 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
772 def ROR64m1  : RI<0xD1, MRM1m, (outs), (ins i64mem:$dst),
773                  "ror{q}\t$dst",
774                [(store (rotr (loadi64 addr:$dst), (i8 1)), addr:$dst)]>;
775
776 // Double shift instructions (generalizations of rotate)
777 let isTwoAddress = 1 in {
778 let Uses = [CL] in {
779 def SHLD64rrCL : RI<0xA5, MRMDestReg, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
780                     "shld{q}\t{%cl, $src2, $dst|$dst, $src2, %CL}",
781                     [(set GR64:$dst, (X86shld GR64:$src1, GR64:$src2, CL))]>, TB;
782 def SHRD64rrCL : RI<0xAD, MRMDestReg, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
783                     "shrd{q}\t{%cl, $src2, $dst|$dst, $src2, %CL}",
784                     [(set GR64:$dst, (X86shrd GR64:$src1, GR64:$src2, CL))]>, TB;
785 }
786
787 let isCommutable = 1 in {  // FIXME: Update X86InstrInfo::commuteInstruction
788 def SHLD64rri8 : RIi8<0xA4, MRMDestReg,
789                       (outs GR64:$dst), (ins GR64:$src1, GR64:$src2, i8imm:$src3),
790                       "shld{q}\t{$src3, $src2, $dst|$dst, $src2, $src3}",
791                       [(set GR64:$dst, (X86shld GR64:$src1, GR64:$src2,
792                                        (i8 imm:$src3)))]>,
793                  TB;
794 def SHRD64rri8 : RIi8<0xAC, MRMDestReg,
795                       (outs GR64:$dst), (ins GR64:$src1, GR64:$src2, i8imm:$src3),
796                       "shrd{q}\t{$src3, $src2, $dst|$dst, $src2, $src3}",
797                       [(set GR64:$dst, (X86shrd GR64:$src1, GR64:$src2,
798                                        (i8 imm:$src3)))]>,
799                  TB;
800 } // isCommutable
801 } // isTwoAddress
802
803 let Uses = [CL] in {
804 def SHLD64mrCL : RI<0xA5, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src2),
805                     "shld{q}\t{%cl, $src2, $dst|$dst, $src2, %CL}",
806                     [(store (X86shld (loadi64 addr:$dst), GR64:$src2, CL),
807                       addr:$dst)]>, TB;
808 def SHRD64mrCL : RI<0xAD, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src2),
809                     "shrd{q}\t{%cl, $src2, $dst|$dst, $src2, %CL}",
810                     [(store (X86shrd (loadi64 addr:$dst), GR64:$src2, CL),
811                       addr:$dst)]>, TB;
812 }
813 def SHLD64mri8 : RIi8<0xA4, MRMDestMem,
814                       (outs), (ins i64mem:$dst, GR64:$src2, i8imm:$src3),
815                       "shld{q}\t{$src3, $src2, $dst|$dst, $src2, $src3}",
816                       [(store (X86shld (loadi64 addr:$dst), GR64:$src2,
817                                        (i8 imm:$src3)), addr:$dst)]>,
818                  TB;
819 def SHRD64mri8 : RIi8<0xAC, MRMDestMem, 
820                       (outs), (ins i64mem:$dst, GR64:$src2, i8imm:$src3),
821                       "shrd{q}\t{$src3, $src2, $dst|$dst, $src2, $src3}",
822                       [(store (X86shrd (loadi64 addr:$dst), GR64:$src2,
823                                        (i8 imm:$src3)), addr:$dst)]>,
824                  TB;
825 } // Defs = [EFLAGS]
826
827 //===----------------------------------------------------------------------===//
828 //  Logical Instructions...
829 //
830
831 let isTwoAddress = 1 , AddedComplexity = 15 in
832 def NOT64r : RI<0xF7, MRM2r, (outs GR64:$dst), (ins GR64:$src), "not{q}\t$dst",
833                 [(set GR64:$dst, (not GR64:$src))]>;
834 def NOT64m : RI<0xF7, MRM2m, (outs), (ins i64mem:$dst), "not{q}\t$dst",
835                 [(store (not (loadi64 addr:$dst)), addr:$dst)]>;
836
837 let Defs = [EFLAGS] in {
838 let isTwoAddress = 1 in {
839 let isCommutable = 1 in
840 def AND64rr  : RI<0x21, MRMDestReg, 
841                   (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
842                   "and{q}\t{$src2, $dst|$dst, $src2}",
843                   [(set GR64:$dst, (and GR64:$src1, GR64:$src2)),
844                    (implicit EFLAGS)]>;
845 def AND64rm  : RI<0x23, MRMSrcMem,
846                   (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
847                   "and{q}\t{$src2, $dst|$dst, $src2}",
848                   [(set GR64:$dst, (and GR64:$src1, (load addr:$src2))),
849                    (implicit EFLAGS)]>;
850 def AND64ri8 : RIi8<0x83, MRM4r, 
851                     (outs GR64:$dst), (ins GR64:$src1, i64i8imm:$src2),
852                     "and{q}\t{$src2, $dst|$dst, $src2}",
853                     [(set GR64:$dst, (and GR64:$src1, i64immSExt8:$src2)),
854                      (implicit EFLAGS)]>;
855 def AND64ri32  : RIi32<0x81, MRM4r, 
856                        (outs GR64:$dst), (ins GR64:$src1, i64i32imm:$src2),
857                        "and{q}\t{$src2, $dst|$dst, $src2}",
858                        [(set GR64:$dst, (and GR64:$src1, i64immSExt32:$src2)),
859                         (implicit EFLAGS)]>;
860 } // isTwoAddress
861
862 def AND64mr  : RI<0x21, MRMDestMem,
863                   (outs), (ins i64mem:$dst, GR64:$src),
864                   "and{q}\t{$src, $dst|$dst, $src}",
865                   [(store (and (load addr:$dst), GR64:$src), addr:$dst),
866                    (implicit EFLAGS)]>;
867 def AND64mi8 : RIi8<0x83, MRM4m,
868                     (outs), (ins i64mem:$dst, i64i8imm :$src),
869                     "and{q}\t{$src, $dst|$dst, $src}",
870                  [(store (and (load addr:$dst), i64immSExt8:$src), addr:$dst),
871                   (implicit EFLAGS)]>;
872 def AND64mi32  : RIi32<0x81, MRM4m,
873                        (outs), (ins i64mem:$dst, i64i32imm:$src),
874                        "and{q}\t{$src, $dst|$dst, $src}",
875              [(store (and (loadi64 addr:$dst), i64immSExt32:$src), addr:$dst),
876               (implicit EFLAGS)]>;
877
878 let isTwoAddress = 1 in {
879 let isCommutable = 1 in
880 def OR64rr   : RI<0x09, MRMDestReg, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
881                   "or{q}\t{$src2, $dst|$dst, $src2}",
882                   [(set GR64:$dst, (or GR64:$src1, GR64:$src2)),
883                    (implicit EFLAGS)]>;
884 def OR64rm   : RI<0x0B, MRMSrcMem , (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
885                   "or{q}\t{$src2, $dst|$dst, $src2}",
886                   [(set GR64:$dst, (or GR64:$src1, (load addr:$src2))),
887                    (implicit EFLAGS)]>;
888 def OR64ri8  : RIi8<0x83, MRM1r, (outs GR64:$dst), (ins GR64:$src1, i64i8imm:$src2),
889                     "or{q}\t{$src2, $dst|$dst, $src2}",
890                     [(set GR64:$dst, (or GR64:$src1, i64immSExt8:$src2)),
891                      (implicit EFLAGS)]>;
892 def OR64ri32 : RIi32<0x81, MRM1r, (outs GR64:$dst), (ins GR64:$src1, i64i32imm:$src2),
893                      "or{q}\t{$src2, $dst|$dst, $src2}",
894                      [(set GR64:$dst, (or GR64:$src1, i64immSExt32:$src2)),
895                       (implicit EFLAGS)]>;
896 } // isTwoAddress
897
898 def OR64mr : RI<0x09, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
899                 "or{q}\t{$src, $dst|$dst, $src}",
900                 [(store (or (load addr:$dst), GR64:$src), addr:$dst),
901                  (implicit EFLAGS)]>;
902 def OR64mi8  : RIi8<0x83, MRM1m, (outs), (ins i64mem:$dst, i64i8imm:$src),
903                     "or{q}\t{$src, $dst|$dst, $src}",
904                   [(store (or (load addr:$dst), i64immSExt8:$src), addr:$dst),
905                    (implicit EFLAGS)]>;
906 def OR64mi32 : RIi32<0x81, MRM1m, (outs), (ins i64mem:$dst, i64i32imm:$src),
907                      "or{q}\t{$src, $dst|$dst, $src}",
908               [(store (or (loadi64 addr:$dst), i64immSExt32:$src), addr:$dst),
909                (implicit EFLAGS)]>;
910
911 let isTwoAddress = 1 in {
912 let isCommutable = 1 in
913 def XOR64rr  : RI<0x31, MRMDestReg,  (outs GR64:$dst), (ins GR64:$src1, GR64:$src2), 
914                   "xor{q}\t{$src2, $dst|$dst, $src2}",
915                   [(set GR64:$dst, (xor GR64:$src1, GR64:$src2)),
916                    (implicit EFLAGS)]>;
917 def XOR64rm  : RI<0x33, MRMSrcMem, (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2), 
918                   "xor{q}\t{$src2, $dst|$dst, $src2}",
919                   [(set GR64:$dst, (xor GR64:$src1, (load addr:$src2))),
920                    (implicit EFLAGS)]>;
921 def XOR64ri8 : RIi8<0x83, MRM6r,  (outs GR64:$dst), (ins GR64:$src1, i64i8imm:$src2),
922                     "xor{q}\t{$src2, $dst|$dst, $src2}",
923                     [(set GR64:$dst, (xor GR64:$src1, i64immSExt8:$src2)),
924                      (implicit EFLAGS)]>;
925 def XOR64ri32 : RIi32<0x81, MRM6r, 
926                       (outs GR64:$dst), (ins GR64:$src1, i64i32imm:$src2), 
927                       "xor{q}\t{$src2, $dst|$dst, $src2}",
928                       [(set GR64:$dst, (xor GR64:$src1, i64immSExt32:$src2)),
929                        (implicit EFLAGS)]>;
930 } // isTwoAddress
931
932 def XOR64mr  : RI<0x31, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
933                   "xor{q}\t{$src, $dst|$dst, $src}",
934                   [(store (xor (load addr:$dst), GR64:$src), addr:$dst),
935                    (implicit EFLAGS)]>;
936 def XOR64mi8 : RIi8<0x83, MRM6m, (outs), (ins i64mem:$dst, i64i8imm :$src),
937                     "xor{q}\t{$src, $dst|$dst, $src}",
938                  [(store (xor (load addr:$dst), i64immSExt8:$src), addr:$dst),
939                   (implicit EFLAGS)]>;
940 def XOR64mi32 : RIi32<0x81, MRM6m, (outs), (ins i64mem:$dst, i64i32imm:$src),
941                       "xor{q}\t{$src, $dst|$dst, $src}",
942              [(store (xor (loadi64 addr:$dst), i64immSExt32:$src), addr:$dst),
943               (implicit EFLAGS)]>;
944 } // Defs = [EFLAGS]
945
946 //===----------------------------------------------------------------------===//
947 //  Comparison Instructions...
948 //
949
950 // Integer comparison
951 let Defs = [EFLAGS] in {
952 let isCommutable = 1 in
953 def TEST64rr : RI<0x85, MRMDestReg, (outs), (ins GR64:$src1, GR64:$src2),
954                   "test{q}\t{$src2, $src1|$src1, $src2}",
955                   [(X86cmp (and GR64:$src1, GR64:$src2), 0),
956                    (implicit EFLAGS)]>;
957 def TEST64rm : RI<0x85, MRMSrcMem, (outs), (ins GR64:$src1, i64mem:$src2),
958                   "test{q}\t{$src2, $src1|$src1, $src2}",
959                   [(X86cmp (and GR64:$src1, (loadi64 addr:$src2)), 0),
960                    (implicit EFLAGS)]>;
961 def TEST64ri32 : RIi32<0xF7, MRM0r, (outs),
962                                         (ins GR64:$src1, i64i32imm:$src2),
963                        "test{q}\t{$src2, $src1|$src1, $src2}",
964                      [(X86cmp (and GR64:$src1, i64immSExt32:$src2), 0),
965                       (implicit EFLAGS)]>;
966 def TEST64mi32 : RIi32<0xF7, MRM0m, (outs),
967                                         (ins i64mem:$src1, i64i32imm:$src2),
968                        "test{q}\t{$src2, $src1|$src1, $src2}",
969                 [(X86cmp (and (loadi64 addr:$src1), i64immSExt32:$src2), 0),
970                  (implicit EFLAGS)]>;
971
972 def CMP64rr : RI<0x39, MRMDestReg, (outs), (ins GR64:$src1, GR64:$src2),
973                  "cmp{q}\t{$src2, $src1|$src1, $src2}",
974                  [(X86cmp GR64:$src1, GR64:$src2),
975                   (implicit EFLAGS)]>;
976 def CMP64mr : RI<0x39, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2),
977                  "cmp{q}\t{$src2, $src1|$src1, $src2}",
978                  [(X86cmp (loadi64 addr:$src1), GR64:$src2),
979                    (implicit EFLAGS)]>;
980 def CMP64rm : RI<0x3B, MRMSrcMem, (outs), (ins GR64:$src1, i64mem:$src2),
981                  "cmp{q}\t{$src2, $src1|$src1, $src2}",
982                  [(X86cmp GR64:$src1, (loadi64 addr:$src2)),
983                   (implicit EFLAGS)]>;
984 def CMP64ri8 : RIi8<0x83, MRM7r, (outs), (ins GR64:$src1, i64i8imm:$src2),
985                     "cmp{q}\t{$src2, $src1|$src1, $src2}",
986                     [(X86cmp GR64:$src1, i64immSExt8:$src2),
987                      (implicit EFLAGS)]>;
988 def CMP64ri32 : RIi32<0x81, MRM7r, (outs), (ins GR64:$src1, i64i32imm:$src2),
989                       "cmp{q}\t{$src2, $src1|$src1, $src2}",
990                       [(X86cmp GR64:$src1, i64immSExt32:$src2),
991                        (implicit EFLAGS)]>;
992 def CMP64mi8 : RIi8<0x83, MRM7m, (outs), (ins i64mem:$src1, i64i8imm:$src2),
993                     "cmp{q}\t{$src2, $src1|$src1, $src2}",
994                     [(X86cmp (loadi64 addr:$src1), i64immSExt8:$src2),
995                      (implicit EFLAGS)]>;
996 def CMP64mi32 : RIi32<0x81, MRM7m, (outs),
997                                        (ins i64mem:$src1, i64i32imm:$src2),
998                       "cmp{q}\t{$src2, $src1|$src1, $src2}",
999                       [(X86cmp (loadi64 addr:$src1), i64immSExt32:$src2),
1000                        (implicit EFLAGS)]>;
1001 } // Defs = [EFLAGS]
1002
1003 // Bit tests.
1004 // TODO: BTC, BTR, and BTS
1005 let Defs = [EFLAGS] in {
1006 def BT64rr : RI<0xA3, MRMDestReg, (outs), (ins GR64:$src1, GR64:$src2),
1007                "bt{q}\t{$src2, $src1|$src1, $src2}",
1008                [(X86bt GR64:$src1, GR64:$src2),
1009                 (implicit EFLAGS)]>, TB;
1010
1011 // Unlike with the register+register form, the memory+register form of the
1012 // bt instruction does not ignore the high bits of the index. From ISel's
1013 // perspective, this is pretty bizarre. Disable these instructions for now.
1014 //def BT64mr : RI<0xA3, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2),
1015 //               "bt{q}\t{$src2, $src1|$src1, $src2}",
1016 //               [(X86bt (loadi64 addr:$src1), GR64:$src2),
1017 //                (implicit EFLAGS)]>, TB;
1018
1019 def BT64ri8 : Ii8<0xBA, MRM4r, (outs), (ins GR64:$src1, i64i8imm:$src2),
1020                 "bt{q}\t{$src2, $src1|$src1, $src2}",
1021                 [(X86bt GR64:$src1, i64immSExt8:$src2),
1022                  (implicit EFLAGS)]>, TB;
1023 // Note that these instructions don't need FastBTMem because that
1024 // only applies when the other operand is in a register. When it's
1025 // an immediate, bt is still fast.
1026 def BT64mi8 : Ii8<0xBA, MRM4m, (outs), (ins i64mem:$src1, i64i8imm:$src2),
1027                 "bt{q}\t{$src2, $src1|$src1, $src2}",
1028                 [(X86bt (loadi64 addr:$src1), i64immSExt8:$src2),
1029                  (implicit EFLAGS)]>, TB;
1030 } // Defs = [EFLAGS]
1031
1032 // Conditional moves
1033 let Uses = [EFLAGS], isTwoAddress = 1 in {
1034 let isCommutable = 1 in {
1035 def CMOVB64rr : RI<0x42, MRMSrcReg,       // if <u, GR64 = GR64
1036                    (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
1037                    "cmovb\t{$src2, $dst|$dst, $src2}",
1038                    [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2,
1039                                      X86_COND_B, EFLAGS))]>, TB;
1040 def CMOVAE64rr: RI<0x43, MRMSrcReg,       // if >=u, GR64 = GR64
1041                    (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
1042                    "cmovae\t{$src2, $dst|$dst, $src2}",
1043                    [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2,
1044                                      X86_COND_AE, EFLAGS))]>, TB;
1045 def CMOVE64rr : RI<0x44, MRMSrcReg,       // if ==, GR64 = GR64
1046                    (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
1047                    "cmove\t{$src2, $dst|$dst, $src2}",
1048                    [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2,
1049                                      X86_COND_E, EFLAGS))]>, TB;
1050 def CMOVNE64rr: RI<0x45, MRMSrcReg,       // if !=, GR64 = GR64
1051                    (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
1052                    "cmovne\t{$src2, $dst|$dst, $src2}",
1053                    [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2,
1054                                     X86_COND_NE, EFLAGS))]>, TB;
1055 def CMOVBE64rr: RI<0x46, MRMSrcReg,       // if <=u, GR64 = GR64
1056                    (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
1057                    "cmovbe\t{$src2, $dst|$dst, $src2}",
1058                    [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2,
1059                                     X86_COND_BE, EFLAGS))]>, TB;
1060 def CMOVA64rr : RI<0x47, MRMSrcReg,       // if >u, GR64 = GR64
1061                    (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
1062                    "cmova\t{$src2, $dst|$dst, $src2}",
1063                    [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2,
1064                                     X86_COND_A, EFLAGS))]>, TB;
1065 def CMOVL64rr : RI<0x4C, MRMSrcReg,       // if <s, GR64 = GR64
1066                    (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
1067                    "cmovl\t{$src2, $dst|$dst, $src2}",
1068                    [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2,
1069                                     X86_COND_L, EFLAGS))]>, TB;
1070 def CMOVGE64rr: RI<0x4D, MRMSrcReg,       // if >=s, GR64 = GR64
1071                    (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
1072                    "cmovge\t{$src2, $dst|$dst, $src2}",
1073                    [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2,
1074                                     X86_COND_GE, EFLAGS))]>, TB;
1075 def CMOVLE64rr: RI<0x4E, MRMSrcReg,       // if <=s, GR64 = GR64
1076                    (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
1077                    "cmovle\t{$src2, $dst|$dst, $src2}",
1078                    [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2,
1079                                     X86_COND_LE, EFLAGS))]>, TB;
1080 def CMOVG64rr : RI<0x4F, MRMSrcReg,       // if >s, GR64 = GR64
1081                    (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
1082                    "cmovg\t{$src2, $dst|$dst, $src2}",
1083                    [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2,
1084                                     X86_COND_G, EFLAGS))]>, TB;
1085 def CMOVS64rr : RI<0x48, MRMSrcReg,       // if signed, GR64 = GR64
1086                    (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
1087                    "cmovs\t{$src2, $dst|$dst, $src2}",
1088                    [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2,
1089                                     X86_COND_S, EFLAGS))]>, TB;
1090 def CMOVNS64rr: RI<0x49, MRMSrcReg,       // if !signed, GR64 = GR64
1091                    (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
1092                    "cmovns\t{$src2, $dst|$dst, $src2}",
1093                    [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2,
1094                                     X86_COND_NS, EFLAGS))]>, TB;
1095 def CMOVP64rr : RI<0x4A, MRMSrcReg,       // if parity, GR64 = GR64
1096                    (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
1097                    "cmovp\t{$src2, $dst|$dst, $src2}",
1098                    [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2,
1099                                     X86_COND_P, EFLAGS))]>, TB;
1100 def CMOVNP64rr : RI<0x4B, MRMSrcReg,       // if !parity, GR64 = GR64
1101                    (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
1102                    "cmovnp\t{$src2, $dst|$dst, $src2}",
1103                     [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2,
1104                                      X86_COND_NP, EFLAGS))]>, TB;
1105 def CMOVO64rr : RI<0x40, MRMSrcReg,       // if overflow, GR64 = GR64
1106                    (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
1107                    "cmovo\t{$src2, $dst|$dst, $src2}",
1108                    [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2,
1109                                     X86_COND_O, EFLAGS))]>, TB;
1110 def CMOVNO64rr : RI<0x41, MRMSrcReg,       // if !overflow, GR64 = GR64
1111                    (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
1112                    "cmovno\t{$src2, $dst|$dst, $src2}",
1113                     [(set GR64:$dst, (X86cmov GR64:$src1, GR64:$src2,
1114                                      X86_COND_NO, EFLAGS))]>, TB;
1115 } // isCommutable = 1
1116
1117 def CMOVB64rm : RI<0x42, MRMSrcMem,       // if <u, GR64 = [mem64]
1118                    (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
1119                    "cmovb\t{$src2, $dst|$dst, $src2}",
1120                    [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
1121                                      X86_COND_B, EFLAGS))]>, TB;
1122 def CMOVAE64rm: RI<0x43, MRMSrcMem,       // if >=u, GR64 = [mem64]
1123                    (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
1124                    "cmovae\t{$src2, $dst|$dst, $src2}",
1125                    [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
1126                                      X86_COND_AE, EFLAGS))]>, TB;
1127 def CMOVE64rm : RI<0x44, MRMSrcMem,       // if ==, GR64 = [mem64]
1128                    (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
1129                    "cmove\t{$src2, $dst|$dst, $src2}",
1130                    [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
1131                                      X86_COND_E, EFLAGS))]>, TB;
1132 def CMOVNE64rm: RI<0x45, MRMSrcMem,       // if !=, GR64 = [mem64]
1133                    (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
1134                    "cmovne\t{$src2, $dst|$dst, $src2}",
1135                    [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
1136                                     X86_COND_NE, EFLAGS))]>, TB;
1137 def CMOVBE64rm: RI<0x46, MRMSrcMem,       // if <=u, GR64 = [mem64]
1138                    (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
1139                    "cmovbe\t{$src2, $dst|$dst, $src2}",
1140                    [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
1141                                     X86_COND_BE, EFLAGS))]>, TB;
1142 def CMOVA64rm : RI<0x47, MRMSrcMem,       // if >u, GR64 = [mem64]
1143                    (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
1144                    "cmova\t{$src2, $dst|$dst, $src2}",
1145                    [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
1146                                     X86_COND_A, EFLAGS))]>, TB;
1147 def CMOVL64rm : RI<0x4C, MRMSrcMem,       // if <s, GR64 = [mem64]
1148                    (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
1149                    "cmovl\t{$src2, $dst|$dst, $src2}",
1150                    [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
1151                                     X86_COND_L, EFLAGS))]>, TB;
1152 def CMOVGE64rm: RI<0x4D, MRMSrcMem,       // if >=s, GR64 = [mem64]
1153                    (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
1154                    "cmovge\t{$src2, $dst|$dst, $src2}",
1155                    [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
1156                                     X86_COND_GE, EFLAGS))]>, TB;
1157 def CMOVLE64rm: RI<0x4E, MRMSrcMem,       // if <=s, GR64 = [mem64]
1158                    (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
1159                    "cmovle\t{$src2, $dst|$dst, $src2}",
1160                    [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
1161                                     X86_COND_LE, EFLAGS))]>, TB;
1162 def CMOVG64rm : RI<0x4F, MRMSrcMem,       // if >s, GR64 = [mem64]
1163                    (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
1164                    "cmovg\t{$src2, $dst|$dst, $src2}",
1165                    [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
1166                                     X86_COND_G, EFLAGS))]>, TB;
1167 def CMOVS64rm : RI<0x48, MRMSrcMem,       // if signed, GR64 = [mem64]
1168                    (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
1169                    "cmovs\t{$src2, $dst|$dst, $src2}",
1170                    [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
1171                                     X86_COND_S, EFLAGS))]>, TB;
1172 def CMOVNS64rm: RI<0x49, MRMSrcMem,       // if !signed, GR64 = [mem64]
1173                    (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
1174                    "cmovns\t{$src2, $dst|$dst, $src2}",
1175                    [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
1176                                     X86_COND_NS, EFLAGS))]>, TB;
1177 def CMOVP64rm : RI<0x4A, MRMSrcMem,       // if parity, GR64 = [mem64]
1178                    (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
1179                    "cmovp\t{$src2, $dst|$dst, $src2}",
1180                    [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
1181                                     X86_COND_P, EFLAGS))]>, TB;
1182 def CMOVNP64rm : RI<0x4B, MRMSrcMem,       // if !parity, GR64 = [mem64]
1183                    (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
1184                    "cmovnp\t{$src2, $dst|$dst, $src2}",
1185                     [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
1186                                      X86_COND_NP, EFLAGS))]>, TB;
1187 def CMOVO64rm : RI<0x40, MRMSrcMem,       // if overflow, GR64 = [mem64]
1188                    (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
1189                    "cmovo\t{$src2, $dst|$dst, $src2}",
1190                    [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
1191                                     X86_COND_O, EFLAGS))]>, TB;
1192 def CMOVNO64rm : RI<0x41, MRMSrcMem,       // if !overflow, GR64 = [mem64]
1193                    (outs GR64:$dst), (ins GR64:$src1, i64mem:$src2),
1194                    "cmovno\t{$src2, $dst|$dst, $src2}",
1195                     [(set GR64:$dst, (X86cmov GR64:$src1, (loadi64 addr:$src2),
1196                                      X86_COND_NO, EFLAGS))]>, TB;
1197 } // isTwoAddress
1198
1199 //===----------------------------------------------------------------------===//
1200 //  Conversion Instructions...
1201 //
1202
1203 // f64 -> signed i64
1204 def Int_CVTSD2SI64rr: RSDI<0x2D, MRMSrcReg, (outs GR64:$dst), (ins VR128:$src),
1205                            "cvtsd2si{q}\t{$src, $dst|$dst, $src}",
1206                            [(set GR64:$dst,
1207                              (int_x86_sse2_cvtsd2si64 VR128:$src))]>;
1208 def Int_CVTSD2SI64rm: RSDI<0x2D, MRMSrcMem, (outs GR64:$dst), (ins f128mem:$src),
1209                            "cvtsd2si{q}\t{$src, $dst|$dst, $src}",
1210                            [(set GR64:$dst, (int_x86_sse2_cvtsd2si64
1211                                              (load addr:$src)))]>;
1212 def CVTTSD2SI64rr: RSDI<0x2C, MRMSrcReg, (outs GR64:$dst), (ins FR64:$src),
1213                         "cvttsd2si{q}\t{$src, $dst|$dst, $src}",
1214                         [(set GR64:$dst, (fp_to_sint FR64:$src))]>;
1215 def CVTTSD2SI64rm: RSDI<0x2C, MRMSrcMem, (outs GR64:$dst), (ins f64mem:$src),
1216                         "cvttsd2si{q}\t{$src, $dst|$dst, $src}",
1217                         [(set GR64:$dst, (fp_to_sint (loadf64 addr:$src)))]>;
1218 def Int_CVTTSD2SI64rr: RSDI<0x2C, MRMSrcReg, (outs GR64:$dst), (ins VR128:$src),
1219                             "cvttsd2si{q}\t{$src, $dst|$dst, $src}",
1220                             [(set GR64:$dst,
1221                               (int_x86_sse2_cvttsd2si64 VR128:$src))]>;
1222 def Int_CVTTSD2SI64rm: RSDI<0x2C, MRMSrcMem, (outs GR64:$dst), (ins f128mem:$src),
1223                             "cvttsd2si{q}\t{$src, $dst|$dst, $src}",
1224                             [(set GR64:$dst,
1225                               (int_x86_sse2_cvttsd2si64
1226                                (load addr:$src)))]>;
1227
1228 // Signed i64 -> f64
1229 def CVTSI2SD64rr: RSDI<0x2A, MRMSrcReg, (outs FR64:$dst), (ins GR64:$src),
1230                        "cvtsi2sd{q}\t{$src, $dst|$dst, $src}",
1231                        [(set FR64:$dst, (sint_to_fp GR64:$src))]>;
1232 def CVTSI2SD64rm: RSDI<0x2A, MRMSrcMem, (outs FR64:$dst), (ins i64mem:$src),
1233                        "cvtsi2sd{q}\t{$src, $dst|$dst, $src}",
1234                        [(set FR64:$dst, (sint_to_fp (loadi64 addr:$src)))]>;
1235
1236 let isTwoAddress = 1 in {
1237 def Int_CVTSI2SD64rr: RSDI<0x2A, MRMSrcReg,
1238                            (outs VR128:$dst), (ins VR128:$src1, GR64:$src2),
1239                            "cvtsi2sd{q}\t{$src2, $dst|$dst, $src2}",
1240                            [(set VR128:$dst,
1241                              (int_x86_sse2_cvtsi642sd VR128:$src1,
1242                               GR64:$src2))]>;
1243 def Int_CVTSI2SD64rm: RSDI<0x2A, MRMSrcMem,
1244                            (outs VR128:$dst), (ins VR128:$src1, i64mem:$src2),
1245                            "cvtsi2sd{q}\t{$src2, $dst|$dst, $src2}",
1246                            [(set VR128:$dst,
1247                              (int_x86_sse2_cvtsi642sd VR128:$src1,
1248                               (loadi64 addr:$src2)))]>;
1249 } // isTwoAddress
1250
1251 // Signed i64 -> f32
1252 def CVTSI2SS64rr: RSSI<0x2A, MRMSrcReg, (outs FR32:$dst), (ins GR64:$src),
1253                        "cvtsi2ss{q}\t{$src, $dst|$dst, $src}",
1254                        [(set FR32:$dst, (sint_to_fp GR64:$src))]>;
1255 def CVTSI2SS64rm: RSSI<0x2A, MRMSrcMem, (outs FR32:$dst), (ins i64mem:$src),
1256                        "cvtsi2ss{q}\t{$src, $dst|$dst, $src}",
1257                        [(set FR32:$dst, (sint_to_fp (loadi64 addr:$src)))]>;
1258
1259 let isTwoAddress = 1 in {
1260   def Int_CVTSI2SS64rr : RSSI<0x2A, MRMSrcReg,
1261                               (outs VR128:$dst), (ins VR128:$src1, GR64:$src2),
1262                               "cvtsi2ss{q}\t{$src2, $dst|$dst, $src2}",
1263                               [(set VR128:$dst,
1264                                 (int_x86_sse_cvtsi642ss VR128:$src1,
1265                                  GR64:$src2))]>;
1266   def Int_CVTSI2SS64rm : RSSI<0x2A, MRMSrcMem,
1267                               (outs VR128:$dst), (ins VR128:$src1, i64mem:$src2),
1268                               "cvtsi2ss{q}\t{$src2, $dst|$dst, $src2}",
1269                               [(set VR128:$dst,
1270                                 (int_x86_sse_cvtsi642ss VR128:$src1,
1271                                  (loadi64 addr:$src2)))]>;
1272 }
1273
1274 // f32 -> signed i64
1275 def Int_CVTSS2SI64rr: RSSI<0x2D, MRMSrcReg, (outs GR64:$dst), (ins VR128:$src),
1276                            "cvtss2si{q}\t{$src, $dst|$dst, $src}",
1277                            [(set GR64:$dst,
1278                              (int_x86_sse_cvtss2si64 VR128:$src))]>;
1279 def Int_CVTSS2SI64rm: RSSI<0x2D, MRMSrcMem, (outs GR64:$dst), (ins f32mem:$src),
1280                            "cvtss2si{q}\t{$src, $dst|$dst, $src}",
1281                            [(set GR64:$dst, (int_x86_sse_cvtss2si64
1282                                              (load addr:$src)))]>;
1283 def CVTTSS2SI64rr: RSSI<0x2C, MRMSrcReg, (outs GR64:$dst), (ins FR32:$src),
1284                         "cvttss2si{q}\t{$src, $dst|$dst, $src}",
1285                         [(set GR64:$dst, (fp_to_sint FR32:$src))]>;
1286 def CVTTSS2SI64rm: RSSI<0x2C, MRMSrcMem, (outs GR64:$dst), (ins f32mem:$src),
1287                         "cvttss2si{q}\t{$src, $dst|$dst, $src}",
1288                         [(set GR64:$dst, (fp_to_sint (loadf32 addr:$src)))]>;
1289 def Int_CVTTSS2SI64rr: RSSI<0x2C, MRMSrcReg, (outs GR64:$dst), (ins VR128:$src),
1290                             "cvttss2si{q}\t{$src, $dst|$dst, $src}",
1291                             [(set GR64:$dst,
1292                               (int_x86_sse_cvttss2si64 VR128:$src))]>;
1293 def Int_CVTTSS2SI64rm: RSSI<0x2C, MRMSrcMem, (outs GR64:$dst), (ins f32mem:$src),
1294                             "cvttss2si{q}\t{$src, $dst|$dst, $src}",
1295                             [(set GR64:$dst,
1296                               (int_x86_sse_cvttss2si64 (load addr:$src)))]>;
1297
1298 //===----------------------------------------------------------------------===//
1299 // Alias Instructions
1300 //===----------------------------------------------------------------------===//
1301
1302 // Alias instructions that map movr0 to xor. Use xorl instead of xorq; it's
1303 // equivalent due to implicit zero-extending, and it sometimes has a smaller
1304 // encoding.
1305 // FIXME: remove when we can teach regalloc that xor reg, reg is ok.
1306 // FIXME: AddedComplexity gives MOV64r0 a higher priority than MOV64ri32. Remove
1307 // when we have a better way to specify isel priority.
1308 let Defs = [EFLAGS], AddedComplexity = 1,
1309     isReMaterializable = 1, isAsCheapAsAMove = 1 in
1310 def MOV64r0  : I<0x31, MRMInitReg,  (outs GR64:$dst), (ins),
1311                 "xor{l}\t${dst:subreg32}, ${dst:subreg32}",
1312                 [(set GR64:$dst, 0)]>;
1313
1314 // Materialize i64 constant where top 32-bits are zero.
1315 let AddedComplexity = 1, isReMaterializable = 1, isAsCheapAsAMove = 1 in
1316 def MOV64ri64i32 : Ii32<0xB8, AddRegFrm, (outs GR64:$dst), (ins i64i32imm:$src),
1317                         "mov{l}\t{$src, ${dst:subreg32}|${dst:subreg32}, $src}",
1318                         [(set GR64:$dst, i64immZExt32:$src)]>;
1319
1320 //===----------------------------------------------------------------------===//
1321 // Thread Local Storage Instructions
1322 //===----------------------------------------------------------------------===//
1323
1324 // All calls clobber the non-callee saved registers. RSP is marked as
1325 // a use to prevent stack-pointer assignments that appear immediately
1326 // before calls from potentially appearing dead.
1327 let Defs = [RAX, RCX, RDX, RSI, RDI, R8, R9, R10, R11,
1328             FP0, FP1, FP2, FP3, FP4, FP5, FP6, ST0, ST1,
1329             MM0, MM1, MM2, MM3, MM4, MM5, MM6, MM7,
1330             XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7,
1331             XMM8, XMM9, XMM10, XMM11, XMM12, XMM13, XMM14, XMM15, EFLAGS],
1332     Uses = [RSP] in
1333 def TLS_addr64 : I<0, Pseudo, (outs), (ins i64imm:$sym),
1334                    ".byte\t0x66; "
1335                    "leaq\t${sym:mem}(%rip), %rdi; "
1336                    ".word\t0x6666; "
1337                    "rex64; "
1338                    "call\t__tls_get_addr@PLT",
1339                   [(X86tlsaddr tglobaltlsaddr:$sym)]>,
1340                   Requires<[In64BitMode]>;
1341
1342 let AddedComplexity = 5 in
1343 def MOV64GSrm : RI<0x8B, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
1344                  "movq\t%gs:$src, $dst",
1345                  [(set GR64:$dst, (gsload addr:$src))]>, SegGS;
1346
1347 let AddedComplexity = 5 in
1348 def MOV64FSrm : RI<0x8B, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
1349                  "movq\t%fs:$src, $dst",
1350                  [(set GR64:$dst, (fsload addr:$src))]>, SegFS;
1351
1352 //===----------------------------------------------------------------------===//
1353 // Atomic Instructions
1354 //===----------------------------------------------------------------------===//
1355
1356 let Defs = [RAX, EFLAGS], Uses = [RAX] in {
1357 def LCMPXCHG64 : RI<0xB1, MRMDestMem, (outs), (ins i64mem:$ptr, GR64:$swap),
1358                "lock\n\t"
1359                "cmpxchgq\t$swap,$ptr",
1360                [(X86cas addr:$ptr, GR64:$swap, 8)]>, TB, LOCK;
1361 }
1362
1363 let Constraints = "$val = $dst" in {
1364 let Defs = [EFLAGS] in
1365 def LXADD64 : RI<0xC1, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$ptr,GR64:$val),
1366                "lock\n\t"
1367                "xadd\t$val, $ptr",
1368                [(set GR64:$dst, (atomic_load_add_64 addr:$ptr, GR64:$val))]>,
1369                 TB, LOCK;
1370 def XCHG64rm : RI<0x87, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$ptr,GR64:$val),
1371                   "xchg\t$val, $ptr", 
1372                   [(set GR64:$dst, (atomic_swap_64 addr:$ptr, GR64:$val))]>;
1373 }
1374
1375 // Atomic exchange, and, or, xor
1376 let Constraints = "$val = $dst", Defs = [EFLAGS],
1377                   usesCustomDAGSchedInserter = 1 in {
1378 def ATOMAND64 : I<0, Pseudo, (outs GR64:$dst),(ins i64mem:$ptr, GR64:$val),
1379                "#ATOMAND64 PSEUDO!", 
1380                [(set GR64:$dst, (atomic_load_and_64 addr:$ptr, GR64:$val))]>;
1381 def ATOMOR64 : I<0, Pseudo, (outs GR64:$dst),(ins i64mem:$ptr, GR64:$val),
1382                "#ATOMOR64 PSEUDO!", 
1383                [(set GR64:$dst, (atomic_load_or_64 addr:$ptr, GR64:$val))]>;
1384 def ATOMXOR64 : I<0, Pseudo,(outs GR64:$dst),(ins i64mem:$ptr, GR64:$val),
1385                "#ATOMXOR64 PSEUDO!", 
1386                [(set GR64:$dst, (atomic_load_xor_64 addr:$ptr, GR64:$val))]>;
1387 def ATOMNAND64 : I<0, Pseudo,(outs GR64:$dst),(ins i64mem:$ptr, GR64:$val),
1388                "#ATOMNAND64 PSEUDO!", 
1389                [(set GR64:$dst, (atomic_load_nand_64 addr:$ptr, GR64:$val))]>;
1390 def ATOMMIN64: I<0, Pseudo, (outs GR64:$dst), (ins i64mem:$ptr, GR64:$val),
1391                "#ATOMMIN64 PSEUDO!", 
1392                [(set GR64:$dst, (atomic_load_min_64 addr:$ptr, GR64:$val))]>;
1393 def ATOMMAX64: I<0, Pseudo, (outs GR64:$dst),(ins i64mem:$ptr, GR64:$val),
1394                "#ATOMMAX64 PSEUDO!", 
1395                [(set GR64:$dst, (atomic_load_max_64 addr:$ptr, GR64:$val))]>;
1396 def ATOMUMIN64: I<0, Pseudo, (outs GR64:$dst),(ins i64mem:$ptr, GR64:$val),
1397                "#ATOMUMIN64 PSEUDO!", 
1398                [(set GR64:$dst, (atomic_load_umin_64 addr:$ptr, GR64:$val))]>;
1399 def ATOMUMAX64: I<0, Pseudo, (outs GR64:$dst),(ins i64mem:$ptr, GR64:$val),
1400                "#ATOMUMAX64 PSEUDO!", 
1401                [(set GR64:$dst, (atomic_load_umax_64 addr:$ptr, GR64:$val))]>;
1402 }
1403
1404 //===----------------------------------------------------------------------===//
1405 // Non-Instruction Patterns
1406 //===----------------------------------------------------------------------===//
1407
1408 // ConstantPool GlobalAddress, ExternalSymbol, and JumpTable
1409 def : Pat<(i64 (X86Wrapper tconstpool  :$dst)),
1410           (MOV64ri tconstpool  :$dst)>, Requires<[NotSmallCode]>;
1411 def : Pat<(i64 (X86Wrapper tjumptable  :$dst)),
1412           (MOV64ri tjumptable  :$dst)>, Requires<[NotSmallCode]>;
1413 def : Pat<(i64 (X86Wrapper tglobaladdr :$dst)),
1414           (MOV64ri tglobaladdr :$dst)>, Requires<[NotSmallCode]>;
1415 def : Pat<(i64 (X86Wrapper texternalsym:$dst)),
1416           (MOV64ri texternalsym:$dst)>, Requires<[NotSmallCode]>;
1417
1418 def : Pat<(store (i64 (X86Wrapper tconstpool:$src)), addr:$dst),
1419           (MOV64mi32 addr:$dst, tconstpool:$src)>,
1420           Requires<[SmallCode, IsStatic]>;
1421 def : Pat<(store (i64 (X86Wrapper tjumptable:$src)), addr:$dst),
1422           (MOV64mi32 addr:$dst, tjumptable:$src)>,
1423           Requires<[SmallCode, IsStatic]>;
1424 def : Pat<(store (i64 (X86Wrapper tglobaladdr:$src)), addr:$dst),
1425           (MOV64mi32 addr:$dst, tglobaladdr:$src)>,
1426           Requires<[SmallCode, IsStatic]>;
1427 def : Pat<(store (i64 (X86Wrapper texternalsym:$src)), addr:$dst),
1428           (MOV64mi32 addr:$dst, texternalsym:$src)>,
1429           Requires<[SmallCode, IsStatic]>;
1430
1431 // Calls
1432 // Direct PC relative function call for small code model. 32-bit displacement
1433 // sign extended to 64-bit.
1434 def : Pat<(X86call (i64 tglobaladdr:$dst)),
1435           (CALL64pcrel32 tglobaladdr:$dst)>;
1436 def : Pat<(X86call (i64 texternalsym:$dst)),
1437           (CALL64pcrel32 texternalsym:$dst)>;
1438
1439 def : Pat<(X86tailcall (i64 tglobaladdr:$dst)),
1440           (CALL64pcrel32 tglobaladdr:$dst)>;
1441 def : Pat<(X86tailcall (i64 texternalsym:$dst)),
1442           (CALL64pcrel32 texternalsym:$dst)>;
1443
1444 def : Pat<(X86tailcall GR64:$dst),
1445           (CALL64r GR64:$dst)>;
1446
1447
1448 // tailcall stuff
1449 def : Pat<(X86tailcall GR32:$dst),
1450           (TAILCALL)>;
1451 def : Pat<(X86tailcall (i64 tglobaladdr:$dst)),
1452           (TAILCALL)>;
1453 def : Pat<(X86tailcall (i64 texternalsym:$dst)),
1454           (TAILCALL)>;
1455
1456 def : Pat<(X86tcret GR64:$dst, imm:$off),
1457           (TCRETURNri64 GR64:$dst, imm:$off)>;
1458
1459 def : Pat<(X86tcret (i64 tglobaladdr:$dst), imm:$off),
1460           (TCRETURNdi64 texternalsym:$dst, imm:$off)>;
1461
1462 def : Pat<(X86tcret (i64 texternalsym:$dst), imm:$off),
1463           (TCRETURNdi64 texternalsym:$dst, imm:$off)>;
1464
1465 // Comparisons.
1466
1467 // TEST R,R is smaller than CMP R,0
1468 def : Pat<(parallel (X86cmp GR64:$src1, 0), (implicit EFLAGS)),
1469           (TEST64rr GR64:$src1, GR64:$src1)>;
1470
1471 // Conditional moves with folded loads with operands swapped and conditions
1472 // inverted.
1473 def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_B, EFLAGS),
1474           (CMOVAE64rm GR64:$src2, addr:$src1)>;
1475 def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_AE, EFLAGS),
1476           (CMOVB64rm GR64:$src2, addr:$src1)>;
1477 def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_E, EFLAGS),
1478           (CMOVNE64rm GR64:$src2, addr:$src1)>;
1479 def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_NE, EFLAGS),
1480           (CMOVE64rm GR64:$src2, addr:$src1)>;
1481 def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_BE, EFLAGS),
1482           (CMOVA64rm GR64:$src2, addr:$src1)>;
1483 def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_A, EFLAGS),
1484           (CMOVBE64rm GR64:$src2, addr:$src1)>;
1485 def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_L, EFLAGS),
1486           (CMOVGE64rm GR64:$src2, addr:$src1)>;
1487 def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_GE, EFLAGS),
1488           (CMOVL64rm GR64:$src2, addr:$src1)>;
1489 def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_LE, EFLAGS),
1490           (CMOVG64rm GR64:$src2, addr:$src1)>;
1491 def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_G, EFLAGS),
1492           (CMOVLE64rm GR64:$src2, addr:$src1)>;
1493 def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_P, EFLAGS),
1494           (CMOVNP64rm GR64:$src2, addr:$src1)>;
1495 def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_NP, EFLAGS),
1496           (CMOVP64rm GR64:$src2, addr:$src1)>;
1497 def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_S, EFLAGS),
1498           (CMOVNS64rm GR64:$src2, addr:$src1)>;
1499 def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_NS, EFLAGS),
1500           (CMOVS64rm GR64:$src2, addr:$src1)>;
1501 def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_O, EFLAGS),
1502           (CMOVNO64rm GR64:$src2, addr:$src1)>;
1503 def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_NO, EFLAGS),
1504           (CMOVO64rm GR64:$src2, addr:$src1)>;
1505
1506 // zextload bool -> zextload byte
1507 def : Pat<(zextloadi64i1 addr:$src), (MOVZX64rm8 addr:$src)>;
1508
1509 // extload
1510 // When extloading from 16-bit and smaller memory locations into 64-bit registers,
1511 // use zero-extending loads so that the entire 64-bit register is defined, avoiding
1512 // partial-register updates.
1513 def : Pat<(extloadi64i1 addr:$src),  (MOVZX64rm8  addr:$src)>;
1514 def : Pat<(extloadi64i8 addr:$src),  (MOVZX64rm8  addr:$src)>;
1515 def : Pat<(extloadi64i16 addr:$src), (MOVZX64rm16 addr:$src)>;
1516 // For other extloads, use subregs, since the high contents of the register are
1517 // defined after an extload.
1518 def : Pat<(extloadi64i32 addr:$src),
1519           (INSERT_SUBREG (i64 (IMPLICIT_DEF)), (MOV32rm addr:$src),
1520                          x86_subreg_32bit)>;
1521 def : Pat<(extloadi16i1 addr:$src), 
1522           (INSERT_SUBREG (i16 (IMPLICIT_DEF)), (MOV8rm addr:$src), 
1523                          x86_subreg_8bit)>,
1524          Requires<[In64BitMode]>;
1525 def : Pat<(extloadi16i8 addr:$src), 
1526           (INSERT_SUBREG (i16 (IMPLICIT_DEF)), (MOV8rm addr:$src), 
1527                          x86_subreg_8bit)>,
1528          Requires<[In64BitMode]>;
1529
1530 // anyext
1531 def : Pat<(i64 (anyext GR8:$src)),
1532           (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR8:$src, x86_subreg_8bit)>;
1533 def : Pat<(i64 (anyext GR16:$src)),
1534           (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR16:$src, x86_subreg_16bit)>;
1535 def : Pat<(i64 (anyext GR32:$src)), 
1536           (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR32:$src, x86_subreg_32bit)>;
1537 def : Pat<(i16 (anyext GR8:$src)),
1538           (INSERT_SUBREG (i16 (IMPLICIT_DEF)), GR8:$src, x86_subreg_8bit)>,
1539          Requires<[In64BitMode]>;
1540 def : Pat<(i32 (anyext GR8:$src)),
1541           (INSERT_SUBREG (i32 (IMPLICIT_DEF)), GR8:$src, x86_subreg_8bit)>,
1542          Requires<[In64BitMode]>;
1543
1544 //===----------------------------------------------------------------------===//
1545 // Some peepholes
1546 //===----------------------------------------------------------------------===//
1547
1548 // Odd encoding trick: -128 fits into an 8-bit immediate field while
1549 // +128 doesn't, so in this special case use a sub instead of an add.
1550 def : Pat<(add GR64:$src1, 128),
1551           (SUB64ri8 GR64:$src1, -128)>;
1552 def : Pat<(store (add (loadi64 addr:$dst), 128), addr:$dst),
1553           (SUB64mi8 addr:$dst, -128)>;
1554
1555 // The same trick applies for 32-bit immediate fields in 64-bit
1556 // instructions.
1557 def : Pat<(add GR64:$src1, 0x0000000080000000),
1558           (SUB64ri32 GR64:$src1, 0xffffffff80000000)>;
1559 def : Pat<(store (add (loadi64 addr:$dst), 0x00000000800000000), addr:$dst),
1560           (SUB64mi32 addr:$dst, 0xffffffff80000000)>;
1561
1562 // r & (2^32-1) ==> movz
1563 def : Pat<(and GR64:$src, 0x00000000FFFFFFFF),
1564           (MOVZX64rr32 (EXTRACT_SUBREG GR64:$src, x86_subreg_32bit))>;
1565 // r & (2^16-1) ==> movz
1566 def : Pat<(and GR64:$src, 0xffff),
1567           (MOVZX64rr16 (i16 (EXTRACT_SUBREG GR64:$src, x86_subreg_16bit)))>;
1568 // r & (2^8-1) ==> movz
1569 def : Pat<(and GR64:$src, 0xff),
1570           (MOVZX64rr8 (i8 (EXTRACT_SUBREG GR64:$src, x86_subreg_8bit)))>;
1571 // r & (2^8-1) ==> movz
1572 def : Pat<(and GR32:$src1, 0xff),
1573            (MOVZX32rr8 (EXTRACT_SUBREG GR32:$src1, x86_subreg_8bit))>,
1574       Requires<[In64BitMode]>;
1575 // r & (2^8-1) ==> movz
1576 def : Pat<(and GR16:$src1, 0xff),
1577            (MOVZX16rr8 (i8 (EXTRACT_SUBREG GR16:$src1, x86_subreg_8bit)))>,
1578       Requires<[In64BitMode]>;
1579
1580 // sext_inreg patterns
1581 def : Pat<(sext_inreg GR64:$src, i32),
1582           (MOVSX64rr32 (EXTRACT_SUBREG GR64:$src, x86_subreg_32bit))>;
1583 def : Pat<(sext_inreg GR64:$src, i16),
1584           (MOVSX64rr16 (EXTRACT_SUBREG GR64:$src, x86_subreg_16bit))>;
1585 def : Pat<(sext_inreg GR64:$src, i8),
1586           (MOVSX64rr8 (EXTRACT_SUBREG GR64:$src, x86_subreg_8bit))>;
1587 def : Pat<(sext_inreg GR32:$src, i8),
1588           (MOVSX32rr8 (EXTRACT_SUBREG GR32:$src, x86_subreg_8bit))>,
1589       Requires<[In64BitMode]>;
1590 def : Pat<(sext_inreg GR16:$src, i8),
1591           (MOVSX16rr8 (i8 (EXTRACT_SUBREG GR16:$src, x86_subreg_8bit)))>,
1592       Requires<[In64BitMode]>;
1593
1594 // trunc patterns
1595 def : Pat<(i32 (trunc GR64:$src)),
1596           (EXTRACT_SUBREG GR64:$src, x86_subreg_32bit)>;
1597 def : Pat<(i16 (trunc GR64:$src)),
1598           (EXTRACT_SUBREG GR64:$src, x86_subreg_16bit)>;
1599 def : Pat<(i8 (trunc GR64:$src)),
1600           (EXTRACT_SUBREG GR64:$src, x86_subreg_8bit)>;
1601 def : Pat<(i8 (trunc GR32:$src)),
1602           (EXTRACT_SUBREG GR32:$src, x86_subreg_8bit)>,
1603       Requires<[In64BitMode]>;
1604 def : Pat<(i8 (trunc GR16:$src)),
1605           (EXTRACT_SUBREG GR16:$src, x86_subreg_8bit)>,
1606       Requires<[In64BitMode]>;
1607
1608 // h-register tricks.
1609 // For now, be conservative on x86-64 and use an h-register extract only if the
1610 // value is immediately zero-extended or stored, which are somewhat common
1611 // cases. This uses a bunch of code to prevent a register requiring a REX prefix
1612 // from being allocated in the same instruction as the h register, as there's
1613 // currently no way to describe this requirement to the register allocator.
1614
1615 // h-register extract and zero-extend.
1616 def : Pat<(and (srl_su GR64:$src, (i8 8)), (i64 255)),
1617           (SUBREG_TO_REG
1618             (i64 0),
1619             (MOVZX32_NOREXrr8
1620               (EXTRACT_SUBREG (COPY_TO_REGCLASS GR64:$src, GR64_ABCD),
1621                               x86_subreg_8bit_hi)),
1622             x86_subreg_32bit)>;
1623 def : Pat<(and (srl_su GR32:$src, (i8 8)), (i32 255)),
1624           (MOVZX32_NOREXrr8
1625             (EXTRACT_SUBREG (COPY_TO_REGCLASS GR32:$src, GR32_ABCD),
1626                             x86_subreg_8bit_hi))>,
1627       Requires<[In64BitMode]>;
1628 def : Pat<(srl_su GR16:$src, (i8 8)),
1629           (EXTRACT_SUBREG
1630             (MOVZX32_NOREXrr8
1631               (EXTRACT_SUBREG (COPY_TO_REGCLASS GR16:$src, GR16_ABCD),
1632                               x86_subreg_8bit_hi)),
1633             x86_subreg_16bit)>,
1634       Requires<[In64BitMode]>;
1635 def : Pat<(i32 (zext (srl_su GR16:$src, (i8 8)))),
1636           (MOVZX32_NOREXrr8
1637             (EXTRACT_SUBREG (COPY_TO_REGCLASS GR16:$src, GR16_ABCD),
1638                             x86_subreg_8bit_hi))>,
1639       Requires<[In64BitMode]>;
1640 def : Pat<(i64 (zext (srl_su GR16:$src, (i8 8)))),
1641           (SUBREG_TO_REG
1642             (i64 0),
1643             (MOVZX32_NOREXrr8
1644               (EXTRACT_SUBREG (COPY_TO_REGCLASS GR16:$src, GR16_ABCD),
1645                               x86_subreg_8bit_hi)),
1646             x86_subreg_32bit)>;
1647
1648 // h-register extract and store.
1649 def : Pat<(store (i8 (trunc_su (srl_su GR64:$src, (i8 8)))), addr:$dst),
1650           (MOV8mr_NOREX
1651             addr:$dst,
1652             (EXTRACT_SUBREG (COPY_TO_REGCLASS GR64:$src, GR64_ABCD),
1653                             x86_subreg_8bit_hi))>;
1654 def : Pat<(store (i8 (trunc_su (srl_su GR32:$src, (i8 8)))), addr:$dst),
1655           (MOV8mr_NOREX
1656             addr:$dst,
1657             (EXTRACT_SUBREG (COPY_TO_REGCLASS GR32:$src, GR32_ABCD),
1658                             x86_subreg_8bit_hi))>,
1659       Requires<[In64BitMode]>;
1660 def : Pat<(store (i8 (trunc_su (srl_su GR16:$src, (i8 8)))), addr:$dst),
1661           (MOV8mr_NOREX
1662             addr:$dst,
1663             (EXTRACT_SUBREG (COPY_TO_REGCLASS GR16:$src, GR16_ABCD),
1664                             x86_subreg_8bit_hi))>,
1665       Requires<[In64BitMode]>;
1666
1667 // (shl x, 1) ==> (add x, x)
1668 def : Pat<(shl GR64:$src1, (i8 1)), (ADD64rr GR64:$src1, GR64:$src1)>;
1669
1670 // (shl x (and y, 63)) ==> (shl x, y)
1671 def : Pat<(shl GR64:$src1, (and CL:$amt, 63)),
1672           (SHL64rCL GR64:$src1)>;
1673 def : Pat<(store (shl (loadi64 addr:$dst), (and CL:$amt, 63)), addr:$dst),
1674           (SHL64mCL addr:$dst)>;
1675
1676 def : Pat<(srl GR64:$src1, (and CL:$amt, 63)),
1677           (SHR64rCL GR64:$src1)>;
1678 def : Pat<(store (srl (loadi64 addr:$dst), (and CL:$amt, 63)), addr:$dst),
1679           (SHR64mCL addr:$dst)>;
1680
1681 def : Pat<(sra GR64:$src1, (and CL:$amt, 63)),
1682           (SAR64rCL GR64:$src1)>;
1683 def : Pat<(store (sra (loadi64 addr:$dst), (and CL:$amt, 63)), addr:$dst),
1684           (SAR64mCL addr:$dst)>;
1685
1686 // (or (x >> c) | (y << (64 - c))) ==> (shrd64 x, y, c)
1687 def : Pat<(or (srl GR64:$src1, CL:$amt),
1688               (shl GR64:$src2, (sub 64, CL:$amt))),
1689           (SHRD64rrCL GR64:$src1, GR64:$src2)>;
1690
1691 def : Pat<(store (or (srl (loadi64 addr:$dst), CL:$amt),
1692                      (shl GR64:$src2, (sub 64, CL:$amt))), addr:$dst),
1693           (SHRD64mrCL addr:$dst, GR64:$src2)>;
1694
1695 def : Pat<(or (srl GR64:$src1, (i8 (trunc RCX:$amt))),
1696               (shl GR64:$src2, (i8 (trunc (sub 64, RCX:$amt))))),
1697           (SHRD64rrCL GR64:$src1, GR64:$src2)>;
1698
1699 def : Pat<(store (or (srl (loadi64 addr:$dst), (i8 (trunc RCX:$amt))),
1700                      (shl GR64:$src2, (i8 (trunc (sub 64, RCX:$amt))))),
1701                  addr:$dst),
1702           (SHRD64mrCL addr:$dst, GR64:$src2)>;
1703
1704 def : Pat<(shrd GR64:$src1, (i8 imm:$amt1), GR64:$src2, (i8 imm:$amt2)),
1705           (SHRD64rri8 GR64:$src1, GR64:$src2, (i8 imm:$amt1))>;
1706
1707 def : Pat<(store (shrd (loadi64 addr:$dst), (i8 imm:$amt1),
1708                        GR64:$src2, (i8 imm:$amt2)), addr:$dst),
1709           (SHRD64mri8 addr:$dst, GR64:$src2, (i8 imm:$amt1))>;
1710
1711 // (or (x << c) | (y >> (64 - c))) ==> (shld64 x, y, c)
1712 def : Pat<(or (shl GR64:$src1, CL:$amt),
1713               (srl GR64:$src2, (sub 64, CL:$amt))),
1714           (SHLD64rrCL GR64:$src1, GR64:$src2)>;
1715
1716 def : Pat<(store (or (shl (loadi64 addr:$dst), CL:$amt),
1717                      (srl GR64:$src2, (sub 64, CL:$amt))), addr:$dst),
1718           (SHLD64mrCL addr:$dst, GR64:$src2)>;
1719
1720 def : Pat<(or (shl GR64:$src1, (i8 (trunc RCX:$amt))),
1721               (srl GR64:$src2, (i8 (trunc (sub 64, RCX:$amt))))),
1722           (SHLD64rrCL GR64:$src1, GR64:$src2)>;
1723
1724 def : Pat<(store (or (shl (loadi64 addr:$dst), (i8 (trunc RCX:$amt))),
1725                      (srl GR64:$src2, (i8 (trunc (sub 64, RCX:$amt))))),
1726                  addr:$dst),
1727           (SHLD64mrCL addr:$dst, GR64:$src2)>;
1728
1729 def : Pat<(shld GR64:$src1, (i8 imm:$amt1), GR64:$src2, (i8 imm:$amt2)),
1730           (SHLD64rri8 GR64:$src1, GR64:$src2, (i8 imm:$amt1))>;
1731
1732 def : Pat<(store (shld (loadi64 addr:$dst), (i8 imm:$amt1),
1733                        GR64:$src2, (i8 imm:$amt2)), addr:$dst),
1734           (SHLD64mri8 addr:$dst, GR64:$src2, (i8 imm:$amt1))>;
1735
1736 // X86 specific add which produces a flag.
1737 def : Pat<(addc GR64:$src1, GR64:$src2),
1738           (ADD64rr GR64:$src1, GR64:$src2)>;
1739 def : Pat<(addc GR64:$src1, (load addr:$src2)),
1740           (ADD64rm GR64:$src1, addr:$src2)>;
1741 def : Pat<(addc GR64:$src1, i64immSExt8:$src2),
1742           (ADD64ri8 GR64:$src1, i64immSExt8:$src2)>;
1743 def : Pat<(addc GR64:$src1, i64immSExt32:$src2),
1744           (ADD64ri32 GR64:$src1, imm:$src2)>;
1745
1746 def : Pat<(subc GR64:$src1, GR64:$src2),
1747           (SUB64rr GR64:$src1, GR64:$src2)>;
1748 def : Pat<(subc GR64:$src1, (load addr:$src2)),
1749           (SUB64rm GR64:$src1, addr:$src2)>;
1750 def : Pat<(subc GR64:$src1, i64immSExt8:$src2),
1751           (SUB64ri8 GR64:$src1, i64immSExt8:$src2)>;
1752 def : Pat<(subc GR64:$src1, imm:$src2),
1753           (SUB64ri32 GR64:$src1, i64immSExt32:$src2)>;
1754
1755 //===----------------------------------------------------------------------===//
1756 // EFLAGS-defining Patterns
1757 //===----------------------------------------------------------------------===//
1758
1759 // Register-Register Addition with EFLAGS result
1760 def : Pat<(parallel (X86add_flag GR64:$src1, GR64:$src2),
1761                     (implicit EFLAGS)),
1762           (ADD64rr GR64:$src1, GR64:$src2)>;
1763
1764 // Register-Integer Addition with EFLAGS result
1765 def : Pat<(parallel (X86add_flag GR64:$src1, i64immSExt8:$src2),
1766                     (implicit EFLAGS)),
1767           (ADD64ri8 GR64:$src1, i64immSExt8:$src2)>;
1768 def : Pat<(parallel (X86add_flag GR64:$src1, i64immSExt32:$src2),
1769                     (implicit EFLAGS)),
1770           (ADD64ri32 GR64:$src1, i64immSExt32:$src2)>;
1771
1772 // Register-Memory Addition with EFLAGS result
1773 def : Pat<(parallel (X86add_flag GR64:$src1, (loadi64 addr:$src2)),
1774                     (implicit EFLAGS)),
1775           (ADD64rm GR64:$src1, addr:$src2)>;
1776
1777 // Memory-Register Addition with EFLAGS result
1778 def : Pat<(parallel (store (X86add_flag (loadi64 addr:$dst), GR64:$src2),
1779                            addr:$dst),
1780                     (implicit EFLAGS)),
1781           (ADD64mr addr:$dst, GR64:$src2)>;
1782 def : Pat<(parallel (store (X86add_flag (loadi64 addr:$dst), i64immSExt8:$src2),
1783                            addr:$dst),
1784                     (implicit EFLAGS)),
1785           (ADD64mi8 addr:$dst, i64immSExt8:$src2)>;
1786 def : Pat<(parallel (store (X86add_flag (loadi64 addr:$dst), i64immSExt32:$src2),
1787                            addr:$dst),
1788                     (implicit EFLAGS)),
1789           (ADD64mi32 addr:$dst, i64immSExt32:$src2)>;
1790
1791 // Register-Register Subtraction with EFLAGS result
1792 def : Pat<(parallel (X86sub_flag GR64:$src1, GR64:$src2),
1793                     (implicit EFLAGS)),
1794           (SUB64rr GR64:$src1, GR64:$src2)>;
1795
1796 // Register-Memory Subtraction with EFLAGS result
1797 def : Pat<(parallel (X86sub_flag GR64:$src1, (loadi64 addr:$src2)),
1798                     (implicit EFLAGS)),
1799           (SUB64rm GR64:$src1, addr:$src2)>;
1800
1801 // Register-Integer Subtraction with EFLAGS result
1802 def : Pat<(parallel (X86sub_flag GR64:$src1, i64immSExt8:$src2),
1803                     (implicit EFLAGS)),
1804           (SUB64ri8 GR64:$src1, i64immSExt8:$src2)>;
1805 def : Pat<(parallel (X86sub_flag GR64:$src1, i64immSExt32:$src2),
1806                     (implicit EFLAGS)),
1807           (SUB64ri32 GR64:$src1, i64immSExt32:$src2)>;
1808
1809 // Memory-Register Subtraction with EFLAGS result
1810 def : Pat<(parallel (store (X86sub_flag (loadi64 addr:$dst), GR64:$src2),
1811                            addr:$dst),
1812                     (implicit EFLAGS)),
1813           (SUB64mr addr:$dst, GR64:$src2)>;
1814
1815 // Memory-Integer Subtraction with EFLAGS result
1816 def : Pat<(parallel (store (X86sub_flag (loadi64 addr:$dst), i64immSExt8:$src2),
1817                            addr:$dst),
1818                     (implicit EFLAGS)),
1819           (SUB64mi8 addr:$dst, i64immSExt8:$src2)>;
1820 def : Pat<(parallel (store (X86sub_flag (loadi64 addr:$dst), i64immSExt32:$src2),
1821                            addr:$dst),
1822                     (implicit EFLAGS)),
1823           (SUB64mi32 addr:$dst, i64immSExt32:$src2)>;
1824
1825 // Register-Register Signed Integer Multiplication with EFLAGS result
1826 def : Pat<(parallel (X86smul_flag GR64:$src1, GR64:$src2),
1827                     (implicit EFLAGS)),
1828           (IMUL64rr GR64:$src1, GR64:$src2)>;
1829
1830 // Register-Memory Signed Integer Multiplication with EFLAGS result
1831 def : Pat<(parallel (X86smul_flag GR64:$src1, (loadi64 addr:$src2)),
1832                     (implicit EFLAGS)),
1833           (IMUL64rm GR64:$src1, addr:$src2)>;
1834
1835 // Register-Integer Signed Integer Multiplication with EFLAGS result
1836 def : Pat<(parallel (X86smul_flag GR64:$src1, i64immSExt8:$src2),
1837                     (implicit EFLAGS)),
1838           (IMUL64rri8 GR64:$src1, i64immSExt8:$src2)>;
1839 def : Pat<(parallel (X86smul_flag GR64:$src1, i64immSExt32:$src2),
1840                     (implicit EFLAGS)),
1841           (IMUL64rri32 GR64:$src1, i64immSExt32:$src2)>;
1842
1843 // Memory-Integer Signed Integer Multiplication with EFLAGS result
1844 def : Pat<(parallel (X86smul_flag (loadi64 addr:$src1), i64immSExt8:$src2),
1845                     (implicit EFLAGS)),
1846           (IMUL64rmi8 addr:$src1, i64immSExt8:$src2)>;
1847 def : Pat<(parallel (X86smul_flag (loadi64 addr:$src1), i64immSExt32:$src2),
1848                     (implicit EFLAGS)),
1849           (IMUL64rmi32 addr:$src1, i64immSExt32:$src2)>;
1850
1851 // INC and DEC with EFLAGS result. Note that these do not set CF.
1852 def : Pat<(parallel (X86inc_flag GR16:$src), (implicit EFLAGS)),
1853           (INC64_16r GR16:$src)>, Requires<[In64BitMode]>;
1854 def : Pat<(parallel (store (i16 (X86inc_flag (loadi16 addr:$dst))), addr:$dst),
1855                     (implicit EFLAGS)),
1856           (INC64_16m addr:$dst)>, Requires<[In64BitMode]>;
1857 def : Pat<(parallel (X86dec_flag GR16:$src), (implicit EFLAGS)),
1858           (DEC64_16r GR16:$src)>, Requires<[In64BitMode]>;
1859 def : Pat<(parallel (store (i16 (X86dec_flag (loadi16 addr:$dst))), addr:$dst),
1860                     (implicit EFLAGS)),
1861           (DEC64_16m addr:$dst)>, Requires<[In64BitMode]>;
1862
1863 def : Pat<(parallel (X86inc_flag GR32:$src), (implicit EFLAGS)),
1864           (INC64_32r GR32:$src)>, Requires<[In64BitMode]>;
1865 def : Pat<(parallel (store (i32 (X86inc_flag (loadi32 addr:$dst))), addr:$dst),
1866                     (implicit EFLAGS)),
1867           (INC64_32m addr:$dst)>, Requires<[In64BitMode]>;
1868 def : Pat<(parallel (X86dec_flag GR32:$src), (implicit EFLAGS)),
1869           (DEC64_32r GR32:$src)>, Requires<[In64BitMode]>;
1870 def : Pat<(parallel (store (i32 (X86dec_flag (loadi32 addr:$dst))), addr:$dst),
1871                     (implicit EFLAGS)),
1872           (DEC64_32m addr:$dst)>, Requires<[In64BitMode]>;
1873
1874 def : Pat<(parallel (X86inc_flag GR64:$src), (implicit EFLAGS)),
1875           (INC64r GR64:$src)>;
1876 def : Pat<(parallel (store (i64 (X86inc_flag (loadi64 addr:$dst))), addr:$dst),
1877                     (implicit EFLAGS)),
1878           (INC64m addr:$dst)>;
1879 def : Pat<(parallel (X86dec_flag GR64:$src), (implicit EFLAGS)),
1880           (DEC64r GR64:$src)>;
1881 def : Pat<(parallel (store (i64 (X86dec_flag (loadi64 addr:$dst))), addr:$dst),
1882                     (implicit EFLAGS)),
1883           (DEC64m addr:$dst)>;
1884
1885 //===----------------------------------------------------------------------===//
1886 // X86-64 SSE Instructions
1887 //===----------------------------------------------------------------------===//
1888
1889 // Move instructions...
1890
1891 def MOV64toPQIrr : RPDI<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR64:$src),
1892                         "mov{d|q}\t{$src, $dst|$dst, $src}",
1893                         [(set VR128:$dst,
1894                           (v2i64 (scalar_to_vector GR64:$src)))]>;
1895 def MOVPQIto64rr  : RPDI<0x7E, MRMDestReg, (outs GR64:$dst), (ins VR128:$src),
1896                          "mov{d|q}\t{$src, $dst|$dst, $src}",
1897                          [(set GR64:$dst, (vector_extract (v2i64 VR128:$src),
1898                                            (iPTR 0)))]>;
1899
1900 def MOV64toSDrr : RPDI<0x6E, MRMSrcReg, (outs FR64:$dst), (ins GR64:$src),
1901                        "mov{d|q}\t{$src, $dst|$dst, $src}",
1902                        [(set FR64:$dst, (bitconvert GR64:$src))]>;
1903 def MOV64toSDrm : RPDI<0x6E, MRMSrcMem, (outs FR64:$dst), (ins i64mem:$src),
1904                        "movq\t{$src, $dst|$dst, $src}",
1905                        [(set FR64:$dst, (bitconvert (loadi64 addr:$src)))]>;
1906
1907 def MOVSDto64rr  : RPDI<0x7E, MRMDestReg, (outs GR64:$dst), (ins FR64:$src),
1908                         "mov{d|q}\t{$src, $dst|$dst, $src}",
1909                         [(set GR64:$dst, (bitconvert FR64:$src))]>;
1910 def MOVSDto64mr  : RPDI<0x7E, MRMDestMem, (outs), (ins i64mem:$dst, FR64:$src),
1911                         "movq\t{$src, $dst|$dst, $src}",
1912                         [(store (i64 (bitconvert FR64:$src)), addr:$dst)]>;
1913
1914 //===----------------------------------------------------------------------===//
1915 // X86-64 SSE4.1 Instructions
1916 //===----------------------------------------------------------------------===//
1917
1918 /// SS41I_extract32 - SSE 4.1 extract 32 bits to int reg or memory destination
1919 multiclass SS41I_extract64<bits<8> opc, string OpcodeStr> {
1920   def rr : SS4AIi8<opc, MRMDestReg, (outs GR64:$dst),
1921                  (ins VR128:$src1, i32i8imm:$src2),
1922                  !strconcat(OpcodeStr, 
1923                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
1924                  [(set GR64:$dst,
1925                   (extractelt (v2i64 VR128:$src1), imm:$src2))]>, OpSize, REX_W;
1926   def mr : SS4AIi8<opc, MRMDestMem, (outs),
1927                  (ins i64mem:$dst, VR128:$src1, i32i8imm:$src2),
1928                  !strconcat(OpcodeStr, 
1929                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
1930                  [(store (extractelt (v2i64 VR128:$src1), imm:$src2),
1931                           addr:$dst)]>, OpSize, REX_W;
1932 }
1933
1934 defm PEXTRQ      : SS41I_extract64<0x16, "pextrq">;
1935
1936 let isTwoAddress = 1 in {
1937   multiclass SS41I_insert64<bits<8> opc, string OpcodeStr> {
1938     def rr : SS4AIi8<opc, MRMSrcReg, (outs VR128:$dst),
1939                    (ins VR128:$src1, GR64:$src2, i32i8imm:$src3),
1940                    !strconcat(OpcodeStr, 
1941                     "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
1942                    [(set VR128:$dst, 
1943                      (v2i64 (insertelt VR128:$src1, GR64:$src2, imm:$src3)))]>,
1944                    OpSize, REX_W;
1945     def rm : SS4AIi8<opc, MRMSrcMem, (outs VR128:$dst),
1946                    (ins VR128:$src1, i64mem:$src2, i32i8imm:$src3),
1947                    !strconcat(OpcodeStr,
1948                     "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
1949                    [(set VR128:$dst, 
1950                      (v2i64 (insertelt VR128:$src1, (loadi64 addr:$src2),
1951                                        imm:$src3)))]>, OpSize, REX_W;
1952   }
1953 }
1954
1955 defm PINSRQ      : SS41I_insert64<0x22, "pinsrq">;