Revert r354244 "[DAGCombiner] Eliminate dead stores to stack."
[llvm-complete.git] / lib / Target / X86 / X86InstrCompiler.td
blob55e87aabb78524eb4979640a9d706427c1a4a4b2
1 //===- X86InstrCompiler.td - Compiler Pseudos and Patterns -*- tablegen -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file describes the various pseudo instructions used by the compiler,
10 // as well as Pat patterns used during instruction selection.
12 //===----------------------------------------------------------------------===//
14 //===----------------------------------------------------------------------===//
15 // Pattern Matching Support
17 def GetLo32XForm : SDNodeXForm<imm, [{
18   // Transformation function: get the low 32 bits.
19   return getI32Imm((uint32_t)N->getZExtValue(), SDLoc(N));
20 }]>;
22 def GetLo8XForm : SDNodeXForm<imm, [{
23   // Transformation function: get the low 8 bits.
24   return getI8Imm((uint8_t)N->getZExtValue(), SDLoc(N));
25 }]>;
28 //===----------------------------------------------------------------------===//
29 // Random Pseudo Instructions.
31 // PIC base construction.  This expands to code that looks like this:
32 //     call  $next_inst
33 //     popl %destreg"
34 let hasSideEffects = 0, isNotDuplicable = 1, Uses = [ESP, SSP],
35     SchedRW = [WriteJump] in
36   def MOVPC32r : Ii32<0xE8, Pseudo, (outs GR32:$reg), (ins i32imm:$label),
37                       "", []>;
39 // ADJCALLSTACKDOWN/UP implicitly use/def ESP because they may be expanded into
40 // a stack adjustment and the codegen must know that they may modify the stack
41 // pointer before prolog-epilog rewriting occurs.
42 // Pessimistically assume ADJCALLSTACKDOWN / ADJCALLSTACKUP will become
43 // sub / add which can clobber EFLAGS.
44 let Defs = [ESP, EFLAGS, SSP], Uses = [ESP, SSP], SchedRW = [WriteALU] in {
45 def ADJCALLSTACKDOWN32 : I<0, Pseudo, (outs),
46                            (ins i32imm:$amt1, i32imm:$amt2, i32imm:$amt3),
47                            "#ADJCALLSTACKDOWN", []>, Requires<[NotLP64]>;
48 def ADJCALLSTACKUP32   : I<0, Pseudo, (outs), (ins i32imm:$amt1, i32imm:$amt2),
49                            "#ADJCALLSTACKUP",
50                            [(X86callseq_end timm:$amt1, timm:$amt2)]>,
51                            Requires<[NotLP64]>;
53 def : Pat<(X86callseq_start timm:$amt1, timm:$amt2),
54        (ADJCALLSTACKDOWN32 i32imm:$amt1, i32imm:$amt2, 0)>, Requires<[NotLP64]>;
57 // ADJCALLSTACKDOWN/UP implicitly use/def RSP because they may be expanded into
58 // a stack adjustment and the codegen must know that they may modify the stack
59 // pointer before prolog-epilog rewriting occurs.
60 // Pessimistically assume ADJCALLSTACKDOWN / ADJCALLSTACKUP will become
61 // sub / add which can clobber EFLAGS.
62 let Defs = [RSP, EFLAGS, SSP], Uses = [RSP, SSP], SchedRW = [WriteALU] in {
63 def ADJCALLSTACKDOWN64 : I<0, Pseudo, (outs),
64                            (ins i32imm:$amt1, i32imm:$amt2, i32imm:$amt3),
65                            "#ADJCALLSTACKDOWN", []>, Requires<[IsLP64]>;
66 def ADJCALLSTACKUP64   : I<0, Pseudo, (outs), (ins i32imm:$amt1, i32imm:$amt2),
67                            "#ADJCALLSTACKUP",
68                            [(X86callseq_end timm:$amt1, timm:$amt2)]>,
69                            Requires<[IsLP64]>;
71 def : Pat<(X86callseq_start timm:$amt1, timm:$amt2),
72         (ADJCALLSTACKDOWN64 i32imm:$amt1, i32imm:$amt2, 0)>, Requires<[IsLP64]>;
74 let SchedRW = [WriteSystem] in {
76 // x86-64 va_start lowering magic.
77 let usesCustomInserter = 1, Defs = [EFLAGS] in {
78 def VASTART_SAVE_XMM_REGS : I<0, Pseudo,
79                               (outs),
80                               (ins GR8:$al,
81                                    i64imm:$regsavefi, i64imm:$offset,
82                                    variable_ops),
83                               "#VASTART_SAVE_XMM_REGS $al, $regsavefi, $offset",
84                               [(X86vastart_save_xmm_regs GR8:$al,
85                                                          imm:$regsavefi,
86                                                          imm:$offset),
87                                (implicit EFLAGS)]>;
89 // The VAARG_64 pseudo-instruction takes the address of the va_list,
90 // and places the address of the next argument into a register.
91 let Defs = [EFLAGS] in
92 def VAARG_64 : I<0, Pseudo,
93                  (outs GR64:$dst),
94                  (ins i8mem:$ap, i32imm:$size, i8imm:$mode, i32imm:$align),
95                  "#VAARG_64 $dst, $ap, $size, $mode, $align",
96                  [(set GR64:$dst,
97                     (X86vaarg64 addr:$ap, imm:$size, imm:$mode, imm:$align)),
98                   (implicit EFLAGS)]>;
101 // When using segmented stacks these are lowered into instructions which first
102 // check if the current stacklet has enough free memory. If it does, memory is
103 // allocated by bumping the stack pointer. Otherwise memory is allocated from
104 // the heap.
106 let Defs = [EAX, ESP, EFLAGS], Uses = [ESP] in
107 def SEG_ALLOCA_32 : I<0, Pseudo, (outs GR32:$dst), (ins GR32:$size),
108                       "# variable sized alloca for segmented stacks",
109                       [(set GR32:$dst,
110                          (X86SegAlloca GR32:$size))]>,
111                     Requires<[NotLP64]>;
113 let Defs = [RAX, RSP, EFLAGS], Uses = [RSP] in
114 def SEG_ALLOCA_64 : I<0, Pseudo, (outs GR64:$dst), (ins GR64:$size),
115                       "# variable sized alloca for segmented stacks",
116                       [(set GR64:$dst,
117                          (X86SegAlloca GR64:$size))]>,
118                     Requires<[In64BitMode]>;
121 // Dynamic stack allocation yields a _chkstk or _alloca call for all Windows
122 // targets.  These calls are needed to probe the stack when allocating more than
123 // 4k bytes in one go. Touching the stack at 4K increments is necessary to
124 // ensure that the guard pages used by the OS virtual memory manager are
125 // allocated in correct sequence.
126 // The main point of having separate instruction are extra unmodelled effects
127 // (compared to ordinary calls) like stack pointer change.
129 let Defs = [EAX, ESP, EFLAGS], Uses = [ESP] in
130 def WIN_ALLOCA_32 : I<0, Pseudo, (outs), (ins GR32:$size),
131                      "# dynamic stack allocation",
132                      [(X86WinAlloca GR32:$size)]>,
133                      Requires<[NotLP64]>;
135 let Defs = [RAX, RSP, EFLAGS], Uses = [RSP] in
136 def WIN_ALLOCA_64 : I<0, Pseudo, (outs), (ins GR64:$size),
137                      "# dynamic stack allocation",
138                      [(X86WinAlloca GR64:$size)]>,
139                      Requires<[In64BitMode]>;
140 } // SchedRW
142 // These instructions XOR the frame pointer into a GPR. They are used in some
143 // stack protection schemes. These are post-RA pseudos because we only know the
144 // frame register after register allocation.
145 let Constraints = "$src = $dst", isMoveImm = 1, isPseudo = 1, Defs = [EFLAGS] in {
146   def XOR32_FP : I<0, Pseudo, (outs GR32:$dst), (ins GR32:$src),
147                   "xorl\t$$FP, $src", []>,
148                   Requires<[NotLP64]>, Sched<[WriteALU]>;
149   def XOR64_FP : I<0, Pseudo, (outs GR64:$dst), (ins GR64:$src),
150                   "xorq\t$$FP $src", []>,
151                   Requires<[In64BitMode]>, Sched<[WriteALU]>;
154 //===----------------------------------------------------------------------===//
155 // EH Pseudo Instructions
157 let SchedRW = [WriteSystem] in {
158 let isTerminator = 1, isReturn = 1, isBarrier = 1,
159     hasCtrlDep = 1, isCodeGenOnly = 1 in {
160 def EH_RETURN   : I<0xC3, RawFrm, (outs), (ins GR32:$addr),
161                     "ret\t#eh_return, addr: $addr",
162                     [(X86ehret GR32:$addr)]>, Sched<[WriteJumpLd]>;
166 let isTerminator = 1, isReturn = 1, isBarrier = 1,
167     hasCtrlDep = 1, isCodeGenOnly = 1 in {
168 def EH_RETURN64   : I<0xC3, RawFrm, (outs), (ins GR64:$addr),
169                      "ret\t#eh_return, addr: $addr",
170                      [(X86ehret GR64:$addr)]>, Sched<[WriteJumpLd]>;
174 let isTerminator = 1, hasSideEffects = 1, isBarrier = 1, hasCtrlDep = 1,
175     isCodeGenOnly = 1, isReturn = 1, isEHScopeReturn = 1 in {
176   def CLEANUPRET : I<0, Pseudo, (outs), (ins), "# CLEANUPRET", [(cleanupret)]>;
178   // CATCHRET needs a custom inserter for SEH.
179   let usesCustomInserter = 1 in
180     def CATCHRET : I<0, Pseudo, (outs), (ins brtarget32:$dst, brtarget32:$from),
181                      "# CATCHRET",
182                      [(catchret bb:$dst, bb:$from)]>;
185 let hasSideEffects = 1, hasCtrlDep = 1, isCodeGenOnly = 1,
186     usesCustomInserter = 1 in
187 def CATCHPAD : I<0, Pseudo, (outs), (ins), "# CATCHPAD", [(catchpad)]>;
189 // This instruction is responsible for re-establishing stack pointers after an
190 // exception has been caught and we are rejoining normal control flow in the
191 // parent function or funclet. It generally sets ESP and EBP, and optionally
192 // ESI. It is only needed for 32-bit WinEH, as the runtime restores CSRs for us
193 // elsewhere.
194 let hasSideEffects = 1, hasCtrlDep = 1, isCodeGenOnly = 1 in
195 def EH_RESTORE : I<0, Pseudo, (outs), (ins), "# EH_RESTORE", []>;
197 let hasSideEffects = 1, isBarrier = 1, isCodeGenOnly = 1,
198     usesCustomInserter = 1 in {
199   def EH_SjLj_SetJmp32  : I<0, Pseudo, (outs GR32:$dst), (ins i32mem:$buf),
200                             "#EH_SJLJ_SETJMP32",
201                             [(set GR32:$dst, (X86eh_sjlj_setjmp addr:$buf))]>,
202                           Requires<[Not64BitMode]>;
203   def EH_SjLj_SetJmp64  : I<0, Pseudo, (outs GR32:$dst), (ins i64mem:$buf),
204                             "#EH_SJLJ_SETJMP64",
205                             [(set GR32:$dst, (X86eh_sjlj_setjmp addr:$buf))]>,
206                           Requires<[In64BitMode]>;
207   let isTerminator = 1 in {
208   def EH_SjLj_LongJmp32 : I<0, Pseudo, (outs), (ins i32mem:$buf),
209                             "#EH_SJLJ_LONGJMP32",
210                             [(X86eh_sjlj_longjmp addr:$buf)]>,
211                           Requires<[Not64BitMode]>;
212   def EH_SjLj_LongJmp64 : I<0, Pseudo, (outs), (ins i64mem:$buf),
213                             "#EH_SJLJ_LONGJMP64",
214                             [(X86eh_sjlj_longjmp addr:$buf)]>,
215                           Requires<[In64BitMode]>;
216   }
219 let isBranch = 1, isTerminator = 1, isCodeGenOnly = 1 in {
220   def EH_SjLj_Setup : I<0, Pseudo, (outs), (ins brtarget:$dst),
221                         "#EH_SjLj_Setup\t$dst", []>;
223 } // SchedRW
225 //===----------------------------------------------------------------------===//
226 // Pseudo instructions used by unwind info.
228 let isPseudo = 1, SchedRW = [WriteSystem] in {
229   def SEH_PushReg : I<0, Pseudo, (outs), (ins i32imm:$reg),
230                             "#SEH_PushReg $reg", []>;
231   def SEH_SaveReg : I<0, Pseudo, (outs), (ins i32imm:$reg, i32imm:$dst),
232                             "#SEH_SaveReg $reg, $dst", []>;
233   def SEH_SaveXMM : I<0, Pseudo, (outs), (ins i32imm:$reg, i32imm:$dst),
234                             "#SEH_SaveXMM $reg, $dst", []>;
235   def SEH_StackAlloc : I<0, Pseudo, (outs), (ins i32imm:$size),
236                             "#SEH_StackAlloc $size", []>;
237   def SEH_StackAlign : I<0, Pseudo, (outs), (ins i32imm:$align),
238                             "#SEH_StackAlign $align", []>;
239   def SEH_SetFrame : I<0, Pseudo, (outs), (ins i32imm:$reg, i32imm:$offset),
240                             "#SEH_SetFrame $reg, $offset", []>;
241   def SEH_PushFrame : I<0, Pseudo, (outs), (ins i1imm:$mode),
242                             "#SEH_PushFrame $mode", []>;
243   def SEH_EndPrologue : I<0, Pseudo, (outs), (ins),
244                             "#SEH_EndPrologue", []>;
245   def SEH_Epilogue : I<0, Pseudo, (outs), (ins),
246                             "#SEH_Epilogue", []>;
249 //===----------------------------------------------------------------------===//
250 // Pseudo instructions used by segmented stacks.
253 // This is lowered into a RET instruction by MCInstLower.  We need
254 // this so that we don't have to have a MachineBasicBlock which ends
255 // with a RET and also has successors.
256 let isPseudo = 1, SchedRW = [WriteJumpLd] in {
257 def MORESTACK_RET: I<0, Pseudo, (outs), (ins), "", []>;
259 // This instruction is lowered to a RET followed by a MOV.  The two
260 // instructions are not generated on a higher level since then the
261 // verifier sees a MachineBasicBlock ending with a non-terminator.
262 def MORESTACK_RET_RESTORE_R10 : I<0, Pseudo, (outs), (ins), "", []>;
265 //===----------------------------------------------------------------------===//
266 // Alias Instructions
267 //===----------------------------------------------------------------------===//
269 // Alias instruction mapping movr0 to xor.
270 // FIXME: remove when we can teach regalloc that xor reg, reg is ok.
271 let Defs = [EFLAGS], isReMaterializable = 1, isAsCheapAsAMove = 1,
272     isPseudo = 1, isMoveImm = 1, AddedComplexity = 10 in
273 def MOV32r0  : I<0, Pseudo, (outs GR32:$dst), (ins), "",
274                  [(set GR32:$dst, 0)]>, Sched<[WriteZero]>;
276 // Other widths can also make use of the 32-bit xor, which may have a smaller
277 // encoding and avoid partial register updates.
278 let AddedComplexity = 10 in {
279 def : Pat<(i8 0), (EXTRACT_SUBREG (MOV32r0), sub_8bit)>;
280 def : Pat<(i16 0), (EXTRACT_SUBREG (MOV32r0), sub_16bit)>;
281 def : Pat<(i64 0), (SUBREG_TO_REG (i64 0), (MOV32r0), sub_32bit)>;
284 let Predicates = [OptForSize, Not64BitMode],
285     AddedComplexity = 10 in {
286   let SchedRW = [WriteALU] in {
287   // Pseudo instructions for materializing 1 and -1 using XOR+INC/DEC,
288   // which only require 3 bytes compared to MOV32ri which requires 5.
289   let Defs = [EFLAGS], isReMaterializable = 1, isPseudo = 1 in {
290     def MOV32r1 : I<0, Pseudo, (outs GR32:$dst), (ins), "",
291                         [(set GR32:$dst, 1)]>;
292     def MOV32r_1 : I<0, Pseudo, (outs GR32:$dst), (ins), "",
293                         [(set GR32:$dst, -1)]>;
294   }
295   } // SchedRW
297   // MOV16ri is 4 bytes, so the instructions above are smaller.
298   def : Pat<(i16 1), (EXTRACT_SUBREG (MOV32r1), sub_16bit)>;
299   def : Pat<(i16 -1), (EXTRACT_SUBREG (MOV32r_1), sub_16bit)>;
302 let isReMaterializable = 1, isPseudo = 1, AddedComplexity = 5,
303     SchedRW = [WriteALU] in {
304 // AddedComplexity higher than MOV64ri but lower than MOV32r0 and MOV32r1.
305 def MOV32ImmSExti8 : I<0, Pseudo, (outs GR32:$dst), (ins i32i8imm:$src), "",
306                        [(set GR32:$dst, i32immSExt8:$src)]>,
307                        Requires<[OptForMinSize, NotWin64WithoutFP]>;
308 def MOV64ImmSExti8 : I<0, Pseudo, (outs GR64:$dst), (ins i64i8imm:$src), "",
309                        [(set GR64:$dst, i64immSExt8:$src)]>,
310                        Requires<[OptForMinSize, NotWin64WithoutFP]>;
313 // Materialize i64 constant where top 32-bits are zero. This could theoretically
314 // use MOV32ri with a SUBREG_TO_REG to represent the zero-extension, however
315 // that would make it more difficult to rematerialize.
316 let isReMaterializable = 1, isAsCheapAsAMove = 1,
317     isPseudo = 1, hasSideEffects = 0, SchedRW = [WriteMove] in
318 def MOV32ri64 : I<0, Pseudo, (outs GR64:$dst), (ins i64i32imm:$src), "", []>;
320 // This 64-bit pseudo-move can be used for both a 64-bit constant that is
321 // actually the zero-extension of a 32-bit constant and for labels in the
322 // x86-64 small code model.
323 def mov64imm32 : ComplexPattern<i64, 1, "selectMOV64Imm32", [imm, X86Wrapper]>;
325 def : Pat<(i64 mov64imm32:$src), (MOV32ri64 mov64imm32:$src)>;
327 // Use sbb to materialize carry bit.
328 let Uses = [EFLAGS], Defs = [EFLAGS], isPseudo = 1, SchedRW = [WriteALU] in {
329 // FIXME: These are pseudo ops that should be replaced with Pat<> patterns.
330 // However, Pat<> can't replicate the destination reg into the inputs of the
331 // result.
332 def SETB_C8r : I<0, Pseudo, (outs GR8:$dst), (ins), "",
333                  [(set GR8:$dst, (X86setcc_c X86_COND_B, EFLAGS))]>;
334 def SETB_C16r : I<0, Pseudo, (outs GR16:$dst), (ins), "",
335                  [(set GR16:$dst, (X86setcc_c X86_COND_B, EFLAGS))]>;
336 def SETB_C32r : I<0, Pseudo, (outs GR32:$dst), (ins), "",
337                  [(set GR32:$dst, (X86setcc_c X86_COND_B, EFLAGS))]>;
338 def SETB_C64r : I<0, Pseudo, (outs GR64:$dst), (ins), "",
339                  [(set GR64:$dst, (X86setcc_c X86_COND_B, EFLAGS))]>;
340 } // isCodeGenOnly
343 def : Pat<(i16 (anyext (i8 (X86setcc_c X86_COND_B, EFLAGS)))),
344           (SETB_C16r)>;
345 def : Pat<(i32 (anyext (i8 (X86setcc_c X86_COND_B, EFLAGS)))),
346           (SETB_C32r)>;
347 def : Pat<(i64 (anyext (i8 (X86setcc_c X86_COND_B, EFLAGS)))),
348           (SETB_C64r)>;
350 def : Pat<(i16 (sext (i8 (X86setcc_c X86_COND_B, EFLAGS)))),
351           (SETB_C16r)>;
352 def : Pat<(i32 (sext (i8 (X86setcc_c X86_COND_B, EFLAGS)))),
353           (SETB_C32r)>;
354 def : Pat<(i64 (sext (i8 (X86setcc_c X86_COND_B, EFLAGS)))),
355           (SETB_C64r)>;
357 // We canonicalize 'setb' to "(and (sbb reg,reg), 1)" on the hope that the and
358 // will be eliminated and that the sbb can be extended up to a wider type.  When
359 // this happens, it is great.  However, if we are left with an 8-bit sbb and an
360 // and, we might as well just match it as a setb.
361 def : Pat<(and (i8 (X86setcc_c X86_COND_B, EFLAGS)), 1),
362           (SETBr)>;
364 // Patterns to give priority when both inputs are zero so that we don't use
365 // an immediate for the RHS.
366 // TODO: Should we use a 32-bit sbb for 8/16 to push the extract_subreg out?
367 def : Pat<(X86sbb_flag (i8 0), (i8 0), EFLAGS),
368           (SBB8rr (EXTRACT_SUBREG (MOV32r0), sub_8bit),
369                   (EXTRACT_SUBREG (MOV32r0), sub_8bit))>;
370 def : Pat<(X86sbb_flag (i16 0), (i16 0), EFLAGS),
371           (SBB16rr (EXTRACT_SUBREG (MOV32r0), sub_16bit),
372                    (EXTRACT_SUBREG (MOV32r0), sub_16bit))>;
373 def : Pat<(X86sbb_flag (i32 0), (i32 0), EFLAGS),
374           (SBB32rr (MOV32r0), (MOV32r0))>;
375 def : Pat<(X86sbb_flag (i64 0), (i64 0), EFLAGS),
376           (SBB64rr (SUBREG_TO_REG (i64 0), (MOV32r0), sub_32bit),
377                    (SUBREG_TO_REG (i64 0), (MOV32r0), sub_32bit))>;
379 //===----------------------------------------------------------------------===//
380 // String Pseudo Instructions
382 let SchedRW = [WriteMicrocoded] in {
383 let Defs = [ECX,EDI,ESI], Uses = [ECX,EDI,ESI], isCodeGenOnly = 1 in {
384 def REP_MOVSB_32 : I<0xA4, RawFrm, (outs), (ins),
385                     "{rep;movsb (%esi), %es:(%edi)|rep movsb es:[edi], [esi]}",
386                     [(X86rep_movs i8)]>, REP, AdSize32,
387                    Requires<[NotLP64]>;
388 def REP_MOVSW_32 : I<0xA5, RawFrm, (outs), (ins),
389                     "{rep;movsw (%esi), %es:(%edi)|rep movsw es:[edi], [esi]}",
390                     [(X86rep_movs i16)]>, REP, AdSize32, OpSize16,
391                    Requires<[NotLP64]>;
392 def REP_MOVSD_32 : I<0xA5, RawFrm, (outs), (ins),
393                     "{rep;movsl (%esi), %es:(%edi)|rep movsd es:[edi], [esi]}",
394                     [(X86rep_movs i32)]>, REP, AdSize32, OpSize32,
395                    Requires<[NotLP64]>;
396 def REP_MOVSQ_32 : RI<0xA5, RawFrm, (outs), (ins),
397                     "{rep;movsq (%esi), %es:(%edi)|rep movsq es:[edi], [esi]}",
398                     [(X86rep_movs i64)]>, REP, AdSize32,
399                    Requires<[NotLP64, In64BitMode]>;
402 let Defs = [RCX,RDI,RSI], Uses = [RCX,RDI,RSI], isCodeGenOnly = 1 in {
403 def REP_MOVSB_64 : I<0xA4, RawFrm, (outs), (ins),
404                     "{rep;movsb (%rsi), %es:(%rdi)|rep movsb es:[rdi], [rsi]}",
405                     [(X86rep_movs i8)]>, REP, AdSize64,
406                    Requires<[IsLP64]>;
407 def REP_MOVSW_64 : I<0xA5, RawFrm, (outs), (ins),
408                     "{rep;movsw (%rsi), %es:(%rdi)|rep movsw es:[rdi], [rsi]}",
409                     [(X86rep_movs i16)]>, REP, AdSize64, OpSize16,
410                    Requires<[IsLP64]>;
411 def REP_MOVSD_64 : I<0xA5, RawFrm, (outs), (ins),
412                     "{rep;movsl (%rsi), %es:(%rdi)|rep movsdi es:[rdi], [rsi]}",
413                     [(X86rep_movs i32)]>, REP, AdSize64, OpSize32,
414                    Requires<[IsLP64]>;
415 def REP_MOVSQ_64 : RI<0xA5, RawFrm, (outs), (ins),
416                     "{rep;movsq (%rsi), %es:(%rdi)|rep movsq es:[rdi], [rsi]}",
417                     [(X86rep_movs i64)]>, REP, AdSize64,
418                    Requires<[IsLP64]>;
421 // FIXME: Should use "(X86rep_stos AL)" as the pattern.
422 let Defs = [ECX,EDI], isCodeGenOnly = 1 in {
423   let Uses = [AL,ECX,EDI] in
424   def REP_STOSB_32 : I<0xAA, RawFrm, (outs), (ins),
425                        "{rep;stosb %al, %es:(%edi)|rep stosb es:[edi], al}",
426                       [(X86rep_stos i8)]>, REP, AdSize32,
427                      Requires<[NotLP64]>;
428   let Uses = [AX,ECX,EDI] in
429   def REP_STOSW_32 : I<0xAB, RawFrm, (outs), (ins),
430                       "{rep;stosw %ax, %es:(%edi)|rep stosw es:[edi], ax}",
431                       [(X86rep_stos i16)]>, REP, AdSize32, OpSize16,
432                      Requires<[NotLP64]>;
433   let Uses = [EAX,ECX,EDI] in
434   def REP_STOSD_32 : I<0xAB, RawFrm, (outs), (ins),
435                       "{rep;stosl %eax, %es:(%edi)|rep stosd es:[edi], eax}",
436                       [(X86rep_stos i32)]>, REP, AdSize32, OpSize32,
437                      Requires<[NotLP64]>;
438   let Uses = [RAX,RCX,RDI] in
439   def REP_STOSQ_32 : RI<0xAB, RawFrm, (outs), (ins),
440                         "{rep;stosq %rax, %es:(%edi)|rep stosq es:[edi], rax}",
441                         [(X86rep_stos i64)]>, REP, AdSize32,
442                         Requires<[NotLP64, In64BitMode]>;
445 let Defs = [RCX,RDI], isCodeGenOnly = 1 in {
446   let Uses = [AL,RCX,RDI] in
447   def REP_STOSB_64 : I<0xAA, RawFrm, (outs), (ins),
448                        "{rep;stosb %al, %es:(%rdi)|rep stosb es:[rdi], al}",
449                        [(X86rep_stos i8)]>, REP, AdSize64,
450                        Requires<[IsLP64]>;
451   let Uses = [AX,RCX,RDI] in
452   def REP_STOSW_64 : I<0xAB, RawFrm, (outs), (ins),
453                        "{rep;stosw %ax, %es:(%rdi)|rep stosw es:[rdi], ax}",
454                        [(X86rep_stos i16)]>, REP, AdSize64, OpSize16,
455                        Requires<[IsLP64]>;
456   let Uses = [RAX,RCX,RDI] in
457   def REP_STOSD_64 : I<0xAB, RawFrm, (outs), (ins),
458                       "{rep;stosl %eax, %es:(%rdi)|rep stosd es:[rdi], eax}",
459                        [(X86rep_stos i32)]>, REP, AdSize64, OpSize32,
460                        Requires<[IsLP64]>;
462   let Uses = [RAX,RCX,RDI] in
463   def REP_STOSQ_64 : RI<0xAB, RawFrm, (outs), (ins),
464                         "{rep;stosq %rax, %es:(%rdi)|rep stosq es:[rdi], rax}",
465                         [(X86rep_stos i64)]>, REP, AdSize64,
466                         Requires<[IsLP64]>;
468 } // SchedRW
470 //===----------------------------------------------------------------------===//
471 // Thread Local Storage Instructions
473 let SchedRW = [WriteSystem] in {
475 // ELF TLS Support
476 // All calls clobber the non-callee saved registers. ESP is marked as
477 // a use to prevent stack-pointer assignments that appear immediately
478 // before calls from potentially appearing dead.
479 let Defs = [EAX, ECX, EDX, FP0, FP1, FP2, FP3, FP4, FP5, FP6, FP7,
480             ST0, ST1, ST2, ST3, ST4, ST5, ST6, ST7,
481             MM0, MM1, MM2, MM3, MM4, MM5, MM6, MM7,
482             XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7,
483             XMM8, XMM9, XMM10, XMM11, XMM12, XMM13, XMM14, XMM15, EFLAGS, DF],
484     usesCustomInserter = 1, Uses = [ESP, SSP] in {
485 def TLS_addr32 : I<0, Pseudo, (outs), (ins i32mem:$sym),
486                   "# TLS_addr32",
487                   [(X86tlsaddr tls32addr:$sym)]>,
488                   Requires<[Not64BitMode]>;
489 def TLS_base_addr32 : I<0, Pseudo, (outs), (ins i32mem:$sym),
490                   "# TLS_base_addr32",
491                   [(X86tlsbaseaddr tls32baseaddr:$sym)]>,
492                   Requires<[Not64BitMode]>;
495 // All calls clobber the non-callee saved registers. RSP is marked as
496 // a use to prevent stack-pointer assignments that appear immediately
497 // before calls from potentially appearing dead.
498 let Defs = [RAX, RCX, RDX, RSI, RDI, R8, R9, R10, R11,
499             FP0, FP1, FP2, FP3, FP4, FP5, FP6, FP7,
500             ST0, ST1, ST2, ST3, ST4, ST5, ST6, ST7,
501             MM0, MM1, MM2, MM3, MM4, MM5, MM6, MM7,
502             XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7,
503             XMM8, XMM9, XMM10, XMM11, XMM12, XMM13, XMM14, XMM15, EFLAGS, DF],
504     usesCustomInserter = 1, Uses = [RSP, SSP] in {
505 def TLS_addr64 : I<0, Pseudo, (outs), (ins i64mem:$sym),
506                    "# TLS_addr64",
507                   [(X86tlsaddr tls64addr:$sym)]>,
508                   Requires<[In64BitMode]>;
509 def TLS_base_addr64 : I<0, Pseudo, (outs), (ins i64mem:$sym),
510                    "# TLS_base_addr64",
511                   [(X86tlsbaseaddr tls64baseaddr:$sym)]>,
512                   Requires<[In64BitMode]>;
515 // Darwin TLS Support
516 // For i386, the address of the thunk is passed on the stack, on return the
517 // address of the variable is in %eax.  %ecx is trashed during the function
518 // call.  All other registers are preserved.
519 let Defs = [EAX, ECX, EFLAGS, DF],
520     Uses = [ESP, SSP],
521     usesCustomInserter = 1 in
522 def TLSCall_32 : I<0, Pseudo, (outs), (ins i32mem:$sym),
523                 "# TLSCall_32",
524                 [(X86TLSCall addr:$sym)]>,
525                 Requires<[Not64BitMode]>;
527 // For x86_64, the address of the thunk is passed in %rdi, but the
528 // pseudo directly use the symbol, so do not add an implicit use of
529 // %rdi. The lowering will do the right thing with RDI.
530 // On return the address of the variable is in %rax.  All other
531 // registers are preserved.
532 let Defs = [RAX, EFLAGS, DF],
533     Uses = [RSP, SSP],
534     usesCustomInserter = 1 in
535 def TLSCall_64 : I<0, Pseudo, (outs), (ins i64mem:$sym),
536                   "# TLSCall_64",
537                   [(X86TLSCall addr:$sym)]>,
538                   Requires<[In64BitMode]>;
539 } // SchedRW
541 //===----------------------------------------------------------------------===//
542 // Conditional Move Pseudo Instructions
544 // CMOV* - Used to implement the SELECT DAG operation.  Expanded after
545 // instruction selection into a branch sequence.
546 multiclass CMOVrr_PSEUDO<RegisterClass RC, ValueType VT> {
547   def CMOV#NAME  : I<0, Pseudo,
548                     (outs RC:$dst), (ins RC:$t, RC:$f, i8imm:$cond),
549                     "#CMOV_"#NAME#" PSEUDO!",
550                     [(set RC:$dst, (VT (X86cmov RC:$t, RC:$f, imm:$cond,
551                                                 EFLAGS)))]>;
554 let usesCustomInserter = 1, hasNoSchedulingInfo = 1, Uses = [EFLAGS] in {
555   // X86 doesn't have 8-bit conditional moves. Use a customInserter to
556   // emit control flow. An alternative to this is to mark i8 SELECT as Promote,
557   // however that requires promoting the operands, and can induce additional
558   // i8 register pressure.
559   defm _GR8 : CMOVrr_PSEUDO<GR8, i8>;
561   let Predicates = [NoCMov] in {
562     defm _GR32 : CMOVrr_PSEUDO<GR32, i32>;
563     defm _GR16 : CMOVrr_PSEUDO<GR16, i16>;
564   } // Predicates = [NoCMov]
566   // fcmov doesn't handle all possible EFLAGS, provide a fallback if there is no
567   // SSE1/SSE2.
568   let Predicates = [FPStackf32] in
569     defm _RFP32 : CMOVrr_PSEUDO<RFP32, f32>;
571   let Predicates = [FPStackf64] in
572     defm _RFP64 : CMOVrr_PSEUDO<RFP64, f64>;
574   defm _RFP80 : CMOVrr_PSEUDO<RFP80, f80>;
576   defm _FR32   : CMOVrr_PSEUDO<FR32, f32>;
577   defm _FR64   : CMOVrr_PSEUDO<FR64, f64>;
578   let Predicates = [NoVLX] in {
579     defm _VR128  : CMOVrr_PSEUDO<VR128, v2i64>;
580     defm _VR256  : CMOVrr_PSEUDO<VR256, v4i64>;
581   }
582   let Predicates = [HasVLX] in {
583     defm _VR128X : CMOVrr_PSEUDO<VR128X, v2i64>;
584     defm _VR256X : CMOVrr_PSEUDO<VR256X, v4i64>;
585   }
586   defm _VR512  : CMOVrr_PSEUDO<VR512, v8i64>;
587   defm _VK2    : CMOVrr_PSEUDO<VK2,  v2i1>;
588   defm _VK4    : CMOVrr_PSEUDO<VK4,  v4i1>;
589   defm _VK8    : CMOVrr_PSEUDO<VK8,  v8i1>;
590   defm _VK16   : CMOVrr_PSEUDO<VK16, v16i1>;
591   defm _VK32   : CMOVrr_PSEUDO<VK32, v32i1>;
592   defm _VK64   : CMOVrr_PSEUDO<VK64, v64i1>;
593 } // usesCustomInserter = 1, hasNoSchedulingInfo = 1, Uses = [EFLAGS]
595 def : Pat<(f128 (X86cmov VR128:$t, VR128:$f, imm:$cond, EFLAGS)),
596           (CMOV_VR128 VR128:$t, VR128:$f, imm:$cond)>;
598 let Predicates = [NoVLX] in {
599   def : Pat<(v16i8 (X86cmov VR128:$t, VR128:$f, imm:$cond, EFLAGS)),
600             (CMOV_VR128 VR128:$t, VR128:$f, imm:$cond)>;
601   def : Pat<(v8i16 (X86cmov VR128:$t, VR128:$f, imm:$cond, EFLAGS)),
602             (CMOV_VR128 VR128:$t, VR128:$f, imm:$cond)>;
603   def : Pat<(v4i32 (X86cmov VR128:$t, VR128:$f, imm:$cond, EFLAGS)),
604             (CMOV_VR128 VR128:$t, VR128:$f, imm:$cond)>;
605   def : Pat<(v4f32 (X86cmov VR128:$t, VR128:$f, imm:$cond, EFLAGS)),
606             (CMOV_VR128 VR128:$t, VR128:$f, imm:$cond)>;
607   def : Pat<(v2f64 (X86cmov VR128:$t, VR128:$f, imm:$cond, EFLAGS)),
608             (CMOV_VR128 VR128:$t, VR128:$f, imm:$cond)>;
610   def : Pat<(v32i8 (X86cmov VR256:$t, VR256:$f, imm:$cond, EFLAGS)),
611             (CMOV_VR256 VR256:$t, VR256:$f, imm:$cond)>;
612   def : Pat<(v16i16 (X86cmov VR256:$t, VR256:$f, imm:$cond, EFLAGS)),
613             (CMOV_VR256 VR256:$t, VR256:$f, imm:$cond)>;
614   def : Pat<(v8i32 (X86cmov VR256:$t, VR256:$f, imm:$cond, EFLAGS)),
615             (CMOV_VR256 VR256:$t, VR256:$f, imm:$cond)>;
616   def : Pat<(v8f32 (X86cmov VR256:$t, VR256:$f, imm:$cond, EFLAGS)),
617             (CMOV_VR256 VR256:$t, VR256:$f, imm:$cond)>;
618   def : Pat<(v4f64 (X86cmov VR256:$t, VR256:$f, imm:$cond, EFLAGS)),
619             (CMOV_VR256 VR256:$t, VR256:$f, imm:$cond)>;
621 let Predicates = [HasVLX] in {
622   def : Pat<(v16i8 (X86cmov VR128X:$t, VR128X:$f, imm:$cond, EFLAGS)),
623             (CMOV_VR128X VR128X:$t, VR128X:$f, imm:$cond)>;
624   def : Pat<(v8i16 (X86cmov VR128X:$t, VR128X:$f, imm:$cond, EFLAGS)),
625             (CMOV_VR128X VR128X:$t, VR128X:$f, imm:$cond)>;
626   def : Pat<(v4i32 (X86cmov VR128X:$t, VR128X:$f, imm:$cond, EFLAGS)),
627             (CMOV_VR128X VR128X:$t, VR128X:$f, imm:$cond)>;
628   def : Pat<(v4f32 (X86cmov VR128X:$t, VR128X:$f, imm:$cond, EFLAGS)),
629             (CMOV_VR128X VR128X:$t, VR128X:$f, imm:$cond)>;
630   def : Pat<(v2f64 (X86cmov VR128X:$t, VR128X:$f, imm:$cond, EFLAGS)),
631             (CMOV_VR128X VR128X:$t, VR128X:$f, imm:$cond)>;
633   def : Pat<(v32i8 (X86cmov VR256X:$t, VR256X:$f, imm:$cond, EFLAGS)),
634             (CMOV_VR256X VR256X:$t, VR256X:$f, imm:$cond)>;
635   def : Pat<(v16i16 (X86cmov VR256X:$t, VR256X:$f, imm:$cond, EFLAGS)),
636             (CMOV_VR256X VR256X:$t, VR256X:$f, imm:$cond)>;
637   def : Pat<(v8i32 (X86cmov VR256X:$t, VR256X:$f, imm:$cond, EFLAGS)),
638             (CMOV_VR256X VR256X:$t, VR256X:$f, imm:$cond)>;
639   def : Pat<(v8f32 (X86cmov VR256X:$t, VR256X:$f, imm:$cond, EFLAGS)),
640             (CMOV_VR256X VR256X:$t, VR256X:$f, imm:$cond)>;
641   def : Pat<(v4f64 (X86cmov VR256X:$t, VR256X:$f, imm:$cond, EFLAGS)),
642             (CMOV_VR256X VR256X:$t, VR256X:$f, imm:$cond)>;
645 def : Pat<(v64i8 (X86cmov VR512:$t, VR512:$f, imm:$cond, EFLAGS)),
646           (CMOV_VR512 VR512:$t, VR512:$f, imm:$cond)>;
647 def : Pat<(v32i16 (X86cmov VR512:$t, VR512:$f, imm:$cond, EFLAGS)),
648           (CMOV_VR512 VR512:$t, VR512:$f, imm:$cond)>;
649 def : Pat<(v16i32 (X86cmov VR512:$t, VR512:$f, imm:$cond, EFLAGS)),
650           (CMOV_VR512 VR512:$t, VR512:$f, imm:$cond)>;
651 def : Pat<(v16f32 (X86cmov VR512:$t, VR512:$f, imm:$cond, EFLAGS)),
652           (CMOV_VR512 VR512:$t, VR512:$f, imm:$cond)>;
653 def : Pat<(v8f64 (X86cmov VR512:$t, VR512:$f, imm:$cond, EFLAGS)),
654           (CMOV_VR512 VR512:$t, VR512:$f, imm:$cond)>;
656 //===----------------------------------------------------------------------===//
657 // Normal-Instructions-With-Lock-Prefix Pseudo Instructions
658 //===----------------------------------------------------------------------===//
660 // FIXME: Use normal instructions and add lock prefix dynamically.
662 // Memory barriers
664 let isCodeGenOnly = 1, Defs = [EFLAGS] in
665 def OR32mi8Locked  : Ii8<0x83, MRM1m, (outs), (ins i32mem:$dst, i32i8imm:$zero),
666                          "or{l}\t{$zero, $dst|$dst, $zero}", []>,
667                          Requires<[Not64BitMode]>, OpSize32, LOCK,
668                          Sched<[WriteALURMW]>;
670 let hasSideEffects = 1 in
671 def Int_MemBarrier : I<0, Pseudo, (outs), (ins),
672                      "#MEMBARRIER",
673                      [(X86MemBarrier)]>, Sched<[WriteLoad]>;
675 // RegOpc corresponds to the mr version of the instruction
676 // ImmOpc corresponds to the mi version of the instruction
677 // ImmOpc8 corresponds to the mi8 version of the instruction
678 // ImmMod corresponds to the instruction format of the mi and mi8 versions
679 multiclass LOCK_ArithBinOp<bits<8> RegOpc, bits<8> ImmOpc, bits<8> ImmOpc8,
680                            Format ImmMod, SDNode Op, string mnemonic> {
681 let Defs = [EFLAGS], mayLoad = 1, mayStore = 1, isCodeGenOnly = 1,
682     SchedRW = [WriteALURMW] in {
684 def NAME#8mr : I<{RegOpc{7}, RegOpc{6}, RegOpc{5}, RegOpc{4},
685                   RegOpc{3}, RegOpc{2}, RegOpc{1}, 0 },
686                   MRMDestMem, (outs), (ins i8mem:$dst, GR8:$src2),
687                   !strconcat(mnemonic, "{b}\t",
688                              "{$src2, $dst|$dst, $src2}"),
689                   [(set EFLAGS, (Op addr:$dst, GR8:$src2))]>, LOCK;
691 def NAME#16mr : I<{RegOpc{7}, RegOpc{6}, RegOpc{5}, RegOpc{4},
692                    RegOpc{3}, RegOpc{2}, RegOpc{1}, 1 },
693                    MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src2),
694                    !strconcat(mnemonic, "{w}\t",
695                               "{$src2, $dst|$dst, $src2}"),
696                    [(set EFLAGS, (Op addr:$dst, GR16:$src2))]>,
697                    OpSize16, LOCK;
699 def NAME#32mr : I<{RegOpc{7}, RegOpc{6}, RegOpc{5}, RegOpc{4},
700                    RegOpc{3}, RegOpc{2}, RegOpc{1}, 1 },
701                    MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src2),
702                    !strconcat(mnemonic, "{l}\t",
703                               "{$src2, $dst|$dst, $src2}"),
704                    [(set EFLAGS, (Op addr:$dst, GR32:$src2))]>,
705                    OpSize32, LOCK;
707 def NAME#64mr : RI<{RegOpc{7}, RegOpc{6}, RegOpc{5}, RegOpc{4},
708                     RegOpc{3}, RegOpc{2}, RegOpc{1}, 1 },
709                     MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src2),
710                     !strconcat(mnemonic, "{q}\t",
711                                "{$src2, $dst|$dst, $src2}"),
712                     [(set EFLAGS, (Op addr:$dst, GR64:$src2))]>, LOCK;
714 def NAME#8mi : Ii8<{ImmOpc{7}, ImmOpc{6}, ImmOpc{5}, ImmOpc{4},
715                     ImmOpc{3}, ImmOpc{2}, ImmOpc{1}, 0 },
716                     ImmMod, (outs), (ins i8mem :$dst, i8imm :$src2),
717                     !strconcat(mnemonic, "{b}\t",
718                                "{$src2, $dst|$dst, $src2}"),
719                     [(set EFLAGS, (Op addr:$dst, (i8 imm:$src2)))]>, LOCK;
721 def NAME#16mi : Ii16<{ImmOpc{7}, ImmOpc{6}, ImmOpc{5}, ImmOpc{4},
722                       ImmOpc{3}, ImmOpc{2}, ImmOpc{1}, 1 },
723                       ImmMod, (outs), (ins i16mem :$dst, i16imm :$src2),
724                       !strconcat(mnemonic, "{w}\t",
725                                  "{$src2, $dst|$dst, $src2}"),
726                       [(set EFLAGS, (Op addr:$dst, (i16 imm:$src2)))]>,
727                       OpSize16, LOCK;
729 def NAME#32mi : Ii32<{ImmOpc{7}, ImmOpc{6}, ImmOpc{5}, ImmOpc{4},
730                       ImmOpc{3}, ImmOpc{2}, ImmOpc{1}, 1 },
731                       ImmMod, (outs), (ins i32mem :$dst, i32imm :$src2),
732                       !strconcat(mnemonic, "{l}\t",
733                                  "{$src2, $dst|$dst, $src2}"),
734                       [(set EFLAGS, (Op addr:$dst, (i32 imm:$src2)))]>,
735                       OpSize32, LOCK;
737 def NAME#64mi32 : RIi32S<{ImmOpc{7}, ImmOpc{6}, ImmOpc{5}, ImmOpc{4},
738                           ImmOpc{3}, ImmOpc{2}, ImmOpc{1}, 1 },
739                           ImmMod, (outs), (ins i64mem :$dst, i64i32imm :$src2),
740                           !strconcat(mnemonic, "{q}\t",
741                                      "{$src2, $dst|$dst, $src2}"),
742                           [(set EFLAGS, (Op addr:$dst, i64immSExt32:$src2))]>,
743                           LOCK;
745 def NAME#16mi8 : Ii8<{ImmOpc8{7}, ImmOpc8{6}, ImmOpc8{5}, ImmOpc8{4},
746                       ImmOpc8{3}, ImmOpc8{2}, ImmOpc8{1}, 1 },
747                       ImmMod, (outs), (ins i16mem :$dst, i16i8imm :$src2),
748                       !strconcat(mnemonic, "{w}\t",
749                                  "{$src2, $dst|$dst, $src2}"),
750                       [(set EFLAGS, (Op addr:$dst, i16immSExt8:$src2))]>,
751                       OpSize16, LOCK;
753 def NAME#32mi8 : Ii8<{ImmOpc8{7}, ImmOpc8{6}, ImmOpc8{5}, ImmOpc8{4},
754                       ImmOpc8{3}, ImmOpc8{2}, ImmOpc8{1}, 1 },
755                       ImmMod, (outs), (ins i32mem :$dst, i32i8imm :$src2),
756                       !strconcat(mnemonic, "{l}\t",
757                                  "{$src2, $dst|$dst, $src2}"),
758                       [(set EFLAGS, (Op addr:$dst, i32immSExt8:$src2))]>,
759                       OpSize32, LOCK;
761 def NAME#64mi8 : RIi8<{ImmOpc8{7}, ImmOpc8{6}, ImmOpc8{5}, ImmOpc8{4},
762                        ImmOpc8{3}, ImmOpc8{2}, ImmOpc8{1}, 1 },
763                        ImmMod, (outs), (ins i64mem :$dst, i64i8imm :$src2),
764                        !strconcat(mnemonic, "{q}\t",
765                                   "{$src2, $dst|$dst, $src2}"),
766                        [(set EFLAGS, (Op addr:$dst, i64immSExt8:$src2))]>,
767                        LOCK;
772 defm LOCK_ADD : LOCK_ArithBinOp<0x00, 0x80, 0x83, MRM0m, X86lock_add, "add">;
773 defm LOCK_SUB : LOCK_ArithBinOp<0x28, 0x80, 0x83, MRM5m, X86lock_sub, "sub">;
774 defm LOCK_OR  : LOCK_ArithBinOp<0x08, 0x80, 0x83, MRM1m, X86lock_or , "or">;
775 defm LOCK_AND : LOCK_ArithBinOp<0x20, 0x80, 0x83, MRM4m, X86lock_and, "and">;
776 defm LOCK_XOR : LOCK_ArithBinOp<0x30, 0x80, 0x83, MRM6m, X86lock_xor, "xor">;
778 def X86lock_add_nocf : PatFrag<(ops node:$lhs, node:$rhs),
779                                (X86lock_add node:$lhs, node:$rhs), [{
780   return hasNoCarryFlagUses(SDValue(N, 0));
781 }]>;
783 def X86lock_sub_nocf : PatFrag<(ops node:$lhs, node:$rhs),
784                                (X86lock_sub node:$lhs, node:$rhs), [{
785   return hasNoCarryFlagUses(SDValue(N, 0));
786 }]>;
788 let Predicates = [UseIncDec] in {
789   let Defs = [EFLAGS], mayLoad = 1, mayStore = 1, isCodeGenOnly = 1,
790       SchedRW = [WriteALURMW]  in {
791     def LOCK_INC8m  : I<0xFE, MRM0m, (outs), (ins i8mem :$dst),
792                         "inc{b}\t$dst",
793                         [(set EFLAGS, (X86lock_add_nocf addr:$dst, (i8 1)))]>,
794                         LOCK;
795     def LOCK_INC16m : I<0xFF, MRM0m, (outs), (ins i16mem:$dst),
796                         "inc{w}\t$dst",
797                         [(set EFLAGS, (X86lock_add_nocf addr:$dst, (i16 1)))]>,
798                         OpSize16, LOCK;
799     def LOCK_INC32m : I<0xFF, MRM0m, (outs), (ins i32mem:$dst),
800                         "inc{l}\t$dst",
801                         [(set EFLAGS, (X86lock_add_nocf addr:$dst, (i32 1)))]>,
802                         OpSize32, LOCK;
803     def LOCK_INC64m : RI<0xFF, MRM0m, (outs), (ins i64mem:$dst),
804                          "inc{q}\t$dst",
805                          [(set EFLAGS, (X86lock_add_nocf addr:$dst, (i64 1)))]>,
806                          LOCK;
808     def LOCK_DEC8m  : I<0xFE, MRM1m, (outs), (ins i8mem :$dst),
809                         "dec{b}\t$dst",
810                         [(set EFLAGS, (X86lock_sub_nocf addr:$dst, (i8 1)))]>,
811                         LOCK;
812     def LOCK_DEC16m : I<0xFF, MRM1m, (outs), (ins i16mem:$dst),
813                         "dec{w}\t$dst",
814                         [(set EFLAGS, (X86lock_sub_nocf addr:$dst, (i16 1)))]>,
815                         OpSize16, LOCK;
816     def LOCK_DEC32m : I<0xFF, MRM1m, (outs), (ins i32mem:$dst),
817                         "dec{l}\t$dst",
818                         [(set EFLAGS, (X86lock_sub_nocf addr:$dst, (i32 1)))]>,
819                         OpSize32, LOCK;
820     def LOCK_DEC64m : RI<0xFF, MRM1m, (outs), (ins i64mem:$dst),
821                          "dec{q}\t$dst",
822                          [(set EFLAGS, (X86lock_sub_nocf addr:$dst, (i64 1)))]>,
823                          LOCK;
824   }
826   // Additional patterns for -1 constant.
827   def : Pat<(X86lock_add addr:$dst, (i8  -1)), (LOCK_DEC8m  addr:$dst)>;
828   def : Pat<(X86lock_add addr:$dst, (i16 -1)), (LOCK_DEC16m addr:$dst)>;
829   def : Pat<(X86lock_add addr:$dst, (i32 -1)), (LOCK_DEC32m addr:$dst)>;
830   def : Pat<(X86lock_add addr:$dst, (i64 -1)), (LOCK_DEC64m addr:$dst)>;
831   def : Pat<(X86lock_sub addr:$dst, (i8  -1)), (LOCK_INC8m  addr:$dst)>;
832   def : Pat<(X86lock_sub addr:$dst, (i16 -1)), (LOCK_INC16m addr:$dst)>;
833   def : Pat<(X86lock_sub addr:$dst, (i32 -1)), (LOCK_INC32m addr:$dst)>;
834   def : Pat<(X86lock_sub addr:$dst, (i64 -1)), (LOCK_INC64m addr:$dst)>;
837 // Atomic compare and swap.
838 multiclass LCMPXCHG_UnOp<bits<8> Opc, Format Form, string mnemonic,
839                          SDPatternOperator frag, X86MemOperand x86memop> {
840 let isCodeGenOnly = 1, usesCustomInserter = 1 in {
841   def NAME : I<Opc, Form, (outs), (ins x86memop:$ptr),
842                !strconcat(mnemonic, "\t$ptr"),
843                [(frag addr:$ptr)]>, TB, LOCK;
847 multiclass LCMPXCHG_BinOp<bits<8> Opc8, bits<8> Opc, Format Form,
848                           string mnemonic, SDPatternOperator frag> {
849 let isCodeGenOnly = 1, SchedRW = [WriteCMPXCHGRMW] in {
850   let Defs = [AL, EFLAGS], Uses = [AL] in
851   def NAME#8  : I<Opc8, Form, (outs), (ins i8mem:$ptr, GR8:$swap),
852                   !strconcat(mnemonic, "{b}\t{$swap, $ptr|$ptr, $swap}"),
853                   [(frag addr:$ptr, GR8:$swap, 1)]>, TB, LOCK;
854   let Defs = [AX, EFLAGS], Uses = [AX] in
855   def NAME#16 : I<Opc, Form, (outs), (ins i16mem:$ptr, GR16:$swap),
856                   !strconcat(mnemonic, "{w}\t{$swap, $ptr|$ptr, $swap}"),
857                   [(frag addr:$ptr, GR16:$swap, 2)]>, TB, OpSize16, LOCK;
858   let Defs = [EAX, EFLAGS], Uses = [EAX] in
859   def NAME#32 : I<Opc, Form, (outs), (ins i32mem:$ptr, GR32:$swap),
860                   !strconcat(mnemonic, "{l}\t{$swap, $ptr|$ptr, $swap}"),
861                   [(frag addr:$ptr, GR32:$swap, 4)]>, TB, OpSize32, LOCK;
862   let Defs = [RAX, EFLAGS], Uses = [RAX] in
863   def NAME#64 : RI<Opc, Form, (outs), (ins i64mem:$ptr, GR64:$swap),
864                    !strconcat(mnemonic, "{q}\t{$swap, $ptr|$ptr, $swap}"),
865                    [(frag addr:$ptr, GR64:$swap, 8)]>, TB, LOCK;
869 let Defs = [EAX, EDX, EFLAGS], Uses = [EAX, EBX, ECX, EDX],
870     SchedRW = [WriteCMPXCHGRMW] in {
871 defm LCMPXCHG8B : LCMPXCHG_UnOp<0xC7, MRM1m, "cmpxchg8b", X86cas8, i64mem>;
874 // This pseudo must be used when the frame uses RBX as
875 // the base pointer. Indeed, in such situation RBX is a reserved
876 // register and the register allocator will ignore any use/def of
877 // it. In other words, the register will not fix the clobbering of
878 // RBX that will happen when setting the arguments for the instrucion.
880 // Unlike the actual related instuction, we mark that this one
881 // defines EBX (instead of using EBX).
882 // The rationale is that we will define RBX during the expansion of
883 // the pseudo. The argument feeding EBX is ebx_input.
885 // The additional argument, $ebx_save, is a temporary register used to
886 // save the value of RBX across the actual instruction.
888 // To make sure the register assigned to $ebx_save does not interfere with
889 // the definition of the actual instruction, we use a definition $dst which
890 // is tied to $rbx_save. That way, the live-range of $rbx_save spans across
891 // the instruction and we are sure we will have a valid register to restore
892 // the value of RBX.
893 let Defs = [EAX, EDX, EBX, EFLAGS], Uses = [EAX, ECX, EDX],
894     SchedRW = [WriteCMPXCHGRMW], isCodeGenOnly = 1, isPseudo = 1,
895     Constraints = "$ebx_save = $dst", usesCustomInserter = 1 in {
896 def LCMPXCHG8B_SAVE_EBX :
897     I<0, Pseudo, (outs GR32:$dst),
898       (ins i64mem:$ptr, GR32:$ebx_input, GR32:$ebx_save),
899       !strconcat("cmpxchg8b", "\t$ptr"),
900       [(set GR32:$dst, (X86cas8save_ebx addr:$ptr, GR32:$ebx_input,
901                                         GR32:$ebx_save))]>;
905 let Defs = [RAX, RDX, EFLAGS], Uses = [RAX, RBX, RCX, RDX],
906     Predicates = [HasCmpxchg16b], SchedRW = [WriteCMPXCHGRMW] in {
907 defm LCMPXCHG16B : LCMPXCHG_UnOp<0xC7, MRM1m, "cmpxchg16b",
908                                  X86cas16, i128mem>, REX_W;
911 // Same as LCMPXCHG8B_SAVE_RBX but for the 16 Bytes variant.
912 let Defs = [RAX, RDX, RBX, EFLAGS], Uses = [RAX, RCX, RDX],
913     Predicates = [HasCmpxchg16b], SchedRW = [WriteCMPXCHGRMW],
914     isCodeGenOnly = 1, isPseudo = 1, Constraints = "$rbx_save = $dst",
915     usesCustomInserter = 1 in {
916 def LCMPXCHG16B_SAVE_RBX :
917     I<0, Pseudo, (outs GR64:$dst),
918       (ins i128mem:$ptr, GR64:$rbx_input, GR64:$rbx_save),
919       !strconcat("cmpxchg16b", "\t$ptr"),
920       [(set GR64:$dst, (X86cas16save_rbx addr:$ptr, GR64:$rbx_input,
921                                                     GR64:$rbx_save))]>;
924 defm LCMPXCHG : LCMPXCHG_BinOp<0xB0, 0xB1, MRMDestMem, "cmpxchg", X86cas>;
926 // Atomic exchange and add
927 multiclass ATOMIC_LOAD_BINOP<bits<8> opc8, bits<8> opc, string mnemonic,
928                              string frag> {
929   let Constraints = "$val = $dst", Defs = [EFLAGS], isCodeGenOnly = 1,
930       SchedRW = [WriteALURMW] in {
931     def NAME#8  : I<opc8, MRMSrcMem, (outs GR8:$dst),
932                     (ins GR8:$val, i8mem:$ptr),
933                     !strconcat(mnemonic, "{b}\t{$val, $ptr|$ptr, $val}"),
934                     [(set GR8:$dst,
935                           (!cast<PatFrag>(frag # "_8") addr:$ptr, GR8:$val))]>;
936     def NAME#16 : I<opc, MRMSrcMem, (outs GR16:$dst),
937                     (ins GR16:$val, i16mem:$ptr),
938                     !strconcat(mnemonic, "{w}\t{$val, $ptr|$ptr, $val}"),
939                     [(set
940                        GR16:$dst,
941                        (!cast<PatFrag>(frag # "_16") addr:$ptr, GR16:$val))]>,
942                     OpSize16;
943     def NAME#32 : I<opc, MRMSrcMem, (outs GR32:$dst),
944                     (ins GR32:$val, i32mem:$ptr),
945                     !strconcat(mnemonic, "{l}\t{$val, $ptr|$ptr, $val}"),
946                     [(set
947                        GR32:$dst,
948                        (!cast<PatFrag>(frag # "_32") addr:$ptr, GR32:$val))]>, 
949                     OpSize32;
950     def NAME#64 : RI<opc, MRMSrcMem, (outs GR64:$dst),
951                      (ins GR64:$val, i64mem:$ptr),
952                      !strconcat(mnemonic, "{q}\t{$val, $ptr|$ptr, $val}"),
953                      [(set
954                         GR64:$dst,
955                         (!cast<PatFrag>(frag # "_64") addr:$ptr, GR64:$val))]>;
956   }
959 defm LXADD : ATOMIC_LOAD_BINOP<0xc0, 0xc1, "xadd", "atomic_load_add">, TB, LOCK;
961 /* The following multiclass tries to make sure that in code like
962  *    x.store (immediate op x.load(acquire), release)
963  * and
964  *    x.store (register op x.load(acquire), release)
965  * an operation directly on memory is generated instead of wasting a register.
966  * It is not automatic as atomic_store/load are only lowered to MOV instructions
967  * extremely late to prevent them from being accidentally reordered in the backend
968  * (see below the RELEASE_MOV* / ACQUIRE_MOV* pseudo-instructions)
969  */
970 multiclass RELEASE_BINOP_MI<string Name, SDNode op> {
971   def : Pat<(atomic_store_8 addr:$dst,
972              (op (atomic_load_8 addr:$dst), (i8 imm:$src))),
973             (!cast<Instruction>(Name#"8mi") addr:$dst, imm:$src)>;
974   def : Pat<(atomic_store_16 addr:$dst,
975              (op (atomic_load_16 addr:$dst), (i16 imm:$src))),
976             (!cast<Instruction>(Name#"16mi") addr:$dst, imm:$src)>;
977   def : Pat<(atomic_store_32 addr:$dst,
978              (op (atomic_load_32 addr:$dst), (i32 imm:$src))),
979             (!cast<Instruction>(Name#"32mi") addr:$dst, imm:$src)>;
980   def : Pat<(atomic_store_64 addr:$dst,
981              (op (atomic_load_64 addr:$dst), (i64immSExt32:$src))),
982             (!cast<Instruction>(Name#"64mi32") addr:$dst, (i64immSExt32:$src))>;
984   def : Pat<(atomic_store_8 addr:$dst,
985              (op (atomic_load_8 addr:$dst), (i8 GR8:$src))),
986             (!cast<Instruction>(Name#"8mr") addr:$dst, GR8:$src)>;
987   def : Pat<(atomic_store_16 addr:$dst,
988              (op (atomic_load_16 addr:$dst), (i16 GR16:$src))),
989             (!cast<Instruction>(Name#"16mr") addr:$dst, GR16:$src)>;
990   def : Pat<(atomic_store_32 addr:$dst,
991              (op (atomic_load_32 addr:$dst), (i32 GR32:$src))),
992             (!cast<Instruction>(Name#"32mr") addr:$dst, GR32:$src)>;
993   def : Pat<(atomic_store_64 addr:$dst,
994              (op (atomic_load_64 addr:$dst), (i64 GR64:$src))),
995             (!cast<Instruction>(Name#"64mr") addr:$dst, GR64:$src)>;
997 defm : RELEASE_BINOP_MI<"ADD", add>;
998 defm : RELEASE_BINOP_MI<"AND", and>;
999 defm : RELEASE_BINOP_MI<"OR",  or>;
1000 defm : RELEASE_BINOP_MI<"XOR", xor>;
1001 defm : RELEASE_BINOP_MI<"SUB", sub>;
1003 // Same as above, but for floating-point.
1004 // FIXME: imm version.
1005 // FIXME: Version that doesn't clobber $src, using AVX's VADDSS.
1006 // FIXME: This could also handle SIMD operations with *ps and *pd instructions.
1007 let usesCustomInserter = 1, SchedRW = [WriteMicrocoded] in {
1008 multiclass RELEASE_FP_BINOP_MI<SDNode op> {
1009     def NAME#32mr : I<0, Pseudo, (outs), (ins i32mem:$dst, FR32:$src),
1010         "#BINOP "#NAME#"32mr PSEUDO!",
1011         [(atomic_store_32 addr:$dst,
1012            (i32 (bitconvert (op
1013              (f32 (bitconvert (i32 (atomic_load_32 addr:$dst)))),
1014           FR32:$src))))]>, Requires<[HasSSE1]>;
1015     def NAME#64mr : I<0, Pseudo, (outs), (ins i64mem:$dst, FR64:$src),
1016         "#BINOP "#NAME#"64mr PSEUDO!",
1017         [(atomic_store_64 addr:$dst,
1018            (i64 (bitconvert (op
1019              (f64 (bitconvert (i64 (atomic_load_64 addr:$dst)))),
1020           FR64:$src))))]>, Requires<[HasSSE2]>;
1022 defm RELEASE_FADD : RELEASE_FP_BINOP_MI<fadd>;
1023 // FIXME: Add fsub, fmul, fdiv, ...
1026 multiclass RELEASE_UNOP<string Name, dag dag8, dag dag16, dag dag32,
1027                         dag dag64> {
1028   def : Pat<(atomic_store_8 addr:$dst, dag8),
1029             (!cast<Instruction>(Name#8m) addr:$dst)>;
1030   def : Pat<(atomic_store_16 addr:$dst, dag16),
1031             (!cast<Instruction>(Name#16m) addr:$dst)>;
1032   def : Pat<(atomic_store_32 addr:$dst, dag32),
1033             (!cast<Instruction>(Name#32m) addr:$dst)>;
1034   def : Pat<(atomic_store_64 addr:$dst, dag64),
1035             (!cast<Instruction>(Name#64m) addr:$dst)>;
1038 let Predicates = [UseIncDec] in {
1039   defm : RELEASE_UNOP<"INC",
1040       (add (atomic_load_8  addr:$dst), (i8 1)),
1041       (add (atomic_load_16 addr:$dst), (i16 1)),
1042       (add (atomic_load_32 addr:$dst), (i32 1)),
1043       (add (atomic_load_64 addr:$dst), (i64 1))>;
1044   defm : RELEASE_UNOP<"DEC",
1045       (add (atomic_load_8  addr:$dst), (i8 -1)),
1046       (add (atomic_load_16 addr:$dst), (i16 -1)),
1047       (add (atomic_load_32 addr:$dst), (i32 -1)),
1048       (add (atomic_load_64 addr:$dst), (i64 -1))>;
1051 defm : RELEASE_UNOP<"NEG",
1052     (ineg (i8 (atomic_load_8  addr:$dst))),
1053     (ineg (i16 (atomic_load_16 addr:$dst))),
1054     (ineg (i32 (atomic_load_32 addr:$dst))),
1055     (ineg (i64 (atomic_load_64 addr:$dst)))>;
1056 defm : RELEASE_UNOP<"NOT",
1057     (not (i8 (atomic_load_8  addr:$dst))),
1058     (not (i16 (atomic_load_16 addr:$dst))),
1059     (not (i32 (atomic_load_32 addr:$dst))),
1060     (not (i64 (atomic_load_64 addr:$dst)))>;
1062 def : Pat<(atomic_store_8 addr:$dst, (i8 imm:$src)),
1063           (MOV8mi addr:$dst, imm:$src)>;
1064 def : Pat<(atomic_store_16 addr:$dst, (i16 imm:$src)),
1065           (MOV16mi addr:$dst, imm:$src)>;
1066 def : Pat<(atomic_store_32 addr:$dst, (i32 imm:$src)),
1067           (MOV32mi addr:$dst, imm:$src)>;
1068 def : Pat<(atomic_store_64 addr:$dst, (i64immSExt32:$src)),
1069           (MOV64mi32 addr:$dst, i64immSExt32:$src)>;
1071 def : Pat<(atomic_store_8 addr:$dst, GR8:$src),
1072           (MOV8mr addr:$dst, GR8:$src)>;
1073 def : Pat<(atomic_store_16 addr:$dst, GR16:$src),
1074           (MOV16mr addr:$dst, GR16:$src)>;
1075 def : Pat<(atomic_store_32 addr:$dst, GR32:$src),
1076           (MOV32mr addr:$dst, GR32:$src)>;
1077 def : Pat<(atomic_store_64 addr:$dst, GR64:$src),
1078           (MOV64mr addr:$dst, GR64:$src)>;
1080 def : Pat<(i8  (atomic_load_8 addr:$src)),  (MOV8rm addr:$src)>;
1081 def : Pat<(i16 (atomic_load_16 addr:$src)), (MOV16rm addr:$src)>;
1082 def : Pat<(i32 (atomic_load_32 addr:$src)), (MOV32rm addr:$src)>;
1083 def : Pat<(i64 (atomic_load_64 addr:$src)), (MOV64rm addr:$src)>;
1085 //===----------------------------------------------------------------------===//
1086 // DAG Pattern Matching Rules
1087 //===----------------------------------------------------------------------===//
1089 // Use AND/OR to store 0/-1 in memory when optimizing for minsize. This saves
1090 // binary size compared to a regular MOV, but it introduces an unnecessary
1091 // load, so is not suitable for regular or optsize functions.
1092 let Predicates = [OptForMinSize] in {
1093 def : Pat<(nonvolatile_store (i16 0), addr:$dst), (AND16mi8 addr:$dst, 0)>;
1094 def : Pat<(nonvolatile_store (i32 0), addr:$dst), (AND32mi8 addr:$dst, 0)>;
1095 def : Pat<(nonvolatile_store (i64 0), addr:$dst), (AND64mi8 addr:$dst, 0)>;
1096 def : Pat<(nonvolatile_store (i16 -1), addr:$dst), (OR16mi8 addr:$dst, -1)>;
1097 def : Pat<(nonvolatile_store (i32 -1), addr:$dst), (OR32mi8 addr:$dst, -1)>;
1098 def : Pat<(nonvolatile_store (i64 -1), addr:$dst), (OR64mi8 addr:$dst, -1)>;
1101 // In kernel code model, we can get the address of a label
1102 // into a register with 'movq'.  FIXME: This is a hack, the 'imm' predicate of
1103 // the MOV64ri32 should accept these.
1104 def : Pat<(i64 (X86Wrapper tconstpool  :$dst)),
1105           (MOV64ri32 tconstpool  :$dst)>, Requires<[KernelCode]>;
1106 def : Pat<(i64 (X86Wrapper tjumptable  :$dst)),
1107           (MOV64ri32 tjumptable  :$dst)>, Requires<[KernelCode]>;
1108 def : Pat<(i64 (X86Wrapper tglobaladdr :$dst)),
1109           (MOV64ri32 tglobaladdr :$dst)>, Requires<[KernelCode]>;
1110 def : Pat<(i64 (X86Wrapper texternalsym:$dst)),
1111           (MOV64ri32 texternalsym:$dst)>, Requires<[KernelCode]>;
1112 def : Pat<(i64 (X86Wrapper mcsym:$dst)),
1113           (MOV64ri32 mcsym:$dst)>, Requires<[KernelCode]>;
1114 def : Pat<(i64 (X86Wrapper tblockaddress:$dst)),
1115           (MOV64ri32 tblockaddress:$dst)>, Requires<[KernelCode]>;
1117 // If we have small model and -static mode, it is safe to store global addresses
1118 // directly as immediates.  FIXME: This is really a hack, the 'imm' predicate
1119 // for MOV64mi32 should handle this sort of thing.
1120 def : Pat<(store (i64 (X86Wrapper tconstpool:$src)), addr:$dst),
1121           (MOV64mi32 addr:$dst, tconstpool:$src)>,
1122           Requires<[NearData, IsNotPIC]>;
1123 def : Pat<(store (i64 (X86Wrapper tjumptable:$src)), addr:$dst),
1124           (MOV64mi32 addr:$dst, tjumptable:$src)>,
1125           Requires<[NearData, IsNotPIC]>;
1126 def : Pat<(store (i64 (X86Wrapper tglobaladdr:$src)), addr:$dst),
1127           (MOV64mi32 addr:$dst, tglobaladdr:$src)>,
1128           Requires<[NearData, IsNotPIC]>;
1129 def : Pat<(store (i64 (X86Wrapper texternalsym:$src)), addr:$dst),
1130           (MOV64mi32 addr:$dst, texternalsym:$src)>,
1131           Requires<[NearData, IsNotPIC]>;
1132 def : Pat<(store (i64 (X86Wrapper mcsym:$src)), addr:$dst),
1133           (MOV64mi32 addr:$dst, mcsym:$src)>,
1134           Requires<[NearData, IsNotPIC]>;
1135 def : Pat<(store (i64 (X86Wrapper tblockaddress:$src)), addr:$dst),
1136           (MOV64mi32 addr:$dst, tblockaddress:$src)>,
1137           Requires<[NearData, IsNotPIC]>;
1139 def : Pat<(i32 (X86RecoverFrameAlloc mcsym:$dst)), (MOV32ri mcsym:$dst)>;
1140 def : Pat<(i64 (X86RecoverFrameAlloc mcsym:$dst)), (MOV64ri mcsym:$dst)>;
1142 // Calls
1144 // tls has some funny stuff here...
1145 // This corresponds to movabs $foo@tpoff, %rax
1146 def : Pat<(i64 (X86Wrapper tglobaltlsaddr :$dst)),
1147           (MOV64ri32 tglobaltlsaddr :$dst)>;
1148 // This corresponds to add $foo@tpoff, %rax
1149 def : Pat<(add GR64:$src1, (X86Wrapper tglobaltlsaddr :$dst)),
1150           (ADD64ri32 GR64:$src1, tglobaltlsaddr :$dst)>;
1153 // Direct PC relative function call for small code model. 32-bit displacement
1154 // sign extended to 64-bit.
1155 def : Pat<(X86call (i64 tglobaladdr:$dst)),
1156           (CALL64pcrel32 tglobaladdr:$dst)>;
1157 def : Pat<(X86call (i64 texternalsym:$dst)),
1158           (CALL64pcrel32 texternalsym:$dst)>;
1160 // Tailcall stuff. The TCRETURN instructions execute after the epilog, so they
1161 // can never use callee-saved registers. That is the purpose of the GR64_TC
1162 // register classes.
1164 // The only volatile register that is never used by the calling convention is
1165 // %r11. This happens when calling a vararg function with 6 arguments.
1167 // Match an X86tcret that uses less than 7 volatile registers.
1168 def X86tcret_6regs : PatFrag<(ops node:$ptr, node:$off),
1169                              (X86tcret node:$ptr, node:$off), [{
1170   // X86tcret args: (*chain, ptr, imm, regs..., glue)
1171   unsigned NumRegs = 0;
1172   for (unsigned i = 3, e = N->getNumOperands(); i != e; ++i)
1173     if (isa<RegisterSDNode>(N->getOperand(i)) && ++NumRegs > 6)
1174       return false;
1175   return true;
1176 }]>;
1178 def : Pat<(X86tcret ptr_rc_tailcall:$dst, imm:$off),
1179           (TCRETURNri ptr_rc_tailcall:$dst, imm:$off)>,
1180           Requires<[Not64BitMode, NotUseRetpolineIndirectCalls]>;
1182 // FIXME: This is disabled for 32-bit PIC mode because the global base
1183 // register which is part of the address mode may be assigned a
1184 // callee-saved register.
1185 def : Pat<(X86tcret (load addr:$dst), imm:$off),
1186           (TCRETURNmi addr:$dst, imm:$off)>,
1187           Requires<[Not64BitMode, IsNotPIC, NotUseRetpolineIndirectCalls]>;
1189 def : Pat<(X86tcret (i32 tglobaladdr:$dst), imm:$off),
1190           (TCRETURNdi tglobaladdr:$dst, imm:$off)>,
1191           Requires<[NotLP64]>;
1193 def : Pat<(X86tcret (i32 texternalsym:$dst), imm:$off),
1194           (TCRETURNdi texternalsym:$dst, imm:$off)>,
1195           Requires<[NotLP64]>;
1197 def : Pat<(X86tcret ptr_rc_tailcall:$dst, imm:$off),
1198           (TCRETURNri64 ptr_rc_tailcall:$dst, imm:$off)>,
1199           Requires<[In64BitMode, NotUseRetpolineIndirectCalls]>;
1201 // Don't fold loads into X86tcret requiring more than 6 regs.
1202 // There wouldn't be enough scratch registers for base+index.
1203 def : Pat<(X86tcret_6regs (load addr:$dst), imm:$off),
1204           (TCRETURNmi64 addr:$dst, imm:$off)>,
1205           Requires<[In64BitMode, NotUseRetpolineIndirectCalls]>;
1207 def : Pat<(X86tcret ptr_rc_tailcall:$dst, imm:$off),
1208           (RETPOLINE_TCRETURN64 ptr_rc_tailcall:$dst, imm:$off)>,
1209           Requires<[In64BitMode, UseRetpolineIndirectCalls]>;
1211 def : Pat<(X86tcret ptr_rc_tailcall:$dst, imm:$off),
1212           (RETPOLINE_TCRETURN32 ptr_rc_tailcall:$dst, imm:$off)>,
1213           Requires<[Not64BitMode, UseRetpolineIndirectCalls]>;
1215 def : Pat<(X86tcret (i64 tglobaladdr:$dst), imm:$off),
1216           (TCRETURNdi64 tglobaladdr:$dst, imm:$off)>,
1217           Requires<[IsLP64]>;
1219 def : Pat<(X86tcret (i64 texternalsym:$dst), imm:$off),
1220           (TCRETURNdi64 texternalsym:$dst, imm:$off)>,
1221           Requires<[IsLP64]>;
1223 // Normal calls, with various flavors of addresses.
1224 def : Pat<(X86call (i32 tglobaladdr:$dst)),
1225           (CALLpcrel32 tglobaladdr:$dst)>;
1226 def : Pat<(X86call (i32 texternalsym:$dst)),
1227           (CALLpcrel32 texternalsym:$dst)>;
1228 def : Pat<(X86call (i32 imm:$dst)),
1229           (CALLpcrel32 imm:$dst)>, Requires<[CallImmAddr]>;
1231 // Comparisons.
1233 // TEST R,R is smaller than CMP R,0
1234 def : Pat<(X86cmp GR8:$src1, 0),
1235           (TEST8rr GR8:$src1, GR8:$src1)>;
1236 def : Pat<(X86cmp GR16:$src1, 0),
1237           (TEST16rr GR16:$src1, GR16:$src1)>;
1238 def : Pat<(X86cmp GR32:$src1, 0),
1239           (TEST32rr GR32:$src1, GR32:$src1)>;
1240 def : Pat<(X86cmp GR64:$src1, 0),
1241           (TEST64rr GR64:$src1, GR64:$src1)>;
1243 // Conditional moves with folded loads with operands swapped and conditions
1244 // inverted.
1245 multiclass CMOVmr<PatLeaf InvertedCond, Instruction Inst16, Instruction Inst32,
1246                   Instruction Inst64> {
1247   let Predicates = [HasCMov] in {
1248     def : Pat<(X86cmov (loadi16 addr:$src1), GR16:$src2, InvertedCond, EFLAGS),
1249               (Inst16 GR16:$src2, addr:$src1)>;
1250     def : Pat<(X86cmov (loadi32 addr:$src1), GR32:$src2, InvertedCond, EFLAGS),
1251               (Inst32 GR32:$src2, addr:$src1)>;
1252     def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, InvertedCond, EFLAGS),
1253               (Inst64 GR64:$src2, addr:$src1)>;
1254   }
1257 defm : CMOVmr<X86_COND_B , CMOVAE16rm, CMOVAE32rm, CMOVAE64rm>;
1258 defm : CMOVmr<X86_COND_AE, CMOVB16rm , CMOVB32rm , CMOVB64rm>;
1259 defm : CMOVmr<X86_COND_E , CMOVNE16rm, CMOVNE32rm, CMOVNE64rm>;
1260 defm : CMOVmr<X86_COND_NE, CMOVE16rm , CMOVE32rm , CMOVE64rm>;
1261 defm : CMOVmr<X86_COND_BE, CMOVA16rm , CMOVA32rm , CMOVA64rm>;
1262 defm : CMOVmr<X86_COND_A , CMOVBE16rm, CMOVBE32rm, CMOVBE64rm>;
1263 defm : CMOVmr<X86_COND_L , CMOVGE16rm, CMOVGE32rm, CMOVGE64rm>;
1264 defm : CMOVmr<X86_COND_GE, CMOVL16rm , CMOVL32rm , CMOVL64rm>;
1265 defm : CMOVmr<X86_COND_LE, CMOVG16rm , CMOVG32rm , CMOVG64rm>;
1266 defm : CMOVmr<X86_COND_G , CMOVLE16rm, CMOVLE32rm, CMOVLE64rm>;
1267 defm : CMOVmr<X86_COND_P , CMOVNP16rm, CMOVNP32rm, CMOVNP64rm>;
1268 defm : CMOVmr<X86_COND_NP, CMOVP16rm , CMOVP32rm , CMOVP64rm>;
1269 defm : CMOVmr<X86_COND_S , CMOVNS16rm, CMOVNS32rm, CMOVNS64rm>;
1270 defm : CMOVmr<X86_COND_NS, CMOVS16rm , CMOVS32rm , CMOVS64rm>;
1271 defm : CMOVmr<X86_COND_O , CMOVNO16rm, CMOVNO32rm, CMOVNO64rm>;
1272 defm : CMOVmr<X86_COND_NO, CMOVO16rm , CMOVO32rm , CMOVO64rm>;
1274 // zextload bool -> zextload byte
1275 // i1 stored in one byte in zero-extended form.
1276 // Upper bits cleanup should be executed before Store.
1277 def : Pat<(zextloadi8i1  addr:$src), (MOV8rm addr:$src)>;
1278 def : Pat<(zextloadi16i1 addr:$src),
1279           (EXTRACT_SUBREG (MOVZX32rm8 addr:$src), sub_16bit)>;
1280 def : Pat<(zextloadi32i1 addr:$src), (MOVZX32rm8 addr:$src)>;
1281 def : Pat<(zextloadi64i1 addr:$src),
1282           (SUBREG_TO_REG (i64 0), (MOVZX32rm8 addr:$src), sub_32bit)>;
1284 // extload bool -> extload byte
1285 // When extloading from 16-bit and smaller memory locations into 64-bit
1286 // registers, use zero-extending loads so that the entire 64-bit register is
1287 // defined, avoiding partial-register updates.
1289 def : Pat<(extloadi8i1 addr:$src),   (MOV8rm      addr:$src)>;
1290 def : Pat<(extloadi16i1 addr:$src),
1291           (EXTRACT_SUBREG (MOVZX32rm8 addr:$src), sub_16bit)>;
1292 def : Pat<(extloadi32i1 addr:$src),  (MOVZX32rm8  addr:$src)>;
1293 def : Pat<(extloadi16i8 addr:$src),
1294           (EXTRACT_SUBREG (MOVZX32rm8 addr:$src), sub_16bit)>;
1295 def : Pat<(extloadi32i8 addr:$src),  (MOVZX32rm8  addr:$src)>;
1296 def : Pat<(extloadi32i16 addr:$src), (MOVZX32rm16 addr:$src)>;
1298 // For other extloads, use subregs, since the high contents of the register are
1299 // defined after an extload.
1300 def : Pat<(extloadi64i1 addr:$src),
1301           (SUBREG_TO_REG (i64 0), (MOVZX32rm8 addr:$src), sub_32bit)>;
1302 def : Pat<(extloadi64i8 addr:$src),
1303           (SUBREG_TO_REG (i64 0), (MOVZX32rm8 addr:$src), sub_32bit)>;
1304 def : Pat<(extloadi64i16 addr:$src),
1305           (SUBREG_TO_REG (i64 0), (MOVZX32rm16 addr:$src), sub_32bit)>;
1306 def : Pat<(extloadi64i32 addr:$src),
1307           (SUBREG_TO_REG (i64 0), (MOV32rm addr:$src), sub_32bit)>;
1309 // anyext. Define these to do an explicit zero-extend to
1310 // avoid partial-register updates.
1311 def : Pat<(i16 (anyext GR8 :$src)), (EXTRACT_SUBREG
1312                                      (MOVZX32rr8 GR8 :$src), sub_16bit)>;
1313 def : Pat<(i32 (anyext GR8 :$src)), (MOVZX32rr8  GR8 :$src)>;
1315 // Except for i16 -> i32 since isel expect i16 ops to be promoted to i32.
1316 def : Pat<(i32 (anyext GR16:$src)),
1317           (INSERT_SUBREG (i32 (IMPLICIT_DEF)), GR16:$src, sub_16bit)>;
1319 def : Pat<(i64 (anyext GR8 :$src)),
1320           (SUBREG_TO_REG (i64 0), (MOVZX32rr8  GR8  :$src), sub_32bit)>;
1321 def : Pat<(i64 (anyext GR16:$src)),
1322           (SUBREG_TO_REG (i64 0), (MOVZX32rr16 GR16 :$src), sub_32bit)>;
1323 def : Pat<(i64 (anyext GR32:$src)),
1324           (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR32:$src, sub_32bit)>;
1326 // If this is an anyext of the remainder of an 8-bit sdivrem, use a MOVSX
1327 // instead of a MOVZX. The sdivrem lowering will emit emit a MOVSX to move
1328 // %ah to the lower byte of a register. By using a MOVSX here we allow a
1329 // post-isel peephole to merge the two MOVSX instructions into one.
1330 def anyext_sdiv : PatFrag<(ops node:$lhs), (anyext node:$lhs),[{
1331   return (N->getOperand(0).getOpcode() == ISD::SDIVREM &&
1332           N->getOperand(0).getResNo() == 1);
1333 }]>;
1334 def : Pat<(i32 (anyext_sdiv GR8:$src)), (MOVSX32rr8 GR8:$src)>;
1336 // Any instruction that defines a 32-bit result leaves the high half of the
1337 // register. Truncate can be lowered to EXTRACT_SUBREG. CopyFromReg may
1338 // be copying from a truncate. Any other 32-bit operation will zero-extend
1339 // up to 64 bits. AssertSext/AssertZext aren't saying anything about the upper
1340 // 32 bits, they're probably just qualifying a CopyFromReg.
1341 def def32 : PatLeaf<(i32 GR32:$src), [{
1342   return N->getOpcode() != ISD::TRUNCATE &&
1343          N->getOpcode() != TargetOpcode::EXTRACT_SUBREG &&
1344          N->getOpcode() != ISD::CopyFromReg &&
1345          N->getOpcode() != ISD::AssertSext &&
1346          N->getOpcode() != ISD::AssertZext;
1347 }]>;
1349 // In the case of a 32-bit def that is known to implicitly zero-extend,
1350 // we can use a SUBREG_TO_REG.
1351 def : Pat<(i64 (zext def32:$src)),
1352           (SUBREG_TO_REG (i64 0), GR32:$src, sub_32bit)>;
1353 def : Pat<(i64 (and (anyext def32:$src), 0x00000000FFFFFFFF)),
1354           (SUBREG_TO_REG (i64 0), GR32:$src, sub_32bit)>;
1356 //===----------------------------------------------------------------------===//
1357 // Pattern match OR as ADD
1358 //===----------------------------------------------------------------------===//
1360 // If safe, we prefer to pattern match OR as ADD at isel time. ADD can be
1361 // 3-addressified into an LEA instruction to avoid copies.  However, we also
1362 // want to finally emit these instructions as an or at the end of the code
1363 // generator to make the generated code easier to read.  To do this, we select
1364 // into "disjoint bits" pseudo ops.
1366 // Treat an 'or' node is as an 'add' if the or'ed bits are known to be zero.
1367 def or_is_add : PatFrag<(ops node:$lhs, node:$rhs), (or node:$lhs, node:$rhs),[{
1368   if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N->getOperand(1)))
1369     return CurDAG->MaskedValueIsZero(N->getOperand(0), CN->getAPIntValue());
1371   KnownBits Known0 = CurDAG->computeKnownBits(N->getOperand(0), 0);
1372   KnownBits Known1 = CurDAG->computeKnownBits(N->getOperand(1), 0);
1373   return (~Known0.Zero & ~Known1.Zero) == 0;
1374 }]>;
1377 // (or x1, x2) -> (add x1, x2) if two operands are known not to share bits.
1378 // Try this before the selecting to OR.
1379 let SchedRW = [WriteALU] in {
1381 let isConvertibleToThreeAddress = 1,
1382     Constraints = "$src1 = $dst", Defs = [EFLAGS] in {
1383 let isCommutable = 1 in {
1384 def ADD16rr_DB  : I<0, Pseudo, (outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
1385                     "", // orw/addw REG, REG
1386                     [(set GR16:$dst, (or_is_add GR16:$src1, GR16:$src2))]>;
1387 def ADD32rr_DB  : I<0, Pseudo, (outs GR32:$dst), (ins GR32:$src1, GR32:$src2),
1388                     "", // orl/addl REG, REG
1389                     [(set GR32:$dst, (or_is_add GR32:$src1, GR32:$src2))]>;
1390 def ADD64rr_DB  : I<0, Pseudo, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
1391                     "", // orq/addq REG, REG
1392                     [(set GR64:$dst, (or_is_add GR64:$src1, GR64:$src2))]>;
1393 } // isCommutable
1395 // NOTE: These are order specific, we want the ri8 forms to be listed
1396 // first so that they are slightly preferred to the ri forms.
1398 def ADD16ri8_DB : I<0, Pseudo,
1399                     (outs GR16:$dst), (ins GR16:$src1, i16i8imm:$src2),
1400                     "", // orw/addw REG, imm8
1401                     [(set GR16:$dst,(or_is_add GR16:$src1,i16immSExt8:$src2))]>;
1402 def ADD16ri_DB  : I<0, Pseudo, (outs GR16:$dst), (ins GR16:$src1, i16imm:$src2),
1403                     "", // orw/addw REG, imm
1404                     [(set GR16:$dst, (or_is_add GR16:$src1, imm:$src2))]>;
1406 def ADD32ri8_DB : I<0, Pseudo,
1407                     (outs GR32:$dst), (ins GR32:$src1, i32i8imm:$src2),
1408                     "", // orl/addl REG, imm8
1409                     [(set GR32:$dst,(or_is_add GR32:$src1,i32immSExt8:$src2))]>;
1410 def ADD32ri_DB  : I<0, Pseudo, (outs GR32:$dst), (ins GR32:$src1, i32imm:$src2),
1411                     "", // orl/addl REG, imm
1412                     [(set GR32:$dst, (or_is_add GR32:$src1, imm:$src2))]>;
1415 def ADD64ri8_DB : I<0, Pseudo,
1416                     (outs GR64:$dst), (ins GR64:$src1, i64i8imm:$src2),
1417                     "", // orq/addq REG, imm8
1418                     [(set GR64:$dst, (or_is_add GR64:$src1,
1419                                                 i64immSExt8:$src2))]>;
1420 def ADD64ri32_DB : I<0, Pseudo,
1421                      (outs GR64:$dst), (ins GR64:$src1, i64i32imm:$src2),
1422                      "", // orq/addq REG, imm
1423                      [(set GR64:$dst, (or_is_add GR64:$src1,
1424                                                  i64immSExt32:$src2))]>;
1426 } // AddedComplexity, SchedRW
1428 //===----------------------------------------------------------------------===//
1429 // Pattern match SUB as XOR
1430 //===----------------------------------------------------------------------===//
1432 // An immediate in the LHS of a subtract can't be encoded in the instruction.
1433 // If there is no possibility of a borrow we can use an XOR instead of a SUB
1434 // to enable the immediate to be folded.
1435 // TODO: Move this to a DAG combine?
1437 def sub_is_xor : PatFrag<(ops node:$lhs, node:$rhs), (sub node:$lhs, node:$rhs),[{
1438   if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N->getOperand(0))) {
1439     KnownBits Known = CurDAG->computeKnownBits(N->getOperand(1));
1441     // If all possible ones in the RHS are set in the LHS then there can't be
1442     // a borrow and we can use xor.
1443     return (~Known.Zero).isSubsetOf(CN->getAPIntValue());
1444   }
1446   return false;
1447 }]>;
1449 let AddedComplexity = 5 in {
1450 def : Pat<(sub_is_xor imm:$src2, GR8:$src1),
1451           (XOR8ri GR8:$src1, imm:$src2)>;
1452 def : Pat<(sub_is_xor i16immSExt8:$src2, GR16:$src1),
1453           (XOR16ri8 GR16:$src1, i16immSExt8:$src2)>;
1454 def : Pat<(sub_is_xor imm:$src2, GR16:$src1),
1455           (XOR16ri GR16:$src1, imm:$src2)>;
1456 def : Pat<(sub_is_xor i32immSExt8:$src2, GR32:$src1),
1457           (XOR32ri8 GR32:$src1, i32immSExt8:$src2)>;
1458 def : Pat<(sub_is_xor imm:$src2, GR32:$src1),
1459           (XOR32ri GR32:$src1, imm:$src2)>;
1460 def : Pat<(sub_is_xor i64immSExt8:$src2, GR64:$src1),
1461           (XOR64ri8 GR64:$src1, i64immSExt8:$src2)>;
1462 def : Pat<(sub_is_xor i64immSExt32:$src2, GR64:$src1),
1463           (XOR64ri32 GR64:$src1, i64immSExt32:$src2)>;
1466 //===----------------------------------------------------------------------===//
1467 // Some peepholes
1468 //===----------------------------------------------------------------------===//
1470 // Odd encoding trick: -128 fits into an 8-bit immediate field while
1471 // +128 doesn't, so in this special case use a sub instead of an add.
1472 def : Pat<(add GR16:$src1, 128),
1473           (SUB16ri8 GR16:$src1, -128)>;
1474 def : Pat<(store (add (loadi16 addr:$dst), 128), addr:$dst),
1475           (SUB16mi8 addr:$dst, -128)>;
1477 def : Pat<(add GR32:$src1, 128),
1478           (SUB32ri8 GR32:$src1, -128)>;
1479 def : Pat<(store (add (loadi32 addr:$dst), 128), addr:$dst),
1480           (SUB32mi8 addr:$dst, -128)>;
1482 def : Pat<(add GR64:$src1, 128),
1483           (SUB64ri8 GR64:$src1, -128)>;
1484 def : Pat<(store (add (loadi64 addr:$dst), 128), addr:$dst),
1485           (SUB64mi8 addr:$dst, -128)>;
1487 // The same trick applies for 32-bit immediate fields in 64-bit
1488 // instructions.
1489 def : Pat<(add GR64:$src1, 0x0000000080000000),
1490           (SUB64ri32 GR64:$src1, 0xffffffff80000000)>;
1491 def : Pat<(store (add (loadi64 addr:$dst), 0x0000000080000000), addr:$dst),
1492           (SUB64mi32 addr:$dst, 0xffffffff80000000)>;
1494 // To avoid needing to materialize an immediate in a register, use a 32-bit and
1495 // with implicit zero-extension instead of a 64-bit and if the immediate has at
1496 // least 32 bits of leading zeros. If in addition the last 32 bits can be
1497 // represented with a sign extension of a 8 bit constant, use that.
1498 // This can also reduce instruction size by eliminating the need for the REX
1499 // prefix.
1501 // AddedComplexity is needed to give priority over i64immSExt8 and i64immSExt32.
1502 let AddedComplexity = 1 in {
1503 def : Pat<(and GR64:$src, i64immZExt32SExt8:$imm),
1504           (SUBREG_TO_REG
1505             (i64 0),
1506             (AND32ri8
1507               (EXTRACT_SUBREG GR64:$src, sub_32bit),
1508               (i32 (GetLo8XForm imm:$imm))),
1509             sub_32bit)>;
1511 def : Pat<(and GR64:$src, i64immZExt32:$imm),
1512           (SUBREG_TO_REG
1513             (i64 0),
1514             (AND32ri
1515               (EXTRACT_SUBREG GR64:$src, sub_32bit),
1516               (i32 (GetLo32XForm imm:$imm))),
1517             sub_32bit)>;
1518 } // AddedComplexity = 1
1521 // AddedComplexity is needed due to the increased complexity on the
1522 // i64immZExt32SExt8 and i64immZExt32 patterns above. Applying this to all
1523 // the MOVZX patterns keeps thems together in DAGIsel tables.
1524 let AddedComplexity = 1 in {
1525 // r & (2^16-1) ==> movz
1526 def : Pat<(and GR32:$src1, 0xffff),
1527           (MOVZX32rr16 (EXTRACT_SUBREG GR32:$src1, sub_16bit))>;
1528 // r & (2^8-1) ==> movz
1529 def : Pat<(and GR32:$src1, 0xff),
1530           (MOVZX32rr8 (EXTRACT_SUBREG GR32:$src1, sub_8bit))>;
1531 // r & (2^8-1) ==> movz
1532 def : Pat<(and GR16:$src1, 0xff),
1533            (EXTRACT_SUBREG (MOVZX32rr8 (EXTRACT_SUBREG GR16:$src1, sub_8bit)),
1534              sub_16bit)>;
1536 // r & (2^32-1) ==> movz
1537 def : Pat<(and GR64:$src, 0x00000000FFFFFFFF),
1538           (SUBREG_TO_REG (i64 0),
1539                          (MOV32rr (EXTRACT_SUBREG GR64:$src, sub_32bit)),
1540                          sub_32bit)>;
1541 // r & (2^16-1) ==> movz
1542 def : Pat<(and GR64:$src, 0xffff),
1543           (SUBREG_TO_REG (i64 0),
1544                       (MOVZX32rr16 (i16 (EXTRACT_SUBREG GR64:$src, sub_16bit))),
1545                       sub_32bit)>;
1546 // r & (2^8-1) ==> movz
1547 def : Pat<(and GR64:$src, 0xff),
1548           (SUBREG_TO_REG (i64 0),
1549                          (MOVZX32rr8 (i8 (EXTRACT_SUBREG GR64:$src, sub_8bit))),
1550                          sub_32bit)>;
1551 } // AddedComplexity = 1
1554 // Try to use BTS/BTR/BTC for single bit operations on the upper 32-bits.
1556 def BTRXForm : SDNodeXForm<imm, [{
1557   // Transformation function: Find the lowest 0.
1558   return getI64Imm((uint8_t)N->getAPIntValue().countTrailingOnes(), SDLoc(N));
1559 }]>;
1561 def BTCBTSXForm : SDNodeXForm<imm, [{
1562   // Transformation function: Find the lowest 1.
1563   return getI64Imm((uint8_t)N->getAPIntValue().countTrailingZeros(), SDLoc(N));
1564 }]>;
1566 def BTRMask64 : ImmLeaf<i64, [{
1567   return !isUInt<32>(Imm) && !isInt<32>(Imm) && isPowerOf2_64(~Imm);
1568 }]>;
1570 def BTCBTSMask64 : ImmLeaf<i64, [{
1571   return !isInt<32>(Imm) && isPowerOf2_64(Imm);
1572 }]>;
1574 // For now only do this for optsize.
1575 let AddedComplexity = 1, Predicates=[OptForSize] in {
1576   def : Pat<(and GR64:$src1, BTRMask64:$mask),
1577             (BTR64ri8 GR64:$src1, (BTRXForm imm:$mask))>;
1578   def : Pat<(or GR64:$src1, BTCBTSMask64:$mask),
1579             (BTS64ri8 GR64:$src1, (BTCBTSXForm imm:$mask))>;
1580   def : Pat<(xor GR64:$src1, BTCBTSMask64:$mask),
1581             (BTC64ri8 GR64:$src1, (BTCBTSXForm imm:$mask))>;
1585 // sext_inreg patterns
1586 def : Pat<(sext_inreg GR32:$src, i16),
1587           (MOVSX32rr16 (EXTRACT_SUBREG GR32:$src, sub_16bit))>;
1588 def : Pat<(sext_inreg GR32:$src, i8),
1589           (MOVSX32rr8 (EXTRACT_SUBREG GR32:$src, sub_8bit))>;
1591 def : Pat<(sext_inreg GR16:$src, i8),
1592            (EXTRACT_SUBREG (MOVSX32rr8 (EXTRACT_SUBREG GR16:$src, sub_8bit)),
1593              sub_16bit)>;
1595 def : Pat<(sext_inreg GR64:$src, i32),
1596           (MOVSX64rr32 (EXTRACT_SUBREG GR64:$src, sub_32bit))>;
1597 def : Pat<(sext_inreg GR64:$src, i16),
1598           (MOVSX64rr16 (EXTRACT_SUBREG GR64:$src, sub_16bit))>;
1599 def : Pat<(sext_inreg GR64:$src, i8),
1600           (MOVSX64rr8 (EXTRACT_SUBREG GR64:$src, sub_8bit))>;
1602 // sext, sext_load, zext, zext_load
1603 def: Pat<(i16 (sext GR8:$src)),
1604           (EXTRACT_SUBREG (MOVSX32rr8 GR8:$src), sub_16bit)>;
1605 def: Pat<(sextloadi16i8 addr:$src),
1606           (EXTRACT_SUBREG (MOVSX32rm8 addr:$src), sub_16bit)>;
1607 def: Pat<(i16 (zext GR8:$src)),
1608           (EXTRACT_SUBREG (MOVZX32rr8 GR8:$src), sub_16bit)>;
1609 def: Pat<(zextloadi16i8 addr:$src),
1610           (EXTRACT_SUBREG (MOVZX32rm8 addr:$src), sub_16bit)>;
1612 // trunc patterns
1613 def : Pat<(i16 (trunc GR32:$src)),
1614           (EXTRACT_SUBREG GR32:$src, sub_16bit)>;
1615 def : Pat<(i8 (trunc GR32:$src)),
1616           (EXTRACT_SUBREG (i32 (COPY_TO_REGCLASS GR32:$src, GR32_ABCD)),
1617                           sub_8bit)>,
1618       Requires<[Not64BitMode]>;
1619 def : Pat<(i8 (trunc GR16:$src)),
1620           (EXTRACT_SUBREG (i16 (COPY_TO_REGCLASS GR16:$src, GR16_ABCD)),
1621                           sub_8bit)>,
1622       Requires<[Not64BitMode]>;
1623 def : Pat<(i32 (trunc GR64:$src)),
1624           (EXTRACT_SUBREG GR64:$src, sub_32bit)>;
1625 def : Pat<(i16 (trunc GR64:$src)),
1626           (EXTRACT_SUBREG GR64:$src, sub_16bit)>;
1627 def : Pat<(i8 (trunc GR64:$src)),
1628           (EXTRACT_SUBREG GR64:$src, sub_8bit)>;
1629 def : Pat<(i8 (trunc GR32:$src)),
1630           (EXTRACT_SUBREG GR32:$src, sub_8bit)>,
1631       Requires<[In64BitMode]>;
1632 def : Pat<(i8 (trunc GR16:$src)),
1633           (EXTRACT_SUBREG GR16:$src, sub_8bit)>,
1634       Requires<[In64BitMode]>;
1636 def immff00_ffff  : ImmLeaf<i32, [{
1637   return Imm >= 0xff00 && Imm <= 0xffff;
1638 }]>;
1640 // h-register tricks
1641 def : Pat<(i8 (trunc (srl_su GR16:$src, (i8 8)))),
1642           (EXTRACT_SUBREG GR16:$src, sub_8bit_hi)>,
1643       Requires<[Not64BitMode]>;
1644 def : Pat<(i8 (trunc (srl_su (i32 (anyext GR16:$src)), (i8 8)))),
1645           (EXTRACT_SUBREG GR16:$src, sub_8bit_hi)>,
1646       Requires<[Not64BitMode]>;
1647 def : Pat<(i8 (trunc (srl_su GR32:$src, (i8 8)))),
1648           (EXTRACT_SUBREG GR32:$src, sub_8bit_hi)>,
1649       Requires<[Not64BitMode]>;
1650 def : Pat<(srl GR16:$src, (i8 8)),
1651           (EXTRACT_SUBREG
1652             (MOVZX32rr8_NOREX (EXTRACT_SUBREG GR16:$src, sub_8bit_hi)),
1653             sub_16bit)>;
1654 def : Pat<(i32 (zext (srl_su GR16:$src, (i8 8)))),
1655           (MOVZX32rr8_NOREX (EXTRACT_SUBREG GR16:$src, sub_8bit_hi))>;
1656 def : Pat<(i32 (anyext (srl_su GR16:$src, (i8 8)))),
1657           (MOVZX32rr8_NOREX (EXTRACT_SUBREG GR16:$src, sub_8bit_hi))>;
1658 def : Pat<(and (srl_su GR32:$src, (i8 8)), (i32 255)),
1659           (MOVZX32rr8_NOREX (EXTRACT_SUBREG GR32:$src, sub_8bit_hi))>;
1660 def : Pat<(srl (and_su GR32:$src, immff00_ffff), (i8 8)),
1661           (MOVZX32rr8_NOREX (EXTRACT_SUBREG GR32:$src, sub_8bit_hi))>;
1663 // h-register tricks.
1664 // For now, be conservative on x86-64 and use an h-register extract only if the
1665 // value is immediately zero-extended or stored, which are somewhat common
1666 // cases. This uses a bunch of code to prevent a register requiring a REX prefix
1667 // from being allocated in the same instruction as the h register, as there's
1668 // currently no way to describe this requirement to the register allocator.
1670 // h-register extract and zero-extend.
1671 def : Pat<(and (srl_su GR64:$src, (i8 8)), (i64 255)),
1672           (SUBREG_TO_REG
1673             (i64 0),
1674             (MOVZX32rr8_NOREX
1675               (EXTRACT_SUBREG GR64:$src, sub_8bit_hi)),
1676             sub_32bit)>;
1677 def : Pat<(i64 (zext (srl_su GR16:$src, (i8 8)))),
1678           (SUBREG_TO_REG
1679             (i64 0),
1680             (MOVZX32rr8_NOREX
1681               (EXTRACT_SUBREG GR16:$src, sub_8bit_hi)),
1682             sub_32bit)>;
1683 def : Pat<(i64 (anyext (srl_su GR16:$src, (i8 8)))),
1684           (SUBREG_TO_REG
1685             (i64 0),
1686             (MOVZX32rr8_NOREX
1687               (EXTRACT_SUBREG GR16:$src, sub_8bit_hi)),
1688             sub_32bit)>;
1690 // h-register extract and store.
1691 def : Pat<(store (i8 (trunc_su (srl_su GR64:$src, (i8 8)))), addr:$dst),
1692           (MOV8mr_NOREX
1693             addr:$dst,
1694             (EXTRACT_SUBREG GR64:$src, sub_8bit_hi))>;
1695 def : Pat<(store (i8 (trunc_su (srl_su GR32:$src, (i8 8)))), addr:$dst),
1696           (MOV8mr_NOREX
1697             addr:$dst,
1698             (EXTRACT_SUBREG GR32:$src, sub_8bit_hi))>,
1699       Requires<[In64BitMode]>;
1700 def : Pat<(store (i8 (trunc_su (srl_su GR16:$src, (i8 8)))), addr:$dst),
1701           (MOV8mr_NOREX
1702             addr:$dst,
1703             (EXTRACT_SUBREG GR16:$src, sub_8bit_hi))>,
1704       Requires<[In64BitMode]>;
1707 // (shl x, 1) ==> (add x, x)
1708 // Note that if x is undef (immediate or otherwise), we could theoretically
1709 // end up with the two uses of x getting different values, producing a result
1710 // where the least significant bit is not 0. However, the probability of this
1711 // happening is considered low enough that this is officially not a
1712 // "real problem".
1713 def : Pat<(shl GR8 :$src1, (i8 1)), (ADD8rr  GR8 :$src1, GR8 :$src1)>;
1714 def : Pat<(shl GR16:$src1, (i8 1)), (ADD16rr GR16:$src1, GR16:$src1)>;
1715 def : Pat<(shl GR32:$src1, (i8 1)), (ADD32rr GR32:$src1, GR32:$src1)>;
1716 def : Pat<(shl GR64:$src1, (i8 1)), (ADD64rr GR64:$src1, GR64:$src1)>;
1718 // Helper imms to check if a mask doesn't change significant shift/rotate bits.
1719 def immShift8 : ImmLeaf<i8, [{
1720   return countTrailingOnes<uint64_t>(Imm) >= 3;
1721 }]>;
1722 def immShift16 : ImmLeaf<i8, [{
1723   return countTrailingOnes<uint64_t>(Imm) >= 4;
1724 }]>;
1725 def immShift32 : ImmLeaf<i8, [{
1726   return countTrailingOnes<uint64_t>(Imm) >= 5;
1727 }]>;
1728 def immShift64 : ImmLeaf<i8, [{
1729   return countTrailingOnes<uint64_t>(Imm) >= 6;
1730 }]>;
1732 // Shift amount is implicitly masked.
1733 multiclass MaskedShiftAmountPats<SDNode frag, string name> {
1734   // (shift x (and y, 31)) ==> (shift x, y)
1735   def : Pat<(frag GR8:$src1, (and CL, immShift32)),
1736             (!cast<Instruction>(name # "8rCL") GR8:$src1)>;
1737   def : Pat<(frag GR16:$src1, (and CL, immShift32)),
1738             (!cast<Instruction>(name # "16rCL") GR16:$src1)>;
1739   def : Pat<(frag GR32:$src1, (and CL, immShift32)),
1740             (!cast<Instruction>(name # "32rCL") GR32:$src1)>;
1741   def : Pat<(store (frag (loadi8 addr:$dst), (and CL, immShift32)), addr:$dst),
1742             (!cast<Instruction>(name # "8mCL") addr:$dst)>;
1743   def : Pat<(store (frag (loadi16 addr:$dst), (and CL, immShift32)), addr:$dst),
1744             (!cast<Instruction>(name # "16mCL") addr:$dst)>;
1745   def : Pat<(store (frag (loadi32 addr:$dst), (and CL, immShift32)), addr:$dst),
1746             (!cast<Instruction>(name # "32mCL") addr:$dst)>;
1748   // (shift x (and y, 63)) ==> (shift x, y)
1749   def : Pat<(frag GR64:$src1, (and CL, immShift64)),
1750             (!cast<Instruction>(name # "64rCL") GR64:$src1)>;
1751   def : Pat<(store (frag (loadi64 addr:$dst), (and CL, immShift64)), addr:$dst),
1752             (!cast<Instruction>(name # "64mCL") addr:$dst)>;
1755 defm : MaskedShiftAmountPats<shl, "SHL">;
1756 defm : MaskedShiftAmountPats<srl, "SHR">;
1757 defm : MaskedShiftAmountPats<sra, "SAR">;
1759 // ROL/ROR instructions allow a stronger mask optimization than shift for 8- and
1760 // 16-bit. We can remove a mask of any (bitwidth - 1) on the rotation amount
1761 // because over-rotating produces the same result. This is noted in the Intel
1762 // docs with: "tempCOUNT <- (COUNT & COUNTMASK) MOD SIZE". Masking the rotation
1763 // amount could affect EFLAGS results, but that does not matter because we are
1764 // not tracking flags for these nodes.
1765 multiclass MaskedRotateAmountPats<SDNode frag, string name> {
1766   // (rot x (and y, BitWidth - 1)) ==> (rot x, y)
1767   def : Pat<(frag GR8:$src1, (and CL, immShift8)),
1768   (!cast<Instruction>(name # "8rCL") GR8:$src1)>;
1769   def : Pat<(frag GR16:$src1, (and CL, immShift16)),
1770   (!cast<Instruction>(name # "16rCL") GR16:$src1)>;
1771   def : Pat<(frag GR32:$src1, (and CL, immShift32)),
1772   (!cast<Instruction>(name # "32rCL") GR32:$src1)>;
1773   def : Pat<(store (frag (loadi8 addr:$dst), (and CL, immShift8)), addr:$dst),
1774   (!cast<Instruction>(name # "8mCL") addr:$dst)>;
1775   def : Pat<(store (frag (loadi16 addr:$dst), (and CL, immShift16)), addr:$dst),
1776   (!cast<Instruction>(name # "16mCL") addr:$dst)>;
1777   def : Pat<(store (frag (loadi32 addr:$dst), (and CL, immShift32)), addr:$dst),
1778   (!cast<Instruction>(name # "32mCL") addr:$dst)>;
1780   // (rot x (and y, 63)) ==> (rot x, y)
1781   def : Pat<(frag GR64:$src1, (and CL, immShift64)),
1782   (!cast<Instruction>(name # "64rCL") GR64:$src1)>;
1783   def : Pat<(store (frag (loadi64 addr:$dst), (and CL, immShift64)), addr:$dst),
1784   (!cast<Instruction>(name # "64mCL") addr:$dst)>;
1788 defm : MaskedRotateAmountPats<rotl, "ROL">;
1789 defm : MaskedRotateAmountPats<rotr, "ROR">;
1791 // Double shift amount is implicitly masked.
1792 multiclass MaskedDoubleShiftAmountPats<SDNode frag, string name> {
1793   // (shift x (and y, 31)) ==> (shift x, y)
1794   def : Pat<(frag GR16:$src1, GR16:$src2, (and CL, immShift32)),
1795             (!cast<Instruction>(name # "16rrCL") GR16:$src1, GR16:$src2)>;
1796   def : Pat<(frag GR32:$src1, GR32:$src2, (and CL, immShift32)),
1797             (!cast<Instruction>(name # "32rrCL") GR32:$src1, GR32:$src2)>;
1799   // (shift x (and y, 63)) ==> (shift x, y)
1800   def : Pat<(frag GR64:$src1, GR64:$src2, (and CL, immShift64)),
1801             (!cast<Instruction>(name # "64rrCL") GR64:$src1, GR64:$src2)>;
1804 defm : MaskedDoubleShiftAmountPats<X86shld, "SHLD">;
1805 defm : MaskedDoubleShiftAmountPats<X86shrd, "SHRD">;
1807 let Predicates = [HasBMI2] in {
1808   let AddedComplexity = 1 in {
1809     def : Pat<(sra GR32:$src1, (and GR8:$src2, immShift32)),
1810               (SARX32rr GR32:$src1,
1811                         (INSERT_SUBREG
1812                           (i32 (IMPLICIT_DEF)), GR8:$src2, sub_8bit))>;
1813     def : Pat<(sra GR64:$src1, (and GR8:$src2, immShift64)),
1814               (SARX64rr GR64:$src1,
1815                         (INSERT_SUBREG
1816                           (i64 (IMPLICIT_DEF)), GR8:$src2, sub_8bit))>;
1818     def : Pat<(srl GR32:$src1, (and GR8:$src2, immShift32)),
1819               (SHRX32rr GR32:$src1,
1820                         (INSERT_SUBREG
1821                           (i32 (IMPLICIT_DEF)), GR8:$src2, sub_8bit))>;
1822     def : Pat<(srl GR64:$src1, (and GR8:$src2, immShift64)),
1823               (SHRX64rr GR64:$src1,
1824                         (INSERT_SUBREG
1825                           (i64 (IMPLICIT_DEF)), GR8:$src2, sub_8bit))>;
1827     def : Pat<(shl GR32:$src1, (and GR8:$src2, immShift32)),
1828               (SHLX32rr GR32:$src1,
1829                         (INSERT_SUBREG
1830                           (i32 (IMPLICIT_DEF)), GR8:$src2, sub_8bit))>;
1831     def : Pat<(shl GR64:$src1, (and GR8:$src2, immShift64)),
1832               (SHLX64rr GR64:$src1,
1833                         (INSERT_SUBREG
1834                           (i64 (IMPLICIT_DEF)), GR8:$src2, sub_8bit))>;
1835   }
1837   def : Pat<(sra (loadi32 addr:$src1), (and GR8:$src2, immShift32)),
1838             (SARX32rm addr:$src1,
1839                       (INSERT_SUBREG
1840                         (i32 (IMPLICIT_DEF)), GR8:$src2, sub_8bit))>;
1841   def : Pat<(sra (loadi64 addr:$src1), (and GR8:$src2, immShift64)),
1842             (SARX64rm addr:$src1,
1843                       (INSERT_SUBREG
1844                         (i64 (IMPLICIT_DEF)), GR8:$src2, sub_8bit))>;
1846   def : Pat<(srl (loadi32 addr:$src1), (and GR8:$src2, immShift32)),
1847             (SHRX32rm addr:$src1,
1848                       (INSERT_SUBREG
1849                         (i32 (IMPLICIT_DEF)), GR8:$src2, sub_8bit))>;
1850   def : Pat<(srl (loadi64 addr:$src1), (and GR8:$src2, immShift64)),
1851             (SHRX64rm addr:$src1,
1852                       (INSERT_SUBREG
1853                         (i64 (IMPLICIT_DEF)), GR8:$src2, sub_8bit))>;
1855   def : Pat<(shl (loadi32 addr:$src1), (and GR8:$src2, immShift32)),
1856             (SHLX32rm addr:$src1,
1857                       (INSERT_SUBREG
1858                         (i32 (IMPLICIT_DEF)), GR8:$src2, sub_8bit))>;
1859   def : Pat<(shl (loadi64 addr:$src1), (and GR8:$src2, immShift64)),
1860             (SHLX64rm addr:$src1,
1861                       (INSERT_SUBREG
1862                         (i64 (IMPLICIT_DEF)), GR8:$src2, sub_8bit))>;
1865 // Use BTR/BTS/BTC for clearing/setting/toggling a bit in a variable location.
1866 multiclass one_bit_patterns<RegisterClass RC, ValueType VT, Instruction BTR,
1867                             Instruction BTS, Instruction BTC,
1868                             ImmLeaf ImmShift> {
1869   def : Pat<(and RC:$src1, (rotl -2, GR8:$src2)),
1870             (BTR RC:$src1,
1871                  (INSERT_SUBREG (VT (IMPLICIT_DEF)), GR8:$src2, sub_8bit))>;
1872   def : Pat<(or RC:$src1, (shl 1, GR8:$src2)),
1873             (BTS RC:$src1,
1874                  (INSERT_SUBREG (VT (IMPLICIT_DEF)), GR8:$src2, sub_8bit))>;
1875   def : Pat<(xor RC:$src1, (shl 1, GR8:$src2)),
1876             (BTC RC:$src1,
1877                  (INSERT_SUBREG (VT (IMPLICIT_DEF)), GR8:$src2, sub_8bit))>;
1879   // Similar to above, but removing unneeded masking of the shift amount.
1880   def : Pat<(and RC:$src1, (rotl -2, (and GR8:$src2, ImmShift))),
1881             (BTR RC:$src1,
1882                  (INSERT_SUBREG (VT (IMPLICIT_DEF)), GR8:$src2, sub_8bit))>;
1883   def : Pat<(or RC:$src1, (shl 1, (and GR8:$src2, ImmShift))),
1884             (BTS RC:$src1,
1885                 (INSERT_SUBREG (VT (IMPLICIT_DEF)), GR8:$src2, sub_8bit))>;
1886   def : Pat<(xor RC:$src1, (shl 1, (and GR8:$src2, ImmShift))),
1887             (BTC RC:$src1,
1888                 (INSERT_SUBREG (VT (IMPLICIT_DEF)), GR8:$src2, sub_8bit))>;
1891 defm : one_bit_patterns<GR16, i16, BTR16rr, BTS16rr, BTC16rr, immShift16>;
1892 defm : one_bit_patterns<GR32, i32, BTR32rr, BTS32rr, BTC32rr, immShift32>;
1893 defm : one_bit_patterns<GR64, i64, BTR64rr, BTS64rr, BTC64rr, immShift64>;
1896 // (anyext (setcc_carry)) -> (setcc_carry)
1897 def : Pat<(i16 (anyext (i8 (X86setcc_c X86_COND_B, EFLAGS)))),
1898           (SETB_C16r)>;
1899 def : Pat<(i32 (anyext (i8 (X86setcc_c X86_COND_B, EFLAGS)))),
1900           (SETB_C32r)>;
1901 def : Pat<(i32 (anyext (i16 (X86setcc_c X86_COND_B, EFLAGS)))),
1902           (SETB_C32r)>;
1904 //===----------------------------------------------------------------------===//
1905 // EFLAGS-defining Patterns
1906 //===----------------------------------------------------------------------===//
1908 // add reg, reg
1909 def : Pat<(add GR8 :$src1, GR8 :$src2), (ADD8rr  GR8 :$src1, GR8 :$src2)>;
1910 def : Pat<(add GR16:$src1, GR16:$src2), (ADD16rr GR16:$src1, GR16:$src2)>;
1911 def : Pat<(add GR32:$src1, GR32:$src2), (ADD32rr GR32:$src1, GR32:$src2)>;
1912 def : Pat<(add GR64:$src1, GR64:$src2), (ADD64rr GR64:$src1, GR64:$src2)>;
1914 // add reg, mem
1915 def : Pat<(add GR8:$src1, (loadi8 addr:$src2)),
1916           (ADD8rm GR8:$src1, addr:$src2)>;
1917 def : Pat<(add GR16:$src1, (loadi16 addr:$src2)),
1918           (ADD16rm GR16:$src1, addr:$src2)>;
1919 def : Pat<(add GR32:$src1, (loadi32 addr:$src2)),
1920           (ADD32rm GR32:$src1, addr:$src2)>;
1921 def : Pat<(add GR64:$src1, (loadi64 addr:$src2)),
1922           (ADD64rm GR64:$src1, addr:$src2)>;
1924 // add reg, imm
1925 def : Pat<(add GR8 :$src1, imm:$src2), (ADD8ri  GR8:$src1 , imm:$src2)>;
1926 def : Pat<(add GR16:$src1, imm:$src2), (ADD16ri GR16:$src1, imm:$src2)>;
1927 def : Pat<(add GR32:$src1, imm:$src2), (ADD32ri GR32:$src1, imm:$src2)>;
1928 def : Pat<(add GR16:$src1, i16immSExt8:$src2),
1929           (ADD16ri8 GR16:$src1, i16immSExt8:$src2)>;
1930 def : Pat<(add GR32:$src1, i32immSExt8:$src2),
1931           (ADD32ri8 GR32:$src1, i32immSExt8:$src2)>;
1932 def : Pat<(add GR64:$src1, i64immSExt8:$src2),
1933           (ADD64ri8 GR64:$src1, i64immSExt8:$src2)>;
1934 def : Pat<(add GR64:$src1, i64immSExt32:$src2),
1935           (ADD64ri32 GR64:$src1, i64immSExt32:$src2)>;
1937 // sub reg, reg
1938 def : Pat<(sub GR8 :$src1, GR8 :$src2), (SUB8rr  GR8 :$src1, GR8 :$src2)>;
1939 def : Pat<(sub GR16:$src1, GR16:$src2), (SUB16rr GR16:$src1, GR16:$src2)>;
1940 def : Pat<(sub GR32:$src1, GR32:$src2), (SUB32rr GR32:$src1, GR32:$src2)>;
1941 def : Pat<(sub GR64:$src1, GR64:$src2), (SUB64rr GR64:$src1, GR64:$src2)>;
1943 // sub reg, mem
1944 def : Pat<(sub GR8:$src1, (loadi8 addr:$src2)),
1945           (SUB8rm GR8:$src1, addr:$src2)>;
1946 def : Pat<(sub GR16:$src1, (loadi16 addr:$src2)),
1947           (SUB16rm GR16:$src1, addr:$src2)>;
1948 def : Pat<(sub GR32:$src1, (loadi32 addr:$src2)),
1949           (SUB32rm GR32:$src1, addr:$src2)>;
1950 def : Pat<(sub GR64:$src1, (loadi64 addr:$src2)),
1951           (SUB64rm GR64:$src1, addr:$src2)>;
1953 // sub reg, imm
1954 def : Pat<(sub GR8:$src1, imm:$src2),
1955           (SUB8ri GR8:$src1, imm:$src2)>;
1956 def : Pat<(sub GR16:$src1, imm:$src2),
1957           (SUB16ri GR16:$src1, imm:$src2)>;
1958 def : Pat<(sub GR32:$src1, imm:$src2),
1959           (SUB32ri GR32:$src1, imm:$src2)>;
1960 def : Pat<(sub GR16:$src1, i16immSExt8:$src2),
1961           (SUB16ri8 GR16:$src1, i16immSExt8:$src2)>;
1962 def : Pat<(sub GR32:$src1, i32immSExt8:$src2),
1963           (SUB32ri8 GR32:$src1, i32immSExt8:$src2)>;
1964 def : Pat<(sub GR64:$src1, i64immSExt8:$src2),
1965           (SUB64ri8 GR64:$src1, i64immSExt8:$src2)>;
1966 def : Pat<(sub GR64:$src1, i64immSExt32:$src2),
1967           (SUB64ri32 GR64:$src1, i64immSExt32:$src2)>;
1969 // sub 0, reg
1970 def : Pat<(X86sub_flag 0, GR8 :$src), (NEG8r  GR8 :$src)>;
1971 def : Pat<(X86sub_flag 0, GR16:$src), (NEG16r GR16:$src)>;
1972 def : Pat<(X86sub_flag 0, GR32:$src), (NEG32r GR32:$src)>;
1973 def : Pat<(X86sub_flag 0, GR64:$src), (NEG64r GR64:$src)>;
1975 // sub reg, relocImm
1976 def : Pat<(X86sub_flag GR64:$src1, i64relocImmSExt8_su:$src2),
1977           (SUB64ri8 GR64:$src1, i64relocImmSExt8_su:$src2)>;
1978 def : Pat<(X86sub_flag GR64:$src1, i64relocImmSExt32_su:$src2),
1979           (SUB64ri32 GR64:$src1, i64relocImmSExt32_su:$src2)>;
1981 // mul reg, reg
1982 def : Pat<(mul GR16:$src1, GR16:$src2),
1983           (IMUL16rr GR16:$src1, GR16:$src2)>;
1984 def : Pat<(mul GR32:$src1, GR32:$src2),
1985           (IMUL32rr GR32:$src1, GR32:$src2)>;
1986 def : Pat<(mul GR64:$src1, GR64:$src2),
1987           (IMUL64rr GR64:$src1, GR64:$src2)>;
1989 // mul reg, mem
1990 def : Pat<(mul GR16:$src1, (loadi16 addr:$src2)),
1991           (IMUL16rm GR16:$src1, addr:$src2)>;
1992 def : Pat<(mul GR32:$src1, (loadi32 addr:$src2)),
1993           (IMUL32rm GR32:$src1, addr:$src2)>;
1994 def : Pat<(mul GR64:$src1, (loadi64 addr:$src2)),
1995           (IMUL64rm GR64:$src1, addr:$src2)>;
1997 // mul reg, imm
1998 def : Pat<(mul GR16:$src1, imm:$src2),
1999           (IMUL16rri GR16:$src1, imm:$src2)>;
2000 def : Pat<(mul GR32:$src1, imm:$src2),
2001           (IMUL32rri GR32:$src1, imm:$src2)>;
2002 def : Pat<(mul GR16:$src1, i16immSExt8:$src2),
2003           (IMUL16rri8 GR16:$src1, i16immSExt8:$src2)>;
2004 def : Pat<(mul GR32:$src1, i32immSExt8:$src2),
2005           (IMUL32rri8 GR32:$src1, i32immSExt8:$src2)>;
2006 def : Pat<(mul GR64:$src1, i64immSExt8:$src2),
2007           (IMUL64rri8 GR64:$src1, i64immSExt8:$src2)>;
2008 def : Pat<(mul GR64:$src1, i64immSExt32:$src2),
2009           (IMUL64rri32 GR64:$src1, i64immSExt32:$src2)>;
2011 // reg = mul mem, imm
2012 def : Pat<(mul (loadi16 addr:$src1), imm:$src2),
2013           (IMUL16rmi addr:$src1, imm:$src2)>;
2014 def : Pat<(mul (loadi32 addr:$src1), imm:$src2),
2015           (IMUL32rmi addr:$src1, imm:$src2)>;
2016 def : Pat<(mul (loadi16 addr:$src1), i16immSExt8:$src2),
2017           (IMUL16rmi8 addr:$src1, i16immSExt8:$src2)>;
2018 def : Pat<(mul (loadi32 addr:$src1), i32immSExt8:$src2),
2019           (IMUL32rmi8 addr:$src1, i32immSExt8:$src2)>;
2020 def : Pat<(mul (loadi64 addr:$src1), i64immSExt8:$src2),
2021           (IMUL64rmi8 addr:$src1, i64immSExt8:$src2)>;
2022 def : Pat<(mul (loadi64 addr:$src1), i64immSExt32:$src2),
2023           (IMUL64rmi32 addr:$src1, i64immSExt32:$src2)>;
2025 // Increment/Decrement reg.
2026 // Do not make INC/DEC if it is slow
2027 let Predicates = [UseIncDec] in {
2028   def : Pat<(add GR8:$src, 1),   (INC8r GR8:$src)>;
2029   def : Pat<(add GR16:$src, 1),  (INC16r GR16:$src)>;
2030   def : Pat<(add GR32:$src, 1),  (INC32r GR32:$src)>;
2031   def : Pat<(add GR64:$src, 1),  (INC64r GR64:$src)>;
2032   def : Pat<(add GR8:$src, -1),  (DEC8r GR8:$src)>;
2033   def : Pat<(add GR16:$src, -1), (DEC16r GR16:$src)>;
2034   def : Pat<(add GR32:$src, -1), (DEC32r GR32:$src)>;
2035   def : Pat<(add GR64:$src, -1), (DEC64r GR64:$src)>;
2037   def : Pat<(X86add_flag_nocf GR8:$src, -1),  (DEC8r GR8:$src)>;
2038   def : Pat<(X86add_flag_nocf GR16:$src, -1), (DEC16r GR16:$src)>;
2039   def : Pat<(X86add_flag_nocf GR32:$src, -1), (DEC32r GR32:$src)>;
2040   def : Pat<(X86add_flag_nocf GR64:$src, -1), (DEC64r GR64:$src)>;
2041   def : Pat<(X86sub_flag_nocf GR8:$src, -1),  (INC8r GR8:$src)>;
2042   def : Pat<(X86sub_flag_nocf GR16:$src, -1), (INC16r GR16:$src)>;
2043   def : Pat<(X86sub_flag_nocf GR32:$src, -1), (INC32r GR32:$src)>;
2044   def : Pat<(X86sub_flag_nocf GR64:$src, -1), (INC64r GR64:$src)>;
2047 // or reg/reg.
2048 def : Pat<(or GR8 :$src1, GR8 :$src2), (OR8rr  GR8 :$src1, GR8 :$src2)>;
2049 def : Pat<(or GR16:$src1, GR16:$src2), (OR16rr GR16:$src1, GR16:$src2)>;
2050 def : Pat<(or GR32:$src1, GR32:$src2), (OR32rr GR32:$src1, GR32:$src2)>;
2051 def : Pat<(or GR64:$src1, GR64:$src2), (OR64rr GR64:$src1, GR64:$src2)>;
2053 // or reg/mem
2054 def : Pat<(or GR8:$src1, (loadi8 addr:$src2)),
2055           (OR8rm GR8:$src1, addr:$src2)>;
2056 def : Pat<(or GR16:$src1, (loadi16 addr:$src2)),
2057           (OR16rm GR16:$src1, addr:$src2)>;
2058 def : Pat<(or GR32:$src1, (loadi32 addr:$src2)),
2059           (OR32rm GR32:$src1, addr:$src2)>;
2060 def : Pat<(or GR64:$src1, (loadi64 addr:$src2)),
2061           (OR64rm GR64:$src1, addr:$src2)>;
2063 // or reg/imm
2064 def : Pat<(or GR8:$src1 , imm:$src2), (OR8ri  GR8 :$src1, imm:$src2)>;
2065 def : Pat<(or GR16:$src1, imm:$src2), (OR16ri GR16:$src1, imm:$src2)>;
2066 def : Pat<(or GR32:$src1, imm:$src2), (OR32ri GR32:$src1, imm:$src2)>;
2067 def : Pat<(or GR16:$src1, i16immSExt8:$src2),
2068           (OR16ri8 GR16:$src1, i16immSExt8:$src2)>;
2069 def : Pat<(or GR32:$src1, i32immSExt8:$src2),
2070           (OR32ri8 GR32:$src1, i32immSExt8:$src2)>;
2071 def : Pat<(or GR64:$src1, i64immSExt8:$src2),
2072           (OR64ri8 GR64:$src1, i64immSExt8:$src2)>;
2073 def : Pat<(or GR64:$src1, i64immSExt32:$src2),
2074           (OR64ri32 GR64:$src1, i64immSExt32:$src2)>;
2076 // xor reg/reg
2077 def : Pat<(xor GR8 :$src1, GR8 :$src2), (XOR8rr  GR8 :$src1, GR8 :$src2)>;
2078 def : Pat<(xor GR16:$src1, GR16:$src2), (XOR16rr GR16:$src1, GR16:$src2)>;
2079 def : Pat<(xor GR32:$src1, GR32:$src2), (XOR32rr GR32:$src1, GR32:$src2)>;
2080 def : Pat<(xor GR64:$src1, GR64:$src2), (XOR64rr GR64:$src1, GR64:$src2)>;
2082 // xor reg/mem
2083 def : Pat<(xor GR8:$src1, (loadi8 addr:$src2)),
2084           (XOR8rm GR8:$src1, addr:$src2)>;
2085 def : Pat<(xor GR16:$src1, (loadi16 addr:$src2)),
2086           (XOR16rm GR16:$src1, addr:$src2)>;
2087 def : Pat<(xor GR32:$src1, (loadi32 addr:$src2)),
2088           (XOR32rm GR32:$src1, addr:$src2)>;
2089 def : Pat<(xor GR64:$src1, (loadi64 addr:$src2)),
2090           (XOR64rm GR64:$src1, addr:$src2)>;
2092 // xor reg/imm
2093 def : Pat<(xor GR8:$src1, imm:$src2),
2094           (XOR8ri GR8:$src1, imm:$src2)>;
2095 def : Pat<(xor GR16:$src1, imm:$src2),
2096           (XOR16ri GR16:$src1, imm:$src2)>;
2097 def : Pat<(xor GR32:$src1, imm:$src2),
2098           (XOR32ri GR32:$src1, imm:$src2)>;
2099 def : Pat<(xor GR16:$src1, i16immSExt8:$src2),
2100           (XOR16ri8 GR16:$src1, i16immSExt8:$src2)>;
2101 def : Pat<(xor GR32:$src1, i32immSExt8:$src2),
2102           (XOR32ri8 GR32:$src1, i32immSExt8:$src2)>;
2103 def : Pat<(xor GR64:$src1, i64immSExt8:$src2),
2104           (XOR64ri8 GR64:$src1, i64immSExt8:$src2)>;
2105 def : Pat<(xor GR64:$src1, i64immSExt32:$src2),
2106           (XOR64ri32 GR64:$src1, i64immSExt32:$src2)>;
2108 // and reg/reg
2109 def : Pat<(and GR8 :$src1, GR8 :$src2), (AND8rr  GR8 :$src1, GR8 :$src2)>;
2110 def : Pat<(and GR16:$src1, GR16:$src2), (AND16rr GR16:$src1, GR16:$src2)>;
2111 def : Pat<(and GR32:$src1, GR32:$src2), (AND32rr GR32:$src1, GR32:$src2)>;
2112 def : Pat<(and GR64:$src1, GR64:$src2), (AND64rr GR64:$src1, GR64:$src2)>;
2114 // and reg/mem
2115 def : Pat<(and GR8:$src1, (loadi8 addr:$src2)),
2116           (AND8rm GR8:$src1, addr:$src2)>;
2117 def : Pat<(and GR16:$src1, (loadi16 addr:$src2)),
2118           (AND16rm GR16:$src1, addr:$src2)>;
2119 def : Pat<(and GR32:$src1, (loadi32 addr:$src2)),
2120           (AND32rm GR32:$src1, addr:$src2)>;
2121 def : Pat<(and GR64:$src1, (loadi64 addr:$src2)),
2122           (AND64rm GR64:$src1, addr:$src2)>;
2124 // and reg/imm
2125 def : Pat<(and GR8:$src1, imm:$src2),
2126           (AND8ri GR8:$src1, imm:$src2)>;
2127 def : Pat<(and GR16:$src1, imm:$src2),
2128           (AND16ri GR16:$src1, imm:$src2)>;
2129 def : Pat<(and GR32:$src1, imm:$src2),
2130           (AND32ri GR32:$src1, imm:$src2)>;
2131 def : Pat<(and GR16:$src1, i16immSExt8:$src2),
2132           (AND16ri8 GR16:$src1, i16immSExt8:$src2)>;
2133 def : Pat<(and GR32:$src1, i32immSExt8:$src2),
2134           (AND32ri8 GR32:$src1, i32immSExt8:$src2)>;
2135 def : Pat<(and GR64:$src1, i64immSExt8:$src2),
2136           (AND64ri8 GR64:$src1, i64immSExt8:$src2)>;
2137 def : Pat<(and GR64:$src1, i64immSExt32:$src2),
2138           (AND64ri32 GR64:$src1, i64immSExt32:$src2)>;
2140 // Bit scan instruction patterns to match explicit zero-undef behavior.
2141 def : Pat<(cttz_zero_undef GR16:$src), (BSF16rr GR16:$src)>;
2142 def : Pat<(cttz_zero_undef GR32:$src), (BSF32rr GR32:$src)>;
2143 def : Pat<(cttz_zero_undef GR64:$src), (BSF64rr GR64:$src)>;
2144 def : Pat<(cttz_zero_undef (loadi16 addr:$src)), (BSF16rm addr:$src)>;
2145 def : Pat<(cttz_zero_undef (loadi32 addr:$src)), (BSF32rm addr:$src)>;
2146 def : Pat<(cttz_zero_undef (loadi64 addr:$src)), (BSF64rm addr:$src)>;
2148 // When HasMOVBE is enabled it is possible to get a non-legalized
2149 // register-register 16 bit bswap. This maps it to a ROL instruction.
2150 let Predicates = [HasMOVBE] in {
2151  def : Pat<(bswap GR16:$src), (ROL16ri GR16:$src, (i8 8))>;