]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/Target/X86/X86InstrSSE.td
MFV r325605: 8713 Buffer overflow in dsl_dataset_name()
[FreeBSD/FreeBSD.git] / contrib / llvm / 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 class OpndItins<InstrItinClass arg_rr, InstrItinClass arg_rm> {
17   InstrItinClass rr = arg_rr;
18   InstrItinClass rm = arg_rm;
19   // InstrSchedModel info.
20   X86FoldableSchedWrite Sched = WriteFAdd;
21 }
22
23 class SizeItins<OpndItins arg_s, OpndItins arg_d> {
24   OpndItins s = arg_s;
25   OpndItins d = arg_d;
26 }
27
28
29 class ShiftOpndItins<InstrItinClass arg_rr, InstrItinClass arg_rm,
30   InstrItinClass arg_ri> {
31   InstrItinClass rr = arg_rr;
32   InstrItinClass rm = arg_rm;
33   InstrItinClass ri = arg_ri;
34 }
35
36 // scalar
37 let Sched = WriteFAdd in {
38 def SSE_ALU_F32S : OpndItins<
39   IIC_SSE_ALU_F32S_RR, IIC_SSE_ALU_F32S_RM
40 >;
41
42 def SSE_ALU_F64S : OpndItins<
43   IIC_SSE_ALU_F64S_RR, IIC_SSE_ALU_F64S_RM
44 >;
45 }
46
47 def SSE_ALU_ITINS_S : SizeItins<
48   SSE_ALU_F32S, SSE_ALU_F64S
49 >;
50
51 let Sched = WriteFMul in {
52 def SSE_MUL_F32S : OpndItins<
53   IIC_SSE_MUL_F32S_RR, IIC_SSE_MUL_F64S_RM
54 >;
55
56 def SSE_MUL_F64S : OpndItins<
57   IIC_SSE_MUL_F64S_RR, IIC_SSE_MUL_F64S_RM
58 >;
59 }
60
61 def SSE_MUL_ITINS_S : SizeItins<
62   SSE_MUL_F32S, SSE_MUL_F64S
63 >;
64
65 let Sched = WriteFDiv in {
66 def SSE_DIV_F32S : OpndItins<
67   IIC_SSE_DIV_F32S_RR, IIC_SSE_DIV_F64S_RM
68 >;
69
70 def SSE_DIV_F64S : OpndItins<
71   IIC_SSE_DIV_F64S_RR, IIC_SSE_DIV_F64S_RM
72 >;
73 }
74
75 def SSE_DIV_ITINS_S : SizeItins<
76   SSE_DIV_F32S, SSE_DIV_F64S
77 >;
78
79 // parallel
80 let Sched = WriteFAdd in {
81 def SSE_ALU_F32P : OpndItins<
82   IIC_SSE_ALU_F32P_RR, IIC_SSE_ALU_F32P_RM
83 >;
84
85 def SSE_ALU_F64P : OpndItins<
86   IIC_SSE_ALU_F64P_RR, IIC_SSE_ALU_F64P_RM
87 >;
88 }
89
90 def SSE_ALU_ITINS_P : SizeItins<
91   SSE_ALU_F32P, SSE_ALU_F64P
92 >;
93
94 let Sched = WriteFMul in {
95 def SSE_MUL_F32P : OpndItins<
96   IIC_SSE_MUL_F32P_RR, IIC_SSE_MUL_F64P_RM
97 >;
98
99 def SSE_MUL_F64P : OpndItins<
100   IIC_SSE_MUL_F64P_RR, IIC_SSE_MUL_F64P_RM
101 >;
102 }
103
104 def SSE_MUL_ITINS_P : SizeItins<
105   SSE_MUL_F32P, SSE_MUL_F64P
106 >;
107
108 let Sched = WriteFDiv in {
109 def SSE_DIV_F32P : OpndItins<
110   IIC_SSE_DIV_F32P_RR, IIC_SSE_DIV_F64P_RM
111 >;
112
113 def SSE_DIV_F64P : OpndItins<
114   IIC_SSE_DIV_F64P_RR, IIC_SSE_DIV_F64P_RM
115 >;
116 }
117
118 def SSE_DIV_ITINS_P : SizeItins<
119   SSE_DIV_F32P, SSE_DIV_F64P
120 >;
121
122 let Sched = WriteVecLogic in
123 def SSE_VEC_BIT_ITINS_P : OpndItins<
124   IIC_SSE_BIT_P_RR, IIC_SSE_BIT_P_RM
125 >;
126
127 def SSE_BIT_ITINS_P : OpndItins<
128   IIC_SSE_BIT_P_RR, IIC_SSE_BIT_P_RM
129 >;
130
131 let Sched = WriteVecALU in {
132 def SSE_INTALU_ITINS_P : OpndItins<
133   IIC_SSE_INTALU_P_RR, IIC_SSE_INTALU_P_RM
134 >;
135
136 def SSE_INTALUQ_ITINS_P : OpndItins<
137   IIC_SSE_INTALUQ_P_RR, IIC_SSE_INTALUQ_P_RM
138 >;
139 }
140
141 let Sched = WriteVecIMul in
142 def SSE_INTMUL_ITINS_P : OpndItins<
143   IIC_SSE_INTMUL_P_RR, IIC_SSE_INTMUL_P_RM
144 >;
145
146 def SSE_INTSHIFT_ITINS_P : ShiftOpndItins<
147   IIC_SSE_INTSH_P_RR, IIC_SSE_INTSH_P_RM, IIC_SSE_INTSH_P_RI
148 >;
149
150 def SSE_MOVA_ITINS : OpndItins<
151   IIC_SSE_MOVA_P_RR, IIC_SSE_MOVA_P_RM
152 >;
153
154 def SSE_MOVU_ITINS : OpndItins<
155   IIC_SSE_MOVU_P_RR, IIC_SSE_MOVU_P_RM
156 >;
157
158 def SSE_DPPD_ITINS : OpndItins<
159   IIC_SSE_DPPD_RR, IIC_SSE_DPPD_RM
160 >;
161
162 def SSE_DPPS_ITINS : OpndItins<
163   IIC_SSE_DPPS_RR, IIC_SSE_DPPD_RM
164 >;
165
166 def DEFAULT_ITINS : OpndItins<
167   IIC_ALU_NONMEM, IIC_ALU_MEM
168 >;
169
170 def SSE_EXTRACT_ITINS : OpndItins<
171   IIC_SSE_EXTRACTPS_RR, IIC_SSE_EXTRACTPS_RM
172 >;
173
174 def SSE_INSERT_ITINS : OpndItins<
175   IIC_SSE_INSERTPS_RR, IIC_SSE_INSERTPS_RM
176 >;
177
178 let Sched = WriteMPSAD in
179 def SSE_MPSADBW_ITINS : OpndItins<
180   IIC_SSE_MPSADBW_RR, IIC_SSE_MPSADBW_RM
181 >;
182
183 let Sched = WriteVecIMul in
184 def SSE_PMULLD_ITINS : OpndItins<
185   IIC_SSE_PMULLD_RR, IIC_SSE_PMULLD_RM
186 >;
187
188 // Definitions for backward compatibility.
189 // The instructions mapped on these definitions uses a different itinerary
190 // than the actual scheduling model.
191 let Sched = WriteShuffle in
192 def DEFAULT_ITINS_SHUFFLESCHED :  OpndItins<
193   IIC_ALU_NONMEM, IIC_ALU_MEM
194 >;
195
196 let Sched = WriteVecIMul in
197 def DEFAULT_ITINS_VECIMULSCHED :  OpndItins<
198   IIC_ALU_NONMEM, IIC_ALU_MEM
199 >;
200
201 let Sched = WriteShuffle in
202 def SSE_INTALU_ITINS_SHUFF_P : OpndItins<
203   IIC_SSE_INTALU_P_RR, IIC_SSE_INTALU_P_RM
204 >;
205
206 let Sched = WriteMPSAD in
207 def DEFAULT_ITINS_MPSADSCHED :  OpndItins<
208   IIC_ALU_NONMEM, IIC_ALU_MEM
209 >;
210
211 let Sched = WriteFBlend in
212 def DEFAULT_ITINS_FBLENDSCHED :  OpndItins<
213   IIC_ALU_NONMEM, IIC_ALU_MEM
214 >;
215
216 let Sched = WriteBlend in
217 def DEFAULT_ITINS_BLENDSCHED :  OpndItins<
218   IIC_ALU_NONMEM, IIC_ALU_MEM
219 >;
220
221 let Sched = WriteVarBlend in
222 def DEFAULT_ITINS_VARBLENDSCHED :  OpndItins<
223   IIC_ALU_NONMEM, IIC_ALU_MEM
224 >;
225
226 let Sched = WriteFBlend in
227 def SSE_INTALU_ITINS_FBLEND_P : OpndItins<
228   IIC_SSE_INTALU_P_RR, IIC_SSE_INTALU_P_RM
229 >;
230
231 let Sched = WriteBlend in
232 def SSE_INTALU_ITINS_BLEND_P : OpndItins<
233   IIC_SSE_INTALU_P_RR, IIC_SSE_INTALU_P_RM
234 >;
235
236 //===----------------------------------------------------------------------===//
237 // SSE 1 & 2 Instructions Classes
238 //===----------------------------------------------------------------------===//
239
240 /// sse12_fp_scalar - SSE 1 & 2 scalar instructions class
241 multiclass sse12_fp_scalar<bits<8> opc, string OpcodeStr, SDNode OpNode,
242                            RegisterClass RC, X86MemOperand x86memop,
243                            Domain d, OpndItins itins, bit Is2Addr = 1> {
244   let isCommutable = 1 in {
245     def rr : SI<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
246        !if(Is2Addr,
247            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
248            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
249        [(set RC:$dst, (OpNode RC:$src1, RC:$src2))], itins.rr, d>,
250        Sched<[itins.Sched]>;
251   }
252   def rm : SI<opc, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
253        !if(Is2Addr,
254            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
255            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
256        [(set RC:$dst, (OpNode RC:$src1, (load addr:$src2)))], itins.rm, d>,
257        Sched<[itins.Sched.Folded, ReadAfterLd]>;
258 }
259
260 /// sse12_fp_scalar_int - SSE 1 & 2 scalar instructions intrinsics class
261 multiclass sse12_fp_scalar_int<bits<8> opc, string OpcodeStr,
262                                SDPatternOperator OpNode, RegisterClass RC,
263                                ValueType VT, string asm, Operand memopr,
264                                ComplexPattern mem_cpat, Domain d,
265                                OpndItins itins, bit Is2Addr = 1> {
266 let isCodeGenOnly = 1, hasSideEffects = 0 in {
267   def rr_Int : SI_Int<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
268        !if(Is2Addr,
269            !strconcat(asm, "\t{$src2, $dst|$dst, $src2}"),
270            !strconcat(asm, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
271        [(set RC:$dst, (VT (OpNode RC:$src1, RC:$src2)))], itins.rr, d>,
272        Sched<[itins.Sched]>;
273   let mayLoad = 1 in
274   def rm_Int : SI_Int<opc, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, memopr:$src2),
275        !if(Is2Addr,
276            !strconcat(asm, "\t{$src2, $dst|$dst, $src2}"),
277            !strconcat(asm, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
278        [(set RC:$dst, (VT (OpNode RC:$src1, mem_cpat:$src2)))], itins.rm, d>,
279        Sched<[itins.Sched.Folded, ReadAfterLd]>;
280 }
281 }
282
283 /// sse12_fp_packed - SSE 1 & 2 packed instructions class
284 multiclass sse12_fp_packed<bits<8> opc, string OpcodeStr, SDNode OpNode,
285                            RegisterClass RC, ValueType vt,
286                            X86MemOperand x86memop, PatFrag mem_frag,
287                            Domain d, OpndItins itins, bit Is2Addr = 1> {
288   let isCommutable = 1 in
289     def rr : PI<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
290        !if(Is2Addr,
291            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
292            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
293        [(set RC:$dst, (vt (OpNode RC:$src1, RC:$src2)))], itins.rr, d>,
294        Sched<[itins.Sched]>;
295   let mayLoad = 1 in
296     def rm : PI<opc, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
297        !if(Is2Addr,
298            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
299            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
300        [(set RC:$dst, (OpNode RC:$src1, (mem_frag addr:$src2)))],
301           itins.rm, d>,
302        Sched<[itins.Sched.Folded, ReadAfterLd]>;
303 }
304
305 /// sse12_fp_packed_logical_rm - SSE 1 & 2 packed instructions class
306 multiclass sse12_fp_packed_logical_rm<bits<8> opc, RegisterClass RC, Domain d,
307                                       string OpcodeStr, X86MemOperand x86memop,
308                                       list<dag> pat_rr, list<dag> pat_rm,
309                                       bit Is2Addr = 1> {
310   let isCommutable = 1, hasSideEffects = 0 in
311     def rr : PI<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
312        !if(Is2Addr,
313            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
314            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
315        pat_rr, NoItinerary, d>,
316        Sched<[WriteVecLogic]>;
317   def rm : PI<opc, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
318        !if(Is2Addr,
319            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
320            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
321        pat_rm, NoItinerary, d>,
322        Sched<[WriteVecLogicLd, ReadAfterLd]>;
323 }
324
325 //===----------------------------------------------------------------------===//
326 //  Non-instruction patterns
327 //===----------------------------------------------------------------------===//
328
329 // A vector extract of the first f32/f64 position is a subregister copy
330 def : Pat<(f32 (extractelt (v4f32 VR128:$src), (iPTR 0))),
331           (COPY_TO_REGCLASS (v4f32 VR128:$src), FR32)>;
332 def : Pat<(f64 (extractelt (v2f64 VR128:$src), (iPTR 0))),
333           (COPY_TO_REGCLASS (v2f64 VR128:$src), FR64)>;
334
335 // A 128-bit subvector extract from the first 256-bit vector position
336 // is a subregister copy that needs no instruction.
337 def : Pat<(v4i32 (extract_subvector (v8i32 VR256:$src), (iPTR 0))),
338           (v4i32 (EXTRACT_SUBREG (v8i32 VR256:$src), sub_xmm))>;
339 def : Pat<(v4f32 (extract_subvector (v8f32 VR256:$src), (iPTR 0))),
340           (v4f32 (EXTRACT_SUBREG (v8f32 VR256:$src), sub_xmm))>;
341
342 def : Pat<(v2i64 (extract_subvector (v4i64 VR256:$src), (iPTR 0))),
343           (v2i64 (EXTRACT_SUBREG (v4i64 VR256:$src), sub_xmm))>;
344 def : Pat<(v2f64 (extract_subvector (v4f64 VR256:$src), (iPTR 0))),
345           (v2f64 (EXTRACT_SUBREG (v4f64 VR256:$src), sub_xmm))>;
346
347 def : Pat<(v8i16 (extract_subvector (v16i16 VR256:$src), (iPTR 0))),
348           (v8i16 (EXTRACT_SUBREG (v16i16 VR256:$src), sub_xmm))>;
349 def : Pat<(v16i8 (extract_subvector (v32i8 VR256:$src), (iPTR 0))),
350           (v16i8 (EXTRACT_SUBREG (v32i8 VR256:$src), sub_xmm))>;
351
352 // A 128-bit subvector insert to the first 256-bit vector position
353 // is a subregister copy that needs no instruction.
354 let AddedComplexity = 25 in { // to give priority over vinsertf128rm
355 def : Pat<(insert_subvector undef, (v2i64 VR128:$src), (iPTR 0)),
356           (INSERT_SUBREG (v4i64 (IMPLICIT_DEF)), VR128:$src, sub_xmm)>;
357 def : Pat<(insert_subvector undef, (v2f64 VR128:$src), (iPTR 0)),
358           (INSERT_SUBREG (v4f64 (IMPLICIT_DEF)), VR128:$src, sub_xmm)>;
359 def : Pat<(insert_subvector undef, (v4i32 VR128:$src), (iPTR 0)),
360           (INSERT_SUBREG (v8i32 (IMPLICIT_DEF)), VR128:$src, sub_xmm)>;
361 def : Pat<(insert_subvector undef, (v4f32 VR128:$src), (iPTR 0)),
362           (INSERT_SUBREG (v8f32 (IMPLICIT_DEF)), VR128:$src, sub_xmm)>;
363 def : Pat<(insert_subvector undef, (v8i16 VR128:$src), (iPTR 0)),
364           (INSERT_SUBREG (v16i16 (IMPLICIT_DEF)), VR128:$src, sub_xmm)>;
365 def : Pat<(insert_subvector undef, (v16i8 VR128:$src), (iPTR 0)),
366           (INSERT_SUBREG (v32i8 (IMPLICIT_DEF)), VR128:$src, sub_xmm)>;
367 }
368
369 // Implicitly promote a 32-bit scalar to a vector.
370 def : Pat<(v4f32 (scalar_to_vector FR32:$src)),
371           (COPY_TO_REGCLASS FR32:$src, VR128)>;
372 // Implicitly promote a 64-bit scalar to a vector.
373 def : Pat<(v2f64 (scalar_to_vector FR64:$src)),
374           (COPY_TO_REGCLASS FR64:$src, VR128)>;
375
376 // Bitcasts between 128-bit vector types. Return the original type since
377 // no instruction is needed for the conversion
378 def : Pat<(v2i64 (bitconvert (v4i32 VR128:$src))), (v2i64 VR128:$src)>;
379 def : Pat<(v2i64 (bitconvert (v8i16 VR128:$src))), (v2i64 VR128:$src)>;
380 def : Pat<(v2i64 (bitconvert (v16i8 VR128:$src))), (v2i64 VR128:$src)>;
381 def : Pat<(v2i64 (bitconvert (v2f64 VR128:$src))), (v2i64 VR128:$src)>;
382 def : Pat<(v2i64 (bitconvert (v4f32 VR128:$src))), (v2i64 VR128:$src)>;
383 def : Pat<(v4i32 (bitconvert (v2i64 VR128:$src))), (v4i32 VR128:$src)>;
384 def : Pat<(v4i32 (bitconvert (v8i16 VR128:$src))), (v4i32 VR128:$src)>;
385 def : Pat<(v4i32 (bitconvert (v16i8 VR128:$src))), (v4i32 VR128:$src)>;
386 def : Pat<(v4i32 (bitconvert (v2f64 VR128:$src))), (v4i32 VR128:$src)>;
387 def : Pat<(v4i32 (bitconvert (v4f32 VR128:$src))), (v4i32 VR128:$src)>;
388 def : Pat<(v8i16 (bitconvert (v2i64 VR128:$src))), (v8i16 VR128:$src)>;
389 def : Pat<(v8i16 (bitconvert (v4i32 VR128:$src))), (v8i16 VR128:$src)>;
390 def : Pat<(v8i16 (bitconvert (v16i8 VR128:$src))), (v8i16 VR128:$src)>;
391 def : Pat<(v8i16 (bitconvert (v2f64 VR128:$src))), (v8i16 VR128:$src)>;
392 def : Pat<(v8i16 (bitconvert (v4f32 VR128:$src))), (v8i16 VR128:$src)>;
393 def : Pat<(v16i8 (bitconvert (v2i64 VR128:$src))), (v16i8 VR128:$src)>;
394 def : Pat<(v16i8 (bitconvert (v4i32 VR128:$src))), (v16i8 VR128:$src)>;
395 def : Pat<(v16i8 (bitconvert (v8i16 VR128:$src))), (v16i8 VR128:$src)>;
396 def : Pat<(v16i8 (bitconvert (v2f64 VR128:$src))), (v16i8 VR128:$src)>;
397 def : Pat<(v16i8 (bitconvert (v4f32 VR128:$src))), (v16i8 VR128:$src)>;
398 def : Pat<(v4f32 (bitconvert (v2i64 VR128:$src))), (v4f32 VR128:$src)>;
399 def : Pat<(v4f32 (bitconvert (v4i32 VR128:$src))), (v4f32 VR128:$src)>;
400 def : Pat<(v4f32 (bitconvert (v8i16 VR128:$src))), (v4f32 VR128:$src)>;
401 def : Pat<(v4f32 (bitconvert (v16i8 VR128:$src))), (v4f32 VR128:$src)>;
402 def : Pat<(v4f32 (bitconvert (v2f64 VR128:$src))), (v4f32 VR128:$src)>;
403 def : Pat<(v2f64 (bitconvert (v2i64 VR128:$src))), (v2f64 VR128:$src)>;
404 def : Pat<(v2f64 (bitconvert (v4i32 VR128:$src))), (v2f64 VR128:$src)>;
405 def : Pat<(v2f64 (bitconvert (v8i16 VR128:$src))), (v2f64 VR128:$src)>;
406 def : Pat<(v2f64 (bitconvert (v16i8 VR128:$src))), (v2f64 VR128:$src)>;
407 def : Pat<(v2f64 (bitconvert (v4f32 VR128:$src))), (v2f64 VR128:$src)>;
408 def : Pat<(f128  (bitconvert (i128  FR128:$src))), (f128  FR128:$src)>;
409 def : Pat<(i128  (bitconvert (f128  FR128:$src))), (i128  FR128:$src)>;
410
411 // Bitcasts between 256-bit vector types. Return the original type since
412 // no instruction is needed for the conversion
413 def : Pat<(v4i64  (bitconvert (v8i32  VR256:$src))), (v4i64  VR256:$src)>;
414 def : Pat<(v4i64  (bitconvert (v16i16 VR256:$src))), (v4i64  VR256:$src)>;
415 def : Pat<(v4i64  (bitconvert (v32i8  VR256:$src))), (v4i64  VR256:$src)>;
416 def : Pat<(v4i64  (bitconvert (v8f32  VR256:$src))), (v4i64  VR256:$src)>;
417 def : Pat<(v4i64  (bitconvert (v4f64  VR256:$src))), (v4i64  VR256:$src)>;
418 def : Pat<(v8i32  (bitconvert (v4i64  VR256:$src))), (v8i32  VR256:$src)>;
419 def : Pat<(v8i32  (bitconvert (v16i16 VR256:$src))), (v8i32  VR256:$src)>;
420 def : Pat<(v8i32  (bitconvert (v32i8  VR256:$src))), (v8i32  VR256:$src)>;
421 def : Pat<(v8i32  (bitconvert (v4f64  VR256:$src))), (v8i32  VR256:$src)>;
422 def : Pat<(v8i32  (bitconvert (v8f32  VR256:$src))), (v8i32  VR256:$src)>;
423 def : Pat<(v16i16 (bitconvert (v4i64  VR256:$src))), (v16i16 VR256:$src)>;
424 def : Pat<(v16i16 (bitconvert (v8i32  VR256:$src))), (v16i16 VR256:$src)>;
425 def : Pat<(v16i16 (bitconvert (v32i8  VR256:$src))), (v16i16 VR256:$src)>;
426 def : Pat<(v16i16 (bitconvert (v4f64  VR256:$src))), (v16i16 VR256:$src)>;
427 def : Pat<(v16i16 (bitconvert (v8f32  VR256:$src))), (v16i16 VR256:$src)>;
428 def : Pat<(v32i8  (bitconvert (v4i64  VR256:$src))), (v32i8  VR256:$src)>;
429 def : Pat<(v32i8  (bitconvert (v8i32  VR256:$src))), (v32i8  VR256:$src)>;
430 def : Pat<(v32i8  (bitconvert (v16i16 VR256:$src))), (v32i8  VR256:$src)>;
431 def : Pat<(v32i8  (bitconvert (v4f64  VR256:$src))), (v32i8  VR256:$src)>;
432 def : Pat<(v32i8  (bitconvert (v8f32  VR256:$src))), (v32i8  VR256:$src)>;
433 def : Pat<(v8f32  (bitconvert (v4i64  VR256:$src))), (v8f32  VR256:$src)>;
434 def : Pat<(v8f32  (bitconvert (v8i32  VR256:$src))), (v8f32  VR256:$src)>;
435 def : Pat<(v8f32  (bitconvert (v16i16 VR256:$src))), (v8f32  VR256:$src)>;
436 def : Pat<(v8f32  (bitconvert (v32i8  VR256:$src))), (v8f32  VR256:$src)>;
437 def : Pat<(v8f32  (bitconvert (v4f64  VR256:$src))), (v8f32  VR256:$src)>;
438 def : Pat<(v4f64  (bitconvert (v4i64  VR256:$src))), (v4f64  VR256:$src)>;
439 def : Pat<(v4f64  (bitconvert (v8i32  VR256:$src))), (v4f64  VR256:$src)>;
440 def : Pat<(v4f64  (bitconvert (v16i16 VR256:$src))), (v4f64  VR256:$src)>;
441 def : Pat<(v4f64  (bitconvert (v32i8  VR256:$src))), (v4f64  VR256:$src)>;
442 def : Pat<(v4f64  (bitconvert (v8f32  VR256:$src))), (v4f64  VR256:$src)>;
443
444 // Alias instructions that map fld0 to xorps for sse or vxorps for avx.
445 // This is expanded by ExpandPostRAPseudos.
446 let isReMaterializable = 1, isAsCheapAsAMove = 1, canFoldAsLoad = 1,
447     isPseudo = 1, SchedRW = [WriteZero] in {
448   def FsFLD0SS : I<0, Pseudo, (outs FR32:$dst), (ins), "",
449                    [(set FR32:$dst, fp32imm0)]>, Requires<[HasSSE1, NoAVX512]>;
450   def FsFLD0SD : I<0, Pseudo, (outs FR64:$dst), (ins), "",
451                    [(set FR64:$dst, fpimm0)]>, Requires<[HasSSE2, NoAVX512]>;
452 }
453
454 //===----------------------------------------------------------------------===//
455 // AVX & SSE - Zero/One Vectors
456 //===----------------------------------------------------------------------===//
457
458 // Alias instruction that maps zero vector to pxor / xorp* for sse.
459 // This is expanded by ExpandPostRAPseudos to an xorps / vxorps, and then
460 // swizzled by ExecutionDepsFix to pxor.
461 // We set canFoldAsLoad because this can be converted to a constant-pool
462 // load of an all-zeros value if folding it would be beneficial.
463 let isReMaterializable = 1, isAsCheapAsAMove = 1, canFoldAsLoad = 1,
464     isPseudo = 1, SchedRW = [WriteZero] in {
465 def V_SET0 : I<0, Pseudo, (outs VR128:$dst), (ins), "",
466                [(set VR128:$dst, (v4f32 immAllZerosV))]>;
467 }
468
469 let Predicates = [NoAVX512] in
470 def : Pat<(v4i32 immAllZerosV), (V_SET0)>;
471
472
473 // The same as done above but for AVX.  The 256-bit AVX1 ISA doesn't support PI,
474 // and doesn't need it because on sandy bridge the register is set to zero
475 // at the rename stage without using any execution unit, so SET0PSY
476 // and SET0PDY can be used for vector int instructions without penalty
477 let isReMaterializable = 1, isAsCheapAsAMove = 1, canFoldAsLoad = 1,
478     isPseudo = 1, Predicates = [NoAVX512], SchedRW = [WriteZero] in {
479 def AVX_SET0 : I<0, Pseudo, (outs VR256:$dst), (ins), "",
480                  [(set VR256:$dst, (v8i32 immAllZerosV))]>;
481 }
482
483 // We set canFoldAsLoad because this can be converted to a constant-pool
484 // load of an all-ones value if folding it would be beneficial.
485 let isReMaterializable = 1, isAsCheapAsAMove = 1, canFoldAsLoad = 1,
486     isPseudo = 1, SchedRW = [WriteZero] in {
487   def V_SETALLONES : I<0, Pseudo, (outs VR128:$dst), (ins), "",
488                        [(set VR128:$dst, (v4i32 immAllOnesV))]>;
489   let Predicates = [HasAVX1Only, OptForMinSize] in {
490   def AVX1_SETALLONES: I<0, Pseudo, (outs VR256:$dst), (ins), "",
491                           [(set VR256:$dst, (v8i32 immAllOnesV))]>;
492   }
493   let Predicates = [HasAVX2] in
494   def AVX2_SETALLONES : I<0, Pseudo, (outs VR256:$dst), (ins), "",
495                           [(set VR256:$dst, (v8i32 immAllOnesV))]>;
496 }
497
498 //===----------------------------------------------------------------------===//
499 // SSE 1 & 2 - Move FP Scalar Instructions
500 //
501 // Move Instructions. Register-to-register movss/movsd is not used for FR32/64
502 // register copies because it's a partial register update; Register-to-register
503 // movss/movsd is not modeled as an INSERT_SUBREG because INSERT_SUBREG requires
504 // that the insert be implementable in terms of a copy, and just mentioned, we
505 // don't use movss/movsd for copies.
506 //===----------------------------------------------------------------------===//
507
508 multiclass sse12_move_rr<RegisterClass RC, SDNode OpNode, ValueType vt,
509                          X86MemOperand x86memop, string base_opc,
510                          string asm_opr, Domain d = GenericDomain,
511                          string Name> {
512   let isCommutable = 1 in
513   def rr : SI<0x10, MRMSrcReg, (outs VR128:$dst),
514               (ins VR128:$src1, RC:$src2),
515               !strconcat(base_opc, asm_opr),
516               [(set VR128:$dst, (vt (OpNode VR128:$src1,
517                                  (scalar_to_vector RC:$src2))))],
518               IIC_SSE_MOV_S_RR, d>, Sched<[WriteFShuffle]>;
519
520   // For the disassembler
521   let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0 in
522   def rr_REV : SI<0x11, MRMDestReg, (outs VR128:$dst),
523                   (ins VR128:$src1, RC:$src2),
524                   !strconcat(base_opc, asm_opr),
525                   [], IIC_SSE_MOV_S_RR>, Sched<[WriteFShuffle]>,
526                   FoldGenData<Name#rr>;
527 }
528
529 multiclass sse12_move<RegisterClass RC, SDNode OpNode, ValueType vt,
530                       X86MemOperand x86memop, string OpcodeStr,
531                       Domain d = GenericDomain, string Name> {
532   // AVX
533   defm V#NAME : sse12_move_rr<RC, OpNode, vt, x86memop, OpcodeStr,
534                               "\t{$src2, $src1, $dst|$dst, $src1, $src2}", d,
535                               "V"#Name>,
536                               VEX_4V, VEX_LIG, VEX_WIG;
537
538   def V#NAME#mr : SI<0x11, MRMDestMem, (outs), (ins x86memop:$dst, RC:$src),
539                      !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
540                      [(store RC:$src, addr:$dst)], IIC_SSE_MOV_S_MR, d>,
541                      VEX, VEX_LIG, Sched<[WriteStore]>, VEX_WIG;
542   // SSE1 & 2
543   let Constraints = "$src1 = $dst" in {
544     defm NAME : sse12_move_rr<RC, OpNode, vt, x86memop, OpcodeStr,
545                               "\t{$src2, $dst|$dst, $src2}", d, Name>;
546   }
547
548   def NAME#mr   : SI<0x11, MRMDestMem, (outs), (ins x86memop:$dst, RC:$src),
549                      !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
550                      [(store RC:$src, addr:$dst)], IIC_SSE_MOV_S_MR, d>,
551                   Sched<[WriteStore]>;
552 }
553
554 // Loading from memory automatically zeroing upper bits.
555 multiclass sse12_move_rm<RegisterClass RC, X86MemOperand x86memop,
556                          PatFrag mem_pat, string OpcodeStr,
557                          Domain d = GenericDomain> {
558   def V#NAME#rm : SI<0x10, MRMSrcMem, (outs RC:$dst), (ins x86memop:$src),
559                      !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
560                      [(set RC:$dst, (mem_pat addr:$src))],
561                      IIC_SSE_MOV_S_RM, d>, VEX, VEX_LIG, Sched<[WriteLoad]>, VEX_WIG;
562   def NAME#rm   : SI<0x10, MRMSrcMem, (outs RC:$dst), (ins x86memop:$src),
563                      !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
564                      [(set RC:$dst, (mem_pat addr:$src))],
565                      IIC_SSE_MOV_S_RM, d>, Sched<[WriteLoad]>;
566 }
567
568 defm MOVSS : sse12_move<FR32, X86Movss, v4f32, f32mem, "movss",
569                         SSEPackedSingle, "MOVSS">, XS;
570 defm MOVSD : sse12_move<FR64, X86Movsd, v2f64, f64mem, "movsd",
571                         SSEPackedDouble, "MOVSD">, XD;
572
573 let canFoldAsLoad = 1, isReMaterializable = 1 in {
574   defm MOVSS : sse12_move_rm<FR32, f32mem, loadf32, "movss",
575                              SSEPackedSingle>, XS;
576
577   let AddedComplexity = 20 in
578     defm MOVSD : sse12_move_rm<FR64, f64mem, loadf64, "movsd",
579                                SSEPackedDouble>, XD;
580 }
581
582 // Patterns
583 let Predicates = [UseAVX] in {
584   let AddedComplexity = 20 in {
585   // MOVSSrm zeros the high parts of the register; represent this
586   // with SUBREG_TO_REG. The AVX versions also write: DST[255:128] <- 0
587   def : Pat<(v4f32 (X86vzmovl (v4f32 (scalar_to_vector (loadf32 addr:$src))))),
588             (COPY_TO_REGCLASS (VMOVSSrm addr:$src), VR128)>;
589   def : Pat<(v4f32 (scalar_to_vector (loadf32 addr:$src))),
590             (COPY_TO_REGCLASS (VMOVSSrm addr:$src), VR128)>;
591   def : Pat<(v4f32 (X86vzmovl (loadv4f32 addr:$src))),
592             (COPY_TO_REGCLASS (VMOVSSrm addr:$src), VR128)>;
593   def : Pat<(v4f32 (X86vzload addr:$src)),
594             (COPY_TO_REGCLASS (VMOVSSrm addr:$src), VR128)>;
595
596   // MOVSDrm zeros the high parts of the register; represent this
597   // with SUBREG_TO_REG. The AVX versions also write: DST[255:128] <- 0
598   def : Pat<(v2f64 (X86vzmovl (v2f64 (scalar_to_vector (loadf64 addr:$src))))),
599             (COPY_TO_REGCLASS (VMOVSDrm addr:$src), VR128)>;
600   def : Pat<(v2f64 (scalar_to_vector (loadf64 addr:$src))),
601             (COPY_TO_REGCLASS (VMOVSDrm addr:$src), VR128)>;
602   def : Pat<(v2f64 (X86vzmovl (loadv2f64 addr:$src))),
603             (COPY_TO_REGCLASS (VMOVSDrm addr:$src), VR128)>;
604   def : Pat<(v2f64 (X86vzmovl (bc_v2f64 (loadv4f32 addr:$src)))),
605             (COPY_TO_REGCLASS (VMOVSDrm addr:$src), VR128)>;
606   def : Pat<(v2f64 (X86vzload addr:$src)),
607             (COPY_TO_REGCLASS (VMOVSDrm addr:$src), VR128)>;
608
609   // Represent the same patterns above but in the form they appear for
610   // 256-bit types
611   def : Pat<(v8f32 (X86vzmovl (insert_subvector undef,
612                    (v4f32 (scalar_to_vector (loadf32 addr:$src))), (iPTR 0)))),
613             (SUBREG_TO_REG (i32 0), (VMOVSSrm addr:$src), sub_xmm)>;
614   def : Pat<(v8f32 (X86vzload addr:$src)),
615             (SUBREG_TO_REG (i32 0), (VMOVSSrm addr:$src), sub_xmm)>;
616   def : Pat<(v4f64 (X86vzmovl (insert_subvector undef,
617                    (v2f64 (scalar_to_vector (loadf64 addr:$src))), (iPTR 0)))),
618             (SUBREG_TO_REG (i32 0), (VMOVSDrm addr:$src), sub_xmm)>;
619   def : Pat<(v4f64 (X86vzload addr:$src)),
620             (SUBREG_TO_REG (i32 0), (VMOVSDrm addr:$src), sub_xmm)>;
621   }
622
623   // Extract and store.
624   def : Pat<(store (f32 (extractelt (v4f32 VR128:$src), (iPTR 0))),
625                    addr:$dst),
626             (VMOVSSmr addr:$dst, (COPY_TO_REGCLASS (v4f32 VR128:$src), FR32))>;
627
628   // Shuffle with VMOVSS
629   def : Pat<(v4i32 (X86Movss VR128:$src1, VR128:$src2)),
630             (VMOVSSrr (v4i32 VR128:$src1),
631                       (COPY_TO_REGCLASS (v4i32 VR128:$src2), FR32))>;
632   def : Pat<(v4f32 (X86Movss VR128:$src1, VR128:$src2)),
633             (VMOVSSrr (v4f32 VR128:$src1),
634                       (COPY_TO_REGCLASS (v4f32 VR128:$src2), FR32))>;
635
636   // 256-bit variants
637   def : Pat<(v8i32 (X86Movss VR256:$src1, VR256:$src2)),
638             (SUBREG_TO_REG (i32 0),
639               (VMOVSSrr (EXTRACT_SUBREG (v8i32 VR256:$src1), sub_xmm),
640                         (EXTRACT_SUBREG (v8i32 VR256:$src2), sub_xmm)),
641               sub_xmm)>;
642   def : Pat<(v8f32 (X86Movss VR256:$src1, VR256:$src2)),
643             (SUBREG_TO_REG (i32 0),
644               (VMOVSSrr (EXTRACT_SUBREG (v8f32 VR256:$src1), sub_xmm),
645                         (EXTRACT_SUBREG (v8f32 VR256:$src2), sub_xmm)),
646               sub_xmm)>;
647
648   // Shuffle with VMOVSD
649   def : Pat<(v2i64 (X86Movsd VR128:$src1, VR128:$src2)),
650             (VMOVSDrr VR128:$src1, (COPY_TO_REGCLASS VR128:$src2, FR64))>;
651   def : Pat<(v2f64 (X86Movsd VR128:$src1, VR128:$src2)),
652             (VMOVSDrr VR128:$src1, (COPY_TO_REGCLASS VR128:$src2, FR64))>;
653
654   // 256-bit variants
655   def : Pat<(v4i64 (X86Movsd VR256:$src1, VR256:$src2)),
656             (SUBREG_TO_REG (i32 0),
657               (VMOVSDrr (EXTRACT_SUBREG (v4i64 VR256:$src1), sub_xmm),
658                         (EXTRACT_SUBREG (v4i64 VR256:$src2), sub_xmm)),
659               sub_xmm)>;
660   def : Pat<(v4f64 (X86Movsd VR256:$src1, VR256:$src2)),
661             (SUBREG_TO_REG (i32 0),
662               (VMOVSDrr (EXTRACT_SUBREG (v4f64 VR256:$src1), sub_xmm),
663                         (EXTRACT_SUBREG (v4f64 VR256:$src2), sub_xmm)),
664               sub_xmm)>;
665
666   // FIXME: Instead of a X86Movlps there should be a X86Movsd here, the problem
667   // is during lowering, where it's not possible to recognize the fold cause
668   // it has two uses through a bitcast. One use disappears at isel time and the
669   // fold opportunity reappears.
670   def : Pat<(v2f64 (X86Movlpd VR128:$src1, VR128:$src2)),
671             (VMOVSDrr VR128:$src1, (COPY_TO_REGCLASS VR128:$src2, FR64))>;
672   def : Pat<(v2i64 (X86Movlpd VR128:$src1, VR128:$src2)),
673             (VMOVSDrr VR128:$src1, (COPY_TO_REGCLASS VR128:$src2, FR64))>;
674   def : Pat<(v4f32 (X86Movlps VR128:$src1, VR128:$src2)),
675             (VMOVSDrr VR128:$src1, (COPY_TO_REGCLASS VR128:$src2, FR64))>;
676   def : Pat<(v4i32 (X86Movlps VR128:$src1, VR128:$src2)),
677             (VMOVSDrr VR128:$src1, (COPY_TO_REGCLASS VR128:$src2, FR64))>;
678 }
679
680 let Predicates = [UseSSE1] in {
681   let Predicates = [NoSSE41], AddedComplexity = 15 in {
682   // Move scalar to XMM zero-extended, zeroing a VR128 then do a
683   // MOVSS to the lower bits.
684   def : Pat<(v4f32 (X86vzmovl (v4f32 (scalar_to_vector FR32:$src)))),
685             (MOVSSrr (v4f32 (V_SET0)), FR32:$src)>;
686   def : Pat<(v4f32 (X86vzmovl (v4f32 VR128:$src))),
687             (MOVSSrr (v4f32 (V_SET0)), (COPY_TO_REGCLASS VR128:$src, FR32))>;
688   def : Pat<(v4i32 (X86vzmovl (v4i32 VR128:$src))),
689             (MOVSSrr (v4i32 (V_SET0)), (COPY_TO_REGCLASS VR128:$src, FR32))>;
690   }
691
692   let AddedComplexity = 20 in {
693   // MOVSSrm already zeros the high parts of the register.
694   def : Pat<(v4f32 (X86vzmovl (v4f32 (scalar_to_vector (loadf32 addr:$src))))),
695             (COPY_TO_REGCLASS (MOVSSrm addr:$src), VR128)>;
696   def : Pat<(v4f32 (scalar_to_vector (loadf32 addr:$src))),
697             (COPY_TO_REGCLASS (MOVSSrm addr:$src), VR128)>;
698   def : Pat<(v4f32 (X86vzmovl (loadv4f32 addr:$src))),
699             (COPY_TO_REGCLASS (MOVSSrm addr:$src), VR128)>;
700   def : Pat<(v4f32 (X86vzload addr:$src)),
701             (COPY_TO_REGCLASS (MOVSSrm addr:$src), VR128)>;
702   }
703
704   // Extract and store.
705   def : Pat<(store (f32 (extractelt (v4f32 VR128:$src), (iPTR 0))),
706                    addr:$dst),
707             (MOVSSmr addr:$dst, (COPY_TO_REGCLASS VR128:$src, FR32))>;
708
709   // Shuffle with MOVSS
710   def : Pat<(v4i32 (X86Movss VR128:$src1, VR128:$src2)),
711             (MOVSSrr VR128:$src1, (COPY_TO_REGCLASS VR128:$src2, FR32))>;
712   def : Pat<(v4f32 (X86Movss VR128:$src1, VR128:$src2)),
713             (MOVSSrr VR128:$src1, (COPY_TO_REGCLASS VR128:$src2, FR32))>;
714 }
715
716 let Predicates = [UseSSE2] in {
717   let Predicates = [NoSSE41], AddedComplexity = 15 in {
718   // Move scalar to XMM zero-extended, zeroing a VR128 then do a
719   // MOVSD to the lower bits.
720   def : Pat<(v2f64 (X86vzmovl (v2f64 (scalar_to_vector FR64:$src)))),
721             (MOVSDrr (v2f64 (V_SET0)), FR64:$src)>;
722   }
723
724   let AddedComplexity = 20 in {
725   // MOVSDrm already zeros the high parts of the register.
726   def : Pat<(v2f64 (X86vzmovl (v2f64 (scalar_to_vector (loadf64 addr:$src))))),
727             (COPY_TO_REGCLASS (MOVSDrm addr:$src), VR128)>;
728   def : Pat<(v2f64 (scalar_to_vector (loadf64 addr:$src))),
729             (COPY_TO_REGCLASS (MOVSDrm addr:$src), VR128)>;
730   def : Pat<(v2f64 (X86vzmovl (loadv2f64 addr:$src))),
731             (COPY_TO_REGCLASS (MOVSDrm addr:$src), VR128)>;
732   def : Pat<(v2f64 (X86vzmovl (bc_v2f64 (loadv4f32 addr:$src)))),
733             (COPY_TO_REGCLASS (MOVSDrm addr:$src), VR128)>;
734   def : Pat<(v2f64 (X86vzload addr:$src)),
735             (COPY_TO_REGCLASS (MOVSDrm addr:$src), VR128)>;
736   }
737
738   // Shuffle with MOVSD
739   def : Pat<(v2i64 (X86Movsd VR128:$src1, VR128:$src2)),
740             (MOVSDrr VR128:$src1, (COPY_TO_REGCLASS VR128:$src2, FR64))>;
741   def : Pat<(v2f64 (X86Movsd VR128:$src1, VR128:$src2)),
742             (MOVSDrr VR128:$src1, (COPY_TO_REGCLASS VR128:$src2, FR64))>;
743
744   // FIXME: Instead of a X86Movlps there should be a X86Movsd here, the problem
745   // is during lowering, where it's not possible to recognize the fold because
746   // it has two uses through a bitcast. One use disappears at isel time and the
747   // fold opportunity reappears.
748   def : Pat<(v2f64 (X86Movlpd VR128:$src1, VR128:$src2)),
749             (MOVSDrr VR128:$src1, (COPY_TO_REGCLASS VR128:$src2, FR64))>;
750   def : Pat<(v2i64 (X86Movlpd VR128:$src1, VR128:$src2)),
751             (MOVSDrr VR128:$src1, (COPY_TO_REGCLASS VR128:$src2, FR64))>;
752   def : Pat<(v4f32 (X86Movlps VR128:$src1, VR128:$src2)),
753             (MOVSDrr VR128:$src1, (COPY_TO_REGCLASS VR128:$src2, FR64))>;
754   def : Pat<(v4i32 (X86Movlps VR128:$src1, VR128:$src2)),
755             (MOVSDrr VR128:$src1, (COPY_TO_REGCLASS VR128:$src2, FR64))>;
756 }
757
758 // Aliases to help the assembler pick two byte VEX encodings by swapping the
759 // operands relative to the normal instructions to use VEX.R instead of VEX.B.
760 def : InstAlias<"vmovss\t{$src2, $src1, $dst|$dst, $src1, $src2}",
761                 (VMOVSSrr_REV VR128L:$dst, VR128:$src1, VR128H:$src2), 0>;
762 def : InstAlias<"vmovsd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
763                 (VMOVSDrr_REV VR128L:$dst, VR128:$src1, VR128H:$src2), 0>;
764
765 //===----------------------------------------------------------------------===//
766 // SSE 1 & 2 - Move Aligned/Unaligned FP Instructions
767 //===----------------------------------------------------------------------===//
768
769 multiclass sse12_mov_packed<bits<8> opc, RegisterClass RC,
770                             X86MemOperand x86memop, PatFrag ld_frag,
771                             string asm, Domain d,
772                             OpndItins itins> {
773 let hasSideEffects = 0 in
774   def rr : PI<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src),
775               !strconcat(asm, "\t{$src, $dst|$dst, $src}"), [], itins.rr, d>,
776            Sched<[WriteFShuffle]>;
777 let canFoldAsLoad = 1, isReMaterializable = 1 in
778   def rm : PI<opc, MRMSrcMem, (outs RC:$dst), (ins x86memop:$src),
779               !strconcat(asm, "\t{$src, $dst|$dst, $src}"),
780                    [(set RC:$dst, (ld_frag addr:$src))], itins.rm, d>,
781            Sched<[WriteLoad]>;
782 }
783
784 let Predicates = [HasAVX, NoVLX] in {
785 defm VMOVAPS : sse12_mov_packed<0x28, VR128, f128mem, alignedloadv4f32,
786                               "movaps", SSEPackedSingle, SSE_MOVA_ITINS>,
787                               PS, VEX, VEX_WIG;
788 defm VMOVAPD : sse12_mov_packed<0x28, VR128, f128mem, alignedloadv2f64,
789                               "movapd", SSEPackedDouble, SSE_MOVA_ITINS>,
790                               PD, VEX, VEX_WIG;
791 defm VMOVUPS : sse12_mov_packed<0x10, VR128, f128mem, loadv4f32,
792                               "movups", SSEPackedSingle, SSE_MOVU_ITINS>,
793                               PS, VEX, VEX_WIG;
794 defm VMOVUPD : sse12_mov_packed<0x10, VR128, f128mem, loadv2f64,
795                               "movupd", SSEPackedDouble, SSE_MOVU_ITINS>,
796                               PD, VEX, VEX_WIG;
797
798 defm VMOVAPSY : sse12_mov_packed<0x28, VR256, f256mem, alignedloadv8f32,
799                               "movaps", SSEPackedSingle, SSE_MOVA_ITINS>,
800                               PS, VEX, VEX_L, VEX_WIG;
801 defm VMOVAPDY : sse12_mov_packed<0x28, VR256, f256mem, alignedloadv4f64,
802                               "movapd", SSEPackedDouble, SSE_MOVA_ITINS>,
803                               PD, VEX, VEX_L, VEX_WIG;
804 defm VMOVUPSY : sse12_mov_packed<0x10, VR256, f256mem, loadv8f32,
805                               "movups", SSEPackedSingle, SSE_MOVU_ITINS>,
806                               PS, VEX, VEX_L, VEX_WIG;
807 defm VMOVUPDY : sse12_mov_packed<0x10, VR256, f256mem, loadv4f64,
808                               "movupd", SSEPackedDouble, SSE_MOVU_ITINS>,
809                               PD, VEX, VEX_L, VEX_WIG;
810 }
811
812 let Predicates = [UseSSE1] in {
813 defm MOVAPS : sse12_mov_packed<0x28, VR128, f128mem, alignedloadv4f32,
814                               "movaps", SSEPackedSingle, SSE_MOVA_ITINS>,
815                               PS;
816 defm MOVUPS : sse12_mov_packed<0x10, VR128, f128mem, loadv4f32,
817                               "movups", SSEPackedSingle, SSE_MOVU_ITINS>,
818                               PS;
819 }
820 let Predicates = [UseSSE2] in {
821 defm MOVAPD : sse12_mov_packed<0x28, VR128, f128mem, alignedloadv2f64,
822                               "movapd", SSEPackedDouble, SSE_MOVA_ITINS>,
823                               PD;
824 defm MOVUPD : sse12_mov_packed<0x10, VR128, f128mem, loadv2f64,
825                               "movupd", SSEPackedDouble, SSE_MOVU_ITINS>,
826                               PD;
827 }
828
829 let SchedRW = [WriteStore], Predicates = [HasAVX, NoVLX]  in {
830 def VMOVAPSmr : VPSI<0x29, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
831                    "movaps\t{$src, $dst|$dst, $src}",
832                    [(alignedstore (v4f32 VR128:$src), addr:$dst)],
833                    IIC_SSE_MOVA_P_MR>, VEX, VEX_WIG;
834 def VMOVAPDmr : VPDI<0x29, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
835                    "movapd\t{$src, $dst|$dst, $src}",
836                    [(alignedstore (v2f64 VR128:$src), addr:$dst)],
837                    IIC_SSE_MOVA_P_MR>, VEX, VEX_WIG;
838 def VMOVUPSmr : VPSI<0x11, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
839                    "movups\t{$src, $dst|$dst, $src}",
840                    [(store (v4f32 VR128:$src), addr:$dst)],
841                    IIC_SSE_MOVU_P_MR>, VEX, VEX_WIG;
842 def VMOVUPDmr : VPDI<0x11, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
843                    "movupd\t{$src, $dst|$dst, $src}",
844                    [(store (v2f64 VR128:$src), addr:$dst)],
845                    IIC_SSE_MOVU_P_MR>, VEX, VEX_WIG;
846 def VMOVAPSYmr : VPSI<0x29, MRMDestMem, (outs), (ins f256mem:$dst, VR256:$src),
847                    "movaps\t{$src, $dst|$dst, $src}",
848                    [(alignedstore256 (v8f32 VR256:$src), addr:$dst)],
849                    IIC_SSE_MOVA_P_MR>, VEX, VEX_L, VEX_WIG;
850 def VMOVAPDYmr : VPDI<0x29, MRMDestMem, (outs), (ins f256mem:$dst, VR256:$src),
851                    "movapd\t{$src, $dst|$dst, $src}",
852                    [(alignedstore256 (v4f64 VR256:$src), addr:$dst)],
853                    IIC_SSE_MOVA_P_MR>, VEX, VEX_L, VEX_WIG;
854 def VMOVUPSYmr : VPSI<0x11, MRMDestMem, (outs), (ins f256mem:$dst, VR256:$src),
855                    "movups\t{$src, $dst|$dst, $src}",
856                    [(store (v8f32 VR256:$src), addr:$dst)],
857                    IIC_SSE_MOVU_P_MR>, VEX, VEX_L, VEX_WIG;
858 def VMOVUPDYmr : VPDI<0x11, MRMDestMem, (outs), (ins f256mem:$dst, VR256:$src),
859                    "movupd\t{$src, $dst|$dst, $src}",
860                    [(store (v4f64 VR256:$src), addr:$dst)],
861                    IIC_SSE_MOVU_P_MR>, VEX, VEX_L, VEX_WIG;
862 } // SchedRW
863
864 // For disassembler
865 let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0,
866     SchedRW = [WriteFShuffle] in {
867   def VMOVAPSrr_REV : VPSI<0x29, MRMDestReg, (outs VR128:$dst),
868                           (ins VR128:$src),
869                           "movaps\t{$src, $dst|$dst, $src}", [],
870                           IIC_SSE_MOVA_P_RR>, VEX, VEX_WIG,
871                           FoldGenData<"VMOVAPSrr">;
872   def VMOVAPDrr_REV : VPDI<0x29, MRMDestReg, (outs VR128:$dst),
873                            (ins VR128:$src),
874                            "movapd\t{$src, $dst|$dst, $src}", [],
875                            IIC_SSE_MOVA_P_RR>, VEX, VEX_WIG,
876                            FoldGenData<"VMOVAPDrr">;
877   def VMOVUPSrr_REV : VPSI<0x11, MRMDestReg, (outs VR128:$dst),
878                            (ins VR128:$src),
879                            "movups\t{$src, $dst|$dst, $src}", [],
880                            IIC_SSE_MOVU_P_RR>, VEX, VEX_WIG,
881                            FoldGenData<"VMOVUPSrr">;
882   def VMOVUPDrr_REV : VPDI<0x11, MRMDestReg, (outs VR128:$dst),
883                            (ins VR128:$src),
884                            "movupd\t{$src, $dst|$dst, $src}", [],
885                            IIC_SSE_MOVU_P_RR>, VEX, VEX_WIG,
886                            FoldGenData<"VMOVUPDrr">;
887   def VMOVAPSYrr_REV : VPSI<0x29, MRMDestReg, (outs VR256:$dst),
888                             (ins VR256:$src),
889                             "movaps\t{$src, $dst|$dst, $src}", [],
890                             IIC_SSE_MOVA_P_RR>, VEX, VEX_L, VEX_WIG,
891                             FoldGenData<"VMOVAPSYrr">;
892   def VMOVAPDYrr_REV : VPDI<0x29, MRMDestReg, (outs VR256:$dst),
893                             (ins VR256:$src),
894                             "movapd\t{$src, $dst|$dst, $src}", [],
895                             IIC_SSE_MOVA_P_RR>, VEX, VEX_L, VEX_WIG,
896                             FoldGenData<"VMOVAPDYrr">;
897   def VMOVUPSYrr_REV : VPSI<0x11, MRMDestReg, (outs VR256:$dst),
898                             (ins VR256:$src),
899                             "movups\t{$src, $dst|$dst, $src}", [],
900                             IIC_SSE_MOVU_P_RR>, VEX, VEX_L, VEX_WIG,
901                             FoldGenData<"VMOVUPSYrr">;
902   def VMOVUPDYrr_REV : VPDI<0x11, MRMDestReg, (outs VR256:$dst),
903                             (ins VR256:$src),
904                             "movupd\t{$src, $dst|$dst, $src}", [],
905                             IIC_SSE_MOVU_P_RR>, VEX, VEX_L, VEX_WIG,
906                             FoldGenData<"VMOVUPDYrr">;
907 }
908
909 // Aliases to help the assembler pick two byte VEX encodings by swapping the
910 // operands relative to the normal instructions to use VEX.R instead of VEX.B.
911 def : InstAlias<"vmovaps\t{$src, $dst|$dst, $src}",
912                 (VMOVAPSrr_REV VR128L:$dst, VR128H:$src), 0>;
913 def : InstAlias<"vmovapd\t{$src, $dst|$dst, $src}",
914                 (VMOVAPDrr_REV VR128L:$dst, VR128H:$src), 0>;
915 def : InstAlias<"vmovups\t{$src, $dst|$dst, $src}",
916                 (VMOVUPSrr_REV VR128L:$dst, VR128H:$src), 0>;
917 def : InstAlias<"vmovupd\t{$src, $dst|$dst, $src}",
918                 (VMOVUPDrr_REV VR128L:$dst, VR128H:$src), 0>;
919 def : InstAlias<"vmovaps\t{$src, $dst|$dst, $src}",
920                 (VMOVAPSYrr_REV VR256L:$dst, VR256H:$src), 0>;
921 def : InstAlias<"vmovapd\t{$src, $dst|$dst, $src}",
922                 (VMOVAPDYrr_REV VR256L:$dst, VR256H:$src), 0>;
923 def : InstAlias<"vmovups\t{$src, $dst|$dst, $src}",
924                 (VMOVUPSYrr_REV VR256L:$dst, VR256H:$src), 0>;
925 def : InstAlias<"vmovupd\t{$src, $dst|$dst, $src}",
926                 (VMOVUPDYrr_REV VR256L:$dst, VR256H:$src), 0>;
927
928 let SchedRW = [WriteStore] in {
929 def MOVAPSmr : PSI<0x29, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
930                    "movaps\t{$src, $dst|$dst, $src}",
931                    [(alignedstore (v4f32 VR128:$src), addr:$dst)],
932                    IIC_SSE_MOVA_P_MR>;
933 def MOVAPDmr : PDI<0x29, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
934                    "movapd\t{$src, $dst|$dst, $src}",
935                    [(alignedstore (v2f64 VR128:$src), addr:$dst)],
936                    IIC_SSE_MOVA_P_MR>;
937 def MOVUPSmr : PSI<0x11, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
938                    "movups\t{$src, $dst|$dst, $src}",
939                    [(store (v4f32 VR128:$src), addr:$dst)],
940                    IIC_SSE_MOVU_P_MR>;
941 def MOVUPDmr : PDI<0x11, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
942                    "movupd\t{$src, $dst|$dst, $src}",
943                    [(store (v2f64 VR128:$src), addr:$dst)],
944                    IIC_SSE_MOVU_P_MR>;
945 } // SchedRW
946
947 // For disassembler
948 let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0,
949     SchedRW = [WriteFShuffle] in {
950   def MOVAPSrr_REV : PSI<0x29, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
951                          "movaps\t{$src, $dst|$dst, $src}", [],
952                          IIC_SSE_MOVA_P_RR>, FoldGenData<"MOVAPSrr">;
953   def MOVAPDrr_REV : PDI<0x29, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
954                          "movapd\t{$src, $dst|$dst, $src}", [],
955                          IIC_SSE_MOVA_P_RR>, FoldGenData<"MOVAPDrr">;
956   def MOVUPSrr_REV : PSI<0x11, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
957                          "movups\t{$src, $dst|$dst, $src}", [],
958                          IIC_SSE_MOVU_P_RR>, FoldGenData<"MOVUPSrr">;
959   def MOVUPDrr_REV : PDI<0x11, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
960                          "movupd\t{$src, $dst|$dst, $src}", [],
961                          IIC_SSE_MOVU_P_RR>, FoldGenData<"MOVUPDrr">;
962 }
963
964 let Predicates = [HasAVX, NoVLX] in {
965   // 256-bit load/store need to use floating point load/store in case we don't
966   // have AVX2. Execution domain fixing will convert to integer if AVX2 is
967   // available and changing the domain is beneficial.
968   def : Pat<(alignedloadv4i64 addr:$src),
969             (VMOVAPSYrm addr:$src)>;
970   def : Pat<(loadv4i64 addr:$src),
971             (VMOVUPSYrm addr:$src)>;
972   def : Pat<(alignedstore256 (v4i64 VR256:$src), addr:$dst),
973             (VMOVAPSYmr addr:$dst, VR256:$src)>;
974   def : Pat<(alignedstore256 (v8i32 VR256:$src), addr:$dst),
975             (VMOVAPSYmr addr:$dst, VR256:$src)>;
976   def : Pat<(alignedstore256 (v16i16 VR256:$src), addr:$dst),
977             (VMOVAPSYmr addr:$dst, VR256:$src)>;
978   def : Pat<(alignedstore256 (v32i8 VR256:$src), addr:$dst),
979             (VMOVAPSYmr addr:$dst, VR256:$src)>;
980   def : Pat<(store (v4i64 VR256:$src), addr:$dst),
981             (VMOVUPSYmr addr:$dst, VR256:$src)>;
982   def : Pat<(store (v8i32 VR256:$src), addr:$dst),
983             (VMOVUPSYmr addr:$dst, VR256:$src)>;
984   def : Pat<(store (v16i16 VR256:$src), addr:$dst),
985             (VMOVUPSYmr addr:$dst, VR256:$src)>;
986   def : Pat<(store (v32i8 VR256:$src), addr:$dst),
987             (VMOVUPSYmr addr:$dst, VR256:$src)>;
988
989   // Special patterns for storing subvector extracts of lower 128-bits
990   // Its cheaper to just use VMOVAPS/VMOVUPS instead of VEXTRACTF128mr
991   def : Pat<(alignedstore (v2f64 (extract_subvector
992                                   (v4f64 VR256:$src), (iPTR 0))), addr:$dst),
993             (VMOVAPDmr addr:$dst, (v2f64 (EXTRACT_SUBREG VR256:$src,sub_xmm)))>;
994   def : Pat<(alignedstore (v4f32 (extract_subvector
995                                   (v8f32 VR256:$src), (iPTR 0))), addr:$dst),
996             (VMOVAPSmr addr:$dst, (v4f32 (EXTRACT_SUBREG VR256:$src,sub_xmm)))>;
997
998   def : Pat<(store (v2f64 (extract_subvector
999                            (v4f64 VR256:$src), (iPTR 0))), addr:$dst),
1000             (VMOVUPDmr addr:$dst, (v2f64 (EXTRACT_SUBREG VR256:$src,sub_xmm)))>;
1001   def : Pat<(store (v4f32 (extract_subvector
1002                            (v8f32 VR256:$src), (iPTR 0))), addr:$dst),
1003             (VMOVUPSmr addr:$dst, (v4f32 (EXTRACT_SUBREG VR256:$src,sub_xmm)))>;
1004 }
1005
1006 // Use movaps / movups for SSE integer load / store (one byte shorter).
1007 // The instructions selected below are then converted to MOVDQA/MOVDQU
1008 // during the SSE domain pass.
1009 let Predicates = [UseSSE1] in {
1010   def : Pat<(alignedloadv2i64 addr:$src),
1011             (MOVAPSrm addr:$src)>;
1012   def : Pat<(loadv2i64 addr:$src),
1013             (MOVUPSrm addr:$src)>;
1014
1015   def : Pat<(alignedstore (v2i64 VR128:$src), addr:$dst),
1016             (MOVAPSmr addr:$dst, VR128:$src)>;
1017   def : Pat<(alignedstore (v4i32 VR128:$src), addr:$dst),
1018             (MOVAPSmr addr:$dst, VR128:$src)>;
1019   def : Pat<(alignedstore (v8i16 VR128:$src), addr:$dst),
1020             (MOVAPSmr addr:$dst, VR128:$src)>;
1021   def : Pat<(alignedstore (v16i8 VR128:$src), addr:$dst),
1022             (MOVAPSmr addr:$dst, VR128:$src)>;
1023   def : Pat<(store (v2i64 VR128:$src), addr:$dst),
1024             (MOVUPSmr addr:$dst, VR128:$src)>;
1025   def : Pat<(store (v4i32 VR128:$src), addr:$dst),
1026             (MOVUPSmr addr:$dst, VR128:$src)>;
1027   def : Pat<(store (v8i16 VR128:$src), addr:$dst),
1028             (MOVUPSmr addr:$dst, VR128:$src)>;
1029   def : Pat<(store (v16i8 VR128:$src), addr:$dst),
1030             (MOVUPSmr addr:$dst, VR128:$src)>;
1031 }
1032
1033 //===----------------------------------------------------------------------===//
1034 // SSE 1 & 2 - Move Low packed FP Instructions
1035 //===----------------------------------------------------------------------===//
1036
1037 multiclass sse12_mov_hilo_packed_base<bits<8>opc, SDNode psnode, SDNode pdnode,
1038                                       string base_opc, string asm_opr,
1039                                       InstrItinClass itin> {
1040   def PSrm : PI<opc, MRMSrcMem,
1041          (outs VR128:$dst), (ins VR128:$src1, f64mem:$src2),
1042          !strconcat(base_opc, "s", asm_opr),
1043      [(set VR128:$dst,
1044        (psnode VR128:$src1,
1045               (bc_v4f32 (v2f64 (scalar_to_vector (loadf64 addr:$src2))))))],
1046               itin, SSEPackedSingle>, PS,
1047      Sched<[WriteFShuffleLd, ReadAfterLd]>;
1048
1049   def PDrm : PI<opc, MRMSrcMem,
1050          (outs VR128:$dst), (ins VR128:$src1, f64mem:$src2),
1051          !strconcat(base_opc, "d", asm_opr),
1052      [(set VR128:$dst, (v2f64 (pdnode VR128:$src1,
1053                               (scalar_to_vector (loadf64 addr:$src2)))))],
1054               itin, SSEPackedDouble>, PD,
1055      Sched<[WriteFShuffleLd, ReadAfterLd]>;
1056
1057 }
1058
1059 multiclass sse12_mov_hilo_packed<bits<8>opc, SDNode psnode, SDNode pdnode,
1060                                  string base_opc, InstrItinClass itin> {
1061   let Predicates = [UseAVX] in
1062     defm V#NAME : sse12_mov_hilo_packed_base<opc, psnode, pdnode, base_opc,
1063                                     "\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1064                                     itin>, VEX_4V, VEX_WIG;
1065
1066   let Constraints = "$src1 = $dst" in
1067     defm NAME : sse12_mov_hilo_packed_base<opc, psnode, pdnode, base_opc,
1068                                     "\t{$src2, $dst|$dst, $src2}",
1069                                     itin>;
1070 }
1071
1072 let AddedComplexity = 20 in {
1073   defm MOVL : sse12_mov_hilo_packed<0x12, X86Movlps, X86Movlpd, "movlp",
1074                                     IIC_SSE_MOV_LH>;
1075 }
1076
1077 let SchedRW = [WriteStore] in {
1078 let Predicates = [UseAVX] in {
1079 def VMOVLPSmr : VPSI<0x13, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
1080                    "movlps\t{$src, $dst|$dst, $src}",
1081                    [(store (f64 (extractelt (bc_v2f64 (v4f32 VR128:$src)),
1082                                  (iPTR 0))), addr:$dst)],
1083                                  IIC_SSE_MOV_LH>, VEX, VEX_WIG;
1084 def VMOVLPDmr : VPDI<0x13, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
1085                    "movlpd\t{$src, $dst|$dst, $src}",
1086                    [(store (f64 (extractelt (v2f64 VR128:$src),
1087                                  (iPTR 0))), addr:$dst)],
1088                                  IIC_SSE_MOV_LH>, VEX, VEX_WIG;
1089 }// UseAVX
1090 def MOVLPSmr : PSI<0x13, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
1091                    "movlps\t{$src, $dst|$dst, $src}",
1092                    [(store (f64 (extractelt (bc_v2f64 (v4f32 VR128:$src)),
1093                                  (iPTR 0))), addr:$dst)],
1094                                  IIC_SSE_MOV_LH>;
1095 def MOVLPDmr : PDI<0x13, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
1096                    "movlpd\t{$src, $dst|$dst, $src}",
1097                    [(store (f64 (extractelt (v2f64 VR128:$src),
1098                                  (iPTR 0))), addr:$dst)],
1099                                  IIC_SSE_MOV_LH>;
1100 } // SchedRW
1101
1102 let Predicates = [UseAVX] in {
1103   // Shuffle with VMOVLPS
1104   def : Pat<(v4f32 (X86Movlps VR128:$src1, (load addr:$src2))),
1105             (VMOVLPSrm VR128:$src1, addr:$src2)>;
1106   def : Pat<(v4i32 (X86Movlps VR128:$src1, (load addr:$src2))),
1107             (VMOVLPSrm VR128:$src1, addr:$src2)>;
1108
1109   // Shuffle with VMOVLPD
1110   def : Pat<(v2f64 (X86Movlpd VR128:$src1, (load addr:$src2))),
1111             (VMOVLPDrm VR128:$src1, addr:$src2)>;
1112   def : Pat<(v2i64 (X86Movlpd VR128:$src1, (load addr:$src2))),
1113             (VMOVLPDrm VR128:$src1, addr:$src2)>;
1114   def : Pat<(v2f64 (X86Movsd VR128:$src1,
1115                              (v2f64 (scalar_to_vector (loadf64 addr:$src2))))),
1116             (VMOVLPDrm VR128:$src1, addr:$src2)>;
1117
1118   // Store patterns
1119   def : Pat<(store (v4f32 (X86Movlps (load addr:$src1), VR128:$src2)),
1120                    addr:$src1),
1121             (VMOVLPSmr addr:$src1, VR128:$src2)>;
1122   def : Pat<(store (v4i32 (X86Movlps
1123                    (bc_v4i32 (loadv2i64 addr:$src1)), VR128:$src2)), addr:$src1),
1124             (VMOVLPSmr addr:$src1, VR128:$src2)>;
1125   def : Pat<(store (v2f64 (X86Movlpd (load addr:$src1), VR128:$src2)),
1126                    addr:$src1),
1127             (VMOVLPDmr addr:$src1, VR128:$src2)>;
1128   def : Pat<(store (v2i64 (X86Movlpd (load addr:$src1), VR128:$src2)),
1129                    addr:$src1),
1130             (VMOVLPDmr addr:$src1, VR128:$src2)>;
1131 }
1132
1133 let Predicates = [UseSSE1] in {
1134   // (store (vector_shuffle (load addr), v2, <4, 5, 2, 3>), addr) using MOVLPS
1135   def : Pat<(store (i64 (extractelt (bc_v2i64 (v4f32 VR128:$src2)),
1136                                  (iPTR 0))), addr:$src1),
1137             (MOVLPSmr addr:$src1, VR128:$src2)>;
1138
1139   // Shuffle with MOVLPS
1140   def : Pat<(v4f32 (X86Movlps VR128:$src1, (load addr:$src2))),
1141             (MOVLPSrm VR128:$src1, addr:$src2)>;
1142   def : Pat<(v4i32 (X86Movlps VR128:$src1, (load addr:$src2))),
1143             (MOVLPSrm VR128:$src1, addr:$src2)>;
1144   def : Pat<(X86Movlps VR128:$src1,
1145                       (bc_v4f32 (v2i64 (scalar_to_vector (loadi64 addr:$src2))))),
1146             (MOVLPSrm VR128:$src1, addr:$src2)>;
1147
1148   // Store patterns
1149   def : Pat<(store (v4f32 (X86Movlps (load addr:$src1), VR128:$src2)),
1150                                       addr:$src1),
1151             (MOVLPSmr addr:$src1, VR128:$src2)>;
1152   def : Pat<(store (v4i32 (X86Movlps
1153                    (bc_v4i32 (loadv2i64 addr:$src1)), VR128:$src2)),
1154                               addr:$src1),
1155             (MOVLPSmr addr:$src1, VR128:$src2)>;
1156 }
1157
1158 let Predicates = [UseSSE2] in {
1159   // Shuffle with MOVLPD
1160   def : Pat<(v2f64 (X86Movlpd VR128:$src1, (load addr:$src2))),
1161             (MOVLPDrm VR128:$src1, addr:$src2)>;
1162   def : Pat<(v2i64 (X86Movlpd VR128:$src1, (load addr:$src2))),
1163             (MOVLPDrm VR128:$src1, addr:$src2)>;
1164   def : Pat<(v2f64 (X86Movsd VR128:$src1,
1165                              (v2f64 (scalar_to_vector (loadf64 addr:$src2))))),
1166             (MOVLPDrm VR128:$src1, addr:$src2)>;
1167
1168   // Store patterns
1169   def : Pat<(store (v2f64 (X86Movlpd (load addr:$src1), VR128:$src2)),
1170                            addr:$src1),
1171             (MOVLPDmr addr:$src1, VR128:$src2)>;
1172   def : Pat<(store (v2i64 (X86Movlpd (load addr:$src1), VR128:$src2)),
1173                            addr:$src1),
1174             (MOVLPDmr addr:$src1, VR128:$src2)>;
1175 }
1176
1177 //===----------------------------------------------------------------------===//
1178 // SSE 1 & 2 - Move Hi packed FP Instructions
1179 //===----------------------------------------------------------------------===//
1180
1181 let AddedComplexity = 20 in {
1182   defm MOVH : sse12_mov_hilo_packed<0x16, X86Movlhps, X86Movlhpd, "movhp",
1183                                     IIC_SSE_MOV_LH>;
1184 }
1185
1186 let SchedRW = [WriteStore] in {
1187 // v2f64 extract element 1 is always custom lowered to unpack high to low
1188 // and extract element 0 so the non-store version isn't too horrible.
1189 let Predicates = [UseAVX] in {
1190 def VMOVHPSmr : VPSI<0x17, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
1191                    "movhps\t{$src, $dst|$dst, $src}",
1192                    [(store (f64 (extractelt
1193                                  (X86Unpckh (bc_v2f64 (v4f32 VR128:$src)),
1194                                             (bc_v2f64 (v4f32 VR128:$src))),
1195                                  (iPTR 0))), addr:$dst)], IIC_SSE_MOV_LH>, VEX, VEX_WIG;
1196 def VMOVHPDmr : VPDI<0x17, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
1197                    "movhpd\t{$src, $dst|$dst, $src}",
1198                    [(store (f64 (extractelt
1199                                  (v2f64 (X86Unpckh VR128:$src, VR128:$src)),
1200                                  (iPTR 0))), addr:$dst)], IIC_SSE_MOV_LH>, VEX, VEX_WIG;
1201 } // UseAVX
1202 def MOVHPSmr : PSI<0x17, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
1203                    "movhps\t{$src, $dst|$dst, $src}",
1204                    [(store (f64 (extractelt
1205                                  (X86Unpckh (bc_v2f64 (v4f32 VR128:$src)),
1206                                             (bc_v2f64 (v4f32 VR128:$src))),
1207                                  (iPTR 0))), addr:$dst)], IIC_SSE_MOV_LH>;
1208 def MOVHPDmr : PDI<0x17, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
1209                    "movhpd\t{$src, $dst|$dst, $src}",
1210                    [(store (f64 (extractelt
1211                                  (v2f64 (X86Unpckh VR128:$src, VR128:$src)),
1212                                  (iPTR 0))), addr:$dst)], IIC_SSE_MOV_LH>;
1213 } // SchedRW
1214
1215 let Predicates = [UseAVX] in {
1216   // VMOVHPS patterns
1217   def : Pat<(X86Movlhps VR128:$src1,
1218                  (bc_v4f32 (v2i64 (scalar_to_vector (loadi64 addr:$src2))))),
1219             (VMOVHPSrm VR128:$src1, addr:$src2)>;
1220   def : Pat<(X86Movlhps VR128:$src1,
1221                  (bc_v4i32 (v2i64 (X86vzload addr:$src2)))),
1222             (VMOVHPSrm VR128:$src1, addr:$src2)>;
1223
1224   // VMOVHPD patterns
1225
1226   // FIXME: Instead of X86Unpckl, there should be a X86Movlhpd here, the problem
1227   // is during lowering, where it's not possible to recognize the load fold
1228   // cause it has two uses through a bitcast. One use disappears at isel time
1229   // and the fold opportunity reappears.
1230   def : Pat<(v2f64 (X86Unpckl VR128:$src1,
1231                       (scalar_to_vector (loadf64 addr:$src2)))),
1232             (VMOVHPDrm VR128:$src1, addr:$src2)>;
1233
1234   // Also handle an i64 load because that may get selected as a faster way to
1235   // load the data.
1236   def : Pat<(v2f64 (X86Unpckl VR128:$src1,
1237                       (bc_v2f64 (v2i64 (scalar_to_vector (loadi64 addr:$src2)))))),
1238             (VMOVHPDrm VR128:$src1, addr:$src2)>;
1239
1240   def : Pat<(store (f64 (extractelt
1241                           (bc_v2f64 (v4f32 (X86Movhlps VR128:$src, VR128:$src))),
1242                           (iPTR 0))), addr:$dst),
1243             (VMOVHPDmr addr:$dst, VR128:$src)>;
1244
1245   def : Pat<(store (f64 (extractelt
1246                           (v2f64 (X86VPermilpi VR128:$src, (i8 1))),
1247                           (iPTR 0))), addr:$dst),
1248             (VMOVHPDmr addr:$dst, VR128:$src)>;
1249 }
1250
1251 let Predicates = [UseSSE1] in {
1252   // MOVHPS patterns
1253   def : Pat<(X86Movlhps VR128:$src1,
1254                  (bc_v4f32 (v2i64 (scalar_to_vector (loadi64 addr:$src2))))),
1255             (MOVHPSrm VR128:$src1, addr:$src2)>;
1256   def : Pat<(X86Movlhps VR128:$src1,
1257                  (bc_v4f32 (v2i64 (X86vzload addr:$src2)))),
1258             (MOVHPSrm VR128:$src1, addr:$src2)>;
1259 }
1260
1261 let Predicates = [UseSSE2] in {
1262   // MOVHPD patterns
1263
1264   // FIXME: Instead of X86Unpckl, there should be a X86Movlhpd here, the problem
1265   // is during lowering, where it's not possible to recognize the load fold
1266   // cause it has two uses through a bitcast. One use disappears at isel time
1267   // and the fold opportunity reappears.
1268   def : Pat<(v2f64 (X86Unpckl VR128:$src1,
1269                       (scalar_to_vector (loadf64 addr:$src2)))),
1270             (MOVHPDrm VR128:$src1, addr:$src2)>;
1271
1272   // Also handle an i64 load because that may get selected as a faster way to
1273   // load the data.
1274   def : Pat<(v2f64 (X86Unpckl VR128:$src1,
1275                       (bc_v2f64 (v2i64 (scalar_to_vector (loadi64 addr:$src2)))))),
1276             (MOVHPDrm VR128:$src1, addr:$src2)>;
1277
1278   def : Pat<(store (f64 (extractelt
1279                           (bc_v2f64 (v4f32 (X86Movhlps VR128:$src, VR128:$src))),
1280                           (iPTR 0))), addr:$dst),
1281             (MOVHPDmr addr:$dst, VR128:$src)>;
1282
1283   def : Pat<(store (f64 (extractelt
1284                           (v2f64 (X86Shufp VR128:$src, VR128:$src, (i8 1))),
1285                           (iPTR 0))), addr:$dst),
1286             (MOVHPDmr addr:$dst, VR128:$src)>;
1287 }
1288
1289 //===----------------------------------------------------------------------===//
1290 // SSE 1 & 2 - Move Low to High and High to Low packed FP Instructions
1291 //===----------------------------------------------------------------------===//
1292
1293 let AddedComplexity = 20, Predicates = [UseAVX] in {
1294   def VMOVLHPSrr : VPSI<0x16, MRMSrcReg, (outs VR128:$dst),
1295                                        (ins VR128:$src1, VR128:$src2),
1296                       "movlhps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1297                       [(set VR128:$dst,
1298                         (v4f32 (X86Movlhps VR128:$src1, VR128:$src2)))],
1299                         IIC_SSE_MOV_LH>,
1300                       VEX_4V, Sched<[WriteFShuffle]>, VEX_WIG;
1301   def VMOVHLPSrr : VPSI<0x12, MRMSrcReg, (outs VR128:$dst),
1302                                        (ins VR128:$src1, VR128:$src2),
1303                       "movhlps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1304                       [(set VR128:$dst,
1305                         (v4f32 (X86Movhlps VR128:$src1, VR128:$src2)))],
1306                         IIC_SSE_MOV_LH>,
1307                       VEX_4V, Sched<[WriteFShuffle]>, VEX_WIG;
1308 }
1309 let Constraints = "$src1 = $dst", AddedComplexity = 20 in {
1310   def MOVLHPSrr : PSI<0x16, MRMSrcReg, (outs VR128:$dst),
1311                                        (ins VR128:$src1, VR128:$src2),
1312                       "movlhps\t{$src2, $dst|$dst, $src2}",
1313                       [(set VR128:$dst,
1314                         (v4f32 (X86Movlhps VR128:$src1, VR128:$src2)))],
1315                         IIC_SSE_MOV_LH>, Sched<[WriteFShuffle]>;
1316   let isCommutable = 1 in
1317   def MOVHLPSrr : PSI<0x12, MRMSrcReg, (outs VR128:$dst),
1318                                        (ins VR128:$src1, VR128:$src2),
1319                       "movhlps\t{$src2, $dst|$dst, $src2}",
1320                       [(set VR128:$dst,
1321                         (v4f32 (X86Movhlps VR128:$src1, VR128:$src2)))],
1322                         IIC_SSE_MOV_LH>, Sched<[WriteFShuffle]>;
1323 }
1324
1325 let Predicates = [UseAVX] in {
1326   // MOVLHPS patterns
1327   def : Pat<(v4i32 (X86Movlhps VR128:$src1, VR128:$src2)),
1328             (VMOVLHPSrr VR128:$src1, VR128:$src2)>;
1329   def : Pat<(v2i64 (X86Movlhps VR128:$src1, VR128:$src2)),
1330             (VMOVLHPSrr (v2i64 VR128:$src1), VR128:$src2)>;
1331
1332   // MOVHLPS patterns
1333   def : Pat<(v4i32 (X86Movhlps VR128:$src1, VR128:$src2)),
1334             (VMOVHLPSrr VR128:$src1, VR128:$src2)>;
1335 }
1336
1337 let Predicates = [UseSSE1] in {
1338   // MOVLHPS patterns
1339   def : Pat<(v4i32 (X86Movlhps VR128:$src1, VR128:$src2)),
1340             (MOVLHPSrr VR128:$src1, VR128:$src2)>;
1341   def : Pat<(v2i64 (X86Movlhps VR128:$src1, VR128:$src2)),
1342             (MOVLHPSrr (v2i64 VR128:$src1), VR128:$src2)>;
1343
1344   // MOVHLPS patterns
1345   def : Pat<(v4i32 (X86Movhlps VR128:$src1, VR128:$src2)),
1346             (MOVHLPSrr VR128:$src1, VR128:$src2)>;
1347 }
1348
1349 //===----------------------------------------------------------------------===//
1350 // SSE 1 & 2 - Conversion Instructions
1351 //===----------------------------------------------------------------------===//
1352
1353 def SSE_CVT_PD : OpndItins<
1354   IIC_SSE_CVT_PD_RR, IIC_SSE_CVT_PD_RM
1355 >;
1356
1357 let Sched = WriteCvtI2F in
1358 def SSE_CVT_PS : OpndItins<
1359   IIC_SSE_CVT_PS_RR, IIC_SSE_CVT_PS_RM
1360 >;
1361
1362 let Sched = WriteCvtI2F in
1363 def SSE_CVT_Scalar : OpndItins<
1364   IIC_SSE_CVT_Scalar_RR, IIC_SSE_CVT_Scalar_RM
1365 >;
1366
1367 let Sched = WriteCvtF2I in
1368 def SSE_CVT_SS2SI_32 : OpndItins<
1369   IIC_SSE_CVT_SS2SI32_RR, IIC_SSE_CVT_SS2SI32_RM
1370 >;
1371
1372 let Sched = WriteCvtF2I in
1373 def SSE_CVT_SS2SI_64 : OpndItins<
1374   IIC_SSE_CVT_SS2SI64_RR, IIC_SSE_CVT_SS2SI64_RM
1375 >;
1376
1377 let Sched = WriteCvtF2I in
1378 def SSE_CVT_SD2SI : OpndItins<
1379   IIC_SSE_CVT_SD2SI_RR, IIC_SSE_CVT_SD2SI_RM
1380 >;
1381
1382 // FIXME: We probably want to match the rm form only when optimizing for
1383 // size, to avoid false depenendecies (see sse_fp_unop_s for details)
1384 multiclass sse12_cvt_s<bits<8> opc, RegisterClass SrcRC, RegisterClass DstRC,
1385                      SDNode OpNode, X86MemOperand x86memop, PatFrag ld_frag,
1386                      string asm, OpndItins itins> {
1387   def rr : SI<opc, MRMSrcReg, (outs DstRC:$dst), (ins SrcRC:$src), asm,
1388                         [(set DstRC:$dst, (OpNode SrcRC:$src))],
1389                         itins.rr>, Sched<[itins.Sched]>;
1390   def rm : SI<opc, MRMSrcMem, (outs DstRC:$dst), (ins x86memop:$src), asm,
1391                         [(set DstRC:$dst, (OpNode (ld_frag addr:$src)))],
1392                         itins.rm>, Sched<[itins.Sched.Folded]>;
1393 }
1394
1395 multiclass sse12_cvt_p<bits<8> opc, RegisterClass RC, X86MemOperand x86memop,
1396                        ValueType DstTy, ValueType SrcTy, PatFrag ld_frag,
1397                        string asm, Domain d, OpndItins itins> {
1398 let hasSideEffects = 0 in {
1399   def rr : I<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src), asm,
1400              [(set RC:$dst, (DstTy (sint_to_fp (SrcTy RC:$src))))],
1401              itins.rr, d>, Sched<[itins.Sched]>;
1402   let mayLoad = 1 in
1403   def rm : I<opc, MRMSrcMem, (outs RC:$dst), (ins x86memop:$src), asm,
1404              [(set RC:$dst, (DstTy (sint_to_fp
1405                                     (SrcTy (bitconvert (ld_frag addr:$src))))))],
1406              itins.rm, d>, Sched<[itins.Sched.Folded]>;
1407 }
1408 }
1409
1410 // FIXME: We probably want to match the rm form only when optimizing for
1411 // size, to avoid false depenendecies (see sse_fp_unop_s for details)
1412 multiclass sse12_vcvt_avx<bits<8> opc, RegisterClass SrcRC, RegisterClass DstRC,
1413                           X86MemOperand x86memop, string asm> {
1414 let hasSideEffects = 0, Predicates = [UseAVX] in {
1415   def rr : SI<opc, MRMSrcReg, (outs DstRC:$dst), (ins DstRC:$src1, SrcRC:$src),
1416               !strconcat(asm,"\t{$src, $src1, $dst|$dst, $src1, $src}"), []>,
1417            Sched<[WriteCvtI2F]>;
1418   let mayLoad = 1 in
1419   def rm : SI<opc, MRMSrcMem, (outs DstRC:$dst),
1420               (ins DstRC:$src1, x86memop:$src),
1421               !strconcat(asm,"\t{$src, $src1, $dst|$dst, $src1, $src}"), []>,
1422            Sched<[WriteCvtI2FLd, ReadAfterLd]>;
1423 } // hasSideEffects = 0
1424 }
1425
1426 let Predicates = [UseAVX] in {
1427 defm VCVTTSS2SI   : sse12_cvt_s<0x2C, FR32, GR32, fp_to_sint, f32mem, loadf32,
1428                                 "cvttss2si\t{$src, $dst|$dst, $src}",
1429                                 SSE_CVT_SS2SI_32>,
1430                                 XS, VEX, VEX_LIG;
1431 defm VCVTTSS2SI64 : sse12_cvt_s<0x2C, FR32, GR64, fp_to_sint, f32mem, loadf32,
1432                                 "cvttss2si\t{$src, $dst|$dst, $src}",
1433                                 SSE_CVT_SS2SI_64>,
1434                                 XS, VEX, VEX_W, VEX_LIG;
1435 defm VCVTTSD2SI   : sse12_cvt_s<0x2C, FR64, GR32, fp_to_sint, f64mem, loadf64,
1436                                 "cvttsd2si\t{$src, $dst|$dst, $src}",
1437                                 SSE_CVT_SD2SI>,
1438                                 XD, VEX, VEX_LIG;
1439 defm VCVTTSD2SI64 : sse12_cvt_s<0x2C, FR64, GR64, fp_to_sint, f64mem, loadf64,
1440                                 "cvttsd2si\t{$src, $dst|$dst, $src}",
1441                                 SSE_CVT_SD2SI>,
1442                                 XD, VEX, VEX_W, VEX_LIG;
1443
1444 def : InstAlias<"vcvttss2si{l}\t{$src, $dst|$dst, $src}",
1445                 (VCVTTSS2SIrr GR32:$dst, FR32:$src), 0>;
1446 def : InstAlias<"vcvttss2si{l}\t{$src, $dst|$dst, $src}",
1447                 (VCVTTSS2SIrm GR32:$dst, f32mem:$src), 0>;
1448 def : InstAlias<"vcvttsd2si{l}\t{$src, $dst|$dst, $src}",
1449                 (VCVTTSD2SIrr GR32:$dst, FR64:$src), 0>;
1450 def : InstAlias<"vcvttsd2si{l}\t{$src, $dst|$dst, $src}",
1451                 (VCVTTSD2SIrm GR32:$dst, f64mem:$src), 0>;
1452 def : InstAlias<"vcvttss2si{q}\t{$src, $dst|$dst, $src}",
1453                 (VCVTTSS2SI64rr GR64:$dst, FR32:$src), 0>;
1454 def : InstAlias<"vcvttss2si{q}\t{$src, $dst|$dst, $src}",
1455                 (VCVTTSS2SI64rm GR64:$dst, f32mem:$src), 0>;
1456 def : InstAlias<"vcvttsd2si{q}\t{$src, $dst|$dst, $src}",
1457                 (VCVTTSD2SI64rr GR64:$dst, FR64:$src), 0>;
1458 def : InstAlias<"vcvttsd2si{q}\t{$src, $dst|$dst, $src}",
1459                 (VCVTTSD2SI64rm GR64:$dst, f64mem:$src), 0>;
1460 }
1461 // The assembler can recognize rr 64-bit instructions by seeing a rxx
1462 // register, but the same isn't true when only using memory operands,
1463 // provide other assembly "l" and "q" forms to address this explicitly
1464 // where appropriate to do so.
1465 defm VCVTSI2SS   : sse12_vcvt_avx<0x2A, GR32, FR32, i32mem, "cvtsi2ss{l}">,
1466                                   XS, VEX_4V, VEX_LIG;
1467 defm VCVTSI2SS64 : sse12_vcvt_avx<0x2A, GR64, FR32, i64mem, "cvtsi2ss{q}">,
1468                                   XS, VEX_4V, VEX_W, VEX_LIG;
1469 defm VCVTSI2SD   : sse12_vcvt_avx<0x2A, GR32, FR64, i32mem, "cvtsi2sd{l}">,
1470                                   XD, VEX_4V, VEX_LIG;
1471 defm VCVTSI2SD64 : sse12_vcvt_avx<0x2A, GR64, FR64, i64mem, "cvtsi2sd{q}">,
1472                                   XD, VEX_4V, VEX_W, VEX_LIG;
1473
1474 let Predicates = [UseAVX] in {
1475   def : InstAlias<"vcvtsi2ss\t{$src, $src1, $dst|$dst, $src1, $src}",
1476                 (VCVTSI2SSrm FR64:$dst, FR64:$src1, i32mem:$src), 0>;
1477   def : InstAlias<"vcvtsi2sd\t{$src, $src1, $dst|$dst, $src1, $src}",
1478                 (VCVTSI2SDrm FR64:$dst, FR64:$src1, i32mem:$src), 0>;
1479
1480   def : Pat<(f32 (sint_to_fp (loadi32 addr:$src))),
1481             (VCVTSI2SSrm (f32 (IMPLICIT_DEF)), addr:$src)>;
1482   def : Pat<(f32 (sint_to_fp (loadi64 addr:$src))),
1483             (VCVTSI2SS64rm (f32 (IMPLICIT_DEF)), addr:$src)>;
1484   def : Pat<(f64 (sint_to_fp (loadi32 addr:$src))),
1485             (VCVTSI2SDrm (f64 (IMPLICIT_DEF)), addr:$src)>;
1486   def : Pat<(f64 (sint_to_fp (loadi64 addr:$src))),
1487             (VCVTSI2SD64rm (f64 (IMPLICIT_DEF)), addr:$src)>;
1488
1489   def : Pat<(f32 (sint_to_fp GR32:$src)),
1490             (VCVTSI2SSrr (f32 (IMPLICIT_DEF)), GR32:$src)>;
1491   def : Pat<(f32 (sint_to_fp GR64:$src)),
1492             (VCVTSI2SS64rr (f32 (IMPLICIT_DEF)), GR64:$src)>;
1493   def : Pat<(f64 (sint_to_fp GR32:$src)),
1494             (VCVTSI2SDrr (f64 (IMPLICIT_DEF)), GR32:$src)>;
1495   def : Pat<(f64 (sint_to_fp GR64:$src)),
1496             (VCVTSI2SD64rr (f64 (IMPLICIT_DEF)), GR64:$src)>;
1497 }
1498
1499 defm CVTTSS2SI : sse12_cvt_s<0x2C, FR32, GR32, fp_to_sint, f32mem, loadf32,
1500                       "cvttss2si\t{$src, $dst|$dst, $src}",
1501                       SSE_CVT_SS2SI_32>, XS;
1502 defm CVTTSS2SI64 : sse12_cvt_s<0x2C, FR32, GR64, fp_to_sint, f32mem, loadf32,
1503                       "cvttss2si\t{$src, $dst|$dst, $src}",
1504                       SSE_CVT_SS2SI_64>, XS, REX_W;
1505 defm CVTTSD2SI : sse12_cvt_s<0x2C, FR64, GR32, fp_to_sint, f64mem, loadf64,
1506                       "cvttsd2si\t{$src, $dst|$dst, $src}",
1507                       SSE_CVT_SD2SI>, XD;
1508 defm CVTTSD2SI64 : sse12_cvt_s<0x2C, FR64, GR64, fp_to_sint, f64mem, loadf64,
1509                       "cvttsd2si\t{$src, $dst|$dst, $src}",
1510                       SSE_CVT_SD2SI>, XD, REX_W;
1511 defm CVTSI2SS  : sse12_cvt_s<0x2A, GR32, FR32, sint_to_fp, i32mem, loadi32,
1512                       "cvtsi2ss{l}\t{$src, $dst|$dst, $src}",
1513                       SSE_CVT_Scalar>, XS;
1514 defm CVTSI2SS64 : sse12_cvt_s<0x2A, GR64, FR32, sint_to_fp, i64mem, loadi64,
1515                       "cvtsi2ss{q}\t{$src, $dst|$dst, $src}",
1516                       SSE_CVT_Scalar>, XS, REX_W;
1517 defm CVTSI2SD  : sse12_cvt_s<0x2A, GR32, FR64, sint_to_fp, i32mem, loadi32,
1518                       "cvtsi2sd{l}\t{$src, $dst|$dst, $src}",
1519                       SSE_CVT_Scalar>, XD;
1520 defm CVTSI2SD64 : sse12_cvt_s<0x2A, GR64, FR64, sint_to_fp, i64mem, loadi64,
1521                       "cvtsi2sd{q}\t{$src, $dst|$dst, $src}",
1522                       SSE_CVT_Scalar>, XD, REX_W;
1523
1524 def : InstAlias<"cvttss2si{l}\t{$src, $dst|$dst, $src}",
1525                 (CVTTSS2SIrr GR32:$dst, FR32:$src), 0>;
1526 def : InstAlias<"cvttss2si{l}\t{$src, $dst|$dst, $src}",
1527                 (CVTTSS2SIrm GR32:$dst, f32mem:$src), 0>;
1528 def : InstAlias<"cvttsd2si{l}\t{$src, $dst|$dst, $src}",
1529                 (CVTTSD2SIrr GR32:$dst, FR64:$src), 0>;
1530 def : InstAlias<"cvttsd2si{l}\t{$src, $dst|$dst, $src}",
1531                 (CVTTSD2SIrm GR32:$dst, f64mem:$src), 0>;
1532 def : InstAlias<"cvttss2si{q}\t{$src, $dst|$dst, $src}",
1533                 (CVTTSS2SI64rr GR64:$dst, FR32:$src), 0>;
1534 def : InstAlias<"cvttss2si{q}\t{$src, $dst|$dst, $src}",
1535                 (CVTTSS2SI64rm GR64:$dst, f32mem:$src), 0>;
1536 def : InstAlias<"cvttsd2si{q}\t{$src, $dst|$dst, $src}",
1537                 (CVTTSD2SI64rr GR64:$dst, FR64:$src), 0>;
1538 def : InstAlias<"cvttsd2si{q}\t{$src, $dst|$dst, $src}",
1539                 (CVTTSD2SI64rm GR64:$dst, f64mem:$src), 0>;
1540
1541 def : InstAlias<"cvtsi2ss\t{$src, $dst|$dst, $src}",
1542                 (CVTSI2SSrm FR64:$dst, i32mem:$src), 0>;
1543 def : InstAlias<"cvtsi2sd\t{$src, $dst|$dst, $src}",
1544                 (CVTSI2SDrm FR64:$dst, i32mem:$src), 0>;
1545
1546 // Conversion Instructions Intrinsics - Match intrinsics which expect MM
1547 // and/or XMM operand(s).
1548
1549 // FIXME: We probably want to match the rm form only when optimizing for
1550 // size, to avoid false depenendecies (see sse_fp_unop_s for details)
1551 multiclass sse12_cvt_sint<bits<8> opc, RegisterClass SrcRC, RegisterClass DstRC,
1552                          Intrinsic Int, Operand memop, ComplexPattern mem_cpat,
1553                          string asm, OpndItins itins> {
1554   def rr : SI<opc, MRMSrcReg, (outs DstRC:$dst), (ins SrcRC:$src),
1555               !strconcat(asm, "\t{$src, $dst|$dst, $src}"),
1556               [(set DstRC:$dst, (Int SrcRC:$src))], itins.rr>,
1557            Sched<[itins.Sched]>;
1558   def rm : SI<opc, MRMSrcMem, (outs DstRC:$dst), (ins memop:$src),
1559               !strconcat(asm, "\t{$src, $dst|$dst, $src}"),
1560               [(set DstRC:$dst, (Int mem_cpat:$src))], itins.rm>,
1561            Sched<[itins.Sched.Folded]>;
1562 }
1563
1564 multiclass sse12_cvt_sint_3addr<bits<8> opc, RegisterClass SrcRC,
1565                     RegisterClass DstRC, Intrinsic Int, X86MemOperand x86memop,
1566                     PatFrag ld_frag, string asm, OpndItins itins,
1567                     bit Is2Addr = 1> {
1568   def rr : SI<opc, MRMSrcReg, (outs DstRC:$dst), (ins DstRC:$src1, SrcRC:$src2),
1569               !if(Is2Addr,
1570                   !strconcat(asm, "\t{$src2, $dst|$dst, $src2}"),
1571                   !strconcat(asm, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
1572               [(set DstRC:$dst, (Int DstRC:$src1, SrcRC:$src2))],
1573               itins.rr>, Sched<[itins.Sched]>;
1574   def rm : SI<opc, MRMSrcMem, (outs DstRC:$dst),
1575               (ins DstRC:$src1, x86memop:$src2),
1576               !if(Is2Addr,
1577                   !strconcat(asm, "\t{$src2, $dst|$dst, $src2}"),
1578                   !strconcat(asm, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
1579               [(set DstRC:$dst, (Int DstRC:$src1, (ld_frag addr:$src2)))],
1580               itins.rm>, Sched<[itins.Sched.Folded, ReadAfterLd]>;
1581 }
1582
1583 let Predicates = [UseAVX] in {
1584 defm VCVTSD2SI : sse12_cvt_sint<0x2D, VR128, GR32,
1585                   int_x86_sse2_cvtsd2si, sdmem, sse_load_f64, "cvtsd2si",
1586                   SSE_CVT_SD2SI>, XD, VEX, VEX_LIG;
1587 defm VCVTSD2SI64 : sse12_cvt_sint<0x2D, VR128, GR64,
1588                     int_x86_sse2_cvtsd2si64, sdmem, sse_load_f64, "cvtsd2si",
1589                     SSE_CVT_SD2SI>, XD, VEX, VEX_W, VEX_LIG;
1590 }
1591 defm CVTSD2SI : sse12_cvt_sint<0x2D, VR128, GR32, int_x86_sse2_cvtsd2si,
1592                  sdmem, sse_load_f64, "cvtsd2si", SSE_CVT_SD2SI>, XD;
1593 defm CVTSD2SI64 : sse12_cvt_sint<0x2D, VR128, GR64, int_x86_sse2_cvtsd2si64,
1594                    sdmem, sse_load_f64, "cvtsd2si", SSE_CVT_SD2SI>, XD, REX_W;
1595
1596
1597 let isCodeGenOnly = 1 in {
1598   let Predicates = [UseAVX] in {
1599   defm Int_VCVTSI2SS : sse12_cvt_sint_3addr<0x2A, GR32, VR128,
1600             int_x86_sse_cvtsi2ss, i32mem, loadi32, "cvtsi2ss{l}",
1601             SSE_CVT_Scalar, 0>, XS, VEX_4V;
1602   defm Int_VCVTSI2SS64 : sse12_cvt_sint_3addr<0x2A, GR64, VR128,
1603             int_x86_sse_cvtsi642ss, i64mem, loadi64, "cvtsi2ss{q}",
1604             SSE_CVT_Scalar, 0>, XS, VEX_4V,
1605             VEX_W;
1606   defm Int_VCVTSI2SD : sse12_cvt_sint_3addr<0x2A, GR32, VR128,
1607             int_x86_sse2_cvtsi2sd, i32mem, loadi32, "cvtsi2sd{l}",
1608             SSE_CVT_Scalar, 0>, XD, VEX_4V;
1609   defm Int_VCVTSI2SD64 : sse12_cvt_sint_3addr<0x2A, GR64, VR128,
1610             int_x86_sse2_cvtsi642sd, i64mem, loadi64, "cvtsi2sd{q}",
1611             SSE_CVT_Scalar, 0>, XD,
1612             VEX_4V, VEX_W;
1613   }
1614   let Constraints = "$src1 = $dst" in {
1615     defm Int_CVTSI2SS : sse12_cvt_sint_3addr<0x2A, GR32, VR128,
1616                           int_x86_sse_cvtsi2ss, i32mem, loadi32,
1617                           "cvtsi2ss{l}", SSE_CVT_Scalar>, XS;
1618     defm Int_CVTSI2SS64 : sse12_cvt_sint_3addr<0x2A, GR64, VR128,
1619                           int_x86_sse_cvtsi642ss, i64mem, loadi64,
1620                           "cvtsi2ss{q}", SSE_CVT_Scalar>, XS, REX_W;
1621     defm Int_CVTSI2SD : sse12_cvt_sint_3addr<0x2A, GR32, VR128,
1622                           int_x86_sse2_cvtsi2sd, i32mem, loadi32,
1623                           "cvtsi2sd{l}", SSE_CVT_Scalar>, XD;
1624     defm Int_CVTSI2SD64 : sse12_cvt_sint_3addr<0x2A, GR64, VR128,
1625                           int_x86_sse2_cvtsi642sd, i64mem, loadi64,
1626                           "cvtsi2sd{q}", SSE_CVT_Scalar>, XD, REX_W;
1627   }
1628 } // isCodeGenOnly = 1
1629
1630 /// SSE 1 Only
1631
1632 // Aliases for intrinsics
1633 let isCodeGenOnly = 1 in {
1634 let Predicates = [UseAVX] in {
1635 defm Int_VCVTTSS2SI : sse12_cvt_sint<0x2C, VR128, GR32, int_x86_sse_cvttss2si,
1636                                     ssmem, sse_load_f32, "cvttss2si",
1637                                     SSE_CVT_SS2SI_32>, XS, VEX;
1638 defm Int_VCVTTSS2SI64 : sse12_cvt_sint<0x2C, VR128, GR64,
1639                                    int_x86_sse_cvttss2si64, ssmem, sse_load_f32,
1640                                    "cvttss2si", SSE_CVT_SS2SI_64>,
1641                                    XS, VEX, VEX_W;
1642 defm Int_VCVTTSD2SI : sse12_cvt_sint<0x2C, VR128, GR32, int_x86_sse2_cvttsd2si,
1643                                     sdmem, sse_load_f64, "cvttsd2si",
1644                                     SSE_CVT_SD2SI>, XD, VEX;
1645 defm Int_VCVTTSD2SI64 : sse12_cvt_sint<0x2C, VR128, GR64,
1646                                   int_x86_sse2_cvttsd2si64, sdmem, sse_load_f64,
1647                                   "cvttsd2si", SSE_CVT_SD2SI>,
1648                                   XD, VEX, VEX_W;
1649 }
1650 defm Int_CVTTSS2SI : sse12_cvt_sint<0x2C, VR128, GR32, int_x86_sse_cvttss2si,
1651                                     ssmem, sse_load_f32, "cvttss2si",
1652                                     SSE_CVT_SS2SI_32>, XS;
1653 defm Int_CVTTSS2SI64 : sse12_cvt_sint<0x2C, VR128, GR64,
1654                                    int_x86_sse_cvttss2si64, ssmem, sse_load_f32,
1655                                    "cvttss2si", SSE_CVT_SS2SI_64>, XS, REX_W;
1656 defm Int_CVTTSD2SI : sse12_cvt_sint<0x2C, VR128, GR32, int_x86_sse2_cvttsd2si,
1657                                     sdmem, sse_load_f64, "cvttsd2si",
1658                                     SSE_CVT_SD2SI>, XD;
1659 defm Int_CVTTSD2SI64 : sse12_cvt_sint<0x2C, VR128, GR64,
1660                                   int_x86_sse2_cvttsd2si64, sdmem, sse_load_f64,
1661                                   "cvttsd2si", SSE_CVT_SD2SI>, XD, REX_W;
1662 } // isCodeGenOnly = 1
1663
1664 let Predicates = [UseAVX] in {
1665 defm VCVTSS2SI   : sse12_cvt_sint<0x2D, VR128, GR32, int_x86_sse_cvtss2si,
1666                                   ssmem, sse_load_f32, "cvtss2si",
1667                                   SSE_CVT_SS2SI_32>, XS, VEX, VEX_LIG;
1668 defm VCVTSS2SI64 : sse12_cvt_sint<0x2D, VR128, GR64, int_x86_sse_cvtss2si64,
1669                                   ssmem, sse_load_f32, "cvtss2si",
1670                                   SSE_CVT_SS2SI_64>, XS, VEX, VEX_W, VEX_LIG;
1671 }
1672 defm CVTSS2SI : sse12_cvt_sint<0x2D, VR128, GR32, int_x86_sse_cvtss2si,
1673                                ssmem, sse_load_f32, "cvtss2si",
1674                                SSE_CVT_SS2SI_32>, XS;
1675 defm CVTSS2SI64 : sse12_cvt_sint<0x2D, VR128, GR64, int_x86_sse_cvtss2si64,
1676                                  ssmem, sse_load_f32, "cvtss2si",
1677                                  SSE_CVT_SS2SI_64>, XS, REX_W;
1678
1679 defm VCVTDQ2PS   : sse12_cvt_p<0x5B, VR128, i128mem, v4f32, v4i32, loadv2i64,
1680                                "vcvtdq2ps\t{$src, $dst|$dst, $src}",
1681                                SSEPackedSingle, SSE_CVT_PS>,
1682                                PS, VEX, Requires<[HasAVX, NoVLX]>, VEX_WIG;
1683 defm VCVTDQ2PSY  : sse12_cvt_p<0x5B, VR256, i256mem, v8f32, v8i32, loadv4i64,
1684                                "vcvtdq2ps\t{$src, $dst|$dst, $src}",
1685                                SSEPackedSingle, SSE_CVT_PS>,
1686                                PS, VEX, VEX_L, Requires<[HasAVX, NoVLX]>, VEX_WIG;
1687
1688 defm CVTDQ2PS : sse12_cvt_p<0x5B, VR128, i128mem, v4f32, v4i32, memopv2i64,
1689                             "cvtdq2ps\t{$src, $dst|$dst, $src}",
1690                             SSEPackedSingle, SSE_CVT_PS>,
1691                             PS, Requires<[UseSSE2]>;
1692
1693 let Predicates = [UseAVX] in {
1694 def : InstAlias<"vcvtss2si{l}\t{$src, $dst|$dst, $src}",
1695                 (VCVTSS2SIrr GR32:$dst, VR128:$src), 0>;
1696 def : InstAlias<"vcvtss2si{l}\t{$src, $dst|$dst, $src}",
1697                 (VCVTSS2SIrm GR32:$dst, ssmem:$src), 0>;
1698 def : InstAlias<"vcvtsd2si{l}\t{$src, $dst|$dst, $src}",
1699                 (VCVTSD2SIrr GR32:$dst, VR128:$src), 0>;
1700 def : InstAlias<"vcvtsd2si{l}\t{$src, $dst|$dst, $src}",
1701                 (VCVTSD2SIrm GR32:$dst, sdmem:$src), 0>;
1702 def : InstAlias<"vcvtss2si{q}\t{$src, $dst|$dst, $src}",
1703                 (VCVTSS2SI64rr GR64:$dst, VR128:$src), 0>;
1704 def : InstAlias<"vcvtss2si{q}\t{$src, $dst|$dst, $src}",
1705                 (VCVTSS2SI64rm GR64:$dst, ssmem:$src), 0>;
1706 def : InstAlias<"vcvtsd2si{q}\t{$src, $dst|$dst, $src}",
1707                 (VCVTSD2SI64rr GR64:$dst, VR128:$src), 0>;
1708 def : InstAlias<"vcvtsd2si{q}\t{$src, $dst|$dst, $src}",
1709                 (VCVTSD2SI64rm GR64:$dst, sdmem:$src), 0>;
1710 }
1711
1712 def : InstAlias<"cvtss2si{l}\t{$src, $dst|$dst, $src}",
1713                 (CVTSS2SIrr GR32:$dst, VR128:$src), 0>;
1714 def : InstAlias<"cvtss2si{l}\t{$src, $dst|$dst, $src}",
1715                 (CVTSS2SIrm GR32:$dst, ssmem:$src), 0>;
1716 def : InstAlias<"cvtsd2si{l}\t{$src, $dst|$dst, $src}",
1717                 (CVTSD2SIrr GR32:$dst, VR128:$src), 0>;
1718 def : InstAlias<"cvtsd2si{l}\t{$src, $dst|$dst, $src}",
1719                 (CVTSD2SIrm GR32:$dst, sdmem:$src), 0>;
1720 def : InstAlias<"cvtss2si{q}\t{$src, $dst|$dst, $src}",
1721                 (CVTSS2SI64rr GR64:$dst, VR128:$src), 0>;
1722 def : InstAlias<"cvtss2si{q}\t{$src, $dst|$dst, $src}",
1723                 (CVTSS2SI64rm GR64:$dst, ssmem:$src), 0>;
1724 def : InstAlias<"cvtsd2si{q}\t{$src, $dst|$dst, $src}",
1725                 (CVTSD2SI64rr GR64:$dst, VR128:$src), 0>;
1726 def : InstAlias<"cvtsd2si{q}\t{$src, $dst|$dst, $src}",
1727                 (CVTSD2SI64rm GR64:$dst, sdmem:$src), 0>;
1728
1729 /// SSE 2 Only
1730
1731 // Convert scalar double to scalar single
1732 let hasSideEffects = 0, Predicates = [UseAVX] in {
1733 def VCVTSD2SSrr  : VSDI<0x5A, MRMSrcReg, (outs FR32:$dst),
1734                        (ins FR32:$src1, FR64:$src2),
1735                       "cvtsd2ss\t{$src2, $src1, $dst|$dst, $src1, $src2}", [],
1736                       IIC_SSE_CVT_Scalar_RR>, VEX_4V, VEX_LIG,
1737                       Sched<[WriteCvtF2F]>, VEX_WIG;
1738 let mayLoad = 1 in
1739 def VCVTSD2SSrm  : I<0x5A, MRMSrcMem, (outs FR32:$dst),
1740                        (ins FR32:$src1, f64mem:$src2),
1741                       "vcvtsd2ss\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1742                       [], IIC_SSE_CVT_Scalar_RM>,
1743                       XD, Requires<[HasAVX, OptForSize]>, VEX_4V, VEX_LIG,
1744                       Sched<[WriteCvtF2FLd, ReadAfterLd]>, VEX_WIG;
1745 }
1746
1747 def : Pat<(f32 (fpround FR64:$src)),
1748             (VCVTSD2SSrr (COPY_TO_REGCLASS FR64:$src, FR32), FR64:$src)>,
1749           Requires<[UseAVX]>;
1750
1751 def CVTSD2SSrr  : SDI<0x5A, MRMSrcReg, (outs FR32:$dst), (ins FR64:$src),
1752                       "cvtsd2ss\t{$src, $dst|$dst, $src}",
1753                       [(set FR32:$dst, (fpround FR64:$src))],
1754                       IIC_SSE_CVT_Scalar_RR>, Sched<[WriteCvtF2F]>;
1755 def CVTSD2SSrm  : I<0x5A, MRMSrcMem, (outs FR32:$dst), (ins f64mem:$src),
1756                       "cvtsd2ss\t{$src, $dst|$dst, $src}",
1757                       [(set FR32:$dst, (fpround (loadf64 addr:$src)))],
1758                       IIC_SSE_CVT_Scalar_RM>,
1759                       XD,
1760                   Requires<[UseSSE2, OptForSize]>, Sched<[WriteCvtF2FLd]>;
1761
1762 let isCodeGenOnly = 1 in {
1763 def Int_VCVTSD2SSrr: I<0x5A, MRMSrcReg,
1764                        (outs VR128:$dst), (ins VR128:$src1, VR128:$src2),
1765                        "vcvtsd2ss\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1766                        [(set VR128:$dst,
1767                          (int_x86_sse2_cvtsd2ss VR128:$src1, VR128:$src2))],
1768                        IIC_SSE_CVT_Scalar_RR>, XD, VEX_4V, VEX_WIG,
1769                        Requires<[HasAVX]>, Sched<[WriteCvtF2F]>;
1770 def Int_VCVTSD2SSrm: I<0x5A, MRMSrcMem,
1771                        (outs VR128:$dst), (ins VR128:$src1, sdmem:$src2),
1772                        "vcvtsd2ss\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1773                        [(set VR128:$dst, (int_x86_sse2_cvtsd2ss
1774                                           VR128:$src1, sse_load_f64:$src2))],
1775                        IIC_SSE_CVT_Scalar_RM>, XD, VEX_4V, VEX_WIG,
1776                        Requires<[HasAVX]>, Sched<[WriteCvtF2FLd, ReadAfterLd]>;
1777
1778 let Constraints = "$src1 = $dst" in {
1779 def Int_CVTSD2SSrr: I<0x5A, MRMSrcReg,
1780                        (outs VR128:$dst), (ins VR128:$src1, VR128:$src2),
1781                        "cvtsd2ss\t{$src2, $dst|$dst, $src2}",
1782                        [(set VR128:$dst,
1783                          (int_x86_sse2_cvtsd2ss VR128:$src1, VR128:$src2))],
1784                        IIC_SSE_CVT_Scalar_RR>, XD, Requires<[UseSSE2]>,
1785                        Sched<[WriteCvtF2F]>;
1786 def Int_CVTSD2SSrm: I<0x5A, MRMSrcMem,
1787                        (outs VR128:$dst), (ins VR128:$src1, sdmem:$src2),
1788                        "cvtsd2ss\t{$src2, $dst|$dst, $src2}",
1789                        [(set VR128:$dst, (int_x86_sse2_cvtsd2ss
1790                                           VR128:$src1, sse_load_f64:$src2))],
1791                        IIC_SSE_CVT_Scalar_RM>, XD, Requires<[UseSSE2]>,
1792                        Sched<[WriteCvtF2FLd, ReadAfterLd]>;
1793 }
1794 } // isCodeGenOnly = 1
1795
1796 // Convert scalar single to scalar double
1797 // SSE2 instructions with XS prefix
1798 let hasSideEffects = 0, Predicates = [UseAVX] in {
1799 def VCVTSS2SDrr : I<0x5A, MRMSrcReg, (outs FR64:$dst),
1800                     (ins FR64:$src1, FR32:$src2),
1801                     "vcvtss2sd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1802                     [], IIC_SSE_CVT_Scalar_RR>,
1803                     XS, Requires<[HasAVX]>, VEX_4V, VEX_LIG,
1804                     Sched<[WriteCvtF2F]>, VEX_WIG;
1805 let mayLoad = 1 in
1806 def VCVTSS2SDrm : I<0x5A, MRMSrcMem, (outs FR64:$dst),
1807                     (ins FR64:$src1, f32mem:$src2),
1808                     "vcvtss2sd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1809                     [], IIC_SSE_CVT_Scalar_RM>,
1810                     XS, VEX_4V, VEX_LIG, Requires<[HasAVX, OptForSize]>,
1811                     Sched<[WriteCvtF2FLd, ReadAfterLd]>, VEX_WIG;
1812 }
1813
1814 def : Pat<(f64 (fpextend FR32:$src)),
1815     (VCVTSS2SDrr (COPY_TO_REGCLASS FR32:$src, FR64), FR32:$src)>, Requires<[UseAVX]>;
1816 def : Pat<(fpextend (loadf32 addr:$src)),
1817     (VCVTSS2SDrm (f64 (IMPLICIT_DEF)), addr:$src)>, Requires<[UseAVX]>;
1818
1819 def : Pat<(extloadf32 addr:$src),
1820     (VCVTSS2SDrm (f64 (IMPLICIT_DEF)), addr:$src)>,
1821     Requires<[UseAVX, OptForSize]>;
1822 def : Pat<(extloadf32 addr:$src),
1823     (VCVTSS2SDrr (f64 (IMPLICIT_DEF)), (VMOVSSrm addr:$src))>,
1824     Requires<[UseAVX, OptForSpeed]>;
1825
1826 def CVTSS2SDrr : I<0x5A, MRMSrcReg, (outs FR64:$dst), (ins FR32:$src),
1827                    "cvtss2sd\t{$src, $dst|$dst, $src}",
1828                    [(set FR64:$dst, (fpextend FR32:$src))],
1829                    IIC_SSE_CVT_Scalar_RR>, XS,
1830                  Requires<[UseSSE2]>, Sched<[WriteCvtF2F]>;
1831 def CVTSS2SDrm : I<0x5A, MRMSrcMem, (outs FR64:$dst), (ins f32mem:$src),
1832                    "cvtss2sd\t{$src, $dst|$dst, $src}",
1833                    [(set FR64:$dst, (extloadf32 addr:$src))],
1834                    IIC_SSE_CVT_Scalar_RM>, XS,
1835                  Requires<[UseSSE2, OptForSize]>, Sched<[WriteCvtF2FLd]>;
1836
1837 // extload f32 -> f64.  This matches load+fpextend because we have a hack in
1838 // the isel (PreprocessForFPConvert) that can introduce loads after dag
1839 // combine.
1840 // Since these loads aren't folded into the fpextend, we have to match it
1841 // explicitly here.
1842 def : Pat<(fpextend (loadf32 addr:$src)),
1843           (CVTSS2SDrm addr:$src)>, Requires<[UseSSE2]>;
1844 def : Pat<(extloadf32 addr:$src),
1845           (CVTSS2SDrr (MOVSSrm addr:$src))>, Requires<[UseSSE2, OptForSpeed]>;
1846
1847 let isCodeGenOnly = 1 in {
1848 def Int_VCVTSS2SDrr: I<0x5A, MRMSrcReg,
1849                       (outs VR128:$dst), (ins VR128:$src1, VR128:$src2),
1850                     "vcvtss2sd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1851                     [(set VR128:$dst,
1852                       (int_x86_sse2_cvtss2sd VR128:$src1, VR128:$src2))],
1853                     IIC_SSE_CVT_Scalar_RR>, XS, VEX_4V, VEX_WIG,
1854                     Requires<[HasAVX]>, Sched<[WriteCvtF2F]>;
1855 def Int_VCVTSS2SDrm: I<0x5A, MRMSrcMem,
1856                       (outs VR128:$dst), (ins VR128:$src1, ssmem:$src2),
1857                     "vcvtss2sd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1858                     [(set VR128:$dst,
1859                       (int_x86_sse2_cvtss2sd VR128:$src1, sse_load_f32:$src2))],
1860                     IIC_SSE_CVT_Scalar_RM>, XS, VEX_4V, VEX_WIG,
1861                     Requires<[HasAVX]>, Sched<[WriteCvtF2FLd, ReadAfterLd]>;
1862 let Constraints = "$src1 = $dst" in { // SSE2 instructions with XS prefix
1863 def Int_CVTSS2SDrr: I<0x5A, MRMSrcReg,
1864                       (outs VR128:$dst), (ins VR128:$src1, VR128:$src2),
1865                     "cvtss2sd\t{$src2, $dst|$dst, $src2}",
1866                     [(set VR128:$dst,
1867                       (int_x86_sse2_cvtss2sd VR128:$src1, VR128:$src2))],
1868                     IIC_SSE_CVT_Scalar_RR>, XS, Requires<[UseSSE2]>,
1869                     Sched<[WriteCvtF2F]>;
1870 def Int_CVTSS2SDrm: I<0x5A, MRMSrcMem,
1871                       (outs VR128:$dst), (ins VR128:$src1, ssmem:$src2),
1872                     "cvtss2sd\t{$src2, $dst|$dst, $src2}",
1873                     [(set VR128:$dst,
1874                       (int_x86_sse2_cvtss2sd VR128:$src1, sse_load_f32:$src2))],
1875                     IIC_SSE_CVT_Scalar_RM>, XS, Requires<[UseSSE2]>,
1876                     Sched<[WriteCvtF2FLd, ReadAfterLd]>;
1877 }
1878 } // isCodeGenOnly = 1
1879
1880 // Patterns used for matching (v)cvtsi2ss, (v)cvtsi2sd, (v)cvtsd2ss and
1881 // (v)cvtss2sd intrinsic sequences from clang which produce unnecessary
1882 // vmovs{s,d} instructions
1883 let Predicates = [UseAVX] in {
1884 def : Pat<(v4f32 (X86Movss
1885                    (v4f32 VR128:$dst),
1886                    (v4f32 (scalar_to_vector
1887                      (f32 (fpround (f64 (extractelt VR128:$src, (iPTR 0))))))))),
1888           (Int_VCVTSD2SSrr VR128:$dst, VR128:$src)>;
1889
1890 def : Pat<(v2f64 (X86Movsd
1891                    (v2f64 VR128:$dst),
1892                    (v2f64 (scalar_to_vector
1893                      (f64 (fpextend (f32 (extractelt VR128:$src, (iPTR 0))))))))),
1894           (Int_VCVTSS2SDrr VR128:$dst, VR128:$src)>;
1895
1896 def : Pat<(v4f32 (X86Movss
1897                    (v4f32 VR128:$dst),
1898                    (v4f32 (scalar_to_vector (f32 (sint_to_fp GR64:$src)))))),
1899           (Int_VCVTSI2SS64rr VR128:$dst, GR64:$src)>;
1900
1901 def : Pat<(v4f32 (X86Movss
1902                    (v4f32 VR128:$dst),
1903                    (v4f32 (scalar_to_vector (f32 (sint_to_fp GR32:$src)))))),
1904           (Int_VCVTSI2SSrr VR128:$dst, GR32:$src)>;
1905
1906 def : Pat<(v2f64 (X86Movsd
1907                    (v2f64 VR128:$dst),
1908                    (v2f64 (scalar_to_vector (f64 (sint_to_fp GR64:$src)))))),
1909           (Int_VCVTSI2SD64rr VR128:$dst, GR64:$src)>;
1910
1911 def : Pat<(v2f64 (X86Movsd
1912                    (v2f64 VR128:$dst),
1913                    (v2f64 (scalar_to_vector (f64 (sint_to_fp GR32:$src)))))),
1914           (Int_VCVTSI2SDrr VR128:$dst, GR32:$src)>;
1915 } // Predicates = [UseAVX]
1916
1917 let Predicates = [UseSSE2] in {
1918 def : Pat<(v4f32 (X86Movss
1919                    (v4f32 VR128:$dst),
1920                    (v4f32 (scalar_to_vector
1921                      (f32 (fpround (f64 (extractelt VR128:$src, (iPTR 0))))))))),
1922           (Int_CVTSD2SSrr VR128:$dst, VR128:$src)>;
1923
1924 def : Pat<(v2f64 (X86Movsd
1925                    (v2f64 VR128:$dst),
1926                    (v2f64 (scalar_to_vector
1927                      (f64 (fpextend (f32 (extractelt VR128:$src, (iPTR 0))))))))),
1928           (Int_CVTSS2SDrr VR128:$dst, VR128:$src)>;
1929
1930 def : Pat<(v2f64 (X86Movsd
1931                    (v2f64 VR128:$dst),
1932                    (v2f64 (scalar_to_vector (f64 (sint_to_fp GR64:$src)))))),
1933           (Int_CVTSI2SD64rr VR128:$dst, GR64:$src)>;
1934
1935 def : Pat<(v2f64 (X86Movsd
1936                    (v2f64 VR128:$dst),
1937                    (v2f64 (scalar_to_vector (f64 (sint_to_fp GR32:$src)))))),
1938           (Int_CVTSI2SDrr VR128:$dst, GR32:$src)>;
1939 } // Predicates = [UseSSE2]
1940
1941 let Predicates = [UseSSE1] in {
1942 def : Pat<(v4f32 (X86Movss
1943                    (v4f32 VR128:$dst),
1944                    (v4f32 (scalar_to_vector (f32 (sint_to_fp GR64:$src)))))),
1945           (Int_CVTSI2SS64rr VR128:$dst, GR64:$src)>;
1946
1947 def : Pat<(v4f32 (X86Movss
1948                    (v4f32 VR128:$dst),
1949                    (v4f32 (scalar_to_vector (f32 (sint_to_fp GR32:$src)))))),
1950           (Int_CVTSI2SSrr VR128:$dst, GR32:$src)>;
1951 } // Predicates = [UseSSE1]
1952
1953 // Convert packed single/double fp to doubleword
1954 def VCVTPS2DQrr : VPDI<0x5B, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1955                        "cvtps2dq\t{$src, $dst|$dst, $src}",
1956                        [(set VR128:$dst, (int_x86_sse2_cvtps2dq VR128:$src))],
1957                        IIC_SSE_CVT_PS_RR>, VEX, Sched<[WriteCvtF2I]>, VEX_WIG;
1958 def VCVTPS2DQrm : VPDI<0x5B, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1959                        "cvtps2dq\t{$src, $dst|$dst, $src}",
1960                        [(set VR128:$dst,
1961                          (int_x86_sse2_cvtps2dq (loadv4f32 addr:$src)))],
1962                        IIC_SSE_CVT_PS_RM>, VEX, Sched<[WriteCvtF2ILd]>, VEX_WIG;
1963 def VCVTPS2DQYrr : VPDI<0x5B, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
1964                         "cvtps2dq\t{$src, $dst|$dst, $src}",
1965                         [(set VR256:$dst,
1966                           (int_x86_avx_cvt_ps2dq_256 VR256:$src))],
1967                         IIC_SSE_CVT_PS_RR>, VEX, VEX_L, Sched<[WriteCvtF2I]>, VEX_WIG;
1968 def VCVTPS2DQYrm : VPDI<0x5B, MRMSrcMem, (outs VR256:$dst), (ins f256mem:$src),
1969                         "cvtps2dq\t{$src, $dst|$dst, $src}",
1970                         [(set VR256:$dst,
1971                           (int_x86_avx_cvt_ps2dq_256 (loadv8f32 addr:$src)))],
1972                         IIC_SSE_CVT_PS_RM>, VEX, VEX_L, Sched<[WriteCvtF2ILd]>, VEX_WIG;
1973 def CVTPS2DQrr : PDI<0x5B, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1974                      "cvtps2dq\t{$src, $dst|$dst, $src}",
1975                      [(set VR128:$dst, (int_x86_sse2_cvtps2dq VR128:$src))],
1976                      IIC_SSE_CVT_PS_RR>, Sched<[WriteCvtF2I]>;
1977 def CVTPS2DQrm : PDI<0x5B, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1978                      "cvtps2dq\t{$src, $dst|$dst, $src}",
1979                      [(set VR128:$dst,
1980                        (int_x86_sse2_cvtps2dq (memopv4f32 addr:$src)))],
1981                      IIC_SSE_CVT_PS_RM>, Sched<[WriteCvtF2ILd]>;
1982
1983
1984 // Convert Packed Double FP to Packed DW Integers
1985 let Predicates = [HasAVX, NoVLX] in {
1986 // The assembler can recognize rr 256-bit instructions by seeing a ymm
1987 // register, but the same isn't true when using memory operands instead.
1988 // Provide other assembly rr and rm forms to address this explicitly.
1989 def VCVTPD2DQrr  : SDI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1990                        "vcvtpd2dq\t{$src, $dst|$dst, $src}",
1991                        [(set VR128:$dst,
1992                          (v4i32 (X86cvtp2Int (v2f64 VR128:$src))))]>,
1993                        VEX, Sched<[WriteCvtF2I]>, VEX_WIG;
1994
1995 // XMM only
1996 def : InstAlias<"vcvtpd2dqx\t{$src, $dst|$dst, $src}",
1997                 (VCVTPD2DQrr VR128:$dst, VR128:$src), 0>;
1998 def VCVTPD2DQrm : SDI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1999                       "vcvtpd2dq{x}\t{$src, $dst|$dst, $src}",
2000                       [(set VR128:$dst,
2001                         (v4i32 (X86cvtp2Int (loadv2f64 addr:$src))))]>, VEX,
2002                       Sched<[WriteCvtF2ILd]>, VEX_WIG;
2003 def : InstAlias<"vcvtpd2dqx\t{$src, $dst|$dst, $src}",
2004                 (VCVTPD2DQrm VR128:$dst, f128mem:$src), 0>;
2005
2006 // YMM only
2007 def VCVTPD2DQYrr : SDI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR256:$src),
2008                        "vcvtpd2dq\t{$src, $dst|$dst, $src}",
2009                        [(set VR128:$dst,
2010                          (v4i32 (X86cvtp2Int (v4f64 VR256:$src))))]>,
2011                        VEX, VEX_L, Sched<[WriteCvtF2I]>, VEX_WIG;
2012 def VCVTPD2DQYrm : SDI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f256mem:$src),
2013                        "vcvtpd2dq{y}\t{$src, $dst|$dst, $src}",
2014                        [(set VR128:$dst,
2015                          (v4i32 (X86cvtp2Int (loadv4f64 addr:$src))))]>,
2016                        VEX, VEX_L, Sched<[WriteCvtF2ILd]>, VEX_WIG;
2017 def : InstAlias<"vcvtpd2dqy\t{$src, $dst|$dst, $src}",
2018                 (VCVTPD2DQYrr VR128:$dst, VR256:$src), 0>;
2019 def : InstAlias<"vcvtpd2dqy\t{$src, $dst|$dst, $src}",
2020                 (VCVTPD2DQYrm VR128:$dst, f256mem:$src), 0>;
2021 }
2022
2023 def CVTPD2DQrm  : SDI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
2024                       "cvtpd2dq\t{$src, $dst|$dst, $src}",
2025                       [(set VR128:$dst,
2026                         (v4i32 (X86cvtp2Int (memopv2f64 addr:$src))))],
2027                       IIC_SSE_CVT_PD_RM>, Sched<[WriteCvtF2ILd]>;
2028 def CVTPD2DQrr  : SDI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2029                       "cvtpd2dq\t{$src, $dst|$dst, $src}",
2030                       [(set VR128:$dst,
2031                         (v4i32 (X86cvtp2Int (v2f64 VR128:$src))))],
2032                       IIC_SSE_CVT_PD_RR>, Sched<[WriteCvtF2I]>;
2033
2034 // Convert with truncation packed single/double fp to doubleword
2035 // SSE2 packed instructions with XS prefix
2036 let Predicates = [HasAVX, NoVLX] in {
2037 def VCVTTPS2DQrr : VS2SI<0x5B, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2038                          "cvttps2dq\t{$src, $dst|$dst, $src}",
2039                          [(set VR128:$dst,
2040                            (v4i32 (fp_to_sint (v4f32 VR128:$src))))],
2041                          IIC_SSE_CVT_PS_RR>, VEX, Sched<[WriteCvtF2I]>, VEX_WIG;
2042 def VCVTTPS2DQrm : VS2SI<0x5B, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
2043                          "cvttps2dq\t{$src, $dst|$dst, $src}",
2044                          [(set VR128:$dst,
2045                            (v4i32 (fp_to_sint (loadv4f32 addr:$src))))],
2046                          IIC_SSE_CVT_PS_RM>, VEX, Sched<[WriteCvtF2ILd]>, VEX_WIG;
2047 def VCVTTPS2DQYrr : VS2SI<0x5B, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
2048                           "cvttps2dq\t{$src, $dst|$dst, $src}",
2049                           [(set VR256:$dst,
2050                             (v8i32 (fp_to_sint (v8f32 VR256:$src))))],
2051                           IIC_SSE_CVT_PS_RR>, VEX, VEX_L, Sched<[WriteCvtF2I]>, VEX_WIG;
2052 def VCVTTPS2DQYrm : VS2SI<0x5B, MRMSrcMem, (outs VR256:$dst), (ins f256mem:$src),
2053                           "cvttps2dq\t{$src, $dst|$dst, $src}",
2054                           [(set VR256:$dst,
2055                             (v8i32 (fp_to_sint (loadv8f32 addr:$src))))],
2056                           IIC_SSE_CVT_PS_RM>, VEX, VEX_L,
2057                           Sched<[WriteCvtF2ILd]>, VEX_WIG;
2058 }
2059
2060 def CVTTPS2DQrr : S2SI<0x5B, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2061                        "cvttps2dq\t{$src, $dst|$dst, $src}",
2062                        [(set VR128:$dst,
2063                          (v4i32 (fp_to_sint (v4f32 VR128:$src))))],
2064                        IIC_SSE_CVT_PS_RR>, Sched<[WriteCvtF2I]>;
2065 def CVTTPS2DQrm : S2SI<0x5B, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
2066                        "cvttps2dq\t{$src, $dst|$dst, $src}",
2067                        [(set VR128:$dst,
2068                          (v4i32 (fp_to_sint (memopv4f32 addr:$src))))],
2069                        IIC_SSE_CVT_PS_RM>, Sched<[WriteCvtF2ILd]>;
2070
2071 let Predicates = [HasAVX, NoVLX] in
2072 def VCVTTPD2DQrr : VPDI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2073                         "cvttpd2dq\t{$src, $dst|$dst, $src}",
2074                         [(set VR128:$dst,
2075                           (v4i32 (X86cvttp2si (v2f64 VR128:$src))))],
2076                         IIC_SSE_CVT_PD_RR>, VEX, Sched<[WriteCvtF2I]>, VEX_WIG;
2077
2078 // The assembler can recognize rr 256-bit instructions by seeing a ymm
2079 // register, but the same isn't true when using memory operands instead.
2080 // Provide other assembly rr and rm forms to address this explicitly.
2081
2082 // XMM only
2083 def : InstAlias<"vcvttpd2dqx\t{$src, $dst|$dst, $src}",
2084                 (VCVTTPD2DQrr VR128:$dst, VR128:$src), 0>;
2085 let Predicates = [HasAVX, NoVLX] in
2086 def VCVTTPD2DQrm : VPDI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
2087                         "cvttpd2dq{x}\t{$src, $dst|$dst, $src}",
2088                         [(set VR128:$dst,
2089                           (v4i32 (X86cvttp2si (loadv2f64 addr:$src))))],
2090                         IIC_SSE_CVT_PD_RM>, VEX, Sched<[WriteCvtF2ILd]>, VEX_WIG;
2091 def : InstAlias<"vcvttpd2dqx\t{$src, $dst|$dst, $src}",
2092                 (VCVTTPD2DQrm VR128:$dst, f128mem:$src), 0>;
2093
2094 // YMM only
2095 let Predicates = [HasAVX, NoVLX] in {
2096 def VCVTTPD2DQYrr : VPDI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR256:$src),
2097                          "cvttpd2dq\t{$src, $dst|$dst, $src}",
2098                          [(set VR128:$dst,
2099                            (v4i32 (fp_to_sint (v4f64 VR256:$src))))],
2100                          IIC_SSE_CVT_PD_RR>, VEX, VEX_L, Sched<[WriteCvtF2I]>, VEX_WIG;
2101 def VCVTTPD2DQYrm : VPDI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f256mem:$src),
2102                          "cvttpd2dq{y}\t{$src, $dst|$dst, $src}",
2103                          [(set VR128:$dst,
2104                            (v4i32 (fp_to_sint (loadv4f64 addr:$src))))],
2105                          IIC_SSE_CVT_PD_RM>, VEX, VEX_L, Sched<[WriteCvtF2ILd]>, VEX_WIG;
2106 }
2107 def : InstAlias<"vcvttpd2dqy\t{$src, $dst|$dst, $src}",
2108                 (VCVTTPD2DQYrr VR128:$dst, VR256:$src), 0>;
2109 def : InstAlias<"vcvttpd2dqy\t{$src, $dst|$dst, $src}",
2110                 (VCVTTPD2DQYrm VR128:$dst, f256mem:$src), 0>;
2111
2112 let Predicates = [HasAVX, NoVLX] in {
2113   let AddedComplexity = 15 in {
2114     def : Pat<(X86vzmovl (v2i64 (bitconvert
2115                                  (v4i32 (X86cvtp2Int (v2f64 VR128:$src)))))),
2116               (VCVTPD2DQrr VR128:$src)>;
2117     def : Pat<(X86vzmovl (v2i64 (bitconvert
2118                                  (v4i32 (X86cvttp2si (v2f64 VR128:$src)))))),
2119               (VCVTTPD2DQrr VR128:$src)>;
2120   }
2121 } // Predicates = [HasAVX]
2122
2123 def CVTTPD2DQrr : PDI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2124                       "cvttpd2dq\t{$src, $dst|$dst, $src}",
2125                       [(set VR128:$dst,
2126                         (v4i32 (X86cvttp2si (v2f64 VR128:$src))))],
2127                       IIC_SSE_CVT_PD_RR>, Sched<[WriteCvtF2I]>;
2128 def CVTTPD2DQrm : PDI<0xE6, MRMSrcMem, (outs VR128:$dst),(ins f128mem:$src),
2129                       "cvttpd2dq\t{$src, $dst|$dst, $src}",
2130                       [(set VR128:$dst,
2131                         (v4i32 (X86cvttp2si (memopv2f64 addr:$src))))],
2132                       IIC_SSE_CVT_PD_RM>, Sched<[WriteCvtF2ILd]>;
2133
2134 let Predicates = [UseSSE2] in {
2135   let AddedComplexity = 15 in {
2136     def : Pat<(X86vzmovl (v2i64 (bitconvert
2137                                  (v4i32 (X86cvtp2Int (v2f64 VR128:$src)))))),
2138               (CVTPD2DQrr VR128:$src)>;
2139     def : Pat<(X86vzmovl (v2i64 (bitconvert
2140                                  (v4i32 (X86cvttp2si (v2f64 VR128:$src)))))),
2141               (CVTTPD2DQrr VR128:$src)>;
2142   }
2143 } // Predicates = [UseSSE2]
2144
2145 // Convert packed single to packed double
2146 let Predicates = [HasAVX, NoVLX] in {
2147                   // SSE2 instructions without OpSize prefix
2148 def VCVTPS2PDrr : I<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2149                     "vcvtps2pd\t{$src, $dst|$dst, $src}",
2150                     [(set VR128:$dst, (v2f64 (X86vfpext (v4f32 VR128:$src))))],
2151                     IIC_SSE_CVT_PD_RR>, PS, VEX, Sched<[WriteCvtF2F]>, VEX_WIG;
2152 def VCVTPS2PDrm : I<0x5A, MRMSrcMem, (outs VR128:$dst), (ins f64mem:$src),
2153                     "vcvtps2pd\t{$src, $dst|$dst, $src}",
2154                     [(set VR128:$dst, (v2f64 (extloadv2f32 addr:$src)))],
2155                     IIC_SSE_CVT_PD_RM>, PS, VEX, Sched<[WriteCvtF2FLd]>, VEX_WIG;
2156 def VCVTPS2PDYrr : I<0x5A, MRMSrcReg, (outs VR256:$dst), (ins VR128:$src),
2157                      "vcvtps2pd\t{$src, $dst|$dst, $src}",
2158                      [(set VR256:$dst, (v4f64 (fpextend (v4f32 VR128:$src))))],
2159                      IIC_SSE_CVT_PD_RR>, PS, VEX, VEX_L, Sched<[WriteCvtF2F]>, VEX_WIG;
2160 def VCVTPS2PDYrm : I<0x5A, MRMSrcMem, (outs VR256:$dst), (ins f128mem:$src),
2161                      "vcvtps2pd\t{$src, $dst|$dst, $src}",
2162                      [(set VR256:$dst, (v4f64 (extloadv4f32 addr:$src)))],
2163                      IIC_SSE_CVT_PD_RM>, PS, VEX, VEX_L, Sched<[WriteCvtF2FLd]>, VEX_WIG;
2164 }
2165
2166 let Predicates = [UseSSE2] in {
2167 def CVTPS2PDrr : I<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2168                    "cvtps2pd\t{$src, $dst|$dst, $src}",
2169                    [(set VR128:$dst, (v2f64 (X86vfpext (v4f32 VR128:$src))))],
2170                    IIC_SSE_CVT_PD_RR>, PS, Sched<[WriteCvtF2F]>;
2171 def CVTPS2PDrm : I<0x5A, MRMSrcMem, (outs VR128:$dst), (ins f64mem:$src),
2172                    "cvtps2pd\t{$src, $dst|$dst, $src}",
2173                    [(set VR128:$dst, (v2f64 (extloadv2f32 addr:$src)))],
2174                    IIC_SSE_CVT_PD_RM>, PS, Sched<[WriteCvtF2FLd]>;
2175 }
2176
2177 // Convert Packed DW Integers to Packed Double FP
2178 let Predicates = [HasAVX, NoVLX] in {
2179 let hasSideEffects = 0, mayLoad = 1 in
2180 def VCVTDQ2PDrm  : S2SI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
2181                         "vcvtdq2pd\t{$src, $dst|$dst, $src}",
2182                         [(set VR128:$dst,
2183                           (v2f64 (X86VSintToFP (bc_v4i32 (v2i64 (X86vzload addr:$src))))))]>,
2184                         VEX, Sched<[WriteCvtI2FLd]>, VEX_WIG;
2185 def VCVTDQ2PDrr  : S2SI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2186                         "vcvtdq2pd\t{$src, $dst|$dst, $src}",
2187                         [(set VR128:$dst,
2188                           (v2f64 (X86VSintToFP (v4i32 VR128:$src))))]>,
2189                         VEX, Sched<[WriteCvtI2F]>, VEX_WIG;
2190 def VCVTDQ2PDYrm  : S2SI<0xE6, MRMSrcMem, (outs VR256:$dst), (ins i128mem:$src),
2191                          "vcvtdq2pd\t{$src, $dst|$dst, $src}",
2192                          [(set VR256:$dst,
2193                            (v4f64 (sint_to_fp (bc_v4i32 (loadv2i64 addr:$src)))))]>,
2194                          VEX, VEX_L, Sched<[WriteCvtI2FLd]>, VEX_WIG;
2195 def VCVTDQ2PDYrr  : S2SI<0xE6, MRMSrcReg, (outs VR256:$dst), (ins VR128:$src),
2196                          "vcvtdq2pd\t{$src, $dst|$dst, $src}",
2197                          [(set VR256:$dst,
2198                            (v4f64 (sint_to_fp (v4i32 VR128:$src))))]>,
2199                          VEX, VEX_L, Sched<[WriteCvtI2F]>, VEX_WIG;
2200 }
2201
2202 let hasSideEffects = 0, mayLoad = 1 in
2203 def CVTDQ2PDrm  : S2SI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
2204                        "cvtdq2pd\t{$src, $dst|$dst, $src}",
2205                        [(set VR128:$dst,
2206                          (v2f64 (X86VSintToFP (bc_v4i32 (v2i64 (X86vzload addr:$src))))))],
2207                        IIC_SSE_CVT_PD_RR>, Sched<[WriteCvtI2FLd]>;
2208 def CVTDQ2PDrr  : S2SI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2209                        "cvtdq2pd\t{$src, $dst|$dst, $src}",
2210                        [(set VR128:$dst,
2211                          (v2f64 (X86VSintToFP (v4i32 VR128:$src))))],
2212                        IIC_SSE_CVT_PD_RM>, Sched<[WriteCvtI2F]>;
2213
2214 // AVX register conversion intrinsics
2215 let Predicates = [HasAVX, NoVLX] in {
2216   def : Pat<(v2f64 (X86VSintToFP (bc_v4i32 (v2i64 (scalar_to_vector (loadi64 addr:$src)))))),
2217             (VCVTDQ2PDrm addr:$src)>;
2218 } // Predicates = [HasAVX, NoVLX]
2219
2220 // SSE2 register conversion intrinsics
2221 let Predicates = [UseSSE2] in {
2222   def : Pat<(v2f64 (X86VSintToFP (bc_v4i32 (v2i64 (scalar_to_vector (loadi64 addr:$src)))))),
2223             (CVTDQ2PDrm addr:$src)>;
2224 } // Predicates = [UseSSE2]
2225
2226 // Convert packed double to packed single
2227 // The assembler can recognize rr 256-bit instructions by seeing a ymm
2228 // register, but the same isn't true when using memory operands instead.
2229 // Provide other assembly rr and rm forms to address this explicitly.
2230 let Predicates = [HasAVX, NoVLX] in
2231 def VCVTPD2PSrr : VPDI<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2232                        "cvtpd2ps\t{$src, $dst|$dst, $src}",
2233                        [(set VR128:$dst, (X86vfpround (v2f64 VR128:$src)))],
2234                        IIC_SSE_CVT_PD_RR>, VEX, Sched<[WriteCvtF2F]>, VEX_WIG;
2235
2236 // XMM only
2237 def : InstAlias<"vcvtpd2psx\t{$src, $dst|$dst, $src}",
2238                 (VCVTPD2PSrr VR128:$dst, VR128:$src), 0>;
2239 let Predicates = [HasAVX, NoVLX] in
2240 def VCVTPD2PSrm : VPDI<0x5A, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
2241                        "cvtpd2ps{x}\t{$src, $dst|$dst, $src}",
2242                        [(set VR128:$dst, (X86vfpround (loadv2f64 addr:$src)))],
2243                        IIC_SSE_CVT_PD_RM>, VEX, Sched<[WriteCvtF2FLd]>, VEX_WIG;
2244 def : InstAlias<"vcvtpd2psx\t{$src, $dst|$dst, $src}",
2245                 (VCVTPD2PSrm VR128:$dst, f128mem:$src), 0>;
2246
2247 // YMM only
2248 let Predicates = [HasAVX, NoVLX] in {
2249 def VCVTPD2PSYrr : VPDI<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR256:$src),
2250                         "cvtpd2ps\t{$src, $dst|$dst, $src}",
2251                         [(set VR128:$dst, (fpround VR256:$src))],
2252                         IIC_SSE_CVT_PD_RR>, VEX, VEX_L, Sched<[WriteCvtF2F]>, VEX_WIG;
2253 def VCVTPD2PSYrm : VPDI<0x5A, MRMSrcMem, (outs VR128:$dst), (ins f256mem:$src),
2254                         "cvtpd2ps{y}\t{$src, $dst|$dst, $src}",
2255                         [(set VR128:$dst, (fpround (loadv4f64 addr:$src)))],
2256                         IIC_SSE_CVT_PD_RM>, VEX, VEX_L, Sched<[WriteCvtF2FLd]>, VEX_WIG;
2257 }
2258 def : InstAlias<"vcvtpd2psy\t{$src, $dst|$dst, $src}",
2259                 (VCVTPD2PSYrr VR128:$dst, VR256:$src), 0>;
2260 def : InstAlias<"vcvtpd2psy\t{$src, $dst|$dst, $src}",
2261                 (VCVTPD2PSYrm VR128:$dst, f256mem:$src), 0>;
2262
2263 def CVTPD2PSrr : PDI<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2264                      "cvtpd2ps\t{$src, $dst|$dst, $src}",
2265                      [(set VR128:$dst, (X86vfpround (v2f64 VR128:$src)))],
2266                      IIC_SSE_CVT_PD_RR>, Sched<[WriteCvtF2F]>;
2267 def CVTPD2PSrm : PDI<0x5A, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
2268                      "cvtpd2ps\t{$src, $dst|$dst, $src}",
2269                      [(set VR128:$dst, (X86vfpround (memopv2f64 addr:$src)))],
2270                      IIC_SSE_CVT_PD_RM>, Sched<[WriteCvtF2FLd]>;
2271
2272 // AVX 256-bit register conversion intrinsics
2273 // FIXME: Migrate SSE conversion intrinsics matching to use patterns as below
2274 // whenever possible to avoid declaring two versions of each one.
2275
2276 let Predicates = [HasAVX, NoVLX] in {
2277   // Match fpround and fpextend for 128/256-bit conversions
2278   let AddedComplexity = 15 in
2279   def : Pat<(X86vzmovl (v2f64 (bitconvert
2280                                (v4f32 (X86vfpround (v2f64 VR128:$src)))))),
2281             (VCVTPD2PSrr VR128:$src)>;
2282 }
2283
2284 let Predicates = [UseSSE2] in {
2285   // Match fpround and fpextend for 128 conversions
2286   let AddedComplexity = 15 in
2287   def : Pat<(X86vzmovl (v2f64 (bitconvert
2288                                (v4f32 (X86vfpround (v2f64 VR128:$src)))))),
2289             (CVTPD2PSrr VR128:$src)>;
2290 }
2291
2292 //===----------------------------------------------------------------------===//
2293 // SSE 1 & 2 - Compare Instructions
2294 //===----------------------------------------------------------------------===//
2295
2296 // sse12_cmp_scalar - sse 1 & 2 compare scalar instructions
2297 multiclass sse12_cmp_scalar<RegisterClass RC, X86MemOperand x86memop,
2298                             Operand CC, SDNode OpNode, ValueType VT,
2299                             PatFrag ld_frag, string asm, string asm_alt,
2300                             OpndItins itins, ImmLeaf immLeaf> {
2301   let isCommutable = 1 in
2302   def rr : SIi8<0xC2, MRMSrcReg,
2303                 (outs RC:$dst), (ins RC:$src1, RC:$src2, CC:$cc), asm,
2304                 [(set RC:$dst, (OpNode (VT RC:$src1), RC:$src2, immLeaf:$cc))],
2305                 itins.rr>, Sched<[itins.Sched]>;
2306   def rm : SIi8<0xC2, MRMSrcMem,
2307                 (outs RC:$dst), (ins RC:$src1, x86memop:$src2, CC:$cc), asm,
2308                 [(set RC:$dst, (OpNode (VT RC:$src1),
2309                                          (ld_frag addr:$src2), immLeaf:$cc))],
2310                                          itins.rm>,
2311            Sched<[itins.Sched.Folded, ReadAfterLd]>;
2312
2313   // Accept explicit immediate argument form instead of comparison code.
2314   let isAsmParserOnly = 1, hasSideEffects = 0 in {
2315     def rr_alt : SIi8<0xC2, MRMSrcReg, (outs RC:$dst),
2316                       (ins RC:$src1, RC:$src2, u8imm:$cc), asm_alt, [],
2317                       IIC_SSE_ALU_F32S_RR>, Sched<[itins.Sched]>;
2318     let mayLoad = 1 in
2319     def rm_alt : SIi8<0xC2, MRMSrcMem, (outs RC:$dst),
2320                       (ins RC:$src1, x86memop:$src2, u8imm:$cc), asm_alt, [],
2321                       IIC_SSE_ALU_F32S_RM>,
2322                       Sched<[itins.Sched.Folded, ReadAfterLd]>;
2323   }
2324 }
2325
2326 let ExeDomain = SSEPackedSingle in
2327 defm VCMPSS : sse12_cmp_scalar<FR32, f32mem, AVXCC, X86cmps, f32, loadf32,
2328                  "cmp${cc}ss\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2329                  "cmpss\t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}",
2330                  SSE_ALU_F32S, i8immZExt5>, XS, VEX_4V, VEX_LIG, VEX_WIG;
2331 let ExeDomain = SSEPackedDouble in
2332 defm VCMPSD : sse12_cmp_scalar<FR64, f64mem, AVXCC, X86cmps, f64, loadf64,
2333                  "cmp${cc}sd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2334                  "cmpsd\t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}",
2335                  SSE_ALU_F32S, i8immZExt5>, // same latency as 32 bit compare
2336                  XD, VEX_4V, VEX_LIG, VEX_WIG;
2337
2338 let Constraints = "$src1 = $dst" in {
2339   let ExeDomain = SSEPackedSingle in
2340   defm CMPSS : sse12_cmp_scalar<FR32, f32mem, SSECC, X86cmps, f32, loadf32,
2341                   "cmp${cc}ss\t{$src2, $dst|$dst, $src2}",
2342                   "cmpss\t{$cc, $src2, $dst|$dst, $src2, $cc}", SSE_ALU_F32S,
2343                   i8immZExt3>, XS;
2344   let ExeDomain = SSEPackedDouble in
2345   defm CMPSD : sse12_cmp_scalar<FR64, f64mem, SSECC, X86cmps, f64, loadf64,
2346                   "cmp${cc}sd\t{$src2, $dst|$dst, $src2}",
2347                   "cmpsd\t{$cc, $src2, $dst|$dst, $src2, $cc}",
2348                   SSE_ALU_F64S, i8immZExt3>, XD;
2349 }
2350
2351 multiclass sse12_cmp_scalar_int<Operand memop, Operand CC,
2352                          Intrinsic Int, string asm, OpndItins itins,
2353                          ImmLeaf immLeaf, ComplexPattern mem_cpat> {
2354   def rr : SIi8<0xC2, MRMSrcReg, (outs VR128:$dst),
2355                       (ins VR128:$src1, VR128:$src, CC:$cc), asm,
2356                         [(set VR128:$dst, (Int VR128:$src1,
2357                                                VR128:$src, immLeaf:$cc))],
2358                                                itins.rr>,
2359            Sched<[itins.Sched]>;
2360 let mayLoad = 1 in
2361   def rm : SIi8<0xC2, MRMSrcMem, (outs VR128:$dst),
2362                       (ins VR128:$src1, memop:$src, CC:$cc), asm,
2363                         [(set VR128:$dst, (Int VR128:$src1,
2364                                                mem_cpat:$src, immLeaf:$cc))],
2365                                                itins.rm>,
2366            Sched<[itins.Sched.Folded, ReadAfterLd]>;
2367 }
2368
2369 let isCodeGenOnly = 1 in {
2370   // Aliases to match intrinsics which expect XMM operand(s).
2371   let ExeDomain = SSEPackedSingle in
2372   defm Int_VCMPSS  : sse12_cmp_scalar_int<ssmem, AVXCC, int_x86_sse_cmp_ss,
2373                        "cmp${cc}ss\t{$src, $src1, $dst|$dst, $src1, $src}",
2374                        SSE_ALU_F32S, i8immZExt5, sse_load_f32>,
2375                        XS, VEX_4V;
2376   let ExeDomain = SSEPackedDouble in
2377   defm Int_VCMPSD  : sse12_cmp_scalar_int<sdmem, AVXCC, int_x86_sse2_cmp_sd,
2378                        "cmp${cc}sd\t{$src, $src1, $dst|$dst, $src1, $src}",
2379                        SSE_ALU_F32S, i8immZExt5, sse_load_f64>, // same latency as f32
2380                        XD, VEX_4V;
2381   let Constraints = "$src1 = $dst" in {
2382     let ExeDomain = SSEPackedSingle in
2383     defm Int_CMPSS  : sse12_cmp_scalar_int<ssmem, SSECC, int_x86_sse_cmp_ss,
2384                          "cmp${cc}ss\t{$src, $dst|$dst, $src}",
2385                          SSE_ALU_F32S, i8immZExt3, sse_load_f32>, XS;
2386     let ExeDomain = SSEPackedDouble in
2387     defm Int_CMPSD  : sse12_cmp_scalar_int<sdmem, SSECC, int_x86_sse2_cmp_sd,
2388                          "cmp${cc}sd\t{$src, $dst|$dst, $src}",
2389                          SSE_ALU_F64S, i8immZExt3, sse_load_f64>,
2390                          XD;
2391 }
2392 }
2393
2394
2395 // sse12_ord_cmp - Unordered/Ordered scalar fp compare and set EFLAGS
2396 multiclass sse12_ord_cmp<bits<8> opc, RegisterClass RC, SDNode OpNode,
2397                             ValueType vt, X86MemOperand x86memop,
2398                             PatFrag ld_frag, string OpcodeStr> {
2399   def rr: SI<opc, MRMSrcReg, (outs), (ins RC:$src1, RC:$src2),
2400                      !strconcat(OpcodeStr, "\t{$src2, $src1|$src1, $src2}"),
2401                      [(set EFLAGS, (OpNode (vt RC:$src1), RC:$src2))],
2402                      IIC_SSE_COMIS_RR>,
2403           Sched<[WriteFAdd]>;
2404 let mayLoad = 1 in
2405   def rm: SI<opc, MRMSrcMem, (outs), (ins RC:$src1, x86memop:$src2),
2406                      !strconcat(OpcodeStr, "\t{$src2, $src1|$src1, $src2}"),
2407                      [(set EFLAGS, (OpNode (vt RC:$src1),
2408                                            (ld_frag addr:$src2)))],
2409                                            IIC_SSE_COMIS_RM>,
2410           Sched<[WriteFAddLd, ReadAfterLd]>;
2411 }
2412
2413 // sse12_ord_cmp_int - Intrinsic version of sse12_ord_cmp
2414 multiclass sse12_ord_cmp_int<bits<8> opc, RegisterClass RC, SDNode OpNode,
2415                             ValueType vt, Operand memop,
2416                             ComplexPattern mem_cpat, string OpcodeStr> {
2417   def rr: SI<opc, MRMSrcReg, (outs), (ins RC:$src1, RC:$src2),
2418                      !strconcat(OpcodeStr, "\t{$src2, $src1|$src1, $src2}"),
2419                      [(set EFLAGS, (OpNode (vt RC:$src1), RC:$src2))],
2420                      IIC_SSE_COMIS_RR>,
2421           Sched<[WriteFAdd]>;
2422 let mayLoad = 1 in
2423   def rm: SI<opc, MRMSrcMem, (outs), (ins RC:$src1, memop:$src2),
2424                      !strconcat(OpcodeStr, "\t{$src2, $src1|$src1, $src2}"),
2425                      [(set EFLAGS, (OpNode (vt RC:$src1),
2426                                            mem_cpat:$src2))],
2427                                            IIC_SSE_COMIS_RM>,
2428           Sched<[WriteFAddLd, ReadAfterLd]>;
2429 }
2430
2431 let Defs = [EFLAGS] in {
2432   defm VUCOMISS : sse12_ord_cmp<0x2E, FR32, X86cmp, f32, f32mem, loadf32,
2433                                   "ucomiss">, PS, VEX, VEX_LIG, VEX_WIG;
2434   defm VUCOMISD : sse12_ord_cmp<0x2E, FR64, X86cmp, f64, f64mem, loadf64,
2435                                   "ucomisd">, PD, VEX, VEX_LIG, VEX_WIG;
2436   let Pattern = []<dag> in {
2437     defm VCOMISS  : sse12_ord_cmp<0x2F, FR32, undef, f32, f32mem, loadf32,
2438                                     "comiss">, PS, VEX, VEX_LIG, VEX_WIG;
2439     defm VCOMISD  : sse12_ord_cmp<0x2F, FR64, undef, f64, f64mem, loadf64,
2440                                     "comisd">, PD, VEX, VEX_LIG, VEX_WIG;
2441   }
2442
2443   let isCodeGenOnly = 1 in {
2444     defm Int_VUCOMISS  : sse12_ord_cmp_int<0x2E, VR128, X86ucomi, v4f32, ssmem,
2445                               sse_load_f32, "ucomiss">, PS, VEX, VEX_WIG;
2446     defm Int_VUCOMISD  : sse12_ord_cmp_int<0x2E, VR128, X86ucomi, v2f64, sdmem,
2447                               sse_load_f64, "ucomisd">, PD, VEX, VEX_WIG;
2448
2449     defm Int_VCOMISS  : sse12_ord_cmp_int<0x2F, VR128, X86comi, v4f32, ssmem,
2450                               sse_load_f32, "comiss">, PS, VEX, VEX_WIG;
2451     defm Int_VCOMISD  : sse12_ord_cmp_int<0x2F, VR128, X86comi, v2f64, sdmem,
2452                               sse_load_f64, "comisd">, PD, VEX, VEX_WIG;
2453   }
2454   defm UCOMISS  : sse12_ord_cmp<0x2E, FR32, X86cmp, f32, f32mem, loadf32,
2455                                   "ucomiss">, PS;
2456   defm UCOMISD  : sse12_ord_cmp<0x2E, FR64, X86cmp, f64, f64mem, loadf64,
2457                                   "ucomisd">, PD;
2458
2459   let Pattern = []<dag> in {
2460     defm COMISS  : sse12_ord_cmp<0x2F, FR32, undef, f32, f32mem, loadf32,
2461                                     "comiss">, PS;
2462     defm COMISD  : sse12_ord_cmp<0x2F, FR64, undef, f64, f64mem, loadf64,
2463                                     "comisd">, PD;
2464   }
2465
2466   let isCodeGenOnly = 1 in {
2467     defm Int_UCOMISS  : sse12_ord_cmp_int<0x2E, VR128, X86ucomi, v4f32, ssmem,
2468                                 sse_load_f32, "ucomiss">, PS;
2469     defm Int_UCOMISD  : sse12_ord_cmp_int<0x2E, VR128, X86ucomi, v2f64, sdmem,
2470                                 sse_load_f64, "ucomisd">, PD;
2471
2472     defm Int_COMISS  : sse12_ord_cmp_int<0x2F, VR128, X86comi, v4f32, ssmem,
2473                                     sse_load_f32, "comiss">, PS;
2474     defm Int_COMISD  : sse12_ord_cmp_int<0x2F, VR128, X86comi, v2f64, sdmem,
2475                                     sse_load_f64, "comisd">, PD;
2476   }
2477 } // Defs = [EFLAGS]
2478
2479 // sse12_cmp_packed - sse 1 & 2 compare packed instructions
2480 multiclass sse12_cmp_packed<RegisterClass RC, X86MemOperand x86memop,
2481                             Operand CC,  ValueType VT, string asm,
2482                             string asm_alt, Domain d, ImmLeaf immLeaf,
2483                             PatFrag ld_frag, OpndItins itins = SSE_ALU_F32P> {
2484   let isCommutable = 1 in
2485   def rri : PIi8<0xC2, MRMSrcReg,
2486              (outs RC:$dst), (ins RC:$src1, RC:$src2, CC:$cc), asm,
2487              [(set RC:$dst, (VT (X86cmpp RC:$src1, RC:$src2, immLeaf:$cc)))],
2488              itins.rr, d>,
2489             Sched<[WriteFAdd]>;
2490   def rmi : PIi8<0xC2, MRMSrcMem,
2491              (outs RC:$dst), (ins RC:$src1, x86memop:$src2, CC:$cc), asm,
2492              [(set RC:$dst,
2493                (VT (X86cmpp RC:$src1, (ld_frag addr:$src2), immLeaf:$cc)))],
2494              itins.rm, d>,
2495             Sched<[WriteFAddLd, ReadAfterLd]>;
2496
2497   // Accept explicit immediate argument form instead of comparison code.
2498   let isAsmParserOnly = 1, hasSideEffects = 0 in {
2499     def rri_alt : PIi8<0xC2, MRMSrcReg,
2500                (outs RC:$dst), (ins RC:$src1, RC:$src2, u8imm:$cc),
2501                asm_alt, [], itins.rr, d>, Sched<[WriteFAdd]>;
2502     let mayLoad = 1 in
2503     def rmi_alt : PIi8<0xC2, MRMSrcMem,
2504                (outs RC:$dst), (ins RC:$src1, x86memop:$src2, u8imm:$cc),
2505                asm_alt, [], itins.rm, d>,
2506                Sched<[WriteFAddLd, ReadAfterLd]>;
2507   }
2508 }
2509
2510 defm VCMPPS : sse12_cmp_packed<VR128, f128mem, AVXCC, v4f32,
2511                "cmp${cc}ps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2512                "cmpps\t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}",
2513                SSEPackedSingle, i8immZExt5, loadv4f32>, PS, VEX_4V, VEX_WIG;
2514 defm VCMPPD : sse12_cmp_packed<VR128, f128mem, AVXCC, v2f64,
2515                "cmp${cc}pd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2516                "cmppd\t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}",
2517                SSEPackedDouble, i8immZExt5, loadv2f64>, PD, VEX_4V, VEX_WIG;
2518 defm VCMPPSY : sse12_cmp_packed<VR256, f256mem, AVXCC, v8f32,
2519                "cmp${cc}ps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2520                "cmpps\t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}",
2521                SSEPackedSingle, i8immZExt5, loadv8f32>, PS, VEX_4V, VEX_L;
2522 defm VCMPPDY : sse12_cmp_packed<VR256, f256mem, AVXCC, v4f64,
2523                "cmp${cc}pd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2524                "cmppd\t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}",
2525                SSEPackedDouble, i8immZExt5, loadv4f64>, PD, VEX_4V, VEX_L;
2526 let Constraints = "$src1 = $dst" in {
2527   defm CMPPS : sse12_cmp_packed<VR128, f128mem, SSECC, v4f32,
2528                  "cmp${cc}ps\t{$src2, $dst|$dst, $src2}",
2529                  "cmpps\t{$cc, $src2, $dst|$dst, $src2, $cc}",
2530                  SSEPackedSingle, i8immZExt5, memopv4f32, SSE_ALU_F32P>, PS;
2531   defm CMPPD : sse12_cmp_packed<VR128, f128mem, SSECC, v2f64,
2532                  "cmp${cc}pd\t{$src2, $dst|$dst, $src2}",
2533                  "cmppd\t{$cc, $src2, $dst|$dst, $src2, $cc}",
2534                  SSEPackedDouble, i8immZExt5, memopv2f64, SSE_ALU_F64P>, PD;
2535 }
2536
2537 //===----------------------------------------------------------------------===//
2538 // SSE 1 & 2 - Shuffle Instructions
2539 //===----------------------------------------------------------------------===//
2540
2541 /// sse12_shuffle - sse 1 & 2 fp shuffle instructions
2542 multiclass sse12_shuffle<RegisterClass RC, X86MemOperand x86memop,
2543                          ValueType vt, string asm, PatFrag mem_frag,
2544                          Domain d> {
2545   def rmi : PIi8<0xC6, MRMSrcMem, (outs RC:$dst),
2546                    (ins RC:$src1, x86memop:$src2, u8imm:$src3), asm,
2547                    [(set RC:$dst, (vt (X86Shufp RC:$src1, (mem_frag addr:$src2),
2548                                        (i8 imm:$src3))))], IIC_SSE_SHUFP, d>,
2549             Sched<[WriteFShuffleLd, ReadAfterLd]>;
2550   def rri : PIi8<0xC6, MRMSrcReg, (outs RC:$dst),
2551                  (ins RC:$src1, RC:$src2, u8imm:$src3), asm,
2552                  [(set RC:$dst, (vt (X86Shufp RC:$src1, RC:$src2,
2553                                      (i8 imm:$src3))))], IIC_SSE_SHUFP, d>,
2554             Sched<[WriteFShuffle]>;
2555 }
2556
2557 let Predicates = [HasAVX, NoVLX] in {
2558   defm VSHUFPS  : sse12_shuffle<VR128, f128mem, v4f32,
2559            "shufps\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
2560            loadv4f32, SSEPackedSingle>, PS, VEX_4V, VEX_WIG;
2561   defm VSHUFPSY : sse12_shuffle<VR256, f256mem, v8f32,
2562            "shufps\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
2563            loadv8f32, SSEPackedSingle>, PS, VEX_4V, VEX_L, VEX_WIG;
2564   defm VSHUFPD  : sse12_shuffle<VR128, f128mem, v2f64,
2565            "shufpd\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
2566            loadv2f64, SSEPackedDouble>, PD, VEX_4V, VEX_WIG;
2567   defm VSHUFPDY : sse12_shuffle<VR256, f256mem, v4f64,
2568            "shufpd\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
2569            loadv4f64, SSEPackedDouble>, PD, VEX_4V, VEX_L, VEX_WIG;
2570 }
2571 let Constraints = "$src1 = $dst" in {
2572   defm SHUFPS : sse12_shuffle<VR128, f128mem, v4f32,
2573                     "shufps\t{$src3, $src2, $dst|$dst, $src2, $src3}",
2574                     memopv4f32, SSEPackedSingle>, PS;
2575   defm SHUFPD : sse12_shuffle<VR128, f128mem, v2f64,
2576                     "shufpd\t{$src3, $src2, $dst|$dst, $src2, $src3}",
2577                     memopv2f64, SSEPackedDouble>, PD;
2578 }
2579
2580 let Predicates = [HasAVX, NoVLX] in {
2581   def : Pat<(v4i32 (X86Shufp VR128:$src1,
2582                        (bc_v4i32 (loadv2i64 addr:$src2)), (i8 imm:$imm))),
2583             (VSHUFPSrmi VR128:$src1, addr:$src2, imm:$imm)>;
2584   def : Pat<(v4i32 (X86Shufp VR128:$src1, VR128:$src2, (i8 imm:$imm))),
2585             (VSHUFPSrri VR128:$src1, VR128:$src2, imm:$imm)>;
2586
2587   def : Pat<(v2i64 (X86Shufp VR128:$src1,
2588                        (loadv2i64 addr:$src2), (i8 imm:$imm))),
2589             (VSHUFPDrmi VR128:$src1, addr:$src2, imm:$imm)>;
2590   def : Pat<(v2i64 (X86Shufp VR128:$src1, VR128:$src2, (i8 imm:$imm))),
2591             (VSHUFPDrri VR128:$src1, VR128:$src2, imm:$imm)>;
2592
2593   // 256-bit patterns
2594   def : Pat<(v8i32 (X86Shufp VR256:$src1, VR256:$src2, (i8 imm:$imm))),
2595             (VSHUFPSYrri VR256:$src1, VR256:$src2, imm:$imm)>;
2596   def : Pat<(v8i32 (X86Shufp VR256:$src1,
2597                       (bc_v8i32 (loadv4i64 addr:$src2)), (i8 imm:$imm))),
2598             (VSHUFPSYrmi VR256:$src1, addr:$src2, imm:$imm)>;
2599
2600   def : Pat<(v4i64 (X86Shufp VR256:$src1, VR256:$src2, (i8 imm:$imm))),
2601             (VSHUFPDYrri VR256:$src1, VR256:$src2, imm:$imm)>;
2602   def : Pat<(v4i64 (X86Shufp VR256:$src1,
2603                               (loadv4i64 addr:$src2), (i8 imm:$imm))),
2604             (VSHUFPDYrmi VR256:$src1, addr:$src2, imm:$imm)>;
2605 }
2606
2607 let Predicates = [UseSSE1] in {
2608   def : Pat<(v4i32 (X86Shufp VR128:$src1,
2609                        (bc_v4i32 (memopv2i64 addr:$src2)), (i8 imm:$imm))),
2610             (SHUFPSrmi VR128:$src1, addr:$src2, imm:$imm)>;
2611   def : Pat<(v4i32 (X86Shufp VR128:$src1, VR128:$src2, (i8 imm:$imm))),
2612             (SHUFPSrri VR128:$src1, VR128:$src2, imm:$imm)>;
2613 }
2614
2615 let Predicates = [UseSSE2] in {
2616   // Generic SHUFPD patterns
2617   def : Pat<(v2i64 (X86Shufp VR128:$src1,
2618                        (memopv2i64 addr:$src2), (i8 imm:$imm))),
2619             (SHUFPDrmi VR128:$src1, addr:$src2, imm:$imm)>;
2620   def : Pat<(v2i64 (X86Shufp VR128:$src1, VR128:$src2, (i8 imm:$imm))),
2621             (SHUFPDrri VR128:$src1, VR128:$src2, imm:$imm)>;
2622 }
2623
2624 //===----------------------------------------------------------------------===//
2625 // SSE 1 & 2 - Unpack FP Instructions
2626 //===----------------------------------------------------------------------===//
2627
2628 /// sse12_unpack_interleave - sse 1 & 2 fp unpack and interleave
2629 multiclass sse12_unpack_interleave<bits<8> opc, SDNode OpNode, ValueType vt,
2630                                    PatFrag mem_frag, RegisterClass RC,
2631                                    X86MemOperand x86memop, string asm,
2632                                    Domain d, bit IsCommutable = 0> {
2633     let isCommutable = IsCommutable in
2634     def rr : PI<opc, MRMSrcReg,
2635                 (outs RC:$dst), (ins RC:$src1, RC:$src2),
2636                 asm, [(set RC:$dst,
2637                            (vt (OpNode RC:$src1, RC:$src2)))],
2638                            IIC_SSE_UNPCK, d>, Sched<[WriteFShuffle]>;
2639     def rm : PI<opc, MRMSrcMem,
2640                 (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
2641                 asm, [(set RC:$dst,
2642                            (vt (OpNode RC:$src1,
2643                                        (mem_frag addr:$src2))))],
2644                                        IIC_SSE_UNPCK, d>,
2645              Sched<[WriteFShuffleLd, ReadAfterLd]>;
2646 }
2647
2648 let Predicates = [HasAVX, NoVLX] in {
2649 defm VUNPCKHPS: sse12_unpack_interleave<0x15, X86Unpckh, v4f32, loadv4f32,
2650       VR128, f128mem, "unpckhps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2651                      SSEPackedSingle>, PS, VEX_4V, VEX_WIG;
2652 defm VUNPCKHPD: sse12_unpack_interleave<0x15, X86Unpckh, v2f64, loadv2f64,
2653       VR128, f128mem, "unpckhpd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2654                      SSEPackedDouble>, PD, VEX_4V, VEX_WIG;
2655 defm VUNPCKLPS: sse12_unpack_interleave<0x14, X86Unpckl, v4f32, loadv4f32,
2656       VR128, f128mem, "unpcklps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2657                      SSEPackedSingle>, PS, VEX_4V, VEX_WIG;
2658 defm VUNPCKLPD: sse12_unpack_interleave<0x14, X86Unpckl, v2f64, loadv2f64,
2659       VR128, f128mem, "unpcklpd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2660                      SSEPackedDouble>, PD, VEX_4V, VEX_WIG;
2661
2662 defm VUNPCKHPSY: sse12_unpack_interleave<0x15, X86Unpckh, v8f32, loadv8f32,
2663       VR256, f256mem, "unpckhps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2664                      SSEPackedSingle>, PS, VEX_4V, VEX_L, VEX_WIG;
2665 defm VUNPCKHPDY: sse12_unpack_interleave<0x15, X86Unpckh, v4f64, loadv4f64,
2666       VR256, f256mem, "unpckhpd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2667                      SSEPackedDouble>, PD, VEX_4V, VEX_L, VEX_WIG;
2668 defm VUNPCKLPSY: sse12_unpack_interleave<0x14, X86Unpckl, v8f32, loadv8f32,
2669       VR256, f256mem, "unpcklps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2670                      SSEPackedSingle>, PS, VEX_4V, VEX_L, VEX_WIG;
2671 defm VUNPCKLPDY: sse12_unpack_interleave<0x14, X86Unpckl, v4f64, loadv4f64,
2672       VR256, f256mem, "unpcklpd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2673                      SSEPackedDouble>, PD, VEX_4V, VEX_L, VEX_WIG;
2674 }// Predicates = [HasAVX, NoVLX]
2675 let Constraints = "$src1 = $dst" in {
2676   defm UNPCKHPS: sse12_unpack_interleave<0x15, X86Unpckh, v4f32, memopv4f32,
2677         VR128, f128mem, "unpckhps\t{$src2, $dst|$dst, $src2}",
2678                        SSEPackedSingle>, PS;
2679   defm UNPCKHPD: sse12_unpack_interleave<0x15, X86Unpckh, v2f64, memopv2f64,
2680         VR128, f128mem, "unpckhpd\t{$src2, $dst|$dst, $src2}",
2681                        SSEPackedDouble, 1>, PD;
2682   defm UNPCKLPS: sse12_unpack_interleave<0x14, X86Unpckl, v4f32, memopv4f32,
2683         VR128, f128mem, "unpcklps\t{$src2, $dst|$dst, $src2}",
2684                        SSEPackedSingle>, PS;
2685   defm UNPCKLPD: sse12_unpack_interleave<0x14, X86Unpckl, v2f64, memopv2f64,
2686         VR128, f128mem, "unpcklpd\t{$src2, $dst|$dst, $src2}",
2687                        SSEPackedDouble>, PD;
2688 } // Constraints = "$src1 = $dst"
2689
2690 let Predicates = [HasAVX1Only] in {
2691   def : Pat<(v8i32 (X86Unpckl VR256:$src1, (bc_v8i32 (loadv4i64 addr:$src2)))),
2692             (VUNPCKLPSYrm VR256:$src1, addr:$src2)>;
2693   def : Pat<(v8i32 (X86Unpckl VR256:$src1, VR256:$src2)),
2694             (VUNPCKLPSYrr VR256:$src1, VR256:$src2)>;
2695   def : Pat<(v8i32 (X86Unpckh VR256:$src1, (bc_v8i32 (loadv4i64 addr:$src2)))),
2696             (VUNPCKHPSYrm VR256:$src1, addr:$src2)>;
2697   def : Pat<(v8i32 (X86Unpckh VR256:$src1, VR256:$src2)),
2698             (VUNPCKHPSYrr VR256:$src1, VR256:$src2)>;
2699
2700   def : Pat<(v4i64 (X86Unpckl VR256:$src1, (loadv4i64 addr:$src2))),
2701             (VUNPCKLPDYrm VR256:$src1, addr:$src2)>;
2702   def : Pat<(v4i64 (X86Unpckl VR256:$src1, VR256:$src2)),
2703             (VUNPCKLPDYrr VR256:$src1, VR256:$src2)>;
2704   def : Pat<(v4i64 (X86Unpckh VR256:$src1, (loadv4i64 addr:$src2))),
2705             (VUNPCKHPDYrm VR256:$src1, addr:$src2)>;
2706   def : Pat<(v4i64 (X86Unpckh VR256:$src1, VR256:$src2)),
2707             (VUNPCKHPDYrr VR256:$src1, VR256:$src2)>;
2708 }
2709
2710 //===----------------------------------------------------------------------===//
2711 // SSE 1 & 2 - Extract Floating-Point Sign mask
2712 //===----------------------------------------------------------------------===//
2713
2714 /// sse12_extr_sign_mask - sse 1 & 2 unpack and interleave
2715 multiclass sse12_extr_sign_mask<RegisterClass RC, ValueType vt,
2716                                 string asm, Domain d> {
2717   def rr : PI<0x50, MRMSrcReg, (outs GR32orGR64:$dst), (ins RC:$src),
2718               !strconcat(asm, "\t{$src, $dst|$dst, $src}"),
2719               [(set GR32orGR64:$dst, (X86movmsk (vt RC:$src)))], IIC_SSE_MOVMSK, d>,
2720               Sched<[WriteVecLogic]>;
2721 }
2722
2723 let Predicates = [HasAVX] in {
2724   defm VMOVMSKPS : sse12_extr_sign_mask<VR128, v4f32, "movmskps",
2725                                         SSEPackedSingle>, PS, VEX, VEX_WIG;
2726   defm VMOVMSKPD : sse12_extr_sign_mask<VR128, v2f64, "movmskpd",
2727                                         SSEPackedDouble>, PD, VEX, VEX_WIG;
2728   defm VMOVMSKPSY : sse12_extr_sign_mask<VR256, v8f32, "movmskps",
2729                                          SSEPackedSingle>, PS, VEX, VEX_L, VEX_WIG;
2730   defm VMOVMSKPDY : sse12_extr_sign_mask<VR256, v4f64, "movmskpd",
2731                                          SSEPackedDouble>, PD, VEX, VEX_L, VEX_WIG;
2732 }
2733
2734 defm MOVMSKPS : sse12_extr_sign_mask<VR128, v4f32, "movmskps",
2735                                      SSEPackedSingle>, PS;
2736 defm MOVMSKPD : sse12_extr_sign_mask<VR128, v2f64, "movmskpd",
2737                                      SSEPackedDouble>, PD;
2738
2739 //===---------------------------------------------------------------------===//
2740 // SSE2 - Packed Integer Logical Instructions
2741 //===---------------------------------------------------------------------===//
2742
2743 let ExeDomain = SSEPackedInt in { // SSE integer instructions
2744
2745 /// PDI_binop_rm - Simple SSE2 binary operator.
2746 multiclass PDI_binop_rm<bits<8> opc, string OpcodeStr, SDNode OpNode,
2747                         ValueType OpVT, RegisterClass RC, PatFrag memop_frag,
2748                         X86MemOperand x86memop, OpndItins itins,
2749                         bit IsCommutable, bit Is2Addr> {
2750   let isCommutable = IsCommutable in
2751   def rr : PDI<opc, MRMSrcReg, (outs RC:$dst),
2752        (ins RC:$src1, RC:$src2),
2753        !if(Is2Addr,
2754            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
2755            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
2756        [(set RC:$dst, (OpVT (OpNode RC:$src1, RC:$src2)))], itins.rr>,
2757        Sched<[itins.Sched]>;
2758   def rm : PDI<opc, MRMSrcMem, (outs RC:$dst),
2759        (ins RC:$src1, x86memop:$src2),
2760        !if(Is2Addr,
2761            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
2762            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
2763        [(set RC:$dst, (OpVT (OpNode RC:$src1,
2764                                      (bitconvert (memop_frag addr:$src2)))))],
2765                                      itins.rm>,
2766        Sched<[itins.Sched.Folded, ReadAfterLd]>;
2767 }
2768 } // ExeDomain = SSEPackedInt
2769
2770 multiclass PDI_binop_all<bits<8> opc, string OpcodeStr, SDNode Opcode,
2771                          ValueType OpVT128, ValueType OpVT256,
2772                          OpndItins itins, bit IsCommutable = 0, Predicate prd> {
2773 let Predicates = [HasAVX, prd] in
2774   defm V#NAME : PDI_binop_rm<opc, !strconcat("v", OpcodeStr), Opcode, OpVT128,
2775                     VR128, loadv2i64, i128mem, itins, IsCommutable, 0>, VEX_4V, VEX_WIG;
2776
2777 let Constraints = "$src1 = $dst" in
2778   defm NAME : PDI_binop_rm<opc, OpcodeStr, Opcode, OpVT128, VR128,
2779                            memopv2i64, i128mem, itins, IsCommutable, 1>;
2780
2781 let Predicates = [HasAVX2, prd] in
2782   defm V#NAME#Y : PDI_binop_rm<opc, !strconcat("v", OpcodeStr), Opcode,
2783                                OpVT256, VR256, loadv4i64, i256mem, itins,
2784                                IsCommutable, 0>, VEX_4V, VEX_L, VEX_WIG;
2785 }
2786
2787 // These are ordered here for pattern ordering requirements with the fp versions
2788
2789 defm PAND  : PDI_binop_all<0xDB, "pand", and, v2i64, v4i64,
2790                            SSE_VEC_BIT_ITINS_P, 1, NoVLX>;
2791 defm POR   : PDI_binop_all<0xEB, "por", or, v2i64, v4i64,
2792                            SSE_VEC_BIT_ITINS_P, 1, NoVLX>;
2793 defm PXOR  : PDI_binop_all<0xEF, "pxor", xor, v2i64, v4i64,
2794                            SSE_VEC_BIT_ITINS_P, 1, NoVLX>;
2795 defm PANDN : PDI_binop_all<0xDF, "pandn", X86andnp, v2i64, v4i64,
2796                            SSE_VEC_BIT_ITINS_P, 0, NoVLX>;
2797
2798 //===----------------------------------------------------------------------===//
2799 // SSE 1 & 2 - Logical Instructions
2800 //===----------------------------------------------------------------------===//
2801
2802 /// sse12_fp_packed_logical - SSE 1 & 2 packed FP logical ops
2803 ///
2804 multiclass sse12_fp_packed_logical<bits<8> opc, string OpcodeStr,
2805                                    SDNode OpNode> {
2806   let Predicates = [HasAVX, NoVLX] in {
2807   defm V#NAME#PSY : sse12_fp_packed_logical_rm<opc, VR256, SSEPackedSingle,
2808         !strconcat(OpcodeStr, "ps"), f256mem,
2809         [(set VR256:$dst, (OpNode (bc_v4i64 (v8f32 VR256:$src1)),
2810                                   (bc_v4i64 (v8f32 VR256:$src2))))],
2811         [(set VR256:$dst, (OpNode (bc_v4i64 (v8f32 VR256:$src1)),
2812                            (loadv4i64 addr:$src2)))], 0>, PS, VEX_4V, VEX_L, VEX_WIG;
2813
2814   defm V#NAME#PDY : sse12_fp_packed_logical_rm<opc, VR256, SSEPackedDouble,
2815         !strconcat(OpcodeStr, "pd"), f256mem,
2816         [(set VR256:$dst, (OpNode (bc_v4i64 (v4f64 VR256:$src1)),
2817                                   (bc_v4i64 (v4f64 VR256:$src2))))],
2818         [(set VR256:$dst, (OpNode (bc_v4i64 (v4f64 VR256:$src1)),
2819                                   (loadv4i64 addr:$src2)))], 0>,
2820                                   PD, VEX_4V, VEX_L, VEX_WIG;
2821
2822   defm V#NAME#PS : sse12_fp_packed_logical_rm<opc, VR128, SSEPackedSingle,
2823        !strconcat(OpcodeStr, "ps"), f128mem,
2824        [(set VR128:$dst, (OpNode (bc_v2i64 (v4f32 VR128:$src1)),
2825                                  (bc_v2i64 (v4f32 VR128:$src2))))],
2826        [(set VR128:$dst, (OpNode (bc_v2i64 (v4f32 VR128:$src1)),
2827                                  (loadv2i64 addr:$src2)))], 0>, PS, VEX_4V, VEX_WIG;
2828
2829   defm V#NAME#PD : sse12_fp_packed_logical_rm<opc, VR128, SSEPackedDouble,
2830        !strconcat(OpcodeStr, "pd"), f128mem,
2831        [(set VR128:$dst, (OpNode (bc_v2i64 (v2f64 VR128:$src1)),
2832                                  (bc_v2i64 (v2f64 VR128:$src2))))],
2833        [(set VR128:$dst, (OpNode (bc_v2i64 (v2f64 VR128:$src1)),
2834                                  (loadv2i64 addr:$src2)))], 0>,
2835                                                  PD, VEX_4V, VEX_WIG;
2836   }
2837
2838   let Constraints = "$src1 = $dst" in {
2839     defm PS : sse12_fp_packed_logical_rm<opc, VR128, SSEPackedSingle,
2840          !strconcat(OpcodeStr, "ps"), f128mem,
2841          [(set VR128:$dst, (OpNode (bc_v2i64 (v4f32 VR128:$src1)),
2842                                    (bc_v2i64 (v4f32 VR128:$src2))))],
2843          [(set VR128:$dst, (OpNode (bc_v2i64 (v4f32 VR128:$src1)),
2844                                    (memopv2i64 addr:$src2)))]>, PS;
2845
2846     defm PD : sse12_fp_packed_logical_rm<opc, VR128, SSEPackedDouble,
2847          !strconcat(OpcodeStr, "pd"), f128mem,
2848          [(set VR128:$dst, (OpNode (bc_v2i64 (v2f64 VR128:$src1)),
2849                                    (bc_v2i64 (v2f64 VR128:$src2))))],
2850          [(set VR128:$dst, (OpNode (bc_v2i64 (v2f64 VR128:$src1)),
2851                                    (memopv2i64 addr:$src2)))]>, PD;
2852   }
2853 }
2854
2855 defm AND  : sse12_fp_packed_logical<0x54, "and", and>;
2856 defm OR   : sse12_fp_packed_logical<0x56, "or", or>;
2857 defm XOR  : sse12_fp_packed_logical<0x57, "xor", xor>;
2858 let isCommutable = 0 in
2859   defm ANDN : sse12_fp_packed_logical<0x55, "andn", X86andnp>;
2860
2861 // If only AVX1 is supported, we need to handle integer operations with
2862 // floating point instructions since the integer versions aren't available.
2863 let Predicates = [HasAVX1Only] in {
2864   def : Pat<(v4i64 (and VR256:$src1, VR256:$src2)),
2865             (VANDPSYrr VR256:$src1, VR256:$src2)>;
2866   def : Pat<(v4i64 (or VR256:$src1, VR256:$src2)),
2867             (VORPSYrr VR256:$src1, VR256:$src2)>;
2868   def : Pat<(v4i64 (xor VR256:$src1, VR256:$src2)),
2869             (VXORPSYrr VR256:$src1, VR256:$src2)>;
2870   def : Pat<(v4i64 (X86andnp VR256:$src1, VR256:$src2)),
2871             (VANDNPSYrr VR256:$src1, VR256:$src2)>;
2872
2873   def : Pat<(and VR256:$src1, (loadv4i64 addr:$src2)),
2874             (VANDPSYrm VR256:$src1, addr:$src2)>;
2875   def : Pat<(or VR256:$src1, (loadv4i64 addr:$src2)),
2876             (VORPSYrm VR256:$src1, addr:$src2)>;
2877   def : Pat<(xor VR256:$src1, (loadv4i64 addr:$src2)),
2878             (VXORPSYrm VR256:$src1, addr:$src2)>;
2879   def : Pat<(X86andnp VR256:$src1, (loadv4i64 addr:$src2)),
2880             (VANDNPSYrm VR256:$src1, addr:$src2)>;
2881 }
2882
2883 let Predicates = [HasAVX, NoVLX_Or_NoDQI] in {
2884   // Use packed logical operations for scalar ops.
2885   def : Pat<(f64 (X86fand FR64:$src1, FR64:$src2)),
2886             (COPY_TO_REGCLASS (VANDPDrr
2887                                (COPY_TO_REGCLASS FR64:$src1, VR128),
2888                                (COPY_TO_REGCLASS FR64:$src2, VR128)), FR64)>;
2889   def : Pat<(f64 (X86for FR64:$src1, FR64:$src2)),
2890             (COPY_TO_REGCLASS (VORPDrr
2891                                (COPY_TO_REGCLASS FR64:$src1, VR128),
2892                                (COPY_TO_REGCLASS FR64:$src2, VR128)), FR64)>;
2893   def : Pat<(f64 (X86fxor FR64:$src1, FR64:$src2)),
2894             (COPY_TO_REGCLASS (VXORPDrr
2895                                (COPY_TO_REGCLASS FR64:$src1, VR128),
2896                                (COPY_TO_REGCLASS FR64:$src2, VR128)), FR64)>;
2897   def : Pat<(f64 (X86fandn FR64:$src1, FR64:$src2)),
2898             (COPY_TO_REGCLASS (VANDNPDrr
2899                                (COPY_TO_REGCLASS FR64:$src1, VR128),
2900                                (COPY_TO_REGCLASS FR64:$src2, VR128)), FR64)>;
2901
2902   def : Pat<(f32 (X86fand FR32:$src1, FR32:$src2)),
2903             (COPY_TO_REGCLASS (VANDPSrr
2904                                (COPY_TO_REGCLASS FR32:$src1, VR128),
2905                                (COPY_TO_REGCLASS FR32:$src2, VR128)), FR32)>;
2906   def : Pat<(f32 (X86for FR32:$src1, FR32:$src2)),
2907             (COPY_TO_REGCLASS (VORPSrr
2908                                (COPY_TO_REGCLASS FR32:$src1, VR128),
2909                                (COPY_TO_REGCLASS FR32:$src2, VR128)), FR32)>;
2910   def : Pat<(f32 (X86fxor FR32:$src1, FR32:$src2)),
2911             (COPY_TO_REGCLASS (VXORPSrr
2912                                (COPY_TO_REGCLASS FR32:$src1, VR128),
2913                                (COPY_TO_REGCLASS FR32:$src2, VR128)), FR32)>;
2914   def : Pat<(f32 (X86fandn FR32:$src1, FR32:$src2)),
2915             (COPY_TO_REGCLASS (VANDNPSrr
2916                                (COPY_TO_REGCLASS FR32:$src1, VR128),
2917                                (COPY_TO_REGCLASS FR32:$src2, VR128)), FR32)>;
2918 }
2919
2920 let Predicates = [UseSSE1] in {
2921   // Use packed logical operations for scalar ops.
2922   def : Pat<(f32 (X86fand FR32:$src1, FR32:$src2)),
2923             (COPY_TO_REGCLASS (ANDPSrr
2924                                (COPY_TO_REGCLASS FR32:$src1, VR128),
2925                                (COPY_TO_REGCLASS FR32:$src2, VR128)), FR32)>;
2926   def : Pat<(f32 (X86for FR32:$src1, FR32:$src2)),
2927             (COPY_TO_REGCLASS (ORPSrr
2928                                (COPY_TO_REGCLASS FR32:$src1, VR128),
2929                                (COPY_TO_REGCLASS FR32:$src2, VR128)), FR32)>;
2930   def : Pat<(f32 (X86fxor FR32:$src1, FR32:$src2)),
2931             (COPY_TO_REGCLASS (XORPSrr
2932                                (COPY_TO_REGCLASS FR32:$src1, VR128),
2933                                (COPY_TO_REGCLASS FR32:$src2, VR128)), FR32)>;
2934   def : Pat<(f32 (X86fandn FR32:$src1, FR32:$src2)),
2935             (COPY_TO_REGCLASS (ANDNPSrr
2936                                (COPY_TO_REGCLASS FR32:$src1, VR128),
2937                                (COPY_TO_REGCLASS FR32:$src2, VR128)), FR32)>;
2938 }
2939
2940 let Predicates = [UseSSE2] in {
2941   // Use packed logical operations for scalar ops.
2942   def : Pat<(f64 (X86fand FR64:$src1, FR64:$src2)),
2943             (COPY_TO_REGCLASS (ANDPDrr
2944                                (COPY_TO_REGCLASS FR64:$src1, VR128),
2945                                (COPY_TO_REGCLASS FR64:$src2, VR128)), FR64)>;
2946   def : Pat<(f64 (X86for FR64:$src1, FR64:$src2)),
2947             (COPY_TO_REGCLASS (ORPDrr
2948                                (COPY_TO_REGCLASS FR64:$src1, VR128),
2949                                (COPY_TO_REGCLASS FR64:$src2, VR128)), FR64)>;
2950   def : Pat<(f64 (X86fxor FR64:$src1, FR64:$src2)),
2951             (COPY_TO_REGCLASS (XORPDrr
2952                                (COPY_TO_REGCLASS FR64:$src1, VR128),
2953                                (COPY_TO_REGCLASS FR64:$src2, VR128)), FR64)>;
2954   def : Pat<(f64 (X86fandn FR64:$src1, FR64:$src2)),
2955             (COPY_TO_REGCLASS (ANDNPDrr
2956                                (COPY_TO_REGCLASS FR64:$src1, VR128),
2957                                (COPY_TO_REGCLASS FR64:$src2, VR128)), FR64)>;
2958 }
2959
2960 // Patterns for packed operations when we don't have integer type available.
2961 def : Pat<(v4f32 (X86fand VR128:$src1, VR128:$src2)),
2962           (ANDPSrr VR128:$src1, VR128:$src2)>;
2963 def : Pat<(v4f32 (X86for VR128:$src1, VR128:$src2)),
2964           (ORPSrr VR128:$src1, VR128:$src2)>;
2965 def : Pat<(v4f32 (X86fxor VR128:$src1, VR128:$src2)),
2966           (XORPSrr VR128:$src1, VR128:$src2)>;
2967 def : Pat<(v4f32 (X86fandn VR128:$src1, VR128:$src2)),
2968           (ANDNPSrr VR128:$src1, VR128:$src2)>;
2969
2970 def : Pat<(X86fand VR128:$src1, (memopv4f32 addr:$src2)),
2971           (ANDPSrm VR128:$src1, addr:$src2)>;
2972 def : Pat<(X86for VR128:$src1, (memopv4f32 addr:$src2)),
2973           (ORPSrm VR128:$src1, addr:$src2)>;
2974 def : Pat<(X86fxor VR128:$src1, (memopv4f32 addr:$src2)),
2975           (XORPSrm VR128:$src1, addr:$src2)>;
2976 def : Pat<(X86fandn VR128:$src1, (memopv4f32 addr:$src2)),
2977           (ANDNPSrm VR128:$src1, addr:$src2)>;
2978
2979 //===----------------------------------------------------------------------===//
2980 // SSE 1 & 2 - Arithmetic Instructions
2981 //===----------------------------------------------------------------------===//
2982
2983 /// basic_sse12_fp_binop_xxx - SSE 1 & 2 binops come in both scalar and
2984 /// vector forms.
2985 ///
2986 /// In addition, we also have a special variant of the scalar form here to
2987 /// represent the associated intrinsic operation.  This form is unlike the
2988 /// plain scalar form, in that it takes an entire vector (instead of a scalar)
2989 /// and leaves the top elements unmodified (therefore these cannot be commuted).
2990 ///
2991 /// These three forms can each be reg+reg or reg+mem.
2992 ///
2993
2994 /// FIXME: once all 256-bit intrinsics are matched, cleanup and refactor those
2995 /// classes below
2996 multiclass basic_sse12_fp_binop_p<bits<8> opc, string OpcodeStr,
2997                                   SDNode OpNode, SizeItins itins> {
2998   let Predicates = [HasAVX, NoVLX] in {
2999   defm V#NAME#PS : sse12_fp_packed<opc, !strconcat(OpcodeStr, "ps"), OpNode,
3000                                VR128, v4f32, f128mem, loadv4f32,
3001                                SSEPackedSingle, itins.s, 0>, PS, VEX_4V, VEX_WIG;
3002   defm V#NAME#PD : sse12_fp_packed<opc, !strconcat(OpcodeStr, "pd"), OpNode,
3003                                VR128, v2f64, f128mem, loadv2f64,
3004                                SSEPackedDouble, itins.d, 0>, PD, VEX_4V, VEX_WIG;
3005
3006   defm V#NAME#PSY : sse12_fp_packed<opc, !strconcat(OpcodeStr, "ps"),
3007                         OpNode, VR256, v8f32, f256mem, loadv8f32,
3008                         SSEPackedSingle, itins.s, 0>, PS, VEX_4V, VEX_L, VEX_WIG;
3009   defm V#NAME#PDY : sse12_fp_packed<opc, !strconcat(OpcodeStr, "pd"),
3010                         OpNode, VR256, v4f64, f256mem, loadv4f64,
3011                         SSEPackedDouble, itins.d, 0>, PD, VEX_4V, VEX_L, VEX_WIG;
3012   }
3013
3014   let Constraints = "$src1 = $dst" in {
3015     defm PS : sse12_fp_packed<opc, !strconcat(OpcodeStr, "ps"), OpNode, VR128,
3016                               v4f32, f128mem, memopv4f32, SSEPackedSingle,
3017                               itins.s>, PS;
3018     defm PD : sse12_fp_packed<opc, !strconcat(OpcodeStr, "pd"), OpNode, VR128,
3019                               v2f64, f128mem, memopv2f64, SSEPackedDouble,
3020                               itins.d>, PD;
3021   }
3022 }
3023
3024 multiclass basic_sse12_fp_binop_s<bits<8> opc, string OpcodeStr, SDNode OpNode,
3025                                   SizeItins itins> {
3026   defm V#NAME#SS : sse12_fp_scalar<opc, !strconcat(OpcodeStr, "ss"),
3027                          OpNode, FR32, f32mem, SSEPackedSingle, itins.s, 0>,
3028                          XS, VEX_4V, VEX_LIG, VEX_WIG;
3029   defm V#NAME#SD : sse12_fp_scalar<opc, !strconcat(OpcodeStr, "sd"),
3030                          OpNode, FR64, f64mem, SSEPackedDouble, itins.d, 0>,
3031                          XD, VEX_4V, VEX_LIG, VEX_WIG;
3032
3033   let Constraints = "$src1 = $dst" in {
3034     defm SS : sse12_fp_scalar<opc, !strconcat(OpcodeStr, "ss"),
3035                               OpNode, FR32, f32mem, SSEPackedSingle,
3036                               itins.s>, XS;
3037     defm SD : sse12_fp_scalar<opc, !strconcat(OpcodeStr, "sd"),
3038                               OpNode, FR64, f64mem, SSEPackedDouble,
3039                               itins.d>, XD;
3040   }
3041 }
3042
3043 multiclass basic_sse12_fp_binop_s_int<bits<8> opc, string OpcodeStr,
3044                                       SDPatternOperator OpNode,
3045                                       SizeItins itins> {
3046   defm V#NAME#SS : sse12_fp_scalar_int<opc, OpcodeStr, OpNode, VR128, v4f32,
3047                    !strconcat(OpcodeStr, "ss"), ssmem, sse_load_f32,
3048                    SSEPackedSingle, itins.s, 0>, XS, VEX_4V, VEX_LIG, VEX_WIG;
3049   defm V#NAME#SD : sse12_fp_scalar_int<opc, OpcodeStr, OpNode, VR128, v2f64,
3050                    !strconcat(OpcodeStr, "sd"), sdmem, sse_load_f64,
3051                    SSEPackedDouble, itins.d, 0>, XD, VEX_4V, VEX_LIG, VEX_WIG;
3052
3053   let Constraints = "$src1 = $dst" in {
3054     defm SS : sse12_fp_scalar_int<opc, OpcodeStr, OpNode, VR128, v4f32,
3055                    !strconcat(OpcodeStr, "ss"), ssmem, sse_load_f32,
3056                    SSEPackedSingle, itins.s>, XS;
3057     defm SD : sse12_fp_scalar_int<opc, OpcodeStr, OpNode, VR128, v2f64,
3058                    !strconcat(OpcodeStr, "sd"), sdmem, sse_load_f64,
3059                    SSEPackedDouble, itins.d>, XD;
3060   }
3061 }
3062
3063 // Binary Arithmetic instructions
3064 defm ADD : basic_sse12_fp_binop_p<0x58, "add", fadd, SSE_ALU_ITINS_P>,
3065            basic_sse12_fp_binop_s<0x58, "add", fadd, SSE_ALU_ITINS_S>,
3066            basic_sse12_fp_binop_s_int<0x58, "add", null_frag, SSE_ALU_ITINS_S>;
3067 defm MUL : basic_sse12_fp_binop_p<0x59, "mul", fmul, SSE_MUL_ITINS_P>,
3068            basic_sse12_fp_binop_s<0x59, "mul", fmul, SSE_MUL_ITINS_S>,
3069            basic_sse12_fp_binop_s_int<0x59, "mul", null_frag, SSE_MUL_ITINS_S>;
3070 let isCommutable = 0 in {
3071   defm SUB : basic_sse12_fp_binop_p<0x5C, "sub", fsub, SSE_ALU_ITINS_P>,
3072              basic_sse12_fp_binop_s<0x5C, "sub", fsub, SSE_ALU_ITINS_S>,
3073              basic_sse12_fp_binop_s_int<0x5C, "sub", null_frag,SSE_ALU_ITINS_S>;
3074   defm DIV : basic_sse12_fp_binop_p<0x5E, "div", fdiv, SSE_DIV_ITINS_P>,
3075              basic_sse12_fp_binop_s<0x5E, "div", fdiv, SSE_DIV_ITINS_S>,
3076              basic_sse12_fp_binop_s_int<0x5E, "div", null_frag,SSE_DIV_ITINS_S>;
3077   defm MAX : basic_sse12_fp_binop_p<0x5F, "max", X86fmax, SSE_ALU_ITINS_P>,
3078              basic_sse12_fp_binop_s<0x5F, "max", X86fmax, SSE_ALU_ITINS_S>,
3079              basic_sse12_fp_binop_s_int<0x5F, "max", X86fmaxs, SSE_ALU_ITINS_S>;
3080   defm MIN : basic_sse12_fp_binop_p<0x5D, "min", X86fmin, SSE_ALU_ITINS_P>,
3081              basic_sse12_fp_binop_s<0x5D, "min", X86fmin, SSE_ALU_ITINS_S>,
3082              basic_sse12_fp_binop_s_int<0x5D, "min", X86fmins, SSE_ALU_ITINS_S>;
3083 }
3084
3085 let isCodeGenOnly = 1 in {
3086   defm MAXC: basic_sse12_fp_binop_p<0x5F, "max", X86fmaxc, SSE_ALU_ITINS_P>,
3087              basic_sse12_fp_binop_s<0x5F, "max", X86fmaxc, SSE_ALU_ITINS_S>;
3088   defm MINC: basic_sse12_fp_binop_p<0x5D, "min", X86fminc, SSE_ALU_ITINS_P>,
3089              basic_sse12_fp_binop_s<0x5D, "min", X86fminc, SSE_ALU_ITINS_S>;
3090 }
3091
3092 // Patterns used to select SSE scalar fp arithmetic instructions from
3093 // either:
3094 //
3095 // (1) a scalar fp operation followed by a blend
3096 //
3097 // The effect is that the backend no longer emits unnecessary vector
3098 // insert instructions immediately after SSE scalar fp instructions
3099 // like addss or mulss.
3100 //
3101 // For example, given the following code:
3102 //   __m128 foo(__m128 A, __m128 B) {
3103 //     A[0] += B[0];
3104 //     return A;
3105 //   }
3106 //
3107 // Previously we generated:
3108 //   addss %xmm0, %xmm1
3109 //   movss %xmm1, %xmm0
3110 //
3111 // We now generate:
3112 //   addss %xmm1, %xmm0
3113 //
3114 // (2) a vector packed single/double fp operation followed by a vector insert
3115 //
3116 // The effect is that the backend converts the packed fp instruction
3117 // followed by a vector insert into a single SSE scalar fp instruction.
3118 //
3119 // For example, given the following code:
3120 //   __m128 foo(__m128 A, __m128 B) {
3121 //     __m128 C = A + B;
3122 //     return (__m128) {c[0], a[1], a[2], a[3]};
3123 //   }
3124 //
3125 // Previously we generated:
3126 //   addps %xmm0, %xmm1
3127 //   movss %xmm1, %xmm0
3128 //
3129 // We now generate:
3130 //   addss %xmm1, %xmm0
3131
3132 // TODO: Some canonicalization in lowering would simplify the number of
3133 // patterns we have to try to match.
3134 multiclass scalar_math_f32_patterns<SDNode Op, string OpcPrefix> {
3135   let Predicates = [UseSSE1] in {
3136     // extracted scalar math op with insert via movss
3137     def : Pat<(v4f32 (X86Movss (v4f32 VR128:$dst), (v4f32 (scalar_to_vector
3138           (Op (f32 (extractelt (v4f32 VR128:$dst), (iPTR 0))),
3139           FR32:$src))))),
3140       (!cast<I>(OpcPrefix#SSrr_Int) v4f32:$dst,
3141           (COPY_TO_REGCLASS FR32:$src, VR128))>;
3142
3143     // vector math op with insert via movss
3144     def : Pat<(v4f32 (X86Movss (v4f32 VR128:$dst),
3145           (Op (v4f32 VR128:$dst), (v4f32 VR128:$src)))),
3146       (!cast<I>(OpcPrefix#SSrr_Int) v4f32:$dst, v4f32:$src)>;
3147   }
3148
3149   // With SSE 4.1, blendi is preferred to movsd, so match that too.
3150   let Predicates = [UseSSE41] in {
3151     // extracted scalar math op with insert via blend
3152     def : Pat<(v4f32 (X86Blendi (v4f32 VR128:$dst), (v4f32 (scalar_to_vector
3153           (Op (f32 (extractelt (v4f32 VR128:$dst), (iPTR 0))),
3154           FR32:$src))), (i8 1))),
3155       (!cast<I>(OpcPrefix#SSrr_Int) v4f32:$dst,
3156           (COPY_TO_REGCLASS FR32:$src, VR128))>;
3157
3158     // vector math op with insert via blend
3159     def : Pat<(v4f32 (X86Blendi (v4f32 VR128:$dst),
3160           (Op (v4f32 VR128:$dst), (v4f32 VR128:$src)), (i8 1))),
3161       (!cast<I>(OpcPrefix#SSrr_Int)v4f32:$dst, v4f32:$src)>;
3162
3163   }
3164
3165   // Repeat everything for AVX.
3166   let Predicates = [UseAVX] in {
3167     // extracted scalar math op with insert via movss
3168     def : Pat<(v4f32 (X86Movss (v4f32 VR128:$dst), (v4f32 (scalar_to_vector
3169           (Op (f32 (extractelt (v4f32 VR128:$dst), (iPTR 0))),
3170           FR32:$src))))),
3171       (!cast<I>("V"#OpcPrefix#SSrr_Int) v4f32:$dst,
3172           (COPY_TO_REGCLASS FR32:$src, VR128))>;
3173
3174     // extracted scalar math op with insert via blend
3175     def : Pat<(v4f32 (X86Blendi (v4f32 VR128:$dst), (v4f32 (scalar_to_vector
3176           (Op (f32 (extractelt (v4f32 VR128:$dst), (iPTR 0))),
3177           FR32:$src))), (i8 1))),
3178       (!cast<I>("V"#OpcPrefix#SSrr_Int) v4f32:$dst,
3179           (COPY_TO_REGCLASS FR32:$src, VR128))>;
3180
3181     // vector math op with insert via movss
3182     def : Pat<(v4f32 (X86Movss (v4f32 VR128:$dst),
3183           (Op (v4f32 VR128:$dst), (v4f32 VR128:$src)))),
3184       (!cast<I>("V"#OpcPrefix#SSrr_Int) v4f32:$dst, v4f32:$src)>;
3185
3186     // vector math op with insert via blend
3187     def : Pat<(v4f32 (X86Blendi (v4f32 VR128:$dst),
3188           (Op (v4f32 VR128:$dst), (v4f32 VR128:$src)), (i8 1))),
3189       (!cast<I>("V"#OpcPrefix#SSrr_Int) v4f32:$dst, v4f32:$src)>;
3190   }
3191 }
3192
3193 defm : scalar_math_f32_patterns<fadd, "ADD">;
3194 defm : scalar_math_f32_patterns<fsub, "SUB">;
3195 defm : scalar_math_f32_patterns<fmul, "MUL">;
3196 defm : scalar_math_f32_patterns<fdiv, "DIV">;
3197
3198 multiclass scalar_math_f64_patterns<SDNode Op, string OpcPrefix> {
3199   let Predicates = [UseSSE2] in {
3200     // extracted scalar math op with insert via movsd
3201     def : Pat<(v2f64 (X86Movsd (v2f64 VR128:$dst), (v2f64 (scalar_to_vector
3202           (Op (f64 (extractelt (v2f64 VR128:$dst), (iPTR 0))),
3203           FR64:$src))))),
3204       (!cast<I>(OpcPrefix#SDrr_Int) v2f64:$dst,
3205           (COPY_TO_REGCLASS FR64:$src, VR128))>;
3206
3207     // vector math op with insert via movsd
3208     def : Pat<(v2f64 (X86Movsd (v2f64 VR128:$dst),
3209           (Op (v2f64 VR128:$dst), (v2f64 VR128:$src)))),
3210       (!cast<I>(OpcPrefix#SDrr_Int) v2f64:$dst, v2f64:$src)>;
3211   }
3212
3213   // With SSE 4.1, blendi is preferred to movsd, so match those too.
3214   let Predicates = [UseSSE41] in {
3215     // extracted scalar math op with insert via blend
3216     def : Pat<(v2f64 (X86Blendi (v2f64 VR128:$dst), (v2f64 (scalar_to_vector
3217           (Op (f64 (extractelt (v2f64 VR128:$dst), (iPTR 0))),
3218           FR64:$src))), (i8 1))),
3219       (!cast<I>(OpcPrefix#SDrr_Int) v2f64:$dst,
3220           (COPY_TO_REGCLASS FR64:$src, VR128))>;
3221
3222     // vector math op with insert via blend
3223     def : Pat<(v2f64 (X86Blendi (v2f64 VR128:$dst),
3224           (Op (v2f64 VR128:$dst), (v2f64 VR128:$src)), (i8 1))),
3225       (!cast<I>(OpcPrefix#SDrr_Int) v2f64:$dst, v2f64:$src)>;
3226   }
3227
3228   // Repeat everything for AVX.
3229   let Predicates = [UseAVX] in {
3230     // extracted scalar math op with insert via movsd
3231     def : Pat<(v2f64 (X86Movsd (v2f64 VR128:$dst), (v2f64 (scalar_to_vector
3232           (Op (f64 (extractelt (v2f64 VR128:$dst), (iPTR 0))),
3233           FR64:$src))))),
3234       (!cast<I>("V"#OpcPrefix#SDrr_Int) v2f64:$dst,
3235           (COPY_TO_REGCLASS FR64:$src, VR128))>;
3236
3237     // extracted scalar math op with insert via blend
3238     def : Pat<(v2f64 (X86Blendi (v2f64 VR128:$dst), (v2f64 (scalar_to_vector
3239           (Op (f64 (extractelt (v2f64 VR128:$dst), (iPTR 0))),
3240           FR64:$src))), (i8 1))),
3241       (!cast<I>("V"#OpcPrefix#SDrr_Int) v2f64:$dst,
3242           (COPY_TO_REGCLASS FR64:$src, VR128))>;
3243
3244     // vector math op with insert via movsd
3245     def : Pat<(v2f64 (X86Movsd (v2f64 VR128:$dst),
3246           (Op (v2f64 VR128:$dst), (v2f64 VR128:$src)))),
3247       (!cast<I>("V"#OpcPrefix#SDrr_Int) v2f64:$dst, v2f64:$src)>;
3248
3249     // vector math op with insert via blend
3250     def : Pat<(v2f64 (X86Blendi (v2f64 VR128:$dst),
3251           (Op (v2f64 VR128:$dst), (v2f64 VR128:$src)), (i8 1))),
3252       (!cast<I>("V"#OpcPrefix#SDrr_Int) v2f64:$dst, v2f64:$src)>;
3253   }
3254 }
3255
3256 defm : scalar_math_f64_patterns<fadd, "ADD">;
3257 defm : scalar_math_f64_patterns<fsub, "SUB">;
3258 defm : scalar_math_f64_patterns<fmul, "MUL">;
3259 defm : scalar_math_f64_patterns<fdiv, "DIV">;
3260
3261
3262 /// Unop Arithmetic
3263 /// In addition, we also have a special variant of the scalar form here to
3264 /// represent the associated intrinsic operation.  This form is unlike the
3265 /// plain scalar form, in that it takes an entire vector (instead of a
3266 /// scalar) and leaves the top elements undefined.
3267 ///
3268 /// And, we have a special variant form for a full-vector intrinsic form.
3269
3270 let Sched = WriteFSqrt in {
3271 def SSE_SQRTPS : OpndItins<
3272   IIC_SSE_SQRTPS_RR, IIC_SSE_SQRTPS_RM
3273 >;
3274
3275 def SSE_SQRTSS : OpndItins<
3276   IIC_SSE_SQRTSS_RR, IIC_SSE_SQRTSS_RM
3277 >;
3278
3279 def SSE_SQRTPD : OpndItins<
3280   IIC_SSE_SQRTPD_RR, IIC_SSE_SQRTPD_RM
3281 >;
3282
3283 def SSE_SQRTSD : OpndItins<
3284   IIC_SSE_SQRTSD_RR, IIC_SSE_SQRTSD_RM
3285 >;
3286 }
3287
3288 let Sched = WriteFRsqrt in {
3289 def SSE_RSQRTPS : OpndItins<
3290   IIC_SSE_RSQRTPS_RR, IIC_SSE_RSQRTPS_RM
3291 >;
3292
3293 def SSE_RSQRTSS : OpndItins<
3294   IIC_SSE_RSQRTSS_RR, IIC_SSE_RSQRTSS_RM
3295 >;
3296 }
3297
3298 let Sched = WriteFRcp in {
3299 def SSE_RCPP : OpndItins<
3300   IIC_SSE_RCPP_RR, IIC_SSE_RCPP_RM
3301 >;
3302
3303 def SSE_RCPS : OpndItins<
3304   IIC_SSE_RCPS_RR, IIC_SSE_RCPS_RM
3305 >;
3306 }
3307
3308 /// sse_fp_unop_s - SSE1 unops in scalar form
3309 /// For the non-AVX defs, we need $src1 to be tied to $dst because
3310 /// the HW instructions are 2 operand / destructive.
3311 multiclass sse_fp_unop_s<bits<8> opc, string OpcodeStr, RegisterClass RC,
3312                           ValueType vt, ValueType ScalarVT,
3313                           X86MemOperand x86memop,
3314                           Intrinsic Intr,
3315                           SDNode OpNode, Domain d, OpndItins itins,
3316                           Predicate target, string Suffix> {
3317   let hasSideEffects = 0 in {
3318   def r : I<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src1),
3319               !strconcat(OpcodeStr, "\t{$src1, $dst|$dst, $src1}"),
3320             [(set RC:$dst, (OpNode RC:$src1))], itins.rr, d>, Sched<[itins.Sched]>,
3321             Requires<[target]>;
3322   let mayLoad = 1 in
3323   def m : I<opc, MRMSrcMem, (outs RC:$dst), (ins x86memop:$src1),
3324             !strconcat(OpcodeStr, "\t{$src1, $dst|$dst, $src1}"),
3325             [(set RC:$dst, (OpNode (load addr:$src1)))], itins.rm, d>,
3326             Sched<[itins.Sched.Folded, ReadAfterLd]>,
3327             Requires<[target, OptForSize]>;
3328
3329   let isCodeGenOnly = 1, Constraints = "$src1 = $dst", ExeDomain = d in {
3330   def r_Int : I<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src1, VR128:$src2),
3331               !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
3332             []>, Sched<[itins.Sched.Folded, ReadAfterLd]>;
3333   let mayLoad = 1 in
3334   def m_Int : I<opc, MRMSrcMem, (outs VR128:$dst), (ins VR128:$src1, x86memop:$src2),
3335               !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
3336             []>, Sched<[itins.Sched.Folded, ReadAfterLd]>;
3337   }
3338   }
3339
3340   let Predicates = [target] in {
3341   // These are unary operations, but they are modeled as having 2 source operands
3342   // because the high elements of the destination are unchanged in SSE.
3343   def : Pat<(Intr VR128:$src),
3344             (!cast<Instruction>(NAME#Suffix##r_Int) VR128:$src, VR128:$src)>;
3345   }
3346   // We don't want to fold scalar loads into these instructions unless
3347   // optimizing for size. This is because the folded instruction will have a
3348   // partial register update, while the unfolded sequence will not, e.g.
3349   // movss mem, %xmm0
3350   // rcpss %xmm0, %xmm0
3351   // which has a clobber before the rcp, vs.
3352   // rcpss mem, %xmm0
3353   let Predicates = [target, OptForSize] in {
3354     def : Pat<(Intr (scalar_to_vector (ScalarVT (load addr:$src2)))),
3355                (!cast<Instruction>(NAME#Suffix##m_Int)
3356                       (vt (IMPLICIT_DEF)), addr:$src2)>;
3357   }
3358 }
3359
3360 multiclass avx_fp_unop_s<bits<8> opc, string OpcodeStr, RegisterClass RC,
3361                           ValueType vt, ValueType ScalarVT,
3362                           X86MemOperand x86memop,
3363                           Intrinsic Intr, SDNode OpNode, Domain d,
3364                           OpndItins itins, string Suffix> {
3365   let hasSideEffects = 0 in {
3366   def r : I<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
3367             !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
3368             [], itins.rr, d>, Sched<[itins.Sched]>;
3369   let mayLoad = 1 in
3370   def m : I<opc, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
3371              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
3372             [], itins.rm, d>, Sched<[itins.Sched.Folded, ReadAfterLd]>;
3373   let isCodeGenOnly = 1, ExeDomain = d in {
3374   def r_Int : I<opc, MRMSrcReg, (outs VR128:$dst),
3375                 (ins VR128:$src1, VR128:$src2),
3376              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
3377              []>, Sched<[itins.Sched.Folded]>;
3378   let mayLoad = 1 in
3379   def m_Int : I<opc, MRMSrcMem, (outs VR128:$dst),
3380                 (ins VR128:$src1, x86memop:$src2),
3381              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
3382              []>, Sched<[itins.Sched.Folded, ReadAfterLd]>;
3383   }
3384   }
3385
3386   // We don't want to fold scalar loads into these instructions unless
3387   // optimizing for size. This is because the folded instruction will have a
3388   // partial register update, while the unfolded sequence will not, e.g.
3389   // vmovss mem, %xmm0
3390   // vrcpss %xmm0, %xmm0, %xmm0
3391   // which has a clobber before the rcp, vs.
3392   // vrcpss mem, %xmm0, %xmm0
3393   // TODO: In theory, we could fold the load, and avoid the stall caused by
3394   // the partial register store, either in ExecutionDepsFix or with smarter RA.
3395   let Predicates = [UseAVX] in {
3396    def : Pat<(OpNode RC:$src),  (!cast<Instruction>("V"#NAME#Suffix##r)
3397                                 (ScalarVT (IMPLICIT_DEF)), RC:$src)>;
3398   }
3399   let Predicates = [HasAVX] in {
3400    def : Pat<(Intr VR128:$src),
3401              (!cast<Instruction>("V"#NAME#Suffix##r_Int) VR128:$src,
3402                                  VR128:$src)>;
3403   }
3404   let Predicates = [HasAVX, OptForSize] in {
3405     def : Pat<(Intr (scalar_to_vector (ScalarVT (load addr:$src2)))),
3406               (!cast<Instruction>("V"#NAME#Suffix##m_Int)
3407                     (vt (IMPLICIT_DEF)), addr:$src2)>;
3408   }
3409   let Predicates = [UseAVX, OptForSize] in {
3410     def : Pat<(ScalarVT (OpNode (load addr:$src))),
3411               (!cast<Instruction>("V"#NAME#Suffix##m) (ScalarVT (IMPLICIT_DEF)),
3412             addr:$src)>;
3413   }
3414 }
3415
3416 /// sse1_fp_unop_p - SSE1 unops in packed form.
3417 multiclass sse1_fp_unop_p<bits<8> opc, string OpcodeStr, SDNode OpNode,
3418                           OpndItins itins, list<Predicate> prds> {
3419 let Predicates = prds in {
3420   def V#NAME#PSr : PSI<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3421                        !strconcat("v", OpcodeStr,
3422                                   "ps\t{$src, $dst|$dst, $src}"),
3423                        [(set VR128:$dst, (v4f32 (OpNode VR128:$src)))],
3424                        itins.rr>, VEX, Sched<[itins.Sched]>, VEX_WIG;
3425   def V#NAME#PSm : PSI<opc, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
3426                        !strconcat("v", OpcodeStr,
3427                                   "ps\t{$src, $dst|$dst, $src}"),
3428                        [(set VR128:$dst, (OpNode (loadv4f32 addr:$src)))],
3429                        itins.rm>, VEX, Sched<[itins.Sched.Folded]>, VEX_WIG;
3430   def V#NAME#PSYr : PSI<opc, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
3431                         !strconcat("v", OpcodeStr,
3432                                    "ps\t{$src, $dst|$dst, $src}"),
3433                         [(set VR256:$dst, (v8f32 (OpNode VR256:$src)))],
3434                         itins.rr>, VEX, VEX_L, Sched<[itins.Sched]>, VEX_WIG;
3435   def V#NAME#PSYm : PSI<opc, MRMSrcMem, (outs VR256:$dst), (ins f256mem:$src),
3436                         !strconcat("v", OpcodeStr,
3437                                    "ps\t{$src, $dst|$dst, $src}"),
3438                         [(set VR256:$dst, (OpNode (loadv8f32 addr:$src)))],
3439                         itins.rm>, VEX, VEX_L, Sched<[itins.Sched.Folded]>, VEX_WIG;
3440 }
3441
3442   def PSr : PSI<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3443                 !strconcat(OpcodeStr, "ps\t{$src, $dst|$dst, $src}"),
3444                 [(set VR128:$dst, (v4f32 (OpNode VR128:$src)))], itins.rr>,
3445             Sched<[itins.Sched]>;
3446   def PSm : PSI<opc, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
3447                 !strconcat(OpcodeStr, "ps\t{$src, $dst|$dst, $src}"),
3448                 [(set VR128:$dst, (OpNode (memopv4f32 addr:$src)))], itins.rm>,
3449             Sched<[itins.Sched.Folded]>;
3450 }
3451
3452 /// sse2_fp_unop_p - SSE2 unops in vector forms.
3453 multiclass sse2_fp_unop_p<bits<8> opc, string OpcodeStr,
3454                           SDNode OpNode, OpndItins itins> {
3455 let Predicates = [HasAVX] in {
3456   def V#NAME#PDr : PDI<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3457                        !strconcat("v", OpcodeStr,
3458                                   "pd\t{$src, $dst|$dst, $src}"),
3459                        [(set VR128:$dst, (v2f64 (OpNode VR128:$src)))],
3460                        itins.rr>, VEX, Sched<[itins.Sched]>, VEX_WIG;
3461   def V#NAME#PDm : PDI<opc, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
3462                        !strconcat("v", OpcodeStr,
3463                                   "pd\t{$src, $dst|$dst, $src}"),
3464                        [(set VR128:$dst, (OpNode (loadv2f64 addr:$src)))],
3465                        itins.rm>, VEX, Sched<[itins.Sched.Folded]>, VEX_WIG;
3466   def V#NAME#PDYr : PDI<opc, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
3467                         !strconcat("v", OpcodeStr,
3468                                    "pd\t{$src, $dst|$dst, $src}"),
3469                         [(set VR256:$dst, (v4f64 (OpNode VR256:$src)))],
3470                         itins.rr>, VEX, VEX_L, Sched<[itins.Sched]>, VEX_WIG;
3471   def V#NAME#PDYm : PDI<opc, MRMSrcMem, (outs VR256:$dst), (ins f256mem:$src),
3472                         !strconcat("v", OpcodeStr,
3473                                    "pd\t{$src, $dst|$dst, $src}"),
3474                         [(set VR256:$dst, (OpNode (loadv4f64 addr:$src)))],
3475                         itins.rm>, VEX, VEX_L, Sched<[itins.Sched.Folded]>, VEX_WIG;
3476 }
3477
3478   def PDr : PDI<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3479               !strconcat(OpcodeStr, "pd\t{$src, $dst|$dst, $src}"),
3480               [(set VR128:$dst, (v2f64 (OpNode VR128:$src)))], itins.rr>,
3481             Sched<[itins.Sched]>;
3482   def PDm : PDI<opc, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
3483                 !strconcat(OpcodeStr, "pd\t{$src, $dst|$dst, $src}"),
3484                 [(set VR128:$dst, (OpNode (memopv2f64 addr:$src)))], itins.rm>,
3485             Sched<[itins.Sched.Folded]>;
3486 }
3487
3488 multiclass sse1_fp_unop_s<bits<8> opc, string OpcodeStr, SDNode OpNode,
3489                           OpndItins itins> {
3490   defm SS        :  sse_fp_unop_s<opc, OpcodeStr##ss, FR32, v4f32, f32, f32mem,
3491                       !cast<Intrinsic>("int_x86_sse_"##OpcodeStr##_ss), OpNode,
3492                       SSEPackedSingle, itins, UseSSE1, "SS">, XS;
3493   defm V#NAME#SS  : avx_fp_unop_s<opc, "v"#OpcodeStr##ss, FR32, v4f32, f32,
3494                       f32mem,
3495                       !cast<Intrinsic>("int_x86_sse_"##OpcodeStr##_ss), OpNode,
3496                       SSEPackedSingle, itins, "SS">, XS, VEX_4V, VEX_LIG, VEX_WIG;
3497 }
3498
3499 multiclass sse2_fp_unop_s<bits<8> opc, string OpcodeStr, SDNode OpNode,
3500                           OpndItins itins> {
3501   defm SD         : sse_fp_unop_s<opc, OpcodeStr##sd, FR64, v2f64, f64, f64mem,
3502                          !cast<Intrinsic>("int_x86_sse2_"##OpcodeStr##_sd),
3503                          OpNode, SSEPackedDouble, itins, UseSSE2, "SD">, XD;
3504   defm V#NAME#SD  : avx_fp_unop_s<opc, "v"#OpcodeStr##sd, FR64, v2f64, f64,
3505                          f64mem,
3506                          !cast<Intrinsic>("int_x86_sse2_"##OpcodeStr##_sd),
3507                          OpNode, SSEPackedDouble, itins, "SD">,
3508                          XD, VEX_4V, VEX_LIG, VEX_WIG;
3509 }
3510
3511 // Square root.
3512 defm SQRT  : sse1_fp_unop_s<0x51, "sqrt", fsqrt, SSE_SQRTSS>,
3513              sse1_fp_unop_p<0x51, "sqrt", fsqrt, SSE_SQRTPS, [HasAVX]>,
3514              sse2_fp_unop_s<0x51, "sqrt", fsqrt, SSE_SQRTSD>,
3515              sse2_fp_unop_p<0x51, "sqrt", fsqrt, SSE_SQRTPD>;
3516
3517 // Reciprocal approximations. Note that these typically require refinement
3518 // in order to obtain suitable precision.
3519 defm RSQRT : sse1_fp_unop_s<0x52, "rsqrt", X86frsqrt, SSE_RSQRTSS>,
3520              sse1_fp_unop_p<0x52, "rsqrt", X86frsqrt, SSE_RSQRTPS, [HasAVX, NoVLX] >;
3521 defm RCP   : sse1_fp_unop_s<0x53, "rcp", X86frcp, SSE_RCPS>,
3522              sse1_fp_unop_p<0x53, "rcp", X86frcp, SSE_RCPP, [HasAVX, NoVLX]>;
3523
3524 // There is no f64 version of the reciprocal approximation instructions.
3525
3526 // TODO: We should add *scalar* op patterns for these just like we have for
3527 // the binops above. If the binop and unop patterns could all be unified
3528 // that would be even better.
3529
3530 multiclass scalar_unary_math_patterns<Intrinsic Intr, string OpcPrefix,
3531                                       SDNode Move, ValueType VT,
3532                                       Predicate BasePredicate> {
3533   let Predicates = [BasePredicate] in {
3534     def : Pat<(VT (Move VT:$dst, (Intr VT:$src))),
3535               (!cast<I>(OpcPrefix#r_Int) VT:$dst, VT:$src)>;
3536   }
3537
3538   // With SSE 4.1, blendi is preferred to movs*, so match that too.
3539   let Predicates = [UseSSE41] in {
3540     def : Pat<(VT (X86Blendi VT:$dst, (Intr VT:$src), (i8 1))),
3541               (!cast<I>(OpcPrefix#r_Int) VT:$dst, VT:$src)>;
3542   }
3543
3544   // Repeat for AVX versions of the instructions.
3545   let Predicates = [HasAVX] in {
3546     def : Pat<(VT (Move VT:$dst, (Intr VT:$src))),
3547               (!cast<I>("V"#OpcPrefix#r_Int) VT:$dst, VT:$src)>;
3548
3549     def : Pat<(VT (X86Blendi VT:$dst, (Intr VT:$src), (i8 1))),
3550               (!cast<I>("V"#OpcPrefix#r_Int) VT:$dst, VT:$src)>;
3551   }
3552 }
3553
3554 defm : scalar_unary_math_patterns<int_x86_sse_rcp_ss, "RCPSS", X86Movss,
3555                                   v4f32, UseSSE1>;
3556 defm : scalar_unary_math_patterns<int_x86_sse_rsqrt_ss, "RSQRTSS", X86Movss,
3557                                   v4f32, UseSSE1>;
3558 defm : scalar_unary_math_patterns<int_x86_sse_sqrt_ss, "SQRTSS", X86Movss,
3559                                   v4f32, UseSSE1>;
3560 defm : scalar_unary_math_patterns<int_x86_sse2_sqrt_sd, "SQRTSD", X86Movsd,
3561                                   v2f64, UseSSE2>;
3562
3563
3564 //===----------------------------------------------------------------------===//
3565 // SSE 1 & 2 - Non-temporal stores
3566 //===----------------------------------------------------------------------===//
3567
3568 let AddedComplexity = 400 in { // Prefer non-temporal versions
3569 let SchedRW = [WriteStore] in {
3570 let Predicates = [HasAVX, NoVLX] in {
3571 def VMOVNTPSmr : VPSI<0x2B, MRMDestMem, (outs),
3572                      (ins f128mem:$dst, VR128:$src),
3573                      "movntps\t{$src, $dst|$dst, $src}",
3574                      [(alignednontemporalstore (v4f32 VR128:$src),
3575                                                addr:$dst)],
3576                                                IIC_SSE_MOVNT>, VEX, VEX_WIG;
3577 def VMOVNTPDmr : VPDI<0x2B, MRMDestMem, (outs),
3578                      (ins f128mem:$dst, VR128:$src),
3579                      "movntpd\t{$src, $dst|$dst, $src}",
3580                      [(alignednontemporalstore (v2f64 VR128:$src),
3581                                                addr:$dst)],
3582                                                IIC_SSE_MOVNT>, VEX, VEX_WIG;
3583
3584 let ExeDomain = SSEPackedInt in
3585 def VMOVNTDQmr    : VPDI<0xE7, MRMDestMem, (outs),
3586                          (ins i128mem:$dst, VR128:$src),
3587                          "movntdq\t{$src, $dst|$dst, $src}",
3588                          [(alignednontemporalstore (v2i64 VR128:$src),
3589                                                    addr:$dst)],
3590                                                    IIC_SSE_MOVNT>, VEX, VEX_WIG;
3591
3592 def VMOVNTPSYmr : VPSI<0x2B, MRMDestMem, (outs),
3593                      (ins f256mem:$dst, VR256:$src),
3594                      "movntps\t{$src, $dst|$dst, $src}",
3595                      [(alignednontemporalstore (v8f32 VR256:$src),
3596                                                addr:$dst)],
3597                                                IIC_SSE_MOVNT>, VEX, VEX_L, VEX_WIG;
3598 def VMOVNTPDYmr : VPDI<0x2B, MRMDestMem, (outs),
3599                      (ins f256mem:$dst, VR256:$src),
3600                      "movntpd\t{$src, $dst|$dst, $src}",
3601                      [(alignednontemporalstore (v4f64 VR256:$src),
3602                                                addr:$dst)],
3603                                                IIC_SSE_MOVNT>, VEX, VEX_L, VEX_WIG;
3604 let ExeDomain = SSEPackedInt in
3605 def VMOVNTDQYmr : VPDI<0xE7, MRMDestMem, (outs),
3606                     (ins i256mem:$dst, VR256:$src),
3607                     "movntdq\t{$src, $dst|$dst, $src}",
3608                     [(alignednontemporalstore (v4i64 VR256:$src),
3609                                               addr:$dst)],
3610                                               IIC_SSE_MOVNT>, VEX, VEX_L, VEX_WIG;
3611 }
3612
3613 def MOVNTPSmr : PSI<0x2B, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
3614                     "movntps\t{$src, $dst|$dst, $src}",
3615                     [(alignednontemporalstore (v4f32 VR128:$src), addr:$dst)],
3616                     IIC_SSE_MOVNT>;
3617 def MOVNTPDmr : PDI<0x2B, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
3618                     "movntpd\t{$src, $dst|$dst, $src}",
3619                     [(alignednontemporalstore(v2f64 VR128:$src), addr:$dst)],
3620                     IIC_SSE_MOVNT>;
3621
3622 let ExeDomain = SSEPackedInt in
3623 def MOVNTDQmr : PDI<0xE7, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
3624                     "movntdq\t{$src, $dst|$dst, $src}",
3625                     [(alignednontemporalstore (v2i64 VR128:$src), addr:$dst)],
3626                     IIC_SSE_MOVNT>;
3627
3628 // There is no AVX form for instructions below this point
3629 def MOVNTImr : I<0xC3, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
3630                  "movnti{l}\t{$src, $dst|$dst, $src}",
3631                  [(nontemporalstore (i32 GR32:$src), addr:$dst)],
3632                  IIC_SSE_MOVNT>,
3633                PS, Requires<[HasSSE2]>;
3634 def MOVNTI_64mr : RI<0xC3, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
3635                      "movnti{q}\t{$src, $dst|$dst, $src}",
3636                      [(nontemporalstore (i64 GR64:$src), addr:$dst)],
3637                      IIC_SSE_MOVNT>,
3638                   PS, Requires<[HasSSE2]>;
3639 } // SchedRW = [WriteStore]
3640
3641 let Predicates = [HasAVX, NoVLX] in {
3642   def : Pat<(alignednontemporalstore (v8i32 VR256:$src), addr:$dst),
3643             (VMOVNTDQYmr addr:$dst, VR256:$src)>;
3644   def : Pat<(alignednontemporalstore (v16i16 VR256:$src), addr:$dst),
3645             (VMOVNTDQYmr addr:$dst, VR256:$src)>;
3646   def : Pat<(alignednontemporalstore (v32i8 VR256:$src), addr:$dst),
3647             (VMOVNTDQYmr addr:$dst, VR256:$src)>;
3648
3649   def : Pat<(alignednontemporalstore (v4i32 VR128:$src), addr:$dst),
3650             (VMOVNTDQmr addr:$dst, VR128:$src)>;
3651   def : Pat<(alignednontemporalstore (v8i16 VR128:$src), addr:$dst),
3652             (VMOVNTDQmr addr:$dst, VR128:$src)>;
3653   def : Pat<(alignednontemporalstore (v16i8 VR128:$src), addr:$dst),
3654             (VMOVNTDQmr addr:$dst, VR128:$src)>;
3655 }
3656
3657 let Predicates = [UseSSE2] in {
3658   def : Pat<(alignednontemporalstore (v4i32 VR128:$src), addr:$dst),
3659             (MOVNTDQmr addr:$dst, VR128:$src)>;
3660   def : Pat<(alignednontemporalstore (v8i16 VR128:$src), addr:$dst),
3661             (MOVNTDQmr addr:$dst, VR128:$src)>;
3662   def : Pat<(alignednontemporalstore (v16i8 VR128:$src), addr:$dst),
3663             (MOVNTDQmr addr:$dst, VR128:$src)>;
3664 }
3665
3666 } // AddedComplexity
3667
3668 //===----------------------------------------------------------------------===//
3669 // SSE 1 & 2 - Prefetch and memory fence
3670 //===----------------------------------------------------------------------===//
3671
3672 // Prefetch intrinsic.
3673 let Predicates = [HasSSE1], SchedRW = [WriteLoad] in {
3674 def PREFETCHT0   : I<0x18, MRM1m, (outs), (ins i8mem:$src),
3675     "prefetcht0\t$src", [(prefetch addr:$src, imm, (i32 3), (i32 1))],
3676     IIC_SSE_PREFETCH>, TB;
3677 def PREFETCHT1   : I<0x18, MRM2m, (outs), (ins i8mem:$src),
3678     "prefetcht1\t$src", [(prefetch addr:$src, imm, (i32 2), (i32 1))],
3679     IIC_SSE_PREFETCH>, TB;
3680 def PREFETCHT2   : I<0x18, MRM3m, (outs), (ins i8mem:$src),
3681     "prefetcht2\t$src", [(prefetch addr:$src, imm, (i32 1), (i32 1))],
3682     IIC_SSE_PREFETCH>, TB;
3683 def PREFETCHNTA  : I<0x18, MRM0m, (outs), (ins i8mem:$src),
3684     "prefetchnta\t$src", [(prefetch addr:$src, imm, (i32 0), (i32 1))],
3685     IIC_SSE_PREFETCH>, TB;
3686 }
3687
3688 // FIXME: How should flush instruction be modeled?
3689 let SchedRW = [WriteLoad] in {
3690 // Flush cache
3691 def CLFLUSH : I<0xAE, MRM7m, (outs), (ins i8mem:$src),
3692                "clflush\t$src", [(int_x86_sse2_clflush addr:$src)],
3693                IIC_SSE_PREFETCH>, PS, Requires<[HasSSE2]>;
3694 }
3695
3696 let SchedRW = [WriteNop] in {
3697 // Pause. This "instruction" is encoded as "rep; nop", so even though it
3698 // was introduced with SSE2, it's backward compatible.
3699 def PAUSE : I<0x90, RawFrm, (outs), (ins),
3700               "pause", [(int_x86_sse2_pause)], IIC_SSE_PAUSE>, OBXS;
3701 }
3702
3703 let SchedRW = [WriteFence] in {
3704 // Load, store, and memory fence
3705 // TODO: As with mfence, we may want to ease the availablity of sfence/lfence
3706 // to include any 64-bit target.
3707 def SFENCE : I<0xAE, MRM_F8, (outs), (ins),
3708                "sfence", [(int_x86_sse_sfence)], IIC_SSE_SFENCE>,
3709                PS, Requires<[HasSSE1]>;
3710 def LFENCE : I<0xAE, MRM_E8, (outs), (ins),
3711                "lfence", [(int_x86_sse2_lfence)], IIC_SSE_LFENCE>,
3712                TB, Requires<[HasSSE2]>;
3713 def MFENCE : I<0xAE, MRM_F0, (outs), (ins),
3714                "mfence", [(int_x86_sse2_mfence)], IIC_SSE_MFENCE>,
3715                TB, Requires<[HasMFence]>;
3716 } // SchedRW
3717
3718 def : Pat<(X86MFence), (MFENCE)>;
3719
3720 //===----------------------------------------------------------------------===//
3721 // SSE 1 & 2 - Load/Store XCSR register
3722 //===----------------------------------------------------------------------===//
3723
3724 def VLDMXCSR : VPSI<0xAE, MRM2m, (outs), (ins i32mem:$src),
3725                "ldmxcsr\t$src", [(int_x86_sse_ldmxcsr addr:$src)],
3726                IIC_SSE_LDMXCSR>, VEX, Sched<[WriteLoad]>, VEX_WIG;
3727 def VSTMXCSR : VPSI<0xAE, MRM3m, (outs), (ins i32mem:$dst),
3728                "stmxcsr\t$dst", [(int_x86_sse_stmxcsr addr:$dst)],
3729                IIC_SSE_STMXCSR>, VEX, Sched<[WriteStore]>, VEX_WIG;
3730
3731 def LDMXCSR : I<0xAE, MRM2m, (outs), (ins i32mem:$src),
3732               "ldmxcsr\t$src", [(int_x86_sse_ldmxcsr addr:$src)],
3733               IIC_SSE_LDMXCSR>, TB, Sched<[WriteLoad]>;
3734 def STMXCSR : I<0xAE, MRM3m, (outs), (ins i32mem:$dst),
3735               "stmxcsr\t$dst", [(int_x86_sse_stmxcsr addr:$dst)],
3736               IIC_SSE_STMXCSR>, TB, Sched<[WriteStore]>;
3737
3738 //===---------------------------------------------------------------------===//
3739 // SSE2 - Move Aligned/Unaligned Packed Integer Instructions
3740 //===---------------------------------------------------------------------===//
3741
3742 let ExeDomain = SSEPackedInt in { // SSE integer instructions
3743
3744 let hasSideEffects = 0, SchedRW = [WriteMove] in {
3745 def VMOVDQArr  : VPDI<0x6F, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3746                     "movdqa\t{$src, $dst|$dst, $src}", [], IIC_SSE_MOVA_P_RR>,
3747                     VEX, VEX_WIG;
3748 def VMOVDQAYrr : VPDI<0x6F, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
3749                     "movdqa\t{$src, $dst|$dst, $src}", [], IIC_SSE_MOVA_P_RR>,
3750                     VEX, VEX_L, VEX_WIG;
3751 def VMOVDQUrr  : VSSI<0x6F, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3752                     "movdqu\t{$src, $dst|$dst, $src}", [], IIC_SSE_MOVU_P_RR>,
3753                     VEX, VEX_WIG;
3754 def VMOVDQUYrr : VSSI<0x6F, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
3755                     "movdqu\t{$src, $dst|$dst, $src}", [], IIC_SSE_MOVU_P_RR>,
3756                     VEX, VEX_L, VEX_WIG;
3757 }
3758
3759 // For Disassembler
3760 let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0,
3761     SchedRW = [WriteMove] in {
3762 def VMOVDQArr_REV  : VPDI<0x7F, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
3763                         "movdqa\t{$src, $dst|$dst, $src}", [],
3764                         IIC_SSE_MOVA_P_RR>,
3765                         VEX, VEX_WIG, FoldGenData<"VMOVDQArr">;
3766 def VMOVDQAYrr_REV : VPDI<0x7F, MRMDestReg, (outs VR256:$dst), (ins VR256:$src),
3767                         "movdqa\t{$src, $dst|$dst, $src}", [],
3768                         IIC_SSE_MOVA_P_RR>, VEX, VEX_L, VEX_WIG,
3769                         FoldGenData<"VMOVDQAYrr">;
3770 def VMOVDQUrr_REV  : VSSI<0x7F, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
3771                         "movdqu\t{$src, $dst|$dst, $src}", [],
3772                         IIC_SSE_MOVU_P_RR>,
3773                         VEX, VEX_WIG, FoldGenData<"VMOVDQUrr">;
3774 def VMOVDQUYrr_REV : VSSI<0x7F, MRMDestReg, (outs VR256:$dst), (ins VR256:$src),
3775                         "movdqu\t{$src, $dst|$dst, $src}", [],
3776                         IIC_SSE_MOVU_P_RR>, VEX, VEX_L, VEX_WIG,
3777                         FoldGenData<"VMOVDQUYrr">;
3778 }
3779
3780 let canFoldAsLoad = 1, mayLoad = 1, isReMaterializable = 1,
3781     hasSideEffects = 0, SchedRW = [WriteLoad] in {
3782 let Predicates = [HasAVX,NoVLX] in
3783 def VMOVDQArm  : VPDI<0x6F, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
3784                    "movdqa\t{$src, $dst|$dst, $src}",
3785                    [(set VR128:$dst, (alignedloadv2i64 addr:$src))],
3786                    IIC_SSE_MOVA_P_RM>, VEX, VEX_WIG;
3787 def VMOVDQAYrm : VPDI<0x6F, MRMSrcMem, (outs VR256:$dst), (ins i256mem:$src),
3788                    "movdqa\t{$src, $dst|$dst, $src}", [], IIC_SSE_MOVA_P_RM>,
3789                    VEX, VEX_L, VEX_WIG;
3790 let Predicates = [HasAVX,NoVLX] in
3791 def VMOVDQUrm  : I<0x6F, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
3792                   "vmovdqu\t{$src, $dst|$dst, $src}",
3793                   [(set VR128:$dst, (loadv2i64 addr:$src))],
3794                   IIC_SSE_MOVU_P_RM>, XS, VEX, VEX_WIG;
3795 def VMOVDQUYrm : I<0x6F, MRMSrcMem, (outs VR256:$dst), (ins i256mem:$src),
3796                   "vmovdqu\t{$src, $dst|$dst, $src}",[], IIC_SSE_MOVU_P_RM>,
3797                   XS, VEX, VEX_L, VEX_WIG;
3798 }
3799
3800 let mayStore = 1, hasSideEffects = 0, SchedRW = [WriteStore] in {
3801 let Predicates = [HasAVX,NoVLX] in
3802 def VMOVDQAmr  : VPDI<0x7F, MRMDestMem, (outs),
3803                      (ins i128mem:$dst, VR128:$src),
3804                      "movdqa\t{$src, $dst|$dst, $src}",
3805                      [(alignedstore (v2i64 VR128:$src), addr:$dst)],
3806                      IIC_SSE_MOVA_P_MR>, VEX, VEX_WIG;
3807 def VMOVDQAYmr : VPDI<0x7F, MRMDestMem, (outs),
3808                      (ins i256mem:$dst, VR256:$src),
3809                      "movdqa\t{$src, $dst|$dst, $src}", [], IIC_SSE_MOVA_P_MR>,
3810                      VEX, VEX_L, VEX_WIG;
3811 let Predicates = [HasAVX,NoVLX] in
3812 def VMOVDQUmr  : I<0x7F, MRMDestMem, (outs), (ins i128mem:$dst, VR128:$src),
3813                   "vmovdqu\t{$src, $dst|$dst, $src}",
3814                   [(store (v2i64 VR128:$src), addr:$dst)], IIC_SSE_MOVU_P_MR>,
3815                   XS, VEX, VEX_WIG;
3816 def VMOVDQUYmr : I<0x7F, MRMDestMem, (outs), (ins i256mem:$dst, VR256:$src),
3817                   "vmovdqu\t{$src, $dst|$dst, $src}",[], IIC_SSE_MOVU_P_MR>,
3818                   XS, VEX, VEX_L, VEX_WIG;
3819 }
3820
3821 let SchedRW = [WriteMove] in {
3822 let hasSideEffects = 0 in {
3823 def MOVDQArr : PDI<0x6F, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3824                    "movdqa\t{$src, $dst|$dst, $src}", [], IIC_SSE_MOVA_P_RR>;
3825
3826 def MOVDQUrr :   I<0x6F, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3827                    "movdqu\t{$src, $dst|$dst, $src}",
3828                    [], IIC_SSE_MOVU_P_RR>, XS, Requires<[UseSSE2]>;
3829 }
3830
3831 // For Disassembler
3832 let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0 in {
3833 def MOVDQArr_REV : PDI<0x7F, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
3834                        "movdqa\t{$src, $dst|$dst, $src}", [],
3835                        IIC_SSE_MOVA_P_RR>, FoldGenData<"MOVDQArr">;
3836
3837 def MOVDQUrr_REV :   I<0x7F, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
3838                        "movdqu\t{$src, $dst|$dst, $src}",
3839                        [], IIC_SSE_MOVU_P_RR>, XS, Requires<[UseSSE2]>,
3840                        FoldGenData<"MOVDQUrr">;
3841 }
3842 } // SchedRW
3843
3844 let canFoldAsLoad = 1, mayLoad = 1, isReMaterializable = 1,
3845     hasSideEffects = 0, SchedRW = [WriteLoad] in {
3846 def MOVDQArm : PDI<0x6F, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
3847                    "movdqa\t{$src, $dst|$dst, $src}",
3848                    [/*(set VR128:$dst, (alignedloadv2i64 addr:$src))*/],
3849                    IIC_SSE_MOVA_P_RM>;
3850 def MOVDQUrm :   I<0x6F, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
3851                    "movdqu\t{$src, $dst|$dst, $src}",
3852                    [/*(set VR128:$dst, (loadv2i64 addr:$src))*/],
3853                    IIC_SSE_MOVU_P_RM>,
3854                  XS, Requires<[UseSSE2]>;
3855 }
3856
3857 let mayStore = 1, hasSideEffects = 0, SchedRW = [WriteStore] in {
3858 def MOVDQAmr : PDI<0x7F, MRMDestMem, (outs), (ins i128mem:$dst, VR128:$src),
3859                    "movdqa\t{$src, $dst|$dst, $src}",
3860                    [/*(alignedstore (v2i64 VR128:$src), addr:$dst)*/],
3861                    IIC_SSE_MOVA_P_MR>;
3862 def MOVDQUmr :   I<0x7F, MRMDestMem, (outs), (ins i128mem:$dst, VR128:$src),
3863                    "movdqu\t{$src, $dst|$dst, $src}",
3864                    [/*(store (v2i64 VR128:$src), addr:$dst)*/],
3865                    IIC_SSE_MOVU_P_MR>,
3866                  XS, Requires<[UseSSE2]>;
3867 }
3868
3869 } // ExeDomain = SSEPackedInt
3870
3871 // Aliases to help the assembler pick two byte VEX encodings by swapping the
3872 // operands relative to the normal instructions to use VEX.R instead of VEX.B.
3873 def : InstAlias<"vmovdqa\t{$src, $dst|$dst, $src}",
3874                 (VMOVDQArr_REV VR128L:$dst, VR128H:$src), 0>;
3875 def : InstAlias<"vmovdqa\t{$src, $dst|$dst, $src}",
3876                 (VMOVDQAYrr_REV VR256L:$dst, VR256H:$src), 0>;
3877 def : InstAlias<"vmovdqu\t{$src, $dst|$dst, $src}",
3878                 (VMOVDQUrr_REV VR128L:$dst, VR128H:$src), 0>;
3879 def : InstAlias<"vmovdqu\t{$src, $dst|$dst, $src}",
3880                 (VMOVDQUYrr_REV VR256L:$dst, VR256H:$src), 0>;
3881
3882 let Predicates = [HasAVX, NoVLX] in {
3883   // Additional patterns for other integer sizes.
3884   def : Pat<(alignedstore (v4i32 VR128:$src), addr:$dst),
3885             (VMOVDQAmr addr:$dst, VR128:$src)>;
3886   def : Pat<(alignedstore (v8i16 VR128:$src), addr:$dst),
3887             (VMOVDQAmr addr:$dst, VR128:$src)>;
3888   def : Pat<(alignedstore (v16i8 VR128:$src), addr:$dst),
3889             (VMOVDQAmr addr:$dst, VR128:$src)>;
3890   def : Pat<(store (v4i32 VR128:$src), addr:$dst),
3891             (VMOVDQUmr addr:$dst, VR128:$src)>;
3892   def : Pat<(store (v8i16 VR128:$src), addr:$dst),
3893             (VMOVDQUmr addr:$dst, VR128:$src)>;
3894   def : Pat<(store (v16i8 VR128:$src), addr:$dst),
3895             (VMOVDQUmr addr:$dst, VR128:$src)>;
3896
3897   // Special patterns for storing subvector extracts of lower 128-bits
3898   // Its cheaper to just use VMOVDQA/VMOVDQU instead of VEXTRACTF128mr
3899   def : Pat<(alignedstore (v2i64 (extract_subvector
3900                                   (v4i64 VR256:$src), (iPTR 0))), addr:$dst),
3901             (VMOVDQAmr addr:$dst, (v2i64 (EXTRACT_SUBREG VR256:$src,sub_xmm)))>;
3902   def : Pat<(alignedstore (v4i32 (extract_subvector
3903                                   (v8i32 VR256:$src), (iPTR 0))), addr:$dst),
3904             (VMOVDQAmr addr:$dst, (v4i32 (EXTRACT_SUBREG VR256:$src,sub_xmm)))>;
3905   def : Pat<(alignedstore (v8i16 (extract_subvector
3906                                   (v16i16 VR256:$src), (iPTR 0))), addr:$dst),
3907             (VMOVDQAmr addr:$dst, (v8i16 (EXTRACT_SUBREG VR256:$src,sub_xmm)))>;
3908   def : Pat<(alignedstore (v16i8 (extract_subvector
3909                                   (v32i8 VR256:$src), (iPTR 0))), addr:$dst),
3910             (VMOVDQAmr addr:$dst, (v16i8 (EXTRACT_SUBREG VR256:$src,sub_xmm)))>;
3911
3912   def : Pat<(store (v2i64 (extract_subvector
3913                            (v4i64 VR256:$src), (iPTR 0))), addr:$dst),
3914             (VMOVDQUmr addr:$dst, (v2i64 (EXTRACT_SUBREG VR256:$src,sub_xmm)))>;
3915   def : Pat<(store (v4i32 (extract_subvector
3916                            (v8i32 VR256:$src), (iPTR 0))), addr:$dst),
3917             (VMOVDQUmr addr:$dst, (v4i32 (EXTRACT_SUBREG VR256:$src,sub_xmm)))>;
3918   def : Pat<(store (v8i16 (extract_subvector
3919                            (v16i16 VR256:$src), (iPTR 0))), addr:$dst),
3920             (VMOVDQUmr addr:$dst, (v8i16 (EXTRACT_SUBREG VR256:$src,sub_xmm)))>;
3921   def : Pat<(store (v16i8 (extract_subvector
3922                            (v32i8 VR256:$src), (iPTR 0))), addr:$dst),
3923             (VMOVDQUmr addr:$dst, (v16i8 (EXTRACT_SUBREG VR256:$src,sub_xmm)))>;
3924 }
3925
3926 //===---------------------------------------------------------------------===//
3927 // SSE2 - Packed Integer Arithmetic Instructions
3928 //===---------------------------------------------------------------------===//
3929
3930 let Sched = WriteVecIMul in
3931 def SSE_PMADD : OpndItins<
3932   IIC_SSE_PMADD, IIC_SSE_PMADD
3933 >;
3934
3935 let ExeDomain = SSEPackedInt in { // SSE integer instructions
3936
3937 /// PDI_binop_rm2 - Simple SSE2 binary operator with different src and dst types
3938 multiclass PDI_binop_rm2<bits<8> opc, string OpcodeStr, SDNode OpNode,
3939                          ValueType DstVT, ValueType SrcVT, RegisterClass RC,
3940                          PatFrag memop_frag, X86MemOperand x86memop,
3941                          OpndItins itins, bit Is2Addr = 1> {
3942   let isCommutable = 1 in
3943   def rr : PDI<opc, MRMSrcReg, (outs RC:$dst),
3944        (ins RC:$src1, RC:$src2),
3945        !if(Is2Addr,
3946            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
3947            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
3948        [(set RC:$dst, (DstVT (OpNode (SrcVT RC:$src1), RC:$src2)))]>,
3949        Sched<[itins.Sched]>;
3950   def rm : PDI<opc, MRMSrcMem, (outs RC:$dst),
3951        (ins RC:$src1, x86memop:$src2),
3952        !if(Is2Addr,
3953            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
3954            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
3955        [(set RC:$dst, (DstVT (OpNode (SrcVT RC:$src1),
3956                                      (bitconvert (memop_frag addr:$src2)))))]>,
3957        Sched<[itins.Sched.Folded, ReadAfterLd]>;
3958 }
3959 } // ExeDomain = SSEPackedInt
3960
3961 defm PADDB   : PDI_binop_all<0xFC, "paddb", add, v16i8, v32i8,
3962                              SSE_INTALU_ITINS_P, 1, NoVLX_Or_NoBWI>;
3963 defm PADDW   : PDI_binop_all<0xFD, "paddw", add, v8i16, v16i16,
3964                              SSE_INTALU_ITINS_P, 1, NoVLX_Or_NoBWI>;
3965 defm PADDD   : PDI_binop_all<0xFE, "paddd", add, v4i32, v8i32,
3966                              SSE_INTALU_ITINS_P, 1, NoVLX>;
3967 defm PADDQ   : PDI_binop_all<0xD4, "paddq", add, v2i64, v4i64,
3968                              SSE_INTALUQ_ITINS_P, 1, NoVLX>;
3969 defm PADDSB  : PDI_binop_all<0xEC, "paddsb", X86adds, v16i8, v32i8,
3970                              SSE_INTALU_ITINS_P, 1, NoVLX_Or_NoBWI>;
3971 defm PADDSW  : PDI_binop_all<0xED, "paddsw", X86adds, v8i16, v16i16,
3972                              SSE_INTALU_ITINS_P, 1, NoVLX_Or_NoBWI>;
3973 defm PADDUSB : PDI_binop_all<0xDC, "paddusb", X86addus, v16i8, v32i8,
3974                              SSE_INTALU_ITINS_P, 1, NoVLX_Or_NoBWI>;
3975 defm PADDUSW : PDI_binop_all<0xDD, "paddusw", X86addus, v8i16, v16i16,
3976                              SSE_INTALU_ITINS_P, 1, NoVLX_Or_NoBWI>;
3977 defm PMULLW  : PDI_binop_all<0xD5, "pmullw", mul, v8i16, v16i16,
3978                              SSE_INTMUL_ITINS_P, 1, NoVLX_Or_NoBWI>;
3979 defm PMULHUW : PDI_binop_all<0xE4, "pmulhuw", mulhu, v8i16, v16i16,
3980                              SSE_INTMUL_ITINS_P, 1, NoVLX_Or_NoBWI>;
3981 defm PMULHW  : PDI_binop_all<0xE5, "pmulhw", mulhs, v8i16, v16i16,
3982                              SSE_INTMUL_ITINS_P, 1, NoVLX_Or_NoBWI>;
3983 defm PSUBB   : PDI_binop_all<0xF8, "psubb", sub, v16i8, v32i8,
3984                              SSE_INTALU_ITINS_P, 0, NoVLX_Or_NoBWI>;
3985 defm PSUBW   : PDI_binop_all<0xF9, "psubw", sub, v8i16, v16i16,
3986                              SSE_INTALU_ITINS_P, 0, NoVLX_Or_NoBWI>;
3987 defm PSUBD   : PDI_binop_all<0xFA, "psubd", sub, v4i32, v8i32,
3988                              SSE_INTALU_ITINS_P, 0, NoVLX>;
3989 defm PSUBQ   : PDI_binop_all<0xFB, "psubq", sub, v2i64, v4i64,
3990                              SSE_INTALUQ_ITINS_P, 0, NoVLX>;
3991 defm PSUBSB  : PDI_binop_all<0xE8, "psubsb", X86subs, v16i8, v32i8,
3992                              SSE_INTALU_ITINS_P, 0, NoVLX_Or_NoBWI>;
3993 defm PSUBSW  : PDI_binop_all<0xE9, "psubsw", X86subs, v8i16, v16i16,
3994                              SSE_INTALU_ITINS_P, 0, NoVLX_Or_NoBWI>;
3995 defm PSUBUSB : PDI_binop_all<0xD8, "psubusb", X86subus, v16i8, v32i8,
3996                              SSE_INTALU_ITINS_P, 0, NoVLX_Or_NoBWI>;
3997 defm PSUBUSW : PDI_binop_all<0xD9, "psubusw", X86subus, v8i16, v16i16,
3998                              SSE_INTALU_ITINS_P, 0, NoVLX_Or_NoBWI>;
3999 defm PMINUB  : PDI_binop_all<0xDA, "pminub", umin, v16i8, v32i8,
4000                              SSE_INTALU_ITINS_P, 1, NoVLX_Or_NoBWI>;
4001 defm PMINSW  : PDI_binop_all<0xEA, "pminsw", smin, v8i16, v16i16,
4002                              SSE_INTALU_ITINS_P, 1, NoVLX_Or_NoBWI>;
4003 defm PMAXUB  : PDI_binop_all<0xDE, "pmaxub", umax, v16i8, v32i8,
4004                              SSE_INTALU_ITINS_P, 1, NoVLX_Or_NoBWI>;
4005 defm PMAXSW  : PDI_binop_all<0xEE, "pmaxsw", smax, v8i16, v16i16,
4006                              SSE_INTALU_ITINS_P, 1, NoVLX_Or_NoBWI>;
4007 defm PAVGB   : PDI_binop_all<0xE0, "pavgb", X86avg, v16i8, v32i8,
4008                              SSE_INTALU_ITINS_P, 1, NoVLX_Or_NoBWI>;
4009 defm PAVGW   : PDI_binop_all<0xE3, "pavgw", X86avg, v8i16, v16i16,
4010                              SSE_INTALU_ITINS_P, 1, NoVLX_Or_NoBWI>;
4011
4012 let Predicates = [HasAVX, NoVLX_Or_NoBWI] in
4013 defm VPMADDWD : PDI_binop_rm2<0xF5, "vpmaddwd", X86vpmaddwd, v4i32, v8i16, VR128,
4014                               loadv2i64, i128mem, SSE_PMADD, 0>, VEX_4V, VEX_WIG;
4015
4016 let Predicates = [HasAVX2, NoVLX_Or_NoBWI] in
4017 defm VPMADDWDY : PDI_binop_rm2<0xF5, "vpmaddwd", X86vpmaddwd, v8i32, v16i16,
4018                                VR256, loadv4i64, i256mem, SSE_PMADD,
4019                                0>, VEX_4V, VEX_L, VEX_WIG;
4020 let Constraints = "$src1 = $dst" in
4021 defm PMADDWD : PDI_binop_rm2<0xF5, "pmaddwd", X86vpmaddwd, v4i32, v8i16, VR128,
4022                              memopv2i64, i128mem, SSE_PMADD>;
4023
4024 let Predicates = [HasAVX, NoVLX_Or_NoBWI] in
4025 defm VPSADBW : PDI_binop_rm2<0xF6, "vpsadbw", X86psadbw, v2i64, v16i8, VR128,
4026                              loadv2i64, i128mem, SSE_INTMUL_ITINS_P, 0>,
4027                              VEX_4V, VEX_WIG;
4028 let Predicates = [HasAVX2, NoVLX_Or_NoBWI] in
4029 defm VPSADBWY : PDI_binop_rm2<0xF6, "vpsadbw", X86psadbw, v4i64, v32i8, VR256,
4030                              loadv4i64, i256mem, SSE_INTMUL_ITINS_P, 0>,
4031                              VEX_4V, VEX_L, VEX_WIG;
4032 let Constraints = "$src1 = $dst" in
4033 defm PSADBW : PDI_binop_rm2<0xF6, "psadbw", X86psadbw, v2i64, v16i8, VR128,
4034                             memopv2i64, i128mem, SSE_INTALU_ITINS_P>;
4035
4036 let Predicates = [HasAVX, NoVLX] in
4037 defm VPMULUDQ : PDI_binop_rm2<0xF4, "vpmuludq", X86pmuludq, v2i64, v4i32, VR128,
4038                               loadv2i64, i128mem, SSE_INTMUL_ITINS_P, 0>,
4039                               VEX_4V, VEX_WIG;
4040 let Predicates = [HasAVX2, NoVLX] in
4041 defm VPMULUDQY : PDI_binop_rm2<0xF4, "vpmuludq", X86pmuludq, v4i64, v8i32,
4042                                VR256, loadv4i64, i256mem,
4043                                SSE_INTMUL_ITINS_P, 0>, VEX_4V, VEX_L, VEX_WIG;
4044 let Constraints = "$src1 = $dst" in
4045 defm PMULUDQ : PDI_binop_rm2<0xF4, "pmuludq", X86pmuludq, v2i64, v4i32, VR128,
4046                              memopv2i64, i128mem, SSE_INTMUL_ITINS_P>;
4047
4048 //===---------------------------------------------------------------------===//
4049 // SSE2 - Packed Integer Logical Instructions
4050 //===---------------------------------------------------------------------===//
4051
4052 multiclass PDI_binop_rmi<bits<8> opc, bits<8> opc2, Format ImmForm,
4053                          string OpcodeStr, SDNode OpNode,
4054                          SDNode OpNode2, RegisterClass RC,
4055                          ValueType DstVT, ValueType SrcVT,
4056                          PatFrag ld_frag, bit Is2Addr = 1> {
4057   // src2 is always 128-bit
4058   def rr : PDI<opc, MRMSrcReg, (outs RC:$dst),
4059        (ins RC:$src1, VR128:$src2),
4060        !if(Is2Addr,
4061            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
4062            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
4063        [(set RC:$dst, (DstVT (OpNode RC:$src1, (SrcVT VR128:$src2))))],
4064        SSE_INTSHIFT_ITINS_P.rr>, Sched<[WriteVecShift]>;
4065   def rm : PDI<opc, MRMSrcMem, (outs RC:$dst),
4066        (ins RC:$src1, i128mem:$src2),
4067        !if(Is2Addr,
4068            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
4069            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
4070        [(set RC:$dst, (DstVT (OpNode RC:$src1,
4071                        (SrcVT (bitconvert (ld_frag addr:$src2))))))],
4072        SSE_INTSHIFT_ITINS_P.rm>, Sched<[WriteVecShiftLd, ReadAfterLd]>;
4073   def ri : PDIi8<opc2, ImmForm, (outs RC:$dst),
4074        (ins RC:$src1, u8imm:$src2),
4075        !if(Is2Addr,
4076            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
4077            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
4078        [(set RC:$dst, (DstVT (OpNode2 RC:$src1, (i8 imm:$src2))))],
4079        SSE_INTSHIFT_ITINS_P.ri>, Sched<[WriteVecShift]>;
4080 }
4081
4082 multiclass PDI_binop_rmi_all<bits<8> opc, bits<8> opc2, Format ImmForm,
4083                              string OpcodeStr, SDNode OpNode,
4084                              SDNode OpNode2, ValueType DstVT128,
4085                              ValueType DstVT256, ValueType SrcVT,
4086                              Predicate prd> {
4087 let Predicates = [HasAVX, prd] in
4088   defm V#NAME : PDI_binop_rmi<opc, opc2, ImmForm, !strconcat("v", OpcodeStr),
4089                               OpNode, OpNode2, VR128, DstVT128, SrcVT,
4090                               loadv2i64, 0>, VEX_4V, VEX_WIG;
4091 let Predicates = [HasAVX2, prd] in
4092   defm V#NAME#Y : PDI_binop_rmi<opc, opc2, ImmForm, !strconcat("v", OpcodeStr),
4093                                 OpNode, OpNode2, VR256, DstVT256, SrcVT,
4094                                 loadv2i64, 0>, VEX_4V, VEX_L, VEX_WIG;
4095 let Constraints = "$src1 = $dst" in
4096   defm NAME : PDI_binop_rmi<opc, opc2, ImmForm, OpcodeStr, OpNode, OpNode2,
4097                            VR128, DstVT128, SrcVT, memopv2i64>;
4098 }
4099
4100 multiclass PDI_binop_ri<bits<8> opc, Format ImmForm, string OpcodeStr,
4101                         SDNode OpNode, RegisterClass RC, ValueType VT,
4102                         bit Is2Addr = 1> {
4103   def ri : PDIi8<opc, ImmForm, (outs RC:$dst), (ins RC:$src1, u8imm:$src2),
4104        !if(Is2Addr,
4105            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
4106            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
4107        [(set RC:$dst, (VT (OpNode RC:$src1, (i8 imm:$src2))))],
4108        IIC_SSE_INTSHDQ_P_RI>, Sched<[WriteVecShift]>;
4109 }
4110
4111 multiclass PDI_binop_ri_all<bits<8> opc, Format ImmForm, string OpcodeStr,
4112                            SDNode OpNode> {
4113 let Predicates = [HasAVX, NoVLX_Or_NoBWI] in
4114   defm V#NAME : PDI_binop_ri<opc, ImmForm, !strconcat("v", OpcodeStr), OpNode,
4115                              VR128, v16i8, 0>, VEX_4V, VEX_WIG;
4116 let Predicates = [HasAVX2, NoVLX_Or_NoBWI] in
4117   defm V#NAME#Y : PDI_binop_ri<opc, ImmForm, !strconcat("v", OpcodeStr), OpNode,
4118                                VR256, v32i8, 0>, VEX_4V, VEX_L, VEX_WIG;
4119 let Constraints = "$src1 = $dst" in
4120   defm NAME : PDI_binop_ri<opc, ImmForm, OpcodeStr, OpNode, VR128, v16i8>;
4121 }
4122
4123 let ExeDomain = SSEPackedInt in {
4124   defm PSLLW : PDI_binop_rmi_all<0xF1, 0x71, MRM6r, "psllw", X86vshl, X86vshli,
4125                                  v8i16, v16i16, v8i16, NoVLX_Or_NoBWI>;
4126   defm PSLLD : PDI_binop_rmi_all<0xF2, 0x72, MRM6r, "pslld", X86vshl, X86vshli,
4127                                  v4i32, v8i32, v4i32, NoVLX>;
4128   defm PSLLQ : PDI_binop_rmi_all<0xF3, 0x73, MRM6r, "psllq", X86vshl, X86vshli,
4129                                  v2i64, v4i64, v2i64, NoVLX>;
4130
4131   defm PSRLW : PDI_binop_rmi_all<0xD1, 0x71, MRM2r, "psrlw", X86vsrl, X86vsrli,
4132                                  v8i16, v16i16, v8i16, NoVLX_Or_NoBWI>;
4133   defm PSRLD : PDI_binop_rmi_all<0xD2, 0x72, MRM2r, "psrld", X86vsrl, X86vsrli,
4134                                  v4i32, v8i32, v4i32, NoVLX>;
4135   defm PSRLQ : PDI_binop_rmi_all<0xD3, 0x73, MRM2r, "psrlq", X86vsrl, X86vsrli,
4136                                  v2i64, v4i64, v2i64, NoVLX>;
4137
4138   defm PSRAW : PDI_binop_rmi_all<0xE1, 0x71, MRM4r, "psraw", X86vsra, X86vsrai,
4139                                  v8i16, v16i16, v8i16, NoVLX_Or_NoBWI>;
4140   defm PSRAD : PDI_binop_rmi_all<0xE2, 0x72, MRM4r, "psrad", X86vsra, X86vsrai,
4141                                  v4i32, v8i32, v4i32, NoVLX>;
4142
4143   defm PSLLDQ : PDI_binop_ri_all<0x73, MRM7r, "pslldq", X86vshldq>;
4144   defm PSRLDQ : PDI_binop_ri_all<0x73, MRM3r, "psrldq", X86vshrdq>;
4145   // PSRADQri doesn't exist in SSE[1-3].
4146 } // ExeDomain = SSEPackedInt
4147
4148 //===---------------------------------------------------------------------===//
4149 // SSE2 - Packed Integer Comparison Instructions
4150 //===---------------------------------------------------------------------===//
4151
4152 defm PCMPEQB : PDI_binop_all<0x74, "pcmpeqb", X86pcmpeq, v16i8, v32i8,
4153                              SSE_INTALU_ITINS_P, 1, TruePredicate>;
4154 defm PCMPEQW : PDI_binop_all<0x75, "pcmpeqw", X86pcmpeq, v8i16, v16i16,
4155                              SSE_INTALU_ITINS_P, 1, TruePredicate>;
4156 defm PCMPEQD : PDI_binop_all<0x76, "pcmpeqd", X86pcmpeq, v4i32, v8i32,
4157                              SSE_INTALU_ITINS_P, 1, TruePredicate>;
4158 defm PCMPGTB : PDI_binop_all<0x64, "pcmpgtb", X86pcmpgt, v16i8, v32i8,
4159                              SSE_INTALU_ITINS_P, 0, TruePredicate>;
4160 defm PCMPGTW : PDI_binop_all<0x65, "pcmpgtw", X86pcmpgt, v8i16, v16i16,
4161                              SSE_INTALU_ITINS_P, 0, TruePredicate>;
4162 defm PCMPGTD : PDI_binop_all<0x66, "pcmpgtd", X86pcmpgt, v4i32, v8i32,
4163                              SSE_INTALU_ITINS_P, 0, TruePredicate>;
4164
4165 //===---------------------------------------------------------------------===//
4166 // SSE2 - Packed Integer Shuffle Instructions
4167 //===---------------------------------------------------------------------===//
4168
4169 let ExeDomain = SSEPackedInt in {
4170 multiclass sse2_pshuffle<string OpcodeStr, ValueType vt128, ValueType vt256,
4171                          SDNode OpNode, Predicate prd> {
4172 let Predicates = [HasAVX, prd] in {
4173   def V#NAME#ri : Ii8<0x70, MRMSrcReg, (outs VR128:$dst),
4174                       (ins VR128:$src1, u8imm:$src2),
4175                       !strconcat("v", OpcodeStr,
4176                                  "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4177                       [(set VR128:$dst,
4178                         (vt128 (OpNode VR128:$src1, (i8 imm:$src2))))],
4179                       IIC_SSE_PSHUF_RI>, VEX, Sched<[WriteShuffle]>, VEX_WIG;
4180   def V#NAME#mi : Ii8<0x70, MRMSrcMem, (outs VR128:$dst),
4181                       (ins i128mem:$src1, u8imm:$src2),
4182                       !strconcat("v", OpcodeStr,
4183                                  "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4184                      [(set VR128:$dst,
4185                        (vt128 (OpNode (bitconvert (loadv2i64 addr:$src1)),
4186                         (i8 imm:$src2))))], IIC_SSE_PSHUF_MI>, VEX,
4187                   Sched<[WriteShuffleLd]>, VEX_WIG;
4188 }
4189
4190 let Predicates = [HasAVX2, prd] in {
4191   def V#NAME#Yri : Ii8<0x70, MRMSrcReg, (outs VR256:$dst),
4192                        (ins VR256:$src1, u8imm:$src2),
4193                        !strconcat("v", OpcodeStr,
4194                                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4195                        [(set VR256:$dst,
4196                          (vt256 (OpNode VR256:$src1, (i8 imm:$src2))))],
4197                        IIC_SSE_PSHUF_RI>, VEX, VEX_L, Sched<[WriteShuffle]>, VEX_WIG;
4198   def V#NAME#Ymi : Ii8<0x70, MRMSrcMem, (outs VR256:$dst),
4199                        (ins i256mem:$src1, u8imm:$src2),
4200                        !strconcat("v", OpcodeStr,
4201                                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4202                       [(set VR256:$dst,
4203                         (vt256 (OpNode (bitconvert (loadv4i64 addr:$src1)),
4204                          (i8 imm:$src2))))], IIC_SSE_PSHUF_MI>, VEX, VEX_L,
4205                    Sched<[WriteShuffleLd]>, VEX_WIG;
4206 }
4207
4208 let Predicates = [UseSSE2] in {
4209   def ri : Ii8<0x70, MRMSrcReg,
4210                (outs VR128:$dst), (ins VR128:$src1, u8imm:$src2),
4211                !strconcat(OpcodeStr,
4212                           "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4213                 [(set VR128:$dst,
4214                   (vt128 (OpNode VR128:$src1, (i8 imm:$src2))))],
4215                 IIC_SSE_PSHUF_RI>, Sched<[WriteShuffle]>;
4216   def mi : Ii8<0x70, MRMSrcMem,
4217                (outs VR128:$dst), (ins i128mem:$src1, u8imm:$src2),
4218                !strconcat(OpcodeStr,
4219                           "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4220                 [(set VR128:$dst,
4221                   (vt128 (OpNode (bitconvert (memopv2i64 addr:$src1)),
4222                           (i8 imm:$src2))))], IIC_SSE_PSHUF_MI>,
4223            Sched<[WriteShuffleLd, ReadAfterLd]>;
4224 }
4225 }
4226 } // ExeDomain = SSEPackedInt
4227
4228 defm PSHUFD  : sse2_pshuffle<"pshufd", v4i32, v8i32, X86PShufd, NoVLX>, PD;
4229 defm PSHUFHW : sse2_pshuffle<"pshufhw", v8i16, v16i16, X86PShufhw,
4230                              NoVLX_Or_NoBWI>, XS;
4231 defm PSHUFLW : sse2_pshuffle<"pshuflw", v8i16, v16i16, X86PShuflw,
4232                              NoVLX_Or_NoBWI>, XD;
4233
4234 //===---------------------------------------------------------------------===//
4235 // Packed Integer Pack Instructions (SSE & AVX)
4236 //===---------------------------------------------------------------------===//
4237
4238 let ExeDomain = SSEPackedInt in {
4239 multiclass sse2_pack<bits<8> opc, string OpcodeStr, ValueType OutVT,
4240                      ValueType ArgVT, SDNode OpNode, PatFrag ld_frag,
4241                      bit Is2Addr = 1> {
4242   def rr : PDI<opc, MRMSrcReg,
4243                (outs VR128:$dst), (ins VR128:$src1, VR128:$src2),
4244                !if(Is2Addr,
4245                    !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
4246                    !strconcat(OpcodeStr,
4247                               "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
4248                [(set VR128:$dst,
4249                      (OutVT (OpNode (ArgVT VR128:$src1), VR128:$src2)))]>,
4250                Sched<[WriteShuffle]>;
4251   def rm : PDI<opc, MRMSrcMem,
4252                (outs VR128:$dst), (ins VR128:$src1, i128mem:$src2),
4253                !if(Is2Addr,
4254                    !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
4255                    !strconcat(OpcodeStr,
4256                               "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
4257                [(set VR128:$dst,
4258                      (OutVT (OpNode (ArgVT VR128:$src1),
4259                                     (bitconvert (ld_frag addr:$src2)))))]>,
4260                Sched<[WriteShuffleLd, ReadAfterLd]>;
4261 }
4262
4263 multiclass sse2_pack_y<bits<8> opc, string OpcodeStr, ValueType OutVT,
4264                        ValueType ArgVT, SDNode OpNode> {
4265   def Yrr : PDI<opc, MRMSrcReg,
4266                 (outs VR256:$dst), (ins VR256:$src1, VR256:$src2),
4267                 !strconcat(OpcodeStr,
4268                            "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4269                 [(set VR256:$dst,
4270                       (OutVT (OpNode (ArgVT VR256:$src1), VR256:$src2)))]>,
4271                 Sched<[WriteShuffle]>;
4272   def Yrm : PDI<opc, MRMSrcMem,
4273                 (outs VR256:$dst), (ins VR256:$src1, i256mem:$src2),
4274                 !strconcat(OpcodeStr,
4275                            "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4276                 [(set VR256:$dst,
4277                       (OutVT (OpNode (ArgVT VR256:$src1),
4278                                      (bitconvert (loadv4i64 addr:$src2)))))]>,
4279                 Sched<[WriteShuffleLd, ReadAfterLd]>;
4280 }
4281
4282 multiclass sse4_pack<bits<8> opc, string OpcodeStr, ValueType OutVT,
4283                      ValueType ArgVT, SDNode OpNode, PatFrag ld_frag,
4284                      bit Is2Addr = 1> {
4285   def rr : SS48I<opc, MRMSrcReg,
4286                  (outs VR128:$dst), (ins VR128:$src1, VR128:$src2),
4287                  !if(Is2Addr,
4288                      !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
4289                      !strconcat(OpcodeStr,
4290                                 "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
4291                  [(set VR128:$dst,
4292                        (OutVT (OpNode (ArgVT VR128:$src1), VR128:$src2)))]>,
4293                  Sched<[WriteShuffle]>;
4294   def rm : SS48I<opc, MRMSrcMem,
4295                  (outs VR128:$dst), (ins VR128:$src1, i128mem:$src2),
4296                  !if(Is2Addr,
4297                      !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
4298                      !strconcat(OpcodeStr,
4299                                 "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
4300                  [(set VR128:$dst,
4301                        (OutVT (OpNode (ArgVT VR128:$src1),
4302                                       (bitconvert (ld_frag addr:$src2)))))]>,
4303                  Sched<[WriteShuffleLd, ReadAfterLd]>;
4304 }
4305
4306 multiclass sse4_pack_y<bits<8> opc, string OpcodeStr, ValueType OutVT,
4307                      ValueType ArgVT, SDNode OpNode> {
4308   def Yrr : SS48I<opc, MRMSrcReg,
4309                   (outs VR256:$dst), (ins VR256:$src1, VR256:$src2),
4310                   !strconcat(OpcodeStr,
4311                              "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4312                   [(set VR256:$dst,
4313                         (OutVT (OpNode (ArgVT VR256:$src1), VR256:$src2)))]>,
4314                   Sched<[WriteShuffle]>;
4315   def Yrm : SS48I<opc, MRMSrcMem,
4316                   (outs VR256:$dst), (ins VR256:$src1, i256mem:$src2),
4317                   !strconcat(OpcodeStr,
4318                              "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4319                   [(set VR256:$dst,
4320                         (OutVT (OpNode (ArgVT VR256:$src1),
4321                                        (bitconvert (loadv4i64 addr:$src2)))))]>,
4322                   Sched<[WriteShuffleLd, ReadAfterLd]>;
4323 }
4324
4325 let Predicates = [HasAVX, NoVLX_Or_NoBWI] in {
4326   defm VPACKSSWB : sse2_pack<0x63, "vpacksswb", v16i8, v8i16, X86Packss,
4327                              loadv2i64, 0>, VEX_4V, VEX_WIG;
4328   defm VPACKSSDW : sse2_pack<0x6B, "vpackssdw", v8i16, v4i32, X86Packss,
4329                              loadv2i64, 0>, VEX_4V, VEX_WIG;
4330
4331   defm VPACKUSWB : sse2_pack<0x67, "vpackuswb", v16i8, v8i16, X86Packus,
4332                              loadv2i64, 0>, VEX_4V, VEX_WIG;
4333   defm VPACKUSDW : sse4_pack<0x2B, "vpackusdw", v8i16, v4i32, X86Packus,
4334                              loadv2i64, 0>, VEX_4V;
4335 }
4336
4337 let Predicates = [HasAVX2, NoVLX_Or_NoBWI] in {
4338   defm VPACKSSWB : sse2_pack_y<0x63, "vpacksswb", v32i8, v16i16, X86Packss>,
4339                                VEX_4V, VEX_L, VEX_WIG;
4340   defm VPACKSSDW : sse2_pack_y<0x6B, "vpackssdw", v16i16, v8i32, X86Packss>,
4341                                VEX_4V, VEX_L, VEX_WIG;
4342
4343   defm VPACKUSWB : sse2_pack_y<0x67, "vpackuswb", v32i8, v16i16, X86Packus>,
4344                                VEX_4V, VEX_L, VEX_WIG;
4345   defm VPACKUSDW : sse4_pack_y<0x2B, "vpackusdw", v16i16, v8i32, X86Packus>,
4346                                VEX_4V, VEX_L;
4347 }
4348
4349 let Constraints = "$src1 = $dst" in {
4350   defm PACKSSWB : sse2_pack<0x63, "packsswb", v16i8, v8i16, X86Packss,
4351                             memopv2i64>;
4352   defm PACKSSDW : sse2_pack<0x6B, "packssdw", v8i16, v4i32, X86Packss,
4353                             memopv2i64>;
4354
4355   defm PACKUSWB : sse2_pack<0x67, "packuswb", v16i8, v8i16, X86Packus,
4356                             memopv2i64>;
4357
4358   defm PACKUSDW : sse4_pack<0x2B, "packusdw", v8i16, v4i32, X86Packus,
4359                             memopv2i64>;
4360 }
4361 } // ExeDomain = SSEPackedInt
4362
4363 //===---------------------------------------------------------------------===//
4364 // SSE2 - Packed Integer Unpack Instructions
4365 //===---------------------------------------------------------------------===//
4366
4367 let ExeDomain = SSEPackedInt in {
4368 multiclass sse2_unpack<bits<8> opc, string OpcodeStr, ValueType vt,
4369                        SDNode OpNode, PatFrag ld_frag, bit Is2Addr = 1> {
4370   def rr : PDI<opc, MRMSrcReg,
4371       (outs VR128:$dst), (ins VR128:$src1, VR128:$src2),
4372       !if(Is2Addr,
4373           !strconcat(OpcodeStr,"\t{$src2, $dst|$dst, $src2}"),
4374           !strconcat(OpcodeStr,"\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
4375       [(set VR128:$dst, (vt (OpNode VR128:$src1, VR128:$src2)))],
4376       IIC_SSE_UNPCK>, Sched<[WriteShuffle]>;
4377   def rm : PDI<opc, MRMSrcMem,
4378       (outs VR128:$dst), (ins VR128:$src1, i128mem:$src2),
4379       !if(Is2Addr,
4380           !strconcat(OpcodeStr,"\t{$src2, $dst|$dst, $src2}"),
4381           !strconcat(OpcodeStr,"\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
4382       [(set VR128:$dst, (vt (OpNode VR128:$src1,
4383                                   (bitconvert (ld_frag addr:$src2)))))],
4384                                                IIC_SSE_UNPCK>,
4385       Sched<[WriteShuffleLd, ReadAfterLd]>;
4386 }
4387
4388 multiclass sse2_unpack_y<bits<8> opc, string OpcodeStr, ValueType vt,
4389                          SDNode OpNode> {
4390   def Yrr : PDI<opc, MRMSrcReg,
4391       (outs VR256:$dst), (ins VR256:$src1, VR256:$src2),
4392       !strconcat(OpcodeStr,"\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4393       [(set VR256:$dst, (vt (OpNode VR256:$src1, VR256:$src2)))]>,
4394       Sched<[WriteShuffle]>;
4395   def Yrm : PDI<opc, MRMSrcMem,
4396       (outs VR256:$dst), (ins VR256:$src1, i256mem:$src2),
4397       !strconcat(OpcodeStr,"\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4398       [(set VR256:$dst, (vt (OpNode VR256:$src1,
4399                                   (bitconvert (loadv4i64 addr:$src2)))))]>,
4400       Sched<[WriteShuffleLd, ReadAfterLd]>;
4401 }
4402
4403
4404 let Predicates = [HasAVX, NoVLX_Or_NoBWI] in {
4405   defm VPUNPCKLBW  : sse2_unpack<0x60, "vpunpcklbw", v16i8, X86Unpckl,
4406                                  loadv2i64, 0>, VEX_4V, VEX_WIG;
4407   defm VPUNPCKLWD  : sse2_unpack<0x61, "vpunpcklwd", v8i16, X86Unpckl,
4408                                  loadv2i64, 0>, VEX_4V, VEX_WIG;
4409   defm VPUNPCKHBW  : sse2_unpack<0x68, "vpunpckhbw", v16i8, X86Unpckh,
4410                                  loadv2i64, 0>, VEX_4V, VEX_WIG;
4411   defm VPUNPCKHWD  : sse2_unpack<0x69, "vpunpckhwd", v8i16, X86Unpckh,
4412                                  loadv2i64, 0>, VEX_4V, VEX_WIG;
4413 }
4414 let Predicates = [HasAVX, NoVLX] in {
4415   defm VPUNPCKLDQ  : sse2_unpack<0x62, "vpunpckldq", v4i32, X86Unpckl,
4416                                  loadv2i64, 0>, VEX_4V, VEX_WIG;
4417   defm VPUNPCKLQDQ : sse2_unpack<0x6C, "vpunpcklqdq", v2i64, X86Unpckl,
4418                                  loadv2i64, 0>, VEX_4V, VEX_WIG;
4419   defm VPUNPCKHDQ  : sse2_unpack<0x6A, "vpunpckhdq", v4i32, X86Unpckh,
4420                                  loadv2i64, 0>, VEX_4V, VEX_WIG;
4421   defm VPUNPCKHQDQ : sse2_unpack<0x6D, "vpunpckhqdq", v2i64, X86Unpckh,
4422                                  loadv2i64, 0>, VEX_4V, VEX_WIG;
4423 }
4424
4425 let Predicates = [HasAVX2, NoVLX_Or_NoBWI] in {
4426   defm VPUNPCKLBW  : sse2_unpack_y<0x60, "vpunpcklbw", v32i8, X86Unpckl>,
4427                                    VEX_4V, VEX_L, VEX_WIG;
4428   defm VPUNPCKLWD  : sse2_unpack_y<0x61, "vpunpcklwd", v16i16, X86Unpckl>,
4429                                    VEX_4V, VEX_L, VEX_WIG;
4430   defm VPUNPCKHBW  : sse2_unpack_y<0x68, "vpunpckhbw", v32i8, X86Unpckh>,
4431                                    VEX_4V, VEX_L, VEX_WIG;
4432   defm VPUNPCKHWD  : sse2_unpack_y<0x69, "vpunpckhwd", v16i16, X86Unpckh>,
4433                                    VEX_4V, VEX_L, VEX_WIG;
4434 }
4435 let Predicates = [HasAVX2, NoVLX] in {
4436   defm VPUNPCKLDQ  : sse2_unpack_y<0x62, "vpunpckldq", v8i32, X86Unpckl>,
4437                                    VEX_4V, VEX_L, VEX_WIG;
4438   defm VPUNPCKLQDQ : sse2_unpack_y<0x6C, "vpunpcklqdq", v4i64, X86Unpckl>,
4439                                    VEX_4V, VEX_L, VEX_WIG;
4440   defm VPUNPCKHDQ  : sse2_unpack_y<0x6A, "vpunpckhdq", v8i32, X86Unpckh>,
4441                                    VEX_4V, VEX_L, VEX_WIG;
4442   defm VPUNPCKHQDQ : sse2_unpack_y<0x6D, "vpunpckhqdq", v4i64, X86Unpckh>,
4443                                    VEX_4V, VEX_L, VEX_WIG;
4444 }
4445
4446 let Constraints = "$src1 = $dst" in {
4447   defm PUNPCKLBW  : sse2_unpack<0x60, "punpcklbw", v16i8, X86Unpckl,
4448                                 memopv2i64>;
4449   defm PUNPCKLWD  : sse2_unpack<0x61, "punpcklwd", v8i16, X86Unpckl,
4450                                 memopv2i64>;
4451   defm PUNPCKLDQ  : sse2_unpack<0x62, "punpckldq", v4i32, X86Unpckl,
4452                                 memopv2i64>;
4453   defm PUNPCKLQDQ : sse2_unpack<0x6C, "punpcklqdq", v2i64, X86Unpckl,
4454                                 memopv2i64>;
4455
4456   defm PUNPCKHBW  : sse2_unpack<0x68, "punpckhbw", v16i8, X86Unpckh,
4457                                 memopv2i64>;
4458   defm PUNPCKHWD  : sse2_unpack<0x69, "punpckhwd", v8i16, X86Unpckh,
4459                                 memopv2i64>;
4460   defm PUNPCKHDQ  : sse2_unpack<0x6A, "punpckhdq", v4i32, X86Unpckh,
4461                                 memopv2i64>;
4462   defm PUNPCKHQDQ : sse2_unpack<0x6D, "punpckhqdq", v2i64, X86Unpckh,
4463                                 memopv2i64>;
4464 }
4465 } // ExeDomain = SSEPackedInt
4466
4467 //===---------------------------------------------------------------------===//
4468 // SSE2 - Packed Integer Extract and Insert
4469 //===---------------------------------------------------------------------===//
4470
4471 let ExeDomain = SSEPackedInt in {
4472 multiclass sse2_pinsrw<bit Is2Addr = 1> {
4473   def rri : Ii8<0xC4, MRMSrcReg,
4474        (outs VR128:$dst), (ins VR128:$src1,
4475         GR32orGR64:$src2, u8imm:$src3),
4476        !if(Is2Addr,
4477            "pinsrw\t{$src3, $src2, $dst|$dst, $src2, $src3}",
4478            "vpinsrw\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
4479        [(set VR128:$dst,
4480          (X86pinsrw VR128:$src1, GR32orGR64:$src2, imm:$src3))],
4481        IIC_SSE_PINSRW>, Sched<[WriteShuffle]>;
4482   def rmi : Ii8<0xC4, MRMSrcMem,
4483                        (outs VR128:$dst), (ins VR128:$src1,
4484                         i16mem:$src2, u8imm:$src3),
4485        !if(Is2Addr,
4486            "pinsrw\t{$src3, $src2, $dst|$dst, $src2, $src3}",
4487            "vpinsrw\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
4488        [(set VR128:$dst,
4489          (X86pinsrw VR128:$src1, (extloadi16 addr:$src2),
4490                     imm:$src3))], IIC_SSE_PINSRW>,
4491        Sched<[WriteShuffleLd, ReadAfterLd]>;
4492 }
4493
4494 // Extract
4495 let Predicates = [HasAVX, NoBWI] in
4496 def VPEXTRWri : Ii8<0xC5, MRMSrcReg,
4497                     (outs GR32orGR64:$dst), (ins VR128:$src1, u8imm:$src2),
4498                     "vpextrw\t{$src2, $src1, $dst|$dst, $src1, $src2}",
4499                     [(set GR32orGR64:$dst, (X86pextrw (v8i16 VR128:$src1),
4500                                             imm:$src2))]>, PD, VEX,
4501                 Sched<[WriteShuffle]>;
4502 def PEXTRWri : PDIi8<0xC5, MRMSrcReg,
4503                     (outs GR32orGR64:$dst), (ins VR128:$src1, u8imm:$src2),
4504                     "pextrw\t{$src2, $src1, $dst|$dst, $src1, $src2}",
4505                     [(set GR32orGR64:$dst, (X86pextrw (v8i16 VR128:$src1),
4506                                             imm:$src2))], IIC_SSE_PEXTRW>,
4507                Sched<[WriteShuffleLd, ReadAfterLd]>;
4508
4509 // Insert
4510 let Predicates = [HasAVX, NoBWI] in
4511 defm VPINSRW : sse2_pinsrw<0>, PD, VEX_4V;
4512
4513 let Predicates = [UseSSE2], Constraints = "$src1 = $dst" in
4514 defm PINSRW : sse2_pinsrw, PD;
4515
4516 } // ExeDomain = SSEPackedInt
4517
4518 //===---------------------------------------------------------------------===//
4519 // SSE2 - Packed Mask Creation
4520 //===---------------------------------------------------------------------===//
4521
4522 let ExeDomain = SSEPackedInt, SchedRW = [WriteVecLogic] in {
4523
4524 def VPMOVMSKBrr  : VPDI<0xD7, MRMSrcReg, (outs GR32orGR64:$dst),
4525            (ins VR128:$src),
4526            "pmovmskb\t{$src, $dst|$dst, $src}",
4527            [(set GR32orGR64:$dst, (X86movmsk (v16i8 VR128:$src)))],
4528            IIC_SSE_MOVMSK>, VEX, VEX_WIG;
4529
4530 let Predicates = [HasAVX2] in {
4531 def VPMOVMSKBYrr  : VPDI<0xD7, MRMSrcReg, (outs GR32orGR64:$dst),
4532            (ins VR256:$src),
4533            "pmovmskb\t{$src, $dst|$dst, $src}",
4534            [(set GR32orGR64:$dst, (X86movmsk (v32i8 VR256:$src)))]>,
4535            VEX, VEX_L, VEX_WIG;
4536 }
4537
4538 def PMOVMSKBrr : PDI<0xD7, MRMSrcReg, (outs GR32orGR64:$dst), (ins VR128:$src),
4539            "pmovmskb\t{$src, $dst|$dst, $src}",
4540            [(set GR32orGR64:$dst, (X86movmsk (v16i8 VR128:$src)))],
4541            IIC_SSE_MOVMSK>;
4542
4543 } // ExeDomain = SSEPackedInt
4544
4545 //===---------------------------------------------------------------------===//
4546 // SSE2 - Conditional Store
4547 //===---------------------------------------------------------------------===//
4548
4549 let ExeDomain = SSEPackedInt, SchedRW = [WriteStore] in {
4550
4551 let Uses = [EDI], Predicates = [HasAVX,Not64BitMode] in
4552 def VMASKMOVDQU : VPDI<0xF7, MRMSrcReg, (outs),
4553            (ins VR128:$src, VR128:$mask),
4554            "maskmovdqu\t{$mask, $src|$src, $mask}",
4555            [(int_x86_sse2_maskmov_dqu VR128:$src, VR128:$mask, EDI)],
4556            IIC_SSE_MASKMOV>, VEX, VEX_WIG;
4557 let Uses = [RDI], Predicates = [HasAVX,In64BitMode] in
4558 def VMASKMOVDQU64 : VPDI<0xF7, MRMSrcReg, (outs),
4559            (ins VR128:$src, VR128:$mask),
4560            "maskmovdqu\t{$mask, $src|$src, $mask}",
4561            [(int_x86_sse2_maskmov_dqu VR128:$src, VR128:$mask, RDI)],
4562            IIC_SSE_MASKMOV>, VEX, VEX_WIG;
4563
4564 let Uses = [EDI], Predicates = [UseSSE2,Not64BitMode] in
4565 def MASKMOVDQU : PDI<0xF7, MRMSrcReg, (outs), (ins VR128:$src, VR128:$mask),
4566            "maskmovdqu\t{$mask, $src|$src, $mask}",
4567            [(int_x86_sse2_maskmov_dqu VR128:$src, VR128:$mask, EDI)],
4568            IIC_SSE_MASKMOV>;
4569 let Uses = [RDI], Predicates = [UseSSE2,In64BitMode] in
4570 def MASKMOVDQU64 : PDI<0xF7, MRMSrcReg, (outs), (ins VR128:$src, VR128:$mask),
4571            "maskmovdqu\t{$mask, $src|$src, $mask}",
4572            [(int_x86_sse2_maskmov_dqu VR128:$src, VR128:$mask, RDI)],
4573            IIC_SSE_MASKMOV>;
4574
4575 } // ExeDomain = SSEPackedInt
4576
4577 //===---------------------------------------------------------------------===//
4578 // SSE2 - Move Doubleword/Quadword
4579 //===---------------------------------------------------------------------===//
4580
4581 //===---------------------------------------------------------------------===//
4582 // Move Int Doubleword to Packed Double Int
4583 //
4584 let ExeDomain = SSEPackedInt in {
4585 def VMOVDI2PDIrr : VS2I<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR32:$src),
4586                       "movd\t{$src, $dst|$dst, $src}",
4587                       [(set VR128:$dst,
4588                         (v4i32 (scalar_to_vector GR32:$src)))], IIC_SSE_MOVDQ>,
4589                         VEX, Sched<[WriteMove]>;
4590 def VMOVDI2PDIrm : VS2I<0x6E, MRMSrcMem, (outs VR128:$dst), (ins i32mem:$src),
4591                       "movd\t{$src, $dst|$dst, $src}",
4592                       [(set VR128:$dst,
4593                         (v4i32 (scalar_to_vector (loadi32 addr:$src))))],
4594                         IIC_SSE_MOVDQ>,
4595                       VEX, Sched<[WriteLoad]>;
4596 def VMOV64toPQIrr : VRS2I<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR64:$src),
4597                         "movq\t{$src, $dst|$dst, $src}",
4598                         [(set VR128:$dst,
4599                           (v2i64 (scalar_to_vector GR64:$src)))],
4600                           IIC_SSE_MOVDQ>, VEX, Sched<[WriteMove]>;
4601 let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0, mayLoad = 1 in
4602 def VMOV64toPQIrm : VRS2I<0x6E, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
4603                         "movq\t{$src, $dst|$dst, $src}",
4604                         [], IIC_SSE_MOVDQ>, VEX, Sched<[WriteLoad]>;
4605 let isCodeGenOnly = 1 in
4606 def VMOV64toSDrr : VRS2I<0x6E, MRMSrcReg, (outs FR64:$dst), (ins GR64:$src),
4607                        "movq\t{$src, $dst|$dst, $src}",
4608                        [(set FR64:$dst, (bitconvert GR64:$src))],
4609                        IIC_SSE_MOVDQ>, VEX, Sched<[WriteMove]>;
4610
4611 def MOVDI2PDIrr : S2I<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR32:$src),
4612                       "movd\t{$src, $dst|$dst, $src}",
4613                       [(set VR128:$dst,
4614                         (v4i32 (scalar_to_vector GR32:$src)))], IIC_SSE_MOVDQ>,
4615                   Sched<[WriteMove]>;
4616 def MOVDI2PDIrm : S2I<0x6E, MRMSrcMem, (outs VR128:$dst), (ins i32mem:$src),
4617                       "movd\t{$src, $dst|$dst, $src}",
4618                       [(set VR128:$dst,
4619                         (v4i32 (scalar_to_vector (loadi32 addr:$src))))],
4620                         IIC_SSE_MOVDQ>, Sched<[WriteLoad]>;
4621 def MOV64toPQIrr : RS2I<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR64:$src),
4622                         "movq\t{$src, $dst|$dst, $src}",
4623                         [(set VR128:$dst,
4624                           (v2i64 (scalar_to_vector GR64:$src)))],
4625                           IIC_SSE_MOVDQ>, Sched<[WriteMove]>;
4626 let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0, mayLoad = 1 in
4627 def MOV64toPQIrm : RS2I<0x6E, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
4628                         "movq\t{$src, $dst|$dst, $src}",
4629                         [], IIC_SSE_MOVDQ>, Sched<[WriteLoad]>;
4630 let isCodeGenOnly = 1 in
4631 def MOV64toSDrr : RS2I<0x6E, MRMSrcReg, (outs FR64:$dst), (ins GR64:$src),
4632                        "movq\t{$src, $dst|$dst, $src}",
4633                        [(set FR64:$dst, (bitconvert GR64:$src))],
4634                        IIC_SSE_MOVDQ>, Sched<[WriteMove]>;
4635 } // ExeDomain = SSEPackedInt
4636
4637 //===---------------------------------------------------------------------===//
4638 // Move Int Doubleword to Single Scalar
4639 //
4640 let ExeDomain = SSEPackedInt, isCodeGenOnly = 1 in {
4641   def VMOVDI2SSrr  : VS2I<0x6E, MRMSrcReg, (outs FR32:$dst), (ins GR32:$src),
4642                         "movd\t{$src, $dst|$dst, $src}",
4643                         [(set FR32:$dst, (bitconvert GR32:$src))],
4644                         IIC_SSE_MOVDQ>, VEX, Sched<[WriteMove]>;
4645
4646   def VMOVDI2SSrm  : VS2I<0x6E, MRMSrcMem, (outs FR32:$dst), (ins i32mem:$src),
4647                         "movd\t{$src, $dst|$dst, $src}",
4648                         [(set FR32:$dst, (bitconvert (loadi32 addr:$src)))],
4649                         IIC_SSE_MOVDQ>,
4650                         VEX, Sched<[WriteLoad]>;
4651   def MOVDI2SSrr  : S2I<0x6E, MRMSrcReg, (outs FR32:$dst), (ins GR32:$src),
4652                         "movd\t{$src, $dst|$dst, $src}",
4653                         [(set FR32:$dst, (bitconvert GR32:$src))],
4654                         IIC_SSE_MOVDQ>, Sched<[WriteMove]>;
4655
4656   def MOVDI2SSrm  : S2I<0x6E, MRMSrcMem, (outs FR32:$dst), (ins i32mem:$src),
4657                         "movd\t{$src, $dst|$dst, $src}",
4658                         [(set FR32:$dst, (bitconvert (loadi32 addr:$src)))],
4659                         IIC_SSE_MOVDQ>, Sched<[WriteLoad]>;
4660 } // ExeDomain = SSEPackedInt, isCodeGenOnly = 1
4661
4662 //===---------------------------------------------------------------------===//
4663 // Move Packed Doubleword Int to Packed Double Int
4664 //
4665 let ExeDomain = SSEPackedInt in {
4666 def VMOVPDI2DIrr  : VS2I<0x7E, MRMDestReg, (outs GR32:$dst), (ins VR128:$src),
4667                        "movd\t{$src, $dst|$dst, $src}",
4668                        [(set GR32:$dst, (extractelt (v4i32 VR128:$src),
4669                                         (iPTR 0)))], IIC_SSE_MOVD_ToGP>, VEX,
4670                     Sched<[WriteMove]>;
4671 def VMOVPDI2DImr  : VS2I<0x7E, MRMDestMem, (outs),
4672                        (ins i32mem:$dst, VR128:$src),
4673                        "movd\t{$src, $dst|$dst, $src}",
4674                        [(store (i32 (extractelt (v4i32 VR128:$src),
4675                                      (iPTR 0))), addr:$dst)], IIC_SSE_MOVDQ>,
4676                                      VEX, Sched<[WriteStore]>;
4677 def MOVPDI2DIrr  : S2I<0x7E, MRMDestReg, (outs GR32:$dst), (ins VR128:$src),
4678                        "movd\t{$src, $dst|$dst, $src}",
4679                        [(set GR32:$dst, (extractelt (v4i32 VR128:$src),
4680                                         (iPTR 0)))], IIC_SSE_MOVD_ToGP>,
4681                    Sched<[WriteMove]>;
4682 def MOVPDI2DImr  : S2I<0x7E, MRMDestMem, (outs), (ins i32mem:$dst, VR128:$src),
4683                        "movd\t{$src, $dst|$dst, $src}",
4684                        [(store (i32 (extractelt (v4i32 VR128:$src),
4685                                      (iPTR 0))), addr:$dst)],
4686                                      IIC_SSE_MOVDQ>, Sched<[WriteStore]>;
4687 } // ExeDomain = SSEPackedInt
4688 //===---------------------------------------------------------------------===//
4689 // Move Packed Doubleword Int first element to Doubleword Int
4690 //
4691 let ExeDomain = SSEPackedInt in {
4692 let SchedRW = [WriteMove] in {
4693 def VMOVPQIto64rr : VRS2I<0x7E, MRMDestReg, (outs GR64:$dst), (ins VR128:$src),
4694                           "movq\t{$src, $dst|$dst, $src}",
4695                           [(set GR64:$dst, (extractelt (v2i64 VR128:$src),
4696                                                         (iPTR 0)))],
4697                                                            IIC_SSE_MOVD_ToGP>,
4698                       VEX;
4699
4700 def MOVPQIto64rr : RS2I<0x7E, MRMDestReg, (outs GR64:$dst), (ins VR128:$src),
4701                         "movq\t{$src, $dst|$dst, $src}",
4702                         [(set GR64:$dst, (extractelt (v2i64 VR128:$src),
4703                                                          (iPTR 0)))],
4704                                                          IIC_SSE_MOVD_ToGP>;
4705 } //SchedRW
4706
4707 let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0, mayStore = 1 in
4708 def VMOVPQIto64mr : VRS2I<0x7E, MRMDestMem, (outs),
4709                           (ins i64mem:$dst, VR128:$src),
4710                           "movq\t{$src, $dst|$dst, $src}",
4711                           [], IIC_SSE_MOVDQ>, VEX, Sched<[WriteStore]>;
4712 let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0, mayStore = 1 in
4713 def MOVPQIto64mr : RS2I<0x7E, MRMDestMem, (outs), (ins i64mem:$dst, VR128:$src),
4714                         "movq\t{$src, $dst|$dst, $src}",
4715                         [], IIC_SSE_MOVDQ>, Sched<[WriteStore]>;
4716 } // ExeDomain = SSEPackedInt
4717
4718 //===---------------------------------------------------------------------===//
4719 // Bitcast FR64 <-> GR64
4720 //
4721 let ExeDomain = SSEPackedInt, isCodeGenOnly = 1 in {
4722   let Predicates = [UseAVX] in
4723   def VMOV64toSDrm : VS2SI<0x7E, MRMSrcMem, (outs FR64:$dst), (ins i64mem:$src),
4724                           "movq\t{$src, $dst|$dst, $src}",
4725                           [(set FR64:$dst, (bitconvert (loadi64 addr:$src)))]>,
4726                           VEX, Sched<[WriteLoad]>;
4727   def VMOVSDto64rr : VRS2I<0x7E, MRMDestReg, (outs GR64:$dst), (ins FR64:$src),
4728                            "movq\t{$src, $dst|$dst, $src}",
4729                            [(set GR64:$dst, (bitconvert FR64:$src))],
4730                            IIC_SSE_MOVDQ>, VEX, Sched<[WriteMove]>;
4731   def VMOVSDto64mr : VRS2I<0x7E, MRMDestMem, (outs), (ins i64mem:$dst, FR64:$src),
4732                            "movq\t{$src, $dst|$dst, $src}",
4733                            [(store (i64 (bitconvert FR64:$src)), addr:$dst)],
4734                            IIC_SSE_MOVDQ>, VEX, Sched<[WriteStore]>;
4735
4736   def MOV64toSDrm : S2SI<0x7E, MRMSrcMem, (outs FR64:$dst), (ins i64mem:$src),
4737                          "movq\t{$src, $dst|$dst, $src}",
4738                          [(set FR64:$dst, (bitconvert (loadi64 addr:$src)))],
4739                          IIC_SSE_MOVDQ>, Sched<[WriteLoad]>;
4740   def MOVSDto64rr : RS2I<0x7E, MRMDestReg, (outs GR64:$dst), (ins FR64:$src),
4741                          "movq\t{$src, $dst|$dst, $src}",
4742                          [(set GR64:$dst, (bitconvert FR64:$src))],
4743                          IIC_SSE_MOVD_ToGP>, Sched<[WriteMove]>;
4744   def MOVSDto64mr : RS2I<0x7E, MRMDestMem, (outs), (ins i64mem:$dst, FR64:$src),
4745                          "movq\t{$src, $dst|$dst, $src}",
4746                          [(store (i64 (bitconvert FR64:$src)), addr:$dst)],
4747                          IIC_SSE_MOVDQ>, Sched<[WriteStore]>;
4748 } // ExeDomain = SSEPackedInt, isCodeGenOnly = 1
4749
4750 //===---------------------------------------------------------------------===//
4751 // Move Scalar Single to Double Int
4752 //
4753 let ExeDomain = SSEPackedInt, isCodeGenOnly = 1 in {
4754   def VMOVSS2DIrr  : VS2I<0x7E, MRMDestReg, (outs GR32:$dst), (ins FR32:$src),
4755                         "movd\t{$src, $dst|$dst, $src}",
4756                         [(set GR32:$dst, (bitconvert FR32:$src))],
4757                         IIC_SSE_MOVD_ToGP>, VEX, Sched<[WriteMove]>;
4758   def VMOVSS2DImr  : VS2I<0x7E, MRMDestMem, (outs), (ins i32mem:$dst, FR32:$src),
4759                         "movd\t{$src, $dst|$dst, $src}",
4760                         [(store (i32 (bitconvert FR32:$src)), addr:$dst)],
4761                         IIC_SSE_MOVDQ>, VEX, Sched<[WriteStore]>;
4762   def MOVSS2DIrr  : S2I<0x7E, MRMDestReg, (outs GR32:$dst), (ins FR32:$src),
4763                         "movd\t{$src, $dst|$dst, $src}",
4764                         [(set GR32:$dst, (bitconvert FR32:$src))],
4765                         IIC_SSE_MOVD_ToGP>, Sched<[WriteMove]>;
4766   def MOVSS2DImr  : S2I<0x7E, MRMDestMem, (outs), (ins i32mem:$dst, FR32:$src),
4767                         "movd\t{$src, $dst|$dst, $src}",
4768                         [(store (i32 (bitconvert FR32:$src)), addr:$dst)],
4769                         IIC_SSE_MOVDQ>, Sched<[WriteStore]>;
4770 } // ExeDomain = SSEPackedInt, isCodeGenOnly = 1
4771
4772 let Predicates = [UseAVX] in {
4773   let AddedComplexity = 15 in {
4774     def : Pat<(v4i32 (X86vzmovl (v4i32 (scalar_to_vector GR32:$src)))),
4775               (VMOVDI2PDIrr GR32:$src)>;
4776
4777     def : Pat<(v2i64 (X86vzmovl (v2i64 (scalar_to_vector GR64:$src)))),
4778               (VMOV64toPQIrr GR64:$src)>;
4779
4780     def : Pat<(v4i64 (X86vzmovl (insert_subvector undef,
4781                 (v2i64 (scalar_to_vector GR64:$src)),(iPTR 0)))),
4782               (SUBREG_TO_REG (i64 0), (VMOV64toPQIrr GR64:$src), sub_xmm)>;
4783   }
4784   // AVX 128-bit movd/movq instructions write zeros in the high 128-bit part.
4785   // These instructions also write zeros in the high part of a 256-bit register.
4786   let AddedComplexity = 20 in {
4787     def : Pat<(v2i64 (X86vzmovl (v2i64 (scalar_to_vector (zextloadi64i32 addr:$src))))),
4788               (VMOVDI2PDIrm addr:$src)>;
4789     def : Pat<(v4i32 (X86vzmovl (v4i32 (scalar_to_vector (loadi32 addr:$src))))),
4790               (VMOVDI2PDIrm addr:$src)>;
4791     def : Pat<(v4i32 (X86vzmovl (bc_v4i32 (loadv4f32 addr:$src)))),
4792               (VMOVDI2PDIrm addr:$src)>;
4793     def : Pat<(v4i32 (X86vzmovl (bc_v4i32 (loadv2i64 addr:$src)))),
4794               (VMOVDI2PDIrm addr:$src)>;
4795     def : Pat<(v4i32 (X86vzload addr:$src)),
4796               (VMOVDI2PDIrm addr:$src)>;
4797     def : Pat<(v8i32 (X86vzmovl (insert_subvector undef,
4798                 (v4i32 (scalar_to_vector (loadi32 addr:$src))), (iPTR 0)))),
4799               (SUBREG_TO_REG (i32 0), (VMOVDI2PDIrm addr:$src), sub_xmm)>;
4800     def : Pat<(v8i32 (X86vzload addr:$src)),
4801               (SUBREG_TO_REG (i64 0), (VMOVDI2PDIrm addr:$src), sub_xmm)>;
4802   }
4803   // Use regular 128-bit instructions to match 256-bit scalar_to_vec+zext.
4804   def : Pat<(v8i32 (X86vzmovl (insert_subvector undef,
4805                                (v4i32 (scalar_to_vector GR32:$src)),(iPTR 0)))),
4806             (SUBREG_TO_REG (i32 0), (VMOVDI2PDIrr GR32:$src), sub_xmm)>;
4807 }
4808
4809 let Predicates = [UseSSE2] in {
4810   let AddedComplexity = 15 in {
4811     def : Pat<(v4i32 (X86vzmovl (v4i32 (scalar_to_vector GR32:$src)))),
4812               (MOVDI2PDIrr GR32:$src)>;
4813
4814     def : Pat<(v2i64 (X86vzmovl (v2i64 (scalar_to_vector GR64:$src)))),
4815               (MOV64toPQIrr GR64:$src)>;
4816   }
4817   let AddedComplexity = 20 in {
4818     def : Pat<(v2i64 (X86vzmovl (v2i64 (scalar_to_vector (zextloadi64i32 addr:$src))))),
4819               (MOVDI2PDIrm addr:$src)>;
4820     def : Pat<(v4i32 (X86vzmovl (v4i32 (scalar_to_vector (loadi32 addr:$src))))),
4821               (MOVDI2PDIrm addr:$src)>;
4822     def : Pat<(v4i32 (X86vzmovl (bc_v4i32 (loadv4f32 addr:$src)))),
4823               (MOVDI2PDIrm addr:$src)>;
4824     def : Pat<(v4i32 (X86vzmovl (bc_v4i32 (loadv2i64 addr:$src)))),
4825               (MOVDI2PDIrm addr:$src)>;
4826     def : Pat<(v4i32 (X86vzload addr:$src)),
4827               (MOVDI2PDIrm addr:$src)>;
4828   }
4829 }
4830
4831 // Before the MC layer of LLVM existed, clang emitted "movd" assembly instead of
4832 // "movq" due to MacOS parsing limitation. In order to parse old assembly, we add
4833 // these aliases.
4834 def : InstAlias<"movd\t{$src, $dst|$dst, $src}",
4835                 (MOV64toPQIrr VR128:$dst, GR64:$src), 0>;
4836 def : InstAlias<"movd\t{$src, $dst|$dst, $src}",
4837                 (MOVPQIto64rr GR64:$dst, VR128:$src), 0>;
4838 // Allow "vmovd" but print "vmovq" since we don't need compatibility for AVX.
4839 def : InstAlias<"vmovd\t{$src, $dst|$dst, $src}",
4840                 (VMOV64toPQIrr VR128:$dst, GR64:$src), 0>;
4841 def : InstAlias<"vmovd\t{$src, $dst|$dst, $src}",
4842                 (VMOVPQIto64rr GR64:$dst, VR128:$src), 0>;
4843
4844 //===---------------------------------------------------------------------===//
4845 // SSE2 - Move Quadword
4846 //===---------------------------------------------------------------------===//
4847
4848 //===---------------------------------------------------------------------===//
4849 // Move Quadword Int to Packed Quadword Int
4850 //
4851
4852 let ExeDomain = SSEPackedInt, SchedRW = [WriteLoad] in {
4853 def VMOVQI2PQIrm : I<0x7E, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
4854                     "vmovq\t{$src, $dst|$dst, $src}",
4855                     [(set VR128:$dst,
4856                       (v2i64 (scalar_to_vector (loadi64 addr:$src))))]>, XS,
4857                     VEX, Requires<[UseAVX]>, VEX_WIG;
4858 def MOVQI2PQIrm : I<0x7E, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
4859                     "movq\t{$src, $dst|$dst, $src}",
4860                     [(set VR128:$dst,
4861                       (v2i64 (scalar_to_vector (loadi64 addr:$src))))],
4862                       IIC_SSE_MOVDQ>, XS,
4863                     Requires<[UseSSE2]>; // SSE2 instruction with XS Prefix
4864 } // ExeDomain, SchedRW
4865
4866 //===---------------------------------------------------------------------===//
4867 // Move Packed Quadword Int to Quadword Int
4868 //
4869 let ExeDomain = SSEPackedInt, SchedRW = [WriteStore] in {
4870 def VMOVPQI2QImr : VS2I<0xD6, MRMDestMem, (outs), (ins i64mem:$dst, VR128:$src),
4871                       "movq\t{$src, $dst|$dst, $src}",
4872                       [(store (i64 (extractelt (v2i64 VR128:$src),
4873                                     (iPTR 0))), addr:$dst)],
4874                                     IIC_SSE_MOVDQ>, VEX, VEX_WIG;
4875 def MOVPQI2QImr : S2I<0xD6, MRMDestMem, (outs), (ins i64mem:$dst, VR128:$src),
4876                       "movq\t{$src, $dst|$dst, $src}",
4877                       [(store (i64 (extractelt (v2i64 VR128:$src),
4878                                     (iPTR 0))), addr:$dst)],
4879                                     IIC_SSE_MOVDQ>;
4880 } // ExeDomain, SchedRW
4881
4882 // For disassembler only
4883 let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0,
4884     SchedRW = [WriteVecLogic] in {
4885 def VMOVPQI2QIrr : VS2I<0xD6, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
4886                      "movq\t{$src, $dst|$dst, $src}", [], IIC_SSE_MOVQ_RR>, VEX, VEX_WIG;
4887 def MOVPQI2QIrr : S2I<0xD6, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
4888                       "movq\t{$src, $dst|$dst, $src}", [], IIC_SSE_MOVQ_RR>;
4889 }
4890
4891 // Aliases to help the assembler pick two byte VEX encodings by swapping the
4892 // operands relative to the normal instructions to use VEX.R instead of VEX.B.
4893 def : InstAlias<"vmovq\t{$src, $dst|$dst, $src}",
4894                 (VMOVPQI2QIrr VR128L:$dst, VR128H:$src), 0>;
4895
4896 let Predicates = [UseAVX], AddedComplexity = 20 in {
4897   def : Pat<(v2i64 (X86vzmovl (v2i64 (scalar_to_vector (loadi64 addr:$src))))),
4898             (VMOVQI2PQIrm addr:$src)>;
4899   def : Pat<(v2i64 (X86vzmovl (loadv2i64 addr:$src))),
4900             (VMOVQI2PQIrm addr:$src)>;
4901   def : Pat<(v2i64 (X86vzmovl (bc_v2i64 (loadv4f32 addr:$src)))),
4902             (VMOVQI2PQIrm addr:$src)>;
4903   def : Pat<(v2i64 (X86vzload addr:$src)),
4904             (VMOVQI2PQIrm addr:$src)>;
4905   def : Pat<(v4i64 (X86vzmovl (insert_subvector undef,
4906               (v2i64 (scalar_to_vector (loadi64 addr:$src))), (iPTR 0)))),
4907             (SUBREG_TO_REG (i64 0), (VMOVQI2PQIrm addr:$src), sub_xmm)>;
4908   def : Pat<(v4i64 (X86vzload addr:$src)),
4909             (SUBREG_TO_REG (i64 0), (VMOVQI2PQIrm addr:$src), sub_xmm)>;
4910 }
4911
4912 let Predicates = [UseSSE2], AddedComplexity = 20 in {
4913   def : Pat<(v2i64 (X86vzmovl (v2i64 (scalar_to_vector (loadi64 addr:$src))))),
4914             (MOVQI2PQIrm addr:$src)>;
4915   def : Pat<(v2i64 (X86vzmovl (loadv2i64 addr:$src))),
4916             (MOVQI2PQIrm addr:$src)>;
4917   def : Pat<(v2i64 (X86vzmovl (bc_v2i64 (loadv4f32 addr:$src)))),
4918             (MOVQI2PQIrm addr:$src)>;
4919   def : Pat<(v2i64 (X86vzload addr:$src)), (MOVQI2PQIrm addr:$src)>;
4920 }
4921
4922 //===---------------------------------------------------------------------===//
4923 // Moving from XMM to XMM and clear upper 64 bits. Note, there is a bug in
4924 // IA32 document. movq xmm1, xmm2 does clear the high bits.
4925 //
4926 let ExeDomain = SSEPackedInt, SchedRW = [WriteVecLogic] in {
4927 let AddedComplexity = 15 in
4928 def VMOVZPQILo2PQIrr : I<0x7E, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
4929                         "vmovq\t{$src, $dst|$dst, $src}",
4930                     [(set VR128:$dst, (v2i64 (X86vzmovl (v2i64 VR128:$src))))],
4931                     IIC_SSE_MOVQ_RR>,
4932                       XS, VEX, Requires<[UseAVX]>, VEX_WIG;
4933 let AddedComplexity = 15 in
4934 def MOVZPQILo2PQIrr : I<0x7E, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
4935                         "movq\t{$src, $dst|$dst, $src}",
4936                     [(set VR128:$dst, (v2i64 (X86vzmovl (v2i64 VR128:$src))))],
4937                     IIC_SSE_MOVQ_RR>,
4938                       XS, Requires<[UseSSE2]>;
4939 } // ExeDomain, SchedRW
4940
4941 let AddedComplexity = 20 in {
4942   let Predicates = [UseAVX] in {
4943     def : Pat<(v2f64 (X86vzmovl (v2f64 VR128:$src))),
4944               (VMOVZPQILo2PQIrr VR128:$src)>;
4945   }
4946   let Predicates = [UseSSE2] in {
4947     def : Pat<(v2f64 (X86vzmovl (v2f64 VR128:$src))),
4948               (MOVZPQILo2PQIrr VR128:$src)>;
4949   }
4950 }
4951
4952 //===---------------------------------------------------------------------===//
4953 // SSE3 - Replicate Single FP - MOVSHDUP and MOVSLDUP
4954 //===---------------------------------------------------------------------===//
4955 multiclass sse3_replicate_sfp<bits<8> op, SDNode OpNode, string OpcodeStr,
4956                               ValueType vt, RegisterClass RC, PatFrag mem_frag,
4957                               X86MemOperand x86memop> {
4958 def rr : S3SI<op, MRMSrcReg, (outs RC:$dst), (ins RC:$src),
4959                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
4960                       [(set RC:$dst, (vt (OpNode RC:$src)))],
4961                       IIC_SSE_MOV_LH>, Sched<[WriteFShuffle]>;
4962 def rm : S3SI<op, MRMSrcMem, (outs RC:$dst), (ins x86memop:$src),
4963                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
4964                       [(set RC:$dst, (OpNode (mem_frag addr:$src)))],
4965                       IIC_SSE_MOV_LH>, Sched<[WriteLoad]>;
4966 }
4967
4968 let Predicates = [HasAVX, NoVLX] in {
4969   defm VMOVSHDUP  : sse3_replicate_sfp<0x16, X86Movshdup, "vmovshdup",
4970                                        v4f32, VR128, loadv4f32, f128mem>, VEX, VEX_WIG;
4971   defm VMOVSLDUP  : sse3_replicate_sfp<0x12, X86Movsldup, "vmovsldup",
4972                                        v4f32, VR128, loadv4f32, f128mem>, VEX, VEX_WIG;
4973   defm VMOVSHDUPY : sse3_replicate_sfp<0x16, X86Movshdup, "vmovshdup",
4974                                  v8f32, VR256, loadv8f32, f256mem>, VEX, VEX_L, VEX_WIG;
4975   defm VMOVSLDUPY : sse3_replicate_sfp<0x12, X86Movsldup, "vmovsldup",
4976                                  v8f32, VR256, loadv8f32, f256mem>, VEX, VEX_L, VEX_WIG;
4977 }
4978 defm MOVSHDUP : sse3_replicate_sfp<0x16, X86Movshdup, "movshdup", v4f32, VR128,
4979                                    memopv4f32, f128mem>;
4980 defm MOVSLDUP : sse3_replicate_sfp<0x12, X86Movsldup, "movsldup", v4f32, VR128,
4981                                    memopv4f32, f128mem>;
4982
4983 let Predicates = [HasAVX, NoVLX] in {
4984   def : Pat<(v4i32 (X86Movshdup VR128:$src)),
4985             (VMOVSHDUPrr VR128:$src)>;
4986   def : Pat<(v4i32 (X86Movshdup (bc_v4i32 (loadv2i64 addr:$src)))),
4987             (VMOVSHDUPrm addr:$src)>;
4988   def : Pat<(v4i32 (X86Movsldup VR128:$src)),
4989             (VMOVSLDUPrr VR128:$src)>;
4990   def : Pat<(v4i32 (X86Movsldup (bc_v4i32 (loadv2i64 addr:$src)))),
4991             (VMOVSLDUPrm addr:$src)>;
4992   def : Pat<(v8i32 (X86Movshdup VR256:$src)),
4993             (VMOVSHDUPYrr VR256:$src)>;
4994   def : Pat<(v8i32 (X86Movshdup (bc_v8i32 (loadv4i64 addr:$src)))),
4995             (VMOVSHDUPYrm addr:$src)>;
4996   def : Pat<(v8i32 (X86Movsldup VR256:$src)),
4997             (VMOVSLDUPYrr VR256:$src)>;
4998   def : Pat<(v8i32 (X86Movsldup (bc_v8i32 (loadv4i64 addr:$src)))),
4999             (VMOVSLDUPYrm addr:$src)>;
5000 }
5001
5002 let Predicates = [UseSSE3] in {
5003   def : Pat<(v4i32 (X86Movshdup VR128:$src)),
5004             (MOVSHDUPrr VR128:$src)>;
5005   def : Pat<(v4i32 (X86Movshdup (bc_v4i32 (memopv2i64 addr:$src)))),
5006             (MOVSHDUPrm addr:$src)>;
5007   def : Pat<(v4i32 (X86Movsldup VR128:$src)),
5008             (MOVSLDUPrr VR128:$src)>;
5009   def : Pat<(v4i32 (X86Movsldup (bc_v4i32 (memopv2i64 addr:$src)))),
5010             (MOVSLDUPrm addr:$src)>;
5011 }
5012
5013 //===---------------------------------------------------------------------===//
5014 // SSE3 - Replicate Double FP - MOVDDUP
5015 //===---------------------------------------------------------------------===//
5016
5017 multiclass sse3_replicate_dfp<string OpcodeStr> {
5018 def rr  : S3DI<0x12, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
5019                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5020                     [(set VR128:$dst, (v2f64 (X86Movddup VR128:$src)))],
5021                     IIC_SSE_MOV_LH>, Sched<[WriteFShuffle]>;
5022 def rm  : S3DI<0x12, MRMSrcMem, (outs VR128:$dst), (ins f64mem:$src),
5023                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5024                     [(set VR128:$dst,
5025                       (v2f64 (X86Movddup
5026                               (scalar_to_vector (loadf64 addr:$src)))))],
5027                               IIC_SSE_MOV_LH>, Sched<[WriteLoad]>;
5028 }
5029
5030 // FIXME: Merge with above classe when there're patterns for the ymm version
5031 multiclass sse3_replicate_dfp_y<string OpcodeStr> {
5032 def rr  : S3DI<0x12, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
5033                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5034                     [(set VR256:$dst, (v4f64 (X86Movddup VR256:$src)))]>,
5035                     Sched<[WriteFShuffle]>;
5036 def rm  : S3DI<0x12, MRMSrcMem, (outs VR256:$dst), (ins f256mem:$src),
5037                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5038                     [(set VR256:$dst,
5039                       (v4f64 (X86Movddup (loadv4f64 addr:$src))))]>,
5040                     Sched<[WriteLoad]>;
5041 }
5042
5043 let Predicates = [HasAVX, NoVLX] in {
5044   defm VMOVDDUP  : sse3_replicate_dfp<"vmovddup">, VEX, VEX_WIG;
5045   defm VMOVDDUPY : sse3_replicate_dfp_y<"vmovddup">, VEX, VEX_L, VEX_WIG;
5046 }
5047
5048 defm MOVDDUP : sse3_replicate_dfp<"movddup">;
5049
5050
5051 let Predicates = [HasAVX, NoVLX] in {
5052   def : Pat<(X86Movddup (loadv2f64 addr:$src)),
5053             (VMOVDDUPrm addr:$src)>, Requires<[HasAVX]>;
5054
5055   // 256-bit version
5056   def : Pat<(X86Movddup (loadv4i64 addr:$src)),
5057             (VMOVDDUPYrm addr:$src)>;
5058   def : Pat<(X86Movddup (v4i64 VR256:$src)),
5059             (VMOVDDUPYrr VR256:$src)>;
5060 }
5061
5062 let Predicates = [HasAVX, NoVLX] in
5063 def : Pat<(v2f64 (X86VBroadcast (loadf64 addr:$src))),
5064           (VMOVDDUPrm addr:$src)>;
5065 let Predicates = [HasAVX1Only] in
5066 def : Pat<(v2i64 (X86VBroadcast (loadi64 addr:$src))),
5067           (VMOVDDUPrm addr:$src)>;
5068
5069 let Predicates = [UseSSE3] in {
5070   def : Pat<(X86Movddup (memopv2f64 addr:$src)),
5071             (MOVDDUPrm addr:$src)>;
5072 }
5073
5074 //===---------------------------------------------------------------------===//
5075 // SSE3 - Move Unaligned Integer
5076 //===---------------------------------------------------------------------===//
5077
5078 let SchedRW = [WriteLoad] in {
5079 let Predicates = [HasAVX] in {
5080   def VLDDQUrm : S3DI<0xF0, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
5081                    "vlddqu\t{$src, $dst|$dst, $src}",
5082                    [(set VR128:$dst, (int_x86_sse3_ldu_dq addr:$src))]>, VEX, VEX_WIG;
5083   def VLDDQUYrm : S3DI<0xF0, MRMSrcMem, (outs VR256:$dst), (ins i256mem:$src),
5084                    "vlddqu\t{$src, $dst|$dst, $src}",
5085                    [(set VR256:$dst, (int_x86_avx_ldu_dq_256 addr:$src))]>,
5086                    VEX, VEX_L, VEX_WIG;
5087 }
5088 def LDDQUrm : S3DI<0xF0, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
5089                    "lddqu\t{$src, $dst|$dst, $src}",
5090                    [(set VR128:$dst, (int_x86_sse3_ldu_dq addr:$src))],
5091                    IIC_SSE_LDDQU>;
5092 }
5093
5094 //===---------------------------------------------------------------------===//
5095 // SSE3 - Arithmetic
5096 //===---------------------------------------------------------------------===//
5097
5098 multiclass sse3_addsub<Intrinsic Int, string OpcodeStr, RegisterClass RC,
5099                        X86MemOperand x86memop, OpndItins itins,
5100                        PatFrag ld_frag, bit Is2Addr = 1> {
5101   def rr : I<0xD0, MRMSrcReg,
5102        (outs RC:$dst), (ins RC:$src1, RC:$src2),
5103        !if(Is2Addr,
5104            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5105            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5106        [(set RC:$dst, (Int RC:$src1, RC:$src2))], itins.rr>,
5107        Sched<[itins.Sched]>;
5108   def rm : I<0xD0, MRMSrcMem,
5109        (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
5110        !if(Is2Addr,
5111            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5112            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5113        [(set RC:$dst, (Int RC:$src1, (ld_frag addr:$src2)))], itins.rr>,
5114        Sched<[itins.Sched.Folded, ReadAfterLd]>;
5115 }
5116
5117 let Predicates = [HasAVX] in {
5118   let ExeDomain = SSEPackedSingle in {
5119     defm VADDSUBPS : sse3_addsub<int_x86_sse3_addsub_ps, "vaddsubps", VR128,
5120                                f128mem, SSE_ALU_F32P, loadv4f32, 0>, XD, VEX_4V, VEX_WIG;
5121     defm VADDSUBPSY : sse3_addsub<int_x86_avx_addsub_ps_256, "vaddsubps", VR256,
5122                         f256mem, SSE_ALU_F32P, loadv8f32, 0>, XD, VEX_4V, VEX_L, VEX_WIG;
5123   }
5124   let ExeDomain = SSEPackedDouble in {
5125     defm VADDSUBPD : sse3_addsub<int_x86_sse3_addsub_pd, "vaddsubpd", VR128,
5126                                f128mem, SSE_ALU_F64P, loadv2f64, 0>, PD, VEX_4V, VEX_WIG;
5127     defm VADDSUBPDY : sse3_addsub<int_x86_avx_addsub_pd_256, "vaddsubpd", VR256,
5128                         f256mem, SSE_ALU_F64P, loadv4f64, 0>, PD, VEX_4V, VEX_L, VEX_WIG;
5129   }
5130 }
5131 let Constraints = "$src1 = $dst", Predicates = [UseSSE3] in {
5132   let ExeDomain = SSEPackedSingle in
5133   defm ADDSUBPS : sse3_addsub<int_x86_sse3_addsub_ps, "addsubps", VR128,
5134                               f128mem, SSE_ALU_F32P, memopv4f32>, XD;
5135   let ExeDomain = SSEPackedDouble in
5136   defm ADDSUBPD : sse3_addsub<int_x86_sse3_addsub_pd, "addsubpd", VR128,
5137                               f128mem, SSE_ALU_F64P, memopv2f64>, PD;
5138 }
5139
5140 // Patterns used to select 'addsub' instructions.
5141 let Predicates = [HasAVX] in {
5142   def : Pat<(v4f32 (X86Addsub (v4f32 VR128:$lhs), (v4f32 VR128:$rhs))),
5143             (VADDSUBPSrr VR128:$lhs, VR128:$rhs)>;
5144   def : Pat<(v4f32 (X86Addsub (v4f32 VR128:$lhs), (loadv4f32 addr:$rhs))),
5145             (VADDSUBPSrm VR128:$lhs, f128mem:$rhs)>;
5146   def : Pat<(v2f64 (X86Addsub (v2f64 VR128:$lhs), (v2f64 VR128:$rhs))),
5147             (VADDSUBPDrr VR128:$lhs, VR128:$rhs)>;
5148   def : Pat<(v2f64 (X86Addsub (v2f64 VR128:$lhs), (loadv2f64 addr:$rhs))),
5149             (VADDSUBPDrm VR128:$lhs, f128mem:$rhs)>;
5150
5151   def : Pat<(v8f32 (X86Addsub (v8f32 VR256:$lhs), (v8f32 VR256:$rhs))),
5152             (VADDSUBPSYrr VR256:$lhs, VR256:$rhs)>;
5153   def : Pat<(v8f32 (X86Addsub (v8f32 VR256:$lhs), (loadv8f32 addr:$rhs))),
5154             (VADDSUBPSYrm VR256:$lhs, f256mem:$rhs)>;
5155   def : Pat<(v4f64 (X86Addsub (v4f64 VR256:$lhs), (v4f64 VR256:$rhs))),
5156             (VADDSUBPDYrr VR256:$lhs, VR256:$rhs)>;
5157   def : Pat<(v4f64 (X86Addsub (v4f64 VR256:$lhs), (loadv4f64 addr:$rhs))),
5158             (VADDSUBPDYrm VR256:$lhs, f256mem:$rhs)>;
5159 }
5160
5161 let Predicates = [UseSSE3] in {
5162   def : Pat<(v4f32 (X86Addsub (v4f32 VR128:$lhs), (v4f32 VR128:$rhs))),
5163             (ADDSUBPSrr VR128:$lhs, VR128:$rhs)>;
5164   def : Pat<(v4f32 (X86Addsub (v4f32 VR128:$lhs), (memopv4f32 addr:$rhs))),
5165             (ADDSUBPSrm VR128:$lhs, f128mem:$rhs)>;
5166   def : Pat<(v2f64 (X86Addsub (v2f64 VR128:$lhs), (v2f64 VR128:$rhs))),
5167             (ADDSUBPDrr VR128:$lhs, VR128:$rhs)>;
5168   def : Pat<(v2f64 (X86Addsub (v2f64 VR128:$lhs), (memopv2f64 addr:$rhs))),
5169             (ADDSUBPDrm VR128:$lhs, f128mem:$rhs)>;
5170 }
5171
5172 //===---------------------------------------------------------------------===//
5173 // SSE3 Instructions
5174 //===---------------------------------------------------------------------===//
5175
5176 // Horizontal ops
5177 multiclass S3D_Int<bits<8> o, string OpcodeStr, ValueType vt, RegisterClass RC,
5178                    X86MemOperand x86memop, SDNode OpNode, PatFrag ld_frag,
5179                    bit Is2Addr = 1> {
5180   def rr : S3DI<o, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
5181        !if(Is2Addr,
5182          !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5183          !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5184       [(set RC:$dst, (vt (OpNode RC:$src1, RC:$src2)))], IIC_SSE_HADDSUB_RR>,
5185       Sched<[WriteFHAdd]>;
5186
5187   def rm : S3DI<o, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
5188        !if(Is2Addr,
5189          !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5190          !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5191       [(set RC:$dst, (vt (OpNode RC:$src1, (ld_frag addr:$src2))))],
5192         IIC_SSE_HADDSUB_RM>, Sched<[WriteFHAddLd, ReadAfterLd]>;
5193 }
5194 multiclass S3_Int<bits<8> o, string OpcodeStr, ValueType vt, RegisterClass RC,
5195                   X86MemOperand x86memop, SDNode OpNode, PatFrag ld_frag,
5196                   bit Is2Addr = 1> {
5197   def rr : S3I<o, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
5198        !if(Is2Addr,
5199          !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5200          !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5201       [(set RC:$dst, (vt (OpNode RC:$src1, RC:$src2)))], IIC_SSE_HADDSUB_RR>,
5202       Sched<[WriteFHAdd]>;
5203
5204   def rm : S3I<o, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
5205        !if(Is2Addr,
5206          !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5207          !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5208       [(set RC:$dst, (vt (OpNode RC:$src1, (ld_frag addr:$src2))))],
5209         IIC_SSE_HADDSUB_RM>, Sched<[WriteFHAddLd, ReadAfterLd]>;
5210 }
5211
5212 let Predicates = [HasAVX] in {
5213   let ExeDomain = SSEPackedSingle in {
5214     defm VHADDPS  : S3D_Int<0x7C, "vhaddps", v4f32, VR128, f128mem,
5215                             X86fhadd, loadv4f32, 0>, VEX_4V, VEX_WIG;
5216     defm VHSUBPS  : S3D_Int<0x7D, "vhsubps", v4f32, VR128, f128mem,
5217                             X86fhsub, loadv4f32, 0>, VEX_4V, VEX_WIG;
5218     defm VHADDPSY : S3D_Int<0x7C, "vhaddps", v8f32, VR256, f256mem,
5219                             X86fhadd, loadv8f32, 0>, VEX_4V, VEX_L, VEX_WIG;
5220     defm VHSUBPSY : S3D_Int<0x7D, "vhsubps", v8f32, VR256, f256mem,
5221                             X86fhsub, loadv8f32, 0>, VEX_4V, VEX_L, VEX_WIG;
5222   }
5223   let ExeDomain = SSEPackedDouble in {
5224     defm VHADDPD  : S3_Int <0x7C, "vhaddpd", v2f64, VR128, f128mem,
5225                             X86fhadd, loadv2f64, 0>, VEX_4V, VEX_WIG;
5226     defm VHSUBPD  : S3_Int <0x7D, "vhsubpd", v2f64, VR128, f128mem,
5227                             X86fhsub, loadv2f64, 0>, VEX_4V, VEX_WIG;
5228     defm VHADDPDY : S3_Int <0x7C, "vhaddpd", v4f64, VR256, f256mem,
5229                             X86fhadd, loadv4f64, 0>, VEX_4V, VEX_L, VEX_WIG;
5230     defm VHSUBPDY : S3_Int <0x7D, "vhsubpd", v4f64, VR256, f256mem,
5231                             X86fhsub, loadv4f64, 0>, VEX_4V, VEX_L, VEX_WIG;
5232   }
5233 }
5234
5235 let Constraints = "$src1 = $dst" in {
5236   let ExeDomain = SSEPackedSingle in {
5237     defm HADDPS : S3D_Int<0x7C, "haddps", v4f32, VR128, f128mem, X86fhadd,
5238                           memopv4f32>;
5239     defm HSUBPS : S3D_Int<0x7D, "hsubps", v4f32, VR128, f128mem, X86fhsub,
5240                           memopv4f32>;
5241   }
5242   let ExeDomain = SSEPackedDouble in {
5243     defm HADDPD : S3_Int<0x7C, "haddpd", v2f64, VR128, f128mem, X86fhadd,
5244                          memopv2f64>;
5245     defm HSUBPD : S3_Int<0x7D, "hsubpd", v2f64, VR128, f128mem, X86fhsub,
5246                          memopv2f64>;
5247   }
5248 }
5249
5250 //===---------------------------------------------------------------------===//
5251 // SSSE3 - Packed Absolute Instructions
5252 //===---------------------------------------------------------------------===//
5253
5254
5255 /// SS3I_unop_rm_int - Simple SSSE3 unary op whose type can be v*{i8,i16,i32}.
5256 multiclass SS3I_unop_rm<bits<8> opc, string OpcodeStr, ValueType vt,
5257                         SDNode OpNode, PatFrag ld_frag> {
5258   def rr : SS38I<opc, MRMSrcReg, (outs VR128:$dst),
5259                  (ins VR128:$src),
5260                  !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5261                  [(set VR128:$dst, (vt (OpNode VR128:$src)))],
5262                  IIC_SSE_PABS_RR>, Sched<[WriteVecALU]>;
5263
5264   def rm : SS38I<opc, MRMSrcMem, (outs VR128:$dst),
5265                  (ins i128mem:$src),
5266                  !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5267                  [(set VR128:$dst,
5268                    (vt (OpNode (bitconvert (ld_frag addr:$src)))))],
5269                  IIC_SSE_PABS_RM>, Sched<[WriteVecALULd]>;
5270 }
5271
5272 /// SS3I_unop_rm_int_y - Simple SSSE3 unary op whose type can be v*{i8,i16,i32}.
5273 multiclass SS3I_unop_rm_y<bits<8> opc, string OpcodeStr, ValueType vt,
5274                           SDNode OpNode> {
5275   def Yrr : SS38I<opc, MRMSrcReg, (outs VR256:$dst),
5276                   (ins VR256:$src),
5277                   !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5278                   [(set VR256:$dst, (vt (OpNode VR256:$src)))]>,
5279                   Sched<[WriteVecALU]>;
5280
5281   def Yrm : SS38I<opc, MRMSrcMem, (outs VR256:$dst),
5282                   (ins i256mem:$src),
5283                   !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5284                   [(set VR256:$dst,
5285                     (vt (OpNode (bitconvert (loadv4i64 addr:$src)))))]>,
5286                   Sched<[WriteVecALULd]>;
5287 }
5288
5289 let Predicates = [HasAVX, NoVLX_Or_NoBWI] in {
5290   defm VPABSB  : SS3I_unop_rm<0x1C, "vpabsb", v16i8, abs, loadv2i64>, VEX, VEX_WIG;
5291   defm VPABSW  : SS3I_unop_rm<0x1D, "vpabsw", v8i16, abs, loadv2i64>, VEX, VEX_WIG;
5292 }
5293 let Predicates = [HasAVX, NoVLX] in {
5294   defm VPABSD  : SS3I_unop_rm<0x1E, "vpabsd", v4i32, abs, loadv2i64>, VEX, VEX_WIG;
5295 }
5296 let Predicates = [HasAVX2, NoVLX_Or_NoBWI] in {
5297   defm VPABSB  : SS3I_unop_rm_y<0x1C, "vpabsb", v32i8, abs>, VEX, VEX_L, VEX_WIG;
5298   defm VPABSW  : SS3I_unop_rm_y<0x1D, "vpabsw", v16i16, abs>, VEX, VEX_L, VEX_WIG;
5299 }
5300 let Predicates = [HasAVX2, NoVLX] in {
5301   defm VPABSD  : SS3I_unop_rm_y<0x1E, "vpabsd", v8i32, abs>, VEX, VEX_L, VEX_WIG;
5302 }
5303
5304 defm PABSB : SS3I_unop_rm<0x1C, "pabsb", v16i8, abs, memopv2i64>;
5305 defm PABSW : SS3I_unop_rm<0x1D, "pabsw", v8i16, abs, memopv2i64>;
5306 defm PABSD : SS3I_unop_rm<0x1E, "pabsd", v4i32, abs, memopv2i64>;
5307
5308 //===---------------------------------------------------------------------===//
5309 // SSSE3 - Packed Binary Operator Instructions
5310 //===---------------------------------------------------------------------===//
5311
5312 let Sched = WritePHAdd in {
5313 def SSE_PHADDSUBD : OpndItins<
5314   IIC_SSE_PHADDSUBD_RR, IIC_SSE_PHADDSUBD_RM
5315 >;
5316 def SSE_PHADDSUBSW : OpndItins<
5317   IIC_SSE_PHADDSUBSW_RR, IIC_SSE_PHADDSUBSW_RM
5318 >;
5319 def SSE_PHADDSUBW : OpndItins<
5320   IIC_SSE_PHADDSUBW_RR, IIC_SSE_PHADDSUBW_RM
5321 >;
5322 }
5323 let Sched = WriteShuffle in
5324 def SSE_PSHUFB : OpndItins<
5325   IIC_SSE_PSHUFB_RR, IIC_SSE_PSHUFB_RM
5326 >;
5327 let Sched = WriteVecALU in
5328 def SSE_PSIGN : OpndItins<
5329   IIC_SSE_PSIGN_RR, IIC_SSE_PSIGN_RM
5330 >;
5331 let Sched = WriteVecIMul in
5332 def SSE_PMULHRSW : OpndItins<
5333   IIC_SSE_PMULHRSW, IIC_SSE_PMULHRSW
5334 >;
5335
5336 /// SS3I_binop_rm - Simple SSSE3 bin op
5337 multiclass SS3I_binop_rm<bits<8> opc, string OpcodeStr, SDNode OpNode,
5338                          ValueType DstVT, ValueType OpVT, RegisterClass RC,
5339                          PatFrag memop_frag, X86MemOperand x86memop,
5340                          OpndItins itins, bit Is2Addr = 1> {
5341   let isCommutable = 1 in
5342   def rr : SS38I<opc, MRMSrcReg, (outs RC:$dst),
5343        (ins RC:$src1, RC:$src2),
5344        !if(Is2Addr,
5345          !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5346          !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5347        [(set RC:$dst, (DstVT (OpNode (OpVT RC:$src1), RC:$src2)))], itins.rr>,
5348        Sched<[itins.Sched]>;
5349   def rm : SS38I<opc, MRMSrcMem, (outs RC:$dst),
5350        (ins RC:$src1, x86memop:$src2),
5351        !if(Is2Addr,
5352          !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5353          !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5354        [(set RC:$dst,
5355          (DstVT (OpNode (OpVT RC:$src1),
5356           (bitconvert (memop_frag addr:$src2)))))], itins.rm>,
5357        Sched<[itins.Sched.Folded, ReadAfterLd]>;
5358 }
5359
5360 /// SS3I_binop_rm_int - Simple SSSE3 bin op whose type can be v*{i8,i16,i32}.
5361 multiclass SS3I_binop_rm_int<bits<8> opc, string OpcodeStr,
5362                              Intrinsic IntId128, OpndItins itins,
5363                              PatFrag ld_frag, bit Is2Addr = 1> {
5364   let isCommutable = 1 in
5365   def rr128 : SS38I<opc, MRMSrcReg, (outs VR128:$dst),
5366        (ins VR128:$src1, VR128:$src2),
5367        !if(Is2Addr,
5368          !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5369          !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5370        [(set VR128:$dst, (IntId128 VR128:$src1, VR128:$src2))]>,
5371        Sched<[itins.Sched]>;
5372   def rm128 : SS38I<opc, MRMSrcMem, (outs VR128:$dst),
5373        (ins VR128:$src1, i128mem:$src2),
5374        !if(Is2Addr,
5375          !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5376          !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5377        [(set VR128:$dst,
5378          (IntId128 VR128:$src1,
5379           (bitconvert (ld_frag addr:$src2))))]>,
5380        Sched<[itins.Sched.Folded, ReadAfterLd]>;
5381 }
5382
5383 multiclass SS3I_binop_rm_int_y<bits<8> opc, string OpcodeStr,
5384                                Intrinsic IntId256,
5385                                X86FoldableSchedWrite Sched> {
5386   let isCommutable = 1 in
5387   def rr256 : SS38I<opc, MRMSrcReg, (outs VR256:$dst),
5388        (ins VR256:$src1, VR256:$src2),
5389        !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5390        [(set VR256:$dst, (IntId256 VR256:$src1, VR256:$src2))]>,
5391        Sched<[Sched]>;
5392   def rm256 : SS38I<opc, MRMSrcMem, (outs VR256:$dst),
5393        (ins VR256:$src1, i256mem:$src2),
5394        !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5395        [(set VR256:$dst,
5396          (IntId256 VR256:$src1, (bitconvert (loadv4i64 addr:$src2))))]>,
5397        Sched<[Sched.Folded, ReadAfterLd]>;
5398 }
5399
5400 let ImmT = NoImm, Predicates = [HasAVX, NoVLX_Or_NoBWI] in {
5401 let isCommutable = 0 in {
5402   defm VPSHUFB    : SS3I_binop_rm<0x00, "vpshufb", X86pshufb, v16i8, v16i8,
5403                                   VR128, loadv2i64, i128mem,
5404                                   SSE_PSHUFB, 0>, VEX_4V, VEX_WIG;
5405   defm VPMADDUBSW : SS3I_binop_rm<0x04, "vpmaddubsw", X86vpmaddubsw, v8i16,
5406                                   v16i8, VR128, loadv2i64, i128mem,
5407                                   SSE_PMADD, 0>, VEX_4V, VEX_WIG;
5408 }
5409 defm VPMULHRSW    : SS3I_binop_rm<0x0B, "vpmulhrsw", X86mulhrs, v8i16, v8i16,
5410                                   VR128, loadv2i64, i128mem,
5411                                   SSE_PMULHRSW, 0>, VEX_4V, VEX_WIG;
5412 }
5413
5414 let ImmT = NoImm, Predicates = [HasAVX] in {
5415 let isCommutable = 0 in {
5416   defm VPHADDW    : SS3I_binop_rm<0x01, "vphaddw", X86hadd, v8i16, v8i16, VR128,
5417                                   loadv2i64, i128mem,
5418                                   SSE_PHADDSUBW, 0>, VEX_4V, VEX_WIG;
5419   defm VPHADDD    : SS3I_binop_rm<0x02, "vphaddd", X86hadd, v4i32, v4i32, VR128,
5420                                   loadv2i64, i128mem,
5421                                   SSE_PHADDSUBD, 0>, VEX_4V, VEX_WIG;
5422   defm VPHSUBW    : SS3I_binop_rm<0x05, "vphsubw", X86hsub, v8i16, v8i16, VR128,
5423                                   loadv2i64, i128mem,
5424                                   SSE_PHADDSUBW, 0>, VEX_4V, VEX_WIG;
5425   defm VPHSUBD    : SS3I_binop_rm<0x06, "vphsubd", X86hsub, v4i32, v4i32, VR128,
5426                                   loadv2i64, i128mem,
5427                                   SSE_PHADDSUBD, 0>, VEX_4V;
5428   defm VPSIGNB    : SS3I_binop_rm_int<0x08, "vpsignb",
5429                                       int_x86_ssse3_psign_b_128,
5430                                       SSE_PSIGN, loadv2i64, 0>, VEX_4V, VEX_WIG;
5431   defm VPSIGNW    : SS3I_binop_rm_int<0x09, "vpsignw",
5432                                       int_x86_ssse3_psign_w_128,
5433                                       SSE_PSIGN, loadv2i64, 0>, VEX_4V, VEX_WIG;
5434   defm VPSIGND    : SS3I_binop_rm_int<0x0A, "vpsignd",
5435                                       int_x86_ssse3_psign_d_128,
5436                                       SSE_PSIGN, loadv2i64, 0>, VEX_4V, VEX_WIG;
5437   defm VPHADDSW   : SS3I_binop_rm_int<0x03, "vphaddsw",
5438                                       int_x86_ssse3_phadd_sw_128,
5439                                       SSE_PHADDSUBSW, loadv2i64, 0>, VEX_4V, VEX_WIG;
5440   defm VPHSUBSW   : SS3I_binop_rm_int<0x07, "vphsubsw",
5441                                       int_x86_ssse3_phsub_sw_128,
5442                                       SSE_PHADDSUBSW, loadv2i64, 0>, VEX_4V, VEX_WIG;
5443 }
5444 }
5445
5446 let ImmT = NoImm, Predicates = [HasAVX2, NoVLX_Or_NoBWI] in {
5447 let isCommutable = 0 in {
5448   defm VPSHUFBY   : SS3I_binop_rm<0x00, "vpshufb", X86pshufb, v32i8, v32i8,
5449                                   VR256, loadv4i64, i256mem,
5450                                   SSE_PSHUFB, 0>, VEX_4V, VEX_L, VEX_WIG;
5451   defm VPMADDUBSWY : SS3I_binop_rm<0x04, "vpmaddubsw", X86vpmaddubsw, v16i16,
5452                                    v32i8, VR256, loadv4i64, i256mem,
5453                                    SSE_PMADD, 0>, VEX_4V, VEX_L, VEX_WIG;
5454 }
5455 defm VPMULHRSWY   : SS3I_binop_rm<0x0B, "vpmulhrsw", X86mulhrs, v16i16, v16i16,
5456                                   VR256, loadv4i64, i256mem,
5457                                   SSE_PMULHRSW, 0>, VEX_4V, VEX_L, VEX_WIG;
5458 }
5459
5460 let ImmT = NoImm, Predicates = [HasAVX2] in {
5461 let isCommutable = 0 in {
5462   defm VPHADDWY   : SS3I_binop_rm<0x01, "vphaddw", X86hadd, v16i16, v16i16,
5463                                   VR256, loadv4i64, i256mem,
5464                                   SSE_PHADDSUBW, 0>, VEX_4V, VEX_L, VEX_WIG;
5465   defm VPHADDDY   : SS3I_binop_rm<0x02, "vphaddd", X86hadd, v8i32, v8i32, VR256,
5466                                   loadv4i64, i256mem,
5467                                   SSE_PHADDSUBW, 0>, VEX_4V, VEX_L, VEX_WIG;
5468   defm VPHSUBWY   : SS3I_binop_rm<0x05, "vphsubw", X86hsub, v16i16, v16i16,
5469                                   VR256, loadv4i64, i256mem,
5470                                   SSE_PHADDSUBW, 0>, VEX_4V, VEX_L, VEX_WIG;
5471   defm VPHSUBDY   : SS3I_binop_rm<0x06, "vphsubd", X86hsub, v8i32, v8i32, VR256,
5472                                   loadv4i64, i256mem,
5473                                   SSE_PHADDSUBW, 0>, VEX_4V, VEX_L;
5474   defm VPSIGNBY   : SS3I_binop_rm_int_y<0x08, "vpsignb", int_x86_avx2_psign_b,
5475                                         WriteVecALU>, VEX_4V, VEX_L, VEX_WIG;
5476   defm VPSIGNWY   : SS3I_binop_rm_int_y<0x09, "vpsignw", int_x86_avx2_psign_w,
5477                                         WriteVecALU>, VEX_4V, VEX_L, VEX_WIG;
5478   defm VPSIGNDY   : SS3I_binop_rm_int_y<0x0A, "vpsignd", int_x86_avx2_psign_d,
5479                                         WriteVecALU>, VEX_4V, VEX_L, VEX_WIG;
5480   defm VPHADDSW   : SS3I_binop_rm_int_y<0x03, "vphaddsw",
5481                                         int_x86_avx2_phadd_sw,
5482                                         WriteVecALU>, VEX_4V, VEX_L, VEX_WIG;
5483   defm VPHSUBSW   : SS3I_binop_rm_int_y<0x07, "vphsubsw",
5484                                         int_x86_avx2_phsub_sw,
5485                                         WriteVecALU>, VEX_4V, VEX_L, VEX_WIG;
5486 }
5487 }
5488
5489 // None of these have i8 immediate fields.
5490 let ImmT = NoImm, Constraints = "$src1 = $dst" in {
5491 let isCommutable = 0 in {
5492   defm PHADDW    : SS3I_binop_rm<0x01, "phaddw", X86hadd, v8i16, v8i16, VR128,
5493                                  memopv2i64, i128mem, SSE_PHADDSUBW>;
5494   defm PHADDD    : SS3I_binop_rm<0x02, "phaddd", X86hadd, v4i32, v4i32, VR128,
5495                                  memopv2i64, i128mem, SSE_PHADDSUBD>;
5496   defm PHSUBW    : SS3I_binop_rm<0x05, "phsubw", X86hsub, v8i16, v8i16, VR128,
5497                                  memopv2i64, i128mem, SSE_PHADDSUBW>;
5498   defm PHSUBD    : SS3I_binop_rm<0x06, "phsubd", X86hsub, v4i32, v4i32, VR128,
5499                                  memopv2i64, i128mem, SSE_PHADDSUBD>;
5500   defm PSIGNB    : SS3I_binop_rm_int<0x08, "psignb", int_x86_ssse3_psign_b_128,
5501                                      SSE_PSIGN, memopv2i64>;
5502   defm PSIGNW    : SS3I_binop_rm_int<0x09, "psignw", int_x86_ssse3_psign_w_128,
5503                                      SSE_PSIGN, memopv2i64>;
5504   defm PSIGND    : SS3I_binop_rm_int<0x0A, "psignd", int_x86_ssse3_psign_d_128,
5505                                      SSE_PSIGN, memopv2i64>;
5506   defm PSHUFB    : SS3I_binop_rm<0x00, "pshufb", X86pshufb, v16i8, v16i8, VR128,
5507                                  memopv2i64, i128mem, SSE_PSHUFB>;
5508   defm PHADDSW   : SS3I_binop_rm_int<0x03, "phaddsw",
5509                                      int_x86_ssse3_phadd_sw_128,
5510                                      SSE_PHADDSUBSW, memopv2i64>;
5511   defm PHSUBSW   : SS3I_binop_rm_int<0x07, "phsubsw",
5512                                      int_x86_ssse3_phsub_sw_128,
5513                                      SSE_PHADDSUBSW, memopv2i64>;
5514   defm PMADDUBSW : SS3I_binop_rm<0x04, "pmaddubsw", X86vpmaddubsw, v8i16,
5515                                  v16i8, VR128, memopv2i64, i128mem,
5516                                  SSE_PMADD>;
5517 }
5518 defm PMULHRSW    : SS3I_binop_rm<0x0B, "pmulhrsw", X86mulhrs, v8i16, v8i16,
5519                                  VR128, memopv2i64, i128mem, SSE_PMULHRSW>;
5520 }
5521
5522 //===---------------------------------------------------------------------===//
5523 // SSSE3 - Packed Align Instruction Patterns
5524 //===---------------------------------------------------------------------===//
5525
5526 multiclass ssse3_palignr<string asm, bit Is2Addr = 1> {
5527   let hasSideEffects = 0 in {
5528   def rri : SS3AI<0x0F, MRMSrcReg, (outs VR128:$dst),
5529       (ins VR128:$src1, VR128:$src2, u8imm:$src3),
5530       !if(Is2Addr,
5531         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5532         !strconcat(asm,
5533                   "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5534       [], IIC_SSE_PALIGNRR>, Sched<[WriteShuffle]>;
5535   let mayLoad = 1 in
5536   def rmi : SS3AI<0x0F, MRMSrcMem, (outs VR128:$dst),
5537       (ins VR128:$src1, i128mem:$src2, u8imm:$src3),
5538       !if(Is2Addr,
5539         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5540         !strconcat(asm,
5541                   "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5542       [], IIC_SSE_PALIGNRM>, Sched<[WriteShuffleLd, ReadAfterLd]>;
5543   }
5544 }
5545
5546 multiclass ssse3_palignr_y<string asm, bit Is2Addr = 1> {
5547   let hasSideEffects = 0 in {
5548   def Yrri : SS3AI<0x0F, MRMSrcReg, (outs VR256:$dst),
5549       (ins VR256:$src1, VR256:$src2, u8imm:$src3),
5550       !strconcat(asm,
5551                  "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
5552       []>, Sched<[WriteShuffle]>;
5553   let mayLoad = 1 in
5554   def Yrmi : SS3AI<0x0F, MRMSrcMem, (outs VR256:$dst),
5555       (ins VR256:$src1, i256mem:$src2, u8imm:$src3),
5556       !strconcat(asm,
5557                  "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
5558       []>, Sched<[WriteShuffleLd, ReadAfterLd]>;
5559   }
5560 }
5561
5562 let Predicates = [HasAVX] in
5563   defm VPALIGNR : ssse3_palignr<"vpalignr", 0>, VEX_4V, VEX_WIG;
5564 let Predicates = [HasAVX2] in
5565   defm VPALIGNR : ssse3_palignr_y<"vpalignr", 0>, VEX_4V, VEX_L, VEX_WIG;
5566 let Constraints = "$src1 = $dst", Predicates = [UseSSSE3] in
5567   defm PALIGNR : ssse3_palignr<"palignr">;
5568
5569 let Predicates = [HasAVX2, NoVLX_Or_NoBWI] in {
5570 def : Pat<(v8i32 (X86PAlignr VR256:$src1, VR256:$src2, (i8 imm:$imm))),
5571           (VPALIGNRYrri VR256:$src1, VR256:$src2, imm:$imm)>;
5572 def : Pat<(v8f32 (X86PAlignr VR256:$src1, VR256:$src2, (i8 imm:$imm))),
5573           (VPALIGNRYrri VR256:$src1, VR256:$src2, imm:$imm)>;
5574 def : Pat<(v16i16 (X86PAlignr VR256:$src1, VR256:$src2, (i8 imm:$imm))),
5575           (VPALIGNRYrri VR256:$src1, VR256:$src2, imm:$imm)>;
5576 def : Pat<(v32i8 (X86PAlignr VR256:$src1, VR256:$src2, (i8 imm:$imm))),
5577           (VPALIGNRYrri VR256:$src1, VR256:$src2, imm:$imm)>;
5578 }
5579
5580 let Predicates = [HasAVX, NoVLX_Or_NoBWI] in {
5581 def : Pat<(v4i32 (X86PAlignr VR128:$src1, VR128:$src2, (i8 imm:$imm))),
5582           (VPALIGNRrri VR128:$src1, VR128:$src2, imm:$imm)>;
5583 def : Pat<(v4f32 (X86PAlignr VR128:$src1, VR128:$src2, (i8 imm:$imm))),
5584           (VPALIGNRrri VR128:$src1, VR128:$src2, imm:$imm)>;
5585 def : Pat<(v8i16 (X86PAlignr VR128:$src1, VR128:$src2, (i8 imm:$imm))),
5586           (VPALIGNRrri VR128:$src1, VR128:$src2, imm:$imm)>;
5587 def : Pat<(v16i8 (X86PAlignr VR128:$src1, VR128:$src2, (i8 imm:$imm))),
5588           (VPALIGNRrri VR128:$src1, VR128:$src2, imm:$imm)>;
5589 }
5590
5591 let Predicates = [UseSSSE3] in {
5592 def : Pat<(v4i32 (X86PAlignr VR128:$src1, VR128:$src2, (i8 imm:$imm))),
5593           (PALIGNRrri VR128:$src1, VR128:$src2, imm:$imm)>;
5594 def : Pat<(v4f32 (X86PAlignr VR128:$src1, VR128:$src2, (i8 imm:$imm))),
5595           (PALIGNRrri VR128:$src1, VR128:$src2, imm:$imm)>;
5596 def : Pat<(v8i16 (X86PAlignr VR128:$src1, VR128:$src2, (i8 imm:$imm))),
5597           (PALIGNRrri VR128:$src1, VR128:$src2, imm:$imm)>;
5598 def : Pat<(v16i8 (X86PAlignr VR128:$src1, VR128:$src2, (i8 imm:$imm))),
5599           (PALIGNRrri VR128:$src1, VR128:$src2, imm:$imm)>;
5600 }
5601
5602 //===---------------------------------------------------------------------===//
5603 // SSSE3 - Thread synchronization
5604 //===---------------------------------------------------------------------===//
5605
5606 let SchedRW = [WriteSystem] in {
5607 let usesCustomInserter = 1 in {
5608 def MONITOR : PseudoI<(outs), (ins i32mem:$src1, GR32:$src2, GR32:$src3),
5609                 [(int_x86_sse3_monitor addr:$src1, GR32:$src2, GR32:$src3)]>,
5610                 Requires<[HasSSE3]>;
5611 }
5612
5613 let Uses = [EAX, ECX, EDX] in
5614 def MONITORrrr : I<0x01, MRM_C8, (outs), (ins), "monitor", [], IIC_SSE_MONITOR>,
5615                  TB, Requires<[HasSSE3]>;
5616
5617 let Uses = [ECX, EAX] in
5618 def MWAITrr   : I<0x01, MRM_C9, (outs), (ins), "mwait",
5619                 [(int_x86_sse3_mwait ECX, EAX)], IIC_SSE_MWAIT>,
5620                 TB, Requires<[HasSSE3]>;
5621 } // SchedRW
5622
5623 def : InstAlias<"mwait\t{%eax, %ecx|ecx, eax}", (MWAITrr)>, Requires<[Not64BitMode]>;
5624 def : InstAlias<"mwait\t{%rax, %rcx|rcx, rax}", (MWAITrr)>, Requires<[In64BitMode]>;
5625
5626 def : InstAlias<"monitor\t{%eax, %ecx, %edx|edx, ecx, eax}", (MONITORrrr)>,
5627       Requires<[Not64BitMode]>;
5628 def : InstAlias<"monitor\t{%rax, %rcx, %rdx|rdx, rcx, rax}", (MONITORrrr)>,
5629       Requires<[In64BitMode]>;
5630
5631 //===----------------------------------------------------------------------===//
5632 // SSE4.1 - Packed Move with Sign/Zero Extend
5633 //===----------------------------------------------------------------------===//
5634
5635 multiclass SS41I_pmovx_rrrm<bits<8> opc, string OpcodeStr, X86MemOperand MemOp,
5636                           RegisterClass OutRC, RegisterClass InRC,
5637                           OpndItins itins> {
5638   def rr : SS48I<opc, MRMSrcReg, (outs OutRC:$dst), (ins InRC:$src),
5639                  !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5640                  [], itins.rr>,
5641                  Sched<[itins.Sched]>;
5642
5643   def rm : SS48I<opc, MRMSrcMem, (outs OutRC:$dst), (ins MemOp:$src),
5644                  !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5645                  [],
5646                  itins.rm>, Sched<[itins.Sched.Folded]>;
5647 }
5648
5649 multiclass SS41I_pmovx_rm_all<bits<8> opc, string OpcodeStr,
5650                           X86MemOperand MemOp, X86MemOperand MemYOp,
5651                           OpndItins SSEItins, OpndItins AVXItins,
5652                           OpndItins AVX2Itins, Predicate prd> {
5653   defm NAME : SS41I_pmovx_rrrm<opc, OpcodeStr, MemOp, VR128, VR128, SSEItins>;
5654   let Predicates = [HasAVX, prd] in
5655     defm V#NAME   : SS41I_pmovx_rrrm<opc, !strconcat("v", OpcodeStr), MemOp,
5656                                      VR128, VR128, AVXItins>, VEX, VEX_WIG;
5657   let Predicates = [HasAVX2, prd] in
5658     defm V#NAME#Y : SS41I_pmovx_rrrm<opc, !strconcat("v", OpcodeStr), MemYOp,
5659                                      VR256, VR128, AVX2Itins>, VEX, VEX_L, VEX_WIG;
5660 }
5661
5662 multiclass SS41I_pmovx_rm<bits<8> opc, string OpcodeStr, X86MemOperand MemOp,
5663                           X86MemOperand MemYOp, Predicate prd> {
5664   defm PMOVSX#NAME : SS41I_pmovx_rm_all<opc, !strconcat("pmovsx", OpcodeStr),
5665                                         MemOp, MemYOp,
5666                                         SSE_INTALU_ITINS_SHUFF_P,
5667                                         DEFAULT_ITINS_SHUFFLESCHED,
5668                                         DEFAULT_ITINS_SHUFFLESCHED, prd>;
5669   defm PMOVZX#NAME : SS41I_pmovx_rm_all<!add(opc, 0x10),
5670                                         !strconcat("pmovzx", OpcodeStr),
5671                                         MemOp, MemYOp,
5672                                         SSE_INTALU_ITINS_SHUFF_P,
5673                                         DEFAULT_ITINS_SHUFFLESCHED,
5674                                         DEFAULT_ITINS_SHUFFLESCHED, prd>;
5675 }
5676
5677 defm BW : SS41I_pmovx_rm<0x20, "bw", i64mem, i128mem, NoVLX_Or_NoBWI>;
5678 defm WD : SS41I_pmovx_rm<0x23, "wd", i64mem, i128mem, NoVLX>;
5679 defm DQ : SS41I_pmovx_rm<0x25, "dq", i64mem, i128mem, NoVLX>;
5680
5681 defm BD : SS41I_pmovx_rm<0x21, "bd", i32mem, i64mem, NoVLX>;
5682 defm WQ : SS41I_pmovx_rm<0x24, "wq", i32mem, i64mem, NoVLX>;
5683
5684 defm BQ : SS41I_pmovx_rm<0x22, "bq", i16mem, i32mem, NoVLX>;
5685
5686 // AVX2 Patterns
5687 multiclass SS41I_pmovx_avx2_patterns<string OpcPrefix, string ExtTy, SDNode ExtOp> {
5688   // Register-Register patterns
5689   let Predicates = [HasAVX, NoVLX_Or_NoBWI] in {
5690   def : Pat<(v16i16 (ExtOp (v16i8 VR128:$src))),
5691             (!cast<I>(OpcPrefix#BWYrr) VR128:$src)>;
5692   }
5693   let Predicates = [HasAVX, NoVLX] in {
5694   def : Pat<(v8i32 (ExtOp (v16i8 VR128:$src))),
5695             (!cast<I>(OpcPrefix#BDYrr) VR128:$src)>;
5696   def : Pat<(v4i64 (ExtOp (v16i8 VR128:$src))),
5697             (!cast<I>(OpcPrefix#BQYrr) VR128:$src)>;
5698
5699   def : Pat<(v8i32 (ExtOp (v8i16 VR128:$src))),
5700             (!cast<I>(OpcPrefix#WDYrr) VR128:$src)>;
5701   def : Pat<(v4i64 (ExtOp (v8i16 VR128:$src))),
5702             (!cast<I>(OpcPrefix#WQYrr) VR128:$src)>;
5703
5704   def : Pat<(v4i64 (ExtOp (v4i32 VR128:$src))),
5705             (!cast<I>(OpcPrefix#DQYrr) VR128:$src)>;
5706   }
5707
5708   // Simple Register-Memory patterns
5709   let Predicates = [HasAVX, NoVLX_Or_NoBWI] in {
5710   def : Pat<(v16i16 (!cast<PatFrag>(ExtTy#"extloadvi8") addr:$src)),
5711             (!cast<I>(OpcPrefix#BWYrm) addr:$src)>;
5712   }
5713   let Predicates = [HasAVX, NoVLX] in {
5714   def : Pat<(v8i32 (!cast<PatFrag>(ExtTy#"extloadvi8") addr:$src)),
5715             (!cast<I>(OpcPrefix#BDYrm) addr:$src)>;
5716   def : Pat<(v4i64 (!cast<PatFrag>(ExtTy#"extloadvi8") addr:$src)),
5717             (!cast<I>(OpcPrefix#BQYrm) addr:$src)>;
5718
5719   def : Pat<(v8i32 (!cast<PatFrag>(ExtTy#"extloadvi16") addr:$src)),
5720             (!cast<I>(OpcPrefix#WDYrm) addr:$src)>;
5721   def : Pat<(v4i64 (!cast<PatFrag>(ExtTy#"extloadvi16") addr:$src)),
5722             (!cast<I>(OpcPrefix#WQYrm) addr:$src)>;
5723
5724   def : Pat<(v4i64 (!cast<PatFrag>(ExtTy#"extloadvi32") addr:$src)),
5725             (!cast<I>(OpcPrefix#DQYrm) addr:$src)>;
5726   }
5727
5728   // AVX2 Register-Memory patterns
5729   let Predicates = [HasAVX, NoVLX_Or_NoBWI] in {
5730   def : Pat<(v16i16 (ExtOp (bc_v16i8 (loadv2i64 addr:$src)))),
5731             (!cast<I>(OpcPrefix#BWYrm) addr:$src)>;
5732   def : Pat<(v16i16 (ExtOp (v16i8 (vzmovl_v2i64 addr:$src)))),
5733             (!cast<I>(OpcPrefix#BWYrm) addr:$src)>;
5734   def : Pat<(v16i16 (ExtOp (v16i8 (vzload_v2i64 addr:$src)))),
5735             (!cast<I>(OpcPrefix#BWYrm) addr:$src)>;
5736   }
5737   let Predicates = [HasAVX, NoVLX] in {
5738   def : Pat<(v8i32 (ExtOp (bc_v16i8 (v2i64 (scalar_to_vector (loadi64 addr:$src)))))),
5739             (!cast<I>(OpcPrefix#BDYrm) addr:$src)>;
5740   def : Pat<(v8i32 (ExtOp (v16i8 (vzmovl_v2i64 addr:$src)))),
5741             (!cast<I>(OpcPrefix#BDYrm) addr:$src)>;
5742   def : Pat<(v8i32 (ExtOp (v16i8 (vzload_v2i64 addr:$src)))),
5743             (!cast<I>(OpcPrefix#BDYrm) addr:$src)>;
5744   def : Pat<(v8i32 (ExtOp (bc_v16i8 (loadv2i64 addr:$src)))),
5745             (!cast<I>(OpcPrefix#BDYrm) addr:$src)>;
5746
5747   def : Pat<(v4i64 (ExtOp (bc_v16i8 (v4i32 (scalar_to_vector (loadi32 addr:$src)))))),
5748             (!cast<I>(OpcPrefix#BQYrm) addr:$src)>;
5749   def : Pat<(v4i64 (ExtOp (v16i8 (vzmovl_v4i32 addr:$src)))),
5750             (!cast<I>(OpcPrefix#BQYrm) addr:$src)>;
5751   def : Pat<(v4i64 (ExtOp (v16i8 (vzload_v2i64 addr:$src)))),
5752             (!cast<I>(OpcPrefix#BQYrm) addr:$src)>;
5753   def : Pat<(v4i64 (ExtOp (bc_v16i8 (loadv2i64 addr:$src)))),
5754             (!cast<I>(OpcPrefix#BQYrm) addr:$src)>;
5755
5756   def : Pat<(v8i32 (ExtOp (bc_v8i16 (loadv2i64 addr:$src)))),
5757             (!cast<I>(OpcPrefix#WDYrm) addr:$src)>;
5758   def : Pat<(v8i32 (ExtOp (v8i16 (vzmovl_v2i64 addr:$src)))),
5759             (!cast<I>(OpcPrefix#WDYrm) addr:$src)>;
5760   def : Pat<(v8i32 (ExtOp (v8i16 (vzload_v2i64 addr:$src)))),
5761             (!cast<I>(OpcPrefix#WDYrm) addr:$src)>;
5762
5763   def : Pat<(v4i64 (ExtOp (bc_v8i16 (v2i64 (scalar_to_vector (loadi64 addr:$src)))))),
5764             (!cast<I>(OpcPrefix#WQYrm) addr:$src)>;
5765   def : Pat<(v4i64 (ExtOp (v8i16 (vzmovl_v2i64 addr:$src)))),
5766             (!cast<I>(OpcPrefix#WQYrm) addr:$src)>;
5767   def : Pat<(v4i64 (ExtOp (v8i16 (vzload_v2i64 addr:$src)))),
5768             (!cast<I>(OpcPrefix#WQYrm) addr:$src)>;
5769   def : Pat<(v4i64 (ExtOp (bc_v8i16 (loadv2i64 addr:$src)))),
5770             (!cast<I>(OpcPrefix#WQYrm) addr:$src)>;
5771
5772   def : Pat<(v4i64 (ExtOp (bc_v4i32 (loadv2i64 addr:$src)))),
5773             (!cast<I>(OpcPrefix#DQYrm) addr:$src)>;
5774   def : Pat<(v4i64 (ExtOp (v4i32 (vzmovl_v2i64 addr:$src)))),
5775             (!cast<I>(OpcPrefix#DQYrm) addr:$src)>;
5776   def : Pat<(v4i64 (ExtOp (v4i32 (vzload_v2i64 addr:$src)))),
5777             (!cast<I>(OpcPrefix#DQYrm) addr:$src)>;
5778   }
5779 }
5780
5781 defm : SS41I_pmovx_avx2_patterns<"VPMOVSX", "s", X86vsext>;
5782 defm : SS41I_pmovx_avx2_patterns<"VPMOVZX", "z", X86vzext>;
5783
5784 // SSE4.1/AVX patterns.
5785 multiclass SS41I_pmovx_patterns<string OpcPrefix, string ExtTy,
5786                                 SDNode ExtOp, PatFrag ExtLoad16> {
5787   let Predicates = [HasAVX, NoVLX_Or_NoBWI] in {
5788   def : Pat<(v8i16 (ExtOp (v16i8 VR128:$src))),
5789             (!cast<I>(OpcPrefix#BWrr) VR128:$src)>;
5790   }
5791   let Predicates = [HasAVX, NoVLX] in {
5792   def : Pat<(v4i32 (ExtOp (v16i8 VR128:$src))),
5793             (!cast<I>(OpcPrefix#BDrr) VR128:$src)>;
5794   def : Pat<(v2i64 (ExtOp (v16i8 VR128:$src))),
5795             (!cast<I>(OpcPrefix#BQrr) VR128:$src)>;
5796
5797   def : Pat<(v4i32 (ExtOp (v8i16 VR128:$src))),
5798             (!cast<I>(OpcPrefix#WDrr) VR128:$src)>;
5799   def : Pat<(v2i64 (ExtOp (v8i16 VR128:$src))),
5800             (!cast<I>(OpcPrefix#WQrr) VR128:$src)>;
5801
5802   def : Pat<(v2i64 (ExtOp (v4i32 VR128:$src))),
5803             (!cast<I>(OpcPrefix#DQrr) VR128:$src)>;
5804   }
5805   let Predicates = [HasAVX, NoVLX_Or_NoBWI] in {
5806   def : Pat<(v8i16 (!cast<PatFrag>(ExtTy#"extloadvi8") addr:$src)),
5807             (!cast<I>(OpcPrefix#BWrm) addr:$src)>;
5808   }
5809   let Predicates = [HasAVX, NoVLX] in {
5810   def : Pat<(v4i32 (!cast<PatFrag>(ExtTy#"extloadvi8") addr:$src)),
5811             (!cast<I>(OpcPrefix#BDrm) addr:$src)>;
5812   def : Pat<(v2i64 (!cast<PatFrag>(ExtTy#"extloadvi8") addr:$src)),
5813             (!cast<I>(OpcPrefix#BQrm) addr:$src)>;
5814
5815   def : Pat<(v4i32 (!cast<PatFrag>(ExtTy#"extloadvi16") addr:$src)),
5816             (!cast<I>(OpcPrefix#WDrm) addr:$src)>;
5817   def : Pat<(v2i64 (!cast<PatFrag>(ExtTy#"extloadvi16") addr:$src)),
5818             (!cast<I>(OpcPrefix#WQrm) addr:$src)>;
5819
5820   def : Pat<(v2i64 (!cast<PatFrag>(ExtTy#"extloadvi32") addr:$src)),
5821             (!cast<I>(OpcPrefix#DQrm) addr:$src)>;
5822   }
5823   let Predicates = [HasAVX, NoVLX_Or_NoBWI] in {
5824   def : Pat<(v8i16 (ExtOp (bc_v16i8 (v2i64 (scalar_to_vector (loadi64 addr:$src)))))),
5825             (!cast<I>(OpcPrefix#BWrm) addr:$src)>;
5826   def : Pat<(v8i16 (ExtOp (bc_v16i8 (v2f64 (scalar_to_vector (loadf64 addr:$src)))))),
5827             (!cast<I>(OpcPrefix#BWrm) addr:$src)>;
5828   def : Pat<(v8i16 (ExtOp (v16i8 (vzmovl_v2i64 addr:$src)))),
5829             (!cast<I>(OpcPrefix#BWrm) addr:$src)>;
5830   def : Pat<(v8i16 (ExtOp (v16i8 (vzload_v2i64 addr:$src)))),
5831             (!cast<I>(OpcPrefix#BWrm) addr:$src)>;
5832   def : Pat<(v8i16 (ExtOp (bc_v16i8 (loadv2i64 addr:$src)))),
5833             (!cast<I>(OpcPrefix#BWrm) addr:$src)>;
5834   }
5835   let Predicates = [HasAVX, NoVLX] in {
5836   def : Pat<(v4i32 (ExtOp (bc_v16i8 (v4i32 (scalar_to_vector (loadi32 addr:$src)))))),
5837             (!cast<I>(OpcPrefix#BDrm) addr:$src)>;
5838   def : Pat<(v4i32 (ExtOp (v16i8 (vzmovl_v4i32 addr:$src)))),
5839             (!cast<I>(OpcPrefix#BDrm) addr:$src)>;
5840   def : Pat<(v4i32 (ExtOp (v16i8 (vzload_v2i64 addr:$src)))),
5841             (!cast<I>(OpcPrefix#BDrm) addr:$src)>;
5842   def : Pat<(v4i32 (ExtOp (bc_v16i8 (loadv2i64 addr:$src)))),
5843             (!cast<I>(OpcPrefix#BDrm) addr:$src)>;
5844
5845   def : Pat<(v2i64 (ExtOp (bc_v16i8 (v4i32 (scalar_to_vector (ExtLoad16 addr:$src)))))),
5846             (!cast<I>(OpcPrefix#BQrm) addr:$src)>;
5847   def : Pat<(v2i64 (ExtOp (v16i8 (vzmovl_v4i32 addr:$src)))),
5848             (!cast<I>(OpcPrefix#BQrm) addr:$src)>;
5849   def : Pat<(v2i64 (ExtOp (v16i8 (vzload_v2i64 addr:$src)))),
5850             (!cast<I>(OpcPrefix#BQrm) addr:$src)>;
5851   def : Pat<(v2i64 (ExtOp (bc_v16i8 (loadv2i64 addr:$src)))),
5852             (!cast<I>(OpcPrefix#BQrm) addr:$src)>;
5853
5854   def : Pat<(v4i32 (ExtOp (bc_v8i16 (v2i64 (scalar_to_vector (loadi64 addr:$src)))))),
5855             (!cast<I>(OpcPrefix#WDrm) addr:$src)>;
5856   def : Pat<(v4i32 (ExtOp (bc_v8i16 (v2f64 (scalar_to_vector (loadf64 addr:$src)))))),
5857             (!cast<I>(OpcPrefix#WDrm) addr:$src)>;
5858   def : Pat<(v4i32 (ExtOp (v8i16 (vzmovl_v2i64 addr:$src)))),
5859             (!cast<I>(OpcPrefix#WDrm) addr:$src)>;
5860   def : Pat<(v4i32 (ExtOp (v8i16 (vzload_v2i64 addr:$src)))),
5861             (!cast<I>(OpcPrefix#WDrm) addr:$src)>;
5862   def : Pat<(v4i32 (ExtOp (bc_v8i16 (loadv2i64 addr:$src)))),
5863             (!cast<I>(OpcPrefix#WDrm) addr:$src)>;
5864
5865   def : Pat<(v2i64 (ExtOp (bc_v8i16 (v4i32 (scalar_to_vector (loadi32 addr:$src)))))),
5866             (!cast<I>(OpcPrefix#WQrm) addr:$src)>;
5867   def : Pat<(v2i64 (ExtOp (v8i16 (vzmovl_v4i32 addr:$src)))),
5868             (!cast<I>(OpcPrefix#WQrm) addr:$src)>;
5869   def : Pat<(v2i64 (ExtOp (v8i16 (vzload_v2i64 addr:$src)))),
5870             (!cast<I>(OpcPrefix#WQrm) addr:$src)>;
5871   def : Pat<(v2i64 (ExtOp (bc_v8i16 (loadv2i64 addr:$src)))),
5872             (!cast<I>(OpcPrefix#WQrm) addr:$src)>;
5873
5874   def : Pat<(v2i64 (ExtOp (bc_v4i32 (v2i64 (scalar_to_vector (loadi64 addr:$src)))))),
5875             (!cast<I>(OpcPrefix#DQrm) addr:$src)>;
5876   def : Pat<(v2i64 (ExtOp (bc_v4i32 (v2f64 (scalar_to_vector (loadf64 addr:$src)))))),
5877             (!cast<I>(OpcPrefix#DQrm) addr:$src)>;
5878   def : Pat<(v2i64 (ExtOp (v4i32 (vzmovl_v2i64 addr:$src)))),
5879             (!cast<I>(OpcPrefix#DQrm) addr:$src)>;
5880   def : Pat<(v2i64 (ExtOp (v4i32 (vzload_v2i64 addr:$src)))),
5881             (!cast<I>(OpcPrefix#DQrm) addr:$src)>;
5882   def : Pat<(v2i64 (ExtOp (bc_v4i32 (loadv2i64 addr:$src)))),
5883             (!cast<I>(OpcPrefix#DQrm) addr:$src)>;
5884   }
5885 }
5886
5887 defm : SS41I_pmovx_patterns<"VPMOVSX", "s", sext_invec, extloadi32i16>;
5888 defm : SS41I_pmovx_patterns<"VPMOVZX", "z", zext_invec, loadi16_anyext>;
5889
5890 let Predicates = [UseSSE41] in {
5891   defm : SS41I_pmovx_patterns<"PMOVSX", "s", sext_invec, extloadi32i16>;
5892   defm : SS41I_pmovx_patterns<"PMOVZX", "z", zext_invec, loadi16_anyext>;
5893 }
5894
5895 //===----------------------------------------------------------------------===//
5896 // SSE4.1 - Extract Instructions
5897 //===----------------------------------------------------------------------===//
5898
5899 /// SS41I_binop_ext8 - SSE 4.1 extract 8 bits to 32 bit reg or 8 bit mem
5900 multiclass SS41I_extract8<bits<8> opc, string OpcodeStr> {
5901   def rr : SS4AIi8<opc, MRMDestReg, (outs GR32orGR64:$dst),
5902                  (ins VR128:$src1, u8imm:$src2),
5903                  !strconcat(OpcodeStr,
5904                             "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5905                  [(set GR32orGR64:$dst, (X86pextrb (v16i8 VR128:$src1),
5906                                          imm:$src2))]>,
5907                   Sched<[WriteShuffle]>;
5908   let hasSideEffects = 0, mayStore = 1,
5909       SchedRW = [WriteShuffleLd, WriteRMW] in
5910   def mr : SS4AIi8<opc, MRMDestMem, (outs),
5911                  (ins i8mem:$dst, VR128:$src1, u8imm:$src2),
5912                  !strconcat(OpcodeStr,
5913                             "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5914                  [(store (i8 (trunc (assertzext (X86pextrb (v16i8 VR128:$src1),
5915                                                  imm:$src2)))), addr:$dst)]>;
5916 }
5917
5918 let Predicates = [HasAVX, NoBWI] in
5919   defm VPEXTRB : SS41I_extract8<0x14, "vpextrb">, VEX;
5920
5921 defm PEXTRB      : SS41I_extract8<0x14, "pextrb">;
5922
5923
5924 /// SS41I_extract16 - SSE 4.1 extract 16 bits to memory destination
5925 multiclass SS41I_extract16<bits<8> opc, string OpcodeStr> {
5926   let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0 in
5927   def rr_REV : SS4AIi8<opc, MRMDestReg, (outs GR32orGR64:$dst),
5928                    (ins VR128:$src1, u8imm:$src2),
5929                    !strconcat(OpcodeStr,
5930                    "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5931                    []>, Sched<[WriteShuffle]>, FoldGenData<NAME#ri>;
5932
5933   let hasSideEffects = 0, mayStore = 1,
5934       SchedRW = [WriteShuffleLd, WriteRMW] in
5935   def mr : SS4AIi8<opc, MRMDestMem, (outs),
5936                  (ins i16mem:$dst, VR128:$src1, u8imm:$src2),
5937                  !strconcat(OpcodeStr,
5938                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5939                  [(store (i16 (trunc (assertzext (X86pextrw (v8i16 VR128:$src1),
5940                                                   imm:$src2)))), addr:$dst)]>;
5941 }
5942
5943 let Predicates = [HasAVX, NoBWI] in
5944   defm VPEXTRW : SS41I_extract16<0x15, "vpextrw">, VEX;
5945
5946 defm PEXTRW      : SS41I_extract16<0x15, "pextrw">;
5947
5948
5949 /// SS41I_extract32 - SSE 4.1 extract 32 bits to int reg or memory destination
5950 multiclass SS41I_extract32<bits<8> opc, string OpcodeStr> {
5951   def rr : SS4AIi8<opc, MRMDestReg, (outs GR32:$dst),
5952                  (ins VR128:$src1, u8imm:$src2),
5953                  !strconcat(OpcodeStr,
5954                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5955                  [(set GR32:$dst,
5956                   (extractelt (v4i32 VR128:$src1), imm:$src2))]>,
5957                   Sched<[WriteShuffle]>;
5958   let SchedRW = [WriteShuffleLd, WriteRMW] in
5959   def mr : SS4AIi8<opc, MRMDestMem, (outs),
5960                  (ins i32mem:$dst, VR128:$src1, u8imm:$src2),
5961                  !strconcat(OpcodeStr,
5962                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5963                  [(store (extractelt (v4i32 VR128:$src1), imm:$src2),
5964                           addr:$dst)]>;
5965 }
5966
5967 let Predicates = [HasAVX, NoDQI] in
5968   defm VPEXTRD : SS41I_extract32<0x16, "vpextrd">, VEX;
5969
5970 defm PEXTRD      : SS41I_extract32<0x16, "pextrd">;
5971
5972 /// SS41I_extract32 - SSE 4.1 extract 32 bits to int reg or memory destination
5973 multiclass SS41I_extract64<bits<8> opc, string OpcodeStr> {
5974   def rr : SS4AIi8<opc, MRMDestReg, (outs GR64:$dst),
5975                  (ins VR128:$src1, u8imm:$src2),
5976                  !strconcat(OpcodeStr,
5977                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5978                  [(set GR64:$dst,
5979                   (extractelt (v2i64 VR128:$src1), imm:$src2))]>,
5980                   Sched<[WriteShuffle]>;
5981   let SchedRW = [WriteShuffleLd, WriteRMW] in
5982   def mr : SS4AIi8<opc, MRMDestMem, (outs),
5983                  (ins i64mem:$dst, VR128:$src1, u8imm:$src2),
5984                  !strconcat(OpcodeStr,
5985                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5986                  [(store (extractelt (v2i64 VR128:$src1), imm:$src2),
5987                           addr:$dst)]>;
5988 }
5989
5990 let Predicates = [HasAVX, NoDQI] in
5991   defm VPEXTRQ : SS41I_extract64<0x16, "vpextrq">, VEX, VEX_W;
5992
5993 defm PEXTRQ      : SS41I_extract64<0x16, "pextrq">, REX_W;
5994
5995 /// SS41I_extractf32 - SSE 4.1 extract 32 bits fp value to int reg or memory
5996 /// destination
5997 multiclass SS41I_extractf32<bits<8> opc, string OpcodeStr,
5998                             OpndItins itins = DEFAULT_ITINS> {
5999   def rr : SS4AIi8<opc, MRMDestReg, (outs GR32orGR64:$dst),
6000                  (ins VR128:$src1, u8imm:$src2),
6001                  !strconcat(OpcodeStr,
6002                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6003                  [(set GR32orGR64:$dst,
6004                     (extractelt (bc_v4i32 (v4f32 VR128:$src1)), imm:$src2))],
6005                     itins.rr>, Sched<[WriteFBlend]>;
6006   let SchedRW = [WriteFBlendLd, WriteRMW] in
6007   def mr : SS4AIi8<opc, MRMDestMem, (outs),
6008                  (ins f32mem:$dst, VR128:$src1, u8imm:$src2),
6009                  !strconcat(OpcodeStr,
6010                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6011                  [(store (extractelt (bc_v4i32 (v4f32 VR128:$src1)), imm:$src2),
6012                           addr:$dst)], itins.rm>;
6013 }
6014
6015 let ExeDomain = SSEPackedSingle in {
6016   let Predicates = [UseAVX] in
6017     defm VEXTRACTPS : SS41I_extractf32<0x17, "vextractps">, VEX, VEX_WIG;
6018   defm EXTRACTPS   : SS41I_extractf32<0x17, "extractps", SSE_EXTRACT_ITINS>;
6019 }
6020
6021 // Also match an EXTRACTPS store when the store is done as f32 instead of i32.
6022 def : Pat<(store (f32 (bitconvert (extractelt (bc_v4i32 (v4f32 VR128:$src1)),
6023                                               imm:$src2))),
6024                  addr:$dst),
6025           (VEXTRACTPSmr addr:$dst, VR128:$src1, imm:$src2)>,
6026           Requires<[HasAVX]>;
6027 def : Pat<(store (f32 (bitconvert (extractelt (bc_v4i32 (v4f32 VR128:$src1)),
6028                                               imm:$src2))),
6029                  addr:$dst),
6030           (EXTRACTPSmr addr:$dst, VR128:$src1, imm:$src2)>,
6031           Requires<[UseSSE41]>;
6032
6033 //===----------------------------------------------------------------------===//
6034 // SSE4.1 - Insert Instructions
6035 //===----------------------------------------------------------------------===//
6036
6037 multiclass SS41I_insert8<bits<8> opc, string asm, bit Is2Addr = 1> {
6038   def rr : SS4AIi8<opc, MRMSrcReg, (outs VR128:$dst),
6039       (ins VR128:$src1, GR32orGR64:$src2, u8imm:$src3),
6040       !if(Is2Addr,
6041         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6042         !strconcat(asm,
6043                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6044       [(set VR128:$dst,
6045         (X86pinsrb VR128:$src1, GR32orGR64:$src2, imm:$src3))]>,
6046       Sched<[WriteShuffle]>;
6047   def rm : SS4AIi8<opc, MRMSrcMem, (outs VR128:$dst),
6048       (ins VR128:$src1, i8mem:$src2, u8imm:$src3),
6049       !if(Is2Addr,
6050         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6051         !strconcat(asm,
6052                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6053       [(set VR128:$dst,
6054         (X86pinsrb VR128:$src1, (extloadi8 addr:$src2),
6055                    imm:$src3))]>, Sched<[WriteShuffleLd, ReadAfterLd]>;
6056 }
6057
6058 let Predicates = [HasAVX, NoBWI] in
6059   defm VPINSRB : SS41I_insert8<0x20, "vpinsrb", 0>, VEX_4V;
6060 let Constraints = "$src1 = $dst" in
6061   defm PINSRB  : SS41I_insert8<0x20, "pinsrb">;
6062
6063 multiclass SS41I_insert32<bits<8> opc, string asm, bit Is2Addr = 1> {
6064   def rr : SS4AIi8<opc, MRMSrcReg, (outs VR128:$dst),
6065       (ins VR128:$src1, GR32:$src2, u8imm:$src3),
6066       !if(Is2Addr,
6067         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6068         !strconcat(asm,
6069                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6070       [(set VR128:$dst,
6071         (v4i32 (insertelt VR128:$src1, GR32:$src2, imm:$src3)))]>,
6072       Sched<[WriteShuffle]>;
6073   def rm : SS4AIi8<opc, MRMSrcMem, (outs VR128:$dst),
6074       (ins VR128:$src1, i32mem:$src2, u8imm:$src3),
6075       !if(Is2Addr,
6076         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6077         !strconcat(asm,
6078                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6079       [(set VR128:$dst,
6080         (v4i32 (insertelt VR128:$src1, (loadi32 addr:$src2),
6081                           imm:$src3)))]>, Sched<[WriteShuffleLd, ReadAfterLd]>;
6082 }
6083
6084 let Predicates = [HasAVX, NoDQI] in
6085   defm VPINSRD : SS41I_insert32<0x22, "vpinsrd", 0>, VEX_4V;
6086 let Constraints = "$src1 = $dst" in
6087   defm PINSRD : SS41I_insert32<0x22, "pinsrd">;
6088
6089 multiclass SS41I_insert64<bits<8> opc, string asm, bit Is2Addr = 1> {
6090   def rr : SS4AIi8<opc, MRMSrcReg, (outs VR128:$dst),
6091       (ins VR128:$src1, GR64:$src2, u8imm:$src3),
6092       !if(Is2Addr,
6093         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6094         !strconcat(asm,
6095                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6096       [(set VR128:$dst,
6097         (v2i64 (insertelt VR128:$src1, GR64:$src2, imm:$src3)))]>,
6098       Sched<[WriteShuffle]>;
6099   def rm : SS4AIi8<opc, MRMSrcMem, (outs VR128:$dst),
6100       (ins VR128:$src1, i64mem:$src2, u8imm:$src3),
6101       !if(Is2Addr,
6102         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6103         !strconcat(asm,
6104                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6105       [(set VR128:$dst,
6106         (v2i64 (insertelt VR128:$src1, (loadi64 addr:$src2),
6107                           imm:$src3)))]>, Sched<[WriteShuffleLd, ReadAfterLd]>;
6108 }
6109
6110 let Predicates = [HasAVX, NoDQI] in
6111   defm VPINSRQ : SS41I_insert64<0x22, "vpinsrq", 0>, VEX_4V, VEX_W;
6112 let Constraints = "$src1 = $dst" in
6113   defm PINSRQ : SS41I_insert64<0x22, "pinsrq">, REX_W;
6114
6115 // insertps has a few different modes, there's the first two here below which
6116 // are optimized inserts that won't zero arbitrary elements in the destination
6117 // vector. The next one matches the intrinsic and could zero arbitrary elements
6118 // in the target vector.
6119 multiclass SS41I_insertf32<bits<8> opc, string asm, bit Is2Addr = 1,
6120                            OpndItins itins = DEFAULT_ITINS> {
6121   def rr : SS4AIi8<opc, MRMSrcReg, (outs VR128:$dst),
6122       (ins VR128:$src1, VR128:$src2, u8imm:$src3),
6123       !if(Is2Addr,
6124         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6125         !strconcat(asm,
6126                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6127       [(set VR128:$dst,
6128         (X86insertps VR128:$src1, VR128:$src2, imm:$src3))], itins.rr>,
6129       Sched<[WriteFShuffle]>;
6130   def rm : SS4AIi8<opc, MRMSrcMem, (outs VR128:$dst),
6131       (ins VR128:$src1, f32mem:$src2, u8imm:$src3),
6132       !if(Is2Addr,
6133         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6134         !strconcat(asm,
6135                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6136       [(set VR128:$dst,
6137         (X86insertps VR128:$src1,
6138                    (v4f32 (scalar_to_vector (loadf32 addr:$src2))),
6139                     imm:$src3))], itins.rm>,
6140       Sched<[WriteFShuffleLd, ReadAfterLd]>;
6141 }
6142
6143 let ExeDomain = SSEPackedSingle in {
6144   let Predicates = [UseAVX] in
6145     defm VINSERTPS : SS41I_insertf32<0x21, "vinsertps", 0>, VEX_4V, VEX_WIG;
6146   let Constraints = "$src1 = $dst" in
6147     defm INSERTPS : SS41I_insertf32<0x21, "insertps", 1, SSE_INSERT_ITINS>;
6148 }
6149
6150 let Predicates = [UseSSE41] in {
6151   // If we're inserting an element from a load or a null pshuf of a load,
6152   // fold the load into the insertps instruction.
6153   def : Pat<(v4f32 (X86insertps (v4f32 VR128:$src1), (X86PShufd (v4f32
6154                        (scalar_to_vector (loadf32 addr:$src2))), (i8 0)),
6155                    imm:$src3)),
6156             (INSERTPSrm VR128:$src1, addr:$src2, imm:$src3)>;
6157   def : Pat<(v4f32 (X86insertps (v4f32 VR128:$src1), (X86PShufd
6158                       (loadv4f32 addr:$src2), (i8 0)), imm:$src3)),
6159             (INSERTPSrm VR128:$src1, addr:$src2, imm:$src3)>;
6160 }
6161
6162 let Predicates = [UseAVX] in {
6163   // If we're inserting an element from a vbroadcast of a load, fold the
6164   // load into the X86insertps instruction.
6165   def : Pat<(v4f32 (X86insertps (v4f32 VR128:$src1),
6166                 (X86VBroadcast (loadf32 addr:$src2)), imm:$src3)),
6167             (VINSERTPSrm VR128:$src1, addr:$src2, imm:$src3)>;
6168   def : Pat<(v4f32 (X86insertps (v4f32 VR128:$src1),
6169                 (X86VBroadcast (loadv4f32 addr:$src2)), imm:$src3)),
6170             (VINSERTPSrm VR128:$src1, addr:$src2, imm:$src3)>;
6171 }
6172
6173 //===----------------------------------------------------------------------===//
6174 // SSE4.1 - Round Instructions
6175 //===----------------------------------------------------------------------===//
6176
6177 multiclass sse41_fp_unop_p<bits<8> opcps, bits<8> opcpd, string OpcodeStr,
6178                            X86MemOperand x86memop, RegisterClass RC,
6179                            PatFrag mem_frag32, PatFrag mem_frag64,
6180                            Intrinsic V4F32Int, Intrinsic V2F64Int> {
6181 let ExeDomain = SSEPackedSingle in {
6182   // Intrinsic operation, reg.
6183   // Vector intrinsic operation, reg
6184   def PSr : SS4AIi8<opcps, MRMSrcReg,
6185                     (outs RC:$dst), (ins RC:$src1, i32u8imm:$src2),
6186                     !strconcat(OpcodeStr,
6187                     "ps\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6188                     [(set RC:$dst, (V4F32Int RC:$src1, imm:$src2))],
6189                     IIC_SSE_ROUNDPS_REG>, Sched<[WriteFAdd]>;
6190
6191   // Vector intrinsic operation, mem
6192   def PSm : SS4AIi8<opcps, MRMSrcMem,
6193                     (outs RC:$dst), (ins x86memop:$src1, i32u8imm:$src2),
6194                     !strconcat(OpcodeStr,
6195                     "ps\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6196                     [(set RC:$dst,
6197                           (V4F32Int (mem_frag32 addr:$src1),imm:$src2))],
6198                           IIC_SSE_ROUNDPS_MEM>, Sched<[WriteFAddLd]>;
6199 } // ExeDomain = SSEPackedSingle
6200
6201 let ExeDomain = SSEPackedDouble in {
6202   // Vector intrinsic operation, reg
6203   def PDr : SS4AIi8<opcpd, MRMSrcReg,
6204                     (outs RC:$dst), (ins RC:$src1, i32u8imm:$src2),
6205                     !strconcat(OpcodeStr,
6206                     "pd\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6207                     [(set RC:$dst, (V2F64Int RC:$src1, imm:$src2))],
6208                     IIC_SSE_ROUNDPS_REG>, Sched<[WriteFAdd]>;
6209
6210   // Vector intrinsic operation, mem
6211   def PDm : SS4AIi8<opcpd, MRMSrcMem,
6212                     (outs RC:$dst), (ins x86memop:$src1, i32u8imm:$src2),
6213                     !strconcat(OpcodeStr,
6214                     "pd\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6215                     [(set RC:$dst,
6216                           (V2F64Int (mem_frag64 addr:$src1),imm:$src2))],
6217                           IIC_SSE_ROUNDPS_REG>, Sched<[WriteFAddLd]>;
6218 } // ExeDomain = SSEPackedDouble
6219 }
6220
6221 multiclass avx_fp_unop_rm<bits<8> opcss, bits<8> opcsd,
6222                           string OpcodeStr> {
6223 let ExeDomain = GenericDomain, hasSideEffects = 0 in {
6224   def SSr : SS4AIi8<opcss, MRMSrcReg,
6225         (outs FR32:$dst), (ins FR32:$src1, FR32:$src2, i32u8imm:$src3),
6226         !strconcat(OpcodeStr,
6227             "ss\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
6228       []>, Sched<[WriteFAdd]>;
6229
6230   let mayLoad = 1 in
6231   def SSm : SS4AIi8<opcss, MRMSrcMem,
6232         (outs FR32:$dst), (ins FR32:$src1, f32mem:$src2, i32u8imm:$src3),
6233         !strconcat(OpcodeStr,
6234              "ss\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
6235         []>, Sched<[WriteFAddLd, ReadAfterLd]>;
6236
6237   def SDr : SS4AIi8<opcsd, MRMSrcReg,
6238         (outs FR64:$dst), (ins FR64:$src1, FR64:$src2, i32u8imm:$src3),
6239         !strconcat(OpcodeStr,
6240               "sd\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
6241         []>, Sched<[WriteFAdd]>;
6242
6243   let mayLoad = 1 in
6244   def SDm : SS4AIi8<opcsd, MRMSrcMem,
6245         (outs FR64:$dst), (ins FR64:$src1, f64mem:$src2, i32u8imm:$src3),
6246         !strconcat(OpcodeStr,
6247              "sd\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
6248         []>, Sched<[WriteFAddLd, ReadAfterLd]>;
6249 } // ExeDomain = GenericDomain, hasSideEffects = 0
6250 }
6251
6252 multiclass sse41_fp_unop_s<bits<8> opcss, bits<8> opcsd,
6253                            string OpcodeStr> {
6254 let ExeDomain = GenericDomain, hasSideEffects = 0 in {
6255   def SSr : SS4AIi8<opcss, MRMSrcReg,
6256                     (outs FR32:$dst), (ins FR32:$src1, i32u8imm:$src2),
6257                     !strconcat(OpcodeStr,
6258                                "ss\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6259                     []>, Sched<[WriteFAdd]>;
6260
6261   let mayLoad = 1 in
6262   def SSm : SS4AIi8<opcss, MRMSrcMem,
6263                     (outs FR32:$dst), (ins f32mem:$src1, i32u8imm:$src2),
6264                     !strconcat(OpcodeStr,
6265                                "ss\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6266                     []>, Sched<[WriteFAddLd, ReadAfterLd]>;
6267
6268   def SDr : SS4AIi8<opcsd, MRMSrcReg,
6269                     (outs FR64:$dst), (ins FR64:$src1, i32u8imm:$src2),
6270                     !strconcat(OpcodeStr,
6271                                "sd\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6272                     []>, Sched<[WriteFAdd]>;
6273
6274   let mayLoad = 1 in
6275   def SDm : SS4AIi8<opcsd, MRMSrcMem,
6276                     (outs FR64:$dst), (ins f64mem:$src1, i32u8imm:$src2),
6277                     !strconcat(OpcodeStr,
6278                                "sd\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6279                     []>, Sched<[WriteFAddLd, ReadAfterLd]>;
6280 } // ExeDomain = GenericDomain, hasSideEffects = 0
6281 }
6282
6283 multiclass sse41_fp_binop_s<bits<8> opcss, bits<8> opcsd,
6284                             string OpcodeStr,
6285                             Intrinsic F32Int,
6286                             Intrinsic F64Int, bit Is2Addr = 1> {
6287 let ExeDomain = GenericDomain, isCodeGenOnly = 1 in {
6288   def SSr_Int : SS4AIi8<opcss, MRMSrcReg,
6289         (outs VR128:$dst), (ins VR128:$src1, VR128:$src2, i32u8imm:$src3),
6290         !if(Is2Addr,
6291             !strconcat(OpcodeStr,
6292                 "ss\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6293             !strconcat(OpcodeStr,
6294                 "ss\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6295         [(set VR128:$dst, (F32Int VR128:$src1, VR128:$src2, imm:$src3))]>,
6296         Sched<[WriteFAdd]>;
6297
6298   def SSm_Int : SS4AIi8<opcss, MRMSrcMem,
6299         (outs VR128:$dst), (ins VR128:$src1, ssmem:$src2, i32u8imm:$src3),
6300         !if(Is2Addr,
6301             !strconcat(OpcodeStr,
6302                 "ss\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6303             !strconcat(OpcodeStr,
6304                 "ss\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6305         [(set VR128:$dst,
6306              (F32Int VR128:$src1, sse_load_f32:$src2, imm:$src3))]>,
6307         Sched<[WriteFAddLd, ReadAfterLd]>;
6308
6309   def SDr_Int : SS4AIi8<opcsd, MRMSrcReg,
6310         (outs VR128:$dst), (ins VR128:$src1, VR128:$src2, i32u8imm:$src3),
6311         !if(Is2Addr,
6312             !strconcat(OpcodeStr,
6313                 "sd\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6314             !strconcat(OpcodeStr,
6315                 "sd\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6316         [(set VR128:$dst, (F64Int VR128:$src1, VR128:$src2, imm:$src3))]>,
6317         Sched<[WriteFAdd]>;
6318
6319   def SDm_Int : SS4AIi8<opcsd, MRMSrcMem,
6320         (outs VR128:$dst), (ins VR128:$src1, sdmem:$src2, i32u8imm:$src3),
6321         !if(Is2Addr,
6322             !strconcat(OpcodeStr,
6323                 "sd\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6324             !strconcat(OpcodeStr,
6325                 "sd\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6326         [(set VR128:$dst,
6327               (F64Int VR128:$src1, sse_load_f64:$src2, imm:$src3))]>,
6328         Sched<[WriteFAddLd, ReadAfterLd]>;
6329 } // ExeDomain = GenericDomain, isCodeGenOnly = 1
6330 }
6331
6332 // FP round - roundss, roundps, roundsd, roundpd
6333 let Predicates = [HasAVX] in {
6334   // Intrinsic form
6335   defm VROUND  : sse41_fp_unop_p<0x08, 0x09, "vround", f128mem, VR128,
6336                                  loadv4f32, loadv2f64,
6337                                  int_x86_sse41_round_ps,
6338                                  int_x86_sse41_round_pd>, VEX, VEX_WIG;
6339   defm VROUNDY : sse41_fp_unop_p<0x08, 0x09, "vround", f256mem, VR256,
6340                                  loadv8f32, loadv4f64,
6341                                  int_x86_avx_round_ps_256,
6342                                  int_x86_avx_round_pd_256>, VEX, VEX_L, VEX_WIG;
6343   defm VROUND  : sse41_fp_binop_s<0x0A, 0x0B, "vround",
6344                                  int_x86_sse41_round_ss,
6345                                  int_x86_sse41_round_sd, 0>, VEX_4V, VEX_LIG, VEX_WIG;
6346   defm VROUND  : avx_fp_unop_rm<0x0A, 0x0B, "vround">, VEX_4V, VEX_LIG;
6347 }
6348
6349 let Predicates = [UseAVX] in {
6350   def : Pat<(ffloor FR32:$src),
6351             (VROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x9))>;
6352   def : Pat<(f64 (ffloor FR64:$src)),
6353             (VROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x9))>;
6354   def : Pat<(f32 (fnearbyint FR32:$src)),
6355             (VROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0xC))>;
6356   def : Pat<(f64 (fnearbyint FR64:$src)),
6357             (VROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0xC))>;
6358   def : Pat<(f32 (fceil FR32:$src)),
6359             (VROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0xA))>;
6360   def : Pat<(f64 (fceil FR64:$src)),
6361             (VROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0xA))>;
6362   def : Pat<(f32 (frint FR32:$src)),
6363             (VROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x4))>;
6364   def : Pat<(f64 (frint FR64:$src)),
6365             (VROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x4))>;
6366   def : Pat<(f32 (ftrunc FR32:$src)),
6367             (VROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0xB))>;
6368   def : Pat<(f64 (ftrunc FR64:$src)),
6369             (VROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0xB))>;
6370 }
6371
6372 let Predicates = [HasAVX] in {
6373   def : Pat<(v4f32 (ffloor VR128:$src)),
6374             (VROUNDPSr VR128:$src, (i32 0x9))>;
6375   def : Pat<(v4f32 (fnearbyint VR128:$src)),
6376             (VROUNDPSr VR128:$src, (i32 0xC))>;
6377   def : Pat<(v4f32 (fceil VR128:$src)),
6378             (VROUNDPSr VR128:$src, (i32 0xA))>;
6379   def : Pat<(v4f32 (frint VR128:$src)),
6380             (VROUNDPSr VR128:$src, (i32 0x4))>;
6381   def : Pat<(v4f32 (ftrunc VR128:$src)),
6382             (VROUNDPSr VR128:$src, (i32 0xB))>;
6383
6384   def : Pat<(v2f64 (ffloor VR128:$src)),
6385             (VROUNDPDr VR128:$src, (i32 0x9))>;
6386   def : Pat<(v2f64 (fnearbyint VR128:$src)),
6387             (VROUNDPDr VR128:$src, (i32 0xC))>;
6388   def : Pat<(v2f64 (fceil VR128:$src)),
6389             (VROUNDPDr VR128:$src, (i32 0xA))>;
6390   def : Pat<(v2f64 (frint VR128:$src)),
6391             (VROUNDPDr VR128:$src, (i32 0x4))>;
6392   def : Pat<(v2f64 (ftrunc VR128:$src)),
6393             (VROUNDPDr VR128:$src, (i32 0xB))>;
6394
6395   def : Pat<(v8f32 (ffloor VR256:$src)),
6396             (VROUNDYPSr VR256:$src, (i32 0x9))>;
6397   def : Pat<(v8f32 (fnearbyint VR256:$src)),
6398             (VROUNDYPSr VR256:$src, (i32 0xC))>;
6399   def : Pat<(v8f32 (fceil VR256:$src)),
6400             (VROUNDYPSr VR256:$src, (i32 0xA))>;
6401   def : Pat<(v8f32 (frint VR256:$src)),
6402             (VROUNDYPSr VR256:$src, (i32 0x4))>;
6403   def : Pat<(v8f32 (ftrunc VR256:$src)),
6404             (VROUNDYPSr VR256:$src, (i32 0xB))>;
6405
6406   def : Pat<(v4f64 (ffloor VR256:$src)),
6407             (VROUNDYPDr VR256:$src, (i32 0x9))>;
6408   def : Pat<(v4f64 (fnearbyint VR256:$src)),
6409             (VROUNDYPDr VR256:$src, (i32 0xC))>;
6410   def : Pat<(v4f64 (fceil VR256:$src)),
6411             (VROUNDYPDr VR256:$src, (i32 0xA))>;
6412   def : Pat<(v4f64 (frint VR256:$src)),
6413             (VROUNDYPDr VR256:$src, (i32 0x4))>;
6414   def : Pat<(v4f64 (ftrunc VR256:$src)),
6415             (VROUNDYPDr VR256:$src, (i32 0xB))>;
6416 }
6417
6418 defm ROUND  : sse41_fp_unop_p<0x08, 0x09, "round", f128mem, VR128,
6419                               memopv4f32, memopv2f64, int_x86_sse41_round_ps,
6420                               int_x86_sse41_round_pd>;
6421
6422 defm ROUND  : sse41_fp_unop_s<0x0A, 0x0B, "round">;
6423
6424 let Constraints = "$src1 = $dst" in
6425 defm ROUND  : sse41_fp_binop_s<0x0A, 0x0B, "round",
6426                                int_x86_sse41_round_ss, int_x86_sse41_round_sd>;
6427
6428 let Predicates = [UseSSE41] in {
6429   def : Pat<(ffloor FR32:$src),
6430             (ROUNDSSr FR32:$src, (i32 0x9))>;
6431   def : Pat<(f64 (ffloor FR64:$src)),
6432             (ROUNDSDr FR64:$src, (i32 0x9))>;
6433   def : Pat<(f32 (fnearbyint FR32:$src)),
6434             (ROUNDSSr FR32:$src, (i32 0xC))>;
6435   def : Pat<(f64 (fnearbyint FR64:$src)),
6436             (ROUNDSDr FR64:$src, (i32 0xC))>;
6437   def : Pat<(f32 (fceil FR32:$src)),
6438             (ROUNDSSr FR32:$src, (i32 0xA))>;
6439   def : Pat<(f64 (fceil FR64:$src)),
6440             (ROUNDSDr FR64:$src, (i32 0xA))>;
6441   def : Pat<(f32 (frint FR32:$src)),
6442             (ROUNDSSr FR32:$src, (i32 0x4))>;
6443   def : Pat<(f64 (frint FR64:$src)),
6444             (ROUNDSDr FR64:$src, (i32 0x4))>;
6445   def : Pat<(f32 (ftrunc FR32:$src)),
6446             (ROUNDSSr FR32:$src, (i32 0xB))>;
6447   def : Pat<(f64 (ftrunc FR64:$src)),
6448             (ROUNDSDr FR64:$src, (i32 0xB))>;
6449
6450   def : Pat<(v4f32 (ffloor VR128:$src)),
6451             (ROUNDPSr VR128:$src, (i32 0x9))>;
6452   def : Pat<(v4f32 (fnearbyint VR128:$src)),
6453             (ROUNDPSr VR128:$src, (i32 0xC))>;
6454   def : Pat<(v4f32 (fceil VR128:$src)),
6455             (ROUNDPSr VR128:$src, (i32 0xA))>;
6456   def : Pat<(v4f32 (frint VR128:$src)),
6457             (ROUNDPSr VR128:$src, (i32 0x4))>;
6458   def : Pat<(v4f32 (ftrunc VR128:$src)),
6459             (ROUNDPSr VR128:$src, (i32 0xB))>;
6460
6461   def : Pat<(v2f64 (ffloor VR128:$src)),
6462             (ROUNDPDr VR128:$src, (i32 0x9))>;
6463   def : Pat<(v2f64 (fnearbyint VR128:$src)),
6464             (ROUNDPDr VR128:$src, (i32 0xC))>;
6465   def : Pat<(v2f64 (fceil VR128:$src)),
6466             (ROUNDPDr VR128:$src, (i32 0xA))>;
6467   def : Pat<(v2f64 (frint VR128:$src)),
6468             (ROUNDPDr VR128:$src, (i32 0x4))>;
6469   def : Pat<(v2f64 (ftrunc VR128:$src)),
6470             (ROUNDPDr VR128:$src, (i32 0xB))>;
6471 }
6472
6473 //===----------------------------------------------------------------------===//
6474 // SSE4.1 - Packed Bit Test
6475 //===----------------------------------------------------------------------===//
6476
6477 // ptest instruction we'll lower to this in X86ISelLowering primarily from
6478 // the intel intrinsic that corresponds to this.
6479 let Defs = [EFLAGS], Predicates = [HasAVX] in {
6480 def VPTESTrr  : SS48I<0x17, MRMSrcReg, (outs), (ins VR128:$src1, VR128:$src2),
6481                 "vptest\t{$src2, $src1|$src1, $src2}",
6482                 [(set EFLAGS, (X86ptest VR128:$src1, (v2i64 VR128:$src2)))]>,
6483                 Sched<[WriteVecLogic]>, VEX, VEX_WIG;
6484 def VPTESTrm  : SS48I<0x17, MRMSrcMem, (outs), (ins VR128:$src1, f128mem:$src2),
6485                 "vptest\t{$src2, $src1|$src1, $src2}",
6486                 [(set EFLAGS,(X86ptest VR128:$src1, (loadv2i64 addr:$src2)))]>,
6487                 Sched<[WriteVecLogicLd, ReadAfterLd]>, VEX, VEX_WIG;
6488
6489 def VPTESTYrr : SS48I<0x17, MRMSrcReg, (outs), (ins VR256:$src1, VR256:$src2),
6490                 "vptest\t{$src2, $src1|$src1, $src2}",
6491                 [(set EFLAGS, (X86ptest VR256:$src1, (v4i64 VR256:$src2)))]>,
6492                 Sched<[WriteVecLogic]>, VEX, VEX_L, VEX_WIG;
6493 def VPTESTYrm : SS48I<0x17, MRMSrcMem, (outs), (ins VR256:$src1, i256mem:$src2),
6494                 "vptest\t{$src2, $src1|$src1, $src2}",
6495                 [(set EFLAGS,(X86ptest VR256:$src1, (loadv4i64 addr:$src2)))]>,
6496                 Sched<[WriteVecLogicLd, ReadAfterLd]>, VEX, VEX_L, VEX_WIG;
6497 }
6498
6499 let Defs = [EFLAGS] in {
6500 def PTESTrr : SS48I<0x17, MRMSrcReg, (outs), (ins VR128:$src1, VR128:$src2),
6501               "ptest\t{$src2, $src1|$src1, $src2}",
6502               [(set EFLAGS, (X86ptest VR128:$src1, (v2i64 VR128:$src2)))]>,
6503               Sched<[WriteVecLogic]>;
6504 def PTESTrm : SS48I<0x17, MRMSrcMem, (outs), (ins VR128:$src1, f128mem:$src2),
6505               "ptest\t{$src2, $src1|$src1, $src2}",
6506               [(set EFLAGS, (X86ptest VR128:$src1, (memopv2i64 addr:$src2)))]>,
6507               Sched<[WriteVecLogicLd, ReadAfterLd]>;
6508 }
6509
6510 // The bit test instructions below are AVX only
6511 multiclass avx_bittest<bits<8> opc, string OpcodeStr, RegisterClass RC,
6512                        X86MemOperand x86memop, PatFrag mem_frag, ValueType vt> {
6513   def rr : SS48I<opc, MRMSrcReg, (outs), (ins RC:$src1, RC:$src2),
6514             !strconcat(OpcodeStr, "\t{$src2, $src1|$src1, $src2}"),
6515             [(set EFLAGS, (X86testp RC:$src1, (vt RC:$src2)))]>,
6516             Sched<[WriteVecLogic]>, VEX;
6517   def rm : SS48I<opc, MRMSrcMem, (outs), (ins RC:$src1, x86memop:$src2),
6518             !strconcat(OpcodeStr, "\t{$src2, $src1|$src1, $src2}"),
6519             [(set EFLAGS, (X86testp RC:$src1, (mem_frag addr:$src2)))]>,
6520             Sched<[WriteVecLogicLd, ReadAfterLd]>, VEX;
6521 }
6522
6523 let Defs = [EFLAGS], Predicates = [HasAVX] in {
6524 let ExeDomain = SSEPackedSingle in {
6525 defm VTESTPS  : avx_bittest<0x0E, "vtestps", VR128, f128mem, loadv4f32, v4f32>;
6526 defm VTESTPSY : avx_bittest<0x0E, "vtestps", VR256, f256mem, loadv8f32, v8f32>,
6527                             VEX_L;
6528 }
6529 let ExeDomain = SSEPackedDouble in {
6530 defm VTESTPD  : avx_bittest<0x0F, "vtestpd", VR128, f128mem, loadv2f64, v2f64>;
6531 defm VTESTPDY : avx_bittest<0x0F, "vtestpd", VR256, f256mem, loadv4f64, v4f64>,
6532                             VEX_L;
6533 }
6534 }
6535
6536 //===----------------------------------------------------------------------===//
6537 // SSE4.1 - Misc Instructions
6538 //===----------------------------------------------------------------------===//
6539
6540 let Defs = [EFLAGS], Predicates = [HasPOPCNT] in {
6541   def POPCNT16rr : I<0xB8, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
6542                      "popcnt{w}\t{$src, $dst|$dst, $src}",
6543                      [(set GR16:$dst, (ctpop GR16:$src)), (implicit EFLAGS)],
6544                      IIC_SSE_POPCNT_RR>, Sched<[WriteFAdd]>,
6545                      OpSize16, XS;
6546   def POPCNT16rm : I<0xB8, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
6547                      "popcnt{w}\t{$src, $dst|$dst, $src}",
6548                      [(set GR16:$dst, (ctpop (loadi16 addr:$src))),
6549                       (implicit EFLAGS)], IIC_SSE_POPCNT_RM>,
6550                       Sched<[WriteFAddLd]>, OpSize16, XS;
6551
6552   def POPCNT32rr : I<0xB8, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
6553                      "popcnt{l}\t{$src, $dst|$dst, $src}",
6554                      [(set GR32:$dst, (ctpop GR32:$src)), (implicit EFLAGS)],
6555                      IIC_SSE_POPCNT_RR>, Sched<[WriteFAdd]>,
6556                      OpSize32, XS;
6557
6558   def POPCNT32rm : I<0xB8, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
6559                      "popcnt{l}\t{$src, $dst|$dst, $src}",
6560                      [(set GR32:$dst, (ctpop (loadi32 addr:$src))),
6561                       (implicit EFLAGS)], IIC_SSE_POPCNT_RM>,
6562                       Sched<[WriteFAddLd]>, OpSize32, XS;
6563
6564   def POPCNT64rr : RI<0xB8, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
6565                       "popcnt{q}\t{$src, $dst|$dst, $src}",
6566                       [(set GR64:$dst, (ctpop GR64:$src)), (implicit EFLAGS)],
6567                       IIC_SSE_POPCNT_RR>, Sched<[WriteFAdd]>, XS;
6568   def POPCNT64rm : RI<0xB8, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
6569                       "popcnt{q}\t{$src, $dst|$dst, $src}",
6570                       [(set GR64:$dst, (ctpop (loadi64 addr:$src))),
6571                        (implicit EFLAGS)], IIC_SSE_POPCNT_RM>,
6572                        Sched<[WriteFAddLd]>, XS;
6573 }
6574
6575
6576
6577 // SS41I_unop_rm_int_v16 - SSE 4.1 unary operator whose type is v8i16.
6578 multiclass SS41I_unop_rm_int_v16<bits<8> opc, string OpcodeStr,
6579                                  Intrinsic IntId128, PatFrag ld_frag,
6580                                  X86FoldableSchedWrite Sched> {
6581   def rr128 : SS48I<opc, MRMSrcReg, (outs VR128:$dst),
6582                     (ins VR128:$src),
6583                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
6584                     [(set VR128:$dst, (IntId128 VR128:$src))]>,
6585                     Sched<[Sched]>;
6586   def rm128 : SS48I<opc, MRMSrcMem, (outs VR128:$dst),
6587                      (ins i128mem:$src),
6588                      !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
6589                      [(set VR128:$dst,
6590                        (IntId128 (bitconvert (ld_frag addr:$src))))]>,
6591                     Sched<[Sched.Folded]>;
6592 }
6593
6594 // PHMIN has the same profile as PSAD, thus we use the same scheduling
6595 // model, although the naming is misleading.
6596 let Predicates = [HasAVX] in
6597 defm VPHMINPOSUW : SS41I_unop_rm_int_v16 <0x41, "vphminposuw",
6598                                          int_x86_sse41_phminposuw, loadv2i64,
6599                                          WriteVecIMul>, VEX, VEX_WIG;
6600 defm PHMINPOSUW : SS41I_unop_rm_int_v16 <0x41, "phminposuw",
6601                                          int_x86_sse41_phminposuw, memopv2i64,
6602                                          WriteVecIMul>;
6603
6604 /// SS48I_binop_rm - Simple SSE41 binary operator.
6605 multiclass SS48I_binop_rm<bits<8> opc, string OpcodeStr, SDNode OpNode,
6606                           ValueType OpVT, RegisterClass RC, PatFrag memop_frag,
6607                           X86MemOperand x86memop, bit Is2Addr = 1,
6608                           OpndItins itins = SSE_INTALU_ITINS_P> {
6609   let isCommutable = 1 in
6610   def rr : SS48I<opc, MRMSrcReg, (outs RC:$dst),
6611        (ins RC:$src1, RC:$src2),
6612        !if(Is2Addr,
6613            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
6614            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
6615        [(set RC:$dst, (OpVT (OpNode RC:$src1, RC:$src2)))]>,
6616        Sched<[itins.Sched]>;
6617   def rm : SS48I<opc, MRMSrcMem, (outs RC:$dst),
6618        (ins RC:$src1, x86memop:$src2),
6619        !if(Is2Addr,
6620            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
6621            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
6622        [(set RC:$dst,
6623          (OpVT (OpNode RC:$src1, (bitconvert (memop_frag addr:$src2)))))]>,
6624        Sched<[itins.Sched.Folded, ReadAfterLd]>;
6625 }
6626
6627 /// SS48I_binop_rm2 - Simple SSE41 binary operator with different src and dst
6628 /// types.
6629 multiclass SS48I_binop_rm2<bits<8> opc, string OpcodeStr, SDNode OpNode,
6630                          ValueType DstVT, ValueType SrcVT, RegisterClass RC,
6631                          PatFrag memop_frag, X86MemOperand x86memop,
6632                          OpndItins itins,
6633                          bit IsCommutable = 0, bit Is2Addr = 1> {
6634   let isCommutable = IsCommutable in
6635   def rr : SS48I<opc, MRMSrcReg, (outs RC:$dst),
6636        (ins RC:$src1, RC:$src2),
6637        !if(Is2Addr,
6638            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
6639            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
6640        [(set RC:$dst, (DstVT (OpNode (SrcVT RC:$src1), RC:$src2)))]>,
6641        Sched<[itins.Sched]>;
6642   def rm : SS48I<opc, MRMSrcMem, (outs RC:$dst),
6643        (ins RC:$src1, x86memop:$src2),
6644        !if(Is2Addr,
6645            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
6646            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
6647        [(set RC:$dst, (DstVT (OpNode (SrcVT RC:$src1),
6648                                      (bitconvert (memop_frag addr:$src2)))))]>,
6649        Sched<[itins.Sched.Folded, ReadAfterLd]>;
6650 }
6651
6652 let Predicates = [HasAVX, NoVLX] in {
6653   defm VPMINSD   : SS48I_binop_rm<0x39, "vpminsd", smin, v4i32, VR128,
6654                                   loadv2i64, i128mem, 0, SSE_INTALU_ITINS_P>,
6655                                   VEX_4V, VEX_WIG;
6656   defm VPMINUD   : SS48I_binop_rm<0x3B, "vpminud", umin, v4i32, VR128,
6657                                   loadv2i64, i128mem, 0, SSE_INTALU_ITINS_P>,
6658                                   VEX_4V, VEX_WIG;
6659   defm VPMAXSD   : SS48I_binop_rm<0x3D, "vpmaxsd", smax, v4i32, VR128,
6660                                   loadv2i64, i128mem, 0, SSE_INTALU_ITINS_P>,
6661                                   VEX_4V, VEX_WIG;
6662   defm VPMAXUD   : SS48I_binop_rm<0x3F, "vpmaxud", umax, v4i32, VR128,
6663                                   loadv2i64, i128mem, 0, SSE_INTALU_ITINS_P>,
6664                                   VEX_4V, VEX_WIG;
6665   defm VPMULDQ   : SS48I_binop_rm2<0x28, "vpmuldq", X86pmuldq, v2i64, v4i32,
6666                                    VR128, loadv2i64, i128mem,
6667                                    SSE_INTMUL_ITINS_P, 1, 0>, VEX_4V, VEX_WIG;
6668 }
6669 let Predicates = [HasAVX, NoVLX_Or_NoBWI] in {
6670   defm VPMINSB   : SS48I_binop_rm<0x38, "vpminsb", smin, v16i8, VR128,
6671                                   loadv2i64, i128mem, 0, SSE_INTALU_ITINS_P>,
6672                                   VEX_4V, VEX_WIG;
6673   defm VPMINUW   : SS48I_binop_rm<0x3A, "vpminuw", umin, v8i16, VR128,
6674                                   loadv2i64, i128mem, 0, SSE_INTALU_ITINS_P>,
6675                                   VEX_4V, VEX_WIG;
6676   defm VPMAXSB   : SS48I_binop_rm<0x3C, "vpmaxsb", smax, v16i8, VR128,
6677                                   loadv2i64, i128mem, 0, SSE_INTALU_ITINS_P>,
6678                                   VEX_4V, VEX_WIG;
6679   defm VPMAXUW   : SS48I_binop_rm<0x3E, "vpmaxuw", umax, v8i16, VR128,
6680                                   loadv2i64, i128mem, 0, SSE_INTALU_ITINS_P>,
6681                                   VEX_4V, VEX_WIG;
6682 }
6683
6684 let Predicates = [HasAVX2, NoVLX] in {
6685   defm VPMINSDY  : SS48I_binop_rm<0x39, "vpminsd", smin, v8i32, VR256,
6686                                   loadv4i64, i256mem, 0, SSE_INTALU_ITINS_P>,
6687                                   VEX_4V, VEX_L, VEX_WIG;
6688   defm VPMINUDY  : SS48I_binop_rm<0x3B, "vpminud", umin, v8i32, VR256,
6689                                   loadv4i64, i256mem, 0, SSE_INTALU_ITINS_P>,
6690                                   VEX_4V, VEX_L, VEX_WIG;
6691   defm VPMAXSDY  : SS48I_binop_rm<0x3D, "vpmaxsd", smax, v8i32, VR256,
6692                                   loadv4i64, i256mem, 0, SSE_INTALU_ITINS_P>,
6693                                   VEX_4V, VEX_L, VEX_WIG;
6694   defm VPMAXUDY  : SS48I_binop_rm<0x3F, "vpmaxud", umax, v8i32, VR256,
6695                                   loadv4i64, i256mem, 0, SSE_INTALU_ITINS_P>,
6696                                   VEX_4V, VEX_L, VEX_WIG;
6697   defm VPMULDQY : SS48I_binop_rm2<0x28, "vpmuldq", X86pmuldq, v4i64, v8i32,
6698                                   VR256, loadv4i64, i256mem,
6699                                   SSE_INTMUL_ITINS_P, 1, 0>, VEX_4V, VEX_L, VEX_WIG;
6700 }
6701 let Predicates = [HasAVX2, NoVLX_Or_NoBWI] in {
6702   defm VPMINSBY  : SS48I_binop_rm<0x38, "vpminsb", smin, v32i8, VR256,
6703                                   loadv4i64, i256mem, 0, SSE_INTALU_ITINS_P>,
6704                                   VEX_4V, VEX_L, VEX_WIG;
6705   defm VPMINUWY  : SS48I_binop_rm<0x3A, "vpminuw", umin, v16i16, VR256,
6706                                   loadv4i64, i256mem, 0, SSE_INTALU_ITINS_P>,
6707                                   VEX_4V, VEX_L, VEX_WIG;
6708   defm VPMAXSBY  : SS48I_binop_rm<0x3C, "vpmaxsb", smax, v32i8, VR256,
6709                                   loadv4i64, i256mem, 0, SSE_INTALU_ITINS_P>,
6710                                   VEX_4V, VEX_L, VEX_WIG;
6711   defm VPMAXUWY  : SS48I_binop_rm<0x3E, "vpmaxuw", umax, v16i16, VR256,
6712                                   loadv4i64, i256mem, 0, SSE_INTALU_ITINS_P>,
6713                                   VEX_4V, VEX_L, VEX_WIG;
6714 }
6715
6716 let Constraints = "$src1 = $dst" in {
6717   defm PMINSB   : SS48I_binop_rm<0x38, "pminsb", smin, v16i8, VR128,
6718                                  memopv2i64, i128mem, 1, SSE_INTALU_ITINS_P>;
6719   defm PMINSD   : SS48I_binop_rm<0x39, "pminsd", smin, v4i32, VR128,
6720                                  memopv2i64, i128mem, 1, SSE_INTALU_ITINS_P>;
6721   defm PMINUD   : SS48I_binop_rm<0x3B, "pminud", umin, v4i32, VR128,
6722                                  memopv2i64, i128mem, 1, SSE_INTALU_ITINS_P>;
6723   defm PMINUW   : SS48I_binop_rm<0x3A, "pminuw", umin, v8i16, VR128,
6724                                  memopv2i64, i128mem, 1, SSE_INTALU_ITINS_P>;
6725   defm PMAXSB   : SS48I_binop_rm<0x3C, "pmaxsb", smax, v16i8, VR128,
6726                                  memopv2i64, i128mem, 1, SSE_INTALU_ITINS_P>;
6727   defm PMAXSD   : SS48I_binop_rm<0x3D, "pmaxsd", smax, v4i32, VR128,
6728                                  memopv2i64, i128mem, 1, SSE_INTALU_ITINS_P>;
6729   defm PMAXUD   : SS48I_binop_rm<0x3F, "pmaxud", umax, v4i32, VR128,
6730                                  memopv2i64, i128mem, 1, SSE_INTALU_ITINS_P>;
6731   defm PMAXUW   : SS48I_binop_rm<0x3E, "pmaxuw", umax, v8i16, VR128,
6732                                  memopv2i64, i128mem, 1, SSE_INTALU_ITINS_P>;
6733   defm PMULDQ   : SS48I_binop_rm2<0x28, "pmuldq", X86pmuldq, v2i64, v4i32,
6734                                   VR128, memopv2i64, i128mem,
6735                                   SSE_INTMUL_ITINS_P, 1>;
6736 }
6737
6738 let Predicates = [HasAVX, NoVLX] in
6739   defm VPMULLD  : SS48I_binop_rm<0x40, "vpmulld", mul, v4i32, VR128,
6740                                  loadv2i64, i128mem, 0, SSE_PMULLD_ITINS>,
6741                                  VEX_4V, VEX_WIG;
6742 let Predicates = [HasAVX] in
6743   defm VPCMPEQQ : SS48I_binop_rm<0x29, "vpcmpeqq", X86pcmpeq, v2i64, VR128,
6744                                  loadv2i64, i128mem, 0, SSE_INTALU_ITINS_P>,
6745                                  VEX_4V, VEX_WIG;
6746
6747 let Predicates = [HasAVX2, NoVLX] in
6748   defm VPMULLDY  : SS48I_binop_rm<0x40, "vpmulld", mul, v8i32, VR256,
6749                                   loadv4i64, i256mem, 0, SSE_PMULLD_ITINS>,
6750                                   VEX_4V, VEX_L, VEX_WIG;
6751 let Predicates = [HasAVX2] in
6752   defm VPCMPEQQY : SS48I_binop_rm<0x29, "vpcmpeqq", X86pcmpeq, v4i64, VR256,
6753                                   loadv4i64, i256mem, 0, SSE_INTALU_ITINS_P>,
6754                                   VEX_4V, VEX_L, VEX_WIG;
6755
6756 let Constraints = "$src1 = $dst" in {
6757   defm PMULLD  : SS48I_binop_rm<0x40, "pmulld", mul, v4i32, VR128,
6758                                 memopv2i64, i128mem, 1, SSE_PMULLD_ITINS>;
6759   defm PCMPEQQ : SS48I_binop_rm<0x29, "pcmpeqq", X86pcmpeq, v2i64, VR128,
6760                                 memopv2i64, i128mem, 1, SSE_INTALUQ_ITINS_P>;
6761 }
6762
6763 /// SS41I_binop_rmi_int - SSE 4.1 binary operator with 8-bit immediate
6764 multiclass SS41I_binop_rmi_int<bits<8> opc, string OpcodeStr,
6765                  Intrinsic IntId, RegisterClass RC, PatFrag memop_frag,
6766                  X86MemOperand x86memop, bit Is2Addr = 1,
6767                  OpndItins itins = DEFAULT_ITINS> {
6768   let isCommutable = 1 in
6769   def rri : SS4AIi8<opc, MRMSrcReg, (outs RC:$dst),
6770         (ins RC:$src1, RC:$src2, u8imm:$src3),
6771         !if(Is2Addr,
6772             !strconcat(OpcodeStr,
6773                 "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6774             !strconcat(OpcodeStr,
6775                 "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6776         [(set RC:$dst, (IntId RC:$src1, RC:$src2, imm:$src3))], itins.rr>,
6777         Sched<[itins.Sched]>;
6778   def rmi : SS4AIi8<opc, MRMSrcMem, (outs RC:$dst),
6779         (ins RC:$src1, x86memop:$src2, u8imm:$src3),
6780         !if(Is2Addr,
6781             !strconcat(OpcodeStr,
6782                 "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6783             !strconcat(OpcodeStr,
6784                 "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6785         [(set RC:$dst,
6786           (IntId RC:$src1,
6787            (bitconvert (memop_frag addr:$src2)), imm:$src3))], itins.rm>,
6788         Sched<[itins.Sched.Folded, ReadAfterLd]>;
6789 }
6790
6791 /// SS41I_binop_rmi - SSE 4.1 binary operator with 8-bit immediate
6792 multiclass SS41I_binop_rmi<bits<8> opc, string OpcodeStr, SDNode OpNode,
6793                            ValueType OpVT, RegisterClass RC, PatFrag memop_frag,
6794                            X86MemOperand x86memop, bit Is2Addr = 1,
6795                            OpndItins itins = DEFAULT_ITINS> {
6796   let isCommutable = 1 in
6797   def rri : SS4AIi8<opc, MRMSrcReg, (outs RC:$dst),
6798         (ins RC:$src1, RC:$src2, u8imm:$src3),
6799         !if(Is2Addr,
6800             !strconcat(OpcodeStr,
6801                 "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6802             !strconcat(OpcodeStr,
6803                 "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6804         [(set RC:$dst, (OpVT (OpNode RC:$src1, RC:$src2, imm:$src3)))],
6805         itins.rr>, Sched<[itins.Sched]>;
6806   def rmi : SS4AIi8<opc, MRMSrcMem, (outs RC:$dst),
6807         (ins RC:$src1, x86memop:$src2, u8imm:$src3),
6808         !if(Is2Addr,
6809             !strconcat(OpcodeStr,
6810                 "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6811             !strconcat(OpcodeStr,
6812                 "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6813         [(set RC:$dst,
6814           (OpVT (OpNode RC:$src1,
6815                  (bitconvert (memop_frag addr:$src2)), imm:$src3)))], itins.rm>,
6816         Sched<[itins.Sched.Folded, ReadAfterLd]>;
6817 }
6818
6819 let Predicates = [HasAVX] in {
6820   let isCommutable = 0 in {
6821     defm VMPSADBW : SS41I_binop_rmi_int<0x42, "vmpsadbw", int_x86_sse41_mpsadbw,
6822                                         VR128, loadv2i64, i128mem, 0,
6823                                         DEFAULT_ITINS_MPSADSCHED>, VEX_4V, VEX_WIG;
6824   }
6825
6826   let ExeDomain = SSEPackedSingle in {
6827   defm VBLENDPS : SS41I_binop_rmi<0x0C, "vblendps", X86Blendi, v4f32,
6828                                   VR128, loadv4f32, f128mem, 0,
6829                                   DEFAULT_ITINS_FBLENDSCHED>, VEX_4V, VEX_WIG;
6830   defm VBLENDPSY : SS41I_binop_rmi<0x0C, "vblendps", X86Blendi, v8f32,
6831                                    VR256, loadv8f32, f256mem, 0,
6832                                    DEFAULT_ITINS_FBLENDSCHED>, VEX_4V, VEX_L, VEX_WIG;
6833   }
6834   let ExeDomain = SSEPackedDouble in {
6835   defm VBLENDPD : SS41I_binop_rmi<0x0D, "vblendpd", X86Blendi, v2f64,
6836                                   VR128, loadv2f64, f128mem, 0,
6837                                   DEFAULT_ITINS_FBLENDSCHED>, VEX_4V, VEX_WIG;
6838   defm VBLENDPDY : SS41I_binop_rmi<0x0D, "vblendpd", X86Blendi, v4f64,
6839                                    VR256, loadv4f64, f256mem, 0,
6840                                    DEFAULT_ITINS_FBLENDSCHED>, VEX_4V, VEX_L, VEX_WIG;
6841   }
6842   defm VPBLENDW : SS41I_binop_rmi<0x0E, "vpblendw", X86Blendi, v8i16,
6843                                   VR128, loadv2i64, i128mem, 0,
6844                                   DEFAULT_ITINS_BLENDSCHED>, VEX_4V, VEX_WIG;
6845
6846   let ExeDomain = SSEPackedSingle in
6847   defm VDPPS : SS41I_binop_rmi_int<0x40, "vdpps", int_x86_sse41_dpps,
6848                                    VR128, loadv4f32, f128mem, 0,
6849                                    SSE_DPPS_ITINS>, VEX_4V, VEX_WIG;
6850   let ExeDomain = SSEPackedDouble in
6851   defm VDPPD : SS41I_binop_rmi_int<0x41, "vdppd", int_x86_sse41_dppd,
6852                                    VR128, loadv2f64, f128mem, 0,
6853                                    SSE_DPPS_ITINS>, VEX_4V, VEX_WIG;
6854   let ExeDomain = SSEPackedSingle in
6855   defm VDPPSY : SS41I_binop_rmi_int<0x40, "vdpps", int_x86_avx_dp_ps_256,
6856                                     VR256, loadv8f32, i256mem, 0,
6857                                     SSE_DPPS_ITINS>, VEX_4V, VEX_L, VEX_WIG;
6858 }
6859
6860 let Predicates = [HasAVX2] in {
6861   let isCommutable = 0 in {
6862   defm VMPSADBWY : SS41I_binop_rmi_int<0x42, "vmpsadbw", int_x86_avx2_mpsadbw,
6863                                   VR256, loadv4i64, i256mem, 0,
6864                                   DEFAULT_ITINS_MPSADSCHED>, VEX_4V, VEX_L, VEX_WIG;
6865   }
6866   defm VPBLENDWY : SS41I_binop_rmi<0x0E, "vpblendw", X86Blendi, v16i16,
6867                                    VR256, loadv4i64, i256mem, 0,
6868                                    DEFAULT_ITINS_BLENDSCHED>, VEX_4V, VEX_L, VEX_WIG;
6869 }
6870
6871 let Constraints = "$src1 = $dst" in {
6872   let isCommutable = 0 in {
6873   defm MPSADBW : SS41I_binop_rmi_int<0x42, "mpsadbw", int_x86_sse41_mpsadbw,
6874                                      VR128, memopv2i64, i128mem,
6875                                      1, SSE_MPSADBW_ITINS>;
6876   }
6877   let ExeDomain = SSEPackedSingle in
6878   defm BLENDPS : SS41I_binop_rmi<0x0C, "blendps", X86Blendi, v4f32,
6879                                  VR128, memopv4f32, f128mem,
6880                                  1, SSE_INTALU_ITINS_FBLEND_P>;
6881   let ExeDomain = SSEPackedDouble in
6882   defm BLENDPD : SS41I_binop_rmi<0x0D, "blendpd", X86Blendi, v2f64,
6883                                  VR128, memopv2f64, f128mem,
6884                                  1, SSE_INTALU_ITINS_FBLEND_P>;
6885   defm PBLENDW : SS41I_binop_rmi<0x0E, "pblendw", X86Blendi, v8i16,
6886                                  VR128, memopv2i64, i128mem,
6887                                  1, SSE_INTALU_ITINS_BLEND_P>;
6888   let ExeDomain = SSEPackedSingle in
6889   defm DPPS : SS41I_binop_rmi_int<0x40, "dpps", int_x86_sse41_dpps,
6890                                   VR128, memopv4f32, f128mem, 1,
6891                                   SSE_DPPS_ITINS>;
6892   let ExeDomain = SSEPackedDouble in
6893   defm DPPD : SS41I_binop_rmi_int<0x41, "dppd", int_x86_sse41_dppd,
6894                                   VR128, memopv2f64, f128mem, 1,
6895                                   SSE_DPPD_ITINS>;
6896 }
6897
6898 // For insertion into the zero index (low half) of a 256-bit vector, it is
6899 // more efficient to generate a blend with immediate instead of an insert*128.
6900 let Predicates = [HasAVX] in {
6901 def : Pat<(insert_subvector (v4f64 VR256:$src1), (v2f64 VR128:$src2), (iPTR 0)),
6902           (VBLENDPDYrri VR256:$src1,
6903                         (INSERT_SUBREG (v4f64 (IMPLICIT_DEF)),
6904                                        VR128:$src2, sub_xmm), 0x3)>;
6905 def : Pat<(insert_subvector (v8f32 VR256:$src1), (v4f32 VR128:$src2), (iPTR 0)),
6906           (VBLENDPSYrri VR256:$src1,
6907                         (INSERT_SUBREG (v8f32 (IMPLICIT_DEF)),
6908                                        VR128:$src2, sub_xmm), 0xf)>;
6909 }
6910
6911 /// SS41I_quaternary_int_avx - AVX SSE 4.1 with 4 operators
6912 multiclass SS41I_quaternary_int_avx<bits<8> opc, string OpcodeStr,
6913                                     RegisterClass RC, X86MemOperand x86memop,
6914                                     PatFrag mem_frag, Intrinsic IntId,
6915                                     X86FoldableSchedWrite Sched> {
6916   def rr : Ii8Reg<opc, MRMSrcReg, (outs RC:$dst),
6917                   (ins RC:$src1, RC:$src2, RC:$src3),
6918                   !strconcat(OpcodeStr,
6919                     "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
6920                   [(set RC:$dst, (IntId RC:$src1, RC:$src2, RC:$src3))],
6921                   NoItinerary, SSEPackedInt>, TAPD, VEX_4V,
6922                 Sched<[Sched]>;
6923
6924   def rm : Ii8Reg<opc, MRMSrcMem, (outs RC:$dst),
6925                   (ins RC:$src1, x86memop:$src2, RC:$src3),
6926                   !strconcat(OpcodeStr,
6927                     "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
6928                   [(set RC:$dst,
6929                         (IntId RC:$src1, (bitconvert (mem_frag addr:$src2)),
6930                                RC:$src3))],
6931                   NoItinerary, SSEPackedInt>, TAPD, VEX_4V,
6932                 Sched<[Sched.Folded, ReadAfterLd]>;
6933 }
6934
6935 let Predicates = [HasAVX] in {
6936 let ExeDomain = SSEPackedDouble in {
6937 defm VBLENDVPD  : SS41I_quaternary_int_avx<0x4B, "vblendvpd", VR128, f128mem,
6938                                            loadv2f64, int_x86_sse41_blendvpd,
6939                                            WriteFVarBlend>;
6940 defm VBLENDVPDY : SS41I_quaternary_int_avx<0x4B, "vblendvpd", VR256, f256mem,
6941                                   loadv4f64, int_x86_avx_blendv_pd_256,
6942                                   WriteFVarBlend>, VEX_L;
6943 } // ExeDomain = SSEPackedDouble
6944 let ExeDomain = SSEPackedSingle in {
6945 defm VBLENDVPS  : SS41I_quaternary_int_avx<0x4A, "vblendvps", VR128, f128mem,
6946                                            loadv4f32, int_x86_sse41_blendvps,
6947                                            WriteFVarBlend>;
6948 defm VBLENDVPSY : SS41I_quaternary_int_avx<0x4A, "vblendvps", VR256, f256mem,
6949                                   loadv8f32, int_x86_avx_blendv_ps_256,
6950                                   WriteFVarBlend>, VEX_L;
6951 } // ExeDomain = SSEPackedSingle
6952 defm VPBLENDVB  : SS41I_quaternary_int_avx<0x4C, "vpblendvb", VR128, i128mem,
6953                                            loadv2i64, int_x86_sse41_pblendvb,
6954                                            WriteVarBlend>;
6955 }
6956
6957 let Predicates = [HasAVX2] in {
6958 defm VPBLENDVBY : SS41I_quaternary_int_avx<0x4C, "vpblendvb", VR256, i256mem,
6959                                       loadv4i64, int_x86_avx2_pblendvb,
6960                                       WriteVarBlend>, VEX_L;
6961 }
6962
6963 let Predicates = [HasAVX] in {
6964   def : Pat<(v16i8 (vselect (v16i8 VR128:$mask), (v16i8 VR128:$src1),
6965                             (v16i8 VR128:$src2))),
6966             (VPBLENDVBrr VR128:$src2, VR128:$src1, VR128:$mask)>;
6967   def : Pat<(v4i32 (vselect (v4i32 VR128:$mask), (v4i32 VR128:$src1),
6968                             (v4i32 VR128:$src2))),
6969             (VBLENDVPSrr VR128:$src2, VR128:$src1, VR128:$mask)>;
6970   def : Pat<(v4f32 (vselect (v4i32 VR128:$mask), (v4f32 VR128:$src1),
6971                             (v4f32 VR128:$src2))),
6972             (VBLENDVPSrr VR128:$src2, VR128:$src1, VR128:$mask)>;
6973   def : Pat<(v2i64 (vselect (v2i64 VR128:$mask), (v2i64 VR128:$src1),
6974                             (v2i64 VR128:$src2))),
6975             (VBLENDVPDrr VR128:$src2, VR128:$src1, VR128:$mask)>;
6976   def : Pat<(v2f64 (vselect (v2i64 VR128:$mask), (v2f64 VR128:$src1),
6977                             (v2f64 VR128:$src2))),
6978             (VBLENDVPDrr VR128:$src2, VR128:$src1, VR128:$mask)>;
6979   def : Pat<(v8i32 (vselect (v8i32 VR256:$mask), (v8i32 VR256:$src1),
6980                             (v8i32 VR256:$src2))),
6981             (VBLENDVPSYrr VR256:$src2, VR256:$src1, VR256:$mask)>;
6982   def : Pat<(v8f32 (vselect (v8i32 VR256:$mask), (v8f32 VR256:$src1),
6983                             (v8f32 VR256:$src2))),
6984             (VBLENDVPSYrr VR256:$src2, VR256:$src1, VR256:$mask)>;
6985   def : Pat<(v4i64 (vselect (v4i64 VR256:$mask), (v4i64 VR256:$src1),
6986                             (v4i64 VR256:$src2))),
6987             (VBLENDVPDYrr VR256:$src2, VR256:$src1, VR256:$mask)>;
6988   def : Pat<(v4f64 (vselect (v4i64 VR256:$mask), (v4f64 VR256:$src1),
6989                             (v4f64 VR256:$src2))),
6990             (VBLENDVPDYrr VR256:$src2, VR256:$src1, VR256:$mask)>;
6991 }
6992
6993 let Predicates = [HasAVX2] in {
6994   def : Pat<(v32i8 (vselect (v32i8 VR256:$mask), (v32i8 VR256:$src1),
6995                             (v32i8 VR256:$src2))),
6996             (VPBLENDVBYrr VR256:$src2, VR256:$src1, VR256:$mask)>;
6997 }
6998
6999 // Patterns
7000 // FIXME: Prefer a movss or movsd over a blendps when optimizing for size or
7001 // on targets where they have equal performance. These were changed to use
7002 // blends because blends have better throughput on SandyBridge and Haswell, but
7003 // movs[s/d] are 1-2 byte shorter instructions.
7004 let Predicates = [UseAVX] in {
7005   let AddedComplexity = 15 in {
7006   // Move scalar to XMM zero-extended, zeroing a VR128 then do a
7007   // MOVS{S,D} to the lower bits.
7008   def : Pat<(v4f32 (X86vzmovl (v4f32 (scalar_to_vector FR32:$src)))),
7009             (VMOVSSrr (v4f32 (V_SET0)), FR32:$src)>;
7010   def : Pat<(v4f32 (X86vzmovl (v4f32 VR128:$src))),
7011             (VBLENDPSrri (v4f32 (V_SET0)), VR128:$src, (i8 1))>;
7012   def : Pat<(v4i32 (X86vzmovl (v4i32 VR128:$src))),
7013             (VPBLENDWrri (v4i32 (V_SET0)), VR128:$src, (i8 3))>;
7014   def : Pat<(v2f64 (X86vzmovl (v2f64 (scalar_to_vector FR64:$src)))),
7015             (VMOVSDrr (v2f64 (V_SET0)), FR64:$src)>;
7016
7017   // Move low f32 and clear high bits.
7018   def : Pat<(v8f32 (X86vzmovl (v8f32 VR256:$src))),
7019             (VBLENDPSYrri (v8f32 (AVX_SET0)), VR256:$src, (i8 1))>;
7020
7021   // Move low f64 and clear high bits.
7022   def : Pat<(v4f64 (X86vzmovl (v4f64 VR256:$src))),
7023             (VBLENDPDYrri (v4f64 (AVX_SET0)), VR256:$src, (i8 1))>;
7024   }
7025
7026   // These will incur an FP/int domain crossing penalty, but it may be the only
7027   // way without AVX2. Do not add any complexity because we may be able to match
7028   // more optimal patterns defined earlier in this file.
7029   def : Pat<(v8i32 (X86vzmovl (v8i32 VR256:$src))),
7030             (VBLENDPSYrri (v8i32 (AVX_SET0)), VR256:$src, (i8 1))>;
7031   def : Pat<(v4i64 (X86vzmovl (v4i64 VR256:$src))),
7032             (VBLENDPDYrri (v4i64 (AVX_SET0)), VR256:$src, (i8 1))>;
7033 }
7034
7035 // FIXME: Prefer a movss or movsd over a blendps when optimizing for size or
7036 // on targets where they have equal performance. These were changed to use
7037 // blends because blends have better throughput on SandyBridge and Haswell, but
7038 // movs[s/d] are 1-2 byte shorter instructions.
7039 let Predicates = [UseSSE41], AddedComplexity = 15 in {
7040   // With SSE41 we can use blends for these patterns.
7041   def : Pat<(v4f32 (X86vzmovl (v4f32 VR128:$src))),
7042             (BLENDPSrri (v4f32 (V_SET0)), VR128:$src, (i8 1))>;
7043   def : Pat<(v4i32 (X86vzmovl (v4i32 VR128:$src))),
7044             (PBLENDWrri (v4i32 (V_SET0)), VR128:$src, (i8 3))>;
7045 }
7046
7047
7048 /// SS41I_ternary_int - SSE 4.1 ternary operator
7049 let Uses = [XMM0], Constraints = "$src1 = $dst" in {
7050   multiclass SS41I_ternary_int<bits<8> opc, string OpcodeStr, PatFrag mem_frag,
7051                                X86MemOperand x86memop, Intrinsic IntId,
7052                                OpndItins itins = DEFAULT_ITINS> {
7053     def rr0 : SS48I<opc, MRMSrcReg, (outs VR128:$dst),
7054                     (ins VR128:$src1, VR128:$src2),
7055                     !strconcat(OpcodeStr,
7056                      "\t{%xmm0, $src2, $dst|$dst, $src2, xmm0}"),
7057                     [(set VR128:$dst, (IntId VR128:$src1, VR128:$src2, XMM0))],
7058                     itins.rr>, Sched<[itins.Sched]>;
7059
7060     def rm0 : SS48I<opc, MRMSrcMem, (outs VR128:$dst),
7061                     (ins VR128:$src1, x86memop:$src2),
7062                     !strconcat(OpcodeStr,
7063                      "\t{%xmm0, $src2, $dst|$dst, $src2, xmm0}"),
7064                     [(set VR128:$dst,
7065                       (IntId VR128:$src1,
7066                        (bitconvert (mem_frag addr:$src2)), XMM0))],
7067                        itins.rm>, Sched<[itins.Sched.Folded, ReadAfterLd]>;
7068   }
7069 }
7070
7071 let ExeDomain = SSEPackedDouble in
7072 defm BLENDVPD : SS41I_ternary_int<0x15, "blendvpd", memopv2f64, f128mem,
7073                                   int_x86_sse41_blendvpd,
7074                                   DEFAULT_ITINS_FBLENDSCHED>;
7075 let ExeDomain = SSEPackedSingle in
7076 defm BLENDVPS : SS41I_ternary_int<0x14, "blendvps", memopv4f32, f128mem,
7077                                   int_x86_sse41_blendvps,
7078                                   DEFAULT_ITINS_FBLENDSCHED>;
7079 defm PBLENDVB : SS41I_ternary_int<0x10, "pblendvb", memopv2i64, i128mem,
7080                                   int_x86_sse41_pblendvb,
7081                                   DEFAULT_ITINS_VARBLENDSCHED>;
7082
7083 // Aliases with the implicit xmm0 argument
7084 def : InstAlias<"blendvpd\t{$src2, $dst|$dst, $src2}",
7085                 (BLENDVPDrr0 VR128:$dst, VR128:$src2), 0>;
7086 def : InstAlias<"blendvpd\t{$src2, $dst|$dst, $src2}",
7087                 (BLENDVPDrm0 VR128:$dst, f128mem:$src2), 0>;
7088 def : InstAlias<"blendvps\t{$src2, $dst|$dst, $src2}",
7089                 (BLENDVPSrr0 VR128:$dst, VR128:$src2), 0>;
7090 def : InstAlias<"blendvps\t{$src2, $dst|$dst, $src2}",
7091                 (BLENDVPSrm0 VR128:$dst, f128mem:$src2), 0>;
7092 def : InstAlias<"pblendvb\t{$src2, $dst|$dst, $src2}",
7093                 (PBLENDVBrr0 VR128:$dst, VR128:$src2), 0>;
7094 def : InstAlias<"pblendvb\t{$src2, $dst|$dst, $src2}",
7095                 (PBLENDVBrm0 VR128:$dst, i128mem:$src2), 0>;
7096
7097 let Predicates = [UseSSE41] in {
7098   def : Pat<(v16i8 (vselect (v16i8 XMM0), (v16i8 VR128:$src1),
7099                             (v16i8 VR128:$src2))),
7100             (PBLENDVBrr0 VR128:$src2, VR128:$src1)>;
7101   def : Pat<(v4i32 (vselect (v4i32 XMM0), (v4i32 VR128:$src1),
7102                             (v4i32 VR128:$src2))),
7103             (BLENDVPSrr0 VR128:$src2, VR128:$src1)>;
7104   def : Pat<(v4f32 (vselect (v4i32 XMM0), (v4f32 VR128:$src1),
7105                             (v4f32 VR128:$src2))),
7106             (BLENDVPSrr0 VR128:$src2, VR128:$src1)>;
7107   def : Pat<(v2i64 (vselect (v2i64 XMM0), (v2i64 VR128:$src1),
7108                             (v2i64 VR128:$src2))),
7109             (BLENDVPDrr0 VR128:$src2, VR128:$src1)>;
7110   def : Pat<(v2f64 (vselect (v2i64 XMM0), (v2f64 VR128:$src1),
7111                             (v2f64 VR128:$src2))),
7112             (BLENDVPDrr0 VR128:$src2, VR128:$src1)>;
7113 }
7114
7115 let AddedComplexity = 400 in { // Prefer non-temporal versions
7116 let SchedRW = [WriteLoad] in {
7117 let Predicates = [HasAVX, NoVLX] in
7118 def VMOVNTDQArm : SS48I<0x2A, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
7119                        "vmovntdqa\t{$src, $dst|$dst, $src}", []>,
7120                        VEX, VEX_WIG;
7121 let Predicates = [HasAVX2, NoVLX] in
7122 def VMOVNTDQAYrm : SS48I<0x2A, MRMSrcMem, (outs VR256:$dst), (ins i256mem:$src),
7123                          "vmovntdqa\t{$src, $dst|$dst, $src}", []>,
7124                          VEX, VEX_L, VEX_WIG;
7125 def MOVNTDQArm : SS48I<0x2A, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
7126                        "movntdqa\t{$src, $dst|$dst, $src}", []>;
7127 } // SchedRW
7128
7129 let Predicates = [HasAVX2, NoVLX] in {
7130   def : Pat<(v8f32 (alignednontemporalload addr:$src)),
7131             (VMOVNTDQAYrm addr:$src)>;
7132   def : Pat<(v4f64 (alignednontemporalload addr:$src)),
7133             (VMOVNTDQAYrm addr:$src)>;
7134   def : Pat<(v4i64 (alignednontemporalload addr:$src)),
7135             (VMOVNTDQAYrm addr:$src)>;
7136 }
7137
7138 let Predicates = [HasAVX, NoVLX] in {
7139   def : Pat<(v4f32 (alignednontemporalload addr:$src)),
7140             (VMOVNTDQArm addr:$src)>;
7141   def : Pat<(v2f64 (alignednontemporalload addr:$src)),
7142             (VMOVNTDQArm addr:$src)>;
7143   def : Pat<(v2i64 (alignednontemporalload addr:$src)),
7144             (VMOVNTDQArm addr:$src)>;
7145 }
7146
7147 let Predicates = [UseSSE41] in {
7148   def : Pat<(v4f32 (alignednontemporalload addr:$src)),
7149             (MOVNTDQArm addr:$src)>;
7150   def : Pat<(v2f64 (alignednontemporalload addr:$src)),
7151             (MOVNTDQArm addr:$src)>;
7152   def : Pat<(v2i64 (alignednontemporalload addr:$src)),
7153             (MOVNTDQArm addr:$src)>;
7154 }
7155
7156 } // AddedComplexity
7157
7158 //===----------------------------------------------------------------------===//
7159 // SSE4.2 - Compare Instructions
7160 //===----------------------------------------------------------------------===//
7161
7162 /// SS42I_binop_rm - Simple SSE 4.2 binary operator
7163 multiclass SS42I_binop_rm<bits<8> opc, string OpcodeStr, SDNode OpNode,
7164                           ValueType OpVT, RegisterClass RC, PatFrag memop_frag,
7165                           X86MemOperand x86memop, OpndItins itins,
7166                           bit Is2Addr = 1> {
7167   def rr : SS428I<opc, MRMSrcReg, (outs RC:$dst),
7168        (ins RC:$src1, RC:$src2),
7169        !if(Is2Addr,
7170            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
7171            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
7172        [(set RC:$dst, (OpVT (OpNode RC:$src1, RC:$src2)))]>, Sched<[itins.Sched]>;
7173   def rm : SS428I<opc, MRMSrcMem, (outs RC:$dst),
7174        (ins RC:$src1, x86memop:$src2),
7175        !if(Is2Addr,
7176            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
7177            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
7178        [(set RC:$dst,
7179          (OpVT (OpNode RC:$src1, (memop_frag addr:$src2))))]>,
7180        Sched<[itins.Sched.Folded, ReadAfterLd]>;
7181 }
7182
7183 let Predicates = [HasAVX] in
7184   defm VPCMPGTQ : SS42I_binop_rm<0x37, "vpcmpgtq", X86pcmpgt, v2i64, VR128,
7185                                  loadv2i64, i128mem, SSE_INTALU_ITINS_P, 0>,
7186                                  VEX_4V, VEX_WIG;
7187
7188 let Predicates = [HasAVX2] in
7189   defm VPCMPGTQY : SS42I_binop_rm<0x37, "vpcmpgtq", X86pcmpgt, v4i64, VR256,
7190                                   loadv4i64, i256mem, SSE_INTALU_ITINS_P, 0>,
7191                                   VEX_4V, VEX_L, VEX_WIG;
7192
7193 let Constraints = "$src1 = $dst" in
7194   defm PCMPGTQ : SS42I_binop_rm<0x37, "pcmpgtq", X86pcmpgt, v2i64, VR128,
7195                                 memopv2i64, i128mem, SSE_INTALU_ITINS_P>;
7196
7197 //===----------------------------------------------------------------------===//
7198 // SSE4.2 - String/text Processing Instructions
7199 //===----------------------------------------------------------------------===//
7200
7201 // Packed Compare Implicit Length Strings, Return Mask
7202 multiclass pseudo_pcmpistrm<string asm, PatFrag ld_frag> {
7203   def REG : PseudoI<(outs VR128:$dst),
7204                     (ins VR128:$src1, VR128:$src2, u8imm:$src3),
7205     [(set VR128:$dst, (int_x86_sse42_pcmpistrm128 VR128:$src1, VR128:$src2,
7206                                                   imm:$src3))]>;
7207   def MEM : PseudoI<(outs VR128:$dst),
7208                     (ins VR128:$src1, i128mem:$src2, u8imm:$src3),
7209     [(set VR128:$dst, (int_x86_sse42_pcmpistrm128 VR128:$src1,
7210                        (bc_v16i8 (ld_frag addr:$src2)), imm:$src3))]>;
7211 }
7212
7213 let Defs = [EFLAGS], usesCustomInserter = 1 in {
7214   defm VPCMPISTRM128 : pseudo_pcmpistrm<"#VPCMPISTRM128", loadv2i64>,
7215                          Requires<[HasAVX]>, VEX_WIG;
7216   defm PCMPISTRM128 : pseudo_pcmpistrm<"#PCMPISTRM128", memopv2i64>,
7217                          Requires<[UseSSE42]>;
7218 }
7219
7220 multiclass pcmpistrm_SS42AI<string asm> {
7221   def rr : SS42AI<0x62, MRMSrcReg, (outs),
7222     (ins VR128:$src1, VR128:$src2, u8imm:$src3),
7223     !strconcat(asm, "\t{$src3, $src2, $src1|$src1, $src2, $src3}"),
7224     []>, Sched<[WritePCmpIStrM]>;
7225   let mayLoad = 1 in
7226   def rm :SS42AI<0x62, MRMSrcMem, (outs),
7227     (ins VR128:$src1, i128mem:$src2, u8imm:$src3),
7228     !strconcat(asm, "\t{$src3, $src2, $src1|$src1, $src2, $src3}"),
7229     []>, Sched<[WritePCmpIStrMLd, ReadAfterLd]>;
7230 }
7231
7232 let Defs = [XMM0, EFLAGS], hasSideEffects = 0 in {
7233   let Predicates = [HasAVX] in
7234   defm VPCMPISTRM128 : pcmpistrm_SS42AI<"vpcmpistrm">, VEX;
7235   defm PCMPISTRM128  : pcmpistrm_SS42AI<"pcmpistrm"> ;
7236 }
7237
7238 // Packed Compare Explicit Length Strings, Return Mask
7239 multiclass pseudo_pcmpestrm<string asm, PatFrag ld_frag> {
7240   def REG : PseudoI<(outs VR128:$dst),
7241                     (ins VR128:$src1, VR128:$src3, u8imm:$src5),
7242     [(set VR128:$dst, (int_x86_sse42_pcmpestrm128
7243                        VR128:$src1, EAX, VR128:$src3, EDX, imm:$src5))]>;
7244   def MEM : PseudoI<(outs VR128:$dst),
7245                     (ins VR128:$src1, i128mem:$src3, u8imm:$src5),
7246     [(set VR128:$dst, (int_x86_sse42_pcmpestrm128 VR128:$src1, EAX,
7247                        (bc_v16i8 (ld_frag addr:$src3)), EDX, imm:$src5))]>;
7248 }
7249
7250 let Defs = [EFLAGS], Uses = [EAX, EDX], usesCustomInserter = 1 in {
7251   defm VPCMPESTRM128 : pseudo_pcmpestrm<"#VPCMPESTRM128", loadv2i64>,
7252                          Requires<[HasAVX]>;
7253   defm PCMPESTRM128 : pseudo_pcmpestrm<"#PCMPESTRM128", memopv2i64>,
7254                          Requires<[UseSSE42]>;
7255 }
7256
7257 multiclass SS42AI_pcmpestrm<string asm> {
7258   def rr : SS42AI<0x60, MRMSrcReg, (outs),
7259     (ins VR128:$src1, VR128:$src3, u8imm:$src5),
7260     !strconcat(asm, "\t{$src5, $src3, $src1|$src1, $src3, $src5}"),
7261     []>, Sched<[WritePCmpEStrM]>;
7262   let mayLoad = 1 in
7263   def rm : SS42AI<0x60, MRMSrcMem, (outs),
7264     (ins VR128:$src1, i128mem:$src3, u8imm:$src5),
7265     !strconcat(asm, "\t{$src5, $src3, $src1|$src1, $src3, $src5}"),
7266     []>, Sched<[WritePCmpEStrMLd, ReadAfterLd]>;
7267 }
7268
7269 let Defs = [XMM0, EFLAGS], Uses = [EAX, EDX], hasSideEffects = 0 in {
7270   let Predicates = [HasAVX] in
7271   defm VPCMPESTRM128 : SS42AI_pcmpestrm<"vpcmpestrm">, VEX;
7272   defm PCMPESTRM128 :  SS42AI_pcmpestrm<"pcmpestrm">;
7273 }
7274
7275 // Packed Compare Implicit Length Strings, Return Index
7276 multiclass pseudo_pcmpistri<string asm, PatFrag ld_frag> {
7277   def REG : PseudoI<(outs GR32:$dst),
7278                     (ins VR128:$src1, VR128:$src2, u8imm:$src3),
7279     [(set GR32:$dst, EFLAGS,
7280       (X86pcmpistri VR128:$src1, VR128:$src2, imm:$src3))]>;
7281   def MEM : PseudoI<(outs GR32:$dst),
7282                     (ins VR128:$src1, i128mem:$src2, u8imm:$src3),
7283     [(set GR32:$dst, EFLAGS, (X86pcmpistri VR128:$src1,
7284                               (bc_v16i8 (ld_frag addr:$src2)), imm:$src3))]>;
7285 }
7286
7287 let Defs = [EFLAGS], usesCustomInserter = 1 in {
7288   defm VPCMPISTRI : pseudo_pcmpistri<"#VPCMPISTRI", loadv2i64>,
7289                       Requires<[HasAVX]>, VEX_WIG;
7290   defm PCMPISTRI  : pseudo_pcmpistri<"#PCMPISTRI", memopv2i64>,
7291                       Requires<[UseSSE42]>;
7292 }
7293
7294 multiclass SS42AI_pcmpistri<string asm> {
7295   def rr : SS42AI<0x63, MRMSrcReg, (outs),
7296     (ins VR128:$src1, VR128:$src2, u8imm:$src3),
7297     !strconcat(asm, "\t{$src3, $src2, $src1|$src1, $src2, $src3}"),
7298     []>, Sched<[WritePCmpIStrI]>;
7299   let mayLoad = 1 in
7300   def rm : SS42AI<0x63, MRMSrcMem, (outs),
7301     (ins VR128:$src1, i128mem:$src2, u8imm:$src3),
7302     !strconcat(asm, "\t{$src3, $src2, $src1|$src1, $src2, $src3}"),
7303     []>, Sched<[WritePCmpIStrILd, ReadAfterLd]>;
7304 }
7305
7306 let Defs = [ECX, EFLAGS], hasSideEffects = 0 in {
7307   let Predicates = [HasAVX] in
7308   defm VPCMPISTRI : SS42AI_pcmpistri<"vpcmpistri">, VEX;
7309   defm PCMPISTRI  : SS42AI_pcmpistri<"pcmpistri">;
7310 }
7311
7312 // Packed Compare Explicit Length Strings, Return Index
7313 multiclass pseudo_pcmpestri<string asm, PatFrag ld_frag> {
7314   def REG : PseudoI<(outs GR32:$dst),
7315                     (ins VR128:$src1, VR128:$src3, u8imm:$src5),
7316     [(set GR32:$dst, EFLAGS,
7317       (X86pcmpestri VR128:$src1, EAX, VR128:$src3, EDX, imm:$src5))]>;
7318   def MEM : PseudoI<(outs GR32:$dst),
7319                     (ins VR128:$src1, i128mem:$src3, u8imm:$src5),
7320     [(set GR32:$dst, EFLAGS,
7321       (X86pcmpestri VR128:$src1, EAX, (bc_v16i8 (ld_frag addr:$src3)), EDX,
7322        imm:$src5))]>;
7323 }
7324
7325 let Defs = [EFLAGS], Uses = [EAX, EDX], usesCustomInserter = 1 in {
7326   defm VPCMPESTRI : pseudo_pcmpestri<"#VPCMPESTRI", loadv2i64>,
7327                       Requires<[HasAVX]>;
7328   defm PCMPESTRI  : pseudo_pcmpestri<"#PCMPESTRI", memopv2i64>,
7329                       Requires<[UseSSE42]>;
7330 }
7331
7332 multiclass SS42AI_pcmpestri<string asm> {
7333   def rr : SS42AI<0x61, MRMSrcReg, (outs),
7334     (ins VR128:$src1, VR128:$src3, u8imm:$src5),
7335     !strconcat(asm, "\t{$src5, $src3, $src1|$src1, $src3, $src5}"),
7336     []>, Sched<[WritePCmpEStrI]>;
7337   let mayLoad = 1 in
7338   def rm : SS42AI<0x61, MRMSrcMem, (outs),
7339     (ins VR128:$src1, i128mem:$src3, u8imm:$src5),
7340     !strconcat(asm, "\t{$src5, $src3, $src1|$src1, $src3, $src5}"),
7341     []>, Sched<[WritePCmpEStrILd, ReadAfterLd]>;
7342 }
7343
7344 let Defs = [ECX, EFLAGS], Uses = [EAX, EDX], hasSideEffects = 0 in {
7345   let Predicates = [HasAVX] in
7346   defm VPCMPESTRI : SS42AI_pcmpestri<"vpcmpestri">, VEX;
7347   defm PCMPESTRI  : SS42AI_pcmpestri<"pcmpestri">;
7348 }
7349
7350 //===----------------------------------------------------------------------===//
7351 // SSE4.2 - CRC Instructions
7352 //===----------------------------------------------------------------------===//
7353
7354 // No CRC instructions have AVX equivalents
7355
7356 // crc intrinsic instruction
7357 // This set of instructions are only rm, the only difference is the size
7358 // of r and m.
7359 class SS42I_crc32r<bits<8> opc, string asm, RegisterClass RCOut,
7360                    RegisterClass RCIn, SDPatternOperator Int> :
7361   SS42FI<opc, MRMSrcReg, (outs RCOut:$dst), (ins RCOut:$src1, RCIn:$src2),
7362          !strconcat(asm, "\t{$src2, $src1|$src1, $src2}"),
7363          [(set RCOut:$dst, (Int RCOut:$src1, RCIn:$src2))], IIC_CRC32_REG>,
7364          Sched<[WriteFAdd]>;
7365
7366 class SS42I_crc32m<bits<8> opc, string asm, RegisterClass RCOut,
7367                    X86MemOperand x86memop, SDPatternOperator Int> :
7368   SS42FI<opc, MRMSrcMem, (outs RCOut:$dst), (ins RCOut:$src1, x86memop:$src2),
7369          !strconcat(asm, "\t{$src2, $src1|$src1, $src2}"),
7370          [(set RCOut:$dst, (Int RCOut:$src1, (load addr:$src2)))],
7371          IIC_CRC32_MEM>, Sched<[WriteFAddLd, ReadAfterLd]>;
7372
7373 let Constraints = "$src1 = $dst" in {
7374   def CRC32r32m8  : SS42I_crc32m<0xF0, "crc32{b}", GR32, i8mem,
7375                                  int_x86_sse42_crc32_32_8>;
7376   def CRC32r32r8  : SS42I_crc32r<0xF0, "crc32{b}", GR32, GR8,
7377                                  int_x86_sse42_crc32_32_8>;
7378   def CRC32r32m16 : SS42I_crc32m<0xF1, "crc32{w}", GR32, i16mem,
7379                                  int_x86_sse42_crc32_32_16>, OpSize16;
7380   def CRC32r32r16 : SS42I_crc32r<0xF1, "crc32{w}", GR32, GR16,
7381                                  int_x86_sse42_crc32_32_16>, OpSize16;
7382   def CRC32r32m32 : SS42I_crc32m<0xF1, "crc32{l}", GR32, i32mem,
7383                                  int_x86_sse42_crc32_32_32>, OpSize32;
7384   def CRC32r32r32 : SS42I_crc32r<0xF1, "crc32{l}", GR32, GR32,
7385                                  int_x86_sse42_crc32_32_32>, OpSize32;
7386   def CRC32r64m64 : SS42I_crc32m<0xF1, "crc32{q}", GR64, i64mem,
7387                                  int_x86_sse42_crc32_64_64>, REX_W;
7388   def CRC32r64r64 : SS42I_crc32r<0xF1, "crc32{q}", GR64, GR64,
7389                                  int_x86_sse42_crc32_64_64>, REX_W;
7390   let hasSideEffects = 0 in {
7391     let mayLoad = 1 in
7392     def CRC32r64m8 : SS42I_crc32m<0xF0, "crc32{b}", GR64, i8mem,
7393                                    null_frag>, REX_W;
7394     def CRC32r64r8 : SS42I_crc32r<0xF0, "crc32{b}", GR64, GR8,
7395                                    null_frag>, REX_W;
7396   }
7397 }
7398
7399 //===----------------------------------------------------------------------===//
7400 // SHA-NI Instructions
7401 //===----------------------------------------------------------------------===//
7402
7403 multiclass SHAI_binop<bits<8> Opc, string OpcodeStr, Intrinsic IntId,
7404                       bit UsesXMM0 = 0> {
7405   def rr : I<Opc, MRMSrcReg, (outs VR128:$dst),
7406              (ins VR128:$src1, VR128:$src2),
7407              !if(UsesXMM0,
7408                  !strconcat(OpcodeStr, "\t{%xmm0, $src2, $dst|$dst, $src2, xmm0}"),
7409                  !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}")),
7410              [!if(UsesXMM0,
7411                   (set VR128:$dst, (IntId VR128:$src1, VR128:$src2, XMM0)),
7412                   (set VR128:$dst, (IntId VR128:$src1, VR128:$src2)))]>, T8;
7413
7414   def rm : I<Opc, MRMSrcMem, (outs VR128:$dst),
7415              (ins VR128:$src1, i128mem:$src2),
7416              !if(UsesXMM0,
7417                  !strconcat(OpcodeStr, "\t{%xmm0, $src2, $dst|$dst, $src2, xmm0}"),
7418                  !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}")),
7419              [!if(UsesXMM0,
7420                   (set VR128:$dst, (IntId VR128:$src1,
7421                     (bc_v4i32 (memopv2i64 addr:$src2)), XMM0)),
7422                   (set VR128:$dst, (IntId VR128:$src1,
7423                     (bc_v4i32 (memopv2i64 addr:$src2)))))]>, T8;
7424 }
7425
7426 let Constraints = "$src1 = $dst", Predicates = [HasSHA] in {
7427   def SHA1RNDS4rri : Ii8<0xCC, MRMSrcReg, (outs VR128:$dst),
7428                          (ins VR128:$src1, VR128:$src2, u8imm:$src3),
7429                          "sha1rnds4\t{$src3, $src2, $dst|$dst, $src2, $src3}",
7430                          [(set VR128:$dst,
7431                            (int_x86_sha1rnds4 VR128:$src1, VR128:$src2,
7432                             (i8 imm:$src3)))]>, TA;
7433   def SHA1RNDS4rmi : Ii8<0xCC, MRMSrcMem, (outs VR128:$dst),
7434                          (ins VR128:$src1, i128mem:$src2, u8imm:$src3),
7435                          "sha1rnds4\t{$src3, $src2, $dst|$dst, $src2, $src3}",
7436                          [(set VR128:$dst,
7437                            (int_x86_sha1rnds4 VR128:$src1,
7438                             (bc_v4i32 (memopv2i64 addr:$src2)),
7439                             (i8 imm:$src3)))]>, TA;
7440
7441   defm SHA1NEXTE : SHAI_binop<0xC8, "sha1nexte", int_x86_sha1nexte>;
7442   defm SHA1MSG1  : SHAI_binop<0xC9, "sha1msg1", int_x86_sha1msg1>;
7443   defm SHA1MSG2  : SHAI_binop<0xCA, "sha1msg2", int_x86_sha1msg2>;
7444
7445   let Uses=[XMM0] in
7446   defm SHA256RNDS2 : SHAI_binop<0xCB, "sha256rnds2", int_x86_sha256rnds2, 1>;
7447
7448   defm SHA256MSG1 : SHAI_binop<0xCC, "sha256msg1", int_x86_sha256msg1>;
7449   defm SHA256MSG2 : SHAI_binop<0xCD, "sha256msg2", int_x86_sha256msg2>;
7450 }
7451
7452 // Aliases with explicit %xmm0
7453 def : InstAlias<"sha256rnds2\t{$src2, $dst|$dst, $src2}",
7454                 (SHA256RNDS2rr VR128:$dst, VR128:$src2), 0>;
7455 def : InstAlias<"sha256rnds2\t{$src2, $dst|$dst, $src2}",
7456                 (SHA256RNDS2rm VR128:$dst, i128mem:$src2), 0>;
7457
7458 //===----------------------------------------------------------------------===//
7459 // AES-NI Instructions
7460 //===----------------------------------------------------------------------===//
7461
7462 multiclass AESI_binop_rm_int<bits<8> opc, string OpcodeStr, Intrinsic IntId128,
7463                              PatFrag ld_frag, bit Is2Addr = 1> {
7464   def rr : AES8I<opc, MRMSrcReg, (outs VR128:$dst),
7465        (ins VR128:$src1, VR128:$src2),
7466        !if(Is2Addr,
7467            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
7468            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
7469        [(set VR128:$dst, (IntId128 VR128:$src1, VR128:$src2))]>,
7470        Sched<[WriteAESDecEnc]>;
7471   def rm : AES8I<opc, MRMSrcMem, (outs VR128:$dst),
7472        (ins VR128:$src1, i128mem:$src2),
7473        !if(Is2Addr,
7474            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
7475            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
7476        [(set VR128:$dst,
7477          (IntId128 VR128:$src1, (ld_frag addr:$src2)))]>,
7478        Sched<[WriteAESDecEncLd, ReadAfterLd]>;
7479 }
7480
7481 // Perform One Round of an AES Encryption/Decryption Flow
7482 let Predicates = [HasAVX, HasAES] in {
7483   defm VAESENC          : AESI_binop_rm_int<0xDC, "vaesenc",
7484                          int_x86_aesni_aesenc, loadv2i64, 0>, VEX_4V, VEX_WIG;
7485   defm VAESENCLAST      : AESI_binop_rm_int<0xDD, "vaesenclast",
7486                          int_x86_aesni_aesenclast, loadv2i64, 0>, VEX_4V, VEX_WIG;
7487   defm VAESDEC          : AESI_binop_rm_int<0xDE, "vaesdec",
7488                          int_x86_aesni_aesdec, loadv2i64, 0>, VEX_4V, VEX_WIG;
7489   defm VAESDECLAST      : AESI_binop_rm_int<0xDF, "vaesdeclast",
7490                          int_x86_aesni_aesdeclast, loadv2i64, 0>, VEX_4V, VEX_WIG;
7491 }
7492
7493 let Constraints = "$src1 = $dst" in {
7494   defm AESENC          : AESI_binop_rm_int<0xDC, "aesenc",
7495                          int_x86_aesni_aesenc, memopv2i64>;
7496   defm AESENCLAST      : AESI_binop_rm_int<0xDD, "aesenclast",
7497                          int_x86_aesni_aesenclast, memopv2i64>;
7498   defm AESDEC          : AESI_binop_rm_int<0xDE, "aesdec",
7499                          int_x86_aesni_aesdec, memopv2i64>;
7500   defm AESDECLAST      : AESI_binop_rm_int<0xDF, "aesdeclast",
7501                          int_x86_aesni_aesdeclast, memopv2i64>;
7502 }
7503
7504 // Perform the AES InvMixColumn Transformation
7505 let Predicates = [HasAVX, HasAES] in {
7506   def VAESIMCrr : AES8I<0xDB, MRMSrcReg, (outs VR128:$dst),
7507       (ins VR128:$src1),
7508       "vaesimc\t{$src1, $dst|$dst, $src1}",
7509       [(set VR128:$dst,
7510         (int_x86_aesni_aesimc VR128:$src1))]>, Sched<[WriteAESIMC]>,
7511       VEX, VEX_WIG;
7512   def VAESIMCrm : AES8I<0xDB, MRMSrcMem, (outs VR128:$dst),
7513       (ins i128mem:$src1),
7514       "vaesimc\t{$src1, $dst|$dst, $src1}",
7515       [(set VR128:$dst, (int_x86_aesni_aesimc (loadv2i64 addr:$src1)))]>,
7516       Sched<[WriteAESIMCLd]>, VEX, VEX_WIG;
7517 }
7518 def AESIMCrr : AES8I<0xDB, MRMSrcReg, (outs VR128:$dst),
7519   (ins VR128:$src1),
7520   "aesimc\t{$src1, $dst|$dst, $src1}",
7521   [(set VR128:$dst,
7522     (int_x86_aesni_aesimc VR128:$src1))]>, Sched<[WriteAESIMC]>;
7523 def AESIMCrm : AES8I<0xDB, MRMSrcMem, (outs VR128:$dst),
7524   (ins i128mem:$src1),
7525   "aesimc\t{$src1, $dst|$dst, $src1}",
7526   [(set VR128:$dst, (int_x86_aesni_aesimc (memopv2i64 addr:$src1)))]>,
7527   Sched<[WriteAESIMCLd]>;
7528
7529 // AES Round Key Generation Assist
7530 let Predicates = [HasAVX, HasAES] in {
7531   def VAESKEYGENASSIST128rr : AESAI<0xDF, MRMSrcReg, (outs VR128:$dst),
7532       (ins VR128:$src1, u8imm:$src2),
7533       "vaeskeygenassist\t{$src2, $src1, $dst|$dst, $src1, $src2}",
7534       [(set VR128:$dst,
7535         (int_x86_aesni_aeskeygenassist VR128:$src1, imm:$src2))]>,
7536       Sched<[WriteAESKeyGen]>, VEX, VEX_WIG;
7537   def VAESKEYGENASSIST128rm : AESAI<0xDF, MRMSrcMem, (outs VR128:$dst),
7538       (ins i128mem:$src1, u8imm:$src2),
7539       "vaeskeygenassist\t{$src2, $src1, $dst|$dst, $src1, $src2}",
7540       [(set VR128:$dst,
7541         (int_x86_aesni_aeskeygenassist (loadv2i64 addr:$src1), imm:$src2))]>,
7542       Sched<[WriteAESKeyGenLd]>, VEX, VEX_WIG;
7543 }
7544 def AESKEYGENASSIST128rr : AESAI<0xDF, MRMSrcReg, (outs VR128:$dst),
7545   (ins VR128:$src1, u8imm:$src2),
7546   "aeskeygenassist\t{$src2, $src1, $dst|$dst, $src1, $src2}",
7547   [(set VR128:$dst,
7548     (int_x86_aesni_aeskeygenassist VR128:$src1, imm:$src2))]>,
7549   Sched<[WriteAESKeyGen]>;
7550 def AESKEYGENASSIST128rm : AESAI<0xDF, MRMSrcMem, (outs VR128:$dst),
7551   (ins i128mem:$src1, u8imm:$src2),
7552   "aeskeygenassist\t{$src2, $src1, $dst|$dst, $src1, $src2}",
7553   [(set VR128:$dst,
7554     (int_x86_aesni_aeskeygenassist (memopv2i64 addr:$src1), imm:$src2))]>,
7555   Sched<[WriteAESKeyGenLd]>;
7556
7557 //===----------------------------------------------------------------------===//
7558 // PCLMUL Instructions
7559 //===----------------------------------------------------------------------===//
7560
7561 // AVX carry-less Multiplication instructions
7562 let isCommutable = 1 in
7563 def VPCLMULQDQrr : AVXPCLMULIi8<0x44, MRMSrcReg, (outs VR128:$dst),
7564            (ins VR128:$src1, VR128:$src2, u8imm:$src3),
7565            "vpclmulqdq\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
7566            [(set VR128:$dst,
7567              (int_x86_pclmulqdq VR128:$src1, VR128:$src2, imm:$src3))]>,
7568            Sched<[WriteCLMul]>, VEX_WIG;
7569
7570 def VPCLMULQDQrm : AVXPCLMULIi8<0x44, MRMSrcMem, (outs VR128:$dst),
7571            (ins VR128:$src1, i128mem:$src2, u8imm:$src3),
7572            "vpclmulqdq\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
7573            [(set VR128:$dst, (int_x86_pclmulqdq VR128:$src1,
7574                               (loadv2i64 addr:$src2), imm:$src3))]>,
7575            Sched<[WriteCLMulLd, ReadAfterLd]>, VEX_WIG;
7576
7577 // Carry-less Multiplication instructions
7578 let Constraints = "$src1 = $dst" in {
7579 let isCommutable = 1 in
7580 def PCLMULQDQrr : PCLMULIi8<0x44, MRMSrcReg, (outs VR128:$dst),
7581            (ins VR128:$src1, VR128:$src2, u8imm:$src3),
7582            "pclmulqdq\t{$src3, $src2, $dst|$dst, $src2, $src3}",
7583            [(set VR128:$dst,
7584              (int_x86_pclmulqdq VR128:$src1, VR128:$src2, imm:$src3))],
7585              IIC_SSE_PCLMULQDQ_RR>, Sched<[WriteCLMul]>;
7586
7587 def PCLMULQDQrm : PCLMULIi8<0x44, MRMSrcMem, (outs VR128:$dst),
7588            (ins VR128:$src1, i128mem:$src2, u8imm:$src3),
7589            "pclmulqdq\t{$src3, $src2, $dst|$dst, $src2, $src3}",
7590            [(set VR128:$dst, (int_x86_pclmulqdq VR128:$src1,
7591                               (memopv2i64 addr:$src2), imm:$src3))],
7592                               IIC_SSE_PCLMULQDQ_RM>,
7593            Sched<[WriteCLMulLd, ReadAfterLd]>;
7594 } // Constraints = "$src1 = $dst"
7595
7596
7597 multiclass pclmul_alias<string asm, int immop> {
7598   def : InstAlias<!strconcat("pclmul", asm, "dq {$src, $dst|$dst, $src}"),
7599                   (PCLMULQDQrr VR128:$dst, VR128:$src, immop), 0>;
7600
7601   def : InstAlias<!strconcat("pclmul", asm, "dq {$src, $dst|$dst, $src}"),
7602                   (PCLMULQDQrm VR128:$dst, i128mem:$src, immop), 0>;
7603
7604   def : InstAlias<!strconcat("vpclmul", asm,
7605                              "dq {$src2, $src1, $dst|$dst, $src1, $src2}"),
7606                   (VPCLMULQDQrr VR128:$dst, VR128:$src1, VR128:$src2, immop),
7607                   0>;
7608
7609   def : InstAlias<!strconcat("vpclmul", asm,
7610                              "dq {$src2, $src1, $dst|$dst, $src1, $src2}"),
7611                   (VPCLMULQDQrm VR128:$dst, VR128:$src1, i128mem:$src2, immop),
7612                   0>;
7613 }
7614 defm : pclmul_alias<"hqhq", 0x11>;
7615 defm : pclmul_alias<"hqlq", 0x01>;
7616 defm : pclmul_alias<"lqhq", 0x10>;
7617 defm : pclmul_alias<"lqlq", 0x00>;
7618
7619 //===----------------------------------------------------------------------===//
7620 // SSE4A Instructions
7621 //===----------------------------------------------------------------------===//
7622
7623 let Predicates = [HasSSE4A] in {
7624
7625 let ExeDomain = SSEPackedInt in {
7626 let Constraints = "$src = $dst" in {
7627 def EXTRQI : Ii8<0x78, MRMXr, (outs VR128:$dst),
7628                  (ins VR128:$src, u8imm:$len, u8imm:$idx),
7629                  "extrq\t{$idx, $len, $src|$src, $len, $idx}",
7630                  [(set VR128:$dst, (X86extrqi VR128:$src, imm:$len,
7631                                     imm:$idx))]>, PD;
7632 def EXTRQ  : I<0x79, MRMSrcReg, (outs VR128:$dst),
7633               (ins VR128:$src, VR128:$mask),
7634               "extrq\t{$mask, $src|$src, $mask}",
7635               [(set VR128:$dst, (int_x86_sse4a_extrq VR128:$src,
7636                                  VR128:$mask))]>, PD;
7637
7638 def INSERTQI : Ii8<0x78, MRMSrcReg, (outs VR128:$dst),
7639                    (ins VR128:$src, VR128:$src2, u8imm:$len, u8imm:$idx),
7640                    "insertq\t{$idx, $len, $src2, $src|$src, $src2, $len, $idx}",
7641                    [(set VR128:$dst, (X86insertqi VR128:$src, VR128:$src2,
7642                                       imm:$len, imm:$idx))]>, XD;
7643 def INSERTQ  : I<0x79, MRMSrcReg, (outs VR128:$dst),
7644                  (ins VR128:$src, VR128:$mask),
7645                  "insertq\t{$mask, $src|$src, $mask}",
7646                  [(set VR128:$dst, (int_x86_sse4a_insertq VR128:$src,
7647                                     VR128:$mask))]>, XD;
7648 }
7649 } // ExeDomain = SSEPackedInt
7650
7651 // Non-temporal (unaligned) scalar stores.
7652 let AddedComplexity = 400 in { // Prefer non-temporal versions
7653 let mayStore = 1, SchedRW = [WriteStore] in {
7654 def MOVNTSS : I<0x2B, MRMDestMem, (outs), (ins f32mem:$dst, VR128:$src),
7655                 "movntss\t{$src, $dst|$dst, $src}", [], IIC_SSE_MOVNT>, XS;
7656
7657 def MOVNTSD : I<0x2B, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
7658                 "movntsd\t{$src, $dst|$dst, $src}", [], IIC_SSE_MOVNT>, XD;
7659 } // SchedRW
7660
7661 def : Pat<(nontemporalstore FR32:$src, addr:$dst),
7662           (MOVNTSS addr:$dst, (COPY_TO_REGCLASS FR32:$src, VR128))>;
7663
7664 def : Pat<(nontemporalstore FR64:$src, addr:$dst),
7665           (MOVNTSD addr:$dst, (COPY_TO_REGCLASS FR64:$src, VR128))>;
7666
7667 } // AddedComplexity
7668 } // HasSSE4A
7669
7670 //===----------------------------------------------------------------------===//
7671 // AVX Instructions
7672 //===----------------------------------------------------------------------===//
7673
7674 //===----------------------------------------------------------------------===//
7675 // VBROADCAST - Load from memory and broadcast to all elements of the
7676 //              destination operand
7677 //
7678 class avx_broadcast_rm<bits<8> opc, string OpcodeStr, RegisterClass RC,
7679                            X86MemOperand x86memop, ValueType VT,
7680                            PatFrag ld_frag, SchedWrite Sched> :
7681   AVX8I<opc, MRMSrcMem, (outs RC:$dst), (ins x86memop:$src),
7682         !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
7683         [(set RC:$dst, (VT (X86VBroadcast (ld_frag addr:$src))))]>,
7684         Sched<[Sched]>, VEX;
7685
7686 // AVX2 adds register forms
7687 class avx2_broadcast_rr<bits<8> opc, string OpcodeStr, RegisterClass RC,
7688                         ValueType ResVT, ValueType OpVT, SchedWrite Sched> :
7689   AVX28I<opc, MRMSrcReg, (outs RC:$dst), (ins VR128:$src),
7690          !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
7691          [(set RC:$dst, (ResVT (X86VBroadcast (OpVT VR128:$src))))]>,
7692          Sched<[Sched]>, VEX;
7693
7694 let ExeDomain = SSEPackedSingle, Predicates = [HasAVX, NoVLX] in {
7695   def VBROADCASTSSrm  : avx_broadcast_rm<0x18, "vbroadcastss", VR128,
7696                                              f32mem, v4f32, loadf32, WriteLoad>;
7697   def VBROADCASTSSYrm : avx_broadcast_rm<0x18, "vbroadcastss", VR256,
7698                                              f32mem, v8f32, loadf32,
7699                                              WriteFShuffleLd>, VEX_L;
7700 }
7701 let ExeDomain = SSEPackedDouble, Predicates = [HasAVX, NoVLX] in
7702 def VBROADCASTSDYrm  : avx_broadcast_rm<0x19, "vbroadcastsd", VR256, f64mem,
7703                                     v4f64, loadf64, WriteFShuffleLd>, VEX_L;
7704
7705 let ExeDomain = SSEPackedSingle, Predicates = [HasAVX2, NoVLX] in {
7706   def VBROADCASTSSrr  : avx2_broadcast_rr<0x18, "vbroadcastss", VR128,
7707                                           v4f32, v4f32, WriteFShuffle>;
7708   def VBROADCASTSSYrr : avx2_broadcast_rr<0x18, "vbroadcastss", VR256,
7709                                           v8f32, v4f32, WriteFShuffle256>, VEX_L;
7710 }
7711 let ExeDomain = SSEPackedDouble, Predicates = [HasAVX2, NoVLX] in
7712 def VBROADCASTSDYrr  : avx2_broadcast_rr<0x19, "vbroadcastsd", VR256,
7713                                          v4f64, v2f64, WriteFShuffle256>, VEX_L;
7714
7715 //===----------------------------------------------------------------------===//
7716 // VBROADCAST*128 - Load from memory and broadcast 128-bit vector to both
7717 //                  halves of a 256-bit vector.
7718 //
7719 let mayLoad = 1, hasSideEffects = 0, Predicates = [HasAVX2] in
7720 def VBROADCASTI128 : AVX8I<0x5A, MRMSrcMem, (outs VR256:$dst),
7721                            (ins i128mem:$src),
7722                            "vbroadcasti128\t{$src, $dst|$dst, $src}", []>,
7723                            Sched<[WriteLoad]>, VEX, VEX_L;
7724
7725 let mayLoad = 1, hasSideEffects = 0, Predicates = [HasAVX] in
7726 def VBROADCASTF128 : AVX8I<0x1A, MRMSrcMem, (outs VR256:$dst),
7727                            (ins f128mem:$src),
7728                            "vbroadcastf128\t{$src, $dst|$dst, $src}", []>,
7729                            Sched<[WriteFShuffleLd]>, VEX, VEX_L;
7730
7731 let Predicates = [HasAVX2, NoVLX] in {
7732 def : Pat<(v4i64 (X86SubVBroadcast (loadv2i64 addr:$src))),
7733           (VBROADCASTI128 addr:$src)>;
7734 def : Pat<(v8i32 (X86SubVBroadcast (bc_v4i32 (loadv2i64 addr:$src)))),
7735           (VBROADCASTI128 addr:$src)>;
7736 def : Pat<(v16i16 (X86SubVBroadcast (bc_v8i16 (loadv2i64 addr:$src)))),
7737           (VBROADCASTI128 addr:$src)>;
7738 def : Pat<(v32i8 (X86SubVBroadcast (bc_v16i8 (loadv2i64 addr:$src)))),
7739           (VBROADCASTI128 addr:$src)>;
7740 }
7741
7742 let Predicates = [HasAVX, NoVLX] in {
7743 def : Pat<(v4f64 (X86SubVBroadcast (loadv2f64 addr:$src))),
7744           (VBROADCASTF128 addr:$src)>;
7745 def : Pat<(v8f32 (X86SubVBroadcast (loadv4f32 addr:$src))),
7746           (VBROADCASTF128 addr:$src)>;
7747 }
7748
7749 let Predicates = [HasAVX1Only] in {
7750 def : Pat<(v4i64 (X86SubVBroadcast (loadv2i64 addr:$src))),
7751           (VBROADCASTF128 addr:$src)>;
7752 def : Pat<(v8i32 (X86SubVBroadcast (bc_v4i32 (loadv2i64 addr:$src)))),
7753           (VBROADCASTF128 addr:$src)>;
7754 def : Pat<(v16i16 (X86SubVBroadcast (bc_v8i16 (loadv2i64 addr:$src)))),
7755           (VBROADCASTF128 addr:$src)>;
7756 def : Pat<(v32i8 (X86SubVBroadcast (bc_v16i8 (loadv2i64 addr:$src)))),
7757           (VBROADCASTF128 addr:$src)>;
7758 }
7759
7760 //===----------------------------------------------------------------------===//
7761 // VINSERTF128 - Insert packed floating-point values
7762 //
7763 let hasSideEffects = 0, ExeDomain = SSEPackedSingle in {
7764 def VINSERTF128rr : AVXAIi8<0x18, MRMSrcReg, (outs VR256:$dst),
7765           (ins VR256:$src1, VR128:$src2, u8imm:$src3),
7766           "vinsertf128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
7767           []>, Sched<[WriteFShuffle]>, VEX_4V, VEX_L;
7768 let mayLoad = 1 in
7769 def VINSERTF128rm : AVXAIi8<0x18, MRMSrcMem, (outs VR256:$dst),
7770           (ins VR256:$src1, f128mem:$src2, u8imm:$src3),
7771           "vinsertf128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
7772           []>, Sched<[WriteFShuffleLd, ReadAfterLd]>, VEX_4V, VEX_L;
7773 }
7774
7775 // To create a 256-bit all ones value, we should produce VCMPTRUEPS
7776 // with YMM register containing zero.
7777 // FIXME: Avoid producing vxorps to clear the fake inputs.
7778 let Predicates = [HasAVX1Only] in {
7779 def : Pat<(v8i32 immAllOnesV), (VCMPPSYrri (AVX_SET0), (AVX_SET0), 0xf)>;
7780 }
7781
7782 multiclass vinsert_lowering<string InstrStr, ValueType From, ValueType To,
7783                             PatFrag memop_frag> {
7784   def : Pat<(vinsert128_insert:$ins (To VR256:$src1), (From VR128:$src2),
7785                                    (iPTR imm)),
7786             (!cast<Instruction>(InstrStr#rr) VR256:$src1, VR128:$src2,
7787                                        (INSERT_get_vinsert128_imm VR256:$ins))>;
7788   def : Pat<(vinsert128_insert:$ins (To VR256:$src1),
7789                                     (From (bitconvert (memop_frag addr:$src2))),
7790                                     (iPTR imm)),
7791             (!cast<Instruction>(InstrStr#rm) VR256:$src1, addr:$src2,
7792                                        (INSERT_get_vinsert128_imm VR256:$ins))>;
7793 }
7794
7795 let Predicates = [HasAVX, NoVLX] in {
7796   defm : vinsert_lowering<"VINSERTF128", v4f32, v8f32, loadv4f32>;
7797   defm : vinsert_lowering<"VINSERTF128", v2f64, v4f64, loadv2f64>;
7798 }
7799
7800 let Predicates = [HasAVX1Only] in {
7801   defm : vinsert_lowering<"VINSERTF128", v2i64, v4i64,  loadv2i64>;
7802   defm : vinsert_lowering<"VINSERTF128", v4i32, v8i32,  loadv2i64>;
7803   defm : vinsert_lowering<"VINSERTF128", v8i16, v16i16, loadv2i64>;
7804   defm : vinsert_lowering<"VINSERTF128", v16i8, v32i8,  loadv2i64>;
7805 }
7806
7807 //===----------------------------------------------------------------------===//
7808 // VEXTRACTF128 - Extract packed floating-point values
7809 //
7810 let hasSideEffects = 0, ExeDomain = SSEPackedSingle in {
7811 def VEXTRACTF128rr : AVXAIi8<0x19, MRMDestReg, (outs VR128:$dst),
7812           (ins VR256:$src1, u8imm:$src2),
7813           "vextractf128\t{$src2, $src1, $dst|$dst, $src1, $src2}",
7814           []>, Sched<[WriteFShuffle]>, VEX, VEX_L;
7815 let mayStore = 1 in
7816 def VEXTRACTF128mr : AVXAIi8<0x19, MRMDestMem, (outs),
7817           (ins f128mem:$dst, VR256:$src1, u8imm:$src2),
7818           "vextractf128\t{$src2, $src1, $dst|$dst, $src1, $src2}",
7819           []>, Sched<[WriteStore]>, VEX, VEX_L;
7820 }
7821
7822 multiclass vextract_lowering<string InstrStr, ValueType From, ValueType To> {
7823   def : Pat<(vextract128_extract:$ext VR256:$src1, (iPTR imm)),
7824             (To (!cast<Instruction>(InstrStr#rr)
7825                                     (From VR256:$src1),
7826                                     (EXTRACT_get_vextract128_imm VR128:$ext)))>;
7827   def : Pat<(store (To (vextract128_extract:$ext (From VR256:$src1),
7828                                                  (iPTR imm))), addr:$dst),
7829             (!cast<Instruction>(InstrStr#mr) addr:$dst, VR256:$src1,
7830              (EXTRACT_get_vextract128_imm VR128:$ext))>;
7831 }
7832
7833 // AVX1 patterns
7834 let Predicates = [HasAVX, NoVLX] in {
7835   defm : vextract_lowering<"VEXTRACTF128", v8f32, v4f32>;
7836   defm : vextract_lowering<"VEXTRACTF128", v4f64, v2f64>;
7837 }
7838
7839 let Predicates = [HasAVX1Only] in {
7840   defm : vextract_lowering<"VEXTRACTF128", v4i64,  v2i64>;
7841   defm : vextract_lowering<"VEXTRACTF128", v8i32,  v4i32>;
7842   defm : vextract_lowering<"VEXTRACTF128", v16i16, v8i16>;
7843   defm : vextract_lowering<"VEXTRACTF128", v32i8,  v16i8>;
7844 }
7845
7846 //===----------------------------------------------------------------------===//
7847 // VMASKMOV - Conditional SIMD Packed Loads and Stores
7848 //
7849 multiclass avx_movmask_rm<bits<8> opc_rm, bits<8> opc_mr, string OpcodeStr,
7850                           Intrinsic IntLd, Intrinsic IntLd256,
7851                           Intrinsic IntSt, Intrinsic IntSt256> {
7852   def rm  : AVX8I<opc_rm, MRMSrcMem, (outs VR128:$dst),
7853              (ins VR128:$src1, f128mem:$src2),
7854              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7855              [(set VR128:$dst, (IntLd addr:$src2, VR128:$src1))]>,
7856              VEX_4V;
7857   def Yrm : AVX8I<opc_rm, MRMSrcMem, (outs VR256:$dst),
7858              (ins VR256:$src1, f256mem:$src2),
7859              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7860              [(set VR256:$dst, (IntLd256 addr:$src2, VR256:$src1))]>,
7861              VEX_4V, VEX_L;
7862   def mr  : AVX8I<opc_mr, MRMDestMem, (outs),
7863              (ins f128mem:$dst, VR128:$src1, VR128:$src2),
7864              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7865              [(IntSt addr:$dst, VR128:$src1, VR128:$src2)]>, VEX_4V;
7866   def Ymr : AVX8I<opc_mr, MRMDestMem, (outs),
7867              (ins f256mem:$dst, VR256:$src1, VR256:$src2),
7868              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7869              [(IntSt256 addr:$dst, VR256:$src1, VR256:$src2)]>, VEX_4V, VEX_L;
7870 }
7871
7872 let ExeDomain = SSEPackedSingle in
7873 defm VMASKMOVPS : avx_movmask_rm<0x2C, 0x2E, "vmaskmovps",
7874                                  int_x86_avx_maskload_ps,
7875                                  int_x86_avx_maskload_ps_256,
7876                                  int_x86_avx_maskstore_ps,
7877                                  int_x86_avx_maskstore_ps_256>;
7878 let ExeDomain = SSEPackedDouble in
7879 defm VMASKMOVPD : avx_movmask_rm<0x2D, 0x2F, "vmaskmovpd",
7880                                  int_x86_avx_maskload_pd,
7881                                  int_x86_avx_maskload_pd_256,
7882                                  int_x86_avx_maskstore_pd,
7883                                  int_x86_avx_maskstore_pd_256>;
7884
7885 //===----------------------------------------------------------------------===//
7886 // VPERMIL - Permute Single and Double Floating-Point Values
7887 //
7888 multiclass avx_permil<bits<8> opc_rm, bits<8> opc_rmi, string OpcodeStr,
7889                       RegisterClass RC, X86MemOperand x86memop_f,
7890                       X86MemOperand x86memop_i, PatFrag i_frag,
7891                       ValueType f_vt, ValueType i_vt> {
7892   let Predicates = [HasAVX, NoVLX] in {
7893     def rr  : AVX8I<opc_rm, MRMSrcReg, (outs RC:$dst),
7894                (ins RC:$src1, RC:$src2),
7895                !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7896                [(set RC:$dst, (f_vt (X86VPermilpv RC:$src1, (i_vt RC:$src2))))]>, VEX_4V,
7897                Sched<[WriteFShuffle]>;
7898     def rm  : AVX8I<opc_rm, MRMSrcMem, (outs RC:$dst),
7899                (ins RC:$src1, x86memop_i:$src2),
7900                !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7901                [(set RC:$dst, (f_vt (X86VPermilpv RC:$src1,
7902                               (i_vt (bitconvert (i_frag addr:$src2))))))]>, VEX_4V,
7903                Sched<[WriteFShuffleLd, ReadAfterLd]>;
7904
7905     def ri  : AVXAIi8<opc_rmi, MRMSrcReg, (outs RC:$dst),
7906              (ins RC:$src1, u8imm:$src2),
7907              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7908              [(set RC:$dst, (f_vt (X86VPermilpi RC:$src1, (i8 imm:$src2))))]>, VEX,
7909              Sched<[WriteFShuffle]>;
7910     def mi  : AVXAIi8<opc_rmi, MRMSrcMem, (outs RC:$dst),
7911              (ins x86memop_f:$src1, u8imm:$src2),
7912              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7913              [(set RC:$dst,
7914                (f_vt (X86VPermilpi (load addr:$src1), (i8 imm:$src2))))]>, VEX,
7915              Sched<[WriteFShuffleLd]>;
7916   }// Predicates = [HasAVX, NoVLX]
7917 }
7918
7919 let ExeDomain = SSEPackedSingle in {
7920   defm VPERMILPS  : avx_permil<0x0C, 0x04, "vpermilps", VR128, f128mem, i128mem,
7921                                loadv2i64, v4f32, v4i32>;
7922   defm VPERMILPSY : avx_permil<0x0C, 0x04, "vpermilps", VR256, f256mem, i256mem,
7923                                loadv4i64, v8f32, v8i32>, VEX_L;
7924 }
7925 let ExeDomain = SSEPackedDouble in {
7926   defm VPERMILPD  : avx_permil<0x0D, 0x05, "vpermilpd", VR128, f128mem, i128mem,
7927                                loadv2i64, v2f64, v2i64>;
7928   defm VPERMILPDY : avx_permil<0x0D, 0x05, "vpermilpd", VR256, f256mem, i256mem,
7929                                loadv4i64, v4f64, v4i64>, VEX_L;
7930 }
7931
7932 //===----------------------------------------------------------------------===//
7933 // VPERM2F128 - Permute Floating-Point Values in 128-bit chunks
7934 //
7935 let ExeDomain = SSEPackedSingle in {
7936 let isCommutable = 1 in
7937 def VPERM2F128rr : AVXAIi8<0x06, MRMSrcReg, (outs VR256:$dst),
7938           (ins VR256:$src1, VR256:$src2, u8imm:$src3),
7939           "vperm2f128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
7940           [(set VR256:$dst, (v8f32 (X86VPerm2x128 VR256:$src1, VR256:$src2,
7941                               (i8 imm:$src3))))]>, VEX_4V, VEX_L,
7942           Sched<[WriteFShuffle]>;
7943 def VPERM2F128rm : AVXAIi8<0x06, MRMSrcMem, (outs VR256:$dst),
7944           (ins VR256:$src1, f256mem:$src2, u8imm:$src3),
7945           "vperm2f128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
7946           [(set VR256:$dst, (X86VPerm2x128 VR256:$src1, (loadv8f32 addr:$src2),
7947                              (i8 imm:$src3)))]>, VEX_4V, VEX_L,
7948           Sched<[WriteFShuffleLd, ReadAfterLd]>;
7949 }
7950
7951 let Predicates = [HasAVX] in {
7952 def : Pat<(v4f64 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
7953           (VPERM2F128rr VR256:$src1, VR256:$src2, imm:$imm)>;
7954 def : Pat<(v4f64 (X86VPerm2x128 VR256:$src1,
7955                   (loadv4f64 addr:$src2), (i8 imm:$imm))),
7956           (VPERM2F128rm VR256:$src1, addr:$src2, imm:$imm)>;
7957 }
7958
7959 let Predicates = [HasAVX1Only] in {
7960 def : Pat<(v8i32 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
7961           (VPERM2F128rr VR256:$src1, VR256:$src2, imm:$imm)>;
7962 def : Pat<(v4i64 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
7963           (VPERM2F128rr VR256:$src1, VR256:$src2, imm:$imm)>;
7964 def : Pat<(v32i8 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
7965           (VPERM2F128rr VR256:$src1, VR256:$src2, imm:$imm)>;
7966 def : Pat<(v16i16 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
7967           (VPERM2F128rr VR256:$src1, VR256:$src2, imm:$imm)>;
7968
7969 def : Pat<(v8i32 (X86VPerm2x128 VR256:$src1,
7970                   (bc_v8i32 (loadv4i64 addr:$src2)), (i8 imm:$imm))),
7971           (VPERM2F128rm VR256:$src1, addr:$src2, imm:$imm)>;
7972 def : Pat<(v4i64 (X86VPerm2x128 VR256:$src1,
7973                   (loadv4i64 addr:$src2), (i8 imm:$imm))),
7974           (VPERM2F128rm VR256:$src1, addr:$src2, imm:$imm)>;
7975 def : Pat<(v32i8 (X86VPerm2x128 VR256:$src1,
7976                   (bc_v32i8 (loadv4i64 addr:$src2)), (i8 imm:$imm))),
7977           (VPERM2F128rm VR256:$src1, addr:$src2, imm:$imm)>;
7978 def : Pat<(v16i16 (X86VPerm2x128 VR256:$src1,
7979                   (bc_v16i16 (loadv4i64 addr:$src2)), (i8 imm:$imm))),
7980           (VPERM2F128rm VR256:$src1, addr:$src2, imm:$imm)>;
7981 }
7982
7983 //===----------------------------------------------------------------------===//
7984 // VZERO - Zero YMM registers
7985 //
7986 // Note, these instruction do not affect the YMM16-YMM31.
7987 let Defs = [YMM0, YMM1, YMM2, YMM3, YMM4, YMM5, YMM6, YMM7,
7988             YMM8, YMM9, YMM10, YMM11, YMM12, YMM13, YMM14, YMM15] in {
7989   // Zero All YMM registers
7990   def VZEROALL : I<0x77, RawFrm, (outs), (ins), "vzeroall",
7991                   [(int_x86_avx_vzeroall)]>, PS, VEX, VEX_L, Requires<[HasAVX]>, VEX_WIG;
7992
7993   // Zero Upper bits of YMM registers
7994   def VZEROUPPER : I<0x77, RawFrm, (outs), (ins), "vzeroupper",
7995                      [(int_x86_avx_vzeroupper)]>, PS, VEX, Requires<[HasAVX]>, VEX_WIG;
7996 }
7997
7998 //===----------------------------------------------------------------------===//
7999 // Half precision conversion instructions
8000 //===----------------------------------------------------------------------===//
8001 multiclass f16c_ph2ps<RegisterClass RC, X86MemOperand x86memop, Intrinsic Int> {
8002   def rr : I<0x13, MRMSrcReg, (outs RC:$dst), (ins VR128:$src),
8003              "vcvtph2ps\t{$src, $dst|$dst, $src}",
8004              [(set RC:$dst, (Int VR128:$src))]>,
8005              T8PD, VEX, Sched<[WriteCvtF2F]>;
8006   let hasSideEffects = 0, mayLoad = 1 in
8007   def rm : I<0x13, MRMSrcMem, (outs RC:$dst), (ins x86memop:$src),
8008              "vcvtph2ps\t{$src, $dst|$dst, $src}", []>, T8PD, VEX,
8009              Sched<[WriteCvtF2FLd]>;
8010 }
8011
8012 multiclass f16c_ps2ph<RegisterClass RC, X86MemOperand x86memop, Intrinsic Int> {
8013   def rr : Ii8<0x1D, MRMDestReg, (outs VR128:$dst),
8014                (ins RC:$src1, i32u8imm:$src2),
8015                "vcvtps2ph\t{$src2, $src1, $dst|$dst, $src1, $src2}",
8016                [(set VR128:$dst, (Int RC:$src1, imm:$src2))]>,
8017                TAPD, VEX, Sched<[WriteCvtF2F]>;
8018   let hasSideEffects = 0, mayStore = 1,
8019       SchedRW = [WriteCvtF2FLd, WriteRMW] in
8020   def mr : Ii8<0x1D, MRMDestMem, (outs),
8021                (ins x86memop:$dst, RC:$src1, i32u8imm:$src2),
8022                "vcvtps2ph\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>,
8023                TAPD, VEX;
8024 }
8025
8026 let Predicates = [HasF16C] in {
8027   defm VCVTPH2PS  : f16c_ph2ps<VR128, f64mem, int_x86_vcvtph2ps_128>;
8028   defm VCVTPH2PSY : f16c_ph2ps<VR256, f128mem, int_x86_vcvtph2ps_256>, VEX_L;
8029   defm VCVTPS2PH  : f16c_ps2ph<VR128, f64mem, int_x86_vcvtps2ph_128>;
8030   defm VCVTPS2PHY : f16c_ps2ph<VR256, f128mem, int_x86_vcvtps2ph_256>, VEX_L;
8031
8032   // Pattern match vcvtph2ps of a scalar i64 load.
8033   def : Pat<(int_x86_vcvtph2ps_128 (vzmovl_v2i64 addr:$src)),
8034             (VCVTPH2PSrm addr:$src)>;
8035   def : Pat<(int_x86_vcvtph2ps_128 (vzload_v2i64 addr:$src)),
8036             (VCVTPH2PSrm addr:$src)>;
8037   def : Pat<(int_x86_vcvtph2ps_128 (bitconvert
8038               (v2i64 (scalar_to_vector (loadi64 addr:$src))))),
8039             (VCVTPH2PSrm addr:$src)>;
8040
8041   def : Pat<(store (f64 (extractelt (bc_v2f64 (v8i16
8042                   (int_x86_vcvtps2ph_128 VR128:$src1, i32:$src2))), (iPTR 0))),
8043                    addr:$dst),
8044                    (VCVTPS2PHmr addr:$dst, VR128:$src1, imm:$src2)>;
8045   def : Pat<(store (i64 (extractelt (bc_v2i64 (v8i16
8046                   (int_x86_vcvtps2ph_128 VR128:$src1, i32:$src2))), (iPTR 0))),
8047                    addr:$dst),
8048                    (VCVTPS2PHmr addr:$dst, VR128:$src1, imm:$src2)>;
8049   def : Pat<(store (v8i16 (int_x86_vcvtps2ph_256 VR256:$src1, i32:$src2)),
8050                    addr:$dst),
8051                    (VCVTPS2PHYmr addr:$dst, VR256:$src1, imm:$src2)>;
8052 }
8053
8054 // Patterns for  matching conversions from float to half-float and vice versa.
8055 let Predicates = [HasF16C, NoVLX] in {
8056   // Use MXCSR.RC for rounding instead of explicitly specifying the default
8057   // rounding mode (Nearest-Even, encoded as 0). Both are equivalent in the
8058   // configurations we support (the default). However, falling back to MXCSR is
8059   // more consistent with other instructions, which are always controlled by it.
8060   // It's encoded as 0b100.
8061   def : Pat<(fp_to_f16 FR32:$src),
8062             (i16 (EXTRACT_SUBREG (VMOVPDI2DIrr (VCVTPS2PHrr
8063               (COPY_TO_REGCLASS FR32:$src, VR128), 4)), sub_16bit))>;
8064
8065   def : Pat<(f16_to_fp GR16:$src),
8066             (f32 (COPY_TO_REGCLASS (VCVTPH2PSrr
8067               (COPY_TO_REGCLASS (MOVSX32rr16 GR16:$src), VR128)), FR32)) >;
8068
8069   def : Pat<(f16_to_fp (i16 (fp_to_f16 FR32:$src))),
8070             (f32 (COPY_TO_REGCLASS (VCVTPH2PSrr
8071               (VCVTPS2PHrr (COPY_TO_REGCLASS FR32:$src, VR128), 4)), FR32)) >;
8072 }
8073
8074 //===----------------------------------------------------------------------===//
8075 // AVX2 Instructions
8076 //===----------------------------------------------------------------------===//
8077
8078 /// AVX2_binop_rmi - AVX2 binary operator with 8-bit immediate
8079 multiclass AVX2_binop_rmi<bits<8> opc, string OpcodeStr, SDNode OpNode,
8080                           ValueType OpVT, RegisterClass RC, PatFrag memop_frag,
8081                           X86MemOperand x86memop> {
8082   let isCommutable = 1 in
8083   def rri : AVX2AIi8<opc, MRMSrcReg, (outs RC:$dst),
8084         (ins RC:$src1, RC:$src2, u8imm:$src3),
8085         !strconcat(OpcodeStr,
8086             "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
8087         [(set RC:$dst, (OpVT (OpNode RC:$src1, RC:$src2, imm:$src3)))]>,
8088         Sched<[WriteBlend]>, VEX_4V;
8089   def rmi : AVX2AIi8<opc, MRMSrcMem, (outs RC:$dst),
8090         (ins RC:$src1, x86memop:$src2, u8imm:$src3),
8091         !strconcat(OpcodeStr,
8092             "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
8093         [(set RC:$dst,
8094           (OpVT (OpNode RC:$src1,
8095            (bitconvert (memop_frag addr:$src2)), imm:$src3)))]>,
8096         Sched<[WriteBlendLd, ReadAfterLd]>, VEX_4V;
8097 }
8098
8099 defm VPBLENDD : AVX2_binop_rmi<0x02, "vpblendd", X86Blendi, v4i32,
8100                                VR128, loadv2i64, i128mem>;
8101 defm VPBLENDDY : AVX2_binop_rmi<0x02, "vpblendd", X86Blendi, v8i32,
8102                                 VR256, loadv4i64, i256mem>, VEX_L;
8103
8104 // For insertion into the zero index (low half) of a 256-bit vector, it is
8105 // more efficient to generate a blend with immediate instead of an insert*128.
8106 let Predicates = [HasAVX2] in {
8107 def : Pat<(insert_subvector (v8i32 VR256:$src1), (v4i32 VR128:$src2), (iPTR 0)),
8108           (VPBLENDDYrri VR256:$src1,
8109                         (INSERT_SUBREG (v8i32 (IMPLICIT_DEF)),
8110                                        VR128:$src2, sub_xmm), 0xf)>;
8111 def : Pat<(insert_subvector (v4i64 VR256:$src1), (v2i64 VR128:$src2), (iPTR 0)),
8112           (VPBLENDDYrri VR256:$src1,
8113                         (INSERT_SUBREG (v8i32 (IMPLICIT_DEF)),
8114                                        VR128:$src2, sub_xmm), 0xf)>;
8115 def : Pat<(insert_subvector (v16i16 VR256:$src1), (v8i16 VR128:$src2), (iPTR 0)),
8116           (VPBLENDDYrri VR256:$src1,
8117                         (INSERT_SUBREG (v8i32 (IMPLICIT_DEF)),
8118                                        VR128:$src2, sub_xmm), 0xf)>;
8119 def : Pat<(insert_subvector (v32i8 VR256:$src1), (v16i8 VR128:$src2), (iPTR 0)),
8120           (VPBLENDDYrri VR256:$src1,
8121                         (INSERT_SUBREG (v8i32 (IMPLICIT_DEF)),
8122                                        VR128:$src2, sub_xmm), 0xf)>;
8123 }
8124
8125 let Predicates = [HasAVX1Only] in {
8126 def : Pat<(insert_subvector (v8i32 VR256:$src1), (v4i32 VR128:$src2), (iPTR 0)),
8127           (VBLENDPSYrri VR256:$src1,
8128                         (INSERT_SUBREG (v8i32 (IMPLICIT_DEF)),
8129                                        VR128:$src2, sub_xmm), 0xf)>;
8130 def : Pat<(insert_subvector (v4i64 VR256:$src1), (v2i64 VR128:$src2), (iPTR 0)),
8131           (VBLENDPSYrri VR256:$src1,
8132                         (INSERT_SUBREG (v8i32 (IMPLICIT_DEF)),
8133                                        VR128:$src2, sub_xmm), 0xf)>;
8134 def : Pat<(insert_subvector (v16i16 VR256:$src1), (v8i16 VR128:$src2), (iPTR 0)),
8135           (VBLENDPSYrri VR256:$src1,
8136                         (INSERT_SUBREG (v8i32 (IMPLICIT_DEF)),
8137                                        VR128:$src2, sub_xmm), 0xf)>;
8138 def : Pat<(insert_subvector (v32i8 VR256:$src1), (v16i8 VR128:$src2), (iPTR 0)),
8139           (VBLENDPSYrri VR256:$src1,
8140                         (INSERT_SUBREG (v8i32 (IMPLICIT_DEF)),
8141                                        VR128:$src2, sub_xmm), 0xf)>;
8142 }
8143
8144 //===----------------------------------------------------------------------===//
8145 // VPBROADCAST - Load from memory and broadcast to all elements of the
8146 //               destination operand
8147 //
8148 multiclass avx2_broadcast<bits<8> opc, string OpcodeStr,
8149                           X86MemOperand x86memop, PatFrag ld_frag,
8150                           ValueType OpVT128, ValueType OpVT256, Predicate prd> {
8151   let Predicates = [HasAVX2, prd] in {
8152     def rr : AVX28I<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
8153                   !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
8154                   [(set VR128:$dst,
8155                    (OpVT128 (X86VBroadcast (OpVT128 VR128:$src))))]>,
8156                   Sched<[WriteShuffle]>, VEX;
8157     def rm : AVX28I<opc, MRMSrcMem, (outs VR128:$dst), (ins x86memop:$src),
8158                   !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
8159                   [(set VR128:$dst,
8160                    (OpVT128 (X86VBroadcast (ld_frag addr:$src))))]>,
8161                   Sched<[WriteLoad]>, VEX;
8162     def Yrr : AVX28I<opc, MRMSrcReg, (outs VR256:$dst), (ins VR128:$src),
8163                    !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
8164                    [(set VR256:$dst,
8165                     (OpVT256 (X86VBroadcast (OpVT128 VR128:$src))))]>,
8166                    Sched<[WriteShuffle256]>, VEX, VEX_L;
8167     def Yrm : AVX28I<opc, MRMSrcMem, (outs VR256:$dst), (ins x86memop:$src),
8168                    !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
8169                    [(set VR256:$dst,
8170                     (OpVT256 (X86VBroadcast (ld_frag addr:$src))))]>,
8171                    Sched<[WriteLoad]>, VEX, VEX_L;
8172
8173     // Provide aliases for broadcast from the same register class that
8174     // automatically does the extract.
8175     def : Pat<(OpVT256 (X86VBroadcast (OpVT256 VR256:$src))),
8176               (!cast<Instruction>(NAME#"Yrr")
8177                   (OpVT128 (EXTRACT_SUBREG (OpVT256 VR256:$src),sub_xmm)))>;
8178   }
8179 }
8180
8181 defm VPBROADCASTB  : avx2_broadcast<0x78, "vpbroadcastb", i8mem, loadi8,
8182                                     v16i8, v32i8, NoVLX_Or_NoBWI>;
8183 defm VPBROADCASTW  : avx2_broadcast<0x79, "vpbroadcastw", i16mem, loadi16,
8184                                     v8i16, v16i16, NoVLX_Or_NoBWI>;
8185 defm VPBROADCASTD  : avx2_broadcast<0x58, "vpbroadcastd", i32mem, loadi32,
8186                                     v4i32, v8i32, NoVLX>;
8187 defm VPBROADCASTQ  : avx2_broadcast<0x59, "vpbroadcastq", i64mem, loadi64,
8188                                     v2i64, v4i64, NoVLX>;
8189
8190 let Predicates = [HasAVX2, NoVLX_Or_NoBWI] in {
8191   // 32-bit targets will fail to load a i64 directly but can use ZEXT_LOAD.
8192   def : Pat<(v2i64 (X86VBroadcast (v2i64 (X86vzload addr:$src)))),
8193             (VPBROADCASTQrm addr:$src)>;
8194   def : Pat<(v4i64 (X86VBroadcast (v4i64 (X86vzload addr:$src)))),
8195             (VPBROADCASTQYrm addr:$src)>;
8196   // loadi16 is tricky to fold, because !isTypeDesirableForOp, justifiably.
8197   // This means we'll encounter truncated i32 loads; match that here.
8198   def : Pat<(v8i16 (X86VBroadcast (i16 (trunc (i32 (load addr:$src)))))),
8199             (VPBROADCASTWrm addr:$src)>;
8200   def : Pat<(v16i16 (X86VBroadcast (i16 (trunc (i32 (load addr:$src)))))),
8201             (VPBROADCASTWYrm addr:$src)>;
8202   def : Pat<(v8i16 (X86VBroadcast
8203               (i16 (trunc (i32 (zextloadi16 addr:$src)))))),
8204             (VPBROADCASTWrm addr:$src)>;
8205   def : Pat<(v16i16 (X86VBroadcast
8206               (i16 (trunc (i32 (zextloadi16 addr:$src)))))),
8207             (VPBROADCASTWYrm addr:$src)>;
8208 }
8209
8210 let Predicates = [HasAVX2, NoVLX] in {
8211   // Provide aliases for broadcast from the same register class that
8212   // automatically does the extract.
8213   def : Pat<(v8f32 (X86VBroadcast (v8f32 VR256:$src))),
8214             (VBROADCASTSSYrr (v4f32 (EXTRACT_SUBREG (v8f32 VR256:$src),
8215                                                     sub_xmm)))>;
8216   def : Pat<(v4f64 (X86VBroadcast (v4f64 VR256:$src))),
8217             (VBROADCASTSDYrr (v2f64 (EXTRACT_SUBREG (v4f64 VR256:$src),
8218                                                     sub_xmm)))>;
8219 }
8220
8221 let Predicates = [HasAVX2, NoVLX] in {
8222   // Provide fallback in case the load node that is used in the patterns above
8223   // is used by additional users, which prevents the pattern selection.
8224     def : Pat<(v4f32 (X86VBroadcast FR32:$src)),
8225               (VBROADCASTSSrr (COPY_TO_REGCLASS FR32:$src, VR128))>;
8226     def : Pat<(v8f32 (X86VBroadcast FR32:$src)),
8227               (VBROADCASTSSYrr (COPY_TO_REGCLASS FR32:$src, VR128))>;
8228     def : Pat<(v4f64 (X86VBroadcast FR64:$src)),
8229               (VBROADCASTSDYrr (COPY_TO_REGCLASS FR64:$src, VR128))>;
8230 }
8231
8232 let Predicates = [HasAVX2, NoVLX_Or_NoBWI] in {
8233   def : Pat<(v16i8 (X86VBroadcast GR8:$src)),
8234         (VPBROADCASTBrr (COPY_TO_REGCLASS
8235                          (i32 (INSERT_SUBREG (i32 (IMPLICIT_DEF)),
8236                                              GR8:$src, sub_8bit)),
8237                          VR128))>;
8238   def : Pat<(v32i8 (X86VBroadcast GR8:$src)),
8239         (VPBROADCASTBYrr (COPY_TO_REGCLASS
8240                           (i32 (INSERT_SUBREG (i32 (IMPLICIT_DEF)),
8241                                               GR8:$src, sub_8bit)),
8242                           VR128))>;
8243
8244   def : Pat<(v8i16 (X86VBroadcast GR16:$src)),
8245         (VPBROADCASTWrr (COPY_TO_REGCLASS
8246                          (i32 (INSERT_SUBREG (i32 (IMPLICIT_DEF)),
8247                                              GR16:$src, sub_16bit)),
8248                          VR128))>;
8249   def : Pat<(v16i16 (X86VBroadcast GR16:$src)),
8250         (VPBROADCASTWYrr (COPY_TO_REGCLASS
8251                           (i32 (INSERT_SUBREG (i32 (IMPLICIT_DEF)),
8252                                               GR16:$src, sub_16bit)),
8253                           VR128))>;
8254 }
8255 let Predicates = [HasAVX2, NoVLX] in {
8256   def : Pat<(v4i32 (X86VBroadcast GR32:$src)),
8257             (VPBROADCASTDrr (COPY_TO_REGCLASS GR32:$src, VR128))>;
8258   def : Pat<(v8i32 (X86VBroadcast GR32:$src)),
8259             (VPBROADCASTDYrr (COPY_TO_REGCLASS GR32:$src, VR128))>;
8260   def : Pat<(v2i64 (X86VBroadcast GR64:$src)),
8261             (VPBROADCASTQrr (COPY_TO_REGCLASS GR64:$src, VR128))>;
8262   def : Pat<(v4i64 (X86VBroadcast GR64:$src)),
8263             (VPBROADCASTQYrr (COPY_TO_REGCLASS GR64:$src, VR128))>;
8264 }
8265
8266 // AVX1 broadcast patterns
8267 let Predicates = [HasAVX1Only] in {
8268 def : Pat<(v8i32 (X86VBroadcast (loadi32 addr:$src))),
8269           (VBROADCASTSSYrm addr:$src)>;
8270 def : Pat<(v4i64 (X86VBroadcast (loadi64 addr:$src))),
8271           (VBROADCASTSDYrm addr:$src)>;
8272 def : Pat<(v4i32 (X86VBroadcast (loadi32 addr:$src))),
8273           (VBROADCASTSSrm addr:$src)>;
8274 }
8275
8276   // Provide fallback in case the load node that is used in the patterns above
8277   // is used by additional users, which prevents the pattern selection.
8278 let Predicates = [HasAVX, NoVLX] in {
8279   // 128bit broadcasts:
8280   def : Pat<(v2f64 (X86VBroadcast f64:$src)),
8281             (VMOVDDUPrr (COPY_TO_REGCLASS FR64:$src, VR128))>;
8282 }
8283
8284 let Predicates = [HasAVX1Only] in {
8285   def : Pat<(v4f32 (X86VBroadcast FR32:$src)),
8286             (VPERMILPSri (COPY_TO_REGCLASS FR32:$src, VR128), 0)>;
8287   def : Pat<(v8f32 (X86VBroadcast FR32:$src)),
8288             (VINSERTF128rr (INSERT_SUBREG (v8f32 (IMPLICIT_DEF)),
8289               (VPERMILPSri (COPY_TO_REGCLASS FR32:$src, VR128), 0), sub_xmm),
8290               (VPERMILPSri (COPY_TO_REGCLASS FR32:$src, VR128), 0), 1)>;
8291   def : Pat<(v4f64 (X86VBroadcast FR64:$src)),
8292             (VINSERTF128rr (INSERT_SUBREG (v4f64 (IMPLICIT_DEF)),
8293               (VMOVDDUPrr (COPY_TO_REGCLASS FR64:$src, VR128)), sub_xmm),
8294               (VMOVDDUPrr (COPY_TO_REGCLASS FR64:$src, VR128)), 1)>;
8295
8296   def : Pat<(v4i32 (X86VBroadcast GR32:$src)),
8297             (VPSHUFDri (COPY_TO_REGCLASS GR32:$src, VR128), 0)>;
8298   def : Pat<(v8i32 (X86VBroadcast GR32:$src)),
8299             (VINSERTF128rr (INSERT_SUBREG (v8i32 (IMPLICIT_DEF)),
8300               (VPSHUFDri (COPY_TO_REGCLASS GR32:$src, VR128), 0), sub_xmm),
8301               (VPSHUFDri (COPY_TO_REGCLASS GR32:$src, VR128), 0), 1)>;
8302   def : Pat<(v4i64 (X86VBroadcast GR64:$src)),
8303             (VINSERTF128rr (INSERT_SUBREG (v4i64 (IMPLICIT_DEF)),
8304               (VPSHUFDri (COPY_TO_REGCLASS GR64:$src, VR128), 0x44), sub_xmm),
8305               (VPSHUFDri (COPY_TO_REGCLASS GR64:$src, VR128), 0x44), 1)>;
8306
8307   def : Pat<(v2i64 (X86VBroadcast i64:$src)),
8308             (VPSHUFDri (COPY_TO_REGCLASS GR64:$src, VR128), 0x44)>;
8309 }
8310
8311 //===----------------------------------------------------------------------===//
8312 // VPERM - Permute instructions
8313 //
8314
8315 multiclass avx2_perm<bits<8> opc, string OpcodeStr, PatFrag mem_frag,
8316                      ValueType OpVT, X86FoldableSchedWrite Sched,
8317                      X86MemOperand memOp> {
8318   let Predicates = [HasAVX2, NoVLX] in {
8319     def Yrr : AVX28I<opc, MRMSrcReg, (outs VR256:$dst),
8320                      (ins VR256:$src1, VR256:$src2),
8321                      !strconcat(OpcodeStr,
8322                          "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8323                      [(set VR256:$dst,
8324                        (OpVT (X86VPermv VR256:$src1, VR256:$src2)))]>,
8325                      Sched<[Sched]>, VEX_4V, VEX_L;
8326     def Yrm : AVX28I<opc, MRMSrcMem, (outs VR256:$dst),
8327                      (ins VR256:$src1, memOp:$src2),
8328                      !strconcat(OpcodeStr,
8329                          "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8330                      [(set VR256:$dst,
8331                        (OpVT (X86VPermv VR256:$src1,
8332                               (bitconvert (mem_frag addr:$src2)))))]>,
8333                      Sched<[Sched.Folded, ReadAfterLd]>, VEX_4V, VEX_L;
8334   }
8335 }
8336
8337 defm VPERMD : avx2_perm<0x36, "vpermd", loadv4i64, v8i32, WriteShuffle256,
8338                         i256mem>;
8339 let ExeDomain = SSEPackedSingle in
8340 defm VPERMPS : avx2_perm<0x16, "vpermps", loadv8f32, v8f32, WriteFShuffle256,
8341                         f256mem>;
8342
8343 multiclass avx2_perm_imm<bits<8> opc, string OpcodeStr, PatFrag mem_frag,
8344                          ValueType OpVT, X86FoldableSchedWrite Sched,
8345                          X86MemOperand memOp> {
8346   let Predicates = [HasAVX2, NoVLX] in {
8347     def Yri : AVX2AIi8<opc, MRMSrcReg, (outs VR256:$dst),
8348                        (ins VR256:$src1, u8imm:$src2),
8349                        !strconcat(OpcodeStr,
8350                            "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8351                        [(set VR256:$dst,
8352                          (OpVT (X86VPermi VR256:$src1, (i8 imm:$src2))))]>,
8353                        Sched<[Sched]>, VEX, VEX_L;
8354     def Ymi : AVX2AIi8<opc, MRMSrcMem, (outs VR256:$dst),
8355                        (ins memOp:$src1, u8imm:$src2),
8356                        !strconcat(OpcodeStr,
8357                            "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8358                        [(set VR256:$dst,
8359                          (OpVT (X86VPermi (mem_frag addr:$src1),
8360                                 (i8 imm:$src2))))]>,
8361                        Sched<[Sched.Folded, ReadAfterLd]>, VEX, VEX_L;
8362   }
8363 }
8364
8365 defm VPERMQ : avx2_perm_imm<0x00, "vpermq", loadv4i64, v4i64,
8366                             WriteShuffle256, i256mem>, VEX_W;
8367 let ExeDomain = SSEPackedDouble in
8368 defm VPERMPD : avx2_perm_imm<0x01, "vpermpd", loadv4f64, v4f64,
8369                              WriteFShuffle256, f256mem>, VEX_W;
8370
8371 //===----------------------------------------------------------------------===//
8372 // VPERM2I128 - Permute Floating-Point Values in 128-bit chunks
8373 //
8374 let isCommutable = 1 in
8375 def VPERM2I128rr : AVX2AIi8<0x46, MRMSrcReg, (outs VR256:$dst),
8376           (ins VR256:$src1, VR256:$src2, u8imm:$src3),
8377           "vperm2i128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
8378           [(set VR256:$dst, (v4i64 (X86VPerm2x128 VR256:$src1, VR256:$src2,
8379                             (i8 imm:$src3))))]>, Sched<[WriteShuffle256]>,
8380           VEX_4V, VEX_L;
8381 def VPERM2I128rm : AVX2AIi8<0x46, MRMSrcMem, (outs VR256:$dst),
8382           (ins VR256:$src1, f256mem:$src2, u8imm:$src3),
8383           "vperm2i128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
8384           [(set VR256:$dst, (X86VPerm2x128 VR256:$src1, (loadv4i64 addr:$src2),
8385                              (i8 imm:$src3)))]>,
8386           Sched<[WriteShuffle256Ld, ReadAfterLd]>, VEX_4V, VEX_L;
8387
8388 let Predicates = [HasAVX2] in {
8389 def : Pat<(v8i32 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
8390           (VPERM2I128rr VR256:$src1, VR256:$src2, imm:$imm)>;
8391 def : Pat<(v32i8 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
8392           (VPERM2I128rr VR256:$src1, VR256:$src2, imm:$imm)>;
8393 def : Pat<(v16i16 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
8394           (VPERM2I128rr VR256:$src1, VR256:$src2, imm:$imm)>;
8395
8396 def : Pat<(v32i8 (X86VPerm2x128 VR256:$src1, (bc_v32i8 (loadv4i64 addr:$src2)),
8397                   (i8 imm:$imm))),
8398           (VPERM2I128rm VR256:$src1, addr:$src2, imm:$imm)>;
8399 def : Pat<(v16i16 (X86VPerm2x128 VR256:$src1,
8400                    (bc_v16i16 (loadv4i64 addr:$src2)), (i8 imm:$imm))),
8401           (VPERM2I128rm VR256:$src1, addr:$src2, imm:$imm)>;
8402 def : Pat<(v8i32 (X86VPerm2x128 VR256:$src1, (bc_v8i32 (loadv4i64 addr:$src2)),
8403                   (i8 imm:$imm))),
8404           (VPERM2I128rm VR256:$src1, addr:$src2, imm:$imm)>;
8405 }
8406
8407
8408 //===----------------------------------------------------------------------===//
8409 // VINSERTI128 - Insert packed integer values
8410 //
8411 let hasSideEffects = 0 in {
8412 def VINSERTI128rr : AVX2AIi8<0x38, MRMSrcReg, (outs VR256:$dst),
8413           (ins VR256:$src1, VR128:$src2, u8imm:$src3),
8414           "vinserti128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
8415           []>, Sched<[WriteShuffle256]>, VEX_4V, VEX_L;
8416 let mayLoad = 1 in
8417 def VINSERTI128rm : AVX2AIi8<0x38, MRMSrcMem, (outs VR256:$dst),
8418           (ins VR256:$src1, i128mem:$src2, u8imm:$src3),
8419           "vinserti128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
8420           []>, Sched<[WriteShuffle256Ld, ReadAfterLd]>, VEX_4V, VEX_L;
8421 }
8422
8423 let Predicates = [HasAVX2, NoVLX] in {
8424   defm : vinsert_lowering<"VINSERTI128", v2i64, v4i64,  loadv2i64>;
8425   defm : vinsert_lowering<"VINSERTI128", v4i32, v8i32,  loadv2i64>;
8426   defm : vinsert_lowering<"VINSERTI128", v8i16, v16i16, loadv2i64>;
8427   defm : vinsert_lowering<"VINSERTI128", v16i8, v32i8,  loadv2i64>;
8428 }
8429
8430 //===----------------------------------------------------------------------===//
8431 // VEXTRACTI128 - Extract packed integer values
8432 //
8433 def VEXTRACTI128rr : AVX2AIi8<0x39, MRMDestReg, (outs VR128:$dst),
8434           (ins VR256:$src1, u8imm:$src2),
8435           "vextracti128\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>,
8436           Sched<[WriteShuffle256]>, VEX, VEX_L;
8437 let hasSideEffects = 0, mayStore = 1 in
8438 def VEXTRACTI128mr : AVX2AIi8<0x39, MRMDestMem, (outs),
8439           (ins i128mem:$dst, VR256:$src1, u8imm:$src2),
8440           "vextracti128\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>,
8441           Sched<[WriteStore]>, VEX, VEX_L;
8442
8443 let Predicates = [HasAVX2, NoVLX] in {
8444   defm : vextract_lowering<"VEXTRACTI128", v4i64,  v2i64>;
8445   defm : vextract_lowering<"VEXTRACTI128", v8i32,  v4i32>;
8446   defm : vextract_lowering<"VEXTRACTI128", v16i16, v8i16>;
8447   defm : vextract_lowering<"VEXTRACTI128", v32i8,  v16i8>;
8448 }
8449
8450 //===----------------------------------------------------------------------===//
8451 // VPMASKMOV - Conditional SIMD Integer Packed Loads and Stores
8452 //
8453 multiclass avx2_pmovmask<string OpcodeStr,
8454                          Intrinsic IntLd128, Intrinsic IntLd256,
8455                          Intrinsic IntSt128, Intrinsic IntSt256> {
8456   def rm  : AVX28I<0x8c, MRMSrcMem, (outs VR128:$dst),
8457              (ins VR128:$src1, i128mem:$src2),
8458              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8459              [(set VR128:$dst, (IntLd128 addr:$src2, VR128:$src1))]>, VEX_4V;
8460   def Yrm : AVX28I<0x8c, MRMSrcMem, (outs VR256:$dst),
8461              (ins VR256:$src1, i256mem:$src2),
8462              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8463              [(set VR256:$dst, (IntLd256 addr:$src2, VR256:$src1))]>,
8464              VEX_4V, VEX_L;
8465   def mr  : AVX28I<0x8e, MRMDestMem, (outs),
8466              (ins i128mem:$dst, VR128:$src1, VR128:$src2),
8467              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8468              [(IntSt128 addr:$dst, VR128:$src1, VR128:$src2)]>, VEX_4V;
8469   def Ymr : AVX28I<0x8e, MRMDestMem, (outs),
8470              (ins i256mem:$dst, VR256:$src1, VR256:$src2),
8471              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8472              [(IntSt256 addr:$dst, VR256:$src1, VR256:$src2)]>, VEX_4V, VEX_L;
8473 }
8474
8475 defm VPMASKMOVD : avx2_pmovmask<"vpmaskmovd",
8476                                 int_x86_avx2_maskload_d,
8477                                 int_x86_avx2_maskload_d_256,
8478                                 int_x86_avx2_maskstore_d,
8479                                 int_x86_avx2_maskstore_d_256>;
8480 defm VPMASKMOVQ : avx2_pmovmask<"vpmaskmovq",
8481                                 int_x86_avx2_maskload_q,
8482                                 int_x86_avx2_maskload_q_256,
8483                                 int_x86_avx2_maskstore_q,
8484                                 int_x86_avx2_maskstore_q_256>, VEX_W;
8485
8486 multiclass maskmov_lowering<string InstrStr, RegisterClass RC, ValueType VT,
8487                           ValueType MaskVT, string BlendStr, ValueType ZeroVT> {
8488     // masked store
8489     def: Pat<(X86mstore addr:$ptr, (MaskVT RC:$mask), (VT RC:$src)),
8490              (!cast<Instruction>(InstrStr#"mr") addr:$ptr, RC:$mask, RC:$src)>;
8491     // masked load
8492     def: Pat<(VT (X86mload addr:$ptr, (MaskVT RC:$mask), undef)),
8493              (!cast<Instruction>(InstrStr#"rm") RC:$mask, addr:$ptr)>;
8494     def: Pat<(VT (X86mload addr:$ptr, (MaskVT RC:$mask),
8495                               (VT (bitconvert (ZeroVT immAllZerosV))))),
8496              (!cast<Instruction>(InstrStr#"rm") RC:$mask, addr:$ptr)>;
8497     def: Pat<(VT (X86mload addr:$ptr, (MaskVT RC:$mask), (VT RC:$src0))),
8498              (!cast<Instruction>(BlendStr#"rr")
8499                  RC:$src0,
8500                  (!cast<Instruction>(InstrStr#"rm") RC:$mask, addr:$ptr),
8501                  RC:$mask)>;
8502 }
8503 let Predicates = [HasAVX] in {
8504   defm : maskmov_lowering<"VMASKMOVPS", VR128, v4f32, v4i32, "VBLENDVPS", v4i32>;
8505   defm : maskmov_lowering<"VMASKMOVPD", VR128, v2f64, v2i64, "VBLENDVPD", v4i32>;
8506   defm : maskmov_lowering<"VMASKMOVPSY", VR256, v8f32, v8i32, "VBLENDVPSY", v8i32>;
8507   defm : maskmov_lowering<"VMASKMOVPDY", VR256, v4f64, v4i64, "VBLENDVPDY", v8i32>;
8508 }
8509 let Predicates = [HasAVX1Only] in {
8510   // load/store i32/i64 not supported use ps/pd version
8511   defm : maskmov_lowering<"VMASKMOVPSY", VR256, v8i32, v8i32, "VBLENDVPSY", v8i32>;
8512   defm : maskmov_lowering<"VMASKMOVPDY", VR256, v4i64, v4i64, "VBLENDVPDY", v8i32>;
8513   defm : maskmov_lowering<"VMASKMOVPS", VR128, v4i32, v4i32, "VBLENDVPS", v4i32>;
8514   defm : maskmov_lowering<"VMASKMOVPD", VR128, v2i64, v2i64, "VBLENDVPD", v4i32>;
8515 }
8516 let Predicates = [HasAVX2] in {
8517   defm : maskmov_lowering<"VPMASKMOVDY", VR256, v8i32, v8i32, "VBLENDVPSY", v8i32>;
8518   defm : maskmov_lowering<"VPMASKMOVQY", VR256, v4i64, v4i64, "VBLENDVPDY", v8i32>;
8519   defm : maskmov_lowering<"VPMASKMOVD", VR128, v4i32, v4i32, "VBLENDVPS", v4i32>;
8520   defm : maskmov_lowering<"VPMASKMOVQ", VR128, v2i64, v2i64, "VBLENDVPD", v4i32>;
8521 }
8522
8523 //===----------------------------------------------------------------------===//
8524 // SubVector Broadcasts
8525 // Provide fallback in case the load node that is used in the patterns above
8526 // is used by additional users, which prevents the pattern selection.
8527
8528 let Predicates = [HasAVX2, NoVLX] in {
8529 def : Pat<(v4i64 (X86SubVBroadcast (v2i64 VR128:$src))),
8530           (VINSERTI128rr (INSERT_SUBREG (v4i64 (IMPLICIT_DEF)), VR128:$src, sub_xmm),
8531                          (v2i64 VR128:$src), 1)>;
8532 def : Pat<(v8i32 (X86SubVBroadcast (v4i32 VR128:$src))),
8533           (VINSERTI128rr (INSERT_SUBREG (v8i32 (IMPLICIT_DEF)), VR128:$src, sub_xmm),
8534                          (v4i32 VR128:$src), 1)>;
8535 def : Pat<(v16i16 (X86SubVBroadcast (v8i16 VR128:$src))),
8536           (VINSERTI128rr (INSERT_SUBREG (v16i16 (IMPLICIT_DEF)), VR128:$src, sub_xmm),
8537                          (v8i16 VR128:$src), 1)>;
8538 def : Pat<(v32i8 (X86SubVBroadcast (v16i8 VR128:$src))),
8539           (VINSERTI128rr (INSERT_SUBREG (v32i8 (IMPLICIT_DEF)), VR128:$src, sub_xmm),
8540                          (v16i8 VR128:$src), 1)>;
8541 }
8542
8543 let Predicates = [HasAVX, NoVLX] in {
8544 def : Pat<(v4f64 (X86SubVBroadcast (v2f64 VR128:$src))),
8545           (VINSERTF128rr (INSERT_SUBREG (v4f64 (IMPLICIT_DEF)), VR128:$src, sub_xmm),
8546                          (v2f64 VR128:$src), 1)>;
8547 def : Pat<(v8f32 (X86SubVBroadcast (v4f32 VR128:$src))),
8548           (VINSERTF128rr (INSERT_SUBREG (v8f32 (IMPLICIT_DEF)), VR128:$src, sub_xmm),
8549                          (v4f32 VR128:$src), 1)>;
8550 }
8551
8552 let Predicates = [HasAVX1Only] in {
8553 def : Pat<(v4i64 (X86SubVBroadcast (v2i64 VR128:$src))),
8554           (VINSERTF128rr (INSERT_SUBREG (v4i64 (IMPLICIT_DEF)), VR128:$src, sub_xmm),
8555                          (v2i64 VR128:$src), 1)>;
8556 def : Pat<(v8i32 (X86SubVBroadcast (v4i32 VR128:$src))),
8557           (VINSERTF128rr (INSERT_SUBREG (v8i32 (IMPLICIT_DEF)), VR128:$src, sub_xmm),
8558                          (v4i32 VR128:$src), 1)>;
8559 def : Pat<(v16i16 (X86SubVBroadcast (v8i16 VR128:$src))),
8560           (VINSERTF128rr (INSERT_SUBREG (v16i16 (IMPLICIT_DEF)), VR128:$src, sub_xmm),
8561                          (v8i16 VR128:$src), 1)>;
8562 def : Pat<(v32i8 (X86SubVBroadcast (v16i8 VR128:$src))),
8563           (VINSERTF128rr (INSERT_SUBREG (v32i8 (IMPLICIT_DEF)), VR128:$src, sub_xmm),
8564                          (v16i8 VR128:$src), 1)>;
8565 }
8566
8567 //===----------------------------------------------------------------------===//
8568 // Variable Bit Shifts
8569 //
8570 multiclass avx2_var_shift<bits<8> opc, string OpcodeStr, SDNode OpNode,
8571                           ValueType vt128, ValueType vt256> {
8572   def rr  : AVX28I<opc, MRMSrcReg, (outs VR128:$dst),
8573              (ins VR128:$src1, VR128:$src2),
8574              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8575              [(set VR128:$dst,
8576                (vt128 (OpNode VR128:$src1, (vt128 VR128:$src2))))]>,
8577              VEX_4V, Sched<[WriteVarVecShift]>;
8578   def rm  : AVX28I<opc, MRMSrcMem, (outs VR128:$dst),
8579              (ins VR128:$src1, i128mem:$src2),
8580              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8581              [(set VR128:$dst,
8582                (vt128 (OpNode VR128:$src1,
8583                        (vt128 (bitconvert (loadv2i64 addr:$src2))))))]>,
8584              VEX_4V, Sched<[WriteVarVecShiftLd, ReadAfterLd]>;
8585   def Yrr : AVX28I<opc, MRMSrcReg, (outs VR256:$dst),
8586              (ins VR256:$src1, VR256:$src2),
8587              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8588              [(set VR256:$dst,
8589                (vt256 (OpNode VR256:$src1, (vt256 VR256:$src2))))]>,
8590              VEX_4V, VEX_L, Sched<[WriteVarVecShift]>;
8591   def Yrm : AVX28I<opc, MRMSrcMem, (outs VR256:$dst),
8592              (ins VR256:$src1, i256mem:$src2),
8593              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8594              [(set VR256:$dst,
8595                (vt256 (OpNode VR256:$src1,
8596                        (vt256 (bitconvert (loadv4i64 addr:$src2))))))]>,
8597              VEX_4V, VEX_L, Sched<[WriteVarVecShiftLd, ReadAfterLd]>;
8598 }
8599
8600 let Predicates = [HasAVX2, NoVLX] in {
8601   defm VPSLLVD : avx2_var_shift<0x47, "vpsllvd", shl, v4i32, v8i32>;
8602   defm VPSLLVQ : avx2_var_shift<0x47, "vpsllvq", shl, v2i64, v4i64>, VEX_W;
8603   defm VPSRLVD : avx2_var_shift<0x45, "vpsrlvd", srl, v4i32, v8i32>;
8604   defm VPSRLVQ : avx2_var_shift<0x45, "vpsrlvq", srl, v2i64, v4i64>, VEX_W;
8605   defm VPSRAVD : avx2_var_shift<0x46, "vpsravd", sra, v4i32, v8i32>;
8606
8607   def : Pat<(v4i32 (X86vsrav VR128:$src1, VR128:$src2)),
8608             (VPSRAVDrr VR128:$src1, VR128:$src2)>;
8609   def : Pat<(v4i32 (X86vsrav VR128:$src1,
8610                     (bitconvert (loadv2i64 addr:$src2)))),
8611             (VPSRAVDrm VR128:$src1, addr:$src2)>;
8612   def : Pat<(v8i32 (X86vsrav VR256:$src1, VR256:$src2)),
8613             (VPSRAVDYrr VR256:$src1, VR256:$src2)>;
8614   def : Pat<(v8i32 (X86vsrav VR256:$src1,
8615                     (bitconvert (loadv4i64 addr:$src2)))),
8616             (VPSRAVDYrm VR256:$src1, addr:$src2)>;
8617 }
8618
8619
8620
8621 //===----------------------------------------------------------------------===//
8622 // VGATHER - GATHER Operations
8623 multiclass avx2_gather<bits<8> opc, string OpcodeStr, RegisterClass RC256,
8624                        X86MemOperand memop128, X86MemOperand memop256> {
8625   def rm  : AVX28I<opc, MRMSrcMem4VOp3, (outs VR128:$dst, VR128:$mask_wb),
8626             (ins VR128:$src1, memop128:$src2, VR128:$mask),
8627             !strconcat(OpcodeStr,
8628               "\t{$mask, $src2, $dst|$dst, $src2, $mask}"),
8629             []>, VEX;
8630   def Yrm : AVX28I<opc, MRMSrcMem4VOp3, (outs RC256:$dst, RC256:$mask_wb),
8631             (ins RC256:$src1, memop256:$src2, RC256:$mask),
8632             !strconcat(OpcodeStr,
8633               "\t{$mask, $src2, $dst|$dst, $src2, $mask}"),
8634             []>, VEX, VEX_L;
8635 }
8636
8637 let mayLoad = 1, hasSideEffects = 0, Constraints
8638   = "@earlyclobber $dst,@earlyclobber $mask_wb, $src1 = $dst, $mask = $mask_wb"
8639   in {
8640   defm VPGATHERDQ : avx2_gather<0x90, "vpgatherdq", VR256, vx128mem, vx256mem>, VEX_W;
8641   defm VPGATHERQQ : avx2_gather<0x91, "vpgatherqq", VR256, vx128mem, vy256mem>, VEX_W;
8642   defm VPGATHERDD : avx2_gather<0x90, "vpgatherdd", VR256, vx128mem, vy256mem>;
8643   defm VPGATHERQD : avx2_gather<0x91, "vpgatherqd", VR128, vx64mem, vy128mem>;
8644
8645   let ExeDomain = SSEPackedDouble in {
8646     defm VGATHERDPD : avx2_gather<0x92, "vgatherdpd", VR256, vx128mem, vx256mem>, VEX_W;
8647     defm VGATHERQPD : avx2_gather<0x93, "vgatherqpd", VR256, vx128mem, vy256mem>, VEX_W;
8648   }
8649
8650   let ExeDomain = SSEPackedSingle in {
8651     defm VGATHERDPS : avx2_gather<0x92, "vgatherdps", VR256, vx128mem, vy256mem>;
8652     defm VGATHERQPS : avx2_gather<0x93, "vgatherqps", VR128, vx64mem, vy128mem>;
8653   }
8654 }
8655
8656 //===----------------------------------------------------------------------===//
8657 // Extra selection patterns for FR128, f128, f128mem
8658
8659 // movaps is shorter than movdqa. movaps is in SSE and movdqa is in SSE2.
8660 def : Pat<(store (f128 FR128:$src), addr:$dst),
8661           (MOVAPSmr addr:$dst, (COPY_TO_REGCLASS (f128 FR128:$src), VR128))>;
8662
8663 def : Pat<(loadf128 addr:$src),
8664           (COPY_TO_REGCLASS (MOVAPSrm addr:$src), FR128)>;
8665
8666 // andps is shorter than andpd or pand. andps is SSE and andpd/pand are in SSE2
8667 def : Pat<(X86fand FR128:$src1, (loadf128 addr:$src2)),
8668           (COPY_TO_REGCLASS
8669            (ANDPSrm (COPY_TO_REGCLASS FR128:$src1, VR128), f128mem:$src2),
8670            FR128)>;
8671
8672 def : Pat<(X86fand FR128:$src1, FR128:$src2),
8673           (COPY_TO_REGCLASS
8674            (ANDPSrr (COPY_TO_REGCLASS FR128:$src1, VR128),
8675                     (COPY_TO_REGCLASS FR128:$src2, VR128)), FR128)>;
8676
8677 def : Pat<(and FR128:$src1, FR128:$src2),
8678           (COPY_TO_REGCLASS
8679            (ANDPSrr (COPY_TO_REGCLASS FR128:$src1, VR128),
8680                     (COPY_TO_REGCLASS FR128:$src2, VR128)), FR128)>;
8681
8682 def : Pat<(X86for FR128:$src1, (loadf128 addr:$src2)),
8683           (COPY_TO_REGCLASS
8684            (ORPSrm (COPY_TO_REGCLASS FR128:$src1, VR128), f128mem:$src2),
8685            FR128)>;
8686
8687 def : Pat<(X86for FR128:$src1, FR128:$src2),
8688           (COPY_TO_REGCLASS
8689            (ORPSrr (COPY_TO_REGCLASS FR128:$src1, VR128),
8690                    (COPY_TO_REGCLASS FR128:$src2, VR128)), FR128)>;
8691
8692 def : Pat<(or FR128:$src1, FR128:$src2),
8693           (COPY_TO_REGCLASS
8694            (ORPSrr (COPY_TO_REGCLASS FR128:$src1, VR128),
8695                    (COPY_TO_REGCLASS FR128:$src2, VR128)), FR128)>;
8696
8697 def : Pat<(X86fxor FR128:$src1, (loadf128 addr:$src2)),
8698           (COPY_TO_REGCLASS
8699            (XORPSrm (COPY_TO_REGCLASS FR128:$src1, VR128), f128mem:$src2),
8700            FR128)>;
8701
8702 def : Pat<(X86fxor FR128:$src1, FR128:$src2),
8703           (COPY_TO_REGCLASS
8704            (XORPSrr (COPY_TO_REGCLASS FR128:$src1, VR128),
8705                     (COPY_TO_REGCLASS FR128:$src2, VR128)), FR128)>;
8706
8707 def : Pat<(xor FR128:$src1, FR128:$src2),
8708           (COPY_TO_REGCLASS
8709            (XORPSrr (COPY_TO_REGCLASS FR128:$src1, VR128),
8710                     (COPY_TO_REGCLASS FR128:$src2, VR128)), FR128)>;