Mark all x86 Int_ and _Int patterns as isCodeGenOnly so the disassembler table builde...
[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 def SSE_BIT_ITINS_P : OpndItins<
124   IIC_SSE_BIT_P_RR, IIC_SSE_BIT_P_RM
125 >;
126
127 let Sched = WriteVecALU in {
128 def SSE_INTALU_ITINS_P : OpndItins<
129   IIC_SSE_INTALU_P_RR, IIC_SSE_INTALU_P_RM
130 >;
131
132 def SSE_INTALUQ_ITINS_P : OpndItins<
133   IIC_SSE_INTALUQ_P_RR, IIC_SSE_INTALUQ_P_RM
134 >;
135 }
136
137 let Sched = WriteVecIMul in
138 def SSE_INTMUL_ITINS_P : OpndItins<
139   IIC_SSE_INTMUL_P_RR, IIC_SSE_INTMUL_P_RM
140 >;
141
142 def SSE_INTSHIFT_ITINS_P : ShiftOpndItins<
143   IIC_SSE_INTSH_P_RR, IIC_SSE_INTSH_P_RM, IIC_SSE_INTSH_P_RI
144 >;
145
146 def SSE_MOVA_ITINS : OpndItins<
147   IIC_SSE_MOVA_P_RR, IIC_SSE_MOVA_P_RM
148 >;
149
150 def SSE_MOVU_ITINS : OpndItins<
151   IIC_SSE_MOVU_P_RR, IIC_SSE_MOVU_P_RM
152 >;
153
154 def SSE_DPPD_ITINS : OpndItins<
155   IIC_SSE_DPPD_RR, IIC_SSE_DPPD_RM
156 >;
157
158 def SSE_DPPS_ITINS : OpndItins<
159   IIC_SSE_DPPS_RR, IIC_SSE_DPPD_RM
160 >;
161
162 def DEFAULT_ITINS : OpndItins<
163   IIC_ALU_NONMEM, IIC_ALU_MEM
164 >;
165
166 def SSE_EXTRACT_ITINS : OpndItins<
167   IIC_SSE_EXTRACTPS_RR, IIC_SSE_EXTRACTPS_RM
168 >;
169
170 def SSE_INSERT_ITINS : OpndItins<
171   IIC_SSE_INSERTPS_RR, IIC_SSE_INSERTPS_RM
172 >;
173
174 def SSE_MPSADBW_ITINS : OpndItins<
175   IIC_SSE_MPSADBW_RR, IIC_SSE_MPSADBW_RM
176 >;
177
178 def SSE_PMULLD_ITINS : OpndItins<
179   IIC_SSE_PMULLD_RR, IIC_SSE_PMULLD_RM
180 >;
181
182 //===----------------------------------------------------------------------===//
183 // SSE 1 & 2 Instructions Classes
184 //===----------------------------------------------------------------------===//
185
186 /// sse12_fp_scalar - SSE 1 & 2 scalar instructions class
187 multiclass sse12_fp_scalar<bits<8> opc, string OpcodeStr, SDNode OpNode,
188                            RegisterClass RC, X86MemOperand x86memop,
189                            OpndItins itins,
190                            bit Is2Addr = 1> {
191   let isCommutable = 1 in {
192     def rr : SI<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
193        !if(Is2Addr,
194            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
195            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
196        [(set RC:$dst, (OpNode RC:$src1, RC:$src2))], itins.rr>,
197        Sched<[itins.Sched]>;
198   }
199   def rm : SI<opc, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
200        !if(Is2Addr,
201            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
202            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
203        [(set RC:$dst, (OpNode RC:$src1, (load addr:$src2)))], itins.rm>,
204        Sched<[itins.Sched.Folded, ReadAfterLd]>;
205 }
206
207 /// sse12_fp_scalar_int - SSE 1 & 2 scalar instructions intrinsics class
208 multiclass sse12_fp_scalar_int<bits<8> opc, string OpcodeStr, RegisterClass RC,
209                              string asm, string SSEVer, string FPSizeStr,
210                              Operand memopr, ComplexPattern mem_cpat,
211                              OpndItins itins,
212                              bit Is2Addr = 1> {
213 let isCodeGenOnly = 1 in {
214   def rr_Int : SI<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
215        !if(Is2Addr,
216            !strconcat(asm, "\t{$src2, $dst|$dst, $src2}"),
217            !strconcat(asm, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
218        [(set RC:$dst, (!cast<Intrinsic>(
219                  !strconcat("int_x86_sse", SSEVer, "_", OpcodeStr, FPSizeStr))
220              RC:$src1, RC:$src2))], itins.rr>,
221        Sched<[itins.Sched]>;
222   def rm_Int : SI<opc, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, memopr:$src2),
223        !if(Is2Addr,
224            !strconcat(asm, "\t{$src2, $dst|$dst, $src2}"),
225            !strconcat(asm, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
226        [(set RC:$dst, (!cast<Intrinsic>(!strconcat("int_x86_sse",
227                                           SSEVer, "_", OpcodeStr, FPSizeStr))
228              RC:$src1, mem_cpat:$src2))], itins.rm>,
229        Sched<[itins.Sched.Folded, ReadAfterLd]>;
230 }
231 }
232
233 /// sse12_fp_packed - SSE 1 & 2 packed instructions class
234 multiclass sse12_fp_packed<bits<8> opc, string OpcodeStr, SDNode OpNode,
235                            RegisterClass RC, ValueType vt,
236                            X86MemOperand x86memop, PatFrag mem_frag,
237                            Domain d, OpndItins itins, bit Is2Addr = 1> {
238   let isCommutable = 1 in
239     def rr : PI<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
240        !if(Is2Addr,
241            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
242            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
243        [(set RC:$dst, (vt (OpNode RC:$src1, RC:$src2)))], itins.rr, d>,
244        Sched<[itins.Sched]>;
245   let mayLoad = 1 in
246     def rm : PI<opc, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
247        !if(Is2Addr,
248            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
249            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
250        [(set RC:$dst, (OpNode RC:$src1, (mem_frag addr:$src2)))],
251           itins.rm, d>,
252        Sched<[itins.Sched.Folded, ReadAfterLd]>;
253 }
254
255 /// sse12_fp_packed_logical_rm - SSE 1 & 2 packed instructions class
256 multiclass sse12_fp_packed_logical_rm<bits<8> opc, RegisterClass RC, Domain d,
257                                       string OpcodeStr, X86MemOperand x86memop,
258                                       list<dag> pat_rr, list<dag> pat_rm,
259                                       bit Is2Addr = 1> {
260   let isCommutable = 1, hasSideEffects = 0 in
261     def rr : PI<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
262        !if(Is2Addr,
263            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
264            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
265        pat_rr, NoItinerary, d>,
266        Sched<[WriteVecLogic]>;
267   def rm : PI<opc, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
268        !if(Is2Addr,
269            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
270            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
271        pat_rm, NoItinerary, d>,
272        Sched<[WriteVecLogicLd, ReadAfterLd]>;
273 }
274
275 //===----------------------------------------------------------------------===//
276 //  Non-instruction patterns
277 //===----------------------------------------------------------------------===//
278
279 // A vector extract of the first f32/f64 position is a subregister copy
280 def : Pat<(f32 (vector_extract (v4f32 VR128:$src), (iPTR 0))),
281           (COPY_TO_REGCLASS (v4f32 VR128:$src), FR32)>;
282 def : Pat<(f64 (vector_extract (v2f64 VR128:$src), (iPTR 0))),
283           (COPY_TO_REGCLASS (v2f64 VR128:$src), FR64)>;
284
285 // A 128-bit subvector extract from the first 256-bit vector position
286 // is a subregister copy that needs no instruction.
287 def : Pat<(v4i32 (extract_subvector (v8i32 VR256:$src), (iPTR 0))),
288           (v4i32 (EXTRACT_SUBREG (v8i32 VR256:$src), sub_xmm))>;
289 def : Pat<(v4f32 (extract_subvector (v8f32 VR256:$src), (iPTR 0))),
290           (v4f32 (EXTRACT_SUBREG (v8f32 VR256:$src), sub_xmm))>;
291
292 def : Pat<(v2i64 (extract_subvector (v4i64 VR256:$src), (iPTR 0))),
293           (v2i64 (EXTRACT_SUBREG (v4i64 VR256:$src), sub_xmm))>;
294 def : Pat<(v2f64 (extract_subvector (v4f64 VR256:$src), (iPTR 0))),
295           (v2f64 (EXTRACT_SUBREG (v4f64 VR256:$src), sub_xmm))>;
296
297 def : Pat<(v8i16 (extract_subvector (v16i16 VR256:$src), (iPTR 0))),
298           (v8i16 (EXTRACT_SUBREG (v16i16 VR256:$src), sub_xmm))>;
299 def : Pat<(v16i8 (extract_subvector (v32i8 VR256:$src), (iPTR 0))),
300           (v16i8 (EXTRACT_SUBREG (v32i8 VR256:$src), sub_xmm))>;
301
302 // A 128-bit subvector insert to the first 256-bit vector position
303 // is a subregister copy that needs no instruction.
304 let AddedComplexity = 25 in { // to give priority over vinsertf128rm
305 def : Pat<(insert_subvector undef, (v2i64 VR128:$src), (iPTR 0)),
306           (INSERT_SUBREG (v4i64 (IMPLICIT_DEF)), VR128:$src, sub_xmm)>;
307 def : Pat<(insert_subvector undef, (v2f64 VR128:$src), (iPTR 0)),
308           (INSERT_SUBREG (v4f64 (IMPLICIT_DEF)), VR128:$src, sub_xmm)>;
309 def : Pat<(insert_subvector undef, (v4i32 VR128:$src), (iPTR 0)),
310           (INSERT_SUBREG (v8i32 (IMPLICIT_DEF)), VR128:$src, sub_xmm)>;
311 def : Pat<(insert_subvector undef, (v4f32 VR128:$src), (iPTR 0)),
312           (INSERT_SUBREG (v8f32 (IMPLICIT_DEF)), VR128:$src, sub_xmm)>;
313 def : Pat<(insert_subvector undef, (v8i16 VR128:$src), (iPTR 0)),
314           (INSERT_SUBREG (v16i16 (IMPLICIT_DEF)), VR128:$src, sub_xmm)>;
315 def : Pat<(insert_subvector undef, (v16i8 VR128:$src), (iPTR 0)),
316           (INSERT_SUBREG (v32i8 (IMPLICIT_DEF)), VR128:$src, sub_xmm)>;
317 }
318
319 // Implicitly promote a 32-bit scalar to a vector.
320 def : Pat<(v4f32 (scalar_to_vector FR32:$src)),
321           (COPY_TO_REGCLASS FR32:$src, VR128)>;
322 def : Pat<(v8f32 (scalar_to_vector FR32:$src)),
323           (COPY_TO_REGCLASS FR32:$src, VR128)>;
324 // Implicitly promote a 64-bit scalar to a vector.
325 def : Pat<(v2f64 (scalar_to_vector FR64:$src)),
326           (COPY_TO_REGCLASS FR64:$src, VR128)>;
327 def : Pat<(v4f64 (scalar_to_vector FR64:$src)),
328           (COPY_TO_REGCLASS FR64:$src, VR128)>;
329
330 // Bitcasts between 128-bit vector types. Return the original type since
331 // no instruction is needed for the conversion
332 let Predicates = [HasSSE2] in {
333   def : Pat<(v2i64 (bitconvert (v4i32 VR128:$src))), (v2i64 VR128:$src)>;
334   def : Pat<(v2i64 (bitconvert (v8i16 VR128:$src))), (v2i64 VR128:$src)>;
335   def : Pat<(v2i64 (bitconvert (v16i8 VR128:$src))), (v2i64 VR128:$src)>;
336   def : Pat<(v2i64 (bitconvert (v2f64 VR128:$src))), (v2i64 VR128:$src)>;
337   def : Pat<(v2i64 (bitconvert (v4f32 VR128:$src))), (v2i64 VR128:$src)>;
338   def : Pat<(v4i32 (bitconvert (v2i64 VR128:$src))), (v4i32 VR128:$src)>;
339   def : Pat<(v4i32 (bitconvert (v8i16 VR128:$src))), (v4i32 VR128:$src)>;
340   def : Pat<(v4i32 (bitconvert (v16i8 VR128:$src))), (v4i32 VR128:$src)>;
341   def : Pat<(v4i32 (bitconvert (v2f64 VR128:$src))), (v4i32 VR128:$src)>;
342   def : Pat<(v4i32 (bitconvert (v4f32 VR128:$src))), (v4i32 VR128:$src)>;
343   def : Pat<(v8i16 (bitconvert (v2i64 VR128:$src))), (v8i16 VR128:$src)>;
344   def : Pat<(v8i16 (bitconvert (v4i32 VR128:$src))), (v8i16 VR128:$src)>;
345   def : Pat<(v8i16 (bitconvert (v16i8 VR128:$src))), (v8i16 VR128:$src)>;
346   def : Pat<(v8i16 (bitconvert (v2f64 VR128:$src))), (v8i16 VR128:$src)>;
347   def : Pat<(v8i16 (bitconvert (v4f32 VR128:$src))), (v8i16 VR128:$src)>;
348   def : Pat<(v16i8 (bitconvert (v2i64 VR128:$src))), (v16i8 VR128:$src)>;
349   def : Pat<(v16i8 (bitconvert (v4i32 VR128:$src))), (v16i8 VR128:$src)>;
350   def : Pat<(v16i8 (bitconvert (v8i16 VR128:$src))), (v16i8 VR128:$src)>;
351   def : Pat<(v16i8 (bitconvert (v2f64 VR128:$src))), (v16i8 VR128:$src)>;
352   def : Pat<(v16i8 (bitconvert (v4f32 VR128:$src))), (v16i8 VR128:$src)>;
353   def : Pat<(v4f32 (bitconvert (v2i64 VR128:$src))), (v4f32 VR128:$src)>;
354   def : Pat<(v4f32 (bitconvert (v4i32 VR128:$src))), (v4f32 VR128:$src)>;
355   def : Pat<(v4f32 (bitconvert (v8i16 VR128:$src))), (v4f32 VR128:$src)>;
356   def : Pat<(v4f32 (bitconvert (v16i8 VR128:$src))), (v4f32 VR128:$src)>;
357   def : Pat<(v4f32 (bitconvert (v2f64 VR128:$src))), (v4f32 VR128:$src)>;
358   def : Pat<(v2f64 (bitconvert (v2i64 VR128:$src))), (v2f64 VR128:$src)>;
359   def : Pat<(v2f64 (bitconvert (v4i32 VR128:$src))), (v2f64 VR128:$src)>;
360   def : Pat<(v2f64 (bitconvert (v8i16 VR128:$src))), (v2f64 VR128:$src)>;
361   def : Pat<(v2f64 (bitconvert (v16i8 VR128:$src))), (v2f64 VR128:$src)>;
362   def : Pat<(v2f64 (bitconvert (v4f32 VR128:$src))), (v2f64 VR128:$src)>;
363 }
364
365 // Bitcasts between 256-bit vector types. Return the original type since
366 // no instruction is needed for the conversion
367 let Predicates = [HasAVX] in {
368   def : Pat<(v4f64  (bitconvert (v8f32 VR256:$src))),  (v4f64 VR256:$src)>;
369   def : Pat<(v4f64  (bitconvert (v8i32 VR256:$src))),  (v4f64 VR256:$src)>;
370   def : Pat<(v4f64  (bitconvert (v4i64 VR256:$src))),  (v4f64 VR256:$src)>;
371   def : Pat<(v4f64  (bitconvert (v16i16 VR256:$src))), (v4f64 VR256:$src)>;
372   def : Pat<(v4f64  (bitconvert (v32i8 VR256:$src))),  (v4f64 VR256:$src)>;
373   def : Pat<(v8f32  (bitconvert (v8i32 VR256:$src))),  (v8f32 VR256:$src)>;
374   def : Pat<(v8f32  (bitconvert (v4i64 VR256:$src))),  (v8f32 VR256:$src)>;
375   def : Pat<(v8f32  (bitconvert (v4f64 VR256:$src))),  (v8f32 VR256:$src)>;
376   def : Pat<(v8f32  (bitconvert (v32i8 VR256:$src))),  (v8f32 VR256:$src)>;
377   def : Pat<(v8f32  (bitconvert (v16i16 VR256:$src))), (v8f32 VR256:$src)>;
378   def : Pat<(v4i64  (bitconvert (v8f32 VR256:$src))),  (v4i64 VR256:$src)>;
379   def : Pat<(v4i64  (bitconvert (v8i32 VR256:$src))),  (v4i64 VR256:$src)>;
380   def : Pat<(v4i64  (bitconvert (v4f64 VR256:$src))),  (v4i64 VR256:$src)>;
381   def : Pat<(v4i64  (bitconvert (v32i8 VR256:$src))),  (v4i64 VR256:$src)>;
382   def : Pat<(v4i64  (bitconvert (v16i16 VR256:$src))), (v4i64 VR256:$src)>;
383   def : Pat<(v32i8  (bitconvert (v4f64 VR256:$src))),  (v32i8 VR256:$src)>;
384   def : Pat<(v32i8  (bitconvert (v4i64 VR256:$src))),  (v32i8 VR256:$src)>;
385   def : Pat<(v32i8  (bitconvert (v8f32 VR256:$src))),  (v32i8 VR256:$src)>;
386   def : Pat<(v32i8  (bitconvert (v8i32 VR256:$src))),  (v32i8 VR256:$src)>;
387   def : Pat<(v32i8  (bitconvert (v16i16 VR256:$src))), (v32i8 VR256:$src)>;
388   def : Pat<(v8i32  (bitconvert (v32i8 VR256:$src))),  (v8i32 VR256:$src)>;
389   def : Pat<(v8i32  (bitconvert (v16i16 VR256:$src))), (v8i32 VR256:$src)>;
390   def : Pat<(v8i32  (bitconvert (v8f32 VR256:$src))),  (v8i32 VR256:$src)>;
391   def : Pat<(v8i32  (bitconvert (v4i64 VR256:$src))),  (v8i32 VR256:$src)>;
392   def : Pat<(v8i32  (bitconvert (v4f64 VR256:$src))),  (v8i32 VR256:$src)>;
393   def : Pat<(v16i16 (bitconvert (v8f32 VR256:$src))),  (v16i16 VR256:$src)>;
394   def : Pat<(v16i16 (bitconvert (v8i32 VR256:$src))),  (v16i16 VR256:$src)>;
395   def : Pat<(v16i16 (bitconvert (v4i64 VR256:$src))),  (v16i16 VR256:$src)>;
396   def : Pat<(v16i16 (bitconvert (v4f64 VR256:$src))),  (v16i16 VR256:$src)>;
397   def : Pat<(v16i16 (bitconvert (v32i8 VR256:$src))),  (v16i16 VR256:$src)>;
398 }
399
400 // Alias instructions that map fld0 to xorps for sse or vxorps for avx.
401 // This is expanded by ExpandPostRAPseudos.
402 let isReMaterializable = 1, isAsCheapAsAMove = 1, canFoldAsLoad = 1,
403     isPseudo = 1, SchedRW = [WriteZero] in {
404   def FsFLD0SS : I<0, Pseudo, (outs FR32:$dst), (ins), "",
405                    [(set FR32:$dst, fp32imm0)]>, Requires<[HasSSE1]>;
406   def FsFLD0SD : I<0, Pseudo, (outs FR64:$dst), (ins), "",
407                    [(set FR64:$dst, fpimm0)]>, Requires<[HasSSE2]>;
408 }
409
410 //===----------------------------------------------------------------------===//
411 // AVX & SSE - Zero/One Vectors
412 //===----------------------------------------------------------------------===//
413
414 // Alias instruction that maps zero vector to pxor / xorp* for sse.
415 // This is expanded by ExpandPostRAPseudos to an xorps / vxorps, and then
416 // swizzled by ExecutionDepsFix to pxor.
417 // We set canFoldAsLoad because this can be converted to a constant-pool
418 // load of an all-zeros value if folding it would be beneficial.
419 let isReMaterializable = 1, isAsCheapAsAMove = 1, canFoldAsLoad = 1,
420     isPseudo = 1, SchedRW = [WriteZero] in {
421 def V_SET0 : I<0, Pseudo, (outs VR128:$dst), (ins), "",
422                [(set VR128:$dst, (v4f32 immAllZerosV))]>;
423 }
424
425 def : Pat<(v2f64 immAllZerosV), (V_SET0)>;
426 def : Pat<(v4i32 immAllZerosV), (V_SET0)>;
427 def : Pat<(v2i64 immAllZerosV), (V_SET0)>;
428 def : Pat<(v8i16 immAllZerosV), (V_SET0)>;
429 def : Pat<(v16i8 immAllZerosV), (V_SET0)>;
430
431
432 // The same as done above but for AVX.  The 256-bit AVX1 ISA doesn't support PI,
433 // and doesn't need it because on sandy bridge the register is set to zero
434 // at the rename stage without using any execution unit, so SET0PSY
435 // and SET0PDY can be used for vector int instructions without penalty
436 let isReMaterializable = 1, isAsCheapAsAMove = 1, canFoldAsLoad = 1,
437     isPseudo = 1, Predicates = [HasAVX], SchedRW = [WriteZero] in {
438 def AVX_SET0 : I<0, Pseudo, (outs VR256:$dst), (ins), "",
439                  [(set VR256:$dst, (v8f32 immAllZerosV))]>;
440 }
441
442 let Predicates = [HasAVX] in
443   def : Pat<(v4f64 immAllZerosV), (AVX_SET0)>;
444
445 let Predicates = [HasAVX2] in {
446   def : Pat<(v4i64 immAllZerosV), (AVX_SET0)>;
447   def : Pat<(v8i32 immAllZerosV), (AVX_SET0)>;
448   def : Pat<(v16i16 immAllZerosV), (AVX_SET0)>;
449   def : Pat<(v32i8 immAllZerosV), (AVX_SET0)>;
450 }
451
452 // AVX1 has no support for 256-bit integer instructions, but since the 128-bit
453 // VPXOR instruction writes zero to its upper part, it's safe build zeros.
454 let Predicates = [HasAVX1Only] in {
455 def : Pat<(v32i8 immAllZerosV), (SUBREG_TO_REG (i8 0), (V_SET0), sub_xmm)>;
456 def : Pat<(bc_v32i8 (v8f32 immAllZerosV)),
457           (SUBREG_TO_REG (i8 0), (V_SET0), sub_xmm)>;
458
459 def : Pat<(v16i16 immAllZerosV), (SUBREG_TO_REG (i16 0), (V_SET0), sub_xmm)>;
460 def : Pat<(bc_v16i16 (v8f32 immAllZerosV)),
461           (SUBREG_TO_REG (i16 0), (V_SET0), sub_xmm)>;
462
463 def : Pat<(v8i32 immAllZerosV), (SUBREG_TO_REG (i32 0), (V_SET0), sub_xmm)>;
464 def : Pat<(bc_v8i32 (v8f32 immAllZerosV)),
465           (SUBREG_TO_REG (i32 0), (V_SET0), sub_xmm)>;
466
467 def : Pat<(v4i64 immAllZerosV), (SUBREG_TO_REG (i64 0), (V_SET0), sub_xmm)>;
468 def : Pat<(bc_v4i64 (v8f32 immAllZerosV)),
469           (SUBREG_TO_REG (i64 0), (V_SET0), sub_xmm)>;
470 }
471
472 // We set canFoldAsLoad because this can be converted to a constant-pool
473 // load of an all-ones value if folding it would be beneficial.
474 let isReMaterializable = 1, isAsCheapAsAMove = 1, canFoldAsLoad = 1,
475     isPseudo = 1, SchedRW = [WriteZero] in {
476   def V_SETALLONES : I<0, Pseudo, (outs VR128:$dst), (ins), "",
477                        [(set VR128:$dst, (v4i32 immAllOnesV))]>;
478   let Predicates = [HasAVX2] in
479   def AVX2_SETALLONES : I<0, Pseudo, (outs VR256:$dst), (ins), "",
480                           [(set VR256:$dst, (v8i32 immAllOnesV))]>;
481 }
482
483
484 //===----------------------------------------------------------------------===//
485 // SSE 1 & 2 - Move FP Scalar Instructions
486 //
487 // Move Instructions. Register-to-register movss/movsd is not used for FR32/64
488 // register copies because it's a partial register update; Register-to-register
489 // movss/movsd is not modeled as an INSERT_SUBREG because INSERT_SUBREG requires
490 // that the insert be implementable in terms of a copy, and just mentioned, we
491 // don't use movss/movsd for copies.
492 //===----------------------------------------------------------------------===//
493
494 multiclass sse12_move_rr<RegisterClass RC, SDNode OpNode, ValueType vt,
495                          X86MemOperand x86memop, string base_opc,
496                          string asm_opr> {
497   def rr : SI<0x10, MRMSrcReg, (outs VR128:$dst),
498               (ins VR128:$src1, RC:$src2),
499               !strconcat(base_opc, asm_opr),
500               [(set VR128:$dst, (vt (OpNode VR128:$src1,
501                                  (scalar_to_vector RC:$src2))))],
502               IIC_SSE_MOV_S_RR>, Sched<[WriteMove]>;
503
504   // For the disassembler
505   let isCodeGenOnly = 1, hasSideEffects = 0 in
506   def rr_REV : SI<0x11, MRMDestReg, (outs VR128:$dst),
507                   (ins VR128:$src1, RC:$src2),
508                   !strconcat(base_opc, asm_opr),
509                   [], IIC_SSE_MOV_S_RR>, Sched<[WriteMove]>;
510 }
511
512 multiclass sse12_move<RegisterClass RC, SDNode OpNode, ValueType vt,
513                       X86MemOperand x86memop, string OpcodeStr> {
514   // AVX
515   defm V#NAME : sse12_move_rr<RC, OpNode, vt, x86memop, OpcodeStr,
516                               "\t{$src2, $src1, $dst|$dst, $src1, $src2}">,
517                               VEX_4V, VEX_LIG;
518
519   def V#NAME#mr : SI<0x11, MRMDestMem, (outs), (ins x86memop:$dst, RC:$src),
520                      !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
521                      [(store RC:$src, addr:$dst)], IIC_SSE_MOV_S_MR>,
522                      VEX, VEX_LIG, Sched<[WriteStore]>;
523   // SSE1 & 2
524   let Constraints = "$src1 = $dst" in {
525     defm NAME : sse12_move_rr<RC, OpNode, vt, x86memop, OpcodeStr,
526                               "\t{$src2, $dst|$dst, $src2}">;
527   }
528
529   def NAME#mr   : SI<0x11, MRMDestMem, (outs), (ins x86memop:$dst, RC:$src),
530                      !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
531                      [(store RC:$src, addr:$dst)], IIC_SSE_MOV_S_MR>,
532                   Sched<[WriteStore]>;
533 }
534
535 // Loading from memory automatically zeroing upper bits.
536 multiclass sse12_move_rm<RegisterClass RC, X86MemOperand x86memop,
537                          PatFrag mem_pat, string OpcodeStr> {
538   def V#NAME#rm : SI<0x10, MRMSrcMem, (outs RC:$dst), (ins x86memop:$src),
539                      !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
540                      [(set RC:$dst, (mem_pat addr:$src))],
541                      IIC_SSE_MOV_S_RM>, VEX, VEX_LIG, Sched<[WriteLoad]>;
542   def NAME#rm   : SI<0x10, MRMSrcMem, (outs RC:$dst), (ins x86memop:$src),
543                      !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
544                      [(set RC:$dst, (mem_pat addr:$src))],
545                      IIC_SSE_MOV_S_RM>, Sched<[WriteLoad]>;
546 }
547
548 defm MOVSS : sse12_move<FR32, X86Movss, v4f32, f32mem, "movss">, XS;
549 defm MOVSD : sse12_move<FR64, X86Movsd, v2f64, f64mem, "movsd">, XD;
550
551 let canFoldAsLoad = 1, isReMaterializable = 1 in {
552   defm MOVSS : sse12_move_rm<FR32, f32mem, loadf32, "movss">, XS;
553
554   let AddedComplexity = 20 in
555     defm MOVSD : sse12_move_rm<FR64, f64mem, loadf64, "movsd">, XD;
556 }
557
558 // Patterns
559 let Predicates = [UseAVX] in {
560   let AddedComplexity = 15 in {
561   // Move scalar to XMM zero-extended, zeroing a VR128 then do a
562   // MOVS{S,D} to the lower bits.
563   def : Pat<(v4f32 (X86vzmovl (v4f32 (scalar_to_vector FR32:$src)))),
564             (VMOVSSrr (v4f32 (V_SET0)), FR32:$src)>;
565   def : Pat<(v4f32 (X86vzmovl (v4f32 VR128:$src))),
566             (VMOVSSrr (v4f32 (V_SET0)), (COPY_TO_REGCLASS VR128:$src, FR32))>;
567   def : Pat<(v4i32 (X86vzmovl (v4i32 VR128:$src))),
568             (VMOVSSrr (v4i32 (V_SET0)), (COPY_TO_REGCLASS VR128:$src, FR32))>;
569   def : Pat<(v2f64 (X86vzmovl (v2f64 (scalar_to_vector FR64:$src)))),
570             (VMOVSDrr (v2f64 (V_SET0)), FR64:$src)>;
571
572   // Move low f32 and clear high bits.
573   def : Pat<(v8f32 (X86vzmovl (v8f32 VR256:$src))),
574             (SUBREG_TO_REG (i32 0),
575              (VMOVSSrr (v4f32 (V_SET0)),
576                        (EXTRACT_SUBREG (v8f32 VR256:$src), sub_xmm)), sub_xmm)>;
577   def : Pat<(v8i32 (X86vzmovl (v8i32 VR256:$src))),
578             (SUBREG_TO_REG (i32 0),
579              (VMOVSSrr (v4i32 (V_SET0)),
580                        (EXTRACT_SUBREG (v8i32 VR256:$src), sub_xmm)), sub_xmm)>;
581   }
582
583   let AddedComplexity = 20 in {
584   // MOVSSrm zeros the high parts of the register; represent this
585   // with SUBREG_TO_REG. The AVX versions also write: DST[255:128] <- 0
586   def : Pat<(v4f32 (X86vzmovl (v4f32 (scalar_to_vector (loadf32 addr:$src))))),
587             (COPY_TO_REGCLASS (VMOVSSrm addr:$src), VR128)>;
588   def : Pat<(v4f32 (scalar_to_vector (loadf32 addr:$src))),
589             (COPY_TO_REGCLASS (VMOVSSrm addr:$src), VR128)>;
590   def : Pat<(v4f32 (X86vzmovl (loadv4f32 addr:$src))),
591             (COPY_TO_REGCLASS (VMOVSSrm addr:$src), VR128)>;
592
593   // MOVSDrm zeros the high parts of the register; represent this
594   // with SUBREG_TO_REG. The AVX versions also write: DST[255:128] <- 0
595   def : Pat<(v2f64 (X86vzmovl (v2f64 (scalar_to_vector (loadf64 addr:$src))))),
596             (COPY_TO_REGCLASS (VMOVSDrm addr:$src), VR128)>;
597   def : Pat<(v2f64 (scalar_to_vector (loadf64 addr:$src))),
598             (COPY_TO_REGCLASS (VMOVSDrm addr:$src), VR128)>;
599   def : Pat<(v2f64 (X86vzmovl (loadv2f64 addr:$src))),
600             (COPY_TO_REGCLASS (VMOVSDrm addr:$src), VR128)>;
601   def : Pat<(v2f64 (X86vzmovl (bc_v2f64 (loadv4f32 addr:$src)))),
602             (COPY_TO_REGCLASS (VMOVSDrm addr:$src), VR128)>;
603   def : Pat<(v2f64 (X86vzload addr:$src)),
604             (COPY_TO_REGCLASS (VMOVSDrm addr:$src), VR128)>;
605
606   // Represent the same patterns above but in the form they appear for
607   // 256-bit types
608   def : Pat<(v8i32 (X86vzmovl (insert_subvector undef,
609                    (v4i32 (scalar_to_vector (loadi32 addr:$src))), (iPTR 0)))),
610             (SUBREG_TO_REG (i32 0), (VMOVSSrm addr:$src), sub_xmm)>;
611   def : Pat<(v8f32 (X86vzmovl (insert_subvector undef,
612                    (v4f32 (scalar_to_vector (loadf32 addr:$src))), (iPTR 0)))),
613             (SUBREG_TO_REG (i32 0), (VMOVSSrm addr:$src), sub_xmm)>;
614   def : Pat<(v4f64 (X86vzmovl (insert_subvector undef,
615                    (v2f64 (scalar_to_vector (loadf64 addr:$src))), (iPTR 0)))),
616             (SUBREG_TO_REG (i32 0), (VMOVSDrm addr:$src), sub_xmm)>;
617   }
618   def : Pat<(v8f32 (X86vzmovl (insert_subvector undef,
619                    (v4f32 (scalar_to_vector FR32:$src)), (iPTR 0)))),
620             (SUBREG_TO_REG (i32 0),
621                            (v4f32 (VMOVSSrr (v4f32 (V_SET0)), FR32:$src)),
622                            sub_xmm)>;
623   def : Pat<(v4f64 (X86vzmovl (insert_subvector undef,
624                    (v2f64 (scalar_to_vector FR64:$src)), (iPTR 0)))),
625             (SUBREG_TO_REG (i64 0),
626                            (v2f64 (VMOVSDrr (v2f64 (V_SET0)), FR64:$src)),
627                            sub_xmm)>;
628   def : Pat<(v4i64 (X86vzmovl (insert_subvector undef,
629                    (v2i64 (scalar_to_vector (loadi64 addr:$src))), (iPTR 0)))),
630             (SUBREG_TO_REG (i64 0), (VMOVSDrm addr:$src), sub_xmm)>;
631
632   // Move low f64 and clear high bits.
633   def : Pat<(v4f64 (X86vzmovl (v4f64 VR256:$src))),
634             (SUBREG_TO_REG (i32 0),
635              (VMOVSDrr (v2f64 (V_SET0)),
636                        (EXTRACT_SUBREG (v4f64 VR256:$src), sub_xmm)), sub_xmm)>;
637
638   def : Pat<(v4i64 (X86vzmovl (v4i64 VR256:$src))),
639             (SUBREG_TO_REG (i32 0),
640              (VMOVSDrr (v2i64 (V_SET0)),
641                        (EXTRACT_SUBREG (v4i64 VR256:$src), sub_xmm)), sub_xmm)>;
642
643   // Extract and store.
644   def : Pat<(store (f32 (vector_extract (v4f32 VR128:$src), (iPTR 0))),
645                    addr:$dst),
646             (VMOVSSmr addr:$dst, (COPY_TO_REGCLASS (v4f32 VR128:$src), FR32))>;
647   def : Pat<(store (f64 (vector_extract (v2f64 VR128:$src), (iPTR 0))),
648                    addr:$dst),
649             (VMOVSDmr addr:$dst, (COPY_TO_REGCLASS (v2f64 VR128:$src), FR64))>;
650
651   // Shuffle with VMOVSS
652   def : Pat<(v4i32 (X86Movss VR128:$src1, VR128:$src2)),
653             (VMOVSSrr (v4i32 VR128:$src1),
654                       (COPY_TO_REGCLASS (v4i32 VR128:$src2), FR32))>;
655   def : Pat<(v4f32 (X86Movss VR128:$src1, VR128:$src2)),
656             (VMOVSSrr (v4f32 VR128:$src1),
657                       (COPY_TO_REGCLASS (v4f32 VR128:$src2), FR32))>;
658
659   // 256-bit variants
660   def : Pat<(v8i32 (X86Movss VR256:$src1, VR256:$src2)),
661             (SUBREG_TO_REG (i32 0),
662               (VMOVSSrr (EXTRACT_SUBREG (v8i32 VR256:$src1), sub_xmm),
663                         (EXTRACT_SUBREG (v8i32 VR256:$src2), sub_xmm)),
664               sub_xmm)>;
665   def : Pat<(v8f32 (X86Movss VR256:$src1, VR256:$src2)),
666             (SUBREG_TO_REG (i32 0),
667               (VMOVSSrr (EXTRACT_SUBREG (v8f32 VR256:$src1), sub_xmm),
668                         (EXTRACT_SUBREG (v8f32 VR256:$src2), sub_xmm)),
669               sub_xmm)>;
670
671   // Shuffle with VMOVSD
672   def : Pat<(v2i64 (X86Movsd VR128:$src1, VR128:$src2)),
673             (VMOVSDrr VR128:$src1, (COPY_TO_REGCLASS VR128:$src2, FR64))>;
674   def : Pat<(v2f64 (X86Movsd VR128:$src1, VR128:$src2)),
675             (VMOVSDrr VR128:$src1, (COPY_TO_REGCLASS VR128:$src2, FR64))>;
676   def : Pat<(v4f32 (X86Movsd VR128:$src1, VR128:$src2)),
677             (VMOVSDrr VR128:$src1, (COPY_TO_REGCLASS VR128:$src2, FR64))>;
678   def : Pat<(v4i32 (X86Movsd VR128:$src1, VR128:$src2)),
679             (VMOVSDrr VR128:$src1, (COPY_TO_REGCLASS VR128:$src2, FR64))>;
680
681   // 256-bit variants
682   def : Pat<(v4i64 (X86Movsd VR256:$src1, VR256:$src2)),
683             (SUBREG_TO_REG (i32 0),
684               (VMOVSDrr (EXTRACT_SUBREG (v4i64 VR256:$src1), sub_xmm),
685                         (EXTRACT_SUBREG (v4i64 VR256:$src2), sub_xmm)),
686               sub_xmm)>;
687   def : Pat<(v4f64 (X86Movsd VR256:$src1, VR256:$src2)),
688             (SUBREG_TO_REG (i32 0),
689               (VMOVSDrr (EXTRACT_SUBREG (v4f64 VR256:$src1), sub_xmm),
690                         (EXTRACT_SUBREG (v4f64 VR256:$src2), sub_xmm)),
691               sub_xmm)>;
692
693
694   // FIXME: Instead of a X86Movlps there should be a X86Movsd here, the problem
695   // is during lowering, where it's not possible to recognize the fold cause
696   // it has two uses through a bitcast. One use disappears at isel time and the
697   // fold opportunity reappears.
698   def : Pat<(v2f64 (X86Movlpd VR128:$src1, VR128:$src2)),
699             (VMOVSDrr VR128:$src1, (COPY_TO_REGCLASS VR128:$src2, FR64))>;
700   def : Pat<(v2i64 (X86Movlpd VR128:$src1, VR128:$src2)),
701             (VMOVSDrr VR128:$src1, (COPY_TO_REGCLASS VR128:$src2, FR64))>;
702   def : Pat<(v4f32 (X86Movlps VR128:$src1, VR128:$src2)),
703             (VMOVSDrr VR128:$src1, (COPY_TO_REGCLASS VR128:$src2, FR64))>;
704   def : Pat<(v4i32 (X86Movlps VR128:$src1, VR128:$src2)),
705             (VMOVSDrr VR128:$src1, (COPY_TO_REGCLASS VR128:$src2, FR64))>;
706 }
707
708 let Predicates = [UseSSE1] in {
709   let AddedComplexity = 15 in {
710   // Move scalar to XMM zero-extended, zeroing a VR128 then do a
711   // MOVSS to the lower bits.
712   def : Pat<(v4f32 (X86vzmovl (v4f32 (scalar_to_vector FR32:$src)))),
713             (MOVSSrr (v4f32 (V_SET0)), FR32:$src)>;
714   def : Pat<(v4f32 (X86vzmovl (v4f32 VR128:$src))),
715             (MOVSSrr (v4f32 (V_SET0)), (COPY_TO_REGCLASS VR128:$src, FR32))>;
716   def : Pat<(v4i32 (X86vzmovl (v4i32 VR128:$src))),
717             (MOVSSrr (v4i32 (V_SET0)), (COPY_TO_REGCLASS VR128:$src, FR32))>;
718   }
719
720   let AddedComplexity = 20 in {
721   // MOVSSrm already zeros the high parts of the register.
722   def : Pat<(v4f32 (X86vzmovl (v4f32 (scalar_to_vector (loadf32 addr:$src))))),
723             (COPY_TO_REGCLASS (MOVSSrm addr:$src), VR128)>;
724   def : Pat<(v4f32 (scalar_to_vector (loadf32 addr:$src))),
725             (COPY_TO_REGCLASS (MOVSSrm addr:$src), VR128)>;
726   def : Pat<(v4f32 (X86vzmovl (loadv4f32 addr:$src))),
727             (COPY_TO_REGCLASS (MOVSSrm addr:$src), VR128)>;
728   }
729
730   // Extract and store.
731   def : Pat<(store (f32 (vector_extract (v4f32 VR128:$src), (iPTR 0))),
732                    addr:$dst),
733             (MOVSSmr addr:$dst, (COPY_TO_REGCLASS VR128:$src, FR32))>;
734
735   // Shuffle with MOVSS
736   def : Pat<(v4i32 (X86Movss VR128:$src1, VR128:$src2)),
737             (MOVSSrr VR128:$src1, (COPY_TO_REGCLASS VR128:$src2, FR32))>;
738   def : Pat<(v4f32 (X86Movss VR128:$src1, VR128:$src2)),
739             (MOVSSrr VR128:$src1, (COPY_TO_REGCLASS VR128:$src2, FR32))>;
740 }
741
742 let Predicates = [UseSSE2] in {
743   let AddedComplexity = 15 in {
744   // Move scalar to XMM zero-extended, zeroing a VR128 then do a
745   // MOVSD to the lower bits.
746   def : Pat<(v2f64 (X86vzmovl (v2f64 (scalar_to_vector FR64:$src)))),
747             (MOVSDrr (v2f64 (V_SET0)), FR64:$src)>;
748   }
749
750   let AddedComplexity = 20 in {
751   // MOVSDrm already zeros the high parts of the register.
752   def : Pat<(v2f64 (X86vzmovl (v2f64 (scalar_to_vector (loadf64 addr:$src))))),
753             (COPY_TO_REGCLASS (MOVSDrm addr:$src), VR128)>;
754   def : Pat<(v2f64 (scalar_to_vector (loadf64 addr:$src))),
755             (COPY_TO_REGCLASS (MOVSDrm addr:$src), VR128)>;
756   def : Pat<(v2f64 (X86vzmovl (loadv2f64 addr:$src))),
757             (COPY_TO_REGCLASS (MOVSDrm addr:$src), VR128)>;
758   def : Pat<(v2f64 (X86vzmovl (bc_v2f64 (loadv4f32 addr:$src)))),
759             (COPY_TO_REGCLASS (MOVSDrm addr:$src), VR128)>;
760   def : Pat<(v2f64 (X86vzload addr:$src)),
761             (COPY_TO_REGCLASS (MOVSDrm addr:$src), VR128)>;
762   }
763
764   // Extract and store.
765   def : Pat<(store (f64 (vector_extract (v2f64 VR128:$src), (iPTR 0))),
766                    addr:$dst),
767             (MOVSDmr addr:$dst, (COPY_TO_REGCLASS VR128:$src, FR64))>;
768
769   // Shuffle with MOVSD
770   def : Pat<(v2i64 (X86Movsd VR128:$src1, VR128:$src2)),
771             (MOVSDrr VR128:$src1, (COPY_TO_REGCLASS VR128:$src2, FR64))>;
772   def : Pat<(v2f64 (X86Movsd VR128:$src1, VR128:$src2)),
773             (MOVSDrr VR128:$src1, (COPY_TO_REGCLASS VR128:$src2, FR64))>;
774   def : Pat<(v4f32 (X86Movsd VR128:$src1, VR128:$src2)),
775             (MOVSDrr VR128:$src1, (COPY_TO_REGCLASS VR128:$src2, FR64))>;
776   def : Pat<(v4i32 (X86Movsd VR128:$src1, VR128:$src2)),
777             (MOVSDrr VR128:$src1, (COPY_TO_REGCLASS VR128:$src2, FR64))>;
778
779   // FIXME: Instead of a X86Movlps there should be a X86Movsd here, the problem
780   // is during lowering, where it's not possible to recognize the fold cause
781   // it has two uses through a bitcast. One use disappears at isel time and the
782   // fold opportunity reappears.
783   def : Pat<(v2f64 (X86Movlpd VR128:$src1, VR128:$src2)),
784             (MOVSDrr VR128:$src1, (COPY_TO_REGCLASS VR128:$src2, FR64))>;
785   def : Pat<(v2i64 (X86Movlpd VR128:$src1, VR128:$src2)),
786             (MOVSDrr VR128:$src1, (COPY_TO_REGCLASS VR128:$src2, FR64))>;
787   def : Pat<(v4f32 (X86Movlps VR128:$src1, VR128:$src2)),
788             (MOVSDrr VR128:$src1, (COPY_TO_REGCLASS VR128:$src2, FR64))>;
789   def : Pat<(v4i32 (X86Movlps VR128:$src1, VR128:$src2)),
790             (MOVSDrr VR128:$src1, (COPY_TO_REGCLASS VR128:$src2, FR64))>;
791 }
792
793 //===----------------------------------------------------------------------===//
794 // SSE 1 & 2 - Move Aligned/Unaligned FP Instructions
795 //===----------------------------------------------------------------------===//
796
797 multiclass sse12_mov_packed<bits<8> opc, RegisterClass RC,
798                             X86MemOperand x86memop, PatFrag ld_frag,
799                             string asm, Domain d,
800                             OpndItins itins,
801                             bit IsReMaterializable = 1> {
802 let neverHasSideEffects = 1 in
803   def rr : PI<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src),
804               !strconcat(asm, "\t{$src, $dst|$dst, $src}"), [], itins.rr, d>,
805            Sched<[WriteMove]>;
806 let canFoldAsLoad = 1, isReMaterializable = IsReMaterializable in
807   def rm : PI<opc, MRMSrcMem, (outs RC:$dst), (ins x86memop:$src),
808               !strconcat(asm, "\t{$src, $dst|$dst, $src}"),
809                    [(set RC:$dst, (ld_frag addr:$src))], itins.rm, d>,
810            Sched<[WriteLoad]>;
811 }
812
813 defm VMOVAPS : sse12_mov_packed<0x28, VR128, f128mem, alignedloadv4f32,
814                               "movaps", SSEPackedSingle, SSE_MOVA_ITINS>,
815                               TB, VEX;
816 defm VMOVAPD : sse12_mov_packed<0x28, VR128, f128mem, alignedloadv2f64,
817                               "movapd", SSEPackedDouble, SSE_MOVA_ITINS>,
818                               TB, OpSize, VEX;
819 defm VMOVUPS : sse12_mov_packed<0x10, VR128, f128mem, loadv4f32,
820                               "movups", SSEPackedSingle, SSE_MOVU_ITINS>,
821                               TB, VEX;
822 defm VMOVUPD : sse12_mov_packed<0x10, VR128, f128mem, loadv2f64,
823                               "movupd", SSEPackedDouble, SSE_MOVU_ITINS, 0>,
824                               TB, OpSize, VEX;
825
826 defm VMOVAPSY : sse12_mov_packed<0x28, VR256, f256mem, alignedloadv8f32,
827                               "movaps", SSEPackedSingle, SSE_MOVA_ITINS>,
828                               TB, VEX, VEX_L;
829 defm VMOVAPDY : sse12_mov_packed<0x28, VR256, f256mem, alignedloadv4f64,
830                               "movapd", SSEPackedDouble, SSE_MOVA_ITINS>,
831                               TB, OpSize, VEX, VEX_L;
832 defm VMOVUPSY : sse12_mov_packed<0x10, VR256, f256mem, loadv8f32,
833                               "movups", SSEPackedSingle, SSE_MOVU_ITINS>,
834                               TB, VEX, VEX_L;
835 defm VMOVUPDY : sse12_mov_packed<0x10, VR256, f256mem, loadv4f64,
836                               "movupd", SSEPackedDouble, SSE_MOVU_ITINS, 0>,
837                               TB, OpSize, VEX, VEX_L;
838 defm MOVAPS : sse12_mov_packed<0x28, VR128, f128mem, alignedloadv4f32,
839                               "movaps", SSEPackedSingle, SSE_MOVA_ITINS>,
840                               TB;
841 defm MOVAPD : sse12_mov_packed<0x28, VR128, f128mem, alignedloadv2f64,
842                               "movapd", SSEPackedDouble, SSE_MOVA_ITINS>,
843                               TB, OpSize;
844 defm MOVUPS : sse12_mov_packed<0x10, VR128, f128mem, loadv4f32,
845                               "movups", SSEPackedSingle, SSE_MOVU_ITINS>,
846                               TB;
847 defm MOVUPD : sse12_mov_packed<0x10, VR128, f128mem, loadv2f64,
848                               "movupd", SSEPackedDouble, SSE_MOVU_ITINS, 0>,
849                               TB, OpSize;
850
851 let SchedRW = [WriteStore] in {
852 def VMOVAPSmr : VPSI<0x29, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
853                    "movaps\t{$src, $dst|$dst, $src}",
854                    [(alignedstore (v4f32 VR128:$src), addr:$dst)],
855                    IIC_SSE_MOVA_P_MR>, VEX;
856 def VMOVAPDmr : VPDI<0x29, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
857                    "movapd\t{$src, $dst|$dst, $src}",
858                    [(alignedstore (v2f64 VR128:$src), addr:$dst)],
859                    IIC_SSE_MOVA_P_MR>, VEX;
860 def VMOVUPSmr : VPSI<0x11, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
861                    "movups\t{$src, $dst|$dst, $src}",
862                    [(store (v4f32 VR128:$src), addr:$dst)],
863                    IIC_SSE_MOVU_P_MR>, VEX;
864 def VMOVUPDmr : VPDI<0x11, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
865                    "movupd\t{$src, $dst|$dst, $src}",
866                    [(store (v2f64 VR128:$src), addr:$dst)],
867                    IIC_SSE_MOVU_P_MR>, VEX;
868 def VMOVAPSYmr : VPSI<0x29, MRMDestMem, (outs), (ins f256mem:$dst, VR256:$src),
869                    "movaps\t{$src, $dst|$dst, $src}",
870                    [(alignedstore256 (v8f32 VR256:$src), addr:$dst)],
871                    IIC_SSE_MOVA_P_MR>, VEX, VEX_L;
872 def VMOVAPDYmr : VPDI<0x29, MRMDestMem, (outs), (ins f256mem:$dst, VR256:$src),
873                    "movapd\t{$src, $dst|$dst, $src}",
874                    [(alignedstore256 (v4f64 VR256:$src), addr:$dst)],
875                    IIC_SSE_MOVA_P_MR>, VEX, VEX_L;
876 def VMOVUPSYmr : VPSI<0x11, MRMDestMem, (outs), (ins f256mem:$dst, VR256:$src),
877                    "movups\t{$src, $dst|$dst, $src}",
878                    [(store (v8f32 VR256:$src), addr:$dst)],
879                    IIC_SSE_MOVU_P_MR>, VEX, VEX_L;
880 def VMOVUPDYmr : VPDI<0x11, MRMDestMem, (outs), (ins f256mem:$dst, VR256:$src),
881                    "movupd\t{$src, $dst|$dst, $src}",
882                    [(store (v4f64 VR256:$src), addr:$dst)],
883                    IIC_SSE_MOVU_P_MR>, VEX, VEX_L;
884 } // SchedRW
885
886 // For disassembler
887 let isCodeGenOnly = 1, hasSideEffects = 0, SchedRW = [WriteMove] in {
888   def VMOVAPSrr_REV : VPSI<0x29, MRMDestReg, (outs VR128:$dst),
889                           (ins VR128:$src),
890                           "movaps\t{$src, $dst|$dst, $src}", [],
891                           IIC_SSE_MOVA_P_RR>, VEX;
892   def VMOVAPDrr_REV : VPDI<0x29, MRMDestReg, (outs VR128:$dst),
893                            (ins VR128:$src),
894                            "movapd\t{$src, $dst|$dst, $src}", [],
895                            IIC_SSE_MOVA_P_RR>, VEX;
896   def VMOVUPSrr_REV : VPSI<0x11, MRMDestReg, (outs VR128:$dst),
897                            (ins VR128:$src),
898                            "movups\t{$src, $dst|$dst, $src}", [],
899                            IIC_SSE_MOVU_P_RR>, VEX;
900   def VMOVUPDrr_REV : VPDI<0x11, MRMDestReg, (outs VR128:$dst),
901                            (ins VR128:$src),
902                            "movupd\t{$src, $dst|$dst, $src}", [],
903                            IIC_SSE_MOVU_P_RR>, VEX;
904   def VMOVAPSYrr_REV : VPSI<0x29, MRMDestReg, (outs VR256:$dst),
905                             (ins VR256:$src),
906                             "movaps\t{$src, $dst|$dst, $src}", [],
907                             IIC_SSE_MOVA_P_RR>, VEX, VEX_L;
908   def VMOVAPDYrr_REV : VPDI<0x29, MRMDestReg, (outs VR256:$dst),
909                             (ins VR256:$src),
910                             "movapd\t{$src, $dst|$dst, $src}", [],
911                             IIC_SSE_MOVA_P_RR>, VEX, VEX_L;
912   def VMOVUPSYrr_REV : VPSI<0x11, MRMDestReg, (outs VR256:$dst),
913                             (ins VR256:$src),
914                             "movups\t{$src, $dst|$dst, $src}", [],
915                             IIC_SSE_MOVU_P_RR>, VEX, VEX_L;
916   def VMOVUPDYrr_REV : VPDI<0x11, MRMDestReg, (outs VR256:$dst),
917                             (ins VR256:$src),
918                             "movupd\t{$src, $dst|$dst, $src}", [],
919                             IIC_SSE_MOVU_P_RR>, VEX, VEX_L;
920 }
921
922 let Predicates = [HasAVX] in {
923 def : Pat<(v8i32 (X86vzmovl
924                   (insert_subvector undef, (v4i32 VR128:$src), (iPTR 0)))),
925           (SUBREG_TO_REG (i32 0), (VMOVAPSrr VR128:$src), sub_xmm)>;
926 def : Pat<(v4i64 (X86vzmovl
927                   (insert_subvector undef, (v2i64 VR128:$src), (iPTR 0)))),
928           (SUBREG_TO_REG (i32 0), (VMOVAPSrr VR128:$src), sub_xmm)>;
929 def : Pat<(v8f32 (X86vzmovl
930                   (insert_subvector undef, (v4f32 VR128:$src), (iPTR 0)))),
931           (SUBREG_TO_REG (i32 0), (VMOVAPSrr VR128:$src), sub_xmm)>;
932 def : Pat<(v4f64 (X86vzmovl
933                   (insert_subvector undef, (v2f64 VR128:$src), (iPTR 0)))),
934           (SUBREG_TO_REG (i32 0), (VMOVAPSrr VR128:$src), sub_xmm)>;
935 }
936
937
938 def : Pat<(int_x86_avx_storeu_ps_256 addr:$dst, VR256:$src),
939           (VMOVUPSYmr addr:$dst, VR256:$src)>;
940 def : Pat<(int_x86_avx_storeu_pd_256 addr:$dst, VR256:$src),
941           (VMOVUPDYmr addr:$dst, VR256:$src)>;
942
943 let SchedRW = [WriteStore] in {
944 def MOVAPSmr : PSI<0x29, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
945                    "movaps\t{$src, $dst|$dst, $src}",
946                    [(alignedstore (v4f32 VR128:$src), addr:$dst)],
947                    IIC_SSE_MOVA_P_MR>;
948 def MOVAPDmr : PDI<0x29, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
949                    "movapd\t{$src, $dst|$dst, $src}",
950                    [(alignedstore (v2f64 VR128:$src), addr:$dst)],
951                    IIC_SSE_MOVA_P_MR>;
952 def MOVUPSmr : PSI<0x11, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
953                    "movups\t{$src, $dst|$dst, $src}",
954                    [(store (v4f32 VR128:$src), addr:$dst)],
955                    IIC_SSE_MOVU_P_MR>;
956 def MOVUPDmr : PDI<0x11, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
957                    "movupd\t{$src, $dst|$dst, $src}",
958                    [(store (v2f64 VR128:$src), addr:$dst)],
959                    IIC_SSE_MOVU_P_MR>;
960 } // SchedRW
961
962 // For disassembler
963 let isCodeGenOnly = 1, hasSideEffects = 0, SchedRW = [WriteMove] in {
964   def MOVAPSrr_REV : PSI<0x29, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
965                          "movaps\t{$src, $dst|$dst, $src}", [],
966                          IIC_SSE_MOVA_P_RR>;
967   def MOVAPDrr_REV : PDI<0x29, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
968                          "movapd\t{$src, $dst|$dst, $src}", [],
969                          IIC_SSE_MOVA_P_RR>;
970   def MOVUPSrr_REV : PSI<0x11, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
971                          "movups\t{$src, $dst|$dst, $src}", [],
972                          IIC_SSE_MOVU_P_RR>;
973   def MOVUPDrr_REV : PDI<0x11, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
974                          "movupd\t{$src, $dst|$dst, $src}", [],
975                          IIC_SSE_MOVU_P_RR>;
976 }
977
978 let Predicates = [HasAVX] in {
979   def : Pat<(int_x86_sse_storeu_ps addr:$dst, VR128:$src),
980             (VMOVUPSmr addr:$dst, VR128:$src)>;
981   def : Pat<(int_x86_sse2_storeu_pd addr:$dst, VR128:$src),
982             (VMOVUPDmr addr:$dst, VR128:$src)>;
983 }
984
985 let Predicates = [UseSSE1] in
986   def : Pat<(int_x86_sse_storeu_ps addr:$dst, VR128:$src),
987             (MOVUPSmr addr:$dst, VR128:$src)>;
988 let Predicates = [UseSSE2] in
989   def : Pat<(int_x86_sse2_storeu_pd addr:$dst, VR128:$src),
990             (MOVUPDmr addr:$dst, VR128:$src)>;
991
992 // Use vmovaps/vmovups for AVX integer load/store.
993 let Predicates = [HasAVX] in {
994   // 128-bit load/store
995   def : Pat<(alignedloadv2i64 addr:$src),
996             (VMOVAPSrm addr:$src)>;
997   def : Pat<(loadv2i64 addr:$src),
998             (VMOVUPSrm addr:$src)>;
999
1000   def : Pat<(alignedstore (v2i64 VR128:$src), addr:$dst),
1001             (VMOVAPSmr addr:$dst, VR128:$src)>;
1002   def : Pat<(alignedstore (v4i32 VR128:$src), addr:$dst),
1003             (VMOVAPSmr addr:$dst, VR128:$src)>;
1004   def : Pat<(alignedstore (v8i16 VR128:$src), addr:$dst),
1005             (VMOVAPSmr addr:$dst, VR128:$src)>;
1006   def : Pat<(alignedstore (v16i8 VR128:$src), addr:$dst),
1007             (VMOVAPSmr addr:$dst, VR128:$src)>;
1008   def : Pat<(store (v2i64 VR128:$src), addr:$dst),
1009             (VMOVUPSmr addr:$dst, VR128:$src)>;
1010   def : Pat<(store (v4i32 VR128:$src), addr:$dst),
1011             (VMOVUPSmr addr:$dst, VR128:$src)>;
1012   def : Pat<(store (v8i16 VR128:$src), addr:$dst),
1013             (VMOVUPSmr addr:$dst, VR128:$src)>;
1014   def : Pat<(store (v16i8 VR128:$src), addr:$dst),
1015             (VMOVUPSmr addr:$dst, VR128:$src)>;
1016
1017   // 256-bit load/store
1018   def : Pat<(alignedloadv4i64 addr:$src),
1019             (VMOVAPSYrm addr:$src)>;
1020   def : Pat<(loadv4i64 addr:$src),
1021             (VMOVUPSYrm addr:$src)>;
1022   def : Pat<(alignedstore256 (v4i64 VR256:$src), addr:$dst),
1023             (VMOVAPSYmr addr:$dst, VR256:$src)>;
1024   def : Pat<(alignedstore256 (v8i32 VR256:$src), addr:$dst),
1025             (VMOVAPSYmr addr:$dst, VR256:$src)>;
1026   def : Pat<(alignedstore256 (v16i16 VR256:$src), addr:$dst),
1027             (VMOVAPSYmr addr:$dst, VR256:$src)>;
1028   def : Pat<(alignedstore256 (v32i8 VR256:$src), addr:$dst),
1029             (VMOVAPSYmr addr:$dst, VR256:$src)>;
1030   def : Pat<(store (v4i64 VR256:$src), addr:$dst),
1031             (VMOVUPSYmr addr:$dst, VR256:$src)>;
1032   def : Pat<(store (v8i32 VR256:$src), addr:$dst),
1033             (VMOVUPSYmr addr:$dst, VR256:$src)>;
1034   def : Pat<(store (v16i16 VR256:$src), addr:$dst),
1035             (VMOVUPSYmr addr:$dst, VR256:$src)>;
1036   def : Pat<(store (v32i8 VR256:$src), addr:$dst),
1037             (VMOVUPSYmr addr:$dst, VR256:$src)>;
1038
1039   // Special patterns for storing subvector extracts of lower 128-bits
1040   // Its cheaper to just use VMOVAPS/VMOVUPS instead of VEXTRACTF128mr
1041   def : Pat<(alignedstore (v2f64 (extract_subvector
1042                                   (v4f64 VR256:$src), (iPTR 0))), addr:$dst),
1043             (VMOVAPDmr addr:$dst, (v2f64 (EXTRACT_SUBREG VR256:$src,sub_xmm)))>;
1044   def : Pat<(alignedstore (v4f32 (extract_subvector
1045                                   (v8f32 VR256:$src), (iPTR 0))), addr:$dst),
1046             (VMOVAPSmr addr:$dst, (v4f32 (EXTRACT_SUBREG VR256:$src,sub_xmm)))>;
1047   def : Pat<(alignedstore (v2i64 (extract_subvector
1048                                   (v4i64 VR256:$src), (iPTR 0))), addr:$dst),
1049             (VMOVAPDmr addr:$dst, (v2i64 (EXTRACT_SUBREG VR256:$src,sub_xmm)))>;
1050   def : Pat<(alignedstore (v4i32 (extract_subvector
1051                                   (v8i32 VR256:$src), (iPTR 0))), addr:$dst),
1052             (VMOVAPSmr addr:$dst, (v4i32 (EXTRACT_SUBREG VR256:$src,sub_xmm)))>;
1053   def : Pat<(alignedstore (v8i16 (extract_subvector
1054                                   (v16i16 VR256:$src), (iPTR 0))), addr:$dst),
1055             (VMOVAPSmr addr:$dst, (v8i16 (EXTRACT_SUBREG VR256:$src,sub_xmm)))>;
1056   def : Pat<(alignedstore (v16i8 (extract_subvector
1057                                   (v32i8 VR256:$src), (iPTR 0))), addr:$dst),
1058             (VMOVAPSmr addr:$dst, (v16i8 (EXTRACT_SUBREG VR256:$src,sub_xmm)))>;
1059
1060   def : Pat<(store (v2f64 (extract_subvector
1061                            (v4f64 VR256:$src), (iPTR 0))), addr:$dst),
1062             (VMOVUPDmr addr:$dst, (v2f64 (EXTRACT_SUBREG VR256:$src,sub_xmm)))>;
1063   def : Pat<(store (v4f32 (extract_subvector
1064                            (v8f32 VR256:$src), (iPTR 0))), addr:$dst),
1065             (VMOVUPSmr addr:$dst, (v4f32 (EXTRACT_SUBREG VR256:$src,sub_xmm)))>;
1066   def : Pat<(store (v2i64 (extract_subvector
1067                            (v4i64 VR256:$src), (iPTR 0))), addr:$dst),
1068             (VMOVUPDmr addr:$dst, (v2i64 (EXTRACT_SUBREG VR256:$src,sub_xmm)))>;
1069   def : Pat<(store (v4i32 (extract_subvector
1070                            (v8i32 VR256:$src), (iPTR 0))), addr:$dst),
1071             (VMOVUPSmr addr:$dst, (v4i32 (EXTRACT_SUBREG VR256:$src,sub_xmm)))>;
1072   def : Pat<(store (v8i16 (extract_subvector
1073                            (v16i16 VR256:$src), (iPTR 0))), addr:$dst),
1074             (VMOVUPSmr addr:$dst, (v8i16 (EXTRACT_SUBREG VR256:$src,sub_xmm)))>;
1075   def : Pat<(store (v16i8 (extract_subvector
1076                            (v32i8 VR256:$src), (iPTR 0))), addr:$dst),
1077             (VMOVUPSmr addr:$dst, (v16i8 (EXTRACT_SUBREG VR256:$src,sub_xmm)))>;
1078 }
1079
1080 // Use movaps / movups for SSE integer load / store (one byte shorter).
1081 // The instructions selected below are then converted to MOVDQA/MOVDQU
1082 // during the SSE domain pass.
1083 let Predicates = [UseSSE1] in {
1084   def : Pat<(alignedloadv2i64 addr:$src),
1085             (MOVAPSrm addr:$src)>;
1086   def : Pat<(loadv2i64 addr:$src),
1087             (MOVUPSrm addr:$src)>;
1088
1089   def : Pat<(alignedstore (v2i64 VR128:$src), addr:$dst),
1090             (MOVAPSmr addr:$dst, VR128:$src)>;
1091   def : Pat<(alignedstore (v4i32 VR128:$src), addr:$dst),
1092             (MOVAPSmr addr:$dst, VR128:$src)>;
1093   def : Pat<(alignedstore (v8i16 VR128:$src), addr:$dst),
1094             (MOVAPSmr addr:$dst, VR128:$src)>;
1095   def : Pat<(alignedstore (v16i8 VR128:$src), addr:$dst),
1096             (MOVAPSmr addr:$dst, VR128:$src)>;
1097   def : Pat<(store (v2i64 VR128:$src), addr:$dst),
1098             (MOVUPSmr addr:$dst, VR128:$src)>;
1099   def : Pat<(store (v4i32 VR128:$src), addr:$dst),
1100             (MOVUPSmr addr:$dst, VR128:$src)>;
1101   def : Pat<(store (v8i16 VR128:$src), addr:$dst),
1102             (MOVUPSmr addr:$dst, VR128:$src)>;
1103   def : Pat<(store (v16i8 VR128:$src), addr:$dst),
1104             (MOVUPSmr addr:$dst, VR128:$src)>;
1105 }
1106
1107 // Alias instruction to load FR32 or FR64 from f128mem using movaps. Upper
1108 // bits are disregarded. FIXME: Set encoding to pseudo!
1109 let canFoldAsLoad = 1, isReMaterializable = 1, SchedRW = [WriteLoad] in {
1110 let isCodeGenOnly = 1 in {
1111   def FsVMOVAPSrm : VPSI<0x28, MRMSrcMem, (outs FR32:$dst), (ins f128mem:$src),
1112                          "movaps\t{$src, $dst|$dst, $src}",
1113                          [(set FR32:$dst, (alignedloadfsf32 addr:$src))],
1114                          IIC_SSE_MOVA_P_RM>, VEX;
1115   def FsVMOVAPDrm : VPDI<0x28, MRMSrcMem, (outs FR64:$dst), (ins f128mem:$src),
1116                          "movapd\t{$src, $dst|$dst, $src}",
1117                          [(set FR64:$dst, (alignedloadfsf64 addr:$src))],
1118                          IIC_SSE_MOVA_P_RM>, VEX;
1119   def FsMOVAPSrm : PSI<0x28, MRMSrcMem, (outs FR32:$dst), (ins f128mem:$src),
1120                        "movaps\t{$src, $dst|$dst, $src}",
1121                        [(set FR32:$dst, (alignedloadfsf32 addr:$src))],
1122                        IIC_SSE_MOVA_P_RM>;
1123   def FsMOVAPDrm : PDI<0x28, MRMSrcMem, (outs FR64:$dst), (ins f128mem:$src),
1124                        "movapd\t{$src, $dst|$dst, $src}",
1125                        [(set FR64:$dst, (alignedloadfsf64 addr:$src))],
1126                        IIC_SSE_MOVA_P_RM>;
1127 }
1128 }
1129
1130 //===----------------------------------------------------------------------===//
1131 // SSE 1 & 2 - Move Low packed FP Instructions
1132 //===----------------------------------------------------------------------===//
1133
1134 multiclass sse12_mov_hilo_packed_base<bits<8>opc, SDNode psnode, SDNode pdnode,
1135                                       string base_opc, string asm_opr,
1136                                       InstrItinClass itin> {
1137   def PSrm : PI<opc, MRMSrcMem,
1138          (outs VR128:$dst), (ins VR128:$src1, f64mem:$src2),
1139          !strconcat(base_opc, "s", asm_opr),
1140      [(set VR128:$dst,
1141        (psnode VR128:$src1,
1142               (bc_v4f32 (v2f64 (scalar_to_vector (loadf64 addr:$src2))))))],
1143               itin, SSEPackedSingle>, TB,
1144      Sched<[WriteShuffleLd, ReadAfterLd]>;
1145
1146   def PDrm : PI<opc, MRMSrcMem,
1147          (outs VR128:$dst), (ins VR128:$src1, f64mem:$src2),
1148          !strconcat(base_opc, "d", asm_opr),
1149      [(set VR128:$dst, (v2f64 (pdnode VR128:$src1,
1150                               (scalar_to_vector (loadf64 addr:$src2)))))],
1151               itin, SSEPackedDouble>, TB, OpSize,
1152      Sched<[WriteShuffleLd, ReadAfterLd]>;
1153
1154 }
1155
1156 multiclass sse12_mov_hilo_packed<bits<8>opc, SDNode psnode, SDNode pdnode,
1157                                  string base_opc, InstrItinClass itin> {
1158   defm V#NAME : sse12_mov_hilo_packed_base<opc, psnode, pdnode, base_opc,
1159                                     "\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1160                                     itin>, VEX_4V;
1161
1162 let Constraints = "$src1 = $dst" in
1163   defm NAME : sse12_mov_hilo_packed_base<opc, psnode, pdnode, base_opc,
1164                                     "\t{$src2, $dst|$dst, $src2}",
1165                                     itin>;
1166 }
1167
1168 let AddedComplexity = 20 in {
1169   defm MOVL : sse12_mov_hilo_packed<0x12, X86Movlps, X86Movlpd, "movlp",
1170                                     IIC_SSE_MOV_LH>;
1171 }
1172
1173 let SchedRW = [WriteStore] in {
1174 def VMOVLPSmr : VPSI<0x13, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
1175                    "movlps\t{$src, $dst|$dst, $src}",
1176                    [(store (f64 (vector_extract (bc_v2f64 (v4f32 VR128:$src)),
1177                                  (iPTR 0))), addr:$dst)],
1178                                  IIC_SSE_MOV_LH>, VEX;
1179 def VMOVLPDmr : VPDI<0x13, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
1180                    "movlpd\t{$src, $dst|$dst, $src}",
1181                    [(store (f64 (vector_extract (v2f64 VR128:$src),
1182                                  (iPTR 0))), addr:$dst)],
1183                                  IIC_SSE_MOV_LH>, VEX;
1184 def MOVLPSmr : PSI<0x13, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
1185                    "movlps\t{$src, $dst|$dst, $src}",
1186                    [(store (f64 (vector_extract (bc_v2f64 (v4f32 VR128:$src)),
1187                                  (iPTR 0))), addr:$dst)],
1188                                  IIC_SSE_MOV_LH>;
1189 def MOVLPDmr : PDI<0x13, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
1190                    "movlpd\t{$src, $dst|$dst, $src}",
1191                    [(store (f64 (vector_extract (v2f64 VR128:$src),
1192                                  (iPTR 0))), addr:$dst)],
1193                                  IIC_SSE_MOV_LH>;
1194 } // SchedRW
1195
1196 let Predicates = [HasAVX] in {
1197   // Shuffle with VMOVLPS
1198   def : Pat<(v4f32 (X86Movlps VR128:$src1, (load addr:$src2))),
1199             (VMOVLPSrm VR128:$src1, addr:$src2)>;
1200   def : Pat<(v4i32 (X86Movlps VR128:$src1, (load addr:$src2))),
1201             (VMOVLPSrm VR128:$src1, addr:$src2)>;
1202
1203   // Shuffle with VMOVLPD
1204   def : Pat<(v2f64 (X86Movlpd VR128:$src1, (load addr:$src2))),
1205             (VMOVLPDrm VR128:$src1, addr:$src2)>;
1206   def : Pat<(v2i64 (X86Movlpd VR128:$src1, (load addr:$src2))),
1207             (VMOVLPDrm VR128:$src1, addr:$src2)>;
1208
1209   // Store patterns
1210   def : Pat<(store (v4f32 (X86Movlps (load addr:$src1), VR128:$src2)),
1211                    addr:$src1),
1212             (VMOVLPSmr addr:$src1, VR128:$src2)>;
1213   def : Pat<(store (v4i32 (X86Movlps
1214                    (bc_v4i32 (loadv2i64 addr:$src1)), VR128:$src2)), addr:$src1),
1215             (VMOVLPSmr addr:$src1, VR128:$src2)>;
1216   def : Pat<(store (v2f64 (X86Movlpd (load addr:$src1), VR128:$src2)),
1217                    addr:$src1),
1218             (VMOVLPDmr addr:$src1, VR128:$src2)>;
1219   def : Pat<(store (v2i64 (X86Movlpd (load addr:$src1), VR128:$src2)),
1220                    addr:$src1),
1221             (VMOVLPDmr addr:$src1, VR128:$src2)>;
1222 }
1223
1224 let Predicates = [UseSSE1] in {
1225   // (store (vector_shuffle (load addr), v2, <4, 5, 2, 3>), addr) using MOVLPS
1226   def : Pat<(store (i64 (vector_extract (bc_v2i64 (v4f32 VR128:$src2)),
1227                                  (iPTR 0))), addr:$src1),
1228             (MOVLPSmr addr:$src1, VR128:$src2)>;
1229
1230   // Shuffle with MOVLPS
1231   def : Pat<(v4f32 (X86Movlps VR128:$src1, (load addr:$src2))),
1232             (MOVLPSrm VR128:$src1, addr:$src2)>;
1233   def : Pat<(v4i32 (X86Movlps VR128:$src1, (load addr:$src2))),
1234             (MOVLPSrm VR128:$src1, addr:$src2)>;
1235   def : Pat<(X86Movlps VR128:$src1,
1236                       (bc_v4f32 (v2i64 (scalar_to_vector (loadi64 addr:$src2))))),
1237             (MOVLPSrm VR128:$src1, addr:$src2)>;
1238
1239   // Store patterns
1240   def : Pat<(store (v4f32 (X86Movlps (load addr:$src1), VR128:$src2)),
1241                                       addr:$src1),
1242             (MOVLPSmr addr:$src1, VR128:$src2)>;
1243   def : Pat<(store (v4i32 (X86Movlps
1244                    (bc_v4i32 (loadv2i64 addr:$src1)), VR128:$src2)),
1245                               addr:$src1),
1246             (MOVLPSmr addr:$src1, VR128:$src2)>;
1247 }
1248
1249 let Predicates = [UseSSE2] in {
1250   // Shuffle with MOVLPD
1251   def : Pat<(v2f64 (X86Movlpd VR128:$src1, (load addr:$src2))),
1252             (MOVLPDrm VR128:$src1, addr:$src2)>;
1253   def : Pat<(v2i64 (X86Movlpd VR128:$src1, (load addr:$src2))),
1254             (MOVLPDrm VR128:$src1, addr:$src2)>;
1255
1256   // Store patterns
1257   def : Pat<(store (v2f64 (X86Movlpd (load addr:$src1), VR128:$src2)),
1258                            addr:$src1),
1259             (MOVLPDmr addr:$src1, VR128:$src2)>;
1260   def : Pat<(store (v2i64 (X86Movlpd (load addr:$src1), VR128:$src2)),
1261                            addr:$src1),
1262             (MOVLPDmr addr:$src1, VR128:$src2)>;
1263 }
1264
1265 //===----------------------------------------------------------------------===//
1266 // SSE 1 & 2 - Move Hi packed FP Instructions
1267 //===----------------------------------------------------------------------===//
1268
1269 let AddedComplexity = 20 in {
1270   defm MOVH : sse12_mov_hilo_packed<0x16, X86Movlhps, X86Movlhpd, "movhp",
1271                                     IIC_SSE_MOV_LH>;
1272 }
1273
1274 let SchedRW = [WriteStore] in {
1275 // v2f64 extract element 1 is always custom lowered to unpack high to low
1276 // and extract element 0 so the non-store version isn't too horrible.
1277 def VMOVHPSmr : VPSI<0x17, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
1278                    "movhps\t{$src, $dst|$dst, $src}",
1279                    [(store (f64 (vector_extract
1280                                  (X86Unpckh (bc_v2f64 (v4f32 VR128:$src)),
1281                                             (bc_v2f64 (v4f32 VR128:$src))),
1282                                  (iPTR 0))), addr:$dst)], IIC_SSE_MOV_LH>, VEX;
1283 def VMOVHPDmr : VPDI<0x17, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
1284                    "movhpd\t{$src, $dst|$dst, $src}",
1285                    [(store (f64 (vector_extract
1286                                  (v2f64 (X86Unpckh VR128:$src, VR128:$src)),
1287                                  (iPTR 0))), addr:$dst)], IIC_SSE_MOV_LH>, VEX;
1288 def MOVHPSmr : PSI<0x17, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
1289                    "movhps\t{$src, $dst|$dst, $src}",
1290                    [(store (f64 (vector_extract
1291                                  (X86Unpckh (bc_v2f64 (v4f32 VR128:$src)),
1292                                             (bc_v2f64 (v4f32 VR128:$src))),
1293                                  (iPTR 0))), addr:$dst)], IIC_SSE_MOV_LH>;
1294 def MOVHPDmr : PDI<0x17, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
1295                    "movhpd\t{$src, $dst|$dst, $src}",
1296                    [(store (f64 (vector_extract
1297                                  (v2f64 (X86Unpckh VR128:$src, VR128:$src)),
1298                                  (iPTR 0))), addr:$dst)], IIC_SSE_MOV_LH>;
1299 } // SchedRW
1300
1301 let Predicates = [HasAVX] in {
1302   // VMOVHPS patterns
1303   def : Pat<(X86Movlhps VR128:$src1,
1304                  (bc_v4f32 (v2i64 (scalar_to_vector (loadi64 addr:$src2))))),
1305             (VMOVHPSrm VR128:$src1, addr:$src2)>;
1306   def : Pat<(X86Movlhps VR128:$src1,
1307                  (bc_v4i32 (v2i64 (X86vzload addr:$src2)))),
1308             (VMOVHPSrm VR128:$src1, addr:$src2)>;
1309
1310   // FIXME: Instead of X86Unpckl, there should be a X86Movlhpd here, the problem
1311   // is during lowering, where it's not possible to recognize the load fold
1312   // cause it has two uses through a bitcast. One use disappears at isel time
1313   // and the fold opportunity reappears.
1314   def : Pat<(v2f64 (X86Unpckl VR128:$src1,
1315                       (scalar_to_vector (loadf64 addr:$src2)))),
1316             (VMOVHPDrm VR128:$src1, addr:$src2)>;
1317 }
1318
1319 let Predicates = [UseSSE1] in {
1320   // MOVHPS patterns
1321   def : Pat<(X86Movlhps VR128:$src1,
1322                  (bc_v4f32 (v2i64 (scalar_to_vector (loadi64 addr:$src2))))),
1323             (MOVHPSrm VR128:$src1, addr:$src2)>;
1324   def : Pat<(X86Movlhps VR128:$src1,
1325                  (bc_v4f32 (v2i64 (X86vzload addr:$src2)))),
1326             (MOVHPSrm VR128:$src1, addr:$src2)>;
1327 }
1328
1329 let Predicates = [UseSSE2] in {
1330   // FIXME: Instead of X86Unpckl, there should be a X86Movlhpd here, the problem
1331   // is during lowering, where it's not possible to recognize the load fold
1332   // cause it has two uses through a bitcast. One use disappears at isel time
1333   // and the fold opportunity reappears.
1334   def : Pat<(v2f64 (X86Unpckl VR128:$src1,
1335                       (scalar_to_vector (loadf64 addr:$src2)))),
1336             (MOVHPDrm VR128:$src1, addr:$src2)>;
1337 }
1338
1339 //===----------------------------------------------------------------------===//
1340 // SSE 1 & 2 - Move Low to High and High to Low packed FP Instructions
1341 //===----------------------------------------------------------------------===//
1342
1343 let AddedComplexity = 20, Predicates = [UseAVX] in {
1344   def VMOVLHPSrr : VPSI<0x16, MRMSrcReg, (outs VR128:$dst),
1345                                        (ins VR128:$src1, VR128:$src2),
1346                       "movlhps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1347                       [(set VR128:$dst,
1348                         (v4f32 (X86Movlhps VR128:$src1, VR128:$src2)))],
1349                         IIC_SSE_MOV_LH>,
1350                       VEX_4V, Sched<[WriteShuffle]>;
1351   def VMOVHLPSrr : VPSI<0x12, MRMSrcReg, (outs VR128:$dst),
1352                                        (ins VR128:$src1, VR128:$src2),
1353                       "movhlps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1354                       [(set VR128:$dst,
1355                         (v4f32 (X86Movhlps VR128:$src1, VR128:$src2)))],
1356                         IIC_SSE_MOV_LH>,
1357                       VEX_4V, Sched<[WriteShuffle]>;
1358 }
1359 let Constraints = "$src1 = $dst", AddedComplexity = 20 in {
1360   def MOVLHPSrr : PSI<0x16, MRMSrcReg, (outs VR128:$dst),
1361                                        (ins VR128:$src1, VR128:$src2),
1362                       "movlhps\t{$src2, $dst|$dst, $src2}",
1363                       [(set VR128:$dst,
1364                         (v4f32 (X86Movlhps VR128:$src1, VR128:$src2)))],
1365                         IIC_SSE_MOV_LH>, Sched<[WriteShuffle]>;
1366   def MOVHLPSrr : PSI<0x12, MRMSrcReg, (outs VR128:$dst),
1367                                        (ins VR128:$src1, VR128:$src2),
1368                       "movhlps\t{$src2, $dst|$dst, $src2}",
1369                       [(set VR128:$dst,
1370                         (v4f32 (X86Movhlps VR128:$src1, VR128:$src2)))],
1371                         IIC_SSE_MOV_LH>, Sched<[WriteShuffle]>;
1372 }
1373
1374 let Predicates = [UseAVX] in {
1375   // MOVLHPS patterns
1376   def : Pat<(v4i32 (X86Movlhps VR128:$src1, VR128:$src2)),
1377             (VMOVLHPSrr VR128:$src1, VR128:$src2)>;
1378   def : Pat<(v2i64 (X86Movlhps VR128:$src1, VR128:$src2)),
1379             (VMOVLHPSrr (v2i64 VR128:$src1), VR128:$src2)>;
1380
1381   // MOVHLPS patterns
1382   def : Pat<(v4i32 (X86Movhlps VR128:$src1, VR128:$src2)),
1383             (VMOVHLPSrr VR128:$src1, VR128:$src2)>;
1384 }
1385
1386 let Predicates = [UseSSE1] in {
1387   // MOVLHPS patterns
1388   def : Pat<(v4i32 (X86Movlhps VR128:$src1, VR128:$src2)),
1389             (MOVLHPSrr VR128:$src1, VR128:$src2)>;
1390   def : Pat<(v2i64 (X86Movlhps VR128:$src1, VR128:$src2)),
1391             (MOVLHPSrr (v2i64 VR128:$src1), VR128:$src2)>;
1392
1393   // MOVHLPS patterns
1394   def : Pat<(v4i32 (X86Movhlps VR128:$src1, VR128:$src2)),
1395             (MOVHLPSrr VR128:$src1, VR128:$src2)>;
1396 }
1397
1398 //===----------------------------------------------------------------------===//
1399 // SSE 1 & 2 - Conversion Instructions
1400 //===----------------------------------------------------------------------===//
1401
1402 def SSE_CVT_PD : OpndItins<
1403   IIC_SSE_CVT_PD_RR, IIC_SSE_CVT_PD_RM
1404 >;
1405
1406 let Sched = WriteCvtI2F in
1407 def SSE_CVT_PS : OpndItins<
1408   IIC_SSE_CVT_PS_RR, IIC_SSE_CVT_PS_RM
1409 >;
1410
1411 let Sched = WriteCvtI2F in
1412 def SSE_CVT_Scalar : OpndItins<
1413   IIC_SSE_CVT_Scalar_RR, IIC_SSE_CVT_Scalar_RM
1414 >;
1415
1416 let Sched = WriteCvtF2I in
1417 def SSE_CVT_SS2SI_32 : OpndItins<
1418   IIC_SSE_CVT_SS2SI32_RR, IIC_SSE_CVT_SS2SI32_RM
1419 >;
1420
1421 let Sched = WriteCvtF2I in
1422 def SSE_CVT_SS2SI_64 : OpndItins<
1423   IIC_SSE_CVT_SS2SI64_RR, IIC_SSE_CVT_SS2SI64_RM
1424 >;
1425
1426 let Sched = WriteCvtF2I in
1427 def SSE_CVT_SD2SI : OpndItins<
1428   IIC_SSE_CVT_SD2SI_RR, IIC_SSE_CVT_SD2SI_RM
1429 >;
1430
1431 multiclass sse12_cvt_s<bits<8> opc, RegisterClass SrcRC, RegisterClass DstRC,
1432                      SDNode OpNode, X86MemOperand x86memop, PatFrag ld_frag,
1433                      string asm, OpndItins itins> {
1434   def rr : SI<opc, MRMSrcReg, (outs DstRC:$dst), (ins SrcRC:$src), asm,
1435                         [(set DstRC:$dst, (OpNode SrcRC:$src))],
1436                         itins.rr>, Sched<[itins.Sched]>;
1437   def rm : SI<opc, MRMSrcMem, (outs DstRC:$dst), (ins x86memop:$src), asm,
1438                         [(set DstRC:$dst, (OpNode (ld_frag addr:$src)))],
1439                         itins.rm>, Sched<[itins.Sched.Folded]>;
1440 }
1441
1442 multiclass sse12_cvt_p<bits<8> opc, RegisterClass SrcRC, RegisterClass DstRC,
1443                        X86MemOperand x86memop, string asm, Domain d,
1444                        OpndItins itins> {
1445 let neverHasSideEffects = 1 in {
1446   def rr : I<opc, MRMSrcReg, (outs DstRC:$dst), (ins SrcRC:$src), asm,
1447              [], itins.rr, d>, Sched<[itins.Sched]>;
1448   let mayLoad = 1 in
1449   def rm : I<opc, MRMSrcMem, (outs DstRC:$dst), (ins x86memop:$src), asm,
1450              [], itins.rm, d>, Sched<[itins.Sched.Folded]>;
1451 }
1452 }
1453
1454 multiclass sse12_vcvt_avx<bits<8> opc, RegisterClass SrcRC, RegisterClass DstRC,
1455                           X86MemOperand x86memop, string asm> {
1456 let neverHasSideEffects = 1, Predicates = [UseAVX] in {
1457   def rr : SI<opc, MRMSrcReg, (outs DstRC:$dst), (ins DstRC:$src1, SrcRC:$src),
1458               !strconcat(asm,"\t{$src, $src1, $dst|$dst, $src1, $src}"), []>,
1459            Sched<[WriteCvtI2F]>;
1460   let mayLoad = 1 in
1461   def rm : SI<opc, MRMSrcMem, (outs DstRC:$dst),
1462               (ins DstRC:$src1, x86memop:$src),
1463               !strconcat(asm,"\t{$src, $src1, $dst|$dst, $src1, $src}"), []>,
1464            Sched<[WriteCvtI2FLd, ReadAfterLd]>;
1465 } // neverHasSideEffects = 1
1466 }
1467
1468 let Predicates = [UseAVX] in {
1469 defm VCVTTSS2SI   : sse12_cvt_s<0x2C, FR32, GR32, fp_to_sint, f32mem, loadf32,
1470                                 "cvttss2si\t{$src, $dst|$dst, $src}",
1471                                 SSE_CVT_SS2SI_32>,
1472                                 XS, VEX, VEX_LIG;
1473 defm VCVTTSS2SI64 : sse12_cvt_s<0x2C, FR32, GR64, fp_to_sint, f32mem, loadf32,
1474                                 "cvttss2si\t{$src, $dst|$dst, $src}",
1475                                 SSE_CVT_SS2SI_64>,
1476                                 XS, VEX, VEX_W, VEX_LIG;
1477 defm VCVTTSD2SI   : sse12_cvt_s<0x2C, FR64, GR32, fp_to_sint, f64mem, loadf64,
1478                                 "cvttsd2si\t{$src, $dst|$dst, $src}",
1479                                 SSE_CVT_SD2SI>,
1480                                 XD, VEX, VEX_LIG;
1481 defm VCVTTSD2SI64 : sse12_cvt_s<0x2C, FR64, GR64, fp_to_sint, f64mem, loadf64,
1482                                 "cvttsd2si\t{$src, $dst|$dst, $src}",
1483                                 SSE_CVT_SD2SI>,
1484                                 XD, VEX, VEX_W, VEX_LIG;
1485
1486 def : InstAlias<"vcvttss2si{l}\t{$src, $dst|$dst, $src}",
1487                 (VCVTTSS2SIrr GR32:$dst, FR32:$src), 0>;
1488 def : InstAlias<"vcvttss2si{l}\t{$src, $dst|$dst, $src}",
1489                 (VCVTTSS2SIrm GR32:$dst, f32mem:$src), 0>;
1490 def : InstAlias<"vcvttsd2si{l}\t{$src, $dst|$dst, $src}",
1491                 (VCVTTSD2SIrr GR32:$dst, FR64:$src), 0>;
1492 def : InstAlias<"vcvttsd2si{l}\t{$src, $dst|$dst, $src}",
1493                 (VCVTTSD2SIrm GR32:$dst, f64mem:$src), 0>;
1494 def : InstAlias<"vcvttss2si{q}\t{$src, $dst|$dst, $src}",
1495                 (VCVTTSS2SI64rr GR64:$dst, FR32:$src), 0>;
1496 def : InstAlias<"vcvttss2si{q}\t{$src, $dst|$dst, $src}",
1497                 (VCVTTSS2SI64rm GR64:$dst, f32mem:$src), 0>;
1498 def : InstAlias<"vcvttsd2si{q}\t{$src, $dst|$dst, $src}",
1499                 (VCVTTSD2SI64rr GR64:$dst, FR64:$src), 0>;
1500 def : InstAlias<"vcvttsd2si{q}\t{$src, $dst|$dst, $src}",
1501                 (VCVTTSD2SI64rm GR64:$dst, f64mem:$src), 0>;
1502 }
1503 // The assembler can recognize rr 64-bit instructions by seeing a rxx
1504 // register, but the same isn't true when only using memory operands,
1505 // provide other assembly "l" and "q" forms to address this explicitly
1506 // where appropriate to do so.
1507 defm VCVTSI2SS   : sse12_vcvt_avx<0x2A, GR32, FR32, i32mem, "cvtsi2ss{l}">,
1508                                   XS, VEX_4V, VEX_LIG;
1509 defm VCVTSI2SS64 : sse12_vcvt_avx<0x2A, GR64, FR32, i64mem, "cvtsi2ss{q}">,
1510                                   XS, VEX_4V, VEX_W, VEX_LIG;
1511 defm VCVTSI2SD   : sse12_vcvt_avx<0x2A, GR32, FR64, i32mem, "cvtsi2sd{l}">,
1512                                   XD, VEX_4V, VEX_LIG;
1513 defm VCVTSI2SD64 : sse12_vcvt_avx<0x2A, GR64, FR64, i64mem, "cvtsi2sd{q}">,
1514                                   XD, VEX_4V, VEX_W, VEX_LIG;
1515
1516 let Predicates = [UseAVX] in {
1517   def : InstAlias<"vcvtsi2ss\t{$src, $src1, $dst|$dst, $src1, $src}",
1518                 (VCVTSI2SSrm FR64:$dst, FR64:$src1, i32mem:$src)>;
1519   def : InstAlias<"vcvtsi2sd\t{$src, $src1, $dst|$dst, $src1, $src}",
1520                 (VCVTSI2SDrm FR64:$dst, FR64:$src1, i32mem:$src)>;
1521
1522   def : Pat<(f32 (sint_to_fp (loadi32 addr:$src))),
1523             (VCVTSI2SSrm (f32 (IMPLICIT_DEF)), addr:$src)>;
1524   def : Pat<(f32 (sint_to_fp (loadi64 addr:$src))),
1525             (VCVTSI2SS64rm (f32 (IMPLICIT_DEF)), addr:$src)>;
1526   def : Pat<(f64 (sint_to_fp (loadi32 addr:$src))),
1527             (VCVTSI2SDrm (f64 (IMPLICIT_DEF)), addr:$src)>;
1528   def : Pat<(f64 (sint_to_fp (loadi64 addr:$src))),
1529             (VCVTSI2SD64rm (f64 (IMPLICIT_DEF)), addr:$src)>;
1530
1531   def : Pat<(f32 (sint_to_fp GR32:$src)),
1532             (VCVTSI2SSrr (f32 (IMPLICIT_DEF)), GR32:$src)>;
1533   def : Pat<(f32 (sint_to_fp GR64:$src)),
1534             (VCVTSI2SS64rr (f32 (IMPLICIT_DEF)), GR64:$src)>;
1535   def : Pat<(f64 (sint_to_fp GR32:$src)),
1536             (VCVTSI2SDrr (f64 (IMPLICIT_DEF)), GR32:$src)>;
1537   def : Pat<(f64 (sint_to_fp GR64:$src)),
1538             (VCVTSI2SD64rr (f64 (IMPLICIT_DEF)), GR64:$src)>;
1539 }
1540
1541 defm CVTTSS2SI : sse12_cvt_s<0x2C, FR32, GR32, fp_to_sint, f32mem, loadf32,
1542                       "cvttss2si\t{$src, $dst|$dst, $src}",
1543                       SSE_CVT_SS2SI_32>, XS;
1544 defm CVTTSS2SI64 : sse12_cvt_s<0x2C, FR32, GR64, fp_to_sint, f32mem, loadf32,
1545                       "cvttss2si\t{$src, $dst|$dst, $src}",
1546                       SSE_CVT_SS2SI_64>, XS, REX_W;
1547 defm CVTTSD2SI : sse12_cvt_s<0x2C, FR64, GR32, fp_to_sint, f64mem, loadf64,
1548                       "cvttsd2si\t{$src, $dst|$dst, $src}",
1549                       SSE_CVT_SD2SI>, XD;
1550 defm CVTTSD2SI64 : sse12_cvt_s<0x2C, FR64, GR64, fp_to_sint, f64mem, loadf64,
1551                       "cvttsd2si\t{$src, $dst|$dst, $src}",
1552                       SSE_CVT_SD2SI>, XD, REX_W;
1553 defm CVTSI2SS  : sse12_cvt_s<0x2A, GR32, FR32, sint_to_fp, i32mem, loadi32,
1554                       "cvtsi2ss{l}\t{$src, $dst|$dst, $src}",
1555                       SSE_CVT_Scalar>, XS;
1556 defm CVTSI2SS64 : sse12_cvt_s<0x2A, GR64, FR32, sint_to_fp, i64mem, loadi64,
1557                       "cvtsi2ss{q}\t{$src, $dst|$dst, $src}",
1558                       SSE_CVT_Scalar>, XS, REX_W;
1559 defm CVTSI2SD  : sse12_cvt_s<0x2A, GR32, FR64, sint_to_fp, i32mem, loadi32,
1560                       "cvtsi2sd{l}\t{$src, $dst|$dst, $src}",
1561                       SSE_CVT_Scalar>, XD;
1562 defm CVTSI2SD64 : sse12_cvt_s<0x2A, GR64, FR64, sint_to_fp, i64mem, loadi64,
1563                       "cvtsi2sd{q}\t{$src, $dst|$dst, $src}",
1564                       SSE_CVT_Scalar>, XD, REX_W;
1565
1566 def : InstAlias<"cvttss2si{l}\t{$src, $dst|$dst, $src}",
1567                 (CVTTSS2SIrr GR32:$dst, FR32:$src), 0>;
1568 def : InstAlias<"cvttss2si{l}\t{$src, $dst|$dst, $src}",
1569                 (CVTTSS2SIrm GR32:$dst, f32mem:$src), 0>;
1570 def : InstAlias<"cvttsd2si{l}\t{$src, $dst|$dst, $src}",
1571                 (CVTTSD2SIrr GR32:$dst, FR64:$src), 0>;
1572 def : InstAlias<"cvttsd2si{l}\t{$src, $dst|$dst, $src}",
1573                 (CVTTSD2SIrm GR32:$dst, f64mem:$src), 0>;
1574 def : InstAlias<"cvttss2si{q}\t{$src, $dst|$dst, $src}",
1575                 (CVTTSS2SI64rr GR64:$dst, FR32:$src), 0>;
1576 def : InstAlias<"cvttss2si{q}\t{$src, $dst|$dst, $src}",
1577                 (CVTTSS2SI64rm GR64:$dst, f32mem:$src), 0>;
1578 def : InstAlias<"cvttsd2si{q}\t{$src, $dst|$dst, $src}",
1579                 (CVTTSD2SI64rr GR64:$dst, FR64:$src), 0>;
1580 def : InstAlias<"cvttsd2si{q}\t{$src, $dst|$dst, $src}",
1581                 (CVTTSD2SI64rm GR64:$dst, f64mem:$src), 0>;
1582
1583 def : InstAlias<"cvtsi2ss\t{$src, $dst|$dst, $src}",
1584                 (CVTSI2SSrm FR64:$dst, i32mem:$src)>;
1585 def : InstAlias<"cvtsi2sd\t{$src, $dst|$dst, $src}",
1586                 (CVTSI2SDrm FR64:$dst, i32mem:$src)>;
1587
1588 // Conversion Instructions Intrinsics - Match intrinsics which expect MM
1589 // and/or XMM operand(s).
1590
1591 multiclass sse12_cvt_sint<bits<8> opc, RegisterClass SrcRC, RegisterClass DstRC,
1592                          Intrinsic Int, Operand memop, ComplexPattern mem_cpat,
1593                          string asm, OpndItins itins> {
1594   def rr : SI<opc, MRMSrcReg, (outs DstRC:$dst), (ins SrcRC:$src),
1595               !strconcat(asm, "\t{$src, $dst|$dst, $src}"),
1596               [(set DstRC:$dst, (Int SrcRC:$src))], itins.rr>,
1597            Sched<[itins.Sched]>;
1598   def rm : SI<opc, MRMSrcMem, (outs DstRC:$dst), (ins memop:$src),
1599               !strconcat(asm, "\t{$src, $dst|$dst, $src}"),
1600               [(set DstRC:$dst, (Int mem_cpat:$src))], itins.rm>,
1601            Sched<[itins.Sched.Folded]>;
1602 }
1603
1604 multiclass sse12_cvt_sint_3addr<bits<8> opc, RegisterClass SrcRC,
1605                     RegisterClass DstRC, Intrinsic Int, X86MemOperand x86memop,
1606                     PatFrag ld_frag, string asm, OpndItins itins,
1607                     bit Is2Addr = 1> {
1608   def rr : SI<opc, MRMSrcReg, (outs DstRC:$dst), (ins DstRC:$src1, SrcRC:$src2),
1609               !if(Is2Addr,
1610                   !strconcat(asm, "\t{$src2, $dst|$dst, $src2}"),
1611                   !strconcat(asm, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
1612               [(set DstRC:$dst, (Int DstRC:$src1, SrcRC:$src2))],
1613               itins.rr>, Sched<[itins.Sched]>;
1614   def rm : SI<opc, MRMSrcMem, (outs DstRC:$dst),
1615               (ins DstRC:$src1, x86memop:$src2),
1616               !if(Is2Addr,
1617                   !strconcat(asm, "\t{$src2, $dst|$dst, $src2}"),
1618                   !strconcat(asm, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
1619               [(set DstRC:$dst, (Int DstRC:$src1, (ld_frag addr:$src2)))],
1620               itins.rm>, Sched<[itins.Sched.Folded, ReadAfterLd]>;
1621 }
1622
1623 let Predicates = [UseAVX] in {
1624 defm VCVTSD2SI : sse12_cvt_sint<0x2D, VR128, GR32,
1625                   int_x86_sse2_cvtsd2si, sdmem, sse_load_f64, "cvtsd2si",
1626                   SSE_CVT_SD2SI>, XD, VEX, VEX_LIG;
1627 defm VCVTSD2SI64 : sse12_cvt_sint<0x2D, VR128, GR64,
1628                     int_x86_sse2_cvtsd2si64, sdmem, sse_load_f64, "cvtsd2si",
1629                     SSE_CVT_SD2SI>, XD, VEX, VEX_W, VEX_LIG;
1630 }
1631 defm CVTSD2SI : sse12_cvt_sint<0x2D, VR128, GR32, int_x86_sse2_cvtsd2si,
1632                  sdmem, sse_load_f64, "cvtsd2si", SSE_CVT_SD2SI>, XD;
1633 defm CVTSD2SI64 : sse12_cvt_sint<0x2D, VR128, GR64, int_x86_sse2_cvtsd2si64,
1634                    sdmem, sse_load_f64, "cvtsd2si", SSE_CVT_SD2SI>, XD, REX_W;
1635
1636
1637 let isCodeGenOnly = 1 in {
1638   let Predicates = [UseAVX] in {
1639   defm Int_VCVTSI2SS : sse12_cvt_sint_3addr<0x2A, GR32, VR128,
1640             int_x86_sse_cvtsi2ss, i32mem, loadi32, "cvtsi2ss{l}",
1641             SSE_CVT_Scalar, 0>, XS, VEX_4V;
1642   defm Int_VCVTSI2SS64 : sse12_cvt_sint_3addr<0x2A, GR64, VR128,
1643             int_x86_sse_cvtsi642ss, i64mem, loadi64, "cvtsi2ss{q}",
1644             SSE_CVT_Scalar, 0>, XS, VEX_4V,
1645             VEX_W;
1646   defm Int_VCVTSI2SD : sse12_cvt_sint_3addr<0x2A, GR32, VR128,
1647             int_x86_sse2_cvtsi2sd, i32mem, loadi32, "cvtsi2sd{l}",
1648             SSE_CVT_Scalar, 0>, XD, VEX_4V;
1649   defm Int_VCVTSI2SD64 : sse12_cvt_sint_3addr<0x2A, GR64, VR128,
1650             int_x86_sse2_cvtsi642sd, i64mem, loadi64, "cvtsi2sd{q}",
1651             SSE_CVT_Scalar, 0>, XD,
1652             VEX_4V, VEX_W;
1653   }
1654   let Constraints = "$src1 = $dst" in {
1655     defm Int_CVTSI2SS : sse12_cvt_sint_3addr<0x2A, GR32, VR128,
1656                           int_x86_sse_cvtsi2ss, i32mem, loadi32,
1657                           "cvtsi2ss{l}", SSE_CVT_Scalar>, XS;
1658     defm Int_CVTSI2SS64 : sse12_cvt_sint_3addr<0x2A, GR64, VR128,
1659                           int_x86_sse_cvtsi642ss, i64mem, loadi64,
1660                           "cvtsi2ss{q}", SSE_CVT_Scalar>, XS, REX_W;
1661     defm Int_CVTSI2SD : sse12_cvt_sint_3addr<0x2A, GR32, VR128,
1662                           int_x86_sse2_cvtsi2sd, i32mem, loadi32,
1663                           "cvtsi2sd{l}", SSE_CVT_Scalar>, XD;
1664     defm Int_CVTSI2SD64 : sse12_cvt_sint_3addr<0x2A, GR64, VR128,
1665                           int_x86_sse2_cvtsi642sd, i64mem, loadi64,
1666                           "cvtsi2sd{q}", SSE_CVT_Scalar>, XD, REX_W;
1667   }
1668 } // isCodeGenOnly = 1
1669
1670 /// SSE 1 Only
1671
1672 // Aliases for intrinsics
1673 let isCodeGenOnly = 1 in {
1674 let Predicates = [UseAVX] in {
1675 defm Int_VCVTTSS2SI : sse12_cvt_sint<0x2C, VR128, GR32, int_x86_sse_cvttss2si,
1676                                     ssmem, sse_load_f32, "cvttss2si",
1677                                     SSE_CVT_SS2SI_32>, XS, VEX;
1678 defm Int_VCVTTSS2SI64 : sse12_cvt_sint<0x2C, VR128, GR64,
1679                                    int_x86_sse_cvttss2si64, ssmem, sse_load_f32,
1680                                    "cvttss2si", SSE_CVT_SS2SI_64>,
1681                                    XS, VEX, VEX_W;
1682 defm Int_VCVTTSD2SI : sse12_cvt_sint<0x2C, VR128, GR32, int_x86_sse2_cvttsd2si,
1683                                     sdmem, sse_load_f64, "cvttsd2si",
1684                                     SSE_CVT_SD2SI>, XD, VEX;
1685 defm Int_VCVTTSD2SI64 : sse12_cvt_sint<0x2C, VR128, GR64,
1686                                   int_x86_sse2_cvttsd2si64, sdmem, sse_load_f64,
1687                                   "cvttsd2si", SSE_CVT_SD2SI>,
1688                                   XD, VEX, VEX_W;
1689 }
1690 defm Int_CVTTSS2SI : sse12_cvt_sint<0x2C, VR128, GR32, int_x86_sse_cvttss2si,
1691                                     ssmem, sse_load_f32, "cvttss2si",
1692                                     SSE_CVT_SS2SI_32>, XS;
1693 defm Int_CVTTSS2SI64 : sse12_cvt_sint<0x2C, VR128, GR64,
1694                                    int_x86_sse_cvttss2si64, ssmem, sse_load_f32,
1695                                    "cvttss2si", SSE_CVT_SS2SI_64>, XS, REX_W;
1696 defm Int_CVTTSD2SI : sse12_cvt_sint<0x2C, VR128, GR32, int_x86_sse2_cvttsd2si,
1697                                     sdmem, sse_load_f64, "cvttsd2si",
1698                                     SSE_CVT_SD2SI>, XD;
1699 defm Int_CVTTSD2SI64 : sse12_cvt_sint<0x2C, VR128, GR64,
1700                                   int_x86_sse2_cvttsd2si64, sdmem, sse_load_f64,
1701                                   "cvttsd2si", SSE_CVT_SD2SI>, XD, REX_W;
1702 } // isCodeGenOnly = 1
1703
1704 let Predicates = [UseAVX] in {
1705 defm VCVTSS2SI   : sse12_cvt_sint<0x2D, VR128, GR32, int_x86_sse_cvtss2si,
1706                                   ssmem, sse_load_f32, "cvtss2si",
1707                                   SSE_CVT_SS2SI_32>, XS, VEX, VEX_LIG;
1708 defm VCVTSS2SI64 : sse12_cvt_sint<0x2D, VR128, GR64, int_x86_sse_cvtss2si64,
1709                                   ssmem, sse_load_f32, "cvtss2si",
1710                                   SSE_CVT_SS2SI_64>, XS, VEX, VEX_W, VEX_LIG;
1711 }
1712 defm CVTSS2SI : sse12_cvt_sint<0x2D, VR128, GR32, int_x86_sse_cvtss2si,
1713                                ssmem, sse_load_f32, "cvtss2si",
1714                                SSE_CVT_SS2SI_32>, XS;
1715 defm CVTSS2SI64 : sse12_cvt_sint<0x2D, VR128, GR64, int_x86_sse_cvtss2si64,
1716                                  ssmem, sse_load_f32, "cvtss2si",
1717                                  SSE_CVT_SS2SI_64>, XS, REX_W;
1718
1719 defm VCVTDQ2PS   : sse12_cvt_p<0x5B, VR128, VR128, i128mem,
1720                                "vcvtdq2ps\t{$src, $dst|$dst, $src}",
1721                                SSEPackedSingle, SSE_CVT_PS>,
1722                                TB, VEX, Requires<[HasAVX]>;
1723 defm VCVTDQ2PSY  : sse12_cvt_p<0x5B, VR256, VR256, i256mem,
1724                                "vcvtdq2ps\t{$src, $dst|$dst, $src}",
1725                                SSEPackedSingle, SSE_CVT_PS>,
1726                                TB, VEX, VEX_L, Requires<[HasAVX]>;
1727
1728 defm CVTDQ2PS : sse12_cvt_p<0x5B, VR128, VR128, i128mem,
1729                             "cvtdq2ps\t{$src, $dst|$dst, $src}",
1730                             SSEPackedSingle, SSE_CVT_PS>,
1731                             TB, Requires<[UseSSE2]>;
1732
1733 let Predicates = [UseAVX] in {
1734 def : InstAlias<"vcvtss2si{l}\t{$src, $dst|$dst, $src}",
1735                 (VCVTSS2SIrr GR32:$dst, VR128:$src), 0>;
1736 def : InstAlias<"vcvtss2si{l}\t{$src, $dst|$dst, $src}",
1737                 (VCVTSS2SIrm GR32:$dst, ssmem:$src), 0>;
1738 def : InstAlias<"vcvtsd2si{l}\t{$src, $dst|$dst, $src}",
1739                 (VCVTSD2SIrr GR32:$dst, VR128:$src), 0>;
1740 def : InstAlias<"vcvtsd2si{l}\t{$src, $dst|$dst, $src}",
1741                 (VCVTSD2SIrm GR32:$dst, sdmem:$src), 0>;
1742 def : InstAlias<"vcvtss2si{q}\t{$src, $dst|$dst, $src}",
1743                 (VCVTSS2SI64rr GR64:$dst, VR128:$src), 0>;
1744 def : InstAlias<"vcvtss2si{q}\t{$src, $dst|$dst, $src}",
1745                 (VCVTSS2SI64rm GR64:$dst, ssmem:$src), 0>;
1746 def : InstAlias<"vcvtsd2si{q}\t{$src, $dst|$dst, $src}",
1747                 (VCVTSD2SI64rr GR64:$dst, VR128:$src), 0>;
1748 def : InstAlias<"vcvtsd2si{q}\t{$src, $dst|$dst, $src}",
1749                 (VCVTSD2SI64rm GR64:$dst, sdmem:$src), 0>;
1750 }
1751
1752 def : InstAlias<"cvtss2si{l}\t{$src, $dst|$dst, $src}",
1753                 (CVTSS2SIrr GR32:$dst, VR128:$src), 0>;
1754 def : InstAlias<"cvtss2si{l}\t{$src, $dst|$dst, $src}",
1755                 (CVTSS2SIrm GR32:$dst, ssmem:$src), 0>;
1756 def : InstAlias<"cvtsd2si{l}\t{$src, $dst|$dst, $src}",
1757                 (CVTSD2SIrr GR32:$dst, VR128:$src), 0>;
1758 def : InstAlias<"cvtsd2si{l}\t{$src, $dst|$dst, $src}",
1759                 (CVTSD2SIrm GR32:$dst, sdmem:$src), 0>;
1760 def : InstAlias<"cvtss2si{q}\t{$src, $dst|$dst, $src}",
1761                 (CVTSS2SI64rr GR64:$dst, VR128:$src), 0>;
1762 def : InstAlias<"cvtss2si{q}\t{$src, $dst|$dst, $src}",
1763                 (CVTSS2SI64rm GR64:$dst, ssmem:$src), 0>;
1764 def : InstAlias<"cvtsd2si{q}\t{$src, $dst|$dst, $src}",
1765                 (CVTSD2SI64rr GR64:$dst, VR128:$src), 0>;
1766 def : InstAlias<"cvtsd2si{q}\t{$src, $dst|$dst, $src}",
1767                 (CVTSD2SI64rm GR64:$dst, sdmem:$src)>;
1768
1769 /// SSE 2 Only
1770
1771 // Convert scalar double to scalar single
1772 let neverHasSideEffects = 1, Predicates = [UseAVX] in {
1773 def VCVTSD2SSrr  : VSDI<0x5A, MRMSrcReg, (outs FR32:$dst),
1774                        (ins FR64:$src1, FR64:$src2),
1775                       "cvtsd2ss\t{$src2, $src1, $dst|$dst, $src1, $src2}", [],
1776                       IIC_SSE_CVT_Scalar_RR>, VEX_4V, VEX_LIG,
1777                       Sched<[WriteCvtF2F]>;
1778 let mayLoad = 1 in
1779 def VCVTSD2SSrm  : I<0x5A, MRMSrcMem, (outs FR32:$dst),
1780                        (ins FR64:$src1, f64mem:$src2),
1781                       "vcvtsd2ss\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1782                       [], IIC_SSE_CVT_Scalar_RM>,
1783                       XD, Requires<[HasAVX, OptForSize]>, VEX_4V, VEX_LIG,
1784                       Sched<[WriteCvtF2FLd, ReadAfterLd]>;
1785 }
1786
1787 def : Pat<(f32 (fround FR64:$src)), (VCVTSD2SSrr FR64:$src, FR64:$src)>,
1788           Requires<[UseAVX]>;
1789
1790 def CVTSD2SSrr  : SDI<0x5A, MRMSrcReg, (outs FR32:$dst), (ins FR64:$src),
1791                       "cvtsd2ss\t{$src, $dst|$dst, $src}",
1792                       [(set FR32:$dst, (fround FR64:$src))],
1793                       IIC_SSE_CVT_Scalar_RR>, Sched<[WriteCvtF2F]>;
1794 def CVTSD2SSrm  : I<0x5A, MRMSrcMem, (outs FR32:$dst), (ins f64mem:$src),
1795                       "cvtsd2ss\t{$src, $dst|$dst, $src}",
1796                       [(set FR32:$dst, (fround (loadf64 addr:$src)))],
1797                       IIC_SSE_CVT_Scalar_RM>,
1798                       XD,
1799                   Requires<[UseSSE2, OptForSize]>, Sched<[WriteCvtF2FLd]>;
1800
1801 let isCodeGenOnly = 1 in {
1802 def Int_VCVTSD2SSrr: I<0x5A, MRMSrcReg,
1803                        (outs VR128:$dst), (ins VR128:$src1, VR128:$src2),
1804                        "vcvtsd2ss\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1805                        [(set VR128:$dst,
1806                          (int_x86_sse2_cvtsd2ss VR128:$src1, VR128:$src2))],
1807                        IIC_SSE_CVT_Scalar_RR>, XD, VEX_4V, Requires<[UseAVX]>,
1808                        Sched<[WriteCvtF2F]>;
1809 def Int_VCVTSD2SSrm: I<0x5A, MRMSrcReg,
1810                        (outs VR128:$dst), (ins VR128:$src1, sdmem:$src2),
1811                        "vcvtsd2ss\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1812                        [(set VR128:$dst, (int_x86_sse2_cvtsd2ss
1813                                           VR128:$src1, sse_load_f64:$src2))],
1814                        IIC_SSE_CVT_Scalar_RM>, XD, VEX_4V, Requires<[UseAVX]>,
1815                        Sched<[WriteCvtF2FLd, ReadAfterLd]>;
1816
1817 let Constraints = "$src1 = $dst" in {
1818 def Int_CVTSD2SSrr: I<0x5A, MRMSrcReg,
1819                        (outs VR128:$dst), (ins VR128:$src1, VR128:$src2),
1820                        "cvtsd2ss\t{$src2, $dst|$dst, $src2}",
1821                        [(set VR128:$dst,
1822                          (int_x86_sse2_cvtsd2ss VR128:$src1, VR128:$src2))],
1823                        IIC_SSE_CVT_Scalar_RR>, XD, Requires<[UseSSE2]>,
1824                        Sched<[WriteCvtF2F]>;
1825 def Int_CVTSD2SSrm: I<0x5A, MRMSrcReg,
1826                        (outs VR128:$dst), (ins VR128:$src1, sdmem:$src2),
1827                        "cvtsd2ss\t{$src2, $dst|$dst, $src2}",
1828                        [(set VR128:$dst, (int_x86_sse2_cvtsd2ss
1829                                           VR128:$src1, sse_load_f64:$src2))],
1830                        IIC_SSE_CVT_Scalar_RM>, XD, Requires<[UseSSE2]>,
1831                        Sched<[WriteCvtF2FLd, ReadAfterLd]>;
1832 }
1833 } // isCodeGenOnly = 1
1834
1835 // Convert scalar single to scalar double
1836 // SSE2 instructions with XS prefix
1837 let neverHasSideEffects = 1, Predicates = [UseAVX] in {
1838 def VCVTSS2SDrr : I<0x5A, MRMSrcReg, (outs FR64:$dst),
1839                     (ins FR32:$src1, FR32:$src2),
1840                     "vcvtss2sd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1841                     [], IIC_SSE_CVT_Scalar_RR>,
1842                     XS, Requires<[HasAVX]>, VEX_4V, VEX_LIG,
1843                     Sched<[WriteCvtF2F]>;
1844 let mayLoad = 1 in
1845 def VCVTSS2SDrm : I<0x5A, MRMSrcMem, (outs FR64:$dst),
1846                     (ins FR32:$src1, f32mem:$src2),
1847                     "vcvtss2sd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1848                     [], IIC_SSE_CVT_Scalar_RM>,
1849                     XS, VEX_4V, VEX_LIG, Requires<[HasAVX, OptForSize]>,
1850                     Sched<[WriteCvtF2FLd, ReadAfterLd]>;
1851 }
1852
1853 def : Pat<(f64 (fextend FR32:$src)),
1854     (VCVTSS2SDrr FR32:$src, FR32:$src)>, Requires<[UseAVX]>;
1855 def : Pat<(fextend (loadf32 addr:$src)),
1856     (VCVTSS2SDrm (f32 (IMPLICIT_DEF)), addr:$src)>, Requires<[UseAVX]>;
1857
1858 def : Pat<(extloadf32 addr:$src),
1859     (VCVTSS2SDrm (f32 (IMPLICIT_DEF)), addr:$src)>,
1860     Requires<[UseAVX, OptForSize]>;
1861 def : Pat<(extloadf32 addr:$src),
1862     (VCVTSS2SDrr (f32 (IMPLICIT_DEF)), (VMOVSSrm addr:$src))>,
1863     Requires<[UseAVX, OptForSpeed]>;
1864
1865 def CVTSS2SDrr : I<0x5A, MRMSrcReg, (outs FR64:$dst), (ins FR32:$src),
1866                    "cvtss2sd\t{$src, $dst|$dst, $src}",
1867                    [(set FR64:$dst, (fextend FR32:$src))],
1868                    IIC_SSE_CVT_Scalar_RR>, XS,
1869                  Requires<[UseSSE2]>, Sched<[WriteCvtF2F]>;
1870 def CVTSS2SDrm : I<0x5A, MRMSrcMem, (outs FR64:$dst), (ins f32mem:$src),
1871                    "cvtss2sd\t{$src, $dst|$dst, $src}",
1872                    [(set FR64:$dst, (extloadf32 addr:$src))],
1873                    IIC_SSE_CVT_Scalar_RM>, XS,
1874                  Requires<[UseSSE2, OptForSize]>, Sched<[WriteCvtF2FLd]>;
1875
1876 // extload f32 -> f64.  This matches load+fextend because we have a hack in
1877 // the isel (PreprocessForFPConvert) that can introduce loads after dag
1878 // combine.
1879 // Since these loads aren't folded into the fextend, we have to match it
1880 // explicitly here.
1881 def : Pat<(fextend (loadf32 addr:$src)),
1882           (CVTSS2SDrm addr:$src)>, Requires<[UseSSE2]>;
1883 def : Pat<(extloadf32 addr:$src),
1884           (CVTSS2SDrr (MOVSSrm addr:$src))>, Requires<[UseSSE2, OptForSpeed]>;
1885
1886 let isCodeGenOnly = 1 in {
1887 def Int_VCVTSS2SDrr: I<0x5A, MRMSrcReg,
1888                       (outs VR128:$dst), (ins VR128:$src1, VR128:$src2),
1889                     "vcvtss2sd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1890                     [(set VR128:$dst,
1891                       (int_x86_sse2_cvtss2sd VR128:$src1, VR128:$src2))],
1892                     IIC_SSE_CVT_Scalar_RR>, XS, VEX_4V, Requires<[UseAVX]>,
1893                     Sched<[WriteCvtF2F]>;
1894 def Int_VCVTSS2SDrm: I<0x5A, MRMSrcMem,
1895                       (outs VR128:$dst), (ins VR128:$src1, ssmem:$src2),
1896                     "vcvtss2sd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1897                     [(set VR128:$dst,
1898                       (int_x86_sse2_cvtss2sd VR128:$src1, sse_load_f32:$src2))],
1899                     IIC_SSE_CVT_Scalar_RM>, XS, VEX_4V, Requires<[UseAVX]>,
1900                     Sched<[WriteCvtF2FLd, ReadAfterLd]>;
1901 let Constraints = "$src1 = $dst" in { // SSE2 instructions with XS prefix
1902 def Int_CVTSS2SDrr: I<0x5A, MRMSrcReg,
1903                       (outs VR128:$dst), (ins VR128:$src1, VR128:$src2),
1904                     "cvtss2sd\t{$src2, $dst|$dst, $src2}",
1905                     [(set VR128:$dst,
1906                       (int_x86_sse2_cvtss2sd VR128:$src1, VR128:$src2))],
1907                     IIC_SSE_CVT_Scalar_RR>, XS, Requires<[UseSSE2]>,
1908                     Sched<[WriteCvtF2F]>;
1909 def Int_CVTSS2SDrm: I<0x5A, MRMSrcMem,
1910                       (outs VR128:$dst), (ins VR128:$src1, ssmem:$src2),
1911                     "cvtss2sd\t{$src2, $dst|$dst, $src2}",
1912                     [(set VR128:$dst,
1913                       (int_x86_sse2_cvtss2sd VR128:$src1, sse_load_f32:$src2))],
1914                     IIC_SSE_CVT_Scalar_RM>, XS, Requires<[UseSSE2]>,
1915                     Sched<[WriteCvtF2FLd, ReadAfterLd]>;
1916 }
1917 } // isCodeGenOnly = 1
1918
1919 // Convert packed single/double fp to doubleword
1920 def VCVTPS2DQrr : VPDI<0x5B, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1921                        "cvtps2dq\t{$src, $dst|$dst, $src}",
1922                        [(set VR128:$dst, (int_x86_sse2_cvtps2dq VR128:$src))],
1923                        IIC_SSE_CVT_PS_RR>, VEX, Sched<[WriteCvtF2I]>;
1924 def VCVTPS2DQrm : VPDI<0x5B, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1925                        "cvtps2dq\t{$src, $dst|$dst, $src}",
1926                        [(set VR128:$dst,
1927                          (int_x86_sse2_cvtps2dq (loadv4f32 addr:$src)))],
1928                        IIC_SSE_CVT_PS_RM>, VEX, Sched<[WriteCvtF2ILd]>;
1929 def VCVTPS2DQYrr : VPDI<0x5B, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
1930                         "cvtps2dq\t{$src, $dst|$dst, $src}",
1931                         [(set VR256:$dst,
1932                           (int_x86_avx_cvt_ps2dq_256 VR256:$src))],
1933                         IIC_SSE_CVT_PS_RR>, VEX, VEX_L, Sched<[WriteCvtF2I]>;
1934 def VCVTPS2DQYrm : VPDI<0x5B, MRMSrcMem, (outs VR256:$dst), (ins f256mem:$src),
1935                         "cvtps2dq\t{$src, $dst|$dst, $src}",
1936                         [(set VR256:$dst,
1937                           (int_x86_avx_cvt_ps2dq_256 (loadv8f32 addr:$src)))],
1938                         IIC_SSE_CVT_PS_RM>, VEX, VEX_L, Sched<[WriteCvtF2ILd]>;
1939 def CVTPS2DQrr : PDI<0x5B, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1940                      "cvtps2dq\t{$src, $dst|$dst, $src}",
1941                      [(set VR128:$dst, (int_x86_sse2_cvtps2dq VR128:$src))],
1942                      IIC_SSE_CVT_PS_RR>, Sched<[WriteCvtF2I]>;
1943 def CVTPS2DQrm : PDI<0x5B, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1944                      "cvtps2dq\t{$src, $dst|$dst, $src}",
1945                      [(set VR128:$dst,
1946                        (int_x86_sse2_cvtps2dq (memopv4f32 addr:$src)))],
1947                      IIC_SSE_CVT_PS_RM>, Sched<[WriteCvtF2ILd]>;
1948
1949
1950 // Convert Packed Double FP to Packed DW Integers
1951 let Predicates = [HasAVX] in {
1952 // The assembler can recognize rr 256-bit instructions by seeing a ymm
1953 // register, but the same isn't true when using memory operands instead.
1954 // Provide other assembly rr and rm forms to address this explicitly.
1955 def VCVTPD2DQrr  : SDI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1956                        "vcvtpd2dq\t{$src, $dst|$dst, $src}",
1957                        [(set VR128:$dst, (int_x86_sse2_cvtpd2dq VR128:$src))]>,
1958                        VEX, Sched<[WriteCvtF2I]>;
1959
1960 // XMM only
1961 def : InstAlias<"vcvtpd2dqx\t{$src, $dst|$dst, $src}",
1962                 (VCVTPD2DQrr VR128:$dst, VR128:$src)>;
1963 def VCVTPD2DQXrm : SDI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1964                        "vcvtpd2dqx\t{$src, $dst|$dst, $src}",
1965                        [(set VR128:$dst,
1966                          (int_x86_sse2_cvtpd2dq (loadv2f64 addr:$src)))]>, VEX,
1967                        Sched<[WriteCvtF2ILd]>;
1968
1969 // YMM only
1970 def VCVTPD2DQYrr : SDI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR256:$src),
1971                        "vcvtpd2dq{y}\t{$src, $dst|$dst, $src}",
1972                        [(set VR128:$dst,
1973                          (int_x86_avx_cvt_pd2dq_256 VR256:$src))]>, VEX, VEX_L,
1974                        Sched<[WriteCvtF2I]>;
1975 def VCVTPD2DQYrm : SDI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f256mem:$src),
1976                        "vcvtpd2dq{y}\t{$src, $dst|$dst, $src}",
1977                        [(set VR128:$dst,
1978                          (int_x86_avx_cvt_pd2dq_256 (loadv4f64 addr:$src)))]>,
1979                        VEX, VEX_L, Sched<[WriteCvtF2ILd]>;
1980 def : InstAlias<"vcvtpd2dq\t{$src, $dst|$dst, $src}",
1981                 (VCVTPD2DQYrr VR128:$dst, VR256:$src)>;
1982 }
1983
1984 def CVTPD2DQrm  : SDI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1985                       "cvtpd2dq\t{$src, $dst|$dst, $src}",
1986                       [(set VR128:$dst,
1987                         (int_x86_sse2_cvtpd2dq (memopv2f64 addr:$src)))],
1988                       IIC_SSE_CVT_PD_RM>, Sched<[WriteCvtF2ILd]>;
1989 def CVTPD2DQrr  : SDI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1990                       "cvtpd2dq\t{$src, $dst|$dst, $src}",
1991                       [(set VR128:$dst, (int_x86_sse2_cvtpd2dq VR128:$src))],
1992                       IIC_SSE_CVT_PD_RR>, Sched<[WriteCvtF2I]>;
1993
1994 // Convert with truncation packed single/double fp to doubleword
1995 // SSE2 packed instructions with XS prefix
1996 def VCVTTPS2DQrr : VS2SI<0x5B, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1997                          "cvttps2dq\t{$src, $dst|$dst, $src}",
1998                          [(set VR128:$dst,
1999                            (int_x86_sse2_cvttps2dq VR128:$src))],
2000                          IIC_SSE_CVT_PS_RR>, VEX, Sched<[WriteCvtF2I]>;
2001 def VCVTTPS2DQrm : VS2SI<0x5B, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
2002                          "cvttps2dq\t{$src, $dst|$dst, $src}",
2003                          [(set VR128:$dst, (int_x86_sse2_cvttps2dq
2004                                             (loadv4f32 addr:$src)))],
2005                          IIC_SSE_CVT_PS_RM>, VEX, Sched<[WriteCvtF2ILd]>;
2006 def VCVTTPS2DQYrr : VS2SI<0x5B, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
2007                           "cvttps2dq\t{$src, $dst|$dst, $src}",
2008                           [(set VR256:$dst,
2009                             (int_x86_avx_cvtt_ps2dq_256 VR256:$src))],
2010                           IIC_SSE_CVT_PS_RR>, VEX, VEX_L, Sched<[WriteCvtF2I]>;
2011 def VCVTTPS2DQYrm : VS2SI<0x5B, MRMSrcMem, (outs VR256:$dst), (ins f256mem:$src),
2012                           "cvttps2dq\t{$src, $dst|$dst, $src}",
2013                           [(set VR256:$dst, (int_x86_avx_cvtt_ps2dq_256
2014                                              (loadv8f32 addr:$src)))],
2015                           IIC_SSE_CVT_PS_RM>, VEX, VEX_L,
2016                           Sched<[WriteCvtF2ILd]>;
2017
2018 def CVTTPS2DQrr : S2SI<0x5B, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2019                        "cvttps2dq\t{$src, $dst|$dst, $src}",
2020                        [(set VR128:$dst, (int_x86_sse2_cvttps2dq VR128:$src))],
2021                        IIC_SSE_CVT_PS_RR>, Sched<[WriteCvtF2I]>;
2022 def CVTTPS2DQrm : S2SI<0x5B, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
2023                        "cvttps2dq\t{$src, $dst|$dst, $src}",
2024                        [(set VR128:$dst,
2025                          (int_x86_sse2_cvttps2dq (memopv4f32 addr:$src)))],
2026                        IIC_SSE_CVT_PS_RM>, Sched<[WriteCvtF2ILd]>;
2027
2028 let Predicates = [HasAVX] in {
2029   def : Pat<(v4f32 (sint_to_fp (v4i32 VR128:$src))),
2030             (VCVTDQ2PSrr VR128:$src)>;
2031   def : Pat<(v4f32 (sint_to_fp (bc_v4i32 (loadv2i64 addr:$src)))),
2032             (VCVTDQ2PSrm addr:$src)>;
2033
2034   def : Pat<(int_x86_sse2_cvtdq2ps VR128:$src),
2035             (VCVTDQ2PSrr VR128:$src)>;
2036   def : Pat<(int_x86_sse2_cvtdq2ps (bc_v4i32 (loadv2i64 addr:$src))),
2037             (VCVTDQ2PSrm addr:$src)>;
2038
2039   def : Pat<(v4i32 (fp_to_sint (v4f32 VR128:$src))),
2040             (VCVTTPS2DQrr VR128:$src)>;
2041   def : Pat<(v4i32 (fp_to_sint (loadv4f32 addr:$src))),
2042             (VCVTTPS2DQrm addr:$src)>;
2043
2044   def : Pat<(v8f32 (sint_to_fp (v8i32 VR256:$src))),
2045             (VCVTDQ2PSYrr VR256:$src)>;
2046   def : Pat<(v8f32 (sint_to_fp (bc_v8i32 (loadv4i64 addr:$src)))),
2047             (VCVTDQ2PSYrm addr:$src)>;
2048
2049   def : Pat<(v8i32 (fp_to_sint (v8f32 VR256:$src))),
2050             (VCVTTPS2DQYrr VR256:$src)>;
2051   def : Pat<(v8i32 (fp_to_sint (loadv8f32 addr:$src))),
2052             (VCVTTPS2DQYrm addr:$src)>;
2053 }
2054
2055 let Predicates = [UseSSE2] in {
2056   def : Pat<(v4f32 (sint_to_fp (v4i32 VR128:$src))),
2057             (CVTDQ2PSrr VR128:$src)>;
2058   def : Pat<(v4f32 (sint_to_fp (bc_v4i32 (memopv2i64 addr:$src)))),
2059             (CVTDQ2PSrm addr:$src)>;
2060
2061   def : Pat<(int_x86_sse2_cvtdq2ps VR128:$src),
2062             (CVTDQ2PSrr VR128:$src)>;
2063   def : Pat<(int_x86_sse2_cvtdq2ps (bc_v4i32 (memopv2i64 addr:$src))),
2064             (CVTDQ2PSrm addr:$src)>;
2065
2066   def : Pat<(v4i32 (fp_to_sint (v4f32 VR128:$src))),
2067             (CVTTPS2DQrr VR128:$src)>;
2068   def : Pat<(v4i32 (fp_to_sint (memopv4f32 addr:$src))),
2069             (CVTTPS2DQrm addr:$src)>;
2070 }
2071
2072 def VCVTTPD2DQrr : VPDI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2073                         "cvttpd2dq\t{$src, $dst|$dst, $src}",
2074                         [(set VR128:$dst,
2075                               (int_x86_sse2_cvttpd2dq VR128:$src))],
2076                               IIC_SSE_CVT_PD_RR>, VEX, Sched<[WriteCvtF2I]>;
2077
2078 // The assembler can recognize rr 256-bit instructions by seeing a ymm
2079 // register, but the same isn't true when using memory operands instead.
2080 // Provide other assembly rr and rm forms to address this explicitly.
2081
2082 // XMM only
2083 def : InstAlias<"vcvttpd2dqx\t{$src, $dst|$dst, $src}",
2084                 (VCVTTPD2DQrr VR128:$dst, VR128:$src)>;
2085 def VCVTTPD2DQXrm : VPDI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
2086                          "cvttpd2dqx\t{$src, $dst|$dst, $src}",
2087                          [(set VR128:$dst, (int_x86_sse2_cvttpd2dq
2088                                             (loadv2f64 addr:$src)))],
2089                          IIC_SSE_CVT_PD_RM>, VEX, Sched<[WriteCvtF2ILd]>;
2090
2091 // YMM only
2092 def VCVTTPD2DQYrr : VPDI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR256:$src),
2093                          "cvttpd2dq{y}\t{$src, $dst|$dst, $src}",
2094                          [(set VR128:$dst,
2095                            (int_x86_avx_cvtt_pd2dq_256 VR256:$src))],
2096                          IIC_SSE_CVT_PD_RR>, VEX, VEX_L, Sched<[WriteCvtF2I]>;
2097 def VCVTTPD2DQYrm : VPDI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f256mem:$src),
2098                          "cvttpd2dq{y}\t{$src, $dst|$dst, $src}",
2099                          [(set VR128:$dst,
2100                           (int_x86_avx_cvtt_pd2dq_256 (loadv4f64 addr:$src)))],
2101                          IIC_SSE_CVT_PD_RM>, VEX, VEX_L, Sched<[WriteCvtF2ILd]>;
2102 def : InstAlias<"vcvttpd2dq\t{$src, $dst|$dst, $src}",
2103                 (VCVTTPD2DQYrr VR128:$dst, VR256:$src)>;
2104
2105 let Predicates = [HasAVX] in {
2106   def : Pat<(v4i32 (fp_to_sint (v4f64 VR256:$src))),
2107             (VCVTTPD2DQYrr VR256:$src)>;
2108   def : Pat<(v4i32 (fp_to_sint (loadv4f64 addr:$src))),
2109             (VCVTTPD2DQYrm addr:$src)>;
2110 } // Predicates = [HasAVX]
2111
2112 def CVTTPD2DQrr : PDI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2113                       "cvttpd2dq\t{$src, $dst|$dst, $src}",
2114                       [(set VR128:$dst, (int_x86_sse2_cvttpd2dq VR128:$src))],
2115                       IIC_SSE_CVT_PD_RR>, Sched<[WriteCvtF2I]>;
2116 def CVTTPD2DQrm : PDI<0xE6, MRMSrcMem, (outs VR128:$dst),(ins f128mem:$src),
2117                       "cvttpd2dq\t{$src, $dst|$dst, $src}",
2118                       [(set VR128:$dst, (int_x86_sse2_cvttpd2dq
2119                                         (memopv2f64 addr:$src)))],
2120                                         IIC_SSE_CVT_PD_RM>,
2121                       Sched<[WriteCvtF2ILd]>;
2122
2123 // Convert packed single to packed double
2124 let Predicates = [HasAVX] in {
2125                   // SSE2 instructions without OpSize prefix
2126 def VCVTPS2PDrr : I<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2127                      "vcvtps2pd\t{$src, $dst|$dst, $src}",
2128                      [(set VR128:$dst, (int_x86_sse2_cvtps2pd VR128:$src))],
2129                      IIC_SSE_CVT_PD_RR>, TB, VEX, Sched<[WriteCvtF2F]>;
2130 def VCVTPS2PDrm : I<0x5A, MRMSrcMem, (outs VR128:$dst), (ins f64mem:$src),
2131                     "vcvtps2pd\t{$src, $dst|$dst, $src}",
2132                     [(set VR128:$dst, (v2f64 (extloadv2f32 addr:$src)))],
2133                     IIC_SSE_CVT_PD_RM>, TB, VEX, Sched<[WriteCvtF2FLd]>;
2134 def VCVTPS2PDYrr : I<0x5A, MRMSrcReg, (outs VR256:$dst), (ins VR128:$src),
2135                      "vcvtps2pd\t{$src, $dst|$dst, $src}",
2136                      [(set VR256:$dst,
2137                        (int_x86_avx_cvt_ps2_pd_256 VR128:$src))],
2138                      IIC_SSE_CVT_PD_RR>, TB, VEX, VEX_L, Sched<[WriteCvtF2F]>;
2139 def VCVTPS2PDYrm : I<0x5A, MRMSrcMem, (outs VR256:$dst), (ins f128mem:$src),
2140                      "vcvtps2pd\t{$src, $dst|$dst, $src}",
2141                      [(set VR256:$dst,
2142                        (int_x86_avx_cvt_ps2_pd_256 (loadv4f32 addr:$src)))],
2143                      IIC_SSE_CVT_PD_RM>, TB, VEX, VEX_L, Sched<[WriteCvtF2FLd]>;
2144 }
2145
2146 let Predicates = [UseSSE2] in {
2147 def CVTPS2PDrr : I<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2148                        "cvtps2pd\t{$src, $dst|$dst, $src}",
2149                        [(set VR128:$dst, (int_x86_sse2_cvtps2pd VR128:$src))],
2150                        IIC_SSE_CVT_PD_RR>, TB, Sched<[WriteCvtF2F]>;
2151 def CVTPS2PDrm : I<0x5A, MRMSrcMem, (outs VR128:$dst), (ins f64mem:$src),
2152                    "cvtps2pd\t{$src, $dst|$dst, $src}",
2153                    [(set VR128:$dst, (v2f64 (extloadv2f32 addr:$src)))],
2154                    IIC_SSE_CVT_PD_RM>, TB, Sched<[WriteCvtF2FLd]>;
2155 }
2156
2157 // Convert Packed DW Integers to Packed Double FP
2158 let Predicates = [HasAVX] in {
2159 let neverHasSideEffects = 1, mayLoad = 1 in
2160 def VCVTDQ2PDrm  : S2SI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
2161                      "vcvtdq2pd\t{$src, $dst|$dst, $src}",
2162                      []>, VEX, Sched<[WriteCvtI2FLd]>;
2163 def VCVTDQ2PDrr  : S2SI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2164                      "vcvtdq2pd\t{$src, $dst|$dst, $src}",
2165                      [(set VR128:$dst,
2166                        (int_x86_sse2_cvtdq2pd VR128:$src))]>, VEX,
2167                    Sched<[WriteCvtI2F]>;
2168 def VCVTDQ2PDYrm  : S2SI<0xE6, MRMSrcMem, (outs VR256:$dst), (ins i128mem:$src),
2169                      "vcvtdq2pd\t{$src, $dst|$dst, $src}",
2170                      [(set VR256:$dst,
2171                        (int_x86_avx_cvtdq2_pd_256
2172                         (bitconvert (loadv2i64 addr:$src))))]>, VEX, VEX_L,
2173                     Sched<[WriteCvtI2FLd]>;
2174 def VCVTDQ2PDYrr  : S2SI<0xE6, MRMSrcReg, (outs VR256:$dst), (ins VR128:$src),
2175                      "vcvtdq2pd\t{$src, $dst|$dst, $src}",
2176                      [(set VR256:$dst,
2177                        (int_x86_avx_cvtdq2_pd_256 VR128:$src))]>, VEX, VEX_L,
2178                     Sched<[WriteCvtI2F]>;
2179 }
2180
2181 let neverHasSideEffects = 1, mayLoad = 1 in
2182 def CVTDQ2PDrm  : S2SI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
2183                        "cvtdq2pd\t{$src, $dst|$dst, $src}", [],
2184                        IIC_SSE_CVT_PD_RR>, Sched<[WriteCvtI2FLd]>;
2185 def CVTDQ2PDrr  : S2SI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2186                        "cvtdq2pd\t{$src, $dst|$dst, $src}",
2187                        [(set VR128:$dst, (int_x86_sse2_cvtdq2pd VR128:$src))],
2188                        IIC_SSE_CVT_PD_RM>, Sched<[WriteCvtI2F]>;
2189
2190 // AVX 256-bit register conversion intrinsics
2191 let Predicates = [HasAVX] in {
2192   def : Pat<(v4f64 (sint_to_fp (v4i32 VR128:$src))),
2193             (VCVTDQ2PDYrr VR128:$src)>;
2194   def : Pat<(v4f64 (sint_to_fp (bc_v4i32 (loadv2i64 addr:$src)))),
2195             (VCVTDQ2PDYrm addr:$src)>;
2196 } // Predicates = [HasAVX]
2197
2198 // Convert packed double to packed single
2199 // The assembler can recognize rr 256-bit instructions by seeing a ymm
2200 // register, but the same isn't true when using memory operands instead.
2201 // Provide other assembly rr and rm forms to address this explicitly.
2202 def VCVTPD2PSrr : VPDI<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2203                        "cvtpd2ps\t{$src, $dst|$dst, $src}",
2204                        [(set VR128:$dst, (int_x86_sse2_cvtpd2ps VR128:$src))],
2205                        IIC_SSE_CVT_PD_RR>, VEX, Sched<[WriteCvtF2F]>;
2206
2207 // XMM only
2208 def : InstAlias<"vcvtpd2psx\t{$src, $dst|$dst, $src}",
2209                 (VCVTPD2PSrr VR128:$dst, VR128:$src)>;
2210 def VCVTPD2PSXrm : VPDI<0x5A, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
2211                         "cvtpd2psx\t{$src, $dst|$dst, $src}",
2212                         [(set VR128:$dst,
2213                           (int_x86_sse2_cvtpd2ps (loadv2f64 addr:$src)))],
2214                         IIC_SSE_CVT_PD_RM>, VEX, Sched<[WriteCvtF2FLd]>;
2215
2216 // YMM only
2217 def VCVTPD2PSYrr : VPDI<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR256:$src),
2218                         "cvtpd2ps{y}\t{$src, $dst|$dst, $src}",
2219                         [(set VR128:$dst,
2220                           (int_x86_avx_cvt_pd2_ps_256 VR256:$src))],
2221                         IIC_SSE_CVT_PD_RR>, VEX, VEX_L, Sched<[WriteCvtF2F]>;
2222 def VCVTPD2PSYrm : VPDI<0x5A, MRMSrcMem, (outs VR128:$dst), (ins f256mem:$src),
2223                         "cvtpd2ps{y}\t{$src, $dst|$dst, $src}",
2224                         [(set VR128:$dst,
2225                           (int_x86_avx_cvt_pd2_ps_256 (loadv4f64 addr:$src)))],
2226                         IIC_SSE_CVT_PD_RM>, VEX, VEX_L, Sched<[WriteCvtF2FLd]>;
2227 def : InstAlias<"vcvtpd2ps\t{$src, $dst|$dst, $src}",
2228                 (VCVTPD2PSYrr VR128:$dst, VR256:$src)>;
2229
2230 def CVTPD2PSrr : PDI<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2231                      "cvtpd2ps\t{$src, $dst|$dst, $src}",
2232                      [(set VR128:$dst, (int_x86_sse2_cvtpd2ps VR128:$src))],
2233                      IIC_SSE_CVT_PD_RR>, Sched<[WriteCvtF2F]>;
2234 def CVTPD2PSrm : PDI<0x5A, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
2235                      "cvtpd2ps\t{$src, $dst|$dst, $src}",
2236                      [(set VR128:$dst,
2237                        (int_x86_sse2_cvtpd2ps (memopv2f64 addr:$src)))],
2238                      IIC_SSE_CVT_PD_RM>, Sched<[WriteCvtF2FLd]>;
2239
2240
2241 // AVX 256-bit register conversion intrinsics
2242 // FIXME: Migrate SSE conversion intrinsics matching to use patterns as below
2243 // whenever possible to avoid declaring two versions of each one.
2244 let Predicates = [HasAVX] in {
2245   def : Pat<(int_x86_avx_cvtdq2_ps_256 VR256:$src),
2246             (VCVTDQ2PSYrr VR256:$src)>;
2247   def : Pat<(int_x86_avx_cvtdq2_ps_256 (bitconvert (loadv4i64 addr:$src))),
2248             (VCVTDQ2PSYrm addr:$src)>;
2249
2250   // Match fround and fextend for 128/256-bit conversions
2251   def : Pat<(v4f32 (X86vfpround (v2f64 VR128:$src))),
2252             (VCVTPD2PSrr VR128:$src)>;
2253   def : Pat<(v4f32 (X86vfpround (loadv2f64 addr:$src))),
2254             (VCVTPD2PSXrm addr:$src)>;
2255   def : Pat<(v4f32 (fround (v4f64 VR256:$src))),
2256             (VCVTPD2PSYrr VR256:$src)>;
2257   def : Pat<(v4f32 (fround (loadv4f64 addr:$src))),
2258             (VCVTPD2PSYrm addr:$src)>;
2259
2260   def : Pat<(v2f64 (X86vfpext (v4f32 VR128:$src))),
2261             (VCVTPS2PDrr VR128:$src)>;
2262   def : Pat<(v4f64 (fextend (v4f32 VR128:$src))),
2263             (VCVTPS2PDYrr VR128:$src)>;
2264   def : Pat<(v4f64 (extloadv4f32 addr:$src)),
2265             (VCVTPS2PDYrm addr:$src)>;
2266 }
2267
2268 let Predicates = [UseSSE2] in {
2269   // Match fround and fextend for 128 conversions
2270   def : Pat<(v4f32 (X86vfpround (v2f64 VR128:$src))),
2271             (CVTPD2PSrr VR128:$src)>;
2272   def : Pat<(v4f32 (X86vfpround (memopv2f64 addr:$src))),
2273             (CVTPD2PSrm addr:$src)>;
2274
2275   def : Pat<(v2f64 (X86vfpext (v4f32 VR128:$src))),
2276             (CVTPS2PDrr VR128:$src)>;
2277 }
2278
2279 //===----------------------------------------------------------------------===//
2280 // SSE 1 & 2 - Compare Instructions
2281 //===----------------------------------------------------------------------===//
2282
2283 // sse12_cmp_scalar - sse 1 & 2 compare scalar instructions
2284 multiclass sse12_cmp_scalar<RegisterClass RC, X86MemOperand x86memop,
2285                             Operand CC, SDNode OpNode, ValueType VT,
2286                             PatFrag ld_frag, string asm, string asm_alt,
2287                             OpndItins itins> {
2288   def rr : SIi8<0xC2, MRMSrcReg,
2289                 (outs RC:$dst), (ins RC:$src1, RC:$src2, CC:$cc), asm,
2290                 [(set RC:$dst, (OpNode (VT RC:$src1), RC:$src2, imm:$cc))],
2291                 itins.rr>, Sched<[itins.Sched]>;
2292   def rm : SIi8<0xC2, MRMSrcMem,
2293                 (outs RC:$dst), (ins RC:$src1, x86memop:$src2, CC:$cc), asm,
2294                 [(set RC:$dst, (OpNode (VT RC:$src1),
2295                                          (ld_frag addr:$src2), imm:$cc))],
2296                                          itins.rm>,
2297            Sched<[itins.Sched.Folded, ReadAfterLd]>;
2298
2299   // Accept explicit immediate argument form instead of comparison code.
2300   let neverHasSideEffects = 1 in {
2301     def rr_alt : SIi8<0xC2, MRMSrcReg, (outs RC:$dst),
2302                       (ins RC:$src1, RC:$src2, i8imm:$cc), asm_alt, [],
2303                       IIC_SSE_ALU_F32S_RR>, Sched<[itins.Sched]>;
2304     let mayLoad = 1 in
2305     def rm_alt : SIi8<0xC2, MRMSrcMem, (outs RC:$dst),
2306                       (ins RC:$src1, x86memop:$src2, i8imm:$cc), asm_alt, [],
2307                       IIC_SSE_ALU_F32S_RM>,
2308                       Sched<[itins.Sched.Folded, ReadAfterLd]>;
2309   }
2310 }
2311
2312 defm VCMPSS : sse12_cmp_scalar<FR32, f32mem, AVXCC, X86cmps, f32, loadf32,
2313                  "cmp${cc}ss\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2314                  "cmpss\t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}",
2315                  SSE_ALU_F32S>,
2316                  XS, VEX_4V, VEX_LIG;
2317 defm VCMPSD : sse12_cmp_scalar<FR64, f64mem, AVXCC, X86cmps, f64, loadf64,
2318                  "cmp${cc}sd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2319                  "cmpsd\t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}",
2320                  SSE_ALU_F32S>, // same latency as 32 bit compare
2321                  XD, VEX_4V, VEX_LIG;
2322
2323 let Constraints = "$src1 = $dst" in {
2324   defm CMPSS : sse12_cmp_scalar<FR32, f32mem, SSECC, X86cmps, f32, loadf32,
2325                   "cmp${cc}ss\t{$src2, $dst|$dst, $src2}",
2326                   "cmpss\t{$cc, $src2, $dst|$dst, $src2, $cc}", SSE_ALU_F32S>,
2327                   XS;
2328   defm CMPSD : sse12_cmp_scalar<FR64, f64mem, SSECC, X86cmps, f64, loadf64,
2329                   "cmp${cc}sd\t{$src2, $dst|$dst, $src2}",
2330                   "cmpsd\t{$cc, $src2, $dst|$dst, $src2, $cc}",
2331                   SSE_ALU_F64S>,
2332                   XD;
2333 }
2334
2335 multiclass sse12_cmp_scalar_int<X86MemOperand x86memop, Operand CC,
2336                          Intrinsic Int, string asm, OpndItins itins> {
2337   def rr : SIi8<0xC2, MRMSrcReg, (outs VR128:$dst),
2338                       (ins VR128:$src1, VR128:$src, CC:$cc), asm,
2339                         [(set VR128:$dst, (Int VR128:$src1,
2340                                                VR128:$src, imm:$cc))],
2341                                                itins.rr>,
2342            Sched<[itins.Sched]>;
2343   def rm : SIi8<0xC2, MRMSrcMem, (outs VR128:$dst),
2344                       (ins VR128:$src1, x86memop:$src, CC:$cc), asm,
2345                         [(set VR128:$dst, (Int VR128:$src1,
2346                                                (load addr:$src), imm:$cc))],
2347                                                itins.rm>,
2348            Sched<[itins.Sched.Folded, ReadAfterLd]>;
2349 }
2350
2351 let isCodeGenOnly = 1 in {
2352   // Aliases to match intrinsics which expect XMM operand(s).
2353   defm Int_VCMPSS  : sse12_cmp_scalar_int<f32mem, AVXCC, int_x86_sse_cmp_ss,
2354                        "cmp${cc}ss\t{$src, $src1, $dst|$dst, $src1, $src}",
2355                        SSE_ALU_F32S>,
2356                        XS, VEX_4V;
2357   defm Int_VCMPSD  : sse12_cmp_scalar_int<f64mem, AVXCC, int_x86_sse2_cmp_sd,
2358                        "cmp${cc}sd\t{$src, $src1, $dst|$dst, $src1, $src}",
2359                        SSE_ALU_F32S>, // same latency as f32
2360                        XD, VEX_4V;
2361   let Constraints = "$src1 = $dst" in {
2362     defm Int_CMPSS  : sse12_cmp_scalar_int<f32mem, SSECC, int_x86_sse_cmp_ss,
2363                          "cmp${cc}ss\t{$src, $dst|$dst, $src}",
2364                          SSE_ALU_F32S>, XS;
2365     defm Int_CMPSD  : sse12_cmp_scalar_int<f64mem, SSECC, int_x86_sse2_cmp_sd,
2366                          "cmp${cc}sd\t{$src, $dst|$dst, $src}",
2367                          SSE_ALU_F64S>,
2368                          XD;
2369 }
2370 }
2371
2372
2373 // sse12_ord_cmp - Unordered/Ordered scalar fp compare and set EFLAGS
2374 multiclass sse12_ord_cmp<bits<8> opc, RegisterClass RC, SDNode OpNode,
2375                             ValueType vt, X86MemOperand x86memop,
2376                             PatFrag ld_frag, string OpcodeStr> {
2377   def rr: SI<opc, MRMSrcReg, (outs), (ins RC:$src1, RC:$src2),
2378                      !strconcat(OpcodeStr, "\t{$src2, $src1|$src1, $src2}"),
2379                      [(set EFLAGS, (OpNode (vt RC:$src1), RC:$src2))],
2380                      IIC_SSE_COMIS_RR>,
2381           Sched<[WriteFAdd]>;
2382   def rm: SI<opc, MRMSrcMem, (outs), (ins RC:$src1, x86memop:$src2),
2383                      !strconcat(OpcodeStr, "\t{$src2, $src1|$src1, $src2}"),
2384                      [(set EFLAGS, (OpNode (vt RC:$src1),
2385                                            (ld_frag addr:$src2)))],
2386                                            IIC_SSE_COMIS_RM>,
2387           Sched<[WriteFAddLd, ReadAfterLd]>;
2388 }
2389
2390 let Defs = [EFLAGS] in {
2391   defm VUCOMISS : sse12_ord_cmp<0x2E, FR32, X86cmp, f32, f32mem, loadf32,
2392                                   "ucomiss">, TB, VEX, VEX_LIG;
2393   defm VUCOMISD : sse12_ord_cmp<0x2E, FR64, X86cmp, f64, f64mem, loadf64,
2394                                   "ucomisd">, TB, OpSize, VEX, VEX_LIG;
2395   let Pattern = []<dag> in {
2396     defm VCOMISS  : sse12_ord_cmp<0x2F, VR128, undef, v4f32, f128mem, load,
2397                                     "comiss">, TB, VEX, VEX_LIG;
2398     defm VCOMISD  : sse12_ord_cmp<0x2F, VR128, undef, v2f64, f128mem, load,
2399                                     "comisd">, TB, OpSize, VEX, VEX_LIG;
2400   }
2401
2402   let isCodeGenOnly = 1 in {
2403     defm Int_VUCOMISS  : sse12_ord_cmp<0x2E, VR128, X86ucomi, v4f32, f128mem,
2404                               load, "ucomiss">, TB, VEX;
2405     defm Int_VUCOMISD  : sse12_ord_cmp<0x2E, VR128, X86ucomi, v2f64, f128mem,
2406                               load, "ucomisd">, TB, OpSize, VEX;
2407
2408     defm Int_VCOMISS  : sse12_ord_cmp<0x2F, VR128, X86comi, v4f32, f128mem,
2409                               load, "comiss">, TB, VEX;
2410     defm Int_VCOMISD  : sse12_ord_cmp<0x2F, VR128, X86comi, v2f64, f128mem,
2411                               load, "comisd">, TB, OpSize, VEX;
2412   }
2413   defm UCOMISS  : sse12_ord_cmp<0x2E, FR32, X86cmp, f32, f32mem, loadf32,
2414                                   "ucomiss">, TB;
2415   defm UCOMISD  : sse12_ord_cmp<0x2E, FR64, X86cmp, f64, f64mem, loadf64,
2416                                   "ucomisd">, TB, OpSize;
2417
2418   let Pattern = []<dag> in {
2419     defm COMISS  : sse12_ord_cmp<0x2F, VR128, undef, v4f32, f128mem, load,
2420                                     "comiss">, TB;
2421     defm COMISD  : sse12_ord_cmp<0x2F, VR128, undef, v2f64, f128mem, load,
2422                                     "comisd">, TB, OpSize;
2423   }
2424
2425   let isCodeGenOnly = 1 in {
2426     defm Int_UCOMISS  : sse12_ord_cmp<0x2E, VR128, X86ucomi, v4f32, f128mem,
2427                                 load, "ucomiss">, TB;
2428     defm Int_UCOMISD  : sse12_ord_cmp<0x2E, VR128, X86ucomi, v2f64, f128mem,
2429                                 load, "ucomisd">, TB, OpSize;
2430
2431     defm Int_COMISS  : sse12_ord_cmp<0x2F, VR128, X86comi, v4f32, f128mem, load,
2432                                     "comiss">, TB;
2433     defm Int_COMISD  : sse12_ord_cmp<0x2F, VR128, X86comi, v2f64, f128mem, load,
2434                                     "comisd">, TB, OpSize;
2435   }
2436 } // Defs = [EFLAGS]
2437
2438 // sse12_cmp_packed - sse 1 & 2 compare packed instructions
2439 multiclass sse12_cmp_packed<RegisterClass RC, X86MemOperand x86memop,
2440                             Operand CC, Intrinsic Int, string asm,
2441                             string asm_alt, Domain d,
2442                             OpndItins itins = SSE_ALU_F32P> {
2443   def rri : PIi8<0xC2, MRMSrcReg,
2444              (outs RC:$dst), (ins RC:$src1, RC:$src2, CC:$cc), asm,
2445              [(set RC:$dst, (Int RC:$src1, RC:$src2, imm:$cc))],
2446              itins.rr, d>,
2447             Sched<[WriteFAdd]>;
2448   def rmi : PIi8<0xC2, MRMSrcMem,
2449              (outs RC:$dst), (ins RC:$src1, x86memop:$src2, CC:$cc), asm,
2450              [(set RC:$dst, (Int RC:$src1, (memop addr:$src2), imm:$cc))],
2451              itins.rm, d>,
2452             Sched<[WriteFAddLd, ReadAfterLd]>;
2453
2454   // Accept explicit immediate argument form instead of comparison code.
2455   let neverHasSideEffects = 1 in {
2456     def rri_alt : PIi8<0xC2, MRMSrcReg,
2457                (outs RC:$dst), (ins RC:$src1, RC:$src2, i8imm:$cc),
2458                asm_alt, [], itins.rr, d>, Sched<[WriteFAdd]>;
2459     def rmi_alt : PIi8<0xC2, MRMSrcMem,
2460                (outs RC:$dst), (ins RC:$src1, x86memop:$src2, i8imm:$cc),
2461                asm_alt, [], itins.rm, d>,
2462                Sched<[WriteFAddLd, ReadAfterLd]>;
2463   }
2464 }
2465
2466 defm VCMPPS : sse12_cmp_packed<VR128, f128mem, AVXCC, int_x86_sse_cmp_ps,
2467                "cmp${cc}ps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2468                "cmpps\t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}",
2469                SSEPackedSingle>, TB, VEX_4V;
2470 defm VCMPPD : sse12_cmp_packed<VR128, f128mem, AVXCC, int_x86_sse2_cmp_pd,
2471                "cmp${cc}pd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2472                "cmppd\t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}",
2473                SSEPackedDouble>, TB, OpSize, VEX_4V;
2474 defm VCMPPSY : sse12_cmp_packed<VR256, f256mem, AVXCC, int_x86_avx_cmp_ps_256,
2475                "cmp${cc}ps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2476                "cmpps\t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}",
2477                SSEPackedSingle>, TB, VEX_4V, VEX_L;
2478 defm VCMPPDY : sse12_cmp_packed<VR256, f256mem, AVXCC, int_x86_avx_cmp_pd_256,
2479                "cmp${cc}pd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2480                "cmppd\t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}",
2481                SSEPackedDouble>, TB, OpSize, VEX_4V, VEX_L;
2482 let Constraints = "$src1 = $dst" in {
2483   defm CMPPS : sse12_cmp_packed<VR128, f128mem, SSECC, int_x86_sse_cmp_ps,
2484                  "cmp${cc}ps\t{$src2, $dst|$dst, $src2}",
2485                  "cmpps\t{$cc, $src2, $dst|$dst, $src2, $cc}",
2486                  SSEPackedSingle, SSE_ALU_F32P>, TB;
2487   defm CMPPD : sse12_cmp_packed<VR128, f128mem, SSECC, int_x86_sse2_cmp_pd,
2488                  "cmp${cc}pd\t{$src2, $dst|$dst, $src2}",
2489                  "cmppd\t{$cc, $src2, $dst|$dst, $src2, $cc}",
2490                  SSEPackedDouble, SSE_ALU_F64P>, TB, OpSize;
2491 }
2492
2493 let Predicates = [HasAVX] in {
2494 def : Pat<(v4i32 (X86cmpp (v4f32 VR128:$src1), VR128:$src2, imm:$cc)),
2495           (VCMPPSrri (v4f32 VR128:$src1), (v4f32 VR128:$src2), imm:$cc)>;
2496 def : Pat<(v4i32 (X86cmpp (v4f32 VR128:$src1), (memop addr:$src2), imm:$cc)),
2497           (VCMPPSrmi (v4f32 VR128:$src1), addr:$src2, imm:$cc)>;
2498 def : Pat<(v2i64 (X86cmpp (v2f64 VR128:$src1), VR128:$src2, imm:$cc)),
2499           (VCMPPDrri VR128:$src1, VR128:$src2, imm:$cc)>;
2500 def : Pat<(v2i64 (X86cmpp (v2f64 VR128:$src1), (memop addr:$src2), imm:$cc)),
2501           (VCMPPDrmi VR128:$src1, addr:$src2, imm:$cc)>;
2502
2503 def : Pat<(v8i32 (X86cmpp (v8f32 VR256:$src1), VR256:$src2, imm:$cc)),
2504           (VCMPPSYrri (v8f32 VR256:$src1), (v8f32 VR256:$src2), imm:$cc)>;
2505 def : Pat<(v8i32 (X86cmpp (v8f32 VR256:$src1), (memop addr:$src2), imm:$cc)),
2506           (VCMPPSYrmi (v8f32 VR256:$src1), addr:$src2, imm:$cc)>;
2507 def : Pat<(v4i64 (X86cmpp (v4f64 VR256:$src1), VR256:$src2, imm:$cc)),
2508           (VCMPPDYrri VR256:$src1, VR256:$src2, imm:$cc)>;
2509 def : Pat<(v4i64 (X86cmpp (v4f64 VR256:$src1), (memop addr:$src2), imm:$cc)),
2510           (VCMPPDYrmi VR256:$src1, addr:$src2, imm:$cc)>;
2511 }
2512
2513 let Predicates = [UseSSE1] in {
2514 def : Pat<(v4i32 (X86cmpp (v4f32 VR128:$src1), VR128:$src2, imm:$cc)),
2515           (CMPPSrri (v4f32 VR128:$src1), (v4f32 VR128:$src2), imm:$cc)>;
2516 def : Pat<(v4i32 (X86cmpp (v4f32 VR128:$src1), (memop addr:$src2), imm:$cc)),
2517           (CMPPSrmi (v4f32 VR128:$src1), addr:$src2, imm:$cc)>;
2518 }
2519
2520 let Predicates = [UseSSE2] in {
2521 def : Pat<(v2i64 (X86cmpp (v2f64 VR128:$src1), VR128:$src2, imm:$cc)),
2522           (CMPPDrri VR128:$src1, VR128:$src2, imm:$cc)>;
2523 def : Pat<(v2i64 (X86cmpp (v2f64 VR128:$src1), (memop addr:$src2), imm:$cc)),
2524           (CMPPDrmi VR128:$src1, addr:$src2, imm:$cc)>;
2525 }
2526
2527 //===----------------------------------------------------------------------===//
2528 // SSE 1 & 2 - Shuffle Instructions
2529 //===----------------------------------------------------------------------===//
2530
2531 /// sse12_shuffle - sse 1 & 2 shuffle instructions
2532 multiclass sse12_shuffle<RegisterClass RC, X86MemOperand x86memop,
2533                          ValueType vt, string asm, PatFrag mem_frag,
2534                          Domain d, bit IsConvertibleToThreeAddress = 0> {
2535   def rmi : PIi8<0xC6, MRMSrcMem, (outs RC:$dst),
2536                    (ins RC:$src1, x86memop:$src2, i8imm:$src3), asm,
2537                    [(set RC:$dst, (vt (X86Shufp RC:$src1, (mem_frag addr:$src2),
2538                                        (i8 imm:$src3))))], IIC_SSE_SHUFP, d>,
2539             Sched<[WriteShuffleLd, ReadAfterLd]>;
2540   let isConvertibleToThreeAddress = IsConvertibleToThreeAddress in
2541     def rri : PIi8<0xC6, MRMSrcReg, (outs RC:$dst),
2542                    (ins RC:$src1, RC:$src2, i8imm:$src3), asm,
2543                    [(set RC:$dst, (vt (X86Shufp RC:$src1, RC:$src2,
2544                                        (i8 imm:$src3))))], IIC_SSE_SHUFP, d>,
2545               Sched<[WriteShuffle]>;
2546 }
2547
2548 defm VSHUFPS  : sse12_shuffle<VR128, f128mem, v4f32,
2549            "shufps\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
2550            loadv4f32, SSEPackedSingle>, TB, VEX_4V;
2551 defm VSHUFPSY : sse12_shuffle<VR256, f256mem, v8f32,
2552            "shufps\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
2553            loadv8f32, SSEPackedSingle>, TB, VEX_4V, VEX_L;
2554 defm VSHUFPD  : sse12_shuffle<VR128, f128mem, v2f64,
2555            "shufpd\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
2556            loadv2f64, SSEPackedDouble>, TB, OpSize, VEX_4V;
2557 defm VSHUFPDY : sse12_shuffle<VR256, f256mem, v4f64,
2558            "shufpd\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
2559            loadv4f64, SSEPackedDouble>, TB, OpSize, VEX_4V, VEX_L;
2560
2561 let Constraints = "$src1 = $dst" in {
2562   defm SHUFPS : sse12_shuffle<VR128, f128mem, v4f32,
2563                     "shufps\t{$src3, $src2, $dst|$dst, $src2, $src3}",
2564                     memopv4f32, SSEPackedSingle, 1 /* cvt to pshufd */>,
2565                     TB;
2566   defm SHUFPD : sse12_shuffle<VR128, f128mem, v2f64,
2567                     "shufpd\t{$src3, $src2, $dst|$dst, $src2, $src3}",
2568                     memopv2f64, SSEPackedDouble, 1 /* cvt to pshufd */>,
2569                     TB, OpSize;
2570 }
2571
2572 let Predicates = [HasAVX] in {
2573   def : Pat<(v4i32 (X86Shufp VR128:$src1,
2574                        (bc_v4i32 (loadv2i64 addr:$src2)), (i8 imm:$imm))),
2575             (VSHUFPSrmi VR128:$src1, addr:$src2, imm:$imm)>;
2576   def : Pat<(v4i32 (X86Shufp VR128:$src1, VR128:$src2, (i8 imm:$imm))),
2577             (VSHUFPSrri VR128:$src1, VR128:$src2, imm:$imm)>;
2578
2579   def : Pat<(v2i64 (X86Shufp VR128:$src1,
2580                        (loadv2i64 addr:$src2), (i8 imm:$imm))),
2581             (VSHUFPDrmi VR128:$src1, addr:$src2, imm:$imm)>;
2582   def : Pat<(v2i64 (X86Shufp VR128:$src1, VR128:$src2, (i8 imm:$imm))),
2583             (VSHUFPDrri VR128:$src1, VR128:$src2, imm:$imm)>;
2584
2585   // 256-bit patterns
2586   def : Pat<(v8i32 (X86Shufp VR256:$src1, VR256:$src2, (i8 imm:$imm))),
2587             (VSHUFPSYrri VR256:$src1, VR256:$src2, imm:$imm)>;
2588   def : Pat<(v8i32 (X86Shufp VR256:$src1,
2589                       (bc_v8i32 (loadv4i64 addr:$src2)), (i8 imm:$imm))),
2590             (VSHUFPSYrmi VR256:$src1, addr:$src2, imm:$imm)>;
2591
2592   def : Pat<(v4i64 (X86Shufp VR256:$src1, VR256:$src2, (i8 imm:$imm))),
2593             (VSHUFPDYrri VR256:$src1, VR256:$src2, imm:$imm)>;
2594   def : Pat<(v4i64 (X86Shufp VR256:$src1,
2595                               (loadv4i64 addr:$src2), (i8 imm:$imm))),
2596             (VSHUFPDYrmi VR256:$src1, addr:$src2, imm:$imm)>;
2597 }
2598
2599 let Predicates = [UseSSE1] in {
2600   def : Pat<(v4i32 (X86Shufp VR128:$src1,
2601                        (bc_v4i32 (memopv2i64 addr:$src2)), (i8 imm:$imm))),
2602             (SHUFPSrmi VR128:$src1, addr:$src2, imm:$imm)>;
2603   def : Pat<(v4i32 (X86Shufp VR128:$src1, VR128:$src2, (i8 imm:$imm))),
2604             (SHUFPSrri VR128:$src1, VR128:$src2, imm:$imm)>;
2605 }
2606
2607 let Predicates = [UseSSE2] in {
2608   // Generic SHUFPD patterns
2609   def : Pat<(v2i64 (X86Shufp VR128:$src1,
2610                        (memopv2i64 addr:$src2), (i8 imm:$imm))),
2611             (SHUFPDrmi VR128:$src1, addr:$src2, imm:$imm)>;
2612   def : Pat<(v2i64 (X86Shufp VR128:$src1, VR128:$src2, (i8 imm:$imm))),
2613             (SHUFPDrri VR128:$src1, VR128:$src2, imm:$imm)>;
2614 }
2615
2616 //===----------------------------------------------------------------------===//
2617 // SSE 1 & 2 - Unpack Instructions
2618 //===----------------------------------------------------------------------===//
2619
2620 /// sse12_unpack_interleave - sse 1 & 2 unpack and interleave
2621 multiclass sse12_unpack_interleave<bits<8> opc, SDNode OpNode, ValueType vt,
2622                                    PatFrag mem_frag, RegisterClass RC,
2623                                    X86MemOperand x86memop, string asm,
2624                                    Domain d> {
2625     def rr : PI<opc, MRMSrcReg,
2626                 (outs RC:$dst), (ins RC:$src1, RC:$src2),
2627                 asm, [(set RC:$dst,
2628                            (vt (OpNode RC:$src1, RC:$src2)))],
2629                            IIC_SSE_UNPCK, d>, Sched<[WriteShuffle]>;
2630     def rm : PI<opc, MRMSrcMem,
2631                 (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
2632                 asm, [(set RC:$dst,
2633                            (vt (OpNode RC:$src1,
2634                                        (mem_frag addr:$src2))))],
2635                                        IIC_SSE_UNPCK, d>,
2636              Sched<[WriteShuffleLd, ReadAfterLd]>;
2637 }
2638
2639 defm VUNPCKHPS: sse12_unpack_interleave<0x15, X86Unpckh, v4f32, loadv4f32,
2640       VR128, f128mem, "unpckhps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2641                      SSEPackedSingle>, TB, VEX_4V;
2642 defm VUNPCKHPD: sse12_unpack_interleave<0x15, X86Unpckh, v2f64, loadv2f64,
2643       VR128, f128mem, "unpckhpd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2644                      SSEPackedDouble>, TB, OpSize, VEX_4V;
2645 defm VUNPCKLPS: sse12_unpack_interleave<0x14, X86Unpckl, v4f32, loadv4f32,
2646       VR128, f128mem, "unpcklps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2647                      SSEPackedSingle>, TB, VEX_4V;
2648 defm VUNPCKLPD: sse12_unpack_interleave<0x14, X86Unpckl, v2f64, loadv2f64,
2649       VR128, f128mem, "unpcklpd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2650                      SSEPackedDouble>, TB, OpSize, VEX_4V;
2651
2652 defm VUNPCKHPSY: sse12_unpack_interleave<0x15, X86Unpckh, v8f32, loadv8f32,
2653       VR256, f256mem, "unpckhps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2654                      SSEPackedSingle>, TB, VEX_4V, VEX_L;
2655 defm VUNPCKHPDY: sse12_unpack_interleave<0x15, X86Unpckh, v4f64, loadv4f64,
2656       VR256, f256mem, "unpckhpd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2657                      SSEPackedDouble>, TB, OpSize, VEX_4V, VEX_L;
2658 defm VUNPCKLPSY: sse12_unpack_interleave<0x14, X86Unpckl, v8f32, loadv8f32,
2659       VR256, f256mem, "unpcklps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2660                      SSEPackedSingle>, TB, VEX_4V, VEX_L;
2661 defm VUNPCKLPDY: sse12_unpack_interleave<0x14, X86Unpckl, v4f64, loadv4f64,
2662       VR256, f256mem, "unpcklpd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2663                      SSEPackedDouble>, TB, OpSize, VEX_4V, VEX_L;
2664
2665 let Constraints = "$src1 = $dst" in {
2666   defm UNPCKHPS: sse12_unpack_interleave<0x15, X86Unpckh, v4f32, memopv4f32,
2667         VR128, f128mem, "unpckhps\t{$src2, $dst|$dst, $src2}",
2668                        SSEPackedSingle>, TB;
2669   defm UNPCKHPD: sse12_unpack_interleave<0x15, X86Unpckh, v2f64, memopv2f64,
2670         VR128, f128mem, "unpckhpd\t{$src2, $dst|$dst, $src2}",
2671                        SSEPackedDouble>, TB, OpSize;
2672   defm UNPCKLPS: sse12_unpack_interleave<0x14, X86Unpckl, v4f32, memopv4f32,
2673         VR128, f128mem, "unpcklps\t{$src2, $dst|$dst, $src2}",
2674                        SSEPackedSingle>, TB;
2675   defm UNPCKLPD: sse12_unpack_interleave<0x14, X86Unpckl, v2f64, memopv2f64,
2676         VR128, f128mem, "unpcklpd\t{$src2, $dst|$dst, $src2}",
2677                        SSEPackedDouble>, TB, OpSize;
2678 } // Constraints = "$src1 = $dst"
2679
2680 let Predicates = [HasAVX1Only] in {
2681   def : Pat<(v8i32 (X86Unpckl VR256:$src1, (bc_v8i32 (loadv4i64 addr:$src2)))),
2682             (VUNPCKLPSYrm VR256:$src1, addr:$src2)>;
2683   def : Pat<(v8i32 (X86Unpckl VR256:$src1, VR256:$src2)),
2684             (VUNPCKLPSYrr VR256:$src1, VR256:$src2)>;
2685   def : Pat<(v8i32 (X86Unpckh VR256:$src1, (bc_v8i32 (loadv4i64 addr:$src2)))),
2686             (VUNPCKHPSYrm VR256:$src1, addr:$src2)>;
2687   def : Pat<(v8i32 (X86Unpckh VR256:$src1, VR256:$src2)),
2688             (VUNPCKHPSYrr VR256:$src1, VR256:$src2)>;
2689
2690   def : Pat<(v4i64 (X86Unpckl VR256:$src1, (loadv4i64 addr:$src2))),
2691             (VUNPCKLPDYrm VR256:$src1, addr:$src2)>;
2692   def : Pat<(v4i64 (X86Unpckl VR256:$src1, VR256:$src2)),
2693             (VUNPCKLPDYrr VR256:$src1, VR256:$src2)>;
2694   def : Pat<(v4i64 (X86Unpckh VR256:$src1, (loadv4i64 addr:$src2))),
2695             (VUNPCKHPDYrm VR256:$src1, addr:$src2)>;
2696   def : Pat<(v4i64 (X86Unpckh VR256:$src1, VR256:$src2)),
2697             (VUNPCKHPDYrr VR256:$src1, VR256:$src2)>;
2698 }
2699
2700 let Predicates = [HasAVX] in {
2701   // FIXME: Instead of X86Movddup, there should be a X86Unpckl here, the
2702   // problem is during lowering, where it's not possible to recognize the load
2703   // fold cause it has two uses through a bitcast. One use disappears at isel
2704   // time and the fold opportunity reappears.
2705   def : Pat<(v2f64 (X86Movddup VR128:$src)),
2706             (VUNPCKLPDrr VR128:$src, VR128:$src)>;
2707 }
2708
2709 let Predicates = [UseSSE2] in {
2710   // FIXME: Instead of X86Movddup, there should be a X86Unpckl here, the
2711   // problem is during lowering, where it's not possible to recognize the load
2712   // fold cause it has two uses through a bitcast. One use disappears at isel
2713   // time and the fold opportunity reappears.
2714   def : Pat<(v2f64 (X86Movddup VR128:$src)),
2715             (UNPCKLPDrr VR128:$src, VR128:$src)>;
2716 }
2717
2718 //===----------------------------------------------------------------------===//
2719 // SSE 1 & 2 - Extract Floating-Point Sign mask
2720 //===----------------------------------------------------------------------===//
2721
2722 /// sse12_extr_sign_mask - sse 1 & 2 unpack and interleave
2723 multiclass sse12_extr_sign_mask<RegisterClass RC, Intrinsic Int, string asm,
2724                                 Domain d> {
2725   def rr : PI<0x50, MRMSrcReg, (outs GR32orGR64:$dst), (ins RC:$src),
2726               !strconcat(asm, "\t{$src, $dst|$dst, $src}"),
2727               [(set GR32orGR64:$dst, (Int RC:$src))], IIC_SSE_MOVMSK, d>,
2728               Sched<[WriteVecLogic]>;
2729 }
2730
2731 let Predicates = [HasAVX] in {
2732   defm VMOVMSKPS : sse12_extr_sign_mask<VR128, int_x86_sse_movmsk_ps,
2733                                         "movmskps", SSEPackedSingle>, TB, VEX;
2734   defm VMOVMSKPD : sse12_extr_sign_mask<VR128, int_x86_sse2_movmsk_pd,
2735                                         "movmskpd", SSEPackedDouble>, TB,
2736                                         OpSize, VEX;
2737   defm VMOVMSKPSY : sse12_extr_sign_mask<VR256, int_x86_avx_movmsk_ps_256,
2738                                         "movmskps", SSEPackedSingle>, TB,
2739                                         VEX, VEX_L;
2740   defm VMOVMSKPDY : sse12_extr_sign_mask<VR256, int_x86_avx_movmsk_pd_256,
2741                                         "movmskpd", SSEPackedDouble>, TB,
2742                                         OpSize, VEX, VEX_L;
2743
2744   def : Pat<(i32 (X86fgetsign FR32:$src)),
2745             (VMOVMSKPSrr (COPY_TO_REGCLASS FR32:$src, VR128))>;
2746   def : Pat<(i64 (X86fgetsign FR32:$src)),
2747             (SUBREG_TO_REG (i64 0),
2748              (VMOVMSKPSrr (COPY_TO_REGCLASS FR32:$src, VR128)), sub_32bit)>;
2749   def : Pat<(i32 (X86fgetsign FR64:$src)),
2750             (VMOVMSKPDrr (COPY_TO_REGCLASS FR64:$src, VR128))>;
2751   def : Pat<(i64 (X86fgetsign FR64:$src)),
2752             (SUBREG_TO_REG (i64 0),
2753              (VMOVMSKPDrr (COPY_TO_REGCLASS FR64:$src, VR128)), sub_32bit)>;
2754 }
2755
2756 defm MOVMSKPS : sse12_extr_sign_mask<VR128, int_x86_sse_movmsk_ps, "movmskps",
2757                                      SSEPackedSingle>, TB;
2758 defm MOVMSKPD : sse12_extr_sign_mask<VR128, int_x86_sse2_movmsk_pd, "movmskpd",
2759                                      SSEPackedDouble>, TB, OpSize;
2760
2761 def : Pat<(i32 (X86fgetsign FR32:$src)),
2762           (MOVMSKPSrr (COPY_TO_REGCLASS FR32:$src, VR128))>,
2763       Requires<[UseSSE1]>;
2764 def : Pat<(i64 (X86fgetsign FR32:$src)),
2765           (SUBREG_TO_REG (i64 0),
2766            (MOVMSKPSrr (COPY_TO_REGCLASS FR32:$src, VR128)), sub_32bit)>,
2767       Requires<[UseSSE1]>;
2768 def : Pat<(i32 (X86fgetsign FR64:$src)),
2769           (MOVMSKPDrr (COPY_TO_REGCLASS FR64:$src, VR128))>,
2770       Requires<[UseSSE2]>;
2771 def : Pat<(i64 (X86fgetsign FR64:$src)),
2772           (SUBREG_TO_REG (i64 0),
2773            (MOVMSKPDrr (COPY_TO_REGCLASS FR64:$src, VR128)), sub_32bit)>,
2774       Requires<[UseSSE2]>;
2775
2776 //===---------------------------------------------------------------------===//
2777 // SSE2 - Packed Integer Logical Instructions
2778 //===---------------------------------------------------------------------===//
2779
2780 let ExeDomain = SSEPackedInt in { // SSE integer instructions
2781
2782 /// PDI_binop_rm - Simple SSE2 binary operator.
2783 multiclass PDI_binop_rm<bits<8> opc, string OpcodeStr, SDNode OpNode,
2784                         ValueType OpVT, RegisterClass RC, PatFrag memop_frag,
2785                         X86MemOperand x86memop, OpndItins itins,
2786                         bit IsCommutable, bit Is2Addr> {
2787   let isCommutable = IsCommutable in
2788   def rr : PDI<opc, MRMSrcReg, (outs RC:$dst),
2789        (ins RC:$src1, RC:$src2),
2790        !if(Is2Addr,
2791            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
2792            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
2793        [(set RC:$dst, (OpVT (OpNode RC:$src1, RC:$src2)))], itins.rr>,
2794        Sched<[itins.Sched]>;
2795   def rm : PDI<opc, MRMSrcMem, (outs RC:$dst),
2796        (ins RC:$src1, x86memop:$src2),
2797        !if(Is2Addr,
2798            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
2799            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
2800        [(set RC:$dst, (OpVT (OpNode RC:$src1,
2801                                      (bitconvert (memop_frag addr:$src2)))))],
2802                                      itins.rm>,
2803        Sched<[itins.Sched.Folded, ReadAfterLd]>;
2804 }
2805 } // ExeDomain = SSEPackedInt
2806
2807 multiclass PDI_binop_all<bits<8> opc, string OpcodeStr, SDNode Opcode,
2808                          ValueType OpVT128, ValueType OpVT256,
2809                          OpndItins itins, bit IsCommutable = 0> {
2810 let Predicates = [HasAVX] in
2811   defm V#NAME : PDI_binop_rm<opc, !strconcat("v", OpcodeStr), Opcode, OpVT128,
2812                     VR128, loadv2i64, i128mem, itins, IsCommutable, 0>, VEX_4V;
2813
2814 let Constraints = "$src1 = $dst" in
2815   defm NAME : PDI_binop_rm<opc, OpcodeStr, Opcode, OpVT128, VR128,
2816                            memopv2i64, i128mem, itins, IsCommutable, 1>;
2817
2818 let Predicates = [HasAVX2] in
2819   defm V#NAME#Y : PDI_binop_rm<opc, !strconcat("v", OpcodeStr), Opcode,
2820                                OpVT256, VR256, loadv4i64, i256mem, itins,
2821                                IsCommutable, 0>, VEX_4V, VEX_L;
2822 }
2823
2824 // These are ordered here for pattern ordering requirements with the fp versions
2825
2826 defm PAND  : PDI_binop_all<0xDB, "pand", and, v2i64, v4i64, SSE_BIT_ITINS_P, 1>;
2827 defm POR   : PDI_binop_all<0xEB, "por", or, v2i64, v4i64, SSE_BIT_ITINS_P, 1>;
2828 defm PXOR  : PDI_binop_all<0xEF, "pxor", xor, v2i64, v4i64, SSE_BIT_ITINS_P, 1>;
2829 defm PANDN : PDI_binop_all<0xDF, "pandn", X86andnp, v2i64, v4i64,
2830                            SSE_BIT_ITINS_P, 0>;
2831
2832 //===----------------------------------------------------------------------===//
2833 // SSE 1 & 2 - Logical Instructions
2834 //===----------------------------------------------------------------------===//
2835
2836 /// sse12_fp_alias_pack_logical - SSE 1 & 2 aliased packed FP logical ops
2837 ///
2838 multiclass sse12_fp_alias_pack_logical<bits<8> opc, string OpcodeStr,
2839                                        SDNode OpNode, OpndItins itins> {
2840   defm V#NAME#PS : sse12_fp_packed<opc, !strconcat(OpcodeStr, "ps"), OpNode,
2841               FR32, f32, f128mem, memopfsf32, SSEPackedSingle, itins, 0>,
2842               TB, VEX_4V;
2843
2844   defm V#NAME#PD : sse12_fp_packed<opc, !strconcat(OpcodeStr, "pd"), OpNode,
2845         FR64, f64, f128mem, memopfsf64, SSEPackedDouble, itins, 0>,
2846         TB, OpSize, VEX_4V;
2847
2848   let Constraints = "$src1 = $dst" in {
2849     defm PS : sse12_fp_packed<opc, !strconcat(OpcodeStr, "ps"), OpNode, FR32,
2850                 f32, f128mem, memopfsf32, SSEPackedSingle, itins>,
2851                 TB;
2852
2853     defm PD : sse12_fp_packed<opc, !strconcat(OpcodeStr, "pd"), OpNode, FR64,
2854                 f64, f128mem, memopfsf64, SSEPackedDouble, itins>,
2855                 TB, OpSize;
2856   }
2857 }
2858
2859 // Alias bitwise logical operations using SSE logical ops on packed FP values.
2860 let isCodeGenOnly = 1 in {
2861   defm FsAND  : sse12_fp_alias_pack_logical<0x54, "and", X86fand,
2862                 SSE_BIT_ITINS_P>;
2863   defm FsOR   : sse12_fp_alias_pack_logical<0x56, "or", X86for,
2864                 SSE_BIT_ITINS_P>;
2865   defm FsXOR  : sse12_fp_alias_pack_logical<0x57, "xor", X86fxor,
2866                 SSE_BIT_ITINS_P>;
2867
2868   let isCommutable = 0 in
2869     defm FsANDN : sse12_fp_alias_pack_logical<0x55, "andn", X86fandn,
2870                   SSE_BIT_ITINS_P>;
2871 }
2872
2873 /// sse12_fp_packed_logical - SSE 1 & 2 packed FP logical ops
2874 ///
2875 multiclass sse12_fp_packed_logical<bits<8> opc, string OpcodeStr,
2876                                    SDNode OpNode> {
2877   defm V#NAME#PSY : sse12_fp_packed_logical_rm<opc, VR256, SSEPackedSingle,
2878         !strconcat(OpcodeStr, "ps"), f256mem,
2879         [(set VR256:$dst, (v4i64 (OpNode VR256:$src1, VR256:$src2)))],
2880         [(set VR256:$dst, (OpNode (bc_v4i64 (v8f32 VR256:$src1)),
2881                            (loadv4i64 addr:$src2)))], 0>, TB, VEX_4V, VEX_L;
2882
2883   defm V#NAME#PDY : sse12_fp_packed_logical_rm<opc, VR256, SSEPackedDouble,
2884         !strconcat(OpcodeStr, "pd"), f256mem,
2885         [(set VR256:$dst, (OpNode (bc_v4i64 (v4f64 VR256:$src1)),
2886                                   (bc_v4i64 (v4f64 VR256:$src2))))],
2887         [(set VR256:$dst, (OpNode (bc_v4i64 (v4f64 VR256:$src1)),
2888                                   (loadv4i64 addr:$src2)))], 0>,
2889                                   TB, OpSize, VEX_4V, VEX_L;
2890
2891   // In AVX no need to add a pattern for 128-bit logical rr ps, because they
2892   // are all promoted to v2i64, and the patterns are covered by the int
2893   // version. This is needed in SSE only, because v2i64 isn't supported on
2894   // SSE1, but only on SSE2.
2895   defm V#NAME#PS : sse12_fp_packed_logical_rm<opc, VR128, SSEPackedSingle,
2896        !strconcat(OpcodeStr, "ps"), f128mem, [],
2897        [(set VR128:$dst, (OpNode (bc_v2i64 (v4f32 VR128:$src1)),
2898                                  (loadv2i64 addr:$src2)))], 0>, TB, VEX_4V;
2899
2900   defm V#NAME#PD : sse12_fp_packed_logical_rm<opc, VR128, SSEPackedDouble,
2901        !strconcat(OpcodeStr, "pd"), f128mem,
2902        [(set VR128:$dst, (OpNode (bc_v2i64 (v2f64 VR128:$src1)),
2903                                  (bc_v2i64 (v2f64 VR128:$src2))))],
2904        [(set VR128:$dst, (OpNode (bc_v2i64 (v2f64 VR128:$src1)),
2905                                  (loadv2i64 addr:$src2)))], 0>,
2906                                                  TB, OpSize, VEX_4V;
2907
2908   let Constraints = "$src1 = $dst" in {
2909     defm PS : sse12_fp_packed_logical_rm<opc, VR128, SSEPackedSingle,
2910          !strconcat(OpcodeStr, "ps"), f128mem,
2911          [(set VR128:$dst, (v2i64 (OpNode VR128:$src1, VR128:$src2)))],
2912          [(set VR128:$dst, (OpNode (bc_v2i64 (v4f32 VR128:$src1)),
2913                                    (memopv2i64 addr:$src2)))]>, TB;
2914
2915     defm PD : sse12_fp_packed_logical_rm<opc, VR128, SSEPackedDouble,
2916          !strconcat(OpcodeStr, "pd"), f128mem,
2917          [(set VR128:$dst, (OpNode (bc_v2i64 (v2f64 VR128:$src1)),
2918                                    (bc_v2i64 (v2f64 VR128:$src2))))],
2919          [(set VR128:$dst, (OpNode (bc_v2i64 (v2f64 VR128:$src1)),
2920                                    (memopv2i64 addr:$src2)))]>, TB, OpSize;
2921   }
2922 }
2923
2924 defm AND  : sse12_fp_packed_logical<0x54, "and", and>;
2925 defm OR   : sse12_fp_packed_logical<0x56, "or", or>;
2926 defm XOR  : sse12_fp_packed_logical<0x57, "xor", xor>;
2927 let isCommutable = 0 in
2928   defm ANDN : sse12_fp_packed_logical<0x55, "andn", X86andnp>;
2929
2930 //===----------------------------------------------------------------------===//
2931 // SSE 1 & 2 - Arithmetic Instructions
2932 //===----------------------------------------------------------------------===//
2933
2934 /// basic_sse12_fp_binop_xxx - SSE 1 & 2 binops come in both scalar and
2935 /// vector forms.
2936 ///
2937 /// In addition, we also have a special variant of the scalar form here to
2938 /// represent the associated intrinsic operation.  This form is unlike the
2939 /// plain scalar form, in that it takes an entire vector (instead of a scalar)
2940 /// and leaves the top elements unmodified (therefore these cannot be commuted).
2941 ///
2942 /// These three forms can each be reg+reg or reg+mem.
2943 ///
2944
2945 /// FIXME: once all 256-bit intrinsics are matched, cleanup and refactor those
2946 /// classes below
2947 multiclass basic_sse12_fp_binop_p<bits<8> opc, string OpcodeStr,
2948                                   SDNode OpNode, SizeItins itins> {
2949   defm V#NAME#PS : sse12_fp_packed<opc, !strconcat(OpcodeStr, "ps"), OpNode,
2950                                VR128, v4f32, f128mem, loadv4f32,
2951                                SSEPackedSingle, itins.s, 0>, TB, VEX_4V;
2952   defm V#NAME#PD : sse12_fp_packed<opc, !strconcat(OpcodeStr, "pd"), OpNode,
2953                                VR128, v2f64, f128mem, loadv2f64,
2954                                SSEPackedDouble, itins.d, 0>, TB, OpSize, VEX_4V;
2955
2956   defm V#NAME#PSY : sse12_fp_packed<opc, !strconcat(OpcodeStr, "ps"),
2957                         OpNode, VR256, v8f32, f256mem, loadv8f32,
2958                         SSEPackedSingle, itins.s, 0>, TB, VEX_4V, VEX_L;
2959   defm V#NAME#PDY : sse12_fp_packed<opc, !strconcat(OpcodeStr, "pd"),
2960                         OpNode, VR256, v4f64, f256mem, loadv4f64,
2961                         SSEPackedDouble, itins.d, 0>, TB, OpSize, VEX_4V, VEX_L;
2962
2963   let Constraints = "$src1 = $dst" in {
2964     defm PS : sse12_fp_packed<opc, !strconcat(OpcodeStr, "ps"), OpNode, VR128,
2965                               v4f32, f128mem, memopv4f32, SSEPackedSingle,
2966                               itins.s>, TB;
2967     defm PD : sse12_fp_packed<opc, !strconcat(OpcodeStr, "pd"), OpNode, VR128,
2968                               v2f64, f128mem, memopv2f64, SSEPackedDouble,
2969                               itins.d>, TB, OpSize;
2970   }
2971 }
2972
2973 multiclass basic_sse12_fp_binop_s<bits<8> opc, string OpcodeStr, SDNode OpNode,
2974                                   SizeItins itins> {
2975   defm V#NAME#SS : sse12_fp_scalar<opc, !strconcat(OpcodeStr, "ss"),
2976                          OpNode, FR32, f32mem, itins.s, 0>, XS, VEX_4V, VEX_LIG;
2977   defm V#NAME#SD : sse12_fp_scalar<opc, !strconcat(OpcodeStr, "sd"),
2978                          OpNode, FR64, f64mem, itins.d, 0>, XD, VEX_4V, VEX_LIG;
2979
2980   let Constraints = "$src1 = $dst" in {
2981     defm SS : sse12_fp_scalar<opc, !strconcat(OpcodeStr, "ss"),
2982                               OpNode, FR32, f32mem, itins.s>, XS;
2983     defm SD : sse12_fp_scalar<opc, !strconcat(OpcodeStr, "sd"),
2984                               OpNode, FR64, f64mem, itins.d>, XD;
2985   }
2986 }
2987
2988 multiclass basic_sse12_fp_binop_s_int<bits<8> opc, string OpcodeStr,
2989                                       SizeItins itins> {
2990   defm V#NAME#SS : sse12_fp_scalar_int<opc, OpcodeStr, VR128,
2991                    !strconcat(OpcodeStr, "ss"), "", "_ss", ssmem, sse_load_f32,
2992                    itins.s, 0>, XS, VEX_4V, VEX_LIG;
2993   defm V#NAME#SD : sse12_fp_scalar_int<opc, OpcodeStr, VR128,
2994                    !strconcat(OpcodeStr, "sd"), "2", "_sd", sdmem, sse_load_f64,
2995                    itins.d, 0>, XD, VEX_4V, VEX_LIG;
2996
2997   let Constraints = "$src1 = $dst" in {
2998     defm SS : sse12_fp_scalar_int<opc, OpcodeStr, VR128,
2999                    !strconcat(OpcodeStr, "ss"), "", "_ss", ssmem, sse_load_f32,
3000                    itins.s>, XS;
3001     defm SD : sse12_fp_scalar_int<opc, OpcodeStr, VR128,
3002                    !strconcat(OpcodeStr, "sd"), "2", "_sd", sdmem, sse_load_f64,
3003                    itins.d>, XD;
3004   }
3005 }
3006
3007 // Binary Arithmetic instructions
3008 defm ADD : basic_sse12_fp_binop_p<0x58, "add", fadd, SSE_ALU_ITINS_P>,
3009            basic_sse12_fp_binop_s<0x58, "add", fadd, SSE_ALU_ITINS_S>,
3010            basic_sse12_fp_binop_s_int<0x58, "add", SSE_ALU_ITINS_S>;
3011 defm MUL : basic_sse12_fp_binop_p<0x59, "mul", fmul, SSE_MUL_ITINS_P>,
3012            basic_sse12_fp_binop_s<0x59, "mul", fmul, SSE_MUL_ITINS_S>,
3013            basic_sse12_fp_binop_s_int<0x59, "mul", SSE_MUL_ITINS_S>;
3014 let isCommutable = 0 in {
3015   defm SUB : basic_sse12_fp_binop_p<0x5C, "sub", fsub, SSE_ALU_ITINS_P>,
3016              basic_sse12_fp_binop_s<0x5C, "sub", fsub, SSE_ALU_ITINS_S>,
3017              basic_sse12_fp_binop_s_int<0x5C, "sub", SSE_ALU_ITINS_S>;
3018   defm DIV : basic_sse12_fp_binop_p<0x5E, "div", fdiv, SSE_DIV_ITINS_P>,
3019              basic_sse12_fp_binop_s<0x5E, "div", fdiv, SSE_DIV_ITINS_S>,
3020              basic_sse12_fp_binop_s_int<0x5E, "div", SSE_DIV_ITINS_S>;
3021   defm MAX : basic_sse12_fp_binop_p<0x5F, "max", X86fmax, SSE_ALU_ITINS_P>,
3022              basic_sse12_fp_binop_s<0x5F, "max", X86fmax, SSE_ALU_ITINS_S>,
3023              basic_sse12_fp_binop_s_int<0x5F, "max", SSE_ALU_ITINS_S>;
3024   defm MIN : basic_sse12_fp_binop_p<0x5D, "min", X86fmin, SSE_ALU_ITINS_P>,
3025              basic_sse12_fp_binop_s<0x5D, "min", X86fmin, SSE_ALU_ITINS_S>,
3026              basic_sse12_fp_binop_s_int<0x5D, "min", SSE_ALU_ITINS_S>;
3027 }
3028
3029 let isCodeGenOnly = 1 in {
3030   defm MAXC: basic_sse12_fp_binop_p<0x5F, "max", X86fmaxc, SSE_ALU_ITINS_P>,
3031              basic_sse12_fp_binop_s<0x5F, "max", X86fmaxc, SSE_ALU_ITINS_S>;
3032   defm MINC: basic_sse12_fp_binop_p<0x5D, "min", X86fminc, SSE_ALU_ITINS_P>,
3033              basic_sse12_fp_binop_s<0x5D, "min", X86fminc, SSE_ALU_ITINS_S>;
3034 }
3035
3036 // Patterns used to select SSE scalar fp arithmetic instructions from
3037 // a scalar fp operation followed by a blend.
3038 //
3039 // These patterns know, for example, how to select an ADDSS from a
3040 // float add plus vector insert.
3041 //
3042 // The effect is that the backend no longer emits unnecessary vector
3043 // insert instructions immediately after SSE scalar fp instructions
3044 // like addss or mulss.
3045 //
3046 // For example, given the following code:
3047 //   __m128 foo(__m128 A, __m128 B) {
3048 //     A[0] += B[0];
3049 //     return A;
3050 //   }
3051 //
3052 // previously we generated:
3053 //   addss %xmm0, %xmm1
3054 //   movss %xmm1, %xmm0
3055 // 
3056 // we now generate:
3057 //   addss %xmm1, %xmm0
3058
3059 def : Pat<(v4f32 (X86Movss (v4f32 VR128:$dst), (v4f32 (scalar_to_vector (fadd
3060                     (f32 (vector_extract (v4f32 VR128:$dst), (iPTR 0))),
3061                     FR32:$src))))),
3062           (ADDSSrr_Int v4f32:$dst, (COPY_TO_REGCLASS FR32:$src, VR128))>;
3063 def : Pat<(v4f32 (X86Movss (v4f32 VR128:$dst), (v4f32 (scalar_to_vector (fsub
3064                     (f32 (vector_extract (v4f32 VR128:$dst), (iPTR 0))),
3065                     FR32:$src))))),
3066           (SUBSSrr_Int v4f32:$dst, (COPY_TO_REGCLASS FR32:$src, VR128))>;
3067 def : Pat<(v4f32 (X86Movss (v4f32 VR128:$dst), (v4f32 (scalar_to_vector (fmul
3068                     (f32 (vector_extract (v4f32 VR128:$dst), (iPTR 0))),
3069                     FR32:$src))))),
3070           (MULSSrr_Int v4f32:$dst, (COPY_TO_REGCLASS FR32:$src, VR128))>;
3071 def : Pat<(v4f32 (X86Movss (v4f32 VR128:$dst), (v4f32 (scalar_to_vector (fdiv
3072                     (f32 (vector_extract (v4f32 VR128:$dst), (iPTR 0))),
3073                     FR32:$src))))),
3074           (DIVSSrr_Int v4f32:$dst, (COPY_TO_REGCLASS FR32:$src, VR128))>;
3075
3076 let Predicates = [HasSSE2] in {
3077   // SSE2 patterns to select scalar double-precision fp arithmetic instructions
3078
3079   def : Pat<(v2f64 (X86Movsd (v2f64 VR128:$dst), (v2f64 (scalar_to_vector (fadd
3080                       (f64 (vector_extract (v2f64 VR128:$dst), (iPTR 0))),
3081                       FR64:$src))))),
3082             (ADDSDrr_Int v2f64:$dst, (COPY_TO_REGCLASS FR64:$src, VR128))>;
3083   def : Pat<(v2f64 (X86Movsd (v2f64 VR128:$dst), (v2f64 (scalar_to_vector (fsub
3084                       (f64 (vector_extract (v2f64 VR128:$dst), (iPTR 0))),
3085                       FR64:$src))))),
3086             (SUBSDrr_Int v2f64:$dst, (COPY_TO_REGCLASS FR64:$src, VR128))>;
3087   def : Pat<(v2f64 (X86Movsd (v2f64 VR128:$dst), (v2f64 (scalar_to_vector (fmul
3088                       (f64 (vector_extract (v2f64 VR128:$dst), (iPTR 0))),
3089                       FR64:$src))))),
3090             (MULSDrr_Int v2f64:$dst, (COPY_TO_REGCLASS FR64:$src, VR128))>;
3091   def : Pat<(v2f64 (X86Movsd (v2f64 VR128:$dst), (v2f64 (scalar_to_vector (fdiv
3092                       (f64 (vector_extract (v2f64 VR128:$dst), (iPTR 0))),
3093                       FR64:$src))))),
3094             (DIVSDrr_Int v2f64:$dst, (COPY_TO_REGCLASS FR64:$src, VR128))>;
3095 }
3096
3097 let Predicates = [UseSSE41] in {
3098   // If the subtarget has SSE4.1 but not AVX, the vector insert
3099   // instruction is lowered into a X86insrtps rather than a X86Movss.
3100   // When selecting SSE scalar single-precision fp arithmetic instructions,
3101   // make sure that we correctly match the X86insrtps.
3102
3103   def : Pat<(v4f32 (X86insrtps (v4f32 VR128:$dst), (v4f32 (scalar_to_vector
3104                   (fadd (f32 (vector_extract (v4f32 VR128:$dst), (iPTR 0))),
3105                     FR32:$src))), (iPTR 0))),
3106             (ADDSSrr_Int v4f32:$dst, (COPY_TO_REGCLASS FR32:$src, VR128))>;
3107   def : Pat<(v4f32 (X86insrtps (v4f32 VR128:$dst), (v4f32 (scalar_to_vector
3108                   (fsub (f32 (vector_extract (v4f32 VR128:$dst), (iPTR 0))),
3109                     FR32:$src))), (iPTR 0))),
3110             (SUBSSrr_Int v4f32:$dst, (COPY_TO_REGCLASS FR32:$src, VR128))>;
3111   def : Pat<(v4f32 (X86insrtps (v4f32 VR128:$dst), (v4f32 (scalar_to_vector
3112                   (fmul (f32 (vector_extract (v4f32 VR128:$dst), (iPTR 0))),
3113                     FR32:$src))), (iPTR 0))),
3114             (MULSSrr_Int v4f32:$dst, (COPY_TO_REGCLASS FR32:$src, VR128))>;
3115   def : Pat<(v4f32 (X86insrtps (v4f32 VR128:$dst), (v4f32 (scalar_to_vector
3116                   (fdiv (f32 (vector_extract (v4f32 VR128:$dst), (iPTR 0))),
3117                     FR32:$src))), (iPTR 0))),
3118             (DIVSSrr_Int v4f32:$dst, (COPY_TO_REGCLASS FR32:$src, VR128))>;
3119 }
3120
3121 let AddedComplexity = 20, Predicates = [HasAVX] in {
3122   // The following patterns select AVX Scalar single/double precision fp
3123   // arithmetic instructions.
3124   // The 'AddedComplexity' is required to give them higher priority over
3125   // the equivalent SSE/SSE2 patterns.
3126
3127   def : Pat<(v2f64 (X86Movsd (v2f64 VR128:$dst), (v2f64 (scalar_to_vector (fadd
3128                       (f64 (vector_extract (v2f64 VR128:$dst), (iPTR 0))),
3129                       FR64:$src))))),
3130             (VADDSDrr_Int v2f64:$dst, (COPY_TO_REGCLASS FR64:$src, VR128))>;
3131   def : Pat<(v2f64 (X86Movsd (v2f64 VR128:$dst), (v2f64 (scalar_to_vector (fsub
3132                       (f64 (vector_extract (v2f64 VR128:$dst), (iPTR 0))),
3133                       FR64:$src))))),
3134             (VSUBSDrr_Int v2f64:$dst, (COPY_TO_REGCLASS FR64:$src, VR128))>;
3135   def : Pat<(v2f64 (X86Movsd (v2f64 VR128:$dst), (v2f64 (scalar_to_vector (fmul
3136                       (f64 (vector_extract (v2f64 VR128:$dst), (iPTR 0))),
3137                       FR64:$src))))),
3138             (VMULSDrr_Int v2f64:$dst, (COPY_TO_REGCLASS FR64:$src, VR128))>;
3139   def : Pat<(v2f64 (X86Movsd (v2f64 VR128:$dst), (v2f64 (scalar_to_vector (fdiv
3140                       (f64 (vector_extract (v2f64 VR128:$dst), (iPTR 0))),
3141                       FR64:$src))))),
3142             (VDIVSDrr_Int v2f64:$dst, (COPY_TO_REGCLASS FR64:$src, VR128))>;
3143   def : Pat<(v4f32 (X86insrtps (v4f32 VR128:$dst), (v4f32 (scalar_to_vector
3144                  (fadd (f32 (vector_extract (v4f32 VR128:$dst), (iPTR 0))),
3145                        FR32:$src))), (iPTR 0))),
3146             (VADDSSrr_Int v4f32:$dst, (COPY_TO_REGCLASS FR32:$src, VR128))>;
3147   def : Pat<(v4f32 (X86insrtps (v4f32 VR128:$dst), (v4f32 (scalar_to_vector
3148                  (fsub (f32 (vector_extract (v4f32 VR128:$dst), (iPTR 0))),
3149                        FR32:$src))), (iPTR 0))),
3150             (VSUBSSrr_Int v4f32:$dst, (COPY_TO_REGCLASS FR32:$src, VR128))>;
3151   def : Pat<(v4f32 (X86insrtps (v4f32 VR128:$dst), (v4f32 (scalar_to_vector
3152                  (fmul (f32 (vector_extract (v4f32 VR128:$dst), (iPTR 0))),
3153                        FR32:$src))), (iPTR 0))),
3154             (VMULSSrr_Int v4f32:$dst, (COPY_TO_REGCLASS FR32:$src, VR128))>;
3155   def : Pat<(v4f32 (X86insrtps (v4f32 VR128:$dst), (v4f32 (scalar_to_vector
3156                  (fdiv (f32 (vector_extract (v4f32 VR128:$dst), (iPTR 0))),
3157                        FR32:$src))), (iPTR 0))),
3158             (VDIVSSrr_Int v4f32:$dst, (COPY_TO_REGCLASS FR32:$src, VR128))>;
3159 }
3160
3161 // Patterns used to select SSE scalar fp arithmetic instructions from
3162 // a vector packed single/double fp operation followed by a vector insert.
3163 //
3164 // The effect is that the backend converts the packed fp instruction
3165 // followed by a vector insert into a single SSE scalar fp instruction.
3166 //
3167 // For example, given the following code:
3168 //   __m128 foo(__m128 A, __m128 B) {
3169 //     __m128 C = A + B;
3170 //     return (__m128) {c[0], a[1], a[2], a[3]};
3171 //   }
3172 //
3173 // previously we generated:
3174 //   addps %xmm0, %xmm1
3175 //   movss %xmm1, %xmm0
3176 // 
3177 // we now generate:
3178 //   addss %xmm1, %xmm0
3179
3180 def : Pat<(v4f32 (X86Movss (v4f32 VR128:$dst),
3181                  (fadd (v4f32 VR128:$dst), (v4f32 VR128:$src)))),
3182           (ADDSSrr_Int v4f32:$dst, v4f32:$src)>;
3183 def : Pat<(v4f32 (X86Movss (v4f32 VR128:$dst), 
3184                  (fsub (v4f32 VR128:$dst), (v4f32 VR128:$src)))),
3185           (SUBSSrr_Int v4f32:$dst, v4f32:$src)>;
3186 def : Pat<(v4f32 (X86Movss (v4f32 VR128:$dst),
3187                  (fmul (v4f32 VR128:$dst), (v4f32 VR128:$src)))),
3188           (MULSSrr_Int v4f32:$dst, v4f32:$src)>;
3189 def : Pat<(v4f32 (X86Movss (v4f32 VR128:$dst), 
3190                  (fdiv (v4f32 VR128:$dst), (v4f32 VR128:$src)))),
3191           (DIVSSrr_Int v4f32:$dst, v4f32:$src)>;
3192
3193 let Predicates = [HasSSE2] in {
3194   // SSE2 patterns to select scalar double-precision fp arithmetic instructions
3195   // from a packed double-precision fp instruction plus movsd.
3196
3197   def : Pat<(v2f64 (X86Movsd (v2f64 VR128:$dst),
3198                    (fadd (v2f64 VR128:$dst), (v2f64 VR128:$src)))),
3199             (ADDSDrr_Int v2f64:$dst, v2f64:$src)>;
3200   def : Pat<(v2f64 (X86Movsd (v2f64 VR128:$dst),
3201                    (fsub (v2f64 VR128:$dst), (v2f64 VR128:$src)))),
3202             (SUBSDrr_Int v2f64:$dst, v2f64:$src)>;
3203   def : Pat<(v2f64 (X86Movsd (v2f64 VR128:$dst),
3204                    (fmul (v2f64 VR128:$dst), (v2f64 VR128:$src)))),
3205             (MULSDrr_Int v2f64:$dst, v2f64:$src)>;
3206   def : Pat<(v2f64 (X86Movsd (v2f64 VR128:$dst),
3207                    (fdiv (v2f64 VR128:$dst), (v2f64 VR128:$src)))),
3208             (DIVSDrr_Int v2f64:$dst, v2f64:$src)>;
3209 }
3210
3211 let AddedComplexity = 20, Predicates = [HasAVX] in {
3212   // The following patterns select AVX Scalar single/double precision fp
3213   // arithmetic instructions from a packed single precision fp instruction
3214   // plus movss/movsd.
3215   // The 'AddedComplexity' is required to give them higher priority over
3216   // the equivalent SSE/SSE2 patterns.
3217
3218   def : Pat<(v4f32 (X86Movss (v4f32 VR128:$dst),
3219                    (fadd (v4f32 VR128:$dst), (v4f32 VR128:$src)))),
3220             (VADDSSrr_Int v4f32:$dst, v4f32:$src)>;
3221   def : Pat<(v4f32 (X86Movss (v4f32 VR128:$dst),
3222                    (fsub (v4f32 VR128:$dst), (v4f32 VR128:$src)))),
3223             (VSUBSSrr_Int v4f32:$dst, v4f32:$src)>;
3224   def : Pat<(v4f32 (X86Movss (v4f32 VR128:$dst),
3225                    (fmul (v4f32 VR128:$dst), (v4f32 VR128:$src)))),
3226             (VMULSSrr_Int v4f32:$dst, v4f32:$src)>;
3227   def : Pat<(v4f32 (X86Movss (v4f32 VR128:$dst),
3228                    (fdiv (v4f32 VR128:$dst), (v4f32 VR128:$src)))),
3229             (VDIVSSrr_Int v4f32:$dst, v4f32:$src)>;
3230   def : Pat<(v2f64 (X86Movsd (v2f64 VR128:$dst),
3231                    (fadd (v2f64 VR128:$dst), (v2f64 VR128:$src)))),
3232             (VADDSDrr_Int v2f64:$dst, v2f64:$src)>;
3233   def : Pat<(v2f64 (X86Movsd (v2f64 VR128:$dst),
3234                    (fsub (v2f64 VR128:$dst), (v2f64 VR128:$src)))),
3235             (VSUBSDrr_Int v2f64:$dst, v2f64:$src)>;
3236   def : Pat<(v2f64 (X86Movsd (v2f64 VR128:$dst),
3237                    (fmul (v2f64 VR128:$dst), (v2f64 VR128:$src)))),
3238             (VMULSDrr_Int v2f64:$dst, v2f64:$src)>;
3239   def : Pat<(v2f64 (X86Movsd (v2f64 VR128:$dst),
3240                    (fdiv (v2f64 VR128:$dst), (v2f64 VR128:$src)))),
3241             (VDIVSDrr_Int v2f64:$dst, v2f64:$src)>;
3242 }
3243
3244 /// Unop Arithmetic
3245 /// In addition, we also have a special variant of the scalar form here to
3246 /// represent the associated intrinsic operation.  This form is unlike the
3247 /// plain scalar form, in that it takes an entire vector (instead of a
3248 /// scalar) and leaves the top elements undefined.
3249 ///
3250 /// And, we have a special variant form for a full-vector intrinsic form.
3251
3252 let Sched = WriteFSqrt in {
3253 def SSE_SQRTPS : OpndItins<
3254   IIC_SSE_SQRTPS_RR, IIC_SSE_SQRTPS_RM
3255 >;
3256
3257 def SSE_SQRTSS : OpndItins<
3258   IIC_SSE_SQRTSS_RR, IIC_SSE_SQRTSS_RM
3259 >;
3260
3261 def SSE_SQRTPD : OpndItins<
3262   IIC_SSE_SQRTPD_RR, IIC_SSE_SQRTPD_RM
3263 >;
3264
3265 def SSE_SQRTSD : OpndItins<
3266   IIC_SSE_SQRTSD_RR, IIC_SSE_SQRTSD_RM
3267 >;
3268 }
3269
3270 let Sched = WriteFRcp in {
3271 def SSE_RCPP : OpndItins<
3272   IIC_SSE_RCPP_RR, IIC_SSE_RCPP_RM
3273 >;
3274
3275 def SSE_RCPS : OpndItins<
3276   IIC_SSE_RCPS_RR, IIC_SSE_RCPS_RM
3277 >;
3278 }
3279
3280 /// sse1_fp_unop_s - SSE1 unops in scalar form.
3281 multiclass sse1_fp_unop_s<bits<8> opc, string OpcodeStr,
3282                           SDNode OpNode, Intrinsic F32Int, OpndItins itins> {
3283 let Predicates = [HasAVX], hasSideEffects = 0 in {
3284   def V#NAME#SSr : SSI<opc, MRMSrcReg, (outs FR32:$dst),
3285                       (ins FR32:$src1, FR32:$src2),
3286                       !strconcat("v", OpcodeStr,
3287                                  "ss\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
3288                       []>, VEX_4V, VEX_LIG, Sched<[itins.Sched]>;
3289   let mayLoad = 1 in {
3290   def V#NAME#SSm : SSI<opc, MRMSrcMem, (outs FR32:$dst),
3291                       (ins FR32:$src1,f32mem:$src2),
3292                       !strconcat("v", OpcodeStr,
3293                                  "ss\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
3294                       []>, VEX_4V, VEX_LIG,
3295                    Sched<[itins.Sched.Folded, ReadAfterLd]>;
3296   let isCodeGenOnly = 1 in
3297   def V#NAME#SSm_Int : SSI<opc, MRMSrcMem, (outs VR128:$dst),
3298                       (ins VR128:$src1, ssmem:$src2),
3299                       !strconcat("v", OpcodeStr,
3300                                  "ss\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
3301                       []>, VEX_4V, VEX_LIG,
3302                       Sched<[itins.Sched.Folded, ReadAfterLd]>;
3303   }
3304 }
3305
3306   def SSr : SSI<opc, MRMSrcReg, (outs FR32:$dst), (ins FR32:$src),
3307                 !strconcat(OpcodeStr, "ss\t{$src, $dst|$dst, $src}"),
3308                 [(set FR32:$dst, (OpNode FR32:$src))]>, Sched<[itins.Sched]>;
3309   // For scalar unary operations, fold a load into the operation
3310   // only in OptForSize mode. It eliminates an instruction, but it also
3311   // eliminates a whole-register clobber (the load), so it introduces a
3312   // partial register update condition.
3313   def SSm : I<opc, MRMSrcMem, (outs FR32:$dst), (ins f32mem:$src),
3314                 !strconcat(OpcodeStr, "ss\t{$src, $dst|$dst, $src}"),
3315                 [(set FR32:$dst, (OpNode (load addr:$src)))], itins.rm>, XS,
3316             Requires<[UseSSE1, OptForSize]>, Sched<[itins.Sched.Folded]>;
3317 let isCodeGenOnly = 1 in {
3318   def SSr_Int : SSI<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3319                     !strconcat(OpcodeStr, "ss\t{$src, $dst|$dst, $src}"),
3320                     [(set VR128:$dst, (F32Int VR128:$src))], itins.rr>,
3321                 Sched<[itins.Sched]>;
3322   def SSm_Int : SSI<opc, MRMSrcMem, (outs VR128:$dst), (ins ssmem:$src),
3323                     !strconcat(OpcodeStr, "ss\t{$src, $dst|$dst, $src}"),
3324                     [(set VR128:$dst, (F32Int sse_load_f32:$src))], itins.rm>,
3325                 Sched<[itins.Sched.Folded]>;
3326 }
3327 }
3328
3329 /// sse1_fp_unop_s_rw - SSE1 unops where vector form has a read-write operand.
3330 multiclass sse1_fp_unop_rw<bits<8> opc, string OpcodeStr, SDNode OpNode,
3331                            OpndItins itins> {
3332 let Predicates = [HasAVX], hasSideEffects = 0 in {
3333   def V#NAME#SSr : SSI<opc, MRMSrcReg, (outs FR32:$dst),
3334                        (ins FR32:$src1, FR32:$src2),
3335                        !strconcat("v", OpcodeStr,
3336                            "ss\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
3337                 []>, VEX_4V, VEX_LIG, Sched<[itins.Sched]>;
3338   let mayLoad = 1 in {
3339   def V#NAME#SSm : SSI<opc, MRMSrcMem, (outs FR32:$dst),
3340                       (ins FR32:$src1,f32mem:$src2),
3341                       !strconcat("v", OpcodeStr,
3342                                  "ss\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
3343                       []>, VEX_4V, VEX_LIG,
3344                    Sched<[itins.Sched.Folded, ReadAfterLd]>;
3345   let isCodeGenOnly = 1 in
3346   def V#NAME#SSm_Int : SSI<opc, MRMSrcMem, (outs VR128:$dst),
3347                       (ins VR128:$src1, ssmem:$src2),
3348                       !strconcat("v", OpcodeStr,
3349                                  "ss\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
3350                       []>, VEX_4V, VEX_LIG,
3351                       Sched<[itins.Sched.Folded, ReadAfterLd]>;
3352   }
3353 }
3354
3355   def SSr : SSI<opc, MRMSrcReg, (outs FR32:$dst), (ins FR32:$src),
3356                 !strconcat(OpcodeStr, "ss\t{$src, $dst|$dst, $src}"),
3357                 [(set FR32:$dst, (OpNode FR32:$src))]>, Sched<[itins.Sched]>;
3358   // For scalar unary operations, fold a load into the operation
3359   // only in OptForSize mode. It eliminates an instruction, but it also
3360   // eliminates a whole-register clobber (the load), so it introduces a
3361   // partial register update condition.
3362   def SSm : I<opc, MRMSrcMem, (outs FR32:$dst), (ins f32mem:$src),
3363                 !strconcat(OpcodeStr, "ss\t{$src, $dst|$dst, $src}"),
3364                 [(set FR32:$dst, (OpNode (load addr:$src)))], itins.rm>, XS,
3365             Requires<[UseSSE1, OptForSize]>, Sched<[itins.Sched.Folded]>;
3366   let isCodeGenOnly = 1, Constraints = "$src1 = $dst" in {
3367     def SSr_Int : SSI<opc, MRMSrcReg, (outs VR128:$dst),
3368                       (ins VR128:$src1, VR128:$src2),
3369                       !strconcat(OpcodeStr, "ss\t{$src2, $dst|$dst, $src2}"),
3370                       [], itins.rr>, Sched<[itins.Sched]>;
3371     let mayLoad = 1, hasSideEffects = 0 in
3372     def SSm_Int : SSI<opc, MRMSrcMem, (outs VR128:$dst),
3373                       (ins VR128:$src1, ssmem:$src2),
3374                       !strconcat(OpcodeStr, "ss\t{$src2, $dst|$dst, $src2}"),
3375                       [], itins.rm>, Sched<[itins.Sched.Folded, ReadAfterLd]>;
3376   }
3377 }
3378
3379 /// sse1_fp_unop_p - SSE1 unops in packed form.
3380 multiclass sse1_fp_unop_p<bits<8> opc, string OpcodeStr, SDNode OpNode,
3381                           OpndItins itins> {
3382 let Predicates = [HasAVX] in {
3383   def V#NAME#PSr : PSI<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3384                        !strconcat("v", OpcodeStr,
3385                                   "ps\t{$src, $dst|$dst, $src}"),
3386                        [(set VR128:$dst, (v4f32 (OpNode VR128:$src)))],
3387                        itins.rr>, VEX, Sched<[itins.Sched]>;
3388   def V#NAME#PSm : PSI<opc, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
3389                        !strconcat("v", OpcodeStr,
3390                                   "ps\t{$src, $dst|$dst, $src}"),
3391                        [(set VR128:$dst, (OpNode (loadv4f32 addr:$src)))],
3392                        itins.rm>, VEX, Sched<[itins.Sched.Folded]>;
3393   def V#NAME#PSYr : PSI<opc, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
3394                         !strconcat("v", OpcodeStr,
3395                                    "ps\t{$src, $dst|$dst, $src}"),
3396                         [(set VR256:$dst, (v8f32 (OpNode VR256:$src)))],
3397                         itins.rr>, VEX, VEX_L, Sched<[itins.Sched]>;
3398   def V#NAME#PSYm : PSI<opc, MRMSrcMem, (outs VR256:$dst), (ins f256mem:$src),
3399                         !strconcat("v", OpcodeStr,
3400                                    "ps\t{$src, $dst|$dst, $src}"),
3401                         [(set VR256:$dst, (OpNode (loadv8f32 addr:$src)))],
3402                         itins.rm>, VEX, VEX_L, Sched<[itins.Sched.Folded]>;
3403 }
3404
3405   def PSr : PSI<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3406                 !strconcat(OpcodeStr, "ps\t{$src, $dst|$dst, $src}"),
3407                 [(set VR128:$dst, (v4f32 (OpNode VR128:$src)))], itins.rr>,
3408             Sched<[itins.Sched]>;
3409   def PSm : PSI<opc, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
3410                 !strconcat(OpcodeStr, "ps\t{$src, $dst|$dst, $src}"),
3411                 [(set VR128:$dst, (OpNode (memopv4f32 addr:$src)))], itins.rm>,
3412             Sched<[itins.Sched.Folded]>;
3413 }
3414
3415 /// sse1_fp_unop_p_int - SSE1 intrinsics unops in packed forms.
3416 multiclass sse1_fp_unop_p_int<bits<8> opc, string OpcodeStr,
3417                               Intrinsic V4F32Int, Intrinsic V8F32Int,
3418                               OpndItins itins> {
3419 let isCodeGenOnly = 1 in {
3420 let Predicates = [HasAVX] in {
3421   def V#NAME#PSr_Int : PSI<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3422                            !strconcat("v", OpcodeStr,
3423                                       "ps\t{$src, $dst|$dst, $src}"),
3424                            [(set VR128:$dst, (V4F32Int VR128:$src))],
3425                            itins.rr>, VEX, Sched<[itins.Sched]>;
3426   def V#NAME#PSm_Int : PSI<opc, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
3427                           !strconcat("v", OpcodeStr,
3428                           "ps\t{$src, $dst|$dst, $src}"),
3429                           [(set VR128:$dst, (V4F32Int (loadv4f32 addr:$src)))],
3430                           itins.rm>, VEX, Sched<[itins.Sched.Folded]>;
3431   def V#NAME#PSYr_Int : PSI<opc, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
3432                             !strconcat("v", OpcodeStr,
3433                                        "ps\t{$src, $dst|$dst, $src}"),
3434                             [(set VR256:$dst, (V8F32Int VR256:$src))],
3435                             itins.rr>, VEX, VEX_L, Sched<[itins.Sched]>;
3436   def V#NAME#PSYm_Int : PSI<opc, MRMSrcMem, (outs VR256:$dst),
3437                           (ins f256mem:$src),
3438                           !strconcat("v", OpcodeStr,
3439                                     "ps\t{$src, $dst|$dst, $src}"),
3440                           [(set VR256:$dst, (V8F32Int (loadv8f32 addr:$src)))],
3441                           itins.rm>, VEX, VEX_L, Sched<[itins.Sched.Folded]>;
3442 }
3443
3444   def PSr_Int : PSI<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3445                     !strconcat(OpcodeStr, "ps\t{$src, $dst|$dst, $src}"),
3446                     [(set VR128:$dst, (V4F32Int VR128:$src))],
3447                     itins.rr>, Sched<[itins.Sched]>;
3448   def PSm_Int : PSI<opc, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
3449                     !strconcat(OpcodeStr, "ps\t{$src, $dst|$dst, $src}"),
3450                     [(set VR128:$dst, (V4F32Int (memopv4f32 addr:$src)))],
3451                     itins.rm>, Sched<[itins.Sched.Folded]>;
3452 } // isCodeGenOnly = 1
3453 }
3454
3455 /// sse2_fp_unop_s - SSE2 unops in scalar form.
3456 multiclass sse2_fp_unop_s<bits<8> opc, string OpcodeStr,
3457                           SDNode OpNode, Intrinsic F64Int, OpndItins itins> {
3458 let Predicates = [HasAVX], hasSideEffects = 0 in {
3459   def V#NAME#SDr : SDI<opc, MRMSrcReg, (outs FR64:$dst),
3460                       (ins FR64:$src1, FR64:$src2),
3461                       !strconcat("v", OpcodeStr,
3462                                  "sd\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
3463                       []>, VEX_4V, VEX_LIG, Sched<[itins.Sched]>;
3464   let mayLoad = 1 in {
3465   def V#NAME#SDm : SDI<opc, MRMSrcMem, (outs FR64:$dst),
3466                       (ins FR64:$src1,f64mem:$src2),
3467                       !strconcat("v", OpcodeStr,
3468                                  "sd\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
3469                       []>, VEX_4V, VEX_LIG,
3470                    Sched<[itins.Sched.Folded, ReadAfterLd]>;
3471   let isCodeGenOnly = 1 in
3472   def V#NAME#SDm_Int : SDI<opc, MRMSrcMem, (outs VR128:$dst),
3473                       (ins VR128:$src1, sdmem:$src2),
3474                       !strconcat("v", OpcodeStr,
3475                                  "sd\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
3476                       []>, VEX_4V, VEX_LIG,
3477                       Sched<[itins.Sched.Folded, ReadAfterLd]>;
3478   }
3479 }
3480
3481   def SDr : SDI<opc, MRMSrcReg, (outs FR64:$dst), (ins FR64:$src),
3482                 !strconcat(OpcodeStr, "sd\t{$src, $dst|$dst, $src}"),
3483                 [(set FR64:$dst, (OpNode FR64:$src))], itins.rr>,
3484             Sched<[itins.Sched]>;
3485   // See the comments in sse1_fp_unop_s for why this is OptForSize.
3486   def SDm : I<opc, MRMSrcMem, (outs FR64:$dst), (ins f64mem:$src),
3487                 !strconcat(OpcodeStr, "sd\t{$src, $dst|$dst, $src}"),
3488                 [(set FR64:$dst, (OpNode (load addr:$src)))], itins.rm>, XD,
3489             Requires<[UseSSE2, OptForSize]>, Sched<[itins.Sched.Folded]>;
3490 let isCodeGenOnly = 1 in {
3491   def SDr_Int : SDI<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3492                     !strconcat(OpcodeStr, "sd\t{$src, $dst|$dst, $src}"),
3493                     [(set VR128:$dst, (F64Int VR128:$src))], itins.rr>,
3494                 Sched<[itins.Sched]>;
3495   def SDm_Int : SDI<opc, MRMSrcMem, (outs VR128:$dst), (ins sdmem:$src),
3496                     !strconcat(OpcodeStr, "sd\t{$src, $dst|$dst, $src}"),
3497                     [(set VR128:$dst, (F64Int sse_load_f64:$src))], itins.rm>,
3498                 Sched<[itins.Sched.Folded]>;
3499 }
3500 }
3501
3502 /// sse2_fp_unop_p - SSE2 unops in vector forms.
3503 multiclass sse2_fp_unop_p<bits<8> opc, string OpcodeStr,
3504                           SDNode OpNode, OpndItins itins> {
3505 let Predicates = [HasAVX] in {
3506   def V#NAME#PDr : PDI<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3507                        !strconcat("v", OpcodeStr,
3508                                   "pd\t{$src, $dst|$dst, $src}"),
3509                        [(set VR128:$dst, (v2f64 (OpNode VR128:$src)))],
3510                        itins.rr>, VEX, Sched<[itins.Sched]>;
3511   def V#NAME#PDm : PDI<opc, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
3512                        !strconcat("v", OpcodeStr,
3513                                   "pd\t{$src, $dst|$dst, $src}"),
3514                        [(set VR128:$dst, (OpNode (loadv2f64 addr:$src)))],
3515                        itins.rm>, VEX, Sched<[itins.Sched.Folded]>;
3516   def V#NAME#PDYr : PDI<opc, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
3517                         !strconcat("v", OpcodeStr,
3518                                    "pd\t{$src, $dst|$dst, $src}"),
3519                         [(set VR256:$dst, (v4f64 (OpNode VR256:$src)))],
3520                         itins.rr>, VEX, VEX_L, Sched<[itins.Sched]>;
3521   def V#NAME#PDYm : PDI<opc, MRMSrcMem, (outs VR256:$dst), (ins f256mem:$src),
3522                         !strconcat("v", OpcodeStr,
3523                                    "pd\t{$src, $dst|$dst, $src}"),
3524                         [(set VR256:$dst, (OpNode (loadv4f64 addr:$src)))],
3525                         itins.rm>, VEX, VEX_L, Sched<[itins.Sched.Folded]>;
3526 }
3527
3528   def PDr : PDI<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3529               !strconcat(OpcodeStr, "pd\t{$src, $dst|$dst, $src}"),
3530               [(set VR128:$dst, (v2f64 (OpNode VR128:$src)))], itins.rr>,
3531             Sched<[itins.Sched]>;
3532   def PDm : PDI<opc, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
3533                 !strconcat(OpcodeStr, "pd\t{$src, $dst|$dst, $src}"),
3534                 [(set VR128:$dst, (OpNode (memopv2f64 addr:$src)))], itins.rm>,
3535             Sched<[itins.Sched.Folded]>;
3536 }
3537
3538 // Square root.
3539 defm SQRT  : sse1_fp_unop_s<0x51, "sqrt",  fsqrt, int_x86_sse_sqrt_ss,
3540                             SSE_SQRTSS>,
3541              sse1_fp_unop_p<0x51, "sqrt", fsqrt, SSE_SQRTPS>,
3542              sse2_fp_unop_s<0x51, "sqrt",  fsqrt, int_x86_sse2_sqrt_sd,
3543                             SSE_SQRTSD>,
3544              sse2_fp_unop_p<0x51, "sqrt", fsqrt, SSE_SQRTPD>;
3545
3546 // Reciprocal approximations. Note that these typically require refinement
3547 // in order to obtain suitable precision.
3548 defm RSQRT : sse1_fp_unop_rw<0x52, "rsqrt", X86frsqrt, SSE_SQRTSS>,
3549              sse1_fp_unop_p<0x52, "rsqrt", X86frsqrt, SSE_SQRTPS>,
3550              sse1_fp_unop_p_int<0x52, "rsqrt", int_x86_sse_rsqrt_ps,
3551                                 int_x86_avx_rsqrt_ps_256, SSE_SQRTPS>;
3552 defm RCP   : sse1_fp_unop_rw<0x53, "rcp", X86frcp, SSE_RCPS>,
3553              sse1_fp_unop_p<0x53, "rcp", X86frcp, SSE_RCPP>,
3554              sse1_fp_unop_p_int<0x53, "rcp", int_x86_sse_rcp_ps,
3555                                 int_x86_avx_rcp_ps_256, SSE_RCPP>;
3556
3557 let Predicates = [UseAVX] in {
3558   def : Pat<(f32 (fsqrt FR32:$src)),
3559             (VSQRTSSr (f32 (IMPLICIT_DEF)), FR32:$src)>, Requires<[HasAVX]>;
3560   def : Pat<(f32 (fsqrt (load addr:$src))),
3561             (VSQRTSSm (f32 (IMPLICIT_DEF)), addr:$src)>,
3562             Requires<[HasAVX, OptForSize]>;
3563   def : Pat<(f64 (fsqrt FR64:$src)),
3564             (VSQRTSDr (f64 (IMPLICIT_DEF)), FR64:$src)>, Requires<[HasAVX]>;
3565   def : Pat<(f64 (fsqrt (load addr:$src))),
3566             (VSQRTSDm (f64 (IMPLICIT_DEF)), addr:$src)>,
3567             Requires<[HasAVX, OptForSize]>;
3568
3569   def : Pat<(f32 (X86frsqrt FR32:$src)),
3570             (VRSQRTSSr (f32 (IMPLICIT_DEF)), FR32:$src)>, Requires<[HasAVX]>;
3571   def : Pat<(f32 (X86frsqrt (load addr:$src))),
3572             (VRSQRTSSm (f32 (IMPLICIT_DEF)), addr:$src)>,
3573             Requires<[HasAVX, OptForSize]>;
3574
3575   def : Pat<(f32 (X86frcp FR32:$src)),
3576             (VRCPSSr (f32 (IMPLICIT_DEF)), FR32:$src)>, Requires<[HasAVX]>;
3577   def : Pat<(f32 (X86frcp (load addr:$src))),
3578             (VRCPSSm (f32 (IMPLICIT_DEF)), addr:$src)>,
3579             Requires<[HasAVX, OptForSize]>;
3580 }
3581 let Predicates = [UseAVX] in {
3582   def : Pat<(int_x86_sse_sqrt_ss VR128:$src),
3583             (COPY_TO_REGCLASS (VSQRTSSr (f32 (IMPLICIT_DEF)),
3584                                         (COPY_TO_REGCLASS VR128:$src, FR32)),
3585                               VR128)>;
3586   def : Pat<(int_x86_sse_sqrt_ss sse_load_f32:$src),
3587             (VSQRTSSm_Int (v4f32 (IMPLICIT_DEF)), sse_load_f32:$src)>;
3588
3589   def : Pat<(int_x86_sse2_sqrt_sd VR128:$src),
3590             (COPY_TO_REGCLASS (VSQRTSDr (f64 (IMPLICIT_DEF)),
3591                                         (COPY_TO_REGCLASS VR128:$src, FR64)),
3592                               VR128)>;
3593   def : Pat<(int_x86_sse2_sqrt_sd sse_load_f64:$src),
3594             (VSQRTSDm_Int (v2f64 (IMPLICIT_DEF)), sse_load_f64:$src)>;
3595 }
3596
3597 let Predicates = [HasAVX] in {
3598   def : Pat<(int_x86_sse_rsqrt_ss VR128:$src),
3599             (COPY_TO_REGCLASS (VRSQRTSSr (f32 (IMPLICIT_DEF)),
3600                                          (COPY_TO_REGCLASS VR128:$src, FR32)),
3601                               VR128)>;
3602   def : Pat<(int_x86_sse_rsqrt_ss sse_load_f32:$src),
3603             (VRSQRTSSm_Int (v4f32 (IMPLICIT_DEF)), sse_load_f32:$src)>;
3604
3605   def : Pat<(int_x86_sse_rcp_ss VR128:$src),
3606             (COPY_TO_REGCLASS (VRCPSSr (f32 (IMPLICIT_DEF)),
3607                                        (COPY_TO_REGCLASS VR128:$src, FR32)),
3608                               VR128)>;
3609   def : Pat<(int_x86_sse_rcp_ss sse_load_f32:$src),
3610             (VRCPSSm_Int (v4f32 (IMPLICIT_DEF)), sse_load_f32:$src)>;
3611 }
3612
3613 // Reciprocal approximations. Note that these typically require refinement
3614 // in order to obtain suitable precision.
3615 let Predicates = [UseSSE1] in {
3616   def : Pat<(int_x86_sse_rsqrt_ss VR128:$src),
3617             (RSQRTSSr_Int VR128:$src, VR128:$src)>;
3618   def : Pat<(int_x86_sse_rcp_ss VR128:$src),
3619             (RCPSSr_Int VR128:$src, VR128:$src)>;
3620 }
3621
3622 // There is no f64 version of the reciprocal approximation instructions.
3623
3624 //===----------------------------------------------------------------------===//
3625 // SSE 1 & 2 - Non-temporal stores
3626 //===----------------------------------------------------------------------===//
3627
3628 let AddedComplexity = 400 in { // Prefer non-temporal versions
3629 let SchedRW = [WriteStore] in {
3630 def VMOVNTPSmr : VPSI<0x2B, MRMDestMem, (outs),
3631                      (ins f128mem:$dst, VR128:$src),
3632                      "movntps\t{$src, $dst|$dst, $src}",
3633                      [(alignednontemporalstore (v4f32 VR128:$src),
3634                                                addr:$dst)],
3635                                                IIC_SSE_MOVNT>, VEX;
3636 def VMOVNTPDmr : VPDI<0x2B, MRMDestMem, (outs),
3637                      (ins f128mem:$dst, VR128:$src),
3638                      "movntpd\t{$src, $dst|$dst, $src}",
3639                      [(alignednontemporalstore (v2f64 VR128:$src),
3640                                                addr:$dst)],
3641                                                IIC_SSE_MOVNT>, VEX;
3642
3643 let ExeDomain = SSEPackedInt in
3644 def VMOVNTDQmr    : VPDI<0xE7, MRMDestMem, (outs),
3645                          (ins f128mem:$dst, VR128:$src),
3646                          "movntdq\t{$src, $dst|$dst, $src}",
3647                          [(alignednontemporalstore (v2i64 VR128:$src),
3648                                                    addr:$dst)],
3649                                                    IIC_SSE_MOVNT>, VEX;
3650
3651 def VMOVNTPSYmr : VPSI<0x2B, MRMDestMem, (outs),
3652                      (ins f256mem:$dst, VR256:$src),
3653                      "movntps\t{$src, $dst|$dst, $src}",
3654                      [(alignednontemporalstore (v8f32 VR256:$src),
3655                                                addr:$dst)],
3656                                                IIC_SSE_MOVNT>, VEX, VEX_L;
3657 def VMOVNTPDYmr : VPDI<0x2B, MRMDestMem, (outs),
3658                      (ins f256mem:$dst, VR256:$src),
3659                      "movntpd\t{$src, $dst|$dst, $src}",
3660                      [(alignednontemporalstore (v4f64 VR256:$src),
3661                                                addr:$dst)],
3662                                                IIC_SSE_MOVNT>, VEX, VEX_L;
3663 let ExeDomain = SSEPackedInt in
3664 def VMOVNTDQYmr : VPDI<0xE7, MRMDestMem, (outs),
3665                     (ins f256mem:$dst, VR256:$src),
3666                     "movntdq\t{$src, $dst|$dst, $src}",
3667                     [(alignednontemporalstore (v4i64 VR256:$src),
3668                                               addr:$dst)],
3669                                               IIC_SSE_MOVNT>, VEX, VEX_L;
3670
3671 def MOVNTPSmr : PSI<0x2B, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
3672                     "movntps\t{$src, $dst|$dst, $src}",
3673                     [(alignednontemporalstore (v4f32 VR128:$src), addr:$dst)],
3674                     IIC_SSE_MOVNT>;
3675 def MOVNTPDmr : PDI<0x2B, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
3676                     "movntpd\t{$src, $dst|$dst, $src}",
3677                     [(alignednontemporalstore(v2f64 VR128:$src), addr:$dst)],
3678                     IIC_SSE_MOVNT>;
3679
3680 let ExeDomain = SSEPackedInt in
3681 def MOVNTDQmr : PDI<0xE7, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
3682                     "movntdq\t{$src, $dst|$dst, $src}",
3683                     [(alignednontemporalstore (v2i64 VR128:$src), addr:$dst)],
3684                     IIC_SSE_MOVNT>;
3685
3686 // There is no AVX form for instructions below this point
3687 def MOVNTImr : I<0xC3, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
3688                  "movnti{l}\t{$src, $dst|$dst, $src}",
3689                  [(nontemporalstore (i32 GR32:$src), addr:$dst)],
3690                  IIC_SSE_MOVNT>,
3691                TB, Requires<[HasSSE2]>;
3692 def MOVNTI_64mr : RI<0xC3, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
3693                      "movnti{q}\t{$src, $dst|$dst, $src}",
3694                      [(nontemporalstore (i64 GR64:$src), addr:$dst)],
3695                      IIC_SSE_MOVNT>,
3696                   TB, Requires<[HasSSE2]>;
3697 } // SchedRW = [WriteStore]
3698
3699 def : Pat<(alignednontemporalstore (v2i64 VR128:$src), addr:$dst),
3700           (VMOVNTDQmr addr:$dst, VR128:$src)>, Requires<[HasAVX]>;
3701
3702 def : Pat<(alignednontemporalstore (v2i64 VR128:$src), addr:$dst),
3703           (MOVNTDQmr addr:$dst, VR128:$src)>, Requires<[UseSSE2]>;
3704 } // AddedComplexity
3705
3706 //===----------------------------------------------------------------------===//
3707 // SSE 1 & 2 - Prefetch and memory fence
3708 //===----------------------------------------------------------------------===//
3709
3710 // Prefetch intrinsic.
3711 let Predicates = [HasSSE1], SchedRW = [WriteLoad] in {
3712 def PREFETCHT0   : I<0x18, MRM1m, (outs), (ins i8mem:$src),
3713     "prefetcht0\t$src", [(prefetch addr:$src, imm, (i32 3), (i32 1))],
3714     IIC_SSE_PREFETCH>, TB;
3715 def PREFETCHT1   : I<0x18, MRM2m, (outs), (ins i8mem:$src),
3716     "prefetcht1\t$src", [(prefetch addr:$src, imm, (i32 2), (i32 1))],
3717     IIC_SSE_PREFETCH>, TB;
3718 def PREFETCHT2   : I<0x18, MRM3m, (outs), (ins i8mem:$src),
3719     "prefetcht2\t$src", [(prefetch addr:$src, imm, (i32 1), (i32 1))],
3720     IIC_SSE_PREFETCH>, TB;
3721 def PREFETCHNTA  : I<0x18, MRM0m, (outs), (ins i8mem:$src),
3722     "prefetchnta\t$src", [(prefetch addr:$src, imm, (i32 0), (i32 1))],
3723     IIC_SSE_PREFETCH>, TB;
3724 }
3725
3726 // FIXME: How should these memory instructions be modeled?
3727 let SchedRW = [WriteLoad] in {
3728 // Flush cache
3729 def CLFLUSH : I<0xAE, MRM7m, (outs), (ins i8mem:$src),
3730                "clflush\t$src", [(int_x86_sse2_clflush addr:$src)],
3731                IIC_SSE_PREFETCH>, TB, Requires<[HasSSE2]>;
3732
3733 // Pause. This "instruction" is encoded as "rep; nop", so even though it
3734 // was introduced with SSE2, it's backward compatible.
3735 def PAUSE : I<0x90, RawFrm, (outs), (ins),  
3736               "pause", [(int_x86_sse2_pause)], IIC_SSE_PAUSE>, 
3737               REP, Requires<[HasSSE2]>;
3738
3739 // Load, store, and memory fence
3740 def SFENCE : I<0xAE, MRM_F8, (outs), (ins),
3741                "sfence", [(int_x86_sse_sfence)], IIC_SSE_SFENCE>,
3742                TB, Requires<[HasSSE1]>;
3743 def LFENCE : I<0xAE, MRM_E8, (outs), (ins),
3744                "lfence", [(int_x86_sse2_lfence)], IIC_SSE_LFENCE>,
3745                TB, Requires<[HasSSE2]>;
3746 def MFENCE : I<0xAE, MRM_F0, (outs), (ins),
3747                "mfence", [(int_x86_sse2_mfence)], IIC_SSE_MFENCE>,
3748                TB, Requires<[HasSSE2]>;
3749 } // SchedRW
3750
3751 def : Pat<(X86SFence), (SFENCE)>;
3752 def : Pat<(X86LFence), (LFENCE)>;
3753 def : Pat<(X86MFence), (MFENCE)>;
3754
3755 //===----------------------------------------------------------------------===//
3756 // SSE 1 & 2 - Load/Store XCSR register
3757 //===----------------------------------------------------------------------===//
3758
3759 def VLDMXCSR : VPSI<0xAE, MRM2m, (outs), (ins i32mem:$src),
3760                   "ldmxcsr\t$src", [(int_x86_sse_ldmxcsr addr:$src)],
3761                   IIC_SSE_LDMXCSR>, VEX, Sched<[WriteLoad]>;
3762 def VSTMXCSR : VPSI<0xAE, MRM3m, (outs), (ins i32mem:$dst),
3763                   "stmxcsr\t$dst", [(int_x86_sse_stmxcsr addr:$dst)],
3764                   IIC_SSE_STMXCSR>, VEX, Sched<[WriteStore]>;
3765
3766 def LDMXCSR : PSI<0xAE, MRM2m, (outs), (ins i32mem:$src),
3767                   "ldmxcsr\t$src", [(int_x86_sse_ldmxcsr addr:$src)],
3768                   IIC_SSE_LDMXCSR>, Sched<[WriteLoad]>;
3769 def STMXCSR : PSI<0xAE, MRM3m, (outs), (ins i32mem:$dst),
3770                   "stmxcsr\t$dst", [(int_x86_sse_stmxcsr addr:$dst)],
3771                   IIC_SSE_STMXCSR>, Sched<[WriteStore]>;
3772
3773 //===---------------------------------------------------------------------===//
3774 // SSE2 - Move Aligned/Unaligned Packed Integer Instructions
3775 //===---------------------------------------------------------------------===//
3776
3777 let ExeDomain = SSEPackedInt in { // SSE integer instructions
3778
3779 let neverHasSideEffects = 1, SchedRW = [WriteMove] in {
3780 def VMOVDQArr  : VPDI<0x6F, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3781                     "movdqa\t{$src, $dst|$dst, $src}", [], IIC_SSE_MOVA_P_RR>,
3782                     VEX;
3783 def VMOVDQAYrr : VPDI<0x6F, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
3784                     "movdqa\t{$src, $dst|$dst, $src}", [], IIC_SSE_MOVA_P_RR>,
3785                     VEX, VEX_L;
3786 def VMOVDQUrr  : VSSI<0x6F, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3787                     "movdqu\t{$src, $dst|$dst, $src}", [], IIC_SSE_MOVU_P_RR>,
3788                     VEX;
3789 def VMOVDQUYrr : VSSI<0x6F, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
3790                     "movdqu\t{$src, $dst|$dst, $src}", [], IIC_SSE_MOVU_P_RR>,
3791                     VEX, VEX_L;
3792 }
3793
3794 // For Disassembler
3795 let isCodeGenOnly = 1, hasSideEffects = 0, SchedRW = [WriteMove] in {
3796 def VMOVDQArr_REV  : VPDI<0x7F, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
3797                         "movdqa\t{$src, $dst|$dst, $src}", [],
3798                         IIC_SSE_MOVA_P_RR>,
3799                         VEX;
3800 def VMOVDQAYrr_REV : VPDI<0x7F, MRMDestReg, (outs VR256:$dst), (ins VR256:$src),
3801                         "movdqa\t{$src, $dst|$dst, $src}", [],
3802                         IIC_SSE_MOVA_P_RR>, VEX, VEX_L;
3803 def VMOVDQUrr_REV  : VSSI<0x7F, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
3804                         "movdqu\t{$src, $dst|$dst, $src}", [],
3805                         IIC_SSE_MOVU_P_RR>,
3806                         VEX;
3807 def VMOVDQUYrr_REV : VSSI<0x7F, MRMDestReg, (outs VR256:$dst), (ins VR256:$src),
3808                         "movdqu\t{$src, $dst|$dst, $src}", [],
3809                         IIC_SSE_MOVU_P_RR>, VEX, VEX_L;
3810 }
3811
3812 let canFoldAsLoad = 1, mayLoad = 1, isReMaterializable = 1,
3813     neverHasSideEffects = 1, SchedRW = [WriteLoad] in {
3814 def VMOVDQArm  : VPDI<0x6F, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
3815                    "movdqa\t{$src, $dst|$dst, $src}", [], IIC_SSE_MOVA_P_RM>,
3816                    VEX;
3817 def VMOVDQAYrm : VPDI<0x6F, MRMSrcMem, (outs VR256:$dst), (ins i256mem:$src),
3818                    "movdqa\t{$src, $dst|$dst, $src}", [], IIC_SSE_MOVA_P_RM>,
3819                    VEX, VEX_L;
3820 let Predicates = [HasAVX] in {
3821   def VMOVDQUrm  : I<0x6F, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
3822                     "vmovdqu\t{$src, $dst|$dst, $src}",[], IIC_SSE_MOVU_P_RM>,
3823                     XS, VEX;
3824   def VMOVDQUYrm : I<0x6F, MRMSrcMem, (outs VR256:$dst), (ins i256mem:$src),
3825                     "vmovdqu\t{$src, $dst|$dst, $src}",[], IIC_SSE_MOVU_P_RM>,
3826                     XS, VEX, VEX_L;
3827 }
3828 }
3829
3830 let mayStore = 1, neverHasSideEffects = 1, SchedRW = [WriteStore] in {
3831 def VMOVDQAmr  : VPDI<0x7F, MRMDestMem, (outs),
3832                      (ins i128mem:$dst, VR128:$src),
3833                      "movdqa\t{$src, $dst|$dst, $src}", [], IIC_SSE_MOVA_P_MR>,
3834                      VEX;
3835 def VMOVDQAYmr : VPDI<0x7F, MRMDestMem, (outs),
3836                      (ins i256mem:$dst, VR256:$src),
3837                      "movdqa\t{$src, $dst|$dst, $src}", [], IIC_SSE_MOVA_P_MR>,
3838                      VEX, VEX_L;
3839 let Predicates = [HasAVX] in {
3840 def VMOVDQUmr  : I<0x7F, MRMDestMem, (outs), (ins i128mem:$dst, VR128:$src),
3841                   "vmovdqu\t{$src, $dst|$dst, $src}",[], IIC_SSE_MOVU_P_MR>,
3842                   XS, VEX;
3843 def VMOVDQUYmr : I<0x7F, MRMDestMem, (outs), (ins i256mem:$dst, VR256:$src),
3844                   "vmovdqu\t{$src, $dst|$dst, $src}",[], IIC_SSE_MOVU_P_MR>,
3845                   XS, VEX, VEX_L;
3846 }
3847 }
3848
3849 let SchedRW = [WriteMove] in {
3850 let neverHasSideEffects = 1 in
3851 def MOVDQArr : PDI<0x6F, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3852                    "movdqa\t{$src, $dst|$dst, $src}", [], IIC_SSE_MOVA_P_RR>;
3853
3854 def MOVDQUrr :   I<0x6F, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3855                    "movdqu\t{$src, $dst|$dst, $src}",
3856                    [], IIC_SSE_MOVU_P_RR>, XS, Requires<[UseSSE2]>;
3857
3858 // For Disassembler
3859 let isCodeGenOnly = 1, hasSideEffects = 0 in {
3860 def MOVDQArr_REV : PDI<0x7F, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
3861                        "movdqa\t{$src, $dst|$dst, $src}", [],
3862                        IIC_SSE_MOVA_P_RR>;
3863
3864 def MOVDQUrr_REV :   I<0x7F, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
3865                        "movdqu\t{$src, $dst|$dst, $src}",
3866                        [], IIC_SSE_MOVU_P_RR>, XS, Requires<[UseSSE2]>;
3867 }
3868 } // SchedRW
3869
3870 let canFoldAsLoad = 1, mayLoad = 1, isReMaterializable = 1,
3871     neverHasSideEffects = 1, SchedRW = [WriteLoad] in {
3872 def MOVDQArm : PDI<0x6F, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
3873                    "movdqa\t{$src, $dst|$dst, $src}",
3874                    [/*(set VR128:$dst, (alignedloadv2i64 addr:$src))*/],
3875                    IIC_SSE_MOVA_P_RM>;
3876 def MOVDQUrm :   I<0x6F, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
3877                    "movdqu\t{$src, $dst|$dst, $src}",
3878                    [/*(set VR128:$dst, (loadv2i64 addr:$src))*/],
3879                    IIC_SSE_MOVU_P_RM>,
3880                  XS, Requires<[UseSSE2]>;
3881 }
3882
3883 let mayStore = 1, neverHasSideEffects = 1, SchedRW = [WriteStore] in {
3884 def MOVDQAmr : PDI<0x7F, MRMDestMem, (outs), (ins i128mem:$dst, VR128:$src),
3885                    "movdqa\t{$src, $dst|$dst, $src}",
3886                    [/*(alignedstore (v2i64 VR128:$src), addr:$dst)*/],
3887                    IIC_SSE_MOVA_P_MR>;
3888 def MOVDQUmr :   I<0x7F, MRMDestMem, (outs), (ins i128mem:$dst, VR128:$src),
3889                    "movdqu\t{$src, $dst|$dst, $src}",
3890                    [/*(store (v2i64 VR128:$src), addr:$dst)*/],
3891                    IIC_SSE_MOVU_P_MR>,
3892                  XS, Requires<[UseSSE2]>;
3893 }
3894
3895 } // ExeDomain = SSEPackedInt
3896
3897 let Predicates = [HasAVX] in {
3898   def : Pat<(int_x86_sse2_storeu_dq addr:$dst, VR128:$src),
3899             (VMOVDQUmr addr:$dst, VR128:$src)>;
3900   def : Pat<(int_x86_avx_storeu_dq_256 addr:$dst, VR256:$src),
3901             (VMOVDQUYmr addr:$dst, VR256:$src)>;
3902 }
3903 let Predicates = [UseSSE2] in
3904 def : Pat<(int_x86_sse2_storeu_dq addr:$dst, VR128:$src),
3905           (MOVDQUmr addr:$dst, VR128:$src)>;
3906
3907 //===---------------------------------------------------------------------===//
3908 // SSE2 - Packed Integer Arithmetic Instructions
3909 //===---------------------------------------------------------------------===//
3910
3911 let Sched = WriteVecIMul in
3912 def SSE_PMADD : OpndItins<
3913   IIC_SSE_PMADD, IIC_SSE_PMADD
3914 >;
3915
3916 let ExeDomain = SSEPackedInt in { // SSE integer instructions
3917
3918 multiclass PDI_binop_rm_int<bits<8> opc, string OpcodeStr, Intrinsic IntId,
3919                             RegisterClass RC, PatFrag memop_frag,
3920                             X86MemOperand x86memop,
3921                             OpndItins itins,
3922                             bit IsCommutable = 0,
3923                             bit Is2Addr = 1> {
3924   let isCommutable = IsCommutable in
3925   def rr : PDI<opc, MRMSrcReg, (outs RC:$dst),
3926        (ins RC:$src1, RC:$src2),
3927        !if(Is2Addr,
3928            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
3929            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
3930        [(set RC:$dst, (IntId RC:$src1, RC:$src2))], itins.rr>,
3931       Sched<[itins.Sched]>;
3932   def rm : PDI<opc, MRMSrcMem, (outs RC:$dst),
3933        (ins RC:$src1, x86memop:$src2),
3934        !if(Is2Addr,
3935            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
3936            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
3937        [(set RC:$dst, (IntId RC:$src1, (bitconvert (memop_frag addr:$src2))))],
3938        itins.rm>, Sched<[itins.Sched.Folded, ReadAfterLd]>;
3939 }
3940
3941 multiclass PDI_binop_all_int<bits<8> opc, string OpcodeStr, Intrinsic IntId128,
3942                              Intrinsic IntId256, OpndItins itins,
3943                              bit IsCommutable = 0> {
3944 let Predicates = [HasAVX] in
3945   defm V#NAME : PDI_binop_rm_int<opc, !strconcat("v", OpcodeStr), IntId128,
3946                                  VR128, loadv2i64, i128mem, itins,
3947                                  IsCommutable, 0>, VEX_4V;
3948
3949 let Constraints = "$src1 = $dst" in
3950   defm NAME : PDI_binop_rm_int<opc, OpcodeStr, IntId128, VR128, memopv2i64,
3951                                i128mem, itins, IsCommutable, 1>;
3952
3953 let Predicates = [HasAVX2] in
3954   defm V#NAME#Y : PDI_binop_rm_int<opc, !strconcat("v", OpcodeStr), IntId256,
3955                                    VR256, loadv4i64, i256mem, itins,
3956                                    IsCommutable, 0>, VEX_4V, VEX_L;
3957 }
3958
3959 multiclass PDI_binop_rmi<bits<8> opc, bits<8> opc2, Format ImmForm,
3960                          string OpcodeStr, SDNode OpNode,
3961                          SDNode OpNode2, RegisterClass RC,
3962                          ValueType DstVT, ValueType SrcVT, PatFrag bc_frag,
3963                          ShiftOpndItins itins,
3964                          bit Is2Addr = 1> {
3965   // src2 is always 128-bit
3966   def rr : PDI<opc, MRMSrcReg, (outs RC:$dst),
3967        (ins RC:$src1, VR128:$src2),
3968        !if(Is2Addr,
3969            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
3970            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
3971        [(set RC:$dst, (DstVT (OpNode RC:$src1, (SrcVT VR128:$src2))))],
3972         itins.rr>, Sched<[WriteVecShift]>;
3973   def rm : PDI<opc, MRMSrcMem, (outs RC:$dst),
3974        (ins RC:$src1, i128mem:$src2),
3975        !if(Is2Addr,
3976            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
3977            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
3978        [(set RC:$dst, (DstVT (OpNode RC:$src1,
3979                        (bc_frag (memopv2i64 addr:$src2)))))], itins.rm>,
3980       Sched<[WriteVecShiftLd, ReadAfterLd]>;
3981   def ri : PDIi8<opc2, ImmForm, (outs RC:$dst),
3982        (ins RC:$src1, i8imm:$src2),
3983        !if(Is2Addr,
3984            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
3985            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
3986        [(set RC:$dst, (DstVT (OpNode2 RC:$src1, (i8 imm:$src2))))], itins.ri>,
3987        Sched<[WriteVecShift]>;
3988 }
3989
3990 /// PDI_binop_rm2 - Simple SSE2 binary operator with different src and dst types
3991 multiclass PDI_binop_rm2<bits<8> opc, string OpcodeStr, SDNode OpNode,
3992                          ValueType DstVT, ValueType SrcVT, RegisterClass RC,
3993                          PatFrag memop_frag, X86MemOperand x86memop,
3994                          OpndItins itins,
3995                          bit IsCommutable = 0, bit Is2Addr = 1> {
3996   let isCommutable = IsCommutable in
3997   def rr : PDI<opc, MRMSrcReg, (outs RC:$dst),
3998        (ins RC:$src1, RC:$src2),
3999        !if(Is2Addr,
4000            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
4001            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
4002        [(set RC:$dst, (DstVT (OpNode (SrcVT RC:$src1), RC:$src2)))]>,
4003        Sched<[itins.Sched]>;
4004   def rm : PDI<opc, MRMSrcMem, (outs RC:$dst),
4005        (ins RC:$src1, x86memop:$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, (DstVT (OpNode (SrcVT RC:$src1),
4010                                      (bitconvert (memop_frag addr:$src2)))))]>,
4011        Sched<[itins.Sched.Folded, ReadAfterLd]>;
4012 }
4013 } // ExeDomain = SSEPackedInt
4014
4015 defm PADDB   : PDI_binop_all<0xFC, "paddb", add, v16i8, v32i8,
4016                              SSE_INTALU_ITINS_P, 1>;
4017 defm PADDW   : PDI_binop_all<0xFD, "paddw", add, v8i16, v16i16,
4018                              SSE_INTALU_ITINS_P, 1>;
4019 defm PADDD   : PDI_binop_all<0xFE, "paddd", add, v4i32, v8i32,
4020                              SSE_INTALU_ITINS_P, 1>;
4021 defm PADDQ   : PDI_binop_all<0xD4, "paddq", add, v2i64, v4i64,
4022                              SSE_INTALUQ_ITINS_P, 1>;
4023 defm PMULLW  : PDI_binop_all<0xD5, "pmullw", mul, v8i16, v16i16,
4024                              SSE_INTMUL_ITINS_P, 1>;
4025 defm PSUBB   : PDI_binop_all<0xF8, "psubb", sub, v16i8, v32i8,
4026                              SSE_INTALU_ITINS_P, 0>;
4027 defm PSUBW   : PDI_binop_all<0xF9, "psubw", sub, v8i16, v16i16,
4028                              SSE_INTALU_ITINS_P, 0>;
4029 defm PSUBD   : PDI_binop_all<0xFA, "psubd", sub, v4i32, v8i32,
4030                              SSE_INTALU_ITINS_P, 0>;
4031 defm PSUBQ   : PDI_binop_all<0xFB, "psubq", sub, v2i64, v4i64,
4032                              SSE_INTALUQ_ITINS_P, 0>;
4033 defm PSUBUSB : PDI_binop_all<0xD8, "psubusb", X86subus, v16i8, v32i8,
4034                              SSE_INTALU_ITINS_P, 0>;
4035 defm PSUBUSW : PDI_binop_all<0xD9, "psubusw", X86subus, v8i16, v16i16,
4036                              SSE_INTALU_ITINS_P, 0>;
4037 defm PMINUB  : PDI_binop_all<0xDA, "pminub", X86umin, v16i8, v32i8,
4038                              SSE_INTALU_ITINS_P, 1>;
4039 defm PMINSW  : PDI_binop_all<0xEA, "pminsw", X86smin, v8i16, v16i16,
4040                              SSE_INTALU_ITINS_P, 1>;
4041 defm PMAXUB  : PDI_binop_all<0xDE, "pmaxub", X86umax, v16i8, v32i8,
4042                              SSE_INTALU_ITINS_P, 1>;
4043 defm PMAXSW  : PDI_binop_all<0xEE, "pmaxsw", X86smax, v8i16, v16i16,
4044                              SSE_INTALU_ITINS_P, 1>;
4045
4046 // Intrinsic forms
4047 defm PSUBSB  : PDI_binop_all_int<0xE8, "psubsb", int_x86_sse2_psubs_b,
4048                                  int_x86_avx2_psubs_b, SSE_INTALU_ITINS_P, 0>;
4049 defm PSUBSW  : PDI_binop_all_int<0xE9, "psubsw" , int_x86_sse2_psubs_w,
4050                                  int_x86_avx2_psubs_w, SSE_INTALU_ITINS_P, 0>;
4051 defm PADDSB  : PDI_binop_all_int<0xEC, "paddsb" , int_x86_sse2_padds_b,
4052                                  int_x86_avx2_padds_b, SSE_INTALU_ITINS_P, 1>;
4053 defm PADDSW  : PDI_binop_all_int<0xED, "paddsw" , int_x86_sse2_padds_w,
4054                                  int_x86_avx2_padds_w, SSE_INTALU_ITINS_P, 1>;
4055 defm PADDUSB : PDI_binop_all_int<0xDC, "paddusb", int_x86_sse2_paddus_b,
4056                                  int_x86_avx2_paddus_b, SSE_INTALU_ITINS_P, 1>;
4057 defm PADDUSW : PDI_binop_all_int<0xDD, "paddusw", int_x86_sse2_paddus_w,
4058                                  int_x86_avx2_paddus_w, SSE_INTALU_ITINS_P, 1>;
4059 defm PMULHUW : PDI_binop_all_int<0xE4, "pmulhuw", int_x86_sse2_pmulhu_w,
4060                                  int_x86_avx2_pmulhu_w, SSE_INTMUL_ITINS_P, 1>;
4061 defm PMULHW  : PDI_binop_all_int<0xE5, "pmulhw" , int_x86_sse2_pmulh_w,
4062                                  int_x86_avx2_pmulh_w, SSE_INTMUL_ITINS_P, 1>;
4063 defm PMADDWD : PDI_binop_all_int<0xF5, "pmaddwd", int_x86_sse2_pmadd_wd,
4064                                  int_x86_avx2_pmadd_wd, SSE_PMADD, 1>;
4065 defm PAVGB   : PDI_binop_all_int<0xE0, "pavgb", int_x86_sse2_pavg_b,
4066                                  int_x86_avx2_pavg_b, SSE_INTALU_ITINS_P, 1>;
4067 defm PAVGW   : PDI_binop_all_int<0xE3, "pavgw", int_x86_sse2_pavg_w,
4068                                  int_x86_avx2_pavg_w, SSE_INTALU_ITINS_P, 1>;
4069 defm PSADBW  : PDI_binop_all_int<0xF6, "psadbw", int_x86_sse2_psad_bw,
4070                                  int_x86_avx2_psad_bw, SSE_PMADD, 1>;
4071
4072 let Predicates = [HasAVX] in
4073 defm VPMULUDQ : PDI_binop_rm2<0xF4, "vpmuludq", X86pmuludq, v2i64, v4i32, VR128,
4074                               loadv2i64, i128mem, SSE_INTMUL_ITINS_P, 1, 0>,
4075                               VEX_4V;
4076 let Predicates = [HasAVX2] in
4077 defm VPMULUDQY : PDI_binop_rm2<0xF4, "vpmuludq", X86pmuludq, v4i64, v8i32,
4078                                VR256, loadv4i64, i256mem,
4079                                SSE_INTMUL_ITINS_P, 1, 0>, VEX_4V, VEX_L;
4080 let Constraints = "$src1 = $dst" in
4081 defm PMULUDQ : PDI_binop_rm2<0xF4, "pmuludq", X86pmuludq, v2i64, v4i32, VR128,
4082                              memopv2i64, i128mem, SSE_INTMUL_ITINS_P, 1>;
4083
4084 //===---------------------------------------------------------------------===//
4085 // SSE2 - Packed Integer Logical Instructions
4086 //===---------------------------------------------------------------------===//
4087
4088 let Predicates = [HasAVX] in {
4089 defm VPSLLW : PDI_binop_rmi<0xF1, 0x71, MRM6r, "vpsllw", X86vshl, X86vshli,
4090                             VR128, v8i16, v8i16, bc_v8i16,
4091                             SSE_INTSHIFT_ITINS_P, 0>, VEX_4V;
4092 defm VPSLLD : PDI_binop_rmi<0xF2, 0x72, MRM6r, "vpslld", X86vshl, X86vshli,
4093                             VR128, v4i32, v4i32, bc_v4i32,
4094                             SSE_INTSHIFT_ITINS_P, 0>, VEX_4V;
4095 defm VPSLLQ : PDI_binop_rmi<0xF3, 0x73, MRM6r, "vpsllq", X86vshl, X86vshli,
4096                             VR128, v2i64, v2i64, bc_v2i64,
4097                             SSE_INTSHIFT_ITINS_P, 0>, VEX_4V;
4098
4099 defm VPSRLW : PDI_binop_rmi<0xD1, 0x71, MRM2r, "vpsrlw", X86vsrl, X86vsrli,
4100                             VR128, v8i16, v8i16, bc_v8i16,
4101                             SSE_INTSHIFT_ITINS_P, 0>, VEX_4V;
4102 defm VPSRLD : PDI_binop_rmi<0xD2, 0x72, MRM2r, "vpsrld", X86vsrl, X86vsrli,
4103                             VR128, v4i32, v4i32, bc_v4i32,
4104                             SSE_INTSHIFT_ITINS_P, 0>, VEX_4V;
4105 defm VPSRLQ : PDI_binop_rmi<0xD3, 0x73, MRM2r, "vpsrlq", X86vsrl, X86vsrli,
4106                             VR128, v2i64, v2i64, bc_v2i64,
4107                             SSE_INTSHIFT_ITINS_P, 0>, VEX_4V;
4108
4109 defm VPSRAW : PDI_binop_rmi<0xE1, 0x71, MRM4r, "vpsraw", X86vsra, X86vsrai,
4110                             VR128, v8i16, v8i16, bc_v8i16,
4111                             SSE_INTSHIFT_ITINS_P, 0>, VEX_4V;
4112 defm VPSRAD : PDI_binop_rmi<0xE2, 0x72, MRM4r, "vpsrad", X86vsra, X86vsrai,
4113                             VR128, v4i32, v4i32, bc_v4i32,
4114                             SSE_INTSHIFT_ITINS_P, 0>, VEX_4V;
4115
4116 let ExeDomain = SSEPackedInt, SchedRW = [WriteVecShift] in {
4117   // 128-bit logical shifts.
4118   def VPSLLDQri : PDIi8<0x73, MRM7r,
4119                     (outs VR128:$dst), (ins VR128:$src1, i32i8imm:$src2),
4120                     "vpslldq\t{$src2, $src1, $dst|$dst, $src1, $src2}",
4121                     [(set VR128:$dst,
4122                       (int_x86_sse2_psll_dq_bs VR128:$src1, imm:$src2))]>,
4123                     VEX_4V;
4124   def VPSRLDQri : PDIi8<0x73, MRM3r,
4125                     (outs VR128:$dst), (ins VR128:$src1, i32i8imm:$src2),
4126                     "vpsrldq\t{$src2, $src1, $dst|$dst, $src1, $src2}",
4127                     [(set VR128:$dst,
4128                       (int_x86_sse2_psrl_dq_bs VR128:$src1, imm:$src2))]>,
4129                     VEX_4V;
4130   // PSRADQri doesn't exist in SSE[1-3].
4131 }
4132 } // Predicates = [HasAVX]
4133
4134 let Predicates = [HasAVX2] in {
4135 defm VPSLLWY : PDI_binop_rmi<0xF1, 0x71, MRM6r, "vpsllw", X86vshl, X86vshli,
4136                              VR256, v16i16, v8i16, bc_v8i16,
4137                              SSE_INTSHIFT_ITINS_P, 0>, VEX_4V, VEX_L;
4138 defm VPSLLDY : PDI_binop_rmi<0xF2, 0x72, MRM6r, "vpslld", X86vshl, X86vshli,
4139                              VR256, v8i32, v4i32, bc_v4i32,
4140                              SSE_INTSHIFT_ITINS_P, 0>, VEX_4V, VEX_L;
4141 defm VPSLLQY : PDI_binop_rmi<0xF3, 0x73, MRM6r, "vpsllq", X86vshl, X86vshli,
4142                              VR256, v4i64, v2i64, bc_v2i64,
4143                              SSE_INTSHIFT_ITINS_P, 0>, VEX_4V, VEX_L;
4144
4145 defm VPSRLWY : PDI_binop_rmi<0xD1, 0x71, MRM2r, "vpsrlw", X86vsrl, X86vsrli,
4146                              VR256, v16i16, v8i16, bc_v8i16,
4147                              SSE_INTSHIFT_ITINS_P, 0>, VEX_4V, VEX_L;
4148 defm VPSRLDY : PDI_binop_rmi<0xD2, 0x72, MRM2r, "vpsrld", X86vsrl, X86vsrli,
4149                              VR256, v8i32, v4i32, bc_v4i32,
4150                              SSE_INTSHIFT_ITINS_P, 0>, VEX_4V, VEX_L;
4151 defm VPSRLQY : PDI_binop_rmi<0xD3, 0x73, MRM2r, "vpsrlq", X86vsrl, X86vsrli,
4152                              VR256, v4i64, v2i64, bc_v2i64,
4153                              SSE_INTSHIFT_ITINS_P, 0>, VEX_4V, VEX_L;
4154
4155 defm VPSRAWY : PDI_binop_rmi<0xE1, 0x71, MRM4r, "vpsraw", X86vsra, X86vsrai,
4156                              VR256, v16i16, v8i16, bc_v8i16,
4157                              SSE_INTSHIFT_ITINS_P, 0>, VEX_4V, VEX_L;
4158 defm VPSRADY : PDI_binop_rmi<0xE2, 0x72, MRM4r, "vpsrad", X86vsra, X86vsrai,
4159                              VR256, v8i32, v4i32, bc_v4i32,
4160                              SSE_INTSHIFT_ITINS_P, 0>, VEX_4V, VEX_L;
4161
4162 let ExeDomain = SSEPackedInt, SchedRW = [WriteVecShift] in {
4163   // 256-bit logical shifts.
4164   def VPSLLDQYri : PDIi8<0x73, MRM7r,
4165                     (outs VR256:$dst), (ins VR256:$src1, i32i8imm:$src2),
4166                     "vpslldq\t{$src2, $src1, $dst|$dst, $src1, $src2}",
4167                     [(set VR256:$dst,
4168                       (int_x86_avx2_psll_dq_bs VR256:$src1, imm:$src2))]>,
4169                     VEX_4V, VEX_L;
4170   def VPSRLDQYri : PDIi8<0x73, MRM3r,
4171                     (outs VR256:$dst), (ins VR256:$src1, i32i8imm:$src2),
4172                     "vpsrldq\t{$src2, $src1, $dst|$dst, $src1, $src2}",
4173                     [(set VR256:$dst,
4174                       (int_x86_avx2_psrl_dq_bs VR256:$src1, imm:$src2))]>,
4175                     VEX_4V, VEX_L;
4176   // PSRADQYri doesn't exist in SSE[1-3].
4177 }
4178 } // Predicates = [HasAVX2]
4179
4180 let Constraints = "$src1 = $dst" in {
4181 defm PSLLW : PDI_binop_rmi<0xF1, 0x71, MRM6r, "psllw", X86vshl, X86vshli,
4182                            VR128, v8i16, v8i16, bc_v8i16,
4183                            SSE_INTSHIFT_ITINS_P>;
4184 defm PSLLD : PDI_binop_rmi<0xF2, 0x72, MRM6r, "pslld", X86vshl, X86vshli,
4185                            VR128, v4i32, v4i32, bc_v4i32,
4186                            SSE_INTSHIFT_ITINS_P>;
4187 defm PSLLQ : PDI_binop_rmi<0xF3, 0x73, MRM6r, "psllq", X86vshl, X86vshli,
4188                            VR128, v2i64, v2i64, bc_v2i64,
4189                            SSE_INTSHIFT_ITINS_P>;
4190
4191 defm PSRLW : PDI_binop_rmi<0xD1, 0x71, MRM2r, "psrlw", X86vsrl, X86vsrli,
4192                            VR128, v8i16, v8i16, bc_v8i16,
4193                            SSE_INTSHIFT_ITINS_P>;
4194 defm PSRLD : PDI_binop_rmi<0xD2, 0x72, MRM2r, "psrld", X86vsrl, X86vsrli,
4195                            VR128, v4i32, v4i32, bc_v4i32,
4196                            SSE_INTSHIFT_ITINS_P>;
4197 defm PSRLQ : PDI_binop_rmi<0xD3, 0x73, MRM2r, "psrlq", X86vsrl, X86vsrli,
4198                            VR128, v2i64, v2i64, bc_v2i64,
4199                            SSE_INTSHIFT_ITINS_P>;
4200
4201 defm PSRAW : PDI_binop_rmi<0xE1, 0x71, MRM4r, "psraw", X86vsra, X86vsrai,
4202                            VR128, v8i16, v8i16, bc_v8i16,
4203                            SSE_INTSHIFT_ITINS_P>;
4204 defm PSRAD : PDI_binop_rmi<0xE2, 0x72, MRM4r, "psrad", X86vsra, X86vsrai,
4205                            VR128, v4i32, v4i32, bc_v4i32,
4206                            SSE_INTSHIFT_ITINS_P>;
4207
4208 let ExeDomain = SSEPackedInt, SchedRW = [WriteVecShift] in {
4209   // 128-bit logical shifts.
4210   def PSLLDQri : PDIi8<0x73, MRM7r,
4211                        (outs VR128:$dst), (ins VR128:$src1, i32i8imm:$src2),
4212                        "pslldq\t{$src2, $dst|$dst, $src2}",
4213                        [(set VR128:$dst,
4214                          (int_x86_sse2_psll_dq_bs VR128:$src1, imm:$src2))],
4215                          IIC_SSE_INTSHDQ_P_RI>;
4216   def PSRLDQri : PDIi8<0x73, MRM3r,
4217                        (outs VR128:$dst), (ins VR128:$src1, i32i8imm:$src2),
4218                        "psrldq\t{$src2, $dst|$dst, $src2}",
4219                        [(set VR128:$dst,
4220                          (int_x86_sse2_psrl_dq_bs VR128:$src1, imm:$src2))],
4221                          IIC_SSE_INTSHDQ_P_RI>;
4222   // PSRADQri doesn't exist in SSE[1-3].
4223 }
4224 } // Constraints = "$src1 = $dst"
4225
4226 let Predicates = [HasAVX] in {
4227   def : Pat<(int_x86_sse2_psll_dq VR128:$src1, imm:$src2),
4228             (VPSLLDQri VR128:$src1, (BYTE_imm imm:$src2))>;
4229   def : Pat<(int_x86_sse2_psrl_dq VR128:$src1, imm:$src2),
4230             (VPSRLDQri VR128:$src1, (BYTE_imm imm:$src2))>;
4231   def : Pat<(v2f64 (X86fsrl VR128:$src1, i32immSExt8:$src2)),
4232             (VPSRLDQri VR128:$src1, (BYTE_imm imm:$src2))>;
4233
4234   // Shift up / down and insert zero's.
4235   def : Pat<(v2i64 (X86vshldq VR128:$src, (i8 imm:$amt))),
4236             (VPSLLDQri VR128:$src, (BYTE_imm imm:$amt))>;
4237   def : Pat<(v2i64 (X86vshrdq VR128:$src, (i8 imm:$amt))),
4238             (VPSRLDQri VR128:$src, (BYTE_imm imm:$amt))>;
4239 }
4240
4241 let Predicates = [HasAVX2] in {
4242   def : Pat<(int_x86_avx2_psll_dq VR256:$src1, imm:$src2),
4243             (VPSLLDQYri VR256:$src1, (BYTE_imm imm:$src2))>;
4244   def : Pat<(int_x86_avx2_psrl_dq VR256:$src1, imm:$src2),
4245             (VPSRLDQYri VR256:$src1, (BYTE_imm imm:$src2))>;
4246 }
4247
4248 let Predicates = [UseSSE2] in {
4249   def : Pat<(int_x86_sse2_psll_dq VR128:$src1, imm:$src2),
4250             (PSLLDQri VR128:$src1, (BYTE_imm imm:$src2))>;
4251   def : Pat<(int_x86_sse2_psrl_dq VR128:$src1, imm:$src2),
4252             (PSRLDQri VR128:$src1, (BYTE_imm imm:$src2))>;
4253   def : Pat<(v2f64 (X86fsrl VR128:$src1, i32immSExt8:$src2)),
4254             (PSRLDQri VR128:$src1, (BYTE_imm imm:$src2))>;
4255
4256   // Shift up / down and insert zero's.
4257   def : Pat<(v2i64 (X86vshldq VR128:$src, (i8 imm:$amt))),
4258             (PSLLDQri VR128:$src, (BYTE_imm imm:$amt))>;
4259   def : Pat<(v2i64 (X86vshrdq VR128:$src, (i8 imm:$amt))),
4260             (PSRLDQri VR128:$src, (BYTE_imm imm:$amt))>;
4261 }
4262
4263 //===---------------------------------------------------------------------===//
4264 // SSE2 - Packed Integer Comparison Instructions
4265 //===---------------------------------------------------------------------===//
4266
4267 defm PCMPEQB : PDI_binop_all<0x74, "pcmpeqb", X86pcmpeq, v16i8, v32i8,
4268                              SSE_INTALU_ITINS_P, 1>;
4269 defm PCMPEQW : PDI_binop_all<0x75, "pcmpeqw", X86pcmpeq, v8i16, v16i16,
4270                              SSE_INTALU_ITINS_P, 1>;
4271 defm PCMPEQD : PDI_binop_all<0x76, "pcmpeqd", X86pcmpeq, v4i32, v8i32,
4272                              SSE_INTALU_ITINS_P, 1>;
4273 defm PCMPGTB : PDI_binop_all<0x64, "pcmpgtb", X86pcmpgt, v16i8, v32i8,
4274                              SSE_INTALU_ITINS_P, 0>;
4275 defm PCMPGTW : PDI_binop_all<0x65, "pcmpgtw", X86pcmpgt, v8i16, v16i16,
4276                              SSE_INTALU_ITINS_P, 0>;
4277 defm PCMPGTD : PDI_binop_all<0x66, "pcmpgtd", X86pcmpgt, v4i32, v8i32,
4278                              SSE_INTALU_ITINS_P, 0>;
4279
4280 //===---------------------------------------------------------------------===//
4281 // SSE2 - Packed Integer Pack Instructions
4282 //===---------------------------------------------------------------------===//
4283
4284 defm PACKSSWB : PDI_binop_all_int<0x63, "packsswb", int_x86_sse2_packsswb_128,
4285                                   int_x86_avx2_packsswb, SSE_INTALU_ITINS_P, 0>;
4286 defm PACKSSDW : PDI_binop_all_int<0x6B, "packssdw", int_x86_sse2_packssdw_128,
4287                                   int_x86_avx2_packssdw, SSE_INTALU_ITINS_P, 0>;
4288 defm PACKUSWB : PDI_binop_all_int<0x67, "packuswb", int_x86_sse2_packuswb_128,
4289                                   int_x86_avx2_packuswb, SSE_INTALU_ITINS_P, 0>;
4290
4291 //===---------------------------------------------------------------------===//
4292 // SSE2 - Packed Integer Shuffle Instructions
4293 //===---------------------------------------------------------------------===//
4294
4295 let ExeDomain = SSEPackedInt in {
4296 multiclass sse2_pshuffle<string OpcodeStr, ValueType vt128, ValueType vt256,
4297                          SDNode OpNode> {
4298 let Predicates = [HasAVX] in {
4299   def V#NAME#ri : Ii8<0x70, MRMSrcReg, (outs VR128:$dst),
4300                       (ins VR128:$src1, i8imm:$src2),
4301                       !strconcat("v", OpcodeStr,
4302                                  "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4303                       [(set VR128:$dst,
4304                         (vt128 (OpNode VR128:$src1, (i8 imm:$src2))))],
4305                       IIC_SSE_PSHUF_RI>, VEX, Sched<[WriteShuffle]>;
4306   def V#NAME#mi : Ii8<0x70, MRMSrcMem, (outs VR128:$dst),
4307                       (ins i128mem:$src1, i8imm:$src2),
4308                       !strconcat("v", OpcodeStr,
4309                                  "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4310                      [(set VR128:$dst,
4311                        (vt128 (OpNode (bitconvert (loadv2i64 addr:$src1)),
4312                         (i8 imm:$src2))))], IIC_SSE_PSHUF_MI>, VEX,
4313                   Sched<[WriteShuffleLd]>;
4314 }
4315
4316 let Predicates = [HasAVX2] in {
4317   def V#NAME#Yri : Ii8<0x70, MRMSrcReg, (outs VR256:$dst),
4318                        (ins VR256:$src1, i8imm:$src2),
4319                        !strconcat("v", OpcodeStr,
4320                                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4321                        [(set VR256:$dst,
4322                          (vt256 (OpNode VR256:$src1, (i8 imm:$src2))))],
4323                        IIC_SSE_PSHUF_RI>, VEX, VEX_L, Sched<[WriteShuffle]>;
4324   def V#NAME#Ymi : Ii8<0x70, MRMSrcMem, (outs VR256:$dst),
4325                        (ins i256mem:$src1, i8imm:$src2),
4326                        !strconcat("v", OpcodeStr,
4327                                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4328                       [(set VR256:$dst,
4329                         (vt256 (OpNode (bitconvert (loadv4i64 addr:$src1)),
4330                          (i8 imm:$src2))))], IIC_SSE_PSHUF_MI>, VEX, VEX_L,
4331                    Sched<[WriteShuffleLd]>;
4332 }
4333
4334 let Predicates = [UseSSE2] in {
4335   def ri : Ii8<0x70, MRMSrcReg,
4336                (outs VR128:$dst), (ins VR128:$src1, i8imm:$src2),
4337                !strconcat(OpcodeStr,
4338                           "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4339                 [(set VR128:$dst,
4340                   (vt128 (OpNode VR128:$src1, (i8 imm:$src2))))],
4341                 IIC_SSE_PSHUF_RI>, Sched<[WriteShuffle]>;
4342   def mi : Ii8<0x70, MRMSrcMem,
4343                (outs VR128:$dst), (ins i128mem:$src1, i8imm:$src2),
4344                !strconcat(OpcodeStr,
4345                           "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4346                 [(set VR128:$dst,
4347                   (vt128 (OpNode (bitconvert (memopv2i64 addr:$src1)),
4348                           (i8 imm:$src2))))], IIC_SSE_PSHUF_MI>,
4349            Sched<[WriteShuffleLd]>;
4350 }
4351 }
4352 } // ExeDomain = SSEPackedInt
4353
4354 defm PSHUFD  : sse2_pshuffle<"pshufd", v4i32, v8i32, X86PShufd>, TB, OpSize;
4355 defm PSHUFHW : sse2_pshuffle<"pshufhw", v8i16, v16i16, X86PShufhw>, XS;
4356 defm PSHUFLW : sse2_pshuffle<"pshuflw", v8i16, v16i16, X86PShuflw>, XD;
4357
4358 let Predicates = [HasAVX] in {
4359   def : Pat<(v4f32 (X86PShufd (loadv4f32 addr:$src1), (i8 imm:$imm))),
4360             (VPSHUFDmi addr:$src1, imm:$imm)>;
4361   def : Pat<(v4f32 (X86PShufd VR128:$src1, (i8 imm:$imm))),
4362             (VPSHUFDri VR128:$src1, imm:$imm)>;
4363 }
4364
4365 let Predicates = [UseSSE2] in {
4366   def : Pat<(v4f32 (X86PShufd (memopv4f32 addr:$src1), (i8 imm:$imm))),
4367             (PSHUFDmi addr:$src1, imm:$imm)>;
4368   def : Pat<(v4f32 (X86PShufd VR128:$src1, (i8 imm:$imm))),
4369             (PSHUFDri VR128:$src1, imm:$imm)>;
4370 }
4371
4372 //===---------------------------------------------------------------------===//
4373 // SSE2 - Packed Integer Unpack Instructions
4374 //===---------------------------------------------------------------------===//
4375
4376 let ExeDomain = SSEPackedInt in {
4377 multiclass sse2_unpack<bits<8> opc, string OpcodeStr, ValueType vt,
4378                        SDNode OpNode, PatFrag bc_frag, bit Is2Addr = 1> {
4379   def rr : PDI<opc, MRMSrcReg,
4380       (outs VR128:$dst), (ins VR128:$src1, VR128:$src2),
4381       !if(Is2Addr,
4382           !strconcat(OpcodeStr,"\t{$src2, $dst|$dst, $src2}"),
4383           !strconcat(OpcodeStr,"\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
4384       [(set VR128:$dst, (vt (OpNode VR128:$src1, VR128:$src2)))],
4385       IIC_SSE_UNPCK>, Sched<[WriteShuffle]>;
4386   def rm : PDI<opc, MRMSrcMem,
4387       (outs VR128:$dst), (ins VR128:$src1, i128mem:$src2),
4388       !if(Is2Addr,
4389           !strconcat(OpcodeStr,"\t{$src2, $dst|$dst, $src2}"),
4390           !strconcat(OpcodeStr,"\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
4391       [(set VR128:$dst, (OpNode VR128:$src1,
4392                                   (bc_frag (memopv2i64
4393                                                addr:$src2))))],
4394                                                IIC_SSE_UNPCK>,
4395       Sched<[WriteShuffleLd, ReadAfterLd]>;
4396 }
4397
4398 multiclass sse2_unpack_y<bits<8> opc, string OpcodeStr, ValueType vt,
4399                          SDNode OpNode, PatFrag bc_frag> {
4400   def Yrr : PDI<opc, MRMSrcReg,
4401       (outs VR256:$dst), (ins VR256:$src1, VR256:$src2),
4402       !strconcat(OpcodeStr,"\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4403       [(set VR256:$dst, (vt (OpNode VR256:$src1, VR256:$src2)))]>,
4404       Sched<[WriteShuffle]>;
4405   def Yrm : PDI<opc, MRMSrcMem,
4406       (outs VR256:$dst), (ins VR256:$src1, i256mem:$src2),
4407       !strconcat(OpcodeStr,"\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4408       [(set VR256:$dst, (OpNode VR256:$src1,
4409                                   (bc_frag (memopv4i64 addr:$src2))))]>,
4410       Sched<[WriteShuffleLd, ReadAfterLd]>;
4411 }
4412
4413 let Predicates = [HasAVX] in {
4414   defm VPUNPCKLBW  : sse2_unpack<0x60, "vpunpcklbw", v16i8, X86Unpckl,
4415                                  bc_v16i8, 0>, VEX_4V;
4416   defm VPUNPCKLWD  : sse2_unpack<0x61, "vpunpcklwd", v8i16, X86Unpckl,
4417                                  bc_v8i16, 0>, VEX_4V;
4418   defm VPUNPCKLDQ  : sse2_unpack<0x62, "vpunpckldq", v4i32, X86Unpckl,
4419                                  bc_v4i32, 0>, VEX_4V;
4420   defm VPUNPCKLQDQ : sse2_unpack<0x6C, "vpunpcklqdq", v2i64, X86Unpckl,
4421                                  bc_v2i64, 0>, VEX_4V;
4422
4423   defm VPUNPCKHBW  : sse2_unpack<0x68, "vpunpckhbw", v16i8, X86Unpckh,
4424                                  bc_v16i8, 0>, VEX_4V;
4425   defm VPUNPCKHWD  : sse2_unpack<0x69, "vpunpckhwd", v8i16, X86Unpckh,
4426                                  bc_v8i16, 0>, VEX_4V;
4427   defm VPUNPCKHDQ  : sse2_unpack<0x6A, "vpunpckhdq", v4i32, X86Unpckh,
4428                                  bc_v4i32, 0>, VEX_4V;
4429   defm VPUNPCKHQDQ : sse2_unpack<0x6D, "vpunpckhqdq", v2i64, X86Unpckh,
4430                                  bc_v2i64, 0>, VEX_4V;
4431 }
4432
4433 let Predicates = [HasAVX2] in {
4434   defm VPUNPCKLBW  : sse2_unpack_y<0x60, "vpunpcklbw", v32i8, X86Unpckl,
4435                                    bc_v32i8>, VEX_4V, VEX_L;
4436   defm VPUNPCKLWD  : sse2_unpack_y<0x61, "vpunpcklwd", v16i16, X86Unpckl,
4437                                    bc_v16i16>, VEX_4V, VEX_L;
4438   defm VPUNPCKLDQ  : sse2_unpack_y<0x62, "vpunpckldq", v8i32, X86Unpckl,
4439                                    bc_v8i32>, VEX_4V, VEX_L;
4440   defm VPUNPCKLQDQ : sse2_unpack_y<0x6C, "vpunpcklqdq", v4i64, X86Unpckl,
4441                                    bc_v4i64>, VEX_4V, VEX_L;
4442
4443   defm VPUNPCKHBW  : sse2_unpack_y<0x68, "vpunpckhbw", v32i8, X86Unpckh,
4444                                    bc_v32i8>, VEX_4V, VEX_L;
4445   defm VPUNPCKHWD  : sse2_unpack_y<0x69, "vpunpckhwd", v16i16, X86Unpckh,
4446                                    bc_v16i16>, VEX_4V, VEX_L;
4447   defm VPUNPCKHDQ  : sse2_unpack_y<0x6A, "vpunpckhdq", v8i32, X86Unpckh,
4448                                    bc_v8i32>, VEX_4V, VEX_L;
4449   defm VPUNPCKHQDQ : sse2_unpack_y<0x6D, "vpunpckhqdq", v4i64, X86Unpckh,
4450                                    bc_v4i64>, VEX_4V, VEX_L;
4451 }
4452
4453 let Constraints = "$src1 = $dst" in {
4454   defm PUNPCKLBW  : sse2_unpack<0x60, "punpcklbw", v16i8, X86Unpckl,
4455                                 bc_v16i8>;
4456   defm PUNPCKLWD  : sse2_unpack<0x61, "punpcklwd", v8i16, X86Unpckl,
4457                                 bc_v8i16>;
4458   defm PUNPCKLDQ  : sse2_unpack<0x62, "punpckldq", v4i32, X86Unpckl,
4459                                 bc_v4i32>;
4460   defm PUNPCKLQDQ : sse2_unpack<0x6C, "punpcklqdq", v2i64, X86Unpckl,
4461                                 bc_v2i64>;
4462
4463   defm PUNPCKHBW  : sse2_unpack<0x68, "punpckhbw", v16i8, X86Unpckh,
4464                                 bc_v16i8>;
4465   defm PUNPCKHWD  : sse2_unpack<0x69, "punpckhwd", v8i16, X86Unpckh,
4466                                 bc_v8i16>;
4467   defm PUNPCKHDQ  : sse2_unpack<0x6A, "punpckhdq", v4i32, X86Unpckh,
4468                                 bc_v4i32>;
4469   defm PUNPCKHQDQ : sse2_unpack<0x6D, "punpckhqdq", v2i64, X86Unpckh,
4470                                 bc_v2i64>;
4471 }
4472 } // ExeDomain = SSEPackedInt
4473
4474 //===---------------------------------------------------------------------===//
4475 // SSE2 - Packed Integer Extract and Insert
4476 //===---------------------------------------------------------------------===//
4477
4478 let ExeDomain = SSEPackedInt in {
4479 multiclass sse2_pinsrw<bit Is2Addr = 1> {
4480   def rri : Ii8<0xC4, MRMSrcReg,
4481        (outs VR128:$dst), (ins VR128:$src1,
4482         GR32orGR64:$src2, i32i8imm:$src3),
4483        !if(Is2Addr,
4484            "pinsrw\t{$src3, $src2, $dst|$dst, $src2, $src3}",
4485            "vpinsrw\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
4486        [(set VR128:$dst,
4487          (X86pinsrw VR128:$src1, GR32orGR64:$src2, imm:$src3))],
4488        IIC_SSE_PINSRW>, Sched<[WriteShuffle]>;
4489   def rmi : Ii8<0xC4, MRMSrcMem,
4490                        (outs VR128:$dst), (ins VR128:$src1,
4491                         i16mem:$src2, i32i8imm:$src3),
4492        !if(Is2Addr,
4493            "pinsrw\t{$src3, $src2, $dst|$dst, $src2, $src3}",
4494            "vpinsrw\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
4495        [(set VR128:$dst,
4496          (X86pinsrw VR128:$src1, (extloadi16 addr:$src2),
4497                     imm:$src3))], IIC_SSE_PINSRW>,
4498        Sched<[WriteShuffleLd, ReadAfterLd]>;
4499 }
4500
4501 // Extract
4502 let Predicates = [HasAVX] in
4503 def VPEXTRWri : Ii8<0xC5, MRMSrcReg,
4504                     (outs GR32orGR64:$dst), (ins VR128:$src1, i32i8imm:$src2),
4505                     "vpextrw\t{$src2, $src1, $dst|$dst, $src1, $src2}",
4506                     [(set GR32orGR64:$dst, (X86pextrw (v8i16 VR128:$src1),
4507                                             imm:$src2))]>, TB, OpSize, VEX,
4508                 Sched<[WriteShuffle]>;
4509 def PEXTRWri : PDIi8<0xC5, MRMSrcReg,
4510                     (outs GR32orGR64:$dst), (ins VR128:$src1, i32i8imm:$src2),
4511                     "pextrw\t{$src2, $src1, $dst|$dst, $src1, $src2}",
4512                     [(set GR32orGR64:$dst, (X86pextrw (v8i16 VR128:$src1),
4513                                             imm:$src2))], IIC_SSE_PEXTRW>,
4514                Sched<[WriteShuffleLd, ReadAfterLd]>;
4515
4516 // Insert
4517 let Predicates = [HasAVX] in
4518 defm VPINSRW : sse2_pinsrw<0>, TB, OpSize, VEX_4V;
4519
4520 let Predicates = [UseSSE2], Constraints = "$src1 = $dst" in
4521 defm PINSRW : sse2_pinsrw, TB, OpSize;
4522
4523 } // ExeDomain = SSEPackedInt
4524
4525 //===---------------------------------------------------------------------===//
4526 // SSE2 - Packed Mask Creation
4527 //===---------------------------------------------------------------------===//
4528
4529 let ExeDomain = SSEPackedInt, SchedRW = [WriteVecLogic] in {
4530
4531 def VPMOVMSKBrr  : VPDI<0xD7, MRMSrcReg, (outs GR32orGR64:$dst),
4532            (ins VR128:$src),
4533            "pmovmskb\t{$src, $dst|$dst, $src}",
4534            [(set GR32orGR64:$dst, (int_x86_sse2_pmovmskb_128 VR128:$src))],
4535            IIC_SSE_MOVMSK>, VEX;
4536
4537 let Predicates = [HasAVX2] in {
4538 def VPMOVMSKBYrr  : VPDI<0xD7, MRMSrcReg, (outs GR32orGR64:$dst),
4539            (ins VR256:$src),
4540            "pmovmskb\t{$src, $dst|$dst, $src}",
4541            [(set GR32orGR64:$dst, (int_x86_avx2_pmovmskb VR256:$src))]>,
4542            VEX, VEX_L;
4543 }
4544
4545 def PMOVMSKBrr : PDI<0xD7, MRMSrcReg, (outs GR32orGR64:$dst), (ins VR128:$src),
4546            "pmovmskb\t{$src, $dst|$dst, $src}",
4547            [(set GR32orGR64:$dst, (int_x86_sse2_pmovmskb_128 VR128:$src))],
4548            IIC_SSE_MOVMSK>;
4549
4550 } // ExeDomain = SSEPackedInt
4551
4552 //===---------------------------------------------------------------------===//
4553 // SSE2 - Conditional Store
4554 //===---------------------------------------------------------------------===//
4555
4556 let ExeDomain = SSEPackedInt, SchedRW = [WriteStore] in {
4557
4558 let Uses = [EDI], Predicates = [HasAVX,Not64BitMode] in
4559 def VMASKMOVDQU : VPDI<0xF7, MRMSrcReg, (outs),
4560            (ins VR128:$src, VR128:$mask),
4561            "maskmovdqu\t{$mask, $src|$src, $mask}",
4562            [(int_x86_sse2_maskmov_dqu VR128:$src, VR128:$mask, EDI)],
4563            IIC_SSE_MASKMOV>, VEX;
4564 let Uses = [RDI], Predicates = [HasAVX,In64BitMode] in
4565 def VMASKMOVDQU64 : VPDI<0xF7, MRMSrcReg, (outs),
4566            (ins VR128:$src, VR128:$mask),
4567            "maskmovdqu\t{$mask, $src|$src, $mask}",
4568            [(int_x86_sse2_maskmov_dqu VR128:$src, VR128:$mask, RDI)],
4569            IIC_SSE_MASKMOV>, VEX;
4570
4571 let Uses = [EDI], Predicates = [UseSSE2,Not64BitMode] in
4572 def MASKMOVDQU : PDI<0xF7, MRMSrcReg, (outs), (ins VR128:$src, VR128:$mask),
4573            "maskmovdqu\t{$mask, $src|$src, $mask}",
4574            [(int_x86_sse2_maskmov_dqu VR128:$src, VR128:$mask, EDI)],
4575            IIC_SSE_MASKMOV>;
4576 let Uses = [RDI], Predicates = [UseSSE2,In64BitMode] in
4577 def MASKMOVDQU64 : PDI<0xF7, MRMSrcReg, (outs), (ins VR128:$src, VR128:$mask),
4578            "maskmovdqu\t{$mask, $src|$src, $mask}",
4579            [(int_x86_sse2_maskmov_dqu VR128:$src, VR128:$mask, RDI)],
4580            IIC_SSE_MASKMOV>;
4581
4582 } // ExeDomain = SSEPackedInt
4583
4584 //===---------------------------------------------------------------------===//
4585 // SSE2 - Move Doubleword
4586 //===---------------------------------------------------------------------===//
4587
4588 //===---------------------------------------------------------------------===//
4589 // Move Int Doubleword to Packed Double Int
4590 //
4591 def VMOVDI2PDIrr : VS2I<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR32:$src),
4592                       "movd\t{$src, $dst|$dst, $src}",
4593                       [(set VR128:$dst,
4594                         (v4i32 (scalar_to_vector GR32:$src)))], IIC_SSE_MOVDQ>,
4595                         VEX, Sched<[WriteMove]>;
4596 def VMOVDI2PDIrm : VS2I<0x6E, MRMSrcMem, (outs VR128:$dst), (ins i32mem:$src),
4597                       "movd\t{$src, $dst|$dst, $src}",
4598                       [(set VR128:$dst,
4599                         (v4i32 (scalar_to_vector (loadi32 addr:$src))))],
4600                         IIC_SSE_MOVDQ>,
4601                       VEX, Sched<[WriteLoad]>;
4602 def VMOV64toPQIrr : VRS2I<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR64:$src),
4603                         "movq\t{$src, $dst|$dst, $src}",
4604                         [(set VR128:$dst,
4605                           (v2i64 (scalar_to_vector GR64:$src)))],
4606                           IIC_SSE_MOVDQ>, VEX, Sched<[WriteMove]>;
4607 let isCodeGenOnly = 1 in
4608 def VMOV64toSDrr : VRS2I<0x6E, MRMSrcReg, (outs FR64:$dst), (ins GR64:$src),
4609                        "movq\t{$src, $dst|$dst, $src}",
4610                        [(set FR64:$dst, (bitconvert GR64:$src))],
4611                        IIC_SSE_MOVDQ>, VEX, Sched<[WriteMove]>;
4612
4613 def MOVDI2PDIrr : S2I<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR32:$src),
4614                       "movd\t{$src, $dst|$dst, $src}",
4615                       [(set VR128:$dst,
4616                         (v4i32 (scalar_to_vector GR32:$src)))], IIC_SSE_MOVDQ>,
4617                   Sched<[WriteMove]>;
4618 def MOVDI2PDIrm : S2I<0x6E, MRMSrcMem, (outs VR128:$dst), (ins i32mem:$src),
4619                       "movd\t{$src, $dst|$dst, $src}",
4620                       [(set VR128:$dst,
4621                         (v4i32 (scalar_to_vector (loadi32 addr:$src))))],
4622                         IIC_SSE_MOVDQ>, Sched<[WriteLoad]>;
4623 def MOV64toPQIrr : RS2I<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR64:$src),
4624                         "mov{d|q}\t{$src, $dst|$dst, $src}",
4625                         [(set VR128:$dst,
4626                           (v2i64 (scalar_to_vector GR64:$src)))],
4627                           IIC_SSE_MOVDQ>, Sched<[WriteMove]>;
4628 let isCodeGenOnly = 1 in
4629 def MOV64toSDrr : RS2I<0x6E, MRMSrcReg, (outs FR64:$dst), (ins GR64:$src),
4630                        "mov{d|q}\t{$src, $dst|$dst, $src}",
4631                        [(set FR64:$dst, (bitconvert GR64:$src))],
4632                        IIC_SSE_MOVDQ>, Sched<[WriteMove]>;
4633
4634 //===---------------------------------------------------------------------===//
4635 // Move Int Doubleword to Single Scalar
4636 //
4637 let isCodeGenOnly = 1 in {
4638   def VMOVDI2SSrr  : VS2I<0x6E, MRMSrcReg, (outs FR32:$dst), (ins GR32:$src),
4639                         "movd\t{$src, $dst|$dst, $src}",
4640                         [(set FR32:$dst, (bitconvert GR32:$src))],
4641                         IIC_SSE_MOVDQ>, VEX, Sched<[WriteMove]>;
4642
4643   def VMOVDI2SSrm  : VS2I<0x6E, MRMSrcMem, (outs FR32:$dst), (ins i32mem:$src),
4644                         "movd\t{$src, $dst|$dst, $src}",
4645                         [(set FR32:$dst, (bitconvert (loadi32 addr:$src)))],
4646                         IIC_SSE_MOVDQ>,
4647                         VEX, Sched<[WriteLoad]>;
4648   def MOVDI2SSrr  : S2I<0x6E, MRMSrcReg, (outs FR32:$dst), (ins GR32:$src),
4649                         "movd\t{$src, $dst|$dst, $src}",
4650                         [(set FR32:$dst, (bitconvert GR32:$src))],
4651                         IIC_SSE_MOVDQ>, Sched<[WriteMove]>;
4652
4653   def MOVDI2SSrm  : S2I<0x6E, MRMSrcMem, (outs FR32:$dst), (ins i32mem:$src),
4654                         "movd\t{$src, $dst|$dst, $src}",
4655                         [(set FR32:$dst, (bitconvert (loadi32 addr:$src)))],
4656                         IIC_SSE_MOVDQ>, Sched<[WriteLoad]>;
4657 }
4658
4659 //===---------------------------------------------------------------------===//
4660 // Move Packed Doubleword Int to Packed Double Int
4661 //
4662 def VMOVPDI2DIrr  : VS2I<0x7E, MRMDestReg, (outs GR32:$dst), (ins VR128:$src),
4663                        "movd\t{$src, $dst|$dst, $src}",
4664                        [(set GR32:$dst, (vector_extract (v4i32 VR128:$src),
4665                                         (iPTR 0)))], IIC_SSE_MOVD_ToGP>, VEX,
4666                     Sched<[WriteMove]>;
4667 def VMOVPDI2DImr  : VS2I<0x7E, MRMDestMem, (outs),
4668                        (ins i32mem:$dst, VR128:$src),
4669                        "movd\t{$src, $dst|$dst, $src}",
4670                        [(store (i32 (vector_extract (v4i32 VR128:$src),
4671                                      (iPTR 0))), addr:$dst)], IIC_SSE_MOVDQ>,
4672                                      VEX, Sched<[WriteLoad]>;
4673 def MOVPDI2DIrr  : S2I<0x7E, MRMDestReg, (outs GR32:$dst), (ins VR128:$src),
4674                        "movd\t{$src, $dst|$dst, $src}",
4675                        [(set GR32:$dst, (vector_extract (v4i32 VR128:$src),
4676                                         (iPTR 0)))], IIC_SSE_MOVD_ToGP>,
4677                    Sched<[WriteMove]>;
4678 def MOVPDI2DImr  : S2I<0x7E, MRMDestMem, (outs), (ins i32mem:$dst, VR128:$src),
4679                        "movd\t{$src, $dst|$dst, $src}",
4680                        [(store (i32 (vector_extract (v4i32 VR128:$src),
4681                                      (iPTR 0))), addr:$dst)],
4682                                      IIC_SSE_MOVDQ>, Sched<[WriteLoad]>;
4683
4684 def : Pat<(v8i32 (X86Vinsert (v8i32 immAllZerosV), GR32:$src2, (iPTR 0))),
4685         (SUBREG_TO_REG (i32 0), (VMOVDI2PDIrr GR32:$src2), sub_xmm)>;
4686
4687 def : Pat<(v4i64 (X86Vinsert (bc_v4i64 (v8i32 immAllZerosV)), GR64:$src2, (iPTR 0))),
4688         (SUBREG_TO_REG (i32 0), (VMOV64toPQIrr GR64:$src2), sub_xmm)>;
4689
4690 def : Pat<(v8i32 (X86Vinsert undef, GR32:$src2, (iPTR 0))),
4691         (SUBREG_TO_REG (i32 0), (VMOVDI2PDIrr GR32:$src2), sub_xmm)>;
4692
4693 def : Pat<(v4i64 (X86Vinsert undef, GR64:$src2, (iPTR 0))),
4694         (SUBREG_TO_REG (i32 0), (VMOV64toPQIrr GR64:$src2), sub_xmm)>;
4695
4696 //===---------------------------------------------------------------------===//
4697 // Move Packed Doubleword Int first element to Doubleword Int
4698 //
4699 let SchedRW = [WriteMove] in {
4700 def VMOVPQIto64rr : VRS2I<0x7E, MRMDestReg, (outs GR64:$dst), (ins VR128:$src),
4701                           "movq\t{$src, $dst|$dst, $src}",
4702                           [(set GR64:$dst, (vector_extract (v2i64 VR128:$src),
4703                                                            (iPTR 0)))],
4704                                                            IIC_SSE_MOVD_ToGP>,
4705                       VEX;
4706
4707 def MOVPQIto64rr : RS2I<0x7E, MRMDestReg, (outs GR64:$dst), (ins VR128:$src),
4708                         "mov{d|q}\t{$src, $dst|$dst, $src}",
4709                         [(set GR64:$dst, (vector_extract (v2i64 VR128:$src),
4710                                                          (iPTR 0)))],
4711                                                          IIC_SSE_MOVD_ToGP>;
4712 } //SchedRW
4713
4714 //===---------------------------------------------------------------------===//
4715 // Bitcast FR64 <-> GR64
4716 //
4717 let isCodeGenOnly = 1 in {
4718   let Predicates = [UseAVX] in
4719   def VMOV64toSDrm : VS2SI<0x7E, MRMSrcMem, (outs FR64:$dst), (ins i64mem:$src),
4720                           "movq\t{$src, $dst|$dst, $src}",
4721                           [(set FR64:$dst, (bitconvert (loadi64 addr:$src)))]>,
4722                           VEX, Sched<[WriteLoad]>;
4723   def VMOVSDto64rr : VRS2I<0x7E, MRMDestReg, (outs GR64:$dst), (ins FR64:$src),
4724                            "movq\t{$src, $dst|$dst, $src}",
4725                            [(set GR64:$dst, (bitconvert FR64:$src))],
4726                            IIC_SSE_MOVDQ>, VEX, Sched<[WriteMove]>;
4727   def VMOVSDto64mr : VRS2I<0x7E, MRMDestMem, (outs), (ins i64mem:$dst, FR64:$src),
4728                            "movq\t{$src, $dst|$dst, $src}",
4729                            [(store (i64 (bitconvert FR64:$src)), addr:$dst)],
4730                            IIC_SSE_MOVDQ>, VEX, Sched<[WriteStore]>;
4731
4732   def MOV64toSDrm : S2SI<0x7E, MRMSrcMem, (outs FR64:$dst), (ins i64mem:$src),
4733                          "movq\t{$src, $dst|$dst, $src}",
4734                          [(set FR64:$dst, (bitconvert (loadi64 addr:$src)))],
4735                          IIC_SSE_MOVDQ>, Sched<[WriteLoad]>;
4736   def MOVSDto64rr : RS2I<0x7E, MRMDestReg, (outs GR64:$dst), (ins FR64:$src),
4737                          "mov{d|q}\t{$src, $dst|$dst, $src}",
4738                          [(set GR64:$dst, (bitconvert FR64:$src))],
4739                          IIC_SSE_MOVD_ToGP>, Sched<[WriteMove]>;
4740   def MOVSDto64mr : RS2I<0x7E, MRMDestMem, (outs), (ins i64mem:$dst, FR64:$src),
4741                          "movq\t{$src, $dst|$dst, $src}",
4742                          [(store (i64 (bitconvert FR64:$src)), addr:$dst)],
4743                          IIC_SSE_MOVDQ>, Sched<[WriteStore]>;
4744 }
4745
4746 //===---------------------------------------------------------------------===//
4747 // Move Scalar Single to Double Int
4748 //
4749 let isCodeGenOnly = 1 in {
4750   def VMOVSS2DIrr  : VS2I<0x7E, MRMDestReg, (outs GR32:$dst), (ins FR32:$src),
4751                         "movd\t{$src, $dst|$dst, $src}",
4752                         [(set GR32:$dst, (bitconvert FR32:$src))],
4753                         IIC_SSE_MOVD_ToGP>, VEX, Sched<[WriteMove]>;
4754   def VMOVSS2DImr  : VS2I<0x7E, MRMDestMem, (outs), (ins i32mem:$dst, FR32:$src),
4755                         "movd\t{$src, $dst|$dst, $src}",
4756                         [(store (i32 (bitconvert FR32:$src)), addr:$dst)],
4757                         IIC_SSE_MOVDQ>, VEX, Sched<[WriteStore]>;
4758   def MOVSS2DIrr  : S2I<0x7E, MRMDestReg, (outs GR32:$dst), (ins FR32:$src),
4759                         "movd\t{$src, $dst|$dst, $src}",
4760                         [(set GR32:$dst, (bitconvert FR32:$src))],
4761                         IIC_SSE_MOVD_ToGP>, Sched<[WriteMove]>;
4762   def MOVSS2DImr  : S2I<0x7E, MRMDestMem, (outs), (ins i32mem:$dst, FR32:$src),
4763                         "movd\t{$src, $dst|$dst, $src}",
4764                         [(store (i32 (bitconvert FR32:$src)), addr:$dst)],
4765                         IIC_SSE_MOVDQ>, Sched<[WriteStore]>;
4766 }
4767
4768 //===---------------------------------------------------------------------===//
4769 // Patterns and instructions to describe movd/movq to XMM register zero-extends
4770 //
4771 let isCodeGenOnly = 1, SchedRW = [WriteMove] in {
4772 let AddedComplexity = 15 in {
4773 def VMOVZQI2PQIrr : VS2I<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR64:$src),
4774                        "movq\t{$src, $dst|$dst, $src}", // X86-64 only
4775                        [(set VR128:$dst, (v2i64 (X86vzmovl
4776                                       (v2i64 (scalar_to_vector GR64:$src)))))],
4777                                       IIC_SSE_MOVDQ>,
4778                                       VEX, VEX_W;
4779 def MOVZQI2PQIrr : RS2I<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR64:$src),
4780                        "mov{d|q}\t{$src, $dst|$dst, $src}", // X86-64 only
4781                        [(set VR128:$dst, (v2i64 (X86vzmovl
4782                                       (v2i64 (scalar_to_vector GR64:$src)))))],
4783                                       IIC_SSE_MOVDQ>;
4784 }
4785 } // isCodeGenOnly, SchedRW
4786
4787 let Predicates = [UseAVX] in {
4788   let AddedComplexity = 15 in
4789     def : Pat<(v4i32 (X86vzmovl (v4i32 (scalar_to_vector GR32:$src)))),
4790               (VMOVDI2PDIrr GR32:$src)>;
4791
4792   // AVX 128-bit movd/movq instruction write zeros in the high 128-bit part.
4793   let AddedComplexity = 20 in {
4794     def : Pat<(v4i32 (X86vzmovl (v4i32 (scalar_to_vector (loadi32 addr:$src))))),
4795               (VMOVDI2PDIrm addr:$src)>;
4796     def : Pat<(v4i32 (X86vzmovl (bc_v4i32 (loadv4f32 addr:$src)))),
4797               (VMOVDI2PDIrm addr:$src)>;
4798     def : Pat<(v4i32 (X86vzmovl (bc_v4i32 (loadv2i64 addr:$src)))),
4799               (VMOVDI2PDIrm addr:$src)>;
4800   }
4801   // Use regular 128-bit instructions to match 256-bit scalar_to_vec+zext.
4802   def : Pat<(v8i32 (X86vzmovl (insert_subvector undef,
4803                                (v4i32 (scalar_to_vector GR32:$src)),(iPTR 0)))),
4804             (SUBREG_TO_REG (i32 0), (VMOVDI2PDIrr GR32:$src), sub_xmm)>;
4805   def : Pat<(v4i64 (X86vzmovl (insert_subvector undef,
4806                                (v2i64 (scalar_to_vector GR64:$src)),(iPTR 0)))),
4807             (SUBREG_TO_REG (i64 0), (VMOVZQI2PQIrr GR64:$src), sub_xmm)>;
4808 }
4809
4810 let Predicates = [UseSSE2] in {
4811   let AddedComplexity = 15 in
4812     def : Pat<(v4i32 (X86vzmovl (v4i32 (scalar_to_vector GR32:$src)))),
4813               (MOVDI2PDIrr GR32:$src)>;
4814
4815   let AddedComplexity = 20 in {
4816     def : Pat<(v4i32 (X86vzmovl (v4i32 (scalar_to_vector (loadi32 addr:$src))))),
4817               (MOVDI2PDIrm addr:$src)>;
4818     def : Pat<(v4i32 (X86vzmovl (bc_v4i32 (loadv4f32 addr:$src)))),
4819               (MOVDI2PDIrm addr:$src)>;
4820     def : Pat<(v4i32 (X86vzmovl (bc_v4i32 (loadv2i64 addr:$src)))),
4821               (MOVDI2PDIrm addr:$src)>;
4822   }
4823 }
4824
4825 // These are the correct encodings of the instructions so that we know how to
4826 // read correct assembly, even though we continue to emit the wrong ones for
4827 // compatibility with Darwin's buggy assembler.
4828 def : InstAlias<"movq\t{$src, $dst|$dst, $src}",
4829                 (MOV64toPQIrr VR128:$dst, GR64:$src), 0>;
4830 def : InstAlias<"movq\t{$src, $dst|$dst, $src}",
4831                 (MOVPQIto64rr GR64:$dst, VR128:$src), 0>;
4832 // Allow "vmovd" but print "vmovq" since we don't need compatibility for AVX.
4833 def : InstAlias<"vmovd\t{$src, $dst|$dst, $src}",
4834                 (VMOV64toPQIrr VR128:$dst, GR64:$src), 0>;
4835 def : InstAlias<"vmovd\t{$src, $dst|$dst, $src}",
4836                 (VMOVPQIto64rr GR64:$dst, VR128:$src), 0>;
4837
4838 //===---------------------------------------------------------------------===//
4839 // SSE2 - Move Quadword
4840 //===---------------------------------------------------------------------===//
4841
4842 //===---------------------------------------------------------------------===//
4843 // Move Quadword Int to Packed Quadword Int
4844 //
4845
4846 let SchedRW = [WriteLoad] in {
4847 def VMOVQI2PQIrm : I<0x7E, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
4848                     "vmovq\t{$src, $dst|$dst, $src}",
4849                     [(set VR128:$dst,
4850                       (v2i64 (scalar_to_vector (loadi64 addr:$src))))]>, XS,
4851                     VEX, Requires<[UseAVX]>;
4852 def MOVQI2PQIrm : I<0x7E, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
4853                     "movq\t{$src, $dst|$dst, $src}",
4854                     [(set VR128:$dst,
4855                       (v2i64 (scalar_to_vector (loadi64 addr:$src))))],
4856                       IIC_SSE_MOVDQ>, XS,
4857                     Requires<[UseSSE2]>; // SSE2 instruction with XS Prefix
4858 } // SchedRW
4859
4860 //===---------------------------------------------------------------------===//
4861 // Move Packed Quadword Int to Quadword Int
4862 //
4863 let SchedRW = [WriteStore] in {
4864 def VMOVPQI2QImr : VS2I<0xD6, MRMDestMem, (outs), (ins i64mem:$dst, VR128:$src),
4865                       "movq\t{$src, $dst|$dst, $src}",
4866                       [(store (i64 (vector_extract (v2i64 VR128:$src),
4867                                     (iPTR 0))), addr:$dst)],
4868                                     IIC_SSE_MOVDQ>, VEX;
4869 def MOVPQI2QImr : S2I<0xD6, MRMDestMem, (outs), (ins i64mem:$dst, VR128:$src),
4870                       "movq\t{$src, $dst|$dst, $src}",
4871                       [(store (i64 (vector_extract (v2i64 VR128:$src),
4872                                     (iPTR 0))), addr:$dst)],
4873                                     IIC_SSE_MOVDQ>;
4874 } // SchedRW
4875
4876 //===---------------------------------------------------------------------===//
4877 // Store / copy lower 64-bits of a XMM register.
4878 //
4879 def VMOVLQ128mr : VS2I<0xD6, MRMDestMem, (outs), (ins i64mem:$dst, VR128:$src),
4880                      "movq\t{$src, $dst|$dst, $src}",
4881                      [(int_x86_sse2_storel_dq addr:$dst, VR128:$src)]>, VEX,
4882                   Sched<[WriteStore]>;
4883 def MOVLQ128mr : S2I<0xD6, MRMDestMem, (outs), (ins i64mem:$dst, VR128:$src),
4884                      "movq\t{$src, $dst|$dst, $src}",
4885                      [(int_x86_sse2_storel_dq addr:$dst, VR128:$src)],
4886                      IIC_SSE_MOVDQ>, Sched<[WriteStore]>;
4887
4888 let isCodeGenOnly = 1, AddedComplexity = 20 in {
4889 def VMOVZQI2PQIrm : I<0x7E, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
4890                      "vmovq\t{$src, $dst|$dst, $src}",
4891                      [(set VR128:$dst,
4892                        (v2i64 (X86vzmovl (v2i64 (scalar_to_vector
4893                                                  (loadi64 addr:$src))))))],
4894                                                  IIC_SSE_MOVDQ>,
4895                      XS, VEX, Requires<[UseAVX]>, Sched<[WriteLoad]>;
4896
4897 def MOVZQI2PQIrm : I<0x7E, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
4898                      "movq\t{$src, $dst|$dst, $src}",
4899                      [(set VR128:$dst,
4900                        (v2i64 (X86vzmovl (v2i64 (scalar_to_vector
4901                                                  (loadi64 addr:$src))))))],
4902                                                  IIC_SSE_MOVDQ>,
4903                      XS, Requires<[UseSSE2]>, Sched<[WriteLoad]>;
4904 }
4905
4906 let Predicates = [UseAVX], AddedComplexity = 20 in {
4907   def : Pat<(v2i64 (X86vzmovl (bc_v2i64 (loadv4f32 addr:$src)))),
4908             (VMOVZQI2PQIrm addr:$src)>;
4909   def : Pat<(v2i64 (X86vzload addr:$src)),
4910             (VMOVZQI2PQIrm addr:$src)>;
4911 }
4912
4913 let Predicates = [UseSSE2], AddedComplexity = 20 in {
4914   def : Pat<(v2i64 (X86vzmovl (bc_v2i64 (loadv4f32 addr:$src)))),
4915             (MOVZQI2PQIrm addr:$src)>;
4916   def : Pat<(v2i64 (X86vzload addr:$src)), (MOVZQI2PQIrm addr:$src)>;
4917 }
4918
4919 let Predicates = [HasAVX] in {
4920 def : Pat<(v4i64 (alignedX86vzload addr:$src)),
4921           (SUBREG_TO_REG (i32 0), (VMOVAPSrm addr:$src), sub_xmm)>;
4922 def : Pat<(v4i64 (X86vzload addr:$src)),
4923           (SUBREG_TO_REG (i32 0), (VMOVUPSrm addr:$src), sub_xmm)>;
4924 }
4925
4926 //===---------------------------------------------------------------------===//
4927 // Moving from XMM to XMM and clear upper 64 bits. Note, there is a bug in
4928 // IA32 document. movq xmm1, xmm2 does clear the high bits.
4929 //
4930 let SchedRW = [WriteVecLogic] in {
4931 let AddedComplexity = 15 in
4932 def VMOVZPQILo2PQIrr : I<0x7E, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
4933                         "vmovq\t{$src, $dst|$dst, $src}",
4934                     [(set VR128:$dst, (v2i64 (X86vzmovl (v2i64 VR128:$src))))],
4935                     IIC_SSE_MOVQ_RR>,
4936                       XS, VEX, Requires<[UseAVX]>;
4937 let AddedComplexity = 15 in
4938 def MOVZPQILo2PQIrr : I<0x7E, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
4939                         "movq\t{$src, $dst|$dst, $src}",
4940                     [(set VR128:$dst, (v2i64 (X86vzmovl (v2i64 VR128:$src))))],
4941                     IIC_SSE_MOVQ_RR>,
4942                       XS, Requires<[UseSSE2]>;
4943 } // SchedRW
4944
4945 let isCodeGenOnly = 1, SchedRW = [WriteVecLogicLd] in {
4946 let AddedComplexity = 20 in
4947 def VMOVZPQILo2PQIrm : I<0x7E, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
4948                         "vmovq\t{$src, $dst|$dst, $src}",
4949                     [(set VR128:$dst, (v2i64 (X86vzmovl
4950                                              (loadv2i64 addr:$src))))],
4951                                              IIC_SSE_MOVDQ>,
4952                       XS, VEX, Requires<[UseAVX]>;
4953 let AddedComplexity = 20 in {
4954 def MOVZPQILo2PQIrm : I<0x7E, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
4955                         "movq\t{$src, $dst|$dst, $src}",
4956                     [(set VR128:$dst, (v2i64 (X86vzmovl
4957                                              (loadv2i64 addr:$src))))],
4958                                              IIC_SSE_MOVDQ>,
4959                       XS, Requires<[UseSSE2]>;
4960 }
4961 } // isCodeGenOnly, SchedRW
4962
4963 let AddedComplexity = 20 in {
4964   let Predicates = [UseAVX] in {
4965     def : Pat<(v2f64 (X86vzmovl (v2f64 VR128:$src))),
4966               (VMOVZPQILo2PQIrr VR128:$src)>;
4967   }
4968   let Predicates = [UseSSE2] in {
4969     def : Pat<(v2f64 (X86vzmovl (v2f64 VR128:$src))),
4970               (MOVZPQILo2PQIrr VR128:$src)>;
4971   }
4972 }
4973
4974 //===---------------------------------------------------------------------===//
4975 // SSE3 - Replicate Single FP - MOVSHDUP and MOVSLDUP
4976 //===---------------------------------------------------------------------===//
4977 multiclass sse3_replicate_sfp<bits<8> op, SDNode OpNode, string OpcodeStr,
4978                               ValueType vt, RegisterClass RC, PatFrag mem_frag,
4979                               X86MemOperand x86memop> {
4980 def rr : S3SI<op, MRMSrcReg, (outs RC:$dst), (ins RC:$src),
4981                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
4982                       [(set RC:$dst, (vt (OpNode RC:$src)))],
4983                       IIC_SSE_MOV_LH>, Sched<[WriteShuffle]>;
4984 def rm : S3SI<op, MRMSrcMem, (outs RC:$dst), (ins x86memop:$src),
4985                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
4986                       [(set RC:$dst, (OpNode (mem_frag addr:$src)))],
4987                       IIC_SSE_MOV_LH>, Sched<[WriteShuffleLd]>;
4988 }
4989
4990 let Predicates = [HasAVX] in {
4991   defm VMOVSHDUP  : sse3_replicate_sfp<0x16, X86Movshdup, "vmovshdup",
4992                                        v4f32, VR128, loadv4f32, f128mem>, VEX;
4993   defm VMOVSLDUP  : sse3_replicate_sfp<0x12, X86Movsldup, "vmovsldup",
4994                                        v4f32, VR128, loadv4f32, f128mem>, VEX;
4995   defm VMOVSHDUPY : sse3_replicate_sfp<0x16, X86Movshdup, "vmovshdup",
4996                                  v8f32, VR256, loadv8f32, f256mem>, VEX, VEX_L;
4997   defm VMOVSLDUPY : sse3_replicate_sfp<0x12, X86Movsldup, "vmovsldup",
4998                                  v8f32, VR256, loadv8f32, f256mem>, VEX, VEX_L;
4999 }
5000 defm MOVSHDUP : sse3_replicate_sfp<0x16, X86Movshdup, "movshdup", v4f32, VR128,
5001                                    memopv4f32, f128mem>;
5002 defm MOVSLDUP : sse3_replicate_sfp<0x12, X86Movsldup, "movsldup", v4f32, VR128,
5003                                    memopv4f32, f128mem>;
5004
5005 let Predicates = [HasAVX] in {
5006   def : Pat<(v4i32 (X86Movshdup VR128:$src)),
5007             (VMOVSHDUPrr VR128:$src)>;
5008   def : Pat<(v4i32 (X86Movshdup (bc_v4i32 (loadv2i64 addr:$src)))),
5009             (VMOVSHDUPrm addr:$src)>;
5010   def : Pat<(v4i32 (X86Movsldup VR128:$src)),
5011             (VMOVSLDUPrr VR128:$src)>;
5012   def : Pat<(v4i32 (X86Movsldup (bc_v4i32 (loadv2i64 addr:$src)))),
5013             (VMOVSLDUPrm addr:$src)>;
5014   def : Pat<(v8i32 (X86Movshdup VR256:$src)),
5015             (VMOVSHDUPYrr VR256:$src)>;
5016   def : Pat<(v8i32 (X86Movshdup (bc_v8i32 (loadv4i64 addr:$src)))),
5017             (VMOVSHDUPYrm addr:$src)>;
5018   def : Pat<(v8i32 (X86Movsldup VR256:$src)),
5019             (VMOVSLDUPYrr VR256:$src)>;
5020   def : Pat<(v8i32 (X86Movsldup (bc_v8i32 (loadv4i64 addr:$src)))),
5021             (VMOVSLDUPYrm addr:$src)>;
5022 }
5023
5024 let Predicates = [UseSSE3] in {
5025   def : Pat<(v4i32 (X86Movshdup VR128:$src)),
5026             (MOVSHDUPrr VR128:$src)>;
5027   def : Pat<(v4i32 (X86Movshdup (bc_v4i32 (memopv2i64 addr:$src)))),
5028             (MOVSHDUPrm addr:$src)>;
5029   def : Pat<(v4i32 (X86Movsldup VR128:$src)),
5030             (MOVSLDUPrr VR128:$src)>;
5031   def : Pat<(v4i32 (X86Movsldup (bc_v4i32 (memopv2i64 addr:$src)))),
5032             (MOVSLDUPrm addr:$src)>;
5033 }
5034
5035 //===---------------------------------------------------------------------===//
5036 // SSE3 - Replicate Double FP - MOVDDUP
5037 //===---------------------------------------------------------------------===//
5038
5039 multiclass sse3_replicate_dfp<string OpcodeStr> {
5040 let neverHasSideEffects = 1 in
5041 def rr  : S3DI<0x12, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
5042                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5043                     [], IIC_SSE_MOV_LH>, Sched<[WriteShuffle]>;
5044 def rm  : S3DI<0x12, MRMSrcMem, (outs VR128:$dst), (ins f64mem:$src),
5045                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5046                     [(set VR128:$dst,
5047                       (v2f64 (X86Movddup
5048                               (scalar_to_vector (loadf64 addr:$src)))))],
5049                               IIC_SSE_MOV_LH>, Sched<[WriteShuffleLd]>;
5050 }
5051
5052 // FIXME: Merge with above classe when there're patterns for the ymm version
5053 multiclass sse3_replicate_dfp_y<string OpcodeStr> {
5054 def rr  : S3DI<0x12, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
5055                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5056                     [(set VR256:$dst, (v4f64 (X86Movddup VR256:$src)))]>,
5057                     Sched<[WriteShuffle]>;
5058 def rm  : S3DI<0x12, MRMSrcMem, (outs VR256:$dst), (ins f256mem:$src),
5059                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5060                     [(set VR256:$dst,
5061                       (v4f64 (X86Movddup
5062                               (scalar_to_vector (loadf64 addr:$src)))))]>,
5063                     Sched<[WriteShuffleLd]>;
5064 }
5065
5066 let Predicates = [HasAVX] in {
5067   defm VMOVDDUP  : sse3_replicate_dfp<"vmovddup">, VEX;
5068   defm VMOVDDUPY : sse3_replicate_dfp_y<"vmovddup">, VEX, VEX_L;
5069 }
5070
5071 defm MOVDDUP : sse3_replicate_dfp<"movddup">;
5072
5073 let Predicates = [HasAVX] in {
5074   def : Pat<(X86Movddup (loadv2f64 addr:$src)),
5075             (VMOVDDUPrm addr:$src)>, Requires<[HasAVX]>;
5076   def : Pat<(X86Movddup (bc_v2f64 (loadv4f32 addr:$src))),
5077             (VMOVDDUPrm addr:$src)>, Requires<[HasAVX]>;
5078   def : Pat<(X86Movddup (bc_v2f64 (loadv2i64 addr:$src))),
5079             (VMOVDDUPrm addr:$src)>, Requires<[HasAVX]>;
5080   def : Pat<(X86Movddup (bc_v2f64
5081                              (v2i64 (scalar_to_vector (loadi64 addr:$src))))),
5082             (VMOVDDUPrm addr:$src)>, Requires<[HasAVX]>;
5083
5084   // 256-bit version
5085   def : Pat<(X86Movddup (loadv4f64 addr:$src)),
5086             (VMOVDDUPYrm addr:$src)>;
5087   def : Pat<(X86Movddup (loadv4i64 addr:$src)),
5088             (VMOVDDUPYrm addr:$src)>;
5089   def : Pat<(X86Movddup (v4i64 (scalar_to_vector (loadi64 addr:$src)))),
5090             (VMOVDDUPYrm addr:$src)>;
5091   def : Pat<(X86Movddup (v4i64 VR256:$src)),
5092             (VMOVDDUPYrr VR256:$src)>;
5093 }
5094
5095 let Predicates = [UseSSE3] in {
5096   def : Pat<(X86Movddup (memopv2f64 addr:$src)),
5097             (MOVDDUPrm addr:$src)>;
5098   def : Pat<(X86Movddup (bc_v2f64 (memopv4f32 addr:$src))),
5099             (MOVDDUPrm addr:$src)>;
5100   def : Pat<(X86Movddup (bc_v2f64 (memopv2i64 addr:$src))),
5101             (MOVDDUPrm addr:$src)>;
5102   def : Pat<(X86Movddup (bc_v2f64
5103                              (v2i64 (scalar_to_vector (loadi64 addr:$src))))),
5104             (MOVDDUPrm addr:$src)>;
5105 }
5106
5107 //===---------------------------------------------------------------------===//
5108 // SSE3 - Move Unaligned Integer
5109 //===---------------------------------------------------------------------===//
5110
5111 let SchedRW = [WriteLoad] in {
5112 let Predicates = [HasAVX] in {
5113   def VLDDQUrm : S3DI<0xF0, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
5114                    "vlddqu\t{$src, $dst|$dst, $src}",
5115                    [(set VR128:$dst, (int_x86_sse3_ldu_dq addr:$src))]>, VEX;
5116   def VLDDQUYrm : S3DI<0xF0, MRMSrcMem, (outs VR256:$dst), (ins i256mem:$src),
5117                    "vlddqu\t{$src, $dst|$dst, $src}",
5118                    [(set VR256:$dst, (int_x86_avx_ldu_dq_256 addr:$src))]>,
5119                    VEX, VEX_L;
5120 }
5121 def LDDQUrm : S3DI<0xF0, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
5122                    "lddqu\t{$src, $dst|$dst, $src}",
5123                    [(set VR128:$dst, (int_x86_sse3_ldu_dq addr:$src))],
5124                    IIC_SSE_LDDQU>;
5125 }
5126
5127 //===---------------------------------------------------------------------===//
5128 // SSE3 - Arithmetic
5129 //===---------------------------------------------------------------------===//
5130
5131 multiclass sse3_addsub<Intrinsic Int, string OpcodeStr, RegisterClass RC,
5132                        X86MemOperand x86memop, OpndItins itins,
5133                        bit Is2Addr = 1> {
5134   def rr : I<0xD0, MRMSrcReg,
5135        (outs RC:$dst), (ins RC:$src1, RC:$src2),
5136        !if(Is2Addr,
5137            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5138            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5139        [(set RC:$dst, (Int RC:$src1, RC:$src2))], itins.rr>,
5140        Sched<[itins.Sched]>;
5141   def rm : I<0xD0, MRMSrcMem,
5142        (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
5143        !if(Is2Addr,
5144            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5145            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5146        [(set RC:$dst, (Int RC:$src1, (memop addr:$src2)))], itins.rr>,
5147        Sched<[itins.Sched.Folded, ReadAfterLd]>;
5148 }
5149
5150 let Predicates = [HasAVX] in {
5151   let ExeDomain = SSEPackedSingle in {
5152     defm VADDSUBPS : sse3_addsub<int_x86_sse3_addsub_ps, "vaddsubps", VR128,
5153                                  f128mem, SSE_ALU_F32P, 0>, TB, XD, VEX_4V;
5154     defm VADDSUBPSY : sse3_addsub<int_x86_avx_addsub_ps_256, "vaddsubps", VR256,
5155                                f256mem, SSE_ALU_F32P, 0>, TB, XD, VEX_4V, VEX_L;
5156   }
5157   let ExeDomain = SSEPackedDouble in {
5158     defm VADDSUBPD : sse3_addsub<int_x86_sse3_addsub_pd, "vaddsubpd", VR128,
5159                                  f128mem, SSE_ALU_F64P, 0>, TB, OpSize, VEX_4V;
5160     defm VADDSUBPDY : sse3_addsub<int_x86_avx_addsub_pd_256, "vaddsubpd", VR256,
5161                            f256mem, SSE_ALU_F64P, 0>, TB, OpSize, VEX_4V, VEX_L;
5162   }
5163 }
5164 let Constraints = "$src1 = $dst", Predicates = [UseSSE3] in {
5165   let ExeDomain = SSEPackedSingle in
5166   defm ADDSUBPS : sse3_addsub<int_x86_sse3_addsub_ps, "addsubps", VR128,
5167                               f128mem, SSE_ALU_F32P>, TB, XD;
5168   let ExeDomain = SSEPackedDouble in
5169   defm ADDSUBPD : sse3_addsub<int_x86_sse3_addsub_pd, "addsubpd", VR128,
5170                               f128mem, SSE_ALU_F64P>, TB, OpSize;
5171 }
5172
5173 //===---------------------------------------------------------------------===//
5174 // SSE3 Instructions
5175 //===---------------------------------------------------------------------===//
5176
5177 // Horizontal ops
5178 multiclass S3D_Int<bits<8> o, string OpcodeStr, ValueType vt, RegisterClass RC,
5179                    X86MemOperand x86memop, SDNode OpNode, bit Is2Addr = 1> {
5180   def rr : S3DI<o, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
5181        !if(Is2Addr,
5182          !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5183          !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5184       [(set RC:$dst, (vt (OpNode RC:$src1, RC:$src2)))], IIC_SSE_HADDSUB_RR>,
5185       Sched<[WriteFAdd]>;
5186
5187   def rm : S3DI<o, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
5188        !if(Is2Addr,
5189          !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5190          !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5191       [(set RC:$dst, (vt (OpNode RC:$src1, (memop addr:$src2))))],
5192         IIC_SSE_HADDSUB_RM>, Sched<[WriteFAddLd, ReadAfterLd]>;
5193 }
5194 multiclass S3_Int<bits<8> o, string OpcodeStr, ValueType vt, RegisterClass RC,
5195                   X86MemOperand x86memop, SDNode OpNode, bit Is2Addr = 1> {
5196   def rr : S3I<o, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
5197        !if(Is2Addr,
5198          !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5199          !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5200       [(set RC:$dst, (vt (OpNode RC:$src1, RC:$src2)))], IIC_SSE_HADDSUB_RR>,
5201       Sched<[WriteFAdd]>;
5202
5203   def rm : S3I<o, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
5204        !if(Is2Addr,
5205          !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5206          !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5207       [(set RC:$dst, (vt (OpNode RC:$src1, (memop addr:$src2))))],
5208         IIC_SSE_HADDSUB_RM>, Sched<[WriteFAddLd, ReadAfterLd]>;
5209 }
5210
5211 let Predicates = [HasAVX] in {
5212   let ExeDomain = SSEPackedSingle in {
5213     defm VHADDPS  : S3D_Int<0x7C, "vhaddps", v4f32, VR128, f128mem,
5214                             X86fhadd, 0>, VEX_4V;
5215     defm VHSUBPS  : S3D_Int<0x7D, "vhsubps", v4f32, VR128, f128mem,
5216                             X86fhsub, 0>, VEX_4V;
5217     defm VHADDPSY : S3D_Int<0x7C, "vhaddps", v8f32, VR256, f256mem,
5218                             X86fhadd, 0>, VEX_4V, VEX_L;
5219     defm VHSUBPSY : S3D_Int<0x7D, "vhsubps", v8f32, VR256, f256mem,
5220                             X86fhsub, 0>, VEX_4V, VEX_L;
5221   }
5222   let ExeDomain = SSEPackedDouble in {
5223     defm VHADDPD  : S3_Int <0x7C, "vhaddpd", v2f64, VR128, f128mem,
5224                             X86fhadd, 0>, VEX_4V;
5225     defm VHSUBPD  : S3_Int <0x7D, "vhsubpd", v2f64, VR128, f128mem,
5226                             X86fhsub, 0>, VEX_4V;
5227     defm VHADDPDY : S3_Int <0x7C, "vhaddpd", v4f64, VR256, f256mem,
5228                             X86fhadd, 0>, VEX_4V, VEX_L;
5229     defm VHSUBPDY : S3_Int <0x7D, "vhsubpd", v4f64, VR256, f256mem,
5230                             X86fhsub, 0>, VEX_4V, VEX_L;
5231   }
5232 }
5233
5234 let Constraints = "$src1 = $dst" in {
5235   let ExeDomain = SSEPackedSingle in {
5236     defm HADDPS : S3D_Int<0x7C, "haddps", v4f32, VR128, f128mem, X86fhadd>;
5237     defm HSUBPS : S3D_Int<0x7D, "hsubps", v4f32, VR128, f128mem, X86fhsub>;
5238   }
5239   let ExeDomain = SSEPackedDouble in {
5240     defm HADDPD : S3_Int<0x7C, "haddpd", v2f64, VR128, f128mem, X86fhadd>;
5241     defm HSUBPD : S3_Int<0x7D, "hsubpd", v2f64, VR128, f128mem, X86fhsub>;
5242   }
5243 }
5244
5245 //===---------------------------------------------------------------------===//
5246 // SSSE3 - Packed Absolute Instructions
5247 //===---------------------------------------------------------------------===//
5248
5249
5250 /// SS3I_unop_rm_int - Simple SSSE3 unary op whose type can be v*{i8,i16,i32}.
5251 multiclass SS3I_unop_rm_int<bits<8> opc, string OpcodeStr,
5252                             Intrinsic IntId128> {
5253   def rr128 : SS38I<opc, MRMSrcReg, (outs VR128:$dst),
5254                     (ins VR128:$src),
5255                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5256                     [(set VR128:$dst, (IntId128 VR128:$src))], IIC_SSE_PABS_RR>,
5257                     OpSize, Sched<[WriteVecALU]>;
5258
5259   def rm128 : SS38I<opc, MRMSrcMem, (outs VR128:$dst),
5260                     (ins i128mem:$src),
5261                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5262                     [(set VR128:$dst,
5263                       (IntId128
5264                        (bitconvert (memopv2i64 addr:$src))))], IIC_SSE_PABS_RM>,
5265                     OpSize, Sched<[WriteVecALULd]>;
5266 }
5267
5268 /// SS3I_unop_rm_int_y - Simple SSSE3 unary op whose type can be v*{i8,i16,i32}.
5269 multiclass SS3I_unop_rm_int_y<bits<8> opc, string OpcodeStr,
5270                               Intrinsic IntId256> {
5271   def rr256 : SS38I<opc, MRMSrcReg, (outs VR256:$dst),
5272                     (ins VR256:$src),
5273                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5274                     [(set VR256:$dst, (IntId256 VR256:$src))]>,
5275                     OpSize, Sched<[WriteVecALU]>;
5276
5277   def rm256 : SS38I<opc, MRMSrcMem, (outs VR256:$dst),
5278                     (ins i256mem:$src),
5279                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5280                     [(set VR256:$dst,
5281                       (IntId256
5282                        (bitconvert (memopv4i64 addr:$src))))]>, OpSize,
5283                     Sched<[WriteVecALULd]>;
5284 }
5285
5286 // Helper fragments to match sext vXi1 to vXiY.
5287 def v16i1sextv16i8 : PatLeaf<(v16i8 (X86pcmpgt (bc_v16i8 (v4i32 immAllZerosV)),
5288                                                VR128:$src))>;
5289 def v8i1sextv8i16  : PatLeaf<(v8i16 (X86vsrai VR128:$src, (i8 15)))>;
5290 def v4i1sextv4i32  : PatLeaf<(v4i32 (X86vsrai VR128:$src, (i8 31)))>;
5291 def v32i1sextv32i8 : PatLeaf<(v32i8 (X86pcmpgt (bc_v32i8 (v8i32 immAllZerosV)),
5292                                                VR256:$src))>;
5293 def v16i1sextv16i16: PatLeaf<(v16i16 (X86vsrai VR256:$src, (i8 15)))>;
5294 def v8i1sextv8i32  : PatLeaf<(v8i32 (X86vsrai VR256:$src, (i8 31)))>;
5295
5296 let Predicates = [HasAVX] in {
5297   defm VPABSB  : SS3I_unop_rm_int<0x1C, "vpabsb",
5298                                   int_x86_ssse3_pabs_b_128>, VEX;
5299   defm VPABSW  : SS3I_unop_rm_int<0x1D, "vpabsw",
5300                                   int_x86_ssse3_pabs_w_128>, VEX;
5301   defm VPABSD  : SS3I_unop_rm_int<0x1E, "vpabsd",
5302                                   int_x86_ssse3_pabs_d_128>, VEX;
5303
5304   def : Pat<(xor
5305             (bc_v2i64 (v16i1sextv16i8)),
5306             (bc_v2i64 (add (v16i8 VR128:$src), (v16i1sextv16i8)))),
5307             (VPABSBrr128 VR128:$src)>;
5308   def : Pat<(xor
5309             (bc_v2i64 (v8i1sextv8i16)),
5310             (bc_v2i64 (add (v8i16 VR128:$src), (v8i1sextv8i16)))),
5311             (VPABSWrr128 VR128:$src)>;
5312   def : Pat<(xor
5313             (bc_v2i64 (v4i1sextv4i32)),
5314             (bc_v2i64 (add (v4i32 VR128:$src), (v4i1sextv4i32)))),
5315             (VPABSDrr128 VR128:$src)>;
5316 }
5317
5318 let Predicates = [HasAVX2] in {
5319   defm VPABSB  : SS3I_unop_rm_int_y<0x1C, "vpabsb",
5320                                     int_x86_avx2_pabs_b>, VEX, VEX_L;
5321   defm VPABSW  : SS3I_unop_rm_int_y<0x1D, "vpabsw",
5322                                     int_x86_avx2_pabs_w>, VEX, VEX_L;
5323   defm VPABSD  : SS3I_unop_rm_int_y<0x1E, "vpabsd",
5324                                     int_x86_avx2_pabs_d>, VEX, VEX_L;
5325
5326   def : Pat<(xor
5327             (bc_v4i64 (v32i1sextv32i8)),
5328             (bc_v4i64 (add (v32i8 VR256:$src), (v32i1sextv32i8)))),
5329             (VPABSBrr256 VR256:$src)>;
5330   def : Pat<(xor
5331             (bc_v4i64 (v16i1sextv16i16)),
5332             (bc_v4i64 (add (v16i16 VR256:$src), (v16i1sextv16i16)))),
5333             (VPABSWrr256 VR256:$src)>;
5334   def : Pat<(xor
5335             (bc_v4i64 (v8i1sextv8i32)),
5336             (bc_v4i64 (add (v8i32 VR256:$src), (v8i1sextv8i32)))),
5337             (VPABSDrr256 VR256:$src)>;
5338 }
5339
5340 defm PABSB : SS3I_unop_rm_int<0x1C, "pabsb",
5341                               int_x86_ssse3_pabs_b_128>;
5342 defm PABSW : SS3I_unop_rm_int<0x1D, "pabsw",
5343                               int_x86_ssse3_pabs_w_128>;
5344 defm PABSD : SS3I_unop_rm_int<0x1E, "pabsd",
5345                               int_x86_ssse3_pabs_d_128>;
5346
5347 let Predicates = [HasSSSE3] in {
5348   def : Pat<(xor
5349             (bc_v2i64 (v16i1sextv16i8)),
5350             (bc_v2i64 (add (v16i8 VR128:$src), (v16i1sextv16i8)))),
5351             (PABSBrr128 VR128:$src)>;
5352   def : Pat<(xor
5353             (bc_v2i64 (v8i1sextv8i16)),
5354             (bc_v2i64 (add (v8i16 VR128:$src), (v8i1sextv8i16)))),
5355             (PABSWrr128 VR128:$src)>;
5356   def : Pat<(xor
5357             (bc_v2i64 (v4i1sextv4i32)),
5358             (bc_v2i64 (add (v4i32 VR128:$src), (v4i1sextv4i32)))),
5359             (PABSDrr128 VR128:$src)>;
5360 }
5361
5362 //===---------------------------------------------------------------------===//
5363 // SSSE3 - Packed Binary Operator Instructions
5364 //===---------------------------------------------------------------------===//
5365
5366 let Sched = WriteVecALU in {
5367 def SSE_PHADDSUBD : OpndItins<
5368   IIC_SSE_PHADDSUBD_RR, IIC_SSE_PHADDSUBD_RM
5369 >;
5370 def SSE_PHADDSUBSW : OpndItins<
5371   IIC_SSE_PHADDSUBSW_RR, IIC_SSE_PHADDSUBSW_RM
5372 >;
5373 def SSE_PHADDSUBW : OpndItins<
5374   IIC_SSE_PHADDSUBW_RR, IIC_SSE_PHADDSUBW_RM
5375 >;
5376 }
5377 let Sched = WriteShuffle in
5378 def SSE_PSHUFB : OpndItins<
5379   IIC_SSE_PSHUFB_RR, IIC_SSE_PSHUFB_RM
5380 >;
5381 let Sched = WriteVecALU in
5382 def SSE_PSIGN : OpndItins<
5383   IIC_SSE_PSIGN_RR, IIC_SSE_PSIGN_RM
5384 >;
5385 let Sched = WriteVecIMul in
5386 def SSE_PMULHRSW : OpndItins<
5387   IIC_SSE_PMULHRSW, IIC_SSE_PMULHRSW
5388 >;
5389
5390 /// SS3I_binop_rm - Simple SSSE3 bin op
5391 multiclass SS3I_binop_rm<bits<8> opc, string OpcodeStr, SDNode OpNode,
5392                          ValueType OpVT, RegisterClass RC, PatFrag memop_frag,
5393                          X86MemOperand x86memop, OpndItins itins,
5394                          bit Is2Addr = 1> {
5395   let isCommutable = 1 in
5396   def rr : SS38I<opc, MRMSrcReg, (outs RC:$dst),
5397        (ins RC:$src1, RC:$src2),
5398        !if(Is2Addr,
5399          !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5400          !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5401        [(set RC:$dst, (OpVT (OpNode RC:$src1, RC:$src2)))], itins.rr>,
5402        OpSize, Sched<[itins.Sched]>;
5403   def rm : SS38I<opc, MRMSrcMem, (outs RC:$dst),
5404        (ins RC:$src1, x86memop:$src2),
5405        !if(Is2Addr,
5406          !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5407          !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5408        [(set RC:$dst,
5409          (OpVT (OpNode RC:$src1,
5410           (bitconvert (memop_frag addr:$src2)))))], itins.rm>, OpSize,
5411        Sched<[itins.Sched.Folded, ReadAfterLd]>;
5412 }
5413
5414 /// SS3I_binop_rm_int - Simple SSSE3 bin op whose type can be v*{i8,i16,i32}.
5415 multiclass SS3I_binop_rm_int<bits<8> opc, string OpcodeStr,
5416                              Intrinsic IntId128, OpndItins itins,
5417                              bit Is2Addr = 1> {
5418   let isCommutable = 1 in
5419   def rr128 : SS38I<opc, MRMSrcReg, (outs VR128:$dst),
5420        (ins VR128:$src1, VR128:$src2),
5421        !if(Is2Addr,
5422          !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5423          !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5424        [(set VR128:$dst, (IntId128 VR128:$src1, VR128:$src2))]>,
5425        OpSize, Sched<[itins.Sched]>;
5426   def rm128 : SS38I<opc, MRMSrcMem, (outs VR128:$dst),
5427        (ins VR128:$src1, i128mem:$src2),
5428        !if(Is2Addr,
5429          !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5430          !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5431        [(set VR128:$dst,
5432          (IntId128 VR128:$src1,
5433           (bitconvert (memopv2i64 addr:$src2))))]>, OpSize,
5434        Sched<[itins.Sched.Folded, ReadAfterLd]>;
5435 }
5436
5437 multiclass SS3I_binop_rm_int_y<bits<8> opc, string OpcodeStr,
5438                                Intrinsic IntId256> {
5439   let isCommutable = 1 in
5440   def rr256 : SS38I<opc, MRMSrcReg, (outs VR256:$dst),
5441        (ins VR256:$src1, VR256:$src2),
5442        !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5443        [(set VR256:$dst, (IntId256 VR256:$src1, VR256:$src2))]>,
5444        OpSize;
5445   def rm256 : SS38I<opc, MRMSrcMem, (outs VR256:$dst),
5446        (ins VR256:$src1, i256mem:$src2),
5447        !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5448        [(set VR256:$dst,
5449          (IntId256 VR256:$src1,
5450           (bitconvert (loadv4i64 addr:$src2))))]>, OpSize;
5451 }
5452
5453 let ImmT = NoImm, Predicates = [HasAVX] in {
5454 let isCommutable = 0 in {
5455   defm VPHADDW    : SS3I_binop_rm<0x01, "vphaddw", X86hadd, v8i16, VR128,
5456                                   loadv2i64, i128mem,
5457                                   SSE_PHADDSUBW, 0>, VEX_4V;
5458   defm VPHADDD    : SS3I_binop_rm<0x02, "vphaddd", X86hadd, v4i32, VR128,
5459                                   loadv2i64, i128mem,
5460                                   SSE_PHADDSUBD, 0>, VEX_4V;
5461   defm VPHSUBW    : SS3I_binop_rm<0x05, "vphsubw", X86hsub, v8i16, VR128,
5462                                   loadv2i64, i128mem,
5463                                   SSE_PHADDSUBW, 0>, VEX_4V;
5464   defm VPHSUBD    : SS3I_binop_rm<0x06, "vphsubd", X86hsub, v4i32, VR128,
5465                                   loadv2i64, i128mem,
5466                                   SSE_PHADDSUBD, 0>, VEX_4V;
5467   defm VPSIGNB    : SS3I_binop_rm<0x08, "vpsignb", X86psign, v16i8, VR128,
5468                                   loadv2i64, i128mem,
5469                                   SSE_PSIGN, 0>, VEX_4V;
5470   defm VPSIGNW    : SS3I_binop_rm<0x09, "vpsignw", X86psign, v8i16, VR128,
5471                                   loadv2i64, i128mem,
5472                                   SSE_PSIGN, 0>, VEX_4V;
5473   defm VPSIGND    : SS3I_binop_rm<0x0A, "vpsignd", X86psign, v4i32, VR128,
5474                                   loadv2i64, i128mem,
5475                                   SSE_PSIGN, 0>, VEX_4V;
5476   defm VPSHUFB    : SS3I_binop_rm<0x00, "vpshufb", X86pshufb, v16i8, VR128,
5477                                   loadv2i64, i128mem,
5478                                   SSE_PSHUFB, 0>, VEX_4V;
5479   defm VPHADDSW   : SS3I_binop_rm_int<0x03, "vphaddsw",
5480                                       int_x86_ssse3_phadd_sw_128,
5481                                       SSE_PHADDSUBSW, 0>, VEX_4V;
5482   defm VPHSUBSW   : SS3I_binop_rm_int<0x07, "vphsubsw",
5483                                       int_x86_ssse3_phsub_sw_128,
5484                                       SSE_PHADDSUBSW, 0>, VEX_4V;
5485   defm VPMADDUBSW : SS3I_binop_rm_int<0x04, "vpmaddubsw",
5486                                       int_x86_ssse3_pmadd_ub_sw_128,
5487                                       SSE_PMADD, 0>, VEX_4V;
5488 }
5489 defm VPMULHRSW    : SS3I_binop_rm_int<0x0B, "vpmulhrsw",
5490                                       int_x86_ssse3_pmul_hr_sw_128,
5491                                       SSE_PMULHRSW, 0>, VEX_4V;
5492 }
5493
5494 let ImmT = NoImm, Predicates = [HasAVX2] in {
5495 let isCommutable = 0 in {
5496   defm VPHADDWY   : SS3I_binop_rm<0x01, "vphaddw", X86hadd, v16i16, VR256,
5497                                   loadv4i64, i256mem,
5498                                   SSE_PHADDSUBW, 0>, VEX_4V, VEX_L;
5499   defm VPHADDDY   : SS3I_binop_rm<0x02, "vphaddd", X86hadd, v8i32, VR256,
5500                                   loadv4i64, i256mem,
5501                                   SSE_PHADDSUBW, 0>, VEX_4V, VEX_L;
5502   defm VPHSUBWY   : SS3I_binop_rm<0x05, "vphsubw", X86hsub, v16i16, VR256,
5503                                   loadv4i64, i256mem,
5504                                   SSE_PHADDSUBW, 0>, VEX_4V, VEX_L;
5505   defm VPHSUBDY   : SS3I_binop_rm<0x06, "vphsubd", X86hsub, v8i32, VR256,
5506                                   loadv4i64, i256mem,
5507                                   SSE_PHADDSUBW, 0>, VEX_4V, VEX_L;
5508   defm VPSIGNBY   : SS3I_binop_rm<0x08, "vpsignb", X86psign, v32i8, VR256,
5509                                   loadv4i64, i256mem,
5510                                   SSE_PHADDSUBW, 0>, VEX_4V, VEX_L;
5511   defm VPSIGNWY   : SS3I_binop_rm<0x09, "vpsignw", X86psign, v16i16, VR256,
5512                                   loadv4i64, i256mem,
5513                                   SSE_PHADDSUBW, 0>, VEX_4V, VEX_L;
5514   defm VPSIGNDY   : SS3I_binop_rm<0x0A, "vpsignd", X86psign, v8i32, VR256,
5515                                   loadv4i64, i256mem,
5516                                   SSE_PHADDSUBW, 0>, VEX_4V, VEX_L;
5517   defm VPSHUFBY   : SS3I_binop_rm<0x00, "vpshufb", X86pshufb, v32i8, VR256,
5518                                   loadv4i64, i256mem,
5519                                   SSE_PHADDSUBW, 0>, VEX_4V, VEX_L;
5520   defm VPHADDSW   : SS3I_binop_rm_int_y<0x03, "vphaddsw",
5521                                         int_x86_avx2_phadd_sw>, VEX_4V, VEX_L;
5522   defm VPHSUBSW   : SS3I_binop_rm_int_y<0x07, "vphsubsw",
5523                                         int_x86_avx2_phsub_sw>, VEX_4V, VEX_L;
5524   defm VPMADDUBSW : SS3I_binop_rm_int_y<0x04, "vpmaddubsw",
5525                                        int_x86_avx2_pmadd_ub_sw>, VEX_4V, VEX_L;
5526 }
5527 defm VPMULHRSW    : SS3I_binop_rm_int_y<0x0B, "vpmulhrsw",
5528                                         int_x86_avx2_pmul_hr_sw>, VEX_4V, VEX_L;
5529 }
5530
5531 // None of these have i8 immediate fields.
5532 let ImmT = NoImm, Constraints = "$src1 = $dst" in {
5533 let isCommutable = 0 in {
5534   defm PHADDW    : SS3I_binop_rm<0x01, "phaddw", X86hadd, v8i16, VR128,
5535                                  memopv2i64, i128mem, SSE_PHADDSUBW>;
5536   defm PHADDD    : SS3I_binop_rm<0x02, "phaddd", X86hadd, v4i32, VR128,
5537                                  memopv2i64, i128mem, SSE_PHADDSUBD>;
5538   defm PHSUBW    : SS3I_binop_rm<0x05, "phsubw", X86hsub, v8i16, VR128,
5539                                  memopv2i64, i128mem, SSE_PHADDSUBW>;
5540   defm PHSUBD    : SS3I_binop_rm<0x06, "phsubd", X86hsub, v4i32, VR128,
5541                                  memopv2i64, i128mem, SSE_PHADDSUBD>;
5542   defm PSIGNB    : SS3I_binop_rm<0x08, "psignb", X86psign, v16i8, VR128,
5543                                  memopv2i64, i128mem, SSE_PSIGN>;
5544   defm PSIGNW    : SS3I_binop_rm<0x09, "psignw", X86psign, v8i16, VR128,
5545                                  memopv2i64, i128mem, SSE_PSIGN>;
5546   defm PSIGND    : SS3I_binop_rm<0x0A, "psignd", X86psign, v4i32, VR128,
5547                                  memopv2i64, i128mem, SSE_PSIGN>;
5548   defm PSHUFB    : SS3I_binop_rm<0x00, "pshufb", X86pshufb, v16i8, VR128,
5549                                  memopv2i64, i128mem, SSE_PSHUFB>;
5550   defm PHADDSW   : SS3I_binop_rm_int<0x03, "phaddsw",
5551                                      int_x86_ssse3_phadd_sw_128,
5552                                      SSE_PHADDSUBSW>;
5553   defm PHSUBSW   : SS3I_binop_rm_int<0x07, "phsubsw",
5554                                      int_x86_ssse3_phsub_sw_128,
5555                                      SSE_PHADDSUBSW>;
5556   defm PMADDUBSW : SS3I_binop_rm_int<0x04, "pmaddubsw",
5557                                      int_x86_ssse3_pmadd_ub_sw_128, SSE_PMADD>;
5558 }
5559 defm PMULHRSW    : SS3I_binop_rm_int<0x0B, "pmulhrsw",
5560                                      int_x86_ssse3_pmul_hr_sw_128,
5561                                      SSE_PMULHRSW>;
5562 }
5563
5564 //===---------------------------------------------------------------------===//
5565 // SSSE3 - Packed Align Instruction Patterns
5566 //===---------------------------------------------------------------------===//
5567
5568 multiclass ssse3_palignr<string asm, bit Is2Addr = 1> {
5569   let neverHasSideEffects = 1 in {
5570   def R128rr : SS3AI<0x0F, MRMSrcReg, (outs VR128:$dst),
5571       (ins VR128:$src1, VR128:$src2, i8imm:$src3),
5572       !if(Is2Addr,
5573         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5574         !strconcat(asm,
5575                   "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5576       [], IIC_SSE_PALIGNRR>, OpSize, Sched<[WriteShuffle]>;
5577   let mayLoad = 1 in
5578   def R128rm : SS3AI<0x0F, MRMSrcMem, (outs VR128:$dst),
5579       (ins VR128:$src1, i128mem:$src2, i8imm:$src3),
5580       !if(Is2Addr,
5581         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5582         !strconcat(asm,
5583                   "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5584       [], IIC_SSE_PALIGNRM>, OpSize, Sched<[WriteShuffleLd, ReadAfterLd]>;
5585   }
5586 }
5587
5588 multiclass ssse3_palignr_y<string asm, bit Is2Addr = 1> {
5589   let neverHasSideEffects = 1 in {
5590   def R256rr : SS3AI<0x0F, MRMSrcReg, (outs VR256:$dst),
5591       (ins VR256:$src1, VR256:$src2, i8imm:$src3),
5592       !strconcat(asm,
5593                  "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
5594       []>, OpSize, Sched<[WriteShuffle]>;
5595   let mayLoad = 1 in
5596   def R256rm : SS3AI<0x0F, MRMSrcMem, (outs VR256:$dst),
5597       (ins VR256:$src1, i256mem:$src2, i8imm:$src3),
5598       !strconcat(asm,
5599                  "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
5600       []>, OpSize, Sched<[WriteShuffleLd, ReadAfterLd]>;
5601   }
5602 }
5603
5604 let Predicates = [HasAVX] in
5605   defm VPALIGN : ssse3_palignr<"vpalignr", 0>, VEX_4V;
5606 let Predicates = [HasAVX2] in
5607   defm VPALIGN : ssse3_palignr_y<"vpalignr", 0>, VEX_4V, VEX_L;
5608 let Constraints = "$src1 = $dst", Predicates = [UseSSSE3] in
5609   defm PALIGN : ssse3_palignr<"palignr">;
5610
5611 let Predicates = [HasAVX2] in {
5612 def : Pat<(v8i32 (X86PAlignr VR256:$src1, VR256:$src2, (i8 imm:$imm))),
5613           (VPALIGNR256rr VR256:$src2, VR256:$src1, imm:$imm)>;
5614 def : Pat<(v8f32 (X86PAlignr VR256:$src1, VR256:$src2, (i8 imm:$imm))),
5615           (VPALIGNR256rr VR256:$src2, VR256:$src1, imm:$imm)>;
5616 def : Pat<(v16i16 (X86PAlignr VR256:$src1, VR256:$src2, (i8 imm:$imm))),
5617           (VPALIGNR256rr VR256:$src2, VR256:$src1, imm:$imm)>;
5618 def : Pat<(v32i8 (X86PAlignr VR256:$src1, VR256:$src2, (i8 imm:$imm))),
5619           (VPALIGNR256rr VR256:$src2, VR256:$src1, imm:$imm)>;
5620 }
5621
5622 let Predicates = [HasAVX] in {
5623 def : Pat<(v4i32 (X86PAlignr VR128:$src1, VR128:$src2, (i8 imm:$imm))),
5624           (VPALIGNR128rr VR128:$src2, VR128:$src1, imm:$imm)>;
5625 def : Pat<(v4f32 (X86PAlignr VR128:$src1, VR128:$src2, (i8 imm:$imm))),
5626           (VPALIGNR128rr VR128:$src2, VR128:$src1, imm:$imm)>;
5627 def : Pat<(v8i16 (X86PAlignr VR128:$src1, VR128:$src2, (i8 imm:$imm))),
5628           (VPALIGNR128rr VR128:$src2, VR128:$src1, imm:$imm)>;
5629 def : Pat<(v16i8 (X86PAlignr VR128:$src1, VR128:$src2, (i8 imm:$imm))),
5630           (VPALIGNR128rr VR128:$src2, VR128:$src1, imm:$imm)>;
5631 }
5632
5633 let Predicates = [UseSSSE3] in {
5634 def : Pat<(v4i32 (X86PAlignr VR128:$src1, VR128:$src2, (i8 imm:$imm))),
5635           (PALIGNR128rr VR128:$src2, VR128:$src1, imm:$imm)>;
5636 def : Pat<(v4f32 (X86PAlignr VR128:$src1, VR128:$src2, (i8 imm:$imm))),
5637           (PALIGNR128rr VR128:$src2, VR128:$src1, imm:$imm)>;
5638 def : Pat<(v8i16 (X86PAlignr VR128:$src1, VR128:$src2, (i8 imm:$imm))),
5639           (PALIGNR128rr VR128:$src2, VR128:$src1, imm:$imm)>;
5640 def : Pat<(v16i8 (X86PAlignr VR128:$src1, VR128:$src2, (i8 imm:$imm))),
5641           (PALIGNR128rr VR128:$src2, VR128:$src1, imm:$imm)>;
5642 }
5643
5644 //===---------------------------------------------------------------------===//
5645 // SSSE3 - Thread synchronization
5646 //===---------------------------------------------------------------------===//
5647
5648 let SchedRW = [WriteSystem] in {
5649 let usesCustomInserter = 1 in {
5650 def MONITOR : PseudoI<(outs), (ins i32mem:$src1, GR32:$src2, GR32:$src3),
5651                 [(int_x86_sse3_monitor addr:$src1, GR32:$src2, GR32:$src3)]>,
5652                 Requires<[HasSSE3]>;
5653 }
5654
5655 let Uses = [EAX, ECX, EDX] in
5656 def MONITORrrr : I<0x01, MRM_C8, (outs), (ins), "monitor", [], IIC_SSE_MONITOR>,
5657                  TB, Requires<[HasSSE3]>;
5658 let Uses = [ECX, EAX] in
5659 def MWAITrr   : I<0x01, MRM_C9, (outs), (ins), "mwait",
5660                 [(int_x86_sse3_mwait ECX, EAX)], IIC_SSE_MWAIT>,
5661                 TB, Requires<[HasSSE3]>;
5662 } // SchedRW
5663
5664 def : InstAlias<"mwait\t{%eax, %ecx|ecx, eax}", (MWAITrr)>, Requires<[Not64BitMode]>;
5665 def : InstAlias<"mwait\t{%rax, %rcx|rcx, rax}", (MWAITrr)>, Requires<[In64BitMode]>;
5666
5667 def : InstAlias<"monitor\t{%eax, %ecx, %edx|edx, ecx, eax}", (MONITORrrr)>,
5668       Requires<[Not64BitMode]>;
5669 def : InstAlias<"monitor\t{%rax, %rcx, %rdx|rdx, rcx, rax}", (MONITORrrr)>,
5670       Requires<[In64BitMode]>;
5671
5672 //===----------------------------------------------------------------------===//
5673 // SSE4.1 - Packed Move with Sign/Zero Extend
5674 //===----------------------------------------------------------------------===//
5675
5676 multiclass SS41I_binop_rm_int8<bits<8> opc, string OpcodeStr, Intrinsic IntId,
5677                                OpndItins itins = DEFAULT_ITINS> {
5678   def rr : SS48I<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
5679                  !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5680                  [(set VR128:$dst, (IntId VR128:$src))], itins.rr>, OpSize;
5681
5682   def rm : SS48I<opc, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
5683                  !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5684        [(set VR128:$dst,
5685          (IntId (bitconvert (v2i64 (scalar_to_vector (loadi64 addr:$src))))))],
5686          itins.rm>, OpSize;
5687 }
5688
5689 multiclass SS41I_binop_rm_int16_y<bits<8> opc, string OpcodeStr,
5690                                  Intrinsic IntId> {
5691   def Yrr : SS48I<opc, MRMSrcReg, (outs VR256:$dst), (ins VR128:$src),
5692                   !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5693                   [(set VR256:$dst, (IntId VR128:$src))]>, OpSize;
5694
5695   def Yrm : SS48I<opc, MRMSrcMem, (outs VR256:$dst), (ins i128mem:$src),
5696                   !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5697                   [(set VR256:$dst, (IntId (load addr:$src)))]>,
5698                   OpSize;
5699 }
5700
5701 let Predicates = [HasAVX] in {
5702 defm VPMOVSXBW : SS41I_binop_rm_int8<0x20, "vpmovsxbw",
5703                                      int_x86_sse41_pmovsxbw>, VEX;
5704 defm VPMOVSXWD : SS41I_binop_rm_int8<0x23, "vpmovsxwd",
5705                                      int_x86_sse41_pmovsxwd>, VEX;
5706 defm VPMOVSXDQ : SS41I_binop_rm_int8<0x25, "vpmovsxdq",
5707                                      int_x86_sse41_pmovsxdq>, VEX;
5708 defm VPMOVZXBW : SS41I_binop_rm_int8<0x30, "vpmovzxbw",
5709                                      int_x86_sse41_pmovzxbw>, VEX;
5710 defm VPMOVZXWD : SS41I_binop_rm_int8<0x33, "vpmovzxwd",
5711                                      int_x86_sse41_pmovzxwd>, VEX;
5712 defm VPMOVZXDQ : SS41I_binop_rm_int8<0x35, "vpmovzxdq",
5713                                      int_x86_sse41_pmovzxdq>, VEX;
5714 }
5715
5716 let Predicates = [HasAVX2] in {
5717 defm VPMOVSXBW : SS41I_binop_rm_int16_y<0x20, "vpmovsxbw",
5718                                         int_x86_avx2_pmovsxbw>, VEX, VEX_L;
5719 defm VPMOVSXWD : SS41I_binop_rm_int16_y<0x23, "vpmovsxwd",
5720                                         int_x86_avx2_pmovsxwd>, VEX, VEX_L;
5721 defm VPMOVSXDQ : SS41I_binop_rm_int16_y<0x25, "vpmovsxdq",
5722                                         int_x86_avx2_pmovsxdq>, VEX, VEX_L;
5723 defm VPMOVZXBW : SS41I_binop_rm_int16_y<0x30, "vpmovzxbw",
5724                                         int_x86_avx2_pmovzxbw>, VEX, VEX_L;
5725 defm VPMOVZXWD : SS41I_binop_rm_int16_y<0x33, "vpmovzxwd",
5726                                         int_x86_avx2_pmovzxwd>, VEX, VEX_L;
5727 defm VPMOVZXDQ : SS41I_binop_rm_int16_y<0x35, "vpmovzxdq",
5728                                         int_x86_avx2_pmovzxdq>, VEX, VEX_L;
5729 }
5730
5731 defm PMOVSXBW   : SS41I_binop_rm_int8<0x20, "pmovsxbw", int_x86_sse41_pmovsxbw,                                       SSE_INTALU_ITINS_P>;
5732 defm PMOVSXWD   : SS41I_binop_rm_int8<0x23, "pmovsxwd", int_x86_sse41_pmovsxwd,                                       SSE_INTALU_ITINS_P>;
5733 defm PMOVSXDQ   : SS41I_binop_rm_int8<0x25, "pmovsxdq", int_x86_sse41_pmovsxdq,                                       SSE_INTALU_ITINS_P>;
5734 defm PMOVZXBW   : SS41I_binop_rm_int8<0x30, "pmovzxbw", int_x86_sse41_pmovzxbw,                                       SSE_INTALU_ITINS_P>;
5735 defm PMOVZXWD   : SS41I_binop_rm_int8<0x33, "pmovzxwd", int_x86_sse41_pmovzxwd,                                       SSE_INTALU_ITINS_P>;
5736 defm PMOVZXDQ   : SS41I_binop_rm_int8<0x35, "pmovzxdq", int_x86_sse41_pmovzxdq,                                       SSE_INTALU_ITINS_P>;
5737
5738 let Predicates = [HasAVX] in {
5739   // Common patterns involving scalar load.
5740   def : Pat<(int_x86_sse41_pmovsxbw (vzmovl_v2i64 addr:$src)),
5741             (VPMOVSXBWrm addr:$src)>;
5742   def : Pat<(int_x86_sse41_pmovsxbw (vzload_v2i64 addr:$src)),
5743             (VPMOVSXBWrm addr:$src)>;
5744   def : Pat<(int_x86_sse41_pmovsxbw (bc_v16i8 (loadv2i64 addr:$src))),
5745             (VPMOVSXBWrm addr:$src)>;
5746
5747   def : Pat<(int_x86_sse41_pmovsxwd (vzmovl_v2i64 addr:$src)),
5748             (VPMOVSXWDrm addr:$src)>;
5749   def : Pat<(int_x86_sse41_pmovsxwd (vzload_v2i64 addr:$src)),
5750             (VPMOVSXWDrm addr:$src)>;
5751   def : Pat<(int_x86_sse41_pmovsxwd (bc_v8i16 (loadv2i64 addr:$src))),
5752             (VPMOVSXWDrm addr:$src)>;
5753
5754   def : Pat<(int_x86_sse41_pmovsxdq (vzmovl_v2i64 addr:$src)),
5755             (VPMOVSXDQrm addr:$src)>;
5756   def : Pat<(int_x86_sse41_pmovsxdq (vzload_v2i64 addr:$src)),
5757             (VPMOVSXDQrm addr:$src)>;
5758   def : Pat<(int_x86_sse41_pmovsxdq (bc_v4i32 (loadv2i64 addr:$src))),
5759             (VPMOVSXDQrm addr:$src)>;
5760
5761   def : Pat<(int_x86_sse41_pmovzxbw (vzmovl_v2i64 addr:$src)),
5762             (VPMOVZXBWrm addr:$src)>;
5763   def : Pat<(int_x86_sse41_pmovzxbw (vzload_v2i64 addr:$src)),
5764             (VPMOVZXBWrm addr:$src)>;
5765   def : Pat<(int_x86_sse41_pmovzxbw (bc_v16i8 (loadv2i64 addr:$src))),
5766             (VPMOVZXBWrm addr:$src)>;
5767
5768   def : Pat<(int_x86_sse41_pmovzxwd (vzmovl_v2i64 addr:$src)),
5769             (VPMOVZXWDrm addr:$src)>;
5770   def : Pat<(int_x86_sse41_pmovzxwd (vzload_v2i64 addr:$src)),
5771             (VPMOVZXWDrm addr:$src)>;
5772   def : Pat<(int_x86_sse41_pmovzxwd (bc_v8i16 (loadv2i64 addr:$src))),
5773             (VPMOVZXWDrm addr:$src)>;
5774
5775   def : Pat<(int_x86_sse41_pmovzxdq (vzmovl_v2i64 addr:$src)),
5776             (VPMOVZXDQrm addr:$src)>;
5777   def : Pat<(int_x86_sse41_pmovzxdq (vzload_v2i64 addr:$src)),
5778             (VPMOVZXDQrm addr:$src)>;
5779   def : Pat<(int_x86_sse41_pmovzxdq (bc_v4i32 (loadv2i64 addr:$src))),
5780             (VPMOVZXDQrm addr:$src)>;
5781 }
5782
5783 let Predicates = [UseSSE41] in {
5784   // Common patterns involving scalar load.
5785   def : Pat<(int_x86_sse41_pmovsxbw (vzmovl_v2i64 addr:$src)),
5786             (PMOVSXBWrm addr:$src)>;
5787   def : Pat<(int_x86_sse41_pmovsxbw (vzload_v2i64 addr:$src)),
5788             (PMOVSXBWrm addr:$src)>;
5789   def : Pat<(int_x86_sse41_pmovsxbw (bc_v16i8 (loadv2i64 addr:$src))),
5790             (PMOVSXBWrm addr:$src)>;
5791
5792   def : Pat<(int_x86_sse41_pmovsxwd (vzmovl_v2i64 addr:$src)),
5793             (PMOVSXWDrm addr:$src)>;
5794   def : Pat<(int_x86_sse41_pmovsxwd (vzload_v2i64 addr:$src)),
5795             (PMOVSXWDrm addr:$src)>;
5796   def : Pat<(int_x86_sse41_pmovsxwd (bc_v8i16 (loadv2i64 addr:$src))),
5797             (PMOVSXWDrm addr:$src)>;
5798
5799   def : Pat<(int_x86_sse41_pmovsxdq (vzmovl_v2i64 addr:$src)),
5800             (PMOVSXDQrm addr:$src)>;
5801   def : Pat<(int_x86_sse41_pmovsxdq (vzload_v2i64 addr:$src)),
5802             (PMOVSXDQrm addr:$src)>;
5803   def : Pat<(int_x86_sse41_pmovsxdq (bc_v4i32 (loadv2i64 addr:$src))),
5804             (PMOVSXDQrm addr:$src)>;
5805
5806   def : Pat<(int_x86_sse41_pmovzxbw (vzmovl_v2i64 addr:$src)),
5807             (PMOVZXBWrm addr:$src)>;
5808   def : Pat<(int_x86_sse41_pmovzxbw (vzload_v2i64 addr:$src)),
5809             (PMOVZXBWrm addr:$src)>;
5810   def : Pat<(int_x86_sse41_pmovzxbw (bc_v16i8 (loadv2i64 addr:$src))),
5811             (PMOVZXBWrm addr:$src)>;
5812
5813   def : Pat<(int_x86_sse41_pmovzxwd (vzmovl_v2i64 addr:$src)),
5814             (PMOVZXWDrm addr:$src)>;
5815   def : Pat<(int_x86_sse41_pmovzxwd (vzload_v2i64 addr:$src)),
5816             (PMOVZXWDrm addr:$src)>;
5817   def : Pat<(int_x86_sse41_pmovzxwd (bc_v8i16 (loadv2i64 addr:$src))),
5818             (PMOVZXWDrm addr:$src)>;
5819
5820   def : Pat<(int_x86_sse41_pmovzxdq (vzmovl_v2i64 addr:$src)),
5821             (PMOVZXDQrm addr:$src)>;
5822   def : Pat<(int_x86_sse41_pmovzxdq (vzload_v2i64 addr:$src)),
5823             (PMOVZXDQrm addr:$src)>;
5824   def : Pat<(int_x86_sse41_pmovzxdq (bc_v4i32 (loadv2i64 addr:$src))),
5825             (PMOVZXDQrm addr:$src)>;
5826 }
5827
5828 let Predicates = [HasAVX2] in {
5829   let AddedComplexity = 15 in {
5830     def : Pat<(v4i64 (X86vzmovly (v4i32 VR128:$src))),
5831               (VPMOVZXDQYrr VR128:$src)>;
5832     def : Pat<(v8i32 (X86vzmovly (v8i16 VR128:$src))),
5833               (VPMOVZXWDYrr VR128:$src)>;
5834     def : Pat<(v16i16 (X86vzmovly (v16i8 VR128:$src))),
5835               (VPMOVZXBWYrr VR128:$src)>;
5836   }
5837
5838   def : Pat<(v4i64 (X86vsmovl (v4i32 VR128:$src))), (VPMOVSXDQYrr VR128:$src)>;
5839   def : Pat<(v8i32 (X86vsmovl (v8i16 VR128:$src))), (VPMOVSXWDYrr VR128:$src)>;
5840   def : Pat<(v16i16 (X86vsmovl (v16i8 VR128:$src))), (VPMOVSXBWYrr VR128:$src)>;
5841 }
5842
5843 let Predicates = [HasAVX] in {
5844   def : Pat<(v2i64 (X86vsmovl (v4i32 VR128:$src))), (VPMOVSXDQrr VR128:$src)>;
5845   def : Pat<(v4i32 (X86vsmovl (v8i16 VR128:$src))), (VPMOVSXWDrr VR128:$src)>;
5846   def : Pat<(v8i16 (X86vsmovl (v16i8 VR128:$src))), (VPMOVSXBWrr VR128:$src)>;
5847 }
5848
5849 let Predicates = [UseSSE41] in {
5850   def : Pat<(v2i64 (X86vsmovl (v4i32 VR128:$src))), (PMOVSXDQrr VR128:$src)>;
5851   def : Pat<(v4i32 (X86vsmovl (v8i16 VR128:$src))), (PMOVSXWDrr VR128:$src)>;
5852   def : Pat<(v8i16 (X86vsmovl (v16i8 VR128:$src))), (PMOVSXBWrr VR128:$src)>;
5853 }
5854
5855
5856 multiclass SS41I_binop_rm_int4<bits<8> opc, string OpcodeStr, Intrinsic IntId,
5857                                OpndItins itins = DEFAULT_ITINS> {
5858   def rr : SS48I<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
5859                  !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5860                  [(set VR128:$dst, (IntId VR128:$src))], itins.rr>, OpSize;
5861
5862   def rm : SS48I<opc, MRMSrcMem, (outs VR128:$dst), (ins i32mem:$src),
5863                  !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5864        [(set VR128:$dst,
5865          (IntId (bitconvert (v4i32 (scalar_to_vector (loadi32 addr:$src))))))],
5866          itins.rm>,
5867           OpSize;
5868 }
5869
5870 multiclass SS41I_binop_rm_int8_y<bits<8> opc, string OpcodeStr,
5871                                  Intrinsic IntId> {
5872   def Yrr : SS48I<opc, MRMSrcReg, (outs VR256:$dst), (ins VR128:$src),
5873                   !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5874                   [(set VR256:$dst, (IntId VR128:$src))]>, OpSize;
5875
5876   def Yrm : SS48I<opc, MRMSrcMem, (outs VR256:$dst), (ins i32mem:$src),
5877                   !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5878        [(set VR256:$dst,
5879          (IntId (bitconvert (v2i64 (scalar_to_vector (loadi64 addr:$src))))))]>,
5880           OpSize;
5881 }
5882
5883 let Predicates = [HasAVX] in {
5884 defm VPMOVSXBD : SS41I_binop_rm_int4<0x21, "vpmovsxbd", int_x86_sse41_pmovsxbd>,
5885                                      VEX;
5886 defm VPMOVSXWQ : SS41I_binop_rm_int4<0x24, "vpmovsxwq", int_x86_sse41_pmovsxwq>,
5887                                      VEX;
5888 defm VPMOVZXBD : SS41I_binop_rm_int4<0x31, "vpmovzxbd", int_x86_sse41_pmovzxbd>,
5889                                      VEX;
5890 defm VPMOVZXWQ : SS41I_binop_rm_int4<0x34, "vpmovzxwq", int_x86_sse41_pmovzxwq>,
5891                                      VEX;
5892 }
5893
5894 let Predicates = [HasAVX2] in {
5895 defm VPMOVSXBD : SS41I_binop_rm_int8_y<0x21, "vpmovsxbd",
5896                                        int_x86_avx2_pmovsxbd>, VEX, VEX_L;
5897 defm VPMOVSXWQ : SS41I_binop_rm_int8_y<0x24, "vpmovsxwq",
5898                                        int_x86_avx2_pmovsxwq>, VEX, VEX_L;
5899 defm VPMOVZXBD : SS41I_binop_rm_int8_y<0x31, "vpmovzxbd",
5900                                        int_x86_avx2_pmovzxbd>, VEX, VEX_L;
5901 defm VPMOVZXWQ : SS41I_binop_rm_int8_y<0x34, "vpmovzxwq",
5902                                        int_x86_avx2_pmovzxwq>, VEX, VEX_L;
5903 }
5904
5905 defm PMOVSXBD   : SS41I_binop_rm_int4<0x21, "pmovsxbd", int_x86_sse41_pmovsxbd,
5906                                       SSE_INTALU_ITINS_P>;
5907 defm PMOVSXWQ   : SS41I_binop_rm_int4<0x24, "pmovsxwq", int_x86_sse41_pmovsxwq,
5908                                       SSE_INTALU_ITINS_P>;
5909 defm PMOVZXBD   : SS41I_binop_rm_int4<0x31, "pmovzxbd", int_x86_sse41_pmovzxbd,
5910                                       SSE_INTALU_ITINS_P>;
5911 defm PMOVZXWQ   : SS41I_binop_rm_int4<0x34, "pmovzxwq", int_x86_sse41_pmovzxwq,
5912                                       SSE_INTALU_ITINS_P>;
5913
5914 let Predicates = [HasAVX] in {
5915   // Common patterns involving scalar load
5916   def : Pat<(int_x86_sse41_pmovsxbd (vzmovl_v4i32 addr:$src)),
5917             (VPMOVSXBDrm addr:$src)>;
5918   def : Pat<(int_x86_sse41_pmovsxwq (vzmovl_v4i32 addr:$src)),
5919             (VPMOVSXWQrm addr:$src)>;
5920
5921   def : Pat<(int_x86_sse41_pmovzxbd (vzmovl_v4i32 addr:$src)),
5922             (VPMOVZXBDrm addr:$src)>;
5923   def : Pat<(int_x86_sse41_pmovzxwq (vzmovl_v4i32 addr:$src)),
5924             (VPMOVZXWQrm addr:$src)>;
5925 }
5926
5927 let Predicates = [UseSSE41] in {
5928   // Common patterns involving scalar load
5929   def : Pat<(int_x86_sse41_pmovsxbd (vzmovl_v4i32 addr:$src)),
5930             (PMOVSXBDrm addr:$src)>;
5931   def : Pat<(int_x86_sse41_pmovsxwq (vzmovl_v4i32 addr:$src)),
5932             (PMOVSXWQrm addr:$src)>;
5933
5934   def : Pat<(int_x86_sse41_pmovzxbd (vzmovl_v4i32 addr:$src)),
5935             (PMOVZXBDrm addr:$src)>;
5936   def : Pat<(int_x86_sse41_pmovzxwq (vzmovl_v4i32 addr:$src)),
5937             (PMOVZXWQrm addr:$src)>;
5938 }
5939
5940 multiclass SS41I_binop_rm_int2<bits<8> opc, string OpcodeStr, Intrinsic IntId,
5941                                OpndItins itins = DEFAULT_ITINS> {
5942   def rr : SS48I<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
5943                  !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5944                  [(set VR128:$dst, (IntId VR128:$src))]>, OpSize;
5945
5946   // Expecting a i16 load any extended to i32 value.
5947   def rm : SS48I<opc, MRMSrcMem, (outs VR128:$dst), (ins i16mem:$src),
5948                  !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5949                  [(set VR128:$dst, (IntId (bitconvert
5950                      (v4i32 (scalar_to_vector (loadi16_anyext addr:$src))))))]>,
5951                  OpSize;
5952 }
5953
5954 multiclass SS41I_binop_rm_int4_y<bits<8> opc, string OpcodeStr,
5955                                  Intrinsic IntId> {
5956   def Yrr : SS48I<opc, MRMSrcReg, (outs VR256:$dst), (ins VR128:$src),
5957                  !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5958                  [(set VR256:$dst, (IntId VR128:$src))]>, OpSize;
5959
5960   // Expecting a i16 load any extended to i32 value.
5961   def Yrm : SS48I<opc, MRMSrcMem, (outs VR256:$dst), (ins i16mem:$src),
5962                   !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5963                   [(set VR256:$dst, (IntId (bitconvert
5964                       (v4i32 (scalar_to_vector (loadi32 addr:$src))))))]>,
5965                   OpSize;
5966 }
5967
5968 let Predicates = [HasAVX] in {
5969 defm VPMOVSXBQ : SS41I_binop_rm_int2<0x22, "vpmovsxbq", int_x86_sse41_pmovsxbq>,
5970                                      VEX;
5971 defm VPMOVZXBQ : SS41I_binop_rm_int2<0x32, "vpmovzxbq", int_x86_sse41_pmovzxbq>,
5972                                      VEX;
5973 }
5974 let Predicates = [HasAVX2] in {
5975 defm VPMOVSXBQ : SS41I_binop_rm_int4_y<0x22, "vpmovsxbq",
5976                                        int_x86_avx2_pmovsxbq>, VEX, VEX_L;
5977 defm VPMOVZXBQ : SS41I_binop_rm_int4_y<0x32, "vpmovzxbq",
5978                                        int_x86_avx2_pmovzxbq>, VEX, VEX_L;
5979 }
5980 defm PMOVSXBQ   : SS41I_binop_rm_int2<0x22, "pmovsxbq", int_x86_sse41_pmovsxbq,
5981                                       SSE_INTALU_ITINS_P>;
5982 defm PMOVZXBQ   : SS41I_binop_rm_int2<0x32, "pmovzxbq", int_x86_sse41_pmovzxbq,
5983                                       SSE_INTALU_ITINS_P>;
5984
5985 let Predicates = [HasAVX2] in {
5986   def : Pat<(v16i16 (X86vsext (v16i8 VR128:$src))), (VPMOVSXBWYrr VR128:$src)>;
5987   def : Pat<(v8i32  (X86vsext (v16i8 VR128:$src))), (VPMOVSXBDYrr VR128:$src)>;
5988   def : Pat<(v4i64  (X86vsext (v16i8 VR128:$src))), (VPMOVSXBQYrr VR128:$src)>;
5989
5990   def : Pat<(v8i32  (X86vsext (v8i16 VR128:$src))), (VPMOVSXWDYrr VR128:$src)>;
5991   def : Pat<(v4i64  (X86vsext (v8i16 VR128:$src))), (VPMOVSXWQYrr VR128:$src)>;
5992
5993   def : Pat<(v4i64  (X86vsext (v4i32 VR128:$src))), (VPMOVSXDQYrr VR128:$src)>;
5994
5995   def : Pat<(v16i16 (X86vsext (v32i8 VR256:$src))),
5996             (VPMOVSXBWYrr (EXTRACT_SUBREG VR256:$src, sub_xmm))>;
5997   def : Pat<(v8i32 (X86vsext (v32i8 VR256:$src))),
5998             (VPMOVSXBDYrr (EXTRACT_SUBREG VR256:$src, sub_xmm))>;
5999   def : Pat<(v4i64 (X86vsext (v32i8 VR256:$src))),
6000             (VPMOVSXBQYrr (EXTRACT_SUBREG VR256:$src, sub_xmm))>;
6001
6002   def : Pat<(v8i32 (X86vsext (v16i16 VR256:$src))),
6003             (VPMOVSXWDYrr (EXTRACT_SUBREG VR256:$src, sub_xmm))>;
6004   def : Pat<(v4i64 (X86vsext (v16i16 VR256:$src))),
6005             (VPMOVSXWQYrr (EXTRACT_SUBREG VR256:$src, sub_xmm))>;
6006
6007   def : Pat<(v4i64 (X86vsext (v8i32 VR256:$src))),
6008             (VPMOVSXDQYrr (EXTRACT_SUBREG VR256:$src, sub_xmm))>;
6009
6010   def : Pat<(v8i32 (X86vsmovl (v8i16 (bitconvert (v2i64 (load addr:$src)))))),
6011             (VPMOVSXWDYrm addr:$src)>;
6012   def : Pat<(v4i64 (X86vsmovl (v4i32 (bitconvert (v2i64 (load addr:$src)))))),
6013             (VPMOVSXDQYrm addr:$src)>;
6014
6015   def : Pat<(v8i32 (X86vsext (v16i8 (bitconvert (v2i64 
6016                     (scalar_to_vector (loadi64 addr:$src))))))),
6017             (VPMOVSXBDYrm addr:$src)>;
6018   def : Pat<(v8i32 (X86vsext (v16i8 (bitconvert (v2f64 
6019                     (scalar_to_vector (loadf64 addr:$src))))))),
6020             (VPMOVSXBDYrm addr:$src)>;
6021
6022   def : Pat<(v4i64 (X86vsext (v8i16 (bitconvert (v2i64 
6023                     (scalar_to_vector (loadi64 addr:$src))))))),
6024             (VPMOVSXWQYrm addr:$src)>;
6025   def : Pat<(v4i64 (X86vsext (v8i16 (bitconvert (v2f64 
6026                     (scalar_to_vector (loadf64 addr:$src))))))),
6027             (VPMOVSXWQYrm addr:$src)>;
6028
6029   def : Pat<(v4i64 (X86vsext (v16i8 (bitconvert (v4i32 
6030                     (scalar_to_vector (loadi32 addr:$src))))))),
6031             (VPMOVSXBQYrm addr:$src)>;
6032 }
6033
6034 let Predicates = [HasAVX] in {
6035   // Common patterns involving scalar load
6036   def : Pat<(int_x86_sse41_pmovsxbq
6037               (bitconvert (v4i32 (X86vzmovl
6038                             (v4i32 (scalar_to_vector (loadi32 addr:$src))))))),
6039             (VPMOVSXBQrm addr:$src)>;
6040
6041   def : Pat<(int_x86_sse41_pmovzxbq
6042               (bitconvert (v4i32 (X86vzmovl
6043                             (v4i32 (scalar_to_vector (loadi32 addr:$src))))))),
6044             (VPMOVZXBQrm addr:$src)>;
6045 }
6046
6047 let Predicates = [UseSSE41] in {
6048   def : Pat<(v8i16 (X86vsext (v16i8 VR128:$src))), (PMOVSXBWrr VR128:$src)>;
6049   def : Pat<(v4i32 (X86vsext (v16i8 VR128:$src))), (PMOVSXBDrr VR128:$src)>;
6050   def : Pat<(v2i64 (X86vsext (v16i8 VR128:$src))), (PMOVSXBQrr VR128:$src)>;
6051
6052   def : Pat<(v4i32 (X86vsext (v8i16 VR128:$src))), (PMOVSXWDrr VR128:$src)>;
6053   def : Pat<(v2i64 (X86vsext (v8i16 VR128:$src))), (PMOVSXWQrr VR128:$src)>;
6054
6055   def : Pat<(v2i64 (X86vsext (v4i32 VR128:$src))), (PMOVSXDQrr VR128:$src)>;
6056
6057   // Common patterns involving scalar load
6058   def : Pat<(int_x86_sse41_pmovsxbq
6059               (bitconvert (v4i32 (X86vzmovl
6060                             (v4i32 (scalar_to_vector (loadi32 addr:$src))))))),
6061             (PMOVSXBQrm addr:$src)>;
6062
6063   def : Pat<(int_x86_sse41_pmovzxbq
6064               (bitconvert (v4i32 (X86vzmovl
6065                             (v4i32 (scalar_to_vector (loadi32 addr:$src))))))),
6066             (PMOVZXBQrm addr:$src)>;
6067
6068   def : Pat<(v4i32 (X86vsext (v8i16 (bitconvert (v2i64
6069                     (scalar_to_vector (loadi64 addr:$src))))))),
6070             (PMOVSXWDrm addr:$src)>;
6071   def : Pat<(v4i32 (X86vsext (v8i16 (bitconvert (v2f64
6072                     (scalar_to_vector (loadf64 addr:$src))))))),
6073             (PMOVSXWDrm addr:$src)>;
6074   def : Pat<(v4i32 (X86vsext (v16i8 (bitconvert (v4i32
6075                     (scalar_to_vector (loadi32 addr:$src))))))),
6076             (PMOVSXBDrm addr:$src)>;
6077   def : Pat<(v2i64 (X86vsext (v8i16 (bitconvert (v4i32
6078                     (scalar_to_vector (loadi32 addr:$src))))))),
6079             (PMOVSXWQrm addr:$src)>;
6080   def : Pat<(v2i64 (X86vsext (v16i8 (bitconvert (v4i32
6081                     (scalar_to_vector (extloadi32i16 addr:$src))))))),
6082             (PMOVSXBQrm addr:$src)>;
6083   def : Pat<(v2i64 (X86vsext (v4i32 (bitconvert (v2i64
6084                     (scalar_to_vector (loadi64 addr:$src))))))),
6085             (PMOVSXDQrm addr:$src)>;
6086   def : Pat<(v2i64 (X86vsext (v4i32 (bitconvert (v2f64
6087                     (scalar_to_vector (loadf64 addr:$src))))))),
6088             (PMOVSXDQrm addr:$src)>;
6089   def : Pat<(v8i16 (X86vsext (v16i8 (bitconvert (v2i64
6090                     (scalar_to_vector (loadi64 addr:$src))))))),
6091             (PMOVSXBWrm addr:$src)>;
6092   def : Pat<(v8i16 (X86vsext (v16i8 (bitconvert (v2f64
6093                     (scalar_to_vector (loadf64 addr:$src))))))),
6094             (PMOVSXBWrm addr:$src)>;
6095 }
6096
6097 let Predicates = [HasAVX2] in {
6098   def : Pat<(v16i16 (X86vzext (v16i8 VR128:$src))), (VPMOVZXBWYrr VR128:$src)>;
6099   def : Pat<(v8i32  (X86vzext (v16i8 VR128:$src))), (VPMOVZXBDYrr VR128:$src)>;
6100   def : Pat<(v4i64  (X86vzext (v16i8 VR128:$src))), (VPMOVZXBQYrr VR128:$src)>;
6101
6102   def : Pat<(v8i32  (X86vzext (v8i16 VR128:$src))), (VPMOVZXWDYrr VR128:$src)>;
6103   def : Pat<(v4i64  (X86vzext (v8i16 VR128:$src))), (VPMOVZXWQYrr VR128:$src)>;
6104
6105   def : Pat<(v4i64  (X86vzext (v4i32 VR128:$src))), (VPMOVZXDQYrr VR128:$src)>;
6106
6107   def : Pat<(v16i16 (X86vzext (v32i8 VR256:$src))),
6108             (VPMOVZXBWYrr (EXTRACT_SUBREG VR256:$src, sub_xmm))>;
6109   def : Pat<(v8i32 (X86vzext (v32i8 VR256:$src))),
6110             (VPMOVZXBDYrr (EXTRACT_SUBREG VR256:$src, sub_xmm))>;
6111   def : Pat<(v4i64 (X86vzext (v32i8 VR256:$src))),
6112             (VPMOVZXBQYrr (EXTRACT_SUBREG VR256:$src, sub_xmm))>;
6113
6114   def : Pat<(v8i32 (X86vzext (v16i16 VR256:$src))),
6115             (VPMOVZXWDYrr (EXTRACT_SUBREG VR256:$src, sub_xmm))>;
6116   def : Pat<(v4i64 (X86vzext (v16i16 VR256:$src))),
6117             (VPMOVZXWQYrr (EXTRACT_SUBREG VR256:$src, sub_xmm))>;
6118
6119   def : Pat<(v4i64 (X86vzext (v8i32 VR256:$src))),
6120             (VPMOVZXDQYrr (EXTRACT_SUBREG VR256:$src, sub_xmm))>;
6121 }
6122
6123 let Predicates = [HasAVX] in {
6124   def : Pat<(v8i16 (X86vzext (v16i8 VR128:$src))), (VPMOVZXBWrr VR128:$src)>;
6125   def : Pat<(v4i32 (X86vzext (v16i8 VR128:$src))), (VPMOVZXBDrr VR128:$src)>;
6126   def : Pat<(v2i64 (X86vzext (v16i8 VR128:$src))), (VPMOVZXBQrr VR128:$src)>;
6127
6128   def : Pat<(v4i32 (X86vzext (v8i16 VR128:$src))), (VPMOVZXWDrr VR128:$src)>;
6129   def : Pat<(v2i64 (X86vzext (v8i16 VR128:$src))), (VPMOVZXWQrr VR128:$src)>;
6130
6131   def : Pat<(v2i64 (X86vzext (v4i32 VR128:$src))), (VPMOVZXDQrr VR128:$src)>;
6132
6133   def : Pat<(v8i16 (X86vzext (v16i8 (bitconvert (v2i64 (scalar_to_vector (loadi64 addr:$src))))))),
6134             (VPMOVZXBWrm addr:$src)>;
6135   def : Pat<(v8i16 (X86vzext (v16i8 (bitconvert (v2f64 (scalar_to_vector (loadf64 addr:$src))))))),
6136             (VPMOVZXBWrm addr:$src)>;
6137   def : Pat<(v4i32 (X86vzext (v16i8 (bitconvert (v4i32 (scalar_to_vector (loadi32 addr:$src))))))),
6138             (VPMOVZXBDrm addr:$src)>;
6139   def : Pat<(v2i64 (X86vzext (v16i8 (bitconvert (v4i32 (scalar_to_vector (loadi16_anyext addr:$src))))))),
6140             (VPMOVZXBQrm addr:$src)>;
6141
6142   def : Pat<(v4i32 (X86vzext (v8i16 (bitconvert (v2i64 (scalar_to_vector (loadi64 addr:$src))))))),
6143             (VPMOVZXWDrm addr:$src)>;
6144   def : Pat<(v4i32 (X86vzext (v8i16 (bitconvert (v2f64 (scalar_to_vector (loadf64 addr:$src))))))),
6145             (VPMOVZXWDrm addr:$src)>;
6146   def : Pat<(v2i64 (X86vzext (v8i16 (bitconvert (v4i32 (scalar_to_vector (loadi32 addr:$src))))))),
6147             (VPMOVZXWQrm addr:$src)>;
6148
6149   def : Pat<(v2i64 (X86vzext (v4i32 (bitconvert (v2i64 (scalar_to_vector (loadi64 addr:$src))))))),
6150             (VPMOVZXDQrm addr:$src)>;
6151   def : Pat<(v2i64 (X86vzext (v4i32 (bitconvert (v2f64 (scalar_to_vector (loadf64 addr:$src))))))),
6152             (VPMOVZXDQrm addr:$src)>;
6153   def : Pat<(v2i64 (X86vzext (v4i32 (bitconvert (v2i64 (X86vzload addr:$src)))))),
6154             (VPMOVZXDQrm addr:$src)>;
6155
6156   def : Pat<(v8i16 (X86vsext (v16i8 VR128:$src))), (VPMOVSXBWrr VR128:$src)>;
6157   def : Pat<(v4i32 (X86vsext (v16i8 VR128:$src))), (VPMOVSXBDrr VR128:$src)>;
6158   def : Pat<(v2i64 (X86vsext (v16i8 VR128:$src))), (VPMOVSXBQrr VR128:$src)>;
6159
6160   def : Pat<(v4i32 (X86vsext (v8i16 VR128:$src))), (VPMOVSXWDrr VR128:$src)>;
6161   def : Pat<(v2i64 (X86vsext (v8i16 VR128:$src))), (VPMOVSXWQrr VR128:$src)>;
6162
6163   def : Pat<(v2i64 (X86vsext (v4i32 VR128:$src))), (VPMOVSXDQrr VR128:$src)>;
6164
6165   def : Pat<(v4i32 (X86vsext (v8i16 (bitconvert (v2i64
6166                     (scalar_to_vector (loadi64 addr:$src))))))),
6167             (VPMOVSXWDrm addr:$src)>;
6168   def : Pat<(v2i64 (X86vsext (v4i32 (bitconvert (v2i64
6169                     (scalar_to_vector (loadi64 addr:$src))))))),
6170             (VPMOVSXDQrm addr:$src)>;
6171   def : Pat<(v4i32 (X86vsext (v8i16 (bitconvert (v2f64
6172                     (scalar_to_vector (loadf64 addr:$src))))))),
6173             (VPMOVSXWDrm addr:$src)>;
6174   def : Pat<(v2i64 (X86vsext (v4i32 (bitconvert (v2f64
6175                     (scalar_to_vector (loadf64 addr:$src))))))),
6176             (VPMOVSXDQrm addr:$src)>;
6177   def : Pat<(v8i16 (X86vsext (v16i8 (bitconvert (v2i64
6178                     (scalar_to_vector (loadi64 addr:$src))))))),
6179             (VPMOVSXBWrm addr:$src)>;
6180   def : Pat<(v8i16 (X86vsext (v16i8 (bitconvert (v2f64
6181                     (scalar_to_vector (loadf64 addr:$src))))))),
6182             (VPMOVSXBWrm addr:$src)>;
6183
6184   def : Pat<(v4i32 (X86vsext (v16i8 (bitconvert (v4i32
6185                     (scalar_to_vector (loadi32 addr:$src))))))),
6186             (VPMOVSXBDrm addr:$src)>;
6187   def : Pat<(v2i64 (X86vsext (v8i16 (bitconvert (v4i32
6188                     (scalar_to_vector (loadi32 addr:$src))))))),
6189             (VPMOVSXWQrm addr:$src)>;
6190   def : Pat<(v2i64 (X86vsext (v16i8 (bitconvert (v4i32
6191                     (scalar_to_vector (extloadi32i16 addr:$src))))))),
6192             (VPMOVSXBQrm addr:$src)>;
6193 }
6194
6195 let Predicates = [UseSSE41] in {
6196   def : Pat<(v8i16 (X86vzext (v16i8 VR128:$src))), (PMOVZXBWrr VR128:$src)>;
6197   def : Pat<(v4i32 (X86vzext (v16i8 VR128:$src))), (PMOVZXBDrr VR128:$src)>;
6198   def : Pat<(v2i64 (X86vzext (v16i8 VR128:$src))), (PMOVZXBQrr VR128:$src)>;
6199
6200   def : Pat<(v4i32 (X86vzext (v8i16 VR128:$src))), (PMOVZXWDrr VR128:$src)>;
6201   def : Pat<(v2i64 (X86vzext (v8i16 VR128:$src))), (PMOVZXWQrr VR128:$src)>;
6202
6203   def : Pat<(v2i64 (X86vzext (v4i32 VR128:$src))), (PMOVZXDQrr VR128:$src)>;
6204
6205   def : Pat<(v8i16 (X86vzext (v16i8 (bitconvert (v2i64 (scalar_to_vector (loadi64 addr:$src))))))),
6206             (PMOVZXBWrm addr:$src)>;
6207   def : Pat<(v8i16 (X86vzext (v16i8 (bitconvert (v2f64 (scalar_to_vector (loadf64 addr:$src))))))),
6208             (PMOVZXBWrm addr:$src)>;
6209   def : Pat<(v4i32 (X86vzext (v16i8 (bitconvert (v4i32 (scalar_to_vector (loadi32 addr:$src))))))),
6210             (PMOVZXBDrm addr:$src)>;
6211   def : Pat<(v2i64 (X86vzext (v16i8 (bitconvert (v4i32 (scalar_to_vector (loadi16_anyext addr:$src))))))),
6212             (PMOVZXBQrm addr:$src)>;
6213
6214   def : Pat<(v4i32 (X86vzext (v8i16 (bitconvert (v2i64 (scalar_to_vector (loadi64 addr:$src))))))),
6215             (PMOVZXWDrm addr:$src)>;
6216   def : Pat<(v4i32 (X86vzext (v8i16 (bitconvert (v2f64 (scalar_to_vector (loadf64 addr:$src))))))),
6217             (PMOVZXWDrm addr:$src)>;
6218   def : Pat<(v2i64 (X86vzext (v8i16 (bitconvert (v4i32 (scalar_to_vector (loadi32 addr:$src))))))),
6219             (PMOVZXWQrm addr:$src)>;
6220
6221   def : Pat<(v2i64 (X86vzext (v4i32 (bitconvert (v2i64 (scalar_to_vector (loadi64 addr:$src))))))),
6222             (PMOVZXDQrm addr:$src)>;
6223   def : Pat<(v2i64 (X86vzext (v4i32 (bitconvert (v2f64 (scalar_to_vector (loadf64 addr:$src))))))),
6224             (PMOVZXDQrm addr:$src)>;
6225   def : Pat<(v2i64 (X86vzext (v4i32 (bitconvert (v2i64 (X86vzload addr:$src)))))),
6226             (PMOVZXDQrm addr:$src)>;
6227 }
6228
6229 //===----------------------------------------------------------------------===//
6230 // SSE4.1 - Extract Instructions
6231 //===----------------------------------------------------------------------===//
6232
6233 /// SS41I_binop_ext8 - SSE 4.1 extract 8 bits to 32 bit reg or 8 bit mem
6234 multiclass SS41I_extract8<bits<8> opc, string OpcodeStr> {
6235   def rr : SS4AIi8<opc, MRMDestReg, (outs GR32orGR64:$dst),
6236                  (ins VR128:$src1, i32i8imm:$src2),
6237                  !strconcat(OpcodeStr,
6238                             "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6239                  [(set GR32orGR64:$dst, (X86pextrb (v16i8 VR128:$src1),
6240                                          imm:$src2))]>,
6241                  OpSize;
6242   let neverHasSideEffects = 1, mayStore = 1 in
6243   def mr : SS4AIi8<opc, MRMDestMem, (outs),
6244                  (ins i8mem:$dst, VR128:$src1, i32i8imm:$src2),
6245                  !strconcat(OpcodeStr,
6246                             "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6247                  []>, OpSize;
6248 // FIXME:
6249 // There's an AssertZext in the way of writing the store pattern
6250 // (store (i8 (trunc (X86pextrb (v16i8 VR128:$src1), imm:$src2))), addr:$dst)
6251 }
6252
6253 let Predicates = [HasAVX] in
6254   defm VPEXTRB : SS41I_extract8<0x14, "vpextrb">, VEX;
6255
6256 defm PEXTRB      : SS41I_extract8<0x14, "pextrb">;
6257
6258
6259 /// SS41I_extract16 - SSE 4.1 extract 16 bits to memory destination
6260 multiclass SS41I_extract16<bits<8> opc, string OpcodeStr> {
6261   let isCodeGenOnly = 1, hasSideEffects = 0 in
6262   def rr_REV : SS4AIi8<opc, MRMDestReg, (outs GR32orGR64:$dst),
6263                    (ins VR128:$src1, i32i8imm:$src2),
6264                    !strconcat(OpcodeStr,
6265                    "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6266                    []>, OpSize;
6267
6268   let neverHasSideEffects = 1, mayStore = 1 in
6269   def mr : SS4AIi8<opc, MRMDestMem, (outs),
6270                  (ins i16mem:$dst, VR128:$src1, i32i8imm:$src2),
6271                  !strconcat(OpcodeStr,
6272                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6273                  []>, OpSize;
6274 // FIXME:
6275 // There's an AssertZext in the way of writing the store pattern
6276 // (store (i16 (trunc (X86pextrw (v16i8 VR128:$src1), imm:$src2))), addr:$dst)
6277 }
6278
6279 let Predicates = [HasAVX] in
6280   defm VPEXTRW : SS41I_extract16<0x15, "vpextrw">, VEX;
6281
6282 defm PEXTRW      : SS41I_extract16<0x15, "pextrw">;
6283
6284
6285 /// SS41I_extract32 - SSE 4.1 extract 32 bits to int reg or memory destination
6286 multiclass SS41I_extract32<bits<8> opc, string OpcodeStr> {
6287   def rr : SS4AIi8<opc, MRMDestReg, (outs GR32:$dst),
6288                  (ins VR128:$src1, i32i8imm:$src2),
6289                  !strconcat(OpcodeStr,
6290                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6291                  [(set GR32:$dst,
6292                   (extractelt (v4i32 VR128:$src1), imm:$src2))]>, OpSize;
6293   def mr : SS4AIi8<opc, MRMDestMem, (outs),
6294                  (ins i32mem:$dst, VR128:$src1, i32i8imm:$src2),
6295                  !strconcat(OpcodeStr,
6296                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6297                  [(store (extractelt (v4i32 VR128:$src1), imm:$src2),
6298                           addr:$dst)]>, OpSize;
6299 }
6300
6301 let Predicates = [HasAVX] in
6302   defm VPEXTRD : SS41I_extract32<0x16, "vpextrd">, VEX;
6303
6304 defm PEXTRD      : SS41I_extract32<0x16, "pextrd">;
6305
6306 /// SS41I_extract32 - SSE 4.1 extract 32 bits to int reg or memory destination
6307 multiclass SS41I_extract64<bits<8> opc, string OpcodeStr> {
6308   def rr : SS4AIi8<opc, MRMDestReg, (outs GR64:$dst),
6309                  (ins VR128:$src1, i32i8imm:$src2),
6310                  !strconcat(OpcodeStr,
6311                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6312                  [(set GR64:$dst,
6313                   (extractelt (v2i64 VR128:$src1), imm:$src2))]>, OpSize, REX_W;
6314   def mr : SS4AIi8<opc, MRMDestMem, (outs),
6315                  (ins i64mem:$dst, VR128:$src1, i32i8imm:$src2),
6316                  !strconcat(OpcodeStr,
6317                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6318                  [(store (extractelt (v2i64 VR128:$src1), imm:$src2),
6319                           addr:$dst)]>, OpSize, REX_W;
6320 }
6321
6322 let Predicates = [HasAVX] in
6323   defm VPEXTRQ : SS41I_extract64<0x16, "vpextrq">, VEX, VEX_W;
6324
6325 defm PEXTRQ      : SS41I_extract64<0x16, "pextrq">;
6326
6327 /// SS41I_extractf32 - SSE 4.1 extract 32 bits fp value to int reg or memory
6328 /// destination
6329 multiclass SS41I_extractf32<bits<8> opc, string OpcodeStr,
6330                             OpndItins itins = DEFAULT_ITINS> {
6331   def rr : SS4AIi8<opc, MRMDestReg, (outs GR32orGR64:$dst),
6332                  (ins VR128:$src1, i32i8imm:$src2),
6333                  !strconcat(OpcodeStr,
6334                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6335                  [(set GR32orGR64:$dst,
6336                     (extractelt (bc_v4i32 (v4f32 VR128:$src1)), imm:$src2))],
6337                     itins.rr>,
6338            OpSize;
6339   def mr : SS4AIi8<opc, MRMDestMem, (outs),
6340                  (ins f32mem:$dst, VR128:$src1, i32i8imm:$src2),
6341                  !strconcat(OpcodeStr,
6342                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6343                  [(store (extractelt (bc_v4i32 (v4f32 VR128:$src1)), imm:$src2),
6344                           addr:$dst)], itins.rm>, OpSize;
6345 }
6346
6347 let ExeDomain = SSEPackedSingle in {
6348   let Predicates = [UseAVX] in
6349     defm VEXTRACTPS : SS41I_extractf32<0x17, "vextractps">, VEX;
6350   defm EXTRACTPS   : SS41I_extractf32<0x17, "extractps", SSE_EXTRACT_ITINS>;
6351 }
6352
6353 // Also match an EXTRACTPS store when the store is done as f32 instead of i32.
6354 def : Pat<(store (f32 (bitconvert (extractelt (bc_v4i32 (v4f32 VR128:$src1)),
6355                                               imm:$src2))),
6356                  addr:$dst),
6357           (VEXTRACTPSmr addr:$dst, VR128:$src1, imm:$src2)>,
6358           Requires<[HasAVX]>;
6359 def : Pat<(store (f32 (bitconvert (extractelt (bc_v4i32 (v4f32 VR128:$src1)),
6360                                               imm:$src2))),
6361                  addr:$dst),
6362           (EXTRACTPSmr addr:$dst, VR128:$src1, imm:$src2)>,
6363           Requires<[UseSSE41]>;
6364
6365 //===----------------------------------------------------------------------===//
6366 // SSE4.1 - Insert Instructions
6367 //===----------------------------------------------------------------------===//
6368
6369 multiclass SS41I_insert8<bits<8> opc, string asm, bit Is2Addr = 1> {
6370   def rr : SS4AIi8<opc, MRMSrcReg, (outs VR128:$dst),
6371       (ins VR128:$src1, GR32orGR64:$src2, i32i8imm:$src3),
6372       !if(Is2Addr,
6373         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6374         !strconcat(asm,
6375                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6376       [(set VR128:$dst,
6377         (X86pinsrb VR128:$src1, GR32orGR64:$src2, imm:$src3))]>, OpSize;
6378   def rm : SS4AIi8<opc, MRMSrcMem, (outs VR128:$dst),
6379       (ins VR128:$src1, i8mem:$src2, i32i8imm:$src3),
6380       !if(Is2Addr,
6381         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6382         !strconcat(asm,
6383                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6384       [(set VR128:$dst,
6385         (X86pinsrb VR128:$src1, (extloadi8 addr:$src2),
6386                    imm:$src3))]>, OpSize;
6387 }
6388
6389 let Predicates = [HasAVX] in
6390   defm VPINSRB : SS41I_insert8<0x20, "vpinsrb", 0>, VEX_4V;
6391 let Constraints = "$src1 = $dst" in
6392   defm PINSRB  : SS41I_insert8<0x20, "pinsrb">;
6393
6394 multiclass SS41I_insert32<bits<8> opc, string asm, bit Is2Addr = 1> {
6395   def rr : SS4AIi8<opc, MRMSrcReg, (outs VR128:$dst),
6396       (ins VR128:$src1, GR32:$src2, i32i8imm:$src3),
6397       !if(Is2Addr,
6398         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6399         !strconcat(asm,
6400                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6401       [(set VR128:$dst,
6402         (v4i32 (insertelt VR128:$src1, GR32:$src2, imm:$src3)))]>,
6403       OpSize;
6404   def rm : SS4AIi8<opc, MRMSrcMem, (outs VR128:$dst),
6405       (ins VR128:$src1, i32mem:$src2, i32i8imm:$src3),
6406       !if(Is2Addr,
6407         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6408         !strconcat(asm,
6409                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6410       [(set VR128:$dst,
6411         (v4i32 (insertelt VR128:$src1, (loadi32 addr:$src2),
6412                           imm:$src3)))]>, OpSize;
6413 }
6414
6415 let Predicates = [HasAVX] in
6416   defm VPINSRD : SS41I_insert32<0x22, "vpinsrd", 0>, VEX_4V;
6417 let Constraints = "$src1 = $dst" in
6418   defm PINSRD : SS41I_insert32<0x22, "pinsrd">;
6419
6420 multiclass SS41I_insert64<bits<8> opc, string asm, bit Is2Addr = 1> {
6421   def rr : SS4AIi8<opc, MRMSrcReg, (outs VR128:$dst),
6422       (ins VR128:$src1, GR64:$src2, i32i8imm:$src3),
6423       !if(Is2Addr,
6424         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6425         !strconcat(asm,
6426                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6427       [(set VR128:$dst,
6428         (v2i64 (insertelt VR128:$src1, GR64:$src2, imm:$src3)))]>,
6429       OpSize;
6430   def rm : SS4AIi8<opc, MRMSrcMem, (outs VR128:$dst),
6431       (ins VR128:$src1, i64mem:$src2, i32i8imm:$src3),
6432       !if(Is2Addr,
6433         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6434         !strconcat(asm,
6435                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6436       [(set VR128:$dst,
6437         (v2i64 (insertelt VR128:$src1, (loadi64 addr:$src2),
6438                           imm:$src3)))]>, OpSize;
6439 }
6440
6441 let Predicates = [HasAVX] in
6442   defm VPINSRQ : SS41I_insert64<0x22, "vpinsrq", 0>, VEX_4V, VEX_W;
6443 let Constraints = "$src1 = $dst" in
6444   defm PINSRQ : SS41I_insert64<0x22, "pinsrq">, REX_W;
6445
6446 // insertps has a few different modes, there's the first two here below which
6447 // are optimized inserts that won't zero arbitrary elements in the destination
6448 // vector. The next one matches the intrinsic and could zero arbitrary elements
6449 // in the target vector.
6450 multiclass SS41I_insertf32<bits<8> opc, string asm, bit Is2Addr = 1,
6451                            OpndItins itins = DEFAULT_ITINS> {
6452   def rr : SS4AIi8<opc, MRMSrcReg, (outs VR128:$dst),
6453       (ins VR128:$src1, VR128:$src2, u32u8imm:$src3),
6454       !if(Is2Addr,
6455         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6456         !strconcat(asm,
6457                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6458       [(set VR128:$dst,
6459         (X86insrtps VR128:$src1, VR128:$src2, imm:$src3))], itins.rr>,
6460       OpSize;
6461   def rm : SS4AIi8<opc, MRMSrcMem, (outs VR128:$dst),
6462       (ins VR128:$src1, f32mem:$src2, u32u8imm:$src3),
6463       !if(Is2Addr,
6464         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6465         !strconcat(asm,
6466                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6467       [(set VR128:$dst,
6468         (X86insrtps VR128:$src1,
6469                    (v4f32 (scalar_to_vector (loadf32 addr:$src2))),
6470                     imm:$src3))], itins.rm>, OpSize;
6471 }
6472
6473 let ExeDomain = SSEPackedSingle in {
6474   let Predicates = [UseAVX] in
6475     defm VINSERTPS : SS41I_insertf32<0x21, "vinsertps", 0>, VEX_4V;
6476   let Constraints = "$src1 = $dst" in
6477     defm INSERTPS : SS41I_insertf32<0x21, "insertps", 1, SSE_INSERT_ITINS>;
6478 }
6479
6480 //===----------------------------------------------------------------------===//
6481 // SSE4.1 - Round Instructions
6482 //===----------------------------------------------------------------------===//
6483
6484 multiclass sse41_fp_unop_rm<bits<8> opcps, bits<8> opcpd, string OpcodeStr,
6485                             X86MemOperand x86memop, RegisterClass RC,
6486                             PatFrag mem_frag32, PatFrag mem_frag64,
6487                             Intrinsic V4F32Int, Intrinsic V2F64Int> {
6488 let ExeDomain = SSEPackedSingle in {
6489   // Intrinsic operation, reg.
6490   // Vector intrinsic operation, reg
6491   def PSr : SS4AIi8<opcps, MRMSrcReg,
6492                     (outs RC:$dst), (ins RC:$src1, i32i8imm:$src2),
6493                     !strconcat(OpcodeStr,
6494                     "ps\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6495                     [(set RC:$dst, (V4F32Int RC:$src1, imm:$src2))],
6496                     IIC_SSE_ROUNDPS_REG>,
6497                     OpSize;
6498
6499   // Vector intrinsic operation, mem
6500   def PSm : SS4AIi8<opcps, MRMSrcMem,
6501                     (outs RC:$dst), (ins x86memop:$src1, i32i8imm:$src2),
6502                     !strconcat(OpcodeStr,
6503                     "ps\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6504                     [(set RC:$dst,
6505                           (V4F32Int (mem_frag32 addr:$src1),imm:$src2))],
6506                           IIC_SSE_ROUNDPS_MEM>,
6507                     OpSize;
6508 } // ExeDomain = SSEPackedSingle
6509
6510 let ExeDomain = SSEPackedDouble in {
6511   // Vector intrinsic operation, reg
6512   def PDr : SS4AIi8<opcpd, MRMSrcReg,
6513                     (outs RC:$dst), (ins RC:$src1, i32i8imm:$src2),
6514                     !strconcat(OpcodeStr,
6515                     "pd\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6516                     [(set RC:$dst, (V2F64Int RC:$src1, imm:$src2))],
6517                     IIC_SSE_ROUNDPS_REG>,
6518                     OpSize;
6519
6520   // Vector intrinsic operation, mem
6521   def PDm : SS4AIi8<opcpd, MRMSrcMem,
6522                     (outs RC:$dst), (ins x86memop:$src1, i32i8imm:$src2),
6523                     !strconcat(OpcodeStr,
6524                     "pd\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6525                     [(set RC:$dst,
6526                           (V2F64Int (mem_frag64 addr:$src1),imm:$src2))],
6527                           IIC_SSE_ROUNDPS_REG>,
6528                     OpSize;
6529 } // ExeDomain = SSEPackedDouble
6530 }
6531
6532 multiclass sse41_fp_binop_rm<bits<8> opcss, bits<8> opcsd,
6533                             string OpcodeStr,
6534                             Intrinsic F32Int,
6535                             Intrinsic F64Int, bit Is2Addr = 1> {
6536 let ExeDomain = GenericDomain in {
6537   // Operation, reg.
6538   let hasSideEffects = 0 in
6539   def SSr : SS4AIi8<opcss, MRMSrcReg,
6540       (outs FR32:$dst), (ins FR32:$src1, FR32:$src2, i32i8imm:$src3),
6541       !if(Is2Addr,
6542           !strconcat(OpcodeStr,
6543               "ss\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6544           !strconcat(OpcodeStr,
6545               "ss\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6546       []>, OpSize;
6547
6548   // Intrinsic operation, reg.
6549   let isCodeGenOnly = 1 in
6550   def SSr_Int : SS4AIi8<opcss, MRMSrcReg,
6551         (outs VR128:$dst), (ins VR128:$src1, VR128:$src2, i32i8imm:$src3),
6552         !if(Is2Addr,
6553             !strconcat(OpcodeStr,
6554                 "ss\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6555             !strconcat(OpcodeStr,
6556                 "ss\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6557         [(set VR128:$dst, (F32Int VR128:$src1, VR128:$src2, imm:$src3))]>,
6558         OpSize;
6559
6560   // Intrinsic operation, mem.
6561   def SSm : SS4AIi8<opcss, MRMSrcMem,
6562         (outs VR128:$dst), (ins VR128:$src1, ssmem:$src2, i32i8imm:$src3),
6563         !if(Is2Addr,
6564             !strconcat(OpcodeStr,
6565                 "ss\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6566             !strconcat(OpcodeStr,
6567                 "ss\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6568         [(set VR128:$dst,
6569              (F32Int VR128:$src1, sse_load_f32:$src2, imm:$src3))]>,
6570         OpSize;
6571
6572   // Operation, reg.
6573   let hasSideEffects = 0 in
6574   def SDr : SS4AIi8<opcsd, MRMSrcReg,
6575         (outs FR64:$dst), (ins FR64:$src1, FR64:$src2, i32i8imm:$src3),
6576         !if(Is2Addr,
6577             !strconcat(OpcodeStr,
6578                 "sd\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6579             !strconcat(OpcodeStr,
6580                 "sd\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6581         []>, OpSize;
6582
6583   // Intrinsic operation, reg.
6584   let isCodeGenOnly = 1 in
6585   def SDr_Int : SS4AIi8<opcsd, MRMSrcReg,
6586         (outs VR128:$dst), (ins VR128:$src1, VR128:$src2, i32i8imm:$src3),
6587         !if(Is2Addr,
6588             !strconcat(OpcodeStr,
6589                 "sd\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6590             !strconcat(OpcodeStr,
6591                 "sd\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6592         [(set VR128:$dst, (F64Int VR128:$src1, VR128:$src2, imm:$src3))]>,
6593         OpSize;
6594
6595   // Intrinsic operation, mem.
6596   def SDm : SS4AIi8<opcsd, MRMSrcMem,
6597         (outs VR128:$dst), (ins VR128:$src1, sdmem:$src2, i32i8imm:$src3),
6598         !if(Is2Addr,
6599             !strconcat(OpcodeStr,
6600                 "sd\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6601             !strconcat(OpcodeStr,
6602                 "sd\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6603         [(set VR128:$dst,
6604               (F64Int VR128:$src1, sse_load_f64:$src2, imm:$src3))]>,
6605         OpSize;
6606 } // ExeDomain = GenericDomain
6607 }
6608
6609 // FP round - roundss, roundps, roundsd, roundpd
6610 let Predicates = [HasAVX] in {
6611   // Intrinsic form
6612   defm VROUND  : sse41_fp_unop_rm<0x08, 0x09, "vround", f128mem, VR128,
6613                                   loadv4f32, loadv2f64,
6614                                   int_x86_sse41_round_ps,
6615                                   int_x86_sse41_round_pd>, VEX;
6616   defm VROUNDY : sse41_fp_unop_rm<0x08, 0x09, "vround", f256mem, VR256,
6617                                   loadv8f32, loadv4f64,
6618                                   int_x86_avx_round_ps_256,
6619                                   int_x86_avx_round_pd_256>, VEX, VEX_L;
6620   defm VROUND  : sse41_fp_binop_rm<0x0A, 0x0B, "vround",
6621                                   int_x86_sse41_round_ss,
6622                                   int_x86_sse41_round_sd, 0>, VEX_4V, VEX_LIG;
6623
6624   def : Pat<(ffloor FR32:$src),
6625             (VROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x1))>;
6626   def : Pat<(f64 (ffloor FR64:$src)),
6627             (VROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x1))>;
6628   def : Pat<(f32 (fnearbyint FR32:$src)),
6629             (VROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0xC))>;
6630   def : Pat<(f64 (fnearbyint FR64:$src)),
6631             (VROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0xC))>;
6632   def : Pat<(f32 (fceil FR32:$src)),
6633             (VROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x2))>;
6634   def : Pat<(f64 (fceil FR64:$src)),
6635             (VROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x2))>;
6636   def : Pat<(f32 (frint FR32:$src)),
6637             (VROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x4))>;
6638   def : Pat<(f64 (frint FR64:$src)),
6639             (VROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x4))>;
6640   def : Pat<(f32 (ftrunc FR32:$src)),
6641             (VROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x3))>;
6642   def : Pat<(f64 (ftrunc FR64:$src)),
6643             (VROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x3))>;
6644
6645   def : Pat<(v4f32 (ffloor VR128:$src)),
6646             (VROUNDPSr VR128:$src, (i32 0x1))>;
6647   def : Pat<(v4f32 (fnearbyint VR128:$src)),
6648             (VROUNDPSr VR128:$src, (i32 0xC))>;
6649   def : Pat<(v4f32 (fceil VR128:$src)),
6650             (VROUNDPSr VR128:$src, (i32 0x2))>;
6651   def : Pat<(v4f32 (frint VR128:$src)),
6652             (VROUNDPSr VR128:$src, (i32 0x4))>;
6653   def : Pat<(v4f32 (ftrunc VR128:$src)),
6654             (VROUNDPSr VR128:$src, (i32 0x3))>;
6655
6656   def : Pat<(v2f64 (ffloor VR128:$src)),
6657             (VROUNDPDr VR128:$src, (i32 0x1))>;
6658   def : Pat<(v2f64 (fnearbyint VR128:$src)),
6659             (VROUNDPDr VR128:$src, (i32 0xC))>;
6660   def : Pat<(v2f64 (fceil VR128:$src)),
6661             (VROUNDPDr VR128:$src, (i32 0x2))>;
6662   def : Pat<(v2f64 (frint VR128:$src)),
6663             (VROUNDPDr VR128:$src, (i32 0x4))>;
6664   def : Pat<(v2f64 (ftrunc VR128:$src)),
6665             (VROUNDPDr VR128:$src, (i32 0x3))>;
6666
6667   def : Pat<(v8f32 (ffloor VR256:$src)),
6668             (VROUNDYPSr VR256:$src, (i32 0x1))>;
6669   def : Pat<(v8f32 (fnearbyint VR256:$src)),
6670             (VROUNDYPSr VR256:$src, (i32 0xC))>;
6671   def : Pat<(v8f32 (fceil VR256:$src)),
6672             (VROUNDYPSr VR256:$src, (i32 0x2))>;
6673   def : Pat<(v8f32 (frint VR256:$src)),
6674             (VROUNDYPSr VR256:$src, (i32 0x4))>;
6675   def : Pat<(v8f32 (ftrunc VR256:$src)),
6676             (VROUNDYPSr VR256:$src, (i32 0x3))>;
6677
6678   def : Pat<(v4f64 (ffloor VR256:$src)),
6679             (VROUNDYPDr VR256:$src, (i32 0x1))>;
6680   def : Pat<(v4f64 (fnearbyint VR256:$src)),
6681             (VROUNDYPDr VR256:$src, (i32 0xC))>;
6682   def : Pat<(v4f64 (fceil VR256:$src)),
6683             (VROUNDYPDr VR256:$src, (i32 0x2))>;
6684   def : Pat<(v4f64 (frint VR256:$src)),
6685             (VROUNDYPDr VR256:$src, (i32 0x4))>;
6686   def : Pat<(v4f64 (ftrunc VR256:$src)),
6687             (VROUNDYPDr VR256:$src, (i32 0x3))>;
6688 }
6689
6690 defm ROUND  : sse41_fp_unop_rm<0x08, 0x09, "round", f128mem, VR128,
6691                                memopv4f32, memopv2f64,
6692                                int_x86_sse41_round_ps, int_x86_sse41_round_pd>;
6693 let Constraints = "$src1 = $dst" in
6694 defm ROUND  : sse41_fp_binop_rm<0x0A, 0x0B, "round",
6695                                int_x86_sse41_round_ss, int_x86_sse41_round_sd>;
6696
6697 let Predicates = [UseSSE41] in {
6698   def : Pat<(ffloor FR32:$src),
6699             (ROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x1))>;
6700   def : Pat<(f64 (ffloor FR64:$src)),
6701             (ROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x1))>;
6702   def : Pat<(f32 (fnearbyint FR32:$src)),
6703             (ROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0xC))>;
6704   def : Pat<(f64 (fnearbyint FR64:$src)),
6705             (ROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0xC))>;
6706   def : Pat<(f32 (fceil FR32:$src)),
6707             (ROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x2))>;
6708   def : Pat<(f64 (fceil FR64:$src)),
6709             (ROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x2))>;
6710   def : Pat<(f32 (frint FR32:$src)),
6711             (ROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x4))>;
6712   def : Pat<(f64 (frint FR64:$src)),
6713             (ROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x4))>;
6714   def : Pat<(f32 (ftrunc FR32:$src)),
6715             (ROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x3))>;
6716   def : Pat<(f64 (ftrunc FR64:$src)),
6717             (ROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x3))>;
6718
6719   def : Pat<(v4f32 (ffloor VR128:$src)),
6720             (ROUNDPSr VR128:$src, (i32 0x1))>;
6721   def : Pat<(v4f32 (fnearbyint VR128:$src)),
6722             (ROUNDPSr VR128:$src, (i32 0xC))>;
6723   def : Pat<(v4f32 (fceil VR128:$src)),
6724             (ROUNDPSr VR128:$src, (i32 0x2))>;
6725   def : Pat<(v4f32 (frint VR128:$src)),
6726             (ROUNDPSr VR128:$src, (i32 0x4))>;
6727   def : Pat<(v4f32 (ftrunc VR128:$src)),
6728             (ROUNDPSr VR128:$src, (i32 0x3))>;
6729
6730   def : Pat<(v2f64 (ffloor VR128:$src)),
6731             (ROUNDPDr VR128:$src, (i32 0x1))>;
6732   def : Pat<(v2f64 (fnearbyint VR128:$src)),
6733             (ROUNDPDr VR128:$src, (i32 0xC))>;
6734   def : Pat<(v2f64 (fceil VR128:$src)),
6735             (ROUNDPDr VR128:$src, (i32 0x2))>;
6736   def : Pat<(v2f64 (frint VR128:$src)),
6737             (ROUNDPDr VR128:$src, (i32 0x4))>;
6738   def : Pat<(v2f64 (ftrunc VR128:$src)),
6739             (ROUNDPDr VR128:$src, (i32 0x3))>;
6740 }
6741
6742 //===----------------------------------------------------------------------===//
6743 // SSE4.1 - Packed Bit Test
6744 //===----------------------------------------------------------------------===//
6745
6746 // ptest instruction we'll lower to this in X86ISelLowering primarily from
6747 // the intel intrinsic that corresponds to this.
6748 let Defs = [EFLAGS], Predicates = [HasAVX] in {
6749 def VPTESTrr  : SS48I<0x17, MRMSrcReg, (outs), (ins VR128:$src1, VR128:$src2),
6750                 "vptest\t{$src2, $src1|$src1, $src2}",
6751                 [(set EFLAGS, (X86ptest VR128:$src1, (v2i64 VR128:$src2)))]>,
6752                 OpSize, VEX;
6753 def VPTESTrm  : SS48I<0x17, MRMSrcMem, (outs), (ins VR128:$src1, f128mem:$src2),
6754                 "vptest\t{$src2, $src1|$src1, $src2}",
6755                 [(set EFLAGS,(X86ptest VR128:$src1, (loadv2i64 addr:$src2)))]>,
6756                 OpSize, VEX;
6757
6758 def VPTESTYrr : SS48I<0x17, MRMSrcReg, (outs), (ins VR256:$src1, VR256:$src2),
6759                 "vptest\t{$src2, $src1|$src1, $src2}",
6760                 [(set EFLAGS, (X86ptest VR256:$src1, (v4i64 VR256:$src2)))]>,
6761                 OpSize, VEX, VEX_L;
6762 def VPTESTYrm : SS48I<0x17, MRMSrcMem, (outs), (ins VR256:$src1, i256mem:$src2),
6763                 "vptest\t{$src2, $src1|$src1, $src2}",
6764                 [(set EFLAGS,(X86ptest VR256:$src1, (loadv4i64 addr:$src2)))]>,
6765                 OpSize, VEX, VEX_L;
6766 }
6767
6768 let Defs = [EFLAGS] in {
6769 def PTESTrr : SS48I<0x17, MRMSrcReg, (outs), (ins VR128:$src1, VR128:$src2),
6770               "ptest\t{$src2, $src1|$src1, $src2}",
6771               [(set EFLAGS, (X86ptest VR128:$src1, (v2i64 VR128:$src2)))]>,
6772               OpSize;
6773 def PTESTrm : SS48I<0x17, MRMSrcMem, (outs), (ins VR128:$src1, f128mem:$src2),
6774               "ptest\t{$src2, $src1|$src1, $src2}",
6775               [(set EFLAGS, (X86ptest VR128:$src1, (memopv2i64 addr:$src2)))]>,
6776               OpSize;
6777 }
6778
6779 // The bit test instructions below are AVX only
6780 multiclass avx_bittest<bits<8> opc, string OpcodeStr, RegisterClass RC,
6781                        X86MemOperand x86memop, PatFrag mem_frag, ValueType vt> {
6782   def rr : SS48I<opc, MRMSrcReg, (outs), (ins RC:$src1, RC:$src2),
6783             !strconcat(OpcodeStr, "\t{$src2, $src1|$src1, $src2}"),
6784             [(set EFLAGS, (X86testp RC:$src1, (vt RC:$src2)))]>, OpSize, VEX;
6785   def rm : SS48I<opc, MRMSrcMem, (outs), (ins RC:$src1, x86memop:$src2),
6786             !strconcat(OpcodeStr, "\t{$src2, $src1|$src1, $src2}"),
6787             [(set EFLAGS, (X86testp RC:$src1, (mem_frag addr:$src2)))]>,
6788             OpSize, VEX;
6789 }
6790
6791 let Defs = [EFLAGS], Predicates = [HasAVX] in {
6792 let ExeDomain = SSEPackedSingle in {
6793 defm VTESTPS  : avx_bittest<0x0E, "vtestps", VR128, f128mem, loadv4f32, v4f32>;
6794 defm VTESTPSY : avx_bittest<0x0E, "vtestps", VR256, f256mem, loadv8f32, v8f32>,
6795                             VEX_L;
6796 }
6797 let ExeDomain = SSEPackedDouble in {
6798 defm VTESTPD  : avx_bittest<0x0F, "vtestpd", VR128, f128mem, loadv2f64, v2f64>;
6799 defm VTESTPDY : avx_bittest<0x0F, "vtestpd", VR256, f256mem, loadv4f64, v4f64>,
6800                             VEX_L;
6801 }
6802 }
6803
6804 //===----------------------------------------------------------------------===//
6805 // SSE4.1 - Misc Instructions
6806 //===----------------------------------------------------------------------===//
6807
6808 let Defs = [EFLAGS], Predicates = [HasPOPCNT] in {
6809   def POPCNT16rr : I<0xB8, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
6810                      "popcnt{w}\t{$src, $dst|$dst, $src}",
6811                      [(set GR16:$dst, (ctpop GR16:$src)), (implicit EFLAGS)],
6812                      IIC_SSE_POPCNT_RR>,
6813                      OpSize, XS;
6814   def POPCNT16rm : I<0xB8, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
6815                      "popcnt{w}\t{$src, $dst|$dst, $src}",
6816                      [(set GR16:$dst, (ctpop (loadi16 addr:$src))),
6817                       (implicit EFLAGS)], IIC_SSE_POPCNT_RM>, OpSize, XS;
6818
6819   def POPCNT32rr : I<0xB8, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
6820                      "popcnt{l}\t{$src, $dst|$dst, $src}",
6821                      [(set GR32:$dst, (ctpop GR32:$src)), (implicit EFLAGS)],
6822                      IIC_SSE_POPCNT_RR>,
6823                      XS;
6824   def POPCNT32rm : I<0xB8, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
6825                      "popcnt{l}\t{$src, $dst|$dst, $src}",
6826                      [(set GR32:$dst, (ctpop (loadi32 addr:$src))),
6827                       (implicit EFLAGS)], IIC_SSE_POPCNT_RM>, XS;
6828
6829   def POPCNT64rr : RI<0xB8, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
6830                       "popcnt{q}\t{$src, $dst|$dst, $src}",
6831                       [(set GR64:$dst, (ctpop GR64:$src)), (implicit EFLAGS)],
6832                       IIC_SSE_POPCNT_RR>,
6833                       XS;
6834   def POPCNT64rm : RI<0xB8, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
6835                       "popcnt{q}\t{$src, $dst|$dst, $src}",
6836                       [(set GR64:$dst, (ctpop (loadi64 addr:$src))),
6837                        (implicit EFLAGS)], IIC_SSE_POPCNT_RM>, XS;
6838 }
6839
6840
6841
6842 // SS41I_unop_rm_int_v16 - SSE 4.1 unary operator whose type is v8i16.
6843 multiclass SS41I_unop_rm_int_v16<bits<8> opc, string OpcodeStr,
6844                                  Intrinsic IntId128> {
6845   def rr128 : SS48I<opc, MRMSrcReg, (outs VR128:$dst),
6846                     (ins VR128:$src),
6847                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
6848                     [(set VR128:$dst, (IntId128 VR128:$src))]>, OpSize;
6849   def rm128 : SS48I<opc, MRMSrcMem, (outs VR128:$dst),
6850                      (ins i128mem:$src),
6851                      !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
6852                      [(set VR128:$dst,
6853                        (IntId128
6854                         (bitconvert (memopv2i64 addr:$src))))]>, OpSize;
6855 }
6856
6857 let Predicates = [HasAVX] in
6858 defm VPHMINPOSUW : SS41I_unop_rm_int_v16 <0x41, "vphminposuw",
6859                                          int_x86_sse41_phminposuw>, VEX;
6860 defm PHMINPOSUW : SS41I_unop_rm_int_v16 <0x41, "phminposuw",
6861                                          int_x86_sse41_phminposuw>;
6862
6863 /// SS41I_binop_rm_int - Simple SSE 4.1 binary operator
6864 multiclass SS41I_binop_rm_int<bits<8> opc, string OpcodeStr,
6865                               Intrinsic IntId128, bit Is2Addr = 1,
6866                               OpndItins itins = DEFAULT_ITINS> {
6867   let isCommutable = 1 in
6868   def rr : SS48I<opc, MRMSrcReg, (outs VR128:$dst),
6869        (ins VR128:$src1, VR128:$src2),
6870        !if(Is2Addr,
6871            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
6872            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
6873        [(set VR128:$dst, (IntId128 VR128:$src1, VR128:$src2))],
6874         itins.rr>, OpSize;
6875   def rm : SS48I<opc, MRMSrcMem, (outs VR128:$dst),
6876        (ins VR128:$src1, i128mem:$src2),
6877        !if(Is2Addr,
6878            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
6879            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
6880        [(set VR128:$dst,
6881          (IntId128 VR128:$src1,
6882           (bitconvert (memopv2i64 addr:$src2))))],
6883           itins.rm>, OpSize;
6884 }
6885
6886 /// SS41I_binop_rm_int_y - Simple SSE 4.1 binary operator
6887 multiclass SS41I_binop_rm_int_y<bits<8> opc, string OpcodeStr,
6888                                 Intrinsic IntId256> {
6889   let isCommutable = 1 in
6890   def Yrr : SS48I<opc, MRMSrcReg, (outs VR256:$dst),
6891        (ins VR256:$src1, VR256:$src2),
6892        !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6893        [(set VR256:$dst, (IntId256 VR256:$src1, VR256:$src2))]>, OpSize;
6894   def Yrm : SS48I<opc, MRMSrcMem, (outs VR256:$dst),
6895        (ins VR256:$src1, i256mem:$src2),
6896        !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6897        [(set VR256:$dst,
6898          (IntId256 VR256:$src1,
6899           (bitconvert (loadv4i64 addr:$src2))))]>, OpSize;
6900 }
6901
6902
6903 /// SS48I_binop_rm - Simple SSE41 binary operator.
6904 multiclass SS48I_binop_rm<bits<8> opc, string OpcodeStr, SDNode OpNode,
6905                           ValueType OpVT, RegisterClass RC, PatFrag memop_frag,
6906                           X86MemOperand x86memop, bit Is2Addr = 1,
6907                           OpndItins itins = DEFAULT_ITINS> {
6908   let isCommutable = 1 in
6909   def rr : SS48I<opc, MRMSrcReg, (outs RC:$dst),
6910        (ins RC:$src1, RC:$src2),
6911        !if(Is2Addr,
6912            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
6913            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
6914        [(set RC:$dst, (OpVT (OpNode RC:$src1, RC:$src2)))]>, OpSize;
6915   def rm : SS48I<opc, MRMSrcMem, (outs RC:$dst),
6916        (ins RC:$src1, x86memop:$src2),
6917        !if(Is2Addr,
6918            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
6919            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
6920        [(set RC:$dst,
6921          (OpVT (OpNode RC:$src1,
6922           (bitconvert (memop_frag addr:$src2)))))]>, OpSize;
6923 }
6924
6925 let Predicates = [HasAVX] in {
6926   let isCommutable = 0 in
6927   defm VPACKUSDW : SS41I_binop_rm_int<0x2B, "vpackusdw", int_x86_sse41_packusdw,
6928                                                          0>, VEX_4V;
6929   defm VPMINSB   : SS48I_binop_rm<0x38, "vpminsb", X86smin, v16i8, VR128,
6930                                   loadv2i64, i128mem, 0>, VEX_4V;
6931   defm VPMINSD   : SS48I_binop_rm<0x39, "vpminsd", X86smin, v4i32, VR128,
6932                                   loadv2i64, i128mem, 0>, VEX_4V;
6933   defm VPMINUD   : SS48I_binop_rm<0x3B, "vpminud", X86umin, v4i32, VR128,
6934                                   loadv2i64, i128mem, 0>, VEX_4V;
6935   defm VPMINUW   : SS48I_binop_rm<0x3A, "vpminuw", X86umin, v8i16, VR128,
6936                                   loadv2i64, i128mem, 0>, VEX_4V;
6937   defm VPMAXSB   : SS48I_binop_rm<0x3C, "vpmaxsb", X86smax, v16i8, VR128,
6938                                   loadv2i64, i128mem, 0>, VEX_4V;
6939   defm VPMAXSD   : SS48I_binop_rm<0x3D, "vpmaxsd", X86smax, v4i32, VR128,
6940                                   loadv2i64, i128mem, 0>, VEX_4V;
6941   defm VPMAXUD   : SS48I_binop_rm<0x3F, "vpmaxud", X86umax, v4i32, VR128,
6942                                   loadv2i64, i128mem, 0>, VEX_4V;
6943   defm VPMAXUW   : SS48I_binop_rm<0x3E, "vpmaxuw", X86umax, v8i16, VR128,
6944                                   loadv2i64, i128mem, 0>, VEX_4V;
6945   defm VPMULDQ   : SS41I_binop_rm_int<0x28, "vpmuldq",   int_x86_sse41_pmuldq,
6946                                                          0>, VEX_4V;
6947 }
6948
6949 let Predicates = [HasAVX2] in {
6950   let isCommutable = 0 in
6951   defm VPACKUSDW : SS41I_binop_rm_int_y<0x2B, "vpackusdw",
6952                                         int_x86_avx2_packusdw>, VEX_4V, VEX_L;
6953   defm VPMINSBY  : SS48I_binop_rm<0x38, "vpminsb", X86smin, v32i8, VR256,
6954                                   loadv4i64, i256mem, 0>, VEX_4V, VEX_L;
6955   defm VPMINSDY  : SS48I_binop_rm<0x39, "vpminsd", X86smin, v8i32, VR256,
6956                                   loadv4i64, i256mem, 0>, VEX_4V, VEX_L;
6957   defm VPMINUDY  : SS48I_binop_rm<0x3B, "vpminud", X86umin, v8i32, VR256,
6958                                   loadv4i64, i256mem, 0>, VEX_4V, VEX_L;
6959   defm VPMINUWY  : SS48I_binop_rm<0x3A, "vpminuw", X86umin, v16i16, VR256,
6960                                   loadv4i64, i256mem, 0>, VEX_4V, VEX_L;
6961   defm VPMAXSBY  : SS48I_binop_rm<0x3C, "vpmaxsb", X86smax, v32i8, VR256,
6962                                   loadv4i64, i256mem, 0>, VEX_4V, VEX_L;
6963   defm VPMAXSDY  : SS48I_binop_rm<0x3D, "vpmaxsd", X86smax, v8i32, VR256,
6964                                   loadv4i64, i256mem, 0>, VEX_4V, VEX_L;
6965   defm VPMAXUDY  : SS48I_binop_rm<0x3F, "vpmaxud", X86umax, v8i32, VR256,
6966                                   loadv4i64, i256mem, 0>, VEX_4V, VEX_L;
6967   defm VPMAXUWY  : SS48I_binop_rm<0x3E, "vpmaxuw", X86umax, v16i16, VR256,
6968                                   loadv4i64, i256mem, 0>, VEX_4V, VEX_L;
6969   defm VPMULDQ   : SS41I_binop_rm_int_y<0x28, "vpmuldq",
6970                                         int_x86_avx2_pmul_dq>, VEX_4V, VEX_L;
6971 }
6972
6973 let Constraints = "$src1 = $dst" in {
6974   let isCommutable = 0 in
6975   defm PACKUSDW : SS41I_binop_rm_int<0x2B, "packusdw", int_x86_sse41_packusdw>;
6976   defm PMINSB   : SS48I_binop_rm<0x38, "pminsb", X86smin, v16i8, VR128,
6977                                  memopv2i64, i128mem, 1, SSE_INTALU_ITINS_P>;
6978   defm PMINSD   : SS48I_binop_rm<0x39, "pminsd", X86smin, v4i32, VR128,
6979                                  memopv2i64, i128mem, 1, SSE_INTALU_ITINS_P>;
6980   defm PMINUD   : SS48I_binop_rm<0x3B, "pminud", X86umin, v4i32, VR128,
6981                                  memopv2i64, i128mem, 1, SSE_INTALU_ITINS_P>;
6982   defm PMINUW   : SS48I_binop_rm<0x3A, "pminuw", X86umin, v8i16, VR128,
6983                                  memopv2i64, i128mem, 1, SSE_INTALU_ITINS_P>;
6984   defm PMAXSB   : SS48I_binop_rm<0x3C, "pmaxsb", X86smax, v16i8, VR128,
6985                                  memopv2i64, i128mem, 1, SSE_INTALU_ITINS_P>;
6986   defm PMAXSD   : SS48I_binop_rm<0x3D, "pmaxsd", X86smax, v4i32, VR128,
6987                                  memopv2i64, i128mem, 1, SSE_INTALU_ITINS_P>;
6988   defm PMAXUD   : SS48I_binop_rm<0x3F, "pmaxud", X86umax, v4i32, VR128,
6989                                  memopv2i64, i128mem, 1, SSE_INTALU_ITINS_P>;
6990   defm PMAXUW   : SS48I_binop_rm<0x3E, "pmaxuw", X86umax, v8i16, VR128,
6991                                  memopv2i64, i128mem, 1, SSE_INTALU_ITINS_P>;
6992   defm PMULDQ   : SS41I_binop_rm_int<0x28, "pmuldq",   int_x86_sse41_pmuldq,
6993                                      1, SSE_INTMUL_ITINS_P>;
6994 }
6995
6996 let Predicates = [HasAVX] in {
6997   defm VPMULLD  : SS48I_binop_rm<0x40, "vpmulld", mul, v4i32, VR128,
6998                                 memopv2i64, i128mem, 0>, VEX_4V;
6999   defm VPCMPEQQ : SS48I_binop_rm<0x29, "vpcmpeqq", X86pcmpeq, v2i64, VR128,
7000                                  memopv2i64, i128mem, 0>, VEX_4V;
7001 }
7002 let Predicates = [HasAVX2] in {
7003   defm VPMULLDY  : SS48I_binop_rm<0x40, "vpmulld", mul, v8i32, VR256,
7004                                   memopv4i64, i256mem, 0>, VEX_4V, VEX_L;
7005   defm VPCMPEQQY : SS48I_binop_rm<0x29, "vpcmpeqq", X86pcmpeq, v4i64, VR256,
7006                                   memopv4i64, i256mem, 0>, VEX_4V, VEX_L;
7007 }
7008
7009 let Constraints = "$src1 = $dst" in {
7010   defm PMULLD  : SS48I_binop_rm<0x40, "pmulld", mul, v4i32, VR128,
7011                                 memopv2i64, i128mem, 1, SSE_PMULLD_ITINS>;
7012   defm PCMPEQQ : SS48I_binop_rm<0x29, "pcmpeqq", X86pcmpeq, v2i64, VR128,
7013                                 memopv2i64, i128mem, 1, SSE_INTALUQ_ITINS_P>;
7014 }
7015
7016 /// SS41I_binop_rmi_int - SSE 4.1 binary operator with 8-bit immediate
7017 multiclass SS41I_binop_rmi_int<bits<8> opc, string OpcodeStr,
7018                  Intrinsic IntId, RegisterClass RC, PatFrag memop_frag,
7019                  X86MemOperand x86memop, bit Is2Addr = 1,
7020                  OpndItins itins = DEFAULT_ITINS> {
7021   let isCommutable = 1 in
7022   def rri : SS4AIi8<opc, MRMSrcReg, (outs RC:$dst),
7023         (ins RC:$src1, RC:$src2, u32u8imm:$src3),
7024         !if(Is2Addr,
7025             !strconcat(OpcodeStr,
7026                 "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
7027             !strconcat(OpcodeStr,
7028                 "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
7029         [(set RC:$dst, (IntId RC:$src1, RC:$src2, imm:$src3))], itins.rr>,
7030         OpSize;
7031   def rmi : SS4AIi8<opc, MRMSrcMem, (outs RC:$dst),
7032         (ins RC:$src1, x86memop:$src2, u32u8imm:$src3),
7033         !if(Is2Addr,
7034             !strconcat(OpcodeStr,
7035                 "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
7036             !strconcat(OpcodeStr,
7037                 "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
7038         [(set RC:$dst,
7039           (IntId RC:$src1,
7040            (bitconvert (memop_frag addr:$src2)), imm:$src3))], itins.rm>,
7041         OpSize;
7042 }
7043
7044 let Predicates = [HasAVX] in {
7045   let isCommutable = 0 in {
7046     let ExeDomain = SSEPackedSingle in {
7047     defm VBLENDPS : SS41I_binop_rmi_int<0x0C, "vblendps", int_x86_sse41_blendps,
7048                                         VR128, loadv4f32, f128mem, 0>, VEX_4V;
7049     defm VBLENDPSY : SS41I_binop_rmi_int<0x0C, "vblendps",
7050                                     int_x86_avx_blend_ps_256, VR256, loadv8f32,
7051                                     f256mem, 0>, VEX_4V, VEX_L;
7052     }
7053     let ExeDomain = SSEPackedDouble in {
7054     defm VBLENDPD : SS41I_binop_rmi_int<0x0D, "vblendpd", int_x86_sse41_blendpd,
7055                                         VR128, loadv2f64, f128mem, 0>, VEX_4V;
7056     defm VBLENDPDY : SS41I_binop_rmi_int<0x0D, "vblendpd",
7057                                      int_x86_avx_blend_pd_256,VR256, loadv4f64,
7058                                      f256mem, 0>, VEX_4V, VEX_L;
7059     }
7060   defm VPBLENDW : SS41I_binop_rmi_int<0x0E, "vpblendw", int_x86_sse41_pblendw,
7061                                       VR128, loadv2i64, i128mem, 0>, VEX_4V;
7062   defm VMPSADBW : SS41I_binop_rmi_int<0x42, "vmpsadbw", int_x86_sse41_mpsadbw,
7063                                       VR128, loadv2i64, i128mem, 0>, VEX_4V;
7064   }
7065   let ExeDomain = SSEPackedSingle in
7066   defm VDPPS : SS41I_binop_rmi_int<0x40, "vdpps", int_x86_sse41_dpps,
7067                                    VR128, loadv4f32, f128mem, 0>, VEX_4V;
7068   let ExeDomain = SSEPackedDouble in
7069   defm VDPPD : SS41I_binop_rmi_int<0x41, "vdppd", int_x86_sse41_dppd,
7070                                    VR128, loadv2f64, f128mem, 0>, VEX_4V;
7071   let ExeDomain = SSEPackedSingle in
7072   defm VDPPSY : SS41I_binop_rmi_int<0x40, "vdpps", int_x86_avx_dp_ps_256,
7073                                   VR256, loadv8f32, i256mem, 0>, VEX_4V, VEX_L;
7074 }
7075
7076 let Predicates = [HasAVX2] in {
7077   let isCommutable = 0 in {
7078   defm VPBLENDWY : SS41I_binop_rmi_int<0x0E, "vpblendw", int_x86_avx2_pblendw,
7079                                   VR256, loadv4i64, i256mem, 0>, VEX_4V, VEX_L;
7080   defm VMPSADBWY : SS41I_binop_rmi_int<0x42, "vmpsadbw", int_x86_avx2_mpsadbw,
7081                                   VR256, loadv4i64, i256mem, 0>, VEX_4V, VEX_L;
7082   }
7083 }
7084
7085 let Constraints = "$src1 = $dst" in {
7086   let isCommutable = 0 in {
7087   let ExeDomain = SSEPackedSingle in
7088   defm BLENDPS : SS41I_binop_rmi_int<0x0C, "blendps", int_x86_sse41_blendps,
7089                                      VR128, memopv4f32, f128mem,
7090                                      1, SSE_INTALU_ITINS_P>;
7091   let ExeDomain = SSEPackedDouble in
7092   defm BLENDPD : SS41I_binop_rmi_int<0x0D, "blendpd", int_x86_sse41_blendpd,
7093                                      VR128, memopv2f64, f128mem,
7094                                      1, SSE_INTALU_ITINS_P>;
7095   defm PBLENDW : SS41I_binop_rmi_int<0x0E, "pblendw", int_x86_sse41_pblendw,
7096                                      VR128, memopv2i64, i128mem,
7097                                      1, SSE_INTALU_ITINS_P>;
7098   defm MPSADBW : SS41I_binop_rmi_int<0x42, "mpsadbw", int_x86_sse41_mpsadbw,
7099                                      VR128, memopv2i64, i128mem,
7100                                      1, SSE_INTMUL_ITINS_P>;
7101   }
7102   let ExeDomain = SSEPackedSingle in
7103   defm DPPS : SS41I_binop_rmi_int<0x40, "dpps", int_x86_sse41_dpps,
7104                                   VR128, memopv4f32, f128mem, 1,
7105                                   SSE_DPPS_ITINS>;
7106   let ExeDomain = SSEPackedDouble in
7107   defm DPPD : SS41I_binop_rmi_int<0x41, "dppd", int_x86_sse41_dppd,
7108                                   VR128, memopv2f64, f128mem, 1,
7109                                   SSE_DPPD_ITINS>;
7110 }
7111
7112 /// SS41I_quaternary_int_avx - AVX SSE 4.1 with 4 operators
7113 multiclass SS41I_quaternary_int_avx<bits<8> opc, string OpcodeStr,
7114                                     RegisterClass RC, X86MemOperand x86memop,
7115                                     PatFrag mem_frag, Intrinsic IntId> {
7116   def rr : Ii8<opc, MRMSrcReg, (outs RC:$dst),
7117                   (ins RC:$src1, RC:$src2, RC:$src3),
7118                   !strconcat(OpcodeStr,
7119                     "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
7120                   [(set RC:$dst, (IntId RC:$src1, RC:$src2, RC:$src3))],
7121                   NoItinerary, SSEPackedInt>, OpSize, TA, VEX_4V, VEX_I8IMM;
7122
7123   def rm : Ii8<opc, MRMSrcMem, (outs RC:$dst),
7124                   (ins RC:$src1, x86memop:$src2, RC:$src3),
7125                   !strconcat(OpcodeStr,
7126                     "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
7127                   [(set RC:$dst,
7128                         (IntId RC:$src1, (bitconvert (mem_frag addr:$src2)),
7129                                RC:$src3))],
7130                   NoItinerary, SSEPackedInt>, OpSize, TA, VEX_4V, VEX_I8IMM;
7131 }
7132
7133 let Predicates = [HasAVX] in {
7134 let ExeDomain = SSEPackedDouble in {
7135 defm VBLENDVPD  : SS41I_quaternary_int_avx<0x4B, "vblendvpd", VR128, f128mem,
7136                                            loadv2f64, int_x86_sse41_blendvpd>;
7137 defm VBLENDVPDY : SS41I_quaternary_int_avx<0x4B, "vblendvpd", VR256, f256mem,
7138                                   loadv4f64, int_x86_avx_blendv_pd_256>, VEX_L;
7139 } // ExeDomain = SSEPackedDouble
7140 let ExeDomain = SSEPackedSingle in {
7141 defm VBLENDVPS  : SS41I_quaternary_int_avx<0x4A, "vblendvps", VR128, f128mem,
7142                                            loadv4f32, int_x86_sse41_blendvps>;
7143 defm VBLENDVPSY : SS41I_quaternary_int_avx<0x4A, "vblendvps", VR256, f256mem,
7144                                   loadv8f32, int_x86_avx_blendv_ps_256>, VEX_L;
7145 } // ExeDomain = SSEPackedSingle
7146 defm VPBLENDVB  : SS41I_quaternary_int_avx<0x4C, "vpblendvb", VR128, i128mem,
7147                                            loadv2i64, int_x86_sse41_pblendvb>;
7148 }
7149
7150 let Predicates = [HasAVX2] in {
7151 defm VPBLENDVBY : SS41I_quaternary_int_avx<0x4C, "vpblendvb", VR256, i256mem,
7152                                       loadv4i64, int_x86_avx2_pblendvb>, VEX_L;
7153 }
7154
7155 let Predicates = [HasAVX] in {
7156   def : Pat<(v16i8 (vselect (v16i8 VR128:$mask), (v16i8 VR128:$src1),
7157                             (v16i8 VR128:$src2))),
7158             (VPBLENDVBrr VR128:$src2, VR128:$src1, VR128:$mask)>;
7159   def : Pat<(v4i32 (vselect (v4i32 VR128:$mask), (v4i32 VR128:$src1),
7160                             (v4i32 VR128:$src2))),
7161             (VBLENDVPSrr VR128:$src2, VR128:$src1, VR128:$mask)>;
7162   def : Pat<(v4f32 (vselect (v4i32 VR128:$mask), (v4f32 VR128:$src1),
7163                             (v4f32 VR128:$src2))),
7164             (VBLENDVPSrr VR128:$src2, VR128:$src1, VR128:$mask)>;
7165   def : Pat<(v2i64 (vselect (v2i64 VR128:$mask), (v2i64 VR128:$src1),
7166                             (v2i64 VR128:$src2))),
7167             (VBLENDVPDrr VR128:$src2, VR128:$src1, VR128:$mask)>;
7168   def : Pat<(v2f64 (vselect (v2i64 VR128:$mask), (v2f64 VR128:$src1),
7169                             (v2f64 VR128:$src2))),
7170             (VBLENDVPDrr VR128:$src2, VR128:$src1, VR128:$mask)>;
7171   def : Pat<(v8i32 (vselect (v8i32 VR256:$mask), (v8i32 VR256:$src1),
7172                             (v8i32 VR256:$src2))),
7173             (VBLENDVPSYrr VR256:$src2, VR256:$src1, VR256:$mask)>;
7174   def : Pat<(v8f32 (vselect (v8i32 VR256:$mask), (v8f32 VR256:$src1),
7175                             (v8f32 VR256:$src2))),
7176             (VBLENDVPSYrr VR256:$src2, VR256:$src1, VR256:$mask)>;
7177   def : Pat<(v4i64 (vselect (v4i64 VR256:$mask), (v4i64 VR256:$src1),
7178                             (v4i64 VR256:$src2))),
7179             (VBLENDVPDYrr VR256:$src2, VR256:$src1, VR256:$mask)>;
7180   def : Pat<(v4f64 (vselect (v4i64 VR256:$mask), (v4f64 VR256:$src1),
7181                             (v4f64 VR256:$src2))),
7182             (VBLENDVPDYrr VR256:$src2, VR256:$src1, VR256:$mask)>;
7183
7184   def : Pat<(v8f32 (X86Blendi (v8f32 VR256:$src1), (v8f32 VR256:$src2),
7185                                (imm:$mask))),
7186             (VBLENDPSYrri VR256:$src1, VR256:$src2, imm:$mask)>;
7187   def : Pat<(v4f64 (X86Blendi (v4f64 VR256:$src1), (v4f64 VR256:$src2),
7188                                (imm:$mask))),
7189             (VBLENDPDYrri VR256:$src1, VR256:$src2, imm:$mask)>;
7190
7191   def : Pat<(v8i16 (X86Blendi (v8i16 VR128:$src1), (v8i16 VR128:$src2),
7192                                (imm:$mask))),
7193             (VPBLENDWrri VR128:$src1, VR128:$src2, imm:$mask)>;
7194   def : Pat<(v4f32 (X86Blendi (v4f32 VR128:$src1), (v4f32 VR128:$src2),
7195                                (imm:$mask))),
7196             (VBLENDPSrri VR128:$src1, VR128:$src2, imm:$mask)>;
7197   def : Pat<(v2f64 (X86Blendi (v2f64 VR128:$src1), (v2f64 VR128:$src2),
7198                                (imm:$mask))),
7199             (VBLENDPDrri VR128:$src1, VR128:$src2, imm:$mask)>;
7200 }
7201
7202 let Predicates = [HasAVX2] in {
7203   def : Pat<(v32i8 (vselect (v32i8 VR256:$mask), (v32i8 VR256:$src1),
7204                             (v32i8 VR256:$src2))),
7205             (VPBLENDVBYrr VR256:$src2, VR256:$src1, VR256:$mask)>;
7206   def : Pat<(v16i16 (X86Blendi (v16i16 VR256:$src1), (v16i16 VR256:$src2),
7207                                (imm:$mask))),
7208             (VPBLENDWYrri VR256:$src1, VR256:$src2, imm:$mask)>;
7209 }
7210
7211 /// SS41I_ternary_int - SSE 4.1 ternary operator
7212 let Uses = [XMM0], Constraints = "$src1 = $dst" in {
7213   multiclass SS41I_ternary_int<bits<8> opc, string OpcodeStr, PatFrag mem_frag,
7214                                X86MemOperand x86memop, Intrinsic IntId,
7215                                OpndItins itins = DEFAULT_ITINS> {
7216     def rr0 : SS48I<opc, MRMSrcReg, (outs VR128:$dst),
7217                     (ins VR128:$src1, VR128:$src2),
7218                     !strconcat(OpcodeStr,
7219                      "\t{$src2, $dst|$dst, $src2}"),
7220                     [(set VR128:$dst, (IntId VR128:$src1, VR128:$src2, XMM0))],
7221                     itins.rr>, OpSize;
7222
7223     def rm0 : SS48I<opc, MRMSrcMem, (outs VR128:$dst),
7224                     (ins VR128:$src1, x86memop:$src2),
7225                     !strconcat(OpcodeStr,
7226                      "\t{$src2, $dst|$dst, $src2}"),
7227                     [(set VR128:$dst,
7228                       (IntId VR128:$src1,
7229                        (bitconvert (mem_frag addr:$src2)), XMM0))],
7230                        itins.rm>, OpSize;
7231   }
7232 }
7233
7234 let ExeDomain = SSEPackedDouble in
7235 defm BLENDVPD : SS41I_ternary_int<0x15, "blendvpd", memopv2f64, f128mem,
7236                                   int_x86_sse41_blendvpd>;
7237 let ExeDomain = SSEPackedSingle in
7238 defm BLENDVPS : SS41I_ternary_int<0x14, "blendvps", memopv4f32, f128mem,
7239                                   int_x86_sse41_blendvps>;
7240 defm PBLENDVB : SS41I_ternary_int<0x10, "pblendvb", memopv2i64, i128mem,
7241                                   int_x86_sse41_pblendvb>;
7242
7243 // Aliases with the implicit xmm0 argument
7244 def : InstAlias<"blendvpd\t{%xmm0, $src2, $dst|$dst, $src2, xmm0}",
7245                 (BLENDVPDrr0 VR128:$dst, VR128:$src2)>;
7246 def : InstAlias<"blendvpd\t{%xmm0, $src2, $dst|$dst, $src2, xmm0}",
7247                 (BLENDVPDrm0 VR128:$dst, f128mem:$src2)>;
7248 def : InstAlias<"blendvps\t{%xmm0, $src2, $dst|$dst, $src2, xmm0}",
7249                 (BLENDVPSrr0 VR128:$dst, VR128:$src2)>;
7250 def : InstAlias<"blendvps\t{%xmm0, $src2, $dst|$dst, $src2, xmm0}",
7251                 (BLENDVPSrm0 VR128:$dst, f128mem:$src2)>;
7252 def : InstAlias<"pblendvb\t{%xmm0, $src2, $dst|$dst, $src2, xmm0}",
7253                 (PBLENDVBrr0 VR128:$dst, VR128:$src2)>;
7254 def : InstAlias<"pblendvb\t{%xmm0, $src2, $dst|$dst, $src2, xmm0}",
7255                 (PBLENDVBrm0 VR128:$dst, i128mem:$src2)>;
7256
7257 let Predicates = [UseSSE41] in {
7258   def : Pat<(v16i8 (vselect (v16i8 XMM0), (v16i8 VR128:$src1),
7259                             (v16i8 VR128:$src2))),
7260             (PBLENDVBrr0 VR128:$src2, VR128:$src1)>;
7261   def : Pat<(v4i32 (vselect (v4i32 XMM0), (v4i32 VR128:$src1),
7262                             (v4i32 VR128:$src2))),
7263             (BLENDVPSrr0 VR128:$src2, VR128:$src1)>;
7264   def : Pat<(v4f32 (vselect (v4i32 XMM0), (v4f32 VR128:$src1),
7265                             (v4f32 VR128:$src2))),
7266             (BLENDVPSrr0 VR128:$src2, VR128:$src1)>;
7267   def : Pat<(v2i64 (vselect (v2i64 XMM0), (v2i64 VR128:$src1),
7268                             (v2i64 VR128:$src2))),
7269             (BLENDVPDrr0 VR128:$src2, VR128:$src1)>;
7270   def : Pat<(v2f64 (vselect (v2i64 XMM0), (v2f64 VR128:$src1),
7271                             (v2f64 VR128:$src2))),
7272             (BLENDVPDrr0 VR128:$src2, VR128:$src1)>;
7273
7274   def : Pat<(v8i16 (X86Blendi (v8i16 VR128:$src1), (v8i16 VR128:$src2),
7275                                (imm:$mask))),
7276             (PBLENDWrri VR128:$src1, VR128:$src2, imm:$mask)>;
7277   def : Pat<(v4f32 (X86Blendi (v4f32 VR128:$src1), (v4f32 VR128:$src2),
7278                                (imm:$mask))),
7279             (BLENDPSrri VR128:$src1, VR128:$src2, imm:$mask)>;
7280   def : Pat<(v2f64 (X86Blendi (v2f64 VR128:$src1), (v2f64 VR128:$src2),
7281                                (imm:$mask))),
7282             (BLENDPDrri VR128:$src1, VR128:$src2, imm:$mask)>;
7283
7284 }
7285
7286 let Predicates = [HasAVX] in
7287 def VMOVNTDQArm : SS48I<0x2A, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
7288                        "vmovntdqa\t{$src, $dst|$dst, $src}",
7289                        [(set VR128:$dst, (int_x86_sse41_movntdqa addr:$src))]>,
7290                        OpSize, VEX;
7291 let Predicates = [HasAVX2] in
7292 def VMOVNTDQAYrm : SS48I<0x2A, MRMSrcMem, (outs VR256:$dst), (ins i256mem:$src),
7293                          "vmovntdqa\t{$src, $dst|$dst, $src}",
7294                          [(set VR256:$dst, (int_x86_avx2_movntdqa addr:$src))]>,
7295                          OpSize, VEX, VEX_L;
7296 def MOVNTDQArm : SS48I<0x2A, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
7297                        "movntdqa\t{$src, $dst|$dst, $src}",
7298                        [(set VR128:$dst, (int_x86_sse41_movntdqa addr:$src))]>,
7299                        OpSize;
7300
7301 //===----------------------------------------------------------------------===//
7302 // SSE4.2 - Compare Instructions
7303 //===----------------------------------------------------------------------===//
7304
7305 /// SS42I_binop_rm - Simple SSE 4.2 binary operator
7306 multiclass SS42I_binop_rm<bits<8> opc, string OpcodeStr, SDNode OpNode,
7307                           ValueType OpVT, RegisterClass RC, PatFrag memop_frag,
7308                           X86MemOperand x86memop, bit Is2Addr = 1> {
7309   def rr : SS428I<opc, MRMSrcReg, (outs RC:$dst),
7310        (ins RC:$src1, RC:$src2),
7311        !if(Is2Addr,
7312            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
7313            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
7314        [(set RC:$dst, (OpVT (OpNode RC:$src1, RC:$src2)))]>,
7315        OpSize;
7316   def rm : SS428I<opc, MRMSrcMem, (outs RC:$dst),
7317        (ins RC:$src1, x86memop:$src2),
7318        !if(Is2Addr,
7319            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
7320            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
7321        [(set RC:$dst,
7322          (OpVT (OpNode RC:$src1, (memop_frag addr:$src2))))]>, OpSize;
7323 }
7324
7325 let Predicates = [HasAVX] in
7326   defm VPCMPGTQ : SS42I_binop_rm<0x37, "vpcmpgtq", X86pcmpgt, v2i64, VR128,
7327                                  loadv2i64, i128mem, 0>, VEX_4V;
7328
7329 let Predicates = [HasAVX2] in
7330   defm VPCMPGTQY : SS42I_binop_rm<0x37, "vpcmpgtq", X86pcmpgt, v4i64, VR256,
7331                                   loadv4i64, i256mem, 0>, VEX_4V, VEX_L;
7332
7333 let Constraints = "$src1 = $dst" in
7334   defm PCMPGTQ : SS42I_binop_rm<0x37, "pcmpgtq", X86pcmpgt, v2i64, VR128,
7335                                 memopv2i64, i128mem>;
7336
7337 //===----------------------------------------------------------------------===//
7338 // SSE4.2 - String/text Processing Instructions
7339 //===----------------------------------------------------------------------===//
7340
7341 // Packed Compare Implicit Length Strings, Return Mask
7342 multiclass pseudo_pcmpistrm<string asm> {
7343   def REG : PseudoI<(outs VR128:$dst),
7344                     (ins VR128:$src1, VR128:$src2, i8imm:$src3),
7345     [(set VR128:$dst, (int_x86_sse42_pcmpistrm128 VR128:$src1, VR128:$src2,
7346                                                   imm:$src3))]>;
7347   def MEM : PseudoI<(outs VR128:$dst),
7348                     (ins VR128:$src1, i128mem:$src2, i8imm:$src3),
7349     [(set VR128:$dst, (int_x86_sse42_pcmpistrm128 VR128:$src1,
7350                        (bc_v16i8 (memopv2i64 addr:$src2)), imm:$src3))]>;
7351 }
7352
7353 let Defs = [EFLAGS], usesCustomInserter = 1 in {
7354   defm VPCMPISTRM128 : pseudo_pcmpistrm<"#VPCMPISTRM128">, Requires<[HasAVX]>;
7355   defm PCMPISTRM128 : pseudo_pcmpistrm<"#PCMPISTRM128">, Requires<[UseSSE42]>;
7356 }
7357
7358 multiclass pcmpistrm_SS42AI<string asm> {
7359   def rr : SS42AI<0x62, MRMSrcReg, (outs),
7360     (ins VR128:$src1, VR128:$src2, i8imm:$src3),
7361     !strconcat(asm, "\t{$src3, $src2, $src1|$src1, $src2, $src3}"),
7362     []>, OpSize;
7363   let mayLoad = 1 in
7364   def rm :SS42AI<0x62, MRMSrcMem, (outs),
7365     (ins VR128:$src1, i128mem:$src2, i8imm:$src3),
7366     !strconcat(asm, "\t{$src3, $src2, $src1|$src1, $src2, $src3}"),
7367     []>, OpSize;
7368 }
7369
7370 let Defs = [XMM0, EFLAGS], neverHasSideEffects = 1 in {
7371   let Predicates = [HasAVX] in
7372   defm VPCMPISTRM128 : pcmpistrm_SS42AI<"vpcmpistrm">, VEX;
7373   defm PCMPISTRM128  : pcmpistrm_SS42AI<"pcmpistrm"> ;
7374 }
7375
7376 // Packed Compare Explicit Length Strings, Return Mask
7377 multiclass pseudo_pcmpestrm<string asm> {
7378   def REG : PseudoI<(outs VR128:$dst),
7379                     (ins VR128:$src1, VR128:$src3, i8imm:$src5),
7380     [(set VR128:$dst, (int_x86_sse42_pcmpestrm128
7381                        VR128:$src1, EAX, VR128:$src3, EDX, imm:$src5))]>;
7382   def MEM : PseudoI<(outs VR128:$dst),
7383                     (ins VR128:$src1, i128mem:$src3, i8imm:$src5),
7384     [(set VR128:$dst, (int_x86_sse42_pcmpestrm128 VR128:$src1, EAX,
7385                        (bc_v16i8 (memopv2i64 addr:$src3)), EDX, imm:$src5))]>;
7386 }
7387
7388 let Defs = [EFLAGS], Uses = [EAX, EDX], usesCustomInserter = 1 in {
7389   defm VPCMPESTRM128 : pseudo_pcmpestrm<"#VPCMPESTRM128">, Requires<[HasAVX]>;
7390   defm PCMPESTRM128 : pseudo_pcmpestrm<"#PCMPESTRM128">, Requires<[UseSSE42]>;
7391 }
7392
7393 multiclass SS42AI_pcmpestrm<string asm> {
7394   def rr : SS42AI<0x60, MRMSrcReg, (outs),
7395     (ins VR128:$src1, VR128:$src3, i8imm:$src5),
7396     !strconcat(asm, "\t{$src5, $src3, $src1|$src1, $src3, $src5}"),
7397     []>, OpSize;
7398   let mayLoad = 1 in
7399   def rm : SS42AI<0x60, MRMSrcMem, (outs),
7400     (ins VR128:$src1, i128mem:$src3, i8imm:$src5),
7401     !strconcat(asm, "\t{$src5, $src3, $src1|$src1, $src3, $src5}"),
7402     []>, OpSize;
7403 }
7404
7405 let Defs = [XMM0, EFLAGS], Uses = [EAX, EDX], neverHasSideEffects = 1 in {
7406   let Predicates = [HasAVX] in
7407   defm VPCMPESTRM128 : SS42AI_pcmpestrm<"vpcmpestrm">, VEX;
7408   defm PCMPESTRM128 :  SS42AI_pcmpestrm<"pcmpestrm">;
7409 }
7410
7411 // Packed Compare Implicit Length Strings, Return Index
7412 multiclass pseudo_pcmpistri<string asm> {
7413   def REG : PseudoI<(outs GR32:$dst),
7414                     (ins VR128:$src1, VR128:$src2, i8imm:$src3),
7415     [(set GR32:$dst, EFLAGS,
7416       (X86pcmpistri VR128:$src1, VR128:$src2, imm:$src3))]>;
7417   def MEM : PseudoI<(outs GR32:$dst),
7418                     (ins VR128:$src1, i128mem:$src2, i8imm:$src3),
7419     [(set GR32:$dst, EFLAGS, (X86pcmpistri VR128:$src1,
7420                               (bc_v16i8 (memopv2i64 addr:$src2)), imm:$src3))]>;
7421 }
7422
7423 let Defs = [EFLAGS], usesCustomInserter = 1 in {
7424   defm VPCMPISTRI : pseudo_pcmpistri<"#VPCMPISTRI">, Requires<[HasAVX]>;
7425   defm PCMPISTRI  : pseudo_pcmpistri<"#PCMPISTRI">, Requires<[UseSSE42]>;
7426 }
7427
7428 multiclass SS42AI_pcmpistri<string asm> {
7429   def rr : SS42AI<0x63, MRMSrcReg, (outs),
7430     (ins VR128:$src1, VR128:$src2, i8imm:$src3),
7431     !strconcat(asm, "\t{$src3, $src2, $src1|$src1, $src2, $src3}"),
7432     []>, OpSize;
7433   let mayLoad = 1 in
7434   def rm : SS42AI<0x63, MRMSrcMem, (outs),
7435     (ins VR128:$src1, i128mem:$src2, i8imm:$src3),
7436     !strconcat(asm, "\t{$src3, $src2, $src1|$src1, $src2, $src3}"),
7437     []>, OpSize;
7438 }
7439
7440 let Defs = [ECX, EFLAGS], neverHasSideEffects = 1 in {
7441   let Predicates = [HasAVX] in
7442   defm VPCMPISTRI : SS42AI_pcmpistri<"vpcmpistri">, VEX;
7443   defm PCMPISTRI  : SS42AI_pcmpistri<"pcmpistri">;
7444 }
7445
7446 // Packed Compare Explicit Length Strings, Return Index
7447 multiclass pseudo_pcmpestri<string asm> {
7448   def REG : PseudoI<(outs GR32:$dst),
7449                     (ins VR128:$src1, VR128:$src3, i8imm:$src5),
7450     [(set GR32:$dst, EFLAGS,
7451       (X86pcmpestri VR128:$src1, EAX, VR128:$src3, EDX, imm:$src5))]>;
7452   def MEM : PseudoI<(outs GR32:$dst),
7453                     (ins VR128:$src1, i128mem:$src3, i8imm:$src5),
7454     [(set GR32:$dst, EFLAGS,
7455       (X86pcmpestri VR128:$src1, EAX, (bc_v16i8 (memopv2i64 addr:$src3)), EDX,
7456        imm:$src5))]>;
7457 }
7458
7459 let Defs = [EFLAGS], Uses = [EAX, EDX], usesCustomInserter = 1 in {
7460   defm VPCMPESTRI : pseudo_pcmpestri<"#VPCMPESTRI">, Requires<[HasAVX]>;
7461   defm PCMPESTRI  : pseudo_pcmpestri<"#PCMPESTRI">, Requires<[UseSSE42]>;
7462 }
7463
7464 multiclass SS42AI_pcmpestri<string asm> {
7465   def rr : SS42AI<0x61, MRMSrcReg, (outs),
7466     (ins VR128:$src1, VR128:$src3, i8imm:$src5),
7467     !strconcat(asm, "\t{$src5, $src3, $src1|$src1, $src3, $src5}"),
7468     []>, OpSize;
7469   let mayLoad = 1 in
7470   def rm : SS42AI<0x61, MRMSrcMem, (outs),
7471     (ins VR128:$src1, i128mem:$src3, i8imm:$src5),
7472     !strconcat(asm, "\t{$src5, $src3, $src1|$src1, $src3, $src5}"),
7473     []>, OpSize;
7474 }
7475
7476 let Defs = [ECX, EFLAGS], Uses = [EAX, EDX], neverHasSideEffects = 1 in {
7477   let Predicates = [HasAVX] in
7478   defm VPCMPESTRI : SS42AI_pcmpestri<"vpcmpestri">, VEX;
7479   defm PCMPESTRI  : SS42AI_pcmpestri<"pcmpestri">;
7480 }
7481
7482 //===----------------------------------------------------------------------===//
7483 // SSE4.2 - CRC Instructions
7484 //===----------------------------------------------------------------------===//
7485
7486 // No CRC instructions have AVX equivalents
7487
7488 // crc intrinsic instruction
7489 // This set of instructions are only rm, the only difference is the size
7490 // of r and m.
7491 class SS42I_crc32r<bits<8> opc, string asm, RegisterClass RCOut,
7492                    RegisterClass RCIn, SDPatternOperator Int> :
7493   SS42FI<opc, MRMSrcReg, (outs RCOut:$dst), (ins RCOut:$src1, RCIn:$src2),
7494          !strconcat(asm, "\t{$src2, $src1|$src1, $src2}"),
7495          [(set RCOut:$dst, (Int RCOut:$src1, RCIn:$src2))], IIC_CRC32_REG>;
7496
7497 class SS42I_crc32m<bits<8> opc, string asm, RegisterClass RCOut,
7498                    X86MemOperand x86memop, SDPatternOperator Int> :
7499   SS42FI<opc, MRMSrcMem, (outs RCOut:$dst), (ins RCOut:$src1, x86memop:$src2),
7500          !strconcat(asm, "\t{$src2, $src1|$src1, $src2}"),
7501          [(set RCOut:$dst, (Int RCOut:$src1, (load addr:$src2)))],
7502          IIC_CRC32_MEM>;
7503
7504 let Constraints = "$src1 = $dst" in {
7505   def CRC32r32m8  : SS42I_crc32m<0xF0, "crc32{b}", GR32, i8mem,
7506                                  int_x86_sse42_crc32_32_8>;
7507   def CRC32r32r8  : SS42I_crc32r<0xF0, "crc32{b}", GR32, GR8,
7508                                  int_x86_sse42_crc32_32_8>;
7509   def CRC32r32m16 : SS42I_crc32m<0xF1, "crc32{w}", GR32, i16mem,
7510                                  int_x86_sse42_crc32_32_16>, OpSize;
7511   def CRC32r32r16 : SS42I_crc32r<0xF1, "crc32{w}", GR32, GR16,
7512                                  int_x86_sse42_crc32_32_16>, OpSize;
7513   def CRC32r32m32 : SS42I_crc32m<0xF1, "crc32{l}", GR32, i32mem,
7514                                  int_x86_sse42_crc32_32_32>;
7515   def CRC32r32r32 : SS42I_crc32r<0xF1, "crc32{l}", GR32, GR32,
7516                                  int_x86_sse42_crc32_32_32>;
7517   def CRC32r64m64 : SS42I_crc32m<0xF1, "crc32{q}", GR64, i64mem,
7518                                  int_x86_sse42_crc32_64_64>, REX_W;
7519   def CRC32r64r64 : SS42I_crc32r<0xF1, "crc32{q}", GR64, GR64,
7520                                  int_x86_sse42_crc32_64_64>, REX_W;
7521   let hasSideEffects = 0 in {
7522     let mayLoad = 1 in
7523     def CRC32r64m8 : SS42I_crc32m<0xF0, "crc32{b}", GR64, i8mem,
7524                                    null_frag>, REX_W;
7525     def CRC32r64r8 : SS42I_crc32r<0xF0, "crc32{b}", GR64, GR8,
7526                                    null_frag>, REX_W;
7527   }
7528 }
7529
7530 //===----------------------------------------------------------------------===//
7531 // SHA-NI Instructions
7532 //===----------------------------------------------------------------------===//
7533
7534 multiclass SHAI_binop<bits<8> Opc, string OpcodeStr, Intrinsic IntId,
7535                       bit UsesXMM0 = 0> {
7536   def rr : I<Opc, MRMSrcReg, (outs VR128:$dst),
7537              (ins VR128:$src1, VR128:$src2),
7538              !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
7539              [!if(UsesXMM0,
7540                   (set VR128:$dst, (IntId VR128:$src1, VR128:$src2, XMM0)),
7541                   (set VR128:$dst, (IntId VR128:$src1, VR128:$src2)))]>, T8;
7542
7543   def rm : I<Opc, MRMSrcMem, (outs VR128:$dst),
7544              (ins VR128:$src1, i128mem:$src2),
7545              !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
7546              [!if(UsesXMM0,
7547                   (set VR128:$dst, (IntId VR128:$src1,
7548                     (bc_v4i32 (memopv2i64 addr:$src2)), XMM0)),
7549                   (set VR128:$dst, (IntId VR128:$src1,
7550                     (bc_v4i32 (memopv2i64 addr:$src2)))))]>, T8;
7551 }
7552
7553 let Constraints = "$src1 = $dst", Predicates = [HasSHA] in {
7554   def SHA1RNDS4rri : Ii8<0xCC, MRMSrcReg, (outs VR128:$dst),
7555                          (ins VR128:$src1, VR128:$src2, i8imm:$src3),
7556                          "sha1rnds4\t{$src3, $src2, $dst|$dst, $src2, $src3}",
7557                          [(set VR128:$dst,
7558                            (int_x86_sha1rnds4 VR128:$src1, VR128:$src2,
7559                             (i8 imm:$src3)))]>, TA;
7560   def SHA1RNDS4rmi : Ii8<0xCC, MRMSrcMem, (outs VR128:$dst),
7561                          (ins VR128:$src1, i128mem:$src2, i8imm:$src3),
7562                          "sha1rnds4\t{$src3, $src2, $dst|$dst, $src2, $src3}",
7563                          [(set VR128:$dst,
7564                            (int_x86_sha1rnds4 VR128:$src1,
7565                             (bc_v4i32 (memopv2i64 addr:$src2)),
7566                             (i8 imm:$src3)))]>, TA;
7567
7568   defm SHA1NEXTE : SHAI_binop<0xC8, "sha1nexte", int_x86_sha1nexte>;
7569   defm SHA1MSG1  : SHAI_binop<0xC9, "sha1msg1", int_x86_sha1msg1>;
7570   defm SHA1MSG2  : SHAI_binop<0xCA, "sha1msg2", int_x86_sha1msg2>;
7571
7572   let Uses=[XMM0] in
7573   defm SHA256RNDS2 : SHAI_binop<0xCB, "sha256rnds2", int_x86_sha256rnds2, 1>;
7574
7575   defm SHA256MSG1 : SHAI_binop<0xCC, "sha256msg1", int_x86_sha256msg1>;
7576   defm SHA256MSG2 : SHAI_binop<0xCD, "sha256msg2", int_x86_sha256msg2>;
7577 }
7578
7579 // Aliases with explicit %xmm0
7580 def : InstAlias<"sha256rnds2\t{%xmm0, $src2, $dst|$dst, $src2, xmm0}",
7581                 (SHA256RNDS2rr VR128:$dst, VR128:$src2)>;
7582 def : InstAlias<"sha256rnds2\t{%xmm0, $src2, $dst|$dst, $src2, xmm0}",
7583                 (SHA256RNDS2rm VR128:$dst, i128mem:$src2)>;
7584
7585 //===----------------------------------------------------------------------===//
7586 // AES-NI Instructions
7587 //===----------------------------------------------------------------------===//
7588
7589 multiclass AESI_binop_rm_int<bits<8> opc, string OpcodeStr,
7590                               Intrinsic IntId128, bit Is2Addr = 1> {
7591   def rr : AES8I<opc, MRMSrcReg, (outs VR128:$dst),
7592        (ins VR128:$src1, VR128:$src2),
7593        !if(Is2Addr,
7594            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
7595            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
7596        [(set VR128:$dst, (IntId128 VR128:$src1, VR128:$src2))]>,
7597        OpSize;
7598   def rm : AES8I<opc, MRMSrcMem, (outs VR128:$dst),
7599        (ins VR128:$src1, i128mem:$src2),
7600        !if(Is2Addr,
7601            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
7602            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
7603        [(set VR128:$dst,
7604          (IntId128 VR128:$src1, (memopv2i64 addr:$src2)))]>, OpSize;
7605 }
7606
7607 // Perform One Round of an AES Encryption/Decryption Flow
7608 let Predicates = [HasAVX, HasAES] in {
7609   defm VAESENC          : AESI_binop_rm_int<0xDC, "vaesenc",
7610                          int_x86_aesni_aesenc, 0>, VEX_4V;
7611   defm VAESENCLAST      : AESI_binop_rm_int<0xDD, "vaesenclast",
7612                          int_x86_aesni_aesenclast, 0>, VEX_4V;
7613   defm VAESDEC          : AESI_binop_rm_int<0xDE, "vaesdec",
7614                          int_x86_aesni_aesdec, 0>, VEX_4V;
7615   defm VAESDECLAST      : AESI_binop_rm_int<0xDF, "vaesdeclast",
7616                          int_x86_aesni_aesdeclast, 0>, VEX_4V;
7617 }
7618
7619 let Constraints = "$src1 = $dst" in {
7620   defm AESENC          : AESI_binop_rm_int<0xDC, "aesenc",
7621                          int_x86_aesni_aesenc>;
7622   defm AESENCLAST      : AESI_binop_rm_int<0xDD, "aesenclast",
7623                          int_x86_aesni_aesenclast>;
7624   defm AESDEC          : AESI_binop_rm_int<0xDE, "aesdec",
7625                          int_x86_aesni_aesdec>;
7626   defm AESDECLAST      : AESI_binop_rm_int<0xDF, "aesdeclast",
7627                          int_x86_aesni_aesdeclast>;
7628 }
7629
7630 // Perform the AES InvMixColumn Transformation
7631 let Predicates = [HasAVX, HasAES] in {
7632   def VAESIMCrr : AES8I<0xDB, MRMSrcReg, (outs VR128:$dst),
7633       (ins VR128:$src1),
7634       "vaesimc\t{$src1, $dst|$dst, $src1}",
7635       [(set VR128:$dst,
7636         (int_x86_aesni_aesimc VR128:$src1))]>,
7637       OpSize, VEX;
7638   def VAESIMCrm : AES8I<0xDB, MRMSrcMem, (outs VR128:$dst),
7639       (ins i128mem:$src1),
7640       "vaesimc\t{$src1, $dst|$dst, $src1}",
7641       [(set VR128:$dst, (int_x86_aesni_aesimc (loadv2i64 addr:$src1)))]>,
7642       OpSize, VEX;
7643 }
7644 def AESIMCrr : AES8I<0xDB, MRMSrcReg, (outs VR128:$dst),
7645   (ins VR128:$src1),
7646   "aesimc\t{$src1, $dst|$dst, $src1}",
7647   [(set VR128:$dst,
7648     (int_x86_aesni_aesimc VR128:$src1))]>,
7649   OpSize;
7650 def AESIMCrm : AES8I<0xDB, MRMSrcMem, (outs VR128:$dst),
7651   (ins i128mem:$src1),
7652   "aesimc\t{$src1, $dst|$dst, $src1}",
7653   [(set VR128:$dst, (int_x86_aesni_aesimc (memopv2i64 addr:$src1)))]>,
7654   OpSize;
7655
7656 // AES Round Key Generation Assist
7657 let Predicates = [HasAVX, HasAES] in {
7658   def VAESKEYGENASSIST128rr : AESAI<0xDF, MRMSrcReg, (outs VR128:$dst),
7659       (ins VR128:$src1, i8imm:$src2),
7660       "vaeskeygenassist\t{$src2, $src1, $dst|$dst, $src1, $src2}",
7661       [(set VR128:$dst,
7662         (int_x86_aesni_aeskeygenassist VR128:$src1, imm:$src2))]>,
7663       OpSize, VEX;
7664   def VAESKEYGENASSIST128rm : AESAI<0xDF, MRMSrcMem, (outs VR128:$dst),
7665       (ins i128mem:$src1, i8imm:$src2),
7666       "vaeskeygenassist\t{$src2, $src1, $dst|$dst, $src1, $src2}",
7667       [(set VR128:$dst,
7668         (int_x86_aesni_aeskeygenassist (loadv2i64 addr:$src1), imm:$src2))]>,
7669       OpSize, VEX;
7670 }
7671 def AESKEYGENASSIST128rr : AESAI<0xDF, MRMSrcReg, (outs VR128:$dst),
7672   (ins VR128:$src1, i8imm:$src2),
7673   "aeskeygenassist\t{$src2, $src1, $dst|$dst, $src1, $src2}",
7674   [(set VR128:$dst,
7675     (int_x86_aesni_aeskeygenassist VR128:$src1, imm:$src2))]>,
7676   OpSize;
7677 def AESKEYGENASSIST128rm : AESAI<0xDF, MRMSrcMem, (outs VR128:$dst),
7678   (ins i128mem:$src1, i8imm:$src2),
7679   "aeskeygenassist\t{$src2, $src1, $dst|$dst, $src1, $src2}",
7680   [(set VR128:$dst,
7681     (int_x86_aesni_aeskeygenassist (memopv2i64 addr:$src1), imm:$src2))]>,
7682   OpSize;
7683
7684 //===----------------------------------------------------------------------===//
7685 // PCLMUL Instructions
7686 //===----------------------------------------------------------------------===//
7687
7688 // AVX carry-less Multiplication instructions
7689 def VPCLMULQDQrr : AVXPCLMULIi8<0x44, MRMSrcReg, (outs VR128:$dst),
7690            (ins VR128:$src1, VR128:$src2, i8imm:$src3),
7691            "vpclmulqdq\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
7692            [(set VR128:$dst,
7693              (int_x86_pclmulqdq VR128:$src1, VR128:$src2, imm:$src3))]>;
7694
7695 def VPCLMULQDQrm : AVXPCLMULIi8<0x44, MRMSrcMem, (outs VR128:$dst),
7696            (ins VR128:$src1, i128mem:$src2, i8imm:$src3),
7697            "vpclmulqdq\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
7698            [(set VR128:$dst, (int_x86_pclmulqdq VR128:$src1,
7699                               (loadv2i64 addr:$src2), imm:$src3))]>;
7700
7701 // Carry-less Multiplication instructions
7702 let Constraints = "$src1 = $dst" in {
7703 def PCLMULQDQrr : PCLMULIi8<0x44, MRMSrcReg, (outs VR128:$dst),
7704            (ins VR128:$src1, VR128:$src2, i8imm:$src3),
7705            "pclmulqdq\t{$src3, $src2, $dst|$dst, $src2, $src3}",
7706            [(set VR128:$dst,
7707              (int_x86_pclmulqdq VR128:$src1, VR128:$src2, imm:$src3))],
7708              IIC_SSE_PCLMULQDQ_RR>;
7709
7710 def PCLMULQDQrm : PCLMULIi8<0x44, MRMSrcMem, (outs VR128:$dst),
7711            (ins VR128:$src1, i128mem:$src2, i8imm:$src3),
7712            "pclmulqdq\t{$src3, $src2, $dst|$dst, $src2, $src3}",
7713            [(set VR128:$dst, (int_x86_pclmulqdq VR128:$src1,
7714                               (memopv2i64 addr:$src2), imm:$src3))],
7715                               IIC_SSE_PCLMULQDQ_RM>;
7716 } // Constraints = "$src1 = $dst"
7717
7718
7719 multiclass pclmul_alias<string asm, int immop> {
7720   def : InstAlias<!strconcat("pclmul", asm, "dq {$src, $dst|$dst, $src}"),
7721                   (PCLMULQDQrr VR128:$dst, VR128:$src, immop)>;
7722
7723   def : InstAlias<!strconcat("pclmul", asm, "dq {$src, $dst|$dst, $src}"),
7724                   (PCLMULQDQrm VR128:$dst, i128mem:$src, immop)>;
7725
7726   def : InstAlias<!strconcat("vpclmul", asm,
7727                              "dq {$src2, $src1, $dst|$dst, $src1, $src2}"),
7728                   (VPCLMULQDQrr VR128:$dst, VR128:$src1, VR128:$src2, immop)>;
7729
7730   def : InstAlias<!strconcat("vpclmul", asm,
7731                              "dq {$src2, $src1, $dst|$dst, $src1, $src2}"),
7732                   (VPCLMULQDQrm VR128:$dst, VR128:$src1, i128mem:$src2, immop)>;
7733 }
7734 defm : pclmul_alias<"hqhq", 0x11>;
7735 defm : pclmul_alias<"hqlq", 0x01>;
7736 defm : pclmul_alias<"lqhq", 0x10>;
7737 defm : pclmul_alias<"lqlq", 0x00>;
7738
7739 //===----------------------------------------------------------------------===//
7740 // SSE4A Instructions
7741 //===----------------------------------------------------------------------===//
7742
7743 let Predicates = [HasSSE4A] in {
7744
7745 let Constraints = "$src = $dst" in {
7746 def EXTRQI : Ii8<0x78, MRM0r, (outs VR128:$dst),
7747                  (ins VR128:$src, i8imm:$len, i8imm:$idx),
7748                  "extrq\t{$idx, $len, $src|$src, $len, $idx}",
7749                  [(set VR128:$dst, (int_x86_sse4a_extrqi VR128:$src, imm:$len,
7750                                     imm:$idx))]>, TB, OpSize;
7751 def EXTRQ  : I<0x79, MRMSrcReg, (outs VR128:$dst),
7752               (ins VR128:$src, VR128:$mask),
7753               "extrq\t{$mask, $src|$src, $mask}",
7754               [(set VR128:$dst, (int_x86_sse4a_extrq VR128:$src,
7755                                  VR128:$mask))]>, TB, OpSize;
7756
7757 def INSERTQI : Ii8<0x78, MRMSrcReg, (outs VR128:$dst),
7758                    (ins VR128:$src, VR128:$src2, i8imm:$len, i8imm:$idx),
7759                    "insertq\t{$idx, $len, $src2, $src|$src, $src2, $len, $idx}",
7760                    [(set VR128:$dst, (int_x86_sse4a_insertqi VR128:$src,
7761                                       VR128:$src2, imm:$len, imm:$idx))]>, XD;
7762 def INSERTQ  : I<0x79, MRMSrcReg, (outs VR128:$dst),
7763                  (ins VR128:$src, VR128:$mask),
7764                  "insertq\t{$mask, $src|$src, $mask}",
7765                  [(set VR128:$dst, (int_x86_sse4a_insertq VR128:$src,
7766                                     VR128:$mask))]>, XD;
7767 }
7768
7769 def MOVNTSS : I<0x2B, MRMDestMem, (outs), (ins f32mem:$dst, VR128:$src),
7770                 "movntss\t{$src, $dst|$dst, $src}",
7771                 [(int_x86_sse4a_movnt_ss addr:$dst, VR128:$src)]>, XS;
7772
7773 def MOVNTSD : I<0x2B, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
7774                 "movntsd\t{$src, $dst|$dst, $src}",
7775                 [(int_x86_sse4a_movnt_sd addr:$dst, VR128:$src)]>, XD;
7776 }
7777
7778 //===----------------------------------------------------------------------===//
7779 // AVX Instructions
7780 //===----------------------------------------------------------------------===//
7781
7782 //===----------------------------------------------------------------------===//
7783 // VBROADCAST - Load from memory and broadcast to all elements of the
7784 //              destination operand
7785 //
7786 class avx_broadcast<bits<8> opc, string OpcodeStr, RegisterClass RC,
7787                     X86MemOperand x86memop, Intrinsic Int> :
7788   AVX8I<opc, MRMSrcMem, (outs RC:$dst), (ins x86memop:$src),
7789         !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
7790         [(set RC:$dst, (Int addr:$src))]>, VEX;
7791
7792 // AVX2 adds register forms
7793 class avx2_broadcast_reg<bits<8> opc, string OpcodeStr, RegisterClass RC,
7794                          Intrinsic Int> :
7795   AVX28I<opc, MRMSrcReg, (outs RC:$dst), (ins VR128:$src),
7796          !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
7797          [(set RC:$dst, (Int VR128:$src))]>, VEX;
7798
7799 let ExeDomain = SSEPackedSingle in {
7800   def VBROADCASTSSrm  : avx_broadcast<0x18, "vbroadcastss", VR128, f32mem,
7801                                       int_x86_avx_vbroadcast_ss>;
7802   def VBROADCASTSSYrm : avx_broadcast<0x18, "vbroadcastss", VR256, f32mem,
7803                                       int_x86_avx_vbroadcast_ss_256>, VEX_L;
7804 }
7805 let ExeDomain = SSEPackedDouble in
7806 def VBROADCASTSDYrm  : avx_broadcast<0x19, "vbroadcastsd", VR256, f64mem,
7807                                     int_x86_avx_vbroadcast_sd_256>, VEX_L;
7808 def VBROADCASTF128 : avx_broadcast<0x1A, "vbroadcastf128", VR256, f128mem,
7809                                    int_x86_avx_vbroadcastf128_pd_256>, VEX_L;
7810
7811 let ExeDomain = SSEPackedSingle in {
7812   def VBROADCASTSSrr  : avx2_broadcast_reg<0x18, "vbroadcastss", VR128,
7813                                            int_x86_avx2_vbroadcast_ss_ps>;
7814   def VBROADCASTSSYrr : avx2_broadcast_reg<0x18, "vbroadcastss", VR256,
7815                                       int_x86_avx2_vbroadcast_ss_ps_256>, VEX_L;
7816 }
7817 let ExeDomain = SSEPackedDouble in
7818 def VBROADCASTSDYrr  : avx2_broadcast_reg<0x19, "vbroadcastsd", VR256,
7819                                       int_x86_avx2_vbroadcast_sd_pd_256>, VEX_L;
7820
7821 let Predicates = [HasAVX2] in
7822 def VBROADCASTI128 : avx_broadcast<0x5A, "vbroadcasti128", VR256, i128mem,
7823                                    int_x86_avx2_vbroadcasti128>, VEX_L;
7824
7825 let Predicates = [HasAVX] in
7826 def : Pat<(int_x86_avx_vbroadcastf128_ps_256 addr:$src),
7827           (VBROADCASTF128 addr:$src)>;
7828
7829
7830 //===----------------------------------------------------------------------===//
7831 // VINSERTF128 - Insert packed floating-point values
7832 //
7833 let neverHasSideEffects = 1, ExeDomain = SSEPackedSingle in {
7834 def VINSERTF128rr : AVXAIi8<0x18, MRMSrcReg, (outs VR256:$dst),
7835           (ins VR256:$src1, VR128:$src2, i8imm:$src3),
7836           "vinsertf128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
7837           []>, VEX_4V, VEX_L;
7838 let mayLoad = 1 in
7839 def VINSERTF128rm : AVXAIi8<0x18, MRMSrcMem, (outs VR256:$dst),
7840           (ins VR256:$src1, f128mem:$src2, i8imm:$src3),
7841           "vinsertf128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
7842           []>, VEX_4V, VEX_L;
7843 }
7844
7845 let Predicates = [HasAVX] in {
7846 def : Pat<(vinsert128_insert:$ins (v8f32 VR256:$src1), (v4f32 VR128:$src2),
7847                                    (iPTR imm)),
7848           (VINSERTF128rr VR256:$src1, VR128:$src2,
7849                          (INSERT_get_vinsert128_imm VR256:$ins))>;
7850 def : Pat<(vinsert128_insert:$ins (v4f64 VR256:$src1), (v2f64 VR128:$src2),
7851                                    (iPTR imm)),
7852           (VINSERTF128rr VR256:$src1, VR128:$src2,
7853                          (INSERT_get_vinsert128_imm VR256:$ins))>;
7854
7855 def : Pat<(vinsert128_insert:$ins (v8f32 VR256:$src1), (loadv4f32 addr:$src2),
7856                                    (iPTR imm)),
7857           (VINSERTF128rm VR256:$src1, addr:$src2,
7858                          (INSERT_get_vinsert128_imm VR256:$ins))>;
7859 def : Pat<(vinsert128_insert:$ins (v4f64 VR256:$src1), (loadv2f64 addr:$src2),
7860                                    (iPTR imm)),
7861           (VINSERTF128rm VR256:$src1, addr:$src2,
7862                          (INSERT_get_vinsert128_imm VR256:$ins))>;
7863 }
7864
7865 let Predicates = [HasAVX1Only] in {
7866 def : Pat<(vinsert128_insert:$ins (v4i64 VR256:$src1), (v2i64 VR128:$src2),
7867                                    (iPTR imm)),
7868           (VINSERTF128rr VR256:$src1, VR128:$src2,
7869                          (INSERT_get_vinsert128_imm VR256:$ins))>;
7870 def : Pat<(vinsert128_insert:$ins (v8i32 VR256:$src1), (v4i32 VR128:$src2),
7871                                    (iPTR imm)),
7872           (VINSERTF128rr VR256:$src1, VR128:$src2,
7873                          (INSERT_get_vinsert128_imm VR256:$ins))>;
7874 def : Pat<(vinsert128_insert:$ins (v32i8 VR256:$src1), (v16i8 VR128:$src2),
7875                                    (iPTR imm)),
7876           (VINSERTF128rr VR256:$src1, VR128:$src2,
7877                          (INSERT_get_vinsert128_imm VR256:$ins))>;
7878 def : Pat<(vinsert128_insert:$ins (v16i16 VR256:$src1), (v8i16 VR128:$src2),
7879                                    (iPTR imm)),
7880           (VINSERTF128rr VR256:$src1, VR128:$src2,
7881                          (INSERT_get_vinsert128_imm VR256:$ins))>;
7882
7883 def : Pat<(vinsert128_insert:$ins (v4i64 VR256:$src1), (loadv2i64 addr:$src2),
7884                                    (iPTR imm)),
7885           (VINSERTF128rm VR256:$src1, addr:$src2,
7886                          (INSERT_get_vinsert128_imm VR256:$ins))>;
7887 def : Pat<(vinsert128_insert:$ins (v8i32 VR256:$src1),
7888                                    (bc_v4i32 (loadv2i64 addr:$src2)),
7889                                    (iPTR imm)),
7890           (VINSERTF128rm VR256:$src1, addr:$src2,
7891                          (INSERT_get_vinsert128_imm VR256:$ins))>;
7892 def : Pat<(vinsert128_insert:$ins (v32i8 VR256:$src1),
7893                                    (bc_v16i8 (loadv2i64 addr:$src2)),
7894                                    (iPTR imm)),
7895           (VINSERTF128rm VR256:$src1, addr:$src2,
7896                          (INSERT_get_vinsert128_imm VR256:$ins))>;
7897 def : Pat<(vinsert128_insert:$ins (v16i16 VR256:$src1),
7898                                    (bc_v8i16 (loadv2i64 addr:$src2)),
7899                                    (iPTR imm)),
7900           (VINSERTF128rm VR256:$src1, addr:$src2,
7901                          (INSERT_get_vinsert128_imm VR256:$ins))>;
7902 }
7903
7904 //===----------------------------------------------------------------------===//
7905 // VEXTRACTF128 - Extract packed floating-point values
7906 //
7907 let neverHasSideEffects = 1, ExeDomain = SSEPackedSingle in {
7908 def VEXTRACTF128rr : AVXAIi8<0x19, MRMDestReg, (outs VR128:$dst),
7909           (ins VR256:$src1, i8imm:$src2),
7910           "vextractf128\t{$src2, $src1, $dst|$dst, $src1, $src2}",
7911           []>, VEX, VEX_L;
7912 let mayStore = 1 in
7913 def VEXTRACTF128mr : AVXAIi8<0x19, MRMDestMem, (outs),
7914           (ins f128mem:$dst, VR256:$src1, i8imm:$src2),
7915           "vextractf128\t{$src2, $src1, $dst|$dst, $src1, $src2}",
7916           []>, VEX, VEX_L;
7917 }
7918
7919 // AVX1 patterns
7920 let Predicates = [HasAVX] in {
7921 def : Pat<(vextract128_extract:$ext VR256:$src1, (iPTR imm)),
7922           (v4f32 (VEXTRACTF128rr
7923                     (v8f32 VR256:$src1),
7924                     (EXTRACT_get_vextract128_imm VR128:$ext)))>;
7925 def : Pat<(vextract128_extract:$ext VR256:$src1, (iPTR imm)),
7926           (v2f64 (VEXTRACTF128rr
7927                     (v4f64 VR256:$src1),
7928                     (EXTRACT_get_vextract128_imm VR128:$ext)))>;
7929
7930 def : Pat<(store (v4f32 (vextract128_extract:$ext (v8f32 VR256:$src1),
7931                          (iPTR imm))), addr:$dst),
7932           (VEXTRACTF128mr addr:$dst, VR256:$src1,
7933            (EXTRACT_get_vextract128_imm VR128:$ext))>;
7934 def : Pat<(store (v2f64 (vextract128_extract:$ext (v4f64 VR256:$src1),
7935                          (iPTR imm))), addr:$dst),
7936           (VEXTRACTF128mr addr:$dst, VR256:$src1,
7937            (EXTRACT_get_vextract128_imm VR128:$ext))>;
7938 }
7939
7940 let Predicates = [HasAVX1Only] in {
7941 def : Pat<(vextract128_extract:$ext VR256:$src1, (iPTR imm)),
7942           (v2i64 (VEXTRACTF128rr
7943                   (v4i64 VR256:$src1),
7944                   (EXTRACT_get_vextract128_imm VR128:$ext)))>;
7945 def : Pat<(vextract128_extract:$ext VR256:$src1, (iPTR imm)),
7946           (v4i32 (VEXTRACTF128rr
7947                   (v8i32 VR256:$src1),
7948                   (EXTRACT_get_vextract128_imm VR128:$ext)))>;
7949 def : Pat<(vextract128_extract:$ext VR256:$src1, (iPTR imm)),
7950           (v8i16 (VEXTRACTF128rr
7951                   (v16i16 VR256:$src1),
7952                   (EXTRACT_get_vextract128_imm VR128:$ext)))>;
7953 def : Pat<(vextract128_extract:$ext VR256:$src1, (iPTR imm)),
7954           (v16i8 (VEXTRACTF128rr
7955                   (v32i8 VR256:$src1),
7956                   (EXTRACT_get_vextract128_imm VR128:$ext)))>;
7957
7958 def : Pat<(alignedstore (v2i64 (vextract128_extract:$ext (v4i64 VR256:$src1),
7959                                 (iPTR imm))), addr:$dst),
7960           (VEXTRACTF128mr addr:$dst, VR256:$src1,
7961            (EXTRACT_get_vextract128_imm VR128:$ext))>;
7962 def : Pat<(alignedstore (v4i32 (vextract128_extract:$ext (v8i32 VR256:$src1),
7963                                 (iPTR imm))), addr:$dst),
7964           (VEXTRACTF128mr addr:$dst, VR256:$src1,
7965            (EXTRACT_get_vextract128_imm VR128:$ext))>;
7966 def : Pat<(alignedstore (v8i16 (vextract128_extract:$ext (v16i16 VR256:$src1),
7967                                 (iPTR imm))), addr:$dst),
7968           (VEXTRACTF128mr addr:$dst, VR256:$src1,
7969            (EXTRACT_get_vextract128_imm VR128:$ext))>;
7970 def : Pat<(alignedstore (v16i8 (vextract128_extract:$ext (v32i8 VR256:$src1),
7971                                 (iPTR imm))), addr:$dst),
7972           (VEXTRACTF128mr addr:$dst, VR256:$src1,
7973            (EXTRACT_get_vextract128_imm VR128:$ext))>;
7974 }
7975
7976 //===----------------------------------------------------------------------===//
7977 // VMASKMOV - Conditional SIMD Packed Loads and Stores
7978 //
7979 multiclass avx_movmask_rm<bits<8> opc_rm, bits<8> opc_mr, string OpcodeStr,
7980                           Intrinsic IntLd, Intrinsic IntLd256,
7981                           Intrinsic IntSt, Intrinsic IntSt256> {
7982   def rm  : AVX8I<opc_rm, MRMSrcMem, (outs VR128:$dst),
7983              (ins VR128:$src1, f128mem:$src2),
7984              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7985              [(set VR128:$dst, (IntLd addr:$src2, VR128:$src1))]>,
7986              VEX_4V;
7987   def Yrm : AVX8I<opc_rm, MRMSrcMem, (outs VR256:$dst),
7988              (ins VR256:$src1, f256mem:$src2),
7989              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7990              [(set VR256:$dst, (IntLd256 addr:$src2, VR256:$src1))]>,
7991              VEX_4V, VEX_L;
7992   def mr  : AVX8I<opc_mr, MRMDestMem, (outs),
7993              (ins f128mem:$dst, VR128:$src1, VR128:$src2),
7994              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7995              [(IntSt addr:$dst, VR128:$src1, VR128:$src2)]>, VEX_4V;
7996   def Ymr : AVX8I<opc_mr, MRMDestMem, (outs),
7997              (ins f256mem:$dst, VR256:$src1, VR256:$src2),
7998              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7999              [(IntSt256 addr:$dst, VR256:$src1, VR256:$src2)]>, VEX_4V, VEX_L;
8000 }
8001
8002 let ExeDomain = SSEPackedSingle in
8003 defm VMASKMOVPS : avx_movmask_rm<0x2C, 0x2E, "vmaskmovps",
8004                                  int_x86_avx_maskload_ps,
8005                                  int_x86_avx_maskload_ps_256,
8006                                  int_x86_avx_maskstore_ps,
8007                                  int_x86_avx_maskstore_ps_256>;
8008 let ExeDomain = SSEPackedDouble in
8009 defm VMASKMOVPD : avx_movmask_rm<0x2D, 0x2F, "vmaskmovpd",
8010                                  int_x86_avx_maskload_pd,
8011                                  int_x86_avx_maskload_pd_256,
8012                                  int_x86_avx_maskstore_pd,
8013                                  int_x86_avx_maskstore_pd_256>;
8014
8015 //===----------------------------------------------------------------------===//
8016 // VPERMIL - Permute Single and Double Floating-Point Values
8017 //
8018 multiclass avx_permil<bits<8> opc_rm, bits<8> opc_rmi, string OpcodeStr,
8019                       RegisterClass RC, X86MemOperand x86memop_f,
8020                       X86MemOperand x86memop_i, PatFrag i_frag,
8021                       Intrinsic IntVar, ValueType vt> {
8022   def rr  : AVX8I<opc_rm, MRMSrcReg, (outs RC:$dst),
8023              (ins RC:$src1, RC:$src2),
8024              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8025              [(set RC:$dst, (IntVar RC:$src1, RC:$src2))]>, VEX_4V;
8026   def rm  : AVX8I<opc_rm, MRMSrcMem, (outs RC:$dst),
8027              (ins RC:$src1, x86memop_i:$src2),
8028              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8029              [(set RC:$dst, (IntVar RC:$src1,
8030                              (bitconvert (i_frag addr:$src2))))]>, VEX_4V;
8031
8032   def ri  : AVXAIi8<opc_rmi, MRMSrcReg, (outs RC:$dst),
8033              (ins RC:$src1, i8imm:$src2),
8034              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8035              [(set RC:$dst, (vt (X86VPermilp RC:$src1, (i8 imm:$src2))))]>, VEX;
8036   def mi  : AVXAIi8<opc_rmi, MRMSrcMem, (outs RC:$dst),
8037              (ins x86memop_f:$src1, i8imm:$src2),
8038              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8039              [(set RC:$dst,
8040                (vt (X86VPermilp (memop addr:$src1), (i8 imm:$src2))))]>, VEX;
8041 }
8042
8043 let ExeDomain = SSEPackedSingle in {
8044   defm VPERMILPS  : avx_permil<0x0C, 0x04, "vpermilps", VR128, f128mem, i128mem,
8045                                loadv2i64, int_x86_avx_vpermilvar_ps, v4f32>;
8046   defm VPERMILPSY : avx_permil<0x0C, 0x04, "vpermilps", VR256, f256mem, i256mem,
8047                        loadv4i64, int_x86_avx_vpermilvar_ps_256, v8f32>, VEX_L;
8048 }
8049 let ExeDomain = SSEPackedDouble in {
8050   defm VPERMILPD  : avx_permil<0x0D, 0x05, "vpermilpd", VR128, f128mem, i128mem,
8051                                loadv2i64, int_x86_avx_vpermilvar_pd, v2f64>;
8052   defm VPERMILPDY : avx_permil<0x0D, 0x05, "vpermilpd", VR256, f256mem, i256mem,
8053                        loadv4i64, int_x86_avx_vpermilvar_pd_256, v4f64>, VEX_L;
8054 }
8055
8056 let Predicates = [HasAVX] in {
8057 def : Pat<(v8i32 (X86VPermilp VR256:$src1, (i8 imm:$imm))),
8058           (VPERMILPSYri VR256:$src1, imm:$imm)>;
8059 def : Pat<(v4i64 (X86VPermilp VR256:$src1, (i8 imm:$imm))),
8060           (VPERMILPDYri VR256:$src1, imm:$imm)>;
8061 def : Pat<(v8i32 (X86VPermilp (bc_v8i32 (loadv4i64 addr:$src1)),
8062                                (i8 imm:$imm))),
8063           (VPERMILPSYmi addr:$src1, imm:$imm)>;
8064 def : Pat<(v4i64 (X86VPermilp (loadv4i64 addr:$src1), (i8 imm:$imm))),
8065           (VPERMILPDYmi addr:$src1, imm:$imm)>;
8066
8067 def : Pat<(v2i64 (X86VPermilp VR128:$src1, (i8 imm:$imm))),
8068           (VPERMILPDri VR128:$src1, imm:$imm)>;
8069 def : Pat<(v2i64 (X86VPermilp (loadv2i64 addr:$src1), (i8 imm:$imm))),
8070           (VPERMILPDmi addr:$src1, imm:$imm)>;
8071 }
8072
8073 //===----------------------------------------------------------------------===//
8074 // VPERM2F128 - Permute Floating-Point Values in 128-bit chunks
8075 //
8076 let ExeDomain = SSEPackedSingle in {
8077 def VPERM2F128rr : AVXAIi8<0x06, MRMSrcReg, (outs VR256:$dst),
8078           (ins VR256:$src1, VR256:$src2, i8imm:$src3),
8079           "vperm2f128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
8080           [(set VR256:$dst, (v8f32 (X86VPerm2x128 VR256:$src1, VR256:$src2,
8081                               (i8 imm:$src3))))]>, VEX_4V, VEX_L;
8082 def VPERM2F128rm : AVXAIi8<0x06, MRMSrcMem, (outs VR256:$dst),
8083           (ins VR256:$src1, f256mem:$src2, i8imm:$src3),
8084           "vperm2f128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
8085           [(set VR256:$dst, (X86VPerm2x128 VR256:$src1, (loadv8f32 addr:$src2),
8086                              (i8 imm:$src3)))]>, VEX_4V, VEX_L;
8087 }
8088
8089 let Predicates = [HasAVX] in {
8090 def : Pat<(v4f64 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
8091           (VPERM2F128rr VR256:$src1, VR256:$src2, imm:$imm)>;
8092 def : Pat<(v4f64 (X86VPerm2x128 VR256:$src1,
8093                   (loadv4f64 addr:$src2), (i8 imm:$imm))),
8094           (VPERM2F128rm VR256:$src1, addr:$src2, imm:$imm)>;
8095 }
8096
8097 let Predicates = [HasAVX1Only] in {
8098 def : Pat<(v8i32 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
8099           (VPERM2F128rr VR256:$src1, VR256:$src2, imm:$imm)>;
8100 def : Pat<(v4i64 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
8101           (VPERM2F128rr VR256:$src1, VR256:$src2, imm:$imm)>;
8102 def : Pat<(v32i8 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
8103           (VPERM2F128rr VR256:$src1, VR256:$src2, imm:$imm)>;
8104 def : Pat<(v16i16 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
8105           (VPERM2F128rr VR256:$src1, VR256:$src2, imm:$imm)>;
8106
8107 def : Pat<(v8i32 (X86VPerm2x128 VR256:$src1,
8108                   (bc_v8i32 (loadv4i64 addr:$src2)), (i8 imm:$imm))),
8109           (VPERM2F128rm VR256:$src1, addr:$src2, imm:$imm)>;
8110 def : Pat<(v4i64 (X86VPerm2x128 VR256:$src1,
8111                   (loadv4i64 addr:$src2), (i8 imm:$imm))),
8112           (VPERM2F128rm VR256:$src1, addr:$src2, imm:$imm)>;
8113 def : Pat<(v32i8 (X86VPerm2x128 VR256:$src1,
8114                   (bc_v32i8 (loadv4i64 addr:$src2)), (i8 imm:$imm))),
8115           (VPERM2F128rm VR256:$src1, addr:$src2, imm:$imm)>;
8116 def : Pat<(v16i16 (X86VPerm2x128 VR256:$src1,
8117                   (bc_v16i16 (loadv4i64 addr:$src2)), (i8 imm:$imm))),
8118           (VPERM2F128rm VR256:$src1, addr:$src2, imm:$imm)>;
8119 }
8120
8121 //===----------------------------------------------------------------------===//
8122 // VZERO - Zero YMM registers
8123 //
8124 let Defs = [YMM0, YMM1, YMM2, YMM3, YMM4, YMM5, YMM6, YMM7,
8125             YMM8, YMM9, YMM10, YMM11, YMM12, YMM13, YMM14, YMM15] in {
8126   // Zero All YMM registers
8127   def VZEROALL : I<0x77, RawFrm, (outs), (ins), "vzeroall",
8128                   [(int_x86_avx_vzeroall)]>, TB, VEX, VEX_L, Requires<[HasAVX]>;
8129
8130   // Zero Upper bits of YMM registers
8131   def VZEROUPPER : I<0x77, RawFrm, (outs), (ins), "vzeroupper",
8132                      [(int_x86_avx_vzeroupper)]>, TB, VEX, Requires<[HasAVX]>;
8133 }
8134
8135 //===----------------------------------------------------------------------===//
8136 // Half precision conversion instructions
8137 //===----------------------------------------------------------------------===//
8138 multiclass f16c_ph2ps<RegisterClass RC, X86MemOperand x86memop, Intrinsic Int> {
8139   def rr : I<0x13, MRMSrcReg, (outs RC:$dst), (ins VR128:$src),
8140              "vcvtph2ps\t{$src, $dst|$dst, $src}",
8141              [(set RC:$dst, (Int VR128:$src))]>,
8142              T8, OpSize, VEX;
8143   let neverHasSideEffects = 1, mayLoad = 1 in
8144   def rm : I<0x13, MRMSrcMem, (outs RC:$dst), (ins x86memop:$src),
8145              "vcvtph2ps\t{$src, $dst|$dst, $src}", []>, T8, OpSize, VEX;
8146 }
8147
8148 multiclass f16c_ps2ph<RegisterClass RC, X86MemOperand x86memop, Intrinsic Int> {
8149   def rr : Ii8<0x1D, MRMDestReg, (outs VR128:$dst),
8150                (ins RC:$src1, i32i8imm:$src2),
8151                "vcvtps2ph\t{$src2, $src1, $dst|$dst, $src1, $src2}",
8152                [(set VR128:$dst, (Int RC:$src1, imm:$src2))]>,
8153                TA, OpSize, VEX;
8154   let neverHasSideEffects = 1, mayStore = 1 in
8155   def mr : Ii8<0x1D, MRMDestMem, (outs),
8156                (ins x86memop:$dst, RC:$src1, i32i8imm:$src2),
8157                "vcvtps2ph\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>,
8158                TA, OpSize, VEX;
8159 }
8160
8161 let Predicates = [HasF16C] in {
8162   defm VCVTPH2PS  : f16c_ph2ps<VR128, f64mem, int_x86_vcvtph2ps_128>;
8163   defm VCVTPH2PSY : f16c_ph2ps<VR256, f128mem, int_x86_vcvtph2ps_256>, VEX_L;
8164   defm VCVTPS2PH  : f16c_ps2ph<VR128, f64mem, int_x86_vcvtps2ph_128>;
8165   defm VCVTPS2PHY : f16c_ps2ph<VR256, f128mem, int_x86_vcvtps2ph_256>, VEX_L;
8166 }
8167
8168 //===----------------------------------------------------------------------===//
8169 // AVX2 Instructions
8170 //===----------------------------------------------------------------------===//
8171
8172 /// AVX2_binop_rmi_int - AVX2 binary operator with 8-bit immediate
8173 multiclass AVX2_binop_rmi_int<bits<8> opc, string OpcodeStr,
8174                  Intrinsic IntId, RegisterClass RC, PatFrag memop_frag,
8175                  X86MemOperand x86memop> {
8176   let isCommutable = 1 in
8177   def rri : AVX2AIi8<opc, MRMSrcReg, (outs RC:$dst),
8178         (ins RC:$src1, RC:$src2, u32u8imm:$src3),
8179         !strconcat(OpcodeStr,
8180             "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
8181         [(set RC:$dst, (IntId RC:$src1, RC:$src2, imm:$src3))]>,
8182         VEX_4V;
8183   def rmi : AVX2AIi8<opc, MRMSrcMem, (outs RC:$dst),
8184         (ins RC:$src1, x86memop:$src2, u32u8imm:$src3),
8185         !strconcat(OpcodeStr,
8186             "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
8187         [(set RC:$dst,
8188           (IntId RC:$src1,
8189            (bitconvert (memop_frag addr:$src2)), imm:$src3))]>,
8190         VEX_4V;
8191 }
8192
8193 let isCommutable = 0 in {
8194 defm VPBLENDD : AVX2_binop_rmi_int<0x02, "vpblendd", int_x86_avx2_pblendd_128,
8195                                    VR128, loadv2i64, i128mem>;
8196 defm VPBLENDDY : AVX2_binop_rmi_int<0x02, "vpblendd", int_x86_avx2_pblendd_256,
8197                                     VR256, loadv4i64, i256mem>, VEX_L;
8198 }
8199
8200 def : Pat<(v4i32 (X86Blendi (v4i32 VR128:$src1), (v4i32 VR128:$src2),
8201                   imm:$mask)),
8202           (VPBLENDDrri VR128:$src1, VR128:$src2, imm:$mask)>;
8203 def : Pat<(v8i32 (X86Blendi (v8i32 VR256:$src1), (v8i32 VR256:$src2),
8204                   imm:$mask)),
8205           (VPBLENDDYrri VR256:$src1, VR256:$src2, imm:$mask)>;
8206
8207 //===----------------------------------------------------------------------===//
8208 // VPBROADCAST - Load from memory and broadcast to all elements of the
8209 //               destination operand
8210 //
8211 multiclass avx2_broadcast<bits<8> opc, string OpcodeStr,
8212                           X86MemOperand x86memop, PatFrag ld_frag,
8213                           Intrinsic Int128, Intrinsic Int256> {
8214   def rr : AVX28I<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
8215                   !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
8216                   [(set VR128:$dst, (Int128 VR128:$src))]>, VEX;
8217   def rm : AVX28I<opc, MRMSrcMem, (outs VR128:$dst), (ins x86memop:$src),
8218                   !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
8219                   [(set VR128:$dst,
8220                     (Int128 (scalar_to_vector (ld_frag addr:$src))))]>, VEX;
8221   def Yrr : AVX28I<opc, MRMSrcReg, (outs VR256:$dst), (ins VR128:$src),
8222                    !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
8223                    [(set VR256:$dst, (Int256 VR128:$src))]>, VEX, VEX_L;
8224   def Yrm : AVX28I<opc, MRMSrcMem, (outs VR256:$dst), (ins x86memop:$src),
8225                    !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
8226                    [(set VR256:$dst,
8227                     (Int256 (scalar_to_vector (ld_frag addr:$src))))]>,
8228                    VEX, VEX_L;
8229 }
8230
8231 defm VPBROADCASTB  : avx2_broadcast<0x78, "vpbroadcastb", i8mem, loadi8,
8232                                     int_x86_avx2_pbroadcastb_128,
8233                                     int_x86_avx2_pbroadcastb_256>;
8234 defm VPBROADCASTW  : avx2_broadcast<0x79, "vpbroadcastw", i16mem, loadi16,
8235                                     int_x86_avx2_pbroadcastw_128,
8236                                     int_x86_avx2_pbroadcastw_256>;
8237 defm VPBROADCASTD  : avx2_broadcast<0x58, "vpbroadcastd", i32mem, loadi32,
8238                                     int_x86_avx2_pbroadcastd_128,
8239                                     int_x86_avx2_pbroadcastd_256>;
8240 defm VPBROADCASTQ  : avx2_broadcast<0x59, "vpbroadcastq", i64mem, loadi64,
8241                                     int_x86_avx2_pbroadcastq_128,
8242                                     int_x86_avx2_pbroadcastq_256>;
8243
8244 let Predicates = [HasAVX2] in {
8245   def : Pat<(v16i8 (X86VBroadcast (loadi8 addr:$src))),
8246           (VPBROADCASTBrm addr:$src)>;
8247   def : Pat<(v32i8 (X86VBroadcast (loadi8 addr:$src))),
8248           (VPBROADCASTBYrm addr:$src)>;
8249   def : Pat<(v8i16 (X86VBroadcast (loadi16 addr:$src))),
8250           (VPBROADCASTWrm addr:$src)>;
8251   def : Pat<(v16i16 (X86VBroadcast (loadi16 addr:$src))),
8252           (VPBROADCASTWYrm addr:$src)>;
8253   def : Pat<(v4i32 (X86VBroadcast (loadi32 addr:$src))),
8254           (VPBROADCASTDrm addr:$src)>;
8255   def : Pat<(v8i32 (X86VBroadcast (loadi32 addr:$src))),
8256           (VPBROADCASTDYrm addr:$src)>;
8257   def : Pat<(v2i64 (X86VBroadcast (loadi64 addr:$src))),
8258           (VPBROADCASTQrm addr:$src)>;
8259   def : Pat<(v4i64 (X86VBroadcast (loadi64 addr:$src))),
8260           (VPBROADCASTQYrm addr:$src)>;
8261
8262   def : Pat<(v16i8 (X86VBroadcast (v16i8 VR128:$src))),
8263           (VPBROADCASTBrr VR128:$src)>;
8264   def : Pat<(v32i8 (X86VBroadcast (v16i8 VR128:$src))),
8265           (VPBROADCASTBYrr VR128:$src)>;
8266   def : Pat<(v8i16 (X86VBroadcast (v8i16 VR128:$src))),
8267           (VPBROADCASTWrr VR128:$src)>;
8268   def : Pat<(v16i16 (X86VBroadcast (v8i16 VR128:$src))),
8269           (VPBROADCASTWYrr VR128:$src)>;
8270   def : Pat<(v4i32 (X86VBroadcast (v4i32 VR128:$src))),
8271           (VPBROADCASTDrr VR128:$src)>;
8272   def : Pat<(v8i32 (X86VBroadcast (v4i32 VR128:$src))),
8273           (VPBROADCASTDYrr VR128:$src)>;
8274   def : Pat<(v2i64 (X86VBroadcast (v2i64 VR128:$src))),
8275           (VPBROADCASTQrr VR128:$src)>;
8276   def : Pat<(v4i64 (X86VBroadcast (v2i64 VR128:$src))),
8277           (VPBROADCASTQYrr VR128:$src)>;
8278   def : Pat<(v4f32 (X86VBroadcast (v4f32 VR128:$src))),
8279           (VBROADCASTSSrr VR128:$src)>;
8280   def : Pat<(v8f32 (X86VBroadcast (v4f32 VR128:$src))),
8281           (VBROADCASTSSYrr VR128:$src)>;
8282   def : Pat<(v2f64 (X86VBroadcast (v2f64 VR128:$src))),
8283           (VPBROADCASTQrr VR128:$src)>;
8284   def : Pat<(v4f64 (X86VBroadcast (v2f64 VR128:$src))),
8285           (VBROADCASTSDYrr VR128:$src)>;
8286
8287   // Provide fallback in case the load node that is used in the patterns above
8288   // is used by additional users, which prevents the pattern selection.
8289   let AddedComplexity = 20 in {
8290     def : Pat<(v4f32 (X86VBroadcast FR32:$src)),
8291               (VBROADCASTSSrr (COPY_TO_REGCLASS FR32:$src, VR128))>;
8292     def : Pat<(v8f32 (X86VBroadcast FR32:$src)),
8293               (VBROADCASTSSYrr (COPY_TO_REGCLASS FR32:$src, VR128))>;
8294     def : Pat<(v4f64 (X86VBroadcast FR64:$src)),
8295               (VBROADCASTSDYrr (COPY_TO_REGCLASS FR64:$src, VR128))>;
8296
8297     def : Pat<(v4i32 (X86VBroadcast GR32:$src)),
8298               (VBROADCASTSSrr (COPY_TO_REGCLASS GR32:$src, VR128))>;
8299     def : Pat<(v8i32 (X86VBroadcast GR32:$src)),
8300               (VBROADCASTSSYrr (COPY_TO_REGCLASS GR32:$src, VR128))>;
8301     def : Pat<(v4i64 (X86VBroadcast GR64:$src)),
8302               (VBROADCASTSDYrr (COPY_TO_REGCLASS GR64:$src, VR128))>;
8303   }
8304 }
8305
8306 // AVX1 broadcast patterns
8307 let Predicates = [HasAVX1Only] in {
8308 def : Pat<(v8i32 (X86VBroadcast (loadi32 addr:$src))),
8309           (VBROADCASTSSYrm addr:$src)>;
8310 def : Pat<(v4i64 (X86VBroadcast (loadi64 addr:$src))),
8311           (VBROADCASTSDYrm addr:$src)>;
8312 def : Pat<(v4i32 (X86VBroadcast (loadi32 addr:$src))),
8313           (VBROADCASTSSrm addr:$src)>;
8314 }
8315
8316 let Predicates = [HasAVX] in {
8317 def : Pat<(v8f32 (X86VBroadcast (loadf32 addr:$src))),
8318           (VBROADCASTSSYrm addr:$src)>;
8319 def : Pat<(v4f64 (X86VBroadcast (loadf64 addr:$src))),
8320           (VBROADCASTSDYrm addr:$src)>;
8321 def : Pat<(v4f32 (X86VBroadcast (loadf32 addr:$src))),
8322           (VBROADCASTSSrm addr:$src)>;
8323
8324   // Provide fallback in case the load node that is used in the patterns above
8325   // is used by additional users, which prevents the pattern selection.
8326   let AddedComplexity = 20 in {
8327   // 128bit broadcasts:
8328   def : Pat<(v4f32 (X86VBroadcast FR32:$src)),
8329             (VPSHUFDri (COPY_TO_REGCLASS FR32:$src, VR128), 0)>;
8330   def : Pat<(v8f32 (X86VBroadcast FR32:$src)),
8331             (VINSERTF128rr (INSERT_SUBREG (v8f32 (IMPLICIT_DEF)),
8332               (VPSHUFDri (COPY_TO_REGCLASS FR32:$src, VR128), 0), sub_xmm),
8333               (VPSHUFDri (COPY_TO_REGCLASS FR32:$src, VR128), 0), 1)>;
8334   def : Pat<(v4f64 (X86VBroadcast FR64:$src)),
8335             (VINSERTF128rr (INSERT_SUBREG (v4f64 (IMPLICIT_DEF)),
8336               (VPSHUFDri (COPY_TO_REGCLASS FR64:$src, VR128), 0x44), sub_xmm),
8337               (VPSHUFDri (COPY_TO_REGCLASS FR64:$src, VR128), 0x44), 1)>;
8338
8339   def : Pat<(v4i32 (X86VBroadcast GR32:$src)),
8340             (VPSHUFDri (COPY_TO_REGCLASS GR32:$src, VR128), 0)>;
8341   def : Pat<(v8i32 (X86VBroadcast GR32:$src)),
8342             (VINSERTF128rr (INSERT_SUBREG (v8i32 (IMPLICIT_DEF)),
8343               (VPSHUFDri (COPY_TO_REGCLASS GR32:$src, VR128), 0), sub_xmm),
8344               (VPSHUFDri (COPY_TO_REGCLASS GR32:$src, VR128), 0), 1)>;
8345   def : Pat<(v4i64 (X86VBroadcast GR64:$src)),
8346             (VINSERTF128rr (INSERT_SUBREG (v4i64 (IMPLICIT_DEF)),
8347               (VPSHUFDri (COPY_TO_REGCLASS GR64:$src, VR128), 0x44), sub_xmm),
8348               (VPSHUFDri (COPY_TO_REGCLASS GR64:$src, VR128), 0x44), 1)>;
8349   }
8350 }
8351
8352 //===----------------------------------------------------------------------===//
8353 // VPERM - Permute instructions
8354 //
8355
8356 multiclass avx2_perm<bits<8> opc, string OpcodeStr, PatFrag mem_frag,
8357                      ValueType OpVT> {
8358   def Yrr : AVX28I<opc, MRMSrcReg, (outs VR256:$dst),
8359                    (ins VR256:$src1, VR256:$src2),
8360                    !strconcat(OpcodeStr,
8361                        "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8362                    [(set VR256:$dst,
8363                      (OpVT (X86VPermv VR256:$src1, VR256:$src2)))]>,
8364                    VEX_4V, VEX_L;
8365   def Yrm : AVX28I<opc, MRMSrcMem, (outs VR256:$dst),
8366                    (ins VR256:$src1, i256mem:$src2),
8367                    !strconcat(OpcodeStr,
8368                        "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8369                    [(set VR256:$dst,
8370                      (OpVT (X86VPermv VR256:$src1,
8371                             (bitconvert (mem_frag addr:$src2)))))]>,
8372                    VEX_4V, VEX_L;
8373 }
8374
8375 defm VPERMD : avx2_perm<0x36, "vpermd", loadv4i64, v8i32>;
8376 let ExeDomain = SSEPackedSingle in
8377 defm VPERMPS : avx2_perm<0x16, "vpermps", loadv8f32, v8f32>;
8378
8379 multiclass avx2_perm_imm<bits<8> opc, string OpcodeStr, PatFrag mem_frag,
8380                          ValueType OpVT> {
8381   def Yri : AVX2AIi8<opc, MRMSrcReg, (outs VR256:$dst),
8382                      (ins VR256:$src1, i8imm:$src2),
8383                      !strconcat(OpcodeStr,
8384                          "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8385                      [(set VR256:$dst,
8386                        (OpVT (X86VPermi VR256:$src1, (i8 imm:$src2))))]>,
8387                      VEX, VEX_L;
8388   def Ymi : AVX2AIi8<opc, MRMSrcMem, (outs VR256:$dst),
8389                      (ins i256mem:$src1, i8imm:$src2),
8390                      !strconcat(OpcodeStr,
8391                          "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8392                      [(set VR256:$dst,
8393                        (OpVT (X86VPermi (mem_frag addr:$src1),
8394                               (i8 imm:$src2))))]>, VEX, VEX_L;
8395 }
8396
8397 defm VPERMQ : avx2_perm_imm<0x00, "vpermq", loadv4i64, v4i64>, VEX_W;
8398 let ExeDomain = SSEPackedDouble in
8399 defm VPERMPD : avx2_perm_imm<0x01, "vpermpd", loadv4f64, v4f64>, VEX_W;
8400
8401 //===----------------------------------------------------------------------===//
8402 // VPERM2I128 - Permute Floating-Point Values in 128-bit chunks
8403 //
8404 def VPERM2I128rr : AVX2AIi8<0x46, MRMSrcReg, (outs VR256:$dst),
8405           (ins VR256:$src1, VR256:$src2, i8imm:$src3),
8406           "vperm2i128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
8407           [(set VR256:$dst, (v4i64 (X86VPerm2x128 VR256:$src1, VR256:$src2,
8408                             (i8 imm:$src3))))]>, VEX_4V, VEX_L;
8409 def VPERM2I128rm : AVX2AIi8<0x46, MRMSrcMem, (outs VR256:$dst),
8410           (ins VR256:$src1, f256mem:$src2, i8imm:$src3),
8411           "vperm2i128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
8412           [(set VR256:$dst, (X86VPerm2x128 VR256:$src1, (loadv4i64 addr:$src2),
8413                              (i8 imm:$src3)))]>, VEX_4V, VEX_L;
8414
8415 let Predicates = [HasAVX2] in {
8416 def : Pat<(v8i32 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
8417           (VPERM2I128rr VR256:$src1, VR256:$src2, imm:$imm)>;
8418 def : Pat<(v32i8 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
8419           (VPERM2I128rr VR256:$src1, VR256:$src2, imm:$imm)>;
8420 def : Pat<(v16i16 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
8421           (VPERM2I128rr VR256:$src1, VR256:$src2, imm:$imm)>;
8422
8423 def : Pat<(v32i8 (X86VPerm2x128 VR256:$src1, (bc_v32i8 (loadv4i64 addr:$src2)),
8424                   (i8 imm:$imm))),
8425           (VPERM2I128rm VR256:$src1, addr:$src2, imm:$imm)>;
8426 def : Pat<(v16i16 (X86VPerm2x128 VR256:$src1,
8427                    (bc_v16i16 (loadv4i64 addr:$src2)), (i8 imm:$imm))),
8428           (VPERM2I128rm VR256:$src1, addr:$src2, imm:$imm)>;
8429 def : Pat<(v8i32 (X86VPerm2x128 VR256:$src1, (bc_v8i32 (loadv4i64 addr:$src2)),
8430                   (i8 imm:$imm))),
8431           (VPERM2I128rm VR256:$src1, addr:$src2, imm:$imm)>;
8432 }
8433
8434
8435 //===----------------------------------------------------------------------===//
8436 // VINSERTI128 - Insert packed integer values
8437 //
8438 let neverHasSideEffects = 1 in {
8439 def VINSERTI128rr : AVX2AIi8<0x38, MRMSrcReg, (outs VR256:$dst),
8440           (ins VR256:$src1, VR128:$src2, i8imm:$src3),
8441           "vinserti128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
8442           []>, VEX_4V, VEX_L;
8443 let mayLoad = 1 in
8444 def VINSERTI128rm : AVX2AIi8<0x38, MRMSrcMem, (outs VR256:$dst),
8445           (ins VR256:$src1, i128mem:$src2, i8imm:$src3),
8446           "vinserti128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
8447           []>, VEX_4V, VEX_L;
8448 }
8449
8450 let Predicates = [HasAVX2] in {
8451 def : Pat<(vinsert128_insert:$ins (v4i64 VR256:$src1), (v2i64 VR128:$src2),
8452                                    (iPTR imm)),
8453           (VINSERTI128rr VR256:$src1, VR128:$src2,
8454                          (INSERT_get_vinsert128_imm VR256:$ins))>;
8455 def : Pat<(vinsert128_insert:$ins (v8i32 VR256:$src1), (v4i32 VR128:$src2),
8456                                    (iPTR imm)),
8457           (VINSERTI128rr VR256:$src1, VR128:$src2,
8458                          (INSERT_get_vinsert128_imm VR256:$ins))>;
8459 def : Pat<(vinsert128_insert:$ins (v32i8 VR256:$src1), (v16i8 VR128:$src2),
8460                                    (iPTR imm)),
8461           (VINSERTI128rr VR256:$src1, VR128:$src2,
8462                          (INSERT_get_vinsert128_imm VR256:$ins))>;
8463 def : Pat<(vinsert128_insert:$ins (v16i16 VR256:$src1), (v8i16 VR128:$src2),
8464                                    (iPTR imm)),
8465           (VINSERTI128rr VR256:$src1, VR128:$src2,
8466                          (INSERT_get_vinsert128_imm VR256:$ins))>;
8467
8468 def : Pat<(vinsert128_insert:$ins (v4i64 VR256:$src1), (loadv2i64 addr:$src2),
8469                                    (iPTR imm)),
8470           (VINSERTI128rm VR256:$src1, addr:$src2,
8471                          (INSERT_get_vinsert128_imm VR256:$ins))>;
8472 def : Pat<(vinsert128_insert:$ins (v8i32 VR256:$src1),
8473                                    (bc_v4i32 (loadv2i64 addr:$src2)),
8474                                    (iPTR imm)),
8475           (VINSERTI128rm VR256:$src1, addr:$src2,
8476                          (INSERT_get_vinsert128_imm VR256:$ins))>;
8477 def : Pat<(vinsert128_insert:$ins (v32i8 VR256:$src1),
8478                                    (bc_v16i8 (loadv2i64 addr:$src2)),
8479                                    (iPTR imm)),
8480           (VINSERTI128rm VR256:$src1, addr:$src2,
8481                          (INSERT_get_vinsert128_imm VR256:$ins))>;
8482 def : Pat<(vinsert128_insert:$ins (v16i16 VR256:$src1),
8483                                    (bc_v8i16 (loadv2i64 addr:$src2)),
8484                                    (iPTR imm)),
8485           (VINSERTI128rm VR256:$src1, addr:$src2,
8486                          (INSERT_get_vinsert128_imm VR256:$ins))>;
8487 }
8488
8489 //===----------------------------------------------------------------------===//
8490 // VEXTRACTI128 - Extract packed integer values
8491 //
8492 def VEXTRACTI128rr : AVX2AIi8<0x39, MRMDestReg, (outs VR128:$dst),
8493           (ins VR256:$src1, i8imm:$src2),
8494           "vextracti128\t{$src2, $src1, $dst|$dst, $src1, $src2}",
8495           [(set VR128:$dst,
8496             (int_x86_avx2_vextracti128 VR256:$src1, imm:$src2))]>,
8497           VEX, VEX_L;
8498 let neverHasSideEffects = 1, mayStore = 1 in
8499 def VEXTRACTI128mr : AVX2AIi8<0x39, MRMDestMem, (outs),
8500           (ins i128mem:$dst, VR256:$src1, i8imm:$src2),
8501           "vextracti128\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>,
8502           VEX, VEX_L;
8503
8504 let Predicates = [HasAVX2] in {
8505 def : Pat<(vextract128_extract:$ext VR256:$src1, (iPTR imm)),
8506           (v2i64 (VEXTRACTI128rr
8507                     (v4i64 VR256:$src1),
8508                     (EXTRACT_get_vextract128_imm VR128:$ext)))>;
8509 def : Pat<(vextract128_extract:$ext VR256:$src1, (iPTR imm)),
8510           (v4i32 (VEXTRACTI128rr
8511                     (v8i32 VR256:$src1),
8512                     (EXTRACT_get_vextract128_imm VR128:$ext)))>;
8513 def : Pat<(vextract128_extract:$ext VR256:$src1, (iPTR imm)),
8514           (v8i16 (VEXTRACTI128rr
8515                     (v16i16 VR256:$src1),
8516                     (EXTRACT_get_vextract128_imm VR128:$ext)))>;
8517 def : Pat<(vextract128_extract:$ext VR256:$src1, (iPTR imm)),
8518           (v16i8 (VEXTRACTI128rr
8519                     (v32i8 VR256:$src1),
8520                     (EXTRACT_get_vextract128_imm VR128:$ext)))>;
8521
8522 def : Pat<(store (v2i64 (vextract128_extract:$ext (v4i64 VR256:$src1),
8523                          (iPTR imm))), addr:$dst),
8524           (VEXTRACTI128mr addr:$dst, VR256:$src1,
8525            (EXTRACT_get_vextract128_imm VR128:$ext))>;
8526 def : Pat<(store (v4i32 (vextract128_extract:$ext (v8i32 VR256:$src1),
8527                          (iPTR imm))), addr:$dst),
8528           (VEXTRACTI128mr addr:$dst, VR256:$src1,
8529            (EXTRACT_get_vextract128_imm VR128:$ext))>;
8530 def : Pat<(store (v8i16 (vextract128_extract:$ext (v16i16 VR256:$src1),
8531                          (iPTR imm))), addr:$dst),
8532           (VEXTRACTI128mr addr:$dst, VR256:$src1,
8533            (EXTRACT_get_vextract128_imm VR128:$ext))>;
8534 def : Pat<(store (v16i8 (vextract128_extract:$ext (v32i8 VR256:$src1),
8535                          (iPTR imm))), addr:$dst),
8536           (VEXTRACTI128mr addr:$dst, VR256:$src1,
8537            (EXTRACT_get_vextract128_imm VR128:$ext))>;
8538 }
8539
8540 //===----------------------------------------------------------------------===//
8541 // VPMASKMOV - Conditional SIMD Integer Packed Loads and Stores
8542 //
8543 multiclass avx2_pmovmask<string OpcodeStr,
8544                          Intrinsic IntLd128, Intrinsic IntLd256,
8545                          Intrinsic IntSt128, Intrinsic IntSt256> {
8546   def rm  : AVX28I<0x8c, MRMSrcMem, (outs VR128:$dst),
8547              (ins VR128:$src1, i128mem:$src2),
8548              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8549              [(set VR128:$dst, (IntLd128 addr:$src2, VR128:$src1))]>, VEX_4V;
8550   def Yrm : AVX28I<0x8c, MRMSrcMem, (outs VR256:$dst),
8551              (ins VR256:$src1, i256mem:$src2),
8552              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8553              [(set VR256:$dst, (IntLd256 addr:$src2, VR256:$src1))]>,
8554              VEX_4V, VEX_L;
8555   def mr  : AVX28I<0x8e, MRMDestMem, (outs),
8556              (ins i128mem:$dst, VR128:$src1, VR128:$src2),
8557              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8558              [(IntSt128 addr:$dst, VR128:$src1, VR128:$src2)]>, VEX_4V;
8559   def Ymr : AVX28I<0x8e, MRMDestMem, (outs),
8560              (ins i256mem:$dst, VR256:$src1, VR256:$src2),
8561              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8562              [(IntSt256 addr:$dst, VR256:$src1, VR256:$src2)]>, VEX_4V, VEX_L;
8563 }
8564
8565 defm VPMASKMOVD : avx2_pmovmask<"vpmaskmovd",
8566                                 int_x86_avx2_maskload_d,
8567                                 int_x86_avx2_maskload_d_256,
8568                                 int_x86_avx2_maskstore_d,
8569                                 int_x86_avx2_maskstore_d_256>;
8570 defm VPMASKMOVQ : avx2_pmovmask<"vpmaskmovq",
8571                                 int_x86_avx2_maskload_q,
8572                                 int_x86_avx2_maskload_q_256,
8573                                 int_x86_avx2_maskstore_q,
8574                                 int_x86_avx2_maskstore_q_256>, VEX_W;
8575
8576
8577 //===----------------------------------------------------------------------===//
8578 // Variable Bit Shifts
8579 //
8580 multiclass avx2_var_shift<bits<8> opc, string OpcodeStr, SDNode OpNode,
8581                           ValueType vt128, ValueType vt256> {
8582   def rr  : AVX28I<opc, MRMSrcReg, (outs VR128:$dst),
8583              (ins VR128:$src1, VR128:$src2),
8584              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8585              [(set VR128:$dst,
8586                (vt128 (OpNode VR128:$src1, (vt128 VR128:$src2))))]>,
8587              VEX_4V;
8588   def rm  : AVX28I<opc, MRMSrcMem, (outs VR128:$dst),
8589              (ins VR128:$src1, i128mem:$src2),
8590              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8591              [(set VR128:$dst,
8592                (vt128 (OpNode VR128:$src1,
8593                        (vt128 (bitconvert (loadv2i64 addr:$src2))))))]>,
8594              VEX_4V;
8595   def Yrr : AVX28I<opc, MRMSrcReg, (outs VR256:$dst),
8596              (ins VR256:$src1, VR256:$src2),
8597              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8598              [(set VR256:$dst,
8599                (vt256 (OpNode VR256:$src1, (vt256 VR256:$src2))))]>,
8600              VEX_4V, VEX_L;
8601   def Yrm : AVX28I<opc, MRMSrcMem, (outs VR256:$dst),
8602              (ins VR256:$src1, i256mem:$src2),
8603              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8604              [(set VR256:$dst,
8605                (vt256 (OpNode VR256:$src1,
8606                        (vt256 (bitconvert (loadv4i64 addr:$src2))))))]>,
8607              VEX_4V, VEX_L;
8608 }
8609
8610 defm VPSLLVD : avx2_var_shift<0x47, "vpsllvd", shl, v4i32, v8i32>;
8611 defm VPSLLVQ : avx2_var_shift<0x47, "vpsllvq", shl, v2i64, v4i64>, VEX_W;
8612 defm VPSRLVD : avx2_var_shift<0x45, "vpsrlvd", srl, v4i32, v8i32>;
8613 defm VPSRLVQ : avx2_var_shift<0x45, "vpsrlvq", srl, v2i64, v4i64>, VEX_W;
8614 defm VPSRAVD : avx2_var_shift<0x46, "vpsravd", sra, v4i32, v8i32>;
8615
8616 //===----------------------------------------------------------------------===//
8617 // VGATHER - GATHER Operations
8618 multiclass avx2_gather<bits<8> opc, string OpcodeStr, RegisterClass RC256,
8619                        X86MemOperand memop128, X86MemOperand memop256> {
8620   def rm  : AVX28I<opc, MRMSrcMem, (outs VR128:$dst, VR128:$mask_wb),
8621             (ins VR128:$src1, memop128:$src2, VR128:$mask),
8622             !strconcat(OpcodeStr,
8623               "\t{$mask, $src2, $dst|$dst, $src2, $mask}"),
8624             []>, VEX_4VOp3;
8625   def Yrm : AVX28I<opc, MRMSrcMem, (outs RC256:$dst, RC256:$mask_wb),
8626             (ins RC256:$src1, memop256:$src2, RC256:$mask),
8627             !strconcat(OpcodeStr,
8628               "\t{$mask, $src2, $dst|$dst, $src2, $mask}"),
8629             []>, VEX_4VOp3, VEX_L;
8630 }
8631
8632 let mayLoad = 1, Constraints
8633   = "@earlyclobber $dst,@earlyclobber $mask_wb, $src1 = $dst, $mask = $mask_wb"
8634   in {
8635   defm VGATHERDPD : avx2_gather<0x92, "vgatherdpd", VR256, vx64mem, vx64mem>, VEX_W;
8636   defm VGATHERQPD : avx2_gather<0x93, "vgatherqpd", VR256, vx64mem, vy64mem>, VEX_W;
8637   defm VGATHERDPS : avx2_gather<0x92, "vgatherdps", VR256, vx32mem, vy32mem>;
8638   defm VGATHERQPS : avx2_gather<0x93, "vgatherqps", VR128, vx32mem, vy32mem>;
8639   defm VPGATHERDQ : avx2_gather<0x90, "vpgatherdq", VR256, vx64mem, vx64mem>, VEX_W;
8640   defm VPGATHERQQ : avx2_gather<0x91, "vpgatherqq", VR256, vx64mem, vy64mem>, VEX_W;
8641   defm VPGATHERDD : avx2_gather<0x90, "vpgatherdd", VR256, vx32mem, vy32mem>;
8642   defm VPGATHERQD : avx2_gather<0x91, "vpgatherqd", VR128, vx32mem, vy32mem>;
8643 }