[AVX512] Added load/store from BW/VL subsets to Register2Memory opcode tables.
[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
1273   // Store patterns
1274   def : Pat<(store (v4f32 (X86Movlps (load addr:$src1), VR128:$src2)),
1275                    addr:$src1),
1276             (VMOVLPSmr addr:$src1, VR128:$src2)>;
1277   def : Pat<(store (v4i32 (X86Movlps
1278                    (bc_v4i32 (loadv2i64 addr:$src1)), VR128:$src2)), addr:$src1),
1279             (VMOVLPSmr addr:$src1, VR128:$src2)>;
1280   def : Pat<(store (v2f64 (X86Movlpd (load addr:$src1), VR128:$src2)),
1281                    addr:$src1),
1282             (VMOVLPDmr addr:$src1, VR128:$src2)>;
1283   def : Pat<(store (v2i64 (X86Movlpd (load addr:$src1), VR128:$src2)),
1284                    addr:$src1),
1285             (VMOVLPDmr addr:$src1, VR128:$src2)>;
1286 }
1287
1288 let Predicates = [UseSSE1] in {
1289   // (store (vector_shuffle (load addr), v2, <4, 5, 2, 3>), addr) using MOVLPS
1290   def : Pat<(store (i64 (vector_extract (bc_v2i64 (v4f32 VR128:$src2)),
1291                                  (iPTR 0))), addr:$src1),
1292             (MOVLPSmr addr:$src1, VR128:$src2)>;
1293
1294   // Shuffle with MOVLPS
1295   def : Pat<(v4f32 (X86Movlps VR128:$src1, (load addr:$src2))),
1296             (MOVLPSrm VR128:$src1, addr:$src2)>;
1297   def : Pat<(v4i32 (X86Movlps VR128:$src1, (load addr:$src2))),
1298             (MOVLPSrm VR128:$src1, addr:$src2)>;
1299   def : Pat<(X86Movlps VR128:$src1,
1300                       (bc_v4f32 (v2i64 (scalar_to_vector (loadi64 addr:$src2))))),
1301             (MOVLPSrm VR128:$src1, addr:$src2)>;
1302
1303   // Store patterns
1304   def : Pat<(store (v4f32 (X86Movlps (load addr:$src1), VR128:$src2)),
1305                                       addr:$src1),
1306             (MOVLPSmr addr:$src1, VR128:$src2)>;
1307   def : Pat<(store (v4i32 (X86Movlps
1308                    (bc_v4i32 (loadv2i64 addr:$src1)), VR128:$src2)),
1309                               addr:$src1),
1310             (MOVLPSmr addr:$src1, VR128:$src2)>;
1311 }
1312
1313 let Predicates = [UseSSE2] in {
1314   // Shuffle with MOVLPD
1315   def : Pat<(v2f64 (X86Movlpd VR128:$src1, (load addr:$src2))),
1316             (MOVLPDrm VR128:$src1, addr:$src2)>;
1317   def : Pat<(v2i64 (X86Movlpd VR128:$src1, (load addr:$src2))),
1318             (MOVLPDrm VR128:$src1, addr:$src2)>;
1319
1320   // Store patterns
1321   def : Pat<(store (v2f64 (X86Movlpd (load addr:$src1), VR128:$src2)),
1322                            addr:$src1),
1323             (MOVLPDmr addr:$src1, VR128:$src2)>;
1324   def : Pat<(store (v2i64 (X86Movlpd (load addr:$src1), VR128:$src2)),
1325                            addr:$src1),
1326             (MOVLPDmr addr:$src1, VR128:$src2)>;
1327 }
1328
1329 //===----------------------------------------------------------------------===//
1330 // SSE 1 & 2 - Move Hi packed FP Instructions
1331 //===----------------------------------------------------------------------===//
1332
1333 let AddedComplexity = 20 in {
1334   defm MOVH : sse12_mov_hilo_packed<0x16, X86Movlhps, X86Movlhpd, "movhp",
1335                                     IIC_SSE_MOV_LH>;
1336 }
1337
1338 let SchedRW = [WriteStore] in {
1339 // v2f64 extract element 1 is always custom lowered to unpack high to low
1340 // and extract element 0 so the non-store version isn't too horrible.
1341 def VMOVHPSmr : VPSI<0x17, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
1342                    "movhps\t{$src, $dst|$dst, $src}",
1343                    [(store (f64 (vector_extract
1344                                  (X86Unpckh (bc_v2f64 (v4f32 VR128:$src)),
1345                                             (bc_v2f64 (v4f32 VR128:$src))),
1346                                  (iPTR 0))), addr:$dst)], IIC_SSE_MOV_LH>, VEX;
1347 def VMOVHPDmr : VPDI<0x17, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
1348                    "movhpd\t{$src, $dst|$dst, $src}",
1349                    [(store (f64 (vector_extract
1350                                  (v2f64 (X86Unpckh VR128:$src, VR128:$src)),
1351                                  (iPTR 0))), addr:$dst)], IIC_SSE_MOV_LH>, VEX;
1352 def MOVHPSmr : PSI<0x17, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
1353                    "movhps\t{$src, $dst|$dst, $src}",
1354                    [(store (f64 (vector_extract
1355                                  (X86Unpckh (bc_v2f64 (v4f32 VR128:$src)),
1356                                             (bc_v2f64 (v4f32 VR128:$src))),
1357                                  (iPTR 0))), addr:$dst)], IIC_SSE_MOV_LH>;
1358 def MOVHPDmr : PDI<0x17, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
1359                    "movhpd\t{$src, $dst|$dst, $src}",
1360                    [(store (f64 (vector_extract
1361                                  (v2f64 (X86Unpckh VR128:$src, VR128:$src)),
1362                                  (iPTR 0))), addr:$dst)], IIC_SSE_MOV_LH>;
1363 } // SchedRW
1364
1365 let Predicates = [HasAVX] in {
1366   // VMOVHPS patterns
1367   def : Pat<(X86Movlhps VR128:$src1,
1368                  (bc_v4f32 (v2i64 (scalar_to_vector (loadi64 addr:$src2))))),
1369             (VMOVHPSrm VR128:$src1, addr:$src2)>;
1370   def : Pat<(X86Movlhps VR128:$src1,
1371                  (bc_v4i32 (v2i64 (X86vzload addr:$src2)))),
1372             (VMOVHPSrm VR128:$src1, addr:$src2)>;
1373
1374   // FIXME: Instead of X86Unpckl, there should be a X86Movlhpd here, the problem
1375   // is during lowering, where it's not possible to recognize the load fold
1376   // cause it has two uses through a bitcast. One use disappears at isel time
1377   // and the fold opportunity reappears.
1378   def : Pat<(v2f64 (X86Unpckl VR128:$src1,
1379                       (scalar_to_vector (loadf64 addr:$src2)))),
1380             (VMOVHPDrm VR128:$src1, addr:$src2)>;
1381 }
1382
1383 let Predicates = [UseSSE1] in {
1384   // MOVHPS patterns
1385   def : Pat<(X86Movlhps VR128:$src1,
1386                  (bc_v4f32 (v2i64 (scalar_to_vector (loadi64 addr:$src2))))),
1387             (MOVHPSrm VR128:$src1, addr:$src2)>;
1388   def : Pat<(X86Movlhps VR128:$src1,
1389                  (bc_v4f32 (v2i64 (X86vzload addr:$src2)))),
1390             (MOVHPSrm VR128:$src1, addr:$src2)>;
1391 }
1392
1393 let Predicates = [UseSSE2] in {
1394   // FIXME: Instead of X86Unpckl, there should be a X86Movlhpd here, the problem
1395   // is during lowering, where it's not possible to recognize the load fold
1396   // cause it has two uses through a bitcast. One use disappears at isel time
1397   // and the fold opportunity reappears.
1398   def : Pat<(v2f64 (X86Unpckl VR128:$src1,
1399                       (scalar_to_vector (loadf64 addr:$src2)))),
1400             (MOVHPDrm VR128:$src1, addr:$src2)>;
1401 }
1402
1403 //===----------------------------------------------------------------------===//
1404 // SSE 1 & 2 - Move Low to High and High to Low packed FP Instructions
1405 //===----------------------------------------------------------------------===//
1406
1407 let AddedComplexity = 20, Predicates = [UseAVX] in {
1408   def VMOVLHPSrr : VPSI<0x16, MRMSrcReg, (outs VR128:$dst),
1409                                        (ins VR128:$src1, VR128:$src2),
1410                       "movlhps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1411                       [(set VR128:$dst,
1412                         (v4f32 (X86Movlhps VR128:$src1, VR128:$src2)))],
1413                         IIC_SSE_MOV_LH>,
1414                       VEX_4V, Sched<[WriteFShuffle]>;
1415   def VMOVHLPSrr : VPSI<0x12, MRMSrcReg, (outs VR128:$dst),
1416                                        (ins VR128:$src1, VR128:$src2),
1417                       "movhlps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1418                       [(set VR128:$dst,
1419                         (v4f32 (X86Movhlps VR128:$src1, VR128:$src2)))],
1420                         IIC_SSE_MOV_LH>,
1421                       VEX_4V, Sched<[WriteFShuffle]>;
1422 }
1423 let Constraints = "$src1 = $dst", AddedComplexity = 20 in {
1424   def MOVLHPSrr : PSI<0x16, MRMSrcReg, (outs VR128:$dst),
1425                                        (ins VR128:$src1, VR128:$src2),
1426                       "movlhps\t{$src2, $dst|$dst, $src2}",
1427                       [(set VR128:$dst,
1428                         (v4f32 (X86Movlhps VR128:$src1, VR128:$src2)))],
1429                         IIC_SSE_MOV_LH>, Sched<[WriteFShuffle]>;
1430   def MOVHLPSrr : PSI<0x12, MRMSrcReg, (outs VR128:$dst),
1431                                        (ins VR128:$src1, VR128:$src2),
1432                       "movhlps\t{$src2, $dst|$dst, $src2}",
1433                       [(set VR128:$dst,
1434                         (v4f32 (X86Movhlps VR128:$src1, VR128:$src2)))],
1435                         IIC_SSE_MOV_LH>, Sched<[WriteFShuffle]>;
1436 }
1437
1438 let Predicates = [UseAVX] in {
1439   // MOVLHPS patterns
1440   def : Pat<(v4i32 (X86Movlhps VR128:$src1, VR128:$src2)),
1441             (VMOVLHPSrr VR128:$src1, VR128:$src2)>;
1442   def : Pat<(v2i64 (X86Movlhps VR128:$src1, VR128:$src2)),
1443             (VMOVLHPSrr (v2i64 VR128:$src1), VR128:$src2)>;
1444
1445   // MOVHLPS patterns
1446   def : Pat<(v4i32 (X86Movhlps VR128:$src1, VR128:$src2)),
1447             (VMOVHLPSrr VR128:$src1, VR128:$src2)>;
1448 }
1449
1450 let Predicates = [UseSSE1] in {
1451   // MOVLHPS patterns
1452   def : Pat<(v4i32 (X86Movlhps VR128:$src1, VR128:$src2)),
1453             (MOVLHPSrr VR128:$src1, VR128:$src2)>;
1454   def : Pat<(v2i64 (X86Movlhps VR128:$src1, VR128:$src2)),
1455             (MOVLHPSrr (v2i64 VR128:$src1), VR128:$src2)>;
1456
1457   // MOVHLPS patterns
1458   def : Pat<(v4i32 (X86Movhlps VR128:$src1, VR128:$src2)),
1459             (MOVHLPSrr VR128:$src1, VR128:$src2)>;
1460 }
1461
1462 //===----------------------------------------------------------------------===//
1463 // SSE 1 & 2 - Conversion Instructions
1464 //===----------------------------------------------------------------------===//
1465
1466 def SSE_CVT_PD : OpndItins<
1467   IIC_SSE_CVT_PD_RR, IIC_SSE_CVT_PD_RM
1468 >;
1469
1470 let Sched = WriteCvtI2F in
1471 def SSE_CVT_PS : OpndItins<
1472   IIC_SSE_CVT_PS_RR, IIC_SSE_CVT_PS_RM
1473 >;
1474
1475 let Sched = WriteCvtI2F in
1476 def SSE_CVT_Scalar : OpndItins<
1477   IIC_SSE_CVT_Scalar_RR, IIC_SSE_CVT_Scalar_RM
1478 >;
1479
1480 let Sched = WriteCvtF2I in
1481 def SSE_CVT_SS2SI_32 : OpndItins<
1482   IIC_SSE_CVT_SS2SI32_RR, IIC_SSE_CVT_SS2SI32_RM
1483 >;
1484
1485 let Sched = WriteCvtF2I in
1486 def SSE_CVT_SS2SI_64 : OpndItins<
1487   IIC_SSE_CVT_SS2SI64_RR, IIC_SSE_CVT_SS2SI64_RM
1488 >;
1489
1490 let Sched = WriteCvtF2I in
1491 def SSE_CVT_SD2SI : OpndItins<
1492   IIC_SSE_CVT_SD2SI_RR, IIC_SSE_CVT_SD2SI_RM
1493 >;
1494
1495 multiclass sse12_cvt_s<bits<8> opc, RegisterClass SrcRC, RegisterClass DstRC,
1496                      SDNode OpNode, X86MemOperand x86memop, PatFrag ld_frag,
1497                      string asm, OpndItins itins> {
1498   def rr : SI<opc, MRMSrcReg, (outs DstRC:$dst), (ins SrcRC:$src), asm,
1499                         [(set DstRC:$dst, (OpNode SrcRC:$src))],
1500                         itins.rr>, Sched<[itins.Sched]>;
1501   def rm : SI<opc, MRMSrcMem, (outs DstRC:$dst), (ins x86memop:$src), asm,
1502                         [(set DstRC:$dst, (OpNode (ld_frag addr:$src)))],
1503                         itins.rm>, Sched<[itins.Sched.Folded]>;
1504 }
1505
1506 multiclass sse12_cvt_p<bits<8> opc, RegisterClass SrcRC, RegisterClass DstRC,
1507                        X86MemOperand x86memop, string asm, Domain d,
1508                        OpndItins itins> {
1509 let neverHasSideEffects = 1 in {
1510   def rr : I<opc, MRMSrcReg, (outs DstRC:$dst), (ins SrcRC:$src), asm,
1511              [], itins.rr, d>, Sched<[itins.Sched]>;
1512   let mayLoad = 1 in
1513   def rm : I<opc, MRMSrcMem, (outs DstRC:$dst), (ins x86memop:$src), asm,
1514              [], itins.rm, d>, Sched<[itins.Sched.Folded]>;
1515 }
1516 }
1517
1518 multiclass sse12_vcvt_avx<bits<8> opc, RegisterClass SrcRC, RegisterClass DstRC,
1519                           X86MemOperand x86memop, string asm> {
1520 let neverHasSideEffects = 1, Predicates = [UseAVX] in {
1521   def rr : SI<opc, MRMSrcReg, (outs DstRC:$dst), (ins DstRC:$src1, SrcRC:$src),
1522               !strconcat(asm,"\t{$src, $src1, $dst|$dst, $src1, $src}"), []>,
1523            Sched<[WriteCvtI2F]>;
1524   let mayLoad = 1 in
1525   def rm : SI<opc, MRMSrcMem, (outs DstRC:$dst),
1526               (ins DstRC:$src1, x86memop:$src),
1527               !strconcat(asm,"\t{$src, $src1, $dst|$dst, $src1, $src}"), []>,
1528            Sched<[WriteCvtI2FLd, ReadAfterLd]>;
1529 } // neverHasSideEffects = 1
1530 }
1531
1532 let Predicates = [UseAVX] in {
1533 defm VCVTTSS2SI   : sse12_cvt_s<0x2C, FR32, GR32, fp_to_sint, f32mem, loadf32,
1534                                 "cvttss2si\t{$src, $dst|$dst, $src}",
1535                                 SSE_CVT_SS2SI_32>,
1536                                 XS, VEX, VEX_LIG;
1537 defm VCVTTSS2SI64 : sse12_cvt_s<0x2C, FR32, GR64, fp_to_sint, f32mem, loadf32,
1538                                 "cvttss2si\t{$src, $dst|$dst, $src}",
1539                                 SSE_CVT_SS2SI_64>,
1540                                 XS, VEX, VEX_W, VEX_LIG;
1541 defm VCVTTSD2SI   : sse12_cvt_s<0x2C, FR64, GR32, fp_to_sint, f64mem, loadf64,
1542                                 "cvttsd2si\t{$src, $dst|$dst, $src}",
1543                                 SSE_CVT_SD2SI>,
1544                                 XD, VEX, VEX_LIG;
1545 defm VCVTTSD2SI64 : sse12_cvt_s<0x2C, FR64, GR64, fp_to_sint, f64mem, loadf64,
1546                                 "cvttsd2si\t{$src, $dst|$dst, $src}",
1547                                 SSE_CVT_SD2SI>,
1548                                 XD, VEX, VEX_W, VEX_LIG;
1549
1550 def : InstAlias<"vcvttss2si{l}\t{$src, $dst|$dst, $src}",
1551                 (VCVTTSS2SIrr GR32:$dst, FR32:$src), 0>;
1552 def : InstAlias<"vcvttss2si{l}\t{$src, $dst|$dst, $src}",
1553                 (VCVTTSS2SIrm GR32:$dst, f32mem:$src), 0>;
1554 def : InstAlias<"vcvttsd2si{l}\t{$src, $dst|$dst, $src}",
1555                 (VCVTTSD2SIrr GR32:$dst, FR64:$src), 0>;
1556 def : InstAlias<"vcvttsd2si{l}\t{$src, $dst|$dst, $src}",
1557                 (VCVTTSD2SIrm GR32:$dst, f64mem:$src), 0>;
1558 def : InstAlias<"vcvttss2si{q}\t{$src, $dst|$dst, $src}",
1559                 (VCVTTSS2SI64rr GR64:$dst, FR32:$src), 0>;
1560 def : InstAlias<"vcvttss2si{q}\t{$src, $dst|$dst, $src}",
1561                 (VCVTTSS2SI64rm GR64:$dst, f32mem:$src), 0>;
1562 def : InstAlias<"vcvttsd2si{q}\t{$src, $dst|$dst, $src}",
1563                 (VCVTTSD2SI64rr GR64:$dst, FR64:$src), 0>;
1564 def : InstAlias<"vcvttsd2si{q}\t{$src, $dst|$dst, $src}",
1565                 (VCVTTSD2SI64rm GR64:$dst, f64mem:$src), 0>;
1566 }
1567 // The assembler can recognize rr 64-bit instructions by seeing a rxx
1568 // register, but the same isn't true when only using memory operands,
1569 // provide other assembly "l" and "q" forms to address this explicitly
1570 // where appropriate to do so.
1571 defm VCVTSI2SS   : sse12_vcvt_avx<0x2A, GR32, FR32, i32mem, "cvtsi2ss{l}">,
1572                                   XS, VEX_4V, VEX_LIG;
1573 defm VCVTSI2SS64 : sse12_vcvt_avx<0x2A, GR64, FR32, i64mem, "cvtsi2ss{q}">,
1574                                   XS, VEX_4V, VEX_W, VEX_LIG;
1575 defm VCVTSI2SD   : sse12_vcvt_avx<0x2A, GR32, FR64, i32mem, "cvtsi2sd{l}">,
1576                                   XD, VEX_4V, VEX_LIG;
1577 defm VCVTSI2SD64 : sse12_vcvt_avx<0x2A, GR64, FR64, i64mem, "cvtsi2sd{q}">,
1578                                   XD, VEX_4V, VEX_W, VEX_LIG;
1579
1580 let Predicates = [UseAVX] in {
1581   def : InstAlias<"vcvtsi2ss\t{$src, $src1, $dst|$dst, $src1, $src}",
1582                 (VCVTSI2SSrm FR64:$dst, FR64:$src1, i32mem:$src), 0>;
1583   def : InstAlias<"vcvtsi2sd\t{$src, $src1, $dst|$dst, $src1, $src}",
1584                 (VCVTSI2SDrm FR64:$dst, FR64:$src1, i32mem:$src), 0>;
1585
1586   def : Pat<(f32 (sint_to_fp (loadi32 addr:$src))),
1587             (VCVTSI2SSrm (f32 (IMPLICIT_DEF)), addr:$src)>;
1588   def : Pat<(f32 (sint_to_fp (loadi64 addr:$src))),
1589             (VCVTSI2SS64rm (f32 (IMPLICIT_DEF)), addr:$src)>;
1590   def : Pat<(f64 (sint_to_fp (loadi32 addr:$src))),
1591             (VCVTSI2SDrm (f64 (IMPLICIT_DEF)), addr:$src)>;
1592   def : Pat<(f64 (sint_to_fp (loadi64 addr:$src))),
1593             (VCVTSI2SD64rm (f64 (IMPLICIT_DEF)), addr:$src)>;
1594
1595   def : Pat<(f32 (sint_to_fp GR32:$src)),
1596             (VCVTSI2SSrr (f32 (IMPLICIT_DEF)), GR32:$src)>;
1597   def : Pat<(f32 (sint_to_fp GR64:$src)),
1598             (VCVTSI2SS64rr (f32 (IMPLICIT_DEF)), GR64:$src)>;
1599   def : Pat<(f64 (sint_to_fp GR32:$src)),
1600             (VCVTSI2SDrr (f64 (IMPLICIT_DEF)), GR32:$src)>;
1601   def : Pat<(f64 (sint_to_fp GR64:$src)),
1602             (VCVTSI2SD64rr (f64 (IMPLICIT_DEF)), GR64:$src)>;
1603 }
1604
1605 defm CVTTSS2SI : sse12_cvt_s<0x2C, FR32, GR32, fp_to_sint, f32mem, loadf32,
1606                       "cvttss2si\t{$src, $dst|$dst, $src}",
1607                       SSE_CVT_SS2SI_32>, XS;
1608 defm CVTTSS2SI64 : sse12_cvt_s<0x2C, FR32, GR64, fp_to_sint, f32mem, loadf32,
1609                       "cvttss2si\t{$src, $dst|$dst, $src}",
1610                       SSE_CVT_SS2SI_64>, XS, REX_W;
1611 defm CVTTSD2SI : sse12_cvt_s<0x2C, FR64, GR32, fp_to_sint, f64mem, loadf64,
1612                       "cvttsd2si\t{$src, $dst|$dst, $src}",
1613                       SSE_CVT_SD2SI>, XD;
1614 defm CVTTSD2SI64 : sse12_cvt_s<0x2C, FR64, GR64, fp_to_sint, f64mem, loadf64,
1615                       "cvttsd2si\t{$src, $dst|$dst, $src}",
1616                       SSE_CVT_SD2SI>, XD, REX_W;
1617 defm CVTSI2SS  : sse12_cvt_s<0x2A, GR32, FR32, sint_to_fp, i32mem, loadi32,
1618                       "cvtsi2ss{l}\t{$src, $dst|$dst, $src}",
1619                       SSE_CVT_Scalar>, XS;
1620 defm CVTSI2SS64 : sse12_cvt_s<0x2A, GR64, FR32, sint_to_fp, i64mem, loadi64,
1621                       "cvtsi2ss{q}\t{$src, $dst|$dst, $src}",
1622                       SSE_CVT_Scalar>, XS, REX_W;
1623 defm CVTSI2SD  : sse12_cvt_s<0x2A, GR32, FR64, sint_to_fp, i32mem, loadi32,
1624                       "cvtsi2sd{l}\t{$src, $dst|$dst, $src}",
1625                       SSE_CVT_Scalar>, XD;
1626 defm CVTSI2SD64 : sse12_cvt_s<0x2A, GR64, FR64, sint_to_fp, i64mem, loadi64,
1627                       "cvtsi2sd{q}\t{$src, $dst|$dst, $src}",
1628                       SSE_CVT_Scalar>, XD, REX_W;
1629
1630 def : InstAlias<"cvttss2si{l}\t{$src, $dst|$dst, $src}",
1631                 (CVTTSS2SIrr GR32:$dst, FR32:$src), 0>;
1632 def : InstAlias<"cvttss2si{l}\t{$src, $dst|$dst, $src}",
1633                 (CVTTSS2SIrm GR32:$dst, f32mem:$src), 0>;
1634 def : InstAlias<"cvttsd2si{l}\t{$src, $dst|$dst, $src}",
1635                 (CVTTSD2SIrr GR32:$dst, FR64:$src), 0>;
1636 def : InstAlias<"cvttsd2si{l}\t{$src, $dst|$dst, $src}",
1637                 (CVTTSD2SIrm GR32:$dst, f64mem:$src), 0>;
1638 def : InstAlias<"cvttss2si{q}\t{$src, $dst|$dst, $src}",
1639                 (CVTTSS2SI64rr GR64:$dst, FR32:$src), 0>;
1640 def : InstAlias<"cvttss2si{q}\t{$src, $dst|$dst, $src}",
1641                 (CVTTSS2SI64rm GR64:$dst, f32mem:$src), 0>;
1642 def : InstAlias<"cvttsd2si{q}\t{$src, $dst|$dst, $src}",
1643                 (CVTTSD2SI64rr GR64:$dst, FR64:$src), 0>;
1644 def : InstAlias<"cvttsd2si{q}\t{$src, $dst|$dst, $src}",
1645                 (CVTTSD2SI64rm GR64:$dst, f64mem:$src), 0>;
1646
1647 def : InstAlias<"cvtsi2ss\t{$src, $dst|$dst, $src}",
1648                 (CVTSI2SSrm FR64:$dst, i32mem:$src), 0>;
1649 def : InstAlias<"cvtsi2sd\t{$src, $dst|$dst, $src}",
1650                 (CVTSI2SDrm FR64:$dst, i32mem:$src), 0>;
1651
1652 // Conversion Instructions Intrinsics - Match intrinsics which expect MM
1653 // and/or XMM operand(s).
1654
1655 multiclass sse12_cvt_sint<bits<8> opc, RegisterClass SrcRC, RegisterClass DstRC,
1656                          Intrinsic Int, Operand memop, ComplexPattern mem_cpat,
1657                          string asm, OpndItins itins> {
1658   def rr : SI<opc, MRMSrcReg, (outs DstRC:$dst), (ins SrcRC:$src),
1659               !strconcat(asm, "\t{$src, $dst|$dst, $src}"),
1660               [(set DstRC:$dst, (Int SrcRC:$src))], itins.rr>,
1661            Sched<[itins.Sched]>;
1662   def rm : SI<opc, MRMSrcMem, (outs DstRC:$dst), (ins memop:$src),
1663               !strconcat(asm, "\t{$src, $dst|$dst, $src}"),
1664               [(set DstRC:$dst, (Int mem_cpat:$src))], itins.rm>,
1665            Sched<[itins.Sched.Folded]>;
1666 }
1667
1668 multiclass sse12_cvt_sint_3addr<bits<8> opc, RegisterClass SrcRC,
1669                     RegisterClass DstRC, Intrinsic Int, X86MemOperand x86memop,
1670                     PatFrag ld_frag, string asm, OpndItins itins,
1671                     bit Is2Addr = 1> {
1672   def rr : SI<opc, MRMSrcReg, (outs DstRC:$dst), (ins DstRC:$src1, SrcRC:$src2),
1673               !if(Is2Addr,
1674                   !strconcat(asm, "\t{$src2, $dst|$dst, $src2}"),
1675                   !strconcat(asm, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
1676               [(set DstRC:$dst, (Int DstRC:$src1, SrcRC:$src2))],
1677               itins.rr>, Sched<[itins.Sched]>;
1678   def rm : SI<opc, MRMSrcMem, (outs DstRC:$dst),
1679               (ins DstRC:$src1, x86memop:$src2),
1680               !if(Is2Addr,
1681                   !strconcat(asm, "\t{$src2, $dst|$dst, $src2}"),
1682                   !strconcat(asm, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
1683               [(set DstRC:$dst, (Int DstRC:$src1, (ld_frag addr:$src2)))],
1684               itins.rm>, Sched<[itins.Sched.Folded, ReadAfterLd]>;
1685 }
1686
1687 let Predicates = [UseAVX] in {
1688 defm VCVTSD2SI : sse12_cvt_sint<0x2D, VR128, GR32,
1689                   int_x86_sse2_cvtsd2si, sdmem, sse_load_f64, "cvtsd2si",
1690                   SSE_CVT_SD2SI>, XD, VEX, VEX_LIG;
1691 defm VCVTSD2SI64 : sse12_cvt_sint<0x2D, VR128, GR64,
1692                     int_x86_sse2_cvtsd2si64, sdmem, sse_load_f64, "cvtsd2si",
1693                     SSE_CVT_SD2SI>, XD, VEX, VEX_W, VEX_LIG;
1694 }
1695 defm CVTSD2SI : sse12_cvt_sint<0x2D, VR128, GR32, int_x86_sse2_cvtsd2si,
1696                  sdmem, sse_load_f64, "cvtsd2si", SSE_CVT_SD2SI>, XD;
1697 defm CVTSD2SI64 : sse12_cvt_sint<0x2D, VR128, GR64, int_x86_sse2_cvtsd2si64,
1698                    sdmem, sse_load_f64, "cvtsd2si", SSE_CVT_SD2SI>, XD, REX_W;
1699
1700
1701 let isCodeGenOnly = 1 in {
1702   let Predicates = [UseAVX] in {
1703   defm Int_VCVTSI2SS : sse12_cvt_sint_3addr<0x2A, GR32, VR128,
1704             int_x86_sse_cvtsi2ss, i32mem, loadi32, "cvtsi2ss{l}",
1705             SSE_CVT_Scalar, 0>, XS, VEX_4V;
1706   defm Int_VCVTSI2SS64 : sse12_cvt_sint_3addr<0x2A, GR64, VR128,
1707             int_x86_sse_cvtsi642ss, i64mem, loadi64, "cvtsi2ss{q}",
1708             SSE_CVT_Scalar, 0>, XS, VEX_4V,
1709             VEX_W;
1710   defm Int_VCVTSI2SD : sse12_cvt_sint_3addr<0x2A, GR32, VR128,
1711             int_x86_sse2_cvtsi2sd, i32mem, loadi32, "cvtsi2sd{l}",
1712             SSE_CVT_Scalar, 0>, XD, VEX_4V;
1713   defm Int_VCVTSI2SD64 : sse12_cvt_sint_3addr<0x2A, GR64, VR128,
1714             int_x86_sse2_cvtsi642sd, i64mem, loadi64, "cvtsi2sd{q}",
1715             SSE_CVT_Scalar, 0>, XD,
1716             VEX_4V, VEX_W;
1717   }
1718   let Constraints = "$src1 = $dst" in {
1719     defm Int_CVTSI2SS : sse12_cvt_sint_3addr<0x2A, GR32, VR128,
1720                           int_x86_sse_cvtsi2ss, i32mem, loadi32,
1721                           "cvtsi2ss{l}", SSE_CVT_Scalar>, XS;
1722     defm Int_CVTSI2SS64 : sse12_cvt_sint_3addr<0x2A, GR64, VR128,
1723                           int_x86_sse_cvtsi642ss, i64mem, loadi64,
1724                           "cvtsi2ss{q}", SSE_CVT_Scalar>, XS, REX_W;
1725     defm Int_CVTSI2SD : sse12_cvt_sint_3addr<0x2A, GR32, VR128,
1726                           int_x86_sse2_cvtsi2sd, i32mem, loadi32,
1727                           "cvtsi2sd{l}", SSE_CVT_Scalar>, XD;
1728     defm Int_CVTSI2SD64 : sse12_cvt_sint_3addr<0x2A, GR64, VR128,
1729                           int_x86_sse2_cvtsi642sd, i64mem, loadi64,
1730                           "cvtsi2sd{q}", SSE_CVT_Scalar>, XD, REX_W;
1731   }
1732 } // isCodeGenOnly = 1
1733
1734 /// SSE 1 Only
1735
1736 // Aliases for intrinsics
1737 let isCodeGenOnly = 1 in {
1738 let Predicates = [UseAVX] in {
1739 defm Int_VCVTTSS2SI : sse12_cvt_sint<0x2C, VR128, GR32, int_x86_sse_cvttss2si,
1740                                     ssmem, sse_load_f32, "cvttss2si",
1741                                     SSE_CVT_SS2SI_32>, XS, VEX;
1742 defm Int_VCVTTSS2SI64 : sse12_cvt_sint<0x2C, VR128, GR64,
1743                                    int_x86_sse_cvttss2si64, ssmem, sse_load_f32,
1744                                    "cvttss2si", SSE_CVT_SS2SI_64>,
1745                                    XS, VEX, VEX_W;
1746 defm Int_VCVTTSD2SI : sse12_cvt_sint<0x2C, VR128, GR32, int_x86_sse2_cvttsd2si,
1747                                     sdmem, sse_load_f64, "cvttsd2si",
1748                                     SSE_CVT_SD2SI>, XD, VEX;
1749 defm Int_VCVTTSD2SI64 : sse12_cvt_sint<0x2C, VR128, GR64,
1750                                   int_x86_sse2_cvttsd2si64, sdmem, sse_load_f64,
1751                                   "cvttsd2si", SSE_CVT_SD2SI>,
1752                                   XD, VEX, VEX_W;
1753 }
1754 defm Int_CVTTSS2SI : sse12_cvt_sint<0x2C, VR128, GR32, int_x86_sse_cvttss2si,
1755                                     ssmem, sse_load_f32, "cvttss2si",
1756                                     SSE_CVT_SS2SI_32>, XS;
1757 defm Int_CVTTSS2SI64 : sse12_cvt_sint<0x2C, VR128, GR64,
1758                                    int_x86_sse_cvttss2si64, ssmem, sse_load_f32,
1759                                    "cvttss2si", SSE_CVT_SS2SI_64>, XS, REX_W;
1760 defm Int_CVTTSD2SI : sse12_cvt_sint<0x2C, VR128, GR32, int_x86_sse2_cvttsd2si,
1761                                     sdmem, sse_load_f64, "cvttsd2si",
1762                                     SSE_CVT_SD2SI>, XD;
1763 defm Int_CVTTSD2SI64 : sse12_cvt_sint<0x2C, VR128, GR64,
1764                                   int_x86_sse2_cvttsd2si64, sdmem, sse_load_f64,
1765                                   "cvttsd2si", SSE_CVT_SD2SI>, XD, REX_W;
1766 } // isCodeGenOnly = 1
1767
1768 let Predicates = [UseAVX] in {
1769 defm VCVTSS2SI   : sse12_cvt_sint<0x2D, VR128, GR32, int_x86_sse_cvtss2si,
1770                                   ssmem, sse_load_f32, "cvtss2si",
1771                                   SSE_CVT_SS2SI_32>, XS, VEX, VEX_LIG;
1772 defm VCVTSS2SI64 : sse12_cvt_sint<0x2D, VR128, GR64, int_x86_sse_cvtss2si64,
1773                                   ssmem, sse_load_f32, "cvtss2si",
1774                                   SSE_CVT_SS2SI_64>, XS, VEX, VEX_W, VEX_LIG;
1775 }
1776 defm CVTSS2SI : sse12_cvt_sint<0x2D, VR128, GR32, int_x86_sse_cvtss2si,
1777                                ssmem, sse_load_f32, "cvtss2si",
1778                                SSE_CVT_SS2SI_32>, XS;
1779 defm CVTSS2SI64 : sse12_cvt_sint<0x2D, VR128, GR64, int_x86_sse_cvtss2si64,
1780                                  ssmem, sse_load_f32, "cvtss2si",
1781                                  SSE_CVT_SS2SI_64>, XS, REX_W;
1782
1783 defm VCVTDQ2PS   : sse12_cvt_p<0x5B, VR128, VR128, i128mem,
1784                                "vcvtdq2ps\t{$src, $dst|$dst, $src}",
1785                                SSEPackedSingle, SSE_CVT_PS>,
1786                                PS, VEX, Requires<[HasAVX]>;
1787 defm VCVTDQ2PSY  : sse12_cvt_p<0x5B, VR256, VR256, i256mem,
1788                                "vcvtdq2ps\t{$src, $dst|$dst, $src}",
1789                                SSEPackedSingle, SSE_CVT_PS>,
1790                                PS, VEX, VEX_L, Requires<[HasAVX]>;
1791
1792 defm CVTDQ2PS : sse12_cvt_p<0x5B, VR128, VR128, i128mem,
1793                             "cvtdq2ps\t{$src, $dst|$dst, $src}",
1794                             SSEPackedSingle, SSE_CVT_PS>,
1795                             PS, Requires<[UseSSE2]>;
1796
1797 let Predicates = [UseAVX] in {
1798 def : InstAlias<"vcvtss2si{l}\t{$src, $dst|$dst, $src}",
1799                 (VCVTSS2SIrr GR32:$dst, VR128:$src), 0>;
1800 def : InstAlias<"vcvtss2si{l}\t{$src, $dst|$dst, $src}",
1801                 (VCVTSS2SIrm GR32:$dst, ssmem:$src), 0>;
1802 def : InstAlias<"vcvtsd2si{l}\t{$src, $dst|$dst, $src}",
1803                 (VCVTSD2SIrr GR32:$dst, VR128:$src), 0>;
1804 def : InstAlias<"vcvtsd2si{l}\t{$src, $dst|$dst, $src}",
1805                 (VCVTSD2SIrm GR32:$dst, sdmem:$src), 0>;
1806 def : InstAlias<"vcvtss2si{q}\t{$src, $dst|$dst, $src}",
1807                 (VCVTSS2SI64rr GR64:$dst, VR128:$src), 0>;
1808 def : InstAlias<"vcvtss2si{q}\t{$src, $dst|$dst, $src}",
1809                 (VCVTSS2SI64rm GR64:$dst, ssmem:$src), 0>;
1810 def : InstAlias<"vcvtsd2si{q}\t{$src, $dst|$dst, $src}",
1811                 (VCVTSD2SI64rr GR64:$dst, VR128:$src), 0>;
1812 def : InstAlias<"vcvtsd2si{q}\t{$src, $dst|$dst, $src}",
1813                 (VCVTSD2SI64rm GR64:$dst, sdmem:$src), 0>;
1814 }
1815
1816 def : InstAlias<"cvtss2si{l}\t{$src, $dst|$dst, $src}",
1817                 (CVTSS2SIrr GR32:$dst, VR128:$src), 0>;
1818 def : InstAlias<"cvtss2si{l}\t{$src, $dst|$dst, $src}",
1819                 (CVTSS2SIrm GR32:$dst, ssmem:$src), 0>;
1820 def : InstAlias<"cvtsd2si{l}\t{$src, $dst|$dst, $src}",
1821                 (CVTSD2SIrr GR32:$dst, VR128:$src), 0>;
1822 def : InstAlias<"cvtsd2si{l}\t{$src, $dst|$dst, $src}",
1823                 (CVTSD2SIrm GR32:$dst, sdmem:$src), 0>;
1824 def : InstAlias<"cvtss2si{q}\t{$src, $dst|$dst, $src}",
1825                 (CVTSS2SI64rr GR64:$dst, VR128:$src), 0>;
1826 def : InstAlias<"cvtss2si{q}\t{$src, $dst|$dst, $src}",
1827                 (CVTSS2SI64rm GR64:$dst, ssmem:$src), 0>;
1828 def : InstAlias<"cvtsd2si{q}\t{$src, $dst|$dst, $src}",
1829                 (CVTSD2SI64rr GR64:$dst, VR128:$src), 0>;
1830 def : InstAlias<"cvtsd2si{q}\t{$src, $dst|$dst, $src}",
1831                 (CVTSD2SI64rm GR64:$dst, sdmem:$src)>;
1832
1833 /// SSE 2 Only
1834
1835 // Convert scalar double to scalar single
1836 let neverHasSideEffects = 1, Predicates = [UseAVX] in {
1837 def VCVTSD2SSrr  : VSDI<0x5A, MRMSrcReg, (outs FR32:$dst),
1838                        (ins FR64:$src1, FR64:$src2),
1839                       "cvtsd2ss\t{$src2, $src1, $dst|$dst, $src1, $src2}", [],
1840                       IIC_SSE_CVT_Scalar_RR>, VEX_4V, VEX_LIG,
1841                       Sched<[WriteCvtF2F]>;
1842 let mayLoad = 1 in
1843 def VCVTSD2SSrm  : I<0x5A, MRMSrcMem, (outs FR32:$dst),
1844                        (ins FR64:$src1, f64mem:$src2),
1845                       "vcvtsd2ss\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1846                       [], IIC_SSE_CVT_Scalar_RM>,
1847                       XD, Requires<[HasAVX, OptForSize]>, VEX_4V, VEX_LIG,
1848                       Sched<[WriteCvtF2FLd, ReadAfterLd]>;
1849 }
1850
1851 def : Pat<(f32 (fround FR64:$src)), (VCVTSD2SSrr FR64:$src, FR64:$src)>,
1852           Requires<[UseAVX]>;
1853
1854 def CVTSD2SSrr  : SDI<0x5A, MRMSrcReg, (outs FR32:$dst), (ins FR64:$src),
1855                       "cvtsd2ss\t{$src, $dst|$dst, $src}",
1856                       [(set FR32:$dst, (fround FR64:$src))],
1857                       IIC_SSE_CVT_Scalar_RR>, Sched<[WriteCvtF2F]>;
1858 def CVTSD2SSrm  : I<0x5A, MRMSrcMem, (outs FR32:$dst), (ins f64mem:$src),
1859                       "cvtsd2ss\t{$src, $dst|$dst, $src}",
1860                       [(set FR32:$dst, (fround (loadf64 addr:$src)))],
1861                       IIC_SSE_CVT_Scalar_RM>,
1862                       XD,
1863                   Requires<[UseSSE2, OptForSize]>, Sched<[WriteCvtF2FLd]>;
1864
1865 let isCodeGenOnly = 1 in {
1866 def Int_VCVTSD2SSrr: I<0x5A, MRMSrcReg,
1867                        (outs VR128:$dst), (ins VR128:$src1, VR128:$src2),
1868                        "vcvtsd2ss\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1869                        [(set VR128:$dst,
1870                          (int_x86_sse2_cvtsd2ss VR128:$src1, VR128:$src2))],
1871                        IIC_SSE_CVT_Scalar_RR>, XD, VEX_4V, Requires<[UseAVX]>,
1872                        Sched<[WriteCvtF2F]>;
1873 def Int_VCVTSD2SSrm: I<0x5A, MRMSrcReg,
1874                        (outs VR128:$dst), (ins VR128:$src1, sdmem:$src2),
1875                        "vcvtsd2ss\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1876                        [(set VR128:$dst, (int_x86_sse2_cvtsd2ss
1877                                           VR128:$src1, sse_load_f64:$src2))],
1878                        IIC_SSE_CVT_Scalar_RM>, XD, VEX_4V, Requires<[UseAVX]>,
1879                        Sched<[WriteCvtF2FLd, ReadAfterLd]>;
1880
1881 let Constraints = "$src1 = $dst" in {
1882 def Int_CVTSD2SSrr: I<0x5A, MRMSrcReg,
1883                        (outs VR128:$dst), (ins VR128:$src1, VR128:$src2),
1884                        "cvtsd2ss\t{$src2, $dst|$dst, $src2}",
1885                        [(set VR128:$dst,
1886                          (int_x86_sse2_cvtsd2ss VR128:$src1, VR128:$src2))],
1887                        IIC_SSE_CVT_Scalar_RR>, XD, Requires<[UseSSE2]>,
1888                        Sched<[WriteCvtF2F]>;
1889 def Int_CVTSD2SSrm: I<0x5A, MRMSrcReg,
1890                        (outs VR128:$dst), (ins VR128:$src1, sdmem:$src2),
1891                        "cvtsd2ss\t{$src2, $dst|$dst, $src2}",
1892                        [(set VR128:$dst, (int_x86_sse2_cvtsd2ss
1893                                           VR128:$src1, sse_load_f64:$src2))],
1894                        IIC_SSE_CVT_Scalar_RM>, XD, Requires<[UseSSE2]>,
1895                        Sched<[WriteCvtF2FLd, ReadAfterLd]>;
1896 }
1897 } // isCodeGenOnly = 1
1898
1899 // Convert scalar single to scalar double
1900 // SSE2 instructions with XS prefix
1901 let neverHasSideEffects = 1, Predicates = [UseAVX] in {
1902 def VCVTSS2SDrr : I<0x5A, MRMSrcReg, (outs FR64:$dst),
1903                     (ins FR32:$src1, FR32:$src2),
1904                     "vcvtss2sd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1905                     [], IIC_SSE_CVT_Scalar_RR>,
1906                     XS, Requires<[HasAVX]>, VEX_4V, VEX_LIG,
1907                     Sched<[WriteCvtF2F]>;
1908 let mayLoad = 1 in
1909 def VCVTSS2SDrm : I<0x5A, MRMSrcMem, (outs FR64:$dst),
1910                     (ins FR32:$src1, f32mem:$src2),
1911                     "vcvtss2sd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1912                     [], IIC_SSE_CVT_Scalar_RM>,
1913                     XS, VEX_4V, VEX_LIG, Requires<[HasAVX, OptForSize]>,
1914                     Sched<[WriteCvtF2FLd, ReadAfterLd]>;
1915 }
1916
1917 def : Pat<(f64 (fextend FR32:$src)),
1918     (VCVTSS2SDrr FR32:$src, FR32:$src)>, Requires<[UseAVX]>;
1919 def : Pat<(fextend (loadf32 addr:$src)),
1920     (VCVTSS2SDrm (f32 (IMPLICIT_DEF)), addr:$src)>, Requires<[UseAVX]>;
1921
1922 def : Pat<(extloadf32 addr:$src),
1923     (VCVTSS2SDrm (f32 (IMPLICIT_DEF)), addr:$src)>,
1924     Requires<[UseAVX, OptForSize]>;
1925 def : Pat<(extloadf32 addr:$src),
1926     (VCVTSS2SDrr (f32 (IMPLICIT_DEF)), (VMOVSSrm addr:$src))>,
1927     Requires<[UseAVX, OptForSpeed]>;
1928
1929 def CVTSS2SDrr : I<0x5A, MRMSrcReg, (outs FR64:$dst), (ins FR32:$src),
1930                    "cvtss2sd\t{$src, $dst|$dst, $src}",
1931                    [(set FR64:$dst, (fextend FR32:$src))],
1932                    IIC_SSE_CVT_Scalar_RR>, XS,
1933                  Requires<[UseSSE2]>, Sched<[WriteCvtF2F]>;
1934 def CVTSS2SDrm : I<0x5A, MRMSrcMem, (outs FR64:$dst), (ins f32mem:$src),
1935                    "cvtss2sd\t{$src, $dst|$dst, $src}",
1936                    [(set FR64:$dst, (extloadf32 addr:$src))],
1937                    IIC_SSE_CVT_Scalar_RM>, XS,
1938                  Requires<[UseSSE2, OptForSize]>, Sched<[WriteCvtF2FLd]>;
1939
1940 // extload f32 -> f64.  This matches load+fextend because we have a hack in
1941 // the isel (PreprocessForFPConvert) that can introduce loads after dag
1942 // combine.
1943 // Since these loads aren't folded into the fextend, we have to match it
1944 // explicitly here.
1945 def : Pat<(fextend (loadf32 addr:$src)),
1946           (CVTSS2SDrm addr:$src)>, Requires<[UseSSE2]>;
1947 def : Pat<(extloadf32 addr:$src),
1948           (CVTSS2SDrr (MOVSSrm addr:$src))>, Requires<[UseSSE2, OptForSpeed]>;
1949
1950 let isCodeGenOnly = 1 in {
1951 def Int_VCVTSS2SDrr: I<0x5A, MRMSrcReg,
1952                       (outs VR128:$dst), (ins VR128:$src1, VR128:$src2),
1953                     "vcvtss2sd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1954                     [(set VR128:$dst,
1955                       (int_x86_sse2_cvtss2sd VR128:$src1, VR128:$src2))],
1956                     IIC_SSE_CVT_Scalar_RR>, XS, VEX_4V, Requires<[UseAVX]>,
1957                     Sched<[WriteCvtF2F]>;
1958 def Int_VCVTSS2SDrm: I<0x5A, MRMSrcMem,
1959                       (outs VR128:$dst), (ins VR128:$src1, ssmem:$src2),
1960                     "vcvtss2sd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1961                     [(set VR128:$dst,
1962                       (int_x86_sse2_cvtss2sd VR128:$src1, sse_load_f32:$src2))],
1963                     IIC_SSE_CVT_Scalar_RM>, XS, VEX_4V, Requires<[UseAVX]>,
1964                     Sched<[WriteCvtF2FLd, ReadAfterLd]>;
1965 let Constraints = "$src1 = $dst" in { // SSE2 instructions with XS prefix
1966 def Int_CVTSS2SDrr: I<0x5A, MRMSrcReg,
1967                       (outs VR128:$dst), (ins VR128:$src1, VR128:$src2),
1968                     "cvtss2sd\t{$src2, $dst|$dst, $src2}",
1969                     [(set VR128:$dst,
1970                       (int_x86_sse2_cvtss2sd VR128:$src1, VR128:$src2))],
1971                     IIC_SSE_CVT_Scalar_RR>, XS, Requires<[UseSSE2]>,
1972                     Sched<[WriteCvtF2F]>;
1973 def Int_CVTSS2SDrm: I<0x5A, MRMSrcMem,
1974                       (outs VR128:$dst), (ins VR128:$src1, ssmem:$src2),
1975                     "cvtss2sd\t{$src2, $dst|$dst, $src2}",
1976                     [(set VR128:$dst,
1977                       (int_x86_sse2_cvtss2sd VR128:$src1, sse_load_f32:$src2))],
1978                     IIC_SSE_CVT_Scalar_RM>, XS, Requires<[UseSSE2]>,
1979                     Sched<[WriteCvtF2FLd, ReadAfterLd]>;
1980 }
1981 } // isCodeGenOnly = 1
1982
1983 // Convert packed single/double fp to doubleword
1984 def VCVTPS2DQrr : VPDI<0x5B, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1985                        "cvtps2dq\t{$src, $dst|$dst, $src}",
1986                        [(set VR128:$dst, (int_x86_sse2_cvtps2dq VR128:$src))],
1987                        IIC_SSE_CVT_PS_RR>, VEX, Sched<[WriteCvtF2I]>;
1988 def VCVTPS2DQrm : VPDI<0x5B, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1989                        "cvtps2dq\t{$src, $dst|$dst, $src}",
1990                        [(set VR128:$dst,
1991                          (int_x86_sse2_cvtps2dq (loadv4f32 addr:$src)))],
1992                        IIC_SSE_CVT_PS_RM>, VEX, Sched<[WriteCvtF2ILd]>;
1993 def VCVTPS2DQYrr : VPDI<0x5B, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
1994                         "cvtps2dq\t{$src, $dst|$dst, $src}",
1995                         [(set VR256:$dst,
1996                           (int_x86_avx_cvt_ps2dq_256 VR256:$src))],
1997                         IIC_SSE_CVT_PS_RR>, VEX, VEX_L, Sched<[WriteCvtF2I]>;
1998 def VCVTPS2DQYrm : VPDI<0x5B, MRMSrcMem, (outs VR256:$dst), (ins f256mem:$src),
1999                         "cvtps2dq\t{$src, $dst|$dst, $src}",
2000                         [(set VR256:$dst,
2001                           (int_x86_avx_cvt_ps2dq_256 (loadv8f32 addr:$src)))],
2002                         IIC_SSE_CVT_PS_RM>, VEX, VEX_L, Sched<[WriteCvtF2ILd]>;
2003 def CVTPS2DQrr : PDI<0x5B, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2004                      "cvtps2dq\t{$src, $dst|$dst, $src}",
2005                      [(set VR128:$dst, (int_x86_sse2_cvtps2dq VR128:$src))],
2006                      IIC_SSE_CVT_PS_RR>, Sched<[WriteCvtF2I]>;
2007 def CVTPS2DQrm : PDI<0x5B, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
2008                      "cvtps2dq\t{$src, $dst|$dst, $src}",
2009                      [(set VR128:$dst,
2010                        (int_x86_sse2_cvtps2dq (memopv4f32 addr:$src)))],
2011                      IIC_SSE_CVT_PS_RM>, Sched<[WriteCvtF2ILd]>;
2012
2013
2014 // Convert Packed Double FP to Packed DW Integers
2015 let Predicates = [HasAVX] in {
2016 // The assembler can recognize rr 256-bit instructions by seeing a ymm
2017 // register, but the same isn't true when using memory operands instead.
2018 // Provide other assembly rr and rm forms to address this explicitly.
2019 def VCVTPD2DQrr  : SDI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2020                        "vcvtpd2dq\t{$src, $dst|$dst, $src}",
2021                        [(set VR128:$dst, (int_x86_sse2_cvtpd2dq VR128:$src))]>,
2022                        VEX, Sched<[WriteCvtF2I]>;
2023
2024 // XMM only
2025 def : InstAlias<"vcvtpd2dqx\t{$src, $dst|$dst, $src}",
2026                 (VCVTPD2DQrr VR128:$dst, VR128:$src), 0>;
2027 def VCVTPD2DQXrm : SDI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
2028                        "vcvtpd2dqx\t{$src, $dst|$dst, $src}",
2029                        [(set VR128:$dst,
2030                          (int_x86_sse2_cvtpd2dq (loadv2f64 addr:$src)))]>, VEX,
2031                        Sched<[WriteCvtF2ILd]>;
2032
2033 // YMM only
2034 def VCVTPD2DQYrr : SDI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR256:$src),
2035                        "vcvtpd2dq{y}\t{$src, $dst|$dst, $src}",
2036                        [(set VR128:$dst,
2037                          (int_x86_avx_cvt_pd2dq_256 VR256:$src))]>, VEX, VEX_L,
2038                        Sched<[WriteCvtF2I]>;
2039 def VCVTPD2DQYrm : SDI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f256mem:$src),
2040                        "vcvtpd2dq{y}\t{$src, $dst|$dst, $src}",
2041                        [(set VR128:$dst,
2042                          (int_x86_avx_cvt_pd2dq_256 (loadv4f64 addr:$src)))]>,
2043                        VEX, VEX_L, Sched<[WriteCvtF2ILd]>;
2044 def : InstAlias<"vcvtpd2dq\t{$src, $dst|$dst, $src}",
2045                 (VCVTPD2DQYrr VR128:$dst, VR256:$src), 0>;
2046 }
2047
2048 def CVTPD2DQrm  : SDI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
2049                       "cvtpd2dq\t{$src, $dst|$dst, $src}",
2050                       [(set VR128:$dst,
2051                         (int_x86_sse2_cvtpd2dq (memopv2f64 addr:$src)))],
2052                       IIC_SSE_CVT_PD_RM>, Sched<[WriteCvtF2ILd]>;
2053 def CVTPD2DQrr  : SDI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2054                       "cvtpd2dq\t{$src, $dst|$dst, $src}",
2055                       [(set VR128:$dst, (int_x86_sse2_cvtpd2dq VR128:$src))],
2056                       IIC_SSE_CVT_PD_RR>, Sched<[WriteCvtF2I]>;
2057
2058 // Convert with truncation packed single/double fp to doubleword
2059 // SSE2 packed instructions with XS prefix
2060 def VCVTTPS2DQrr : VS2SI<0x5B, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2061                          "cvttps2dq\t{$src, $dst|$dst, $src}",
2062                          [(set VR128:$dst,
2063                            (int_x86_sse2_cvttps2dq VR128:$src))],
2064                          IIC_SSE_CVT_PS_RR>, VEX, Sched<[WriteCvtF2I]>;
2065 def VCVTTPS2DQrm : VS2SI<0x5B, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
2066                          "cvttps2dq\t{$src, $dst|$dst, $src}",
2067                          [(set VR128:$dst, (int_x86_sse2_cvttps2dq
2068                                             (loadv4f32 addr:$src)))],
2069                          IIC_SSE_CVT_PS_RM>, VEX, Sched<[WriteCvtF2ILd]>;
2070 def VCVTTPS2DQYrr : VS2SI<0x5B, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
2071                           "cvttps2dq\t{$src, $dst|$dst, $src}",
2072                           [(set VR256:$dst,
2073                             (int_x86_avx_cvtt_ps2dq_256 VR256:$src))],
2074                           IIC_SSE_CVT_PS_RR>, VEX, VEX_L, Sched<[WriteCvtF2I]>;
2075 def VCVTTPS2DQYrm : VS2SI<0x5B, MRMSrcMem, (outs VR256:$dst), (ins f256mem:$src),
2076                           "cvttps2dq\t{$src, $dst|$dst, $src}",
2077                           [(set VR256:$dst, (int_x86_avx_cvtt_ps2dq_256
2078                                              (loadv8f32 addr:$src)))],
2079                           IIC_SSE_CVT_PS_RM>, VEX, VEX_L,
2080                           Sched<[WriteCvtF2ILd]>;
2081
2082 def CVTTPS2DQrr : S2SI<0x5B, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2083                        "cvttps2dq\t{$src, $dst|$dst, $src}",
2084                        [(set VR128:$dst, (int_x86_sse2_cvttps2dq VR128:$src))],
2085                        IIC_SSE_CVT_PS_RR>, Sched<[WriteCvtF2I]>;
2086 def CVTTPS2DQrm : S2SI<0x5B, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
2087                        "cvttps2dq\t{$src, $dst|$dst, $src}",
2088                        [(set VR128:$dst,
2089                          (int_x86_sse2_cvttps2dq (memopv4f32 addr:$src)))],
2090                        IIC_SSE_CVT_PS_RM>, Sched<[WriteCvtF2ILd]>;
2091
2092 let Predicates = [HasAVX] in {
2093   def : Pat<(v4f32 (sint_to_fp (v4i32 VR128:$src))),
2094             (VCVTDQ2PSrr VR128:$src)>;
2095   def : Pat<(v4f32 (sint_to_fp (bc_v4i32 (loadv2i64 addr:$src)))),
2096             (VCVTDQ2PSrm addr:$src)>;
2097
2098   def : Pat<(int_x86_sse2_cvtdq2ps VR128:$src),
2099             (VCVTDQ2PSrr VR128:$src)>;
2100   def : Pat<(int_x86_sse2_cvtdq2ps (bc_v4i32 (loadv2i64 addr:$src))),
2101             (VCVTDQ2PSrm addr:$src)>;
2102
2103   def : Pat<(v4i32 (fp_to_sint (v4f32 VR128:$src))),
2104             (VCVTTPS2DQrr VR128:$src)>;
2105   def : Pat<(v4i32 (fp_to_sint (loadv4f32 addr:$src))),
2106             (VCVTTPS2DQrm addr:$src)>;
2107
2108   def : Pat<(v8f32 (sint_to_fp (v8i32 VR256:$src))),
2109             (VCVTDQ2PSYrr VR256:$src)>;
2110   def : Pat<(v8f32 (sint_to_fp (bc_v8i32 (loadv4i64 addr:$src)))),
2111             (VCVTDQ2PSYrm addr:$src)>;
2112
2113   def : Pat<(v8i32 (fp_to_sint (v8f32 VR256:$src))),
2114             (VCVTTPS2DQYrr VR256:$src)>;
2115   def : Pat<(v8i32 (fp_to_sint (loadv8f32 addr:$src))),
2116             (VCVTTPS2DQYrm addr:$src)>;
2117 }
2118
2119 let Predicates = [UseSSE2] in {
2120   def : Pat<(v4f32 (sint_to_fp (v4i32 VR128:$src))),
2121             (CVTDQ2PSrr VR128:$src)>;
2122   def : Pat<(v4f32 (sint_to_fp (bc_v4i32 (memopv2i64 addr:$src)))),
2123             (CVTDQ2PSrm addr:$src)>;
2124
2125   def : Pat<(int_x86_sse2_cvtdq2ps VR128:$src),
2126             (CVTDQ2PSrr VR128:$src)>;
2127   def : Pat<(int_x86_sse2_cvtdq2ps (bc_v4i32 (memopv2i64 addr:$src))),
2128             (CVTDQ2PSrm addr:$src)>;
2129
2130   def : Pat<(v4i32 (fp_to_sint (v4f32 VR128:$src))),
2131             (CVTTPS2DQrr VR128:$src)>;
2132   def : Pat<(v4i32 (fp_to_sint (memopv4f32 addr:$src))),
2133             (CVTTPS2DQrm addr:$src)>;
2134 }
2135
2136 def VCVTTPD2DQrr : VPDI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2137                         "cvttpd2dq\t{$src, $dst|$dst, $src}",
2138                         [(set VR128:$dst,
2139                               (int_x86_sse2_cvttpd2dq VR128:$src))],
2140                               IIC_SSE_CVT_PD_RR>, VEX, Sched<[WriteCvtF2I]>;
2141
2142 // The assembler can recognize rr 256-bit instructions by seeing a ymm
2143 // register, but the same isn't true when using memory operands instead.
2144 // Provide other assembly rr and rm forms to address this explicitly.
2145
2146 // XMM only
2147 def : InstAlias<"vcvttpd2dqx\t{$src, $dst|$dst, $src}",
2148                 (VCVTTPD2DQrr VR128:$dst, VR128:$src), 0>;
2149 def VCVTTPD2DQXrm : VPDI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
2150                          "cvttpd2dqx\t{$src, $dst|$dst, $src}",
2151                          [(set VR128:$dst, (int_x86_sse2_cvttpd2dq
2152                                             (loadv2f64 addr:$src)))],
2153                          IIC_SSE_CVT_PD_RM>, VEX, Sched<[WriteCvtF2ILd]>;
2154
2155 // YMM only
2156 def VCVTTPD2DQYrr : VPDI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR256:$src),
2157                          "cvttpd2dq{y}\t{$src, $dst|$dst, $src}",
2158                          [(set VR128:$dst,
2159                            (int_x86_avx_cvtt_pd2dq_256 VR256:$src))],
2160                          IIC_SSE_CVT_PD_RR>, VEX, VEX_L, Sched<[WriteCvtF2I]>;
2161 def VCVTTPD2DQYrm : VPDI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f256mem:$src),
2162                          "cvttpd2dq{y}\t{$src, $dst|$dst, $src}",
2163                          [(set VR128:$dst,
2164                           (int_x86_avx_cvtt_pd2dq_256 (loadv4f64 addr:$src)))],
2165                          IIC_SSE_CVT_PD_RM>, VEX, VEX_L, Sched<[WriteCvtF2ILd]>;
2166 def : InstAlias<"vcvttpd2dq\t{$src, $dst|$dst, $src}",
2167                 (VCVTTPD2DQYrr VR128:$dst, VR256:$src), 0>;
2168
2169 let Predicates = [HasAVX] in {
2170   def : Pat<(v4i32 (fp_to_sint (v4f64 VR256:$src))),
2171             (VCVTTPD2DQYrr VR256:$src)>;
2172   def : Pat<(v4i32 (fp_to_sint (loadv4f64 addr:$src))),
2173             (VCVTTPD2DQYrm addr:$src)>;
2174 } // Predicates = [HasAVX]
2175
2176 def CVTTPD2DQrr : PDI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2177                       "cvttpd2dq\t{$src, $dst|$dst, $src}",
2178                       [(set VR128:$dst, (int_x86_sse2_cvttpd2dq VR128:$src))],
2179                       IIC_SSE_CVT_PD_RR>, Sched<[WriteCvtF2I]>;
2180 def CVTTPD2DQrm : PDI<0xE6, MRMSrcMem, (outs VR128:$dst),(ins f128mem:$src),
2181                       "cvttpd2dq\t{$src, $dst|$dst, $src}",
2182                       [(set VR128:$dst, (int_x86_sse2_cvttpd2dq
2183                                         (memopv2f64 addr:$src)))],
2184                                         IIC_SSE_CVT_PD_RM>,
2185                       Sched<[WriteCvtF2ILd]>;
2186
2187 // Convert packed single to packed double
2188 let Predicates = [HasAVX] in {
2189                   // SSE2 instructions without OpSize prefix
2190 def VCVTPS2PDrr : I<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2191                      "vcvtps2pd\t{$src, $dst|$dst, $src}",
2192                      [(set VR128:$dst, (int_x86_sse2_cvtps2pd VR128:$src))],
2193                      IIC_SSE_CVT_PD_RR>, PS, VEX, Sched<[WriteCvtF2F]>;
2194 def VCVTPS2PDrm : I<0x5A, MRMSrcMem, (outs VR128:$dst), (ins f64mem:$src),
2195                     "vcvtps2pd\t{$src, $dst|$dst, $src}",
2196                     [(set VR128:$dst, (v2f64 (extloadv2f32 addr:$src)))],
2197                     IIC_SSE_CVT_PD_RM>, PS, VEX, Sched<[WriteCvtF2FLd]>;
2198 def VCVTPS2PDYrr : I<0x5A, MRMSrcReg, (outs VR256:$dst), (ins VR128:$src),
2199                      "vcvtps2pd\t{$src, $dst|$dst, $src}",
2200                      [(set VR256:$dst,
2201                        (int_x86_avx_cvt_ps2_pd_256 VR128:$src))],
2202                      IIC_SSE_CVT_PD_RR>, PS, VEX, VEX_L, Sched<[WriteCvtF2F]>;
2203 def VCVTPS2PDYrm : I<0x5A, MRMSrcMem, (outs VR256:$dst), (ins f128mem:$src),
2204                      "vcvtps2pd\t{$src, $dst|$dst, $src}",
2205                      [(set VR256:$dst,
2206                        (int_x86_avx_cvt_ps2_pd_256 (loadv4f32 addr:$src)))],
2207                      IIC_SSE_CVT_PD_RM>, PS, VEX, VEX_L, Sched<[WriteCvtF2FLd]>;
2208 }
2209
2210 let Predicates = [UseSSE2] in {
2211 def CVTPS2PDrr : I<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2212                        "cvtps2pd\t{$src, $dst|$dst, $src}",
2213                        [(set VR128:$dst, (int_x86_sse2_cvtps2pd VR128:$src))],
2214                        IIC_SSE_CVT_PD_RR>, PS, Sched<[WriteCvtF2F]>;
2215 def CVTPS2PDrm : I<0x5A, MRMSrcMem, (outs VR128:$dst), (ins f64mem:$src),
2216                    "cvtps2pd\t{$src, $dst|$dst, $src}",
2217                    [(set VR128:$dst, (v2f64 (extloadv2f32 addr:$src)))],
2218                    IIC_SSE_CVT_PD_RM>, PS, Sched<[WriteCvtF2FLd]>;
2219 }
2220
2221 // Convert Packed DW Integers to Packed Double FP
2222 let Predicates = [HasAVX] in {
2223 let neverHasSideEffects = 1, mayLoad = 1 in
2224 def VCVTDQ2PDrm  : S2SI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
2225                      "vcvtdq2pd\t{$src, $dst|$dst, $src}",
2226                      []>, VEX, Sched<[WriteCvtI2FLd]>;
2227 def VCVTDQ2PDrr  : S2SI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2228                      "vcvtdq2pd\t{$src, $dst|$dst, $src}",
2229                      [(set VR128:$dst,
2230                        (int_x86_sse2_cvtdq2pd VR128:$src))]>, VEX,
2231                    Sched<[WriteCvtI2F]>;
2232 def VCVTDQ2PDYrm  : S2SI<0xE6, MRMSrcMem, (outs VR256:$dst), (ins i128mem:$src),
2233                      "vcvtdq2pd\t{$src, $dst|$dst, $src}",
2234                      [(set VR256:$dst,
2235                        (int_x86_avx_cvtdq2_pd_256
2236                         (bitconvert (loadv2i64 addr:$src))))]>, VEX, VEX_L,
2237                     Sched<[WriteCvtI2FLd]>;
2238 def VCVTDQ2PDYrr  : S2SI<0xE6, MRMSrcReg, (outs VR256:$dst), (ins VR128:$src),
2239                      "vcvtdq2pd\t{$src, $dst|$dst, $src}",
2240                      [(set VR256:$dst,
2241                        (int_x86_avx_cvtdq2_pd_256 VR128:$src))]>, VEX, VEX_L,
2242                     Sched<[WriteCvtI2F]>;
2243 }
2244
2245 let neverHasSideEffects = 1, mayLoad = 1 in
2246 def CVTDQ2PDrm  : S2SI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
2247                        "cvtdq2pd\t{$src, $dst|$dst, $src}", [],
2248                        IIC_SSE_CVT_PD_RR>, Sched<[WriteCvtI2FLd]>;
2249 def CVTDQ2PDrr  : S2SI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2250                        "cvtdq2pd\t{$src, $dst|$dst, $src}",
2251                        [(set VR128:$dst, (int_x86_sse2_cvtdq2pd VR128:$src))],
2252                        IIC_SSE_CVT_PD_RM>, Sched<[WriteCvtI2F]>;
2253
2254 // AVX 256-bit register conversion intrinsics
2255 let Predicates = [HasAVX] in {
2256   def : Pat<(v4f64 (sint_to_fp (v4i32 VR128:$src))),
2257             (VCVTDQ2PDYrr VR128:$src)>;
2258   def : Pat<(v4f64 (sint_to_fp (bc_v4i32 (loadv2i64 addr:$src)))),
2259             (VCVTDQ2PDYrm addr:$src)>;
2260 } // Predicates = [HasAVX]
2261
2262 // Convert packed double to packed single
2263 // The assembler can recognize rr 256-bit instructions by seeing a ymm
2264 // register, but the same isn't true when using memory operands instead.
2265 // Provide other assembly rr and rm forms to address this explicitly.
2266 def VCVTPD2PSrr : VPDI<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2267                        "cvtpd2ps\t{$src, $dst|$dst, $src}",
2268                        [(set VR128:$dst, (int_x86_sse2_cvtpd2ps VR128:$src))],
2269                        IIC_SSE_CVT_PD_RR>, VEX, Sched<[WriteCvtF2F]>;
2270
2271 // XMM only
2272 def : InstAlias<"vcvtpd2psx\t{$src, $dst|$dst, $src}",
2273                 (VCVTPD2PSrr VR128:$dst, VR128:$src), 0>;
2274 def VCVTPD2PSXrm : VPDI<0x5A, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
2275                         "cvtpd2psx\t{$src, $dst|$dst, $src}",
2276                         [(set VR128:$dst,
2277                           (int_x86_sse2_cvtpd2ps (loadv2f64 addr:$src)))],
2278                         IIC_SSE_CVT_PD_RM>, VEX, Sched<[WriteCvtF2FLd]>;
2279
2280 // YMM only
2281 def VCVTPD2PSYrr : VPDI<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR256:$src),
2282                         "cvtpd2ps{y}\t{$src, $dst|$dst, $src}",
2283                         [(set VR128:$dst,
2284                           (int_x86_avx_cvt_pd2_ps_256 VR256:$src))],
2285                         IIC_SSE_CVT_PD_RR>, VEX, VEX_L, Sched<[WriteCvtF2F]>;
2286 def VCVTPD2PSYrm : VPDI<0x5A, MRMSrcMem, (outs VR128:$dst), (ins f256mem:$src),
2287                         "cvtpd2ps{y}\t{$src, $dst|$dst, $src}",
2288                         [(set VR128:$dst,
2289                           (int_x86_avx_cvt_pd2_ps_256 (loadv4f64 addr:$src)))],
2290                         IIC_SSE_CVT_PD_RM>, VEX, VEX_L, Sched<[WriteCvtF2FLd]>;
2291 def : InstAlias<"vcvtpd2ps\t{$src, $dst|$dst, $src}",
2292                 (VCVTPD2PSYrr VR128:$dst, VR256:$src), 0>;
2293
2294 def CVTPD2PSrr : PDI<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2295                      "cvtpd2ps\t{$src, $dst|$dst, $src}",
2296                      [(set VR128:$dst, (int_x86_sse2_cvtpd2ps VR128:$src))],
2297                      IIC_SSE_CVT_PD_RR>, Sched<[WriteCvtF2F]>;
2298 def CVTPD2PSrm : PDI<0x5A, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
2299                      "cvtpd2ps\t{$src, $dst|$dst, $src}",
2300                      [(set VR128:$dst,
2301                        (int_x86_sse2_cvtpd2ps (memopv2f64 addr:$src)))],
2302                      IIC_SSE_CVT_PD_RM>, Sched<[WriteCvtF2FLd]>;
2303
2304
2305 // AVX 256-bit register conversion intrinsics
2306 // FIXME: Migrate SSE conversion intrinsics matching to use patterns as below
2307 // whenever possible to avoid declaring two versions of each one.
2308 let Predicates = [HasAVX] in {
2309   def : Pat<(int_x86_avx_cvtdq2_ps_256 VR256:$src),
2310             (VCVTDQ2PSYrr VR256:$src)>;
2311   def : Pat<(int_x86_avx_cvtdq2_ps_256 (bitconvert (loadv4i64 addr:$src))),
2312             (VCVTDQ2PSYrm addr:$src)>;
2313
2314   // Match fround and fextend for 128/256-bit conversions
2315   def : Pat<(v4f32 (X86vfpround (v2f64 VR128:$src))),
2316             (VCVTPD2PSrr VR128:$src)>;
2317   def : Pat<(v4f32 (X86vfpround (loadv2f64 addr:$src))),
2318             (VCVTPD2PSXrm addr:$src)>;
2319   def : Pat<(v4f32 (fround (v4f64 VR256:$src))),
2320             (VCVTPD2PSYrr VR256:$src)>;
2321   def : Pat<(v4f32 (fround (loadv4f64 addr:$src))),
2322             (VCVTPD2PSYrm addr:$src)>;
2323
2324   def : Pat<(v2f64 (X86vfpext (v4f32 VR128:$src))),
2325             (VCVTPS2PDrr VR128:$src)>;
2326   def : Pat<(v4f64 (fextend (v4f32 VR128:$src))),
2327             (VCVTPS2PDYrr VR128:$src)>;
2328   def : Pat<(v4f64 (extloadv4f32 addr:$src)),
2329             (VCVTPS2PDYrm addr:$src)>;
2330 }
2331
2332 let Predicates = [UseSSE2] in {
2333   // Match fround and fextend for 128 conversions
2334   def : Pat<(v4f32 (X86vfpround (v2f64 VR128:$src))),
2335             (CVTPD2PSrr VR128:$src)>;
2336   def : Pat<(v4f32 (X86vfpround (memopv2f64 addr:$src))),
2337             (CVTPD2PSrm addr:$src)>;
2338
2339   def : Pat<(v2f64 (X86vfpext (v4f32 VR128:$src))),
2340             (CVTPS2PDrr VR128:$src)>;
2341 }
2342
2343 //===----------------------------------------------------------------------===//
2344 // SSE 1 & 2 - Compare Instructions
2345 //===----------------------------------------------------------------------===//
2346
2347 // sse12_cmp_scalar - sse 1 & 2 compare scalar instructions
2348 multiclass sse12_cmp_scalar<RegisterClass RC, X86MemOperand x86memop,
2349                             Operand CC, SDNode OpNode, ValueType VT,
2350                             PatFrag ld_frag, string asm, string asm_alt,
2351                             OpndItins itins> {
2352   def rr : SIi8<0xC2, MRMSrcReg,
2353                 (outs RC:$dst), (ins RC:$src1, RC:$src2, CC:$cc), asm,
2354                 [(set RC:$dst, (OpNode (VT RC:$src1), RC:$src2, imm:$cc))],
2355                 itins.rr>, Sched<[itins.Sched]>;
2356   def rm : SIi8<0xC2, MRMSrcMem,
2357                 (outs RC:$dst), (ins RC:$src1, x86memop:$src2, CC:$cc), asm,
2358                 [(set RC:$dst, (OpNode (VT RC:$src1),
2359                                          (ld_frag addr:$src2), imm:$cc))],
2360                                          itins.rm>,
2361            Sched<[itins.Sched.Folded, ReadAfterLd]>;
2362
2363   // Accept explicit immediate argument form instead of comparison code.
2364   let isAsmParserOnly = 1, hasSideEffects = 0 in {
2365     def rr_alt : SIi8<0xC2, MRMSrcReg, (outs RC:$dst),
2366                       (ins RC:$src1, RC:$src2, i8imm:$cc), asm_alt, [],
2367                       IIC_SSE_ALU_F32S_RR>, Sched<[itins.Sched]>;
2368     let mayLoad = 1 in
2369     def rm_alt : SIi8<0xC2, MRMSrcMem, (outs RC:$dst),
2370                       (ins RC:$src1, x86memop:$src2, i8imm:$cc), asm_alt, [],
2371                       IIC_SSE_ALU_F32S_RM>,
2372                       Sched<[itins.Sched.Folded, ReadAfterLd]>;
2373   }
2374 }
2375
2376 defm VCMPSS : sse12_cmp_scalar<FR32, f32mem, AVXCC, X86cmps, f32, loadf32,
2377                  "cmp${cc}ss\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2378                  "cmpss\t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}",
2379                  SSE_ALU_F32S>,
2380                  XS, VEX_4V, VEX_LIG;
2381 defm VCMPSD : sse12_cmp_scalar<FR64, f64mem, AVXCC, X86cmps, f64, loadf64,
2382                  "cmp${cc}sd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2383                  "cmpsd\t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}",
2384                  SSE_ALU_F32S>, // same latency as 32 bit compare
2385                  XD, VEX_4V, VEX_LIG;
2386
2387 let Constraints = "$src1 = $dst" in {
2388   defm CMPSS : sse12_cmp_scalar<FR32, f32mem, SSECC, X86cmps, f32, loadf32,
2389                   "cmp${cc}ss\t{$src2, $dst|$dst, $src2}",
2390                   "cmpss\t{$cc, $src2, $dst|$dst, $src2, $cc}", SSE_ALU_F32S>,
2391                   XS;
2392   defm CMPSD : sse12_cmp_scalar<FR64, f64mem, SSECC, X86cmps, f64, loadf64,
2393                   "cmp${cc}sd\t{$src2, $dst|$dst, $src2}",
2394                   "cmpsd\t{$cc, $src2, $dst|$dst, $src2, $cc}",
2395                   SSE_ALU_F64S>,
2396                   XD;
2397 }
2398
2399 multiclass sse12_cmp_scalar_int<X86MemOperand x86memop, Operand CC,
2400                          Intrinsic Int, string asm, OpndItins itins> {
2401   def rr : SIi8<0xC2, MRMSrcReg, (outs VR128:$dst),
2402                       (ins VR128:$src1, VR128:$src, CC:$cc), asm,
2403                         [(set VR128:$dst, (Int VR128:$src1,
2404                                                VR128:$src, imm:$cc))],
2405                                                itins.rr>,
2406            Sched<[itins.Sched]>;
2407   def rm : SIi8<0xC2, MRMSrcMem, (outs VR128:$dst),
2408                       (ins VR128:$src1, x86memop:$src, CC:$cc), asm,
2409                         [(set VR128:$dst, (Int VR128:$src1,
2410                                                (load addr:$src), imm:$cc))],
2411                                                itins.rm>,
2412            Sched<[itins.Sched.Folded, ReadAfterLd]>;
2413 }
2414
2415 let isCodeGenOnly = 1 in {
2416   // Aliases to match intrinsics which expect XMM operand(s).
2417   defm Int_VCMPSS  : sse12_cmp_scalar_int<f32mem, AVXCC, int_x86_sse_cmp_ss,
2418                        "cmp${cc}ss\t{$src, $src1, $dst|$dst, $src1, $src}",
2419                        SSE_ALU_F32S>,
2420                        XS, VEX_4V;
2421   defm Int_VCMPSD  : sse12_cmp_scalar_int<f64mem, AVXCC, int_x86_sse2_cmp_sd,
2422                        "cmp${cc}sd\t{$src, $src1, $dst|$dst, $src1, $src}",
2423                        SSE_ALU_F32S>, // same latency as f32
2424                        XD, VEX_4V;
2425   let Constraints = "$src1 = $dst" in {
2426     defm Int_CMPSS  : sse12_cmp_scalar_int<f32mem, SSECC, int_x86_sse_cmp_ss,
2427                          "cmp${cc}ss\t{$src, $dst|$dst, $src}",
2428                          SSE_ALU_F32S>, XS;
2429     defm Int_CMPSD  : sse12_cmp_scalar_int<f64mem, SSECC, int_x86_sse2_cmp_sd,
2430                          "cmp${cc}sd\t{$src, $dst|$dst, $src}",
2431                          SSE_ALU_F64S>,
2432                          XD;
2433 }
2434 }
2435
2436
2437 // sse12_ord_cmp - Unordered/Ordered scalar fp compare and set EFLAGS
2438 multiclass sse12_ord_cmp<bits<8> opc, RegisterClass RC, SDNode OpNode,
2439                             ValueType vt, X86MemOperand x86memop,
2440                             PatFrag ld_frag, string OpcodeStr> {
2441   def rr: SI<opc, MRMSrcReg, (outs), (ins RC:$src1, RC:$src2),
2442                      !strconcat(OpcodeStr, "\t{$src2, $src1|$src1, $src2}"),
2443                      [(set EFLAGS, (OpNode (vt RC:$src1), RC:$src2))],
2444                      IIC_SSE_COMIS_RR>,
2445           Sched<[WriteFAdd]>;
2446   def rm: SI<opc, MRMSrcMem, (outs), (ins RC:$src1, x86memop:$src2),
2447                      !strconcat(OpcodeStr, "\t{$src2, $src1|$src1, $src2}"),
2448                      [(set EFLAGS, (OpNode (vt RC:$src1),
2449                                            (ld_frag addr:$src2)))],
2450                                            IIC_SSE_COMIS_RM>,
2451           Sched<[WriteFAddLd, ReadAfterLd]>;
2452 }
2453
2454 let Defs = [EFLAGS] in {
2455   defm VUCOMISS : sse12_ord_cmp<0x2E, FR32, X86cmp, f32, f32mem, loadf32,
2456                                   "ucomiss">, PS, VEX, VEX_LIG;
2457   defm VUCOMISD : sse12_ord_cmp<0x2E, FR64, X86cmp, f64, f64mem, loadf64,
2458                                   "ucomisd">, PD, VEX, VEX_LIG;
2459   let Pattern = []<dag> in {
2460     defm VCOMISS  : sse12_ord_cmp<0x2F, VR128, undef, v4f32, f128mem, load,
2461                                     "comiss">, PS, VEX, VEX_LIG;
2462     defm VCOMISD  : sse12_ord_cmp<0x2F, VR128, undef, v2f64, f128mem, load,
2463                                     "comisd">, PD, VEX, VEX_LIG;
2464   }
2465
2466   let isCodeGenOnly = 1 in {
2467     defm Int_VUCOMISS  : sse12_ord_cmp<0x2E, VR128, X86ucomi, v4f32, f128mem,
2468                               load, "ucomiss">, PS, VEX;
2469     defm Int_VUCOMISD  : sse12_ord_cmp<0x2E, VR128, X86ucomi, v2f64, f128mem,
2470                               load, "ucomisd">, PD, VEX;
2471
2472     defm Int_VCOMISS  : sse12_ord_cmp<0x2F, VR128, X86comi, v4f32, f128mem,
2473                               load, "comiss">, PS, VEX;
2474     defm Int_VCOMISD  : sse12_ord_cmp<0x2F, VR128, X86comi, v2f64, f128mem,
2475                               load, "comisd">, PD, VEX;
2476   }
2477   defm UCOMISS  : sse12_ord_cmp<0x2E, FR32, X86cmp, f32, f32mem, loadf32,
2478                                   "ucomiss">, PS;
2479   defm UCOMISD  : sse12_ord_cmp<0x2E, FR64, X86cmp, f64, f64mem, loadf64,
2480                                   "ucomisd">, PD;
2481
2482   let Pattern = []<dag> in {
2483     defm COMISS  : sse12_ord_cmp<0x2F, VR128, undef, v4f32, f128mem, load,
2484                                     "comiss">, PS;
2485     defm COMISD  : sse12_ord_cmp<0x2F, VR128, undef, v2f64, f128mem, load,
2486                                     "comisd">, PD;
2487   }
2488
2489   let isCodeGenOnly = 1 in {
2490     defm Int_UCOMISS  : sse12_ord_cmp<0x2E, VR128, X86ucomi, v4f32, f128mem,
2491                                 load, "ucomiss">, PS;
2492     defm Int_UCOMISD  : sse12_ord_cmp<0x2E, VR128, X86ucomi, v2f64, f128mem,
2493                                 load, "ucomisd">, PD;
2494
2495     defm Int_COMISS  : sse12_ord_cmp<0x2F, VR128, X86comi, v4f32, f128mem, load,
2496                                     "comiss">, PS;
2497     defm Int_COMISD  : sse12_ord_cmp<0x2F, VR128, X86comi, v2f64, f128mem, load,
2498                                     "comisd">, PD;
2499   }
2500 } // Defs = [EFLAGS]
2501
2502 // sse12_cmp_packed - sse 1 & 2 compare packed instructions
2503 multiclass sse12_cmp_packed<RegisterClass RC, X86MemOperand x86memop,
2504                             Operand CC, Intrinsic Int, string asm,
2505                             string asm_alt, Domain d,
2506                             OpndItins itins = SSE_ALU_F32P> {
2507   def rri : PIi8<0xC2, MRMSrcReg,
2508              (outs RC:$dst), (ins RC:$src1, RC:$src2, CC:$cc), asm,
2509              [(set RC:$dst, (Int RC:$src1, RC:$src2, imm:$cc))],
2510              itins.rr, d>,
2511             Sched<[WriteFAdd]>;
2512   def rmi : PIi8<0xC2, MRMSrcMem,
2513              (outs RC:$dst), (ins RC:$src1, x86memop:$src2, CC:$cc), asm,
2514              [(set RC:$dst, (Int RC:$src1, (memop addr:$src2), imm:$cc))],
2515              itins.rm, d>,
2516             Sched<[WriteFAddLd, ReadAfterLd]>;
2517
2518   // Accept explicit immediate argument form instead of comparison code.
2519   let isAsmParserOnly = 1, hasSideEffects = 0 in {
2520     def rri_alt : PIi8<0xC2, MRMSrcReg,
2521                (outs RC:$dst), (ins RC:$src1, RC:$src2, i8imm:$cc),
2522                asm_alt, [], itins.rr, d>, Sched<[WriteFAdd]>;
2523     def rmi_alt : PIi8<0xC2, MRMSrcMem,
2524                (outs RC:$dst), (ins RC:$src1, x86memop:$src2, i8imm:$cc),
2525                asm_alt, [], itins.rm, d>,
2526                Sched<[WriteFAddLd, ReadAfterLd]>;
2527   }
2528 }
2529
2530 defm VCMPPS : sse12_cmp_packed<VR128, f128mem, AVXCC, int_x86_sse_cmp_ps,
2531                "cmp${cc}ps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2532                "cmpps\t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}",
2533                SSEPackedSingle>, PS, VEX_4V;
2534 defm VCMPPD : sse12_cmp_packed<VR128, f128mem, AVXCC, int_x86_sse2_cmp_pd,
2535                "cmp${cc}pd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2536                "cmppd\t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}",
2537                SSEPackedDouble>, PD, VEX_4V;
2538 defm VCMPPSY : sse12_cmp_packed<VR256, f256mem, AVXCC, int_x86_avx_cmp_ps_256,
2539                "cmp${cc}ps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2540                "cmpps\t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}",
2541                SSEPackedSingle>, PS, VEX_4V, VEX_L;
2542 defm VCMPPDY : sse12_cmp_packed<VR256, f256mem, AVXCC, int_x86_avx_cmp_pd_256,
2543                "cmp${cc}pd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2544                "cmppd\t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}",
2545                SSEPackedDouble>, PD, VEX_4V, VEX_L;
2546 let Constraints = "$src1 = $dst" in {
2547   defm CMPPS : sse12_cmp_packed<VR128, f128mem, SSECC, int_x86_sse_cmp_ps,
2548                  "cmp${cc}ps\t{$src2, $dst|$dst, $src2}",
2549                  "cmpps\t{$cc, $src2, $dst|$dst, $src2, $cc}",
2550                  SSEPackedSingle, SSE_ALU_F32P>, PS;
2551   defm CMPPD : sse12_cmp_packed<VR128, f128mem, SSECC, int_x86_sse2_cmp_pd,
2552                  "cmp${cc}pd\t{$src2, $dst|$dst, $src2}",
2553                  "cmppd\t{$cc, $src2, $dst|$dst, $src2, $cc}",
2554                  SSEPackedDouble, SSE_ALU_F64P>, PD;
2555 }
2556
2557 let Predicates = [HasAVX] in {
2558 def : Pat<(v4i32 (X86cmpp (v4f32 VR128:$src1), VR128:$src2, imm:$cc)),
2559           (VCMPPSrri (v4f32 VR128:$src1), (v4f32 VR128:$src2), imm:$cc)>;
2560 def : Pat<(v4i32 (X86cmpp (v4f32 VR128:$src1), (memop addr:$src2), imm:$cc)),
2561           (VCMPPSrmi (v4f32 VR128:$src1), addr:$src2, imm:$cc)>;
2562 def : Pat<(v2i64 (X86cmpp (v2f64 VR128:$src1), VR128:$src2, imm:$cc)),
2563           (VCMPPDrri VR128:$src1, VR128:$src2, imm:$cc)>;
2564 def : Pat<(v2i64 (X86cmpp (v2f64 VR128:$src1), (memop addr:$src2), imm:$cc)),
2565           (VCMPPDrmi VR128:$src1, addr:$src2, imm:$cc)>;
2566
2567 def : Pat<(v8i32 (X86cmpp (v8f32 VR256:$src1), VR256:$src2, imm:$cc)),
2568           (VCMPPSYrri (v8f32 VR256:$src1), (v8f32 VR256:$src2), imm:$cc)>;
2569 def : Pat<(v8i32 (X86cmpp (v8f32 VR256:$src1), (memop addr:$src2), imm:$cc)),
2570           (VCMPPSYrmi (v8f32 VR256:$src1), addr:$src2, imm:$cc)>;
2571 def : Pat<(v4i64 (X86cmpp (v4f64 VR256:$src1), VR256:$src2, imm:$cc)),
2572           (VCMPPDYrri VR256:$src1, VR256:$src2, imm:$cc)>;
2573 def : Pat<(v4i64 (X86cmpp (v4f64 VR256:$src1), (memop addr:$src2), imm:$cc)),
2574           (VCMPPDYrmi VR256:$src1, addr:$src2, imm:$cc)>;
2575 }
2576
2577 let Predicates = [UseSSE1] in {
2578 def : Pat<(v4i32 (X86cmpp (v4f32 VR128:$src1), VR128:$src2, imm:$cc)),
2579           (CMPPSrri (v4f32 VR128:$src1), (v4f32 VR128:$src2), imm:$cc)>;
2580 def : Pat<(v4i32 (X86cmpp (v4f32 VR128:$src1), (memop addr:$src2), imm:$cc)),
2581           (CMPPSrmi (v4f32 VR128:$src1), addr:$src2, imm:$cc)>;
2582 }
2583
2584 let Predicates = [UseSSE2] in {
2585 def : Pat<(v2i64 (X86cmpp (v2f64 VR128:$src1), VR128:$src2, imm:$cc)),
2586           (CMPPDrri VR128:$src1, VR128:$src2, imm:$cc)>;
2587 def : Pat<(v2i64 (X86cmpp (v2f64 VR128:$src1), (memop addr:$src2), imm:$cc)),
2588           (CMPPDrmi VR128:$src1, addr:$src2, imm:$cc)>;
2589 }
2590
2591 //===----------------------------------------------------------------------===//
2592 // SSE 1 & 2 - Shuffle Instructions
2593 //===----------------------------------------------------------------------===//
2594
2595 /// sse12_shuffle - sse 1 & 2 fp shuffle instructions
2596 multiclass sse12_shuffle<RegisterClass RC, X86MemOperand x86memop,
2597                          ValueType vt, string asm, PatFrag mem_frag,
2598                          Domain d, bit IsConvertibleToThreeAddress = 0> {
2599   def rmi : PIi8<0xC6, MRMSrcMem, (outs RC:$dst),
2600                    (ins RC:$src1, x86memop:$src2, i8imm:$src3), asm,
2601                    [(set RC:$dst, (vt (X86Shufp RC:$src1, (mem_frag addr:$src2),
2602                                        (i8 imm:$src3))))], IIC_SSE_SHUFP, d>,
2603             Sched<[WriteFShuffleLd, ReadAfterLd]>;
2604   let isConvertibleToThreeAddress = IsConvertibleToThreeAddress in
2605     def rri : PIi8<0xC6, MRMSrcReg, (outs RC:$dst),
2606                    (ins RC:$src1, RC:$src2, i8imm:$src3), asm,
2607                    [(set RC:$dst, (vt (X86Shufp RC:$src1, RC:$src2,
2608                                        (i8 imm:$src3))))], IIC_SSE_SHUFP, d>,
2609               Sched<[WriteFShuffle]>;
2610 }
2611
2612 defm VSHUFPS  : sse12_shuffle<VR128, f128mem, v4f32,
2613            "shufps\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
2614            loadv4f32, SSEPackedSingle>, PS, VEX_4V;
2615 defm VSHUFPSY : sse12_shuffle<VR256, f256mem, v8f32,
2616            "shufps\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
2617            loadv8f32, SSEPackedSingle>, PS, VEX_4V, VEX_L;
2618 defm VSHUFPD  : sse12_shuffle<VR128, f128mem, v2f64,
2619            "shufpd\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
2620            loadv2f64, SSEPackedDouble>, PD, VEX_4V;
2621 defm VSHUFPDY : sse12_shuffle<VR256, f256mem, v4f64,
2622            "shufpd\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
2623            loadv4f64, SSEPackedDouble>, PD, VEX_4V, VEX_L;
2624
2625 let Constraints = "$src1 = $dst" in {
2626   defm SHUFPS : sse12_shuffle<VR128, f128mem, v4f32,
2627                     "shufps\t{$src3, $src2, $dst|$dst, $src2, $src3}",
2628                     memopv4f32, SSEPackedSingle, 1 /* cvt to pshufd */>, PS;
2629   defm SHUFPD : sse12_shuffle<VR128, f128mem, v2f64,
2630                     "shufpd\t{$src3, $src2, $dst|$dst, $src2, $src3}",
2631                     memopv2f64, SSEPackedDouble, 1 /* cvt to pshufd */>, PD;
2632 }
2633
2634 let Predicates = [HasAVX] in {
2635   def : Pat<(v4i32 (X86Shufp VR128:$src1,
2636                        (bc_v4i32 (loadv2i64 addr:$src2)), (i8 imm:$imm))),
2637             (VSHUFPSrmi VR128:$src1, addr:$src2, imm:$imm)>;
2638   def : Pat<(v4i32 (X86Shufp VR128:$src1, VR128:$src2, (i8 imm:$imm))),
2639             (VSHUFPSrri VR128:$src1, VR128:$src2, imm:$imm)>;
2640
2641   def : Pat<(v2i64 (X86Shufp VR128:$src1,
2642                        (loadv2i64 addr:$src2), (i8 imm:$imm))),
2643             (VSHUFPDrmi VR128:$src1, addr:$src2, imm:$imm)>;
2644   def : Pat<(v2i64 (X86Shufp VR128:$src1, VR128:$src2, (i8 imm:$imm))),
2645             (VSHUFPDrri VR128:$src1, VR128:$src2, imm:$imm)>;
2646
2647   // 256-bit patterns
2648   def : Pat<(v8i32 (X86Shufp VR256:$src1, VR256:$src2, (i8 imm:$imm))),
2649             (VSHUFPSYrri VR256:$src1, VR256:$src2, imm:$imm)>;
2650   def : Pat<(v8i32 (X86Shufp VR256:$src1,
2651                       (bc_v8i32 (loadv4i64 addr:$src2)), (i8 imm:$imm))),
2652             (VSHUFPSYrmi VR256:$src1, addr:$src2, imm:$imm)>;
2653
2654   def : Pat<(v4i64 (X86Shufp VR256:$src1, VR256:$src2, (i8 imm:$imm))),
2655             (VSHUFPDYrri VR256:$src1, VR256:$src2, imm:$imm)>;
2656   def : Pat<(v4i64 (X86Shufp VR256:$src1,
2657                               (loadv4i64 addr:$src2), (i8 imm:$imm))),
2658             (VSHUFPDYrmi VR256:$src1, addr:$src2, imm:$imm)>;
2659 }
2660
2661 let Predicates = [UseSSE1] in {
2662   def : Pat<(v4i32 (X86Shufp VR128:$src1,
2663                        (bc_v4i32 (memopv2i64 addr:$src2)), (i8 imm:$imm))),
2664             (SHUFPSrmi VR128:$src1, addr:$src2, imm:$imm)>;
2665   def : Pat<(v4i32 (X86Shufp VR128:$src1, VR128:$src2, (i8 imm:$imm))),
2666             (SHUFPSrri VR128:$src1, VR128:$src2, imm:$imm)>;
2667 }
2668
2669 let Predicates = [UseSSE2] in {
2670   // Generic SHUFPD patterns
2671   def : Pat<(v2i64 (X86Shufp VR128:$src1,
2672                        (memopv2i64 addr:$src2), (i8 imm:$imm))),
2673             (SHUFPDrmi VR128:$src1, addr:$src2, imm:$imm)>;
2674   def : Pat<(v2i64 (X86Shufp VR128:$src1, VR128:$src2, (i8 imm:$imm))),
2675             (SHUFPDrri VR128:$src1, VR128:$src2, imm:$imm)>;
2676 }
2677
2678 //===----------------------------------------------------------------------===//
2679 // SSE 1 & 2 - Unpack FP Instructions
2680 //===----------------------------------------------------------------------===//
2681
2682 /// sse12_unpack_interleave - sse 1 & 2 fp unpack and interleave
2683 multiclass sse12_unpack_interleave<bits<8> opc, SDNode OpNode, ValueType vt,
2684                                    PatFrag mem_frag, RegisterClass RC,
2685                                    X86MemOperand x86memop, string asm,
2686                                    Domain d> {
2687     def rr : PI<opc, MRMSrcReg,
2688                 (outs RC:$dst), (ins RC:$src1, RC:$src2),
2689                 asm, [(set RC:$dst,
2690                            (vt (OpNode RC:$src1, RC:$src2)))],
2691                            IIC_SSE_UNPCK, d>, Sched<[WriteFShuffle]>;
2692     def rm : PI<opc, MRMSrcMem,
2693                 (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
2694                 asm, [(set RC:$dst,
2695                            (vt (OpNode RC:$src1,
2696                                        (mem_frag addr:$src2))))],
2697                                        IIC_SSE_UNPCK, d>,
2698              Sched<[WriteFShuffleLd, ReadAfterLd]>;
2699 }
2700
2701 defm VUNPCKHPS: sse12_unpack_interleave<0x15, X86Unpckh, v4f32, loadv4f32,
2702       VR128, f128mem, "unpckhps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2703                      SSEPackedSingle>, PS, VEX_4V;
2704 defm VUNPCKHPD: sse12_unpack_interleave<0x15, X86Unpckh, v2f64, loadv2f64,
2705       VR128, f128mem, "unpckhpd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2706                      SSEPackedDouble>, PD, VEX_4V;
2707 defm VUNPCKLPS: sse12_unpack_interleave<0x14, X86Unpckl, v4f32, loadv4f32,
2708       VR128, f128mem, "unpcklps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2709                      SSEPackedSingle>, PS, VEX_4V;
2710 defm VUNPCKLPD: sse12_unpack_interleave<0x14, X86Unpckl, v2f64, loadv2f64,
2711       VR128, f128mem, "unpcklpd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2712                      SSEPackedDouble>, PD, VEX_4V;
2713
2714 defm VUNPCKHPSY: sse12_unpack_interleave<0x15, X86Unpckh, v8f32, loadv8f32,
2715       VR256, f256mem, "unpckhps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2716                      SSEPackedSingle>, PS, VEX_4V, VEX_L;
2717 defm VUNPCKHPDY: sse12_unpack_interleave<0x15, X86Unpckh, v4f64, loadv4f64,
2718       VR256, f256mem, "unpckhpd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2719                      SSEPackedDouble>, PD, VEX_4V, VEX_L;
2720 defm VUNPCKLPSY: sse12_unpack_interleave<0x14, X86Unpckl, v8f32, loadv8f32,
2721       VR256, f256mem, "unpcklps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2722                      SSEPackedSingle>, PS, VEX_4V, VEX_L;
2723 defm VUNPCKLPDY: sse12_unpack_interleave<0x14, X86Unpckl, v4f64, loadv4f64,
2724       VR256, f256mem, "unpcklpd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2725                      SSEPackedDouble>, PD, VEX_4V, VEX_L;
2726
2727 let Constraints = "$src1 = $dst" in {
2728   defm UNPCKHPS: sse12_unpack_interleave<0x15, X86Unpckh, v4f32, memopv4f32,
2729         VR128, f128mem, "unpckhps\t{$src2, $dst|$dst, $src2}",
2730                        SSEPackedSingle>, PS;
2731   defm UNPCKHPD: sse12_unpack_interleave<0x15, X86Unpckh, v2f64, memopv2f64,
2732         VR128, f128mem, "unpckhpd\t{$src2, $dst|$dst, $src2}",
2733                        SSEPackedDouble>, PD;
2734   defm UNPCKLPS: sse12_unpack_interleave<0x14, X86Unpckl, v4f32, memopv4f32,
2735         VR128, f128mem, "unpcklps\t{$src2, $dst|$dst, $src2}",
2736                        SSEPackedSingle>, PS;
2737   defm UNPCKLPD: sse12_unpack_interleave<0x14, X86Unpckl, v2f64, memopv2f64,
2738         VR128, f128mem, "unpcklpd\t{$src2, $dst|$dst, $src2}",
2739                        SSEPackedDouble>, PD;
2740 } // Constraints = "$src1 = $dst"
2741
2742 let Predicates = [HasAVX1Only] in {
2743   def : Pat<(v8i32 (X86Unpckl VR256:$src1, (bc_v8i32 (loadv4i64 addr:$src2)))),
2744             (VUNPCKLPSYrm VR256:$src1, addr:$src2)>;
2745   def : Pat<(v8i32 (X86Unpckl VR256:$src1, VR256:$src2)),
2746             (VUNPCKLPSYrr VR256:$src1, VR256:$src2)>;
2747   def : Pat<(v8i32 (X86Unpckh VR256:$src1, (bc_v8i32 (loadv4i64 addr:$src2)))),
2748             (VUNPCKHPSYrm VR256:$src1, addr:$src2)>;
2749   def : Pat<(v8i32 (X86Unpckh VR256:$src1, VR256:$src2)),
2750             (VUNPCKHPSYrr VR256:$src1, VR256:$src2)>;
2751
2752   def : Pat<(v4i64 (X86Unpckl VR256:$src1, (loadv4i64 addr:$src2))),
2753             (VUNPCKLPDYrm VR256:$src1, addr:$src2)>;
2754   def : Pat<(v4i64 (X86Unpckl VR256:$src1, VR256:$src2)),
2755             (VUNPCKLPDYrr VR256:$src1, VR256:$src2)>;
2756   def : Pat<(v4i64 (X86Unpckh VR256:$src1, (loadv4i64 addr:$src2))),
2757             (VUNPCKHPDYrm VR256:$src1, addr:$src2)>;
2758   def : Pat<(v4i64 (X86Unpckh VR256:$src1, VR256:$src2)),
2759             (VUNPCKHPDYrr VR256:$src1, VR256:$src2)>;
2760 }
2761
2762 let Predicates = [HasAVX] in {
2763   // FIXME: Instead of X86Movddup, there should be a X86Unpckl here, the
2764   // problem is during lowering, where it's not possible to recognize the load
2765   // fold cause it has two uses through a bitcast. One use disappears at isel
2766   // time and the fold opportunity reappears.
2767   def : Pat<(v2f64 (X86Movddup VR128:$src)),
2768             (VUNPCKLPDrr VR128:$src, VR128:$src)>;
2769 }
2770
2771 let Predicates = [UseSSE2] in {
2772   // FIXME: Instead of X86Movddup, there should be a X86Unpckl here, the
2773   // problem is during lowering, where it's not possible to recognize the load
2774   // fold cause it has two uses through a bitcast. One use disappears at isel
2775   // time and the fold opportunity reappears.
2776   def : Pat<(v2f64 (X86Movddup VR128:$src)),
2777             (UNPCKLPDrr VR128:$src, VR128:$src)>;
2778 }
2779
2780 //===----------------------------------------------------------------------===//
2781 // SSE 1 & 2 - Extract Floating-Point Sign mask
2782 //===----------------------------------------------------------------------===//
2783
2784 /// sse12_extr_sign_mask - sse 1 & 2 unpack and interleave
2785 multiclass sse12_extr_sign_mask<RegisterClass RC, Intrinsic Int, string asm,
2786                                 Domain d> {
2787   def rr : PI<0x50, MRMSrcReg, (outs GR32orGR64:$dst), (ins RC:$src),
2788               !strconcat(asm, "\t{$src, $dst|$dst, $src}"),
2789               [(set GR32orGR64:$dst, (Int RC:$src))], IIC_SSE_MOVMSK, d>,
2790               Sched<[WriteVecLogic]>;
2791 }
2792
2793 let Predicates = [HasAVX] in {
2794   defm VMOVMSKPS : sse12_extr_sign_mask<VR128, int_x86_sse_movmsk_ps,
2795                                         "movmskps", SSEPackedSingle>, PS, VEX;
2796   defm VMOVMSKPD : sse12_extr_sign_mask<VR128, int_x86_sse2_movmsk_pd,
2797                                         "movmskpd", SSEPackedDouble>, PD, VEX;
2798   defm VMOVMSKPSY : sse12_extr_sign_mask<VR256, int_x86_avx_movmsk_ps_256,
2799                                         "movmskps", SSEPackedSingle>, PS,
2800                                         VEX, VEX_L;
2801   defm VMOVMSKPDY : sse12_extr_sign_mask<VR256, int_x86_avx_movmsk_pd_256,
2802                                         "movmskpd", SSEPackedDouble>, PD,
2803                                         VEX, VEX_L;
2804
2805   def : Pat<(i32 (X86fgetsign FR32:$src)),
2806             (VMOVMSKPSrr (COPY_TO_REGCLASS FR32:$src, VR128))>;
2807   def : Pat<(i64 (X86fgetsign FR32:$src)),
2808             (SUBREG_TO_REG (i64 0),
2809              (VMOVMSKPSrr (COPY_TO_REGCLASS FR32:$src, VR128)), sub_32bit)>;
2810   def : Pat<(i32 (X86fgetsign FR64:$src)),
2811             (VMOVMSKPDrr (COPY_TO_REGCLASS FR64:$src, VR128))>;
2812   def : Pat<(i64 (X86fgetsign FR64:$src)),
2813             (SUBREG_TO_REG (i64 0),
2814              (VMOVMSKPDrr (COPY_TO_REGCLASS FR64:$src, VR128)), sub_32bit)>;
2815 }
2816
2817 defm MOVMSKPS : sse12_extr_sign_mask<VR128, int_x86_sse_movmsk_ps, "movmskps",
2818                                      SSEPackedSingle>, PS;
2819 defm MOVMSKPD : sse12_extr_sign_mask<VR128, int_x86_sse2_movmsk_pd, "movmskpd",
2820                                      SSEPackedDouble>, PD;
2821
2822 def : Pat<(i32 (X86fgetsign FR32:$src)),
2823           (MOVMSKPSrr (COPY_TO_REGCLASS FR32:$src, VR128))>,
2824       Requires<[UseSSE1]>;
2825 def : Pat<(i64 (X86fgetsign FR32:$src)),
2826           (SUBREG_TO_REG (i64 0),
2827            (MOVMSKPSrr (COPY_TO_REGCLASS FR32:$src, VR128)), sub_32bit)>,
2828       Requires<[UseSSE1]>;
2829 def : Pat<(i32 (X86fgetsign FR64:$src)),
2830           (MOVMSKPDrr (COPY_TO_REGCLASS FR64:$src, VR128))>,
2831       Requires<[UseSSE2]>;
2832 def : Pat<(i64 (X86fgetsign FR64:$src)),
2833           (SUBREG_TO_REG (i64 0),
2834            (MOVMSKPDrr (COPY_TO_REGCLASS FR64:$src, VR128)), sub_32bit)>,
2835       Requires<[UseSSE2]>;
2836
2837 //===---------------------------------------------------------------------===//
2838 // SSE2 - Packed Integer Logical Instructions
2839 //===---------------------------------------------------------------------===//
2840
2841 let ExeDomain = SSEPackedInt in { // SSE integer instructions
2842
2843 /// PDI_binop_rm - Simple SSE2 binary operator.
2844 multiclass PDI_binop_rm<bits<8> opc, string OpcodeStr, SDNode OpNode,
2845                         ValueType OpVT, RegisterClass RC, PatFrag memop_frag,
2846                         X86MemOperand x86memop, OpndItins itins,
2847                         bit IsCommutable, bit Is2Addr> {
2848   let isCommutable = IsCommutable in
2849   def rr : PDI<opc, MRMSrcReg, (outs RC:$dst),
2850        (ins RC:$src1, RC:$src2),
2851        !if(Is2Addr,
2852            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
2853            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
2854        [(set RC:$dst, (OpVT (OpNode RC:$src1, RC:$src2)))], itins.rr>,
2855        Sched<[itins.Sched]>;
2856   def rm : PDI<opc, MRMSrcMem, (outs RC:$dst),
2857        (ins RC:$src1, x86memop:$src2),
2858        !if(Is2Addr,
2859            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
2860            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
2861        [(set RC:$dst, (OpVT (OpNode RC:$src1,
2862                                      (bitconvert (memop_frag addr:$src2)))))],
2863                                      itins.rm>,
2864        Sched<[itins.Sched.Folded, ReadAfterLd]>;
2865 }
2866 } // ExeDomain = SSEPackedInt
2867
2868 multiclass PDI_binop_all<bits<8> opc, string OpcodeStr, SDNode Opcode,
2869                          ValueType OpVT128, ValueType OpVT256,
2870                          OpndItins itins, bit IsCommutable = 0> {
2871 let Predicates = [HasAVX] in
2872   defm V#NAME : PDI_binop_rm<opc, !strconcat("v", OpcodeStr), Opcode, OpVT128,
2873                     VR128, loadv2i64, i128mem, itins, IsCommutable, 0>, VEX_4V;
2874
2875 let Constraints = "$src1 = $dst" in
2876   defm NAME : PDI_binop_rm<opc, OpcodeStr, Opcode, OpVT128, VR128,
2877                            memopv2i64, i128mem, itins, IsCommutable, 1>;
2878
2879 let Predicates = [HasAVX2] in
2880   defm V#NAME#Y : PDI_binop_rm<opc, !strconcat("v", OpcodeStr), Opcode,
2881                                OpVT256, VR256, loadv4i64, i256mem, itins,
2882                                IsCommutable, 0>, VEX_4V, VEX_L;
2883 }
2884
2885 // These are ordered here for pattern ordering requirements with the fp versions
2886
2887 defm PAND  : PDI_binop_all<0xDB, "pand", and, v2i64, v4i64,
2888                            SSE_VEC_BIT_ITINS_P, 1>;
2889 defm POR   : PDI_binop_all<0xEB, "por", or, v2i64, v4i64,
2890                            SSE_VEC_BIT_ITINS_P, 1>;
2891 defm PXOR  : PDI_binop_all<0xEF, "pxor", xor, v2i64, v4i64,
2892                            SSE_VEC_BIT_ITINS_P, 1>;
2893 defm PANDN : PDI_binop_all<0xDF, "pandn", X86andnp, v2i64, v4i64,
2894                            SSE_VEC_BIT_ITINS_P, 0>;
2895
2896 //===----------------------------------------------------------------------===//
2897 // SSE 1 & 2 - Logical Instructions
2898 //===----------------------------------------------------------------------===//
2899
2900 /// sse12_fp_alias_pack_logical - SSE 1 & 2 aliased packed FP logical ops
2901 ///
2902 multiclass sse12_fp_alias_pack_logical<bits<8> opc, string OpcodeStr,
2903                                        SDNode OpNode, OpndItins itins> {
2904   defm V#NAME#PS : sse12_fp_packed<opc, !strconcat(OpcodeStr, "ps"), OpNode,
2905               FR32, f32, f128mem, memopfsf32, SSEPackedSingle, itins, 0>,
2906               PS, VEX_4V;
2907
2908   defm V#NAME#PD : sse12_fp_packed<opc, !strconcat(OpcodeStr, "pd"), OpNode,
2909         FR64, f64, f128mem, memopfsf64, SSEPackedDouble, itins, 0>,
2910         PD, VEX_4V;
2911
2912   let Constraints = "$src1 = $dst" in {
2913     defm PS : sse12_fp_packed<opc, !strconcat(OpcodeStr, "ps"), OpNode, FR32,
2914                 f32, f128mem, memopfsf32, SSEPackedSingle, itins>,
2915                 PS;
2916
2917     defm PD : sse12_fp_packed<opc, !strconcat(OpcodeStr, "pd"), OpNode, FR64,
2918                 f64, f128mem, memopfsf64, SSEPackedDouble, itins>,
2919                 PD;
2920   }
2921 }
2922
2923 // Alias bitwise logical operations using SSE logical ops on packed FP values.
2924 let isCodeGenOnly = 1 in {
2925   defm FsAND  : sse12_fp_alias_pack_logical<0x54, "and", X86fand,
2926                 SSE_BIT_ITINS_P>;
2927   defm FsOR   : sse12_fp_alias_pack_logical<0x56, "or", X86for,
2928                 SSE_BIT_ITINS_P>;
2929   defm FsXOR  : sse12_fp_alias_pack_logical<0x57, "xor", X86fxor,
2930                 SSE_BIT_ITINS_P>;
2931
2932   let isCommutable = 0 in
2933     defm FsANDN : sse12_fp_alias_pack_logical<0x55, "andn", X86fandn,
2934                   SSE_BIT_ITINS_P>;
2935 }
2936
2937 /// sse12_fp_packed_logical - SSE 1 & 2 packed FP logical ops
2938 ///
2939 multiclass sse12_fp_packed_logical<bits<8> opc, string OpcodeStr,
2940                                    SDNode OpNode> {
2941   defm V#NAME#PSY : sse12_fp_packed_logical_rm<opc, VR256, SSEPackedSingle,
2942         !strconcat(OpcodeStr, "ps"), f256mem,
2943         [(set VR256:$dst, (v4i64 (OpNode VR256:$src1, VR256:$src2)))],
2944         [(set VR256:$dst, (OpNode (bc_v4i64 (v8f32 VR256:$src1)),
2945                            (loadv4i64 addr:$src2)))], 0>, PS, VEX_4V, VEX_L;
2946
2947   defm V#NAME#PDY : sse12_fp_packed_logical_rm<opc, VR256, SSEPackedDouble,
2948         !strconcat(OpcodeStr, "pd"), f256mem,
2949         [(set VR256:$dst, (OpNode (bc_v4i64 (v4f64 VR256:$src1)),
2950                                   (bc_v4i64 (v4f64 VR256:$src2))))],
2951         [(set VR256:$dst, (OpNode (bc_v4i64 (v4f64 VR256:$src1)),
2952                                   (loadv4i64 addr:$src2)))], 0>,
2953                                   PD, VEX_4V, VEX_L;
2954
2955   // In AVX no need to add a pattern for 128-bit logical rr ps, because they
2956   // are all promoted to v2i64, and the patterns are covered by the int
2957   // version. This is needed in SSE only, because v2i64 isn't supported on
2958   // SSE1, but only on SSE2.
2959   defm V#NAME#PS : sse12_fp_packed_logical_rm<opc, VR128, SSEPackedSingle,
2960        !strconcat(OpcodeStr, "ps"), f128mem, [],
2961        [(set VR128:$dst, (OpNode (bc_v2i64 (v4f32 VR128:$src1)),
2962                                  (loadv2i64 addr:$src2)))], 0>, PS, VEX_4V;
2963
2964   defm V#NAME#PD : sse12_fp_packed_logical_rm<opc, VR128, SSEPackedDouble,
2965        !strconcat(OpcodeStr, "pd"), f128mem,
2966        [(set VR128:$dst, (OpNode (bc_v2i64 (v2f64 VR128:$src1)),
2967                                  (bc_v2i64 (v2f64 VR128:$src2))))],
2968        [(set VR128:$dst, (OpNode (bc_v2i64 (v2f64 VR128:$src1)),
2969                                  (loadv2i64 addr:$src2)))], 0>,
2970                                                  PD, VEX_4V;
2971
2972   let Constraints = "$src1 = $dst" in {
2973     defm PS : sse12_fp_packed_logical_rm<opc, VR128, SSEPackedSingle,
2974          !strconcat(OpcodeStr, "ps"), f128mem,
2975          [(set VR128:$dst, (v2i64 (OpNode VR128:$src1, VR128:$src2)))],
2976          [(set VR128:$dst, (OpNode (bc_v2i64 (v4f32 VR128:$src1)),
2977                                    (memopv2i64 addr:$src2)))]>, PS;
2978
2979     defm PD : sse12_fp_packed_logical_rm<opc, VR128, SSEPackedDouble,
2980          !strconcat(OpcodeStr, "pd"), f128mem,
2981          [(set VR128:$dst, (OpNode (bc_v2i64 (v2f64 VR128:$src1)),
2982                                    (bc_v2i64 (v2f64 VR128:$src2))))],
2983          [(set VR128:$dst, (OpNode (bc_v2i64 (v2f64 VR128:$src1)),
2984                                    (memopv2i64 addr:$src2)))]>, PD;
2985   }
2986 }
2987
2988 defm AND  : sse12_fp_packed_logical<0x54, "and", and>;
2989 defm OR   : sse12_fp_packed_logical<0x56, "or", or>;
2990 defm XOR  : sse12_fp_packed_logical<0x57, "xor", xor>;
2991 let isCommutable = 0 in
2992   defm ANDN : sse12_fp_packed_logical<0x55, "andn", X86andnp>;
2993
2994 // AVX1 requires type coercions in order to fold loads directly into logical
2995 // operations.
2996 let Predicates = [HasAVX1Only] in {
2997   def : Pat<(bc_v8f32 (and VR256:$src1, (loadv4i64 addr:$src2))),
2998             (VANDPSYrm VR256:$src1, addr:$src2)>;
2999   def : Pat<(bc_v8f32 (or VR256:$src1, (loadv4i64 addr:$src2))),
3000             (VORPSYrm VR256:$src1, addr:$src2)>;
3001   def : Pat<(bc_v8f32 (xor VR256:$src1, (loadv4i64 addr:$src2))),
3002             (VXORPSYrm VR256:$src1, addr:$src2)>;
3003   def : Pat<(bc_v8f32 (X86andnp VR256:$src1, (loadv4i64 addr:$src2))),
3004             (VANDNPSYrm VR256:$src1, addr:$src2)>;
3005 }
3006
3007 //===----------------------------------------------------------------------===//
3008 // SSE 1 & 2 - Arithmetic Instructions
3009 //===----------------------------------------------------------------------===//
3010
3011 /// basic_sse12_fp_binop_xxx - SSE 1 & 2 binops come in both scalar and
3012 /// vector forms.
3013 ///
3014 /// In addition, we also have a special variant of the scalar form here to
3015 /// represent the associated intrinsic operation.  This form is unlike the
3016 /// plain scalar form, in that it takes an entire vector (instead of a scalar)
3017 /// and leaves the top elements unmodified (therefore these cannot be commuted).
3018 ///
3019 /// These three forms can each be reg+reg or reg+mem.
3020 ///
3021
3022 /// FIXME: once all 256-bit intrinsics are matched, cleanup and refactor those
3023 /// classes below
3024 multiclass basic_sse12_fp_binop_p<bits<8> opc, string OpcodeStr,
3025                                   SDNode OpNode, SizeItins itins> {
3026   defm V#NAME#PS : sse12_fp_packed<opc, !strconcat(OpcodeStr, "ps"), OpNode,
3027                                VR128, v4f32, f128mem, loadv4f32,
3028                                SSEPackedSingle, itins.s, 0>, PS, VEX_4V;
3029   defm V#NAME#PD : sse12_fp_packed<opc, !strconcat(OpcodeStr, "pd"), OpNode,
3030                                VR128, v2f64, f128mem, loadv2f64,
3031                                SSEPackedDouble, itins.d, 0>, PD, VEX_4V;
3032
3033   defm V#NAME#PSY : sse12_fp_packed<opc, !strconcat(OpcodeStr, "ps"),
3034                         OpNode, VR256, v8f32, f256mem, loadv8f32,
3035                         SSEPackedSingle, itins.s, 0>, PS, VEX_4V, VEX_L;
3036   defm V#NAME#PDY : sse12_fp_packed<opc, !strconcat(OpcodeStr, "pd"),
3037                         OpNode, VR256, v4f64, f256mem, loadv4f64,
3038                         SSEPackedDouble, itins.d, 0>, PD, VEX_4V, VEX_L;
3039
3040   let Constraints = "$src1 = $dst" in {
3041     defm PS : sse12_fp_packed<opc, !strconcat(OpcodeStr, "ps"), OpNode, VR128,
3042                               v4f32, f128mem, memopv4f32, SSEPackedSingle,
3043                               itins.s>, PS;
3044     defm PD : sse12_fp_packed<opc, !strconcat(OpcodeStr, "pd"), OpNode, VR128,
3045                               v2f64, f128mem, memopv2f64, SSEPackedDouble,
3046                               itins.d>, PD;
3047   }
3048 }
3049
3050 multiclass basic_sse12_fp_binop_s<bits<8> opc, string OpcodeStr, SDNode OpNode,
3051                                   SizeItins itins> {
3052   defm V#NAME#SS : sse12_fp_scalar<opc, !strconcat(OpcodeStr, "ss"),
3053                          OpNode, FR32, f32mem, itins.s, 0>, XS, VEX_4V, VEX_LIG;
3054   defm V#NAME#SD : sse12_fp_scalar<opc, !strconcat(OpcodeStr, "sd"),
3055                          OpNode, FR64, f64mem, itins.d, 0>, XD, VEX_4V, VEX_LIG;
3056
3057   let Constraints = "$src1 = $dst" in {
3058     defm SS : sse12_fp_scalar<opc, !strconcat(OpcodeStr, "ss"),
3059                               OpNode, FR32, f32mem, itins.s>, XS;
3060     defm SD : sse12_fp_scalar<opc, !strconcat(OpcodeStr, "sd"),
3061                               OpNode, FR64, f64mem, itins.d>, XD;
3062   }
3063 }
3064
3065 multiclass basic_sse12_fp_binop_s_int<bits<8> opc, string OpcodeStr,
3066                                       SizeItins itins> {
3067   defm V#NAME#SS : sse12_fp_scalar_int<opc, OpcodeStr, VR128,
3068                    !strconcat(OpcodeStr, "ss"), "", "_ss", ssmem, sse_load_f32,
3069                    itins.s, 0>, XS, VEX_4V, VEX_LIG;
3070   defm V#NAME#SD : sse12_fp_scalar_int<opc, OpcodeStr, VR128,
3071                    !strconcat(OpcodeStr, "sd"), "2", "_sd", sdmem, sse_load_f64,
3072                    itins.d, 0>, XD, VEX_4V, VEX_LIG;
3073
3074   let Constraints = "$src1 = $dst" in {
3075     defm SS : sse12_fp_scalar_int<opc, OpcodeStr, VR128,
3076                    !strconcat(OpcodeStr, "ss"), "", "_ss", ssmem, sse_load_f32,
3077                    itins.s>, XS;
3078     defm SD : sse12_fp_scalar_int<opc, OpcodeStr, VR128,
3079                    !strconcat(OpcodeStr, "sd"), "2", "_sd", sdmem, sse_load_f64,
3080                    itins.d>, XD;
3081   }
3082 }
3083
3084 // Binary Arithmetic instructions
3085 defm ADD : basic_sse12_fp_binop_p<0x58, "add", fadd, SSE_ALU_ITINS_P>,
3086            basic_sse12_fp_binop_s<0x58, "add", fadd, SSE_ALU_ITINS_S>,
3087            basic_sse12_fp_binop_s_int<0x58, "add", SSE_ALU_ITINS_S>;
3088 defm MUL : basic_sse12_fp_binop_p<0x59, "mul", fmul, SSE_MUL_ITINS_P>,
3089            basic_sse12_fp_binop_s<0x59, "mul", fmul, SSE_MUL_ITINS_S>,
3090            basic_sse12_fp_binop_s_int<0x59, "mul", SSE_MUL_ITINS_S>;
3091 let isCommutable = 0 in {
3092   defm SUB : basic_sse12_fp_binop_p<0x5C, "sub", fsub, SSE_ALU_ITINS_P>,
3093              basic_sse12_fp_binop_s<0x5C, "sub", fsub, SSE_ALU_ITINS_S>,
3094              basic_sse12_fp_binop_s_int<0x5C, "sub", SSE_ALU_ITINS_S>;
3095   defm DIV : basic_sse12_fp_binop_p<0x5E, "div", fdiv, SSE_DIV_ITINS_P>,
3096              basic_sse12_fp_binop_s<0x5E, "div", fdiv, SSE_DIV_ITINS_S>,
3097              basic_sse12_fp_binop_s_int<0x5E, "div", SSE_DIV_ITINS_S>;
3098   defm MAX : basic_sse12_fp_binop_p<0x5F, "max", X86fmax, SSE_ALU_ITINS_P>,
3099              basic_sse12_fp_binop_s<0x5F, "max", X86fmax, SSE_ALU_ITINS_S>,
3100              basic_sse12_fp_binop_s_int<0x5F, "max", SSE_ALU_ITINS_S>;
3101   defm MIN : basic_sse12_fp_binop_p<0x5D, "min", X86fmin, SSE_ALU_ITINS_P>,
3102              basic_sse12_fp_binop_s<0x5D, "min", X86fmin, SSE_ALU_ITINS_S>,
3103              basic_sse12_fp_binop_s_int<0x5D, "min", SSE_ALU_ITINS_S>;
3104 }
3105
3106 let isCodeGenOnly = 1 in {
3107   defm MAXC: basic_sse12_fp_binop_p<0x5F, "max", X86fmaxc, SSE_ALU_ITINS_P>,
3108              basic_sse12_fp_binop_s<0x5F, "max", X86fmaxc, SSE_ALU_ITINS_S>;
3109   defm MINC: basic_sse12_fp_binop_p<0x5D, "min", X86fminc, SSE_ALU_ITINS_P>,
3110              basic_sse12_fp_binop_s<0x5D, "min", X86fminc, SSE_ALU_ITINS_S>;
3111 }
3112
3113 // Patterns used to select SSE scalar fp arithmetic instructions from
3114 // a scalar fp operation followed by a blend.
3115 //
3116 // These patterns know, for example, how to select an ADDSS from a
3117 // float add plus vector insert.
3118 //
3119 // The effect is that the backend no longer emits unnecessary vector
3120 // insert instructions immediately after SSE scalar fp instructions
3121 // like addss or mulss.
3122 //
3123 // For example, given the following code:
3124 //   __m128 foo(__m128 A, __m128 B) {
3125 //     A[0] += B[0];
3126 //     return A;
3127 //   }
3128 //
3129 // previously we generated:
3130 //   addss %xmm0, %xmm1
3131 //   movss %xmm1, %xmm0
3132 // 
3133 // we now generate:
3134 //   addss %xmm1, %xmm0
3135
3136 let Predicates = [UseSSE1] in {
3137   def : Pat<(v4f32 (X86Movss (v4f32 VR128:$dst), (v4f32 (scalar_to_vector (fadd
3138                       (f32 (vector_extract (v4f32 VR128:$dst), (iPTR 0))),
3139                       FR32:$src))))),
3140             (ADDSSrr_Int v4f32:$dst, (COPY_TO_REGCLASS FR32:$src, VR128))>;
3141   def : Pat<(v4f32 (X86Movss (v4f32 VR128:$dst), (v4f32 (scalar_to_vector (fsub
3142                       (f32 (vector_extract (v4f32 VR128:$dst), (iPTR 0))),
3143                       FR32:$src))))),
3144             (SUBSSrr_Int v4f32:$dst, (COPY_TO_REGCLASS FR32:$src, VR128))>;
3145   def : Pat<(v4f32 (X86Movss (v4f32 VR128:$dst), (v4f32 (scalar_to_vector (fmul
3146                       (f32 (vector_extract (v4f32 VR128:$dst), (iPTR 0))),
3147                       FR32:$src))))),
3148             (MULSSrr_Int v4f32:$dst, (COPY_TO_REGCLASS FR32:$src, VR128))>;
3149   def : Pat<(v4f32 (X86Movss (v4f32 VR128:$dst), (v4f32 (scalar_to_vector (fdiv
3150                       (f32 (vector_extract (v4f32 VR128:$dst), (iPTR 0))),
3151                       FR32:$src))))),
3152             (DIVSSrr_Int v4f32:$dst, (COPY_TO_REGCLASS FR32:$src, VR128))>;
3153 }
3154
3155 let Predicates = [UseSSE2] in {
3156   // SSE2 patterns to select scalar double-precision fp arithmetic instructions
3157
3158   def : Pat<(v2f64 (X86Movsd (v2f64 VR128:$dst), (v2f64 (scalar_to_vector (fadd
3159                       (f64 (vector_extract (v2f64 VR128:$dst), (iPTR 0))),
3160                       FR64:$src))))),
3161             (ADDSDrr_Int v2f64:$dst, (COPY_TO_REGCLASS FR64:$src, VR128))>;
3162   def : Pat<(v2f64 (X86Movsd (v2f64 VR128:$dst), (v2f64 (scalar_to_vector (fsub
3163                       (f64 (vector_extract (v2f64 VR128:$dst), (iPTR 0))),
3164                       FR64:$src))))),
3165             (SUBSDrr_Int v2f64:$dst, (COPY_TO_REGCLASS FR64:$src, VR128))>;
3166   def : Pat<(v2f64 (X86Movsd (v2f64 VR128:$dst), (v2f64 (scalar_to_vector (fmul
3167                       (f64 (vector_extract (v2f64 VR128:$dst), (iPTR 0))),
3168                       FR64:$src))))),
3169             (MULSDrr_Int v2f64:$dst, (COPY_TO_REGCLASS FR64:$src, VR128))>;
3170   def : Pat<(v2f64 (X86Movsd (v2f64 VR128:$dst), (v2f64 (scalar_to_vector (fdiv
3171                       (f64 (vector_extract (v2f64 VR128:$dst), (iPTR 0))),
3172                       FR64:$src))))),
3173             (DIVSDrr_Int v2f64:$dst, (COPY_TO_REGCLASS FR64:$src, VR128))>;
3174 }
3175
3176 let Predicates = [UseSSE41] in {
3177   // If the subtarget has SSE4.1 but not AVX, the vector insert
3178   // instruction is lowered into a X86insertps rather than a X86Movss.
3179   // When selecting SSE scalar single-precision fp arithmetic instructions,
3180   // make sure that we correctly match the X86insertps.
3181
3182   def : Pat<(v4f32 (X86insertps (v4f32 VR128:$dst), (v4f32 (scalar_to_vector
3183                   (fadd (f32 (vector_extract (v4f32 VR128:$dst), (iPTR 0))),
3184                     FR32:$src))), (iPTR 0))),
3185             (ADDSSrr_Int v4f32:$dst, (COPY_TO_REGCLASS FR32:$src, VR128))>;
3186   def : Pat<(v4f32 (X86insertps (v4f32 VR128:$dst), (v4f32 (scalar_to_vector
3187                   (fsub (f32 (vector_extract (v4f32 VR128:$dst), (iPTR 0))),
3188                     FR32:$src))), (iPTR 0))),
3189             (SUBSSrr_Int v4f32:$dst, (COPY_TO_REGCLASS FR32:$src, VR128))>;
3190   def : Pat<(v4f32 (X86insertps (v4f32 VR128:$dst), (v4f32 (scalar_to_vector
3191                   (fmul (f32 (vector_extract (v4f32 VR128:$dst), (iPTR 0))),
3192                     FR32:$src))), (iPTR 0))),
3193             (MULSSrr_Int v4f32:$dst, (COPY_TO_REGCLASS FR32:$src, VR128))>;
3194   def : Pat<(v4f32 (X86insertps (v4f32 VR128:$dst), (v4f32 (scalar_to_vector
3195                   (fdiv (f32 (vector_extract (v4f32 VR128:$dst), (iPTR 0))),
3196                     FR32:$src))), (iPTR 0))),
3197             (DIVSSrr_Int v4f32:$dst, (COPY_TO_REGCLASS FR32:$src, VR128))>;
3198 }
3199
3200 let Predicates = [HasAVX] in {
3201   // The following patterns select AVX Scalar single/double precision fp
3202   // arithmetic instructions.
3203
3204   def : Pat<(v2f64 (X86Movsd (v2f64 VR128:$dst), (v2f64 (scalar_to_vector (fadd
3205                       (f64 (vector_extract (v2f64 VR128:$dst), (iPTR 0))),
3206                       FR64:$src))))),
3207             (VADDSDrr_Int v2f64:$dst, (COPY_TO_REGCLASS FR64:$src, VR128))>;
3208   def : Pat<(v2f64 (X86Movsd (v2f64 VR128:$dst), (v2f64 (scalar_to_vector (fsub
3209                       (f64 (vector_extract (v2f64 VR128:$dst), (iPTR 0))),
3210                       FR64:$src))))),
3211             (VSUBSDrr_Int v2f64:$dst, (COPY_TO_REGCLASS FR64:$src, VR128))>;
3212   def : Pat<(v2f64 (X86Movsd (v2f64 VR128:$dst), (v2f64 (scalar_to_vector (fmul
3213                       (f64 (vector_extract (v2f64 VR128:$dst), (iPTR 0))),
3214                       FR64:$src))))),
3215             (VMULSDrr_Int v2f64:$dst, (COPY_TO_REGCLASS FR64:$src, VR128))>;
3216   def : Pat<(v2f64 (X86Movsd (v2f64 VR128:$dst), (v2f64 (scalar_to_vector (fdiv
3217                       (f64 (vector_extract (v2f64 VR128:$dst), (iPTR 0))),
3218                       FR64:$src))))),
3219             (VDIVSDrr_Int v2f64:$dst, (COPY_TO_REGCLASS FR64:$src, VR128))>;
3220   def : Pat<(v4f32 (X86insertps (v4f32 VR128:$dst), (v4f32 (scalar_to_vector
3221                  (fadd (f32 (vector_extract (v4f32 VR128:$dst), (iPTR 0))),
3222                        FR32:$src))), (iPTR 0))),
3223             (VADDSSrr_Int v4f32:$dst, (COPY_TO_REGCLASS FR32:$src, VR128))>;
3224   def : Pat<(v4f32 (X86insertps (v4f32 VR128:$dst), (v4f32 (scalar_to_vector
3225                  (fsub (f32 (vector_extract (v4f32 VR128:$dst), (iPTR 0))),
3226                        FR32:$src))), (iPTR 0))),
3227             (VSUBSSrr_Int v4f32:$dst, (COPY_TO_REGCLASS FR32:$src, VR128))>;
3228   def : Pat<(v4f32 (X86insertps (v4f32 VR128:$dst), (v4f32 (scalar_to_vector
3229                  (fmul (f32 (vector_extract (v4f32 VR128:$dst), (iPTR 0))),
3230                        FR32:$src))), (iPTR 0))),
3231             (VMULSSrr_Int v4f32:$dst, (COPY_TO_REGCLASS FR32:$src, VR128))>;
3232   def : Pat<(v4f32 (X86insertps (v4f32 VR128:$dst), (v4f32 (scalar_to_vector
3233                  (fdiv (f32 (vector_extract (v4f32 VR128:$dst), (iPTR 0))),
3234                        FR32:$src))), (iPTR 0))),
3235             (VDIVSSrr_Int v4f32:$dst, (COPY_TO_REGCLASS FR32:$src, VR128))>;
3236 }
3237
3238 // Patterns used to select SSE scalar fp arithmetic instructions from
3239 // a vector packed single/double fp operation followed by a vector insert.
3240 //
3241 // The effect is that the backend converts the packed fp instruction
3242 // followed by a vector insert into a single SSE scalar fp instruction.
3243 //
3244 // For example, given the following code:
3245 //   __m128 foo(__m128 A, __m128 B) {
3246 //     __m128 C = A + B;
3247 //     return (__m128) {c[0], a[1], a[2], a[3]};
3248 //   }
3249 //
3250 // previously we generated:
3251 //   addps %xmm0, %xmm1
3252 //   movss %xmm1, %xmm0
3253 // 
3254 // we now generate:
3255 //   addss %xmm1, %xmm0
3256
3257 let Predicates = [UseSSE1] in {
3258   def : Pat<(v4f32 (X86Movss (v4f32 VR128:$dst),
3259                    (fadd (v4f32 VR128:$dst), (v4f32 VR128:$src)))),
3260             (ADDSSrr_Int v4f32:$dst, v4f32:$src)>;
3261   def : Pat<(v4f32 (X86Movss (v4f32 VR128:$dst), 
3262                    (fsub (v4f32 VR128:$dst), (v4f32 VR128:$src)))),
3263             (SUBSSrr_Int v4f32:$dst, v4f32:$src)>;
3264   def : Pat<(v4f32 (X86Movss (v4f32 VR128:$dst),
3265                    (fmul (v4f32 VR128:$dst), (v4f32 VR128:$src)))),
3266             (MULSSrr_Int v4f32:$dst, v4f32:$src)>;
3267   def : Pat<(v4f32 (X86Movss (v4f32 VR128:$dst), 
3268                    (fdiv (v4f32 VR128:$dst), (v4f32 VR128:$src)))),
3269             (DIVSSrr_Int v4f32:$dst, v4f32:$src)>;
3270 }
3271
3272 let Predicates = [UseSSE2] in {
3273   // SSE2 patterns to select scalar double-precision fp arithmetic instructions
3274   // from a packed double-precision fp instruction plus movsd.
3275
3276   def : Pat<(v2f64 (X86Movsd (v2f64 VR128:$dst),
3277                    (fadd (v2f64 VR128:$dst), (v2f64 VR128:$src)))),
3278             (ADDSDrr_Int v2f64:$dst, v2f64:$src)>;
3279   def : Pat<(v2f64 (X86Movsd (v2f64 VR128:$dst),
3280                    (fsub (v2f64 VR128:$dst), (v2f64 VR128:$src)))),
3281             (SUBSDrr_Int v2f64:$dst, v2f64:$src)>;
3282   def : Pat<(v2f64 (X86Movsd (v2f64 VR128:$dst),
3283                    (fmul (v2f64 VR128:$dst), (v2f64 VR128:$src)))),
3284             (MULSDrr_Int v2f64:$dst, v2f64:$src)>;
3285   def : Pat<(v2f64 (X86Movsd (v2f64 VR128:$dst),
3286                    (fdiv (v2f64 VR128:$dst), (v2f64 VR128:$src)))),
3287             (DIVSDrr_Int v2f64:$dst, v2f64:$src)>;
3288 }
3289
3290 let Predicates = [HasAVX] in {
3291   // The following patterns select AVX Scalar single/double precision fp
3292   // arithmetic instructions from a packed single precision fp instruction
3293   // plus movss/movsd.
3294
3295   def : Pat<(v4f32 (X86Movss (v4f32 VR128:$dst),
3296                    (fadd (v4f32 VR128:$dst), (v4f32 VR128:$src)))),
3297             (VADDSSrr_Int v4f32:$dst, v4f32:$src)>;
3298   def : Pat<(v4f32 (X86Movss (v4f32 VR128:$dst),
3299                    (fsub (v4f32 VR128:$dst), (v4f32 VR128:$src)))),
3300             (VSUBSSrr_Int v4f32:$dst, v4f32:$src)>;
3301   def : Pat<(v4f32 (X86Movss (v4f32 VR128:$dst),
3302                    (fmul (v4f32 VR128:$dst), (v4f32 VR128:$src)))),
3303             (VMULSSrr_Int v4f32:$dst, v4f32:$src)>;
3304   def : Pat<(v4f32 (X86Movss (v4f32 VR128:$dst),
3305                    (fdiv (v4f32 VR128:$dst), (v4f32 VR128:$src)))),
3306             (VDIVSSrr_Int v4f32:$dst, v4f32:$src)>;
3307   def : Pat<(v2f64 (X86Movsd (v2f64 VR128:$dst),
3308                    (fadd (v2f64 VR128:$dst), (v2f64 VR128:$src)))),
3309             (VADDSDrr_Int v2f64:$dst, v2f64:$src)>;
3310   def : Pat<(v2f64 (X86Movsd (v2f64 VR128:$dst),
3311                    (fsub (v2f64 VR128:$dst), (v2f64 VR128:$src)))),
3312             (VSUBSDrr_Int v2f64:$dst, v2f64:$src)>;
3313   def : Pat<(v2f64 (X86Movsd (v2f64 VR128:$dst),
3314                    (fmul (v2f64 VR128:$dst), (v2f64 VR128:$src)))),
3315             (VMULSDrr_Int v2f64:$dst, v2f64:$src)>;
3316   def : Pat<(v2f64 (X86Movsd (v2f64 VR128:$dst),
3317                    (fdiv (v2f64 VR128:$dst), (v2f64 VR128:$src)))),
3318             (VDIVSDrr_Int v2f64:$dst, v2f64:$src)>;
3319 }
3320
3321 /// Unop Arithmetic
3322 /// In addition, we also have a special variant of the scalar form here to
3323 /// represent the associated intrinsic operation.  This form is unlike the
3324 /// plain scalar form, in that it takes an entire vector (instead of a
3325 /// scalar) and leaves the top elements undefined.
3326 ///
3327 /// And, we have a special variant form for a full-vector intrinsic form.
3328
3329 let Sched = WriteFSqrt in {
3330 def SSE_SQRTPS : OpndItins<
3331   IIC_SSE_SQRTPS_RR, IIC_SSE_SQRTPS_RM
3332 >;
3333
3334 def SSE_SQRTSS : OpndItins<
3335   IIC_SSE_SQRTSS_RR, IIC_SSE_SQRTSS_RM
3336 >;
3337
3338 def SSE_SQRTPD : OpndItins<
3339   IIC_SSE_SQRTPD_RR, IIC_SSE_SQRTPD_RM
3340 >;
3341
3342 def SSE_SQRTSD : OpndItins<
3343   IIC_SSE_SQRTSD_RR, IIC_SSE_SQRTSD_RM
3344 >;
3345 }
3346
3347 let Sched = WriteFRcp in {
3348 def SSE_RCPP : OpndItins<
3349   IIC_SSE_RCPP_RR, IIC_SSE_RCPP_RM
3350 >;
3351
3352 def SSE_RCPS : OpndItins<
3353   IIC_SSE_RCPS_RR, IIC_SSE_RCPS_RM
3354 >;
3355 }
3356
3357 /// sse1_fp_unop_s - SSE1 unops in scalar form.
3358 multiclass sse1_fp_unop_s<bits<8> opc, string OpcodeStr,
3359                           SDNode OpNode, Intrinsic F32Int, OpndItins itins> {
3360 let Predicates = [HasAVX], hasSideEffects = 0 in {
3361   def V#NAME#SSr : SSI<opc, MRMSrcReg, (outs FR32:$dst),
3362                       (ins FR32:$src1, FR32:$src2),
3363                       !strconcat("v", OpcodeStr,
3364                                  "ss\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
3365                       []>, VEX_4V, VEX_LIG, Sched<[itins.Sched]>;
3366   let mayLoad = 1 in {
3367   def V#NAME#SSm : SSI<opc, MRMSrcMem, (outs FR32:$dst),
3368                       (ins FR32:$src1,f32mem:$src2),
3369                       !strconcat("v", OpcodeStr,
3370                                  "ss\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
3371                       []>, VEX_4V, VEX_LIG,
3372                    Sched<[itins.Sched.Folded, ReadAfterLd]>;
3373   let isCodeGenOnly = 1 in
3374   def V#NAME#SSm_Int : SSI<opc, MRMSrcMem, (outs VR128:$dst),
3375                       (ins VR128:$src1, ssmem:$src2),
3376                       !strconcat("v", OpcodeStr,
3377                                  "ss\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
3378                       []>, VEX_4V, VEX_LIG,
3379                       Sched<[itins.Sched.Folded, ReadAfterLd]>;
3380   }
3381 }
3382
3383   def SSr : SSI<opc, MRMSrcReg, (outs FR32:$dst), (ins FR32:$src),
3384                 !strconcat(OpcodeStr, "ss\t{$src, $dst|$dst, $src}"),
3385                 [(set FR32:$dst, (OpNode FR32:$src))]>, Sched<[itins.Sched]>;
3386   // For scalar unary operations, fold a load into the operation
3387   // only in OptForSize mode. It eliminates an instruction, but it also
3388   // eliminates a whole-register clobber (the load), so it introduces a
3389   // partial register update condition.
3390   def SSm : I<opc, MRMSrcMem, (outs FR32:$dst), (ins f32mem:$src),
3391                 !strconcat(OpcodeStr, "ss\t{$src, $dst|$dst, $src}"),
3392                 [(set FR32:$dst, (OpNode (load addr:$src)))], itins.rm>, XS,
3393             Requires<[UseSSE1, OptForSize]>, Sched<[itins.Sched.Folded]>;
3394 let isCodeGenOnly = 1 in {
3395   def SSr_Int : SSI<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3396                     !strconcat(OpcodeStr, "ss\t{$src, $dst|$dst, $src}"),
3397                     [(set VR128:$dst, (F32Int VR128:$src))], itins.rr>,
3398                 Sched<[itins.Sched]>;
3399   def SSm_Int : SSI<opc, MRMSrcMem, (outs VR128:$dst), (ins ssmem:$src),
3400                     !strconcat(OpcodeStr, "ss\t{$src, $dst|$dst, $src}"),
3401                     [(set VR128:$dst, (F32Int sse_load_f32:$src))], itins.rm>,
3402                 Sched<[itins.Sched.Folded]>;
3403 }
3404 }
3405
3406 /// sse1_fp_unop_s_rw - SSE1 unops where vector form has a read-write operand.
3407 multiclass sse1_fp_unop_rw<bits<8> opc, string OpcodeStr, SDNode OpNode,
3408                            OpndItins itins> {
3409 let Predicates = [HasAVX], hasSideEffects = 0 in {
3410   def V#NAME#SSr : SSI<opc, MRMSrcReg, (outs FR32:$dst),
3411                        (ins FR32:$src1, FR32:$src2),
3412                        !strconcat("v", OpcodeStr,
3413                            "ss\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
3414                 []>, VEX_4V, VEX_LIG, Sched<[itins.Sched]>;
3415   let mayLoad = 1 in {
3416   def V#NAME#SSm : SSI<opc, MRMSrcMem, (outs FR32:$dst),
3417                       (ins FR32:$src1,f32mem:$src2),
3418                       !strconcat("v", OpcodeStr,
3419                                  "ss\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
3420                       []>, VEX_4V, VEX_LIG,
3421                    Sched<[itins.Sched.Folded, ReadAfterLd]>;
3422   let isCodeGenOnly = 1 in
3423   def V#NAME#SSm_Int : SSI<opc, MRMSrcMem, (outs VR128:$dst),
3424                       (ins VR128:$src1, ssmem:$src2),
3425                       !strconcat("v", OpcodeStr,
3426                                  "ss\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
3427                       []>, VEX_4V, VEX_LIG,
3428                       Sched<[itins.Sched.Folded, ReadAfterLd]>;
3429   }
3430 }
3431
3432   def SSr : SSI<opc, MRMSrcReg, (outs FR32:$dst), (ins FR32:$src),
3433                 !strconcat(OpcodeStr, "ss\t{$src, $dst|$dst, $src}"),
3434                 [(set FR32:$dst, (OpNode FR32:$src))]>, Sched<[itins.Sched]>;
3435   // For scalar unary operations, fold a load into the operation
3436   // only in OptForSize mode. It eliminates an instruction, but it also
3437   // eliminates a whole-register clobber (the load), so it introduces a
3438   // partial register update condition.
3439   def SSm : I<opc, MRMSrcMem, (outs FR32:$dst), (ins f32mem:$src),
3440                 !strconcat(OpcodeStr, "ss\t{$src, $dst|$dst, $src}"),
3441                 [(set FR32:$dst, (OpNode (load addr:$src)))], itins.rm>, XS,
3442             Requires<[UseSSE1, OptForSize]>, Sched<[itins.Sched.Folded]>;
3443   let isCodeGenOnly = 1, Constraints = "$src1 = $dst" in {
3444     def SSr_Int : SSI<opc, MRMSrcReg, (outs VR128:$dst),
3445                       (ins VR128:$src1, VR128:$src2),
3446                       !strconcat(OpcodeStr, "ss\t{$src2, $dst|$dst, $src2}"),
3447                       [], itins.rr>, Sched<[itins.Sched]>;
3448     let mayLoad = 1, hasSideEffects = 0 in
3449     def SSm_Int : SSI<opc, MRMSrcMem, (outs VR128:$dst),
3450                       (ins VR128:$src1, ssmem:$src2),
3451                       !strconcat(OpcodeStr, "ss\t{$src2, $dst|$dst, $src2}"),
3452                       [], itins.rm>, Sched<[itins.Sched.Folded, ReadAfterLd]>;
3453   }
3454 }
3455
3456 /// sse1_fp_unop_p - SSE1 unops in packed form.
3457 multiclass sse1_fp_unop_p<bits<8> opc, string OpcodeStr, SDNode OpNode,
3458                           OpndItins itins> {
3459 let Predicates = [HasAVX] in {
3460   def V#NAME#PSr : PSI<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3461                        !strconcat("v", OpcodeStr,
3462                                   "ps\t{$src, $dst|$dst, $src}"),
3463                        [(set VR128:$dst, (v4f32 (OpNode VR128:$src)))],
3464                        itins.rr>, VEX, Sched<[itins.Sched]>;
3465   def V#NAME#PSm : PSI<opc, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
3466                        !strconcat("v", OpcodeStr,
3467                                   "ps\t{$src, $dst|$dst, $src}"),
3468                        [(set VR128:$dst, (OpNode (loadv4f32 addr:$src)))],
3469                        itins.rm>, VEX, Sched<[itins.Sched.Folded]>;
3470   def V#NAME#PSYr : PSI<opc, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
3471                         !strconcat("v", OpcodeStr,
3472                                    "ps\t{$src, $dst|$dst, $src}"),
3473                         [(set VR256:$dst, (v8f32 (OpNode VR256:$src)))],
3474                         itins.rr>, VEX, VEX_L, Sched<[itins.Sched]>;
3475   def V#NAME#PSYm : PSI<opc, MRMSrcMem, (outs VR256:$dst), (ins f256mem:$src),
3476                         !strconcat("v", OpcodeStr,
3477                                    "ps\t{$src, $dst|$dst, $src}"),
3478                         [(set VR256:$dst, (OpNode (loadv8f32 addr:$src)))],
3479                         itins.rm>, VEX, VEX_L, Sched<[itins.Sched.Folded]>;
3480 }
3481
3482   def PSr : PSI<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3483                 !strconcat(OpcodeStr, "ps\t{$src, $dst|$dst, $src}"),
3484                 [(set VR128:$dst, (v4f32 (OpNode VR128:$src)))], itins.rr>,
3485             Sched<[itins.Sched]>;
3486   def PSm : PSI<opc, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
3487                 !strconcat(OpcodeStr, "ps\t{$src, $dst|$dst, $src}"),
3488                 [(set VR128:$dst, (OpNode (memopv4f32 addr:$src)))], itins.rm>,
3489             Sched<[itins.Sched.Folded]>;
3490 }
3491
3492 /// sse1_fp_unop_p_int - SSE1 intrinsics unops in packed forms.
3493 multiclass sse1_fp_unop_p_int<bits<8> opc, string OpcodeStr,
3494                               Intrinsic V4F32Int, Intrinsic V8F32Int,
3495                               OpndItins itins> {
3496 let isCodeGenOnly = 1 in {
3497 let Predicates = [HasAVX] in {
3498   def V#NAME#PSr_Int : PSI<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3499                            !strconcat("v", OpcodeStr,
3500                                       "ps\t{$src, $dst|$dst, $src}"),
3501                            [(set VR128:$dst, (V4F32Int VR128:$src))],
3502                            itins.rr>, VEX, Sched<[itins.Sched]>;
3503   def V#NAME#PSm_Int : PSI<opc, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
3504                           !strconcat("v", OpcodeStr,
3505                           "ps\t{$src, $dst|$dst, $src}"),
3506                           [(set VR128:$dst, (V4F32Int (loadv4f32 addr:$src)))],
3507                           itins.rm>, VEX, Sched<[itins.Sched.Folded]>;
3508   def V#NAME#PSYr_Int : PSI<opc, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
3509                             !strconcat("v", OpcodeStr,
3510                                        "ps\t{$src, $dst|$dst, $src}"),
3511                             [(set VR256:$dst, (V8F32Int VR256:$src))],
3512                             itins.rr>, VEX, VEX_L, Sched<[itins.Sched]>;
3513   def V#NAME#PSYm_Int : PSI<opc, MRMSrcMem, (outs VR256:$dst),
3514                           (ins f256mem:$src),
3515                           !strconcat("v", OpcodeStr,
3516                                     "ps\t{$src, $dst|$dst, $src}"),
3517                           [(set VR256:$dst, (V8F32Int (loadv8f32 addr:$src)))],
3518                           itins.rm>, VEX, VEX_L, Sched<[itins.Sched.Folded]>;
3519 }
3520
3521   def PSr_Int : PSI<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3522                     !strconcat(OpcodeStr, "ps\t{$src, $dst|$dst, $src}"),
3523                     [(set VR128:$dst, (V4F32Int VR128:$src))],
3524                     itins.rr>, Sched<[itins.Sched]>;
3525   def PSm_Int : PSI<opc, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
3526                     !strconcat(OpcodeStr, "ps\t{$src, $dst|$dst, $src}"),
3527                     [(set VR128:$dst, (V4F32Int (memopv4f32 addr:$src)))],
3528                     itins.rm>, Sched<[itins.Sched.Folded]>;
3529 } // isCodeGenOnly = 1
3530 }
3531
3532 /// sse2_fp_unop_s - SSE2 unops in scalar form.
3533 multiclass sse2_fp_unop_s<bits<8> opc, string OpcodeStr,
3534                           SDNode OpNode, Intrinsic F64Int, OpndItins itins> {
3535 let Predicates = [HasAVX], hasSideEffects = 0 in {
3536   def V#NAME#SDr : SDI<opc, MRMSrcReg, (outs FR64:$dst),
3537                       (ins FR64:$src1, FR64:$src2),
3538                       !strconcat("v", OpcodeStr,
3539                                  "sd\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
3540                       []>, VEX_4V, VEX_LIG, Sched<[itins.Sched]>;
3541   let mayLoad = 1 in {
3542   def V#NAME#SDm : SDI<opc, MRMSrcMem, (outs FR64:$dst),
3543                       (ins FR64:$src1,f64mem:$src2),
3544                       !strconcat("v", OpcodeStr,
3545                                  "sd\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
3546                       []>, VEX_4V, VEX_LIG,
3547                    Sched<[itins.Sched.Folded, ReadAfterLd]>;
3548   let isCodeGenOnly = 1 in
3549   def V#NAME#SDm_Int : SDI<opc, MRMSrcMem, (outs VR128:$dst),
3550                       (ins VR128:$src1, sdmem:$src2),
3551                       !strconcat("v", OpcodeStr,
3552                                  "sd\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
3553                       []>, VEX_4V, VEX_LIG,
3554                       Sched<[itins.Sched.Folded, ReadAfterLd]>;
3555   }
3556 }
3557
3558   def SDr : SDI<opc, MRMSrcReg, (outs FR64:$dst), (ins FR64:$src),
3559                 !strconcat(OpcodeStr, "sd\t{$src, $dst|$dst, $src}"),
3560                 [(set FR64:$dst, (OpNode FR64:$src))], itins.rr>,
3561             Sched<[itins.Sched]>;
3562   // See the comments in sse1_fp_unop_s for why this is OptForSize.
3563   def SDm : I<opc, MRMSrcMem, (outs FR64:$dst), (ins f64mem:$src),
3564                 !strconcat(OpcodeStr, "sd\t{$src, $dst|$dst, $src}"),
3565                 [(set FR64:$dst, (OpNode (load addr:$src)))], itins.rm>, XD,
3566             Requires<[UseSSE2, OptForSize]>, Sched<[itins.Sched.Folded]>;
3567 let isCodeGenOnly = 1 in {
3568   def SDr_Int : SDI<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3569                     !strconcat(OpcodeStr, "sd\t{$src, $dst|$dst, $src}"),
3570                     [(set VR128:$dst, (F64Int VR128:$src))], itins.rr>,
3571                 Sched<[itins.Sched]>;
3572   def SDm_Int : SDI<opc, MRMSrcMem, (outs VR128:$dst), (ins sdmem:$src),
3573                     !strconcat(OpcodeStr, "sd\t{$src, $dst|$dst, $src}"),
3574                     [(set VR128:$dst, (F64Int sse_load_f64:$src))], itins.rm>,
3575                 Sched<[itins.Sched.Folded]>;
3576 }
3577 }
3578
3579 /// sse2_fp_unop_p - SSE2 unops in vector forms.
3580 multiclass sse2_fp_unop_p<bits<8> opc, string OpcodeStr,
3581                           SDNode OpNode, OpndItins itins> {
3582 let Predicates = [HasAVX] in {
3583   def V#NAME#PDr : PDI<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3584                        !strconcat("v", OpcodeStr,
3585                                   "pd\t{$src, $dst|$dst, $src}"),
3586                        [(set VR128:$dst, (v2f64 (OpNode VR128:$src)))],
3587                        itins.rr>, VEX, Sched<[itins.Sched]>;
3588   def V#NAME#PDm : PDI<opc, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
3589                        !strconcat("v", OpcodeStr,
3590                                   "pd\t{$src, $dst|$dst, $src}"),
3591                        [(set VR128:$dst, (OpNode (loadv2f64 addr:$src)))],
3592                        itins.rm>, VEX, Sched<[itins.Sched.Folded]>;
3593   def V#NAME#PDYr : PDI<opc, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
3594                         !strconcat("v", OpcodeStr,
3595                                    "pd\t{$src, $dst|$dst, $src}"),
3596                         [(set VR256:$dst, (v4f64 (OpNode VR256:$src)))],
3597                         itins.rr>, VEX, VEX_L, Sched<[itins.Sched]>;
3598   def V#NAME#PDYm : PDI<opc, MRMSrcMem, (outs VR256:$dst), (ins f256mem:$src),
3599                         !strconcat("v", OpcodeStr,
3600                                    "pd\t{$src, $dst|$dst, $src}"),
3601                         [(set VR256:$dst, (OpNode (loadv4f64 addr:$src)))],
3602                         itins.rm>, VEX, VEX_L, Sched<[itins.Sched.Folded]>;
3603 }
3604
3605   def PDr : PDI<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3606               !strconcat(OpcodeStr, "pd\t{$src, $dst|$dst, $src}"),
3607               [(set VR128:$dst, (v2f64 (OpNode VR128:$src)))], itins.rr>,
3608             Sched<[itins.Sched]>;
3609   def PDm : PDI<opc, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
3610                 !strconcat(OpcodeStr, "pd\t{$src, $dst|$dst, $src}"),
3611                 [(set VR128:$dst, (OpNode (memopv2f64 addr:$src)))], itins.rm>,
3612             Sched<[itins.Sched.Folded]>;
3613 }
3614
3615 // Square root.
3616 defm SQRT  : sse1_fp_unop_s<0x51, "sqrt",  fsqrt, int_x86_sse_sqrt_ss,
3617                             SSE_SQRTSS>,
3618              sse1_fp_unop_p<0x51, "sqrt", fsqrt, SSE_SQRTPS>,
3619              sse2_fp_unop_s<0x51, "sqrt",  fsqrt, int_x86_sse2_sqrt_sd,
3620                             SSE_SQRTSD>,
3621              sse2_fp_unop_p<0x51, "sqrt", fsqrt, SSE_SQRTPD>;
3622
3623 // Reciprocal approximations. Note that these typically require refinement
3624 // in order to obtain suitable precision.
3625 defm RSQRT : sse1_fp_unop_rw<0x52, "rsqrt", X86frsqrt, SSE_SQRTSS>,
3626              sse1_fp_unop_p<0x52, "rsqrt", X86frsqrt, SSE_SQRTPS>,
3627              sse1_fp_unop_p_int<0x52, "rsqrt", int_x86_sse_rsqrt_ps,
3628                                 int_x86_avx_rsqrt_ps_256, SSE_SQRTPS>;
3629 defm RCP   : sse1_fp_unop_rw<0x53, "rcp", X86frcp, SSE_RCPS>,
3630              sse1_fp_unop_p<0x53, "rcp", X86frcp, SSE_RCPP>,
3631              sse1_fp_unop_p_int<0x53, "rcp", int_x86_sse_rcp_ps,
3632                                 int_x86_avx_rcp_ps_256, SSE_RCPP>;
3633
3634 let Predicates = [UseAVX] in {
3635   def : Pat<(f32 (fsqrt FR32:$src)),
3636             (VSQRTSSr (f32 (IMPLICIT_DEF)), FR32:$src)>, Requires<[HasAVX]>;
3637   def : Pat<(f32 (fsqrt (load addr:$src))),
3638             (VSQRTSSm (f32 (IMPLICIT_DEF)), addr:$src)>,
3639             Requires<[HasAVX, OptForSize]>;
3640   def : Pat<(f64 (fsqrt FR64:$src)),
3641             (VSQRTSDr (f64 (IMPLICIT_DEF)), FR64:$src)>, Requires<[HasAVX]>;
3642   def : Pat<(f64 (fsqrt (load addr:$src))),
3643             (VSQRTSDm (f64 (IMPLICIT_DEF)), addr:$src)>,
3644             Requires<[HasAVX, OptForSize]>;
3645
3646   def : Pat<(f32 (X86frsqrt FR32:$src)),
3647             (VRSQRTSSr (f32 (IMPLICIT_DEF)), FR32:$src)>, Requires<[HasAVX]>;
3648   def : Pat<(f32 (X86frsqrt (load addr:$src))),
3649             (VRSQRTSSm (f32 (IMPLICIT_DEF)), addr:$src)>,
3650             Requires<[HasAVX, OptForSize]>;
3651
3652   def : Pat<(f32 (X86frcp FR32:$src)),
3653             (VRCPSSr (f32 (IMPLICIT_DEF)), FR32:$src)>, Requires<[HasAVX]>;
3654   def : Pat<(f32 (X86frcp (load addr:$src))),
3655             (VRCPSSm (f32 (IMPLICIT_DEF)), addr:$src)>,
3656             Requires<[HasAVX, OptForSize]>;
3657 }
3658 let Predicates = [UseAVX] in {
3659   def : Pat<(int_x86_sse_sqrt_ss VR128:$src),
3660             (COPY_TO_REGCLASS (VSQRTSSr (f32 (IMPLICIT_DEF)),
3661                                         (COPY_TO_REGCLASS VR128:$src, FR32)),
3662                               VR128)>;
3663   def : Pat<(int_x86_sse_sqrt_ss sse_load_f32:$src),
3664             (VSQRTSSm_Int (v4f32 (IMPLICIT_DEF)), sse_load_f32:$src)>;
3665
3666   def : Pat<(int_x86_sse2_sqrt_sd VR128:$src),
3667             (COPY_TO_REGCLASS (VSQRTSDr (f64 (IMPLICIT_DEF)),
3668                                         (COPY_TO_REGCLASS VR128:$src, FR64)),
3669                               VR128)>;
3670   def : Pat<(int_x86_sse2_sqrt_sd sse_load_f64:$src),
3671             (VSQRTSDm_Int (v2f64 (IMPLICIT_DEF)), sse_load_f64:$src)>;
3672 }
3673
3674 let Predicates = [HasAVX] in {
3675   def : Pat<(int_x86_sse_rsqrt_ss VR128:$src),
3676             (COPY_TO_REGCLASS (VRSQRTSSr (f32 (IMPLICIT_DEF)),
3677                                          (COPY_TO_REGCLASS VR128:$src, FR32)),
3678                               VR128)>;
3679   def : Pat<(int_x86_sse_rsqrt_ss sse_load_f32:$src),
3680             (VRSQRTSSm_Int (v4f32 (IMPLICIT_DEF)), sse_load_f32:$src)>;
3681
3682   def : Pat<(int_x86_sse_rcp_ss VR128:$src),
3683             (COPY_TO_REGCLASS (VRCPSSr (f32 (IMPLICIT_DEF)),
3684                                        (COPY_TO_REGCLASS VR128:$src, FR32)),
3685                               VR128)>;
3686   def : Pat<(int_x86_sse_rcp_ss sse_load_f32:$src),
3687             (VRCPSSm_Int (v4f32 (IMPLICIT_DEF)), sse_load_f32:$src)>;
3688 }
3689
3690 // Reciprocal approximations. Note that these typically require refinement
3691 // in order to obtain suitable precision.
3692 let Predicates = [UseSSE1] in {
3693   def : Pat<(int_x86_sse_rsqrt_ss VR128:$src),
3694             (RSQRTSSr_Int VR128:$src, VR128:$src)>;
3695   def : Pat<(int_x86_sse_rcp_ss VR128:$src),
3696             (RCPSSr_Int VR128:$src, VR128:$src)>;
3697 }
3698
3699 // There is no f64 version of the reciprocal approximation instructions.
3700
3701 //===----------------------------------------------------------------------===//
3702 // SSE 1 & 2 - Non-temporal stores
3703 //===----------------------------------------------------------------------===//
3704
3705 let AddedComplexity = 400 in { // Prefer non-temporal versions
3706 let SchedRW = [WriteStore] in {
3707 let Predicates = [HasAVX, NoVLX] in {
3708 def VMOVNTPSmr : VPSI<0x2B, MRMDestMem, (outs),
3709                      (ins f128mem:$dst, VR128:$src),
3710                      "movntps\t{$src, $dst|$dst, $src}",
3711                      [(alignednontemporalstore (v4f32 VR128:$src),
3712                                                addr:$dst)],
3713                                                IIC_SSE_MOVNT>, VEX;
3714 def VMOVNTPDmr : VPDI<0x2B, MRMDestMem, (outs),
3715                      (ins f128mem:$dst, VR128:$src),
3716                      "movntpd\t{$src, $dst|$dst, $src}",
3717                      [(alignednontemporalstore (v2f64 VR128:$src),
3718                                                addr:$dst)],
3719                                                IIC_SSE_MOVNT>, VEX;
3720
3721 let ExeDomain = SSEPackedInt in
3722 def VMOVNTDQmr    : VPDI<0xE7, MRMDestMem, (outs),
3723                          (ins f128mem:$dst, VR128:$src),
3724                          "movntdq\t{$src, $dst|$dst, $src}",
3725                          [(alignednontemporalstore (v2i64 VR128:$src),
3726                                                    addr:$dst)],
3727                                                    IIC_SSE_MOVNT>, VEX;
3728
3729 def VMOVNTPSYmr : VPSI<0x2B, MRMDestMem, (outs),
3730                      (ins f256mem:$dst, VR256:$src),
3731                      "movntps\t{$src, $dst|$dst, $src}",
3732                      [(alignednontemporalstore (v8f32 VR256:$src),
3733                                                addr:$dst)],
3734                                                IIC_SSE_MOVNT>, VEX, VEX_L;
3735 def VMOVNTPDYmr : VPDI<0x2B, MRMDestMem, (outs),
3736                      (ins f256mem:$dst, VR256:$src),
3737                      "movntpd\t{$src, $dst|$dst, $src}",
3738                      [(alignednontemporalstore (v4f64 VR256:$src),
3739                                                addr:$dst)],
3740                                                IIC_SSE_MOVNT>, VEX, VEX_L;
3741 let ExeDomain = SSEPackedInt in
3742 def VMOVNTDQYmr : VPDI<0xE7, MRMDestMem, (outs),
3743                     (ins f256mem:$dst, VR256:$src),
3744                     "movntdq\t{$src, $dst|$dst, $src}",
3745                     [(alignednontemporalstore (v4i64 VR256:$src),
3746                                               addr:$dst)],
3747                                               IIC_SSE_MOVNT>, VEX, VEX_L;
3748 }
3749
3750 def MOVNTPSmr : PSI<0x2B, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
3751                     "movntps\t{$src, $dst|$dst, $src}",
3752                     [(alignednontemporalstore (v4f32 VR128:$src), addr:$dst)],
3753                     IIC_SSE_MOVNT>;
3754 def MOVNTPDmr : PDI<0x2B, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
3755                     "movntpd\t{$src, $dst|$dst, $src}",
3756                     [(alignednontemporalstore(v2f64 VR128:$src), addr:$dst)],
3757                     IIC_SSE_MOVNT>;
3758
3759 let ExeDomain = SSEPackedInt in
3760 def MOVNTDQmr : PDI<0xE7, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
3761                     "movntdq\t{$src, $dst|$dst, $src}",
3762                     [(alignednontemporalstore (v2i64 VR128:$src), addr:$dst)],
3763                     IIC_SSE_MOVNT>;
3764
3765 // There is no AVX form for instructions below this point
3766 def MOVNTImr : I<0xC3, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
3767                  "movnti{l}\t{$src, $dst|$dst, $src}",
3768                  [(nontemporalstore (i32 GR32:$src), addr:$dst)],
3769                  IIC_SSE_MOVNT>,
3770                PS, Requires<[HasSSE2]>;
3771 def MOVNTI_64mr : RI<0xC3, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
3772                      "movnti{q}\t{$src, $dst|$dst, $src}",
3773                      [(nontemporalstore (i64 GR64:$src), addr:$dst)],
3774                      IIC_SSE_MOVNT>,
3775                   PS, Requires<[HasSSE2]>;
3776 } // SchedRW = [WriteStore]
3777
3778 } // AddedComplexity
3779
3780 //===----------------------------------------------------------------------===//
3781 // SSE 1 & 2 - Prefetch and memory fence
3782 //===----------------------------------------------------------------------===//
3783
3784 // Prefetch intrinsic.
3785 let Predicates = [HasSSE1], SchedRW = [WriteLoad] in {
3786 def PREFETCHT0   : I<0x18, MRM1m, (outs), (ins i8mem:$src),
3787     "prefetcht0\t$src", [(prefetch addr:$src, imm, (i32 3), (i32 1))],
3788     IIC_SSE_PREFETCH>, TB;
3789 def PREFETCHT1   : I<0x18, MRM2m, (outs), (ins i8mem:$src),
3790     "prefetcht1\t$src", [(prefetch addr:$src, imm, (i32 2), (i32 1))],
3791     IIC_SSE_PREFETCH>, TB;
3792 def PREFETCHT2   : I<0x18, MRM3m, (outs), (ins i8mem:$src),
3793     "prefetcht2\t$src", [(prefetch addr:$src, imm, (i32 1), (i32 1))],
3794     IIC_SSE_PREFETCH>, TB;
3795 def PREFETCHNTA  : I<0x18, MRM0m, (outs), (ins i8mem:$src),
3796     "prefetchnta\t$src", [(prefetch addr:$src, imm, (i32 0), (i32 1))],
3797     IIC_SSE_PREFETCH>, TB;
3798 }
3799
3800 // FIXME: How should flush instruction be modeled?
3801 let SchedRW = [WriteLoad] in {
3802 // Flush cache
3803 def CLFLUSH : I<0xAE, MRM7m, (outs), (ins i8mem:$src),
3804                "clflush\t$src", [(int_x86_sse2_clflush addr:$src)],
3805                IIC_SSE_PREFETCH>, TB, Requires<[HasSSE2]>;
3806 }
3807
3808 let SchedRW = [WriteNop] in {
3809 // Pause. This "instruction" is encoded as "rep; nop", so even though it
3810 // was introduced with SSE2, it's backward compatible.
3811 def PAUSE : I<0x90, RawFrm, (outs), (ins),  
3812               "pause", [(int_x86_sse2_pause)], IIC_SSE_PAUSE>, 
3813               OBXS, Requires<[HasSSE2]>;
3814 }
3815
3816 let SchedRW = [WriteFence] in {
3817 // Load, store, and memory fence
3818 def SFENCE : I<0xAE, MRM_F8, (outs), (ins),
3819                "sfence", [(int_x86_sse_sfence)], IIC_SSE_SFENCE>,
3820                TB, Requires<[HasSSE1]>;
3821 def LFENCE : I<0xAE, MRM_E8, (outs), (ins),
3822                "lfence", [(int_x86_sse2_lfence)], IIC_SSE_LFENCE>,
3823                TB, Requires<[HasSSE2]>;
3824 def MFENCE : I<0xAE, MRM_F0, (outs), (ins),
3825                "mfence", [(int_x86_sse2_mfence)], IIC_SSE_MFENCE>,
3826                TB, Requires<[HasSSE2]>;
3827 } // SchedRW
3828
3829 def : Pat<(X86SFence), (SFENCE)>;
3830 def : Pat<(X86LFence), (LFENCE)>;
3831 def : Pat<(X86MFence), (MFENCE)>;
3832
3833 //===----------------------------------------------------------------------===//
3834 // SSE 1 & 2 - Load/Store XCSR register
3835 //===----------------------------------------------------------------------===//
3836
3837 def VLDMXCSR : VPSI<0xAE, MRM2m, (outs), (ins i32mem:$src),
3838                   "ldmxcsr\t$src", [(int_x86_sse_ldmxcsr addr:$src)],
3839                   IIC_SSE_LDMXCSR>, VEX, Sched<[WriteLoad]>;
3840 def VSTMXCSR : VPSI<0xAE, MRM3m, (outs), (ins i32mem:$dst),
3841                   "stmxcsr\t$dst", [(int_x86_sse_stmxcsr addr:$dst)],
3842                   IIC_SSE_STMXCSR>, VEX, Sched<[WriteStore]>;
3843
3844 def LDMXCSR : PSI<0xAE, MRM2m, (outs), (ins i32mem:$src),
3845                   "ldmxcsr\t$src", [(int_x86_sse_ldmxcsr addr:$src)],
3846                   IIC_SSE_LDMXCSR>, Sched<[WriteLoad]>;
3847 def STMXCSR : PSI<0xAE, MRM3m, (outs), (ins i32mem:$dst),
3848                   "stmxcsr\t$dst", [(int_x86_sse_stmxcsr addr:$dst)],
3849                   IIC_SSE_STMXCSR>, Sched<[WriteStore]>;
3850
3851 //===---------------------------------------------------------------------===//
3852 // SSE2 - Move Aligned/Unaligned Packed Integer Instructions
3853 //===---------------------------------------------------------------------===//
3854
3855 let ExeDomain = SSEPackedInt in { // SSE integer instructions
3856
3857 let neverHasSideEffects = 1, SchedRW = [WriteMove] in {
3858 def VMOVDQArr  : VPDI<0x6F, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3859                     "movdqa\t{$src, $dst|$dst, $src}", [], IIC_SSE_MOVA_P_RR>,
3860                     VEX;
3861 def VMOVDQAYrr : VPDI<0x6F, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
3862                     "movdqa\t{$src, $dst|$dst, $src}", [], IIC_SSE_MOVA_P_RR>,
3863                     VEX, VEX_L;
3864 def VMOVDQUrr  : VSSI<0x6F, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3865                     "movdqu\t{$src, $dst|$dst, $src}", [], IIC_SSE_MOVU_P_RR>,
3866                     VEX;
3867 def VMOVDQUYrr : VSSI<0x6F, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
3868                     "movdqu\t{$src, $dst|$dst, $src}", [], IIC_SSE_MOVU_P_RR>,
3869                     VEX, VEX_L;
3870 }
3871
3872 // For Disassembler
3873 let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0,
3874     SchedRW = [WriteMove] in {
3875 def VMOVDQArr_REV  : VPDI<0x7F, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
3876                         "movdqa\t{$src, $dst|$dst, $src}", [],
3877                         IIC_SSE_MOVA_P_RR>,
3878                         VEX;
3879 def VMOVDQAYrr_REV : VPDI<0x7F, MRMDestReg, (outs VR256:$dst), (ins VR256:$src),
3880                         "movdqa\t{$src, $dst|$dst, $src}", [],
3881                         IIC_SSE_MOVA_P_RR>, VEX, VEX_L;
3882 def VMOVDQUrr_REV  : VSSI<0x7F, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
3883                         "movdqu\t{$src, $dst|$dst, $src}", [],
3884                         IIC_SSE_MOVU_P_RR>,
3885                         VEX;
3886 def VMOVDQUYrr_REV : VSSI<0x7F, MRMDestReg, (outs VR256:$dst), (ins VR256:$src),
3887                         "movdqu\t{$src, $dst|$dst, $src}", [],
3888                         IIC_SSE_MOVU_P_RR>, VEX, VEX_L;
3889 }
3890
3891 let canFoldAsLoad = 1, mayLoad = 1, isReMaterializable = 1,
3892     neverHasSideEffects = 1, SchedRW = [WriteLoad] in {
3893 def VMOVDQArm  : VPDI<0x6F, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
3894                    "movdqa\t{$src, $dst|$dst, $src}", [], IIC_SSE_MOVA_P_RM>,
3895                    VEX;
3896 def VMOVDQAYrm : VPDI<0x6F, MRMSrcMem, (outs VR256:$dst), (ins i256mem:$src),
3897                    "movdqa\t{$src, $dst|$dst, $src}", [], IIC_SSE_MOVA_P_RM>,
3898                    VEX, VEX_L;
3899 let Predicates = [HasAVX] in {
3900   def VMOVDQUrm  : I<0x6F, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
3901                     "vmovdqu\t{$src, $dst|$dst, $src}",[], IIC_SSE_MOVU_P_RM>,
3902                     XS, VEX;
3903   def VMOVDQUYrm : I<0x6F, MRMSrcMem, (outs VR256:$dst), (ins i256mem:$src),
3904                     "vmovdqu\t{$src, $dst|$dst, $src}",[], IIC_SSE_MOVU_P_RM>,
3905                     XS, VEX, VEX_L;
3906 }
3907 }
3908
3909 let mayStore = 1, neverHasSideEffects = 1, SchedRW = [WriteStore] in {
3910 def VMOVDQAmr  : VPDI<0x7F, MRMDestMem, (outs),
3911                      (ins i128mem:$dst, VR128:$src),
3912                      "movdqa\t{$src, $dst|$dst, $src}", [], IIC_SSE_MOVA_P_MR>,
3913                      VEX;
3914 def VMOVDQAYmr : VPDI<0x7F, MRMDestMem, (outs),
3915                      (ins i256mem:$dst, VR256:$src),
3916                      "movdqa\t{$src, $dst|$dst, $src}", [], IIC_SSE_MOVA_P_MR>,
3917                      VEX, VEX_L;
3918 let Predicates = [HasAVX] in {
3919 def VMOVDQUmr  : I<0x7F, MRMDestMem, (outs), (ins i128mem:$dst, VR128:$src),
3920                   "vmovdqu\t{$src, $dst|$dst, $src}",[], IIC_SSE_MOVU_P_MR>,
3921                   XS, VEX;
3922 def VMOVDQUYmr : I<0x7F, MRMDestMem, (outs), (ins i256mem:$dst, VR256:$src),
3923                   "vmovdqu\t{$src, $dst|$dst, $src}",[], IIC_SSE_MOVU_P_MR>,
3924                   XS, VEX, VEX_L;
3925 }
3926 }
3927
3928 let SchedRW = [WriteMove] in {
3929 let neverHasSideEffects = 1 in
3930 def MOVDQArr : PDI<0x6F, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3931                    "movdqa\t{$src, $dst|$dst, $src}", [], IIC_SSE_MOVA_P_RR>;
3932
3933 def MOVDQUrr :   I<0x6F, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3934                    "movdqu\t{$src, $dst|$dst, $src}",
3935                    [], IIC_SSE_MOVU_P_RR>, XS, Requires<[UseSSE2]>;
3936
3937 // For Disassembler
3938 let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0 in {
3939 def MOVDQArr_REV : PDI<0x7F, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
3940                        "movdqa\t{$src, $dst|$dst, $src}", [],
3941                        IIC_SSE_MOVA_P_RR>;
3942
3943 def MOVDQUrr_REV :   I<0x7F, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
3944                        "movdqu\t{$src, $dst|$dst, $src}",
3945                        [], IIC_SSE_MOVU_P_RR>, XS, Requires<[UseSSE2]>;
3946 }
3947 } // SchedRW
3948
3949 let canFoldAsLoad = 1, mayLoad = 1, isReMaterializable = 1,
3950     neverHasSideEffects = 1, SchedRW = [WriteLoad] in {
3951 def MOVDQArm : PDI<0x6F, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
3952                    "movdqa\t{$src, $dst|$dst, $src}",
3953                    [/*(set VR128:$dst, (alignedloadv2i64 addr:$src))*/],
3954                    IIC_SSE_MOVA_P_RM>;
3955 def MOVDQUrm :   I<0x6F, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
3956                    "movdqu\t{$src, $dst|$dst, $src}",
3957                    [/*(set VR128:$dst, (loadv2i64 addr:$src))*/],
3958                    IIC_SSE_MOVU_P_RM>,
3959                  XS, Requires<[UseSSE2]>;
3960 }
3961
3962 let mayStore = 1, neverHasSideEffects = 1, SchedRW = [WriteStore] in {
3963 def MOVDQAmr : PDI<0x7F, MRMDestMem, (outs), (ins i128mem:$dst, VR128:$src),
3964                    "movdqa\t{$src, $dst|$dst, $src}",
3965                    [/*(alignedstore (v2i64 VR128:$src), addr:$dst)*/],
3966                    IIC_SSE_MOVA_P_MR>;
3967 def MOVDQUmr :   I<0x7F, MRMDestMem, (outs), (ins i128mem:$dst, VR128:$src),
3968                    "movdqu\t{$src, $dst|$dst, $src}",
3969                    [/*(store (v2i64 VR128:$src), addr:$dst)*/],
3970                    IIC_SSE_MOVU_P_MR>,
3971                  XS, Requires<[UseSSE2]>;
3972 }
3973
3974 } // ExeDomain = SSEPackedInt
3975
3976 let Predicates = [HasAVX] in {
3977   def : Pat<(int_x86_sse2_storeu_dq addr:$dst, VR128:$src),
3978             (VMOVDQUmr addr:$dst, VR128:$src)>;
3979   def : Pat<(int_x86_avx_storeu_dq_256 addr:$dst, VR256:$src),
3980             (VMOVDQUYmr addr:$dst, VR256:$src)>;
3981 }
3982 let Predicates = [UseSSE2] in
3983 def : Pat<(int_x86_sse2_storeu_dq addr:$dst, VR128:$src),
3984           (MOVDQUmr addr:$dst, VR128:$src)>;
3985
3986 //===---------------------------------------------------------------------===//
3987 // SSE2 - Packed Integer Arithmetic Instructions
3988 //===---------------------------------------------------------------------===//
3989
3990 let Sched = WriteVecIMul in
3991 def SSE_PMADD : OpndItins<
3992   IIC_SSE_PMADD, IIC_SSE_PMADD
3993 >;
3994
3995 let ExeDomain = SSEPackedInt in { // SSE integer instructions
3996
3997 multiclass PDI_binop_rm_int<bits<8> opc, string OpcodeStr, Intrinsic IntId,
3998                             RegisterClass RC, PatFrag memop_frag,
3999                             X86MemOperand x86memop,
4000                             OpndItins itins,
4001                             bit IsCommutable = 0,
4002                             bit Is2Addr = 1> {
4003   let isCommutable = IsCommutable in
4004   def rr : PDI<opc, MRMSrcReg, (outs RC:$dst),
4005        (ins RC:$src1, RC:$src2),
4006        !if(Is2Addr,
4007            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
4008            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
4009        [(set RC:$dst, (IntId RC:$src1, RC:$src2))], itins.rr>,
4010       Sched<[itins.Sched]>;
4011   def rm : PDI<opc, MRMSrcMem, (outs RC:$dst),
4012        (ins RC:$src1, x86memop:$src2),
4013        !if(Is2Addr,
4014            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
4015            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
4016        [(set RC:$dst, (IntId RC:$src1, (bitconvert (memop_frag addr:$src2))))],
4017        itins.rm>, Sched<[itins.Sched.Folded, ReadAfterLd]>;
4018 }
4019
4020 multiclass PDI_binop_all_int<bits<8> opc, string OpcodeStr, Intrinsic IntId128,
4021                              Intrinsic IntId256, OpndItins itins,
4022                              bit IsCommutable = 0> {
4023 let Predicates = [HasAVX] in
4024   defm V#NAME : PDI_binop_rm_int<opc, !strconcat("v", OpcodeStr), IntId128,
4025                                  VR128, loadv2i64, i128mem, itins,
4026                                  IsCommutable, 0>, VEX_4V;
4027
4028 let Constraints = "$src1 = $dst" in
4029   defm NAME : PDI_binop_rm_int<opc, OpcodeStr, IntId128, VR128, memopv2i64,
4030                                i128mem, itins, IsCommutable, 1>;
4031
4032 let Predicates = [HasAVX2] in
4033   defm V#NAME#Y : PDI_binop_rm_int<opc, !strconcat("v", OpcodeStr), IntId256,
4034                                    VR256, loadv4i64, i256mem, itins,
4035                                    IsCommutable, 0>, VEX_4V, VEX_L;
4036 }
4037
4038 multiclass PDI_binop_rmi<bits<8> opc, bits<8> opc2, Format ImmForm,
4039                          string OpcodeStr, SDNode OpNode,
4040                          SDNode OpNode2, RegisterClass RC,
4041                          ValueType DstVT, ValueType SrcVT, PatFrag bc_frag,
4042                          ShiftOpndItins itins,
4043                          bit Is2Addr = 1> {
4044   // src2 is always 128-bit
4045   def rr : PDI<opc, MRMSrcReg, (outs RC:$dst),
4046        (ins RC:$src1, VR128:$src2),
4047        !if(Is2Addr,
4048            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
4049            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
4050        [(set RC:$dst, (DstVT (OpNode RC:$src1, (SrcVT VR128:$src2))))],
4051         itins.rr>, Sched<[WriteVecShift]>;
4052   def rm : PDI<opc, MRMSrcMem, (outs RC:$dst),
4053        (ins RC:$src1, i128mem:$src2),
4054        !if(Is2Addr,
4055            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
4056            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
4057        [(set RC:$dst, (DstVT (OpNode RC:$src1,
4058                        (bc_frag (memopv2i64 addr:$src2)))))], itins.rm>,
4059       Sched<[WriteVecShiftLd, ReadAfterLd]>;
4060   def ri : PDIi8<opc2, ImmForm, (outs RC:$dst),
4061        (ins RC:$src1, i8imm:$src2),
4062        !if(Is2Addr,
4063            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
4064            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
4065        [(set RC:$dst, (DstVT (OpNode2 RC:$src1, (i8 imm:$src2))))], itins.ri>,
4066        Sched<[WriteVecShift]>;
4067 }
4068
4069 /// PDI_binop_rm2 - Simple SSE2 binary operator with different src and dst types
4070 multiclass PDI_binop_rm2<bits<8> opc, string OpcodeStr, SDNode OpNode,
4071                          ValueType DstVT, ValueType SrcVT, RegisterClass RC,
4072                          PatFrag memop_frag, X86MemOperand x86memop,
4073                          OpndItins itins,
4074                          bit IsCommutable = 0, bit Is2Addr = 1> {
4075   let isCommutable = IsCommutable in
4076   def rr : PDI<opc, MRMSrcReg, (outs RC:$dst),
4077        (ins RC:$src1, RC:$src2),
4078        !if(Is2Addr,
4079            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
4080            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
4081        [(set RC:$dst, (DstVT (OpNode (SrcVT RC:$src1), RC:$src2)))]>,
4082        Sched<[itins.Sched]>;
4083   def rm : PDI<opc, MRMSrcMem, (outs RC:$dst),
4084        (ins RC:$src1, x86memop:$src2),
4085        !if(Is2Addr,
4086            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
4087            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
4088        [(set RC:$dst, (DstVT (OpNode (SrcVT RC:$src1),
4089                                      (bitconvert (memop_frag addr:$src2)))))]>,
4090        Sched<[itins.Sched.Folded, ReadAfterLd]>;
4091 }
4092 } // ExeDomain = SSEPackedInt
4093
4094 defm PADDB   : PDI_binop_all<0xFC, "paddb", add, v16i8, v32i8,
4095                              SSE_INTALU_ITINS_P, 1>;
4096 defm PADDW   : PDI_binop_all<0xFD, "paddw", add, v8i16, v16i16,
4097                              SSE_INTALU_ITINS_P, 1>;
4098 defm PADDD   : PDI_binop_all<0xFE, "paddd", add, v4i32, v8i32,
4099                              SSE_INTALU_ITINS_P, 1>;
4100 defm PADDQ   : PDI_binop_all<0xD4, "paddq", add, v2i64, v4i64,
4101                              SSE_INTALUQ_ITINS_P, 1>;
4102 defm PMULLW  : PDI_binop_all<0xD5, "pmullw", mul, v8i16, v16i16,
4103                              SSE_INTMUL_ITINS_P, 1>;
4104 defm PMULHUW : PDI_binop_all<0xE4, "pmulhuw", mulhu, v8i16, v16i16,
4105                              SSE_INTMUL_ITINS_P, 1>;
4106 defm PMULHW  : PDI_binop_all<0xE5, "pmulhw", mulhs, v8i16, v16i16,
4107                              SSE_INTMUL_ITINS_P, 1>;
4108 defm PSUBB   : PDI_binop_all<0xF8, "psubb", sub, v16i8, v32i8,
4109                              SSE_INTALU_ITINS_P, 0>;
4110 defm PSUBW   : PDI_binop_all<0xF9, "psubw", sub, v8i16, v16i16,
4111                              SSE_INTALU_ITINS_P, 0>;
4112 defm PSUBD   : PDI_binop_all<0xFA, "psubd", sub, v4i32, v8i32,
4113                              SSE_INTALU_ITINS_P, 0>;
4114 defm PSUBQ   : PDI_binop_all<0xFB, "psubq", sub, v2i64, v4i64,
4115                              SSE_INTALUQ_ITINS_P, 0>;
4116 defm PSUBUSB : PDI_binop_all<0xD8, "psubusb", X86subus, v16i8, v32i8,
4117                              SSE_INTALU_ITINS_P, 0>;
4118 defm PSUBUSW : PDI_binop_all<0xD9, "psubusw", X86subus, v8i16, v16i16,
4119                              SSE_INTALU_ITINS_P, 0>;
4120 defm PMINUB  : PDI_binop_all<0xDA, "pminub", X86umin, v16i8, v32i8,
4121                              SSE_INTALU_ITINS_P, 1>;
4122 defm PMINSW  : PDI_binop_all<0xEA, "pminsw", X86smin, v8i16, v16i16,
4123                              SSE_INTALU_ITINS_P, 1>;
4124 defm PMAXUB  : PDI_binop_all<0xDE, "pmaxub", X86umax, v16i8, v32i8,
4125                              SSE_INTALU_ITINS_P, 1>;
4126 defm PMAXSW  : PDI_binop_all<0xEE, "pmaxsw", X86smax, v8i16, v16i16,
4127                              SSE_INTALU_ITINS_P, 1>;
4128
4129 // Intrinsic forms
4130 defm PSUBSB  : PDI_binop_all_int<0xE8, "psubsb", int_x86_sse2_psubs_b,
4131                                  int_x86_avx2_psubs_b, SSE_INTALU_ITINS_P, 0>;
4132 defm PSUBSW  : PDI_binop_all_int<0xE9, "psubsw" , int_x86_sse2_psubs_w,
4133                                  int_x86_avx2_psubs_w, SSE_INTALU_ITINS_P, 0>;
4134 defm PADDSB  : PDI_binop_all_int<0xEC, "paddsb" , int_x86_sse2_padds_b,
4135                                  int_x86_avx2_padds_b, SSE_INTALU_ITINS_P, 1>;
4136 defm PADDSW  : PDI_binop_all_int<0xED, "paddsw" , int_x86_sse2_padds_w,
4137                                  int_x86_avx2_padds_w, SSE_INTALU_ITINS_P, 1>;
4138 defm PADDUSB : PDI_binop_all_int<0xDC, "paddusb", int_x86_sse2_paddus_b,
4139                                  int_x86_avx2_paddus_b, SSE_INTALU_ITINS_P, 1>;
4140 defm PADDUSW : PDI_binop_all_int<0xDD, "paddusw", int_x86_sse2_paddus_w,
4141                                  int_x86_avx2_paddus_w, SSE_INTALU_ITINS_P, 1>;
4142 defm PMADDWD : PDI_binop_all_int<0xF5, "pmaddwd", int_x86_sse2_pmadd_wd,
4143                                  int_x86_avx2_pmadd_wd, SSE_PMADD, 1>;
4144 defm PAVGB   : PDI_binop_all_int<0xE0, "pavgb", int_x86_sse2_pavg_b,
4145                                  int_x86_avx2_pavg_b, SSE_INTALU_ITINS_P, 1>;
4146 defm PAVGW   : PDI_binop_all_int<0xE3, "pavgw", int_x86_sse2_pavg_w,
4147                                  int_x86_avx2_pavg_w, SSE_INTALU_ITINS_P, 1>;
4148 defm PSADBW  : PDI_binop_all_int<0xF6, "psadbw", int_x86_sse2_psad_bw,
4149                                  int_x86_avx2_psad_bw, SSE_PMADD, 1>;
4150
4151 let Predicates = [HasAVX] in
4152 defm VPMULUDQ : PDI_binop_rm2<0xF4, "vpmuludq", X86pmuludq, v2i64, v4i32, VR128,
4153                               loadv2i64, i128mem, SSE_INTMUL_ITINS_P, 1, 0>,
4154                               VEX_4V;
4155 let Predicates = [HasAVX2] in
4156 defm VPMULUDQY : PDI_binop_rm2<0xF4, "vpmuludq", X86pmuludq, v4i64, v8i32,
4157                                VR256, loadv4i64, i256mem,
4158                                SSE_INTMUL_ITINS_P, 1, 0>, VEX_4V, VEX_L;
4159 let Constraints = "$src1 = $dst" in
4160 defm PMULUDQ : PDI_binop_rm2<0xF4, "pmuludq", X86pmuludq, v2i64, v4i32, VR128,
4161                              memopv2i64, i128mem, SSE_INTMUL_ITINS_P, 1>;
4162
4163 //===---------------------------------------------------------------------===//
4164 // SSE2 - Packed Integer Logical Instructions
4165 //===---------------------------------------------------------------------===//
4166
4167 let Predicates = [HasAVX] in {
4168 defm VPSLLW : PDI_binop_rmi<0xF1, 0x71, MRM6r, "vpsllw", X86vshl, X86vshli,
4169                             VR128, v8i16, v8i16, bc_v8i16,
4170                             SSE_INTSHIFT_ITINS_P, 0>, VEX_4V;
4171 defm VPSLLD : PDI_binop_rmi<0xF2, 0x72, MRM6r, "vpslld", X86vshl, X86vshli,
4172                             VR128, v4i32, v4i32, bc_v4i32,
4173                             SSE_INTSHIFT_ITINS_P, 0>, VEX_4V;
4174 defm VPSLLQ : PDI_binop_rmi<0xF3, 0x73, MRM6r, "vpsllq", X86vshl, X86vshli,
4175                             VR128, v2i64, v2i64, bc_v2i64,
4176                             SSE_INTSHIFT_ITINS_P, 0>, VEX_4V;
4177
4178 defm VPSRLW : PDI_binop_rmi<0xD1, 0x71, MRM2r, "vpsrlw", X86vsrl, X86vsrli,
4179                             VR128, v8i16, v8i16, bc_v8i16,
4180                             SSE_INTSHIFT_ITINS_P, 0>, VEX_4V;
4181 defm VPSRLD : PDI_binop_rmi<0xD2, 0x72, MRM2r, "vpsrld", X86vsrl, X86vsrli,
4182                             VR128, v4i32, v4i32, bc_v4i32,
4183                             SSE_INTSHIFT_ITINS_P, 0>, VEX_4V;
4184 defm VPSRLQ : PDI_binop_rmi<0xD3, 0x73, MRM2r, "vpsrlq", X86vsrl, X86vsrli,
4185                             VR128, v2i64, v2i64, bc_v2i64,
4186                             SSE_INTSHIFT_ITINS_P, 0>, VEX_4V;
4187
4188 defm VPSRAW : PDI_binop_rmi<0xE1, 0x71, MRM4r, "vpsraw", X86vsra, X86vsrai,
4189                             VR128, v8i16, v8i16, bc_v8i16,
4190                             SSE_INTSHIFT_ITINS_P, 0>, VEX_4V;
4191 defm VPSRAD : PDI_binop_rmi<0xE2, 0x72, MRM4r, "vpsrad", X86vsra, X86vsrai,
4192                             VR128, v4i32, v4i32, bc_v4i32,
4193                             SSE_INTSHIFT_ITINS_P, 0>, VEX_4V;
4194
4195 let ExeDomain = SSEPackedInt, SchedRW = [WriteVecShift] in {
4196   // 128-bit logical shifts.
4197   def VPSLLDQri : PDIi8<0x73, MRM7r,
4198                     (outs VR128:$dst), (ins VR128:$src1, i32i8imm:$src2),
4199                     "vpslldq\t{$src2, $src1, $dst|$dst, $src1, $src2}",
4200                     [(set VR128:$dst,
4201                       (int_x86_sse2_psll_dq_bs VR128:$src1, imm:$src2))]>,
4202                     VEX_4V;
4203   def VPSRLDQri : PDIi8<0x73, MRM3r,
4204                     (outs VR128:$dst), (ins VR128:$src1, i32i8imm:$src2),
4205                     "vpsrldq\t{$src2, $src1, $dst|$dst, $src1, $src2}",
4206                     [(set VR128:$dst,
4207                       (int_x86_sse2_psrl_dq_bs VR128:$src1, imm:$src2))]>,
4208                     VEX_4V;
4209   // PSRADQri doesn't exist in SSE[1-3].
4210 }
4211 } // Predicates = [HasAVX]
4212
4213 let Predicates = [HasAVX2] in {
4214 defm VPSLLWY : PDI_binop_rmi<0xF1, 0x71, MRM6r, "vpsllw", X86vshl, X86vshli,
4215                              VR256, v16i16, v8i16, bc_v8i16,
4216                              SSE_INTSHIFT_ITINS_P, 0>, VEX_4V, VEX_L;
4217 defm VPSLLDY : PDI_binop_rmi<0xF2, 0x72, MRM6r, "vpslld", X86vshl, X86vshli,
4218                              VR256, v8i32, v4i32, bc_v4i32,
4219                              SSE_INTSHIFT_ITINS_P, 0>, VEX_4V, VEX_L;
4220 defm VPSLLQY : PDI_binop_rmi<0xF3, 0x73, MRM6r, "vpsllq", X86vshl, X86vshli,
4221                              VR256, v4i64, v2i64, bc_v2i64,
4222                              SSE_INTSHIFT_ITINS_P, 0>, VEX_4V, VEX_L;
4223
4224 defm VPSRLWY : PDI_binop_rmi<0xD1, 0x71, MRM2r, "vpsrlw", X86vsrl, X86vsrli,
4225                              VR256, v16i16, v8i16, bc_v8i16,
4226                              SSE_INTSHIFT_ITINS_P, 0>, VEX_4V, VEX_L;
4227 defm VPSRLDY : PDI_binop_rmi<0xD2, 0x72, MRM2r, "vpsrld", X86vsrl, X86vsrli,
4228                              VR256, v8i32, v4i32, bc_v4i32,
4229                              SSE_INTSHIFT_ITINS_P, 0>, VEX_4V, VEX_L;
4230 defm VPSRLQY : PDI_binop_rmi<0xD3, 0x73, MRM2r, "vpsrlq", X86vsrl, X86vsrli,
4231                              VR256, v4i64, v2i64, bc_v2i64,
4232                              SSE_INTSHIFT_ITINS_P, 0>, VEX_4V, VEX_L;
4233
4234 defm VPSRAWY : PDI_binop_rmi<0xE1, 0x71, MRM4r, "vpsraw", X86vsra, X86vsrai,
4235                              VR256, v16i16, v8i16, bc_v8i16,
4236                              SSE_INTSHIFT_ITINS_P, 0>, VEX_4V, VEX_L;
4237 defm VPSRADY : PDI_binop_rmi<0xE2, 0x72, MRM4r, "vpsrad", X86vsra, X86vsrai,
4238                              VR256, v8i32, v4i32, bc_v4i32,
4239                              SSE_INTSHIFT_ITINS_P, 0>, VEX_4V, VEX_L;
4240
4241 let ExeDomain = SSEPackedInt, SchedRW = [WriteVecShift] in {
4242   // 256-bit logical shifts.
4243   def VPSLLDQYri : PDIi8<0x73, MRM7r,
4244                     (outs VR256:$dst), (ins VR256:$src1, i32i8imm:$src2),
4245                     "vpslldq\t{$src2, $src1, $dst|$dst, $src1, $src2}",
4246                     [(set VR256:$dst,
4247                       (int_x86_avx2_psll_dq_bs VR256:$src1, imm:$src2))]>,
4248                     VEX_4V, VEX_L;
4249   def VPSRLDQYri : PDIi8<0x73, MRM3r,
4250                     (outs VR256:$dst), (ins VR256:$src1, i32i8imm:$src2),
4251                     "vpsrldq\t{$src2, $src1, $dst|$dst, $src1, $src2}",
4252                     [(set VR256:$dst,
4253                       (int_x86_avx2_psrl_dq_bs VR256:$src1, imm:$src2))]>,
4254                     VEX_4V, VEX_L;
4255   // PSRADQYri doesn't exist in SSE[1-3].
4256 }
4257 } // Predicates = [HasAVX2]
4258
4259 let Constraints = "$src1 = $dst" in {
4260 defm PSLLW : PDI_binop_rmi<0xF1, 0x71, MRM6r, "psllw", X86vshl, X86vshli,
4261                            VR128, v8i16, v8i16, bc_v8i16,
4262                            SSE_INTSHIFT_ITINS_P>;
4263 defm PSLLD : PDI_binop_rmi<0xF2, 0x72, MRM6r, "pslld", X86vshl, X86vshli,
4264                            VR128, v4i32, v4i32, bc_v4i32,
4265                            SSE_INTSHIFT_ITINS_P>;
4266 defm PSLLQ : PDI_binop_rmi<0xF3, 0x73, MRM6r, "psllq", X86vshl, X86vshli,
4267                            VR128, v2i64, v2i64, bc_v2i64,
4268                            SSE_INTSHIFT_ITINS_P>;
4269
4270 defm PSRLW : PDI_binop_rmi<0xD1, 0x71, MRM2r, "psrlw", X86vsrl, X86vsrli,
4271                            VR128, v8i16, v8i16, bc_v8i16,
4272                            SSE_INTSHIFT_ITINS_P>;
4273 defm PSRLD : PDI_binop_rmi<0xD2, 0x72, MRM2r, "psrld", X86vsrl, X86vsrli,
4274                            VR128, v4i32, v4i32, bc_v4i32,
4275                            SSE_INTSHIFT_ITINS_P>;
4276 defm PSRLQ : PDI_binop_rmi<0xD3, 0x73, MRM2r, "psrlq", X86vsrl, X86vsrli,
4277                            VR128, v2i64, v2i64, bc_v2i64,
4278                            SSE_INTSHIFT_ITINS_P>;
4279
4280 defm PSRAW : PDI_binop_rmi<0xE1, 0x71, MRM4r, "psraw", X86vsra, X86vsrai,
4281                            VR128, v8i16, v8i16, bc_v8i16,
4282                            SSE_INTSHIFT_ITINS_P>;
4283 defm PSRAD : PDI_binop_rmi<0xE2, 0x72, MRM4r, "psrad", X86vsra, X86vsrai,
4284                            VR128, v4i32, v4i32, bc_v4i32,
4285                            SSE_INTSHIFT_ITINS_P>;
4286
4287 let ExeDomain = SSEPackedInt, SchedRW = [WriteVecShift] in {
4288   // 128-bit logical shifts.
4289   def PSLLDQri : PDIi8<0x73, MRM7r,
4290                        (outs VR128:$dst), (ins VR128:$src1, i32i8imm:$src2),
4291                        "pslldq\t{$src2, $dst|$dst, $src2}",
4292                        [(set VR128:$dst,
4293                          (int_x86_sse2_psll_dq_bs VR128:$src1, imm:$src2))],
4294                          IIC_SSE_INTSHDQ_P_RI>;
4295   def PSRLDQri : PDIi8<0x73, MRM3r,
4296                        (outs VR128:$dst), (ins VR128:$src1, i32i8imm:$src2),
4297                        "psrldq\t{$src2, $dst|$dst, $src2}",
4298                        [(set VR128:$dst,
4299                          (int_x86_sse2_psrl_dq_bs VR128:$src1, imm:$src2))],
4300                          IIC_SSE_INTSHDQ_P_RI>;
4301   // PSRADQri doesn't exist in SSE[1-3].
4302 }
4303 } // Constraints = "$src1 = $dst"
4304
4305 let Predicates = [HasAVX] in {
4306   def : Pat<(int_x86_sse2_psll_dq VR128:$src1, imm:$src2),
4307             (VPSLLDQri VR128:$src1, (BYTE_imm imm:$src2))>;
4308   def : Pat<(int_x86_sse2_psrl_dq VR128:$src1, imm:$src2),
4309             (VPSRLDQri VR128:$src1, (BYTE_imm imm:$src2))>;
4310   def : Pat<(v2f64 (X86fsrl VR128:$src1, i32immSExt8:$src2)),
4311             (VPSRLDQri VR128:$src1, (BYTE_imm imm:$src2))>;
4312
4313   // Shift up / down and insert zero's.
4314   def : Pat<(v2i64 (X86vshldq VR128:$src, (i8 imm:$amt))),
4315             (VPSLLDQri VR128:$src, (BYTE_imm imm:$amt))>;
4316   def : Pat<(v2i64 (X86vshrdq VR128:$src, (i8 imm:$amt))),
4317             (VPSRLDQri VR128:$src, (BYTE_imm imm:$amt))>;
4318 }
4319
4320 let Predicates = [HasAVX2] in {
4321   def : Pat<(int_x86_avx2_psll_dq VR256:$src1, imm:$src2),
4322             (VPSLLDQYri VR256:$src1, (BYTE_imm imm:$src2))>;
4323   def : Pat<(int_x86_avx2_psrl_dq VR256:$src1, imm:$src2),
4324             (VPSRLDQYri VR256:$src1, (BYTE_imm imm:$src2))>;
4325 }
4326
4327 let Predicates = [UseSSE2] in {
4328   def : Pat<(int_x86_sse2_psll_dq VR128:$src1, imm:$src2),
4329             (PSLLDQri VR128:$src1, (BYTE_imm imm:$src2))>;
4330   def : Pat<(int_x86_sse2_psrl_dq VR128:$src1, imm:$src2),
4331             (PSRLDQri VR128:$src1, (BYTE_imm imm:$src2))>;
4332   def : Pat<(v2f64 (X86fsrl VR128:$src1, i32immSExt8:$src2)),
4333             (PSRLDQri VR128:$src1, (BYTE_imm imm:$src2))>;
4334
4335   // Shift up / down and insert zero's.
4336   def : Pat<(v2i64 (X86vshldq VR128:$src, (i8 imm:$amt))),
4337             (PSLLDQri VR128:$src, (BYTE_imm imm:$amt))>;
4338   def : Pat<(v2i64 (X86vshrdq VR128:$src, (i8 imm:$amt))),
4339             (PSRLDQri VR128:$src, (BYTE_imm imm:$amt))>;
4340 }
4341
4342 //===---------------------------------------------------------------------===//
4343 // SSE2 - Packed Integer Comparison Instructions
4344 //===---------------------------------------------------------------------===//
4345
4346 defm PCMPEQB : PDI_binop_all<0x74, "pcmpeqb", X86pcmpeq, v16i8, v32i8,
4347                              SSE_INTALU_ITINS_P, 1>;
4348 defm PCMPEQW : PDI_binop_all<0x75, "pcmpeqw", X86pcmpeq, v8i16, v16i16,
4349                              SSE_INTALU_ITINS_P, 1>;
4350 defm PCMPEQD : PDI_binop_all<0x76, "pcmpeqd", X86pcmpeq, v4i32, v8i32,
4351                              SSE_INTALU_ITINS_P, 1>;
4352 defm PCMPGTB : PDI_binop_all<0x64, "pcmpgtb", X86pcmpgt, v16i8, v32i8,
4353                              SSE_INTALU_ITINS_P, 0>;
4354 defm PCMPGTW : PDI_binop_all<0x65, "pcmpgtw", X86pcmpgt, v8i16, v16i16,
4355                              SSE_INTALU_ITINS_P, 0>;
4356 defm PCMPGTD : PDI_binop_all<0x66, "pcmpgtd", X86pcmpgt, v4i32, v8i32,
4357                              SSE_INTALU_ITINS_P, 0>;
4358
4359 //===---------------------------------------------------------------------===//
4360 // SSE2 - Packed Integer Shuffle Instructions
4361 //===---------------------------------------------------------------------===//
4362
4363 let ExeDomain = SSEPackedInt in {
4364 multiclass sse2_pshuffle<string OpcodeStr, ValueType vt128, ValueType vt256,
4365                          SDNode OpNode> {
4366 let Predicates = [HasAVX] in {
4367   def V#NAME#ri : Ii8<0x70, MRMSrcReg, (outs VR128:$dst),
4368                       (ins VR128:$src1, i8imm:$src2),
4369                       !strconcat("v", OpcodeStr,
4370                                  "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4371                       [(set VR128:$dst,
4372                         (vt128 (OpNode VR128:$src1, (i8 imm:$src2))))],
4373                       IIC_SSE_PSHUF_RI>, VEX, Sched<[WriteShuffle]>;
4374   def V#NAME#mi : Ii8<0x70, MRMSrcMem, (outs VR128:$dst),
4375                       (ins i128mem:$src1, i8imm:$src2),
4376                       !strconcat("v", OpcodeStr,
4377                                  "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4378                      [(set VR128:$dst,
4379                        (vt128 (OpNode (bitconvert (loadv2i64 addr:$src1)),
4380                         (i8 imm:$src2))))], IIC_SSE_PSHUF_MI>, VEX,
4381                   Sched<[WriteShuffleLd]>;
4382 }
4383
4384 let Predicates = [HasAVX2] in {
4385   def V#NAME#Yri : Ii8<0x70, MRMSrcReg, (outs VR256:$dst),
4386                        (ins VR256:$src1, i8imm:$src2),
4387                        !strconcat("v", OpcodeStr,
4388                                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4389                        [(set VR256:$dst,
4390                          (vt256 (OpNode VR256:$src1, (i8 imm:$src2))))],
4391                        IIC_SSE_PSHUF_RI>, VEX, VEX_L, Sched<[WriteShuffle]>;
4392   def V#NAME#Ymi : Ii8<0x70, MRMSrcMem, (outs VR256:$dst),
4393                        (ins i256mem:$src1, i8imm:$src2),
4394                        !strconcat("v", OpcodeStr,
4395                                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4396                       [(set VR256:$dst,
4397                         (vt256 (OpNode (bitconvert (loadv4i64 addr:$src1)),
4398                          (i8 imm:$src2))))], IIC_SSE_PSHUF_MI>, VEX, VEX_L,
4399                    Sched<[WriteShuffleLd]>;
4400 }
4401
4402 let Predicates = [UseSSE2] in {
4403   def ri : Ii8<0x70, MRMSrcReg,
4404                (outs VR128:$dst), (ins VR128:$src1, i8imm:$src2),
4405                !strconcat(OpcodeStr,
4406                           "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4407                 [(set VR128:$dst,
4408                   (vt128 (OpNode VR128:$src1, (i8 imm:$src2))))],
4409                 IIC_SSE_PSHUF_RI>, Sched<[WriteShuffle]>;
4410   def mi : Ii8<0x70, MRMSrcMem,
4411                (outs VR128:$dst), (ins i128mem:$src1, i8imm:$src2),
4412                !strconcat(OpcodeStr,
4413                           "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4414                 [(set VR128:$dst,
4415                   (vt128 (OpNode (bitconvert (memopv2i64 addr:$src1)),
4416                           (i8 imm:$src2))))], IIC_SSE_PSHUF_MI>,
4417            Sched<[WriteShuffleLd, ReadAfterLd]>;
4418 }
4419 }
4420 } // ExeDomain = SSEPackedInt
4421
4422 defm PSHUFD  : sse2_pshuffle<"pshufd", v4i32, v8i32, X86PShufd>, PD;
4423 defm PSHUFHW : sse2_pshuffle<"pshufhw", v8i16, v16i16, X86PShufhw>, XS;
4424 defm PSHUFLW : sse2_pshuffle<"pshuflw", v8i16, v16i16, X86PShuflw>, XD;
4425
4426 let Predicates = [HasAVX] in {
4427   def : Pat<(v4f32 (X86PShufd (loadv4f32 addr:$src1), (i8 imm:$imm))),
4428             (VPSHUFDmi addr:$src1, imm:$imm)>;
4429   def : Pat<(v4f32 (X86PShufd VR128:$src1, (i8 imm:$imm))),
4430             (VPSHUFDri VR128:$src1, imm:$imm)>;
4431 }
4432
4433 let Predicates = [UseSSE2] in {
4434   def : Pat<(v4f32 (X86PShufd (memopv4f32 addr:$src1), (i8 imm:$imm))),
4435             (PSHUFDmi addr:$src1, imm:$imm)>;
4436   def : Pat<(v4f32 (X86PShufd VR128:$src1, (i8 imm:$imm))),
4437             (PSHUFDri VR128:$src1, imm:$imm)>;
4438 }
4439
4440 //===---------------------------------------------------------------------===//
4441 // Packed Integer Pack Instructions (SSE & AVX)
4442 //===---------------------------------------------------------------------===//
4443
4444 let ExeDomain = SSEPackedInt in {
4445 multiclass sse2_pack<bits<8> opc, string OpcodeStr, ValueType OutVT,
4446                      ValueType ArgVT, SDNode OpNode, PatFrag bc_frag,
4447                      bit Is2Addr = 1> {
4448   def rr : PDI<opc, MRMSrcReg,
4449                (outs VR128:$dst), (ins VR128:$src1, VR128:$src2),
4450                !if(Is2Addr,
4451                    !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
4452                    !strconcat(OpcodeStr,
4453                               "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
4454                [(set VR128:$dst,
4455                      (OutVT (OpNode (ArgVT VR128:$src1), VR128:$src2)))]>,
4456                Sched<[WriteShuffle]>;
4457   def rm : PDI<opc, MRMSrcMem,
4458                (outs VR128:$dst), (ins VR128:$src1, i128mem:$src2),
4459                !if(Is2Addr,
4460                    !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
4461                    !strconcat(OpcodeStr,
4462                               "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
4463                [(set VR128:$dst,
4464                      (OutVT (OpNode VR128:$src1,
4465                                     (bc_frag (memopv2i64 addr:$src2)))))]>,
4466                Sched<[WriteShuffleLd, ReadAfterLd]>;
4467 }
4468
4469 multiclass sse2_pack_y<bits<8> opc, string OpcodeStr, ValueType OutVT,
4470                        ValueType ArgVT, SDNode OpNode, PatFrag bc_frag> {
4471   def Yrr : PDI<opc, MRMSrcReg,
4472                 (outs VR256:$dst), (ins VR256:$src1, VR256:$src2),
4473                 !strconcat(OpcodeStr,
4474                            "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4475                 [(set VR256:$dst,
4476                       (OutVT (OpNode (ArgVT VR256:$src1), VR256:$src2)))]>,
4477                 Sched<[WriteShuffle]>;
4478   def Yrm : PDI<opc, MRMSrcMem,
4479                 (outs VR256:$dst), (ins VR256:$src1, i256mem:$src2),
4480                 !strconcat(OpcodeStr,
4481                            "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4482                 [(set VR256:$dst,
4483                       (OutVT (OpNode VR256:$src1,
4484                                      (bc_frag (memopv4i64 addr:$src2)))))]>,
4485                 Sched<[WriteShuffleLd, ReadAfterLd]>;
4486 }
4487
4488 multiclass sse4_pack<bits<8> opc, string OpcodeStr, ValueType OutVT,
4489                      ValueType ArgVT, SDNode OpNode, PatFrag bc_frag,
4490                      bit Is2Addr = 1> {
4491   def rr : SS48I<opc, MRMSrcReg,
4492                  (outs VR128:$dst), (ins VR128:$src1, VR128:$src2),
4493                  !if(Is2Addr,
4494                      !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
4495                      !strconcat(OpcodeStr,
4496                                 "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
4497                  [(set VR128:$dst,
4498                        (OutVT (OpNode (ArgVT VR128:$src1), VR128:$src2)))]>,
4499                  Sched<[WriteShuffle]>;
4500   def rm : SS48I<opc, MRMSrcMem,
4501                  (outs VR128:$dst), (ins VR128:$src1, i128mem:$src2),
4502                  !if(Is2Addr,
4503                      !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
4504                      !strconcat(OpcodeStr,
4505                                 "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
4506                  [(set VR128:$dst,
4507                        (OutVT (OpNode VR128:$src1,
4508                                       (bc_frag (memopv2i64 addr:$src2)))))]>,
4509                  Sched<[WriteShuffleLd, ReadAfterLd]>;
4510 }
4511
4512 multiclass sse4_pack_y<bits<8> opc, string OpcodeStr, ValueType OutVT,
4513                      ValueType ArgVT, SDNode OpNode, PatFrag bc_frag> {
4514   def Yrr : SS48I<opc, MRMSrcReg,
4515                   (outs VR256:$dst), (ins VR256:$src1, VR256:$src2),
4516                   !strconcat(OpcodeStr,
4517                              "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4518                   [(set VR256:$dst,
4519                         (OutVT (OpNode (ArgVT VR256:$src1), VR256:$src2)))]>,
4520                   Sched<[WriteShuffle]>;
4521   def Yrm : SS48I<opc, MRMSrcMem,
4522                   (outs VR256:$dst), (ins VR256:$src1, i256mem:$src2),
4523                   !strconcat(OpcodeStr,
4524                              "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4525                   [(set VR256:$dst,
4526                         (OutVT (OpNode VR256:$src1,
4527                                        (bc_frag (memopv4i64 addr:$src2)))))]>,
4528                   Sched<[WriteShuffleLd, ReadAfterLd]>;
4529 }
4530
4531 let Predicates = [HasAVX] in {
4532   defm VPACKSSWB : sse2_pack<0x63, "vpacksswb", v16i8, v8i16, X86Packss,
4533                              bc_v8i16, 0>, VEX_4V;
4534   defm VPACKSSDW : sse2_pack<0x6B, "vpackssdw", v8i16, v4i32, X86Packss,
4535                              bc_v4i32, 0>, VEX_4V;
4536
4537   defm VPACKUSWB : sse2_pack<0x67, "vpackuswb", v16i8, v8i16, X86Packus,
4538                              bc_v8i16, 0>, VEX_4V;
4539   defm VPACKUSDW : sse4_pack<0x2B, "vpackusdw", v8i16, v4i32, X86Packus,
4540                              bc_v4i32, 0>, VEX_4V;
4541 }
4542
4543 let Predicates = [HasAVX2] in {
4544   defm VPACKSSWB : sse2_pack_y<0x63, "vpacksswb", v32i8, v16i16, X86Packss,
4545                                bc_v16i16>, VEX_4V, VEX_L;
4546   defm VPACKSSDW : sse2_pack_y<0x6B, "vpackssdw", v16i16, v8i32, X86Packss,
4547                                bc_v8i32>, VEX_4V, VEX_L;
4548
4549   defm VPACKUSWB : sse2_pack_y<0x67, "vpackuswb", v32i8, v16i16, X86Packus,
4550                                bc_v16i16>, VEX_4V, VEX_L;
4551   defm VPACKUSDW : sse4_pack_y<0x2B, "vpackusdw", v16i16, v8i32, X86Packus,
4552                                bc_v8i32>, VEX_4V, VEX_L;
4553 }
4554
4555 let Constraints = "$src1 = $dst" in {
4556   defm PACKSSWB : sse2_pack<0x63, "packsswb", v16i8, v8i16, X86Packss,
4557                             bc_v8i16>;
4558   defm PACKSSDW : sse2_pack<0x6B, "packssdw", v8i16, v4i32, X86Packss,
4559                             bc_v4i32>;
4560
4561   defm PACKUSWB : sse2_pack<0x67, "packuswb", v16i8, v8i16, X86Packus,
4562                             bc_v8i16>;
4563
4564   let Predicates = [HasSSE41] in
4565   defm PACKUSDW : sse4_pack<0x2B, "packusdw", v8i16, v4i32, X86Packus,
4566                             bc_v4i32>;
4567 }
4568 } // ExeDomain = SSEPackedInt
4569
4570 //===---------------------------------------------------------------------===//
4571 // SSE2 - Packed Integer Unpack Instructions
4572 //===---------------------------------------------------------------------===//
4573
4574 let ExeDomain = SSEPackedInt in {
4575 multiclass sse2_unpack<bits<8> opc, string OpcodeStr, ValueType vt,
4576                        SDNode OpNode, PatFrag bc_frag, bit Is2Addr = 1> {
4577   def rr : PDI<opc, MRMSrcReg,
4578       (outs VR128:$dst), (ins VR128:$src1, VR128:$src2),
4579       !if(Is2Addr,
4580           !strconcat(OpcodeStr,"\t{$src2, $dst|$dst, $src2}"),
4581           !strconcat(OpcodeStr,"\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
4582       [(set VR128:$dst, (vt (OpNode VR128:$src1, VR128:$src2)))],
4583       IIC_SSE_UNPCK>, Sched<[WriteShuffle]>;
4584   def rm : PDI<opc, MRMSrcMem,
4585       (outs VR128:$dst), (ins VR128:$src1, i128mem:$src2),
4586       !if(Is2Addr,
4587           !strconcat(OpcodeStr,"\t{$src2, $dst|$dst, $src2}"),
4588           !strconcat(OpcodeStr,"\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
4589       [(set VR128:$dst, (OpNode VR128:$src1,
4590                                   (bc_frag (memopv2i64
4591                                                addr:$src2))))],
4592                                                IIC_SSE_UNPCK>,
4593       Sched<[WriteShuffleLd, ReadAfterLd]>;
4594 }
4595
4596 multiclass sse2_unpack_y<bits<8> opc, string OpcodeStr, ValueType vt,
4597                          SDNode OpNode, PatFrag bc_frag> {
4598   def Yrr : PDI<opc, MRMSrcReg,
4599       (outs VR256:$dst), (ins VR256:$src1, VR256:$src2),
4600       !strconcat(OpcodeStr,"\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4601       [(set VR256:$dst, (vt (OpNode VR256:$src1, VR256:$src2)))]>,
4602       Sched<[WriteShuffle]>;
4603   def Yrm : PDI<opc, MRMSrcMem,
4604       (outs VR256:$dst), (ins VR256:$src1, i256mem:$src2),
4605       !strconcat(OpcodeStr,"\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4606       [(set VR256:$dst, (OpNode VR256:$src1,
4607                                   (bc_frag (memopv4i64 addr:$src2))))]>,
4608       Sched<[WriteShuffleLd, ReadAfterLd]>;
4609 }
4610
4611 let Predicates = [HasAVX] in {
4612   defm VPUNPCKLBW  : sse2_unpack<0x60, "vpunpcklbw", v16i8, X86Unpckl,
4613                                  bc_v16i8, 0>, VEX_4V;
4614   defm VPUNPCKLWD  : sse2_unpack<0x61, "vpunpcklwd", v8i16, X86Unpckl,
4615                                  bc_v8i16, 0>, VEX_4V;
4616   defm VPUNPCKLDQ  : sse2_unpack<0x62, "vpunpckldq", v4i32, X86Unpckl,
4617                                  bc_v4i32, 0>, VEX_4V;
4618   defm VPUNPCKLQDQ : sse2_unpack<0x6C, "vpunpcklqdq", v2i64, X86Unpckl,
4619                                  bc_v2i64, 0>, VEX_4V;
4620
4621   defm VPUNPCKHBW  : sse2_unpack<0x68, "vpunpckhbw", v16i8, X86Unpckh,
4622                                  bc_v16i8, 0>, VEX_4V;
4623   defm VPUNPCKHWD  : sse2_unpack<0x69, "vpunpckhwd", v8i16, X86Unpckh,
4624                                  bc_v8i16, 0>, VEX_4V;
4625   defm VPUNPCKHDQ  : sse2_unpack<0x6A, "vpunpckhdq", v4i32, X86Unpckh,
4626                                  bc_v4i32, 0>, VEX_4V;
4627   defm VPUNPCKHQDQ : sse2_unpack<0x6D, "vpunpckhqdq", v2i64, X86Unpckh,
4628                                  bc_v2i64, 0>, VEX_4V;
4629 }
4630
4631 let Predicates = [HasAVX2] in {
4632   defm VPUNPCKLBW  : sse2_unpack_y<0x60, "vpunpcklbw", v32i8, X86Unpckl,
4633                                    bc_v32i8>, VEX_4V, VEX_L;
4634   defm VPUNPCKLWD  : sse2_unpack_y<0x61, "vpunpcklwd", v16i16, X86Unpckl,
4635                                    bc_v16i16>, VEX_4V, VEX_L;
4636   defm VPUNPCKLDQ  : sse2_unpack_y<0x62, "vpunpckldq", v8i32, X86Unpckl,
4637                                    bc_v8i32>, VEX_4V, VEX_L;
4638   defm VPUNPCKLQDQ : sse2_unpack_y<0x6C, "vpunpcklqdq", v4i64, X86Unpckl,
4639                                    bc_v4i64>, VEX_4V, VEX_L;
4640
4641   defm VPUNPCKHBW  : sse2_unpack_y<0x68, "vpunpckhbw", v32i8, X86Unpckh,
4642                                    bc_v32i8>, VEX_4V, VEX_L;
4643   defm VPUNPCKHWD  : sse2_unpack_y<0x69, "vpunpckhwd", v16i16, X86Unpckh,
4644                                    bc_v16i16>, VEX_4V, VEX_L;
4645   defm VPUNPCKHDQ  : sse2_unpack_y<0x6A, "vpunpckhdq", v8i32, X86Unpckh,
4646                                    bc_v8i32>, VEX_4V, VEX_L;
4647   defm VPUNPCKHQDQ : sse2_unpack_y<0x6D, "vpunpckhqdq", v4i64, X86Unpckh,
4648                                    bc_v4i64>, VEX_4V, VEX_L;
4649 }
4650
4651 let Constraints = "$src1 = $dst" in {
4652   defm PUNPCKLBW  : sse2_unpack<0x60, "punpcklbw", v16i8, X86Unpckl,
4653                                 bc_v16i8>;
4654   defm PUNPCKLWD  : sse2_unpack<0x61, "punpcklwd", v8i16, X86Unpckl,
4655                                 bc_v8i16>;
4656   defm PUNPCKLDQ  : sse2_unpack<0x62, "punpckldq", v4i32, X86Unpckl,
4657                                 bc_v4i32>;
4658   defm PUNPCKLQDQ : sse2_unpack<0x6C, "punpcklqdq", v2i64, X86Unpckl,
4659                                 bc_v2i64>;
4660
4661   defm PUNPCKHBW  : sse2_unpack<0x68, "punpckhbw", v16i8, X86Unpckh,
4662                                 bc_v16i8>;
4663   defm PUNPCKHWD  : sse2_unpack<0x69, "punpckhwd", v8i16, X86Unpckh,
4664                                 bc_v8i16>;
4665   defm PUNPCKHDQ  : sse2_unpack<0x6A, "punpckhdq", v4i32, X86Unpckh,
4666                                 bc_v4i32>;
4667   defm PUNPCKHQDQ : sse2_unpack<0x6D, "punpckhqdq", v2i64, X86Unpckh,
4668                                 bc_v2i64>;
4669 }
4670 } // ExeDomain = SSEPackedInt
4671
4672 //===---------------------------------------------------------------------===//
4673 // SSE2 - Packed Integer Extract and Insert
4674 //===---------------------------------------------------------------------===//
4675
4676 let ExeDomain = SSEPackedInt in {
4677 multiclass sse2_pinsrw<bit Is2Addr = 1> {
4678   def rri : Ii8<0xC4, MRMSrcReg,
4679        (outs VR128:$dst), (ins VR128:$src1,
4680         GR32orGR64:$src2, i32i8imm:$src3),
4681        !if(Is2Addr,
4682            "pinsrw\t{$src3, $src2, $dst|$dst, $src2, $src3}",
4683            "vpinsrw\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
4684        [(set VR128:$dst,
4685          (X86pinsrw VR128:$src1, GR32orGR64:$src2, imm:$src3))],
4686        IIC_SSE_PINSRW>, Sched<[WriteShuffle]>;
4687   def rmi : Ii8<0xC4, MRMSrcMem,
4688                        (outs VR128:$dst), (ins VR128:$src1,
4689                         i16mem:$src2, i32i8imm:$src3),
4690        !if(Is2Addr,
4691            "pinsrw\t{$src3, $src2, $dst|$dst, $src2, $src3}",
4692            "vpinsrw\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
4693        [(set VR128:$dst,
4694          (X86pinsrw VR128:$src1, (extloadi16 addr:$src2),
4695                     imm:$src3))], IIC_SSE_PINSRW>,
4696        Sched<[WriteShuffleLd, ReadAfterLd]>;
4697 }
4698
4699 // Extract
4700 let Predicates = [HasAVX] in
4701 def VPEXTRWri : Ii8<0xC5, MRMSrcReg,
4702                     (outs GR32orGR64:$dst), (ins VR128:$src1, i32i8imm:$src2),
4703                     "vpextrw\t{$src2, $src1, $dst|$dst, $src1, $src2}",
4704                     [(set GR32orGR64:$dst, (X86pextrw (v8i16 VR128:$src1),
4705                                             imm:$src2))]>, PD, VEX,
4706                 Sched<[WriteShuffle]>;
4707 def PEXTRWri : PDIi8<0xC5, MRMSrcReg,
4708                     (outs GR32orGR64:$dst), (ins VR128:$src1, i32i8imm:$src2),
4709                     "pextrw\t{$src2, $src1, $dst|$dst, $src1, $src2}",
4710                     [(set GR32orGR64:$dst, (X86pextrw (v8i16 VR128:$src1),
4711                                             imm:$src2))], IIC_SSE_PEXTRW>,
4712                Sched<[WriteShuffleLd, ReadAfterLd]>;
4713
4714 // Insert
4715 let Predicates = [HasAVX] in
4716 defm VPINSRW : sse2_pinsrw<0>, PD, VEX_4V;
4717
4718 let Predicates = [UseSSE2], Constraints = "$src1 = $dst" in
4719 defm PINSRW : sse2_pinsrw, PD;
4720
4721 } // ExeDomain = SSEPackedInt
4722
4723 //===---------------------------------------------------------------------===//
4724 // SSE2 - Packed Mask Creation
4725 //===---------------------------------------------------------------------===//
4726
4727 let ExeDomain = SSEPackedInt, SchedRW = [WriteVecLogic] in {
4728
4729 def VPMOVMSKBrr  : VPDI<0xD7, MRMSrcReg, (outs GR32orGR64:$dst),
4730            (ins VR128:$src),
4731            "pmovmskb\t{$src, $dst|$dst, $src}",
4732            [(set GR32orGR64:$dst, (int_x86_sse2_pmovmskb_128 VR128:$src))],
4733            IIC_SSE_MOVMSK>, VEX;
4734
4735 let Predicates = [HasAVX2] in {
4736 def VPMOVMSKBYrr  : VPDI<0xD7, MRMSrcReg, (outs GR32orGR64:$dst),
4737            (ins VR256:$src),
4738            "pmovmskb\t{$src, $dst|$dst, $src}",
4739            [(set GR32orGR64:$dst, (int_x86_avx2_pmovmskb VR256:$src))]>,
4740            VEX, VEX_L;
4741 }
4742
4743 def PMOVMSKBrr : PDI<0xD7, MRMSrcReg, (outs GR32orGR64:$dst), (ins VR128:$src),
4744            "pmovmskb\t{$src, $dst|$dst, $src}",
4745            [(set GR32orGR64:$dst, (int_x86_sse2_pmovmskb_128 VR128:$src))],
4746            IIC_SSE_MOVMSK>;
4747
4748 } // ExeDomain = SSEPackedInt
4749
4750 //===---------------------------------------------------------------------===//
4751 // SSE2 - Conditional Store
4752 //===---------------------------------------------------------------------===//
4753
4754 let ExeDomain = SSEPackedInt, SchedRW = [WriteStore] in {
4755
4756 let Uses = [EDI], Predicates = [HasAVX,Not64BitMode] in
4757 def VMASKMOVDQU : VPDI<0xF7, MRMSrcReg, (outs),
4758            (ins VR128:$src, VR128:$mask),
4759            "maskmovdqu\t{$mask, $src|$src, $mask}",
4760            [(int_x86_sse2_maskmov_dqu VR128:$src, VR128:$mask, EDI)],
4761            IIC_SSE_MASKMOV>, VEX;
4762 let Uses = [RDI], Predicates = [HasAVX,In64BitMode] in
4763 def VMASKMOVDQU64 : VPDI<0xF7, MRMSrcReg, (outs),
4764            (ins VR128:$src, VR128:$mask),
4765            "maskmovdqu\t{$mask, $src|$src, $mask}",
4766            [(int_x86_sse2_maskmov_dqu VR128:$src, VR128:$mask, RDI)],
4767            IIC_SSE_MASKMOV>, VEX;
4768
4769 let Uses = [EDI], Predicates = [UseSSE2,Not64BitMode] in
4770 def MASKMOVDQU : PDI<0xF7, MRMSrcReg, (outs), (ins VR128:$src, VR128:$mask),
4771            "maskmovdqu\t{$mask, $src|$src, $mask}",
4772            [(int_x86_sse2_maskmov_dqu VR128:$src, VR128:$mask, EDI)],
4773            IIC_SSE_MASKMOV>;
4774 let Uses = [RDI], Predicates = [UseSSE2,In64BitMode] in
4775 def MASKMOVDQU64 : PDI<0xF7, MRMSrcReg, (outs), (ins VR128:$src, VR128:$mask),
4776            "maskmovdqu\t{$mask, $src|$src, $mask}",
4777            [(int_x86_sse2_maskmov_dqu VR128:$src, VR128:$mask, RDI)],
4778            IIC_SSE_MASKMOV>;
4779
4780 } // ExeDomain = SSEPackedInt
4781
4782 //===---------------------------------------------------------------------===//
4783 // SSE2 - Move Doubleword
4784 //===---------------------------------------------------------------------===//
4785
4786 //===---------------------------------------------------------------------===//
4787 // Move Int Doubleword to Packed Double Int
4788 //
4789 def VMOVDI2PDIrr : VS2I<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR32:$src),
4790                       "movd\t{$src, $dst|$dst, $src}",
4791                       [(set VR128:$dst,
4792                         (v4i32 (scalar_to_vector GR32:$src)))], IIC_SSE_MOVDQ>,
4793                         VEX, Sched<[WriteMove]>;
4794 def VMOVDI2PDIrm : VS2I<0x6E, MRMSrcMem, (outs VR128:$dst), (ins i32mem:$src),
4795                       "movd\t{$src, $dst|$dst, $src}",
4796                       [(set VR128:$dst,
4797                         (v4i32 (scalar_to_vector (loadi32 addr:$src))))],
4798                         IIC_SSE_MOVDQ>,
4799                       VEX, Sched<[WriteLoad]>;
4800 def VMOV64toPQIrr : VRS2I<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR64:$src),
4801                         "movq\t{$src, $dst|$dst, $src}",
4802                         [(set VR128:$dst,
4803                           (v2i64 (scalar_to_vector GR64:$src)))],
4804                           IIC_SSE_MOVDQ>, VEX, Sched<[WriteMove]>;
4805 let isCodeGenOnly = 1 in
4806 def VMOV64toSDrr : VRS2I<0x6E, MRMSrcReg, (outs FR64:$dst), (ins GR64:$src),
4807                        "movq\t{$src, $dst|$dst, $src}",
4808                        [(set FR64:$dst, (bitconvert GR64:$src))],
4809                        IIC_SSE_MOVDQ>, VEX, Sched<[WriteMove]>;
4810
4811 def MOVDI2PDIrr : S2I<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR32:$src),
4812                       "movd\t{$src, $dst|$dst, $src}",
4813                       [(set VR128:$dst,
4814                         (v4i32 (scalar_to_vector GR32:$src)))], IIC_SSE_MOVDQ>,
4815                   Sched<[WriteMove]>;
4816 def MOVDI2PDIrm : S2I<0x6E, MRMSrcMem, (outs VR128:$dst), (ins i32mem:$src),
4817                       "movd\t{$src, $dst|$dst, $src}",
4818                       [(set VR128:$dst,
4819                         (v4i32 (scalar_to_vector (loadi32 addr:$src))))],
4820                         IIC_SSE_MOVDQ>, Sched<[WriteLoad]>;
4821 def MOV64toPQIrr : RS2I<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR64:$src),
4822                         "mov{d|q}\t{$src, $dst|$dst, $src}",
4823                         [(set VR128:$dst,
4824                           (v2i64 (scalar_to_vector GR64:$src)))],
4825                           IIC_SSE_MOVDQ>, Sched<[WriteMove]>;
4826 let isCodeGenOnly = 1 in
4827 def MOV64toSDrr : RS2I<0x6E, MRMSrcReg, (outs FR64:$dst), (ins GR64:$src),
4828                        "mov{d|q}\t{$src, $dst|$dst, $src}",
4829                        [(set FR64:$dst, (bitconvert GR64:$src))],
4830                        IIC_SSE_MOVDQ>, Sched<[WriteMove]>;
4831
4832 //===---------------------------------------------------------------------===//
4833 // Move Int Doubleword to Single Scalar
4834 //
4835 let isCodeGenOnly = 1 in {
4836   def VMOVDI2SSrr  : VS2I<0x6E, MRMSrcReg, (outs FR32:$dst), (ins GR32:$src),
4837                         "movd\t{$src, $dst|$dst, $src}",
4838                         [(set FR32:$dst, (bitconvert GR32:$src))],
4839                         IIC_SSE_MOVDQ>, VEX, Sched<[WriteMove]>;
4840
4841   def VMOVDI2SSrm  : VS2I<0x6E, MRMSrcMem, (outs FR32:$dst), (ins i32mem:$src),
4842                         "movd\t{$src, $dst|$dst, $src}",
4843                         [(set FR32:$dst, (bitconvert (loadi32 addr:$src)))],
4844                         IIC_SSE_MOVDQ>,
4845                         VEX, Sched<[WriteLoad]>;
4846   def MOVDI2SSrr  : S2I<0x6E, MRMSrcReg, (outs FR32:$dst), (ins GR32:$src),
4847                         "movd\t{$src, $dst|$dst, $src}",
4848                         [(set FR32:$dst, (bitconvert GR32:$src))],
4849                         IIC_SSE_MOVDQ>, Sched<[WriteMove]>;
4850
4851   def MOVDI2SSrm  : S2I<0x6E, MRMSrcMem, (outs FR32:$dst), (ins i32mem:$src),
4852                         "movd\t{$src, $dst|$dst, $src}",
4853                         [(set FR32:$dst, (bitconvert (loadi32 addr:$src)))],
4854                         IIC_SSE_MOVDQ>, Sched<[WriteLoad]>;
4855 }
4856
4857 //===---------------------------------------------------------------------===//
4858 // Move Packed Doubleword Int to Packed Double Int
4859 //
4860 def VMOVPDI2DIrr  : VS2I<0x7E, MRMDestReg, (outs GR32:$dst), (ins VR128:$src),
4861                        "movd\t{$src, $dst|$dst, $src}",
4862                        [(set GR32:$dst, (vector_extract (v4i32 VR128:$src),
4863                                         (iPTR 0)))], IIC_SSE_MOVD_ToGP>, VEX,
4864                     Sched<[WriteMove]>;
4865 def VMOVPDI2DImr  : VS2I<0x7E, MRMDestMem, (outs),
4866                        (ins i32mem:$dst, VR128:$src),
4867                        "movd\t{$src, $dst|$dst, $src}",
4868                        [(store (i32 (vector_extract (v4i32 VR128:$src),
4869                                      (iPTR 0))), addr:$dst)], IIC_SSE_MOVDQ>,
4870                                      VEX, Sched<[WriteStore]>;
4871 def MOVPDI2DIrr  : S2I<0x7E, MRMDestReg, (outs GR32:$dst), (ins VR128:$src),
4872                        "movd\t{$src, $dst|$dst, $src}",
4873                        [(set GR32:$dst, (vector_extract (v4i32 VR128:$src),
4874                                         (iPTR 0)))], IIC_SSE_MOVD_ToGP>,
4875                    Sched<[WriteMove]>;
4876 def MOVPDI2DImr  : S2I<0x7E, MRMDestMem, (outs), (ins i32mem:$dst, VR128:$src),
4877                        "movd\t{$src, $dst|$dst, $src}",
4878                        [(store (i32 (vector_extract (v4i32 VR128:$src),
4879                                      (iPTR 0))), addr:$dst)],
4880                                      IIC_SSE_MOVDQ>, Sched<[WriteStore]>;
4881
4882 def : Pat<(v8i32 (X86Vinsert (v8i32 immAllZerosV), GR32:$src2, (iPTR 0))),
4883         (SUBREG_TO_REG (i32 0), (VMOVDI2PDIrr GR32:$src2), sub_xmm)>;
4884
4885 def : Pat<(v4i64 (X86Vinsert (bc_v4i64 (v8i32 immAllZerosV)), GR64:$src2, (iPTR 0))),
4886         (SUBREG_TO_REG (i32 0), (VMOV64toPQIrr GR64:$src2), sub_xmm)>;
4887
4888 def : Pat<(v8i32 (X86Vinsert undef, GR32:$src2, (iPTR 0))),
4889         (SUBREG_TO_REG (i32 0), (VMOVDI2PDIrr GR32:$src2), sub_xmm)>;
4890
4891 def : Pat<(v4i64 (X86Vinsert undef, GR64:$src2, (iPTR 0))),
4892         (SUBREG_TO_REG (i32 0), (VMOV64toPQIrr GR64:$src2), sub_xmm)>;
4893
4894 //===---------------------------------------------------------------------===//
4895 // Move Packed Doubleword Int first element to Doubleword Int
4896 //
4897 let SchedRW = [WriteMove] in {
4898 def VMOVPQIto64rr : VRS2I<0x7E, MRMDestReg, (outs GR64:$dst), (ins VR128:$src),
4899                           "movq\t{$src, $dst|$dst, $src}",
4900                           [(set GR64:$dst, (vector_extract (v2i64 VR128:$src),
4901                                                            (iPTR 0)))],
4902                                                            IIC_SSE_MOVD_ToGP>,
4903                       VEX;
4904
4905 def MOVPQIto64rr : RS2I<0x7E, MRMDestReg, (outs GR64:$dst), (ins VR128:$src),
4906                         "mov{d|q}\t{$src, $dst|$dst, $src}",
4907                         [(set GR64:$dst, (vector_extract (v2i64 VR128:$src),
4908                                                          (iPTR 0)))],
4909                                                          IIC_SSE_MOVD_ToGP>;
4910 } //SchedRW
4911
4912 //===---------------------------------------------------------------------===//
4913 // Bitcast FR64 <-> GR64
4914 //
4915 let isCodeGenOnly = 1 in {
4916   let Predicates = [UseAVX] in
4917   def VMOV64toSDrm : VS2SI<0x7E, MRMSrcMem, (outs FR64:$dst), (ins i64mem:$src),
4918                           "movq\t{$src, $dst|$dst, $src}",
4919                           [(set FR64:$dst, (bitconvert (loadi64 addr:$src)))]>,
4920                           VEX, Sched<[WriteLoad]>;
4921   def VMOVSDto64rr : VRS2I<0x7E, MRMDestReg, (outs GR64:$dst), (ins FR64:$src),
4922                            "movq\t{$src, $dst|$dst, $src}",
4923                            [(set GR64:$dst, (bitconvert FR64:$src))],
4924                            IIC_SSE_MOVDQ>, VEX, Sched<[WriteMove]>;
4925   def VMOVSDto64mr : VRS2I<0x7E, MRMDestMem, (outs), (ins i64mem:$dst, FR64:$src),
4926                            "movq\t{$src, $dst|$dst, $src}",
4927                            [(store (i64 (bitconvert FR64:$src)), addr:$dst)],
4928                            IIC_SSE_MOVDQ>, VEX, Sched<[WriteStore]>;
4929
4930   def MOV64toSDrm : S2SI<0x7E, MRMSrcMem, (outs FR64:$dst), (ins i64mem:$src),
4931                          "movq\t{$src, $dst|$dst, $src}",
4932                          [(set FR64:$dst, (bitconvert (loadi64 addr:$src)))],
4933                          IIC_SSE_MOVDQ>, Sched<[WriteLoad]>;
4934   def MOVSDto64rr : RS2I<0x7E, MRMDestReg, (outs GR64:$dst), (ins FR64:$src),
4935                          "mov{d|q}\t{$src, $dst|$dst, $src}",
4936                          [(set GR64:$dst, (bitconvert FR64:$src))],
4937                          IIC_SSE_MOVD_ToGP>, Sched<[WriteMove]>;
4938   def MOVSDto64mr : RS2I<0x7E, MRMDestMem, (outs), (ins i64mem:$dst, FR64:$src),
4939                          "movq\t{$src, $dst|$dst, $src}",
4940                          [(store (i64 (bitconvert FR64:$src)), addr:$dst)],
4941                          IIC_SSE_MOVDQ>, Sched<[WriteStore]>;
4942 }
4943
4944 //===---------------------------------------------------------------------===//
4945 // Move Scalar Single to Double Int
4946 //
4947 let isCodeGenOnly = 1 in {
4948   def VMOVSS2DIrr  : VS2I<0x7E, MRMDestReg, (outs GR32:$dst), (ins FR32:$src),
4949                         "movd\t{$src, $dst|$dst, $src}",
4950                         [(set GR32:$dst, (bitconvert FR32:$src))],
4951                         IIC_SSE_MOVD_ToGP>, VEX, Sched<[WriteMove]>;
4952   def VMOVSS2DImr  : VS2I<0x7E, MRMDestMem, (outs), (ins i32mem:$dst, FR32:$src),
4953                         "movd\t{$src, $dst|$dst, $src}",
4954                         [(store (i32 (bitconvert FR32:$src)), addr:$dst)],
4955                         IIC_SSE_MOVDQ>, VEX, Sched<[WriteStore]>;
4956   def MOVSS2DIrr  : S2I<0x7E, MRMDestReg, (outs GR32:$dst), (ins FR32:$src),
4957                         "movd\t{$src, $dst|$dst, $src}",
4958                         [(set GR32:$dst, (bitconvert FR32:$src))],
4959                         IIC_SSE_MOVD_ToGP>, Sched<[WriteMove]>;
4960   def MOVSS2DImr  : S2I<0x7E, MRMDestMem, (outs), (ins i32mem:$dst, FR32:$src),
4961                         "movd\t{$src, $dst|$dst, $src}",
4962                         [(store (i32 (bitconvert FR32:$src)), addr:$dst)],
4963                         IIC_SSE_MOVDQ>, Sched<[WriteStore]>;
4964 }
4965
4966 //===---------------------------------------------------------------------===//
4967 // Patterns and instructions to describe movd/movq to XMM register zero-extends
4968 //
4969 let isCodeGenOnly = 1, SchedRW = [WriteMove] in {
4970 let AddedComplexity = 15 in {
4971 def VMOVZQI2PQIrr : VS2I<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR64:$src),
4972                        "movq\t{$src, $dst|$dst, $src}", // X86-64 only
4973                        [(set VR128:$dst, (v2i64 (X86vzmovl
4974                                       (v2i64 (scalar_to_vector GR64:$src)))))],
4975                                       IIC_SSE_MOVDQ>,
4976                                       VEX, VEX_W;
4977 def MOVZQI2PQIrr : RS2I<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR64:$src),
4978                        "mov{d|q}\t{$src, $dst|$dst, $src}", // X86-64 only
4979                        [(set VR128:$dst, (v2i64 (X86vzmovl
4980                                       (v2i64 (scalar_to_vector GR64:$src)))))],
4981                                       IIC_SSE_MOVDQ>;
4982 }
4983 } // isCodeGenOnly, SchedRW
4984
4985 let Predicates = [UseAVX] in {
4986   let AddedComplexity = 15 in
4987     def : Pat<(v4i32 (X86vzmovl (v4i32 (scalar_to_vector GR32:$src)))),
4988               (VMOVDI2PDIrr GR32:$src)>;
4989
4990   // AVX 128-bit movd/movq instruction write zeros in the high 128-bit part.
4991   let AddedComplexity = 20 in {
4992     def : Pat<(v4i32 (X86vzmovl (v4i32 (scalar_to_vector (loadi32 addr:$src))))),
4993               (VMOVDI2PDIrm addr:$src)>;
4994     def : Pat<(v4i32 (X86vzmovl (bc_v4i32 (loadv4f32 addr:$src)))),
4995               (VMOVDI2PDIrm addr:$src)>;
4996     def : Pat<(v4i32 (X86vzmovl (bc_v4i32 (loadv2i64 addr:$src)))),
4997               (VMOVDI2PDIrm addr:$src)>;
4998   }
4999   // Use regular 128-bit instructions to match 256-bit scalar_to_vec+zext.
5000   def : Pat<(v8i32 (X86vzmovl (insert_subvector undef,
5001                                (v4i32 (scalar_to_vector GR32:$src)),(iPTR 0)))),
5002             (SUBREG_TO_REG (i32 0), (VMOVDI2PDIrr GR32:$src), sub_xmm)>;
5003   def : Pat<(v4i64 (X86vzmovl (insert_subvector undef,
5004                                (v2i64 (scalar_to_vector GR64:$src)),(iPTR 0)))),
5005             (SUBREG_TO_REG (i64 0), (VMOVZQI2PQIrr GR64:$src), sub_xmm)>;
5006 }
5007
5008 let Predicates = [UseSSE2] in {
5009   let AddedComplexity = 15 in
5010     def : Pat<(v4i32 (X86vzmovl (v4i32 (scalar_to_vector GR32:$src)))),
5011               (MOVDI2PDIrr GR32:$src)>;
5012
5013   let AddedComplexity = 20 in {
5014     def : Pat<(v4i32 (X86vzmovl (v4i32 (scalar_to_vector (loadi32 addr:$src))))),
5015               (MOVDI2PDIrm addr:$src)>;
5016     def : Pat<(v4i32 (X86vzmovl (bc_v4i32 (loadv4f32 addr:$src)))),
5017               (MOVDI2PDIrm addr:$src)>;
5018     def : Pat<(v4i32 (X86vzmovl (bc_v4i32 (loadv2i64 addr:$src)))),
5019               (MOVDI2PDIrm addr:$src)>;
5020   }
5021 }
5022
5023 // These are the correct encodings of the instructions so that we know how to
5024 // read correct assembly, even though we continue to emit the wrong ones for
5025 // compatibility with Darwin's buggy assembler.
5026 def : InstAlias<"movq\t{$src, $dst|$dst, $src}",
5027                 (MOV64toPQIrr VR128:$dst, GR64:$src), 0>;
5028 def : InstAlias<"movq\t{$src, $dst|$dst, $src}",
5029                 (MOVPQIto64rr GR64:$dst, VR128:$src), 0>;
5030 // Allow "vmovd" but print "vmovq" since we don't need compatibility for AVX.
5031 def : InstAlias<"vmovd\t{$src, $dst|$dst, $src}",
5032                 (VMOV64toPQIrr VR128:$dst, GR64:$src), 0>;
5033 def : InstAlias<"vmovd\t{$src, $dst|$dst, $src}",
5034                 (VMOVPQIto64rr GR64:$dst, VR128:$src), 0>;
5035
5036 //===---------------------------------------------------------------------===//
5037 // SSE2 - Move Quadword
5038 //===---------------------------------------------------------------------===//
5039
5040 //===---------------------------------------------------------------------===//
5041 // Move Quadword Int to Packed Quadword Int
5042 //
5043
5044 let SchedRW = [WriteLoad] in {
5045 def VMOVQI2PQIrm : I<0x7E, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
5046                     "vmovq\t{$src, $dst|$dst, $src}",
5047                     [(set VR128:$dst,
5048                       (v2i64 (scalar_to_vector (loadi64 addr:$src))))]>, XS,
5049                     VEX, Requires<[UseAVX]>;
5050 def MOVQI2PQIrm : I<0x7E, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
5051                     "movq\t{$src, $dst|$dst, $src}",
5052                     [(set VR128:$dst,
5053                       (v2i64 (scalar_to_vector (loadi64 addr:$src))))],
5054                       IIC_SSE_MOVDQ>, XS,
5055                     Requires<[UseSSE2]>; // SSE2 instruction with XS Prefix
5056 } // SchedRW
5057
5058 //===---------------------------------------------------------------------===//
5059 // Move Packed Quadword Int to Quadword Int
5060 //
5061 let SchedRW = [WriteStore] in {
5062 def VMOVPQI2QImr : VS2I<0xD6, MRMDestMem, (outs), (ins i64mem:$dst, VR128:$src),
5063                       "movq\t{$src, $dst|$dst, $src}",
5064                       [(store (i64 (vector_extract (v2i64 VR128:$src),
5065                                     (iPTR 0))), addr:$dst)],
5066                                     IIC_SSE_MOVDQ>, VEX;
5067 def MOVPQI2QImr : S2I<0xD6, MRMDestMem, (outs), (ins i64mem:$dst, VR128:$src),
5068                       "movq\t{$src, $dst|$dst, $src}",
5069                       [(store (i64 (vector_extract (v2i64 VR128:$src),
5070                                     (iPTR 0))), addr:$dst)],
5071                                     IIC_SSE_MOVDQ>;
5072 } // SchedRW
5073
5074 // For disassembler only
5075 let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0,
5076     SchedRW = [WriteVecLogic] in {
5077 def VMOVPQI2QIrr : VS2I<0xD6, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
5078                      "movq\t{$src, $dst|$dst, $src}", [], IIC_SSE_MOVQ_RR>, VEX;
5079 def MOVPQI2QIrr : S2I<0xD6, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
5080                       "movq\t{$src, $dst|$dst, $src}", [], IIC_SSE_MOVQ_RR>;
5081 }
5082
5083 //===---------------------------------------------------------------------===//
5084 // Store / copy lower 64-bits of a XMM register.
5085 //
5086 let Predicates = [UseAVX] in
5087 def : Pat<(int_x86_sse2_storel_dq addr:$dst, VR128:$src),
5088           (VMOVPQI2QImr addr:$dst, VR128:$src)>;
5089 let Predicates = [UseSSE2] in
5090 def : Pat<(int_x86_sse2_storel_dq addr:$dst, VR128:$src),
5091           (MOVPQI2QImr addr:$dst, VR128:$src)>;
5092
5093 let isCodeGenOnly = 1, AddedComplexity = 20 in {
5094 def VMOVZQI2PQIrm : I<0x7E, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
5095                      "vmovq\t{$src, $dst|$dst, $src}",
5096                      [(set VR128:$dst,
5097                        (v2i64 (X86vzmovl (v2i64 (scalar_to_vector
5098                                                  (loadi64 addr:$src))))))],
5099                                                  IIC_SSE_MOVDQ>,
5100                      XS, VEX, Requires<[UseAVX]>, Sched<[WriteLoad]>;
5101
5102 def MOVZQI2PQIrm : I<0x7E, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
5103                      "movq\t{$src, $dst|$dst, $src}",
5104                      [(set VR128:$dst,
5105                        (v2i64 (X86vzmovl (v2i64 (scalar_to_vector
5106                                                  (loadi64 addr:$src))))))],
5107                                                  IIC_SSE_MOVDQ>,
5108                      XS, Requires<[UseSSE2]>, Sched<[WriteLoad]>;
5109 }
5110
5111 let Predicates = [UseAVX], AddedComplexity = 20 in {
5112   def : Pat<(v2i64 (X86vzmovl (bc_v2i64 (loadv4f32 addr:$src)))),
5113             (VMOVZQI2PQIrm addr:$src)>;
5114   def : Pat<(v2i64 (X86vzload addr:$src)),
5115             (VMOVZQI2PQIrm addr:$src)>;
5116 }
5117
5118 let Predicates = [UseSSE2], AddedComplexity = 20 in {
5119   def : Pat<(v2i64 (X86vzmovl (bc_v2i64 (loadv4f32 addr:$src)))),
5120             (MOVZQI2PQIrm addr:$src)>;
5121   def : Pat<(v2i64 (X86vzload addr:$src)), (MOVZQI2PQIrm addr:$src)>;
5122 }
5123
5124 let Predicates = [HasAVX] in {
5125 def : Pat<(v4i64 (alignedX86vzload addr:$src)),
5126           (SUBREG_TO_REG (i32 0), (VMOVAPSrm addr:$src), sub_xmm)>;
5127 def : Pat<(v4i64 (X86vzload addr:$src)),
5128           (SUBREG_TO_REG (i32 0), (VMOVUPSrm addr:$src), sub_xmm)>;
5129 }
5130
5131 //===---------------------------------------------------------------------===//
5132 // Moving from XMM to XMM and clear upper 64 bits. Note, there is a bug in
5133 // IA32 document. movq xmm1, xmm2 does clear the high bits.
5134 //
5135 let SchedRW = [WriteVecLogic] in {
5136 let AddedComplexity = 15 in
5137 def VMOVZPQILo2PQIrr : I<0x7E, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
5138                         "vmovq\t{$src, $dst|$dst, $src}",
5139                     [(set VR128:$dst, (v2i64 (X86vzmovl (v2i64 VR128:$src))))],
5140                     IIC_SSE_MOVQ_RR>,
5141                       XS, VEX, Requires<[UseAVX]>;
5142 let AddedComplexity = 15 in
5143 def MOVZPQILo2PQIrr : I<0x7E, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
5144                         "movq\t{$src, $dst|$dst, $src}",
5145                     [(set VR128:$dst, (v2i64 (X86vzmovl (v2i64 VR128:$src))))],
5146                     IIC_SSE_MOVQ_RR>,
5147                       XS, Requires<[UseSSE2]>;
5148 } // SchedRW
5149
5150 let isCodeGenOnly = 1, SchedRW = [WriteVecLogicLd] in {
5151 let AddedComplexity = 20 in
5152 def VMOVZPQILo2PQIrm : I<0x7E, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
5153                         "vmovq\t{$src, $dst|$dst, $src}",
5154                     [(set VR128:$dst, (v2i64 (X86vzmovl
5155                                              (loadv2i64 addr:$src))))],
5156                                              IIC_SSE_MOVDQ>,
5157                       XS, VEX, Requires<[UseAVX]>;
5158 let AddedComplexity = 20 in {
5159 def MOVZPQILo2PQIrm : I<0x7E, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
5160                         "movq\t{$src, $dst|$dst, $src}",
5161                     [(set VR128:$dst, (v2i64 (X86vzmovl
5162                                              (loadv2i64 addr:$src))))],
5163                                              IIC_SSE_MOVDQ>,
5164                       XS, Requires<[UseSSE2]>;
5165 }
5166 } // isCodeGenOnly, SchedRW
5167
5168 let AddedComplexity = 20 in {
5169   let Predicates = [UseAVX] in {
5170     def : Pat<(v2f64 (X86vzmovl (v2f64 VR128:$src))),
5171               (VMOVZPQILo2PQIrr VR128:$src)>;
5172   }
5173   let Predicates = [UseSSE2] in {
5174     def : Pat<(v2f64 (X86vzmovl (v2f64 VR128:$src))),
5175               (MOVZPQILo2PQIrr VR128:$src)>;
5176   }
5177 }
5178
5179 //===---------------------------------------------------------------------===//
5180 // SSE3 - Replicate Single FP - MOVSHDUP and MOVSLDUP
5181 //===---------------------------------------------------------------------===//
5182 multiclass sse3_replicate_sfp<bits<8> op, SDNode OpNode, string OpcodeStr,
5183                               ValueType vt, RegisterClass RC, PatFrag mem_frag,
5184                               X86MemOperand x86memop> {
5185 def rr : S3SI<op, MRMSrcReg, (outs RC:$dst), (ins RC:$src),
5186                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5187                       [(set RC:$dst, (vt (OpNode RC:$src)))],
5188                       IIC_SSE_MOV_LH>, Sched<[WriteFShuffle]>;
5189 def rm : S3SI<op, MRMSrcMem, (outs RC:$dst), (ins x86memop:$src),
5190                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5191                       [(set RC:$dst, (OpNode (mem_frag addr:$src)))],
5192                       IIC_SSE_MOV_LH>, Sched<[WriteLoad]>;
5193 }
5194
5195 let Predicates = [HasAVX] in {
5196   defm VMOVSHDUP  : sse3_replicate_sfp<0x16, X86Movshdup, "vmovshdup",
5197                                        v4f32, VR128, loadv4f32, f128mem>, VEX;
5198   defm VMOVSLDUP  : sse3_replicate_sfp<0x12, X86Movsldup, "vmovsldup",
5199                                        v4f32, VR128, loadv4f32, f128mem>, VEX;
5200   defm VMOVSHDUPY : sse3_replicate_sfp<0x16, X86Movshdup, "vmovshdup",
5201                                  v8f32, VR256, loadv8f32, f256mem>, VEX, VEX_L;
5202   defm VMOVSLDUPY : sse3_replicate_sfp<0x12, X86Movsldup, "vmovsldup",
5203                                  v8f32, VR256, loadv8f32, f256mem>, VEX, VEX_L;
5204 }
5205 defm MOVSHDUP : sse3_replicate_sfp<0x16, X86Movshdup, "movshdup", v4f32, VR128,
5206                                    memopv4f32, f128mem>;
5207 defm MOVSLDUP : sse3_replicate_sfp<0x12, X86Movsldup, "movsldup", v4f32, VR128,
5208                                    memopv4f32, f128mem>;
5209
5210 let Predicates = [HasAVX] in {
5211   def : Pat<(v4i32 (X86Movshdup VR128:$src)),
5212             (VMOVSHDUPrr VR128:$src)>;
5213   def : Pat<(v4i32 (X86Movshdup (bc_v4i32 (loadv2i64 addr:$src)))),
5214             (VMOVSHDUPrm addr:$src)>;
5215   def : Pat<(v4i32 (X86Movsldup VR128:$src)),
5216             (VMOVSLDUPrr VR128:$src)>;
5217   def : Pat<(v4i32 (X86Movsldup (bc_v4i32 (loadv2i64 addr:$src)))),
5218             (VMOVSLDUPrm addr:$src)>;
5219   def : Pat<(v8i32 (X86Movshdup VR256:$src)),
5220             (VMOVSHDUPYrr VR256:$src)>;
5221   def : Pat<(v8i32 (X86Movshdup (bc_v8i32 (loadv4i64 addr:$src)))),
5222             (VMOVSHDUPYrm addr:$src)>;
5223   def : Pat<(v8i32 (X86Movsldup VR256:$src)),
5224             (VMOVSLDUPYrr VR256:$src)>;
5225   def : Pat<(v8i32 (X86Movsldup (bc_v8i32 (loadv4i64 addr:$src)))),
5226             (VMOVSLDUPYrm addr:$src)>;
5227 }
5228
5229 let Predicates = [UseSSE3] in {
5230   def : Pat<(v4i32 (X86Movshdup VR128:$src)),
5231             (MOVSHDUPrr VR128:$src)>;
5232   def : Pat<(v4i32 (X86Movshdup (bc_v4i32 (memopv2i64 addr:$src)))),
5233             (MOVSHDUPrm addr:$src)>;
5234   def : Pat<(v4i32 (X86Movsldup VR128:$src)),
5235             (MOVSLDUPrr VR128:$src)>;
5236   def : Pat<(v4i32 (X86Movsldup (bc_v4i32 (memopv2i64 addr:$src)))),
5237             (MOVSLDUPrm addr:$src)>;
5238 }
5239
5240 //===---------------------------------------------------------------------===//
5241 // SSE3 - Replicate Double FP - MOVDDUP
5242 //===---------------------------------------------------------------------===//
5243
5244 multiclass sse3_replicate_dfp<string OpcodeStr> {
5245 let neverHasSideEffects = 1 in
5246 def rr  : S3DI<0x12, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
5247                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5248                     [], IIC_SSE_MOV_LH>, Sched<[WriteFShuffle]>;
5249 def rm  : S3DI<0x12, MRMSrcMem, (outs VR128:$dst), (ins f64mem:$src),
5250                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5251                     [(set VR128:$dst,
5252                       (v2f64 (X86Movddup
5253                               (scalar_to_vector (loadf64 addr:$src)))))],
5254                               IIC_SSE_MOV_LH>, Sched<[WriteLoad]>;
5255 }
5256
5257 // FIXME: Merge with above classe when there're patterns for the ymm version
5258 multiclass sse3_replicate_dfp_y<string OpcodeStr> {
5259 def rr  : S3DI<0x12, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
5260                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5261                     [(set VR256:$dst, (v4f64 (X86Movddup VR256:$src)))]>,
5262                     Sched<[WriteFShuffle]>;
5263 def rm  : S3DI<0x12, MRMSrcMem, (outs VR256:$dst), (ins f256mem:$src),
5264                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5265                     [(set VR256:$dst,
5266                       (v4f64 (X86Movddup
5267                               (scalar_to_vector (loadf64 addr:$src)))))]>,
5268                     Sched<[WriteLoad]>;
5269 }
5270
5271 let Predicates = [HasAVX] in {
5272   defm VMOVDDUP  : sse3_replicate_dfp<"vmovddup">, VEX;
5273   defm VMOVDDUPY : sse3_replicate_dfp_y<"vmovddup">, VEX, VEX_L;
5274 }
5275
5276 defm MOVDDUP : sse3_replicate_dfp<"movddup">;
5277
5278 let Predicates = [HasAVX] in {
5279   def : Pat<(X86Movddup (loadv2f64 addr:$src)),
5280             (VMOVDDUPrm addr:$src)>, Requires<[HasAVX]>;
5281   def : Pat<(X86Movddup (bc_v2f64 (loadv4f32 addr:$src))),
5282             (VMOVDDUPrm addr:$src)>, Requires<[HasAVX]>;
5283   def : Pat<(X86Movddup (bc_v2f64 (loadv2i64 addr:$src))),
5284             (VMOVDDUPrm addr:$src)>, Requires<[HasAVX]>;
5285   def : Pat<(X86Movddup (bc_v2f64
5286                              (v2i64 (scalar_to_vector (loadi64 addr:$src))))),
5287             (VMOVDDUPrm addr:$src)>, Requires<[HasAVX]>;
5288
5289   // 256-bit version
5290   def : Pat<(X86Movddup (loadv4f64 addr:$src)),
5291             (VMOVDDUPYrm addr:$src)>;
5292   def : Pat<(X86Movddup (loadv4i64 addr:$src)),
5293             (VMOVDDUPYrm addr:$src)>;
5294   def : Pat<(X86Movddup (v4i64 (scalar_to_vector (loadi64 addr:$src)))),
5295             (VMOVDDUPYrm addr:$src)>;
5296   def : Pat<(X86Movddup (v4i64 VR256:$src)),
5297             (VMOVDDUPYrr VR256:$src)>;
5298 }
5299
5300 let Predicates = [UseAVX, OptForSize] in {
5301   def : Pat<(v2f64 (X86VBroadcast (loadf64 addr:$src))),
5302   (VMOVDDUPrm addr:$src)>;
5303   def : Pat<(v2i64 (X86VBroadcast (loadi64 addr:$src))),
5304   (VMOVDDUPrm addr:$src)>;
5305 }
5306
5307 let Predicates = [UseSSE3] in {
5308   def : Pat<(X86Movddup (memopv2f64 addr:$src)),
5309             (MOVDDUPrm addr:$src)>;
5310   def : Pat<(X86Movddup (bc_v2f64 (memopv4f32 addr:$src))),
5311             (MOVDDUPrm addr:$src)>;
5312   def : Pat<(X86Movddup (bc_v2f64 (memopv2i64 addr:$src))),
5313             (MOVDDUPrm addr:$src)>;
5314   def : Pat<(X86Movddup (bc_v2f64
5315                              (v2i64 (scalar_to_vector (loadi64 addr:$src))))),
5316             (MOVDDUPrm addr:$src)>;
5317 }
5318
5319 //===---------------------------------------------------------------------===//
5320 // SSE3 - Move Unaligned Integer
5321 //===---------------------------------------------------------------------===//
5322
5323 let SchedRW = [WriteLoad] in {
5324 let Predicates = [HasAVX] in {
5325   def VLDDQUrm : S3DI<0xF0, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
5326                    "vlddqu\t{$src, $dst|$dst, $src}",
5327                    [(set VR128:$dst, (int_x86_sse3_ldu_dq addr:$src))]>, VEX;
5328   def VLDDQUYrm : S3DI<0xF0, MRMSrcMem, (outs VR256:$dst), (ins i256mem:$src),
5329                    "vlddqu\t{$src, $dst|$dst, $src}",
5330                    [(set VR256:$dst, (int_x86_avx_ldu_dq_256 addr:$src))]>,
5331                    VEX, VEX_L;
5332 }
5333 def LDDQUrm : S3DI<0xF0, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
5334                    "lddqu\t{$src, $dst|$dst, $src}",
5335                    [(set VR128:$dst, (int_x86_sse3_ldu_dq addr:$src))],
5336                    IIC_SSE_LDDQU>;
5337 }
5338
5339 //===---------------------------------------------------------------------===//
5340 // SSE3 - Arithmetic
5341 //===---------------------------------------------------------------------===//
5342
5343 multiclass sse3_addsub<Intrinsic Int, string OpcodeStr, RegisterClass RC,
5344                        X86MemOperand x86memop, OpndItins itins,
5345                        bit Is2Addr = 1> {
5346   def rr : I<0xD0, MRMSrcReg,
5347        (outs RC:$dst), (ins RC:$src1, RC:$src2),
5348        !if(Is2Addr,
5349            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5350            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5351        [(set RC:$dst, (Int RC:$src1, RC:$src2))], itins.rr>,
5352        Sched<[itins.Sched]>;
5353   def rm : I<0xD0, MRMSrcMem,
5354        (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
5355        !if(Is2Addr,
5356            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5357            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5358        [(set RC:$dst, (Int RC:$src1, (memop addr:$src2)))], itins.rr>,
5359        Sched<[itins.Sched.Folded, ReadAfterLd]>;
5360 }
5361
5362 let Predicates = [HasAVX] in {
5363   let ExeDomain = SSEPackedSingle in {
5364     defm VADDSUBPS : sse3_addsub<int_x86_sse3_addsub_ps, "vaddsubps", VR128,
5365                                  f128mem, SSE_ALU_F32P, 0>, XD, VEX_4V;
5366     defm VADDSUBPSY : sse3_addsub<int_x86_avx_addsub_ps_256, "vaddsubps", VR256,
5367                                f256mem, SSE_ALU_F32P, 0>, XD, VEX_4V, VEX_L;
5368   }
5369   let ExeDomain = SSEPackedDouble in {
5370     defm VADDSUBPD : sse3_addsub<int_x86_sse3_addsub_pd, "vaddsubpd", VR128,
5371                                  f128mem, SSE_ALU_F64P, 0>, PD, VEX_4V;
5372     defm VADDSUBPDY : sse3_addsub<int_x86_avx_addsub_pd_256, "vaddsubpd", VR256,
5373                            f256mem, SSE_ALU_F64P, 0>, PD, VEX_4V, VEX_L;
5374   }
5375 }
5376 let Constraints = "$src1 = $dst", Predicates = [UseSSE3] in {
5377   let ExeDomain = SSEPackedSingle in
5378   defm ADDSUBPS : sse3_addsub<int_x86_sse3_addsub_ps, "addsubps", VR128,
5379                               f128mem, SSE_ALU_F32P>, XD;
5380   let ExeDomain = SSEPackedDouble in
5381   defm ADDSUBPD : sse3_addsub<int_x86_sse3_addsub_pd, "addsubpd", VR128,
5382                               f128mem, SSE_ALU_F64P>, PD;
5383 }
5384
5385 // Patterns used to select 'addsub' instructions.
5386 let Predicates = [HasAVX] in {
5387   def : Pat<(v4f32 (X86Addsub (v4f32 VR128:$lhs), (v4f32 VR128:$rhs))),
5388             (VADDSUBPSrr VR128:$lhs, VR128:$rhs)>;
5389   def : Pat<(v4f32 (X86Addsub (v4f32 VR128:$lhs), (v4f32 (memop addr:$rhs)))),
5390             (VADDSUBPSrm VR128:$lhs, f128mem:$rhs)>;
5391   def : Pat<(v2f64 (X86Addsub (v2f64 VR128:$lhs), (v2f64 VR128:$rhs))),
5392             (VADDSUBPDrr VR128:$lhs, VR128:$rhs)>;
5393   def : Pat<(v2f64 (X86Addsub (v2f64 VR128:$lhs), (v2f64 (memop addr:$rhs)))),
5394             (VADDSUBPDrm VR128:$lhs, f128mem:$rhs)>;
5395
5396   def : Pat<(v8f32 (X86Addsub (v8f32 VR256:$lhs), (v8f32 VR256:$rhs))),
5397             (VADDSUBPSYrr VR256:$lhs, VR256:$rhs)>;
5398   def : Pat<(v8f32 (X86Addsub (v8f32 VR256:$lhs), (v8f32 (memop addr:$rhs)))),
5399             (VADDSUBPSYrm VR256:$lhs, f256mem:$rhs)>;
5400   def : Pat<(v4f64 (X86Addsub (v4f64 VR256:$lhs), (v4f64 VR256:$rhs))),
5401             (VADDSUBPDYrr VR256:$lhs, VR256:$rhs)>;
5402   def : Pat<(v4f64 (X86Addsub (v4f64 VR256:$lhs), (v4f64 (memop addr:$rhs)))),
5403             (VADDSUBPDYrm VR256:$lhs, f256mem:$rhs)>;
5404 }
5405
5406 let Predicates = [UseSSE3] in {
5407   def : Pat<(v4f32 (X86Addsub (v4f32 VR128:$lhs), (v4f32 VR128:$rhs))),
5408             (ADDSUBPSrr VR128:$lhs, VR128:$rhs)>;
5409   def : Pat<(v4f32 (X86Addsub (v4f32 VR128:$lhs), (v4f32 (memop addr:$rhs)))),
5410             (ADDSUBPSrm VR128:$lhs, f128mem:$rhs)>;
5411   def : Pat<(v2f64 (X86Addsub (v2f64 VR128:$lhs), (v2f64 VR128:$rhs))),
5412             (ADDSUBPDrr VR128:$lhs, VR128:$rhs)>;
5413   def : Pat<(v2f64 (X86Addsub (v2f64 VR128:$lhs), (v2f64 (memop addr:$rhs)))),
5414             (ADDSUBPDrm VR128:$lhs, f128mem:$rhs)>;
5415 }
5416
5417 //===---------------------------------------------------------------------===//
5418 // SSE3 Instructions
5419 //===---------------------------------------------------------------------===//
5420
5421 // Horizontal ops
5422 multiclass S3D_Int<bits<8> o, string OpcodeStr, ValueType vt, RegisterClass RC,
5423                    X86MemOperand x86memop, SDNode OpNode, bit Is2Addr = 1> {
5424   def rr : S3DI<o, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
5425        !if(Is2Addr,
5426          !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5427          !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5428       [(set RC:$dst, (vt (OpNode RC:$src1, RC:$src2)))], IIC_SSE_HADDSUB_RR>,
5429       Sched<[WriteFAdd]>;
5430
5431   def rm : S3DI<o, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
5432        !if(Is2Addr,
5433          !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5434          !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5435       [(set RC:$dst, (vt (OpNode RC:$src1, (memop addr:$src2))))],
5436         IIC_SSE_HADDSUB_RM>, Sched<[WriteFAddLd, ReadAfterLd]>;
5437 }
5438 multiclass S3_Int<bits<8> o, string OpcodeStr, ValueType vt, RegisterClass RC,
5439                   X86MemOperand x86memop, SDNode OpNode, bit Is2Addr = 1> {
5440   def rr : S3I<o, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
5441        !if(Is2Addr,
5442          !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5443          !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5444       [(set RC:$dst, (vt (OpNode RC:$src1, RC:$src2)))], IIC_SSE_HADDSUB_RR>,
5445       Sched<[WriteFAdd]>;
5446
5447   def rm : S3I<o, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
5448        !if(Is2Addr,
5449          !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5450          !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5451       [(set RC:$dst, (vt (OpNode RC:$src1, (memop addr:$src2))))],
5452         IIC_SSE_HADDSUB_RM>, Sched<[WriteFAddLd, ReadAfterLd]>;
5453 }
5454
5455 let Predicates = [HasAVX] in {
5456   let ExeDomain = SSEPackedSingle in {
5457     defm VHADDPS  : S3D_Int<0x7C, "vhaddps", v4f32, VR128, f128mem,
5458                             X86fhadd, 0>, VEX_4V;
5459     defm VHSUBPS  : S3D_Int<0x7D, "vhsubps", v4f32, VR128, f128mem,
5460                             X86fhsub, 0>, VEX_4V;
5461     defm VHADDPSY : S3D_Int<0x7C, "vhaddps", v8f32, VR256, f256mem,
5462                             X86fhadd, 0>, VEX_4V, VEX_L;
5463     defm VHSUBPSY : S3D_Int<0x7D, "vhsubps", v8f32, VR256, f256mem,
5464                             X86fhsub, 0>, VEX_4V, VEX_L;
5465   }
5466   let ExeDomain = SSEPackedDouble in {
5467     defm VHADDPD  : S3_Int <0x7C, "vhaddpd", v2f64, VR128, f128mem,
5468                             X86fhadd, 0>, VEX_4V;
5469     defm VHSUBPD  : S3_Int <0x7D, "vhsubpd", v2f64, VR128, f128mem,
5470                             X86fhsub, 0>, VEX_4V;
5471     defm VHADDPDY : S3_Int <0x7C, "vhaddpd", v4f64, VR256, f256mem,
5472                             X86fhadd, 0>, VEX_4V, VEX_L;
5473     defm VHSUBPDY : S3_Int <0x7D, "vhsubpd", v4f64, VR256, f256mem,
5474                             X86fhsub, 0>, VEX_4V, VEX_L;
5475   }
5476 }
5477
5478 let Constraints = "$src1 = $dst" in {
5479   let ExeDomain = SSEPackedSingle in {
5480     defm HADDPS : S3D_Int<0x7C, "haddps", v4f32, VR128, f128mem, X86fhadd>;
5481     defm HSUBPS : S3D_Int<0x7D, "hsubps", v4f32, VR128, f128mem, X86fhsub>;
5482   }
5483   let ExeDomain = SSEPackedDouble in {
5484     defm HADDPD : S3_Int<0x7C, "haddpd", v2f64, VR128, f128mem, X86fhadd>;
5485     defm HSUBPD : S3_Int<0x7D, "hsubpd", v2f64, VR128, f128mem, X86fhsub>;
5486   }
5487 }
5488
5489 //===---------------------------------------------------------------------===//
5490 // SSSE3 - Packed Absolute Instructions
5491 //===---------------------------------------------------------------------===//
5492
5493
5494 /// SS3I_unop_rm_int - Simple SSSE3 unary op whose type can be v*{i8,i16,i32}.
5495 multiclass SS3I_unop_rm_int<bits<8> opc, string OpcodeStr,
5496                             Intrinsic IntId128> {
5497   def rr128 : SS38I<opc, MRMSrcReg, (outs VR128:$dst),
5498                     (ins VR128:$src),
5499                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5500                     [(set VR128:$dst, (IntId128 VR128:$src))], IIC_SSE_PABS_RR>,
5501                     Sched<[WriteVecALU]>;
5502
5503   def rm128 : SS38I<opc, MRMSrcMem, (outs VR128:$dst),
5504                     (ins i128mem:$src),
5505                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5506                     [(set VR128:$dst,
5507                       (IntId128
5508                        (bitconvert (memopv2i64 addr:$src))))], IIC_SSE_PABS_RM>,
5509                     Sched<[WriteVecALULd]>;
5510 }
5511
5512 /// SS3I_unop_rm_int_y - Simple SSSE3 unary op whose type can be v*{i8,i16,i32}.
5513 multiclass SS3I_unop_rm_int_y<bits<8> opc, string OpcodeStr,
5514                               Intrinsic IntId256> {
5515   def rr256 : SS38I<opc, MRMSrcReg, (outs VR256:$dst),
5516                     (ins VR256:$src),
5517                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5518                     [(set VR256:$dst, (IntId256 VR256:$src))]>,
5519                     Sched<[WriteVecALU]>;
5520
5521   def rm256 : SS38I<opc, MRMSrcMem, (outs VR256:$dst),
5522                     (ins i256mem:$src),
5523                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5524                     [(set VR256:$dst,
5525                       (IntId256
5526                        (bitconvert (memopv4i64 addr:$src))))]>,
5527                     Sched<[WriteVecALULd]>;
5528 }
5529
5530 // Helper fragments to match sext vXi1 to vXiY.
5531 def v16i1sextv16i8 : PatLeaf<(v16i8 (X86pcmpgt (bc_v16i8 (v4i32 immAllZerosV)),
5532                                                VR128:$src))>;
5533 def v8i1sextv8i16  : PatLeaf<(v8i16 (X86vsrai VR128:$src, (i8 15)))>;
5534 def v4i1sextv4i32  : PatLeaf<(v4i32 (X86vsrai VR128:$src, (i8 31)))>;
5535 def v32i1sextv32i8 : PatLeaf<(v32i8 (X86pcmpgt (bc_v32i8 (v8i32 immAllZerosV)),
5536                                                VR256:$src))>;
5537 def v16i1sextv16i16: PatLeaf<(v16i16 (X86vsrai VR256:$src, (i8 15)))>;
5538 def v8i1sextv8i32  : PatLeaf<(v8i32 (X86vsrai VR256:$src, (i8 31)))>;
5539
5540 let Predicates = [HasAVX] in {
5541   defm VPABSB  : SS3I_unop_rm_int<0x1C, "vpabsb",
5542                                   int_x86_ssse3_pabs_b_128>, VEX;
5543   defm VPABSW  : SS3I_unop_rm_int<0x1D, "vpabsw",
5544                                   int_x86_ssse3_pabs_w_128>, VEX;
5545   defm VPABSD  : SS3I_unop_rm_int<0x1E, "vpabsd",
5546                                   int_x86_ssse3_pabs_d_128>, VEX;
5547
5548   def : Pat<(xor
5549             (bc_v2i64 (v16i1sextv16i8)),
5550             (bc_v2i64 (add (v16i8 VR128:$src), (v16i1sextv16i8)))),
5551             (VPABSBrr128 VR128:$src)>;
5552   def : Pat<(xor
5553             (bc_v2i64 (v8i1sextv8i16)),
5554             (bc_v2i64 (add (v8i16 VR128:$src), (v8i1sextv8i16)))),
5555             (VPABSWrr128 VR128:$src)>;
5556   def : Pat<(xor
5557             (bc_v2i64 (v4i1sextv4i32)),
5558             (bc_v2i64 (add (v4i32 VR128:$src), (v4i1sextv4i32)))),
5559             (VPABSDrr128 VR128:$src)>;
5560 }
5561
5562 let Predicates = [HasAVX2] in {
5563   defm VPABSB  : SS3I_unop_rm_int_y<0x1C, "vpabsb",
5564                                     int_x86_avx2_pabs_b>, VEX, VEX_L;
5565   defm VPABSW  : SS3I_unop_rm_int_y<0x1D, "vpabsw",
5566                                     int_x86_avx2_pabs_w>, VEX, VEX_L;
5567   defm VPABSD  : SS3I_unop_rm_int_y<0x1E, "vpabsd",
5568                                     int_x86_avx2_pabs_d>, VEX, VEX_L;
5569
5570   def : Pat<(xor
5571             (bc_v4i64 (v32i1sextv32i8)),
5572             (bc_v4i64 (add (v32i8 VR256:$src), (v32i1sextv32i8)))),
5573             (VPABSBrr256 VR256:$src)>;
5574   def : Pat<(xor
5575             (bc_v4i64 (v16i1sextv16i16)),
5576             (bc_v4i64 (add (v16i16 VR256:$src), (v16i1sextv16i16)))),
5577             (VPABSWrr256 VR256:$src)>;
5578   def : Pat<(xor
5579             (bc_v4i64 (v8i1sextv8i32)),
5580             (bc_v4i64 (add (v8i32 VR256:$src), (v8i1sextv8i32)))),
5581             (VPABSDrr256 VR256:$src)>;
5582 }
5583
5584 defm PABSB : SS3I_unop_rm_int<0x1C, "pabsb",
5585                               int_x86_ssse3_pabs_b_128>;
5586 defm PABSW : SS3I_unop_rm_int<0x1D, "pabsw",
5587                               int_x86_ssse3_pabs_w_128>;
5588 defm PABSD : SS3I_unop_rm_int<0x1E, "pabsd",
5589                               int_x86_ssse3_pabs_d_128>;
5590
5591 let Predicates = [HasSSSE3] in {
5592   def : Pat<(xor
5593             (bc_v2i64 (v16i1sextv16i8)),
5594             (bc_v2i64 (add (v16i8 VR128:$src), (v16i1sextv16i8)))),
5595             (PABSBrr128 VR128:$src)>;
5596   def : Pat<(xor
5597             (bc_v2i64 (v8i1sextv8i16)),
5598             (bc_v2i64 (add (v8i16 VR128:$src), (v8i1sextv8i16)))),
5599             (PABSWrr128 VR128:$src)>;
5600   def : Pat<(xor
5601             (bc_v2i64 (v4i1sextv4i32)),
5602             (bc_v2i64 (add (v4i32 VR128:$src), (v4i1sextv4i32)))),
5603             (PABSDrr128 VR128:$src)>;
5604 }
5605
5606 //===---------------------------------------------------------------------===//
5607 // SSSE3 - Packed Binary Operator Instructions
5608 //===---------------------------------------------------------------------===//
5609
5610 let Sched = WriteVecALU in {
5611 def SSE_PHADDSUBD : OpndItins<
5612   IIC_SSE_PHADDSUBD_RR, IIC_SSE_PHADDSUBD_RM
5613 >;
5614 def SSE_PHADDSUBSW : OpndItins<
5615   IIC_SSE_PHADDSUBSW_RR, IIC_SSE_PHADDSUBSW_RM
5616 >;
5617 def SSE_PHADDSUBW : OpndItins<
5618   IIC_SSE_PHADDSUBW_RR, IIC_SSE_PHADDSUBW_RM
5619 >;
5620 }
5621 let Sched = WriteShuffle in
5622 def SSE_PSHUFB : OpndItins<
5623   IIC_SSE_PSHUFB_RR, IIC_SSE_PSHUFB_RM
5624 >;
5625 let Sched = WriteVecALU in
5626 def SSE_PSIGN : OpndItins<
5627   IIC_SSE_PSIGN_RR, IIC_SSE_PSIGN_RM
5628 >;
5629 let Sched = WriteVecIMul in
5630 def SSE_PMULHRSW : OpndItins<
5631   IIC_SSE_PMULHRSW, IIC_SSE_PMULHRSW
5632 >;
5633
5634 /// SS3I_binop_rm - Simple SSSE3 bin op
5635 multiclass SS3I_binop_rm<bits<8> opc, string OpcodeStr, SDNode OpNode,
5636                          ValueType OpVT, RegisterClass RC, PatFrag memop_frag,
5637                          X86MemOperand x86memop, OpndItins itins,
5638                          bit Is2Addr = 1> {
5639   let isCommutable = 1 in
5640   def rr : SS38I<opc, MRMSrcReg, (outs RC:$dst),
5641        (ins RC:$src1, RC:$src2),
5642        !if(Is2Addr,
5643          !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5644          !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5645        [(set RC:$dst, (OpVT (OpNode RC:$src1, RC:$src2)))], itins.rr>,
5646        Sched<[itins.Sched]>;
5647   def rm : SS38I<opc, MRMSrcMem, (outs RC:$dst),
5648        (ins RC:$src1, x86memop:$src2),
5649        !if(Is2Addr,
5650          !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5651          !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5652        [(set RC:$dst,
5653          (OpVT (OpNode RC:$src1,
5654           (bitconvert (memop_frag addr:$src2)))))], itins.rm>,
5655        Sched<[itins.Sched.Folded, ReadAfterLd]>;
5656 }
5657
5658 /// SS3I_binop_rm_int - Simple SSSE3 bin op whose type can be v*{i8,i16,i32}.
5659 multiclass SS3I_binop_rm_int<bits<8> opc, string OpcodeStr,
5660                              Intrinsic IntId128, OpndItins itins,
5661                              bit Is2Addr = 1> {
5662   let isCommutable = 1 in
5663   def rr128 : SS38I<opc, MRMSrcReg, (outs VR128:$dst),
5664        (ins VR128:$src1, VR128:$src2),
5665        !if(Is2Addr,
5666          !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5667          !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5668        [(set VR128:$dst, (IntId128 VR128:$src1, VR128:$src2))]>,
5669        Sched<[itins.Sched]>;
5670   def rm128 : SS38I<opc, MRMSrcMem, (outs VR128:$dst),
5671        (ins VR128:$src1, i128mem:$src2),
5672        !if(Is2Addr,
5673          !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5674          !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5675        [(set VR128:$dst,
5676          (IntId128 VR128:$src1,
5677           (bitconvert (memopv2i64 addr:$src2))))]>,
5678        Sched<[itins.Sched.Folded, ReadAfterLd]>;
5679 }
5680
5681 multiclass SS3I_binop_rm_int_y<bits<8> opc, string OpcodeStr,
5682                                Intrinsic IntId256,
5683                                X86FoldableSchedWrite Sched> {
5684   let isCommutable = 1 in
5685   def rr256 : SS38I<opc, MRMSrcReg, (outs VR256:$dst),
5686        (ins VR256:$src1, VR256:$src2),
5687        !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5688        [(set VR256:$dst, (IntId256 VR256:$src1, VR256:$src2))]>,
5689        Sched<[Sched]>;
5690   def rm256 : SS38I<opc, MRMSrcMem, (outs VR256:$dst),
5691        (ins VR256:$src1, i256mem:$src2),
5692        !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5693        [(set VR256:$dst,
5694          (IntId256 VR256:$src1, (bitconvert (loadv4i64 addr:$src2))))]>,
5695        Sched<[Sched.Folded, ReadAfterLd]>;
5696 }
5697
5698 let ImmT = NoImm, Predicates = [HasAVX] in {
5699 let isCommutable = 0 in {
5700   defm VPHADDW    : SS3I_binop_rm<0x01, "vphaddw", X86hadd, v8i16, VR128,
5701                                   loadv2i64, i128mem,
5702                                   SSE_PHADDSUBW, 0>, VEX_4V;
5703   defm VPHADDD    : SS3I_binop_rm<0x02, "vphaddd", X86hadd, v4i32, VR128,
5704                                   loadv2i64, i128mem,
5705                                   SSE_PHADDSUBD, 0>, VEX_4V;
5706   defm VPHSUBW    : SS3I_binop_rm<0x05, "vphsubw", X86hsub, v8i16, VR128,
5707                                   loadv2i64, i128mem,
5708                                   SSE_PHADDSUBW, 0>, VEX_4V;
5709   defm VPHSUBD    : SS3I_binop_rm<0x06, "vphsubd", X86hsub, v4i32, VR128,
5710                                   loadv2i64, i128mem,
5711                                   SSE_PHADDSUBD, 0>, VEX_4V;
5712   defm VPSIGNB    : SS3I_binop_rm<0x08, "vpsignb", X86psign, v16i8, VR128,
5713                                   loadv2i64, i128mem,
5714                                   SSE_PSIGN, 0>, VEX_4V;
5715   defm VPSIGNW    : SS3I_binop_rm<0x09, "vpsignw", X86psign, v8i16, VR128,
5716                                   loadv2i64, i128mem,
5717                                   SSE_PSIGN, 0>, VEX_4V;
5718   defm VPSIGND    : SS3I_binop_rm<0x0A, "vpsignd", X86psign, v4i32, VR128,
5719                                   loadv2i64, i128mem,
5720                                   SSE_PSIGN, 0>, VEX_4V;
5721   defm VPSHUFB    : SS3I_binop_rm<0x00, "vpshufb", X86pshufb, v16i8, VR128,
5722                                   loadv2i64, i128mem,
5723                                   SSE_PSHUFB, 0>, VEX_4V;
5724   defm VPHADDSW   : SS3I_binop_rm_int<0x03, "vphaddsw",
5725                                       int_x86_ssse3_phadd_sw_128,
5726                                       SSE_PHADDSUBSW, 0>, VEX_4V;
5727   defm VPHSUBSW   : SS3I_binop_rm_int<0x07, "vphsubsw",
5728                                       int_x86_ssse3_phsub_sw_128,
5729                                       SSE_PHADDSUBSW, 0>, VEX_4V;
5730   defm VPMADDUBSW : SS3I_binop_rm_int<0x04, "vpmaddubsw",
5731                                       int_x86_ssse3_pmadd_ub_sw_128,
5732                                       SSE_PMADD, 0>, VEX_4V;
5733 }
5734 defm VPMULHRSW    : SS3I_binop_rm_int<0x0B, "vpmulhrsw",
5735                                       int_x86_ssse3_pmul_hr_sw_128,
5736                                       SSE_PMULHRSW, 0>, VEX_4V;
5737 }
5738
5739 let ImmT = NoImm, Predicates = [HasAVX2] in {
5740 let isCommutable = 0 in {
5741   defm VPHADDWY   : SS3I_binop_rm<0x01, "vphaddw", X86hadd, v16i16, VR256,
5742                                   loadv4i64, i256mem,
5743                                   SSE_PHADDSUBW, 0>, VEX_4V, VEX_L;
5744   defm VPHADDDY   : SS3I_binop_rm<0x02, "vphaddd", X86hadd, v8i32, VR256,
5745                                   loadv4i64, i256mem,
5746                                   SSE_PHADDSUBW, 0>, VEX_4V, VEX_L;
5747   defm VPHSUBWY   : SS3I_binop_rm<0x05, "vphsubw", X86hsub, v16i16, VR256,
5748                                   loadv4i64, i256mem,
5749                                   SSE_PHADDSUBW, 0>, VEX_4V, VEX_L;
5750   defm VPHSUBDY   : SS3I_binop_rm<0x06, "vphsubd", X86hsub, v8i32, VR256,
5751                                   loadv4i64, i256mem,
5752                                   SSE_PHADDSUBW, 0>, VEX_4V, VEX_L;
5753   defm VPSIGNBY   : SS3I_binop_rm<0x08, "vpsignb", X86psign, v32i8, VR256,
5754                                   loadv4i64, i256mem,
5755                                   SSE_PHADDSUBW, 0>, VEX_4V, VEX_L;
5756   defm VPSIGNWY   : SS3I_binop_rm<0x09, "vpsignw", X86psign, v16i16, VR256,
5757                                   loadv4i64, i256mem,
5758                                   SSE_PHADDSUBW, 0>, VEX_4V, VEX_L;
5759   defm VPSIGNDY   : SS3I_binop_rm<0x0A, "vpsignd", X86psign, v8i32, VR256,
5760                                   loadv4i64, i256mem,
5761                                   SSE_PHADDSUBW, 0>, VEX_4V, VEX_L;
5762   defm VPSHUFBY   : SS3I_binop_rm<0x00, "vpshufb", X86pshufb, v32i8, VR256,
5763                                   loadv4i64, i256mem,
5764                                   SSE_PSHUFB, 0>, VEX_4V, VEX_L;
5765   defm VPHADDSW   : SS3I_binop_rm_int_y<0x03, "vphaddsw",
5766                                         int_x86_avx2_phadd_sw,
5767                                         WriteVecALU>, VEX_4V, VEX_L;
5768   defm VPHSUBSW   : SS3I_binop_rm_int_y<0x07, "vphsubsw",
5769                                         int_x86_avx2_phsub_sw,
5770                                         WriteVecALU>, VEX_4V, VEX_L;
5771   defm VPMADDUBSW : SS3I_binop_rm_int_y<0x04, "vpmaddubsw",
5772                                        int_x86_avx2_pmadd_ub_sw,
5773                                         WriteVecIMul>, VEX_4V, VEX_L;
5774 }
5775 defm VPMULHRSW    : SS3I_binop_rm_int_y<0x0B, "vpmulhrsw",
5776                                         int_x86_avx2_pmul_hr_sw,
5777                                         WriteVecIMul>, VEX_4V, VEX_L;
5778 }
5779
5780 // None of these have i8 immediate fields.
5781 let ImmT = NoImm, Constraints = "$src1 = $dst" in {
5782 let isCommutable = 0 in {
5783   defm PHADDW    : SS3I_binop_rm<0x01, "phaddw", X86hadd, v8i16, VR128,
5784                                  memopv2i64, i128mem, SSE_PHADDSUBW>;
5785   defm PHADDD    : SS3I_binop_rm<0x02, "phaddd", X86hadd, v4i32, VR128,
5786                                  memopv2i64, i128mem, SSE_PHADDSUBD>;
5787   defm PHSUBW    : SS3I_binop_rm<0x05, "phsubw", X86hsub, v8i16, VR128,
5788                                  memopv2i64, i128mem, SSE_PHADDSUBW>;
5789   defm PHSUBD    : SS3I_binop_rm<0x06, "phsubd", X86hsub, v4i32, VR128,
5790                                  memopv2i64, i128mem, SSE_PHADDSUBD>;
5791   defm PSIGNB    : SS3I_binop_rm<0x08, "psignb", X86psign, v16i8, VR128,
5792                                  memopv2i64, i128mem, SSE_PSIGN>;
5793   defm PSIGNW    : SS3I_binop_rm<0x09, "psignw", X86psign, v8i16, VR128,
5794                                  memopv2i64, i128mem, SSE_PSIGN>;
5795   defm PSIGND    : SS3I_binop_rm<0x0A, "psignd", X86psign, v4i32, VR128,
5796                                  memopv2i64, i128mem, SSE_PSIGN>;
5797   defm PSHUFB    : SS3I_binop_rm<0x00, "pshufb", X86pshufb, v16i8, VR128,
5798                                  memopv2i64, i128mem, SSE_PSHUFB>;
5799   defm PHADDSW   : SS3I_binop_rm_int<0x03, "phaddsw",
5800                                      int_x86_ssse3_phadd_sw_128,
5801                                      SSE_PHADDSUBSW>;
5802   defm PHSUBSW   : SS3I_binop_rm_int<0x07, "phsubsw",
5803                                      int_x86_ssse3_phsub_sw_128,
5804                                      SSE_PHADDSUBSW>;
5805   defm PMADDUBSW : SS3I_binop_rm_int<0x04, "pmaddubsw",
5806                                      int_x86_ssse3_pmadd_ub_sw_128, SSE_PMADD>;
5807 }
5808 defm PMULHRSW    : SS3I_binop_rm_int<0x0B, "pmulhrsw",
5809                                      int_x86_ssse3_pmul_hr_sw_128,
5810                                      SSE_PMULHRSW>;
5811 }
5812
5813 //===---------------------------------------------------------------------===//
5814 // SSSE3 - Packed Align Instruction Patterns
5815 //===---------------------------------------------------------------------===//
5816
5817 multiclass ssse3_palignr<string asm, bit Is2Addr = 1> {
5818   let neverHasSideEffects = 1 in {
5819   def R128rr : SS3AI<0x0F, MRMSrcReg, (outs VR128:$dst),
5820       (ins VR128:$src1, VR128:$src2, i8imm:$src3),
5821       !if(Is2Addr,
5822         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5823         !strconcat(asm,
5824                   "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5825       [], IIC_SSE_PALIGNRR>, Sched<[WriteShuffle]>;
5826   let mayLoad = 1 in
5827   def R128rm : SS3AI<0x0F, MRMSrcMem, (outs VR128:$dst),
5828       (ins VR128:$src1, i128mem:$src2, i8imm:$src3),
5829       !if(Is2Addr,
5830         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5831         !strconcat(asm,
5832                   "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5833       [], IIC_SSE_PALIGNRM>, Sched<[WriteShuffleLd, ReadAfterLd]>;
5834   }
5835 }
5836
5837 multiclass ssse3_palignr_y<string asm, bit Is2Addr = 1> {
5838   let neverHasSideEffects = 1 in {
5839   def R256rr : SS3AI<0x0F, MRMSrcReg, (outs VR256:$dst),
5840       (ins VR256:$src1, VR256:$src2, i8imm:$src3),
5841       !strconcat(asm,
5842                  "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
5843       []>, Sched<[WriteShuffle]>;
5844   let mayLoad = 1 in
5845   def R256rm : SS3AI<0x0F, MRMSrcMem, (outs VR256:$dst),
5846       (ins VR256:$src1, i256mem:$src2, i8imm:$src3),
5847       !strconcat(asm,
5848                  "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
5849       []>, Sched<[WriteShuffleLd, ReadAfterLd]>;
5850   }
5851 }
5852
5853 let Predicates = [HasAVX] in
5854   defm VPALIGN : ssse3_palignr<"vpalignr", 0>, VEX_4V;
5855 let Predicates = [HasAVX2] in
5856   defm VPALIGN : ssse3_palignr_y<"vpalignr", 0>, VEX_4V, VEX_L;
5857 let Constraints = "$src1 = $dst", Predicates = [UseSSSE3] in
5858   defm PALIGN : ssse3_palignr<"palignr">;
5859
5860 let Predicates = [HasAVX2] in {
5861 def : Pat<(v8i32 (X86PAlignr VR256:$src1, VR256:$src2, (i8 imm:$imm))),
5862           (VPALIGNR256rr VR256:$src2, VR256:$src1, imm:$imm)>;
5863 def : Pat<(v8f32 (X86PAlignr VR256:$src1, VR256:$src2, (i8 imm:$imm))),
5864           (VPALIGNR256rr VR256:$src2, VR256:$src1, imm:$imm)>;
5865 def : Pat<(v16i16 (X86PAlignr VR256:$src1, VR256:$src2, (i8 imm:$imm))),
5866           (VPALIGNR256rr VR256:$src2, VR256:$src1, imm:$imm)>;
5867 def : Pat<(v32i8 (X86PAlignr VR256:$src1, VR256:$src2, (i8 imm:$imm))),
5868           (VPALIGNR256rr VR256:$src2, VR256:$src1, imm:$imm)>;
5869 }
5870
5871 let Predicates = [HasAVX] in {
5872 def : Pat<(v4i32 (X86PAlignr VR128:$src1, VR128:$src2, (i8 imm:$imm))),
5873           (VPALIGNR128rr VR128:$src2, VR128:$src1, imm:$imm)>;
5874 def : Pat<(v4f32 (X86PAlignr VR128:$src1, VR128:$src2, (i8 imm:$imm))),
5875           (VPALIGNR128rr VR128:$src2, VR128:$src1, imm:$imm)>;
5876 def : Pat<(v8i16 (X86PAlignr VR128:$src1, VR128:$src2, (i8 imm:$imm))),
5877           (VPALIGNR128rr VR128:$src2, VR128:$src1, imm:$imm)>;
5878 def : Pat<(v16i8 (X86PAlignr VR128:$src1, VR128:$src2, (i8 imm:$imm))),
5879           (VPALIGNR128rr VR128:$src2, VR128:$src1, imm:$imm)>;
5880 }
5881
5882 let Predicates = [UseSSSE3] in {
5883 def : Pat<(v4i32 (X86PAlignr VR128:$src1, VR128:$src2, (i8 imm:$imm))),
5884           (PALIGNR128rr VR128:$src2, VR128:$src1, imm:$imm)>;
5885 def : Pat<(v4f32 (X86PAlignr VR128:$src1, VR128:$src2, (i8 imm:$imm))),
5886           (PALIGNR128rr VR128:$src2, VR128:$src1, imm:$imm)>;
5887 def : Pat<(v8i16 (X86PAlignr VR128:$src1, VR128:$src2, (i8 imm:$imm))),
5888           (PALIGNR128rr VR128:$src2, VR128:$src1, imm:$imm)>;
5889 def : Pat<(v16i8 (X86PAlignr VR128:$src1, VR128:$src2, (i8 imm:$imm))),
5890           (PALIGNR128rr VR128:$src2, VR128:$src1, imm:$imm)>;
5891 }
5892
5893 //===---------------------------------------------------------------------===//
5894 // SSSE3 - Thread synchronization
5895 //===---------------------------------------------------------------------===//
5896
5897 let SchedRW = [WriteSystem] in {
5898 let usesCustomInserter = 1 in {
5899 def MONITOR : PseudoI<(outs), (ins i32mem:$src1, GR32:$src2, GR32:$src3),
5900                 [(int_x86_sse3_monitor addr:$src1, GR32:$src2, GR32:$src3)]>,
5901                 Requires<[HasSSE3]>;
5902 }
5903
5904 let Uses = [EAX, ECX, EDX] in
5905 def MONITORrrr : I<0x01, MRM_C8, (outs), (ins), "monitor", [], IIC_SSE_MONITOR>,
5906                  TB, Requires<[HasSSE3]>;
5907 let Uses = [ECX, EAX] in
5908 def MWAITrr   : I<0x01, MRM_C9, (outs), (ins), "mwait",
5909                 [(int_x86_sse3_mwait ECX, EAX)], IIC_SSE_MWAIT>,
5910                 TB, Requires<[HasSSE3]>;
5911 } // SchedRW
5912
5913 def : InstAlias<"mwait\t{%eax, %ecx|ecx, eax}", (MWAITrr)>, Requires<[Not64BitMode]>;
5914 def : InstAlias<"mwait\t{%rax, %rcx|rcx, rax}", (MWAITrr)>, Requires<[In64BitMode]>;
5915
5916 def : InstAlias<"monitor\t{%eax, %ecx, %edx|edx, ecx, eax}", (MONITORrrr)>,
5917       Requires<[Not64BitMode]>;
5918 def : InstAlias<"monitor\t{%rax, %rcx, %rdx|rdx, rcx, rax}", (MONITORrrr)>,
5919       Requires<[In64BitMode]>;
5920
5921 //===----------------------------------------------------------------------===//
5922 // SSE4.1 - Packed Move with Sign/Zero Extend
5923 //===----------------------------------------------------------------------===//
5924
5925 multiclass SS41I_binop_rm_int8<bits<8> opc, string OpcodeStr, Intrinsic IntId,
5926                                OpndItins itins = DEFAULT_ITINS> {
5927   def rr : SS48I<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
5928                  !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5929                  [(set VR128:$dst, (IntId VR128:$src))], itins.rr>,
5930                  Sched<[itins.Sched]>;
5931
5932   def rm : SS48I<opc, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
5933                  !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5934        [(set VR128:$dst,
5935          (IntId (bitconvert (v2i64 (scalar_to_vector (loadi64 addr:$src))))))],
5936          itins.rm>, Sched<[itins.Sched.Folded]>;
5937 }
5938
5939 multiclass SS41I_binop_rm_int16_y<bits<8> opc, string OpcodeStr,
5940                                  Intrinsic IntId, X86FoldableSchedWrite Sched> {
5941   def Yrr : SS48I<opc, MRMSrcReg, (outs VR256:$dst), (ins VR128:$src),
5942                   !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5943                   [(set VR256:$dst, (IntId VR128:$src))]>, Sched<[Sched]>;
5944
5945   def Yrm : SS48I<opc, MRMSrcMem, (outs VR256:$dst), (ins i128mem:$src),
5946                   !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5947                   [(set VR256:$dst, (IntId (load addr:$src)))]>,
5948                   Sched<[Sched.Folded]>;
5949 }
5950
5951 let Predicates = [HasAVX] in {
5952 defm VPMOVSXBW : SS41I_binop_rm_int8<0x20, "vpmovsxbw",
5953                                      int_x86_sse41_pmovsxbw,
5954                                      DEFAULT_ITINS_SHUFFLESCHED>, VEX;
5955 defm VPMOVSXWD : SS41I_binop_rm_int8<0x23, "vpmovsxwd",
5956                                      int_x86_sse41_pmovsxwd,
5957                                      DEFAULT_ITINS_SHUFFLESCHED>, VEX;
5958 defm VPMOVSXDQ : SS41I_binop_rm_int8<0x25, "vpmovsxdq",
5959                                      int_x86_sse41_pmovsxdq,
5960                                      DEFAULT_ITINS_SHUFFLESCHED>, VEX;
5961 defm VPMOVZXBW : SS41I_binop_rm_int8<0x30, "vpmovzxbw",
5962                                      int_x86_sse41_pmovzxbw,
5963                                      DEFAULT_ITINS_SHUFFLESCHED>, VEX;
5964 defm VPMOVZXWD : SS41I_binop_rm_int8<0x33, "vpmovzxwd",
5965                                      int_x86_sse41_pmovzxwd,
5966                                      DEFAULT_ITINS_SHUFFLESCHED>, VEX;
5967 defm VPMOVZXDQ : SS41I_binop_rm_int8<0x35, "vpmovzxdq",
5968                                      int_x86_sse41_pmovzxdq,
5969                                      DEFAULT_ITINS_SHUFFLESCHED>, VEX;
5970 }
5971
5972 let Predicates = [HasAVX2] in {
5973 defm VPMOVSXBW : SS41I_binop_rm_int16_y<0x20, "vpmovsxbw",
5974                                         int_x86_avx2_pmovsxbw,
5975                                         WriteShuffle>, VEX, VEX_L;
5976 defm VPMOVSXWD : SS41I_binop_rm_int16_y<0x23, "vpmovsxwd",
5977                                         int_x86_avx2_pmovsxwd,
5978                                         WriteShuffle>, VEX, VEX_L;
5979 defm VPMOVSXDQ : SS41I_binop_rm_int16_y<0x25, "vpmovsxdq",
5980                                         int_x86_avx2_pmovsxdq,
5981                                         WriteShuffle>, VEX, VEX_L;
5982 defm VPMOVZXBW : SS41I_binop_rm_int16_y<0x30, "vpmovzxbw",
5983                                         int_x86_avx2_pmovzxbw,
5984                                         WriteShuffle>, VEX, VEX_L;
5985 defm VPMOVZXWD : SS41I_binop_rm_int16_y<0x33, "vpmovzxwd",
5986                                         int_x86_avx2_pmovzxwd,
5987                                         WriteShuffle>, VEX, VEX_L;
5988 defm VPMOVZXDQ : SS41I_binop_rm_int16_y<0x35, "vpmovzxdq",
5989                                         int_x86_avx2_pmovzxdq,
5990                                         WriteShuffle>, VEX, VEX_L;
5991 }
5992
5993 defm PMOVSXBW   : SS41I_binop_rm_int8<0x20, "pmovsxbw", int_x86_sse41_pmovsxbw,
5994                                       SSE_INTALU_ITINS_SHUFF_P>;
5995 defm PMOVSXWD   : SS41I_binop_rm_int8<0x23, "pmovsxwd", int_x86_sse41_pmovsxwd,
5996                                       SSE_INTALU_ITINS_SHUFF_P>;
5997 defm PMOVSXDQ   : SS41I_binop_rm_int8<0x25, "pmovsxdq", int_x86_sse41_pmovsxdq,
5998                                       SSE_INTALU_ITINS_SHUFF_P>;
5999 defm PMOVZXBW   : SS41I_binop_rm_int8<0x30, "pmovzxbw", int_x86_sse41_pmovzxbw,
6000                                       SSE_INTALU_ITINS_SHUFF_P>;
6001 defm PMOVZXWD   : SS41I_binop_rm_int8<0x33, "pmovzxwd", int_x86_sse41_pmovzxwd,
6002                                       SSE_INTALU_ITINS_SHUFF_P>;
6003 defm PMOVZXDQ   : SS41I_binop_rm_int8<0x35, "pmovzxdq", int_x86_sse41_pmovzxdq,
6004                                       SSE_INTALU_ITINS_SHUFF_P>;
6005
6006 let Predicates = [HasAVX] in {
6007   // Common patterns involving scalar load.
6008   def : Pat<(int_x86_sse41_pmovsxbw (vzmovl_v2i64 addr:$src)),
6009             (VPMOVSXBWrm addr:$src)>;
6010   def : Pat<(int_x86_sse41_pmovsxbw (vzload_v2i64 addr:$src)),
6011             (VPMOVSXBWrm addr:$src)>;
6012   def : Pat<(int_x86_sse41_pmovsxbw (bc_v16i8 (loadv2i64 addr:$src))),
6013             (VPMOVSXBWrm addr:$src)>;
6014
6015   def : Pat<(int_x86_sse41_pmovsxwd (vzmovl_v2i64 addr:$src)),
6016             (VPMOVSXWDrm addr:$src)>;
6017   def : Pat<(int_x86_sse41_pmovsxwd (vzload_v2i64 addr:$src)),
6018             (VPMOVSXWDrm addr:$src)>;
6019   def : Pat<(int_x86_sse41_pmovsxwd (bc_v8i16 (loadv2i64 addr:$src))),
6020             (VPMOVSXWDrm addr:$src)>;
6021
6022   def : Pat<(int_x86_sse41_pmovsxdq (vzmovl_v2i64 addr:$src)),
6023             (VPMOVSXDQrm addr:$src)>;
6024   def : Pat<(int_x86_sse41_pmovsxdq (vzload_v2i64 addr:$src)),
6025             (VPMOVSXDQrm addr:$src)>;
6026   def : Pat<(int_x86_sse41_pmovsxdq (bc_v4i32 (loadv2i64 addr:$src))),
6027             (VPMOVSXDQrm addr:$src)>;
6028
6029   def : Pat<(int_x86_sse41_pmovzxbw (vzmovl_v2i64 addr:$src)),
6030             (VPMOVZXBWrm addr:$src)>;
6031   def : Pat<(int_x86_sse41_pmovzxbw (vzload_v2i64 addr:$src)),
6032             (VPMOVZXBWrm addr:$src)>;
6033   def : Pat<(int_x86_sse41_pmovzxbw (bc_v16i8 (loadv2i64 addr:$src))),
6034             (VPMOVZXBWrm addr:$src)>;
6035
6036   def : Pat<(int_x86_sse41_pmovzxwd (vzmovl_v2i64 addr:$src)),
6037             (VPMOVZXWDrm addr:$src)>;
6038   def : Pat<(int_x86_sse41_pmovzxwd (vzload_v2i64 addr:$src)),
6039             (VPMOVZXWDrm addr:$src)>;
6040   def : Pat<(int_x86_sse41_pmovzxwd (bc_v8i16 (loadv2i64 addr:$src))),
6041             (VPMOVZXWDrm addr:$src)>;
6042
6043   def : Pat<(int_x86_sse41_pmovzxdq (vzmovl_v2i64 addr:$src)),
6044             (VPMOVZXDQrm addr:$src)>;
6045   def : Pat<(int_x86_sse41_pmovzxdq (vzload_v2i64 addr:$src)),
6046             (VPMOVZXDQrm addr:$src)>;
6047   def : Pat<(int_x86_sse41_pmovzxdq (bc_v4i32 (loadv2i64 addr:$src))),
6048             (VPMOVZXDQrm addr:$src)>;
6049 }
6050
6051 let Predicates = [UseSSE41] in {
6052   // Common patterns involving scalar load.
6053   def : Pat<(int_x86_sse41_pmovsxbw (vzmovl_v2i64 addr:$src)),
6054             (PMOVSXBWrm addr:$src)>;
6055   def : Pat<(int_x86_sse41_pmovsxbw (vzload_v2i64 addr:$src)),
6056             (PMOVSXBWrm addr:$src)>;
6057   def : Pat<(int_x86_sse41_pmovsxbw (bc_v16i8 (loadv2i64 addr:$src))),
6058             (PMOVSXBWrm addr:$src)>;
6059
6060   def : Pat<(int_x86_sse41_pmovsxwd (vzmovl_v2i64 addr:$src)),
6061             (PMOVSXWDrm addr:$src)>;
6062   def : Pat<(int_x86_sse41_pmovsxwd (vzload_v2i64 addr:$src)),
6063             (PMOVSXWDrm addr:$src)>;
6064   def : Pat<(int_x86_sse41_pmovsxwd (bc_v8i16 (loadv2i64 addr:$src))),
6065             (PMOVSXWDrm addr:$src)>;
6066
6067   def : Pat<(int_x86_sse41_pmovsxdq (vzmovl_v2i64 addr:$src)),
6068             (PMOVSXDQrm addr:$src)>;
6069   def : Pat<(int_x86_sse41_pmovsxdq (vzload_v2i64 addr:$src)),
6070             (PMOVSXDQrm addr:$src)>;
6071   def : Pat<(int_x86_sse41_pmovsxdq (bc_v4i32 (loadv2i64 addr:$src))),
6072             (PMOVSXDQrm addr:$src)>;
6073
6074   def : Pat<(int_x86_sse41_pmovzxbw (vzmovl_v2i64 addr:$src)),
6075             (PMOVZXBWrm addr:$src)>;
6076   def : Pat<(int_x86_sse41_pmovzxbw (vzload_v2i64 addr:$src)),
6077             (PMOVZXBWrm addr:$src)>;
6078   def : Pat<(int_x86_sse41_pmovzxbw (bc_v16i8 (loadv2i64 addr:$src))),
6079             (PMOVZXBWrm addr:$src)>;
6080
6081   def : Pat<(int_x86_sse41_pmovzxwd (vzmovl_v2i64 addr:$src)),
6082             (PMOVZXWDrm addr:$src)>;
6083   def : Pat<(int_x86_sse41_pmovzxwd (vzload_v2i64 addr:$src)),
6084             (PMOVZXWDrm addr:$src)>;
6085   def : Pat<(int_x86_sse41_pmovzxwd (bc_v8i16 (loadv2i64 addr:$src))),
6086             (PMOVZXWDrm addr:$src)>;
6087
6088   def : Pat<(int_x86_sse41_pmovzxdq (vzmovl_v2i64 addr:$src)),
6089             (PMOVZXDQrm addr:$src)>;
6090   def : Pat<(int_x86_sse41_pmovzxdq (vzload_v2i64 addr:$src)),
6091             (PMOVZXDQrm addr:$src)>;
6092   def : Pat<(int_x86_sse41_pmovzxdq (bc_v4i32 (loadv2i64 addr:$src))),
6093             (PMOVZXDQrm addr:$src)>;
6094 }
6095
6096 multiclass SS41I_binop_rm_int4<bits<8> opc, string OpcodeStr, Intrinsic IntId,
6097                                OpndItins itins = DEFAULT_ITINS> {
6098   def rr : SS48I<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
6099                  !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
6100                  [(set VR128:$dst, (IntId VR128:$src))], itins.rr>,
6101                  Sched<[itins.Sched]>;
6102
6103   def rm : SS48I<opc, MRMSrcMem, (outs VR128:$dst), (ins i32mem:$src),
6104                  !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
6105        [(set VR128:$dst,
6106          (IntId (bitconvert (v4i32 (scalar_to_vector (loadi32 addr:$src))))))],
6107          itins.rm>, Sched<[itins.Sched.Folded]>;
6108 }
6109
6110 multiclass SS41I_binop_rm_int8_y<bits<8> opc, string OpcodeStr,
6111                                  Intrinsic IntId, X86FoldableSchedWrite Sched> {
6112   def Yrr : SS48I<opc, MRMSrcReg, (outs VR256:$dst), (ins VR128:$src),
6113                   !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
6114                   [(set VR256:$dst, (IntId VR128:$src))]>, Sched<[Sched]>;
6115
6116   def Yrm : SS48I<opc, MRMSrcMem, (outs VR256:$dst), (ins i32mem:$src),
6117                   !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
6118        [(set VR256:$dst,
6119          (IntId (bitconvert (v2i64 (scalar_to_vector (loadi64 addr:$src))))))]>,
6120          Sched<[Sched.Folded]>;
6121 }
6122
6123 let Predicates = [HasAVX] in {
6124 defm VPMOVSXBD : SS41I_binop_rm_int4<0x21, "vpmovsxbd", int_x86_sse41_pmovsxbd,
6125                                      DEFAULT_ITINS_SHUFFLESCHED>, VEX;
6126 defm VPMOVSXWQ : SS41I_binop_rm_int4<0x24, "vpmovsxwq", int_x86_sse41_pmovsxwq,
6127                                      DEFAULT_ITINS_SHUFFLESCHED>, VEX;
6128 defm VPMOVZXBD : SS41I_binop_rm_int4<0x31, "vpmovzxbd", int_x86_sse41_pmovzxbd,
6129                                      DEFAULT_ITINS_SHUFFLESCHED>, VEX;
6130 defm VPMOVZXWQ : SS41I_binop_rm_int4<0x34, "vpmovzxwq", int_x86_sse41_pmovzxwq,
6131                                      DEFAULT_ITINS_SHUFFLESCHED>, VEX;
6132 }
6133
6134 let Predicates = [HasAVX2] in {
6135 defm VPMOVSXBD : SS41I_binop_rm_int8_y<0x21, "vpmovsxbd",
6136                                        int_x86_avx2_pmovsxbd, WriteShuffle>,
6137                                        VEX, VEX_L;
6138 defm VPMOVSXWQ : SS41I_binop_rm_int8_y<0x24, "vpmovsxwq",
6139                                        int_x86_avx2_pmovsxwq, WriteShuffle>,
6140                                        VEX, VEX_L;
6141 defm VPMOVZXBD : SS41I_binop_rm_int8_y<0x31, "vpmovzxbd",
6142                                        int_x86_avx2_pmovzxbd, WriteShuffle>,
6143                                        VEX, VEX_L;
6144 defm VPMOVZXWQ : SS41I_binop_rm_int8_y<0x34, "vpmovzxwq",
6145                                        int_x86_avx2_pmovzxwq, WriteShuffle>,
6146                                        VEX, VEX_L;
6147 }
6148
6149 defm PMOVSXBD   : SS41I_binop_rm_int4<0x21, "pmovsxbd", int_x86_sse41_pmovsxbd,
6150                                       SSE_INTALU_ITINS_SHUFF_P>;
6151 defm PMOVSXWQ   : SS41I_binop_rm_int4<0x24, "pmovsxwq", int_x86_sse41_pmovsxwq,
6152                                       SSE_INTALU_ITINS_SHUFF_P>;
6153 defm PMOVZXBD   : SS41I_binop_rm_int4<0x31, "pmovzxbd", int_x86_sse41_pmovzxbd,
6154                                       SSE_INTALU_ITINS_SHUFF_P>;
6155 defm PMOVZXWQ   : SS41I_binop_rm_int4<0x34, "pmovzxwq", int_x86_sse41_pmovzxwq,
6156                                       SSE_INTALU_ITINS_SHUFF_P>;
6157
6158 let Predicates = [HasAVX] in {
6159   // Common patterns involving scalar load
6160   def : Pat<(int_x86_sse41_pmovsxbd (vzmovl_v4i32 addr:$src)),
6161             (VPMOVSXBDrm addr:$src)>;
6162   def : Pat<(int_x86_sse41_pmovsxwq (vzmovl_v4i32 addr:$src)),
6163             (VPMOVSXWQrm addr:$src)>;
6164
6165   def : Pat<(int_x86_sse41_pmovzxbd (vzmovl_v4i32 addr:$src)),
6166             (VPMOVZXBDrm addr:$src)>;
6167   def : Pat<(int_x86_sse41_pmovzxwq (vzmovl_v4i32 addr:$src)),
6168             (VPMOVZXWQrm addr:$src)>;
6169 }
6170
6171 let Predicates = [UseSSE41] in {
6172   // Common patterns involving scalar load
6173   def : Pat<(int_x86_sse41_pmovsxbd (vzmovl_v4i32 addr:$src)),
6174             (PMOVSXBDrm addr:$src)>;
6175   def : Pat<(int_x86_sse41_pmovsxwq (vzmovl_v4i32 addr:$src)),
6176             (PMOVSXWQrm addr:$src)>;
6177
6178   def : Pat<(int_x86_sse41_pmovzxbd (vzmovl_v4i32 addr:$src)),
6179             (PMOVZXBDrm addr:$src)>;
6180   def : Pat<(int_x86_sse41_pmovzxwq (vzmovl_v4i32 addr:$src)),
6181             (PMOVZXWQrm addr:$src)>;
6182 }
6183
6184 multiclass SS41I_binop_rm_int2<bits<8> opc, string OpcodeStr, Intrinsic IntId,
6185                                X86FoldableSchedWrite Sched> {
6186   def rr : SS48I<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
6187                  !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
6188                  [(set VR128:$dst, (IntId VR128:$src))]>, Sched<[Sched]>;
6189
6190   // Expecting a i16 load any extended to i32 value.
6191   def rm : SS48I<opc, MRMSrcMem, (outs VR128:$dst), (ins i16mem:$src),
6192                  !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
6193                  [(set VR128:$dst, (IntId (bitconvert
6194                      (v4i32 (scalar_to_vector (loadi16_anyext addr:$src))))))]>,
6195                  Sched<[Sched.Folded]>;
6196 }
6197
6198 multiclass SS41I_binop_rm_int4_y<bits<8> opc, string OpcodeStr,
6199                                  Intrinsic IntId, X86FoldableSchedWrite Sched> {
6200   def Yrr : SS48I<opc, MRMSrcReg, (outs VR256:$dst), (ins VR128:$src),
6201                  !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
6202                  [(set VR256:$dst, (IntId VR128:$src))]>, Sched<[Sched]>;
6203
6204   // Expecting a i16 load any extended to i32 value.
6205   def Yrm : SS48I<opc, MRMSrcMem, (outs VR256:$dst), (ins i16mem:$src),
6206                   !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
6207                   [(set VR256:$dst, (IntId (bitconvert
6208                       (v4i32 (scalar_to_vector (loadi32 addr:$src))))))]>,
6209                  Sched<[Sched.Folded]>;
6210 }
6211
6212 let Predicates = [HasAVX] in {
6213 defm VPMOVSXBQ : SS41I_binop_rm_int2<0x22, "vpmovsxbq", int_x86_sse41_pmovsxbq,
6214                                      WriteShuffle>, VEX;
6215 defm VPMOVZXBQ : SS41I_binop_rm_int2<0x32, "vpmovzxbq", int_x86_sse41_pmovzxbq,
6216                                      WriteShuffle>, VEX;
6217 }
6218 let Predicates = [HasAVX2] in {
6219 defm VPMOVSXBQ : SS41I_binop_rm_int4_y<0x22, "vpmovsxbq", int_x86_avx2_pmovsxbq,
6220                                        WriteShuffle>, VEX, VEX_L;
6221 defm VPMOVZXBQ : SS41I_binop_rm_int4_y<0x32, "vpmovzxbq", int_x86_avx2_pmovzxbq,
6222                                        WriteShuffle>, VEX, VEX_L;
6223 }
6224 defm PMOVSXBQ   : SS41I_binop_rm_int2<0x22, "pmovsxbq", int_x86_sse41_pmovsxbq,
6225                                       WriteShuffle>;
6226 defm PMOVZXBQ   : SS41I_binop_rm_int2<0x32, "pmovzxbq", int_x86_sse41_pmovzxbq,
6227                                       WriteShuffle>;
6228
6229 let Predicates = [HasAVX2] in {
6230   def : Pat<(v16i16 (X86vsext (v16i8 VR128:$src))), (VPMOVSXBWYrr VR128:$src)>;
6231   def : Pat<(v8i32  (X86vsext (v16i8 VR128:$src))), (VPMOVSXBDYrr VR128:$src)>;
6232   def : Pat<(v4i64  (X86vsext (v16i8 VR128:$src))), (VPMOVSXBQYrr VR128:$src)>;
6233
6234   def : Pat<(v8i32  (X86vsext (v8i16 VR128:$src))), (VPMOVSXWDYrr VR128:$src)>;
6235   def : Pat<(v4i64  (X86vsext (v8i16 VR128:$src))), (VPMOVSXWQYrr VR128:$src)>;
6236
6237   def : Pat<(v4i64  (X86vsext (v4i32 VR128:$src))), (VPMOVSXDQYrr VR128:$src)>;
6238
6239   def : Pat<(v16i16 (X86vsext (v32i8 VR256:$src))),
6240             (VPMOVSXBWYrr (EXTRACT_SUBREG VR256:$src, sub_xmm))>;
6241   def : Pat<(v8i32 (X86vsext (v32i8 VR256:$src))),
6242             (VPMOVSXBDYrr (EXTRACT_SUBREG VR256:$src, sub_xmm))>;
6243   def : Pat<(v4i64 (X86vsext (v32i8 VR256:$src))),
6244             (VPMOVSXBQYrr (EXTRACT_SUBREG VR256:$src, sub_xmm))>;
6245
6246   def : Pat<(v8i32 (X86vsext (v16i16 VR256:$src))),
6247             (VPMOVSXWDYrr (EXTRACT_SUBREG VR256:$src, sub_xmm))>;
6248   def : Pat<(v4i64 (X86vsext (v16i16 VR256:$src))),
6249             (VPMOVSXWQYrr (EXTRACT_SUBREG VR256:$src, sub_xmm))>;
6250
6251   def : Pat<(v4i64 (X86vsext (v8i32 VR256:$src))),
6252             (VPMOVSXDQYrr (EXTRACT_SUBREG VR256:$src, sub_xmm))>;
6253
6254   def : Pat<(v8i32 (X86vsext (v8i16 (bitconvert (v2i64 (load addr:$src)))))),
6255             (VPMOVSXWDYrm addr:$src)>;
6256   def : Pat<(v4i64 (X86vsext (v4i32 (bitconvert (v2i64 (load addr:$src)))))),
6257             (VPMOVSXDQYrm addr:$src)>;
6258
6259   def : Pat<(v8i32 (X86vsext (v16i8 (bitconvert (v2i64 
6260                     (scalar_to_vector (loadi64 addr:$src))))))),
6261             (VPMOVSXBDYrm addr:$src)>;
6262   def : Pat<(v8i32 (X86vsext (v16i8 (bitconvert (v2f64 
6263                     (scalar_to_vector (loadf64 addr:$src))))))),
6264             (VPMOVSXBDYrm addr:$src)>;
6265
6266   def : Pat<(v4i64 (X86vsext (v8i16 (bitconvert (v2i64 
6267                     (scalar_to_vector (loadi64 addr:$src))))))),
6268             (VPMOVSXWQYrm addr:$src)>;
6269   def : Pat<(v4i64 (X86vsext (v8i16 (bitconvert (v2f64 
6270                     (scalar_to_vector (loadf64 addr:$src))))))),
6271             (VPMOVSXWQYrm addr:$src)>;
6272
6273   def : Pat<(v4i64 (X86vsext (v16i8 (bitconvert (v4i32 
6274                     (scalar_to_vector (loadi32 addr:$src))))))),
6275             (VPMOVSXBQYrm addr:$src)>;
6276 }
6277
6278 let Predicates = [HasAVX] in {
6279   // Common patterns involving scalar load
6280   def : Pat<(int_x86_sse41_pmovsxbq
6281               (bitconvert (v4i32 (X86vzmovl
6282                             (v4i32 (scalar_to_vector (loadi32 addr:$src))))))),
6283             (VPMOVSXBQrm addr:$src)>;
6284
6285   def : Pat<(int_x86_sse41_pmovzxbq
6286               (bitconvert (v4i32 (X86vzmovl
6287                             (v4i32 (scalar_to_vector (loadi32 addr:$src))))))),
6288             (VPMOVZXBQrm addr:$src)>;
6289 }
6290
6291 let Predicates = [UseSSE41] in {
6292   def : Pat<(v8i16 (X86vsext (v16i8 VR128:$src))), (PMOVSXBWrr VR128:$src)>;
6293   def : Pat<(v4i32 (X86vsext (v16i8 VR128:$src))), (PMOVSXBDrr VR128:$src)>;
6294   def : Pat<(v2i64 (X86vsext (v16i8 VR128:$src))), (PMOVSXBQrr VR128:$src)>;
6295
6296   def : Pat<(v4i32 (X86vsext (v8i16 VR128:$src))), (PMOVSXWDrr VR128:$src)>;
6297   def : Pat<(v2i64 (X86vsext (v8i16 VR128:$src))), (PMOVSXWQrr VR128:$src)>;
6298
6299   def : Pat<(v2i64 (X86vsext (v4i32 VR128:$src))), (PMOVSXDQrr VR128:$src)>;
6300
6301   // Common patterns involving scalar load
6302   def : Pat<(int_x86_sse41_pmovsxbq
6303               (bitconvert (v4i32 (X86vzmovl
6304                             (v4i32 (scalar_to_vector (loadi32 addr:$src))))))),
6305             (PMOVSXBQrm addr:$src)>;
6306
6307   def : Pat<(int_x86_sse41_pmovzxbq
6308               (bitconvert (v4i32 (X86vzmovl
6309                             (v4i32 (scalar_to_vector (loadi32 addr:$src))))))),
6310             (PMOVZXBQrm addr:$src)>;
6311
6312   def : Pat<(v4i32 (X86vsext (v8i16 (bitconvert (v2i64
6313                     (scalar_to_vector (loadi64 addr:$src))))))),
6314             (PMOVSXWDrm addr:$src)>;
6315   def : Pat<(v4i32 (X86vsext (v8i16 (bitconvert (v2f64
6316                     (scalar_to_vector (loadf64 addr:$src))))))),
6317             (PMOVSXWDrm addr:$src)>;
6318   def : Pat<(v4i32 (X86vsext (v16i8 (bitconvert (v4i32
6319                     (scalar_to_vector (loadi32 addr:$src))))))),
6320             (PMOVSXBDrm addr:$src)>;
6321   def : Pat<(v2i64 (X86vsext (v8i16 (bitconvert (v4i32
6322                     (scalar_to_vector (loadi32 addr:$src))))))),
6323             (PMOVSXWQrm addr:$src)>;
6324   def : Pat<(v2i64 (X86vsext (v16i8 (bitconvert (v4i32
6325                     (scalar_to_vector (extloadi32i16 addr:$src))))))),
6326             (PMOVSXBQrm addr:$src)>;
6327   def : Pat<(v2i64 (X86vsext (v4i32 (bitconvert (v2i64
6328                     (scalar_to_vector (loadi64 addr:$src))))))),
6329             (PMOVSXDQrm addr:$src)>;
6330   def : Pat<(v2i64 (X86vsext (v4i32 (bitconvert (v2f64
6331                     (scalar_to_vector (loadf64 addr:$src))))))),
6332             (PMOVSXDQrm addr:$src)>;
6333   def : Pat<(v8i16 (X86vsext (v16i8 (bitconvert (v2i64
6334                     (scalar_to_vector (loadi64 addr:$src))))))),
6335             (PMOVSXBWrm addr:$src)>;
6336   def : Pat<(v8i16 (X86vsext (v16i8 (bitconvert (v2f64
6337                     (scalar_to_vector (loadf64 addr:$src))))))),
6338             (PMOVSXBWrm addr:$src)>;
6339 }
6340
6341 let Predicates = [HasAVX2] in {
6342   def : Pat<(v16i16 (X86vzext (v16i8 VR128:$src))), (VPMOVZXBWYrr VR128:$src)>;
6343   def : Pat<(v8i32  (X86vzext (v16i8 VR128:$src))), (VPMOVZXBDYrr VR128:$src)>;
6344   def : Pat<(v4i64  (X86vzext (v16i8 VR128:$src))), (VPMOVZXBQYrr VR128:$src)>;
6345
6346   def : Pat<(v8i32  (X86vzext (v8i16 VR128:$src))), (VPMOVZXWDYrr VR128:$src)>;
6347   def : Pat<(v4i64  (X86vzext (v8i16 VR128:$src))), (VPMOVZXWQYrr VR128:$src)>;
6348
6349   def : Pat<(v4i64  (X86vzext (v4i32 VR128:$src))), (VPMOVZXDQYrr VR128:$src)>;
6350
6351   def : Pat<(v16i16 (X86vzext (v32i8 VR256:$src))),
6352             (VPMOVZXBWYrr (EXTRACT_SUBREG VR256:$src, sub_xmm))>;
6353   def : Pat<(v8i32 (X86vzext (v32i8 VR256:$src))),
6354             (VPMOVZXBDYrr (EXTRACT_SUBREG VR256:$src, sub_xmm))>;
6355   def : Pat<(v4i64 (X86vzext (v32i8 VR256:$src))),
6356             (VPMOVZXBQYrr (EXTRACT_SUBREG VR256:$src, sub_xmm))>;
6357
6358   def : Pat<(v8i32 (X86vzext (v16i16 VR256:$src))),
6359             (VPMOVZXWDYrr (EXTRACT_SUBREG VR256:$src, sub_xmm))>;
6360   def : Pat<(v4i64 (X86vzext (v16i16 VR256:$src))),
6361             (VPMOVZXWQYrr (EXTRACT_SUBREG VR256:$src, sub_xmm))>;
6362
6363   def : Pat<(v4i64 (X86vzext (v8i32 VR256:$src))),
6364             (VPMOVZXDQYrr (EXTRACT_SUBREG VR256:$src, sub_xmm))>;
6365 }
6366
6367 let Predicates = [HasAVX] in {
6368   def : Pat<(v8i16 (X86vzext (v16i8 VR128:$src))), (VPMOVZXBWrr VR128:$src)>;
6369   def : Pat<(v4i32 (X86vzext (v16i8 VR128:$src))), (VPMOVZXBDrr VR128:$src)>;
6370   def : Pat<(v2i64 (X86vzext (v16i8 VR128:$src))), (VPMOVZXBQrr VR128:$src)>;
6371
6372   def : Pat<(v4i32 (X86vzext (v8i16 VR128:$src))), (VPMOVZXWDrr VR128:$src)>;
6373   def : Pat<(v2i64 (X86vzext (v8i16 VR128:$src))), (VPMOVZXWQrr VR128:$src)>;
6374
6375   def : Pat<(v2i64 (X86vzext (v4i32 VR128:$src))), (VPMOVZXDQrr VR128:$src)>;
6376
6377   def : Pat<(v8i16 (X86vzext (v16i8 (bitconvert (v2i64 (scalar_to_vector (loadi64 addr:$src))))))),
6378             (VPMOVZXBWrm addr:$src)>;
6379   def : Pat<(v8i16 (X86vzext (v16i8 (bitconvert (v2f64 (scalar_to_vector (loadf64 addr:$src))))))),
6380             (VPMOVZXBWrm addr:$src)>;
6381   def : Pat<(v4i32 (X86vzext (v16i8 (bitconvert (v4i32 (scalar_to_vector (loadi32 addr:$src))))))),
6382             (VPMOVZXBDrm addr:$src)>;
6383   def : Pat<(v2i64 (X86vzext (v16i8 (bitconvert (v4i32 (scalar_to_vector (loadi16_anyext addr:$src))))))),
6384             (VPMOVZXBQrm addr:$src)>;
6385
6386   def : Pat<(v4i32 (X86vzext (v8i16 (bitconvert (v2i64 (scalar_to_vector (loadi64 addr:$src))))))),
6387             (VPMOVZXWDrm addr:$src)>;
6388   def : Pat<(v4i32 (X86vzext (v8i16 (bitconvert (v2f64 (scalar_to_vector (loadf64 addr:$src))))))),
6389             (VPMOVZXWDrm addr:$src)>;
6390   def : Pat<(v2i64 (X86vzext (v8i16 (bitconvert (v4i32 (scalar_to_vector (loadi32 addr:$src))))))),
6391             (VPMOVZXWQrm addr:$src)>;
6392
6393   def : Pat<(v2i64 (X86vzext (v4i32 (bitconvert (v2i64 (scalar_to_vector (loadi64 addr:$src))))))),
6394             (VPMOVZXDQrm addr:$src)>;
6395   def : Pat<(v2i64 (X86vzext (v4i32 (bitconvert (v2f64 (scalar_to_vector (loadf64 addr:$src))))))),
6396             (VPMOVZXDQrm addr:$src)>;
6397   def : Pat<(v2i64 (X86vzext (v4i32 (bitconvert (v2i64 (X86vzload addr:$src)))))),
6398             (VPMOVZXDQrm addr:$src)>;
6399
6400   def : Pat<(v8i16 (X86vsext (v16i8 VR128:$src))), (VPMOVSXBWrr VR128:$src)>;
6401   def : Pat<(v4i32 (X86vsext (v16i8 VR128:$src))), (VPMOVSXBDrr VR128:$src)>;
6402   def : Pat<(v2i64 (X86vsext (v16i8 VR128:$src))), (VPMOVSXBQrr VR128:$src)>;
6403
6404   def : Pat<(v4i32 (X86vsext (v8i16 VR128:$src))), (VPMOVSXWDrr VR128:$src)>;
6405   def : Pat<(v2i64 (X86vsext (v8i16 VR128:$src))), (VPMOVSXWQrr VR128:$src)>;
6406
6407   def : Pat<(v2i64 (X86vsext (v4i32 VR128:$src))), (VPMOVSXDQrr VR128:$src)>;
6408
6409   def : Pat<(v4i32 (X86vsext (v8i16 (bitconvert (v2i64
6410                     (scalar_to_vector (loadi64 addr:$src))))))),
6411             (VPMOVSXWDrm addr:$src)>;
6412   def : Pat<(v2i64 (X86vsext (v4i32 (bitconvert (v2i64
6413                     (scalar_to_vector (loadi64 addr:$src))))))),
6414             (VPMOVSXDQrm addr:$src)>;
6415   def : Pat<(v4i32 (X86vsext (v8i16 (bitconvert (v2f64
6416                     (scalar_to_vector (loadf64 addr:$src))))))),
6417             (VPMOVSXWDrm addr:$src)>;
6418   def : Pat<(v2i64 (X86vsext (v4i32 (bitconvert (v2f64
6419                     (scalar_to_vector (loadf64 addr:$src))))))),
6420             (VPMOVSXDQrm addr:$src)>;
6421   def : Pat<(v8i16 (X86vsext (v16i8 (bitconvert (v2i64
6422                     (scalar_to_vector (loadi64 addr:$src))))))),
6423             (VPMOVSXBWrm addr:$src)>;
6424   def : Pat<(v8i16 (X86vsext (v16i8 (bitconvert (v2f64
6425                     (scalar_to_vector (loadf64 addr:$src))))))),
6426             (VPMOVSXBWrm addr:$src)>;
6427
6428   def : Pat<(v4i32 (X86vsext (v16i8 (bitconvert (v4i32
6429                     (scalar_to_vector (loadi32 addr:$src))))))),
6430             (VPMOVSXBDrm addr:$src)>;
6431   def : Pat<(v2i64 (X86vsext (v8i16 (bitconvert (v4i32
6432                     (scalar_to_vector (loadi32 addr:$src))))))),
6433             (VPMOVSXWQrm addr:$src)>;
6434   def : Pat<(v2i64 (X86vsext (v16i8 (bitconvert (v4i32
6435                     (scalar_to_vector (extloadi32i16 addr:$src))))))),
6436             (VPMOVSXBQrm addr:$src)>;
6437 }
6438
6439 let Predicates = [UseSSE41] in {
6440   def : Pat<(v8i16 (X86vzext (v16i8 VR128:$src))), (PMOVZXBWrr VR128:$src)>;
6441   def : Pat<(v4i32 (X86vzext (v16i8 VR128:$src))), (PMOVZXBDrr VR128:$src)>;
6442   def : Pat<(v2i64 (X86vzext (v16i8 VR128:$src))), (PMOVZXBQrr VR128:$src)>;
6443
6444   def : Pat<(v4i32 (X86vzext (v8i16 VR128:$src))), (PMOVZXWDrr VR128:$src)>;
6445   def : Pat<(v2i64 (X86vzext (v8i16 VR128:$src))), (PMOVZXWQrr VR128:$src)>;
6446
6447   def : Pat<(v2i64 (X86vzext (v4i32 VR128:$src))), (PMOVZXDQrr VR128:$src)>;
6448
6449   def : Pat<(v8i16 (X86vzext (v16i8 (bitconvert (v2i64 (scalar_to_vector (loadi64 addr:$src))))))),
6450             (PMOVZXBWrm addr:$src)>;
6451   def : Pat<(v8i16 (X86vzext (v16i8 (bitconvert (v2f64 (scalar_to_vector (loadf64 addr:$src))))))),
6452             (PMOVZXBWrm addr:$src)>;
6453   def : Pat<(v4i32 (X86vzext (v16i8 (bitconvert (v4i32 (scalar_to_vector (loadi32 addr:$src))))))),
6454             (PMOVZXBDrm addr:$src)>;
6455   def : Pat<(v2i64 (X86vzext (v16i8 (bitconvert (v4i32 (scalar_to_vector (loadi16_anyext addr:$src))))))),
6456             (PMOVZXBQrm addr:$src)>;
6457
6458   def : Pat<(v4i32 (X86vzext (v8i16 (bitconvert (v2i64 (scalar_to_vector (loadi64 addr:$src))))))),
6459             (PMOVZXWDrm addr:$src)>;
6460   def : Pat<(v4i32 (X86vzext (v8i16 (bitconvert (v2f64 (scalar_to_vector (loadf64 addr:$src))))))),
6461             (PMOVZXWDrm addr:$src)>;
6462   def : Pat<(v2i64 (X86vzext (v8i16 (bitconvert (v4i32 (scalar_to_vector (loadi32 addr:$src))))))),
6463             (PMOVZXWQrm addr:$src)>;
6464
6465   def : Pat<(v2i64 (X86vzext (v4i32 (bitconvert (v2i64 (scalar_to_vector (loadi64 addr:$src))))))),
6466             (PMOVZXDQrm addr:$src)>;
6467   def : Pat<(v2i64 (X86vzext (v4i32 (bitconvert (v2f64 (scalar_to_vector (loadf64 addr:$src))))))),
6468             (PMOVZXDQrm addr:$src)>;
6469   def : Pat<(v2i64 (X86vzext (v4i32 (bitconvert (v2i64 (X86vzload addr:$src)))))),
6470             (PMOVZXDQrm addr:$src)>;
6471 }
6472
6473 //===----------------------------------------------------------------------===//
6474 // SSE4.1 - Extract Instructions
6475 //===----------------------------------------------------------------------===//
6476
6477 /// SS41I_binop_ext8 - SSE 4.1 extract 8 bits to 32 bit reg or 8 bit mem
6478 multiclass SS41I_extract8<bits<8> opc, string OpcodeStr> {
6479   def rr : SS4AIi8<opc, MRMDestReg, (outs GR32orGR64:$dst),
6480                  (ins VR128:$src1, i32i8imm:$src2),
6481                  !strconcat(OpcodeStr,
6482                             "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6483                  [(set GR32orGR64:$dst, (X86pextrb (v16i8 VR128:$src1),
6484                                          imm:$src2))]>,
6485                   Sched<[WriteShuffle]>;
6486   let neverHasSideEffects = 1, mayStore = 1,
6487       SchedRW = [WriteShuffleLd, WriteRMW] in
6488   def mr : SS4AIi8<opc, MRMDestMem, (outs),
6489                  (ins i8mem:$dst, VR128:$src1, i32i8imm:$src2),
6490                  !strconcat(OpcodeStr,
6491                             "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6492                  [(store (i8 (trunc (assertzext (X86pextrb (v16i8 VR128:$src1),
6493                                                  imm:$src2)))), addr:$dst)]>;
6494 }
6495
6496 let Predicates = [HasAVX] in
6497   defm VPEXTRB : SS41I_extract8<0x14, "vpextrb">, VEX;
6498
6499 defm PEXTRB      : SS41I_extract8<0x14, "pextrb">;
6500
6501
6502 /// SS41I_extract16 - SSE 4.1 extract 16 bits to memory destination
6503 multiclass SS41I_extract16<bits<8> opc, string OpcodeStr> {
6504   let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0 in
6505   def rr_REV : SS4AIi8<opc, MRMDestReg, (outs GR32orGR64:$dst),
6506                    (ins VR128:$src1, i32i8imm:$src2),
6507                    !strconcat(OpcodeStr,
6508                    "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6509                    []>, Sched<[WriteShuffle]>;
6510
6511   let neverHasSideEffects = 1, mayStore = 1,
6512       SchedRW = [WriteShuffleLd, WriteRMW] in
6513   def mr : SS4AIi8<opc, MRMDestMem, (outs),
6514                  (ins i16mem:$dst, VR128:$src1, i32i8imm:$src2),
6515                  !strconcat(OpcodeStr,
6516                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6517                  [(store (i16 (trunc (assertzext (X86pextrw (v8i16 VR128:$src1),
6518                                                   imm:$src2)))), addr:$dst)]>;
6519 }
6520
6521 let Predicates = [HasAVX] in
6522   defm VPEXTRW : SS41I_extract16<0x15, "vpextrw">, VEX;
6523
6524 defm PEXTRW      : SS41I_extract16<0x15, "pextrw">;
6525
6526
6527 /// SS41I_extract32 - SSE 4.1 extract 32 bits to int reg or memory destination
6528 multiclass SS41I_extract32<bits<8> opc, string OpcodeStr> {
6529   def rr : SS4AIi8<opc, MRMDestReg, (outs GR32:$dst),
6530                  (ins VR128:$src1, i32i8imm:$src2),
6531                  !strconcat(OpcodeStr,
6532                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6533                  [(set GR32:$dst,
6534                   (extractelt (v4i32 VR128:$src1), imm:$src2))]>,
6535                   Sched<[WriteShuffle]>;
6536   let SchedRW = [WriteShuffleLd, WriteRMW] in
6537   def mr : SS4AIi8<opc, MRMDestMem, (outs),
6538                  (ins i32mem:$dst, VR128:$src1, i32i8imm:$src2),
6539                  !strconcat(OpcodeStr,
6540                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6541                  [(store (extractelt (v4i32 VR128:$src1), imm:$src2),
6542                           addr:$dst)]>;
6543 }
6544
6545 let Predicates = [HasAVX] in
6546   defm VPEXTRD : SS41I_extract32<0x16, "vpextrd">, VEX;
6547
6548 defm PEXTRD      : SS41I_extract32<0x16, "pextrd">;
6549
6550 /// SS41I_extract32 - SSE 4.1 extract 32 bits to int reg or memory destination
6551 multiclass SS41I_extract64<bits<8> opc, string OpcodeStr> {
6552   def rr : SS4AIi8<opc, MRMDestReg, (outs GR64:$dst),
6553                  (ins VR128:$src1, i32i8imm:$src2),
6554                  !strconcat(OpcodeStr,
6555                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6556                  [(set GR64:$dst,
6557                   (extractelt (v2i64 VR128:$src1), imm:$src2))]>,
6558                   Sched<[WriteShuffle]>, REX_W;
6559   let SchedRW = [WriteShuffleLd, WriteRMW] in
6560   def mr : SS4AIi8<opc, MRMDestMem, (outs),
6561                  (ins i64mem:$dst, VR128:$src1, i32i8imm:$src2),
6562                  !strconcat(OpcodeStr,
6563                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6564                  [(store (extractelt (v2i64 VR128:$src1), imm:$src2),
6565                           addr:$dst)]>, REX_W;
6566 }
6567
6568 let Predicates = [HasAVX] in
6569   defm VPEXTRQ : SS41I_extract64<0x16, "vpextrq">, VEX, VEX_W;
6570
6571 defm PEXTRQ      : SS41I_extract64<0x16, "pextrq">;
6572
6573 /// SS41I_extractf32 - SSE 4.1 extract 32 bits fp value to int reg or memory
6574 /// destination
6575 multiclass SS41I_extractf32<bits<8> opc, string OpcodeStr,
6576                             OpndItins itins = DEFAULT_ITINS> {
6577   def rr : SS4AIi8<opc, MRMDestReg, (outs GR32orGR64:$dst),
6578                  (ins VR128:$src1, i32i8imm:$src2),
6579                  !strconcat(OpcodeStr,
6580                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6581                  [(set GR32orGR64:$dst,
6582                     (extractelt (bc_v4i32 (v4f32 VR128:$src1)), imm:$src2))],
6583                     itins.rr>, Sched<[WriteFBlend]>;
6584   let SchedRW = [WriteFBlendLd, WriteRMW] in
6585   def mr : SS4AIi8<opc, MRMDestMem, (outs),
6586                  (ins f32mem:$dst, VR128:$src1, i32i8imm:$src2),
6587                  !strconcat(OpcodeStr,
6588                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6589                  [(store (extractelt (bc_v4i32 (v4f32 VR128:$src1)), imm:$src2),
6590                           addr:$dst)], itins.rm>;
6591 }
6592
6593 let ExeDomain = SSEPackedSingle in {
6594   let Predicates = [UseAVX] in
6595     defm VEXTRACTPS : SS41I_extractf32<0x17, "vextractps">, VEX;
6596   defm EXTRACTPS   : SS41I_extractf32<0x17, "extractps", SSE_EXTRACT_ITINS>;
6597 }
6598
6599 // Also match an EXTRACTPS store when the store is done as f32 instead of i32.
6600 def : Pat<(store (f32 (bitconvert (extractelt (bc_v4i32 (v4f32 VR128:$src1)),
6601                                               imm:$src2))),
6602                  addr:$dst),
6603           (VEXTRACTPSmr addr:$dst, VR128:$src1, imm:$src2)>,
6604           Requires<[HasAVX]>;
6605 def : Pat<(store (f32 (bitconvert (extractelt (bc_v4i32 (v4f32 VR128:$src1)),
6606                                               imm:$src2))),
6607                  addr:$dst),
6608           (EXTRACTPSmr addr:$dst, VR128:$src1, imm:$src2)>,
6609           Requires<[UseSSE41]>;
6610
6611 //===----------------------------------------------------------------------===//
6612 // SSE4.1 - Insert Instructions
6613 //===----------------------------------------------------------------------===//
6614
6615 multiclass SS41I_insert8<bits<8> opc, string asm, bit Is2Addr = 1> {
6616   def rr : SS4AIi8<opc, MRMSrcReg, (outs VR128:$dst),
6617       (ins VR128:$src1, GR32orGR64:$src2, i32i8imm:$src3),
6618       !if(Is2Addr,
6619         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6620         !strconcat(asm,
6621                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6622       [(set VR128:$dst,
6623         (X86pinsrb VR128:$src1, GR32orGR64:$src2, imm:$src3))]>,
6624       Sched<[WriteShuffle]>;
6625   def rm : SS4AIi8<opc, MRMSrcMem, (outs VR128:$dst),
6626       (ins VR128:$src1, i8mem:$src2, i32i8imm:$src3),
6627       !if(Is2Addr,
6628         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6629         !strconcat(asm,
6630                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6631       [(set VR128:$dst,
6632         (X86pinsrb VR128:$src1, (extloadi8 addr:$src2),
6633                    imm:$src3))]>, Sched<[WriteShuffleLd, ReadAfterLd]>;
6634 }
6635
6636 let Predicates = [HasAVX] in
6637   defm VPINSRB : SS41I_insert8<0x20, "vpinsrb", 0>, VEX_4V;
6638 let Constraints = "$src1 = $dst" in
6639   defm PINSRB  : SS41I_insert8<0x20, "pinsrb">;
6640
6641 multiclass SS41I_insert32<bits<8> opc, string asm, bit Is2Addr = 1> {
6642   def rr : SS4AIi8<opc, MRMSrcReg, (outs VR128:$dst),
6643       (ins VR128:$src1, GR32:$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         (v4i32 (insertelt VR128:$src1, GR32:$src2, imm:$src3)))]>,
6650       Sched<[WriteShuffle]>;
6651   def rm : SS4AIi8<opc, MRMSrcMem, (outs VR128:$dst),
6652       (ins VR128:$src1, i32mem:$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         (v4i32 (insertelt VR128:$src1, (loadi32 addr:$src2),
6659                           imm:$src3)))]>, Sched<[WriteShuffleLd, ReadAfterLd]>;
6660 }
6661
6662 let Predicates = [HasAVX] in
6663   defm VPINSRD : SS41I_insert32<0x22, "vpinsrd", 0>, VEX_4V;
6664 let Constraints = "$src1 = $dst" in
6665   defm PINSRD : SS41I_insert32<0x22, "pinsrd">;
6666
6667 multiclass SS41I_insert64<bits<8> opc, string asm, bit Is2Addr = 1> {
6668   def rr : SS4AIi8<opc, MRMSrcReg, (outs VR128:$dst),
6669       (ins VR128:$src1, GR64:$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         (v2i64 (insertelt VR128:$src1, GR64:$src2, imm:$src3)))]>,
6676       Sched<[WriteShuffle]>;
6677   def rm : SS4AIi8<opc, MRMSrcMem, (outs VR128:$dst),
6678       (ins VR128:$src1, i64mem:$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         (v2i64 (insertelt VR128:$src1, (loadi64 addr:$src2),
6685                           imm:$src3)))]>, Sched<[WriteShuffleLd, ReadAfterLd]>;
6686 }
6687
6688 let Predicates = [HasAVX] in
6689   defm VPINSRQ : SS41I_insert64<0x22, "vpinsrq", 0>, VEX_4V, VEX_W;
6690 let Constraints = "$src1 = $dst" in
6691   defm PINSRQ : SS41I_insert64<0x22, "pinsrq">, REX_W;
6692
6693 // insertps has a few different modes, there's the first two here below which
6694 // are optimized inserts that won't zero arbitrary elements in the destination
6695 // vector. The next one matches the intrinsic and could zero arbitrary elements
6696 // in the target vector.
6697 multiclass SS41I_insertf32<bits<8> opc, string asm, bit Is2Addr = 1,
6698                            OpndItins itins = DEFAULT_ITINS> {
6699   def rr : SS4AIi8<opc, MRMSrcReg, (outs VR128:$dst),
6700       (ins VR128:$src1, VR128:$src2, i8imm:$src3),
6701       !if(Is2Addr,
6702         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6703         !strconcat(asm,
6704                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6705       [(set VR128:$dst,
6706         (X86insertps VR128:$src1, VR128:$src2, imm:$src3))], itins.rr>,
6707       Sched<[WriteFShuffle]>;
6708   def rm : SS4AIi8<opc, MRMSrcMem, (outs VR128:$dst),
6709       (ins VR128:$src1, f32mem:$src2, i8imm:$src3),
6710       !if(Is2Addr,
6711         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6712         !strconcat(asm,
6713                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6714       [(set VR128:$dst,
6715         (X86insertps VR128:$src1,
6716                    (v4f32 (scalar_to_vector (loadf32 addr:$src2))),
6717                     imm:$src3))], itins.rm>,
6718       Sched<[WriteFShuffleLd, ReadAfterLd]>;
6719 }
6720
6721 let ExeDomain = SSEPackedSingle in {
6722   let Predicates = [UseAVX] in
6723     defm VINSERTPS : SS41I_insertf32<0x21, "vinsertps", 0>, VEX_4V;
6724   let Constraints = "$src1 = $dst" in
6725     defm INSERTPS : SS41I_insertf32<0x21, "insertps", 1, SSE_INSERT_ITINS>;
6726 }
6727
6728 let Predicates = [UseSSE41] in {
6729   // If we're inserting an element from a load or a null pshuf of a load,
6730   // fold the load into the insertps instruction.
6731   def : Pat<(v4f32 (X86insertps (v4f32 VR128:$src1), (X86PShufd (v4f32
6732                        (scalar_to_vector (loadf32 addr:$src2))), (i8 0)),
6733                    imm:$src3)),
6734             (INSERTPSrm VR128:$src1, addr:$src2, imm:$src3)>;
6735   def : Pat<(v4f32 (X86insertps (v4f32 VR128:$src1), (X86PShufd
6736                       (loadv4f32 addr:$src2), (i8 0)), imm:$src3)),
6737             (INSERTPSrm VR128:$src1, addr:$src2, imm:$src3)>;
6738 }
6739
6740 let Predicates = [UseAVX] in {
6741   // If we're inserting an element from a vbroadcast of a load, fold the
6742   // load into the X86insertps instruction.
6743   def : Pat<(v4f32 (X86insertps (v4f32 VR128:$src1),
6744                 (X86VBroadcast (loadf32 addr:$src2)), imm:$src3)),
6745             (VINSERTPSrm VR128:$src1, addr:$src2, imm:$src3)>;
6746   def : Pat<(v4f32 (X86insertps (v4f32 VR128:$src1),
6747                 (X86VBroadcast (loadv4f32 addr:$src2)), imm:$src3)),
6748             (VINSERTPSrm VR128:$src1, addr:$src2, imm:$src3)>;
6749 }
6750
6751 //===----------------------------------------------------------------------===//
6752 // SSE4.1 - Round Instructions
6753 //===----------------------------------------------------------------------===//
6754
6755 multiclass sse41_fp_unop_rm<bits<8> opcps, bits<8> opcpd, string OpcodeStr,
6756                             X86MemOperand x86memop, RegisterClass RC,
6757                             PatFrag mem_frag32, PatFrag mem_frag64,
6758                             Intrinsic V4F32Int, Intrinsic V2F64Int> {
6759 let ExeDomain = SSEPackedSingle in {
6760   // Intrinsic operation, reg.
6761   // Vector intrinsic operation, reg
6762   def PSr : SS4AIi8<opcps, MRMSrcReg,
6763                     (outs RC:$dst), (ins RC:$src1, i32i8imm:$src2),
6764                     !strconcat(OpcodeStr,
6765                     "ps\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6766                     [(set RC:$dst, (V4F32Int RC:$src1, imm:$src2))],
6767                     IIC_SSE_ROUNDPS_REG>, Sched<[WriteFAdd]>;
6768
6769   // Vector intrinsic operation, mem
6770   def PSm : SS4AIi8<opcps, MRMSrcMem,
6771                     (outs RC:$dst), (ins x86memop:$src1, i32i8imm:$src2),
6772                     !strconcat(OpcodeStr,
6773                     "ps\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6774                     [(set RC:$dst,
6775                           (V4F32Int (mem_frag32 addr:$src1),imm:$src2))],
6776                           IIC_SSE_ROUNDPS_MEM>, Sched<[WriteFAddLd]>;
6777 } // ExeDomain = SSEPackedSingle
6778
6779 let ExeDomain = SSEPackedDouble in {
6780   // Vector intrinsic operation, reg
6781   def PDr : SS4AIi8<opcpd, MRMSrcReg,
6782                     (outs RC:$dst), (ins RC:$src1, i32i8imm:$src2),
6783                     !strconcat(OpcodeStr,
6784                     "pd\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6785                     [(set RC:$dst, (V2F64Int RC:$src1, imm:$src2))],
6786                     IIC_SSE_ROUNDPS_REG>, Sched<[WriteFAdd]>;
6787
6788   // Vector intrinsic operation, mem
6789   def PDm : SS4AIi8<opcpd, MRMSrcMem,
6790                     (outs RC:$dst), (ins x86memop:$src1, i32i8imm:$src2),
6791                     !strconcat(OpcodeStr,
6792                     "pd\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6793                     [(set RC:$dst,
6794                           (V2F64Int (mem_frag64 addr:$src1),imm:$src2))],
6795                           IIC_SSE_ROUNDPS_REG>, Sched<[WriteFAddLd]>;
6796 } // ExeDomain = SSEPackedDouble
6797 }
6798
6799 multiclass sse41_fp_binop_rm<bits<8> opcss, bits<8> opcsd,
6800                             string OpcodeStr,
6801                             Intrinsic F32Int,
6802                             Intrinsic F64Int, bit Is2Addr = 1> {
6803 let ExeDomain = GenericDomain in {
6804   // Operation, reg.
6805   let hasSideEffects = 0 in
6806   def SSr : SS4AIi8<opcss, MRMSrcReg,
6807       (outs FR32:$dst), (ins FR32:$src1, FR32:$src2, i32i8imm:$src3),
6808       !if(Is2Addr,
6809           !strconcat(OpcodeStr,
6810               "ss\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6811           !strconcat(OpcodeStr,
6812               "ss\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6813       []>, Sched<[WriteFAdd]>;
6814
6815   // Intrinsic operation, reg.
6816   let isCodeGenOnly = 1 in
6817   def SSr_Int : SS4AIi8<opcss, MRMSrcReg,
6818         (outs VR128:$dst), (ins VR128:$src1, VR128:$src2, i32i8imm:$src3),
6819         !if(Is2Addr,
6820             !strconcat(OpcodeStr,
6821                 "ss\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6822             !strconcat(OpcodeStr,
6823                 "ss\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6824         [(set VR128:$dst, (F32Int VR128:$src1, VR128:$src2, imm:$src3))]>,
6825         Sched<[WriteFAdd]>;
6826
6827   // Intrinsic operation, mem.
6828   def SSm : SS4AIi8<opcss, MRMSrcMem,
6829         (outs VR128:$dst), (ins VR128:$src1, ssmem:$src2, i32i8imm:$src3),
6830         !if(Is2Addr,
6831             !strconcat(OpcodeStr,
6832                 "ss\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6833             !strconcat(OpcodeStr,
6834                 "ss\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6835         [(set VR128:$dst,
6836              (F32Int VR128:$src1, sse_load_f32:$src2, imm:$src3))]>,
6837         Sched<[WriteFAddLd, ReadAfterLd]>;
6838
6839   // Operation, reg.
6840   let hasSideEffects = 0 in
6841   def SDr : SS4AIi8<opcsd, MRMSrcReg,
6842         (outs FR64:$dst), (ins FR64:$src1, FR64:$src2, i32i8imm:$src3),
6843         !if(Is2Addr,
6844             !strconcat(OpcodeStr,
6845                 "sd\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6846             !strconcat(OpcodeStr,
6847                 "sd\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6848         []>, Sched<[WriteFAdd]>;
6849
6850   // Intrinsic operation, reg.
6851   let isCodeGenOnly = 1 in
6852   def SDr_Int : SS4AIi8<opcsd, MRMSrcReg,
6853         (outs VR128:$dst), (ins VR128:$src1, VR128:$src2, i32i8imm:$src3),
6854         !if(Is2Addr,
6855             !strconcat(OpcodeStr,
6856                 "sd\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6857             !strconcat(OpcodeStr,
6858                 "sd\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6859         [(set VR128:$dst, (F64Int VR128:$src1, VR128:$src2, imm:$src3))]>,
6860         Sched<[WriteFAdd]>;
6861
6862   // Intrinsic operation, mem.
6863   def SDm : SS4AIi8<opcsd, MRMSrcMem,
6864         (outs VR128:$dst), (ins VR128:$src1, sdmem:$src2, i32i8imm:$src3),
6865         !if(Is2Addr,
6866             !strconcat(OpcodeStr,
6867                 "sd\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6868             !strconcat(OpcodeStr,
6869                 "sd\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6870         [(set VR128:$dst,
6871               (F64Int VR128:$src1, sse_load_f64:$src2, imm:$src3))]>,
6872         Sched<[WriteFAddLd, ReadAfterLd]>;
6873 } // ExeDomain = GenericDomain
6874 }
6875
6876 // FP round - roundss, roundps, roundsd, roundpd
6877 let Predicates = [HasAVX] in {
6878   // Intrinsic form
6879   defm VROUND  : sse41_fp_unop_rm<0x08, 0x09, "vround", f128mem, VR128,
6880                                   loadv4f32, loadv2f64,
6881                                   int_x86_sse41_round_ps,
6882                                   int_x86_sse41_round_pd>, VEX;
6883   defm VROUNDY : sse41_fp_unop_rm<0x08, 0x09, "vround", f256mem, VR256,
6884                                   loadv8f32, loadv4f64,
6885                                   int_x86_avx_round_ps_256,
6886                                   int_x86_avx_round_pd_256>, VEX, VEX_L;
6887   defm VROUND  : sse41_fp_binop_rm<0x0A, 0x0B, "vround",
6888                                   int_x86_sse41_round_ss,
6889                                   int_x86_sse41_round_sd, 0>, VEX_4V, VEX_LIG;
6890
6891   def : Pat<(ffloor FR32:$src),
6892             (VROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x1))>;
6893   def : Pat<(f64 (ffloor FR64:$src)),
6894             (VROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x1))>;
6895   def : Pat<(f32 (fnearbyint FR32:$src)),
6896             (VROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0xC))>;
6897   def : Pat<(f64 (fnearbyint FR64:$src)),
6898             (VROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0xC))>;
6899   def : Pat<(f32 (fceil FR32:$src)),
6900             (VROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x2))>;
6901   def : Pat<(f64 (fceil FR64:$src)),
6902             (VROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x2))>;
6903   def : Pat<(f32 (frint FR32:$src)),
6904             (VROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x4))>;
6905   def : Pat<(f64 (frint FR64:$src)),
6906             (VROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x4))>;
6907   def : Pat<(f32 (ftrunc FR32:$src)),
6908             (VROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x3))>;
6909   def : Pat<(f64 (ftrunc FR64:$src)),
6910             (VROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x3))>;
6911
6912   def : Pat<(v4f32 (ffloor VR128:$src)),
6913             (VROUNDPSr VR128:$src, (i32 0x1))>;
6914   def : Pat<(v4f32 (fnearbyint VR128:$src)),
6915             (VROUNDPSr VR128:$src, (i32 0xC))>;
6916   def : Pat<(v4f32 (fceil VR128:$src)),
6917             (VROUNDPSr VR128:$src, (i32 0x2))>;
6918   def : Pat<(v4f32 (frint VR128:$src)),
6919             (VROUNDPSr VR128:$src, (i32 0x4))>;
6920   def : Pat<(v4f32 (ftrunc VR128:$src)),
6921             (VROUNDPSr VR128:$src, (i32 0x3))>;
6922
6923   def : Pat<(v2f64 (ffloor VR128:$src)),
6924             (VROUNDPDr VR128:$src, (i32 0x1))>;
6925   def : Pat<(v2f64 (fnearbyint VR128:$src)),
6926             (VROUNDPDr VR128:$src, (i32 0xC))>;
6927   def : Pat<(v2f64 (fceil VR128:$src)),
6928             (VROUNDPDr VR128:$src, (i32 0x2))>;
6929   def : Pat<(v2f64 (frint VR128:$src)),
6930             (VROUNDPDr VR128:$src, (i32 0x4))>;
6931   def : Pat<(v2f64 (ftrunc VR128:$src)),
6932             (VROUNDPDr VR128:$src, (i32 0x3))>;
6933
6934   def : Pat<(v8f32 (ffloor VR256:$src)),
6935             (VROUNDYPSr VR256:$src, (i32 0x1))>;
6936   def : Pat<(v8f32 (fnearbyint VR256:$src)),
6937             (VROUNDYPSr VR256:$src, (i32 0xC))>;
6938   def : Pat<(v8f32 (fceil VR256:$src)),
6939             (VROUNDYPSr VR256:$src, (i32 0x2))>;
6940   def : Pat<(v8f32 (frint VR256:$src)),
6941             (VROUNDYPSr VR256:$src, (i32 0x4))>;
6942   def : Pat<(v8f32 (ftrunc VR256:$src)),
6943             (VROUNDYPSr VR256:$src, (i32 0x3))>;
6944
6945   def : Pat<(v4f64 (ffloor VR256:$src)),
6946             (VROUNDYPDr VR256:$src, (i32 0x1))>;
6947   def : Pat<(v4f64 (fnearbyint VR256:$src)),
6948             (VROUNDYPDr VR256:$src, (i32 0xC))>;
6949   def : Pat<(v4f64 (fceil VR256:$src)),
6950             (VROUNDYPDr VR256:$src, (i32 0x2))>;
6951   def : Pat<(v4f64 (frint VR256:$src)),
6952             (VROUNDYPDr VR256:$src, (i32 0x4))>;
6953   def : Pat<(v4f64 (ftrunc VR256:$src)),
6954             (VROUNDYPDr VR256:$src, (i32 0x3))>;
6955 }
6956
6957 defm ROUND  : sse41_fp_unop_rm<0x08, 0x09, "round", f128mem, VR128,
6958                                memopv4f32, memopv2f64,
6959                                int_x86_sse41_round_ps, int_x86_sse41_round_pd>;
6960 let Constraints = "$src1 = $dst" in
6961 defm ROUND  : sse41_fp_binop_rm<0x0A, 0x0B, "round",
6962                                int_x86_sse41_round_ss, int_x86_sse41_round_sd>;
6963
6964 let Predicates = [UseSSE41] in {
6965   def : Pat<(ffloor FR32:$src),
6966             (ROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x1))>;
6967   def : Pat<(f64 (ffloor FR64:$src)),
6968             (ROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x1))>;
6969   def : Pat<(f32 (fnearbyint FR32:$src)),
6970             (ROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0xC))>;
6971   def : Pat<(f64 (fnearbyint FR64:$src)),
6972             (ROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0xC))>;
6973   def : Pat<(f32 (fceil FR32:$src)),
6974             (ROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x2))>;
6975   def : Pat<(f64 (fceil FR64:$src)),
6976             (ROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x2))>;
6977   def : Pat<(f32 (frint FR32:$src)),
6978             (ROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x4))>;
6979   def : Pat<(f64 (frint FR64:$src)),
6980             (ROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x4))>;
6981   def : Pat<(f32 (ftrunc FR32:$src)),
6982             (ROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x3))>;
6983   def : Pat<(f64 (ftrunc FR64:$src)),
6984             (ROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x3))>;
6985
6986   def : Pat<(v4f32 (ffloor VR128:$src)),
6987             (ROUNDPSr VR128:$src, (i32 0x1))>;
6988   def : Pat<(v4f32 (fnearbyint VR128:$src)),
6989             (ROUNDPSr VR128:$src, (i32 0xC))>;
6990   def : Pat<(v4f32 (fceil VR128:$src)),
6991             (ROUNDPSr VR128:$src, (i32 0x2))>;
6992   def : Pat<(v4f32 (frint VR128:$src)),
6993             (ROUNDPSr VR128:$src, (i32 0x4))>;
6994   def : Pat<(v4f32 (ftrunc VR128:$src)),
6995             (ROUNDPSr VR128:$src, (i32 0x3))>;
6996
6997   def : Pat<(v2f64 (ffloor VR128:$src)),
6998             (ROUNDPDr VR128:$src, (i32 0x1))>;
6999   def : Pat<(v2f64 (fnearbyint VR128:$src)),
7000             (ROUNDPDr VR128:$src, (i32 0xC))>;
7001   def : Pat<(v2f64 (fceil VR128:$src)),
7002             (ROUNDPDr VR128:$src, (i32 0x2))>;
7003   def : Pat<(v2f64 (frint VR128:$src)),
7004             (ROUNDPDr VR128:$src, (i32 0x4))>;
7005   def : Pat<(v2f64 (ftrunc VR128:$src)),
7006             (ROUNDPDr VR128:$src, (i32 0x3))>;
7007 }
7008
7009 //===----------------------------------------------------------------------===//
7010 // SSE4.1 - Packed Bit Test
7011 //===----------------------------------------------------------------------===//
7012
7013 // ptest instruction we'll lower to this in X86ISelLowering primarily from
7014 // the intel intrinsic that corresponds to this.
7015 let Defs = [EFLAGS], Predicates = [HasAVX] in {
7016 def VPTESTrr  : SS48I<0x17, MRMSrcReg, (outs), (ins VR128:$src1, VR128:$src2),
7017                 "vptest\t{$src2, $src1|$src1, $src2}",
7018                 [(set EFLAGS, (X86ptest VR128:$src1, (v2i64 VR128:$src2)))]>,
7019                 Sched<[WriteVecLogic]>, VEX;
7020 def VPTESTrm  : SS48I<0x17, MRMSrcMem, (outs), (ins VR128:$src1, f128mem:$src2),
7021                 "vptest\t{$src2, $src1|$src1, $src2}",
7022                 [(set EFLAGS,(X86ptest VR128:$src1, (loadv2i64 addr:$src2)))]>,
7023                 Sched<[WriteVecLogicLd, ReadAfterLd]>, VEX;
7024
7025 def VPTESTYrr : SS48I<0x17, MRMSrcReg, (outs), (ins VR256:$src1, VR256:$src2),
7026                 "vptest\t{$src2, $src1|$src1, $src2}",
7027                 [(set EFLAGS, (X86ptest VR256:$src1, (v4i64 VR256:$src2)))]>,
7028                 Sched<[WriteVecLogic]>, VEX, VEX_L;
7029 def VPTESTYrm : SS48I<0x17, MRMSrcMem, (outs), (ins VR256:$src1, i256mem:$src2),
7030                 "vptest\t{$src2, $src1|$src1, $src2}",
7031                 [(set EFLAGS,(X86ptest VR256:$src1, (loadv4i64 addr:$src2)))]>,
7032                 Sched<[WriteVecLogicLd, ReadAfterLd]>, VEX, VEX_L;
7033 }
7034
7035 let Defs = [EFLAGS] in {
7036 def PTESTrr : SS48I<0x17, MRMSrcReg, (outs), (ins VR128:$src1, VR128:$src2),
7037               "ptest\t{$src2, $src1|$src1, $src2}",
7038               [(set EFLAGS, (X86ptest VR128:$src1, (v2i64 VR128:$src2)))]>,
7039               Sched<[WriteVecLogic]>;
7040 def PTESTrm : SS48I<0x17, MRMSrcMem, (outs), (ins VR128:$src1, f128mem:$src2),
7041               "ptest\t{$src2, $src1|$src1, $src2}",
7042               [(set EFLAGS, (X86ptest VR128:$src1, (memopv2i64 addr:$src2)))]>,
7043               Sched<[WriteVecLogicLd, ReadAfterLd]>;
7044 }
7045
7046 // The bit test instructions below are AVX only
7047 multiclass avx_bittest<bits<8> opc, string OpcodeStr, RegisterClass RC,
7048                        X86MemOperand x86memop, PatFrag mem_frag, ValueType vt> {
7049   def rr : SS48I<opc, MRMSrcReg, (outs), (ins RC:$src1, RC:$src2),
7050             !strconcat(OpcodeStr, "\t{$src2, $src1|$src1, $src2}"),
7051             [(set EFLAGS, (X86testp RC:$src1, (vt RC:$src2)))]>,
7052             Sched<[WriteVecLogic]>, VEX;
7053   def rm : SS48I<opc, MRMSrcMem, (outs), (ins RC:$src1, x86memop:$src2),
7054             !strconcat(OpcodeStr, "\t{$src2, $src1|$src1, $src2}"),
7055             [(set EFLAGS, (X86testp RC:$src1, (mem_frag addr:$src2)))]>,
7056             Sched<[WriteVecLogicLd, ReadAfterLd]>, VEX;
7057 }
7058
7059 let Defs = [EFLAGS], Predicates = [HasAVX] in {
7060 let ExeDomain = SSEPackedSingle in {
7061 defm VTESTPS  : avx_bittest<0x0E, "vtestps", VR128, f128mem, loadv4f32, v4f32>;
7062 defm VTESTPSY : avx_bittest<0x0E, "vtestps", VR256, f256mem, loadv8f32, v8f32>,
7063                             VEX_L;
7064 }
7065 let ExeDomain = SSEPackedDouble in {
7066 defm VTESTPD  : avx_bittest<0x0F, "vtestpd", VR128, f128mem, loadv2f64, v2f64>;
7067 defm VTESTPDY : avx_bittest<0x0F, "vtestpd", VR256, f256mem, loadv4f64, v4f64>,
7068                             VEX_L;
7069 }
7070 }
7071
7072 //===----------------------------------------------------------------------===//
7073 // SSE4.1 - Misc Instructions
7074 //===----------------------------------------------------------------------===//
7075
7076 let Defs = [EFLAGS], Predicates = [HasPOPCNT] in {
7077   def POPCNT16rr : I<0xB8, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
7078                      "popcnt{w}\t{$src, $dst|$dst, $src}",
7079                      [(set GR16:$dst, (ctpop GR16:$src)), (implicit EFLAGS)],
7080                      IIC_SSE_POPCNT_RR>, Sched<[WriteFAdd]>,
7081                      OpSize16, XS;
7082   def POPCNT16rm : I<0xB8, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
7083                      "popcnt{w}\t{$src, $dst|$dst, $src}",
7084                      [(set GR16:$dst, (ctpop (loadi16 addr:$src))),
7085                       (implicit EFLAGS)], IIC_SSE_POPCNT_RM>,
7086                       Sched<[WriteFAddLd]>, OpSize16, XS;
7087
7088   def POPCNT32rr : I<0xB8, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
7089                      "popcnt{l}\t{$src, $dst|$dst, $src}",
7090                      [(set GR32:$dst, (ctpop GR32:$src)), (implicit EFLAGS)],
7091                      IIC_SSE_POPCNT_RR>, Sched<[WriteFAdd]>,
7092                      OpSize32, XS;
7093
7094   def POPCNT32rm : I<0xB8, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
7095                      "popcnt{l}\t{$src, $dst|$dst, $src}",
7096                      [(set GR32:$dst, (ctpop (loadi32 addr:$src))),
7097                       (implicit EFLAGS)], IIC_SSE_POPCNT_RM>,
7098                       Sched<[WriteFAddLd]>, OpSize32, XS;
7099
7100   def POPCNT64rr : RI<0xB8, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
7101                       "popcnt{q}\t{$src, $dst|$dst, $src}",
7102                       [(set GR64:$dst, (ctpop GR64:$src)), (implicit EFLAGS)],
7103                       IIC_SSE_POPCNT_RR>, Sched<[WriteFAdd]>, XS;
7104   def POPCNT64rm : RI<0xB8, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
7105                       "popcnt{q}\t{$src, $dst|$dst, $src}",
7106                       [(set GR64:$dst, (ctpop (loadi64 addr:$src))),
7107                        (implicit EFLAGS)], IIC_SSE_POPCNT_RM>,
7108                        Sched<[WriteFAddLd]>, XS;
7109 }
7110
7111
7112
7113 // SS41I_unop_rm_int_v16 - SSE 4.1 unary operator whose type is v8i16.
7114 multiclass SS41I_unop_rm_int_v16<bits<8> opc, string OpcodeStr,
7115                                  Intrinsic IntId128,
7116                                  X86FoldableSchedWrite Sched> {
7117   def rr128 : SS48I<opc, MRMSrcReg, (outs VR128:$dst),
7118                     (ins VR128:$src),
7119                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
7120                     [(set VR128:$dst, (IntId128 VR128:$src))]>,
7121                     Sched<[Sched]>;
7122   def rm128 : SS48I<opc, MRMSrcMem, (outs VR128:$dst),
7123                      (ins i128mem:$src),
7124                      !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
7125                      [(set VR128:$dst,
7126                        (IntId128 (bitconvert (memopv2i64 addr:$src))))]>,
7127                     Sched<[Sched.Folded]>;
7128 }
7129
7130 // PHMIN has the same profile as PSAD, thus we use the same scheduling
7131 // model, although the naming is misleading.
7132 let Predicates = [HasAVX] in
7133 defm VPHMINPOSUW : SS41I_unop_rm_int_v16 <0x41, "vphminposuw",
7134                                          int_x86_sse41_phminposuw,
7135                                          WriteVecIMul>, VEX;
7136 defm PHMINPOSUW : SS41I_unop_rm_int_v16 <0x41, "phminposuw",
7137                                          int_x86_sse41_phminposuw,
7138                                          WriteVecIMul>;
7139
7140 /// SS41I_binop_rm_int - Simple SSE 4.1 binary operator
7141 multiclass SS41I_binop_rm_int<bits<8> opc, string OpcodeStr,
7142                               Intrinsic IntId128, bit Is2Addr = 1,
7143                               OpndItins itins = DEFAULT_ITINS> {
7144   let isCommutable = 1 in
7145   def rr : SS48I<opc, MRMSrcReg, (outs VR128:$dst),
7146        (ins VR128:$src1, VR128:$src2),
7147        !if(Is2Addr,
7148            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
7149            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
7150        [(set VR128:$dst, (IntId128 VR128:$src1, VR128:$src2))],
7151        itins.rr>, Sched<[itins.Sched]>;
7152   def rm : SS48I<opc, MRMSrcMem, (outs VR128:$dst),
7153        (ins VR128:$src1, i128mem:$src2),
7154        !if(Is2Addr,
7155            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
7156            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
7157        [(set VR128:$dst,
7158          (IntId128 VR128:$src1, (bitconvert (memopv2i64 addr:$src2))))],
7159        itins.rm>, Sched<[itins.Sched.Folded, ReadAfterLd]>;
7160 }
7161
7162 /// SS41I_binop_rm_int_y - Simple SSE 4.1 binary operator
7163 multiclass SS41I_binop_rm_int_y<bits<8> opc, string OpcodeStr,
7164                                 Intrinsic IntId256,
7165                                 X86FoldableSchedWrite Sched> {
7166   let isCommutable = 1 in
7167   def Yrr : SS48I<opc, MRMSrcReg, (outs VR256:$dst),
7168        (ins VR256:$src1, VR256:$src2),
7169        !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7170        [(set VR256:$dst, (IntId256 VR256:$src1, VR256:$src2))]>,
7171        Sched<[Sched]>;
7172   def Yrm : SS48I<opc, MRMSrcMem, (outs VR256:$dst),
7173        (ins VR256:$src1, i256mem:$src2),
7174        !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7175        [(set VR256:$dst,
7176          (IntId256 VR256:$src1, (bitconvert (loadv4i64 addr:$src2))))]>,
7177        Sched<[Sched.Folded, ReadAfterLd]>;
7178 }
7179
7180
7181 /// SS48I_binop_rm - Simple SSE41 binary operator.
7182 multiclass SS48I_binop_rm<bits<8> opc, string OpcodeStr, SDNode OpNode,
7183                           ValueType OpVT, RegisterClass RC, PatFrag memop_frag,
7184                           X86MemOperand x86memop, bit Is2Addr = 1,
7185                           OpndItins itins = SSE_INTALU_ITINS_P> {
7186   let isCommutable = 1 in
7187   def rr : SS48I<opc, MRMSrcReg, (outs RC:$dst),
7188        (ins RC:$src1, RC:$src2),
7189        !if(Is2Addr,
7190            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
7191            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
7192        [(set RC:$dst, (OpVT (OpNode RC:$src1, RC:$src2)))]>,
7193        Sched<[itins.Sched]>;
7194   def rm : SS48I<opc, MRMSrcMem, (outs RC:$dst),
7195        (ins RC:$src1, x86memop:$src2),
7196        !if(Is2Addr,
7197            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
7198            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
7199        [(set RC:$dst,
7200          (OpVT (OpNode RC:$src1, (bitconvert (memop_frag addr:$src2)))))]>,
7201        Sched<[itins.Sched.Folded, ReadAfterLd]>;
7202 }
7203
7204 /// SS48I_binop_rm2 - Simple SSE41 binary operator with different src and dst
7205 /// types.
7206 multiclass SS48I_binop_rm2<bits<8> opc, string OpcodeStr, SDNode OpNode,
7207                          ValueType DstVT, ValueType SrcVT, RegisterClass RC,
7208                          PatFrag memop_frag, X86MemOperand x86memop,
7209                          OpndItins itins,
7210                          bit IsCommutable = 0, bit Is2Addr = 1> {
7211   let isCommutable = IsCommutable in
7212   def rr : SS48I<opc, MRMSrcReg, (outs RC:$dst),
7213        (ins RC:$src1, RC:$src2),
7214        !if(Is2Addr,
7215            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
7216            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
7217        [(set RC:$dst, (DstVT (OpNode (SrcVT RC:$src1), RC:$src2)))]>,
7218        Sched<[itins.Sched]>;
7219   def rm : SS48I<opc, MRMSrcMem, (outs RC:$dst),
7220        (ins RC:$src1, x86memop:$src2),
7221        !if(Is2Addr,
7222            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
7223            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
7224        [(set RC:$dst, (DstVT (OpNode (SrcVT RC:$src1),
7225                                      (bitconvert (memop_frag addr:$src2)))))]>,
7226        Sched<[itins.Sched.Folded, ReadAfterLd]>;
7227 }
7228
7229 let Predicates = [HasAVX] in {
7230   let isCommutable = 0 in
7231   defm VPMINSB   : SS48I_binop_rm<0x38, "vpminsb", X86smin, v16i8, VR128,
7232                                   loadv2i64, i128mem, 0, SSE_INTALU_ITINS_P>,
7233                                   VEX_4V;
7234   defm VPMINSD   : SS48I_binop_rm<0x39, "vpminsd", X86smin, v4i32, VR128,
7235                                   loadv2i64, i128mem, 0, SSE_INTALU_ITINS_P>,
7236                                   VEX_4V;
7237   defm VPMINUD   : SS48I_binop_rm<0x3B, "vpminud", X86umin, v4i32, VR128,
7238                                   loadv2i64, i128mem, 0, SSE_INTALU_ITINS_P>,
7239                                   VEX_4V;
7240   defm VPMINUW   : SS48I_binop_rm<0x3A, "vpminuw", X86umin, v8i16, VR128,
7241                                   loadv2i64, i128mem, 0, SSE_INTALU_ITINS_P>,
7242                                   VEX_4V;
7243   defm VPMAXSB   : SS48I_binop_rm<0x3C, "vpmaxsb", X86smax, v16i8, VR128,
7244                                   loadv2i64, i128mem, 0, SSE_INTALU_ITINS_P>,
7245                                   VEX_4V;
7246   defm VPMAXSD   : SS48I_binop_rm<0x3D, "vpmaxsd", X86smax, v4i32, VR128,
7247                                   loadv2i64, i128mem, 0, SSE_INTALU_ITINS_P>,
7248                                   VEX_4V;
7249   defm VPMAXUD   : SS48I_binop_rm<0x3F, "vpmaxud", X86umax, v4i32, VR128,
7250                                   loadv2i64, i128mem, 0, SSE_INTALU_ITINS_P>,
7251                                   VEX_4V;
7252   defm VPMAXUW   : SS48I_binop_rm<0x3E, "vpmaxuw", X86umax, v8i16, VR128,
7253                                   loadv2i64, i128mem, 0, SSE_INTALU_ITINS_P>,
7254                                   VEX_4V;
7255   defm VPMULDQ   : SS48I_binop_rm2<0x28, "vpmuldq", X86pmuldq, v2i64, v4i32,
7256                                    VR128, loadv2i64, i128mem,
7257                                    SSE_INTMUL_ITINS_P, 1, 0>, VEX_4V;
7258 }
7259
7260 let Predicates = [HasAVX2] in {
7261   let isCommutable = 0 in
7262   defm VPMINSBY  : SS48I_binop_rm<0x38, "vpminsb", X86smin, v32i8, VR256,
7263                                   loadv4i64, i256mem, 0, SSE_INTALU_ITINS_P>,
7264                                   VEX_4V, VEX_L;
7265   defm VPMINSDY  : SS48I_binop_rm<0x39, "vpminsd", X86smin, v8i32, VR256,
7266                                   loadv4i64, i256mem, 0, SSE_INTALU_ITINS_P>,
7267                                   VEX_4V, VEX_L;
7268   defm VPMINUDY  : SS48I_binop_rm<0x3B, "vpminud", X86umin, v8i32, VR256,
7269                                   loadv4i64, i256mem, 0, SSE_INTALU_ITINS_P>,
7270                                   VEX_4V, VEX_L;
7271   defm VPMINUWY  : SS48I_binop_rm<0x3A, "vpminuw", X86umin, v16i16, VR256,
7272                                   loadv4i64, i256mem, 0, SSE_INTALU_ITINS_P>,
7273                                   VEX_4V, VEX_L;
7274   defm VPMAXSBY  : SS48I_binop_rm<0x3C, "vpmaxsb", X86smax, v32i8, VR256,
7275                                   loadv4i64, i256mem, 0, SSE_INTALU_ITINS_P>,
7276                                   VEX_4V, VEX_L;
7277   defm VPMAXSDY  : SS48I_binop_rm<0x3D, "vpmaxsd", X86smax, v8i32, VR256,
7278                                   loadv4i64, i256mem, 0, SSE_INTALU_ITINS_P>,
7279                                   VEX_4V, VEX_L;
7280   defm VPMAXUDY  : SS48I_binop_rm<0x3F, "vpmaxud", X86umax, v8i32, VR256,
7281                                   loadv4i64, i256mem, 0, SSE_INTALU_ITINS_P>,
7282                                   VEX_4V, VEX_L;
7283   defm VPMAXUWY  : SS48I_binop_rm<0x3E, "vpmaxuw", X86umax, v16i16, VR256,
7284                                   loadv4i64, i256mem, 0, SSE_INTALU_ITINS_P>,
7285                                   VEX_4V, VEX_L;
7286   defm VPMULDQY : SS48I_binop_rm2<0x28, "vpmuldq", X86pmuldq, v4i64, v8i32,
7287                                   VR256, loadv4i64, i256mem,
7288                                   SSE_INTMUL_ITINS_P, 1, 0>, VEX_4V, VEX_L;
7289 }
7290
7291 let Constraints = "$src1 = $dst" in {
7292   let isCommutable = 0 in
7293   defm PMINSB   : SS48I_binop_rm<0x38, "pminsb", X86smin, v16i8, VR128,
7294                                  memopv2i64, i128mem, 1, SSE_INTALU_ITINS_P>;
7295   defm PMINSD   : SS48I_binop_rm<0x39, "pminsd", X86smin, v4i32, VR128,
7296                                  memopv2i64, i128mem, 1, SSE_INTALU_ITINS_P>;
7297   defm PMINUD   : SS48I_binop_rm<0x3B, "pminud", X86umin, v4i32, VR128,
7298                                  memopv2i64, i128mem, 1, SSE_INTALU_ITINS_P>;
7299   defm PMINUW   : SS48I_binop_rm<0x3A, "pminuw", X86umin, v8i16, VR128,
7300                                  memopv2i64, i128mem, 1, SSE_INTALU_ITINS_P>;
7301   defm PMAXSB   : SS48I_binop_rm<0x3C, "pmaxsb", X86smax, v16i8, VR128,
7302                                  memopv2i64, i128mem, 1, SSE_INTALU_ITINS_P>;
7303   defm PMAXSD   : SS48I_binop_rm<0x3D, "pmaxsd", X86smax, v4i32, VR128,
7304                                  memopv2i64, i128mem, 1, SSE_INTALU_ITINS_P>;
7305   defm PMAXUD   : SS48I_binop_rm<0x3F, "pmaxud", X86umax, v4i32, VR128,
7306                                  memopv2i64, i128mem, 1, SSE_INTALU_ITINS_P>;
7307   defm PMAXUW   : SS48I_binop_rm<0x3E, "pmaxuw", X86umax, v8i16, VR128,
7308                                  memopv2i64, i128mem, 1, SSE_INTALU_ITINS_P>;
7309   defm PMULDQ   : SS48I_binop_rm2<0x28, "pmuldq", X86pmuldq, v2i64, v4i32,
7310                                   VR128, memopv2i64, i128mem,
7311                                   SSE_INTMUL_ITINS_P, 1>;
7312 }
7313
7314 let Predicates = [HasAVX] in {
7315   defm VPMULLD  : SS48I_binop_rm<0x40, "vpmulld", mul, v4i32, VR128,
7316                                  memopv2i64, i128mem, 0, SSE_PMULLD_ITINS>,
7317                                  VEX_4V;
7318   defm VPCMPEQQ : SS48I_binop_rm<0x29, "vpcmpeqq", X86pcmpeq, v2i64, VR128,
7319                                  memopv2i64, i128mem, 0, SSE_INTALU_ITINS_P>,
7320                                  VEX_4V;
7321 }
7322 let Predicates = [HasAVX2] in {
7323   defm VPMULLDY  : SS48I_binop_rm<0x40, "vpmulld", mul, v8i32, VR256,
7324                                   memopv4i64, i256mem, 0, SSE_PMULLD_ITINS>,
7325                                   VEX_4V, VEX_L;
7326   defm VPCMPEQQY : SS48I_binop_rm<0x29, "vpcmpeqq", X86pcmpeq, v4i64, VR256,
7327                                   memopv4i64, i256mem, 0, SSE_INTALU_ITINS_P>,
7328                                   VEX_4V, VEX_L;
7329 }
7330
7331 let Constraints = "$src1 = $dst" in {
7332   defm PMULLD  : SS48I_binop_rm<0x40, "pmulld", mul, v4i32, VR128,
7333                                 memopv2i64, i128mem, 1, SSE_PMULLD_ITINS>;
7334   defm PCMPEQQ : SS48I_binop_rm<0x29, "pcmpeqq", X86pcmpeq, v2i64, VR128,
7335                                 memopv2i64, i128mem, 1, SSE_INTALUQ_ITINS_P>;
7336 }
7337
7338 /// SS41I_binop_rmi_int - SSE 4.1 binary operator with 8-bit immediate
7339 multiclass SS41I_binop_rmi_int<bits<8> opc, string OpcodeStr,
7340                  Intrinsic IntId, RegisterClass RC, PatFrag memop_frag,
7341                  X86MemOperand x86memop, bit Is2Addr = 1,
7342                  OpndItins itins = DEFAULT_ITINS> {
7343   let isCommutable = 1 in
7344   def rri : SS4AIi8<opc, MRMSrcReg, (outs RC:$dst),
7345         (ins RC:$src1, RC:$src2, i8imm:$src3),
7346         !if(Is2Addr,
7347             !strconcat(OpcodeStr,
7348                 "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
7349             !strconcat(OpcodeStr,
7350                 "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
7351         [(set RC:$dst, (IntId RC:$src1, RC:$src2, imm:$src3))], itins.rr>,
7352         Sched<[itins.Sched]>;
7353   def rmi : SS4AIi8<opc, MRMSrcMem, (outs RC:$dst),
7354         (ins RC:$src1, x86memop:$src2, i8imm:$src3),
7355         !if(Is2Addr,
7356             !strconcat(OpcodeStr,
7357                 "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
7358             !strconcat(OpcodeStr,
7359                 "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
7360         [(set RC:$dst,
7361           (IntId RC:$src1,
7362            (bitconvert (memop_frag addr:$src2)), imm:$src3))], itins.rm>,
7363         Sched<[itins.Sched.Folded, ReadAfterLd]>;
7364 }
7365
7366 let Predicates = [HasAVX] in {
7367   let isCommutable = 0 in {
7368     let ExeDomain = SSEPackedSingle in {
7369     defm VBLENDPS : SS41I_binop_rmi_int<0x0C, "vblendps", int_x86_sse41_blendps,
7370                                         VR128, loadv4f32, f128mem, 0,
7371                                         DEFAULT_ITINS_FBLENDSCHED>, VEX_4V;
7372     defm VBLENDPSY : SS41I_binop_rmi_int<0x0C, "vblendps",
7373                                     int_x86_avx_blend_ps_256, VR256, loadv8f32,
7374                                     f256mem, 0, DEFAULT_ITINS_FBLENDSCHED>,
7375                                     VEX_4V, VEX_L;
7376     }
7377     let ExeDomain = SSEPackedDouble in {
7378     defm VBLENDPD : SS41I_binop_rmi_int<0x0D, "vblendpd", int_x86_sse41_blendpd,
7379                                         VR128, loadv2f64, f128mem, 0,
7380                                         DEFAULT_ITINS_FBLENDSCHED>, VEX_4V;
7381     defm VBLENDPDY : SS41I_binop_rmi_int<0x0D, "vblendpd",
7382                                      int_x86_avx_blend_pd_256,VR256, loadv4f64,
7383                                      f256mem, 0, DEFAULT_ITINS_FBLENDSCHED>,
7384                                      VEX_4V, VEX_L;
7385     }
7386   defm VPBLENDW : SS41I_binop_rmi_int<0x0E, "vpblendw", int_x86_sse41_pblendw,
7387                                       VR128, loadv2i64, i128mem, 0,
7388                                       DEFAULT_ITINS_BLENDSCHED>, VEX_4V;
7389   defm VMPSADBW : SS41I_binop_rmi_int<0x42, "vmpsadbw", int_x86_sse41_mpsadbw,
7390                                       VR128, loadv2i64, i128mem, 0,
7391                                       DEFAULT_ITINS_MPSADSCHED>, VEX_4V;
7392   }
7393   let ExeDomain = SSEPackedSingle in
7394   defm VDPPS : SS41I_binop_rmi_int<0x40, "vdpps", int_x86_sse41_dpps,
7395                                    VR128, loadv4f32, f128mem, 0,
7396                                    SSE_DPPS_ITINS>, VEX_4V;
7397   let ExeDomain = SSEPackedDouble in
7398   defm VDPPD : SS41I_binop_rmi_int<0x41, "vdppd", int_x86_sse41_dppd,
7399                                    VR128, loadv2f64, f128mem, 0,
7400                                    SSE_DPPS_ITINS>, VEX_4V;
7401   let ExeDomain = SSEPackedSingle in
7402   defm VDPPSY : SS41I_binop_rmi_int<0x40, "vdpps", int_x86_avx_dp_ps_256,
7403                                     VR256, loadv8f32, i256mem, 0,
7404                                     SSE_DPPS_ITINS>, VEX_4V, VEX_L;
7405 }
7406
7407 let Predicates = [HasAVX2] in {
7408   let isCommutable = 0 in {
7409   defm VPBLENDWY : SS41I_binop_rmi_int<0x0E, "vpblendw", int_x86_avx2_pblendw,
7410                                   VR256, loadv4i64, i256mem, 0,
7411                                   DEFAULT_ITINS_BLENDSCHED>, VEX_4V, VEX_L;
7412   defm VMPSADBWY : SS41I_binop_rmi_int<0x42, "vmpsadbw", int_x86_avx2_mpsadbw,
7413                                   VR256, loadv4i64, i256mem, 0,
7414                                   DEFAULT_ITINS_MPSADSCHED>, VEX_4V, VEX_L;
7415   }
7416 }
7417
7418 let Constraints = "$src1 = $dst" in {
7419   let isCommutable = 0 in {
7420   let ExeDomain = SSEPackedSingle in
7421   defm BLENDPS : SS41I_binop_rmi_int<0x0C, "blendps", int_x86_sse41_blendps,
7422                                      VR128, memopv4f32, f128mem,
7423                                      1, SSE_INTALU_ITINS_FBLEND_P>;
7424   let ExeDomain = SSEPackedDouble in
7425   defm BLENDPD : SS41I_binop_rmi_int<0x0D, "blendpd", int_x86_sse41_blendpd,
7426                                      VR128, memopv2f64, f128mem,
7427                                      1, SSE_INTALU_ITINS_FBLEND_P>;
7428   defm PBLENDW : SS41I_binop_rmi_int<0x0E, "pblendw", int_x86_sse41_pblendw,
7429                                      VR128, memopv2i64, i128mem,
7430                                      1, SSE_INTALU_ITINS_BLEND_P>;
7431   defm MPSADBW : SS41I_binop_rmi_int<0x42, "mpsadbw", int_x86_sse41_mpsadbw,
7432                                      VR128, memopv2i64, i128mem,
7433                                      1, SSE_MPSADBW_ITINS>;
7434   }
7435   let ExeDomain = SSEPackedSingle in
7436   defm DPPS : SS41I_binop_rmi_int<0x40, "dpps", int_x86_sse41_dpps,
7437                                   VR128, memopv4f32, f128mem, 1,
7438                                   SSE_DPPS_ITINS>;
7439   let ExeDomain = SSEPackedDouble in
7440   defm DPPD : SS41I_binop_rmi_int<0x41, "dppd", int_x86_sse41_dppd,
7441                                   VR128, memopv2f64, f128mem, 1,
7442                                   SSE_DPPD_ITINS>;
7443 }
7444
7445 /// SS41I_quaternary_int_avx - AVX SSE 4.1 with 4 operators
7446 multiclass SS41I_quaternary_int_avx<bits<8> opc, string OpcodeStr,
7447                                     RegisterClass RC, X86MemOperand x86memop,
7448                                     PatFrag mem_frag, Intrinsic IntId,
7449                                     X86FoldableSchedWrite Sched> {
7450   def rr : Ii8<opc, MRMSrcReg, (outs RC:$dst),
7451                   (ins RC:$src1, RC:$src2, RC:$src3),
7452                   !strconcat(OpcodeStr,
7453                     "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
7454                   [(set RC:$dst, (IntId RC:$src1, RC:$src2, RC:$src3))],
7455                   NoItinerary, SSEPackedInt>, TAPD, VEX_4V, VEX_I8IMM,
7456                 Sched<[Sched]>;
7457
7458   def rm : Ii8<opc, MRMSrcMem, (outs RC:$dst),
7459                   (ins RC:$src1, x86memop:$src2, RC:$src3),
7460                   !strconcat(OpcodeStr,
7461                     "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
7462                   [(set RC:$dst,
7463                         (IntId RC:$src1, (bitconvert (mem_frag addr:$src2)),
7464                                RC:$src3))],
7465                   NoItinerary, SSEPackedInt>, TAPD, VEX_4V, VEX_I8IMM,
7466                 Sched<[Sched.Folded, ReadAfterLd]>;
7467 }
7468
7469 let Predicates = [HasAVX] in {
7470 let ExeDomain = SSEPackedDouble in {
7471 defm VBLENDVPD  : SS41I_quaternary_int_avx<0x4B, "vblendvpd", VR128, f128mem,
7472                                            loadv2f64, int_x86_sse41_blendvpd,
7473                                            WriteFVarBlend>;
7474 defm VBLENDVPDY : SS41I_quaternary_int_avx<0x4B, "vblendvpd", VR256, f256mem,
7475                                   loadv4f64, int_x86_avx_blendv_pd_256,
7476                                   WriteFVarBlend>, VEX_L;
7477 } // ExeDomain = SSEPackedDouble
7478 let ExeDomain = SSEPackedSingle in {
7479 defm VBLENDVPS  : SS41I_quaternary_int_avx<0x4A, "vblendvps", VR128, f128mem,
7480                                            loadv4f32, int_x86_sse41_blendvps,
7481                                            WriteFVarBlend>;
7482 defm VBLENDVPSY : SS41I_quaternary_int_avx<0x4A, "vblendvps", VR256, f256mem,
7483                                   loadv8f32, int_x86_avx_blendv_ps_256,
7484                                   WriteFVarBlend>, VEX_L;
7485 } // ExeDomain = SSEPackedSingle
7486 defm VPBLENDVB  : SS41I_quaternary_int_avx<0x4C, "vpblendvb", VR128, i128mem,
7487                                            loadv2i64, int_x86_sse41_pblendvb,
7488                                            WriteVarBlend>;
7489 }
7490
7491 let Predicates = [HasAVX2] in {
7492 defm VPBLENDVBY : SS41I_quaternary_int_avx<0x4C, "vpblendvb", VR256, i256mem,
7493                                       loadv4i64, int_x86_avx2_pblendvb,
7494                                       WriteVarBlend>, VEX_L;
7495 }
7496
7497 let Predicates = [HasAVX] in {
7498   def : Pat<(v16i8 (vselect (v16i8 VR128:$mask), (v16i8 VR128:$src1),
7499                             (v16i8 VR128:$src2))),
7500             (VPBLENDVBrr VR128:$src2, VR128:$src1, VR128:$mask)>;
7501   def : Pat<(v4i32 (vselect (v4i32 VR128:$mask), (v4i32 VR128:$src1),
7502                             (v4i32 VR128:$src2))),
7503             (VBLENDVPSrr VR128:$src2, VR128:$src1, VR128:$mask)>;
7504   def : Pat<(v4f32 (vselect (v4i32 VR128:$mask), (v4f32 VR128:$src1),
7505                             (v4f32 VR128:$src2))),
7506             (VBLENDVPSrr VR128:$src2, VR128:$src1, VR128:$mask)>;
7507   def : Pat<(v2i64 (vselect (v2i64 VR128:$mask), (v2i64 VR128:$src1),
7508                             (v2i64 VR128:$src2))),
7509             (VBLENDVPDrr VR128:$src2, VR128:$src1, VR128:$mask)>;
7510   def : Pat<(v2f64 (vselect (v2i64 VR128:$mask), (v2f64 VR128:$src1),
7511                             (v2f64 VR128:$src2))),
7512             (VBLENDVPDrr VR128:$src2, VR128:$src1, VR128:$mask)>;
7513   def : Pat<(v8i32 (vselect (v8i32 VR256:$mask), (v8i32 VR256:$src1),
7514                             (v8i32 VR256:$src2))),
7515             (VBLENDVPSYrr VR256:$src2, VR256:$src1, VR256:$mask)>;
7516   def : Pat<(v8f32 (vselect (v8i32 VR256:$mask), (v8f32 VR256:$src1),
7517                             (v8f32 VR256:$src2))),
7518             (VBLENDVPSYrr VR256:$src2, VR256:$src1, VR256:$mask)>;
7519   def : Pat<(v4i64 (vselect (v4i64 VR256:$mask), (v4i64 VR256:$src1),
7520                             (v4i64 VR256:$src2))),
7521             (VBLENDVPDYrr VR256:$src2, VR256:$src1, VR256:$mask)>;
7522   def : Pat<(v4f64 (vselect (v4i64 VR256:$mask), (v4f64 VR256:$src1),
7523                             (v4f64 VR256:$src2))),
7524             (VBLENDVPDYrr VR256:$src2, VR256:$src1, VR256:$mask)>;
7525
7526   def : Pat<(v8f32 (X86Blendi (v8f32 VR256:$src1), (v8f32 VR256:$src2),
7527                                (imm:$mask))),
7528             (VBLENDPSYrri VR256:$src1, VR256:$src2, imm:$mask)>;
7529   def : Pat<(v4f64 (X86Blendi (v4f64 VR256:$src1), (v4f64 VR256:$src2),
7530                                (imm:$mask))),
7531             (VBLENDPDYrri VR256:$src1, VR256:$src2, imm:$mask)>;
7532
7533   def : Pat<(v8i16 (X86Blendi (v8i16 VR128:$src1), (v8i16 VR128:$src2),
7534                                (imm:$mask))),
7535             (VPBLENDWrri VR128:$src1, VR128:$src2, imm:$mask)>;
7536   def : Pat<(v4f32 (X86Blendi (v4f32 VR128:$src1), (v4f32 VR128:$src2),
7537                                (imm:$mask))),
7538             (VBLENDPSrri VR128:$src1, VR128:$src2, imm:$mask)>;
7539   def : Pat<(v2f64 (X86Blendi (v2f64 VR128:$src1), (v2f64 VR128:$src2),
7540                                (imm:$mask))),
7541             (VBLENDPDrri VR128:$src1, VR128:$src2, imm:$mask)>;
7542 }
7543
7544 let Predicates = [HasAVX2] in {
7545   def : Pat<(v32i8 (vselect (v32i8 VR256:$mask), (v32i8 VR256:$src1),
7546                             (v32i8 VR256:$src2))),
7547             (VPBLENDVBYrr VR256:$src2, VR256:$src1, VR256:$mask)>;
7548   def : Pat<(v16i16 (X86Blendi (v16i16 VR256:$src1), (v16i16 VR256:$src2),
7549                                (imm:$mask))),
7550             (VPBLENDWYrri VR256:$src1, VR256:$src2, imm:$mask)>;
7551 }
7552
7553 /// SS41I_ternary_int - SSE 4.1 ternary operator
7554 let Uses = [XMM0], Constraints = "$src1 = $dst" in {
7555   multiclass SS41I_ternary_int<bits<8> opc, string OpcodeStr, PatFrag mem_frag,
7556                                X86MemOperand x86memop, Intrinsic IntId,
7557                                OpndItins itins = DEFAULT_ITINS> {
7558     def rr0 : SS48I<opc, MRMSrcReg, (outs VR128:$dst),
7559                     (ins VR128:$src1, VR128:$src2),
7560                     !strconcat(OpcodeStr,
7561                      "\t{$src2, $dst|$dst, $src2}"),
7562                     [(set VR128:$dst, (IntId VR128:$src1, VR128:$src2, XMM0))],
7563                     itins.rr>, Sched<[itins.Sched]>;
7564
7565     def rm0 : SS48I<opc, MRMSrcMem, (outs VR128:$dst),
7566                     (ins VR128:$src1, x86memop:$src2),
7567                     !strconcat(OpcodeStr,
7568                      "\t{$src2, $dst|$dst, $src2}"),
7569                     [(set VR128:$dst,
7570                       (IntId VR128:$src1,
7571                        (bitconvert (mem_frag addr:$src2)), XMM0))],
7572                        itins.rm>, Sched<[itins.Sched.Folded, ReadAfterLd]>;
7573   }
7574 }
7575
7576 let ExeDomain = SSEPackedDouble in
7577 defm BLENDVPD : SS41I_ternary_int<0x15, "blendvpd", memopv2f64, f128mem,
7578                                   int_x86_sse41_blendvpd,
7579                                   DEFAULT_ITINS_FBLENDSCHED>;
7580 let ExeDomain = SSEPackedSingle in
7581 defm BLENDVPS : SS41I_ternary_int<0x14, "blendvps", memopv4f32, f128mem,
7582                                   int_x86_sse41_blendvps,
7583                                   DEFAULT_ITINS_FBLENDSCHED>;
7584 defm PBLENDVB : SS41I_ternary_int<0x10, "pblendvb", memopv2i64, i128mem,
7585                                   int_x86_sse41_pblendvb,
7586                                   DEFAULT_ITINS_VARBLENDSCHED>;
7587
7588 // Aliases with the implicit xmm0 argument
7589 def : InstAlias<"blendvpd\t{%xmm0, $src2, $dst|$dst, $src2, xmm0}",
7590                 (BLENDVPDrr0 VR128:$dst, VR128:$src2)>;
7591 def : InstAlias<"blendvpd\t{%xmm0, $src2, $dst|$dst, $src2, xmm0}",
7592                 (BLENDVPDrm0 VR128:$dst, f128mem:$src2)>;
7593 def : InstAlias<"blendvps\t{%xmm0, $src2, $dst|$dst, $src2, xmm0}",
7594                 (BLENDVPSrr0 VR128:$dst, VR128:$src2)>;
7595 def : InstAlias<"blendvps\t{%xmm0, $src2, $dst|$dst, $src2, xmm0}",
7596                 (BLENDVPSrm0 VR128:$dst, f128mem:$src2)>;
7597 def : InstAlias<"pblendvb\t{%xmm0, $src2, $dst|$dst, $src2, xmm0}",
7598                 (PBLENDVBrr0 VR128:$dst, VR128:$src2)>;
7599 def : InstAlias<"pblendvb\t{%xmm0, $src2, $dst|$dst, $src2, xmm0}",
7600                 (PBLENDVBrm0 VR128:$dst, i128mem:$src2)>;
7601
7602 let Predicates = [UseSSE41] in {
7603   def : Pat<(v16i8 (vselect (v16i8 XMM0), (v16i8 VR128:$src1),
7604                             (v16i8 VR128:$src2))),
7605             (PBLENDVBrr0 VR128:$src2, VR128:$src1)>;
7606   def : Pat<(v4i32 (vselect (v4i32 XMM0), (v4i32 VR128:$src1),
7607                             (v4i32 VR128:$src2))),
7608             (BLENDVPSrr0 VR128:$src2, VR128:$src1)>;
7609   def : Pat<(v4f32 (vselect (v4i32 XMM0), (v4f32 VR128:$src1),
7610                             (v4f32 VR128:$src2))),
7611             (BLENDVPSrr0 VR128:$src2, VR128:$src1)>;
7612   def : Pat<(v2i64 (vselect (v2i64 XMM0), (v2i64 VR128:$src1),
7613                             (v2i64 VR128:$src2))),
7614             (BLENDVPDrr0 VR128:$src2, VR128:$src1)>;
7615   def : Pat<(v2f64 (vselect (v2i64 XMM0), (v2f64 VR128:$src1),
7616                             (v2f64 VR128:$src2))),
7617             (BLENDVPDrr0 VR128:$src2, VR128:$src1)>;
7618
7619   def : Pat<(v8i16 (X86Blendi (v8i16 VR128:$src1), (v8i16 VR128:$src2),
7620                                (imm:$mask))),
7621             (PBLENDWrri VR128:$src1, VR128:$src2, imm:$mask)>;
7622   def : Pat<(v4f32 (X86Blendi (v4f32 VR128:$src1), (v4f32 VR128:$src2),
7623                                (imm:$mask))),
7624             (BLENDPSrri VR128:$src1, VR128:$src2, imm:$mask)>;
7625   def : Pat<(v2f64 (X86Blendi (v2f64 VR128:$src1), (v2f64 VR128:$src2),
7626                                (imm:$mask))),
7627             (BLENDPDrri VR128:$src1, VR128:$src2, imm:$mask)>;
7628
7629 }
7630
7631 let SchedRW = [WriteLoad] in {
7632 let Predicates = [HasAVX] in
7633 def VMOVNTDQArm : SS48I<0x2A, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
7634                        "vmovntdqa\t{$src, $dst|$dst, $src}",
7635                        [(set VR128:$dst, (int_x86_sse41_movntdqa addr:$src))]>,
7636                        VEX;
7637 let Predicates = [HasAVX2] in
7638 def VMOVNTDQAYrm : SS48I<0x2A, MRMSrcMem, (outs VR256:$dst), (ins i256mem:$src),
7639                          "vmovntdqa\t{$src, $dst|$dst, $src}",
7640                          [(set VR256:$dst, (int_x86_avx2_movntdqa addr:$src))]>,
7641                          VEX, VEX_L;
7642 def MOVNTDQArm : SS48I<0x2A, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
7643                        "movntdqa\t{$src, $dst|$dst, $src}",
7644                        [(set VR128:$dst, (int_x86_sse41_movntdqa addr:$src))]>;
7645 } // SchedRW
7646
7647 //===----------------------------------------------------------------------===//
7648 // SSE4.2 - Compare Instructions
7649 //===----------------------------------------------------------------------===//
7650
7651 /// SS42I_binop_rm - Simple SSE 4.2 binary operator
7652 multiclass SS42I_binop_rm<bits<8> opc, string OpcodeStr, SDNode OpNode,
7653                           ValueType OpVT, RegisterClass RC, PatFrag memop_frag,
7654                           X86MemOperand x86memop, bit Is2Addr = 1> {
7655   def rr : SS428I<opc, MRMSrcReg, (outs RC:$dst),
7656        (ins RC:$src1, RC:$src2),
7657        !if(Is2Addr,
7658            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
7659            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
7660        [(set RC:$dst, (OpVT (OpNode RC:$src1, RC:$src2)))]>;
7661   def rm : SS428I<opc, MRMSrcMem, (outs RC:$dst),
7662        (ins RC:$src1, x86memop:$src2),
7663        !if(Is2Addr,
7664            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
7665            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
7666        [(set RC:$dst,
7667          (OpVT (OpNode RC:$src1, (memop_frag addr:$src2))))]>;
7668 }
7669
7670 let Predicates = [HasAVX] in
7671   defm VPCMPGTQ : SS42I_binop_rm<0x37, "vpcmpgtq", X86pcmpgt, v2i64, VR128,
7672                                  loadv2i64, i128mem, 0>, VEX_4V;
7673
7674 let Predicates = [HasAVX2] in
7675   defm VPCMPGTQY : SS42I_binop_rm<0x37, "vpcmpgtq", X86pcmpgt, v4i64, VR256,
7676                                   loadv4i64, i256mem, 0>, VEX_4V, VEX_L;
7677
7678 let Constraints = "$src1 = $dst" in
7679   defm PCMPGTQ : SS42I_binop_rm<0x37, "pcmpgtq", X86pcmpgt, v2i64, VR128,
7680                                 memopv2i64, i128mem>;
7681
7682 //===----------------------------------------------------------------------===//
7683 // SSE4.2 - String/text Processing Instructions
7684 //===----------------------------------------------------------------------===//
7685
7686 // Packed Compare Implicit Length Strings, Return Mask
7687 multiclass pseudo_pcmpistrm<string asm> {
7688   def REG : PseudoI<(outs VR128:$dst),
7689                     (ins VR128:$src1, VR128:$src2, i8imm:$src3),
7690     [(set VR128:$dst, (int_x86_sse42_pcmpistrm128 VR128:$src1, VR128:$src2,
7691                                                   imm:$src3))]>;
7692   def MEM : PseudoI<(outs VR128:$dst),
7693                     (ins VR128:$src1, i128mem:$src2, i8imm:$src3),
7694     [(set VR128:$dst, (int_x86_sse42_pcmpistrm128 VR128:$src1,
7695                        (bc_v16i8 (memopv2i64 addr:$src2)), imm:$src3))]>;
7696 }
7697
7698 let Defs = [EFLAGS], usesCustomInserter = 1 in {
7699   defm VPCMPISTRM128 : pseudo_pcmpistrm<"#VPCMPISTRM128">, Requires<[HasAVX]>;
7700   defm PCMPISTRM128 : pseudo_pcmpistrm<"#PCMPISTRM128">, Requires<[UseSSE42]>;
7701 }
7702
7703 multiclass pcmpistrm_SS42AI<string asm> {
7704   def rr : SS42AI<0x62, MRMSrcReg, (outs),
7705     (ins VR128:$src1, VR128:$src2, i8imm:$src3),
7706     !strconcat(asm, "\t{$src3, $src2, $src1|$src1, $src2, $src3}"),
7707     []>, Sched<[WritePCmpIStrM]>;
7708   let mayLoad = 1 in
7709   def rm :SS42AI<0x62, MRMSrcMem, (outs),
7710     (ins VR128:$src1, i128mem:$src2, i8imm:$src3),
7711     !strconcat(asm, "\t{$src3, $src2, $src1|$src1, $src2, $src3}"),
7712     []>, Sched<[WritePCmpIStrMLd, ReadAfterLd]>;
7713 }
7714
7715 let Defs = [XMM0, EFLAGS], neverHasSideEffects = 1 in {
7716   let Predicates = [HasAVX] in
7717   defm VPCMPISTRM128 : pcmpistrm_SS42AI<"vpcmpistrm">, VEX;
7718   defm PCMPISTRM128  : pcmpistrm_SS42AI<"pcmpistrm"> ;
7719 }
7720
7721 // Packed Compare Explicit Length Strings, Return Mask
7722 multiclass pseudo_pcmpestrm<string asm> {
7723   def REG : PseudoI<(outs VR128:$dst),
7724                     (ins VR128:$src1, VR128:$src3, i8imm:$src5),
7725     [(set VR128:$dst, (int_x86_sse42_pcmpestrm128
7726                        VR128:$src1, EAX, VR128:$src3, EDX, imm:$src5))]>;
7727   def MEM : PseudoI<(outs VR128:$dst),
7728                     (ins VR128:$src1, i128mem:$src3, i8imm:$src5),
7729     [(set VR128:$dst, (int_x86_sse42_pcmpestrm128 VR128:$src1, EAX,
7730                        (bc_v16i8 (memopv2i64 addr:$src3)), EDX, imm:$src5))]>;
7731 }
7732
7733 let Defs = [EFLAGS], Uses = [EAX, EDX], usesCustomInserter = 1 in {
7734   defm VPCMPESTRM128 : pseudo_pcmpestrm<"#VPCMPESTRM128">, Requires<[HasAVX]>;
7735   defm PCMPESTRM128 : pseudo_pcmpestrm<"#PCMPESTRM128">, Requires<[UseSSE42]>;
7736 }
7737
7738 multiclass SS42AI_pcmpestrm<string asm> {
7739   def rr : SS42AI<0x60, MRMSrcReg, (outs),
7740     (ins VR128:$src1, VR128:$src3, i8imm:$src5),
7741     !strconcat(asm, "\t{$src5, $src3, $src1|$src1, $src3, $src5}"),
7742     []>, Sched<[WritePCmpEStrM]>;
7743   let mayLoad = 1 in
7744   def rm : SS42AI<0x60, MRMSrcMem, (outs),
7745     (ins VR128:$src1, i128mem:$src3, i8imm:$src5),
7746     !strconcat(asm, "\t{$src5, $src3, $src1|$src1, $src3, $src5}"),
7747     []>, Sched<[WritePCmpEStrMLd, ReadAfterLd]>;
7748 }
7749
7750 let Defs = [XMM0, EFLAGS], Uses = [EAX, EDX], neverHasSideEffects = 1 in {
7751   let Predicates = [HasAVX] in
7752   defm VPCMPESTRM128 : SS42AI_pcmpestrm<"vpcmpestrm">, VEX;
7753   defm PCMPESTRM128 :  SS42AI_pcmpestrm<"pcmpestrm">;
7754 }
7755
7756 // Packed Compare Implicit Length Strings, Return Index
7757 multiclass pseudo_pcmpistri<string asm> {
7758   def REG : PseudoI<(outs GR32:$dst),
7759                     (ins VR128:$src1, VR128:$src2, i8imm:$src3),
7760     [(set GR32:$dst, EFLAGS,
7761       (X86pcmpistri VR128:$src1, VR128:$src2, imm:$src3))]>;
7762   def MEM : PseudoI<(outs GR32:$dst),
7763                     (ins VR128:$src1, i128mem:$src2, i8imm:$src3),
7764     [(set GR32:$dst, EFLAGS, (X86pcmpistri VR128:$src1,
7765                               (bc_v16i8 (memopv2i64 addr:$src2)), imm:$src3))]>;
7766 }
7767
7768 let Defs = [EFLAGS], usesCustomInserter = 1 in {
7769   defm VPCMPISTRI : pseudo_pcmpistri<"#VPCMPISTRI">, Requires<[HasAVX]>;
7770   defm PCMPISTRI  : pseudo_pcmpistri<"#PCMPISTRI">, Requires<[UseSSE42]>;
7771 }
7772
7773 multiclass SS42AI_pcmpistri<string asm> {
7774   def rr : SS42AI<0x63, MRMSrcReg, (outs),
7775     (ins VR128:$src1, VR128:$src2, i8imm:$src3),
7776     !strconcat(asm, "\t{$src3, $src2, $src1|$src1, $src2, $src3}"),
7777     []>, Sched<[WritePCmpIStrI]>;
7778   let mayLoad = 1 in
7779   def rm : SS42AI<0x63, MRMSrcMem, (outs),
7780     (ins VR128:$src1, i128mem:$src2, i8imm:$src3),
7781     !strconcat(asm, "\t{$src3, $src2, $src1|$src1, $src2, $src3}"),
7782     []>, Sched<[WritePCmpIStrILd, ReadAfterLd]>;
7783 }
7784
7785 let Defs = [ECX, EFLAGS], neverHasSideEffects = 1 in {
7786   let Predicates = [HasAVX] in
7787   defm VPCMPISTRI : SS42AI_pcmpistri<"vpcmpistri">, VEX;
7788   defm PCMPISTRI  : SS42AI_pcmpistri<"pcmpistri">;
7789 }
7790
7791 // Packed Compare Explicit Length Strings, Return Index
7792 multiclass pseudo_pcmpestri<string asm> {
7793   def REG : PseudoI<(outs GR32:$dst),
7794                     (ins VR128:$src1, VR128:$src3, i8imm:$src5),
7795     [(set GR32:$dst, EFLAGS,
7796       (X86pcmpestri VR128:$src1, EAX, VR128:$src3, EDX, imm:$src5))]>;
7797   def MEM : PseudoI<(outs GR32:$dst),
7798                     (ins VR128:$src1, i128mem:$src3, i8imm:$src5),
7799     [(set GR32:$dst, EFLAGS,
7800       (X86pcmpestri VR128:$src1, EAX, (bc_v16i8 (memopv2i64 addr:$src3)), EDX,
7801        imm:$src5))]>;
7802 }
7803
7804 let Defs = [EFLAGS], Uses = [EAX, EDX], usesCustomInserter = 1 in {
7805   defm VPCMPESTRI : pseudo_pcmpestri<"#VPCMPESTRI">, Requires<[HasAVX]>;
7806   defm PCMPESTRI  : pseudo_pcmpestri<"#PCMPESTRI">, Requires<[UseSSE42]>;
7807 }
7808
7809 multiclass SS42AI_pcmpestri<string asm> {
7810   def rr : SS42AI<0x61, MRMSrcReg, (outs),
7811     (ins VR128:$src1, VR128:$src3, i8imm:$src5),
7812     !strconcat(asm, "\t{$src5, $src3, $src1|$src1, $src3, $src5}"),
7813     []>, Sched<[WritePCmpEStrI]>;
7814   let mayLoad = 1 in
7815   def rm : SS42AI<0x61, MRMSrcMem, (outs),
7816     (ins VR128:$src1, i128mem:$src3, i8imm:$src5),
7817     !strconcat(asm, "\t{$src5, $src3, $src1|$src1, $src3, $src5}"),
7818     []>, Sched<[WritePCmpEStrILd, ReadAfterLd]>;
7819 }
7820
7821 let Defs = [ECX, EFLAGS], Uses = [EAX, EDX], neverHasSideEffects = 1 in {
7822   let Predicates = [HasAVX] in
7823   defm VPCMPESTRI : SS42AI_pcmpestri<"vpcmpestri">, VEX;
7824   defm PCMPESTRI  : SS42AI_pcmpestri<"pcmpestri">;
7825 }
7826
7827 //===----------------------------------------------------------------------===//
7828 // SSE4.2 - CRC Instructions
7829 //===----------------------------------------------------------------------===//
7830
7831 // No CRC instructions have AVX equivalents
7832
7833 // crc intrinsic instruction
7834 // This set of instructions are only rm, the only difference is the size
7835 // of r and m.
7836 class SS42I_crc32r<bits<8> opc, string asm, RegisterClass RCOut,
7837                    RegisterClass RCIn, SDPatternOperator Int> :
7838   SS42FI<opc, MRMSrcReg, (outs RCOut:$dst), (ins RCOut:$src1, RCIn:$src2),
7839          !strconcat(asm, "\t{$src2, $src1|$src1, $src2}"),
7840          [(set RCOut:$dst, (Int RCOut:$src1, RCIn:$src2))], IIC_CRC32_REG>,
7841          Sched<[WriteFAdd]>;
7842
7843 class SS42I_crc32m<bits<8> opc, string asm, RegisterClass RCOut,
7844                    X86MemOperand x86memop, SDPatternOperator Int> :
7845   SS42FI<opc, MRMSrcMem, (outs RCOut:$dst), (ins RCOut:$src1, x86memop:$src2),
7846          !strconcat(asm, "\t{$src2, $src1|$src1, $src2}"),
7847          [(set RCOut:$dst, (Int RCOut:$src1, (load addr:$src2)))],
7848          IIC_CRC32_MEM>, Sched<[WriteFAddLd, ReadAfterLd]>;
7849
7850 let Constraints = "$src1 = $dst" in {
7851   def CRC32r32m8  : SS42I_crc32m<0xF0, "crc32{b}", GR32, i8mem,
7852                                  int_x86_sse42_crc32_32_8>;
7853   def CRC32r32r8  : SS42I_crc32r<0xF0, "crc32{b}", GR32, GR8,
7854                                  int_x86_sse42_crc32_32_8>;
7855   def CRC32r32m16 : SS42I_crc32m<0xF1, "crc32{w}", GR32, i16mem,
7856                                  int_x86_sse42_crc32_32_16>, OpSize16;
7857   def CRC32r32r16 : SS42I_crc32r<0xF1, "crc32{w}", GR32, GR16,
7858                                  int_x86_sse42_crc32_32_16>, OpSize16;
7859   def CRC32r32m32 : SS42I_crc32m<0xF1, "crc32{l}", GR32, i32mem,
7860                                  int_x86_sse42_crc32_32_32>, OpSize32;
7861   def CRC32r32r32 : SS42I_crc32r<0xF1, "crc32{l}", GR32, GR32,
7862                                  int_x86_sse42_crc32_32_32>, OpSize32;
7863   def CRC32r64m64 : SS42I_crc32m<0xF1, "crc32{q}", GR64, i64mem,
7864                                  int_x86_sse42_crc32_64_64>, REX_W;
7865   def CRC32r64r64 : SS42I_crc32r<0xF1, "crc32{q}", GR64, GR64,
7866                                  int_x86_sse42_crc32_64_64>, REX_W;
7867   let hasSideEffects = 0 in {
7868     let mayLoad = 1 in
7869     def CRC32r64m8 : SS42I_crc32m<0xF0, "crc32{b}", GR64, i8mem,
7870                                    null_frag>, REX_W;
7871     def CRC32r64r8 : SS42I_crc32r<0xF0, "crc32{b}", GR64, GR8,
7872                                    null_frag>, REX_W;
7873   }
7874 }
7875
7876 //===----------------------------------------------------------------------===//
7877 // SHA-NI Instructions
7878 //===----------------------------------------------------------------------===//
7879
7880 multiclass SHAI_binop<bits<8> Opc, string OpcodeStr, Intrinsic IntId,
7881                       bit UsesXMM0 = 0> {
7882   def rr : I<Opc, MRMSrcReg, (outs VR128:$dst),
7883              (ins VR128:$src1, VR128:$src2),
7884              !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
7885              [!if(UsesXMM0,
7886                   (set VR128:$dst, (IntId VR128:$src1, VR128:$src2, XMM0)),
7887                   (set VR128:$dst, (IntId VR128:$src1, VR128:$src2)))]>, T8;
7888
7889   def rm : I<Opc, MRMSrcMem, (outs VR128:$dst),
7890              (ins VR128:$src1, i128mem:$src2),
7891              !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
7892              [!if(UsesXMM0,
7893                   (set VR128:$dst, (IntId VR128:$src1,
7894                     (bc_v4i32 (memopv2i64 addr:$src2)), XMM0)),
7895                   (set VR128:$dst, (IntId VR128:$src1,
7896                     (bc_v4i32 (memopv2i64 addr:$src2)))))]>, T8;
7897 }
7898
7899 let Constraints = "$src1 = $dst", Predicates = [HasSHA] in {
7900   def SHA1RNDS4rri : Ii8<0xCC, MRMSrcReg, (outs VR128:$dst),
7901                          (ins VR128:$src1, VR128:$src2, i8imm:$src3),
7902                          "sha1rnds4\t{$src3, $src2, $dst|$dst, $src2, $src3}",
7903                          [(set VR128:$dst,
7904                            (int_x86_sha1rnds4 VR128:$src1, VR128:$src2,
7905                             (i8 imm:$src3)))]>, TA;
7906   def SHA1RNDS4rmi : Ii8<0xCC, MRMSrcMem, (outs VR128:$dst),
7907                          (ins VR128:$src1, i128mem:$src2, i8imm:$src3),
7908                          "sha1rnds4\t{$src3, $src2, $dst|$dst, $src2, $src3}",
7909                          [(set VR128:$dst,
7910                            (int_x86_sha1rnds4 VR128:$src1,
7911                             (bc_v4i32 (memopv2i64 addr:$src2)),
7912                             (i8 imm:$src3)))]>, TA;
7913
7914   defm SHA1NEXTE : SHAI_binop<0xC8, "sha1nexte", int_x86_sha1nexte>;
7915   defm SHA1MSG1  : SHAI_binop<0xC9, "sha1msg1", int_x86_sha1msg1>;
7916   defm SHA1MSG2  : SHAI_binop<0xCA, "sha1msg2", int_x86_sha1msg2>;
7917
7918   let Uses=[XMM0] in
7919   defm SHA256RNDS2 : SHAI_binop<0xCB, "sha256rnds2", int_x86_sha256rnds2, 1>;
7920
7921   defm SHA256MSG1 : SHAI_binop<0xCC, "sha256msg1", int_x86_sha256msg1>;
7922   defm SHA256MSG2 : SHAI_binop<0xCD, "sha256msg2", int_x86_sha256msg2>;
7923 }
7924
7925 // Aliases with explicit %xmm0
7926 def : InstAlias<"sha256rnds2\t{%xmm0, $src2, $dst|$dst, $src2, xmm0}",
7927                 (SHA256RNDS2rr VR128:$dst, VR128:$src2)>;
7928 def : InstAlias<"sha256rnds2\t{%xmm0, $src2, $dst|$dst, $src2, xmm0}",
7929                 (SHA256RNDS2rm VR128:$dst, i128mem:$src2)>;
7930
7931 //===----------------------------------------------------------------------===//
7932 // AES-NI Instructions
7933 //===----------------------------------------------------------------------===//
7934
7935 multiclass AESI_binop_rm_int<bits<8> opc, string OpcodeStr,
7936                               Intrinsic IntId128, bit Is2Addr = 1> {
7937   def rr : AES8I<opc, MRMSrcReg, (outs VR128:$dst),
7938        (ins VR128:$src1, VR128:$src2),
7939        !if(Is2Addr,
7940            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
7941            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
7942        [(set VR128:$dst, (IntId128 VR128:$src1, VR128:$src2))]>,
7943        Sched<[WriteAESDecEnc]>;
7944   def rm : AES8I<opc, MRMSrcMem, (outs VR128:$dst),
7945        (ins VR128:$src1, i128mem:$src2),
7946        !if(Is2Addr,
7947            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
7948            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
7949        [(set VR128:$dst,
7950          (IntId128 VR128:$src1, (memopv2i64 addr:$src2)))]>,
7951        Sched<[WriteAESDecEncLd, ReadAfterLd]>;
7952 }
7953
7954 // Perform One Round of an AES Encryption/Decryption Flow
7955 let Predicates = [HasAVX, HasAES] in {
7956   defm VAESENC          : AESI_binop_rm_int<0xDC, "vaesenc",
7957                          int_x86_aesni_aesenc, 0>, VEX_4V;
7958   defm VAESENCLAST      : AESI_binop_rm_int<0xDD, "vaesenclast",
7959                          int_x86_aesni_aesenclast, 0>, VEX_4V;
7960   defm VAESDEC          : AESI_binop_rm_int<0xDE, "vaesdec",
7961                          int_x86_aesni_aesdec, 0>, VEX_4V;
7962   defm VAESDECLAST      : AESI_binop_rm_int<0xDF, "vaesdeclast",
7963                          int_x86_aesni_aesdeclast, 0>, VEX_4V;
7964 }
7965
7966 let Constraints = "$src1 = $dst" in {
7967   defm AESENC          : AESI_binop_rm_int<0xDC, "aesenc",
7968                          int_x86_aesni_aesenc>;
7969   defm AESENCLAST      : AESI_binop_rm_int<0xDD, "aesenclast",
7970                          int_x86_aesni_aesenclast>;
7971   defm AESDEC          : AESI_binop_rm_int<0xDE, "aesdec",
7972                          int_x86_aesni_aesdec>;
7973   defm AESDECLAST      : AESI_binop_rm_int<0xDF, "aesdeclast",
7974                          int_x86_aesni_aesdeclast>;
7975 }
7976
7977 // Perform the AES InvMixColumn Transformation
7978 let Predicates = [HasAVX, HasAES] in {
7979   def VAESIMCrr : AES8I<0xDB, MRMSrcReg, (outs VR128:$dst),
7980       (ins VR128:$src1),
7981       "vaesimc\t{$src1, $dst|$dst, $src1}",
7982       [(set VR128:$dst,
7983         (int_x86_aesni_aesimc VR128:$src1))]>, Sched<[WriteAESIMC]>,
7984       VEX;
7985   def VAESIMCrm : AES8I<0xDB, MRMSrcMem, (outs VR128:$dst),
7986       (ins i128mem:$src1),
7987       "vaesimc\t{$src1, $dst|$dst, $src1}",
7988       [(set VR128:$dst, (int_x86_aesni_aesimc (loadv2i64 addr:$src1)))]>,
7989       Sched<[WriteAESIMCLd]>, VEX;
7990 }
7991 def AESIMCrr : AES8I<0xDB, MRMSrcReg, (outs VR128:$dst),
7992   (ins VR128:$src1),
7993   "aesimc\t{$src1, $dst|$dst, $src1}",
7994   [(set VR128:$dst,
7995     (int_x86_aesni_aesimc VR128:$src1))]>, Sched<[WriteAESIMC]>;
7996 def AESIMCrm : AES8I<0xDB, MRMSrcMem, (outs VR128:$dst),
7997   (ins i128mem:$src1),
7998   "aesimc\t{$src1, $dst|$dst, $src1}",
7999   [(set VR128:$dst, (int_x86_aesni_aesimc (memopv2i64 addr:$src1)))]>,
8000   Sched<[WriteAESIMCLd]>;
8001
8002 // AES Round Key Generation Assist
8003 let Predicates = [HasAVX, HasAES] in {
8004   def VAESKEYGENASSIST128rr : AESAI<0xDF, MRMSrcReg, (outs VR128:$dst),
8005       (ins VR128:$src1, i8imm:$src2),
8006       "vaeskeygenassist\t{$src2, $src1, $dst|$dst, $src1, $src2}",
8007       [(set VR128:$dst,
8008         (int_x86_aesni_aeskeygenassist VR128:$src1, imm:$src2))]>,
8009       Sched<[WriteAESKeyGen]>, VEX;
8010   def VAESKEYGENASSIST128rm : AESAI<0xDF, MRMSrcMem, (outs VR128:$dst),
8011       (ins i128mem:$src1, i8imm:$src2),
8012       "vaeskeygenassist\t{$src2, $src1, $dst|$dst, $src1, $src2}",
8013       [(set VR128:$dst,
8014         (int_x86_aesni_aeskeygenassist (loadv2i64 addr:$src1), imm:$src2))]>,
8015       Sched<[WriteAESKeyGenLd]>, VEX;
8016 }
8017 def AESKEYGENASSIST128rr : AESAI<0xDF, MRMSrcReg, (outs VR128:$dst),
8018   (ins VR128:$src1, i8imm:$src2),
8019   "aeskeygenassist\t{$src2, $src1, $dst|$dst, $src1, $src2}",
8020   [(set VR128:$dst,
8021     (int_x86_aesni_aeskeygenassist VR128:$src1, imm:$src2))]>,
8022   Sched<[WriteAESKeyGen]>;
8023 def AESKEYGENASSIST128rm : AESAI<0xDF, MRMSrcMem, (outs VR128:$dst),
8024   (ins i128mem:$src1, i8imm:$src2),
8025   "aeskeygenassist\t{$src2, $src1, $dst|$dst, $src1, $src2}",
8026   [(set VR128:$dst,
8027     (int_x86_aesni_aeskeygenassist (memopv2i64 addr:$src1), imm:$src2))]>,
8028   Sched<[WriteAESKeyGenLd]>;
8029
8030 //===----------------------------------------------------------------------===//
8031 // PCLMUL Instructions
8032 //===----------------------------------------------------------------------===//
8033
8034 // AVX carry-less Multiplication instructions
8035 def VPCLMULQDQrr : AVXPCLMULIi8<0x44, MRMSrcReg, (outs VR128:$dst),
8036            (ins VR128:$src1, VR128:$src2, i8imm:$src3),
8037            "vpclmulqdq\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
8038            [(set VR128:$dst,
8039              (int_x86_pclmulqdq VR128:$src1, VR128:$src2, imm:$src3))]>,
8040            Sched<[WriteCLMul]>;
8041
8042 def VPCLMULQDQrm : AVXPCLMULIi8<0x44, MRMSrcMem, (outs VR128:$dst),
8043            (ins VR128:$src1, i128mem:$src2, i8imm:$src3),
8044            "vpclmulqdq\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
8045            [(set VR128:$dst, (int_x86_pclmulqdq VR128:$src1,
8046                               (loadv2i64 addr:$src2), imm:$src3))]>,
8047            Sched<[WriteCLMulLd, ReadAfterLd]>;
8048
8049 // Carry-less Multiplication instructions
8050 let Constraints = "$src1 = $dst" in {
8051 def PCLMULQDQrr : PCLMULIi8<0x44, MRMSrcReg, (outs VR128:$dst),
8052            (ins VR128:$src1, VR128:$src2, i8imm:$src3),
8053            "pclmulqdq\t{$src3, $src2, $dst|$dst, $src2, $src3}",
8054            [(set VR128:$dst,
8055              (int_x86_pclmulqdq VR128:$src1, VR128:$src2, imm:$src3))],
8056              IIC_SSE_PCLMULQDQ_RR>, Sched<[WriteCLMul]>;
8057
8058 def PCLMULQDQrm : PCLMULIi8<0x44, MRMSrcMem, (outs VR128:$dst),
8059            (ins VR128:$src1, i128mem:$src2, i8imm:$src3),
8060            "pclmulqdq\t{$src3, $src2, $dst|$dst, $src2, $src3}",
8061            [(set VR128:$dst, (int_x86_pclmulqdq VR128:$src1,
8062                               (memopv2i64 addr:$src2), imm:$src3))],
8063                               IIC_SSE_PCLMULQDQ_RM>,
8064            Sched<[WriteCLMulLd, ReadAfterLd]>;
8065 } // Constraints = "$src1 = $dst"
8066
8067
8068 multiclass pclmul_alias<string asm, int immop> {
8069   def : InstAlias<!strconcat("pclmul", asm, "dq {$src, $dst|$dst, $src}"),
8070                   (PCLMULQDQrr VR128:$dst, VR128:$src, immop), 0>;
8071
8072   def : InstAlias<!strconcat("pclmul", asm, "dq {$src, $dst|$dst, $src}"),
8073                   (PCLMULQDQrm VR128:$dst, i128mem:$src, immop), 0>;
8074
8075   def : InstAlias<!strconcat("vpclmul", asm,
8076                              "dq {$src2, $src1, $dst|$dst, $src1, $src2}"),
8077                   (VPCLMULQDQrr VR128:$dst, VR128:$src1, VR128:$src2, immop),
8078                   0>;
8079
8080   def : InstAlias<!strconcat("vpclmul", asm,
8081                              "dq {$src2, $src1, $dst|$dst, $src1, $src2}"),
8082                   (VPCLMULQDQrm VR128:$dst, VR128:$src1, i128mem:$src2, immop),
8083                   0>;
8084 }
8085 defm : pclmul_alias<"hqhq", 0x11>;
8086 defm : pclmul_alias<"hqlq", 0x01>;
8087 defm : pclmul_alias<"lqhq", 0x10>;
8088 defm : pclmul_alias<"lqlq", 0x00>;
8089
8090 //===----------------------------------------------------------------------===//
8091 // SSE4A Instructions
8092 //===----------------------------------------------------------------------===//
8093
8094 let Predicates = [HasSSE4A] in {
8095
8096 let Constraints = "$src = $dst" in {
8097 def EXTRQI : Ii8<0x78, MRMXr, (outs VR128:$dst),
8098                  (ins VR128:$src, i8imm:$len, i8imm:$idx),
8099                  "extrq\t{$idx, $len, $src|$src, $len, $idx}",
8100                  [(set VR128:$dst, (int_x86_sse4a_extrqi VR128:$src, imm:$len,
8101                                     imm:$idx))]>, PD;
8102 def EXTRQ  : I<0x79, MRMSrcReg, (outs VR128:$dst),
8103               (ins VR128:$src, VR128:$mask),
8104               "extrq\t{$mask, $src|$src, $mask}",
8105               [(set VR128:$dst, (int_x86_sse4a_extrq VR128:$src,
8106                                  VR128:$mask))]>, PD;
8107
8108 def INSERTQI : Ii8<0x78, MRMSrcReg, (outs VR128:$dst),
8109                    (ins VR128:$src, VR128:$src2, i8imm:$len, i8imm:$idx),
8110                    "insertq\t{$idx, $len, $src2, $src|$src, $src2, $len, $idx}",
8111                    [(set VR128:$dst, (int_x86_sse4a_insertqi VR128:$src,
8112                                       VR128:$src2, imm:$len, imm:$idx))]>, XD;
8113 def INSERTQ  : I<0x79, MRMSrcReg, (outs VR128:$dst),
8114                  (ins VR128:$src, VR128:$mask),
8115                  "insertq\t{$mask, $src|$src, $mask}",
8116                  [(set VR128:$dst, (int_x86_sse4a_insertq VR128:$src,
8117                                     VR128:$mask))]>, XD;
8118 }
8119
8120 def MOVNTSS : I<0x2B, MRMDestMem, (outs), (ins f32mem:$dst, VR128:$src),
8121                 "movntss\t{$src, $dst|$dst, $src}",
8122                 [(int_x86_sse4a_movnt_ss addr:$dst, VR128:$src)]>, XS;
8123
8124 def MOVNTSD : I<0x2B, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
8125                 "movntsd\t{$src, $dst|$dst, $src}",
8126                 [(int_x86_sse4a_movnt_sd addr:$dst, VR128:$src)]>, XD;
8127 }
8128
8129 //===----------------------------------------------------------------------===//
8130 // AVX Instructions
8131 //===----------------------------------------------------------------------===//
8132
8133 //===----------------------------------------------------------------------===//
8134 // VBROADCAST - Load from memory and broadcast to all elements of the
8135 //              destination operand
8136 //
8137 class avx_broadcast<bits<8> opc, string OpcodeStr, RegisterClass RC,
8138                     X86MemOperand x86memop, Intrinsic Int, SchedWrite Sched> :
8139   AVX8I<opc, MRMSrcMem, (outs RC:$dst), (ins x86memop:$src),
8140         !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
8141         [(set RC:$dst, (Int addr:$src))]>, Sched<[Sched]>, VEX;
8142
8143 class avx_broadcast_no_int<bits<8> opc, string OpcodeStr, RegisterClass RC,
8144                            X86MemOperand x86memop, ValueType VT,
8145                            PatFrag ld_frag, SchedWrite Sched> :
8146   AVX8I<opc, MRMSrcMem, (outs RC:$dst), (ins x86memop:$src),
8147         !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
8148         [(set RC:$dst, (VT (X86VBroadcast (ld_frag addr:$src))))]>,
8149         Sched<[Sched]>, VEX {
8150     let mayLoad = 1;
8151 }
8152
8153 // AVX2 adds register forms
8154 class avx2_broadcast_reg<bits<8> opc, string OpcodeStr, RegisterClass RC,
8155                          Intrinsic Int, SchedWrite Sched> :
8156   AVX28I<opc, MRMSrcReg, (outs RC:$dst), (ins VR128:$src),
8157          !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
8158          [(set RC:$dst, (Int VR128:$src))]>, Sched<[Sched]>, VEX;
8159
8160 let ExeDomain = SSEPackedSingle in {
8161   def VBROADCASTSSrm  : avx_broadcast_no_int<0x18, "vbroadcastss", VR128,
8162                                              f32mem, v4f32, loadf32, WriteLoad>;
8163   def VBROADCASTSSYrm : avx_broadcast_no_int<0x18, "vbroadcastss", VR256,
8164                                              f32mem, v8f32, loadf32,
8165                                              WriteFShuffleLd>, VEX_L;
8166 }
8167 let ExeDomain = SSEPackedDouble in
8168 def VBROADCASTSDYrm  : avx_broadcast_no_int<0x19, "vbroadcastsd", VR256, f64mem,
8169                                     v4f64, loadf64, WriteFShuffleLd>, VEX_L;
8170 def VBROADCASTF128 : avx_broadcast<0x1A, "vbroadcastf128", VR256, f128mem,
8171                                    int_x86_avx_vbroadcastf128_pd_256,
8172                                    WriteFShuffleLd>, VEX_L;
8173
8174 let ExeDomain = SSEPackedSingle in {
8175   def VBROADCASTSSrr  : avx2_broadcast_reg<0x18, "vbroadcastss", VR128,
8176                                            int_x86_avx2_vbroadcast_ss_ps,
8177                                            WriteFShuffle>;
8178   def VBROADCASTSSYrr : avx2_broadcast_reg<0x18, "vbroadcastss", VR256,
8179                                       int_x86_avx2_vbroadcast_ss_ps_256,
8180                                       WriteFShuffle256>, VEX_L;
8181 }
8182 let ExeDomain = SSEPackedDouble in
8183 def VBROADCASTSDYrr  : avx2_broadcast_reg<0x19, "vbroadcastsd", VR256,
8184                                       int_x86_avx2_vbroadcast_sd_pd_256,
8185                                       WriteFShuffle256>, VEX_L;
8186
8187 let Predicates = [HasAVX2] in
8188 def VBROADCASTI128 : avx_broadcast<0x5A, "vbroadcasti128", VR256, i128mem,
8189                                    int_x86_avx2_vbroadcasti128, WriteLoad>,
8190                                    VEX_L;
8191
8192 let Predicates = [HasAVX] in
8193 def : Pat<(int_x86_avx_vbroadcastf128_ps_256 addr:$src),
8194           (VBROADCASTF128 addr:$src)>;
8195
8196
8197 //===----------------------------------------------------------------------===//
8198 // VINSERTF128 - Insert packed floating-point values
8199 //
8200 let neverHasSideEffects = 1, ExeDomain = SSEPackedSingle in {
8201 def VINSERTF128rr : AVXAIi8<0x18, MRMSrcReg, (outs VR256:$dst),
8202           (ins VR256:$src1, VR128:$src2, i8imm:$src3),
8203           "vinsertf128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
8204           []>, Sched<[WriteFShuffle]>, VEX_4V, VEX_L;
8205 let mayLoad = 1 in
8206 def VINSERTF128rm : AVXAIi8<0x18, MRMSrcMem, (outs VR256:$dst),
8207           (ins VR256:$src1, f128mem:$src2, i8imm:$src3),
8208           "vinsertf128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
8209           []>, Sched<[WriteFShuffleLd, ReadAfterLd]>, VEX_4V, VEX_L;
8210 }
8211
8212 let Predicates = [HasAVX] in {
8213 def : Pat<(vinsert128_insert:$ins (v8f32 VR256:$src1), (v4f32 VR128:$src2),
8214                                    (iPTR imm)),
8215           (VINSERTF128rr VR256:$src1, VR128:$src2,
8216                          (INSERT_get_vinsert128_imm VR256:$ins))>;
8217 def : Pat<(vinsert128_insert:$ins (v4f64 VR256:$src1), (v2f64 VR128:$src2),
8218                                    (iPTR imm)),
8219           (VINSERTF128rr VR256:$src1, VR128:$src2,
8220                          (INSERT_get_vinsert128_imm VR256:$ins))>;
8221
8222 def : Pat<(vinsert128_insert:$ins (v8f32 VR256:$src1), (loadv4f32 addr:$src2),
8223                                    (iPTR imm)),
8224           (VINSERTF128rm VR256:$src1, addr:$src2,
8225                          (INSERT_get_vinsert128_imm VR256:$ins))>;
8226 def : Pat<(vinsert128_insert:$ins (v4f64 VR256:$src1), (loadv2f64 addr:$src2),
8227                                    (iPTR imm)),
8228           (VINSERTF128rm VR256:$src1, addr:$src2,
8229                          (INSERT_get_vinsert128_imm VR256:$ins))>;
8230 }
8231
8232 let Predicates = [HasAVX1Only] in {
8233 def : Pat<(vinsert128_insert:$ins (v4i64 VR256:$src1), (v2i64 VR128:$src2),
8234                                    (iPTR imm)),
8235           (VINSERTF128rr VR256:$src1, VR128:$src2,
8236                          (INSERT_get_vinsert128_imm VR256:$ins))>;
8237 def : Pat<(vinsert128_insert:$ins (v8i32 VR256:$src1), (v4i32 VR128:$src2),
8238                                    (iPTR imm)),
8239           (VINSERTF128rr VR256:$src1, VR128:$src2,
8240                          (INSERT_get_vinsert128_imm VR256:$ins))>;
8241 def : Pat<(vinsert128_insert:$ins (v32i8 VR256:$src1), (v16i8 VR128:$src2),
8242                                    (iPTR imm)),
8243           (VINSERTF128rr VR256:$src1, VR128:$src2,
8244                          (INSERT_get_vinsert128_imm VR256:$ins))>;
8245 def : Pat<(vinsert128_insert:$ins (v16i16 VR256:$src1), (v8i16 VR128:$src2),
8246                                    (iPTR imm)),
8247           (VINSERTF128rr VR256:$src1, VR128:$src2,
8248                          (INSERT_get_vinsert128_imm VR256:$ins))>;
8249
8250 def : Pat<(vinsert128_insert:$ins (v4i64 VR256:$src1), (loadv2i64 addr:$src2),
8251                                    (iPTR imm)),
8252           (VINSERTF128rm VR256:$src1, addr:$src2,
8253                          (INSERT_get_vinsert128_imm VR256:$ins))>;
8254 def : Pat<(vinsert128_insert:$ins (v8i32 VR256:$src1),
8255                                    (bc_v4i32 (loadv2i64 addr:$src2)),
8256                                    (iPTR imm)),
8257           (VINSERTF128rm VR256:$src1, addr:$src2,
8258                          (INSERT_get_vinsert128_imm VR256:$ins))>;
8259 def : Pat<(vinsert128_insert:$ins (v32i8 VR256:$src1),
8260                                    (bc_v16i8 (loadv2i64 addr:$src2)),
8261                                    (iPTR imm)),
8262           (VINSERTF128rm VR256:$src1, addr:$src2,
8263                          (INSERT_get_vinsert128_imm VR256:$ins))>;
8264 def : Pat<(vinsert128_insert:$ins (v16i16 VR256:$src1),
8265                                    (bc_v8i16 (loadv2i64 addr:$src2)),
8266                                    (iPTR imm)),
8267           (VINSERTF128rm VR256:$src1, addr:$src2,
8268                          (INSERT_get_vinsert128_imm VR256:$ins))>;
8269 }
8270
8271 //===----------------------------------------------------------------------===//
8272 // VEXTRACTF128 - Extract packed floating-point values
8273 //
8274 let neverHasSideEffects = 1, ExeDomain = SSEPackedSingle in {
8275 def VEXTRACTF128rr : AVXAIi8<0x19, MRMDestReg, (outs VR128:$dst),
8276           (ins VR256:$src1, i8imm:$src2),
8277           "vextractf128\t{$src2, $src1, $dst|$dst, $src1, $src2}",
8278           []>, Sched<[WriteFShuffle]>, VEX, VEX_L;
8279 let mayStore = 1 in
8280 def VEXTRACTF128mr : AVXAIi8<0x19, MRMDestMem, (outs),
8281           (ins f128mem:$dst, VR256:$src1, i8imm:$src2),
8282           "vextractf128\t{$src2, $src1, $dst|$dst, $src1, $src2}",
8283           []>, Sched<[WriteStore]>, VEX, VEX_L;
8284 }
8285
8286 // AVX1 patterns
8287 let Predicates = [HasAVX] in {
8288 def : Pat<(vextract128_extract:$ext VR256:$src1, (iPTR imm)),
8289           (v4f32 (VEXTRACTF128rr
8290                     (v8f32 VR256:$src1),
8291                     (EXTRACT_get_vextract128_imm VR128:$ext)))>;
8292 def : Pat<(vextract128_extract:$ext VR256:$src1, (iPTR imm)),
8293           (v2f64 (VEXTRACTF128rr
8294                     (v4f64 VR256:$src1),
8295                     (EXTRACT_get_vextract128_imm VR128:$ext)))>;
8296
8297 def : Pat<(store (v4f32 (vextract128_extract:$ext (v8f32 VR256:$src1),
8298                          (iPTR imm))), addr:$dst),
8299           (VEXTRACTF128mr addr:$dst, VR256:$src1,
8300            (EXTRACT_get_vextract128_imm VR128:$ext))>;
8301 def : Pat<(store (v2f64 (vextract128_extract:$ext (v4f64 VR256:$src1),
8302                          (iPTR imm))), addr:$dst),
8303           (VEXTRACTF128mr addr:$dst, VR256:$src1,
8304            (EXTRACT_get_vextract128_imm VR128:$ext))>;
8305 }
8306
8307 let Predicates = [HasAVX1Only] in {
8308 def : Pat<(vextract128_extract:$ext VR256:$src1, (iPTR imm)),
8309           (v2i64 (VEXTRACTF128rr
8310                   (v4i64 VR256:$src1),
8311                   (EXTRACT_get_vextract128_imm VR128:$ext)))>;
8312 def : Pat<(vextract128_extract:$ext VR256:$src1, (iPTR imm)),
8313           (v4i32 (VEXTRACTF128rr
8314                   (v8i32 VR256:$src1),
8315                   (EXTRACT_get_vextract128_imm VR128:$ext)))>;
8316 def : Pat<(vextract128_extract:$ext VR256:$src1, (iPTR imm)),
8317           (v8i16 (VEXTRACTF128rr
8318                   (v16i16 VR256:$src1),
8319                   (EXTRACT_get_vextract128_imm VR128:$ext)))>;
8320 def : Pat<(vextract128_extract:$ext VR256:$src1, (iPTR imm)),
8321           (v16i8 (VEXTRACTF128rr
8322                   (v32i8 VR256:$src1),
8323                   (EXTRACT_get_vextract128_imm VR128:$ext)))>;
8324
8325 def : Pat<(alignedstore (v2i64 (vextract128_extract:$ext (v4i64 VR256:$src1),
8326                                 (iPTR imm))), addr:$dst),
8327           (VEXTRACTF128mr addr:$dst, VR256:$src1,
8328            (EXTRACT_get_vextract128_imm VR128:$ext))>;
8329 def : Pat<(alignedstore (v4i32 (vextract128_extract:$ext (v8i32 VR256:$src1),
8330                                 (iPTR imm))), addr:$dst),
8331           (VEXTRACTF128mr addr:$dst, VR256:$src1,
8332            (EXTRACT_get_vextract128_imm VR128:$ext))>;
8333 def : Pat<(alignedstore (v8i16 (vextract128_extract:$ext (v16i16 VR256:$src1),
8334                                 (iPTR imm))), addr:$dst),
8335           (VEXTRACTF128mr addr:$dst, VR256:$src1,
8336            (EXTRACT_get_vextract128_imm VR128:$ext))>;
8337 def : Pat<(alignedstore (v16i8 (vextract128_extract:$ext (v32i8 VR256:$src1),
8338                                 (iPTR imm))), addr:$dst),
8339           (VEXTRACTF128mr addr:$dst, VR256:$src1,
8340            (EXTRACT_get_vextract128_imm VR128:$ext))>;
8341 }
8342
8343 //===----------------------------------------------------------------------===//
8344 // VMASKMOV - Conditional SIMD Packed Loads and Stores
8345 //
8346 multiclass avx_movmask_rm<bits<8> opc_rm, bits<8> opc_mr, string OpcodeStr,
8347                           Intrinsic IntLd, Intrinsic IntLd256,
8348                           Intrinsic IntSt, Intrinsic IntSt256> {
8349   def rm  : AVX8I<opc_rm, MRMSrcMem, (outs VR128:$dst),
8350              (ins VR128:$src1, f128mem:$src2),
8351              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8352              [(set VR128:$dst, (IntLd addr:$src2, VR128:$src1))]>,
8353              VEX_4V;
8354   def Yrm : AVX8I<opc_rm, MRMSrcMem, (outs VR256:$dst),
8355              (ins VR256:$src1, f256mem:$src2),
8356              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8357              [(set VR256:$dst, (IntLd256 addr:$src2, VR256:$src1))]>,
8358              VEX_4V, VEX_L;
8359   def mr  : AVX8I<opc_mr, MRMDestMem, (outs),
8360              (ins f128mem:$dst, VR128:$src1, VR128:$src2),
8361              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8362              [(IntSt addr:$dst, VR128:$src1, VR128:$src2)]>, VEX_4V;
8363   def Ymr : AVX8I<opc_mr, MRMDestMem, (outs),
8364              (ins f256mem:$dst, VR256:$src1, VR256:$src2),
8365              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8366              [(IntSt256 addr:$dst, VR256:$src1, VR256:$src2)]>, VEX_4V, VEX_L;
8367 }
8368
8369 let ExeDomain = SSEPackedSingle in
8370 defm VMASKMOVPS : avx_movmask_rm<0x2C, 0x2E, "vmaskmovps",
8371                                  int_x86_avx_maskload_ps,
8372                                  int_x86_avx_maskload_ps_256,
8373                                  int_x86_avx_maskstore_ps,
8374                                  int_x86_avx_maskstore_ps_256>;
8375 let ExeDomain = SSEPackedDouble in
8376 defm VMASKMOVPD : avx_movmask_rm<0x2D, 0x2F, "vmaskmovpd",
8377                                  int_x86_avx_maskload_pd,
8378                                  int_x86_avx_maskload_pd_256,
8379                                  int_x86_avx_maskstore_pd,
8380                                  int_x86_avx_maskstore_pd_256>;
8381
8382 //===----------------------------------------------------------------------===//
8383 // VPERMIL - Permute Single and Double Floating-Point Values
8384 //
8385 multiclass avx_permil<bits<8> opc_rm, bits<8> opc_rmi, string OpcodeStr,
8386                       RegisterClass RC, X86MemOperand x86memop_f,
8387                       X86MemOperand x86memop_i, PatFrag i_frag,
8388                       Intrinsic IntVar, ValueType vt> {
8389   def rr  : AVX8I<opc_rm, MRMSrcReg, (outs RC:$dst),
8390              (ins RC:$src1, RC:$src2),
8391              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8392              [(set RC:$dst, (IntVar RC:$src1, RC:$src2))]>, VEX_4V,
8393              Sched<[WriteFShuffle]>;
8394   def rm  : AVX8I<opc_rm, MRMSrcMem, (outs RC:$dst),
8395              (ins RC:$src1, x86memop_i:$src2),
8396              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8397              [(set RC:$dst, (IntVar RC:$src1,
8398                              (bitconvert (i_frag addr:$src2))))]>, VEX_4V,
8399              Sched<[WriteFShuffleLd, ReadAfterLd]>;
8400
8401   def ri  : AVXAIi8<opc_rmi, MRMSrcReg, (outs RC:$dst),
8402              (ins RC:$src1, i8imm:$src2),
8403              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8404              [(set RC:$dst, (vt (X86VPermilpi RC:$src1, (i8 imm:$src2))))]>, VEX,
8405              Sched<[WriteFShuffle]>;
8406   def mi  : AVXAIi8<opc_rmi, MRMSrcMem, (outs RC:$dst),
8407              (ins x86memop_f:$src1, i8imm:$src2),
8408              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8409              [(set RC:$dst,
8410                (vt (X86VPermilpi (memop addr:$src1), (i8 imm:$src2))))]>, VEX,
8411              Sched<[WriteFShuffleLd]>;
8412 }
8413
8414 let ExeDomain = SSEPackedSingle in {
8415   defm VPERMILPS  : avx_permil<0x0C, 0x04, "vpermilps", VR128, f128mem, i128mem,
8416                                loadv2i64, int_x86_avx_vpermilvar_ps, v4f32>;
8417   defm VPERMILPSY : avx_permil<0x0C, 0x04, "vpermilps", VR256, f256mem, i256mem,
8418                        loadv4i64, int_x86_avx_vpermilvar_ps_256, v8f32>, VEX_L;
8419 }
8420 let ExeDomain = SSEPackedDouble in {
8421   defm VPERMILPD  : avx_permil<0x0D, 0x05, "vpermilpd", VR128, f128mem, i128mem,
8422                                loadv2i64, int_x86_avx_vpermilvar_pd, v2f64>;
8423   defm VPERMILPDY : avx_permil<0x0D, 0x05, "vpermilpd", VR256, f256mem, i256mem,
8424                        loadv4i64, int_x86_avx_vpermilvar_pd_256, v4f64>, VEX_L;
8425 }
8426
8427 let Predicates = [HasAVX] in {
8428 def : Pat<(v8f32 (X86VPermilpv VR256:$src1, (v8i32 VR256:$src2))),
8429           (VPERMILPSYrr VR256:$src1, VR256:$src2)>;
8430 def : Pat<(v8f32 (X86VPermilpv VR256:$src1, (bc_v8i32 (loadv4i64 addr:$src2)))),
8431           (VPERMILPSYrm VR256:$src1, addr:$src2)>;
8432 def : Pat<(v4f64 (X86VPermilpv VR256:$src1, (v4i64 VR256:$src2))),
8433           (VPERMILPDYrr VR256:$src1, VR256:$src2)>;
8434 def : Pat<(v4f64 (X86VPermilpv VR256:$src1, (loadv4i64 addr:$src2))),
8435           (VPERMILPDYrm VR256:$src1, addr:$src2)>;
8436
8437 def : Pat<(v8i32 (X86VPermilpi VR256:$src1, (i8 imm:$imm))),
8438           (VPERMILPSYri VR256:$src1, imm:$imm)>;
8439 def : Pat<(v4i64 (X86VPermilpi VR256:$src1, (i8 imm:$imm))),
8440           (VPERMILPDYri VR256:$src1, imm:$imm)>;
8441 def : Pat<(v8i32 (X86VPermilpi (bc_v8i32 (loadv4i64 addr:$src1)),
8442                                (i8 imm:$imm))),
8443           (VPERMILPSYmi addr:$src1, imm:$imm)>;
8444 def : Pat<(v4i64 (X86VPermilpi (loadv4i64 addr:$src1), (i8 imm:$imm))),
8445           (VPERMILPDYmi addr:$src1, imm:$imm)>;
8446
8447 def : Pat<(v4f32 (X86VPermilpv VR128:$src1, (v4i32 VR128:$src2))),
8448           (VPERMILPSrr VR128:$src1, VR128:$src2)>;
8449 def : Pat<(v4f32 (X86VPermilpv VR128:$src1, (bc_v4i32 (loadv2i64 addr:$src2)))),
8450           (VPERMILPSrm VR128:$src1, addr:$src2)>;
8451 def : Pat<(v2f64 (X86VPermilpv VR128:$src1, (v2i64 VR128:$src2))),
8452           (VPERMILPDrr VR128:$src1, VR128:$src2)>;
8453 def : Pat<(v2f64 (X86VPermilpv VR128:$src1, (loadv2i64 addr:$src2))),
8454           (VPERMILPDrm VR128:$src1, addr:$src2)>;
8455
8456 def : Pat<(v2i64 (X86VPermilpi VR128:$src1, (i8 imm:$imm))),
8457           (VPERMILPDri VR128:$src1, imm:$imm)>;
8458 def : Pat<(v2i64 (X86VPermilpi (loadv2i64 addr:$src1), (i8 imm:$imm))),
8459           (VPERMILPDmi addr:$src1, imm:$imm)>;
8460 }
8461
8462 //===----------------------------------------------------------------------===//
8463 // VPERM2F128 - Permute Floating-Point Values in 128-bit chunks
8464 //
8465 let ExeDomain = SSEPackedSingle in {
8466 def VPERM2F128rr : AVXAIi8<0x06, MRMSrcReg, (outs VR256:$dst),
8467           (ins VR256:$src1, VR256:$src2, i8imm:$src3),
8468           "vperm2f128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
8469           [(set VR256:$dst, (v8f32 (X86VPerm2x128 VR256:$src1, VR256:$src2,
8470                               (i8 imm:$src3))))]>, VEX_4V, VEX_L,
8471           Sched<[WriteFShuffle]>;
8472 def VPERM2F128rm : AVXAIi8<0x06, MRMSrcMem, (outs VR256:$dst),
8473           (ins VR256:$src1, f256mem:$src2, i8imm:$src3),
8474           "vperm2f128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
8475           [(set VR256:$dst, (X86VPerm2x128 VR256:$src1, (loadv8f32 addr:$src2),
8476                              (i8 imm:$src3)))]>, VEX_4V, VEX_L,
8477           Sched<[WriteFShuffleLd, ReadAfterLd]>;
8478 }
8479
8480 let Predicates = [HasAVX] in {
8481 def : Pat<(v4f64 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
8482           (VPERM2F128rr VR256:$src1, VR256:$src2, imm:$imm)>;
8483 def : Pat<(v4f64 (X86VPerm2x128 VR256:$src1,
8484                   (loadv4f64 addr:$src2), (i8 imm:$imm))),
8485           (VPERM2F128rm VR256:$src1, addr:$src2, imm:$imm)>;
8486 }
8487
8488 let Predicates = [HasAVX1Only] in {
8489 def : Pat<(v8i32 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
8490           (VPERM2F128rr VR256:$src1, VR256:$src2, imm:$imm)>;
8491 def : Pat<(v4i64 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
8492           (VPERM2F128rr VR256:$src1, VR256:$src2, imm:$imm)>;
8493 def : Pat<(v32i8 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
8494           (VPERM2F128rr VR256:$src1, VR256:$src2, imm:$imm)>;
8495 def : Pat<(v16i16 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
8496           (VPERM2F128rr VR256:$src1, VR256:$src2, imm:$imm)>;
8497
8498 def : Pat<(v8i32 (X86VPerm2x128 VR256:$src1,
8499                   (bc_v8i32 (loadv4i64 addr:$src2)), (i8 imm:$imm))),
8500           (VPERM2F128rm VR256:$src1, addr:$src2, imm:$imm)>;
8501 def : Pat<(v4i64 (X86VPerm2x128 VR256:$src1,
8502                   (loadv4i64 addr:$src2), (i8 imm:$imm))),
8503           (VPERM2F128rm VR256:$src1, addr:$src2, imm:$imm)>;
8504 def : Pat<(v32i8 (X86VPerm2x128 VR256:$src1,
8505                   (bc_v32i8 (loadv4i64 addr:$src2)), (i8 imm:$imm))),
8506           (VPERM2F128rm VR256:$src1, addr:$src2, imm:$imm)>;
8507 def : Pat<(v16i16 (X86VPerm2x128 VR256:$src1,
8508                   (bc_v16i16 (loadv4i64 addr:$src2)), (i8 imm:$imm))),
8509           (VPERM2F128rm VR256:$src1, addr:$src2, imm:$imm)>;
8510 }
8511
8512 //===----------------------------------------------------------------------===//
8513 // VZERO - Zero YMM registers
8514 //
8515 let Defs = [YMM0, YMM1, YMM2, YMM3, YMM4, YMM5, YMM6, YMM7,
8516             YMM8, YMM9, YMM10, YMM11, YMM12, YMM13, YMM14, YMM15] in {
8517   // Zero All YMM registers
8518   def VZEROALL : I<0x77, RawFrm, (outs), (ins), "vzeroall",
8519                   [(int_x86_avx_vzeroall)]>, PS, VEX, VEX_L, Requires<[HasAVX]>;
8520
8521   // Zero Upper bits of YMM registers
8522   def VZEROUPPER : I<0x77, RawFrm, (outs), (ins), "vzeroupper",
8523                      [(int_x86_avx_vzeroupper)]>, PS, VEX, Requires<[HasAVX]>;
8524 }
8525
8526 //===----------------------------------------------------------------------===//
8527 // Half precision conversion instructions
8528 //===----------------------------------------------------------------------===//
8529 multiclass f16c_ph2ps<RegisterClass RC, X86MemOperand x86memop, Intrinsic Int> {
8530   def rr : I<0x13, MRMSrcReg, (outs RC:$dst), (ins VR128:$src),
8531              "vcvtph2ps\t{$src, $dst|$dst, $src}",
8532              [(set RC:$dst, (Int VR128:$src))]>,
8533              T8PD, VEX, Sched<[WriteCvtF2F]>;
8534   let neverHasSideEffects = 1, mayLoad = 1 in
8535   def rm : I<0x13, MRMSrcMem, (outs RC:$dst), (ins x86memop:$src),
8536              "vcvtph2ps\t{$src, $dst|$dst, $src}", []>, T8PD, VEX,
8537              Sched<[WriteCvtF2FLd]>;
8538 }
8539
8540 multiclass f16c_ps2ph<RegisterClass RC, X86MemOperand x86memop, Intrinsic Int> {
8541   def rr : Ii8<0x1D, MRMDestReg, (outs VR128:$dst),
8542                (ins RC:$src1, i32i8imm:$src2),
8543                "vcvtps2ph\t{$src2, $src1, $dst|$dst, $src1, $src2}",
8544                [(set VR128:$dst, (Int RC:$src1, imm:$src2))]>,
8545                TAPD, VEX, Sched<[WriteCvtF2F]>;
8546   let neverHasSideEffects = 1, mayStore = 1,
8547       SchedRW = [WriteCvtF2FLd, WriteRMW] in
8548   def mr : Ii8<0x1D, MRMDestMem, (outs),
8549                (ins x86memop:$dst, RC:$src1, i32i8imm:$src2),
8550                "vcvtps2ph\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>,
8551                TAPD, VEX;
8552 }
8553
8554 let Predicates = [HasF16C] in {
8555   defm VCVTPH2PS  : f16c_ph2ps<VR128, f64mem, int_x86_vcvtph2ps_128>;
8556   defm VCVTPH2PSY : f16c_ph2ps<VR256, f128mem, int_x86_vcvtph2ps_256>, VEX_L;
8557   defm VCVTPS2PH  : f16c_ps2ph<VR128, f64mem, int_x86_vcvtps2ph_128>;
8558   defm VCVTPS2PHY : f16c_ps2ph<VR256, f128mem, int_x86_vcvtps2ph_256>, VEX_L;
8559
8560   // Pattern match vcvtph2ps of a scalar i64 load.
8561   def : Pat<(int_x86_vcvtph2ps_128 (vzmovl_v2i64 addr:$src)),
8562             (VCVTPH2PSrm addr:$src)>;
8563   def : Pat<(int_x86_vcvtph2ps_128 (vzload_v2i64 addr:$src)),
8564             (VCVTPH2PSrm addr:$src)>;
8565 }
8566
8567 // Patterns for  matching conversions from float to half-float and vice versa.
8568 let Predicates = [HasF16C] in {
8569   def : Pat<(fp_to_f16 FR32:$src),
8570             (i16 (EXTRACT_SUBREG (VMOVPDI2DIrr (VCVTPS2PHrr
8571               (COPY_TO_REGCLASS FR32:$src, VR128), 0)), sub_16bit))>;
8572
8573   def : Pat<(f16_to_fp GR16:$src),
8574             (f32 (COPY_TO_REGCLASS (VCVTPH2PSrr
8575               (COPY_TO_REGCLASS (MOVSX32rr16 GR16:$src), VR128)), FR32)) >;
8576
8577   def : Pat<(f16_to_fp (i16 (fp_to_f16 FR32:$src))),
8578             (f32 (COPY_TO_REGCLASS (VCVTPH2PSrr
8579               (VCVTPS2PHrr (COPY_TO_REGCLASS FR32:$src, VR128), 0)), FR32)) >;
8580 }
8581
8582 //===----------------------------------------------------------------------===//
8583 // AVX2 Instructions
8584 //===----------------------------------------------------------------------===//
8585
8586 /// AVX2_binop_rmi_int - AVX2 binary operator with 8-bit immediate
8587 multiclass AVX2_binop_rmi_int<bits<8> opc, string OpcodeStr,
8588                  Intrinsic IntId, RegisterClass RC, PatFrag memop_frag,
8589                  X86MemOperand x86memop> {
8590   let isCommutable = 1 in
8591   def rri : AVX2AIi8<opc, MRMSrcReg, (outs RC:$dst),
8592         (ins RC:$src1, RC:$src2, i8imm:$src3),
8593         !strconcat(OpcodeStr,
8594             "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
8595         [(set RC:$dst, (IntId RC:$src1, RC:$src2, imm:$src3))]>,
8596         Sched<[WriteBlend]>, VEX_4V;
8597   def rmi : AVX2AIi8<opc, MRMSrcMem, (outs RC:$dst),
8598         (ins RC:$src1, x86memop:$src2, i8imm:$src3),
8599         !strconcat(OpcodeStr,
8600             "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
8601         [(set RC:$dst,
8602           (IntId RC:$src1,
8603            (bitconvert (memop_frag addr:$src2)), imm:$src3))]>,
8604         Sched<[WriteBlendLd, ReadAfterLd]>, VEX_4V;
8605 }
8606
8607 let isCommutable = 0 in {
8608 defm VPBLENDD : AVX2_binop_rmi_int<0x02, "vpblendd", int_x86_avx2_pblendd_128,
8609                                    VR128, loadv2i64, i128mem>;
8610 defm VPBLENDDY : AVX2_binop_rmi_int<0x02, "vpblendd", int_x86_avx2_pblendd_256,
8611                                     VR256, loadv4i64, i256mem>, VEX_L;
8612 }
8613
8614 def : Pat<(v4i32 (X86Blendi (v4i32 VR128:$src1), (v4i32 VR128:$src2),
8615                   imm:$mask)),
8616           (VPBLENDDrri VR128:$src1, VR128:$src2, imm:$mask)>;
8617 def : Pat<(v8i32 (X86Blendi (v8i32 VR256:$src1), (v8i32 VR256:$src2),
8618                   imm:$mask)),
8619           (VPBLENDDYrri VR256:$src1, VR256:$src2, imm:$mask)>;
8620
8621 //===----------------------------------------------------------------------===//
8622 // VPBROADCAST - Load from memory and broadcast to all elements of the
8623 //               destination operand
8624 //
8625 multiclass avx2_broadcast<bits<8> opc, string OpcodeStr,
8626                           X86MemOperand x86memop, PatFrag ld_frag,
8627                           Intrinsic Int128, Intrinsic Int256> {
8628   def rr : AVX28I<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
8629                   !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
8630                   [(set VR128:$dst, (Int128 VR128:$src))]>,
8631                   Sched<[WriteShuffle]>, VEX;
8632   def rm : AVX28I<opc, MRMSrcMem, (outs VR128:$dst), (ins x86memop:$src),
8633                   !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
8634                   [(set VR128:$dst,
8635                     (Int128 (scalar_to_vector (ld_frag addr:$src))))]>,
8636                   Sched<[WriteLoad]>, VEX;
8637   def Yrr : AVX28I<opc, MRMSrcReg, (outs VR256:$dst), (ins VR128:$src),
8638                    !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
8639                    [(set VR256:$dst, (Int256 VR128:$src))]>,
8640                    Sched<[WriteShuffle256]>, VEX, VEX_L;
8641   def Yrm : AVX28I<opc, MRMSrcMem, (outs VR256:$dst), (ins x86memop:$src),
8642                    !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
8643                    [(set VR256:$dst,
8644                     (Int256 (scalar_to_vector (ld_frag addr:$src))))]>,
8645                    Sched<[WriteLoad]>, VEX, VEX_L;
8646 }
8647
8648 defm VPBROADCASTB  : avx2_broadcast<0x78, "vpbroadcastb", i8mem, loadi8,
8649                                     int_x86_avx2_pbroadcastb_128,
8650                                     int_x86_avx2_pbroadcastb_256>;
8651 defm VPBROADCASTW  : avx2_broadcast<0x79, "vpbroadcastw", i16mem, loadi16,
8652                                     int_x86_avx2_pbroadcastw_128,
8653                                     int_x86_avx2_pbroadcastw_256>;
8654 defm VPBROADCASTD  : avx2_broadcast<0x58, "vpbroadcastd", i32mem, loadi32,
8655                                     int_x86_avx2_pbroadcastd_128,
8656                                     int_x86_avx2_pbroadcastd_256>;
8657 defm VPBROADCASTQ  : avx2_broadcast<0x59, "vpbroadcastq", i64mem, loadi64,
8658                                     int_x86_avx2_pbroadcastq_128,
8659                                     int_x86_avx2_pbroadcastq_256>;
8660
8661 let Predicates = [HasAVX2] in {
8662   def : Pat<(v16i8 (X86VBroadcast (loadi8 addr:$src))),
8663           (VPBROADCASTBrm addr:$src)>;
8664   def : Pat<(v32i8 (X86VBroadcast (loadi8 addr:$src))),
8665           (VPBROADCASTBYrm addr:$src)>;
8666   def : Pat<(v8i16 (X86VBroadcast (loadi16 addr:$src))),
8667           (VPBROADCASTWrm addr:$src)>;
8668   def : Pat<(v16i16 (X86VBroadcast (loadi16 addr:$src))),
8669           (VPBROADCASTWYrm addr:$src)>;
8670   def : Pat<(v4i32 (X86VBroadcast (loadi32 addr:$src))),
8671           (VPBROADCASTDrm addr:$src)>;
8672   def : Pat<(v8i32 (X86VBroadcast (loadi32 addr:$src))),
8673           (VPBROADCASTDYrm addr:$src)>;
8674   def : Pat<(v2i64 (X86VBroadcast (loadi64 addr:$src))),
8675           (VPBROADCASTQrm addr:$src)>;
8676   def : Pat<(v4i64 (X86VBroadcast (loadi64 addr:$src))),
8677           (VPBROADCASTQYrm addr:$src)>;
8678
8679   def : Pat<(v16i8 (X86VBroadcast (v16i8 VR128:$src))),
8680           (VPBROADCASTBrr VR128:$src)>;
8681   def : Pat<(v32i8 (X86VBroadcast (v16i8 VR128:$src))),
8682           (VPBROADCASTBYrr VR128:$src)>;
8683   def : Pat<(v8i16 (X86VBroadcast (v8i16 VR128:$src))),
8684           (VPBROADCASTWrr VR128:$src)>;
8685   def : Pat<(v16i16 (X86VBroadcast (v8i16 VR128:$src))),
8686           (VPBROADCASTWYrr VR128:$src)>;
8687   def : Pat<(v4i32 (X86VBroadcast (v4i32 VR128:$src))),
8688           (VPBROADCASTDrr VR128:$src)>;
8689   def : Pat<(v8i32 (X86VBroadcast (v4i32 VR128:$src))),
8690           (VPBROADCASTDYrr VR128:$src)>;
8691   def : Pat<(v2i64 (X86VBroadcast (v2i64 VR128:$src))),
8692           (VPBROADCASTQrr VR128:$src)>;
8693   def : Pat<(v4i64 (X86VBroadcast (v2i64 VR128:$src))),
8694           (VPBROADCASTQYrr VR128:$src)>;
8695   def : Pat<(v4f32 (X86VBroadcast (v4f32 VR128:$src))),
8696           (VBROADCASTSSrr VR128:$src)>;
8697   def : Pat<(v8f32 (X86VBroadcast (v4f32 VR128:$src))),
8698           (VBROADCASTSSYrr VR128:$src)>;
8699   def : Pat<(v2f64 (X86VBroadcast (v2f64 VR128:$src))),
8700           (VPBROADCASTQrr VR128:$src)>;
8701   def : Pat<(v4f64 (X86VBroadcast (v2f64 VR128:$src))),
8702           (VBROADCASTSDYrr VR128:$src)>;
8703
8704   // Provide fallback in case the load node that is used in the patterns above
8705   // is used by additional users, which prevents the pattern selection.
8706   let AddedComplexity = 20 in {
8707     def : Pat<(v4f32 (X86VBroadcast FR32:$src)),
8708               (VBROADCASTSSrr (COPY_TO_REGCLASS FR32:$src, VR128))>;
8709     def : Pat<(v8f32 (X86VBroadcast FR32:$src)),
8710               (VBROADCASTSSYrr (COPY_TO_REGCLASS FR32:$src, VR128))>;
8711     def : Pat<(v4f64 (X86VBroadcast FR64:$src)),
8712               (VBROADCASTSDYrr (COPY_TO_REGCLASS FR64:$src, VR128))>;
8713
8714     def : Pat<(v4i32 (X86VBroadcast GR32:$src)),
8715               (VBROADCASTSSrr (COPY_TO_REGCLASS GR32:$src, VR128))>;
8716     def : Pat<(v8i32 (X86VBroadcast GR32:$src)),
8717               (VBROADCASTSSYrr (COPY_TO_REGCLASS GR32:$src, VR128))>;
8718     def : Pat<(v4i64 (X86VBroadcast GR64:$src)),
8719               (VBROADCASTSDYrr (COPY_TO_REGCLASS GR64:$src, VR128))>;
8720
8721     def : Pat<(v16i8 (X86VBroadcast GR8:$src)),
8722           (VPBROADCASTBrr (COPY_TO_REGCLASS
8723                            (i32 (SUBREG_TO_REG (i32 0), GR8:$src, sub_8bit)),
8724                            VR128))>;
8725     def : Pat<(v32i8 (X86VBroadcast GR8:$src)),
8726           (VPBROADCASTBYrr (COPY_TO_REGCLASS
8727                             (i32 (SUBREG_TO_REG (i32 0), GR8:$src, sub_8bit)),
8728                             VR128))>;
8729
8730     def : Pat<(v8i16 (X86VBroadcast GR16:$src)),
8731           (VPBROADCASTWrr (COPY_TO_REGCLASS
8732                            (i32 (SUBREG_TO_REG (i32 0), GR16:$src, sub_16bit)),
8733                            VR128))>;
8734     def : Pat<(v16i16 (X86VBroadcast GR16:$src)),
8735           (VPBROADCASTWYrr (COPY_TO_REGCLASS
8736                             (i32 (SUBREG_TO_REG (i32 0), GR16:$src, sub_16bit)),
8737                             VR128))>;
8738
8739     // The patterns for VPBROADCASTD are not needed because they would match
8740     // the exact same thing as VBROADCASTSS patterns.
8741
8742     def : Pat<(v2i64 (X86VBroadcast GR64:$src)),
8743           (VPBROADCASTQrr (COPY_TO_REGCLASS GR64:$src, VR128))>;
8744     // The v4i64 pattern is not needed because VBROADCASTSDYrr already match.
8745   }
8746 }
8747
8748 // AVX1 broadcast patterns
8749 let Predicates = [HasAVX1Only] in {
8750 def : Pat<(v8i32 (X86VBroadcast (loadi32 addr:$src))),
8751           (VBROADCASTSSYrm addr:$src)>;
8752 def : Pat<(v4i64 (X86VBroadcast (loadi64 addr:$src))),
8753           (VBROADCASTSDYrm addr:$src)>;
8754 def : Pat<(v4i32 (X86VBroadcast (loadi32 addr:$src))),
8755           (VBROADCASTSSrm addr:$src)>;
8756 }
8757
8758 let Predicates = [HasAVX] in {
8759   // Provide fallback in case the load node that is used in the patterns above
8760   // is used by additional users, which prevents the pattern selection.
8761   let AddedComplexity = 20 in {
8762   // 128bit broadcasts:
8763   def : Pat<(v4f32 (X86VBroadcast FR32:$src)),
8764             (VPSHUFDri (COPY_TO_REGCLASS FR32:$src, VR128), 0)>;
8765   def : Pat<(v8f32 (X86VBroadcast FR32:$src)),
8766             (VINSERTF128rr (INSERT_SUBREG (v8f32 (IMPLICIT_DEF)),
8767               (VPSHUFDri (COPY_TO_REGCLASS FR32:$src, VR128), 0), sub_xmm),
8768               (VPSHUFDri (COPY_TO_REGCLASS FR32:$src, VR128), 0), 1)>;
8769   def : Pat<(v4f64 (X86VBroadcast FR64:$src)),
8770             (VINSERTF128rr (INSERT_SUBREG (v4f64 (IMPLICIT_DEF)),
8771               (VPSHUFDri (COPY_TO_REGCLASS FR64:$src, VR128), 0x44), sub_xmm),
8772               (VPSHUFDri (COPY_TO_REGCLASS FR64:$src, VR128), 0x44), 1)>;
8773
8774   def : Pat<(v4i32 (X86VBroadcast GR32:$src)),
8775             (VPSHUFDri (COPY_TO_REGCLASS GR32:$src, VR128), 0)>;
8776   def : Pat<(v8i32 (X86VBroadcast GR32:$src)),
8777             (VINSERTF128rr (INSERT_SUBREG (v8i32 (IMPLICIT_DEF)),
8778               (VPSHUFDri (COPY_TO_REGCLASS GR32:$src, VR128), 0), sub_xmm),
8779               (VPSHUFDri (COPY_TO_REGCLASS GR32:$src, VR128), 0), 1)>;
8780   def : Pat<(v4i64 (X86VBroadcast GR64:$src)),
8781             (VINSERTF128rr (INSERT_SUBREG (v4i64 (IMPLICIT_DEF)),
8782               (VPSHUFDri (COPY_TO_REGCLASS GR64:$src, VR128), 0x44), sub_xmm),
8783               (VPSHUFDri (COPY_TO_REGCLASS GR64:$src, VR128), 0x44), 1)>;
8784   }
8785
8786   def : Pat<(v2f64 (X86VBroadcast f64:$src)),
8787             (VMOVDDUPrr (COPY_TO_REGCLASS FR64:$src, VR128))>;
8788 }
8789
8790 //===----------------------------------------------------------------------===//
8791 // VPERM - Permute instructions
8792 //
8793
8794 multiclass avx2_perm<bits<8> opc, string OpcodeStr, PatFrag mem_frag,
8795                      ValueType OpVT, X86FoldableSchedWrite Sched> {
8796   def Yrr : AVX28I<opc, MRMSrcReg, (outs VR256:$dst),
8797                    (ins VR256:$src1, VR256:$src2),
8798                    !strconcat(OpcodeStr,
8799                        "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8800                    [(set VR256:$dst,
8801                      (OpVT (X86VPermv VR256:$src1, VR256:$src2)))]>,
8802                    Sched<[Sched]>, VEX_4V, VEX_L;
8803   def Yrm : AVX28I<opc, MRMSrcMem, (outs VR256:$dst),
8804                    (ins VR256:$src1, i256mem:$src2),
8805                    !strconcat(OpcodeStr,
8806                        "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8807                    [(set VR256:$dst,
8808                      (OpVT (X86VPermv VR256:$src1,
8809                             (bitconvert (mem_frag addr:$src2)))))]>,
8810                    Sched<[Sched.Folded, ReadAfterLd]>, VEX_4V, VEX_L;
8811 }
8812
8813 defm VPERMD : avx2_perm<0x36, "vpermd", loadv4i64, v8i32, WriteShuffle256>;
8814 let ExeDomain = SSEPackedSingle in
8815 defm VPERMPS : avx2_perm<0x16, "vpermps", loadv8f32, v8f32, WriteFShuffle256>;
8816
8817 multiclass avx2_perm_imm<bits<8> opc, string OpcodeStr, PatFrag mem_frag,
8818                          ValueType OpVT, X86FoldableSchedWrite Sched> {
8819   def Yri : AVX2AIi8<opc, MRMSrcReg, (outs VR256:$dst),
8820                      (ins VR256:$src1, i8imm:$src2),
8821                      !strconcat(OpcodeStr,
8822                          "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8823                      [(set VR256:$dst,
8824                        (OpVT (X86VPermi VR256:$src1, (i8 imm:$src2))))]>,
8825                      Sched<[Sched]>, VEX, VEX_L;
8826   def Ymi : AVX2AIi8<opc, MRMSrcMem, (outs VR256:$dst),
8827                      (ins i256mem:$src1, i8imm:$src2),
8828                      !strconcat(OpcodeStr,
8829                          "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8830                      [(set VR256:$dst,
8831                        (OpVT (X86VPermi (mem_frag addr:$src1),
8832                               (i8 imm:$src2))))]>,
8833                      Sched<[Sched.Folded, ReadAfterLd]>, VEX, VEX_L;
8834 }
8835
8836 defm VPERMQ : avx2_perm_imm<0x00, "vpermq", loadv4i64, v4i64,
8837                             WriteShuffle256>, VEX_W;
8838 let ExeDomain = SSEPackedDouble in
8839 defm VPERMPD : avx2_perm_imm<0x01, "vpermpd", loadv4f64, v4f64,
8840                              WriteFShuffle256>, VEX_W;
8841
8842 //===----------------------------------------------------------------------===//
8843 // VPERM2I128 - Permute Floating-Point Values in 128-bit chunks
8844 //
8845 def VPERM2I128rr : AVX2AIi8<0x46, MRMSrcReg, (outs VR256:$dst),
8846           (ins VR256:$src1, VR256:$src2, i8imm:$src3),
8847           "vperm2i128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
8848           [(set VR256:$dst, (v4i64 (X86VPerm2x128 VR256:$src1, VR256:$src2,
8849                             (i8 imm:$src3))))]>, Sched<[WriteShuffle256]>,
8850           VEX_4V, VEX_L;
8851 def VPERM2I128rm : AVX2AIi8<0x46, MRMSrcMem, (outs VR256:$dst),
8852           (ins VR256:$src1, f256mem:$src2, i8imm:$src3),
8853           "vperm2i128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
8854           [(set VR256:$dst, (X86VPerm2x128 VR256:$src1, (loadv4i64 addr:$src2),
8855                              (i8 imm:$src3)))]>,
8856           Sched<[WriteShuffle256Ld, ReadAfterLd]>, VEX_4V, VEX_L;
8857
8858 let Predicates = [HasAVX2] in {
8859 def : Pat<(v8i32 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
8860           (VPERM2I128rr VR256:$src1, VR256:$src2, imm:$imm)>;
8861 def : Pat<(v32i8 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
8862           (VPERM2I128rr VR256:$src1, VR256:$src2, imm:$imm)>;
8863 def : Pat<(v16i16 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
8864           (VPERM2I128rr VR256:$src1, VR256:$src2, imm:$imm)>;
8865
8866 def : Pat<(v32i8 (X86VPerm2x128 VR256:$src1, (bc_v32i8 (loadv4i64 addr:$src2)),
8867                   (i8 imm:$imm))),
8868           (VPERM2I128rm VR256:$src1, addr:$src2, imm:$imm)>;
8869 def : Pat<(v16i16 (X86VPerm2x128 VR256:$src1,
8870                    (bc_v16i16 (loadv4i64 addr:$src2)), (i8 imm:$imm))),
8871           (VPERM2I128rm VR256:$src1, addr:$src2, imm:$imm)>;
8872 def : Pat<(v8i32 (X86VPerm2x128 VR256:$src1, (bc_v8i32 (loadv4i64 addr:$src2)),
8873                   (i8 imm:$imm))),
8874           (VPERM2I128rm VR256:$src1, addr:$src2, imm:$imm)>;
8875 }
8876
8877
8878 //===----------------------------------------------------------------------===//
8879 // VINSERTI128 - Insert packed integer values
8880 //
8881 let neverHasSideEffects = 1 in {
8882 def VINSERTI128rr : AVX2AIi8<0x38, MRMSrcReg, (outs VR256:$dst),
8883           (ins VR256:$src1, VR128:$src2, i8imm:$src3),
8884           "vinserti128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
8885           []>, Sched<[WriteShuffle256]>, VEX_4V, VEX_L;
8886 let mayLoad = 1 in
8887 def VINSERTI128rm : AVX2AIi8<0x38, MRMSrcMem, (outs VR256:$dst),
8888           (ins VR256:$src1, i128mem:$src2, i8imm:$src3),
8889           "vinserti128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
8890           []>, Sched<[WriteShuffle256Ld, ReadAfterLd]>, VEX_4V, VEX_L;
8891 }
8892
8893 let Predicates = [HasAVX2] in {
8894 def : Pat<(vinsert128_insert:$ins (v4i64 VR256:$src1), (v2i64 VR128:$src2),
8895                                    (iPTR imm)),
8896           (VINSERTI128rr VR256:$src1, VR128:$src2,
8897                          (INSERT_get_vinsert128_imm VR256:$ins))>;
8898 def : Pat<(vinsert128_insert:$ins (v8i32 VR256:$src1), (v4i32 VR128:$src2),
8899                                    (iPTR imm)),
8900           (VINSERTI128rr VR256:$src1, VR128:$src2,
8901                          (INSERT_get_vinsert128_imm VR256:$ins))>;
8902 def : Pat<(vinsert128_insert:$ins (v32i8 VR256:$src1), (v16i8 VR128:$src2),
8903                                    (iPTR imm)),
8904           (VINSERTI128rr VR256:$src1, VR128:$src2,
8905                          (INSERT_get_vinsert128_imm VR256:$ins))>;
8906 def : Pat<(vinsert128_insert:$ins (v16i16 VR256:$src1), (v8i16 VR128:$src2),
8907                                    (iPTR imm)),
8908           (VINSERTI128rr VR256:$src1, VR128:$src2,
8909                          (INSERT_get_vinsert128_imm VR256:$ins))>;
8910
8911 def : Pat<(vinsert128_insert:$ins (v4i64 VR256:$src1), (loadv2i64 addr:$src2),
8912                                    (iPTR imm)),
8913           (VINSERTI128rm VR256:$src1, addr:$src2,
8914                          (INSERT_get_vinsert128_imm VR256:$ins))>;
8915 def : Pat<(vinsert128_insert:$ins (v8i32 VR256:$src1),
8916                                    (bc_v4i32 (loadv2i64 addr:$src2)),
8917                                    (iPTR imm)),
8918           (VINSERTI128rm VR256:$src1, addr:$src2,
8919                          (INSERT_get_vinsert128_imm VR256:$ins))>;
8920 def : Pat<(vinsert128_insert:$ins (v32i8 VR256:$src1),
8921                                    (bc_v16i8 (loadv2i64 addr:$src2)),
8922                                    (iPTR imm)),
8923           (VINSERTI128rm VR256:$src1, addr:$src2,
8924                          (INSERT_get_vinsert128_imm VR256:$ins))>;
8925 def : Pat<(vinsert128_insert:$ins (v16i16 VR256:$src1),
8926                                    (bc_v8i16 (loadv2i64 addr:$src2)),
8927                                    (iPTR imm)),
8928           (VINSERTI128rm VR256:$src1, addr:$src2,
8929                          (INSERT_get_vinsert128_imm VR256:$ins))>;
8930 }
8931
8932 //===----------------------------------------------------------------------===//
8933 // VEXTRACTI128 - Extract packed integer values
8934 //
8935 def VEXTRACTI128rr : AVX2AIi8<0x39, MRMDestReg, (outs VR128:$dst),
8936           (ins VR256:$src1, i8imm:$src2),
8937           "vextracti128\t{$src2, $src1, $dst|$dst, $src1, $src2}",
8938           [(set VR128:$dst,
8939             (int_x86_avx2_vextracti128 VR256:$src1, imm:$src2))]>,
8940           Sched<[WriteShuffle256]>, VEX, VEX_L;
8941 let neverHasSideEffects = 1, mayStore = 1 in
8942 def VEXTRACTI128mr : AVX2AIi8<0x39, MRMDestMem, (outs),
8943           (ins i128mem:$dst, VR256:$src1, i8imm:$src2),
8944           "vextracti128\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>,
8945           Sched<[WriteStore]>, VEX, VEX_L;
8946
8947 let Predicates = [HasAVX2] in {
8948 def : Pat<(vextract128_extract:$ext VR256:$src1, (iPTR imm)),
8949           (v2i64 (VEXTRACTI128rr
8950                     (v4i64 VR256:$src1),
8951                     (EXTRACT_get_vextract128_imm VR128:$ext)))>;
8952 def : Pat<(vextract128_extract:$ext VR256:$src1, (iPTR imm)),
8953           (v4i32 (VEXTRACTI128rr
8954                     (v8i32 VR256:$src1),
8955                     (EXTRACT_get_vextract128_imm VR128:$ext)))>;
8956 def : Pat<(vextract128_extract:$ext VR256:$src1, (iPTR imm)),
8957           (v8i16 (VEXTRACTI128rr
8958                     (v16i16 VR256:$src1),
8959                     (EXTRACT_get_vextract128_imm VR128:$ext)))>;
8960 def : Pat<(vextract128_extract:$ext VR256:$src1, (iPTR imm)),
8961           (v16i8 (VEXTRACTI128rr
8962                     (v32i8 VR256:$src1),
8963                     (EXTRACT_get_vextract128_imm VR128:$ext)))>;
8964
8965 def : Pat<(store (v2i64 (vextract128_extract:$ext (v4i64 VR256:$src1),
8966                          (iPTR imm))), addr:$dst),
8967           (VEXTRACTI128mr addr:$dst, VR256:$src1,
8968            (EXTRACT_get_vextract128_imm VR128:$ext))>;
8969 def : Pat<(store (v4i32 (vextract128_extract:$ext (v8i32 VR256:$src1),
8970                          (iPTR imm))), addr:$dst),
8971           (VEXTRACTI128mr addr:$dst, VR256:$src1,
8972            (EXTRACT_get_vextract128_imm VR128:$ext))>;
8973 def : Pat<(store (v8i16 (vextract128_extract:$ext (v16i16 VR256:$src1),
8974                          (iPTR imm))), addr:$dst),
8975           (VEXTRACTI128mr addr:$dst, VR256:$src1,
8976            (EXTRACT_get_vextract128_imm VR128:$ext))>;
8977 def : Pat<(store (v16i8 (vextract128_extract:$ext (v32i8 VR256:$src1),
8978                          (iPTR imm))), addr:$dst),
8979           (VEXTRACTI128mr addr:$dst, VR256:$src1,
8980            (EXTRACT_get_vextract128_imm VR128:$ext))>;
8981 }
8982
8983 //===----------------------------------------------------------------------===//
8984 // VPMASKMOV - Conditional SIMD Integer Packed Loads and Stores
8985 //
8986 multiclass avx2_pmovmask<string OpcodeStr,
8987                          Intrinsic IntLd128, Intrinsic IntLd256,
8988                          Intrinsic IntSt128, Intrinsic IntSt256> {
8989   def rm  : AVX28I<0x8c, MRMSrcMem, (outs VR128:$dst),
8990              (ins VR128:$src1, i128mem:$src2),
8991              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8992              [(set VR128:$dst, (IntLd128 addr:$src2, VR128:$src1))]>, VEX_4V;
8993   def Yrm : AVX28I<0x8c, MRMSrcMem, (outs VR256:$dst),
8994              (ins VR256:$src1, i256mem:$src2),
8995              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8996              [(set VR256:$dst, (IntLd256 addr:$src2, VR256:$src1))]>,
8997              VEX_4V, VEX_L;
8998   def mr  : AVX28I<0x8e, MRMDestMem, (outs),
8999              (ins i128mem:$dst, VR128:$src1, VR128:$src2),
9000              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
9001              [(IntSt128 addr:$dst, VR128:$src1, VR128:$src2)]>, VEX_4V;
9002   def Ymr : AVX28I<0x8e, MRMDestMem, (outs),
9003              (ins i256mem:$dst, VR256:$src1, VR256:$src2),
9004              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
9005              [(IntSt256 addr:$dst, VR256:$src1, VR256:$src2)]>, VEX_4V, VEX_L;
9006 }
9007
9008 defm VPMASKMOVD : avx2_pmovmask<"vpmaskmovd",
9009                                 int_x86_avx2_maskload_d,
9010                                 int_x86_avx2_maskload_d_256,
9011                                 int_x86_avx2_maskstore_d,
9012                                 int_x86_avx2_maskstore_d_256>;
9013 defm VPMASKMOVQ : avx2_pmovmask<"vpmaskmovq",
9014                                 int_x86_avx2_maskload_q,
9015                                 int_x86_avx2_maskload_q_256,
9016                                 int_x86_avx2_maskstore_q,
9017                                 int_x86_avx2_maskstore_q_256>, VEX_W;
9018
9019
9020 //===----------------------------------------------------------------------===//
9021 // Variable Bit Shifts
9022 //
9023 multiclass avx2_var_shift<bits<8> opc, string OpcodeStr, SDNode OpNode,
9024                           ValueType vt128, ValueType vt256> {
9025   def rr  : AVX28I<opc, MRMSrcReg, (outs VR128:$dst),
9026              (ins VR128:$src1, VR128:$src2),
9027              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
9028              [(set VR128:$dst,
9029                (vt128 (OpNode VR128:$src1, (vt128 VR128:$src2))))]>,
9030              VEX_4V, Sched<[WriteVarVecShift]>;
9031   def rm  : AVX28I<opc, MRMSrcMem, (outs VR128:$dst),
9032              (ins VR128:$src1, i128mem:$src2),
9033              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
9034              [(set VR128:$dst,
9035                (vt128 (OpNode VR128:$src1,
9036                        (vt128 (bitconvert (loadv2i64 addr:$src2))))))]>,
9037              VEX_4V, Sched<[WriteVarVecShiftLd, ReadAfterLd]>;
9038   def Yrr : AVX28I<opc, MRMSrcReg, (outs VR256:$dst),
9039              (ins VR256:$src1, VR256:$src2),
9040              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
9041              [(set VR256:$dst,
9042                (vt256 (OpNode VR256:$src1, (vt256 VR256:$src2))))]>,
9043              VEX_4V, VEX_L, Sched<[WriteVarVecShift]>;
9044   def Yrm : AVX28I<opc, MRMSrcMem, (outs VR256:$dst),
9045              (ins VR256:$src1, i256mem:$src2),
9046              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
9047              [(set VR256:$dst,
9048                (vt256 (OpNode VR256:$src1,
9049                        (vt256 (bitconvert (loadv4i64 addr:$src2))))))]>,
9050              VEX_4V, VEX_L, Sched<[WriteVarVecShiftLd, ReadAfterLd]>;
9051 }
9052
9053 defm VPSLLVD : avx2_var_shift<0x47, "vpsllvd", shl, v4i32, v8i32>;
9054 defm VPSLLVQ : avx2_var_shift<0x47, "vpsllvq", shl, v2i64, v4i64>, VEX_W;
9055 defm VPSRLVD : avx2_var_shift<0x45, "vpsrlvd", srl, v4i32, v8i32>;
9056 defm VPSRLVQ : avx2_var_shift<0x45, "vpsrlvq", srl, v2i64, v4i64>, VEX_W;
9057 defm VPSRAVD : avx2_var_shift<0x46, "vpsravd", sra, v4i32, v8i32>;
9058
9059 //===----------------------------------------------------------------------===//
9060 // VGATHER - GATHER Operations
9061 multiclass avx2_gather<bits<8> opc, string OpcodeStr, RegisterClass RC256,
9062                        X86MemOperand memop128, X86MemOperand memop256> {
9063   def rm  : AVX28I<opc, MRMSrcMem, (outs VR128:$dst, VR128:$mask_wb),
9064             (ins VR128:$src1, memop128:$src2, VR128:$mask),
9065             !strconcat(OpcodeStr,
9066               "\t{$mask, $src2, $dst|$dst, $src2, $mask}"),
9067             []>, VEX_4VOp3;
9068   def Yrm : AVX28I<opc, MRMSrcMem, (outs RC256:$dst, RC256:$mask_wb),
9069             (ins RC256:$src1, memop256:$src2, RC256:$mask),
9070             !strconcat(OpcodeStr,
9071               "\t{$mask, $src2, $dst|$dst, $src2, $mask}"),
9072             []>, VEX_4VOp3, VEX_L;
9073 }
9074
9075 let mayLoad = 1, Constraints
9076   = "@earlyclobber $dst,@earlyclobber $mask_wb, $src1 = $dst, $mask = $mask_wb"
9077   in {
9078   defm VPGATHERDQ : avx2_gather<0x90, "vpgatherdq", VR256, vx64mem, vx64mem>, VEX_W;
9079   defm VPGATHERQQ : avx2_gather<0x91, "vpgatherqq", VR256, vx64mem, vy64mem>, VEX_W;
9080   defm VPGATHERDD : avx2_gather<0x90, "vpgatherdd", VR256, vx32mem, vy32mem>;
9081   defm VPGATHERQD : avx2_gather<0x91, "vpgatherqd", VR128, vx32mem, vy32mem>;
9082
9083   let ExeDomain = SSEPackedDouble in {
9084     defm VGATHERDPD : avx2_gather<0x92, "vgatherdpd", VR256, vx64mem, vx64mem>, VEX_W;
9085     defm VGATHERQPD : avx2_gather<0x93, "vgatherqpd", VR256, vx64mem, vy64mem>, VEX_W;
9086   }
9087
9088   let ExeDomain = SSEPackedSingle in {
9089     defm VGATHERDPS : avx2_gather<0x92, "vgatherdps", VR256, vx32mem, vy32mem>;
9090     defm VGATHERQPS : avx2_gather<0x93, "vgatherqps", VR128, vx32mem, vy32mem>;
9091   }
9092 }