[x86] Teach the new vector shuffle lowering to aggressively form MOVSS
[oota-llvm.git] / lib / Target / X86 / X86InstrSSE.td
1 //===-- X86InstrSSE.td - SSE Instruction Set ---------------*- tablegen -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file describes the X86 SSE instruction set, defining the instructions,
11 // and properties of the instructions which are needed for code generation,
12 // machine code emission, and analysis.
13 //
14 //===----------------------------------------------------------------------===//
15
16 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
37 // scalar
38 let Sched = WriteFAdd in {
39 def SSE_ALU_F32S : OpndItins<
40   IIC_SSE_ALU_F32S_RR, IIC_SSE_ALU_F32S_RM
41 >;
42
43 def SSE_ALU_F64S : OpndItins<
44   IIC_SSE_ALU_F64S_RR, IIC_SSE_ALU_F64S_RM
45 >;
46 }
47
48 def SSE_ALU_ITINS_S : SizeItins<
49   SSE_ALU_F32S, SSE_ALU_F64S
50 >;
51
52 let Sched = WriteFMul in {
53 def SSE_MUL_F32S : OpndItins<
54   IIC_SSE_MUL_F32S_RR, IIC_SSE_MUL_F64S_RM
55 >;
56
57 def SSE_MUL_F64S : OpndItins<
58   IIC_SSE_MUL_F64S_RR, IIC_SSE_MUL_F64S_RM
59 >;
60 }
61
62 def SSE_MUL_ITINS_S : SizeItins<
63   SSE_MUL_F32S, SSE_MUL_F64S
64 >;
65
66 let Sched = WriteFDiv in {
67 def SSE_DIV_F32S : OpndItins<
68   IIC_SSE_DIV_F32S_RR, IIC_SSE_DIV_F64S_RM
69 >;
70
71 def SSE_DIV_F64S : OpndItins<
72   IIC_SSE_DIV_F64S_RR, IIC_SSE_DIV_F64S_RM
73 >;
74 }
75
76 def SSE_DIV_ITINS_S : SizeItins<
77   SSE_DIV_F32S, SSE_DIV_F64S
78 >;
79
80 // parallel
81 let Sched = WriteFAdd in {
82 def SSE_ALU_F32P : OpndItins<
83   IIC_SSE_ALU_F32P_RR, IIC_SSE_ALU_F32P_RM
84 >;
85
86 def SSE_ALU_F64P : OpndItins<
87   IIC_SSE_ALU_F64P_RR, IIC_SSE_ALU_F64P_RM
88 >;
89 }
90
91 def SSE_ALU_ITINS_P : SizeItins<
92   SSE_ALU_F32P, SSE_ALU_F64P
93 >;
94
95 let Sched = WriteFMul in {
96 def SSE_MUL_F32P : OpndItins<
97   IIC_SSE_MUL_F32P_RR, IIC_SSE_MUL_F64P_RM
98 >;
99
100 def SSE_MUL_F64P : OpndItins<
101   IIC_SSE_MUL_F64P_RR, IIC_SSE_MUL_F64P_RM
102 >;
103 }
104
105 def SSE_MUL_ITINS_P : SizeItins<
106   SSE_MUL_F32P, SSE_MUL_F64P
107 >;
108
109 let Sched = WriteFDiv in {
110 def SSE_DIV_F32P : OpndItins<
111   IIC_SSE_DIV_F32P_RR, IIC_SSE_DIV_F64P_RM
112 >;
113
114 def SSE_DIV_F64P : OpndItins<
115   IIC_SSE_DIV_F64P_RR, IIC_SSE_DIV_F64P_RM
116 >;
117 }
118
119 def SSE_DIV_ITINS_P : SizeItins<
120   SSE_DIV_F32P, SSE_DIV_F64P
121 >;
122
123 let Sched = WriteVecLogic in
124 def SSE_VEC_BIT_ITINS_P : OpndItins<
125   IIC_SSE_BIT_P_RR, IIC_SSE_BIT_P_RM
126 >;
127
128 def SSE_BIT_ITINS_P : OpndItins<
129   IIC_SSE_BIT_P_RR, IIC_SSE_BIT_P_RM
130 >;
131
132 let Sched = WriteVecALU in {
133 def SSE_INTALU_ITINS_P : OpndItins<
134   IIC_SSE_INTALU_P_RR, IIC_SSE_INTALU_P_RM
135 >;
136
137 def SSE_INTALUQ_ITINS_P : OpndItins<
138   IIC_SSE_INTALUQ_P_RR, IIC_SSE_INTALUQ_P_RM
139 >;
140 }
141
142 let Sched = WriteVecIMul in
143 def SSE_INTMUL_ITINS_P : OpndItins<
144   IIC_SSE_INTMUL_P_RR, IIC_SSE_INTMUL_P_RM
145 >;
146
147 def SSE_INTSHIFT_ITINS_P : ShiftOpndItins<
148   IIC_SSE_INTSH_P_RR, IIC_SSE_INTSH_P_RM, IIC_SSE_INTSH_P_RI
149 >;
150
151 def SSE_MOVA_ITINS : OpndItins<
152   IIC_SSE_MOVA_P_RR, IIC_SSE_MOVA_P_RM
153 >;
154
155 def SSE_MOVU_ITINS : OpndItins<
156   IIC_SSE_MOVU_P_RR, IIC_SSE_MOVU_P_RM
157 >;
158
159 def SSE_DPPD_ITINS : OpndItins<
160   IIC_SSE_DPPD_RR, IIC_SSE_DPPD_RM
161 >;
162
163 def SSE_DPPS_ITINS : OpndItins<
164   IIC_SSE_DPPS_RR, IIC_SSE_DPPD_RM
165 >;
166
167 def DEFAULT_ITINS : OpndItins<
168   IIC_ALU_NONMEM, IIC_ALU_MEM
169 >;
170
171 def SSE_EXTRACT_ITINS : OpndItins<
172   IIC_SSE_EXTRACTPS_RR, IIC_SSE_EXTRACTPS_RM
173 >;
174
175 def SSE_INSERT_ITINS : OpndItins<
176   IIC_SSE_INSERTPS_RR, IIC_SSE_INSERTPS_RM
177 >;
178
179 let Sched = WriteMPSAD in
180 def SSE_MPSADBW_ITINS : OpndItins<
181   IIC_SSE_MPSADBW_RR, IIC_SSE_MPSADBW_RM
182 >;
183
184 let Sched = WriteVecIMul in
185 def SSE_PMULLD_ITINS : OpndItins<
186   IIC_SSE_PMULLD_RR, IIC_SSE_PMULLD_RM
187 >;
188
189 // Definitions for backward compatibility.
190 // The instructions mapped on these definitions uses a different itinerary
191 // than the actual scheduling model.
192 let Sched = WriteShuffle in
193 def DEFAULT_ITINS_SHUFFLESCHED :  OpndItins<
194   IIC_ALU_NONMEM, IIC_ALU_MEM
195 >;
196
197 let Sched = WriteVecIMul in
198 def DEFAULT_ITINS_VECIMULSCHED :  OpndItins<
199   IIC_ALU_NONMEM, IIC_ALU_MEM
200 >;
201
202 let Sched = WriteShuffle in
203 def SSE_INTALU_ITINS_SHUFF_P : OpndItins<
204   IIC_SSE_INTALU_P_RR, IIC_SSE_INTALU_P_RM
205 >;
206
207 let Sched = WriteMPSAD in
208 def DEFAULT_ITINS_MPSADSCHED :  OpndItins<
209   IIC_ALU_NONMEM, IIC_ALU_MEM
210 >;
211
212 let Sched = WriteFBlend in
213 def DEFAULT_ITINS_FBLENDSCHED :  OpndItins<
214   IIC_ALU_NONMEM, IIC_ALU_MEM
215 >;
216
217 let Sched = WriteBlend in
218 def DEFAULT_ITINS_BLENDSCHED :  OpndItins<
219   IIC_ALU_NONMEM, IIC_ALU_MEM
220 >;
221
222 let Sched = WriteVarBlend in
223 def DEFAULT_ITINS_VARBLENDSCHED :  OpndItins<
224   IIC_ALU_NONMEM, IIC_ALU_MEM
225 >;
226
227 let Sched = WriteFBlend in
228 def SSE_INTALU_ITINS_FBLEND_P : OpndItins<
229   IIC_SSE_INTALU_P_RR, IIC_SSE_INTALU_P_RM
230 >;
231
232 let Sched = WriteBlend in
233 def SSE_INTALU_ITINS_BLEND_P : OpndItins<
234   IIC_SSE_INTALU_P_RR, IIC_SSE_INTALU_P_RM
235 >;
236
237 //===----------------------------------------------------------------------===//
238 // SSE 1 & 2 Instructions Classes
239 //===----------------------------------------------------------------------===//
240
241 /// sse12_fp_scalar - SSE 1 & 2 scalar instructions class
242 multiclass sse12_fp_scalar<bits<8> opc, string OpcodeStr, SDNode OpNode,
243                            RegisterClass RC, X86MemOperand x86memop,
244                            OpndItins itins,
245                            bit Is2Addr = 1> {
246   let isCommutable = 1 in {
247     def rr : SI<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
248        !if(Is2Addr,
249            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
250            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
251        [(set RC:$dst, (OpNode RC:$src1, RC:$src2))], itins.rr>,
252        Sched<[itins.Sched]>;
253   }
254   def rm : SI<opc, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
255        !if(Is2Addr,
256            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
257            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
258        [(set RC:$dst, (OpNode RC:$src1, (load addr:$src2)))], itins.rm>,
259        Sched<[itins.Sched.Folded, ReadAfterLd]>;
260 }
261
262 /// sse12_fp_scalar_int - SSE 1 & 2 scalar instructions intrinsics class
263 multiclass sse12_fp_scalar_int<bits<8> opc, string OpcodeStr, RegisterClass RC,
264                              string asm, string SSEVer, string FPSizeStr,
265                              Operand memopr, ComplexPattern mem_cpat,
266                              OpndItins itins,
267                              bit Is2Addr = 1> {
268 let isCodeGenOnly = 1 in {
269   def rr_Int : SI<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
270        !if(Is2Addr,
271            !strconcat(asm, "\t{$src2, $dst|$dst, $src2}"),
272            !strconcat(asm, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
273        [(set RC:$dst, (!cast<Intrinsic>(
274                  !strconcat("int_x86_sse", SSEVer, "_", OpcodeStr, FPSizeStr))
275              RC:$src1, RC:$src2))], itins.rr>,
276        Sched<[itins.Sched]>;
277   def rm_Int : SI<opc, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, memopr:$src2),
278        !if(Is2Addr,
279            !strconcat(asm, "\t{$src2, $dst|$dst, $src2}"),
280            !strconcat(asm, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
281        [(set RC:$dst, (!cast<Intrinsic>(!strconcat("int_x86_sse",
282                                           SSEVer, "_", OpcodeStr, FPSizeStr))
283              RC:$src1, mem_cpat:$src2))], itins.rm>,
284        Sched<[itins.Sched.Folded, ReadAfterLd]>;
285 }
286 }
287
288 /// sse12_fp_packed - SSE 1 & 2 packed instructions class
289 multiclass sse12_fp_packed<bits<8> opc, string OpcodeStr, SDNode OpNode,
290                            RegisterClass RC, ValueType vt,
291                            X86MemOperand x86memop, PatFrag mem_frag,
292                            Domain d, OpndItins itins, bit Is2Addr = 1> {
293   let isCommutable = 1 in
294     def rr : PI<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
295        !if(Is2Addr,
296            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
297            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
298        [(set RC:$dst, (vt (OpNode RC:$src1, RC:$src2)))], itins.rr, d>,
299        Sched<[itins.Sched]>;
300   let mayLoad = 1 in
301     def rm : PI<opc, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
302        !if(Is2Addr,
303            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
304            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
305        [(set RC:$dst, (OpNode RC:$src1, (mem_frag addr:$src2)))],
306           itins.rm, d>,
307        Sched<[itins.Sched.Folded, ReadAfterLd]>;
308 }
309
310 /// sse12_fp_packed_logical_rm - SSE 1 & 2 packed instructions class
311 multiclass sse12_fp_packed_logical_rm<bits<8> opc, RegisterClass RC, Domain d,
312                                       string OpcodeStr, X86MemOperand x86memop,
313                                       list<dag> pat_rr, list<dag> pat_rm,
314                                       bit Is2Addr = 1> {
315   let isCommutable = 1, hasSideEffects = 0 in
316     def rr : PI<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
317        !if(Is2Addr,
318            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
319            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
320        pat_rr, NoItinerary, d>,
321        Sched<[WriteVecLogic]>;
322   def rm : PI<opc, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
323        !if(Is2Addr,
324            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
325            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
326        pat_rm, NoItinerary, d>,
327        Sched<[WriteVecLogicLd, ReadAfterLd]>;
328 }
329
330 //===----------------------------------------------------------------------===//
331 //  Non-instruction patterns
332 //===----------------------------------------------------------------------===//
333
334 // A vector extract of the first f32/f64 position is a subregister copy
335 def : Pat<(f32 (vector_extract (v4f32 VR128:$src), (iPTR 0))),
336           (COPY_TO_REGCLASS (v4f32 VR128:$src), FR32)>;
337 def : Pat<(f64 (vector_extract (v2f64 VR128:$src), (iPTR 0))),
338           (COPY_TO_REGCLASS (v2f64 VR128:$src), FR64)>;
339
340 // A 128-bit subvector extract from the first 256-bit vector position
341 // is a subregister copy that needs no instruction.
342 def : Pat<(v4i32 (extract_subvector (v8i32 VR256:$src), (iPTR 0))),
343           (v4i32 (EXTRACT_SUBREG (v8i32 VR256:$src), sub_xmm))>;
344 def : Pat<(v4f32 (extract_subvector (v8f32 VR256:$src), (iPTR 0))),
345           (v4f32 (EXTRACT_SUBREG (v8f32 VR256:$src), sub_xmm))>;
346
347 def : Pat<(v2i64 (extract_subvector (v4i64 VR256:$src), (iPTR 0))),
348           (v2i64 (EXTRACT_SUBREG (v4i64 VR256:$src), sub_xmm))>;
349 def : Pat<(v2f64 (extract_subvector (v4f64 VR256:$src), (iPTR 0))),
350           (v2f64 (EXTRACT_SUBREG (v4f64 VR256:$src), sub_xmm))>;
351
352 def : Pat<(v8i16 (extract_subvector (v16i16 VR256:$src), (iPTR 0))),
353           (v8i16 (EXTRACT_SUBREG (v16i16 VR256:$src), sub_xmm))>;
354 def : Pat<(v16i8 (extract_subvector (v32i8 VR256:$src), (iPTR 0))),
355           (v16i8 (EXTRACT_SUBREG (v32i8 VR256:$src), sub_xmm))>;
356
357 // A 128-bit subvector insert to the first 256-bit vector position
358 // is a subregister copy that needs no instruction.
359 let AddedComplexity = 25 in { // to give priority over vinsertf128rm
360 def : Pat<(insert_subvector undef, (v2i64 VR128:$src), (iPTR 0)),
361           (INSERT_SUBREG (v4i64 (IMPLICIT_DEF)), VR128:$src, sub_xmm)>;
362 def : Pat<(insert_subvector undef, (v2f64 VR128:$src), (iPTR 0)),
363           (INSERT_SUBREG (v4f64 (IMPLICIT_DEF)), VR128:$src, sub_xmm)>;
364 def : Pat<(insert_subvector undef, (v4i32 VR128:$src), (iPTR 0)),
365           (INSERT_SUBREG (v8i32 (IMPLICIT_DEF)), VR128:$src, sub_xmm)>;
366 def : Pat<(insert_subvector undef, (v4f32 VR128:$src), (iPTR 0)),
367           (INSERT_SUBREG (v8f32 (IMPLICIT_DEF)), VR128:$src, sub_xmm)>;
368 def : Pat<(insert_subvector undef, (v8i16 VR128:$src), (iPTR 0)),
369           (INSERT_SUBREG (v16i16 (IMPLICIT_DEF)), VR128:$src, sub_xmm)>;
370 def : Pat<(insert_subvector undef, (v16i8 VR128:$src), (iPTR 0)),
371           (INSERT_SUBREG (v32i8 (IMPLICIT_DEF)), VR128:$src, sub_xmm)>;
372 }
373
374 // Implicitly promote a 32-bit scalar to a vector.
375 def : Pat<(v4f32 (scalar_to_vector FR32:$src)),
376           (COPY_TO_REGCLASS FR32:$src, VR128)>;
377 def : Pat<(v8f32 (scalar_to_vector FR32:$src)),
378           (COPY_TO_REGCLASS FR32:$src, VR128)>;
379 // Implicitly promote a 64-bit scalar to a vector.
380 def : Pat<(v2f64 (scalar_to_vector FR64:$src)),
381           (COPY_TO_REGCLASS FR64:$src, VR128)>;
382 def : Pat<(v4f64 (scalar_to_vector FR64:$src)),
383           (COPY_TO_REGCLASS FR64:$src, VR128)>;
384
385 // Bitcasts between 128-bit vector types. Return the original type since
386 // no instruction is needed for the conversion
387 let Predicates = [HasSSE2] in {
388   def : Pat<(v2i64 (bitconvert (v4i32 VR128:$src))), (v2i64 VR128:$src)>;
389   def : Pat<(v2i64 (bitconvert (v8i16 VR128:$src))), (v2i64 VR128:$src)>;
390   def : Pat<(v2i64 (bitconvert (v16i8 VR128:$src))), (v2i64 VR128:$src)>;
391   def : Pat<(v2i64 (bitconvert (v2f64 VR128:$src))), (v2i64 VR128:$src)>;
392   def : Pat<(v2i64 (bitconvert (v4f32 VR128:$src))), (v2i64 VR128:$src)>;
393   def : Pat<(v4i32 (bitconvert (v2i64 VR128:$src))), (v4i32 VR128:$src)>;
394   def : Pat<(v4i32 (bitconvert (v8i16 VR128:$src))), (v4i32 VR128:$src)>;
395   def : Pat<(v4i32 (bitconvert (v16i8 VR128:$src))), (v4i32 VR128:$src)>;
396   def : Pat<(v4i32 (bitconvert (v2f64 VR128:$src))), (v4i32 VR128:$src)>;
397   def : Pat<(v4i32 (bitconvert (v4f32 VR128:$src))), (v4i32 VR128:$src)>;
398   def : Pat<(v8i16 (bitconvert (v2i64 VR128:$src))), (v8i16 VR128:$src)>;
399   def : Pat<(v8i16 (bitconvert (v4i32 VR128:$src))), (v8i16 VR128:$src)>;
400   def : Pat<(v8i16 (bitconvert (v16i8 VR128:$src))), (v8i16 VR128:$src)>;
401   def : Pat<(v8i16 (bitconvert (v2f64 VR128:$src))), (v8i16 VR128:$src)>;
402   def : Pat<(v8i16 (bitconvert (v4f32 VR128:$src))), (v8i16 VR128:$src)>;
403   def : Pat<(v16i8 (bitconvert (v2i64 VR128:$src))), (v16i8 VR128:$src)>;
404   def : Pat<(v16i8 (bitconvert (v4i32 VR128:$src))), (v16i8 VR128:$src)>;
405   def : Pat<(v16i8 (bitconvert (v8i16 VR128:$src))), (v16i8 VR128:$src)>;
406   def : Pat<(v16i8 (bitconvert (v2f64 VR128:$src))), (v16i8 VR128:$src)>;
407   def : Pat<(v16i8 (bitconvert (v4f32 VR128:$src))), (v16i8 VR128:$src)>;
408   def : Pat<(v4f32 (bitconvert (v2i64 VR128:$src))), (v4f32 VR128:$src)>;
409   def : Pat<(v4f32 (bitconvert (v4i32 VR128:$src))), (v4f32 VR128:$src)>;
410   def : Pat<(v4f32 (bitconvert (v8i16 VR128:$src))), (v4f32 VR128:$src)>;
411   def : Pat<(v4f32 (bitconvert (v16i8 VR128:$src))), (v4f32 VR128:$src)>;
412   def : Pat<(v4f32 (bitconvert (v2f64 VR128:$src))), (v4f32 VR128:$src)>;
413   def : Pat<(v2f64 (bitconvert (v2i64 VR128:$src))), (v2f64 VR128:$src)>;
414   def : Pat<(v2f64 (bitconvert (v4i32 VR128:$src))), (v2f64 VR128:$src)>;
415   def : Pat<(v2f64 (bitconvert (v8i16 VR128:$src))), (v2f64 VR128:$src)>;
416   def : Pat<(v2f64 (bitconvert (v16i8 VR128:$src))), (v2f64 VR128:$src)>;
417   def : Pat<(v2f64 (bitconvert (v4f32 VR128:$src))), (v2f64 VR128:$src)>;
418 }
419
420 // Bitcasts between 256-bit vector types. Return the original type since
421 // no instruction is needed for the conversion
422 let Predicates = [HasAVX] in {
423   def : Pat<(v4f64  (bitconvert (v8f32 VR256:$src))),  (v4f64 VR256:$src)>;
424   def : Pat<(v4f64  (bitconvert (v8i32 VR256:$src))),  (v4f64 VR256:$src)>;
425   def : Pat<(v4f64  (bitconvert (v4i64 VR256:$src))),  (v4f64 VR256:$src)>;
426   def : Pat<(v4f64  (bitconvert (v16i16 VR256:$src))), (v4f64 VR256:$src)>;
427   def : Pat<(v4f64  (bitconvert (v32i8 VR256:$src))),  (v4f64 VR256:$src)>;
428   def : Pat<(v8f32  (bitconvert (v8i32 VR256:$src))),  (v8f32 VR256:$src)>;
429   def : Pat<(v8f32  (bitconvert (v4i64 VR256:$src))),  (v8f32 VR256:$src)>;
430   def : Pat<(v8f32  (bitconvert (v4f64 VR256:$src))),  (v8f32 VR256:$src)>;
431   def : Pat<(v8f32  (bitconvert (v32i8 VR256:$src))),  (v8f32 VR256:$src)>;
432   def : Pat<(v8f32  (bitconvert (v16i16 VR256:$src))), (v8f32 VR256:$src)>;
433   def : Pat<(v4i64  (bitconvert (v8f32 VR256:$src))),  (v4i64 VR256:$src)>;
434   def : Pat<(v4i64  (bitconvert (v8i32 VR256:$src))),  (v4i64 VR256:$src)>;
435   def : Pat<(v4i64  (bitconvert (v4f64 VR256:$src))),  (v4i64 VR256:$src)>;
436   def : Pat<(v4i64  (bitconvert (v32i8 VR256:$src))),  (v4i64 VR256:$src)>;
437   def : Pat<(v4i64  (bitconvert (v16i16 VR256:$src))), (v4i64 VR256:$src)>;
438   def : Pat<(v32i8  (bitconvert (v4f64 VR256:$src))),  (v32i8 VR256:$src)>;
439   def : Pat<(v32i8  (bitconvert (v4i64 VR256:$src))),  (v32i8 VR256:$src)>;
440   def : Pat<(v32i8  (bitconvert (v8f32 VR256:$src))),  (v32i8 VR256:$src)>;
441   def : Pat<(v32i8  (bitconvert (v8i32 VR256:$src))),  (v32i8 VR256:$src)>;
442   def : Pat<(v32i8  (bitconvert (v16i16 VR256:$src))), (v32i8 VR256:$src)>;
443   def : Pat<(v8i32  (bitconvert (v32i8 VR256:$src))),  (v8i32 VR256:$src)>;
444   def : Pat<(v8i32  (bitconvert (v16i16 VR256:$src))), (v8i32 VR256:$src)>;
445   def : Pat<(v8i32  (bitconvert (v8f32 VR256:$src))),  (v8i32 VR256:$src)>;
446   def : Pat<(v8i32  (bitconvert (v4i64 VR256:$src))),  (v8i32 VR256:$src)>;
447   def : Pat<(v8i32  (bitconvert (v4f64 VR256:$src))),  (v8i32 VR256:$src)>;
448   def : Pat<(v16i16 (bitconvert (v8f32 VR256:$src))),  (v16i16 VR256:$src)>;
449   def : Pat<(v16i16 (bitconvert (v8i32 VR256:$src))),  (v16i16 VR256:$src)>;
450   def : Pat<(v16i16 (bitconvert (v4i64 VR256:$src))),  (v16i16 VR256:$src)>;
451   def : Pat<(v16i16 (bitconvert (v4f64 VR256:$src))),  (v16i16 VR256:$src)>;
452   def : Pat<(v16i16 (bitconvert (v32i8 VR256:$src))),  (v16i16 VR256:$src)>;
453 }
454
455 // Alias instructions that map fld0 to xorps for sse or vxorps for avx.
456 // This is expanded by ExpandPostRAPseudos.
457 let isReMaterializable = 1, isAsCheapAsAMove = 1, canFoldAsLoad = 1,
458     isPseudo = 1, SchedRW = [WriteZero] in {
459   def FsFLD0SS : I<0, Pseudo, (outs FR32:$dst), (ins), "",
460                    [(set FR32:$dst, fp32imm0)]>, Requires<[HasSSE1]>;
461   def FsFLD0SD : I<0, Pseudo, (outs FR64:$dst), (ins), "",
462                    [(set FR64:$dst, fpimm0)]>, Requires<[HasSSE2]>;
463 }
464
465 //===----------------------------------------------------------------------===//
466 // AVX & SSE - Zero/One Vectors
467 //===----------------------------------------------------------------------===//
468
469 // Alias instruction that maps zero vector to pxor / xorp* for sse.
470 // This is expanded by ExpandPostRAPseudos to an xorps / vxorps, and then
471 // swizzled by ExecutionDepsFix to pxor.
472 // We set canFoldAsLoad because this can be converted to a constant-pool
473 // load of an all-zeros value if folding it would be beneficial.
474 let isReMaterializable = 1, isAsCheapAsAMove = 1, canFoldAsLoad = 1,
475     isPseudo = 1, SchedRW = [WriteZero] in {
476 def V_SET0 : I<0, Pseudo, (outs VR128:$dst), (ins), "",
477                [(set VR128:$dst, (v4f32 immAllZerosV))]>;
478 }
479
480 def : Pat<(v2f64 immAllZerosV), (V_SET0)>;
481 def : Pat<(v4i32 immAllZerosV), (V_SET0)>;
482 def : Pat<(v2i64 immAllZerosV), (V_SET0)>;
483 def : Pat<(v8i16 immAllZerosV), (V_SET0)>;
484 def : Pat<(v16i8 immAllZerosV), (V_SET0)>;
485
486
487 // The same as done above but for AVX.  The 256-bit AVX1 ISA doesn't support PI,
488 // and doesn't need it because on sandy bridge the register is set to zero
489 // at the rename stage without using any execution unit, so SET0PSY
490 // and SET0PDY can be used for vector int instructions without penalty
491 let isReMaterializable = 1, isAsCheapAsAMove = 1, canFoldAsLoad = 1,
492     isPseudo = 1, Predicates = [HasAVX], SchedRW = [WriteZero] in {
493 def AVX_SET0 : I<0, Pseudo, (outs VR256:$dst), (ins), "",
494                  [(set VR256:$dst, (v8f32 immAllZerosV))]>;
495 }
496
497 let Predicates = [HasAVX] in
498   def : Pat<(v4f64 immAllZerosV), (AVX_SET0)>;
499
500 let Predicates = [HasAVX2] in {
501   def : Pat<(v4i64 immAllZerosV), (AVX_SET0)>;
502   def : Pat<(v8i32 immAllZerosV), (AVX_SET0)>;
503   def : Pat<(v16i16 immAllZerosV), (AVX_SET0)>;
504   def : Pat<(v32i8 immAllZerosV), (AVX_SET0)>;
505 }
506
507 // AVX1 has no support for 256-bit integer instructions, but since the 128-bit
508 // VPXOR instruction writes zero to its upper part, it's safe build zeros.
509 let Predicates = [HasAVX1Only] in {
510 def : Pat<(v32i8 immAllZerosV), (SUBREG_TO_REG (i8 0), (V_SET0), sub_xmm)>;
511 def : Pat<(bc_v32i8 (v8f32 immAllZerosV)),
512           (SUBREG_TO_REG (i8 0), (V_SET0), sub_xmm)>;
513
514 def : Pat<(v16i16 immAllZerosV), (SUBREG_TO_REG (i16 0), (V_SET0), sub_xmm)>;
515 def : Pat<(bc_v16i16 (v8f32 immAllZerosV)),
516           (SUBREG_TO_REG (i16 0), (V_SET0), sub_xmm)>;
517
518 def : Pat<(v8i32 immAllZerosV), (SUBREG_TO_REG (i32 0), (V_SET0), sub_xmm)>;
519 def : Pat<(bc_v8i32 (v8f32 immAllZerosV)),
520           (SUBREG_TO_REG (i32 0), (V_SET0), sub_xmm)>;
521
522 def : Pat<(v4i64 immAllZerosV), (SUBREG_TO_REG (i64 0), (V_SET0), sub_xmm)>;
523 def : Pat<(bc_v4i64 (v8f32 immAllZerosV)),
524           (SUBREG_TO_REG (i64 0), (V_SET0), sub_xmm)>;
525 }
526
527 // We set canFoldAsLoad because this can be converted to a constant-pool
528 // load of an all-ones value if folding it would be beneficial.
529 let isReMaterializable = 1, isAsCheapAsAMove = 1, canFoldAsLoad = 1,
530     isPseudo = 1, SchedRW = [WriteZero] in {
531   def V_SETALLONES : I<0, Pseudo, (outs VR128:$dst), (ins), "",
532                        [(set VR128:$dst, (v4i32 immAllOnesV))]>;
533   let Predicates = [HasAVX2] in
534   def AVX2_SETALLONES : I<0, Pseudo, (outs VR256:$dst), (ins), "",
535                           [(set VR256:$dst, (v8i32 immAllOnesV))]>;
536 }
537
538
539 //===----------------------------------------------------------------------===//
540 // SSE 1 & 2 - Move FP Scalar Instructions
541 //
542 // Move Instructions. Register-to-register movss/movsd is not used for FR32/64
543 // register copies because it's a partial register update; Register-to-register
544 // movss/movsd is not modeled as an INSERT_SUBREG because INSERT_SUBREG requires
545 // that the insert be implementable in terms of a copy, and just mentioned, we
546 // don't use movss/movsd for copies.
547 //===----------------------------------------------------------------------===//
548
549 multiclass sse12_move_rr<RegisterClass RC, SDNode OpNode, ValueType vt,
550                          X86MemOperand x86memop, string base_opc,
551                          string asm_opr> {
552   def rr : SI<0x10, MRMSrcReg, (outs VR128:$dst),
553               (ins VR128:$src1, RC:$src2),
554               !strconcat(base_opc, asm_opr),
555               [(set VR128:$dst, (vt (OpNode VR128:$src1,
556                                  (scalar_to_vector RC:$src2))))],
557               IIC_SSE_MOV_S_RR>, Sched<[WriteFShuffle]>;
558
559   // For the disassembler
560   let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0 in
561   def rr_REV : SI<0x11, MRMDestReg, (outs VR128:$dst),
562                   (ins VR128:$src1, RC:$src2),
563                   !strconcat(base_opc, asm_opr),
564                   [], IIC_SSE_MOV_S_RR>, Sched<[WriteFShuffle]>;
565 }
566
567 multiclass sse12_move<RegisterClass RC, SDNode OpNode, ValueType vt,
568                       X86MemOperand x86memop, string OpcodeStr> {
569   // AVX
570   defm V#NAME : sse12_move_rr<RC, OpNode, vt, x86memop, OpcodeStr,
571                               "\t{$src2, $src1, $dst|$dst, $src1, $src2}">,
572                               VEX_4V, VEX_LIG;
573
574   def V#NAME#mr : SI<0x11, MRMDestMem, (outs), (ins x86memop:$dst, RC:$src),
575                      !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
576                      [(store RC:$src, addr:$dst)], IIC_SSE_MOV_S_MR>,
577                      VEX, VEX_LIG, Sched<[WriteStore]>;
578   // SSE1 & 2
579   let Constraints = "$src1 = $dst" in {
580     defm NAME : sse12_move_rr<RC, OpNode, vt, x86memop, OpcodeStr,
581                               "\t{$src2, $dst|$dst, $src2}">;
582   }
583
584   def NAME#mr   : SI<0x11, MRMDestMem, (outs), (ins x86memop:$dst, RC:$src),
585                      !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
586                      [(store RC:$src, addr:$dst)], IIC_SSE_MOV_S_MR>,
587                   Sched<[WriteStore]>;
588 }
589
590 // Loading from memory automatically zeroing upper bits.
591 multiclass sse12_move_rm<RegisterClass RC, X86MemOperand x86memop,
592                          PatFrag mem_pat, string OpcodeStr> {
593   def V#NAME#rm : SI<0x10, MRMSrcMem, (outs RC:$dst), (ins x86memop:$src),
594                      !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
595                      [(set RC:$dst, (mem_pat addr:$src))],
596                      IIC_SSE_MOV_S_RM>, VEX, VEX_LIG, Sched<[WriteLoad]>;
597   def NAME#rm   : SI<0x10, MRMSrcMem, (outs RC:$dst), (ins x86memop:$src),
598                      !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
599                      [(set RC:$dst, (mem_pat addr:$src))],
600                      IIC_SSE_MOV_S_RM>, Sched<[WriteLoad]>;
601 }
602
603 defm MOVSS : sse12_move<FR32, X86Movss, v4f32, f32mem, "movss">, XS;
604 defm MOVSD : sse12_move<FR64, X86Movsd, v2f64, f64mem, "movsd">, XD;
605
606 let canFoldAsLoad = 1, isReMaterializable = 1 in {
607   defm MOVSS : sse12_move_rm<FR32, f32mem, loadf32, "movss">, XS;
608
609   let AddedComplexity = 20 in
610     defm MOVSD : sse12_move_rm<FR64, f64mem, loadf64, "movsd">, XD;
611 }
612
613 // Patterns
614 let Predicates = [UseAVX] in {
615   let AddedComplexity = 15 in {
616   // Move scalar to XMM zero-extended, zeroing a VR128 then do a
617   // MOVS{S,D} to the lower bits.
618   def : Pat<(v4f32 (X86vzmovl (v4f32 (scalar_to_vector FR32:$src)))),
619             (VMOVSSrr (v4f32 (V_SET0)), FR32:$src)>;
620   def : Pat<(v4f32 (X86vzmovl (v4f32 VR128:$src))),
621             (VMOVSSrr (v4f32 (V_SET0)), (COPY_TO_REGCLASS VR128:$src, FR32))>;
622   def : Pat<(v4i32 (X86vzmovl (v4i32 VR128:$src))),
623             (VMOVSSrr (v4i32 (V_SET0)), (COPY_TO_REGCLASS VR128:$src, FR32))>;
624   def : Pat<(v2f64 (X86vzmovl (v2f64 (scalar_to_vector FR64:$src)))),
625             (VMOVSDrr (v2f64 (V_SET0)), FR64:$src)>;
626
627   // Move low f32 and clear high bits.
628   def : Pat<(v8f32 (X86vzmovl (v8f32 VR256:$src))),
629             (SUBREG_TO_REG (i32 0),
630              (VMOVSSrr (v4f32 (V_SET0)),
631                        (EXTRACT_SUBREG (v8f32 VR256:$src), sub_xmm)), sub_xmm)>;
632   def : Pat<(v8i32 (X86vzmovl (v8i32 VR256:$src))),
633             (SUBREG_TO_REG (i32 0),
634              (VMOVSSrr (v4i32 (V_SET0)),
635                        (EXTRACT_SUBREG (v8i32 VR256:$src), sub_xmm)), sub_xmm)>;
636   }
637
638   let AddedComplexity = 20 in {
639   // MOVSSrm zeros the high parts of the register; represent this
640   // with SUBREG_TO_REG. The AVX versions also write: DST[255:128] <- 0
641   def : Pat<(v4f32 (X86vzmovl (v4f32 (scalar_to_vector (loadf32 addr:$src))))),
642             (COPY_TO_REGCLASS (VMOVSSrm addr:$src), VR128)>;
643   def : Pat<(v4f32 (scalar_to_vector (loadf32 addr:$src))),
644             (COPY_TO_REGCLASS (VMOVSSrm addr:$src), VR128)>;
645   def : Pat<(v4f32 (X86vzmovl (loadv4f32 addr:$src))),
646             (COPY_TO_REGCLASS (VMOVSSrm addr:$src), VR128)>;
647
648   // MOVSDrm zeros the high parts of the register; represent this
649   // with SUBREG_TO_REG. The AVX versions also write: DST[255:128] <- 0
650   def : Pat<(v2f64 (X86vzmovl (v2f64 (scalar_to_vector (loadf64 addr:$src))))),
651             (COPY_TO_REGCLASS (VMOVSDrm addr:$src), VR128)>;
652   def : Pat<(v2f64 (scalar_to_vector (loadf64 addr:$src))),
653             (COPY_TO_REGCLASS (VMOVSDrm addr:$src), VR128)>;
654   def : Pat<(v2f64 (X86vzmovl (loadv2f64 addr:$src))),
655             (COPY_TO_REGCLASS (VMOVSDrm addr:$src), VR128)>;
656   def : Pat<(v2f64 (X86vzmovl (bc_v2f64 (loadv4f32 addr:$src)))),
657             (COPY_TO_REGCLASS (VMOVSDrm addr:$src), VR128)>;
658   def : Pat<(v2f64 (X86vzload addr:$src)),
659             (COPY_TO_REGCLASS (VMOVSDrm addr:$src), VR128)>;
660
661   // Represent the same patterns above but in the form they appear for
662   // 256-bit types
663   def : Pat<(v8i32 (X86vzmovl (insert_subvector undef,
664                    (v4i32 (scalar_to_vector (loadi32 addr:$src))), (iPTR 0)))),
665             (SUBREG_TO_REG (i32 0), (VMOVSSrm addr:$src), sub_xmm)>;
666   def : Pat<(v8f32 (X86vzmovl (insert_subvector undef,
667                    (v4f32 (scalar_to_vector (loadf32 addr:$src))), (iPTR 0)))),
668             (SUBREG_TO_REG (i32 0), (VMOVSSrm addr:$src), sub_xmm)>;
669   def : Pat<(v4f64 (X86vzmovl (insert_subvector undef,
670                    (v2f64 (scalar_to_vector (loadf64 addr:$src))), (iPTR 0)))),
671             (SUBREG_TO_REG (i32 0), (VMOVSDrm addr:$src), sub_xmm)>;
672   }
673   def : Pat<(v8f32 (X86vzmovl (insert_subvector undef,
674                    (v4f32 (scalar_to_vector FR32:$src)), (iPTR 0)))),
675             (SUBREG_TO_REG (i32 0),
676                            (v4f32 (VMOVSSrr (v4f32 (V_SET0)), FR32:$src)),
677                            sub_xmm)>;
678   def : Pat<(v4f64 (X86vzmovl (insert_subvector undef,
679                    (v2f64 (scalar_to_vector FR64:$src)), (iPTR 0)))),
680             (SUBREG_TO_REG (i64 0),
681                            (v2f64 (VMOVSDrr (v2f64 (V_SET0)), FR64:$src)),
682                            sub_xmm)>;
683   def : Pat<(v4i64 (X86vzmovl (insert_subvector undef,
684                    (v2i64 (scalar_to_vector (loadi64 addr:$src))), (iPTR 0)))),
685             (SUBREG_TO_REG (i64 0), (VMOVSDrm addr:$src), sub_xmm)>;
686
687   // Move low f64 and clear high bits.
688   def : Pat<(v4f64 (X86vzmovl (v4f64 VR256:$src))),
689             (SUBREG_TO_REG (i32 0),
690              (VMOVSDrr (v2f64 (V_SET0)),
691                        (EXTRACT_SUBREG (v4f64 VR256:$src), sub_xmm)), sub_xmm)>;
692
693   def : Pat<(v4i64 (X86vzmovl (v4i64 VR256:$src))),
694             (SUBREG_TO_REG (i32 0),
695              (VMOVSDrr (v2i64 (V_SET0)),
696                        (EXTRACT_SUBREG (v4i64 VR256:$src), sub_xmm)), sub_xmm)>;
697
698   // Extract and store.
699   def : Pat<(store (f32 (vector_extract (v4f32 VR128:$src), (iPTR 0))),
700                    addr:$dst),
701             (VMOVSSmr addr:$dst, (COPY_TO_REGCLASS (v4f32 VR128:$src), FR32))>;
702   def : Pat<(store (f64 (vector_extract (v2f64 VR128:$src), (iPTR 0))),
703                    addr:$dst),
704             (VMOVSDmr addr:$dst, (COPY_TO_REGCLASS (v2f64 VR128:$src), FR64))>;
705
706   // Shuffle with VMOVSS
707   def : Pat<(v4i32 (X86Movss VR128:$src1, VR128:$src2)),
708             (VMOVSSrr (v4i32 VR128:$src1),
709                       (COPY_TO_REGCLASS (v4i32 VR128:$src2), FR32))>;
710   def : Pat<(v4f32 (X86Movss VR128:$src1, VR128:$src2)),
711             (VMOVSSrr (v4f32 VR128:$src1),
712                       (COPY_TO_REGCLASS (v4f32 VR128:$src2), FR32))>;
713
714   // 256-bit variants
715   def : Pat<(v8i32 (X86Movss VR256:$src1, VR256:$src2)),
716             (SUBREG_TO_REG (i32 0),
717               (VMOVSSrr (EXTRACT_SUBREG (v8i32 VR256:$src1), sub_xmm),
718                         (EXTRACT_SUBREG (v8i32 VR256:$src2), sub_xmm)),
719               sub_xmm)>;
720   def : Pat<(v8f32 (X86Movss VR256:$src1, VR256:$src2)),
721             (SUBREG_TO_REG (i32 0),
722               (VMOVSSrr (EXTRACT_SUBREG (v8f32 VR256:$src1), sub_xmm),
723                         (EXTRACT_SUBREG (v8f32 VR256:$src2), sub_xmm)),
724               sub_xmm)>;
725
726   // Shuffle with VMOVSD
727   def : Pat<(v2i64 (X86Movsd VR128:$src1, VR128:$src2)),
728             (VMOVSDrr VR128:$src1, (COPY_TO_REGCLASS VR128:$src2, FR64))>;
729   def : Pat<(v2f64 (X86Movsd VR128:$src1, VR128:$src2)),
730             (VMOVSDrr VR128:$src1, (COPY_TO_REGCLASS VR128:$src2, FR64))>;
731   def : Pat<(v4f32 (X86Movsd VR128:$src1, VR128:$src2)),
732             (VMOVSDrr VR128:$src1, (COPY_TO_REGCLASS VR128:$src2, FR64))>;
733   def : Pat<(v4i32 (X86Movsd VR128:$src1, VR128:$src2)),
734             (VMOVSDrr VR128:$src1, (COPY_TO_REGCLASS VR128:$src2, FR64))>;
735
736   // 256-bit variants
737   def : Pat<(v4i64 (X86Movsd VR256:$src1, VR256:$src2)),
738             (SUBREG_TO_REG (i32 0),
739               (VMOVSDrr (EXTRACT_SUBREG (v4i64 VR256:$src1), sub_xmm),
740                         (EXTRACT_SUBREG (v4i64 VR256:$src2), sub_xmm)),
741               sub_xmm)>;
742   def : Pat<(v4f64 (X86Movsd VR256:$src1, VR256:$src2)),
743             (SUBREG_TO_REG (i32 0),
744               (VMOVSDrr (EXTRACT_SUBREG (v4f64 VR256:$src1), sub_xmm),
745                         (EXTRACT_SUBREG (v4f64 VR256:$src2), sub_xmm)),
746               sub_xmm)>;
747
748
749   // FIXME: Instead of a X86Movlps there should be a X86Movsd here, the problem
750   // is during lowering, where it's not possible to recognize the fold cause
751   // it has two uses through a bitcast. One use disappears at isel time and the
752   // fold opportunity reappears.
753   def : Pat<(v2f64 (X86Movlpd VR128:$src1, VR128:$src2)),
754             (VMOVSDrr VR128:$src1, (COPY_TO_REGCLASS VR128:$src2, FR64))>;
755   def : Pat<(v2i64 (X86Movlpd VR128:$src1, VR128:$src2)),
756             (VMOVSDrr VR128:$src1, (COPY_TO_REGCLASS VR128:$src2, FR64))>;
757   def : Pat<(v4f32 (X86Movlps VR128:$src1, VR128:$src2)),
758             (VMOVSDrr VR128:$src1, (COPY_TO_REGCLASS VR128:$src2, FR64))>;
759   def : Pat<(v4i32 (X86Movlps VR128:$src1, VR128:$src2)),
760             (VMOVSDrr VR128:$src1, (COPY_TO_REGCLASS VR128:$src2, FR64))>;
761 }
762
763 let Predicates = [UseSSE1] in {
764   let AddedComplexity = 15 in {
765   // Move scalar to XMM zero-extended, zeroing a VR128 then do a
766   // MOVSS to the lower bits.
767   def : Pat<(v4f32 (X86vzmovl (v4f32 (scalar_to_vector FR32:$src)))),
768             (MOVSSrr (v4f32 (V_SET0)), FR32:$src)>;
769   def : Pat<(v4f32 (X86vzmovl (v4f32 VR128:$src))),
770             (MOVSSrr (v4f32 (V_SET0)), (COPY_TO_REGCLASS VR128:$src, FR32))>;
771   def : Pat<(v4i32 (X86vzmovl (v4i32 VR128:$src))),
772             (MOVSSrr (v4i32 (V_SET0)), (COPY_TO_REGCLASS VR128:$src, FR32))>;
773   }
774
775   let AddedComplexity = 20 in {
776   // MOVSSrm already zeros the high parts of the register.
777   def : Pat<(v4f32 (X86vzmovl (v4f32 (scalar_to_vector (loadf32 addr:$src))))),
778             (COPY_TO_REGCLASS (MOVSSrm addr:$src), VR128)>;
779   def : Pat<(v4f32 (scalar_to_vector (loadf32 addr:$src))),
780             (COPY_TO_REGCLASS (MOVSSrm addr:$src), VR128)>;
781   def : Pat<(v4f32 (X86vzmovl (loadv4f32 addr:$src))),
782             (COPY_TO_REGCLASS (MOVSSrm addr:$src), VR128)>;
783   }
784
785   // Extract and store.
786   def : Pat<(store (f32 (vector_extract (v4f32 VR128:$src), (iPTR 0))),
787                    addr:$dst),
788             (MOVSSmr addr:$dst, (COPY_TO_REGCLASS VR128:$src, FR32))>;
789
790   // Shuffle with MOVSS
791   def : Pat<(v4i32 (X86Movss VR128:$src1, VR128:$src2)),
792             (MOVSSrr VR128:$src1, (COPY_TO_REGCLASS VR128:$src2, FR32))>;
793   def : Pat<(v4f32 (X86Movss VR128:$src1, VR128:$src2)),
794             (MOVSSrr VR128:$src1, (COPY_TO_REGCLASS VR128:$src2, FR32))>;
795 }
796
797 let Predicates = [UseSSE2] in {
798   let AddedComplexity = 15 in {
799   // Move scalar to XMM zero-extended, zeroing a VR128 then do a
800   // MOVSD to the lower bits.
801   def : Pat<(v2f64 (X86vzmovl (v2f64 (scalar_to_vector FR64:$src)))),
802             (MOVSDrr (v2f64 (V_SET0)), FR64:$src)>;
803   }
804
805   let AddedComplexity = 20 in {
806   // MOVSDrm already zeros the high parts of the register.
807   def : Pat<(v2f64 (X86vzmovl (v2f64 (scalar_to_vector (loadf64 addr:$src))))),
808             (COPY_TO_REGCLASS (MOVSDrm addr:$src), VR128)>;
809   def : Pat<(v2f64 (scalar_to_vector (loadf64 addr:$src))),
810             (COPY_TO_REGCLASS (MOVSDrm addr:$src), VR128)>;
811   def : Pat<(v2f64 (X86vzmovl (loadv2f64 addr:$src))),
812             (COPY_TO_REGCLASS (MOVSDrm addr:$src), VR128)>;
813   def : Pat<(v2f64 (X86vzmovl (bc_v2f64 (loadv4f32 addr:$src)))),
814             (COPY_TO_REGCLASS (MOVSDrm addr:$src), VR128)>;
815   def : Pat<(v2f64 (X86vzload addr:$src)),
816             (COPY_TO_REGCLASS (MOVSDrm addr:$src), VR128)>;
817   }
818
819   // Extract and store.
820   def : Pat<(store (f64 (vector_extract (v2f64 VR128:$src), (iPTR 0))),
821                    addr:$dst),
822             (MOVSDmr addr:$dst, (COPY_TO_REGCLASS VR128:$src, FR64))>;
823
824   // Shuffle with MOVSD
825   def : Pat<(v2i64 (X86Movsd VR128:$src1, VR128:$src2)),
826             (MOVSDrr VR128:$src1, (COPY_TO_REGCLASS VR128:$src2, FR64))>;
827   def : Pat<(v2f64 (X86Movsd VR128:$src1, VR128:$src2)),
828             (MOVSDrr VR128:$src1, (COPY_TO_REGCLASS VR128:$src2, FR64))>;
829   def : Pat<(v4f32 (X86Movsd VR128:$src1, VR128:$src2)),
830             (MOVSDrr VR128:$src1, (COPY_TO_REGCLASS VR128:$src2, FR64))>;
831   def : Pat<(v4i32 (X86Movsd VR128:$src1, VR128:$src2)),
832             (MOVSDrr VR128:$src1, (COPY_TO_REGCLASS VR128:$src2, FR64))>;
833
834   // FIXME: Instead of a X86Movlps there should be a X86Movsd here, the problem
835   // is during lowering, where it's not possible to recognize the fold cause
836   // it has two uses through a bitcast. One use disappears at isel time and the
837   // fold opportunity reappears.
838   def : Pat<(v2f64 (X86Movlpd VR128:$src1, VR128:$src2)),
839             (MOVSDrr VR128:$src1, (COPY_TO_REGCLASS VR128:$src2, FR64))>;
840   def : Pat<(v2i64 (X86Movlpd VR128:$src1, VR128:$src2)),
841             (MOVSDrr VR128:$src1, (COPY_TO_REGCLASS VR128:$src2, FR64))>;
842   def : Pat<(v4f32 (X86Movlps VR128:$src1, VR128:$src2)),
843             (MOVSDrr VR128:$src1, (COPY_TO_REGCLASS VR128:$src2, FR64))>;
844   def : Pat<(v4i32 (X86Movlps VR128:$src1, VR128:$src2)),
845             (MOVSDrr VR128:$src1, (COPY_TO_REGCLASS VR128:$src2, FR64))>;
846 }
847
848 //===----------------------------------------------------------------------===//
849 // SSE 1 & 2 - Move Aligned/Unaligned FP Instructions
850 //===----------------------------------------------------------------------===//
851
852 multiclass sse12_mov_packed<bits<8> opc, RegisterClass RC,
853                             X86MemOperand x86memop, PatFrag ld_frag,
854                             string asm, Domain d,
855                             OpndItins itins,
856                             bit IsReMaterializable = 1> {
857 let neverHasSideEffects = 1 in
858   def rr : PI<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src),
859               !strconcat(asm, "\t{$src, $dst|$dst, $src}"), [], itins.rr, d>,
860            Sched<[WriteFShuffle]>;
861 let canFoldAsLoad = 1, isReMaterializable = IsReMaterializable in
862   def rm : PI<opc, MRMSrcMem, (outs RC:$dst), (ins x86memop:$src),
863               !strconcat(asm, "\t{$src, $dst|$dst, $src}"),
864                    [(set RC:$dst, (ld_frag addr:$src))], itins.rm, d>,
865            Sched<[WriteLoad]>;
866 }
867
868 let Predicates = [HasAVX, NoVLX] in {
869 defm VMOVAPS : sse12_mov_packed<0x28, VR128, f128mem, alignedloadv4f32,
870                               "movaps", SSEPackedSingle, SSE_MOVA_ITINS>,
871                               PS, VEX;
872 defm VMOVAPD : sse12_mov_packed<0x28, VR128, f128mem, alignedloadv2f64,
873                               "movapd", SSEPackedDouble, SSE_MOVA_ITINS>,
874                               PD, VEX;
875 defm VMOVUPS : sse12_mov_packed<0x10, VR128, f128mem, loadv4f32,
876                               "movups", SSEPackedSingle, SSE_MOVU_ITINS>,
877                               PS, VEX;
878 defm VMOVUPD : sse12_mov_packed<0x10, VR128, f128mem, loadv2f64,
879                               "movupd", SSEPackedDouble, SSE_MOVU_ITINS, 0>,
880                               PD, VEX;
881
882 defm VMOVAPSY : sse12_mov_packed<0x28, VR256, f256mem, alignedloadv8f32,
883                               "movaps", SSEPackedSingle, SSE_MOVA_ITINS>,
884                               PS, VEX, VEX_L;
885 defm VMOVAPDY : sse12_mov_packed<0x28, VR256, f256mem, alignedloadv4f64,
886                               "movapd", SSEPackedDouble, SSE_MOVA_ITINS>,
887                               PD, VEX, VEX_L;
888 defm VMOVUPSY : sse12_mov_packed<0x10, VR256, f256mem, loadv8f32,
889                               "movups", SSEPackedSingle, SSE_MOVU_ITINS>,
890                               PS, VEX, VEX_L;
891 defm VMOVUPDY : sse12_mov_packed<0x10, VR256, f256mem, loadv4f64,
892                               "movupd", SSEPackedDouble, SSE_MOVU_ITINS, 0>,
893                               PD, VEX, VEX_L;
894 }
895
896 let Predicates = [UseSSE1] in {
897 defm MOVAPS : sse12_mov_packed<0x28, VR128, f128mem, alignedloadv4f32,
898                               "movaps", SSEPackedSingle, SSE_MOVA_ITINS>,
899                               PS;
900 defm MOVUPS : sse12_mov_packed<0x10, VR128, f128mem, loadv4f32,
901                               "movups", SSEPackedSingle, SSE_MOVU_ITINS>,
902                               PS;
903 }
904 let Predicates = [UseSSE2] in {
905 defm MOVAPD : sse12_mov_packed<0x28, VR128, f128mem, alignedloadv2f64,
906                               "movapd", SSEPackedDouble, SSE_MOVA_ITINS>,
907                               PD;
908 defm MOVUPD : sse12_mov_packed<0x10, VR128, f128mem, loadv2f64,
909                               "movupd", SSEPackedDouble, SSE_MOVU_ITINS, 0>,
910                               PD;
911 }
912
913 let SchedRW = [WriteStore], Predicates = [HasAVX, NoVLX]  in {
914 def VMOVAPSmr : VPSI<0x29, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
915                    "movaps\t{$src, $dst|$dst, $src}",
916                    [(alignedstore (v4f32 VR128:$src), addr:$dst)],
917                    IIC_SSE_MOVA_P_MR>, VEX;
918 def VMOVAPDmr : VPDI<0x29, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
919                    "movapd\t{$src, $dst|$dst, $src}",
920                    [(alignedstore (v2f64 VR128:$src), addr:$dst)],
921                    IIC_SSE_MOVA_P_MR>, VEX;
922 def VMOVUPSmr : VPSI<0x11, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
923                    "movups\t{$src, $dst|$dst, $src}",
924                    [(store (v4f32 VR128:$src), addr:$dst)],
925                    IIC_SSE_MOVU_P_MR>, VEX;
926 def VMOVUPDmr : VPDI<0x11, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
927                    "movupd\t{$src, $dst|$dst, $src}",
928                    [(store (v2f64 VR128:$src), addr:$dst)],
929                    IIC_SSE_MOVU_P_MR>, VEX;
930 def VMOVAPSYmr : VPSI<0x29, MRMDestMem, (outs), (ins f256mem:$dst, VR256:$src),
931                    "movaps\t{$src, $dst|$dst, $src}",
932                    [(alignedstore256 (v8f32 VR256:$src), addr:$dst)],
933                    IIC_SSE_MOVA_P_MR>, VEX, VEX_L;
934 def VMOVAPDYmr : VPDI<0x29, MRMDestMem, (outs), (ins f256mem:$dst, VR256:$src),
935                    "movapd\t{$src, $dst|$dst, $src}",
936                    [(alignedstore256 (v4f64 VR256:$src), addr:$dst)],
937                    IIC_SSE_MOVA_P_MR>, VEX, VEX_L;
938 def VMOVUPSYmr : VPSI<0x11, MRMDestMem, (outs), (ins f256mem:$dst, VR256:$src),
939                    "movups\t{$src, $dst|$dst, $src}",
940                    [(store (v8f32 VR256:$src), addr:$dst)],
941                    IIC_SSE_MOVU_P_MR>, VEX, VEX_L;
942 def VMOVUPDYmr : VPDI<0x11, MRMDestMem, (outs), (ins f256mem:$dst, VR256:$src),
943                    "movupd\t{$src, $dst|$dst, $src}",
944                    [(store (v4f64 VR256:$src), addr:$dst)],
945                    IIC_SSE_MOVU_P_MR>, VEX, VEX_L;
946 } // SchedRW
947
948 // For disassembler
949 let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0,
950     SchedRW = [WriteFShuffle] in {
951   def VMOVAPSrr_REV : VPSI<0x29, MRMDestReg, (outs VR128:$dst),
952                           (ins VR128:$src),
953                           "movaps\t{$src, $dst|$dst, $src}", [],
954                           IIC_SSE_MOVA_P_RR>, VEX;
955   def VMOVAPDrr_REV : VPDI<0x29, MRMDestReg, (outs VR128:$dst),
956                            (ins VR128:$src),
957                            "movapd\t{$src, $dst|$dst, $src}", [],
958                            IIC_SSE_MOVA_P_RR>, VEX;
959   def VMOVUPSrr_REV : VPSI<0x11, MRMDestReg, (outs VR128:$dst),
960                            (ins VR128:$src),
961                            "movups\t{$src, $dst|$dst, $src}", [],
962                            IIC_SSE_MOVU_P_RR>, VEX;
963   def VMOVUPDrr_REV : VPDI<0x11, MRMDestReg, (outs VR128:$dst),
964                            (ins VR128:$src),
965                            "movupd\t{$src, $dst|$dst, $src}", [],
966                            IIC_SSE_MOVU_P_RR>, VEX;
967   def VMOVAPSYrr_REV : VPSI<0x29, MRMDestReg, (outs VR256:$dst),
968                             (ins VR256:$src),
969                             "movaps\t{$src, $dst|$dst, $src}", [],
970                             IIC_SSE_MOVA_P_RR>, VEX, VEX_L;
971   def VMOVAPDYrr_REV : VPDI<0x29, MRMDestReg, (outs VR256:$dst),
972                             (ins VR256:$src),
973                             "movapd\t{$src, $dst|$dst, $src}", [],
974                             IIC_SSE_MOVA_P_RR>, VEX, VEX_L;
975   def VMOVUPSYrr_REV : VPSI<0x11, MRMDestReg, (outs VR256:$dst),
976                             (ins VR256:$src),
977                             "movups\t{$src, $dst|$dst, $src}", [],
978                             IIC_SSE_MOVU_P_RR>, VEX, VEX_L;
979   def VMOVUPDYrr_REV : VPDI<0x11, MRMDestReg, (outs VR256:$dst),
980                             (ins VR256:$src),
981                             "movupd\t{$src, $dst|$dst, $src}", [],
982                             IIC_SSE_MOVU_P_RR>, VEX, VEX_L;
983 }
984
985 let Predicates = [HasAVX] in {
986 def : Pat<(v8i32 (X86vzmovl
987                   (insert_subvector undef, (v4i32 VR128:$src), (iPTR 0)))),
988           (SUBREG_TO_REG (i32 0), (VMOVAPSrr VR128:$src), sub_xmm)>;
989 def : Pat<(v4i64 (X86vzmovl
990                   (insert_subvector undef, (v2i64 VR128:$src), (iPTR 0)))),
991           (SUBREG_TO_REG (i32 0), (VMOVAPSrr VR128:$src), sub_xmm)>;
992 def : Pat<(v8f32 (X86vzmovl
993                   (insert_subvector undef, (v4f32 VR128:$src), (iPTR 0)))),
994           (SUBREG_TO_REG (i32 0), (VMOVAPSrr VR128:$src), sub_xmm)>;
995 def : Pat<(v4f64 (X86vzmovl
996                   (insert_subvector undef, (v2f64 VR128:$src), (iPTR 0)))),
997           (SUBREG_TO_REG (i32 0), (VMOVAPSrr VR128:$src), sub_xmm)>;
998 }
999
1000
1001 def : Pat<(int_x86_avx_storeu_ps_256 addr:$dst, VR256:$src),
1002           (VMOVUPSYmr addr:$dst, VR256:$src)>;
1003 def : Pat<(int_x86_avx_storeu_pd_256 addr:$dst, VR256:$src),
1004           (VMOVUPDYmr addr:$dst, VR256:$src)>;
1005
1006 let SchedRW = [WriteStore] in {
1007 def MOVAPSmr : PSI<0x29, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
1008                    "movaps\t{$src, $dst|$dst, $src}",
1009                    [(alignedstore (v4f32 VR128:$src), addr:$dst)],
1010                    IIC_SSE_MOVA_P_MR>;
1011 def MOVAPDmr : PDI<0x29, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
1012                    "movapd\t{$src, $dst|$dst, $src}",
1013                    [(alignedstore (v2f64 VR128:$src), addr:$dst)],
1014                    IIC_SSE_MOVA_P_MR>;
1015 def MOVUPSmr : PSI<0x11, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
1016                    "movups\t{$src, $dst|$dst, $src}",
1017                    [(store (v4f32 VR128:$src), addr:$dst)],
1018                    IIC_SSE_MOVU_P_MR>;
1019 def MOVUPDmr : PDI<0x11, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
1020                    "movupd\t{$src, $dst|$dst, $src}",
1021                    [(store (v2f64 VR128:$src), addr:$dst)],
1022                    IIC_SSE_MOVU_P_MR>;
1023 } // SchedRW
1024
1025 // For disassembler
1026 let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0,
1027     SchedRW = [WriteFShuffle] in {
1028   def MOVAPSrr_REV : PSI<0x29, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
1029                          "movaps\t{$src, $dst|$dst, $src}", [],
1030                          IIC_SSE_MOVA_P_RR>;
1031   def MOVAPDrr_REV : PDI<0x29, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
1032                          "movapd\t{$src, $dst|$dst, $src}", [],
1033                          IIC_SSE_MOVA_P_RR>;
1034   def MOVUPSrr_REV : PSI<0x11, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
1035                          "movups\t{$src, $dst|$dst, $src}", [],
1036                          IIC_SSE_MOVU_P_RR>;
1037   def MOVUPDrr_REV : PDI<0x11, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
1038                          "movupd\t{$src, $dst|$dst, $src}", [],
1039                          IIC_SSE_MOVU_P_RR>;
1040 }
1041
1042 let Predicates = [HasAVX] in {
1043   def : Pat<(int_x86_sse_storeu_ps addr:$dst, VR128:$src),
1044             (VMOVUPSmr addr:$dst, VR128:$src)>;
1045   def : Pat<(int_x86_sse2_storeu_pd addr:$dst, VR128:$src),
1046             (VMOVUPDmr addr:$dst, VR128:$src)>;
1047 }
1048
1049 let Predicates = [UseSSE1] in
1050   def : Pat<(int_x86_sse_storeu_ps addr:$dst, VR128:$src),
1051             (MOVUPSmr addr:$dst, VR128:$src)>;
1052 let Predicates = [UseSSE2] in
1053   def : Pat<(int_x86_sse2_storeu_pd addr:$dst, VR128:$src),
1054             (MOVUPDmr addr:$dst, VR128:$src)>;
1055
1056 // Use vmovaps/vmovups for AVX integer load/store.
1057 let Predicates = [HasAVX, NoVLX] in {
1058   // 128-bit load/store
1059   def : Pat<(alignedloadv2i64 addr:$src),
1060             (VMOVAPSrm addr:$src)>;
1061   def : Pat<(loadv2i64 addr:$src),
1062             (VMOVUPSrm addr:$src)>;
1063
1064   def : Pat<(alignedstore (v2i64 VR128:$src), addr:$dst),
1065             (VMOVAPSmr addr:$dst, VR128:$src)>;
1066   def : Pat<(alignedstore (v4i32 VR128:$src), addr:$dst),
1067             (VMOVAPSmr addr:$dst, VR128:$src)>;
1068   def : Pat<(alignedstore (v8i16 VR128:$src), addr:$dst),
1069             (VMOVAPSmr addr:$dst, VR128:$src)>;
1070   def : Pat<(alignedstore (v16i8 VR128:$src), addr:$dst),
1071             (VMOVAPSmr addr:$dst, VR128:$src)>;
1072   def : Pat<(store (v2i64 VR128:$src), addr:$dst),
1073             (VMOVUPSmr addr:$dst, VR128:$src)>;
1074   def : Pat<(store (v4i32 VR128:$src), addr:$dst),
1075             (VMOVUPSmr addr:$dst, VR128:$src)>;
1076   def : Pat<(store (v8i16 VR128:$src), addr:$dst),
1077             (VMOVUPSmr addr:$dst, VR128:$src)>;
1078   def : Pat<(store (v16i8 VR128:$src), addr:$dst),
1079             (VMOVUPSmr addr:$dst, VR128:$src)>;
1080
1081   // 256-bit load/store
1082   def : Pat<(alignedloadv4i64 addr:$src),
1083             (VMOVAPSYrm addr:$src)>;
1084   def : Pat<(loadv4i64 addr:$src),
1085             (VMOVUPSYrm addr:$src)>;
1086   def : Pat<(alignedstore256 (v4i64 VR256:$src), addr:$dst),
1087             (VMOVAPSYmr addr:$dst, VR256:$src)>;
1088   def : Pat<(alignedstore256 (v8i32 VR256:$src), addr:$dst),
1089             (VMOVAPSYmr addr:$dst, VR256:$src)>;
1090   def : Pat<(alignedstore256 (v16i16 VR256:$src), addr:$dst),
1091             (VMOVAPSYmr addr:$dst, VR256:$src)>;
1092   def : Pat<(alignedstore256 (v32i8 VR256:$src), addr:$dst),
1093             (VMOVAPSYmr addr:$dst, VR256:$src)>;
1094   def : Pat<(store (v4i64 VR256:$src), addr:$dst),
1095             (VMOVUPSYmr addr:$dst, VR256:$src)>;
1096   def : Pat<(store (v8i32 VR256:$src), addr:$dst),
1097             (VMOVUPSYmr addr:$dst, VR256:$src)>;
1098   def : Pat<(store (v16i16 VR256:$src), addr:$dst),
1099             (VMOVUPSYmr addr:$dst, VR256:$src)>;
1100   def : Pat<(store (v32i8 VR256:$src), addr:$dst),
1101             (VMOVUPSYmr addr:$dst, VR256:$src)>;
1102
1103   // Special patterns for storing subvector extracts of lower 128-bits
1104   // Its cheaper to just use VMOVAPS/VMOVUPS instead of VEXTRACTF128mr
1105   def : Pat<(alignedstore (v2f64 (extract_subvector
1106                                   (v4f64 VR256:$src), (iPTR 0))), addr:$dst),
1107             (VMOVAPDmr addr:$dst, (v2f64 (EXTRACT_SUBREG VR256:$src,sub_xmm)))>;
1108   def : Pat<(alignedstore (v4f32 (extract_subvector
1109                                   (v8f32 VR256:$src), (iPTR 0))), addr:$dst),
1110             (VMOVAPSmr addr:$dst, (v4f32 (EXTRACT_SUBREG VR256:$src,sub_xmm)))>;
1111   def : Pat<(alignedstore (v2i64 (extract_subvector
1112                                   (v4i64 VR256:$src), (iPTR 0))), addr:$dst),
1113             (VMOVAPDmr addr:$dst, (v2i64 (EXTRACT_SUBREG VR256:$src,sub_xmm)))>;
1114   def : Pat<(alignedstore (v4i32 (extract_subvector
1115                                   (v8i32 VR256:$src), (iPTR 0))), addr:$dst),
1116             (VMOVAPSmr addr:$dst, (v4i32 (EXTRACT_SUBREG VR256:$src,sub_xmm)))>;
1117   def : Pat<(alignedstore (v8i16 (extract_subvector
1118                                   (v16i16 VR256:$src), (iPTR 0))), addr:$dst),
1119             (VMOVAPSmr addr:$dst, (v8i16 (EXTRACT_SUBREG VR256:$src,sub_xmm)))>;
1120   def : Pat<(alignedstore (v16i8 (extract_subvector
1121                                   (v32i8 VR256:$src), (iPTR 0))), addr:$dst),
1122             (VMOVAPSmr addr:$dst, (v16i8 (EXTRACT_SUBREG VR256:$src,sub_xmm)))>;
1123
1124   def : Pat<(store (v2f64 (extract_subvector
1125                            (v4f64 VR256:$src), (iPTR 0))), addr:$dst),
1126             (VMOVUPDmr addr:$dst, (v2f64 (EXTRACT_SUBREG VR256:$src,sub_xmm)))>;
1127   def : Pat<(store (v4f32 (extract_subvector
1128                            (v8f32 VR256:$src), (iPTR 0))), addr:$dst),
1129             (VMOVUPSmr addr:$dst, (v4f32 (EXTRACT_SUBREG VR256:$src,sub_xmm)))>;
1130   def : Pat<(store (v2i64 (extract_subvector
1131                            (v4i64 VR256:$src), (iPTR 0))), addr:$dst),
1132             (VMOVUPDmr addr:$dst, (v2i64 (EXTRACT_SUBREG VR256:$src,sub_xmm)))>;
1133   def : Pat<(store (v4i32 (extract_subvector
1134                            (v8i32 VR256:$src), (iPTR 0))), addr:$dst),
1135             (VMOVUPSmr addr:$dst, (v4i32 (EXTRACT_SUBREG VR256:$src,sub_xmm)))>;
1136   def : Pat<(store (v8i16 (extract_subvector
1137                            (v16i16 VR256:$src), (iPTR 0))), addr:$dst),
1138             (VMOVUPSmr addr:$dst, (v8i16 (EXTRACT_SUBREG VR256:$src,sub_xmm)))>;
1139   def : Pat<(store (v16i8 (extract_subvector
1140                            (v32i8 VR256:$src), (iPTR 0))), addr:$dst),
1141             (VMOVUPSmr addr:$dst, (v16i8 (EXTRACT_SUBREG VR256:$src,sub_xmm)))>;
1142 }
1143
1144 // Use movaps / movups for SSE integer load / store (one byte shorter).
1145 // The instructions selected below are then converted to MOVDQA/MOVDQU
1146 // during the SSE domain pass.
1147 let Predicates = [UseSSE1] in {
1148   def : Pat<(alignedloadv2i64 addr:$src),
1149             (MOVAPSrm addr:$src)>;
1150   def : Pat<(loadv2i64 addr:$src),
1151             (MOVUPSrm addr:$src)>;
1152
1153   def : Pat<(alignedstore (v2i64 VR128:$src), addr:$dst),
1154             (MOVAPSmr addr:$dst, VR128:$src)>;
1155   def : Pat<(alignedstore (v4i32 VR128:$src), addr:$dst),
1156             (MOVAPSmr addr:$dst, VR128:$src)>;
1157   def : Pat<(alignedstore (v8i16 VR128:$src), addr:$dst),
1158             (MOVAPSmr addr:$dst, VR128:$src)>;
1159   def : Pat<(alignedstore (v16i8 VR128:$src), addr:$dst),
1160             (MOVAPSmr addr:$dst, VR128:$src)>;
1161   def : Pat<(store (v2i64 VR128:$src), addr:$dst),
1162             (MOVUPSmr addr:$dst, VR128:$src)>;
1163   def : Pat<(store (v4i32 VR128:$src), addr:$dst),
1164             (MOVUPSmr addr:$dst, VR128:$src)>;
1165   def : Pat<(store (v8i16 VR128:$src), addr:$dst),
1166             (MOVUPSmr addr:$dst, VR128:$src)>;
1167   def : Pat<(store (v16i8 VR128:$src), addr:$dst),
1168             (MOVUPSmr addr:$dst, VR128:$src)>;
1169 }
1170
1171 // Alias instruction to load FR32 or FR64 from f128mem using movaps. Upper
1172 // bits are disregarded. FIXME: Set encoding to pseudo!
1173 let canFoldAsLoad = 1, isReMaterializable = 1, SchedRW = [WriteLoad] in {
1174 let isCodeGenOnly = 1 in {
1175   def FsVMOVAPSrm : VPSI<0x28, MRMSrcMem, (outs FR32:$dst), (ins f128mem:$src),
1176                          "movaps\t{$src, $dst|$dst, $src}",
1177                          [(set FR32:$dst, (alignedloadfsf32 addr:$src))],
1178                          IIC_SSE_MOVA_P_RM>, VEX;
1179   def FsVMOVAPDrm : VPDI<0x28, MRMSrcMem, (outs FR64:$dst), (ins f128mem:$src),
1180                          "movapd\t{$src, $dst|$dst, $src}",
1181                          [(set FR64:$dst, (alignedloadfsf64 addr:$src))],
1182                          IIC_SSE_MOVA_P_RM>, VEX;
1183   def FsMOVAPSrm : PSI<0x28, MRMSrcMem, (outs FR32:$dst), (ins f128mem:$src),
1184                        "movaps\t{$src, $dst|$dst, $src}",
1185                        [(set FR32:$dst, (alignedloadfsf32 addr:$src))],
1186                        IIC_SSE_MOVA_P_RM>;
1187   def FsMOVAPDrm : PDI<0x28, MRMSrcMem, (outs FR64:$dst), (ins f128mem:$src),
1188                        "movapd\t{$src, $dst|$dst, $src}",
1189                        [(set FR64:$dst, (alignedloadfsf64 addr:$src))],
1190                        IIC_SSE_MOVA_P_RM>;
1191 }
1192 }
1193
1194 //===----------------------------------------------------------------------===//
1195 // SSE 1 & 2 - Move Low packed FP Instructions
1196 //===----------------------------------------------------------------------===//
1197
1198 multiclass sse12_mov_hilo_packed_base<bits<8>opc, SDNode psnode, SDNode pdnode,
1199                                       string base_opc, string asm_opr,
1200                                       InstrItinClass itin> {
1201   def PSrm : PI<opc, MRMSrcMem,
1202          (outs VR128:$dst), (ins VR128:$src1, f64mem:$src2),
1203          !strconcat(base_opc, "s", asm_opr),
1204      [(set VR128:$dst,
1205        (psnode VR128:$src1,
1206               (bc_v4f32 (v2f64 (scalar_to_vector (loadf64 addr:$src2))))))],
1207               itin, SSEPackedSingle>, PS,
1208      Sched<[WriteFShuffleLd, ReadAfterLd]>;
1209
1210   def PDrm : PI<opc, MRMSrcMem,
1211          (outs VR128:$dst), (ins VR128:$src1, f64mem:$src2),
1212          !strconcat(base_opc, "d", asm_opr),
1213      [(set VR128:$dst, (v2f64 (pdnode VR128:$src1,
1214                               (scalar_to_vector (loadf64 addr:$src2)))))],
1215               itin, SSEPackedDouble>, PD,
1216      Sched<[WriteFShuffleLd, ReadAfterLd]>;
1217
1218 }
1219
1220 multiclass sse12_mov_hilo_packed<bits<8>opc, SDNode psnode, SDNode pdnode,
1221                                  string base_opc, InstrItinClass itin> {
1222   defm V#NAME : sse12_mov_hilo_packed_base<opc, psnode, pdnode, base_opc,
1223                                     "\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1224                                     itin>, VEX_4V;
1225
1226 let Constraints = "$src1 = $dst" in
1227   defm NAME : sse12_mov_hilo_packed_base<opc, psnode, pdnode, base_opc,
1228                                     "\t{$src2, $dst|$dst, $src2}",
1229                                     itin>;
1230 }
1231
1232 let AddedComplexity = 20 in {
1233   defm MOVL : sse12_mov_hilo_packed<0x12, X86Movlps, X86Movlpd, "movlp",
1234                                     IIC_SSE_MOV_LH>;
1235 }
1236
1237 let SchedRW = [WriteStore] in {
1238 def VMOVLPSmr : VPSI<0x13, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
1239                    "movlps\t{$src, $dst|$dst, $src}",
1240                    [(store (f64 (vector_extract (bc_v2f64 (v4f32 VR128:$src)),
1241                                  (iPTR 0))), addr:$dst)],
1242                                  IIC_SSE_MOV_LH>, VEX;
1243 def VMOVLPDmr : VPDI<0x13, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
1244                    "movlpd\t{$src, $dst|$dst, $src}",
1245                    [(store (f64 (vector_extract (v2f64 VR128:$src),
1246                                  (iPTR 0))), addr:$dst)],
1247                                  IIC_SSE_MOV_LH>, VEX;
1248 def MOVLPSmr : PSI<0x13, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
1249                    "movlps\t{$src, $dst|$dst, $src}",
1250                    [(store (f64 (vector_extract (bc_v2f64 (v4f32 VR128:$src)),
1251                                  (iPTR 0))), addr:$dst)],
1252                                  IIC_SSE_MOV_LH>;
1253 def MOVLPDmr : PDI<0x13, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
1254                    "movlpd\t{$src, $dst|$dst, $src}",
1255                    [(store (f64 (vector_extract (v2f64 VR128:$src),
1256                                  (iPTR 0))), addr:$dst)],
1257                                  IIC_SSE_MOV_LH>;
1258 } // SchedRW
1259
1260 let Predicates = [HasAVX] in {
1261   // Shuffle with VMOVLPS
1262   def : Pat<(v4f32 (X86Movlps VR128:$src1, (load addr:$src2))),
1263             (VMOVLPSrm VR128:$src1, addr:$src2)>;
1264   def : Pat<(v4i32 (X86Movlps VR128:$src1, (load addr:$src2))),
1265             (VMOVLPSrm VR128:$src1, addr:$src2)>;
1266
1267   // Shuffle with VMOVLPD
1268   def : Pat<(v2f64 (X86Movlpd VR128:$src1, (load addr:$src2))),
1269             (VMOVLPDrm VR128:$src1, addr:$src2)>;
1270   def : Pat<(v2i64 (X86Movlpd VR128:$src1, (load addr:$src2))),
1271             (VMOVLPDrm VR128:$src1, addr:$src2)>;
1272   def : Pat<(v2f64 (X86Movsd VR128:$src1,
1273                              (v2f64 (scalar_to_vector (loadf64 addr:$src2))))),
1274             (VMOVLPDrm VR128:$src1, addr:$src2)>;
1275
1276   // Store patterns
1277   def : Pat<(store (v4f32 (X86Movlps (load addr:$src1), VR128:$src2)),
1278                    addr:$src1),
1279             (VMOVLPSmr addr:$src1, VR128:$src2)>;
1280   def : Pat<(store (v4i32 (X86Movlps
1281                    (bc_v4i32 (loadv2i64 addr:$src1)), VR128:$src2)), addr:$src1),
1282             (VMOVLPSmr addr:$src1, VR128:$src2)>;
1283   def : Pat<(store (v2f64 (X86Movlpd (load addr:$src1), VR128:$src2)),
1284                    addr:$src1),
1285             (VMOVLPDmr addr:$src1, VR128:$src2)>;
1286   def : Pat<(store (v2i64 (X86Movlpd (load addr:$src1), VR128:$src2)),
1287                    addr:$src1),
1288             (VMOVLPDmr addr:$src1, VR128:$src2)>;
1289 }
1290
1291 let Predicates = [UseSSE1] in {
1292   // (store (vector_shuffle (load addr), v2, <4, 5, 2, 3>), addr) using MOVLPS
1293   def : Pat<(store (i64 (vector_extract (bc_v2i64 (v4f32 VR128:$src2)),
1294                                  (iPTR 0))), addr:$src1),
1295             (MOVLPSmr addr:$src1, VR128:$src2)>;
1296
1297   // Shuffle with MOVLPS
1298   def : Pat<(v4f32 (X86Movlps VR128:$src1, (load addr:$src2))),
1299             (MOVLPSrm VR128:$src1, addr:$src2)>;
1300   def : Pat<(v4i32 (X86Movlps VR128:$src1, (load addr:$src2))),
1301             (MOVLPSrm VR128:$src1, addr:$src2)>;
1302   def : Pat<(X86Movlps VR128:$src1,
1303                       (bc_v4f32 (v2i64 (scalar_to_vector (loadi64 addr:$src2))))),
1304             (MOVLPSrm VR128:$src1, addr:$src2)>;
1305
1306   // Store patterns
1307   def : Pat<(store (v4f32 (X86Movlps (load addr:$src1), VR128:$src2)),
1308                                       addr:$src1),
1309             (MOVLPSmr addr:$src1, VR128:$src2)>;
1310   def : Pat<(store (v4i32 (X86Movlps
1311                    (bc_v4i32 (loadv2i64 addr:$src1)), VR128:$src2)),
1312                               addr:$src1),
1313             (MOVLPSmr addr:$src1, VR128:$src2)>;
1314 }
1315
1316 let Predicates = [UseSSE2] in {
1317   // Shuffle with MOVLPD
1318   def : Pat<(v2f64 (X86Movlpd VR128:$src1, (load addr:$src2))),
1319             (MOVLPDrm VR128:$src1, addr:$src2)>;
1320   def : Pat<(v2i64 (X86Movlpd VR128:$src1, (load addr:$src2))),
1321             (MOVLPDrm VR128:$src1, addr:$src2)>;
1322   def : Pat<(v2f64 (X86Movsd VR128:$src1,
1323                              (v2f64 (scalar_to_vector (loadf64 addr:$src2))))),
1324             (MOVLPDrm VR128:$src1, addr:$src2)>;
1325
1326   // Store patterns
1327   def : Pat<(store (v2f64 (X86Movlpd (load addr:$src1), VR128:$src2)),
1328                            addr:$src1),
1329             (MOVLPDmr addr:$src1, VR128:$src2)>;
1330   def : Pat<(store (v2i64 (X86Movlpd (load addr:$src1), VR128:$src2)),
1331                            addr:$src1),
1332             (MOVLPDmr addr:$src1, VR128:$src2)>;
1333 }
1334
1335 //===----------------------------------------------------------------------===//
1336 // SSE 1 & 2 - Move Hi packed FP Instructions
1337 //===----------------------------------------------------------------------===//
1338
1339 let AddedComplexity = 20 in {
1340   defm MOVH : sse12_mov_hilo_packed<0x16, X86Movlhps, X86Movlhpd, "movhp",
1341                                     IIC_SSE_MOV_LH>;
1342 }
1343
1344 let SchedRW = [WriteStore] in {
1345 // v2f64 extract element 1 is always custom lowered to unpack high to low
1346 // and extract element 0 so the non-store version isn't too horrible.
1347 def VMOVHPSmr : VPSI<0x17, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
1348                    "movhps\t{$src, $dst|$dst, $src}",
1349                    [(store (f64 (vector_extract
1350                                  (X86Unpckh (bc_v2f64 (v4f32 VR128:$src)),
1351                                             (bc_v2f64 (v4f32 VR128:$src))),
1352                                  (iPTR 0))), addr:$dst)], IIC_SSE_MOV_LH>, VEX;
1353 def VMOVHPDmr : VPDI<0x17, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
1354                    "movhpd\t{$src, $dst|$dst, $src}",
1355                    [(store (f64 (vector_extract
1356                                  (v2f64 (X86Unpckh VR128:$src, VR128:$src)),
1357                                  (iPTR 0))), addr:$dst)], IIC_SSE_MOV_LH>, VEX;
1358 def MOVHPSmr : PSI<0x17, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
1359                    "movhps\t{$src, $dst|$dst, $src}",
1360                    [(store (f64 (vector_extract
1361                                  (X86Unpckh (bc_v2f64 (v4f32 VR128:$src)),
1362                                             (bc_v2f64 (v4f32 VR128:$src))),
1363                                  (iPTR 0))), addr:$dst)], IIC_SSE_MOV_LH>;
1364 def MOVHPDmr : PDI<0x17, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
1365                    "movhpd\t{$src, $dst|$dst, $src}",
1366                    [(store (f64 (vector_extract
1367                                  (v2f64 (X86Unpckh VR128:$src, VR128:$src)),
1368                                  (iPTR 0))), addr:$dst)], IIC_SSE_MOV_LH>;
1369 } // SchedRW
1370
1371 let Predicates = [HasAVX] in {
1372   // VMOVHPS patterns
1373   def : Pat<(X86Movlhps VR128:$src1,
1374                  (bc_v4f32 (v2i64 (scalar_to_vector (loadi64 addr:$src2))))),
1375             (VMOVHPSrm VR128:$src1, addr:$src2)>;
1376   def : Pat<(X86Movlhps VR128:$src1,
1377                  (bc_v4i32 (v2i64 (X86vzload addr:$src2)))),
1378             (VMOVHPSrm VR128:$src1, addr:$src2)>;
1379
1380   // FIXME: Instead of X86Unpckl, there should be a X86Movlhpd here, the problem
1381   // is during lowering, where it's not possible to recognize the load fold
1382   // cause it has two uses through a bitcast. One use disappears at isel time
1383   // and the fold opportunity reappears.
1384   def : Pat<(v2f64 (X86Unpckl VR128:$src1,
1385                       (scalar_to_vector (loadf64 addr:$src2)))),
1386             (VMOVHPDrm VR128:$src1, addr:$src2)>;
1387   // Also handle an i64 load because that may get selected as a faster way to
1388   // load the data.
1389   def : Pat<(v2f64 (X86Unpckl VR128:$src1,
1390                       (bc_v2f64 (v2i64 (scalar_to_vector (loadi64 addr:$src2)))))),
1391             (VMOVHPDrm VR128:$src1, addr:$src2)>;
1392 }
1393
1394 let Predicates = [UseSSE1] in {
1395   // MOVHPS patterns
1396   def : Pat<(X86Movlhps VR128:$src1,
1397                  (bc_v4f32 (v2i64 (scalar_to_vector (loadi64 addr:$src2))))),
1398             (MOVHPSrm VR128:$src1, addr:$src2)>;
1399   def : Pat<(X86Movlhps VR128:$src1,
1400                  (bc_v4f32 (v2i64 (X86vzload addr:$src2)))),
1401             (MOVHPSrm VR128:$src1, addr:$src2)>;
1402 }
1403
1404 let Predicates = [UseSSE2] in {
1405   // FIXME: Instead of X86Unpckl, there should be a X86Movlhpd here, the problem
1406   // is during lowering, where it's not possible to recognize the load fold
1407   // cause it has two uses through a bitcast. One use disappears at isel time
1408   // and the fold opportunity reappears.
1409   def : Pat<(v2f64 (X86Unpckl VR128:$src1,
1410                       (scalar_to_vector (loadf64 addr:$src2)))),
1411             (MOVHPDrm VR128:$src1, addr:$src2)>;
1412   // Also handle an i64 load because that may get selected as a faster way to
1413   // load the data.
1414   def : Pat<(v2f64 (X86Unpckl VR128:$src1,
1415                       (bc_v2f64 (v2i64 (scalar_to_vector (loadi64 addr:$src2)))))),
1416             (MOVHPDrm VR128:$src1, addr:$src2)>;
1417 }
1418
1419 //===----------------------------------------------------------------------===//
1420 // SSE 1 & 2 - Move Low to High and High to Low packed FP Instructions
1421 //===----------------------------------------------------------------------===//
1422
1423 let AddedComplexity = 20, Predicates = [UseAVX] in {
1424   def VMOVLHPSrr : VPSI<0x16, MRMSrcReg, (outs VR128:$dst),
1425                                        (ins VR128:$src1, VR128:$src2),
1426                       "movlhps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1427                       [(set VR128:$dst,
1428                         (v4f32 (X86Movlhps VR128:$src1, VR128:$src2)))],
1429                         IIC_SSE_MOV_LH>,
1430                       VEX_4V, Sched<[WriteFShuffle]>;
1431   def VMOVHLPSrr : VPSI<0x12, MRMSrcReg, (outs VR128:$dst),
1432                                        (ins VR128:$src1, VR128:$src2),
1433                       "movhlps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1434                       [(set VR128:$dst,
1435                         (v4f32 (X86Movhlps VR128:$src1, VR128:$src2)))],
1436                         IIC_SSE_MOV_LH>,
1437                       VEX_4V, Sched<[WriteFShuffle]>;
1438 }
1439 let Constraints = "$src1 = $dst", AddedComplexity = 20 in {
1440   def MOVLHPSrr : PSI<0x16, MRMSrcReg, (outs VR128:$dst),
1441                                        (ins VR128:$src1, VR128:$src2),
1442                       "movlhps\t{$src2, $dst|$dst, $src2}",
1443                       [(set VR128:$dst,
1444                         (v4f32 (X86Movlhps VR128:$src1, VR128:$src2)))],
1445                         IIC_SSE_MOV_LH>, Sched<[WriteFShuffle]>;
1446   def MOVHLPSrr : PSI<0x12, MRMSrcReg, (outs VR128:$dst),
1447                                        (ins VR128:$src1, VR128:$src2),
1448                       "movhlps\t{$src2, $dst|$dst, $src2}",
1449                       [(set VR128:$dst,
1450                         (v4f32 (X86Movhlps VR128:$src1, VR128:$src2)))],
1451                         IIC_SSE_MOV_LH>, Sched<[WriteFShuffle]>;
1452 }
1453
1454 let Predicates = [UseAVX] in {
1455   // MOVLHPS patterns
1456   def : Pat<(v4i32 (X86Movlhps VR128:$src1, VR128:$src2)),
1457             (VMOVLHPSrr VR128:$src1, VR128:$src2)>;
1458   def : Pat<(v2i64 (X86Movlhps VR128:$src1, VR128:$src2)),
1459             (VMOVLHPSrr (v2i64 VR128:$src1), VR128:$src2)>;
1460
1461   // MOVHLPS patterns
1462   def : Pat<(v4i32 (X86Movhlps VR128:$src1, VR128:$src2)),
1463             (VMOVHLPSrr VR128:$src1, VR128:$src2)>;
1464 }
1465
1466 let Predicates = [UseSSE1] in {
1467   // MOVLHPS patterns
1468   def : Pat<(v4i32 (X86Movlhps VR128:$src1, VR128:$src2)),
1469             (MOVLHPSrr VR128:$src1, VR128:$src2)>;
1470   def : Pat<(v2i64 (X86Movlhps VR128:$src1, VR128:$src2)),
1471             (MOVLHPSrr (v2i64 VR128:$src1), VR128:$src2)>;
1472
1473   // MOVHLPS patterns
1474   def : Pat<(v4i32 (X86Movhlps VR128:$src1, VR128:$src2)),
1475             (MOVHLPSrr VR128:$src1, VR128:$src2)>;
1476 }
1477
1478 //===----------------------------------------------------------------------===//
1479 // SSE 1 & 2 - Conversion Instructions
1480 //===----------------------------------------------------------------------===//
1481
1482 def SSE_CVT_PD : OpndItins<
1483   IIC_SSE_CVT_PD_RR, IIC_SSE_CVT_PD_RM
1484 >;
1485
1486 let Sched = WriteCvtI2F in
1487 def SSE_CVT_PS : OpndItins<
1488   IIC_SSE_CVT_PS_RR, IIC_SSE_CVT_PS_RM
1489 >;
1490
1491 let Sched = WriteCvtI2F in
1492 def SSE_CVT_Scalar : OpndItins<
1493   IIC_SSE_CVT_Scalar_RR, IIC_SSE_CVT_Scalar_RM
1494 >;
1495
1496 let Sched = WriteCvtF2I in
1497 def SSE_CVT_SS2SI_32 : OpndItins<
1498   IIC_SSE_CVT_SS2SI32_RR, IIC_SSE_CVT_SS2SI32_RM
1499 >;
1500
1501 let Sched = WriteCvtF2I in
1502 def SSE_CVT_SS2SI_64 : OpndItins<
1503   IIC_SSE_CVT_SS2SI64_RR, IIC_SSE_CVT_SS2SI64_RM
1504 >;
1505
1506 let Sched = WriteCvtF2I in
1507 def SSE_CVT_SD2SI : OpndItins<
1508   IIC_SSE_CVT_SD2SI_RR, IIC_SSE_CVT_SD2SI_RM
1509 >;
1510
1511 multiclass sse12_cvt_s<bits<8> opc, RegisterClass SrcRC, RegisterClass DstRC,
1512                      SDNode OpNode, X86MemOperand x86memop, PatFrag ld_frag,
1513                      string asm, OpndItins itins> {
1514   def rr : SI<opc, MRMSrcReg, (outs DstRC:$dst), (ins SrcRC:$src), asm,
1515                         [(set DstRC:$dst, (OpNode SrcRC:$src))],
1516                         itins.rr>, Sched<[itins.Sched]>;
1517   def rm : SI<opc, MRMSrcMem, (outs DstRC:$dst), (ins x86memop:$src), asm,
1518                         [(set DstRC:$dst, (OpNode (ld_frag addr:$src)))],
1519                         itins.rm>, Sched<[itins.Sched.Folded]>;
1520 }
1521
1522 multiclass sse12_cvt_p<bits<8> opc, RegisterClass SrcRC, RegisterClass DstRC,
1523                        X86MemOperand x86memop, string asm, Domain d,
1524                        OpndItins itins> {
1525 let neverHasSideEffects = 1 in {
1526   def rr : I<opc, MRMSrcReg, (outs DstRC:$dst), (ins SrcRC:$src), asm,
1527              [], itins.rr, d>, Sched<[itins.Sched]>;
1528   let mayLoad = 1 in
1529   def rm : I<opc, MRMSrcMem, (outs DstRC:$dst), (ins x86memop:$src), asm,
1530              [], itins.rm, d>, Sched<[itins.Sched.Folded]>;
1531 }
1532 }
1533
1534 multiclass sse12_vcvt_avx<bits<8> opc, RegisterClass SrcRC, RegisterClass DstRC,
1535                           X86MemOperand x86memop, string asm> {
1536 let neverHasSideEffects = 1, Predicates = [UseAVX] in {
1537   def rr : SI<opc, MRMSrcReg, (outs DstRC:$dst), (ins DstRC:$src1, SrcRC:$src),
1538               !strconcat(asm,"\t{$src, $src1, $dst|$dst, $src1, $src}"), []>,
1539            Sched<[WriteCvtI2F]>;
1540   let mayLoad = 1 in
1541   def rm : SI<opc, MRMSrcMem, (outs DstRC:$dst),
1542               (ins DstRC:$src1, x86memop:$src),
1543               !strconcat(asm,"\t{$src, $src1, $dst|$dst, $src1, $src}"), []>,
1544            Sched<[WriteCvtI2FLd, ReadAfterLd]>;
1545 } // neverHasSideEffects = 1
1546 }
1547
1548 let Predicates = [UseAVX] in {
1549 defm VCVTTSS2SI   : sse12_cvt_s<0x2C, FR32, GR32, fp_to_sint, f32mem, loadf32,
1550                                 "cvttss2si\t{$src, $dst|$dst, $src}",
1551                                 SSE_CVT_SS2SI_32>,
1552                                 XS, VEX, VEX_LIG;
1553 defm VCVTTSS2SI64 : sse12_cvt_s<0x2C, FR32, GR64, fp_to_sint, f32mem, loadf32,
1554                                 "cvttss2si\t{$src, $dst|$dst, $src}",
1555                                 SSE_CVT_SS2SI_64>,
1556                                 XS, VEX, VEX_W, VEX_LIG;
1557 defm VCVTTSD2SI   : sse12_cvt_s<0x2C, FR64, GR32, fp_to_sint, f64mem, loadf64,
1558                                 "cvttsd2si\t{$src, $dst|$dst, $src}",
1559                                 SSE_CVT_SD2SI>,
1560                                 XD, VEX, VEX_LIG;
1561 defm VCVTTSD2SI64 : sse12_cvt_s<0x2C, FR64, GR64, fp_to_sint, f64mem, loadf64,
1562                                 "cvttsd2si\t{$src, $dst|$dst, $src}",
1563                                 SSE_CVT_SD2SI>,
1564                                 XD, VEX, VEX_W, VEX_LIG;
1565
1566 def : InstAlias<"vcvttss2si{l}\t{$src, $dst|$dst, $src}",
1567                 (VCVTTSS2SIrr GR32:$dst, FR32:$src), 0>;
1568 def : InstAlias<"vcvttss2si{l}\t{$src, $dst|$dst, $src}",
1569                 (VCVTTSS2SIrm GR32:$dst, f32mem:$src), 0>;
1570 def : InstAlias<"vcvttsd2si{l}\t{$src, $dst|$dst, $src}",
1571                 (VCVTTSD2SIrr GR32:$dst, FR64:$src), 0>;
1572 def : InstAlias<"vcvttsd2si{l}\t{$src, $dst|$dst, $src}",
1573                 (VCVTTSD2SIrm GR32:$dst, f64mem:$src), 0>;
1574 def : InstAlias<"vcvttss2si{q}\t{$src, $dst|$dst, $src}",
1575                 (VCVTTSS2SI64rr GR64:$dst, FR32:$src), 0>;
1576 def : InstAlias<"vcvttss2si{q}\t{$src, $dst|$dst, $src}",
1577                 (VCVTTSS2SI64rm GR64:$dst, f32mem:$src), 0>;
1578 def : InstAlias<"vcvttsd2si{q}\t{$src, $dst|$dst, $src}",
1579                 (VCVTTSD2SI64rr GR64:$dst, FR64:$src), 0>;
1580 def : InstAlias<"vcvttsd2si{q}\t{$src, $dst|$dst, $src}",
1581                 (VCVTTSD2SI64rm GR64:$dst, f64mem:$src), 0>;
1582 }
1583 // The assembler can recognize rr 64-bit instructions by seeing a rxx
1584 // register, but the same isn't true when only using memory operands,
1585 // provide other assembly "l" and "q" forms to address this explicitly
1586 // where appropriate to do so.
1587 defm VCVTSI2SS   : sse12_vcvt_avx<0x2A, GR32, FR32, i32mem, "cvtsi2ss{l}">,
1588                                   XS, VEX_4V, VEX_LIG;
1589 defm VCVTSI2SS64 : sse12_vcvt_avx<0x2A, GR64, FR32, i64mem, "cvtsi2ss{q}">,
1590                                   XS, VEX_4V, VEX_W, VEX_LIG;
1591 defm VCVTSI2SD   : sse12_vcvt_avx<0x2A, GR32, FR64, i32mem, "cvtsi2sd{l}">,
1592                                   XD, VEX_4V, VEX_LIG;
1593 defm VCVTSI2SD64 : sse12_vcvt_avx<0x2A, GR64, FR64, i64mem, "cvtsi2sd{q}">,
1594                                   XD, VEX_4V, VEX_W, VEX_LIG;
1595
1596 let Predicates = [UseAVX] in {
1597   def : InstAlias<"vcvtsi2ss\t{$src, $src1, $dst|$dst, $src1, $src}",
1598                 (VCVTSI2SSrm FR64:$dst, FR64:$src1, i32mem:$src), 0>;
1599   def : InstAlias<"vcvtsi2sd\t{$src, $src1, $dst|$dst, $src1, $src}",
1600                 (VCVTSI2SDrm FR64:$dst, FR64:$src1, i32mem:$src), 0>;
1601
1602   def : Pat<(f32 (sint_to_fp (loadi32 addr:$src))),
1603             (VCVTSI2SSrm (f32 (IMPLICIT_DEF)), addr:$src)>;
1604   def : Pat<(f32 (sint_to_fp (loadi64 addr:$src))),
1605             (VCVTSI2SS64rm (f32 (IMPLICIT_DEF)), addr:$src)>;
1606   def : Pat<(f64 (sint_to_fp (loadi32 addr:$src))),
1607             (VCVTSI2SDrm (f64 (IMPLICIT_DEF)), addr:$src)>;
1608   def : Pat<(f64 (sint_to_fp (loadi64 addr:$src))),
1609             (VCVTSI2SD64rm (f64 (IMPLICIT_DEF)), addr:$src)>;
1610
1611   def : Pat<(f32 (sint_to_fp GR32:$src)),
1612             (VCVTSI2SSrr (f32 (IMPLICIT_DEF)), GR32:$src)>;
1613   def : Pat<(f32 (sint_to_fp GR64:$src)),
1614             (VCVTSI2SS64rr (f32 (IMPLICIT_DEF)), GR64:$src)>;
1615   def : Pat<(f64 (sint_to_fp GR32:$src)),
1616             (VCVTSI2SDrr (f64 (IMPLICIT_DEF)), GR32:$src)>;
1617   def : Pat<(f64 (sint_to_fp GR64:$src)),
1618             (VCVTSI2SD64rr (f64 (IMPLICIT_DEF)), GR64:$src)>;
1619 }
1620
1621 defm CVTTSS2SI : sse12_cvt_s<0x2C, FR32, GR32, fp_to_sint, f32mem, loadf32,
1622                       "cvttss2si\t{$src, $dst|$dst, $src}",
1623                       SSE_CVT_SS2SI_32>, XS;
1624 defm CVTTSS2SI64 : sse12_cvt_s<0x2C, FR32, GR64, fp_to_sint, f32mem, loadf32,
1625                       "cvttss2si\t{$src, $dst|$dst, $src}",
1626                       SSE_CVT_SS2SI_64>, XS, REX_W;
1627 defm CVTTSD2SI : sse12_cvt_s<0x2C, FR64, GR32, fp_to_sint, f64mem, loadf64,
1628                       "cvttsd2si\t{$src, $dst|$dst, $src}",
1629                       SSE_CVT_SD2SI>, XD;
1630 defm CVTTSD2SI64 : sse12_cvt_s<0x2C, FR64, GR64, fp_to_sint, f64mem, loadf64,
1631                       "cvttsd2si\t{$src, $dst|$dst, $src}",
1632                       SSE_CVT_SD2SI>, XD, REX_W;
1633 defm CVTSI2SS  : sse12_cvt_s<0x2A, GR32, FR32, sint_to_fp, i32mem, loadi32,
1634                       "cvtsi2ss{l}\t{$src, $dst|$dst, $src}",
1635                       SSE_CVT_Scalar>, XS;
1636 defm CVTSI2SS64 : sse12_cvt_s<0x2A, GR64, FR32, sint_to_fp, i64mem, loadi64,
1637                       "cvtsi2ss{q}\t{$src, $dst|$dst, $src}",
1638                       SSE_CVT_Scalar>, XS, REX_W;
1639 defm CVTSI2SD  : sse12_cvt_s<0x2A, GR32, FR64, sint_to_fp, i32mem, loadi32,
1640                       "cvtsi2sd{l}\t{$src, $dst|$dst, $src}",
1641                       SSE_CVT_Scalar>, XD;
1642 defm CVTSI2SD64 : sse12_cvt_s<0x2A, GR64, FR64, sint_to_fp, i64mem, loadi64,
1643                       "cvtsi2sd{q}\t{$src, $dst|$dst, $src}",
1644                       SSE_CVT_Scalar>, XD, REX_W;
1645
1646 def : InstAlias<"cvttss2si{l}\t{$src, $dst|$dst, $src}",
1647                 (CVTTSS2SIrr GR32:$dst, FR32:$src), 0>;
1648 def : InstAlias<"cvttss2si{l}\t{$src, $dst|$dst, $src}",
1649                 (CVTTSS2SIrm GR32:$dst, f32mem:$src), 0>;
1650 def : InstAlias<"cvttsd2si{l}\t{$src, $dst|$dst, $src}",
1651                 (CVTTSD2SIrr GR32:$dst, FR64:$src), 0>;
1652 def : InstAlias<"cvttsd2si{l}\t{$src, $dst|$dst, $src}",
1653                 (CVTTSD2SIrm GR32:$dst, f64mem:$src), 0>;
1654 def : InstAlias<"cvttss2si{q}\t{$src, $dst|$dst, $src}",
1655                 (CVTTSS2SI64rr GR64:$dst, FR32:$src), 0>;
1656 def : InstAlias<"cvttss2si{q}\t{$src, $dst|$dst, $src}",
1657                 (CVTTSS2SI64rm GR64:$dst, f32mem:$src), 0>;
1658 def : InstAlias<"cvttsd2si{q}\t{$src, $dst|$dst, $src}",
1659                 (CVTTSD2SI64rr GR64:$dst, FR64:$src), 0>;
1660 def : InstAlias<"cvttsd2si{q}\t{$src, $dst|$dst, $src}",
1661                 (CVTTSD2SI64rm GR64:$dst, f64mem:$src), 0>;
1662
1663 def : InstAlias<"cvtsi2ss\t{$src, $dst|$dst, $src}",
1664                 (CVTSI2SSrm FR64:$dst, i32mem:$src), 0>;
1665 def : InstAlias<"cvtsi2sd\t{$src, $dst|$dst, $src}",
1666                 (CVTSI2SDrm FR64:$dst, i32mem:$src), 0>;
1667
1668 // Conversion Instructions Intrinsics - Match intrinsics which expect MM
1669 // and/or XMM operand(s).
1670
1671 multiclass sse12_cvt_sint<bits<8> opc, RegisterClass SrcRC, RegisterClass DstRC,
1672                          Intrinsic Int, Operand memop, ComplexPattern mem_cpat,
1673                          string asm, OpndItins itins> {
1674   def rr : SI<opc, MRMSrcReg, (outs DstRC:$dst), (ins SrcRC:$src),
1675               !strconcat(asm, "\t{$src, $dst|$dst, $src}"),
1676               [(set DstRC:$dst, (Int SrcRC:$src))], itins.rr>,
1677            Sched<[itins.Sched]>;
1678   def rm : SI<opc, MRMSrcMem, (outs DstRC:$dst), (ins memop:$src),
1679               !strconcat(asm, "\t{$src, $dst|$dst, $src}"),
1680               [(set DstRC:$dst, (Int mem_cpat:$src))], itins.rm>,
1681            Sched<[itins.Sched.Folded]>;
1682 }
1683
1684 multiclass sse12_cvt_sint_3addr<bits<8> opc, RegisterClass SrcRC,
1685                     RegisterClass DstRC, Intrinsic Int, X86MemOperand x86memop,
1686                     PatFrag ld_frag, string asm, OpndItins itins,
1687                     bit Is2Addr = 1> {
1688   def rr : SI<opc, MRMSrcReg, (outs DstRC:$dst), (ins DstRC:$src1, SrcRC:$src2),
1689               !if(Is2Addr,
1690                   !strconcat(asm, "\t{$src2, $dst|$dst, $src2}"),
1691                   !strconcat(asm, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
1692               [(set DstRC:$dst, (Int DstRC:$src1, SrcRC:$src2))],
1693               itins.rr>, Sched<[itins.Sched]>;
1694   def rm : SI<opc, MRMSrcMem, (outs DstRC:$dst),
1695               (ins DstRC:$src1, x86memop:$src2),
1696               !if(Is2Addr,
1697                   !strconcat(asm, "\t{$src2, $dst|$dst, $src2}"),
1698                   !strconcat(asm, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
1699               [(set DstRC:$dst, (Int DstRC:$src1, (ld_frag addr:$src2)))],
1700               itins.rm>, Sched<[itins.Sched.Folded, ReadAfterLd]>;
1701 }
1702
1703 let Predicates = [UseAVX] in {
1704 defm VCVTSD2SI : sse12_cvt_sint<0x2D, VR128, GR32,
1705                   int_x86_sse2_cvtsd2si, sdmem, sse_load_f64, "cvtsd2si",
1706                   SSE_CVT_SD2SI>, XD, VEX, VEX_LIG;
1707 defm VCVTSD2SI64 : sse12_cvt_sint<0x2D, VR128, GR64,
1708                     int_x86_sse2_cvtsd2si64, sdmem, sse_load_f64, "cvtsd2si",
1709                     SSE_CVT_SD2SI>, XD, VEX, VEX_W, VEX_LIG;
1710 }
1711 defm CVTSD2SI : sse12_cvt_sint<0x2D, VR128, GR32, int_x86_sse2_cvtsd2si,
1712                  sdmem, sse_load_f64, "cvtsd2si", SSE_CVT_SD2SI>, XD;
1713 defm CVTSD2SI64 : sse12_cvt_sint<0x2D, VR128, GR64, int_x86_sse2_cvtsd2si64,
1714                    sdmem, sse_load_f64, "cvtsd2si", SSE_CVT_SD2SI>, XD, REX_W;
1715
1716
1717 let isCodeGenOnly = 1 in {
1718   let Predicates = [UseAVX] in {
1719   defm Int_VCVTSI2SS : sse12_cvt_sint_3addr<0x2A, GR32, VR128,
1720             int_x86_sse_cvtsi2ss, i32mem, loadi32, "cvtsi2ss{l}",
1721             SSE_CVT_Scalar, 0>, XS, VEX_4V;
1722   defm Int_VCVTSI2SS64 : sse12_cvt_sint_3addr<0x2A, GR64, VR128,
1723             int_x86_sse_cvtsi642ss, i64mem, loadi64, "cvtsi2ss{q}",
1724             SSE_CVT_Scalar, 0>, XS, VEX_4V,
1725             VEX_W;
1726   defm Int_VCVTSI2SD : sse12_cvt_sint_3addr<0x2A, GR32, VR128,
1727             int_x86_sse2_cvtsi2sd, i32mem, loadi32, "cvtsi2sd{l}",
1728             SSE_CVT_Scalar, 0>, XD, VEX_4V;
1729   defm Int_VCVTSI2SD64 : sse12_cvt_sint_3addr<0x2A, GR64, VR128,
1730             int_x86_sse2_cvtsi642sd, i64mem, loadi64, "cvtsi2sd{q}",
1731             SSE_CVT_Scalar, 0>, XD,
1732             VEX_4V, VEX_W;
1733   }
1734   let Constraints = "$src1 = $dst" in {
1735     defm Int_CVTSI2SS : sse12_cvt_sint_3addr<0x2A, GR32, VR128,
1736                           int_x86_sse_cvtsi2ss, i32mem, loadi32,
1737                           "cvtsi2ss{l}", SSE_CVT_Scalar>, XS;
1738     defm Int_CVTSI2SS64 : sse12_cvt_sint_3addr<0x2A, GR64, VR128,
1739                           int_x86_sse_cvtsi642ss, i64mem, loadi64,
1740                           "cvtsi2ss{q}", SSE_CVT_Scalar>, XS, REX_W;
1741     defm Int_CVTSI2SD : sse12_cvt_sint_3addr<0x2A, GR32, VR128,
1742                           int_x86_sse2_cvtsi2sd, i32mem, loadi32,
1743                           "cvtsi2sd{l}", SSE_CVT_Scalar>, XD;
1744     defm Int_CVTSI2SD64 : sse12_cvt_sint_3addr<0x2A, GR64, VR128,
1745                           int_x86_sse2_cvtsi642sd, i64mem, loadi64,
1746                           "cvtsi2sd{q}", SSE_CVT_Scalar>, XD, REX_W;
1747   }
1748 } // isCodeGenOnly = 1
1749
1750 /// SSE 1 Only
1751
1752 // Aliases for intrinsics
1753 let isCodeGenOnly = 1 in {
1754 let Predicates = [UseAVX] in {
1755 defm Int_VCVTTSS2SI : sse12_cvt_sint<0x2C, VR128, GR32, int_x86_sse_cvttss2si,
1756                                     ssmem, sse_load_f32, "cvttss2si",
1757                                     SSE_CVT_SS2SI_32>, XS, VEX;
1758 defm Int_VCVTTSS2SI64 : sse12_cvt_sint<0x2C, VR128, GR64,
1759                                    int_x86_sse_cvttss2si64, ssmem, sse_load_f32,
1760                                    "cvttss2si", SSE_CVT_SS2SI_64>,
1761                                    XS, VEX, VEX_W;
1762 defm Int_VCVTTSD2SI : sse12_cvt_sint<0x2C, VR128, GR32, int_x86_sse2_cvttsd2si,
1763                                     sdmem, sse_load_f64, "cvttsd2si",
1764                                     SSE_CVT_SD2SI>, XD, VEX;
1765 defm Int_VCVTTSD2SI64 : sse12_cvt_sint<0x2C, VR128, GR64,
1766                                   int_x86_sse2_cvttsd2si64, sdmem, sse_load_f64,
1767                                   "cvttsd2si", SSE_CVT_SD2SI>,
1768                                   XD, VEX, VEX_W;
1769 }
1770 defm Int_CVTTSS2SI : sse12_cvt_sint<0x2C, VR128, GR32, int_x86_sse_cvttss2si,
1771                                     ssmem, sse_load_f32, "cvttss2si",
1772                                     SSE_CVT_SS2SI_32>, XS;
1773 defm Int_CVTTSS2SI64 : sse12_cvt_sint<0x2C, VR128, GR64,
1774                                    int_x86_sse_cvttss2si64, ssmem, sse_load_f32,
1775                                    "cvttss2si", SSE_CVT_SS2SI_64>, XS, REX_W;
1776 defm Int_CVTTSD2SI : sse12_cvt_sint<0x2C, VR128, GR32, int_x86_sse2_cvttsd2si,
1777                                     sdmem, sse_load_f64, "cvttsd2si",
1778                                     SSE_CVT_SD2SI>, XD;
1779 defm Int_CVTTSD2SI64 : sse12_cvt_sint<0x2C, VR128, GR64,
1780                                   int_x86_sse2_cvttsd2si64, sdmem, sse_load_f64,
1781                                   "cvttsd2si", SSE_CVT_SD2SI>, XD, REX_W;
1782 } // isCodeGenOnly = 1
1783
1784 let Predicates = [UseAVX] in {
1785 defm VCVTSS2SI   : sse12_cvt_sint<0x2D, VR128, GR32, int_x86_sse_cvtss2si,
1786                                   ssmem, sse_load_f32, "cvtss2si",
1787                                   SSE_CVT_SS2SI_32>, XS, VEX, VEX_LIG;
1788 defm VCVTSS2SI64 : sse12_cvt_sint<0x2D, VR128, GR64, int_x86_sse_cvtss2si64,
1789                                   ssmem, sse_load_f32, "cvtss2si",
1790                                   SSE_CVT_SS2SI_64>, XS, VEX, VEX_W, VEX_LIG;
1791 }
1792 defm CVTSS2SI : sse12_cvt_sint<0x2D, VR128, GR32, int_x86_sse_cvtss2si,
1793                                ssmem, sse_load_f32, "cvtss2si",
1794                                SSE_CVT_SS2SI_32>, XS;
1795 defm CVTSS2SI64 : sse12_cvt_sint<0x2D, VR128, GR64, int_x86_sse_cvtss2si64,
1796                                  ssmem, sse_load_f32, "cvtss2si",
1797                                  SSE_CVT_SS2SI_64>, XS, REX_W;
1798
1799 defm VCVTDQ2PS   : sse12_cvt_p<0x5B, VR128, VR128, i128mem,
1800                                "vcvtdq2ps\t{$src, $dst|$dst, $src}",
1801                                SSEPackedSingle, SSE_CVT_PS>,
1802                                PS, VEX, Requires<[HasAVX]>;
1803 defm VCVTDQ2PSY  : sse12_cvt_p<0x5B, VR256, VR256, i256mem,
1804                                "vcvtdq2ps\t{$src, $dst|$dst, $src}",
1805                                SSEPackedSingle, SSE_CVT_PS>,
1806                                PS, VEX, VEX_L, Requires<[HasAVX]>;
1807
1808 defm CVTDQ2PS : sse12_cvt_p<0x5B, VR128, VR128, i128mem,
1809                             "cvtdq2ps\t{$src, $dst|$dst, $src}",
1810                             SSEPackedSingle, SSE_CVT_PS>,
1811                             PS, Requires<[UseSSE2]>;
1812
1813 let Predicates = [UseAVX] in {
1814 def : InstAlias<"vcvtss2si{l}\t{$src, $dst|$dst, $src}",
1815                 (VCVTSS2SIrr GR32:$dst, VR128:$src), 0>;
1816 def : InstAlias<"vcvtss2si{l}\t{$src, $dst|$dst, $src}",
1817                 (VCVTSS2SIrm GR32:$dst, ssmem:$src), 0>;
1818 def : InstAlias<"vcvtsd2si{l}\t{$src, $dst|$dst, $src}",
1819                 (VCVTSD2SIrr GR32:$dst, VR128:$src), 0>;
1820 def : InstAlias<"vcvtsd2si{l}\t{$src, $dst|$dst, $src}",
1821                 (VCVTSD2SIrm GR32:$dst, sdmem:$src), 0>;
1822 def : InstAlias<"vcvtss2si{q}\t{$src, $dst|$dst, $src}",
1823                 (VCVTSS2SI64rr GR64:$dst, VR128:$src), 0>;
1824 def : InstAlias<"vcvtss2si{q}\t{$src, $dst|$dst, $src}",
1825                 (VCVTSS2SI64rm GR64:$dst, ssmem:$src), 0>;
1826 def : InstAlias<"vcvtsd2si{q}\t{$src, $dst|$dst, $src}",
1827                 (VCVTSD2SI64rr GR64:$dst, VR128:$src), 0>;
1828 def : InstAlias<"vcvtsd2si{q}\t{$src, $dst|$dst, $src}",
1829                 (VCVTSD2SI64rm GR64:$dst, sdmem:$src), 0>;
1830 }
1831
1832 def : InstAlias<"cvtss2si{l}\t{$src, $dst|$dst, $src}",
1833                 (CVTSS2SIrr GR32:$dst, VR128:$src), 0>;
1834 def : InstAlias<"cvtss2si{l}\t{$src, $dst|$dst, $src}",
1835                 (CVTSS2SIrm GR32:$dst, ssmem:$src), 0>;
1836 def : InstAlias<"cvtsd2si{l}\t{$src, $dst|$dst, $src}",
1837                 (CVTSD2SIrr GR32:$dst, VR128:$src), 0>;
1838 def : InstAlias<"cvtsd2si{l}\t{$src, $dst|$dst, $src}",
1839                 (CVTSD2SIrm GR32:$dst, sdmem:$src), 0>;
1840 def : InstAlias<"cvtss2si{q}\t{$src, $dst|$dst, $src}",
1841                 (CVTSS2SI64rr GR64:$dst, VR128:$src), 0>;
1842 def : InstAlias<"cvtss2si{q}\t{$src, $dst|$dst, $src}",
1843                 (CVTSS2SI64rm GR64:$dst, ssmem:$src), 0>;
1844 def : InstAlias<"cvtsd2si{q}\t{$src, $dst|$dst, $src}",
1845                 (CVTSD2SI64rr GR64:$dst, VR128:$src), 0>;
1846 def : InstAlias<"cvtsd2si{q}\t{$src, $dst|$dst, $src}",
1847                 (CVTSD2SI64rm GR64:$dst, sdmem:$src)>;
1848
1849 /// SSE 2 Only
1850
1851 // Convert scalar double to scalar single
1852 let neverHasSideEffects = 1, Predicates = [UseAVX] in {
1853 def VCVTSD2SSrr  : VSDI<0x5A, MRMSrcReg, (outs FR32:$dst),
1854                        (ins FR64:$src1, FR64:$src2),
1855                       "cvtsd2ss\t{$src2, $src1, $dst|$dst, $src1, $src2}", [],
1856                       IIC_SSE_CVT_Scalar_RR>, VEX_4V, VEX_LIG,
1857                       Sched<[WriteCvtF2F]>;
1858 let mayLoad = 1 in
1859 def VCVTSD2SSrm  : I<0x5A, MRMSrcMem, (outs FR32:$dst),
1860                        (ins FR64:$src1, f64mem:$src2),
1861                       "vcvtsd2ss\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1862                       [], IIC_SSE_CVT_Scalar_RM>,
1863                       XD, Requires<[HasAVX, OptForSize]>, VEX_4V, VEX_LIG,
1864                       Sched<[WriteCvtF2FLd, ReadAfterLd]>;
1865 }
1866
1867 def : Pat<(f32 (fround FR64:$src)), (VCVTSD2SSrr FR64:$src, FR64:$src)>,
1868           Requires<[UseAVX]>;
1869
1870 def CVTSD2SSrr  : SDI<0x5A, MRMSrcReg, (outs FR32:$dst), (ins FR64:$src),
1871                       "cvtsd2ss\t{$src, $dst|$dst, $src}",
1872                       [(set FR32:$dst, (fround FR64:$src))],
1873                       IIC_SSE_CVT_Scalar_RR>, Sched<[WriteCvtF2F]>;
1874 def CVTSD2SSrm  : I<0x5A, MRMSrcMem, (outs FR32:$dst), (ins f64mem:$src),
1875                       "cvtsd2ss\t{$src, $dst|$dst, $src}",
1876                       [(set FR32:$dst, (fround (loadf64 addr:$src)))],
1877                       IIC_SSE_CVT_Scalar_RM>,
1878                       XD,
1879                   Requires<[UseSSE2, OptForSize]>, Sched<[WriteCvtF2FLd]>;
1880
1881 let isCodeGenOnly = 1 in {
1882 def Int_VCVTSD2SSrr: I<0x5A, MRMSrcReg,
1883                        (outs VR128:$dst), (ins VR128:$src1, VR128:$src2),
1884                        "vcvtsd2ss\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1885                        [(set VR128:$dst,
1886                          (int_x86_sse2_cvtsd2ss VR128:$src1, VR128:$src2))],
1887                        IIC_SSE_CVT_Scalar_RR>, XD, VEX_4V, Requires<[UseAVX]>,
1888                        Sched<[WriteCvtF2F]>;
1889 def Int_VCVTSD2SSrm: I<0x5A, MRMSrcReg,
1890                        (outs VR128:$dst), (ins VR128:$src1, sdmem:$src2),
1891                        "vcvtsd2ss\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1892                        [(set VR128:$dst, (int_x86_sse2_cvtsd2ss
1893                                           VR128:$src1, sse_load_f64:$src2))],
1894                        IIC_SSE_CVT_Scalar_RM>, XD, VEX_4V, Requires<[UseAVX]>,
1895                        Sched<[WriteCvtF2FLd, ReadAfterLd]>;
1896
1897 let Constraints = "$src1 = $dst" in {
1898 def Int_CVTSD2SSrr: I<0x5A, MRMSrcReg,
1899                        (outs VR128:$dst), (ins VR128:$src1, VR128:$src2),
1900                        "cvtsd2ss\t{$src2, $dst|$dst, $src2}",
1901                        [(set VR128:$dst,
1902                          (int_x86_sse2_cvtsd2ss VR128:$src1, VR128:$src2))],
1903                        IIC_SSE_CVT_Scalar_RR>, XD, Requires<[UseSSE2]>,
1904                        Sched<[WriteCvtF2F]>;
1905 def Int_CVTSD2SSrm: I<0x5A, MRMSrcReg,
1906                        (outs VR128:$dst), (ins VR128:$src1, sdmem:$src2),
1907                        "cvtsd2ss\t{$src2, $dst|$dst, $src2}",
1908                        [(set VR128:$dst, (int_x86_sse2_cvtsd2ss
1909                                           VR128:$src1, sse_load_f64:$src2))],
1910                        IIC_SSE_CVT_Scalar_RM>, XD, Requires<[UseSSE2]>,
1911                        Sched<[WriteCvtF2FLd, ReadAfterLd]>;
1912 }
1913 } // isCodeGenOnly = 1
1914
1915 // Convert scalar single to scalar double
1916 // SSE2 instructions with XS prefix
1917 let neverHasSideEffects = 1, Predicates = [UseAVX] in {
1918 def VCVTSS2SDrr : I<0x5A, MRMSrcReg, (outs FR64:$dst),
1919                     (ins FR32:$src1, FR32:$src2),
1920                     "vcvtss2sd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1921                     [], IIC_SSE_CVT_Scalar_RR>,
1922                     XS, Requires<[HasAVX]>, VEX_4V, VEX_LIG,
1923                     Sched<[WriteCvtF2F]>;
1924 let mayLoad = 1 in
1925 def VCVTSS2SDrm : I<0x5A, MRMSrcMem, (outs FR64:$dst),
1926                     (ins FR32:$src1, f32mem:$src2),
1927                     "vcvtss2sd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1928                     [], IIC_SSE_CVT_Scalar_RM>,
1929                     XS, VEX_4V, VEX_LIG, Requires<[HasAVX, OptForSize]>,
1930                     Sched<[WriteCvtF2FLd, ReadAfterLd]>;
1931 }
1932
1933 def : Pat<(f64 (fextend FR32:$src)),
1934     (VCVTSS2SDrr FR32:$src, FR32:$src)>, Requires<[UseAVX]>;
1935 def : Pat<(fextend (loadf32 addr:$src)),
1936     (VCVTSS2SDrm (f32 (IMPLICIT_DEF)), addr:$src)>, Requires<[UseAVX]>;
1937
1938 def : Pat<(extloadf32 addr:$src),
1939     (VCVTSS2SDrm (f32 (IMPLICIT_DEF)), addr:$src)>,
1940     Requires<[UseAVX, OptForSize]>;
1941 def : Pat<(extloadf32 addr:$src),
1942     (VCVTSS2SDrr (f32 (IMPLICIT_DEF)), (VMOVSSrm addr:$src))>,
1943     Requires<[UseAVX, OptForSpeed]>;
1944
1945 def CVTSS2SDrr : I<0x5A, MRMSrcReg, (outs FR64:$dst), (ins FR32:$src),
1946                    "cvtss2sd\t{$src, $dst|$dst, $src}",
1947                    [(set FR64:$dst, (fextend FR32:$src))],
1948                    IIC_SSE_CVT_Scalar_RR>, XS,
1949                  Requires<[UseSSE2]>, Sched<[WriteCvtF2F]>;
1950 def CVTSS2SDrm : I<0x5A, MRMSrcMem, (outs FR64:$dst), (ins f32mem:$src),
1951                    "cvtss2sd\t{$src, $dst|$dst, $src}",
1952                    [(set FR64:$dst, (extloadf32 addr:$src))],
1953                    IIC_SSE_CVT_Scalar_RM>, XS,
1954                  Requires<[UseSSE2, OptForSize]>, Sched<[WriteCvtF2FLd]>;
1955
1956 // extload f32 -> f64.  This matches load+fextend because we have a hack in
1957 // the isel (PreprocessForFPConvert) that can introduce loads after dag
1958 // combine.
1959 // Since these loads aren't folded into the fextend, we have to match it
1960 // explicitly here.
1961 def : Pat<(fextend (loadf32 addr:$src)),
1962           (CVTSS2SDrm addr:$src)>, Requires<[UseSSE2]>;
1963 def : Pat<(extloadf32 addr:$src),
1964           (CVTSS2SDrr (MOVSSrm addr:$src))>, Requires<[UseSSE2, OptForSpeed]>;
1965
1966 let isCodeGenOnly = 1 in {
1967 def Int_VCVTSS2SDrr: I<0x5A, MRMSrcReg,
1968                       (outs VR128:$dst), (ins VR128:$src1, VR128:$src2),
1969                     "vcvtss2sd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1970                     [(set VR128:$dst,
1971                       (int_x86_sse2_cvtss2sd VR128:$src1, VR128:$src2))],
1972                     IIC_SSE_CVT_Scalar_RR>, XS, VEX_4V, Requires<[UseAVX]>,
1973                     Sched<[WriteCvtF2F]>;
1974 def Int_VCVTSS2SDrm: I<0x5A, MRMSrcMem,
1975                       (outs VR128:$dst), (ins VR128:$src1, ssmem:$src2),
1976                     "vcvtss2sd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1977                     [(set VR128:$dst,
1978                       (int_x86_sse2_cvtss2sd VR128:$src1, sse_load_f32:$src2))],
1979                     IIC_SSE_CVT_Scalar_RM>, XS, VEX_4V, Requires<[UseAVX]>,
1980                     Sched<[WriteCvtF2FLd, ReadAfterLd]>;
1981 let Constraints = "$src1 = $dst" in { // SSE2 instructions with XS prefix
1982 def Int_CVTSS2SDrr: I<0x5A, MRMSrcReg,
1983                       (outs VR128:$dst), (ins VR128:$src1, VR128:$src2),
1984                     "cvtss2sd\t{$src2, $dst|$dst, $src2}",
1985                     [(set VR128:$dst,
1986                       (int_x86_sse2_cvtss2sd VR128:$src1, VR128:$src2))],
1987                     IIC_SSE_CVT_Scalar_RR>, XS, Requires<[UseSSE2]>,
1988                     Sched<[WriteCvtF2F]>;
1989 def Int_CVTSS2SDrm: I<0x5A, MRMSrcMem,
1990                       (outs VR128:$dst), (ins VR128:$src1, ssmem:$src2),
1991                     "cvtss2sd\t{$src2, $dst|$dst, $src2}",
1992                     [(set VR128:$dst,
1993                       (int_x86_sse2_cvtss2sd VR128:$src1, sse_load_f32:$src2))],
1994                     IIC_SSE_CVT_Scalar_RM>, XS, Requires<[UseSSE2]>,
1995                     Sched<[WriteCvtF2FLd, ReadAfterLd]>;
1996 }
1997 } // isCodeGenOnly = 1
1998
1999 // Convert packed single/double fp to doubleword
2000 def VCVTPS2DQrr : VPDI<0x5B, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2001                        "cvtps2dq\t{$src, $dst|$dst, $src}",
2002                        [(set VR128:$dst, (int_x86_sse2_cvtps2dq VR128:$src))],
2003                        IIC_SSE_CVT_PS_RR>, VEX, Sched<[WriteCvtF2I]>;
2004 def VCVTPS2DQrm : VPDI<0x5B, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
2005                        "cvtps2dq\t{$src, $dst|$dst, $src}",
2006                        [(set VR128:$dst,
2007                          (int_x86_sse2_cvtps2dq (loadv4f32 addr:$src)))],
2008                        IIC_SSE_CVT_PS_RM>, VEX, Sched<[WriteCvtF2ILd]>;
2009 def VCVTPS2DQYrr : VPDI<0x5B, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
2010                         "cvtps2dq\t{$src, $dst|$dst, $src}",
2011                         [(set VR256:$dst,
2012                           (int_x86_avx_cvt_ps2dq_256 VR256:$src))],
2013                         IIC_SSE_CVT_PS_RR>, VEX, VEX_L, Sched<[WriteCvtF2I]>;
2014 def VCVTPS2DQYrm : VPDI<0x5B, MRMSrcMem, (outs VR256:$dst), (ins f256mem:$src),
2015                         "cvtps2dq\t{$src, $dst|$dst, $src}",
2016                         [(set VR256:$dst,
2017                           (int_x86_avx_cvt_ps2dq_256 (loadv8f32 addr:$src)))],
2018                         IIC_SSE_CVT_PS_RM>, VEX, VEX_L, Sched<[WriteCvtF2ILd]>;
2019 def CVTPS2DQrr : PDI<0x5B, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2020                      "cvtps2dq\t{$src, $dst|$dst, $src}",
2021                      [(set VR128:$dst, (int_x86_sse2_cvtps2dq VR128:$src))],
2022                      IIC_SSE_CVT_PS_RR>, Sched<[WriteCvtF2I]>;
2023 def CVTPS2DQrm : PDI<0x5B, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
2024                      "cvtps2dq\t{$src, $dst|$dst, $src}",
2025                      [(set VR128:$dst,
2026                        (int_x86_sse2_cvtps2dq (memopv4f32 addr:$src)))],
2027                      IIC_SSE_CVT_PS_RM>, Sched<[WriteCvtF2ILd]>;
2028
2029
2030 // Convert Packed Double FP to Packed DW Integers
2031 let Predicates = [HasAVX] in {
2032 // The assembler can recognize rr 256-bit instructions by seeing a ymm
2033 // register, but the same isn't true when using memory operands instead.
2034 // Provide other assembly rr and rm forms to address this explicitly.
2035 def VCVTPD2DQrr  : SDI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2036                        "vcvtpd2dq\t{$src, $dst|$dst, $src}",
2037                        [(set VR128:$dst, (int_x86_sse2_cvtpd2dq VR128:$src))]>,
2038                        VEX, Sched<[WriteCvtF2I]>;
2039
2040 // XMM only
2041 def : InstAlias<"vcvtpd2dqx\t{$src, $dst|$dst, $src}",
2042                 (VCVTPD2DQrr VR128:$dst, VR128:$src), 0>;
2043 def VCVTPD2DQXrm : SDI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
2044                        "vcvtpd2dqx\t{$src, $dst|$dst, $src}",
2045                        [(set VR128:$dst,
2046                          (int_x86_sse2_cvtpd2dq (loadv2f64 addr:$src)))]>, VEX,
2047                        Sched<[WriteCvtF2ILd]>;
2048
2049 // YMM only
2050 def VCVTPD2DQYrr : SDI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR256:$src),
2051                        "vcvtpd2dq{y}\t{$src, $dst|$dst, $src}",
2052                        [(set VR128:$dst,
2053                          (int_x86_avx_cvt_pd2dq_256 VR256:$src))]>, VEX, VEX_L,
2054                        Sched<[WriteCvtF2I]>;
2055 def VCVTPD2DQYrm : SDI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f256mem:$src),
2056                        "vcvtpd2dq{y}\t{$src, $dst|$dst, $src}",
2057                        [(set VR128:$dst,
2058                          (int_x86_avx_cvt_pd2dq_256 (loadv4f64 addr:$src)))]>,
2059                        VEX, VEX_L, Sched<[WriteCvtF2ILd]>;
2060 def : InstAlias<"vcvtpd2dq\t{$src, $dst|$dst, $src}",
2061                 (VCVTPD2DQYrr VR128:$dst, VR256:$src), 0>;
2062 }
2063
2064 def CVTPD2DQrm  : SDI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
2065                       "cvtpd2dq\t{$src, $dst|$dst, $src}",
2066                       [(set VR128:$dst,
2067                         (int_x86_sse2_cvtpd2dq (memopv2f64 addr:$src)))],
2068                       IIC_SSE_CVT_PD_RM>, Sched<[WriteCvtF2ILd]>;
2069 def CVTPD2DQrr  : SDI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2070                       "cvtpd2dq\t{$src, $dst|$dst, $src}",
2071                       [(set VR128:$dst, (int_x86_sse2_cvtpd2dq VR128:$src))],
2072                       IIC_SSE_CVT_PD_RR>, Sched<[WriteCvtF2I]>;
2073
2074 // Convert with truncation packed single/double fp to doubleword
2075 // SSE2 packed instructions with XS prefix
2076 def VCVTTPS2DQrr : VS2SI<0x5B, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2077                          "cvttps2dq\t{$src, $dst|$dst, $src}",
2078                          [(set VR128:$dst,
2079                            (int_x86_sse2_cvttps2dq VR128:$src))],
2080                          IIC_SSE_CVT_PS_RR>, VEX, Sched<[WriteCvtF2I]>;
2081 def VCVTTPS2DQrm : VS2SI<0x5B, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
2082                          "cvttps2dq\t{$src, $dst|$dst, $src}",
2083                          [(set VR128:$dst, (int_x86_sse2_cvttps2dq
2084                                             (loadv4f32 addr:$src)))],
2085                          IIC_SSE_CVT_PS_RM>, VEX, Sched<[WriteCvtF2ILd]>;
2086 def VCVTTPS2DQYrr : VS2SI<0x5B, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
2087                           "cvttps2dq\t{$src, $dst|$dst, $src}",
2088                           [(set VR256:$dst,
2089                             (int_x86_avx_cvtt_ps2dq_256 VR256:$src))],
2090                           IIC_SSE_CVT_PS_RR>, VEX, VEX_L, Sched<[WriteCvtF2I]>;
2091 def VCVTTPS2DQYrm : VS2SI<0x5B, MRMSrcMem, (outs VR256:$dst), (ins f256mem:$src),
2092                           "cvttps2dq\t{$src, $dst|$dst, $src}",
2093                           [(set VR256:$dst, (int_x86_avx_cvtt_ps2dq_256
2094                                              (loadv8f32 addr:$src)))],
2095                           IIC_SSE_CVT_PS_RM>, VEX, VEX_L,
2096                           Sched<[WriteCvtF2ILd]>;
2097
2098 def CVTTPS2DQrr : S2SI<0x5B, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2099                        "cvttps2dq\t{$src, $dst|$dst, $src}",
2100                        [(set VR128:$dst, (int_x86_sse2_cvttps2dq VR128:$src))],
2101                        IIC_SSE_CVT_PS_RR>, Sched<[WriteCvtF2I]>;
2102 def CVTTPS2DQrm : S2SI<0x5B, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
2103                        "cvttps2dq\t{$src, $dst|$dst, $src}",
2104                        [(set VR128:$dst,
2105                          (int_x86_sse2_cvttps2dq (memopv4f32 addr:$src)))],
2106                        IIC_SSE_CVT_PS_RM>, Sched<[WriteCvtF2ILd]>;
2107
2108 let Predicates = [HasAVX] in {
2109   def : Pat<(v4f32 (sint_to_fp (v4i32 VR128:$src))),
2110             (VCVTDQ2PSrr VR128:$src)>;
2111   def : Pat<(v4f32 (sint_to_fp (bc_v4i32 (loadv2i64 addr:$src)))),
2112             (VCVTDQ2PSrm addr:$src)>;
2113
2114   def : Pat<(int_x86_sse2_cvtdq2ps VR128:$src),
2115             (VCVTDQ2PSrr VR128:$src)>;
2116   def : Pat<(int_x86_sse2_cvtdq2ps (bc_v4i32 (loadv2i64 addr:$src))),
2117             (VCVTDQ2PSrm addr:$src)>;
2118
2119   def : Pat<(v4i32 (fp_to_sint (v4f32 VR128:$src))),
2120             (VCVTTPS2DQrr VR128:$src)>;
2121   def : Pat<(v4i32 (fp_to_sint (loadv4f32 addr:$src))),
2122             (VCVTTPS2DQrm addr:$src)>;
2123
2124   def : Pat<(v8f32 (sint_to_fp (v8i32 VR256:$src))),
2125             (VCVTDQ2PSYrr VR256:$src)>;
2126   def : Pat<(v8f32 (sint_to_fp (bc_v8i32 (loadv4i64 addr:$src)))),
2127             (VCVTDQ2PSYrm addr:$src)>;
2128
2129   def : Pat<(v8i32 (fp_to_sint (v8f32 VR256:$src))),
2130             (VCVTTPS2DQYrr VR256:$src)>;
2131   def : Pat<(v8i32 (fp_to_sint (loadv8f32 addr:$src))),
2132             (VCVTTPS2DQYrm addr:$src)>;
2133 }
2134
2135 let Predicates = [UseSSE2] in {
2136   def : Pat<(v4f32 (sint_to_fp (v4i32 VR128:$src))),
2137             (CVTDQ2PSrr VR128:$src)>;
2138   def : Pat<(v4f32 (sint_to_fp (bc_v4i32 (memopv2i64 addr:$src)))),
2139             (CVTDQ2PSrm addr:$src)>;
2140
2141   def : Pat<(int_x86_sse2_cvtdq2ps VR128:$src),
2142             (CVTDQ2PSrr VR128:$src)>;
2143   def : Pat<(int_x86_sse2_cvtdq2ps (bc_v4i32 (memopv2i64 addr:$src))),
2144             (CVTDQ2PSrm addr:$src)>;
2145
2146   def : Pat<(v4i32 (fp_to_sint (v4f32 VR128:$src))),
2147             (CVTTPS2DQrr VR128:$src)>;
2148   def : Pat<(v4i32 (fp_to_sint (memopv4f32 addr:$src))),
2149             (CVTTPS2DQrm addr:$src)>;
2150 }
2151
2152 def VCVTTPD2DQrr : VPDI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2153                         "cvttpd2dq\t{$src, $dst|$dst, $src}",
2154                         [(set VR128:$dst,
2155                               (int_x86_sse2_cvttpd2dq VR128:$src))],
2156                               IIC_SSE_CVT_PD_RR>, VEX, Sched<[WriteCvtF2I]>;
2157
2158 // The assembler can recognize rr 256-bit instructions by seeing a ymm
2159 // register, but the same isn't true when using memory operands instead.
2160 // Provide other assembly rr and rm forms to address this explicitly.
2161
2162 // XMM only
2163 def : InstAlias<"vcvttpd2dqx\t{$src, $dst|$dst, $src}",
2164                 (VCVTTPD2DQrr VR128:$dst, VR128:$src), 0>;
2165 def VCVTTPD2DQXrm : VPDI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
2166                          "cvttpd2dqx\t{$src, $dst|$dst, $src}",
2167                          [(set VR128:$dst, (int_x86_sse2_cvttpd2dq
2168                                             (loadv2f64 addr:$src)))],
2169                          IIC_SSE_CVT_PD_RM>, VEX, Sched<[WriteCvtF2ILd]>;
2170
2171 // YMM only
2172 def VCVTTPD2DQYrr : VPDI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR256:$src),
2173                          "cvttpd2dq{y}\t{$src, $dst|$dst, $src}",
2174                          [(set VR128:$dst,
2175                            (int_x86_avx_cvtt_pd2dq_256 VR256:$src))],
2176                          IIC_SSE_CVT_PD_RR>, VEX, VEX_L, Sched<[WriteCvtF2I]>;
2177 def VCVTTPD2DQYrm : VPDI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f256mem:$src),
2178                          "cvttpd2dq{y}\t{$src, $dst|$dst, $src}",
2179                          [(set VR128:$dst,
2180                           (int_x86_avx_cvtt_pd2dq_256 (loadv4f64 addr:$src)))],
2181                          IIC_SSE_CVT_PD_RM>, VEX, VEX_L, Sched<[WriteCvtF2ILd]>;
2182 def : InstAlias<"vcvttpd2dq\t{$src, $dst|$dst, $src}",
2183                 (VCVTTPD2DQYrr VR128:$dst, VR256:$src), 0>;
2184
2185 let Predicates = [HasAVX] in {
2186   def : Pat<(v4i32 (fp_to_sint (v4f64 VR256:$src))),
2187             (VCVTTPD2DQYrr VR256:$src)>;
2188   def : Pat<(v4i32 (fp_to_sint (loadv4f64 addr:$src))),
2189             (VCVTTPD2DQYrm addr:$src)>;
2190 } // Predicates = [HasAVX]
2191
2192 def CVTTPD2DQrr : PDI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2193                       "cvttpd2dq\t{$src, $dst|$dst, $src}",
2194                       [(set VR128:$dst, (int_x86_sse2_cvttpd2dq VR128:$src))],
2195                       IIC_SSE_CVT_PD_RR>, Sched<[WriteCvtF2I]>;
2196 def CVTTPD2DQrm : PDI<0xE6, MRMSrcMem, (outs VR128:$dst),(ins f128mem:$src),
2197                       "cvttpd2dq\t{$src, $dst|$dst, $src}",
2198                       [(set VR128:$dst, (int_x86_sse2_cvttpd2dq
2199                                         (memopv2f64 addr:$src)))],
2200                                         IIC_SSE_CVT_PD_RM>,
2201                       Sched<[WriteCvtF2ILd]>;
2202
2203 // Convert packed single to packed double
2204 let Predicates = [HasAVX] in {
2205                   // SSE2 instructions without OpSize prefix
2206 def VCVTPS2PDrr : I<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2207                      "vcvtps2pd\t{$src, $dst|$dst, $src}",
2208                      [(set VR128:$dst, (int_x86_sse2_cvtps2pd VR128:$src))],
2209                      IIC_SSE_CVT_PD_RR>, PS, VEX, Sched<[WriteCvtF2F]>;
2210 def VCVTPS2PDrm : I<0x5A, MRMSrcMem, (outs VR128:$dst), (ins f64mem:$src),
2211                     "vcvtps2pd\t{$src, $dst|$dst, $src}",
2212                     [(set VR128:$dst, (v2f64 (extloadv2f32 addr:$src)))],
2213                     IIC_SSE_CVT_PD_RM>, PS, VEX, Sched<[WriteCvtF2FLd]>;
2214 def VCVTPS2PDYrr : I<0x5A, MRMSrcReg, (outs VR256:$dst), (ins VR128:$src),
2215                      "vcvtps2pd\t{$src, $dst|$dst, $src}",
2216                      [(set VR256:$dst,
2217                        (int_x86_avx_cvt_ps2_pd_256 VR128:$src))],
2218                      IIC_SSE_CVT_PD_RR>, PS, VEX, VEX_L, Sched<[WriteCvtF2F]>;
2219 def VCVTPS2PDYrm : I<0x5A, MRMSrcMem, (outs VR256:$dst), (ins f128mem:$src),
2220                      "vcvtps2pd\t{$src, $dst|$dst, $src}",
2221                      [(set VR256:$dst,
2222                        (int_x86_avx_cvt_ps2_pd_256 (loadv4f32 addr:$src)))],
2223                      IIC_SSE_CVT_PD_RM>, PS, VEX, VEX_L, Sched<[WriteCvtF2FLd]>;
2224 }
2225
2226 let Predicates = [UseSSE2] in {
2227 def CVTPS2PDrr : I<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2228                        "cvtps2pd\t{$src, $dst|$dst, $src}",
2229                        [(set VR128:$dst, (int_x86_sse2_cvtps2pd VR128:$src))],
2230                        IIC_SSE_CVT_PD_RR>, PS, Sched<[WriteCvtF2F]>;
2231 def CVTPS2PDrm : I<0x5A, MRMSrcMem, (outs VR128:$dst), (ins f64mem:$src),
2232                    "cvtps2pd\t{$src, $dst|$dst, $src}",
2233                    [(set VR128:$dst, (v2f64 (extloadv2f32 addr:$src)))],
2234                    IIC_SSE_CVT_PD_RM>, PS, Sched<[WriteCvtF2FLd]>;
2235 }
2236
2237 // Convert Packed DW Integers to Packed Double FP
2238 let Predicates = [HasAVX] in {
2239 let neverHasSideEffects = 1, mayLoad = 1 in
2240 def VCVTDQ2PDrm  : S2SI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
2241                      "vcvtdq2pd\t{$src, $dst|$dst, $src}",
2242                      []>, VEX, Sched<[WriteCvtI2FLd]>;
2243 def VCVTDQ2PDrr  : S2SI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2244                      "vcvtdq2pd\t{$src, $dst|$dst, $src}",
2245                      [(set VR128:$dst,
2246                        (int_x86_sse2_cvtdq2pd VR128:$src))]>, VEX,
2247                    Sched<[WriteCvtI2F]>;
2248 def VCVTDQ2PDYrm  : S2SI<0xE6, MRMSrcMem, (outs VR256:$dst), (ins i128mem:$src),
2249                      "vcvtdq2pd\t{$src, $dst|$dst, $src}",
2250                      [(set VR256:$dst,
2251                        (int_x86_avx_cvtdq2_pd_256
2252                         (bitconvert (loadv2i64 addr:$src))))]>, VEX, VEX_L,
2253                     Sched<[WriteCvtI2FLd]>;
2254 def VCVTDQ2PDYrr  : S2SI<0xE6, MRMSrcReg, (outs VR256:$dst), (ins VR128:$src),
2255                      "vcvtdq2pd\t{$src, $dst|$dst, $src}",
2256                      [(set VR256:$dst,
2257                        (int_x86_avx_cvtdq2_pd_256 VR128:$src))]>, VEX, VEX_L,
2258                     Sched<[WriteCvtI2F]>;
2259 }
2260
2261 let neverHasSideEffects = 1, mayLoad = 1 in
2262 def CVTDQ2PDrm  : S2SI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
2263                        "cvtdq2pd\t{$src, $dst|$dst, $src}", [],
2264                        IIC_SSE_CVT_PD_RR>, Sched<[WriteCvtI2FLd]>;
2265 def CVTDQ2PDrr  : S2SI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2266                        "cvtdq2pd\t{$src, $dst|$dst, $src}",
2267                        [(set VR128:$dst, (int_x86_sse2_cvtdq2pd VR128:$src))],
2268                        IIC_SSE_CVT_PD_RM>, Sched<[WriteCvtI2F]>;
2269
2270 // AVX 256-bit register conversion intrinsics
2271 let Predicates = [HasAVX] in {
2272   def : Pat<(v4f64 (sint_to_fp (v4i32 VR128:$src))),
2273             (VCVTDQ2PDYrr VR128:$src)>;
2274   def : Pat<(v4f64 (sint_to_fp (bc_v4i32 (loadv2i64 addr:$src)))),
2275             (VCVTDQ2PDYrm addr:$src)>;
2276 } // Predicates = [HasAVX]
2277
2278 // Convert packed double to packed single
2279 // The assembler can recognize rr 256-bit instructions by seeing a ymm
2280 // register, but the same isn't true when using memory operands instead.
2281 // Provide other assembly rr and rm forms to address this explicitly.
2282 def VCVTPD2PSrr : VPDI<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2283                        "cvtpd2ps\t{$src, $dst|$dst, $src}",
2284                        [(set VR128:$dst, (int_x86_sse2_cvtpd2ps VR128:$src))],
2285                        IIC_SSE_CVT_PD_RR>, VEX, Sched<[WriteCvtF2F]>;
2286
2287 // XMM only
2288 def : InstAlias<"vcvtpd2psx\t{$src, $dst|$dst, $src}",
2289                 (VCVTPD2PSrr VR128:$dst, VR128:$src), 0>;
2290 def VCVTPD2PSXrm : VPDI<0x5A, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
2291                         "cvtpd2psx\t{$src, $dst|$dst, $src}",
2292                         [(set VR128:$dst,
2293                           (int_x86_sse2_cvtpd2ps (loadv2f64 addr:$src)))],
2294                         IIC_SSE_CVT_PD_RM>, VEX, Sched<[WriteCvtF2FLd]>;
2295
2296 // YMM only
2297 def VCVTPD2PSYrr : VPDI<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR256:$src),
2298                         "cvtpd2ps{y}\t{$src, $dst|$dst, $src}",
2299                         [(set VR128:$dst,
2300                           (int_x86_avx_cvt_pd2_ps_256 VR256:$src))],
2301                         IIC_SSE_CVT_PD_RR>, VEX, VEX_L, Sched<[WriteCvtF2F]>;
2302 def VCVTPD2PSYrm : VPDI<0x5A, MRMSrcMem, (outs VR128:$dst), (ins f256mem:$src),
2303                         "cvtpd2ps{y}\t{$src, $dst|$dst, $src}",
2304                         [(set VR128:$dst,
2305                           (int_x86_avx_cvt_pd2_ps_256 (loadv4f64 addr:$src)))],
2306                         IIC_SSE_CVT_PD_RM>, VEX, VEX_L, Sched<[WriteCvtF2FLd]>;
2307 def : InstAlias<"vcvtpd2ps\t{$src, $dst|$dst, $src}",
2308                 (VCVTPD2PSYrr VR128:$dst, VR256:$src), 0>;
2309
2310 def CVTPD2PSrr : PDI<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2311                      "cvtpd2ps\t{$src, $dst|$dst, $src}",
2312                      [(set VR128:$dst, (int_x86_sse2_cvtpd2ps VR128:$src))],
2313                      IIC_SSE_CVT_PD_RR>, Sched<[WriteCvtF2F]>;
2314 def CVTPD2PSrm : PDI<0x5A, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
2315                      "cvtpd2ps\t{$src, $dst|$dst, $src}",
2316                      [(set VR128:$dst,
2317                        (int_x86_sse2_cvtpd2ps (memopv2f64 addr:$src)))],
2318                      IIC_SSE_CVT_PD_RM>, Sched<[WriteCvtF2FLd]>;
2319
2320
2321 // AVX 256-bit register conversion intrinsics
2322 // FIXME: Migrate SSE conversion intrinsics matching to use patterns as below
2323 // whenever possible to avoid declaring two versions of each one.
2324 let Predicates = [HasAVX] in {
2325   def : Pat<(int_x86_avx_cvtdq2_ps_256 VR256:$src),
2326             (VCVTDQ2PSYrr VR256:$src)>;
2327   def : Pat<(int_x86_avx_cvtdq2_ps_256 (bitconvert (loadv4i64 addr:$src))),
2328             (VCVTDQ2PSYrm addr:$src)>;
2329
2330   // Match fround and fextend for 128/256-bit conversions
2331   def : Pat<(v4f32 (X86vfpround (v2f64 VR128:$src))),
2332             (VCVTPD2PSrr VR128:$src)>;
2333   def : Pat<(v4f32 (X86vfpround (loadv2f64 addr:$src))),
2334             (VCVTPD2PSXrm addr:$src)>;
2335   def : Pat<(v4f32 (fround (v4f64 VR256:$src))),
2336             (VCVTPD2PSYrr VR256:$src)>;
2337   def : Pat<(v4f32 (fround (loadv4f64 addr:$src))),
2338             (VCVTPD2PSYrm addr:$src)>;
2339
2340   def : Pat<(v2f64 (X86vfpext (v4f32 VR128:$src))),
2341             (VCVTPS2PDrr VR128:$src)>;
2342   def : Pat<(v4f64 (fextend (v4f32 VR128:$src))),
2343             (VCVTPS2PDYrr VR128:$src)>;
2344   def : Pat<(v4f64 (extloadv4f32 addr:$src)),
2345             (VCVTPS2PDYrm addr:$src)>;
2346 }
2347
2348 let Predicates = [UseSSE2] in {
2349   // Match fround and fextend for 128 conversions
2350   def : Pat<(v4f32 (X86vfpround (v2f64 VR128:$src))),
2351             (CVTPD2PSrr VR128:$src)>;
2352   def : Pat<(v4f32 (X86vfpround (memopv2f64 addr:$src))),
2353             (CVTPD2PSrm addr:$src)>;
2354
2355   def : Pat<(v2f64 (X86vfpext (v4f32 VR128:$src))),
2356             (CVTPS2PDrr VR128:$src)>;
2357 }
2358
2359 //===----------------------------------------------------------------------===//
2360 // SSE 1 & 2 - Compare Instructions
2361 //===----------------------------------------------------------------------===//
2362
2363 // sse12_cmp_scalar - sse 1 & 2 compare scalar instructions
2364 multiclass sse12_cmp_scalar<RegisterClass RC, X86MemOperand x86memop,
2365                             Operand CC, SDNode OpNode, ValueType VT,
2366                             PatFrag ld_frag, string asm, string asm_alt,
2367                             OpndItins itins> {
2368   def rr : SIi8<0xC2, MRMSrcReg,
2369                 (outs RC:$dst), (ins RC:$src1, RC:$src2, CC:$cc), asm,
2370                 [(set RC:$dst, (OpNode (VT RC:$src1), RC:$src2, imm:$cc))],
2371                 itins.rr>, Sched<[itins.Sched]>;
2372   def rm : SIi8<0xC2, MRMSrcMem,
2373                 (outs RC:$dst), (ins RC:$src1, x86memop:$src2, CC:$cc), asm,
2374                 [(set RC:$dst, (OpNode (VT RC:$src1),
2375                                          (ld_frag addr:$src2), imm:$cc))],
2376                                          itins.rm>,
2377            Sched<[itins.Sched.Folded, ReadAfterLd]>;
2378
2379   // Accept explicit immediate argument form instead of comparison code.
2380   let isAsmParserOnly = 1, hasSideEffects = 0 in {
2381     def rr_alt : SIi8<0xC2, MRMSrcReg, (outs RC:$dst),
2382                       (ins RC:$src1, RC:$src2, i8imm:$cc), asm_alt, [],
2383                       IIC_SSE_ALU_F32S_RR>, Sched<[itins.Sched]>;
2384     let mayLoad = 1 in
2385     def rm_alt : SIi8<0xC2, MRMSrcMem, (outs RC:$dst),
2386                       (ins RC:$src1, x86memop:$src2, i8imm:$cc), asm_alt, [],
2387                       IIC_SSE_ALU_F32S_RM>,
2388                       Sched<[itins.Sched.Folded, ReadAfterLd]>;
2389   }
2390 }
2391
2392 defm VCMPSS : sse12_cmp_scalar<FR32, f32mem, AVXCC, X86cmps, f32, loadf32,
2393                  "cmp${cc}ss\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2394                  "cmpss\t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}",
2395                  SSE_ALU_F32S>,
2396                  XS, VEX_4V, VEX_LIG;
2397 defm VCMPSD : sse12_cmp_scalar<FR64, f64mem, AVXCC, X86cmps, f64, loadf64,
2398                  "cmp${cc}sd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2399                  "cmpsd\t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}",
2400                  SSE_ALU_F32S>, // same latency as 32 bit compare
2401                  XD, VEX_4V, VEX_LIG;
2402
2403 let Constraints = "$src1 = $dst" in {
2404   defm CMPSS : sse12_cmp_scalar<FR32, f32mem, SSECC, X86cmps, f32, loadf32,
2405                   "cmp${cc}ss\t{$src2, $dst|$dst, $src2}",
2406                   "cmpss\t{$cc, $src2, $dst|$dst, $src2, $cc}", SSE_ALU_F32S>,
2407                   XS;
2408   defm CMPSD : sse12_cmp_scalar<FR64, f64mem, SSECC, X86cmps, f64, loadf64,
2409                   "cmp${cc}sd\t{$src2, $dst|$dst, $src2}",
2410                   "cmpsd\t{$cc, $src2, $dst|$dst, $src2, $cc}",
2411                   SSE_ALU_F64S>,
2412                   XD;
2413 }
2414
2415 multiclass sse12_cmp_scalar_int<X86MemOperand x86memop, Operand CC,
2416                          Intrinsic Int, string asm, OpndItins itins> {
2417   def rr : SIi8<0xC2, MRMSrcReg, (outs VR128:$dst),
2418                       (ins VR128:$src1, VR128:$src, CC:$cc), asm,
2419                         [(set VR128:$dst, (Int VR128:$src1,
2420                                                VR128:$src, imm:$cc))],
2421                                                itins.rr>,
2422            Sched<[itins.Sched]>;
2423   def rm : SIi8<0xC2, MRMSrcMem, (outs VR128:$dst),
2424                       (ins VR128:$src1, x86memop:$src, CC:$cc), asm,
2425                         [(set VR128:$dst, (Int VR128:$src1,
2426                                                (load addr:$src), imm:$cc))],
2427                                                itins.rm>,
2428            Sched<[itins.Sched.Folded, ReadAfterLd]>;
2429 }
2430
2431 let isCodeGenOnly = 1 in {
2432   // Aliases to match intrinsics which expect XMM operand(s).
2433   defm Int_VCMPSS  : sse12_cmp_scalar_int<f32mem, AVXCC, int_x86_sse_cmp_ss,
2434                        "cmp${cc}ss\t{$src, $src1, $dst|$dst, $src1, $src}",
2435                        SSE_ALU_F32S>,
2436                        XS, VEX_4V;
2437   defm Int_VCMPSD  : sse12_cmp_scalar_int<f64mem, AVXCC, int_x86_sse2_cmp_sd,
2438                        "cmp${cc}sd\t{$src, $src1, $dst|$dst, $src1, $src}",
2439                        SSE_ALU_F32S>, // same latency as f32
2440                        XD, VEX_4V;
2441   let Constraints = "$src1 = $dst" in {
2442     defm Int_CMPSS  : sse12_cmp_scalar_int<f32mem, SSECC, int_x86_sse_cmp_ss,
2443                          "cmp${cc}ss\t{$src, $dst|$dst, $src}",
2444                          SSE_ALU_F32S>, XS;
2445     defm Int_CMPSD  : sse12_cmp_scalar_int<f64mem, SSECC, int_x86_sse2_cmp_sd,
2446                          "cmp${cc}sd\t{$src, $dst|$dst, $src}",
2447                          SSE_ALU_F64S>,
2448                          XD;
2449 }
2450 }
2451
2452
2453 // sse12_ord_cmp - Unordered/Ordered scalar fp compare and set EFLAGS
2454 multiclass sse12_ord_cmp<bits<8> opc, RegisterClass RC, SDNode OpNode,
2455                             ValueType vt, X86MemOperand x86memop,
2456                             PatFrag ld_frag, string OpcodeStr> {
2457   def rr: SI<opc, MRMSrcReg, (outs), (ins RC:$src1, RC:$src2),
2458                      !strconcat(OpcodeStr, "\t{$src2, $src1|$src1, $src2}"),
2459                      [(set EFLAGS, (OpNode (vt RC:$src1), RC:$src2))],
2460                      IIC_SSE_COMIS_RR>,
2461           Sched<[WriteFAdd]>;
2462   def rm: SI<opc, MRMSrcMem, (outs), (ins RC:$src1, x86memop:$src2),
2463                      !strconcat(OpcodeStr, "\t{$src2, $src1|$src1, $src2}"),
2464                      [(set EFLAGS, (OpNode (vt RC:$src1),
2465                                            (ld_frag addr:$src2)))],
2466                                            IIC_SSE_COMIS_RM>,
2467           Sched<[WriteFAddLd, ReadAfterLd]>;
2468 }
2469
2470 let Defs = [EFLAGS] in {
2471   defm VUCOMISS : sse12_ord_cmp<0x2E, FR32, X86cmp, f32, f32mem, loadf32,
2472                                   "ucomiss">, PS, VEX, VEX_LIG;
2473   defm VUCOMISD : sse12_ord_cmp<0x2E, FR64, X86cmp, f64, f64mem, loadf64,
2474                                   "ucomisd">, PD, VEX, VEX_LIG;
2475   let Pattern = []<dag> in {
2476     defm VCOMISS  : sse12_ord_cmp<0x2F, VR128, undef, v4f32, f128mem, load,
2477                                     "comiss">, PS, VEX, VEX_LIG;
2478     defm VCOMISD  : sse12_ord_cmp<0x2F, VR128, undef, v2f64, f128mem, load,
2479                                     "comisd">, PD, VEX, VEX_LIG;
2480   }
2481
2482   let isCodeGenOnly = 1 in {
2483     defm Int_VUCOMISS  : sse12_ord_cmp<0x2E, VR128, X86ucomi, v4f32, f128mem,
2484                               load, "ucomiss">, PS, VEX;
2485     defm Int_VUCOMISD  : sse12_ord_cmp<0x2E, VR128, X86ucomi, v2f64, f128mem,
2486                               load, "ucomisd">, PD, VEX;
2487
2488     defm Int_VCOMISS  : sse12_ord_cmp<0x2F, VR128, X86comi, v4f32, f128mem,
2489                               load, "comiss">, PS, VEX;
2490     defm Int_VCOMISD  : sse12_ord_cmp<0x2F, VR128, X86comi, v2f64, f128mem,
2491                               load, "comisd">, PD, VEX;
2492   }
2493   defm UCOMISS  : sse12_ord_cmp<0x2E, FR32, X86cmp, f32, f32mem, loadf32,
2494                                   "ucomiss">, PS;
2495   defm UCOMISD  : sse12_ord_cmp<0x2E, FR64, X86cmp, f64, f64mem, loadf64,
2496                                   "ucomisd">, PD;
2497
2498   let Pattern = []<dag> in {
2499     defm COMISS  : sse12_ord_cmp<0x2F, VR128, undef, v4f32, f128mem, load,
2500                                     "comiss">, PS;
2501     defm COMISD  : sse12_ord_cmp<0x2F, VR128, undef, v2f64, f128mem, load,
2502                                     "comisd">, PD;
2503   }
2504
2505   let isCodeGenOnly = 1 in {
2506     defm Int_UCOMISS  : sse12_ord_cmp<0x2E, VR128, X86ucomi, v4f32, f128mem,
2507                                 load, "ucomiss">, PS;
2508     defm Int_UCOMISD  : sse12_ord_cmp<0x2E, VR128, X86ucomi, v2f64, f128mem,
2509                                 load, "ucomisd">, PD;
2510
2511     defm Int_COMISS  : sse12_ord_cmp<0x2F, VR128, X86comi, v4f32, f128mem, load,
2512                                     "comiss">, PS;
2513     defm Int_COMISD  : sse12_ord_cmp<0x2F, VR128, X86comi, v2f64, f128mem, load,
2514                                     "comisd">, PD;
2515   }
2516 } // Defs = [EFLAGS]
2517
2518 // sse12_cmp_packed - sse 1 & 2 compare packed instructions
2519 multiclass sse12_cmp_packed<RegisterClass RC, X86MemOperand x86memop,
2520                             Operand CC, Intrinsic Int, string asm,
2521                             string asm_alt, Domain d,
2522                             OpndItins itins = SSE_ALU_F32P> {
2523   def rri : PIi8<0xC2, MRMSrcReg,
2524              (outs RC:$dst), (ins RC:$src1, RC:$src2, CC:$cc), asm,
2525              [(set RC:$dst, (Int RC:$src1, RC:$src2, imm:$cc))],
2526              itins.rr, d>,
2527             Sched<[WriteFAdd]>;
2528   def rmi : PIi8<0xC2, MRMSrcMem,
2529              (outs RC:$dst), (ins RC:$src1, x86memop:$src2, CC:$cc), asm,
2530              [(set RC:$dst, (Int RC:$src1, (memop addr:$src2), imm:$cc))],
2531              itins.rm, d>,
2532             Sched<[WriteFAddLd, ReadAfterLd]>;
2533
2534   // Accept explicit immediate argument form instead of comparison code.
2535   let isAsmParserOnly = 1, hasSideEffects = 0 in {
2536     def rri_alt : PIi8<0xC2, MRMSrcReg,
2537                (outs RC:$dst), (ins RC:$src1, RC:$src2, i8imm:$cc),
2538                asm_alt, [], itins.rr, d>, Sched<[WriteFAdd]>;
2539     def rmi_alt : PIi8<0xC2, MRMSrcMem,
2540                (outs RC:$dst), (ins RC:$src1, x86memop:$src2, i8imm:$cc),
2541                asm_alt, [], itins.rm, d>,
2542                Sched<[WriteFAddLd, ReadAfterLd]>;
2543   }
2544 }
2545
2546 defm VCMPPS : sse12_cmp_packed<VR128, f128mem, AVXCC, int_x86_sse_cmp_ps,
2547                "cmp${cc}ps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2548                "cmpps\t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}",
2549                SSEPackedSingle>, PS, VEX_4V;
2550 defm VCMPPD : sse12_cmp_packed<VR128, f128mem, AVXCC, int_x86_sse2_cmp_pd,
2551                "cmp${cc}pd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2552                "cmppd\t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}",
2553                SSEPackedDouble>, PD, VEX_4V;
2554 defm VCMPPSY : sse12_cmp_packed<VR256, f256mem, AVXCC, int_x86_avx_cmp_ps_256,
2555                "cmp${cc}ps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2556                "cmpps\t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}",
2557                SSEPackedSingle>, PS, VEX_4V, VEX_L;
2558 defm VCMPPDY : sse12_cmp_packed<VR256, f256mem, AVXCC, int_x86_avx_cmp_pd_256,
2559                "cmp${cc}pd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2560                "cmppd\t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}",
2561                SSEPackedDouble>, PD, VEX_4V, VEX_L;
2562 let Constraints = "$src1 = $dst" in {
2563   defm CMPPS : sse12_cmp_packed<VR128, f128mem, SSECC, int_x86_sse_cmp_ps,
2564                  "cmp${cc}ps\t{$src2, $dst|$dst, $src2}",
2565                  "cmpps\t{$cc, $src2, $dst|$dst, $src2, $cc}",
2566                  SSEPackedSingle, SSE_ALU_F32P>, PS;
2567   defm CMPPD : sse12_cmp_packed<VR128, f128mem, SSECC, int_x86_sse2_cmp_pd,
2568                  "cmp${cc}pd\t{$src2, $dst|$dst, $src2}",
2569                  "cmppd\t{$cc, $src2, $dst|$dst, $src2, $cc}",
2570                  SSEPackedDouble, SSE_ALU_F64P>, PD;
2571 }
2572
2573 let Predicates = [HasAVX] in {
2574 def : Pat<(v4i32 (X86cmpp (v4f32 VR128:$src1), VR128:$src2, imm:$cc)),
2575           (VCMPPSrri (v4f32 VR128:$src1), (v4f32 VR128:$src2), imm:$cc)>;
2576 def : Pat<(v4i32 (X86cmpp (v4f32 VR128:$src1), (memop addr:$src2), imm:$cc)),
2577           (VCMPPSrmi (v4f32 VR128:$src1), addr:$src2, imm:$cc)>;
2578 def : Pat<(v2i64 (X86cmpp (v2f64 VR128:$src1), VR128:$src2, imm:$cc)),
2579           (VCMPPDrri VR128:$src1, VR128:$src2, imm:$cc)>;
2580 def : Pat<(v2i64 (X86cmpp (v2f64 VR128:$src1), (memop addr:$src2), imm:$cc)),
2581           (VCMPPDrmi VR128:$src1, addr:$src2, imm:$cc)>;
2582
2583 def : Pat<(v8i32 (X86cmpp (v8f32 VR256:$src1), VR256:$src2, imm:$cc)),
2584           (VCMPPSYrri (v8f32 VR256:$src1), (v8f32 VR256:$src2), imm:$cc)>;
2585 def : Pat<(v8i32 (X86cmpp (v8f32 VR256:$src1), (memop addr:$src2), imm:$cc)),
2586           (VCMPPSYrmi (v8f32 VR256:$src1), addr:$src2, imm:$cc)>;
2587 def : Pat<(v4i64 (X86cmpp (v4f64 VR256:$src1), VR256:$src2, imm:$cc)),
2588           (VCMPPDYrri VR256:$src1, VR256:$src2, imm:$cc)>;
2589 def : Pat<(v4i64 (X86cmpp (v4f64 VR256:$src1), (memop addr:$src2), imm:$cc)),
2590           (VCMPPDYrmi VR256:$src1, addr:$src2, imm:$cc)>;
2591 }
2592
2593 let Predicates = [UseSSE1] in {
2594 def : Pat<(v4i32 (X86cmpp (v4f32 VR128:$src1), VR128:$src2, imm:$cc)),
2595           (CMPPSrri (v4f32 VR128:$src1), (v4f32 VR128:$src2), imm:$cc)>;
2596 def : Pat<(v4i32 (X86cmpp (v4f32 VR128:$src1), (memop addr:$src2), imm:$cc)),
2597           (CMPPSrmi (v4f32 VR128:$src1), addr:$src2, imm:$cc)>;
2598 }
2599
2600 let Predicates = [UseSSE2] in {
2601 def : Pat<(v2i64 (X86cmpp (v2f64 VR128:$src1), VR128:$src2, imm:$cc)),
2602           (CMPPDrri VR128:$src1, VR128:$src2, imm:$cc)>;
2603 def : Pat<(v2i64 (X86cmpp (v2f64 VR128:$src1), (memop addr:$src2), imm:$cc)),
2604           (CMPPDrmi VR128:$src1, addr:$src2, imm:$cc)>;
2605 }
2606
2607 //===----------------------------------------------------------------------===//
2608 // SSE 1 & 2 - Shuffle Instructions
2609 //===----------------------------------------------------------------------===//
2610
2611 /// sse12_shuffle - sse 1 & 2 fp shuffle instructions
2612 multiclass sse12_shuffle<RegisterClass RC, X86MemOperand x86memop,
2613                          ValueType vt, string asm, PatFrag mem_frag,
2614                          Domain d, bit IsConvertibleToThreeAddress = 0> {
2615   def rmi : PIi8<0xC6, MRMSrcMem, (outs RC:$dst),
2616                    (ins RC:$src1, x86memop:$src2, i8imm:$src3), asm,
2617                    [(set RC:$dst, (vt (X86Shufp RC:$src1, (mem_frag addr:$src2),
2618                                        (i8 imm:$src3))))], IIC_SSE_SHUFP, d>,
2619             Sched<[WriteFShuffleLd, ReadAfterLd]>;
2620   let isConvertibleToThreeAddress = IsConvertibleToThreeAddress in
2621     def rri : PIi8<0xC6, MRMSrcReg, (outs RC:$dst),
2622                    (ins RC:$src1, RC:$src2, i8imm:$src3), asm,
2623                    [(set RC:$dst, (vt (X86Shufp RC:$src1, RC:$src2,
2624                                        (i8 imm:$src3))))], IIC_SSE_SHUFP, d>,
2625               Sched<[WriteFShuffle]>;
2626 }
2627
2628 defm VSHUFPS  : sse12_shuffle<VR128, f128mem, v4f32,
2629            "shufps\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
2630            loadv4f32, SSEPackedSingle>, PS, VEX_4V;
2631 defm VSHUFPSY : sse12_shuffle<VR256, f256mem, v8f32,
2632            "shufps\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
2633            loadv8f32, SSEPackedSingle>, PS, VEX_4V, VEX_L;
2634 defm VSHUFPD  : sse12_shuffle<VR128, f128mem, v2f64,
2635            "shufpd\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
2636            loadv2f64, SSEPackedDouble>, PD, VEX_4V;
2637 defm VSHUFPDY : sse12_shuffle<VR256, f256mem, v4f64,
2638            "shufpd\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
2639            loadv4f64, SSEPackedDouble>, PD, VEX_4V, VEX_L;
2640
2641 let Constraints = "$src1 = $dst" in {
2642   defm SHUFPS : sse12_shuffle<VR128, f128mem, v4f32,
2643                     "shufps\t{$src3, $src2, $dst|$dst, $src2, $src3}",
2644                     memopv4f32, SSEPackedSingle, 1 /* cvt to pshufd */>, PS;
2645   defm SHUFPD : sse12_shuffle<VR128, f128mem, v2f64,
2646                     "shufpd\t{$src3, $src2, $dst|$dst, $src2, $src3}",
2647                     memopv2f64, SSEPackedDouble, 1 /* cvt to pshufd */>, PD;
2648 }
2649
2650 let Predicates = [HasAVX] in {
2651   def : Pat<(v4i32 (X86Shufp VR128:$src1,
2652                        (bc_v4i32 (loadv2i64 addr:$src2)), (i8 imm:$imm))),
2653             (VSHUFPSrmi VR128:$src1, addr:$src2, imm:$imm)>;
2654   def : Pat<(v4i32 (X86Shufp VR128:$src1, VR128:$src2, (i8 imm:$imm))),
2655             (VSHUFPSrri VR128:$src1, VR128:$src2, imm:$imm)>;
2656
2657   def : Pat<(v2i64 (X86Shufp VR128:$src1,
2658                        (loadv2i64 addr:$src2), (i8 imm:$imm))),
2659             (VSHUFPDrmi VR128:$src1, addr:$src2, imm:$imm)>;
2660   def : Pat<(v2i64 (X86Shufp VR128:$src1, VR128:$src2, (i8 imm:$imm))),
2661             (VSHUFPDrri VR128:$src1, VR128:$src2, imm:$imm)>;
2662
2663   // 256-bit patterns
2664   def : Pat<(v8i32 (X86Shufp VR256:$src1, VR256:$src2, (i8 imm:$imm))),
2665             (VSHUFPSYrri VR256:$src1, VR256:$src2, imm:$imm)>;
2666   def : Pat<(v8i32 (X86Shufp VR256:$src1,
2667                       (bc_v8i32 (loadv4i64 addr:$src2)), (i8 imm:$imm))),
2668             (VSHUFPSYrmi VR256:$src1, addr:$src2, imm:$imm)>;
2669
2670   def : Pat<(v4i64 (X86Shufp VR256:$src1, VR256:$src2, (i8 imm:$imm))),
2671             (VSHUFPDYrri VR256:$src1, VR256:$src2, imm:$imm)>;
2672   def : Pat<(v4i64 (X86Shufp VR256:$src1,
2673                               (loadv4i64 addr:$src2), (i8 imm:$imm))),
2674             (VSHUFPDYrmi VR256:$src1, addr:$src2, imm:$imm)>;
2675 }
2676
2677 let Predicates = [UseSSE1] in {
2678   def : Pat<(v4i32 (X86Shufp VR128:$src1,
2679                        (bc_v4i32 (memopv2i64 addr:$src2)), (i8 imm:$imm))),
2680             (SHUFPSrmi VR128:$src1, addr:$src2, imm:$imm)>;
2681   def : Pat<(v4i32 (X86Shufp VR128:$src1, VR128:$src2, (i8 imm:$imm))),
2682             (SHUFPSrri VR128:$src1, VR128:$src2, imm:$imm)>;
2683 }
2684
2685 let Predicates = [UseSSE2] in {
2686   // Generic SHUFPD patterns
2687   def : Pat<(v2i64 (X86Shufp VR128:$src1,
2688                        (memopv2i64 addr:$src2), (i8 imm:$imm))),
2689             (SHUFPDrmi VR128:$src1, addr:$src2, imm:$imm)>;
2690   def : Pat<(v2i64 (X86Shufp VR128:$src1, VR128:$src2, (i8 imm:$imm))),
2691             (SHUFPDrri VR128:$src1, VR128:$src2, imm:$imm)>;
2692 }
2693
2694 //===----------------------------------------------------------------------===//
2695 // SSE 1 & 2 - Unpack FP Instructions
2696 //===----------------------------------------------------------------------===//
2697
2698 /// sse12_unpack_interleave - sse 1 & 2 fp unpack and interleave
2699 multiclass sse12_unpack_interleave<bits<8> opc, SDNode OpNode, ValueType vt,
2700                                    PatFrag mem_frag, RegisterClass RC,
2701                                    X86MemOperand x86memop, string asm,
2702                                    Domain d> {
2703     def rr : PI<opc, MRMSrcReg,
2704                 (outs RC:$dst), (ins RC:$src1, RC:$src2),
2705                 asm, [(set RC:$dst,
2706                            (vt (OpNode RC:$src1, RC:$src2)))],
2707                            IIC_SSE_UNPCK, d>, Sched<[WriteFShuffle]>;
2708     def rm : PI<opc, MRMSrcMem,
2709                 (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
2710                 asm, [(set RC:$dst,
2711                            (vt (OpNode RC:$src1,
2712                                        (mem_frag addr:$src2))))],
2713                                        IIC_SSE_UNPCK, d>,
2714              Sched<[WriteFShuffleLd, ReadAfterLd]>;
2715 }
2716
2717 defm VUNPCKHPS: sse12_unpack_interleave<0x15, X86Unpckh, v4f32, loadv4f32,
2718       VR128, f128mem, "unpckhps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2719                      SSEPackedSingle>, PS, VEX_4V;
2720 defm VUNPCKHPD: sse12_unpack_interleave<0x15, X86Unpckh, v2f64, loadv2f64,
2721       VR128, f128mem, "unpckhpd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2722                      SSEPackedDouble>, PD, VEX_4V;
2723 defm VUNPCKLPS: sse12_unpack_interleave<0x14, X86Unpckl, v4f32, loadv4f32,
2724       VR128, f128mem, "unpcklps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2725                      SSEPackedSingle>, PS, VEX_4V;
2726 defm VUNPCKLPD: sse12_unpack_interleave<0x14, X86Unpckl, v2f64, loadv2f64,
2727       VR128, f128mem, "unpcklpd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2728                      SSEPackedDouble>, PD, VEX_4V;
2729
2730 defm VUNPCKHPSY: sse12_unpack_interleave<0x15, X86Unpckh, v8f32, loadv8f32,
2731       VR256, f256mem, "unpckhps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2732                      SSEPackedSingle>, PS, VEX_4V, VEX_L;
2733 defm VUNPCKHPDY: sse12_unpack_interleave<0x15, X86Unpckh, v4f64, loadv4f64,
2734       VR256, f256mem, "unpckhpd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2735                      SSEPackedDouble>, PD, VEX_4V, VEX_L;
2736 defm VUNPCKLPSY: sse12_unpack_interleave<0x14, X86Unpckl, v8f32, loadv8f32,
2737       VR256, f256mem, "unpcklps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2738                      SSEPackedSingle>, PS, VEX_4V, VEX_L;
2739 defm VUNPCKLPDY: sse12_unpack_interleave<0x14, X86Unpckl, v4f64, loadv4f64,
2740       VR256, f256mem, "unpcklpd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2741                      SSEPackedDouble>, PD, VEX_4V, VEX_L;
2742
2743 let Constraints = "$src1 = $dst" in {
2744   defm UNPCKHPS: sse12_unpack_interleave<0x15, X86Unpckh, v4f32, memopv4f32,
2745         VR128, f128mem, "unpckhps\t{$src2, $dst|$dst, $src2}",
2746                        SSEPackedSingle>, PS;
2747   defm UNPCKHPD: sse12_unpack_interleave<0x15, X86Unpckh, v2f64, memopv2f64,
2748         VR128, f128mem, "unpckhpd\t{$src2, $dst|$dst, $src2}",
2749                        SSEPackedDouble>, PD;
2750   defm UNPCKLPS: sse12_unpack_interleave<0x14, X86Unpckl, v4f32, memopv4f32,
2751         VR128, f128mem, "unpcklps\t{$src2, $dst|$dst, $src2}",
2752                        SSEPackedSingle>, PS;
2753   defm UNPCKLPD: sse12_unpack_interleave<0x14, X86Unpckl, v2f64, memopv2f64,
2754         VR128, f128mem, "unpcklpd\t{$src2, $dst|$dst, $src2}",
2755                        SSEPackedDouble>, PD;
2756 } // Constraints = "$src1 = $dst"
2757
2758 let Predicates = [HasAVX1Only] in {
2759   def : Pat<(v8i32 (X86Unpckl VR256:$src1, (bc_v8i32 (loadv4i64 addr:$src2)))),
2760             (VUNPCKLPSYrm VR256:$src1, addr:$src2)>;
2761   def : Pat<(v8i32 (X86Unpckl VR256:$src1, VR256:$src2)),
2762             (VUNPCKLPSYrr VR256:$src1, VR256:$src2)>;
2763   def : Pat<(v8i32 (X86Unpckh VR256:$src1, (bc_v8i32 (loadv4i64 addr:$src2)))),
2764             (VUNPCKHPSYrm VR256:$src1, addr:$src2)>;
2765   def : Pat<(v8i32 (X86Unpckh VR256:$src1, VR256:$src2)),
2766             (VUNPCKHPSYrr VR256:$src1, VR256:$src2)>;
2767
2768   def : Pat<(v4i64 (X86Unpckl VR256:$src1, (loadv4i64 addr:$src2))),
2769             (VUNPCKLPDYrm VR256:$src1, addr:$src2)>;
2770   def : Pat<(v4i64 (X86Unpckl VR256:$src1, VR256:$src2)),
2771             (VUNPCKLPDYrr VR256:$src1, VR256:$src2)>;
2772   def : Pat<(v4i64 (X86Unpckh VR256:$src1, (loadv4i64 addr:$src2))),
2773             (VUNPCKHPDYrm VR256:$src1, addr:$src2)>;
2774   def : Pat<(v4i64 (X86Unpckh VR256:$src1, VR256:$src2)),
2775             (VUNPCKHPDYrr VR256:$src1, VR256:$src2)>;
2776 }
2777
2778 let Predicates = [HasAVX] in {
2779   // FIXME: Instead of X86Movddup, there should be a X86Unpckl here, the
2780   // problem is during lowering, where it's not possible to recognize the load
2781   // fold cause it has two uses through a bitcast. One use disappears at isel
2782   // time and the fold opportunity reappears.
2783   def : Pat<(v2f64 (X86Movddup VR128:$src)),
2784             (VUNPCKLPDrr VR128:$src, VR128:$src)>;
2785 }
2786
2787 let Predicates = [UseSSE2] in {
2788   // FIXME: Instead of X86Movddup, there should be a X86Unpckl here, the
2789   // problem is during lowering, where it's not possible to recognize the load
2790   // fold cause it has two uses through a bitcast. One use disappears at isel
2791   // time and the fold opportunity reappears.
2792   def : Pat<(v2f64 (X86Movddup VR128:$src)),
2793             (UNPCKLPDrr VR128:$src, VR128:$src)>;
2794 }
2795
2796 //===----------------------------------------------------------------------===//
2797 // SSE 1 & 2 - Extract Floating-Point Sign mask
2798 //===----------------------------------------------------------------------===//
2799
2800 /// sse12_extr_sign_mask - sse 1 & 2 unpack and interleave
2801 multiclass sse12_extr_sign_mask<RegisterClass RC, Intrinsic Int, string asm,
2802                                 Domain d> {
2803   def rr : PI<0x50, MRMSrcReg, (outs GR32orGR64:$dst), (ins RC:$src),
2804               !strconcat(asm, "\t{$src, $dst|$dst, $src}"),
2805               [(set GR32orGR64:$dst, (Int RC:$src))], IIC_SSE_MOVMSK, d>,
2806               Sched<[WriteVecLogic]>;
2807 }
2808
2809 let Predicates = [HasAVX] in {
2810   defm VMOVMSKPS : sse12_extr_sign_mask<VR128, int_x86_sse_movmsk_ps,
2811                                         "movmskps", SSEPackedSingle>, PS, VEX;
2812   defm VMOVMSKPD : sse12_extr_sign_mask<VR128, int_x86_sse2_movmsk_pd,
2813                                         "movmskpd", SSEPackedDouble>, PD, VEX;
2814   defm VMOVMSKPSY : sse12_extr_sign_mask<VR256, int_x86_avx_movmsk_ps_256,
2815                                         "movmskps", SSEPackedSingle>, PS,
2816                                         VEX, VEX_L;
2817   defm VMOVMSKPDY : sse12_extr_sign_mask<VR256, int_x86_avx_movmsk_pd_256,
2818                                         "movmskpd", SSEPackedDouble>, PD,
2819                                         VEX, VEX_L;
2820
2821   def : Pat<(i32 (X86fgetsign FR32:$src)),
2822             (VMOVMSKPSrr (COPY_TO_REGCLASS FR32:$src, VR128))>;
2823   def : Pat<(i64 (X86fgetsign FR32:$src)),
2824             (SUBREG_TO_REG (i64 0),
2825              (VMOVMSKPSrr (COPY_TO_REGCLASS FR32:$src, VR128)), sub_32bit)>;
2826   def : Pat<(i32 (X86fgetsign FR64:$src)),
2827             (VMOVMSKPDrr (COPY_TO_REGCLASS FR64:$src, VR128))>;
2828   def : Pat<(i64 (X86fgetsign FR64:$src)),
2829             (SUBREG_TO_REG (i64 0),
2830              (VMOVMSKPDrr (COPY_TO_REGCLASS FR64:$src, VR128)), sub_32bit)>;
2831 }
2832
2833 defm MOVMSKPS : sse12_extr_sign_mask<VR128, int_x86_sse_movmsk_ps, "movmskps",
2834                                      SSEPackedSingle>, PS;
2835 defm MOVMSKPD : sse12_extr_sign_mask<VR128, int_x86_sse2_movmsk_pd, "movmskpd",
2836                                      SSEPackedDouble>, PD;
2837
2838 def : Pat<(i32 (X86fgetsign FR32:$src)),
2839           (MOVMSKPSrr (COPY_TO_REGCLASS FR32:$src, VR128))>,
2840       Requires<[UseSSE1]>;
2841 def : Pat<(i64 (X86fgetsign FR32:$src)),
2842           (SUBREG_TO_REG (i64 0),
2843            (MOVMSKPSrr (COPY_TO_REGCLASS FR32:$src, VR128)), sub_32bit)>,
2844       Requires<[UseSSE1]>;
2845 def : Pat<(i32 (X86fgetsign FR64:$src)),
2846           (MOVMSKPDrr (COPY_TO_REGCLASS FR64:$src, VR128))>,
2847       Requires<[UseSSE2]>;
2848 def : Pat<(i64 (X86fgetsign FR64:$src)),
2849           (SUBREG_TO_REG (i64 0),
2850            (MOVMSKPDrr (COPY_TO_REGCLASS FR64:$src, VR128)), sub_32bit)>,
2851       Requires<[UseSSE2]>;
2852
2853 //===---------------------------------------------------------------------===//
2854 // SSE2 - Packed Integer Logical Instructions
2855 //===---------------------------------------------------------------------===//
2856
2857 let ExeDomain = SSEPackedInt in { // SSE integer instructions
2858
2859 /// PDI_binop_rm - Simple SSE2 binary operator.
2860 multiclass PDI_binop_rm<bits<8> opc, string OpcodeStr, SDNode OpNode,
2861                         ValueType OpVT, RegisterClass RC, PatFrag memop_frag,
2862                         X86MemOperand x86memop, OpndItins itins,
2863                         bit IsCommutable, bit Is2Addr> {
2864   let isCommutable = IsCommutable in
2865   def rr : PDI<opc, MRMSrcReg, (outs RC:$dst),
2866        (ins RC:$src1, RC:$src2),
2867        !if(Is2Addr,
2868            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
2869            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
2870        [(set RC:$dst, (OpVT (OpNode RC:$src1, RC:$src2)))], itins.rr>,
2871        Sched<[itins.Sched]>;
2872   def rm : PDI<opc, MRMSrcMem, (outs RC:$dst),
2873        (ins RC:$src1, x86memop:$src2),
2874        !if(Is2Addr,
2875            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
2876            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
2877        [(set RC:$dst, (OpVT (OpNode RC:$src1,
2878                                      (bitconvert (memop_frag addr:$src2)))))],
2879                                      itins.rm>,
2880        Sched<[itins.Sched.Folded, ReadAfterLd]>;
2881 }
2882 } // ExeDomain = SSEPackedInt
2883
2884 multiclass PDI_binop_all<bits<8> opc, string OpcodeStr, SDNode Opcode,
2885                          ValueType OpVT128, ValueType OpVT256,
2886                          OpndItins itins, bit IsCommutable = 0> {
2887 let Predicates = [HasAVX] in
2888   defm V#NAME : PDI_binop_rm<opc, !strconcat("v", OpcodeStr), Opcode, OpVT128,
2889                     VR128, loadv2i64, i128mem, itins, IsCommutable, 0>, VEX_4V;
2890
2891 let Constraints = "$src1 = $dst" in
2892   defm NAME : PDI_binop_rm<opc, OpcodeStr, Opcode, OpVT128, VR128,
2893                            memopv2i64, i128mem, itins, IsCommutable, 1>;
2894
2895 let Predicates = [HasAVX2] in
2896   defm V#NAME#Y : PDI_binop_rm<opc, !strconcat("v", OpcodeStr), Opcode,
2897                                OpVT256, VR256, loadv4i64, i256mem, itins,
2898                                IsCommutable, 0>, VEX_4V, VEX_L;
2899 }
2900
2901 // These are ordered here for pattern ordering requirements with the fp versions
2902
2903 defm PAND  : PDI_binop_all<0xDB, "pand", and, v2i64, v4i64,
2904                            SSE_VEC_BIT_ITINS_P, 1>;
2905 defm POR   : PDI_binop_all<0xEB, "por", or, v2i64, v4i64,
2906                            SSE_VEC_BIT_ITINS_P, 1>;
2907 defm PXOR  : PDI_binop_all<0xEF, "pxor", xor, v2i64, v4i64,
2908                            SSE_VEC_BIT_ITINS_P, 1>;
2909 defm PANDN : PDI_binop_all<0xDF, "pandn", X86andnp, v2i64, v4i64,
2910                            SSE_VEC_BIT_ITINS_P, 0>;
2911
2912 //===----------------------------------------------------------------------===//
2913 // SSE 1 & 2 - Logical Instructions
2914 //===----------------------------------------------------------------------===//
2915
2916 /// sse12_fp_alias_pack_logical - SSE 1 & 2 aliased packed FP logical ops
2917 ///
2918 multiclass sse12_fp_alias_pack_logical<bits<8> opc, string OpcodeStr,
2919                                        SDNode OpNode, OpndItins itins> {
2920   defm V#NAME#PS : sse12_fp_packed<opc, !strconcat(OpcodeStr, "ps"), OpNode,
2921               FR32, f32, f128mem, memopfsf32, SSEPackedSingle, itins, 0>,
2922               PS, VEX_4V;
2923
2924   defm V#NAME#PD : sse12_fp_packed<opc, !strconcat(OpcodeStr, "pd"), OpNode,
2925         FR64, f64, f128mem, memopfsf64, SSEPackedDouble, itins, 0>,
2926         PD, VEX_4V;
2927
2928   let Constraints = "$src1 = $dst" in {
2929     defm PS : sse12_fp_packed<opc, !strconcat(OpcodeStr, "ps"), OpNode, FR32,
2930                 f32, f128mem, memopfsf32, SSEPackedSingle, itins>,
2931                 PS;
2932
2933     defm PD : sse12_fp_packed<opc, !strconcat(OpcodeStr, "pd"), OpNode, FR64,
2934                 f64, f128mem, memopfsf64, SSEPackedDouble, itins>,
2935                 PD;
2936   }
2937 }
2938
2939 // Alias bitwise logical operations using SSE logical ops on packed FP values.
2940 let isCodeGenOnly = 1 in {
2941   defm FsAND  : sse12_fp_alias_pack_logical<0x54, "and", X86fand,
2942                 SSE_BIT_ITINS_P>;
2943   defm FsOR   : sse12_fp_alias_pack_logical<0x56, "or", X86for,
2944                 SSE_BIT_ITINS_P>;
2945   defm FsXOR  : sse12_fp_alias_pack_logical<0x57, "xor", X86fxor,
2946                 SSE_BIT_ITINS_P>;
2947
2948   let isCommutable = 0 in
2949     defm FsANDN : sse12_fp_alias_pack_logical<0x55, "andn", X86fandn,
2950                   SSE_BIT_ITINS_P>;
2951 }
2952
2953 /// sse12_fp_packed_logical - SSE 1 & 2 packed FP logical ops
2954 ///
2955 multiclass sse12_fp_packed_logical<bits<8> opc, string OpcodeStr,
2956                                    SDNode OpNode> {
2957   defm V#NAME#PSY : sse12_fp_packed_logical_rm<opc, VR256, SSEPackedSingle,
2958         !strconcat(OpcodeStr, "ps"), f256mem,
2959         [(set VR256:$dst, (v4i64 (OpNode VR256:$src1, VR256:$src2)))],
2960         [(set VR256:$dst, (OpNode (bc_v4i64 (v8f32 VR256:$src1)),
2961                            (loadv4i64 addr:$src2)))], 0>, PS, VEX_4V, VEX_L;
2962
2963   defm V#NAME#PDY : sse12_fp_packed_logical_rm<opc, VR256, SSEPackedDouble,
2964         !strconcat(OpcodeStr, "pd"), f256mem,
2965         [(set VR256:$dst, (OpNode (bc_v4i64 (v4f64 VR256:$src1)),
2966                                   (bc_v4i64 (v4f64 VR256:$src2))))],
2967         [(set VR256:$dst, (OpNode (bc_v4i64 (v4f64 VR256:$src1)),
2968                                   (loadv4i64 addr:$src2)))], 0>,
2969                                   PD, VEX_4V, VEX_L;
2970
2971   // In AVX no need to add a pattern for 128-bit logical rr ps, because they
2972   // are all promoted to v2i64, and the patterns are covered by the int
2973   // version. This is needed in SSE only, because v2i64 isn't supported on
2974   // SSE1, but only on SSE2.
2975   defm V#NAME#PS : sse12_fp_packed_logical_rm<opc, VR128, SSEPackedSingle,
2976        !strconcat(OpcodeStr, "ps"), f128mem, [],
2977        [(set VR128:$dst, (OpNode (bc_v2i64 (v4f32 VR128:$src1)),
2978                                  (loadv2i64 addr:$src2)))], 0>, PS, VEX_4V;
2979
2980   defm V#NAME#PD : sse12_fp_packed_logical_rm<opc, VR128, SSEPackedDouble,
2981        !strconcat(OpcodeStr, "pd"), f128mem,
2982        [(set VR128:$dst, (OpNode (bc_v2i64 (v2f64 VR128:$src1)),
2983                                  (bc_v2i64 (v2f64 VR128:$src2))))],
2984        [(set VR128:$dst, (OpNode (bc_v2i64 (v2f64 VR128:$src1)),
2985                                  (loadv2i64 addr:$src2)))], 0>,
2986                                                  PD, VEX_4V;
2987
2988   let Constraints = "$src1 = $dst" in {
2989     defm PS : sse12_fp_packed_logical_rm<opc, VR128, SSEPackedSingle,
2990          !strconcat(OpcodeStr, "ps"), f128mem,
2991          [(set VR128:$dst, (v2i64 (OpNode VR128:$src1, VR128:$src2)))],
2992          [(set VR128:$dst, (OpNode (bc_v2i64 (v4f32 VR128:$src1)),
2993                                    (memopv2i64 addr:$src2)))]>, PS;
2994
2995     defm PD : sse12_fp_packed_logical_rm<opc, VR128, SSEPackedDouble,
2996          !strconcat(OpcodeStr, "pd"), f128mem,
2997          [(set VR128:$dst, (OpNode (bc_v2i64 (v2f64 VR128:$src1)),
2998                                    (bc_v2i64 (v2f64 VR128:$src2))))],
2999          [(set VR128:$dst, (OpNode (bc_v2i64 (v2f64 VR128:$src1)),
3000                                    (memopv2i64 addr:$src2)))]>, PD;
3001   }
3002 }
3003
3004 defm AND  : sse12_fp_packed_logical<0x54, "and", and>;
3005 defm OR   : sse12_fp_packed_logical<0x56, "or", or>;
3006 defm XOR  : sse12_fp_packed_logical<0x57, "xor", xor>;
3007 let isCommutable = 0 in
3008   defm ANDN : sse12_fp_packed_logical<0x55, "andn", X86andnp>;
3009
3010 // AVX1 requires type coercions in order to fold loads directly into logical
3011 // operations.
3012 let Predicates = [HasAVX1Only] in {
3013   def : Pat<(bc_v8f32 (and VR256:$src1, (loadv4i64 addr:$src2))),
3014             (VANDPSYrm VR256:$src1, addr:$src2)>;
3015   def : Pat<(bc_v8f32 (or VR256:$src1, (loadv4i64 addr:$src2))),
3016             (VORPSYrm VR256:$src1, addr:$src2)>;
3017   def : Pat<(bc_v8f32 (xor VR256:$src1, (loadv4i64 addr:$src2))),
3018             (VXORPSYrm VR256:$src1, addr:$src2)>;
3019   def : Pat<(bc_v8f32 (X86andnp VR256:$src1, (loadv4i64 addr:$src2))),
3020             (VANDNPSYrm VR256:$src1, addr:$src2)>;
3021 }
3022
3023 //===----------------------------------------------------------------------===//
3024 // SSE 1 & 2 - Arithmetic Instructions
3025 //===----------------------------------------------------------------------===//
3026
3027 /// basic_sse12_fp_binop_xxx - SSE 1 & 2 binops come in both scalar and
3028 /// vector forms.
3029 ///
3030 /// In addition, we also have a special variant of the scalar form here to
3031 /// represent the associated intrinsic operation.  This form is unlike the
3032 /// plain scalar form, in that it takes an entire vector (instead of a scalar)
3033 /// and leaves the top elements unmodified (therefore these cannot be commuted).
3034 ///
3035 /// These three forms can each be reg+reg or reg+mem.
3036 ///
3037
3038 /// FIXME: once all 256-bit intrinsics are matched, cleanup and refactor those
3039 /// classes below
3040 multiclass basic_sse12_fp_binop_p<bits<8> opc, string OpcodeStr,
3041                                   SDNode OpNode, SizeItins itins> {
3042   defm V#NAME#PS : sse12_fp_packed<opc, !strconcat(OpcodeStr, "ps"), OpNode,
3043                                VR128, v4f32, f128mem, loadv4f32,
3044                                SSEPackedSingle, itins.s, 0>, PS, VEX_4V;
3045   defm V#NAME#PD : sse12_fp_packed<opc, !strconcat(OpcodeStr, "pd"), OpNode,
3046                                VR128, v2f64, f128mem, loadv2f64,
3047                                SSEPackedDouble, itins.d, 0>, PD, VEX_4V;
3048
3049   defm V#NAME#PSY : sse12_fp_packed<opc, !strconcat(OpcodeStr, "ps"),
3050                         OpNode, VR256, v8f32, f256mem, loadv8f32,
3051                         SSEPackedSingle, itins.s, 0>, PS, VEX_4V, VEX_L;
3052   defm V#NAME#PDY : sse12_fp_packed<opc, !strconcat(OpcodeStr, "pd"),
3053                         OpNode, VR256, v4f64, f256mem, loadv4f64,
3054                         SSEPackedDouble, itins.d, 0>, PD, VEX_4V, VEX_L;
3055
3056   let Constraints = "$src1 = $dst" in {
3057     defm PS : sse12_fp_packed<opc, !strconcat(OpcodeStr, "ps"), OpNode, VR128,
3058                               v4f32, f128mem, memopv4f32, SSEPackedSingle,
3059                               itins.s>, PS;
3060     defm PD : sse12_fp_packed<opc, !strconcat(OpcodeStr, "pd"), OpNode, VR128,
3061                               v2f64, f128mem, memopv2f64, SSEPackedDouble,
3062                               itins.d>, PD;
3063   }
3064 }
3065
3066 multiclass basic_sse12_fp_binop_s<bits<8> opc, string OpcodeStr, SDNode OpNode,
3067                                   SizeItins itins> {
3068   defm V#NAME#SS : sse12_fp_scalar<opc, !strconcat(OpcodeStr, "ss"),
3069                          OpNode, FR32, f32mem, itins.s, 0>, XS, VEX_4V, VEX_LIG;
3070   defm V#NAME#SD : sse12_fp_scalar<opc, !strconcat(OpcodeStr, "sd"),
3071                          OpNode, FR64, f64mem, itins.d, 0>, XD, VEX_4V, VEX_LIG;
3072
3073   let Constraints = "$src1 = $dst" in {
3074     defm SS : sse12_fp_scalar<opc, !strconcat(OpcodeStr, "ss"),
3075                               OpNode, FR32, f32mem, itins.s>, XS;
3076     defm SD : sse12_fp_scalar<opc, !strconcat(OpcodeStr, "sd"),
3077                               OpNode, FR64, f64mem, itins.d>, XD;
3078   }
3079 }
3080
3081 multiclass basic_sse12_fp_binop_s_int<bits<8> opc, string OpcodeStr,
3082                                       SizeItins itins> {
3083   defm V#NAME#SS : sse12_fp_scalar_int<opc, OpcodeStr, VR128,
3084                    !strconcat(OpcodeStr, "ss"), "", "_ss", ssmem, sse_load_f32,
3085                    itins.s, 0>, XS, VEX_4V, VEX_LIG;
3086   defm V#NAME#SD : sse12_fp_scalar_int<opc, OpcodeStr, VR128,
3087                    !strconcat(OpcodeStr, "sd"), "2", "_sd", sdmem, sse_load_f64,
3088                    itins.d, 0>, XD, VEX_4V, VEX_LIG;
3089
3090   let Constraints = "$src1 = $dst" in {
3091     defm SS : sse12_fp_scalar_int<opc, OpcodeStr, VR128,
3092                    !strconcat(OpcodeStr, "ss"), "", "_ss", ssmem, sse_load_f32,
3093                    itins.s>, XS;
3094     defm SD : sse12_fp_scalar_int<opc, OpcodeStr, VR128,
3095                    !strconcat(OpcodeStr, "sd"), "2", "_sd", sdmem, sse_load_f64,
3096                    itins.d>, XD;
3097   }
3098 }
3099
3100 // Binary Arithmetic instructions
3101 defm ADD : basic_sse12_fp_binop_p<0x58, "add", fadd, SSE_ALU_ITINS_P>,
3102            basic_sse12_fp_binop_s<0x58, "add", fadd, SSE_ALU_ITINS_S>,
3103            basic_sse12_fp_binop_s_int<0x58, "add", SSE_ALU_ITINS_S>;
3104 defm MUL : basic_sse12_fp_binop_p<0x59, "mul", fmul, SSE_MUL_ITINS_P>,
3105            basic_sse12_fp_binop_s<0x59, "mul", fmul, SSE_MUL_ITINS_S>,
3106            basic_sse12_fp_binop_s_int<0x59, "mul", SSE_MUL_ITINS_S>;
3107 let isCommutable = 0 in {
3108   defm SUB : basic_sse12_fp_binop_p<0x5C, "sub", fsub, SSE_ALU_ITINS_P>,
3109              basic_sse12_fp_binop_s<0x5C, "sub", fsub, SSE_ALU_ITINS_S>,
3110              basic_sse12_fp_binop_s_int<0x5C, "sub", SSE_ALU_ITINS_S>;
3111   defm DIV : basic_sse12_fp_binop_p<0x5E, "div", fdiv, SSE_DIV_ITINS_P>,
3112              basic_sse12_fp_binop_s<0x5E, "div", fdiv, SSE_DIV_ITINS_S>,
3113              basic_sse12_fp_binop_s_int<0x5E, "div", SSE_DIV_ITINS_S>;
3114   defm MAX : basic_sse12_fp_binop_p<0x5F, "max", X86fmax, SSE_ALU_ITINS_P>,
3115              basic_sse12_fp_binop_s<0x5F, "max", X86fmax, SSE_ALU_ITINS_S>,
3116              basic_sse12_fp_binop_s_int<0x5F, "max", SSE_ALU_ITINS_S>;
3117   defm MIN : basic_sse12_fp_binop_p<0x5D, "min", X86fmin, SSE_ALU_ITINS_P>,
3118              basic_sse12_fp_binop_s<0x5D, "min", X86fmin, SSE_ALU_ITINS_S>,
3119              basic_sse12_fp_binop_s_int<0x5D, "min", SSE_ALU_ITINS_S>;
3120 }
3121
3122 let isCodeGenOnly = 1 in {
3123   defm MAXC: basic_sse12_fp_binop_p<0x5F, "max", X86fmaxc, SSE_ALU_ITINS_P>,
3124              basic_sse12_fp_binop_s<0x5F, "max", X86fmaxc, SSE_ALU_ITINS_S>;
3125   defm MINC: basic_sse12_fp_binop_p<0x5D, "min", X86fminc, SSE_ALU_ITINS_P>,
3126              basic_sse12_fp_binop_s<0x5D, "min", X86fminc, SSE_ALU_ITINS_S>;
3127 }
3128
3129 // Patterns used to select SSE scalar fp arithmetic instructions from
3130 // a scalar fp operation followed by a blend.
3131 //
3132 // These patterns know, for example, how to select an ADDSS from a
3133 // float add plus vector insert.
3134 //
3135 // The effect is that the backend no longer emits unnecessary vector
3136 // insert instructions immediately after SSE scalar fp instructions
3137 // like addss or mulss.
3138 //
3139 // For example, given the following code:
3140 //   __m128 foo(__m128 A, __m128 B) {
3141 //     A[0] += B[0];
3142 //     return A;
3143 //   }
3144 //
3145 // previously we generated:
3146 //   addss %xmm0, %xmm1
3147 //   movss %xmm1, %xmm0
3148 // 
3149 // we now generate:
3150 //   addss %xmm1, %xmm0
3151
3152 let Predicates = [UseSSE1] in {
3153   def : Pat<(v4f32 (X86Movss (v4f32 VR128:$dst), (v4f32 (scalar_to_vector (fadd
3154                       (f32 (vector_extract (v4f32 VR128:$dst), (iPTR 0))),
3155                       FR32:$src))))),
3156             (ADDSSrr_Int v4f32:$dst, (COPY_TO_REGCLASS FR32:$src, VR128))>;
3157   def : Pat<(v4f32 (X86Movss (v4f32 VR128:$dst), (v4f32 (scalar_to_vector (fsub
3158                       (f32 (vector_extract (v4f32 VR128:$dst), (iPTR 0))),
3159                       FR32:$src))))),
3160             (SUBSSrr_Int v4f32:$dst, (COPY_TO_REGCLASS FR32:$src, VR128))>;
3161   def : Pat<(v4f32 (X86Movss (v4f32 VR128:$dst), (v4f32 (scalar_to_vector (fmul
3162                       (f32 (vector_extract (v4f32 VR128:$dst), (iPTR 0))),
3163                       FR32:$src))))),
3164             (MULSSrr_Int v4f32:$dst, (COPY_TO_REGCLASS FR32:$src, VR128))>;
3165   def : Pat<(v4f32 (X86Movss (v4f32 VR128:$dst), (v4f32 (scalar_to_vector (fdiv
3166                       (f32 (vector_extract (v4f32 VR128:$dst), (iPTR 0))),
3167                       FR32:$src))))),
3168             (DIVSSrr_Int v4f32:$dst, (COPY_TO_REGCLASS FR32:$src, VR128))>;
3169 }
3170
3171 let Predicates = [UseSSE2] in {
3172   // SSE2 patterns to select scalar double-precision fp arithmetic instructions
3173
3174   def : Pat<(v2f64 (X86Movsd (v2f64 VR128:$dst), (v2f64 (scalar_to_vector (fadd
3175                       (f64 (vector_extract (v2f64 VR128:$dst), (iPTR 0))),
3176                       FR64:$src))))),
3177             (ADDSDrr_Int v2f64:$dst, (COPY_TO_REGCLASS FR64:$src, VR128))>;
3178   def : Pat<(v2f64 (X86Movsd (v2f64 VR128:$dst), (v2f64 (scalar_to_vector (fsub
3179                       (f64 (vector_extract (v2f64 VR128:$dst), (iPTR 0))),
3180                       FR64:$src))))),
3181             (SUBSDrr_Int v2f64:$dst, (COPY_TO_REGCLASS FR64:$src, VR128))>;
3182   def : Pat<(v2f64 (X86Movsd (v2f64 VR128:$dst), (v2f64 (scalar_to_vector (fmul
3183                       (f64 (vector_extract (v2f64 VR128:$dst), (iPTR 0))),
3184                       FR64:$src))))),
3185             (MULSDrr_Int v2f64:$dst, (COPY_TO_REGCLASS FR64:$src, VR128))>;
3186   def : Pat<(v2f64 (X86Movsd (v2f64 VR128:$dst), (v2f64 (scalar_to_vector (fdiv
3187                       (f64 (vector_extract (v2f64 VR128:$dst), (iPTR 0))),
3188                       FR64:$src))))),
3189             (DIVSDrr_Int v2f64:$dst, (COPY_TO_REGCLASS FR64:$src, VR128))>;
3190 }
3191
3192 let Predicates = [UseSSE41] in {
3193   // If the subtarget has SSE4.1 but not AVX, the vector insert
3194   // instruction is lowered into a X86insertps rather than a X86Movss.
3195   // When selecting SSE scalar single-precision fp arithmetic instructions,
3196   // make sure that we correctly match the X86insertps.
3197
3198   def : Pat<(v4f32 (X86insertps (v4f32 VR128:$dst), (v4f32 (scalar_to_vector
3199                   (fadd (f32 (vector_extract (v4f32 VR128:$dst), (iPTR 0))),
3200                     FR32:$src))), (iPTR 0))),
3201             (ADDSSrr_Int v4f32:$dst, (COPY_TO_REGCLASS FR32:$src, VR128))>;
3202   def : Pat<(v4f32 (X86insertps (v4f32 VR128:$dst), (v4f32 (scalar_to_vector
3203                   (fsub (f32 (vector_extract (v4f32 VR128:$dst), (iPTR 0))),
3204                     FR32:$src))), (iPTR 0))),
3205             (SUBSSrr_Int v4f32:$dst, (COPY_TO_REGCLASS FR32:$src, VR128))>;
3206   def : Pat<(v4f32 (X86insertps (v4f32 VR128:$dst), (v4f32 (scalar_to_vector
3207                   (fmul (f32 (vector_extract (v4f32 VR128:$dst), (iPTR 0))),
3208                     FR32:$src))), (iPTR 0))),
3209             (MULSSrr_Int v4f32:$dst, (COPY_TO_REGCLASS FR32:$src, VR128))>;
3210   def : Pat<(v4f32 (X86insertps (v4f32 VR128:$dst), (v4f32 (scalar_to_vector
3211                   (fdiv (f32 (vector_extract (v4f32 VR128:$dst), (iPTR 0))),
3212                     FR32:$src))), (iPTR 0))),
3213             (DIVSSrr_Int v4f32:$dst, (COPY_TO_REGCLASS FR32:$src, VR128))>;
3214 }
3215
3216 let Predicates = [HasAVX] in {
3217   // The following patterns select AVX Scalar single/double precision fp
3218   // arithmetic instructions.
3219
3220   def : Pat<(v2f64 (X86Movsd (v2f64 VR128:$dst), (v2f64 (scalar_to_vector (fadd
3221                       (f64 (vector_extract (v2f64 VR128:$dst), (iPTR 0))),
3222                       FR64:$src))))),
3223             (VADDSDrr_Int v2f64:$dst, (COPY_TO_REGCLASS FR64:$src, VR128))>;
3224   def : Pat<(v2f64 (X86Movsd (v2f64 VR128:$dst), (v2f64 (scalar_to_vector (fsub
3225                       (f64 (vector_extract (v2f64 VR128:$dst), (iPTR 0))),
3226                       FR64:$src))))),
3227             (VSUBSDrr_Int v2f64:$dst, (COPY_TO_REGCLASS FR64:$src, VR128))>;
3228   def : Pat<(v2f64 (X86Movsd (v2f64 VR128:$dst), (v2f64 (scalar_to_vector (fmul
3229                       (f64 (vector_extract (v2f64 VR128:$dst), (iPTR 0))),
3230                       FR64:$src))))),
3231             (VMULSDrr_Int v2f64:$dst, (COPY_TO_REGCLASS FR64:$src, VR128))>;
3232   def : Pat<(v2f64 (X86Movsd (v2f64 VR128:$dst), (v2f64 (scalar_to_vector (fdiv
3233                       (f64 (vector_extract (v2f64 VR128:$dst), (iPTR 0))),
3234                       FR64:$src))))),
3235             (VDIVSDrr_Int v2f64:$dst, (COPY_TO_REGCLASS FR64:$src, VR128))>;
3236   def : Pat<(v4f32 (X86insertps (v4f32 VR128:$dst), (v4f32 (scalar_to_vector
3237                  (fadd (f32 (vector_extract (v4f32 VR128:$dst), (iPTR 0))),
3238                        FR32:$src))), (iPTR 0))),
3239             (VADDSSrr_Int v4f32:$dst, (COPY_TO_REGCLASS FR32:$src, VR128))>;
3240   def : Pat<(v4f32 (X86insertps (v4f32 VR128:$dst), (v4f32 (scalar_to_vector
3241                  (fsub (f32 (vector_extract (v4f32 VR128:$dst), (iPTR 0))),
3242                        FR32:$src))), (iPTR 0))),
3243             (VSUBSSrr_Int v4f32:$dst, (COPY_TO_REGCLASS FR32:$src, VR128))>;
3244   def : Pat<(v4f32 (X86insertps (v4f32 VR128:$dst), (v4f32 (scalar_to_vector
3245                  (fmul (f32 (vector_extract (v4f32 VR128:$dst), (iPTR 0))),
3246                        FR32:$src))), (iPTR 0))),
3247             (VMULSSrr_Int v4f32:$dst, (COPY_TO_REGCLASS FR32:$src, VR128))>;
3248   def : Pat<(v4f32 (X86insertps (v4f32 VR128:$dst), (v4f32 (scalar_to_vector
3249                  (fdiv (f32 (vector_extract (v4f32 VR128:$dst), (iPTR 0))),
3250                        FR32:$src))), (iPTR 0))),
3251             (VDIVSSrr_Int v4f32:$dst, (COPY_TO_REGCLASS FR32:$src, VR128))>;
3252 }
3253
3254 // Patterns used to select SSE scalar fp arithmetic instructions from
3255 // a vector packed single/double fp operation followed by a vector insert.
3256 //
3257 // The effect is that the backend converts the packed fp instruction
3258 // followed by a vector insert into a single SSE scalar fp instruction.
3259 //
3260 // For example, given the following code:
3261 //   __m128 foo(__m128 A, __m128 B) {
3262 //     __m128 C = A + B;
3263 //     return (__m128) {c[0], a[1], a[2], a[3]};
3264 //   }
3265 //
3266 // previously we generated:
3267 //   addps %xmm0, %xmm1
3268 //   movss %xmm1, %xmm0
3269 // 
3270 // we now generate:
3271 //   addss %xmm1, %xmm0
3272
3273 let Predicates = [UseSSE1] in {
3274   def : Pat<(v4f32 (X86Movss (v4f32 VR128:$dst),
3275                    (fadd (v4f32 VR128:$dst), (v4f32 VR128:$src)))),
3276             (ADDSSrr_Int v4f32:$dst, v4f32:$src)>;
3277   def : Pat<(v4f32 (X86Movss (v4f32 VR128:$dst), 
3278                    (fsub (v4f32 VR128:$dst), (v4f32 VR128:$src)))),
3279             (SUBSSrr_Int v4f32:$dst, v4f32:$src)>;
3280   def : Pat<(v4f32 (X86Movss (v4f32 VR128:$dst),
3281                    (fmul (v4f32 VR128:$dst), (v4f32 VR128:$src)))),
3282             (MULSSrr_Int v4f32:$dst, v4f32:$src)>;
3283   def : Pat<(v4f32 (X86Movss (v4f32 VR128:$dst), 
3284                    (fdiv (v4f32 VR128:$dst), (v4f32 VR128:$src)))),
3285             (DIVSSrr_Int v4f32:$dst, v4f32:$src)>;
3286 }
3287
3288 let Predicates = [UseSSE2] in {
3289   // SSE2 patterns to select scalar double-precision fp arithmetic instructions
3290   // from a packed double-precision fp instruction plus movsd.
3291
3292   def : Pat<(v2f64 (X86Movsd (v2f64 VR128:$dst),
3293                    (fadd (v2f64 VR128:$dst), (v2f64 VR128:$src)))),
3294             (ADDSDrr_Int v2f64:$dst, v2f64:$src)>;
3295   def : Pat<(v2f64 (X86Movsd (v2f64 VR128:$dst),
3296                    (fsub (v2f64 VR128:$dst), (v2f64 VR128:$src)))),
3297             (SUBSDrr_Int v2f64:$dst, v2f64:$src)>;
3298   def : Pat<(v2f64 (X86Movsd (v2f64 VR128:$dst),
3299                    (fmul (v2f64 VR128:$dst), (v2f64 VR128:$src)))),
3300             (MULSDrr_Int v2f64:$dst, v2f64:$src)>;
3301   def : Pat<(v2f64 (X86Movsd (v2f64 VR128:$dst),
3302                    (fdiv (v2f64 VR128:$dst), (v2f64 VR128:$src)))),
3303             (DIVSDrr_Int v2f64:$dst, v2f64:$src)>;
3304 }
3305
3306 let Predicates = [HasAVX] in {
3307   // The following patterns select AVX Scalar single/double precision fp
3308   // arithmetic instructions from a packed single precision fp instruction
3309   // plus movss/movsd.
3310
3311   def : Pat<(v4f32 (X86Movss (v4f32 VR128:$dst),
3312                    (fadd (v4f32 VR128:$dst), (v4f32 VR128:$src)))),
3313             (VADDSSrr_Int v4f32:$dst, v4f32:$src)>;
3314   def : Pat<(v4f32 (X86Movss (v4f32 VR128:$dst),
3315                    (fsub (v4f32 VR128:$dst), (v4f32 VR128:$src)))),
3316             (VSUBSSrr_Int v4f32:$dst, v4f32:$src)>;
3317   def : Pat<(v4f32 (X86Movss (v4f32 VR128:$dst),
3318                    (fmul (v4f32 VR128:$dst), (v4f32 VR128:$src)))),
3319             (VMULSSrr_Int v4f32:$dst, v4f32:$src)>;
3320   def : Pat<(v4f32 (X86Movss (v4f32 VR128:$dst),
3321                    (fdiv (v4f32 VR128:$dst), (v4f32 VR128:$src)))),
3322             (VDIVSSrr_Int v4f32:$dst, v4f32:$src)>;
3323   def : Pat<(v2f64 (X86Movsd (v2f64 VR128:$dst),
3324                    (fadd (v2f64 VR128:$dst), (v2f64 VR128:$src)))),
3325             (VADDSDrr_Int v2f64:$dst, v2f64:$src)>;
3326   def : Pat<(v2f64 (X86Movsd (v2f64 VR128:$dst),
3327                    (fsub (v2f64 VR128:$dst), (v2f64 VR128:$src)))),
3328             (VSUBSDrr_Int v2f64:$dst, v2f64:$src)>;
3329   def : Pat<(v2f64 (X86Movsd (v2f64 VR128:$dst),
3330                    (fmul (v2f64 VR128:$dst), (v2f64 VR128:$src)))),
3331             (VMULSDrr_Int v2f64:$dst, v2f64:$src)>;
3332   def : Pat<(v2f64 (X86Movsd (v2f64 VR128:$dst),
3333                    (fdiv (v2f64 VR128:$dst), (v2f64 VR128:$src)))),
3334             (VDIVSDrr_Int v2f64:$dst, v2f64:$src)>;
3335 }
3336
3337 /// Unop Arithmetic
3338 /// In addition, we also have a special variant of the scalar form here to
3339 /// represent the associated intrinsic operation.  This form is unlike the
3340 /// plain scalar form, in that it takes an entire vector (instead of a
3341 /// scalar) and leaves the top elements undefined.
3342 ///
3343 /// And, we have a special variant form for a full-vector intrinsic form.
3344
3345 let Sched = WriteFSqrt in {
3346 def SSE_SQRTPS : OpndItins<
3347   IIC_SSE_SQRTPS_RR, IIC_SSE_SQRTPS_RM
3348 >;
3349
3350 def SSE_SQRTSS : OpndItins<
3351   IIC_SSE_SQRTSS_RR, IIC_SSE_SQRTSS_RM
3352 >;
3353
3354 def SSE_SQRTPD : OpndItins<
3355   IIC_SSE_SQRTPD_RR, IIC_SSE_SQRTPD_RM
3356 >;
3357
3358 def SSE_SQRTSD : OpndItins<
3359   IIC_SSE_SQRTSD_RR, IIC_SSE_SQRTSD_RM
3360 >;
3361 }
3362
3363 let Sched = WriteFRsqrt in {
3364 def SSE_RSQRTPS : OpndItins<
3365   IIC_SSE_RSQRTPS_RR, IIC_SSE_RSQRTPS_RM
3366 >;
3367
3368 def SSE_RSQRTSS : OpndItins<
3369   IIC_SSE_RSQRTSS_RR, IIC_SSE_RSQRTSS_RM
3370 >;
3371 }
3372
3373 let Sched = WriteFRcp in {
3374 def SSE_RCPP : OpndItins<
3375   IIC_SSE_RCPP_RR, IIC_SSE_RCPP_RM
3376 >;
3377
3378 def SSE_RCPS : OpndItins<
3379   IIC_SSE_RCPS_RR, IIC_SSE_RCPS_RM
3380 >;
3381 }
3382
3383 /// sse1_fp_unop_s - SSE1 unops in scalar form.
3384 multiclass sse1_fp_unop_s<bits<8> opc, string OpcodeStr,
3385                           SDNode OpNode, Intrinsic F32Int, OpndItins itins> {
3386 let Predicates = [HasAVX], hasSideEffects = 0 in {
3387   def V#NAME#SSr : SSI<opc, MRMSrcReg, (outs FR32:$dst),
3388                       (ins FR32:$src1, FR32:$src2),
3389                       !strconcat("v", OpcodeStr,
3390                                  "ss\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
3391                       []>, VEX_4V, VEX_LIG, Sched<[itins.Sched]>;
3392   let mayLoad = 1 in {
3393   def V#NAME#SSm : SSI<opc, MRMSrcMem, (outs FR32:$dst),
3394                       (ins FR32:$src1,f32mem:$src2),
3395                       !strconcat("v", OpcodeStr,
3396                                  "ss\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
3397                       []>, VEX_4V, VEX_LIG,
3398                    Sched<[itins.Sched.Folded, ReadAfterLd]>;
3399   let isCodeGenOnly = 1 in
3400   def V#NAME#SSm_Int : SSI<opc, MRMSrcMem, (outs VR128:$dst),
3401                       (ins VR128:$src1, ssmem:$src2),
3402                       !strconcat("v", OpcodeStr,
3403                                  "ss\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
3404                       []>, VEX_4V, VEX_LIG,
3405                       Sched<[itins.Sched.Folded, ReadAfterLd]>;
3406   }
3407 }
3408
3409   def SSr : SSI<opc, MRMSrcReg, (outs FR32:$dst), (ins FR32:$src),
3410                 !strconcat(OpcodeStr, "ss\t{$src, $dst|$dst, $src}"),
3411                 [(set FR32:$dst, (OpNode FR32:$src))]>, Sched<[itins.Sched]>;
3412   // For scalar unary operations, fold a load into the operation
3413   // only in OptForSize mode. It eliminates an instruction, but it also
3414   // eliminates a whole-register clobber (the load), so it introduces a
3415   // partial register update condition.
3416   def SSm : I<opc, MRMSrcMem, (outs FR32:$dst), (ins f32mem:$src),
3417                 !strconcat(OpcodeStr, "ss\t{$src, $dst|$dst, $src}"),
3418                 [(set FR32:$dst, (OpNode (load addr:$src)))], itins.rm>, XS,
3419             Requires<[UseSSE1, OptForSize]>, Sched<[itins.Sched.Folded]>;
3420 let isCodeGenOnly = 1 in {
3421   def SSr_Int : SSI<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3422                     !strconcat(OpcodeStr, "ss\t{$src, $dst|$dst, $src}"),
3423                     [(set VR128:$dst, (F32Int VR128:$src))], itins.rr>,
3424                 Sched<[itins.Sched]>;
3425   def SSm_Int : SSI<opc, MRMSrcMem, (outs VR128:$dst), (ins ssmem:$src),
3426                     !strconcat(OpcodeStr, "ss\t{$src, $dst|$dst, $src}"),
3427                     [(set VR128:$dst, (F32Int sse_load_f32:$src))], itins.rm>,
3428                 Sched<[itins.Sched.Folded]>;
3429 }
3430 }
3431
3432 /// sse1_fp_unop_s_rw - SSE1 unops where vector form has a read-write operand.
3433 multiclass sse1_fp_unop_rw<bits<8> opc, string OpcodeStr, SDNode OpNode,
3434                            OpndItins itins> {
3435 let Predicates = [HasAVX], hasSideEffects = 0 in {
3436   def V#NAME#SSr : SSI<opc, MRMSrcReg, (outs FR32:$dst),
3437                        (ins FR32:$src1, FR32:$src2),
3438                        !strconcat("v", OpcodeStr,
3439                            "ss\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
3440                 []>, VEX_4V, VEX_LIG, Sched<[itins.Sched]>;
3441   let mayLoad = 1 in {
3442   def V#NAME#SSm : SSI<opc, MRMSrcMem, (outs FR32:$dst),
3443                       (ins FR32:$src1,f32mem:$src2),
3444                       !strconcat("v", OpcodeStr,
3445                                  "ss\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
3446                       []>, VEX_4V, VEX_LIG,
3447                    Sched<[itins.Sched.Folded, ReadAfterLd]>;
3448   let isCodeGenOnly = 1 in
3449   def V#NAME#SSm_Int : SSI<opc, MRMSrcMem, (outs VR128:$dst),
3450                       (ins VR128:$src1, ssmem:$src2),
3451                       !strconcat("v", OpcodeStr,
3452                                  "ss\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
3453                       []>, VEX_4V, VEX_LIG,
3454                       Sched<[itins.Sched.Folded, ReadAfterLd]>;
3455   }
3456 }
3457
3458   def SSr : SSI<opc, MRMSrcReg, (outs FR32:$dst), (ins FR32:$src),
3459                 !strconcat(OpcodeStr, "ss\t{$src, $dst|$dst, $src}"),
3460                 [(set FR32:$dst, (OpNode FR32:$src))]>, Sched<[itins.Sched]>;
3461   // For scalar unary operations, fold a load into the operation
3462   // only in OptForSize mode. It eliminates an instruction, but it also
3463   // eliminates a whole-register clobber (the load), so it introduces a
3464   // partial register update condition.
3465   def SSm : I<opc, MRMSrcMem, (outs FR32:$dst), (ins f32mem:$src),
3466                 !strconcat(OpcodeStr, "ss\t{$src, $dst|$dst, $src}"),
3467                 [(set FR32:$dst, (OpNode (load addr:$src)))], itins.rm>, XS,
3468             Requires<[UseSSE1, OptForSize]>, Sched<[itins.Sched.Folded]>;
3469   let isCodeGenOnly = 1, Constraints = "$src1 = $dst" in {
3470     def SSr_Int : SSI<opc, MRMSrcReg, (outs VR128:$dst),
3471                       (ins VR128:$src1, VR128:$src2),
3472                       !strconcat(OpcodeStr, "ss\t{$src2, $dst|$dst, $src2}"),
3473                       [], itins.rr>, Sched<[itins.Sched]>;
3474     let mayLoad = 1, hasSideEffects = 0 in
3475     def SSm_Int : SSI<opc, MRMSrcMem, (outs VR128:$dst),
3476                       (ins VR128:$src1, ssmem:$src2),
3477                       !strconcat(OpcodeStr, "ss\t{$src2, $dst|$dst, $src2}"),
3478                       [], itins.rm>, Sched<[itins.Sched.Folded, ReadAfterLd]>;
3479   }
3480 }
3481
3482 /// sse1_fp_unop_p - SSE1 unops in packed form.
3483 multiclass sse1_fp_unop_p<bits<8> opc, string OpcodeStr, SDNode OpNode,
3484                           OpndItins itins> {
3485 let Predicates = [HasAVX] in {
3486   def V#NAME#PSr : PSI<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3487                        !strconcat("v", OpcodeStr,
3488                                   "ps\t{$src, $dst|$dst, $src}"),
3489                        [(set VR128:$dst, (v4f32 (OpNode VR128:$src)))],
3490                        itins.rr>, VEX, Sched<[itins.Sched]>;
3491   def V#NAME#PSm : PSI<opc, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
3492                        !strconcat("v", OpcodeStr,
3493                                   "ps\t{$src, $dst|$dst, $src}"),
3494                        [(set VR128:$dst, (OpNode (loadv4f32 addr:$src)))],
3495                        itins.rm>, VEX, Sched<[itins.Sched.Folded]>;
3496   def V#NAME#PSYr : PSI<opc, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
3497                         !strconcat("v", OpcodeStr,
3498                                    "ps\t{$src, $dst|$dst, $src}"),
3499                         [(set VR256:$dst, (v8f32 (OpNode VR256:$src)))],
3500                         itins.rr>, VEX, VEX_L, Sched<[itins.Sched]>;
3501   def V#NAME#PSYm : PSI<opc, MRMSrcMem, (outs VR256:$dst), (ins f256mem:$src),
3502                         !strconcat("v", OpcodeStr,
3503                                    "ps\t{$src, $dst|$dst, $src}"),
3504                         [(set VR256:$dst, (OpNode (loadv8f32 addr:$src)))],
3505                         itins.rm>, VEX, VEX_L, Sched<[itins.Sched.Folded]>;
3506 }
3507
3508   def PSr : PSI<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3509                 !strconcat(OpcodeStr, "ps\t{$src, $dst|$dst, $src}"),
3510                 [(set VR128:$dst, (v4f32 (OpNode VR128:$src)))], itins.rr>,
3511             Sched<[itins.Sched]>;
3512   def PSm : PSI<opc, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
3513                 !strconcat(OpcodeStr, "ps\t{$src, $dst|$dst, $src}"),
3514                 [(set VR128:$dst, (OpNode (memopv4f32 addr:$src)))], itins.rm>,
3515             Sched<[itins.Sched.Folded]>;
3516 }
3517
3518 /// sse1_fp_unop_p_int - SSE1 intrinsics unops in packed forms.
3519 multiclass sse1_fp_unop_p_int<bits<8> opc, string OpcodeStr,
3520                               Intrinsic V4F32Int, Intrinsic V8F32Int,
3521                               OpndItins itins> {
3522 let isCodeGenOnly = 1 in {
3523 let Predicates = [HasAVX] in {
3524   def V#NAME#PSr_Int : PSI<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3525                            !strconcat("v", OpcodeStr,
3526                                       "ps\t{$src, $dst|$dst, $src}"),
3527                            [(set VR128:$dst, (V4F32Int VR128:$src))],
3528                            itins.rr>, VEX, Sched<[itins.Sched]>;
3529   def V#NAME#PSm_Int : PSI<opc, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
3530                           !strconcat("v", OpcodeStr,
3531                           "ps\t{$src, $dst|$dst, $src}"),
3532                           [(set VR128:$dst, (V4F32Int (loadv4f32 addr:$src)))],
3533                           itins.rm>, VEX, Sched<[itins.Sched.Folded]>;
3534   def V#NAME#PSYr_Int : PSI<opc, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
3535                             !strconcat("v", OpcodeStr,
3536                                        "ps\t{$src, $dst|$dst, $src}"),
3537                             [(set VR256:$dst, (V8F32Int VR256:$src))],
3538                             itins.rr>, VEX, VEX_L, Sched<[itins.Sched]>;
3539   def V#NAME#PSYm_Int : PSI<opc, MRMSrcMem, (outs VR256:$dst),
3540                           (ins f256mem:$src),
3541                           !strconcat("v", OpcodeStr,
3542                                     "ps\t{$src, $dst|$dst, $src}"),
3543                           [(set VR256:$dst, (V8F32Int (loadv8f32 addr:$src)))],
3544                           itins.rm>, VEX, VEX_L, Sched<[itins.Sched.Folded]>;
3545 }
3546
3547   def PSr_Int : PSI<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3548                     !strconcat(OpcodeStr, "ps\t{$src, $dst|$dst, $src}"),
3549                     [(set VR128:$dst, (V4F32Int VR128:$src))],
3550                     itins.rr>, Sched<[itins.Sched]>;
3551   def PSm_Int : PSI<opc, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
3552                     !strconcat(OpcodeStr, "ps\t{$src, $dst|$dst, $src}"),
3553                     [(set VR128:$dst, (V4F32Int (memopv4f32 addr:$src)))],
3554                     itins.rm>, Sched<[itins.Sched.Folded]>;
3555 } // isCodeGenOnly = 1
3556 }
3557
3558 /// sse2_fp_unop_s - SSE2 unops in scalar form.
3559 multiclass sse2_fp_unop_s<bits<8> opc, string OpcodeStr,
3560                           SDNode OpNode, Intrinsic F64Int, OpndItins itins> {
3561 let Predicates = [HasAVX], hasSideEffects = 0 in {
3562   def V#NAME#SDr : SDI<opc, MRMSrcReg, (outs FR64:$dst),
3563                       (ins FR64:$src1, FR64:$src2),
3564                       !strconcat("v", OpcodeStr,
3565                                  "sd\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
3566                       []>, VEX_4V, VEX_LIG, Sched<[itins.Sched]>;
3567   let mayLoad = 1 in {
3568   def V#NAME#SDm : SDI<opc, MRMSrcMem, (outs FR64:$dst),
3569                       (ins FR64:$src1,f64mem:$src2),
3570                       !strconcat("v", OpcodeStr,
3571                                  "sd\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
3572                       []>, VEX_4V, VEX_LIG,
3573                    Sched<[itins.Sched.Folded, ReadAfterLd]>;
3574   let isCodeGenOnly = 1 in
3575   def V#NAME#SDm_Int : SDI<opc, MRMSrcMem, (outs VR128:$dst),
3576                       (ins VR128:$src1, sdmem:$src2),
3577                       !strconcat("v", OpcodeStr,
3578                                  "sd\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
3579                       []>, VEX_4V, VEX_LIG,
3580                       Sched<[itins.Sched.Folded, ReadAfterLd]>;
3581   }
3582 }
3583
3584   def SDr : SDI<opc, MRMSrcReg, (outs FR64:$dst), (ins FR64:$src),
3585                 !strconcat(OpcodeStr, "sd\t{$src, $dst|$dst, $src}"),
3586                 [(set FR64:$dst, (OpNode FR64:$src))], itins.rr>,
3587             Sched<[itins.Sched]>;
3588   // See the comments in sse1_fp_unop_s for why this is OptForSize.
3589   def SDm : I<opc, MRMSrcMem, (outs FR64:$dst), (ins f64mem:$src),
3590                 !strconcat(OpcodeStr, "sd\t{$src, $dst|$dst, $src}"),
3591                 [(set FR64:$dst, (OpNode (load addr:$src)))], itins.rm>, XD,
3592             Requires<[UseSSE2, OptForSize]>, Sched<[itins.Sched.Folded]>;
3593 let isCodeGenOnly = 1 in {
3594   def SDr_Int : SDI<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3595                     !strconcat(OpcodeStr, "sd\t{$src, $dst|$dst, $src}"),
3596                     [(set VR128:$dst, (F64Int VR128:$src))], itins.rr>,
3597                 Sched<[itins.Sched]>;
3598   def SDm_Int : SDI<opc, MRMSrcMem, (outs VR128:$dst), (ins sdmem:$src),
3599                     !strconcat(OpcodeStr, "sd\t{$src, $dst|$dst, $src}"),
3600                     [(set VR128:$dst, (F64Int sse_load_f64:$src))], itins.rm>,
3601                 Sched<[itins.Sched.Folded]>;
3602 }
3603 }
3604
3605 /// sse2_fp_unop_p - SSE2 unops in vector forms.
3606 multiclass sse2_fp_unop_p<bits<8> opc, string OpcodeStr,
3607                           SDNode OpNode, OpndItins itins> {
3608 let Predicates = [HasAVX] in {
3609   def V#NAME#PDr : PDI<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3610                        !strconcat("v", OpcodeStr,
3611                                   "pd\t{$src, $dst|$dst, $src}"),
3612                        [(set VR128:$dst, (v2f64 (OpNode VR128:$src)))],
3613                        itins.rr>, VEX, Sched<[itins.Sched]>;
3614   def V#NAME#PDm : PDI<opc, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
3615                        !strconcat("v", OpcodeStr,
3616                                   "pd\t{$src, $dst|$dst, $src}"),
3617                        [(set VR128:$dst, (OpNode (loadv2f64 addr:$src)))],
3618                        itins.rm>, VEX, Sched<[itins.Sched.Folded]>;
3619   def V#NAME#PDYr : PDI<opc, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
3620                         !strconcat("v", OpcodeStr,
3621                                    "pd\t{$src, $dst|$dst, $src}"),
3622                         [(set VR256:$dst, (v4f64 (OpNode VR256:$src)))],
3623                         itins.rr>, VEX, VEX_L, Sched<[itins.Sched]>;
3624   def V#NAME#PDYm : PDI<opc, MRMSrcMem, (outs VR256:$dst), (ins f256mem:$src),
3625                         !strconcat("v", OpcodeStr,
3626                                    "pd\t{$src, $dst|$dst, $src}"),
3627                         [(set VR256:$dst, (OpNode (loadv4f64 addr:$src)))],
3628                         itins.rm>, VEX, VEX_L, Sched<[itins.Sched.Folded]>;
3629 }
3630
3631   def PDr : PDI<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3632               !strconcat(OpcodeStr, "pd\t{$src, $dst|$dst, $src}"),
3633               [(set VR128:$dst, (v2f64 (OpNode VR128:$src)))], itins.rr>,
3634             Sched<[itins.Sched]>;
3635   def PDm : PDI<opc, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
3636                 !strconcat(OpcodeStr, "pd\t{$src, $dst|$dst, $src}"),
3637                 [(set VR128:$dst, (OpNode (memopv2f64 addr:$src)))], itins.rm>,
3638             Sched<[itins.Sched.Folded]>;
3639 }
3640
3641 // Square root.
3642 defm SQRT  : sse1_fp_unop_s<0x51, "sqrt",  fsqrt, int_x86_sse_sqrt_ss,
3643                             SSE_SQRTSS>,
3644              sse1_fp_unop_p<0x51, "sqrt", fsqrt, SSE_SQRTPS>,
3645              sse2_fp_unop_s<0x51, "sqrt",  fsqrt, int_x86_sse2_sqrt_sd,
3646                             SSE_SQRTSD>,
3647              sse2_fp_unop_p<0x51, "sqrt", fsqrt, SSE_SQRTPD>;
3648
3649 // Reciprocal approximations. Note that these typically require refinement
3650 // in order to obtain suitable precision.
3651 defm RSQRT : sse1_fp_unop_rw<0x52, "rsqrt", X86frsqrt, SSE_RSQRTSS>,
3652              sse1_fp_unop_p<0x52, "rsqrt", X86frsqrt, SSE_RSQRTPS>,
3653              sse1_fp_unop_p_int<0x52, "rsqrt", int_x86_sse_rsqrt_ps,
3654                                 int_x86_avx_rsqrt_ps_256, SSE_RSQRTPS>;
3655 defm RCP   : sse1_fp_unop_rw<0x53, "rcp", X86frcp, SSE_RCPS>,
3656              sse1_fp_unop_p<0x53, "rcp", X86frcp, SSE_RCPP>,
3657              sse1_fp_unop_p_int<0x53, "rcp", int_x86_sse_rcp_ps,
3658                                 int_x86_avx_rcp_ps_256, SSE_RCPP>;
3659
3660 let Predicates = [UseAVX] in {
3661   def : Pat<(f32 (fsqrt FR32:$src)),
3662             (VSQRTSSr (f32 (IMPLICIT_DEF)), FR32:$src)>, Requires<[HasAVX]>;
3663   def : Pat<(f32 (fsqrt (load addr:$src))),
3664             (VSQRTSSm (f32 (IMPLICIT_DEF)), addr:$src)>,
3665             Requires<[HasAVX, OptForSize]>;
3666   def : Pat<(f64 (fsqrt FR64:$src)),
3667             (VSQRTSDr (f64 (IMPLICIT_DEF)), FR64:$src)>, Requires<[HasAVX]>;
3668   def : Pat<(f64 (fsqrt (load addr:$src))),
3669             (VSQRTSDm (f64 (IMPLICIT_DEF)), addr:$src)>,
3670             Requires<[HasAVX, OptForSize]>;
3671
3672   def : Pat<(f32 (X86frsqrt FR32:$src)),
3673             (VRSQRTSSr (f32 (IMPLICIT_DEF)), FR32:$src)>, Requires<[HasAVX]>;
3674   def : Pat<(f32 (X86frsqrt (load addr:$src))),
3675             (VRSQRTSSm (f32 (IMPLICIT_DEF)), addr:$src)>,
3676             Requires<[HasAVX, OptForSize]>;
3677
3678   def : Pat<(f32 (X86frcp FR32:$src)),
3679             (VRCPSSr (f32 (IMPLICIT_DEF)), FR32:$src)>, Requires<[HasAVX]>;
3680   def : Pat<(f32 (X86frcp (load addr:$src))),
3681             (VRCPSSm (f32 (IMPLICIT_DEF)), addr:$src)>,
3682             Requires<[HasAVX, OptForSize]>;
3683 }
3684 let Predicates = [UseAVX] in {
3685   def : Pat<(int_x86_sse_sqrt_ss VR128:$src),
3686             (COPY_TO_REGCLASS (VSQRTSSr (f32 (IMPLICIT_DEF)),
3687                                         (COPY_TO_REGCLASS VR128:$src, FR32)),
3688                               VR128)>;
3689   def : Pat<(int_x86_sse_sqrt_ss sse_load_f32:$src),
3690             (VSQRTSSm_Int (v4f32 (IMPLICIT_DEF)), sse_load_f32:$src)>;
3691
3692   def : Pat<(int_x86_sse2_sqrt_sd VR128:$src),
3693             (COPY_TO_REGCLASS (VSQRTSDr (f64 (IMPLICIT_DEF)),
3694                                         (COPY_TO_REGCLASS VR128:$src, FR64)),
3695                               VR128)>;
3696   def : Pat<(int_x86_sse2_sqrt_sd sse_load_f64:$src),
3697             (VSQRTSDm_Int (v2f64 (IMPLICIT_DEF)), sse_load_f64:$src)>;
3698 }
3699
3700 let Predicates = [HasAVX] in {
3701   def : Pat<(int_x86_sse_rsqrt_ss VR128:$src),
3702             (COPY_TO_REGCLASS (VRSQRTSSr (f32 (IMPLICIT_DEF)),
3703                                          (COPY_TO_REGCLASS VR128:$src, FR32)),
3704                               VR128)>;
3705   def : Pat<(int_x86_sse_rsqrt_ss sse_load_f32:$src),
3706             (VRSQRTSSm_Int (v4f32 (IMPLICIT_DEF)), sse_load_f32:$src)>;
3707
3708   def : Pat<(int_x86_sse_rcp_ss VR128:$src),
3709             (COPY_TO_REGCLASS (VRCPSSr (f32 (IMPLICIT_DEF)),
3710                                        (COPY_TO_REGCLASS VR128:$src, FR32)),
3711                               VR128)>;
3712   def : Pat<(int_x86_sse_rcp_ss sse_load_f32:$src),
3713             (VRCPSSm_Int (v4f32 (IMPLICIT_DEF)), sse_load_f32:$src)>;
3714 }
3715
3716 // Reciprocal approximations. Note that these typically require refinement
3717 // in order to obtain suitable precision.
3718 let Predicates = [UseSSE1] in {
3719   def : Pat<(int_x86_sse_rsqrt_ss VR128:$src),
3720             (RSQRTSSr_Int VR128:$src, VR128:$src)>;
3721   def : Pat<(int_x86_sse_rcp_ss VR128:$src),
3722             (RCPSSr_Int VR128:$src, VR128:$src)>;
3723 }
3724
3725 // There is no f64 version of the reciprocal approximation instructions.
3726
3727 //===----------------------------------------------------------------------===//
3728 // SSE 1 & 2 - Non-temporal stores
3729 //===----------------------------------------------------------------------===//
3730
3731 let AddedComplexity = 400 in { // Prefer non-temporal versions
3732 let SchedRW = [WriteStore] in {
3733 let Predicates = [HasAVX, NoVLX] in {
3734 def VMOVNTPSmr : VPSI<0x2B, MRMDestMem, (outs),
3735                      (ins f128mem:$dst, VR128:$src),
3736                      "movntps\t{$src, $dst|$dst, $src}",
3737                      [(alignednontemporalstore (v4f32 VR128:$src),
3738                                                addr:$dst)],
3739                                                IIC_SSE_MOVNT>, VEX;
3740 def VMOVNTPDmr : VPDI<0x2B, MRMDestMem, (outs),
3741                      (ins f128mem:$dst, VR128:$src),
3742                      "movntpd\t{$src, $dst|$dst, $src}",
3743                      [(alignednontemporalstore (v2f64 VR128:$src),
3744                                                addr:$dst)],
3745                                                IIC_SSE_MOVNT>, VEX;
3746
3747 let ExeDomain = SSEPackedInt in
3748 def VMOVNTDQmr    : VPDI<0xE7, MRMDestMem, (outs),
3749                          (ins f128mem:$dst, VR128:$src),
3750                          "movntdq\t{$src, $dst|$dst, $src}",
3751                          [(alignednontemporalstore (v2i64 VR128:$src),
3752                                                    addr:$dst)],
3753                                                    IIC_SSE_MOVNT>, VEX;
3754
3755 def VMOVNTPSYmr : VPSI<0x2B, MRMDestMem, (outs),
3756                      (ins f256mem:$dst, VR256:$src),
3757                      "movntps\t{$src, $dst|$dst, $src}",
3758                      [(alignednontemporalstore (v8f32 VR256:$src),
3759                                                addr:$dst)],
3760                                                IIC_SSE_MOVNT>, VEX, VEX_L;
3761 def VMOVNTPDYmr : VPDI<0x2B, MRMDestMem, (outs),
3762                      (ins f256mem:$dst, VR256:$src),
3763                      "movntpd\t{$src, $dst|$dst, $src}",
3764                      [(alignednontemporalstore (v4f64 VR256:$src),
3765                                                addr:$dst)],
3766                                                IIC_SSE_MOVNT>, VEX, VEX_L;
3767 let ExeDomain = SSEPackedInt in
3768 def VMOVNTDQYmr : VPDI<0xE7, MRMDestMem, (outs),
3769                     (ins f256mem:$dst, VR256:$src),
3770                     "movntdq\t{$src, $dst|$dst, $src}",
3771                     [(alignednontemporalstore (v4i64 VR256:$src),
3772                                               addr:$dst)],
3773                                               IIC_SSE_MOVNT>, VEX, VEX_L;
3774 }
3775
3776 def MOVNTPSmr : PSI<0x2B, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
3777                     "movntps\t{$src, $dst|$dst, $src}",
3778                     [(alignednontemporalstore (v4f32 VR128:$src), addr:$dst)],
3779                     IIC_SSE_MOVNT>;
3780 def MOVNTPDmr : PDI<0x2B, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
3781                     "movntpd\t{$src, $dst|$dst, $src}",
3782                     [(alignednontemporalstore(v2f64 VR128:$src), addr:$dst)],
3783                     IIC_SSE_MOVNT>;
3784
3785 let ExeDomain = SSEPackedInt in
3786 def MOVNTDQmr : PDI<0xE7, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
3787                     "movntdq\t{$src, $dst|$dst, $src}",
3788                     [(alignednontemporalstore (v2i64 VR128:$src), addr:$dst)],
3789                     IIC_SSE_MOVNT>;
3790
3791 // There is no AVX form for instructions below this point
3792 def MOVNTImr : I<0xC3, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
3793                  "movnti{l}\t{$src, $dst|$dst, $src}",
3794                  [(nontemporalstore (i32 GR32:$src), addr:$dst)],
3795                  IIC_SSE_MOVNT>,
3796                PS, Requires<[HasSSE2]>;
3797 def MOVNTI_64mr : RI<0xC3, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
3798                      "movnti{q}\t{$src, $dst|$dst, $src}",
3799                      [(nontemporalstore (i64 GR64:$src), addr:$dst)],
3800                      IIC_SSE_MOVNT>,
3801                   PS, Requires<[HasSSE2]>;
3802 } // SchedRW = [WriteStore]
3803
3804 } // AddedComplexity
3805
3806 //===----------------------------------------------------------------------===//
3807 // SSE 1 & 2 - Prefetch and memory fence
3808 //===----------------------------------------------------------------------===//
3809
3810 // Prefetch intrinsic.
3811 let Predicates = [HasSSE1], SchedRW = [WriteLoad] in {
3812 def PREFETCHT0   : I<0x18, MRM1m, (outs), (ins i8mem:$src),
3813     "prefetcht0\t$src", [(prefetch addr:$src, imm, (i32 3), (i32 1))],
3814     IIC_SSE_PREFETCH>, TB;
3815 def PREFETCHT1   : I<0x18, MRM2m, (outs), (ins i8mem:$src),
3816     "prefetcht1\t$src", [(prefetch addr:$src, imm, (i32 2), (i32 1))],
3817     IIC_SSE_PREFETCH>, TB;
3818 def PREFETCHT2   : I<0x18, MRM3m, (outs), (ins i8mem:$src),
3819     "prefetcht2\t$src", [(prefetch addr:$src, imm, (i32 1), (i32 1))],
3820     IIC_SSE_PREFETCH>, TB;
3821 def PREFETCHNTA  : I<0x18, MRM0m, (outs), (ins i8mem:$src),
3822     "prefetchnta\t$src", [(prefetch addr:$src, imm, (i32 0), (i32 1))],
3823     IIC_SSE_PREFETCH>, TB;
3824 }
3825
3826 // FIXME: How should flush instruction be modeled?
3827 let SchedRW = [WriteLoad] in {
3828 // Flush cache
3829 def CLFLUSH : I<0xAE, MRM7m, (outs), (ins i8mem:$src),
3830                "clflush\t$src", [(int_x86_sse2_clflush addr:$src)],
3831                IIC_SSE_PREFETCH>, TB, Requires<[HasSSE2]>;
3832 }
3833
3834 let SchedRW = [WriteNop] in {
3835 // Pause. This "instruction" is encoded as "rep; nop", so even though it
3836 // was introduced with SSE2, it's backward compatible.
3837 def PAUSE : I<0x90, RawFrm, (outs), (ins),  
3838               "pause", [(int_x86_sse2_pause)], IIC_SSE_PAUSE>, 
3839               OBXS, Requires<[HasSSE2]>;
3840 }
3841
3842 let SchedRW = [WriteFence] in {
3843 // Load, store, and memory fence
3844 def SFENCE : I<0xAE, MRM_F8, (outs), (ins),
3845                "sfence", [(int_x86_sse_sfence)], IIC_SSE_SFENCE>,
3846                TB, Requires<[HasSSE1]>;
3847 def LFENCE : I<0xAE, MRM_E8, (outs), (ins),
3848                "lfence", [(int_x86_sse2_lfence)], IIC_SSE_LFENCE>,
3849                TB, Requires<[HasSSE2]>;
3850 def MFENCE : I<0xAE, MRM_F0, (outs), (ins),
3851                "mfence", [(int_x86_sse2_mfence)], IIC_SSE_MFENCE>,
3852                TB, Requires<[HasSSE2]>;
3853 } // SchedRW
3854
3855 def : Pat<(X86SFence), (SFENCE)>;
3856 def : Pat<(X86LFence), (LFENCE)>;
3857 def : Pat<(X86MFence), (MFENCE)>;
3858
3859 //===----------------------------------------------------------------------===//
3860 // SSE 1 & 2 - Load/Store XCSR register
3861 //===----------------------------------------------------------------------===//
3862
3863 def VLDMXCSR : VPSI<0xAE, MRM2m, (outs), (ins i32mem:$src),
3864                   "ldmxcsr\t$src", [(int_x86_sse_ldmxcsr addr:$src)],
3865                   IIC_SSE_LDMXCSR>, VEX, Sched<[WriteLoad]>;
3866 def VSTMXCSR : VPSI<0xAE, MRM3m, (outs), (ins i32mem:$dst),
3867                   "stmxcsr\t$dst", [(int_x86_sse_stmxcsr addr:$dst)],
3868                   IIC_SSE_STMXCSR>, VEX, Sched<[WriteStore]>;
3869
3870 def LDMXCSR : PSI<0xAE, MRM2m, (outs), (ins i32mem:$src),
3871                   "ldmxcsr\t$src", [(int_x86_sse_ldmxcsr addr:$src)],
3872                   IIC_SSE_LDMXCSR>, Sched<[WriteLoad]>;
3873 def STMXCSR : PSI<0xAE, MRM3m, (outs), (ins i32mem:$dst),
3874                   "stmxcsr\t$dst", [(int_x86_sse_stmxcsr addr:$dst)],
3875                   IIC_SSE_STMXCSR>, Sched<[WriteStore]>;
3876
3877 //===---------------------------------------------------------------------===//
3878 // SSE2 - Move Aligned/Unaligned Packed Integer Instructions
3879 //===---------------------------------------------------------------------===//
3880
3881 let ExeDomain = SSEPackedInt in { // SSE integer instructions
3882
3883 let neverHasSideEffects = 1, SchedRW = [WriteMove] in {
3884 def VMOVDQArr  : VPDI<0x6F, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3885                     "movdqa\t{$src, $dst|$dst, $src}", [], IIC_SSE_MOVA_P_RR>,
3886                     VEX;
3887 def VMOVDQAYrr : VPDI<0x6F, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
3888                     "movdqa\t{$src, $dst|$dst, $src}", [], IIC_SSE_MOVA_P_RR>,
3889                     VEX, VEX_L;
3890 def VMOVDQUrr  : VSSI<0x6F, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3891                     "movdqu\t{$src, $dst|$dst, $src}", [], IIC_SSE_MOVU_P_RR>,
3892                     VEX;
3893 def VMOVDQUYrr : VSSI<0x6F, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
3894                     "movdqu\t{$src, $dst|$dst, $src}", [], IIC_SSE_MOVU_P_RR>,
3895                     VEX, VEX_L;
3896 }
3897
3898 // For Disassembler
3899 let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0,
3900     SchedRW = [WriteMove] in {
3901 def VMOVDQArr_REV  : VPDI<0x7F, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
3902                         "movdqa\t{$src, $dst|$dst, $src}", [],
3903                         IIC_SSE_MOVA_P_RR>,
3904                         VEX;
3905 def VMOVDQAYrr_REV : VPDI<0x7F, MRMDestReg, (outs VR256:$dst), (ins VR256:$src),
3906                         "movdqa\t{$src, $dst|$dst, $src}", [],
3907                         IIC_SSE_MOVA_P_RR>, VEX, VEX_L;
3908 def VMOVDQUrr_REV  : VSSI<0x7F, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
3909                         "movdqu\t{$src, $dst|$dst, $src}", [],
3910                         IIC_SSE_MOVU_P_RR>,
3911                         VEX;
3912 def VMOVDQUYrr_REV : VSSI<0x7F, MRMDestReg, (outs VR256:$dst), (ins VR256:$src),
3913                         "movdqu\t{$src, $dst|$dst, $src}", [],
3914                         IIC_SSE_MOVU_P_RR>, VEX, VEX_L;
3915 }
3916
3917 let canFoldAsLoad = 1, mayLoad = 1, isReMaterializable = 1,
3918     neverHasSideEffects = 1, SchedRW = [WriteLoad] in {
3919 def VMOVDQArm  : VPDI<0x6F, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
3920                    "movdqa\t{$src, $dst|$dst, $src}", [], IIC_SSE_MOVA_P_RM>,
3921                    VEX;
3922 def VMOVDQAYrm : VPDI<0x6F, MRMSrcMem, (outs VR256:$dst), (ins i256mem:$src),
3923                    "movdqa\t{$src, $dst|$dst, $src}", [], IIC_SSE_MOVA_P_RM>,
3924                    VEX, VEX_L;
3925 let Predicates = [HasAVX] in {
3926   def VMOVDQUrm  : I<0x6F, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
3927                     "vmovdqu\t{$src, $dst|$dst, $src}",[], IIC_SSE_MOVU_P_RM>,
3928                     XS, VEX;
3929   def VMOVDQUYrm : I<0x6F, MRMSrcMem, (outs VR256:$dst), (ins i256mem:$src),
3930                     "vmovdqu\t{$src, $dst|$dst, $src}",[], IIC_SSE_MOVU_P_RM>,
3931                     XS, VEX, VEX_L;
3932 }
3933 }
3934
3935 let mayStore = 1, neverHasSideEffects = 1, SchedRW = [WriteStore] in {
3936 def VMOVDQAmr  : VPDI<0x7F, MRMDestMem, (outs),
3937                      (ins i128mem:$dst, VR128:$src),
3938                      "movdqa\t{$src, $dst|$dst, $src}", [], IIC_SSE_MOVA_P_MR>,
3939                      VEX;
3940 def VMOVDQAYmr : VPDI<0x7F, MRMDestMem, (outs),
3941                      (ins i256mem:$dst, VR256:$src),
3942                      "movdqa\t{$src, $dst|$dst, $src}", [], IIC_SSE_MOVA_P_MR>,
3943                      VEX, VEX_L;
3944 let Predicates = [HasAVX] in {
3945 def VMOVDQUmr  : I<0x7F, MRMDestMem, (outs), (ins i128mem:$dst, VR128:$src),
3946                   "vmovdqu\t{$src, $dst|$dst, $src}",[], IIC_SSE_MOVU_P_MR>,
3947                   XS, VEX;
3948 def VMOVDQUYmr : I<0x7F, MRMDestMem, (outs), (ins i256mem:$dst, VR256:$src),
3949                   "vmovdqu\t{$src, $dst|$dst, $src}",[], IIC_SSE_MOVU_P_MR>,
3950                   XS, VEX, VEX_L;
3951 }
3952 }
3953
3954 let SchedRW = [WriteMove] in {
3955 let neverHasSideEffects = 1 in
3956 def MOVDQArr : PDI<0x6F, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3957                    "movdqa\t{$src, $dst|$dst, $src}", [], IIC_SSE_MOVA_P_RR>;
3958
3959 def MOVDQUrr :   I<0x6F, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3960                    "movdqu\t{$src, $dst|$dst, $src}",
3961                    [], IIC_SSE_MOVU_P_RR>, XS, Requires<[UseSSE2]>;
3962
3963 // For Disassembler
3964 let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0 in {
3965 def MOVDQArr_REV : PDI<0x7F, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
3966                        "movdqa\t{$src, $dst|$dst, $src}", [],
3967                        IIC_SSE_MOVA_P_RR>;
3968
3969 def MOVDQUrr_REV :   I<0x7F, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
3970                        "movdqu\t{$src, $dst|$dst, $src}",
3971                        [], IIC_SSE_MOVU_P_RR>, XS, Requires<[UseSSE2]>;
3972 }
3973 } // SchedRW
3974
3975 let canFoldAsLoad = 1, mayLoad = 1, isReMaterializable = 1,
3976     neverHasSideEffects = 1, SchedRW = [WriteLoad] in {
3977 def MOVDQArm : PDI<0x6F, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
3978                    "movdqa\t{$src, $dst|$dst, $src}",
3979                    [/*(set VR128:$dst, (alignedloadv2i64 addr:$src))*/],
3980                    IIC_SSE_MOVA_P_RM>;
3981 def MOVDQUrm :   I<0x6F, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
3982                    "movdqu\t{$src, $dst|$dst, $src}",
3983                    [/*(set VR128:$dst, (loadv2i64 addr:$src))*/],
3984                    IIC_SSE_MOVU_P_RM>,
3985                  XS, Requires<[UseSSE2]>;
3986 }
3987
3988 let mayStore = 1, neverHasSideEffects = 1, SchedRW = [WriteStore] in {
3989 def MOVDQAmr : PDI<0x7F, MRMDestMem, (outs), (ins i128mem:$dst, VR128:$src),
3990                    "movdqa\t{$src, $dst|$dst, $src}",
3991                    [/*(alignedstore (v2i64 VR128:$src), addr:$dst)*/],
3992                    IIC_SSE_MOVA_P_MR>;
3993 def MOVDQUmr :   I<0x7F, MRMDestMem, (outs), (ins i128mem:$dst, VR128:$src),
3994                    "movdqu\t{$src, $dst|$dst, $src}",
3995                    [/*(store (v2i64 VR128:$src), addr:$dst)*/],
3996                    IIC_SSE_MOVU_P_MR>,
3997                  XS, Requires<[UseSSE2]>;
3998 }
3999
4000 } // ExeDomain = SSEPackedInt
4001
4002 let Predicates = [HasAVX] in {
4003   def : Pat<(int_x86_sse2_storeu_dq addr:$dst, VR128:$src),
4004             (VMOVDQUmr addr:$dst, VR128:$src)>;
4005   def : Pat<(int_x86_avx_storeu_dq_256 addr:$dst, VR256:$src),
4006             (VMOVDQUYmr addr:$dst, VR256:$src)>;
4007 }
4008 let Predicates = [UseSSE2] in
4009 def : Pat<(int_x86_sse2_storeu_dq addr:$dst, VR128:$src),
4010           (MOVDQUmr addr:$dst, VR128:$src)>;
4011
4012 //===---------------------------------------------------------------------===//
4013 // SSE2 - Packed Integer Arithmetic Instructions
4014 //===---------------------------------------------------------------------===//
4015
4016 let Sched = WriteVecIMul in
4017 def SSE_PMADD : OpndItins<
4018   IIC_SSE_PMADD, IIC_SSE_PMADD
4019 >;
4020
4021 let ExeDomain = SSEPackedInt in { // SSE integer instructions
4022
4023 multiclass PDI_binop_rm_int<bits<8> opc, string OpcodeStr, Intrinsic IntId,
4024                             RegisterClass RC, PatFrag memop_frag,
4025                             X86MemOperand x86memop,
4026                             OpndItins itins,
4027                             bit IsCommutable = 0,
4028                             bit Is2Addr = 1> {
4029   let isCommutable = IsCommutable in
4030   def rr : PDI<opc, MRMSrcReg, (outs RC:$dst),
4031        (ins RC:$src1, RC:$src2),
4032        !if(Is2Addr,
4033            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
4034            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
4035        [(set RC:$dst, (IntId RC:$src1, RC:$src2))], itins.rr>,
4036       Sched<[itins.Sched]>;
4037   def rm : PDI<opc, MRMSrcMem, (outs RC:$dst),
4038        (ins RC:$src1, x86memop:$src2),
4039        !if(Is2Addr,
4040            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
4041            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
4042        [(set RC:$dst, (IntId RC:$src1, (bitconvert (memop_frag addr:$src2))))],
4043        itins.rm>, Sched<[itins.Sched.Folded, ReadAfterLd]>;
4044 }
4045
4046 multiclass PDI_binop_all_int<bits<8> opc, string OpcodeStr, Intrinsic IntId128,
4047                              Intrinsic IntId256, OpndItins itins,
4048                              bit IsCommutable = 0> {
4049 let Predicates = [HasAVX] in
4050   defm V#NAME : PDI_binop_rm_int<opc, !strconcat("v", OpcodeStr), IntId128,
4051                                  VR128, loadv2i64, i128mem, itins,
4052                                  IsCommutable, 0>, VEX_4V;
4053
4054 let Constraints = "$src1 = $dst" in
4055   defm NAME : PDI_binop_rm_int<opc, OpcodeStr, IntId128, VR128, memopv2i64,
4056                                i128mem, itins, IsCommutable, 1>;
4057
4058 let Predicates = [HasAVX2] in
4059   defm V#NAME#Y : PDI_binop_rm_int<opc, !strconcat("v", OpcodeStr), IntId256,
4060                                    VR256, loadv4i64, i256mem, itins,
4061                                    IsCommutable, 0>, VEX_4V, VEX_L;
4062 }
4063
4064 multiclass PDI_binop_rmi<bits<8> opc, bits<8> opc2, Format ImmForm,
4065                          string OpcodeStr, SDNode OpNode,
4066                          SDNode OpNode2, RegisterClass RC,
4067                          ValueType DstVT, ValueType SrcVT, PatFrag bc_frag,
4068                          ShiftOpndItins itins,
4069                          bit Is2Addr = 1> {
4070   // src2 is always 128-bit
4071   def rr : PDI<opc, MRMSrcReg, (outs RC:$dst),
4072        (ins RC:$src1, VR128:$src2),
4073        !if(Is2Addr,
4074            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
4075            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
4076        [(set RC:$dst, (DstVT (OpNode RC:$src1, (SrcVT VR128:$src2))))],
4077         itins.rr>, Sched<[WriteVecShift]>;
4078   def rm : PDI<opc, MRMSrcMem, (outs RC:$dst),
4079        (ins RC:$src1, i128mem:$src2),
4080        !if(Is2Addr,
4081            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
4082            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
4083        [(set RC:$dst, (DstVT (OpNode RC:$src1,
4084                        (bc_frag (memopv2i64 addr:$src2)))))], itins.rm>,
4085       Sched<[WriteVecShiftLd, ReadAfterLd]>;
4086   def ri : PDIi8<opc2, ImmForm, (outs RC:$dst),
4087        (ins RC:$src1, i8imm:$src2),
4088        !if(Is2Addr,
4089            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
4090            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
4091        [(set RC:$dst, (DstVT (OpNode2 RC:$src1, (i8 imm:$src2))))], itins.ri>,
4092        Sched<[WriteVecShift]>;
4093 }
4094
4095 /// PDI_binop_rm2 - Simple SSE2 binary operator with different src and dst types
4096 multiclass PDI_binop_rm2<bits<8> opc, string OpcodeStr, SDNode OpNode,
4097                          ValueType DstVT, ValueType SrcVT, RegisterClass RC,
4098                          PatFrag memop_frag, X86MemOperand x86memop,
4099                          OpndItins itins,
4100                          bit IsCommutable = 0, bit Is2Addr = 1> {
4101   let isCommutable = IsCommutable in
4102   def rr : PDI<opc, MRMSrcReg, (outs RC:$dst),
4103        (ins RC:$src1, RC:$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, (DstVT (OpNode (SrcVT RC:$src1), RC:$src2)))]>,
4108        Sched<[itins.Sched]>;
4109   def rm : PDI<opc, MRMSrcMem, (outs RC:$dst),
4110        (ins RC:$src1, x86memop:$src2),
4111        !if(Is2Addr,
4112            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
4113            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
4114        [(set RC:$dst, (DstVT (OpNode (SrcVT RC:$src1),
4115                                      (bitconvert (memop_frag addr:$src2)))))]>,
4116        Sched<[itins.Sched.Folded, ReadAfterLd]>;
4117 }
4118 } // ExeDomain = SSEPackedInt
4119
4120 defm PADDB   : PDI_binop_all<0xFC, "paddb", add, v16i8, v32i8,
4121                              SSE_INTALU_ITINS_P, 1>;
4122 defm PADDW   : PDI_binop_all<0xFD, "paddw", add, v8i16, v16i16,
4123                              SSE_INTALU_ITINS_P, 1>;
4124 defm PADDD   : PDI_binop_all<0xFE, "paddd", add, v4i32, v8i32,
4125                              SSE_INTALU_ITINS_P, 1>;
4126 defm PADDQ   : PDI_binop_all<0xD4, "paddq", add, v2i64, v4i64,
4127                              SSE_INTALUQ_ITINS_P, 1>;
4128 defm PMULLW  : PDI_binop_all<0xD5, "pmullw", mul, v8i16, v16i16,
4129                              SSE_INTMUL_ITINS_P, 1>;
4130 defm PMULHUW : PDI_binop_all<0xE4, "pmulhuw", mulhu, v8i16, v16i16,
4131                              SSE_INTMUL_ITINS_P, 1>;
4132 defm PMULHW  : PDI_binop_all<0xE5, "pmulhw", mulhs, v8i16, v16i16,
4133                              SSE_INTMUL_ITINS_P, 1>;
4134 defm PSUBB   : PDI_binop_all<0xF8, "psubb", sub, v16i8, v32i8,
4135                              SSE_INTALU_ITINS_P, 0>;
4136 defm PSUBW   : PDI_binop_all<0xF9, "psubw", sub, v8i16, v16i16,
4137                              SSE_INTALU_ITINS_P, 0>;
4138 defm PSUBD   : PDI_binop_all<0xFA, "psubd", sub, v4i32, v8i32,
4139                              SSE_INTALU_ITINS_P, 0>;
4140 defm PSUBQ   : PDI_binop_all<0xFB, "psubq", sub, v2i64, v4i64,
4141                              SSE_INTALUQ_ITINS_P, 0>;
4142 defm PSUBUSB : PDI_binop_all<0xD8, "psubusb", X86subus, v16i8, v32i8,
4143                              SSE_INTALU_ITINS_P, 0>;
4144 defm PSUBUSW : PDI_binop_all<0xD9, "psubusw", X86subus, v8i16, v16i16,
4145                              SSE_INTALU_ITINS_P, 0>;
4146 defm PMINUB  : PDI_binop_all<0xDA, "pminub", X86umin, v16i8, v32i8,
4147                              SSE_INTALU_ITINS_P, 1>;
4148 defm PMINSW  : PDI_binop_all<0xEA, "pminsw", X86smin, v8i16, v16i16,
4149                              SSE_INTALU_ITINS_P, 1>;
4150 defm PMAXUB  : PDI_binop_all<0xDE, "pmaxub", X86umax, v16i8, v32i8,
4151                              SSE_INTALU_ITINS_P, 1>;
4152 defm PMAXSW  : PDI_binop_all<0xEE, "pmaxsw", X86smax, v8i16, v16i16,
4153                              SSE_INTALU_ITINS_P, 1>;
4154
4155 // Intrinsic forms
4156 defm PSUBSB  : PDI_binop_all_int<0xE8, "psubsb", int_x86_sse2_psubs_b,
4157                                  int_x86_avx2_psubs_b, SSE_INTALU_ITINS_P, 0>;
4158 defm PSUBSW  : PDI_binop_all_int<0xE9, "psubsw" , int_x86_sse2_psubs_w,
4159                                  int_x86_avx2_psubs_w, SSE_INTALU_ITINS_P, 0>;
4160 defm PADDSB  : PDI_binop_all_int<0xEC, "paddsb" , int_x86_sse2_padds_b,
4161                                  int_x86_avx2_padds_b, SSE_INTALU_ITINS_P, 1>;
4162 defm PADDSW  : PDI_binop_all_int<0xED, "paddsw" , int_x86_sse2_padds_w,
4163                                  int_x86_avx2_padds_w, SSE_INTALU_ITINS_P, 1>;
4164 defm PADDUSB : PDI_binop_all_int<0xDC, "paddusb", int_x86_sse2_paddus_b,
4165                                  int_x86_avx2_paddus_b, SSE_INTALU_ITINS_P, 1>;
4166 defm PADDUSW : PDI_binop_all_int<0xDD, "paddusw", int_x86_sse2_paddus_w,
4167                                  int_x86_avx2_paddus_w, SSE_INTALU_ITINS_P, 1>;
4168 defm PMADDWD : PDI_binop_all_int<0xF5, "pmaddwd", int_x86_sse2_pmadd_wd,
4169                                  int_x86_avx2_pmadd_wd, SSE_PMADD, 1>;
4170 defm PAVGB   : PDI_binop_all_int<0xE0, "pavgb", int_x86_sse2_pavg_b,
4171                                  int_x86_avx2_pavg_b, SSE_INTALU_ITINS_P, 1>;
4172 defm PAVGW   : PDI_binop_all_int<0xE3, "pavgw", int_x86_sse2_pavg_w,
4173                                  int_x86_avx2_pavg_w, SSE_INTALU_ITINS_P, 1>;
4174 defm PSADBW  : PDI_binop_all_int<0xF6, "psadbw", int_x86_sse2_psad_bw,
4175                                  int_x86_avx2_psad_bw, SSE_PMADD, 1>;
4176
4177 let Predicates = [HasAVX] in
4178 defm VPMULUDQ : PDI_binop_rm2<0xF4, "vpmuludq", X86pmuludq, v2i64, v4i32, VR128,
4179                               loadv2i64, i128mem, SSE_INTMUL_ITINS_P, 1, 0>,
4180                               VEX_4V;
4181 let Predicates = [HasAVX2] in
4182 defm VPMULUDQY : PDI_binop_rm2<0xF4, "vpmuludq", X86pmuludq, v4i64, v8i32,
4183                                VR256, loadv4i64, i256mem,
4184                                SSE_INTMUL_ITINS_P, 1, 0>, VEX_4V, VEX_L;
4185 let Constraints = "$src1 = $dst" in
4186 defm PMULUDQ : PDI_binop_rm2<0xF4, "pmuludq", X86pmuludq, v2i64, v4i32, VR128,
4187                              memopv2i64, i128mem, SSE_INTMUL_ITINS_P, 1>;
4188
4189 //===---------------------------------------------------------------------===//
4190 // SSE2 - Packed Integer Logical Instructions
4191 //===---------------------------------------------------------------------===//
4192
4193 let Predicates = [HasAVX] in {
4194 defm VPSLLW : PDI_binop_rmi<0xF1, 0x71, MRM6r, "vpsllw", X86vshl, X86vshli,
4195                             VR128, v8i16, v8i16, bc_v8i16,
4196                             SSE_INTSHIFT_ITINS_P, 0>, VEX_4V;
4197 defm VPSLLD : PDI_binop_rmi<0xF2, 0x72, MRM6r, "vpslld", X86vshl, X86vshli,
4198                             VR128, v4i32, v4i32, bc_v4i32,
4199                             SSE_INTSHIFT_ITINS_P, 0>, VEX_4V;
4200 defm VPSLLQ : PDI_binop_rmi<0xF3, 0x73, MRM6r, "vpsllq", X86vshl, X86vshli,
4201                             VR128, v2i64, v2i64, bc_v2i64,
4202                             SSE_INTSHIFT_ITINS_P, 0>, VEX_4V;
4203
4204 defm VPSRLW : PDI_binop_rmi<0xD1, 0x71, MRM2r, "vpsrlw", X86vsrl, X86vsrli,
4205                             VR128, v8i16, v8i16, bc_v8i16,
4206                             SSE_INTSHIFT_ITINS_P, 0>, VEX_4V;
4207 defm VPSRLD : PDI_binop_rmi<0xD2, 0x72, MRM2r, "vpsrld", X86vsrl, X86vsrli,
4208                             VR128, v4i32, v4i32, bc_v4i32,
4209                             SSE_INTSHIFT_ITINS_P, 0>, VEX_4V;
4210 defm VPSRLQ : PDI_binop_rmi<0xD3, 0x73, MRM2r, "vpsrlq", X86vsrl, X86vsrli,
4211                             VR128, v2i64, v2i64, bc_v2i64,
4212                             SSE_INTSHIFT_ITINS_P, 0>, VEX_4V;
4213
4214 defm VPSRAW : PDI_binop_rmi<0xE1, 0x71, MRM4r, "vpsraw", X86vsra, X86vsrai,
4215                             VR128, v8i16, v8i16, bc_v8i16,
4216                             SSE_INTSHIFT_ITINS_P, 0>, VEX_4V;
4217 defm VPSRAD : PDI_binop_rmi<0xE2, 0x72, MRM4r, "vpsrad", X86vsra, X86vsrai,
4218                             VR128, v4i32, v4i32, bc_v4i32,
4219                             SSE_INTSHIFT_ITINS_P, 0>, VEX_4V;
4220
4221 let ExeDomain = SSEPackedInt, SchedRW = [WriteVecShift] in {
4222   // 128-bit logical shifts.
4223   def VPSLLDQri : PDIi8<0x73, MRM7r,
4224                     (outs VR128:$dst), (ins VR128:$src1, i32i8imm:$src2),
4225                     "vpslldq\t{$src2, $src1, $dst|$dst, $src1, $src2}",
4226                     [(set VR128:$dst,
4227                       (int_x86_sse2_psll_dq_bs VR128:$src1, imm:$src2))]>,
4228                     VEX_4V;
4229   def VPSRLDQri : PDIi8<0x73, MRM3r,
4230                     (outs VR128:$dst), (ins VR128:$src1, i32i8imm:$src2),
4231                     "vpsrldq\t{$src2, $src1, $dst|$dst, $src1, $src2}",
4232                     [(set VR128:$dst,
4233                       (int_x86_sse2_psrl_dq_bs VR128:$src1, imm:$src2))]>,
4234                     VEX_4V;
4235   // PSRADQri doesn't exist in SSE[1-3].
4236 }
4237 } // Predicates = [HasAVX]
4238
4239 let Predicates = [HasAVX2] in {
4240 defm VPSLLWY : PDI_binop_rmi<0xF1, 0x71, MRM6r, "vpsllw", X86vshl, X86vshli,
4241                              VR256, v16i16, v8i16, bc_v8i16,
4242                              SSE_INTSHIFT_ITINS_P, 0>, VEX_4V, VEX_L;
4243 defm VPSLLDY : PDI_binop_rmi<0xF2, 0x72, MRM6r, "vpslld", X86vshl, X86vshli,
4244                              VR256, v8i32, v4i32, bc_v4i32,
4245                              SSE_INTSHIFT_ITINS_P, 0>, VEX_4V, VEX_L;
4246 defm VPSLLQY : PDI_binop_rmi<0xF3, 0x73, MRM6r, "vpsllq", X86vshl, X86vshli,
4247                              VR256, v4i64, v2i64, bc_v2i64,
4248                              SSE_INTSHIFT_ITINS_P, 0>, VEX_4V, VEX_L;
4249
4250 defm VPSRLWY : PDI_binop_rmi<0xD1, 0x71, MRM2r, "vpsrlw", X86vsrl, X86vsrli,
4251                              VR256, v16i16, v8i16, bc_v8i16,
4252                              SSE_INTSHIFT_ITINS_P, 0>, VEX_4V, VEX_L;
4253 defm VPSRLDY : PDI_binop_rmi<0xD2, 0x72, MRM2r, "vpsrld", X86vsrl, X86vsrli,
4254                              VR256, v8i32, v4i32, bc_v4i32,
4255                              SSE_INTSHIFT_ITINS_P, 0>, VEX_4V, VEX_L;
4256 defm VPSRLQY : PDI_binop_rmi<0xD3, 0x73, MRM2r, "vpsrlq", X86vsrl, X86vsrli,
4257                              VR256, v4i64, v2i64, bc_v2i64,
4258                              SSE_INTSHIFT_ITINS_P, 0>, VEX_4V, VEX_L;
4259
4260 defm VPSRAWY : PDI_binop_rmi<0xE1, 0x71, MRM4r, "vpsraw", X86vsra, X86vsrai,
4261                              VR256, v16i16, v8i16, bc_v8i16,
4262                              SSE_INTSHIFT_ITINS_P, 0>, VEX_4V, VEX_L;
4263 defm VPSRADY : PDI_binop_rmi<0xE2, 0x72, MRM4r, "vpsrad", X86vsra, X86vsrai,
4264                              VR256, v8i32, v4i32, bc_v4i32,
4265                              SSE_INTSHIFT_ITINS_P, 0>, VEX_4V, VEX_L;
4266
4267 let ExeDomain = SSEPackedInt, SchedRW = [WriteVecShift] in {
4268   // 256-bit logical shifts.
4269   def VPSLLDQYri : PDIi8<0x73, MRM7r,
4270                     (outs VR256:$dst), (ins VR256:$src1, i32i8imm:$src2),
4271                     "vpslldq\t{$src2, $src1, $dst|$dst, $src1, $src2}",
4272                     [(set VR256:$dst,
4273                       (int_x86_avx2_psll_dq_bs VR256:$src1, imm:$src2))]>,
4274                     VEX_4V, VEX_L;
4275   def VPSRLDQYri : PDIi8<0x73, MRM3r,
4276                     (outs VR256:$dst), (ins VR256:$src1, i32i8imm:$src2),
4277                     "vpsrldq\t{$src2, $src1, $dst|$dst, $src1, $src2}",
4278                     [(set VR256:$dst,
4279                       (int_x86_avx2_psrl_dq_bs VR256:$src1, imm:$src2))]>,
4280                     VEX_4V, VEX_L;
4281   // PSRADQYri doesn't exist in SSE[1-3].
4282 }
4283 } // Predicates = [HasAVX2]
4284
4285 let Constraints = "$src1 = $dst" in {
4286 defm PSLLW : PDI_binop_rmi<0xF1, 0x71, MRM6r, "psllw", X86vshl, X86vshli,
4287                            VR128, v8i16, v8i16, bc_v8i16,
4288                            SSE_INTSHIFT_ITINS_P>;
4289 defm PSLLD : PDI_binop_rmi<0xF2, 0x72, MRM6r, "pslld", X86vshl, X86vshli,
4290                            VR128, v4i32, v4i32, bc_v4i32,
4291                            SSE_INTSHIFT_ITINS_P>;
4292 defm PSLLQ : PDI_binop_rmi<0xF3, 0x73, MRM6r, "psllq", X86vshl, X86vshli,
4293                            VR128, v2i64, v2i64, bc_v2i64,
4294                            SSE_INTSHIFT_ITINS_P>;
4295
4296 defm PSRLW : PDI_binop_rmi<0xD1, 0x71, MRM2r, "psrlw", X86vsrl, X86vsrli,
4297                            VR128, v8i16, v8i16, bc_v8i16,
4298                            SSE_INTSHIFT_ITINS_P>;
4299 defm PSRLD : PDI_binop_rmi<0xD2, 0x72, MRM2r, "psrld", X86vsrl, X86vsrli,
4300                            VR128, v4i32, v4i32, bc_v4i32,
4301                            SSE_INTSHIFT_ITINS_P>;
4302 defm PSRLQ : PDI_binop_rmi<0xD3, 0x73, MRM2r, "psrlq", X86vsrl, X86vsrli,
4303                            VR128, v2i64, v2i64, bc_v2i64,
4304                            SSE_INTSHIFT_ITINS_P>;
4305
4306 defm PSRAW : PDI_binop_rmi<0xE1, 0x71, MRM4r, "psraw", X86vsra, X86vsrai,
4307                            VR128, v8i16, v8i16, bc_v8i16,
4308                            SSE_INTSHIFT_ITINS_P>;
4309 defm PSRAD : PDI_binop_rmi<0xE2, 0x72, MRM4r, "psrad", X86vsra, X86vsrai,
4310                            VR128, v4i32, v4i32, bc_v4i32,
4311                            SSE_INTSHIFT_ITINS_P>;
4312
4313 let ExeDomain = SSEPackedInt, SchedRW = [WriteVecShift] in {
4314   // 128-bit logical shifts.
4315   def PSLLDQri : PDIi8<0x73, MRM7r,
4316                        (outs VR128:$dst), (ins VR128:$src1, i32i8imm:$src2),
4317                        "pslldq\t{$src2, $dst|$dst, $src2}",
4318                        [(set VR128:$dst,
4319                          (int_x86_sse2_psll_dq_bs VR128:$src1, imm:$src2))],
4320                          IIC_SSE_INTSHDQ_P_RI>;
4321   def PSRLDQri : PDIi8<0x73, MRM3r,
4322                        (outs VR128:$dst), (ins VR128:$src1, i32i8imm:$src2),
4323                        "psrldq\t{$src2, $dst|$dst, $src2}",
4324                        [(set VR128:$dst,
4325                          (int_x86_sse2_psrl_dq_bs VR128:$src1, imm:$src2))],
4326                          IIC_SSE_INTSHDQ_P_RI>;
4327   // PSRADQri doesn't exist in SSE[1-3].
4328 }
4329 } // Constraints = "$src1 = $dst"
4330
4331 let Predicates = [HasAVX] in {
4332   def : Pat<(int_x86_sse2_psll_dq VR128:$src1, imm:$src2),
4333             (VPSLLDQri VR128:$src1, (BYTE_imm imm:$src2))>;
4334   def : Pat<(int_x86_sse2_psrl_dq VR128:$src1, imm:$src2),
4335             (VPSRLDQri VR128:$src1, (BYTE_imm imm:$src2))>;
4336   def : Pat<(v2f64 (X86fsrl VR128:$src1, i32immSExt8:$src2)),
4337             (VPSRLDQri VR128:$src1, (BYTE_imm imm:$src2))>;
4338
4339   // Shift up / down and insert zero's.
4340   def : Pat<(v2i64 (X86vshldq VR128:$src, (i8 imm:$amt))),
4341             (VPSLLDQri VR128:$src, (BYTE_imm imm:$amt))>;
4342   def : Pat<(v2i64 (X86vshrdq VR128:$src, (i8 imm:$amt))),
4343             (VPSRLDQri VR128:$src, (BYTE_imm imm:$amt))>;
4344 }
4345
4346 let Predicates = [HasAVX2] in {
4347   def : Pat<(int_x86_avx2_psll_dq VR256:$src1, imm:$src2),
4348             (VPSLLDQYri VR256:$src1, (BYTE_imm imm:$src2))>;
4349   def : Pat<(int_x86_avx2_psrl_dq VR256:$src1, imm:$src2),
4350             (VPSRLDQYri VR256:$src1, (BYTE_imm imm:$src2))>;
4351 }
4352
4353 let Predicates = [UseSSE2] in {
4354   def : Pat<(int_x86_sse2_psll_dq VR128:$src1, imm:$src2),
4355             (PSLLDQri VR128:$src1, (BYTE_imm imm:$src2))>;
4356   def : Pat<(int_x86_sse2_psrl_dq VR128:$src1, imm:$src2),
4357             (PSRLDQri VR128:$src1, (BYTE_imm imm:$src2))>;
4358   def : Pat<(v2f64 (X86fsrl VR128:$src1, i32immSExt8:$src2)),
4359             (PSRLDQri VR128:$src1, (BYTE_imm imm:$src2))>;
4360
4361   // Shift up / down and insert zero's.
4362   def : Pat<(v2i64 (X86vshldq VR128:$src, (i8 imm:$amt))),
4363             (PSLLDQri VR128:$src, (BYTE_imm imm:$amt))>;
4364   def : Pat<(v2i64 (X86vshrdq VR128:$src, (i8 imm:$amt))),
4365             (PSRLDQri VR128:$src, (BYTE_imm imm:$amt))>;
4366 }
4367
4368 //===---------------------------------------------------------------------===//
4369 // SSE2 - Packed Integer Comparison Instructions
4370 //===---------------------------------------------------------------------===//
4371
4372 defm PCMPEQB : PDI_binop_all<0x74, "pcmpeqb", X86pcmpeq, v16i8, v32i8,
4373                              SSE_INTALU_ITINS_P, 1>;
4374 defm PCMPEQW : PDI_binop_all<0x75, "pcmpeqw", X86pcmpeq, v8i16, v16i16,
4375                              SSE_INTALU_ITINS_P, 1>;
4376 defm PCMPEQD : PDI_binop_all<0x76, "pcmpeqd", X86pcmpeq, v4i32, v8i32,
4377                              SSE_INTALU_ITINS_P, 1>;
4378 defm PCMPGTB : PDI_binop_all<0x64, "pcmpgtb", X86pcmpgt, v16i8, v32i8,
4379                              SSE_INTALU_ITINS_P, 0>;
4380 defm PCMPGTW : PDI_binop_all<0x65, "pcmpgtw", X86pcmpgt, v8i16, v16i16,
4381                              SSE_INTALU_ITINS_P, 0>;
4382 defm PCMPGTD : PDI_binop_all<0x66, "pcmpgtd", X86pcmpgt, v4i32, v8i32,
4383                              SSE_INTALU_ITINS_P, 0>;
4384
4385 //===---------------------------------------------------------------------===//
4386 // SSE2 - Packed Integer Shuffle Instructions
4387 //===---------------------------------------------------------------------===//
4388
4389 let ExeDomain = SSEPackedInt in {
4390 multiclass sse2_pshuffle<string OpcodeStr, ValueType vt128, ValueType vt256,
4391                          SDNode OpNode> {
4392 let Predicates = [HasAVX] in {
4393   def V#NAME#ri : Ii8<0x70, MRMSrcReg, (outs VR128:$dst),
4394                       (ins VR128:$src1, i8imm:$src2),
4395                       !strconcat("v", OpcodeStr,
4396                                  "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4397                       [(set VR128:$dst,
4398                         (vt128 (OpNode VR128:$src1, (i8 imm:$src2))))],
4399                       IIC_SSE_PSHUF_RI>, VEX, Sched<[WriteShuffle]>;
4400   def V#NAME#mi : Ii8<0x70, MRMSrcMem, (outs VR128:$dst),
4401                       (ins i128mem:$src1, i8imm:$src2),
4402                       !strconcat("v", OpcodeStr,
4403                                  "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4404                      [(set VR128:$dst,
4405                        (vt128 (OpNode (bitconvert (loadv2i64 addr:$src1)),
4406                         (i8 imm:$src2))))], IIC_SSE_PSHUF_MI>, VEX,
4407                   Sched<[WriteShuffleLd]>;
4408 }
4409
4410 let Predicates = [HasAVX2] in {
4411   def V#NAME#Yri : Ii8<0x70, MRMSrcReg, (outs VR256:$dst),
4412                        (ins VR256:$src1, i8imm:$src2),
4413                        !strconcat("v", OpcodeStr,
4414                                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4415                        [(set VR256:$dst,
4416                          (vt256 (OpNode VR256:$src1, (i8 imm:$src2))))],
4417                        IIC_SSE_PSHUF_RI>, VEX, VEX_L, Sched<[WriteShuffle]>;
4418   def V#NAME#Ymi : Ii8<0x70, MRMSrcMem, (outs VR256:$dst),
4419                        (ins i256mem:$src1, i8imm:$src2),
4420                        !strconcat("v", OpcodeStr,
4421                                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4422                       [(set VR256:$dst,
4423                         (vt256 (OpNode (bitconvert (loadv4i64 addr:$src1)),
4424                          (i8 imm:$src2))))], IIC_SSE_PSHUF_MI>, VEX, VEX_L,
4425                    Sched<[WriteShuffleLd]>;
4426 }
4427
4428 let Predicates = [UseSSE2] in {
4429   def ri : Ii8<0x70, MRMSrcReg,
4430                (outs VR128:$dst), (ins VR128:$src1, i8imm:$src2),
4431                !strconcat(OpcodeStr,
4432                           "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4433                 [(set VR128:$dst,
4434                   (vt128 (OpNode VR128:$src1, (i8 imm:$src2))))],
4435                 IIC_SSE_PSHUF_RI>, Sched<[WriteShuffle]>;
4436   def mi : Ii8<0x70, MRMSrcMem,
4437                (outs VR128:$dst), (ins i128mem:$src1, i8imm:$src2),
4438                !strconcat(OpcodeStr,
4439                           "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4440                 [(set VR128:$dst,
4441                   (vt128 (OpNode (bitconvert (memopv2i64 addr:$src1)),
4442                           (i8 imm:$src2))))], IIC_SSE_PSHUF_MI>,
4443            Sched<[WriteShuffleLd, ReadAfterLd]>;
4444 }
4445 }
4446 } // ExeDomain = SSEPackedInt
4447
4448 defm PSHUFD  : sse2_pshuffle<"pshufd", v4i32, v8i32, X86PShufd>, PD;
4449 defm PSHUFHW : sse2_pshuffle<"pshufhw", v8i16, v16i16, X86PShufhw>, XS;
4450 defm PSHUFLW : sse2_pshuffle<"pshuflw", v8i16, v16i16, X86PShuflw>, XD;
4451
4452 let Predicates = [HasAVX] in {
4453   def : Pat<(v4f32 (X86PShufd (loadv4f32 addr:$src1), (i8 imm:$imm))),
4454             (VPSHUFDmi addr:$src1, imm:$imm)>;
4455   def : Pat<(v4f32 (X86PShufd VR128:$src1, (i8 imm:$imm))),
4456             (VPSHUFDri VR128:$src1, imm:$imm)>;
4457 }
4458
4459 let Predicates = [UseSSE2] in {
4460   def : Pat<(v4f32 (X86PShufd (memopv4f32 addr:$src1), (i8 imm:$imm))),
4461             (PSHUFDmi addr:$src1, imm:$imm)>;
4462   def : Pat<(v4f32 (X86PShufd VR128:$src1, (i8 imm:$imm))),
4463             (PSHUFDri VR128:$src1, imm:$imm)>;
4464 }
4465
4466 //===---------------------------------------------------------------------===//
4467 // Packed Integer Pack Instructions (SSE & AVX)
4468 //===---------------------------------------------------------------------===//
4469
4470 let ExeDomain = SSEPackedInt in {
4471 multiclass sse2_pack<bits<8> opc, string OpcodeStr, ValueType OutVT,
4472                      ValueType ArgVT, SDNode OpNode, PatFrag bc_frag,
4473                      bit Is2Addr = 1> {
4474   def rr : PDI<opc, MRMSrcReg,
4475                (outs VR128:$dst), (ins VR128:$src1, VR128:$src2),
4476                !if(Is2Addr,
4477                    !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
4478                    !strconcat(OpcodeStr,
4479                               "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
4480                [(set VR128:$dst,
4481                      (OutVT (OpNode (ArgVT VR128:$src1), VR128:$src2)))]>,
4482                Sched<[WriteShuffle]>;
4483   def rm : PDI<opc, MRMSrcMem,
4484                (outs VR128:$dst), (ins VR128:$src1, i128mem:$src2),
4485                !if(Is2Addr,
4486                    !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
4487                    !strconcat(OpcodeStr,
4488                               "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
4489                [(set VR128:$dst,
4490                      (OutVT (OpNode VR128:$src1,
4491                                     (bc_frag (memopv2i64 addr:$src2)))))]>,
4492                Sched<[WriteShuffleLd, ReadAfterLd]>;
4493 }
4494
4495 multiclass sse2_pack_y<bits<8> opc, string OpcodeStr, ValueType OutVT,
4496                        ValueType ArgVT, SDNode OpNode, PatFrag bc_frag> {
4497   def Yrr : PDI<opc, MRMSrcReg,
4498                 (outs VR256:$dst), (ins VR256:$src1, VR256:$src2),
4499                 !strconcat(OpcodeStr,
4500                            "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4501                 [(set VR256:$dst,
4502                       (OutVT (OpNode (ArgVT VR256:$src1), VR256:$src2)))]>,
4503                 Sched<[WriteShuffle]>;
4504   def Yrm : PDI<opc, MRMSrcMem,
4505                 (outs VR256:$dst), (ins VR256:$src1, i256mem:$src2),
4506                 !strconcat(OpcodeStr,
4507                            "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4508                 [(set VR256:$dst,
4509                       (OutVT (OpNode VR256:$src1,
4510                                      (bc_frag (memopv4i64 addr:$src2)))))]>,
4511                 Sched<[WriteShuffleLd, ReadAfterLd]>;
4512 }
4513
4514 multiclass sse4_pack<bits<8> opc, string OpcodeStr, ValueType OutVT,
4515                      ValueType ArgVT, SDNode OpNode, PatFrag bc_frag,
4516                      bit Is2Addr = 1> {
4517   def rr : SS48I<opc, MRMSrcReg,
4518                  (outs VR128:$dst), (ins VR128:$src1, VR128:$src2),
4519                  !if(Is2Addr,
4520                      !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
4521                      !strconcat(OpcodeStr,
4522                                 "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
4523                  [(set VR128:$dst,
4524                        (OutVT (OpNode (ArgVT VR128:$src1), VR128:$src2)))]>,
4525                  Sched<[WriteShuffle]>;
4526   def rm : SS48I<opc, MRMSrcMem,
4527                  (outs VR128:$dst), (ins VR128:$src1, i128mem:$src2),
4528                  !if(Is2Addr,
4529                      !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
4530                      !strconcat(OpcodeStr,
4531                                 "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
4532                  [(set VR128:$dst,
4533                        (OutVT (OpNode VR128:$src1,
4534                                       (bc_frag (memopv2i64 addr:$src2)))))]>,
4535                  Sched<[WriteShuffleLd, ReadAfterLd]>;
4536 }
4537
4538 multiclass sse4_pack_y<bits<8> opc, string OpcodeStr, ValueType OutVT,
4539                      ValueType ArgVT, SDNode OpNode, PatFrag bc_frag> {
4540   def Yrr : SS48I<opc, MRMSrcReg,
4541                   (outs VR256:$dst), (ins VR256:$src1, VR256:$src2),
4542                   !strconcat(OpcodeStr,
4543                              "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4544                   [(set VR256:$dst,
4545                         (OutVT (OpNode (ArgVT VR256:$src1), VR256:$src2)))]>,
4546                   Sched<[WriteShuffle]>;
4547   def Yrm : SS48I<opc, MRMSrcMem,
4548                   (outs VR256:$dst), (ins VR256:$src1, i256mem:$src2),
4549                   !strconcat(OpcodeStr,
4550                              "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4551                   [(set VR256:$dst,
4552                         (OutVT (OpNode VR256:$src1,
4553                                        (bc_frag (memopv4i64 addr:$src2)))))]>,
4554                   Sched<[WriteShuffleLd, ReadAfterLd]>;
4555 }
4556
4557 let Predicates = [HasAVX] in {
4558   defm VPACKSSWB : sse2_pack<0x63, "vpacksswb", v16i8, v8i16, X86Packss,
4559                              bc_v8i16, 0>, VEX_4V;
4560   defm VPACKSSDW : sse2_pack<0x6B, "vpackssdw", v8i16, v4i32, X86Packss,
4561                              bc_v4i32, 0>, VEX_4V;
4562
4563   defm VPACKUSWB : sse2_pack<0x67, "vpackuswb", v16i8, v8i16, X86Packus,
4564                              bc_v8i16, 0>, VEX_4V;
4565   defm VPACKUSDW : sse4_pack<0x2B, "vpackusdw", v8i16, v4i32, X86Packus,
4566                              bc_v4i32, 0>, VEX_4V;
4567 }
4568
4569 let Predicates = [HasAVX2] in {
4570   defm VPACKSSWB : sse2_pack_y<0x63, "vpacksswb", v32i8, v16i16, X86Packss,
4571                                bc_v16i16>, VEX_4V, VEX_L;
4572   defm VPACKSSDW : sse2_pack_y<0x6B, "vpackssdw", v16i16, v8i32, X86Packss,
4573                                bc_v8i32>, VEX_4V, VEX_L;
4574
4575   defm VPACKUSWB : sse2_pack_y<0x67, "vpackuswb", v32i8, v16i16, X86Packus,
4576                                bc_v16i16>, VEX_4V, VEX_L;
4577   defm VPACKUSDW : sse4_pack_y<0x2B, "vpackusdw", v16i16, v8i32, X86Packus,
4578                                bc_v8i32>, VEX_4V, VEX_L;
4579 }
4580
4581 let Constraints = "$src1 = $dst" in {
4582   defm PACKSSWB : sse2_pack<0x63, "packsswb", v16i8, v8i16, X86Packss,
4583                             bc_v8i16>;
4584   defm PACKSSDW : sse2_pack<0x6B, "packssdw", v8i16, v4i32, X86Packss,
4585                             bc_v4i32>;
4586
4587   defm PACKUSWB : sse2_pack<0x67, "packuswb", v16i8, v8i16, X86Packus,
4588                             bc_v8i16>;
4589
4590   let Predicates = [HasSSE41] in
4591   defm PACKUSDW : sse4_pack<0x2B, "packusdw", v8i16, v4i32, X86Packus,
4592                             bc_v4i32>;
4593 }
4594 } // ExeDomain = SSEPackedInt
4595
4596 //===---------------------------------------------------------------------===//
4597 // SSE2 - Packed Integer Unpack Instructions
4598 //===---------------------------------------------------------------------===//
4599
4600 let ExeDomain = SSEPackedInt in {
4601 multiclass sse2_unpack<bits<8> opc, string OpcodeStr, ValueType vt,
4602                        SDNode OpNode, PatFrag bc_frag, bit Is2Addr = 1> {
4603   def rr : PDI<opc, MRMSrcReg,
4604       (outs VR128:$dst), (ins VR128:$src1, VR128:$src2),
4605       !if(Is2Addr,
4606           !strconcat(OpcodeStr,"\t{$src2, $dst|$dst, $src2}"),
4607           !strconcat(OpcodeStr,"\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
4608       [(set VR128:$dst, (vt (OpNode VR128:$src1, VR128:$src2)))],
4609       IIC_SSE_UNPCK>, Sched<[WriteShuffle]>;
4610   def rm : PDI<opc, MRMSrcMem,
4611       (outs VR128:$dst), (ins VR128:$src1, i128mem:$src2),
4612       !if(Is2Addr,
4613           !strconcat(OpcodeStr,"\t{$src2, $dst|$dst, $src2}"),
4614           !strconcat(OpcodeStr,"\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
4615       [(set VR128:$dst, (OpNode VR128:$src1,
4616                                   (bc_frag (memopv2i64
4617                                                addr:$src2))))],
4618                                                IIC_SSE_UNPCK>,
4619       Sched<[WriteShuffleLd, ReadAfterLd]>;
4620 }
4621
4622 multiclass sse2_unpack_y<bits<8> opc, string OpcodeStr, ValueType vt,
4623                          SDNode OpNode, PatFrag bc_frag> {
4624   def Yrr : PDI<opc, MRMSrcReg,
4625       (outs VR256:$dst), (ins VR256:$src1, VR256:$src2),
4626       !strconcat(OpcodeStr,"\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4627       [(set VR256:$dst, (vt (OpNode VR256:$src1, VR256:$src2)))]>,
4628       Sched<[WriteShuffle]>;
4629   def Yrm : PDI<opc, MRMSrcMem,
4630       (outs VR256:$dst), (ins VR256:$src1, i256mem:$src2),
4631       !strconcat(OpcodeStr,"\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4632       [(set VR256:$dst, (OpNode VR256:$src1,
4633                                   (bc_frag (memopv4i64 addr:$src2))))]>,
4634       Sched<[WriteShuffleLd, ReadAfterLd]>;
4635 }
4636
4637 let Predicates = [HasAVX] in {
4638   defm VPUNPCKLBW  : sse2_unpack<0x60, "vpunpcklbw", v16i8, X86Unpckl,
4639                                  bc_v16i8, 0>, VEX_4V;
4640   defm VPUNPCKLWD  : sse2_unpack<0x61, "vpunpcklwd", v8i16, X86Unpckl,
4641                                  bc_v8i16, 0>, VEX_4V;
4642   defm VPUNPCKLDQ  : sse2_unpack<0x62, "vpunpckldq", v4i32, X86Unpckl,
4643                                  bc_v4i32, 0>, VEX_4V;
4644   defm VPUNPCKLQDQ : sse2_unpack<0x6C, "vpunpcklqdq", v2i64, X86Unpckl,
4645                                  bc_v2i64, 0>, VEX_4V;
4646
4647   defm VPUNPCKHBW  : sse2_unpack<0x68, "vpunpckhbw", v16i8, X86Unpckh,
4648                                  bc_v16i8, 0>, VEX_4V;
4649   defm VPUNPCKHWD  : sse2_unpack<0x69, "vpunpckhwd", v8i16, X86Unpckh,
4650                                  bc_v8i16, 0>, VEX_4V;
4651   defm VPUNPCKHDQ  : sse2_unpack<0x6A, "vpunpckhdq", v4i32, X86Unpckh,
4652                                  bc_v4i32, 0>, VEX_4V;
4653   defm VPUNPCKHQDQ : sse2_unpack<0x6D, "vpunpckhqdq", v2i64, X86Unpckh,
4654                                  bc_v2i64, 0>, VEX_4V;
4655 }
4656
4657 let Predicates = [HasAVX2] in {
4658   defm VPUNPCKLBW  : sse2_unpack_y<0x60, "vpunpcklbw", v32i8, X86Unpckl,
4659                                    bc_v32i8>, VEX_4V, VEX_L;
4660   defm VPUNPCKLWD  : sse2_unpack_y<0x61, "vpunpcklwd", v16i16, X86Unpckl,
4661                                    bc_v16i16>, VEX_4V, VEX_L;
4662   defm VPUNPCKLDQ  : sse2_unpack_y<0x62, "vpunpckldq", v8i32, X86Unpckl,
4663                                    bc_v8i32>, VEX_4V, VEX_L;
4664   defm VPUNPCKLQDQ : sse2_unpack_y<0x6C, "vpunpcklqdq", v4i64, X86Unpckl,
4665                                    bc_v4i64>, VEX_4V, VEX_L;
4666
4667   defm VPUNPCKHBW  : sse2_unpack_y<0x68, "vpunpckhbw", v32i8, X86Unpckh,
4668                                    bc_v32i8>, VEX_4V, VEX_L;
4669   defm VPUNPCKHWD  : sse2_unpack_y<0x69, "vpunpckhwd", v16i16, X86Unpckh,
4670                                    bc_v16i16>, VEX_4V, VEX_L;
4671   defm VPUNPCKHDQ  : sse2_unpack_y<0x6A, "vpunpckhdq", v8i32, X86Unpckh,
4672                                    bc_v8i32>, VEX_4V, VEX_L;
4673   defm VPUNPCKHQDQ : sse2_unpack_y<0x6D, "vpunpckhqdq", v4i64, X86Unpckh,
4674                                    bc_v4i64>, VEX_4V, VEX_L;
4675 }
4676
4677 let Constraints = "$src1 = $dst" in {
4678   defm PUNPCKLBW  : sse2_unpack<0x60, "punpcklbw", v16i8, X86Unpckl,
4679                                 bc_v16i8>;
4680   defm PUNPCKLWD  : sse2_unpack<0x61, "punpcklwd", v8i16, X86Unpckl,
4681                                 bc_v8i16>;
4682   defm PUNPCKLDQ  : sse2_unpack<0x62, "punpckldq", v4i32, X86Unpckl,
4683                                 bc_v4i32>;
4684   defm PUNPCKLQDQ : sse2_unpack<0x6C, "punpcklqdq", v2i64, X86Unpckl,
4685                                 bc_v2i64>;
4686
4687   defm PUNPCKHBW  : sse2_unpack<0x68, "punpckhbw", v16i8, X86Unpckh,
4688                                 bc_v16i8>;
4689   defm PUNPCKHWD  : sse2_unpack<0x69, "punpckhwd", v8i16, X86Unpckh,
4690                                 bc_v8i16>;
4691   defm PUNPCKHDQ  : sse2_unpack<0x6A, "punpckhdq", v4i32, X86Unpckh,
4692                                 bc_v4i32>;
4693   defm PUNPCKHQDQ : sse2_unpack<0x6D, "punpckhqdq", v2i64, X86Unpckh,
4694                                 bc_v2i64>;
4695 }
4696 } // ExeDomain = SSEPackedInt
4697
4698 //===---------------------------------------------------------------------===//
4699 // SSE2 - Packed Integer Extract and Insert
4700 //===---------------------------------------------------------------------===//
4701
4702 let ExeDomain = SSEPackedInt in {
4703 multiclass sse2_pinsrw<bit Is2Addr = 1> {
4704   def rri : Ii8<0xC4, MRMSrcReg,
4705        (outs VR128:$dst), (ins VR128:$src1,
4706         GR32orGR64:$src2, i32i8imm:$src3),
4707        !if(Is2Addr,
4708            "pinsrw\t{$src3, $src2, $dst|$dst, $src2, $src3}",
4709            "vpinsrw\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
4710        [(set VR128:$dst,
4711          (X86pinsrw VR128:$src1, GR32orGR64:$src2, imm:$src3))],
4712        IIC_SSE_PINSRW>, Sched<[WriteShuffle]>;
4713   def rmi : Ii8<0xC4, MRMSrcMem,
4714                        (outs VR128:$dst), (ins VR128:$src1,
4715                         i16mem:$src2, i32i8imm:$src3),
4716        !if(Is2Addr,
4717            "pinsrw\t{$src3, $src2, $dst|$dst, $src2, $src3}",
4718            "vpinsrw\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
4719        [(set VR128:$dst,
4720          (X86pinsrw VR128:$src1, (extloadi16 addr:$src2),
4721                     imm:$src3))], IIC_SSE_PINSRW>,
4722        Sched<[WriteShuffleLd, ReadAfterLd]>;
4723 }
4724
4725 // Extract
4726 let Predicates = [HasAVX] in
4727 def VPEXTRWri : Ii8<0xC5, MRMSrcReg,
4728                     (outs GR32orGR64:$dst), (ins VR128:$src1, i32i8imm:$src2),
4729                     "vpextrw\t{$src2, $src1, $dst|$dst, $src1, $src2}",
4730                     [(set GR32orGR64:$dst, (X86pextrw (v8i16 VR128:$src1),
4731                                             imm:$src2))]>, PD, VEX,
4732                 Sched<[WriteShuffle]>;
4733 def PEXTRWri : PDIi8<0xC5, MRMSrcReg,
4734                     (outs GR32orGR64:$dst), (ins VR128:$src1, i32i8imm:$src2),
4735                     "pextrw\t{$src2, $src1, $dst|$dst, $src1, $src2}",
4736                     [(set GR32orGR64:$dst, (X86pextrw (v8i16 VR128:$src1),
4737                                             imm:$src2))], IIC_SSE_PEXTRW>,
4738                Sched<[WriteShuffleLd, ReadAfterLd]>;
4739
4740 // Insert
4741 let Predicates = [HasAVX] in
4742 defm VPINSRW : sse2_pinsrw<0>, PD, VEX_4V;
4743
4744 let Predicates = [UseSSE2], Constraints = "$src1 = $dst" in
4745 defm PINSRW : sse2_pinsrw, PD;
4746
4747 } // ExeDomain = SSEPackedInt
4748
4749 //===---------------------------------------------------------------------===//
4750 // SSE2 - Packed Mask Creation
4751 //===---------------------------------------------------------------------===//
4752
4753 let ExeDomain = SSEPackedInt, SchedRW = [WriteVecLogic] in {
4754
4755 def VPMOVMSKBrr  : VPDI<0xD7, MRMSrcReg, (outs GR32orGR64:$dst),
4756            (ins VR128:$src),
4757            "pmovmskb\t{$src, $dst|$dst, $src}",
4758            [(set GR32orGR64:$dst, (int_x86_sse2_pmovmskb_128 VR128:$src))],
4759            IIC_SSE_MOVMSK>, VEX;
4760
4761 let Predicates = [HasAVX2] in {
4762 def VPMOVMSKBYrr  : VPDI<0xD7, MRMSrcReg, (outs GR32orGR64:$dst),
4763            (ins VR256:$src),
4764            "pmovmskb\t{$src, $dst|$dst, $src}",
4765            [(set GR32orGR64:$dst, (int_x86_avx2_pmovmskb VR256:$src))]>,
4766            VEX, VEX_L;
4767 }
4768
4769 def PMOVMSKBrr : PDI<0xD7, MRMSrcReg, (outs GR32orGR64:$dst), (ins VR128:$src),
4770            "pmovmskb\t{$src, $dst|$dst, $src}",
4771            [(set GR32orGR64:$dst, (int_x86_sse2_pmovmskb_128 VR128:$src))],
4772            IIC_SSE_MOVMSK>;
4773
4774 } // ExeDomain = SSEPackedInt
4775
4776 //===---------------------------------------------------------------------===//
4777 // SSE2 - Conditional Store
4778 //===---------------------------------------------------------------------===//
4779
4780 let ExeDomain = SSEPackedInt, SchedRW = [WriteStore] in {
4781
4782 let Uses = [EDI], Predicates = [HasAVX,Not64BitMode] in
4783 def VMASKMOVDQU : VPDI<0xF7, MRMSrcReg, (outs),
4784            (ins VR128:$src, VR128:$mask),
4785            "maskmovdqu\t{$mask, $src|$src, $mask}",
4786            [(int_x86_sse2_maskmov_dqu VR128:$src, VR128:$mask, EDI)],
4787            IIC_SSE_MASKMOV>, VEX;
4788 let Uses = [RDI], Predicates = [HasAVX,In64BitMode] in
4789 def VMASKMOVDQU64 : VPDI<0xF7, MRMSrcReg, (outs),
4790            (ins VR128:$src, VR128:$mask),
4791            "maskmovdqu\t{$mask, $src|$src, $mask}",
4792            [(int_x86_sse2_maskmov_dqu VR128:$src, VR128:$mask, RDI)],
4793            IIC_SSE_MASKMOV>, VEX;
4794
4795 let Uses = [EDI], Predicates = [UseSSE2,Not64BitMode] in
4796 def MASKMOVDQU : PDI<0xF7, MRMSrcReg, (outs), (ins VR128:$src, VR128:$mask),
4797            "maskmovdqu\t{$mask, $src|$src, $mask}",
4798            [(int_x86_sse2_maskmov_dqu VR128:$src, VR128:$mask, EDI)],
4799            IIC_SSE_MASKMOV>;
4800 let Uses = [RDI], Predicates = [UseSSE2,In64BitMode] in
4801 def MASKMOVDQU64 : PDI<0xF7, MRMSrcReg, (outs), (ins VR128:$src, VR128:$mask),
4802            "maskmovdqu\t{$mask, $src|$src, $mask}",
4803            [(int_x86_sse2_maskmov_dqu VR128:$src, VR128:$mask, RDI)],
4804            IIC_SSE_MASKMOV>;
4805
4806 } // ExeDomain = SSEPackedInt
4807
4808 //===---------------------------------------------------------------------===//
4809 // SSE2 - Move Doubleword
4810 //===---------------------------------------------------------------------===//
4811
4812 //===---------------------------------------------------------------------===//
4813 // Move Int Doubleword to Packed Double Int
4814 //
4815 def VMOVDI2PDIrr : VS2I<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR32:$src),
4816                       "movd\t{$src, $dst|$dst, $src}",
4817                       [(set VR128:$dst,
4818                         (v4i32 (scalar_to_vector GR32:$src)))], IIC_SSE_MOVDQ>,
4819                         VEX, Sched<[WriteMove]>;
4820 def VMOVDI2PDIrm : VS2I<0x6E, MRMSrcMem, (outs VR128:$dst), (ins i32mem:$src),
4821                       "movd\t{$src, $dst|$dst, $src}",
4822                       [(set VR128:$dst,
4823                         (v4i32 (scalar_to_vector (loadi32 addr:$src))))],
4824                         IIC_SSE_MOVDQ>,
4825                       VEX, Sched<[WriteLoad]>;
4826 def VMOV64toPQIrr : VRS2I<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR64:$src),
4827                         "movq\t{$src, $dst|$dst, $src}",
4828                         [(set VR128:$dst,
4829                           (v2i64 (scalar_to_vector GR64:$src)))],
4830                           IIC_SSE_MOVDQ>, VEX, Sched<[WriteMove]>;
4831 let isCodeGenOnly = 1 in
4832 def VMOV64toSDrr : VRS2I<0x6E, MRMSrcReg, (outs FR64:$dst), (ins GR64:$src),
4833                        "movq\t{$src, $dst|$dst, $src}",
4834                        [(set FR64:$dst, (bitconvert GR64:$src))],
4835                        IIC_SSE_MOVDQ>, VEX, Sched<[WriteMove]>;
4836
4837 def MOVDI2PDIrr : S2I<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR32:$src),
4838                       "movd\t{$src, $dst|$dst, $src}",
4839                       [(set VR128:$dst,
4840                         (v4i32 (scalar_to_vector GR32:$src)))], IIC_SSE_MOVDQ>,
4841                   Sched<[WriteMove]>;
4842 def MOVDI2PDIrm : S2I<0x6E, MRMSrcMem, (outs VR128:$dst), (ins i32mem:$src),
4843                       "movd\t{$src, $dst|$dst, $src}",
4844                       [(set VR128:$dst,
4845                         (v4i32 (scalar_to_vector (loadi32 addr:$src))))],
4846                         IIC_SSE_MOVDQ>, Sched<[WriteLoad]>;
4847 def MOV64toPQIrr : RS2I<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR64:$src),
4848                         "mov{d|q}\t{$src, $dst|$dst, $src}",
4849                         [(set VR128:$dst,
4850                           (v2i64 (scalar_to_vector GR64:$src)))],
4851                           IIC_SSE_MOVDQ>, Sched<[WriteMove]>;
4852 let isCodeGenOnly = 1 in
4853 def MOV64toSDrr : RS2I<0x6E, MRMSrcReg, (outs FR64:$dst), (ins GR64:$src),
4854                        "mov{d|q}\t{$src, $dst|$dst, $src}",
4855                        [(set FR64:$dst, (bitconvert GR64:$src))],
4856                        IIC_SSE_MOVDQ>, Sched<[WriteMove]>;
4857
4858 //===---------------------------------------------------------------------===//
4859 // Move Int Doubleword to Single Scalar
4860 //
4861 let isCodeGenOnly = 1 in {
4862   def VMOVDI2SSrr  : VS2I<0x6E, MRMSrcReg, (outs FR32:$dst), (ins GR32:$src),
4863                         "movd\t{$src, $dst|$dst, $src}",
4864                         [(set FR32:$dst, (bitconvert GR32:$src))],
4865                         IIC_SSE_MOVDQ>, VEX, Sched<[WriteMove]>;
4866
4867   def VMOVDI2SSrm  : VS2I<0x6E, MRMSrcMem, (outs FR32:$dst), (ins i32mem:$src),
4868                         "movd\t{$src, $dst|$dst, $src}",
4869                         [(set FR32:$dst, (bitconvert (loadi32 addr:$src)))],
4870                         IIC_SSE_MOVDQ>,
4871                         VEX, Sched<[WriteLoad]>;
4872   def MOVDI2SSrr  : S2I<0x6E, MRMSrcReg, (outs FR32:$dst), (ins GR32:$src),
4873                         "movd\t{$src, $dst|$dst, $src}",
4874                         [(set FR32:$dst, (bitconvert GR32:$src))],
4875                         IIC_SSE_MOVDQ>, Sched<[WriteMove]>;
4876
4877   def MOVDI2SSrm  : S2I<0x6E, MRMSrcMem, (outs FR32:$dst), (ins i32mem:$src),
4878                         "movd\t{$src, $dst|$dst, $src}",
4879                         [(set FR32:$dst, (bitconvert (loadi32 addr:$src)))],
4880                         IIC_SSE_MOVDQ>, Sched<[WriteLoad]>;
4881 }
4882
4883 //===---------------------------------------------------------------------===//
4884 // Move Packed Doubleword Int to Packed Double Int
4885 //
4886 def VMOVPDI2DIrr  : VS2I<0x7E, MRMDestReg, (outs GR32:$dst), (ins VR128:$src),
4887                        "movd\t{$src, $dst|$dst, $src}",
4888                        [(set GR32:$dst, (vector_extract (v4i32 VR128:$src),
4889                                         (iPTR 0)))], IIC_SSE_MOVD_ToGP>, VEX,
4890                     Sched<[WriteMove]>;
4891 def VMOVPDI2DImr  : VS2I<0x7E, MRMDestMem, (outs),
4892                        (ins i32mem:$dst, VR128:$src),
4893                        "movd\t{$src, $dst|$dst, $src}",
4894                        [(store (i32 (vector_extract (v4i32 VR128:$src),
4895                                      (iPTR 0))), addr:$dst)], IIC_SSE_MOVDQ>,
4896                                      VEX, Sched<[WriteStore]>;
4897 def MOVPDI2DIrr  : S2I<0x7E, MRMDestReg, (outs GR32:$dst), (ins VR128:$src),
4898                        "movd\t{$src, $dst|$dst, $src}",
4899                        [(set GR32:$dst, (vector_extract (v4i32 VR128:$src),
4900                                         (iPTR 0)))], IIC_SSE_MOVD_ToGP>,
4901                    Sched<[WriteMove]>;
4902 def MOVPDI2DImr  : S2I<0x7E, MRMDestMem, (outs), (ins i32mem:$dst, VR128:$src),
4903                        "movd\t{$src, $dst|$dst, $src}",
4904                        [(store (i32 (vector_extract (v4i32 VR128:$src),
4905                                      (iPTR 0))), addr:$dst)],
4906                                      IIC_SSE_MOVDQ>, Sched<[WriteStore]>;
4907
4908 def : Pat<(v8i32 (X86Vinsert (v8i32 immAllZerosV), GR32:$src2, (iPTR 0))),
4909         (SUBREG_TO_REG (i32 0), (VMOVDI2PDIrr GR32:$src2), sub_xmm)>;
4910
4911 def : Pat<(v4i64 (X86Vinsert (bc_v4i64 (v8i32 immAllZerosV)), GR64:$src2, (iPTR 0))),
4912         (SUBREG_TO_REG (i32 0), (VMOV64toPQIrr GR64:$src2), sub_xmm)>;
4913
4914 def : Pat<(v8i32 (X86Vinsert undef, GR32:$src2, (iPTR 0))),
4915         (SUBREG_TO_REG (i32 0), (VMOVDI2PDIrr GR32:$src2), sub_xmm)>;
4916
4917 def : Pat<(v4i64 (X86Vinsert undef, GR64:$src2, (iPTR 0))),
4918         (SUBREG_TO_REG (i32 0), (VMOV64toPQIrr GR64:$src2), sub_xmm)>;
4919
4920 //===---------------------------------------------------------------------===//
4921 // Move Packed Doubleword Int first element to Doubleword Int
4922 //
4923 let SchedRW = [WriteMove] in {
4924 def VMOVPQIto64rr : VRS2I<0x7E, MRMDestReg, (outs GR64:$dst), (ins VR128:$src),
4925                           "movq\t{$src, $dst|$dst, $src}",
4926                           [(set GR64:$dst, (vector_extract (v2i64 VR128:$src),
4927                                                            (iPTR 0)))],
4928                                                            IIC_SSE_MOVD_ToGP>,
4929                       VEX;
4930
4931 def MOVPQIto64rr : RS2I<0x7E, MRMDestReg, (outs GR64:$dst), (ins VR128:$src),
4932                         "mov{d|q}\t{$src, $dst|$dst, $src}",
4933                         [(set GR64:$dst, (vector_extract (v2i64 VR128:$src),
4934                                                          (iPTR 0)))],
4935                                                          IIC_SSE_MOVD_ToGP>;
4936 } //SchedRW
4937
4938 //===---------------------------------------------------------------------===//
4939 // Bitcast FR64 <-> GR64
4940 //
4941 let isCodeGenOnly = 1 in {
4942   let Predicates = [UseAVX] in
4943   def VMOV64toSDrm : VS2SI<0x7E, MRMSrcMem, (outs FR64:$dst), (ins i64mem:$src),
4944                           "movq\t{$src, $dst|$dst, $src}",
4945                           [(set FR64:$dst, (bitconvert (loadi64 addr:$src)))]>,
4946                           VEX, Sched<[WriteLoad]>;
4947   def VMOVSDto64rr : VRS2I<0x7E, MRMDestReg, (outs GR64:$dst), (ins FR64:$src),
4948                            "movq\t{$src, $dst|$dst, $src}",
4949                            [(set GR64:$dst, (bitconvert FR64:$src))],
4950                            IIC_SSE_MOVDQ>, VEX, Sched<[WriteMove]>;
4951   def VMOVSDto64mr : VRS2I<0x7E, MRMDestMem, (outs), (ins i64mem:$dst, FR64:$src),
4952                            "movq\t{$src, $dst|$dst, $src}",
4953                            [(store (i64 (bitconvert FR64:$src)), addr:$dst)],
4954                            IIC_SSE_MOVDQ>, VEX, Sched<[WriteStore]>;
4955
4956   def MOV64toSDrm : S2SI<0x7E, MRMSrcMem, (outs FR64:$dst), (ins i64mem:$src),
4957                          "movq\t{$src, $dst|$dst, $src}",
4958                          [(set FR64:$dst, (bitconvert (loadi64 addr:$src)))],
4959                          IIC_SSE_MOVDQ>, Sched<[WriteLoad]>;
4960   def MOVSDto64rr : RS2I<0x7E, MRMDestReg, (outs GR64:$dst), (ins FR64:$src),
4961                          "mov{d|q}\t{$src, $dst|$dst, $src}",
4962                          [(set GR64:$dst, (bitconvert FR64:$src))],
4963                          IIC_SSE_MOVD_ToGP>, Sched<[WriteMove]>;
4964   def MOVSDto64mr : RS2I<0x7E, MRMDestMem, (outs), (ins i64mem:$dst, FR64:$src),
4965                          "movq\t{$src, $dst|$dst, $src}",
4966                          [(store (i64 (bitconvert FR64:$src)), addr:$dst)],
4967                          IIC_SSE_MOVDQ>, Sched<[WriteStore]>;
4968 }
4969
4970 //===---------------------------------------------------------------------===//
4971 // Move Scalar Single to Double Int
4972 //
4973 let isCodeGenOnly = 1 in {
4974   def VMOVSS2DIrr  : VS2I<0x7E, MRMDestReg, (outs GR32:$dst), (ins FR32:$src),
4975                         "movd\t{$src, $dst|$dst, $src}",
4976                         [(set GR32:$dst, (bitconvert FR32:$src))],
4977                         IIC_SSE_MOVD_ToGP>, VEX, Sched<[WriteMove]>;
4978   def VMOVSS2DImr  : VS2I<0x7E, MRMDestMem, (outs), (ins i32mem:$dst, FR32:$src),
4979                         "movd\t{$src, $dst|$dst, $src}",
4980                         [(store (i32 (bitconvert FR32:$src)), addr:$dst)],
4981                         IIC_SSE_MOVDQ>, VEX, Sched<[WriteStore]>;
4982   def MOVSS2DIrr  : S2I<0x7E, MRMDestReg, (outs GR32:$dst), (ins FR32:$src),
4983                         "movd\t{$src, $dst|$dst, $src}",
4984                         [(set GR32:$dst, (bitconvert FR32:$src))],
4985                         IIC_SSE_MOVD_ToGP>, Sched<[WriteMove]>;
4986   def MOVSS2DImr  : S2I<0x7E, MRMDestMem, (outs), (ins i32mem:$dst, FR32:$src),
4987                         "movd\t{$src, $dst|$dst, $src}",
4988                         [(store (i32 (bitconvert FR32:$src)), addr:$dst)],
4989                         IIC_SSE_MOVDQ>, Sched<[WriteStore]>;
4990 }
4991
4992 //===---------------------------------------------------------------------===//
4993 // Patterns and instructions to describe movd/movq to XMM register zero-extends
4994 //
4995 let isCodeGenOnly = 1, SchedRW = [WriteMove] in {
4996 let AddedComplexity = 15 in {
4997 def VMOVZQI2PQIrr : VS2I<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR64:$src),
4998                        "movq\t{$src, $dst|$dst, $src}", // X86-64 only
4999                        [(set VR128:$dst, (v2i64 (X86vzmovl
5000                                       (v2i64 (scalar_to_vector GR64:$src)))))],
5001                                       IIC_SSE_MOVDQ>,
5002                                       VEX, VEX_W;
5003 def MOVZQI2PQIrr : RS2I<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR64:$src),
5004                        "mov{d|q}\t{$src, $dst|$dst, $src}", // X86-64 only
5005                        [(set VR128:$dst, (v2i64 (X86vzmovl
5006                                       (v2i64 (scalar_to_vector GR64:$src)))))],
5007                                       IIC_SSE_MOVDQ>;
5008 }
5009 } // isCodeGenOnly, SchedRW
5010
5011 let Predicates = [UseAVX] in {
5012   let AddedComplexity = 15 in
5013     def : Pat<(v4i32 (X86vzmovl (v4i32 (scalar_to_vector GR32:$src)))),
5014               (VMOVDI2PDIrr GR32:$src)>;
5015
5016   // AVX 128-bit movd/movq instruction write zeros in the high 128-bit part.
5017   let AddedComplexity = 20 in {
5018     def : Pat<(v4i32 (X86vzmovl (v4i32 (scalar_to_vector (loadi32 addr:$src))))),
5019               (VMOVDI2PDIrm addr:$src)>;
5020     def : Pat<(v4i32 (X86vzmovl (bc_v4i32 (loadv4f32 addr:$src)))),
5021               (VMOVDI2PDIrm addr:$src)>;
5022     def : Pat<(v4i32 (X86vzmovl (bc_v4i32 (loadv2i64 addr:$src)))),
5023               (VMOVDI2PDIrm addr:$src)>;
5024   }
5025   // Use regular 128-bit instructions to match 256-bit scalar_to_vec+zext.
5026   def : Pat<(v8i32 (X86vzmovl (insert_subvector undef,
5027                                (v4i32 (scalar_to_vector GR32:$src)),(iPTR 0)))),
5028             (SUBREG_TO_REG (i32 0), (VMOVDI2PDIrr GR32:$src), sub_xmm)>;
5029   def : Pat<(v4i64 (X86vzmovl (insert_subvector undef,
5030                                (v2i64 (scalar_to_vector GR64:$src)),(iPTR 0)))),
5031             (SUBREG_TO_REG (i64 0), (VMOVZQI2PQIrr GR64:$src), sub_xmm)>;
5032 }
5033
5034 let Predicates = [UseSSE2] in {
5035   let AddedComplexity = 15 in
5036     def : Pat<(v4i32 (X86vzmovl (v4i32 (scalar_to_vector GR32:$src)))),
5037               (MOVDI2PDIrr GR32:$src)>;
5038
5039   let AddedComplexity = 20 in {
5040     def : Pat<(v4i32 (X86vzmovl (v4i32 (scalar_to_vector (loadi32 addr:$src))))),
5041               (MOVDI2PDIrm addr:$src)>;
5042     def : Pat<(v4i32 (X86vzmovl (bc_v4i32 (loadv4f32 addr:$src)))),
5043               (MOVDI2PDIrm addr:$src)>;
5044     def : Pat<(v4i32 (X86vzmovl (bc_v4i32 (loadv2i64 addr:$src)))),
5045               (MOVDI2PDIrm addr:$src)>;
5046   }
5047 }
5048
5049 // These are the correct encodings of the instructions so that we know how to
5050 // read correct assembly, even though we continue to emit the wrong ones for
5051 // compatibility with Darwin's buggy assembler.
5052 def : InstAlias<"movq\t{$src, $dst|$dst, $src}",
5053                 (MOV64toPQIrr VR128:$dst, GR64:$src), 0>;
5054 def : InstAlias<"movq\t{$src, $dst|$dst, $src}",
5055                 (MOVPQIto64rr GR64:$dst, VR128:$src), 0>;
5056 // Allow "vmovd" but print "vmovq" since we don't need compatibility for AVX.
5057 def : InstAlias<"vmovd\t{$src, $dst|$dst, $src}",
5058                 (VMOV64toPQIrr VR128:$dst, GR64:$src), 0>;
5059 def : InstAlias<"vmovd\t{$src, $dst|$dst, $src}",
5060                 (VMOVPQIto64rr GR64:$dst, VR128:$src), 0>;
5061
5062 //===---------------------------------------------------------------------===//
5063 // SSE2 - Move Quadword
5064 //===---------------------------------------------------------------------===//
5065
5066 //===---------------------------------------------------------------------===//
5067 // Move Quadword Int to Packed Quadword Int
5068 //
5069
5070 let SchedRW = [WriteLoad] in {
5071 def VMOVQI2PQIrm : I<0x7E, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
5072                     "vmovq\t{$src, $dst|$dst, $src}",
5073                     [(set VR128:$dst,
5074                       (v2i64 (scalar_to_vector (loadi64 addr:$src))))]>, XS,
5075                     VEX, Requires<[UseAVX]>;
5076 def MOVQI2PQIrm : I<0x7E, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
5077                     "movq\t{$src, $dst|$dst, $src}",
5078                     [(set VR128:$dst,
5079                       (v2i64 (scalar_to_vector (loadi64 addr:$src))))],
5080                       IIC_SSE_MOVDQ>, XS,
5081                     Requires<[UseSSE2]>; // SSE2 instruction with XS Prefix
5082 } // SchedRW
5083
5084 //===---------------------------------------------------------------------===//
5085 // Move Packed Quadword Int to Quadword Int
5086 //
5087 let SchedRW = [WriteStore] in {
5088 def VMOVPQI2QImr : VS2I<0xD6, MRMDestMem, (outs), (ins i64mem:$dst, VR128:$src),
5089                       "movq\t{$src, $dst|$dst, $src}",
5090                       [(store (i64 (vector_extract (v2i64 VR128:$src),
5091                                     (iPTR 0))), addr:$dst)],
5092                                     IIC_SSE_MOVDQ>, VEX;
5093 def MOVPQI2QImr : S2I<0xD6, MRMDestMem, (outs), (ins i64mem:$dst, VR128:$src),
5094                       "movq\t{$src, $dst|$dst, $src}",
5095                       [(store (i64 (vector_extract (v2i64 VR128:$src),
5096                                     (iPTR 0))), addr:$dst)],
5097                                     IIC_SSE_MOVDQ>;
5098 } // SchedRW
5099
5100 // For disassembler only
5101 let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0,
5102     SchedRW = [WriteVecLogic] in {
5103 def VMOVPQI2QIrr : VS2I<0xD6, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
5104                      "movq\t{$src, $dst|$dst, $src}", [], IIC_SSE_MOVQ_RR>, VEX;
5105 def MOVPQI2QIrr : S2I<0xD6, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
5106                       "movq\t{$src, $dst|$dst, $src}", [], IIC_SSE_MOVQ_RR>;
5107 }
5108
5109 //===---------------------------------------------------------------------===//
5110 // Store / copy lower 64-bits of a XMM register.
5111 //
5112 let Predicates = [UseAVX] in
5113 def : Pat<(int_x86_sse2_storel_dq addr:$dst, VR128:$src),
5114           (VMOVPQI2QImr addr:$dst, VR128:$src)>;
5115 let Predicates = [UseSSE2] in
5116 def : Pat<(int_x86_sse2_storel_dq addr:$dst, VR128:$src),
5117           (MOVPQI2QImr addr:$dst, VR128:$src)>;
5118
5119 let isCodeGenOnly = 1, AddedComplexity = 20 in {
5120 def VMOVZQI2PQIrm : I<0x7E, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
5121                      "vmovq\t{$src, $dst|$dst, $src}",
5122                      [(set VR128:$dst,
5123                        (v2i64 (X86vzmovl (v2i64 (scalar_to_vector
5124                                                  (loadi64 addr:$src))))))],
5125                                                  IIC_SSE_MOVDQ>,
5126                      XS, VEX, Requires<[UseAVX]>, Sched<[WriteLoad]>;
5127
5128 def MOVZQI2PQIrm : I<0x7E, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
5129                      "movq\t{$src, $dst|$dst, $src}",
5130                      [(set VR128:$dst,
5131                        (v2i64 (X86vzmovl (v2i64 (scalar_to_vector
5132                                                  (loadi64 addr:$src))))))],
5133                                                  IIC_SSE_MOVDQ>,
5134                      XS, Requires<[UseSSE2]>, Sched<[WriteLoad]>;
5135 }
5136
5137 let Predicates = [UseAVX], AddedComplexity = 20 in {
5138   def : Pat<(v2i64 (X86vzmovl (bc_v2i64 (loadv4f32 addr:$src)))),
5139             (VMOVZQI2PQIrm addr:$src)>;
5140   def : Pat<(v2i64 (X86vzload addr:$src)),
5141             (VMOVZQI2PQIrm addr:$src)>;
5142 }
5143
5144 let Predicates = [UseSSE2], AddedComplexity = 20 in {
5145   def : Pat<(v2i64 (X86vzmovl (bc_v2i64 (loadv4f32 addr:$src)))),
5146             (MOVZQI2PQIrm addr:$src)>;
5147   def : Pat<(v2i64 (X86vzload addr:$src)), (MOVZQI2PQIrm addr:$src)>;
5148 }
5149
5150 let Predicates = [HasAVX] in {
5151 def : Pat<(v4i64 (alignedX86vzload addr:$src)),
5152           (SUBREG_TO_REG (i32 0), (VMOVAPSrm addr:$src), sub_xmm)>;
5153 def : Pat<(v4i64 (X86vzload addr:$src)),
5154           (SUBREG_TO_REG (i32 0), (VMOVUPSrm addr:$src), sub_xmm)>;
5155 }
5156
5157 //===---------------------------------------------------------------------===//
5158 // Moving from XMM to XMM and clear upper 64 bits. Note, there is a bug in
5159 // IA32 document. movq xmm1, xmm2 does clear the high bits.
5160 //
5161 let SchedRW = [WriteVecLogic] in {
5162 let AddedComplexity = 15 in
5163 def VMOVZPQILo2PQIrr : I<0x7E, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
5164                         "vmovq\t{$src, $dst|$dst, $src}",
5165                     [(set VR128:$dst, (v2i64 (X86vzmovl (v2i64 VR128:$src))))],
5166                     IIC_SSE_MOVQ_RR>,
5167                       XS, VEX, Requires<[UseAVX]>;
5168 let AddedComplexity = 15 in
5169 def MOVZPQILo2PQIrr : I<0x7E, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
5170                         "movq\t{$src, $dst|$dst, $src}",
5171                     [(set VR128:$dst, (v2i64 (X86vzmovl (v2i64 VR128:$src))))],
5172                     IIC_SSE_MOVQ_RR>,
5173                       XS, Requires<[UseSSE2]>;
5174 } // SchedRW
5175
5176 let isCodeGenOnly = 1, SchedRW = [WriteVecLogicLd] in {
5177 let AddedComplexity = 20 in
5178 def VMOVZPQILo2PQIrm : I<0x7E, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
5179                         "vmovq\t{$src, $dst|$dst, $src}",
5180                     [(set VR128:$dst, (v2i64 (X86vzmovl
5181                                              (loadv2i64 addr:$src))))],
5182                                              IIC_SSE_MOVDQ>,
5183                       XS, VEX, Requires<[UseAVX]>;
5184 let AddedComplexity = 20 in {
5185 def MOVZPQILo2PQIrm : I<0x7E, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
5186                         "movq\t{$src, $dst|$dst, $src}",
5187                     [(set VR128:$dst, (v2i64 (X86vzmovl
5188                                              (loadv2i64 addr:$src))))],
5189                                              IIC_SSE_MOVDQ>,
5190                       XS, Requires<[UseSSE2]>;
5191 }
5192 } // isCodeGenOnly, SchedRW
5193
5194 let AddedComplexity = 20 in {
5195   let Predicates = [UseAVX] in {
5196     def : Pat<(v2f64 (X86vzmovl (v2f64 VR128:$src))),
5197               (VMOVZPQILo2PQIrr VR128:$src)>;
5198   }
5199   let Predicates = [UseSSE2] in {
5200     def : Pat<(v2f64 (X86vzmovl (v2f64 VR128:$src))),
5201               (MOVZPQILo2PQIrr VR128:$src)>;
5202   }
5203 }
5204
5205 //===---------------------------------------------------------------------===//
5206 // SSE3 - Replicate Single FP - MOVSHDUP and MOVSLDUP
5207 //===---------------------------------------------------------------------===//
5208 multiclass sse3_replicate_sfp<bits<8> op, SDNode OpNode, string OpcodeStr,
5209                               ValueType vt, RegisterClass RC, PatFrag mem_frag,
5210                               X86MemOperand x86memop> {
5211 def rr : S3SI<op, MRMSrcReg, (outs RC:$dst), (ins RC:$src),
5212                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5213                       [(set RC:$dst, (vt (OpNode RC:$src)))],
5214                       IIC_SSE_MOV_LH>, Sched<[WriteFShuffle]>;
5215 def rm : S3SI<op, MRMSrcMem, (outs RC:$dst), (ins x86memop:$src),
5216                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5217                       [(set RC:$dst, (OpNode (mem_frag addr:$src)))],
5218                       IIC_SSE_MOV_LH>, Sched<[WriteLoad]>;
5219 }
5220
5221 let Predicates = [HasAVX] in {
5222   defm VMOVSHDUP  : sse3_replicate_sfp<0x16, X86Movshdup, "vmovshdup",
5223                                        v4f32, VR128, loadv4f32, f128mem>, VEX;
5224   defm VMOVSLDUP  : sse3_replicate_sfp<0x12, X86Movsldup, "vmovsldup",
5225                                        v4f32, VR128, loadv4f32, f128mem>, VEX;
5226   defm VMOVSHDUPY : sse3_replicate_sfp<0x16, X86Movshdup, "vmovshdup",
5227                                  v8f32, VR256, loadv8f32, f256mem>, VEX, VEX_L;
5228   defm VMOVSLDUPY : sse3_replicate_sfp<0x12, X86Movsldup, "vmovsldup",
5229                                  v8f32, VR256, loadv8f32, f256mem>, VEX, VEX_L;
5230 }
5231 defm MOVSHDUP : sse3_replicate_sfp<0x16, X86Movshdup, "movshdup", v4f32, VR128,
5232                                    memopv4f32, f128mem>;
5233 defm MOVSLDUP : sse3_replicate_sfp<0x12, X86Movsldup, "movsldup", v4f32, VR128,
5234                                    memopv4f32, f128mem>;
5235
5236 let Predicates = [HasAVX] in {
5237   def : Pat<(v4i32 (X86Movshdup VR128:$src)),
5238             (VMOVSHDUPrr VR128:$src)>;
5239   def : Pat<(v4i32 (X86Movshdup (bc_v4i32 (loadv2i64 addr:$src)))),
5240             (VMOVSHDUPrm addr:$src)>;
5241   def : Pat<(v4i32 (X86Movsldup VR128:$src)),
5242             (VMOVSLDUPrr VR128:$src)>;
5243   def : Pat<(v4i32 (X86Movsldup (bc_v4i32 (loadv2i64 addr:$src)))),
5244             (VMOVSLDUPrm addr:$src)>;
5245   def : Pat<(v8i32 (X86Movshdup VR256:$src)),
5246             (VMOVSHDUPYrr VR256:$src)>;
5247   def : Pat<(v8i32 (X86Movshdup (bc_v8i32 (loadv4i64 addr:$src)))),
5248             (VMOVSHDUPYrm addr:$src)>;
5249   def : Pat<(v8i32 (X86Movsldup VR256:$src)),
5250             (VMOVSLDUPYrr VR256:$src)>;
5251   def : Pat<(v8i32 (X86Movsldup (bc_v8i32 (loadv4i64 addr:$src)))),
5252             (VMOVSLDUPYrm addr:$src)>;
5253 }
5254
5255 let Predicates = [UseSSE3] in {
5256   def : Pat<(v4i32 (X86Movshdup VR128:$src)),
5257             (MOVSHDUPrr VR128:$src)>;
5258   def : Pat<(v4i32 (X86Movshdup (bc_v4i32 (memopv2i64 addr:$src)))),
5259             (MOVSHDUPrm addr:$src)>;
5260   def : Pat<(v4i32 (X86Movsldup VR128:$src)),
5261             (MOVSLDUPrr VR128:$src)>;
5262   def : Pat<(v4i32 (X86Movsldup (bc_v4i32 (memopv2i64 addr:$src)))),
5263             (MOVSLDUPrm addr:$src)>;
5264 }
5265
5266 //===---------------------------------------------------------------------===//
5267 // SSE3 - Replicate Double FP - MOVDDUP
5268 //===---------------------------------------------------------------------===//
5269
5270 multiclass sse3_replicate_dfp<string OpcodeStr> {
5271 let neverHasSideEffects = 1 in
5272 def rr  : S3DI<0x12, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
5273                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5274                     [], IIC_SSE_MOV_LH>, Sched<[WriteFShuffle]>;
5275 def rm  : S3DI<0x12, MRMSrcMem, (outs VR128:$dst), (ins f64mem:$src),
5276                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5277                     [(set VR128:$dst,
5278                       (v2f64 (X86Movddup
5279                               (scalar_to_vector (loadf64 addr:$src)))))],
5280                               IIC_SSE_MOV_LH>, Sched<[WriteLoad]>;
5281 }
5282
5283 // FIXME: Merge with above classe when there're patterns for the ymm version
5284 multiclass sse3_replicate_dfp_y<string OpcodeStr> {
5285 def rr  : S3DI<0x12, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
5286                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5287                     [(set VR256:$dst, (v4f64 (X86Movddup VR256:$src)))]>,
5288                     Sched<[WriteFShuffle]>;
5289 def rm  : S3DI<0x12, MRMSrcMem, (outs VR256:$dst), (ins f256mem:$src),
5290                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5291                     [(set VR256:$dst,
5292                       (v4f64 (X86Movddup
5293                               (scalar_to_vector (loadf64 addr:$src)))))]>,
5294                     Sched<[WriteLoad]>;
5295 }
5296
5297 let Predicates = [HasAVX] in {
5298   defm VMOVDDUP  : sse3_replicate_dfp<"vmovddup">, VEX;
5299   defm VMOVDDUPY : sse3_replicate_dfp_y<"vmovddup">, VEX, VEX_L;
5300 }
5301
5302 defm MOVDDUP : sse3_replicate_dfp<"movddup">;
5303
5304 let Predicates = [HasAVX] in {
5305   def : Pat<(X86Movddup (loadv2f64 addr:$src)),
5306             (VMOVDDUPrm addr:$src)>, Requires<[HasAVX]>;
5307   def : Pat<(X86Movddup (bc_v2f64 (loadv4f32 addr:$src))),
5308             (VMOVDDUPrm addr:$src)>, Requires<[HasAVX]>;
5309   def : Pat<(X86Movddup (bc_v2f64 (loadv2i64 addr:$src))),
5310             (VMOVDDUPrm addr:$src)>, Requires<[HasAVX]>;
5311   def : Pat<(X86Movddup (bc_v2f64
5312                              (v2i64 (scalar_to_vector (loadi64 addr:$src))))),
5313             (VMOVDDUPrm addr:$src)>, Requires<[HasAVX]>;
5314
5315   // 256-bit version
5316   def : Pat<(X86Movddup (loadv4f64 addr:$src)),
5317             (VMOVDDUPYrm addr:$src)>;
5318   def : Pat<(X86Movddup (loadv4i64 addr:$src)),
5319             (VMOVDDUPYrm addr:$src)>;
5320   def : Pat<(X86Movddup (v4i64 (scalar_to_vector (loadi64 addr:$src)))),
5321             (VMOVDDUPYrm addr:$src)>;
5322   def : Pat<(X86Movddup (v4i64 VR256:$src)),
5323             (VMOVDDUPYrr VR256:$src)>;
5324 }
5325
5326 let Predicates = [UseAVX, OptForSize] in {
5327   def : Pat<(v2f64 (X86VBroadcast (loadf64 addr:$src))),
5328   (VMOVDDUPrm addr:$src)>;
5329   def : Pat<(v2i64 (X86VBroadcast (loadi64 addr:$src))),
5330   (VMOVDDUPrm addr:$src)>;
5331 }
5332
5333 let Predicates = [UseSSE3] in {
5334   def : Pat<(X86Movddup (memopv2f64 addr:$src)),
5335             (MOVDDUPrm addr:$src)>;
5336   def : Pat<(X86Movddup (bc_v2f64 (memopv4f32 addr:$src))),
5337             (MOVDDUPrm addr:$src)>;
5338   def : Pat<(X86Movddup (bc_v2f64 (memopv2i64 addr:$src))),
5339             (MOVDDUPrm addr:$src)>;
5340   def : Pat<(X86Movddup (bc_v2f64
5341                              (v2i64 (scalar_to_vector (loadi64 addr:$src))))),
5342             (MOVDDUPrm addr:$src)>;
5343 }
5344
5345 //===---------------------------------------------------------------------===//
5346 // SSE3 - Move Unaligned Integer
5347 //===---------------------------------------------------------------------===//
5348
5349 let SchedRW = [WriteLoad] in {
5350 let Predicates = [HasAVX] in {
5351   def VLDDQUrm : S3DI<0xF0, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
5352                    "vlddqu\t{$src, $dst|$dst, $src}",
5353                    [(set VR128:$dst, (int_x86_sse3_ldu_dq addr:$src))]>, VEX;
5354   def VLDDQUYrm : S3DI<0xF0, MRMSrcMem, (outs VR256:$dst), (ins i256mem:$src),
5355                    "vlddqu\t{$src, $dst|$dst, $src}",
5356                    [(set VR256:$dst, (int_x86_avx_ldu_dq_256 addr:$src))]>,
5357                    VEX, VEX_L;
5358 }
5359 def LDDQUrm : S3DI<0xF0, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
5360                    "lddqu\t{$src, $dst|$dst, $src}",
5361                    [(set VR128:$dst, (int_x86_sse3_ldu_dq addr:$src))],
5362                    IIC_SSE_LDDQU>;
5363 }
5364
5365 //===---------------------------------------------------------------------===//
5366 // SSE3 - Arithmetic
5367 //===---------------------------------------------------------------------===//
5368
5369 multiclass sse3_addsub<Intrinsic Int, string OpcodeStr, RegisterClass RC,
5370                        X86MemOperand x86memop, OpndItins itins,
5371                        bit Is2Addr = 1> {
5372   def rr : I<0xD0, MRMSrcReg,
5373        (outs RC:$dst), (ins RC:$src1, RC:$src2),
5374        !if(Is2Addr,
5375            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5376            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5377        [(set RC:$dst, (Int RC:$src1, RC:$src2))], itins.rr>,
5378        Sched<[itins.Sched]>;
5379   def rm : I<0xD0, MRMSrcMem,
5380        (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
5381        !if(Is2Addr,
5382            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5383            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5384        [(set RC:$dst, (Int RC:$src1, (memop addr:$src2)))], itins.rr>,
5385        Sched<[itins.Sched.Folded, ReadAfterLd]>;
5386 }
5387
5388 let Predicates = [HasAVX] in {
5389   let ExeDomain = SSEPackedSingle in {
5390     defm VADDSUBPS : sse3_addsub<int_x86_sse3_addsub_ps, "vaddsubps", VR128,
5391                                  f128mem, SSE_ALU_F32P, 0>, XD, VEX_4V;
5392     defm VADDSUBPSY : sse3_addsub<int_x86_avx_addsub_ps_256, "vaddsubps", VR256,
5393                                f256mem, SSE_ALU_F32P, 0>, XD, VEX_4V, VEX_L;
5394   }
5395   let ExeDomain = SSEPackedDouble in {
5396     defm VADDSUBPD : sse3_addsub<int_x86_sse3_addsub_pd, "vaddsubpd", VR128,
5397                                  f128mem, SSE_ALU_F64P, 0>, PD, VEX_4V;
5398     defm VADDSUBPDY : sse3_addsub<int_x86_avx_addsub_pd_256, "vaddsubpd", VR256,
5399                            f256mem, SSE_ALU_F64P, 0>, PD, VEX_4V, VEX_L;
5400   }
5401 }
5402 let Constraints = "$src1 = $dst", Predicates = [UseSSE3] in {
5403   let ExeDomain = SSEPackedSingle in
5404   defm ADDSUBPS : sse3_addsub<int_x86_sse3_addsub_ps, "addsubps", VR128,
5405                               f128mem, SSE_ALU_F32P>, XD;
5406   let ExeDomain = SSEPackedDouble in
5407   defm ADDSUBPD : sse3_addsub<int_x86_sse3_addsub_pd, "addsubpd", VR128,
5408                               f128mem, SSE_ALU_F64P>, PD;
5409 }
5410
5411 // Patterns used to select 'addsub' instructions.
5412 let Predicates = [HasAVX] in {
5413   def : Pat<(v4f32 (X86Addsub (v4f32 VR128:$lhs), (v4f32 VR128:$rhs))),
5414             (VADDSUBPSrr VR128:$lhs, VR128:$rhs)>;
5415   def : Pat<(v4f32 (X86Addsub (v4f32 VR128:$lhs), (v4f32 (memop addr:$rhs)))),
5416             (VADDSUBPSrm VR128:$lhs, f128mem:$rhs)>;
5417   def : Pat<(v2f64 (X86Addsub (v2f64 VR128:$lhs), (v2f64 VR128:$rhs))),
5418             (VADDSUBPDrr VR128:$lhs, VR128:$rhs)>;
5419   def : Pat<(v2f64 (X86Addsub (v2f64 VR128:$lhs), (v2f64 (memop addr:$rhs)))),
5420             (VADDSUBPDrm VR128:$lhs, f128mem:$rhs)>;
5421
5422   def : Pat<(v8f32 (X86Addsub (v8f32 VR256:$lhs), (v8f32 VR256:$rhs))),
5423             (VADDSUBPSYrr VR256:$lhs, VR256:$rhs)>;
5424   def : Pat<(v8f32 (X86Addsub (v8f32 VR256:$lhs), (v8f32 (memop addr:$rhs)))),
5425             (VADDSUBPSYrm VR256:$lhs, f256mem:$rhs)>;
5426   def : Pat<(v4f64 (X86Addsub (v4f64 VR256:$lhs), (v4f64 VR256:$rhs))),
5427             (VADDSUBPDYrr VR256:$lhs, VR256:$rhs)>;
5428   def : Pat<(v4f64 (X86Addsub (v4f64 VR256:$lhs), (v4f64 (memop addr:$rhs)))),
5429             (VADDSUBPDYrm VR256:$lhs, f256mem:$rhs)>;
5430 }
5431
5432 let Predicates = [UseSSE3] in {
5433   def : Pat<(v4f32 (X86Addsub (v4f32 VR128:$lhs), (v4f32 VR128:$rhs))),
5434             (ADDSUBPSrr VR128:$lhs, VR128:$rhs)>;
5435   def : Pat<(v4f32 (X86Addsub (v4f32 VR128:$lhs), (v4f32 (memop addr:$rhs)))),
5436             (ADDSUBPSrm VR128:$lhs, f128mem:$rhs)>;
5437   def : Pat<(v2f64 (X86Addsub (v2f64 VR128:$lhs), (v2f64 VR128:$rhs))),
5438             (ADDSUBPDrr VR128:$lhs, VR128:$rhs)>;
5439   def : Pat<(v2f64 (X86Addsub (v2f64 VR128:$lhs), (v2f64 (memop addr:$rhs)))),
5440             (ADDSUBPDrm VR128:$lhs, f128mem:$rhs)>;
5441 }
5442
5443 //===---------------------------------------------------------------------===//
5444 // SSE3 Instructions
5445 //===---------------------------------------------------------------------===//
5446
5447 // Horizontal ops
5448 multiclass S3D_Int<bits<8> o, string OpcodeStr, ValueType vt, RegisterClass RC,
5449                    X86MemOperand x86memop, SDNode OpNode, bit Is2Addr = 1> {
5450   def rr : S3DI<o, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
5451        !if(Is2Addr,
5452          !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5453          !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5454       [(set RC:$dst, (vt (OpNode RC:$src1, RC:$src2)))], IIC_SSE_HADDSUB_RR>,
5455       Sched<[WriteFAdd]>;
5456
5457   def rm : S3DI<o, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
5458        !if(Is2Addr,
5459          !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5460          !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5461       [(set RC:$dst, (vt (OpNode RC:$src1, (memop addr:$src2))))],
5462         IIC_SSE_HADDSUB_RM>, Sched<[WriteFAddLd, ReadAfterLd]>;
5463 }
5464 multiclass S3_Int<bits<8> o, string OpcodeStr, ValueType vt, RegisterClass RC,
5465                   X86MemOperand x86memop, SDNode OpNode, bit Is2Addr = 1> {
5466   def rr : S3I<o, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
5467        !if(Is2Addr,
5468          !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5469          !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5470       [(set RC:$dst, (vt (OpNode RC:$src1, RC:$src2)))], IIC_SSE_HADDSUB_RR>,
5471       Sched<[WriteFAdd]>;
5472
5473   def rm : S3I<o, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
5474        !if(Is2Addr,
5475          !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5476          !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5477       [(set RC:$dst, (vt (OpNode RC:$src1, (memop addr:$src2))))],
5478         IIC_SSE_HADDSUB_RM>, Sched<[WriteFAddLd, ReadAfterLd]>;
5479 }
5480
5481 let Predicates = [HasAVX] in {
5482   let ExeDomain = SSEPackedSingle in {
5483     defm VHADDPS  : S3D_Int<0x7C, "vhaddps", v4f32, VR128, f128mem,
5484                             X86fhadd, 0>, VEX_4V;
5485     defm VHSUBPS  : S3D_Int<0x7D, "vhsubps", v4f32, VR128, f128mem,
5486                             X86fhsub, 0>, VEX_4V;
5487     defm VHADDPSY : S3D_Int<0x7C, "vhaddps", v8f32, VR256, f256mem,
5488                             X86fhadd, 0>, VEX_4V, VEX_L;
5489     defm VHSUBPSY : S3D_Int<0x7D, "vhsubps", v8f32, VR256, f256mem,
5490                             X86fhsub, 0>, VEX_4V, VEX_L;
5491   }
5492   let ExeDomain = SSEPackedDouble in {
5493     defm VHADDPD  : S3_Int <0x7C, "vhaddpd", v2f64, VR128, f128mem,
5494                             X86fhadd, 0>, VEX_4V;
5495     defm VHSUBPD  : S3_Int <0x7D, "vhsubpd", v2f64, VR128, f128mem,
5496                             X86fhsub, 0>, VEX_4V;
5497     defm VHADDPDY : S3_Int <0x7C, "vhaddpd", v4f64, VR256, f256mem,
5498                             X86fhadd, 0>, VEX_4V, VEX_L;
5499     defm VHSUBPDY : S3_Int <0x7D, "vhsubpd", v4f64, VR256, f256mem,
5500                             X86fhsub, 0>, VEX_4V, VEX_L;
5501   }
5502 }
5503
5504 let Constraints = "$src1 = $dst" in {
5505   let ExeDomain = SSEPackedSingle in {
5506     defm HADDPS : S3D_Int<0x7C, "haddps", v4f32, VR128, f128mem, X86fhadd>;
5507     defm HSUBPS : S3D_Int<0x7D, "hsubps", v4f32, VR128, f128mem, X86fhsub>;
5508   }
5509   let ExeDomain = SSEPackedDouble in {
5510     defm HADDPD : S3_Int<0x7C, "haddpd", v2f64, VR128, f128mem, X86fhadd>;
5511     defm HSUBPD : S3_Int<0x7D, "hsubpd", v2f64, VR128, f128mem, X86fhsub>;
5512   }
5513 }
5514
5515 //===---------------------------------------------------------------------===//
5516 // SSSE3 - Packed Absolute Instructions
5517 //===---------------------------------------------------------------------===//
5518
5519
5520 /// SS3I_unop_rm_int - Simple SSSE3 unary op whose type can be v*{i8,i16,i32}.
5521 multiclass SS3I_unop_rm_int<bits<8> opc, string OpcodeStr,
5522                             Intrinsic IntId128> {
5523   def rr128 : SS38I<opc, MRMSrcReg, (outs VR128:$dst),
5524                     (ins VR128:$src),
5525                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5526                     [(set VR128:$dst, (IntId128 VR128:$src))], IIC_SSE_PABS_RR>,
5527                     Sched<[WriteVecALU]>;
5528
5529   def rm128 : SS38I<opc, MRMSrcMem, (outs VR128:$dst),
5530                     (ins i128mem:$src),
5531                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5532                     [(set VR128:$dst,
5533                       (IntId128
5534                        (bitconvert (memopv2i64 addr:$src))))], IIC_SSE_PABS_RM>,
5535                     Sched<[WriteVecALULd]>;
5536 }
5537
5538 /// SS3I_unop_rm_int_y - Simple SSSE3 unary op whose type can be v*{i8,i16,i32}.
5539 multiclass SS3I_unop_rm_int_y<bits<8> opc, string OpcodeStr,
5540                               Intrinsic IntId256> {
5541   def rr256 : SS38I<opc, MRMSrcReg, (outs VR256:$dst),
5542                     (ins VR256:$src),
5543                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5544                     [(set VR256:$dst, (IntId256 VR256:$src))]>,
5545                     Sched<[WriteVecALU]>;
5546
5547   def rm256 : SS38I<opc, MRMSrcMem, (outs VR256:$dst),
5548                     (ins i256mem:$src),
5549                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5550                     [(set VR256:$dst,
5551                       (IntId256
5552                        (bitconvert (memopv4i64 addr:$src))))]>,
5553                     Sched<[WriteVecALULd]>;
5554 }
5555
5556 // Helper fragments to match sext vXi1 to vXiY.
5557 def v16i1sextv16i8 : PatLeaf<(v16i8 (X86pcmpgt (bc_v16i8 (v4i32 immAllZerosV)),
5558                                                VR128:$src))>;
5559 def v8i1sextv8i16  : PatLeaf<(v8i16 (X86vsrai VR128:$src, (i8 15)))>;
5560 def v4i1sextv4i32  : PatLeaf<(v4i32 (X86vsrai VR128:$src, (i8 31)))>;
5561 def v32i1sextv32i8 : PatLeaf<(v32i8 (X86pcmpgt (bc_v32i8 (v8i32 immAllZerosV)),
5562                                                VR256:$src))>;
5563 def v16i1sextv16i16: PatLeaf<(v16i16 (X86vsrai VR256:$src, (i8 15)))>;
5564 def v8i1sextv8i32  : PatLeaf<(v8i32 (X86vsrai VR256:$src, (i8 31)))>;
5565
5566 let Predicates = [HasAVX] in {
5567   defm VPABSB  : SS3I_unop_rm_int<0x1C, "vpabsb",
5568                                   int_x86_ssse3_pabs_b_128>, VEX;
5569   defm VPABSW  : SS3I_unop_rm_int<0x1D, "vpabsw",
5570                                   int_x86_ssse3_pabs_w_128>, VEX;
5571   defm VPABSD  : SS3I_unop_rm_int<0x1E, "vpabsd",
5572                                   int_x86_ssse3_pabs_d_128>, VEX;
5573
5574   def : Pat<(xor
5575             (bc_v2i64 (v16i1sextv16i8)),
5576             (bc_v2i64 (add (v16i8 VR128:$src), (v16i1sextv16i8)))),
5577             (VPABSBrr128 VR128:$src)>;
5578   def : Pat<(xor
5579             (bc_v2i64 (v8i1sextv8i16)),
5580             (bc_v2i64 (add (v8i16 VR128:$src), (v8i1sextv8i16)))),
5581             (VPABSWrr128 VR128:$src)>;
5582   def : Pat<(xor
5583             (bc_v2i64 (v4i1sextv4i32)),
5584             (bc_v2i64 (add (v4i32 VR128:$src), (v4i1sextv4i32)))),
5585             (VPABSDrr128 VR128:$src)>;
5586 }
5587
5588 let Predicates = [HasAVX2] in {
5589   defm VPABSB  : SS3I_unop_rm_int_y<0x1C, "vpabsb",
5590                                     int_x86_avx2_pabs_b>, VEX, VEX_L;
5591   defm VPABSW  : SS3I_unop_rm_int_y<0x1D, "vpabsw",
5592                                     int_x86_avx2_pabs_w>, VEX, VEX_L;
5593   defm VPABSD  : SS3I_unop_rm_int_y<0x1E, "vpabsd",
5594                                     int_x86_avx2_pabs_d>, VEX, VEX_L;
5595
5596   def : Pat<(xor
5597             (bc_v4i64 (v32i1sextv32i8)),
5598             (bc_v4i64 (add (v32i8 VR256:$src), (v32i1sextv32i8)))),
5599             (VPABSBrr256 VR256:$src)>;
5600   def : Pat<(xor
5601             (bc_v4i64 (v16i1sextv16i16)),
5602             (bc_v4i64 (add (v16i16 VR256:$src), (v16i1sextv16i16)))),
5603             (VPABSWrr256 VR256:$src)>;
5604   def : Pat<(xor
5605             (bc_v4i64 (v8i1sextv8i32)),
5606             (bc_v4i64 (add (v8i32 VR256:$src), (v8i1sextv8i32)))),
5607             (VPABSDrr256 VR256:$src)>;
5608 }
5609
5610 defm PABSB : SS3I_unop_rm_int<0x1C, "pabsb",
5611                               int_x86_ssse3_pabs_b_128>;
5612 defm PABSW : SS3I_unop_rm_int<0x1D, "pabsw",
5613                               int_x86_ssse3_pabs_w_128>;
5614 defm PABSD : SS3I_unop_rm_int<0x1E, "pabsd",
5615                               int_x86_ssse3_pabs_d_128>;
5616
5617 let Predicates = [HasSSSE3] in {
5618   def : Pat<(xor
5619             (bc_v2i64 (v16i1sextv16i8)),
5620             (bc_v2i64 (add (v16i8 VR128:$src), (v16i1sextv16i8)))),
5621             (PABSBrr128 VR128:$src)>;
5622   def : Pat<(xor
5623             (bc_v2i64 (v8i1sextv8i16)),
5624             (bc_v2i64 (add (v8i16 VR128:$src), (v8i1sextv8i16)))),
5625             (PABSWrr128 VR128:$src)>;
5626   def : Pat<(xor
5627             (bc_v2i64 (v4i1sextv4i32)),
5628             (bc_v2i64 (add (v4i32 VR128:$src), (v4i1sextv4i32)))),
5629             (PABSDrr128 VR128:$src)>;
5630 }
5631
5632 //===---------------------------------------------------------------------===//
5633 // SSSE3 - Packed Binary Operator Instructions
5634 //===---------------------------------------------------------------------===//
5635
5636 let Sched = WriteVecALU in {
5637 def SSE_PHADDSUBD : OpndItins<
5638   IIC_SSE_PHADDSUBD_RR, IIC_SSE_PHADDSUBD_RM
5639 >;
5640 def SSE_PHADDSUBSW : OpndItins<
5641   IIC_SSE_PHADDSUBSW_RR, IIC_SSE_PHADDSUBSW_RM
5642 >;
5643 def SSE_PHADDSUBW : OpndItins<
5644   IIC_SSE_PHADDSUBW_RR, IIC_SSE_PHADDSUBW_RM
5645 >;
5646 }
5647 let Sched = WriteShuffle in
5648 def SSE_PSHUFB : OpndItins<
5649   IIC_SSE_PSHUFB_RR, IIC_SSE_PSHUFB_RM
5650 >;
5651 let Sched = WriteVecALU in
5652 def SSE_PSIGN : OpndItins<
5653   IIC_SSE_PSIGN_RR, IIC_SSE_PSIGN_RM
5654 >;
5655 let Sched = WriteVecIMul in
5656 def SSE_PMULHRSW : OpndItins<
5657   IIC_SSE_PMULHRSW, IIC_SSE_PMULHRSW
5658 >;
5659
5660 /// SS3I_binop_rm - Simple SSSE3 bin op
5661 multiclass SS3I_binop_rm<bits<8> opc, string OpcodeStr, SDNode OpNode,
5662                          ValueType OpVT, RegisterClass RC, PatFrag memop_frag,
5663                          X86MemOperand x86memop, OpndItins itins,
5664                          bit Is2Addr = 1> {
5665   let isCommutable = 1 in
5666   def rr : SS38I<opc, MRMSrcReg, (outs RC:$dst),
5667        (ins RC:$src1, RC:$src2),
5668        !if(Is2Addr,
5669          !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5670          !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5671        [(set RC:$dst, (OpVT (OpNode RC:$src1, RC:$src2)))], itins.rr>,
5672        Sched<[itins.Sched]>;
5673   def rm : SS38I<opc, MRMSrcMem, (outs RC:$dst),
5674        (ins RC:$src1, x86memop:$src2),
5675        !if(Is2Addr,
5676          !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5677          !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5678        [(set RC:$dst,
5679          (OpVT (OpNode RC:$src1,
5680           (bitconvert (memop_frag addr:$src2)))))], itins.rm>,
5681        Sched<[itins.Sched.Folded, ReadAfterLd]>;
5682 }
5683
5684 /// SS3I_binop_rm_int - Simple SSSE3 bin op whose type can be v*{i8,i16,i32}.
5685 multiclass SS3I_binop_rm_int<bits<8> opc, string OpcodeStr,
5686                              Intrinsic IntId128, OpndItins itins,
5687                              bit Is2Addr = 1> {
5688   let isCommutable = 1 in
5689   def rr128 : SS38I<opc, MRMSrcReg, (outs VR128:$dst),
5690        (ins VR128:$src1, VR128:$src2),
5691        !if(Is2Addr,
5692          !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5693          !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5694        [(set VR128:$dst, (IntId128 VR128:$src1, VR128:$src2))]>,
5695        Sched<[itins.Sched]>;
5696   def rm128 : SS38I<opc, MRMSrcMem, (outs VR128:$dst),
5697        (ins VR128:$src1, i128mem:$src2),
5698        !if(Is2Addr,
5699          !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5700          !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5701        [(set VR128:$dst,
5702          (IntId128 VR128:$src1,
5703           (bitconvert (memopv2i64 addr:$src2))))]>,
5704        Sched<[itins.Sched.Folded, ReadAfterLd]>;
5705 }
5706
5707 multiclass SS3I_binop_rm_int_y<bits<8> opc, string OpcodeStr,
5708                                Intrinsic IntId256,
5709                                X86FoldableSchedWrite Sched> {
5710   let isCommutable = 1 in
5711   def rr256 : SS38I<opc, MRMSrcReg, (outs VR256:$dst),
5712        (ins VR256:$src1, VR256:$src2),
5713        !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5714        [(set VR256:$dst, (IntId256 VR256:$src1, VR256:$src2))]>,
5715        Sched<[Sched]>;
5716   def rm256 : SS38I<opc, MRMSrcMem, (outs VR256:$dst),
5717        (ins VR256:$src1, i256mem:$src2),
5718        !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5719        [(set VR256:$dst,
5720          (IntId256 VR256:$src1, (bitconvert (loadv4i64 addr:$src2))))]>,
5721        Sched<[Sched.Folded, ReadAfterLd]>;
5722 }
5723
5724 let ImmT = NoImm, Predicates = [HasAVX] in {
5725 let isCommutable = 0 in {
5726   defm VPHADDW    : SS3I_binop_rm<0x01, "vphaddw", X86hadd, v8i16, VR128,
5727                                   loadv2i64, i128mem,
5728                                   SSE_PHADDSUBW, 0>, VEX_4V;
5729   defm VPHADDD    : SS3I_binop_rm<0x02, "vphaddd", X86hadd, v4i32, VR128,
5730                                   loadv2i64, i128mem,
5731                                   SSE_PHADDSUBD, 0>, VEX_4V;
5732   defm VPHSUBW    : SS3I_binop_rm<0x05, "vphsubw", X86hsub, v8i16, VR128,
5733                                   loadv2i64, i128mem,
5734                                   SSE_PHADDSUBW, 0>, VEX_4V;
5735   defm VPHSUBD    : SS3I_binop_rm<0x06, "vphsubd", X86hsub, v4i32, VR128,
5736                                   loadv2i64, i128mem,
5737                                   SSE_PHADDSUBD, 0>, VEX_4V;
5738   defm VPSIGNB    : SS3I_binop_rm<0x08, "vpsignb", X86psign, v16i8, VR128,
5739                                   loadv2i64, i128mem,
5740                                   SSE_PSIGN, 0>, VEX_4V;
5741   defm VPSIGNW    : SS3I_binop_rm<0x09, "vpsignw", X86psign, v8i16, VR128,
5742                                   loadv2i64, i128mem,
5743                                   SSE_PSIGN, 0>, VEX_4V;
5744   defm VPSIGND    : SS3I_binop_rm<0x0A, "vpsignd", X86psign, v4i32, VR128,
5745                                   loadv2i64, i128mem,
5746                                   SSE_PSIGN, 0>, VEX_4V;
5747   defm VPSHUFB    : SS3I_binop_rm<0x00, "vpshufb", X86pshufb, v16i8, VR128,
5748                                   loadv2i64, i128mem,
5749                                   SSE_PSHUFB, 0>, VEX_4V;
5750   defm VPHADDSW   : SS3I_binop_rm_int<0x03, "vphaddsw",
5751                                       int_x86_ssse3_phadd_sw_128,
5752                                       SSE_PHADDSUBSW, 0>, VEX_4V;
5753   defm VPHSUBSW   : SS3I_binop_rm_int<0x07, "vphsubsw",
5754                                       int_x86_ssse3_phsub_sw_128,
5755                                       SSE_PHADDSUBSW, 0>, VEX_4V;
5756   defm VPMADDUBSW : SS3I_binop_rm_int<0x04, "vpmaddubsw",
5757                                       int_x86_ssse3_pmadd_ub_sw_128,
5758                                       SSE_PMADD, 0>, VEX_4V;
5759 }
5760 defm VPMULHRSW    : SS3I_binop_rm_int<0x0B, "vpmulhrsw",
5761                                       int_x86_ssse3_pmul_hr_sw_128,
5762                                       SSE_PMULHRSW, 0>, VEX_4V;
5763 }
5764
5765 let ImmT = NoImm, Predicates = [HasAVX2] in {
5766 let isCommutable = 0 in {
5767   defm VPHADDWY   : SS3I_binop_rm<0x01, "vphaddw", X86hadd, v16i16, VR256,
5768                                   loadv4i64, i256mem,
5769                                   SSE_PHADDSUBW, 0>, VEX_4V, VEX_L;
5770   defm VPHADDDY   : SS3I_binop_rm<0x02, "vphaddd", X86hadd, v8i32, VR256,
5771                                   loadv4i64, i256mem,
5772                                   SSE_PHADDSUBW, 0>, VEX_4V, VEX_L;
5773   defm VPHSUBWY   : SS3I_binop_rm<0x05, "vphsubw", X86hsub, v16i16, VR256,
5774                                   loadv4i64, i256mem,
5775                                   SSE_PHADDSUBW, 0>, VEX_4V, VEX_L;
5776   defm VPHSUBDY   : SS3I_binop_rm<0x06, "vphsubd", X86hsub, v8i32, VR256,
5777                                   loadv4i64, i256mem,
5778                                   SSE_PHADDSUBW, 0>, VEX_4V, VEX_L;
5779   defm VPSIGNBY   : SS3I_binop_rm<0x08, "vpsignb", X86psign, v32i8, VR256,
5780                                   loadv4i64, i256mem,
5781                                   SSE_PHADDSUBW, 0>, VEX_4V, VEX_L;
5782   defm VPSIGNWY   : SS3I_binop_rm<0x09, "vpsignw", X86psign, v16i16, VR256,
5783                                   loadv4i64, i256mem,
5784                                   SSE_PHADDSUBW, 0>, VEX_4V, VEX_L;
5785   defm VPSIGNDY   : SS3I_binop_rm<0x0A, "vpsignd", X86psign, v8i32, VR256,
5786                                   loadv4i64, i256mem,
5787                                   SSE_PHADDSUBW, 0>, VEX_4V, VEX_L;
5788   defm VPSHUFBY   : SS3I_binop_rm<0x00, "vpshufb", X86pshufb, v32i8, VR256,
5789                                   loadv4i64, i256mem,
5790                                   SSE_PSHUFB, 0>, VEX_4V, VEX_L;
5791   defm VPHADDSW   : SS3I_binop_rm_int_y<0x03, "vphaddsw",
5792                                         int_x86_avx2_phadd_sw,
5793                                         WriteVecALU>, VEX_4V, VEX_L;
5794   defm VPHSUBSW   : SS3I_binop_rm_int_y<0x07, "vphsubsw",
5795                                         int_x86_avx2_phsub_sw,
5796                                         WriteVecALU>, VEX_4V, VEX_L;
5797   defm VPMADDUBSW : SS3I_binop_rm_int_y<0x04, "vpmaddubsw",
5798                                        int_x86_avx2_pmadd_ub_sw,
5799                                         WriteVecIMul>, VEX_4V, VEX_L;
5800 }
5801 defm VPMULHRSW    : SS3I_binop_rm_int_y<0x0B, "vpmulhrsw",
5802                                         int_x86_avx2_pmul_hr_sw,
5803                                         WriteVecIMul>, VEX_4V, VEX_L;
5804 }
5805
5806 // None of these have i8 immediate fields.
5807 let ImmT = NoImm, Constraints = "$src1 = $dst" in {
5808 let isCommutable = 0 in {
5809   defm PHADDW    : SS3I_binop_rm<0x01, "phaddw", X86hadd, v8i16, VR128,
5810                                  memopv2i64, i128mem, SSE_PHADDSUBW>;
5811   defm PHADDD    : SS3I_binop_rm<0x02, "phaddd", X86hadd, v4i32, VR128,
5812                                  memopv2i64, i128mem, SSE_PHADDSUBD>;
5813   defm PHSUBW    : SS3I_binop_rm<0x05, "phsubw", X86hsub, v8i16, VR128,
5814                                  memopv2i64, i128mem, SSE_PHADDSUBW>;
5815   defm PHSUBD    : SS3I_binop_rm<0x06, "phsubd", X86hsub, v4i32, VR128,
5816                                  memopv2i64, i128mem, SSE_PHADDSUBD>;
5817   defm PSIGNB    : SS3I_binop_rm<0x08, "psignb", X86psign, v16i8, VR128,
5818                                  memopv2i64, i128mem, SSE_PSIGN>;
5819   defm PSIGNW    : SS3I_binop_rm<0x09, "psignw", X86psign, v8i16, VR128,
5820                                  memopv2i64, i128mem, SSE_PSIGN>;
5821   defm PSIGND    : SS3I_binop_rm<0x0A, "psignd", X86psign, v4i32, VR128,
5822                                  memopv2i64, i128mem, SSE_PSIGN>;
5823   defm PSHUFB    : SS3I_binop_rm<0x00, "pshufb", X86pshufb, v16i8, VR128,
5824                                  memopv2i64, i128mem, SSE_PSHUFB>;
5825   defm PHADDSW   : SS3I_binop_rm_int<0x03, "phaddsw",
5826                                      int_x86_ssse3_phadd_sw_128,
5827                                      SSE_PHADDSUBSW>;
5828   defm PHSUBSW   : SS3I_binop_rm_int<0x07, "phsubsw",
5829                                      int_x86_ssse3_phsub_sw_128,
5830                                      SSE_PHADDSUBSW>;
5831   defm PMADDUBSW : SS3I_binop_rm_int<0x04, "pmaddubsw",
5832                                      int_x86_ssse3_pmadd_ub_sw_128, SSE_PMADD>;
5833 }
5834 defm PMULHRSW    : SS3I_binop_rm_int<0x0B, "pmulhrsw",
5835                                      int_x86_ssse3_pmul_hr_sw_128,
5836                                      SSE_PMULHRSW>;
5837 }
5838
5839 //===---------------------------------------------------------------------===//
5840 // SSSE3 - Packed Align Instruction Patterns
5841 //===---------------------------------------------------------------------===//
5842
5843 multiclass ssse3_palignr<string asm, bit Is2Addr = 1> {
5844   let neverHasSideEffects = 1 in {
5845   def R128rr : SS3AI<0x0F, MRMSrcReg, (outs VR128:$dst),
5846       (ins VR128:$src1, VR128:$src2, i8imm:$src3),
5847       !if(Is2Addr,
5848         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5849         !strconcat(asm,
5850                   "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5851       [], IIC_SSE_PALIGNRR>, Sched<[WriteShuffle]>;
5852   let mayLoad = 1 in
5853   def R128rm : SS3AI<0x0F, MRMSrcMem, (outs VR128:$dst),
5854       (ins VR128:$src1, i128mem:$src2, i8imm:$src3),
5855       !if(Is2Addr,
5856         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5857         !strconcat(asm,
5858                   "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5859       [], IIC_SSE_PALIGNRM>, Sched<[WriteShuffleLd, ReadAfterLd]>;
5860   }
5861 }
5862
5863 multiclass ssse3_palignr_y<string asm, bit Is2Addr = 1> {
5864   let neverHasSideEffects = 1 in {
5865   def R256rr : SS3AI<0x0F, MRMSrcReg, (outs VR256:$dst),
5866       (ins VR256:$src1, VR256:$src2, i8imm:$src3),
5867       !strconcat(asm,
5868                  "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
5869       []>, Sched<[WriteShuffle]>;
5870   let mayLoad = 1 in
5871   def R256rm : SS3AI<0x0F, MRMSrcMem, (outs VR256:$dst),
5872       (ins VR256:$src1, i256mem:$src2, i8imm:$src3),
5873       !strconcat(asm,
5874                  "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
5875       []>, Sched<[WriteShuffleLd, ReadAfterLd]>;
5876   }
5877 }
5878
5879 let Predicates = [HasAVX] in
5880   defm VPALIGN : ssse3_palignr<"vpalignr", 0>, VEX_4V;
5881 let Predicates = [HasAVX2] in
5882   defm VPALIGN : ssse3_palignr_y<"vpalignr", 0>, VEX_4V, VEX_L;
5883 let Constraints = "$src1 = $dst", Predicates = [UseSSSE3] in
5884   defm PALIGN : ssse3_palignr<"palignr">;
5885
5886 let Predicates = [HasAVX2] in {
5887 def : Pat<(v8i32 (X86PAlignr VR256:$src1, VR256:$src2, (i8 imm:$imm))),
5888           (VPALIGNR256rr VR256:$src2, VR256:$src1, imm:$imm)>;
5889 def : Pat<(v8f32 (X86PAlignr VR256:$src1, VR256:$src2, (i8 imm:$imm))),
5890           (VPALIGNR256rr VR256:$src2, VR256:$src1, imm:$imm)>;
5891 def : Pat<(v16i16 (X86PAlignr VR256:$src1, VR256:$src2, (i8 imm:$imm))),
5892           (VPALIGNR256rr VR256:$src2, VR256:$src1, imm:$imm)>;
5893 def : Pat<(v32i8 (X86PAlignr VR256:$src1, VR256:$src2, (i8 imm:$imm))),
5894           (VPALIGNR256rr VR256:$src2, VR256:$src1, imm:$imm)>;
5895 }
5896
5897 let Predicates = [HasAVX] in {
5898 def : Pat<(v4i32 (X86PAlignr VR128:$src1, VR128:$src2, (i8 imm:$imm))),
5899           (VPALIGNR128rr VR128:$src2, VR128:$src1, imm:$imm)>;
5900 def : Pat<(v4f32 (X86PAlignr VR128:$src1, VR128:$src2, (i8 imm:$imm))),
5901           (VPALIGNR128rr VR128:$src2, VR128:$src1, imm:$imm)>;
5902 def : Pat<(v8i16 (X86PAlignr VR128:$src1, VR128:$src2, (i8 imm:$imm))),
5903           (VPALIGNR128rr VR128:$src2, VR128:$src1, imm:$imm)>;
5904 def : Pat<(v16i8 (X86PAlignr VR128:$src1, VR128:$src2, (i8 imm:$imm))),
5905           (VPALIGNR128rr VR128:$src2, VR128:$src1, imm:$imm)>;
5906 }
5907
5908 let Predicates = [UseSSSE3] in {
5909 def : Pat<(v4i32 (X86PAlignr VR128:$src1, VR128:$src2, (i8 imm:$imm))),
5910           (PALIGNR128rr VR128:$src2, VR128:$src1, imm:$imm)>;
5911 def : Pat<(v4f32 (X86PAlignr VR128:$src1, VR128:$src2, (i8 imm:$imm))),
5912           (PALIGNR128rr VR128:$src2, VR128:$src1, imm:$imm)>;
5913 def : Pat<(v8i16 (X86PAlignr VR128:$src1, VR128:$src2, (i8 imm:$imm))),
5914           (PALIGNR128rr VR128:$src2, VR128:$src1, imm:$imm)>;
5915 def : Pat<(v16i8 (X86PAlignr VR128:$src1, VR128:$src2, (i8 imm:$imm))),
5916           (PALIGNR128rr VR128:$src2, VR128:$src1, imm:$imm)>;
5917 }
5918
5919 //===---------------------------------------------------------------------===//
5920 // SSSE3 - Thread synchronization
5921 //===---------------------------------------------------------------------===//
5922
5923 let SchedRW = [WriteSystem] in {
5924 let usesCustomInserter = 1 in {
5925 def MONITOR : PseudoI<(outs), (ins i32mem:$src1, GR32:$src2, GR32:$src3),
5926                 [(int_x86_sse3_monitor addr:$src1, GR32:$src2, GR32:$src3)]>,
5927                 Requires<[HasSSE3]>;
5928 }
5929
5930 let Uses = [EAX, ECX, EDX] in
5931 def MONITORrrr : I<0x01, MRM_C8, (outs), (ins), "monitor", [], IIC_SSE_MONITOR>,
5932                  TB, Requires<[HasSSE3]>;
5933 let Uses = [ECX, EAX] in
5934 def MWAITrr   : I<0x01, MRM_C9, (outs), (ins), "mwait",
5935                 [(int_x86_sse3_mwait ECX, EAX)], IIC_SSE_MWAIT>,
5936                 TB, Requires<[HasSSE3]>;
5937 } // SchedRW
5938
5939 def : InstAlias<"mwait\t{%eax, %ecx|ecx, eax}", (MWAITrr)>, Requires<[Not64BitMode]>;
5940 def : InstAlias<"mwait\t{%rax, %rcx|rcx, rax}", (MWAITrr)>, Requires<[In64BitMode]>;
5941
5942 def : InstAlias<"monitor\t{%eax, %ecx, %edx|edx, ecx, eax}", (MONITORrrr)>,
5943       Requires<[Not64BitMode]>;
5944 def : InstAlias<"monitor\t{%rax, %rcx, %rdx|rdx, rcx, rax}", (MONITORrrr)>,
5945       Requires<[In64BitMode]>;
5946
5947 //===----------------------------------------------------------------------===//
5948 // SSE4.1 - Packed Move with Sign/Zero Extend
5949 //===----------------------------------------------------------------------===//
5950
5951 multiclass SS41I_binop_rm_int8<bits<8> opc, string OpcodeStr, Intrinsic IntId,
5952                                OpndItins itins = DEFAULT_ITINS> {
5953   def rr : SS48I<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
5954                  !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5955                  [(set VR128:$dst, (IntId VR128:$src))], itins.rr>,
5956                  Sched<[itins.Sched]>;
5957
5958   def rm : SS48I<opc, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
5959                  !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5960        [(set VR128:$dst,
5961          (IntId (bitconvert (v2i64 (scalar_to_vector (loadi64 addr:$src))))))],
5962          itins.rm>, Sched<[itins.Sched.Folded]>;
5963 }
5964
5965 multiclass SS41I_binop_rm_int16_y<bits<8> opc, string OpcodeStr,
5966                                  Intrinsic IntId, X86FoldableSchedWrite Sched> {
5967   def Yrr : SS48I<opc, MRMSrcReg, (outs VR256:$dst), (ins VR128:$src),
5968                   !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5969                   [(set VR256:$dst, (IntId VR128:$src))]>, Sched<[Sched]>;
5970
5971   def Yrm : SS48I<opc, MRMSrcMem, (outs VR256:$dst), (ins i128mem:$src),
5972                   !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5973                   [(set VR256:$dst, (IntId (load addr:$src)))]>,
5974                   Sched<[Sched.Folded]>;
5975 }
5976
5977 let Predicates = [HasAVX] in {
5978 defm VPMOVSXBW : SS41I_binop_rm_int8<0x20, "vpmovsxbw",
5979                                      int_x86_sse41_pmovsxbw,
5980                                      DEFAULT_ITINS_SHUFFLESCHED>, VEX;
5981 defm VPMOVSXWD : SS41I_binop_rm_int8<0x23, "vpmovsxwd",
5982                                      int_x86_sse41_pmovsxwd,
5983                                      DEFAULT_ITINS_SHUFFLESCHED>, VEX;
5984 defm VPMOVSXDQ : SS41I_binop_rm_int8<0x25, "vpmovsxdq",
5985                                      int_x86_sse41_pmovsxdq,
5986                                      DEFAULT_ITINS_SHUFFLESCHED>, VEX;
5987 defm VPMOVZXBW : SS41I_binop_rm_int8<0x30, "vpmovzxbw",
5988                                      int_x86_sse41_pmovzxbw,
5989                                      DEFAULT_ITINS_SHUFFLESCHED>, VEX;
5990 defm VPMOVZXWD : SS41I_binop_rm_int8<0x33, "vpmovzxwd",
5991                                      int_x86_sse41_pmovzxwd,
5992                                      DEFAULT_ITINS_SHUFFLESCHED>, VEX;
5993 defm VPMOVZXDQ : SS41I_binop_rm_int8<0x35, "vpmovzxdq",
5994                                      int_x86_sse41_pmovzxdq,
5995                                      DEFAULT_ITINS_SHUFFLESCHED>, VEX;
5996 }
5997
5998 let Predicates = [HasAVX2] in {
5999 defm VPMOVSXBW : SS41I_binop_rm_int16_y<0x20, "vpmovsxbw",
6000                                         int_x86_avx2_pmovsxbw,
6001                                         WriteShuffle>, VEX, VEX_L;
6002 defm VPMOVSXWD : SS41I_binop_rm_int16_y<0x23, "vpmovsxwd",
6003                                         int_x86_avx2_pmovsxwd,
6004                                         WriteShuffle>, VEX, VEX_L;
6005 defm VPMOVSXDQ : SS41I_binop_rm_int16_y<0x25, "vpmovsxdq",
6006                                         int_x86_avx2_pmovsxdq,
6007                                         WriteShuffle>, VEX, VEX_L;
6008 defm VPMOVZXBW : SS41I_binop_rm_int16_y<0x30, "vpmovzxbw",
6009                                         int_x86_avx2_pmovzxbw,
6010                                         WriteShuffle>, VEX, VEX_L;
6011 defm VPMOVZXWD : SS41I_binop_rm_int16_y<0x33, "vpmovzxwd",
6012                                         int_x86_avx2_pmovzxwd,
6013                                         WriteShuffle>, VEX, VEX_L;
6014 defm VPMOVZXDQ : SS41I_binop_rm_int16_y<0x35, "vpmovzxdq",
6015                                         int_x86_avx2_pmovzxdq,
6016                                         WriteShuffle>, VEX, VEX_L;
6017 }
6018
6019 defm PMOVSXBW   : SS41I_binop_rm_int8<0x20, "pmovsxbw", int_x86_sse41_pmovsxbw,
6020                                       SSE_INTALU_ITINS_SHUFF_P>;
6021 defm PMOVSXWD   : SS41I_binop_rm_int8<0x23, "pmovsxwd", int_x86_sse41_pmovsxwd,
6022                                       SSE_INTALU_ITINS_SHUFF_P>;
6023 defm PMOVSXDQ   : SS41I_binop_rm_int8<0x25, "pmovsxdq", int_x86_sse41_pmovsxdq,
6024                                       SSE_INTALU_ITINS_SHUFF_P>;
6025 defm PMOVZXBW   : SS41I_binop_rm_int8<0x30, "pmovzxbw", int_x86_sse41_pmovzxbw,
6026                                       SSE_INTALU_ITINS_SHUFF_P>;
6027 defm PMOVZXWD   : SS41I_binop_rm_int8<0x33, "pmovzxwd", int_x86_sse41_pmovzxwd,
6028                                       SSE_INTALU_ITINS_SHUFF_P>;
6029 defm PMOVZXDQ   : SS41I_binop_rm_int8<0x35, "pmovzxdq", int_x86_sse41_pmovzxdq,
6030                                       SSE_INTALU_ITINS_SHUFF_P>;
6031
6032 let Predicates = [HasAVX] in {
6033   // Common patterns involving scalar load.
6034   def : Pat<(int_x86_sse41_pmovsxbw (vzmovl_v2i64 addr:$src)),
6035             (VPMOVSXBWrm addr:$src)>;
6036   def : Pat<(int_x86_sse41_pmovsxbw (vzload_v2i64 addr:$src)),
6037             (VPMOVSXBWrm addr:$src)>;
6038   def : Pat<(int_x86_sse41_pmovsxbw (bc_v16i8 (loadv2i64 addr:$src))),
6039             (VPMOVSXBWrm addr:$src)>;
6040
6041   def : Pat<(int_x86_sse41_pmovsxwd (vzmovl_v2i64 addr:$src)),
6042             (VPMOVSXWDrm addr:$src)>;
6043   def : Pat<(int_x86_sse41_pmovsxwd (vzload_v2i64 addr:$src)),
6044             (VPMOVSXWDrm addr:$src)>;
6045   def : Pat<(int_x86_sse41_pmovsxwd (bc_v8i16 (loadv2i64 addr:$src))),
6046             (VPMOVSXWDrm addr:$src)>;
6047
6048   def : Pat<(int_x86_sse41_pmovsxdq (vzmovl_v2i64 addr:$src)),
6049             (VPMOVSXDQrm addr:$src)>;
6050   def : Pat<(int_x86_sse41_pmovsxdq (vzload_v2i64 addr:$src)),
6051             (VPMOVSXDQrm addr:$src)>;
6052   def : Pat<(int_x86_sse41_pmovsxdq (bc_v4i32 (loadv2i64 addr:$src))),
6053             (VPMOVSXDQrm addr:$src)>;
6054
6055   def : Pat<(int_x86_sse41_pmovzxbw (vzmovl_v2i64 addr:$src)),
6056             (VPMOVZXBWrm addr:$src)>;
6057   def : Pat<(int_x86_sse41_pmovzxbw (vzload_v2i64 addr:$src)),
6058             (VPMOVZXBWrm addr:$src)>;
6059   def : Pat<(int_x86_sse41_pmovzxbw (bc_v16i8 (loadv2i64 addr:$src))),
6060             (VPMOVZXBWrm addr:$src)>;
6061
6062   def : Pat<(int_x86_sse41_pmovzxwd (vzmovl_v2i64 addr:$src)),
6063             (VPMOVZXWDrm addr:$src)>;
6064   def : Pat<(int_x86_sse41_pmovzxwd (vzload_v2i64 addr:$src)),
6065             (VPMOVZXWDrm addr:$src)>;
6066   def : Pat<(int_x86_sse41_pmovzxwd (bc_v8i16 (loadv2i64 addr:$src))),
6067             (VPMOVZXWDrm addr:$src)>;
6068
6069   def : Pat<(int_x86_sse41_pmovzxdq (vzmovl_v2i64 addr:$src)),
6070             (VPMOVZXDQrm addr:$src)>;
6071   def : Pat<(int_x86_sse41_pmovzxdq (vzload_v2i64 addr:$src)),
6072             (VPMOVZXDQrm addr:$src)>;
6073   def : Pat<(int_x86_sse41_pmovzxdq (bc_v4i32 (loadv2i64 addr:$src))),
6074             (VPMOVZXDQrm addr:$src)>;
6075 }
6076
6077 let Predicates = [UseSSE41] in {
6078   // Common patterns involving scalar load.
6079   def : Pat<(int_x86_sse41_pmovsxbw (vzmovl_v2i64 addr:$src)),
6080             (PMOVSXBWrm addr:$src)>;
6081   def : Pat<(int_x86_sse41_pmovsxbw (vzload_v2i64 addr:$src)),
6082             (PMOVSXBWrm addr:$src)>;
6083   def : Pat<(int_x86_sse41_pmovsxbw (bc_v16i8 (loadv2i64 addr:$src))),
6084             (PMOVSXBWrm addr:$src)>;
6085
6086   def : Pat<(int_x86_sse41_pmovsxwd (vzmovl_v2i64 addr:$src)),
6087             (PMOVSXWDrm addr:$src)>;
6088   def : Pat<(int_x86_sse41_pmovsxwd (vzload_v2i64 addr:$src)),
6089             (PMOVSXWDrm addr:$src)>;
6090   def : Pat<(int_x86_sse41_pmovsxwd (bc_v8i16 (loadv2i64 addr:$src))),
6091             (PMOVSXWDrm addr:$src)>;
6092
6093   def : Pat<(int_x86_sse41_pmovsxdq (vzmovl_v2i64 addr:$src)),
6094             (PMOVSXDQrm addr:$src)>;
6095   def : Pat<(int_x86_sse41_pmovsxdq (vzload_v2i64 addr:$src)),
6096             (PMOVSXDQrm addr:$src)>;
6097   def : Pat<(int_x86_sse41_pmovsxdq (bc_v4i32 (loadv2i64 addr:$src))),
6098             (PMOVSXDQrm addr:$src)>;
6099
6100   def : Pat<(int_x86_sse41_pmovzxbw (vzmovl_v2i64 addr:$src)),
6101             (PMOVZXBWrm addr:$src)>;
6102   def : Pat<(int_x86_sse41_pmovzxbw (vzload_v2i64 addr:$src)),
6103             (PMOVZXBWrm addr:$src)>;
6104   def : Pat<(int_x86_sse41_pmovzxbw (bc_v16i8 (loadv2i64 addr:$src))),
6105             (PMOVZXBWrm addr:$src)>;
6106
6107   def : Pat<(int_x86_sse41_pmovzxwd (vzmovl_v2i64 addr:$src)),
6108             (PMOVZXWDrm addr:$src)>;
6109   def : Pat<(int_x86_sse41_pmovzxwd (vzload_v2i64 addr:$src)),
6110             (PMOVZXWDrm addr:$src)>;
6111   def : Pat<(int_x86_sse41_pmovzxwd (bc_v8i16 (loadv2i64 addr:$src))),
6112             (PMOVZXWDrm addr:$src)>;
6113
6114   def : Pat<(int_x86_sse41_pmovzxdq (vzmovl_v2i64 addr:$src)),
6115             (PMOVZXDQrm addr:$src)>;
6116   def : Pat<(int_x86_sse41_pmovzxdq (vzload_v2i64 addr:$src)),
6117             (PMOVZXDQrm addr:$src)>;
6118   def : Pat<(int_x86_sse41_pmovzxdq (bc_v4i32 (loadv2i64 addr:$src))),
6119             (PMOVZXDQrm addr:$src)>;
6120 }
6121
6122 multiclass SS41I_binop_rm_int4<bits<8> opc, string OpcodeStr, Intrinsic IntId,
6123                                OpndItins itins = DEFAULT_ITINS> {
6124   def rr : SS48I<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
6125                  !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
6126                  [(set VR128:$dst, (IntId VR128:$src))], itins.rr>,
6127                  Sched<[itins.Sched]>;
6128
6129   def rm : SS48I<opc, MRMSrcMem, (outs VR128:$dst), (ins i32mem:$src),
6130                  !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
6131        [(set VR128:$dst,
6132          (IntId (bitconvert (v4i32 (scalar_to_vector (loadi32 addr:$src))))))],
6133          itins.rm>, Sched<[itins.Sched.Folded]>;
6134 }
6135
6136 multiclass SS41I_binop_rm_int8_y<bits<8> opc, string OpcodeStr,
6137                                  Intrinsic IntId, X86FoldableSchedWrite Sched> {
6138   def Yrr : SS48I<opc, MRMSrcReg, (outs VR256:$dst), (ins VR128:$src),
6139                   !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
6140                   [(set VR256:$dst, (IntId VR128:$src))]>, Sched<[Sched]>;
6141
6142   def Yrm : SS48I<opc, MRMSrcMem, (outs VR256:$dst), (ins i32mem:$src),
6143                   !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
6144        [(set VR256:$dst,
6145          (IntId (bitconvert (v2i64 (scalar_to_vector (loadi64 addr:$src))))))]>,
6146          Sched<[Sched.Folded]>;
6147 }
6148
6149 let Predicates = [HasAVX] in {
6150 defm VPMOVSXBD : SS41I_binop_rm_int4<0x21, "vpmovsxbd", int_x86_sse41_pmovsxbd,
6151                                      DEFAULT_ITINS_SHUFFLESCHED>, VEX;
6152 defm VPMOVSXWQ : SS41I_binop_rm_int4<0x24, "vpmovsxwq", int_x86_sse41_pmovsxwq,
6153                                      DEFAULT_ITINS_SHUFFLESCHED>, VEX;
6154 defm VPMOVZXBD : SS41I_binop_rm_int4<0x31, "vpmovzxbd", int_x86_sse41_pmovzxbd,
6155                                      DEFAULT_ITINS_SHUFFLESCHED>, VEX;
6156 defm VPMOVZXWQ : SS41I_binop_rm_int4<0x34, "vpmovzxwq", int_x86_sse41_pmovzxwq,
6157                                      DEFAULT_ITINS_SHUFFLESCHED>, VEX;
6158 }
6159
6160 let Predicates = [HasAVX2] in {
6161 defm VPMOVSXBD : SS41I_binop_rm_int8_y<0x21, "vpmovsxbd",
6162                                        int_x86_avx2_pmovsxbd, WriteShuffle>,
6163                                        VEX, VEX_L;
6164 defm VPMOVSXWQ : SS41I_binop_rm_int8_y<0x24, "vpmovsxwq",
6165                                        int_x86_avx2_pmovsxwq, WriteShuffle>,
6166                                        VEX, VEX_L;
6167 defm VPMOVZXBD : SS41I_binop_rm_int8_y<0x31, "vpmovzxbd",
6168                                        int_x86_avx2_pmovzxbd, WriteShuffle>,
6169                                        VEX, VEX_L;
6170 defm VPMOVZXWQ : SS41I_binop_rm_int8_y<0x34, "vpmovzxwq",
6171                                        int_x86_avx2_pmovzxwq, WriteShuffle>,
6172                                        VEX, VEX_L;
6173 }
6174
6175 defm PMOVSXBD   : SS41I_binop_rm_int4<0x21, "pmovsxbd", int_x86_sse41_pmovsxbd,
6176                                       SSE_INTALU_ITINS_SHUFF_P>;
6177 defm PMOVSXWQ   : SS41I_binop_rm_int4<0x24, "pmovsxwq", int_x86_sse41_pmovsxwq,
6178                                       SSE_INTALU_ITINS_SHUFF_P>;
6179 defm PMOVZXBD   : SS41I_binop_rm_int4<0x31, "pmovzxbd", int_x86_sse41_pmovzxbd,
6180                                       SSE_INTALU_ITINS_SHUFF_P>;
6181 defm PMOVZXWQ   : SS41I_binop_rm_int4<0x34, "pmovzxwq", int_x86_sse41_pmovzxwq,
6182                                       SSE_INTALU_ITINS_SHUFF_P>;
6183
6184 let Predicates = [HasAVX] in {
6185   // Common patterns involving scalar load
6186   def : Pat<(int_x86_sse41_pmovsxbd (vzmovl_v4i32 addr:$src)),
6187             (VPMOVSXBDrm addr:$src)>;
6188   def : Pat<(int_x86_sse41_pmovsxwq (vzmovl_v4i32 addr:$src)),
6189             (VPMOVSXWQrm addr:$src)>;
6190
6191   def : Pat<(int_x86_sse41_pmovzxbd (vzmovl_v4i32 addr:$src)),
6192             (VPMOVZXBDrm addr:$src)>;
6193   def : Pat<(int_x86_sse41_pmovzxwq (vzmovl_v4i32 addr:$src)),
6194             (VPMOVZXWQrm addr:$src)>;
6195 }
6196
6197 let Predicates = [UseSSE41] in {
6198   // Common patterns involving scalar load
6199   def : Pat<(int_x86_sse41_pmovsxbd (vzmovl_v4i32 addr:$src)),
6200             (PMOVSXBDrm addr:$src)>;
6201   def : Pat<(int_x86_sse41_pmovsxwq (vzmovl_v4i32 addr:$src)),
6202             (PMOVSXWQrm addr:$src)>;
6203
6204   def : Pat<(int_x86_sse41_pmovzxbd (vzmovl_v4i32 addr:$src)),
6205             (PMOVZXBDrm addr:$src)>;
6206   def : Pat<(int_x86_sse41_pmovzxwq (vzmovl_v4i32 addr:$src)),
6207             (PMOVZXWQrm addr:$src)>;
6208 }
6209
6210 multiclass SS41I_binop_rm_int2<bits<8> opc, string OpcodeStr, Intrinsic IntId,
6211                                X86FoldableSchedWrite Sched> {
6212   def rr : SS48I<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
6213                  !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
6214                  [(set VR128:$dst, (IntId VR128:$src))]>, Sched<[Sched]>;
6215
6216   // Expecting a i16 load any extended to i32 value.
6217   def rm : SS48I<opc, MRMSrcMem, (outs VR128:$dst), (ins i16mem:$src),
6218                  !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
6219                  [(set VR128:$dst, (IntId (bitconvert
6220                      (v4i32 (scalar_to_vector (loadi16_anyext addr:$src))))))]>,
6221                  Sched<[Sched.Folded]>;
6222 }
6223
6224 multiclass SS41I_binop_rm_int4_y<bits<8> opc, string OpcodeStr,
6225                                  Intrinsic IntId, X86FoldableSchedWrite Sched> {
6226   def Yrr : SS48I<opc, MRMSrcReg, (outs VR256:$dst), (ins VR128:$src),
6227                  !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
6228                  [(set VR256:$dst, (IntId VR128:$src))]>, Sched<[Sched]>;
6229
6230   // Expecting a i16 load any extended to i32 value.
6231   def Yrm : SS48I<opc, MRMSrcMem, (outs VR256:$dst), (ins i16mem:$src),
6232                   !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
6233                   [(set VR256:$dst, (IntId (bitconvert
6234                       (v4i32 (scalar_to_vector (loadi32 addr:$src))))))]>,
6235                  Sched<[Sched.Folded]>;
6236 }
6237
6238 let Predicates = [HasAVX] in {
6239 defm VPMOVSXBQ : SS41I_binop_rm_int2<0x22, "vpmovsxbq", int_x86_sse41_pmovsxbq,
6240                                      WriteShuffle>, VEX;
6241 defm VPMOVZXBQ : SS41I_binop_rm_int2<0x32, "vpmovzxbq", int_x86_sse41_pmovzxbq,
6242                                      WriteShuffle>, VEX;
6243 }
6244 let Predicates = [HasAVX2] in {
6245 defm VPMOVSXBQ : SS41I_binop_rm_int4_y<0x22, "vpmovsxbq", int_x86_avx2_pmovsxbq,
6246                                        WriteShuffle>, VEX, VEX_L;
6247 defm VPMOVZXBQ : SS41I_binop_rm_int4_y<0x32, "vpmovzxbq", int_x86_avx2_pmovzxbq,
6248                                        WriteShuffle>, VEX, VEX_L;
6249 }
6250 defm PMOVSXBQ   : SS41I_binop_rm_int2<0x22, "pmovsxbq", int_x86_sse41_pmovsxbq,
6251                                       WriteShuffle>;
6252 defm PMOVZXBQ   : SS41I_binop_rm_int2<0x32, "pmovzxbq", int_x86_sse41_pmovzxbq,
6253                                       WriteShuffle>;
6254
6255 let Predicates = [HasAVX2] in {
6256   def : Pat<(v16i16 (X86vsext (v16i8 VR128:$src))), (VPMOVSXBWYrr VR128:$src)>;
6257   def : Pat<(v8i32  (X86vsext (v16i8 VR128:$src))), (VPMOVSXBDYrr VR128:$src)>;
6258   def : Pat<(v4i64  (X86vsext (v16i8 VR128:$src))), (VPMOVSXBQYrr VR128:$src)>;
6259
6260   def : Pat<(v8i32  (X86vsext (v8i16 VR128:$src))), (VPMOVSXWDYrr VR128:$src)>;
6261   def : Pat<(v4i64  (X86vsext (v8i16 VR128:$src))), (VPMOVSXWQYrr VR128:$src)>;
6262
6263   def : Pat<(v4i64  (X86vsext (v4i32 VR128:$src))), (VPMOVSXDQYrr VR128:$src)>;
6264
6265   def : Pat<(v16i16 (X86vsext (v32i8 VR256:$src))),
6266             (VPMOVSXBWYrr (EXTRACT_SUBREG VR256:$src, sub_xmm))>;
6267   def : Pat<(v8i32 (X86vsext (v32i8 VR256:$src))),
6268             (VPMOVSXBDYrr (EXTRACT_SUBREG VR256:$src, sub_xmm))>;
6269   def : Pat<(v4i64 (X86vsext (v32i8 VR256:$src))),
6270             (VPMOVSXBQYrr (EXTRACT_SUBREG VR256:$src, sub_xmm))>;
6271
6272   def : Pat<(v8i32 (X86vsext (v16i16 VR256:$src))),
6273             (VPMOVSXWDYrr (EXTRACT_SUBREG VR256:$src, sub_xmm))>;
6274   def : Pat<(v4i64 (X86vsext (v16i16 VR256:$src))),
6275             (VPMOVSXWQYrr (EXTRACT_SUBREG VR256:$src, sub_xmm))>;
6276
6277   def : Pat<(v4i64 (X86vsext (v8i32 VR256:$src))),
6278             (VPMOVSXDQYrr (EXTRACT_SUBREG VR256:$src, sub_xmm))>;
6279
6280   def : Pat<(v8i32 (X86vsext (v8i16 (bitconvert (v2i64 (load addr:$src)))))),
6281             (VPMOVSXWDYrm addr:$src)>;
6282   def : Pat<(v4i64 (X86vsext (v4i32 (bitconvert (v2i64 (load addr:$src)))))),
6283             (VPMOVSXDQYrm addr:$src)>;
6284
6285   def : Pat<(v8i32 (X86vsext (v16i8 (bitconvert (v2i64 
6286                     (scalar_to_vector (loadi64 addr:$src))))))),
6287             (VPMOVSXBDYrm addr:$src)>;
6288   def : Pat<(v8i32 (X86vsext (v16i8 (bitconvert (v2f64 
6289                     (scalar_to_vector (loadf64 addr:$src))))))),
6290             (VPMOVSXBDYrm addr:$src)>;
6291
6292   def : Pat<(v4i64 (X86vsext (v8i16 (bitconvert (v2i64 
6293                     (scalar_to_vector (loadi64 addr:$src))))))),
6294             (VPMOVSXWQYrm addr:$src)>;
6295   def : Pat<(v4i64 (X86vsext (v8i16 (bitconvert (v2f64 
6296                     (scalar_to_vector (loadf64 addr:$src))))))),
6297             (VPMOVSXWQYrm addr:$src)>;
6298
6299   def : Pat<(v4i64 (X86vsext (v16i8 (bitconvert (v4i32 
6300                     (scalar_to_vector (loadi32 addr:$src))))))),
6301             (VPMOVSXBQYrm addr:$src)>;
6302 }
6303
6304 let Predicates = [HasAVX] in {
6305   // Common patterns involving scalar load
6306   def : Pat<(int_x86_sse41_pmovsxbq
6307               (bitconvert (v4i32 (X86vzmovl
6308                             (v4i32 (scalar_to_vector (loadi32 addr:$src))))))),
6309             (VPMOVSXBQrm addr:$src)>;
6310
6311   def : Pat<(int_x86_sse41_pmovzxbq
6312               (bitconvert (v4i32 (X86vzmovl
6313                             (v4i32 (scalar_to_vector (loadi32 addr:$src))))))),
6314             (VPMOVZXBQrm addr:$src)>;
6315 }
6316
6317 let Predicates = [UseSSE41] in {
6318   def : Pat<(v8i16 (X86vsext (v16i8 VR128:$src))), (PMOVSXBWrr VR128:$src)>;
6319   def : Pat<(v4i32 (X86vsext (v16i8 VR128:$src))), (PMOVSXBDrr VR128:$src)>;
6320   def : Pat<(v2i64 (X86vsext (v16i8 VR128:$src))), (PMOVSXBQrr VR128:$src)>;
6321
6322   def : Pat<(v4i32 (X86vsext (v8i16 VR128:$src))), (PMOVSXWDrr VR128:$src)>;
6323   def : Pat<(v2i64 (X86vsext (v8i16 VR128:$src))), (PMOVSXWQrr VR128:$src)>;
6324
6325   def : Pat<(v2i64 (X86vsext (v4i32 VR128:$src))), (PMOVSXDQrr VR128:$src)>;
6326
6327   // Common patterns involving scalar load
6328   def : Pat<(int_x86_sse41_pmovsxbq
6329               (bitconvert (v4i32 (X86vzmovl
6330                             (v4i32 (scalar_to_vector (loadi32 addr:$src))))))),
6331             (PMOVSXBQrm addr:$src)>;
6332
6333   def : Pat<(int_x86_sse41_pmovzxbq
6334               (bitconvert (v4i32 (X86vzmovl
6335                             (v4i32 (scalar_to_vector (loadi32 addr:$src))))))),
6336             (PMOVZXBQrm addr:$src)>;
6337
6338   def : Pat<(v4i32 (X86vsext (v8i16 (bitconvert (v2i64
6339                     (scalar_to_vector (loadi64 addr:$src))))))),
6340             (PMOVSXWDrm addr:$src)>;
6341   def : Pat<(v4i32 (X86vsext (v8i16 (bitconvert (v2f64
6342                     (scalar_to_vector (loadf64 addr:$src))))))),
6343             (PMOVSXWDrm addr:$src)>;
6344   def : Pat<(v4i32 (X86vsext (v16i8 (bitconvert (v4i32
6345                     (scalar_to_vector (loadi32 addr:$src))))))),
6346             (PMOVSXBDrm addr:$src)>;
6347   def : Pat<(v2i64 (X86vsext (v8i16 (bitconvert (v4i32
6348                     (scalar_to_vector (loadi32 addr:$src))))))),
6349             (PMOVSXWQrm addr:$src)>;
6350   def : Pat<(v2i64 (X86vsext (v16i8 (bitconvert (v4i32
6351                     (scalar_to_vector (extloadi32i16 addr:$src))))))),
6352             (PMOVSXBQrm addr:$src)>;
6353   def : Pat<(v2i64 (X86vsext (v4i32 (bitconvert (v2i64
6354                     (scalar_to_vector (loadi64 addr:$src))))))),
6355             (PMOVSXDQrm addr:$src)>;
6356   def : Pat<(v2i64 (X86vsext (v4i32 (bitconvert (v2f64
6357                     (scalar_to_vector (loadf64 addr:$src))))))),
6358             (PMOVSXDQrm addr:$src)>;
6359   def : Pat<(v8i16 (X86vsext (v16i8 (bitconvert (v2i64
6360                     (scalar_to_vector (loadi64 addr:$src))))))),
6361             (PMOVSXBWrm addr:$src)>;
6362   def : Pat<(v8i16 (X86vsext (v16i8 (bitconvert (v2f64
6363                     (scalar_to_vector (loadf64 addr:$src))))))),
6364             (PMOVSXBWrm addr:$src)>;
6365 }
6366
6367 let Predicates = [HasAVX2] in {
6368   def : Pat<(v16i16 (X86vzext (v16i8 VR128:$src))), (VPMOVZXBWYrr VR128:$src)>;
6369   def : Pat<(v8i32  (X86vzext (v16i8 VR128:$src))), (VPMOVZXBDYrr VR128:$src)>;
6370   def : Pat<(v4i64  (X86vzext (v16i8 VR128:$src))), (VPMOVZXBQYrr VR128:$src)>;
6371
6372   def : Pat<(v8i32  (X86vzext (v8i16 VR128:$src))), (VPMOVZXWDYrr VR128:$src)>;
6373   def : Pat<(v4i64  (X86vzext (v8i16 VR128:$src))), (VPMOVZXWQYrr VR128:$src)>;
6374
6375   def : Pat<(v4i64  (X86vzext (v4i32 VR128:$src))), (VPMOVZXDQYrr VR128:$src)>;
6376
6377   def : Pat<(v16i16 (X86vzext (v32i8 VR256:$src))),
6378             (VPMOVZXBWYrr (EXTRACT_SUBREG VR256:$src, sub_xmm))>;
6379   def : Pat<(v8i32 (X86vzext (v32i8 VR256:$src))),
6380             (VPMOVZXBDYrr (EXTRACT_SUBREG VR256:$src, sub_xmm))>;
6381   def : Pat<(v4i64 (X86vzext (v32i8 VR256:$src))),
6382             (VPMOVZXBQYrr (EXTRACT_SUBREG VR256:$src, sub_xmm))>;
6383
6384   def : Pat<(v8i32 (X86vzext (v16i16 VR256:$src))),
6385             (VPMOVZXWDYrr (EXTRACT_SUBREG VR256:$src, sub_xmm))>;
6386   def : Pat<(v4i64 (X86vzext (v16i16 VR256:$src))),
6387             (VPMOVZXWQYrr (EXTRACT_SUBREG VR256:$src, sub_xmm))>;
6388
6389   def : Pat<(v4i64 (X86vzext (v8i32 VR256:$src))),
6390             (VPMOVZXDQYrr (EXTRACT_SUBREG VR256:$src, sub_xmm))>;
6391 }
6392
6393 let Predicates = [HasAVX] in {
6394   def : Pat<(v8i16 (X86vzext (v16i8 VR128:$src))), (VPMOVZXBWrr VR128:$src)>;
6395   def : Pat<(v4i32 (X86vzext (v16i8 VR128:$src))), (VPMOVZXBDrr VR128:$src)>;
6396   def : Pat<(v2i64 (X86vzext (v16i8 VR128:$src))), (VPMOVZXBQrr VR128:$src)>;
6397
6398   def : Pat<(v4i32 (X86vzext (v8i16 VR128:$src))), (VPMOVZXWDrr VR128:$src)>;
6399   def : Pat<(v2i64 (X86vzext (v8i16 VR128:$src))), (VPMOVZXWQrr VR128:$src)>;
6400
6401   def : Pat<(v2i64 (X86vzext (v4i32 VR128:$src))), (VPMOVZXDQrr VR128:$src)>;
6402
6403   def : Pat<(v8i16 (X86vzext (v16i8 (bitconvert (v2i64 (scalar_to_vector (loadi64 addr:$src))))))),
6404             (VPMOVZXBWrm addr:$src)>;
6405   def : Pat<(v8i16 (X86vzext (v16i8 (bitconvert (v2f64 (scalar_to_vector (loadf64 addr:$src))))))),
6406             (VPMOVZXBWrm addr:$src)>;
6407   def : Pat<(v4i32 (X86vzext (v16i8 (bitconvert (v4i32 (scalar_to_vector (loadi32 addr:$src))))))),
6408             (VPMOVZXBDrm addr:$src)>;
6409   def : Pat<(v2i64 (X86vzext (v16i8 (bitconvert (v4i32 (scalar_to_vector (loadi16_anyext addr:$src))))))),
6410             (VPMOVZXBQrm addr:$src)>;
6411
6412   def : Pat<(v4i32 (X86vzext (v8i16 (bitconvert (v2i64 (scalar_to_vector (loadi64 addr:$src))))))),
6413             (VPMOVZXWDrm addr:$src)>;
6414   def : Pat<(v4i32 (X86vzext (v8i16 (bitconvert (v2f64 (scalar_to_vector (loadf64 addr:$src))))))),
6415             (VPMOVZXWDrm addr:$src)>;
6416   def : Pat<(v2i64 (X86vzext (v8i16 (bitconvert (v4i32 (scalar_to_vector (loadi32 addr:$src))))))),
6417             (VPMOVZXWQrm addr:$src)>;
6418
6419   def : Pat<(v2i64 (X86vzext (v4i32 (bitconvert (v2i64 (scalar_to_vector (loadi64 addr:$src))))))),
6420             (VPMOVZXDQrm addr:$src)>;
6421   def : Pat<(v2i64 (X86vzext (v4i32 (bitconvert (v2f64 (scalar_to_vector (loadf64 addr:$src))))))),
6422             (VPMOVZXDQrm addr:$src)>;
6423   def : Pat<(v2i64 (X86vzext (v4i32 (bitconvert (v2i64 (X86vzload addr:$src)))))),
6424             (VPMOVZXDQrm addr:$src)>;
6425
6426   def : Pat<(v8i16 (X86vsext (v16i8 VR128:$src))), (VPMOVSXBWrr VR128:$src)>;
6427   def : Pat<(v4i32 (X86vsext (v16i8 VR128:$src))), (VPMOVSXBDrr VR128:$src)>;
6428   def : Pat<(v2i64 (X86vsext (v16i8 VR128:$src))), (VPMOVSXBQrr VR128:$src)>;
6429
6430   def : Pat<(v4i32 (X86vsext (v8i16 VR128:$src))), (VPMOVSXWDrr VR128:$src)>;
6431   def : Pat<(v2i64 (X86vsext (v8i16 VR128:$src))), (VPMOVSXWQrr VR128:$src)>;
6432
6433   def : Pat<(v2i64 (X86vsext (v4i32 VR128:$src))), (VPMOVSXDQrr VR128:$src)>;
6434
6435   def : Pat<(v4i32 (X86vsext (v8i16 (bitconvert (v2i64
6436                     (scalar_to_vector (loadi64 addr:$src))))))),
6437             (VPMOVSXWDrm addr:$src)>;
6438   def : Pat<(v2i64 (X86vsext (v4i32 (bitconvert (v2i64
6439                     (scalar_to_vector (loadi64 addr:$src))))))),
6440             (VPMOVSXDQrm addr:$src)>;
6441   def : Pat<(v4i32 (X86vsext (v8i16 (bitconvert (v2f64
6442                     (scalar_to_vector (loadf64 addr:$src))))))),
6443             (VPMOVSXWDrm addr:$src)>;
6444   def : Pat<(v2i64 (X86vsext (v4i32 (bitconvert (v2f64
6445                     (scalar_to_vector (loadf64 addr:$src))))))),
6446             (VPMOVSXDQrm addr:$src)>;
6447   def : Pat<(v8i16 (X86vsext (v16i8 (bitconvert (v2i64
6448                     (scalar_to_vector (loadi64 addr:$src))))))),
6449             (VPMOVSXBWrm addr:$src)>;
6450   def : Pat<(v8i16 (X86vsext (v16i8 (bitconvert (v2f64
6451                     (scalar_to_vector (loadf64 addr:$src))))))),
6452             (VPMOVSXBWrm addr:$src)>;
6453
6454   def : Pat<(v4i32 (X86vsext (v16i8 (bitconvert (v4i32
6455                     (scalar_to_vector (loadi32 addr:$src))))))),
6456             (VPMOVSXBDrm addr:$src)>;
6457   def : Pat<(v2i64 (X86vsext (v8i16 (bitconvert (v4i32
6458                     (scalar_to_vector (loadi32 addr:$src))))))),
6459             (VPMOVSXWQrm addr:$src)>;
6460   def : Pat<(v2i64 (X86vsext (v16i8 (bitconvert (v4i32
6461                     (scalar_to_vector (extloadi32i16 addr:$src))))))),
6462             (VPMOVSXBQrm addr:$src)>;
6463 }
6464
6465 let Predicates = [UseSSE41] in {
6466   def : Pat<(v8i16 (X86vzext (v16i8 VR128:$src))), (PMOVZXBWrr VR128:$src)>;
6467   def : Pat<(v4i32 (X86vzext (v16i8 VR128:$src))), (PMOVZXBDrr VR128:$src)>;
6468   def : Pat<(v2i64 (X86vzext (v16i8 VR128:$src))), (PMOVZXBQrr VR128:$src)>;
6469
6470   def : Pat<(v4i32 (X86vzext (v8i16 VR128:$src))), (PMOVZXWDrr VR128:$src)>;
6471   def : Pat<(v2i64 (X86vzext (v8i16 VR128:$src))), (PMOVZXWQrr VR128:$src)>;
6472
6473   def : Pat<(v2i64 (X86vzext (v4i32 VR128:$src))), (PMOVZXDQrr VR128:$src)>;
6474
6475   def : Pat<(v8i16 (X86vzext (v16i8 (bitconvert (v2i64 (scalar_to_vector (loadi64 addr:$src))))))),
6476             (PMOVZXBWrm addr:$src)>;
6477   def : Pat<(v8i16 (X86vzext (v16i8 (bitconvert (v2f64 (scalar_to_vector (loadf64 addr:$src))))))),
6478             (PMOVZXBWrm addr:$src)>;
6479   def : Pat<(v4i32 (X86vzext (v16i8 (bitconvert (v4i32 (scalar_to_vector (loadi32 addr:$src))))))),
6480             (PMOVZXBDrm addr:$src)>;
6481   def : Pat<(v2i64 (X86vzext (v16i8 (bitconvert (v4i32 (scalar_to_vector (loadi16_anyext addr:$src))))))),
6482             (PMOVZXBQrm addr:$src)>;
6483
6484   def : Pat<(v4i32 (X86vzext (v8i16 (bitconvert (v2i64 (scalar_to_vector (loadi64 addr:$src))))))),
6485             (PMOVZXWDrm addr:$src)>;
6486   def : Pat<(v4i32 (X86vzext (v8i16 (bitconvert (v2f64 (scalar_to_vector (loadf64 addr:$src))))))),
6487             (PMOVZXWDrm addr:$src)>;
6488   def : Pat<(v2i64 (X86vzext (v8i16 (bitconvert (v4i32 (scalar_to_vector (loadi32 addr:$src))))))),
6489             (PMOVZXWQrm addr:$src)>;
6490
6491   def : Pat<(v2i64 (X86vzext (v4i32 (bitconvert (v2i64 (scalar_to_vector (loadi64 addr:$src))))))),
6492             (PMOVZXDQrm addr:$src)>;
6493   def : Pat<(v2i64 (X86vzext (v4i32 (bitconvert (v2f64 (scalar_to_vector (loadf64 addr:$src))))))),
6494             (PMOVZXDQrm addr:$src)>;
6495   def : Pat<(v2i64 (X86vzext (v4i32 (bitconvert (v2i64 (X86vzload addr:$src)))))),
6496             (PMOVZXDQrm addr:$src)>;
6497 }
6498
6499 //===----------------------------------------------------------------------===//
6500 // SSE4.1 - Extract Instructions
6501 //===----------------------------------------------------------------------===//
6502
6503 /// SS41I_binop_ext8 - SSE 4.1 extract 8 bits to 32 bit reg or 8 bit mem
6504 multiclass SS41I_extract8<bits<8> opc, string OpcodeStr> {
6505   def rr : SS4AIi8<opc, MRMDestReg, (outs GR32orGR64:$dst),
6506                  (ins VR128:$src1, i32i8imm:$src2),
6507                  !strconcat(OpcodeStr,
6508                             "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6509                  [(set GR32orGR64:$dst, (X86pextrb (v16i8 VR128:$src1),
6510                                          imm:$src2))]>,
6511                   Sched<[WriteShuffle]>;
6512   let neverHasSideEffects = 1, mayStore = 1,
6513       SchedRW = [WriteShuffleLd, WriteRMW] in
6514   def mr : SS4AIi8<opc, MRMDestMem, (outs),
6515                  (ins i8mem:$dst, VR128:$src1, i32i8imm:$src2),
6516                  !strconcat(OpcodeStr,
6517                             "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6518                  [(store (i8 (trunc (assertzext (X86pextrb (v16i8 VR128:$src1),
6519                                                  imm:$src2)))), addr:$dst)]>;
6520 }
6521
6522 let Predicates = [HasAVX] in
6523   defm VPEXTRB : SS41I_extract8<0x14, "vpextrb">, VEX;
6524
6525 defm PEXTRB      : SS41I_extract8<0x14, "pextrb">;
6526
6527
6528 /// SS41I_extract16 - SSE 4.1 extract 16 bits to memory destination
6529 multiclass SS41I_extract16<bits<8> opc, string OpcodeStr> {
6530   let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0 in
6531   def rr_REV : SS4AIi8<opc, MRMDestReg, (outs GR32orGR64:$dst),
6532                    (ins VR128:$src1, i32i8imm:$src2),
6533                    !strconcat(OpcodeStr,
6534                    "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6535                    []>, Sched<[WriteShuffle]>;
6536
6537   let neverHasSideEffects = 1, mayStore = 1,
6538       SchedRW = [WriteShuffleLd, WriteRMW] in
6539   def mr : SS4AIi8<opc, MRMDestMem, (outs),
6540                  (ins i16mem:$dst, VR128:$src1, i32i8imm:$src2),
6541                  !strconcat(OpcodeStr,
6542                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6543                  [(store (i16 (trunc (assertzext (X86pextrw (v8i16 VR128:$src1),
6544                                                   imm:$src2)))), addr:$dst)]>;
6545 }
6546
6547 let Predicates = [HasAVX] in
6548   defm VPEXTRW : SS41I_extract16<0x15, "vpextrw">, VEX;
6549
6550 defm PEXTRW      : SS41I_extract16<0x15, "pextrw">;
6551
6552
6553 /// SS41I_extract32 - SSE 4.1 extract 32 bits to int reg or memory destination
6554 multiclass SS41I_extract32<bits<8> opc, string OpcodeStr> {
6555   def rr : SS4AIi8<opc, MRMDestReg, (outs GR32:$dst),
6556                  (ins VR128:$src1, i32i8imm:$src2),
6557                  !strconcat(OpcodeStr,
6558                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6559                  [(set GR32:$dst,
6560                   (extractelt (v4i32 VR128:$src1), imm:$src2))]>,
6561                   Sched<[WriteShuffle]>;
6562   let SchedRW = [WriteShuffleLd, WriteRMW] in
6563   def mr : SS4AIi8<opc, MRMDestMem, (outs),
6564                  (ins i32mem:$dst, VR128:$src1, i32i8imm:$src2),
6565                  !strconcat(OpcodeStr,
6566                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6567                  [(store (extractelt (v4i32 VR128:$src1), imm:$src2),
6568                           addr:$dst)]>;
6569 }
6570
6571 let Predicates = [HasAVX] in
6572   defm VPEXTRD : SS41I_extract32<0x16, "vpextrd">, VEX;
6573
6574 defm PEXTRD      : SS41I_extract32<0x16, "pextrd">;
6575
6576 /// SS41I_extract32 - SSE 4.1 extract 32 bits to int reg or memory destination
6577 multiclass SS41I_extract64<bits<8> opc, string OpcodeStr> {
6578   def rr : SS4AIi8<opc, MRMDestReg, (outs GR64:$dst),
6579                  (ins VR128:$src1, i32i8imm:$src2),
6580                  !strconcat(OpcodeStr,
6581                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6582                  [(set GR64:$dst,
6583                   (extractelt (v2i64 VR128:$src1), imm:$src2))]>,
6584                   Sched<[WriteShuffle]>, REX_W;
6585   let SchedRW = [WriteShuffleLd, WriteRMW] in
6586   def mr : SS4AIi8<opc, MRMDestMem, (outs),
6587                  (ins i64mem:$dst, VR128:$src1, i32i8imm:$src2),
6588                  !strconcat(OpcodeStr,
6589                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6590                  [(store (extractelt (v2i64 VR128:$src1), imm:$src2),
6591                           addr:$dst)]>, REX_W;
6592 }
6593
6594 let Predicates = [HasAVX] in
6595   defm VPEXTRQ : SS41I_extract64<0x16, "vpextrq">, VEX, VEX_W;
6596
6597 defm PEXTRQ      : SS41I_extract64<0x16, "pextrq">;
6598
6599 /// SS41I_extractf32 - SSE 4.1 extract 32 bits fp value to int reg or memory
6600 /// destination
6601 multiclass SS41I_extractf32<bits<8> opc, string OpcodeStr,
6602                             OpndItins itins = DEFAULT_ITINS> {
6603   def rr : SS4AIi8<opc, MRMDestReg, (outs GR32orGR64:$dst),
6604                  (ins VR128:$src1, i32i8imm:$src2),
6605                  !strconcat(OpcodeStr,
6606                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6607                  [(set GR32orGR64:$dst,
6608                     (extractelt (bc_v4i32 (v4f32 VR128:$src1)), imm:$src2))],
6609                     itins.rr>, Sched<[WriteFBlend]>;
6610   let SchedRW = [WriteFBlendLd, WriteRMW] in
6611   def mr : SS4AIi8<opc, MRMDestMem, (outs),
6612                  (ins f32mem:$dst, VR128:$src1, i32i8imm:$src2),
6613                  !strconcat(OpcodeStr,
6614                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6615                  [(store (extractelt (bc_v4i32 (v4f32 VR128:$src1)), imm:$src2),
6616                           addr:$dst)], itins.rm>;
6617 }
6618
6619 let ExeDomain = SSEPackedSingle in {
6620   let Predicates = [UseAVX] in
6621     defm VEXTRACTPS : SS41I_extractf32<0x17, "vextractps">, VEX;
6622   defm EXTRACTPS   : SS41I_extractf32<0x17, "extractps", SSE_EXTRACT_ITINS>;
6623 }
6624
6625 // Also match an EXTRACTPS store when the store is done as f32 instead of i32.
6626 def : Pat<(store (f32 (bitconvert (extractelt (bc_v4i32 (v4f32 VR128:$src1)),
6627                                               imm:$src2))),
6628                  addr:$dst),
6629           (VEXTRACTPSmr addr:$dst, VR128:$src1, imm:$src2)>,
6630           Requires<[HasAVX]>;
6631 def : Pat<(store (f32 (bitconvert (extractelt (bc_v4i32 (v4f32 VR128:$src1)),
6632                                               imm:$src2))),
6633                  addr:$dst),
6634           (EXTRACTPSmr addr:$dst, VR128:$src1, imm:$src2)>,
6635           Requires<[UseSSE41]>;
6636
6637 //===----------------------------------------------------------------------===//
6638 // SSE4.1 - Insert Instructions
6639 //===----------------------------------------------------------------------===//
6640
6641 multiclass SS41I_insert8<bits<8> opc, string asm, bit Is2Addr = 1> {
6642   def rr : SS4AIi8<opc, MRMSrcReg, (outs VR128:$dst),
6643       (ins VR128:$src1, GR32orGR64:$src2, i32i8imm:$src3),
6644       !if(Is2Addr,
6645         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6646         !strconcat(asm,
6647                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6648       [(set VR128:$dst,
6649         (X86pinsrb VR128:$src1, GR32orGR64:$src2, imm:$src3))]>,
6650       Sched<[WriteShuffle]>;
6651   def rm : SS4AIi8<opc, MRMSrcMem, (outs VR128:$dst),
6652       (ins VR128:$src1, i8mem:$src2, i32i8imm:$src3),
6653       !if(Is2Addr,
6654         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6655         !strconcat(asm,
6656                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6657       [(set VR128:$dst,
6658         (X86pinsrb VR128:$src1, (extloadi8 addr:$src2),
6659                    imm:$src3))]>, Sched<[WriteShuffleLd, ReadAfterLd]>;
6660 }
6661
6662 let Predicates = [HasAVX] in
6663   defm VPINSRB : SS41I_insert8<0x20, "vpinsrb", 0>, VEX_4V;
6664 let Constraints = "$src1 = $dst" in
6665   defm PINSRB  : SS41I_insert8<0x20, "pinsrb">;
6666
6667 multiclass SS41I_insert32<bits<8> opc, string asm, bit Is2Addr = 1> {
6668   def rr : SS4AIi8<opc, MRMSrcReg, (outs VR128:$dst),
6669       (ins VR128:$src1, GR32:$src2, i32i8imm:$src3),
6670       !if(Is2Addr,
6671         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6672         !strconcat(asm,
6673                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6674       [(set VR128:$dst,
6675         (v4i32 (insertelt VR128:$src1, GR32:$src2, imm:$src3)))]>,
6676       Sched<[WriteShuffle]>;
6677   def rm : SS4AIi8<opc, MRMSrcMem, (outs VR128:$dst),
6678       (ins VR128:$src1, i32mem:$src2, i32i8imm:$src3),
6679       !if(Is2Addr,
6680         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6681         !strconcat(asm,
6682                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6683       [(set VR128:$dst,
6684         (v4i32 (insertelt VR128:$src1, (loadi32 addr:$src2),
6685                           imm:$src3)))]>, Sched<[WriteShuffleLd, ReadAfterLd]>;
6686 }
6687
6688 let Predicates = [HasAVX] in
6689   defm VPINSRD : SS41I_insert32<0x22, "vpinsrd", 0>, VEX_4V;
6690 let Constraints = "$src1 = $dst" in
6691   defm PINSRD : SS41I_insert32<0x22, "pinsrd">;
6692
6693 multiclass SS41I_insert64<bits<8> opc, string asm, bit Is2Addr = 1> {
6694   def rr : SS4AIi8<opc, MRMSrcReg, (outs VR128:$dst),
6695       (ins VR128:$src1, GR64:$src2, i32i8imm:$src3),
6696       !if(Is2Addr,
6697         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6698         !strconcat(asm,
6699                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6700       [(set VR128:$dst,
6701         (v2i64 (insertelt VR128:$src1, GR64:$src2, imm:$src3)))]>,
6702       Sched<[WriteShuffle]>;
6703   def rm : SS4AIi8<opc, MRMSrcMem, (outs VR128:$dst),
6704       (ins VR128:$src1, i64mem:$src2, i32i8imm:$src3),
6705       !if(Is2Addr,
6706         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6707         !strconcat(asm,
6708                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6709       [(set VR128:$dst,
6710         (v2i64 (insertelt VR128:$src1, (loadi64 addr:$src2),
6711                           imm:$src3)))]>, Sched<[WriteShuffleLd, ReadAfterLd]>;
6712 }
6713
6714 let Predicates = [HasAVX] in
6715   defm VPINSRQ : SS41I_insert64<0x22, "vpinsrq", 0>, VEX_4V, VEX_W;
6716 let Constraints = "$src1 = $dst" in
6717   defm PINSRQ : SS41I_insert64<0x22, "pinsrq">, REX_W;
6718
6719 // insertps has a few different modes, there's the first two here below which
6720 // are optimized inserts that won't zero arbitrary elements in the destination
6721 // vector. The next one matches the intrinsic and could zero arbitrary elements
6722 // in the target vector.
6723 multiclass SS41I_insertf32<bits<8> opc, string asm, bit Is2Addr = 1,
6724                            OpndItins itins = DEFAULT_ITINS> {
6725   def rr : SS4AIi8<opc, MRMSrcReg, (outs VR128:$dst),
6726       (ins VR128:$src1, VR128:$src2, i8imm:$src3),
6727       !if(Is2Addr,
6728         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6729         !strconcat(asm,
6730                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6731       [(set VR128:$dst,
6732         (X86insertps VR128:$src1, VR128:$src2, imm:$src3))], itins.rr>,
6733       Sched<[WriteFShuffle]>;
6734   def rm : SS4AIi8<opc, MRMSrcMem, (outs VR128:$dst),
6735       (ins VR128:$src1, f32mem:$src2, i8imm:$src3),
6736       !if(Is2Addr,
6737         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6738         !strconcat(asm,
6739                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6740       [(set VR128:$dst,
6741         (X86insertps VR128:$src1,
6742                    (v4f32 (scalar_to_vector (loadf32 addr:$src2))),
6743                     imm:$src3))], itins.rm>,
6744       Sched<[WriteFShuffleLd, ReadAfterLd]>;
6745 }
6746
6747 let ExeDomain = SSEPackedSingle in {
6748   let Predicates = [UseAVX] in
6749     defm VINSERTPS : SS41I_insertf32<0x21, "vinsertps", 0>, VEX_4V;
6750   let Constraints = "$src1 = $dst" in
6751     defm INSERTPS : SS41I_insertf32<0x21, "insertps", 1, SSE_INSERT_ITINS>;
6752 }
6753
6754 let Predicates = [UseSSE41] in {
6755   // If we're inserting an element from a load or a null pshuf of a load,
6756   // fold the load into the insertps instruction.
6757   def : Pat<(v4f32 (X86insertps (v4f32 VR128:$src1), (X86PShufd (v4f32
6758                        (scalar_to_vector (loadf32 addr:$src2))), (i8 0)),
6759                    imm:$src3)),
6760             (INSERTPSrm VR128:$src1, addr:$src2, imm:$src3)>;
6761   def : Pat<(v4f32 (X86insertps (v4f32 VR128:$src1), (X86PShufd
6762                       (loadv4f32 addr:$src2), (i8 0)), imm:$src3)),
6763             (INSERTPSrm VR128:$src1, addr:$src2, imm:$src3)>;
6764 }
6765
6766 let Predicates = [UseAVX] in {
6767   // If we're inserting an element from a vbroadcast of a load, fold the
6768   // load into the X86insertps instruction.
6769   def : Pat<(v4f32 (X86insertps (v4f32 VR128:$src1),
6770                 (X86VBroadcast (loadf32 addr:$src2)), imm:$src3)),
6771             (VINSERTPSrm VR128:$src1, addr:$src2, imm:$src3)>;
6772   def : Pat<(v4f32 (X86insertps (v4f32 VR128:$src1),
6773                 (X86VBroadcast (loadv4f32 addr:$src2)), imm:$src3)),
6774             (VINSERTPSrm VR128:$src1, addr:$src2, imm:$src3)>;
6775 }
6776
6777 //===----------------------------------------------------------------------===//
6778 // SSE4.1 - Round Instructions
6779 //===----------------------------------------------------------------------===//
6780
6781 multiclass sse41_fp_unop_rm<bits<8> opcps, bits<8> opcpd, string OpcodeStr,
6782                             X86MemOperand x86memop, RegisterClass RC,
6783                             PatFrag mem_frag32, PatFrag mem_frag64,
6784                             Intrinsic V4F32Int, Intrinsic V2F64Int> {
6785 let ExeDomain = SSEPackedSingle in {
6786   // Intrinsic operation, reg.
6787   // Vector intrinsic operation, reg
6788   def PSr : SS4AIi8<opcps, MRMSrcReg,
6789                     (outs RC:$dst), (ins RC:$src1, i32i8imm:$src2),
6790                     !strconcat(OpcodeStr,
6791                     "ps\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6792                     [(set RC:$dst, (V4F32Int RC:$src1, imm:$src2))],
6793                     IIC_SSE_ROUNDPS_REG>, Sched<[WriteFAdd]>;
6794
6795   // Vector intrinsic operation, mem
6796   def PSm : SS4AIi8<opcps, MRMSrcMem,
6797                     (outs RC:$dst), (ins x86memop:$src1, i32i8imm:$src2),
6798                     !strconcat(OpcodeStr,
6799                     "ps\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6800                     [(set RC:$dst,
6801                           (V4F32Int (mem_frag32 addr:$src1),imm:$src2))],
6802                           IIC_SSE_ROUNDPS_MEM>, Sched<[WriteFAddLd]>;
6803 } // ExeDomain = SSEPackedSingle
6804
6805 let ExeDomain = SSEPackedDouble in {
6806   // Vector intrinsic operation, reg
6807   def PDr : SS4AIi8<opcpd, MRMSrcReg,
6808                     (outs RC:$dst), (ins RC:$src1, i32i8imm:$src2),
6809                     !strconcat(OpcodeStr,
6810                     "pd\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6811                     [(set RC:$dst, (V2F64Int RC:$src1, imm:$src2))],
6812                     IIC_SSE_ROUNDPS_REG>, Sched<[WriteFAdd]>;
6813
6814   // Vector intrinsic operation, mem
6815   def PDm : SS4AIi8<opcpd, MRMSrcMem,
6816                     (outs RC:$dst), (ins x86memop:$src1, i32i8imm:$src2),
6817                     !strconcat(OpcodeStr,
6818                     "pd\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6819                     [(set RC:$dst,
6820                           (V2F64Int (mem_frag64 addr:$src1),imm:$src2))],
6821                           IIC_SSE_ROUNDPS_REG>, Sched<[WriteFAddLd]>;
6822 } // ExeDomain = SSEPackedDouble
6823 }
6824
6825 multiclass sse41_fp_binop_rm<bits<8> opcss, bits<8> opcsd,
6826                             string OpcodeStr,
6827                             Intrinsic F32Int,
6828                             Intrinsic F64Int, bit Is2Addr = 1> {
6829 let ExeDomain = GenericDomain in {
6830   // Operation, reg.
6831   let hasSideEffects = 0 in
6832   def SSr : SS4AIi8<opcss, MRMSrcReg,
6833       (outs FR32:$dst), (ins FR32:$src1, FR32:$src2, i32i8imm:$src3),
6834       !if(Is2Addr,
6835           !strconcat(OpcodeStr,
6836               "ss\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6837           !strconcat(OpcodeStr,
6838               "ss\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6839       []>, Sched<[WriteFAdd]>;
6840
6841   // Intrinsic operation, reg.
6842   let isCodeGenOnly = 1 in
6843   def SSr_Int : SS4AIi8<opcss, MRMSrcReg,
6844         (outs VR128:$dst), (ins VR128:$src1, VR128:$src2, i32i8imm:$src3),
6845         !if(Is2Addr,
6846             !strconcat(OpcodeStr,
6847                 "ss\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6848             !strconcat(OpcodeStr,
6849                 "ss\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6850         [(set VR128:$dst, (F32Int VR128:$src1, VR128:$src2, imm:$src3))]>,
6851         Sched<[WriteFAdd]>;
6852
6853   // Intrinsic operation, mem.
6854   def SSm : SS4AIi8<opcss, MRMSrcMem,
6855         (outs VR128:$dst), (ins VR128:$src1, ssmem:$src2, i32i8imm:$src3),
6856         !if(Is2Addr,
6857             !strconcat(OpcodeStr,
6858                 "ss\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6859             !strconcat(OpcodeStr,
6860                 "ss\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6861         [(set VR128:$dst,
6862              (F32Int VR128:$src1, sse_load_f32:$src2, imm:$src3))]>,
6863         Sched<[WriteFAddLd, ReadAfterLd]>;
6864
6865   // Operation, reg.
6866   let hasSideEffects = 0 in
6867   def SDr : SS4AIi8<opcsd, MRMSrcReg,
6868         (outs FR64:$dst), (ins FR64:$src1, FR64:$src2, i32i8imm:$src3),
6869         !if(Is2Addr,
6870             !strconcat(OpcodeStr,
6871                 "sd\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6872             !strconcat(OpcodeStr,
6873                 "sd\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6874         []>, Sched<[WriteFAdd]>;
6875
6876   // Intrinsic operation, reg.
6877   let isCodeGenOnly = 1 in
6878   def SDr_Int : SS4AIi8<opcsd, MRMSrcReg,
6879         (outs VR128:$dst), (ins VR128:$src1, VR128:$src2, i32i8imm:$src3),
6880         !if(Is2Addr,
6881             !strconcat(OpcodeStr,
6882                 "sd\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6883             !strconcat(OpcodeStr,
6884                 "sd\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6885         [(set VR128:$dst, (F64Int VR128:$src1, VR128:$src2, imm:$src3))]>,
6886         Sched<[WriteFAdd]>;
6887
6888   // Intrinsic operation, mem.
6889   def SDm : SS4AIi8<opcsd, MRMSrcMem,
6890         (outs VR128:$dst), (ins VR128:$src1, sdmem:$src2, i32i8imm:$src3),
6891         !if(Is2Addr,
6892             !strconcat(OpcodeStr,
6893                 "sd\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6894             !strconcat(OpcodeStr,
6895                 "sd\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6896         [(set VR128:$dst,
6897               (F64Int VR128:$src1, sse_load_f64:$src2, imm:$src3))]>,
6898         Sched<[WriteFAddLd, ReadAfterLd]>;
6899 } // ExeDomain = GenericDomain
6900 }
6901
6902 // FP round - roundss, roundps, roundsd, roundpd
6903 let Predicates = [HasAVX] in {
6904   // Intrinsic form
6905   defm VROUND  : sse41_fp_unop_rm<0x08, 0x09, "vround", f128mem, VR128,
6906                                   loadv4f32, loadv2f64,
6907                                   int_x86_sse41_round_ps,
6908                                   int_x86_sse41_round_pd>, VEX;
6909   defm VROUNDY : sse41_fp_unop_rm<0x08, 0x09, "vround", f256mem, VR256,
6910                                   loadv8f32, loadv4f64,
6911                                   int_x86_avx_round_ps_256,
6912                                   int_x86_avx_round_pd_256>, VEX, VEX_L;
6913   defm VROUND  : sse41_fp_binop_rm<0x0A, 0x0B, "vround",
6914                                   int_x86_sse41_round_ss,
6915                                   int_x86_sse41_round_sd, 0>, VEX_4V, VEX_LIG;
6916
6917   def : Pat<(ffloor FR32:$src),
6918             (VROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x1))>;
6919   def : Pat<(f64 (ffloor FR64:$src)),
6920             (VROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x1))>;
6921   def : Pat<(f32 (fnearbyint FR32:$src)),
6922             (VROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0xC))>;
6923   def : Pat<(f64 (fnearbyint FR64:$src)),
6924             (VROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0xC))>;
6925   def : Pat<(f32 (fceil FR32:$src)),
6926             (VROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x2))>;
6927   def : Pat<(f64 (fceil FR64:$src)),
6928             (VROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x2))>;
6929   def : Pat<(f32 (frint FR32:$src)),
6930             (VROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x4))>;
6931   def : Pat<(f64 (frint FR64:$src)),
6932             (VROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x4))>;
6933   def : Pat<(f32 (ftrunc FR32:$src)),
6934             (VROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x3))>;
6935   def : Pat<(f64 (ftrunc FR64:$src)),
6936             (VROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x3))>;
6937
6938   def : Pat<(v4f32 (ffloor VR128:$src)),
6939             (VROUNDPSr VR128:$src, (i32 0x1))>;
6940   def : Pat<(v4f32 (fnearbyint VR128:$src)),
6941             (VROUNDPSr VR128:$src, (i32 0xC))>;
6942   def : Pat<(v4f32 (fceil VR128:$src)),
6943             (VROUNDPSr VR128:$src, (i32 0x2))>;
6944   def : Pat<(v4f32 (frint VR128:$src)),
6945             (VROUNDPSr VR128:$src, (i32 0x4))>;
6946   def : Pat<(v4f32 (ftrunc VR128:$src)),
6947             (VROUNDPSr VR128:$src, (i32 0x3))>;
6948
6949   def : Pat<(v2f64 (ffloor VR128:$src)),
6950             (VROUNDPDr VR128:$src, (i32 0x1))>;
6951   def : Pat<(v2f64 (fnearbyint VR128:$src)),
6952             (VROUNDPDr VR128:$src, (i32 0xC))>;
6953   def : Pat<(v2f64 (fceil VR128:$src)),
6954             (VROUNDPDr VR128:$src, (i32 0x2))>;
6955   def : Pat<(v2f64 (frint VR128:$src)),
6956             (VROUNDPDr VR128:$src, (i32 0x4))>;
6957   def : Pat<(v2f64 (ftrunc VR128:$src)),
6958             (VROUNDPDr VR128:$src, (i32 0x3))>;
6959
6960   def : Pat<(v8f32 (ffloor VR256:$src)),
6961             (VROUNDYPSr VR256:$src, (i32 0x1))>;
6962   def : Pat<(v8f32 (fnearbyint VR256:$src)),
6963             (VROUNDYPSr VR256:$src, (i32 0xC))>;
6964   def : Pat<(v8f32 (fceil VR256:$src)),
6965             (VROUNDYPSr VR256:$src, (i32 0x2))>;
6966   def : Pat<(v8f32 (frint VR256:$src)),
6967             (VROUNDYPSr VR256:$src, (i32 0x4))>;
6968   def : Pat<(v8f32 (ftrunc VR256:$src)),
6969             (VROUNDYPSr VR256:$src, (i32 0x3))>;
6970
6971   def : Pat<(v4f64 (ffloor VR256:$src)),
6972             (VROUNDYPDr VR256:$src, (i32 0x1))>;
6973   def : Pat<(v4f64 (fnearbyint VR256:$src)),
6974             (VROUNDYPDr VR256:$src, (i32 0xC))>;
6975   def : Pat<(v4f64 (fceil VR256:$src)),
6976             (VROUNDYPDr VR256:$src, (i32 0x2))>;
6977   def : Pat<(v4f64 (frint VR256:$src)),
6978             (VROUNDYPDr VR256:$src, (i32 0x4))>;
6979   def : Pat<(v4f64 (ftrunc VR256:$src)),
6980             (VROUNDYPDr VR256:$src, (i32 0x3))>;
6981 }
6982
6983 defm ROUND  : sse41_fp_unop_rm<0x08, 0x09, "round", f128mem, VR128,
6984                                memopv4f32, memopv2f64,
6985                                int_x86_sse41_round_ps, int_x86_sse41_round_pd>;
6986 let Constraints = "$src1 = $dst" in
6987 defm ROUND  : sse41_fp_binop_rm<0x0A, 0x0B, "round",
6988                                int_x86_sse41_round_ss, int_x86_sse41_round_sd>;
6989
6990 let Predicates = [UseSSE41] in {
6991   def : Pat<(ffloor FR32:$src),
6992             (ROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x1))>;
6993   def : Pat<(f64 (ffloor FR64:$src)),
6994             (ROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x1))>;
6995   def : Pat<(f32 (fnearbyint FR32:$src)),
6996             (ROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0xC))>;
6997   def : Pat<(f64 (fnearbyint FR64:$src)),
6998             (ROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0xC))>;
6999   def : Pat<(f32 (fceil FR32:$src)),
7000             (ROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x2))>;
7001   def : Pat<(f64 (fceil FR64:$src)),
7002             (ROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x2))>;
7003   def : Pat<(f32 (frint FR32:$src)),
7004             (ROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x4))>;
7005   def : Pat<(f64 (frint FR64:$src)),
7006             (ROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x4))>;
7007   def : Pat<(f32 (ftrunc FR32:$src)),
7008             (ROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x3))>;
7009   def : Pat<(f64 (ftrunc FR64:$src)),
7010             (ROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x3))>;
7011
7012   def : Pat<(v4f32 (ffloor VR128:$src)),
7013             (ROUNDPSr VR128:$src, (i32 0x1))>;
7014   def : Pat<(v4f32 (fnearbyint VR128:$src)),
7015             (ROUNDPSr VR128:$src, (i32 0xC))>;
7016   def : Pat<(v4f32 (fceil VR128:$src)),
7017             (ROUNDPSr VR128:$src, (i32 0x2))>;
7018   def : Pat<(v4f32 (frint VR128:$src)),
7019             (ROUNDPSr VR128:$src, (i32 0x4))>;
7020   def : Pat<(v4f32 (ftrunc VR128:$src)),
7021             (ROUNDPSr VR128:$src, (i32 0x3))>;
7022
7023   def : Pat<(v2f64 (ffloor VR128:$src)),
7024             (ROUNDPDr VR128:$src, (i32 0x1))>;
7025   def : Pat<(v2f64 (fnearbyint VR128:$src)),
7026             (ROUNDPDr VR128:$src, (i32 0xC))>;
7027   def : Pat<(v2f64 (fceil VR128:$src)),
7028             (ROUNDPDr VR128:$src, (i32 0x2))>;
7029   def : Pat<(v2f64 (frint VR128:$src)),
7030             (ROUNDPDr VR128:$src, (i32 0x4))>;
7031   def : Pat<(v2f64 (ftrunc VR128:$src)),
7032             (ROUNDPDr VR128:$src, (i32 0x3))>;
7033 }
7034
7035 //===----------------------------------------------------------------------===//
7036 // SSE4.1 - Packed Bit Test
7037 //===----------------------------------------------------------------------===//
7038
7039 // ptest instruction we'll lower to this in X86ISelLowering primarily from
7040 // the intel intrinsic that corresponds to this.
7041 let Defs = [EFLAGS], Predicates = [HasAVX] in {
7042 def VPTESTrr  : SS48I<0x17, MRMSrcReg, (outs), (ins VR128:$src1, VR128:$src2),
7043                 "vptest\t{$src2, $src1|$src1, $src2}",
7044                 [(set EFLAGS, (X86ptest VR128:$src1, (v2i64 VR128:$src2)))]>,
7045                 Sched<[WriteVecLogic]>, VEX;
7046 def VPTESTrm  : SS48I<0x17, MRMSrcMem, (outs), (ins VR128:$src1, f128mem:$src2),
7047                 "vptest\t{$src2, $src1|$src1, $src2}",
7048                 [(set EFLAGS,(X86ptest VR128:$src1, (loadv2i64 addr:$src2)))]>,
7049                 Sched<[WriteVecLogicLd, ReadAfterLd]>, VEX;
7050
7051 def VPTESTYrr : SS48I<0x17, MRMSrcReg, (outs), (ins VR256:$src1, VR256:$src2),
7052                 "vptest\t{$src2, $src1|$src1, $src2}",
7053                 [(set EFLAGS, (X86ptest VR256:$src1, (v4i64 VR256:$src2)))]>,
7054                 Sched<[WriteVecLogic]>, VEX, VEX_L;
7055 def VPTESTYrm : SS48I<0x17, MRMSrcMem, (outs), (ins VR256:$src1, i256mem:$src2),
7056                 "vptest\t{$src2, $src1|$src1, $src2}",
7057                 [(set EFLAGS,(X86ptest VR256:$src1, (loadv4i64 addr:$src2)))]>,
7058                 Sched<[WriteVecLogicLd, ReadAfterLd]>, VEX, VEX_L;
7059 }
7060
7061 let Defs = [EFLAGS] in {
7062 def PTESTrr : SS48I<0x17, MRMSrcReg, (outs), (ins VR128:$src1, VR128:$src2),
7063               "ptest\t{$src2, $src1|$src1, $src2}",
7064               [(set EFLAGS, (X86ptest VR128:$src1, (v2i64 VR128:$src2)))]>,
7065               Sched<[WriteVecLogic]>;
7066 def PTESTrm : SS48I<0x17, MRMSrcMem, (outs), (ins VR128:$src1, f128mem:$src2),
7067               "ptest\t{$src2, $src1|$src1, $src2}",
7068               [(set EFLAGS, (X86ptest VR128:$src1, (memopv2i64 addr:$src2)))]>,
7069               Sched<[WriteVecLogicLd, ReadAfterLd]>;
7070 }
7071
7072 // The bit test instructions below are AVX only
7073 multiclass avx_bittest<bits<8> opc, string OpcodeStr, RegisterClass RC,
7074                        X86MemOperand x86memop, PatFrag mem_frag, ValueType vt> {
7075   def rr : SS48I<opc, MRMSrcReg, (outs), (ins RC:$src1, RC:$src2),
7076             !strconcat(OpcodeStr, "\t{$src2, $src1|$src1, $src2}"),
7077             [(set EFLAGS, (X86testp RC:$src1, (vt RC:$src2)))]>,
7078             Sched<[WriteVecLogic]>, VEX;
7079   def rm : SS48I<opc, MRMSrcMem, (outs), (ins RC:$src1, x86memop:$src2),
7080             !strconcat(OpcodeStr, "\t{$src2, $src1|$src1, $src2}"),
7081             [(set EFLAGS, (X86testp RC:$src1, (mem_frag addr:$src2)))]>,
7082             Sched<[WriteVecLogicLd, ReadAfterLd]>, VEX;
7083 }
7084
7085 let Defs = [EFLAGS], Predicates = [HasAVX] in {
7086 let ExeDomain = SSEPackedSingle in {
7087 defm VTESTPS  : avx_bittest<0x0E, "vtestps", VR128, f128mem, loadv4f32, v4f32>;
7088 defm VTESTPSY : avx_bittest<0x0E, "vtestps", VR256, f256mem, loadv8f32, v8f32>,
7089                             VEX_L;
7090 }
7091 let ExeDomain = SSEPackedDouble in {
7092 defm VTESTPD  : avx_bittest<0x0F, "vtestpd", VR128, f128mem, loadv2f64, v2f64>;
7093 defm VTESTPDY : avx_bittest<0x0F, "vtestpd", VR256, f256mem, loadv4f64, v4f64>,
7094                             VEX_L;
7095 }
7096 }
7097
7098 //===----------------------------------------------------------------------===//
7099 // SSE4.1 - Misc Instructions
7100 //===----------------------------------------------------------------------===//
7101
7102 let Defs = [EFLAGS], Predicates = [HasPOPCNT] in {
7103   def POPCNT16rr : I<0xB8, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
7104                      "popcnt{w}\t{$src, $dst|$dst, $src}",
7105                      [(set GR16:$dst, (ctpop GR16:$src)), (implicit EFLAGS)],
7106                      IIC_SSE_POPCNT_RR>, Sched<[WriteFAdd]>,
7107                      OpSize16, XS;
7108   def POPCNT16rm : I<0xB8, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
7109                      "popcnt{w}\t{$src, $dst|$dst, $src}",
7110                      [(set GR16:$dst, (ctpop (loadi16 addr:$src))),
7111                       (implicit EFLAGS)], IIC_SSE_POPCNT_RM>,
7112                       Sched<[WriteFAddLd]>, OpSize16, XS;
7113
7114   def POPCNT32rr : I<0xB8, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
7115                      "popcnt{l}\t{$src, $dst|$dst, $src}",
7116                      [(set GR32:$dst, (ctpop GR32:$src)), (implicit EFLAGS)],
7117                      IIC_SSE_POPCNT_RR>, Sched<[WriteFAdd]>,
7118                      OpSize32, XS;
7119
7120   def POPCNT32rm : I<0xB8, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
7121                      "popcnt{l}\t{$src, $dst|$dst, $src}",
7122                      [(set GR32:$dst, (ctpop (loadi32 addr:$src))),
7123                       (implicit EFLAGS)], IIC_SSE_POPCNT_RM>,
7124                       Sched<[WriteFAddLd]>, OpSize32, XS;
7125
7126   def POPCNT64rr : RI<0xB8, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
7127                       "popcnt{q}\t{$src, $dst|$dst, $src}",
7128                       [(set GR64:$dst, (ctpop GR64:$src)), (implicit EFLAGS)],
7129                       IIC_SSE_POPCNT_RR>, Sched<[WriteFAdd]>, XS;
7130   def POPCNT64rm : RI<0xB8, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
7131                       "popcnt{q}\t{$src, $dst|$dst, $src}",
7132                       [(set GR64:$dst, (ctpop (loadi64 addr:$src))),
7133                        (implicit EFLAGS)], IIC_SSE_POPCNT_RM>,
7134                        Sched<[WriteFAddLd]>, XS;
7135 }
7136
7137
7138
7139 // SS41I_unop_rm_int_v16 - SSE 4.1 unary operator whose type is v8i16.
7140 multiclass SS41I_unop_rm_int_v16<bits<8> opc, string OpcodeStr,
7141                                  Intrinsic IntId128,
7142                                  X86FoldableSchedWrite Sched> {
7143   def rr128 : SS48I<opc, MRMSrcReg, (outs VR128:$dst),
7144                     (ins VR128:$src),
7145                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
7146                     [(set VR128:$dst, (IntId128 VR128:$src))]>,
7147                     Sched<[Sched]>;
7148   def rm128 : SS48I<opc, MRMSrcMem, (outs VR128:$dst),
7149                      (ins i128mem:$src),
7150                      !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
7151                      [(set VR128:$dst,
7152                        (IntId128 (bitconvert (memopv2i64 addr:$src))))]>,
7153                     Sched<[Sched.Folded]>;
7154 }
7155
7156 // PHMIN has the same profile as PSAD, thus we use the same scheduling
7157 // model, although the naming is misleading.
7158 let Predicates = [HasAVX] in
7159 defm VPHMINPOSUW : SS41I_unop_rm_int_v16 <0x41, "vphminposuw",
7160                                          int_x86_sse41_phminposuw,
7161                                          WriteVecIMul>, VEX;
7162 defm PHMINPOSUW : SS41I_unop_rm_int_v16 <0x41, "phminposuw",
7163                                          int_x86_sse41_phminposuw,
7164                                          WriteVecIMul>;
7165
7166 /// SS41I_binop_rm_int - Simple SSE 4.1 binary operator
7167 multiclass SS41I_binop_rm_int<bits<8> opc, string OpcodeStr,
7168                               Intrinsic IntId128, bit Is2Addr = 1,
7169                               OpndItins itins = DEFAULT_ITINS> {
7170   let isCommutable = 1 in
7171   def rr : SS48I<opc, MRMSrcReg, (outs VR128:$dst),
7172        (ins VR128:$src1, VR128:$src2),
7173        !if(Is2Addr,
7174            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
7175            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
7176        [(set VR128:$dst, (IntId128 VR128:$src1, VR128:$src2))],
7177        itins.rr>, Sched<[itins.Sched]>;
7178   def rm : SS48I<opc, MRMSrcMem, (outs VR128:$dst),
7179        (ins VR128:$src1, i128mem:$src2),
7180        !if(Is2Addr,
7181            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
7182            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
7183        [(set VR128:$dst,
7184          (IntId128 VR128:$src1, (bitconvert (memopv2i64 addr:$src2))))],
7185        itins.rm>, Sched<[itins.Sched.Folded, ReadAfterLd]>;
7186 }
7187
7188 /// SS41I_binop_rm_int_y - Simple SSE 4.1 binary operator
7189 multiclass SS41I_binop_rm_int_y<bits<8> opc, string OpcodeStr,
7190                                 Intrinsic IntId256,
7191                                 X86FoldableSchedWrite Sched> {
7192   let isCommutable = 1 in
7193   def Yrr : SS48I<opc, MRMSrcReg, (outs VR256:$dst),
7194        (ins VR256:$src1, VR256:$src2),
7195        !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7196        [(set VR256:$dst, (IntId256 VR256:$src1, VR256:$src2))]>,
7197        Sched<[Sched]>;
7198   def Yrm : SS48I<opc, MRMSrcMem, (outs VR256:$dst),
7199        (ins VR256:$src1, i256mem:$src2),
7200        !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7201        [(set VR256:$dst,
7202          (IntId256 VR256:$src1, (bitconvert (loadv4i64 addr:$src2))))]>,
7203        Sched<[Sched.Folded, ReadAfterLd]>;
7204 }
7205
7206
7207 /// SS48I_binop_rm - Simple SSE41 binary operator.
7208 multiclass SS48I_binop_rm<bits<8> opc, string OpcodeStr, SDNode OpNode,
7209                           ValueType OpVT, RegisterClass RC, PatFrag memop_frag,
7210                           X86MemOperand x86memop, bit Is2Addr = 1,
7211                           OpndItins itins = SSE_INTALU_ITINS_P> {
7212   let isCommutable = 1 in
7213   def rr : SS48I<opc, MRMSrcReg, (outs RC:$dst),
7214        (ins RC:$src1, RC:$src2),
7215        !if(Is2Addr,
7216            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
7217            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
7218        [(set RC:$dst, (OpVT (OpNode RC:$src1, RC:$src2)))]>,
7219        Sched<[itins.Sched]>;
7220   def rm : SS48I<opc, MRMSrcMem, (outs RC:$dst),
7221        (ins RC:$src1, x86memop:$src2),
7222        !if(Is2Addr,
7223            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
7224            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
7225        [(set RC:$dst,
7226          (OpVT (OpNode RC:$src1, (bitconvert (memop_frag addr:$src2)))))]>,
7227        Sched<[itins.Sched.Folded, ReadAfterLd]>;
7228 }
7229
7230 /// SS48I_binop_rm2 - Simple SSE41 binary operator with different src and dst
7231 /// types.
7232 multiclass SS48I_binop_rm2<bits<8> opc, string OpcodeStr, SDNode OpNode,
7233                          ValueType DstVT, ValueType SrcVT, RegisterClass RC,
7234                          PatFrag memop_frag, X86MemOperand x86memop,
7235                          OpndItins itins,
7236                          bit IsCommutable = 0, bit Is2Addr = 1> {
7237   let isCommutable = IsCommutable in
7238   def rr : SS48I<opc, MRMSrcReg, (outs RC:$dst),
7239        (ins RC:$src1, RC:$src2),
7240        !if(Is2Addr,
7241            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
7242            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
7243        [(set RC:$dst, (DstVT (OpNode (SrcVT RC:$src1), RC:$src2)))]>,
7244        Sched<[itins.Sched]>;
7245   def rm : SS48I<opc, MRMSrcMem, (outs RC:$dst),
7246        (ins RC:$src1, x86memop:$src2),
7247        !if(Is2Addr,
7248            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
7249            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
7250        [(set RC:$dst, (DstVT (OpNode (SrcVT RC:$src1),
7251                                      (bitconvert (memop_frag addr:$src2)))))]>,
7252        Sched<[itins.Sched.Folded, ReadAfterLd]>;
7253 }
7254
7255 let Predicates = [HasAVX] in {
7256   let isCommutable = 0 in
7257   defm VPMINSB   : SS48I_binop_rm<0x38, "vpminsb", X86smin, v16i8, VR128,
7258                                   loadv2i64, i128mem, 0, SSE_INTALU_ITINS_P>,
7259                                   VEX_4V;
7260   defm VPMINSD   : SS48I_binop_rm<0x39, "vpminsd", X86smin, v4i32, VR128,
7261                                   loadv2i64, i128mem, 0, SSE_INTALU_ITINS_P>,
7262                                   VEX_4V;
7263   defm VPMINUD   : SS48I_binop_rm<0x3B, "vpminud", X86umin, v4i32, VR128,
7264                                   loadv2i64, i128mem, 0, SSE_INTALU_ITINS_P>,
7265                                   VEX_4V;
7266   defm VPMINUW   : SS48I_binop_rm<0x3A, "vpminuw", X86umin, v8i16, VR128,
7267                                   loadv2i64, i128mem, 0, SSE_INTALU_ITINS_P>,
7268                                   VEX_4V;
7269   defm VPMAXSB   : SS48I_binop_rm<0x3C, "vpmaxsb", X86smax, v16i8, VR128,
7270                                   loadv2i64, i128mem, 0, SSE_INTALU_ITINS_P>,
7271                                   VEX_4V;
7272   defm VPMAXSD   : SS48I_binop_rm<0x3D, "vpmaxsd", X86smax, v4i32, VR128,
7273                                   loadv2i64, i128mem, 0, SSE_INTALU_ITINS_P>,
7274                                   VEX_4V;
7275   defm VPMAXUD   : SS48I_binop_rm<0x3F, "vpmaxud", X86umax, v4i32, VR128,
7276                                   loadv2i64, i128mem, 0, SSE_INTALU_ITINS_P>,
7277                                   VEX_4V;
7278   defm VPMAXUW   : SS48I_binop_rm<0x3E, "vpmaxuw", X86umax, v8i16, VR128,
7279                                   loadv2i64, i128mem, 0, SSE_INTALU_ITINS_P>,
7280                                   VEX_4V;
7281   defm VPMULDQ   : SS48I_binop_rm2<0x28, "vpmuldq", X86pmuldq, v2i64, v4i32,
7282                                    VR128, loadv2i64, i128mem,
7283                                    SSE_INTMUL_ITINS_P, 1, 0>, VEX_4V;
7284 }
7285
7286 let Predicates = [HasAVX2] in {
7287   let isCommutable = 0 in
7288   defm VPMINSBY  : SS48I_binop_rm<0x38, "vpminsb", X86smin, v32i8, VR256,
7289                                   loadv4i64, i256mem, 0, SSE_INTALU_ITINS_P>,
7290                                   VEX_4V, VEX_L;
7291   defm VPMINSDY  : SS48I_binop_rm<0x39, "vpminsd", X86smin, v8i32, VR256,
7292                                   loadv4i64, i256mem, 0, SSE_INTALU_ITINS_P>,
7293                                   VEX_4V, VEX_L;
7294   defm VPMINUDY  : SS48I_binop_rm<0x3B, "vpminud", X86umin, v8i32, VR256,
7295                                   loadv4i64, i256mem, 0, SSE_INTALU_ITINS_P>,
7296                                   VEX_4V, VEX_L;
7297   defm VPMINUWY  : SS48I_binop_rm<0x3A, "vpminuw", X86umin, v16i16, VR256,
7298                                   loadv4i64, i256mem, 0, SSE_INTALU_ITINS_P>,
7299                                   VEX_4V, VEX_L;
7300   defm VPMAXSBY  : SS48I_binop_rm<0x3C, "vpmaxsb", X86smax, v32i8, VR256,
7301                                   loadv4i64, i256mem, 0, SSE_INTALU_ITINS_P>,
7302                                   VEX_4V, VEX_L;
7303   defm VPMAXSDY  : SS48I_binop_rm<0x3D, "vpmaxsd", X86smax, v8i32, VR256,
7304                                   loadv4i64, i256mem, 0, SSE_INTALU_ITINS_P>,
7305                                   VEX_4V, VEX_L;
7306   defm VPMAXUDY  : SS48I_binop_rm<0x3F, "vpmaxud", X86umax, v8i32, VR256,
7307                                   loadv4i64, i256mem, 0, SSE_INTALU_ITINS_P>,
7308                                   VEX_4V, VEX_L;
7309   defm VPMAXUWY  : SS48I_binop_rm<0x3E, "vpmaxuw", X86umax, v16i16, VR256,
7310                                   loadv4i64, i256mem, 0, SSE_INTALU_ITINS_P>,
7311                                   VEX_4V, VEX_L;
7312   defm VPMULDQY : SS48I_binop_rm2<0x28, "vpmuldq", X86pmuldq, v4i64, v8i32,
7313                                   VR256, loadv4i64, i256mem,
7314                                   SSE_INTMUL_ITINS_P, 1, 0>, VEX_4V, VEX_L;
7315 }
7316
7317 let Constraints = "$src1 = $dst" in {
7318   let isCommutable = 0 in
7319   defm PMINSB   : SS48I_binop_rm<0x38, "pminsb", X86smin, v16i8, VR128,
7320                                  memopv2i64, i128mem, 1, SSE_INTALU_ITINS_P>;
7321   defm PMINSD   : SS48I_binop_rm<0x39, "pminsd", X86smin, v4i32, VR128,
7322                                  memopv2i64, i128mem, 1, SSE_INTALU_ITINS_P>;
7323   defm PMINUD   : SS48I_binop_rm<0x3B, "pminud", X86umin, v4i32, VR128,
7324                                  memopv2i64, i128mem, 1, SSE_INTALU_ITINS_P>;
7325   defm PMINUW   : SS48I_binop_rm<0x3A, "pminuw", X86umin, v8i16, VR128,
7326                                  memopv2i64, i128mem, 1, SSE_INTALU_ITINS_P>;
7327   defm PMAXSB   : SS48I_binop_rm<0x3C, "pmaxsb", X86smax, v16i8, VR128,
7328                                  memopv2i64, i128mem, 1, SSE_INTALU_ITINS_P>;
7329   defm PMAXSD   : SS48I_binop_rm<0x3D, "pmaxsd", X86smax, v4i32, VR128,
7330                                  memopv2i64, i128mem, 1, SSE_INTALU_ITINS_P>;
7331   defm PMAXUD   : SS48I_binop_rm<0x3F, "pmaxud", X86umax, v4i32, VR128,
7332                                  memopv2i64, i128mem, 1, SSE_INTALU_ITINS_P>;
7333   defm PMAXUW   : SS48I_binop_rm<0x3E, "pmaxuw", X86umax, v8i16, VR128,
7334                                  memopv2i64, i128mem, 1, SSE_INTALU_ITINS_P>;
7335   defm PMULDQ   : SS48I_binop_rm2<0x28, "pmuldq", X86pmuldq, v2i64, v4i32,
7336                                   VR128, memopv2i64, i128mem,
7337                                   SSE_INTMUL_ITINS_P, 1>;
7338 }
7339
7340 let Predicates = [HasAVX] in {
7341   defm VPMULLD  : SS48I_binop_rm<0x40, "vpmulld", mul, v4i32, VR128,
7342                                  memopv2i64, i128mem, 0, SSE_PMULLD_ITINS>,
7343                                  VEX_4V;
7344   defm VPCMPEQQ : SS48I_binop_rm<0x29, "vpcmpeqq", X86pcmpeq, v2i64, VR128,
7345                                  memopv2i64, i128mem, 0, SSE_INTALU_ITINS_P>,
7346                                  VEX_4V;
7347 }
7348 let Predicates = [HasAVX2] in {
7349   defm VPMULLDY  : SS48I_binop_rm<0x40, "vpmulld", mul, v8i32, VR256,
7350                                   memopv4i64, i256mem, 0, SSE_PMULLD_ITINS>,
7351                                   VEX_4V, VEX_L;
7352   defm VPCMPEQQY : SS48I_binop_rm<0x29, "vpcmpeqq", X86pcmpeq, v4i64, VR256,
7353                                   memopv4i64, i256mem, 0, SSE_INTALU_ITINS_P>,
7354                                   VEX_4V, VEX_L;
7355 }
7356
7357 let Constraints = "$src1 = $dst" in {
7358   defm PMULLD  : SS48I_binop_rm<0x40, "pmulld", mul, v4i32, VR128,
7359                                 memopv2i64, i128mem, 1, SSE_PMULLD_ITINS>;
7360   defm PCMPEQQ : SS48I_binop_rm<0x29, "pcmpeqq", X86pcmpeq, v2i64, VR128,
7361                                 memopv2i64, i128mem, 1, SSE_INTALUQ_ITINS_P>;
7362 }
7363
7364 /// SS41I_binop_rmi_int - SSE 4.1 binary operator with 8-bit immediate
7365 multiclass SS41I_binop_rmi_int<bits<8> opc, string OpcodeStr,
7366                  Intrinsic IntId, RegisterClass RC, PatFrag memop_frag,
7367                  X86MemOperand x86memop, bit Is2Addr = 1,
7368                  OpndItins itins = DEFAULT_ITINS> {
7369   let isCommutable = 1 in
7370   def rri : SS4AIi8<opc, MRMSrcReg, (outs RC:$dst),
7371         (ins RC:$src1, RC:$src2, i8imm:$src3),
7372         !if(Is2Addr,
7373             !strconcat(OpcodeStr,
7374                 "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
7375             !strconcat(OpcodeStr,
7376                 "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
7377         [(set RC:$dst, (IntId RC:$src1, RC:$src2, imm:$src3))], itins.rr>,
7378         Sched<[itins.Sched]>;
7379   def rmi : SS4AIi8<opc, MRMSrcMem, (outs RC:$dst),
7380         (ins RC:$src1, x86memop:$src2, i8imm:$src3),
7381         !if(Is2Addr,
7382             !strconcat(OpcodeStr,
7383                 "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
7384             !strconcat(OpcodeStr,
7385                 "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
7386         [(set RC:$dst,
7387           (IntId RC:$src1,
7388            (bitconvert (memop_frag addr:$src2)), imm:$src3))], itins.rm>,
7389         Sched<[itins.Sched.Folded, ReadAfterLd]>;
7390 }
7391
7392 let Predicates = [HasAVX] in {
7393   let isCommutable = 0 in {
7394     let ExeDomain = SSEPackedSingle in {
7395     defm VBLENDPS : SS41I_binop_rmi_int<0x0C, "vblendps", int_x86_sse41_blendps,
7396                                         VR128, loadv4f32, f128mem, 0,
7397                                         DEFAULT_ITINS_FBLENDSCHED>, VEX_4V;
7398     defm VBLENDPSY : SS41I_binop_rmi_int<0x0C, "vblendps",
7399                                     int_x86_avx_blend_ps_256, VR256, loadv8f32,
7400                                     f256mem, 0, DEFAULT_ITINS_FBLENDSCHED>,
7401                                     VEX_4V, VEX_L;
7402     }
7403     let ExeDomain = SSEPackedDouble in {
7404     defm VBLENDPD : SS41I_binop_rmi_int<0x0D, "vblendpd", int_x86_sse41_blendpd,
7405                                         VR128, loadv2f64, f128mem, 0,
7406                                         DEFAULT_ITINS_FBLENDSCHED>, VEX_4V;
7407     defm VBLENDPDY : SS41I_binop_rmi_int<0x0D, "vblendpd",
7408                                      int_x86_avx_blend_pd_256,VR256, loadv4f64,
7409                                      f256mem, 0, DEFAULT_ITINS_FBLENDSCHED>,
7410                                      VEX_4V, VEX_L;
7411     }
7412   defm VPBLENDW : SS41I_binop_rmi_int<0x0E, "vpblendw", int_x86_sse41_pblendw,
7413                                       VR128, loadv2i64, i128mem, 0,
7414                                       DEFAULT_ITINS_BLENDSCHED>, VEX_4V;
7415   defm VMPSADBW : SS41I_binop_rmi_int<0x42, "vmpsadbw", int_x86_sse41_mpsadbw,
7416                                       VR128, loadv2i64, i128mem, 0,
7417                                       DEFAULT_ITINS_MPSADSCHED>, VEX_4V;
7418   }
7419   let ExeDomain = SSEPackedSingle in
7420   defm VDPPS : SS41I_binop_rmi_int<0x40, "vdpps", int_x86_sse41_dpps,
7421                                    VR128, loadv4f32, f128mem, 0,
7422                                    SSE_DPPS_ITINS>, VEX_4V;
7423   let ExeDomain = SSEPackedDouble in
7424   defm VDPPD : SS41I_binop_rmi_int<0x41, "vdppd", int_x86_sse41_dppd,
7425                                    VR128, loadv2f64, f128mem, 0,
7426                                    SSE_DPPS_ITINS>, VEX_4V;
7427   let ExeDomain = SSEPackedSingle in
7428   defm VDPPSY : SS41I_binop_rmi_int<0x40, "vdpps", int_x86_avx_dp_ps_256,
7429                                     VR256, loadv8f32, i256mem, 0,
7430                                     SSE_DPPS_ITINS>, VEX_4V, VEX_L;
7431 }
7432
7433 let Predicates = [HasAVX2] in {
7434   let isCommutable = 0 in {
7435   defm VPBLENDWY : SS41I_binop_rmi_int<0x0E, "vpblendw", int_x86_avx2_pblendw,
7436                                   VR256, loadv4i64, i256mem, 0,
7437                                   DEFAULT_ITINS_BLENDSCHED>, VEX_4V, VEX_L;
7438   defm VMPSADBWY : SS41I_binop_rmi_int<0x42, "vmpsadbw", int_x86_avx2_mpsadbw,
7439                                   VR256, loadv4i64, i256mem, 0,
7440                                   DEFAULT_ITINS_MPSADSCHED>, VEX_4V, VEX_L;
7441   }
7442 }
7443
7444 let Constraints = "$src1 = $dst" in {
7445   let isCommutable = 0 in {
7446   let ExeDomain = SSEPackedSingle in
7447   defm BLENDPS : SS41I_binop_rmi_int<0x0C, "blendps", int_x86_sse41_blendps,
7448                                      VR128, memopv4f32, f128mem,
7449                                      1, SSE_INTALU_ITINS_FBLEND_P>;
7450   let ExeDomain = SSEPackedDouble in
7451   defm BLENDPD : SS41I_binop_rmi_int<0x0D, "blendpd", int_x86_sse41_blendpd,
7452                                      VR128, memopv2f64, f128mem,
7453                                      1, SSE_INTALU_ITINS_FBLEND_P>;
7454   defm PBLENDW : SS41I_binop_rmi_int<0x0E, "pblendw", int_x86_sse41_pblendw,
7455                                      VR128, memopv2i64, i128mem,
7456                                      1, SSE_INTALU_ITINS_BLEND_P>;
7457   defm MPSADBW : SS41I_binop_rmi_int<0x42, "mpsadbw", int_x86_sse41_mpsadbw,
7458                                      VR128, memopv2i64, i128mem,
7459                                      1, SSE_MPSADBW_ITINS>;
7460   }
7461   let ExeDomain = SSEPackedSingle in
7462   defm DPPS : SS41I_binop_rmi_int<0x40, "dpps", int_x86_sse41_dpps,
7463                                   VR128, memopv4f32, f128mem, 1,
7464                                   SSE_DPPS_ITINS>;
7465   let ExeDomain = SSEPackedDouble in
7466   defm DPPD : SS41I_binop_rmi_int<0x41, "dppd", int_x86_sse41_dppd,
7467                                   VR128, memopv2f64, f128mem, 1,
7468                                   SSE_DPPD_ITINS>;
7469 }
7470
7471 /// SS41I_quaternary_int_avx - AVX SSE 4.1 with 4 operators
7472 multiclass SS41I_quaternary_int_avx<bits<8> opc, string OpcodeStr,
7473                                     RegisterClass RC, X86MemOperand x86memop,
7474                                     PatFrag mem_frag, Intrinsic IntId,
7475                                     X86FoldableSchedWrite Sched> {
7476   def rr : Ii8<opc, MRMSrcReg, (outs RC:$dst),
7477                   (ins RC:$src1, RC:$src2, RC:$src3),
7478                   !strconcat(OpcodeStr,
7479                     "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
7480                   [(set RC:$dst, (IntId RC:$src1, RC:$src2, RC:$src3))],
7481                   NoItinerary, SSEPackedInt>, TAPD, VEX_4V, VEX_I8IMM,
7482                 Sched<[Sched]>;
7483
7484   def rm : Ii8<opc, MRMSrcMem, (outs RC:$dst),
7485                   (ins RC:$src1, x86memop:$src2, RC:$src3),
7486                   !strconcat(OpcodeStr,
7487                     "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
7488                   [(set RC:$dst,
7489                         (IntId RC:$src1, (bitconvert (mem_frag addr:$src2)),
7490                                RC:$src3))],
7491                   NoItinerary, SSEPackedInt>, TAPD, VEX_4V, VEX_I8IMM,
7492                 Sched<[Sched.Folded, ReadAfterLd]>;
7493 }
7494
7495 let Predicates = [HasAVX] in {
7496 let ExeDomain = SSEPackedDouble in {
7497 defm VBLENDVPD  : SS41I_quaternary_int_avx<0x4B, "vblendvpd", VR128, f128mem,
7498                                            loadv2f64, int_x86_sse41_blendvpd,
7499                                            WriteFVarBlend>;
7500 defm VBLENDVPDY : SS41I_quaternary_int_avx<0x4B, "vblendvpd", VR256, f256mem,
7501                                   loadv4f64, int_x86_avx_blendv_pd_256,
7502                                   WriteFVarBlend>, VEX_L;
7503 } // ExeDomain = SSEPackedDouble
7504 let ExeDomain = SSEPackedSingle in {
7505 defm VBLENDVPS  : SS41I_quaternary_int_avx<0x4A, "vblendvps", VR128, f128mem,
7506                                            loadv4f32, int_x86_sse41_blendvps,
7507                                            WriteFVarBlend>;
7508 defm VBLENDVPSY : SS41I_quaternary_int_avx<0x4A, "vblendvps", VR256, f256mem,
7509                                   loadv8f32, int_x86_avx_blendv_ps_256,
7510                                   WriteFVarBlend>, VEX_L;
7511 } // ExeDomain = SSEPackedSingle
7512 defm VPBLENDVB  : SS41I_quaternary_int_avx<0x4C, "vpblendvb", VR128, i128mem,
7513                                            loadv2i64, int_x86_sse41_pblendvb,
7514                                            WriteVarBlend>;
7515 }
7516
7517 let Predicates = [HasAVX2] in {
7518 defm VPBLENDVBY : SS41I_quaternary_int_avx<0x4C, "vpblendvb", VR256, i256mem,
7519                                       loadv4i64, int_x86_avx2_pblendvb,
7520                                       WriteVarBlend>, VEX_L;
7521 }
7522
7523 let Predicates = [HasAVX] in {
7524   def : Pat<(v16i8 (vselect (v16i8 VR128:$mask), (v16i8 VR128:$src1),
7525                             (v16i8 VR128:$src2))),
7526             (VPBLENDVBrr VR128:$src2, VR128:$src1, VR128:$mask)>;
7527   def : Pat<(v4i32 (vselect (v4i32 VR128:$mask), (v4i32 VR128:$src1),
7528                             (v4i32 VR128:$src2))),
7529             (VBLENDVPSrr VR128:$src2, VR128:$src1, VR128:$mask)>;
7530   def : Pat<(v4f32 (vselect (v4i32 VR128:$mask), (v4f32 VR128:$src1),
7531                             (v4f32 VR128:$src2))),
7532             (VBLENDVPSrr VR128:$src2, VR128:$src1, VR128:$mask)>;
7533   def : Pat<(v2i64 (vselect (v2i64 VR128:$mask), (v2i64 VR128:$src1),
7534                             (v2i64 VR128:$src2))),
7535             (VBLENDVPDrr VR128:$src2, VR128:$src1, VR128:$mask)>;
7536   def : Pat<(v2f64 (vselect (v2i64 VR128:$mask), (v2f64 VR128:$src1),
7537                             (v2f64 VR128:$src2))),
7538             (VBLENDVPDrr VR128:$src2, VR128:$src1, VR128:$mask)>;
7539   def : Pat<(v8i32 (vselect (v8i32 VR256:$mask), (v8i32 VR256:$src1),
7540                             (v8i32 VR256:$src2))),
7541             (VBLENDVPSYrr VR256:$src2, VR256:$src1, VR256:$mask)>;
7542   def : Pat<(v8f32 (vselect (v8i32 VR256:$mask), (v8f32 VR256:$src1),
7543                             (v8f32 VR256:$src2))),
7544             (VBLENDVPSYrr VR256:$src2, VR256:$src1, VR256:$mask)>;
7545   def : Pat<(v4i64 (vselect (v4i64 VR256:$mask), (v4i64 VR256:$src1),
7546                             (v4i64 VR256:$src2))),
7547             (VBLENDVPDYrr VR256:$src2, VR256:$src1, VR256:$mask)>;
7548   def : Pat<(v4f64 (vselect (v4i64 VR256:$mask), (v4f64 VR256:$src1),
7549                             (v4f64 VR256:$src2))),
7550             (VBLENDVPDYrr VR256:$src2, VR256:$src1, VR256:$mask)>;
7551
7552   def : Pat<(v8f32 (X86Blendi (v8f32 VR256:$src1), (v8f32 VR256:$src2),
7553                                (imm:$mask))),
7554             (VBLENDPSYrri VR256:$src1, VR256:$src2, imm:$mask)>;
7555   def : Pat<(v4f64 (X86Blendi (v4f64 VR256:$src1), (v4f64 VR256:$src2),
7556                                (imm:$mask))),
7557             (VBLENDPDYrri VR256:$src1, VR256:$src2, imm:$mask)>;
7558
7559   def : Pat<(v8i16 (X86Blendi (v8i16 VR128:$src1), (v8i16 VR128:$src2),
7560                                (imm:$mask))),
7561             (VPBLENDWrri VR128:$src1, VR128:$src2, imm:$mask)>;
7562   def : Pat<(v4f32 (X86Blendi (v4f32 VR128:$src1), (v4f32 VR128:$src2),
7563                                (imm:$mask))),
7564             (VBLENDPSrri VR128:$src1, VR128:$src2, imm:$mask)>;
7565   def : Pat<(v2f64 (X86Blendi (v2f64 VR128:$src1), (v2f64 VR128:$src2),
7566                                (imm:$mask))),
7567             (VBLENDPDrri VR128:$src1, VR128:$src2, imm:$mask)>;
7568 }
7569
7570 let Predicates = [HasAVX2] in {
7571   def : Pat<(v32i8 (vselect (v32i8 VR256:$mask), (v32i8 VR256:$src1),
7572                             (v32i8 VR256:$src2))),
7573             (VPBLENDVBYrr VR256:$src2, VR256:$src1, VR256:$mask)>;
7574   def : Pat<(v16i16 (X86Blendi (v16i16 VR256:$src1), (v16i16 VR256:$src2),
7575                                (imm:$mask))),
7576             (VPBLENDWYrri VR256:$src1, VR256:$src2, imm:$mask)>;
7577 }
7578
7579 /// SS41I_ternary_int - SSE 4.1 ternary operator
7580 let Uses = [XMM0], Constraints = "$src1 = $dst" in {
7581   multiclass SS41I_ternary_int<bits<8> opc, string OpcodeStr, PatFrag mem_frag,
7582                                X86MemOperand x86memop, Intrinsic IntId,
7583                                OpndItins itins = DEFAULT_ITINS> {
7584     def rr0 : SS48I<opc, MRMSrcReg, (outs VR128:$dst),
7585                     (ins VR128:$src1, VR128:$src2),
7586                     !strconcat(OpcodeStr,
7587                      "\t{$src2, $dst|$dst, $src2}"),
7588                     [(set VR128:$dst, (IntId VR128:$src1, VR128:$src2, XMM0))],
7589                     itins.rr>, Sched<[itins.Sched]>;
7590
7591     def rm0 : SS48I<opc, MRMSrcMem, (outs VR128:$dst),
7592                     (ins VR128:$src1, x86memop:$src2),
7593                     !strconcat(OpcodeStr,
7594                      "\t{$src2, $dst|$dst, $src2}"),
7595                     [(set VR128:$dst,
7596                       (IntId VR128:$src1,
7597                        (bitconvert (mem_frag addr:$src2)), XMM0))],
7598                        itins.rm>, Sched<[itins.Sched.Folded, ReadAfterLd]>;
7599   }
7600 }
7601
7602 let ExeDomain = SSEPackedDouble in
7603 defm BLENDVPD : SS41I_ternary_int<0x15, "blendvpd", memopv2f64, f128mem,
7604                                   int_x86_sse41_blendvpd,
7605                                   DEFAULT_ITINS_FBLENDSCHED>;
7606 let ExeDomain = SSEPackedSingle in
7607 defm BLENDVPS : SS41I_ternary_int<0x14, "blendvps", memopv4f32, f128mem,
7608                                   int_x86_sse41_blendvps,
7609                                   DEFAULT_ITINS_FBLENDSCHED>;
7610 defm PBLENDVB : SS41I_ternary_int<0x10, "pblendvb", memopv2i64, i128mem,
7611                                   int_x86_sse41_pblendvb,
7612                                   DEFAULT_ITINS_VARBLENDSCHED>;
7613
7614 // Aliases with the implicit xmm0 argument
7615 def : InstAlias<"blendvpd\t{%xmm0, $src2, $dst|$dst, $src2, xmm0}",
7616                 (BLENDVPDrr0 VR128:$dst, VR128:$src2)>;
7617 def : InstAlias<"blendvpd\t{%xmm0, $src2, $dst|$dst, $src2, xmm0}",
7618                 (BLENDVPDrm0 VR128:$dst, f128mem:$src2)>;
7619 def : InstAlias<"blendvps\t{%xmm0, $src2, $dst|$dst, $src2, xmm0}",
7620                 (BLENDVPSrr0 VR128:$dst, VR128:$src2)>;
7621 def : InstAlias<"blendvps\t{%xmm0, $src2, $dst|$dst, $src2, xmm0}",
7622                 (BLENDVPSrm0 VR128:$dst, f128mem:$src2)>;
7623 def : InstAlias<"pblendvb\t{%xmm0, $src2, $dst|$dst, $src2, xmm0}",
7624                 (PBLENDVBrr0 VR128:$dst, VR128:$src2)>;
7625 def : InstAlias<"pblendvb\t{%xmm0, $src2, $dst|$dst, $src2, xmm0}",
7626                 (PBLENDVBrm0 VR128:$dst, i128mem:$src2)>;
7627
7628 let Predicates = [UseSSE41] in {
7629   def : Pat<(v16i8 (vselect (v16i8 XMM0), (v16i8 VR128:$src1),
7630                             (v16i8 VR128:$src2))),
7631             (PBLENDVBrr0 VR128:$src2, VR128:$src1)>;
7632   def : Pat<(v4i32 (vselect (v4i32 XMM0), (v4i32 VR128:$src1),
7633                             (v4i32 VR128:$src2))),
7634             (BLENDVPSrr0 VR128:$src2, VR128:$src1)>;
7635   def : Pat<(v4f32 (vselect (v4i32 XMM0), (v4f32 VR128:$src1),
7636                             (v4f32 VR128:$src2))),
7637             (BLENDVPSrr0 VR128:$src2, VR128:$src1)>;
7638   def : Pat<(v2i64 (vselect (v2i64 XMM0), (v2i64 VR128:$src1),
7639                             (v2i64 VR128:$src2))),
7640             (BLENDVPDrr0 VR128:$src2, VR128:$src1)>;
7641   def : Pat<(v2f64 (vselect (v2i64 XMM0), (v2f64 VR128:$src1),
7642                             (v2f64 VR128:$src2))),
7643             (BLENDVPDrr0 VR128:$src2, VR128:$src1)>;
7644
7645   def : Pat<(v8i16 (X86Blendi (v8i16 VR128:$src1), (v8i16 VR128:$src2),
7646                                (imm:$mask))),
7647             (PBLENDWrri VR128:$src1, VR128:$src2, imm:$mask)>;
7648   def : Pat<(v4f32 (X86Blendi (v4f32 VR128:$src1), (v4f32 VR128:$src2),
7649                                (imm:$mask))),
7650             (BLENDPSrri VR128:$src1, VR128:$src2, imm:$mask)>;
7651   def : Pat<(v2f64 (X86Blendi (v2f64 VR128:$src1), (v2f64 VR128:$src2),
7652                                (imm:$mask))),
7653             (BLENDPDrri VR128:$src1, VR128:$src2, imm:$mask)>;
7654
7655 }
7656
7657 let SchedRW = [WriteLoad] in {
7658 let Predicates = [HasAVX] in
7659 def VMOVNTDQArm : SS48I<0x2A, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
7660                        "vmovntdqa\t{$src, $dst|$dst, $src}",
7661                        [(set VR128:$dst, (int_x86_sse41_movntdqa addr:$src))]>,
7662                        VEX;
7663 let Predicates = [HasAVX2] in
7664 def VMOVNTDQAYrm : SS48I<0x2A, MRMSrcMem, (outs VR256:$dst), (ins i256mem:$src),
7665                          "vmovntdqa\t{$src, $dst|$dst, $src}",
7666                          [(set VR256:$dst, (int_x86_avx2_movntdqa addr:$src))]>,
7667                          VEX, VEX_L;
7668 def MOVNTDQArm : SS48I<0x2A, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
7669                        "movntdqa\t{$src, $dst|$dst, $src}",
7670                        [(set VR128:$dst, (int_x86_sse41_movntdqa addr:$src))]>;
7671 } // SchedRW
7672
7673 //===----------------------------------------------------------------------===//
7674 // SSE4.2 - Compare Instructions
7675 //===----------------------------------------------------------------------===//
7676
7677 /// SS42I_binop_rm - Simple SSE 4.2 binary operator
7678 multiclass SS42I_binop_rm<bits<8> opc, string OpcodeStr, SDNode OpNode,
7679                           ValueType OpVT, RegisterClass RC, PatFrag memop_frag,
7680                           X86MemOperand x86memop, bit Is2Addr = 1> {
7681   def rr : SS428I<opc, MRMSrcReg, (outs RC:$dst),
7682        (ins RC:$src1, RC:$src2),
7683        !if(Is2Addr,
7684            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
7685            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
7686        [(set RC:$dst, (OpVT (OpNode RC:$src1, RC:$src2)))]>;
7687   def rm : SS428I<opc, MRMSrcMem, (outs RC:$dst),
7688        (ins RC:$src1, x86memop:$src2),
7689        !if(Is2Addr,
7690            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
7691            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
7692        [(set RC:$dst,
7693          (OpVT (OpNode RC:$src1, (memop_frag addr:$src2))))]>;
7694 }
7695
7696 let Predicates = [HasAVX] in
7697   defm VPCMPGTQ : SS42I_binop_rm<0x37, "vpcmpgtq", X86pcmpgt, v2i64, VR128,
7698                                  loadv2i64, i128mem, 0>, VEX_4V;
7699
7700 let Predicates = [HasAVX2] in
7701   defm VPCMPGTQY : SS42I_binop_rm<0x37, "vpcmpgtq", X86pcmpgt, v4i64, VR256,
7702                                   loadv4i64, i256mem, 0>, VEX_4V, VEX_L;
7703
7704 let Constraints = "$src1 = $dst" in
7705   defm PCMPGTQ : SS42I_binop_rm<0x37, "pcmpgtq", X86pcmpgt, v2i64, VR128,
7706                                 memopv2i64, i128mem>;
7707
7708 //===----------------------------------------------------------------------===//
7709 // SSE4.2 - String/text Processing Instructions
7710 //===----------------------------------------------------------------------===//
7711
7712 // Packed Compare Implicit Length Strings, Return Mask
7713 multiclass pseudo_pcmpistrm<string asm> {
7714   def REG : PseudoI<(outs VR128:$dst),
7715                     (ins VR128:$src1, VR128:$src2, i8imm:$src3),
7716     [(set VR128:$dst, (int_x86_sse42_pcmpistrm128 VR128:$src1, VR128:$src2,
7717                                                   imm:$src3))]>;
7718   def MEM : PseudoI<(outs VR128:$dst),
7719                     (ins VR128:$src1, i128mem:$src2, i8imm:$src3),
7720     [(set VR128:$dst, (int_x86_sse42_pcmpistrm128 VR128:$src1,
7721                        (bc_v16i8 (memopv2i64 addr:$src2)), imm:$src3))]>;
7722 }
7723
7724 let Defs = [EFLAGS], usesCustomInserter = 1 in {
7725   defm VPCMPISTRM128 : pseudo_pcmpistrm<"#VPCMPISTRM128">, Requires<[HasAVX]>;
7726   defm PCMPISTRM128 : pseudo_pcmpistrm<"#PCMPISTRM128">, Requires<[UseSSE42]>;
7727 }
7728
7729 multiclass pcmpistrm_SS42AI<string asm> {
7730   def rr : SS42AI<0x62, MRMSrcReg, (outs),
7731     (ins VR128:$src1, VR128:$src2, i8imm:$src3),
7732     !strconcat(asm, "\t{$src3, $src2, $src1|$src1, $src2, $src3}"),
7733     []>, Sched<[WritePCmpIStrM]>;
7734   let mayLoad = 1 in
7735   def rm :SS42AI<0x62, MRMSrcMem, (outs),
7736     (ins VR128:$src1, i128mem:$src2, i8imm:$src3),
7737     !strconcat(asm, "\t{$src3, $src2, $src1|$src1, $src2, $src3}"),
7738     []>, Sched<[WritePCmpIStrMLd, ReadAfterLd]>;
7739 }
7740
7741 let Defs = [XMM0, EFLAGS], neverHasSideEffects = 1 in {
7742   let Predicates = [HasAVX] in
7743   defm VPCMPISTRM128 : pcmpistrm_SS42AI<"vpcmpistrm">, VEX;
7744   defm PCMPISTRM128  : pcmpistrm_SS42AI<"pcmpistrm"> ;
7745 }
7746
7747 // Packed Compare Explicit Length Strings, Return Mask
7748 multiclass pseudo_pcmpestrm<string asm> {
7749   def REG : PseudoI<(outs VR128:$dst),
7750                     (ins VR128:$src1, VR128:$src3, i8imm:$src5),
7751     [(set VR128:$dst, (int_x86_sse42_pcmpestrm128
7752                        VR128:$src1, EAX, VR128:$src3, EDX, imm:$src5))]>;
7753   def MEM : PseudoI<(outs VR128:$dst),
7754                     (ins VR128:$src1, i128mem:$src3, i8imm:$src5),
7755     [(set VR128:$dst, (int_x86_sse42_pcmpestrm128 VR128:$src1, EAX,
7756                        (bc_v16i8 (memopv2i64 addr:$src3)), EDX, imm:$src5))]>;
7757 }
7758
7759 let Defs = [EFLAGS], Uses = [EAX, EDX], usesCustomInserter = 1 in {
7760   defm VPCMPESTRM128 : pseudo_pcmpestrm<"#VPCMPESTRM128">, Requires<[HasAVX]>;
7761   defm PCMPESTRM128 : pseudo_pcmpestrm<"#PCMPESTRM128">, Requires<[UseSSE42]>;
7762 }
7763
7764 multiclass SS42AI_pcmpestrm<string asm> {
7765   def rr : SS42AI<0x60, MRMSrcReg, (outs),
7766     (ins VR128:$src1, VR128:$src3, i8imm:$src5),
7767     !strconcat(asm, "\t{$src5, $src3, $src1|$src1, $src3, $src5}"),
7768     []>, Sched<[WritePCmpEStrM]>;
7769   let mayLoad = 1 in
7770   def rm : SS42AI<0x60, MRMSrcMem, (outs),
7771     (ins VR128:$src1, i128mem:$src3, i8imm:$src5),
7772     !strconcat(asm, "\t{$src5, $src3, $src1|$src1, $src3, $src5}"),
7773     []>, Sched<[WritePCmpEStrMLd, ReadAfterLd]>;
7774 }
7775
7776 let Defs = [XMM0, EFLAGS], Uses = [EAX, EDX], neverHasSideEffects = 1 in {
7777   let Predicates = [HasAVX] in
7778   defm VPCMPESTRM128 : SS42AI_pcmpestrm<"vpcmpestrm">, VEX;
7779   defm PCMPESTRM128 :  SS42AI_pcmpestrm<"pcmpestrm">;
7780 }
7781
7782 // Packed Compare Implicit Length Strings, Return Index
7783 multiclass pseudo_pcmpistri<string asm> {
7784   def REG : PseudoI<(outs GR32:$dst),
7785                     (ins VR128:$src1, VR128:$src2, i8imm:$src3),
7786     [(set GR32:$dst, EFLAGS,
7787       (X86pcmpistri VR128:$src1, VR128:$src2, imm:$src3))]>;
7788   def MEM : PseudoI<(outs GR32:$dst),
7789                     (ins VR128:$src1, i128mem:$src2, i8imm:$src3),
7790     [(set GR32:$dst, EFLAGS, (X86pcmpistri VR128:$src1,
7791                               (bc_v16i8 (memopv2i64 addr:$src2)), imm:$src3))]>;
7792 }
7793
7794 let Defs = [EFLAGS], usesCustomInserter = 1 in {
7795   defm VPCMPISTRI : pseudo_pcmpistri<"#VPCMPISTRI">, Requires<[HasAVX]>;
7796   defm PCMPISTRI  : pseudo_pcmpistri<"#PCMPISTRI">, Requires<[UseSSE42]>;
7797 }
7798
7799 multiclass SS42AI_pcmpistri<string asm> {
7800   def rr : SS42AI<0x63, MRMSrcReg, (outs),
7801     (ins VR128:$src1, VR128:$src2, i8imm:$src3),
7802     !strconcat(asm, "\t{$src3, $src2, $src1|$src1, $src2, $src3}"),
7803     []>, Sched<[WritePCmpIStrI]>;
7804   let mayLoad = 1 in
7805   def rm : SS42AI<0x63, MRMSrcMem, (outs),
7806     (ins VR128:$src1, i128mem:$src2, i8imm:$src3),
7807     !strconcat(asm, "\t{$src3, $src2, $src1|$src1, $src2, $src3}"),
7808     []>, Sched<[WritePCmpIStrILd, ReadAfterLd]>;
7809 }
7810
7811 let Defs = [ECX, EFLAGS], neverHasSideEffects = 1 in {
7812   let Predicates = [HasAVX] in
7813   defm VPCMPISTRI : SS42AI_pcmpistri<"vpcmpistri">, VEX;
7814   defm PCMPISTRI  : SS42AI_pcmpistri<"pcmpistri">;
7815 }
7816
7817 // Packed Compare Explicit Length Strings, Return Index
7818 multiclass pseudo_pcmpestri<string asm> {
7819   def REG : PseudoI<(outs GR32:$dst),
7820                     (ins VR128:$src1, VR128:$src3, i8imm:$src5),
7821     [(set GR32:$dst, EFLAGS,
7822       (X86pcmpestri VR128:$src1, EAX, VR128:$src3, EDX, imm:$src5))]>;
7823   def MEM : PseudoI<(outs GR32:$dst),
7824                     (ins VR128:$src1, i128mem:$src3, i8imm:$src5),
7825     [(set GR32:$dst, EFLAGS,
7826       (X86pcmpestri VR128:$src1, EAX, (bc_v16i8 (memopv2i64 addr:$src3)), EDX,
7827        imm:$src5))]>;
7828 }
7829
7830 let Defs = [EFLAGS], Uses = [EAX, EDX], usesCustomInserter = 1 in {
7831   defm VPCMPESTRI : pseudo_pcmpestri<"#VPCMPESTRI">, Requires<[HasAVX]>;
7832   defm PCMPESTRI  : pseudo_pcmpestri<"#PCMPESTRI">, Requires<[UseSSE42]>;
7833 }
7834
7835 multiclass SS42AI_pcmpestri<string asm> {
7836   def rr : SS42AI<0x61, MRMSrcReg, (outs),
7837     (ins VR128:$src1, VR128:$src3, i8imm:$src5),
7838     !strconcat(asm, "\t{$src5, $src3, $src1|$src1, $src3, $src5}"),
7839     []>, Sched<[WritePCmpEStrI]>;
7840   let mayLoad = 1 in
7841   def rm : SS42AI<0x61, MRMSrcMem, (outs),
7842     (ins VR128:$src1, i128mem:$src3, i8imm:$src5),
7843     !strconcat(asm, "\t{$src5, $src3, $src1|$src1, $src3, $src5}"),
7844     []>, Sched<[WritePCmpEStrILd, ReadAfterLd]>;
7845 }
7846
7847 let Defs = [ECX, EFLAGS], Uses = [EAX, EDX], neverHasSideEffects = 1 in {
7848   let Predicates = [HasAVX] in
7849   defm VPCMPESTRI : SS42AI_pcmpestri<"vpcmpestri">, VEX;
7850   defm PCMPESTRI  : SS42AI_pcmpestri<"pcmpestri">;
7851 }
7852
7853 //===----------------------------------------------------------------------===//
7854 // SSE4.2 - CRC Instructions
7855 //===----------------------------------------------------------------------===//
7856
7857 // No CRC instructions have AVX equivalents
7858
7859 // crc intrinsic instruction
7860 // This set of instructions are only rm, the only difference is the size
7861 // of r and m.
7862 class SS42I_crc32r<bits<8> opc, string asm, RegisterClass RCOut,
7863                    RegisterClass RCIn, SDPatternOperator Int> :
7864   SS42FI<opc, MRMSrcReg, (outs RCOut:$dst), (ins RCOut:$src1, RCIn:$src2),
7865          !strconcat(asm, "\t{$src2, $src1|$src1, $src2}"),
7866          [(set RCOut:$dst, (Int RCOut:$src1, RCIn:$src2))], IIC_CRC32_REG>,
7867          Sched<[WriteFAdd]>;
7868
7869 class SS42I_crc32m<bits<8> opc, string asm, RegisterClass RCOut,
7870                    X86MemOperand x86memop, SDPatternOperator Int> :
7871   SS42FI<opc, MRMSrcMem, (outs RCOut:$dst), (ins RCOut:$src1, x86memop:$src2),
7872          !strconcat(asm, "\t{$src2, $src1|$src1, $src2}"),
7873          [(set RCOut:$dst, (Int RCOut:$src1, (load addr:$src2)))],
7874          IIC_CRC32_MEM>, Sched<[WriteFAddLd, ReadAfterLd]>;
7875
7876 let Constraints = "$src1 = $dst" in {
7877   def CRC32r32m8  : SS42I_crc32m<0xF0, "crc32{b}", GR32, i8mem,
7878                                  int_x86_sse42_crc32_32_8>;
7879   def CRC32r32r8  : SS42I_crc32r<0xF0, "crc32{b}", GR32, GR8,
7880                                  int_x86_sse42_crc32_32_8>;
7881   def CRC32r32m16 : SS42I_crc32m<0xF1, "crc32{w}", GR32, i16mem,
7882                                  int_x86_sse42_crc32_32_16>, OpSize16;
7883   def CRC32r32r16 : SS42I_crc32r<0xF1, "crc32{w}", GR32, GR16,
7884                                  int_x86_sse42_crc32_32_16>, OpSize16;
7885   def CRC32r32m32 : SS42I_crc32m<0xF1, "crc32{l}", GR32, i32mem,
7886                                  int_x86_sse42_crc32_32_32>, OpSize32;
7887   def CRC32r32r32 : SS42I_crc32r<0xF1, "crc32{l}", GR32, GR32,
7888                                  int_x86_sse42_crc32_32_32>, OpSize32;
7889   def CRC32r64m64 : SS42I_crc32m<0xF1, "crc32{q}", GR64, i64mem,
7890                                  int_x86_sse42_crc32_64_64>, REX_W;
7891   def CRC32r64r64 : SS42I_crc32r<0xF1, "crc32{q}", GR64, GR64,
7892                                  int_x86_sse42_crc32_64_64>, REX_W;
7893   let hasSideEffects = 0 in {
7894     let mayLoad = 1 in
7895     def CRC32r64m8 : SS42I_crc32m<0xF0, "crc32{b}", GR64, i8mem,
7896                                    null_frag>, REX_W;
7897     def CRC32r64r8 : SS42I_crc32r<0xF0, "crc32{b}", GR64, GR8,
7898                                    null_frag>, REX_W;
7899   }
7900 }
7901
7902 //===----------------------------------------------------------------------===//
7903 // SHA-NI Instructions
7904 //===----------------------------------------------------------------------===//
7905
7906 multiclass SHAI_binop<bits<8> Opc, string OpcodeStr, Intrinsic IntId,
7907                       bit UsesXMM0 = 0> {
7908   def rr : I<Opc, MRMSrcReg, (outs VR128:$dst),
7909              (ins VR128:$src1, VR128:$src2),
7910              !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
7911              [!if(UsesXMM0,
7912                   (set VR128:$dst, (IntId VR128:$src1, VR128:$src2, XMM0)),
7913                   (set VR128:$dst, (IntId VR128:$src1, VR128:$src2)))]>, T8;
7914
7915   def rm : I<Opc, MRMSrcMem, (outs VR128:$dst),
7916              (ins VR128:$src1, i128mem:$src2),
7917              !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
7918              [!if(UsesXMM0,
7919                   (set VR128:$dst, (IntId VR128:$src1,
7920                     (bc_v4i32 (memopv2i64 addr:$src2)), XMM0)),
7921                   (set VR128:$dst, (IntId VR128:$src1,
7922                     (bc_v4i32 (memopv2i64 addr:$src2)))))]>, T8;
7923 }
7924
7925 let Constraints = "$src1 = $dst", Predicates = [HasSHA] in {
7926   def SHA1RNDS4rri : Ii8<0xCC, MRMSrcReg, (outs VR128:$dst),
7927                          (ins VR128:$src1, VR128:$src2, i8imm:$src3),
7928                          "sha1rnds4\t{$src3, $src2, $dst|$dst, $src2, $src3}",
7929                          [(set VR128:$dst,
7930                            (int_x86_sha1rnds4 VR128:$src1, VR128:$src2,
7931                             (i8 imm:$src3)))]>, TA;
7932   def SHA1RNDS4rmi : Ii8<0xCC, MRMSrcMem, (outs VR128:$dst),
7933                          (ins VR128:$src1, i128mem:$src2, i8imm:$src3),
7934                          "sha1rnds4\t{$src3, $src2, $dst|$dst, $src2, $src3}",
7935                          [(set VR128:$dst,
7936                            (int_x86_sha1rnds4 VR128:$src1,
7937                             (bc_v4i32 (memopv2i64 addr:$src2)),
7938                             (i8 imm:$src3)))]>, TA;
7939
7940   defm SHA1NEXTE : SHAI_binop<0xC8, "sha1nexte", int_x86_sha1nexte>;
7941   defm SHA1MSG1  : SHAI_binop<0xC9, "sha1msg1", int_x86_sha1msg1>;
7942   defm SHA1MSG2  : SHAI_binop<0xCA, "sha1msg2", int_x86_sha1msg2>;
7943
7944   let Uses=[XMM0] in
7945   defm SHA256RNDS2 : SHAI_binop<0xCB, "sha256rnds2", int_x86_sha256rnds2, 1>;
7946
7947   defm SHA256MSG1 : SHAI_binop<0xCC, "sha256msg1", int_x86_sha256msg1>;
7948   defm SHA256MSG2 : SHAI_binop<0xCD, "sha256msg2", int_x86_sha256msg2>;
7949 }
7950
7951 // Aliases with explicit %xmm0
7952 def : InstAlias<"sha256rnds2\t{%xmm0, $src2, $dst|$dst, $src2, xmm0}",
7953                 (SHA256RNDS2rr VR128:$dst, VR128:$src2)>;
7954 def : InstAlias<"sha256rnds2\t{%xmm0, $src2, $dst|$dst, $src2, xmm0}",
7955                 (SHA256RNDS2rm VR128:$dst, i128mem:$src2)>;
7956
7957 //===----------------------------------------------------------------------===//
7958 // AES-NI Instructions
7959 //===----------------------------------------------------------------------===//
7960
7961 multiclass AESI_binop_rm_int<bits<8> opc, string OpcodeStr,
7962                               Intrinsic IntId128, bit Is2Addr = 1> {
7963   def rr : AES8I<opc, MRMSrcReg, (outs VR128:$dst),
7964        (ins VR128:$src1, VR128:$src2),
7965        !if(Is2Addr,
7966            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
7967            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
7968        [(set VR128:$dst, (IntId128 VR128:$src1, VR128:$src2))]>,
7969        Sched<[WriteAESDecEnc]>;
7970   def rm : AES8I<opc, MRMSrcMem, (outs VR128:$dst),
7971        (ins VR128:$src1, i128mem:$src2),
7972        !if(Is2Addr,
7973            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
7974            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
7975        [(set VR128:$dst,
7976          (IntId128 VR128:$src1, (memopv2i64 addr:$src2)))]>,
7977        Sched<[WriteAESDecEncLd, ReadAfterLd]>;
7978 }
7979
7980 // Perform One Round of an AES Encryption/Decryption Flow
7981 let Predicates = [HasAVX, HasAES] in {
7982   defm VAESENC          : AESI_binop_rm_int<0xDC, "vaesenc",
7983                          int_x86_aesni_aesenc, 0>, VEX_4V;
7984   defm VAESENCLAST      : AESI_binop_rm_int<0xDD, "vaesenclast",
7985                          int_x86_aesni_aesenclast, 0>, VEX_4V;
7986   defm VAESDEC          : AESI_binop_rm_int<0xDE, "vaesdec",
7987                          int_x86_aesni_aesdec, 0>, VEX_4V;
7988   defm VAESDECLAST      : AESI_binop_rm_int<0xDF, "vaesdeclast",
7989                          int_x86_aesni_aesdeclast, 0>, VEX_4V;
7990 }
7991
7992 let Constraints = "$src1 = $dst" in {
7993   defm AESENC          : AESI_binop_rm_int<0xDC, "aesenc",
7994                          int_x86_aesni_aesenc>;
7995   defm AESENCLAST      : AESI_binop_rm_int<0xDD, "aesenclast",
7996                          int_x86_aesni_aesenclast>;
7997   defm AESDEC          : AESI_binop_rm_int<0xDE, "aesdec",
7998                          int_x86_aesni_aesdec>;
7999   defm AESDECLAST      : AESI_binop_rm_int<0xDF, "aesdeclast",
8000                          int_x86_aesni_aesdeclast>;
8001 }
8002
8003 // Perform the AES InvMixColumn Transformation
8004 let Predicates = [HasAVX, HasAES] in {
8005   def VAESIMCrr : AES8I<0xDB, MRMSrcReg, (outs VR128:$dst),
8006       (ins VR128:$src1),
8007       "vaesimc\t{$src1, $dst|$dst, $src1}",
8008       [(set VR128:$dst,
8009         (int_x86_aesni_aesimc VR128:$src1))]>, Sched<[WriteAESIMC]>,
8010       VEX;
8011   def VAESIMCrm : AES8I<0xDB, MRMSrcMem, (outs VR128:$dst),
8012       (ins i128mem:$src1),
8013       "vaesimc\t{$src1, $dst|$dst, $src1}",
8014       [(set VR128:$dst, (int_x86_aesni_aesimc (loadv2i64 addr:$src1)))]>,
8015       Sched<[WriteAESIMCLd]>, VEX;
8016 }
8017 def AESIMCrr : AES8I<0xDB, MRMSrcReg, (outs VR128:$dst),
8018   (ins VR128:$src1),
8019   "aesimc\t{$src1, $dst|$dst, $src1}",
8020   [(set VR128:$dst,
8021     (int_x86_aesni_aesimc VR128:$src1))]>, Sched<[WriteAESIMC]>;
8022 def AESIMCrm : AES8I<0xDB, MRMSrcMem, (outs VR128:$dst),
8023   (ins i128mem:$src1),
8024   "aesimc\t{$src1, $dst|$dst, $src1}",
8025   [(set VR128:$dst, (int_x86_aesni_aesimc (memopv2i64 addr:$src1)))]>,
8026   Sched<[WriteAESIMCLd]>;
8027
8028 // AES Round Key Generation Assist
8029 let Predicates = [HasAVX, HasAES] in {
8030   def VAESKEYGENASSIST128rr : AESAI<0xDF, MRMSrcReg, (outs VR128:$dst),
8031       (ins VR128:$src1, i8imm:$src2),
8032       "vaeskeygenassist\t{$src2, $src1, $dst|$dst, $src1, $src2}",
8033       [(set VR128:$dst,
8034         (int_x86_aesni_aeskeygenassist VR128:$src1, imm:$src2))]>,
8035       Sched<[WriteAESKeyGen]>, VEX;
8036   def VAESKEYGENASSIST128rm : AESAI<0xDF, MRMSrcMem, (outs VR128:$dst),
8037       (ins i128mem:$src1, i8imm:$src2),
8038       "vaeskeygenassist\t{$src2, $src1, $dst|$dst, $src1, $src2}",
8039       [(set VR128:$dst,
8040         (int_x86_aesni_aeskeygenassist (loadv2i64 addr:$src1), imm:$src2))]>,
8041       Sched<[WriteAESKeyGenLd]>, VEX;
8042 }
8043 def AESKEYGENASSIST128rr : AESAI<0xDF, MRMSrcReg, (outs VR128:$dst),
8044   (ins VR128:$src1, i8imm:$src2),
8045   "aeskeygenassist\t{$src2, $src1, $dst|$dst, $src1, $src2}",
8046   [(set VR128:$dst,
8047     (int_x86_aesni_aeskeygenassist VR128:$src1, imm:$src2))]>,
8048   Sched<[WriteAESKeyGen]>;
8049 def AESKEYGENASSIST128rm : AESAI<0xDF, MRMSrcMem, (outs VR128:$dst),
8050   (ins i128mem:$src1, i8imm:$src2),
8051   "aeskeygenassist\t{$src2, $src1, $dst|$dst, $src1, $src2}",
8052   [(set VR128:$dst,
8053     (int_x86_aesni_aeskeygenassist (memopv2i64 addr:$src1), imm:$src2))]>,
8054   Sched<[WriteAESKeyGenLd]>;
8055
8056 //===----------------------------------------------------------------------===//
8057 // PCLMUL Instructions
8058 //===----------------------------------------------------------------------===//
8059
8060 // AVX carry-less Multiplication instructions
8061 def VPCLMULQDQrr : AVXPCLMULIi8<0x44, MRMSrcReg, (outs VR128:$dst),
8062            (ins VR128:$src1, VR128:$src2, i8imm:$src3),
8063            "vpclmulqdq\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
8064            [(set VR128:$dst,
8065              (int_x86_pclmulqdq VR128:$src1, VR128:$src2, imm:$src3))]>,
8066            Sched<[WriteCLMul]>;
8067
8068 def VPCLMULQDQrm : AVXPCLMULIi8<0x44, MRMSrcMem, (outs VR128:$dst),
8069            (ins VR128:$src1, i128mem:$src2, i8imm:$src3),
8070            "vpclmulqdq\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
8071            [(set VR128:$dst, (int_x86_pclmulqdq VR128:$src1,
8072                               (loadv2i64 addr:$src2), imm:$src3))]>,
8073            Sched<[WriteCLMulLd, ReadAfterLd]>;
8074
8075 // Carry-less Multiplication instructions
8076 let Constraints = "$src1 = $dst" in {
8077 def PCLMULQDQrr : PCLMULIi8<0x44, MRMSrcReg, (outs VR128:$dst),
8078            (ins VR128:$src1, VR128:$src2, i8imm:$src3),
8079            "pclmulqdq\t{$src3, $src2, $dst|$dst, $src2, $src3}",
8080            [(set VR128:$dst,
8081              (int_x86_pclmulqdq VR128:$src1, VR128:$src2, imm:$src3))],
8082              IIC_SSE_PCLMULQDQ_RR>, Sched<[WriteCLMul]>;
8083
8084 def PCLMULQDQrm : PCLMULIi8<0x44, MRMSrcMem, (outs VR128:$dst),
8085            (ins VR128:$src1, i128mem:$src2, i8imm:$src3),
8086            "pclmulqdq\t{$src3, $src2, $dst|$dst, $src2, $src3}",
8087            [(set VR128:$dst, (int_x86_pclmulqdq VR128:$src1,
8088                               (memopv2i64 addr:$src2), imm:$src3))],
8089                               IIC_SSE_PCLMULQDQ_RM>,
8090            Sched<[WriteCLMulLd, ReadAfterLd]>;
8091 } // Constraints = "$src1 = $dst"
8092
8093
8094 multiclass pclmul_alias<string asm, int immop> {
8095   def : InstAlias<!strconcat("pclmul", asm, "dq {$src, $dst|$dst, $src}"),
8096                   (PCLMULQDQrr VR128:$dst, VR128:$src, immop), 0>;
8097
8098   def : InstAlias<!strconcat("pclmul", asm, "dq {$src, $dst|$dst, $src}"),
8099                   (PCLMULQDQrm VR128:$dst, i128mem:$src, immop), 0>;
8100
8101   def : InstAlias<!strconcat("vpclmul", asm,
8102                              "dq {$src2, $src1, $dst|$dst, $src1, $src2}"),
8103                   (VPCLMULQDQrr VR128:$dst, VR128:$src1, VR128:$src2, immop),
8104                   0>;
8105
8106   def : InstAlias<!strconcat("vpclmul", asm,
8107                              "dq {$src2, $src1, $dst|$dst, $src1, $src2}"),
8108                   (VPCLMULQDQrm VR128:$dst, VR128:$src1, i128mem:$src2, immop),
8109                   0>;
8110 }
8111 defm : pclmul_alias<"hqhq", 0x11>;
8112 defm : pclmul_alias<"hqlq", 0x01>;
8113 defm : pclmul_alias<"lqhq", 0x10>;
8114 defm : pclmul_alias<"lqlq", 0x00>;
8115
8116 //===----------------------------------------------------------------------===//
8117 // SSE4A Instructions
8118 //===----------------------------------------------------------------------===//
8119
8120 let Predicates = [HasSSE4A] in {
8121
8122 let Constraints = "$src = $dst" in {
8123 def EXTRQI : Ii8<0x78, MRMXr, (outs VR128:$dst),
8124                  (ins VR128:$src, i8imm:$len, i8imm:$idx),
8125                  "extrq\t{$idx, $len, $src|$src, $len, $idx}",
8126                  [(set VR128:$dst, (int_x86_sse4a_extrqi VR128:$src, imm:$len,
8127                                     imm:$idx))]>, PD;
8128 def EXTRQ  : I<0x79, MRMSrcReg, (outs VR128:$dst),
8129               (ins VR128:$src, VR128:$mask),
8130               "extrq\t{$mask, $src|$src, $mask}",
8131               [(set VR128:$dst, (int_x86_sse4a_extrq VR128:$src,
8132                                  VR128:$mask))]>, PD;
8133
8134 def INSERTQI : Ii8<0x78, MRMSrcReg, (outs VR128:$dst),
8135                    (ins VR128:$src, VR128:$src2, i8imm:$len, i8imm:$idx),
8136                    "insertq\t{$idx, $len, $src2, $src|$src, $src2, $len, $idx}",
8137                    [(set VR128:$dst, (int_x86_sse4a_insertqi VR128:$src,
8138                                       VR128:$src2, imm:$len, imm:$idx))]>, XD;
8139 def INSERTQ  : I<0x79, MRMSrcReg, (outs VR128:$dst),
8140                  (ins VR128:$src, VR128:$mask),
8141                  "insertq\t{$mask, $src|$src, $mask}",
8142                  [(set VR128:$dst, (int_x86_sse4a_insertq VR128:$src,
8143                                     VR128:$mask))]>, XD;
8144 }
8145
8146 def MOVNTSS : I<0x2B, MRMDestMem, (outs), (ins f32mem:$dst, VR128:$src),
8147                 "movntss\t{$src, $dst|$dst, $src}",
8148                 [(int_x86_sse4a_movnt_ss addr:$dst, VR128:$src)]>, XS;
8149
8150 def MOVNTSD : I<0x2B, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
8151                 "movntsd\t{$src, $dst|$dst, $src}",
8152                 [(int_x86_sse4a_movnt_sd addr:$dst, VR128:$src)]>, XD;
8153 }
8154
8155 //===----------------------------------------------------------------------===//
8156 // AVX Instructions
8157 //===----------------------------------------------------------------------===//
8158
8159 //===----------------------------------------------------------------------===//
8160 // VBROADCAST - Load from memory and broadcast to all elements of the
8161 //              destination operand
8162 //
8163 class avx_broadcast<bits<8> opc, string OpcodeStr, RegisterClass RC,
8164                     X86MemOperand x86memop, Intrinsic Int, SchedWrite Sched> :
8165   AVX8I<opc, MRMSrcMem, (outs RC:$dst), (ins x86memop:$src),
8166         !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
8167         [(set RC:$dst, (Int addr:$src))]>, Sched<[Sched]>, VEX;
8168
8169 class avx_broadcast_no_int<bits<8> opc, string OpcodeStr, RegisterClass RC,
8170                            X86MemOperand x86memop, ValueType VT,
8171                            PatFrag ld_frag, SchedWrite Sched> :
8172   AVX8I<opc, MRMSrcMem, (outs RC:$dst), (ins x86memop:$src),
8173         !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
8174         [(set RC:$dst, (VT (X86VBroadcast (ld_frag addr:$src))))]>,
8175         Sched<[Sched]>, VEX {
8176     let mayLoad = 1;
8177 }
8178
8179 // AVX2 adds register forms
8180 class avx2_broadcast_reg<bits<8> opc, string OpcodeStr, RegisterClass RC,
8181                          Intrinsic Int, SchedWrite Sched> :
8182   AVX28I<opc, MRMSrcReg, (outs RC:$dst), (ins VR128:$src),
8183          !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
8184          [(set RC:$dst, (Int VR128:$src))]>, Sched<[Sched]>, VEX;
8185
8186 let ExeDomain = SSEPackedSingle in {
8187   def VBROADCASTSSrm  : avx_broadcast_no_int<0x18, "vbroadcastss", VR128,
8188                                              f32mem, v4f32, loadf32, WriteLoad>;
8189   def VBROADCASTSSYrm : avx_broadcast_no_int<0x18, "vbroadcastss", VR256,
8190                                              f32mem, v8f32, loadf32,
8191                                              WriteFShuffleLd>, VEX_L;
8192 }
8193 let ExeDomain = SSEPackedDouble in
8194 def VBROADCASTSDYrm  : avx_broadcast_no_int<0x19, "vbroadcastsd", VR256, f64mem,
8195                                     v4f64, loadf64, WriteFShuffleLd>, VEX_L;
8196 def VBROADCASTF128 : avx_broadcast<0x1A, "vbroadcastf128", VR256, f128mem,
8197                                    int_x86_avx_vbroadcastf128_pd_256,
8198                                    WriteFShuffleLd>, VEX_L;
8199
8200 let ExeDomain = SSEPackedSingle in {
8201   def VBROADCASTSSrr  : avx2_broadcast_reg<0x18, "vbroadcastss", VR128,
8202                                            int_x86_avx2_vbroadcast_ss_ps,
8203                                            WriteFShuffle>;
8204   def VBROADCASTSSYrr : avx2_broadcast_reg<0x18, "vbroadcastss", VR256,
8205                                       int_x86_avx2_vbroadcast_ss_ps_256,
8206                                       WriteFShuffle256>, VEX_L;
8207 }
8208 let ExeDomain = SSEPackedDouble in
8209 def VBROADCASTSDYrr  : avx2_broadcast_reg<0x19, "vbroadcastsd", VR256,
8210                                       int_x86_avx2_vbroadcast_sd_pd_256,
8211                                       WriteFShuffle256>, VEX_L;
8212
8213 let Predicates = [HasAVX2] in
8214 def VBROADCASTI128 : avx_broadcast<0x5A, "vbroadcasti128", VR256, i128mem,
8215                                    int_x86_avx2_vbroadcasti128, WriteLoad>,
8216                                    VEX_L;
8217
8218 let Predicates = [HasAVX] in
8219 def : Pat<(int_x86_avx_vbroadcastf128_ps_256 addr:$src),
8220           (VBROADCASTF128 addr:$src)>;
8221
8222
8223 //===----------------------------------------------------------------------===//
8224 // VINSERTF128 - Insert packed floating-point values
8225 //
8226 let neverHasSideEffects = 1, ExeDomain = SSEPackedSingle in {
8227 def VINSERTF128rr : AVXAIi8<0x18, MRMSrcReg, (outs VR256:$dst),
8228           (ins VR256:$src1, VR128:$src2, i8imm:$src3),
8229           "vinsertf128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
8230           []>, Sched<[WriteFShuffle]>, VEX_4V, VEX_L;
8231 let mayLoad = 1 in
8232 def VINSERTF128rm : AVXAIi8<0x18, MRMSrcMem, (outs VR256:$dst),
8233           (ins VR256:$src1, f128mem:$src2, i8imm:$src3),
8234           "vinsertf128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
8235           []>, Sched<[WriteFShuffleLd, ReadAfterLd]>, VEX_4V, VEX_L;
8236 }
8237
8238 let Predicates = [HasAVX] in {
8239 def : Pat<(vinsert128_insert:$ins (v8f32 VR256:$src1), (v4f32 VR128:$src2),
8240                                    (iPTR imm)),
8241           (VINSERTF128rr VR256:$src1, VR128:$src2,
8242                          (INSERT_get_vinsert128_imm VR256:$ins))>;
8243 def : Pat<(vinsert128_insert:$ins (v4f64 VR256:$src1), (v2f64 VR128:$src2),
8244                                    (iPTR imm)),
8245           (VINSERTF128rr VR256:$src1, VR128:$src2,
8246                          (INSERT_get_vinsert128_imm VR256:$ins))>;
8247
8248 def : Pat<(vinsert128_insert:$ins (v8f32 VR256:$src1), (loadv4f32 addr:$src2),
8249                                    (iPTR imm)),
8250           (VINSERTF128rm VR256:$src1, addr:$src2,
8251                          (INSERT_get_vinsert128_imm VR256:$ins))>;
8252 def : Pat<(vinsert128_insert:$ins (v4f64 VR256:$src1), (loadv2f64 addr:$src2),
8253                                    (iPTR imm)),
8254           (VINSERTF128rm VR256:$src1, addr:$src2,
8255                          (INSERT_get_vinsert128_imm VR256:$ins))>;
8256 }
8257
8258 let Predicates = [HasAVX1Only] in {
8259 def : Pat<(vinsert128_insert:$ins (v4i64 VR256:$src1), (v2i64 VR128:$src2),
8260                                    (iPTR imm)),
8261           (VINSERTF128rr VR256:$src1, VR128:$src2,
8262                          (INSERT_get_vinsert128_imm VR256:$ins))>;
8263 def : Pat<(vinsert128_insert:$ins (v8i32 VR256:$src1), (v4i32 VR128:$src2),
8264                                    (iPTR imm)),
8265           (VINSERTF128rr VR256:$src1, VR128:$src2,
8266                          (INSERT_get_vinsert128_imm VR256:$ins))>;
8267 def : Pat<(vinsert128_insert:$ins (v32i8 VR256:$src1), (v16i8 VR128:$src2),
8268                                    (iPTR imm)),
8269           (VINSERTF128rr VR256:$src1, VR128:$src2,
8270                          (INSERT_get_vinsert128_imm VR256:$ins))>;
8271 def : Pat<(vinsert128_insert:$ins (v16i16 VR256:$src1), (v8i16 VR128:$src2),
8272                                    (iPTR imm)),
8273           (VINSERTF128rr VR256:$src1, VR128:$src2,
8274                          (INSERT_get_vinsert128_imm VR256:$ins))>;
8275
8276 def : Pat<(vinsert128_insert:$ins (v4i64 VR256:$src1), (loadv2i64 addr:$src2),
8277                                    (iPTR imm)),
8278           (VINSERTF128rm VR256:$src1, addr:$src2,
8279                          (INSERT_get_vinsert128_imm VR256:$ins))>;
8280 def : Pat<(vinsert128_insert:$ins (v8i32 VR256:$src1),
8281                                    (bc_v4i32 (loadv2i64 addr:$src2)),
8282                                    (iPTR imm)),
8283           (VINSERTF128rm VR256:$src1, addr:$src2,
8284                          (INSERT_get_vinsert128_imm VR256:$ins))>;
8285 def : Pat<(vinsert128_insert:$ins (v32i8 VR256:$src1),
8286                                    (bc_v16i8 (loadv2i64 addr:$src2)),
8287                                    (iPTR imm)),
8288           (VINSERTF128rm VR256:$src1, addr:$src2,
8289                          (INSERT_get_vinsert128_imm VR256:$ins))>;
8290 def : Pat<(vinsert128_insert:$ins (v16i16 VR256:$src1),
8291                                    (bc_v8i16 (loadv2i64 addr:$src2)),
8292                                    (iPTR imm)),
8293           (VINSERTF128rm VR256:$src1, addr:$src2,
8294                          (INSERT_get_vinsert128_imm VR256:$ins))>;
8295 }
8296
8297 //===----------------------------------------------------------------------===//
8298 // VEXTRACTF128 - Extract packed floating-point values
8299 //
8300 let neverHasSideEffects = 1, ExeDomain = SSEPackedSingle in {
8301 def VEXTRACTF128rr : AVXAIi8<0x19, MRMDestReg, (outs VR128:$dst),
8302           (ins VR256:$src1, i8imm:$src2),
8303           "vextractf128\t{$src2, $src1, $dst|$dst, $src1, $src2}",
8304           []>, Sched<[WriteFShuffle]>, VEX, VEX_L;
8305 let mayStore = 1 in
8306 def VEXTRACTF128mr : AVXAIi8<0x19, MRMDestMem, (outs),
8307           (ins f128mem:$dst, VR256:$src1, i8imm:$src2),
8308           "vextractf128\t{$src2, $src1, $dst|$dst, $src1, $src2}",
8309           []>, Sched<[WriteStore]>, VEX, VEX_L;
8310 }
8311
8312 // AVX1 patterns
8313 let Predicates = [HasAVX] in {
8314 def : Pat<(vextract128_extract:$ext VR256:$src1, (iPTR imm)),
8315           (v4f32 (VEXTRACTF128rr
8316                     (v8f32 VR256:$src1),
8317                     (EXTRACT_get_vextract128_imm VR128:$ext)))>;
8318 def : Pat<(vextract128_extract:$ext VR256:$src1, (iPTR imm)),
8319           (v2f64 (VEXTRACTF128rr
8320                     (v4f64 VR256:$src1),
8321                     (EXTRACT_get_vextract128_imm VR128:$ext)))>;
8322
8323 def : Pat<(store (v4f32 (vextract128_extract:$ext (v8f32 VR256:$src1),
8324                          (iPTR imm))), addr:$dst),
8325           (VEXTRACTF128mr addr:$dst, VR256:$src1,
8326            (EXTRACT_get_vextract128_imm VR128:$ext))>;
8327 def : Pat<(store (v2f64 (vextract128_extract:$ext (v4f64 VR256:$src1),
8328                          (iPTR imm))), addr:$dst),
8329           (VEXTRACTF128mr addr:$dst, VR256:$src1,
8330            (EXTRACT_get_vextract128_imm VR128:$ext))>;
8331 }
8332
8333 let Predicates = [HasAVX1Only] in {
8334 def : Pat<(vextract128_extract:$ext VR256:$src1, (iPTR imm)),
8335           (v2i64 (VEXTRACTF128rr
8336                   (v4i64 VR256:$src1),
8337                   (EXTRACT_get_vextract128_imm VR128:$ext)))>;
8338 def : Pat<(vextract128_extract:$ext VR256:$src1, (iPTR imm)),
8339           (v4i32 (VEXTRACTF128rr
8340                   (v8i32 VR256:$src1),
8341                   (EXTRACT_get_vextract128_imm VR128:$ext)))>;
8342 def : Pat<(vextract128_extract:$ext VR256:$src1, (iPTR imm)),
8343           (v8i16 (VEXTRACTF128rr
8344                   (v16i16 VR256:$src1),
8345                   (EXTRACT_get_vextract128_imm VR128:$ext)))>;
8346 def : Pat<(vextract128_extract:$ext VR256:$src1, (iPTR imm)),
8347           (v16i8 (VEXTRACTF128rr
8348                   (v32i8 VR256:$src1),
8349                   (EXTRACT_get_vextract128_imm VR128:$ext)))>;
8350
8351 def : Pat<(alignedstore (v2i64 (vextract128_extract:$ext (v4i64 VR256:$src1),
8352                                 (iPTR imm))), addr:$dst),
8353           (VEXTRACTF128mr addr:$dst, VR256:$src1,
8354            (EXTRACT_get_vextract128_imm VR128:$ext))>;
8355 def : Pat<(alignedstore (v4i32 (vextract128_extract:$ext (v8i32 VR256:$src1),
8356                                 (iPTR imm))), addr:$dst),
8357           (VEXTRACTF128mr addr:$dst, VR256:$src1,
8358            (EXTRACT_get_vextract128_imm VR128:$ext))>;
8359 def : Pat<(alignedstore (v8i16 (vextract128_extract:$ext (v16i16 VR256:$src1),
8360                                 (iPTR imm))), addr:$dst),
8361           (VEXTRACTF128mr addr:$dst, VR256:$src1,
8362            (EXTRACT_get_vextract128_imm VR128:$ext))>;
8363 def : Pat<(alignedstore (v16i8 (vextract128_extract:$ext (v32i8 VR256:$src1),
8364                                 (iPTR imm))), addr:$dst),
8365           (VEXTRACTF128mr addr:$dst, VR256:$src1,
8366            (EXTRACT_get_vextract128_imm VR128:$ext))>;
8367 }
8368
8369 //===----------------------------------------------------------------------===//
8370 // VMASKMOV - Conditional SIMD Packed Loads and Stores
8371 //
8372 multiclass avx_movmask_rm<bits<8> opc_rm, bits<8> opc_mr, string OpcodeStr,
8373                           Intrinsic IntLd, Intrinsic IntLd256,
8374                           Intrinsic IntSt, Intrinsic IntSt256> {
8375   def rm  : AVX8I<opc_rm, MRMSrcMem, (outs VR128:$dst),
8376              (ins VR128:$src1, f128mem:$src2),
8377              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8378              [(set VR128:$dst, (IntLd addr:$src2, VR128:$src1))]>,
8379              VEX_4V;
8380   def Yrm : AVX8I<opc_rm, MRMSrcMem, (outs VR256:$dst),
8381              (ins VR256:$src1, f256mem:$src2),
8382              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8383              [(set VR256:$dst, (IntLd256 addr:$src2, VR256:$src1))]>,
8384              VEX_4V, VEX_L;
8385   def mr  : AVX8I<opc_mr, MRMDestMem, (outs),
8386              (ins f128mem:$dst, VR128:$src1, VR128:$src2),
8387              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8388              [(IntSt addr:$dst, VR128:$src1, VR128:$src2)]>, VEX_4V;
8389   def Ymr : AVX8I<opc_mr, MRMDestMem, (outs),
8390              (ins f256mem:$dst, VR256:$src1, VR256:$src2),
8391              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8392              [(IntSt256 addr:$dst, VR256:$src1, VR256:$src2)]>, VEX_4V, VEX_L;
8393 }
8394
8395 let ExeDomain = SSEPackedSingle in
8396 defm VMASKMOVPS : avx_movmask_rm<0x2C, 0x2E, "vmaskmovps",
8397                                  int_x86_avx_maskload_ps,
8398                                  int_x86_avx_maskload_ps_256,
8399                                  int_x86_avx_maskstore_ps,
8400                                  int_x86_avx_maskstore_ps_256>;
8401 let ExeDomain = SSEPackedDouble in
8402 defm VMASKMOVPD : avx_movmask_rm<0x2D, 0x2F, "vmaskmovpd",
8403                                  int_x86_avx_maskload_pd,
8404                                  int_x86_avx_maskload_pd_256,
8405                                  int_x86_avx_maskstore_pd,
8406                                  int_x86_avx_maskstore_pd_256>;
8407
8408 //===----------------------------------------------------------------------===//
8409 // VPERMIL - Permute Single and Double Floating-Point Values
8410 //
8411 multiclass avx_permil<bits<8> opc_rm, bits<8> opc_rmi, string OpcodeStr,
8412                       RegisterClass RC, X86MemOperand x86memop_f,
8413                       X86MemOperand x86memop_i, PatFrag i_frag,
8414                       Intrinsic IntVar, ValueType vt> {
8415   def rr  : AVX8I<opc_rm, MRMSrcReg, (outs RC:$dst),
8416              (ins RC:$src1, RC:$src2),
8417              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8418              [(set RC:$dst, (IntVar RC:$src1, RC:$src2))]>, VEX_4V,
8419              Sched<[WriteFShuffle]>;
8420   def rm  : AVX8I<opc_rm, MRMSrcMem, (outs RC:$dst),
8421              (ins RC:$src1, x86memop_i:$src2),
8422              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8423              [(set RC:$dst, (IntVar RC:$src1,
8424                              (bitconvert (i_frag addr:$src2))))]>, VEX_4V,
8425              Sched<[WriteFShuffleLd, ReadAfterLd]>;
8426
8427   def ri  : AVXAIi8<opc_rmi, MRMSrcReg, (outs RC:$dst),
8428              (ins RC:$src1, i8imm:$src2),
8429              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8430              [(set RC:$dst, (vt (X86VPermilpi RC:$src1, (i8 imm:$src2))))]>, VEX,
8431              Sched<[WriteFShuffle]>;
8432   def mi  : AVXAIi8<opc_rmi, MRMSrcMem, (outs RC:$dst),
8433              (ins x86memop_f:$src1, i8imm:$src2),
8434              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8435              [(set RC:$dst,
8436                (vt (X86VPermilpi (memop addr:$src1), (i8 imm:$src2))))]>, VEX,
8437              Sched<[WriteFShuffleLd]>;
8438 }
8439
8440 let ExeDomain = SSEPackedSingle in {
8441   defm VPERMILPS  : avx_permil<0x0C, 0x04, "vpermilps", VR128, f128mem, i128mem,
8442                                loadv2i64, int_x86_avx_vpermilvar_ps, v4f32>;
8443   defm VPERMILPSY : avx_permil<0x0C, 0x04, "vpermilps", VR256, f256mem, i256mem,
8444                        loadv4i64, int_x86_avx_vpermilvar_ps_256, v8f32>, VEX_L;
8445 }
8446 let ExeDomain = SSEPackedDouble in {
8447   defm VPERMILPD  : avx_permil<0x0D, 0x05, "vpermilpd", VR128, f128mem, i128mem,
8448                                loadv2i64, int_x86_avx_vpermilvar_pd, v2f64>;
8449   defm VPERMILPDY : avx_permil<0x0D, 0x05, "vpermilpd", VR256, f256mem, i256mem,
8450                        loadv4i64, int_x86_avx_vpermilvar_pd_256, v4f64>, VEX_L;
8451 }
8452
8453 let Predicates = [HasAVX] in {
8454 def : Pat<(v8f32 (X86VPermilpv VR256:$src1, (v8i32 VR256:$src2))),
8455           (VPERMILPSYrr VR256:$src1, VR256:$src2)>;
8456 def : Pat<(v8f32 (X86VPermilpv VR256:$src1, (bc_v8i32 (loadv4i64 addr:$src2)))),
8457           (VPERMILPSYrm VR256:$src1, addr:$src2)>;
8458 def : Pat<(v4f64 (X86VPermilpv VR256:$src1, (v4i64 VR256:$src2))),
8459           (VPERMILPDYrr VR256:$src1, VR256:$src2)>;
8460 def : Pat<(v4f64 (X86VPermilpv VR256:$src1, (loadv4i64 addr:$src2))),
8461           (VPERMILPDYrm VR256:$src1, addr:$src2)>;
8462
8463 def : Pat<(v8i32 (X86VPermilpi VR256:$src1, (i8 imm:$imm))),
8464           (VPERMILPSYri VR256:$src1, imm:$imm)>;
8465 def : Pat<(v4i64 (X86VPermilpi VR256:$src1, (i8 imm:$imm))),
8466           (VPERMILPDYri VR256:$src1, imm:$imm)>;
8467 def : Pat<(v8i32 (X86VPermilpi (bc_v8i32 (loadv4i64 addr:$src1)),
8468                                (i8 imm:$imm))),
8469           (VPERMILPSYmi addr:$src1, imm:$imm)>;
8470 def : Pat<(v4i64 (X86VPermilpi (loadv4i64 addr:$src1), (i8 imm:$imm))),
8471           (VPERMILPDYmi addr:$src1, imm:$imm)>;
8472
8473 def : Pat<(v4f32 (X86VPermilpv VR128:$src1, (v4i32 VR128:$src2))),
8474           (VPERMILPSrr VR128:$src1, VR128:$src2)>;
8475 def : Pat<(v4f32 (X86VPermilpv VR128:$src1, (bc_v4i32 (loadv2i64 addr:$src2)))),
8476           (VPERMILPSrm VR128:$src1, addr:$src2)>;
8477 def : Pat<(v2f64 (X86VPermilpv VR128:$src1, (v2i64 VR128:$src2))),
8478           (VPERMILPDrr VR128:$src1, VR128:$src2)>;
8479 def : Pat<(v2f64 (X86VPermilpv VR128:$src1, (loadv2i64 addr:$src2))),
8480           (VPERMILPDrm VR128:$src1, addr:$src2)>;
8481
8482 def : Pat<(v2i64 (X86VPermilpi VR128:$src1, (i8 imm:$imm))),
8483           (VPERMILPDri VR128:$src1, imm:$imm)>;
8484 def : Pat<(v2i64 (X86VPermilpi (loadv2i64 addr:$src1), (i8 imm:$imm))),
8485           (VPERMILPDmi addr:$src1, imm:$imm)>;
8486 }
8487
8488 //===----------------------------------------------------------------------===//
8489 // VPERM2F128 - Permute Floating-Point Values in 128-bit chunks
8490 //
8491 let ExeDomain = SSEPackedSingle in {
8492 def VPERM2F128rr : AVXAIi8<0x06, MRMSrcReg, (outs VR256:$dst),
8493           (ins VR256:$src1, VR256:$src2, i8imm:$src3),
8494           "vperm2f128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
8495           [(set VR256:$dst, (v8f32 (X86VPerm2x128 VR256:$src1, VR256:$src2,
8496                               (i8 imm:$src3))))]>, VEX_4V, VEX_L,
8497           Sched<[WriteFShuffle]>;
8498 def VPERM2F128rm : AVXAIi8<0x06, MRMSrcMem, (outs VR256:$dst),
8499           (ins VR256:$src1, f256mem:$src2, i8imm:$src3),
8500           "vperm2f128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
8501           [(set VR256:$dst, (X86VPerm2x128 VR256:$src1, (loadv8f32 addr:$src2),
8502                              (i8 imm:$src3)))]>, VEX_4V, VEX_L,
8503           Sched<[WriteFShuffleLd, ReadAfterLd]>;
8504 }
8505
8506 let Predicates = [HasAVX] in {
8507 def : Pat<(v4f64 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
8508           (VPERM2F128rr VR256:$src1, VR256:$src2, imm:$imm)>;
8509 def : Pat<(v4f64 (X86VPerm2x128 VR256:$src1,
8510                   (loadv4f64 addr:$src2), (i8 imm:$imm))),
8511           (VPERM2F128rm VR256:$src1, addr:$src2, imm:$imm)>;
8512 }
8513
8514 let Predicates = [HasAVX1Only] in {
8515 def : Pat<(v8i32 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
8516           (VPERM2F128rr VR256:$src1, VR256:$src2, imm:$imm)>;
8517 def : Pat<(v4i64 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
8518           (VPERM2F128rr VR256:$src1, VR256:$src2, imm:$imm)>;
8519 def : Pat<(v32i8 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
8520           (VPERM2F128rr VR256:$src1, VR256:$src2, imm:$imm)>;
8521 def : Pat<(v16i16 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
8522           (VPERM2F128rr VR256:$src1, VR256:$src2, imm:$imm)>;
8523
8524 def : Pat<(v8i32 (X86VPerm2x128 VR256:$src1,
8525                   (bc_v8i32 (loadv4i64 addr:$src2)), (i8 imm:$imm))),
8526           (VPERM2F128rm VR256:$src1, addr:$src2, imm:$imm)>;
8527 def : Pat<(v4i64 (X86VPerm2x128 VR256:$src1,
8528                   (loadv4i64 addr:$src2), (i8 imm:$imm))),
8529           (VPERM2F128rm VR256:$src1, addr:$src2, imm:$imm)>;
8530 def : Pat<(v32i8 (X86VPerm2x128 VR256:$src1,
8531                   (bc_v32i8 (loadv4i64 addr:$src2)), (i8 imm:$imm))),
8532           (VPERM2F128rm VR256:$src1, addr:$src2, imm:$imm)>;
8533 def : Pat<(v16i16 (X86VPerm2x128 VR256:$src1,
8534                   (bc_v16i16 (loadv4i64 addr:$src2)), (i8 imm:$imm))),
8535           (VPERM2F128rm VR256:$src1, addr:$src2, imm:$imm)>;
8536 }
8537
8538 //===----------------------------------------------------------------------===//
8539 // VZERO - Zero YMM registers
8540 //
8541 let Defs = [YMM0, YMM1, YMM2, YMM3, YMM4, YMM5, YMM6, YMM7,
8542             YMM8, YMM9, YMM10, YMM11, YMM12, YMM13, YMM14, YMM15] in {
8543   // Zero All YMM registers
8544   def VZEROALL : I<0x77, RawFrm, (outs), (ins), "vzeroall",
8545                   [(int_x86_avx_vzeroall)]>, PS, VEX, VEX_L, Requires<[HasAVX]>;
8546
8547   // Zero Upper bits of YMM registers
8548   def VZEROUPPER : I<0x77, RawFrm, (outs), (ins), "vzeroupper",
8549                      [(int_x86_avx_vzeroupper)]>, PS, VEX, Requires<[HasAVX]>;
8550 }
8551
8552 //===----------------------------------------------------------------------===//
8553 // Half precision conversion instructions
8554 //===----------------------------------------------------------------------===//
8555 multiclass f16c_ph2ps<RegisterClass RC, X86MemOperand x86memop, Intrinsic Int> {
8556   def rr : I<0x13, MRMSrcReg, (outs RC:$dst), (ins VR128:$src),
8557              "vcvtph2ps\t{$src, $dst|$dst, $src}",
8558              [(set RC:$dst, (Int VR128:$src))]>,
8559              T8PD, VEX, Sched<[WriteCvtF2F]>;
8560   let neverHasSideEffects = 1, mayLoad = 1 in
8561   def rm : I<0x13, MRMSrcMem, (outs RC:$dst), (ins x86memop:$src),
8562              "vcvtph2ps\t{$src, $dst|$dst, $src}", []>, T8PD, VEX,
8563              Sched<[WriteCvtF2FLd]>;
8564 }
8565
8566 multiclass f16c_ps2ph<RegisterClass RC, X86MemOperand x86memop, Intrinsic Int> {
8567   def rr : Ii8<0x1D, MRMDestReg, (outs VR128:$dst),
8568                (ins RC:$src1, i32i8imm:$src2),
8569                "vcvtps2ph\t{$src2, $src1, $dst|$dst, $src1, $src2}",
8570                [(set VR128:$dst, (Int RC:$src1, imm:$src2))]>,
8571                TAPD, VEX, Sched<[WriteCvtF2F]>;
8572   let neverHasSideEffects = 1, mayStore = 1,
8573       SchedRW = [WriteCvtF2FLd, WriteRMW] in
8574   def mr : Ii8<0x1D, MRMDestMem, (outs),
8575                (ins x86memop:$dst, RC:$src1, i32i8imm:$src2),
8576                "vcvtps2ph\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>,
8577                TAPD, VEX;
8578 }
8579
8580 let Predicates = [HasF16C] in {
8581   defm VCVTPH2PS  : f16c_ph2ps<VR128, f64mem, int_x86_vcvtph2ps_128>;
8582   defm VCVTPH2PSY : f16c_ph2ps<VR256, f128mem, int_x86_vcvtph2ps_256>, VEX_L;
8583   defm VCVTPS2PH  : f16c_ps2ph<VR128, f64mem, int_x86_vcvtps2ph_128>;
8584   defm VCVTPS2PHY : f16c_ps2ph<VR256, f128mem, int_x86_vcvtps2ph_256>, VEX_L;
8585
8586   // Pattern match vcvtph2ps of a scalar i64 load.
8587   def : Pat<(int_x86_vcvtph2ps_128 (vzmovl_v2i64 addr:$src)),
8588             (VCVTPH2PSrm addr:$src)>;
8589   def : Pat<(int_x86_vcvtph2ps_128 (vzload_v2i64 addr:$src)),
8590             (VCVTPH2PSrm addr:$src)>;
8591 }
8592
8593 // Patterns for  matching conversions from float to half-float and vice versa.
8594 let Predicates = [HasF16C] in {
8595   def : Pat<(fp_to_f16 FR32:$src),
8596             (i16 (EXTRACT_SUBREG (VMOVPDI2DIrr (VCVTPS2PHrr
8597               (COPY_TO_REGCLASS FR32:$src, VR128), 0)), sub_16bit))>;
8598
8599   def : Pat<(f16_to_fp GR16:$src),
8600             (f32 (COPY_TO_REGCLASS (VCVTPH2PSrr
8601               (COPY_TO_REGCLASS (MOVSX32rr16 GR16:$src), VR128)), FR32)) >;
8602
8603   def : Pat<(f16_to_fp (i16 (fp_to_f16 FR32:$src))),
8604             (f32 (COPY_TO_REGCLASS (VCVTPH2PSrr
8605               (VCVTPS2PHrr (COPY_TO_REGCLASS FR32:$src, VR128), 0)), FR32)) >;
8606 }
8607
8608 //===----------------------------------------------------------------------===//
8609 // AVX2 Instructions
8610 //===----------------------------------------------------------------------===//
8611
8612 /// AVX2_binop_rmi_int - AVX2 binary operator with 8-bit immediate
8613 multiclass AVX2_binop_rmi_int<bits<8> opc, string OpcodeStr,
8614                  Intrinsic IntId, RegisterClass RC, PatFrag memop_frag,
8615                  X86MemOperand x86memop> {
8616   let isCommutable = 1 in
8617   def rri : AVX2AIi8<opc, MRMSrcReg, (outs RC:$dst),
8618         (ins RC:$src1, RC:$src2, i8imm:$src3),
8619         !strconcat(OpcodeStr,
8620             "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
8621         [(set RC:$dst, (IntId RC:$src1, RC:$src2, imm:$src3))]>,
8622         Sched<[WriteBlend]>, VEX_4V;
8623   def rmi : AVX2AIi8<opc, MRMSrcMem, (outs RC:$dst),
8624         (ins RC:$src1, x86memop:$src2, i8imm:$src3),
8625         !strconcat(OpcodeStr,
8626             "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
8627         [(set RC:$dst,
8628           (IntId RC:$src1,
8629            (bitconvert (memop_frag addr:$src2)), imm:$src3))]>,
8630         Sched<[WriteBlendLd, ReadAfterLd]>, VEX_4V;
8631 }
8632
8633 let isCommutable = 0 in {
8634 defm VPBLENDD : AVX2_binop_rmi_int<0x02, "vpblendd", int_x86_avx2_pblendd_128,
8635                                    VR128, loadv2i64, i128mem>;
8636 defm VPBLENDDY : AVX2_binop_rmi_int<0x02, "vpblendd", int_x86_avx2_pblendd_256,
8637                                     VR256, loadv4i64, i256mem>, VEX_L;
8638 }
8639
8640 def : Pat<(v4i32 (X86Blendi (v4i32 VR128:$src1), (v4i32 VR128:$src2),
8641                   imm:$mask)),
8642           (VPBLENDDrri VR128:$src1, VR128:$src2, imm:$mask)>;
8643 def : Pat<(v8i32 (X86Blendi (v8i32 VR256:$src1), (v8i32 VR256:$src2),
8644                   imm:$mask)),
8645           (VPBLENDDYrri VR256:$src1, VR256:$src2, imm:$mask)>;
8646
8647 //===----------------------------------------------------------------------===//
8648 // VPBROADCAST - Load from memory and broadcast to all elements of the
8649 //               destination operand
8650 //
8651 multiclass avx2_broadcast<bits<8> opc, string OpcodeStr,
8652                           X86MemOperand x86memop, PatFrag ld_frag,
8653                           Intrinsic Int128, Intrinsic Int256> {
8654   def rr : AVX28I<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
8655                   !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
8656                   [(set VR128:$dst, (Int128 VR128:$src))]>,
8657                   Sched<[WriteShuffle]>, VEX;
8658   def rm : AVX28I<opc, MRMSrcMem, (outs VR128:$dst), (ins x86memop:$src),
8659                   !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
8660                   [(set VR128:$dst,
8661                     (Int128 (scalar_to_vector (ld_frag addr:$src))))]>,
8662                   Sched<[WriteLoad]>, VEX;
8663   def Yrr : AVX28I<opc, MRMSrcReg, (outs VR256:$dst), (ins VR128:$src),
8664                    !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
8665                    [(set VR256:$dst, (Int256 VR128:$src))]>,
8666                    Sched<[WriteShuffle256]>, VEX, VEX_L;
8667   def Yrm : AVX28I<opc, MRMSrcMem, (outs VR256:$dst), (ins x86memop:$src),
8668                    !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
8669                    [(set VR256:$dst,
8670                     (Int256 (scalar_to_vector (ld_frag addr:$src))))]>,
8671                    Sched<[WriteLoad]>, VEX, VEX_L;
8672 }
8673
8674 defm VPBROADCASTB  : avx2_broadcast<0x78, "vpbroadcastb", i8mem, loadi8,
8675                                     int_x86_avx2_pbroadcastb_128,
8676                                     int_x86_avx2_pbroadcastb_256>;
8677 defm VPBROADCASTW  : avx2_broadcast<0x79, "vpbroadcastw", i16mem, loadi16,
8678                                     int_x86_avx2_pbroadcastw_128,
8679                                     int_x86_avx2_pbroadcastw_256>;
8680 defm VPBROADCASTD  : avx2_broadcast<0x58, "vpbroadcastd", i32mem, loadi32,
8681                                     int_x86_avx2_pbroadcastd_128,
8682                                     int_x86_avx2_pbroadcastd_256>;
8683 defm VPBROADCASTQ  : avx2_broadcast<0x59, "vpbroadcastq", i64mem, loadi64,
8684                                     int_x86_avx2_pbroadcastq_128,
8685                                     int_x86_avx2_pbroadcastq_256>;
8686
8687 let Predicates = [HasAVX2] in {
8688   def : Pat<(v16i8 (X86VBroadcast (loadi8 addr:$src))),
8689           (VPBROADCASTBrm addr:$src)>;
8690   def : Pat<(v32i8 (X86VBroadcast (loadi8 addr:$src))),
8691           (VPBROADCASTBYrm addr:$src)>;
8692   def : Pat<(v8i16 (X86VBroadcast (loadi16 addr:$src))),
8693           (VPBROADCASTWrm addr:$src)>;
8694   def : Pat<(v16i16 (X86VBroadcast (loadi16 addr:$src))),
8695           (VPBROADCASTWYrm addr:$src)>;
8696   def : Pat<(v4i32 (X86VBroadcast (loadi32 addr:$src))),
8697           (VPBROADCASTDrm addr:$src)>;
8698   def : Pat<(v8i32 (X86VBroadcast (loadi32 addr:$src))),
8699           (VPBROADCASTDYrm addr:$src)>;
8700   def : Pat<(v2i64 (X86VBroadcast (loadi64 addr:$src))),
8701           (VPBROADCASTQrm addr:$src)>;
8702   def : Pat<(v4i64 (X86VBroadcast (loadi64 addr:$src))),
8703           (VPBROADCASTQYrm addr:$src)>;
8704
8705   def : Pat<(v16i8 (X86VBroadcast (v16i8 VR128:$src))),
8706           (VPBROADCASTBrr VR128:$src)>;
8707   def : Pat<(v32i8 (X86VBroadcast (v16i8 VR128:$src))),
8708           (VPBROADCASTBYrr VR128:$src)>;
8709   def : Pat<(v8i16 (X86VBroadcast (v8i16 VR128:$src))),
8710           (VPBROADCASTWrr VR128:$src)>;
8711   def : Pat<(v16i16 (X86VBroadcast (v8i16 VR128:$src))),
8712           (VPBROADCASTWYrr VR128:$src)>;
8713   def : Pat<(v4i32 (X86VBroadcast (v4i32 VR128:$src))),
8714           (VPBROADCASTDrr VR128:$src)>;
8715   def : Pat<(v8i32 (X86VBroadcast (v4i32 VR128:$src))),
8716           (VPBROADCASTDYrr VR128:$src)>;
8717   def : Pat<(v2i64 (X86VBroadcast (v2i64 VR128:$src))),
8718           (VPBROADCASTQrr VR128:$src)>;
8719   def : Pat<(v4i64 (X86VBroadcast (v2i64 VR128:$src))),
8720           (VPBROADCASTQYrr VR128:$src)>;
8721   def : Pat<(v4f32 (X86VBroadcast (v4f32 VR128:$src))),
8722           (VBROADCASTSSrr VR128:$src)>;
8723   def : Pat<(v8f32 (X86VBroadcast (v4f32 VR128:$src))),
8724           (VBROADCASTSSYrr VR128:$src)>;
8725   def : Pat<(v2f64 (X86VBroadcast (v2f64 VR128:$src))),
8726           (VPBROADCASTQrr VR128:$src)>;
8727   def : Pat<(v4f64 (X86VBroadcast (v2f64 VR128:$src))),
8728           (VBROADCASTSDYrr VR128:$src)>;
8729
8730   // Provide aliases for broadcast from the same regitser class that
8731   // automatically does the extract.
8732   def : Pat<(v32i8 (X86VBroadcast (v32i8 VR256:$src))),
8733             (VPBROADCASTBYrr (v16i8 (EXTRACT_SUBREG (v32i8 VR256:$src),
8734                                                     sub_xmm)))>;
8735   def : Pat<(v16i16 (X86VBroadcast (v16i16 VR256:$src))),
8736             (VPBROADCASTWYrr (v8i16 (EXTRACT_SUBREG (v16i16 VR256:$src),
8737                                                     sub_xmm)))>;
8738   def : Pat<(v8i32 (X86VBroadcast (v8i32 VR256:$src))),
8739             (VPBROADCASTDYrr (v4i32 (EXTRACT_SUBREG (v8i32 VR256:$src),
8740                                                     sub_xmm)))>;
8741   def : Pat<(v4i64 (X86VBroadcast (v4i64 VR256:$src))),
8742             (VPBROADCASTQYrr (v2i64 (EXTRACT_SUBREG (v4i64 VR256:$src),
8743                                                     sub_xmm)))>;
8744   def : Pat<(v8f32 (X86VBroadcast (v8f32 VR256:$src))),
8745             (VBROADCASTSSYrr (v4f32 (EXTRACT_SUBREG (v8f32 VR256:$src),
8746                                                     sub_xmm)))>;
8747   def : Pat<(v4f64 (X86VBroadcast (v4f64 VR256:$src))),
8748             (VBROADCASTSDYrr (v2f64 (EXTRACT_SUBREG (v4f64 VR256:$src),
8749                                                     sub_xmm)))>;
8750
8751   // Provide fallback in case the load node that is used in the patterns above
8752   // is used by additional users, which prevents the pattern selection.
8753   let AddedComplexity = 20 in {
8754     def : Pat<(v4f32 (X86VBroadcast FR32:$src)),
8755               (VBROADCASTSSrr (COPY_TO_REGCLASS FR32:$src, VR128))>;
8756     def : Pat<(v8f32 (X86VBroadcast FR32:$src)),
8757               (VBROADCASTSSYrr (COPY_TO_REGCLASS FR32:$src, VR128))>;
8758     def : Pat<(v4f64 (X86VBroadcast FR64:$src)),
8759               (VBROADCASTSDYrr (COPY_TO_REGCLASS FR64:$src, VR128))>;
8760
8761     def : Pat<(v4i32 (X86VBroadcast GR32:$src)),
8762               (VBROADCASTSSrr (COPY_TO_REGCLASS GR32:$src, VR128))>;
8763     def : Pat<(v8i32 (X86VBroadcast GR32:$src)),
8764               (VBROADCASTSSYrr (COPY_TO_REGCLASS GR32:$src, VR128))>;
8765     def : Pat<(v4i64 (X86VBroadcast GR64:$src)),
8766               (VBROADCASTSDYrr (COPY_TO_REGCLASS GR64:$src, VR128))>;
8767
8768     def : Pat<(v16i8 (X86VBroadcast GR8:$src)),
8769           (VPBROADCASTBrr (COPY_TO_REGCLASS
8770                            (i32 (SUBREG_TO_REG (i32 0), GR8:$src, sub_8bit)),
8771                            VR128))>;
8772     def : Pat<(v32i8 (X86VBroadcast GR8:$src)),
8773           (VPBROADCASTBYrr (COPY_TO_REGCLASS
8774                             (i32 (SUBREG_TO_REG (i32 0), GR8:$src, sub_8bit)),
8775                             VR128))>;
8776
8777     def : Pat<(v8i16 (X86VBroadcast GR16:$src)),
8778           (VPBROADCASTWrr (COPY_TO_REGCLASS
8779                            (i32 (SUBREG_TO_REG (i32 0), GR16:$src, sub_16bit)),
8780                            VR128))>;
8781     def : Pat<(v16i16 (X86VBroadcast GR16:$src)),
8782           (VPBROADCASTWYrr (COPY_TO_REGCLASS
8783                             (i32 (SUBREG_TO_REG (i32 0), GR16:$src, sub_16bit)),
8784                             VR128))>;
8785
8786     // The patterns for VPBROADCASTD are not needed because they would match
8787     // the exact same thing as VBROADCASTSS patterns.
8788
8789     def : Pat<(v2i64 (X86VBroadcast GR64:$src)),
8790           (VPBROADCASTQrr (COPY_TO_REGCLASS GR64:$src, VR128))>;
8791     // The v4i64 pattern is not needed because VBROADCASTSDYrr already match.
8792   }
8793 }
8794
8795 // AVX1 broadcast patterns
8796 let Predicates = [HasAVX1Only] in {
8797 def : Pat<(v8i32 (X86VBroadcast (loadi32 addr:$src))),
8798           (VBROADCASTSSYrm addr:$src)>;
8799 def : Pat<(v4i64 (X86VBroadcast (loadi64 addr:$src))),
8800           (VBROADCASTSDYrm addr:$src)>;
8801 def : Pat<(v4i32 (X86VBroadcast (loadi32 addr:$src))),
8802           (VBROADCASTSSrm addr:$src)>;
8803 }
8804
8805 let Predicates = [HasAVX] in {
8806   // Provide fallback in case the load node that is used in the patterns above
8807   // is used by additional users, which prevents the pattern selection.
8808   let AddedComplexity = 20 in {
8809   // 128bit broadcasts:
8810   def : Pat<(v4f32 (X86VBroadcast FR32:$src)),
8811             (VPSHUFDri (COPY_TO_REGCLASS FR32:$src, VR128), 0)>;
8812   def : Pat<(v8f32 (X86VBroadcast FR32:$src)),
8813             (VINSERTF128rr (INSERT_SUBREG (v8f32 (IMPLICIT_DEF)),
8814               (VPSHUFDri (COPY_TO_REGCLASS FR32:$src, VR128), 0), sub_xmm),
8815               (VPSHUFDri (COPY_TO_REGCLASS FR32:$src, VR128), 0), 1)>;
8816   def : Pat<(v4f64 (X86VBroadcast FR64:$src)),
8817             (VINSERTF128rr (INSERT_SUBREG (v4f64 (IMPLICIT_DEF)),
8818               (VPSHUFDri (COPY_TO_REGCLASS FR64:$src, VR128), 0x44), sub_xmm),
8819               (VPSHUFDri (COPY_TO_REGCLASS FR64:$src, VR128), 0x44), 1)>;
8820
8821   def : Pat<(v4i32 (X86VBroadcast GR32:$src)),
8822             (VPSHUFDri (COPY_TO_REGCLASS GR32:$src, VR128), 0)>;
8823   def : Pat<(v8i32 (X86VBroadcast GR32:$src)),
8824             (VINSERTF128rr (INSERT_SUBREG (v8i32 (IMPLICIT_DEF)),
8825               (VPSHUFDri (COPY_TO_REGCLASS GR32:$src, VR128), 0), sub_xmm),
8826               (VPSHUFDri (COPY_TO_REGCLASS GR32:$src, VR128), 0), 1)>;
8827   def : Pat<(v4i64 (X86VBroadcast GR64:$src)),
8828             (VINSERTF128rr (INSERT_SUBREG (v4i64 (IMPLICIT_DEF)),
8829               (VPSHUFDri (COPY_TO_REGCLASS GR64:$src, VR128), 0x44), sub_xmm),
8830               (VPSHUFDri (COPY_TO_REGCLASS GR64:$src, VR128), 0x44), 1)>;
8831   }
8832
8833   def : Pat<(v2f64 (X86VBroadcast f64:$src)),
8834             (VMOVDDUPrr (COPY_TO_REGCLASS FR64:$src, VR128))>;
8835 }
8836
8837 //===----------------------------------------------------------------------===//
8838 // VPERM - Permute instructions
8839 //
8840
8841 multiclass avx2_perm<bits<8> opc, string OpcodeStr, PatFrag mem_frag,
8842                      ValueType OpVT, X86FoldableSchedWrite Sched> {
8843   def Yrr : AVX28I<opc, MRMSrcReg, (outs VR256:$dst),
8844                    (ins VR256:$src1, VR256:$src2),
8845                    !strconcat(OpcodeStr,
8846                        "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8847                    [(set VR256:$dst,
8848                      (OpVT (X86VPermv VR256:$src1, VR256:$src2)))]>,
8849                    Sched<[Sched]>, VEX_4V, VEX_L;
8850   def Yrm : AVX28I<opc, MRMSrcMem, (outs VR256:$dst),
8851                    (ins VR256:$src1, i256mem:$src2),
8852                    !strconcat(OpcodeStr,
8853                        "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8854                    [(set VR256:$dst,
8855                      (OpVT (X86VPermv VR256:$src1,
8856                             (bitconvert (mem_frag addr:$src2)))))]>,
8857                    Sched<[Sched.Folded, ReadAfterLd]>, VEX_4V, VEX_L;
8858 }
8859
8860 defm VPERMD : avx2_perm<0x36, "vpermd", loadv4i64, v8i32, WriteShuffle256>;
8861 let ExeDomain = SSEPackedSingle in
8862 defm VPERMPS : avx2_perm<0x16, "vpermps", loadv8f32, v8f32, WriteFShuffle256>;
8863
8864 multiclass avx2_perm_imm<bits<8> opc, string OpcodeStr, PatFrag mem_frag,
8865                          ValueType OpVT, X86FoldableSchedWrite Sched> {
8866   def Yri : AVX2AIi8<opc, MRMSrcReg, (outs VR256:$dst),
8867                      (ins VR256:$src1, i8imm:$src2),
8868                      !strconcat(OpcodeStr,
8869                          "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8870                      [(set VR256:$dst,
8871                        (OpVT (X86VPermi VR256:$src1, (i8 imm:$src2))))]>,
8872                      Sched<[Sched]>, VEX, VEX_L;
8873   def Ymi : AVX2AIi8<opc, MRMSrcMem, (outs VR256:$dst),
8874                      (ins i256mem:$src1, i8imm:$src2),
8875                      !strconcat(OpcodeStr,
8876                          "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8877                      [(set VR256:$dst,
8878                        (OpVT (X86VPermi (mem_frag addr:$src1),
8879                               (i8 imm:$src2))))]>,
8880                      Sched<[Sched.Folded, ReadAfterLd]>, VEX, VEX_L;
8881 }
8882
8883 defm VPERMQ : avx2_perm_imm<0x00, "vpermq", loadv4i64, v4i64,
8884                             WriteShuffle256>, VEX_W;
8885 let ExeDomain = SSEPackedDouble in
8886 defm VPERMPD : avx2_perm_imm<0x01, "vpermpd", loadv4f64, v4f64,
8887                              WriteFShuffle256>, VEX_W;
8888
8889 //===----------------------------------------------------------------------===//
8890 // VPERM2I128 - Permute Floating-Point Values in 128-bit chunks
8891 //
8892 def VPERM2I128rr : AVX2AIi8<0x46, MRMSrcReg, (outs VR256:$dst),
8893           (ins VR256:$src1, VR256:$src2, i8imm:$src3),
8894           "vperm2i128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
8895           [(set VR256:$dst, (v4i64 (X86VPerm2x128 VR256:$src1, VR256:$src2,
8896                             (i8 imm:$src3))))]>, Sched<[WriteShuffle256]>,
8897           VEX_4V, VEX_L;
8898 def VPERM2I128rm : AVX2AIi8<0x46, MRMSrcMem, (outs VR256:$dst),
8899           (ins VR256:$src1, f256mem:$src2, i8imm:$src3),
8900           "vperm2i128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
8901           [(set VR256:$dst, (X86VPerm2x128 VR256:$src1, (loadv4i64 addr:$src2),
8902                              (i8 imm:$src3)))]>,
8903           Sched<[WriteShuffle256Ld, ReadAfterLd]>, VEX_4V, VEX_L;
8904
8905 let Predicates = [HasAVX2] in {
8906 def : Pat<(v8i32 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
8907           (VPERM2I128rr VR256:$src1, VR256:$src2, imm:$imm)>;
8908 def : Pat<(v32i8 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
8909           (VPERM2I128rr VR256:$src1, VR256:$src2, imm:$imm)>;
8910 def : Pat<(v16i16 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
8911           (VPERM2I128rr VR256:$src1, VR256:$src2, imm:$imm)>;
8912
8913 def : Pat<(v32i8 (X86VPerm2x128 VR256:$src1, (bc_v32i8 (loadv4i64 addr:$src2)),
8914                   (i8 imm:$imm))),
8915           (VPERM2I128rm VR256:$src1, addr:$src2, imm:$imm)>;
8916 def : Pat<(v16i16 (X86VPerm2x128 VR256:$src1,
8917                    (bc_v16i16 (loadv4i64 addr:$src2)), (i8 imm:$imm))),
8918           (VPERM2I128rm VR256:$src1, addr:$src2, imm:$imm)>;
8919 def : Pat<(v8i32 (X86VPerm2x128 VR256:$src1, (bc_v8i32 (loadv4i64 addr:$src2)),
8920                   (i8 imm:$imm))),
8921           (VPERM2I128rm VR256:$src1, addr:$src2, imm:$imm)>;
8922 }
8923
8924
8925 //===----------------------------------------------------------------------===//
8926 // VINSERTI128 - Insert packed integer values
8927 //
8928 let neverHasSideEffects = 1 in {
8929 def VINSERTI128rr : AVX2AIi8<0x38, MRMSrcReg, (outs VR256:$dst),
8930           (ins VR256:$src1, VR128:$src2, i8imm:$src3),
8931           "vinserti128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
8932           []>, Sched<[WriteShuffle256]>, VEX_4V, VEX_L;
8933 let mayLoad = 1 in
8934 def VINSERTI128rm : AVX2AIi8<0x38, MRMSrcMem, (outs VR256:$dst),
8935           (ins VR256:$src1, i128mem:$src2, i8imm:$src3),
8936           "vinserti128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
8937           []>, Sched<[WriteShuffle256Ld, ReadAfterLd]>, VEX_4V, VEX_L;
8938 }
8939
8940 let Predicates = [HasAVX2] in {
8941 def : Pat<(vinsert128_insert:$ins (v4i64 VR256:$src1), (v2i64 VR128:$src2),
8942                                    (iPTR imm)),
8943           (VINSERTI128rr VR256:$src1, VR128:$src2,
8944                          (INSERT_get_vinsert128_imm VR256:$ins))>;
8945 def : Pat<(vinsert128_insert:$ins (v8i32 VR256:$src1), (v4i32 VR128:$src2),
8946                                    (iPTR imm)),
8947           (VINSERTI128rr VR256:$src1, VR128:$src2,
8948                          (INSERT_get_vinsert128_imm VR256:$ins))>;
8949 def : Pat<(vinsert128_insert:$ins (v32i8 VR256:$src1), (v16i8 VR128:$src2),
8950                                    (iPTR imm)),
8951           (VINSERTI128rr VR256:$src1, VR128:$src2,
8952                          (INSERT_get_vinsert128_imm VR256:$ins))>;
8953 def : Pat<(vinsert128_insert:$ins (v16i16 VR256:$src1), (v8i16 VR128:$src2),
8954                                    (iPTR imm)),
8955           (VINSERTI128rr VR256:$src1, VR128:$src2,
8956                          (INSERT_get_vinsert128_imm VR256:$ins))>;
8957
8958 def : Pat<(vinsert128_insert:$ins (v4i64 VR256:$src1), (loadv2i64 addr:$src2),
8959                                    (iPTR imm)),
8960           (VINSERTI128rm VR256:$src1, addr:$src2,
8961                          (INSERT_get_vinsert128_imm VR256:$ins))>;
8962 def : Pat<(vinsert128_insert:$ins (v8i32 VR256:$src1),
8963                                    (bc_v4i32 (loadv2i64 addr:$src2)),
8964                                    (iPTR imm)),
8965           (VINSERTI128rm VR256:$src1, addr:$src2,
8966                          (INSERT_get_vinsert128_imm VR256:$ins))>;
8967 def : Pat<(vinsert128_insert:$ins (v32i8 VR256:$src1),
8968                                    (bc_v16i8 (loadv2i64 addr:$src2)),
8969                                    (iPTR imm)),
8970           (VINSERTI128rm VR256:$src1, addr:$src2,
8971                          (INSERT_get_vinsert128_imm VR256:$ins))>;
8972 def : Pat<(vinsert128_insert:$ins (v16i16 VR256:$src1),
8973                                    (bc_v8i16 (loadv2i64 addr:$src2)),
8974                                    (iPTR imm)),
8975           (VINSERTI128rm VR256:$src1, addr:$src2,
8976                          (INSERT_get_vinsert128_imm VR256:$ins))>;
8977 }
8978
8979 //===----------------------------------------------------------------------===//
8980 // VEXTRACTI128 - Extract packed integer values
8981 //
8982 def VEXTRACTI128rr : AVX2AIi8<0x39, MRMDestReg, (outs VR128:$dst),
8983           (ins VR256:$src1, i8imm:$src2),
8984           "vextracti128\t{$src2, $src1, $dst|$dst, $src1, $src2}",
8985           [(set VR128:$dst,
8986             (int_x86_avx2_vextracti128 VR256:$src1, imm:$src2))]>,
8987           Sched<[WriteShuffle256]>, VEX, VEX_L;
8988 let neverHasSideEffects = 1, mayStore = 1 in
8989 def VEXTRACTI128mr : AVX2AIi8<0x39, MRMDestMem, (outs),
8990           (ins i128mem:$dst, VR256:$src1, i8imm:$src2),
8991           "vextracti128\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>,
8992           Sched<[WriteStore]>, VEX, VEX_L;
8993
8994 let Predicates = [HasAVX2] in {
8995 def : Pat<(vextract128_extract:$ext VR256:$src1, (iPTR imm)),
8996           (v2i64 (VEXTRACTI128rr
8997                     (v4i64 VR256:$src1),
8998                     (EXTRACT_get_vextract128_imm VR128:$ext)))>;
8999 def : Pat<(vextract128_extract:$ext VR256:$src1, (iPTR imm)),
9000           (v4i32 (VEXTRACTI128rr
9001                     (v8i32 VR256:$src1),
9002                     (EXTRACT_get_vextract128_imm VR128:$ext)))>;
9003 def : Pat<(vextract128_extract:$ext VR256:$src1, (iPTR imm)),
9004           (v8i16 (VEXTRACTI128rr
9005                     (v16i16 VR256:$src1),
9006                     (EXTRACT_get_vextract128_imm VR128:$ext)))>;
9007 def : Pat<(vextract128_extract:$ext VR256:$src1, (iPTR imm)),
9008           (v16i8 (VEXTRACTI128rr
9009                     (v32i8 VR256:$src1),
9010                     (EXTRACT_get_vextract128_imm VR128:$ext)))>;
9011
9012 def : Pat<(store (v2i64 (vextract128_extract:$ext (v4i64 VR256:$src1),
9013                          (iPTR imm))), addr:$dst),
9014           (VEXTRACTI128mr addr:$dst, VR256:$src1,
9015            (EXTRACT_get_vextract128_imm VR128:$ext))>;
9016 def : Pat<(store (v4i32 (vextract128_extract:$ext (v8i32 VR256:$src1),
9017                          (iPTR imm))), addr:$dst),
9018           (VEXTRACTI128mr addr:$dst, VR256:$src1,
9019            (EXTRACT_get_vextract128_imm VR128:$ext))>;
9020 def : Pat<(store (v8i16 (vextract128_extract:$ext (v16i16 VR256:$src1),
9021                          (iPTR imm))), addr:$dst),
9022           (VEXTRACTI128mr addr:$dst, VR256:$src1,
9023            (EXTRACT_get_vextract128_imm VR128:$ext))>;
9024 def : Pat<(store (v16i8 (vextract128_extract:$ext (v32i8 VR256:$src1),
9025                          (iPTR imm))), addr:$dst),
9026           (VEXTRACTI128mr addr:$dst, VR256:$src1,
9027            (EXTRACT_get_vextract128_imm VR128:$ext))>;
9028 }
9029
9030 //===----------------------------------------------------------------------===//
9031 // VPMASKMOV - Conditional SIMD Integer Packed Loads and Stores
9032 //
9033 multiclass avx2_pmovmask<string OpcodeStr,
9034                          Intrinsic IntLd128, Intrinsic IntLd256,
9035                          Intrinsic IntSt128, Intrinsic IntSt256> {
9036   def rm  : AVX28I<0x8c, MRMSrcMem, (outs VR128:$dst),
9037              (ins VR128:$src1, i128mem:$src2),
9038              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
9039              [(set VR128:$dst, (IntLd128 addr:$src2, VR128:$src1))]>, VEX_4V;
9040   def Yrm : AVX28I<0x8c, MRMSrcMem, (outs VR256:$dst),
9041              (ins VR256:$src1, i256mem:$src2),
9042              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
9043              [(set VR256:$dst, (IntLd256 addr:$src2, VR256:$src1))]>,
9044              VEX_4V, VEX_L;
9045   def mr  : AVX28I<0x8e, MRMDestMem, (outs),
9046              (ins i128mem:$dst, VR128:$src1, VR128:$src2),
9047              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
9048              [(IntSt128 addr:$dst, VR128:$src1, VR128:$src2)]>, VEX_4V;
9049   def Ymr : AVX28I<0x8e, MRMDestMem, (outs),
9050              (ins i256mem:$dst, VR256:$src1, VR256:$src2),
9051              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
9052              [(IntSt256 addr:$dst, VR256:$src1, VR256:$src2)]>, VEX_4V, VEX_L;
9053 }
9054
9055 defm VPMASKMOVD : avx2_pmovmask<"vpmaskmovd",
9056                                 int_x86_avx2_maskload_d,
9057                                 int_x86_avx2_maskload_d_256,
9058                                 int_x86_avx2_maskstore_d,
9059                                 int_x86_avx2_maskstore_d_256>;
9060 defm VPMASKMOVQ : avx2_pmovmask<"vpmaskmovq",
9061                                 int_x86_avx2_maskload_q,
9062                                 int_x86_avx2_maskload_q_256,
9063                                 int_x86_avx2_maskstore_q,
9064                                 int_x86_avx2_maskstore_q_256>, VEX_W;
9065
9066
9067 //===----------------------------------------------------------------------===//
9068 // Variable Bit Shifts
9069 //
9070 multiclass avx2_var_shift<bits<8> opc, string OpcodeStr, SDNode OpNode,
9071                           ValueType vt128, ValueType vt256> {
9072   def rr  : AVX28I<opc, MRMSrcReg, (outs VR128:$dst),
9073              (ins VR128:$src1, VR128:$src2),
9074              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
9075              [(set VR128:$dst,
9076                (vt128 (OpNode VR128:$src1, (vt128 VR128:$src2))))]>,
9077              VEX_4V, Sched<[WriteVarVecShift]>;
9078   def rm  : AVX28I<opc, MRMSrcMem, (outs VR128:$dst),
9079              (ins VR128:$src1, i128mem:$src2),
9080              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
9081              [(set VR128:$dst,
9082                (vt128 (OpNode VR128:$src1,
9083                        (vt128 (bitconvert (loadv2i64 addr:$src2))))))]>,
9084              VEX_4V, Sched<[WriteVarVecShiftLd, ReadAfterLd]>;
9085   def Yrr : AVX28I<opc, MRMSrcReg, (outs VR256:$dst),
9086              (ins VR256:$src1, VR256:$src2),
9087              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
9088              [(set VR256:$dst,
9089                (vt256 (OpNode VR256:$src1, (vt256 VR256:$src2))))]>,
9090              VEX_4V, VEX_L, Sched<[WriteVarVecShift]>;
9091   def Yrm : AVX28I<opc, MRMSrcMem, (outs VR256:$dst),
9092              (ins VR256:$src1, i256mem:$src2),
9093              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
9094              [(set VR256:$dst,
9095                (vt256 (OpNode VR256:$src1,
9096                        (vt256 (bitconvert (loadv4i64 addr:$src2))))))]>,
9097              VEX_4V, VEX_L, Sched<[WriteVarVecShiftLd, ReadAfterLd]>;
9098 }
9099
9100 defm VPSLLVD : avx2_var_shift<0x47, "vpsllvd", shl, v4i32, v8i32>;
9101 defm VPSLLVQ : avx2_var_shift<0x47, "vpsllvq", shl, v2i64, v4i64>, VEX_W;
9102 defm VPSRLVD : avx2_var_shift<0x45, "vpsrlvd", srl, v4i32, v8i32>;
9103 defm VPSRLVQ : avx2_var_shift<0x45, "vpsrlvq", srl, v2i64, v4i64>, VEX_W;
9104 defm VPSRAVD : avx2_var_shift<0x46, "vpsravd", sra, v4i32, v8i32>;
9105
9106 //===----------------------------------------------------------------------===//
9107 // VGATHER - GATHER Operations
9108 multiclass avx2_gather<bits<8> opc, string OpcodeStr, RegisterClass RC256,
9109                        X86MemOperand memop128, X86MemOperand memop256> {
9110   def rm  : AVX28I<opc, MRMSrcMem, (outs VR128:$dst, VR128:$mask_wb),
9111             (ins VR128:$src1, memop128:$src2, VR128:$mask),
9112             !strconcat(OpcodeStr,
9113               "\t{$mask, $src2, $dst|$dst, $src2, $mask}"),
9114             []>, VEX_4VOp3;
9115   def Yrm : AVX28I<opc, MRMSrcMem, (outs RC256:$dst, RC256:$mask_wb),
9116             (ins RC256:$src1, memop256:$src2, RC256:$mask),
9117             !strconcat(OpcodeStr,
9118               "\t{$mask, $src2, $dst|$dst, $src2, $mask}"),
9119             []>, VEX_4VOp3, VEX_L;
9120 }
9121
9122 let mayLoad = 1, Constraints
9123   = "@earlyclobber $dst,@earlyclobber $mask_wb, $src1 = $dst, $mask = $mask_wb"
9124   in {
9125   defm VPGATHERDQ : avx2_gather<0x90, "vpgatherdq", VR256, vx64mem, vx64mem>, VEX_W;
9126   defm VPGATHERQQ : avx2_gather<0x91, "vpgatherqq", VR256, vx64mem, vy64mem>, VEX_W;
9127   defm VPGATHERDD : avx2_gather<0x90, "vpgatherdd", VR256, vx32mem, vy32mem>;
9128   defm VPGATHERQD : avx2_gather<0x91, "vpgatherqd", VR128, vx32mem, vy32mem>;
9129
9130   let ExeDomain = SSEPackedDouble in {
9131     defm VGATHERDPD : avx2_gather<0x92, "vgatherdpd", VR256, vx64mem, vx64mem>, VEX_W;
9132     defm VGATHERQPD : avx2_gather<0x93, "vgatherqpd", VR256, vx64mem, vy64mem>, VEX_W;
9133   }
9134
9135   let ExeDomain = SSEPackedSingle in {
9136     defm VGATHERDPS : avx2_gather<0x92, "vgatherdps", VR256, vx32mem, vy32mem>;
9137     defm VGATHERQPS : avx2_gather<0x93, "vgatherqps", VR128, vx32mem, vy32mem>;
9138   }
9139 }