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