OSDN Git Service

foo
[android-x86/external-llvm.git] / lib / Target / X86 / X86InstrSSE.td
1 //===-- X86InstrSSE.td - SSE Instruction Set ---------------*- tablegen -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file describes the X86 SSE instruction set, defining the instructions,
11 // and properties of the instructions which are needed for code generation,
12 // machine code emission, and analysis.
13 //
14 //===----------------------------------------------------------------------===//
15
16 //===----------------------------------------------------------------------===//
17 // SSE 1 & 2 Instructions Classes
18 //===----------------------------------------------------------------------===//
19
20 /// sse12_fp_scalar - SSE 1 & 2 scalar instructions class
21 multiclass sse12_fp_scalar<bits<8> opc, string OpcodeStr, SDNode OpNode,
22                            RegisterClass RC, X86MemOperand x86memop,
23                            Domain d, X86FoldableSchedWrite sched,
24                            bit Is2Addr = 1> {
25   let isCommutable = 1 in {
26     def rr : SI<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
27        !if(Is2Addr,
28            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
29            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
30        [(set RC:$dst, (OpNode RC:$src1, RC:$src2))], d>,
31        Sched<[sched]>;
32   }
33   def rm : SI<opc, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
34        !if(Is2Addr,
35            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
36            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
37        [(set RC:$dst, (OpNode RC:$src1, (load addr:$src2)))], d>,
38        Sched<[sched.Folded, ReadAfterLd]>;
39 }
40
41 /// sse12_fp_scalar_int - SSE 1 & 2 scalar instructions intrinsics class
42 multiclass sse12_fp_scalar_int<bits<8> opc, string OpcodeStr,
43                                SDPatternOperator OpNode, RegisterClass RC,
44                                ValueType VT, string asm, Operand memopr,
45                                ComplexPattern mem_cpat, Domain d,
46                                X86FoldableSchedWrite sched, bit Is2Addr = 1> {
47 let isCodeGenOnly = 1, hasSideEffects = 0 in {
48   def rr_Int : SI_Int<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
49        !if(Is2Addr,
50            !strconcat(asm, "\t{$src2, $dst|$dst, $src2}"),
51            !strconcat(asm, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
52        [(set RC:$dst, (VT (OpNode RC:$src1, RC:$src2)))], d>,
53        Sched<[sched]>;
54   let mayLoad = 1 in
55   def rm_Int : SI_Int<opc, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, memopr:$src2),
56        !if(Is2Addr,
57            !strconcat(asm, "\t{$src2, $dst|$dst, $src2}"),
58            !strconcat(asm, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
59        [(set RC:$dst, (VT (OpNode RC:$src1, mem_cpat:$src2)))], d>,
60        Sched<[sched.Folded, ReadAfterLd]>;
61 }
62 }
63
64 /// sse12_fp_packed - SSE 1 & 2 packed instructions class
65 multiclass sse12_fp_packed<bits<8> opc, string OpcodeStr, SDNode OpNode,
66                            RegisterClass RC, ValueType vt,
67                            X86MemOperand x86memop, PatFrag mem_frag,
68                            Domain d, X86FoldableSchedWrite sched,
69                            bit Is2Addr = 1> {
70   let isCommutable = 1 in
71     def rr : PI<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
72        !if(Is2Addr,
73            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
74            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
75        [(set RC:$dst, (vt (OpNode RC:$src1, RC:$src2)))], d>,
76        Sched<[sched]>;
77   let mayLoad = 1 in
78     def rm : PI<opc, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
79        !if(Is2Addr,
80            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
81            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
82        [(set RC:$dst, (OpNode RC:$src1, (mem_frag addr:$src2)))],
83           d>,
84        Sched<[sched.Folded, ReadAfterLd]>;
85 }
86
87 /// sse12_fp_packed_logical_rm - SSE 1 & 2 packed instructions class
88 multiclass sse12_fp_packed_logical_rm<bits<8> opc, RegisterClass RC, Domain d,
89                                       string OpcodeStr, X86MemOperand x86memop,
90                                       X86FoldableSchedWrite sched,
91                                       list<dag> pat_rr, list<dag> pat_rm,
92                                       bit Is2Addr = 1> {
93   let isCommutable = 1, hasSideEffects = 0 in
94     def rr : PI<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
95        !if(Is2Addr,
96            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
97            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
98        pat_rr, d>,
99        Sched<[sched]>;
100   let hasSideEffects = 0, mayLoad = 1 in
101   def rm : PI<opc, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
102        !if(Is2Addr,
103            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
104            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
105        pat_rm, d>,
106        Sched<[sched.Folded, ReadAfterLd]>;
107 }
108
109
110 // Alias instructions that map fld0 to xorps for sse or vxorps for avx.
111 // This is expanded by ExpandPostRAPseudos.
112 let isReMaterializable = 1, isAsCheapAsAMove = 1, canFoldAsLoad = 1,
113     isPseudo = 1, SchedRW = [WriteZero] in {
114   def FsFLD0SS : I<0, Pseudo, (outs FR32:$dst), (ins), "",
115                    [(set FR32:$dst, fp32imm0)]>, Requires<[HasSSE1, NoAVX512]>;
116   def FsFLD0SD : I<0, Pseudo, (outs FR64:$dst), (ins), "",
117                    [(set FR64:$dst, fpimm0)]>, Requires<[HasSSE2, NoAVX512]>;
118 }
119
120 //===----------------------------------------------------------------------===//
121 // AVX & SSE - Zero/One Vectors
122 //===----------------------------------------------------------------------===//
123
124 // Alias instruction that maps zero vector to pxor / xorp* for sse.
125 // This is expanded by ExpandPostRAPseudos to an xorps / vxorps, and then
126 // swizzled by ExecutionDomainFix to pxor.
127 // We set canFoldAsLoad because this can be converted to a constant-pool
128 // load of an all-zeros value if folding it would be beneficial.
129 let isReMaterializable = 1, isAsCheapAsAMove = 1, canFoldAsLoad = 1,
130     isPseudo = 1, SchedRW = [WriteZero] in {
131 def V_SET0 : I<0, Pseudo, (outs VR128:$dst), (ins), "",
132                [(set VR128:$dst, (v4f32 immAllZerosV))]>;
133 }
134
135 let Predicates = [NoAVX512] in
136 def : Pat<(v4i32 immAllZerosV), (V_SET0)>;
137
138
139 // The same as done above but for AVX.  The 256-bit AVX1 ISA doesn't support PI,
140 // and doesn't need it because on sandy bridge the register is set to zero
141 // at the rename stage without using any execution unit, so SET0PSY
142 // and SET0PDY can be used for vector int instructions without penalty
143 let isReMaterializable = 1, isAsCheapAsAMove = 1, canFoldAsLoad = 1,
144     isPseudo = 1, Predicates = [NoAVX512], SchedRW = [WriteZero] in {
145 def AVX_SET0 : I<0, Pseudo, (outs VR256:$dst), (ins), "",
146                  [(set VR256:$dst, (v8i32 immAllZerosV))]>;
147 }
148
149 // We set canFoldAsLoad because this can be converted to a constant-pool
150 // load of an all-ones value if folding it would be beneficial.
151 let isReMaterializable = 1, isAsCheapAsAMove = 1, canFoldAsLoad = 1,
152     isPseudo = 1, SchedRW = [WriteZero] in {
153   def V_SETALLONES : I<0, Pseudo, (outs VR128:$dst), (ins), "",
154                        [(set VR128:$dst, (v4i32 immAllOnesV))]>;
155   let Predicates = [HasAVX1Only, OptForMinSize] in {
156   def AVX1_SETALLONES: I<0, Pseudo, (outs VR256:$dst), (ins), "",
157                           [(set VR256:$dst, (v8i32 immAllOnesV))]>;
158   }
159   let Predicates = [HasAVX2] in
160   def AVX2_SETALLONES : I<0, Pseudo, (outs VR256:$dst), (ins), "",
161                           [(set VR256:$dst, (v8i32 immAllOnesV))]>;
162 }
163
164 //===----------------------------------------------------------------------===//
165 // SSE 1 & 2 - Move FP Scalar Instructions
166 //
167 // Move Instructions. Register-to-register movss/movsd is not used for FR32/64
168 // register copies because it's a partial register update; Register-to-register
169 // movss/movsd is not modeled as an INSERT_SUBREG because INSERT_SUBREG requires
170 // that the insert be implementable in terms of a copy, and just mentioned, we
171 // don't use movss/movsd for copies.
172 //===----------------------------------------------------------------------===//
173
174 multiclass sse12_move_rr<SDNode OpNode, ValueType vt,
175                          X86MemOperand x86memop, string base_opc,
176                          string asm_opr, Domain d, string Name> {
177   let isCommutable = 1 in
178   def rr : SI<0x10, MRMSrcReg, (outs VR128:$dst),
179               (ins VR128:$src1, VR128:$src2),
180               !strconcat(base_opc, asm_opr),
181               [(set VR128:$dst, (vt (OpNode VR128:$src1, VR128:$src2)))], d>,
182               Sched<[SchedWriteFShuffle.XMM]>;
183
184   // For the disassembler
185   let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0 in
186   def rr_REV : SI<0x11, MRMDestReg, (outs VR128:$dst),
187                   (ins VR128:$src1, VR128:$src2),
188                   !strconcat(base_opc, asm_opr), []>,
189                   Sched<[SchedWriteFShuffle.XMM]>, FoldGenData<Name#rr>;
190 }
191
192 multiclass sse12_move<RegisterClass RC, SDNode OpNode, ValueType vt,
193                       X86MemOperand x86memop, string OpcodeStr,
194                       Domain d, string Name> {
195   // AVX
196   defm V#NAME : sse12_move_rr<OpNode, vt, x86memop, OpcodeStr,
197                               "\t{$src2, $src1, $dst|$dst, $src1, $src2}", d,
198                               "V"#Name>,
199                               VEX_4V, VEX_LIG, VEX_WIG;
200
201   def V#NAME#mr : SI<0x11, MRMDestMem, (outs), (ins x86memop:$dst, RC:$src),
202                      !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
203                      [(store RC:$src, addr:$dst)], d>,
204                      VEX, VEX_LIG, Sched<[WriteFStore]>, VEX_WIG;
205   // SSE1 & 2
206   let Constraints = "$src1 = $dst" in {
207     defm NAME : sse12_move_rr<OpNode, vt, x86memop, OpcodeStr,
208                               "\t{$src2, $dst|$dst, $src2}", d, Name>;
209   }
210
211   def NAME#mr   : SI<0x11, MRMDestMem, (outs), (ins x86memop:$dst, RC:$src),
212                      !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
213                      [(store RC:$src, addr:$dst)], d>,
214                      Sched<[WriteFStore]>;
215
216   def : InstAlias<"v"#OpcodeStr#".s\t{$src2, $src1, $dst|$dst, $src1, $src2}",
217                   (!cast<Instruction>("V"#NAME#"rr_REV")
218                    VR128:$dst, VR128:$src1, VR128:$src2), 0>;
219   def : InstAlias<OpcodeStr#".s\t{$src2, $dst|$dst, $src2}",
220                   (!cast<Instruction>(NAME#"rr_REV")
221                    VR128:$dst, VR128:$src2), 0>;
222 }
223
224 // Loading from memory automatically zeroing upper bits.
225 multiclass sse12_move_rm<RegisterClass RC, X86MemOperand x86memop,
226                          PatFrag mem_pat, string OpcodeStr, Domain d> {
227   def V#NAME#rm : SI<0x10, MRMSrcMem, (outs RC:$dst), (ins x86memop:$src),
228                      !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
229                      [(set RC:$dst, (mem_pat addr:$src))], d>,
230                      VEX, VEX_LIG, Sched<[WriteFLoad]>, VEX_WIG;
231   def NAME#rm   : SI<0x10, MRMSrcMem, (outs RC:$dst), (ins x86memop:$src),
232                      !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
233                      [(set RC:$dst, (mem_pat addr:$src))], d>,
234                      Sched<[WriteFLoad]>;
235 }
236
237 defm MOVSS : sse12_move<FR32, X86Movss, v4f32, f32mem, "movss",
238                         SSEPackedSingle, "MOVSS">, XS;
239 defm MOVSD : sse12_move<FR64, X86Movsd, v2f64, f64mem, "movsd",
240                         SSEPackedDouble, "MOVSD">, XD;
241
242 let canFoldAsLoad = 1, isReMaterializable = 1 in {
243   defm MOVSS : sse12_move_rm<FR32, f32mem, loadf32, "movss",
244                              SSEPackedSingle>, XS;
245   defm MOVSD : sse12_move_rm<FR64, f64mem, loadf64, "movsd",
246                              SSEPackedDouble>, XD;
247 }
248
249 // Patterns
250 let Predicates = [UseAVX] in {
251   // MOVSSrm zeros the high parts of the register; represent this
252   // with SUBREG_TO_REG. The AVX versions also write: DST[255:128] <- 0
253   def : Pat<(v4f32 (X86vzmovl (v4f32 (scalar_to_vector (loadf32 addr:$src))))),
254             (COPY_TO_REGCLASS (VMOVSSrm addr:$src), VR128)>;
255   def : Pat<(v4f32 (X86vzmovl (loadv4f32 addr:$src))),
256             (COPY_TO_REGCLASS (VMOVSSrm addr:$src), VR128)>;
257   def : Pat<(v4f32 (X86vzload addr:$src)),
258             (COPY_TO_REGCLASS (VMOVSSrm addr:$src), VR128)>;
259
260   // MOVSDrm zeros the high parts of the register; represent this
261   // with SUBREG_TO_REG. The AVX versions also write: DST[255:128] <- 0
262   def : Pat<(v2f64 (X86vzmovl (v2f64 (scalar_to_vector (loadf64 addr:$src))))),
263             (COPY_TO_REGCLASS (VMOVSDrm addr:$src), VR128)>;
264   def : Pat<(v2f64 (X86vzmovl (loadv2f64 addr:$src))),
265             (COPY_TO_REGCLASS (VMOVSDrm addr:$src), VR128)>;
266   def : Pat<(v2f64 (X86vzmovl (bc_v2f64 (loadv4f32 addr:$src)))),
267             (COPY_TO_REGCLASS (VMOVSDrm addr:$src), VR128)>;
268   def : Pat<(v2f64 (X86vzload addr:$src)),
269             (COPY_TO_REGCLASS (VMOVSDrm addr:$src), VR128)>;
270
271   // Represent the same patterns above but in the form they appear for
272   // 256-bit types
273   def : Pat<(v8f32 (X86vzmovl (insert_subvector undef,
274                    (v4f32 (scalar_to_vector (loadf32 addr:$src))), (iPTR 0)))),
275             (SUBREG_TO_REG (i32 0), (VMOVSSrm addr:$src), sub_xmm)>;
276   def : Pat<(v8f32 (X86vzload addr:$src)),
277             (SUBREG_TO_REG (i32 0), (VMOVSSrm addr:$src), sub_xmm)>;
278   def : Pat<(v4f64 (X86vzmovl (insert_subvector undef,
279                    (v2f64 (scalar_to_vector (loadf64 addr:$src))), (iPTR 0)))),
280             (SUBREG_TO_REG (i32 0), (VMOVSDrm addr:$src), sub_xmm)>;
281   def : Pat<(v4f64 (X86vzload addr:$src)),
282             (SUBREG_TO_REG (i32 0), (VMOVSDrm addr:$src), sub_xmm)>;
283
284   // Extract and store.
285   def : Pat<(store (f32 (extractelt (v4f32 VR128:$src), (iPTR 0))),
286                    addr:$dst),
287             (VMOVSSmr addr:$dst, (COPY_TO_REGCLASS (v4f32 VR128:$src), FR32))>;
288
289   // Shuffle with VMOVSS
290   def : Pat<(v4i32 (X86Movss VR128:$src1, VR128:$src2)),
291             (VMOVSSrr VR128:$src1, VR128:$src2)>;
292
293   // Shuffle with VMOVSD
294   def : Pat<(v2i64 (X86Movsd VR128:$src1, VR128:$src2)),
295             (VMOVSDrr VR128:$src1, VR128:$src2)>;
296 }
297
298 let Predicates = [UseSSE1] in {
299   let Predicates = [NoSSE41] in {
300   // Move scalar to XMM zero-extended, zeroing a VR128 then do a
301   // MOVSS to the lower bits.
302   def : Pat<(v4f32 (X86vzmovl (v4f32 VR128:$src))),
303             (MOVSSrr (v4f32 (V_SET0)), VR128:$src)>;
304   def : Pat<(v4i32 (X86vzmovl (v4i32 VR128:$src))),
305             (MOVSSrr (v4i32 (V_SET0)), VR128:$src)>;
306   }
307
308   // MOVSSrm already zeros the high parts of the register.
309   def : Pat<(v4f32 (X86vzmovl (v4f32 (scalar_to_vector (loadf32 addr:$src))))),
310             (COPY_TO_REGCLASS (MOVSSrm addr:$src), VR128)>;
311   def : Pat<(v4f32 (X86vzmovl (loadv4f32 addr:$src))),
312             (COPY_TO_REGCLASS (MOVSSrm addr:$src), VR128)>;
313   def : Pat<(v4f32 (X86vzload addr:$src)),
314             (COPY_TO_REGCLASS (MOVSSrm addr:$src), VR128)>;
315
316   // Extract and store.
317   def : Pat<(store (f32 (extractelt (v4f32 VR128:$src), (iPTR 0))),
318                    addr:$dst),
319             (MOVSSmr addr:$dst, (COPY_TO_REGCLASS VR128:$src, FR32))>;
320
321   // Shuffle with MOVSS
322   def : Pat<(v4i32 (X86Movss VR128:$src1, VR128:$src2)),
323             (MOVSSrr VR128:$src1, VR128:$src2)>;
324 }
325
326 let Predicates = [UseSSE2] in {
327   // MOVSDrm already zeros the high parts of the register.
328   def : Pat<(v2f64 (X86vzmovl (v2f64 (scalar_to_vector (loadf64 addr:$src))))),
329             (COPY_TO_REGCLASS (MOVSDrm addr:$src), VR128)>;
330   def : Pat<(v2f64 (X86vzmovl (loadv2f64 addr:$src))),
331             (COPY_TO_REGCLASS (MOVSDrm addr:$src), VR128)>;
332   def : Pat<(v2f64 (X86vzmovl (bc_v2f64 (loadv4f32 addr:$src)))),
333             (COPY_TO_REGCLASS (MOVSDrm addr:$src), VR128)>;
334   def : Pat<(v2f64 (X86vzload addr:$src)),
335             (COPY_TO_REGCLASS (MOVSDrm addr:$src), VR128)>;
336
337   // Shuffle with MOVSD
338   def : Pat<(v2i64 (X86Movsd VR128:$src1, VR128:$src2)),
339             (MOVSDrr VR128:$src1, VR128:$src2)>;
340 }
341
342 // Aliases to help the assembler pick two byte VEX encodings by swapping the
343 // operands relative to the normal instructions to use VEX.R instead of VEX.B.
344 def : InstAlias<"vmovss\t{$src2, $src1, $dst|$dst, $src1, $src2}",
345                 (VMOVSSrr_REV VR128L:$dst, VR128:$src1, VR128H:$src2), 0>;
346 def : InstAlias<"vmovsd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
347                 (VMOVSDrr_REV VR128L:$dst, VR128:$src1, VR128H:$src2), 0>;
348
349 //===----------------------------------------------------------------------===//
350 // SSE 1 & 2 - Move Aligned/Unaligned FP Instructions
351 //===----------------------------------------------------------------------===//
352
353 multiclass sse12_mov_packed<bits<8> opc, RegisterClass RC,
354                             X86MemOperand x86memop, PatFrag ld_frag,
355                             string asm, Domain d,
356                             X86SchedWriteMoveLS sched> {
357 let hasSideEffects = 0, isMoveReg = 1 in
358   def rr : PI<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src),
359               !strconcat(asm, "\t{$src, $dst|$dst, $src}"), [], d>,
360            Sched<[sched.RR]>;
361 let canFoldAsLoad = 1, isReMaterializable = 1 in
362   def rm : PI<opc, MRMSrcMem, (outs RC:$dst), (ins x86memop:$src),
363               !strconcat(asm, "\t{$src, $dst|$dst, $src}"),
364                    [(set RC:$dst, (ld_frag addr:$src))], d>,
365            Sched<[sched.RM]>;
366 }
367
368 let Predicates = [HasAVX, NoVLX] in {
369 defm VMOVAPS : sse12_mov_packed<0x28, VR128, f128mem, alignedloadv4f32, "movaps",
370                                 SSEPackedSingle, SchedWriteFMoveLS.XMM>,
371                                 PS, VEX, VEX_WIG;
372 defm VMOVAPD : sse12_mov_packed<0x28, VR128, f128mem, alignedloadv2f64, "movapd",
373                                 SSEPackedDouble, SchedWriteFMoveLS.XMM>,
374                                 PD, VEX, VEX_WIG;
375 defm VMOVUPS : sse12_mov_packed<0x10, VR128, f128mem, loadv4f32, "movups",
376                                 SSEPackedSingle, SchedWriteFMoveLS.XMM>,
377                                 PS, VEX, VEX_WIG;
378 defm VMOVUPD : sse12_mov_packed<0x10, VR128, f128mem, loadv2f64, "movupd",
379                                 SSEPackedDouble, SchedWriteFMoveLS.XMM>,
380                                 PD, VEX, VEX_WIG;
381
382 defm VMOVAPSY : sse12_mov_packed<0x28, VR256, f256mem, alignedloadv8f32, "movaps",
383                                  SSEPackedSingle, SchedWriteFMoveLS.YMM>,
384                                  PS, VEX, VEX_L, VEX_WIG;
385 defm VMOVAPDY : sse12_mov_packed<0x28, VR256, f256mem, alignedloadv4f64, "movapd",
386                                  SSEPackedDouble, SchedWriteFMoveLS.YMM>,
387                                  PD, VEX, VEX_L, VEX_WIG;
388 defm VMOVUPSY : sse12_mov_packed<0x10, VR256, f256mem, loadv8f32, "movups",
389                                  SSEPackedSingle, SchedWriteFMoveLS.YMM>,
390                                  PS, VEX, VEX_L, VEX_WIG;
391 defm VMOVUPDY : sse12_mov_packed<0x10, VR256, f256mem, loadv4f64, "movupd", 
392                                  SSEPackedDouble, SchedWriteFMoveLS.YMM>,
393                                  PD, VEX, VEX_L, VEX_WIG;
394 }
395
396 let Predicates = [UseSSE1] in {
397 defm MOVAPS : sse12_mov_packed<0x28, VR128, f128mem, alignedloadv4f32, "movaps",
398                                SSEPackedSingle, SchedWriteFMoveLS.XMM>,
399                                PS;
400 defm MOVUPS : sse12_mov_packed<0x10, VR128, f128mem, loadv4f32, "movups",
401                                SSEPackedSingle, SchedWriteFMoveLS.XMM>,
402                                PS;
403 }
404 let Predicates = [UseSSE2] in {
405 defm MOVAPD : sse12_mov_packed<0x28, VR128, f128mem, alignedloadv2f64, "movapd",
406                                SSEPackedDouble, SchedWriteFMoveLS.XMM>,
407                                PD;
408 defm MOVUPD : sse12_mov_packed<0x10, VR128, f128mem, loadv2f64, "movupd",
409                                SSEPackedDouble, SchedWriteFMoveLS.XMM>,
410                                PD;
411 }
412
413 let Predicates = [HasAVX, NoVLX]  in {
414 let SchedRW = [SchedWriteFMoveLS.XMM.MR] in {
415 def VMOVAPSmr : VPSI<0x29, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
416                    "movaps\t{$src, $dst|$dst, $src}",
417                    [(alignedstore (v4f32 VR128:$src), addr:$dst)]>,
418                    VEX, VEX_WIG;
419 def VMOVAPDmr : VPDI<0x29, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
420                    "movapd\t{$src, $dst|$dst, $src}",
421                    [(alignedstore (v2f64 VR128:$src), addr:$dst)]>,
422                    VEX, VEX_WIG;
423 def VMOVUPSmr : VPSI<0x11, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
424                    "movups\t{$src, $dst|$dst, $src}",
425                    [(store (v4f32 VR128:$src), addr:$dst)]>,
426                    VEX, VEX_WIG;
427 def VMOVUPDmr : VPDI<0x11, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
428                    "movupd\t{$src, $dst|$dst, $src}",
429                    [(store (v2f64 VR128:$src), addr:$dst)]>,
430                    VEX, VEX_WIG;
431 } // SchedRW
432
433 let SchedRW = [SchedWriteFMoveLS.YMM.MR] in {
434 def VMOVAPSYmr : VPSI<0x29, MRMDestMem, (outs), (ins f256mem:$dst, VR256:$src),
435                    "movaps\t{$src, $dst|$dst, $src}",
436                    [(alignedstore (v8f32 VR256:$src), addr:$dst)]>,
437                    VEX, VEX_L, VEX_WIG;
438 def VMOVAPDYmr : VPDI<0x29, MRMDestMem, (outs), (ins f256mem:$dst, VR256:$src),
439                    "movapd\t{$src, $dst|$dst, $src}",
440                    [(alignedstore (v4f64 VR256:$src), addr:$dst)]>,
441                    VEX, VEX_L, VEX_WIG;
442 def VMOVUPSYmr : VPSI<0x11, MRMDestMem, (outs), (ins f256mem:$dst, VR256:$src),
443                    "movups\t{$src, $dst|$dst, $src}",
444                    [(store (v8f32 VR256:$src), addr:$dst)]>,
445                    VEX, VEX_L, VEX_WIG;
446 def VMOVUPDYmr : VPDI<0x11, MRMDestMem, (outs), (ins f256mem:$dst, VR256:$src),
447                    "movupd\t{$src, $dst|$dst, $src}",
448                    [(store (v4f64 VR256:$src), addr:$dst)]>,
449                    VEX, VEX_L, VEX_WIG;
450 } // SchedRW
451 } // Predicate
452
453 // For disassembler
454 let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0,
455     isMoveReg = 1 in {
456 let SchedRW = [SchedWriteFMoveLS.XMM.RR] in {
457   def VMOVAPSrr_REV : VPSI<0x29, MRMDestReg, (outs VR128:$dst),
458                           (ins VR128:$src),
459                           "movaps\t{$src, $dst|$dst, $src}", []>,
460                           VEX, VEX_WIG, FoldGenData<"VMOVAPSrr">;
461   def VMOVAPDrr_REV : VPDI<0x29, MRMDestReg, (outs VR128:$dst),
462                            (ins VR128:$src),
463                            "movapd\t{$src, $dst|$dst, $src}", []>,
464                            VEX, VEX_WIG, FoldGenData<"VMOVAPDrr">;
465   def VMOVUPSrr_REV : VPSI<0x11, MRMDestReg, (outs VR128:$dst),
466                            (ins VR128:$src),
467                            "movups\t{$src, $dst|$dst, $src}", []>,
468                            VEX, VEX_WIG, FoldGenData<"VMOVUPSrr">;
469   def VMOVUPDrr_REV : VPDI<0x11, MRMDestReg, (outs VR128:$dst),
470                            (ins VR128:$src),
471                            "movupd\t{$src, $dst|$dst, $src}", []>,
472                            VEX, VEX_WIG, FoldGenData<"VMOVUPDrr">;
473 } // SchedRW
474
475 let SchedRW = [SchedWriteFMoveLS.YMM.RR] in {
476   def VMOVAPSYrr_REV : VPSI<0x29, MRMDestReg, (outs VR256:$dst),
477                             (ins VR256:$src),
478                             "movaps\t{$src, $dst|$dst, $src}", []>,
479                             VEX, VEX_L, VEX_WIG, FoldGenData<"VMOVAPSYrr">;
480   def VMOVAPDYrr_REV : VPDI<0x29, MRMDestReg, (outs VR256:$dst),
481                             (ins VR256:$src),
482                             "movapd\t{$src, $dst|$dst, $src}", []>,
483                             VEX, VEX_L, VEX_WIG, FoldGenData<"VMOVAPDYrr">;
484   def VMOVUPSYrr_REV : VPSI<0x11, MRMDestReg, (outs VR256:$dst),
485                             (ins VR256:$src),
486                             "movups\t{$src, $dst|$dst, $src}", []>,
487                             VEX, VEX_L, VEX_WIG, FoldGenData<"VMOVUPSYrr">;
488   def VMOVUPDYrr_REV : VPDI<0x11, MRMDestReg, (outs VR256:$dst),
489                             (ins VR256:$src),
490                             "movupd\t{$src, $dst|$dst, $src}", []>,
491                             VEX, VEX_L, VEX_WIG, FoldGenData<"VMOVUPDYrr">;
492 } // SchedRW
493 } // Predicate
494
495 // Aliases to help the assembler pick two byte VEX encodings by swapping the
496 // operands relative to the normal instructions to use VEX.R instead of VEX.B.
497 def : InstAlias<"vmovaps\t{$src, $dst|$dst, $src}",
498                 (VMOVAPSrr_REV VR128L:$dst, VR128H:$src), 0>;
499 def : InstAlias<"vmovapd\t{$src, $dst|$dst, $src}",
500                 (VMOVAPDrr_REV VR128L:$dst, VR128H:$src), 0>;
501 def : InstAlias<"vmovups\t{$src, $dst|$dst, $src}",
502                 (VMOVUPSrr_REV VR128L:$dst, VR128H:$src), 0>;
503 def : InstAlias<"vmovupd\t{$src, $dst|$dst, $src}",
504                 (VMOVUPDrr_REV VR128L:$dst, VR128H:$src), 0>;
505 def : InstAlias<"vmovaps\t{$src, $dst|$dst, $src}",
506                 (VMOVAPSYrr_REV VR256L:$dst, VR256H:$src), 0>;
507 def : InstAlias<"vmovapd\t{$src, $dst|$dst, $src}",
508                 (VMOVAPDYrr_REV VR256L:$dst, VR256H:$src), 0>;
509 def : InstAlias<"vmovups\t{$src, $dst|$dst, $src}",
510                 (VMOVUPSYrr_REV VR256L:$dst, VR256H:$src), 0>;
511 def : InstAlias<"vmovupd\t{$src, $dst|$dst, $src}",
512                 (VMOVUPDYrr_REV VR256L:$dst, VR256H:$src), 0>;
513
514 // Reversed version with ".s" suffix for GAS compatibility.
515 def : InstAlias<"vmovaps.s\t{$src, $dst|$dst, $src}",
516                 (VMOVAPSrr_REV VR128:$dst, VR128:$src), 0>;
517 def : InstAlias<"vmovapd.s\t{$src, $dst|$dst, $src}",
518                 (VMOVAPDrr_REV VR128:$dst, VR128:$src), 0>;
519 def : InstAlias<"vmovups.s\t{$src, $dst|$dst, $src}",
520                 (VMOVUPSrr_REV VR128:$dst, VR128:$src), 0>;
521 def : InstAlias<"vmovupd.s\t{$src, $dst|$dst, $src}",
522                 (VMOVUPDrr_REV VR128:$dst, VR128:$src), 0>;
523 def : InstAlias<"vmovaps.s\t{$src, $dst|$dst, $src}",
524                 (VMOVAPSYrr_REV VR256:$dst, VR256:$src), 0>;
525 def : InstAlias<"vmovapd.s\t{$src, $dst|$dst, $src}",
526                 (VMOVAPDYrr_REV VR256:$dst, VR256:$src), 0>;
527 def : InstAlias<"vmovups.s\t{$src, $dst|$dst, $src}",
528                 (VMOVUPSYrr_REV VR256:$dst, VR256:$src), 0>;
529 def : InstAlias<"vmovupd.s\t{$src, $dst|$dst, $src}",
530                 (VMOVUPDYrr_REV VR256:$dst, VR256:$src), 0>;
531
532 let SchedRW = [SchedWriteFMoveLS.XMM.MR] in {
533 def MOVAPSmr : PSI<0x29, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
534                    "movaps\t{$src, $dst|$dst, $src}",
535                    [(alignedstore (v4f32 VR128:$src), addr:$dst)]>;
536 def MOVAPDmr : PDI<0x29, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
537                    "movapd\t{$src, $dst|$dst, $src}",
538                    [(alignedstore (v2f64 VR128:$src), addr:$dst)]>;
539 def MOVUPSmr : PSI<0x11, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
540                    "movups\t{$src, $dst|$dst, $src}",
541                    [(store (v4f32 VR128:$src), addr:$dst)]>;
542 def MOVUPDmr : PDI<0x11, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
543                    "movupd\t{$src, $dst|$dst, $src}",
544                    [(store (v2f64 VR128:$src), addr:$dst)]>;
545 } // SchedRW
546
547 // For disassembler
548 let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0,
549     isMoveReg = 1, SchedRW = [SchedWriteFMoveLS.XMM.RR] in {
550   def MOVAPSrr_REV : PSI<0x29, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
551                          "movaps\t{$src, $dst|$dst, $src}", []>,
552                          FoldGenData<"MOVAPSrr">;
553   def MOVAPDrr_REV : PDI<0x29, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
554                          "movapd\t{$src, $dst|$dst, $src}", []>,
555                          FoldGenData<"MOVAPDrr">;
556   def MOVUPSrr_REV : PSI<0x11, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
557                          "movups\t{$src, $dst|$dst, $src}", []>,
558                          FoldGenData<"MOVUPSrr">;
559   def MOVUPDrr_REV : PDI<0x11, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
560                          "movupd\t{$src, $dst|$dst, $src}", []>,
561                          FoldGenData<"MOVUPDrr">;
562 }
563
564 // Reversed version with ".s" suffix for GAS compatibility.
565 def : InstAlias<"movaps.s\t{$src, $dst|$dst, $src}",
566                 (MOVAPSrr_REV VR128:$dst, VR128:$src), 0>;
567 def : InstAlias<"movapd.s\t{$src, $dst|$dst, $src}",
568                 (MOVAPDrr_REV VR128:$dst, VR128:$src), 0>;
569 def : InstAlias<"movups.s\t{$src, $dst|$dst, $src}",
570                 (MOVUPSrr_REV VR128:$dst, VR128:$src), 0>;
571 def : InstAlias<"movupd.s\t{$src, $dst|$dst, $src}",
572                 (MOVUPDrr_REV VR128:$dst, VR128:$src), 0>;
573
574 let Predicates = [HasAVX, NoVLX] in {
575   // 256-bit load/store need to use floating point load/store in case we don't
576   // have AVX2. Execution domain fixing will convert to integer if AVX2 is
577   // available and changing the domain is beneficial.
578   def : Pat<(alignedloadv4i64 addr:$src),
579             (VMOVAPSYrm addr:$src)>;
580   def : Pat<(loadv4i64 addr:$src),
581             (VMOVUPSYrm addr:$src)>;
582   def : Pat<(alignedstore (v4i64 VR256:$src), addr:$dst),
583             (VMOVAPSYmr addr:$dst, VR256:$src)>;
584   def : Pat<(alignedstore (v8i32 VR256:$src), addr:$dst),
585             (VMOVAPSYmr addr:$dst, VR256:$src)>;
586   def : Pat<(alignedstore (v16i16 VR256:$src), addr:$dst),
587             (VMOVAPSYmr addr:$dst, VR256:$src)>;
588   def : Pat<(alignedstore (v32i8 VR256:$src), addr:$dst),
589             (VMOVAPSYmr addr:$dst, VR256:$src)>;
590   def : Pat<(store (v4i64 VR256:$src), addr:$dst),
591             (VMOVUPSYmr addr:$dst, VR256:$src)>;
592   def : Pat<(store (v8i32 VR256:$src), addr:$dst),
593             (VMOVUPSYmr addr:$dst, VR256:$src)>;
594   def : Pat<(store (v16i16 VR256:$src), addr:$dst),
595             (VMOVUPSYmr addr:$dst, VR256:$src)>;
596   def : Pat<(store (v32i8 VR256:$src), addr:$dst),
597             (VMOVUPSYmr addr:$dst, VR256:$src)>;
598 }
599
600 // Use movaps / movups for SSE integer load / store (one byte shorter).
601 // The instructions selected below are then converted to MOVDQA/MOVDQU
602 // during the SSE domain pass.
603 let Predicates = [UseSSE1] in {
604   def : Pat<(alignedloadv2i64 addr:$src),
605             (MOVAPSrm addr:$src)>;
606   def : Pat<(loadv2i64 addr:$src),
607             (MOVUPSrm addr:$src)>;
608
609   def : Pat<(alignedstore (v2i64 VR128:$src), addr:$dst),
610             (MOVAPSmr addr:$dst, VR128:$src)>;
611   def : Pat<(alignedstore (v4i32 VR128:$src), addr:$dst),
612             (MOVAPSmr addr:$dst, VR128:$src)>;
613   def : Pat<(alignedstore (v8i16 VR128:$src), addr:$dst),
614             (MOVAPSmr addr:$dst, VR128:$src)>;
615   def : Pat<(alignedstore (v16i8 VR128:$src), addr:$dst),
616             (MOVAPSmr addr:$dst, VR128:$src)>;
617   def : Pat<(store (v2i64 VR128:$src), addr:$dst),
618             (MOVUPSmr addr:$dst, VR128:$src)>;
619   def : Pat<(store (v4i32 VR128:$src), addr:$dst),
620             (MOVUPSmr addr:$dst, VR128:$src)>;
621   def : Pat<(store (v8i16 VR128:$src), addr:$dst),
622             (MOVUPSmr addr:$dst, VR128:$src)>;
623   def : Pat<(store (v16i8 VR128:$src), addr:$dst),
624             (MOVUPSmr addr:$dst, VR128:$src)>;
625 }
626
627 //===----------------------------------------------------------------------===//
628 // SSE 1 & 2 - Move Low packed FP Instructions
629 //===----------------------------------------------------------------------===//
630
631 multiclass sse12_mov_hilo_packed_base<bits<8>opc, SDNode psnode, SDNode pdnode,
632                                       string base_opc, string asm_opr> {
633   let hasSideEffects = 0, mayLoad = 1 in
634   def PSrm : PI<opc, MRMSrcMem,
635          (outs VR128:$dst), (ins VR128:$src1, f64mem:$src2),
636          !strconcat(base_opc, "s", asm_opr),
637      [(set VR128:$dst,
638        (psnode VR128:$src1,
639               (bc_v4f32 (v2f64 (scalar_to_vector (loadf64 addr:$src2))))))],
640               SSEPackedSingle>, PS,
641      Sched<[SchedWriteFShuffle.XMM.Folded, ReadAfterLd]>;
642
643   let hasSideEffects = 0, mayLoad = 1 in
644   def PDrm : PI<opc, MRMSrcMem,
645          (outs VR128:$dst), (ins VR128:$src1, f64mem:$src2),
646          !strconcat(base_opc, "d", asm_opr),
647      [(set VR128:$dst, (v2f64 (pdnode VR128:$src1,
648                               (scalar_to_vector (loadf64 addr:$src2)))))],
649               SSEPackedDouble>, PD,
650      Sched<[SchedWriteFShuffle.XMM.Folded, ReadAfterLd]>;
651 }
652
653 multiclass sse12_mov_hilo_packed<bits<8>opc, SDPatternOperator psnode,
654                                  SDPatternOperator pdnode, string base_opc> {
655   let Predicates = [UseAVX] in
656     defm V#NAME : sse12_mov_hilo_packed_base<opc, psnode, pdnode, base_opc,
657                                     "\t{$src2, $src1, $dst|$dst, $src1, $src2}">,
658                                     VEX_4V, VEX_WIG;
659
660   let Constraints = "$src1 = $dst" in
661     defm NAME : sse12_mov_hilo_packed_base<opc, psnode, pdnode, base_opc,
662                                     "\t{$src2, $dst|$dst, $src2}">;
663 }
664
665 defm MOVL : sse12_mov_hilo_packed<0x12, null_frag, null_frag, "movlp">;
666
667 let SchedRW = [WriteFStore] in {
668 let Predicates = [UseAVX] in {
669 def VMOVLPSmr : VPSI<0x13, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
670                      "movlps\t{$src, $dst|$dst, $src}",
671                      [(store (f64 (extractelt (bc_v2f64 (v4f32 VR128:$src)),
672                                    (iPTR 0))), addr:$dst)]>,
673                      VEX, VEX_WIG;
674 def VMOVLPDmr : VPDI<0x13, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
675                      "movlpd\t{$src, $dst|$dst, $src}",
676                      [(store (f64 (extractelt (v2f64 VR128:$src),
677                                    (iPTR 0))), addr:$dst)]>,
678                      VEX, VEX_WIG;
679 }// UseAVX
680 def MOVLPSmr : PSI<0x13, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
681                    "movlps\t{$src, $dst|$dst, $src}",
682                    [(store (f64 (extractelt (bc_v2f64 (v4f32 VR128:$src)),
683                                  (iPTR 0))), addr:$dst)]>;
684 def MOVLPDmr : PDI<0x13, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
685                    "movlpd\t{$src, $dst|$dst, $src}",
686                    [(store (f64 (extractelt (v2f64 VR128:$src),
687                                  (iPTR 0))), addr:$dst)]>;
688 } // SchedRW
689
690 let Predicates = [UseAVX] in {
691   // Shuffle with VMOVLPD
692   def : Pat<(v2f64 (X86Movsd VR128:$src1,
693                              (v2f64 (scalar_to_vector (loadf64 addr:$src2))))),
694             (VMOVLPDrm VR128:$src1, addr:$src2)>;
695 }
696
697 let Predicates = [UseSSE1] in {
698   // (store (vector_shuffle (load addr), v2, <4, 5, 2, 3>), addr) using MOVLPS
699   def : Pat<(store (i64 (extractelt (bc_v2i64 (v4f32 VR128:$src2)),
700                                  (iPTR 0))), addr:$src1),
701             (MOVLPSmr addr:$src1, VR128:$src2)>;
702 }
703
704 let Predicates = [UseSSE2] in {
705   // Shuffle with MOVLPD
706   def : Pat<(v2f64 (X86Movsd VR128:$src1,
707                              (v2f64 (scalar_to_vector (loadf64 addr:$src2))))),
708             (MOVLPDrm VR128:$src1, addr:$src2)>;
709 }
710
711 //===----------------------------------------------------------------------===//
712 // SSE 1 & 2 - Move Hi packed FP Instructions
713 //===----------------------------------------------------------------------===//
714
715 defm MOVH : sse12_mov_hilo_packed<0x16, X86Movlhps, X86Unpckl, "movhp">;
716
717 let SchedRW = [WriteFStore] in {
718 // v2f64 extract element 1 is always custom lowered to unpack high to low
719 // and extract element 0 so the non-store version isn't too horrible.
720 let Predicates = [UseAVX] in {
721 def VMOVHPSmr : VPSI<0x17, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
722                    "movhps\t{$src, $dst|$dst, $src}",
723                    [(store (f64 (extractelt
724                                  (X86Unpckh (bc_v2f64 (v4f32 VR128:$src)),
725                                             (bc_v2f64 (v4f32 VR128:$src))),
726                                  (iPTR 0))), addr:$dst)]>, VEX, VEX_WIG;
727 def VMOVHPDmr : VPDI<0x17, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
728                    "movhpd\t{$src, $dst|$dst, $src}",
729                    [(store (f64 (extractelt
730                                  (v2f64 (X86Unpckh VR128:$src, VR128:$src)),
731                                  (iPTR 0))), addr:$dst)]>, VEX, VEX_WIG;
732 } // UseAVX
733 def MOVHPSmr : PSI<0x17, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
734                    "movhps\t{$src, $dst|$dst, $src}",
735                    [(store (f64 (extractelt
736                                  (X86Unpckh (bc_v2f64 (v4f32 VR128:$src)),
737                                             (bc_v2f64 (v4f32 VR128:$src))),
738                                  (iPTR 0))), addr:$dst)]>;
739 def MOVHPDmr : PDI<0x17, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
740                    "movhpd\t{$src, $dst|$dst, $src}",
741                    [(store (f64 (extractelt
742                                  (v2f64 (X86Unpckh VR128:$src, VR128:$src)),
743                                  (iPTR 0))), addr:$dst)]>;
744 } // SchedRW
745
746 let Predicates = [UseAVX] in {
747   // VMOVHPS patterns
748   def : Pat<(X86Movlhps VR128:$src1,
749                  (bc_v4f32 (v2i64 (scalar_to_vector (loadi64 addr:$src2))))),
750             (VMOVHPSrm VR128:$src1, addr:$src2)>;
751   def : Pat<(X86Movlhps VR128:$src1,
752                  (bc_v4f32 (v2i64 (X86vzload addr:$src2)))),
753             (VMOVHPSrm VR128:$src1, addr:$src2)>;
754
755   // Also handle an i64 load because that may get selected as a faster way to
756   // load the data.
757   def : Pat<(v2f64 (X86Unpckl VR128:$src1,
758                       (bc_v2f64 (v2i64 (scalar_to_vector (loadi64 addr:$src2)))))),
759             (VMOVHPDrm VR128:$src1, addr:$src2)>;
760
761   def : Pat<(store (f64 (extractelt
762                           (bc_v2f64 (v4f32 (X86Movhlps VR128:$src, VR128:$src))),
763                           (iPTR 0))), addr:$dst),
764             (VMOVHPDmr addr:$dst, VR128:$src)>;
765
766   def : Pat<(store (f64 (extractelt
767                           (v2f64 (X86VPermilpi VR128:$src, (i8 1))),
768                           (iPTR 0))), addr:$dst),
769             (VMOVHPDmr addr:$dst, VR128:$src)>;
770 }
771
772 let Predicates = [UseSSE1] in {
773   // MOVHPS patterns
774   def : Pat<(X86Movlhps VR128:$src1,
775                  (bc_v4f32 (v2i64 (scalar_to_vector (loadi64 addr:$src2))))),
776             (MOVHPSrm VR128:$src1, addr:$src2)>;
777   def : Pat<(X86Movlhps VR128:$src1,
778                  (bc_v4f32 (v2i64 (X86vzload addr:$src2)))),
779             (MOVHPSrm VR128:$src1, addr:$src2)>;
780 }
781
782 let Predicates = [UseSSE2] in {
783   // MOVHPD patterns
784
785   // Also handle an i64 load because that may get selected as a faster way to
786   // load the data.
787   def : Pat<(v2f64 (X86Unpckl VR128:$src1,
788                       (bc_v2f64 (v2i64 (scalar_to_vector (loadi64 addr:$src2)))))),
789             (MOVHPDrm VR128:$src1, addr:$src2)>;
790
791   def : Pat<(store (f64 (extractelt
792                           (bc_v2f64 (v4f32 (X86Movhlps VR128:$src, VR128:$src))),
793                           (iPTR 0))), addr:$dst),
794             (MOVHPDmr addr:$dst, VR128:$src)>;
795
796   def : Pat<(store (f64 (extractelt
797                           (v2f64 (X86Shufp VR128:$src, VR128:$src, (i8 1))),
798                           (iPTR 0))), addr:$dst),
799             (MOVHPDmr addr:$dst, VR128:$src)>;
800 }
801
802 //===----------------------------------------------------------------------===//
803 // SSE 1 & 2 - Move Low to High and High to Low packed FP Instructions
804 //===----------------------------------------------------------------------===//
805
806 let Predicates = [UseAVX] in {
807   def VMOVLHPSrr : VPSI<0x16, MRMSrcReg, (outs VR128:$dst),
808                                        (ins VR128:$src1, VR128:$src2),
809                       "movlhps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
810                       [(set VR128:$dst,
811                         (v4f32 (X86Movlhps VR128:$src1, VR128:$src2)))]>,
812                       VEX_4V, Sched<[SchedWriteFShuffle.XMM]>, VEX_WIG;
813   def VMOVHLPSrr : VPSI<0x12, MRMSrcReg, (outs VR128:$dst),
814                                        (ins VR128:$src1, VR128:$src2),
815                       "movhlps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
816                       [(set VR128:$dst,
817                         (v4f32 (X86Movhlps VR128:$src1, VR128:$src2)))]>,
818                       VEX_4V, Sched<[SchedWriteFShuffle.XMM]>, VEX_WIG,
819                       NotMemoryFoldable;
820 }
821 let Constraints = "$src1 = $dst" in {
822   def MOVLHPSrr : PSI<0x16, MRMSrcReg, (outs VR128:$dst),
823                                        (ins VR128:$src1, VR128:$src2),
824                       "movlhps\t{$src2, $dst|$dst, $src2}",
825                       [(set VR128:$dst,
826                         (v4f32 (X86Movlhps VR128:$src1, VR128:$src2)))]>,
827                       Sched<[SchedWriteFShuffle.XMM]>;
828   let isCommutable = 1 in
829   def MOVHLPSrr : PSI<0x12, MRMSrcReg, (outs VR128:$dst),
830                                        (ins VR128:$src1, VR128:$src2),
831                       "movhlps\t{$src2, $dst|$dst, $src2}",
832                       [(set VR128:$dst,
833                         (v4f32 (X86Movhlps VR128:$src1, VR128:$src2)))]>,
834                       Sched<[SchedWriteFShuffle.XMM]>, NotMemoryFoldable;
835 }
836
837 //===----------------------------------------------------------------------===//
838 // SSE 1 & 2 - Conversion Instructions
839 //===----------------------------------------------------------------------===//
840
841 multiclass sse12_cvt_s<bits<8> opc, RegisterClass SrcRC, RegisterClass DstRC,
842                      SDNode OpNode, X86MemOperand x86memop, PatFrag ld_frag,
843                      string asm, X86FoldableSchedWrite sched> {
844   def rr : SI<opc, MRMSrcReg, (outs DstRC:$dst), (ins SrcRC:$src), asm,
845                         [(set DstRC:$dst, (OpNode SrcRC:$src))]>,
846                         Sched<[sched]>;
847   def rm : SI<opc, MRMSrcMem, (outs DstRC:$dst), (ins x86memop:$src), asm,
848                         [(set DstRC:$dst, (OpNode (ld_frag addr:$src)))]>,
849                         Sched<[sched.Folded]>;
850 }
851
852 multiclass sse12_cvt_p<bits<8> opc, RegisterClass RC, X86MemOperand x86memop,
853                        ValueType DstTy, ValueType SrcTy, PatFrag ld_frag,
854                        string asm, Domain d, X86FoldableSchedWrite sched> {
855 let hasSideEffects = 0 in {
856   def rr : I<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src), asm,
857              [(set RC:$dst, (DstTy (sint_to_fp (SrcTy RC:$src))))], d>,
858              Sched<[sched]>;
859   let mayLoad = 1 in
860   def rm : I<opc, MRMSrcMem, (outs RC:$dst), (ins x86memop:$src), asm,
861              [(set RC:$dst, (DstTy (sint_to_fp
862                                     (SrcTy (bitconvert (ld_frag addr:$src))))))], d>,
863              Sched<[sched.Folded]>;
864 }
865 }
866
867 multiclass sse12_vcvt_avx<bits<8> opc, RegisterClass SrcRC, RegisterClass DstRC,
868                           X86MemOperand x86memop, string asm,
869                           X86FoldableSchedWrite sched> {
870 let hasSideEffects = 0, Predicates = [UseAVX] in {
871   def rr : SI<opc, MRMSrcReg, (outs DstRC:$dst), (ins DstRC:$src1, SrcRC:$src),
872               !strconcat(asm,"\t{$src, $src1, $dst|$dst, $src1, $src}"), []>,
873               Sched<[sched]>;
874   let mayLoad = 1 in
875   def rm : SI<opc, MRMSrcMem, (outs DstRC:$dst),
876               (ins DstRC:$src1, x86memop:$src),
877               !strconcat(asm,"\t{$src, $src1, $dst|$dst, $src1, $src}"), []>,
878            Sched<[sched.Folded, ReadAfterLd]>;
879 } // hasSideEffects = 0
880 }
881
882 let Predicates = [UseAVX] in {
883 defm VCVTTSS2SI   : sse12_cvt_s<0x2C, FR32, GR32, fp_to_sint, f32mem, loadf32,
884                                 "cvttss2si\t{$src, $dst|$dst, $src}",
885                                 WriteCvtSS2I>,
886                                 XS, VEX, VEX_LIG;
887 defm VCVTTSS2SI64 : sse12_cvt_s<0x2C, FR32, GR64, fp_to_sint, f32mem, loadf32,
888                                 "cvttss2si\t{$src, $dst|$dst, $src}",
889                                 WriteCvtSS2I>,
890                                 XS, VEX, VEX_W, VEX_LIG;
891 defm VCVTTSD2SI   : sse12_cvt_s<0x2C, FR64, GR32, fp_to_sint, f64mem, loadf64,
892                                 "cvttsd2si\t{$src, $dst|$dst, $src}",
893                                 WriteCvtSD2I>,
894                                 XD, VEX, VEX_LIG;
895 defm VCVTTSD2SI64 : sse12_cvt_s<0x2C, FR64, GR64, fp_to_sint, f64mem, loadf64,
896                                 "cvttsd2si\t{$src, $dst|$dst, $src}",
897                                 WriteCvtSD2I>,
898                                 XD, VEX, VEX_W, VEX_LIG;
899
900 def : InstAlias<"vcvttss2si{l}\t{$src, $dst|$dst, $src}",
901                 (VCVTTSS2SIrr GR32:$dst, FR32:$src), 0, "att">;
902 def : InstAlias<"vcvttss2si{l}\t{$src, $dst|$dst, $src}",
903                 (VCVTTSS2SIrm GR32:$dst, f32mem:$src), 0, "att">;
904 def : InstAlias<"vcvttsd2si{l}\t{$src, $dst|$dst, $src}",
905                 (VCVTTSD2SIrr GR32:$dst, FR64:$src), 0, "att">;
906 def : InstAlias<"vcvttsd2si{l}\t{$src, $dst|$dst, $src}",
907                 (VCVTTSD2SIrm GR32:$dst, f64mem:$src), 0, "att">;
908 def : InstAlias<"vcvttss2si{q}\t{$src, $dst|$dst, $src}",
909                 (VCVTTSS2SI64rr GR64:$dst, FR32:$src), 0, "att">;
910 def : InstAlias<"vcvttss2si{q}\t{$src, $dst|$dst, $src}",
911                 (VCVTTSS2SI64rm GR64:$dst, f32mem:$src), 0, "att">;
912 def : InstAlias<"vcvttsd2si{q}\t{$src, $dst|$dst, $src}",
913                 (VCVTTSD2SI64rr GR64:$dst, FR64:$src), 0, "att">;
914 def : InstAlias<"vcvttsd2si{q}\t{$src, $dst|$dst, $src}",
915                 (VCVTTSD2SI64rm GR64:$dst, f64mem:$src), 0, "att">;
916 }
917 // The assembler can recognize rr 64-bit instructions by seeing a rxx
918 // register, but the same isn't true when only using memory operands,
919 // provide other assembly "l" and "q" forms to address this explicitly
920 // where appropriate to do so.
921 defm VCVTSI2SS   : sse12_vcvt_avx<0x2A, GR32, FR32, i32mem, "cvtsi2ss{l}",
922                                   WriteCvtI2SS>, XS, VEX_4V, VEX_LIG;
923 defm VCVTSI642SS : sse12_vcvt_avx<0x2A, GR64, FR32, i64mem, "cvtsi2ss{q}",
924                                   WriteCvtI2SS>, XS, VEX_4V, VEX_W, VEX_LIG;
925 defm VCVTSI2SD   : sse12_vcvt_avx<0x2A, GR32, FR64, i32mem, "cvtsi2sd{l}",
926                                   WriteCvtI2SD>, XD, VEX_4V, VEX_LIG;
927 defm VCVTSI642SD : sse12_vcvt_avx<0x2A, GR64, FR64, i64mem, "cvtsi2sd{q}",
928                                   WriteCvtI2SD>, XD, VEX_4V, VEX_W, VEX_LIG;
929
930 let Predicates = [UseAVX] in {
931   def : InstAlias<"vcvtsi2ss\t{$src, $src1, $dst|$dst, $src1, $src}",
932                 (VCVTSI2SSrm FR64:$dst, FR64:$src1, i32mem:$src), 0, "att">;
933   def : InstAlias<"vcvtsi2sd\t{$src, $src1, $dst|$dst, $src1, $src}",
934                 (VCVTSI2SDrm FR64:$dst, FR64:$src1, i32mem:$src), 0, "att">;
935
936   def : Pat<(f32 (sint_to_fp (loadi32 addr:$src))),
937             (VCVTSI2SSrm (f32 (IMPLICIT_DEF)), addr:$src)>;
938   def : Pat<(f32 (sint_to_fp (loadi64 addr:$src))),
939             (VCVTSI642SSrm (f32 (IMPLICIT_DEF)), addr:$src)>;
940   def : Pat<(f64 (sint_to_fp (loadi32 addr:$src))),
941             (VCVTSI2SDrm (f64 (IMPLICIT_DEF)), addr:$src)>;
942   def : Pat<(f64 (sint_to_fp (loadi64 addr:$src))),
943             (VCVTSI642SDrm (f64 (IMPLICIT_DEF)), addr:$src)>;
944
945   def : Pat<(f32 (sint_to_fp GR32:$src)),
946             (VCVTSI2SSrr (f32 (IMPLICIT_DEF)), GR32:$src)>;
947   def : Pat<(f32 (sint_to_fp GR64:$src)),
948             (VCVTSI642SSrr (f32 (IMPLICIT_DEF)), GR64:$src)>;
949   def : Pat<(f64 (sint_to_fp GR32:$src)),
950             (VCVTSI2SDrr (f64 (IMPLICIT_DEF)), GR32:$src)>;
951   def : Pat<(f64 (sint_to_fp GR64:$src)),
952             (VCVTSI642SDrr (f64 (IMPLICIT_DEF)), GR64:$src)>;
953 }
954
955 defm CVTTSS2SI : sse12_cvt_s<0x2C, FR32, GR32, fp_to_sint, f32mem, loadf32,
956                       "cvttss2si\t{$src, $dst|$dst, $src}",
957                       WriteCvtSS2I>, XS;
958 defm CVTTSS2SI64 : sse12_cvt_s<0x2C, FR32, GR64, fp_to_sint, f32mem, loadf32,
959                       "cvttss2si\t{$src, $dst|$dst, $src}",
960                       WriteCvtSS2I>, XS, REX_W;
961 defm CVTTSD2SI : sse12_cvt_s<0x2C, FR64, GR32, fp_to_sint, f64mem, loadf64,
962                       "cvttsd2si\t{$src, $dst|$dst, $src}",
963                       WriteCvtSD2I>, XD;
964 defm CVTTSD2SI64 : sse12_cvt_s<0x2C, FR64, GR64, fp_to_sint, f64mem, loadf64,
965                       "cvttsd2si\t{$src, $dst|$dst, $src}",
966                       WriteCvtSD2I>, XD, REX_W;
967 defm CVTSI2SS  : sse12_cvt_s<0x2A, GR32, FR32, sint_to_fp, i32mem, loadi32,
968                       "cvtsi2ss{l}\t{$src, $dst|$dst, $src}",
969                       WriteCvtI2SS>, XS;
970 defm CVTSI642SS : sse12_cvt_s<0x2A, GR64, FR32, sint_to_fp, i64mem, loadi64,
971                       "cvtsi2ss{q}\t{$src, $dst|$dst, $src}",
972                       WriteCvtI2SS>, XS, REX_W;
973 defm CVTSI2SD  : sse12_cvt_s<0x2A, GR32, FR64, sint_to_fp, i32mem, loadi32,
974                       "cvtsi2sd{l}\t{$src, $dst|$dst, $src}",
975                       WriteCvtI2SD>, XD;
976 defm CVTSI642SD : sse12_cvt_s<0x2A, GR64, FR64, sint_to_fp, i64mem, loadi64,
977                       "cvtsi2sd{q}\t{$src, $dst|$dst, $src}",
978                       WriteCvtI2SD>, XD, REX_W;
979
980 def : InstAlias<"cvttss2si{l}\t{$src, $dst|$dst, $src}",
981                 (CVTTSS2SIrr GR32:$dst, FR32:$src), 0, "att">;
982 def : InstAlias<"cvttss2si{l}\t{$src, $dst|$dst, $src}",
983                 (CVTTSS2SIrm GR32:$dst, f32mem:$src), 0, "att">;
984 def : InstAlias<"cvttsd2si{l}\t{$src, $dst|$dst, $src}",
985                 (CVTTSD2SIrr GR32:$dst, FR64:$src), 0, "att">;
986 def : InstAlias<"cvttsd2si{l}\t{$src, $dst|$dst, $src}",
987                 (CVTTSD2SIrm GR32:$dst, f64mem:$src), 0, "att">;
988 def : InstAlias<"cvttss2si{q}\t{$src, $dst|$dst, $src}",
989                 (CVTTSS2SI64rr GR64:$dst, FR32:$src), 0, "att">;
990 def : InstAlias<"cvttss2si{q}\t{$src, $dst|$dst, $src}",
991                 (CVTTSS2SI64rm GR64:$dst, f32mem:$src), 0, "att">;
992 def : InstAlias<"cvttsd2si{q}\t{$src, $dst|$dst, $src}",
993                 (CVTTSD2SI64rr GR64:$dst, FR64:$src), 0, "att">;
994 def : InstAlias<"cvttsd2si{q}\t{$src, $dst|$dst, $src}",
995                 (CVTTSD2SI64rm GR64:$dst, f64mem:$src), 0, "att">;
996
997 def : InstAlias<"cvtsi2ss\t{$src, $dst|$dst, $src}",
998                 (CVTSI2SSrm FR64:$dst, i32mem:$src), 0, "att">;
999 def : InstAlias<"cvtsi2sd\t{$src, $dst|$dst, $src}",
1000                 (CVTSI2SDrm FR64:$dst, i32mem:$src), 0, "att">;
1001
1002 // Conversion Instructions Intrinsics - Match intrinsics which expect MM
1003 // and/or XMM operand(s).
1004
1005 // FIXME: We probably want to match the rm form only when optimizing for
1006 // size, to avoid false depenendecies (see sse_fp_unop_s for details)
1007 multiclass sse12_cvt_sint<bits<8> opc, RegisterClass SrcRC, RegisterClass DstRC,
1008                           Intrinsic Int, Operand memop, ComplexPattern mem_cpat,
1009                           string asm, X86FoldableSchedWrite sched> {
1010   def rr_Int : SI<opc, MRMSrcReg, (outs DstRC:$dst), (ins SrcRC:$src),
1011                   !strconcat(asm, "\t{$src, $dst|$dst, $src}"),
1012                   [(set DstRC:$dst, (Int SrcRC:$src))]>,
1013                Sched<[sched]>;
1014   def rm_Int : SI<opc, MRMSrcMem, (outs DstRC:$dst), (ins memop:$src),
1015                   !strconcat(asm, "\t{$src, $dst|$dst, $src}"),
1016                   [(set DstRC:$dst, (Int mem_cpat:$src))]>,
1017                Sched<[sched.Folded]>;
1018 }
1019
1020 multiclass sse12_cvt_sint_3addr<bits<8> opc, RegisterClass SrcRC,
1021                     RegisterClass DstRC, X86MemOperand x86memop,
1022                     string asm, X86FoldableSchedWrite sched,
1023                     bit Is2Addr = 1> {
1024 let hasSideEffects = 0 in {
1025   def rr_Int : SI<opc, MRMSrcReg, (outs DstRC:$dst), (ins DstRC:$src1, SrcRC:$src2),
1026                   !if(Is2Addr,
1027                       !strconcat(asm, "\t{$src2, $dst|$dst, $src2}"),
1028                       !strconcat(asm, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
1029                   []>, Sched<[sched]>;
1030   let mayLoad = 1 in
1031   def rm_Int : SI<opc, MRMSrcMem, (outs DstRC:$dst),
1032                   (ins DstRC:$src1, x86memop:$src2),
1033                   !if(Is2Addr,
1034                       !strconcat(asm, "\t{$src2, $dst|$dst, $src2}"),
1035                       !strconcat(asm, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
1036                   []>, Sched<[sched.Folded, ReadAfterLd]>;
1037 }
1038 }
1039
1040 let Predicates = [UseAVX] in {
1041 defm VCVTSD2SI : sse12_cvt_sint<0x2D, VR128, GR32,
1042                   int_x86_sse2_cvtsd2si, sdmem, sse_load_f64, "cvtsd2si",
1043                   WriteCvtSD2I>, XD, VEX, VEX_LIG;
1044 defm VCVTSD2SI64 : sse12_cvt_sint<0x2D, VR128, GR64,
1045                     int_x86_sse2_cvtsd2si64, sdmem, sse_load_f64, "cvtsd2si",
1046                     WriteCvtSD2I>, XD, VEX, VEX_W, VEX_LIG;
1047 }
1048 defm CVTSD2SI : sse12_cvt_sint<0x2D, VR128, GR32, int_x86_sse2_cvtsd2si,
1049                  sdmem, sse_load_f64, "cvtsd2si", WriteCvtSD2I>, XD;
1050 defm CVTSD2SI64 : sse12_cvt_sint<0x2D, VR128, GR64, int_x86_sse2_cvtsd2si64,
1051                    sdmem, sse_load_f64, "cvtsd2si", WriteCvtSD2I>, XD, REX_W;
1052
1053
1054 let isCodeGenOnly = 1 in {
1055   let Predicates = [UseAVX] in {
1056   defm VCVTSI2SS : sse12_cvt_sint_3addr<0x2A, GR32, VR128,
1057             i32mem, "cvtsi2ss{l}", WriteCvtI2SS, 0>, XS, VEX_4V;
1058   defm VCVTSI642SS : sse12_cvt_sint_3addr<0x2A, GR64, VR128,
1059             i64mem, "cvtsi2ss{q}", WriteCvtI2SS, 0>, XS, VEX_4V, VEX_W;
1060   defm VCVTSI2SD : sse12_cvt_sint_3addr<0x2A, GR32, VR128,
1061             i32mem, "cvtsi2sd{l}", WriteCvtI2SD, 0>, XD, VEX_4V;
1062   defm VCVTSI642SD : sse12_cvt_sint_3addr<0x2A, GR64, VR128,
1063             i64mem, "cvtsi2sd{q}", WriteCvtI2SD, 0>, XD, VEX_4V, VEX_W;
1064   }
1065   let Constraints = "$src1 = $dst" in {
1066     defm CVTSI2SS : sse12_cvt_sint_3addr<0x2A, GR32, VR128,
1067                           i32mem, "cvtsi2ss{l}", WriteCvtI2SS>, XS;
1068     defm CVTSI642SS : sse12_cvt_sint_3addr<0x2A, GR64, VR128,
1069                           i64mem, "cvtsi2ss{q}", WriteCvtI2SS>, XS, REX_W;
1070     defm CVTSI2SD : sse12_cvt_sint_3addr<0x2A, GR32, VR128,
1071                           i32mem, "cvtsi2sd{l}", WriteCvtI2SD>, XD;
1072     defm CVTSI642SD : sse12_cvt_sint_3addr<0x2A, GR64, VR128,
1073                           i64mem, "cvtsi2sd{q}", WriteCvtI2SD>, XD, REX_W;
1074   }
1075 } // isCodeGenOnly = 1
1076
1077 /// SSE 1 Only
1078
1079 // Aliases for intrinsics
1080 let isCodeGenOnly = 1 in {
1081 let Predicates = [UseAVX] in {
1082 defm VCVTTSS2SI : sse12_cvt_sint<0x2C, VR128, GR32, int_x86_sse_cvttss2si,
1083                                 ssmem, sse_load_f32, "cvttss2si",
1084                                 WriteCvtSS2I>, XS, VEX;
1085 defm VCVTTSS2SI64 : sse12_cvt_sint<0x2C, VR128, GR64,
1086                                int_x86_sse_cvttss2si64, ssmem, sse_load_f32,
1087                                "cvttss2si", WriteCvtSS2I>,
1088                                XS, VEX, VEX_W;
1089 defm VCVTTSD2SI : sse12_cvt_sint<0x2C, VR128, GR32, int_x86_sse2_cvttsd2si,
1090                                 sdmem, sse_load_f64, "cvttsd2si",
1091                                 WriteCvtSS2I>, XD, VEX;
1092 defm VCVTTSD2SI64 : sse12_cvt_sint<0x2C, VR128, GR64,
1093                               int_x86_sse2_cvttsd2si64, sdmem, sse_load_f64,
1094                               "cvttsd2si", WriteCvtSS2I>,
1095                               XD, VEX, VEX_W;
1096 }
1097 defm CVTTSS2SI : sse12_cvt_sint<0x2C, VR128, GR32, int_x86_sse_cvttss2si,
1098                                     ssmem, sse_load_f32, "cvttss2si",
1099                                     WriteCvtSS2I>, XS;
1100 defm CVTTSS2SI64 : sse12_cvt_sint<0x2C, VR128, GR64,
1101                                    int_x86_sse_cvttss2si64, ssmem, sse_load_f32,
1102                                    "cvttss2si", WriteCvtSS2I>, XS, REX_W;
1103 defm CVTTSD2SI : sse12_cvt_sint<0x2C, VR128, GR32, int_x86_sse2_cvttsd2si,
1104                                     sdmem, sse_load_f64, "cvttsd2si",
1105                                     WriteCvtSD2I>, XD;
1106 defm CVTTSD2SI64 : sse12_cvt_sint<0x2C, VR128, GR64,
1107                                   int_x86_sse2_cvttsd2si64, sdmem, sse_load_f64,
1108                                   "cvttsd2si", WriteCvtSD2I>, XD, REX_W;
1109 } // isCodeGenOnly = 1
1110
1111 let Predicates = [UseAVX] in {
1112 defm VCVTSS2SI   : sse12_cvt_sint<0x2D, VR128, GR32, int_x86_sse_cvtss2si,
1113                                   ssmem, sse_load_f32, "cvtss2si",
1114                                   WriteCvtSS2I>, XS, VEX, VEX_LIG;
1115 defm VCVTSS2SI64 : sse12_cvt_sint<0x2D, VR128, GR64, int_x86_sse_cvtss2si64,
1116                                   ssmem, sse_load_f32, "cvtss2si",
1117                                   WriteCvtSS2I>, XS, VEX, VEX_W, VEX_LIG;
1118 }
1119 defm CVTSS2SI : sse12_cvt_sint<0x2D, VR128, GR32, int_x86_sse_cvtss2si,
1120                                ssmem, sse_load_f32, "cvtss2si",
1121                                WriteCvtSS2I>, XS;
1122 defm CVTSS2SI64 : sse12_cvt_sint<0x2D, VR128, GR64, int_x86_sse_cvtss2si64,
1123                                  ssmem, sse_load_f32, "cvtss2si",
1124                                  WriteCvtSS2I>, XS, REX_W;
1125
1126 defm VCVTDQ2PS   : sse12_cvt_p<0x5B, VR128, i128mem, v4f32, v4i32, loadv2i64,
1127                                "vcvtdq2ps\t{$src, $dst|$dst, $src}",
1128                                SSEPackedSingle, WriteCvtI2PS>,
1129                                PS, VEX, Requires<[HasAVX, NoVLX]>, VEX_WIG;
1130 defm VCVTDQ2PSY  : sse12_cvt_p<0x5B, VR256, i256mem, v8f32, v8i32, loadv4i64,
1131                                "vcvtdq2ps\t{$src, $dst|$dst, $src}",
1132                                SSEPackedSingle, WriteCvtI2PSY>,
1133                                PS, VEX, VEX_L, Requires<[HasAVX, NoVLX]>, VEX_WIG;
1134
1135 defm CVTDQ2PS : sse12_cvt_p<0x5B, VR128, i128mem, v4f32, v4i32, memopv2i64,
1136                             "cvtdq2ps\t{$src, $dst|$dst, $src}",
1137                             SSEPackedSingle, WriteCvtI2PS>,
1138                             PS, Requires<[UseSSE2]>;
1139
1140 let Predicates = [UseAVX] in {
1141 def : InstAlias<"vcvtss2si{l}\t{$src, $dst|$dst, $src}",
1142                 (VCVTSS2SIrr_Int GR32:$dst, VR128:$src), 0, "att">;
1143 def : InstAlias<"vcvtss2si{l}\t{$src, $dst|$dst, $src}",
1144                 (VCVTSS2SIrm_Int GR32:$dst, ssmem:$src), 0, "att">;
1145 def : InstAlias<"vcvtsd2si{l}\t{$src, $dst|$dst, $src}",
1146                 (VCVTSD2SIrr_Int GR32:$dst, VR128:$src), 0, "att">;
1147 def : InstAlias<"vcvtsd2si{l}\t{$src, $dst|$dst, $src}",
1148                 (VCVTSD2SIrm_Int GR32:$dst, sdmem:$src), 0, "att">;
1149 def : InstAlias<"vcvtss2si{q}\t{$src, $dst|$dst, $src}",
1150                 (VCVTSS2SI64rr_Int GR64:$dst, VR128:$src), 0, "att">;
1151 def : InstAlias<"vcvtss2si{q}\t{$src, $dst|$dst, $src}",
1152                 (VCVTSS2SI64rm_Int GR64:$dst, ssmem:$src), 0, "att">;
1153 def : InstAlias<"vcvtsd2si{q}\t{$src, $dst|$dst, $src}",
1154                 (VCVTSD2SI64rr_Int GR64:$dst, VR128:$src), 0, "att">;
1155 def : InstAlias<"vcvtsd2si{q}\t{$src, $dst|$dst, $src}",
1156                 (VCVTSD2SI64rm_Int GR64:$dst, sdmem:$src), 0, "att">;
1157 }
1158
1159 def : InstAlias<"cvtss2si{l}\t{$src, $dst|$dst, $src}",
1160                 (CVTSS2SIrr_Int GR32:$dst, VR128:$src), 0, "att">;
1161 def : InstAlias<"cvtss2si{l}\t{$src, $dst|$dst, $src}",
1162                 (CVTSS2SIrm_Int GR32:$dst, ssmem:$src), 0, "att">;
1163 def : InstAlias<"cvtsd2si{l}\t{$src, $dst|$dst, $src}",
1164                 (CVTSD2SIrr_Int GR32:$dst, VR128:$src), 0, "att">;
1165 def : InstAlias<"cvtsd2si{l}\t{$src, $dst|$dst, $src}",
1166                 (CVTSD2SIrm_Int GR32:$dst, sdmem:$src), 0, "att">;
1167 def : InstAlias<"cvtss2si{q}\t{$src, $dst|$dst, $src}",
1168                 (CVTSS2SI64rr_Int GR64:$dst, VR128:$src), 0, "att">;
1169 def : InstAlias<"cvtss2si{q}\t{$src, $dst|$dst, $src}",
1170                 (CVTSS2SI64rm_Int GR64:$dst, ssmem:$src), 0, "att">;
1171 def : InstAlias<"cvtsd2si{q}\t{$src, $dst|$dst, $src}",
1172                 (CVTSD2SI64rr_Int GR64:$dst, VR128:$src), 0, "att">;
1173 def : InstAlias<"cvtsd2si{q}\t{$src, $dst|$dst, $src}",
1174                 (CVTSD2SI64rm_Int GR64:$dst, sdmem:$src), 0, "att">;
1175
1176 /// SSE 2 Only
1177
1178 // Convert scalar double to scalar single
1179 let hasSideEffects = 0, Predicates = [UseAVX] in {
1180 def VCVTSD2SSrr  : VSDI<0x5A, MRMSrcReg, (outs FR32:$dst),
1181                         (ins FR32:$src1, FR64:$src2),
1182                         "cvtsd2ss\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>,
1183                         VEX_4V, VEX_LIG, VEX_WIG,
1184                         Sched<[WriteCvtSD2SS]>;
1185 let mayLoad = 1 in
1186 def VCVTSD2SSrm  : I<0x5A, MRMSrcMem, (outs FR32:$dst),
1187                      (ins FR32:$src1, f64mem:$src2),
1188                      "vcvtsd2ss\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>,
1189                      XD, VEX_4V, VEX_LIG, VEX_WIG,
1190                      Sched<[WriteCvtSD2SS.Folded, ReadAfterLd]>;
1191 }
1192
1193 def : Pat<(f32 (fpround FR64:$src)),
1194             (VCVTSD2SSrr (f32 (IMPLICIT_DEF)), FR64:$src)>,
1195           Requires<[UseAVX]>;
1196
1197 def CVTSD2SSrr  : SDI<0x5A, MRMSrcReg, (outs FR32:$dst), (ins FR64:$src),
1198                       "cvtsd2ss\t{$src, $dst|$dst, $src}",
1199                       [(set FR32:$dst, (fpround FR64:$src))]>,
1200                       Sched<[WriteCvtSD2SS]>;
1201 def CVTSD2SSrm  : I<0x5A, MRMSrcMem, (outs FR32:$dst), (ins f64mem:$src),
1202                     "cvtsd2ss\t{$src, $dst|$dst, $src}",
1203                     [(set FR32:$dst, (fpround (loadf64 addr:$src)))]>,
1204                     XD, Requires<[UseSSE2, OptForSize]>,
1205                     Sched<[WriteCvtSD2SS.Folded]>;
1206
1207 let isCodeGenOnly = 1 in {
1208 def VCVTSD2SSrr_Int: I<0x5A, MRMSrcReg,
1209                        (outs VR128:$dst), (ins VR128:$src1, VR128:$src2),
1210                        "vcvtsd2ss\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1211                        [(set VR128:$dst,
1212                          (int_x86_sse2_cvtsd2ss VR128:$src1, VR128:$src2))]>,
1213                        XD, VEX_4V, VEX_WIG, Requires<[HasAVX]>,
1214                        Sched<[WriteCvtSD2SS]>;
1215 def VCVTSD2SSrm_Int: I<0x5A, MRMSrcMem,
1216                        (outs VR128:$dst), (ins VR128:$src1, sdmem:$src2),
1217                        "vcvtsd2ss\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1218                        [(set VR128:$dst, (int_x86_sse2_cvtsd2ss
1219                                           VR128:$src1, sse_load_f64:$src2))]>,
1220                        XD, VEX_4V, VEX_WIG, Requires<[HasAVX]>,
1221                        Sched<[WriteCvtSD2SS.Folded, ReadAfterLd]>;
1222 let Constraints = "$src1 = $dst" in {
1223 def CVTSD2SSrr_Int: I<0x5A, MRMSrcReg,
1224                        (outs VR128:$dst), (ins VR128:$src1, VR128:$src2),
1225                        "cvtsd2ss\t{$src2, $dst|$dst, $src2}",
1226                        [(set VR128:$dst,
1227                          (int_x86_sse2_cvtsd2ss VR128:$src1, VR128:$src2))]>,
1228                        XD, Requires<[UseSSE2]>, Sched<[WriteCvtSD2SS]>;
1229 def CVTSD2SSrm_Int: I<0x5A, MRMSrcMem,
1230                        (outs VR128:$dst), (ins VR128:$src1, sdmem:$src2),
1231                        "cvtsd2ss\t{$src2, $dst|$dst, $src2}",
1232                        [(set VR128:$dst, (int_x86_sse2_cvtsd2ss
1233                                           VR128:$src1, sse_load_f64:$src2))]>,
1234                        XD, Requires<[UseSSE2]>,
1235                        Sched<[WriteCvtSD2SS.Folded, ReadAfterLd]>;
1236 }
1237 } // isCodeGenOnly = 1
1238
1239 // Convert scalar single to scalar double
1240 // SSE2 instructions with XS prefix
1241 let hasSideEffects = 0 in {
1242 def VCVTSS2SDrr : I<0x5A, MRMSrcReg, (outs FR64:$dst),
1243                     (ins FR64:$src1, FR32:$src2),
1244                     "vcvtss2sd\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>,
1245                     XS, VEX_4V, VEX_LIG, VEX_WIG,
1246                     Sched<[WriteCvtSS2SD]>, Requires<[UseAVX]>;
1247 let mayLoad = 1 in
1248 def VCVTSS2SDrm : I<0x5A, MRMSrcMem, (outs FR64:$dst),
1249                     (ins FR64:$src1, f32mem:$src2),
1250                     "vcvtss2sd\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>,
1251                     XS, VEX_4V, VEX_LIG, VEX_WIG,
1252                     Sched<[WriteCvtSS2SD.Folded, ReadAfterLd]>,
1253                     Requires<[UseAVX, OptForSize]>;
1254 }
1255
1256 def : Pat<(f64 (fpextend FR32:$src)),
1257     (VCVTSS2SDrr (f64 (IMPLICIT_DEF)), FR32:$src)>, Requires<[UseAVX]>;
1258 def : Pat<(fpextend (loadf32 addr:$src)),
1259     (VCVTSS2SDrm (f64 (IMPLICIT_DEF)), addr:$src)>, Requires<[UseAVX, OptForSize]>;
1260
1261 def : Pat<(extloadf32 addr:$src),
1262     (VCVTSS2SDrm (f64 (IMPLICIT_DEF)), addr:$src)>,
1263     Requires<[UseAVX, OptForSize]>;
1264 def : Pat<(extloadf32 addr:$src),
1265     (VCVTSS2SDrr (f64 (IMPLICIT_DEF)), (VMOVSSrm addr:$src))>,
1266     Requires<[UseAVX, OptForSpeed]>;
1267
1268 def CVTSS2SDrr : I<0x5A, MRMSrcReg, (outs FR64:$dst), (ins FR32:$src),
1269                    "cvtss2sd\t{$src, $dst|$dst, $src}",
1270                    [(set FR64:$dst, (fpextend FR32:$src))]>,
1271                    XS, Requires<[UseSSE2]>, Sched<[WriteCvtSS2SD]>;
1272 def CVTSS2SDrm : I<0x5A, MRMSrcMem, (outs FR64:$dst), (ins f32mem:$src),
1273                    "cvtss2sd\t{$src, $dst|$dst, $src}",
1274                    [(set FR64:$dst, (extloadf32 addr:$src))]>,
1275                    XS, Requires<[UseSSE2, OptForSize]>,
1276                    Sched<[WriteCvtSS2SD.Folded]>;
1277
1278 // extload f32 -> f64.  This matches load+fpextend because we have a hack in
1279 // the isel (PreprocessForFPConvert) that can introduce loads after dag
1280 // combine.
1281 // Since these loads aren't folded into the fpextend, we have to match it
1282 // explicitly here.
1283 def : Pat<(fpextend (loadf32 addr:$src)),
1284           (CVTSS2SDrm addr:$src)>, Requires<[UseSSE2, OptForSize]>;
1285 def : Pat<(extloadf32 addr:$src),
1286           (CVTSS2SDrr (MOVSSrm addr:$src))>, Requires<[UseSSE2, OptForSpeed]>;
1287
1288 let isCodeGenOnly = 1, hasSideEffects = 0 in {
1289 def VCVTSS2SDrr_Int: I<0x5A, MRMSrcReg,
1290                       (outs VR128:$dst), (ins VR128:$src1, VR128:$src2),
1291                     "vcvtss2sd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1292                     []>, XS, VEX_4V, VEX_WIG,
1293                     Requires<[HasAVX]>, Sched<[WriteCvtSS2SD]>;
1294 let mayLoad = 1 in
1295 def VCVTSS2SDrm_Int: I<0x5A, MRMSrcMem,
1296                       (outs VR128:$dst), (ins VR128:$src1, ssmem:$src2),
1297                     "vcvtss2sd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1298                     []>, XS, VEX_4V, VEX_WIG, Requires<[HasAVX]>,
1299                     Sched<[WriteCvtSS2SD.Folded, ReadAfterLd]>;
1300 let Constraints = "$src1 = $dst" in { // SSE2 instructions with XS prefix
1301 def CVTSS2SDrr_Int: I<0x5A, MRMSrcReg,
1302                       (outs VR128:$dst), (ins VR128:$src1, VR128:$src2),
1303                     "cvtss2sd\t{$src2, $dst|$dst, $src2}",
1304                     []>, XS, Requires<[UseSSE2]>,
1305                     Sched<[WriteCvtSS2SD]>;
1306 let mayLoad = 1 in
1307 def CVTSS2SDrm_Int: I<0x5A, MRMSrcMem,
1308                       (outs VR128:$dst), (ins VR128:$src1, ssmem:$src2),
1309                     "cvtss2sd\t{$src2, $dst|$dst, $src2}",
1310                     []>, XS, Requires<[UseSSE2]>,
1311                     Sched<[WriteCvtSS2SD.Folded, ReadAfterLd]>;
1312 }
1313 } // isCodeGenOnly = 1
1314
1315 // Patterns used for matching (v)cvtsi2ss, (v)cvtsi2sd, (v)cvtsd2ss and
1316 // (v)cvtss2sd intrinsic sequences from clang which produce unnecessary
1317 // vmovs{s,d} instructions
1318 let Predicates = [UseAVX] in {
1319 def : Pat<(v4f32 (X86Movss
1320                    (v4f32 VR128:$dst),
1321                    (v4f32 (scalar_to_vector
1322                      (f32 (fpround (f64 (extractelt VR128:$src, (iPTR 0))))))))),
1323           (VCVTSD2SSrr_Int VR128:$dst, VR128:$src)>;
1324
1325 def : Pat<(v2f64 (X86Movsd
1326                    (v2f64 VR128:$dst),
1327                    (v2f64 (scalar_to_vector
1328                      (f64 (fpextend (f32 (extractelt VR128:$src, (iPTR 0))))))))),
1329           (VCVTSS2SDrr_Int VR128:$dst, VR128:$src)>;
1330
1331 def : Pat<(v4f32 (X86Movss
1332                    (v4f32 VR128:$dst),
1333                    (v4f32 (scalar_to_vector (f32 (sint_to_fp GR64:$src)))))),
1334           (VCVTSI642SSrr_Int VR128:$dst, GR64:$src)>;
1335
1336 def : Pat<(v4f32 (X86Movss
1337                    (v4f32 VR128:$dst),
1338                    (v4f32 (scalar_to_vector (f32 (sint_to_fp (loadi64 addr:$src))))))),
1339           (VCVTSI642SSrm_Int VR128:$dst, addr:$src)>;
1340
1341 def : Pat<(v4f32 (X86Movss
1342                    (v4f32 VR128:$dst),
1343                    (v4f32 (scalar_to_vector (f32 (sint_to_fp GR32:$src)))))),
1344           (VCVTSI2SSrr_Int VR128:$dst, GR32:$src)>;
1345
1346 def : Pat<(v4f32 (X86Movss
1347                    (v4f32 VR128:$dst),
1348                    (v4f32 (scalar_to_vector (f32 (sint_to_fp (loadi32 addr:$src))))))),
1349           (VCVTSI2SSrm_Int VR128:$dst, addr:$src)>;
1350
1351 def : Pat<(v2f64 (X86Movsd
1352                    (v2f64 VR128:$dst),
1353                    (v2f64 (scalar_to_vector (f64 (sint_to_fp GR64:$src)))))),
1354           (VCVTSI642SDrr_Int VR128:$dst, GR64:$src)>;
1355
1356 def : Pat<(v2f64 (X86Movsd
1357                    (v2f64 VR128:$dst),
1358                    (v2f64 (scalar_to_vector (f64 (sint_to_fp (loadi64 addr:$src))))))),
1359           (VCVTSI642SDrm_Int VR128:$dst, addr:$src)>;
1360
1361 def : Pat<(v2f64 (X86Movsd
1362                    (v2f64 VR128:$dst),
1363                    (v2f64 (scalar_to_vector (f64 (sint_to_fp GR32:$src)))))),
1364           (VCVTSI2SDrr_Int VR128:$dst, GR32:$src)>;
1365
1366 def : Pat<(v2f64 (X86Movsd
1367                    (v2f64 VR128:$dst),
1368                    (v2f64 (scalar_to_vector (f64 (sint_to_fp (loadi32 addr:$src))))))),
1369           (VCVTSI2SDrm_Int VR128:$dst, addr:$src)>;
1370 } // Predicates = [UseAVX]
1371
1372 let Predicates = [UseSSE2] in {
1373 def : Pat<(v4f32 (X86Movss
1374                    (v4f32 VR128:$dst),
1375                    (v4f32 (scalar_to_vector
1376                      (f32 (fpround (f64 (extractelt VR128:$src, (iPTR 0))))))))),
1377           (CVTSD2SSrr_Int VR128:$dst, VR128:$src)>;
1378
1379 def : Pat<(v2f64 (X86Movsd
1380                    (v2f64 VR128:$dst),
1381                    (v2f64 (scalar_to_vector
1382                      (f64 (fpextend (f32 (extractelt VR128:$src, (iPTR 0))))))))),
1383           (CVTSS2SDrr_Int VR128:$dst, VR128:$src)>;
1384
1385 def : Pat<(v2f64 (X86Movsd
1386                    (v2f64 VR128:$dst),
1387                    (v2f64 (scalar_to_vector (f64 (sint_to_fp GR64:$src)))))),
1388           (CVTSI642SDrr_Int VR128:$dst, GR64:$src)>;
1389
1390 def : Pat<(v2f64 (X86Movsd
1391                    (v2f64 VR128:$dst),
1392                    (v2f64 (scalar_to_vector (f64 (sint_to_fp (loadi64 addr:$src))))))),
1393           (CVTSI642SDrm_Int VR128:$dst, addr:$src)>;
1394
1395 def : Pat<(v2f64 (X86Movsd
1396                    (v2f64 VR128:$dst),
1397                    (v2f64 (scalar_to_vector (f64 (sint_to_fp GR32:$src)))))),
1398           (CVTSI2SDrr_Int VR128:$dst, GR32:$src)>;
1399
1400 def : Pat<(v2f64 (X86Movsd
1401                    (v2f64 VR128:$dst),
1402                    (v2f64 (scalar_to_vector (f64 (sint_to_fp (loadi32 addr:$src))))))),
1403           (CVTSI2SDrm_Int VR128:$dst, addr:$src)>;
1404 } // Predicates = [UseSSE2]
1405
1406 let Predicates = [UseSSE1] in {
1407 def : Pat<(v4f32 (X86Movss
1408                    (v4f32 VR128:$dst),
1409                    (v4f32 (scalar_to_vector (f32 (sint_to_fp GR64:$src)))))),
1410           (CVTSI642SSrr_Int VR128:$dst, GR64:$src)>;
1411
1412 def : Pat<(v4f32 (X86Movss
1413                    (v4f32 VR128:$dst),
1414                    (v4f32 (scalar_to_vector (f32 (sint_to_fp (loadi64 addr:$src))))))),
1415           (CVTSI642SSrm_Int VR128:$dst, addr:$src)>;
1416
1417 def : Pat<(v4f32 (X86Movss
1418                    (v4f32 VR128:$dst),
1419                    (v4f32 (scalar_to_vector (f32 (sint_to_fp GR32:$src)))))),
1420           (CVTSI2SSrr_Int VR128:$dst, GR32:$src)>;
1421
1422 def : Pat<(v4f32 (X86Movss
1423                    (v4f32 VR128:$dst),
1424                    (v4f32 (scalar_to_vector (f32 (sint_to_fp (loadi32 addr:$src))))))),
1425           (CVTSI2SSrm_Int VR128:$dst, addr:$src)>;
1426 } // Predicates = [UseSSE1]
1427
1428 let Predicates = [HasAVX, NoVLX] in {
1429 // Convert packed single/double fp to doubleword
1430 def VCVTPS2DQrr : VPDI<0x5B, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1431                        "cvtps2dq\t{$src, $dst|$dst, $src}",
1432                        [(set VR128:$dst, (v4i32 (X86cvtp2Int (v4f32 VR128:$src))))]>,
1433                        VEX, Sched<[WriteCvtPS2I]>, VEX_WIG;
1434 def VCVTPS2DQrm : VPDI<0x5B, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1435                        "cvtps2dq\t{$src, $dst|$dst, $src}",
1436                        [(set VR128:$dst,
1437                          (v4i32 (X86cvtp2Int (loadv4f32 addr:$src))))]>,
1438                        VEX, Sched<[WriteCvtPS2ILd]>, VEX_WIG;
1439 def VCVTPS2DQYrr : VPDI<0x5B, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
1440                         "cvtps2dq\t{$src, $dst|$dst, $src}",
1441                         [(set VR256:$dst,
1442                           (v8i32 (X86cvtp2Int (v8f32 VR256:$src))))]>,
1443                         VEX, VEX_L, Sched<[WriteCvtPS2IY]>, VEX_WIG;
1444 def VCVTPS2DQYrm : VPDI<0x5B, MRMSrcMem, (outs VR256:$dst), (ins f256mem:$src),
1445                         "cvtps2dq\t{$src, $dst|$dst, $src}",
1446                         [(set VR256:$dst,
1447                           (v8i32 (X86cvtp2Int (loadv8f32 addr:$src))))]>,
1448                         VEX, VEX_L, Sched<[WriteCvtPS2IYLd]>, VEX_WIG;
1449 }
1450 def CVTPS2DQrr : PDI<0x5B, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1451                      "cvtps2dq\t{$src, $dst|$dst, $src}",
1452                      [(set VR128:$dst, (v4i32 (X86cvtp2Int (v4f32 VR128:$src))))]>,
1453                      Sched<[WriteCvtPS2I]>;
1454 def CVTPS2DQrm : PDI<0x5B, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1455                      "cvtps2dq\t{$src, $dst|$dst, $src}",
1456                      [(set VR128:$dst,
1457                        (v4i32 (X86cvtp2Int (memopv4f32 addr:$src))))]>,
1458                      Sched<[WriteCvtPS2ILd]>;
1459
1460
1461 // Convert Packed Double FP to Packed DW Integers
1462 let Predicates = [HasAVX, NoVLX] in {
1463 // The assembler can recognize rr 256-bit instructions by seeing a ymm
1464 // register, but the same isn't true when using memory operands instead.
1465 // Provide other assembly rr and rm forms to address this explicitly.
1466 def VCVTPD2DQrr  : SDI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1467                        "vcvtpd2dq\t{$src, $dst|$dst, $src}",
1468                        [(set VR128:$dst,
1469                          (v4i32 (X86cvtp2Int (v2f64 VR128:$src))))]>,
1470                        VEX, Sched<[WriteCvtPD2I]>, VEX_WIG;
1471
1472 // XMM only
1473 def : InstAlias<"vcvtpd2dqx\t{$src, $dst|$dst, $src}",
1474                 (VCVTPD2DQrr VR128:$dst, VR128:$src), 0>;
1475 def VCVTPD2DQrm : SDI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1476                       "vcvtpd2dq{x}\t{$src, $dst|$dst, $src}",
1477                       [(set VR128:$dst,
1478                         (v4i32 (X86cvtp2Int (loadv2f64 addr:$src))))]>, VEX,
1479                       Sched<[WriteCvtPD2ILd]>, VEX_WIG;
1480 def : InstAlias<"vcvtpd2dqx\t{$src, $dst|$dst, $src}",
1481                 (VCVTPD2DQrm VR128:$dst, f128mem:$src), 0, "intel">;
1482
1483 // YMM only
1484 def VCVTPD2DQYrr : SDI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR256:$src),
1485                        "vcvtpd2dq\t{$src, $dst|$dst, $src}",
1486                        [(set VR128:$dst,
1487                          (v4i32 (X86cvtp2Int (v4f64 VR256:$src))))]>,
1488                        VEX, VEX_L, Sched<[WriteCvtPD2IY]>, VEX_WIG;
1489 def VCVTPD2DQYrm : SDI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f256mem:$src),
1490                        "vcvtpd2dq{y}\t{$src, $dst|$dst, $src}",
1491                        [(set VR128:$dst,
1492                          (v4i32 (X86cvtp2Int (loadv4f64 addr:$src))))]>,
1493                        VEX, VEX_L, Sched<[WriteCvtPD2IYLd]>, VEX_WIG;
1494 def : InstAlias<"vcvtpd2dqy\t{$src, $dst|$dst, $src}",
1495                 (VCVTPD2DQYrr VR128:$dst, VR256:$src), 0>;
1496 def : InstAlias<"vcvtpd2dqy\t{$src, $dst|$dst, $src}",
1497                 (VCVTPD2DQYrm VR128:$dst, f256mem:$src), 0, "intel">;
1498 }
1499
1500 def CVTPD2DQrm  : SDI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1501                       "cvtpd2dq\t{$src, $dst|$dst, $src}",
1502                       [(set VR128:$dst,
1503                         (v4i32 (X86cvtp2Int (memopv2f64 addr:$src))))]>,
1504                       Sched<[WriteCvtPD2ILd]>;
1505 def CVTPD2DQrr  : SDI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1506                       "cvtpd2dq\t{$src, $dst|$dst, $src}",
1507                       [(set VR128:$dst,
1508                         (v4i32 (X86cvtp2Int (v2f64 VR128:$src))))]>,
1509                       Sched<[WriteCvtPD2I]>;
1510
1511 // Convert with truncation packed single/double fp to doubleword
1512 // SSE2 packed instructions with XS prefix
1513 let Predicates = [HasAVX, NoVLX] in {
1514 def VCVTTPS2DQrr : VS2SI<0x5B, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1515                          "cvttps2dq\t{$src, $dst|$dst, $src}",
1516                          [(set VR128:$dst,
1517                            (v4i32 (X86cvttp2si (v4f32 VR128:$src))))]>,
1518                          VEX, Sched<[WriteCvtPS2I]>, VEX_WIG;
1519 def VCVTTPS2DQrm : VS2SI<0x5B, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1520                          "cvttps2dq\t{$src, $dst|$dst, $src}",
1521                          [(set VR128:$dst,
1522                            (v4i32 (X86cvttp2si (loadv4f32 addr:$src))))]>,
1523                          VEX, Sched<[WriteCvtPS2ILd]>, VEX_WIG;
1524 def VCVTTPS2DQYrr : VS2SI<0x5B, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
1525                           "cvttps2dq\t{$src, $dst|$dst, $src}",
1526                           [(set VR256:$dst,
1527                             (v8i32 (X86cvttp2si (v8f32 VR256:$src))))]>,
1528                           VEX, VEX_L, Sched<[WriteCvtPS2IY]>, VEX_WIG;
1529 def VCVTTPS2DQYrm : VS2SI<0x5B, MRMSrcMem, (outs VR256:$dst), (ins f256mem:$src),
1530                           "cvttps2dq\t{$src, $dst|$dst, $src}",
1531                           [(set VR256:$dst,
1532                             (v8i32 (X86cvttp2si (loadv8f32 addr:$src))))]>,
1533                           VEX, VEX_L,
1534                           Sched<[WriteCvtPS2IYLd]>, VEX_WIG;
1535 }
1536
1537 let Predicates = [HasAVX, NoVLX] in {
1538   def : Pat<(v4i32 (fp_to_sint (v4f32 VR128:$src))),
1539             (VCVTTPS2DQrr VR128:$src)>;
1540   def : Pat<(v4i32 (fp_to_sint (loadv4f32 addr:$src))),
1541             (VCVTTPS2DQrm addr:$src)>;
1542   def : Pat<(v8i32 (fp_to_sint (v8f32 VR256:$src))),
1543             (VCVTTPS2DQYrr VR256:$src)>;
1544   def : Pat<(v8i32 (fp_to_sint (loadv8f32 addr:$src))),
1545             (VCVTTPS2DQYrm addr:$src)>;
1546 }
1547
1548 def CVTTPS2DQrr : S2SI<0x5B, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1549                        "cvttps2dq\t{$src, $dst|$dst, $src}",
1550                        [(set VR128:$dst,
1551                          (v4i32 (X86cvttp2si (v4f32 VR128:$src))))]>,
1552                        Sched<[WriteCvtPS2I]>;
1553 def CVTTPS2DQrm : S2SI<0x5B, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1554                        "cvttps2dq\t{$src, $dst|$dst, $src}",
1555                        [(set VR128:$dst,
1556                          (v4i32 (X86cvttp2si (memopv4f32 addr:$src))))]>,
1557                        Sched<[WriteCvtPS2ILd]>;
1558
1559 let Predicates = [UseSSE2] in {
1560   def : Pat<(v4i32 (fp_to_sint (v4f32 VR128:$src))),
1561             (CVTTPS2DQrr VR128:$src)>;
1562   def : Pat<(v4i32 (fp_to_sint (memopv4f32 addr:$src))),
1563             (CVTTPS2DQrm addr:$src)>;
1564 }
1565
1566 let Predicates = [HasAVX, NoVLX] in
1567 def VCVTTPD2DQrr : VPDI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1568                         "cvttpd2dq\t{$src, $dst|$dst, $src}",
1569                         [(set VR128:$dst,
1570                           (v4i32 (X86cvttp2si (v2f64 VR128:$src))))]>,
1571                         VEX, Sched<[WriteCvtPD2I]>, VEX_WIG;
1572
1573 // The assembler can recognize rr 256-bit instructions by seeing a ymm
1574 // register, but the same isn't true when using memory operands instead.
1575 // Provide other assembly rr and rm forms to address this explicitly.
1576
1577 // XMM only
1578 def : InstAlias<"vcvttpd2dqx\t{$src, $dst|$dst, $src}",
1579                 (VCVTTPD2DQrr VR128:$dst, VR128:$src), 0>;
1580
1581 let Predicates = [HasAVX, NoVLX] in
1582 def VCVTTPD2DQrm : VPDI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1583                         "cvttpd2dq{x}\t{$src, $dst|$dst, $src}",
1584                         [(set VR128:$dst,
1585                           (v4i32 (X86cvttp2si (loadv2f64 addr:$src))))]>,
1586                         VEX, Sched<[WriteCvtPD2ILd]>, VEX_WIG;
1587 def : InstAlias<"vcvttpd2dqx\t{$src, $dst|$dst, $src}",
1588                 (VCVTTPD2DQrm VR128:$dst, f128mem:$src), 0, "intel">;
1589
1590 // YMM only
1591 let Predicates = [HasAVX, NoVLX] in {
1592 def VCVTTPD2DQYrr : VPDI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR256:$src),
1593                          "cvttpd2dq\t{$src, $dst|$dst, $src}",
1594                          [(set VR128:$dst,
1595                            (v4i32 (X86cvttp2si (v4f64 VR256:$src))))]>,
1596                          VEX, VEX_L, Sched<[WriteCvtPD2IY]>, VEX_WIG;
1597 def VCVTTPD2DQYrm : VPDI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f256mem:$src),
1598                          "cvttpd2dq{y}\t{$src, $dst|$dst, $src}",
1599                          [(set VR128:$dst,
1600                            (v4i32 (X86cvttp2si (loadv4f64 addr:$src))))]>,
1601                          VEX, VEX_L, Sched<[WriteCvtPD2IYLd]>, VEX_WIG;
1602 }
1603 def : InstAlias<"vcvttpd2dqy\t{$src, $dst|$dst, $src}",
1604                 (VCVTTPD2DQYrr VR128:$dst, VR256:$src), 0>;
1605 def : InstAlias<"vcvttpd2dqy\t{$src, $dst|$dst, $src}",
1606                 (VCVTTPD2DQYrm VR128:$dst, f256mem:$src), 0, "intel">;
1607
1608 let Predicates = [HasAVX, NoVLX] in {
1609   def : Pat<(v4i32 (fp_to_sint (v4f64 VR256:$src))),
1610             (VCVTTPD2DQYrr VR256:$src)>;
1611   def : Pat<(v4i32 (fp_to_sint (loadv4f64 addr:$src))),
1612             (VCVTTPD2DQYrm addr:$src)>;
1613 }
1614
1615 let Predicates = [HasAVX, NoVLX] in {
1616   def : Pat<(X86vzmovl (v2i64 (bitconvert
1617                                (v4i32 (X86cvtp2Int (v2f64 VR128:$src)))))),
1618             (VCVTPD2DQrr VR128:$src)>;
1619   def : Pat<(X86vzmovl (v2i64 (bitconvert
1620                                (v4i32 (X86cvtp2Int (loadv2f64 addr:$src)))))),
1621             (VCVTPD2DQrm addr:$src)>;
1622   def : Pat<(X86vzmovl (v2i64 (bitconvert
1623                                (v4i32 (X86cvttp2si (v2f64 VR128:$src)))))),
1624             (VCVTTPD2DQrr VR128:$src)>;
1625   def : Pat<(X86vzmovl (v2i64 (bitconvert
1626                                (v4i32 (X86cvttp2si (loadv2f64 addr:$src)))))),
1627             (VCVTTPD2DQrm addr:$src)>;
1628 } // Predicates = [HasAVX, NoVLX]
1629
1630 def CVTTPD2DQrr : PDI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1631                       "cvttpd2dq\t{$src, $dst|$dst, $src}",
1632                       [(set VR128:$dst,
1633                         (v4i32 (X86cvttp2si (v2f64 VR128:$src))))]>,
1634                       Sched<[WriteCvtPD2I]>;
1635 def CVTTPD2DQrm : PDI<0xE6, MRMSrcMem, (outs VR128:$dst),(ins f128mem:$src),
1636                       "cvttpd2dq\t{$src, $dst|$dst, $src}",
1637                       [(set VR128:$dst,
1638                         (v4i32 (X86cvttp2si (memopv2f64 addr:$src))))]>,
1639                       Sched<[WriteCvtPD2ILd]>;
1640
1641 let Predicates = [UseSSE2] in {
1642   def : Pat<(X86vzmovl (v2i64 (bitconvert
1643                                (v4i32 (X86cvtp2Int (v2f64 VR128:$src)))))),
1644             (CVTPD2DQrr VR128:$src)>;
1645   def : Pat<(X86vzmovl (v2i64 (bitconvert
1646                                (v4i32 (X86cvtp2Int (memopv2f64 addr:$src)))))),
1647             (CVTPD2DQrm addr:$src)>;
1648   def : Pat<(X86vzmovl (v2i64 (bitconvert
1649                                (v4i32 (X86cvttp2si (v2f64 VR128:$src)))))),
1650             (CVTTPD2DQrr VR128:$src)>;
1651   def : Pat<(X86vzmovl (v2i64 (bitconvert
1652                                (v4i32 (X86cvttp2si (memopv2f64 addr:$src)))))),
1653             (CVTTPD2DQrm addr:$src)>;
1654 } // Predicates = [UseSSE2]
1655
1656 // Convert packed single to packed double
1657 let Predicates = [HasAVX, NoVLX] in {
1658                   // SSE2 instructions without OpSize prefix
1659 def VCVTPS2PDrr : I<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1660                     "vcvtps2pd\t{$src, $dst|$dst, $src}",
1661                     [(set VR128:$dst, (v2f64 (X86vfpext (v4f32 VR128:$src))))]>,
1662                     PS, VEX, Sched<[WriteCvtPS2PD]>, VEX_WIG;
1663 def VCVTPS2PDrm : I<0x5A, MRMSrcMem, (outs VR128:$dst), (ins f64mem:$src),
1664                     "vcvtps2pd\t{$src, $dst|$dst, $src}",
1665                     [(set VR128:$dst, (v2f64 (extloadv2f32 addr:$src)))]>,
1666                     PS, VEX, Sched<[WriteCvtPS2PD.Folded]>, VEX_WIG;
1667 def VCVTPS2PDYrr : I<0x5A, MRMSrcReg, (outs VR256:$dst), (ins VR128:$src),
1668                      "vcvtps2pd\t{$src, $dst|$dst, $src}",
1669                      [(set VR256:$dst, (v4f64 (fpextend (v4f32 VR128:$src))))]>,
1670                      PS, VEX, VEX_L, Sched<[WriteCvtPS2PDY]>, VEX_WIG;
1671 def VCVTPS2PDYrm : I<0x5A, MRMSrcMem, (outs VR256:$dst), (ins f128mem:$src),
1672                      "vcvtps2pd\t{$src, $dst|$dst, $src}",
1673                      [(set VR256:$dst, (v4f64 (extloadv4f32 addr:$src)))]>,
1674                      PS, VEX, VEX_L, Sched<[WriteCvtPS2PDY.Folded]>, VEX_WIG;
1675 }
1676
1677 let Predicates = [UseSSE2] in {
1678 def CVTPS2PDrr : I<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1679                    "cvtps2pd\t{$src, $dst|$dst, $src}",
1680                    [(set VR128:$dst, (v2f64 (X86vfpext (v4f32 VR128:$src))))]>,
1681                    PS, Sched<[WriteCvtPS2PD]>;
1682 def CVTPS2PDrm : I<0x5A, MRMSrcMem, (outs VR128:$dst), (ins f64mem:$src),
1683                    "cvtps2pd\t{$src, $dst|$dst, $src}",
1684                    [(set VR128:$dst, (v2f64 (extloadv2f32 addr:$src)))]>,
1685                    PS, Sched<[WriteCvtPS2PD.Folded]>;
1686 }
1687
1688 // Convert Packed DW Integers to Packed Double FP
1689 let Predicates = [HasAVX, NoVLX] in {
1690 let hasSideEffects = 0, mayLoad = 1 in
1691 def VCVTDQ2PDrm  : S2SI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
1692                         "vcvtdq2pd\t{$src, $dst|$dst, $src}",
1693                         [(set VR128:$dst,
1694                           (v2f64 (X86VSintToFP (bc_v4i32 (loadv2i64 addr:$src)))))]>,
1695                         VEX, Sched<[WriteCvtI2PDLd]>, VEX_WIG;
1696 def VCVTDQ2PDrr  : S2SI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1697                         "vcvtdq2pd\t{$src, $dst|$dst, $src}",
1698                         [(set VR128:$dst,
1699                           (v2f64 (X86VSintToFP (v4i32 VR128:$src))))]>,
1700                         VEX, Sched<[WriteCvtI2PD]>, VEX_WIG;
1701 def VCVTDQ2PDYrm  : S2SI<0xE6, MRMSrcMem, (outs VR256:$dst), (ins i128mem:$src),
1702                          "vcvtdq2pd\t{$src, $dst|$dst, $src}",
1703                          [(set VR256:$dst,
1704                            (v4f64 (sint_to_fp (bc_v4i32 (loadv2i64 addr:$src)))))]>,
1705                          VEX, VEX_L, Sched<[WriteCvtI2PDYLd]>,
1706                          VEX_WIG;
1707 def VCVTDQ2PDYrr  : S2SI<0xE6, MRMSrcReg, (outs VR256:$dst), (ins VR128:$src),
1708                          "vcvtdq2pd\t{$src, $dst|$dst, $src}",
1709                          [(set VR256:$dst,
1710                            (v4f64 (sint_to_fp (v4i32 VR128:$src))))]>,
1711                          VEX, VEX_L, Sched<[WriteCvtI2PDY]>, VEX_WIG;
1712 }
1713
1714 let hasSideEffects = 0, mayLoad = 1 in
1715 def CVTDQ2PDrm  : S2SI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
1716                        "cvtdq2pd\t{$src, $dst|$dst, $src}",
1717                        [(set VR128:$dst,
1718                          (v2f64 (X86VSintToFP (bc_v4i32 (loadv2i64 addr:$src)))))]>,
1719                        Sched<[WriteCvtI2PDLd]>;
1720 def CVTDQ2PDrr  : S2SI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1721                        "cvtdq2pd\t{$src, $dst|$dst, $src}",
1722                        [(set VR128:$dst,
1723                          (v2f64 (X86VSintToFP (v4i32 VR128:$src))))]>,
1724                        Sched<[WriteCvtI2PD]>;
1725
1726 // AVX register conversion intrinsics
1727 let Predicates = [HasAVX, NoVLX] in {
1728   def : Pat<(v2f64 (X86VSintToFP (bc_v4i32 (v2i64 (scalar_to_vector (loadi64 addr:$src)))))),
1729             (VCVTDQ2PDrm addr:$src)>;
1730   def : Pat<(v2f64 (X86VSintToFP (bc_v4i32 (v2i64 (X86vzload addr:$src))))),
1731             (VCVTDQ2PDrm addr:$src)>;
1732 } // Predicates = [HasAVX, NoVLX]
1733
1734 // SSE2 register conversion intrinsics
1735 let Predicates = [UseSSE2] in {
1736   def : Pat<(v2f64 (X86VSintToFP (bc_v4i32 (v2i64 (scalar_to_vector (loadi64 addr:$src)))))),
1737             (CVTDQ2PDrm addr:$src)>;
1738   def : Pat<(v2f64 (X86VSintToFP (bc_v4i32 (v2i64 (X86vzload addr:$src))))),
1739             (CVTDQ2PDrm addr:$src)>;
1740 } // Predicates = [UseSSE2]
1741
1742 // Convert packed double to packed single
1743 // The assembler can recognize rr 256-bit instructions by seeing a ymm
1744 // register, but the same isn't true when using memory operands instead.
1745 // Provide other assembly rr and rm forms to address this explicitly.
1746 let Predicates = [HasAVX, NoVLX] in
1747 def VCVTPD2PSrr : VPDI<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1748                        "cvtpd2ps\t{$src, $dst|$dst, $src}",
1749                        [(set VR128:$dst, (X86vfpround (v2f64 VR128:$src)))]>,
1750                        VEX, Sched<[WriteCvtPD2PS]>, VEX_WIG;
1751
1752 // XMM only
1753 def : InstAlias<"vcvtpd2psx\t{$src, $dst|$dst, $src}",
1754                 (VCVTPD2PSrr VR128:$dst, VR128:$src), 0>;
1755 let Predicates = [HasAVX, NoVLX] in
1756 def VCVTPD2PSrm : VPDI<0x5A, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1757                        "cvtpd2ps{x}\t{$src, $dst|$dst, $src}",
1758                        [(set VR128:$dst, (X86vfpround (loadv2f64 addr:$src)))]>,
1759                        VEX, Sched<[WriteCvtPD2PS.Folded]>, VEX_WIG;
1760 def : InstAlias<"vcvtpd2psx\t{$src, $dst|$dst, $src}",
1761                 (VCVTPD2PSrm VR128:$dst, f128mem:$src), 0, "intel">;
1762
1763 // YMM only
1764 let Predicates = [HasAVX, NoVLX] in {
1765 def VCVTPD2PSYrr : VPDI<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR256:$src),
1766                         "cvtpd2ps\t{$src, $dst|$dst, $src}",
1767                         [(set VR128:$dst, (fpround VR256:$src))]>,
1768                         VEX, VEX_L, Sched<[WriteCvtPD2PSY]>, VEX_WIG;
1769 def VCVTPD2PSYrm : VPDI<0x5A, MRMSrcMem, (outs VR128:$dst), (ins f256mem:$src),
1770                         "cvtpd2ps{y}\t{$src, $dst|$dst, $src}",
1771                         [(set VR128:$dst, (fpround (loadv4f64 addr:$src)))]>,
1772                         VEX, VEX_L, Sched<[WriteCvtPD2PSY.Folded]>, VEX_WIG;
1773 }
1774 def : InstAlias<"vcvtpd2psy\t{$src, $dst|$dst, $src}",
1775                 (VCVTPD2PSYrr VR128:$dst, VR256:$src), 0>;
1776 def : InstAlias<"vcvtpd2psy\t{$src, $dst|$dst, $src}",
1777                 (VCVTPD2PSYrm VR128:$dst, f256mem:$src), 0, "intel">;
1778
1779 def CVTPD2PSrr : PDI<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1780                      "cvtpd2ps\t{$src, $dst|$dst, $src}",
1781                      [(set VR128:$dst, (X86vfpround (v2f64 VR128:$src)))]>,
1782                      Sched<[WriteCvtPD2PS]>;
1783 def CVTPD2PSrm : PDI<0x5A, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1784                      "cvtpd2ps\t{$src, $dst|$dst, $src}",
1785                      [(set VR128:$dst, (X86vfpround (memopv2f64 addr:$src)))]>,
1786                      Sched<[WriteCvtPD2PS.Folded]>;
1787
1788 // AVX 256-bit register conversion intrinsics
1789 // FIXME: Migrate SSE conversion intrinsics matching to use patterns as below
1790 // whenever possible to avoid declaring two versions of each one.
1791
1792 let Predicates = [HasAVX, NoVLX] in {
1793   // Match fpround and fpextend for 128/256-bit conversions
1794   def : Pat<(X86vzmovl (v2f64 (bitconvert
1795                                (v4f32 (X86vfpround (v2f64 VR128:$src)))))),
1796             (VCVTPD2PSrr VR128:$src)>;
1797   def : Pat<(X86vzmovl (v2f64 (bitconvert
1798                                (v4f32 (X86vfpround (loadv2f64 addr:$src)))))),
1799             (VCVTPD2PSrm addr:$src)>;
1800 }
1801
1802 let Predicates = [UseSSE2] in {
1803   // Match fpround and fpextend for 128 conversions
1804   def : Pat<(X86vzmovl (v2f64 (bitconvert
1805                                (v4f32 (X86vfpround (v2f64 VR128:$src)))))),
1806             (CVTPD2PSrr VR128:$src)>;
1807   def : Pat<(X86vzmovl (v2f64 (bitconvert
1808                                (v4f32 (X86vfpround (memopv2f64 addr:$src)))))),
1809             (CVTPD2PSrm addr:$src)>;
1810 }
1811
1812 //===----------------------------------------------------------------------===//
1813 // SSE 1 & 2 - Compare Instructions
1814 //===----------------------------------------------------------------------===//
1815
1816 // sse12_cmp_scalar - sse 1 & 2 compare scalar instructions
1817 multiclass sse12_cmp_scalar<RegisterClass RC, X86MemOperand x86memop,
1818                             Operand CC, SDNode OpNode, ValueType VT,
1819                             PatFrag ld_frag, string asm, string asm_alt,
1820                             X86FoldableSchedWrite sched> {
1821   let isCommutable = 1 in
1822   def rr : SIi8<0xC2, MRMSrcReg,
1823                 (outs RC:$dst), (ins RC:$src1, RC:$src2, CC:$cc), asm,
1824                 [(set RC:$dst, (OpNode (VT RC:$src1), RC:$src2, imm:$cc))]>,
1825                 Sched<[sched]>;
1826   def rm : SIi8<0xC2, MRMSrcMem,
1827                 (outs RC:$dst), (ins RC:$src1, x86memop:$src2, CC:$cc), asm,
1828                 [(set RC:$dst, (OpNode (VT RC:$src1),
1829                                          (ld_frag addr:$src2), imm:$cc))]>,
1830                 Sched<[sched.Folded, ReadAfterLd]>;
1831
1832   // Accept explicit immediate argument form instead of comparison code.
1833   let isAsmParserOnly = 1, hasSideEffects = 0 in {
1834     def rr_alt : SIi8<0xC2, MRMSrcReg, (outs RC:$dst),
1835                       (ins RC:$src1, RC:$src2, u8imm:$cc), asm_alt, []>,
1836                       Sched<[sched]>, NotMemoryFoldable;
1837     let mayLoad = 1 in
1838     def rm_alt : SIi8<0xC2, MRMSrcMem, (outs RC:$dst),
1839                       (ins RC:$src1, x86memop:$src2, u8imm:$cc), asm_alt, []>,
1840                       Sched<[sched.Folded, ReadAfterLd]>, NotMemoryFoldable;
1841   }
1842 }
1843
1844 let ExeDomain = SSEPackedSingle in
1845 defm VCMPSS : sse12_cmp_scalar<FR32, f32mem, AVXCC, X86cmps, f32, loadf32,
1846                  "cmp${cc}ss\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1847                  "cmpss\t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}",
1848                  SchedWriteFCmpSizes.PS.Scl>, XS, VEX_4V, VEX_LIG, VEX_WIG;
1849 let ExeDomain = SSEPackedDouble in
1850 defm VCMPSD : sse12_cmp_scalar<FR64, f64mem, AVXCC, X86cmps, f64, loadf64,
1851                  "cmp${cc}sd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1852                  "cmpsd\t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}",
1853                  SchedWriteFCmpSizes.PD.Scl>,
1854                  XD, VEX_4V, VEX_LIG, VEX_WIG;
1855
1856 let Constraints = "$src1 = $dst" in {
1857   let ExeDomain = SSEPackedSingle in
1858   defm CMPSS : sse12_cmp_scalar<FR32, f32mem, SSECC, X86cmps, f32, loadf32,
1859                   "cmp${cc}ss\t{$src2, $dst|$dst, $src2}",
1860                   "cmpss\t{$cc, $src2, $dst|$dst, $src2, $cc}",
1861                   SchedWriteFCmpSizes.PS.Scl>, XS;
1862   let ExeDomain = SSEPackedDouble in
1863   defm CMPSD : sse12_cmp_scalar<FR64, f64mem, SSECC, X86cmps, f64, loadf64,
1864                   "cmp${cc}sd\t{$src2, $dst|$dst, $src2}",
1865                   "cmpsd\t{$cc, $src2, $dst|$dst, $src2, $cc}",
1866                   SchedWriteFCmpSizes.PD.Scl>, XD;
1867 }
1868
1869 multiclass sse12_cmp_scalar_int<Operand memop, Operand CC,
1870                          Intrinsic Int, string asm, X86FoldableSchedWrite sched,
1871                          ComplexPattern mem_cpat> {
1872   def rr_Int : SIi8<0xC2, MRMSrcReg, (outs VR128:$dst),
1873                       (ins VR128:$src1, VR128:$src, CC:$cc), asm,
1874                         [(set VR128:$dst, (Int VR128:$src1,
1875                                                VR128:$src, imm:$cc))]>,
1876            Sched<[sched]>;
1877 let mayLoad = 1 in
1878   def rm_Int : SIi8<0xC2, MRMSrcMem, (outs VR128:$dst),
1879                       (ins VR128:$src1, memop:$src, CC:$cc), asm,
1880                         [(set VR128:$dst, (Int VR128:$src1,
1881                                                mem_cpat:$src, imm:$cc))]>,
1882            Sched<[sched.Folded, ReadAfterLd]>;
1883 }
1884
1885 let isCodeGenOnly = 1 in {
1886   // Aliases to match intrinsics which expect XMM operand(s).
1887   let ExeDomain = SSEPackedSingle in
1888   defm VCMPSS  : sse12_cmp_scalar_int<ssmem, AVXCC, int_x86_sse_cmp_ss,
1889                        "cmp${cc}ss\t{$src, $src1, $dst|$dst, $src1, $src}",
1890                        SchedWriteFCmpSizes.PS.Scl, sse_load_f32>, XS, VEX_4V;
1891   let ExeDomain = SSEPackedDouble in
1892   defm VCMPSD  : sse12_cmp_scalar_int<sdmem, AVXCC, int_x86_sse2_cmp_sd,
1893                        "cmp${cc}sd\t{$src, $src1, $dst|$dst, $src1, $src}",
1894                        SchedWriteFCmpSizes.PD.Scl, sse_load_f64>,
1895                        XD, VEX_4V;
1896   let Constraints = "$src1 = $dst" in {
1897     let ExeDomain = SSEPackedSingle in
1898     defm CMPSS  : sse12_cmp_scalar_int<ssmem, SSECC, int_x86_sse_cmp_ss,
1899                          "cmp${cc}ss\t{$src, $dst|$dst, $src}",
1900                          SchedWriteFCmpSizes.PS.Scl, sse_load_f32>, XS;
1901     let ExeDomain = SSEPackedDouble in
1902     defm CMPSD  : sse12_cmp_scalar_int<sdmem, SSECC, int_x86_sse2_cmp_sd,
1903                          "cmp${cc}sd\t{$src, $dst|$dst, $src}",
1904                          SchedWriteFCmpSizes.PD.Scl, sse_load_f64>, XD;
1905 }
1906 }
1907
1908
1909 // sse12_ord_cmp - Unordered/Ordered scalar fp compare and set EFLAGS
1910 multiclass sse12_ord_cmp<bits<8> opc, RegisterClass RC, SDNode OpNode,
1911                          ValueType vt, X86MemOperand x86memop,
1912                          PatFrag ld_frag, string OpcodeStr,
1913                          X86FoldableSchedWrite sched> {
1914 let hasSideEffects = 0 in {
1915   def rr: SI<opc, MRMSrcReg, (outs), (ins RC:$src1, RC:$src2),
1916                      !strconcat(OpcodeStr, "\t{$src2, $src1|$src1, $src2}"),
1917                      [(set EFLAGS, (OpNode (vt RC:$src1), RC:$src2))]>,
1918           Sched<[sched]>;
1919 let mayLoad = 1 in
1920   def rm: SI<opc, MRMSrcMem, (outs), (ins RC:$src1, x86memop:$src2),
1921                      !strconcat(OpcodeStr, "\t{$src2, $src1|$src1, $src2}"),
1922                      [(set EFLAGS, (OpNode (vt RC:$src1),
1923                                            (ld_frag addr:$src2)))]>,
1924           Sched<[sched.Folded, ReadAfterLd]>;
1925 }
1926 }
1927
1928 // sse12_ord_cmp_int - Intrinsic version of sse12_ord_cmp
1929 multiclass sse12_ord_cmp_int<bits<8> opc, RegisterClass RC, SDNode OpNode,
1930                              ValueType vt, Operand memop,
1931                              ComplexPattern mem_cpat, string OpcodeStr,
1932                              X86FoldableSchedWrite sched> {
1933   def rr_Int: SI<opc, MRMSrcReg, (outs), (ins RC:$src1, RC:$src2),
1934                      !strconcat(OpcodeStr, "\t{$src2, $src1|$src1, $src2}"),
1935                      [(set EFLAGS, (OpNode (vt RC:$src1), RC:$src2))]>,
1936           Sched<[sched]>;
1937 let mayLoad = 1 in
1938   def rm_Int: SI<opc, MRMSrcMem, (outs), (ins RC:$src1, memop:$src2),
1939                      !strconcat(OpcodeStr, "\t{$src2, $src1|$src1, $src2}"),
1940                      [(set EFLAGS, (OpNode (vt RC:$src1),
1941                                            mem_cpat:$src2))]>,
1942           Sched<[sched.Folded, ReadAfterLd]>;
1943 }
1944
1945 let Defs = [EFLAGS] in {
1946   defm VUCOMISS : sse12_ord_cmp<0x2E, FR32, X86cmp, f32, f32mem, loadf32,
1947                                "ucomiss", WriteFCom>, PS, VEX, VEX_LIG, VEX_WIG;
1948   defm VUCOMISD : sse12_ord_cmp<0x2E, FR64, X86cmp, f64, f64mem, loadf64,
1949                                "ucomisd", WriteFCom>, PD, VEX, VEX_LIG, VEX_WIG;
1950   let Pattern = []<dag> in {
1951     defm VCOMISS  : sse12_ord_cmp<0x2F, FR32, undef, f32, f32mem, loadf32,
1952                                 "comiss", WriteFCom>, PS, VEX, VEX_LIG, VEX_WIG;
1953     defm VCOMISD  : sse12_ord_cmp<0x2F, FR64, undef, f64, f64mem, loadf64,
1954                                 "comisd", WriteFCom>, PD, VEX, VEX_LIG, VEX_WIG;
1955   }
1956
1957   let isCodeGenOnly = 1 in {
1958     defm VUCOMISS  : sse12_ord_cmp_int<0x2E, VR128, X86ucomi, v4f32, ssmem,
1959                       sse_load_f32, "ucomiss", WriteFCom>, PS, VEX, VEX_WIG;
1960     defm VUCOMISD  : sse12_ord_cmp_int<0x2E, VR128, X86ucomi, v2f64, sdmem,
1961                       sse_load_f64, "ucomisd", WriteFCom>, PD, VEX, VEX_WIG;
1962
1963     defm VCOMISS  : sse12_ord_cmp_int<0x2F, VR128, X86comi, v4f32, ssmem,
1964                        sse_load_f32, "comiss", WriteFCom>, PS, VEX, VEX_WIG;
1965     defm VCOMISD  : sse12_ord_cmp_int<0x2F, VR128, X86comi, v2f64, sdmem,
1966                        sse_load_f64, "comisd", WriteFCom>, PD, VEX, VEX_WIG;
1967   }
1968   defm UCOMISS  : sse12_ord_cmp<0x2E, FR32, X86cmp, f32, f32mem, loadf32,
1969                                   "ucomiss", WriteFCom>, PS;
1970   defm UCOMISD  : sse12_ord_cmp<0x2E, FR64, X86cmp, f64, f64mem, loadf64,
1971                                   "ucomisd", WriteFCom>, PD;
1972
1973   let Pattern = []<dag> in {
1974     defm COMISS  : sse12_ord_cmp<0x2F, FR32, undef, f32, f32mem, loadf32,
1975                                     "comiss", WriteFCom>, PS;
1976     defm COMISD  : sse12_ord_cmp<0x2F, FR64, undef, f64, f64mem, loadf64,
1977                                     "comisd", WriteFCom>, PD;
1978   }
1979
1980   let isCodeGenOnly = 1 in {
1981     defm UCOMISS  : sse12_ord_cmp_int<0x2E, VR128, X86ucomi, v4f32, ssmem,
1982                             sse_load_f32, "ucomiss", WriteFCom>, PS;
1983     defm UCOMISD  : sse12_ord_cmp_int<0x2E, VR128, X86ucomi, v2f64, sdmem,
1984                             sse_load_f64, "ucomisd", WriteFCom>, PD;
1985
1986     defm COMISS  : sse12_ord_cmp_int<0x2F, VR128, X86comi, v4f32, ssmem,
1987                                 sse_load_f32, "comiss", WriteFCom>, PS;
1988     defm COMISD  : sse12_ord_cmp_int<0x2F, VR128, X86comi, v2f64, sdmem,
1989                                     sse_load_f64, "comisd", WriteFCom>, PD;
1990   }
1991 } // Defs = [EFLAGS]
1992
1993 // sse12_cmp_packed - sse 1 & 2 compare packed instructions
1994 multiclass sse12_cmp_packed<RegisterClass RC, X86MemOperand x86memop,
1995                             Operand CC,  ValueType VT, string asm,
1996                             string asm_alt, X86FoldableSchedWrite sched,
1997                             Domain d, PatFrag ld_frag> {
1998   let isCommutable = 1 in
1999   def rri : PIi8<0xC2, MRMSrcReg,
2000              (outs RC:$dst), (ins RC:$src1, RC:$src2, CC:$cc), asm,
2001              [(set RC:$dst, (VT (X86cmpp RC:$src1, RC:$src2, imm:$cc)))], d>,
2002             Sched<[sched]>;
2003   def rmi : PIi8<0xC2, MRMSrcMem,
2004              (outs RC:$dst), (ins RC:$src1, x86memop:$src2, CC:$cc), asm,
2005              [(set RC:$dst,
2006                (VT (X86cmpp RC:$src1, (ld_frag addr:$src2), imm:$cc)))], d>,
2007             Sched<[sched.Folded, ReadAfterLd]>;
2008
2009   // Accept explicit immediate argument form instead of comparison code.
2010   let isAsmParserOnly = 1, hasSideEffects = 0 in {
2011     def rri_alt : PIi8<0xC2, MRMSrcReg,
2012                (outs RC:$dst), (ins RC:$src1, RC:$src2, u8imm:$cc),
2013                asm_alt, [], d>, Sched<[sched]>, NotMemoryFoldable;
2014     let mayLoad = 1 in
2015     def rmi_alt : PIi8<0xC2, MRMSrcMem,
2016                (outs RC:$dst), (ins RC:$src1, x86memop:$src2, u8imm:$cc),
2017                asm_alt, [], d>, Sched<[sched.Folded, ReadAfterLd]>,
2018                NotMemoryFoldable;
2019   }
2020 }
2021
2022 defm VCMPPS : sse12_cmp_packed<VR128, f128mem, AVXCC, v4f32,
2023                "cmp${cc}ps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2024                "cmpps\t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}",
2025                SchedWriteFCmpSizes.PS.XMM, SSEPackedSingle, loadv4f32>, PS, VEX_4V, VEX_WIG;
2026 defm VCMPPD : sse12_cmp_packed<VR128, f128mem, AVXCC, v2f64,
2027                "cmp${cc}pd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2028                "cmppd\t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}",
2029                SchedWriteFCmpSizes.PD.XMM, SSEPackedDouble, loadv2f64>, PD, VEX_4V, VEX_WIG;
2030 defm VCMPPSY : sse12_cmp_packed<VR256, f256mem, AVXCC, v8f32,
2031                "cmp${cc}ps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2032                "cmpps\t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}",
2033                SchedWriteFCmpSizes.PS.YMM, SSEPackedSingle, loadv8f32>, PS, VEX_4V, VEX_L, VEX_WIG;
2034 defm VCMPPDY : sse12_cmp_packed<VR256, f256mem, AVXCC, v4f64,
2035                "cmp${cc}pd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2036                "cmppd\t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}",
2037                SchedWriteFCmpSizes.PD.YMM, SSEPackedDouble, loadv4f64>, PD, VEX_4V, VEX_L, VEX_WIG;
2038 let Constraints = "$src1 = $dst" in {
2039   defm CMPPS : sse12_cmp_packed<VR128, f128mem, SSECC, v4f32,
2040                  "cmp${cc}ps\t{$src2, $dst|$dst, $src2}",
2041                  "cmpps\t{$cc, $src2, $dst|$dst, $src2, $cc}",
2042                  SchedWriteFCmpSizes.PS.XMM, SSEPackedSingle, memopv4f32>, PS;
2043   defm CMPPD : sse12_cmp_packed<VR128, f128mem, SSECC, v2f64,
2044                  "cmp${cc}pd\t{$src2, $dst|$dst, $src2}",
2045                  "cmppd\t{$cc, $src2, $dst|$dst, $src2, $cc}",
2046                  SchedWriteFCmpSizes.PD.XMM, SSEPackedDouble, memopv2f64>, PD;
2047 }
2048
2049 def CommutableCMPCC : PatLeaf<(imm), [{
2050   uint64_t Imm = N->getZExtValue() & 0x7;
2051   return (Imm == 0x00 || Imm == 0x03 || Imm == 0x04 || Imm == 0x07);
2052 }]>;
2053
2054 // Patterns to select compares with loads in first operand.
2055 let Predicates = [HasAVX] in {
2056   def : Pat<(v4f64 (X86cmpp (loadv4f64 addr:$src2), VR256:$src1,
2057                             CommutableCMPCC:$cc)),
2058             (VCMPPDYrmi VR256:$src1, addr:$src2, imm:$cc)>;
2059
2060   def : Pat<(v8f32 (X86cmpp (loadv8f32 addr:$src2), VR256:$src1,
2061                             CommutableCMPCC:$cc)),
2062             (VCMPPSYrmi VR256:$src1, addr:$src2, imm:$cc)>;
2063
2064   def : Pat<(v2f64 (X86cmpp (loadv2f64 addr:$src2), VR128:$src1,
2065                             CommutableCMPCC:$cc)),
2066             (VCMPPDrmi VR128:$src1, addr:$src2, imm:$cc)>;
2067
2068   def : Pat<(v4f32 (X86cmpp (loadv4f32 addr:$src2), VR128:$src1,
2069                             CommutableCMPCC:$cc)),
2070             (VCMPPSrmi VR128:$src1, addr:$src2, imm:$cc)>;
2071
2072   def : Pat<(f64 (X86cmps (loadf64 addr:$src2), FR64:$src1,
2073                           CommutableCMPCC:$cc)),
2074             (VCMPSDrm FR64:$src1, addr:$src2, imm:$cc)>;
2075
2076   def : Pat<(f32 (X86cmps (loadf32 addr:$src2), FR32:$src1,
2077                           CommutableCMPCC:$cc)),
2078             (VCMPSSrm FR32:$src1, addr:$src2, imm:$cc)>;
2079 }
2080
2081 let Predicates = [UseSSE2] in {
2082   def : Pat<(v2f64 (X86cmpp (memopv2f64 addr:$src2), VR128:$src1,
2083                             CommutableCMPCC:$cc)),
2084             (CMPPDrmi VR128:$src1, addr:$src2, imm:$cc)>;
2085
2086   def : Pat<(f64 (X86cmps (loadf64 addr:$src2), FR64:$src1,
2087                           CommutableCMPCC:$cc)),
2088             (CMPSDrm FR64:$src1, addr:$src2, imm:$cc)>;
2089 }
2090
2091 let Predicates = [UseSSE1] in {
2092   def : Pat<(v4f32 (X86cmpp (memopv4f32 addr:$src2), VR128:$src1,
2093                             CommutableCMPCC:$cc)),
2094             (CMPPSrmi VR128:$src1, addr:$src2, imm:$cc)>;
2095
2096   def : Pat<(f32 (X86cmps (loadf32 addr:$src2), FR32:$src1,
2097                           CommutableCMPCC:$cc)),
2098             (CMPSSrm FR32:$src1, addr:$src2, imm:$cc)>;
2099 }
2100
2101 //===----------------------------------------------------------------------===//
2102 // SSE 1 & 2 - Shuffle Instructions
2103 //===----------------------------------------------------------------------===//
2104
2105 /// sse12_shuffle - sse 1 & 2 fp shuffle instructions
2106 multiclass sse12_shuffle<RegisterClass RC, X86MemOperand x86memop,
2107                          ValueType vt, string asm, PatFrag mem_frag,
2108                          X86FoldableSchedWrite sched, Domain d> {
2109   def rmi : PIi8<0xC6, MRMSrcMem, (outs RC:$dst),
2110                    (ins RC:$src1, x86memop:$src2, u8imm:$src3), asm,
2111                    [(set RC:$dst, (vt (X86Shufp RC:$src1, (mem_frag addr:$src2),
2112                                        (i8 imm:$src3))))], d>,
2113             Sched<[sched.Folded, ReadAfterLd]>;
2114   def rri : PIi8<0xC6, MRMSrcReg, (outs RC:$dst),
2115                  (ins RC:$src1, RC:$src2, u8imm:$src3), asm,
2116                  [(set RC:$dst, (vt (X86Shufp RC:$src1, RC:$src2,
2117                                      (i8 imm:$src3))))], d>,
2118             Sched<[sched]>;
2119 }
2120
2121 let Predicates = [HasAVX, NoVLX] in {
2122   defm VSHUFPS  : sse12_shuffle<VR128, f128mem, v4f32,
2123            "shufps\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
2124            loadv4f32, SchedWriteFShuffle.XMM, SSEPackedSingle>,
2125            PS, VEX_4V, VEX_WIG;
2126   defm VSHUFPSY : sse12_shuffle<VR256, f256mem, v8f32,
2127            "shufps\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
2128            loadv8f32, SchedWriteFShuffle.YMM, SSEPackedSingle>,
2129            PS, VEX_4V, VEX_L, VEX_WIG;
2130   defm VSHUFPD  : sse12_shuffle<VR128, f128mem, v2f64,
2131            "shufpd\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
2132            loadv2f64, SchedWriteFShuffle.XMM, SSEPackedDouble>,
2133            PD, VEX_4V, VEX_WIG;
2134   defm VSHUFPDY : sse12_shuffle<VR256, f256mem, v4f64,
2135            "shufpd\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
2136            loadv4f64, SchedWriteFShuffle.YMM, SSEPackedDouble>,
2137            PD, VEX_4V, VEX_L, VEX_WIG;
2138 }
2139 let Constraints = "$src1 = $dst" in {
2140   defm SHUFPS : sse12_shuffle<VR128, f128mem, v4f32,
2141                     "shufps\t{$src3, $src2, $dst|$dst, $src2, $src3}",
2142                     memopv4f32, SchedWriteFShuffle.XMM, SSEPackedSingle>, PS;
2143   defm SHUFPD : sse12_shuffle<VR128, f128mem, v2f64,
2144                     "shufpd\t{$src3, $src2, $dst|$dst, $src2, $src3}",
2145                     memopv2f64, SchedWriteFShuffle.XMM, SSEPackedDouble>, PD;
2146 }
2147
2148 //===----------------------------------------------------------------------===//
2149 // SSE 1 & 2 - Unpack FP Instructions
2150 //===----------------------------------------------------------------------===//
2151
2152 /// sse12_unpack_interleave - sse 1 & 2 fp unpack and interleave
2153 multiclass sse12_unpack_interleave<bits<8> opc, SDNode OpNode, ValueType vt,
2154                                    PatFrag mem_frag, RegisterClass RC,
2155                                    X86MemOperand x86memop, string asm,
2156                                    X86FoldableSchedWrite sched, Domain d,
2157                                    bit IsCommutable = 0> {
2158     let isCommutable = IsCommutable in
2159     def rr : PI<opc, MRMSrcReg,
2160                 (outs RC:$dst), (ins RC:$src1, RC:$src2),
2161                 asm, [(set RC:$dst,
2162                            (vt (OpNode RC:$src1, RC:$src2)))], d>,
2163                 Sched<[sched]>;
2164     def rm : PI<opc, MRMSrcMem,
2165                 (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
2166                 asm, [(set RC:$dst,
2167                            (vt (OpNode RC:$src1,
2168                                        (mem_frag addr:$src2))))], d>,
2169              Sched<[sched.Folded, ReadAfterLd]>;
2170 }
2171
2172 let Predicates = [HasAVX, NoVLX] in {
2173 defm VUNPCKHPS: sse12_unpack_interleave<0x15, X86Unpckh, v4f32, loadv4f32,
2174       VR128, f128mem, "unpckhps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2175                      SchedWriteFShuffle.XMM, SSEPackedSingle>, PS, VEX_4V, VEX_WIG;
2176 defm VUNPCKHPD: sse12_unpack_interleave<0x15, X86Unpckh, v2f64, loadv2f64,
2177       VR128, f128mem, "unpckhpd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2178                      SchedWriteFShuffle.XMM, SSEPackedDouble>, PD, VEX_4V, VEX_WIG;
2179 defm VUNPCKLPS: sse12_unpack_interleave<0x14, X86Unpckl, v4f32, loadv4f32,
2180       VR128, f128mem, "unpcklps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2181                      SchedWriteFShuffle.XMM, SSEPackedSingle>, PS, VEX_4V, VEX_WIG;
2182 defm VUNPCKLPD: sse12_unpack_interleave<0x14, X86Unpckl, v2f64, loadv2f64,
2183       VR128, f128mem, "unpcklpd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2184                      SchedWriteFShuffle.XMM, SSEPackedDouble>, PD, VEX_4V, VEX_WIG;
2185
2186 defm VUNPCKHPSY: sse12_unpack_interleave<0x15, X86Unpckh, v8f32, loadv8f32,
2187       VR256, f256mem, "unpckhps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2188                      SchedWriteFShuffle.YMM, SSEPackedSingle>, PS, VEX_4V, VEX_L, VEX_WIG;
2189 defm VUNPCKHPDY: sse12_unpack_interleave<0x15, X86Unpckh, v4f64, loadv4f64,
2190       VR256, f256mem, "unpckhpd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2191                      SchedWriteFShuffle.YMM, SSEPackedDouble>, PD, VEX_4V, VEX_L, VEX_WIG;
2192 defm VUNPCKLPSY: sse12_unpack_interleave<0x14, X86Unpckl, v8f32, loadv8f32,
2193       VR256, f256mem, "unpcklps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2194                      SchedWriteFShuffle.YMM, SSEPackedSingle>, PS, VEX_4V, VEX_L, VEX_WIG;
2195 defm VUNPCKLPDY: sse12_unpack_interleave<0x14, X86Unpckl, v4f64, loadv4f64,
2196       VR256, f256mem, "unpcklpd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2197                      SchedWriteFShuffle.YMM, SSEPackedDouble>, PD, VEX_4V, VEX_L, VEX_WIG;
2198 }// Predicates = [HasAVX, NoVLX]
2199
2200 let Constraints = "$src1 = $dst" in {
2201   defm UNPCKHPS: sse12_unpack_interleave<0x15, X86Unpckh, v4f32, memopv4f32,
2202         VR128, f128mem, "unpckhps\t{$src2, $dst|$dst, $src2}",
2203                        SchedWriteFShuffle.XMM, SSEPackedSingle>, PS;
2204   defm UNPCKHPD: sse12_unpack_interleave<0x15, X86Unpckh, v2f64, memopv2f64,
2205         VR128, f128mem, "unpckhpd\t{$src2, $dst|$dst, $src2}",
2206                        SchedWriteFShuffle.XMM, SSEPackedDouble, 1>, PD;
2207   defm UNPCKLPS: sse12_unpack_interleave<0x14, X86Unpckl, v4f32, memopv4f32,
2208         VR128, f128mem, "unpcklps\t{$src2, $dst|$dst, $src2}",
2209                        SchedWriteFShuffle.XMM, SSEPackedSingle>, PS;
2210   defm UNPCKLPD: sse12_unpack_interleave<0x14, X86Unpckl, v2f64, memopv2f64,
2211         VR128, f128mem, "unpcklpd\t{$src2, $dst|$dst, $src2}",
2212                        SchedWriteFShuffle.XMM, SSEPackedDouble>, PD;
2213 } // Constraints = "$src1 = $dst"
2214
2215 let Predicates = [HasAVX1Only] in {
2216   def : Pat<(v8i32 (X86Unpckl VR256:$src1, (bc_v8i32 (loadv4i64 addr:$src2)))),
2217             (VUNPCKLPSYrm VR256:$src1, addr:$src2)>;
2218   def : Pat<(v8i32 (X86Unpckl VR256:$src1, VR256:$src2)),
2219             (VUNPCKLPSYrr VR256:$src1, VR256:$src2)>;
2220   def : Pat<(v8i32 (X86Unpckh VR256:$src1, (bc_v8i32 (loadv4i64 addr:$src2)))),
2221             (VUNPCKHPSYrm VR256:$src1, addr:$src2)>;
2222   def : Pat<(v8i32 (X86Unpckh VR256:$src1, VR256:$src2)),
2223             (VUNPCKHPSYrr VR256:$src1, VR256:$src2)>;
2224
2225   def : Pat<(v4i64 (X86Unpckl VR256:$src1, (loadv4i64 addr:$src2))),
2226             (VUNPCKLPDYrm VR256:$src1, addr:$src2)>;
2227   def : Pat<(v4i64 (X86Unpckl VR256:$src1, VR256:$src2)),
2228             (VUNPCKLPDYrr VR256:$src1, VR256:$src2)>;
2229   def : Pat<(v4i64 (X86Unpckh VR256:$src1, (loadv4i64 addr:$src2))),
2230             (VUNPCKHPDYrm VR256:$src1, addr:$src2)>;
2231   def : Pat<(v4i64 (X86Unpckh VR256:$src1, VR256:$src2)),
2232             (VUNPCKHPDYrr VR256:$src1, VR256:$src2)>;
2233 }
2234
2235 //===----------------------------------------------------------------------===//
2236 // SSE 1 & 2 - Extract Floating-Point Sign mask
2237 //===----------------------------------------------------------------------===//
2238
2239 /// sse12_extr_sign_mask - sse 1 & 2 unpack and interleave
2240 multiclass sse12_extr_sign_mask<RegisterClass RC, ValueType vt,
2241                                 string asm, Domain d> {
2242   def rr : PI<0x50, MRMSrcReg, (outs GR32orGR64:$dst), (ins RC:$src),
2243               !strconcat(asm, "\t{$src, $dst|$dst, $src}"),
2244               [(set GR32orGR64:$dst, (X86movmsk (vt RC:$src)))], d>,
2245               Sched<[WriteFMOVMSK]>;
2246 }
2247
2248 let Predicates = [HasAVX] in {
2249   defm VMOVMSKPS : sse12_extr_sign_mask<VR128, v4f32, "movmskps",
2250                                         SSEPackedSingle>, PS, VEX, VEX_WIG;
2251   defm VMOVMSKPD : sse12_extr_sign_mask<VR128, v2f64, "movmskpd",
2252                                         SSEPackedDouble>, PD, VEX, VEX_WIG;
2253   defm VMOVMSKPSY : sse12_extr_sign_mask<VR256, v8f32, "movmskps",
2254                                          SSEPackedSingle>, PS, VEX, VEX_L, VEX_WIG;
2255   defm VMOVMSKPDY : sse12_extr_sign_mask<VR256, v4f64, "movmskpd",
2256                                          SSEPackedDouble>, PD, VEX, VEX_L, VEX_WIG;
2257 }
2258
2259 defm MOVMSKPS : sse12_extr_sign_mask<VR128, v4f32, "movmskps",
2260                                      SSEPackedSingle>, PS;
2261 defm MOVMSKPD : sse12_extr_sign_mask<VR128, v2f64, "movmskpd",
2262                                      SSEPackedDouble>, PD;
2263
2264 //===---------------------------------------------------------------------===//
2265 // SSE2 - Packed Integer Logical Instructions
2266 //===---------------------------------------------------------------------===//
2267
2268 let ExeDomain = SSEPackedInt in { // SSE integer instructions
2269
2270 /// PDI_binop_rm - Simple SSE2 binary operator.
2271 multiclass PDI_binop_rm<bits<8> opc, string OpcodeStr, SDNode OpNode,
2272                         ValueType OpVT, RegisterClass RC, PatFrag memop_frag,
2273                         X86MemOperand x86memop, X86FoldableSchedWrite sched,
2274                         bit IsCommutable, bit Is2Addr> {
2275   let isCommutable = IsCommutable in
2276   def rr : PDI<opc, MRMSrcReg, (outs RC:$dst),
2277        (ins RC:$src1, RC:$src2),
2278        !if(Is2Addr,
2279            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
2280            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
2281        [(set RC:$dst, (OpVT (OpNode RC:$src1, RC:$src2)))]>,
2282        Sched<[sched]>;
2283   def rm : PDI<opc, MRMSrcMem, (outs RC:$dst),
2284        (ins RC:$src1, x86memop:$src2),
2285        !if(Is2Addr,
2286            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
2287            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
2288        [(set RC:$dst, (OpVT (OpNode RC:$src1,
2289                                      (bitconvert (memop_frag addr:$src2)))))]>,
2290        Sched<[sched.Folded, ReadAfterLd]>;
2291 }
2292 } // ExeDomain = SSEPackedInt
2293
2294 multiclass PDI_binop_all<bits<8> opc, string OpcodeStr, SDNode Opcode,
2295                          ValueType OpVT128, ValueType OpVT256,
2296                          X86SchedWriteWidths sched, bit IsCommutable,
2297                          Predicate prd> {
2298 let Predicates = [HasAVX, prd] in
2299   defm V#NAME : PDI_binop_rm<opc, !strconcat("v", OpcodeStr), Opcode, OpVT128,
2300                              VR128, loadv2i64, i128mem, sched.XMM,
2301                              IsCommutable, 0>, VEX_4V, VEX_WIG;
2302
2303 let Constraints = "$src1 = $dst" in
2304   defm NAME : PDI_binop_rm<opc, OpcodeStr, Opcode, OpVT128, VR128,
2305                            memopv2i64, i128mem, sched.XMM, IsCommutable, 1>;
2306
2307 let Predicates = [HasAVX2, prd] in
2308   defm V#NAME#Y : PDI_binop_rm<opc, !strconcat("v", OpcodeStr), Opcode,
2309                                OpVT256, VR256, loadv4i64, i256mem, sched.YMM,
2310                                IsCommutable, 0>, VEX_4V, VEX_L, VEX_WIG;
2311 }
2312
2313 // These are ordered here for pattern ordering requirements with the fp versions
2314
2315 defm PAND  : PDI_binop_all<0xDB, "pand", and, v2i64, v4i64,
2316                            SchedWriteVecLogic, 1, NoVLX>;
2317 defm POR   : PDI_binop_all<0xEB, "por", or, v2i64, v4i64,
2318                            SchedWriteVecLogic, 1, NoVLX>;
2319 defm PXOR  : PDI_binop_all<0xEF, "pxor", xor, v2i64, v4i64,
2320                            SchedWriteVecLogic, 1, NoVLX>;
2321 defm PANDN : PDI_binop_all<0xDF, "pandn", X86andnp, v2i64, v4i64,
2322                            SchedWriteVecLogic, 0, NoVLX>;
2323
2324 //===----------------------------------------------------------------------===//
2325 // SSE 1 & 2 - Logical Instructions
2326 //===----------------------------------------------------------------------===//
2327
2328 /// sse12_fp_packed_logical - SSE 1 & 2 packed FP logical ops
2329 ///
2330 /// There are no patterns here because isel prefers integer versions for SSE2
2331 /// and later. There are SSE1 v4f32 patterns later.
2332 multiclass sse12_fp_packed_logical<bits<8> opc, string OpcodeStr,
2333                                    SDNode OpNode, X86SchedWriteWidths sched> {
2334   let Predicates = [HasAVX, NoVLX] in {
2335   defm V#NAME#PSY : sse12_fp_packed_logical_rm<opc, VR256, SSEPackedSingle,
2336         !strconcat(OpcodeStr, "ps"), f256mem, sched.YMM,
2337         [], [], 0>, PS, VEX_4V, VEX_L, VEX_WIG;
2338
2339   defm V#NAME#PDY : sse12_fp_packed_logical_rm<opc, VR256, SSEPackedDouble,
2340         !strconcat(OpcodeStr, "pd"), f256mem, sched.YMM,
2341         [], [], 0>, PD, VEX_4V, VEX_L, VEX_WIG;
2342
2343   defm V#NAME#PS : sse12_fp_packed_logical_rm<opc, VR128, SSEPackedSingle,
2344        !strconcat(OpcodeStr, "ps"), f128mem, sched.XMM,
2345        [], [], 0>, PS, VEX_4V, VEX_WIG;
2346
2347   defm V#NAME#PD : sse12_fp_packed_logical_rm<opc, VR128, SSEPackedDouble,
2348        !strconcat(OpcodeStr, "pd"), f128mem, sched.XMM,
2349        [], [], 0>, PD, VEX_4V, VEX_WIG;
2350   }
2351
2352   let Constraints = "$src1 = $dst" in {
2353     defm PS : sse12_fp_packed_logical_rm<opc, VR128, SSEPackedSingle,
2354          !strconcat(OpcodeStr, "ps"), f128mem, sched.XMM,
2355          [], []>, PS;
2356
2357     defm PD : sse12_fp_packed_logical_rm<opc, VR128, SSEPackedDouble,
2358          !strconcat(OpcodeStr, "pd"), f128mem, sched.XMM,
2359          [], []>, PD;
2360   }
2361 }
2362
2363 defm AND  : sse12_fp_packed_logical<0x54, "and", and, SchedWriteFLogic>;
2364 defm OR   : sse12_fp_packed_logical<0x56, "or", or, SchedWriteFLogic>;
2365 defm XOR  : sse12_fp_packed_logical<0x57, "xor", xor, SchedWriteFLogic>;
2366 let isCommutable = 0 in
2367   defm ANDN : sse12_fp_packed_logical<0x55, "andn", X86andnp, SchedWriteFLogic>;
2368
2369 // If only AVX1 is supported, we need to handle integer operations with
2370 // floating point instructions since the integer versions aren't available.
2371 let Predicates = [HasAVX1Only] in {
2372   def : Pat<(v4i64 (and VR256:$src1, VR256:$src2)),
2373             (VANDPSYrr VR256:$src1, VR256:$src2)>;
2374   def : Pat<(v4i64 (or VR256:$src1, VR256:$src2)),
2375             (VORPSYrr VR256:$src1, VR256:$src2)>;
2376   def : Pat<(v4i64 (xor VR256:$src1, VR256:$src2)),
2377             (VXORPSYrr VR256:$src1, VR256:$src2)>;
2378   def : Pat<(v4i64 (X86andnp VR256:$src1, VR256:$src2)),
2379             (VANDNPSYrr VR256:$src1, VR256:$src2)>;
2380
2381   def : Pat<(and VR256:$src1, (loadv4i64 addr:$src2)),
2382             (VANDPSYrm VR256:$src1, addr:$src2)>;
2383   def : Pat<(or VR256:$src1, (loadv4i64 addr:$src2)),
2384             (VORPSYrm VR256:$src1, addr:$src2)>;
2385   def : Pat<(xor VR256:$src1, (loadv4i64 addr:$src2)),
2386             (VXORPSYrm VR256:$src1, addr:$src2)>;
2387   def : Pat<(X86andnp VR256:$src1, (loadv4i64 addr:$src2)),
2388             (VANDNPSYrm VR256:$src1, addr:$src2)>;
2389 }
2390
2391 let Predicates = [HasAVX, NoVLX_Or_NoDQI] in {
2392   // Use packed logical operations for scalar ops.
2393   def : Pat<(f64 (X86fand FR64:$src1, FR64:$src2)),
2394             (COPY_TO_REGCLASS (VANDPDrr
2395                                (COPY_TO_REGCLASS FR64:$src1, VR128),
2396                                (COPY_TO_REGCLASS FR64:$src2, VR128)), FR64)>;
2397   def : Pat<(f64 (X86for FR64:$src1, FR64:$src2)),
2398             (COPY_TO_REGCLASS (VORPDrr
2399                                (COPY_TO_REGCLASS FR64:$src1, VR128),
2400                                (COPY_TO_REGCLASS FR64:$src2, VR128)), FR64)>;
2401   def : Pat<(f64 (X86fxor FR64:$src1, FR64:$src2)),
2402             (COPY_TO_REGCLASS (VXORPDrr
2403                                (COPY_TO_REGCLASS FR64:$src1, VR128),
2404                                (COPY_TO_REGCLASS FR64:$src2, VR128)), FR64)>;
2405   def : Pat<(f64 (X86fandn FR64:$src1, FR64:$src2)),
2406             (COPY_TO_REGCLASS (VANDNPDrr
2407                                (COPY_TO_REGCLASS FR64:$src1, VR128),
2408                                (COPY_TO_REGCLASS FR64:$src2, VR128)), FR64)>;
2409
2410   def : Pat<(f32 (X86fand FR32:$src1, FR32:$src2)),
2411             (COPY_TO_REGCLASS (VANDPSrr
2412                                (COPY_TO_REGCLASS FR32:$src1, VR128),
2413                                (COPY_TO_REGCLASS FR32:$src2, VR128)), FR32)>;
2414   def : Pat<(f32 (X86for FR32:$src1, FR32:$src2)),
2415             (COPY_TO_REGCLASS (VORPSrr
2416                                (COPY_TO_REGCLASS FR32:$src1, VR128),
2417                                (COPY_TO_REGCLASS FR32:$src2, VR128)), FR32)>;
2418   def : Pat<(f32 (X86fxor FR32:$src1, FR32:$src2)),
2419             (COPY_TO_REGCLASS (VXORPSrr
2420                                (COPY_TO_REGCLASS FR32:$src1, VR128),
2421                                (COPY_TO_REGCLASS FR32:$src2, VR128)), FR32)>;
2422   def : Pat<(f32 (X86fandn FR32:$src1, FR32:$src2)),
2423             (COPY_TO_REGCLASS (VANDNPSrr
2424                                (COPY_TO_REGCLASS FR32:$src1, VR128),
2425                                (COPY_TO_REGCLASS FR32:$src2, VR128)), FR32)>;
2426 }
2427
2428 let Predicates = [UseSSE1] in {
2429   // Use packed logical operations for scalar ops.
2430   def : Pat<(f32 (X86fand FR32:$src1, FR32:$src2)),
2431             (COPY_TO_REGCLASS (ANDPSrr
2432                                (COPY_TO_REGCLASS FR32:$src1, VR128),
2433                                (COPY_TO_REGCLASS FR32:$src2, VR128)), FR32)>;
2434   def : Pat<(f32 (X86for FR32:$src1, FR32:$src2)),
2435             (COPY_TO_REGCLASS (ORPSrr
2436                                (COPY_TO_REGCLASS FR32:$src1, VR128),
2437                                (COPY_TO_REGCLASS FR32:$src2, VR128)), FR32)>;
2438   def : Pat<(f32 (X86fxor FR32:$src1, FR32:$src2)),
2439             (COPY_TO_REGCLASS (XORPSrr
2440                                (COPY_TO_REGCLASS FR32:$src1, VR128),
2441                                (COPY_TO_REGCLASS FR32:$src2, VR128)), FR32)>;
2442   def : Pat<(f32 (X86fandn FR32:$src1, FR32:$src2)),
2443             (COPY_TO_REGCLASS (ANDNPSrr
2444                                (COPY_TO_REGCLASS FR32:$src1, VR128),
2445                                (COPY_TO_REGCLASS FR32:$src2, VR128)), FR32)>;
2446 }
2447
2448 let Predicates = [UseSSE2] in {
2449   // Use packed logical operations for scalar ops.
2450   def : Pat<(f64 (X86fand FR64:$src1, FR64:$src2)),
2451             (COPY_TO_REGCLASS (ANDPDrr
2452                                (COPY_TO_REGCLASS FR64:$src1, VR128),
2453                                (COPY_TO_REGCLASS FR64:$src2, VR128)), FR64)>;
2454   def : Pat<(f64 (X86for FR64:$src1, FR64:$src2)),
2455             (COPY_TO_REGCLASS (ORPDrr
2456                                (COPY_TO_REGCLASS FR64:$src1, VR128),
2457                                (COPY_TO_REGCLASS FR64:$src2, VR128)), FR64)>;
2458   def : Pat<(f64 (X86fxor FR64:$src1, FR64:$src2)),
2459             (COPY_TO_REGCLASS (XORPDrr
2460                                (COPY_TO_REGCLASS FR64:$src1, VR128),
2461                                (COPY_TO_REGCLASS FR64:$src2, VR128)), FR64)>;
2462   def : Pat<(f64 (X86fandn FR64:$src1, FR64:$src2)),
2463             (COPY_TO_REGCLASS (ANDNPDrr
2464                                (COPY_TO_REGCLASS FR64:$src1, VR128),
2465                                (COPY_TO_REGCLASS FR64:$src2, VR128)), FR64)>;
2466 }
2467
2468 // Patterns for packed operations when we don't have integer type available.
2469 def : Pat<(v4f32 (X86fand VR128:$src1, VR128:$src2)),
2470           (ANDPSrr VR128:$src1, VR128:$src2)>;
2471 def : Pat<(v4f32 (X86for VR128:$src1, VR128:$src2)),
2472           (ORPSrr VR128:$src1, VR128:$src2)>;
2473 def : Pat<(v4f32 (X86fxor VR128:$src1, VR128:$src2)),
2474           (XORPSrr VR128:$src1, VR128:$src2)>;
2475 def : Pat<(v4f32 (X86fandn VR128:$src1, VR128:$src2)),
2476           (ANDNPSrr VR128:$src1, VR128:$src2)>;
2477
2478 def : Pat<(X86fand VR128:$src1, (memopv4f32 addr:$src2)),
2479           (ANDPSrm VR128:$src1, addr:$src2)>;
2480 def : Pat<(X86for VR128:$src1, (memopv4f32 addr:$src2)),
2481           (ORPSrm VR128:$src1, addr:$src2)>;
2482 def : Pat<(X86fxor VR128:$src1, (memopv4f32 addr:$src2)),
2483           (XORPSrm VR128:$src1, addr:$src2)>;
2484 def : Pat<(X86fandn VR128:$src1, (memopv4f32 addr:$src2)),
2485           (ANDNPSrm VR128:$src1, addr:$src2)>;
2486
2487 //===----------------------------------------------------------------------===//
2488 // SSE 1 & 2 - Arithmetic Instructions
2489 //===----------------------------------------------------------------------===//
2490
2491 /// basic_sse12_fp_binop_xxx - SSE 1 & 2 binops come in both scalar and
2492 /// vector forms.
2493 ///
2494 /// In addition, we also have a special variant of the scalar form here to
2495 /// represent the associated intrinsic operation.  This form is unlike the
2496 /// plain scalar form, in that it takes an entire vector (instead of a scalar)
2497 /// and leaves the top elements unmodified (therefore these cannot be commuted).
2498 ///
2499 /// These three forms can each be reg+reg or reg+mem.
2500 ///
2501
2502 /// FIXME: once all 256-bit intrinsics are matched, cleanup and refactor those
2503 /// classes below
2504 multiclass basic_sse12_fp_binop_p<bits<8> opc, string OpcodeStr,
2505                                   SDNode OpNode, X86SchedWriteSizes sched> {
2506   let Predicates = [HasAVX, NoVLX] in {
2507   defm V#NAME#PS : sse12_fp_packed<opc, !strconcat(OpcodeStr, "ps"), OpNode,
2508                                VR128, v4f32, f128mem, loadv4f32,
2509                                SSEPackedSingle, sched.PS.XMM, 0>, PS, VEX_4V, VEX_WIG;
2510   defm V#NAME#PD : sse12_fp_packed<opc, !strconcat(OpcodeStr, "pd"), OpNode,
2511                                VR128, v2f64, f128mem, loadv2f64,
2512                                SSEPackedDouble, sched.PD.XMM, 0>, PD, VEX_4V, VEX_WIG;
2513
2514   defm V#NAME#PSY : sse12_fp_packed<opc, !strconcat(OpcodeStr, "ps"),
2515                         OpNode, VR256, v8f32, f256mem, loadv8f32,
2516                         SSEPackedSingle, sched.PS.YMM, 0>, PS, VEX_4V, VEX_L, VEX_WIG;
2517   defm V#NAME#PDY : sse12_fp_packed<opc, !strconcat(OpcodeStr, "pd"),
2518                         OpNode, VR256, v4f64, f256mem, loadv4f64,
2519                         SSEPackedDouble, sched.PD.YMM, 0>, PD, VEX_4V, VEX_L, VEX_WIG;
2520   }
2521
2522   let Constraints = "$src1 = $dst" in {
2523     defm PS : sse12_fp_packed<opc, !strconcat(OpcodeStr, "ps"), OpNode, VR128,
2524                               v4f32, f128mem, memopv4f32, SSEPackedSingle,
2525                               sched.PS.XMM>, PS;
2526     defm PD : sse12_fp_packed<opc, !strconcat(OpcodeStr, "pd"), OpNode, VR128,
2527                               v2f64, f128mem, memopv2f64, SSEPackedDouble,
2528                               sched.PD.XMM>, PD;
2529   }
2530 }
2531
2532 multiclass basic_sse12_fp_binop_s<bits<8> opc, string OpcodeStr, SDNode OpNode,
2533                                   X86SchedWriteSizes sched> {
2534   defm V#NAME#SS : sse12_fp_scalar<opc, !strconcat(OpcodeStr, "ss"),
2535                          OpNode, FR32, f32mem, SSEPackedSingle, sched.PS.Scl, 0>,
2536                          XS, VEX_4V, VEX_LIG, VEX_WIG;
2537   defm V#NAME#SD : sse12_fp_scalar<opc, !strconcat(OpcodeStr, "sd"),
2538                          OpNode, FR64, f64mem, SSEPackedDouble, sched.PD.Scl, 0>,
2539                          XD, VEX_4V, VEX_LIG, VEX_WIG;
2540
2541   let Constraints = "$src1 = $dst" in {
2542     defm SS : sse12_fp_scalar<opc, !strconcat(OpcodeStr, "ss"),
2543                               OpNode, FR32, f32mem, SSEPackedSingle,
2544                               sched.PS.Scl>, XS;
2545     defm SD : sse12_fp_scalar<opc, !strconcat(OpcodeStr, "sd"),
2546                               OpNode, FR64, f64mem, SSEPackedDouble,
2547                               sched.PD.Scl>, XD;
2548   }
2549 }
2550
2551 multiclass basic_sse12_fp_binop_s_int<bits<8> opc, string OpcodeStr,
2552                                       SDPatternOperator OpNode,
2553                                       X86SchedWriteSizes sched> {
2554   defm V#NAME#SS : sse12_fp_scalar_int<opc, OpcodeStr, OpNode, VR128, v4f32,
2555                    !strconcat(OpcodeStr, "ss"), ssmem, sse_load_f32,
2556                    SSEPackedSingle, sched.PS.Scl, 0>, XS, VEX_4V, VEX_LIG, VEX_WIG;
2557   defm V#NAME#SD : sse12_fp_scalar_int<opc, OpcodeStr, OpNode, VR128, v2f64,
2558                    !strconcat(OpcodeStr, "sd"), sdmem, sse_load_f64,
2559                    SSEPackedDouble, sched.PD.Scl, 0>, XD, VEX_4V, VEX_LIG, VEX_WIG;
2560
2561   let Constraints = "$src1 = $dst" in {
2562     defm SS : sse12_fp_scalar_int<opc, OpcodeStr, OpNode, VR128, v4f32,
2563                    !strconcat(OpcodeStr, "ss"), ssmem, sse_load_f32,
2564                    SSEPackedSingle, sched.PS.Scl>, XS;
2565     defm SD : sse12_fp_scalar_int<opc, OpcodeStr, OpNode, VR128, v2f64,
2566                    !strconcat(OpcodeStr, "sd"), sdmem, sse_load_f64,
2567                    SSEPackedDouble, sched.PD.Scl>, XD;
2568   }
2569 }
2570
2571 // Binary Arithmetic instructions
2572 defm ADD : basic_sse12_fp_binop_p<0x58, "add", fadd, SchedWriteFAddSizes>,
2573            basic_sse12_fp_binop_s<0x58, "add", fadd, SchedWriteFAddSizes>,
2574            basic_sse12_fp_binop_s_int<0x58, "add", null_frag, SchedWriteFAddSizes>;
2575 defm MUL : basic_sse12_fp_binop_p<0x59, "mul", fmul, SchedWriteFMulSizes>,
2576            basic_sse12_fp_binop_s<0x59, "mul", fmul, SchedWriteFMulSizes>,
2577            basic_sse12_fp_binop_s_int<0x59, "mul", null_frag, SchedWriteFMulSizes>;
2578 let isCommutable = 0 in {
2579   defm SUB : basic_sse12_fp_binop_p<0x5C, "sub", fsub, SchedWriteFAddSizes>,
2580              basic_sse12_fp_binop_s<0x5C, "sub", fsub, SchedWriteFAddSizes>,
2581              basic_sse12_fp_binop_s_int<0x5C, "sub", null_frag, SchedWriteFAddSizes>;
2582   defm DIV : basic_sse12_fp_binop_p<0x5E, "div", fdiv, SchedWriteFDivSizes>,
2583              basic_sse12_fp_binop_s<0x5E, "div", fdiv, SchedWriteFDivSizes>,
2584              basic_sse12_fp_binop_s_int<0x5E, "div", null_frag, SchedWriteFDivSizes>;
2585   defm MAX : basic_sse12_fp_binop_p<0x5F, "max", X86fmax, SchedWriteFCmpSizes>,
2586              basic_sse12_fp_binop_s<0x5F, "max", X86fmax, SchedWriteFCmpSizes>,
2587              basic_sse12_fp_binop_s_int<0x5F, "max", X86fmaxs, SchedWriteFCmpSizes>;
2588   defm MIN : basic_sse12_fp_binop_p<0x5D, "min", X86fmin, SchedWriteFCmpSizes>,
2589              basic_sse12_fp_binop_s<0x5D, "min", X86fmin, SchedWriteFCmpSizes>,
2590              basic_sse12_fp_binop_s_int<0x5D, "min", X86fmins, SchedWriteFCmpSizes>;
2591 }
2592
2593 let isCodeGenOnly = 1 in {
2594   defm MAXC: basic_sse12_fp_binop_p<0x5F, "max", X86fmaxc, SchedWriteFCmpSizes>,
2595              basic_sse12_fp_binop_s<0x5F, "max", X86fmaxc, SchedWriteFCmpSizes>;
2596   defm MINC: basic_sse12_fp_binop_p<0x5D, "min", X86fminc, SchedWriteFCmpSizes>,
2597              basic_sse12_fp_binop_s<0x5D, "min", X86fminc, SchedWriteFCmpSizes>;
2598 }
2599
2600 // Patterns used to select SSE scalar fp arithmetic instructions from
2601 // either:
2602 //
2603 // (1) a scalar fp operation followed by a blend
2604 //
2605 // The effect is that the backend no longer emits unnecessary vector
2606 // insert instructions immediately after SSE scalar fp instructions
2607 // like addss or mulss.
2608 //
2609 // For example, given the following code:
2610 //   __m128 foo(__m128 A, __m128 B) {
2611 //     A[0] += B[0];
2612 //     return A;
2613 //   }
2614 //
2615 // Previously we generated:
2616 //   addss %xmm0, %xmm1
2617 //   movss %xmm1, %xmm0
2618 //
2619 // We now generate:
2620 //   addss %xmm1, %xmm0
2621 //
2622 // (2) a vector packed single/double fp operation followed by a vector insert
2623 //
2624 // The effect is that the backend converts the packed fp instruction
2625 // followed by a vector insert into a single SSE scalar fp instruction.
2626 //
2627 // For example, given the following code:
2628 //   __m128 foo(__m128 A, __m128 B) {
2629 //     __m128 C = A + B;
2630 //     return (__m128) {c[0], a[1], a[2], a[3]};
2631 //   }
2632 //
2633 // Previously we generated:
2634 //   addps %xmm0, %xmm1
2635 //   movss %xmm1, %xmm0
2636 //
2637 // We now generate:
2638 //   addss %xmm1, %xmm0
2639
2640 // TODO: Some canonicalization in lowering would simplify the number of
2641 // patterns we have to try to match.
2642 multiclass scalar_math_patterns<SDNode Op, string OpcPrefix, SDNode Move,
2643                                     ValueType VT, ValueType EltTy,
2644                                     RegisterClass RC, Predicate BasePredicate> {
2645    let Predicates = [BasePredicate] in {
2646     // extracted scalar math op with insert via movss/movsd
2647     def : Pat<(VT (Move (VT VR128:$dst), (VT (scalar_to_vector
2648           (Op (EltTy (extractelt (VT VR128:$dst), (iPTR 0))),
2649           RC:$src))))),
2650       (!cast<Instruction>(OpcPrefix#rr_Int) VT:$dst,
2651           (COPY_TO_REGCLASS RC:$src, VR128))>;
2652
2653     // vector math op with insert via movss/movsd
2654     def : Pat<(VT (Move (VT VR128:$dst),
2655           (Op (VT VR128:$dst), (VT VR128:$src)))),
2656       (!cast<Instruction>(OpcPrefix#rr_Int) VT:$dst, VT:$src)>;
2657    }
2658
2659    // Repeat for AVX versions of the instructions.
2660    let Predicates = [UseAVX] in {
2661     // extracted scalar math op with insert via movss/movsd
2662     def : Pat<(VT (Move (VT VR128:$dst), (VT (scalar_to_vector
2663           (Op (EltTy (extractelt (VT VR128:$dst), (iPTR 0))),
2664           RC:$src))))),
2665       (!cast<Instruction>("V"#OpcPrefix#rr_Int) VT:$dst,
2666           (COPY_TO_REGCLASS RC:$src, VR128))>;
2667
2668     // vector math op with insert via movss/movsd
2669     def : Pat<(VT (Move (VT VR128:$dst),
2670           (Op (VT VR128:$dst), (VT VR128:$src)))),
2671       (!cast<Instruction>("V"#OpcPrefix#rr_Int) VT:$dst, VT:$src)>;
2672    }
2673 }
2674
2675 defm : scalar_math_patterns<fadd, "ADDSS", X86Movss, v4f32, f32, FR32, UseSSE1>;
2676 defm : scalar_math_patterns<fsub, "SUBSS", X86Movss, v4f32, f32, FR32, UseSSE1>;
2677 defm : scalar_math_patterns<fmul, "MULSS", X86Movss, v4f32, f32, FR32, UseSSE1>;
2678 defm : scalar_math_patterns<fdiv, "DIVSS", X86Movss, v4f32, f32, FR32, UseSSE1>;
2679
2680 defm : scalar_math_patterns<fadd, "ADDSD", X86Movsd, v2f64, f64, FR64, UseSSE2>;
2681 defm : scalar_math_patterns<fsub, "SUBSD", X86Movsd, v2f64, f64, FR64, UseSSE2>;
2682 defm : scalar_math_patterns<fmul, "MULSD", X86Movsd, v2f64, f64, FR64, UseSSE2>;
2683 defm : scalar_math_patterns<fdiv, "DIVSD", X86Movsd, v2f64, f64, FR64, UseSSE2>;
2684  
2685 /// Unop Arithmetic
2686 /// In addition, we also have a special variant of the scalar form here to
2687 /// represent the associated intrinsic operation.  This form is unlike the
2688 /// plain scalar form, in that it takes an entire vector (instead of a
2689 /// scalar) and leaves the top elements undefined.
2690 ///
2691 /// And, we have a special variant form for a full-vector intrinsic form.
2692
2693 /// sse_fp_unop_s - SSE1 unops in scalar form
2694 /// For the non-AVX defs, we need $src1 to be tied to $dst because
2695 /// the HW instructions are 2 operand / destructive.
2696 multiclass sse_fp_unop_s<bits<8> opc, string OpcodeStr, RegisterClass RC,
2697                           ValueType ScalarVT, X86MemOperand x86memop,
2698                           Operand intmemop, SDNode OpNode, Domain d,
2699                           X86FoldableSchedWrite sched, Predicate target> {
2700   let hasSideEffects = 0 in {
2701   def r : I<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src1),
2702               !strconcat(OpcodeStr, "\t{$src1, $dst|$dst, $src1}"),
2703             [(set RC:$dst, (OpNode RC:$src1))], d>, Sched<[sched]>,
2704             Requires<[target]>;
2705   let mayLoad = 1 in
2706   def m : I<opc, MRMSrcMem, (outs RC:$dst), (ins x86memop:$src1),
2707             !strconcat(OpcodeStr, "\t{$src1, $dst|$dst, $src1}"),
2708             [(set RC:$dst, (OpNode (load addr:$src1)))], d>,
2709             Sched<[sched.Folded, ReadAfterLd]>,
2710             Requires<[target, OptForSize]>;
2711
2712   let isCodeGenOnly = 1, Constraints = "$src1 = $dst", ExeDomain = d in {
2713   def r_Int : I<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src1, VR128:$src2),
2714                 !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"), []>,
2715                 Sched<[sched]>;
2716   let mayLoad = 1 in
2717   def m_Int : I<opc, MRMSrcMem, (outs VR128:$dst), (ins VR128:$src1, intmemop:$src2),
2718                 !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"), []>,
2719                 Sched<[sched.Folded, ReadAfterLd]>;
2720   }
2721   }
2722
2723 }
2724
2725 multiclass sse_fp_unop_s_intr<RegisterClass RC, ValueType vt,
2726                               ComplexPattern int_cpat, Intrinsic Intr,
2727                               Predicate target, string Suffix> {
2728   let Predicates = [target] in {
2729   // These are unary operations, but they are modeled as having 2 source operands
2730   // because the high elements of the destination are unchanged in SSE.
2731   def : Pat<(Intr VR128:$src),
2732             (!cast<Instruction>(NAME#r_Int) VR128:$src, VR128:$src)>;
2733   }
2734   // We don't want to fold scalar loads into these instructions unless
2735   // optimizing for size. This is because the folded instruction will have a
2736   // partial register update, while the unfolded sequence will not, e.g.
2737   // movss mem, %xmm0
2738   // rcpss %xmm0, %xmm0
2739   // which has a clobber before the rcp, vs.
2740   // rcpss mem, %xmm0
2741   let Predicates = [target, OptForSize] in {
2742     def : Pat<(Intr int_cpat:$src2),
2743                (!cast<Instruction>(NAME#m_Int)
2744                       (vt (IMPLICIT_DEF)), addr:$src2)>;
2745   }
2746 }
2747
2748 multiclass avx_fp_unop_s_intr<RegisterClass RC, ValueType vt, ComplexPattern int_cpat,
2749                               Intrinsic Intr, Predicate target> {
2750   let Predicates = [target] in {
2751    def : Pat<(Intr VR128:$src),
2752              (!cast<Instruction>(NAME#r_Int) VR128:$src,
2753                                  VR128:$src)>;
2754   }
2755   let Predicates = [target, OptForSize] in {
2756     def : Pat<(Intr int_cpat:$src2),
2757               (!cast<Instruction>(NAME#m_Int)
2758                     (vt (IMPLICIT_DEF)), addr:$src2)>;
2759   }
2760 }
2761
2762 multiclass avx_fp_unop_s<bits<8> opc, string OpcodeStr, RegisterClass RC,
2763                           ValueType ScalarVT, X86MemOperand x86memop,
2764                           Operand intmemop, SDNode OpNode, Domain d,
2765                           X86FoldableSchedWrite sched, Predicate target> {
2766   let hasSideEffects = 0 in {
2767   def r : I<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
2768             !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2769             [], d>, Sched<[sched]>;
2770   let mayLoad = 1 in
2771   def m : I<opc, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
2772              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2773             [], d>, Sched<[sched.Folded, ReadAfterLd]>;
2774   let isCodeGenOnly = 1, ExeDomain = d in {
2775   def r_Int : I<opc, MRMSrcReg, (outs VR128:$dst),
2776                 (ins VR128:$src1, VR128:$src2),
2777              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2778              []>, Sched<[sched]>;
2779   let mayLoad = 1 in
2780   def m_Int : I<opc, MRMSrcMem, (outs VR128:$dst),
2781                 (ins VR128:$src1, intmemop:$src2),
2782              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
2783              []>, Sched<[sched.Folded, ReadAfterLd]>;
2784   }
2785   }
2786
2787   // We don't want to fold scalar loads into these instructions unless
2788   // optimizing for size. This is because the folded instruction will have a
2789   // partial register update, while the unfolded sequence will not, e.g.
2790   // vmovss mem, %xmm0
2791   // vrcpss %xmm0, %xmm0, %xmm0
2792   // which has a clobber before the rcp, vs.
2793   // vrcpss mem, %xmm0, %xmm0
2794   // TODO: In theory, we could fold the load, and avoid the stall caused by
2795   // the partial register store, either in BreakFalseDeps or with smarter RA.
2796   let Predicates = [target] in {
2797    def : Pat<(OpNode RC:$src),  (!cast<Instruction>(NAME#r)
2798                                 (ScalarVT (IMPLICIT_DEF)), RC:$src)>;
2799   }
2800   let Predicates = [target, OptForSize] in {
2801     def : Pat<(ScalarVT (OpNode (load addr:$src))),
2802               (!cast<Instruction>(NAME#m) (ScalarVT (IMPLICIT_DEF)),
2803             addr:$src)>;
2804   }
2805 }
2806
2807 /// sse1_fp_unop_p - SSE1 unops in packed form.
2808 multiclass sse1_fp_unop_p<bits<8> opc, string OpcodeStr, SDNode OpNode,
2809                           X86SchedWriteWidths sched, list<Predicate> prds> {
2810 let Predicates = prds in {
2811   def V#NAME#PSr : PSI<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2812                        !strconcat("v", OpcodeStr,
2813                                   "ps\t{$src, $dst|$dst, $src}"),
2814                        [(set VR128:$dst, (v4f32 (OpNode VR128:$src)))]>,
2815                        VEX, Sched<[sched.XMM]>, VEX_WIG;
2816   def V#NAME#PSm : PSI<opc, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
2817                        !strconcat("v", OpcodeStr,
2818                                   "ps\t{$src, $dst|$dst, $src}"),
2819                        [(set VR128:$dst, (OpNode (loadv4f32 addr:$src)))]>,
2820                        VEX, Sched<[sched.XMM.Folded]>, VEX_WIG;
2821   def V#NAME#PSYr : PSI<opc, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
2822                         !strconcat("v", OpcodeStr,
2823                                    "ps\t{$src, $dst|$dst, $src}"),
2824                         [(set VR256:$dst, (v8f32 (OpNode VR256:$src)))]>,
2825                         VEX, VEX_L, Sched<[sched.YMM]>, VEX_WIG;
2826   def V#NAME#PSYm : PSI<opc, MRMSrcMem, (outs VR256:$dst), (ins f256mem:$src),
2827                         !strconcat("v", OpcodeStr,
2828                                    "ps\t{$src, $dst|$dst, $src}"),
2829                         [(set VR256:$dst, (OpNode (loadv8f32 addr:$src)))]>,
2830                         VEX, VEX_L, Sched<[sched.YMM.Folded]>, VEX_WIG;
2831 }
2832
2833   def PSr : PSI<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2834                 !strconcat(OpcodeStr, "ps\t{$src, $dst|$dst, $src}"),
2835                 [(set VR128:$dst, (v4f32 (OpNode VR128:$src)))]>,
2836                 Sched<[sched.XMM]>;
2837   def PSm : PSI<opc, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
2838                 !strconcat(OpcodeStr, "ps\t{$src, $dst|$dst, $src}"),
2839                 [(set VR128:$dst, (OpNode (memopv4f32 addr:$src)))]>,
2840                 Sched<[sched.XMM.Folded]>;
2841 }
2842
2843 /// sse2_fp_unop_p - SSE2 unops in vector forms.
2844 multiclass sse2_fp_unop_p<bits<8> opc, string OpcodeStr,
2845                           SDNode OpNode, X86SchedWriteWidths sched> {
2846 let Predicates = [HasAVX, NoVLX] in {
2847   def V#NAME#PDr : PDI<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2848                        !strconcat("v", OpcodeStr,
2849                                   "pd\t{$src, $dst|$dst, $src}"),
2850                        [(set VR128:$dst, (v2f64 (OpNode VR128:$src)))]>,
2851                        VEX, Sched<[sched.XMM]>, VEX_WIG;
2852   def V#NAME#PDm : PDI<opc, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
2853                        !strconcat("v", OpcodeStr,
2854                                   "pd\t{$src, $dst|$dst, $src}"),
2855                        [(set VR128:$dst, (OpNode (loadv2f64 addr:$src)))]>,
2856                        VEX, Sched<[sched.XMM.Folded]>, VEX_WIG;
2857   def V#NAME#PDYr : PDI<opc, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
2858                         !strconcat("v", OpcodeStr,
2859                                    "pd\t{$src, $dst|$dst, $src}"),
2860                         [(set VR256:$dst, (v4f64 (OpNode VR256:$src)))]>,
2861                         VEX, VEX_L, Sched<[sched.YMM]>, VEX_WIG;
2862   def V#NAME#PDYm : PDI<opc, MRMSrcMem, (outs VR256:$dst), (ins f256mem:$src),
2863                         !strconcat("v", OpcodeStr,
2864                                    "pd\t{$src, $dst|$dst, $src}"),
2865                         [(set VR256:$dst, (OpNode (loadv4f64 addr:$src)))]>,
2866                         VEX, VEX_L, Sched<[sched.YMM.Folded]>, VEX_WIG;
2867 }
2868
2869   def PDr : PDI<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2870                 !strconcat(OpcodeStr, "pd\t{$src, $dst|$dst, $src}"),
2871                 [(set VR128:$dst, (v2f64 (OpNode VR128:$src)))]>,
2872                 Sched<[sched.XMM]>;
2873   def PDm : PDI<opc, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
2874                 !strconcat(OpcodeStr, "pd\t{$src, $dst|$dst, $src}"),
2875                 [(set VR128:$dst, (OpNode (memopv2f64 addr:$src)))]>,
2876                 Sched<[sched.XMM.Folded]>;
2877 }
2878
2879 multiclass sse1_fp_unop_s_intr<bits<8> opc, string OpcodeStr, SDNode OpNode,
2880                           X86SchedWriteWidths sched, Predicate AVXTarget> {
2881   defm SS        :  sse_fp_unop_s_intr<FR32, v4f32, sse_load_f32,
2882                       !cast<Intrinsic>("int_x86_sse_"##OpcodeStr##_ss),
2883                       UseSSE1, "SS">, XS;
2884   defm V#NAME#SS  : avx_fp_unop_s_intr<FR32, v4f32, sse_load_f32,
2885                       !cast<Intrinsic>("int_x86_sse_"##OpcodeStr##_ss),
2886                       AVXTarget>,
2887                       XS, VEX_4V, VEX_LIG, VEX_WIG, NotMemoryFoldable;
2888 }
2889
2890 multiclass sse1_fp_unop_s<bits<8> opc, string OpcodeStr, SDNode OpNode,
2891                           X86SchedWriteWidths sched, Predicate AVXTarget> {
2892   defm SS        :  sse_fp_unop_s<opc, OpcodeStr##ss, FR32, f32, f32mem,
2893                       ssmem, OpNode, SSEPackedSingle, sched.Scl, UseSSE1>, XS;
2894   defm V#NAME#SS  : avx_fp_unop_s<opc, "v"#OpcodeStr##ss, FR32, f32,
2895                       f32mem, ssmem, OpNode, SSEPackedSingle, sched.Scl, AVXTarget>,
2896                        XS, VEX_4V, VEX_LIG, VEX_WIG;
2897 }
2898
2899 multiclass sse2_fp_unop_s<bits<8> opc, string OpcodeStr, SDNode OpNode,
2900                           X86SchedWriteWidths sched, Predicate AVXTarget> {
2901   defm SD         : sse_fp_unop_s<opc, OpcodeStr##sd, FR64, f64, f64mem,
2902                          sdmem, OpNode, SSEPackedDouble, sched.Scl, UseSSE2>, XD;
2903   defm V#NAME#SD  : avx_fp_unop_s<opc, "v"#OpcodeStr##sd, FR64, f64,
2904                          f64mem, sdmem, OpNode, SSEPackedDouble, sched.Scl, AVXTarget>,
2905                          XD, VEX_4V, VEX_LIG, VEX_WIG;
2906 }
2907
2908 // Square root.
2909 defm SQRT  : sse1_fp_unop_s<0x51, "sqrt", fsqrt, SchedWriteFSqrt, UseAVX>,
2910              sse1_fp_unop_p<0x51, "sqrt", fsqrt, SchedWriteFSqrt, [HasAVX, NoVLX]>,
2911              sse2_fp_unop_s<0x51, "sqrt", fsqrt, SchedWriteFSqrt64, UseAVX>,
2912              sse2_fp_unop_p<0x51, "sqrt", fsqrt, SchedWriteFSqrt64>;
2913
2914 // Reciprocal approximations. Note that these typically require refinement
2915 // in order to obtain suitable precision.
2916 defm RSQRT : sse1_fp_unop_s<0x52, "rsqrt", X86frsqrt, SchedWriteFRsqrt, HasAVX>,
2917              sse1_fp_unop_s_intr<0x52, "rsqrt", X86frsqrt, SchedWriteFRsqrt, HasAVX>,
2918              sse1_fp_unop_p<0x52, "rsqrt", X86frsqrt, SchedWriteFRsqrt, [HasAVX]>;
2919 defm RCP   : sse1_fp_unop_s<0x53, "rcp", X86frcp, SchedWriteFRcp, HasAVX>,
2920              sse1_fp_unop_s_intr<0x53, "rcp", X86frcp, SchedWriteFRcp, HasAVX>,
2921              sse1_fp_unop_p<0x53, "rcp", X86frcp, SchedWriteFRcp, [HasAVX]>;
2922
2923 // There is no f64 version of the reciprocal approximation instructions.
2924
2925 multiclass scalar_unary_math_patterns<SDNode OpNode, string OpcPrefix, SDNode Move,
2926                                       ValueType VT, Predicate BasePredicate> {
2927   let Predicates = [BasePredicate] in {
2928     def : Pat<(VT (Move VT:$dst, (scalar_to_vector
2929                                   (OpNode (extractelt VT:$src, 0))))),
2930               (!cast<Instruction>(OpcPrefix#r_Int) VT:$dst, VT:$src)>;
2931   }
2932
2933   // Repeat for AVX versions of the instructions.
2934   let Predicates = [UseAVX] in {
2935     def : Pat<(VT (Move VT:$dst, (scalar_to_vector
2936                                   (OpNode (extractelt VT:$src, 0))))),
2937               (!cast<Instruction>("V"#OpcPrefix#r_Int) VT:$dst, VT:$src)>;
2938   }
2939 }
2940
2941 multiclass scalar_unary_math_imm_patterns<SDNode OpNode, string OpcPrefix, SDNode Move,
2942                                           ValueType VT, bits<8> ImmV,
2943                                           Predicate BasePredicate> {
2944   let Predicates = [BasePredicate] in {
2945     def : Pat<(VT (Move VT:$dst, (scalar_to_vector
2946                                   (OpNode (extractelt VT:$src, 0))))),
2947               (!cast<Instruction>(OpcPrefix#r_Int) VT:$dst, VT:$src, (i32 ImmV))>;
2948   }
2949
2950   // Repeat for AVX versions of the instructions.
2951   let Predicates = [UseAVX] in {
2952     def : Pat<(VT (Move VT:$dst, (scalar_to_vector
2953                                   (OpNode (extractelt VT:$src, 0))))),
2954               (!cast<Instruction>("V"#OpcPrefix#r_Int) VT:$dst, VT:$src, (i32 ImmV))>;
2955   }
2956 }
2957
2958 defm : scalar_unary_math_patterns<fsqrt, "SQRTSS", X86Movss, v4f32, UseSSE1>;
2959 defm : scalar_unary_math_patterns<fsqrt, "SQRTSD", X86Movsd, v2f64, UseSSE2>;
2960
2961 multiclass scalar_unary_math_intr_patterns<Intrinsic Intr, string OpcPrefix,
2962                                            SDNode Move, ValueType VT,
2963                                            Predicate BasePredicate> {
2964   let Predicates = [BasePredicate] in {
2965     def : Pat<(VT (Move VT:$dst, (Intr VT:$src))),
2966               (!cast<Instruction>(OpcPrefix#r_Int) VT:$dst, VT:$src)>;
2967   }
2968
2969   // Repeat for AVX versions of the instructions.
2970   let Predicates = [HasAVX] in {
2971     def : Pat<(VT (Move VT:$dst, (Intr VT:$src))),
2972               (!cast<Instruction>("V"#OpcPrefix#r_Int) VT:$dst, VT:$src)>;
2973   }
2974 }
2975
2976 defm : scalar_unary_math_intr_patterns<int_x86_sse_rcp_ss, "RCPSS", X86Movss,
2977                                        v4f32, UseSSE1>;
2978 defm : scalar_unary_math_intr_patterns<int_x86_sse_rsqrt_ss, "RSQRTSS", X86Movss,
2979                                        v4f32, UseSSE1>;
2980
2981
2982 //===----------------------------------------------------------------------===//
2983 // SSE 1 & 2 - Non-temporal stores
2984 //===----------------------------------------------------------------------===//
2985
2986 let AddedComplexity = 400 in { // Prefer non-temporal versions
2987 let Predicates = [HasAVX, NoVLX] in {
2988 let SchedRW = [SchedWriteFMoveLSNT.XMM.MR] in {
2989 def VMOVNTPSmr : VPSI<0x2B, MRMDestMem, (outs),
2990                      (ins f128mem:$dst, VR128:$src),
2991                      "movntps\t{$src, $dst|$dst, $src}",
2992                      [(alignednontemporalstore (v4f32 VR128:$src),
2993                                                addr:$dst)]>, VEX, VEX_WIG;
2994 def VMOVNTPDmr : VPDI<0x2B, MRMDestMem, (outs),
2995                      (ins f128mem:$dst, VR128:$src),
2996                      "movntpd\t{$src, $dst|$dst, $src}",
2997                      [(alignednontemporalstore (v2f64 VR128:$src),
2998                                                addr:$dst)]>, VEX, VEX_WIG;
2999 } // SchedRW
3000
3001 let SchedRW = [SchedWriteFMoveLSNT.YMM.MR] in {
3002 def VMOVNTPSYmr : VPSI<0x2B, MRMDestMem, (outs),
3003                      (ins f256mem:$dst, VR256:$src),
3004                      "movntps\t{$src, $dst|$dst, $src}",
3005                      [(alignednontemporalstore (v8f32 VR256:$src),
3006                                                addr:$dst)]>, VEX, VEX_L, VEX_WIG;
3007 def VMOVNTPDYmr : VPDI<0x2B, MRMDestMem, (outs),
3008                      (ins f256mem:$dst, VR256:$src),
3009                      "movntpd\t{$src, $dst|$dst, $src}",
3010                      [(alignednontemporalstore (v4f64 VR256:$src),
3011                                                addr:$dst)]>, VEX, VEX_L, VEX_WIG;
3012 } // SchedRW
3013
3014 let ExeDomain = SSEPackedInt in {
3015 def VMOVNTDQmr    : VPDI<0xE7, MRMDestMem, (outs),
3016                          (ins i128mem:$dst, VR128:$src),
3017                          "movntdq\t{$src, $dst|$dst, $src}",
3018                          [(alignednontemporalstore (v2i64 VR128:$src),
3019                                                    addr:$dst)]>, VEX, VEX_WIG,
3020                          Sched<[SchedWriteVecMoveLSNT.XMM.MR]>;
3021 def VMOVNTDQYmr : VPDI<0xE7, MRMDestMem, (outs),
3022                     (ins i256mem:$dst, VR256:$src),
3023                     "movntdq\t{$src, $dst|$dst, $src}",
3024                     [(alignednontemporalstore (v4i64 VR256:$src),
3025                                               addr:$dst)]>, VEX, VEX_L, VEX_WIG,
3026                     Sched<[SchedWriteVecMoveLSNT.YMM.MR]>;
3027 } // ExeDomain
3028 } // Predicates
3029
3030 let SchedRW = [SchedWriteFMoveLSNT.XMM.MR] in {
3031 def MOVNTPSmr : PSI<0x2B, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
3032                     "movntps\t{$src, $dst|$dst, $src}",
3033                     [(alignednontemporalstore (v4f32 VR128:$src), addr:$dst)]>;
3034 def MOVNTPDmr : PDI<0x2B, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
3035                     "movntpd\t{$src, $dst|$dst, $src}",
3036                     [(alignednontemporalstore(v2f64 VR128:$src), addr:$dst)]>;
3037 } // SchedRW
3038
3039 let ExeDomain = SSEPackedInt, SchedRW = [SchedWriteVecMoveLSNT.XMM.MR] in
3040 def MOVNTDQmr : PDI<0xE7, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
3041                     "movntdq\t{$src, $dst|$dst, $src}",
3042                     [(alignednontemporalstore (v2i64 VR128:$src), addr:$dst)]>;
3043
3044 let SchedRW = [WriteStoreNT] in {
3045 // There is no AVX form for instructions below this point
3046 def MOVNTImr : I<0xC3, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
3047                  "movnti{l}\t{$src, $dst|$dst, $src}",
3048                  [(nontemporalstore (i32 GR32:$src), addr:$dst)]>,
3049                PS, Requires<[HasSSE2]>;
3050 def MOVNTI_64mr : RI<0xC3, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
3051                      "movnti{q}\t{$src, $dst|$dst, $src}",
3052                      [(nontemporalstore (i64 GR64:$src), addr:$dst)]>,
3053                   PS, Requires<[HasSSE2]>;
3054 } // SchedRW = [WriteStoreNT]
3055
3056 let Predicates = [HasAVX, NoVLX] in {
3057   def : Pat<(alignednontemporalstore (v8i32 VR256:$src), addr:$dst),
3058             (VMOVNTDQYmr addr:$dst, VR256:$src)>;
3059   def : Pat<(alignednontemporalstore (v16i16 VR256:$src), addr:$dst),
3060             (VMOVNTDQYmr addr:$dst, VR256:$src)>;
3061   def : Pat<(alignednontemporalstore (v32i8 VR256:$src), addr:$dst),
3062             (VMOVNTDQYmr addr:$dst, VR256:$src)>;
3063
3064   def : Pat<(alignednontemporalstore (v4i32 VR128:$src), addr:$dst),
3065             (VMOVNTDQmr addr:$dst, VR128:$src)>;
3066   def : Pat<(alignednontemporalstore (v8i16 VR128:$src), addr:$dst),
3067             (VMOVNTDQmr addr:$dst, VR128:$src)>;
3068   def : Pat<(alignednontemporalstore (v16i8 VR128:$src), addr:$dst),
3069             (VMOVNTDQmr addr:$dst, VR128:$src)>;
3070 }
3071
3072 let Predicates = [UseSSE2] in {
3073   def : Pat<(alignednontemporalstore (v4i32 VR128:$src), addr:$dst),
3074             (MOVNTDQmr addr:$dst, VR128:$src)>;
3075   def : Pat<(alignednontemporalstore (v8i16 VR128:$src), addr:$dst),
3076             (MOVNTDQmr addr:$dst, VR128:$src)>;
3077   def : Pat<(alignednontemporalstore (v16i8 VR128:$src), addr:$dst),
3078             (MOVNTDQmr addr:$dst, VR128:$src)>;
3079 }
3080
3081 } // AddedComplexity
3082
3083 //===----------------------------------------------------------------------===//
3084 // SSE 1 & 2 - Prefetch and memory fence
3085 //===----------------------------------------------------------------------===//
3086
3087 // Prefetch intrinsic.
3088 let Predicates = [HasSSEPrefetch], SchedRW = [WriteLoad] in {
3089 def PREFETCHT0   : I<0x18, MRM1m, (outs), (ins i8mem:$src),
3090     "prefetcht0\t$src", [(prefetch addr:$src, imm, (i32 3), (i32 1))]>, TB;
3091 def PREFETCHT1   : I<0x18, MRM2m, (outs), (ins i8mem:$src),
3092     "prefetcht1\t$src", [(prefetch addr:$src, imm, (i32 2), (i32 1))]>, TB;
3093 def PREFETCHT2   : I<0x18, MRM3m, (outs), (ins i8mem:$src),
3094     "prefetcht2\t$src", [(prefetch addr:$src, imm, (i32 1), (i32 1))]>, TB;
3095 def PREFETCHNTA  : I<0x18, MRM0m, (outs), (ins i8mem:$src),
3096     "prefetchnta\t$src", [(prefetch addr:$src, imm, (i32 0), (i32 1))]>, TB;
3097 }
3098
3099 // FIXME: How should flush instruction be modeled?
3100 let SchedRW = [WriteLoad] in {
3101 // Flush cache
3102 def CLFLUSH : I<0xAE, MRM7m, (outs), (ins i8mem:$src),
3103                "clflush\t$src", [(int_x86_sse2_clflush addr:$src)]>,
3104                PS, Requires<[HasSSE2]>;
3105 }
3106
3107 let SchedRW = [WriteNop] in {
3108 // Pause. This "instruction" is encoded as "rep; nop", so even though it
3109 // was introduced with SSE2, it's backward compatible.
3110 def PAUSE : I<0x90, RawFrm, (outs), (ins),
3111               "pause", [(int_x86_sse2_pause)]>, OBXS;
3112 }
3113
3114 let SchedRW = [WriteFence] in {
3115 // Load, store, and memory fence
3116 // TODO: As with mfence, we may want to ease the availablity of sfence/lfence
3117 // to include any 64-bit target.
3118 def SFENCE : I<0xAE, MRM_F8, (outs), (ins), "sfence", [(int_x86_sse_sfence)]>,
3119                PS, Requires<[HasSSE1]>;
3120 def LFENCE : I<0xAE, MRM_E8, (outs), (ins), "lfence", [(int_x86_sse2_lfence)]>,
3121                PS, Requires<[HasSSE2]>;
3122 def MFENCE : I<0xAE, MRM_F0, (outs), (ins), "mfence", [(int_x86_sse2_mfence)]>,
3123                PS, Requires<[HasMFence]>;
3124 } // SchedRW
3125
3126 def : Pat<(X86MFence), (MFENCE)>;
3127
3128 //===----------------------------------------------------------------------===//
3129 // SSE 1 & 2 - Load/Store XCSR register
3130 //===----------------------------------------------------------------------===//
3131
3132 def VLDMXCSR : VPSI<0xAE, MRM2m, (outs), (ins i32mem:$src),
3133                "ldmxcsr\t$src", [(int_x86_sse_ldmxcsr addr:$src)]>,
3134                VEX, Sched<[WriteLDMXCSR]>, VEX_WIG;
3135 def VSTMXCSR : VPSI<0xAE, MRM3m, (outs), (ins i32mem:$dst),
3136                "stmxcsr\t$dst", [(int_x86_sse_stmxcsr addr:$dst)]>,
3137                VEX, Sched<[WriteSTMXCSR]>, VEX_WIG;
3138
3139 def LDMXCSR : I<0xAE, MRM2m, (outs), (ins i32mem:$src),
3140               "ldmxcsr\t$src", [(int_x86_sse_ldmxcsr addr:$src)]>,
3141               TB, Sched<[WriteLDMXCSR]>;
3142 def STMXCSR : I<0xAE, MRM3m, (outs), (ins i32mem:$dst),
3143               "stmxcsr\t$dst", [(int_x86_sse_stmxcsr addr:$dst)]>,
3144               TB, Sched<[WriteSTMXCSR]>;
3145
3146 //===---------------------------------------------------------------------===//
3147 // SSE2 - Move Aligned/Unaligned Packed Integer Instructions
3148 //===---------------------------------------------------------------------===//
3149
3150 let ExeDomain = SSEPackedInt in { // SSE integer instructions
3151
3152 let hasSideEffects = 0 in {
3153 def VMOVDQArr  : VPDI<0x6F, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3154                       "movdqa\t{$src, $dst|$dst, $src}", []>,
3155                       Sched<[SchedWriteVecMoveLS.XMM.RR]>, VEX, VEX_WIG;
3156 def VMOVDQUrr  : VSSI<0x6F, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3157                       "movdqu\t{$src, $dst|$dst, $src}", []>,
3158                       Sched<[SchedWriteVecMoveLS.XMM.RR]>, VEX, VEX_WIG;
3159 def VMOVDQAYrr : VPDI<0x6F, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
3160                       "movdqa\t{$src, $dst|$dst, $src}", []>,
3161                       Sched<[SchedWriteVecMoveLS.YMM.RR]>, VEX, VEX_L, VEX_WIG;
3162 def VMOVDQUYrr : VSSI<0x6F, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
3163                       "movdqu\t{$src, $dst|$dst, $src}", []>,
3164                       Sched<[SchedWriteVecMoveLS.YMM.RR]>, VEX, VEX_L, VEX_WIG;
3165 }
3166
3167 // For Disassembler
3168 let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0 in {
3169 def VMOVDQArr_REV  : VPDI<0x7F, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
3170                           "movdqa\t{$src, $dst|$dst, $src}", []>,
3171                           Sched<[SchedWriteVecMoveLS.XMM.RR]>,
3172                           VEX, VEX_WIG, FoldGenData<"VMOVDQArr">;
3173 def VMOVDQAYrr_REV : VPDI<0x7F, MRMDestReg, (outs VR256:$dst), (ins VR256:$src),
3174                           "movdqa\t{$src, $dst|$dst, $src}", []>,
3175                           Sched<[SchedWriteVecMoveLS.YMM.RR]>,
3176                           VEX, VEX_L, VEX_WIG, FoldGenData<"VMOVDQAYrr">;
3177 def VMOVDQUrr_REV  : VSSI<0x7F, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
3178                           "movdqu\t{$src, $dst|$dst, $src}", []>,
3179                           Sched<[SchedWriteVecMoveLS.XMM.RR]>,
3180                           VEX, VEX_WIG, FoldGenData<"VMOVDQUrr">;
3181 def VMOVDQUYrr_REV : VSSI<0x7F, MRMDestReg, (outs VR256:$dst), (ins VR256:$src),
3182                           "movdqu\t{$src, $dst|$dst, $src}", []>,
3183                           Sched<[SchedWriteVecMoveLS.YMM.RR]>,
3184                           VEX, VEX_L, VEX_WIG, FoldGenData<"VMOVDQUYrr">;
3185 }
3186
3187 let canFoldAsLoad = 1, mayLoad = 1, isReMaterializable = 1,
3188     hasSideEffects = 0, Predicates = [HasAVX,NoVLX] in {
3189 def VMOVDQArm  : VPDI<0x6F, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
3190                       "movdqa\t{$src, $dst|$dst, $src}",
3191                       [(set VR128:$dst, (alignedloadv2i64 addr:$src))]>,
3192                       Sched<[SchedWriteVecMoveLS.XMM.RM]>, VEX, VEX_WIG;
3193 def VMOVDQAYrm : VPDI<0x6F, MRMSrcMem, (outs VR256:$dst), (ins i256mem:$src),
3194                       "movdqa\t{$src, $dst|$dst, $src}", []>,
3195                       Sched<[SchedWriteVecMoveLS.YMM.RM]>,
3196                       VEX, VEX_L, VEX_WIG;
3197 def VMOVDQUrm  : I<0x6F, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
3198                    "vmovdqu\t{$src, $dst|$dst, $src}",
3199                    [(set VR128:$dst, (loadv2i64 addr:$src))]>,
3200                    Sched<[SchedWriteVecMoveLS.XMM.RM]>,
3201                    XS, VEX, VEX_WIG;
3202 def VMOVDQUYrm : I<0x6F, MRMSrcMem, (outs VR256:$dst), (ins i256mem:$src),
3203                    "vmovdqu\t{$src, $dst|$dst, $src}", []>,
3204                    Sched<[SchedWriteVecMoveLS.YMM.RM]>,
3205                    XS, VEX, VEX_L, VEX_WIG;
3206 }
3207
3208 let mayStore = 1, hasSideEffects = 0, Predicates = [HasAVX,NoVLX] in {
3209 def VMOVDQAmr  : VPDI<0x7F, MRMDestMem, (outs),
3210                       (ins i128mem:$dst, VR128:$src),
3211                       "movdqa\t{$src, $dst|$dst, $src}",
3212                       [(alignedstore (v2i64 VR128:$src), addr:$dst)]>,
3213                       Sched<[SchedWriteVecMoveLS.XMM.MR]>, VEX, VEX_WIG;
3214 def VMOVDQAYmr : VPDI<0x7F, MRMDestMem, (outs),
3215                       (ins i256mem:$dst, VR256:$src),
3216                       "movdqa\t{$src, $dst|$dst, $src}", []>,
3217                      Sched<[SchedWriteVecMoveLS.YMM.MR]>, VEX, VEX_L, VEX_WIG;
3218 def VMOVDQUmr  : I<0x7F, MRMDestMem, (outs), (ins i128mem:$dst, VR128:$src),
3219                    "vmovdqu\t{$src, $dst|$dst, $src}",
3220                    [(store (v2i64 VR128:$src), addr:$dst)]>,
3221                    Sched<[SchedWriteVecMoveLS.XMM.MR]>, XS, VEX, VEX_WIG;
3222 def VMOVDQUYmr : I<0x7F, MRMDestMem, (outs), (ins i256mem:$dst, VR256:$src),
3223                    "vmovdqu\t{$src, $dst|$dst, $src}",[]>,
3224                    Sched<[SchedWriteVecMoveLS.YMM.MR]>, XS, VEX, VEX_L, VEX_WIG;
3225 }
3226
3227 let SchedRW = [SchedWriteVecMoveLS.XMM.RR] in {
3228 let hasSideEffects = 0 in {
3229 def MOVDQArr : PDI<0x6F, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3230                    "movdqa\t{$src, $dst|$dst, $src}", []>;
3231
3232 def MOVDQUrr :   I<0x6F, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3233                    "movdqu\t{$src, $dst|$dst, $src}", []>,
3234                    XS, Requires<[UseSSE2]>;
3235 }
3236
3237 // For Disassembler
3238 let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0 in {
3239 def MOVDQArr_REV : PDI<0x7F, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
3240                        "movdqa\t{$src, $dst|$dst, $src}", []>,
3241                        FoldGenData<"MOVDQArr">;
3242
3243 def MOVDQUrr_REV :   I<0x7F, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
3244                        "movdqu\t{$src, $dst|$dst, $src}", []>,
3245                        XS, Requires<[UseSSE2]>, FoldGenData<"MOVDQUrr">;
3246 }
3247 } // SchedRW
3248
3249 let canFoldAsLoad = 1, mayLoad = 1, isReMaterializable = 1,
3250     hasSideEffects = 0, SchedRW = [SchedWriteVecMoveLS.XMM.RM] in {
3251 def MOVDQArm : PDI<0x6F, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
3252                    "movdqa\t{$src, $dst|$dst, $src}",
3253                    [/*(set VR128:$dst, (alignedloadv2i64 addr:$src))*/]>;
3254 def MOVDQUrm :   I<0x6F, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
3255                    "movdqu\t{$src, $dst|$dst, $src}",
3256                    [/*(set VR128:$dst, (loadv2i64 addr:$src))*/]>,
3257                  XS, Requires<[UseSSE2]>;
3258 }
3259
3260 let mayStore = 1, hasSideEffects = 0,
3261     SchedRW = [SchedWriteVecMoveLS.XMM.MR] in {
3262 def MOVDQAmr : PDI<0x7F, MRMDestMem, (outs), (ins i128mem:$dst, VR128:$src),
3263                    "movdqa\t{$src, $dst|$dst, $src}",
3264                    [/*(alignedstore (v2i64 VR128:$src), addr:$dst)*/]>;
3265 def MOVDQUmr :   I<0x7F, MRMDestMem, (outs), (ins i128mem:$dst, VR128:$src),
3266                    "movdqu\t{$src, $dst|$dst, $src}",
3267                    [/*(store (v2i64 VR128:$src), addr:$dst)*/]>,
3268                  XS, Requires<[UseSSE2]>;
3269 }
3270
3271 } // ExeDomain = SSEPackedInt
3272
3273 // Aliases to help the assembler pick two byte VEX encodings by swapping the
3274 // operands relative to the normal instructions to use VEX.R instead of VEX.B.
3275 def : InstAlias<"vmovdqa\t{$src, $dst|$dst, $src}",
3276                 (VMOVDQArr_REV VR128L:$dst, VR128H:$src), 0>;
3277 def : InstAlias<"vmovdqa\t{$src, $dst|$dst, $src}",
3278                 (VMOVDQAYrr_REV VR256L:$dst, VR256H:$src), 0>;
3279 def : InstAlias<"vmovdqu\t{$src, $dst|$dst, $src}",
3280                 (VMOVDQUrr_REV VR128L:$dst, VR128H:$src), 0>;
3281 def : InstAlias<"vmovdqu\t{$src, $dst|$dst, $src}",
3282                 (VMOVDQUYrr_REV VR256L:$dst, VR256H:$src), 0>;
3283
3284 // Reversed version with ".s" suffix for GAS compatibility.
3285 def : InstAlias<"vmovdqa.s\t{$src, $dst|$dst, $src}",
3286                 (VMOVDQArr_REV VR128:$dst, VR128:$src), 0>;
3287 def : InstAlias<"vmovdqa.s\t{$src, $dst|$dst, $src}",
3288                 (VMOVDQAYrr_REV VR256:$dst, VR256:$src), 0>;
3289 def : InstAlias<"vmovdqu.s\t{$src, $dst|$dst, $src}",
3290                 (VMOVDQUrr_REV VR128:$dst, VR128:$src), 0>;
3291 def : InstAlias<"vmovdqu.s\t{$src, $dst|$dst, $src}",
3292                 (VMOVDQUYrr_REV VR256:$dst, VR256:$src), 0>;
3293
3294 // Reversed version with ".s" suffix for GAS compatibility.
3295 def : InstAlias<"movdqa.s\t{$src, $dst|$dst, $src}",
3296                 (MOVDQArr_REV VR128:$dst, VR128:$src), 0>;
3297 def : InstAlias<"movdqu.s\t{$src, $dst|$dst, $src}",
3298                 (MOVDQUrr_REV VR128:$dst, VR128:$src), 0>;
3299
3300 let Predicates = [HasAVX, NoVLX] in {
3301   // Additional patterns for other integer sizes.
3302   def : Pat<(alignedstore (v4i32 VR128:$src), addr:$dst),
3303             (VMOVDQAmr addr:$dst, VR128:$src)>;
3304   def : Pat<(alignedstore (v8i16 VR128:$src), addr:$dst),
3305             (VMOVDQAmr addr:$dst, VR128:$src)>;
3306   def : Pat<(alignedstore (v16i8 VR128:$src), addr:$dst),
3307             (VMOVDQAmr addr:$dst, VR128:$src)>;
3308   def : Pat<(store (v4i32 VR128:$src), addr:$dst),
3309             (VMOVDQUmr addr:$dst, VR128:$src)>;
3310   def : Pat<(store (v8i16 VR128:$src), addr:$dst),
3311             (VMOVDQUmr addr:$dst, VR128:$src)>;
3312   def : Pat<(store (v16i8 VR128:$src), addr:$dst),
3313             (VMOVDQUmr addr:$dst, VR128:$src)>;
3314 }
3315
3316 //===---------------------------------------------------------------------===//
3317 // SSE2 - Packed Integer Arithmetic Instructions
3318 //===---------------------------------------------------------------------===//
3319
3320 let ExeDomain = SSEPackedInt in { // SSE integer instructions
3321
3322 /// PDI_binop_rm2 - Simple SSE2 binary operator with different src and dst types
3323 multiclass PDI_binop_rm2<bits<8> opc, string OpcodeStr, SDNode OpNode,
3324                          ValueType DstVT, ValueType SrcVT, RegisterClass RC,
3325                          PatFrag memop_frag, X86MemOperand x86memop,
3326                          X86FoldableSchedWrite sched, bit Is2Addr = 1> {
3327   let isCommutable = 1 in
3328   def rr : PDI<opc, MRMSrcReg, (outs RC:$dst),
3329        (ins RC:$src1, RC:$src2),
3330        !if(Is2Addr,
3331            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
3332            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
3333        [(set RC:$dst, (DstVT (OpNode (SrcVT RC:$src1), RC:$src2)))]>,
3334        Sched<[sched]>;
3335   def rm : PDI<opc, MRMSrcMem, (outs RC:$dst),
3336        (ins RC:$src1, x86memop:$src2),
3337        !if(Is2Addr,
3338            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
3339            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
3340        [(set RC:$dst, (DstVT (OpNode (SrcVT RC:$src1),
3341                                      (bitconvert (memop_frag addr:$src2)))))]>,
3342        Sched<[sched.Folded, ReadAfterLd]>;
3343 }
3344 } // ExeDomain = SSEPackedInt
3345
3346 defm PADDB   : PDI_binop_all<0xFC, "paddb", add, v16i8, v32i8,
3347                              SchedWriteVecALU, 1, NoVLX_Or_NoBWI>;
3348 defm PADDW   : PDI_binop_all<0xFD, "paddw", add, v8i16, v16i16,
3349                              SchedWriteVecALU, 1, NoVLX_Or_NoBWI>;
3350 defm PADDD   : PDI_binop_all<0xFE, "paddd", add, v4i32, v8i32,
3351                              SchedWriteVecALU, 1, NoVLX>;
3352 defm PADDQ   : PDI_binop_all<0xD4, "paddq", add, v2i64, v4i64,
3353                              SchedWriteVecALU, 1, NoVLX>;
3354 defm PADDSB  : PDI_binop_all<0xEC, "paddsb", X86adds, v16i8, v32i8,
3355                              SchedWriteVecALU, 1, NoVLX_Or_NoBWI>;
3356 defm PADDSW  : PDI_binop_all<0xED, "paddsw", X86adds, v8i16, v16i16,
3357                              SchedWriteVecALU, 1, NoVLX_Or_NoBWI>;
3358 defm PADDUSB : PDI_binop_all<0xDC, "paddusb", X86addus, v16i8, v32i8,
3359                              SchedWriteVecALU, 1, NoVLX_Or_NoBWI>;
3360 defm PADDUSW : PDI_binop_all<0xDD, "paddusw", X86addus, v8i16, v16i16,
3361                              SchedWriteVecALU, 1, NoVLX_Or_NoBWI>;
3362 defm PMULLW  : PDI_binop_all<0xD5, "pmullw", mul, v8i16, v16i16,
3363                              SchedWriteVecIMul, 1, NoVLX_Or_NoBWI>;
3364 defm PMULHUW : PDI_binop_all<0xE4, "pmulhuw", mulhu, v8i16, v16i16,
3365                              SchedWriteVecIMul, 1, NoVLX_Or_NoBWI>;
3366 defm PMULHW  : PDI_binop_all<0xE5, "pmulhw", mulhs, v8i16, v16i16,
3367                              SchedWriteVecIMul, 1, NoVLX_Or_NoBWI>;
3368 defm PSUBB   : PDI_binop_all<0xF8, "psubb", sub, v16i8, v32i8,
3369                              SchedWriteVecALU, 0, NoVLX_Or_NoBWI>;
3370 defm PSUBW   : PDI_binop_all<0xF9, "psubw", sub, v8i16, v16i16,
3371                              SchedWriteVecALU, 0, NoVLX_Or_NoBWI>;
3372 defm PSUBD   : PDI_binop_all<0xFA, "psubd", sub, v4i32, v8i32,
3373                              SchedWriteVecALU, 0, NoVLX>;
3374 defm PSUBQ   : PDI_binop_all<0xFB, "psubq", sub, v2i64, v4i64,
3375                              SchedWriteVecALU, 0, NoVLX>;
3376 defm PSUBSB  : PDI_binop_all<0xE8, "psubsb", X86subs, v16i8, v32i8,
3377                              SchedWriteVecALU, 0, NoVLX_Or_NoBWI>;
3378 defm PSUBSW  : PDI_binop_all<0xE9, "psubsw", X86subs, v8i16, v16i16,
3379                              SchedWriteVecALU, 0, NoVLX_Or_NoBWI>;
3380 defm PSUBUSB : PDI_binop_all<0xD8, "psubusb", X86subus, v16i8, v32i8,
3381                              SchedWriteVecALU, 0, NoVLX_Or_NoBWI>;
3382 defm PSUBUSW : PDI_binop_all<0xD9, "psubusw", X86subus, v8i16, v16i16,
3383                              SchedWriteVecALU, 0, NoVLX_Or_NoBWI>;
3384 defm PMINUB  : PDI_binop_all<0xDA, "pminub", umin, v16i8, v32i8,
3385                              SchedWriteVecALU, 1, NoVLX_Or_NoBWI>;
3386 defm PMINSW  : PDI_binop_all<0xEA, "pminsw", smin, v8i16, v16i16,
3387                              SchedWriteVecALU, 1, NoVLX_Or_NoBWI>;
3388 defm PMAXUB  : PDI_binop_all<0xDE, "pmaxub", umax, v16i8, v32i8,
3389                              SchedWriteVecALU, 1, NoVLX_Or_NoBWI>;
3390 defm PMAXSW  : PDI_binop_all<0xEE, "pmaxsw", smax, v8i16, v16i16,
3391                              SchedWriteVecALU, 1, NoVLX_Or_NoBWI>;
3392 defm PAVGB   : PDI_binop_all<0xE0, "pavgb", X86avg, v16i8, v32i8,
3393                              SchedWriteVecALU, 1, NoVLX_Or_NoBWI>;
3394 defm PAVGW   : PDI_binop_all<0xE3, "pavgw", X86avg, v8i16, v16i16,
3395                              SchedWriteVecALU, 1, NoVLX_Or_NoBWI>;
3396 defm PMULUDQ : PDI_binop_all<0xF4, "pmuludq", X86pmuludq, v2i64, v4i64,
3397                              SchedWriteVecIMul, 1, NoVLX>;
3398
3399 let Predicates = [HasAVX, NoVLX_Or_NoBWI] in
3400 defm VPMADDWD : PDI_binop_rm2<0xF5, "vpmaddwd", X86vpmaddwd, v4i32, v8i16, VR128,
3401                               loadv2i64, i128mem, SchedWriteVecIMul.XMM, 0>,
3402                               VEX_4V, VEX_WIG;
3403
3404 let Predicates = [HasAVX2, NoVLX_Or_NoBWI] in
3405 defm VPMADDWDY : PDI_binop_rm2<0xF5, "vpmaddwd", X86vpmaddwd, v8i32, v16i16,
3406                                VR256, loadv4i64, i256mem, SchedWriteVecIMul.YMM,
3407                                0>, VEX_4V, VEX_L, VEX_WIG;
3408 let Constraints = "$src1 = $dst" in
3409 defm PMADDWD : PDI_binop_rm2<0xF5, "pmaddwd", X86vpmaddwd, v4i32, v8i16, VR128,
3410                              memopv2i64, i128mem, SchedWriteVecIMul.XMM>;
3411
3412 let Predicates = [HasAVX, NoVLX_Or_NoBWI] in
3413 defm VPSADBW : PDI_binop_rm2<0xF6, "vpsadbw", X86psadbw, v2i64, v16i8, VR128,
3414                              loadv2i64, i128mem, SchedWritePSADBW.XMM, 0>,
3415                              VEX_4V, VEX_WIG;
3416 let Predicates = [HasAVX2, NoVLX_Or_NoBWI] in
3417 defm VPSADBWY : PDI_binop_rm2<0xF6, "vpsadbw", X86psadbw, v4i64, v32i8, VR256,
3418                              loadv4i64, i256mem, SchedWritePSADBW.YMM, 0>,
3419                              VEX_4V, VEX_L, VEX_WIG;
3420 let Constraints = "$src1 = $dst" in
3421 defm PSADBW : PDI_binop_rm2<0xF6, "psadbw", X86psadbw, v2i64, v16i8, VR128,
3422                             memopv2i64, i128mem, SchedWritePSADBW.XMM>;
3423
3424 //===---------------------------------------------------------------------===//
3425 // SSE2 - Packed Integer Logical Instructions
3426 //===---------------------------------------------------------------------===//
3427
3428 multiclass PDI_binop_rmi<bits<8> opc, bits<8> opc2, Format ImmForm,
3429                          string OpcodeStr, SDNode OpNode,
3430                          SDNode OpNode2, RegisterClass RC,
3431                          X86FoldableSchedWrite sched,
3432                          X86FoldableSchedWrite schedImm,
3433                          ValueType DstVT, ValueType SrcVT,
3434                          PatFrag ld_frag, bit Is2Addr = 1> {
3435   // src2 is always 128-bit
3436   def rr : PDI<opc, MRMSrcReg, (outs RC:$dst),
3437        (ins RC:$src1, VR128:$src2),
3438        !if(Is2Addr,
3439            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
3440            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
3441        [(set RC:$dst, (DstVT (OpNode RC:$src1, (SrcVT VR128:$src2))))]>,
3442        Sched<[sched]>;
3443   def rm : PDI<opc, MRMSrcMem, (outs RC:$dst),
3444        (ins RC:$src1, i128mem:$src2),
3445        !if(Is2Addr,
3446            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
3447            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
3448        [(set RC:$dst, (DstVT (OpNode RC:$src1,
3449                        (SrcVT (bitconvert (ld_frag addr:$src2))))))]>,
3450        Sched<[sched.Folded, ReadAfterLd]>;
3451   def ri : PDIi8<opc2, ImmForm, (outs RC:$dst),
3452        (ins RC:$src1, u8imm:$src2),
3453        !if(Is2Addr,
3454            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
3455            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
3456        [(set RC:$dst, (DstVT (OpNode2 RC:$src1, (i8 imm:$src2))))]>,
3457        Sched<[schedImm]>;
3458 }
3459
3460 multiclass PDI_binop_rmi_all<bits<8> opc, bits<8> opc2, Format ImmForm,
3461                              string OpcodeStr, SDNode OpNode,
3462                              SDNode OpNode2, ValueType DstVT128,
3463                              ValueType DstVT256, ValueType SrcVT,
3464                              X86SchedWriteWidths sched,
3465                              X86SchedWriteWidths schedImm, Predicate prd> {
3466 let Predicates = [HasAVX, prd] in
3467   defm V#NAME : PDI_binop_rmi<opc, opc2, ImmForm, !strconcat("v", OpcodeStr),
3468                               OpNode, OpNode2, VR128, sched.XMM, schedImm.XMM,
3469                               DstVT128, SrcVT, loadv2i64, 0>, VEX_4V, VEX_WIG;
3470 let Predicates = [HasAVX2, prd] in
3471   defm V#NAME#Y : PDI_binop_rmi<opc, opc2, ImmForm, !strconcat("v", OpcodeStr),
3472                                 OpNode, OpNode2, VR256, sched.YMM, schedImm.YMM,
3473                                 DstVT256, SrcVT, loadv2i64, 0>, VEX_4V, VEX_L,
3474                                 VEX_WIG;
3475 let Constraints = "$src1 = $dst" in
3476   defm NAME : PDI_binop_rmi<opc, opc2, ImmForm, OpcodeStr, OpNode, OpNode2,
3477                             VR128, sched.XMM, schedImm.XMM, DstVT128, SrcVT,
3478                             memopv2i64>;
3479 }
3480
3481 multiclass PDI_binop_ri<bits<8> opc, Format ImmForm, string OpcodeStr,
3482                         SDNode OpNode, RegisterClass RC, ValueType VT,
3483                         X86FoldableSchedWrite sched, bit Is2Addr = 1> {
3484   def ri : PDIi8<opc, ImmForm, (outs RC:$dst), (ins RC:$src1, u8imm:$src2),
3485        !if(Is2Addr,
3486            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
3487            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
3488        [(set RC:$dst, (VT (OpNode RC:$src1, (i8 imm:$src2))))]>,
3489        Sched<[sched]>;
3490 }
3491
3492 multiclass PDI_binop_ri_all<bits<8> opc, Format ImmForm, string OpcodeStr,
3493                             SDNode OpNode, X86SchedWriteWidths sched> {
3494 let Predicates = [HasAVX, NoVLX_Or_NoBWI] in
3495   defm V#NAME : PDI_binop_ri<opc, ImmForm, !strconcat("v", OpcodeStr), OpNode,
3496                              VR128, v16i8, sched.XMM, 0>, VEX_4V, VEX_WIG;
3497 let Predicates = [HasAVX2, NoVLX_Or_NoBWI] in
3498   defm V#NAME#Y : PDI_binop_ri<opc, ImmForm, !strconcat("v", OpcodeStr), OpNode,
3499                                VR256, v32i8, sched.YMM, 0>,
3500                                VEX_4V, VEX_L, VEX_WIG;
3501 let Constraints = "$src1 = $dst" in
3502   defm NAME : PDI_binop_ri<opc, ImmForm, OpcodeStr, OpNode, VR128, v16i8,
3503                            sched.XMM>;
3504 }
3505
3506 let ExeDomain = SSEPackedInt in {
3507   defm PSLLW : PDI_binop_rmi_all<0xF1, 0x71, MRM6r, "psllw", X86vshl, X86vshli,
3508                                  v8i16, v16i16, v8i16, SchedWriteVecShift,
3509                                  SchedWriteVecShiftImm, NoVLX_Or_NoBWI>;
3510   defm PSLLD : PDI_binop_rmi_all<0xF2, 0x72, MRM6r, "pslld", X86vshl, X86vshli,
3511                                  v4i32, v8i32, v4i32, SchedWriteVecShift,
3512                                  SchedWriteVecShiftImm, NoVLX>;
3513   defm PSLLQ : PDI_binop_rmi_all<0xF3, 0x73, MRM6r, "psllq", X86vshl, X86vshli,
3514                                  v2i64, v4i64, v2i64, SchedWriteVecShift,
3515                                  SchedWriteVecShiftImm, NoVLX>;
3516
3517   defm PSRLW : PDI_binop_rmi_all<0xD1, 0x71, MRM2r, "psrlw", X86vsrl, X86vsrli,
3518                                  v8i16, v16i16, v8i16, SchedWriteVecShift,
3519                                  SchedWriteVecShiftImm, NoVLX_Or_NoBWI>;
3520   defm PSRLD : PDI_binop_rmi_all<0xD2, 0x72, MRM2r, "psrld", X86vsrl, X86vsrli,
3521                                  v4i32, v8i32, v4i32, SchedWriteVecShift,
3522                                  SchedWriteVecShiftImm, NoVLX>;
3523   defm PSRLQ : PDI_binop_rmi_all<0xD3, 0x73, MRM2r, "psrlq", X86vsrl, X86vsrli,
3524                                  v2i64, v4i64, v2i64, SchedWriteVecShift,
3525                                  SchedWriteVecShiftImm, NoVLX>;
3526
3527   defm PSRAW : PDI_binop_rmi_all<0xE1, 0x71, MRM4r, "psraw", X86vsra, X86vsrai,
3528                                  v8i16, v16i16, v8i16, SchedWriteVecShift,
3529                                  SchedWriteVecShiftImm, NoVLX_Or_NoBWI>;
3530   defm PSRAD : PDI_binop_rmi_all<0xE2, 0x72, MRM4r, "psrad", X86vsra, X86vsrai,
3531                                  v4i32, v8i32, v4i32, SchedWriteVecShift,
3532                                  SchedWriteVecShiftImm, NoVLX>;
3533
3534   defm PSLLDQ : PDI_binop_ri_all<0x73, MRM7r, "pslldq", X86vshldq,
3535                                  SchedWriteShuffle>;
3536   defm PSRLDQ : PDI_binop_ri_all<0x73, MRM3r, "psrldq", X86vshrdq,
3537                                  SchedWriteShuffle>;
3538 } // ExeDomain = SSEPackedInt
3539
3540 //===---------------------------------------------------------------------===//
3541 // SSE2 - Packed Integer Comparison Instructions
3542 //===---------------------------------------------------------------------===//
3543
3544 defm PCMPEQB : PDI_binop_all<0x74, "pcmpeqb", X86pcmpeq, v16i8, v32i8,
3545                              SchedWriteVecALU, 1, TruePredicate>;
3546 defm PCMPEQW : PDI_binop_all<0x75, "pcmpeqw", X86pcmpeq, v8i16, v16i16,
3547                              SchedWriteVecALU, 1, TruePredicate>;
3548 defm PCMPEQD : PDI_binop_all<0x76, "pcmpeqd", X86pcmpeq, v4i32, v8i32,
3549                              SchedWriteVecALU, 1, TruePredicate>;
3550 defm PCMPGTB : PDI_binop_all<0x64, "pcmpgtb", X86pcmpgt, v16i8, v32i8,
3551                              SchedWriteVecALU, 0, TruePredicate>;
3552 defm PCMPGTW : PDI_binop_all<0x65, "pcmpgtw", X86pcmpgt, v8i16, v16i16,
3553                              SchedWriteVecALU, 0, TruePredicate>;
3554 defm PCMPGTD : PDI_binop_all<0x66, "pcmpgtd", X86pcmpgt, v4i32, v8i32,
3555                              SchedWriteVecALU, 0, TruePredicate>;
3556
3557 //===---------------------------------------------------------------------===//
3558 // SSE2 - Packed Integer Shuffle Instructions
3559 //===---------------------------------------------------------------------===//
3560
3561 let ExeDomain = SSEPackedInt in {
3562 multiclass sse2_pshuffle<string OpcodeStr, ValueType vt128, ValueType vt256,
3563                          SDNode OpNode, X86SchedWriteWidths sched,
3564                          Predicate prd> {
3565 let Predicates = [HasAVX, prd] in {
3566   def V#NAME#ri : Ii8<0x70, MRMSrcReg, (outs VR128:$dst),
3567                       (ins VR128:$src1, u8imm:$src2),
3568                       !strconcat("v", OpcodeStr,
3569                                  "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
3570                       [(set VR128:$dst,
3571                         (vt128 (OpNode VR128:$src1, (i8 imm:$src2))))]>,
3572                       VEX, Sched<[sched.XMM]>, VEX_WIG;
3573   def V#NAME#mi : Ii8<0x70, MRMSrcMem, (outs VR128:$dst),
3574                       (ins i128mem:$src1, u8imm:$src2),
3575                       !strconcat("v", OpcodeStr,
3576                                  "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
3577                      [(set VR128:$dst,
3578                        (vt128 (OpNode (bitconvert (loadv2i64 addr:$src1)),
3579                         (i8 imm:$src2))))]>, VEX,
3580                   Sched<[sched.XMM.Folded]>, VEX_WIG;
3581 }
3582
3583 let Predicates = [HasAVX2, prd] in {
3584   def V#NAME#Yri : Ii8<0x70, MRMSrcReg, (outs VR256:$dst),
3585                        (ins VR256:$src1, u8imm:$src2),
3586                        !strconcat("v", OpcodeStr,
3587                                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
3588                        [(set VR256:$dst,
3589                          (vt256 (OpNode VR256:$src1, (i8 imm:$src2))))]>,
3590                        VEX, VEX_L, Sched<[sched.YMM]>, VEX_WIG;
3591   def V#NAME#Ymi : Ii8<0x70, MRMSrcMem, (outs VR256:$dst),
3592                        (ins i256mem:$src1, u8imm:$src2),
3593                        !strconcat("v", OpcodeStr,
3594                                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
3595                       [(set VR256:$dst,
3596                         (vt256 (OpNode (bitconvert (loadv4i64 addr:$src1)),
3597                          (i8 imm:$src2))))]>, VEX, VEX_L,
3598                    Sched<[sched.YMM.Folded]>, VEX_WIG;
3599 }
3600
3601 let Predicates = [UseSSE2] in {
3602   def ri : Ii8<0x70, MRMSrcReg,
3603                (outs VR128:$dst), (ins VR128:$src1, u8imm:$src2),
3604                !strconcat(OpcodeStr,
3605                           "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
3606                [(set VR128:$dst,
3607                  (vt128 (OpNode VR128:$src1, (i8 imm:$src2))))]>,
3608                Sched<[sched.XMM]>;
3609   def mi : Ii8<0x70, MRMSrcMem,
3610                (outs VR128:$dst), (ins i128mem:$src1, u8imm:$src2),
3611                !strconcat(OpcodeStr,
3612                           "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
3613                [(set VR128:$dst,
3614                  (vt128 (OpNode (bitconvert (memopv2i64 addr:$src1)),
3615                         (i8 imm:$src2))))]>,
3616                Sched<[sched.XMM.Folded]>;
3617 }
3618 }
3619 } // ExeDomain = SSEPackedInt
3620
3621 defm PSHUFD  : sse2_pshuffle<"pshufd", v4i32, v8i32, X86PShufd,
3622                              SchedWriteShuffle, NoVLX>, PD;
3623 defm PSHUFHW : sse2_pshuffle<"pshufhw", v8i16, v16i16, X86PShufhw,
3624                              SchedWriteShuffle, NoVLX_Or_NoBWI>, XS;
3625 defm PSHUFLW : sse2_pshuffle<"pshuflw", v8i16, v16i16, X86PShuflw,
3626                              SchedWriteShuffle, NoVLX_Or_NoBWI>, XD;
3627
3628 //===---------------------------------------------------------------------===//
3629 // Packed Integer Pack Instructions (SSE & AVX)
3630 //===---------------------------------------------------------------------===//
3631
3632 let ExeDomain = SSEPackedInt in {
3633 multiclass sse2_pack<bits<8> opc, string OpcodeStr, ValueType OutVT,
3634                      ValueType ArgVT, SDNode OpNode, RegisterClass RC,
3635                      X86MemOperand x86memop, X86FoldableSchedWrite sched,
3636                      PatFrag ld_frag, bit Is2Addr = 1> {
3637   def rr : PDI<opc, MRMSrcReg,
3638                (outs RC:$dst), (ins RC:$src1, RC:$src2),
3639                !if(Is2Addr,
3640                    !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
3641                    !strconcat(OpcodeStr,
3642                               "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
3643                [(set RC:$dst,
3644                      (OutVT (OpNode (ArgVT RC:$src1), RC:$src2)))]>,
3645                Sched<[sched]>;
3646   def rm : PDI<opc, MRMSrcMem,
3647                (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
3648                !if(Is2Addr,
3649                    !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
3650                    !strconcat(OpcodeStr,
3651                               "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
3652                [(set RC:$dst,
3653                      (OutVT (OpNode (ArgVT RC:$src1),
3654                                     (bitconvert (ld_frag addr:$src2)))))]>,
3655                Sched<[sched.Folded, ReadAfterLd]>;
3656 }
3657
3658 multiclass sse4_pack<bits<8> opc, string OpcodeStr, ValueType OutVT,
3659                      ValueType ArgVT, SDNode OpNode, RegisterClass RC,
3660                      X86MemOperand x86memop, X86FoldableSchedWrite sched,
3661                      PatFrag ld_frag, bit Is2Addr = 1> {
3662   def rr : SS48I<opc, MRMSrcReg,
3663                  (outs RC:$dst), (ins RC:$src1, RC:$src2),
3664                  !if(Is2Addr,
3665                      !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
3666                      !strconcat(OpcodeStr,
3667                                 "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
3668                  [(set RC:$dst,
3669                        (OutVT (OpNode (ArgVT RC:$src1), RC:$src2)))]>,
3670                  Sched<[sched]>;
3671   def rm : SS48I<opc, MRMSrcMem,
3672                  (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
3673                  !if(Is2Addr,
3674                      !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
3675                      !strconcat(OpcodeStr,
3676                                 "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
3677                  [(set RC:$dst,
3678                        (OutVT (OpNode (ArgVT RC:$src1),
3679                                       (bitconvert (ld_frag addr:$src2)))))]>,
3680                  Sched<[sched.Folded, ReadAfterLd]>;
3681 }
3682
3683 let Predicates = [HasAVX, NoVLX_Or_NoBWI] in {
3684   defm VPACKSSWB : sse2_pack<0x63, "vpacksswb", v16i8, v8i16, X86Packss, VR128,
3685                              i128mem, SchedWriteShuffle.XMM, loadv2i64, 0>,
3686                              VEX_4V, VEX_WIG;
3687   defm VPACKSSDW : sse2_pack<0x6B, "vpackssdw", v8i16, v4i32, X86Packss, VR128,
3688                              i128mem, SchedWriteShuffle.XMM, loadv2i64, 0>,
3689                              VEX_4V, VEX_WIG;
3690
3691   defm VPACKUSWB : sse2_pack<0x67, "vpackuswb", v16i8, v8i16, X86Packus, VR128,
3692                              i128mem, SchedWriteShuffle.XMM, loadv2i64, 0>,
3693                              VEX_4V, VEX_WIG;
3694   defm VPACKUSDW : sse4_pack<0x2B, "vpackusdw", v8i16, v4i32, X86Packus, VR128,
3695                              i128mem, SchedWriteShuffle.XMM, loadv2i64, 0>,
3696                              VEX_4V;
3697 }
3698
3699 let Predicates = [HasAVX2, NoVLX_Or_NoBWI] in {
3700   defm VPACKSSWBY : sse2_pack<0x63, "vpacksswb", v32i8, v16i16, X86Packss, VR256,
3701                               i256mem, SchedWriteShuffle.YMM, loadv4i64, 0>,
3702                               VEX_4V, VEX_L, VEX_WIG;
3703   defm VPACKSSDWY : sse2_pack<0x6B, "vpackssdw", v16i16, v8i32, X86Packss, VR256,
3704                               i256mem, SchedWriteShuffle.YMM, loadv4i64, 0>,
3705                               VEX_4V, VEX_L, VEX_WIG;
3706
3707   defm VPACKUSWBY : sse2_pack<0x67, "vpackuswb", v32i8, v16i16, X86Packus, VR256,
3708                               i256mem, SchedWriteShuffle.YMM, loadv4i64, 0>,
3709                               VEX_4V, VEX_L, VEX_WIG;
3710   defm VPACKUSDWY : sse4_pack<0x2B, "vpackusdw", v16i16, v8i32, X86Packus, VR256,
3711                               i256mem, SchedWriteShuffle.YMM, loadv4i64, 0>,
3712                               VEX_4V, VEX_L;
3713 }
3714
3715 let Constraints = "$src1 = $dst" in {
3716   defm PACKSSWB : sse2_pack<0x63, "packsswb", v16i8, v8i16, X86Packss, VR128,
3717                             i128mem, SchedWriteShuffle.XMM, memopv2i64>;
3718   defm PACKSSDW : sse2_pack<0x6B, "packssdw", v8i16, v4i32, X86Packss, VR128,
3719                             i128mem, SchedWriteShuffle.XMM, memopv2i64>;
3720
3721   defm PACKUSWB : sse2_pack<0x67, "packuswb", v16i8, v8i16, X86Packus, VR128,
3722                             i128mem, SchedWriteShuffle.XMM, memopv2i64>;
3723
3724   defm PACKUSDW : sse4_pack<0x2B, "packusdw", v8i16, v4i32, X86Packus, VR128,
3725                             i128mem, SchedWriteShuffle.XMM, memopv2i64>;
3726 }
3727 } // ExeDomain = SSEPackedInt
3728
3729 //===---------------------------------------------------------------------===//
3730 // SSE2 - Packed Integer Unpack Instructions
3731 //===---------------------------------------------------------------------===//
3732
3733 let ExeDomain = SSEPackedInt in {
3734 multiclass sse2_unpack<bits<8> opc, string OpcodeStr, ValueType vt,
3735                        SDNode OpNode, RegisterClass RC, X86MemOperand x86memop,
3736                        X86FoldableSchedWrite sched, PatFrag ld_frag,
3737                        bit Is2Addr = 1> {
3738   def rr : PDI<opc, MRMSrcReg,
3739       (outs RC:$dst), (ins RC:$src1, RC:$src2),
3740       !if(Is2Addr,
3741           !strconcat(OpcodeStr,"\t{$src2, $dst|$dst, $src2}"),
3742           !strconcat(OpcodeStr,"\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
3743       [(set RC:$dst, (vt (OpNode RC:$src1, RC:$src2)))]>,
3744       Sched<[sched]>;
3745   def rm : PDI<opc, MRMSrcMem,
3746       (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
3747       !if(Is2Addr,
3748           !strconcat(OpcodeStr,"\t{$src2, $dst|$dst, $src2}"),
3749           !strconcat(OpcodeStr,"\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
3750       [(set RC:$dst, (vt (OpNode RC:$src1,
3751                                   (bitconvert (ld_frag addr:$src2)))))]>,
3752       Sched<[sched.Folded, ReadAfterLd]>;
3753 }
3754
3755 let Predicates = [HasAVX, NoVLX_Or_NoBWI] in {
3756   defm VPUNPCKLBW  : sse2_unpack<0x60, "vpunpcklbw", v16i8, X86Unpckl, VR128,
3757                                  i128mem, SchedWriteShuffle.XMM, loadv2i64, 0>,
3758                                  VEX_4V, VEX_WIG;
3759   defm VPUNPCKLWD  : sse2_unpack<0x61, "vpunpcklwd", v8i16, X86Unpckl, VR128,
3760                                  i128mem, SchedWriteShuffle.XMM, loadv2i64, 0>,
3761                                  VEX_4V, VEX_WIG;
3762   defm VPUNPCKHBW  : sse2_unpack<0x68, "vpunpckhbw", v16i8, X86Unpckh, VR128,
3763                                  i128mem, SchedWriteShuffle.XMM, loadv2i64, 0>,
3764                                  VEX_4V, VEX_WIG;
3765   defm VPUNPCKHWD  : sse2_unpack<0x69, "vpunpckhwd", v8i16, X86Unpckh, VR128,
3766                                  i128mem, SchedWriteShuffle.XMM, loadv2i64, 0>,
3767                                  VEX_4V, VEX_WIG;
3768 }
3769
3770 let Predicates = [HasAVX, NoVLX] in {
3771   defm VPUNPCKLDQ  : sse2_unpack<0x62, "vpunpckldq", v4i32, X86Unpckl, VR128,
3772                                  i128mem, SchedWriteShuffle.XMM, loadv2i64, 0>,
3773                                  VEX_4V, VEX_WIG;
3774   defm VPUNPCKLQDQ : sse2_unpack<0x6C, "vpunpcklqdq", v2i64, X86Unpckl, VR128,
3775                                  i128mem, SchedWriteShuffle.XMM, loadv2i64, 0>,
3776                                  VEX_4V, VEX_WIG;
3777   defm VPUNPCKHDQ  : sse2_unpack<0x6A, "vpunpckhdq", v4i32, X86Unpckh, VR128,
3778                                  i128mem, SchedWriteShuffle.XMM, loadv2i64, 0>,
3779                                  VEX_4V, VEX_WIG;
3780   defm VPUNPCKHQDQ : sse2_unpack<0x6D, "vpunpckhqdq", v2i64, X86Unpckh, VR128,
3781                                  i128mem, SchedWriteShuffle.XMM, loadv2i64, 0>,
3782                                  VEX_4V, VEX_WIG;
3783 }
3784
3785 let Predicates = [HasAVX2, NoVLX_Or_NoBWI] in {
3786   defm VPUNPCKLBWY  : sse2_unpack<0x60, "vpunpcklbw", v32i8, X86Unpckl, VR256,
3787                                   i256mem, SchedWriteShuffle.YMM, loadv4i64, 0>,
3788                                   VEX_4V, VEX_L, VEX_WIG;
3789   defm VPUNPCKLWDY  : sse2_unpack<0x61, "vpunpcklwd", v16i16, X86Unpckl, VR256,
3790                                   i256mem, SchedWriteShuffle.YMM, loadv4i64, 0>,
3791                                   VEX_4V, VEX_L, VEX_WIG;
3792   defm VPUNPCKHBWY  : sse2_unpack<0x68, "vpunpckhbw", v32i8, X86Unpckh, VR256,
3793                                   i256mem, SchedWriteShuffle.YMM, loadv4i64, 0>,
3794                                   VEX_4V, VEX_L, VEX_WIG;
3795   defm VPUNPCKHWDY  : sse2_unpack<0x69, "vpunpckhwd", v16i16, X86Unpckh, VR256,
3796                                   i256mem, SchedWriteShuffle.YMM, loadv4i64, 0>,
3797                                   VEX_4V, VEX_L, VEX_WIG;
3798 }
3799
3800 let Predicates = [HasAVX2, NoVLX] in {
3801   defm VPUNPCKLDQY  : sse2_unpack<0x62, "vpunpckldq", v8i32, X86Unpckl, VR256,
3802                                   i256mem, SchedWriteShuffle.YMM, loadv4i64, 0>,
3803                                   VEX_4V, VEX_L, VEX_WIG;
3804   defm VPUNPCKLQDQY : sse2_unpack<0x6C, "vpunpcklqdq", v4i64, X86Unpckl, VR256,
3805                                   i256mem, SchedWriteShuffle.YMM, loadv4i64, 0>,
3806                                   VEX_4V, VEX_L, VEX_WIG;
3807   defm VPUNPCKHDQY  : sse2_unpack<0x6A, "vpunpckhdq", v8i32, X86Unpckh, VR256,
3808                                   i256mem, SchedWriteShuffle.YMM, loadv4i64, 0>,
3809                                   VEX_4V, VEX_L, VEX_WIG;
3810   defm VPUNPCKHQDQY : sse2_unpack<0x6D, "vpunpckhqdq", v4i64, X86Unpckh, VR256,
3811                                   i256mem, SchedWriteShuffle.YMM, loadv4i64, 0>,
3812                                   VEX_4V, VEX_L, VEX_WIG;
3813 }
3814
3815 let Constraints = "$src1 = $dst" in {
3816   defm PUNPCKLBW  : sse2_unpack<0x60, "punpcklbw", v16i8, X86Unpckl, VR128,
3817                                 i128mem, SchedWriteShuffle.XMM, memopv2i64>;
3818   defm PUNPCKLWD  : sse2_unpack<0x61, "punpcklwd", v8i16, X86Unpckl, VR128,
3819                                 i128mem, SchedWriteShuffle.XMM, memopv2i64>;
3820   defm PUNPCKLDQ  : sse2_unpack<0x62, "punpckldq", v4i32, X86Unpckl, VR128,
3821                                 i128mem, SchedWriteShuffle.XMM, memopv2i64>;
3822   defm PUNPCKLQDQ : sse2_unpack<0x6C, "punpcklqdq", v2i64, X86Unpckl, VR128,
3823                                 i128mem, SchedWriteShuffle.XMM, memopv2i64>;
3824
3825   defm PUNPCKHBW  : sse2_unpack<0x68, "punpckhbw", v16i8, X86Unpckh, VR128,
3826                                 i128mem, SchedWriteShuffle.XMM, memopv2i64>;
3827   defm PUNPCKHWD  : sse2_unpack<0x69, "punpckhwd", v8i16, X86Unpckh, VR128,
3828                                 i128mem, SchedWriteShuffle.XMM, memopv2i64>;
3829   defm PUNPCKHDQ  : sse2_unpack<0x6A, "punpckhdq", v4i32, X86Unpckh, VR128,
3830                                 i128mem, SchedWriteShuffle.XMM, memopv2i64>;
3831   defm PUNPCKHQDQ : sse2_unpack<0x6D, "punpckhqdq", v2i64, X86Unpckh, VR128,
3832                                 i128mem, SchedWriteShuffle.XMM, memopv2i64>;
3833 }
3834 } // ExeDomain = SSEPackedInt
3835
3836 //===---------------------------------------------------------------------===//
3837 // SSE2 - Packed Integer Extract and Insert
3838 //===---------------------------------------------------------------------===//
3839
3840 let ExeDomain = SSEPackedInt in {
3841 multiclass sse2_pinsrw<bit Is2Addr = 1> {
3842   def rr : Ii8<0xC4, MRMSrcReg,
3843        (outs VR128:$dst), (ins VR128:$src1,
3844         GR32orGR64:$src2, u8imm:$src3),
3845        !if(Is2Addr,
3846            "pinsrw\t{$src3, $src2, $dst|$dst, $src2, $src3}",
3847            "vpinsrw\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
3848        [(set VR128:$dst,
3849          (X86pinsrw VR128:$src1, GR32orGR64:$src2, imm:$src3))]>,
3850        Sched<[WriteVecInsert]>;
3851   def rm : Ii8<0xC4, MRMSrcMem,
3852                       (outs VR128:$dst), (ins VR128:$src1,
3853                        i16mem:$src2, u8imm:$src3),
3854        !if(Is2Addr,
3855            "pinsrw\t{$src3, $src2, $dst|$dst, $src2, $src3}",
3856            "vpinsrw\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
3857        [(set VR128:$dst,
3858          (X86pinsrw VR128:$src1, (extloadi16 addr:$src2),
3859                     imm:$src3))]>,
3860        Sched<[WriteVecInsertLd, ReadAfterLd]>;
3861 }
3862
3863 // Extract
3864 let Predicates = [HasAVX, NoBWI] in
3865 def VPEXTRWrr : Ii8<0xC5, MRMSrcReg,
3866                     (outs GR32orGR64:$dst), (ins VR128:$src1, u8imm:$src2),
3867                     "vpextrw\t{$src2, $src1, $dst|$dst, $src1, $src2}",
3868                     [(set GR32orGR64:$dst, (X86pextrw (v8i16 VR128:$src1),
3869                                             imm:$src2))]>,
3870                 PD, VEX, Sched<[WriteVecExtract]>;
3871 def PEXTRWrr : PDIi8<0xC5, MRMSrcReg,
3872                     (outs GR32orGR64:$dst), (ins VR128:$src1, u8imm:$src2),
3873                     "pextrw\t{$src2, $src1, $dst|$dst, $src1, $src2}",
3874                     [(set GR32orGR64:$dst, (X86pextrw (v8i16 VR128:$src1),
3875                                             imm:$src2))]>,
3876                Sched<[WriteVecExtract]>;
3877
3878 // Insert
3879 let Predicates = [HasAVX, NoBWI] in
3880 defm VPINSRW : sse2_pinsrw<0>, PD, VEX_4V;
3881
3882 let Predicates = [UseSSE2], Constraints = "$src1 = $dst" in
3883 defm PINSRW : sse2_pinsrw, PD;
3884
3885 } // ExeDomain = SSEPackedInt
3886
3887 //===---------------------------------------------------------------------===//
3888 // SSE2 - Packed Mask Creation
3889 //===---------------------------------------------------------------------===//
3890
3891 let ExeDomain = SSEPackedInt in {
3892
3893 def VPMOVMSKBrr  : VPDI<0xD7, MRMSrcReg, (outs GR32orGR64:$dst),
3894            (ins VR128:$src),
3895            "pmovmskb\t{$src, $dst|$dst, $src}",
3896            [(set GR32orGR64:$dst, (X86movmsk (v16i8 VR128:$src)))]>,
3897            Sched<[WriteVecMOVMSK]>, VEX, VEX_WIG;
3898
3899 let Predicates = [HasAVX2] in {
3900 def VPMOVMSKBYrr  : VPDI<0xD7, MRMSrcReg, (outs GR32orGR64:$dst),
3901            (ins VR256:$src),
3902            "pmovmskb\t{$src, $dst|$dst, $src}",
3903            [(set GR32orGR64:$dst, (X86movmsk (v32i8 VR256:$src)))]>,
3904            Sched<[WriteVecMOVMSKY]>, VEX, VEX_L, VEX_WIG;
3905 }
3906
3907 def PMOVMSKBrr : PDI<0xD7, MRMSrcReg, (outs GR32orGR64:$dst), (ins VR128:$src),
3908            "pmovmskb\t{$src, $dst|$dst, $src}",
3909            [(set GR32orGR64:$dst, (X86movmsk (v16i8 VR128:$src)))]>,
3910            Sched<[WriteVecMOVMSK]>;
3911
3912 } // ExeDomain = SSEPackedInt
3913
3914 //===---------------------------------------------------------------------===//
3915 // SSE2 - Conditional Store
3916 //===---------------------------------------------------------------------===//
3917
3918 let ExeDomain = SSEPackedInt, SchedRW = [SchedWriteVecMoveLS.XMM.MR] in {
3919 let Uses = [EDI], Predicates = [HasAVX,Not64BitMode] in
3920 def VMASKMOVDQU : VPDI<0xF7, MRMSrcReg, (outs),
3921            (ins VR128:$src, VR128:$mask),
3922            "maskmovdqu\t{$mask, $src|$src, $mask}",
3923            [(int_x86_sse2_maskmov_dqu VR128:$src, VR128:$mask, EDI)]>,
3924            VEX, VEX_WIG;
3925 let Uses = [RDI], Predicates = [HasAVX,In64BitMode] in
3926 def VMASKMOVDQU64 : VPDI<0xF7, MRMSrcReg, (outs),
3927            (ins VR128:$src, VR128:$mask),
3928            "maskmovdqu\t{$mask, $src|$src, $mask}",
3929            [(int_x86_sse2_maskmov_dqu VR128:$src, VR128:$mask, RDI)]>,
3930            VEX, VEX_WIG;
3931
3932 let Uses = [EDI], Predicates = [UseSSE2,Not64BitMode] in
3933 def MASKMOVDQU : PDI<0xF7, MRMSrcReg, (outs), (ins VR128:$src, VR128:$mask),
3934            "maskmovdqu\t{$mask, $src|$src, $mask}",
3935            [(int_x86_sse2_maskmov_dqu VR128:$src, VR128:$mask, EDI)]>;
3936 let Uses = [RDI], Predicates = [UseSSE2,In64BitMode] in
3937 def MASKMOVDQU64 : PDI<0xF7, MRMSrcReg, (outs), (ins VR128:$src, VR128:$mask),
3938            "maskmovdqu\t{$mask, $src|$src, $mask}",
3939            [(int_x86_sse2_maskmov_dqu VR128:$src, VR128:$mask, RDI)]>;
3940
3941 } // ExeDomain = SSEPackedInt
3942
3943 //===---------------------------------------------------------------------===//
3944 // SSE2 - Move Doubleword/Quadword
3945 //===---------------------------------------------------------------------===//
3946
3947 //===---------------------------------------------------------------------===//
3948 // Move Int Doubleword to Packed Double Int
3949 //
3950 let ExeDomain = SSEPackedInt in {
3951 def VMOVDI2PDIrr : VS2I<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR32:$src),
3952                         "movd\t{$src, $dst|$dst, $src}",
3953                         [(set VR128:$dst,
3954                           (v4i32 (scalar_to_vector GR32:$src)))]>,
3955                           VEX, Sched<[WriteVecMoveFromGpr]>;
3956 def VMOVDI2PDIrm : VS2I<0x6E, MRMSrcMem, (outs VR128:$dst), (ins i32mem:$src),
3957                         "movd\t{$src, $dst|$dst, $src}",
3958                         [(set VR128:$dst,
3959                           (v4i32 (scalar_to_vector (loadi32 addr:$src))))]>,
3960                         VEX, Sched<[WriteVecLoad]>;
3961 def VMOV64toPQIrr : VRS2I<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR64:$src),
3962                           "movq\t{$src, $dst|$dst, $src}",
3963                           [(set VR128:$dst,
3964                             (v2i64 (scalar_to_vector GR64:$src)))]>,
3965                           VEX, Sched<[WriteVecMoveFromGpr]>;
3966 let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0, mayLoad = 1 in
3967 def VMOV64toPQIrm : VRS2I<0x6E, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
3968                           "movq\t{$src, $dst|$dst, $src}", []>,
3969                           VEX, Sched<[WriteVecLoad]>;
3970 let isCodeGenOnly = 1 in
3971 def VMOV64toSDrr : VRS2I<0x6E, MRMSrcReg, (outs FR64:$dst), (ins GR64:$src),
3972                          "movq\t{$src, $dst|$dst, $src}",
3973                          [(set FR64:$dst, (bitconvert GR64:$src))]>,
3974                          VEX, Sched<[WriteVecMoveFromGpr]>;
3975
3976 def MOVDI2PDIrr : S2I<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR32:$src),
3977                       "movd\t{$src, $dst|$dst, $src}",
3978                       [(set VR128:$dst,
3979                         (v4i32 (scalar_to_vector GR32:$src)))]>,
3980                       Sched<[WriteVecMoveFromGpr]>;
3981 def MOVDI2PDIrm : S2I<0x6E, MRMSrcMem, (outs VR128:$dst), (ins i32mem:$src),
3982                       "movd\t{$src, $dst|$dst, $src}",
3983                       [(set VR128:$dst,
3984                         (v4i32 (scalar_to_vector (loadi32 addr:$src))))]>,
3985                       Sched<[WriteVecLoad]>;
3986 def MOV64toPQIrr : RS2I<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR64:$src),
3987                         "movq\t{$src, $dst|$dst, $src}",
3988                         [(set VR128:$dst,
3989                           (v2i64 (scalar_to_vector GR64:$src)))]>,
3990                         Sched<[WriteVecMoveFromGpr]>;
3991 let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0, mayLoad = 1 in
3992 def MOV64toPQIrm : RS2I<0x6E, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
3993                         "movq\t{$src, $dst|$dst, $src}", []>,
3994                         Sched<[WriteVecLoad]>;
3995 let isCodeGenOnly = 1 in
3996 def MOV64toSDrr : RS2I<0x6E, MRMSrcReg, (outs FR64:$dst), (ins GR64:$src),
3997                        "movq\t{$src, $dst|$dst, $src}",
3998                        [(set FR64:$dst, (bitconvert GR64:$src))]>,
3999                        Sched<[WriteVecMoveFromGpr]>;
4000 } // ExeDomain = SSEPackedInt
4001
4002 //===---------------------------------------------------------------------===//
4003 // Move Int Doubleword to Single Scalar
4004 //
4005 let ExeDomain = SSEPackedInt, isCodeGenOnly = 1 in {
4006   def VMOVDI2SSrr  : VS2I<0x6E, MRMSrcReg, (outs FR32:$dst), (ins GR32:$src),
4007                         "movd\t{$src, $dst|$dst, $src}",
4008                         [(set FR32:$dst, (bitconvert GR32:$src))]>,
4009                         VEX, Sched<[WriteVecMoveFromGpr]>;
4010
4011   def VMOVDI2SSrm  : VS2I<0x6E, MRMSrcMem, (outs FR32:$dst), (ins i32mem:$src),
4012                         "movd\t{$src, $dst|$dst, $src}",
4013                         [(set FR32:$dst, (bitconvert (loadi32 addr:$src)))]>,
4014                         VEX, Sched<[WriteVecLoad]>;
4015   def MOVDI2SSrr  : S2I<0x6E, MRMSrcReg, (outs FR32:$dst), (ins GR32:$src),
4016                         "movd\t{$src, $dst|$dst, $src}",
4017                         [(set FR32:$dst, (bitconvert GR32:$src))]>,
4018                         Sched<[WriteVecMoveFromGpr]>;
4019
4020   def MOVDI2SSrm  : S2I<0x6E, MRMSrcMem, (outs FR32:$dst), (ins i32mem:$src),
4021                         "movd\t{$src, $dst|$dst, $src}",
4022                         [(set FR32:$dst, (bitconvert (loadi32 addr:$src)))]>,
4023                         Sched<[WriteVecLoad]>;
4024 } // ExeDomain = SSEPackedInt, isCodeGenOnly = 1
4025
4026 //===---------------------------------------------------------------------===//
4027 // Move Packed Doubleword Int to Packed Double Int
4028 //
4029 let ExeDomain = SSEPackedInt in {
4030 def VMOVPDI2DIrr  : VS2I<0x7E, MRMDestReg, (outs GR32:$dst), (ins VR128:$src),
4031                          "movd\t{$src, $dst|$dst, $src}",
4032                          [(set GR32:$dst, (extractelt (v4i32 VR128:$src),
4033                                           (iPTR 0)))]>, VEX,
4034                          Sched<[WriteVecMoveToGpr]>;
4035 def VMOVPDI2DImr  : VS2I<0x7E, MRMDestMem, (outs),
4036                          (ins i32mem:$dst, VR128:$src),
4037                          "movd\t{$src, $dst|$dst, $src}",
4038                          [(store (i32 (extractelt (v4i32 VR128:$src),
4039                                        (iPTR 0))), addr:$dst)]>,
4040                          VEX, Sched<[WriteVecStore]>;
4041 def MOVPDI2DIrr  : S2I<0x7E, MRMDestReg, (outs GR32:$dst), (ins VR128:$src),
4042                        "movd\t{$src, $dst|$dst, $src}",
4043                        [(set GR32:$dst, (extractelt (v4i32 VR128:$src),
4044                                         (iPTR 0)))]>,
4045                    Sched<[WriteVecMoveToGpr]>;
4046 def MOVPDI2DImr  : S2I<0x7E, MRMDestMem, (outs), (ins i32mem:$dst, VR128:$src),
4047                        "movd\t{$src, $dst|$dst, $src}",
4048                        [(store (i32 (extractelt (v4i32 VR128:$src),
4049                                      (iPTR 0))), addr:$dst)]>,
4050                        Sched<[WriteVecStore]>;
4051 } // ExeDomain = SSEPackedInt
4052
4053 //===---------------------------------------------------------------------===//
4054 // Move Packed Doubleword Int first element to Doubleword Int
4055 //
4056 let ExeDomain = SSEPackedInt in {
4057 let SchedRW = [WriteVecMoveToGpr] in {
4058 def VMOVPQIto64rr : VRS2I<0x7E, MRMDestReg, (outs GR64:$dst), (ins VR128:$src),
4059                           "movq\t{$src, $dst|$dst, $src}",
4060                           [(set GR64:$dst, (extractelt (v2i64 VR128:$src),
4061                                                         (iPTR 0)))]>,
4062                       VEX;
4063
4064 def MOVPQIto64rr : RS2I<0x7E, MRMDestReg, (outs GR64:$dst), (ins VR128:$src),
4065                         "movq\t{$src, $dst|$dst, $src}",
4066                         [(set GR64:$dst, (extractelt (v2i64 VR128:$src),
4067                                                          (iPTR 0)))]>;
4068 } //SchedRW
4069
4070 let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0, mayStore = 1 in
4071 def VMOVPQIto64mr : VRS2I<0x7E, MRMDestMem, (outs),
4072                           (ins i64mem:$dst, VR128:$src),
4073                           "movq\t{$src, $dst|$dst, $src}", []>,
4074                           VEX, Sched<[WriteVecStore]>;
4075 let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0, mayStore = 1 in
4076 def MOVPQIto64mr : RS2I<0x7E, MRMDestMem, (outs), (ins i64mem:$dst, VR128:$src),
4077                         "movq\t{$src, $dst|$dst, $src}", []>,
4078                         Sched<[WriteVecStore]>;
4079 } // ExeDomain = SSEPackedInt
4080
4081 //===---------------------------------------------------------------------===//
4082 // Bitcast FR64 <-> GR64
4083 //
4084 let ExeDomain = SSEPackedInt, isCodeGenOnly = 1 in {
4085   let Predicates = [UseAVX] in
4086   def VMOV64toSDrm : VS2SI<0x7E, MRMSrcMem, (outs FR64:$dst), (ins i64mem:$src),
4087                           "movq\t{$src, $dst|$dst, $src}",
4088                           [(set FR64:$dst, (bitconvert (loadi64 addr:$src)))]>,
4089                           VEX, Sched<[WriteVecLoad]>;
4090   def VMOVSDto64rr : VRS2I<0x7E, MRMDestReg, (outs GR64:$dst), (ins FR64:$src),
4091                            "movq\t{$src, $dst|$dst, $src}",
4092                            [(set GR64:$dst, (bitconvert FR64:$src))]>,
4093                            VEX, Sched<[WriteVecMoveToGpr]>;
4094   def VMOVSDto64mr : VRS2I<0x7E, MRMDestMem, (outs), (ins i64mem:$dst, FR64:$src),
4095                            "movq\t{$src, $dst|$dst, $src}",
4096                            [(store (i64 (bitconvert FR64:$src)), addr:$dst)]>,
4097                            VEX, Sched<[WriteVecStore]>;
4098
4099   def MOV64toSDrm : S2SI<0x7E, MRMSrcMem, (outs FR64:$dst), (ins i64mem:$src),
4100                          "movq\t{$src, $dst|$dst, $src}",
4101                          [(set FR64:$dst, (bitconvert (loadi64 addr:$src)))]>,
4102                          Sched<[WriteVecLoad]>;
4103   def MOVSDto64rr : RS2I<0x7E, MRMDestReg, (outs GR64:$dst), (ins FR64:$src),
4104                          "movq\t{$src, $dst|$dst, $src}",
4105                          [(set GR64:$dst, (bitconvert FR64:$src))]>,
4106                          Sched<[WriteVecMoveToGpr]>;
4107   def MOVSDto64mr : RS2I<0x7E, MRMDestMem, (outs), (ins i64mem:$dst, FR64:$src),
4108                          "movq\t{$src, $dst|$dst, $src}",
4109                          [(store (i64 (bitconvert FR64:$src)), addr:$dst)]>,
4110                          Sched<[WriteVecStore]>;
4111 } // ExeDomain = SSEPackedInt, isCodeGenOnly = 1
4112
4113 //===---------------------------------------------------------------------===//
4114 // Move Scalar Single to Double Int
4115 //
4116 let ExeDomain = SSEPackedInt, isCodeGenOnly = 1 in {
4117   def VMOVSS2DIrr  : VS2I<0x7E, MRMDestReg, (outs GR32:$dst), (ins FR32:$src),
4118                         "movd\t{$src, $dst|$dst, $src}",
4119                         [(set GR32:$dst, (bitconvert FR32:$src))]>,
4120                         VEX, Sched<[WriteVecMoveToGpr]>;
4121   def VMOVSS2DImr  : VS2I<0x7E, MRMDestMem, (outs), (ins i32mem:$dst, FR32:$src),
4122                         "movd\t{$src, $dst|$dst, $src}",
4123                         [(store (i32 (bitconvert FR32:$src)), addr:$dst)]>,
4124                         VEX, Sched<[WriteVecStore]>;
4125   def MOVSS2DIrr  : S2I<0x7E, MRMDestReg, (outs GR32:$dst), (ins FR32:$src),
4126                         "movd\t{$src, $dst|$dst, $src}",
4127                         [(set GR32:$dst, (bitconvert FR32:$src))]>,
4128                         Sched<[WriteVecMoveToGpr]>;
4129   def MOVSS2DImr  : S2I<0x7E, MRMDestMem, (outs), (ins i32mem:$dst, FR32:$src),
4130                         "movd\t{$src, $dst|$dst, $src}",
4131                         [(store (i32 (bitconvert FR32:$src)), addr:$dst)]>,
4132                         Sched<[WriteVecStore]>;
4133 } // ExeDomain = SSEPackedInt, isCodeGenOnly = 1
4134
4135 let Predicates = [UseAVX] in {
4136   def : Pat<(v4i32 (X86vzmovl (v4i32 (scalar_to_vector GR32:$src)))),
4137             (VMOVDI2PDIrr GR32:$src)>;
4138
4139   def : Pat<(v2i64 (X86vzmovl (v2i64 (scalar_to_vector GR64:$src)))),
4140             (VMOV64toPQIrr GR64:$src)>;
4141
4142   def : Pat<(v4i64 (X86vzmovl (insert_subvector undef,
4143               (v2i64 (scalar_to_vector GR64:$src)),(iPTR 0)))),
4144             (SUBREG_TO_REG (i64 0), (VMOV64toPQIrr GR64:$src), sub_xmm)>;
4145   // AVX 128-bit movd/movq instructions write zeros in the high 128-bit part.
4146   // These instructions also write zeros in the high part of a 256-bit register.
4147   def : Pat<(v2i64 (X86vzmovl (v2i64 (scalar_to_vector (zextloadi64i32 addr:$src))))),
4148             (VMOVDI2PDIrm addr:$src)>;
4149   def : Pat<(v4i32 (X86vzmovl (v4i32 (scalar_to_vector (loadi32 addr:$src))))),
4150             (VMOVDI2PDIrm addr:$src)>;
4151   def : Pat<(v4i32 (X86vzmovl (bc_v4i32 (loadv2i64 addr:$src)))),
4152             (VMOVDI2PDIrm addr:$src)>;
4153   def : Pat<(v4i32 (X86vzload addr:$src)),
4154             (VMOVDI2PDIrm addr:$src)>;
4155   def : Pat<(v8i32 (X86vzmovl (insert_subvector undef,
4156               (v4i32 (scalar_to_vector (loadi32 addr:$src))), (iPTR 0)))),
4157             (SUBREG_TO_REG (i32 0), (VMOVDI2PDIrm addr:$src), sub_xmm)>;
4158   def : Pat<(v8i32 (X86vzload addr:$src)),
4159             (SUBREG_TO_REG (i64 0), (VMOVDI2PDIrm addr:$src), sub_xmm)>;
4160   // Use regular 128-bit instructions to match 256-bit scalar_to_vec+zext.
4161   def : Pat<(v8i32 (X86vzmovl (insert_subvector undef,
4162                                (v4i32 (scalar_to_vector GR32:$src)),(iPTR 0)))),
4163             (SUBREG_TO_REG (i32 0), (VMOVDI2PDIrr GR32:$src), sub_xmm)>;
4164 }
4165
4166 let Predicates = [UseSSE2] in {
4167   def : Pat<(v4i32 (X86vzmovl (v4i32 (scalar_to_vector GR32:$src)))),
4168             (MOVDI2PDIrr GR32:$src)>;
4169
4170   def : Pat<(v2i64 (X86vzmovl (v2i64 (scalar_to_vector GR64:$src)))),
4171             (MOV64toPQIrr GR64:$src)>;
4172   def : Pat<(v2i64 (X86vzmovl (v2i64 (scalar_to_vector (zextloadi64i32 addr:$src))))),
4173             (MOVDI2PDIrm addr:$src)>;
4174   def : Pat<(v4i32 (X86vzmovl (v4i32 (scalar_to_vector (loadi32 addr:$src))))),
4175             (MOVDI2PDIrm addr:$src)>;
4176   def : Pat<(v4i32 (X86vzmovl (bc_v4i32 (loadv2i64 addr:$src)))),
4177             (MOVDI2PDIrm addr:$src)>;
4178   def : Pat<(v4i32 (X86vzload addr:$src)),
4179             (MOVDI2PDIrm addr:$src)>;
4180 }
4181
4182 // Before the MC layer of LLVM existed, clang emitted "movd" assembly instead of
4183 // "movq" due to MacOS parsing limitation. In order to parse old assembly, we add
4184 // these aliases.
4185 def : InstAlias<"movd\t{$src, $dst|$dst, $src}",
4186                 (MOV64toPQIrr VR128:$dst, GR64:$src), 0>;
4187 def : InstAlias<"movd\t{$src, $dst|$dst, $src}",
4188                 (MOVPQIto64rr GR64:$dst, VR128:$src), 0>;
4189 // Allow "vmovd" but print "vmovq" since we don't need compatibility for AVX.
4190 def : InstAlias<"vmovd\t{$src, $dst|$dst, $src}",
4191                 (VMOV64toPQIrr VR128:$dst, GR64:$src), 0>;
4192 def : InstAlias<"vmovd\t{$src, $dst|$dst, $src}",
4193                 (VMOVPQIto64rr GR64:$dst, VR128:$src), 0>;
4194
4195 //===---------------------------------------------------------------------===//
4196 // SSE2 - Move Quadword
4197 //===---------------------------------------------------------------------===//
4198
4199 //===---------------------------------------------------------------------===//
4200 // Move Quadword Int to Packed Quadword Int
4201 //
4202
4203 let ExeDomain = SSEPackedInt, SchedRW = [WriteVecLoad] in {
4204 def VMOVQI2PQIrm : I<0x7E, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
4205                     "vmovq\t{$src, $dst|$dst, $src}",
4206                     [(set VR128:$dst,
4207                       (v2i64 (scalar_to_vector (loadi64 addr:$src))))]>, XS,
4208                     VEX, Requires<[UseAVX]>, VEX_WIG;
4209 def MOVQI2PQIrm : I<0x7E, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
4210                     "movq\t{$src, $dst|$dst, $src}",
4211                     [(set VR128:$dst,
4212                       (v2i64 (scalar_to_vector (loadi64 addr:$src))))]>,
4213                     XS, Requires<[UseSSE2]>; // SSE2 instruction with XS Prefix
4214 } // ExeDomain, SchedRW
4215
4216 //===---------------------------------------------------------------------===//
4217 // Move Packed Quadword Int to Quadword Int
4218 //
4219 let ExeDomain = SSEPackedInt, SchedRW = [WriteVecStore] in {
4220 def VMOVPQI2QImr : VS2I<0xD6, MRMDestMem, (outs), (ins i64mem:$dst, VR128:$src),
4221                         "movq\t{$src, $dst|$dst, $src}",
4222                         [(store (i64 (extractelt (v2i64 VR128:$src),
4223                                       (iPTR 0))), addr:$dst)]>,
4224                         VEX, VEX_WIG;
4225 def MOVPQI2QImr : S2I<0xD6, MRMDestMem, (outs), (ins i64mem:$dst, VR128:$src),
4226                       "movq\t{$src, $dst|$dst, $src}",
4227                       [(store (i64 (extractelt (v2i64 VR128:$src),
4228                                     (iPTR 0))), addr:$dst)]>;
4229 } // ExeDomain, SchedRW
4230
4231 // For disassembler only
4232 let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0,
4233     SchedRW = [SchedWriteVecLogic.XMM] in {
4234 def VMOVPQI2QIrr : VS2I<0xD6, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
4235                      "movq\t{$src, $dst|$dst, $src}", []>, VEX, VEX_WIG;
4236 def MOVPQI2QIrr : S2I<0xD6, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
4237                       "movq\t{$src, $dst|$dst, $src}", []>;
4238 }
4239
4240 // Aliases to help the assembler pick two byte VEX encodings by swapping the
4241 // operands relative to the normal instructions to use VEX.R instead of VEX.B.
4242 def : InstAlias<"vmovq\t{$src, $dst|$dst, $src}",
4243                 (VMOVPQI2QIrr VR128L:$dst, VR128H:$src), 0>;
4244
4245 def : InstAlias<"vmovq.s\t{$src, $dst|$dst, $src}",
4246                 (VMOVPQI2QIrr VR128:$dst, VR128:$src), 0>;
4247 def : InstAlias<"movq.s\t{$src, $dst|$dst, $src}",
4248                 (MOVPQI2QIrr VR128:$dst, VR128:$src), 0>;
4249
4250 let Predicates = [UseAVX] in {
4251   def : Pat<(v2i64 (X86vzmovl (loadv2i64 addr:$src))),
4252             (VMOVQI2PQIrm addr:$src)>;
4253   def : Pat<(v2i64 (X86vzload addr:$src)),
4254             (VMOVQI2PQIrm addr:$src)>;
4255   def : Pat<(v4i64 (X86vzmovl (insert_subvector undef,
4256               (v2i64 (scalar_to_vector (loadi64 addr:$src))), (iPTR 0)))),
4257             (SUBREG_TO_REG (i64 0), (VMOVQI2PQIrm addr:$src), sub_xmm)>;
4258   def : Pat<(v4i64 (X86vzload addr:$src)),
4259             (SUBREG_TO_REG (i64 0), (VMOVQI2PQIrm addr:$src), sub_xmm)>;
4260 }
4261
4262 let Predicates = [UseSSE2] in {
4263   def : Pat<(v2i64 (X86vzmovl (loadv2i64 addr:$src))),
4264             (MOVQI2PQIrm addr:$src)>;
4265   def : Pat<(v2i64 (X86vzload addr:$src)), (MOVQI2PQIrm addr:$src)>;
4266 }
4267
4268 //===---------------------------------------------------------------------===//
4269 // Moving from XMM to XMM and clear upper 64 bits. Note, there is a bug in
4270 // IA32 document. movq xmm1, xmm2 does clear the high bits.
4271 //
4272 let ExeDomain = SSEPackedInt, SchedRW = [SchedWriteVecLogic.XMM] in {
4273 def VMOVZPQILo2PQIrr : I<0x7E, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
4274                         "vmovq\t{$src, $dst|$dst, $src}",
4275                     [(set VR128:$dst, (v2i64 (X86vzmovl (v2i64 VR128:$src))))]>,
4276                          XS, VEX, Requires<[UseAVX]>, VEX_WIG;
4277 def MOVZPQILo2PQIrr : I<0x7E, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
4278                         "movq\t{$src, $dst|$dst, $src}",
4279                     [(set VR128:$dst, (v2i64 (X86vzmovl (v2i64 VR128:$src))))]>,
4280                         XS, Requires<[UseSSE2]>;
4281 } // ExeDomain, SchedRW
4282
4283 let Predicates = [UseAVX] in {
4284   def : Pat<(v2f64 (X86vzmovl (v2f64 VR128:$src))),
4285             (VMOVZPQILo2PQIrr VR128:$src)>;
4286 }
4287 let Predicates = [UseSSE2] in {
4288   def : Pat<(v2f64 (X86vzmovl (v2f64 VR128:$src))),
4289             (MOVZPQILo2PQIrr VR128:$src)>;
4290 }
4291
4292 //===---------------------------------------------------------------------===//
4293 // SSE3 - Replicate Single FP - MOVSHDUP and MOVSLDUP
4294 //===---------------------------------------------------------------------===//
4295
4296 multiclass sse3_replicate_sfp<bits<8> op, SDNode OpNode, string OpcodeStr,
4297                               ValueType vt, RegisterClass RC, PatFrag mem_frag,
4298                               X86MemOperand x86memop, X86FoldableSchedWrite sched> {
4299 def rr : S3SI<op, MRMSrcReg, (outs RC:$dst), (ins RC:$src),
4300                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
4301                       [(set RC:$dst, (vt (OpNode RC:$src)))]>,
4302                       Sched<[sched]>;
4303 def rm : S3SI<op, MRMSrcMem, (outs RC:$dst), (ins x86memop:$src),
4304                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
4305                       [(set RC:$dst, (OpNode (mem_frag addr:$src)))]>,
4306                       Sched<[sched.Folded]>;
4307 }
4308
4309 let Predicates = [HasAVX, NoVLX] in {
4310   defm VMOVSHDUP  : sse3_replicate_sfp<0x16, X86Movshdup, "vmovshdup",
4311                                        v4f32, VR128, loadv4f32, f128mem,
4312                                        SchedWriteFShuffle.XMM>, VEX, VEX_WIG;
4313   defm VMOVSLDUP  : sse3_replicate_sfp<0x12, X86Movsldup, "vmovsldup",
4314                                        v4f32, VR128, loadv4f32, f128mem,
4315                                        SchedWriteFShuffle.XMM>, VEX, VEX_WIG;
4316   defm VMOVSHDUPY : sse3_replicate_sfp<0x16, X86Movshdup, "vmovshdup",
4317                                        v8f32, VR256, loadv8f32, f256mem,
4318                                        SchedWriteFShuffle.YMM>, VEX, VEX_L, VEX_WIG;
4319   defm VMOVSLDUPY : sse3_replicate_sfp<0x12, X86Movsldup, "vmovsldup",
4320                                        v8f32, VR256, loadv8f32, f256mem,
4321                                        SchedWriteFShuffle.YMM>, VEX, VEX_L, VEX_WIG;
4322 }
4323 defm MOVSHDUP : sse3_replicate_sfp<0x16, X86Movshdup, "movshdup", v4f32, VR128,
4324                                    memopv4f32, f128mem, SchedWriteFShuffle.XMM>;
4325 defm MOVSLDUP : sse3_replicate_sfp<0x12, X86Movsldup, "movsldup", v4f32, VR128,
4326                                    memopv4f32, f128mem, SchedWriteFShuffle.XMM>;
4327
4328 let Predicates = [HasAVX, NoVLX] in {
4329   def : Pat<(v4i32 (X86Movshdup VR128:$src)),
4330             (VMOVSHDUPrr VR128:$src)>;
4331   def : Pat<(v4i32 (X86Movshdup (bc_v4i32 (loadv2i64 addr:$src)))),
4332             (VMOVSHDUPrm addr:$src)>;
4333   def : Pat<(v4i32 (X86Movsldup VR128:$src)),
4334             (VMOVSLDUPrr VR128:$src)>;
4335   def : Pat<(v4i32 (X86Movsldup (bc_v4i32 (loadv2i64 addr:$src)))),
4336             (VMOVSLDUPrm addr:$src)>;
4337   def : Pat<(v8i32 (X86Movshdup VR256:$src)),
4338             (VMOVSHDUPYrr VR256:$src)>;
4339   def : Pat<(v8i32 (X86Movshdup (bc_v8i32 (loadv4i64 addr:$src)))),
4340             (VMOVSHDUPYrm addr:$src)>;
4341   def : Pat<(v8i32 (X86Movsldup VR256:$src)),
4342             (VMOVSLDUPYrr VR256:$src)>;
4343   def : Pat<(v8i32 (X86Movsldup (bc_v8i32 (loadv4i64 addr:$src)))),
4344             (VMOVSLDUPYrm addr:$src)>;
4345 }
4346
4347 let Predicates = [UseSSE3] in {
4348   def : Pat<(v4i32 (X86Movshdup VR128:$src)),
4349             (MOVSHDUPrr VR128:$src)>;
4350   def : Pat<(v4i32 (X86Movshdup (bc_v4i32 (memopv2i64 addr:$src)))),
4351             (MOVSHDUPrm addr:$src)>;
4352   def : Pat<(v4i32 (X86Movsldup VR128:$src)),
4353             (MOVSLDUPrr VR128:$src)>;
4354   def : Pat<(v4i32 (X86Movsldup (bc_v4i32 (memopv2i64 addr:$src)))),
4355             (MOVSLDUPrm addr:$src)>;
4356 }
4357
4358 //===---------------------------------------------------------------------===//
4359 // SSE3 - Replicate Double FP - MOVDDUP
4360 //===---------------------------------------------------------------------===//
4361
4362 multiclass sse3_replicate_dfp<string OpcodeStr, X86SchedWriteWidths sched> {
4363 def rr  : S3DI<0x12, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
4364                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
4365                     [(set VR128:$dst, (v2f64 (X86Movddup VR128:$src)))]>,
4366                     Sched<[sched.XMM]>;
4367 def rm  : S3DI<0x12, MRMSrcMem, (outs VR128:$dst), (ins f64mem:$src),
4368                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
4369                     [(set VR128:$dst,
4370                       (v2f64 (X86Movddup
4371                               (scalar_to_vector (loadf64 addr:$src)))))]>,
4372                     Sched<[sched.XMM.Folded]>;
4373 }
4374
4375 // FIXME: Merge with above classes when there are patterns for the ymm version
4376 multiclass sse3_replicate_dfp_y<string OpcodeStr, X86SchedWriteWidths sched> {
4377 def rr  : S3DI<0x12, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
4378                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
4379                     [(set VR256:$dst, (v4f64 (X86Movddup VR256:$src)))]>,
4380                     Sched<[sched.YMM]>;
4381 def rm  : S3DI<0x12, MRMSrcMem, (outs VR256:$dst), (ins f256mem:$src),
4382                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
4383                     [(set VR256:$dst,
4384                       (v4f64 (X86Movddup (loadv4f64 addr:$src))))]>,
4385                     Sched<[sched.YMM.Folded]>;
4386 }
4387
4388 let Predicates = [HasAVX, NoVLX] in {
4389   defm VMOVDDUP  : sse3_replicate_dfp<"vmovddup", SchedWriteFShuffle>,
4390                                       VEX, VEX_WIG;
4391   defm VMOVDDUPY : sse3_replicate_dfp_y<"vmovddup", SchedWriteFShuffle>,
4392                                         VEX, VEX_L, VEX_WIG;
4393 }
4394
4395 defm MOVDDUP : sse3_replicate_dfp<"movddup", SchedWriteFShuffle>;
4396
4397
4398 let Predicates = [HasAVX, NoVLX] in {
4399   def : Pat<(X86Movddup (loadv2f64 addr:$src)),
4400             (VMOVDDUPrm addr:$src)>, Requires<[HasAVX]>;
4401 }
4402
4403 let Predicates = [UseSSE3] in {
4404   // No need for aligned memory as this only loads 64-bits.
4405   def : Pat<(X86Movddup (loadv2f64 addr:$src)),
4406             (MOVDDUPrm addr:$src)>;
4407 }
4408
4409 //===---------------------------------------------------------------------===//
4410 // SSE3 - Move Unaligned Integer
4411 //===---------------------------------------------------------------------===//
4412
4413 let Predicates = [HasAVX] in {
4414   def VLDDQUrm : S3DI<0xF0, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
4415                       "vlddqu\t{$src, $dst|$dst, $src}",
4416                       [(set VR128:$dst, (int_x86_sse3_ldu_dq addr:$src))]>,
4417                       Sched<[SchedWriteVecMoveLS.XMM.RM]>, VEX, VEX_WIG;
4418   def VLDDQUYrm : S3DI<0xF0, MRMSrcMem, (outs VR256:$dst), (ins i256mem:$src),
4419                        "vlddqu\t{$src, $dst|$dst, $src}",
4420                        [(set VR256:$dst, (int_x86_avx_ldu_dq_256 addr:$src))]>,
4421                        Sched<[SchedWriteVecMoveLS.YMM.RM]>, VEX, VEX_L, VEX_WIG;
4422 } // Predicates
4423
4424 def LDDQUrm : S3DI<0xF0, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
4425                    "lddqu\t{$src, $dst|$dst, $src}",
4426                    [(set VR128:$dst, (int_x86_sse3_ldu_dq addr:$src))]>,
4427                    Sched<[SchedWriteVecMoveLS.XMM.RM]>;
4428
4429 //===---------------------------------------------------------------------===//
4430 // SSE3 - Arithmetic
4431 //===---------------------------------------------------------------------===//
4432
4433 multiclass sse3_addsub<string OpcodeStr, ValueType vt, RegisterClass RC,
4434                        X86MemOperand x86memop, X86FoldableSchedWrite sched,
4435                        PatFrag ld_frag, bit Is2Addr = 1> {
4436   def rr : I<0xD0, MRMSrcReg,
4437        (outs RC:$dst), (ins RC:$src1, RC:$src2),
4438        !if(Is2Addr,
4439            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
4440            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
4441        [(set RC:$dst, (vt (X86Addsub RC:$src1, RC:$src2)))]>,
4442        Sched<[sched]>;
4443   def rm : I<0xD0, MRMSrcMem,
4444        (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
4445        !if(Is2Addr,
4446            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
4447            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
4448        [(set RC:$dst, (vt (X86Addsub RC:$src1, (ld_frag addr:$src2))))]>,
4449        Sched<[sched.Folded, ReadAfterLd]>;
4450 }
4451
4452 let Predicates = [HasAVX] in {
4453   let ExeDomain = SSEPackedSingle in {
4454     defm VADDSUBPS : sse3_addsub<"vaddsubps", v4f32, VR128, f128mem,
4455                                  SchedWriteFAddSizes.PS.XMM, loadv4f32, 0>,
4456                                  XD, VEX_4V, VEX_WIG;
4457     defm VADDSUBPSY : sse3_addsub<"vaddsubps", v8f32, VR256, f256mem,
4458                                   SchedWriteFAddSizes.PS.YMM, loadv8f32, 0>,
4459                                   XD, VEX_4V, VEX_L, VEX_WIG;
4460   }
4461   let ExeDomain = SSEPackedDouble in {
4462     defm VADDSUBPD : sse3_addsub<"vaddsubpd", v2f64, VR128, f128mem,
4463                                  SchedWriteFAddSizes.PD.XMM, loadv2f64, 0>,
4464                                  PD, VEX_4V, VEX_WIG;
4465     defm VADDSUBPDY : sse3_addsub<"vaddsubpd", v4f64, VR256, f256mem,
4466                                   SchedWriteFAddSizes.PD.YMM, loadv4f64, 0>,
4467                                   PD, VEX_4V, VEX_L, VEX_WIG;
4468   }
4469 }
4470 let Constraints = "$src1 = $dst", Predicates = [UseSSE3] in {
4471   let ExeDomain = SSEPackedSingle in
4472   defm ADDSUBPS : sse3_addsub<"addsubps", v4f32, VR128, f128mem,
4473                               SchedWriteFAddSizes.PS.XMM, memopv4f32>, XD;
4474   let ExeDomain = SSEPackedDouble in
4475   defm ADDSUBPD : sse3_addsub<"addsubpd", v2f64, VR128, f128mem,
4476                               SchedWriteFAddSizes.PD.XMM, memopv2f64>, PD;
4477 }
4478
4479 //===---------------------------------------------------------------------===//
4480 // SSE3 Instructions
4481 //===---------------------------------------------------------------------===//
4482
4483 // Horizontal ops
4484 multiclass S3D_Int<bits<8> o, string OpcodeStr, ValueType vt, RegisterClass RC,
4485                    X86MemOperand x86memop, SDNode OpNode,
4486                    X86FoldableSchedWrite sched, PatFrag ld_frag,
4487                    bit Is2Addr = 1> {
4488   def rr : S3DI<o, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
4489        !if(Is2Addr,
4490          !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
4491          !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
4492       [(set RC:$dst, (vt (OpNode RC:$src1, RC:$src2)))]>,
4493       Sched<[sched]>;
4494
4495   def rm : S3DI<o, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
4496        !if(Is2Addr,
4497          !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
4498          !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
4499       [(set RC:$dst, (vt (OpNode RC:$src1, (ld_frag addr:$src2))))]>,
4500       Sched<[sched.Folded, ReadAfterLd]>;
4501 }
4502 multiclass S3_Int<bits<8> o, string OpcodeStr, ValueType vt, RegisterClass RC,
4503                   X86MemOperand x86memop, SDNode OpNode,
4504                   X86FoldableSchedWrite sched, PatFrag ld_frag,
4505                   bit Is2Addr = 1> {
4506   def rr : S3I<o, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
4507        !if(Is2Addr,
4508          !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
4509          !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
4510       [(set RC:$dst, (vt (OpNode RC:$src1, RC:$src2)))]>,
4511         Sched<[sched]>;
4512
4513   def rm : S3I<o, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
4514        !if(Is2Addr,
4515          !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
4516          !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
4517       [(set RC:$dst, (vt (OpNode RC:$src1, (ld_frag addr:$src2))))]>,
4518         Sched<[sched.Folded, ReadAfterLd]>;
4519 }
4520
4521 let Predicates = [HasAVX] in {
4522   let ExeDomain = SSEPackedSingle in {
4523     defm VHADDPS  : S3D_Int<0x7C, "vhaddps", v4f32, VR128, f128mem,
4524                             X86fhadd, WriteFHAdd, loadv4f32, 0>, VEX_4V, VEX_WIG;
4525     defm VHSUBPS  : S3D_Int<0x7D, "vhsubps", v4f32, VR128, f128mem,
4526                             X86fhsub, WriteFHAdd, loadv4f32, 0>, VEX_4V, VEX_WIG;
4527     defm VHADDPSY : S3D_Int<0x7C, "vhaddps", v8f32, VR256, f256mem,
4528                             X86fhadd, WriteFHAddY, loadv8f32, 0>, VEX_4V, VEX_L, VEX_WIG;
4529     defm VHSUBPSY : S3D_Int<0x7D, "vhsubps", v8f32, VR256, f256mem,
4530                             X86fhsub, WriteFHAddY, loadv8f32, 0>, VEX_4V, VEX_L, VEX_WIG;
4531   }
4532   let ExeDomain = SSEPackedDouble in {
4533     defm VHADDPD  : S3_Int<0x7C, "vhaddpd", v2f64, VR128, f128mem,
4534                            X86fhadd, WriteFHAdd, loadv2f64, 0>, VEX_4V, VEX_WIG;
4535     defm VHSUBPD  : S3_Int<0x7D, "vhsubpd", v2f64, VR128, f128mem,
4536                            X86fhsub, WriteFHAdd, loadv2f64, 0>, VEX_4V, VEX_WIG;
4537     defm VHADDPDY : S3_Int<0x7C, "vhaddpd", v4f64, VR256, f256mem,
4538                            X86fhadd, WriteFHAddY, loadv4f64, 0>, VEX_4V, VEX_L, VEX_WIG;
4539     defm VHSUBPDY : S3_Int<0x7D, "vhsubpd", v4f64, VR256, f256mem,
4540                            X86fhsub, WriteFHAddY, loadv4f64, 0>, VEX_4V, VEX_L, VEX_WIG;
4541   }
4542 }
4543
4544 let Constraints = "$src1 = $dst" in {
4545   let ExeDomain = SSEPackedSingle in {
4546     defm HADDPS : S3D_Int<0x7C, "haddps", v4f32, VR128, f128mem, X86fhadd,
4547                           WriteFHAdd, memopv4f32>;
4548     defm HSUBPS : S3D_Int<0x7D, "hsubps", v4f32, VR128, f128mem, X86fhsub,
4549                           WriteFHAdd, memopv4f32>;
4550   }
4551   let ExeDomain = SSEPackedDouble in {
4552     defm HADDPD : S3_Int<0x7C, "haddpd", v2f64, VR128, f128mem, X86fhadd,
4553                          WriteFHAdd, memopv2f64>;
4554     defm HSUBPD : S3_Int<0x7D, "hsubpd", v2f64, VR128, f128mem, X86fhsub,
4555                          WriteFHAdd, memopv2f64>;
4556   }
4557 }
4558
4559 //===---------------------------------------------------------------------===//
4560 // SSSE3 - Packed Absolute Instructions
4561 //===---------------------------------------------------------------------===//
4562
4563 /// SS3I_unop_rm_int - Simple SSSE3 unary op whose type can be v*{i8,i16,i32}.
4564 multiclass SS3I_unop_rm<bits<8> opc, string OpcodeStr, ValueType vt,
4565                         SDNode OpNode, X86SchedWriteWidths sched, PatFrag ld_frag> {
4566   def rr : SS38I<opc, MRMSrcReg, (outs VR128:$dst),
4567                  (ins VR128:$src),
4568                  !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
4569                  [(set VR128:$dst, (vt (OpNode VR128:$src)))]>,
4570                  Sched<[sched.XMM]>;
4571
4572   def rm : SS38I<opc, MRMSrcMem, (outs VR128:$dst),
4573                  (ins i128mem:$src),
4574                  !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
4575                  [(set VR128:$dst,
4576                    (vt (OpNode (bitconvert (ld_frag addr:$src)))))]>,
4577                  Sched<[sched.XMM.Folded]>;
4578 }
4579
4580 /// SS3I_unop_rm_int_y - Simple SSSE3 unary op whose type can be v*{i8,i16,i32}.
4581 multiclass SS3I_unop_rm_y<bits<8> opc, string OpcodeStr, ValueType vt,
4582                           SDNode OpNode, X86SchedWriteWidths sched> {
4583   def Yrr : SS38I<opc, MRMSrcReg, (outs VR256:$dst),
4584                   (ins VR256:$src),
4585                   !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
4586                   [(set VR256:$dst, (vt (OpNode VR256:$src)))]>,
4587                   Sched<[sched.YMM]>;
4588
4589   def Yrm : SS38I<opc, MRMSrcMem, (outs VR256:$dst),
4590                   (ins i256mem:$src),
4591                   !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
4592                   [(set VR256:$dst,
4593                     (vt (OpNode (bitconvert (loadv4i64 addr:$src)))))]>,
4594                   Sched<[sched.YMM.Folded]>;
4595 }
4596
4597 let Predicates = [HasAVX, NoVLX_Or_NoBWI] in {
4598   defm VPABSB  : SS3I_unop_rm<0x1C, "vpabsb", v16i8, abs, SchedWriteVecALU,
4599                               loadv2i64>, VEX, VEX_WIG;
4600   defm VPABSW  : SS3I_unop_rm<0x1D, "vpabsw", v8i16, abs, SchedWriteVecALU,
4601                               loadv2i64>, VEX, VEX_WIG;
4602 }
4603 let Predicates = [HasAVX, NoVLX] in {
4604   defm VPABSD  : SS3I_unop_rm<0x1E, "vpabsd", v4i32, abs, SchedWriteVecALU,
4605                               loadv2i64>, VEX, VEX_WIG;
4606 }
4607 let Predicates = [HasAVX2, NoVLX_Or_NoBWI] in {
4608   defm VPABSB  : SS3I_unop_rm_y<0x1C, "vpabsb", v32i8, abs, SchedWriteVecALU>,
4609                                 VEX, VEX_L, VEX_WIG;
4610   defm VPABSW  : SS3I_unop_rm_y<0x1D, "vpabsw", v16i16, abs, SchedWriteVecALU>,
4611                                 VEX, VEX_L, VEX_WIG;
4612 }
4613 let Predicates = [HasAVX2, NoVLX] in {
4614   defm VPABSD  : SS3I_unop_rm_y<0x1E, "vpabsd", v8i32, abs, SchedWriteVecALU>,
4615                                 VEX, VEX_L, VEX_WIG;
4616 }
4617
4618 defm PABSB : SS3I_unop_rm<0x1C, "pabsb", v16i8, abs, SchedWriteVecALU,
4619                           memopv2i64>;
4620 defm PABSW : SS3I_unop_rm<0x1D, "pabsw", v8i16, abs, SchedWriteVecALU,
4621                           memopv2i64>;
4622 defm PABSD : SS3I_unop_rm<0x1E, "pabsd", v4i32, abs, SchedWriteVecALU,
4623                           memopv2i64>;
4624
4625 //===---------------------------------------------------------------------===//
4626 // SSSE3 - Packed Binary Operator Instructions
4627 //===---------------------------------------------------------------------===//
4628
4629 /// SS3I_binop_rm - Simple SSSE3 bin op
4630 multiclass SS3I_binop_rm<bits<8> opc, string OpcodeStr, SDNode OpNode,
4631                          ValueType DstVT, ValueType OpVT, RegisterClass RC,
4632                          PatFrag memop_frag, X86MemOperand x86memop,
4633                          X86FoldableSchedWrite sched, bit Is2Addr = 1> {
4634   let isCommutable = 1 in
4635   def rr : SS38I<opc, MRMSrcReg, (outs RC:$dst),
4636        (ins RC:$src1, RC:$src2),
4637        !if(Is2Addr,
4638          !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
4639          !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
4640        [(set RC:$dst, (DstVT (OpNode (OpVT RC:$src1), RC:$src2)))]>,
4641        Sched<[sched]>;
4642   def rm : SS38I<opc, MRMSrcMem, (outs RC:$dst),
4643        (ins RC:$src1, x86memop:$src2),
4644        !if(Is2Addr,
4645          !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
4646          !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
4647        [(set RC:$dst,
4648          (DstVT (OpNode (OpVT RC:$src1),
4649           (bitconvert (memop_frag addr:$src2)))))]>,
4650        Sched<[sched.Folded, ReadAfterLd]>;
4651 }
4652
4653 /// SS3I_binop_rm_int - Simple SSSE3 bin op whose type can be v*{i8,i16,i32}.
4654 multiclass SS3I_binop_rm_int<bits<8> opc, string OpcodeStr,
4655                              Intrinsic IntId128, X86FoldableSchedWrite sched,
4656                              PatFrag ld_frag, bit Is2Addr = 1> {
4657   let isCommutable = 1 in
4658   def rr : SS38I<opc, MRMSrcReg, (outs VR128:$dst),
4659        (ins VR128:$src1, VR128:$src2),
4660        !if(Is2Addr,
4661          !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
4662          !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
4663        [(set VR128:$dst, (IntId128 VR128:$src1, VR128:$src2))]>,
4664        Sched<[sched]>;
4665   def rm : SS38I<opc, MRMSrcMem, (outs VR128:$dst),
4666        (ins VR128:$src1, i128mem:$src2),
4667        !if(Is2Addr,
4668          !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
4669          !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
4670        [(set VR128:$dst,
4671          (IntId128 VR128:$src1,
4672           (bitconvert (ld_frag addr:$src2))))]>,
4673        Sched<[sched.Folded, ReadAfterLd]>;
4674 }
4675
4676 multiclass SS3I_binop_rm_int_y<bits<8> opc, string OpcodeStr,
4677                                Intrinsic IntId256,
4678                                X86FoldableSchedWrite sched> {
4679   let isCommutable = 1 in
4680   def Yrr : SS38I<opc, MRMSrcReg, (outs VR256:$dst),
4681        (ins VR256:$src1, VR256:$src2),
4682        !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4683        [(set VR256:$dst, (IntId256 VR256:$src1, VR256:$src2))]>,
4684        Sched<[sched]>;
4685   def Yrm : SS38I<opc, MRMSrcMem, (outs VR256:$dst),
4686        (ins VR256:$src1, i256mem:$src2),
4687        !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4688        [(set VR256:$dst,
4689          (IntId256 VR256:$src1, (bitconvert (loadv4i64 addr:$src2))))]>,
4690        Sched<[sched.Folded, ReadAfterLd]>;
4691 }
4692
4693 let ImmT = NoImm, Predicates = [HasAVX, NoVLX_Or_NoBWI] in {
4694 let isCommutable = 0 in {
4695   defm VPSHUFB    : SS3I_binop_rm<0x00, "vpshufb", X86pshufb, v16i8, v16i8,
4696                                   VR128, loadv2i64, i128mem,
4697                                   SchedWriteVarShuffle.XMM, 0>, VEX_4V, VEX_WIG;
4698   defm VPMADDUBSW : SS3I_binop_rm<0x04, "vpmaddubsw", X86vpmaddubsw, v8i16,
4699                                   v16i8, VR128, loadv2i64, i128mem,
4700                                   SchedWriteVecIMul.XMM, 0>, VEX_4V, VEX_WIG;
4701 }
4702 defm VPMULHRSW    : SS3I_binop_rm<0x0B, "vpmulhrsw", X86mulhrs, v8i16, v8i16,
4703                                   VR128, loadv2i64, i128mem,
4704                                   SchedWriteVecIMul.XMM, 0>, VEX_4V, VEX_WIG;
4705 }
4706
4707 let ImmT = NoImm, Predicates = [HasAVX] in {
4708 let isCommutable = 0 in {
4709   defm VPHADDW    : SS3I_binop_rm<0x01, "vphaddw", X86hadd, v8i16, v8i16, VR128,
4710                                   loadv2i64, i128mem,
4711                                   SchedWritePHAdd.XMM, 0>, VEX_4V, VEX_WIG;
4712   defm VPHADDD    : SS3I_binop_rm<0x02, "vphaddd", X86hadd, v4i32, v4i32, VR128,
4713                                   loadv2i64, i128mem,
4714                                   SchedWritePHAdd.XMM, 0>, VEX_4V, VEX_WIG;
4715   defm VPHSUBW    : SS3I_binop_rm<0x05, "vphsubw", X86hsub, v8i16, v8i16, VR128,
4716                                   loadv2i64, i128mem,
4717                                   SchedWritePHAdd.XMM, 0>, VEX_4V, VEX_WIG;
4718   defm VPHSUBD    : SS3I_binop_rm<0x06, "vphsubd", X86hsub, v4i32, v4i32, VR128,
4719                                   loadv2i64, i128mem,
4720                                   SchedWritePHAdd.XMM, 0>, VEX_4V;
4721   defm VPSIGNB    : SS3I_binop_rm_int<0x08, "vpsignb",
4722                                       int_x86_ssse3_psign_b_128,
4723                                       SchedWriteVecALU.XMM, loadv2i64, 0>, VEX_4V, VEX_WIG;
4724   defm VPSIGNW    : SS3I_binop_rm_int<0x09, "vpsignw",
4725                                       int_x86_ssse3_psign_w_128,
4726                                       SchedWriteVecALU.XMM, loadv2i64, 0>, VEX_4V, VEX_WIG;
4727   defm VPSIGND    : SS3I_binop_rm_int<0x0A, "vpsignd",
4728                                       int_x86_ssse3_psign_d_128,
4729                                       SchedWriteVecALU.XMM, loadv2i64, 0>, VEX_4V, VEX_WIG;
4730   defm VPHADDSW   : SS3I_binop_rm_int<0x03, "vphaddsw",
4731                                       int_x86_ssse3_phadd_sw_128,
4732                                       SchedWritePHAdd.XMM, loadv2i64, 0>, VEX_4V, VEX_WIG;
4733   defm VPHSUBSW   : SS3I_binop_rm_int<0x07, "vphsubsw",
4734                                       int_x86_ssse3_phsub_sw_128,
4735                                       SchedWritePHAdd.XMM, loadv2i64, 0>, VEX_4V, VEX_WIG;
4736 }
4737 }
4738
4739 let ImmT = NoImm, Predicates = [HasAVX2, NoVLX_Or_NoBWI] in {
4740 let isCommutable = 0 in {
4741   defm VPSHUFBY   : SS3I_binop_rm<0x00, "vpshufb", X86pshufb, v32i8, v32i8,
4742                                   VR256, loadv4i64, i256mem,
4743                                   SchedWriteVarShuffle.YMM, 0>, VEX_4V, VEX_L, VEX_WIG;
4744   defm VPMADDUBSWY : SS3I_binop_rm<0x04, "vpmaddubsw", X86vpmaddubsw, v16i16,
4745                                    v32i8, VR256, loadv4i64, i256mem,
4746                                    SchedWriteVecIMul.YMM, 0>, VEX_4V, VEX_L, VEX_WIG;
4747 }
4748 defm VPMULHRSWY   : SS3I_binop_rm<0x0B, "vpmulhrsw", X86mulhrs, v16i16, v16i16,
4749                                   VR256, loadv4i64, i256mem,
4750                                   SchedWriteVecIMul.YMM, 0>, VEX_4V, VEX_L, VEX_WIG;
4751 }
4752
4753 let ImmT = NoImm, Predicates = [HasAVX2] in {
4754 let isCommutable = 0 in {
4755   defm VPHADDWY   : SS3I_binop_rm<0x01, "vphaddw", X86hadd, v16i16, v16i16,
4756                                   VR256, loadv4i64, i256mem,
4757                                   SchedWritePHAdd.YMM, 0>, VEX_4V, VEX_L, VEX_WIG;
4758   defm VPHADDDY   : SS3I_binop_rm<0x02, "vphaddd", X86hadd, v8i32, v8i32, VR256,
4759                                   loadv4i64, i256mem,
4760                                   SchedWritePHAdd.YMM, 0>, VEX_4V, VEX_L, VEX_WIG;
4761   defm VPHSUBWY   : SS3I_binop_rm<0x05, "vphsubw", X86hsub, v16i16, v16i16,
4762                                   VR256, loadv4i64, i256mem,
4763                                   SchedWritePHAdd.YMM, 0>, VEX_4V, VEX_L, VEX_WIG;
4764   defm VPHSUBDY   : SS3I_binop_rm<0x06, "vphsubd", X86hsub, v8i32, v8i32, VR256,
4765                                   loadv4i64, i256mem,
4766                                   SchedWritePHAdd.YMM, 0>, VEX_4V, VEX_L;
4767   defm VPSIGNB   : SS3I_binop_rm_int_y<0x08, "vpsignb", int_x86_avx2_psign_b,
4768                                        SchedWriteVecALU.YMM>, VEX_4V, VEX_L, VEX_WIG;
4769   defm VPSIGNW   : SS3I_binop_rm_int_y<0x09, "vpsignw", int_x86_avx2_psign_w,
4770                                        SchedWriteVecALU.YMM>, VEX_4V, VEX_L, VEX_WIG;
4771   defm VPSIGND   : SS3I_binop_rm_int_y<0x0A, "vpsignd", int_x86_avx2_psign_d,
4772                                        SchedWriteVecALU.YMM>, VEX_4V, VEX_L, VEX_WIG;
4773   defm VPHADDSW  : SS3I_binop_rm_int_y<0x03, "vphaddsw",
4774                                        int_x86_avx2_phadd_sw,
4775                                        SchedWritePHAdd.YMM>, VEX_4V, VEX_L, VEX_WIG;
4776   defm VPHSUBSW  : SS3I_binop_rm_int_y<0x07, "vphsubsw",
4777                                        int_x86_avx2_phsub_sw,
4778                                        SchedWritePHAdd.YMM>, VEX_4V, VEX_L, VEX_WIG;
4779 }
4780 }
4781
4782 // None of these have i8 immediate fields.
4783 let ImmT = NoImm, Constraints = "$src1 = $dst" in {
4784 let isCommutable = 0 in {
4785   defm PHADDW    : SS3I_binop_rm<0x01, "phaddw", X86hadd, v8i16, v8i16, VR128,
4786                                  memopv2i64, i128mem, SchedWritePHAdd.XMM>;
4787   defm PHADDD    : SS3I_binop_rm<0x02, "phaddd", X86hadd, v4i32, v4i32, VR128,
4788                                  memopv2i64, i128mem, SchedWritePHAdd.XMM>;
4789   defm PHSUBW    : SS3I_binop_rm<0x05, "phsubw", X86hsub, v8i16, v8i16, VR128,
4790                                  memopv2i64, i128mem, SchedWritePHAdd.XMM>;
4791   defm PHSUBD    : SS3I_binop_rm<0x06, "phsubd", X86hsub, v4i32, v4i32, VR128,
4792                                  memopv2i64, i128mem, SchedWritePHAdd.XMM>;
4793   defm PSIGNB    : SS3I_binop_rm_int<0x08, "psignb", int_x86_ssse3_psign_b_128,
4794                                      SchedWriteVecALU.XMM, memopv2i64>;
4795   defm PSIGNW    : SS3I_binop_rm_int<0x09, "psignw", int_x86_ssse3_psign_w_128,
4796                                      SchedWriteVecALU.XMM, memopv2i64>;
4797   defm PSIGND    : SS3I_binop_rm_int<0x0A, "psignd", int_x86_ssse3_psign_d_128,
4798                                      SchedWriteVecALU.XMM, memopv2i64>;
4799   defm PSHUFB    : SS3I_binop_rm<0x00, "pshufb", X86pshufb, v16i8, v16i8, VR128,
4800                                  memopv2i64, i128mem, SchedWriteVarShuffle.XMM>;
4801   defm PHADDSW   : SS3I_binop_rm_int<0x03, "phaddsw",
4802                                      int_x86_ssse3_phadd_sw_128,
4803                                      SchedWritePHAdd.XMM, memopv2i64>;
4804   defm PHSUBSW   : SS3I_binop_rm_int<0x07, "phsubsw",
4805                                      int_x86_ssse3_phsub_sw_128,
4806                                      SchedWritePHAdd.XMM, memopv2i64>;
4807   defm PMADDUBSW : SS3I_binop_rm<0x04, "pmaddubsw", X86vpmaddubsw, v8i16,
4808                                  v16i8, VR128, memopv2i64, i128mem,
4809                                  SchedWriteVecIMul.XMM>;
4810 }
4811 defm PMULHRSW    : SS3I_binop_rm<0x0B, "pmulhrsw", X86mulhrs, v8i16, v8i16,
4812                                  VR128, memopv2i64, i128mem, SchedWriteVecIMul.XMM>;
4813 }
4814
4815 //===---------------------------------------------------------------------===//
4816 // SSSE3 - Packed Align Instruction Patterns
4817 //===---------------------------------------------------------------------===//
4818
4819 multiclass ssse3_palignr<string asm, ValueType VT, RegisterClass RC,
4820                          PatFrag memop_frag, X86MemOperand x86memop,
4821                          X86FoldableSchedWrite sched, bit Is2Addr = 1> {
4822   let hasSideEffects = 0 in {
4823   def rri : SS3AI<0x0F, MRMSrcReg, (outs RC:$dst),
4824       (ins RC:$src1, RC:$src2, u8imm:$src3),
4825       !if(Is2Addr,
4826         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
4827         !strconcat(asm,
4828                   "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
4829       [(set RC:$dst, (VT (X86PAlignr RC:$src1, RC:$src2, (i8 imm:$src3))))]>,
4830       Sched<[sched]>;
4831   let mayLoad = 1 in
4832   def rmi : SS3AI<0x0F, MRMSrcMem, (outs RC:$dst),
4833       (ins RC:$src1, x86memop:$src2, u8imm:$src3),
4834       !if(Is2Addr,
4835         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
4836         !strconcat(asm,
4837                   "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
4838       [(set RC:$dst, (VT (X86PAlignr RC:$src1,
4839                                      (bitconvert (memop_frag addr:$src2)),
4840                                      (i8 imm:$src3))))]>,
4841       Sched<[sched.Folded, ReadAfterLd]>;
4842   }
4843 }
4844
4845 let Predicates = [HasAVX, NoVLX_Or_NoBWI] in
4846   defm VPALIGNR : ssse3_palignr<"vpalignr", v16i8, VR128, loadv2i64, i128mem,
4847                                 SchedWriteShuffle.XMM, 0>, VEX_4V, VEX_WIG;
4848 let Predicates = [HasAVX2, NoVLX_Or_NoBWI] in
4849   defm VPALIGNRY : ssse3_palignr<"vpalignr", v32i8, VR256, loadv4i64, i256mem,
4850                                  SchedWriteShuffle.YMM, 0>, VEX_4V, VEX_L, VEX_WIG;
4851 let Constraints = "$src1 = $dst", Predicates = [UseSSSE3] in
4852   defm PALIGNR : ssse3_palignr<"palignr", v16i8, VR128, memopv2i64, i128mem,
4853                                SchedWriteShuffle.XMM>;
4854
4855 //===---------------------------------------------------------------------===//
4856 // SSSE3 - Thread synchronization
4857 //===---------------------------------------------------------------------===//
4858
4859 let SchedRW = [WriteSystem] in {
4860 let usesCustomInserter = 1 in {
4861 def MONITOR : PseudoI<(outs), (ins i32mem:$src1, GR32:$src2, GR32:$src3),
4862                 [(int_x86_sse3_monitor addr:$src1, GR32:$src2, GR32:$src3)]>,
4863                 Requires<[HasSSE3]>;
4864 }
4865
4866 let Uses = [EAX, ECX, EDX] in
4867 def MONITORrrr : I<0x01, MRM_C8, (outs), (ins), "monitor", []>,
4868                    TB, Requires<[HasSSE3]>;
4869
4870 let Uses = [ECX, EAX] in
4871 def MWAITrr   : I<0x01, MRM_C9, (outs), (ins), "mwait",
4872                   [(int_x86_sse3_mwait ECX, EAX)]>, TB, Requires<[HasSSE3]>;
4873 } // SchedRW
4874
4875 def : InstAlias<"mwait\t{%eax, %ecx|ecx, eax}", (MWAITrr)>, Requires<[Not64BitMode]>;
4876 def : InstAlias<"mwait\t{%rax, %rcx|rcx, rax}", (MWAITrr)>, Requires<[In64BitMode]>;
4877
4878 def : InstAlias<"monitor\t{%eax, %ecx, %edx|edx, ecx, eax}", (MONITORrrr)>,
4879       Requires<[Not64BitMode]>;
4880 def : InstAlias<"monitor\t{%rax, %rcx, %rdx|rdx, rcx, rax}", (MONITORrrr)>,
4881       Requires<[In64BitMode]>;
4882
4883 //===----------------------------------------------------------------------===//
4884 // SSE4.1 - Packed Move with Sign/Zero Extend
4885 //===----------------------------------------------------------------------===//
4886
4887 multiclass SS41I_pmovx_rrrm<bits<8> opc, string OpcodeStr, X86MemOperand MemOp,
4888                             RegisterClass OutRC, RegisterClass InRC,
4889                             X86FoldableSchedWrite sched> {
4890   def rr : SS48I<opc, MRMSrcReg, (outs OutRC:$dst), (ins InRC:$src),
4891                  !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"), []>,
4892                  Sched<[sched]>;
4893
4894   def rm : SS48I<opc, MRMSrcMem, (outs OutRC:$dst), (ins MemOp:$src),
4895                  !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"), []>,
4896                  Sched<[sched.Folded]>;
4897 }
4898
4899 multiclass SS41I_pmovx_rm_all<bits<8> opc, string OpcodeStr,
4900                               X86MemOperand MemOp, X86MemOperand MemYOp,
4901                               Predicate prd> {
4902   defm NAME : SS41I_pmovx_rrrm<opc, OpcodeStr, MemOp, VR128, VR128,
4903                                SchedWriteShuffle.XMM>;
4904   let Predicates = [HasAVX, prd] in
4905     defm V#NAME   : SS41I_pmovx_rrrm<opc, !strconcat("v", OpcodeStr), MemOp,
4906                                      VR128, VR128, SchedWriteShuffle.XMM>,
4907                                      VEX, VEX_WIG;
4908   let Predicates = [HasAVX2, prd] in
4909     defm V#NAME#Y : SS41I_pmovx_rrrm<opc, !strconcat("v", OpcodeStr), MemYOp,
4910                                      VR256, VR128, WriteShuffle256>,
4911                                      VEX, VEX_L, VEX_WIG;
4912 }
4913
4914 multiclass SS41I_pmovx_rm<bits<8> opc, string OpcodeStr, X86MemOperand MemOp,
4915                           X86MemOperand MemYOp, Predicate prd> {
4916   defm PMOVSX#NAME : SS41I_pmovx_rm_all<opc, !strconcat("pmovsx", OpcodeStr),
4917                                         MemOp, MemYOp, prd>;
4918   defm PMOVZX#NAME : SS41I_pmovx_rm_all<!add(opc, 0x10),
4919                                         !strconcat("pmovzx", OpcodeStr),
4920                                         MemOp, MemYOp, prd>;
4921 }
4922
4923 defm BW : SS41I_pmovx_rm<0x20, "bw", i64mem, i128mem, NoVLX_Or_NoBWI>;
4924 defm WD : SS41I_pmovx_rm<0x23, "wd", i64mem, i128mem, NoVLX>;
4925 defm DQ : SS41I_pmovx_rm<0x25, "dq", i64mem, i128mem, NoVLX>;
4926
4927 defm BD : SS41I_pmovx_rm<0x21, "bd", i32mem, i64mem, NoVLX>;
4928 defm WQ : SS41I_pmovx_rm<0x24, "wq", i32mem, i64mem, NoVLX>;
4929
4930 defm BQ : SS41I_pmovx_rm<0x22, "bq", i16mem, i32mem, NoVLX>;
4931
4932 // AVX2 Patterns
4933 multiclass SS41I_pmovx_avx2_patterns<string OpcPrefix, string ExtTy, SDNode ExtOp> {
4934   // Register-Register patterns
4935   let Predicates = [HasAVX, NoVLX_Or_NoBWI] in {
4936   def : Pat<(v16i16 (ExtOp (v16i8 VR128:$src))),
4937             (!cast<I>(OpcPrefix#BWYrr) VR128:$src)>;
4938   }
4939   let Predicates = [HasAVX, NoVLX] in {
4940   def : Pat<(v8i32 (ExtOp (v16i8 VR128:$src))),
4941             (!cast<I>(OpcPrefix#BDYrr) VR128:$src)>;
4942   def : Pat<(v4i64 (ExtOp (v16i8 VR128:$src))),
4943             (!cast<I>(OpcPrefix#BQYrr) VR128:$src)>;
4944
4945   def : Pat<(v8i32 (ExtOp (v8i16 VR128:$src))),
4946             (!cast<I>(OpcPrefix#WDYrr) VR128:$src)>;
4947   def : Pat<(v4i64 (ExtOp (v8i16 VR128:$src))),
4948             (!cast<I>(OpcPrefix#WQYrr) VR128:$src)>;
4949
4950   def : Pat<(v4i64 (ExtOp (v4i32 VR128:$src))),
4951             (!cast<I>(OpcPrefix#DQYrr) VR128:$src)>;
4952   }
4953
4954   // Simple Register-Memory patterns
4955   let Predicates = [HasAVX, NoVLX_Or_NoBWI] in {
4956   def : Pat<(v16i16 (!cast<PatFrag>(ExtTy#"extloadvi8") addr:$src)),
4957             (!cast<I>(OpcPrefix#BWYrm) addr:$src)>;
4958   }
4959   let Predicates = [HasAVX, NoVLX] in {
4960   def : Pat<(v8i32 (!cast<PatFrag>(ExtTy#"extloadvi8") addr:$src)),
4961             (!cast<I>(OpcPrefix#BDYrm) addr:$src)>;
4962   def : Pat<(v4i64 (!cast<PatFrag>(ExtTy#"extloadvi8") addr:$src)),
4963             (!cast<I>(OpcPrefix#BQYrm) addr:$src)>;
4964
4965   def : Pat<(v8i32 (!cast<PatFrag>(ExtTy#"extloadvi16") addr:$src)),
4966             (!cast<I>(OpcPrefix#WDYrm) addr:$src)>;
4967   def : Pat<(v4i64 (!cast<PatFrag>(ExtTy#"extloadvi16") addr:$src)),
4968             (!cast<I>(OpcPrefix#WQYrm) addr:$src)>;
4969
4970   def : Pat<(v4i64 (!cast<PatFrag>(ExtTy#"extloadvi32") addr:$src)),
4971             (!cast<I>(OpcPrefix#DQYrm) addr:$src)>;
4972   }
4973
4974   // AVX2 Register-Memory patterns
4975   let Predicates = [HasAVX, NoVLX_Or_NoBWI] in {
4976   def : Pat<(v16i16 (ExtOp (bc_v16i8 (loadv2i64 addr:$src)))),
4977             (!cast<I>(OpcPrefix#BWYrm) addr:$src)>;
4978   def : Pat<(v16i16 (ExtOp (v16i8 (vzmovl_v2i64 addr:$src)))),
4979             (!cast<I>(OpcPrefix#BWYrm) addr:$src)>;
4980   def : Pat<(v16i16 (ExtOp (v16i8 (vzload_v2i64 addr:$src)))),
4981             (!cast<I>(OpcPrefix#BWYrm) addr:$src)>;
4982   }
4983   let Predicates = [HasAVX, NoVLX] in {
4984   def : Pat<(v8i32 (ExtOp (bc_v16i8 (v2i64 (scalar_to_vector (loadi64 addr:$src)))))),
4985             (!cast<I>(OpcPrefix#BDYrm) addr:$src)>;
4986   def : Pat<(v8i32 (ExtOp (v16i8 (vzmovl_v2i64 addr:$src)))),
4987             (!cast<I>(OpcPrefix#BDYrm) addr:$src)>;
4988   def : Pat<(v8i32 (ExtOp (v16i8 (vzload_v2i64 addr:$src)))),
4989             (!cast<I>(OpcPrefix#BDYrm) addr:$src)>;
4990   def : Pat<(v8i32 (ExtOp (bc_v16i8 (loadv2i64 addr:$src)))),
4991             (!cast<I>(OpcPrefix#BDYrm) addr:$src)>;
4992
4993   def : Pat<(v4i64 (ExtOp (bc_v16i8 (v4i32 (scalar_to_vector (loadi32 addr:$src)))))),
4994             (!cast<I>(OpcPrefix#BQYrm) addr:$src)>;
4995   def : Pat<(v4i64 (ExtOp (v16i8 (vzmovl_v4i32 addr:$src)))),
4996             (!cast<I>(OpcPrefix#BQYrm) addr:$src)>;
4997   def : Pat<(v4i64 (ExtOp (v16i8 (vzload_v2i64 addr:$src)))),
4998             (!cast<I>(OpcPrefix#BQYrm) addr:$src)>;
4999   def : Pat<(v4i64 (ExtOp (bc_v16i8 (loadv2i64 addr:$src)))),
5000             (!cast<I>(OpcPrefix#BQYrm) addr:$src)>;
5001
5002   def : Pat<(v8i32 (ExtOp (bc_v8i16 (loadv2i64 addr:$src)))),
5003             (!cast<I>(OpcPrefix#WDYrm) addr:$src)>;
5004   def : Pat<(v8i32 (ExtOp (v8i16 (vzmovl_v2i64 addr:$src)))),
5005             (!cast<I>(OpcPrefix#WDYrm) addr:$src)>;
5006   def : Pat<(v8i32 (ExtOp (v8i16 (vzload_v2i64 addr:$src)))),
5007             (!cast<I>(OpcPrefix#WDYrm) addr:$src)>;
5008
5009   def : Pat<(v4i64 (ExtOp (bc_v8i16 (v2i64 (scalar_to_vector (loadi64 addr:$src)))))),
5010             (!cast<I>(OpcPrefix#WQYrm) addr:$src)>;
5011   def : Pat<(v4i64 (ExtOp (v8i16 (vzmovl_v2i64 addr:$src)))),
5012             (!cast<I>(OpcPrefix#WQYrm) addr:$src)>;
5013   def : Pat<(v4i64 (ExtOp (v8i16 (vzload_v2i64 addr:$src)))),
5014             (!cast<I>(OpcPrefix#WQYrm) addr:$src)>;
5015   def : Pat<(v4i64 (ExtOp (bc_v8i16 (loadv2i64 addr:$src)))),
5016             (!cast<I>(OpcPrefix#WQYrm) addr:$src)>;
5017
5018   def : Pat<(v4i64 (ExtOp (bc_v4i32 (loadv2i64 addr:$src)))),
5019             (!cast<I>(OpcPrefix#DQYrm) addr:$src)>;
5020   def : Pat<(v4i64 (ExtOp (v4i32 (vzmovl_v2i64 addr:$src)))),
5021             (!cast<I>(OpcPrefix#DQYrm) addr:$src)>;
5022   def : Pat<(v4i64 (ExtOp (v4i32 (vzload_v2i64 addr:$src)))),
5023             (!cast<I>(OpcPrefix#DQYrm) addr:$src)>;
5024   }
5025 }
5026
5027 defm : SS41I_pmovx_avx2_patterns<"VPMOVSX", "s", X86vsext>;
5028 defm : SS41I_pmovx_avx2_patterns<"VPMOVZX", "z", X86vzext>;
5029
5030 // SSE4.1/AVX patterns.
5031 multiclass SS41I_pmovx_patterns<string OpcPrefix, string ExtTy,
5032                                 SDNode ExtOp> {
5033   let Predicates = [HasAVX, NoVLX_Or_NoBWI] in {
5034   def : Pat<(v8i16 (ExtOp (v16i8 VR128:$src))),
5035             (!cast<I>(OpcPrefix#BWrr) VR128:$src)>;
5036   }
5037   let Predicates = [HasAVX, NoVLX] in {
5038   def : Pat<(v4i32 (ExtOp (v16i8 VR128:$src))),
5039             (!cast<I>(OpcPrefix#BDrr) VR128:$src)>;
5040   def : Pat<(v2i64 (ExtOp (v16i8 VR128:$src))),
5041             (!cast<I>(OpcPrefix#BQrr) VR128:$src)>;
5042
5043   def : Pat<(v4i32 (ExtOp (v8i16 VR128:$src))),
5044             (!cast<I>(OpcPrefix#WDrr) VR128:$src)>;
5045   def : Pat<(v2i64 (ExtOp (v8i16 VR128:$src))),
5046             (!cast<I>(OpcPrefix#WQrr) VR128:$src)>;
5047
5048   def : Pat<(v2i64 (ExtOp (v4i32 VR128:$src))),
5049             (!cast<I>(OpcPrefix#DQrr) VR128:$src)>;
5050   }
5051   let Predicates = [HasAVX, NoVLX_Or_NoBWI] in {
5052   def : Pat<(v8i16 (!cast<PatFrag>(ExtTy#"extloadvi8") addr:$src)),
5053             (!cast<I>(OpcPrefix#BWrm) addr:$src)>;
5054   }
5055   let Predicates = [HasAVX, NoVLX] in {
5056   def : Pat<(v4i32 (!cast<PatFrag>(ExtTy#"extloadvi8") addr:$src)),
5057             (!cast<I>(OpcPrefix#BDrm) addr:$src)>;
5058   def : Pat<(v2i64 (!cast<PatFrag>(ExtTy#"extloadvi8") addr:$src)),
5059             (!cast<I>(OpcPrefix#BQrm) addr:$src)>;
5060
5061   def : Pat<(v4i32 (!cast<PatFrag>(ExtTy#"extloadvi16") addr:$src)),
5062             (!cast<I>(OpcPrefix#WDrm) addr:$src)>;
5063   def : Pat<(v2i64 (!cast<PatFrag>(ExtTy#"extloadvi16") addr:$src)),
5064             (!cast<I>(OpcPrefix#WQrm) addr:$src)>;
5065
5066   def : Pat<(v2i64 (!cast<PatFrag>(ExtTy#"extloadvi32") addr:$src)),
5067             (!cast<I>(OpcPrefix#DQrm) addr:$src)>;
5068   }
5069   let Predicates = [HasAVX, NoVLX_Or_NoBWI] in {
5070   def : Pat<(v8i16 (ExtOp (bc_v16i8 (v2i64 (scalar_to_vector (loadi64 addr:$src)))))),
5071             (!cast<I>(OpcPrefix#BWrm) addr:$src)>;
5072   def : Pat<(v8i16 (ExtOp (bc_v16i8 (v2f64 (scalar_to_vector (loadf64 addr:$src)))))),
5073             (!cast<I>(OpcPrefix#BWrm) addr:$src)>;
5074   def : Pat<(v8i16 (ExtOp (v16i8 (vzmovl_v2i64 addr:$src)))),
5075             (!cast<I>(OpcPrefix#BWrm) addr:$src)>;
5076   def : Pat<(v8i16 (ExtOp (v16i8 (vzload_v2i64 addr:$src)))),
5077             (!cast<I>(OpcPrefix#BWrm) addr:$src)>;
5078   def : Pat<(v8i16 (ExtOp (bc_v16i8 (loadv2i64 addr:$src)))),
5079             (!cast<I>(OpcPrefix#BWrm) addr:$src)>;
5080   }
5081   let Predicates = [HasAVX, NoVLX] in {
5082   def : Pat<(v4i32 (ExtOp (bc_v16i8 (v4i32 (scalar_to_vector (loadi32 addr:$src)))))),
5083             (!cast<I>(OpcPrefix#BDrm) addr:$src)>;
5084   def : Pat<(v4i32 (ExtOp (v16i8 (vzmovl_v4i32 addr:$src)))),
5085             (!cast<I>(OpcPrefix#BDrm) addr:$src)>;
5086   def : Pat<(v4i32 (ExtOp (v16i8 (vzload_v2i64 addr:$src)))),
5087             (!cast<I>(OpcPrefix#BDrm) addr:$src)>;
5088   def : Pat<(v4i32 (ExtOp (bc_v16i8 (loadv2i64 addr:$src)))),
5089             (!cast<I>(OpcPrefix#BDrm) addr:$src)>;
5090
5091   def : Pat<(v2i64 (ExtOp (bc_v16i8 (v4i32 (scalar_to_vector (extloadi32i16 addr:$src)))))),
5092             (!cast<I>(OpcPrefix#BQrm) addr:$src)>;
5093   def : Pat<(v2i64 (ExtOp (v16i8 (vzmovl_v4i32 addr:$src)))),
5094             (!cast<I>(OpcPrefix#BQrm) addr:$src)>;
5095   def : Pat<(v2i64 (ExtOp (v16i8 (vzload_v2i64 addr:$src)))),
5096             (!cast<I>(OpcPrefix#BQrm) addr:$src)>;
5097   def : Pat<(v2i64 (ExtOp (bc_v16i8 (loadv2i64 addr:$src)))),
5098             (!cast<I>(OpcPrefix#BQrm) addr:$src)>;
5099
5100   def : Pat<(v4i32 (ExtOp (bc_v8i16 (v2i64 (scalar_to_vector (loadi64 addr:$src)))))),
5101             (!cast<I>(OpcPrefix#WDrm) addr:$src)>;
5102   def : Pat<(v4i32 (ExtOp (bc_v8i16 (v2f64 (scalar_to_vector (loadf64 addr:$src)))))),
5103             (!cast<I>(OpcPrefix#WDrm) addr:$src)>;
5104   def : Pat<(v4i32 (ExtOp (v8i16 (vzmovl_v2i64 addr:$src)))),
5105             (!cast<I>(OpcPrefix#WDrm) addr:$src)>;
5106   def : Pat<(v4i32 (ExtOp (v8i16 (vzload_v2i64 addr:$src)))),
5107             (!cast<I>(OpcPrefix#WDrm) addr:$src)>;
5108   def : Pat<(v4i32 (ExtOp (bc_v8i16 (loadv2i64 addr:$src)))),
5109             (!cast<I>(OpcPrefix#WDrm) addr:$src)>;
5110
5111   def : Pat<(v2i64 (ExtOp (bc_v8i16 (v4i32 (scalar_to_vector (loadi32 addr:$src)))))),
5112             (!cast<I>(OpcPrefix#WQrm) addr:$src)>;
5113   def : Pat<(v2i64 (ExtOp (v8i16 (vzmovl_v4i32 addr:$src)))),
5114             (!cast<I>(OpcPrefix#WQrm) addr:$src)>;
5115   def : Pat<(v2i64 (ExtOp (v8i16 (vzload_v2i64 addr:$src)))),
5116             (!cast<I>(OpcPrefix#WQrm) addr:$src)>;
5117   def : Pat<(v2i64 (ExtOp (bc_v8i16 (loadv2i64 addr:$src)))),
5118             (!cast<I>(OpcPrefix#WQrm) addr:$src)>;
5119
5120   def : Pat<(v2i64 (ExtOp (bc_v4i32 (v2i64 (scalar_to_vector (loadi64 addr:$src)))))),
5121             (!cast<I>(OpcPrefix#DQrm) addr:$src)>;
5122   def : Pat<(v2i64 (ExtOp (bc_v4i32 (v2f64 (scalar_to_vector (loadf64 addr:$src)))))),
5123             (!cast<I>(OpcPrefix#DQrm) addr:$src)>;
5124   def : Pat<(v2i64 (ExtOp (v4i32 (vzmovl_v2i64 addr:$src)))),
5125             (!cast<I>(OpcPrefix#DQrm) addr:$src)>;
5126   def : Pat<(v2i64 (ExtOp (v4i32 (vzload_v2i64 addr:$src)))),
5127             (!cast<I>(OpcPrefix#DQrm) addr:$src)>;
5128   def : Pat<(v2i64 (ExtOp (bc_v4i32 (loadv2i64 addr:$src)))),
5129             (!cast<I>(OpcPrefix#DQrm) addr:$src)>;
5130   }
5131 }
5132
5133 defm : SS41I_pmovx_patterns<"VPMOVSX", "s", sext_invec>;
5134 defm : SS41I_pmovx_patterns<"VPMOVZX", "z", zext_invec>;
5135
5136 let Predicates = [UseSSE41] in {
5137   defm : SS41I_pmovx_patterns<"PMOVSX", "s", sext_invec>;
5138   defm : SS41I_pmovx_patterns<"PMOVZX", "z", zext_invec>;
5139 }
5140
5141 //===----------------------------------------------------------------------===//
5142 // SSE4.1 - Extract Instructions
5143 //===----------------------------------------------------------------------===//
5144
5145 /// SS41I_binop_ext8 - SSE 4.1 extract 8 bits to 32 bit reg or 8 bit mem
5146 multiclass SS41I_extract8<bits<8> opc, string OpcodeStr> {
5147   def rr : SS4AIi8<opc, MRMDestReg, (outs GR32orGR64:$dst),
5148                  (ins VR128:$src1, u8imm:$src2),
5149                  !strconcat(OpcodeStr,
5150                             "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5151                  [(set GR32orGR64:$dst, (X86pextrb (v16i8 VR128:$src1),
5152                                          imm:$src2))]>,
5153                   Sched<[WriteVecExtract]>;
5154   let hasSideEffects = 0, mayStore = 1 in
5155   def mr : SS4AIi8<opc, MRMDestMem, (outs),
5156                  (ins i8mem:$dst, VR128:$src1, u8imm:$src2),
5157                  !strconcat(OpcodeStr,
5158                             "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5159                  [(store (i8 (trunc (X86pextrb (v16i8 VR128:$src1), imm:$src2))),
5160                           addr:$dst)]>, Sched<[WriteVecExtractSt]>;
5161 }
5162
5163 let Predicates = [HasAVX, NoBWI] in
5164   defm VPEXTRB : SS41I_extract8<0x14, "vpextrb">, VEX;
5165
5166 defm PEXTRB      : SS41I_extract8<0x14, "pextrb">;
5167
5168
5169 /// SS41I_extract16 - SSE 4.1 extract 16 bits to memory destination
5170 multiclass SS41I_extract16<bits<8> opc, string OpcodeStr> {
5171   let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0 in
5172   def rr_REV : SS4AIi8<opc, MRMDestReg, (outs GR32orGR64:$dst),
5173                    (ins VR128:$src1, u8imm:$src2),
5174                    !strconcat(OpcodeStr,
5175                    "\t{$src2, $src1, $dst|$dst, $src1, $src2}"), []>,
5176                    Sched<[WriteVecExtract]>, FoldGenData<NAME#rr>;
5177
5178   let hasSideEffects = 0, mayStore = 1 in
5179   def mr : SS4AIi8<opc, MRMDestMem, (outs),
5180                  (ins i16mem:$dst, VR128:$src1, u8imm:$src2),
5181                  !strconcat(OpcodeStr,
5182                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5183                  [(store (i16 (trunc (X86pextrw (v8i16 VR128:$src1), imm:$src2))),
5184                           addr:$dst)]>, Sched<[WriteVecExtractSt]>;
5185 }
5186
5187 let Predicates = [HasAVX, NoBWI] in
5188   defm VPEXTRW : SS41I_extract16<0x15, "vpextrw">, VEX;
5189
5190 defm PEXTRW      : SS41I_extract16<0x15, "pextrw">;
5191
5192
5193 /// SS41I_extract32 - SSE 4.1 extract 32 bits to int reg or memory destination
5194 multiclass SS41I_extract32<bits<8> opc, string OpcodeStr> {
5195   def rr : SS4AIi8<opc, MRMDestReg, (outs GR32:$dst),
5196                  (ins VR128:$src1, u8imm:$src2),
5197                  !strconcat(OpcodeStr,
5198                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5199                  [(set GR32:$dst,
5200                   (extractelt (v4i32 VR128:$src1), imm:$src2))]>,
5201                   Sched<[WriteVecExtract]>;
5202   def mr : SS4AIi8<opc, MRMDestMem, (outs),
5203                  (ins i32mem:$dst, VR128:$src1, u8imm:$src2),
5204                  !strconcat(OpcodeStr,
5205                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5206                  [(store (extractelt (v4i32 VR128:$src1), imm:$src2),
5207                           addr:$dst)]>, Sched<[WriteVecExtractSt]>;
5208 }
5209
5210 let Predicates = [HasAVX, NoDQI] in
5211   defm VPEXTRD : SS41I_extract32<0x16, "vpextrd">, VEX;
5212
5213 defm PEXTRD      : SS41I_extract32<0x16, "pextrd">;
5214
5215 /// SS41I_extract32 - SSE 4.1 extract 32 bits to int reg or memory destination
5216 multiclass SS41I_extract64<bits<8> opc, string OpcodeStr> {
5217   def rr : SS4AIi8<opc, MRMDestReg, (outs GR64:$dst),
5218                  (ins VR128:$src1, u8imm:$src2),
5219                  !strconcat(OpcodeStr,
5220                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5221                  [(set GR64:$dst,
5222                   (extractelt (v2i64 VR128:$src1), imm:$src2))]>,
5223                   Sched<[WriteVecExtract]>;
5224   def mr : SS4AIi8<opc, MRMDestMem, (outs),
5225                  (ins i64mem:$dst, VR128:$src1, u8imm:$src2),
5226                  !strconcat(OpcodeStr,
5227                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5228                  [(store (extractelt (v2i64 VR128:$src1), imm:$src2),
5229                           addr:$dst)]>, Sched<[WriteVecExtractSt]>;
5230 }
5231
5232 let Predicates = [HasAVX, NoDQI] in
5233   defm VPEXTRQ : SS41I_extract64<0x16, "vpextrq">, VEX, VEX_W;
5234
5235 defm PEXTRQ      : SS41I_extract64<0x16, "pextrq">, REX_W;
5236
5237 /// SS41I_extractf32 - SSE 4.1 extract 32 bits fp value to int reg or memory
5238 /// destination
5239 multiclass SS41I_extractf32<bits<8> opc, string OpcodeStr> {
5240   def rr : SS4AIi8<opc, MRMDestReg, (outs GR32orGR64:$dst),
5241                    (ins VR128:$src1, u8imm:$src2),
5242                    !strconcat(OpcodeStr,
5243                     "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5244                    [(set GR32orGR64:$dst,
5245                       (extractelt (bc_v4i32 (v4f32 VR128:$src1)), imm:$src2))]>,
5246                    Sched<[WriteVecExtract]>;
5247   def mr : SS4AIi8<opc, MRMDestMem, (outs),
5248                    (ins f32mem:$dst, VR128:$src1, u8imm:$src2),
5249                    !strconcat(OpcodeStr,
5250                     "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5251                    [(store (extractelt (bc_v4i32 (v4f32 VR128:$src1)), imm:$src2),
5252                             addr:$dst)]>, Sched<[WriteVecExtractSt]>;
5253 }
5254
5255 let ExeDomain = SSEPackedSingle in {
5256   let Predicates = [UseAVX] in
5257     defm VEXTRACTPS : SS41I_extractf32<0x17, "vextractps">, VEX, VEX_WIG;
5258   defm EXTRACTPS   : SS41I_extractf32<0x17, "extractps">;
5259 }
5260
5261 // Also match an EXTRACTPS store when the store is done as f32 instead of i32.
5262 def : Pat<(store (f32 (bitconvert (extractelt (bc_v4i32 (v4f32 VR128:$src1)),
5263                                               imm:$src2))),
5264                  addr:$dst),
5265           (VEXTRACTPSmr addr:$dst, VR128:$src1, imm:$src2)>,
5266           Requires<[HasAVX]>;
5267 def : Pat<(store (f32 (bitconvert (extractelt (bc_v4i32 (v4f32 VR128:$src1)),
5268                                               imm:$src2))),
5269                  addr:$dst),
5270           (EXTRACTPSmr addr:$dst, VR128:$src1, imm:$src2)>,
5271           Requires<[UseSSE41]>;
5272
5273 //===----------------------------------------------------------------------===//
5274 // SSE4.1 - Insert Instructions
5275 //===----------------------------------------------------------------------===//
5276
5277 multiclass SS41I_insert8<bits<8> opc, string asm, bit Is2Addr = 1> {
5278   def rr : SS4AIi8<opc, MRMSrcReg, (outs VR128:$dst),
5279       (ins VR128:$src1, GR32orGR64:$src2, u8imm:$src3),
5280       !if(Is2Addr,
5281         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5282         !strconcat(asm,
5283                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5284       [(set VR128:$dst,
5285         (X86pinsrb VR128:$src1, GR32orGR64:$src2, imm:$src3))]>,
5286       Sched<[WriteVecInsert]>;
5287   def rm : SS4AIi8<opc, MRMSrcMem, (outs VR128:$dst),
5288       (ins VR128:$src1, i8mem:$src2, u8imm:$src3),
5289       !if(Is2Addr,
5290         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5291         !strconcat(asm,
5292                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5293       [(set VR128:$dst,
5294         (X86pinsrb VR128:$src1, (extloadi8 addr:$src2),
5295                    imm:$src3))]>, Sched<[WriteVecInsertLd, ReadAfterLd]>;
5296 }
5297
5298 let Predicates = [HasAVX, NoBWI] in
5299   defm VPINSRB : SS41I_insert8<0x20, "vpinsrb", 0>, VEX_4V;
5300 let Constraints = "$src1 = $dst" in
5301   defm PINSRB  : SS41I_insert8<0x20, "pinsrb">;
5302
5303 multiclass SS41I_insert32<bits<8> opc, string asm, bit Is2Addr = 1> {
5304   def rr : SS4AIi8<opc, MRMSrcReg, (outs VR128:$dst),
5305       (ins VR128:$src1, GR32:$src2, u8imm:$src3),
5306       !if(Is2Addr,
5307         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5308         !strconcat(asm,
5309                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5310       [(set VR128:$dst,
5311         (v4i32 (insertelt VR128:$src1, GR32:$src2, imm:$src3)))]>,
5312       Sched<[WriteVecInsert]>;
5313   def rm : SS4AIi8<opc, MRMSrcMem, (outs VR128:$dst),
5314       (ins VR128:$src1, i32mem:$src2, u8imm:$src3),
5315       !if(Is2Addr,
5316         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5317         !strconcat(asm,
5318                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5319       [(set VR128:$dst,
5320         (v4i32 (insertelt VR128:$src1, (loadi32 addr:$src2),
5321                           imm:$src3)))]>, Sched<[WriteVecInsertLd, ReadAfterLd]>;
5322 }
5323
5324 let Predicates = [HasAVX, NoDQI] in
5325   defm VPINSRD : SS41I_insert32<0x22, "vpinsrd", 0>, VEX_4V;
5326 let Constraints = "$src1 = $dst" in
5327   defm PINSRD : SS41I_insert32<0x22, "pinsrd">;
5328
5329 multiclass SS41I_insert64<bits<8> opc, string asm, bit Is2Addr = 1> {
5330   def rr : SS4AIi8<opc, MRMSrcReg, (outs VR128:$dst),
5331       (ins VR128:$src1, GR64:$src2, u8imm:$src3),
5332       !if(Is2Addr,
5333         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5334         !strconcat(asm,
5335                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5336       [(set VR128:$dst,
5337         (v2i64 (insertelt VR128:$src1, GR64:$src2, imm:$src3)))]>,
5338       Sched<[WriteVecInsert]>;
5339   def rm : SS4AIi8<opc, MRMSrcMem, (outs VR128:$dst),
5340       (ins VR128:$src1, i64mem:$src2, u8imm:$src3),
5341       !if(Is2Addr,
5342         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5343         !strconcat(asm,
5344                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5345       [(set VR128:$dst,
5346         (v2i64 (insertelt VR128:$src1, (loadi64 addr:$src2),
5347                           imm:$src3)))]>, Sched<[WriteVecInsertLd, ReadAfterLd]>;
5348 }
5349
5350 let Predicates = [HasAVX, NoDQI] in
5351   defm VPINSRQ : SS41I_insert64<0x22, "vpinsrq", 0>, VEX_4V, VEX_W;
5352 let Constraints = "$src1 = $dst" in
5353   defm PINSRQ : SS41I_insert64<0x22, "pinsrq">, REX_W;
5354
5355 // insertps has a few different modes, there's the first two here below which
5356 // are optimized inserts that won't zero arbitrary elements in the destination
5357 // vector. The next one matches the intrinsic and could zero arbitrary elements
5358 // in the target vector.
5359 multiclass SS41I_insertf32<bits<8> opc, string asm, bit Is2Addr = 1> {
5360   def rr : SS4AIi8<opc, MRMSrcReg, (outs VR128:$dst),
5361       (ins VR128:$src1, VR128:$src2, u8imm:$src3),
5362       !if(Is2Addr,
5363         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5364         !strconcat(asm,
5365                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5366       [(set VR128:$dst,
5367         (X86insertps VR128:$src1, VR128:$src2, imm:$src3))]>,
5368       Sched<[SchedWriteFShuffle.XMM]>;
5369   def rm : SS4AIi8<opc, MRMSrcMem, (outs VR128:$dst),
5370       (ins VR128:$src1, f32mem:$src2, u8imm:$src3),
5371       !if(Is2Addr,
5372         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5373         !strconcat(asm,
5374                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5375       [(set VR128:$dst,
5376         (X86insertps VR128:$src1,
5377                    (v4f32 (scalar_to_vector (loadf32 addr:$src2))),
5378                     imm:$src3))]>,
5379       Sched<[SchedWriteFShuffle.XMM.Folded, ReadAfterLd]>;
5380 }
5381
5382 let ExeDomain = SSEPackedSingle in {
5383   let Predicates = [UseAVX] in
5384     defm VINSERTPS : SS41I_insertf32<0x21, "vinsertps", 0>,
5385                      VEX_4V, VEX_WIG;
5386   let Constraints = "$src1 = $dst" in
5387     defm INSERTPS : SS41I_insertf32<0x21, "insertps", 1>;
5388 }
5389
5390 let Predicates = [UseAVX] in {
5391   // If we're inserting an element from a vbroadcast of a load, fold the
5392   // load into the X86insertps instruction.
5393   def : Pat<(v4f32 (X86insertps (v4f32 VR128:$src1),
5394                 (X86VBroadcast (loadf32 addr:$src2)), imm:$src3)),
5395             (VINSERTPSrm VR128:$src1, addr:$src2, imm:$src3)>;
5396   def : Pat<(v4f32 (X86insertps (v4f32 VR128:$src1),
5397                 (X86VBroadcast (loadv4f32 addr:$src2)), imm:$src3)),
5398             (VINSERTPSrm VR128:$src1, addr:$src2, imm:$src3)>;
5399 }
5400
5401 //===----------------------------------------------------------------------===//
5402 // SSE4.1 - Round Instructions
5403 //===----------------------------------------------------------------------===//
5404
5405 multiclass sse41_fp_unop_p<bits<8> opc, string OpcodeStr,
5406                            X86MemOperand x86memop, RegisterClass RC,
5407                            ValueType VT, PatFrag mem_frag, SDNode OpNode,
5408                            X86FoldableSchedWrite sched> {
5409   // Intrinsic operation, reg.
5410   // Vector intrinsic operation, reg
5411   def r : SS4AIi8<opc, MRMSrcReg,
5412                   (outs RC:$dst), (ins RC:$src1, i32u8imm:$src2),
5413                   !strconcat(OpcodeStr,
5414                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5415                   [(set RC:$dst, (VT (OpNode RC:$src1, imm:$src2)))]>,
5416                   Sched<[sched]>;
5417
5418   // Vector intrinsic operation, mem
5419   def m : SS4AIi8<opc, MRMSrcMem,
5420                   (outs RC:$dst), (ins x86memop:$src1, i32u8imm:$src2),
5421                   !strconcat(OpcodeStr,
5422                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5423                   [(set RC:$dst,
5424                         (VT (OpNode (mem_frag addr:$src1),imm:$src2)))]>,
5425                   Sched<[sched.Folded]>;
5426 }
5427
5428 multiclass avx_fp_unop_rm<bits<8> opcss, bits<8> opcsd,
5429                           string OpcodeStr, X86FoldableSchedWrite sched> {
5430 let ExeDomain = SSEPackedSingle, hasSideEffects = 0 in {
5431   def SSr : SS4AIi8<opcss, MRMSrcReg,
5432         (outs FR32:$dst), (ins FR32:$src1, FR32:$src2, i32u8imm:$src3),
5433         !strconcat(OpcodeStr,
5434             "ss\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
5435       []>, Sched<[sched]>;
5436
5437   let mayLoad = 1 in
5438   def SSm : SS4AIi8<opcss, MRMSrcMem,
5439         (outs FR32:$dst), (ins FR32:$src1, f32mem:$src2, i32u8imm:$src3),
5440         !strconcat(OpcodeStr,
5441              "ss\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
5442         []>, Sched<[sched.Folded, ReadAfterLd]>;
5443 } // ExeDomain = SSEPackedSingle, hasSideEffects = 0
5444
5445 let ExeDomain = SSEPackedDouble, hasSideEffects = 0 in {
5446   def SDr : SS4AIi8<opcsd, MRMSrcReg,
5447         (outs FR64:$dst), (ins FR64:$src1, FR64:$src2, i32u8imm:$src3),
5448         !strconcat(OpcodeStr,
5449               "sd\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
5450         []>, Sched<[sched]>;
5451
5452   let mayLoad = 1 in
5453   def SDm : SS4AIi8<opcsd, MRMSrcMem,
5454         (outs FR64:$dst), (ins FR64:$src1, f64mem:$src2, i32u8imm:$src3),
5455         !strconcat(OpcodeStr,
5456              "sd\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
5457         []>, Sched<[sched.Folded, ReadAfterLd]>;
5458 } // ExeDomain = SSEPackedDouble, hasSideEffects = 0
5459 }
5460
5461 multiclass sse41_fp_unop_s<bits<8> opcss, bits<8> opcsd,
5462                            string OpcodeStr, X86FoldableSchedWrite sched> {
5463 let ExeDomain = SSEPackedSingle, hasSideEffects = 0 in {
5464   def SSr : SS4AIi8<opcss, MRMSrcReg,
5465                     (outs FR32:$dst), (ins FR32:$src1, i32u8imm:$src2),
5466                     !strconcat(OpcodeStr,
5467                                "ss\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5468                     []>, Sched<[sched]>;
5469
5470   let mayLoad = 1 in
5471   def SSm : SS4AIi8<opcss, MRMSrcMem,
5472                     (outs FR32:$dst), (ins f32mem:$src1, i32u8imm:$src2),
5473                     !strconcat(OpcodeStr,
5474                                "ss\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5475                     []>, Sched<[sched.Folded, ReadAfterLd]>;
5476 } // ExeDomain = SSEPackedSingle, hasSideEffects = 0
5477
5478 let ExeDomain = SSEPackedDouble, hasSideEffects = 0 in {
5479   def SDr : SS4AIi8<opcsd, MRMSrcReg,
5480                     (outs FR64:$dst), (ins FR64:$src1, i32u8imm:$src2),
5481                     !strconcat(OpcodeStr,
5482                                "sd\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5483                     []>, Sched<[sched]>;
5484
5485   let mayLoad = 1 in
5486   def SDm : SS4AIi8<opcsd, MRMSrcMem,
5487                     (outs FR64:$dst), (ins f64mem:$src1, i32u8imm:$src2),
5488                     !strconcat(OpcodeStr,
5489                                "sd\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5490                     []>, Sched<[sched.Folded, ReadAfterLd]>;
5491 } // ExeDomain = SSEPackedDouble, hasSideEffects = 0
5492 }
5493
5494 multiclass sse41_fp_binop_s<bits<8> opcss, bits<8> opcsd,
5495                             string OpcodeStr, X86FoldableSchedWrite sched,
5496                             ValueType VT32, ValueType VT64,
5497                             SDNode OpNode, bit Is2Addr = 1> {
5498 let ExeDomain = SSEPackedSingle, isCodeGenOnly = 1 in {
5499   def SSr_Int : SS4AIi8<opcss, MRMSrcReg,
5500         (outs VR128:$dst), (ins VR128:$src1, VR128:$src2, i32u8imm:$src3),
5501         !if(Is2Addr,
5502             !strconcat(OpcodeStr,
5503                 "ss\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5504             !strconcat(OpcodeStr,
5505                 "ss\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5506         [(set VR128:$dst, (VT32 (OpNode VR128:$src1, VR128:$src2, imm:$src3)))]>,
5507         Sched<[sched]>;
5508
5509   def SSm_Int : SS4AIi8<opcss, MRMSrcMem,
5510         (outs VR128:$dst), (ins VR128:$src1, ssmem:$src2, i32u8imm:$src3),
5511         !if(Is2Addr,
5512             !strconcat(OpcodeStr,
5513                 "ss\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5514             !strconcat(OpcodeStr,
5515                 "ss\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5516         [(set VR128:$dst,
5517              (OpNode VR128:$src1, sse_load_f32:$src2, imm:$src3))]>,
5518         Sched<[sched.Folded, ReadAfterLd]>;
5519 } // ExeDomain = SSEPackedSingle, isCodeGenOnly = 1
5520
5521 let ExeDomain = SSEPackedDouble, isCodeGenOnly = 1 in {
5522   def SDr_Int : SS4AIi8<opcsd, MRMSrcReg,
5523         (outs VR128:$dst), (ins VR128:$src1, VR128:$src2, i32u8imm:$src3),
5524         !if(Is2Addr,
5525             !strconcat(OpcodeStr,
5526                 "sd\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5527             !strconcat(OpcodeStr,
5528                 "sd\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5529         [(set VR128:$dst, (VT64 (OpNode VR128:$src1, VR128:$src2, imm:$src3)))]>,
5530         Sched<[sched]>;
5531
5532   def SDm_Int : SS4AIi8<opcsd, MRMSrcMem,
5533         (outs VR128:$dst), (ins VR128:$src1, sdmem:$src2, i32u8imm:$src3),
5534         !if(Is2Addr,
5535             !strconcat(OpcodeStr,
5536                 "sd\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5537             !strconcat(OpcodeStr,
5538                 "sd\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5539         [(set VR128:$dst,
5540               (OpNode VR128:$src1, sse_load_f64:$src2, imm:$src3))]>,
5541         Sched<[sched.Folded, ReadAfterLd]>;
5542 } // ExeDomain = SSEPackedDouble, isCodeGenOnly = 1
5543 }
5544
5545 // FP round - roundss, roundps, roundsd, roundpd
5546 let Predicates = [HasAVX, NoVLX] in {
5547   let ExeDomain = SSEPackedSingle in {
5548     // Intrinsic form
5549     defm VROUNDPS  : sse41_fp_unop_p<0x08, "vroundps", f128mem, VR128, v4f32,
5550                                      loadv4f32, X86VRndScale, SchedWriteFRnd.XMM>,
5551                                    VEX, VEX_WIG;
5552     defm VROUNDPSY : sse41_fp_unop_p<0x08, "vroundps", f256mem, VR256, v8f32,
5553                                      loadv8f32, X86VRndScale, SchedWriteFRnd.YMM>,
5554                                    VEX, VEX_L, VEX_WIG;
5555   }
5556
5557   let ExeDomain = SSEPackedDouble in {
5558     defm VROUNDPD  : sse41_fp_unop_p<0x09, "vroundpd", f128mem, VR128, v2f64,
5559                                      loadv2f64, X86VRndScale, SchedWriteFRnd.XMM>,
5560                                    VEX, VEX_WIG;
5561     defm VROUNDPDY : sse41_fp_unop_p<0x09, "vroundpd", f256mem, VR256, v4f64,
5562                                      loadv4f64, X86VRndScale, SchedWriteFRnd.YMM>,
5563                                    VEX, VEX_L, VEX_WIG;
5564   }
5565 }
5566 let Predicates = [HasAVX, NoAVX512] in {
5567   defm VROUND  : sse41_fp_binop_s<0x0A, 0x0B, "vround", SchedWriteFRnd.Scl,
5568                                   v4f32, v2f64, X86RndScales, 0>,
5569                                   VEX_4V, VEX_LIG, VEX_WIG;
5570   defm VROUND  : avx_fp_unop_rm<0x0A, 0x0B, "vround", SchedWriteFRnd.Scl>,
5571                                 VEX_4V, VEX_LIG, VEX_WIG;
5572 }
5573
5574 let Predicates = [UseAVX] in {
5575   def : Pat<(ffloor FR32:$src),
5576             (VROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x9))>;
5577   def : Pat<(f32 (fnearbyint FR32:$src)),
5578             (VROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0xC))>;
5579   def : Pat<(f32 (fceil FR32:$src)),
5580             (VROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0xA))>;
5581   def : Pat<(f32 (frint FR32:$src)),
5582             (VROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x4))>;
5583   def : Pat<(f32 (ftrunc FR32:$src)),
5584             (VROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0xB))>;
5585
5586   def : Pat<(f64 (ffloor FR64:$src)),
5587             (VROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x9))>;
5588   def : Pat<(f64 (fnearbyint FR64:$src)),
5589             (VROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0xC))>;
5590   def : Pat<(f64 (fceil FR64:$src)),
5591             (VROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0xA))>;
5592   def : Pat<(f64 (frint FR64:$src)),
5593             (VROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x4))>;
5594   def : Pat<(f64 (ftrunc FR64:$src)),
5595             (VROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0xB))>;
5596 }
5597
5598 let Predicates = [UseAVX, OptForSize] in {
5599   def : Pat<(ffloor (loadf32 addr:$src)),
5600             (VROUNDSSm (f32 (IMPLICIT_DEF)), addr:$src, (i32 0x9))>;
5601   def : Pat<(f32 (fnearbyint (loadf32 addr:$src))),
5602             (VROUNDSSm (f32 (IMPLICIT_DEF)), addr:$src, (i32 0xC))>;
5603   def : Pat<(f32 (fceil (loadf32 addr:$src))),
5604             (VROUNDSSm (f32 (IMPLICIT_DEF)), addr:$src, (i32 0xA))>;
5605   def : Pat<(f32 (frint (loadf32 addr:$src))),
5606             (VROUNDSSm (f32 (IMPLICIT_DEF)), addr:$src, (i32 0x4))>;
5607   def : Pat<(f32 (ftrunc (loadf32 addr:$src))),
5608             (VROUNDSSm (f32 (IMPLICIT_DEF)), addr:$src, (i32 0xB))>;
5609
5610   def : Pat<(f64 (ffloor (loadf64 addr:$src))),
5611             (VROUNDSDm (f64 (IMPLICIT_DEF)), addr:$src, (i32 0x9))>;
5612   def : Pat<(f64 (fnearbyint (loadf64 addr:$src))),
5613             (VROUNDSDm (f64 (IMPLICIT_DEF)), addr:$src, (i32 0xC))>;
5614   def : Pat<(f64 (fceil (loadf64 addr:$src))),
5615             (VROUNDSDm (f64 (IMPLICIT_DEF)), addr:$src, (i32 0xA))>;
5616   def : Pat<(f64 (frint (loadf64 addr:$src))),
5617             (VROUNDSDm (f64 (IMPLICIT_DEF)), addr:$src, (i32 0x4))>;
5618   def : Pat<(f64 (ftrunc (loadf64 addr:$src))),
5619             (VROUNDSDm (f64 (IMPLICIT_DEF)), addr:$src, (i32 0xB))>;
5620 }
5621
5622 let Predicates = [HasAVX, NoVLX] in {
5623   def : Pat<(v4f32 (ffloor VR128:$src)),
5624             (VROUNDPSr VR128:$src, (i32 0x9))>;
5625   def : Pat<(v4f32 (fnearbyint VR128:$src)),
5626             (VROUNDPSr VR128:$src, (i32 0xC))>;
5627   def : Pat<(v4f32 (fceil VR128:$src)),
5628             (VROUNDPSr VR128:$src, (i32 0xA))>;
5629   def : Pat<(v4f32 (frint VR128:$src)),
5630             (VROUNDPSr VR128:$src, (i32 0x4))>;
5631   def : Pat<(v4f32 (ftrunc VR128:$src)),
5632             (VROUNDPSr VR128:$src, (i32 0xB))>;
5633
5634   def : Pat<(v4f32 (ffloor (loadv4f32 addr:$src))),
5635             (VROUNDPSm addr:$src, (i32 0x9))>;
5636   def : Pat<(v4f32 (fnearbyint (loadv4f32 addr:$src))),
5637             (VROUNDPSm addr:$src, (i32 0xC))>;
5638   def : Pat<(v4f32 (fceil (loadv4f32 addr:$src))),
5639             (VROUNDPSm addr:$src, (i32 0xA))>;
5640   def : Pat<(v4f32 (frint (loadv4f32 addr:$src))),
5641             (VROUNDPSm addr:$src, (i32 0x4))>;
5642   def : Pat<(v4f32 (ftrunc (loadv4f32 addr:$src))),
5643             (VROUNDPSm addr:$src, (i32 0xB))>;
5644
5645   def : Pat<(v2f64 (ffloor VR128:$src)),
5646             (VROUNDPDr VR128:$src, (i32 0x9))>;
5647   def : Pat<(v2f64 (fnearbyint VR128:$src)),
5648             (VROUNDPDr VR128:$src, (i32 0xC))>;
5649   def : Pat<(v2f64 (fceil VR128:$src)),
5650             (VROUNDPDr VR128:$src, (i32 0xA))>;
5651   def : Pat<(v2f64 (frint VR128:$src)),
5652             (VROUNDPDr VR128:$src, (i32 0x4))>;
5653   def : Pat<(v2f64 (ftrunc VR128:$src)),
5654             (VROUNDPDr VR128:$src, (i32 0xB))>;
5655
5656   def : Pat<(v2f64 (ffloor (loadv2f64 addr:$src))),
5657             (VROUNDPDm addr:$src, (i32 0x9))>;
5658   def : Pat<(v2f64 (fnearbyint (loadv2f64 addr:$src))),
5659             (VROUNDPDm addr:$src, (i32 0xC))>;
5660   def : Pat<(v2f64 (fceil (loadv2f64 addr:$src))),
5661             (VROUNDPDm addr:$src, (i32 0xA))>;
5662   def : Pat<(v2f64 (frint (loadv2f64 addr:$src))),
5663             (VROUNDPDm addr:$src, (i32 0x4))>;
5664   def : Pat<(v2f64 (ftrunc (loadv2f64 addr:$src))),
5665             (VROUNDPDm addr:$src, (i32 0xB))>;
5666
5667   def : Pat<(v8f32 (ffloor VR256:$src)),
5668             (VROUNDPSYr VR256:$src, (i32 0x9))>;
5669   def : Pat<(v8f32 (fnearbyint VR256:$src)),
5670             (VROUNDPSYr VR256:$src, (i32 0xC))>;
5671   def : Pat<(v8f32 (fceil VR256:$src)),
5672             (VROUNDPSYr VR256:$src, (i32 0xA))>;
5673   def : Pat<(v8f32 (frint VR256:$src)),
5674             (VROUNDPSYr VR256:$src, (i32 0x4))>;
5675   def : Pat<(v8f32 (ftrunc VR256:$src)),
5676             (VROUNDPSYr VR256:$src, (i32 0xB))>;
5677
5678   def : Pat<(v8f32 (ffloor (loadv8f32 addr:$src))),
5679             (VROUNDPSYm addr:$src, (i32 0x9))>;
5680   def : Pat<(v8f32 (fnearbyint (loadv8f32 addr:$src))),
5681             (VROUNDPSYm addr:$src, (i32 0xC))>;
5682   def : Pat<(v8f32 (fceil (loadv8f32 addr:$src))),
5683             (VROUNDPSYm addr:$src, (i32 0xA))>;
5684   def : Pat<(v8f32 (frint (loadv8f32 addr:$src))),
5685             (VROUNDPSYm addr:$src, (i32 0x4))>;
5686   def : Pat<(v8f32 (ftrunc (loadv8f32 addr:$src))),
5687             (VROUNDPSYm addr:$src, (i32 0xB))>;
5688
5689   def : Pat<(v4f64 (ffloor VR256:$src)),
5690             (VROUNDPDYr VR256:$src, (i32 0x9))>;
5691   def : Pat<(v4f64 (fnearbyint VR256:$src)),
5692             (VROUNDPDYr VR256:$src, (i32 0xC))>;
5693   def : Pat<(v4f64 (fceil VR256:$src)),
5694             (VROUNDPDYr VR256:$src, (i32 0xA))>;
5695   def : Pat<(v4f64 (frint VR256:$src)),
5696             (VROUNDPDYr VR256:$src, (i32 0x4))>;
5697   def : Pat<(v4f64 (ftrunc VR256:$src)),
5698             (VROUNDPDYr VR256:$src, (i32 0xB))>;
5699
5700   def : Pat<(v4f64 (ffloor (loadv4f64 addr:$src))),
5701             (VROUNDPDYm addr:$src, (i32 0x9))>;
5702   def : Pat<(v4f64 (fnearbyint (loadv4f64 addr:$src))),
5703             (VROUNDPDYm addr:$src, (i32 0xC))>;
5704   def : Pat<(v4f64 (fceil (loadv4f64 addr:$src))),
5705             (VROUNDPDYm addr:$src, (i32 0xA))>;
5706   def : Pat<(v4f64 (frint (loadv4f64 addr:$src))),
5707             (VROUNDPDYm addr:$src, (i32 0x4))>;
5708   def : Pat<(v4f64 (ftrunc (loadv4f64 addr:$src))),
5709             (VROUNDPDYm addr:$src, (i32 0xB))>;
5710 }
5711
5712 let ExeDomain = SSEPackedSingle in
5713 defm ROUNDPS  : sse41_fp_unop_p<0x08, "roundps", f128mem, VR128, v4f32,
5714                                 memopv4f32, X86VRndScale, SchedWriteFRnd.XMM>;
5715 let ExeDomain = SSEPackedDouble in
5716 defm ROUNDPD  : sse41_fp_unop_p<0x09, "roundpd", f128mem, VR128, v2f64,
5717                                 memopv2f64, X86VRndScale, SchedWriteFRnd.XMM>;
5718
5719 defm ROUND  : sse41_fp_unop_s<0x0A, 0x0B, "round", SchedWriteFRnd.Scl>;
5720
5721 let Constraints = "$src1 = $dst" in
5722 defm ROUND  : sse41_fp_binop_s<0x0A, 0x0B, "round", SchedWriteFRnd.Scl,
5723                                v4f32, v2f64, X86RndScales>;
5724
5725 let Predicates = [UseSSE41] in {
5726   def : Pat<(ffloor FR32:$src),
5727             (ROUNDSSr FR32:$src, (i32 0x9))>;
5728   def : Pat<(f32 (fnearbyint FR32:$src)),
5729             (ROUNDSSr FR32:$src, (i32 0xC))>;
5730   def : Pat<(f32 (fceil FR32:$src)),
5731             (ROUNDSSr FR32:$src, (i32 0xA))>;
5732   def : Pat<(f32 (frint FR32:$src)),
5733             (ROUNDSSr FR32:$src, (i32 0x4))>;
5734   def : Pat<(f32 (ftrunc FR32:$src)),
5735             (ROUNDSSr FR32:$src, (i32 0xB))>;
5736
5737   def : Pat<(f64 (ffloor FR64:$src)),
5738             (ROUNDSDr FR64:$src, (i32 0x9))>;
5739   def : Pat<(f64 (fnearbyint FR64:$src)),
5740             (ROUNDSDr FR64:$src, (i32 0xC))>;
5741   def : Pat<(f64 (fceil FR64:$src)),
5742             (ROUNDSDr FR64:$src, (i32 0xA))>;
5743   def : Pat<(f64 (frint FR64:$src)),
5744             (ROUNDSDr FR64:$src, (i32 0x4))>;
5745   def : Pat<(f64 (ftrunc FR64:$src)),
5746             (ROUNDSDr FR64:$src, (i32 0xB))>;
5747 }
5748
5749 let Predicates = [UseSSE41, OptForSize] in {
5750   def : Pat<(ffloor (loadf32 addr:$src)),
5751             (ROUNDSSm addr:$src, (i32 0x9))>;
5752   def : Pat<(f32 (fnearbyint (loadf32 addr:$src))),
5753             (ROUNDSSm addr:$src, (i32 0xC))>;
5754   def : Pat<(f32 (fceil (loadf32 addr:$src))),
5755             (ROUNDSSm addr:$src, (i32 0xA))>;
5756   def : Pat<(f32 (frint (loadf32 addr:$src))),
5757             (ROUNDSSm addr:$src, (i32 0x4))>;
5758   def : Pat<(f32 (ftrunc (loadf32 addr:$src))),
5759             (ROUNDSSm addr:$src, (i32 0xB))>;
5760
5761   def : Pat<(f64 (ffloor (loadf64 addr:$src))),
5762             (ROUNDSDm addr:$src, (i32 0x9))>;
5763   def : Pat<(f64 (fnearbyint (loadf64 addr:$src))),
5764             (ROUNDSDm addr:$src, (i32 0xC))>;
5765   def : Pat<(f64 (fceil (loadf64 addr:$src))),
5766             (ROUNDSDm addr:$src, (i32 0xA))>;
5767   def : Pat<(f64 (frint (loadf64 addr:$src))),
5768             (ROUNDSDm addr:$src, (i32 0x4))>;
5769   def : Pat<(f64 (ftrunc (loadf64 addr:$src))),
5770             (ROUNDSDm addr:$src, (i32 0xB))>;
5771 }
5772
5773 let Predicates = [UseSSE41] in {
5774   def : Pat<(v4f32 (ffloor VR128:$src)),
5775             (ROUNDPSr VR128:$src, (i32 0x9))>;
5776   def : Pat<(v4f32 (fnearbyint VR128:$src)),
5777             (ROUNDPSr VR128:$src, (i32 0xC))>;
5778   def : Pat<(v4f32 (fceil VR128:$src)),
5779             (ROUNDPSr VR128:$src, (i32 0xA))>;
5780   def : Pat<(v4f32 (frint VR128:$src)),
5781             (ROUNDPSr VR128:$src, (i32 0x4))>;
5782   def : Pat<(v4f32 (ftrunc VR128:$src)),
5783             (ROUNDPSr VR128:$src, (i32 0xB))>;
5784
5785   def : Pat<(v4f32 (ffloor (memopv4f32 addr:$src))),
5786             (ROUNDPSm addr:$src, (i32 0x9))>;
5787   def : Pat<(v4f32 (fnearbyint (memopv4f32 addr:$src))),
5788             (ROUNDPSm addr:$src, (i32 0xC))>;
5789   def : Pat<(v4f32 (fceil (memopv4f32 addr:$src))),
5790             (ROUNDPSm addr:$src, (i32 0xA))>;
5791   def : Pat<(v4f32 (frint (memopv4f32 addr:$src))),
5792             (ROUNDPSm addr:$src, (i32 0x4))>;
5793   def : Pat<(v4f32 (ftrunc (memopv4f32 addr:$src))),
5794             (ROUNDPSm addr:$src, (i32 0xB))>;
5795
5796   def : Pat<(v2f64 (ffloor VR128:$src)),
5797             (ROUNDPDr VR128:$src, (i32 0x9))>;
5798   def : Pat<(v2f64 (fnearbyint VR128:$src)),
5799             (ROUNDPDr VR128:$src, (i32 0xC))>;
5800   def : Pat<(v2f64 (fceil VR128:$src)),
5801             (ROUNDPDr VR128:$src, (i32 0xA))>;
5802   def : Pat<(v2f64 (frint VR128:$src)),
5803             (ROUNDPDr VR128:$src, (i32 0x4))>;
5804   def : Pat<(v2f64 (ftrunc VR128:$src)),
5805             (ROUNDPDr VR128:$src, (i32 0xB))>;
5806
5807   def : Pat<(v2f64 (ffloor (memopv2f64 addr:$src))),
5808             (ROUNDPDm addr:$src, (i32 0x9))>;
5809   def : Pat<(v2f64 (fnearbyint (memopv2f64 addr:$src))),
5810             (ROUNDPDm addr:$src, (i32 0xC))>;
5811   def : Pat<(v2f64 (fceil (memopv2f64 addr:$src))),
5812             (ROUNDPDm addr:$src, (i32 0xA))>;
5813   def : Pat<(v2f64 (frint (memopv2f64 addr:$src))),
5814             (ROUNDPDm addr:$src, (i32 0x4))>;
5815   def : Pat<(v2f64 (ftrunc (memopv2f64 addr:$src))),
5816             (ROUNDPDm addr:$src, (i32 0xB))>;
5817 }
5818
5819 defm : scalar_unary_math_imm_patterns<ffloor, "ROUNDSS", X86Movss,
5820                                       v4f32, 0x01, UseSSE41>;
5821 defm : scalar_unary_math_imm_patterns<fceil, "ROUNDSS", X86Movss,
5822                                       v4f32, 0x02, UseSSE41>;
5823 defm : scalar_unary_math_imm_patterns<ffloor, "ROUNDSD", X86Movsd,
5824                                       v2f64, 0x01, UseSSE41>;
5825 defm : scalar_unary_math_imm_patterns<fceil, "ROUNDSD", X86Movsd,
5826                                       v2f64, 0x02, UseSSE41>;
5827
5828 //===----------------------------------------------------------------------===//
5829 // SSE4.1 - Packed Bit Test
5830 //===----------------------------------------------------------------------===//
5831
5832 // ptest instruction we'll lower to this in X86ISelLowering primarily from
5833 // the intel intrinsic that corresponds to this.
5834 let Defs = [EFLAGS], Predicates = [HasAVX] in {
5835 def VPTESTrr  : SS48I<0x17, MRMSrcReg, (outs), (ins VR128:$src1, VR128:$src2),
5836                 "vptest\t{$src2, $src1|$src1, $src2}",
5837                 [(set EFLAGS, (X86ptest VR128:$src1, (v2i64 VR128:$src2)))]>,
5838                 Sched<[SchedWriteVecTest.XMM]>, VEX, VEX_WIG;
5839 def VPTESTrm  : SS48I<0x17, MRMSrcMem, (outs), (ins VR128:$src1, f128mem:$src2),
5840                 "vptest\t{$src2, $src1|$src1, $src2}",
5841                 [(set EFLAGS,(X86ptest VR128:$src1, (loadv2i64 addr:$src2)))]>,
5842                 Sched<[SchedWriteVecTest.XMM.Folded, ReadAfterLd]>,
5843                 VEX, VEX_WIG;
5844
5845 def VPTESTYrr : SS48I<0x17, MRMSrcReg, (outs), (ins VR256:$src1, VR256:$src2),
5846                 "vptest\t{$src2, $src1|$src1, $src2}",
5847                 [(set EFLAGS, (X86ptest VR256:$src1, (v4i64 VR256:$src2)))]>,
5848                 Sched<[SchedWriteVecTest.YMM]>, VEX, VEX_L, VEX_WIG;
5849 def VPTESTYrm : SS48I<0x17, MRMSrcMem, (outs), (ins VR256:$src1, i256mem:$src2),
5850                 "vptest\t{$src2, $src1|$src1, $src2}",
5851                 [(set EFLAGS,(X86ptest VR256:$src1, (loadv4i64 addr:$src2)))]>,
5852                 Sched<[SchedWriteVecTest.YMM.Folded, ReadAfterLd]>,
5853                 VEX, VEX_L, VEX_WIG;
5854 }
5855
5856 let Defs = [EFLAGS] in {
5857 def PTESTrr : SS48I<0x17, MRMSrcReg, (outs), (ins VR128:$src1, VR128:$src2),
5858               "ptest\t{$src2, $src1|$src1, $src2}",
5859               [(set EFLAGS, (X86ptest VR128:$src1, (v2i64 VR128:$src2)))]>,
5860               Sched<[SchedWriteVecTest.XMM]>;
5861 def PTESTrm : SS48I<0x17, MRMSrcMem, (outs), (ins VR128:$src1, f128mem:$src2),
5862               "ptest\t{$src2, $src1|$src1, $src2}",
5863               [(set EFLAGS, (X86ptest VR128:$src1, (memopv2i64 addr:$src2)))]>,
5864               Sched<[SchedWriteVecTest.XMM.Folded, ReadAfterLd]>;
5865 }
5866
5867 // The bit test instructions below are AVX only
5868 multiclass avx_bittest<bits<8> opc, string OpcodeStr, RegisterClass RC,
5869                        X86MemOperand x86memop, PatFrag mem_frag, ValueType vt,
5870                        X86FoldableSchedWrite sched> {
5871   def rr : SS48I<opc, MRMSrcReg, (outs), (ins RC:$src1, RC:$src2),
5872             !strconcat(OpcodeStr, "\t{$src2, $src1|$src1, $src2}"),
5873             [(set EFLAGS, (X86testp RC:$src1, (vt RC:$src2)))]>,
5874             Sched<[sched]>, VEX;
5875   def rm : SS48I<opc, MRMSrcMem, (outs), (ins RC:$src1, x86memop:$src2),
5876             !strconcat(OpcodeStr, "\t{$src2, $src1|$src1, $src2}"),
5877             [(set EFLAGS, (X86testp RC:$src1, (mem_frag addr:$src2)))]>,
5878             Sched<[sched.Folded, ReadAfterLd]>, VEX;
5879 }
5880
5881 let Defs = [EFLAGS], Predicates = [HasAVX] in {
5882 let ExeDomain = SSEPackedSingle in {
5883 defm VTESTPS  : avx_bittest<0x0E, "vtestps", VR128, f128mem, loadv4f32, v4f32,
5884                             SchedWriteFTest.XMM>;
5885 defm VTESTPSY : avx_bittest<0x0E, "vtestps", VR256, f256mem, loadv8f32, v8f32,
5886                             SchedWriteFTest.YMM>, VEX_L;
5887 }
5888 let ExeDomain = SSEPackedDouble in {
5889 defm VTESTPD  : avx_bittest<0x0F, "vtestpd", VR128, f128mem, loadv2f64, v2f64,
5890                             SchedWriteFTest.XMM>;
5891 defm VTESTPDY : avx_bittest<0x0F, "vtestpd", VR256, f256mem, loadv4f64, v4f64,
5892                             SchedWriteFTest.YMM>, VEX_L;
5893 }
5894 }
5895
5896 //===----------------------------------------------------------------------===//
5897 // SSE4.1 - Misc Instructions
5898 //===----------------------------------------------------------------------===//
5899
5900 let Defs = [EFLAGS], Predicates = [HasPOPCNT] in {
5901   def POPCNT16rr : I<0xB8, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
5902                      "popcnt{w}\t{$src, $dst|$dst, $src}",
5903                      [(set GR16:$dst, (ctpop GR16:$src)), (implicit EFLAGS)]>,
5904                      Sched<[WritePOPCNT]>, OpSize16, XS;
5905   def POPCNT16rm : I<0xB8, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
5906                      "popcnt{w}\t{$src, $dst|$dst, $src}",
5907                      [(set GR16:$dst, (ctpop (loadi16 addr:$src))),
5908                       (implicit EFLAGS)]>,
5909                       Sched<[WritePOPCNT.Folded]>, OpSize16, XS;
5910
5911   def POPCNT32rr : I<0xB8, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
5912                      "popcnt{l}\t{$src, $dst|$dst, $src}",
5913                      [(set GR32:$dst, (ctpop GR32:$src)), (implicit EFLAGS)]>,
5914                      Sched<[WritePOPCNT]>, OpSize32, XS;
5915
5916   def POPCNT32rm : I<0xB8, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
5917                      "popcnt{l}\t{$src, $dst|$dst, $src}",
5918                      [(set GR32:$dst, (ctpop (loadi32 addr:$src))),
5919                       (implicit EFLAGS)]>,
5920                       Sched<[WritePOPCNT.Folded]>, OpSize32, XS;
5921
5922   def POPCNT64rr : RI<0xB8, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
5923                       "popcnt{q}\t{$src, $dst|$dst, $src}",
5924                       [(set GR64:$dst, (ctpop GR64:$src)), (implicit EFLAGS)]>,
5925                       Sched<[WritePOPCNT]>, XS;
5926   def POPCNT64rm : RI<0xB8, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
5927                       "popcnt{q}\t{$src, $dst|$dst, $src}",
5928                       [(set GR64:$dst, (ctpop (loadi64 addr:$src))),
5929                        (implicit EFLAGS)]>,
5930                        Sched<[WritePOPCNT.Folded]>, XS;
5931 }
5932
5933 // SS41I_unop_rm_int_v16 - SSE 4.1 unary operator whose type is v8i16.
5934 multiclass SS41I_unop_rm_int_v16<bits<8> opc, string OpcodeStr,
5935                                  SDNode OpNode, PatFrag ld_frag,
5936                                  X86FoldableSchedWrite Sched> {
5937   def rr : SS48I<opc, MRMSrcReg, (outs VR128:$dst),
5938                  (ins VR128:$src),
5939                  !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5940                  [(set VR128:$dst, (v8i16 (OpNode (v8i16 VR128:$src))))]>,
5941                  Sched<[Sched]>;
5942   def rm : SS48I<opc, MRMSrcMem, (outs VR128:$dst),
5943                   (ins i128mem:$src),
5944                   !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5945                   [(set VR128:$dst,
5946                     (v8i16 (OpNode (v8i16 (bitconvert (ld_frag addr:$src))))))]>,
5947                  Sched<[Sched.Folded]>;
5948 }
5949
5950 // PHMIN has the same profile as PSAD, thus we use the same scheduling
5951 // model, although the naming is misleading.
5952 let Predicates = [HasAVX] in
5953 defm VPHMINPOSUW : SS41I_unop_rm_int_v16<0x41, "vphminposuw",
5954                                          X86phminpos, loadv2i64,
5955                                          WritePHMINPOS>, VEX, VEX_WIG;
5956 defm PHMINPOSUW : SS41I_unop_rm_int_v16<0x41, "phminposuw",
5957                                          X86phminpos, memopv2i64,
5958                                          WritePHMINPOS>;
5959
5960 /// SS48I_binop_rm - Simple SSE41 binary operator.
5961 multiclass SS48I_binop_rm<bits<8> opc, string OpcodeStr, SDNode OpNode,
5962                           ValueType OpVT, RegisterClass RC, PatFrag memop_frag,
5963                           X86MemOperand x86memop, X86FoldableSchedWrite sched,
5964                           bit Is2Addr = 1> {
5965   let isCommutable = 1 in
5966   def rr : SS48I<opc, MRMSrcReg, (outs RC:$dst),
5967        (ins RC:$src1, RC:$src2),
5968        !if(Is2Addr,
5969            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5970            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5971        [(set RC:$dst, (OpVT (OpNode RC:$src1, RC:$src2)))]>,
5972        Sched<[sched]>;
5973   def rm : SS48I<opc, MRMSrcMem, (outs RC:$dst),
5974        (ins RC:$src1, x86memop:$src2),
5975        !if(Is2Addr,
5976            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5977            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5978        [(set RC:$dst,
5979          (OpVT (OpNode RC:$src1, (bitconvert (memop_frag addr:$src2)))))]>,
5980        Sched<[sched.Folded, ReadAfterLd]>;
5981 }
5982
5983 let Predicates = [HasAVX, NoVLX] in {
5984   defm VPMINSD   : SS48I_binop_rm<0x39, "vpminsd", smin, v4i32, VR128,
5985                                   loadv2i64, i128mem, SchedWriteVecALU.XMM, 0>,
5986                                   VEX_4V, VEX_WIG;
5987   defm VPMINUD   : SS48I_binop_rm<0x3B, "vpminud", umin, v4i32, VR128,
5988                                   loadv2i64, i128mem, SchedWriteVecALU.XMM, 0>,
5989                                   VEX_4V, VEX_WIG;
5990   defm VPMAXSD   : SS48I_binop_rm<0x3D, "vpmaxsd", smax, v4i32, VR128,
5991                                   loadv2i64, i128mem, SchedWriteVecALU.XMM, 0>,
5992                                   VEX_4V, VEX_WIG;
5993   defm VPMAXUD   : SS48I_binop_rm<0x3F, "vpmaxud", umax, v4i32, VR128,
5994                                   loadv2i64, i128mem, SchedWriteVecALU.XMM, 0>,
5995                                   VEX_4V, VEX_WIG;
5996   defm VPMULDQ   : SS48I_binop_rm<0x28, "vpmuldq", X86pmuldq, v2i64, VR128,
5997                                   loadv2i64, i128mem, SchedWriteVecIMul.XMM, 0>,
5998                                   VEX_4V, VEX_WIG;
5999 }
6000 let Predicates = [HasAVX, NoVLX_Or_NoBWI] in {
6001   defm VPMINSB   : SS48I_binop_rm<0x38, "vpminsb", smin, v16i8, VR128,
6002                                   loadv2i64, i128mem, SchedWriteVecALU.XMM, 0>,
6003                                   VEX_4V, VEX_WIG;
6004   defm VPMINUW   : SS48I_binop_rm<0x3A, "vpminuw", umin, v8i16, VR128,
6005                                   loadv2i64, i128mem, SchedWriteVecALU.XMM, 0>,
6006                                   VEX_4V, VEX_WIG;
6007   defm VPMAXSB   : SS48I_binop_rm<0x3C, "vpmaxsb", smax, v16i8, VR128,
6008                                   loadv2i64, i128mem, SchedWriteVecALU.XMM, 0>,
6009                                   VEX_4V, VEX_WIG;
6010   defm VPMAXUW   : SS48I_binop_rm<0x3E, "vpmaxuw", umax, v8i16, VR128,
6011                                   loadv2i64, i128mem, SchedWriteVecALU.XMM, 0>,
6012                                   VEX_4V, VEX_WIG;
6013 }
6014
6015 let Predicates = [HasAVX2, NoVLX] in {
6016   defm VPMINSDY  : SS48I_binop_rm<0x39, "vpminsd", smin, v8i32, VR256,
6017                                   loadv4i64, i256mem, SchedWriteVecALU.YMM, 0>,
6018                                   VEX_4V, VEX_L, VEX_WIG;
6019   defm VPMINUDY  : SS48I_binop_rm<0x3B, "vpminud", umin, v8i32, VR256,
6020                                   loadv4i64, i256mem, SchedWriteVecALU.YMM, 0>,
6021                                   VEX_4V, VEX_L, VEX_WIG;
6022   defm VPMAXSDY  : SS48I_binop_rm<0x3D, "vpmaxsd", smax, v8i32, VR256,
6023                                   loadv4i64, i256mem, SchedWriteVecALU.YMM, 0>,
6024                                   VEX_4V, VEX_L, VEX_WIG;
6025   defm VPMAXUDY  : SS48I_binop_rm<0x3F, "vpmaxud", umax, v8i32, VR256,
6026                                   loadv4i64, i256mem, SchedWriteVecALU.YMM, 0>,
6027                                   VEX_4V, VEX_L, VEX_WIG;
6028   defm VPMULDQY  : SS48I_binop_rm<0x28, "vpmuldq", X86pmuldq, v4i64, VR256,
6029                                   loadv4i64, i256mem, SchedWriteVecIMul.YMM, 0>,
6030                                   VEX_4V, VEX_L, VEX_WIG;
6031 }
6032 let Predicates = [HasAVX2, NoVLX_Or_NoBWI] in {
6033   defm VPMINSBY  : SS48I_binop_rm<0x38, "vpminsb", smin, v32i8, VR256,
6034                                   loadv4i64, i256mem, SchedWriteVecALU.YMM, 0>,
6035                                   VEX_4V, VEX_L, VEX_WIG;
6036   defm VPMINUWY  : SS48I_binop_rm<0x3A, "vpminuw", umin, v16i16, VR256,
6037                                   loadv4i64, i256mem, SchedWriteVecALU.YMM, 0>,
6038                                   VEX_4V, VEX_L, VEX_WIG;
6039   defm VPMAXSBY  : SS48I_binop_rm<0x3C, "vpmaxsb", smax, v32i8, VR256,
6040                                   loadv4i64, i256mem, SchedWriteVecALU.YMM, 0>,
6041                                   VEX_4V, VEX_L, VEX_WIG;
6042   defm VPMAXUWY  : SS48I_binop_rm<0x3E, "vpmaxuw", umax, v16i16, VR256,
6043                                   loadv4i64, i256mem, SchedWriteVecALU.YMM, 0>,
6044                                   VEX_4V, VEX_L, VEX_WIG;
6045 }
6046
6047 let Constraints = "$src1 = $dst" in {
6048   defm PMINSB   : SS48I_binop_rm<0x38, "pminsb", smin, v16i8, VR128,
6049                                  memopv2i64, i128mem, SchedWriteVecALU.XMM, 1>;
6050   defm PMINSD   : SS48I_binop_rm<0x39, "pminsd", smin, v4i32, VR128,
6051                                  memopv2i64, i128mem, SchedWriteVecALU.XMM, 1>;
6052   defm PMINUD   : SS48I_binop_rm<0x3B, "pminud", umin, v4i32, VR128,
6053                                  memopv2i64, i128mem, SchedWriteVecALU.XMM, 1>;
6054   defm PMINUW   : SS48I_binop_rm<0x3A, "pminuw", umin, v8i16, VR128,
6055                                  memopv2i64, i128mem, SchedWriteVecALU.XMM, 1>;
6056   defm PMAXSB   : SS48I_binop_rm<0x3C, "pmaxsb", smax, v16i8, VR128,
6057                                  memopv2i64, i128mem, SchedWriteVecALU.XMM, 1>;
6058   defm PMAXSD   : SS48I_binop_rm<0x3D, "pmaxsd", smax, v4i32, VR128,
6059                                  memopv2i64, i128mem, SchedWriteVecALU.XMM, 1>;
6060   defm PMAXUD   : SS48I_binop_rm<0x3F, "pmaxud", umax, v4i32, VR128,
6061                                  memopv2i64, i128mem, SchedWriteVecALU.XMM, 1>;
6062   defm PMAXUW   : SS48I_binop_rm<0x3E, "pmaxuw", umax, v8i16, VR128,
6063                                  memopv2i64, i128mem, SchedWriteVecALU.XMM, 1>;
6064   defm PMULDQ   : SS48I_binop_rm<0x28, "pmuldq", X86pmuldq, v2i64, VR128,
6065                                  memopv2i64, i128mem, SchedWriteVecIMul.XMM, 1>;
6066 }
6067
6068 let Predicates = [HasAVX, NoVLX] in
6069   defm VPMULLD  : SS48I_binop_rm<0x40, "vpmulld", mul, v4i32, VR128,
6070                                  loadv2i64, i128mem, SchedWritePMULLD.XMM, 0>,
6071                                  VEX_4V, VEX_WIG;
6072 let Predicates = [HasAVX] in
6073   defm VPCMPEQQ : SS48I_binop_rm<0x29, "vpcmpeqq", X86pcmpeq, v2i64, VR128,
6074                                  loadv2i64, i128mem, SchedWriteVecALU.XMM, 0>,
6075                                  VEX_4V, VEX_WIG;
6076
6077 let Predicates = [HasAVX2, NoVLX] in
6078   defm VPMULLDY  : SS48I_binop_rm<0x40, "vpmulld", mul, v8i32, VR256,
6079                                   loadv4i64, i256mem, SchedWritePMULLD.YMM, 0>,
6080                                   VEX_4V, VEX_L, VEX_WIG;
6081 let Predicates = [HasAVX2] in
6082   defm VPCMPEQQY : SS48I_binop_rm<0x29, "vpcmpeqq", X86pcmpeq, v4i64, VR256,
6083                                   loadv4i64, i256mem, SchedWriteVecALU.YMM, 0>,
6084                                   VEX_4V, VEX_L, VEX_WIG;
6085
6086 let Constraints = "$src1 = $dst" in {
6087   defm PMULLD  : SS48I_binop_rm<0x40, "pmulld", mul, v4i32, VR128,
6088                                 memopv2i64, i128mem, SchedWritePMULLD.XMM, 1>;
6089   defm PCMPEQQ : SS48I_binop_rm<0x29, "pcmpeqq", X86pcmpeq, v2i64, VR128,
6090                                 memopv2i64, i128mem, SchedWriteVecALU.XMM, 1>;
6091 }
6092
6093 /// SS41I_binop_rmi_int - SSE 4.1 binary operator with 8-bit immediate
6094 multiclass SS41I_binop_rmi_int<bits<8> opc, string OpcodeStr,
6095                  Intrinsic IntId, RegisterClass RC, PatFrag memop_frag,
6096                  X86MemOperand x86memop, bit Is2Addr,
6097                  X86FoldableSchedWrite sched> {
6098   let isCommutable = 1 in
6099   def rri : SS4AIi8<opc, MRMSrcReg, (outs RC:$dst),
6100         (ins RC:$src1, RC:$src2, u8imm:$src3),
6101         !if(Is2Addr,
6102             !strconcat(OpcodeStr,
6103                 "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6104             !strconcat(OpcodeStr,
6105                 "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6106         [(set RC:$dst, (IntId RC:$src1, RC:$src2, imm:$src3))]>,
6107         Sched<[sched]>;
6108   def rmi : SS4AIi8<opc, MRMSrcMem, (outs RC:$dst),
6109         (ins RC:$src1, x86memop:$src2, u8imm:$src3),
6110         !if(Is2Addr,
6111             !strconcat(OpcodeStr,
6112                 "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6113             !strconcat(OpcodeStr,
6114                 "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6115         [(set RC:$dst,
6116           (IntId RC:$src1,
6117            (bitconvert (memop_frag addr:$src2)), imm:$src3))]>,
6118         Sched<[sched.Folded, ReadAfterLd]>;
6119 }
6120
6121 /// SS41I_binop_rmi - SSE 4.1 binary operator with 8-bit immediate
6122 multiclass SS41I_binop_rmi<bits<8> opc, string OpcodeStr, SDNode OpNode,
6123                            ValueType OpVT, RegisterClass RC, PatFrag memop_frag,
6124                            X86MemOperand x86memop, bit Is2Addr,
6125                            X86FoldableSchedWrite sched> {
6126   let isCommutable = 1 in
6127   def rri : SS4AIi8<opc, MRMSrcReg, (outs RC:$dst),
6128         (ins RC:$src1, RC:$src2, u8imm:$src3),
6129         !if(Is2Addr,
6130             !strconcat(OpcodeStr,
6131                 "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6132             !strconcat(OpcodeStr,
6133                 "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6134         [(set RC:$dst, (OpVT (OpNode RC:$src1, RC:$src2, imm:$src3)))]>,
6135         Sched<[sched]>;
6136   def rmi : SS4AIi8<opc, MRMSrcMem, (outs RC:$dst),
6137         (ins RC:$src1, x86memop:$src2, u8imm:$src3),
6138         !if(Is2Addr,
6139             !strconcat(OpcodeStr,
6140                 "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6141             !strconcat(OpcodeStr,
6142                 "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6143         [(set RC:$dst,
6144           (OpVT (OpNode RC:$src1,
6145                  (bitconvert (memop_frag addr:$src2)), imm:$src3)))]>,
6146         Sched<[sched.Folded, ReadAfterLd]>;
6147 }
6148
6149 def BlendCommuteImm2 : SDNodeXForm<imm, [{
6150   uint8_t Imm = N->getZExtValue() & 0x03;
6151   return getI8Imm(Imm ^ 0x03, SDLoc(N));
6152 }]>;
6153
6154 def BlendCommuteImm4 : SDNodeXForm<imm, [{
6155   uint8_t Imm = N->getZExtValue() & 0x0f;
6156   return getI8Imm(Imm ^ 0x0f, SDLoc(N));
6157 }]>;
6158
6159 def BlendCommuteImm8 : SDNodeXForm<imm, [{
6160   uint8_t Imm = N->getZExtValue() & 0xff;
6161   return getI8Imm(Imm ^ 0xff, SDLoc(N));
6162 }]>;
6163
6164 let Predicates = [HasAVX] in {
6165   let isCommutable = 0 in {
6166     defm VMPSADBW : SS41I_binop_rmi_int<0x42, "vmpsadbw", int_x86_sse41_mpsadbw,
6167                                         VR128, loadv2i64, i128mem, 0,
6168                                         SchedWriteMPSAD.XMM>, VEX_4V, VEX_WIG;
6169   }
6170
6171   let ExeDomain = SSEPackedSingle in
6172   defm VDPPS : SS41I_binop_rmi_int<0x40, "vdpps", int_x86_sse41_dpps,
6173                                    VR128, loadv4f32, f128mem, 0,
6174                                    SchedWriteDPPS.XMM>, VEX_4V, VEX_WIG;
6175   let ExeDomain = SSEPackedDouble in
6176   defm VDPPD : SS41I_binop_rmi_int<0x41, "vdppd", int_x86_sse41_dppd,
6177                                    VR128, loadv2f64, f128mem, 0,
6178                                    SchedWriteDPPD.XMM>, VEX_4V, VEX_WIG;
6179   let ExeDomain = SSEPackedSingle in
6180   defm VDPPSY : SS41I_binop_rmi_int<0x40, "vdpps", int_x86_avx_dp_ps_256,
6181                                     VR256, loadv8f32, i256mem, 0,
6182                                     SchedWriteDPPS.YMM>, VEX_4V, VEX_L, VEX_WIG;
6183 }
6184
6185 let Predicates = [HasAVX2] in {
6186   let isCommutable = 0 in {
6187   defm VMPSADBWY : SS41I_binop_rmi_int<0x42, "vmpsadbw", int_x86_avx2_mpsadbw,
6188                                   VR256, loadv4i64, i256mem, 0,
6189                                   SchedWriteMPSAD.YMM>, VEX_4V, VEX_L, VEX_WIG;
6190   }
6191 }
6192
6193 let Constraints = "$src1 = $dst" in {
6194   let isCommutable = 0 in {
6195   defm MPSADBW : SS41I_binop_rmi_int<0x42, "mpsadbw", int_x86_sse41_mpsadbw,
6196                                      VR128, memopv2i64, i128mem, 1,
6197                                      SchedWriteMPSAD.XMM>;
6198   }
6199
6200   let ExeDomain = SSEPackedSingle in
6201   defm DPPS : SS41I_binop_rmi_int<0x40, "dpps", int_x86_sse41_dpps,
6202                                   VR128, memopv4f32, f128mem, 1,
6203                                   SchedWriteDPPS.XMM>;
6204   let ExeDomain = SSEPackedDouble in
6205   defm DPPD : SS41I_binop_rmi_int<0x41, "dppd", int_x86_sse41_dppd,
6206                                   VR128, memopv2f64, f128mem, 1,
6207                                   SchedWriteDPPD.XMM>;
6208 }
6209
6210 /// SS41I_blend_rmi - SSE 4.1 blend with 8-bit immediate
6211 multiclass SS41I_blend_rmi<bits<8> opc, string OpcodeStr, SDNode OpNode,
6212                            ValueType OpVT, RegisterClass RC, PatFrag memop_frag,
6213                            X86MemOperand x86memop, bit Is2Addr, Domain d,
6214                            X86FoldableSchedWrite sched, SDNodeXForm commuteXForm> {
6215 let ExeDomain = d, Constraints = !if(Is2Addr, "$src1 = $dst", "") in {
6216   let isCommutable = 1 in
6217   def rri : SS4AIi8<opc, MRMSrcReg, (outs RC:$dst),
6218         (ins RC:$src1, RC:$src2, u8imm:$src3),
6219         !if(Is2Addr,
6220             !strconcat(OpcodeStr,
6221                 "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6222             !strconcat(OpcodeStr,
6223                 "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6224         [(set RC:$dst, (OpVT (OpNode RC:$src1, RC:$src2, imm:$src3)))]>,
6225         Sched<[sched]>;
6226   def rmi : SS4AIi8<opc, MRMSrcMem, (outs RC:$dst),
6227         (ins RC:$src1, x86memop:$src2, u8imm:$src3),
6228         !if(Is2Addr,
6229             !strconcat(OpcodeStr,
6230                 "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6231             !strconcat(OpcodeStr,
6232                 "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6233         [(set RC:$dst,
6234           (OpVT (OpNode RC:$src1,
6235                  (bitconvert (memop_frag addr:$src2)), imm:$src3)))]>,
6236         Sched<[sched.Folded, ReadAfterLd]>;
6237 }
6238
6239   // Pattern to commute if load is in first source.
6240   def : Pat<(OpVT (OpNode (bitconvert (memop_frag addr:$src2)),
6241                           RC:$src1, imm:$src3)),
6242             (!cast<Instruction>(NAME#"rmi") RC:$src1, addr:$src2,
6243                                             (commuteXForm imm:$src3))>;
6244 }
6245
6246 let Predicates = [HasAVX] in {
6247   defm VBLENDPS : SS41I_blend_rmi<0x0C, "vblendps", X86Blendi, v4f32,
6248                                   VR128, loadv4f32, f128mem, 0, SSEPackedSingle,
6249                                   SchedWriteFBlend.XMM, BlendCommuteImm4>,
6250                                   VEX_4V, VEX_WIG;
6251   defm VBLENDPSY : SS41I_blend_rmi<0x0C, "vblendps", X86Blendi, v8f32,
6252                                    VR256, loadv8f32, f256mem, 0, SSEPackedSingle,
6253                                    SchedWriteFBlend.YMM, BlendCommuteImm8>,
6254                                    VEX_4V, VEX_L, VEX_WIG;
6255   defm VBLENDPD : SS41I_blend_rmi<0x0D, "vblendpd", X86Blendi, v2f64,
6256                                   VR128, loadv2f64, f128mem, 0, SSEPackedDouble,
6257                                   SchedWriteFBlend.XMM, BlendCommuteImm2>,
6258                                   VEX_4V, VEX_WIG;
6259   defm VBLENDPDY : SS41I_blend_rmi<0x0D, "vblendpd", X86Blendi, v4f64,
6260                                    VR256, loadv4f64, f256mem, 0, SSEPackedDouble,
6261                                    SchedWriteFBlend.YMM, BlendCommuteImm4>,
6262                                    VEX_4V, VEX_L, VEX_WIG;
6263   defm VPBLENDW : SS41I_blend_rmi<0x0E, "vpblendw", X86Blendi, v8i16,
6264                                   VR128, loadv2i64, i128mem, 0, SSEPackedInt,
6265                                   SchedWriteBlend.XMM, BlendCommuteImm8>,
6266                                   VEX_4V, VEX_WIG;
6267 }
6268
6269 let Predicates = [HasAVX2] in {
6270   defm VPBLENDWY : SS41I_blend_rmi<0x0E, "vpblendw", X86Blendi, v16i16,
6271                                    VR256, loadv4i64, i256mem, 0, SSEPackedInt,
6272                                    SchedWriteBlend.YMM, BlendCommuteImm8>,
6273                                    VEX_4V, VEX_L, VEX_WIG;
6274 }
6275
6276 defm BLENDPS : SS41I_blend_rmi<0x0C, "blendps", X86Blendi, v4f32,
6277                                VR128, memopv4f32, f128mem, 1, SSEPackedSingle,
6278                                SchedWriteFBlend.XMM, BlendCommuteImm4>;
6279 defm BLENDPD : SS41I_blend_rmi<0x0D, "blendpd", X86Blendi, v2f64,
6280                                VR128, memopv2f64, f128mem, 1, SSEPackedDouble,
6281                                SchedWriteFBlend.XMM, BlendCommuteImm2>;
6282 defm PBLENDW : SS41I_blend_rmi<0x0E, "pblendw", X86Blendi, v8i16,
6283                                VR128, memopv2i64, i128mem, 1, SSEPackedInt,
6284                                SchedWriteBlend.XMM, BlendCommuteImm8>;
6285
6286 // For insertion into the zero index (low half) of a 256-bit vector, it is
6287 // more efficient to generate a blend with immediate instead of an insert*128.
6288 let Predicates = [HasAVX] in {
6289 def : Pat<(insert_subvector (v4f64 VR256:$src1), (v2f64 VR128:$src2), (iPTR 0)),
6290           (VBLENDPDYrri VR256:$src1,
6291                         (INSERT_SUBREG (v4f64 (IMPLICIT_DEF)),
6292                                        VR128:$src2, sub_xmm), 0x3)>;
6293 def : Pat<(insert_subvector (v8f32 VR256:$src1), (v4f32 VR128:$src2), (iPTR 0)),
6294           (VBLENDPSYrri VR256:$src1,
6295                         (INSERT_SUBREG (v8f32 (IMPLICIT_DEF)),
6296                                        VR128:$src2, sub_xmm), 0xf)>;
6297 }
6298
6299 /// SS41I_quaternary_int_avx - AVX SSE 4.1 with 4 operators
6300 multiclass SS41I_quaternary_int_avx<bits<8> opc, string OpcodeStr,
6301                                     RegisterClass RC, X86MemOperand x86memop,
6302                                     PatFrag mem_frag, Intrinsic IntId,
6303                                     X86FoldableSchedWrite sched> {
6304   def rr : Ii8Reg<opc, MRMSrcReg, (outs RC:$dst),
6305                   (ins RC:$src1, RC:$src2, RC:$src3),
6306                   !strconcat(OpcodeStr,
6307                     "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
6308                   [(set RC:$dst, (IntId RC:$src1, RC:$src2, RC:$src3))],
6309                   SSEPackedInt>, TAPD, VEX_4V,
6310                 Sched<[sched]>;
6311
6312   def rm : Ii8Reg<opc, MRMSrcMem, (outs RC:$dst),
6313                   (ins RC:$src1, x86memop:$src2, RC:$src3),
6314                   !strconcat(OpcodeStr,
6315                     "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
6316                   [(set RC:$dst,
6317                         (IntId RC:$src1, (bitconvert (mem_frag addr:$src2)),
6318                                RC:$src3))], SSEPackedInt>, TAPD, VEX_4V,
6319                 Sched<[sched.Folded, ReadAfterLd,
6320                        // x86memop:$src2
6321                        ReadDefault, ReadDefault, ReadDefault, ReadDefault,
6322                        ReadDefault,
6323                        // RC::$src3
6324                        ReadAfterLd]>;
6325 }
6326
6327 let Predicates = [HasAVX] in {
6328 let ExeDomain = SSEPackedDouble in {
6329 defm VBLENDVPD  : SS41I_quaternary_int_avx<0x4B, "vblendvpd", VR128, f128mem,
6330                                            loadv2f64, int_x86_sse41_blendvpd,
6331                                            SchedWriteFVarBlend.XMM>;
6332 defm VBLENDVPDY : SS41I_quaternary_int_avx<0x4B, "vblendvpd", VR256, f256mem,
6333                                   loadv4f64, int_x86_avx_blendv_pd_256,
6334                                   SchedWriteFVarBlend.YMM>, VEX_L;
6335 } // ExeDomain = SSEPackedDouble
6336 let ExeDomain = SSEPackedSingle in {
6337 defm VBLENDVPS  : SS41I_quaternary_int_avx<0x4A, "vblendvps", VR128, f128mem,
6338                                            loadv4f32, int_x86_sse41_blendvps,
6339                                            SchedWriteFVarBlend.XMM>;
6340 defm VBLENDVPSY : SS41I_quaternary_int_avx<0x4A, "vblendvps", VR256, f256mem,
6341                                   loadv8f32, int_x86_avx_blendv_ps_256,
6342                                   SchedWriteFVarBlend.YMM>, VEX_L;
6343 } // ExeDomain = SSEPackedSingle
6344 defm VPBLENDVB  : SS41I_quaternary_int_avx<0x4C, "vpblendvb", VR128, i128mem,
6345                                            loadv2i64, int_x86_sse41_pblendvb,
6346                                            SchedWriteVarBlend.XMM>;
6347 }
6348
6349 let Predicates = [HasAVX2] in {
6350 defm VPBLENDVBY : SS41I_quaternary_int_avx<0x4C, "vpblendvb", VR256, i256mem,
6351                                       loadv4i64, int_x86_avx2_pblendvb,
6352                                       SchedWriteVarBlend.YMM>, VEX_L;
6353 }
6354
6355 let Predicates = [HasAVX] in {
6356   def : Pat<(v16i8 (vselect (v16i8 VR128:$mask), (v16i8 VR128:$src1),
6357                             (v16i8 VR128:$src2))),
6358             (VPBLENDVBrr VR128:$src2, VR128:$src1, VR128:$mask)>;
6359   def : Pat<(v4i32 (vselect (v4i32 VR128:$mask), (v4i32 VR128:$src1),
6360                             (v4i32 VR128:$src2))),
6361             (VBLENDVPSrr VR128:$src2, VR128:$src1, VR128:$mask)>;
6362   def : Pat<(v4f32 (vselect (v4i32 VR128:$mask), (v4f32 VR128:$src1),
6363                             (v4f32 VR128:$src2))),
6364             (VBLENDVPSrr VR128:$src2, VR128:$src1, VR128:$mask)>;
6365   def : Pat<(v2i64 (vselect (v2i64 VR128:$mask), (v2i64 VR128:$src1),
6366                             (v2i64 VR128:$src2))),
6367             (VBLENDVPDrr VR128:$src2, VR128:$src1, VR128:$mask)>;
6368   def : Pat<(v2f64 (vselect (v2i64 VR128:$mask), (v2f64 VR128:$src1),
6369                             (v2f64 VR128:$src2))),
6370             (VBLENDVPDrr VR128:$src2, VR128:$src1, VR128:$mask)>;
6371   def : Pat<(v8i32 (vselect (v8i32 VR256:$mask), (v8i32 VR256:$src1),
6372                             (v8i32 VR256:$src2))),
6373             (VBLENDVPSYrr VR256:$src2, VR256:$src1, VR256:$mask)>;
6374   def : Pat<(v8f32 (vselect (v8i32 VR256:$mask), (v8f32 VR256:$src1),
6375                             (v8f32 VR256:$src2))),
6376             (VBLENDVPSYrr VR256:$src2, VR256:$src1, VR256:$mask)>;
6377   def : Pat<(v4i64 (vselect (v4i64 VR256:$mask), (v4i64 VR256:$src1),
6378                             (v4i64 VR256:$src2))),
6379             (VBLENDVPDYrr VR256:$src2, VR256:$src1, VR256:$mask)>;
6380   def : Pat<(v4f64 (vselect (v4i64 VR256:$mask), (v4f64 VR256:$src1),
6381                             (v4f64 VR256:$src2))),
6382             (VBLENDVPDYrr VR256:$src2, VR256:$src1, VR256:$mask)>;
6383 }
6384
6385 let Predicates = [HasAVX2] in {
6386   def : Pat<(v32i8 (vselect (v32i8 VR256:$mask), (v32i8 VR256:$src1),
6387                             (v32i8 VR256:$src2))),
6388             (VPBLENDVBYrr VR256:$src2, VR256:$src1, VR256:$mask)>;
6389 }
6390
6391 // Patterns
6392 // FIXME: Prefer a movss or movsd over a blendps when optimizing for size or
6393 // on targets where they have equal performance. These were changed to use
6394 // blends because blends have better throughput on SandyBridge and Haswell, but
6395 // movs[s/d] are 1-2 byte shorter instructions.
6396 let Predicates = [UseAVX] in {
6397   def : Pat<(v4f32 (X86vzmovl (v4f32 VR128:$src))),
6398             (VBLENDPSrri (v4f32 (V_SET0)), VR128:$src, (i8 1))>;
6399   def : Pat<(v4i32 (X86vzmovl (v4i32 VR128:$src))),
6400             (VPBLENDWrri (v4i32 (V_SET0)), VR128:$src, (i8 3))>;
6401
6402   // Move low f32 and clear high bits.
6403   def : Pat<(v8f32 (X86vzmovl (v8f32 VR256:$src))),
6404             (VBLENDPSYrri (v8f32 (AVX_SET0)), VR256:$src, (i8 1))>;
6405
6406   // Move low f64 and clear high bits.
6407   def : Pat<(v4f64 (X86vzmovl (v4f64 VR256:$src))),
6408             (VBLENDPDYrri (v4f64 (AVX_SET0)), VR256:$src, (i8 1))>;
6409
6410   // These will incur an FP/int domain crossing penalty, but it may be the only
6411   // way without AVX2. Do not add any complexity because we may be able to match
6412   // more optimal patterns defined earlier in this file.
6413   def : Pat<(v8i32 (X86vzmovl (v8i32 VR256:$src))),
6414             (VBLENDPSYrri (v8i32 (AVX_SET0)), VR256:$src, (i8 1))>;
6415   def : Pat<(v4i64 (X86vzmovl (v4i64 VR256:$src))),
6416             (VBLENDPDYrri (v4i64 (AVX_SET0)), VR256:$src, (i8 1))>;
6417 }
6418
6419 // FIXME: Prefer a movss or movsd over a blendps when optimizing for size or
6420 // on targets where they have equal performance. These were changed to use
6421 // blends because blends have better throughput on SandyBridge and Haswell, but
6422 // movs[s/d] are 1-2 byte shorter instructions.
6423 let Predicates = [UseSSE41] in {
6424   // With SSE41 we can use blends for these patterns.
6425   def : Pat<(v4f32 (X86vzmovl (v4f32 VR128:$src))),
6426             (BLENDPSrri (v4f32 (V_SET0)), VR128:$src, (i8 1))>;
6427   def : Pat<(v4i32 (X86vzmovl (v4i32 VR128:$src))),
6428             (PBLENDWrri (v4i32 (V_SET0)), VR128:$src, (i8 3))>;
6429 }
6430
6431
6432 /// SS41I_ternary_int - SSE 4.1 ternary operator
6433 let Uses = [XMM0], Constraints = "$src1 = $dst" in {
6434   multiclass SS41I_ternary_int<bits<8> opc, string OpcodeStr, PatFrag mem_frag,
6435                                X86MemOperand x86memop, Intrinsic IntId,
6436                                X86FoldableSchedWrite sched> {
6437     def rr0 : SS48I<opc, MRMSrcReg, (outs VR128:$dst),
6438                     (ins VR128:$src1, VR128:$src2),
6439                     !strconcat(OpcodeStr,
6440                      "\t{%xmm0, $src2, $dst|$dst, $src2, xmm0}"),
6441                     [(set VR128:$dst, (IntId VR128:$src1, VR128:$src2, XMM0))]>,
6442                     Sched<[sched]>;
6443
6444     def rm0 : SS48I<opc, MRMSrcMem, (outs VR128:$dst),
6445                     (ins VR128:$src1, x86memop:$src2),
6446                     !strconcat(OpcodeStr,
6447                      "\t{%xmm0, $src2, $dst|$dst, $src2, xmm0}"),
6448                     [(set VR128:$dst,
6449                       (IntId VR128:$src1,
6450                        (bitconvert (mem_frag addr:$src2)), XMM0))]>,
6451                     Sched<[sched.Folded, ReadAfterLd]>;
6452   }
6453 }
6454
6455 let ExeDomain = SSEPackedDouble in
6456 defm BLENDVPD : SS41I_ternary_int<0x15, "blendvpd", memopv2f64, f128mem,
6457                                   int_x86_sse41_blendvpd, SchedWriteFVarBlend.XMM>;
6458 let ExeDomain = SSEPackedSingle in
6459 defm BLENDVPS : SS41I_ternary_int<0x14, "blendvps", memopv4f32, f128mem,
6460                                   int_x86_sse41_blendvps, SchedWriteFVarBlend.XMM>;
6461 defm PBLENDVB : SS41I_ternary_int<0x10, "pblendvb", memopv2i64, i128mem,
6462                                   int_x86_sse41_pblendvb, SchedWriteVarBlend.XMM>;
6463
6464 // Aliases with the implicit xmm0 argument
6465 def : InstAlias<"blendvpd\t{$src2, $dst|$dst, $src2}",
6466                 (BLENDVPDrr0 VR128:$dst, VR128:$src2), 0>;
6467 def : InstAlias<"blendvpd\t{$src2, $dst|$dst, $src2}",
6468                 (BLENDVPDrm0 VR128:$dst, f128mem:$src2), 0>;
6469 def : InstAlias<"blendvps\t{$src2, $dst|$dst, $src2}",
6470                 (BLENDVPSrr0 VR128:$dst, VR128:$src2), 0>;
6471 def : InstAlias<"blendvps\t{$src2, $dst|$dst, $src2}",
6472                 (BLENDVPSrm0 VR128:$dst, f128mem:$src2), 0>;
6473 def : InstAlias<"pblendvb\t{$src2, $dst|$dst, $src2}",
6474                 (PBLENDVBrr0 VR128:$dst, VR128:$src2), 0>;
6475 def : InstAlias<"pblendvb\t{$src2, $dst|$dst, $src2}",
6476                 (PBLENDVBrm0 VR128:$dst, i128mem:$src2), 0>;
6477
6478 let Predicates = [UseSSE41] in {
6479   def : Pat<(v16i8 (vselect (v16i8 XMM0), (v16i8 VR128:$src1),
6480                             (v16i8 VR128:$src2))),
6481             (PBLENDVBrr0 VR128:$src2, VR128:$src1)>;
6482   def : Pat<(v4i32 (vselect (v4i32 XMM0), (v4i32 VR128:$src1),
6483                             (v4i32 VR128:$src2))),
6484             (BLENDVPSrr0 VR128:$src2, VR128:$src1)>;
6485   def : Pat<(v4f32 (vselect (v4i32 XMM0), (v4f32 VR128:$src1),
6486                             (v4f32 VR128:$src2))),
6487             (BLENDVPSrr0 VR128:$src2, VR128:$src1)>;
6488   def : Pat<(v2i64 (vselect (v2i64 XMM0), (v2i64 VR128:$src1),
6489                             (v2i64 VR128:$src2))),
6490             (BLENDVPDrr0 VR128:$src2, VR128:$src1)>;
6491   def : Pat<(v2f64 (vselect (v2i64 XMM0), (v2f64 VR128:$src1),
6492                             (v2f64 VR128:$src2))),
6493             (BLENDVPDrr0 VR128:$src2, VR128:$src1)>;
6494 }
6495
6496 let AddedComplexity = 400 in { // Prefer non-temporal versions
6497
6498 let Predicates = [HasAVX, NoVLX] in
6499 def VMOVNTDQArm : SS48I<0x2A, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
6500                         "vmovntdqa\t{$src, $dst|$dst, $src}", []>,
6501                         Sched<[SchedWriteVecMoveLSNT.XMM.RM]>, VEX, VEX_WIG;
6502 let Predicates = [HasAVX2, NoVLX] in
6503 def VMOVNTDQAYrm : SS48I<0x2A, MRMSrcMem, (outs VR256:$dst), (ins i256mem:$src),
6504                          "vmovntdqa\t{$src, $dst|$dst, $src}", []>,
6505                          Sched<[SchedWriteVecMoveLSNT.YMM.RM]>, VEX, VEX_L, VEX_WIG;
6506 def MOVNTDQArm : SS48I<0x2A, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
6507                        "movntdqa\t{$src, $dst|$dst, $src}", []>,
6508                        Sched<[SchedWriteVecMoveLSNT.XMM.RM]>;
6509
6510 let Predicates = [HasAVX2, NoVLX] in {
6511   def : Pat<(v8f32 (alignednontemporalload addr:$src)),
6512             (VMOVNTDQAYrm addr:$src)>;
6513   def : Pat<(v4f64 (alignednontemporalload addr:$src)),
6514             (VMOVNTDQAYrm addr:$src)>;
6515   def : Pat<(v4i64 (alignednontemporalload addr:$src)),
6516             (VMOVNTDQAYrm addr:$src)>;
6517 }
6518
6519 let Predicates = [HasAVX, NoVLX] in {
6520   def : Pat<(v4f32 (alignednontemporalload addr:$src)),
6521             (VMOVNTDQArm addr:$src)>;
6522   def : Pat<(v2f64 (alignednontemporalload addr:$src)),
6523             (VMOVNTDQArm addr:$src)>;
6524   def : Pat<(v2i64 (alignednontemporalload addr:$src)),
6525             (VMOVNTDQArm addr:$src)>;
6526 }
6527
6528 let Predicates = [UseSSE41] in {
6529   def : Pat<(v4f32 (alignednontemporalload addr:$src)),
6530             (MOVNTDQArm addr:$src)>;
6531   def : Pat<(v2f64 (alignednontemporalload addr:$src)),
6532             (MOVNTDQArm addr:$src)>;
6533   def : Pat<(v2i64 (alignednontemporalload addr:$src)),
6534             (MOVNTDQArm addr:$src)>;
6535 }
6536
6537 } // AddedComplexity
6538
6539 //===----------------------------------------------------------------------===//
6540 // SSE4.2 - Compare Instructions
6541 //===----------------------------------------------------------------------===//
6542
6543 /// SS42I_binop_rm - Simple SSE 4.2 binary operator
6544 multiclass SS42I_binop_rm<bits<8> opc, string OpcodeStr, SDNode OpNode,
6545                           ValueType OpVT, RegisterClass RC, PatFrag memop_frag,
6546                           X86MemOperand x86memop, X86FoldableSchedWrite sched,
6547                           bit Is2Addr = 1> {
6548   def rr : SS428I<opc, MRMSrcReg, (outs RC:$dst),
6549        (ins RC:$src1, RC:$src2),
6550        !if(Is2Addr,
6551            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
6552            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
6553        [(set RC:$dst, (OpVT (OpNode RC:$src1, RC:$src2)))]>,
6554        Sched<[sched]>;
6555   def rm : SS428I<opc, MRMSrcMem, (outs RC:$dst),
6556        (ins RC:$src1, x86memop:$src2),
6557        !if(Is2Addr,
6558            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
6559            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
6560        [(set RC:$dst,
6561          (OpVT (OpNode RC:$src1, (memop_frag addr:$src2))))]>,
6562        Sched<[sched.Folded, ReadAfterLd]>;
6563 }
6564
6565 let Predicates = [HasAVX] in
6566   defm VPCMPGTQ : SS42I_binop_rm<0x37, "vpcmpgtq", X86pcmpgt, v2i64, VR128,
6567                                  loadv2i64, i128mem, SchedWriteVecALU.XMM, 0>,
6568                                  VEX_4V, VEX_WIG;
6569
6570 let Predicates = [HasAVX2] in
6571   defm VPCMPGTQY : SS42I_binop_rm<0x37, "vpcmpgtq", X86pcmpgt, v4i64, VR256,
6572                                   loadv4i64, i256mem, SchedWriteVecALU.YMM, 0>,
6573                                   VEX_4V, VEX_L, VEX_WIG;
6574
6575 let Constraints = "$src1 = $dst" in
6576   defm PCMPGTQ : SS42I_binop_rm<0x37, "pcmpgtq", X86pcmpgt, v2i64, VR128,
6577                                 memopv2i64, i128mem, SchedWriteVecALU.XMM>;
6578
6579 //===----------------------------------------------------------------------===//
6580 // SSE4.2 - String/text Processing Instructions
6581 //===----------------------------------------------------------------------===//
6582
6583 multiclass pcmpistrm_SS42AI<string asm> {
6584   def rr : SS42AI<0x62, MRMSrcReg, (outs),
6585     (ins VR128:$src1, VR128:$src2, u8imm:$src3),
6586     !strconcat(asm, "\t{$src3, $src2, $src1|$src1, $src2, $src3}"),
6587     []>, Sched<[WritePCmpIStrM]>;
6588   let mayLoad = 1 in
6589   def rm :SS42AI<0x62, MRMSrcMem, (outs),
6590     (ins VR128:$src1, i128mem:$src2, u8imm:$src3),
6591     !strconcat(asm, "\t{$src3, $src2, $src1|$src1, $src2, $src3}"),
6592     []>, Sched<[WritePCmpIStrM.Folded, ReadAfterLd]>;
6593 }
6594
6595 let Defs = [XMM0, EFLAGS], hasSideEffects = 0 in {
6596   let Predicates = [HasAVX] in
6597   defm VPCMPISTRM : pcmpistrm_SS42AI<"vpcmpistrm">, VEX;
6598   defm PCMPISTRM  : pcmpistrm_SS42AI<"pcmpistrm"> ;
6599 }
6600
6601 multiclass SS42AI_pcmpestrm<string asm> {
6602   def rr : SS42AI<0x60, MRMSrcReg, (outs),
6603     (ins VR128:$src1, VR128:$src3, u8imm:$src5),
6604     !strconcat(asm, "\t{$src5, $src3, $src1|$src1, $src3, $src5}"),
6605     []>, Sched<[WritePCmpEStrM]>;
6606   let mayLoad = 1 in
6607   def rm : SS42AI<0x60, MRMSrcMem, (outs),
6608     (ins VR128:$src1, i128mem:$src3, u8imm:$src5),
6609     !strconcat(asm, "\t{$src5, $src3, $src1|$src1, $src3, $src5}"),
6610     []>, Sched<[WritePCmpEStrM.Folded, ReadAfterLd]>;
6611 }
6612
6613 let Defs = [XMM0, EFLAGS], Uses = [EAX, EDX], hasSideEffects = 0 in {
6614   let Predicates = [HasAVX] in
6615   defm VPCMPESTRM : SS42AI_pcmpestrm<"vpcmpestrm">, VEX;
6616   defm PCMPESTRM :  SS42AI_pcmpestrm<"pcmpestrm">;
6617 }
6618
6619 multiclass SS42AI_pcmpistri<string asm> {
6620   def rr : SS42AI<0x63, MRMSrcReg, (outs),
6621     (ins VR128:$src1, VR128:$src2, u8imm:$src3),
6622     !strconcat(asm, "\t{$src3, $src2, $src1|$src1, $src2, $src3}"),
6623     []>, Sched<[WritePCmpIStrI]>;
6624   let mayLoad = 1 in
6625   def rm : SS42AI<0x63, MRMSrcMem, (outs),
6626     (ins VR128:$src1, i128mem:$src2, u8imm:$src3),
6627     !strconcat(asm, "\t{$src3, $src2, $src1|$src1, $src2, $src3}"),
6628     []>, Sched<[WritePCmpIStrI.Folded, ReadAfterLd]>;
6629 }
6630
6631 let Defs = [ECX, EFLAGS], hasSideEffects = 0 in {
6632   let Predicates = [HasAVX] in
6633   defm VPCMPISTRI : SS42AI_pcmpistri<"vpcmpistri">, VEX;
6634   defm PCMPISTRI  : SS42AI_pcmpistri<"pcmpistri">;
6635 }
6636
6637 multiclass SS42AI_pcmpestri<string asm> {
6638   def rr : SS42AI<0x61, MRMSrcReg, (outs),
6639     (ins VR128:$src1, VR128:$src3, u8imm:$src5),
6640     !strconcat(asm, "\t{$src5, $src3, $src1|$src1, $src3, $src5}"),
6641     []>, Sched<[WritePCmpEStrI]>;
6642   let mayLoad = 1 in
6643   def rm : SS42AI<0x61, MRMSrcMem, (outs),
6644     (ins VR128:$src1, i128mem:$src3, u8imm:$src5),
6645     !strconcat(asm, "\t{$src5, $src3, $src1|$src1, $src3, $src5}"),
6646     []>, Sched<[WritePCmpEStrI.Folded, ReadAfterLd]>;
6647 }
6648
6649 let Defs = [ECX, EFLAGS], Uses = [EAX, EDX], hasSideEffects = 0 in {
6650   let Predicates = [HasAVX] in
6651   defm VPCMPESTRI : SS42AI_pcmpestri<"vpcmpestri">, VEX;
6652   defm PCMPESTRI  : SS42AI_pcmpestri<"pcmpestri">;
6653 }
6654
6655 //===----------------------------------------------------------------------===//
6656 // SSE4.2 - CRC Instructions
6657 //===----------------------------------------------------------------------===//
6658
6659 // No CRC instructions have AVX equivalents
6660
6661 // crc intrinsic instruction
6662 // This set of instructions are only rm, the only difference is the size
6663 // of r and m.
6664 class SS42I_crc32r<bits<8> opc, string asm, RegisterClass RCOut,
6665                    RegisterClass RCIn, SDPatternOperator Int> :
6666   SS42FI<opc, MRMSrcReg, (outs RCOut:$dst), (ins RCOut:$src1, RCIn:$src2),
6667          !strconcat(asm, "\t{$src2, $src1|$src1, $src2}"),
6668          [(set RCOut:$dst, (Int RCOut:$src1, RCIn:$src2))]>,
6669          Sched<[WriteCRC32]>;
6670
6671 class SS42I_crc32m<bits<8> opc, string asm, RegisterClass RCOut,
6672                    X86MemOperand x86memop, SDPatternOperator Int> :
6673   SS42FI<opc, MRMSrcMem, (outs RCOut:$dst), (ins RCOut:$src1, x86memop:$src2),
6674          !strconcat(asm, "\t{$src2, $src1|$src1, $src2}"),
6675          [(set RCOut:$dst, (Int RCOut:$src1, (load addr:$src2)))]>,
6676          Sched<[WriteCRC32.Folded, ReadAfterLd]>;
6677
6678 let Constraints = "$src1 = $dst" in {
6679   def CRC32r32m8  : SS42I_crc32m<0xF0, "crc32{b}", GR32, i8mem,
6680                                  int_x86_sse42_crc32_32_8>;
6681   def CRC32r32r8  : SS42I_crc32r<0xF0, "crc32{b}", GR32, GR8,
6682                                  int_x86_sse42_crc32_32_8>;
6683   def CRC32r32m16 : SS42I_crc32m<0xF1, "crc32{w}", GR32, i16mem,
6684                                  int_x86_sse42_crc32_32_16>, OpSize16;
6685   def CRC32r32r16 : SS42I_crc32r<0xF1, "crc32{w}", GR32, GR16,
6686                                  int_x86_sse42_crc32_32_16>, OpSize16;
6687   def CRC32r32m32 : SS42I_crc32m<0xF1, "crc32{l}", GR32, i32mem,
6688                                  int_x86_sse42_crc32_32_32>, OpSize32;
6689   def CRC32r32r32 : SS42I_crc32r<0xF1, "crc32{l}", GR32, GR32,
6690                                  int_x86_sse42_crc32_32_32>, OpSize32;
6691   def CRC32r64m64 : SS42I_crc32m<0xF1, "crc32{q}", GR64, i64mem,
6692                                  int_x86_sse42_crc32_64_64>, REX_W;
6693   def CRC32r64r64 : SS42I_crc32r<0xF1, "crc32{q}", GR64, GR64,
6694                                  int_x86_sse42_crc32_64_64>, REX_W;
6695   let hasSideEffects = 0 in {
6696     let mayLoad = 1 in
6697     def CRC32r64m8 : SS42I_crc32m<0xF0, "crc32{b}", GR64, i8mem,
6698                                    null_frag>, REX_W;
6699     def CRC32r64r8 : SS42I_crc32r<0xF0, "crc32{b}", GR64, GR8,
6700                                    null_frag>, REX_W;
6701   }
6702 }
6703
6704 //===----------------------------------------------------------------------===//
6705 // SHA-NI Instructions
6706 //===----------------------------------------------------------------------===//
6707
6708 // FIXME: Is there a better scheduler class for SHA than WriteVecIMul?
6709 multiclass SHAI_binop<bits<8> Opc, string OpcodeStr, Intrinsic IntId,
6710                       X86FoldableSchedWrite sched, bit UsesXMM0 = 0> {
6711   def rr : I<Opc, MRMSrcReg, (outs VR128:$dst),
6712              (ins VR128:$src1, VR128:$src2),
6713              !if(UsesXMM0,
6714                  !strconcat(OpcodeStr, "\t{%xmm0, $src2, $dst|$dst, $src2, xmm0}"),
6715                  !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}")),
6716              [!if(UsesXMM0,
6717                   (set VR128:$dst, (IntId VR128:$src1, VR128:$src2, XMM0)),
6718                   (set VR128:$dst, (IntId VR128:$src1, VR128:$src2)))]>,
6719              T8, Sched<[sched]>;
6720
6721   def rm : I<Opc, MRMSrcMem, (outs VR128:$dst),
6722              (ins VR128:$src1, i128mem:$src2),
6723              !if(UsesXMM0,
6724                  !strconcat(OpcodeStr, "\t{%xmm0, $src2, $dst|$dst, $src2, xmm0}"),
6725                  !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}")),
6726              [!if(UsesXMM0,
6727                   (set VR128:$dst, (IntId VR128:$src1,
6728                     (bc_v4i32 (memopv2i64 addr:$src2)), XMM0)),
6729                   (set VR128:$dst, (IntId VR128:$src1,
6730                     (bc_v4i32 (memopv2i64 addr:$src2)))))]>, T8,
6731              Sched<[sched.Folded, ReadAfterLd]>;
6732 }
6733
6734 let Constraints = "$src1 = $dst", Predicates = [HasSHA] in {
6735   def SHA1RNDS4rri : Ii8<0xCC, MRMSrcReg, (outs VR128:$dst),
6736                          (ins VR128:$src1, VR128:$src2, u8imm:$src3),
6737                          "sha1rnds4\t{$src3, $src2, $dst|$dst, $src2, $src3}",
6738                          [(set VR128:$dst,
6739                            (int_x86_sha1rnds4 VR128:$src1, VR128:$src2,
6740                             (i8 imm:$src3)))]>, TA,
6741                          Sched<[SchedWriteVecIMul.XMM]>;
6742   def SHA1RNDS4rmi : Ii8<0xCC, MRMSrcMem, (outs VR128:$dst),
6743                          (ins VR128:$src1, i128mem:$src2, u8imm:$src3),
6744                          "sha1rnds4\t{$src3, $src2, $dst|$dst, $src2, $src3}",
6745                          [(set VR128:$dst,
6746                            (int_x86_sha1rnds4 VR128:$src1,
6747                             (bc_v4i32 (memopv2i64 addr:$src2)),
6748                             (i8 imm:$src3)))]>, TA,
6749                          Sched<[SchedWriteVecIMul.XMM.Folded, ReadAfterLd]>;
6750
6751   defm SHA1NEXTE : SHAI_binop<0xC8, "sha1nexte", int_x86_sha1nexte,
6752                               SchedWriteVecIMul.XMM>;
6753   defm SHA1MSG1  : SHAI_binop<0xC9, "sha1msg1", int_x86_sha1msg1,
6754                               SchedWriteVecIMul.XMM>;
6755   defm SHA1MSG2  : SHAI_binop<0xCA, "sha1msg2", int_x86_sha1msg2,
6756                               SchedWriteVecIMul.XMM>;
6757
6758   let Uses=[XMM0] in
6759   defm SHA256RNDS2 : SHAI_binop<0xCB, "sha256rnds2", int_x86_sha256rnds2,
6760                                 SchedWriteVecIMul.XMM, 1>;
6761
6762   defm SHA256MSG1 : SHAI_binop<0xCC, "sha256msg1", int_x86_sha256msg1,
6763                                SchedWriteVecIMul.XMM>;
6764   defm SHA256MSG2 : SHAI_binop<0xCD, "sha256msg2", int_x86_sha256msg2,
6765                                SchedWriteVecIMul.XMM>;
6766 }
6767
6768 // Aliases with explicit %xmm0
6769 def : InstAlias<"sha256rnds2\t{$src2, $dst|$dst, $src2}",
6770                 (SHA256RNDS2rr VR128:$dst, VR128:$src2), 0>;
6771 def : InstAlias<"sha256rnds2\t{$src2, $dst|$dst, $src2}",
6772                 (SHA256RNDS2rm VR128:$dst, i128mem:$src2), 0>;
6773
6774 //===----------------------------------------------------------------------===//
6775 // AES-NI Instructions
6776 //===----------------------------------------------------------------------===//
6777
6778 multiclass AESI_binop_rm_int<bits<8> opc, string OpcodeStr,
6779                              Intrinsic IntId, PatFrag ld_frag,
6780                              bit Is2Addr = 0, RegisterClass RC = VR128,
6781                              X86MemOperand MemOp = i128mem> {
6782   let AsmString = OpcodeStr##
6783                   !if(Is2Addr, "\t{$src2, $dst|$dst, $src2}",
6784                                "\t{$src2, $src1, $dst|$dst, $src1, $src2}") in {
6785     def rr : AES8I<opc, MRMSrcReg, (outs RC:$dst),
6786                    (ins RC:$src1, RC:$src2), "",
6787                    [(set RC:$dst, (IntId RC:$src1, RC:$src2))]>,
6788                    Sched<[WriteAESDecEnc]>;
6789     def rm : AES8I<opc, MRMSrcMem, (outs RC:$dst),
6790                    (ins RC:$src1, MemOp:$src2), "",
6791                    [(set RC:$dst, (IntId RC:$src1, (ld_frag addr:$src2)))]>,
6792                    Sched<[WriteAESDecEnc.Folded, ReadAfterLd]>;
6793   }
6794 }
6795
6796 // Perform One Round of an AES Encryption/Decryption Flow
6797 let Predicates = [HasAVX, NoVLX_Or_NoVAES, HasAES] in {
6798   defm VAESENC          : AESI_binop_rm_int<0xDC, "vaesenc",
6799                          int_x86_aesni_aesenc, loadv2i64>, VEX_4V, VEX_WIG;
6800   defm VAESENCLAST      : AESI_binop_rm_int<0xDD, "vaesenclast",
6801                          int_x86_aesni_aesenclast, loadv2i64>, VEX_4V, VEX_WIG;
6802   defm VAESDEC          : AESI_binop_rm_int<0xDE, "vaesdec",
6803                          int_x86_aesni_aesdec, loadv2i64>, VEX_4V, VEX_WIG;
6804   defm VAESDECLAST      : AESI_binop_rm_int<0xDF, "vaesdeclast",
6805                          int_x86_aesni_aesdeclast, loadv2i64>, VEX_4V, VEX_WIG;
6806 }
6807
6808 let Predicates = [NoVLX, HasVAES] in {
6809   defm VAESENCY         : AESI_binop_rm_int<0xDC, "vaesenc",
6810                          int_x86_aesni_aesenc_256, loadv4i64, 0, VR256,
6811                          i256mem>, VEX_4V, VEX_L, VEX_WIG;
6812   defm VAESENCLASTY     : AESI_binop_rm_int<0xDD, "vaesenclast",
6813                          int_x86_aesni_aesenclast_256, loadv4i64, 0, VR256,
6814                          i256mem>, VEX_4V, VEX_L, VEX_WIG;
6815   defm VAESDECY         : AESI_binop_rm_int<0xDE, "vaesdec",
6816                          int_x86_aesni_aesdec_256, loadv4i64, 0, VR256,
6817                          i256mem>, VEX_4V, VEX_L, VEX_WIG;
6818   defm VAESDECLASTY     : AESI_binop_rm_int<0xDF, "vaesdeclast",
6819                          int_x86_aesni_aesdeclast_256, loadv4i64, 0, VR256,
6820                          i256mem>, VEX_4V, VEX_L, VEX_WIG;
6821 }
6822
6823 let Constraints = "$src1 = $dst" in {
6824   defm AESENC          : AESI_binop_rm_int<0xDC, "aesenc",
6825                          int_x86_aesni_aesenc, memopv2i64, 1>;
6826   defm AESENCLAST      : AESI_binop_rm_int<0xDD, "aesenclast",
6827                          int_x86_aesni_aesenclast, memopv2i64, 1>;
6828   defm AESDEC          : AESI_binop_rm_int<0xDE, "aesdec",
6829                          int_x86_aesni_aesdec, memopv2i64, 1>;
6830   defm AESDECLAST      : AESI_binop_rm_int<0xDF, "aesdeclast",
6831                          int_x86_aesni_aesdeclast, memopv2i64, 1>;
6832 }
6833
6834 // Perform the AES InvMixColumn Transformation
6835 let Predicates = [HasAVX, HasAES] in {
6836   def VAESIMCrr : AES8I<0xDB, MRMSrcReg, (outs VR128:$dst),
6837       (ins VR128:$src1),
6838       "vaesimc\t{$src1, $dst|$dst, $src1}",
6839       [(set VR128:$dst,
6840         (int_x86_aesni_aesimc VR128:$src1))]>, Sched<[WriteAESIMC]>,
6841       VEX, VEX_WIG;
6842   def VAESIMCrm : AES8I<0xDB, MRMSrcMem, (outs VR128:$dst),
6843       (ins i128mem:$src1),
6844       "vaesimc\t{$src1, $dst|$dst, $src1}",
6845       [(set VR128:$dst, (int_x86_aesni_aesimc (loadv2i64 addr:$src1)))]>,
6846       Sched<[WriteAESIMC.Folded]>, VEX, VEX_WIG;
6847 }
6848 def AESIMCrr : AES8I<0xDB, MRMSrcReg, (outs VR128:$dst),
6849   (ins VR128:$src1),
6850   "aesimc\t{$src1, $dst|$dst, $src1}",
6851   [(set VR128:$dst,
6852     (int_x86_aesni_aesimc VR128:$src1))]>, Sched<[WriteAESIMC]>;
6853 def AESIMCrm : AES8I<0xDB, MRMSrcMem, (outs VR128:$dst),
6854   (ins i128mem:$src1),
6855   "aesimc\t{$src1, $dst|$dst, $src1}",
6856   [(set VR128:$dst, (int_x86_aesni_aesimc (memopv2i64 addr:$src1)))]>,
6857   Sched<[WriteAESIMC.Folded]>;
6858
6859 // AES Round Key Generation Assist
6860 let Predicates = [HasAVX, HasAES] in {
6861   def VAESKEYGENASSIST128rr : AESAI<0xDF, MRMSrcReg, (outs VR128:$dst),
6862       (ins VR128:$src1, u8imm:$src2),
6863       "vaeskeygenassist\t{$src2, $src1, $dst|$dst, $src1, $src2}",
6864       [(set VR128:$dst,
6865         (int_x86_aesni_aeskeygenassist VR128:$src1, imm:$src2))]>,
6866       Sched<[WriteAESKeyGen]>, VEX, VEX_WIG;
6867   def VAESKEYGENASSIST128rm : AESAI<0xDF, MRMSrcMem, (outs VR128:$dst),
6868       (ins i128mem:$src1, u8imm:$src2),
6869       "vaeskeygenassist\t{$src2, $src1, $dst|$dst, $src1, $src2}",
6870       [(set VR128:$dst,
6871         (int_x86_aesni_aeskeygenassist (loadv2i64 addr:$src1), imm:$src2))]>,
6872       Sched<[WriteAESKeyGen.Folded]>, VEX, VEX_WIG;
6873 }
6874 def AESKEYGENASSIST128rr : AESAI<0xDF, MRMSrcReg, (outs VR128:$dst),
6875   (ins VR128:$src1, u8imm:$src2),
6876   "aeskeygenassist\t{$src2, $src1, $dst|$dst, $src1, $src2}",
6877   [(set VR128:$dst,
6878     (int_x86_aesni_aeskeygenassist VR128:$src1, imm:$src2))]>,
6879   Sched<[WriteAESKeyGen]>;
6880 def AESKEYGENASSIST128rm : AESAI<0xDF, MRMSrcMem, (outs VR128:$dst),
6881   (ins i128mem:$src1, u8imm:$src2),
6882   "aeskeygenassist\t{$src2, $src1, $dst|$dst, $src1, $src2}",
6883   [(set VR128:$dst,
6884     (int_x86_aesni_aeskeygenassist (memopv2i64 addr:$src1), imm:$src2))]>,
6885   Sched<[WriteAESKeyGen.Folded]>;
6886
6887 //===----------------------------------------------------------------------===//
6888 // PCLMUL Instructions
6889 //===----------------------------------------------------------------------===//
6890
6891 // Immediate transform to help with commuting.
6892 def PCLMULCommuteImm : SDNodeXForm<imm, [{
6893   uint8_t Imm = N->getZExtValue();
6894   return getI8Imm((uint8_t)((Imm >> 4) | (Imm << 4)), SDLoc(N));
6895 }]>;
6896
6897 // SSE carry-less Multiplication instructions
6898 let Predicates = [NoAVX, HasPCLMUL] in {
6899   let Constraints = "$src1 = $dst" in {
6900     let isCommutable = 1 in
6901     def PCLMULQDQrr : PCLMULIi8<0x44, MRMSrcReg, (outs VR128:$dst),
6902               (ins VR128:$src1, VR128:$src2, u8imm:$src3),
6903               "pclmulqdq\t{$src3, $src2, $dst|$dst, $src2, $src3}",
6904               [(set VR128:$dst,
6905                 (int_x86_pclmulqdq VR128:$src1, VR128:$src2, imm:$src3))]>,
6906                 Sched<[WriteCLMul]>;
6907
6908     def PCLMULQDQrm : PCLMULIi8<0x44, MRMSrcMem, (outs VR128:$dst),
6909               (ins VR128:$src1, i128mem:$src2, u8imm:$src3),
6910               "pclmulqdq\t{$src3, $src2, $dst|$dst, $src2, $src3}",
6911               [(set VR128:$dst,
6912                  (int_x86_pclmulqdq VR128:$src1, (memopv2i64 addr:$src2),
6913                   imm:$src3))]>,
6914               Sched<[WriteCLMul.Folded, ReadAfterLd]>;
6915   } // Constraints = "$src1 = $dst"
6916
6917   def : Pat<(int_x86_pclmulqdq (memopv2i64 addr:$src2), VR128:$src1,
6918                                 (i8 imm:$src3)),
6919             (PCLMULQDQrm VR128:$src1, addr:$src2,
6920                           (PCLMULCommuteImm imm:$src3))>;
6921 } // Predicates = [NoAVX, HasPCLMUL]
6922
6923 // SSE aliases
6924 foreach HI = ["hq","lq"] in
6925 foreach LO = ["hq","lq"] in {
6926   def : InstAlias<"pclmul" # HI # LO # "dq\t{$src, $dst|$dst, $src}",
6927                   (PCLMULQDQrr VR128:$dst, VR128:$src,
6928                    !add(!shl(!eq(LO,"hq"),4),!eq(HI,"hq"))), 0>;
6929   def : InstAlias<"pclmul" # HI # LO # "dq\t{$src, $dst|$dst, $src}",
6930                   (PCLMULQDQrm VR128:$dst, i128mem:$src,
6931                    !add(!shl(!eq(LO,"hq"),4),!eq(HI,"hq"))), 0>;
6932 }
6933
6934 // AVX carry-less Multiplication instructions
6935 multiclass vpclmulqdq<RegisterClass RC, X86MemOperand MemOp,
6936                       PatFrag LdFrag, Intrinsic IntId> {
6937   let isCommutable = 1 in
6938   def rr : PCLMULIi8<0x44, MRMSrcReg, (outs RC:$dst),
6939             (ins RC:$src1, RC:$src2, u8imm:$src3),
6940             "vpclmulqdq\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
6941             [(set RC:$dst,
6942               (IntId RC:$src1, RC:$src2, imm:$src3))]>,
6943             Sched<[WriteCLMul]>;
6944
6945   def rm : PCLMULIi8<0x44, MRMSrcMem, (outs RC:$dst),
6946             (ins RC:$src1, MemOp:$src2, u8imm:$src3),
6947             "vpclmulqdq\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
6948             [(set RC:$dst,
6949                (IntId RC:$src1, (LdFrag addr:$src2), imm:$src3))]>,
6950             Sched<[WriteCLMul.Folded, ReadAfterLd]>;
6951
6952   // We can commute a load in the first operand by swapping the sources and
6953   // rotating the immediate.
6954   def : Pat<(IntId (LdFrag addr:$src2), RC:$src1, (i8 imm:$src3)),
6955             (!cast<Instruction>(NAME#"rm") RC:$src1, addr:$src2,
6956                                            (PCLMULCommuteImm imm:$src3))>;
6957 }
6958
6959 let Predicates = [HasAVX, NoVLX_Or_NoVPCLMULQDQ, HasPCLMUL] in
6960 defm VPCLMULQDQ : vpclmulqdq<VR128, i128mem, loadv2i64,
6961                              int_x86_pclmulqdq>, VEX_4V, VEX_WIG;
6962
6963 let Predicates = [NoVLX, HasVPCLMULQDQ] in
6964 defm VPCLMULQDQY : vpclmulqdq<VR256, i256mem, loadv4i64,
6965                               int_x86_pclmulqdq_256>, VEX_4V, VEX_L, VEX_WIG;
6966
6967 multiclass vpclmulqdq_aliases_impl<string InstStr, RegisterClass RC,
6968                                    X86MemOperand MemOp, string Hi, string Lo> {
6969   def : InstAlias<"vpclmul"##Hi##Lo##"dq\t{$src2, $src1, $dst|$dst, $src1, $src2}",
6970                   (!cast<Instruction>(InstStr # "rr") RC:$dst, RC:$src1, RC:$src2,
6971                         !add(!shl(!eq(Lo,"hq"),4),!eq(Hi,"hq"))), 0>;
6972   def : InstAlias<"vpclmul"##Hi##Lo##"dq\t{$src2, $src1, $dst|$dst, $src1, $src2}",
6973                   (!cast<Instruction>(InstStr # "rm") RC:$dst, RC:$src1, MemOp:$src2,
6974                         !add(!shl(!eq(Lo,"hq"),4),!eq(Hi,"hq"))), 0>;
6975 }
6976
6977 multiclass vpclmulqdq_aliases<string InstStr, RegisterClass RC,
6978                               X86MemOperand MemOp> {
6979   defm : vpclmulqdq_aliases_impl<InstStr, RC, MemOp, "hq", "hq">;
6980   defm : vpclmulqdq_aliases_impl<InstStr, RC, MemOp, "hq", "lq">;
6981   defm : vpclmulqdq_aliases_impl<InstStr, RC, MemOp, "lq", "hq">;
6982   defm : vpclmulqdq_aliases_impl<InstStr, RC, MemOp, "lq", "lq">;
6983 }
6984
6985 // AVX aliases
6986 defm : vpclmulqdq_aliases<"VPCLMULQDQ", VR128, i128mem>;
6987 defm : vpclmulqdq_aliases<"VPCLMULQDQY", VR256, i256mem>;
6988
6989 //===----------------------------------------------------------------------===//
6990 // SSE4A Instructions
6991 //===----------------------------------------------------------------------===//
6992
6993 let Predicates = [HasSSE4A] in {
6994
6995 let ExeDomain = SSEPackedInt in {
6996 let Constraints = "$src = $dst" in {
6997 def EXTRQI : Ii8<0x78, MRMXr, (outs VR128:$dst),
6998                  (ins VR128:$src, u8imm:$len, u8imm:$idx),
6999                  "extrq\t{$idx, $len, $src|$src, $len, $idx}",
7000                  [(set VR128:$dst, (X86extrqi VR128:$src, imm:$len,
7001                                     imm:$idx))]>,
7002                  PD, Sched<[SchedWriteVecALU.XMM]>;
7003 def EXTRQ  : I<0x79, MRMSrcReg, (outs VR128:$dst),
7004               (ins VR128:$src, VR128:$mask),
7005               "extrq\t{$mask, $src|$src, $mask}",
7006               [(set VR128:$dst, (int_x86_sse4a_extrq VR128:$src,
7007                                  VR128:$mask))]>,
7008               PD, Sched<[SchedWriteVecALU.XMM]>;
7009
7010 def INSERTQI : Ii8<0x78, MRMSrcReg, (outs VR128:$dst),
7011                    (ins VR128:$src, VR128:$src2, u8imm:$len, u8imm:$idx),
7012                    "insertq\t{$idx, $len, $src2, $src|$src, $src2, $len, $idx}",
7013                    [(set VR128:$dst, (X86insertqi VR128:$src, VR128:$src2,
7014                                       imm:$len, imm:$idx))]>,
7015                    XD, Sched<[SchedWriteVecALU.XMM]>;
7016 def INSERTQ  : I<0x79, MRMSrcReg, (outs VR128:$dst),
7017                  (ins VR128:$src, VR128:$mask),
7018                  "insertq\t{$mask, $src|$src, $mask}",
7019                  [(set VR128:$dst, (int_x86_sse4a_insertq VR128:$src,
7020                                     VR128:$mask))]>,
7021                  XD, Sched<[SchedWriteVecALU.XMM]>;
7022 }
7023 } // ExeDomain = SSEPackedInt
7024
7025 // Non-temporal (unaligned) scalar stores.
7026 let AddedComplexity = 400 in { // Prefer non-temporal versions
7027 let hasSideEffects = 0, mayStore = 1, SchedRW = [SchedWriteFMoveLSNT.Scl.MR] in {
7028 def MOVNTSS : I<0x2B, MRMDestMem, (outs), (ins f32mem:$dst, VR128:$src),
7029                 "movntss\t{$src, $dst|$dst, $src}", []>, XS;
7030
7031 def MOVNTSD : I<0x2B, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
7032                 "movntsd\t{$src, $dst|$dst, $src}", []>, XD;
7033 } // SchedRW
7034
7035 def : Pat<(nontemporalstore FR32:$src, addr:$dst),
7036           (MOVNTSS addr:$dst, (COPY_TO_REGCLASS FR32:$src, VR128))>;
7037
7038 def : Pat<(nontemporalstore FR64:$src, addr:$dst),
7039           (MOVNTSD addr:$dst, (COPY_TO_REGCLASS FR64:$src, VR128))>;
7040
7041 } // AddedComplexity
7042 } // HasSSE4A
7043
7044 //===----------------------------------------------------------------------===//
7045 // AVX Instructions
7046 //===----------------------------------------------------------------------===//
7047
7048 //===----------------------------------------------------------------------===//
7049 // VBROADCAST - Load from memory and broadcast to all elements of the
7050 //              destination operand
7051 //
7052 class avx_broadcast_rm<bits<8> opc, string OpcodeStr, RegisterClass RC,
7053                            X86MemOperand x86memop, ValueType VT,
7054                            PatFrag ld_frag, SchedWrite Sched> :
7055   AVX8I<opc, MRMSrcMem, (outs RC:$dst), (ins x86memop:$src),
7056         !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
7057         [(set RC:$dst, (VT (X86VBroadcast (ld_frag addr:$src))))]>,
7058         Sched<[Sched]>, VEX;
7059
7060 // AVX2 adds register forms
7061 class avx2_broadcast_rr<bits<8> opc, string OpcodeStr, RegisterClass RC,
7062                         ValueType ResVT, ValueType OpVT, SchedWrite Sched> :
7063   AVX28I<opc, MRMSrcReg, (outs RC:$dst), (ins VR128:$src),
7064          !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
7065          [(set RC:$dst, (ResVT (X86VBroadcast (OpVT VR128:$src))))]>,
7066          Sched<[Sched]>, VEX;
7067
7068 let ExeDomain = SSEPackedSingle, Predicates = [HasAVX, NoVLX] in {
7069   def VBROADCASTSSrm  : avx_broadcast_rm<0x18, "vbroadcastss", VR128,
7070                                          f32mem, v4f32, loadf32,
7071                                          SchedWriteFShuffle.XMM.Folded>;
7072   def VBROADCASTSSYrm : avx_broadcast_rm<0x18, "vbroadcastss", VR256,
7073                                          f32mem, v8f32, loadf32,
7074                                          SchedWriteFShuffle.XMM.Folded>, VEX_L;
7075 }
7076 let ExeDomain = SSEPackedDouble, Predicates = [HasAVX, NoVLX] in
7077 def VBROADCASTSDYrm  : avx_broadcast_rm<0x19, "vbroadcastsd", VR256, f64mem,
7078                                         v4f64, loadf64,
7079                                         SchedWriteFShuffle.XMM.Folded>, VEX_L;
7080
7081 let ExeDomain = SSEPackedSingle, Predicates = [HasAVX2, NoVLX] in {
7082   def VBROADCASTSSrr  : avx2_broadcast_rr<0x18, "vbroadcastss", VR128,
7083                                           v4f32, v4f32, SchedWriteFShuffle.XMM>;
7084   def VBROADCASTSSYrr : avx2_broadcast_rr<0x18, "vbroadcastss", VR256,
7085                                           v8f32, v4f32, WriteFShuffle256>, VEX_L;
7086 }
7087 let ExeDomain = SSEPackedDouble, Predicates = [HasAVX2, NoVLX] in
7088 def VBROADCASTSDYrr  : avx2_broadcast_rr<0x19, "vbroadcastsd", VR256,
7089                                          v4f64, v2f64, WriteFShuffle256>, VEX_L;
7090
7091 let Predicates = [HasAVX, NoVLX] in {
7092   def : Pat<(v4f32 (X86VBroadcast (v4f32 (scalar_to_vector (loadf32 addr:$src))))),
7093             (VBROADCASTSSrm addr:$src)>;
7094   def : Pat<(v8f32 (X86VBroadcast (v4f32 (scalar_to_vector (loadf32 addr:$src))))),
7095             (VBROADCASTSSYrm addr:$src)>;
7096   def : Pat<(v4f64 (X86VBroadcast (v2f64 (scalar_to_vector (loadf64 addr:$src))))),
7097             (VBROADCASTSDYrm addr:$src)>;
7098 }
7099
7100 //===----------------------------------------------------------------------===//
7101 // VBROADCAST*128 - Load from memory and broadcast 128-bit vector to both
7102 //                  halves of a 256-bit vector.
7103 //
7104 let mayLoad = 1, hasSideEffects = 0, Predicates = [HasAVX2] in
7105 def VBROADCASTI128 : AVX8I<0x5A, MRMSrcMem, (outs VR256:$dst),
7106                            (ins i128mem:$src),
7107                            "vbroadcasti128\t{$src, $dst|$dst, $src}", []>,
7108                            Sched<[WriteShuffleLd]>, VEX, VEX_L;
7109
7110 let mayLoad = 1, hasSideEffects = 0, Predicates = [HasAVX],
7111     ExeDomain = SSEPackedSingle in
7112 def VBROADCASTF128 : AVX8I<0x1A, MRMSrcMem, (outs VR256:$dst),
7113                            (ins f128mem:$src),
7114                            "vbroadcastf128\t{$src, $dst|$dst, $src}", []>,
7115                            Sched<[SchedWriteFShuffle.XMM.Folded]>, VEX, VEX_L;
7116
7117 let Predicates = [HasAVX2, NoVLX] in {
7118 def : Pat<(v4i64 (X86SubVBroadcast (loadv2i64 addr:$src))),
7119           (VBROADCASTI128 addr:$src)>;
7120 def : Pat<(v8i32 (X86SubVBroadcast (bc_v4i32 (loadv2i64 addr:$src)))),
7121           (VBROADCASTI128 addr:$src)>;
7122 def : Pat<(v16i16 (X86SubVBroadcast (bc_v8i16 (loadv2i64 addr:$src)))),
7123           (VBROADCASTI128 addr:$src)>;
7124 def : Pat<(v32i8 (X86SubVBroadcast (bc_v16i8 (loadv2i64 addr:$src)))),
7125           (VBROADCASTI128 addr:$src)>;
7126 }
7127
7128 let Predicates = [HasAVX, NoVLX] in {
7129 def : Pat<(v4f64 (X86SubVBroadcast (loadv2f64 addr:$src))),
7130           (VBROADCASTF128 addr:$src)>;
7131 def : Pat<(v8f32 (X86SubVBroadcast (loadv4f32 addr:$src))),
7132           (VBROADCASTF128 addr:$src)>;
7133 }
7134
7135 let Predicates = [HasAVX1Only] in {
7136 def : Pat<(v4i64 (X86SubVBroadcast (loadv2i64 addr:$src))),
7137           (VBROADCASTF128 addr:$src)>;
7138 def : Pat<(v8i32 (X86SubVBroadcast (bc_v4i32 (loadv2i64 addr:$src)))),
7139           (VBROADCASTF128 addr:$src)>;
7140 def : Pat<(v16i16 (X86SubVBroadcast (bc_v8i16 (loadv2i64 addr:$src)))),
7141           (VBROADCASTF128 addr:$src)>;
7142 def : Pat<(v32i8 (X86SubVBroadcast (bc_v16i8 (loadv2i64 addr:$src)))),
7143           (VBROADCASTF128 addr:$src)>;
7144 }
7145
7146 //===----------------------------------------------------------------------===//
7147 // VINSERTF128 - Insert packed floating-point values
7148 //
7149 let hasSideEffects = 0, ExeDomain = SSEPackedSingle in {
7150 def VINSERTF128rr : AVXAIi8<0x18, MRMSrcReg, (outs VR256:$dst),
7151           (ins VR256:$src1, VR128:$src2, u8imm:$src3),
7152           "vinsertf128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
7153           []>, Sched<[WriteFShuffle256]>, VEX_4V, VEX_L;
7154 let mayLoad = 1 in
7155 def VINSERTF128rm : AVXAIi8<0x18, MRMSrcMem, (outs VR256:$dst),
7156           (ins VR256:$src1, f128mem:$src2, u8imm:$src3),
7157           "vinsertf128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
7158           []>, Sched<[WriteFShuffle256Ld, ReadAfterLd]>, VEX_4V, VEX_L;
7159 }
7160
7161 // To create a 256-bit all ones value, we should produce VCMPTRUEPS
7162 // with YMM register containing zero.
7163 // FIXME: Avoid producing vxorps to clear the fake inputs.
7164 let Predicates = [HasAVX1Only] in {
7165 def : Pat<(v8i32 immAllOnesV), (VCMPPSYrri (AVX_SET0), (AVX_SET0), 0xf)>;
7166 }
7167
7168 multiclass vinsert_lowering<string InstrStr, ValueType From, ValueType To,
7169                             PatFrag memop_frag> {
7170   def : Pat<(vinsert128_insert:$ins (To VR256:$src1), (From VR128:$src2),
7171                                    (iPTR imm)),
7172             (!cast<Instruction>(InstrStr#rr) VR256:$src1, VR128:$src2,
7173                                        (INSERT_get_vinsert128_imm VR256:$ins))>;
7174   def : Pat<(vinsert128_insert:$ins (To VR256:$src1),
7175                                     (From (bitconvert (memop_frag addr:$src2))),
7176                                     (iPTR imm)),
7177             (!cast<Instruction>(InstrStr#rm) VR256:$src1, addr:$src2,
7178                                        (INSERT_get_vinsert128_imm VR256:$ins))>;
7179 }
7180
7181 let Predicates = [HasAVX, NoVLX] in {
7182   defm : vinsert_lowering<"VINSERTF128", v4f32, v8f32, loadv4f32>;
7183   defm : vinsert_lowering<"VINSERTF128", v2f64, v4f64, loadv2f64>;
7184 }
7185
7186 let Predicates = [HasAVX1Only] in {
7187   defm : vinsert_lowering<"VINSERTF128", v2i64, v4i64,  loadv2i64>;
7188   defm : vinsert_lowering<"VINSERTF128", v4i32, v8i32,  loadv2i64>;
7189   defm : vinsert_lowering<"VINSERTF128", v8i16, v16i16, loadv2i64>;
7190   defm : vinsert_lowering<"VINSERTF128", v16i8, v32i8,  loadv2i64>;
7191 }
7192
7193 //===----------------------------------------------------------------------===//
7194 // VEXTRACTF128 - Extract packed floating-point values
7195 //
7196 let hasSideEffects = 0, ExeDomain = SSEPackedSingle in {
7197 def VEXTRACTF128rr : AVXAIi8<0x19, MRMDestReg, (outs VR128:$dst),
7198           (ins VR256:$src1, u8imm:$src2),
7199           "vextractf128\t{$src2, $src1, $dst|$dst, $src1, $src2}",
7200           []>, Sched<[WriteFShuffle256]>, VEX, VEX_L;
7201 let mayStore = 1 in
7202 def VEXTRACTF128mr : AVXAIi8<0x19, MRMDestMem, (outs),
7203           (ins f128mem:$dst, VR256:$src1, u8imm:$src2),
7204           "vextractf128\t{$src2, $src1, $dst|$dst, $src1, $src2}",
7205           []>, Sched<[WriteFStoreX]>, VEX, VEX_L;
7206 }
7207
7208 multiclass vextract_lowering<string InstrStr, ValueType From, ValueType To> {
7209   def : Pat<(vextract128_extract:$ext VR256:$src1, (iPTR imm)),
7210             (To (!cast<Instruction>(InstrStr#rr)
7211                                     (From VR256:$src1),
7212                                     (EXTRACT_get_vextract128_imm VR128:$ext)))>;
7213   def : Pat<(store (To (vextract128_extract:$ext (From VR256:$src1),
7214                                                  (iPTR imm))), addr:$dst),
7215             (!cast<Instruction>(InstrStr#mr) addr:$dst, VR256:$src1,
7216              (EXTRACT_get_vextract128_imm VR128:$ext))>;
7217 }
7218
7219 // AVX1 patterns
7220 let Predicates = [HasAVX, NoVLX] in {
7221   defm : vextract_lowering<"VEXTRACTF128", v8f32, v4f32>;
7222   defm : vextract_lowering<"VEXTRACTF128", v4f64, v2f64>;
7223 }
7224
7225 let Predicates = [HasAVX1Only] in {
7226   defm : vextract_lowering<"VEXTRACTF128", v4i64,  v2i64>;
7227   defm : vextract_lowering<"VEXTRACTF128", v8i32,  v4i32>;
7228   defm : vextract_lowering<"VEXTRACTF128", v16i16, v8i16>;
7229   defm : vextract_lowering<"VEXTRACTF128", v32i8,  v16i8>;
7230 }
7231
7232 //===----------------------------------------------------------------------===//
7233 // VMASKMOV - Conditional SIMD Packed Loads and Stores
7234 //
7235 multiclass avx_movmask_rm<bits<8> opc_rm, bits<8> opc_mr, string OpcodeStr,
7236                           Intrinsic IntLd, Intrinsic IntLd256,
7237                           Intrinsic IntSt, Intrinsic IntSt256> {
7238   def rm  : AVX8I<opc_rm, MRMSrcMem, (outs VR128:$dst),
7239              (ins VR128:$src1, f128mem:$src2),
7240              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7241              [(set VR128:$dst, (IntLd addr:$src2, VR128:$src1))]>,
7242              VEX_4V, Sched<[WriteFMaskedLoad]>;
7243   def Yrm : AVX8I<opc_rm, MRMSrcMem, (outs VR256:$dst),
7244              (ins VR256:$src1, f256mem:$src2),
7245              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7246              [(set VR256:$dst, (IntLd256 addr:$src2, VR256:$src1))]>,
7247              VEX_4V, VEX_L, Sched<[WriteFMaskedLoadY]>;
7248   def mr  : AVX8I<opc_mr, MRMDestMem, (outs),
7249              (ins f128mem:$dst, VR128:$src1, VR128:$src2),
7250              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7251              [(IntSt addr:$dst, VR128:$src1, VR128:$src2)]>,
7252              VEX_4V, Sched<[WriteFMaskedStore]>;
7253   def Ymr : AVX8I<opc_mr, MRMDestMem, (outs),
7254              (ins f256mem:$dst, VR256:$src1, VR256:$src2),
7255              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7256              [(IntSt256 addr:$dst, VR256:$src1, VR256:$src2)]>,
7257              VEX_4V, VEX_L, Sched<[WriteFMaskedStoreY]>;
7258 }
7259
7260 let ExeDomain = SSEPackedSingle in
7261 defm VMASKMOVPS : avx_movmask_rm<0x2C, 0x2E, "vmaskmovps",
7262                                  int_x86_avx_maskload_ps,
7263                                  int_x86_avx_maskload_ps_256,
7264                                  int_x86_avx_maskstore_ps,
7265                                  int_x86_avx_maskstore_ps_256>;
7266 let ExeDomain = SSEPackedDouble in
7267 defm VMASKMOVPD : avx_movmask_rm<0x2D, 0x2F, "vmaskmovpd",
7268                                  int_x86_avx_maskload_pd,
7269                                  int_x86_avx_maskload_pd_256,
7270                                  int_x86_avx_maskstore_pd,
7271                                  int_x86_avx_maskstore_pd_256>;
7272
7273 //===----------------------------------------------------------------------===//
7274 // VPERMIL - Permute Single and Double Floating-Point Values
7275 //
7276
7277 multiclass avx_permil<bits<8> opc_rm, bits<8> opc_rmi, string OpcodeStr,
7278                       RegisterClass RC, X86MemOperand x86memop_f,
7279                       X86MemOperand x86memop_i, PatFrag i_frag,
7280                       ValueType f_vt, ValueType i_vt,
7281                       X86FoldableSchedWrite sched,
7282                       X86FoldableSchedWrite varsched> {
7283   let Predicates = [HasAVX, NoVLX] in {
7284     def rr  : AVX8I<opc_rm, MRMSrcReg, (outs RC:$dst),
7285                (ins RC:$src1, RC:$src2),
7286                !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7287                [(set RC:$dst, (f_vt (X86VPermilpv RC:$src1, (i_vt RC:$src2))))]>, VEX_4V,
7288                Sched<[varsched]>;
7289     def rm  : AVX8I<opc_rm, MRMSrcMem, (outs RC:$dst),
7290                (ins RC:$src1, x86memop_i:$src2),
7291                !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7292                [(set RC:$dst, (f_vt (X86VPermilpv RC:$src1,
7293                               (i_vt (bitconvert (i_frag addr:$src2))))))]>, VEX_4V,
7294                Sched<[varsched.Folded, ReadAfterLd]>;
7295
7296     def ri  : AVXAIi8<opc_rmi, MRMSrcReg, (outs RC:$dst),
7297              (ins RC:$src1, u8imm:$src2),
7298              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7299              [(set RC:$dst, (f_vt (X86VPermilpi RC:$src1, (i8 imm:$src2))))]>, VEX,
7300              Sched<[sched]>;
7301     def mi  : AVXAIi8<opc_rmi, MRMSrcMem, (outs RC:$dst),
7302              (ins x86memop_f:$src1, u8imm:$src2),
7303              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7304              [(set RC:$dst,
7305                (f_vt (X86VPermilpi (load addr:$src1), (i8 imm:$src2))))]>, VEX,
7306              Sched<[sched.Folded]>;
7307   }// Predicates = [HasAVX, NoVLX]
7308 }
7309
7310 let ExeDomain = SSEPackedSingle in {
7311   defm VPERMILPS  : avx_permil<0x0C, 0x04, "vpermilps", VR128, f128mem, i128mem,
7312                                loadv2i64, v4f32, v4i32, SchedWriteFShuffle.XMM,
7313                                SchedWriteFVarShuffle.XMM>;
7314   defm VPERMILPSY : avx_permil<0x0C, 0x04, "vpermilps", VR256, f256mem, i256mem,
7315                                loadv4i64, v8f32, v8i32, SchedWriteFShuffle.YMM,
7316                                SchedWriteFVarShuffle.YMM>, VEX_L;
7317 }
7318 let ExeDomain = SSEPackedDouble in {
7319   defm VPERMILPD  : avx_permil<0x0D, 0x05, "vpermilpd", VR128, f128mem, i128mem,
7320                                loadv2i64, v2f64, v2i64, SchedWriteFShuffle.XMM,
7321                                SchedWriteFVarShuffle.XMM>;
7322   defm VPERMILPDY : avx_permil<0x0D, 0x05, "vpermilpd", VR256, f256mem, i256mem,
7323                                loadv4i64, v4f64, v4i64, SchedWriteFShuffle.YMM,
7324                                SchedWriteFVarShuffle.YMM>, VEX_L;
7325 }
7326
7327 //===----------------------------------------------------------------------===//
7328 // VPERM2F128 - Permute Floating-Point Values in 128-bit chunks
7329 //
7330
7331 let ExeDomain = SSEPackedSingle in {
7332 let isCommutable = 1 in
7333 def VPERM2F128rr : AVXAIi8<0x06, MRMSrcReg, (outs VR256:$dst),
7334           (ins VR256:$src1, VR256:$src2, u8imm:$src3),
7335           "vperm2f128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
7336           [(set VR256:$dst, (v4f64 (X86VPerm2x128 VR256:$src1, VR256:$src2,
7337                               (i8 imm:$src3))))]>, VEX_4V, VEX_L,
7338           Sched<[WriteFShuffle256]>;
7339 def VPERM2F128rm : AVXAIi8<0x06, MRMSrcMem, (outs VR256:$dst),
7340           (ins VR256:$src1, f256mem:$src2, u8imm:$src3),
7341           "vperm2f128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
7342           [(set VR256:$dst, (X86VPerm2x128 VR256:$src1, (loadv4f64 addr:$src2),
7343                              (i8 imm:$src3)))]>, VEX_4V, VEX_L,
7344           Sched<[WriteFShuffle256Ld, ReadAfterLd]>;
7345 }
7346
7347 // Immediate transform to help with commuting.
7348 def Perm2XCommuteImm : SDNodeXForm<imm, [{
7349   return getI8Imm(N->getZExtValue() ^ 0x22, SDLoc(N));
7350 }]>;
7351
7352 let Predicates = [HasAVX] in {
7353 // Pattern with load in other operand.
7354 def : Pat<(v4f64 (X86VPerm2x128 (loadv4f64 addr:$src2),
7355                                 VR256:$src1, (i8 imm:$imm))),
7356           (VPERM2F128rm VR256:$src1, addr:$src2, (Perm2XCommuteImm imm:$imm))>;
7357 }
7358
7359 let Predicates = [HasAVX1Only] in {
7360 def : Pat<(v4i64 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
7361           (VPERM2F128rr VR256:$src1, VR256:$src2, imm:$imm)>;
7362 def : Pat<(v4i64 (X86VPerm2x128 VR256:$src1,
7363                   (loadv4i64 addr:$src2), (i8 imm:$imm))),
7364           (VPERM2F128rm VR256:$src1, addr:$src2, imm:$imm)>;
7365 // Pattern with load in other operand.
7366 def : Pat<(v4i64 (X86VPerm2x128 (loadv4i64 addr:$src2),
7367                                 VR256:$src1, (i8 imm:$imm))),
7368           (VPERM2F128rm VR256:$src1, addr:$src2, (Perm2XCommuteImm imm:$imm))>;
7369 }
7370
7371 //===----------------------------------------------------------------------===//
7372 // VZERO - Zero YMM registers
7373 // Note: These instruction do not affect the YMM16-YMM31.
7374 //
7375
7376 let SchedRW = [WriteSystem] in {
7377 let Defs = [YMM0, YMM1, YMM2, YMM3, YMM4, YMM5, YMM6, YMM7,
7378             YMM8, YMM9, YMM10, YMM11, YMM12, YMM13, YMM14, YMM15] in {
7379   // Zero All YMM registers
7380   def VZEROALL : I<0x77, RawFrm, (outs), (ins), "vzeroall",
7381                   [(int_x86_avx_vzeroall)]>, PS, VEX, VEX_L,
7382                   Requires<[HasAVX]>, VEX_WIG;
7383
7384   // Zero Upper bits of YMM registers
7385   def VZEROUPPER : I<0x77, RawFrm, (outs), (ins), "vzeroupper",
7386                      [(int_x86_avx_vzeroupper)]>, PS, VEX,
7387                      Requires<[HasAVX]>, VEX_WIG;
7388 } // Defs
7389 } // SchedRW
7390
7391 //===----------------------------------------------------------------------===//
7392 // Half precision conversion instructions
7393 //
7394
7395 multiclass f16c_ph2ps<RegisterClass RC, X86MemOperand x86memop,
7396                       X86FoldableSchedWrite sched> {
7397   def rr : I<0x13, MRMSrcReg, (outs RC:$dst), (ins VR128:$src),
7398              "vcvtph2ps\t{$src, $dst|$dst, $src}",
7399              [(set RC:$dst, (X86cvtph2ps VR128:$src))]>,
7400              T8PD, VEX, Sched<[sched]>;
7401   let hasSideEffects = 0, mayLoad = 1 in
7402   def rm : I<0x13, MRMSrcMem, (outs RC:$dst), (ins x86memop:$src),
7403              "vcvtph2ps\t{$src, $dst|$dst, $src}",
7404              [(set RC:$dst, (X86cvtph2ps (bc_v8i16
7405                                           (loadv2i64 addr:$src))))]>,
7406              T8PD, VEX, Sched<[sched.Folded]>;
7407 }
7408
7409 multiclass f16c_ps2ph<RegisterClass RC, X86MemOperand x86memop,
7410                       SchedWrite RR, SchedWrite MR> {
7411   def rr : Ii8<0x1D, MRMDestReg, (outs VR128:$dst),
7412                (ins RC:$src1, i32u8imm:$src2),
7413                "vcvtps2ph\t{$src2, $src1, $dst|$dst, $src1, $src2}",
7414                [(set VR128:$dst, (X86cvtps2ph RC:$src1, imm:$src2))]>,
7415                TAPD, VEX, Sched<[RR]>;
7416   let hasSideEffects = 0, mayStore = 1 in
7417   def mr : Ii8<0x1D, MRMDestMem, (outs),
7418                (ins x86memop:$dst, RC:$src1, i32u8imm:$src2),
7419                "vcvtps2ph\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>,
7420                TAPD, VEX, Sched<[MR]>;
7421 }
7422
7423 let Predicates = [HasF16C, NoVLX] in {
7424   defm VCVTPH2PS  : f16c_ph2ps<VR128, f64mem, WriteCvtPH2PS>;
7425   defm VCVTPH2PSY : f16c_ph2ps<VR256, f128mem, WriteCvtPH2PSY>, VEX_L;
7426   defm VCVTPS2PH  : f16c_ps2ph<VR128, f64mem, WriteCvtPS2PH,
7427                                WriteCvtPS2PHSt>;
7428   defm VCVTPS2PHY : f16c_ps2ph<VR256, f128mem, WriteCvtPS2PHY,
7429                                WriteCvtPS2PHYSt>, VEX_L;
7430
7431   // Pattern match vcvtph2ps of a scalar i64 load.
7432   def : Pat<(v4f32 (X86cvtph2ps (v8i16 (vzmovl_v2i64 addr:$src)))),
7433             (VCVTPH2PSrm addr:$src)>;
7434   def : Pat<(v4f32 (X86cvtph2ps (v8i16 (vzload_v2i64 addr:$src)))),
7435             (VCVTPH2PSrm addr:$src)>;
7436   def : Pat<(v4f32 (X86cvtph2ps (v8i16 (bitconvert
7437               (v2i64 (scalar_to_vector (loadi64 addr:$src))))))),
7438             (VCVTPH2PSrm addr:$src)>;
7439
7440   def : Pat<(store (f64 (extractelt
7441                          (bc_v2f64 (v8i16 (X86cvtps2ph VR128:$src1, i32:$src2))),
7442                          (iPTR 0))), addr:$dst),
7443             (VCVTPS2PHmr addr:$dst, VR128:$src1, imm:$src2)>;
7444   def : Pat<(store (i64 (extractelt
7445                          (bc_v2i64 (v8i16 (X86cvtps2ph VR128:$src1, i32:$src2))),
7446                          (iPTR 0))), addr:$dst),
7447             (VCVTPS2PHmr addr:$dst, VR128:$src1, imm:$src2)>;
7448   def : Pat<(store (v8i16 (X86cvtps2ph VR256:$src1, i32:$src2)), addr:$dst),
7449             (VCVTPS2PHYmr addr:$dst, VR256:$src1, imm:$src2)>;
7450 }
7451
7452 // Patterns for  matching conversions from float to half-float and vice versa.
7453 let Predicates = [HasF16C, NoVLX] in {
7454   // Use MXCSR.RC for rounding instead of explicitly specifying the default
7455   // rounding mode (Nearest-Even, encoded as 0). Both are equivalent in the
7456   // configurations we support (the default). However, falling back to MXCSR is
7457   // more consistent with other instructions, which are always controlled by it.
7458   // It's encoded as 0b100.
7459   def : Pat<(fp_to_f16 FR32:$src),
7460             (i16 (EXTRACT_SUBREG (VMOVPDI2DIrr (VCVTPS2PHrr
7461               (COPY_TO_REGCLASS FR32:$src, VR128), 4)), sub_16bit))>;
7462
7463   def : Pat<(f16_to_fp GR16:$src),
7464             (f32 (COPY_TO_REGCLASS (VCVTPH2PSrr
7465               (COPY_TO_REGCLASS (MOVSX32rr16 GR16:$src), VR128)), FR32)) >;
7466
7467   def : Pat<(f16_to_fp (i16 (fp_to_f16 FR32:$src))),
7468             (f32 (COPY_TO_REGCLASS (VCVTPH2PSrr
7469               (VCVTPS2PHrr (COPY_TO_REGCLASS FR32:$src, VR128), 4)), FR32)) >;
7470 }
7471
7472 //===----------------------------------------------------------------------===//
7473 // AVX2 Instructions
7474 //===----------------------------------------------------------------------===//
7475
7476 /// AVX2_blend_rmi - AVX2 blend with 8-bit immediate
7477 multiclass AVX2_blend_rmi<bits<8> opc, string OpcodeStr, SDNode OpNode,
7478                           ValueType OpVT, X86FoldableSchedWrite sched,
7479                           RegisterClass RC, PatFrag memop_frag,
7480                           X86MemOperand x86memop, SDNodeXForm commuteXForm> {
7481   let isCommutable = 1 in
7482   def rri : AVX2AIi8<opc, MRMSrcReg, (outs RC:$dst),
7483         (ins RC:$src1, RC:$src2, u8imm:$src3),
7484         !strconcat(OpcodeStr,
7485             "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
7486         [(set RC:$dst, (OpVT (OpNode RC:$src1, RC:$src2, imm:$src3)))]>,
7487         Sched<[sched]>, VEX_4V;
7488   def rmi : AVX2AIi8<opc, MRMSrcMem, (outs RC:$dst),
7489         (ins RC:$src1, x86memop:$src2, u8imm:$src3),
7490         !strconcat(OpcodeStr,
7491             "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
7492         [(set RC:$dst,
7493           (OpVT (OpNode RC:$src1,
7494            (bitconvert (memop_frag addr:$src2)), imm:$src3)))]>,
7495         Sched<[sched.Folded, ReadAfterLd]>, VEX_4V;
7496
7497   // Pattern to commute if load is in first source.
7498   def : Pat<(OpVT (OpNode (bitconvert (memop_frag addr:$src2)),
7499                           RC:$src1, imm:$src3)),
7500             (!cast<Instruction>(NAME#"rmi") RC:$src1, addr:$src2,
7501                                             (commuteXForm imm:$src3))>;
7502 }
7503
7504 defm VPBLENDD : AVX2_blend_rmi<0x02, "vpblendd", X86Blendi, v4i32,
7505                                SchedWriteBlend.XMM, VR128, loadv2i64, i128mem,
7506                                BlendCommuteImm4>;
7507 defm VPBLENDDY : AVX2_blend_rmi<0x02, "vpblendd", X86Blendi, v8i32,
7508                                 SchedWriteBlend.YMM, VR256, loadv4i64, i256mem,
7509                                 BlendCommuteImm8>, VEX_L;
7510
7511 // For insertion into the zero index (low half) of a 256-bit vector, it is
7512 // more efficient to generate a blend with immediate instead of an insert*128.
7513 let Predicates = [HasAVX2] in {
7514 def : Pat<(insert_subvector (v8i32 VR256:$src1), (v4i32 VR128:$src2), (iPTR 0)),
7515           (VPBLENDDYrri VR256:$src1,
7516                         (INSERT_SUBREG (v8i32 (IMPLICIT_DEF)),
7517                                        VR128:$src2, sub_xmm), 0xf)>;
7518 def : Pat<(insert_subvector (v4i64 VR256:$src1), (v2i64 VR128:$src2), (iPTR 0)),
7519           (VPBLENDDYrri VR256:$src1,
7520                         (INSERT_SUBREG (v8i32 (IMPLICIT_DEF)),
7521                                        VR128:$src2, sub_xmm), 0xf)>;
7522 def : Pat<(insert_subvector (v16i16 VR256:$src1), (v8i16 VR128:$src2), (iPTR 0)),
7523           (VPBLENDDYrri VR256:$src1,
7524                         (INSERT_SUBREG (v8i32 (IMPLICIT_DEF)),
7525                                        VR128:$src2, sub_xmm), 0xf)>;
7526 def : Pat<(insert_subvector (v32i8 VR256:$src1), (v16i8 VR128:$src2), (iPTR 0)),
7527           (VPBLENDDYrri VR256:$src1,
7528                         (INSERT_SUBREG (v8i32 (IMPLICIT_DEF)),
7529                                        VR128:$src2, sub_xmm), 0xf)>;
7530 }
7531
7532 let Predicates = [HasAVX1Only] in {
7533 def : Pat<(insert_subvector (v8i32 VR256:$src1), (v4i32 VR128:$src2), (iPTR 0)),
7534           (VBLENDPSYrri VR256:$src1,
7535                         (INSERT_SUBREG (v8i32 (IMPLICIT_DEF)),
7536                                        VR128:$src2, sub_xmm), 0xf)>;
7537 def : Pat<(insert_subvector (v4i64 VR256:$src1), (v2i64 VR128:$src2), (iPTR 0)),
7538           (VBLENDPSYrri VR256:$src1,
7539                         (INSERT_SUBREG (v8i32 (IMPLICIT_DEF)),
7540                                        VR128:$src2, sub_xmm), 0xf)>;
7541 def : Pat<(insert_subvector (v16i16 VR256:$src1), (v8i16 VR128:$src2), (iPTR 0)),
7542           (VBLENDPSYrri VR256:$src1,
7543                         (INSERT_SUBREG (v8i32 (IMPLICIT_DEF)),
7544                                        VR128:$src2, sub_xmm), 0xf)>;
7545 def : Pat<(insert_subvector (v32i8 VR256:$src1), (v16i8 VR128:$src2), (iPTR 0)),
7546           (VBLENDPSYrri VR256:$src1,
7547                         (INSERT_SUBREG (v8i32 (IMPLICIT_DEF)),
7548                                        VR128:$src2, sub_xmm), 0xf)>;
7549 }
7550
7551 //===----------------------------------------------------------------------===//
7552 // VPBROADCAST - Load from memory and broadcast to all elements of the
7553 //               destination operand
7554 //
7555 multiclass avx2_broadcast<bits<8> opc, string OpcodeStr,
7556                           X86MemOperand x86memop, PatFrag ld_frag,
7557                           ValueType OpVT128, ValueType OpVT256, Predicate prd> {
7558   let Predicates = [HasAVX2, prd] in {
7559     def rr : AVX28I<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
7560                   !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
7561                   [(set VR128:$dst,
7562                    (OpVT128 (X86VBroadcast (OpVT128 VR128:$src))))]>,
7563                   Sched<[SchedWriteShuffle.XMM]>, VEX;
7564     def rm : AVX28I<opc, MRMSrcMem, (outs VR128:$dst), (ins x86memop:$src),
7565                   !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
7566                   [(set VR128:$dst,
7567                    (OpVT128 (X86VBroadcast (ld_frag addr:$src))))]>,
7568                   Sched<[SchedWriteShuffle.XMM.Folded]>, VEX;
7569     def Yrr : AVX28I<opc, MRMSrcReg, (outs VR256:$dst), (ins VR128:$src),
7570                    !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
7571                    [(set VR256:$dst,
7572                     (OpVT256 (X86VBroadcast (OpVT128 VR128:$src))))]>,
7573                    Sched<[WriteShuffle256]>, VEX, VEX_L;
7574     def Yrm : AVX28I<opc, MRMSrcMem, (outs VR256:$dst), (ins x86memop:$src),
7575                    !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
7576                    [(set VR256:$dst,
7577                     (OpVT256 (X86VBroadcast (ld_frag addr:$src))))]>,
7578                    Sched<[SchedWriteShuffle.XMM.Folded]>, VEX, VEX_L;
7579
7580     // Provide aliases for broadcast from the same register class that
7581     // automatically does the extract.
7582     def : Pat<(OpVT256 (X86VBroadcast (OpVT256 VR256:$src))),
7583               (!cast<Instruction>(NAME#"Yrr")
7584                   (OpVT128 (EXTRACT_SUBREG (OpVT256 VR256:$src),sub_xmm)))>;
7585   }
7586 }
7587
7588 defm VPBROADCASTB  : avx2_broadcast<0x78, "vpbroadcastb", i8mem, loadi8,
7589                                     v16i8, v32i8, NoVLX_Or_NoBWI>;
7590 defm VPBROADCASTW  : avx2_broadcast<0x79, "vpbroadcastw", i16mem, loadi16,
7591                                     v8i16, v16i16, NoVLX_Or_NoBWI>;
7592 defm VPBROADCASTD  : avx2_broadcast<0x58, "vpbroadcastd", i32mem, loadi32,
7593                                     v4i32, v8i32, NoVLX>;
7594 defm VPBROADCASTQ  : avx2_broadcast<0x59, "vpbroadcastq", i64mem, loadi64,
7595                                     v2i64, v4i64, NoVLX>;
7596
7597 let Predicates = [HasAVX2, NoVLX] in {
7598   // 32-bit targets will fail to load a i64 directly but can use ZEXT_LOAD.
7599   def : Pat<(v2i64 (X86VBroadcast (v2i64 (X86vzload addr:$src)))),
7600             (VPBROADCASTQrm addr:$src)>;
7601   def : Pat<(v4i64 (X86VBroadcast (v4i64 (X86vzload addr:$src)))),
7602             (VPBROADCASTQYrm addr:$src)>;
7603
7604   def : Pat<(v4i32 (X86VBroadcast (v4i32 (scalar_to_vector (loadi32 addr:$src))))),
7605             (VPBROADCASTDrm addr:$src)>;
7606   def : Pat<(v8i32 (X86VBroadcast (v4i32 (scalar_to_vector (loadi32 addr:$src))))),
7607             (VPBROADCASTDYrm addr:$src)>;
7608   def : Pat<(v2i64 (X86VBroadcast (v2i64 (scalar_to_vector (loadi64 addr:$src))))),
7609             (VPBROADCASTQrm addr:$src)>;
7610   def : Pat<(v4i64 (X86VBroadcast (v2i64 (scalar_to_vector (loadi64 addr:$src))))),
7611             (VPBROADCASTQYrm addr:$src)>;
7612 }
7613 let Predicates = [HasAVX2, NoVLX_Or_NoBWI] in {
7614   // loadi16 is tricky to fold, because !isTypeDesirableForOp, justifiably.
7615   // This means we'll encounter truncated i32 loads; match that here.
7616   def : Pat<(v8i16 (X86VBroadcast (i16 (trunc (i32 (load addr:$src)))))),
7617             (VPBROADCASTWrm addr:$src)>;
7618   def : Pat<(v16i16 (X86VBroadcast (i16 (trunc (i32 (load addr:$src)))))),
7619             (VPBROADCASTWYrm addr:$src)>;
7620   def : Pat<(v8i16 (X86VBroadcast
7621               (i16 (trunc (i32 (zextloadi16 addr:$src)))))),
7622             (VPBROADCASTWrm addr:$src)>;
7623   def : Pat<(v16i16 (X86VBroadcast
7624               (i16 (trunc (i32 (zextloadi16 addr:$src)))))),
7625             (VPBROADCASTWYrm addr:$src)>;
7626 }
7627
7628 let Predicates = [HasAVX2, NoVLX] in {
7629   // Provide aliases for broadcast from the same register class that
7630   // automatically does the extract.
7631   def : Pat<(v8f32 (X86VBroadcast (v8f32 VR256:$src))),
7632             (VBROADCASTSSYrr (v4f32 (EXTRACT_SUBREG (v8f32 VR256:$src),
7633                                                     sub_xmm)))>;
7634   def : Pat<(v4f64 (X86VBroadcast (v4f64 VR256:$src))),
7635             (VBROADCASTSDYrr (v2f64 (EXTRACT_SUBREG (v4f64 VR256:$src),
7636                                                     sub_xmm)))>;
7637 }
7638
7639 let Predicates = [HasAVX2, NoVLX] in {
7640   // Provide fallback in case the load node that is used in the patterns above
7641   // is used by additional users, which prevents the pattern selection.
7642     def : Pat<(v4f32 (X86VBroadcast FR32:$src)),
7643               (VBROADCASTSSrr (COPY_TO_REGCLASS FR32:$src, VR128))>;
7644     def : Pat<(v8f32 (X86VBroadcast FR32:$src)),
7645               (VBROADCASTSSYrr (COPY_TO_REGCLASS FR32:$src, VR128))>;
7646     def : Pat<(v4f64 (X86VBroadcast FR64:$src)),
7647               (VBROADCASTSDYrr (COPY_TO_REGCLASS FR64:$src, VR128))>;
7648 }
7649
7650 let Predicates = [HasAVX2, NoVLX_Or_NoBWI] in {
7651   def : Pat<(v16i8 (X86VBroadcast GR8:$src)),
7652         (VPBROADCASTBrr (COPY_TO_REGCLASS
7653                          (i32 (INSERT_SUBREG (i32 (IMPLICIT_DEF)),
7654                                              GR8:$src, sub_8bit)),
7655                          VR128))>;
7656   def : Pat<(v32i8 (X86VBroadcast GR8:$src)),
7657         (VPBROADCASTBYrr (COPY_TO_REGCLASS
7658                           (i32 (INSERT_SUBREG (i32 (IMPLICIT_DEF)),
7659                                               GR8:$src, sub_8bit)),
7660                           VR128))>;
7661
7662   def : Pat<(v8i16 (X86VBroadcast GR16:$src)),
7663         (VPBROADCASTWrr (COPY_TO_REGCLASS
7664                          (i32 (INSERT_SUBREG (i32 (IMPLICIT_DEF)),
7665                                              GR16:$src, sub_16bit)),
7666                          VR128))>;
7667   def : Pat<(v16i16 (X86VBroadcast GR16:$src)),
7668         (VPBROADCASTWYrr (COPY_TO_REGCLASS
7669                           (i32 (INSERT_SUBREG (i32 (IMPLICIT_DEF)),
7670                                               GR16:$src, sub_16bit)),
7671                           VR128))>;
7672 }
7673 let Predicates = [HasAVX2, NoVLX] in {
7674   def : Pat<(v4i32 (X86VBroadcast GR32:$src)),
7675             (VPBROADCASTDrr (COPY_TO_REGCLASS GR32:$src, VR128))>;
7676   def : Pat<(v8i32 (X86VBroadcast GR32:$src)),
7677             (VPBROADCASTDYrr (COPY_TO_REGCLASS GR32:$src, VR128))>;
7678   def : Pat<(v2i64 (X86VBroadcast GR64:$src)),
7679             (VPBROADCASTQrr (COPY_TO_REGCLASS GR64:$src, VR128))>;
7680   def : Pat<(v4i64 (X86VBroadcast GR64:$src)),
7681             (VPBROADCASTQYrr (COPY_TO_REGCLASS GR64:$src, VR128))>;
7682 }
7683
7684 // AVX1 broadcast patterns
7685 let Predicates = [HasAVX1Only] in {
7686 def : Pat<(v8i32 (X86VBroadcast (loadi32 addr:$src))),
7687           (VBROADCASTSSYrm addr:$src)>;
7688 def : Pat<(v4i64 (X86VBroadcast (loadi64 addr:$src))),
7689           (VBROADCASTSDYrm addr:$src)>;
7690 def : Pat<(v4i32 (X86VBroadcast (loadi32 addr:$src))),
7691           (VBROADCASTSSrm addr:$src)>;
7692 }
7693
7694   // Provide fallback in case the load node that is used in the patterns above
7695   // is used by additional users, which prevents the pattern selection.
7696 let Predicates = [HasAVX, NoVLX] in {
7697   // 128bit broadcasts:
7698   def : Pat<(v2f64 (X86VBroadcast f64:$src)),
7699             (VMOVDDUPrr (COPY_TO_REGCLASS FR64:$src, VR128))>;
7700   def : Pat<(v2f64 (X86VBroadcast (loadf64 addr:$src))),
7701             (VMOVDDUPrm addr:$src)>;
7702
7703   def : Pat<(v2f64 (X86VBroadcast v2f64:$src)),
7704             (VMOVDDUPrr VR128:$src)>;
7705   def : Pat<(v2f64 (X86VBroadcast (loadv2f64 addr:$src))),
7706             (VMOVDDUPrm addr:$src)>;
7707 }
7708
7709 let Predicates = [HasAVX1Only] in {
7710   def : Pat<(v4f32 (X86VBroadcast FR32:$src)),
7711             (VPERMILPSri (COPY_TO_REGCLASS FR32:$src, VR128), 0)>;
7712   def : Pat<(v8f32 (X86VBroadcast FR32:$src)),
7713             (VINSERTF128rr (INSERT_SUBREG (v8f32 (IMPLICIT_DEF)),
7714               (VPERMILPSri (COPY_TO_REGCLASS FR32:$src, VR128), 0), sub_xmm),
7715               (VPERMILPSri (COPY_TO_REGCLASS FR32:$src, VR128), 0), 1)>;
7716   def : Pat<(v4f64 (X86VBroadcast FR64:$src)),
7717             (VINSERTF128rr (INSERT_SUBREG (v4f64 (IMPLICIT_DEF)),
7718               (VMOVDDUPrr (COPY_TO_REGCLASS FR64:$src, VR128)), sub_xmm),
7719               (VMOVDDUPrr (COPY_TO_REGCLASS FR64:$src, VR128)), 1)>;
7720
7721   def : Pat<(v4i32 (X86VBroadcast GR32:$src)),
7722             (VPSHUFDri (COPY_TO_REGCLASS GR32:$src, VR128), 0)>;
7723   def : Pat<(v8i32 (X86VBroadcast GR32:$src)),
7724             (VINSERTF128rr (INSERT_SUBREG (v8i32 (IMPLICIT_DEF)),
7725               (VPSHUFDri (COPY_TO_REGCLASS GR32:$src, VR128), 0), sub_xmm),
7726               (VPSHUFDri (COPY_TO_REGCLASS GR32:$src, VR128), 0), 1)>;
7727   def : Pat<(v4i64 (X86VBroadcast GR64:$src)),
7728             (VINSERTF128rr (INSERT_SUBREG (v4i64 (IMPLICIT_DEF)),
7729               (VPSHUFDri (COPY_TO_REGCLASS GR64:$src, VR128), 0x44), sub_xmm),
7730               (VPSHUFDri (COPY_TO_REGCLASS GR64:$src, VR128), 0x44), 1)>;
7731
7732   def : Pat<(v2i64 (X86VBroadcast i64:$src)),
7733             (VPSHUFDri (COPY_TO_REGCLASS GR64:$src, VR128), 0x44)>;
7734   def : Pat<(v2i64 (X86VBroadcast (loadi64 addr:$src))),
7735             (VMOVDDUPrm addr:$src)>;
7736 }
7737
7738 //===----------------------------------------------------------------------===//
7739 // VPERM - Permute instructions
7740 //
7741
7742 multiclass avx2_perm<bits<8> opc, string OpcodeStr, PatFrag mem_frag,
7743                      ValueType OpVT, X86FoldableSchedWrite Sched,
7744                      X86MemOperand memOp> {
7745   let Predicates = [HasAVX2, NoVLX] in {
7746     def Yrr : AVX28I<opc, MRMSrcReg, (outs VR256:$dst),
7747                      (ins VR256:$src1, VR256:$src2),
7748                      !strconcat(OpcodeStr,
7749                          "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7750                      [(set VR256:$dst,
7751                        (OpVT (X86VPermv VR256:$src1, VR256:$src2)))]>,
7752                      Sched<[Sched]>, VEX_4V, VEX_L;
7753     def Yrm : AVX28I<opc, MRMSrcMem, (outs VR256:$dst),
7754                      (ins VR256:$src1, memOp:$src2),
7755                      !strconcat(OpcodeStr,
7756                          "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7757                      [(set VR256:$dst,
7758                        (OpVT (X86VPermv VR256:$src1,
7759                               (bitconvert (mem_frag addr:$src2)))))]>,
7760                      Sched<[Sched.Folded, ReadAfterLd]>, VEX_4V, VEX_L;
7761   }
7762 }
7763
7764 defm VPERMD : avx2_perm<0x36, "vpermd", loadv4i64, v8i32, WriteVarShuffle256,
7765                         i256mem>;
7766 let ExeDomain = SSEPackedSingle in
7767 defm VPERMPS : avx2_perm<0x16, "vpermps", loadv8f32, v8f32, WriteFVarShuffle256,
7768                         f256mem>;
7769
7770 multiclass avx2_perm_imm<bits<8> opc, string OpcodeStr, PatFrag mem_frag,
7771                          ValueType OpVT, X86FoldableSchedWrite Sched,
7772                          X86MemOperand memOp> {
7773   let Predicates = [HasAVX2, NoVLX] in {
7774     def Yri : AVX2AIi8<opc, MRMSrcReg, (outs VR256:$dst),
7775                        (ins VR256:$src1, u8imm:$src2),
7776                        !strconcat(OpcodeStr,
7777                            "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7778                        [(set VR256:$dst,
7779                          (OpVT (X86VPermi VR256:$src1, (i8 imm:$src2))))]>,
7780                        Sched<[Sched]>, VEX, VEX_L;
7781     def Ymi : AVX2AIi8<opc, MRMSrcMem, (outs VR256:$dst),
7782                        (ins memOp:$src1, u8imm:$src2),
7783                        !strconcat(OpcodeStr,
7784                            "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7785                        [(set VR256:$dst,
7786                          (OpVT (X86VPermi (mem_frag addr:$src1),
7787                                 (i8 imm:$src2))))]>,
7788                        Sched<[Sched.Folded, ReadAfterLd]>, VEX, VEX_L;
7789   }
7790 }
7791
7792 defm VPERMQ : avx2_perm_imm<0x00, "vpermq", loadv4i64, v4i64,
7793                             WriteShuffle256, i256mem>, VEX_W;
7794 let ExeDomain = SSEPackedDouble in
7795 defm VPERMPD : avx2_perm_imm<0x01, "vpermpd", loadv4f64, v4f64,
7796                              WriteFShuffle256, f256mem>, VEX_W;
7797
7798 //===----------------------------------------------------------------------===//
7799 // VPERM2I128 - Permute Floating-Point Values in 128-bit chunks
7800 //
7801 let isCommutable = 1 in
7802 def VPERM2I128rr : AVX2AIi8<0x46, MRMSrcReg, (outs VR256:$dst),
7803           (ins VR256:$src1, VR256:$src2, u8imm:$src3),
7804           "vperm2i128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
7805           [(set VR256:$dst, (v4i64 (X86VPerm2x128 VR256:$src1, VR256:$src2,
7806                             (i8 imm:$src3))))]>, Sched<[WriteShuffle256]>,
7807           VEX_4V, VEX_L;
7808 def VPERM2I128rm : AVX2AIi8<0x46, MRMSrcMem, (outs VR256:$dst),
7809           (ins VR256:$src1, f256mem:$src2, u8imm:$src3),
7810           "vperm2i128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
7811           [(set VR256:$dst, (X86VPerm2x128 VR256:$src1, (loadv4i64 addr:$src2),
7812                              (i8 imm:$src3)))]>,
7813           Sched<[WriteShuffle256Ld, ReadAfterLd]>, VEX_4V, VEX_L;
7814
7815 let Predicates = [HasAVX2] in
7816 def : Pat<(v4i64 (X86VPerm2x128 (loadv4i64 addr:$src2),
7817                                 VR256:$src1, (i8 imm:$imm))),
7818           (VPERM2I128rm VR256:$src1, addr:$src2, (Perm2XCommuteImm imm:$imm))>;
7819
7820
7821 //===----------------------------------------------------------------------===//
7822 // VINSERTI128 - Insert packed integer values
7823 //
7824 let hasSideEffects = 0 in {
7825 def VINSERTI128rr : AVX2AIi8<0x38, MRMSrcReg, (outs VR256:$dst),
7826           (ins VR256:$src1, VR128:$src2, u8imm:$src3),
7827           "vinserti128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
7828           []>, Sched<[WriteShuffle256]>, VEX_4V, VEX_L;
7829 let mayLoad = 1 in
7830 def VINSERTI128rm : AVX2AIi8<0x38, MRMSrcMem, (outs VR256:$dst),
7831           (ins VR256:$src1, i128mem:$src2, u8imm:$src3),
7832           "vinserti128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
7833           []>, Sched<[WriteShuffle256Ld, ReadAfterLd]>, VEX_4V, VEX_L;
7834 }
7835
7836 let Predicates = [HasAVX2, NoVLX] in {
7837   defm : vinsert_lowering<"VINSERTI128", v2i64, v4i64,  loadv2i64>;
7838   defm : vinsert_lowering<"VINSERTI128", v4i32, v8i32,  loadv2i64>;
7839   defm : vinsert_lowering<"VINSERTI128", v8i16, v16i16, loadv2i64>;
7840   defm : vinsert_lowering<"VINSERTI128", v16i8, v32i8,  loadv2i64>;
7841 }
7842
7843 //===----------------------------------------------------------------------===//
7844 // VEXTRACTI128 - Extract packed integer values
7845 //
7846 def VEXTRACTI128rr : AVX2AIi8<0x39, MRMDestReg, (outs VR128:$dst),
7847           (ins VR256:$src1, u8imm:$src2),
7848           "vextracti128\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>,
7849           Sched<[WriteShuffle256]>, VEX, VEX_L;
7850 let hasSideEffects = 0, mayStore = 1 in
7851 def VEXTRACTI128mr : AVX2AIi8<0x39, MRMDestMem, (outs),
7852           (ins i128mem:$dst, VR256:$src1, u8imm:$src2),
7853           "vextracti128\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>,
7854           Sched<[SchedWriteVecMoveLS.XMM.MR]>, VEX, VEX_L;
7855
7856 let Predicates = [HasAVX2, NoVLX] in {
7857   defm : vextract_lowering<"VEXTRACTI128", v4i64,  v2i64>;
7858   defm : vextract_lowering<"VEXTRACTI128", v8i32,  v4i32>;
7859   defm : vextract_lowering<"VEXTRACTI128", v16i16, v8i16>;
7860   defm : vextract_lowering<"VEXTRACTI128", v32i8,  v16i8>;
7861 }
7862
7863 //===----------------------------------------------------------------------===//
7864 // VPMASKMOV - Conditional SIMD Integer Packed Loads and Stores
7865 //
7866 multiclass avx2_pmovmask<string OpcodeStr,
7867                          Intrinsic IntLd128, Intrinsic IntLd256,
7868                          Intrinsic IntSt128, Intrinsic IntSt256> {
7869   def rm  : AVX28I<0x8c, MRMSrcMem, (outs VR128:$dst),
7870              (ins VR128:$src1, i128mem:$src2),
7871              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7872              [(set VR128:$dst, (IntLd128 addr:$src2, VR128:$src1))]>,
7873              VEX_4V, Sched<[WriteVecMaskedLoad]>;
7874   def Yrm : AVX28I<0x8c, MRMSrcMem, (outs VR256:$dst),
7875              (ins VR256:$src1, i256mem:$src2),
7876              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7877              [(set VR256:$dst, (IntLd256 addr:$src2, VR256:$src1))]>,
7878              VEX_4V, VEX_L, Sched<[WriteVecMaskedLoadY]>;
7879   def mr  : AVX28I<0x8e, MRMDestMem, (outs),
7880              (ins i128mem:$dst, VR128:$src1, VR128:$src2),
7881              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7882              [(IntSt128 addr:$dst, VR128:$src1, VR128:$src2)]>,
7883              VEX_4V, Sched<[WriteVecMaskedStore]>;
7884   def Ymr : AVX28I<0x8e, MRMDestMem, (outs),
7885              (ins i256mem:$dst, VR256:$src1, VR256:$src2),
7886              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7887              [(IntSt256 addr:$dst, VR256:$src1, VR256:$src2)]>,
7888              VEX_4V, VEX_L, Sched<[WriteVecMaskedStoreY]>;
7889 }
7890
7891 defm VPMASKMOVD : avx2_pmovmask<"vpmaskmovd",
7892                                 int_x86_avx2_maskload_d,
7893                                 int_x86_avx2_maskload_d_256,
7894                                 int_x86_avx2_maskstore_d,
7895                                 int_x86_avx2_maskstore_d_256>;
7896 defm VPMASKMOVQ : avx2_pmovmask<"vpmaskmovq",
7897                                 int_x86_avx2_maskload_q,
7898                                 int_x86_avx2_maskload_q_256,
7899                                 int_x86_avx2_maskstore_q,
7900                                 int_x86_avx2_maskstore_q_256>, VEX_W;
7901
7902 multiclass maskmov_lowering<string InstrStr, RegisterClass RC, ValueType VT,
7903                           ValueType MaskVT, string BlendStr, ValueType ZeroVT> {
7904     // masked store
7905     def: Pat<(X86mstore addr:$ptr, (MaskVT RC:$mask), (VT RC:$src)),
7906              (!cast<Instruction>(InstrStr#"mr") addr:$ptr, RC:$mask, RC:$src)>;
7907     // masked load
7908     def: Pat<(VT (X86mload addr:$ptr, (MaskVT RC:$mask), undef)),
7909              (!cast<Instruction>(InstrStr#"rm") RC:$mask, addr:$ptr)>;
7910     def: Pat<(VT (X86mload addr:$ptr, (MaskVT RC:$mask),
7911                               (VT (bitconvert (ZeroVT immAllZerosV))))),
7912              (!cast<Instruction>(InstrStr#"rm") RC:$mask, addr:$ptr)>;
7913     def: Pat<(VT (X86mload addr:$ptr, (MaskVT RC:$mask), (VT RC:$src0))),
7914              (!cast<Instruction>(BlendStr#"rr")
7915                  RC:$src0,
7916                  (!cast<Instruction>(InstrStr#"rm") RC:$mask, addr:$ptr),
7917                  RC:$mask)>;
7918 }
7919 let Predicates = [HasAVX] in {
7920   defm : maskmov_lowering<"VMASKMOVPS", VR128, v4f32, v4i32, "VBLENDVPS", v4i32>;
7921   defm : maskmov_lowering<"VMASKMOVPD", VR128, v2f64, v2i64, "VBLENDVPD", v4i32>;
7922   defm : maskmov_lowering<"VMASKMOVPSY", VR256, v8f32, v8i32, "VBLENDVPSY", v8i32>;
7923   defm : maskmov_lowering<"VMASKMOVPDY", VR256, v4f64, v4i64, "VBLENDVPDY", v8i32>;
7924 }
7925 let Predicates = [HasAVX1Only] in {
7926   // load/store i32/i64 not supported use ps/pd version
7927   defm : maskmov_lowering<"VMASKMOVPSY", VR256, v8i32, v8i32, "VBLENDVPSY", v8i32>;
7928   defm : maskmov_lowering<"VMASKMOVPDY", VR256, v4i64, v4i64, "VBLENDVPDY", v8i32>;
7929   defm : maskmov_lowering<"VMASKMOVPS", VR128, v4i32, v4i32, "VBLENDVPS", v4i32>;
7930   defm : maskmov_lowering<"VMASKMOVPD", VR128, v2i64, v2i64, "VBLENDVPD", v4i32>;
7931 }
7932 let Predicates = [HasAVX2] in {
7933   defm : maskmov_lowering<"VPMASKMOVDY", VR256, v8i32, v8i32, "VBLENDVPSY", v8i32>;
7934   defm : maskmov_lowering<"VPMASKMOVQY", VR256, v4i64, v4i64, "VBLENDVPDY", v8i32>;
7935   defm : maskmov_lowering<"VPMASKMOVD", VR128, v4i32, v4i32, "VBLENDVPS", v4i32>;
7936   defm : maskmov_lowering<"VPMASKMOVQ", VR128, v2i64, v2i64, "VBLENDVPD", v4i32>;
7937 }
7938
7939 //===----------------------------------------------------------------------===//
7940 // SubVector Broadcasts
7941 // Provide fallback in case the load node that is used in the patterns above
7942 // is used by additional users, which prevents the pattern selection.
7943
7944 let Predicates = [HasAVX2, NoVLX] in {
7945 def : Pat<(v4i64 (X86SubVBroadcast (v2i64 VR128:$src))),
7946           (VINSERTI128rr (INSERT_SUBREG (v4i64 (IMPLICIT_DEF)), VR128:$src, sub_xmm),
7947                          (v2i64 VR128:$src), 1)>;
7948 def : Pat<(v8i32 (X86SubVBroadcast (v4i32 VR128:$src))),
7949           (VINSERTI128rr (INSERT_SUBREG (v8i32 (IMPLICIT_DEF)), VR128:$src, sub_xmm),
7950                          (v4i32 VR128:$src), 1)>;
7951 def : Pat<(v16i16 (X86SubVBroadcast (v8i16 VR128:$src))),
7952           (VINSERTI128rr (INSERT_SUBREG (v16i16 (IMPLICIT_DEF)), VR128:$src, sub_xmm),
7953                          (v8i16 VR128:$src), 1)>;
7954 def : Pat<(v32i8 (X86SubVBroadcast (v16i8 VR128:$src))),
7955           (VINSERTI128rr (INSERT_SUBREG (v32i8 (IMPLICIT_DEF)), VR128:$src, sub_xmm),
7956                          (v16i8 VR128:$src), 1)>;
7957 }
7958
7959 let Predicates = [HasAVX, NoVLX] in {
7960 def : Pat<(v4f64 (X86SubVBroadcast (v2f64 VR128:$src))),
7961           (VINSERTF128rr (INSERT_SUBREG (v4f64 (IMPLICIT_DEF)), VR128:$src, sub_xmm),
7962                          (v2f64 VR128:$src), 1)>;
7963 def : Pat<(v8f32 (X86SubVBroadcast (v4f32 VR128:$src))),
7964           (VINSERTF128rr (INSERT_SUBREG (v8f32 (IMPLICIT_DEF)), VR128:$src, sub_xmm),
7965                          (v4f32 VR128:$src), 1)>;
7966 }
7967
7968 let Predicates = [HasAVX1Only] in {
7969 def : Pat<(v4i64 (X86SubVBroadcast (v2i64 VR128:$src))),
7970           (VINSERTF128rr (INSERT_SUBREG (v4i64 (IMPLICIT_DEF)), VR128:$src, sub_xmm),
7971                          (v2i64 VR128:$src), 1)>;
7972 def : Pat<(v8i32 (X86SubVBroadcast (v4i32 VR128:$src))),
7973           (VINSERTF128rr (INSERT_SUBREG (v8i32 (IMPLICIT_DEF)), VR128:$src, sub_xmm),
7974                          (v4i32 VR128:$src), 1)>;
7975 def : Pat<(v16i16 (X86SubVBroadcast (v8i16 VR128:$src))),
7976           (VINSERTF128rr (INSERT_SUBREG (v16i16 (IMPLICIT_DEF)), VR128:$src, sub_xmm),
7977                          (v8i16 VR128:$src), 1)>;
7978 def : Pat<(v32i8 (X86SubVBroadcast (v16i8 VR128:$src))),
7979           (VINSERTF128rr (INSERT_SUBREG (v32i8 (IMPLICIT_DEF)), VR128:$src, sub_xmm),
7980                          (v16i8 VR128:$src), 1)>;
7981 }
7982
7983 //===----------------------------------------------------------------------===//
7984 // Variable Bit Shifts
7985 //
7986 multiclass avx2_var_shift<bits<8> opc, string OpcodeStr, SDNode OpNode,
7987                           ValueType vt128, ValueType vt256> {
7988   def rr  : AVX28I<opc, MRMSrcReg, (outs VR128:$dst),
7989              (ins VR128:$src1, VR128:$src2),
7990              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7991              [(set VR128:$dst,
7992                (vt128 (OpNode VR128:$src1, (vt128 VR128:$src2))))]>,
7993              VEX_4V, Sched<[SchedWriteVarVecShift.XMM]>;
7994   def rm  : AVX28I<opc, MRMSrcMem, (outs VR128:$dst),
7995              (ins VR128:$src1, i128mem:$src2),
7996              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7997              [(set VR128:$dst,
7998                (vt128 (OpNode VR128:$src1,
7999                        (vt128 (bitconvert (loadv2i64 addr:$src2))))))]>,
8000              VEX_4V, Sched<[SchedWriteVarVecShift.XMM.Folded, ReadAfterLd]>;
8001   def Yrr : AVX28I<opc, MRMSrcReg, (outs VR256:$dst),
8002              (ins VR256:$src1, VR256:$src2),
8003              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8004              [(set VR256:$dst,
8005                (vt256 (OpNode VR256:$src1, (vt256 VR256:$src2))))]>,
8006              VEX_4V, VEX_L, Sched<[SchedWriteVarVecShift.YMM]>;
8007   def Yrm : AVX28I<opc, MRMSrcMem, (outs VR256:$dst),
8008              (ins VR256:$src1, i256mem:$src2),
8009              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8010              [(set VR256:$dst,
8011                (vt256 (OpNode VR256:$src1,
8012                        (vt256 (bitconvert (loadv4i64 addr:$src2))))))]>,
8013              VEX_4V, VEX_L, Sched<[SchedWriteVarVecShift.YMM.Folded, ReadAfterLd]>;
8014 }
8015
8016 let Predicates = [HasAVX2, NoVLX] in {
8017   defm VPSLLVD : avx2_var_shift<0x47, "vpsllvd", shl, v4i32, v8i32>;
8018   defm VPSLLVQ : avx2_var_shift<0x47, "vpsllvq", shl, v2i64, v4i64>, VEX_W;
8019   defm VPSRLVD : avx2_var_shift<0x45, "vpsrlvd", srl, v4i32, v8i32>;
8020   defm VPSRLVQ : avx2_var_shift<0x45, "vpsrlvq", srl, v2i64, v4i64>, VEX_W;
8021   defm VPSRAVD : avx2_var_shift<0x46, "vpsravd", sra, v4i32, v8i32>;
8022
8023   def : Pat<(v4i32 (X86vsrav VR128:$src1, VR128:$src2)),
8024             (VPSRAVDrr VR128:$src1, VR128:$src2)>;
8025   def : Pat<(v4i32 (X86vsrav VR128:$src1,
8026                     (bitconvert (loadv2i64 addr:$src2)))),
8027             (VPSRAVDrm VR128:$src1, addr:$src2)>;
8028   def : Pat<(v8i32 (X86vsrav VR256:$src1, VR256:$src2)),
8029             (VPSRAVDYrr VR256:$src1, VR256:$src2)>;
8030   def : Pat<(v8i32 (X86vsrav VR256:$src1,
8031                     (bitconvert (loadv4i64 addr:$src2)))),
8032             (VPSRAVDYrm VR256:$src1, addr:$src2)>;
8033 }
8034
8035 //===----------------------------------------------------------------------===//
8036 // VGATHER - GATHER Operations
8037
8038 // FIXME: Improve scheduling of gather instructions.
8039 multiclass avx2_gather<bits<8> opc, string OpcodeStr, ValueType VTx,
8040                        ValueType VTy, PatFrag GatherNode128,
8041                        PatFrag GatherNode256, RegisterClass RC256,
8042                        X86MemOperand memop128, X86MemOperand memop256,
8043                        ValueType MTx = VTx, ValueType MTy = VTy> {
8044   def rm  : AVX28I<opc, MRMSrcMem4VOp3, (outs VR128:$dst, VR128:$mask_wb),
8045             (ins VR128:$src1, memop128:$src2, VR128:$mask),
8046             !strconcat(OpcodeStr,
8047               "\t{$mask, $src2, $dst|$dst, $src2, $mask}"),
8048             [(set (VTx VR128:$dst), (MTx VR128:$mask_wb),
8049                   (GatherNode128 VR128:$src1, VR128:$mask,
8050                                 vectoraddr:$src2))]>,
8051             VEX, Sched<[WriteLoad]>;
8052   def Yrm : AVX28I<opc, MRMSrcMem4VOp3, (outs RC256:$dst, RC256:$mask_wb),
8053             (ins RC256:$src1, memop256:$src2, RC256:$mask),
8054             !strconcat(OpcodeStr,
8055               "\t{$mask, $src2, $dst|$dst, $src2, $mask}"),
8056             [(set (VTy RC256:$dst), (MTy RC256:$mask_wb),
8057                   (GatherNode256 RC256:$src1, RC256:$mask,
8058                                 vectoraddr:$src2))]>,
8059             VEX, VEX_L, Sched<[WriteLoad]>;
8060 }
8061
8062 let Predicates = [UseAVX2] in {
8063   let mayLoad = 1, hasSideEffects = 0, Constraints
8064     = "@earlyclobber $dst,@earlyclobber $mask_wb, $src1 = $dst, $mask = $mask_wb"
8065     in {
8066     defm VPGATHERDQ : avx2_gather<0x90, "vpgatherdq", v2i64, v4i64, mgatherv4i32,
8067                         mgatherv4i32, VR256, vx128mem, vx256mem>, VEX_W;
8068     defm VPGATHERQQ : avx2_gather<0x91, "vpgatherqq", v2i64, v4i64, mgatherv2i64,
8069                         mgatherv4i64, VR256, vx128mem, vy256mem>, VEX_W;
8070     defm VPGATHERDD : avx2_gather<0x90, "vpgatherdd", v4i32, v8i32, mgatherv4i32,
8071                         mgatherv8i32, VR256, vx128mem, vy256mem>;
8072     defm VPGATHERQD : avx2_gather<0x91, "vpgatherqd", v4i32, v4i32, mgatherv2i64,
8073                         mgatherv4i64, VR128, vx64mem, vy128mem>;
8074
8075     let ExeDomain = SSEPackedDouble in {
8076       defm VGATHERDPD : avx2_gather<0x92, "vgatherdpd", v2f64, v4f64, mgatherv4i32,
8077                           mgatherv4i32, VR256, vx128mem, vx256mem,
8078                           v2i64, v4i64>, VEX_W;
8079       defm VGATHERQPD : avx2_gather<0x93, "vgatherqpd", v2f64, v4f64, mgatherv2i64,
8080                           mgatherv4i64, VR256, vx128mem, vy256mem,
8081                           v2i64, v4i64>, VEX_W;
8082     }
8083
8084     let ExeDomain = SSEPackedSingle in {
8085       defm VGATHERDPS : avx2_gather<0x92, "vgatherdps", v4f32, v8f32, mgatherv4i32,
8086                           mgatherv8i32, VR256, vx128mem, vy256mem,
8087                           v4i32, v8i32>;
8088       defm VGATHERQPS : avx2_gather<0x93, "vgatherqps", v4f32, v4f32, mgatherv2i64,
8089                           mgatherv4i64, VR128, vx64mem, vy128mem,
8090                           v4i32, v4i32>;
8091     }
8092   }
8093 }
8094
8095 //===----------------------------------------------------------------------===//
8096 // Extra selection patterns for FR128, f128, f128mem
8097
8098 // movaps is shorter than movdqa. movaps is in SSE and movdqa is in SSE2.
8099 def : Pat<(alignedstore (f128 FR128:$src), addr:$dst),
8100           (MOVAPSmr addr:$dst, (COPY_TO_REGCLASS (f128 FR128:$src), VR128))>;
8101 def : Pat<(store (f128 FR128:$src), addr:$dst),
8102           (MOVUPSmr addr:$dst, (COPY_TO_REGCLASS (f128 FR128:$src), VR128))>;
8103
8104 def : Pat<(alignedloadf128 addr:$src),
8105           (COPY_TO_REGCLASS (MOVAPSrm addr:$src), FR128)>;
8106 def : Pat<(loadf128 addr:$src),
8107           (COPY_TO_REGCLASS (MOVUPSrm addr:$src), FR128)>;
8108
8109 // andps is shorter than andpd or pand. andps is SSE and andpd/pand are in SSE2
8110 def : Pat<(X86fand FR128:$src1, (memopf128 addr:$src2)),
8111           (COPY_TO_REGCLASS
8112            (ANDPSrm (COPY_TO_REGCLASS FR128:$src1, VR128), f128mem:$src2),
8113            FR128)>;
8114
8115 def : Pat<(X86fand FR128:$src1, FR128:$src2),
8116           (COPY_TO_REGCLASS
8117            (ANDPSrr (COPY_TO_REGCLASS FR128:$src1, VR128),
8118                     (COPY_TO_REGCLASS FR128:$src2, VR128)), FR128)>;
8119
8120 def : Pat<(X86for FR128:$src1, (memopf128 addr:$src2)),
8121           (COPY_TO_REGCLASS
8122            (ORPSrm (COPY_TO_REGCLASS FR128:$src1, VR128), f128mem:$src2),
8123            FR128)>;
8124
8125 def : Pat<(X86for FR128:$src1, FR128:$src2),
8126           (COPY_TO_REGCLASS
8127            (ORPSrr (COPY_TO_REGCLASS FR128:$src1, VR128),
8128                    (COPY_TO_REGCLASS FR128:$src2, VR128)), FR128)>;
8129
8130 def : Pat<(X86fxor FR128:$src1, (memopf128 addr:$src2)),
8131           (COPY_TO_REGCLASS
8132            (XORPSrm (COPY_TO_REGCLASS FR128:$src1, VR128), f128mem:$src2),
8133            FR128)>;
8134
8135 def : Pat<(X86fxor FR128:$src1, FR128:$src2),
8136           (COPY_TO_REGCLASS
8137            (XORPSrr (COPY_TO_REGCLASS FR128:$src1, VR128),
8138                     (COPY_TO_REGCLASS FR128:$src2, VR128)), FR128)>;
8139
8140 //===----------------------------------------------------------------------===//
8141 // GFNI instructions
8142 //===----------------------------------------------------------------------===//
8143
8144 multiclass GF2P8MULB_rm<string OpcodeStr, ValueType OpVT,
8145                         RegisterClass RC, PatFrag MemOpFrag,
8146                         X86MemOperand X86MemOp, bit Is2Addr = 0> {
8147   let ExeDomain = SSEPackedInt,
8148       AsmString = !if(Is2Addr,
8149         OpcodeStr##"\t{$src2, $dst|$dst, $src2}",
8150         OpcodeStr##"\t{$src2, $src1, $dst|$dst, $src1, $src2}") in {
8151     let isCommutable = 1 in
8152     def rr : PDI<0xCF, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2), "",
8153                  [(set RC:$dst, (OpVT (X86GF2P8mulb RC:$src1, RC:$src2)))]>,
8154              Sched<[SchedWriteVecALU.XMM]>, T8PD;
8155
8156     def rm : PDI<0xCF, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, X86MemOp:$src2), "",
8157                  [(set RC:$dst, (OpVT (X86GF2P8mulb RC:$src1,
8158                                  (bitconvert (MemOpFrag addr:$src2)))))]>,
8159              Sched<[SchedWriteVecALU.XMM.Folded, ReadAfterLd]>, T8PD;
8160   }
8161 }
8162
8163 multiclass GF2P8AFFINE_rmi<bits<8> Op, string OpStr, ValueType OpVT,
8164                            SDNode OpNode, RegisterClass RC, PatFrag MemOpFrag,
8165                            X86MemOperand X86MemOp, bit Is2Addr = 0> {
8166   let AsmString = !if(Is2Addr,
8167       OpStr##"\t{$src3, $src2, $dst|$dst, $src2, $src3}",
8168       OpStr##"\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}") in {
8169   def rri : Ii8<Op, MRMSrcReg, (outs RC:$dst),
8170               (ins RC:$src1, RC:$src2, u8imm:$src3), "",
8171               [(set RC:$dst, (OpVT (OpNode RC:$src1, RC:$src2, imm:$src3)))],
8172               SSEPackedInt>, Sched<[SchedWriteVecALU.XMM]>;
8173   def rmi : Ii8<Op, MRMSrcMem, (outs RC:$dst),
8174               (ins RC:$src1, X86MemOp:$src2, u8imm:$src3), "",
8175               [(set RC:$dst, (OpVT (OpNode RC:$src1,
8176                                     (bitconvert (MemOpFrag addr:$src2)),
8177                               imm:$src3)))], SSEPackedInt>,
8178               Sched<[SchedWriteVecALU.XMM.Folded, ReadAfterLd]>;
8179   }
8180 }
8181
8182 multiclass GF2P8AFFINE_common<bits<8> Op, string OpStr, SDNode OpNode> {
8183   let Constraints = "$src1 = $dst",
8184       Predicates  = [HasGFNI, UseSSE2] in
8185   defm NAME         : GF2P8AFFINE_rmi<Op, OpStr, v16i8, OpNode,
8186                                       VR128, loadv2i64, i128mem, 1>;
8187   let Predicates  = [HasGFNI, HasAVX, NoVLX_Or_NoBWI] in {
8188     defm V##NAME    : GF2P8AFFINE_rmi<Op, "v"##OpStr, v16i8, OpNode, VR128,
8189                                       loadv2i64, i128mem>, VEX_4V, VEX_W;
8190     defm V##NAME##Y : GF2P8AFFINE_rmi<Op, "v"##OpStr, v32i8, OpNode, VR256,
8191                                       loadv4i64, i256mem>, VEX_4V, VEX_L, VEX_W;
8192   }
8193 }
8194
8195 // GF2P8MULB
8196 let Constraints = "$src1 = $dst",
8197     Predicates  = [HasGFNI, UseSSE2] in
8198 defm GF2P8MULB      : GF2P8MULB_rm<"gf2p8mulb", v16i8, VR128, memopv2i64,
8199                                     i128mem, 1>;
8200 let Predicates  = [HasGFNI, HasAVX, NoVLX_Or_NoBWI] in {
8201   defm VGF2P8MULB   : GF2P8MULB_rm<"vgf2p8mulb", v16i8, VR128, loadv2i64,
8202                                    i128mem>, VEX_4V;
8203   defm VGF2P8MULBY  : GF2P8MULB_rm<"vgf2p8mulb", v32i8, VR256, loadv4i64,
8204                                    i256mem>, VEX_4V, VEX_L;
8205 }
8206 // GF2P8AFFINEINVQB, GF2P8AFFINEQB
8207 let isCommutable = 0 in {
8208   defm GF2P8AFFINEINVQB : GF2P8AFFINE_common<0xCF, "gf2p8affineinvqb",
8209                                              X86GF2P8affineinvqb>, TAPD;
8210   defm GF2P8AFFINEQB    : GF2P8AFFINE_common<0xCE, "gf2p8affineqb",
8211                                              X86GF2P8affineqb>, TAPD;
8212 }
8213