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