Remove pattern fragments for v32i8, v16i16, v8i32, v16i8, v8i16, and v4i32 loads...
[oota-llvm.git] / lib / Target / X86 / X86InstrSSE.td
1 //====- X86InstrSSE.td - Describe the X86 Instruction Set --*- tablegen -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file describes the X86 SSE instruction set, defining the instructions,
11 // and properties of the instructions which are needed for code generation,
12 // machine code emission, and analysis.
13 //
14 //===----------------------------------------------------------------------===//
15
16
17 //===----------------------------------------------------------------------===//
18 // SSE 1 & 2 Instructions Classes
19 //===----------------------------------------------------------------------===//
20
21 /// sse12_fp_scalar - SSE 1 & 2 scalar instructions class
22 multiclass sse12_fp_scalar<bits<8> opc, string OpcodeStr, SDNode OpNode,
23                            RegisterClass RC, X86MemOperand x86memop,
24                            bit Is2Addr = 1> {
25   let isCommutable = 1 in {
26     def rr : SI<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
27        !if(Is2Addr,
28            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
29            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
30        [(set RC:$dst, (OpNode RC:$src1, RC:$src2))]>;
31   }
32   def rm : SI<opc, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
33        !if(Is2Addr,
34            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
35            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
36        [(set RC:$dst, (OpNode RC:$src1, (load addr:$src2)))]>;
37 }
38
39 /// sse12_fp_scalar_int - SSE 1 & 2 scalar instructions intrinsics class
40 multiclass sse12_fp_scalar_int<bits<8> opc, string OpcodeStr, RegisterClass RC,
41                              string asm, string SSEVer, string FPSizeStr,
42                              Operand memopr, ComplexPattern mem_cpat,
43                              bit Is2Addr = 1> {
44   def rr_Int : SI<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
45        !if(Is2Addr,
46            !strconcat(asm, "\t{$src2, $dst|$dst, $src2}"),
47            !strconcat(asm, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
48        [(set RC:$dst, (!cast<Intrinsic>(
49                  !strconcat("int_x86_sse", SSEVer, "_", OpcodeStr, FPSizeStr))
50              RC:$src1, RC:$src2))]>;
51   def rm_Int : SI<opc, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, memopr:$src2),
52        !if(Is2Addr,
53            !strconcat(asm, "\t{$src2, $dst|$dst, $src2}"),
54            !strconcat(asm, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
55        [(set RC:$dst, (!cast<Intrinsic>(!strconcat("int_x86_sse",
56                                           SSEVer, "_", OpcodeStr, FPSizeStr))
57              RC:$src1, mem_cpat:$src2))]>;
58 }
59
60 /// sse12_fp_packed - SSE 1 & 2 packed instructions class
61 multiclass sse12_fp_packed<bits<8> opc, string OpcodeStr, SDNode OpNode,
62                            RegisterClass RC, ValueType vt,
63                            X86MemOperand x86memop, PatFrag mem_frag,
64                            Domain d, bit Is2Addr = 1> {
65   let isCommutable = 1 in
66     def rr : PI<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
67        !if(Is2Addr,
68            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
69            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
70        [(set RC:$dst, (vt (OpNode RC:$src1, RC:$src2)))], d>;
71   let mayLoad = 1 in
72     def rm : PI<opc, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
73        !if(Is2Addr,
74            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
75            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
76        [(set RC:$dst, (OpNode RC:$src1, (mem_frag addr:$src2)))], d>;
77 }
78
79 /// sse12_fp_packed_logical_rm - SSE 1 & 2 packed instructions class
80 multiclass sse12_fp_packed_logical_rm<bits<8> opc, RegisterClass RC, Domain d,
81                                       string OpcodeStr, X86MemOperand x86memop,
82                                       list<dag> pat_rr, list<dag> pat_rm,
83                                       bit Is2Addr = 1,
84                                       bit rr_hasSideEffects = 0> {
85   let isCommutable = 1, neverHasSideEffects = rr_hasSideEffects in
86     def rr : PI<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
87        !if(Is2Addr,
88            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
89            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
90        pat_rr, d>;
91   def rm : PI<opc, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
92        !if(Is2Addr,
93            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
94            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
95        pat_rm, d>;
96 }
97
98 /// sse12_fp_packed_int - SSE 1 & 2 packed instructions intrinsics class
99 multiclass sse12_fp_packed_int<bits<8> opc, string OpcodeStr, RegisterClass RC,
100                            string asm, string SSEVer, string FPSizeStr,
101                            X86MemOperand x86memop, PatFrag mem_frag,
102                            Domain d, bit Is2Addr = 1> {
103   def rr_Int : PI<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
104        !if(Is2Addr,
105            !strconcat(asm, "\t{$src2, $dst|$dst, $src2}"),
106            !strconcat(asm, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
107            [(set RC:$dst, (!cast<Intrinsic>(
108                      !strconcat("int_x86_", SSEVer, "_", OpcodeStr, FPSizeStr))
109                  RC:$src1, RC:$src2))], d>;
110   def rm_Int : PI<opc, MRMSrcMem, (outs RC:$dst), (ins RC:$src1,x86memop:$src2),
111        !if(Is2Addr,
112            !strconcat(asm, "\t{$src2, $dst|$dst, $src2}"),
113            !strconcat(asm, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
114        [(set RC:$dst, (!cast<Intrinsic>(
115                      !strconcat("int_x86_", SSEVer, "_", OpcodeStr, FPSizeStr))
116              RC:$src1, (mem_frag addr:$src2)))], d>;
117 }
118
119 //===----------------------------------------------------------------------===//
120 //  Non-instruction patterns
121 //===----------------------------------------------------------------------===//
122
123 // A vector extract of the first f32/f64 position is a subregister copy
124 def : Pat<(f32 (vector_extract (v4f32 VR128:$src), (iPTR 0))),
125           (f32 (EXTRACT_SUBREG (v4f32 VR128:$src), sub_ss))>;
126 def : Pat<(f64 (vector_extract (v2f64 VR128:$src), (iPTR 0))),
127           (f64 (EXTRACT_SUBREG (v2f64 VR128:$src), sub_sd))>;
128
129 // A 128-bit subvector extract from the first 256-bit vector position
130 // is a subregister copy that needs no instruction.
131 def : Pat<(v4i32 (extract_subvector (v8i32 VR256:$src), (i32 0))),
132           (v4i32 (EXTRACT_SUBREG (v8i32 VR256:$src), sub_xmm))>;
133 def : Pat<(v4f32 (extract_subvector (v8f32 VR256:$src), (i32 0))),
134           (v4f32 (EXTRACT_SUBREG (v8f32 VR256:$src), sub_xmm))>;
135
136 def : Pat<(v2i64 (extract_subvector (v4i64 VR256:$src), (i32 0))),
137           (v2i64 (EXTRACT_SUBREG (v4i64 VR256:$src), sub_xmm))>;
138 def : Pat<(v2f64 (extract_subvector (v4f64 VR256:$src), (i32 0))),
139           (v2f64 (EXTRACT_SUBREG (v4f64 VR256:$src), sub_xmm))>;
140
141 def : Pat<(v8i16 (extract_subvector (v16i16 VR256:$src), (i32 0))),
142           (v8i16 (EXTRACT_SUBREG (v16i16 VR256:$src), sub_xmm))>;
143 def : Pat<(v16i8 (extract_subvector (v32i8 VR256:$src), (i32 0))),
144           (v16i8 (EXTRACT_SUBREG (v32i8 VR256:$src), sub_xmm))>;
145
146 // A 128-bit subvector insert to the first 256-bit vector position
147 // is a subregister copy that needs no instruction.
148 def : Pat<(insert_subvector undef, (v2i64 VR128:$src), (i32 0)),
149           (INSERT_SUBREG (v4i64 (IMPLICIT_DEF)), VR128:$src, sub_xmm)>;
150 def : Pat<(insert_subvector undef, (v2f64 VR128:$src), (i32 0)),
151           (INSERT_SUBREG (v4f64 (IMPLICIT_DEF)), VR128:$src, sub_xmm)>;
152 def : Pat<(insert_subvector undef, (v4i32 VR128:$src), (i32 0)),
153           (INSERT_SUBREG (v8i32 (IMPLICIT_DEF)), VR128:$src, sub_xmm)>;
154 def : Pat<(insert_subvector undef, (v4f32 VR128:$src), (i32 0)),
155           (INSERT_SUBREG (v8f32 (IMPLICIT_DEF)), VR128:$src, sub_xmm)>;
156 def : Pat<(insert_subvector undef, (v8i16 VR128:$src), (i32 0)),
157           (INSERT_SUBREG (v16i16 (IMPLICIT_DEF)), VR128:$src, sub_xmm)>;
158 def : Pat<(insert_subvector undef, (v16i8 VR128:$src), (i32 0)),
159           (INSERT_SUBREG (v32i8 (IMPLICIT_DEF)), VR128:$src, sub_xmm)>;
160
161 // Implicitly promote a 32-bit scalar to a vector.
162 def : Pat<(v4f32 (scalar_to_vector FR32:$src)),
163           (INSERT_SUBREG (v4f32 (IMPLICIT_DEF)), FR32:$src, sub_ss)>;
164 def : Pat<(v8f32 (scalar_to_vector FR32:$src)),
165           (INSERT_SUBREG (v8f32 (IMPLICIT_DEF)), FR32:$src, sub_ss)>;
166 // Implicitly promote a 64-bit scalar to a vector.
167 def : Pat<(v2f64 (scalar_to_vector FR64:$src)),
168           (INSERT_SUBREG (v2f64 (IMPLICIT_DEF)), FR64:$src, sub_sd)>;
169 def : Pat<(v4f64 (scalar_to_vector FR64:$src)),
170           (INSERT_SUBREG (v4f64 (IMPLICIT_DEF)), FR64:$src, sub_sd)>;
171
172 // Bitcasts between 128-bit vector types. Return the original type since
173 // no instruction is needed for the conversion
174 let Predicates = [HasSSE2] in {
175   def : Pat<(v2i64 (bitconvert (v4i32 VR128:$src))), (v2i64 VR128:$src)>;
176   def : Pat<(v2i64 (bitconvert (v8i16 VR128:$src))), (v2i64 VR128:$src)>;
177   def : Pat<(v2i64 (bitconvert (v16i8 VR128:$src))), (v2i64 VR128:$src)>;
178   def : Pat<(v2i64 (bitconvert (v2f64 VR128:$src))), (v2i64 VR128:$src)>;
179   def : Pat<(v2i64 (bitconvert (v4f32 VR128:$src))), (v2i64 VR128:$src)>;
180   def : Pat<(v4i32 (bitconvert (v2i64 VR128:$src))), (v4i32 VR128:$src)>;
181   def : Pat<(v4i32 (bitconvert (v8i16 VR128:$src))), (v4i32 VR128:$src)>;
182   def : Pat<(v4i32 (bitconvert (v16i8 VR128:$src))), (v4i32 VR128:$src)>;
183   def : Pat<(v4i32 (bitconvert (v2f64 VR128:$src))), (v4i32 VR128:$src)>;
184   def : Pat<(v4i32 (bitconvert (v4f32 VR128:$src))), (v4i32 VR128:$src)>;
185   def : Pat<(v8i16 (bitconvert (v2i64 VR128:$src))), (v8i16 VR128:$src)>;
186   def : Pat<(v8i16 (bitconvert (v4i32 VR128:$src))), (v8i16 VR128:$src)>;
187   def : Pat<(v8i16 (bitconvert (v16i8 VR128:$src))), (v8i16 VR128:$src)>;
188   def : Pat<(v8i16 (bitconvert (v2f64 VR128:$src))), (v8i16 VR128:$src)>;
189   def : Pat<(v8i16 (bitconvert (v4f32 VR128:$src))), (v8i16 VR128:$src)>;
190   def : Pat<(v16i8 (bitconvert (v2i64 VR128:$src))), (v16i8 VR128:$src)>;
191   def : Pat<(v16i8 (bitconvert (v4i32 VR128:$src))), (v16i8 VR128:$src)>;
192   def : Pat<(v16i8 (bitconvert (v8i16 VR128:$src))), (v16i8 VR128:$src)>;
193   def : Pat<(v16i8 (bitconvert (v2f64 VR128:$src))), (v16i8 VR128:$src)>;
194   def : Pat<(v16i8 (bitconvert (v4f32 VR128:$src))), (v16i8 VR128:$src)>;
195   def : Pat<(v4f32 (bitconvert (v2i64 VR128:$src))), (v4f32 VR128:$src)>;
196   def : Pat<(v4f32 (bitconvert (v4i32 VR128:$src))), (v4f32 VR128:$src)>;
197   def : Pat<(v4f32 (bitconvert (v8i16 VR128:$src))), (v4f32 VR128:$src)>;
198   def : Pat<(v4f32 (bitconvert (v16i8 VR128:$src))), (v4f32 VR128:$src)>;
199   def : Pat<(v4f32 (bitconvert (v2f64 VR128:$src))), (v4f32 VR128:$src)>;
200   def : Pat<(v2f64 (bitconvert (v2i64 VR128:$src))), (v2f64 VR128:$src)>;
201   def : Pat<(v2f64 (bitconvert (v4i32 VR128:$src))), (v2f64 VR128:$src)>;
202   def : Pat<(v2f64 (bitconvert (v8i16 VR128:$src))), (v2f64 VR128:$src)>;
203   def : Pat<(v2f64 (bitconvert (v16i8 VR128:$src))), (v2f64 VR128:$src)>;
204   def : Pat<(v2f64 (bitconvert (v4f32 VR128:$src))), (v2f64 VR128:$src)>;
205 }
206
207 // Bitcasts between 256-bit vector types. Return the original type since
208 // no instruction is needed for the conversion
209 let Predicates = [HasAVX] in {
210   def : Pat<(v4f64  (bitconvert (v8f32 VR256:$src))),  (v4f64 VR256:$src)>;
211   def : Pat<(v4f64  (bitconvert (v8i32 VR256:$src))),  (v4f64 VR256:$src)>;
212   def : Pat<(v4f64  (bitconvert (v4i64 VR256:$src))),  (v4f64 VR256:$src)>;
213   def : Pat<(v4f64  (bitconvert (v16i16 VR256:$src))), (v4f64 VR256:$src)>;
214   def : Pat<(v4f64  (bitconvert (v32i8 VR256:$src))),  (v4f64 VR256:$src)>;
215   def : Pat<(v8f32  (bitconvert (v8i32 VR256:$src))),  (v8f32 VR256:$src)>;
216   def : Pat<(v8f32  (bitconvert (v4i64 VR256:$src))),  (v8f32 VR256:$src)>;
217   def : Pat<(v8f32  (bitconvert (v4f64 VR256:$src))),  (v8f32 VR256:$src)>;
218   def : Pat<(v8f32  (bitconvert (v32i8 VR256:$src))),  (v8f32 VR256:$src)>;
219   def : Pat<(v8f32  (bitconvert (v16i16 VR256:$src))), (v8f32 VR256:$src)>;
220   def : Pat<(v4i64  (bitconvert (v8f32 VR256:$src))),  (v4i64 VR256:$src)>;
221   def : Pat<(v4i64  (bitconvert (v8i32 VR256:$src))),  (v4i64 VR256:$src)>;
222   def : Pat<(v4i64  (bitconvert (v4f64 VR256:$src))),  (v4i64 VR256:$src)>;
223   def : Pat<(v4i64  (bitconvert (v32i8 VR256:$src))),  (v4i64 VR256:$src)>;
224   def : Pat<(v4i64  (bitconvert (v16i16 VR256:$src))), (v4i64 VR256:$src)>;
225   def : Pat<(v32i8  (bitconvert (v4f64 VR256:$src))),  (v32i8 VR256:$src)>;
226   def : Pat<(v32i8  (bitconvert (v4i64 VR256:$src))),  (v32i8 VR256:$src)>;
227   def : Pat<(v32i8  (bitconvert (v8f32 VR256:$src))),  (v32i8 VR256:$src)>;
228   def : Pat<(v32i8  (bitconvert (v8i32 VR256:$src))),  (v32i8 VR256:$src)>;
229   def : Pat<(v32i8  (bitconvert (v16i16 VR256:$src))), (v32i8 VR256:$src)>;
230   def : Pat<(v8i32  (bitconvert (v32i8 VR256:$src))),  (v8i32 VR256:$src)>;
231   def : Pat<(v8i32  (bitconvert (v16i16 VR256:$src))), (v8i32 VR256:$src)>;
232   def : Pat<(v8i32  (bitconvert (v8f32 VR256:$src))),  (v8i32 VR256:$src)>;
233   def : Pat<(v8i32  (bitconvert (v4i64 VR256:$src))),  (v8i32 VR256:$src)>;
234   def : Pat<(v8i32  (bitconvert (v4f64 VR256:$src))),  (v8i32 VR256:$src)>;
235   def : Pat<(v16i16 (bitconvert (v8f32 VR256:$src))),  (v16i16 VR256:$src)>;
236   def : Pat<(v16i16 (bitconvert (v8i32 VR256:$src))),  (v16i16 VR256:$src)>;
237   def : Pat<(v16i16 (bitconvert (v4i64 VR256:$src))),  (v16i16 VR256:$src)>;
238   def : Pat<(v16i16 (bitconvert (v4f64 VR256:$src))),  (v16i16 VR256:$src)>;
239   def : Pat<(v16i16 (bitconvert (v32i8 VR256:$src))),  (v16i16 VR256:$src)>;
240 }
241
242 // Alias instructions that map fld0 to pxor for sse.
243 // This is expanded by ExpandPostRAPseudos.
244 let isReMaterializable = 1, isAsCheapAsAMove = 1, canFoldAsLoad = 1,
245     isPseudo = 1 in {
246   def FsFLD0SS : I<0, Pseudo, (outs FR32:$dst), (ins), "",
247                    [(set FR32:$dst, fp32imm0)]>, Requires<[HasSSE1]>;
248   def FsFLD0SD : I<0, Pseudo, (outs FR64:$dst), (ins), "",
249                    [(set FR64:$dst, fpimm0)]>, Requires<[HasSSE2]>;
250 }
251
252 //===----------------------------------------------------------------------===//
253 // AVX & SSE - Zero/One Vectors
254 //===----------------------------------------------------------------------===//
255
256 // Alias instruction that maps zero vector to pxor / xorp* for sse.
257 // This is expanded by ExpandPostRAPseudos to an xorps / vxorps, and then
258 // swizzled by ExecutionDepsFix to pxor.
259 // We set canFoldAsLoad because this can be converted to a constant-pool
260 // load of an all-zeros value if folding it would be beneficial.
261 let isReMaterializable = 1, isAsCheapAsAMove = 1, canFoldAsLoad = 1,
262     isPseudo = 1, neverHasSideEffects = 1 in {
263 def V_SET0 : I<0, Pseudo, (outs VR128:$dst), (ins), "", []>;
264 }
265
266 def : Pat<(v4f32 immAllZerosV), (V_SET0)>;
267 def : Pat<(v2f64 immAllZerosV), (V_SET0)>;
268 def : Pat<(v4i32 immAllZerosV), (V_SET0)>;
269 def : Pat<(v2i64 immAllZerosV), (V_SET0)>;
270 def : Pat<(v8i16 immAllZerosV), (V_SET0)>;
271 def : Pat<(v16i8 immAllZerosV), (V_SET0)>;
272
273
274 // The same as done above but for AVX.  The 256-bit ISA does not support PI,
275 // and doesn't need it because on sandy bridge the register is set to zero
276 // at the rename stage without using any execution unit, so SET0PSY
277 // and SET0PDY can be used for vector int instructions without penalty
278 // FIXME: Change encoding to pseudo! This is blocked right now by the x86
279 // JIT implementatioan, it does not expand the instructions below like
280 // X86MCInstLower does.
281 let isReMaterializable = 1, isAsCheapAsAMove = 1, canFoldAsLoad = 1,
282     isCodeGenOnly = 1 in {
283 let Predicates = [HasAVX] in {
284 def AVX_SET0PSY : PSI<0x57, MRMInitReg, (outs VR256:$dst), (ins), "",
285                    [(set VR256:$dst, (v8f32 immAllZerosV))]>, VEX_4V;
286 def AVX_SET0PDY : PDI<0x57, MRMInitReg, (outs VR256:$dst), (ins), "",
287                    [(set VR256:$dst, (v4f64 immAllZerosV))]>, VEX_4V;
288 }
289 let Predicates = [HasAVX2], neverHasSideEffects = 1 in
290 def AVX2_SET0   : PDI<0xef, MRMInitReg, (outs VR256:$dst), (ins), "",
291                    []>, VEX_4V;
292 }
293
294 let Predicates = [HasAVX2], AddedComplexity = 5 in {
295   def : Pat<(v4i64 immAllZerosV), (AVX2_SET0)>;
296   def : Pat<(v8i32 immAllZerosV), (AVX2_SET0)>;
297   def : Pat<(v16i16 immAllZerosV), (AVX2_SET0)>;
298   def : Pat<(v32i8 immAllZerosV), (AVX2_SET0)>;
299 }
300
301 // AVX has no support for 256-bit integer instructions, but since the 128-bit
302 // VPXOR instruction writes zero to its upper part, it's safe build zeros.
303 def : Pat<(v32i8 immAllZerosV), (SUBREG_TO_REG (i8 0), (V_SET0), sub_xmm)>;
304 def : Pat<(bc_v32i8 (v8f32 immAllZerosV)),
305           (SUBREG_TO_REG (i8 0), (V_SET0), sub_xmm)>;
306
307 def : Pat<(v16i16 immAllZerosV), (SUBREG_TO_REG (i16 0), (V_SET0), sub_xmm)>;
308 def : Pat<(bc_v16i16 (v8f32 immAllZerosV)),
309           (SUBREG_TO_REG (i16 0), (V_SET0), sub_xmm)>;
310
311 def : Pat<(v8i32 immAllZerosV), (SUBREG_TO_REG (i32 0), (V_SET0), sub_xmm)>;
312 def : Pat<(bc_v8i32 (v8f32 immAllZerosV)),
313           (SUBREG_TO_REG (i32 0), (V_SET0), sub_xmm)>;
314
315 def : Pat<(v4i64 immAllZerosV), (SUBREG_TO_REG (i64 0), (V_SET0), sub_xmm)>;
316 def : Pat<(bc_v4i64 (v8f32 immAllZerosV)),
317           (SUBREG_TO_REG (i64 0), (V_SET0), sub_xmm)>;
318
319 // We set canFoldAsLoad because this can be converted to a constant-pool
320 // load of an all-ones value if folding it would be beneficial.
321 // FIXME: Change encoding to pseudo! This is blocked right now by the x86
322 // JIT implementation, it does not expand the instructions below like
323 // X86MCInstLower does.
324 let isReMaterializable = 1, isAsCheapAsAMove = 1, canFoldAsLoad = 1,
325     isCodeGenOnly = 1, ExeDomain = SSEPackedInt in {
326   let Predicates = [HasAVX] in
327   def AVX_SETALLONES : PDI<0x76, MRMInitReg, (outs VR128:$dst), (ins), "",
328                          [(set VR128:$dst, (v4i32 immAllOnesV))]>, VEX_4V;
329   def V_SETALLONES : PDI<0x76, MRMInitReg, (outs VR128:$dst), (ins), "",
330                          [(set VR128:$dst, (v4i32 immAllOnesV))]>;
331   let Predicates = [HasAVX2] in
332   def AVX2_SETALLONES : PDI<0x76, MRMInitReg, (outs VR256:$dst), (ins), "",
333                           [(set VR256:$dst, (v8i32 immAllOnesV))]>, VEX_4V;
334 }
335
336
337 //===----------------------------------------------------------------------===//
338 // SSE 1 & 2 - Move FP Scalar Instructions
339 //
340 // Move Instructions. Register-to-register movss/movsd is not used for FR32/64
341 // register copies because it's a partial register update; FsMOVAPSrr/FsMOVAPDrr
342 // is used instead. Register-to-register movss/movsd is not modeled as an
343 // INSERT_SUBREG because INSERT_SUBREG requires that the insert be implementable
344 // in terms of a copy, and just mentioned, we don't use movss/movsd for copies.
345 //===----------------------------------------------------------------------===//
346
347 class sse12_move_rr<RegisterClass RC, ValueType vt, string asm> :
348       SI<0x10, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src1, RC:$src2), asm,
349       [(set (vt VR128:$dst), (movl VR128:$src1, (scalar_to_vector RC:$src2)))]>;
350
351 // Loading from memory automatically zeroing upper bits.
352 class sse12_move_rm<RegisterClass RC, X86MemOperand x86memop,
353                     PatFrag mem_pat, string OpcodeStr> :
354       SI<0x10, MRMSrcMem, (outs RC:$dst), (ins x86memop:$src),
355          !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
356                         [(set RC:$dst, (mem_pat addr:$src))]>;
357
358 // AVX
359 def VMOVSSrr : sse12_move_rr<FR32, v4f32,
360                 "movss\t{$src2, $src1, $dst|$dst, $src1, $src2}">, XS, VEX_4V,
361                 VEX_LIG;
362 def VMOVSDrr : sse12_move_rr<FR64, v2f64,
363                 "movsd\t{$src2, $src1, $dst|$dst, $src1, $src2}">, XD, VEX_4V,
364                 VEX_LIG;
365
366 // For the disassembler
367 let isCodeGenOnly = 1 in {
368   def VMOVSSrr_REV : SI<0x11, MRMDestReg, (outs VR128:$dst),
369                         (ins VR128:$src1, FR32:$src2),
370                         "movss\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>,
371                         XS, VEX_4V, VEX_LIG;
372   def VMOVSDrr_REV : SI<0x11, MRMDestReg, (outs VR128:$dst),
373                         (ins VR128:$src1, FR64:$src2),
374                         "movsd\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>,
375                         XD, VEX_4V, VEX_LIG;
376 }
377
378 let canFoldAsLoad = 1, isReMaterializable = 1 in {
379   def VMOVSSrm : sse12_move_rm<FR32, f32mem, loadf32, "movss">, XS, VEX,
380                  VEX_LIG;
381   let AddedComplexity = 20 in
382     def VMOVSDrm : sse12_move_rm<FR64, f64mem, loadf64, "movsd">, XD, VEX,
383                    VEX_LIG;
384 }
385
386 def VMOVSSmr : SI<0x11, MRMDestMem, (outs), (ins f32mem:$dst, FR32:$src),
387                   "movss\t{$src, $dst|$dst, $src}",
388                   [(store FR32:$src, addr:$dst)]>, XS, VEX, VEX_LIG;
389 def VMOVSDmr : SI<0x11, MRMDestMem, (outs), (ins f64mem:$dst, FR64:$src),
390                   "movsd\t{$src, $dst|$dst, $src}",
391                   [(store FR64:$src, addr:$dst)]>, XD, VEX, VEX_LIG;
392
393 // SSE1 & 2
394 let Constraints = "$src1 = $dst" in {
395   def MOVSSrr : sse12_move_rr<FR32, v4f32,
396                           "movss\t{$src2, $dst|$dst, $src2}">, XS;
397   def MOVSDrr : sse12_move_rr<FR64, v2f64,
398                           "movsd\t{$src2, $dst|$dst, $src2}">, XD;
399
400   // For the disassembler
401   let isCodeGenOnly = 1 in {
402     def MOVSSrr_REV : SI<0x11, MRMDestReg, (outs VR128:$dst),
403                          (ins VR128:$src1, FR32:$src2),
404                          "movss\t{$src2, $dst|$dst, $src2}", []>, XS;
405     def MOVSDrr_REV : SI<0x11, MRMDestReg, (outs VR128:$dst),
406                          (ins VR128:$src1, FR64:$src2),
407                          "movsd\t{$src2, $dst|$dst, $src2}", []>, XD;
408   }
409 }
410
411 let canFoldAsLoad = 1, isReMaterializable = 1 in {
412   def MOVSSrm : sse12_move_rm<FR32, f32mem, loadf32, "movss">, XS;
413
414   let AddedComplexity = 20 in
415     def MOVSDrm : sse12_move_rm<FR64, f64mem, loadf64, "movsd">, XD;
416 }
417
418 def MOVSSmr : SSI<0x11, MRMDestMem, (outs), (ins f32mem:$dst, FR32:$src),
419                   "movss\t{$src, $dst|$dst, $src}",
420                   [(store FR32:$src, addr:$dst)]>;
421 def MOVSDmr : SDI<0x11, MRMDestMem, (outs), (ins f64mem:$dst, FR64:$src),
422                   "movsd\t{$src, $dst|$dst, $src}",
423                   [(store FR64:$src, addr:$dst)]>;
424
425 // Patterns
426 let Predicates = [HasAVX] in {
427   let AddedComplexity = 15 in {
428   // Extract the low 32-bit value from one vector and insert it into another.
429   def : Pat<(v4f32 (movl VR128:$src1, VR128:$src2)),
430             (VMOVSSrr (v4f32 VR128:$src1),
431                       (EXTRACT_SUBREG (v4f32 VR128:$src2), sub_ss))>;
432   def : Pat<(v4i32 (movl VR128:$src1, VR128:$src2)),
433             (VMOVSSrr (v4i32 VR128:$src1),
434                       (EXTRACT_SUBREG (v4i32 VR128:$src2), sub_ss))>;
435
436   // Extract the low 64-bit value from one vector and insert it into another.
437   def : Pat<(v2f64 (movl VR128:$src1, VR128:$src2)),
438             (VMOVSDrr (v2f64 VR128:$src1),
439                       (EXTRACT_SUBREG (v2f64 VR128:$src2), sub_sd))>;
440   def : Pat<(v2i64 (movl VR128:$src1, VR128:$src2)),
441             (VMOVSDrr (v2i64 VR128:$src1),
442                       (EXTRACT_SUBREG (v2i64 VR128:$src2), sub_sd))>;
443
444   // vector_shuffle v1, v2 <4, 5, 2, 3> using movsd
445   def : Pat<(v4f32 (movlp VR128:$src1, VR128:$src2)),
446             (VMOVSDrr VR128:$src1, (EXTRACT_SUBREG VR128:$src2, sub_sd))>;
447   def : Pat<(v4i32 (movlp VR128:$src1, VR128:$src2)),
448             (VMOVSDrr VR128:$src1, (EXTRACT_SUBREG VR128:$src2, sub_sd))>;
449
450   // Move scalar to XMM zero-extended, zeroing a VR128 then do a
451   // MOVS{S,D} to the lower bits.
452   def : Pat<(v4f32 (X86vzmovl (v4f32 (scalar_to_vector FR32:$src)))),
453             (VMOVSSrr (v4f32 (V_SET0)), FR32:$src)>;
454   def : Pat<(v4f32 (X86vzmovl (v4f32 VR128:$src))),
455             (VMOVSSrr (v4f32 (V_SET0)),
456                       (f32 (EXTRACT_SUBREG (v4f32 VR128:$src), sub_ss)))>;
457   def : Pat<(v4i32 (X86vzmovl (v4i32 VR128:$src))),
458             (VMOVSSrr (v4i32 (V_SET0)),
459                       (EXTRACT_SUBREG (v4i32 VR128:$src), sub_ss))>;
460   def : Pat<(v2f64 (X86vzmovl (v2f64 (scalar_to_vector FR64:$src)))),
461             (VMOVSDrr (v2f64 (V_SET0)), FR64:$src)>;
462
463   // Move low f32 and clear high bits.
464   def : Pat<(v8f32 (X86vzmovl (v8f32 VR256:$src))),
465             (SUBREG_TO_REG (i32 0),
466               (VMOVSSrr (v4f32 (V_SET0)),
467                         (EXTRACT_SUBREG (v8f32 VR256:$src), sub_ss)), sub_xmm)>;
468   def : Pat<(v8i32 (X86vzmovl (v8i32 VR256:$src))),
469             (SUBREG_TO_REG (i32 0),
470               (VMOVSSrr (v4i32 (V_SET0)),
471                         (EXTRACT_SUBREG (v8i32 VR256:$src), sub_ss)), sub_xmm)>;
472   }
473
474   let AddedComplexity = 20 in {
475   // MOVSSrm zeros the high parts of the register; represent this
476   // with SUBREG_TO_REG. The AVX versions also write: DST[255:128] <- 0
477   def : Pat<(v4f32 (X86vzmovl (v4f32 (scalar_to_vector (loadf32 addr:$src))))),
478             (SUBREG_TO_REG (i32 0), (VMOVSSrm addr:$src), sub_ss)>;
479   def : Pat<(v4f32 (scalar_to_vector (loadf32 addr:$src))),
480             (SUBREG_TO_REG (i32 0), (VMOVSSrm addr:$src), sub_ss)>;
481   def : Pat<(v4f32 (X86vzmovl (loadv4f32 addr:$src))),
482             (SUBREG_TO_REG (i32 0), (VMOVSSrm addr:$src), sub_ss)>;
483
484   // MOVSDrm zeros the high parts of the register; represent this
485   // with SUBREG_TO_REG. The AVX versions also write: DST[255:128] <- 0
486   def : Pat<(v2f64 (X86vzmovl (v2f64 (scalar_to_vector (loadf64 addr:$src))))),
487             (SUBREG_TO_REG (i64 0), (VMOVSDrm addr:$src), sub_sd)>;
488   def : Pat<(v2f64 (scalar_to_vector (loadf64 addr:$src))),
489             (SUBREG_TO_REG (i64 0), (VMOVSDrm addr:$src), sub_sd)>;
490   def : Pat<(v2f64 (X86vzmovl (loadv2f64 addr:$src))),
491             (SUBREG_TO_REG (i64 0), (VMOVSDrm addr:$src), sub_sd)>;
492   def : Pat<(v2f64 (X86vzmovl (bc_v2f64 (loadv4f32 addr:$src)))),
493             (SUBREG_TO_REG (i64 0), (VMOVSDrm addr:$src), sub_sd)>;
494   def : Pat<(v2f64 (X86vzload addr:$src)),
495             (SUBREG_TO_REG (i64 0), (VMOVSDrm addr:$src), sub_sd)>;
496
497   // Represent the same patterns above but in the form they appear for
498   // 256-bit types
499   def : Pat<(v8i32 (X86vzmovl (insert_subvector undef,
500                    (v4i32 (scalar_to_vector (loadi32 addr:$src))), (i32 0)))),
501             (SUBREG_TO_REG (i32 0), (VMOVSSrm addr:$src), sub_ss)>;
502   def : Pat<(v8f32 (X86vzmovl (insert_subvector undef,
503                    (v4f32 (scalar_to_vector (loadf32 addr:$src))), (i32 0)))),
504             (SUBREG_TO_REG (i32 0), (VMOVSSrm addr:$src), sub_ss)>;
505   def : Pat<(v4f64 (X86vzmovl (insert_subvector undef,
506                    (v2f64 (scalar_to_vector (loadf64 addr:$src))), (i32 0)))),
507             (SUBREG_TO_REG (i32 0), (VMOVSDrm addr:$src), sub_sd)>;
508   }
509   def : Pat<(v8f32 (X86vzmovl (insert_subvector undef,
510                    (v4f32 (scalar_to_vector FR32:$src)), (i32 0)))),
511             (SUBREG_TO_REG (i32 0),
512                            (v4f32 (VMOVSSrr (v4f32 (V_SET0)), FR32:$src)),
513                            sub_xmm)>;
514   def : Pat<(v4f64 (X86vzmovl (insert_subvector undef,
515                    (v2f64 (scalar_to_vector FR64:$src)), (i32 0)))),
516             (SUBREG_TO_REG (i64 0),
517                            (v2f64 (VMOVSDrr (v2f64 (V_SET0)), FR64:$src)),
518                            sub_xmm)>;
519   def : Pat<(v4i64 (X86vzmovl (insert_subvector undef,
520                    (v2i64 (scalar_to_vector (loadi64 addr:$src))), (i32 0)))),
521             (SUBREG_TO_REG (i64 0), (VMOVSDrm addr:$src), sub_sd)>;
522
523   // Move low f64 and clear high bits.
524   def : Pat<(v4f64 (X86vzmovl (v4f64 VR256:$src))),
525             (SUBREG_TO_REG (i32 0),
526               (VMOVSDrr (v2f64 (V_SET0)),
527                         (EXTRACT_SUBREG (v4f64 VR256:$src), sub_sd)), sub_xmm)>;
528
529   def : Pat<(v4i64 (X86vzmovl (v4i64 VR256:$src))),
530             (SUBREG_TO_REG (i32 0),
531               (VMOVSDrr (v2i64 (V_SET0)),
532                         (EXTRACT_SUBREG (v4i64 VR256:$src), sub_sd)), sub_xmm)>;
533
534 // Extract and store.
535   def : Pat<(store (f32 (vector_extract (v4f32 VR128:$src), (iPTR 0))),
536                    addr:$dst),
537             (VMOVSSmr addr:$dst,
538                      (EXTRACT_SUBREG (v4f32 VR128:$src), sub_ss))>;
539   def : Pat<(store (f64 (vector_extract (v2f64 VR128:$src), (iPTR 0))),
540                    addr:$dst),
541             (VMOVSDmr addr:$dst,
542                      (EXTRACT_SUBREG (v2f64 VR128:$src), sub_sd))>;
543
544   // Shuffle with VMOVSS
545   def : Pat<(v4f32 (X86Movss VR128:$src1, (scalar_to_vector FR32:$src2))),
546             (VMOVSSrr VR128:$src1, FR32:$src2)>;
547   def : Pat<(v4i32 (X86Movss VR128:$src1, VR128:$src2)),
548             (VMOVSSrr (v4i32 VR128:$src1),
549                       (EXTRACT_SUBREG (v4i32 VR128:$src2), sub_ss))>;
550   def : Pat<(v4f32 (X86Movss VR128:$src1, VR128:$src2)),
551             (VMOVSSrr (v4f32 VR128:$src1),
552                       (EXTRACT_SUBREG (v4f32 VR128:$src2), sub_ss))>;
553
554   // 256-bit variants
555   def : Pat<(v8i32 (X86Movss VR256:$src1, VR256:$src2)),
556             (SUBREG_TO_REG (i32 0),
557                 (VMOVSSrr (EXTRACT_SUBREG (v8i32 VR256:$src1), sub_ss),
558                           (EXTRACT_SUBREG (v8i32 VR256:$src2), sub_ss)), sub_xmm)>;
559   def : Pat<(v8f32 (X86Movss VR256:$src1, VR256:$src2)),
560             (SUBREG_TO_REG (i32 0),
561                 (VMOVSSrr (EXTRACT_SUBREG (v8f32 VR256:$src1), sub_ss),
562                           (EXTRACT_SUBREG (v8f32 VR256:$src2), sub_ss)), sub_xmm)>;
563
564   // Shuffle with VMOVSD
565   def : Pat<(v2f64 (X86Movsd VR128:$src1, (scalar_to_vector FR64:$src2))),
566             (VMOVSDrr VR128:$src1, FR64:$src2)>;
567   def : Pat<(v2i64 (X86Movsd VR128:$src1, VR128:$src2)),
568             (VMOVSDrr (v2i64 VR128:$src1),
569                      (EXTRACT_SUBREG (v2i64 VR128:$src2), sub_sd))>;
570   def : Pat<(v2f64 (X86Movsd VR128:$src1, VR128:$src2)),
571             (VMOVSDrr (v2f64 VR128:$src1),
572                      (EXTRACT_SUBREG (v2f64 VR128:$src2), sub_sd))>;
573   def : Pat<(v4f32 (X86Movsd VR128:$src1, VR128:$src2)),
574             (VMOVSDrr VR128:$src1, (EXTRACT_SUBREG (v4f32 VR128:$src2),
575                                                    sub_sd))>;
576   def : Pat<(v4i32 (X86Movsd VR128:$src1, VR128:$src2)),
577             (VMOVSDrr VR128:$src1, (EXTRACT_SUBREG (v4i32 VR128:$src2),
578                                                    sub_sd))>;
579
580   // 256-bit variants
581   def : Pat<(v4i64 (X86Movsd VR256:$src1, VR256:$src2)),
582             (SUBREG_TO_REG (i32 0),
583                 (VMOVSDrr (EXTRACT_SUBREG (v4i64 VR256:$src1), sub_sd),
584                           (EXTRACT_SUBREG (v4i64 VR256:$src2), sub_sd)), sub_xmm)>;
585   def : Pat<(v4f64 (X86Movsd VR256:$src1, VR256:$src2)),
586             (SUBREG_TO_REG (i32 0),
587                 (VMOVSDrr (EXTRACT_SUBREG (v4f64 VR256:$src1), sub_sd),
588                           (EXTRACT_SUBREG (v4f64 VR256:$src2), sub_sd)), sub_xmm)>;
589
590
591   // FIXME: Instead of a X86Movlps there should be a X86Movsd here, the problem
592   // is during lowering, where it's not possible to recognize the fold cause
593   // it has two uses through a bitcast. One use disappears at isel time and the
594   // fold opportunity reappears.
595   def : Pat<(v2f64 (X86Movlpd VR128:$src1, VR128:$src2)),
596             (VMOVSDrr VR128:$src1, (EXTRACT_SUBREG (v2f64 VR128:$src2),
597                                                    sub_sd))>;
598   def : Pat<(v2i64 (X86Movlpd VR128:$src1, VR128:$src2)),
599             (VMOVSDrr VR128:$src1, (EXTRACT_SUBREG (v2i64 VR128:$src2),
600                                                    sub_sd))>;
601   def : Pat<(v4f32 (X86Movlps VR128:$src1, VR128:$src2)),
602             (VMOVSDrr VR128:$src1, (EXTRACT_SUBREG (v4f32 VR128:$src2),
603                                                    sub_sd))>;
604   def : Pat<(v4i32 (X86Movlps VR128:$src1, VR128:$src2)),
605             (VMOVSDrr VR128:$src1, (EXTRACT_SUBREG (v4i32 VR128:$src2),
606                                                    sub_sd))>;
607 }
608
609 let Predicates = [HasSSE1] in {
610   let AddedComplexity = 15 in {
611   // Extract the low 32-bit value from one vector and insert it into another.
612   def : Pat<(v4f32 (movl VR128:$src1, VR128:$src2)),
613             (MOVSSrr (v4f32 VR128:$src1),
614                      (EXTRACT_SUBREG (v4f32 VR128:$src2), sub_ss))>;
615   def : Pat<(v4i32 (movl VR128:$src1, VR128:$src2)),
616             (MOVSSrr (v4i32 VR128:$src1),
617                      (EXTRACT_SUBREG (v4i32 VR128:$src2), sub_ss))>;
618
619   // Move scalar to XMM zero-extended, zeroing a VR128 then do a
620   // MOVSS to the lower bits.
621   def : Pat<(v4f32 (X86vzmovl (v4f32 (scalar_to_vector FR32:$src)))),
622             (MOVSSrr (v4f32 (V_SET0)), FR32:$src)>;
623   def : Pat<(v4f32 (X86vzmovl (v4f32 VR128:$src))),
624             (MOVSSrr (v4f32 (V_SET0)),
625                      (f32 (EXTRACT_SUBREG (v4f32 VR128:$src), sub_ss)))>;
626   def : Pat<(v4i32 (X86vzmovl (v4i32 VR128:$src))),
627             (MOVSSrr (v4i32 (V_SET0)),
628                      (EXTRACT_SUBREG (v4i32 VR128:$src), sub_ss))>;
629   }
630
631   let AddedComplexity = 20 in {
632   // MOVSSrm zeros the high parts of the register; represent this
633   // with SUBREG_TO_REG.
634   def : Pat<(v4f32 (X86vzmovl (v4f32 (scalar_to_vector (loadf32 addr:$src))))),
635             (SUBREG_TO_REG (i32 0), (MOVSSrm addr:$src), sub_ss)>;
636   def : Pat<(v4f32 (scalar_to_vector (loadf32 addr:$src))),
637             (SUBREG_TO_REG (i32 0), (MOVSSrm addr:$src), sub_ss)>;
638   def : Pat<(v4f32 (X86vzmovl (loadv4f32 addr:$src))),
639             (SUBREG_TO_REG (i32 0), (MOVSSrm addr:$src), sub_ss)>;
640   }
641
642   // Extract and store.
643   def : Pat<(store (f32 (vector_extract (v4f32 VR128:$src), (iPTR 0))),
644                    addr:$dst),
645             (MOVSSmr addr:$dst,
646                      (EXTRACT_SUBREG (v4f32 VR128:$src), sub_ss))>;
647
648   // Shuffle with MOVSS
649   def : Pat<(v4f32 (X86Movss VR128:$src1, (scalar_to_vector FR32:$src2))),
650             (MOVSSrr VR128:$src1, FR32:$src2)>;
651   def : Pat<(v4i32 (X86Movss VR128:$src1, VR128:$src2)),
652             (MOVSSrr (v4i32 VR128:$src1),
653                      (EXTRACT_SUBREG (v4i32 VR128:$src2), sub_ss))>;
654   def : Pat<(v4f32 (X86Movss VR128:$src1, VR128:$src2)),
655             (MOVSSrr (v4f32 VR128:$src1),
656                      (EXTRACT_SUBREG (v4f32 VR128:$src2), sub_ss))>;
657 }
658
659 let Predicates = [HasSSE2] in {
660   let AddedComplexity = 15 in {
661   // Extract the low 64-bit value from one vector and insert it into another.
662   def : Pat<(v2f64 (movl VR128:$src1, VR128:$src2)),
663             (MOVSDrr (v2f64 VR128:$src1),
664                      (EXTRACT_SUBREG (v2f64 VR128:$src2), sub_sd))>;
665   def : Pat<(v2i64 (movl VR128:$src1, VR128:$src2)),
666             (MOVSDrr (v2i64 VR128:$src1),
667                      (EXTRACT_SUBREG (v2i64 VR128:$src2), sub_sd))>;
668
669   // vector_shuffle v1, v2 <4, 5, 2, 3> using movsd
670   def : Pat<(v4f32 (movlp VR128:$src1, VR128:$src2)),
671             (MOVSDrr VR128:$src1, (EXTRACT_SUBREG VR128:$src2, sub_sd))>;
672   def : Pat<(v4i32 (movlp VR128:$src1, VR128:$src2)),
673             (MOVSDrr VR128:$src1, (EXTRACT_SUBREG VR128:$src2, sub_sd))>;
674
675   // Move scalar to XMM zero-extended, zeroing a VR128 then do a
676   // MOVSD to the lower bits.
677   def : Pat<(v2f64 (X86vzmovl (v2f64 (scalar_to_vector FR64:$src)))),
678             (MOVSDrr (v2f64 (V_SET0)), FR64:$src)>;
679   }
680
681   let AddedComplexity = 20 in {
682   // MOVSDrm zeros the high parts of the register; represent this
683   // with SUBREG_TO_REG.
684   def : Pat<(v2f64 (X86vzmovl (v2f64 (scalar_to_vector (loadf64 addr:$src))))),
685             (SUBREG_TO_REG (i64 0), (MOVSDrm addr:$src), sub_sd)>;
686   def : Pat<(v2f64 (scalar_to_vector (loadf64 addr:$src))),
687             (SUBREG_TO_REG (i64 0), (MOVSDrm addr:$src), sub_sd)>;
688   def : Pat<(v2f64 (X86vzmovl (loadv2f64 addr:$src))),
689             (SUBREG_TO_REG (i64 0), (MOVSDrm addr:$src), sub_sd)>;
690   def : Pat<(v2f64 (X86vzmovl (bc_v2f64 (loadv4f32 addr:$src)))),
691             (SUBREG_TO_REG (i64 0), (MOVSDrm addr:$src), sub_sd)>;
692   def : Pat<(v2f64 (X86vzload addr:$src)),
693             (SUBREG_TO_REG (i64 0), (MOVSDrm addr:$src), sub_sd)>;
694   }
695
696   // Extract and store.
697   def : Pat<(store (f64 (vector_extract (v2f64 VR128:$src), (iPTR 0))),
698                    addr:$dst),
699             (MOVSDmr addr:$dst,
700                      (EXTRACT_SUBREG (v2f64 VR128:$src), sub_sd))>;
701
702   // Shuffle with MOVSD
703   def : Pat<(v2f64 (X86Movsd VR128:$src1, (scalar_to_vector FR64:$src2))),
704             (MOVSDrr VR128:$src1, FR64:$src2)>;
705   def : Pat<(v2i64 (X86Movsd VR128:$src1, VR128:$src2)),
706             (MOVSDrr (v2i64 VR128:$src1),
707                      (EXTRACT_SUBREG (v2i64 VR128:$src2), sub_sd))>;
708   def : Pat<(v2f64 (X86Movsd VR128:$src1, VR128:$src2)),
709             (MOVSDrr (v2f64 VR128:$src1),
710                      (EXTRACT_SUBREG (v2f64 VR128:$src2), sub_sd))>;
711   def : Pat<(v4f32 (X86Movsd VR128:$src1, VR128:$src2)),
712             (MOVSDrr VR128:$src1, (EXTRACT_SUBREG (v4f32 VR128:$src2),sub_sd))>;
713   def : Pat<(v4i32 (X86Movsd VR128:$src1, VR128:$src2)),
714             (MOVSDrr VR128:$src1, (EXTRACT_SUBREG (v4i32 VR128:$src2),sub_sd))>;
715
716   // FIXME: Instead of a X86Movlps there should be a X86Movsd here, the problem
717   // is during lowering, where it's not possible to recognize the fold cause
718   // it has two uses through a bitcast. One use disappears at isel time and the
719   // fold opportunity reappears.
720   def : Pat<(v2f64 (X86Movlpd VR128:$src1, VR128:$src2)),
721             (MOVSDrr VR128:$src1, (EXTRACT_SUBREG (v2f64 VR128:$src2),sub_sd))>;
722   def : Pat<(v2i64 (X86Movlpd VR128:$src1, VR128:$src2)),
723             (MOVSDrr VR128:$src1, (EXTRACT_SUBREG (v2i64 VR128:$src2),sub_sd))>;
724   def : Pat<(v4f32 (X86Movlps VR128:$src1, VR128:$src2)),
725             (MOVSDrr VR128:$src1, (EXTRACT_SUBREG (v4f32 VR128:$src2),sub_sd))>;
726   def : Pat<(v4i32 (X86Movlps VR128:$src1, VR128:$src2)),
727             (MOVSDrr VR128:$src1, (EXTRACT_SUBREG (v4i32 VR128:$src2),sub_sd))>;
728 }
729
730 //===----------------------------------------------------------------------===//
731 // SSE 1 & 2 - Move Aligned/Unaligned FP Instructions
732 //===----------------------------------------------------------------------===//
733
734 multiclass sse12_mov_packed<bits<8> opc, RegisterClass RC,
735                             X86MemOperand x86memop, PatFrag ld_frag,
736                             string asm, Domain d,
737                             bit IsReMaterializable = 1> {
738 let neverHasSideEffects = 1 in
739   def rr : PI<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src),
740               !strconcat(asm, "\t{$src, $dst|$dst, $src}"), [], d>;
741 let canFoldAsLoad = 1, isReMaterializable = IsReMaterializable in
742   def rm : PI<opc, MRMSrcMem, (outs RC:$dst), (ins x86memop:$src),
743               !strconcat(asm, "\t{$src, $dst|$dst, $src}"),
744                    [(set RC:$dst, (ld_frag addr:$src))], d>;
745 }
746
747 defm VMOVAPS : sse12_mov_packed<0x28, VR128, f128mem, alignedloadv4f32,
748                               "movaps", SSEPackedSingle>, TB, VEX;
749 defm VMOVAPD : sse12_mov_packed<0x28, VR128, f128mem, alignedloadv2f64,
750                               "movapd", SSEPackedDouble>, TB, OpSize, VEX;
751 defm VMOVUPS : sse12_mov_packed<0x10, VR128, f128mem, loadv4f32,
752                               "movups", SSEPackedSingle>, TB, VEX;
753 defm VMOVUPD : sse12_mov_packed<0x10, VR128, f128mem, loadv2f64,
754                               "movupd", SSEPackedDouble, 0>, TB, OpSize, VEX;
755
756 defm VMOVAPSY : sse12_mov_packed<0x28, VR256, f256mem, alignedloadv8f32,
757                               "movaps", SSEPackedSingle>, TB, VEX;
758 defm VMOVAPDY : sse12_mov_packed<0x28, VR256, f256mem, alignedloadv4f64,
759                               "movapd", SSEPackedDouble>, TB, OpSize, VEX;
760 defm VMOVUPSY : sse12_mov_packed<0x10, VR256, f256mem, loadv8f32,
761                               "movups", SSEPackedSingle>, TB, VEX;
762 defm VMOVUPDY : sse12_mov_packed<0x10, VR256, f256mem, loadv4f64,
763                               "movupd", SSEPackedDouble, 0>, TB, OpSize, VEX;
764 defm MOVAPS : sse12_mov_packed<0x28, VR128, f128mem, alignedloadv4f32,
765                               "movaps", SSEPackedSingle>, TB;
766 defm MOVAPD : sse12_mov_packed<0x28, VR128, f128mem, alignedloadv2f64,
767                               "movapd", SSEPackedDouble>, TB, OpSize;
768 defm MOVUPS : sse12_mov_packed<0x10, VR128, f128mem, loadv4f32,
769                               "movups", SSEPackedSingle>, TB;
770 defm MOVUPD : sse12_mov_packed<0x10, VR128, f128mem, loadv2f64,
771                               "movupd", SSEPackedDouble, 0>, TB, OpSize;
772
773 def VMOVAPSmr : VPSI<0x29, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
774                    "movaps\t{$src, $dst|$dst, $src}",
775                    [(alignedstore (v4f32 VR128:$src), addr:$dst)]>, VEX;
776 def VMOVAPDmr : VPDI<0x29, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
777                    "movapd\t{$src, $dst|$dst, $src}",
778                    [(alignedstore (v2f64 VR128:$src), addr:$dst)]>, VEX;
779 def VMOVUPSmr : VPSI<0x11, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
780                    "movups\t{$src, $dst|$dst, $src}",
781                    [(store (v4f32 VR128:$src), addr:$dst)]>, VEX;
782 def VMOVUPDmr : VPDI<0x11, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
783                    "movupd\t{$src, $dst|$dst, $src}",
784                    [(store (v2f64 VR128:$src), addr:$dst)]>, VEX;
785 def VMOVAPSYmr : VPSI<0x29, MRMDestMem, (outs), (ins f256mem:$dst, VR256:$src),
786                    "movaps\t{$src, $dst|$dst, $src}",
787                    [(alignedstore256 (v8f32 VR256:$src), addr:$dst)]>, VEX;
788 def VMOVAPDYmr : VPDI<0x29, MRMDestMem, (outs), (ins f256mem:$dst, VR256:$src),
789                    "movapd\t{$src, $dst|$dst, $src}",
790                    [(alignedstore256 (v4f64 VR256:$src), addr:$dst)]>, VEX;
791 def VMOVUPSYmr : VPSI<0x11, MRMDestMem, (outs), (ins f256mem:$dst, VR256:$src),
792                    "movups\t{$src, $dst|$dst, $src}",
793                    [(store (v8f32 VR256:$src), addr:$dst)]>, VEX;
794 def VMOVUPDYmr : VPDI<0x11, MRMDestMem, (outs), (ins f256mem:$dst, VR256:$src),
795                    "movupd\t{$src, $dst|$dst, $src}",
796                    [(store (v4f64 VR256:$src), addr:$dst)]>, VEX;
797
798 // For disassembler
799 let isCodeGenOnly = 1 in {
800   def VMOVAPSrr_REV : VPSI<0x29, MRMDestReg, (outs VR128:$dst),
801                           (ins VR128:$src),
802                           "movaps\t{$src, $dst|$dst, $src}", []>, VEX;
803   def VMOVAPDrr_REV : VPDI<0x29, MRMDestReg, (outs VR128:$dst),
804                            (ins VR128:$src),
805                            "movapd\t{$src, $dst|$dst, $src}", []>, VEX;
806   def VMOVUPSrr_REV : VPSI<0x11, MRMDestReg, (outs VR128:$dst),
807                            (ins VR128:$src),
808                            "movups\t{$src, $dst|$dst, $src}", []>, VEX;
809   def VMOVUPDrr_REV : VPDI<0x11, MRMDestReg, (outs VR128:$dst),
810                            (ins VR128:$src),
811                            "movupd\t{$src, $dst|$dst, $src}", []>, VEX;
812   def VMOVAPSYrr_REV : VPSI<0x29, MRMDestReg, (outs VR256:$dst),
813                             (ins VR256:$src),
814                             "movaps\t{$src, $dst|$dst, $src}", []>, VEX;
815   def VMOVAPDYrr_REV : VPDI<0x29, MRMDestReg, (outs VR256:$dst),
816                             (ins VR256:$src),
817                             "movapd\t{$src, $dst|$dst, $src}", []>, VEX;
818   def VMOVUPSYrr_REV : VPSI<0x11, MRMDestReg, (outs VR256:$dst),
819                             (ins VR256:$src),
820                             "movups\t{$src, $dst|$dst, $src}", []>, VEX;
821   def VMOVUPDYrr_REV : VPDI<0x11, MRMDestReg, (outs VR256:$dst),
822                             (ins VR256:$src),
823                             "movupd\t{$src, $dst|$dst, $src}", []>, VEX;
824 }
825
826 let Predicates = [HasAVX] in {
827 def : Pat<(v8i32 (X86vzmovl
828                         (insert_subvector undef, (v4i32 VR128:$src), (i32 0)))),
829           (SUBREG_TO_REG (i32 0), (VMOVAPSrr VR128:$src), sub_xmm)>;
830 def : Pat<(v4i64 (X86vzmovl
831                         (insert_subvector undef, (v2i64 VR128:$src), (i32 0)))),
832           (SUBREG_TO_REG (i32 0), (VMOVAPSrr VR128:$src), sub_xmm)>;
833 def : Pat<(v8f32 (X86vzmovl
834                         (insert_subvector undef, (v4f32 VR128:$src), (i32 0)))),
835           (SUBREG_TO_REG (i32 0), (VMOVAPSrr VR128:$src), sub_xmm)>;
836 def : Pat<(v4f64 (X86vzmovl
837                         (insert_subvector undef, (v2f64 VR128:$src), (i32 0)))),
838           (SUBREG_TO_REG (i32 0), (VMOVAPSrr VR128:$src), sub_xmm)>;
839 }
840
841
842 def : Pat<(int_x86_avx_loadu_ps_256 addr:$src), (VMOVUPSYrm addr:$src)>;
843 def : Pat<(int_x86_avx_storeu_ps_256 addr:$dst, VR256:$src),
844           (VMOVUPSYmr addr:$dst, VR256:$src)>;
845
846 def : Pat<(int_x86_avx_loadu_pd_256 addr:$src), (VMOVUPDYrm addr:$src)>;
847 def : Pat<(int_x86_avx_storeu_pd_256 addr:$dst, VR256:$src),
848           (VMOVUPDYmr addr:$dst, VR256:$src)>;
849
850 def MOVAPSmr : PSI<0x29, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
851                    "movaps\t{$src, $dst|$dst, $src}",
852                    [(alignedstore (v4f32 VR128:$src), addr:$dst)]>;
853 def MOVAPDmr : PDI<0x29, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
854                    "movapd\t{$src, $dst|$dst, $src}",
855                    [(alignedstore (v2f64 VR128:$src), addr:$dst)]>;
856 def MOVUPSmr : PSI<0x11, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
857                    "movups\t{$src, $dst|$dst, $src}",
858                    [(store (v4f32 VR128:$src), addr:$dst)]>;
859 def MOVUPDmr : PDI<0x11, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
860                    "movupd\t{$src, $dst|$dst, $src}",
861                    [(store (v2f64 VR128:$src), addr:$dst)]>;
862
863 // For disassembler
864 let isCodeGenOnly = 1 in {
865   def MOVAPSrr_REV : PSI<0x29, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
866                          "movaps\t{$src, $dst|$dst, $src}", []>;
867   def MOVAPDrr_REV : PDI<0x29, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
868                          "movapd\t{$src, $dst|$dst, $src}", []>;
869   def MOVUPSrr_REV : PSI<0x11, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
870                          "movups\t{$src, $dst|$dst, $src}", []>;
871   def MOVUPDrr_REV : PDI<0x11, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
872                          "movupd\t{$src, $dst|$dst, $src}", []>;
873 }
874
875 let Predicates = [HasAVX] in {
876   def : Pat<(int_x86_sse_storeu_ps addr:$dst, VR128:$src),
877             (VMOVUPSmr addr:$dst, VR128:$src)>;
878   def : Pat<(int_x86_sse2_storeu_pd addr:$dst, VR128:$src),
879             (VMOVUPDmr addr:$dst, VR128:$src)>;
880 }
881
882 let Predicates = [HasSSE1] in
883   def : Pat<(int_x86_sse_storeu_ps addr:$dst, VR128:$src),
884             (MOVUPSmr addr:$dst, VR128:$src)>;
885 let Predicates = [HasSSE2] in
886   def : Pat<(int_x86_sse2_storeu_pd addr:$dst, VR128:$src),
887             (MOVUPDmr addr:$dst, VR128:$src)>;
888
889 // Use vmovaps/vmovups for AVX integer load/store.
890 let Predicates = [HasAVX] in {
891   // 128-bit load/store
892   def : Pat<(alignedloadv2i64 addr:$src),
893             (VMOVAPSrm addr:$src)>;
894   def : Pat<(loadv2i64 addr:$src),
895             (VMOVUPSrm addr:$src)>;
896
897   def : Pat<(alignedstore (v2i64 VR128:$src), addr:$dst),
898             (VMOVAPSmr addr:$dst, VR128:$src)>;
899   def : Pat<(alignedstore (v4i32 VR128:$src), addr:$dst),
900             (VMOVAPSmr addr:$dst, VR128:$src)>;
901   def : Pat<(alignedstore (v8i16 VR128:$src), addr:$dst),
902             (VMOVAPSmr addr:$dst, VR128:$src)>;
903   def : Pat<(alignedstore (v16i8 VR128:$src), addr:$dst),
904             (VMOVAPSmr addr:$dst, VR128:$src)>;
905   def : Pat<(store (v2i64 VR128:$src), addr:$dst),
906             (VMOVUPSmr addr:$dst, VR128:$src)>;
907   def : Pat<(store (v4i32 VR128:$src), addr:$dst),
908             (VMOVUPSmr addr:$dst, VR128:$src)>;
909   def : Pat<(store (v8i16 VR128:$src), addr:$dst),
910             (VMOVUPSmr addr:$dst, VR128:$src)>;
911   def : Pat<(store (v16i8 VR128:$src), addr:$dst),
912             (VMOVUPSmr addr:$dst, VR128:$src)>;
913
914   // 256-bit load/store
915   def : Pat<(alignedloadv4i64 addr:$src),
916             (VMOVAPSYrm addr:$src)>;
917   def : Pat<(loadv4i64 addr:$src),
918             (VMOVUPSYrm addr:$src)>;
919   def : Pat<(alignedstore256 (v4i64 VR256:$src), addr:$dst),
920             (VMOVAPSYmr addr:$dst, VR256:$src)>;
921   def : Pat<(alignedstore256 (v8i32 VR256:$src), addr:$dst),
922             (VMOVAPSYmr addr:$dst, VR256:$src)>;
923   def : Pat<(alignedstore256 (v16i16 VR256:$src), addr:$dst),
924             (VMOVAPSYmr addr:$dst, VR256:$src)>;
925   def : Pat<(alignedstore256 (v32i8 VR256:$src), addr:$dst),
926             (VMOVAPSYmr addr:$dst, VR256:$src)>;
927   def : Pat<(store (v4i64 VR256:$src), addr:$dst),
928             (VMOVUPSYmr addr:$dst, VR256:$src)>;
929   def : Pat<(store (v8i32 VR256:$src), addr:$dst),
930             (VMOVUPSYmr addr:$dst, VR256:$src)>;
931   def : Pat<(store (v16i16 VR256:$src), addr:$dst),
932             (VMOVUPSYmr addr:$dst, VR256:$src)>;
933   def : Pat<(store (v32i8 VR256:$src), addr:$dst),
934             (VMOVUPSYmr addr:$dst, VR256:$src)>;
935 }
936
937 // Use movaps / movups for SSE integer load / store (one byte shorter).
938 // The instructions selected below are then converted to MOVDQA/MOVDQU
939 // during the SSE domain pass.
940 let Predicates = [HasSSE1] in {
941   def : Pat<(alignedloadv2i64 addr:$src),
942             (MOVAPSrm addr:$src)>;
943   def : Pat<(loadv2i64 addr:$src),
944             (MOVUPSrm addr:$src)>;
945
946   def : Pat<(alignedstore (v2i64 VR128:$src), addr:$dst),
947             (MOVAPSmr addr:$dst, VR128:$src)>;
948   def : Pat<(alignedstore (v4i32 VR128:$src), addr:$dst),
949             (MOVAPSmr addr:$dst, VR128:$src)>;
950   def : Pat<(alignedstore (v8i16 VR128:$src), addr:$dst),
951             (MOVAPSmr addr:$dst, VR128:$src)>;
952   def : Pat<(alignedstore (v16i8 VR128:$src), addr:$dst),
953             (MOVAPSmr addr:$dst, VR128:$src)>;
954   def : Pat<(store (v2i64 VR128:$src), addr:$dst),
955             (MOVUPSmr addr:$dst, VR128:$src)>;
956   def : Pat<(store (v4i32 VR128:$src), addr:$dst),
957             (MOVUPSmr addr:$dst, VR128:$src)>;
958   def : Pat<(store (v8i16 VR128:$src), addr:$dst),
959             (MOVUPSmr addr:$dst, VR128:$src)>;
960   def : Pat<(store (v16i8 VR128:$src), addr:$dst),
961             (MOVUPSmr addr:$dst, VR128:$src)>;
962 }
963
964 // Alias instruction to do FR32 or FR64 reg-to-reg copy using movaps. Upper
965 // bits are disregarded. FIXME: Set encoding to pseudo!
966 let neverHasSideEffects = 1 in {
967 def FsVMOVAPSrr : VPSI<0x28, MRMSrcReg, (outs FR32:$dst), (ins FR32:$src),
968                        "movaps\t{$src, $dst|$dst, $src}", []>, VEX;
969 def FsVMOVAPDrr : VPDI<0x28, MRMSrcReg, (outs FR64:$dst), (ins FR64:$src),
970                        "movapd\t{$src, $dst|$dst, $src}", []>, VEX;
971 def FsMOVAPSrr : PSI<0x28, MRMSrcReg, (outs FR32:$dst), (ins FR32:$src),
972                      "movaps\t{$src, $dst|$dst, $src}", []>;
973 def FsMOVAPDrr : PDI<0x28, MRMSrcReg, (outs FR64:$dst), (ins FR64:$src),
974                      "movapd\t{$src, $dst|$dst, $src}", []>;
975 }
976
977 // Alias instruction to load FR32 or FR64 from f128mem using movaps. Upper
978 // bits are disregarded. FIXME: Set encoding to pseudo!
979 let canFoldAsLoad = 1, isReMaterializable = 1 in {
980 let isCodeGenOnly = 1 in {
981   def FsVMOVAPSrm : VPSI<0x28, MRMSrcMem, (outs FR32:$dst), (ins f128mem:$src),
982                          "movaps\t{$src, $dst|$dst, $src}",
983                          [(set FR32:$dst, (alignedloadfsf32 addr:$src))]>, VEX;
984   def FsVMOVAPDrm : VPDI<0x28, MRMSrcMem, (outs FR64:$dst), (ins f128mem:$src),
985                          "movapd\t{$src, $dst|$dst, $src}",
986                          [(set FR64:$dst, (alignedloadfsf64 addr:$src))]>, VEX;
987 }
988 def FsMOVAPSrm : PSI<0x28, MRMSrcMem, (outs FR32:$dst), (ins f128mem:$src),
989                      "movaps\t{$src, $dst|$dst, $src}",
990                      [(set FR32:$dst, (alignedloadfsf32 addr:$src))]>;
991 def FsMOVAPDrm : PDI<0x28, MRMSrcMem, (outs FR64:$dst), (ins f128mem:$src),
992                      "movapd\t{$src, $dst|$dst, $src}",
993                      [(set FR64:$dst, (alignedloadfsf64 addr:$src))]>;
994 }
995
996 //===----------------------------------------------------------------------===//
997 // SSE 1 & 2 - Move Low packed FP Instructions
998 //===----------------------------------------------------------------------===//
999
1000 multiclass sse12_mov_hilo_packed<bits<8>opc, RegisterClass RC,
1001                                  PatFrag mov_frag, string base_opc,
1002                                  string asm_opr> {
1003   def PSrm : PI<opc, MRMSrcMem,
1004          (outs VR128:$dst), (ins VR128:$src1, f64mem:$src2),
1005          !strconcat(base_opc, "s", asm_opr),
1006      [(set RC:$dst,
1007        (mov_frag RC:$src1,
1008               (bc_v4f32 (v2f64 (scalar_to_vector (loadf64 addr:$src2))))))],
1009               SSEPackedSingle>, TB;
1010
1011   def PDrm : PI<opc, MRMSrcMem,
1012          (outs RC:$dst), (ins RC:$src1, f64mem:$src2),
1013          !strconcat(base_opc, "d", asm_opr),
1014      [(set RC:$dst, (v2f64 (mov_frag RC:$src1,
1015                               (scalar_to_vector (loadf64 addr:$src2)))))],
1016               SSEPackedDouble>, TB, OpSize;
1017 }
1018
1019 let AddedComplexity = 20 in {
1020   defm VMOVL : sse12_mov_hilo_packed<0x12, VR128, movlp, "movlp",
1021                      "\t{$src2, $src1, $dst|$dst, $src1, $src2}">, VEX_4V;
1022 }
1023 let Constraints = "$src1 = $dst", AddedComplexity = 20 in {
1024   defm MOVL : sse12_mov_hilo_packed<0x12, VR128, movlp, "movlp",
1025                                    "\t{$src2, $dst|$dst, $src2}">;
1026 }
1027
1028 def VMOVLPSmr : VPSI<0x13, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
1029                    "movlps\t{$src, $dst|$dst, $src}",
1030                    [(store (f64 (vector_extract (bc_v2f64 (v4f32 VR128:$src)),
1031                                  (iPTR 0))), addr:$dst)]>, VEX;
1032 def VMOVLPDmr : VPDI<0x13, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
1033                    "movlpd\t{$src, $dst|$dst, $src}",
1034                    [(store (f64 (vector_extract (v2f64 VR128:$src),
1035                                  (iPTR 0))), addr:$dst)]>, VEX;
1036 def MOVLPSmr : PSI<0x13, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
1037                    "movlps\t{$src, $dst|$dst, $src}",
1038                    [(store (f64 (vector_extract (bc_v2f64 (v4f32 VR128:$src)),
1039                                  (iPTR 0))), addr:$dst)]>;
1040 def MOVLPDmr : PDI<0x13, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
1041                    "movlpd\t{$src, $dst|$dst, $src}",
1042                    [(store (f64 (vector_extract (v2f64 VR128:$src),
1043                                  (iPTR 0))), addr:$dst)]>;
1044
1045 let Predicates = [HasAVX] in {
1046   let AddedComplexity = 20 in {
1047     // vector_shuffle v1, (load v2) <4, 5, 2, 3> using MOVLPS
1048     def : Pat<(v4f32 (movlp VR128:$src1, (load addr:$src2))),
1049               (VMOVLPSrm VR128:$src1, addr:$src2)>;
1050     def : Pat<(v4i32 (movlp VR128:$src1, (load addr:$src2))),
1051               (VMOVLPSrm VR128:$src1, addr:$src2)>;
1052     // vector_shuffle v1, (load v2) <2, 1> using MOVLPS
1053     def : Pat<(v2f64 (movlp VR128:$src1, (load addr:$src2))),
1054               (VMOVLPDrm VR128:$src1, addr:$src2)>;
1055     def : Pat<(v2i64 (movlp VR128:$src1, (load addr:$src2))),
1056               (VMOVLPDrm VR128:$src1, addr:$src2)>;
1057   }
1058
1059   // (store (vector_shuffle (load addr), v2, <4, 5, 2, 3>), addr) using MOVLPS
1060   def : Pat<(store (v4f32 (movlp (load addr:$src1), VR128:$src2)), addr:$src1),
1061             (VMOVLPSmr addr:$src1, VR128:$src2)>;
1062   def : Pat<(store (v4i32 (movlp (bc_v4i32 (loadv2i64 addr:$src1)),
1063                                  VR128:$src2)), addr:$src1),
1064             (VMOVLPSmr addr:$src1, VR128:$src2)>;
1065
1066   // (store (vector_shuffle (load addr), v2, <2, 1>), addr) using MOVLPS
1067   def : Pat<(store (v2f64 (movlp (load addr:$src1), VR128:$src2)), addr:$src1),
1068             (VMOVLPDmr addr:$src1, VR128:$src2)>;
1069   def : Pat<(store (v2i64 (movlp (load addr:$src1), VR128:$src2)), addr:$src1),
1070             (VMOVLPDmr addr:$src1, VR128:$src2)>;
1071
1072   // Shuffle with VMOVLPS
1073   def : Pat<(v4f32 (X86Movlps VR128:$src1, (load addr:$src2))),
1074             (VMOVLPSrm VR128:$src1, addr:$src2)>;
1075   def : Pat<(v4i32 (X86Movlps VR128:$src1, (load addr:$src2))),
1076             (VMOVLPSrm VR128:$src1, addr:$src2)>;
1077   def : Pat<(X86Movlps VR128:$src1,
1078                       (bc_v4f32 (v2f64 (scalar_to_vector (loadf64 addr:$src2))))),
1079             (VMOVLPSrm VR128:$src1, addr:$src2)>;
1080
1081   // Shuffle with VMOVLPD
1082   def : Pat<(v2f64 (X86Movlpd VR128:$src1, (load addr:$src2))),
1083             (VMOVLPDrm VR128:$src1, addr:$src2)>;
1084   def : Pat<(v2i64 (X86Movlpd VR128:$src1, (load addr:$src2))),
1085             (VMOVLPDrm VR128:$src1, addr:$src2)>;
1086   def : Pat<(v2f64 (X86Movlpd VR128:$src1,
1087                               (scalar_to_vector (loadf64 addr:$src2)))),
1088             (VMOVLPDrm VR128:$src1, addr:$src2)>;
1089
1090   // Store patterns
1091   def : Pat<(store (v4f32 (X86Movlps (load addr:$src1), VR128:$src2)),
1092                    addr:$src1),
1093             (VMOVLPSmr addr:$src1, VR128:$src2)>;
1094   def : Pat<(store (v4i32 (X86Movlps
1095                    (bc_v4i32 (loadv2i64 addr:$src1)), VR128:$src2)), addr:$src1),
1096             (VMOVLPSmr addr:$src1, VR128:$src2)>;
1097   def : Pat<(store (v2f64 (X86Movlpd (load addr:$src1), VR128:$src2)),
1098                    addr:$src1),
1099             (VMOVLPDmr addr:$src1, VR128:$src2)>;
1100   def : Pat<(store (v2i64 (X86Movlpd (load addr:$src1), VR128:$src2)),
1101                    addr:$src1),
1102             (VMOVLPDmr addr:$src1, VR128:$src2)>;
1103 }
1104
1105 let Predicates = [HasSSE1] in {
1106   let AddedComplexity = 20 in {
1107     // vector_shuffle v1, (load v2) <4, 5, 2, 3> using MOVLPS
1108     def : Pat<(v4f32 (movlp VR128:$src1, (load addr:$src2))),
1109               (MOVLPSrm VR128:$src1, addr:$src2)>;
1110     def : Pat<(v4i32 (movlp VR128:$src1, (load addr:$src2))),
1111               (MOVLPSrm VR128:$src1, addr:$src2)>;
1112   }
1113
1114   // (store (vector_shuffle (load addr), v2, <4, 5, 2, 3>), addr) using MOVLPS
1115   def : Pat<(store (i64 (vector_extract (bc_v2i64 (v4f32 VR128:$src2)),
1116                                  (iPTR 0))), addr:$src1),
1117             (MOVLPSmr addr:$src1, VR128:$src2)>;
1118   def : Pat<(store (v4f32 (movlp (load addr:$src1), VR128:$src2)), addr:$src1),
1119             (MOVLPSmr addr:$src1, VR128:$src2)>;
1120   def : Pat<(store (v4i32 (movlp (bc_v4i32 (loadv2i64 addr:$src1)),
1121                                  VR128:$src2)), addr:$src1),
1122             (MOVLPSmr addr:$src1, VR128:$src2)>;
1123
1124   // Shuffle with MOVLPS
1125   def : Pat<(v4f32 (X86Movlps VR128:$src1, (load addr:$src2))),
1126             (MOVLPSrm VR128:$src1, addr:$src2)>;
1127   def : Pat<(v4i32 (X86Movlps VR128:$src1, (load addr:$src2))),
1128             (MOVLPSrm VR128:$src1, addr:$src2)>;
1129   def : Pat<(X86Movlps VR128:$src1,
1130                       (bc_v4f32 (v2f64 (scalar_to_vector (loadf64 addr:$src2))))),
1131             (MOVLPSrm VR128:$src1, addr:$src2)>;
1132   def : Pat<(X86Movlps VR128:$src1,
1133                       (bc_v4f32 (v2i64 (scalar_to_vector (loadi64 addr:$src2))))),
1134             (MOVLPSrm VR128:$src1, addr:$src2)>;
1135
1136   // Store patterns
1137   def : Pat<(store (v4f32 (X86Movlps (load addr:$src1), VR128:$src2)),
1138                                       addr:$src1),
1139             (MOVLPSmr addr:$src1, VR128:$src2)>;
1140   def : Pat<(store (v4i32 (X86Movlps
1141                    (bc_v4i32 (loadv2i64 addr:$src1)), VR128:$src2)),
1142                               addr:$src1),
1143             (MOVLPSmr addr:$src1, VR128:$src2)>;
1144 }
1145
1146 let Predicates = [HasSSE2] in {
1147   let AddedComplexity = 20 in {
1148     // vector_shuffle v1, (load v2) <2, 1> using MOVLPS
1149     def : Pat<(v2f64 (movlp VR128:$src1, (load addr:$src2))),
1150               (MOVLPDrm VR128:$src1, addr:$src2)>;
1151     def : Pat<(v2i64 (movlp VR128:$src1, (load addr:$src2))),
1152               (MOVLPDrm VR128:$src1, addr:$src2)>;
1153   }
1154
1155   // (store (vector_shuffle (load addr), v2, <2, 1>), addr) using MOVLPS
1156   def : Pat<(store (v2f64 (movlp (load addr:$src1), VR128:$src2)), addr:$src1),
1157             (MOVLPDmr addr:$src1, VR128:$src2)>;
1158   def : Pat<(store (v2i64 (movlp (load addr:$src1), VR128:$src2)), addr:$src1),
1159             (MOVLPDmr addr:$src1, VR128:$src2)>;
1160
1161   // Shuffle with MOVLPD
1162   def : Pat<(v2f64 (X86Movlpd VR128:$src1, (load addr:$src2))),
1163             (MOVLPDrm VR128:$src1, addr:$src2)>;
1164   def : Pat<(v2i64 (X86Movlpd VR128:$src1, (load addr:$src2))),
1165             (MOVLPDrm VR128:$src1, addr:$src2)>;
1166   def : Pat<(v2f64 (X86Movlpd VR128:$src1,
1167                               (scalar_to_vector (loadf64 addr:$src2)))),
1168             (MOVLPDrm VR128:$src1, addr:$src2)>;
1169
1170   // Store patterns
1171   def : Pat<(store (v2f64 (X86Movlpd (load addr:$src1), VR128:$src2)),
1172                            addr:$src1),
1173             (MOVLPDmr addr:$src1, VR128:$src2)>;
1174   def : Pat<(store (v2i64 (X86Movlpd (load addr:$src1), VR128:$src2)),
1175                            addr:$src1),
1176             (MOVLPDmr addr:$src1, VR128:$src2)>;
1177 }
1178
1179 //===----------------------------------------------------------------------===//
1180 // SSE 1 & 2 - Move Hi packed FP Instructions
1181 //===----------------------------------------------------------------------===//
1182
1183 let AddedComplexity = 20 in {
1184   defm VMOVH : sse12_mov_hilo_packed<0x16, VR128, movlhps, "movhp",
1185                      "\t{$src2, $src1, $dst|$dst, $src1, $src2}">, VEX_4V;
1186 }
1187 let Constraints = "$src1 = $dst", AddedComplexity = 20 in {
1188   defm MOVH : sse12_mov_hilo_packed<0x16, VR128, movlhps, "movhp",
1189                                    "\t{$src2, $dst|$dst, $src2}">;
1190 }
1191
1192 // v2f64 extract element 1 is always custom lowered to unpack high to low
1193 // and extract element 0 so the non-store version isn't too horrible.
1194 def VMOVHPSmr : VPSI<0x17, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
1195                    "movhps\t{$src, $dst|$dst, $src}",
1196                    [(store (f64 (vector_extract
1197                                  (unpckh (bc_v2f64 (v4f32 VR128:$src)),
1198                                          (undef)), (iPTR 0))), addr:$dst)]>,
1199                    VEX;
1200 def VMOVHPDmr : VPDI<0x17, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
1201                    "movhpd\t{$src, $dst|$dst, $src}",
1202                    [(store (f64 (vector_extract
1203                                  (v2f64 (unpckh VR128:$src, (undef))),
1204                                  (iPTR 0))), addr:$dst)]>,
1205                    VEX;
1206 def MOVHPSmr : PSI<0x17, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
1207                    "movhps\t{$src, $dst|$dst, $src}",
1208                    [(store (f64 (vector_extract
1209                                  (unpckh (bc_v2f64 (v4f32 VR128:$src)),
1210                                          (undef)), (iPTR 0))), addr:$dst)]>;
1211 def MOVHPDmr : PDI<0x17, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
1212                    "movhpd\t{$src, $dst|$dst, $src}",
1213                    [(store (f64 (vector_extract
1214                                  (v2f64 (unpckh VR128:$src, (undef))),
1215                                  (iPTR 0))), addr:$dst)]>;
1216
1217 let Predicates = [HasAVX] in {
1218   // VMOVHPS patterns
1219   def : Pat<(movlhps VR128:$src1, (bc_v4i32 (v2i64 (X86vzload addr:$src2)))),
1220             (VMOVHPSrm (v4i32 VR128:$src1), addr:$src2)>;
1221   def : Pat<(X86Movlhps VR128:$src1,
1222                  (bc_v4f32 (v2f64 (scalar_to_vector (loadf64 addr:$src2))))),
1223             (VMOVHPSrm VR128:$src1, addr:$src2)>;
1224   def : Pat<(X86Movlhps VR128:$src1,
1225                  (bc_v4f32 (v2i64 (scalar_to_vector (loadi64 addr:$src2))))),
1226             (VMOVHPSrm VR128:$src1, addr:$src2)>;
1227   def : Pat<(X86Movlhps VR128:$src1,
1228                  (bc_v4i32 (v2i64 (X86vzload addr:$src2)))),
1229             (VMOVHPSrm VR128:$src1, addr:$src2)>;
1230
1231   // FIXME: Instead of X86Unpckl, there should be a X86Movlhpd here, the problem
1232   // is during lowering, where it's not possible to recognize the load fold 
1233   // cause it has two uses through a bitcast. One use disappears at isel time
1234   // and the fold opportunity reappears.
1235   def : Pat<(v2f64 (X86Unpckl VR128:$src1,
1236                       (scalar_to_vector (loadf64 addr:$src2)))),
1237             (VMOVHPDrm VR128:$src1, addr:$src2)>;
1238
1239   // FIXME: This should be matched by a X86Movhpd instead. Same as above
1240   def : Pat<(v2f64 (X86Movlhpd VR128:$src1,
1241                       (scalar_to_vector (loadf64 addr:$src2)))),
1242             (VMOVHPDrm VR128:$src1, addr:$src2)>;
1243
1244   // Store patterns
1245   def : Pat<(store (f64 (vector_extract
1246             (X86Unpckh (bc_v2f64 (v4f32 VR128:$src)),
1247                        (bc_v2f64 (v4f32 VR128:$src))), (iPTR 0))), addr:$dst),
1248             (VMOVHPSmr addr:$dst, VR128:$src)>;
1249   def : Pat<(store (f64 (vector_extract
1250             (v2f64 (X86Unpckh VR128:$src, VR128:$src)), (iPTR 0))), addr:$dst),
1251             (VMOVHPDmr addr:$dst, VR128:$src)>;
1252 }
1253
1254 let Predicates = [HasSSE1] in {
1255   // MOVHPS patterns
1256   def : Pat<(movlhps VR128:$src1, (bc_v4i32 (v2i64 (X86vzload addr:$src2)))),
1257             (MOVHPSrm (v4i32 VR128:$src1), addr:$src2)>;
1258   def : Pat<(X86Movlhps VR128:$src1,
1259                  (bc_v4f32 (v2f64 (scalar_to_vector (loadf64 addr:$src2))))),
1260             (MOVHPSrm VR128:$src1, addr:$src2)>;
1261   def : Pat<(X86Movlhps VR128:$src1,
1262                  (bc_v4f32 (v2i64 (scalar_to_vector (loadi64 addr:$src2))))),
1263             (MOVHPSrm VR128:$src1, addr:$src2)>;
1264   def : Pat<(X86Movlhps VR128:$src1,
1265                  (bc_v4f32 (v2i64 (X86vzload addr:$src2)))),
1266             (MOVHPSrm VR128:$src1, addr:$src2)>;
1267
1268   // Store patterns
1269   def : Pat<(store (f64 (vector_extract
1270             (X86Unpckh (bc_v2f64 (v4f32 VR128:$src)),
1271                        (bc_v2f64 (v4f32 VR128:$src))), (iPTR 0))), addr:$dst),
1272             (MOVHPSmr addr:$dst, VR128:$src)>;
1273 }
1274
1275 let Predicates = [HasSSE2] in {
1276   // FIXME: Instead of X86Unpckl, there should be a X86Movlhpd here, the problem
1277   // is during lowering, where it's not possible to recognize the load fold 
1278   // cause it has two uses through a bitcast. One use disappears at isel time
1279   // and the fold opportunity reappears.
1280   def : Pat<(v2f64 (X86Unpckl VR128:$src1,
1281                       (scalar_to_vector (loadf64 addr:$src2)))),
1282             (MOVHPDrm VR128:$src1, addr:$src2)>;
1283
1284   // FIXME: This should be matched by a X86Movhpd instead. Same as above
1285   def : Pat<(v2f64 (X86Movlhpd VR128:$src1,
1286                       (scalar_to_vector (loadf64 addr:$src2)))),
1287             (MOVHPDrm VR128:$src1, addr:$src2)>;
1288
1289   // Store patterns
1290   def : Pat<(store (f64 (vector_extract
1291             (v2f64 (X86Unpckh VR128:$src, VR128:$src)), (iPTR 0))),addr:$dst),
1292             (MOVHPDmr addr:$dst, VR128:$src)>;
1293 }
1294
1295 //===----------------------------------------------------------------------===//
1296 // SSE 1 & 2 - Move Low to High and High to Low packed FP Instructions
1297 //===----------------------------------------------------------------------===//
1298
1299 let AddedComplexity = 20 in {
1300   def VMOVLHPSrr : VPSI<0x16, MRMSrcReg, (outs VR128:$dst),
1301                                        (ins VR128:$src1, VR128:$src2),
1302                       "movlhps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1303                       [(set VR128:$dst,
1304                         (v4f32 (movlhps VR128:$src1, VR128:$src2)))]>,
1305                       VEX_4V;
1306   def VMOVHLPSrr : VPSI<0x12, MRMSrcReg, (outs VR128:$dst),
1307                                        (ins VR128:$src1, VR128:$src2),
1308                       "movhlps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1309                       [(set VR128:$dst,
1310                         (v4f32 (movhlps VR128:$src1, VR128:$src2)))]>,
1311                       VEX_4V;
1312 }
1313 let Constraints = "$src1 = $dst", AddedComplexity = 20 in {
1314   def MOVLHPSrr : PSI<0x16, MRMSrcReg, (outs VR128:$dst),
1315                                        (ins VR128:$src1, VR128:$src2),
1316                       "movlhps\t{$src2, $dst|$dst, $src2}",
1317                       [(set VR128:$dst,
1318                         (v4f32 (movlhps VR128:$src1, VR128:$src2)))]>;
1319   def MOVHLPSrr : PSI<0x12, MRMSrcReg, (outs VR128:$dst),
1320                                        (ins VR128:$src1, VR128:$src2),
1321                       "movhlps\t{$src2, $dst|$dst, $src2}",
1322                       [(set VR128:$dst,
1323                         (v4f32 (movhlps VR128:$src1, VR128:$src2)))]>;
1324 }
1325
1326 let Predicates = [HasAVX] in {
1327   // MOVLHPS patterns
1328   let AddedComplexity = 20 in {
1329     def : Pat<(v4f32 (movddup VR128:$src, (undef))),
1330               (VMOVLHPSrr (v4f32 VR128:$src), (v4f32 VR128:$src))>;
1331     def : Pat<(v2i64 (movddup VR128:$src, (undef))),
1332               (VMOVLHPSrr (v2i64 VR128:$src), (v2i64 VR128:$src))>;
1333
1334     // vector_shuffle v1, v2 <0, 1, 4, 5> using MOVLHPS
1335     def : Pat<(v4i32 (movlhps VR128:$src1, VR128:$src2)),
1336               (VMOVLHPSrr VR128:$src1, VR128:$src2)>;
1337   }
1338   def : Pat<(v4f32 (X86Movlhps VR128:$src1, VR128:$src2)),
1339             (VMOVLHPSrr VR128:$src1, VR128:$src2)>;
1340   def : Pat<(v4i32 (X86Movlhps VR128:$src1, VR128:$src2)),
1341             (VMOVLHPSrr VR128:$src1, VR128:$src2)>;
1342   def : Pat<(v2i64 (X86Movlhps VR128:$src1, VR128:$src2)),
1343             (VMOVLHPSrr (v2i64 VR128:$src1), VR128:$src2)>;
1344
1345   // MOVHLPS patterns
1346   let AddedComplexity = 20 in {
1347     // vector_shuffle v1, v2 <6, 7, 2, 3> using MOVHLPS
1348     def : Pat<(v4i32 (movhlps VR128:$src1, VR128:$src2)),
1349               (VMOVHLPSrr VR128:$src1, VR128:$src2)>;
1350
1351     // vector_shuffle v1, undef <2, ?, ?, ?> using MOVHLPS
1352     def : Pat<(v4f32 (movhlps_undef VR128:$src1, (undef))),
1353               (VMOVHLPSrr VR128:$src1, VR128:$src1)>;
1354     def : Pat<(v4i32 (movhlps_undef VR128:$src1, (undef))),
1355               (VMOVHLPSrr VR128:$src1, VR128:$src1)>;
1356   }
1357
1358   def : Pat<(v4f32 (X86Movhlps VR128:$src1, VR128:$src2)),
1359             (VMOVHLPSrr VR128:$src1, VR128:$src2)>;
1360   def : Pat<(v4i32 (X86Movhlps VR128:$src1, VR128:$src2)),
1361             (VMOVHLPSrr VR128:$src1, VR128:$src2)>;
1362 }
1363
1364 let Predicates = [HasSSE1] in {
1365   // MOVLHPS patterns
1366   let AddedComplexity = 20 in {
1367     def : Pat<(v4f32 (movddup VR128:$src, (undef))),
1368               (MOVLHPSrr (v4f32 VR128:$src), (v4f32 VR128:$src))>;
1369     def : Pat<(v2i64 (movddup VR128:$src, (undef))),
1370               (MOVLHPSrr (v2i64 VR128:$src), (v2i64 VR128:$src))>;
1371
1372     // vector_shuffle v1, v2 <0, 1, 4, 5> using MOVLHPS
1373     def : Pat<(v4i32 (movlhps VR128:$src1, VR128:$src2)),
1374               (MOVLHPSrr VR128:$src1, VR128:$src2)>;
1375   }
1376   def : Pat<(v4f32 (X86Movlhps VR128:$src1, VR128:$src2)),
1377             (MOVLHPSrr VR128:$src1, VR128:$src2)>;
1378   def : Pat<(v4i32 (X86Movlhps VR128:$src1, VR128:$src2)),
1379             (MOVLHPSrr VR128:$src1, VR128:$src2)>;
1380   def : Pat<(v2i64 (X86Movlhps VR128:$src1, VR128:$src2)),
1381             (MOVLHPSrr (v2i64 VR128:$src1), VR128:$src2)>;
1382
1383   // MOVHLPS patterns
1384   let AddedComplexity = 20 in {
1385     // vector_shuffle v1, v2 <6, 7, 2, 3> using MOVHLPS
1386     def : Pat<(v4i32 (movhlps VR128:$src1, VR128:$src2)),
1387               (MOVHLPSrr VR128:$src1, VR128:$src2)>;
1388
1389     // vector_shuffle v1, undef <2, ?, ?, ?> using MOVHLPS
1390     def : Pat<(v4f32 (movhlps_undef VR128:$src1, (undef))),
1391               (MOVHLPSrr VR128:$src1, VR128:$src1)>;
1392     def : Pat<(v4i32 (movhlps_undef VR128:$src1, (undef))),
1393               (MOVHLPSrr VR128:$src1, VR128:$src1)>;
1394   }
1395
1396   def : Pat<(v4f32 (X86Movhlps VR128:$src1, VR128:$src2)),
1397             (MOVHLPSrr VR128:$src1, VR128:$src2)>;
1398   def : Pat<(v4i32 (X86Movhlps VR128:$src1, VR128:$src2)),
1399             (MOVHLPSrr VR128:$src1, VR128:$src2)>;
1400 }
1401
1402 //===----------------------------------------------------------------------===//
1403 // SSE 1 & 2 - Conversion Instructions
1404 //===----------------------------------------------------------------------===//
1405
1406 multiclass sse12_cvt_s<bits<8> opc, RegisterClass SrcRC, RegisterClass DstRC,
1407                      SDNode OpNode, X86MemOperand x86memop, PatFrag ld_frag,
1408                      string asm> {
1409   def rr : SI<opc, MRMSrcReg, (outs DstRC:$dst), (ins SrcRC:$src), asm,
1410                         [(set DstRC:$dst, (OpNode SrcRC:$src))]>;
1411   def rm : SI<opc, MRMSrcMem, (outs DstRC:$dst), (ins x86memop:$src), asm,
1412                         [(set DstRC:$dst, (OpNode (ld_frag addr:$src)))]>;
1413 }
1414
1415 multiclass sse12_cvt_s_np<bits<8> opc, RegisterClass SrcRC, RegisterClass DstRC,
1416                           X86MemOperand x86memop, string asm> {
1417 let neverHasSideEffects = 1 in {
1418   def rr : SI<opc, MRMSrcReg, (outs DstRC:$dst), (ins SrcRC:$src), asm, []>;
1419   let mayLoad = 1 in
1420   def rm : SI<opc, MRMSrcMem, (outs DstRC:$dst), (ins x86memop:$src), asm, []>;
1421 } // neverHasSideEffects = 1
1422 }
1423
1424 multiclass sse12_cvt_p<bits<8> opc, RegisterClass SrcRC, RegisterClass DstRC,
1425                          SDNode OpNode, X86MemOperand x86memop, PatFrag ld_frag,
1426                          string asm, Domain d> {
1427   def rr : PI<opc, MRMSrcReg, (outs DstRC:$dst), (ins SrcRC:$src), asm,
1428                         [(set DstRC:$dst, (OpNode SrcRC:$src))], d>;
1429   def rm : PI<opc, MRMSrcMem, (outs DstRC:$dst), (ins x86memop:$src), asm,
1430                         [(set DstRC:$dst, (OpNode (ld_frag addr:$src)))], d>;
1431 }
1432
1433 multiclass sse12_vcvt_avx<bits<8> opc, RegisterClass SrcRC, RegisterClass DstRC,
1434                           X86MemOperand x86memop, string asm> {
1435 let neverHasSideEffects = 1 in {
1436   def rr : SI<opc, MRMSrcReg, (outs DstRC:$dst), (ins DstRC:$src1, SrcRC:$src),
1437               !strconcat(asm,"\t{$src, $src1, $dst|$dst, $src1, $src}"), []>;
1438   let mayLoad = 1 in
1439   def rm : SI<opc, MRMSrcMem, (outs DstRC:$dst),
1440               (ins DstRC:$src1, x86memop:$src),
1441               !strconcat(asm,"\t{$src, $src1, $dst|$dst, $src1, $src}"), []>;
1442 } // neverHasSideEffects = 1
1443 }
1444
1445 defm VCVTTSS2SI   : sse12_cvt_s<0x2C, FR32, GR32, fp_to_sint, f32mem, loadf32,
1446                                 "cvttss2si\t{$src, $dst|$dst, $src}">, XS, VEX,
1447                                 VEX_LIG;
1448 defm VCVTTSS2SI64 : sse12_cvt_s<0x2C, FR32, GR64, fp_to_sint, f32mem, loadf32,
1449                                 "cvttss2si\t{$src, $dst|$dst, $src}">, XS, VEX,
1450                                 VEX_W, VEX_LIG;
1451 defm VCVTTSD2SI   : sse12_cvt_s<0x2C, FR64, GR32, fp_to_sint, f64mem, loadf64,
1452                                 "cvttsd2si\t{$src, $dst|$dst, $src}">, XD, VEX,
1453                                 VEX_LIG;
1454 defm VCVTTSD2SI64 : sse12_cvt_s<0x2C, FR64, GR64, fp_to_sint, f64mem, loadf64,
1455                                 "cvttsd2si\t{$src, $dst|$dst, $src}">, XD,
1456                                 VEX, VEX_W, VEX_LIG;
1457
1458 // The assembler can recognize rr 64-bit instructions by seeing a rxx
1459 // register, but the same isn't true when only using memory operands,
1460 // provide other assembly "l" and "q" forms to address this explicitly
1461 // where appropriate to do so.
1462 defm VCVTSI2SS   : sse12_vcvt_avx<0x2A, GR32, FR32, i32mem, "cvtsi2ss">, XS,
1463                                   VEX_4V, VEX_LIG;
1464 defm VCVTSI2SS64 : sse12_vcvt_avx<0x2A, GR64, FR32, i64mem, "cvtsi2ss{q}">, XS,
1465                                   VEX_4V, VEX_W, VEX_LIG;
1466 defm VCVTSI2SD   : sse12_vcvt_avx<0x2A, GR32, FR64, i32mem, "cvtsi2sd">, XD,
1467                                   VEX_4V, VEX_LIG;
1468 defm VCVTSI2SDL  : sse12_vcvt_avx<0x2A, GR32, FR64, i32mem, "cvtsi2sd{l}">, XD,
1469                                   VEX_4V, VEX_LIG;
1470 defm VCVTSI2SD64 : sse12_vcvt_avx<0x2A, GR64, FR64, i64mem, "cvtsi2sd{q}">, XD,
1471                                   VEX_4V, VEX_W, VEX_LIG;
1472
1473 let Predicates = [HasAVX], AddedComplexity = 1 in {
1474   def : Pat<(f32 (sint_to_fp (loadi32 addr:$src))),
1475             (VCVTSI2SSrm (f32 (IMPLICIT_DEF)), addr:$src)>;
1476   def : Pat<(f32 (sint_to_fp (loadi64 addr:$src))),
1477             (VCVTSI2SS64rm (f32 (IMPLICIT_DEF)), addr:$src)>;
1478   def : Pat<(f64 (sint_to_fp (loadi32 addr:$src))),
1479             (VCVTSI2SDrm (f64 (IMPLICIT_DEF)), addr:$src)>;
1480   def : Pat<(f64 (sint_to_fp (loadi64 addr:$src))),
1481             (VCVTSI2SD64rm (f64 (IMPLICIT_DEF)), addr:$src)>;
1482
1483   def : Pat<(f32 (sint_to_fp GR32:$src)),
1484             (VCVTSI2SSrr (f32 (IMPLICIT_DEF)), GR32:$src)>;
1485   def : Pat<(f32 (sint_to_fp GR64:$src)),
1486             (VCVTSI2SS64rr (f32 (IMPLICIT_DEF)), GR64:$src)>;
1487   def : Pat<(f64 (sint_to_fp GR32:$src)),
1488             (VCVTSI2SDrr (f64 (IMPLICIT_DEF)), GR32:$src)>;
1489   def : Pat<(f64 (sint_to_fp GR64:$src)),
1490             (VCVTSI2SD64rr (f64 (IMPLICIT_DEF)), GR64:$src)>;
1491 }
1492
1493 defm CVTTSS2SI : sse12_cvt_s<0x2C, FR32, GR32, fp_to_sint, f32mem, loadf32,
1494                       "cvttss2si\t{$src, $dst|$dst, $src}">, XS;
1495 defm CVTTSS2SI64 : sse12_cvt_s<0x2C, FR32, GR64, fp_to_sint, f32mem, loadf32,
1496                       "cvttss2si{q}\t{$src, $dst|$dst, $src}">, XS, REX_W;
1497 defm CVTTSD2SI : sse12_cvt_s<0x2C, FR64, GR32, fp_to_sint, f64mem, loadf64,
1498                       "cvttsd2si\t{$src, $dst|$dst, $src}">, XD;
1499 defm CVTTSD2SI64 : sse12_cvt_s<0x2C, FR64, GR64, fp_to_sint, f64mem, loadf64,
1500                       "cvttsd2si{q}\t{$src, $dst|$dst, $src}">, XD, REX_W;
1501 defm CVTSI2SS  : sse12_cvt_s<0x2A, GR32, FR32, sint_to_fp, i32mem, loadi32,
1502                       "cvtsi2ss\t{$src, $dst|$dst, $src}">, XS;
1503 defm CVTSI2SS64 : sse12_cvt_s<0x2A, GR64, FR32, sint_to_fp, i64mem, loadi64,
1504                       "cvtsi2ss{q}\t{$src, $dst|$dst, $src}">, XS, REX_W;
1505 defm CVTSI2SD  : sse12_cvt_s<0x2A, GR32, FR64, sint_to_fp, i32mem, loadi32,
1506                       "cvtsi2sd\t{$src, $dst|$dst, $src}">, XD;
1507 defm CVTSI2SD64 : sse12_cvt_s<0x2A, GR64, FR64, sint_to_fp, i64mem, loadi64,
1508                       "cvtsi2sd{q}\t{$src, $dst|$dst, $src}">, XD, REX_W;
1509
1510 // Conversion Instructions Intrinsics - Match intrinsics which expect MM
1511 // and/or XMM operand(s).
1512
1513 multiclass sse12_cvt_sint<bits<8> opc, RegisterClass SrcRC, RegisterClass DstRC,
1514                          Intrinsic Int, X86MemOperand x86memop, PatFrag ld_frag,
1515                          string asm> {
1516   def rr : SI<opc, MRMSrcReg, (outs DstRC:$dst), (ins SrcRC:$src),
1517               !strconcat(asm, "\t{$src, $dst|$dst, $src}"),
1518               [(set DstRC:$dst, (Int SrcRC:$src))]>;
1519   def rm : SI<opc, MRMSrcMem, (outs DstRC:$dst), (ins x86memop:$src),
1520               !strconcat(asm, "\t{$src, $dst|$dst, $src}"),
1521               [(set DstRC:$dst, (Int (ld_frag addr:$src)))]>;
1522 }
1523
1524 multiclass sse12_cvt_sint_3addr<bits<8> opc, RegisterClass SrcRC,
1525                     RegisterClass DstRC, Intrinsic Int, X86MemOperand x86memop,
1526                     PatFrag ld_frag, string asm, bit Is2Addr = 1> {
1527   def rr : SI<opc, MRMSrcReg, (outs DstRC:$dst), (ins DstRC:$src1, SrcRC:$src2),
1528               !if(Is2Addr,
1529                   !strconcat(asm, "\t{$src2, $dst|$dst, $src2}"),
1530                   !strconcat(asm, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
1531               [(set DstRC:$dst, (Int DstRC:$src1, SrcRC:$src2))]>;
1532   def rm : SI<opc, MRMSrcMem, (outs DstRC:$dst),
1533               (ins DstRC:$src1, x86memop:$src2),
1534               !if(Is2Addr,
1535                   !strconcat(asm, "\t{$src2, $dst|$dst, $src2}"),
1536                   !strconcat(asm, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
1537               [(set DstRC:$dst, (Int DstRC:$src1, (ld_frag addr:$src2)))]>;
1538 }
1539
1540 defm Int_VCVTSD2SI : sse12_cvt_sint<0x2D, VR128, GR32, int_x86_sse2_cvtsd2si,
1541                       f128mem, load, "cvtsd2si">, XD, VEX;
1542 defm Int_VCVTSD2SI64 : sse12_cvt_sint<0x2D, VR128, GR64,
1543                       int_x86_sse2_cvtsd2si64, f128mem, load, "cvtsd2si">,
1544                       XD, VEX, VEX_W;
1545
1546 // FIXME: The asm matcher has a hack to ignore instructions with _Int and Int_
1547 // Get rid of this hack or rename the intrinsics, there are several
1548 // intructions that only match with the intrinsic form, why create duplicates
1549 // to let them be recognized by the assembler?
1550 defm VCVTSD2SI     : sse12_cvt_s_np<0x2D, FR64, GR32, f64mem,
1551                       "cvtsd2si\t{$src, $dst|$dst, $src}">, XD, VEX, VEX_LIG;
1552 defm VCVTSD2SI64   : sse12_cvt_s_np<0x2D, FR64, GR64, f64mem,
1553                       "cvtsd2si\t{$src, $dst|$dst, $src}">, XD, VEX, VEX_W,
1554                       VEX_LIG;
1555
1556 defm CVTSD2SI : sse12_cvt_sint<0x2D, VR128, GR32, int_x86_sse2_cvtsd2si,
1557                 f128mem, load, "cvtsd2si{l}">, XD;
1558 defm CVTSD2SI64 : sse12_cvt_sint<0x2D, VR128, GR64, int_x86_sse2_cvtsd2si64,
1559                   f128mem, load, "cvtsd2si{q}">, XD, REX_W;
1560
1561
1562 defm Int_VCVTSI2SS : sse12_cvt_sint_3addr<0x2A, GR32, VR128,
1563           int_x86_sse_cvtsi2ss, i32mem, loadi32, "cvtsi2ss", 0>, XS, VEX_4V;
1564 defm Int_VCVTSI2SS64 : sse12_cvt_sint_3addr<0x2A, GR64, VR128,
1565           int_x86_sse_cvtsi642ss, i64mem, loadi64, "cvtsi2ss", 0>, XS, VEX_4V,
1566           VEX_W;
1567 defm Int_VCVTSI2SD : sse12_cvt_sint_3addr<0x2A, GR32, VR128,
1568           int_x86_sse2_cvtsi2sd, i32mem, loadi32, "cvtsi2sd", 0>, XD, VEX_4V;
1569 defm Int_VCVTSI2SD64 : sse12_cvt_sint_3addr<0x2A, GR64, VR128,
1570           int_x86_sse2_cvtsi642sd, i64mem, loadi64, "cvtsi2sd", 0>, XD,
1571           VEX_4V, VEX_W;
1572
1573 let Constraints = "$src1 = $dst" in {
1574   defm Int_CVTSI2SS : sse12_cvt_sint_3addr<0x2A, GR32, VR128,
1575                         int_x86_sse_cvtsi2ss, i32mem, loadi32,
1576                         "cvtsi2ss">, XS;
1577   defm Int_CVTSI2SS64 : sse12_cvt_sint_3addr<0x2A, GR64, VR128,
1578                         int_x86_sse_cvtsi642ss, i64mem, loadi64,
1579                         "cvtsi2ss{q}">, XS, REX_W;
1580   defm Int_CVTSI2SD : sse12_cvt_sint_3addr<0x2A, GR32, VR128,
1581                         int_x86_sse2_cvtsi2sd, i32mem, loadi32,
1582                         "cvtsi2sd">, XD;
1583   defm Int_CVTSI2SD64 : sse12_cvt_sint_3addr<0x2A, GR64, VR128,
1584                         int_x86_sse2_cvtsi642sd, i64mem, loadi64,
1585                         "cvtsi2sd">, XD, REX_W;
1586 }
1587
1588 /// SSE 1 Only
1589
1590 // Aliases for intrinsics
1591 defm Int_VCVTTSS2SI : sse12_cvt_sint<0x2C, VR128, GR32, int_x86_sse_cvttss2si,
1592                                     f32mem, load, "cvttss2si">, XS, VEX;
1593 defm Int_VCVTTSS2SI64 : sse12_cvt_sint<0x2C, VR128, GR64,
1594                                     int_x86_sse_cvttss2si64, f32mem, load,
1595                                     "cvttss2si">, XS, VEX, VEX_W;
1596 defm Int_VCVTTSD2SI : sse12_cvt_sint<0x2C, VR128, GR32, int_x86_sse2_cvttsd2si,
1597                                     f128mem, load, "cvttsd2si">, XD, VEX;
1598 defm Int_VCVTTSD2SI64 : sse12_cvt_sint<0x2C, VR128, GR64,
1599                                     int_x86_sse2_cvttsd2si64, f128mem, load,
1600                                     "cvttsd2si">, XD, VEX, VEX_W;
1601 defm Int_CVTTSS2SI : sse12_cvt_sint<0x2C, VR128, GR32, int_x86_sse_cvttss2si,
1602                                     f32mem, load, "cvttss2si">, XS;
1603 defm Int_CVTTSS2SI64 : sse12_cvt_sint<0x2C, VR128, GR64,
1604                                     int_x86_sse_cvttss2si64, f32mem, load,
1605                                     "cvttss2si{q}">, XS, REX_W;
1606 defm Int_CVTTSD2SI : sse12_cvt_sint<0x2C, VR128, GR32, int_x86_sse2_cvttsd2si,
1607                                     f128mem, load, "cvttsd2si">, XD;
1608 defm Int_CVTTSD2SI64 : sse12_cvt_sint<0x2C, VR128, GR64,
1609                                     int_x86_sse2_cvttsd2si64, f128mem, load,
1610                                     "cvttsd2si{q}">, XD, REX_W;
1611
1612 let Pattern = []<dag> in {
1613 defm VCVTSS2SI   : sse12_cvt_s<0x2D, FR32, GR32, undef, f32mem, load,
1614                                "cvtss2si{l}\t{$src, $dst|$dst, $src}">, XS,
1615                                VEX, VEX_LIG;
1616 defm VCVTSS2SI64 : sse12_cvt_s<0x2D, FR32, GR64, undef, f32mem, load,
1617                                "cvtss2si\t{$src, $dst|$dst, $src}">, XS, VEX,
1618                                VEX_W, VEX_LIG;
1619 defm VCVTDQ2PS   : sse12_cvt_p<0x5B, VR128, VR128, undef, i128mem, load,
1620                                "cvtdq2ps\t{$src, $dst|$dst, $src}",
1621                                SSEPackedSingle>, TB, VEX;
1622 defm VCVTDQ2PSY  : sse12_cvt_p<0x5B, VR256, VR256, undef, i256mem, load,
1623                                "cvtdq2ps\t{$src, $dst|$dst, $src}",
1624                                SSEPackedSingle>, TB, VEX;
1625 }
1626
1627 let Pattern = []<dag> in {
1628 defm CVTSS2SI : sse12_cvt_s<0x2D, FR32, GR32, undef, f32mem, load /*dummy*/,
1629                           "cvtss2si{l}\t{$src, $dst|$dst, $src}">, XS;
1630 defm CVTSS2SI64 : sse12_cvt_s<0x2D, FR32, GR64, undef, f32mem, load /*dummy*/,
1631                           "cvtss2si{q}\t{$src, $dst|$dst, $src}">, XS, REX_W;
1632 defm CVTDQ2PS : sse12_cvt_p<0x5B, VR128, VR128, undef, i128mem, load /*dummy*/,
1633                             "cvtdq2ps\t{$src, $dst|$dst, $src}",
1634                             SSEPackedSingle>, TB; /* PD SSE3 form is avaiable */
1635 }
1636
1637 let Predicates = [HasAVX] in {
1638   def : Pat<(int_x86_sse_cvtss2si VR128:$src),
1639             (VCVTSS2SIrr (EXTRACT_SUBREG (v4f32 VR128:$src), sub_ss))>;
1640   def : Pat<(int_x86_sse_cvtss2si (load addr:$src)),
1641             (VCVTSS2SIrm addr:$src)>;
1642   def : Pat<(int_x86_sse_cvtss2si64 VR128:$src),
1643             (VCVTSS2SI64rr (EXTRACT_SUBREG (v4f32 VR128:$src), sub_ss))>;
1644   def : Pat<(int_x86_sse_cvtss2si64 (load addr:$src)),
1645             (VCVTSS2SI64rm addr:$src)>;
1646 }
1647
1648 let Predicates = [HasSSE1] in {
1649   def : Pat<(int_x86_sse_cvtss2si VR128:$src),
1650             (CVTSS2SIrr (EXTRACT_SUBREG (v4f32 VR128:$src), sub_ss))>;
1651   def : Pat<(int_x86_sse_cvtss2si (load addr:$src)),
1652             (CVTSS2SIrm addr:$src)>;
1653   def : Pat<(int_x86_sse_cvtss2si64 VR128:$src),
1654             (CVTSS2SI64rr (EXTRACT_SUBREG (v4f32 VR128:$src), sub_ss))>;
1655   def : Pat<(int_x86_sse_cvtss2si64 (load addr:$src)),
1656             (CVTSS2SI64rm addr:$src)>;
1657 }
1658
1659 /// SSE 2 Only
1660
1661 // Convert scalar double to scalar single
1662 def VCVTSD2SSrr  : VSDI<0x5A, MRMSrcReg, (outs FR32:$dst),
1663                        (ins FR64:$src1, FR64:$src2),
1664                       "cvtsd2ss\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>,
1665                       VEX_4V, VEX_LIG;
1666 let mayLoad = 1 in
1667 def VCVTSD2SSrm  : I<0x5A, MRMSrcMem, (outs FR32:$dst),
1668                        (ins FR64:$src1, f64mem:$src2),
1669                       "vcvtsd2ss\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1670                       []>, XD, Requires<[HasAVX, OptForSize]>, VEX_4V, VEX_LIG;
1671
1672 def : Pat<(f32 (fround FR64:$src)), (VCVTSD2SSrr FR64:$src, FR64:$src)>,
1673           Requires<[HasAVX]>;
1674
1675 def CVTSD2SSrr  : SDI<0x5A, MRMSrcReg, (outs FR32:$dst), (ins FR64:$src),
1676                       "cvtsd2ss\t{$src, $dst|$dst, $src}",
1677                       [(set FR32:$dst, (fround FR64:$src))]>;
1678 def CVTSD2SSrm  : I<0x5A, MRMSrcMem, (outs FR32:$dst), (ins f64mem:$src),
1679                       "cvtsd2ss\t{$src, $dst|$dst, $src}",
1680                       [(set FR32:$dst, (fround (loadf64 addr:$src)))]>, XD,
1681                   Requires<[HasSSE2, OptForSize]>;
1682
1683 defm Int_VCVTSD2SS: sse12_cvt_sint_3addr<0x5A, VR128, VR128,
1684                       int_x86_sse2_cvtsd2ss, f64mem, load, "cvtsd2ss", 0>,
1685                       XS, VEX_4V;
1686 let Constraints = "$src1 = $dst" in
1687 defm Int_CVTSD2SS: sse12_cvt_sint_3addr<0x5A, VR128, VR128,
1688                       int_x86_sse2_cvtsd2ss, f64mem, load, "cvtsd2ss">, XS;
1689
1690 // Convert scalar single to scalar double
1691 // SSE2 instructions with XS prefix
1692 def VCVTSS2SDrr : I<0x5A, MRMSrcReg, (outs FR64:$dst),
1693                     (ins FR32:$src1, FR32:$src2),
1694                     "vcvtss2sd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1695                     []>, XS, Requires<[HasAVX]>, VEX_4V, VEX_LIG;
1696 let mayLoad = 1 in
1697 def VCVTSS2SDrm : I<0x5A, MRMSrcMem, (outs FR64:$dst),
1698                     (ins FR32:$src1, f32mem:$src2),
1699                     "vcvtss2sd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1700                     []>, XS, VEX_4V, VEX_LIG, Requires<[HasAVX, OptForSize]>;
1701
1702 let Predicates = [HasAVX] in {
1703   def : Pat<(f64 (fextend FR32:$src)),
1704             (VCVTSS2SDrr FR32:$src, FR32:$src)>;
1705   def : Pat<(fextend (loadf32 addr:$src)),
1706             (VCVTSS2SDrm (f32 (IMPLICIT_DEF)), addr:$src)>;
1707   def : Pat<(extloadf32 addr:$src),
1708             (VCVTSS2SDrm (f32 (IMPLICIT_DEF)), addr:$src)>;
1709 }
1710
1711 def : Pat<(extloadf32 addr:$src),
1712           (VCVTSS2SDrr (f32 (IMPLICIT_DEF)), (MOVSSrm addr:$src))>,
1713           Requires<[HasAVX, OptForSpeed]>;
1714
1715 def CVTSS2SDrr : I<0x5A, MRMSrcReg, (outs FR64:$dst), (ins FR32:$src),
1716                    "cvtss2sd\t{$src, $dst|$dst, $src}",
1717                    [(set FR64:$dst, (fextend FR32:$src))]>, XS,
1718                  Requires<[HasSSE2]>;
1719 def CVTSS2SDrm : I<0x5A, MRMSrcMem, (outs FR64:$dst), (ins f32mem:$src),
1720                    "cvtss2sd\t{$src, $dst|$dst, $src}",
1721                    [(set FR64:$dst, (extloadf32 addr:$src))]>, XS,
1722                  Requires<[HasSSE2, OptForSize]>;
1723
1724 // extload f32 -> f64.  This matches load+fextend because we have a hack in
1725 // the isel (PreprocessForFPConvert) that can introduce loads after dag
1726 // combine.
1727 // Since these loads aren't folded into the fextend, we have to match it
1728 // explicitly here.
1729 def : Pat<(fextend (loadf32 addr:$src)),
1730           (CVTSS2SDrm addr:$src)>, Requires<[HasSSE2]>;
1731 def : Pat<(extloadf32 addr:$src),
1732           (CVTSS2SDrr (MOVSSrm addr:$src))>, Requires<[HasSSE2, OptForSpeed]>;
1733
1734 def Int_VCVTSS2SDrr: I<0x5A, MRMSrcReg,
1735                       (outs VR128:$dst), (ins VR128:$src1, VR128:$src2),
1736                     "vcvtss2sd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1737                     [(set VR128:$dst, (int_x86_sse2_cvtss2sd VR128:$src1,
1738                                        VR128:$src2))]>, XS, VEX_4V,
1739                     Requires<[HasAVX]>;
1740 def Int_VCVTSS2SDrm: I<0x5A, MRMSrcMem,
1741                       (outs VR128:$dst), (ins VR128:$src1, f32mem:$src2),
1742                     "vcvtss2sd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1743                     [(set VR128:$dst, (int_x86_sse2_cvtss2sd VR128:$src1,
1744                                        (load addr:$src2)))]>, XS, VEX_4V,
1745                     Requires<[HasAVX]>;
1746 let Constraints = "$src1 = $dst" in { // SSE2 instructions with XS prefix
1747 def Int_CVTSS2SDrr: I<0x5A, MRMSrcReg,
1748                       (outs VR128:$dst), (ins VR128:$src1, VR128:$src2),
1749                     "cvtss2sd\t{$src2, $dst|$dst, $src2}",
1750                     [(set VR128:$dst, (int_x86_sse2_cvtss2sd VR128:$src1,
1751                                        VR128:$src2))]>, XS,
1752                     Requires<[HasSSE2]>;
1753 def Int_CVTSS2SDrm: I<0x5A, MRMSrcMem,
1754                       (outs VR128:$dst), (ins VR128:$src1, f32mem:$src2),
1755                     "cvtss2sd\t{$src2, $dst|$dst, $src2}",
1756                     [(set VR128:$dst, (int_x86_sse2_cvtss2sd VR128:$src1,
1757                                        (load addr:$src2)))]>, XS,
1758                     Requires<[HasSSE2]>;
1759 }
1760
1761 // Convert doubleword to packed single/double fp
1762 // SSE2 instructions without OpSize prefix
1763 def Int_VCVTDQ2PSrr : I<0x5B, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1764                        "vcvtdq2ps\t{$src, $dst|$dst, $src}",
1765                        [(set VR128:$dst, (int_x86_sse2_cvtdq2ps VR128:$src))]>,
1766                      TB, VEX, Requires<[HasAVX]>;
1767 def Int_VCVTDQ2PSrm : I<0x5B, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
1768                       "vcvtdq2ps\t{$src, $dst|$dst, $src}",
1769                       [(set VR128:$dst, (int_x86_sse2_cvtdq2ps
1770                                         (bitconvert (memopv2i64 addr:$src))))]>,
1771                      TB, VEX, Requires<[HasAVX]>;
1772 def Int_CVTDQ2PSrr : I<0x5B, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1773                        "cvtdq2ps\t{$src, $dst|$dst, $src}",
1774                        [(set VR128:$dst, (int_x86_sse2_cvtdq2ps VR128:$src))]>,
1775                      TB, Requires<[HasSSE2]>;
1776 def Int_CVTDQ2PSrm : I<0x5B, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
1777                       "cvtdq2ps\t{$src, $dst|$dst, $src}",
1778                       [(set VR128:$dst, (int_x86_sse2_cvtdq2ps
1779                                         (bitconvert (memopv2i64 addr:$src))))]>,
1780                      TB, Requires<[HasSSE2]>;
1781
1782 // FIXME: why the non-intrinsic version is described as SSE3?
1783 // SSE2 instructions with XS prefix
1784 def Int_VCVTDQ2PDrr : I<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1785                        "vcvtdq2pd\t{$src, $dst|$dst, $src}",
1786                        [(set VR128:$dst, (int_x86_sse2_cvtdq2pd VR128:$src))]>,
1787                      XS, VEX, Requires<[HasAVX]>;
1788 def Int_VCVTDQ2PDrm : I<0xE6, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
1789                        "vcvtdq2pd\t{$src, $dst|$dst, $src}",
1790                        [(set VR128:$dst, (int_x86_sse2_cvtdq2pd
1791                                         (bitconvert (memopv2i64 addr:$src))))]>,
1792                      XS, VEX, Requires<[HasAVX]>;
1793 def Int_CVTDQ2PDrr : I<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1794                        "cvtdq2pd\t{$src, $dst|$dst, $src}",
1795                        [(set VR128:$dst, (int_x86_sse2_cvtdq2pd VR128:$src))]>,
1796                      XS, Requires<[HasSSE2]>;
1797 def Int_CVTDQ2PDrm : I<0xE6, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
1798                      "cvtdq2pd\t{$src, $dst|$dst, $src}",
1799                      [(set VR128:$dst, (int_x86_sse2_cvtdq2pd
1800                                         (bitconvert (memopv2i64 addr:$src))))]>,
1801                      XS, Requires<[HasSSE2]>;
1802
1803
1804 // Convert packed single/double fp to doubleword
1805 def VCVTPS2DQrr : VPDI<0x5B, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1806                        "cvtps2dq\t{$src, $dst|$dst, $src}", []>, VEX;
1807 def VCVTPS2DQrm : VPDI<0x5B, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1808                        "cvtps2dq\t{$src, $dst|$dst, $src}", []>, VEX;
1809 def VCVTPS2DQYrr : VPDI<0x5B, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
1810                         "cvtps2dq\t{$src, $dst|$dst, $src}", []>, VEX;
1811 def VCVTPS2DQYrm : VPDI<0x5B, MRMSrcMem, (outs VR256:$dst), (ins f256mem:$src),
1812                         "cvtps2dq\t{$src, $dst|$dst, $src}", []>, VEX;
1813 def CVTPS2DQrr : PDI<0x5B, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1814                      "cvtps2dq\t{$src, $dst|$dst, $src}", []>;
1815 def CVTPS2DQrm : PDI<0x5B, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1816                      "cvtps2dq\t{$src, $dst|$dst, $src}", []>;
1817
1818 def Int_VCVTPS2DQrr : VPDI<0x5B, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1819                         "cvtps2dq\t{$src, $dst|$dst, $src}",
1820                         [(set VR128:$dst, (int_x86_sse2_cvtps2dq VR128:$src))]>,
1821                         VEX;
1822 def Int_VCVTPS2DQrm : VPDI<0x5B, MRMSrcMem, (outs VR128:$dst),
1823                          (ins f128mem:$src),
1824                          "cvtps2dq\t{$src, $dst|$dst, $src}",
1825                          [(set VR128:$dst, (int_x86_sse2_cvtps2dq
1826                                             (memop addr:$src)))]>, VEX;
1827 def Int_CVTPS2DQrr : PDI<0x5B, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1828                         "cvtps2dq\t{$src, $dst|$dst, $src}",
1829                         [(set VR128:$dst, (int_x86_sse2_cvtps2dq VR128:$src))]>;
1830 def Int_CVTPS2DQrm : PDI<0x5B, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1831                          "cvtps2dq\t{$src, $dst|$dst, $src}",
1832                          [(set VR128:$dst, (int_x86_sse2_cvtps2dq
1833                                             (memop addr:$src)))]>;
1834
1835 // SSE2 packed instructions with XD prefix
1836 def Int_VCVTPD2DQrr : I<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1837                        "vcvtpd2dq\t{$src, $dst|$dst, $src}",
1838                        [(set VR128:$dst, (int_x86_sse2_cvtpd2dq VR128:$src))]>,
1839                      XD, VEX, Requires<[HasAVX]>;
1840 def Int_VCVTPD2DQrm : I<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1841                        "vcvtpd2dq\t{$src, $dst|$dst, $src}",
1842                        [(set VR128:$dst, (int_x86_sse2_cvtpd2dq
1843                                           (memop addr:$src)))]>,
1844                      XD, VEX, Requires<[HasAVX]>;
1845 def Int_CVTPD2DQrr : I<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1846                        "cvtpd2dq\t{$src, $dst|$dst, $src}",
1847                        [(set VR128:$dst, (int_x86_sse2_cvtpd2dq VR128:$src))]>,
1848                      XD, Requires<[HasSSE2]>;
1849 def Int_CVTPD2DQrm : I<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1850                        "cvtpd2dq\t{$src, $dst|$dst, $src}",
1851                        [(set VR128:$dst, (int_x86_sse2_cvtpd2dq
1852                                           (memop addr:$src)))]>,
1853                      XD, Requires<[HasSSE2]>;
1854
1855
1856 // Convert with truncation packed single/double fp to doubleword
1857 // SSE2 packed instructions with XS prefix
1858 def VCVTTPS2DQrr : VSSI<0x5B, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1859                         "cvttps2dq\t{$src, $dst|$dst, $src}",
1860                         [(set VR128:$dst,
1861                           (int_x86_sse2_cvttps2dq VR128:$src))]>, VEX;
1862 def VCVTTPS2DQrm : VSSI<0x5B, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1863                         "cvttps2dq\t{$src, $dst|$dst, $src}",
1864                         [(set VR128:$dst, (int_x86_sse2_cvttps2dq
1865                                            (memop addr:$src)))]>, VEX;
1866 def VCVTTPS2DQYrr : VSSI<0x5B, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
1867                          "cvttps2dq\t{$src, $dst|$dst, $src}",
1868                          [(set VR256:$dst,
1869                            (int_x86_avx_cvtt_ps2dq_256 VR256:$src))]>, VEX;
1870 def VCVTTPS2DQYrm : VSSI<0x5B, MRMSrcMem, (outs VR256:$dst), (ins f256mem:$src),
1871                          "cvttps2dq\t{$src, $dst|$dst, $src}",
1872                          [(set VR256:$dst, (int_x86_avx_cvtt_ps2dq_256
1873                                             (memopv8f32 addr:$src)))]>, VEX;
1874
1875 def CVTTPS2DQrr : SSI<0x5B, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1876                       "cvttps2dq\t{$src, $dst|$dst, $src}",
1877                       [(set VR128:$dst,
1878                             (int_x86_sse2_cvttps2dq VR128:$src))]>;
1879 def CVTTPS2DQrm : SSI<0x5B, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1880                       "cvttps2dq\t{$src, $dst|$dst, $src}",
1881                       [(set VR128:$dst,
1882                             (int_x86_sse2_cvttps2dq (memop addr:$src)))]>;
1883
1884 let Predicates = [HasAVX] in {
1885   def : Pat<(v4f32 (sint_to_fp (v4i32 VR128:$src))),
1886             (Int_VCVTDQ2PSrr VR128:$src)>;
1887   def : Pat<(v4f32 (sint_to_fp (bc_v4i32 (memopv2i64 addr:$src)))),
1888             (Int_VCVTDQ2PSrm addr:$src)>;
1889
1890   def : Pat<(v4i32 (fp_to_sint (v4f32 VR128:$src))),
1891             (VCVTTPS2DQrr VR128:$src)>;
1892   def : Pat<(v4i32 (fp_to_sint (memopv4f32 addr:$src))),
1893             (VCVTTPS2DQrm addr:$src)>;
1894
1895   def : Pat<(v8f32 (sint_to_fp (v8i32 VR256:$src))),
1896             (VCVTDQ2PSYrr VR256:$src)>;
1897   def : Pat<(v8f32 (sint_to_fp (bc_v8i32 (memopv4i64 addr:$src)))),
1898             (VCVTDQ2PSYrm addr:$src)>;
1899
1900   def : Pat<(v8i32 (fp_to_sint (v8f32 VR256:$src))),
1901             (VCVTTPS2DQYrr VR256:$src)>;
1902   def : Pat<(v8i32 (fp_to_sint (memopv8f32 addr:$src))),
1903             (VCVTTPS2DQYrm addr:$src)>;
1904 }
1905
1906 let Predicates = [HasSSE2] in {
1907   def : Pat<(v4f32 (sint_to_fp (v4i32 VR128:$src))),
1908             (Int_CVTDQ2PSrr VR128:$src)>;
1909   def : Pat<(v4f32 (sint_to_fp (bc_v4i32 (memopv2i64 addr:$src)))),
1910             (Int_CVTDQ2PSrm addr:$src)>;
1911
1912   def : Pat<(v4i32 (fp_to_sint (v4f32 VR128:$src))),
1913             (CVTTPS2DQrr VR128:$src)>;
1914   def : Pat<(v4i32 (fp_to_sint (memopv4f32 addr:$src))),
1915             (CVTTPS2DQrm addr:$src)>;
1916 }
1917
1918 def VCVTTPD2DQrr : VPDI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1919                         "cvttpd2dq\t{$src, $dst|$dst, $src}",
1920                         [(set VR128:$dst,
1921                               (int_x86_sse2_cvttpd2dq VR128:$src))]>, VEX;
1922 let isCodeGenOnly = 1 in
1923 def VCVTTPD2DQrm : VPDI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1924                         "cvttpd2dq\t{$src, $dst|$dst, $src}",
1925                         [(set VR128:$dst, (int_x86_sse2_cvttpd2dq
1926                                                (memop addr:$src)))]>, VEX;
1927 def CVTTPD2DQrr : PDI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1928                       "cvttpd2dq\t{$src, $dst|$dst, $src}",
1929                       [(set VR128:$dst, (int_x86_sse2_cvttpd2dq VR128:$src))]>;
1930 def CVTTPD2DQrm : PDI<0xE6, MRMSrcMem, (outs VR128:$dst),(ins f128mem:$src),
1931                       "cvttpd2dq\t{$src, $dst|$dst, $src}",
1932                       [(set VR128:$dst, (int_x86_sse2_cvttpd2dq
1933                                         (memop addr:$src)))]>;
1934
1935 // The assembler can recognize rr 256-bit instructions by seeing a ymm
1936 // register, but the same isn't true when using memory operands instead.
1937 // Provide other assembly rr and rm forms to address this explicitly.
1938 def VCVTTPD2DQXrYr : VPDI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR256:$src),
1939                           "cvttpd2dq\t{$src, $dst|$dst, $src}", []>, VEX;
1940
1941 // XMM only
1942 def VCVTTPD2DQXrr : VPDI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1943                          "cvttpd2dqx\t{$src, $dst|$dst, $src}", []>, VEX;
1944 def VCVTTPD2DQXrm : VPDI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1945                          "cvttpd2dqx\t{$src, $dst|$dst, $src}", []>, VEX;
1946
1947 // YMM only
1948 def VCVTTPD2DQYrr : VPDI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR256:$src),
1949                          "cvttpd2dqy\t{$src, $dst|$dst, $src}", []>, VEX;
1950 def VCVTTPD2DQYrm : VPDI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f256mem:$src),
1951                          "cvttpd2dqy\t{$src, $dst|$dst, $src}", []>, VEX, VEX_L;
1952
1953 // Convert packed single to packed double
1954 let Predicates = [HasAVX] in {
1955                   // SSE2 instructions without OpSize prefix
1956 def VCVTPS2PDrr : I<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1957                      "vcvtps2pd\t{$src, $dst|$dst, $src}", []>, TB, VEX;
1958 def VCVTPS2PDrm : I<0x5A, MRMSrcMem, (outs VR128:$dst), (ins f64mem:$src),
1959                      "vcvtps2pd\t{$src, $dst|$dst, $src}", []>, TB, VEX;
1960 def VCVTPS2PDYrr : I<0x5A, MRMSrcReg, (outs VR256:$dst), (ins VR128:$src),
1961                      "vcvtps2pd\t{$src, $dst|$dst, $src}", []>, TB, VEX;
1962 def VCVTPS2PDYrm : I<0x5A, MRMSrcMem, (outs VR256:$dst), (ins f128mem:$src),
1963                      "vcvtps2pd\t{$src, $dst|$dst, $src}", []>, TB, VEX;
1964 }
1965 def CVTPS2PDrr : I<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1966                        "cvtps2pd\t{$src, $dst|$dst, $src}", []>, TB;
1967 def CVTPS2PDrm : I<0x5A, MRMSrcMem, (outs VR128:$dst), (ins f64mem:$src),
1968                        "cvtps2pd\t{$src, $dst|$dst, $src}", []>, TB;
1969
1970 def Int_VCVTPS2PDrr : I<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1971                        "vcvtps2pd\t{$src, $dst|$dst, $src}",
1972                        [(set VR128:$dst, (int_x86_sse2_cvtps2pd VR128:$src))]>,
1973                      TB, VEX, Requires<[HasAVX]>;
1974 def Int_VCVTPS2PDrm : I<0x5A, MRMSrcMem, (outs VR128:$dst), (ins f64mem:$src),
1975                        "vcvtps2pd\t{$src, $dst|$dst, $src}",
1976                        [(set VR128:$dst, (int_x86_sse2_cvtps2pd
1977                                           (load addr:$src)))]>,
1978                      TB, VEX, Requires<[HasAVX]>;
1979 def Int_CVTPS2PDrr : I<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1980                        "cvtps2pd\t{$src, $dst|$dst, $src}",
1981                        [(set VR128:$dst, (int_x86_sse2_cvtps2pd VR128:$src))]>,
1982                      TB, Requires<[HasSSE2]>;
1983 def Int_CVTPS2PDrm : I<0x5A, MRMSrcMem, (outs VR128:$dst), (ins f64mem:$src),
1984                        "cvtps2pd\t{$src, $dst|$dst, $src}",
1985                        [(set VR128:$dst, (int_x86_sse2_cvtps2pd
1986                                           (load addr:$src)))]>,
1987                      TB, Requires<[HasSSE2]>;
1988
1989 // Convert packed double to packed single
1990 // The assembler can recognize rr 256-bit instructions by seeing a ymm
1991 // register, but the same isn't true when using memory operands instead.
1992 // Provide other assembly rr and rm forms to address this explicitly.
1993 def VCVTPD2PSrr : VPDI<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1994                        "cvtpd2ps\t{$src, $dst|$dst, $src}", []>, VEX;
1995 def VCVTPD2PSXrYr : VPDI<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR256:$src),
1996                          "cvtpd2ps\t{$src, $dst|$dst, $src}", []>, VEX;
1997
1998 // XMM only
1999 def VCVTPD2PSXrr : VPDI<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2000                         "cvtpd2psx\t{$src, $dst|$dst, $src}", []>, VEX;
2001 def VCVTPD2PSXrm : VPDI<0x5A, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
2002                         "cvtpd2psx\t{$src, $dst|$dst, $src}", []>, VEX;
2003
2004 // YMM only
2005 def VCVTPD2PSYrr : VPDI<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR256:$src),
2006                         "cvtpd2psy\t{$src, $dst|$dst, $src}", []>, VEX;
2007 def VCVTPD2PSYrm : VPDI<0x5A, MRMSrcMem, (outs VR128:$dst), (ins f256mem:$src),
2008                         "cvtpd2psy\t{$src, $dst|$dst, $src}", []>, VEX, VEX_L;
2009 def CVTPD2PSrr : PDI<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2010                      "cvtpd2ps\t{$src, $dst|$dst, $src}", []>;
2011 def CVTPD2PSrm : PDI<0x5A, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
2012                      "cvtpd2ps\t{$src, $dst|$dst, $src}", []>;
2013
2014
2015 def Int_VCVTPD2PSrr : VPDI<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2016                          "cvtpd2ps\t{$src, $dst|$dst, $src}",
2017                         [(set VR128:$dst, (int_x86_sse2_cvtpd2ps VR128:$src))]>;
2018 def Int_VCVTPD2PSrm : VPDI<0x5A, MRMSrcMem, (outs VR128:$dst),
2019                          (ins f128mem:$src),
2020                          "cvtpd2ps\t{$src, $dst|$dst, $src}",
2021                          [(set VR128:$dst, (int_x86_sse2_cvtpd2ps
2022                                             (memop addr:$src)))]>;
2023 def Int_CVTPD2PSrr : PDI<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2024                          "cvtpd2ps\t{$src, $dst|$dst, $src}",
2025                         [(set VR128:$dst, (int_x86_sse2_cvtpd2ps VR128:$src))]>;
2026 def Int_CVTPD2PSrm : PDI<0x5A, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
2027                          "cvtpd2ps\t{$src, $dst|$dst, $src}",
2028                          [(set VR128:$dst, (int_x86_sse2_cvtpd2ps
2029                                             (memop addr:$src)))]>;
2030
2031 // AVX 256-bit register conversion intrinsics
2032 // FIXME: Migrate SSE conversion intrinsics matching to use patterns as below
2033 // whenever possible to avoid declaring two versions of each one.
2034 def : Pat<(int_x86_avx_cvtdq2_ps_256 VR256:$src),
2035           (VCVTDQ2PSYrr VR256:$src)>;
2036 def : Pat<(int_x86_avx_cvtdq2_ps_256 (bitconvert (memopv4i64 addr:$src))),
2037           (VCVTDQ2PSYrm addr:$src)>;
2038
2039 def : Pat<(int_x86_avx_cvt_pd2_ps_256 VR256:$src),
2040           (VCVTPD2PSYrr VR256:$src)>;
2041 def : Pat<(int_x86_avx_cvt_pd2_ps_256 (memopv4f64 addr:$src)),
2042           (VCVTPD2PSYrm addr:$src)>;
2043
2044 def : Pat<(int_x86_avx_cvt_ps2dq_256 VR256:$src),
2045           (VCVTPS2DQYrr VR256:$src)>;
2046 def : Pat<(int_x86_avx_cvt_ps2dq_256 (memopv8f32 addr:$src)),
2047           (VCVTPS2DQYrm addr:$src)>;
2048
2049 def : Pat<(int_x86_avx_cvt_ps2_pd_256 VR128:$src),
2050           (VCVTPS2PDYrr VR128:$src)>;
2051 def : Pat<(int_x86_avx_cvt_ps2_pd_256 (memopv4f32 addr:$src)),
2052           (VCVTPS2PDYrm addr:$src)>;
2053
2054 def : Pat<(int_x86_avx_cvtt_pd2dq_256 VR256:$src),
2055           (VCVTTPD2DQYrr VR256:$src)>;
2056 def : Pat<(int_x86_avx_cvtt_pd2dq_256 (memopv4f64 addr:$src)),
2057           (VCVTTPD2DQYrm addr:$src)>;
2058
2059 // Match fround and fextend for 128/256-bit conversions
2060 def : Pat<(v4f32 (fround (v4f64 VR256:$src))),
2061           (VCVTPD2PSYrr VR256:$src)>;
2062 def : Pat<(v4f32 (fround (loadv4f64 addr:$src))),
2063           (VCVTPD2PSYrm addr:$src)>;
2064
2065 def : Pat<(v4f64 (fextend (v4f32 VR128:$src))),
2066           (VCVTPS2PDYrr VR128:$src)>;
2067 def : Pat<(v4f64 (fextend (loadv4f32 addr:$src))),
2068           (VCVTPS2PDYrm addr:$src)>;
2069
2070 //===----------------------------------------------------------------------===//
2071 // SSE 1 & 2 - Compare Instructions
2072 //===----------------------------------------------------------------------===//
2073
2074 // sse12_cmp_scalar - sse 1 & 2 compare scalar instructions
2075 multiclass sse12_cmp_scalar<RegisterClass RC, X86MemOperand x86memop,
2076                             SDNode OpNode, ValueType VT, PatFrag ld_frag,
2077                             string asm, string asm_alt> {
2078   def rr : SIi8<0xC2, MRMSrcReg,
2079                 (outs RC:$dst), (ins RC:$src1, RC:$src2, SSECC:$cc), asm,
2080                 [(set RC:$dst, (OpNode (VT RC:$src1), RC:$src2, imm:$cc))]>;
2081   def rm : SIi8<0xC2, MRMSrcMem,
2082                 (outs RC:$dst), (ins RC:$src1, x86memop:$src2, SSECC:$cc), asm,
2083                 [(set RC:$dst, (OpNode (VT RC:$src1),
2084                                          (ld_frag addr:$src2), imm:$cc))]>;
2085
2086   // Accept explicit immediate argument form instead of comparison code.
2087   let neverHasSideEffects = 1 in {
2088     def rr_alt : SIi8<0xC2, MRMSrcReg, (outs RC:$dst),
2089                       (ins RC:$src1, RC:$src2, i8imm:$cc), asm_alt, []>;
2090     let mayLoad = 1 in
2091     def rm_alt : SIi8<0xC2, MRMSrcMem, (outs RC:$dst),
2092                       (ins RC:$src1, x86memop:$src2, i8imm:$cc), asm_alt, []>;
2093   }
2094 }
2095
2096 defm VCMPSS : sse12_cmp_scalar<FR32, f32mem, X86cmpss, f32, loadf32,
2097                  "cmp${cc}ss\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2098                  "cmpss\t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}">,
2099                  XS, VEX_4V, VEX_LIG;
2100 defm VCMPSD : sse12_cmp_scalar<FR64, f64mem, X86cmpsd, f64, loadf64,
2101                  "cmp${cc}sd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2102                  "cmpsd\t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}">,
2103                  XD, VEX_4V, VEX_LIG;
2104
2105 let Constraints = "$src1 = $dst" in {
2106   defm CMPSS : sse12_cmp_scalar<FR32, f32mem, X86cmpss, f32, loadf32,
2107                   "cmp${cc}ss\t{$src2, $dst|$dst, $src2}",
2108                   "cmpss\t{$cc, $src2, $dst|$dst, $src2, $cc}">,
2109                   XS;
2110   defm CMPSD : sse12_cmp_scalar<FR64, f64mem, X86cmpsd, f64, loadf64,
2111                   "cmp${cc}sd\t{$src2, $dst|$dst, $src2}",
2112                   "cmpsd\t{$cc, $src2, $dst|$dst, $src2, $cc}">,
2113                   XD;
2114 }
2115
2116 multiclass sse12_cmp_scalar_int<RegisterClass RC, X86MemOperand x86memop,
2117                          Intrinsic Int, string asm> {
2118   def rr : SIi8<0xC2, MRMSrcReg, (outs VR128:$dst),
2119                       (ins VR128:$src1, VR128:$src, SSECC:$cc), asm,
2120                         [(set VR128:$dst, (Int VR128:$src1,
2121                                                VR128:$src, imm:$cc))]>;
2122   def rm : SIi8<0xC2, MRMSrcMem, (outs VR128:$dst),
2123                       (ins VR128:$src1, x86memop:$src, SSECC:$cc), asm,
2124                         [(set VR128:$dst, (Int VR128:$src1,
2125                                                (load addr:$src), imm:$cc))]>;
2126 }
2127
2128 // Aliases to match intrinsics which expect XMM operand(s).
2129 defm Int_VCMPSS  : sse12_cmp_scalar_int<VR128, f32mem, int_x86_sse_cmp_ss,
2130                      "cmp${cc}ss\t{$src, $src1, $dst|$dst, $src1, $src}">,
2131                      XS, VEX_4V;
2132 defm Int_VCMPSD  : sse12_cmp_scalar_int<VR128, f64mem, int_x86_sse2_cmp_sd,
2133                      "cmp${cc}sd\t{$src, $src1, $dst|$dst, $src1, $src}">,
2134                      XD, VEX_4V;
2135 let Constraints = "$src1 = $dst" in {
2136   defm Int_CMPSS  : sse12_cmp_scalar_int<VR128, f32mem, int_x86_sse_cmp_ss,
2137                        "cmp${cc}ss\t{$src, $dst|$dst, $src}">, XS;
2138   defm Int_CMPSD  : sse12_cmp_scalar_int<VR128, f64mem, int_x86_sse2_cmp_sd,
2139                        "cmp${cc}sd\t{$src, $dst|$dst, $src}">, XD;
2140 }
2141
2142
2143 // sse12_ord_cmp - Unordered/Ordered scalar fp compare and set EFLAGS
2144 multiclass sse12_ord_cmp<bits<8> opc, RegisterClass RC, SDNode OpNode,
2145                             ValueType vt, X86MemOperand x86memop,
2146                             PatFrag ld_frag, string OpcodeStr, Domain d> {
2147   def rr: PI<opc, MRMSrcReg, (outs), (ins RC:$src1, RC:$src2),
2148                      !strconcat(OpcodeStr, "\t{$src2, $src1|$src1, $src2}"),
2149                      [(set EFLAGS, (OpNode (vt RC:$src1), RC:$src2))], d>;
2150   def rm: PI<opc, MRMSrcMem, (outs), (ins RC:$src1, x86memop:$src2),
2151                      !strconcat(OpcodeStr, "\t{$src2, $src1|$src1, $src2}"),
2152                      [(set EFLAGS, (OpNode (vt RC:$src1),
2153                                            (ld_frag addr:$src2)))], d>;
2154 }
2155
2156 let Defs = [EFLAGS] in {
2157   defm VUCOMISS : sse12_ord_cmp<0x2E, FR32, X86cmp, f32, f32mem, loadf32,
2158                                   "ucomiss", SSEPackedSingle>, TB, VEX, VEX_LIG;
2159   defm VUCOMISD : sse12_ord_cmp<0x2E, FR64, X86cmp, f64, f64mem, loadf64,
2160                                   "ucomisd", SSEPackedDouble>, TB, OpSize, VEX,
2161                                   VEX_LIG;
2162   let Pattern = []<dag> in {
2163     defm VCOMISS  : sse12_ord_cmp<0x2F, VR128, undef, v4f32, f128mem, load,
2164                                     "comiss", SSEPackedSingle>, TB, VEX,
2165                                     VEX_LIG;
2166     defm VCOMISD  : sse12_ord_cmp<0x2F, VR128, undef, v2f64, f128mem, load,
2167                                     "comisd", SSEPackedDouble>, TB, OpSize, VEX,
2168                                     VEX_LIG;
2169   }
2170
2171   defm Int_VUCOMISS  : sse12_ord_cmp<0x2E, VR128, X86ucomi, v4f32, f128mem,
2172                             load, "ucomiss", SSEPackedSingle>, TB, VEX;
2173   defm Int_VUCOMISD  : sse12_ord_cmp<0x2E, VR128, X86ucomi, v2f64, f128mem,
2174                             load, "ucomisd", SSEPackedDouble>, TB, OpSize, VEX;
2175
2176   defm Int_VCOMISS  : sse12_ord_cmp<0x2F, VR128, X86comi, v4f32, f128mem,
2177                             load, "comiss", SSEPackedSingle>, TB, VEX;
2178   defm Int_VCOMISD  : sse12_ord_cmp<0x2F, VR128, X86comi, v2f64, f128mem,
2179                             load, "comisd", SSEPackedDouble>, TB, OpSize, VEX;
2180   defm UCOMISS  : sse12_ord_cmp<0x2E, FR32, X86cmp, f32, f32mem, loadf32,
2181                                   "ucomiss", SSEPackedSingle>, TB;
2182   defm UCOMISD  : sse12_ord_cmp<0x2E, FR64, X86cmp, f64, f64mem, loadf64,
2183                                   "ucomisd", SSEPackedDouble>, TB, OpSize;
2184
2185   let Pattern = []<dag> in {
2186     defm COMISS  : sse12_ord_cmp<0x2F, VR128, undef, v4f32, f128mem, load,
2187                                     "comiss", SSEPackedSingle>, TB;
2188     defm COMISD  : sse12_ord_cmp<0x2F, VR128, undef, v2f64, f128mem, load,
2189                                     "comisd", SSEPackedDouble>, TB, OpSize;
2190   }
2191
2192   defm Int_UCOMISS  : sse12_ord_cmp<0x2E, VR128, X86ucomi, v4f32, f128mem,
2193                               load, "ucomiss", SSEPackedSingle>, TB;
2194   defm Int_UCOMISD  : sse12_ord_cmp<0x2E, VR128, X86ucomi, v2f64, f128mem,
2195                               load, "ucomisd", SSEPackedDouble>, TB, OpSize;
2196
2197   defm Int_COMISS  : sse12_ord_cmp<0x2F, VR128, X86comi, v4f32, f128mem, load,
2198                                   "comiss", SSEPackedSingle>, TB;
2199   defm Int_COMISD  : sse12_ord_cmp<0x2F, VR128, X86comi, v2f64, f128mem, load,
2200                                   "comisd", SSEPackedDouble>, TB, OpSize;
2201 } // Defs = [EFLAGS]
2202
2203 // sse12_cmp_packed - sse 1 & 2 compared packed instructions
2204 multiclass sse12_cmp_packed<RegisterClass RC, X86MemOperand x86memop,
2205                             Intrinsic Int, string asm, string asm_alt,
2206                             Domain d> {
2207   let isAsmParserOnly = 1 in {
2208     def rri : PIi8<0xC2, MRMSrcReg,
2209                (outs RC:$dst), (ins RC:$src1, RC:$src2, SSECC:$cc), asm,
2210                [(set RC:$dst, (Int RC:$src1, RC:$src2, imm:$cc))], d>;
2211     def rmi : PIi8<0xC2, MRMSrcMem,
2212                (outs RC:$dst), (ins RC:$src1, x86memop:$src2, SSECC:$cc), asm,
2213                [(set RC:$dst, (Int RC:$src1, (memop addr:$src2), imm:$cc))], d>;
2214   }
2215
2216   // Accept explicit immediate argument form instead of comparison code.
2217   def rri_alt : PIi8<0xC2, MRMSrcReg,
2218              (outs RC:$dst), (ins RC:$src1, RC:$src2, i8imm:$cc),
2219              asm_alt, [], d>;
2220   def rmi_alt : PIi8<0xC2, MRMSrcMem,
2221              (outs RC:$dst), (ins RC:$src1, x86memop:$src2, i8imm:$cc),
2222              asm_alt, [], d>;
2223 }
2224
2225 defm VCMPPS : sse12_cmp_packed<VR128, f128mem, int_x86_sse_cmp_ps,
2226                "cmp${cc}ps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2227                "cmpps\t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}",
2228                SSEPackedSingle>, TB, VEX_4V;
2229 defm VCMPPD : sse12_cmp_packed<VR128, f128mem, int_x86_sse2_cmp_pd,
2230                "cmp${cc}pd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2231                "cmppd\t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}",
2232                SSEPackedDouble>, TB, OpSize, VEX_4V;
2233 defm VCMPPSY : sse12_cmp_packed<VR256, f256mem, int_x86_avx_cmp_ps_256,
2234                "cmp${cc}ps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2235                "cmpps\t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}",
2236                SSEPackedSingle>, TB, VEX_4V;
2237 defm VCMPPDY : sse12_cmp_packed<VR256, f256mem, int_x86_avx_cmp_pd_256,
2238                "cmp${cc}pd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2239                "cmppd\t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}",
2240                SSEPackedDouble>, TB, OpSize, VEX_4V;
2241 let Constraints = "$src1 = $dst" in {
2242   defm CMPPS : sse12_cmp_packed<VR128, f128mem, int_x86_sse_cmp_ps,
2243                  "cmp${cc}ps\t{$src2, $dst|$dst, $src2}",
2244                  "cmpps\t{$cc, $src2, $dst|$dst, $src2, $cc}",
2245                  SSEPackedSingle>, TB;
2246   defm CMPPD : sse12_cmp_packed<VR128, f128mem, int_x86_sse2_cmp_pd,
2247                  "cmp${cc}pd\t{$src2, $dst|$dst, $src2}",
2248                  "cmppd\t{$cc, $src2, $dst|$dst, $src2, $cc}",
2249                  SSEPackedDouble>, TB, OpSize;
2250 }
2251
2252 let Predicates = [HasAVX] in {
2253 def : Pat<(v4i32 (X86cmpp (v4f32 VR128:$src1), VR128:$src2, imm:$cc)),
2254           (VCMPPSrri (v4f32 VR128:$src1), (v4f32 VR128:$src2), imm:$cc)>;
2255 def : Pat<(v4i32 (X86cmpp (v4f32 VR128:$src1), (memop addr:$src2), imm:$cc)),
2256           (VCMPPSrmi (v4f32 VR128:$src1), addr:$src2, imm:$cc)>;
2257 def : Pat<(v2i64 (X86cmpp (v2f64 VR128:$src1), VR128:$src2, imm:$cc)),
2258           (VCMPPDrri VR128:$src1, VR128:$src2, imm:$cc)>;
2259 def : Pat<(v2i64 (X86cmpp (v2f64 VR128:$src1), (memop addr:$src2), imm:$cc)),
2260           (VCMPPDrmi VR128:$src1, addr:$src2, imm:$cc)>;
2261
2262 def : Pat<(v8i32 (X86cmpp (v8f32 VR256:$src1), VR256:$src2, imm:$cc)),
2263           (VCMPPSYrri (v8f32 VR256:$src1), (v8f32 VR256:$src2), imm:$cc)>;
2264 def : Pat<(v8i32 (X86cmpp (v8f32 VR256:$src1), (memop addr:$src2), imm:$cc)),
2265           (VCMPPSYrmi (v8f32 VR256:$src1), addr:$src2, imm:$cc)>;
2266 def : Pat<(v4i64 (X86cmpp (v4f64 VR256:$src1), VR256:$src2, imm:$cc)),
2267           (VCMPPDYrri VR256:$src1, VR256:$src2, imm:$cc)>;
2268 def : Pat<(v4i64 (X86cmpp (v4f64 VR256:$src1), (memop addr:$src2), imm:$cc)),
2269           (VCMPPDYrmi VR256:$src1, addr:$src2, imm:$cc)>;
2270 }
2271
2272 let Predicates = [HasSSE1] in {
2273 def : Pat<(v4i32 (X86cmpp (v4f32 VR128:$src1), VR128:$src2, imm:$cc)),
2274           (CMPPSrri (v4f32 VR128:$src1), (v4f32 VR128:$src2), imm:$cc)>;
2275 def : Pat<(v4i32 (X86cmpp (v4f32 VR128:$src1), (memop addr:$src2), imm:$cc)),
2276           (CMPPSrmi (v4f32 VR128:$src1), addr:$src2, imm:$cc)>;
2277 }
2278
2279 let Predicates = [HasSSE2] in {
2280 def : Pat<(v2i64 (X86cmpp (v2f64 VR128:$src1), VR128:$src2, imm:$cc)),
2281           (CMPPDrri VR128:$src1, VR128:$src2, imm:$cc)>;
2282 def : Pat<(v2i64 (X86cmpp (v2f64 VR128:$src1), (memop addr:$src2), imm:$cc)),
2283           (CMPPDrmi VR128:$src1, addr:$src2, imm:$cc)>;
2284 }
2285
2286 //===----------------------------------------------------------------------===//
2287 // SSE 1 & 2 - Shuffle Instructions
2288 //===----------------------------------------------------------------------===//
2289
2290 /// sse12_shuffle - sse 1 & 2 shuffle instructions
2291 multiclass sse12_shuffle<RegisterClass RC, X86MemOperand x86memop,
2292                          ValueType vt, string asm, PatFrag mem_frag,
2293                          Domain d, bit IsConvertibleToThreeAddress = 0> {
2294   def rmi : PIi8<0xC6, MRMSrcMem, (outs RC:$dst),
2295                    (ins RC:$src1, x86memop:$src2, i8imm:$src3), asm,
2296                    [(set RC:$dst, (vt (shufp:$src3
2297                             RC:$src1, (mem_frag addr:$src2))))], d>;
2298   let isConvertibleToThreeAddress = IsConvertibleToThreeAddress in
2299     def rri : PIi8<0xC6, MRMSrcReg, (outs RC:$dst),
2300                    (ins RC:$src1, RC:$src2, i8imm:$src3), asm,
2301                    [(set RC:$dst,
2302                             (vt (shufp:$src3 RC:$src1, RC:$src2)))], d>;
2303 }
2304
2305 defm VSHUFPS  : sse12_shuffle<VR128, f128mem, v4f32,
2306            "shufps\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
2307            memopv4f32, SSEPackedSingle>, TB, VEX_4V;
2308 defm VSHUFPSY : sse12_shuffle<VR256, f256mem, v8f32,
2309            "shufps\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
2310            memopv8f32, SSEPackedSingle>, TB, VEX_4V;
2311 defm VSHUFPD  : sse12_shuffle<VR128, f128mem, v2f64,
2312            "shufpd\t{$src3, $src2, $src1, $dst|$dst, $src2, $src2, $src3}",
2313            memopv2f64, SSEPackedDouble>, TB, OpSize, VEX_4V;
2314 defm VSHUFPDY : sse12_shuffle<VR256, f256mem, v4f64,
2315            "shufpd\t{$src3, $src2, $src1, $dst|$dst, $src2, $src2, $src3}",
2316            memopv4f64, SSEPackedDouble>, TB, OpSize, VEX_4V;
2317
2318 let Constraints = "$src1 = $dst" in {
2319   defm SHUFPS : sse12_shuffle<VR128, f128mem, v4f32,
2320                     "shufps\t{$src3, $src2, $dst|$dst, $src2, $src3}",
2321                     memopv4f32, SSEPackedSingle, 1 /* cvt to pshufd */>,
2322                     TB;
2323   defm SHUFPD : sse12_shuffle<VR128, f128mem, v2f64,
2324                     "shufpd\t{$src3, $src2, $dst|$dst, $src2, $src3}",
2325                     memopv2f64, SSEPackedDouble, 1 /* cvt to pshufd */>,
2326                     TB, OpSize;
2327 }
2328
2329 let Predicates = [HasAVX] in {
2330   def : Pat<(v4f32 (X86Shufp VR128:$src1,
2331                        (memopv4f32 addr:$src2), (i8 imm:$imm))),
2332             (VSHUFPSrmi VR128:$src1, addr:$src2, imm:$imm)>;
2333   def : Pat<(v4f32 (X86Shufp VR128:$src1, VR128:$src2, (i8 imm:$imm))),
2334             (VSHUFPSrri VR128:$src1, VR128:$src2, imm:$imm)>;
2335   def : Pat<(v4i32 (X86Shufp VR128:$src1,
2336                        (bc_v4i32 (memopv2i64 addr:$src2)), (i8 imm:$imm))),
2337             (VSHUFPSrmi VR128:$src1, addr:$src2, imm:$imm)>;
2338   def : Pat<(v4i32 (X86Shufp VR128:$src1, VR128:$src2, (i8 imm:$imm))),
2339             (VSHUFPSrri VR128:$src1, VR128:$src2, imm:$imm)>;
2340   // vector_shuffle v1, v2 <4, 5, 2, 3> using SHUFPSrri (we prefer movsd, but
2341   // fall back to this for SSE1)
2342   def : Pat<(v4f32 (movlp:$src3 VR128:$src1, (v4f32 VR128:$src2))),
2343             (VSHUFPSrri VR128:$src2, VR128:$src1,
2344                         (SHUFFLE_get_shuf_imm VR128:$src3))>;
2345   // Special unary SHUFPSrri case.
2346   def : Pat<(v4f32 (pshufd:$src3 VR128:$src1, (undef))),
2347             (VSHUFPSrri VR128:$src1, VR128:$src1,
2348                         (SHUFFLE_get_shuf_imm VR128:$src3))>;
2349   // Special binary v4i32 shuffle cases with SHUFPS.
2350   def : Pat<(v4i32 (shufp:$src3 VR128:$src1, (v4i32 VR128:$src2))),
2351             (VSHUFPSrri VR128:$src1, VR128:$src2,
2352                         (SHUFFLE_get_shuf_imm VR128:$src3))>;
2353   def : Pat<(v4i32 (shufp:$src3 VR128:$src1,
2354                                 (bc_v4i32 (memopv2i64 addr:$src2)))),
2355             (VSHUFPSrmi VR128:$src1, addr:$src2,
2356                         (SHUFFLE_get_shuf_imm VR128:$src3))>;
2357   // Special unary SHUFPDrri cases.
2358   def : Pat<(v2i64 (pshufd:$src3 VR128:$src1, (undef))),
2359             (VSHUFPDrri VR128:$src1, VR128:$src1,
2360                         (SHUFFLE_get_shuf_imm VR128:$src3))>;
2361   def : Pat<(v2f64 (pshufd:$src3 VR128:$src1, (undef))),
2362             (VSHUFPDrri VR128:$src1, VR128:$src1,
2363                         (SHUFFLE_get_shuf_imm VR128:$src3))>;
2364   // Special binary v2i64 shuffle cases using SHUFPDrri.
2365   def : Pat<(v2i64 (shufp:$src3 VR128:$src1, VR128:$src2)),
2366             (VSHUFPDrri VR128:$src1, VR128:$src2,
2367                         (SHUFFLE_get_shuf_imm VR128:$src3))>;
2368
2369   def : Pat<(v2i64 (X86Shufp VR128:$src1,
2370                        (memopv2i64 addr:$src2), (i8 imm:$imm))),
2371             (VSHUFPDrmi VR128:$src1, addr:$src2, imm:$imm)>;
2372   def : Pat<(v2f64 (X86Shufp VR128:$src1,
2373                        (memopv2f64 addr:$src2), (i8 imm:$imm))),
2374             (VSHUFPDrmi VR128:$src1, addr:$src2, imm:$imm)>;
2375   def : Pat<(v2i64 (X86Shufp VR128:$src1, VR128:$src2, (i8 imm:$imm))),
2376             (VSHUFPDrri VR128:$src1, VR128:$src2, imm:$imm)>;
2377   def : Pat<(v2f64 (X86Shufp VR128:$src1, VR128:$src2, (i8 imm:$imm))),
2378             (VSHUFPDrri VR128:$src1, VR128:$src2, imm:$imm)>;
2379
2380   // 256-bit patterns
2381   def : Pat<(v8i32 (X86Shufp VR256:$src1, VR256:$src2, (i8 imm:$imm))),
2382             (VSHUFPSYrri VR256:$src1, VR256:$src2, imm:$imm)>;
2383   def : Pat<(v8i32 (X86Shufp VR256:$src1,
2384                       (bc_v8i32 (memopv4i64 addr:$src2)), (i8 imm:$imm))),
2385             (VSHUFPSYrmi VR256:$src1, addr:$src2, imm:$imm)>;
2386
2387   def : Pat<(v8f32 (X86Shufp VR256:$src1, VR256:$src2, (i8 imm:$imm))),
2388             (VSHUFPSYrri VR256:$src1, VR256:$src2, imm:$imm)>;
2389   def : Pat<(v8f32 (X86Shufp VR256:$src1,
2390                               (memopv8f32 addr:$src2), (i8 imm:$imm))),
2391             (VSHUFPSYrmi VR256:$src1, addr:$src2, imm:$imm)>;
2392
2393   def : Pat<(v4i64 (X86Shufp VR256:$src1, VR256:$src2, (i8 imm:$imm))),
2394             (VSHUFPDYrri VR256:$src1, VR256:$src2, imm:$imm)>;
2395   def : Pat<(v4i64 (X86Shufp VR256:$src1,
2396                               (memopv4i64 addr:$src2), (i8 imm:$imm))),
2397             (VSHUFPDYrmi VR256:$src1, addr:$src2, imm:$imm)>;
2398
2399   def : Pat<(v4f64 (X86Shufp VR256:$src1, VR256:$src2, (i8 imm:$imm))),
2400             (VSHUFPDYrri VR256:$src1, VR256:$src2, imm:$imm)>;
2401   def : Pat<(v4f64 (X86Shufp VR256:$src1,
2402                               (memopv4f64 addr:$src2), (i8 imm:$imm))),
2403             (VSHUFPDYrmi VR256:$src1, addr:$src2, imm:$imm)>;
2404 }
2405
2406 let Predicates = [HasSSE1] in {
2407   def : Pat<(v4f32 (X86Shufp VR128:$src1,
2408                        (memopv4f32 addr:$src2), (i8 imm:$imm))),
2409             (SHUFPSrmi VR128:$src1, addr:$src2, imm:$imm)>;
2410   def : Pat<(v4f32 (X86Shufp VR128:$src1, VR128:$src2, (i8 imm:$imm))),
2411             (SHUFPSrri VR128:$src1, VR128:$src2, imm:$imm)>;
2412   def : Pat<(v4i32 (X86Shufp VR128:$src1,
2413                        (bc_v4i32 (memopv2i64 addr:$src2)), (i8 imm:$imm))),
2414             (SHUFPSrmi VR128:$src1, addr:$src2, imm:$imm)>;
2415   def : Pat<(v4i32 (X86Shufp VR128:$src1, VR128:$src2, (i8 imm:$imm))),
2416             (SHUFPSrri VR128:$src1, VR128:$src2, imm:$imm)>;
2417   // vector_shuffle v1, v2 <4, 5, 2, 3> using SHUFPSrri (we prefer movsd, but
2418   // fall back to this for SSE1)
2419   def : Pat<(v4f32 (movlp:$src3 VR128:$src1, (v4f32 VR128:$src2))),
2420             (SHUFPSrri VR128:$src2, VR128:$src1,
2421                        (SHUFFLE_get_shuf_imm VR128:$src3))>;
2422   // Special unary SHUFPSrri case.
2423   def : Pat<(v4f32 (pshufd:$src3 VR128:$src1, (undef))),
2424             (SHUFPSrri VR128:$src1, VR128:$src1,
2425                        (SHUFFLE_get_shuf_imm VR128:$src3))>;
2426 }
2427
2428 let Predicates = [HasSSE2] in {
2429   // Special binary v4i32 shuffle cases with SHUFPS.
2430   def : Pat<(v4i32 (shufp:$src3 VR128:$src1, (v4i32 VR128:$src2))),
2431             (SHUFPSrri VR128:$src1, VR128:$src2,
2432                        (SHUFFLE_get_shuf_imm VR128:$src3))>;
2433   def : Pat<(v4i32 (shufp:$src3 VR128:$src1,
2434                                 (bc_v4i32 (memopv2i64 addr:$src2)))),
2435             (SHUFPSrmi VR128:$src1, addr:$src2,
2436                       (SHUFFLE_get_shuf_imm VR128:$src3))>;
2437   // Special unary SHUFPDrri cases.
2438   def : Pat<(v2i64 (pshufd:$src3 VR128:$src1, (undef))),
2439             (SHUFPDrri VR128:$src1, VR128:$src1,
2440                        (SHUFFLE_get_shuf_imm VR128:$src3))>;
2441   def : Pat<(v2f64 (pshufd:$src3 VR128:$src1, (undef))),
2442             (SHUFPDrri VR128:$src1, VR128:$src1,
2443                        (SHUFFLE_get_shuf_imm VR128:$src3))>;
2444   // Special binary v2i64 shuffle cases using SHUFPDrri.
2445   def : Pat<(v2i64 (shufp:$src3 VR128:$src1, VR128:$src2)),
2446             (SHUFPDrri VR128:$src1, VR128:$src2,
2447                        (SHUFFLE_get_shuf_imm VR128:$src3))>;
2448   // Generic SHUFPD patterns
2449   def : Pat<(v2i64 (X86Shufp VR128:$src1,
2450                        (memopv2i64 addr:$src2), (i8 imm:$imm))),
2451             (SHUFPDrmi VR128:$src1, addr:$src2, imm:$imm)>;
2452   def : Pat<(v2f64 (X86Shufp VR128:$src1,
2453                        (memopv2f64 addr:$src2), (i8 imm:$imm))),
2454             (SHUFPDrmi VR128:$src1, addr:$src2, imm:$imm)>;
2455   def : Pat<(v2i64 (X86Shufp VR128:$src1, VR128:$src2, (i8 imm:$imm))),
2456             (SHUFPDrri VR128:$src1, VR128:$src2, imm:$imm)>;
2457   def : Pat<(v2f64 (X86Shufp VR128:$src1, VR128:$src2, (i8 imm:$imm))),
2458             (SHUFPDrri VR128:$src1, VR128:$src2, imm:$imm)>;
2459 }
2460
2461 //===----------------------------------------------------------------------===//
2462 // SSE 1 & 2 - Unpack Instructions
2463 //===----------------------------------------------------------------------===//
2464
2465 /// sse12_unpack_interleave - sse 1 & 2 unpack and interleave
2466 multiclass sse12_unpack_interleave<bits<8> opc, PatFrag OpNode, ValueType vt,
2467                                    PatFrag mem_frag, RegisterClass RC,
2468                                    X86MemOperand x86memop, string asm,
2469                                    Domain d> {
2470     def rr : PI<opc, MRMSrcReg,
2471                 (outs RC:$dst), (ins RC:$src1, RC:$src2),
2472                 asm, [(set RC:$dst,
2473                            (vt (OpNode RC:$src1, RC:$src2)))], d>;
2474     def rm : PI<opc, MRMSrcMem,
2475                 (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
2476                 asm, [(set RC:$dst,
2477                            (vt (OpNode RC:$src1,
2478                                        (mem_frag addr:$src2))))], d>;
2479 }
2480
2481 let AddedComplexity = 10 in {
2482   defm VUNPCKHPS: sse12_unpack_interleave<0x15, unpckh, v4f32, memopv4f32,
2483         VR128, f128mem, "unpckhps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2484                        SSEPackedSingle>, TB, VEX_4V;
2485   defm VUNPCKHPD: sse12_unpack_interleave<0x15, unpckh, v2f64, memopv2f64,
2486         VR128, f128mem, "unpckhpd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2487                        SSEPackedDouble>, TB, OpSize, VEX_4V;
2488   defm VUNPCKLPS: sse12_unpack_interleave<0x14, unpckl, v4f32, memopv4f32,
2489         VR128, f128mem, "unpcklps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2490                        SSEPackedSingle>, TB, VEX_4V;
2491   defm VUNPCKLPD: sse12_unpack_interleave<0x14, unpckl, v2f64, memopv2f64,
2492         VR128, f128mem, "unpcklpd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2493                        SSEPackedDouble>, TB, OpSize, VEX_4V;
2494
2495   defm VUNPCKHPSY: sse12_unpack_interleave<0x15, unpckh, v8f32, memopv8f32,
2496         VR256, f256mem, "unpckhps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2497                        SSEPackedSingle>, TB, VEX_4V;
2498   defm VUNPCKHPDY: sse12_unpack_interleave<0x15, unpckh, v4f64, memopv4f64,
2499         VR256, f256mem, "unpckhpd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2500                        SSEPackedDouble>, TB, OpSize, VEX_4V;
2501   defm VUNPCKLPSY: sse12_unpack_interleave<0x14, unpckl, v8f32, memopv8f32,
2502         VR256, f256mem, "unpcklps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2503                        SSEPackedSingle>, TB, VEX_4V;
2504   defm VUNPCKLPDY: sse12_unpack_interleave<0x14, unpckl, v4f64, memopv4f64,
2505         VR256, f256mem, "unpcklpd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2506                        SSEPackedDouble>, TB, OpSize, VEX_4V;
2507
2508   let Constraints = "$src1 = $dst" in {
2509     defm UNPCKHPS: sse12_unpack_interleave<0x15, unpckh, v4f32, memopv4f32,
2510           VR128, f128mem, "unpckhps\t{$src2, $dst|$dst, $src2}",
2511                          SSEPackedSingle>, TB;
2512     defm UNPCKHPD: sse12_unpack_interleave<0x15, unpckh, v2f64, memopv2f64,
2513           VR128, f128mem, "unpckhpd\t{$src2, $dst|$dst, $src2}",
2514                          SSEPackedDouble>, TB, OpSize;
2515     defm UNPCKLPS: sse12_unpack_interleave<0x14, unpckl, v4f32, memopv4f32,
2516           VR128, f128mem, "unpcklps\t{$src2, $dst|$dst, $src2}",
2517                          SSEPackedSingle>, TB;
2518     defm UNPCKLPD: sse12_unpack_interleave<0x14, unpckl, v2f64, memopv2f64,
2519           VR128, f128mem, "unpcklpd\t{$src2, $dst|$dst, $src2}",
2520                          SSEPackedDouble>, TB, OpSize;
2521   } // Constraints = "$src1 = $dst"
2522 } // AddedComplexity
2523
2524 let Predicates = [HasAVX], AddedComplexity = 1 in {
2525   def : Pat<(v4f32 (X86Unpckl VR128:$src1, (memopv4f32 addr:$src2))),
2526             (VUNPCKLPSrm VR128:$src1, addr:$src2)>;
2527   def : Pat<(v4f32 (X86Unpckl VR128:$src1, VR128:$src2)),
2528             (VUNPCKLPSrr VR128:$src1, VR128:$src2)>;
2529   def : Pat<(v4f32 (X86Unpckh VR128:$src1, (memopv4f32 addr:$src2))),
2530             (VUNPCKHPSrm VR128:$src1, addr:$src2)>;
2531   def : Pat<(v4f32 (X86Unpckh VR128:$src1, VR128:$src2)),
2532             (VUNPCKHPSrr VR128:$src1, VR128:$src2)>;
2533
2534   def : Pat<(v8f32 (X86Unpckl VR256:$src1, (memopv8f32 addr:$src2))),
2535             (VUNPCKLPSYrm VR256:$src1, addr:$src2)>;
2536   def : Pat<(v8f32 (X86Unpckl VR256:$src1, VR256:$src2)),
2537             (VUNPCKLPSYrr VR256:$src1, VR256:$src2)>;
2538   def : Pat<(v8f32 (X86Unpckh VR256:$src1, (memopv8f32 addr:$src2))),
2539             (VUNPCKHPSYrm VR256:$src1, addr:$src2)>;
2540   def : Pat<(v8f32 (X86Unpckh VR256:$src1, VR256:$src2)),
2541             (VUNPCKHPSYrr VR256:$src1, VR256:$src2)>;
2542
2543   def : Pat<(v2f64 (X86Unpckl VR128:$src1, (memopv2f64 addr:$src2))),
2544             (VUNPCKLPDrm VR128:$src1, addr:$src2)>;
2545   def : Pat<(v2f64 (X86Unpckl VR128:$src1, VR128:$src2)),
2546             (VUNPCKLPDrr VR128:$src1, VR128:$src2)>;
2547   def : Pat<(v2f64 (X86Unpckh VR128:$src1, (memopv2f64 addr:$src2))),
2548             (VUNPCKHPDrm VR128:$src1, addr:$src2)>;
2549   def : Pat<(v2f64 (X86Unpckh VR128:$src1, VR128:$src2)),
2550             (VUNPCKHPDrr VR128:$src1, VR128:$src2)>;
2551
2552   def : Pat<(v4f64 (X86Unpckl VR256:$src1, (memopv4f64 addr:$src2))),
2553             (VUNPCKLPDYrm VR256:$src1, addr:$src2)>;
2554   def : Pat<(v4f64 (X86Unpckl VR256:$src1, VR256:$src2)),
2555             (VUNPCKLPDYrr VR256:$src1, VR256:$src2)>;
2556   def : Pat<(v4f64 (X86Unpckh VR256:$src1, (memopv4f64 addr:$src2))),
2557             (VUNPCKHPDYrm VR256:$src1, addr:$src2)>;
2558   def : Pat<(v4f64 (X86Unpckh VR256:$src1, VR256:$src2)),
2559             (VUNPCKHPDYrr VR256:$src1, VR256:$src2)>;
2560
2561   // FIXME: Instead of X86Movddup, there should be a X86Unpckl here, the
2562   // problem is during lowering, where it's not possible to recognize the load
2563   // fold cause it has two uses through a bitcast. One use disappears at isel
2564   // time and the fold opportunity reappears.
2565   def : Pat<(v2f64 (X86Movddup VR128:$src)),
2566             (VUNPCKLPDrr VR128:$src, VR128:$src)>;
2567   let AddedComplexity = 10 in
2568   def : Pat<(splat_lo (v2f64 VR128:$src), (undef)),
2569             (VUNPCKLPDrr VR128:$src, VR128:$src)>;
2570 }
2571
2572 let Predicates = [HasSSE1] in {
2573   def : Pat<(v4f32 (X86Unpckl VR128:$src1, (memopv4f32 addr:$src2))),
2574             (UNPCKLPSrm VR128:$src1, addr:$src2)>;
2575   def : Pat<(v4f32 (X86Unpckl VR128:$src1, VR128:$src2)),
2576             (UNPCKLPSrr VR128:$src1, VR128:$src2)>;
2577   def : Pat<(v4f32 (X86Unpckh VR128:$src1, (memopv4f32 addr:$src2))),
2578             (UNPCKHPSrm VR128:$src1, addr:$src2)>;
2579   def : Pat<(v4f32 (X86Unpckh VR128:$src1, VR128:$src2)),
2580             (UNPCKHPSrr VR128:$src1, VR128:$src2)>;
2581 }
2582
2583 let Predicates = [HasSSE2] in {
2584   def : Pat<(v2f64 (X86Unpckl VR128:$src1, (memopv2f64 addr:$src2))),
2585             (UNPCKLPDrm VR128:$src1, addr:$src2)>;
2586   def : Pat<(v2f64 (X86Unpckl VR128:$src1, VR128:$src2)),
2587             (UNPCKLPDrr VR128:$src1, VR128:$src2)>;
2588   def : Pat<(v2f64 (X86Unpckh VR128:$src1, (memopv2f64 addr:$src2))),
2589             (UNPCKHPDrm VR128:$src1, addr:$src2)>;
2590   def : Pat<(v2f64 (X86Unpckh VR128:$src1, VR128:$src2)),
2591             (UNPCKHPDrr VR128:$src1, VR128:$src2)>;
2592
2593   // FIXME: Instead of X86Movddup, there should be a X86Unpckl here, the
2594   // problem is during lowering, where it's not possible to recognize the load
2595   // fold cause it has two uses through a bitcast. One use disappears at isel
2596   // time and the fold opportunity reappears.
2597   def : Pat<(v2f64 (X86Movddup VR128:$src)),
2598             (UNPCKLPDrr VR128:$src, VR128:$src)>;
2599
2600   let AddedComplexity = 10 in
2601   def : Pat<(splat_lo (v2f64 VR128:$src), (undef)),
2602             (UNPCKLPDrr VR128:$src, VR128:$src)>;
2603 }
2604
2605 //===----------------------------------------------------------------------===//
2606 // SSE 1 & 2 - Extract Floating-Point Sign mask
2607 //===----------------------------------------------------------------------===//
2608
2609 /// sse12_extr_sign_mask - sse 1 & 2 unpack and interleave
2610 multiclass sse12_extr_sign_mask<RegisterClass RC, Intrinsic Int, string asm,
2611                                 Domain d> {
2612   def rr32 : PI<0x50, MRMSrcReg, (outs GR32:$dst), (ins RC:$src),
2613                 !strconcat(asm, "\t{$src, $dst|$dst, $src}"),
2614                      [(set GR32:$dst, (Int RC:$src))], d>;
2615   def rr64 : PI<0x50, MRMSrcReg, (outs GR64:$dst), (ins RC:$src),
2616                 !strconcat(asm, "\t{$src, $dst|$dst, $src}"), [], d>, REX_W;
2617 }
2618
2619 let Predicates = [HasAVX] in {
2620   defm VMOVMSKPS : sse12_extr_sign_mask<VR128, int_x86_sse_movmsk_ps,
2621                                         "movmskps", SSEPackedSingle>, TB, VEX;
2622   defm VMOVMSKPD : sse12_extr_sign_mask<VR128, int_x86_sse2_movmsk_pd,
2623                                         "movmskpd", SSEPackedDouble>, TB,
2624                                         OpSize, VEX;
2625   defm VMOVMSKPSY : sse12_extr_sign_mask<VR256, int_x86_avx_movmsk_ps_256,
2626                                         "movmskps", SSEPackedSingle>, TB, VEX;
2627   defm VMOVMSKPDY : sse12_extr_sign_mask<VR256, int_x86_avx_movmsk_pd_256,
2628                                         "movmskpd", SSEPackedDouble>, TB,
2629                                         OpSize, VEX;
2630
2631   def : Pat<(i32 (X86fgetsign FR32:$src)),
2632             (VMOVMSKPSrr32 (INSERT_SUBREG (v4f32 (IMPLICIT_DEF)), FR32:$src,
2633                                           sub_ss))>;
2634   def : Pat<(i64 (X86fgetsign FR32:$src)),
2635             (VMOVMSKPSrr64 (INSERT_SUBREG (v4f32 (IMPLICIT_DEF)), FR32:$src,
2636                                           sub_ss))>;
2637   def : Pat<(i32 (X86fgetsign FR64:$src)),
2638             (VMOVMSKPDrr32 (INSERT_SUBREG (v2f64 (IMPLICIT_DEF)), FR64:$src,
2639                                           sub_sd))>;
2640   def : Pat<(i64 (X86fgetsign FR64:$src)),
2641             (VMOVMSKPDrr64 (INSERT_SUBREG (v2f64 (IMPLICIT_DEF)), FR64:$src,
2642                                           sub_sd))>;
2643
2644   // Assembler Only
2645   def VMOVMSKPSr64r : PI<0x50, MRMSrcReg, (outs GR64:$dst), (ins VR128:$src),
2646              "movmskps\t{$src, $dst|$dst, $src}", [], SSEPackedSingle>, TB, VEX;
2647   def VMOVMSKPDr64r : PI<0x50, MRMSrcReg, (outs GR64:$dst), (ins VR128:$src),
2648              "movmskpd\t{$src, $dst|$dst, $src}", [], SSEPackedDouble>, TB,
2649              OpSize, VEX;
2650   def VMOVMSKPSYr64r : PI<0x50, MRMSrcReg, (outs GR64:$dst), (ins VR256:$src),
2651              "movmskps\t{$src, $dst|$dst, $src}", [], SSEPackedSingle>, TB, VEX;
2652   def VMOVMSKPDYr64r : PI<0x50, MRMSrcReg, (outs GR64:$dst), (ins VR256:$src),
2653              "movmskpd\t{$src, $dst|$dst, $src}", [], SSEPackedDouble>, TB,
2654              OpSize, VEX;
2655 }
2656
2657 defm MOVMSKPS : sse12_extr_sign_mask<VR128, int_x86_sse_movmsk_ps, "movmskps",
2658                                      SSEPackedSingle>, TB;
2659 defm MOVMSKPD : sse12_extr_sign_mask<VR128, int_x86_sse2_movmsk_pd, "movmskpd",
2660                                      SSEPackedDouble>, TB, OpSize;
2661
2662 def : Pat<(i32 (X86fgetsign FR32:$src)),
2663           (MOVMSKPSrr32 (INSERT_SUBREG (v4f32 (IMPLICIT_DEF)), FR32:$src,
2664                                        sub_ss))>, Requires<[HasSSE1]>;
2665 def : Pat<(i64 (X86fgetsign FR32:$src)),
2666           (MOVMSKPSrr64 (INSERT_SUBREG (v4f32 (IMPLICIT_DEF)), FR32:$src,
2667                                        sub_ss))>, Requires<[HasSSE1]>;
2668 def : Pat<(i32 (X86fgetsign FR64:$src)),
2669           (MOVMSKPDrr32 (INSERT_SUBREG (v2f64 (IMPLICIT_DEF)), FR64:$src,
2670                                        sub_sd))>, Requires<[HasSSE2]>;
2671 def : Pat<(i64 (X86fgetsign FR64:$src)),
2672           (MOVMSKPDrr64 (INSERT_SUBREG (v2f64 (IMPLICIT_DEF)), FR64:$src,
2673                                        sub_sd))>, Requires<[HasSSE2]>;
2674
2675 //===---------------------------------------------------------------------===//
2676 // SSE2 - Packed Integer Logical Instructions
2677 //===---------------------------------------------------------------------===//
2678
2679 let ExeDomain = SSEPackedInt in { // SSE integer instructions
2680
2681 /// PDI_binop_rm - Simple SSE2 binary operator.
2682 multiclass PDI_binop_rm<bits<8> opc, string OpcodeStr, SDNode OpNode,
2683                         ValueType OpVT, RegisterClass RC, PatFrag memop_frag,
2684                         X86MemOperand x86memop, bit IsCommutable = 0,
2685                         bit Is2Addr = 1> {
2686   let isCommutable = IsCommutable in
2687   def rr : PDI<opc, MRMSrcReg, (outs RC:$dst),
2688        (ins RC:$src1, RC:$src2),
2689        !if(Is2Addr,
2690            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
2691            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
2692        [(set RC:$dst, (OpVT (OpNode RC:$src1, RC:$src2)))]>;
2693   def rm : PDI<opc, MRMSrcMem, (outs RC:$dst),
2694        (ins RC:$src1, x86memop:$src2),
2695        !if(Is2Addr,
2696            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
2697            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
2698        [(set RC:$dst, (OpVT (OpNode RC:$src1,
2699                                      (bitconvert (memop_frag addr:$src2)))))]>;
2700 }
2701 } // ExeDomain = SSEPackedInt
2702
2703 // These are ordered here for pattern ordering requirements with the fp versions
2704
2705 let Predicates = [HasAVX] in {
2706 defm VPAND : PDI_binop_rm<0xDB, "vpand", and, v2i64, VR128, memopv2i64,
2707                           i128mem, 1, 0>, VEX_4V;
2708 defm VPOR  : PDI_binop_rm<0xEB, "vpor" , or, v2i64, VR128, memopv2i64,
2709                           i128mem, 1, 0>, VEX_4V;
2710 defm VPXOR : PDI_binop_rm<0xEF, "vpxor", xor, v2i64, VR128, memopv2i64,
2711                           i128mem, 1, 0>, VEX_4V;
2712 defm VPANDN : PDI_binop_rm<0xDF, "vpandn", X86andnp, v2i64, VR128, memopv2i64,
2713                           i128mem, 0, 0>, VEX_4V;
2714 }
2715
2716 let Constraints = "$src1 = $dst" in {
2717 defm PAND : PDI_binop_rm<0xDB, "pand", and, v2i64, VR128, memopv2i64,
2718                          i128mem, 1>;
2719 defm POR  : PDI_binop_rm<0xEB, "por" , or, v2i64, VR128, memopv2i64,
2720                          i128mem, 1>;
2721 defm PXOR : PDI_binop_rm<0xEF, "pxor", xor, v2i64, VR128, memopv2i64,
2722                          i128mem, 1>;
2723 defm PANDN : PDI_binop_rm<0xDF, "pandn", X86andnp, v2i64, VR128, memopv2i64,
2724                           i128mem, 0>;
2725 } // Constraints = "$src1 = $dst"
2726
2727 let Predicates = [HasAVX2] in {
2728 defm VPANDY : PDI_binop_rm<0xDB, "vpand", and, v4i64, VR256, memopv4i64,
2729                            i256mem, 1, 0>, VEX_4V;
2730 defm VPORY  : PDI_binop_rm<0xEB, "vpor", or, v4i64, VR256, memopv4i64,
2731                            i256mem, 1, 0>, VEX_4V;
2732 defm VPXORY : PDI_binop_rm<0xEF, "vpxor", xor, v4i64, VR256, memopv4i64,
2733                            i256mem, 1, 0>, VEX_4V;
2734 defm VPANDNY : PDI_binop_rm<0xDF, "vpandn", X86andnp, v4i64, VR256, memopv4i64,
2735                             i256mem, 0, 0>, VEX_4V;
2736 }
2737
2738 //===----------------------------------------------------------------------===//
2739 // SSE 1 & 2 - Logical Instructions
2740 //===----------------------------------------------------------------------===//
2741
2742 /// sse12_fp_alias_pack_logical - SSE 1 & 2 aliased packed FP logical ops
2743 ///
2744 multiclass sse12_fp_alias_pack_logical<bits<8> opc, string OpcodeStr,
2745                                        SDNode OpNode> {
2746   defm V#NAME#PS : sse12_fp_packed<opc, !strconcat(OpcodeStr, "ps"), OpNode,
2747               FR32, f32, f128mem, memopfsf32, SSEPackedSingle, 0>, TB, VEX_4V;
2748
2749   defm V#NAME#PD : sse12_fp_packed<opc, !strconcat(OpcodeStr, "pd"), OpNode,
2750         FR64, f64, f128mem, memopfsf64, SSEPackedDouble, 0>, TB, OpSize, VEX_4V;
2751
2752   let Constraints = "$src1 = $dst" in {
2753     defm PS : sse12_fp_packed<opc, !strconcat(OpcodeStr, "ps"), OpNode, FR32,
2754                 f32, f128mem, memopfsf32, SSEPackedSingle>, TB;
2755
2756     defm PD : sse12_fp_packed<opc, !strconcat(OpcodeStr, "pd"), OpNode, FR64,
2757                 f64, f128mem, memopfsf64, SSEPackedDouble>, TB, OpSize;
2758   }
2759 }
2760
2761 // Alias bitwise logical operations using SSE logical ops on packed FP values.
2762 let mayLoad = 0 in {
2763   defm FsAND  : sse12_fp_alias_pack_logical<0x54, "and", X86fand>;
2764   defm FsOR   : sse12_fp_alias_pack_logical<0x56, "or", X86for>;
2765   defm FsXOR  : sse12_fp_alias_pack_logical<0x57, "xor", X86fxor>;
2766 }
2767
2768 let neverHasSideEffects = 1, Pattern = []<dag>, isCommutable = 0 in
2769   defm FsANDN : sse12_fp_alias_pack_logical<0x55, "andn", undef>;
2770
2771 /// sse12_fp_packed_logical - SSE 1 & 2 packed FP logical ops
2772 ///
2773 multiclass sse12_fp_packed_logical<bits<8> opc, string OpcodeStr,
2774                                    SDNode OpNode> {
2775   // In AVX no need to add a pattern for 128-bit logical rr ps, because they
2776   // are all promoted to v2i64, and the patterns are covered by the int
2777   // version. This is needed in SSE only, because v2i64 isn't supported on
2778   // SSE1, but only on SSE2.
2779   defm V#NAME#PS : sse12_fp_packed_logical_rm<opc, VR128, SSEPackedSingle,
2780        !strconcat(OpcodeStr, "ps"), f128mem, [],
2781        [(set VR128:$dst, (OpNode (bc_v2i64 (v4f32 VR128:$src1)),
2782                                  (memopv2i64 addr:$src2)))], 0, 1>, TB, VEX_4V;
2783
2784   defm V#NAME#PD : sse12_fp_packed_logical_rm<opc, VR128, SSEPackedDouble,
2785        !strconcat(OpcodeStr, "pd"), f128mem,
2786        [(set VR128:$dst, (OpNode (bc_v2i64 (v2f64 VR128:$src1)),
2787                                  (bc_v2i64 (v2f64 VR128:$src2))))],
2788        [(set VR128:$dst, (OpNode (bc_v2i64 (v2f64 VR128:$src1)),
2789                                  (memopv2i64 addr:$src2)))], 0>,
2790                                                  TB, OpSize, VEX_4V;
2791   let Constraints = "$src1 = $dst" in {
2792     defm PS : sse12_fp_packed_logical_rm<opc, VR128, SSEPackedSingle,
2793          !strconcat(OpcodeStr, "ps"), f128mem,
2794          [(set VR128:$dst, (v2i64 (OpNode VR128:$src1, VR128:$src2)))],
2795          [(set VR128:$dst, (OpNode (bc_v2i64 (v4f32 VR128:$src1)),
2796                                    (memopv2i64 addr:$src2)))]>, TB;
2797
2798     defm PD : sse12_fp_packed_logical_rm<opc, VR128, SSEPackedDouble,
2799          !strconcat(OpcodeStr, "pd"), f128mem,
2800          [(set VR128:$dst, (OpNode (bc_v2i64 (v2f64 VR128:$src1)),
2801                                    (bc_v2i64 (v2f64 VR128:$src2))))],
2802          [(set VR128:$dst, (OpNode (bc_v2i64 (v2f64 VR128:$src1)),
2803                                    (memopv2i64 addr:$src2)))]>, TB, OpSize;
2804   }
2805 }
2806
2807 /// sse12_fp_packed_logical_y - AVX 256-bit SSE 1 & 2 logical ops forms
2808 ///
2809 multiclass sse12_fp_packed_logical_y<bits<8> opc, string OpcodeStr,
2810                                      SDNode OpNode> {
2811     defm PSY : sse12_fp_packed_logical_rm<opc, VR256, SSEPackedSingle,
2812           !strconcat(OpcodeStr, "ps"), f256mem,
2813           [(set VR256:$dst, (v4i64 (OpNode VR256:$src1, VR256:$src2)))],
2814           [(set VR256:$dst, (OpNode (bc_v4i64 (v8f32 VR256:$src1)),
2815                                     (memopv4i64 addr:$src2)))], 0>, TB, VEX_4V;
2816
2817     defm PDY : sse12_fp_packed_logical_rm<opc, VR256, SSEPackedDouble,
2818           !strconcat(OpcodeStr, "pd"), f256mem,
2819           [(set VR256:$dst, (OpNode (bc_v4i64 (v4f64 VR256:$src1)),
2820                                     (bc_v4i64 (v4f64 VR256:$src2))))],
2821           [(set VR256:$dst, (OpNode (bc_v4i64 (v4f64 VR256:$src1)),
2822                                     (memopv4i64 addr:$src2)))], 0>,
2823                                     TB, OpSize, VEX_4V;
2824 }
2825
2826 // AVX 256-bit packed logical ops forms
2827 defm VAND  : sse12_fp_packed_logical_y<0x54, "and", and>;
2828 defm VOR   : sse12_fp_packed_logical_y<0x56, "or", or>;
2829 defm VXOR  : sse12_fp_packed_logical_y<0x57, "xor", xor>;
2830 defm VANDN : sse12_fp_packed_logical_y<0x55, "andn", X86andnp>;
2831
2832 defm AND  : sse12_fp_packed_logical<0x54, "and", and>;
2833 defm OR   : sse12_fp_packed_logical<0x56, "or", or>;
2834 defm XOR  : sse12_fp_packed_logical<0x57, "xor", xor>;
2835 let isCommutable = 0 in
2836   defm ANDN : sse12_fp_packed_logical<0x55, "andn", X86andnp>;
2837
2838 //===----------------------------------------------------------------------===//
2839 // SSE 1 & 2 - Arithmetic Instructions
2840 //===----------------------------------------------------------------------===//
2841
2842 /// basic_sse12_fp_binop_xxx - SSE 1 & 2 binops come in both scalar and
2843 /// vector forms.
2844 ///
2845 /// In addition, we also have a special variant of the scalar form here to
2846 /// represent the associated intrinsic operation.  This form is unlike the
2847 /// plain scalar form, in that it takes an entire vector (instead of a scalar)
2848 /// and leaves the top elements unmodified (therefore these cannot be commuted).
2849 ///
2850 /// These three forms can each be reg+reg or reg+mem.
2851 ///
2852
2853 /// FIXME: once all 256-bit intrinsics are matched, cleanup and refactor those
2854 /// classes below
2855 multiclass basic_sse12_fp_binop_s<bits<8> opc, string OpcodeStr, SDNode OpNode,
2856                                   bit Is2Addr = 1> {
2857   defm SS : sse12_fp_scalar<opc, !strconcat(OpcodeStr, "ss"),
2858                             OpNode, FR32, f32mem, Is2Addr>, XS;
2859   defm SD : sse12_fp_scalar<opc, !strconcat(OpcodeStr, "sd"),
2860                             OpNode, FR64, f64mem, Is2Addr>, XD;
2861 }
2862
2863 multiclass basic_sse12_fp_binop_p<bits<8> opc, string OpcodeStr, SDNode OpNode,
2864                                    bit Is2Addr = 1> {
2865   let mayLoad = 0 in {
2866   defm PS : sse12_fp_packed<opc, !strconcat(OpcodeStr, "ps"), OpNode, VR128,
2867               v4f32, f128mem, memopv4f32, SSEPackedSingle, Is2Addr>, TB;
2868   defm PD : sse12_fp_packed<opc, !strconcat(OpcodeStr, "pd"), OpNode, VR128,
2869               v2f64, f128mem, memopv2f64, SSEPackedDouble, Is2Addr>, TB, OpSize;
2870   }
2871 }
2872
2873 multiclass basic_sse12_fp_binop_p_y<bits<8> opc, string OpcodeStr,
2874                                     SDNode OpNode> {
2875   let mayLoad = 0 in {
2876     defm PSY : sse12_fp_packed<opc, !strconcat(OpcodeStr, "ps"), OpNode, VR256,
2877                 v8f32, f256mem, memopv8f32, SSEPackedSingle, 0>, TB;
2878     defm PDY : sse12_fp_packed<opc, !strconcat(OpcodeStr, "pd"), OpNode, VR256,
2879                 v4f64, f256mem, memopv4f64, SSEPackedDouble, 0>, TB, OpSize;
2880   }
2881 }
2882
2883 multiclass basic_sse12_fp_binop_s_int<bits<8> opc, string OpcodeStr,
2884                                       bit Is2Addr = 1> {
2885   defm SS : sse12_fp_scalar_int<opc, OpcodeStr, VR128,
2886      !strconcat(OpcodeStr, "ss"), "", "_ss", ssmem, sse_load_f32, Is2Addr>, XS;
2887   defm SD : sse12_fp_scalar_int<opc, OpcodeStr, VR128,
2888      !strconcat(OpcodeStr, "sd"), "2", "_sd", sdmem, sse_load_f64, Is2Addr>, XD;
2889 }
2890
2891 multiclass basic_sse12_fp_binop_p_int<bits<8> opc, string OpcodeStr,
2892                                       bit Is2Addr = 1> {
2893   defm PS : sse12_fp_packed_int<opc, OpcodeStr, VR128,
2894      !strconcat(OpcodeStr, "ps"), "sse", "_ps", f128mem, memopv4f32,
2895                                               SSEPackedSingle, Is2Addr>, TB;
2896
2897   defm PD : sse12_fp_packed_int<opc, OpcodeStr, VR128,
2898      !strconcat(OpcodeStr, "pd"), "sse2", "_pd", f128mem, memopv2f64,
2899                                       SSEPackedDouble, Is2Addr>, TB, OpSize;
2900 }
2901
2902 multiclass basic_sse12_fp_binop_p_y_int<bits<8> opc, string OpcodeStr> {
2903   defm PSY : sse12_fp_packed_int<opc, OpcodeStr, VR256,
2904      !strconcat(OpcodeStr, "ps"), "avx", "_ps_256", f256mem, memopv8f32,
2905       SSEPackedSingle, 0>, TB;
2906
2907   defm PDY : sse12_fp_packed_int<opc, OpcodeStr, VR256,
2908      !strconcat(OpcodeStr, "pd"), "avx", "_pd_256", f256mem, memopv4f64,
2909       SSEPackedDouble, 0>, TB, OpSize;
2910 }
2911
2912 // Binary Arithmetic instructions
2913 defm VADD : basic_sse12_fp_binop_s<0x58, "add", fadd, 0>,
2914             basic_sse12_fp_binop_s_int<0x58, "add", 0>, VEX_4V, VEX_LIG;
2915 defm VADD : basic_sse12_fp_binop_p<0x58, "add", fadd, 0>,
2916             basic_sse12_fp_binop_p_y<0x58, "add", fadd>, VEX_4V;
2917 defm VMUL : basic_sse12_fp_binop_s<0x59, "mul", fmul, 0>,
2918             basic_sse12_fp_binop_s_int<0x59, "mul", 0>, VEX_4V, VEX_LIG;
2919 defm VMUL : basic_sse12_fp_binop_p<0x59, "mul", fmul, 0>,
2920             basic_sse12_fp_binop_p_y<0x59, "mul", fmul>, VEX_4V;
2921
2922 let isCommutable = 0 in {
2923   defm VSUB : basic_sse12_fp_binop_s<0x5C, "sub", fsub, 0>,
2924               basic_sse12_fp_binop_s_int<0x5C, "sub", 0>, VEX_4V, VEX_LIG;
2925   defm VSUB : basic_sse12_fp_binop_p<0x5C, "sub", fsub, 0>,
2926               basic_sse12_fp_binop_p_y<0x5C, "sub", fsub>, VEX_4V;
2927   defm VDIV : basic_sse12_fp_binop_s<0x5E, "div", fdiv, 0>,
2928               basic_sse12_fp_binop_s_int<0x5E, "div", 0>, VEX_4V, VEX_LIG;
2929   defm VDIV : basic_sse12_fp_binop_p<0x5E, "div", fdiv, 0>,
2930               basic_sse12_fp_binop_p_y<0x5E, "div", fdiv>, VEX_4V;
2931   defm VMAX : basic_sse12_fp_binop_s<0x5F, "max", X86fmax, 0>,
2932               basic_sse12_fp_binop_s_int<0x5F, "max", 0>, VEX_4V, VEX_LIG;
2933   defm VMAX : basic_sse12_fp_binop_p<0x5F, "max", X86fmax, 0>,
2934               basic_sse12_fp_binop_p_int<0x5F, "max", 0>,
2935               basic_sse12_fp_binop_p_y<0x5F, "max", X86fmax>,
2936               basic_sse12_fp_binop_p_y_int<0x5F, "max">, VEX_4V;
2937   defm VMIN : basic_sse12_fp_binop_s<0x5D, "min", X86fmin, 0>,
2938               basic_sse12_fp_binop_s_int<0x5D, "min", 0>, VEX_4V, VEX_LIG;
2939   defm VMIN : basic_sse12_fp_binop_p<0x5D, "min", X86fmin, 0>,
2940               basic_sse12_fp_binop_p_int<0x5D, "min", 0>,
2941               basic_sse12_fp_binop_p_y_int<0x5D, "min">,
2942               basic_sse12_fp_binop_p_y<0x5D, "min", X86fmin>, VEX_4V;
2943 }
2944
2945 let Constraints = "$src1 = $dst" in {
2946   defm ADD : basic_sse12_fp_binop_s<0x58, "add", fadd>,
2947              basic_sse12_fp_binop_p<0x58, "add", fadd>,
2948              basic_sse12_fp_binop_s_int<0x58, "add">;
2949   defm MUL : basic_sse12_fp_binop_s<0x59, "mul", fmul>,
2950              basic_sse12_fp_binop_p<0x59, "mul", fmul>,
2951              basic_sse12_fp_binop_s_int<0x59, "mul">;
2952
2953   let isCommutable = 0 in {
2954     defm SUB : basic_sse12_fp_binop_s<0x5C, "sub", fsub>,
2955                basic_sse12_fp_binop_p<0x5C, "sub", fsub>,
2956                basic_sse12_fp_binop_s_int<0x5C, "sub">;
2957     defm DIV : basic_sse12_fp_binop_s<0x5E, "div", fdiv>,
2958                basic_sse12_fp_binop_p<0x5E, "div", fdiv>,
2959                basic_sse12_fp_binop_s_int<0x5E, "div">;
2960     defm MAX : basic_sse12_fp_binop_s<0x5F, "max", X86fmax>,
2961                basic_sse12_fp_binop_p<0x5F, "max", X86fmax>,
2962                basic_sse12_fp_binop_s_int<0x5F, "max">,
2963                basic_sse12_fp_binop_p_int<0x5F, "max">;
2964     defm MIN : basic_sse12_fp_binop_s<0x5D, "min", X86fmin>,
2965                basic_sse12_fp_binop_p<0x5D, "min", X86fmin>,
2966                basic_sse12_fp_binop_s_int<0x5D, "min">,
2967                basic_sse12_fp_binop_p_int<0x5D, "min">;
2968   }
2969 }
2970
2971 /// Unop Arithmetic
2972 /// In addition, we also have a special variant of the scalar form here to
2973 /// represent the associated intrinsic operation.  This form is unlike the
2974 /// plain scalar form, in that it takes an entire vector (instead of a
2975 /// scalar) and leaves the top elements undefined.
2976 ///
2977 /// And, we have a special variant form for a full-vector intrinsic form.
2978
2979 /// sse1_fp_unop_s - SSE1 unops in scalar form.
2980 multiclass sse1_fp_unop_s<bits<8> opc, string OpcodeStr,
2981                           SDNode OpNode, Intrinsic F32Int> {
2982   def SSr : SSI<opc, MRMSrcReg, (outs FR32:$dst), (ins FR32:$src),
2983                 !strconcat(OpcodeStr, "ss\t{$src, $dst|$dst, $src}"),
2984                 [(set FR32:$dst, (OpNode FR32:$src))]>;
2985   // For scalar unary operations, fold a load into the operation
2986   // only in OptForSize mode. It eliminates an instruction, but it also
2987   // eliminates a whole-register clobber (the load), so it introduces a
2988   // partial register update condition.
2989   def SSm : I<opc, MRMSrcMem, (outs FR32:$dst), (ins f32mem:$src),
2990                 !strconcat(OpcodeStr, "ss\t{$src, $dst|$dst, $src}"),
2991                 [(set FR32:$dst, (OpNode (load addr:$src)))]>, XS,
2992             Requires<[HasSSE1, OptForSize]>;
2993   def SSr_Int : SSI<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2994                     !strconcat(OpcodeStr, "ss\t{$src, $dst|$dst, $src}"),
2995                     [(set VR128:$dst, (F32Int VR128:$src))]>;
2996   def SSm_Int : SSI<opc, MRMSrcMem, (outs VR128:$dst), (ins ssmem:$src),
2997                     !strconcat(OpcodeStr, "ss\t{$src, $dst|$dst, $src}"),
2998                     [(set VR128:$dst, (F32Int sse_load_f32:$src))]>;
2999 }
3000
3001 /// sse1_fp_unop_s_avx - AVX SSE1 unops in scalar form.
3002 multiclass sse1_fp_unop_s_avx<bits<8> opc, string OpcodeStr> {
3003   def SSr : SSI<opc, MRMSrcReg, (outs FR32:$dst), (ins FR32:$src1, FR32:$src2),
3004                 !strconcat(OpcodeStr,
3005                            "ss\t{$src2, $src1, $dst|$dst, $src1, $src2}"), []>;
3006   let mayLoad = 1 in
3007   def SSm : SSI<opc, MRMSrcMem, (outs FR32:$dst), (ins FR32:$src1,f32mem:$src2),
3008                 !strconcat(OpcodeStr,
3009                            "ss\t{$src2, $src1, $dst|$dst, $src1, $src2}"), []>;
3010   def SSm_Int : SSI<opc, MRMSrcMem, (outs VR128:$dst),
3011                 (ins VR128:$src1, ssmem:$src2),
3012                 !strconcat(OpcodeStr,
3013                            "ss\t{$src2, $src1, $dst|$dst, $src1, $src2}"), []>;
3014 }
3015
3016 /// sse1_fp_unop_p - SSE1 unops in packed form.
3017 multiclass sse1_fp_unop_p<bits<8> opc, string OpcodeStr, SDNode OpNode> {
3018   def PSr : PSI<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3019               !strconcat(OpcodeStr, "ps\t{$src, $dst|$dst, $src}"),
3020               [(set VR128:$dst, (v4f32 (OpNode VR128:$src)))]>;
3021   def PSm : PSI<opc, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
3022                 !strconcat(OpcodeStr, "ps\t{$src, $dst|$dst, $src}"),
3023                 [(set VR128:$dst, (OpNode (memopv4f32 addr:$src)))]>;
3024 }
3025
3026 /// sse1_fp_unop_p_y - AVX 256-bit SSE1 unops in packed form.
3027 multiclass sse1_fp_unop_p_y<bits<8> opc, string OpcodeStr, SDNode OpNode> {
3028   def PSYr : PSI<opc, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
3029               !strconcat(OpcodeStr, "ps\t{$src, $dst|$dst, $src}"),
3030               [(set VR256:$dst, (v8f32 (OpNode VR256:$src)))]>;
3031   def PSYm : PSI<opc, MRMSrcMem, (outs VR256:$dst), (ins f256mem:$src),
3032                 !strconcat(OpcodeStr, "ps\t{$src, $dst|$dst, $src}"),
3033                 [(set VR256:$dst, (OpNode (memopv8f32 addr:$src)))]>;
3034 }
3035
3036 /// sse1_fp_unop_p_int - SSE1 intrinsics unops in packed forms.
3037 multiclass sse1_fp_unop_p_int<bits<8> opc, string OpcodeStr,
3038                               Intrinsic V4F32Int> {
3039   def PSr_Int : PSI<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3040                     !strconcat(OpcodeStr, "ps\t{$src, $dst|$dst, $src}"),
3041                     [(set VR128:$dst, (V4F32Int VR128:$src))]>;
3042   def PSm_Int : PSI<opc, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
3043                     !strconcat(OpcodeStr, "ps\t{$src, $dst|$dst, $src}"),
3044                     [(set VR128:$dst, (V4F32Int (memopv4f32 addr:$src)))]>;
3045 }
3046
3047 /// sse1_fp_unop_p_y_int - AVX 256-bit intrinsics unops in packed forms.
3048 multiclass sse1_fp_unop_p_y_int<bits<8> opc, string OpcodeStr,
3049                                 Intrinsic V4F32Int> {
3050   def PSYr_Int : PSI<opc, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
3051                     !strconcat(OpcodeStr, "ps\t{$src, $dst|$dst, $src}"),
3052                     [(set VR256:$dst, (V4F32Int VR256:$src))]>;
3053   def PSYm_Int : PSI<opc, MRMSrcMem, (outs VR256:$dst), (ins f256mem:$src),
3054                     !strconcat(OpcodeStr, "ps\t{$src, $dst|$dst, $src}"),
3055                     [(set VR256:$dst, (V4F32Int (memopv8f32 addr:$src)))]>;
3056 }
3057
3058 /// sse2_fp_unop_s - SSE2 unops in scalar form.
3059 multiclass sse2_fp_unop_s<bits<8> opc, string OpcodeStr,
3060                           SDNode OpNode, Intrinsic F64Int> {
3061   def SDr : SDI<opc, MRMSrcReg, (outs FR64:$dst), (ins FR64:$src),
3062                 !strconcat(OpcodeStr, "sd\t{$src, $dst|$dst, $src}"),
3063                 [(set FR64:$dst, (OpNode FR64:$src))]>;
3064   // See the comments in sse1_fp_unop_s for why this is OptForSize.
3065   def SDm : I<opc, MRMSrcMem, (outs FR64:$dst), (ins f64mem:$src),
3066                 !strconcat(OpcodeStr, "sd\t{$src, $dst|$dst, $src}"),
3067                 [(set FR64:$dst, (OpNode (load addr:$src)))]>, XD,
3068             Requires<[HasSSE2, OptForSize]>;
3069   def SDr_Int : SDI<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3070                     !strconcat(OpcodeStr, "sd\t{$src, $dst|$dst, $src}"),
3071                     [(set VR128:$dst, (F64Int VR128:$src))]>;
3072   def SDm_Int : SDI<opc, MRMSrcMem, (outs VR128:$dst), (ins sdmem:$src),
3073                     !strconcat(OpcodeStr, "sd\t{$src, $dst|$dst, $src}"),
3074                     [(set VR128:$dst, (F64Int sse_load_f64:$src))]>;
3075 }
3076
3077 /// sse2_fp_unop_s_avx - AVX SSE2 unops in scalar form.
3078 multiclass sse2_fp_unop_s_avx<bits<8> opc, string OpcodeStr> {
3079   let neverHasSideEffects = 1 in {
3080   def SDr : SDI<opc, MRMSrcReg, (outs FR64:$dst), (ins FR64:$src1, FR64:$src2),
3081                !strconcat(OpcodeStr,
3082                           "sd\t{$src2, $src1, $dst|$dst, $src1, $src2}"), []>;
3083   let mayLoad = 1 in
3084   def SDm : SDI<opc, MRMSrcMem, (outs FR64:$dst), (ins FR64:$src1,f64mem:$src2),
3085                !strconcat(OpcodeStr,
3086                           "sd\t{$src2, $src1, $dst|$dst, $src1, $src2}"), []>;
3087   }
3088   def SDm_Int : SDI<opc, MRMSrcMem, (outs VR128:$dst),
3089                (ins VR128:$src1, sdmem:$src2),
3090                !strconcat(OpcodeStr,
3091                           "sd\t{$src2, $src1, $dst|$dst, $src1, $src2}"), []>;
3092 }
3093
3094 /// sse2_fp_unop_p - SSE2 unops in vector forms.
3095 multiclass sse2_fp_unop_p<bits<8> opc, string OpcodeStr,
3096                           SDNode OpNode> {
3097   def PDr : PDI<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3098               !strconcat(OpcodeStr, "pd\t{$src, $dst|$dst, $src}"),
3099               [(set VR128:$dst, (v2f64 (OpNode VR128:$src)))]>;
3100   def PDm : PDI<opc, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
3101                 !strconcat(OpcodeStr, "pd\t{$src, $dst|$dst, $src}"),
3102                 [(set VR128:$dst, (OpNode (memopv2f64 addr:$src)))]>;
3103 }
3104
3105 /// sse2_fp_unop_p_y - AVX SSE2 256-bit unops in vector forms.
3106 multiclass sse2_fp_unop_p_y<bits<8> opc, string OpcodeStr, SDNode OpNode> {
3107   def PDYr : PDI<opc, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
3108               !strconcat(OpcodeStr, "pd\t{$src, $dst|$dst, $src}"),
3109               [(set VR256:$dst, (v4f64 (OpNode VR256:$src)))]>;
3110   def PDYm : PDI<opc, MRMSrcMem, (outs VR256:$dst), (ins f256mem:$src),
3111                 !strconcat(OpcodeStr, "pd\t{$src, $dst|$dst, $src}"),
3112                 [(set VR256:$dst, (OpNode (memopv4f64 addr:$src)))]>;
3113 }
3114
3115 /// sse2_fp_unop_p_int - SSE2 intrinsic unops in vector forms.
3116 multiclass sse2_fp_unop_p_int<bits<8> opc, string OpcodeStr,
3117                               Intrinsic V2F64Int> {
3118   def PDr_Int : PDI<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3119                     !strconcat(OpcodeStr, "pd\t{$src, $dst|$dst, $src}"),
3120                     [(set VR128:$dst, (V2F64Int VR128:$src))]>;
3121   def PDm_Int : PDI<opc, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
3122                     !strconcat(OpcodeStr, "pd\t{$src, $dst|$dst, $src}"),
3123                     [(set VR128:$dst, (V2F64Int (memopv2f64 addr:$src)))]>;
3124 }
3125
3126 /// sse2_fp_unop_p_y_int - AVX 256-bit intrinsic unops in vector forms.
3127 multiclass sse2_fp_unop_p_y_int<bits<8> opc, string OpcodeStr,
3128                                 Intrinsic V2F64Int> {
3129   def PDYr_Int : PDI<opc, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
3130                     !strconcat(OpcodeStr, "pd\t{$src, $dst|$dst, $src}"),
3131                     [(set VR256:$dst, (V2F64Int VR256:$src))]>;
3132   def PDYm_Int : PDI<opc, MRMSrcMem, (outs VR256:$dst), (ins f256mem:$src),
3133                     !strconcat(OpcodeStr, "pd\t{$src, $dst|$dst, $src}"),
3134                     [(set VR256:$dst, (V2F64Int (memopv4f64 addr:$src)))]>;
3135 }
3136
3137 let Predicates = [HasAVX] in {
3138   // Square root.
3139   defm VSQRT  : sse1_fp_unop_s_avx<0x51, "vsqrt">,
3140                 sse2_fp_unop_s_avx<0x51, "vsqrt">, VEX_4V, VEX_LIG;
3141
3142   defm VSQRT  : sse1_fp_unop_p<0x51, "vsqrt", fsqrt>,
3143                 sse2_fp_unop_p<0x51, "vsqrt", fsqrt>,
3144                 sse1_fp_unop_p_y<0x51, "vsqrt", fsqrt>,
3145                 sse2_fp_unop_p_y<0x51, "vsqrt", fsqrt>,
3146                 sse1_fp_unop_p_int<0x51, "vsqrt", int_x86_sse_sqrt_ps>,
3147                 sse2_fp_unop_p_int<0x51, "vsqrt", int_x86_sse2_sqrt_pd>,
3148                 sse1_fp_unop_p_y_int<0x51, "vsqrt", int_x86_avx_sqrt_ps_256>,
3149                 sse2_fp_unop_p_y_int<0x51, "vsqrt", int_x86_avx_sqrt_pd_256>,
3150                 VEX;
3151
3152   // Reciprocal approximations. Note that these typically require refinement
3153   // in order to obtain suitable precision.
3154   defm VRSQRT : sse1_fp_unop_s_avx<0x52, "vrsqrt">, VEX_4V, VEX_LIG;
3155   defm VRSQRT : sse1_fp_unop_p<0x52, "vrsqrt", X86frsqrt>,
3156                 sse1_fp_unop_p_y<0x52, "vrsqrt", X86frsqrt>,
3157                 sse1_fp_unop_p_y_int<0x52, "vrsqrt", int_x86_avx_rsqrt_ps_256>,
3158                 sse1_fp_unop_p_int<0x52, "vrsqrt", int_x86_sse_rsqrt_ps>, VEX;
3159
3160   defm VRCP   : sse1_fp_unop_s_avx<0x53, "vrcp">, VEX_4V, VEX_LIG;
3161   defm VRCP   : sse1_fp_unop_p<0x53, "vrcp", X86frcp>,
3162                 sse1_fp_unop_p_y<0x53, "vrcp", X86frcp>,
3163                 sse1_fp_unop_p_y_int<0x53, "vrcp", int_x86_avx_rcp_ps_256>,
3164                 sse1_fp_unop_p_int<0x53, "vrcp", int_x86_sse_rcp_ps>, VEX;
3165 }
3166
3167 let AddedComplexity = 1 in {
3168 def : Pat<(f32 (fsqrt FR32:$src)),
3169           (VSQRTSSr (f32 (IMPLICIT_DEF)), FR32:$src)>, Requires<[HasAVX]>;
3170 def : Pat<(f32 (fsqrt (load addr:$src))),
3171           (VSQRTSSm (f32 (IMPLICIT_DEF)), addr:$src)>,
3172           Requires<[HasAVX, OptForSize]>;
3173 def : Pat<(f64 (fsqrt FR64:$src)),
3174           (VSQRTSDr (f64 (IMPLICIT_DEF)), FR64:$src)>, Requires<[HasAVX]>;
3175 def : Pat<(f64 (fsqrt (load addr:$src))),
3176           (VSQRTSDm (f64 (IMPLICIT_DEF)), addr:$src)>,
3177           Requires<[HasAVX, OptForSize]>;
3178
3179 def : Pat<(f32 (X86frsqrt FR32:$src)),
3180           (VRSQRTSSr (f32 (IMPLICIT_DEF)), FR32:$src)>, Requires<[HasAVX]>;
3181 def : Pat<(f32 (X86frsqrt (load addr:$src))),
3182           (VRSQRTSSm (f32 (IMPLICIT_DEF)), addr:$src)>,
3183           Requires<[HasAVX, OptForSize]>;
3184
3185 def : Pat<(f32 (X86frcp FR32:$src)),
3186           (VRCPSSr (f32 (IMPLICIT_DEF)), FR32:$src)>, Requires<[HasAVX]>;
3187 def : Pat<(f32 (X86frcp (load addr:$src))),
3188           (VRCPSSm (f32 (IMPLICIT_DEF)), addr:$src)>,
3189           Requires<[HasAVX, OptForSize]>;
3190 }
3191
3192 let Predicates = [HasAVX], AddedComplexity = 1 in {
3193   def : Pat<(int_x86_sse_sqrt_ss VR128:$src),
3194             (INSERT_SUBREG (v4f32 (IMPLICIT_DEF)),
3195                 (VSQRTSSr (f32 (IMPLICIT_DEF)),
3196                           (EXTRACT_SUBREG (v4f32 VR128:$src), sub_ss)),
3197                 sub_ss)>;
3198   def : Pat<(int_x86_sse_sqrt_ss sse_load_f32:$src),
3199             (VSQRTSSm_Int (v4f32 (IMPLICIT_DEF)), sse_load_f32:$src)>;
3200
3201   def : Pat<(int_x86_sse2_sqrt_sd VR128:$src),
3202             (INSERT_SUBREG (v2f64 (IMPLICIT_DEF)),
3203                 (VSQRTSDr (f64 (IMPLICIT_DEF)),
3204                           (EXTRACT_SUBREG (v2f64 VR128:$src), sub_sd)),
3205                 sub_sd)>;
3206   def : Pat<(int_x86_sse2_sqrt_sd sse_load_f64:$src),
3207             (VSQRTSDm_Int (v2f64 (IMPLICIT_DEF)), sse_load_f64:$src)>;
3208
3209   def : Pat<(int_x86_sse_rsqrt_ss VR128:$src),
3210             (INSERT_SUBREG (v4f32 (IMPLICIT_DEF)),
3211                 (VRSQRTSSr (f32 (IMPLICIT_DEF)),
3212                           (EXTRACT_SUBREG (v4f32 VR128:$src), sub_ss)),
3213                 sub_ss)>;
3214   def : Pat<(int_x86_sse_rsqrt_ss sse_load_f32:$src),
3215             (VRSQRTSSm_Int (v4f32 (IMPLICIT_DEF)), sse_load_f32:$src)>;
3216
3217   def : Pat<(int_x86_sse_rcp_ss VR128:$src),
3218             (INSERT_SUBREG (v4f32 (IMPLICIT_DEF)),
3219                 (VRCPSSr (f32 (IMPLICIT_DEF)),
3220                          (EXTRACT_SUBREG (v4f32 VR128:$src), sub_ss)),
3221                 sub_ss)>;
3222   def : Pat<(int_x86_sse_rcp_ss sse_load_f32:$src),
3223             (VRCPSSm_Int (v4f32 (IMPLICIT_DEF)), sse_load_f32:$src)>;
3224 }
3225
3226 // Square root.
3227 defm SQRT  : sse1_fp_unop_s<0x51, "sqrt",  fsqrt, int_x86_sse_sqrt_ss>,
3228              sse1_fp_unop_p<0x51, "sqrt",  fsqrt>,
3229              sse1_fp_unop_p_int<0x51, "sqrt",  int_x86_sse_sqrt_ps>,
3230              sse2_fp_unop_s<0x51, "sqrt",  fsqrt, int_x86_sse2_sqrt_sd>,
3231              sse2_fp_unop_p<0x51, "sqrt",  fsqrt>,
3232              sse2_fp_unop_p_int<0x51, "sqrt", int_x86_sse2_sqrt_pd>;
3233
3234 // Reciprocal approximations. Note that these typically require refinement
3235 // in order to obtain suitable precision.
3236 defm RSQRT : sse1_fp_unop_s<0x52, "rsqrt", X86frsqrt, int_x86_sse_rsqrt_ss>,
3237              sse1_fp_unop_p<0x52, "rsqrt", X86frsqrt>,
3238              sse1_fp_unop_p_int<0x52, "rsqrt", int_x86_sse_rsqrt_ps>;
3239 defm RCP   : sse1_fp_unop_s<0x53, "rcp", X86frcp, int_x86_sse_rcp_ss>,
3240              sse1_fp_unop_p<0x53, "rcp", X86frcp>,
3241              sse1_fp_unop_p_int<0x53, "rcp", int_x86_sse_rcp_ps>;
3242
3243 // There is no f64 version of the reciprocal approximation instructions.
3244
3245 //===----------------------------------------------------------------------===//
3246 // SSE 1 & 2 - Non-temporal stores
3247 //===----------------------------------------------------------------------===//
3248
3249 let AddedComplexity = 400 in { // Prefer non-temporal versions
3250   def VMOVNTPSmr : VPSI<0x2B, MRMDestMem, (outs),
3251                        (ins f128mem:$dst, VR128:$src),
3252                        "movntps\t{$src, $dst|$dst, $src}",
3253                        [(alignednontemporalstore (v4f32 VR128:$src),
3254                                                  addr:$dst)]>, VEX;
3255   def VMOVNTPDmr : VPDI<0x2B, MRMDestMem, (outs),
3256                        (ins f128mem:$dst, VR128:$src),
3257                        "movntpd\t{$src, $dst|$dst, $src}",
3258                        [(alignednontemporalstore (v2f64 VR128:$src),
3259                                                  addr:$dst)]>, VEX;
3260
3261   let ExeDomain = SSEPackedInt in
3262   def VMOVNTDQmr    : VPDI<0xE7, MRMDestMem, (outs),
3263                            (ins f128mem:$dst, VR128:$src),
3264                            "movntdq\t{$src, $dst|$dst, $src}",
3265                            [(alignednontemporalstore (v2i64 VR128:$src),
3266                                                      addr:$dst)]>, VEX;
3267
3268   def : Pat<(alignednontemporalstore (v2i64 VR128:$src), addr:$dst),
3269             (VMOVNTDQmr addr:$dst, VR128:$src)>, Requires<[HasAVX]>;
3270
3271   def VMOVNTPSYmr : VPSI<0x2B, MRMDestMem, (outs),
3272                        (ins f256mem:$dst, VR256:$src),
3273                        "movntps\t{$src, $dst|$dst, $src}",
3274                        [(alignednontemporalstore (v8f32 VR256:$src),
3275                                                  addr:$dst)]>, VEX;
3276   def VMOVNTPDYmr : VPDI<0x2B, MRMDestMem, (outs),
3277                        (ins f256mem:$dst, VR256:$src),
3278                        "movntpd\t{$src, $dst|$dst, $src}",
3279                        [(alignednontemporalstore (v4f64 VR256:$src),
3280                                                  addr:$dst)]>, VEX;
3281   let ExeDomain = SSEPackedInt in
3282   def VMOVNTDQYmr : VPDI<0xE7, MRMDestMem, (outs),
3283                       (ins f256mem:$dst, VR256:$src),
3284                       "movntdq\t{$src, $dst|$dst, $src}",
3285                       [(alignednontemporalstore (v4i64 VR256:$src),
3286                                                 addr:$dst)]>, VEX;
3287 }
3288
3289 def : Pat<(int_x86_avx_movnt_dq_256 addr:$dst, VR256:$src),
3290           (VMOVNTDQYmr addr:$dst, VR256:$src)>;
3291 def : Pat<(int_x86_avx_movnt_pd_256 addr:$dst, VR256:$src),
3292           (VMOVNTPDYmr addr:$dst, VR256:$src)>;
3293 def : Pat<(int_x86_avx_movnt_ps_256 addr:$dst, VR256:$src),
3294           (VMOVNTPSYmr addr:$dst, VR256:$src)>;
3295
3296 let AddedComplexity = 400 in { // Prefer non-temporal versions
3297 def MOVNTPSmr : PSI<0x2B, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
3298                     "movntps\t{$src, $dst|$dst, $src}",
3299                     [(alignednontemporalstore (v4f32 VR128:$src), addr:$dst)]>;
3300 def MOVNTPDmr : PDI<0x2B, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
3301                     "movntpd\t{$src, $dst|$dst, $src}",
3302                     [(alignednontemporalstore(v2f64 VR128:$src), addr:$dst)]>;
3303
3304 let ExeDomain = SSEPackedInt in
3305 def MOVNTDQmr : PDI<0xE7, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
3306                     "movntdq\t{$src, $dst|$dst, $src}",
3307                     [(alignednontemporalstore (v2i64 VR128:$src), addr:$dst)]>;
3308
3309 def : Pat<(alignednontemporalstore (v2i64 VR128:$src), addr:$dst),
3310           (MOVNTDQmr addr:$dst, VR128:$src)>, Requires<[HasSSE2]>;
3311
3312 // There is no AVX form for instructions below this point
3313 def MOVNTImr : I<0xC3, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
3314                  "movnti{l}\t{$src, $dst|$dst, $src}",
3315                  [(nontemporalstore (i32 GR32:$src), addr:$dst)]>,
3316                TB, Requires<[HasSSE2]>;
3317 def MOVNTI_64mr : RI<0xC3, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
3318                      "movnti{q}\t{$src, $dst|$dst, $src}",
3319                      [(nontemporalstore (i64 GR64:$src), addr:$dst)]>,
3320                   TB, Requires<[HasSSE2]>;
3321 }
3322
3323 //===----------------------------------------------------------------------===//
3324 // SSE 1 & 2 - Prefetch and memory fence
3325 //===----------------------------------------------------------------------===//
3326
3327 // Prefetch intrinsic.
3328 let Predicates = [HasSSE1] in {
3329 def PREFETCHT0   : I<0x18, MRM1m, (outs), (ins i8mem:$src),
3330     "prefetcht0\t$src", [(prefetch addr:$src, imm, (i32 3), (i32 1))]>, TB;
3331 def PREFETCHT1   : I<0x18, MRM2m, (outs), (ins i8mem:$src),
3332     "prefetcht1\t$src", [(prefetch addr:$src, imm, (i32 2), (i32 1))]>, TB;
3333 def PREFETCHT2   : I<0x18, MRM3m, (outs), (ins i8mem:$src),
3334     "prefetcht2\t$src", [(prefetch addr:$src, imm, (i32 1), (i32 1))]>, TB;
3335 def PREFETCHNTA  : I<0x18, MRM0m, (outs), (ins i8mem:$src),
3336     "prefetchnta\t$src", [(prefetch addr:$src, imm, (i32 0), (i32 1))]>, TB;
3337 }
3338
3339 // Flush cache
3340 def CLFLUSH : I<0xAE, MRM7m, (outs), (ins i8mem:$src),
3341                "clflush\t$src", [(int_x86_sse2_clflush addr:$src)]>,
3342               TB, Requires<[HasSSE2]>;
3343
3344 // Pause. This "instruction" is encoded as "rep; nop", so even though it
3345 // was introduced with SSE2, it's backward compatible.
3346 def PAUSE : I<0x90, RawFrm, (outs), (ins), "pause", []>, REP;
3347
3348 // Load, store, and memory fence
3349 def SFENCE : I<0xAE, MRM_F8, (outs), (ins),
3350                "sfence", [(int_x86_sse_sfence)]>, TB, Requires<[HasSSE1]>;
3351 def LFENCE : I<0xAE, MRM_E8, (outs), (ins),
3352                "lfence", [(int_x86_sse2_lfence)]>, TB, Requires<[HasSSE2]>;
3353 def MFENCE : I<0xAE, MRM_F0, (outs), (ins),
3354                "mfence", [(int_x86_sse2_mfence)]>, TB, Requires<[HasSSE2]>;
3355
3356 def : Pat<(X86SFence), (SFENCE)>;
3357 def : Pat<(X86LFence), (LFENCE)>;
3358 def : Pat<(X86MFence), (MFENCE)>;
3359
3360 //===----------------------------------------------------------------------===//
3361 // SSE 1 & 2 - Load/Store XCSR register
3362 //===----------------------------------------------------------------------===//
3363
3364 def VLDMXCSR : VPSI<0xAE, MRM2m, (outs), (ins i32mem:$src),
3365                   "ldmxcsr\t$src", [(int_x86_sse_ldmxcsr addr:$src)]>, VEX;
3366 def VSTMXCSR : VPSI<0xAE, MRM3m, (outs), (ins i32mem:$dst),
3367                   "stmxcsr\t$dst", [(int_x86_sse_stmxcsr addr:$dst)]>, VEX;
3368
3369 def LDMXCSR : PSI<0xAE, MRM2m, (outs), (ins i32mem:$src),
3370                   "ldmxcsr\t$src", [(int_x86_sse_ldmxcsr addr:$src)]>;
3371 def STMXCSR : PSI<0xAE, MRM3m, (outs), (ins i32mem:$dst),
3372                   "stmxcsr\t$dst", [(int_x86_sse_stmxcsr addr:$dst)]>;
3373
3374 //===---------------------------------------------------------------------===//
3375 // SSE2 - Move Aligned/Unaligned Packed Integer Instructions
3376 //===---------------------------------------------------------------------===//
3377
3378 let ExeDomain = SSEPackedInt in { // SSE integer instructions
3379
3380 let neverHasSideEffects = 1 in {
3381 def VMOVDQArr  : VPDI<0x6F, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3382                     "movdqa\t{$src, $dst|$dst, $src}", []>, VEX;
3383 def VMOVDQAYrr : VPDI<0x6F, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
3384                     "movdqa\t{$src, $dst|$dst, $src}", []>, VEX;
3385 }
3386 def VMOVDQUrr  : VSSI<0x6F, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3387                     "movdqu\t{$src, $dst|$dst, $src}", []>, VEX;
3388 def VMOVDQUYrr : VSSI<0x6F, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
3389                     "movdqu\t{$src, $dst|$dst, $src}", []>, VEX;
3390
3391 // For Disassembler
3392 let isCodeGenOnly = 1 in {
3393 def VMOVDQArr_REV  : VPDI<0x7F, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
3394                         "movdqa\t{$src, $dst|$dst, $src}", []>, VEX;
3395 def VMOVDQAYrr_REV : VPDI<0x7F, MRMDestReg, (outs VR256:$dst), (ins VR256:$src),
3396                         "movdqa\t{$src, $dst|$dst, $src}", []>, VEX;
3397 def VMOVDQUrr_REV  : VSSI<0x7F, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
3398                         "movdqu\t{$src, $dst|$dst, $src}", []>, VEX;
3399 def VMOVDQUYrr_REV : VSSI<0x7F, MRMDestReg, (outs VR256:$dst), (ins VR256:$src),
3400                         "movdqu\t{$src, $dst|$dst, $src}", []>, VEX;
3401 }
3402
3403 let canFoldAsLoad = 1, mayLoad = 1 in {
3404 def VMOVDQArm  : VPDI<0x6F, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
3405                    "movdqa\t{$src, $dst|$dst, $src}", []>, VEX;
3406 def VMOVDQAYrm : VPDI<0x6F, MRMSrcMem, (outs VR256:$dst), (ins i256mem:$src),
3407                    "movdqa\t{$src, $dst|$dst, $src}", []>, VEX;
3408 let Predicates = [HasAVX] in {
3409   def VMOVDQUrm  : I<0x6F, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
3410                     "vmovdqu\t{$src, $dst|$dst, $src}",[]>, XS, VEX;
3411   def VMOVDQUYrm : I<0x6F, MRMSrcMem, (outs VR256:$dst), (ins i256mem:$src),
3412                     "vmovdqu\t{$src, $dst|$dst, $src}",[]>, XS, VEX;
3413 }
3414 }
3415
3416 let mayStore = 1 in {
3417 def VMOVDQAmr  : VPDI<0x7F, MRMDestMem, (outs),
3418                      (ins i128mem:$dst, VR128:$src),
3419                      "movdqa\t{$src, $dst|$dst, $src}", []>, VEX;
3420 def VMOVDQAYmr : VPDI<0x7F, MRMDestMem, (outs),
3421                      (ins i256mem:$dst, VR256:$src),
3422                      "movdqa\t{$src, $dst|$dst, $src}", []>, VEX;
3423 let Predicates = [HasAVX] in {
3424 def VMOVDQUmr  : I<0x7F, MRMDestMem, (outs), (ins i128mem:$dst, VR128:$src),
3425                   "vmovdqu\t{$src, $dst|$dst, $src}",[]>, XS, VEX;
3426 def VMOVDQUYmr : I<0x7F, MRMDestMem, (outs), (ins i256mem:$dst, VR256:$src),
3427                   "vmovdqu\t{$src, $dst|$dst, $src}",[]>, XS, VEX;
3428 }
3429 }
3430
3431 let neverHasSideEffects = 1 in
3432 def MOVDQArr : PDI<0x6F, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3433                    "movdqa\t{$src, $dst|$dst, $src}", []>;
3434
3435 def MOVDQUrr :   I<0x6F, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3436                    "movdqu\t{$src, $dst|$dst, $src}",
3437                    []>, XS, Requires<[HasSSE2]>;
3438
3439 // For Disassembler
3440 let isCodeGenOnly = 1 in {
3441 def MOVDQArr_REV : PDI<0x7F, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
3442                        "movdqa\t{$src, $dst|$dst, $src}", []>;
3443
3444 def MOVDQUrr_REV :   I<0x7F, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
3445                        "movdqu\t{$src, $dst|$dst, $src}",
3446                        []>, XS, Requires<[HasSSE2]>;
3447 }
3448
3449 let canFoldAsLoad = 1, mayLoad = 1 in {
3450 def MOVDQArm : PDI<0x6F, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
3451                    "movdqa\t{$src, $dst|$dst, $src}",
3452                    [/*(set VR128:$dst, (alignedloadv2i64 addr:$src))*/]>;
3453 def MOVDQUrm :   I<0x6F, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
3454                    "movdqu\t{$src, $dst|$dst, $src}",
3455                    [/*(set VR128:$dst, (loadv2i64 addr:$src))*/]>,
3456                  XS, Requires<[HasSSE2]>;
3457 }
3458
3459 let mayStore = 1 in {
3460 def MOVDQAmr : PDI<0x7F, MRMDestMem, (outs), (ins i128mem:$dst, VR128:$src),
3461                    "movdqa\t{$src, $dst|$dst, $src}",
3462                    [/*(alignedstore (v2i64 VR128:$src), addr:$dst)*/]>;
3463 def MOVDQUmr :   I<0x7F, MRMDestMem, (outs), (ins i128mem:$dst, VR128:$src),
3464                    "movdqu\t{$src, $dst|$dst, $src}",
3465                    [/*(store (v2i64 VR128:$src), addr:$dst)*/]>,
3466                  XS, Requires<[HasSSE2]>;
3467 }
3468
3469 // Intrinsic forms of MOVDQU load and store
3470 def VMOVDQUmr_Int : I<0x7F, MRMDestMem, (outs), (ins i128mem:$dst, VR128:$src),
3471                        "vmovdqu\t{$src, $dst|$dst, $src}",
3472                        [(int_x86_sse2_storeu_dq addr:$dst, VR128:$src)]>,
3473                      XS, VEX, Requires<[HasAVX]>;
3474
3475 def MOVDQUmr_Int :   I<0x7F, MRMDestMem, (outs), (ins i128mem:$dst, VR128:$src),
3476                        "movdqu\t{$src, $dst|$dst, $src}",
3477                        [(int_x86_sse2_storeu_dq addr:$dst, VR128:$src)]>,
3478                      XS, Requires<[HasSSE2]>;
3479
3480 } // ExeDomain = SSEPackedInt
3481
3482 let Predicates = [HasAVX] in {
3483   def : Pat<(int_x86_avx_loadu_dq_256 addr:$src), (VMOVDQUYrm addr:$src)>;
3484   def : Pat<(int_x86_avx_storeu_dq_256 addr:$dst, VR256:$src),
3485             (VMOVDQUYmr addr:$dst, VR256:$src)>;
3486 }
3487
3488 //===---------------------------------------------------------------------===//
3489 // SSE2 - Packed Integer Arithmetic Instructions
3490 //===---------------------------------------------------------------------===//
3491
3492 let ExeDomain = SSEPackedInt in { // SSE integer instructions
3493
3494 multiclass PDI_binop_rm_int<bits<8> opc, string OpcodeStr, Intrinsic IntId,
3495                             RegisterClass RC, PatFrag memop_frag,
3496                             X86MemOperand x86memop, bit IsCommutable = 0,
3497                             bit Is2Addr = 1> {
3498   let isCommutable = IsCommutable in
3499   def rr : PDI<opc, MRMSrcReg, (outs RC:$dst),
3500        (ins RC:$src1, RC:$src2),
3501        !if(Is2Addr,
3502            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
3503            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
3504        [(set RC:$dst, (IntId RC:$src1, RC:$src2))]>;
3505   def rm : PDI<opc, MRMSrcMem, (outs RC:$dst),
3506        (ins RC:$src1, x86memop:$src2),
3507        !if(Is2Addr,
3508            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
3509            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
3510        [(set RC:$dst, (IntId RC:$src1, (bitconvert (memop_frag addr:$src2))))]>;
3511 }
3512
3513 multiclass PDI_binop_rmi_int<bits<8> opc, bits<8> opc2, Format ImmForm,
3514                              string OpcodeStr, Intrinsic IntId,
3515                              Intrinsic IntId2, RegisterClass RC,
3516                              bit Is2Addr = 1> {
3517   // src2 is always 128-bit
3518   def rr : PDI<opc, MRMSrcReg, (outs RC:$dst),
3519        (ins RC:$src1, VR128:$src2),
3520        !if(Is2Addr,
3521            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
3522            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
3523        [(set RC:$dst, (IntId RC:$src1, VR128:$src2))]>;
3524   def rm : PDI<opc, MRMSrcMem, (outs RC:$dst),
3525        (ins RC:$src1, i128mem:$src2),
3526        !if(Is2Addr,
3527            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
3528            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
3529        [(set RC:$dst, (IntId RC:$src1, (bitconvert (memopv2i64 addr:$src2))))]>;
3530   def ri : PDIi8<opc2, ImmForm, (outs RC:$dst),
3531        (ins RC:$src1, i32i8imm:$src2),
3532        !if(Is2Addr,
3533            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
3534            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
3535        [(set RC:$dst, (IntId2 RC:$src1, (i32 imm:$src2)))]>;
3536 }
3537
3538 } // ExeDomain = SSEPackedInt
3539
3540 // 128-bit Integer Arithmetic
3541
3542 let Predicates = [HasAVX] in {
3543 defm VPADDB  : PDI_binop_rm<0xFC, "vpaddb", add, v16i8, VR128, memopv2i64,
3544                             i128mem, 1, 0 /*3addr*/>, VEX_4V;
3545 defm VPADDW  : PDI_binop_rm<0xFD, "vpaddw", add, v8i16, VR128, memopv2i64,
3546                             i128mem, 1, 0>, VEX_4V;
3547 defm VPADDD  : PDI_binop_rm<0xFE, "vpaddd", add, v4i32, VR128, memopv2i64,
3548                             i128mem, 1, 0>, VEX_4V;
3549 defm VPADDQ  : PDI_binop_rm<0xD4, "vpaddq", add, v2i64, VR128, memopv2i64,
3550                             i128mem, 1, 0>, VEX_4V;
3551 defm VPMULLW : PDI_binop_rm<0xD5, "vpmullw", mul, v8i16, VR128, memopv2i64,
3552                             i128mem, 1, 0>, VEX_4V;
3553 defm VPSUBB : PDI_binop_rm<0xF8, "vpsubb", sub, v16i8, VR128, memopv2i64,
3554                             i128mem, 0, 0>, VEX_4V;
3555 defm VPSUBW : PDI_binop_rm<0xF9, "vpsubw", sub, v8i16, VR128, memopv2i64,
3556                             i128mem, 0, 0>, VEX_4V;
3557 defm VPSUBD : PDI_binop_rm<0xFA, "vpsubd", sub, v4i32, VR128, memopv2i64,
3558                             i128mem, 0, 0>, VEX_4V;
3559 defm VPSUBQ : PDI_binop_rm<0xFB, "vpsubq", sub, v2i64, VR128, memopv2i64,
3560                             i128mem, 0, 0>, VEX_4V;
3561
3562 // Intrinsic forms
3563 defm VPSUBSB  : PDI_binop_rm_int<0xE8, "vpsubsb" , int_x86_sse2_psubs_b,
3564                                  VR128, memopv2i64, i128mem, 0, 0>, VEX_4V;
3565 defm VPSUBSW  : PDI_binop_rm_int<0xE9, "vpsubsw" , int_x86_sse2_psubs_w,
3566                                  VR128, memopv2i64, i128mem, 0, 0>, VEX_4V;
3567 defm VPSUBUSB : PDI_binop_rm_int<0xD8, "vpsubusb", int_x86_sse2_psubus_b,
3568                                  VR128, memopv2i64, i128mem, 0, 0>, VEX_4V;
3569 defm VPSUBUSW : PDI_binop_rm_int<0xD9, "vpsubusw", int_x86_sse2_psubus_w,
3570                                  VR128, memopv2i64, i128mem, 0, 0>, VEX_4V;
3571 defm VPADDSB  : PDI_binop_rm_int<0xEC, "vpaddsb" , int_x86_sse2_padds_b,
3572                                  VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3573 defm VPADDSW  : PDI_binop_rm_int<0xED, "vpaddsw" , int_x86_sse2_padds_w,
3574                                  VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3575 defm VPADDUSB : PDI_binop_rm_int<0xDC, "vpaddusb", int_x86_sse2_paddus_b,
3576                                  VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3577 defm VPADDUSW : PDI_binop_rm_int<0xDD, "vpaddusw", int_x86_sse2_paddus_w,
3578                                  VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3579 defm VPMULHUW : PDI_binop_rm_int<0xE4, "vpmulhuw", int_x86_sse2_pmulhu_w,
3580                                  VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3581 defm VPMULHW  : PDI_binop_rm_int<0xE5, "vpmulhw" , int_x86_sse2_pmulh_w,
3582                                  VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3583 defm VPMULUDQ : PDI_binop_rm_int<0xF4, "vpmuludq", int_x86_sse2_pmulu_dq,
3584                                  VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3585 defm VPMADDWD : PDI_binop_rm_int<0xF5, "vpmaddwd", int_x86_sse2_pmadd_wd,
3586                                  VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3587 defm VPAVGB   : PDI_binop_rm_int<0xE0, "vpavgb", int_x86_sse2_pavg_b,
3588                                  VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3589 defm VPAVGW   : PDI_binop_rm_int<0xE3, "vpavgw", int_x86_sse2_pavg_w,
3590                                  VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3591 defm VPMINUB  : PDI_binop_rm_int<0xDA, "vpminub", int_x86_sse2_pminu_b,
3592                                  VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3593 defm VPMINSW  : PDI_binop_rm_int<0xEA, "vpminsw", int_x86_sse2_pmins_w,
3594                                  VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3595 defm VPMAXUB  : PDI_binop_rm_int<0xDE, "vpmaxub", int_x86_sse2_pmaxu_b,
3596                                  VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3597 defm VPMAXSW  : PDI_binop_rm_int<0xEE, "vpmaxsw", int_x86_sse2_pmaxs_w,
3598                                  VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3599 defm VPSADBW  : PDI_binop_rm_int<0xF6, "vpsadbw", int_x86_sse2_psad_bw,
3600                                  VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3601 }
3602
3603 let Predicates = [HasAVX2] in {
3604 defm VPADDBY  : PDI_binop_rm<0xFC, "vpaddb", add, v32i8, VR256, memopv4i64,
3605                              i256mem, 1, 0>, VEX_4V;
3606 defm VPADDWY  : PDI_binop_rm<0xFD, "vpaddw", add, v16i16, VR256, memopv4i64,
3607                              i256mem, 1, 0>, VEX_4V;
3608 defm VPADDDY  : PDI_binop_rm<0xFE, "vpaddd", add, v8i32, VR256, memopv4i64,
3609                              i256mem, 1, 0>, VEX_4V;
3610 defm VPADDQY  : PDI_binop_rm<0xD4, "vpaddq", add, v4i64, VR256, memopv4i64,
3611                              i256mem, 1, 0>, VEX_4V;
3612 defm VPMULLWY : PDI_binop_rm<0xD5, "vpmullw", mul, v16i16, VR256, memopv4i64,
3613                              i256mem, 1, 0>, VEX_4V;
3614 defm VPSUBBY  : PDI_binop_rm<0xF8, "vpsubb", sub, v32i8, VR256, memopv4i64,
3615                              i256mem, 0, 0>, VEX_4V;
3616 defm VPSUBWY  : PDI_binop_rm<0xF9, "vpsubw", sub, v16i16,VR256, memopv4i64,
3617                              i256mem, 0, 0>, VEX_4V;
3618 defm VPSUBDY  : PDI_binop_rm<0xFA, "vpsubd", sub, v8i32, VR256, memopv4i64,
3619                              i256mem, 0, 0>, VEX_4V;
3620 defm VPSUBQY  : PDI_binop_rm<0xFB, "vpsubq", sub, v4i64, VR256, memopv4i64,
3621                              i256mem, 0, 0>, VEX_4V;
3622
3623 // Intrinsic forms
3624 defm VPSUBSBY  : PDI_binop_rm_int<0xE8, "vpsubsb" , int_x86_avx2_psubs_b,
3625                                   VR256, memopv4i64, i256mem, 0, 0>, VEX_4V;
3626 defm VPSUBSWY  : PDI_binop_rm_int<0xE9, "vpsubsw" , int_x86_avx2_psubs_w,
3627                                   VR256, memopv4i64, i256mem, 0, 0>, VEX_4V;
3628 defm VPSUBUSBY : PDI_binop_rm_int<0xD8, "vpsubusb", int_x86_avx2_psubus_b,
3629                                   VR256, memopv4i64, i256mem, 0, 0>, VEX_4V;
3630 defm VPSUBUSWY : PDI_binop_rm_int<0xD9, "vpsubusw", int_x86_avx2_psubus_w,
3631                                   VR256, memopv4i64, i256mem, 0, 0>, VEX_4V;
3632 defm VPADDSBY  : PDI_binop_rm_int<0xEC, "vpaddsb" , int_x86_avx2_padds_b,
3633                                   VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3634 defm VPADDSWY  : PDI_binop_rm_int<0xED, "vpaddsw" , int_x86_avx2_padds_w,
3635                                   VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3636 defm VPADDUSBY : PDI_binop_rm_int<0xDC, "vpaddusb", int_x86_avx2_paddus_b,
3637                                   VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3638 defm VPADDUSWY : PDI_binop_rm_int<0xDD, "vpaddusw", int_x86_avx2_paddus_w,
3639                                   VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3640 defm VPMULHUWY : PDI_binop_rm_int<0xE4, "vpmulhuw", int_x86_avx2_pmulhu_w,
3641                                   VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3642 defm VPMULHWY  : PDI_binop_rm_int<0xE5, "vpmulhw" , int_x86_avx2_pmulh_w,
3643                                   VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3644 defm VPMULUDQY : PDI_binop_rm_int<0xF4, "vpmuludq", int_x86_avx2_pmulu_dq,
3645                                   VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3646 defm VPMADDWDY : PDI_binop_rm_int<0xF5, "vpmaddwd", int_x86_avx2_pmadd_wd,
3647                                   VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3648 defm VPAVGBY   : PDI_binop_rm_int<0xE0, "vpavgb", int_x86_avx2_pavg_b,
3649                                   VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3650 defm VPAVGWY   : PDI_binop_rm_int<0xE3, "vpavgw", int_x86_avx2_pavg_w,
3651                                   VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3652 defm VPMINUBY  : PDI_binop_rm_int<0xDA, "vpminub", int_x86_avx2_pminu_b,
3653                                   VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3654 defm VPMINSWY  : PDI_binop_rm_int<0xEA, "vpminsw", int_x86_avx2_pmins_w,
3655                                   VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3656 defm VPMAXUBY  : PDI_binop_rm_int<0xDE, "vpmaxub", int_x86_avx2_pmaxu_b,
3657                                   VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3658 defm VPMAXSWY  : PDI_binop_rm_int<0xEE, "vpmaxsw", int_x86_avx2_pmaxs_w,
3659                                   VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3660 defm VPSADBWY  : PDI_binop_rm_int<0xF6, "vpsadbw", int_x86_avx2_psad_bw,
3661                                   VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3662 }
3663
3664 let Constraints = "$src1 = $dst" in {
3665 defm PADDB  : PDI_binop_rm<0xFC, "paddb", add, v16i8, VR128, memopv2i64,
3666                            i128mem, 1>;
3667 defm PADDW  : PDI_binop_rm<0xFD, "paddw", add, v8i16, VR128, memopv2i64,
3668                            i128mem, 1>;
3669 defm PADDD  : PDI_binop_rm<0xFE, "paddd", add, v4i32, VR128, memopv2i64,
3670                            i128mem, 1>;
3671 defm PADDQ  : PDI_binop_rm<0xD4, "paddq", add, v2i64, VR128, memopv2i64,
3672                            i128mem, 1>;
3673 defm PMULLW : PDI_binop_rm<0xD5, "pmullw", mul, v8i16, VR128, memopv2i64,
3674                            i128mem, 1>;
3675 defm PSUBB : PDI_binop_rm<0xF8, "psubb", sub, v16i8, VR128, memopv2i64,
3676                           i128mem>;
3677 defm PSUBW : PDI_binop_rm<0xF9, "psubw", sub, v8i16, VR128, memopv2i64,
3678                           i128mem>;
3679 defm PSUBD : PDI_binop_rm<0xFA, "psubd", sub, v4i32, VR128, memopv2i64,
3680                           i128mem>;
3681 defm PSUBQ : PDI_binop_rm<0xFB, "psubq", sub, v2i64, VR128, memopv2i64,
3682                           i128mem>;
3683
3684 // Intrinsic forms
3685 defm PSUBSB  : PDI_binop_rm_int<0xE8, "psubsb" , int_x86_sse2_psubs_b,
3686                                 VR128, memopv2i64, i128mem>;
3687 defm PSUBSW  : PDI_binop_rm_int<0xE9, "psubsw" , int_x86_sse2_psubs_w,
3688                                 VR128, memopv2i64, i128mem>;
3689 defm PSUBUSB : PDI_binop_rm_int<0xD8, "psubusb", int_x86_sse2_psubus_b,
3690                                 VR128, memopv2i64, i128mem>;
3691 defm PSUBUSW : PDI_binop_rm_int<0xD9, "psubusw", int_x86_sse2_psubus_w,
3692                                 VR128, memopv2i64, i128mem>;
3693 defm PADDSB  : PDI_binop_rm_int<0xEC, "paddsb" , int_x86_sse2_padds_b,
3694                                 VR128, memopv2i64, i128mem, 1>;
3695 defm PADDSW  : PDI_binop_rm_int<0xED, "paddsw" , int_x86_sse2_padds_w,
3696                                 VR128, memopv2i64, i128mem, 1>;
3697 defm PADDUSB : PDI_binop_rm_int<0xDC, "paddusb", int_x86_sse2_paddus_b,
3698                                 VR128, memopv2i64, i128mem, 1>;
3699 defm PADDUSW : PDI_binop_rm_int<0xDD, "paddusw", int_x86_sse2_paddus_w,
3700                                 VR128, memopv2i64, i128mem, 1>;
3701 defm PMULHUW : PDI_binop_rm_int<0xE4, "pmulhuw", int_x86_sse2_pmulhu_w,
3702                                 VR128, memopv2i64, i128mem, 1>;
3703 defm PMULHW  : PDI_binop_rm_int<0xE5, "pmulhw" , int_x86_sse2_pmulh_w,
3704                                 VR128, memopv2i64, i128mem, 1>;
3705 defm PMULUDQ : PDI_binop_rm_int<0xF4, "pmuludq", int_x86_sse2_pmulu_dq,
3706                                 VR128, memopv2i64, i128mem, 1>;
3707 defm PMADDWD : PDI_binop_rm_int<0xF5, "pmaddwd", int_x86_sse2_pmadd_wd,
3708                                 VR128, memopv2i64, i128mem, 1>;
3709 defm PAVGB   : PDI_binop_rm_int<0xE0, "pavgb", int_x86_sse2_pavg_b,
3710                                 VR128, memopv2i64, i128mem, 1>;
3711 defm PAVGW   : PDI_binop_rm_int<0xE3, "pavgw", int_x86_sse2_pavg_w,
3712                                 VR128, memopv2i64, i128mem, 1>;
3713 defm PMINUB  : PDI_binop_rm_int<0xDA, "pminub", int_x86_sse2_pminu_b,
3714                                 VR128, memopv2i64, i128mem, 1>;
3715 defm PMINSW  : PDI_binop_rm_int<0xEA, "pminsw", int_x86_sse2_pmins_w,
3716                                 VR128, memopv2i64, i128mem, 1>;
3717 defm PMAXUB  : PDI_binop_rm_int<0xDE, "pmaxub", int_x86_sse2_pmaxu_b,
3718                                 VR128, memopv2i64, i128mem, 1>;
3719 defm PMAXSW  : PDI_binop_rm_int<0xEE, "pmaxsw", int_x86_sse2_pmaxs_w,
3720                                 VR128, memopv2i64, i128mem, 1>;
3721 defm PSADBW  : PDI_binop_rm_int<0xF6, "psadbw", int_x86_sse2_psad_bw,
3722                                 VR128, memopv2i64, i128mem, 1>;
3723
3724 } // Constraints = "$src1 = $dst"
3725
3726 //===---------------------------------------------------------------------===//
3727 // SSE2 - Packed Integer Logical Instructions
3728 //===---------------------------------------------------------------------===//
3729
3730 let Predicates = [HasAVX] in {
3731 defm VPSLLW : PDI_binop_rmi_int<0xF1, 0x71, MRM6r, "vpsllw",
3732                                 int_x86_sse2_psll_w, int_x86_sse2_pslli_w,
3733                                 VR128, 0>, VEX_4V;
3734 defm VPSLLD : PDI_binop_rmi_int<0xF2, 0x72, MRM6r, "vpslld",
3735                                 int_x86_sse2_psll_d, int_x86_sse2_pslli_d,
3736                                 VR128, 0>, VEX_4V;
3737 defm VPSLLQ : PDI_binop_rmi_int<0xF3, 0x73, MRM6r, "vpsllq",
3738                                 int_x86_sse2_psll_q, int_x86_sse2_pslli_q,
3739                                 VR128, 0>, VEX_4V;
3740
3741 defm VPSRLW : PDI_binop_rmi_int<0xD1, 0x71, MRM2r, "vpsrlw",
3742                                 int_x86_sse2_psrl_w, int_x86_sse2_psrli_w,
3743                                 VR128, 0>, VEX_4V;
3744 defm VPSRLD : PDI_binop_rmi_int<0xD2, 0x72, MRM2r, "vpsrld",
3745                                 int_x86_sse2_psrl_d, int_x86_sse2_psrli_d,
3746                                 VR128, 0>, VEX_4V;
3747 defm VPSRLQ : PDI_binop_rmi_int<0xD3, 0x73, MRM2r, "vpsrlq",
3748                                 int_x86_sse2_psrl_q, int_x86_sse2_psrli_q,
3749                                 VR128, 0>, VEX_4V;
3750
3751 defm VPSRAW : PDI_binop_rmi_int<0xE1, 0x71, MRM4r, "vpsraw",
3752                                 int_x86_sse2_psra_w, int_x86_sse2_psrai_w,
3753                                 VR128, 0>, VEX_4V;
3754 defm VPSRAD : PDI_binop_rmi_int<0xE2, 0x72, MRM4r, "vpsrad",
3755                                 int_x86_sse2_psra_d, int_x86_sse2_psrai_d,
3756                                 VR128, 0>, VEX_4V;
3757
3758 let ExeDomain = SSEPackedInt in {
3759   // 128-bit logical shifts.
3760   def VPSLLDQri : PDIi8<0x73, MRM7r,
3761                     (outs VR128:$dst), (ins VR128:$src1, i32i8imm:$src2),
3762                     "vpslldq\t{$src2, $src1, $dst|$dst, $src1, $src2}",
3763                     [(set VR128:$dst,
3764                       (int_x86_sse2_psll_dq_bs VR128:$src1, imm:$src2))]>,
3765                     VEX_4V;
3766   def VPSRLDQri : PDIi8<0x73, MRM3r,
3767                     (outs VR128:$dst), (ins VR128:$src1, i32i8imm:$src2),
3768                     "vpsrldq\t{$src2, $src1, $dst|$dst, $src1, $src2}",
3769                     [(set VR128:$dst,
3770                       (int_x86_sse2_psrl_dq_bs VR128:$src1, imm:$src2))]>,
3771                     VEX_4V;
3772   // PSRADQri doesn't exist in SSE[1-3].
3773 }
3774 } // Predicates = [HasAVX]
3775
3776 let Predicates = [HasAVX2] in {
3777 defm VPSLLWY : PDI_binop_rmi_int<0xF1, 0x71, MRM6r, "vpsllw",
3778                                  int_x86_avx2_psll_w, int_x86_avx2_pslli_w,
3779                                  VR256, 0>, VEX_4V;
3780 defm VPSLLDY : PDI_binop_rmi_int<0xF2, 0x72, MRM6r, "vpslld",
3781                                  int_x86_avx2_psll_d, int_x86_avx2_pslli_d,
3782                                  VR256, 0>, VEX_4V;
3783 defm VPSLLQY : PDI_binop_rmi_int<0xF3, 0x73, MRM6r, "vpsllq",
3784                                  int_x86_avx2_psll_q, int_x86_avx2_pslli_q,
3785                                  VR256, 0>, VEX_4V;
3786
3787 defm VPSRLWY : PDI_binop_rmi_int<0xD1, 0x71, MRM2r, "vpsrlw",
3788                                  int_x86_avx2_psrl_w, int_x86_avx2_psrli_w,
3789                                  VR256, 0>, VEX_4V;
3790 defm VPSRLDY : PDI_binop_rmi_int<0xD2, 0x72, MRM2r, "vpsrld",
3791                                  int_x86_avx2_psrl_d, int_x86_avx2_psrli_d,
3792                                  VR256, 0>, VEX_4V;
3793 defm VPSRLQY : PDI_binop_rmi_int<0xD3, 0x73, MRM2r, "vpsrlq",
3794                                  int_x86_avx2_psrl_q, int_x86_avx2_psrli_q,
3795                                  VR256, 0>, VEX_4V;
3796
3797 defm VPSRAWY : PDI_binop_rmi_int<0xE1, 0x71, MRM4r, "vpsraw",
3798                                  int_x86_avx2_psra_w, int_x86_avx2_psrai_w,
3799                                  VR256, 0>, VEX_4V;
3800 defm VPSRADY : PDI_binop_rmi_int<0xE2, 0x72, MRM4r, "vpsrad",
3801                                  int_x86_avx2_psra_d, int_x86_avx2_psrai_d,
3802                                  VR256, 0>, VEX_4V;
3803
3804 let ExeDomain = SSEPackedInt in {
3805   // 256-bit logical shifts.
3806   def VPSLLDQYri : PDIi8<0x73, MRM7r,
3807                     (outs VR256:$dst), (ins VR256:$src1, i32i8imm:$src2),
3808                     "vpslldq\t{$src2, $src1, $dst|$dst, $src1, $src2}",
3809                     [(set VR256:$dst,
3810                       (int_x86_avx2_psll_dq_bs VR256:$src1, imm:$src2))]>,
3811                     VEX_4V;
3812   def VPSRLDQYri : PDIi8<0x73, MRM3r,
3813                     (outs VR256:$dst), (ins VR256:$src1, i32i8imm:$src2),
3814                     "vpsrldq\t{$src2, $src1, $dst|$dst, $src1, $src2}",
3815                     [(set VR256:$dst,
3816                       (int_x86_avx2_psrl_dq_bs VR256:$src1, imm:$src2))]>,
3817                     VEX_4V;
3818   // PSRADQYri doesn't exist in SSE[1-3].
3819 }
3820 } // Predicates = [HasAVX2]
3821
3822 let Constraints = "$src1 = $dst" in {
3823 defm PSLLW : PDI_binop_rmi_int<0xF1, 0x71, MRM6r, "psllw",
3824                                int_x86_sse2_psll_w, int_x86_sse2_pslli_w,
3825                                VR128>;
3826 defm PSLLD : PDI_binop_rmi_int<0xF2, 0x72, MRM6r, "pslld",
3827                                int_x86_sse2_psll_d, int_x86_sse2_pslli_d,
3828                                VR128>;
3829 defm PSLLQ : PDI_binop_rmi_int<0xF3, 0x73, MRM6r, "psllq",
3830                                int_x86_sse2_psll_q, int_x86_sse2_pslli_q,
3831                                VR128>;
3832
3833 defm PSRLW : PDI_binop_rmi_int<0xD1, 0x71, MRM2r, "psrlw",
3834                                int_x86_sse2_psrl_w, int_x86_sse2_psrli_w,
3835                                VR128>;
3836 defm PSRLD : PDI_binop_rmi_int<0xD2, 0x72, MRM2r, "psrld",
3837                                int_x86_sse2_psrl_d, int_x86_sse2_psrli_d,
3838                                VR128>;
3839 defm PSRLQ : PDI_binop_rmi_int<0xD3, 0x73, MRM2r, "psrlq",
3840                                int_x86_sse2_psrl_q, int_x86_sse2_psrli_q,
3841                                VR128>;
3842
3843 defm PSRAW : PDI_binop_rmi_int<0xE1, 0x71, MRM4r, "psraw",
3844                                int_x86_sse2_psra_w, int_x86_sse2_psrai_w,
3845                                VR128>;
3846 defm PSRAD : PDI_binop_rmi_int<0xE2, 0x72, MRM4r, "psrad",
3847                                int_x86_sse2_psra_d, int_x86_sse2_psrai_d,
3848                                VR128>;
3849
3850 let ExeDomain = SSEPackedInt in {
3851   // 128-bit logical shifts.
3852   def PSLLDQri : PDIi8<0x73, MRM7r,
3853                        (outs VR128:$dst), (ins VR128:$src1, i32i8imm:$src2),
3854                        "pslldq\t{$src2, $dst|$dst, $src2}",
3855                        [(set VR128:$dst,
3856                          (int_x86_sse2_psll_dq_bs VR128:$src1, imm:$src2))]>;
3857   def PSRLDQri : PDIi8<0x73, MRM3r,
3858                        (outs VR128:$dst), (ins VR128:$src1, i32i8imm:$src2),
3859                        "psrldq\t{$src2, $dst|$dst, $src2}",
3860                        [(set VR128:$dst,
3861                          (int_x86_sse2_psrl_dq_bs VR128:$src1, imm:$src2))]>;
3862   // PSRADQri doesn't exist in SSE[1-3].
3863 }
3864 } // Constraints = "$src1 = $dst"
3865
3866 let Predicates = [HasAVX] in {
3867   def : Pat<(int_x86_sse2_psll_dq VR128:$src1, imm:$src2),
3868             (VPSLLDQri VR128:$src1, (BYTE_imm imm:$src2))>;
3869   def : Pat<(int_x86_sse2_psrl_dq VR128:$src1, imm:$src2),
3870             (VPSRLDQri VR128:$src1, (BYTE_imm imm:$src2))>;
3871   def : Pat<(v2f64 (X86fsrl VR128:$src1, i32immSExt8:$src2)),
3872             (VPSRLDQri VR128:$src1, (BYTE_imm imm:$src2))>;
3873
3874   // Shift up / down and insert zero's.
3875   def : Pat<(v2i64 (X86vshldq VR128:$src, (i8 imm:$amt))),
3876             (VPSLLDQri VR128:$src, (BYTE_imm imm:$amt))>;
3877   def : Pat<(v2i64 (X86vshrdq VR128:$src, (i8 imm:$amt))),
3878             (VPSRLDQri VR128:$src, (BYTE_imm imm:$amt))>;
3879
3880   def : Pat<(v8i16 (X86vshli VR128:$src1, (i32 imm:$src2))),
3881             (VPSLLWri VR128:$src1, imm:$src2)>;
3882   def : Pat<(v4i32 (X86vshli VR128:$src1, (i32 imm:$src2))),
3883             (VPSLLDri VR128:$src1, imm:$src2)>;
3884   def : Pat<(v2i64 (X86vshli VR128:$src1, (i32 imm:$src2))),
3885             (VPSLLQri VR128:$src1, imm:$src2)>;
3886
3887   def : Pat<(v8i16 (X86vsrli VR128:$src1, (i32 imm:$src2))),
3888             (VPSRLWri VR128:$src1, imm:$src2)>;
3889   def : Pat<(v4i32 (X86vsrli VR128:$src1, (i32 imm:$src2))),
3890             (VPSRLDri VR128:$src1, imm:$src2)>;
3891   def : Pat<(v2i64 (X86vsrli VR128:$src1, (i32 imm:$src2))),
3892             (VPSRLQri VR128:$src1, imm:$src2)>;
3893
3894   def : Pat<(v8i16 (X86vsrai VR128:$src1, (i32 imm:$src2))),
3895             (VPSRAWri VR128:$src1, imm:$src2)>;
3896   def : Pat<(v4i32 (X86vsrai VR128:$src1, (i32 imm:$src2))),
3897             (VPSRADri VR128:$src1, imm:$src2)>;
3898
3899   def : Pat<(v8i16 (X86vshl VR128:$src1, (v8i16 VR128:$src2))),
3900             (VPSLLWrr VR128:$src1, VR128:$src2)>;
3901   def : Pat<(v8i16 (X86vshl VR128:$src1, (bc_v8i16 (memopv2i64 addr:$src2)))),
3902             (VPSLLWrm VR128:$src1, addr:$src2)>;
3903   def : Pat<(v4i32 (X86vshl VR128:$src1, (v4i32 VR128:$src2))),
3904             (VPSLLDrr VR128:$src1, VR128:$src2)>;
3905   def : Pat<(v4i32 (X86vshl VR128:$src1, (bc_v4i32 (memopv2i64 addr:$src2)))),
3906             (VPSLLDrm VR128:$src1, addr:$src2)>;
3907   def : Pat<(v2i64 (X86vshl VR128:$src1, (v2i64 VR128:$src2))),
3908             (VPSLLQrr VR128:$src1, VR128:$src2)>;
3909   def : Pat<(v2i64 (X86vshl VR128:$src1, (memopv2i64 addr:$src2))),
3910             (VPSLLQrm VR128:$src1, addr:$src2)>;
3911
3912   def : Pat<(v8i16 (X86vsrl VR128:$src1, (v8i16 VR128:$src2))),
3913             (VPSRLWrr VR128:$src1, VR128:$src2)>;
3914   def : Pat<(v8i16 (X86vsrl VR128:$src1, (bc_v8i16 (memopv2i64 addr:$src2)))),
3915             (VPSRLWrm VR128:$src1, addr:$src2)>;
3916   def : Pat<(v4i32 (X86vsrl VR128:$src1, (v4i32 VR128:$src2))),
3917             (VPSRLDrr VR128:$src1, VR128:$src2)>;
3918   def : Pat<(v4i32 (X86vsrl VR128:$src1, (bc_v4i32 (memopv2i64 addr:$src2)))),
3919             (VPSRLDrm VR128:$src1, addr:$src2)>;
3920   def : Pat<(v2i64 (X86vsrl VR128:$src1, (v2i64 VR128:$src2))),
3921             (VPSRLQrr VR128:$src1, VR128:$src2)>;
3922   def : Pat<(v2i64 (X86vsrl VR128:$src1, (memopv2i64 addr:$src2))),
3923             (VPSRLQrm VR128:$src1, addr:$src2)>;
3924
3925   def : Pat<(v8i16 (X86vsra VR128:$src1, (v8i16 VR128:$src2))),
3926             (VPSRAWrr VR128:$src1, VR128:$src2)>;
3927   def : Pat<(v8i16 (X86vsra VR128:$src1, (bc_v8i16 (memopv2i64 addr:$src2)))),
3928             (VPSRAWrm VR128:$src1, addr:$src2)>;
3929   def : Pat<(v4i32 (X86vsra VR128:$src1, (v4i32 VR128:$src2))),
3930             (VPSRADrr VR128:$src1, VR128:$src2)>;
3931   def : Pat<(v4i32 (X86vsra VR128:$src1, (bc_v4i32 (memopv2i64 addr:$src2)))),
3932             (VPSRADrm VR128:$src1, addr:$src2)>;
3933 }
3934
3935 let Predicates = [HasAVX2] in {
3936   def : Pat<(int_x86_avx2_psll_dq VR256:$src1, imm:$src2),
3937             (VPSLLDQYri VR256:$src1, (BYTE_imm imm:$src2))>;
3938   def : Pat<(int_x86_avx2_psrl_dq VR256:$src1, imm:$src2),
3939             (VPSRLDQYri VR256:$src1, (BYTE_imm imm:$src2))>;
3940
3941   def : Pat<(v16i16 (X86vshli VR256:$src1, (i32 imm:$src2))),
3942             (VPSLLWYri VR256:$src1, imm:$src2)>;
3943   def : Pat<(v8i32 (X86vshli VR256:$src1, (i32 imm:$src2))),
3944             (VPSLLDYri VR256:$src1, imm:$src2)>;
3945   def : Pat<(v4i64 (X86vshli VR256:$src1, (i32 imm:$src2))),
3946             (VPSLLQYri VR256:$src1, imm:$src2)>;
3947
3948   def : Pat<(v16i16 (X86vsrli VR256:$src1, (i32 imm:$src2))),
3949             (VPSRLWYri VR256:$src1, imm:$src2)>;
3950   def : Pat<(v8i32 (X86vsrli VR256:$src1, (i32 imm:$src2))),
3951             (VPSRLDYri VR256:$src1, imm:$src2)>;
3952   def : Pat<(v4i64 (X86vsrli VR256:$src1, (i32 imm:$src2))),
3953             (VPSRLQYri VR256:$src1, imm:$src2)>;
3954
3955   def : Pat<(v16i16 (X86vsrai VR256:$src1, (i32 imm:$src2))),
3956             (VPSRAWYri VR256:$src1, imm:$src2)>;
3957   def : Pat<(v8i32 (X86vsrai VR256:$src1, (i32 imm:$src2))),
3958             (VPSRADYri VR256:$src1, imm:$src2)>;
3959
3960   def : Pat<(v16i16 (X86vshl VR256:$src1, (v8i16 VR128:$src2))),
3961             (VPSLLWYrr VR256:$src1, VR128:$src2)>;
3962   def : Pat<(v16i16 (X86vshl VR256:$src1, (bc_v8i16 (memopv2i64 addr:$src2)))),
3963             (VPSLLWYrm VR256:$src1, addr:$src2)>;
3964   def : Pat<(v8i32 (X86vshl VR256:$src1, (v4i32 VR128:$src2))),
3965             (VPSLLDYrr VR256:$src1, VR128:$src2)>;
3966   def : Pat<(v8i32 (X86vshl VR256:$src1, (bc_v4i32 (memopv2i64 addr:$src2)))),
3967             (VPSLLDYrm VR256:$src1, addr:$src2)>;
3968   def : Pat<(v4i64 (X86vshl VR256:$src1, (v2i64 VR128:$src2))),
3969             (VPSLLQYrr VR256:$src1, VR128:$src2)>;
3970   def : Pat<(v4i64 (X86vshl VR256:$src1, (memopv2i64 addr:$src2))),
3971             (VPSLLQYrm VR256:$src1, addr:$src2)>;
3972
3973   def : Pat<(v16i16 (X86vsrl VR256:$src1, (v8i16 VR128:$src2))),
3974             (VPSRLWYrr VR256:$src1, VR128:$src2)>;
3975   def : Pat<(v16i16 (X86vsrl VR256:$src1, (bc_v8i16 (memopv2i64 addr:$src2)))),
3976             (VPSRLWYrm VR256:$src1, addr:$src2)>;
3977   def : Pat<(v8i32 (X86vsrl VR256:$src1, (v4i32 VR128:$src2))),
3978             (VPSRLDYrr VR256:$src1, VR128:$src2)>;
3979   def : Pat<(v8i32 (X86vsrl VR256:$src1, (bc_v4i32 (memopv2i64 addr:$src2)))),
3980             (VPSRLDYrm VR256:$src1, addr:$src2)>;
3981   def : Pat<(v4i64 (X86vsrl VR256:$src1, (v2i64 VR128:$src2))),
3982             (VPSRLQYrr VR256:$src1, VR128:$src2)>;
3983   def : Pat<(v4i64 (X86vsrl VR256:$src1, (memopv2i64 addr:$src2))),
3984             (VPSRLQYrm VR256:$src1, addr:$src2)>;
3985
3986   def : Pat<(v16i16 (X86vsra VR256:$src1, (v8i16 VR128:$src2))),
3987             (VPSRAWYrr VR256:$src1, VR128:$src2)>;
3988   def : Pat<(v16i16 (X86vsra VR256:$src1, (bc_v8i16 (memopv2i64 addr:$src2)))),
3989             (VPSRAWYrm VR256:$src1, addr:$src2)>;
3990   def : Pat<(v8i32 (X86vsra VR256:$src1, (v4i32 VR128:$src2))),
3991             (VPSRADYrr VR256:$src1, VR128:$src2)>;
3992   def : Pat<(v8i32 (X86vsra VR256:$src1, (bc_v4i32 (memopv2i64 addr:$src2)))),
3993             (VPSRADYrm VR256:$src1, addr:$src2)>;
3994 }
3995
3996 let Predicates = [HasSSE2] in {
3997   def : Pat<(int_x86_sse2_psll_dq VR128:$src1, imm:$src2),
3998             (PSLLDQri VR128:$src1, (BYTE_imm imm:$src2))>;
3999   def : Pat<(int_x86_sse2_psrl_dq VR128:$src1, imm:$src2),
4000             (PSRLDQri VR128:$src1, (BYTE_imm imm:$src2))>;
4001   def : Pat<(v2f64 (X86fsrl VR128:$src1, i32immSExt8:$src2)),
4002             (PSRLDQri VR128:$src1, (BYTE_imm imm:$src2))>;
4003
4004   // Shift up / down and insert zero's.
4005   def : Pat<(v2i64 (X86vshldq VR128:$src, (i8 imm:$amt))),
4006             (PSLLDQri VR128:$src, (BYTE_imm imm:$amt))>;
4007   def : Pat<(v2i64 (X86vshrdq VR128:$src, (i8 imm:$amt))),
4008             (PSRLDQri VR128:$src, (BYTE_imm imm:$amt))>;
4009
4010   def : Pat<(v8i16 (X86vshli VR128:$src1, (i32 imm:$src2))),
4011             (PSLLWri VR128:$src1, imm:$src2)>;
4012   def : Pat<(v4i32 (X86vshli VR128:$src1, (i32 imm:$src2))),
4013             (PSLLDri VR128:$src1, imm:$src2)>;
4014   def : Pat<(v2i64 (X86vshli VR128:$src1, (i32 imm:$src2))),
4015             (PSLLQri VR128:$src1, imm:$src2)>;
4016
4017   def : Pat<(v8i16 (X86vsrli VR128:$src1, (i32 imm:$src2))),
4018             (PSRLWri VR128:$src1, imm:$src2)>;
4019   def : Pat<(v4i32 (X86vsrli VR128:$src1, (i32 imm:$src2))),
4020             (PSRLDri VR128:$src1, imm:$src2)>;
4021   def : Pat<(v2i64 (X86vsrli VR128:$src1, (i32 imm:$src2))),
4022             (PSRLQri VR128:$src1, imm:$src2)>;
4023
4024   def : Pat<(v8i16 (X86vsrai VR128:$src1, (i32 imm:$src2))),
4025             (PSRAWri VR128:$src1, imm:$src2)>;
4026   def : Pat<(v4i32 (X86vsrai VR128:$src1, (i32 imm:$src2))),
4027             (PSRADri VR128:$src1, imm:$src2)>;
4028
4029   def : Pat<(v8i16 (X86vshl VR128:$src1, (v8i16 VR128:$src2))),
4030             (PSLLWrr VR128:$src1, VR128:$src2)>;
4031   def : Pat<(v8i16 (X86vshl VR128:$src1, (bc_v8i16 (memopv2i64 addr:$src2)))),
4032             (PSLLWrm VR128:$src1, addr:$src2)>;
4033   def : Pat<(v4i32 (X86vshl VR128:$src1, (v4i32 VR128:$src2))),
4034             (PSLLDrr VR128:$src1, VR128:$src2)>;
4035   def : Pat<(v4i32 (X86vshl VR128:$src1, (bc_v4i32 (memopv2i64 addr:$src2)))),
4036             (PSLLDrm VR128:$src1, addr:$src2)>;
4037   def : Pat<(v2i64 (X86vshl VR128:$src1, (v2i64 VR128:$src2))),
4038             (PSLLQrr VR128:$src1, VR128:$src2)>;
4039   def : Pat<(v2i64 (X86vshl VR128:$src1, (memopv2i64 addr:$src2))),
4040             (PSLLQrm VR128:$src1, addr:$src2)>;
4041
4042   def : Pat<(v8i16 (X86vsrl VR128:$src1, (v8i16 VR128:$src2))),
4043             (PSRLWrr VR128:$src1, VR128:$src2)>;
4044   def : Pat<(v8i16 (X86vsrl VR128:$src1, (bc_v8i16 (memopv2i64 addr:$src2)))),
4045             (PSRLWrm VR128:$src1, addr:$src2)>;
4046   def : Pat<(v4i32 (X86vsrl VR128:$src1, (v4i32 VR128:$src2))),
4047             (PSRLDrr VR128:$src1, VR128:$src2)>;
4048   def : Pat<(v4i32 (X86vsrl VR128:$src1, (bc_v4i32 (memopv2i64 addr:$src2)))),
4049             (PSRLDrm VR128:$src1, addr:$src2)>;
4050   def : Pat<(v2i64 (X86vsrl VR128:$src1, (v2i64 VR128:$src2))),
4051             (PSRLQrr VR128:$src1, VR128:$src2)>;
4052   def : Pat<(v2i64 (X86vsrl VR128:$src1, (memopv2i64 addr:$src2))),
4053             (PSRLQrm VR128:$src1, addr:$src2)>;
4054
4055   def : Pat<(v8i16 (X86vsra VR128:$src1, (v8i16 VR128:$src2))),
4056             (PSRAWrr VR128:$src1, VR128:$src2)>;
4057   def : Pat<(v8i16 (X86vsra VR128:$src1, (bc_v8i16 (memopv2i64 addr:$src2)))),
4058             (PSRAWrm VR128:$src1, addr:$src2)>;
4059   def : Pat<(v4i32 (X86vsra VR128:$src1, (v4i32 VR128:$src2))),
4060             (PSRADrr VR128:$src1, VR128:$src2)>;
4061   def : Pat<(v4i32 (X86vsra VR128:$src1, (bc_v4i32 (memopv2i64 addr:$src2)))),
4062             (PSRADrm VR128:$src1, addr:$src2)>;
4063 }
4064
4065 //===---------------------------------------------------------------------===//
4066 // SSE2 - Packed Integer Comparison Instructions
4067 //===---------------------------------------------------------------------===//
4068
4069 let Predicates = [HasAVX] in {
4070   defm VPCMPEQB  : PDI_binop_rm_int<0x74, "vpcmpeqb", int_x86_sse2_pcmpeq_b,
4071                                     VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
4072   defm VPCMPEQW  : PDI_binop_rm_int<0x75, "vpcmpeqw", int_x86_sse2_pcmpeq_w,
4073                                     VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
4074   defm VPCMPEQD  : PDI_binop_rm_int<0x76, "vpcmpeqd", int_x86_sse2_pcmpeq_d,
4075                                     VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
4076   defm VPCMPGTB  : PDI_binop_rm_int<0x64, "vpcmpgtb", int_x86_sse2_pcmpgt_b,
4077                                     VR128, memopv2i64, i128mem, 0, 0>, VEX_4V;
4078   defm VPCMPGTW  : PDI_binop_rm_int<0x65, "vpcmpgtw", int_x86_sse2_pcmpgt_w,
4079                                     VR128, memopv2i64, i128mem, 0, 0>, VEX_4V;
4080   defm VPCMPGTD  : PDI_binop_rm_int<0x66, "vpcmpgtd", int_x86_sse2_pcmpgt_d,
4081                                     VR128, memopv2i64, i128mem, 0, 0>, VEX_4V;
4082
4083   def : Pat<(v16i8 (X86pcmpeq VR128:$src1, VR128:$src2)),
4084             (VPCMPEQBrr VR128:$src1, VR128:$src2)>;
4085   def : Pat<(v16i8 (X86pcmpeq VR128:$src1,
4086                     (bc_v16i8 (memopv2i64 addr:$src2)))),
4087             (VPCMPEQBrm VR128:$src1, addr:$src2)>;
4088   def : Pat<(v8i16 (X86pcmpeq VR128:$src1, VR128:$src2)),
4089             (VPCMPEQWrr VR128:$src1, VR128:$src2)>;
4090   def : Pat<(v8i16 (X86pcmpeq VR128:$src1,
4091                     (bc_v8i16 (memopv2i64 addr:$src2)))),
4092             (VPCMPEQWrm VR128:$src1, addr:$src2)>;
4093   def : Pat<(v4i32 (X86pcmpeq VR128:$src1, VR128:$src2)),
4094             (VPCMPEQDrr VR128:$src1, VR128:$src2)>;
4095   def : Pat<(v4i32 (X86pcmpeq VR128:$src1,
4096                     (bc_v4i32 (memopv2i64 addr:$src2)))),
4097             (VPCMPEQDrm VR128:$src1, addr:$src2)>;
4098
4099   def : Pat<(v16i8 (X86pcmpgt VR128:$src1, VR128:$src2)),
4100             (VPCMPGTBrr VR128:$src1, VR128:$src2)>;
4101   def : Pat<(v16i8 (X86pcmpgt VR128:$src1,
4102                     (bc_v16i8 (memopv2i64 addr:$src2)))),
4103             (VPCMPGTBrm VR128:$src1, addr:$src2)>;
4104   def : Pat<(v8i16 (X86pcmpgt VR128:$src1, VR128:$src2)),
4105             (VPCMPGTWrr VR128:$src1, VR128:$src2)>;
4106   def : Pat<(v8i16 (X86pcmpgt VR128:$src1,
4107                     (bc_v8i16 (memopv2i64 addr:$src2)))),
4108             (VPCMPGTWrm VR128:$src1, addr:$src2)>;
4109   def : Pat<(v4i32 (X86pcmpgt VR128:$src1, VR128:$src2)),
4110             (VPCMPGTDrr VR128:$src1, VR128:$src2)>;
4111   def : Pat<(v4i32 (X86pcmpgt VR128:$src1,
4112                     (bc_v4i32 (memopv2i64 addr:$src2)))),
4113             (VPCMPGTDrm VR128:$src1, addr:$src2)>;
4114 }
4115
4116 let Predicates = [HasAVX2] in {
4117   defm VPCMPEQBY : PDI_binop_rm_int<0x74, "vpcmpeqb", int_x86_avx2_pcmpeq_b,
4118                                     VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
4119   defm VPCMPEQWY : PDI_binop_rm_int<0x75, "vpcmpeqw", int_x86_avx2_pcmpeq_w,
4120                                     VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
4121   defm VPCMPEQDY : PDI_binop_rm_int<0x76, "vpcmpeqd", int_x86_avx2_pcmpeq_d,
4122                                     VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
4123   defm VPCMPGTBY : PDI_binop_rm_int<0x64, "vpcmpgtb", int_x86_avx2_pcmpgt_b,
4124                                     VR256, memopv4i64, i256mem, 0, 0>, VEX_4V;
4125   defm VPCMPGTWY : PDI_binop_rm_int<0x65, "vpcmpgtw", int_x86_avx2_pcmpgt_w,
4126                                     VR256, memopv4i64, i256mem, 0, 0>, VEX_4V;
4127   defm VPCMPGTDY : PDI_binop_rm_int<0x66, "vpcmpgtd", int_x86_avx2_pcmpgt_d,
4128                                     VR256, memopv4i64, i256mem, 0, 0>, VEX_4V;
4129
4130   def : Pat<(v32i8 (X86pcmpeq VR256:$src1, VR256:$src2)),
4131             (VPCMPEQBYrr VR256:$src1, VR256:$src2)>;
4132   def : Pat<(v32i8 (X86pcmpeq VR256:$src1,
4133                     (bc_v32i8 (memopv4i64 addr:$src2)))),
4134             (VPCMPEQBYrm VR256:$src1, addr:$src2)>;
4135   def : Pat<(v16i16 (X86pcmpeq VR256:$src1, VR256:$src2)),
4136             (VPCMPEQWYrr VR256:$src1, VR256:$src2)>;
4137   def : Pat<(v16i16 (X86pcmpeq VR256:$src1,
4138                      (bc_v16i16 (memopv4i64 addr:$src2)))),
4139             (VPCMPEQWYrm VR256:$src1, addr:$src2)>;
4140   def : Pat<(v8i32 (X86pcmpeq VR256:$src1, VR256:$src2)),
4141             (VPCMPEQDYrr VR256:$src1, VR256:$src2)>;
4142   def : Pat<(v8i32 (X86pcmpeq VR256:$src1,
4143                     (bc_v8i32 (memopv4i64 addr:$src2)))),
4144             (VPCMPEQDYrm VR256:$src1, addr:$src2)>;
4145
4146   def : Pat<(v32i8 (X86pcmpgt VR256:$src1, VR256:$src2)),
4147             (VPCMPGTBYrr VR256:$src1, VR256:$src2)>;
4148   def : Pat<(v32i8 (X86pcmpgt VR256:$src1,
4149                     (bc_v32i8 (memopv4i64 addr:$src2)))),
4150             (VPCMPGTBYrm VR256:$src1, addr:$src2)>;
4151   def : Pat<(v16i16 (X86pcmpgt VR256:$src1, VR256:$src2)),
4152             (VPCMPGTWYrr VR256:$src1, VR256:$src2)>;
4153   def : Pat<(v16i16 (X86pcmpgt VR256:$src1,
4154                      (bc_v16i16 (memopv4i64 addr:$src2)))),
4155             (VPCMPGTWYrm VR256:$src1, addr:$src2)>;
4156   def : Pat<(v8i32 (X86pcmpgt VR256:$src1, VR256:$src2)),
4157             (VPCMPGTDYrr VR256:$src1, VR256:$src2)>;
4158   def : Pat<(v8i32 (X86pcmpgt VR256:$src1,
4159                     (bc_v8i32 (memopv4i64 addr:$src2)))),
4160             (VPCMPGTDYrm VR256:$src1, addr:$src2)>;
4161 }
4162
4163 let Constraints = "$src1 = $dst" in {
4164   defm PCMPEQB  : PDI_binop_rm_int<0x74, "pcmpeqb", int_x86_sse2_pcmpeq_b,
4165                                    VR128, memopv2i64, i128mem, 1>;
4166   defm PCMPEQW  : PDI_binop_rm_int<0x75, "pcmpeqw", int_x86_sse2_pcmpeq_w,
4167                                    VR128, memopv2i64, i128mem, 1>;
4168   defm PCMPEQD  : PDI_binop_rm_int<0x76, "pcmpeqd", int_x86_sse2_pcmpeq_d,
4169                                    VR128, memopv2i64, i128mem, 1>;
4170   defm PCMPGTB  : PDI_binop_rm_int<0x64, "pcmpgtb", int_x86_sse2_pcmpgt_b,
4171                                    VR128, memopv2i64, i128mem>;
4172   defm PCMPGTW  : PDI_binop_rm_int<0x65, "pcmpgtw", int_x86_sse2_pcmpgt_w,
4173                                    VR128, memopv2i64, i128mem>;
4174   defm PCMPGTD  : PDI_binop_rm_int<0x66, "pcmpgtd", int_x86_sse2_pcmpgt_d,
4175                                    VR128, memopv2i64, i128mem>;
4176 } // Constraints = "$src1 = $dst"
4177
4178 let Predicates = [HasSSE2] in {
4179   def : Pat<(v16i8 (X86pcmpeq VR128:$src1, VR128:$src2)),
4180             (PCMPEQBrr VR128:$src1, VR128:$src2)>;
4181   def : Pat<(v16i8 (X86pcmpeq VR128:$src1,
4182                     (bc_v16i8 (memopv2i64 addr:$src2)))),
4183             (PCMPEQBrm VR128:$src1, addr:$src2)>;
4184   def : Pat<(v8i16 (X86pcmpeq VR128:$src1, VR128:$src2)),
4185             (PCMPEQWrr VR128:$src1, VR128:$src2)>;
4186   def : Pat<(v8i16 (X86pcmpeq VR128:$src1,
4187                     (bc_v8i16 (memopv2i64 addr:$src2)))),
4188             (PCMPEQWrm VR128:$src1, addr:$src2)>;
4189   def : Pat<(v4i32 (X86pcmpeq VR128:$src1, VR128:$src2)),
4190             (PCMPEQDrr VR128:$src1, VR128:$src2)>;
4191   def : Pat<(v4i32 (X86pcmpeq VR128:$src1,
4192                     (bc_v4i32 (memopv2i64 addr:$src2)))),
4193             (PCMPEQDrm VR128:$src1, addr:$src2)>;
4194
4195   def : Pat<(v16i8 (X86pcmpgt VR128:$src1, VR128:$src2)),
4196             (PCMPGTBrr VR128:$src1, VR128:$src2)>;
4197   def : Pat<(v16i8 (X86pcmpgt VR128:$src1,
4198              (bc_v16i8 (memopv2i64 addr:$src2)))),
4199             (PCMPGTBrm VR128:$src1, addr:$src2)>;
4200   def : Pat<(v8i16 (X86pcmpgt VR128:$src1, VR128:$src2)),
4201             (PCMPGTWrr VR128:$src1, VR128:$src2)>;
4202   def : Pat<(v8i16 (X86pcmpgt VR128:$src1,
4203                     (bc_v8i16 (memopv2i64 addr:$src2)))),
4204             (PCMPGTWrm VR128:$src1, addr:$src2)>;
4205   def : Pat<(v4i32 (X86pcmpgt VR128:$src1, VR128:$src2)),
4206             (PCMPGTDrr VR128:$src1, VR128:$src2)>;
4207   def : Pat<(v4i32 (X86pcmpgt VR128:$src1,
4208                     (bc_v4i32 (memopv2i64 addr:$src2)))),
4209             (PCMPGTDrm VR128:$src1, addr:$src2)>;
4210 }
4211
4212 //===---------------------------------------------------------------------===//
4213 // SSE2 - Packed Integer Pack Instructions
4214 //===---------------------------------------------------------------------===//
4215
4216 let Predicates = [HasAVX] in {
4217 defm VPACKSSWB : PDI_binop_rm_int<0x63, "vpacksswb", int_x86_sse2_packsswb_128,
4218                                   VR128, memopv2i64, i128mem, 0, 0>, VEX_4V;
4219 defm VPACKSSDW : PDI_binop_rm_int<0x6B, "vpackssdw", int_x86_sse2_packssdw_128,
4220                                   VR128, memopv2i64, i128mem, 0, 0>, VEX_4V;
4221 defm VPACKUSWB : PDI_binop_rm_int<0x67, "vpackuswb", int_x86_sse2_packuswb_128,
4222                                   VR128, memopv2i64, i128mem, 0, 0>, VEX_4V;
4223 }
4224
4225 let Predicates = [HasAVX2] in {
4226 defm VPACKSSWBY : PDI_binop_rm_int<0x63, "vpacksswb", int_x86_avx2_packsswb,
4227                                    VR256, memopv4i64, i256mem, 0, 0>, VEX_4V;
4228 defm VPACKSSDWY : PDI_binop_rm_int<0x6B, "vpackssdw", int_x86_avx2_packssdw,
4229                                    VR256, memopv4i64, i256mem, 0, 0>, VEX_4V;
4230 defm VPACKUSWBY : PDI_binop_rm_int<0x67, "vpackuswb", int_x86_avx2_packuswb,
4231                                    VR256, memopv4i64, i256mem, 0, 0>, VEX_4V;
4232 }
4233
4234 let Constraints = "$src1 = $dst" in {
4235 defm PACKSSWB : PDI_binop_rm_int<0x63, "packsswb", int_x86_sse2_packsswb_128,
4236                                  VR128, memopv2i64, i128mem>;
4237 defm PACKSSDW : PDI_binop_rm_int<0x6B, "packssdw", int_x86_sse2_packssdw_128,
4238                                  VR128, memopv2i64, i128mem>;
4239 defm PACKUSWB : PDI_binop_rm_int<0x67, "packuswb", int_x86_sse2_packuswb_128,
4240                                  VR128, memopv2i64, i128mem>;
4241 } // Constraints = "$src1 = $dst"
4242
4243 //===---------------------------------------------------------------------===//
4244 // SSE2 - Packed Integer Shuffle Instructions
4245 //===---------------------------------------------------------------------===//
4246
4247 let ExeDomain = SSEPackedInt in {
4248 multiclass sse2_pshuffle<string OpcodeStr, ValueType vt, PatFrag pshuf_frag,
4249                          PatFrag bc_frag> {
4250 def ri : Ii8<0x70, MRMSrcReg,
4251               (outs VR128:$dst), (ins VR128:$src1, i8imm:$src2),
4252               !strconcat(OpcodeStr,
4253                          "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4254               [(set VR128:$dst, (vt (pshuf_frag:$src2 VR128:$src1,
4255                                                       (undef))))]>;
4256 def mi : Ii8<0x70, MRMSrcMem,
4257               (outs VR128:$dst), (ins i128mem:$src1, i8imm:$src2),
4258               !strconcat(OpcodeStr,
4259                          "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4260               [(set VR128:$dst, (vt (pshuf_frag:$src2
4261                                       (bc_frag (memopv2i64 addr:$src1)),
4262                                       (undef))))]>;
4263 }
4264
4265 multiclass sse2_pshuffle_y<string OpcodeStr, ValueType vt, PatFrag pshuf_frag,
4266                            PatFrag bc_frag> {
4267 def Yri : Ii8<0x70, MRMSrcReg,
4268               (outs VR256:$dst), (ins VR256:$src1, i8imm:$src2),
4269               !strconcat(OpcodeStr,
4270                          "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4271               [(set VR256:$dst, (vt (pshuf_frag:$src2 VR256:$src1,
4272                                                       (undef))))]>;
4273 def Ymi : Ii8<0x70, MRMSrcMem,
4274               (outs VR256:$dst), (ins i256mem:$src1, i8imm:$src2),
4275               !strconcat(OpcodeStr,
4276                          "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4277               [(set VR256:$dst, (vt (pshuf_frag:$src2
4278                                       (bc_frag (memopv4i64 addr:$src1)),
4279                                       (undef))))]>;
4280 }
4281 } // ExeDomain = SSEPackedInt
4282
4283 let Predicates = [HasAVX] in {
4284   let AddedComplexity = 5 in
4285   defm VPSHUFD : sse2_pshuffle<"vpshufd", v4i32, pshufd, bc_v4i32>, TB, OpSize,
4286                                VEX;
4287
4288   // SSE2 with ImmT == Imm8 and XS prefix.
4289   defm VPSHUFHW : sse2_pshuffle<"vpshufhw", v8i16, pshufhw, bc_v8i16>, XS,
4290                                VEX;
4291
4292   // SSE2 with ImmT == Imm8 and XD prefix.
4293   defm VPSHUFLW : sse2_pshuffle<"vpshuflw", v8i16, pshuflw, bc_v8i16>, XD,
4294                                VEX;
4295
4296   let AddedComplexity = 5 in
4297   def : Pat<(v4f32 (pshufd:$src2 VR128:$src1, (undef))),
4298             (VPSHUFDri VR128:$src1, (SHUFFLE_get_shuf_imm VR128:$src2))>;
4299   // Unary v4f32 shuffle with VPSHUF* in order to fold a load.
4300   def : Pat<(pshufd:$src2 (bc_v4i32 (memopv4f32 addr:$src1)), (undef)),
4301             (VPSHUFDmi addr:$src1, (SHUFFLE_get_shuf_imm VR128:$src2))>;
4302
4303   def : Pat<(v4i32 (X86PShufd (bc_v4i32 (memopv2i64 addr:$src1)),
4304                                    (i8 imm:$imm))),
4305             (VPSHUFDmi addr:$src1, imm:$imm)>;
4306   def : Pat<(v4i32 (X86PShufd (bc_v4i32 (memopv4f32 addr:$src1)),
4307                                    (i8 imm:$imm))),
4308             (VPSHUFDmi addr:$src1, imm:$imm)>;
4309   def : Pat<(v4f32 (X86PShufd VR128:$src1, (i8 imm:$imm))),
4310             (VPSHUFDri VR128:$src1, imm:$imm)>;
4311   def : Pat<(v4i32 (X86PShufd VR128:$src1, (i8 imm:$imm))),
4312             (VPSHUFDri VR128:$src1, imm:$imm)>;
4313   def : Pat<(v8i16 (X86PShufhw VR128:$src, (i8 imm:$imm))),
4314             (VPSHUFHWri VR128:$src, imm:$imm)>;
4315   def : Pat<(v8i16 (X86PShufhw (bc_v8i16 (memopv2i64 addr:$src)),
4316                                (i8 imm:$imm))),
4317             (VPSHUFHWmi addr:$src, imm:$imm)>;
4318   def : Pat<(v8i16 (X86PShuflw VR128:$src, (i8 imm:$imm))),
4319             (VPSHUFLWri VR128:$src, imm:$imm)>;
4320   def : Pat<(v8i16 (X86PShuflw (bc_v8i16 (memopv2i64 addr:$src)),
4321                                (i8 imm:$imm))),
4322             (VPSHUFLWmi addr:$src, imm:$imm)>;
4323 }
4324
4325 let Predicates = [HasAVX2] in {
4326   let AddedComplexity = 5 in
4327   defm VPSHUFD : sse2_pshuffle_y<"vpshufd", v8i32, pshufd, bc_v8i32>, TB,
4328                                  OpSize, VEX;
4329
4330   // SSE2 with ImmT == Imm8 and XS prefix.
4331   defm VPSHUFHW : sse2_pshuffle_y<"vpshufhw", v16i16, pshufhw, bc_v16i16>, XS,
4332                                   VEX;
4333
4334   // SSE2 with ImmT == Imm8 and XD prefix.
4335   defm VPSHUFLW : sse2_pshuffle_y<"vpshuflw", v16i16, pshuflw, bc_v16i16>, XD,
4336                                   VEX;
4337 }
4338
4339 let Predicates = [HasSSE2] in {
4340   let AddedComplexity = 5 in
4341   defm PSHUFD : sse2_pshuffle<"pshufd", v4i32, pshufd, bc_v4i32>, TB, OpSize;
4342
4343   // SSE2 with ImmT == Imm8 and XS prefix.
4344   defm PSHUFHW : sse2_pshuffle<"pshufhw", v8i16, pshufhw, bc_v8i16>, XS;
4345
4346   // SSE2 with ImmT == Imm8 and XD prefix.
4347   defm PSHUFLW : sse2_pshuffle<"pshuflw", v8i16, pshuflw, bc_v8i16>, XD;
4348
4349   let AddedComplexity = 5 in
4350   def : Pat<(v4f32 (pshufd:$src2 VR128:$src1, (undef))),
4351             (PSHUFDri VR128:$src1, (SHUFFLE_get_shuf_imm VR128:$src2))>;
4352   // Unary v4f32 shuffle with PSHUF* in order to fold a load.
4353   def : Pat<(pshufd:$src2 (bc_v4i32 (memopv4f32 addr:$src1)), (undef)),
4354             (PSHUFDmi addr:$src1, (SHUFFLE_get_shuf_imm VR128:$src2))>;
4355
4356   def : Pat<(v4i32 (X86PShufd (bc_v4i32 (memopv2i64 addr:$src1)),
4357                                    (i8 imm:$imm))),
4358             (PSHUFDmi addr:$src1, imm:$imm)>;
4359   def : Pat<(v4i32 (X86PShufd (bc_v4i32 (memopv4f32 addr:$src1)),
4360                                    (i8 imm:$imm))),
4361             (PSHUFDmi addr:$src1, imm:$imm)>;
4362   def : Pat<(v4f32 (X86PShufd VR128:$src1, (i8 imm:$imm))),
4363             (PSHUFDri VR128:$src1, imm:$imm)>;
4364   def : Pat<(v4i32 (X86PShufd VR128:$src1, (i8 imm:$imm))),
4365             (PSHUFDri VR128:$src1, imm:$imm)>;
4366   def : Pat<(v8i16 (X86PShufhw VR128:$src, (i8 imm:$imm))),
4367             (PSHUFHWri VR128:$src, imm:$imm)>;
4368   def : Pat<(v8i16 (X86PShufhw (bc_v8i16 (memopv2i64 addr:$src)),
4369                                (i8 imm:$imm))),
4370             (PSHUFHWmi addr:$src, imm:$imm)>;
4371   def : Pat<(v8i16 (X86PShuflw VR128:$src, (i8 imm:$imm))),
4372             (PSHUFLWri VR128:$src, imm:$imm)>;
4373   def : Pat<(v8i16 (X86PShuflw (bc_v8i16 (memopv2i64 addr:$src)),
4374                                (i8 imm:$imm))),
4375             (PSHUFLWmi addr:$src, imm:$imm)>;
4376 }
4377
4378 //===---------------------------------------------------------------------===//
4379 // SSE2 - Packed Integer Unpack Instructions
4380 //===---------------------------------------------------------------------===//
4381
4382 let ExeDomain = SSEPackedInt in {
4383 multiclass sse2_unpack<bits<8> opc, string OpcodeStr, ValueType vt,
4384                        SDNode OpNode, PatFrag bc_frag, bit Is2Addr = 1> {
4385   def rr : PDI<opc, MRMSrcReg,
4386       (outs VR128:$dst), (ins VR128:$src1, VR128:$src2),
4387       !if(Is2Addr,
4388           !strconcat(OpcodeStr,"\t{$src2, $dst|$dst, $src2}"),
4389           !strconcat(OpcodeStr,"\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
4390       [(set VR128:$dst, (vt (OpNode VR128:$src1, VR128:$src2)))]>;
4391   def rm : PDI<opc, MRMSrcMem,
4392       (outs VR128:$dst), (ins VR128:$src1, i128mem:$src2),
4393       !if(Is2Addr,
4394           !strconcat(OpcodeStr,"\t{$src2, $dst|$dst, $src2}"),
4395           !strconcat(OpcodeStr,"\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
4396       [(set VR128:$dst, (OpNode VR128:$src1,
4397                                   (bc_frag (memopv2i64
4398                                                addr:$src2))))]>;
4399 }
4400
4401 multiclass sse2_unpack_y<bits<8> opc, string OpcodeStr, ValueType vt,
4402                          SDNode OpNode, PatFrag bc_frag> {
4403   def Yrr : PDI<opc, MRMSrcReg,
4404       (outs VR256:$dst), (ins VR256:$src1, VR256:$src2),
4405       !strconcat(OpcodeStr,"\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4406       [(set VR256:$dst, (vt (OpNode VR256:$src1, VR256:$src2)))]>;
4407   def Yrm : PDI<opc, MRMSrcMem,
4408       (outs VR256:$dst), (ins VR256:$src1, i256mem:$src2),
4409       !strconcat(OpcodeStr,"\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4410       [(set VR256:$dst, (OpNode VR256:$src1,
4411                                   (bc_frag (memopv4i64 addr:$src2))))]>;
4412 }
4413
4414 let Predicates = [HasAVX] in {
4415   defm VPUNPCKLBW  : sse2_unpack<0x60, "vpunpcklbw", v16i8, X86Unpckl,
4416                                  bc_v16i8, 0>, VEX_4V;
4417   defm VPUNPCKLWD  : sse2_unpack<0x61, "vpunpcklwd", v8i16, X86Unpckl,
4418                                  bc_v8i16, 0>, VEX_4V;
4419   defm VPUNPCKLDQ  : sse2_unpack<0x62, "vpunpckldq", v4i32, X86Unpckl,
4420                                  bc_v4i32, 0>, VEX_4V;
4421   defm VPUNPCKLQDQ : sse2_unpack<0x6C, "vpunpcklqdq", v2i64, X86Unpckl,
4422                                  bc_v2i64, 0>, VEX_4V;
4423
4424   defm VPUNPCKHBW  : sse2_unpack<0x68, "vpunpckhbw", v16i8, X86Unpckh,
4425                                  bc_v16i8, 0>, VEX_4V;
4426   defm VPUNPCKHWD  : sse2_unpack<0x69, "vpunpckhwd", v8i16, X86Unpckh,
4427                                  bc_v8i16, 0>, VEX_4V;
4428   defm VPUNPCKHDQ  : sse2_unpack<0x6A, "vpunpckhdq", v4i32, X86Unpckh,
4429                                  bc_v4i32, 0>, VEX_4V;
4430   defm VPUNPCKHQDQ : sse2_unpack<0x6D, "vpunpckhqdq", v2i64, X86Unpckh,
4431                                  bc_v2i64, 0>, VEX_4V;
4432 }
4433
4434 let Predicates = [HasAVX2] in {
4435   defm VPUNPCKLBW  : sse2_unpack_y<0x60, "vpunpcklbw", v32i8, X86Unpckl,
4436                                    bc_v32i8>, VEX_4V;
4437   defm VPUNPCKLWD  : sse2_unpack_y<0x61, "vpunpcklwd", v16i16, X86Unpckl,
4438                                    bc_v16i16>, VEX_4V;
4439   defm VPUNPCKLDQ  : sse2_unpack_y<0x62, "vpunpckldq", v8i32, X86Unpckl,
4440                                    bc_v8i32>, VEX_4V;
4441   defm VPUNPCKLQDQ : sse2_unpack_y<0x6C, "vpunpcklqdq", v4i64, X86Unpckl,
4442                                    bc_v4i64>, VEX_4V;
4443
4444   defm VPUNPCKHBW  : sse2_unpack_y<0x68, "vpunpckhbw", v32i8, X86Unpckh,
4445                                    bc_v32i8>, VEX_4V;
4446   defm VPUNPCKHWD  : sse2_unpack_y<0x69, "vpunpckhwd", v16i16, X86Unpckh,
4447                                    bc_v16i16>, VEX_4V;
4448   defm VPUNPCKHDQ  : sse2_unpack_y<0x6A, "vpunpckhdq", v8i32, X86Unpckh,
4449                                    bc_v8i32>, VEX_4V;
4450   defm VPUNPCKHQDQ : sse2_unpack_y<0x6D, "vpunpckhqdq", v4i64, X86Unpckh,
4451                                    bc_v4i64>, VEX_4V;
4452 }
4453
4454 let Constraints = "$src1 = $dst" in {
4455   defm PUNPCKLBW  : sse2_unpack<0x60, "punpcklbw", v16i8, X86Unpckl,
4456                                 bc_v16i8>;
4457   defm PUNPCKLWD  : sse2_unpack<0x61, "punpcklwd", v8i16, X86Unpckl,
4458                                 bc_v8i16>;
4459   defm PUNPCKLDQ  : sse2_unpack<0x62, "punpckldq", v4i32, X86Unpckl,
4460                                 bc_v4i32>;
4461   defm PUNPCKLQDQ : sse2_unpack<0x6C, "punpcklqdq", v2i64, X86Unpckl,
4462                                 bc_v2i64>;
4463
4464   defm PUNPCKHBW  : sse2_unpack<0x68, "punpckhbw", v16i8, X86Unpckh,
4465                                 bc_v16i8>;
4466   defm PUNPCKHWD  : sse2_unpack<0x69, "punpckhwd", v8i16, X86Unpckh,
4467                                 bc_v8i16>;
4468   defm PUNPCKHDQ  : sse2_unpack<0x6A, "punpckhdq", v4i32, X86Unpckh,
4469                                 bc_v4i32>;
4470   defm PUNPCKHQDQ : sse2_unpack<0x6D, "punpckhqdq", v2i64, X86Unpckh,
4471                                 bc_v2i64>;
4472 }
4473 } // ExeDomain = SSEPackedInt
4474
4475 // Patterns for using AVX1 instructions with integer vectors
4476 // Here to give AVX2 priority
4477 let Predicates = [HasAVX] in {
4478   def : Pat<(v8i32 (X86Unpckl VR256:$src1, (bc_v8i32 (memopv4i64 addr:$src2)))),
4479             (VUNPCKLPSYrm VR256:$src1, addr:$src2)>;
4480   def : Pat<(v8i32 (X86Unpckl VR256:$src1, VR256:$src2)),
4481             (VUNPCKLPSYrr VR256:$src1, VR256:$src2)>;
4482   def : Pat<(v8i32 (X86Unpckh VR256:$src1, (bc_v8i32 (memopv4i64 addr:$src2)))),
4483             (VUNPCKHPSYrm VR256:$src1, addr:$src2)>;
4484   def : Pat<(v8i32 (X86Unpckh VR256:$src1, VR256:$src2)),
4485             (VUNPCKHPSYrr VR256:$src1, VR256:$src2)>;
4486
4487   def : Pat<(v4i64 (X86Unpckl VR256:$src1, (memopv4i64 addr:$src2))),
4488             (VUNPCKLPDYrm VR256:$src1, addr:$src2)>;
4489   def : Pat<(v4i64 (X86Unpckl VR256:$src1, VR256:$src2)),
4490             (VUNPCKLPDYrr VR256:$src1, VR256:$src2)>;
4491   def : Pat<(v4i64 (X86Unpckh VR256:$src1, (memopv4i64 addr:$src2))),
4492             (VUNPCKHPDYrm VR256:$src1, addr:$src2)>;
4493   def : Pat<(v4i64 (X86Unpckh VR256:$src1, VR256:$src2)),
4494             (VUNPCKHPDYrr VR256:$src1, VR256:$src2)>;
4495 }
4496
4497 // Splat v2f64 / v2i64
4498 let AddedComplexity = 10 in {
4499   def : Pat<(splat_lo (v2i64 VR128:$src), (undef)),
4500             (PUNPCKLQDQrr VR128:$src, VR128:$src)>, Requires<[HasSSE2]>;
4501   def : Pat<(splat_lo (v2i64 VR128:$src), (undef)),
4502             (VPUNPCKLQDQrr VR128:$src, VR128:$src)>, Requires<[HasAVX]>;
4503 }
4504
4505 //===---------------------------------------------------------------------===//
4506 // SSE2 - Packed Integer Extract and Insert
4507 //===---------------------------------------------------------------------===//
4508
4509 let ExeDomain = SSEPackedInt in {
4510 multiclass sse2_pinsrw<bit Is2Addr = 1> {
4511   def rri : Ii8<0xC4, MRMSrcReg,
4512        (outs VR128:$dst), (ins VR128:$src1,
4513         GR32:$src2, i32i8imm:$src3),
4514        !if(Is2Addr,
4515            "pinsrw\t{$src3, $src2, $dst|$dst, $src2, $src3}",
4516            "vpinsrw\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
4517        [(set VR128:$dst,
4518          (X86pinsrw VR128:$src1, GR32:$src2, imm:$src3))]>;
4519   def rmi : Ii8<0xC4, MRMSrcMem,
4520                        (outs VR128:$dst), (ins VR128:$src1,
4521                         i16mem:$src2, i32i8imm:$src3),
4522        !if(Is2Addr,
4523            "pinsrw\t{$src3, $src2, $dst|$dst, $src2, $src3}",
4524            "vpinsrw\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
4525        [(set VR128:$dst,
4526          (X86pinsrw VR128:$src1, (extloadi16 addr:$src2),
4527                     imm:$src3))]>;
4528 }
4529
4530 // Extract
4531 let Predicates = [HasAVX] in
4532 def VPEXTRWri : Ii8<0xC5, MRMSrcReg,
4533                     (outs GR32:$dst), (ins VR128:$src1, i32i8imm:$src2),
4534                     "vpextrw\t{$src2, $src1, $dst|$dst, $src1, $src2}",
4535                     [(set GR32:$dst, (X86pextrw (v8i16 VR128:$src1),
4536                                                 imm:$src2))]>, TB, OpSize, VEX;
4537 def PEXTRWri : PDIi8<0xC5, MRMSrcReg,
4538                     (outs GR32:$dst), (ins VR128:$src1, i32i8imm:$src2),
4539                     "pextrw\t{$src2, $src1, $dst|$dst, $src1, $src2}",
4540                     [(set GR32:$dst, (X86pextrw (v8i16 VR128:$src1),
4541                                                 imm:$src2))]>;
4542
4543 // Insert
4544 let Predicates = [HasAVX] in {
4545   defm VPINSRW : sse2_pinsrw<0>, TB, OpSize, VEX_4V;
4546   def  VPINSRWrr64i : Ii8<0xC4, MRMSrcReg, (outs VR128:$dst),
4547        (ins VR128:$src1, GR64:$src2, i32i8imm:$src3),
4548        "vpinsrw\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
4549        []>, TB, OpSize, VEX_4V;
4550 }
4551
4552 let Constraints = "$src1 = $dst" in
4553   defm PINSRW : sse2_pinsrw, TB, OpSize, Requires<[HasSSE2]>;
4554
4555 } // ExeDomain = SSEPackedInt
4556
4557 //===---------------------------------------------------------------------===//
4558 // SSE2 - Packed Mask Creation
4559 //===---------------------------------------------------------------------===//
4560
4561 let ExeDomain = SSEPackedInt in {
4562
4563 def VPMOVMSKBrr  : VPDI<0xD7, MRMSrcReg, (outs GR32:$dst), (ins VR128:$src),
4564            "pmovmskb\t{$src, $dst|$dst, $src}",
4565            [(set GR32:$dst, (int_x86_sse2_pmovmskb_128 VR128:$src))]>, VEX;
4566 def VPMOVMSKBr64r : VPDI<0xD7, MRMSrcReg, (outs GR64:$dst), (ins VR128:$src),
4567            "pmovmskb\t{$src, $dst|$dst, $src}", []>, VEX;
4568
4569 let Predicates = [HasAVX2] in {
4570 def VPMOVMSKBYrr  : VPDI<0xD7, MRMSrcReg, (outs GR32:$dst), (ins VR256:$src),
4571            "pmovmskb\t{$src, $dst|$dst, $src}",
4572            [(set GR32:$dst, (int_x86_avx2_pmovmskb VR256:$src))]>, VEX;
4573 def VPMOVMSKBYr64r : VPDI<0xD7, MRMSrcReg, (outs GR64:$dst), (ins VR256:$src),
4574            "pmovmskb\t{$src, $dst|$dst, $src}", []>, VEX;
4575 }
4576
4577 def PMOVMSKBrr : PDI<0xD7, MRMSrcReg, (outs GR32:$dst), (ins VR128:$src),
4578            "pmovmskb\t{$src, $dst|$dst, $src}",
4579            [(set GR32:$dst, (int_x86_sse2_pmovmskb_128 VR128:$src))]>;
4580
4581 } // ExeDomain = SSEPackedInt
4582
4583 //===---------------------------------------------------------------------===//
4584 // SSE2 - Conditional Store
4585 //===---------------------------------------------------------------------===//
4586
4587 let ExeDomain = SSEPackedInt in {
4588
4589 let Uses = [EDI] in
4590 def VMASKMOVDQU : VPDI<0xF7, MRMSrcReg, (outs),
4591            (ins VR128:$src, VR128:$mask),
4592            "maskmovdqu\t{$mask, $src|$src, $mask}",
4593            [(int_x86_sse2_maskmov_dqu VR128:$src, VR128:$mask, EDI)]>, VEX;
4594 let Uses = [RDI] in
4595 def VMASKMOVDQU64 : VPDI<0xF7, MRMSrcReg, (outs),
4596            (ins VR128:$src, VR128:$mask),
4597            "maskmovdqu\t{$mask, $src|$src, $mask}",
4598            [(int_x86_sse2_maskmov_dqu VR128:$src, VR128:$mask, RDI)]>, VEX;
4599
4600 let Uses = [EDI] in
4601 def MASKMOVDQU : PDI<0xF7, MRMSrcReg, (outs), (ins VR128:$src, VR128:$mask),
4602            "maskmovdqu\t{$mask, $src|$src, $mask}",
4603            [(int_x86_sse2_maskmov_dqu VR128:$src, VR128:$mask, EDI)]>;
4604 let Uses = [RDI] in
4605 def MASKMOVDQU64 : PDI<0xF7, MRMSrcReg, (outs), (ins VR128:$src, VR128:$mask),
4606            "maskmovdqu\t{$mask, $src|$src, $mask}",
4607            [(int_x86_sse2_maskmov_dqu VR128:$src, VR128:$mask, RDI)]>;
4608
4609 } // ExeDomain = SSEPackedInt
4610
4611 //===---------------------------------------------------------------------===//
4612 // SSE2 - Move Doubleword
4613 //===---------------------------------------------------------------------===//
4614
4615 //===---------------------------------------------------------------------===//
4616 // Move Int Doubleword to Packed Double Int
4617 //
4618 def VMOVDI2PDIrr : VPDI<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR32:$src),
4619                       "movd\t{$src, $dst|$dst, $src}",
4620                       [(set VR128:$dst,
4621                         (v4i32 (scalar_to_vector GR32:$src)))]>, VEX;
4622 def VMOVDI2PDIrm : VPDI<0x6E, MRMSrcMem, (outs VR128:$dst), (ins i32mem:$src),
4623                       "movd\t{$src, $dst|$dst, $src}",
4624                       [(set VR128:$dst,
4625                         (v4i32 (scalar_to_vector (loadi32 addr:$src))))]>,
4626                       VEX;
4627 def VMOV64toPQIrr : VRPDI<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR64:$src),
4628                         "mov{d|q}\t{$src, $dst|$dst, $src}",
4629                         [(set VR128:$dst,
4630                           (v2i64 (scalar_to_vector GR64:$src)))]>, VEX;
4631 def VMOV64toSDrr : VRPDI<0x6E, MRMSrcReg, (outs FR64:$dst), (ins GR64:$src),
4632                        "mov{d|q}\t{$src, $dst|$dst, $src}",
4633                        [(set FR64:$dst, (bitconvert GR64:$src))]>, VEX;
4634
4635 def MOVDI2PDIrr : PDI<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR32:$src),
4636                       "movd\t{$src, $dst|$dst, $src}",
4637                       [(set VR128:$dst,
4638                         (v4i32 (scalar_to_vector GR32:$src)))]>;
4639 def MOVDI2PDIrm : PDI<0x6E, MRMSrcMem, (outs VR128:$dst), (ins i32mem:$src),
4640                       "movd\t{$src, $dst|$dst, $src}",
4641                       [(set VR128:$dst,
4642                         (v4i32 (scalar_to_vector (loadi32 addr:$src))))]>;
4643 def MOV64toPQIrr : RPDI<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR64:$src),
4644                         "mov{d|q}\t{$src, $dst|$dst, $src}",
4645                         [(set VR128:$dst,
4646                           (v2i64 (scalar_to_vector GR64:$src)))]>;
4647 def MOV64toSDrr : RPDI<0x6E, MRMSrcReg, (outs FR64:$dst), (ins GR64:$src),
4648                        "mov{d|q}\t{$src, $dst|$dst, $src}",
4649                        [(set FR64:$dst, (bitconvert GR64:$src))]>;
4650
4651 //===---------------------------------------------------------------------===//
4652 // Move Int Doubleword to Single Scalar
4653 //
4654 def VMOVDI2SSrr  : VPDI<0x6E, MRMSrcReg, (outs FR32:$dst), (ins GR32:$src),
4655                       "movd\t{$src, $dst|$dst, $src}",
4656                       [(set FR32:$dst, (bitconvert GR32:$src))]>, VEX;
4657
4658 def VMOVDI2SSrm  : VPDI<0x6E, MRMSrcMem, (outs FR32:$dst), (ins i32mem:$src),
4659                       "movd\t{$src, $dst|$dst, $src}",
4660                       [(set FR32:$dst, (bitconvert (loadi32 addr:$src)))]>,
4661                       VEX;
4662 def MOVDI2SSrr  : PDI<0x6E, MRMSrcReg, (outs FR32:$dst), (ins GR32:$src),
4663                       "movd\t{$src, $dst|$dst, $src}",
4664                       [(set FR32:$dst, (bitconvert GR32:$src))]>;
4665
4666 def MOVDI2SSrm  : PDI<0x6E, MRMSrcMem, (outs FR32:$dst), (ins i32mem:$src),
4667                       "movd\t{$src, $dst|$dst, $src}",
4668                       [(set FR32:$dst, (bitconvert (loadi32 addr:$src)))]>;
4669
4670 //===---------------------------------------------------------------------===//
4671 // Move Packed Doubleword Int to Packed Double Int
4672 //
4673 def VMOVPDI2DIrr  : VPDI<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)))]>, VEX;
4677 def VMOVPDI2DImr  : VPDI<0x7E, MRMDestMem, (outs),
4678                        (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)]>, VEX;
4682 def MOVPDI2DIrr  : PDI<0x7E, MRMDestReg, (outs GR32:$dst), (ins VR128:$src),
4683                        "movd\t{$src, $dst|$dst, $src}",
4684                        [(set GR32:$dst, (vector_extract (v4i32 VR128:$src),
4685                                         (iPTR 0)))]>;
4686 def MOVPDI2DImr  : PDI<0x7E, MRMDestMem, (outs), (ins i32mem:$dst, VR128:$src),
4687                        "movd\t{$src, $dst|$dst, $src}",
4688                        [(store (i32 (vector_extract (v4i32 VR128:$src),
4689                                      (iPTR 0))), addr:$dst)]>;
4690
4691 //===---------------------------------------------------------------------===//
4692 // Move Packed Doubleword Int first element to Doubleword Int
4693 //
4694 def VMOVPQIto64rr : I<0x7E, MRMDestReg, (outs GR64:$dst), (ins VR128:$src),
4695                           "mov{d|q}\t{$src, $dst|$dst, $src}",
4696                           [(set GR64:$dst, (vector_extract (v2i64 VR128:$src),
4697                                                            (iPTR 0)))]>,
4698                       TB, OpSize, VEX, VEX_W, Requires<[HasAVX, In64BitMode]>;
4699
4700 def MOVPQIto64rr : RPDI<0x7E, MRMDestReg, (outs GR64:$dst), (ins VR128:$src),
4701                         "mov{d|q}\t{$src, $dst|$dst, $src}",
4702                         [(set GR64:$dst, (vector_extract (v2i64 VR128:$src),
4703                                                          (iPTR 0)))]>;
4704
4705 //===---------------------------------------------------------------------===//
4706 // Bitcast FR64 <-> GR64
4707 //
4708 let Predicates = [HasAVX] in
4709 def VMOV64toSDrm : S3SI<0x7E, MRMSrcMem, (outs FR64:$dst), (ins i64mem:$src),
4710                         "vmovq\t{$src, $dst|$dst, $src}",
4711                         [(set FR64:$dst, (bitconvert (loadi64 addr:$src)))]>,
4712                         VEX;
4713 def VMOVSDto64rr : VRPDI<0x7E, MRMDestReg, (outs GR64:$dst), (ins FR64:$src),
4714                          "mov{d|q}\t{$src, $dst|$dst, $src}",
4715                          [(set GR64:$dst, (bitconvert FR64:$src))]>, VEX;
4716 def VMOVSDto64mr : VRPDI<0x7E, MRMDestMem, (outs), (ins i64mem:$dst, FR64:$src),
4717                          "movq\t{$src, $dst|$dst, $src}",
4718                          [(store (i64 (bitconvert FR64:$src)), addr:$dst)]>,
4719                          VEX;
4720
4721 def MOV64toSDrm : S3SI<0x7E, MRMSrcMem, (outs FR64:$dst), (ins i64mem:$src),
4722                        "movq\t{$src, $dst|$dst, $src}",
4723                        [(set FR64:$dst, (bitconvert (loadi64 addr:$src)))]>;
4724 def MOVSDto64rr : RPDI<0x7E, MRMDestReg, (outs GR64:$dst), (ins FR64:$src),
4725                        "mov{d|q}\t{$src, $dst|$dst, $src}",
4726                        [(set GR64:$dst, (bitconvert FR64:$src))]>;
4727 def MOVSDto64mr : RPDI<0x7E, MRMDestMem, (outs), (ins i64mem:$dst, FR64:$src),
4728                        "movq\t{$src, $dst|$dst, $src}",
4729                        [(store (i64 (bitconvert FR64:$src)), addr:$dst)]>;
4730
4731 //===---------------------------------------------------------------------===//
4732 // Move Scalar Single to Double Int
4733 //
4734 def VMOVSS2DIrr  : VPDI<0x7E, MRMDestReg, (outs GR32:$dst), (ins FR32:$src),
4735                       "movd\t{$src, $dst|$dst, $src}",
4736                       [(set GR32:$dst, (bitconvert FR32:$src))]>, VEX;
4737 def VMOVSS2DImr  : VPDI<0x7E, MRMDestMem, (outs), (ins i32mem:$dst, FR32:$src),
4738                       "movd\t{$src, $dst|$dst, $src}",
4739                       [(store (i32 (bitconvert FR32:$src)), addr:$dst)]>, VEX;
4740 def MOVSS2DIrr  : PDI<0x7E, MRMDestReg, (outs GR32:$dst), (ins FR32:$src),
4741                       "movd\t{$src, $dst|$dst, $src}",
4742                       [(set GR32:$dst, (bitconvert FR32:$src))]>;
4743 def MOVSS2DImr  : PDI<0x7E, MRMDestMem, (outs), (ins i32mem:$dst, FR32:$src),
4744                       "movd\t{$src, $dst|$dst, $src}",
4745                       [(store (i32 (bitconvert FR32:$src)), addr:$dst)]>;
4746
4747 //===---------------------------------------------------------------------===//
4748 // Patterns and instructions to describe movd/movq to XMM register zero-extends
4749 //
4750 let AddedComplexity = 15 in {
4751 def VMOVZDI2PDIrr : VPDI<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR32:$src),
4752                        "movd\t{$src, $dst|$dst, $src}",
4753                        [(set VR128:$dst, (v4i32 (X86vzmovl
4754                                       (v4i32 (scalar_to_vector GR32:$src)))))]>,
4755                                       VEX;
4756 def VMOVZQI2PQIrr : VPDI<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR64:$src),
4757                        "mov{d|q}\t{$src, $dst|$dst, $src}", // X86-64 only
4758                        [(set VR128:$dst, (v2i64 (X86vzmovl
4759                                       (v2i64 (scalar_to_vector GR64:$src)))))]>,
4760                                       VEX, VEX_W;
4761 }
4762 let AddedComplexity = 15 in {
4763 def MOVZDI2PDIrr : PDI<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR32:$src),
4764                        "movd\t{$src, $dst|$dst, $src}",
4765                        [(set VR128:$dst, (v4i32 (X86vzmovl
4766                                       (v4i32 (scalar_to_vector GR32:$src)))))]>;
4767 def MOVZQI2PQIrr : RPDI<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR64:$src),
4768                        "mov{d|q}\t{$src, $dst|$dst, $src}", // X86-64 only
4769                        [(set VR128:$dst, (v2i64 (X86vzmovl
4770                                       (v2i64 (scalar_to_vector GR64:$src)))))]>;
4771 }
4772
4773 let AddedComplexity = 20 in {
4774 def VMOVZDI2PDIrm : VPDI<0x6E, MRMSrcMem, (outs VR128:$dst), (ins i32mem:$src),
4775                        "movd\t{$src, $dst|$dst, $src}",
4776                        [(set VR128:$dst,
4777                          (v4i32 (X86vzmovl (v4i32 (scalar_to_vector
4778                                                    (loadi32 addr:$src))))))]>,
4779                                                    VEX;
4780 def MOVZDI2PDIrm : PDI<0x6E, MRMSrcMem, (outs VR128:$dst), (ins i32mem:$src),
4781                        "movd\t{$src, $dst|$dst, $src}",
4782                        [(set VR128:$dst,
4783                          (v4i32 (X86vzmovl (v4i32 (scalar_to_vector
4784                                                    (loadi32 addr:$src))))))]>;
4785 }
4786
4787 let Predicates = [HasAVX] in {
4788   // AVX 128-bit movd/movq instruction write zeros in the high 128-bit part.
4789   let AddedComplexity = 20 in {
4790     def : Pat<(v4i32 (X86vzmovl (bc_v4i32 (loadv4f32 addr:$src)))),
4791               (VMOVZDI2PDIrm addr:$src)>;
4792     def : Pat<(v4i32 (X86vzmovl (bc_v4i32 (loadv2i64 addr:$src)))),
4793               (VMOVZDI2PDIrm addr:$src)>;
4794   }
4795   // Use regular 128-bit instructions to match 256-bit scalar_to_vec+zext.
4796   def : Pat<(v8i32 (X86vzmovl (insert_subvector undef,
4797                                 (v4i32 (scalar_to_vector GR32:$src)),(i32 0)))),
4798             (SUBREG_TO_REG (i32 0), (VMOVZDI2PDIrr GR32:$src), sub_xmm)>;
4799   def : Pat<(v4i64 (X86vzmovl (insert_subvector undef,
4800                                 (v2i64 (scalar_to_vector GR64:$src)),(i32 0)))),
4801             (SUBREG_TO_REG (i64 0), (VMOVZQI2PQIrr GR64:$src), sub_xmm)>;
4802 }
4803
4804 let Predicates = [HasSSE2], AddedComplexity = 20 in {
4805   def : Pat<(v4i32 (X86vzmovl (bc_v4i32 (loadv4f32 addr:$src)))),
4806             (MOVZDI2PDIrm addr:$src)>;
4807   def : Pat<(v4i32 (X86vzmovl (bc_v4i32 (loadv2i64 addr:$src)))),
4808             (MOVZDI2PDIrm addr:$src)>;
4809 }
4810
4811 // These are the correct encodings of the instructions so that we know how to
4812 // read correct assembly, even though we continue to emit the wrong ones for
4813 // compatibility with Darwin's buggy assembler.
4814 def : InstAlias<"movq\t{$src, $dst|$dst, $src}",
4815                 (MOV64toPQIrr VR128:$dst, GR64:$src), 0>;
4816 def : InstAlias<"movq\t{$src, $dst|$dst, $src}",
4817                 (MOV64toSDrr FR64:$dst, GR64:$src), 0>;
4818 def : InstAlias<"movq\t{$src, $dst|$dst, $src}",
4819                 (MOVPQIto64rr GR64:$dst, VR128:$src), 0>;
4820 def : InstAlias<"movq\t{$src, $dst|$dst, $src}",
4821                 (MOVSDto64rr GR64:$dst, FR64:$src), 0>;
4822 def : InstAlias<"movq\t{$src, $dst|$dst, $src}",
4823                 (VMOVZQI2PQIrr VR128:$dst, GR64:$src), 0>;
4824 def : InstAlias<"movq\t{$src, $dst|$dst, $src}",
4825                 (MOVZQI2PQIrr VR128:$dst, GR64:$src), 0>;
4826
4827 //===---------------------------------------------------------------------===//
4828 // SSE2 - Move Quadword
4829 //===---------------------------------------------------------------------===//
4830
4831 //===---------------------------------------------------------------------===//
4832 // Move Quadword Int to Packed Quadword Int
4833 //
4834 def VMOVQI2PQIrm : I<0x7E, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
4835                     "vmovq\t{$src, $dst|$dst, $src}",
4836                     [(set VR128:$dst,
4837                       (v2i64 (scalar_to_vector (loadi64 addr:$src))))]>, XS,
4838                     VEX, Requires<[HasAVX]>;
4839 def MOVQI2PQIrm : I<0x7E, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
4840                     "movq\t{$src, $dst|$dst, $src}",
4841                     [(set VR128:$dst,
4842                       (v2i64 (scalar_to_vector (loadi64 addr:$src))))]>, XS,
4843                     Requires<[HasSSE2]>; // SSE2 instruction with XS Prefix
4844
4845 //===---------------------------------------------------------------------===//
4846 // Move Packed Quadword Int to Quadword Int
4847 //
4848 def VMOVPQI2QImr : VPDI<0xD6, MRMDestMem, (outs), (ins i64mem:$dst, VR128:$src),
4849                       "movq\t{$src, $dst|$dst, $src}",
4850                       [(store (i64 (vector_extract (v2i64 VR128:$src),
4851                                     (iPTR 0))), addr:$dst)]>, VEX;
4852 def MOVPQI2QImr : PDI<0xD6, MRMDestMem, (outs), (ins i64mem:$dst, VR128:$src),
4853                       "movq\t{$src, $dst|$dst, $src}",
4854                       [(store (i64 (vector_extract (v2i64 VR128:$src),
4855                                     (iPTR 0))), addr:$dst)]>;
4856
4857 //===---------------------------------------------------------------------===//
4858 // Store / copy lower 64-bits of a XMM register.
4859 //
4860 def VMOVLQ128mr : VPDI<0xD6, MRMDestMem, (outs), (ins i64mem:$dst, VR128:$src),
4861                      "movq\t{$src, $dst|$dst, $src}",
4862                      [(int_x86_sse2_storel_dq addr:$dst, VR128:$src)]>, VEX;
4863 def MOVLQ128mr : PDI<0xD6, MRMDestMem, (outs), (ins i64mem:$dst, VR128:$src),
4864                      "movq\t{$src, $dst|$dst, $src}",
4865                      [(int_x86_sse2_storel_dq addr:$dst, VR128:$src)]>;
4866
4867 let AddedComplexity = 20 in
4868 def VMOVZQI2PQIrm : I<0x7E, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
4869                      "vmovq\t{$src, $dst|$dst, $src}",
4870                      [(set VR128:$dst,
4871                        (v2i64 (X86vzmovl (v2i64 (scalar_to_vector
4872                                                  (loadi64 addr:$src))))))]>,
4873                      XS, VEX, Requires<[HasAVX]>;
4874
4875 let AddedComplexity = 20 in
4876 def MOVZQI2PQIrm : I<0x7E, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
4877                      "movq\t{$src, $dst|$dst, $src}",
4878                      [(set VR128:$dst,
4879                        (v2i64 (X86vzmovl (v2i64 (scalar_to_vector
4880                                                  (loadi64 addr:$src))))))]>,
4881                      XS, Requires<[HasSSE2]>;
4882
4883 let Predicates = [HasAVX], AddedComplexity = 20 in {
4884   def : Pat<(v2i64 (X86vzmovl (loadv2i64 addr:$src))),
4885             (VMOVZQI2PQIrm addr:$src)>;
4886   def : Pat<(v2i64 (X86vzmovl (bc_v2i64 (loadv4f32 addr:$src)))),
4887             (VMOVZQI2PQIrm addr:$src)>;
4888   def : Pat<(v2i64 (X86vzload addr:$src)),
4889             (VMOVZQI2PQIrm addr:$src)>;
4890 }
4891
4892 let Predicates = [HasSSE2], AddedComplexity = 20 in {
4893   def : Pat<(v2i64 (X86vzmovl (loadv2i64 addr:$src))),
4894             (MOVZQI2PQIrm addr:$src)>;
4895   def : Pat<(v2i64 (X86vzmovl (bc_v2i64 (loadv4f32 addr:$src)))),
4896             (MOVZQI2PQIrm addr:$src)>;
4897   def : Pat<(v2i64 (X86vzload addr:$src)), (MOVZQI2PQIrm addr:$src)>;
4898 }
4899
4900 let Predicates = [HasAVX] in {
4901 def : Pat<(v4i64 (X86vzload addr:$src)),
4902           (SUBREG_TO_REG (i32 0), (VMOVAPSrm addr:$src), sub_xmm)>;
4903 }
4904
4905 //===---------------------------------------------------------------------===//
4906 // Moving from XMM to XMM and clear upper 64 bits. Note, there is a bug in
4907 // IA32 document. movq xmm1, xmm2 does clear the high bits.
4908 //
4909 let AddedComplexity = 15 in
4910 def VMOVZPQILo2PQIrr : I<0x7E, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
4911                         "vmovq\t{$src, $dst|$dst, $src}",
4912                     [(set VR128:$dst, (v2i64 (X86vzmovl (v2i64 VR128:$src))))]>,
4913                       XS, VEX, Requires<[HasAVX]>;
4914 let AddedComplexity = 15 in
4915 def MOVZPQILo2PQIrr : I<0x7E, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
4916                         "movq\t{$src, $dst|$dst, $src}",
4917                     [(set VR128:$dst, (v2i64 (X86vzmovl (v2i64 VR128:$src))))]>,
4918                       XS, Requires<[HasSSE2]>;
4919
4920 let AddedComplexity = 20 in
4921 def VMOVZPQILo2PQIrm : I<0x7E, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
4922                         "vmovq\t{$src, $dst|$dst, $src}",
4923                     [(set VR128:$dst, (v2i64 (X86vzmovl
4924                                              (loadv2i64 addr:$src))))]>,
4925                       XS, VEX, Requires<[HasAVX]>;
4926 let AddedComplexity = 20 in {
4927 def MOVZPQILo2PQIrm : I<0x7E, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
4928                         "movq\t{$src, $dst|$dst, $src}",
4929                     [(set VR128:$dst, (v2i64 (X86vzmovl
4930                                              (loadv2i64 addr:$src))))]>,
4931                       XS, Requires<[HasSSE2]>;
4932 }
4933
4934 let AddedComplexity = 20 in {
4935   let Predicates = [HasAVX] in {
4936     def : Pat<(v2i64 (X86vzmovl (loadv2i64 addr:$src))),
4937               (VMOVZPQILo2PQIrm addr:$src)>;
4938     def : Pat<(v2f64 (X86vzmovl (v2f64 VR128:$src))),
4939               (VMOVZPQILo2PQIrr VR128:$src)>;
4940   }
4941   let Predicates = [HasSSE2] in {
4942     def : Pat<(v2i64 (X86vzmovl (loadv2i64 addr:$src))),
4943               (MOVZPQILo2PQIrm addr:$src)>;
4944     def : Pat<(v2f64 (X86vzmovl (v2f64 VR128:$src))),
4945               (MOVZPQILo2PQIrr VR128:$src)>;
4946   }
4947 }
4948
4949 // Instructions to match in the assembler
4950 def VMOVQs64rr : VPDI<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR64:$src),
4951                       "movq\t{$src, $dst|$dst, $src}", []>, VEX, VEX_W;
4952 def VMOVQd64rr : VPDI<0x7E, MRMDestReg, (outs GR64:$dst), (ins VR128:$src),
4953                       "movq\t{$src, $dst|$dst, $src}", []>, VEX, VEX_W;
4954 // Recognize "movd" with GR64 destination, but encode as a "movq"
4955 def VMOVQd64rr_alt : VPDI<0x7E, MRMDestReg, (outs GR64:$dst), (ins VR128:$src),
4956                           "movd\t{$src, $dst|$dst, $src}", []>, VEX, VEX_W;
4957
4958 // Instructions for the disassembler
4959 // xr = XMM register
4960 // xm = mem64
4961
4962 let Predicates = [HasAVX] in
4963 def VMOVQxrxr: I<0x7E, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
4964                  "vmovq\t{$src, $dst|$dst, $src}", []>, VEX, XS;
4965 def MOVQxrxr : I<0x7E, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
4966                  "movq\t{$src, $dst|$dst, $src}", []>, XS;
4967
4968 //===---------------------------------------------------------------------===//
4969 // SSE3 - Conversion Instructions
4970 //===---------------------------------------------------------------------===//
4971
4972 // Convert Packed Double FP to Packed DW Integers
4973 let Predicates = [HasAVX] in {
4974 // The assembler can recognize rr 256-bit instructions by seeing a ymm
4975 // register, but the same isn't true when using memory operands instead.
4976 // Provide other assembly rr and rm forms to address this explicitly.
4977 def VCVTPD2DQrr  : S3DI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
4978                        "vcvtpd2dq\t{$src, $dst|$dst, $src}", []>, VEX;
4979 def VCVTPD2DQXrYr  : S3DI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR256:$src),
4980                        "vcvtpd2dq\t{$src, $dst|$dst, $src}", []>, VEX;
4981
4982 // XMM only
4983 def VCVTPD2DQXrr : S3DI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
4984                       "vcvtpd2dqx\t{$src, $dst|$dst, $src}", []>, VEX;
4985 def VCVTPD2DQXrm : S3DI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
4986                       "vcvtpd2dqx\t{$src, $dst|$dst, $src}", []>, VEX;
4987
4988 // YMM only
4989 def VCVTPD2DQYrr : S3DI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR256:$src),
4990                       "vcvtpd2dqy\t{$src, $dst|$dst, $src}", []>, VEX;
4991 def VCVTPD2DQYrm : S3DI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f256mem:$src),
4992                       "vcvtpd2dqy\t{$src, $dst|$dst, $src}", []>, VEX, VEX_L;
4993 }
4994
4995 def CVTPD2DQrm  : S3DI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
4996                        "cvtpd2dq\t{$src, $dst|$dst, $src}", []>;
4997 def CVTPD2DQrr  : S3DI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
4998                        "cvtpd2dq\t{$src, $dst|$dst, $src}", []>;
4999
5000 def : Pat<(v4i32 (fp_to_sint (v4f64 VR256:$src))),
5001           (VCVTPD2DQYrr VR256:$src)>;
5002 def : Pat<(v4i32 (fp_to_sint (memopv4f64 addr:$src))),
5003           (VCVTPD2DQYrm addr:$src)>;
5004
5005 // Convert Packed DW Integers to Packed Double FP
5006 let Predicates = [HasAVX] in {
5007 def VCVTDQ2PDrm  : S3SI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
5008                      "vcvtdq2pd\t{$src, $dst|$dst, $src}", []>, VEX;
5009 def VCVTDQ2PDrr  : S3SI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
5010                      "vcvtdq2pd\t{$src, $dst|$dst, $src}", []>, VEX;
5011 def VCVTDQ2PDYrm  : S3SI<0xE6, MRMSrcMem, (outs VR256:$dst), (ins f128mem:$src),
5012                      "vcvtdq2pd\t{$src, $dst|$dst, $src}", []>, VEX;
5013 def VCVTDQ2PDYrr  : S3SI<0xE6, MRMSrcReg, (outs VR256:$dst), (ins VR128:$src),
5014                      "vcvtdq2pd\t{$src, $dst|$dst, $src}", []>, VEX;
5015 }
5016
5017 def CVTDQ2PDrm  : S3SI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
5018                        "cvtdq2pd\t{$src, $dst|$dst, $src}", []>;
5019 def CVTDQ2PDrr  : S3SI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
5020                        "cvtdq2pd\t{$src, $dst|$dst, $src}", []>;
5021
5022 // AVX 256-bit register conversion intrinsics
5023 def : Pat<(int_x86_avx_cvtdq2_pd_256 VR128:$src),
5024            (VCVTDQ2PDYrr VR128:$src)>;
5025 def : Pat<(int_x86_avx_cvtdq2_pd_256 (bitconvert (memopv2i64 addr:$src))),
5026            (VCVTDQ2PDYrm addr:$src)>;
5027
5028 def : Pat<(int_x86_avx_cvt_pd2dq_256 VR256:$src),
5029           (VCVTPD2DQYrr VR256:$src)>;
5030 def : Pat<(int_x86_avx_cvt_pd2dq_256 (memopv4f64 addr:$src)),
5031           (VCVTPD2DQYrm addr:$src)>;
5032
5033 def : Pat<(v4f64 (sint_to_fp (v4i32 VR128:$src))),
5034           (VCVTDQ2PDYrr VR128:$src)>;
5035 def : Pat<(v4f64 (sint_to_fp (bc_v4i32 (memopv2i64 addr:$src)))),
5036           (VCVTDQ2PDYrm addr:$src)>;
5037
5038 //===---------------------------------------------------------------------===//
5039 // SSE3 - Replicate Single FP - MOVSHDUP and MOVSLDUP
5040 //===---------------------------------------------------------------------===//
5041 multiclass sse3_replicate_sfp<bits<8> op, SDNode OpNode, string OpcodeStr,
5042                               ValueType vt, RegisterClass RC, PatFrag mem_frag,
5043                               X86MemOperand x86memop> {
5044 def rr : S3SI<op, MRMSrcReg, (outs RC:$dst), (ins RC:$src),
5045                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5046                       [(set RC:$dst, (vt (OpNode RC:$src)))]>;
5047 def rm : S3SI<op, MRMSrcMem, (outs RC:$dst), (ins x86memop:$src),
5048                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5049                       [(set RC:$dst, (OpNode (mem_frag addr:$src)))]>;
5050 }
5051
5052 let Predicates = [HasAVX] in {
5053   defm VMOVSHDUP  : sse3_replicate_sfp<0x16, X86Movshdup, "vmovshdup",
5054                                        v4f32, VR128, memopv4f32, f128mem>, VEX;
5055   defm VMOVSLDUP  : sse3_replicate_sfp<0x12, X86Movsldup, "vmovsldup",
5056                                        v4f32, VR128, memopv4f32, f128mem>, VEX;
5057   defm VMOVSHDUPY : sse3_replicate_sfp<0x16, X86Movshdup, "vmovshdup",
5058                                        v8f32, VR256, memopv8f32, f256mem>, VEX;
5059   defm VMOVSLDUPY : sse3_replicate_sfp<0x12, X86Movsldup, "vmovsldup",
5060                                        v8f32, VR256, memopv8f32, f256mem>, VEX;
5061 }
5062 defm MOVSHDUP : sse3_replicate_sfp<0x16, X86Movshdup, "movshdup", v4f32, VR128,
5063                                    memopv4f32, f128mem>;
5064 defm MOVSLDUP : sse3_replicate_sfp<0x12, X86Movsldup, "movsldup", v4f32, VR128,
5065                                    memopv4f32, f128mem>;
5066
5067 let Predicates = [HasAVX] in {
5068   def : Pat<(v4i32 (X86Movshdup VR128:$src)),
5069             (VMOVSHDUPrr VR128:$src)>;
5070   def : Pat<(v4i32 (X86Movshdup (bc_v4i32 (memopv2i64 addr:$src)))),
5071             (VMOVSHDUPrm addr:$src)>;
5072   def : Pat<(v4i32 (X86Movsldup VR128:$src)),
5073             (VMOVSLDUPrr VR128:$src)>;
5074   def : Pat<(v4i32 (X86Movsldup (bc_v4i32 (memopv2i64 addr:$src)))),
5075             (VMOVSLDUPrm addr:$src)>;
5076   def : Pat<(v8i32 (X86Movshdup VR256:$src)),
5077             (VMOVSHDUPYrr VR256:$src)>;
5078   def : Pat<(v8i32 (X86Movshdup (bc_v8i32 (memopv4i64 addr:$src)))),
5079             (VMOVSHDUPYrm addr:$src)>;
5080   def : Pat<(v8i32 (X86Movsldup VR256:$src)),
5081             (VMOVSLDUPYrr VR256:$src)>;
5082   def : Pat<(v8i32 (X86Movsldup (bc_v8i32 (memopv4i64 addr:$src)))),
5083             (VMOVSLDUPYrm addr:$src)>;
5084 }
5085
5086 let Predicates = [HasSSE3] in {
5087   def : Pat<(v4i32 (X86Movshdup VR128:$src)),
5088             (MOVSHDUPrr VR128:$src)>;
5089   def : Pat<(v4i32 (X86Movshdup (bc_v4i32 (memopv2i64 addr:$src)))),
5090             (MOVSHDUPrm addr:$src)>;
5091   def : Pat<(v4i32 (X86Movsldup VR128:$src)),
5092             (MOVSLDUPrr VR128:$src)>;
5093   def : Pat<(v4i32 (X86Movsldup (bc_v4i32 (memopv2i64 addr:$src)))),
5094             (MOVSLDUPrm addr:$src)>;
5095 }
5096
5097 //===---------------------------------------------------------------------===//
5098 // SSE3 - Replicate Double FP - MOVDDUP
5099 //===---------------------------------------------------------------------===//
5100
5101 multiclass sse3_replicate_dfp<string OpcodeStr> {
5102 def rr  : S3DI<0x12, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
5103                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5104                     [(set VR128:$dst,(v2f64 (movddup VR128:$src, (undef))))]>;
5105 def rm  : S3DI<0x12, MRMSrcMem, (outs VR128:$dst), (ins f64mem:$src),
5106                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5107                     [(set VR128:$dst,
5108                       (v2f64 (movddup (scalar_to_vector (loadf64 addr:$src)),
5109                                       (undef))))]>;
5110 }
5111
5112 // FIXME: Merge with above classe when there're patterns for the ymm version
5113 multiclass sse3_replicate_dfp_y<string OpcodeStr> {
5114 let Predicates = [HasAVX] in {
5115   def rr  : S3DI<0x12, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
5116                       !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5117                       []>;
5118   def rm  : S3DI<0x12, MRMSrcMem, (outs VR256:$dst), (ins f256mem:$src),
5119                       !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5120                       []>;
5121   }
5122 }
5123
5124 defm MOVDDUP : sse3_replicate_dfp<"movddup">;
5125 defm VMOVDDUP  : sse3_replicate_dfp<"vmovddup">, VEX;
5126 defm VMOVDDUPY : sse3_replicate_dfp_y<"vmovddup">, VEX;
5127
5128 let Predicates = [HasAVX] in {
5129   def : Pat<(movddup (bc_v2f64 (v2i64 (scalar_to_vector (loadi64 addr:$src)))),
5130                    (undef)),
5131             (VMOVDDUPrm addr:$src)>;
5132   let AddedComplexity = 5 in {
5133   def : Pat<(movddup (memopv2f64 addr:$src), (undef)), (VMOVDDUPrm addr:$src)>;
5134   def : Pat<(movddup (bc_v4f32 (memopv2f64 addr:$src)), (undef)),
5135             (VMOVDDUPrm addr:$src)>;
5136   def : Pat<(movddup (memopv2i64 addr:$src), (undef)), (VMOVDDUPrm addr:$src)>;
5137   def : Pat<(movddup (bc_v4i32 (memopv2i64 addr:$src)), (undef)),
5138             (VMOVDDUPrm addr:$src)>;
5139   }
5140   def : Pat<(X86Movddup (memopv2f64 addr:$src)),
5141             (VMOVDDUPrm addr:$src)>, Requires<[HasAVX]>;
5142   def : Pat<(X86Movddup (bc_v2f64 (memopv4f32 addr:$src))),
5143             (VMOVDDUPrm addr:$src)>, Requires<[HasAVX]>;
5144   def : Pat<(X86Movddup (bc_v2f64 (memopv2i64 addr:$src))),
5145             (VMOVDDUPrm addr:$src)>, Requires<[HasAVX]>;
5146   def : Pat<(X86Movddup (v2f64 (scalar_to_vector (loadf64 addr:$src)))),
5147             (VMOVDDUPrm addr:$src)>, Requires<[HasAVX]>;
5148   def : Pat<(X86Movddup (bc_v2f64
5149                              (v2i64 (scalar_to_vector (loadi64 addr:$src))))),
5150             (VMOVDDUPrm addr:$src)>, Requires<[HasAVX]>;
5151
5152   // 256-bit version
5153   def : Pat<(X86Movddup (memopv4f64 addr:$src)),
5154             (VMOVDDUPYrm addr:$src)>;
5155   def : Pat<(X86Movddup (memopv4i64 addr:$src)),
5156             (VMOVDDUPYrm addr:$src)>;
5157   def : Pat<(X86Movddup (v4f64 (scalar_to_vector (loadf64 addr:$src)))),
5158             (VMOVDDUPYrm addr:$src)>;
5159   def : Pat<(X86Movddup (v4i64 (scalar_to_vector (loadi64 addr:$src)))),
5160             (VMOVDDUPYrm addr:$src)>;
5161   def : Pat<(X86Movddup (v4f64 VR256:$src)),
5162             (VMOVDDUPYrr VR256:$src)>;
5163   def : Pat<(X86Movddup (v4i64 VR256:$src)),
5164             (VMOVDDUPYrr VR256:$src)>;
5165 }
5166
5167 let Predicates = [HasSSE3] in {
5168   def : Pat<(movddup (bc_v2f64 (v2i64 (scalar_to_vector (loadi64 addr:$src)))),
5169                    (undef)),
5170             (MOVDDUPrm addr:$src)>;
5171   let AddedComplexity = 5 in {
5172   def : Pat<(movddup (memopv2f64 addr:$src), (undef)), (MOVDDUPrm addr:$src)>;
5173   def : Pat<(movddup (bc_v4f32 (memopv2f64 addr:$src)), (undef)),
5174             (MOVDDUPrm addr:$src)>;
5175   def : Pat<(movddup (memopv2i64 addr:$src), (undef)), (MOVDDUPrm addr:$src)>;
5176   def : Pat<(movddup (bc_v4i32 (memopv2i64 addr:$src)), (undef)),
5177             (MOVDDUPrm addr:$src)>;
5178   }
5179   def : Pat<(X86Movddup (memopv2f64 addr:$src)),
5180             (MOVDDUPrm addr:$src)>;
5181   def : Pat<(X86Movddup (bc_v2f64 (memopv4f32 addr:$src))),
5182             (MOVDDUPrm addr:$src)>;
5183   def : Pat<(X86Movddup (bc_v2f64 (memopv2i64 addr:$src))),
5184             (MOVDDUPrm addr:$src)>;
5185   def : Pat<(X86Movddup (v2f64 (scalar_to_vector (loadf64 addr:$src)))),
5186             (MOVDDUPrm addr:$src)>;
5187   def : Pat<(X86Movddup (bc_v2f64
5188                              (v2i64 (scalar_to_vector (loadi64 addr:$src))))),
5189             (MOVDDUPrm addr:$src)>;
5190 }
5191
5192 //===---------------------------------------------------------------------===//
5193 // SSE3 - Move Unaligned Integer
5194 //===---------------------------------------------------------------------===//
5195
5196 let Predicates = [HasAVX] in {
5197   def VLDDQUrm : S3DI<0xF0, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
5198                    "vlddqu\t{$src, $dst|$dst, $src}",
5199                    [(set VR128:$dst, (int_x86_sse3_ldu_dq addr:$src))]>, VEX;
5200   def VLDDQUYrm : S3DI<0xF0, MRMSrcMem, (outs VR256:$dst), (ins i256mem:$src),
5201                    "vlddqu\t{$src, $dst|$dst, $src}",
5202                    [(set VR256:$dst, (int_x86_avx_ldu_dq_256 addr:$src))]>, VEX;
5203 }
5204 def LDDQUrm : S3DI<0xF0, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
5205                    "lddqu\t{$src, $dst|$dst, $src}",
5206                    [(set VR128:$dst, (int_x86_sse3_ldu_dq addr:$src))]>;
5207
5208 //===---------------------------------------------------------------------===//
5209 // SSE3 - Arithmetic
5210 //===---------------------------------------------------------------------===//
5211
5212 multiclass sse3_addsub<Intrinsic Int, string OpcodeStr, RegisterClass RC,
5213                        X86MemOperand x86memop, bit Is2Addr = 1> {
5214   def rr : I<0xD0, MRMSrcReg,
5215        (outs RC:$dst), (ins RC:$src1, RC:$src2),
5216        !if(Is2Addr,
5217            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5218            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5219        [(set RC:$dst, (Int RC:$src1, RC:$src2))]>;
5220   def rm : I<0xD0, MRMSrcMem,
5221        (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
5222        !if(Is2Addr,
5223            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5224            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5225        [(set RC:$dst, (Int RC:$src1, (memop addr:$src2)))]>;
5226 }
5227
5228 let Predicates = [HasAVX] in {
5229   let ExeDomain = SSEPackedSingle in {
5230     defm VADDSUBPS : sse3_addsub<int_x86_sse3_addsub_ps, "vaddsubps", VR128,
5231                                  f128mem, 0>, TB, XD, VEX_4V;
5232     defm VADDSUBPSY : sse3_addsub<int_x86_avx_addsub_ps_256, "vaddsubps", VR256,
5233                                  f256mem, 0>, TB, XD, VEX_4V;
5234   }
5235   let ExeDomain = SSEPackedDouble in {
5236     defm VADDSUBPD : sse3_addsub<int_x86_sse3_addsub_pd, "vaddsubpd", VR128,
5237                                  f128mem, 0>, TB, OpSize, VEX_4V;
5238     defm VADDSUBPDY : sse3_addsub<int_x86_avx_addsub_pd_256, "vaddsubpd", VR256,
5239                                  f256mem, 0>, TB, OpSize, VEX_4V;
5240   }
5241 }
5242 let Constraints = "$src1 = $dst", Predicates = [HasSSE3] in {
5243   let ExeDomain = SSEPackedSingle in
5244   defm ADDSUBPS : sse3_addsub<int_x86_sse3_addsub_ps, "addsubps", VR128,
5245                               f128mem>, TB, XD;
5246   let ExeDomain = SSEPackedDouble in
5247   defm ADDSUBPD : sse3_addsub<int_x86_sse3_addsub_pd, "addsubpd", VR128,
5248                               f128mem>, TB, OpSize;
5249 }
5250
5251 //===---------------------------------------------------------------------===//
5252 // SSE3 Instructions
5253 //===---------------------------------------------------------------------===//
5254
5255 // Horizontal ops
5256 multiclass S3D_Int<bits<8> o, string OpcodeStr, ValueType vt, RegisterClass RC,
5257                    X86MemOperand x86memop, SDNode OpNode, bit Is2Addr = 1> {
5258   def rr : S3DI<o, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
5259        !if(Is2Addr,
5260          !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5261          !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5262       [(set RC:$dst, (vt (OpNode RC:$src1, RC:$src2)))]>;
5263
5264   def rm : S3DI<o, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
5265        !if(Is2Addr,
5266          !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5267          !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5268       [(set RC:$dst, (vt (OpNode RC:$src1, (memop addr:$src2))))]>;
5269 }
5270 multiclass S3_Int<bits<8> o, string OpcodeStr, ValueType vt, RegisterClass RC,
5271                   X86MemOperand x86memop, SDNode OpNode, bit Is2Addr = 1> {
5272   def rr : S3I<o, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
5273        !if(Is2Addr,
5274          !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5275          !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5276       [(set RC:$dst, (vt (OpNode RC:$src1, RC:$src2)))]>;
5277
5278   def rm : S3I<o, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
5279        !if(Is2Addr,
5280          !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5281          !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5282       [(set RC:$dst, (vt (OpNode RC:$src1, (memop addr:$src2))))]>;
5283 }
5284
5285 let Predicates = [HasAVX] in {
5286   let ExeDomain = SSEPackedSingle in {
5287     defm VHADDPS  : S3D_Int<0x7C, "vhaddps", v4f32, VR128, f128mem,
5288                             X86fhadd, 0>, VEX_4V;
5289     defm VHSUBPS  : S3D_Int<0x7D, "vhsubps", v4f32, VR128, f128mem,
5290                             X86fhsub, 0>, VEX_4V;
5291     defm VHADDPSY : S3D_Int<0x7C, "vhaddps", v8f32, VR256, f256mem,
5292                             X86fhadd, 0>, VEX_4V;
5293     defm VHSUBPSY : S3D_Int<0x7D, "vhsubps", v8f32, VR256, f256mem,
5294                             X86fhsub, 0>, VEX_4V;
5295   }
5296   let ExeDomain = SSEPackedDouble in {
5297     defm VHADDPD  : S3_Int <0x7C, "vhaddpd", v2f64, VR128, f128mem,
5298                             X86fhadd, 0>, VEX_4V;
5299     defm VHSUBPD  : S3_Int <0x7D, "vhsubpd", v2f64, VR128, f128mem,
5300                             X86fhsub, 0>, VEX_4V;
5301     defm VHADDPDY : S3_Int <0x7C, "vhaddpd", v4f64, VR256, f256mem,
5302                             X86fhadd, 0>, VEX_4V;
5303     defm VHSUBPDY : S3_Int <0x7D, "vhsubpd", v4f64, VR256, f256mem,
5304                             X86fhsub, 0>, VEX_4V;
5305   }
5306 }
5307
5308 let Constraints = "$src1 = $dst" in {
5309   let ExeDomain = SSEPackedSingle in {
5310     defm HADDPS : S3D_Int<0x7C, "haddps", v4f32, VR128, f128mem, X86fhadd>;
5311     defm HSUBPS : S3D_Int<0x7D, "hsubps", v4f32, VR128, f128mem, X86fhsub>;
5312   }
5313   let ExeDomain = SSEPackedDouble in {
5314     defm HADDPD : S3_Int<0x7C, "haddpd", v2f64, VR128, f128mem, X86fhadd>;
5315     defm HSUBPD : S3_Int<0x7D, "hsubpd", v2f64, VR128, f128mem, X86fhsub>;
5316   }
5317 }
5318
5319 //===---------------------------------------------------------------------===//
5320 // SSSE3 - Packed Absolute Instructions
5321 //===---------------------------------------------------------------------===//
5322
5323
5324 /// SS3I_unop_rm_int - Simple SSSE3 unary op whose type can be v*{i8,i16,i32}.
5325 multiclass SS3I_unop_rm_int<bits<8> opc, string OpcodeStr,
5326                             Intrinsic IntId128> {
5327   def rr128 : SS38I<opc, MRMSrcReg, (outs VR128:$dst),
5328                     (ins VR128:$src),
5329                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5330                     [(set VR128:$dst, (IntId128 VR128:$src))]>,
5331                     OpSize;
5332
5333   def rm128 : SS38I<opc, MRMSrcMem, (outs VR128:$dst),
5334                     (ins i128mem:$src),
5335                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5336                     [(set VR128:$dst,
5337                       (IntId128
5338                        (bitconvert (memopv2i64 addr:$src))))]>, OpSize;
5339 }
5340
5341 /// SS3I_unop_rm_int_y - Simple SSSE3 unary op whose type can be v*{i8,i16,i32}.
5342 multiclass SS3I_unop_rm_int_y<bits<8> opc, string OpcodeStr,
5343                               Intrinsic IntId256> {
5344   def rr256 : SS38I<opc, MRMSrcReg, (outs VR256:$dst),
5345                     (ins VR256:$src),
5346                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5347                     [(set VR256:$dst, (IntId256 VR256:$src))]>,
5348                     OpSize;
5349
5350   def rm256 : SS38I<opc, MRMSrcMem, (outs VR256:$dst),
5351                     (ins i256mem:$src),
5352                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5353                     [(set VR256:$dst,
5354                       (IntId256
5355                        (bitconvert (memopv4i64 addr:$src))))]>, OpSize;
5356 }
5357
5358 let Predicates = [HasAVX] in {
5359   defm VPABSB  : SS3I_unop_rm_int<0x1C, "vpabsb",
5360                                   int_x86_ssse3_pabs_b_128>, VEX;
5361   defm VPABSW  : SS3I_unop_rm_int<0x1D, "vpabsw",
5362                                   int_x86_ssse3_pabs_w_128>, VEX;
5363   defm VPABSD  : SS3I_unop_rm_int<0x1E, "vpabsd",
5364                                   int_x86_ssse3_pabs_d_128>, VEX;
5365 }
5366
5367 let Predicates = [HasAVX2] in {
5368   defm VPABSB  : SS3I_unop_rm_int_y<0x1C, "vpabsb",
5369                                     int_x86_avx2_pabs_b>, VEX;
5370   defm VPABSW  : SS3I_unop_rm_int_y<0x1D, "vpabsw",
5371                                     int_x86_avx2_pabs_w>, VEX;
5372   defm VPABSD  : SS3I_unop_rm_int_y<0x1E, "vpabsd",
5373                                     int_x86_avx2_pabs_d>, VEX;
5374 }
5375
5376 defm PABSB : SS3I_unop_rm_int<0x1C, "pabsb",
5377                               int_x86_ssse3_pabs_b_128>;
5378 defm PABSW : SS3I_unop_rm_int<0x1D, "pabsw",
5379                               int_x86_ssse3_pabs_w_128>;
5380 defm PABSD : SS3I_unop_rm_int<0x1E, "pabsd",
5381                               int_x86_ssse3_pabs_d_128>;
5382
5383 //===---------------------------------------------------------------------===//
5384 // SSSE3 - Packed Binary Operator Instructions
5385 //===---------------------------------------------------------------------===//
5386
5387 /// SS3I_binop_rm_int - Simple SSSE3 bin op whose type can be v*{i8,i16,i32}.
5388 multiclass SS3I_binop_rm_int<bits<8> opc, string OpcodeStr,
5389                              Intrinsic IntId128, bit Is2Addr = 1> {
5390   let isCommutable = 1 in
5391   def rr128 : SS38I<opc, MRMSrcReg, (outs VR128:$dst),
5392        (ins VR128:$src1, VR128:$src2),
5393        !if(Is2Addr,
5394          !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5395          !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5396        [(set VR128:$dst, (IntId128 VR128:$src1, VR128:$src2))]>,
5397        OpSize;
5398   def rm128 : SS38I<opc, MRMSrcMem, (outs VR128:$dst),
5399        (ins VR128:$src1, i128mem:$src2),
5400        !if(Is2Addr,
5401          !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5402          !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5403        [(set VR128:$dst,
5404          (IntId128 VR128:$src1,
5405           (bitconvert (memopv2i64 addr:$src2))))]>, OpSize;
5406 }
5407
5408 multiclass SS3I_binop_rm_int_y<bits<8> opc, string OpcodeStr,
5409                                Intrinsic IntId256> {
5410   let isCommutable = 1 in
5411   def rr256 : SS38I<opc, MRMSrcReg, (outs VR256:$dst),
5412        (ins VR256:$src1, VR256:$src2),
5413        !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5414        [(set VR256:$dst, (IntId256 VR256:$src1, VR256:$src2))]>,
5415        OpSize;
5416   def rm256 : SS38I<opc, MRMSrcMem, (outs VR256:$dst),
5417        (ins VR256:$src1, i256mem:$src2),
5418        !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5419        [(set VR256:$dst,
5420          (IntId256 VR256:$src1,
5421           (bitconvert (memopv4i64 addr:$src2))))]>, OpSize;
5422 }
5423
5424 let ImmT = NoImm, Predicates = [HasAVX] in {
5425 let isCommutable = 0 in {
5426   defm VPHADDW    : SS3I_binop_rm_int<0x01, "vphaddw",
5427                                       int_x86_ssse3_phadd_w_128, 0>, VEX_4V;
5428   defm VPHADDD    : SS3I_binop_rm_int<0x02, "vphaddd",
5429                                       int_x86_ssse3_phadd_d_128, 0>, VEX_4V;
5430   defm VPHADDSW   : SS3I_binop_rm_int<0x03, "vphaddsw",
5431                                       int_x86_ssse3_phadd_sw_128, 0>, VEX_4V;
5432   defm VPHSUBW    : SS3I_binop_rm_int<0x05, "vphsubw",
5433                                       int_x86_ssse3_phsub_w_128, 0>, VEX_4V;
5434   defm VPHSUBD    : SS3I_binop_rm_int<0x06, "vphsubd",
5435                                       int_x86_ssse3_phsub_d_128, 0>, VEX_4V;
5436   defm VPHSUBSW   : SS3I_binop_rm_int<0x07, "vphsubsw",
5437                                       int_x86_ssse3_phsub_sw_128, 0>, VEX_4V;
5438   defm VPMADDUBSW : SS3I_binop_rm_int<0x04, "vpmaddubsw",
5439                                       int_x86_ssse3_pmadd_ub_sw_128, 0>, VEX_4V;
5440   defm VPSHUFB    : SS3I_binop_rm_int<0x00, "vpshufb",
5441                                       int_x86_ssse3_pshuf_b_128, 0>, VEX_4V;
5442   defm VPSIGNB    : SS3I_binop_rm_int<0x08, "vpsignb",
5443                                       int_x86_ssse3_psign_b_128, 0>, VEX_4V;
5444   defm VPSIGNW    : SS3I_binop_rm_int<0x09, "vpsignw",
5445                                       int_x86_ssse3_psign_w_128, 0>, VEX_4V;
5446   defm VPSIGND    : SS3I_binop_rm_int<0x0A, "vpsignd",
5447                                       int_x86_ssse3_psign_d_128, 0>, VEX_4V;
5448 }
5449 defm VPMULHRSW    : SS3I_binop_rm_int<0x0B, "vpmulhrsw",
5450                                       int_x86_ssse3_pmul_hr_sw_128, 0>, VEX_4V;
5451 }
5452
5453 let ImmT = NoImm, Predicates = [HasAVX2] in {
5454 let isCommutable = 0 in {
5455   defm VPHADDW    : SS3I_binop_rm_int_y<0x01, "vphaddw",
5456                                         int_x86_avx2_phadd_w>, VEX_4V;
5457   defm VPHADDD    : SS3I_binop_rm_int_y<0x02, "vphaddd",
5458                                         int_x86_avx2_phadd_d>, VEX_4V;
5459   defm VPHADDSW   : SS3I_binop_rm_int_y<0x03, "vphaddsw",
5460                                         int_x86_avx2_phadd_sw>, VEX_4V;
5461   defm VPHSUBW    : SS3I_binop_rm_int_y<0x05, "vphsubw",
5462                                         int_x86_avx2_phsub_w>, VEX_4V;
5463   defm VPHSUBD    : SS3I_binop_rm_int_y<0x06, "vphsubd",
5464                                         int_x86_avx2_phsub_d>, VEX_4V;
5465   defm VPHSUBSW   : SS3I_binop_rm_int_y<0x07, "vphsubsw",
5466                                         int_x86_avx2_phsub_sw>, VEX_4V;
5467   defm VPMADDUBSW : SS3I_binop_rm_int_y<0x04, "vpmaddubsw",
5468                                         int_x86_avx2_pmadd_ub_sw>, VEX_4V;
5469   defm VPSHUFB    : SS3I_binop_rm_int_y<0x00, "vpshufb",
5470                                         int_x86_avx2_pshuf_b>, VEX_4V;
5471   defm VPSIGNB    : SS3I_binop_rm_int_y<0x08, "vpsignb",
5472                                         int_x86_avx2_psign_b>, VEX_4V;
5473   defm VPSIGNW    : SS3I_binop_rm_int_y<0x09, "vpsignw",
5474                                         int_x86_avx2_psign_w>, VEX_4V;
5475   defm VPSIGND    : SS3I_binop_rm_int_y<0x0A, "vpsignd",
5476                                         int_x86_avx2_psign_d>, VEX_4V;
5477 }
5478 defm VPMULHRSW    : SS3I_binop_rm_int_y<0x0B, "vpmulhrsw",
5479                                         int_x86_avx2_pmul_hr_sw>, VEX_4V;
5480 }
5481
5482 // None of these have i8 immediate fields.
5483 let ImmT = NoImm, Constraints = "$src1 = $dst" in {
5484 let isCommutable = 0 in {
5485   defm PHADDW    : SS3I_binop_rm_int<0x01, "phaddw",
5486                                      int_x86_ssse3_phadd_w_128>;
5487   defm PHADDD    : SS3I_binop_rm_int<0x02, "phaddd",
5488                                      int_x86_ssse3_phadd_d_128>;
5489   defm PHADDSW   : SS3I_binop_rm_int<0x03, "phaddsw",
5490                                      int_x86_ssse3_phadd_sw_128>;
5491   defm PHSUBW    : SS3I_binop_rm_int<0x05, "phsubw",
5492                                      int_x86_ssse3_phsub_w_128>;
5493   defm PHSUBD    : SS3I_binop_rm_int<0x06, "phsubd",
5494                                      int_x86_ssse3_phsub_d_128>;
5495   defm PHSUBSW   : SS3I_binop_rm_int<0x07, "phsubsw",
5496                                      int_x86_ssse3_phsub_sw_128>;
5497   defm PMADDUBSW : SS3I_binop_rm_int<0x04, "pmaddubsw",
5498                                      int_x86_ssse3_pmadd_ub_sw_128>;
5499   defm PSHUFB    : SS3I_binop_rm_int<0x00, "pshufb",
5500                                      int_x86_ssse3_pshuf_b_128>;
5501   defm PSIGNB    : SS3I_binop_rm_int<0x08, "psignb",
5502                                      int_x86_ssse3_psign_b_128>;
5503   defm PSIGNW    : SS3I_binop_rm_int<0x09, "psignw",
5504                                      int_x86_ssse3_psign_w_128>;
5505   defm PSIGND    : SS3I_binop_rm_int<0x0A, "psignd",
5506                                        int_x86_ssse3_psign_d_128>;
5507 }
5508 defm PMULHRSW    : SS3I_binop_rm_int<0x0B, "pmulhrsw",
5509                                      int_x86_ssse3_pmul_hr_sw_128>;
5510 }
5511
5512 let Predicates = [HasAVX] in {
5513   def : Pat<(X86pshufb VR128:$src, VR128:$mask),
5514             (VPSHUFBrr128 VR128:$src, VR128:$mask)>;
5515   def : Pat<(X86pshufb VR128:$src, (bc_v16i8 (memopv2i64 addr:$mask))),
5516             (VPSHUFBrm128 VR128:$src, addr:$mask)>;
5517
5518   def : Pat<(v16i8 (X86psign VR128:$src1, VR128:$src2)),
5519             (VPSIGNBrr128 VR128:$src1, VR128:$src2)>;
5520   def : Pat<(v8i16 (X86psign VR128:$src1, VR128:$src2)),
5521             (VPSIGNWrr128 VR128:$src1, VR128:$src2)>;
5522   def : Pat<(v4i32 (X86psign VR128:$src1, VR128:$src2)),
5523             (VPSIGNDrr128 VR128:$src1, VR128:$src2)>;
5524
5525   def : Pat<(v8i16 (X86hadd VR128:$src1, VR128:$src2)),
5526             (VPHADDWrr128 VR128:$src1, VR128:$src2)>;
5527   def : Pat<(v4i32 (X86hadd VR128:$src1, VR128:$src2)),
5528             (VPHADDDrr128 VR128:$src1, VR128:$src2)>;
5529   def : Pat<(v8i16 (X86hsub VR128:$src1, VR128:$src2)),
5530             (VPHSUBWrr128 VR128:$src1, VR128:$src2)>;
5531   def : Pat<(v4i32 (X86hsub VR128:$src1, VR128:$src2)),
5532             (VPHSUBDrr128 VR128:$src1, VR128:$src2)>;
5533 }
5534
5535 let Predicates = [HasAVX2] in {
5536   def : Pat<(v32i8 (X86psign VR256:$src1, VR256:$src2)),
5537             (VPSIGNBrr256 VR256:$src1, VR256:$src2)>;
5538   def : Pat<(v16i16 (X86psign VR256:$src1, VR256:$src2)),
5539             (VPSIGNWrr256 VR256:$src1, VR256:$src2)>;
5540   def : Pat<(v8i32 (X86psign VR256:$src1, VR256:$src2)),
5541             (VPSIGNDrr256 VR256:$src1, VR256:$src2)>;
5542
5543   def : Pat<(v16i16 (X86hadd VR256:$src1, VR256:$src2)),
5544             (VPHADDWrr256 VR256:$src1, VR256:$src2)>;
5545   def : Pat<(v8i32 (X86hadd VR256:$src1, VR256:$src2)),
5546             (VPHADDDrr256 VR256:$src1, VR256:$src2)>;
5547   def : Pat<(v16i16 (X86hsub VR256:$src1, VR256:$src2)),
5548             (VPHSUBWrr256 VR256:$src1, VR256:$src2)>;
5549   def : Pat<(v8i32 (X86hsub VR256:$src1, VR256:$src2)),
5550             (VPHSUBDrr256 VR256:$src1, VR256:$src2)>;
5551 }
5552
5553 let Predicates = [HasSSSE3] in {
5554   def : Pat<(X86pshufb VR128:$src, VR128:$mask),
5555             (PSHUFBrr128 VR128:$src, VR128:$mask)>;
5556   def : Pat<(X86pshufb VR128:$src, (bc_v16i8 (memopv2i64 addr:$mask))),
5557             (PSHUFBrm128 VR128:$src, addr:$mask)>;
5558
5559   def : Pat<(v16i8 (X86psign VR128:$src1, VR128:$src2)),
5560             (PSIGNBrr128 VR128:$src1, VR128:$src2)>;
5561   def : Pat<(v8i16 (X86psign VR128:$src1, VR128:$src2)),
5562             (PSIGNWrr128 VR128:$src1, VR128:$src2)>;
5563   def : Pat<(v4i32 (X86psign VR128:$src1, VR128:$src2)),
5564             (PSIGNDrr128 VR128:$src1, VR128:$src2)>;
5565
5566   def : Pat<(v8i16 (X86hadd VR128:$src1, VR128:$src2)),
5567             (PHADDWrr128 VR128:$src1, VR128:$src2)>;
5568   def : Pat<(v4i32 (X86hadd VR128:$src1, VR128:$src2)),
5569             (PHADDDrr128 VR128:$src1, VR128:$src2)>;
5570   def : Pat<(v8i16 (X86hsub VR128:$src1, VR128:$src2)),
5571             (PHSUBWrr128 VR128:$src1, VR128:$src2)>;
5572   def : Pat<(v4i32 (X86hsub VR128:$src1, VR128:$src2)),
5573             (PHSUBDrr128 VR128:$src1, VR128:$src2)>;
5574 }
5575
5576 //===---------------------------------------------------------------------===//
5577 // SSSE3 - Packed Align Instruction Patterns
5578 //===---------------------------------------------------------------------===//
5579
5580 multiclass ssse3_palign<string asm, bit Is2Addr = 1> {
5581   let neverHasSideEffects = 1 in {
5582   def R128rr : SS3AI<0x0F, MRMSrcReg, (outs VR128:$dst),
5583       (ins VR128:$src1, VR128:$src2, i8imm:$src3),
5584       !if(Is2Addr,
5585         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5586         !strconcat(asm,
5587                   "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5588       []>, OpSize;
5589   let mayLoad = 1 in
5590   def R128rm : SS3AI<0x0F, MRMSrcMem, (outs VR128:$dst),
5591       (ins VR128:$src1, i128mem:$src2, i8imm:$src3),
5592       !if(Is2Addr,
5593         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5594         !strconcat(asm,
5595                   "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5596       []>, OpSize;
5597   }
5598 }
5599
5600 multiclass ssse3_palign_y<string asm, bit Is2Addr = 1> {
5601   let neverHasSideEffects = 1 in {
5602   def R256rr : SS3AI<0x0F, MRMSrcReg, (outs VR256:$dst),
5603       (ins VR256:$src1, VR256:$src2, i8imm:$src3),
5604       !strconcat(asm,
5605                  "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
5606       []>, OpSize;
5607   let mayLoad = 1 in
5608   def R256rm : SS3AI<0x0F, MRMSrcMem, (outs VR256:$dst),
5609       (ins VR256:$src1, i256mem:$src2, i8imm:$src3),
5610       !strconcat(asm,
5611                  "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
5612       []>, OpSize;
5613   }
5614 }
5615
5616 let Predicates = [HasAVX] in
5617   defm VPALIGN : ssse3_palign<"vpalignr", 0>, VEX_4V;
5618 let Predicates = [HasAVX2] in
5619   defm VPALIGN : ssse3_palign_y<"vpalignr", 0>, VEX_4V;
5620 let Constraints = "$src1 = $dst", Predicates = [HasSSSE3] in
5621   defm PALIGN : ssse3_palign<"palignr">;
5622
5623 let Predicates = [HasAVX2] in {
5624 def : Pat<(v8i32 (X86PAlign VR256:$src1, VR256:$src2, (i8 imm:$imm))),
5625           (VPALIGNR256rr VR256:$src2, VR256:$src1, imm:$imm)>;
5626 def : Pat<(v8f32 (X86PAlign VR256:$src1, VR256:$src2, (i8 imm:$imm))),
5627           (VPALIGNR256rr VR256:$src2, VR256:$src1, imm:$imm)>;
5628 def : Pat<(v16i16 (X86PAlign VR256:$src1, VR256:$src2, (i8 imm:$imm))),
5629           (VPALIGNR256rr VR256:$src2, VR256:$src1, imm:$imm)>;
5630 def : Pat<(v32i8 (X86PAlign VR256:$src1, VR256:$src2, (i8 imm:$imm))),
5631           (VPALIGNR256rr VR256:$src2, VR256:$src1, imm:$imm)>;
5632 }
5633
5634 let Predicates = [HasAVX] in {
5635 def : Pat<(v4i32 (X86PAlign VR128:$src1, VR128:$src2, (i8 imm:$imm))),
5636           (VPALIGNR128rr VR128:$src2, VR128:$src1, imm:$imm)>;
5637 def : Pat<(v4f32 (X86PAlign VR128:$src1, VR128:$src2, (i8 imm:$imm))),
5638           (VPALIGNR128rr VR128:$src2, VR128:$src1, imm:$imm)>;
5639 def : Pat<(v8i16 (X86PAlign VR128:$src1, VR128:$src2, (i8 imm:$imm))),
5640           (VPALIGNR128rr VR128:$src2, VR128:$src1, imm:$imm)>;
5641 def : Pat<(v16i8 (X86PAlign VR128:$src1, VR128:$src2, (i8 imm:$imm))),
5642           (VPALIGNR128rr VR128:$src2, VR128:$src1, imm:$imm)>;
5643 }
5644
5645 let Predicates = [HasSSSE3] in {
5646 def : Pat<(v4i32 (X86PAlign VR128:$src1, VR128:$src2, (i8 imm:$imm))),
5647           (PALIGNR128rr VR128:$src2, VR128:$src1, imm:$imm)>;
5648 def : Pat<(v4f32 (X86PAlign VR128:$src1, VR128:$src2, (i8 imm:$imm))),
5649           (PALIGNR128rr VR128:$src2, VR128:$src1, imm:$imm)>;
5650 def : Pat<(v8i16 (X86PAlign VR128:$src1, VR128:$src2, (i8 imm:$imm))),
5651           (PALIGNR128rr VR128:$src2, VR128:$src1, imm:$imm)>;
5652 def : Pat<(v16i8 (X86PAlign VR128:$src1, VR128:$src2, (i8 imm:$imm))),
5653           (PALIGNR128rr VR128:$src2, VR128:$src1, imm:$imm)>;
5654 }
5655
5656 //===---------------------------------------------------------------------===//
5657 // SSSE3 - Thread synchronization
5658 //===---------------------------------------------------------------------===//
5659
5660 let usesCustomInserter = 1 in {
5661 def MONITOR : PseudoI<(outs), (ins i32mem:$src1, GR32:$src2, GR32:$src3),
5662                 [(int_x86_sse3_monitor addr:$src1, GR32:$src2, GR32:$src3)]>,
5663                 Requires<[HasSSE3]>;
5664 def MWAIT : PseudoI<(outs), (ins GR32:$src1, GR32:$src2),
5665                 [(int_x86_sse3_mwait GR32:$src1, GR32:$src2)]>,
5666                 Requires<[HasSSE3]>;
5667 }
5668
5669 let Uses = [EAX, ECX, EDX] in
5670 def MONITORrrr : I<0x01, MRM_C8, (outs), (ins), "monitor", []>, TB,
5671                  Requires<[HasSSE3]>;
5672 let Uses = [ECX, EAX] in
5673 def MWAITrr   : I<0x01, MRM_C9, (outs), (ins), "mwait", []>, TB,
5674                 Requires<[HasSSE3]>;
5675
5676 def : InstAlias<"mwait %eax, %ecx", (MWAITrr)>, Requires<[In32BitMode]>;
5677 def : InstAlias<"mwait %rax, %rcx", (MWAITrr)>, Requires<[In64BitMode]>;
5678
5679 def : InstAlias<"monitor %eax, %ecx, %edx", (MONITORrrr)>,
5680       Requires<[In32BitMode]>;
5681 def : InstAlias<"monitor %rax, %rcx, %rdx", (MONITORrrr)>,
5682       Requires<[In64BitMode]>;
5683
5684 //===----------------------------------------------------------------------===//
5685 // SSE4.1 - Packed Move with Sign/Zero Extend
5686 //===----------------------------------------------------------------------===//
5687
5688 multiclass SS41I_binop_rm_int8<bits<8> opc, string OpcodeStr, Intrinsic IntId> {
5689   def rr : SS48I<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
5690                  !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5691                  [(set VR128:$dst, (IntId VR128:$src))]>, OpSize;
5692
5693   def rm : SS48I<opc, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
5694                  !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5695        [(set VR128:$dst,
5696          (IntId (bitconvert (v2i64 (scalar_to_vector (loadi64 addr:$src))))))]>,
5697        OpSize;
5698 }
5699
5700 multiclass SS41I_binop_rm_int16_y<bits<8> opc, string OpcodeStr,
5701                                  Intrinsic IntId> {
5702   def Yrr : SS48I<opc, MRMSrcReg, (outs VR256:$dst), (ins VR128:$src),
5703                   !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5704                   [(set VR256:$dst, (IntId VR128:$src))]>, OpSize;
5705
5706   def Yrm : SS48I<opc, MRMSrcMem, (outs VR256:$dst), (ins i128mem:$src),
5707                   !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5708                   [(set VR256:$dst, (IntId (load addr:$src)))]>, OpSize;
5709 }
5710
5711 let Predicates = [HasAVX] in {
5712 defm VPMOVSXBW : SS41I_binop_rm_int8<0x20, "vpmovsxbw", int_x86_sse41_pmovsxbw>,
5713                                      VEX;
5714 defm VPMOVSXWD : SS41I_binop_rm_int8<0x23, "vpmovsxwd", int_x86_sse41_pmovsxwd>,
5715                                      VEX;
5716 defm VPMOVSXDQ : SS41I_binop_rm_int8<0x25, "vpmovsxdq", int_x86_sse41_pmovsxdq>,
5717                                      VEX;
5718 defm VPMOVZXBW : SS41I_binop_rm_int8<0x30, "vpmovzxbw", int_x86_sse41_pmovzxbw>,
5719                                      VEX;
5720 defm VPMOVZXWD : SS41I_binop_rm_int8<0x33, "vpmovzxwd", int_x86_sse41_pmovzxwd>,
5721                                      VEX;
5722 defm VPMOVZXDQ : SS41I_binop_rm_int8<0x35, "vpmovzxdq", int_x86_sse41_pmovzxdq>,
5723                                      VEX;
5724 }
5725
5726 let Predicates = [HasAVX2] in {
5727 defm VPMOVSXBW : SS41I_binop_rm_int16_y<0x20, "vpmovsxbw",
5728                                         int_x86_avx2_pmovsxbw>, VEX;
5729 defm VPMOVSXWD : SS41I_binop_rm_int16_y<0x23, "vpmovsxwd",
5730                                         int_x86_avx2_pmovsxwd>, VEX;
5731 defm VPMOVSXDQ : SS41I_binop_rm_int16_y<0x25, "vpmovsxdq",
5732                                         int_x86_avx2_pmovsxdq>, VEX;
5733 defm VPMOVZXBW : SS41I_binop_rm_int16_y<0x30, "vpmovzxbw",
5734                                         int_x86_avx2_pmovzxbw>, VEX;
5735 defm VPMOVZXWD : SS41I_binop_rm_int16_y<0x33, "vpmovzxwd",
5736                                         int_x86_avx2_pmovzxwd>, VEX;
5737 defm VPMOVZXDQ : SS41I_binop_rm_int16_y<0x35, "vpmovzxdq",
5738                                         int_x86_avx2_pmovzxdq>, VEX;
5739 }
5740
5741 defm PMOVSXBW   : SS41I_binop_rm_int8<0x20, "pmovsxbw", int_x86_sse41_pmovsxbw>;
5742 defm PMOVSXWD   : SS41I_binop_rm_int8<0x23, "pmovsxwd", int_x86_sse41_pmovsxwd>;
5743 defm PMOVSXDQ   : SS41I_binop_rm_int8<0x25, "pmovsxdq", int_x86_sse41_pmovsxdq>;
5744 defm PMOVZXBW   : SS41I_binop_rm_int8<0x30, "pmovzxbw", int_x86_sse41_pmovzxbw>;
5745 defm PMOVZXWD   : SS41I_binop_rm_int8<0x33, "pmovzxwd", int_x86_sse41_pmovzxwd>;
5746 defm PMOVZXDQ   : SS41I_binop_rm_int8<0x35, "pmovzxdq", int_x86_sse41_pmovzxdq>;
5747
5748 let Predicates = [HasAVX] in {
5749   // Common patterns involving scalar load.
5750   def : Pat<(int_x86_sse41_pmovsxbw (vzmovl_v2i64 addr:$src)),
5751             (VPMOVSXBWrm addr:$src)>;
5752   def : Pat<(int_x86_sse41_pmovsxbw (vzload_v2i64 addr:$src)),
5753             (VPMOVSXBWrm addr:$src)>;
5754
5755   def : Pat<(int_x86_sse41_pmovsxwd (vzmovl_v2i64 addr:$src)),
5756             (VPMOVSXWDrm addr:$src)>;
5757   def : Pat<(int_x86_sse41_pmovsxwd (vzload_v2i64 addr:$src)),
5758             (VPMOVSXWDrm addr:$src)>;
5759
5760   def : Pat<(int_x86_sse41_pmovsxdq (vzmovl_v2i64 addr:$src)),
5761             (VPMOVSXDQrm addr:$src)>;
5762   def : Pat<(int_x86_sse41_pmovsxdq (vzload_v2i64 addr:$src)),
5763             (VPMOVSXDQrm addr:$src)>;
5764
5765   def : Pat<(int_x86_sse41_pmovzxbw (vzmovl_v2i64 addr:$src)),
5766             (VPMOVZXBWrm addr:$src)>;
5767   def : Pat<(int_x86_sse41_pmovzxbw (vzload_v2i64 addr:$src)),
5768             (VPMOVZXBWrm addr:$src)>;
5769
5770   def : Pat<(int_x86_sse41_pmovzxwd (vzmovl_v2i64 addr:$src)),
5771             (VPMOVZXWDrm addr:$src)>;
5772   def : Pat<(int_x86_sse41_pmovzxwd (vzload_v2i64 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 }
5780
5781 let Predicates = [HasSSE41] in {
5782   // Common patterns involving scalar load.
5783   def : Pat<(int_x86_sse41_pmovsxbw (vzmovl_v2i64 addr:$src)),
5784             (PMOVSXBWrm addr:$src)>;
5785   def : Pat<(int_x86_sse41_pmovsxbw (vzload_v2i64 addr:$src)),
5786             (PMOVSXBWrm addr:$src)>;
5787
5788   def : Pat<(int_x86_sse41_pmovsxwd (vzmovl_v2i64 addr:$src)),
5789             (PMOVSXWDrm addr:$src)>;
5790   def : Pat<(int_x86_sse41_pmovsxwd (vzload_v2i64 addr:$src)),
5791             (PMOVSXWDrm addr:$src)>;
5792
5793   def : Pat<(int_x86_sse41_pmovsxdq (vzmovl_v2i64 addr:$src)),
5794             (PMOVSXDQrm addr:$src)>;
5795   def : Pat<(int_x86_sse41_pmovsxdq (vzload_v2i64 addr:$src)),
5796             (PMOVSXDQrm addr:$src)>;
5797
5798   def : Pat<(int_x86_sse41_pmovzxbw (vzmovl_v2i64 addr:$src)),
5799             (PMOVZXBWrm addr:$src)>;
5800   def : Pat<(int_x86_sse41_pmovzxbw (vzload_v2i64 addr:$src)),
5801             (PMOVZXBWrm addr:$src)>;
5802
5803   def : Pat<(int_x86_sse41_pmovzxwd (vzmovl_v2i64 addr:$src)),
5804             (PMOVZXWDrm addr:$src)>;
5805   def : Pat<(int_x86_sse41_pmovzxwd (vzload_v2i64 addr:$src)),
5806             (PMOVZXWDrm addr:$src)>;
5807
5808   def : Pat<(int_x86_sse41_pmovzxdq (vzmovl_v2i64 addr:$src)),
5809             (PMOVZXDQrm addr:$src)>;
5810   def : Pat<(int_x86_sse41_pmovzxdq (vzload_v2i64 addr:$src)),
5811             (PMOVZXDQrm addr:$src)>;
5812 }
5813
5814
5815 multiclass SS41I_binop_rm_int4<bits<8> opc, string OpcodeStr, Intrinsic IntId> {
5816   def rr : SS48I<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
5817                  !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5818                  [(set VR128:$dst, (IntId VR128:$src))]>, OpSize;
5819
5820   def rm : SS48I<opc, MRMSrcMem, (outs VR128:$dst), (ins i32mem:$src),
5821                  !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5822        [(set VR128:$dst,
5823          (IntId (bitconvert (v4i32 (scalar_to_vector (loadi32 addr:$src))))))]>,
5824           OpSize;
5825 }
5826
5827 multiclass SS41I_binop_rm_int8_y<bits<8> opc, string OpcodeStr,
5828                                  Intrinsic IntId> {
5829   def Yrr : SS48I<opc, MRMSrcReg, (outs VR256:$dst), (ins VR128:$src),
5830                   !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5831                   [(set VR256:$dst, (IntId VR128:$src))]>, OpSize;
5832
5833   def Yrm : SS48I<opc, MRMSrcMem, (outs VR256:$dst), (ins i32mem:$src),
5834                   !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5835        [(set VR256:$dst,
5836          (IntId (bitconvert (v2i64 (scalar_to_vector (loadi64 addr:$src))))))]>,
5837           OpSize;
5838 }
5839
5840 let Predicates = [HasAVX] in {
5841 defm VPMOVSXBD : SS41I_binop_rm_int4<0x21, "vpmovsxbd", int_x86_sse41_pmovsxbd>,
5842                                      VEX;
5843 defm VPMOVSXWQ : SS41I_binop_rm_int4<0x24, "vpmovsxwq", int_x86_sse41_pmovsxwq>,
5844                                      VEX;
5845 defm VPMOVZXBD : SS41I_binop_rm_int4<0x31, "vpmovzxbd", int_x86_sse41_pmovzxbd>,
5846                                      VEX;
5847 defm VPMOVZXWQ : SS41I_binop_rm_int4<0x34, "vpmovzxwq", int_x86_sse41_pmovzxwq>,
5848                                      VEX;
5849 }
5850
5851 let Predicates = [HasAVX2] in {
5852 defm VPMOVSXBD : SS41I_binop_rm_int8_y<0x21, "vpmovsxbd",
5853                                        int_x86_avx2_pmovsxbd>, VEX;
5854 defm VPMOVSXWQ : SS41I_binop_rm_int8_y<0x24, "vpmovsxwq",
5855                                        int_x86_avx2_pmovsxwq>, VEX;
5856 defm VPMOVZXBD : SS41I_binop_rm_int8_y<0x31, "vpmovzxbd",
5857                                        int_x86_avx2_pmovzxbd>, VEX;
5858 defm VPMOVZXWQ : SS41I_binop_rm_int8_y<0x34, "vpmovzxwq",
5859                                        int_x86_avx2_pmovzxwq>, VEX;
5860 }
5861
5862 defm PMOVSXBD   : SS41I_binop_rm_int4<0x21, "pmovsxbd", int_x86_sse41_pmovsxbd>;
5863 defm PMOVSXWQ   : SS41I_binop_rm_int4<0x24, "pmovsxwq", int_x86_sse41_pmovsxwq>;
5864 defm PMOVZXBD   : SS41I_binop_rm_int4<0x31, "pmovzxbd", int_x86_sse41_pmovzxbd>;
5865 defm PMOVZXWQ   : SS41I_binop_rm_int4<0x34, "pmovzxwq", int_x86_sse41_pmovzxwq>;
5866
5867 let Predicates = [HasAVX] in {
5868   // Common patterns involving scalar load
5869   def : Pat<(int_x86_sse41_pmovsxbd (vzmovl_v4i32 addr:$src)),
5870             (VPMOVSXBDrm addr:$src)>;
5871   def : Pat<(int_x86_sse41_pmovsxwq (vzmovl_v4i32 addr:$src)),
5872             (VPMOVSXWQrm addr:$src)>;
5873
5874   def : Pat<(int_x86_sse41_pmovzxbd (vzmovl_v4i32 addr:$src)),
5875             (VPMOVZXBDrm addr:$src)>;
5876   def : Pat<(int_x86_sse41_pmovzxwq (vzmovl_v4i32 addr:$src)),
5877             (VPMOVZXWQrm addr:$src)>;
5878 }
5879
5880 let Predicates = [HasSSE41] in {
5881   // Common patterns involving scalar load
5882   def : Pat<(int_x86_sse41_pmovsxbd (vzmovl_v4i32 addr:$src)),
5883             (PMOVSXBDrm addr:$src)>;
5884   def : Pat<(int_x86_sse41_pmovsxwq (vzmovl_v4i32 addr:$src)),
5885             (PMOVSXWQrm addr:$src)>;
5886
5887   def : Pat<(int_x86_sse41_pmovzxbd (vzmovl_v4i32 addr:$src)),
5888             (PMOVZXBDrm addr:$src)>;
5889   def : Pat<(int_x86_sse41_pmovzxwq (vzmovl_v4i32 addr:$src)),
5890             (PMOVZXWQrm addr:$src)>;
5891 }
5892
5893 multiclass SS41I_binop_rm_int2<bits<8> opc, string OpcodeStr, Intrinsic IntId> {
5894   def rr : SS48I<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
5895                  !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5896                  [(set VR128:$dst, (IntId VR128:$src))]>, OpSize;
5897
5898   // Expecting a i16 load any extended to i32 value.
5899   def rm : SS48I<opc, MRMSrcMem, (outs VR128:$dst), (ins i16mem:$src),
5900                  !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5901                  [(set VR128:$dst, (IntId (bitconvert
5902                      (v4i32 (scalar_to_vector (loadi16_anyext addr:$src))))))]>,
5903                  OpSize;
5904 }
5905
5906 multiclass SS41I_binop_rm_int4_y<bits<8> opc, string OpcodeStr,
5907                                  Intrinsic IntId> {
5908   def Yrr : SS48I<opc, MRMSrcReg, (outs VR256:$dst), (ins VR128:$src),
5909                  !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5910                  [(set VR256:$dst, (IntId VR128:$src))]>, OpSize;
5911
5912   // Expecting a i16 load any extended to i32 value.
5913   def Yrm : SS48I<opc, MRMSrcMem, (outs VR256:$dst), (ins i16mem:$src),
5914                   !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5915                   [(set VR256:$dst, (IntId (bitconvert
5916                       (v4i32 (scalar_to_vector (loadi32 addr:$src))))))]>,
5917                   OpSize;
5918 }
5919
5920 let Predicates = [HasAVX] in {
5921 defm VPMOVSXBQ : SS41I_binop_rm_int2<0x22, "vpmovsxbq", int_x86_sse41_pmovsxbq>,
5922                                      VEX;
5923 defm VPMOVZXBQ : SS41I_binop_rm_int2<0x32, "vpmovzxbq", int_x86_sse41_pmovzxbq>,
5924                                      VEX;
5925 }
5926 let Predicates = [HasAVX2] in {
5927 defm VPMOVSXBQ : SS41I_binop_rm_int4_y<0x22, "vpmovsxbq",
5928                                        int_x86_avx2_pmovsxbq>, VEX;
5929 defm VPMOVZXBQ : SS41I_binop_rm_int4_y<0x32, "vpmovzxbq",
5930                                        int_x86_avx2_pmovzxbq>, VEX;
5931 }
5932 defm PMOVSXBQ   : SS41I_binop_rm_int2<0x22, "pmovsxbq", int_x86_sse41_pmovsxbq>;
5933 defm PMOVZXBQ   : SS41I_binop_rm_int2<0x32, "pmovzxbq", int_x86_sse41_pmovzxbq>;
5934
5935 let Predicates = [HasAVX] in {
5936   // Common patterns involving scalar load
5937   def : Pat<(int_x86_sse41_pmovsxbq
5938               (bitconvert (v4i32 (X86vzmovl
5939                             (v4i32 (scalar_to_vector (loadi32 addr:$src))))))),
5940             (VPMOVSXBQrm addr:$src)>;
5941
5942   def : Pat<(int_x86_sse41_pmovzxbq
5943               (bitconvert (v4i32 (X86vzmovl
5944                             (v4i32 (scalar_to_vector (loadi32 addr:$src))))))),
5945             (VPMOVZXBQrm addr:$src)>;
5946 }
5947
5948 let Predicates = [HasSSE41] in {
5949   // Common patterns involving scalar load
5950   def : Pat<(int_x86_sse41_pmovsxbq
5951               (bitconvert (v4i32 (X86vzmovl
5952                             (v4i32 (scalar_to_vector (loadi32 addr:$src))))))),
5953             (PMOVSXBQrm addr:$src)>;
5954
5955   def : Pat<(int_x86_sse41_pmovzxbq
5956               (bitconvert (v4i32 (X86vzmovl
5957                             (v4i32 (scalar_to_vector (loadi32 addr:$src))))))),
5958             (PMOVZXBQrm addr:$src)>;
5959 }
5960
5961 //===----------------------------------------------------------------------===//
5962 // SSE4.1 - Extract Instructions
5963 //===----------------------------------------------------------------------===//
5964
5965 /// SS41I_binop_ext8 - SSE 4.1 extract 8 bits to 32 bit reg or 8 bit mem
5966 multiclass SS41I_extract8<bits<8> opc, string OpcodeStr> {
5967   def rr : SS4AIi8<opc, MRMDestReg, (outs GR32:$dst),
5968                  (ins VR128:$src1, i32i8imm:$src2),
5969                  !strconcat(OpcodeStr,
5970                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5971                  [(set GR32:$dst, (X86pextrb (v16i8 VR128:$src1), imm:$src2))]>,
5972                  OpSize;
5973   let neverHasSideEffects = 1, mayStore = 1 in
5974   def mr : SS4AIi8<opc, MRMDestMem, (outs),
5975                  (ins i8mem:$dst, VR128:$src1, i32i8imm:$src2),
5976                  !strconcat(OpcodeStr,
5977                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5978                  []>, OpSize;
5979 // FIXME:
5980 // There's an AssertZext in the way of writing the store pattern
5981 // (store (i8 (trunc (X86pextrb (v16i8 VR128:$src1), imm:$src2))), addr:$dst)
5982 }
5983
5984 let Predicates = [HasAVX] in {
5985   defm VPEXTRB : SS41I_extract8<0x14, "vpextrb">, VEX;
5986   def  VPEXTRBrr64 : SS4AIi8<0x14, MRMDestReg, (outs GR64:$dst),
5987          (ins VR128:$src1, i32i8imm:$src2),
5988          "vpextrb\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>, OpSize, VEX;
5989 }
5990
5991 defm PEXTRB      : SS41I_extract8<0x14, "pextrb">;
5992
5993
5994 /// SS41I_extract16 - SSE 4.1 extract 16 bits to memory destination
5995 multiclass SS41I_extract16<bits<8> opc, string OpcodeStr> {
5996   let neverHasSideEffects = 1, mayStore = 1 in
5997   def mr : SS4AIi8<opc, MRMDestMem, (outs),
5998                  (ins i16mem:$dst, VR128:$src1, i32i8imm:$src2),
5999                  !strconcat(OpcodeStr,
6000                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6001                  []>, OpSize;
6002 // FIXME:
6003 // There's an AssertZext in the way of writing the store pattern
6004 // (store (i16 (trunc (X86pextrw (v16i8 VR128:$src1), imm:$src2))), addr:$dst)
6005 }
6006
6007 let Predicates = [HasAVX] in
6008   defm VPEXTRW : SS41I_extract16<0x15, "vpextrw">, VEX;
6009
6010 defm PEXTRW      : SS41I_extract16<0x15, "pextrw">;
6011
6012
6013 /// SS41I_extract32 - SSE 4.1 extract 32 bits to int reg or memory destination
6014 multiclass SS41I_extract32<bits<8> opc, string OpcodeStr> {
6015   def rr : SS4AIi8<opc, MRMDestReg, (outs GR32:$dst),
6016                  (ins VR128:$src1, i32i8imm:$src2),
6017                  !strconcat(OpcodeStr,
6018                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6019                  [(set GR32:$dst,
6020                   (extractelt (v4i32 VR128:$src1), imm:$src2))]>, OpSize;
6021   def mr : SS4AIi8<opc, MRMDestMem, (outs),
6022                  (ins i32mem:$dst, VR128:$src1, i32i8imm:$src2),
6023                  !strconcat(OpcodeStr,
6024                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6025                  [(store (extractelt (v4i32 VR128:$src1), imm:$src2),
6026                           addr:$dst)]>, OpSize;
6027 }
6028
6029 let Predicates = [HasAVX] in
6030   defm VPEXTRD : SS41I_extract32<0x16, "vpextrd">, VEX;
6031
6032 defm PEXTRD      : SS41I_extract32<0x16, "pextrd">;
6033
6034 /// SS41I_extract32 - SSE 4.1 extract 32 bits to int reg or memory destination
6035 multiclass SS41I_extract64<bits<8> opc, string OpcodeStr> {
6036   def rr : SS4AIi8<opc, MRMDestReg, (outs GR64:$dst),
6037                  (ins VR128:$src1, i32i8imm:$src2),
6038                  !strconcat(OpcodeStr,
6039                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6040                  [(set GR64:$dst,
6041                   (extractelt (v2i64 VR128:$src1), imm:$src2))]>, OpSize, REX_W;
6042   def mr : SS4AIi8<opc, MRMDestMem, (outs),
6043                  (ins i64mem:$dst, VR128:$src1, i32i8imm:$src2),
6044                  !strconcat(OpcodeStr,
6045                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6046                  [(store (extractelt (v2i64 VR128:$src1), imm:$src2),
6047                           addr:$dst)]>, OpSize, REX_W;
6048 }
6049
6050 let Predicates = [HasAVX] in
6051   defm VPEXTRQ : SS41I_extract64<0x16, "vpextrq">, VEX, VEX_W;
6052
6053 defm PEXTRQ      : SS41I_extract64<0x16, "pextrq">;
6054
6055 /// SS41I_extractf32 - SSE 4.1 extract 32 bits fp value to int reg or memory
6056 /// destination
6057 multiclass SS41I_extractf32<bits<8> opc, string OpcodeStr> {
6058   def rr : SS4AIi8<opc, MRMDestReg, (outs GR32:$dst),
6059                  (ins VR128:$src1, i32i8imm:$src2),
6060                  !strconcat(OpcodeStr,
6061                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6062                  [(set GR32:$dst,
6063                     (extractelt (bc_v4i32 (v4f32 VR128:$src1)), imm:$src2))]>,
6064            OpSize;
6065   def mr : SS4AIi8<opc, MRMDestMem, (outs),
6066                  (ins f32mem:$dst, VR128:$src1, i32i8imm:$src2),
6067                  !strconcat(OpcodeStr,
6068                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6069                  [(store (extractelt (bc_v4i32 (v4f32 VR128:$src1)), imm:$src2),
6070                           addr:$dst)]>, OpSize;
6071 }
6072
6073 let ExeDomain = SSEPackedSingle in {
6074   let Predicates = [HasAVX] in {
6075     defm VEXTRACTPS : SS41I_extractf32<0x17, "vextractps">, VEX;
6076     def VEXTRACTPSrr64 : SS4AIi8<0x17, MRMDestReg, (outs GR64:$dst),
6077                     (ins VR128:$src1, i32i8imm:$src2),
6078                     "vextractps \t{$src2, $src1, $dst|$dst, $src1, $src2}",
6079                     []>, OpSize, VEX;
6080   }
6081   defm EXTRACTPS   : SS41I_extractf32<0x17, "extractps">;
6082 }
6083
6084 // Also match an EXTRACTPS store when the store is done as f32 instead of i32.
6085 def : Pat<(store (f32 (bitconvert (extractelt (bc_v4i32 (v4f32 VR128:$src1)),
6086                                               imm:$src2))),
6087                  addr:$dst),
6088           (VEXTRACTPSmr addr:$dst, VR128:$src1, imm:$src2)>,
6089           Requires<[HasAVX]>;
6090 def : Pat<(store (f32 (bitconvert (extractelt (bc_v4i32 (v4f32 VR128:$src1)),
6091                                               imm:$src2))),
6092                  addr:$dst),
6093           (EXTRACTPSmr addr:$dst, VR128:$src1, imm:$src2)>,
6094           Requires<[HasSSE41]>;
6095
6096 //===----------------------------------------------------------------------===//
6097 // SSE4.1 - Insert Instructions
6098 //===----------------------------------------------------------------------===//
6099
6100 multiclass SS41I_insert8<bits<8> opc, string asm, bit Is2Addr = 1> {
6101   def rr : SS4AIi8<opc, MRMSrcReg, (outs VR128:$dst),
6102       (ins VR128:$src1, GR32:$src2, i32i8imm:$src3),
6103       !if(Is2Addr,
6104         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6105         !strconcat(asm,
6106                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6107       [(set VR128:$dst,
6108         (X86pinsrb VR128:$src1, GR32:$src2, imm:$src3))]>, OpSize;
6109   def rm : SS4AIi8<opc, MRMSrcMem, (outs VR128:$dst),
6110       (ins VR128:$src1, i8mem:$src2, i32i8imm:$src3),
6111       !if(Is2Addr,
6112         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6113         !strconcat(asm,
6114                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6115       [(set VR128:$dst,
6116         (X86pinsrb VR128:$src1, (extloadi8 addr:$src2),
6117                    imm:$src3))]>, OpSize;
6118 }
6119
6120 let Predicates = [HasAVX] in
6121   defm VPINSRB : SS41I_insert8<0x20, "vpinsrb", 0>, VEX_4V;
6122 let Constraints = "$src1 = $dst" in
6123   defm PINSRB  : SS41I_insert8<0x20, "pinsrb">;
6124
6125 multiclass SS41I_insert32<bits<8> opc, string asm, bit Is2Addr = 1> {
6126   def rr : SS4AIi8<opc, MRMSrcReg, (outs VR128:$dst),
6127       (ins VR128:$src1, GR32:$src2, i32i8imm:$src3),
6128       !if(Is2Addr,
6129         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6130         !strconcat(asm,
6131                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6132       [(set VR128:$dst,
6133         (v4i32 (insertelt VR128:$src1, GR32:$src2, imm:$src3)))]>,
6134       OpSize;
6135   def rm : SS4AIi8<opc, MRMSrcMem, (outs VR128:$dst),
6136       (ins VR128:$src1, i32mem:$src2, i32i8imm:$src3),
6137       !if(Is2Addr,
6138         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6139         !strconcat(asm,
6140                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6141       [(set VR128:$dst,
6142         (v4i32 (insertelt VR128:$src1, (loadi32 addr:$src2),
6143                           imm:$src3)))]>, OpSize;
6144 }
6145
6146 let Predicates = [HasAVX] in
6147   defm VPINSRD : SS41I_insert32<0x22, "vpinsrd", 0>, VEX_4V;
6148 let Constraints = "$src1 = $dst" in
6149   defm PINSRD : SS41I_insert32<0x22, "pinsrd">;
6150
6151 multiclass SS41I_insert64<bits<8> opc, string asm, bit Is2Addr = 1> {
6152   def rr : SS4AIi8<opc, MRMSrcReg, (outs VR128:$dst),
6153       (ins VR128:$src1, GR64:$src2, i32i8imm:$src3),
6154       !if(Is2Addr,
6155         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6156         !strconcat(asm,
6157                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6158       [(set VR128:$dst,
6159         (v2i64 (insertelt VR128:$src1, GR64:$src2, imm:$src3)))]>,
6160       OpSize;
6161   def rm : SS4AIi8<opc, MRMSrcMem, (outs VR128:$dst),
6162       (ins VR128:$src1, i64mem:$src2, i32i8imm:$src3),
6163       !if(Is2Addr,
6164         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6165         !strconcat(asm,
6166                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6167       [(set VR128:$dst,
6168         (v2i64 (insertelt VR128:$src1, (loadi64 addr:$src2),
6169                           imm:$src3)))]>, OpSize;
6170 }
6171
6172 let Predicates = [HasAVX] in
6173   defm VPINSRQ : SS41I_insert64<0x22, "vpinsrq", 0>, VEX_4V, VEX_W;
6174 let Constraints = "$src1 = $dst" in
6175   defm PINSRQ : SS41I_insert64<0x22, "pinsrq">, REX_W;
6176
6177 // insertps has a few different modes, there's the first two here below which
6178 // are optimized inserts that won't zero arbitrary elements in the destination
6179 // vector. The next one matches the intrinsic and could zero arbitrary elements
6180 // in the target vector.
6181 multiclass SS41I_insertf32<bits<8> opc, string asm, bit Is2Addr = 1> {
6182   def rr : SS4AIi8<opc, MRMSrcReg, (outs VR128:$dst),
6183       (ins VR128:$src1, VR128:$src2, u32u8imm:$src3),
6184       !if(Is2Addr,
6185         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6186         !strconcat(asm,
6187                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6188       [(set VR128:$dst,
6189         (X86insrtps VR128:$src1, VR128:$src2, imm:$src3))]>,
6190       OpSize;
6191   def rm : SS4AIi8<opc, MRMSrcMem, (outs VR128:$dst),
6192       (ins VR128:$src1, f32mem:$src2, u32u8imm:$src3),
6193       !if(Is2Addr,
6194         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6195         !strconcat(asm,
6196                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6197       [(set VR128:$dst,
6198         (X86insrtps VR128:$src1,
6199                    (v4f32 (scalar_to_vector (loadf32 addr:$src2))),
6200                     imm:$src3))]>, OpSize;
6201 }
6202
6203 let ExeDomain = SSEPackedSingle in {
6204   let Predicates = [HasAVX] in
6205     defm VINSERTPS : SS41I_insertf32<0x21, "vinsertps", 0>, VEX_4V;
6206   let Constraints = "$src1 = $dst" in
6207     defm INSERTPS : SS41I_insertf32<0x21, "insertps">;
6208 }
6209
6210 def : Pat<(int_x86_sse41_insertps VR128:$src1, VR128:$src2, imm:$src3),
6211           (VINSERTPSrr VR128:$src1, VR128:$src2, imm:$src3)>,
6212           Requires<[HasAVX]>;
6213 def : Pat<(int_x86_sse41_insertps VR128:$src1, VR128:$src2, imm:$src3),
6214           (INSERTPSrr VR128:$src1, VR128:$src2, imm:$src3)>,
6215           Requires<[HasSSE41]>;
6216
6217 //===----------------------------------------------------------------------===//
6218 // SSE4.1 - Round Instructions
6219 //===----------------------------------------------------------------------===//
6220
6221 multiclass sse41_fp_unop_rm<bits<8> opcps, bits<8> opcpd, string OpcodeStr,
6222                             X86MemOperand x86memop, RegisterClass RC,
6223                             PatFrag mem_frag32, PatFrag mem_frag64,
6224                             Intrinsic V4F32Int, Intrinsic V2F64Int> {
6225 let ExeDomain = SSEPackedSingle in {
6226   // Intrinsic operation, reg.
6227   // Vector intrinsic operation, reg
6228   def PSr : SS4AIi8<opcps, MRMSrcReg,
6229                     (outs RC:$dst), (ins RC:$src1, i32i8imm:$src2),
6230                     !strconcat(OpcodeStr,
6231                     "ps\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6232                     [(set RC:$dst, (V4F32Int RC:$src1, imm:$src2))]>,
6233                     OpSize;
6234
6235   // Vector intrinsic operation, mem
6236   def PSm : SS4AIi8<opcps, MRMSrcMem,
6237                     (outs RC:$dst), (ins x86memop:$src1, i32i8imm:$src2),
6238                     !strconcat(OpcodeStr,
6239                     "ps\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6240                     [(set RC:$dst,
6241                           (V4F32Int (mem_frag32 addr:$src1),imm:$src2))]>,
6242                     OpSize;
6243 } // ExeDomain = SSEPackedSingle
6244
6245 let ExeDomain = SSEPackedDouble in {
6246   // Vector intrinsic operation, reg
6247   def PDr : SS4AIi8<opcpd, MRMSrcReg,
6248                     (outs RC:$dst), (ins RC:$src1, i32i8imm:$src2),
6249                     !strconcat(OpcodeStr,
6250                     "pd\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6251                     [(set RC:$dst, (V2F64Int RC:$src1, imm:$src2))]>,
6252                     OpSize;
6253
6254   // Vector intrinsic operation, mem
6255   def PDm : SS4AIi8<opcpd, MRMSrcMem,
6256                     (outs RC:$dst), (ins x86memop:$src1, i32i8imm:$src2),
6257                     !strconcat(OpcodeStr,
6258                     "pd\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6259                     [(set RC:$dst,
6260                           (V2F64Int (mem_frag64 addr:$src1),imm:$src2))]>,
6261                     OpSize;
6262 } // ExeDomain = SSEPackedDouble
6263 }
6264
6265 multiclass sse41_fp_binop_rm<bits<8> opcss, bits<8> opcsd,
6266                             string OpcodeStr,
6267                             Intrinsic F32Int,
6268                             Intrinsic F64Int, bit Is2Addr = 1> {
6269 let ExeDomain = GenericDomain in {
6270   // Operation, reg.
6271   def SSr : SS4AIi8<opcss, MRMSrcReg,
6272       (outs FR32:$dst), (ins FR32:$src1, FR32:$src2, i32i8imm:$src3),
6273       !if(Is2Addr,
6274           !strconcat(OpcodeStr,
6275               "ss\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6276           !strconcat(OpcodeStr,
6277               "ss\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6278       []>, OpSize;
6279
6280   // Intrinsic operation, reg.
6281   def SSr_Int : SS4AIi8<opcss, MRMSrcReg,
6282         (outs VR128:$dst), (ins VR128:$src1, VR128:$src2, i32i8imm:$src3),
6283         !if(Is2Addr,
6284             !strconcat(OpcodeStr,
6285                 "ss\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6286             !strconcat(OpcodeStr,
6287                 "ss\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6288         [(set VR128:$dst, (F32Int VR128:$src1, VR128:$src2, imm:$src3))]>,
6289         OpSize;
6290
6291   // Intrinsic operation, mem.
6292   def SSm : SS4AIi8<opcss, MRMSrcMem,
6293         (outs VR128:$dst), (ins VR128:$src1, ssmem:$src2, i32i8imm:$src3),
6294         !if(Is2Addr,
6295             !strconcat(OpcodeStr,
6296                 "ss\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6297             !strconcat(OpcodeStr,
6298                 "ss\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6299         [(set VR128:$dst,
6300              (F32Int VR128:$src1, sse_load_f32:$src2, imm:$src3))]>,
6301         OpSize;
6302
6303   // Operation, reg.
6304   def SDr : SS4AIi8<opcsd, MRMSrcReg,
6305         (outs FR64:$dst), (ins FR64:$src1, FR64:$src2, i32i8imm:$src3),
6306         !if(Is2Addr,
6307             !strconcat(OpcodeStr,
6308                 "sd\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6309             !strconcat(OpcodeStr,
6310                 "sd\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6311         []>, OpSize;
6312
6313   // Intrinsic operation, reg.
6314   def SDr_Int : SS4AIi8<opcsd, MRMSrcReg,
6315         (outs VR128:$dst), (ins VR128:$src1, VR128:$src2, i32i8imm:$src3),
6316         !if(Is2Addr,
6317             !strconcat(OpcodeStr,
6318                 "sd\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6319             !strconcat(OpcodeStr,
6320                 "sd\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6321         [(set VR128:$dst, (F64Int VR128:$src1, VR128:$src2, imm:$src3))]>,
6322         OpSize;
6323
6324   // Intrinsic operation, mem.
6325   def SDm : SS4AIi8<opcsd, MRMSrcMem,
6326         (outs VR128:$dst), (ins VR128:$src1, sdmem:$src2, i32i8imm:$src3),
6327         !if(Is2Addr,
6328             !strconcat(OpcodeStr,
6329                 "sd\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6330             !strconcat(OpcodeStr,
6331                 "sd\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6332         [(set VR128:$dst,
6333               (F64Int VR128:$src1, sse_load_f64:$src2, imm:$src3))]>,
6334         OpSize;
6335 } // ExeDomain = GenericDomain
6336 }
6337
6338 // FP round - roundss, roundps, roundsd, roundpd
6339 let Predicates = [HasAVX] in {
6340   // Intrinsic form
6341   defm VROUND  : sse41_fp_unop_rm<0x08, 0x09, "vround", f128mem, VR128,
6342                                   memopv4f32, memopv2f64,
6343                                   int_x86_sse41_round_ps,
6344                                   int_x86_sse41_round_pd>, VEX;
6345   defm VROUNDY : sse41_fp_unop_rm<0x08, 0x09, "vround", f256mem, VR256,
6346                                   memopv8f32, memopv4f64,
6347                                   int_x86_avx_round_ps_256,
6348                                   int_x86_avx_round_pd_256>, VEX;
6349   defm VROUND  : sse41_fp_binop_rm<0x0A, 0x0B, "vround",
6350                                   int_x86_sse41_round_ss,
6351                                   int_x86_sse41_round_sd, 0>, VEX_4V, VEX_LIG;
6352
6353   def : Pat<(ffloor FR32:$src),
6354             (VROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x1))>;
6355   def : Pat<(f64 (ffloor FR64:$src)),
6356             (VROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x1))>;
6357   def : Pat<(f32 (fnearbyint FR32:$src)),
6358             (VROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0xC))>;
6359   def : Pat<(f64 (fnearbyint FR64:$src)),
6360             (VROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0xC))>;
6361   def : Pat<(f32 (fceil FR32:$src)),
6362             (VROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x2))>;
6363   def : Pat<(f64 (fceil FR64:$src)),
6364             (VROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x2))>;
6365   def : Pat<(f32 (frint FR32:$src)),
6366             (VROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x4))>;
6367   def : Pat<(f64 (frint FR64:$src)),
6368             (VROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x4))>;
6369   def : Pat<(f32 (ftrunc FR32:$src)),
6370             (VROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x3))>;
6371   def : Pat<(f64 (ftrunc FR64:$src)),
6372             (VROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x3))>;
6373 }
6374
6375 defm ROUND  : sse41_fp_unop_rm<0x08, 0x09, "round", f128mem, VR128,
6376                                memopv4f32, memopv2f64,
6377                                int_x86_sse41_round_ps, int_x86_sse41_round_pd>;
6378 let Constraints = "$src1 = $dst" in
6379 defm ROUND  : sse41_fp_binop_rm<0x0A, 0x0B, "round",
6380                                int_x86_sse41_round_ss, int_x86_sse41_round_sd>;
6381
6382 def : Pat<(ffloor FR32:$src),
6383           (ROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x1))>;
6384 def : Pat<(f64 (ffloor FR64:$src)),
6385           (ROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x1))>;
6386 def : Pat<(f32 (fnearbyint FR32:$src)),
6387           (ROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0xC))>;
6388 def : Pat<(f64 (fnearbyint FR64:$src)),
6389           (ROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0xC))>;
6390 def : Pat<(f32 (fceil FR32:$src)),
6391           (ROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x2))>;
6392 def : Pat<(f64 (fceil FR64:$src)),
6393           (ROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x2))>;
6394 def : Pat<(f32 (frint FR32:$src)),
6395           (ROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x4))>;
6396 def : Pat<(f64 (frint FR64:$src)),
6397           (ROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x4))>;
6398 def : Pat<(f32 (ftrunc FR32:$src)),
6399           (ROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x3))>;
6400 def : Pat<(f64 (ftrunc FR64:$src)),
6401           (ROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x3))>;
6402
6403 //===----------------------------------------------------------------------===//
6404 // SSE4.1 - Packed Bit Test
6405 //===----------------------------------------------------------------------===//
6406
6407 // ptest instruction we'll lower to this in X86ISelLowering primarily from
6408 // the intel intrinsic that corresponds to this.
6409 let Defs = [EFLAGS], Predicates = [HasAVX] in {
6410 def VPTESTrr  : SS48I<0x17, MRMSrcReg, (outs), (ins VR128:$src1, VR128:$src2),
6411                 "vptest\t{$src2, $src1|$src1, $src2}",
6412                 [(set EFLAGS, (X86ptest VR128:$src1, (v4f32 VR128:$src2)))]>,
6413                 OpSize, VEX;
6414 def VPTESTrm  : SS48I<0x17, MRMSrcMem, (outs), (ins VR128:$src1, f128mem:$src2),
6415                 "vptest\t{$src2, $src1|$src1, $src2}",
6416                 [(set EFLAGS,(X86ptest VR128:$src1, (memopv4f32 addr:$src2)))]>,
6417                 OpSize, VEX;
6418
6419 def VPTESTYrr : SS48I<0x17, MRMSrcReg, (outs), (ins VR256:$src1, VR256:$src2),
6420                 "vptest\t{$src2, $src1|$src1, $src2}",
6421                 [(set EFLAGS, (X86ptest VR256:$src1, (v4i64 VR256:$src2)))]>,
6422                 OpSize, VEX;
6423 def VPTESTYrm : SS48I<0x17, MRMSrcMem, (outs), (ins VR256:$src1, i256mem:$src2),
6424                 "vptest\t{$src2, $src1|$src1, $src2}",
6425                 [(set EFLAGS,(X86ptest VR256:$src1, (memopv4i64 addr:$src2)))]>,
6426                 OpSize, VEX;
6427 }
6428
6429 let Defs = [EFLAGS] in {
6430 def PTESTrr : SS48I<0x17, MRMSrcReg, (outs), (ins VR128:$src1, VR128:$src2),
6431               "ptest\t{$src2, $src1|$src1, $src2}",
6432               [(set EFLAGS, (X86ptest VR128:$src1, (v4f32 VR128:$src2)))]>,
6433               OpSize;
6434 def PTESTrm : SS48I<0x17, MRMSrcMem, (outs), (ins VR128:$src1, f128mem:$src2),
6435               "ptest\t{$src2, $src1|$src1, $src2}",
6436               [(set EFLAGS, (X86ptest VR128:$src1, (memopv4f32 addr:$src2)))]>,
6437               OpSize;
6438 }
6439
6440 // The bit test instructions below are AVX only
6441 multiclass avx_bittest<bits<8> opc, string OpcodeStr, RegisterClass RC,
6442                        X86MemOperand x86memop, PatFrag mem_frag, ValueType vt> {
6443   def rr : SS48I<opc, MRMSrcReg, (outs), (ins RC:$src1, RC:$src2),
6444             !strconcat(OpcodeStr, "\t{$src2, $src1|$src1, $src2}"),
6445             [(set EFLAGS, (X86testp RC:$src1, (vt RC:$src2)))]>, OpSize, VEX;
6446   def rm : SS48I<opc, MRMSrcMem, (outs), (ins RC:$src1, x86memop:$src2),
6447             !strconcat(OpcodeStr, "\t{$src2, $src1|$src1, $src2}"),
6448             [(set EFLAGS, (X86testp RC:$src1, (mem_frag addr:$src2)))]>,
6449             OpSize, VEX;
6450 }
6451
6452 let Defs = [EFLAGS], Predicates = [HasAVX] in {
6453 let ExeDomain = SSEPackedSingle in {
6454 defm VTESTPS  : avx_bittest<0x0E, "vtestps", VR128, f128mem, memopv4f32, v4f32>;
6455 defm VTESTPSY : avx_bittest<0x0E, "vtestps", VR256, f256mem, memopv8f32, v8f32>;
6456 }
6457 let ExeDomain = SSEPackedDouble in {
6458 defm VTESTPD  : avx_bittest<0x0F, "vtestpd", VR128, f128mem, memopv2f64, v2f64>;
6459 defm VTESTPDY : avx_bittest<0x0F, "vtestpd", VR256, f256mem, memopv4f64, v4f64>;
6460 }
6461 }
6462
6463 //===----------------------------------------------------------------------===//
6464 // SSE4.1 - Misc Instructions
6465 //===----------------------------------------------------------------------===//
6466
6467 let Defs = [EFLAGS], Predicates = [HasPOPCNT] in {
6468   def POPCNT16rr : I<0xB8, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
6469                      "popcnt{w}\t{$src, $dst|$dst, $src}",
6470                      [(set GR16:$dst, (ctpop GR16:$src)), (implicit EFLAGS)]>,
6471                      OpSize, XS;
6472   def POPCNT16rm : I<0xB8, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
6473                      "popcnt{w}\t{$src, $dst|$dst, $src}",
6474                      [(set GR16:$dst, (ctpop (loadi16 addr:$src))),
6475                       (implicit EFLAGS)]>, OpSize, XS;
6476
6477   def POPCNT32rr : I<0xB8, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
6478                      "popcnt{l}\t{$src, $dst|$dst, $src}",
6479                      [(set GR32:$dst, (ctpop GR32:$src)), (implicit EFLAGS)]>,
6480                      XS;
6481   def POPCNT32rm : I<0xB8, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
6482                      "popcnt{l}\t{$src, $dst|$dst, $src}",
6483                      [(set GR32:$dst, (ctpop (loadi32 addr:$src))),
6484                       (implicit EFLAGS)]>, XS;
6485
6486   def POPCNT64rr : RI<0xB8, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
6487                       "popcnt{q}\t{$src, $dst|$dst, $src}",
6488                       [(set GR64:$dst, (ctpop GR64:$src)), (implicit EFLAGS)]>,
6489                       XS;
6490   def POPCNT64rm : RI<0xB8, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
6491                       "popcnt{q}\t{$src, $dst|$dst, $src}",
6492                       [(set GR64:$dst, (ctpop (loadi64 addr:$src))),
6493                        (implicit EFLAGS)]>, XS;
6494 }
6495
6496
6497
6498 // SS41I_unop_rm_int_v16 - SSE 4.1 unary operator whose type is v8i16.
6499 multiclass SS41I_unop_rm_int_v16<bits<8> opc, string OpcodeStr,
6500                                  Intrinsic IntId128> {
6501   def rr128 : SS48I<opc, MRMSrcReg, (outs VR128:$dst),
6502                     (ins VR128:$src),
6503                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
6504                     [(set VR128:$dst, (IntId128 VR128:$src))]>, OpSize;
6505   def rm128 : SS48I<opc, MRMSrcMem, (outs VR128:$dst),
6506                      (ins i128mem:$src),
6507                      !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
6508                      [(set VR128:$dst,
6509                        (IntId128
6510                         (bitconvert (memopv2i64 addr:$src))))]>, OpSize;
6511 }
6512
6513 let Predicates = [HasAVX] in
6514 defm VPHMINPOSUW : SS41I_unop_rm_int_v16 <0x41, "vphminposuw",
6515                                          int_x86_sse41_phminposuw>, VEX;
6516 defm PHMINPOSUW : SS41I_unop_rm_int_v16 <0x41, "phminposuw",
6517                                          int_x86_sse41_phminposuw>;
6518
6519 /// SS41I_binop_rm_int - Simple SSE 4.1 binary operator
6520 multiclass SS41I_binop_rm_int<bits<8> opc, string OpcodeStr,
6521                               Intrinsic IntId128, bit Is2Addr = 1> {
6522   let isCommutable = 1 in
6523   def rr : SS48I<opc, MRMSrcReg, (outs VR128:$dst),
6524        (ins VR128:$src1, VR128:$src2),
6525        !if(Is2Addr,
6526            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
6527            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
6528        [(set VR128:$dst, (IntId128 VR128:$src1, VR128:$src2))]>, OpSize;
6529   def rm : SS48I<opc, MRMSrcMem, (outs VR128:$dst),
6530        (ins VR128:$src1, i128mem:$src2),
6531        !if(Is2Addr,
6532            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
6533            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
6534        [(set VR128:$dst,
6535          (IntId128 VR128:$src1,
6536           (bitconvert (memopv2i64 addr:$src2))))]>, OpSize;
6537 }
6538
6539 /// SS41I_binop_rm_int - Simple SSE 4.1 binary operator
6540 multiclass SS41I_binop_rm_int_y<bits<8> opc, string OpcodeStr,
6541                                 Intrinsic IntId256> {
6542   let isCommutable = 1 in
6543   def Yrr : SS48I<opc, MRMSrcReg, (outs VR256:$dst),
6544        (ins VR256:$src1, VR256:$src2),
6545        !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6546        [(set VR256:$dst, (IntId256 VR256:$src1, VR256:$src2))]>, OpSize;
6547   def Yrm : SS48I<opc, MRMSrcMem, (outs VR256:$dst),
6548        (ins VR256:$src1, i256mem:$src2),
6549        !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6550        [(set VR256:$dst,
6551          (IntId256 VR256:$src1,
6552           (bitconvert (memopv4i64 addr:$src2))))]>, OpSize;
6553 }
6554
6555 let Predicates = [HasAVX] in {
6556   let isCommutable = 0 in
6557   defm VPACKUSDW : SS41I_binop_rm_int<0x2B, "vpackusdw", int_x86_sse41_packusdw,
6558                                                          0>, VEX_4V;
6559   defm VPCMPEQQ  : SS41I_binop_rm_int<0x29, "vpcmpeqq",  int_x86_sse41_pcmpeqq,
6560                                                          0>, VEX_4V;
6561   defm VPMINSB   : SS41I_binop_rm_int<0x38, "vpminsb",   int_x86_sse41_pminsb,
6562                                                          0>, VEX_4V;
6563   defm VPMINSD   : SS41I_binop_rm_int<0x39, "vpminsd",   int_x86_sse41_pminsd,
6564                                                          0>, VEX_4V;
6565   defm VPMINUD   : SS41I_binop_rm_int<0x3B, "vpminud",   int_x86_sse41_pminud,
6566                                                          0>, VEX_4V;
6567   defm VPMINUW   : SS41I_binop_rm_int<0x3A, "vpminuw",   int_x86_sse41_pminuw,
6568                                                          0>, VEX_4V;
6569   defm VPMAXSB   : SS41I_binop_rm_int<0x3C, "vpmaxsb",   int_x86_sse41_pmaxsb,
6570                                                          0>, VEX_4V;
6571   defm VPMAXSD   : SS41I_binop_rm_int<0x3D, "vpmaxsd",   int_x86_sse41_pmaxsd,
6572                                                          0>, VEX_4V;
6573   defm VPMAXUD   : SS41I_binop_rm_int<0x3F, "vpmaxud",   int_x86_sse41_pmaxud,
6574                                                          0>, VEX_4V;
6575   defm VPMAXUW   : SS41I_binop_rm_int<0x3E, "vpmaxuw",   int_x86_sse41_pmaxuw,
6576                                                          0>, VEX_4V;
6577   defm VPMULDQ   : SS41I_binop_rm_int<0x28, "vpmuldq",   int_x86_sse41_pmuldq,
6578                                                          0>, VEX_4V;
6579
6580   def : Pat<(v2i64 (X86pcmpeq VR128:$src1, VR128:$src2)),
6581             (VPCMPEQQrr VR128:$src1, VR128:$src2)>;
6582   def : Pat<(v2i64 (X86pcmpeq VR128:$src1, (memop addr:$src2))),
6583             (VPCMPEQQrm VR128:$src1, addr:$src2)>;
6584 }
6585
6586 let Predicates = [HasAVX2] in {
6587   let isCommutable = 0 in
6588   defm VPACKUSDW : SS41I_binop_rm_int_y<0x2B, "vpackusdw",
6589                                         int_x86_avx2_packusdw>, VEX_4V;
6590   defm VPCMPEQQ  : SS41I_binop_rm_int_y<0x29, "vpcmpeqq",
6591                                         int_x86_avx2_pcmpeq_q>, VEX_4V;
6592   defm VPMINSB   : SS41I_binop_rm_int_y<0x38, "vpminsb",
6593                                         int_x86_avx2_pmins_b>, VEX_4V;
6594   defm VPMINSD   : SS41I_binop_rm_int_y<0x39, "vpminsd",
6595                                         int_x86_avx2_pmins_d>, VEX_4V;
6596   defm VPMINUD   : SS41I_binop_rm_int_y<0x3B, "vpminud",
6597                                         int_x86_avx2_pminu_d>, VEX_4V;
6598   defm VPMINUW   : SS41I_binop_rm_int_y<0x3A, "vpminuw",
6599                                         int_x86_avx2_pminu_w>, VEX_4V;
6600   defm VPMAXSB   : SS41I_binop_rm_int_y<0x3C, "vpmaxsb",
6601                                         int_x86_avx2_pmaxs_b>, VEX_4V;
6602   defm VPMAXSD   : SS41I_binop_rm_int_y<0x3D, "vpmaxsd",
6603                                         int_x86_avx2_pmaxs_d>, VEX_4V;
6604   defm VPMAXUD   : SS41I_binop_rm_int_y<0x3F, "vpmaxud",
6605                                         int_x86_avx2_pmaxu_d>, VEX_4V;
6606   defm VPMAXUW   : SS41I_binop_rm_int_y<0x3E, "vpmaxuw",
6607                                         int_x86_avx2_pmaxu_w>, VEX_4V;
6608   defm VPMULDQ   : SS41I_binop_rm_int_y<0x28, "vpmuldq",
6609                                         int_x86_avx2_pmul_dq>, VEX_4V;
6610
6611   def : Pat<(v4i64 (X86pcmpeq VR256:$src1, VR256:$src2)),
6612             (VPCMPEQQYrr VR256:$src1, VR256:$src2)>;
6613   def : Pat<(v4i64 (X86pcmpeq VR256:$src1, (memop addr:$src2))),
6614             (VPCMPEQQYrm VR256:$src1, addr:$src2)>;
6615 }
6616
6617 let Constraints = "$src1 = $dst" in {
6618   let isCommutable = 0 in
6619   defm PACKUSDW : SS41I_binop_rm_int<0x2B, "packusdw", int_x86_sse41_packusdw>;
6620   defm PCMPEQQ  : SS41I_binop_rm_int<0x29, "pcmpeqq",  int_x86_sse41_pcmpeqq>;
6621   defm PMINSB   : SS41I_binop_rm_int<0x38, "pminsb",   int_x86_sse41_pminsb>;
6622   defm PMINSD   : SS41I_binop_rm_int<0x39, "pminsd",   int_x86_sse41_pminsd>;
6623   defm PMINUD   : SS41I_binop_rm_int<0x3B, "pminud",   int_x86_sse41_pminud>;
6624   defm PMINUW   : SS41I_binop_rm_int<0x3A, "pminuw",   int_x86_sse41_pminuw>;
6625   defm PMAXSB   : SS41I_binop_rm_int<0x3C, "pmaxsb",   int_x86_sse41_pmaxsb>;
6626   defm PMAXSD   : SS41I_binop_rm_int<0x3D, "pmaxsd",   int_x86_sse41_pmaxsd>;
6627   defm PMAXUD   : SS41I_binop_rm_int<0x3F, "pmaxud",   int_x86_sse41_pmaxud>;
6628   defm PMAXUW   : SS41I_binop_rm_int<0x3E, "pmaxuw",   int_x86_sse41_pmaxuw>;
6629   defm PMULDQ   : SS41I_binop_rm_int<0x28, "pmuldq",   int_x86_sse41_pmuldq>;
6630 }
6631
6632 let Predicates = [HasSSE41] in {
6633   def : Pat<(v2i64 (X86pcmpeq VR128:$src1, VR128:$src2)),
6634             (PCMPEQQrr VR128:$src1, VR128:$src2)>;
6635   def : Pat<(v2i64 (X86pcmpeq VR128:$src1, (memop addr:$src2))),
6636             (PCMPEQQrm VR128:$src1, addr:$src2)>;
6637 }
6638
6639 /// SS48I_binop_rm - Simple SSE41 binary operator.
6640 multiclass SS48I_binop_rm<bits<8> opc, string OpcodeStr, SDNode OpNode,
6641                           ValueType OpVT, bit Is2Addr = 1> {
6642   let isCommutable = 1 in
6643   def rr : SS48I<opc, MRMSrcReg, (outs VR128:$dst),
6644        (ins VR128:$src1, VR128:$src2),
6645        !if(Is2Addr,
6646            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
6647            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
6648        [(set VR128:$dst, (OpVT (OpNode VR128:$src1, VR128:$src2)))]>,
6649        OpSize;
6650   def rm : SS48I<opc, MRMSrcMem, (outs VR128:$dst),
6651        (ins VR128:$src1, i128mem:$src2),
6652        !if(Is2Addr,
6653            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
6654            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
6655        [(set VR128:$dst, (OpNode VR128:$src1,
6656                                   (bc_v4i32 (memopv2i64 addr:$src2))))]>,
6657        OpSize;
6658 }
6659
6660 /// SS48I_binop_rm - Simple SSE41 binary operator.
6661 multiclass SS48I_binop_rm_y<bits<8> opc, string OpcodeStr, SDNode OpNode,
6662                             ValueType OpVT> {
6663   let isCommutable = 1 in
6664   def Yrr : SS48I<opc, MRMSrcReg, (outs VR256:$dst),
6665        (ins VR256:$src1, VR256:$src2),
6666        !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6667        [(set VR256:$dst, (OpVT (OpNode VR256:$src1, VR256:$src2)))]>,
6668        OpSize;
6669   def Yrm : SS48I<opc, MRMSrcMem, (outs VR256:$dst),
6670        (ins VR256:$src1, i256mem:$src2),
6671        !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6672        [(set VR256:$dst, (OpNode VR256:$src1,
6673                                   (bc_v8i32 (memopv4i64 addr:$src2))))]>,
6674        OpSize;
6675 }
6676
6677 let Predicates = [HasAVX] in
6678   defm VPMULLD : SS48I_binop_rm<0x40, "vpmulld", mul, v4i32, 0>, VEX_4V;
6679 let Predicates = [HasAVX2] in
6680   defm VPMULLD : SS48I_binop_rm_y<0x40, "vpmulld", mul, v8i32>, VEX_4V;
6681 let Constraints = "$src1 = $dst" in
6682   defm PMULLD : SS48I_binop_rm<0x40, "pmulld", mul, v4i32>;
6683
6684 /// SS41I_binop_rmi_int - SSE 4.1 binary operator with 8-bit immediate
6685 multiclass SS41I_binop_rmi_int<bits<8> opc, string OpcodeStr,
6686                  Intrinsic IntId, RegisterClass RC, PatFrag memop_frag,
6687                  X86MemOperand x86memop, bit Is2Addr = 1> {
6688   let isCommutable = 1 in
6689   def rri : SS4AIi8<opc, MRMSrcReg, (outs RC:$dst),
6690         (ins RC:$src1, RC:$src2, u32u8imm:$src3),
6691         !if(Is2Addr,
6692             !strconcat(OpcodeStr,
6693                 "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6694             !strconcat(OpcodeStr,
6695                 "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6696         [(set RC:$dst, (IntId RC:$src1, RC:$src2, imm:$src3))]>,
6697         OpSize;
6698   def rmi : SS4AIi8<opc, MRMSrcMem, (outs RC:$dst),
6699         (ins RC:$src1, x86memop:$src2, u32u8imm:$src3),
6700         !if(Is2Addr,
6701             !strconcat(OpcodeStr,
6702                 "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6703             !strconcat(OpcodeStr,
6704                 "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6705         [(set RC:$dst,
6706           (IntId RC:$src1,
6707            (bitconvert (memop_frag addr:$src2)), imm:$src3))]>,
6708         OpSize;
6709 }
6710
6711 let Predicates = [HasAVX] in {
6712   let isCommutable = 0 in {
6713     let ExeDomain = SSEPackedSingle in {
6714     defm VBLENDPS : SS41I_binop_rmi_int<0x0C, "vblendps", int_x86_sse41_blendps,
6715                                         VR128, memopv4f32, i128mem, 0>, VEX_4V;
6716     defm VBLENDPSY : SS41I_binop_rmi_int<0x0C, "vblendps",
6717               int_x86_avx_blend_ps_256, VR256, memopv8f32, i256mem, 0>, VEX_4V;
6718     }
6719     let ExeDomain = SSEPackedDouble in {
6720     defm VBLENDPD : SS41I_binop_rmi_int<0x0D, "vblendpd", int_x86_sse41_blendpd,
6721                                         VR128, memopv2f64, i128mem, 0>, VEX_4V;
6722     defm VBLENDPDY : SS41I_binop_rmi_int<0x0D, "vblendpd",
6723               int_x86_avx_blend_pd_256, VR256, memopv4f64, i256mem, 0>, VEX_4V;
6724     }
6725   defm VPBLENDW : SS41I_binop_rmi_int<0x0E, "vpblendw", int_x86_sse41_pblendw,
6726                                       VR128, memopv2i64, i128mem, 0>, VEX_4V;
6727   defm VMPSADBW : SS41I_binop_rmi_int<0x42, "vmpsadbw", int_x86_sse41_mpsadbw,
6728                                       VR128, memopv2i64, i128mem, 0>, VEX_4V;
6729   }
6730   let ExeDomain = SSEPackedSingle in
6731   defm VDPPS : SS41I_binop_rmi_int<0x40, "vdpps", int_x86_sse41_dpps,
6732                                    VR128, memopv4f32, i128mem, 0>, VEX_4V;
6733   let ExeDomain = SSEPackedDouble in
6734   defm VDPPD : SS41I_binop_rmi_int<0x41, "vdppd", int_x86_sse41_dppd,
6735                                    VR128, memopv2f64, i128mem, 0>, VEX_4V;
6736   let ExeDomain = SSEPackedSingle in
6737   defm VDPPSY : SS41I_binop_rmi_int<0x40, "vdpps", int_x86_avx_dp_ps_256,
6738                                    VR256, memopv8f32, i256mem, 0>, VEX_4V;
6739 }
6740
6741 let Predicates = [HasAVX2] in {
6742   let isCommutable = 0 in {
6743   defm VPBLENDWY : SS41I_binop_rmi_int<0x0E, "vpblendw", int_x86_avx2_pblendw,
6744                                        VR256, memopv4i64, i256mem, 0>, VEX_4V;
6745   defm VMPSADBWY : SS41I_binop_rmi_int<0x42, "vmpsadbw", int_x86_avx2_mpsadbw,
6746                                        VR256, memopv4i64, i256mem, 0>, VEX_4V;
6747   }
6748 }
6749
6750 let Constraints = "$src1 = $dst" in {
6751   let isCommutable = 0 in {
6752   let ExeDomain = SSEPackedSingle in
6753   defm BLENDPS : SS41I_binop_rmi_int<0x0C, "blendps", int_x86_sse41_blendps,
6754                                      VR128, memopv4f32, i128mem>;
6755   let ExeDomain = SSEPackedDouble in
6756   defm BLENDPD : SS41I_binop_rmi_int<0x0D, "blendpd", int_x86_sse41_blendpd,
6757                                      VR128, memopv2f64, i128mem>;
6758   defm PBLENDW : SS41I_binop_rmi_int<0x0E, "pblendw", int_x86_sse41_pblendw,
6759                                      VR128, memopv2i64, i128mem>;
6760   defm MPSADBW : SS41I_binop_rmi_int<0x42, "mpsadbw", int_x86_sse41_mpsadbw,
6761                                      VR128, memopv2i64, i128mem>;
6762   }
6763   let ExeDomain = SSEPackedSingle in
6764   defm DPPS : SS41I_binop_rmi_int<0x40, "dpps", int_x86_sse41_dpps,
6765                                   VR128, memopv4f32, i128mem>;
6766   let ExeDomain = SSEPackedDouble in
6767   defm DPPD : SS41I_binop_rmi_int<0x41, "dppd", int_x86_sse41_dppd,
6768                                   VR128, memopv2f64, i128mem>;
6769 }
6770
6771 /// SS41I_quaternary_int_avx - AVX SSE 4.1 with 4 operators
6772 multiclass SS41I_quaternary_int_avx<bits<8> opc, string OpcodeStr,
6773                                     RegisterClass RC, X86MemOperand x86memop,
6774                                     PatFrag mem_frag, Intrinsic IntId> {
6775   def rr : Ii8<opc, MRMSrcReg, (outs RC:$dst),
6776                   (ins RC:$src1, RC:$src2, RC:$src3),
6777                   !strconcat(OpcodeStr,
6778                     "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
6779                   [(set RC:$dst, (IntId RC:$src1, RC:$src2, RC:$src3))],
6780                   SSEPackedInt>, OpSize, TA, VEX_4V, VEX_I8IMM;
6781
6782   def rm : Ii8<opc, MRMSrcMem, (outs RC:$dst),
6783                   (ins RC:$src1, x86memop:$src2, RC:$src3),
6784                   !strconcat(OpcodeStr,
6785                     "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
6786                   [(set RC:$dst,
6787                         (IntId RC:$src1, (bitconvert (mem_frag addr:$src2)),
6788                                RC:$src3))],
6789                   SSEPackedInt>, OpSize, TA, VEX_4V, VEX_I8IMM;
6790 }
6791
6792 let Predicates = [HasAVX] in {
6793 let ExeDomain = SSEPackedDouble in {
6794 defm VBLENDVPD  : SS41I_quaternary_int_avx<0x4B, "vblendvpd", VR128, i128mem,
6795                                            memopv2f64, int_x86_sse41_blendvpd>;
6796 defm VBLENDVPDY : SS41I_quaternary_int_avx<0x4B, "vblendvpd", VR256, i256mem,
6797                                          memopv4f64, int_x86_avx_blendv_pd_256>;
6798 } // ExeDomain = SSEPackedDouble
6799 let ExeDomain = SSEPackedSingle in {
6800 defm VBLENDVPS  : SS41I_quaternary_int_avx<0x4A, "vblendvps", VR128, i128mem,
6801                                            memopv4f32, int_x86_sse41_blendvps>;
6802 defm VBLENDVPSY : SS41I_quaternary_int_avx<0x4A, "vblendvps", VR256, i256mem,
6803                                          memopv8f32, int_x86_avx_blendv_ps_256>;
6804 } // ExeDomain = SSEPackedSingle
6805 defm VPBLENDVB  : SS41I_quaternary_int_avx<0x4C, "vpblendvb", VR128, i128mem,
6806                                            memopv2i64, int_x86_sse41_pblendvb>;
6807 }
6808
6809 let Predicates = [HasAVX2] in {
6810 defm VPBLENDVBY : SS41I_quaternary_int_avx<0x4C, "vpblendvb", VR256, i256mem,
6811                                            memopv4i64, int_x86_avx2_pblendvb>;
6812 }
6813
6814 let Predicates = [HasAVX] in {
6815   def : Pat<(v16i8 (vselect (v16i8 VR128:$mask), (v16i8 VR128:$src1),
6816                             (v16i8 VR128:$src2))),
6817             (VPBLENDVBrr VR128:$src2, VR128:$src1, VR128:$mask)>;
6818   def : Pat<(v4i32 (vselect (v4i32 VR128:$mask), (v4i32 VR128:$src1),
6819                             (v4i32 VR128:$src2))),
6820             (VBLENDVPSrr VR128:$src2, VR128:$src1, VR128:$mask)>;
6821   def : Pat<(v4f32 (vselect (v4i32 VR128:$mask), (v4f32 VR128:$src1),
6822                             (v4f32 VR128:$src2))),
6823             (VBLENDVPSrr VR128:$src2, VR128:$src1, VR128:$mask)>;
6824   def : Pat<(v2i64 (vselect (v2i64 VR128:$mask), (v2i64 VR128:$src1),
6825                             (v2i64 VR128:$src2))),
6826             (VBLENDVPDrr VR128:$src2, VR128:$src1, VR128:$mask)>;
6827   def : Pat<(v2f64 (vselect (v2i64 VR128:$mask), (v2f64 VR128:$src1),
6828                             (v2f64 VR128:$src2))),
6829             (VBLENDVPDrr VR128:$src2, VR128:$src1, VR128:$mask)>;
6830   def : Pat<(v8i32 (vselect (v8i32 VR256:$mask), (v8i32 VR256:$src1),
6831                             (v8i32 VR256:$src2))),
6832             (VBLENDVPSYrr VR256:$src2, VR256:$src1, VR256:$mask)>;
6833   def : Pat<(v8f32 (vselect (v8i32 VR256:$mask), (v8f32 VR256:$src1),
6834                             (v8f32 VR256:$src2))),
6835             (VBLENDVPSYrr VR256:$src2, VR256:$src1, VR256:$mask)>;
6836   def : Pat<(v4i64 (vselect (v4i64 VR256:$mask), (v4i64 VR256:$src1),
6837                             (v4i64 VR256:$src2))),
6838             (VBLENDVPDYrr VR256:$src2, VR256:$src1, VR256:$mask)>;
6839   def : Pat<(v4f64 (vselect (v4i64 VR256:$mask), (v4f64 VR256:$src1),
6840                             (v4f64 VR256:$src2))),
6841             (VBLENDVPDYrr VR256:$src2, VR256:$src1, VR256:$mask)>;
6842 }
6843
6844 let Predicates = [HasAVX2] in {
6845   def : Pat<(v32i8 (vselect (v32i8 VR256:$mask), (v32i8 VR256:$src1),
6846                             (v32i8 VR256:$src2))),
6847             (VPBLENDVBYrr VR256:$src2, VR256:$src1, VR256:$mask)>;
6848 }
6849
6850 /// SS41I_ternary_int - SSE 4.1 ternary operator
6851 let Uses = [XMM0], Constraints = "$src1 = $dst" in {
6852   multiclass SS41I_ternary_int<bits<8> opc, string OpcodeStr, PatFrag mem_frag,
6853                                Intrinsic IntId> {
6854     def rr0 : SS48I<opc, MRMSrcReg, (outs VR128:$dst),
6855                     (ins VR128:$src1, VR128:$src2),
6856                     !strconcat(OpcodeStr,
6857                      "\t{$src2, $dst|$dst, $src2}"),
6858                     [(set VR128:$dst, (IntId VR128:$src1, VR128:$src2, XMM0))]>,
6859                     OpSize;
6860
6861     def rm0 : SS48I<opc, MRMSrcMem, (outs VR128:$dst),
6862                     (ins VR128:$src1, i128mem:$src2),
6863                     !strconcat(OpcodeStr,
6864                      "\t{$src2, $dst|$dst, $src2}"),
6865                     [(set VR128:$dst,
6866                       (IntId VR128:$src1,
6867                        (bitconvert (mem_frag addr:$src2)), XMM0))]>, OpSize;
6868   }
6869 }
6870
6871 let ExeDomain = SSEPackedDouble in
6872 defm BLENDVPD : SS41I_ternary_int<0x15, "blendvpd", memopv2f64,
6873                                   int_x86_sse41_blendvpd>;
6874 let ExeDomain = SSEPackedSingle in
6875 defm BLENDVPS : SS41I_ternary_int<0x14, "blendvps", memopv4f32,
6876                                   int_x86_sse41_blendvps>;
6877 defm PBLENDVB : SS41I_ternary_int<0x10, "pblendvb", memopv2i64,
6878                                   int_x86_sse41_pblendvb>;
6879
6880 let Predicates = [HasSSE41] in {
6881   def : Pat<(v16i8 (vselect (v16i8 XMM0), (v16i8 VR128:$src1),
6882                             (v16i8 VR128:$src2))),
6883             (PBLENDVBrr0 VR128:$src2, VR128:$src1)>;
6884   def : Pat<(v4i32 (vselect (v4i32 XMM0), (v4i32 VR128:$src1),
6885                             (v4i32 VR128:$src2))),
6886             (BLENDVPSrr0 VR128:$src2, VR128:$src1)>;
6887   def : Pat<(v4f32 (vselect (v4i32 XMM0), (v4f32 VR128:$src1),
6888                             (v4f32 VR128:$src2))),
6889             (BLENDVPSrr0 VR128:$src2, VR128:$src1)>;
6890   def : Pat<(v2i64 (vselect (v2i64 XMM0), (v2i64 VR128:$src1),
6891                             (v2i64 VR128:$src2))),
6892             (BLENDVPDrr0 VR128:$src2, VR128:$src1)>;
6893   def : Pat<(v2f64 (vselect (v2i64 XMM0), (v2f64 VR128:$src1),
6894                             (v2f64 VR128:$src2))),
6895             (BLENDVPDrr0 VR128:$src2, VR128:$src1)>;
6896 }
6897
6898 let Predicates = [HasAVX] in
6899 def VMOVNTDQArm : SS48I<0x2A, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
6900                        "vmovntdqa\t{$src, $dst|$dst, $src}",
6901                        [(set VR128:$dst, (int_x86_sse41_movntdqa addr:$src))]>,
6902                        OpSize, VEX;
6903 let Predicates = [HasAVX2] in
6904 def VMOVNTDQAYrm : SS48I<0x2A, MRMSrcMem, (outs VR256:$dst), (ins i256mem:$src),
6905                          "vmovntdqa\t{$src, $dst|$dst, $src}",
6906                          [(set VR256:$dst, (int_x86_avx2_movntdqa addr:$src))]>,
6907                          OpSize, VEX;
6908 def MOVNTDQArm : SS48I<0x2A, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
6909                        "movntdqa\t{$src, $dst|$dst, $src}",
6910                        [(set VR128:$dst, (int_x86_sse41_movntdqa addr:$src))]>,
6911                        OpSize;
6912
6913 //===----------------------------------------------------------------------===//
6914 // SSE4.2 - Compare Instructions
6915 //===----------------------------------------------------------------------===//
6916
6917 /// SS42I_binop_rm_int - Simple SSE 4.2 binary operator
6918 multiclass SS42I_binop_rm_int<bits<8> opc, string OpcodeStr,
6919                               Intrinsic IntId128, bit Is2Addr = 1> {
6920   def rr : SS428I<opc, MRMSrcReg, (outs VR128:$dst),
6921        (ins VR128:$src1, VR128:$src2),
6922        !if(Is2Addr,
6923            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
6924            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
6925        [(set VR128:$dst, (IntId128 VR128:$src1, VR128:$src2))]>,
6926        OpSize;
6927   def rm : SS428I<opc, MRMSrcMem, (outs VR128:$dst),
6928        (ins VR128:$src1, i128mem:$src2),
6929        !if(Is2Addr,
6930            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
6931            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
6932        [(set VR128:$dst,
6933          (IntId128 VR128:$src1, (memopv2i64 addr:$src2)))]>, OpSize;
6934 }
6935
6936 /// SS42I_binop_rm_int - Simple SSE 4.2 binary operator
6937 multiclass SS42I_binop_rm_int_y<bits<8> opc, string OpcodeStr,
6938                                 Intrinsic IntId256> {
6939   def Yrr : SS428I<opc, MRMSrcReg, (outs VR256:$dst),
6940        (ins VR256:$src1, VR256:$src2),
6941        !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6942        [(set VR256:$dst, (IntId256 VR256:$src1, VR256:$src2))]>,
6943        OpSize;
6944   def Yrm : SS428I<opc, MRMSrcMem, (outs VR256:$dst),
6945        (ins VR256:$src1, i256mem:$src2),
6946        !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6947        [(set VR256:$dst,
6948          (IntId256 VR256:$src1, (memopv4i64 addr:$src2)))]>, OpSize;
6949 }
6950
6951 let Predicates = [HasAVX] in {
6952   defm VPCMPGTQ : SS42I_binop_rm_int<0x37, "vpcmpgtq", int_x86_sse42_pcmpgtq,
6953                                      0>, VEX_4V;
6954
6955   def : Pat<(v2i64 (X86pcmpgt VR128:$src1, VR128:$src2)),
6956             (VPCMPGTQrr VR128:$src1, VR128:$src2)>;
6957   def : Pat<(v2i64 (X86pcmpgt VR128:$src1, (memop addr:$src2))),
6958             (VPCMPGTQrm VR128:$src1, addr:$src2)>;
6959 }
6960
6961 let Predicates = [HasAVX2] in {
6962   defm VPCMPGTQ : SS42I_binop_rm_int_y<0x37, "vpcmpgtq", int_x86_avx2_pcmpgt_q>,
6963                                        VEX_4V;
6964
6965   def : Pat<(v4i64 (X86pcmpgt VR256:$src1, VR256:$src2)),
6966             (VPCMPGTQYrr VR256:$src1, VR256:$src2)>;
6967   def : Pat<(v4i64 (X86pcmpgt VR256:$src1, (memop addr:$src2))),
6968             (VPCMPGTQYrm VR256:$src1, addr:$src2)>;
6969 }
6970
6971 let Constraints = "$src1 = $dst" in
6972   defm PCMPGTQ : SS42I_binop_rm_int<0x37, "pcmpgtq", int_x86_sse42_pcmpgtq>;
6973
6974 let Predicates = [HasSSE42] in {
6975   def : Pat<(v2i64 (X86pcmpgt VR128:$src1, VR128:$src2)),
6976             (PCMPGTQrr VR128:$src1, VR128:$src2)>;
6977   def : Pat<(v2i64 (X86pcmpgt VR128:$src1, (memop addr:$src2))),
6978             (PCMPGTQrm VR128:$src1, addr:$src2)>;
6979 }
6980
6981 //===----------------------------------------------------------------------===//
6982 // SSE4.2 - String/text Processing Instructions
6983 //===----------------------------------------------------------------------===//
6984
6985 // Packed Compare Implicit Length Strings, Return Mask
6986 multiclass pseudo_pcmpistrm<string asm> {
6987   def REG : PseudoI<(outs VR128:$dst),
6988                     (ins VR128:$src1, VR128:$src2, i8imm:$src3),
6989     [(set VR128:$dst, (int_x86_sse42_pcmpistrm128 VR128:$src1, VR128:$src2,
6990                                                   imm:$src3))]>;
6991   def MEM : PseudoI<(outs VR128:$dst),
6992                     (ins VR128:$src1, i128mem:$src2, i8imm:$src3),
6993     [(set VR128:$dst, (int_x86_sse42_pcmpistrm128
6994                        VR128:$src1, (load addr:$src2), imm:$src3))]>;
6995 }
6996
6997 let Defs = [EFLAGS], usesCustomInserter = 1 in {
6998   defm PCMPISTRM128 : pseudo_pcmpistrm<"#PCMPISTRM128">, Requires<[HasSSE42]>;
6999   defm VPCMPISTRM128 : pseudo_pcmpistrm<"#VPCMPISTRM128">, Requires<[HasAVX]>;
7000 }
7001
7002 let Defs = [XMM0, EFLAGS], neverHasSideEffects = 1, Predicates = [HasAVX] in {
7003   def VPCMPISTRM128rr : SS42AI<0x62, MRMSrcReg, (outs),
7004       (ins VR128:$src1, VR128:$src2, i8imm:$src3),
7005       "vpcmpistrm\t{$src3, $src2, $src1|$src1, $src2, $src3}", []>, OpSize, VEX;
7006   let mayLoad = 1 in
7007   def VPCMPISTRM128rm : SS42AI<0x62, MRMSrcMem, (outs),
7008       (ins VR128:$src1, i128mem:$src2, i8imm:$src3),
7009       "vpcmpistrm\t{$src3, $src2, $src1|$src1, $src2, $src3}", []>, OpSize, VEX;
7010 }
7011
7012 let Defs = [XMM0, EFLAGS], neverHasSideEffects = 1 in {
7013   def PCMPISTRM128rr : SS42AI<0x62, MRMSrcReg, (outs),
7014       (ins VR128:$src1, VR128:$src2, i8imm:$src3),
7015       "pcmpistrm\t{$src3, $src2, $src1|$src1, $src2, $src3}", []>, OpSize;
7016   let mayLoad = 1 in
7017   def PCMPISTRM128rm : SS42AI<0x62, MRMSrcMem, (outs),
7018       (ins VR128:$src1, i128mem:$src2, i8imm:$src3),
7019       "pcmpistrm\t{$src3, $src2, $src1|$src1, $src2, $src3}", []>, OpSize;
7020 }
7021
7022 // Packed Compare Explicit Length Strings, Return Mask
7023 multiclass pseudo_pcmpestrm<string asm> {
7024   def REG : PseudoI<(outs VR128:$dst),
7025                     (ins VR128:$src1, VR128:$src3, i8imm:$src5),
7026     [(set VR128:$dst, (int_x86_sse42_pcmpestrm128
7027                        VR128:$src1, EAX, VR128:$src3, EDX, imm:$src5))]>;
7028   def MEM : PseudoI<(outs VR128:$dst),
7029                     (ins VR128:$src1, i128mem:$src3, i8imm:$src5),
7030     [(set VR128:$dst, (int_x86_sse42_pcmpestrm128
7031                        VR128:$src1, EAX, (load addr:$src3), EDX, imm:$src5))]>;
7032 }
7033
7034 let Defs = [EFLAGS], Uses = [EAX, EDX], usesCustomInserter = 1 in {
7035   defm PCMPESTRM128 : pseudo_pcmpestrm<"#PCMPESTRM128">, Requires<[HasSSE42]>;
7036   defm VPCMPESTRM128 : pseudo_pcmpestrm<"#VPCMPESTRM128">, Requires<[HasAVX]>;
7037 }
7038
7039 let Predicates = [HasAVX],
7040     Defs = [XMM0, EFLAGS], Uses = [EAX, EDX], neverHasSideEffects = 1 in {
7041   def VPCMPESTRM128rr : SS42AI<0x60, MRMSrcReg, (outs),
7042       (ins VR128:$src1, VR128:$src3, i8imm:$src5),
7043       "vpcmpestrm\t{$src5, $src3, $src1|$src1, $src3, $src5}", []>, OpSize, VEX;
7044   let mayLoad = 1 in
7045   def VPCMPESTRM128rm : SS42AI<0x60, MRMSrcMem, (outs),
7046       (ins VR128:$src1, i128mem:$src3, i8imm:$src5),
7047       "vpcmpestrm\t{$src5, $src3, $src1|$src1, $src3, $src5}", []>, OpSize, VEX;
7048 }
7049
7050 let Defs = [XMM0, EFLAGS], Uses = [EAX, EDX], neverHasSideEffects = 1 in {
7051   def PCMPESTRM128rr : SS42AI<0x60, MRMSrcReg, (outs),
7052       (ins VR128:$src1, VR128:$src3, i8imm:$src5),
7053       "pcmpestrm\t{$src5, $src3, $src1|$src1, $src3, $src5}", []>, OpSize;
7054   let mayLoad = 1 in
7055   def PCMPESTRM128rm : SS42AI<0x60, MRMSrcMem, (outs),
7056       (ins VR128:$src1, i128mem:$src3, i8imm:$src5),
7057       "pcmpestrm\t{$src5, $src3, $src1|$src1, $src3, $src5}", []>, OpSize;
7058 }
7059
7060 // Packed Compare Implicit Length Strings, Return Index
7061 let Defs = [ECX, EFLAGS] in {
7062   multiclass SS42AI_pcmpistri<Intrinsic IntId128, string asm = "pcmpistri"> {
7063     def rr : SS42AI<0x63, MRMSrcReg, (outs),
7064       (ins VR128:$src1, VR128:$src2, i8imm:$src3),
7065       !strconcat(asm, "\t{$src3, $src2, $src1|$src1, $src2, $src3}"),
7066       [(set ECX, (IntId128 VR128:$src1, VR128:$src2, imm:$src3)),
7067        (implicit EFLAGS)]>, OpSize;
7068     def rm : SS42AI<0x63, MRMSrcMem, (outs),
7069       (ins VR128:$src1, i128mem:$src2, i8imm:$src3),
7070       !strconcat(asm, "\t{$src3, $src2, $src1|$src1, $src2, $src3}"),
7071       [(set ECX, (IntId128 VR128:$src1, (load addr:$src2), imm:$src3)),
7072        (implicit EFLAGS)]>, OpSize;
7073   }
7074 }
7075
7076 let Predicates = [HasAVX] in {
7077 defm VPCMPISTRI  : SS42AI_pcmpistri<int_x86_sse42_pcmpistri128, "vpcmpistri">,
7078                                     VEX;
7079 defm VPCMPISTRIA : SS42AI_pcmpistri<int_x86_sse42_pcmpistria128, "vpcmpistri">,
7080                                     VEX;
7081 defm VPCMPISTRIC : SS42AI_pcmpistri<int_x86_sse42_pcmpistric128, "vpcmpistri">,
7082                                     VEX;
7083 defm VPCMPISTRIO : SS42AI_pcmpistri<int_x86_sse42_pcmpistrio128, "vpcmpistri">,
7084                                     VEX;
7085 defm VPCMPISTRIS : SS42AI_pcmpistri<int_x86_sse42_pcmpistris128, "vpcmpistri">,
7086                                     VEX;
7087 defm VPCMPISTRIZ : SS42AI_pcmpistri<int_x86_sse42_pcmpistriz128, "vpcmpistri">,
7088                                     VEX;
7089 }
7090
7091 defm PCMPISTRI  : SS42AI_pcmpistri<int_x86_sse42_pcmpistri128>;
7092 defm PCMPISTRIA : SS42AI_pcmpistri<int_x86_sse42_pcmpistria128>;
7093 defm PCMPISTRIC : SS42AI_pcmpistri<int_x86_sse42_pcmpistric128>;
7094 defm PCMPISTRIO : SS42AI_pcmpistri<int_x86_sse42_pcmpistrio128>;
7095 defm PCMPISTRIS : SS42AI_pcmpistri<int_x86_sse42_pcmpistris128>;
7096 defm PCMPISTRIZ : SS42AI_pcmpistri<int_x86_sse42_pcmpistriz128>;
7097
7098 // Packed Compare Explicit Length Strings, Return Index
7099 let Defs = [ECX, EFLAGS], Uses = [EAX, EDX] in {
7100   multiclass SS42AI_pcmpestri<Intrinsic IntId128, string asm = "pcmpestri"> {
7101     def rr : SS42AI<0x61, MRMSrcReg, (outs),
7102       (ins VR128:$src1, VR128:$src3, i8imm:$src5),
7103       !strconcat(asm, "\t{$src5, $src3, $src1|$src1, $src3, $src5}"),
7104       [(set ECX, (IntId128 VR128:$src1, EAX, VR128:$src3, EDX, imm:$src5)),
7105        (implicit EFLAGS)]>, OpSize;
7106     def rm : SS42AI<0x61, MRMSrcMem, (outs),
7107       (ins VR128:$src1, i128mem:$src3, i8imm:$src5),
7108       !strconcat(asm, "\t{$src5, $src3, $src1|$src1, $src3, $src5}"),
7109        [(set ECX,
7110              (IntId128 VR128:$src1, EAX, (load addr:$src3), EDX, imm:$src5)),
7111         (implicit EFLAGS)]>, OpSize;
7112   }
7113 }
7114
7115 let Predicates = [HasAVX] in {
7116 defm VPCMPESTRI  : SS42AI_pcmpestri<int_x86_sse42_pcmpestri128, "vpcmpestri">,
7117                                     VEX;
7118 defm VPCMPESTRIA : SS42AI_pcmpestri<int_x86_sse42_pcmpestria128, "vpcmpestri">,
7119                                     VEX;
7120 defm VPCMPESTRIC : SS42AI_pcmpestri<int_x86_sse42_pcmpestric128, "vpcmpestri">,
7121                                     VEX;
7122 defm VPCMPESTRIO : SS42AI_pcmpestri<int_x86_sse42_pcmpestrio128, "vpcmpestri">,
7123                                     VEX;
7124 defm VPCMPESTRIS : SS42AI_pcmpestri<int_x86_sse42_pcmpestris128, "vpcmpestri">,
7125                                     VEX;
7126 defm VPCMPESTRIZ : SS42AI_pcmpestri<int_x86_sse42_pcmpestriz128, "vpcmpestri">,
7127                                     VEX;
7128 }
7129
7130 defm PCMPESTRI  : SS42AI_pcmpestri<int_x86_sse42_pcmpestri128>;
7131 defm PCMPESTRIA : SS42AI_pcmpestri<int_x86_sse42_pcmpestria128>;
7132 defm PCMPESTRIC : SS42AI_pcmpestri<int_x86_sse42_pcmpestric128>;
7133 defm PCMPESTRIO : SS42AI_pcmpestri<int_x86_sse42_pcmpestrio128>;
7134 defm PCMPESTRIS : SS42AI_pcmpestri<int_x86_sse42_pcmpestris128>;
7135 defm PCMPESTRIZ : SS42AI_pcmpestri<int_x86_sse42_pcmpestriz128>;
7136
7137 //===----------------------------------------------------------------------===//
7138 // SSE4.2 - CRC Instructions
7139 //===----------------------------------------------------------------------===//
7140
7141 // No CRC instructions have AVX equivalents
7142
7143 // crc intrinsic instruction
7144 // This set of instructions are only rm, the only difference is the size
7145 // of r and m.
7146 let Constraints = "$src1 = $dst" in {
7147   def CRC32r32m8  : SS42FI<0xF0, MRMSrcMem, (outs GR32:$dst),
7148                       (ins GR32:$src1, i8mem:$src2),
7149                       "crc32{b} \t{$src2, $src1|$src1, $src2}",
7150                        [(set GR32:$dst,
7151                          (int_x86_sse42_crc32_32_8 GR32:$src1,
7152                          (load addr:$src2)))]>;
7153   def CRC32r32r8  : SS42FI<0xF0, MRMSrcReg, (outs GR32:$dst),
7154                       (ins GR32:$src1, GR8:$src2),
7155                       "crc32{b} \t{$src2, $src1|$src1, $src2}",
7156                        [(set GR32:$dst,
7157                          (int_x86_sse42_crc32_32_8 GR32:$src1, GR8:$src2))]>;
7158   def CRC32r32m16  : SS42FI<0xF1, MRMSrcMem, (outs GR32:$dst),
7159                       (ins GR32:$src1, i16mem:$src2),
7160                       "crc32{w} \t{$src2, $src1|$src1, $src2}",
7161                        [(set GR32:$dst,
7162                          (int_x86_sse42_crc32_32_16 GR32:$src1,
7163                          (load addr:$src2)))]>,
7164                          OpSize;
7165   def CRC32r32r16  : SS42FI<0xF1, MRMSrcReg, (outs GR32:$dst),
7166                       (ins GR32:$src1, GR16:$src2),
7167                       "crc32{w} \t{$src2, $src1|$src1, $src2}",
7168                        [(set GR32:$dst,
7169                          (int_x86_sse42_crc32_32_16 GR32:$src1, GR16:$src2))]>,
7170                          OpSize;
7171   def CRC32r32m32  : SS42FI<0xF1, MRMSrcMem, (outs GR32:$dst),
7172                       (ins GR32:$src1, i32mem:$src2),
7173                       "crc32{l} \t{$src2, $src1|$src1, $src2}",
7174                        [(set GR32:$dst,
7175                          (int_x86_sse42_crc32_32_32 GR32:$src1,
7176                          (load addr:$src2)))]>;
7177   def CRC32r32r32  : SS42FI<0xF1, MRMSrcReg, (outs GR32:$dst),
7178                       (ins GR32:$src1, GR32:$src2),
7179                       "crc32{l} \t{$src2, $src1|$src1, $src2}",
7180                        [(set GR32:$dst,
7181                          (int_x86_sse42_crc32_32_32 GR32:$src1, GR32:$src2))]>;
7182   def CRC32r64m8  : SS42FI<0xF0, MRMSrcMem, (outs GR64:$dst),
7183                       (ins GR64:$src1, i8mem:$src2),
7184                       "crc32{b} \t{$src2, $src1|$src1, $src2}",
7185                        [(set GR64:$dst,
7186                          (int_x86_sse42_crc32_64_8 GR64:$src1,
7187                          (load addr:$src2)))]>,
7188                          REX_W;
7189   def CRC32r64r8  : SS42FI<0xF0, MRMSrcReg, (outs GR64:$dst),
7190                       (ins GR64:$src1, GR8:$src2),
7191                       "crc32{b} \t{$src2, $src1|$src1, $src2}",
7192                        [(set GR64:$dst,
7193                          (int_x86_sse42_crc32_64_8 GR64:$src1, GR8:$src2))]>,
7194                          REX_W;
7195   def CRC32r64m64  : SS42FI<0xF1, MRMSrcMem, (outs GR64:$dst),
7196                       (ins GR64:$src1, i64mem:$src2),
7197                       "crc32{q} \t{$src2, $src1|$src1, $src2}",
7198                        [(set GR64:$dst,
7199                          (int_x86_sse42_crc32_64_64 GR64:$src1,
7200                          (load addr:$src2)))]>,
7201                          REX_W;
7202   def CRC32r64r64  : SS42FI<0xF1, MRMSrcReg, (outs GR64:$dst),
7203                       (ins GR64:$src1, GR64:$src2),
7204                       "crc32{q} \t{$src2, $src1|$src1, $src2}",
7205                        [(set GR64:$dst,
7206                          (int_x86_sse42_crc32_64_64 GR64:$src1, GR64:$src2))]>,
7207                          REX_W;
7208 }
7209
7210 //===----------------------------------------------------------------------===//
7211 // AES-NI Instructions
7212 //===----------------------------------------------------------------------===//
7213
7214 multiclass AESI_binop_rm_int<bits<8> opc, string OpcodeStr,
7215                               Intrinsic IntId128, bit Is2Addr = 1> {
7216   def rr : AES8I<opc, MRMSrcReg, (outs VR128:$dst),
7217        (ins VR128:$src1, VR128:$src2),
7218        !if(Is2Addr,
7219            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
7220            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
7221        [(set VR128:$dst, (IntId128 VR128:$src1, VR128:$src2))]>,
7222        OpSize;
7223   def rm : AES8I<opc, MRMSrcMem, (outs VR128:$dst),
7224        (ins VR128:$src1, i128mem:$src2),
7225        !if(Is2Addr,
7226            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
7227            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
7228        [(set VR128:$dst,
7229          (IntId128 VR128:$src1, (memopv2i64 addr:$src2)))]>, OpSize;
7230 }
7231
7232 // Perform One Round of an AES Encryption/Decryption Flow
7233 let Predicates = [HasAVX, HasAES] in {
7234   defm VAESENC          : AESI_binop_rm_int<0xDC, "vaesenc",
7235                          int_x86_aesni_aesenc, 0>, VEX_4V;
7236   defm VAESENCLAST      : AESI_binop_rm_int<0xDD, "vaesenclast",
7237                          int_x86_aesni_aesenclast, 0>, VEX_4V;
7238   defm VAESDEC          : AESI_binop_rm_int<0xDE, "vaesdec",
7239                          int_x86_aesni_aesdec, 0>, VEX_4V;
7240   defm VAESDECLAST      : AESI_binop_rm_int<0xDF, "vaesdeclast",
7241                          int_x86_aesni_aesdeclast, 0>, VEX_4V;
7242 }
7243
7244 let Constraints = "$src1 = $dst" in {
7245   defm AESENC          : AESI_binop_rm_int<0xDC, "aesenc",
7246                          int_x86_aesni_aesenc>;
7247   defm AESENCLAST      : AESI_binop_rm_int<0xDD, "aesenclast",
7248                          int_x86_aesni_aesenclast>;
7249   defm AESDEC          : AESI_binop_rm_int<0xDE, "aesdec",
7250                          int_x86_aesni_aesdec>;
7251   defm AESDECLAST      : AESI_binop_rm_int<0xDF, "aesdeclast",
7252                          int_x86_aesni_aesdeclast>;
7253 }
7254
7255 // Perform the AES InvMixColumn Transformation
7256 let Predicates = [HasAVX, HasAES] in {
7257   def VAESIMCrr : AES8I<0xDB, MRMSrcReg, (outs VR128:$dst),
7258       (ins VR128:$src1),
7259       "vaesimc\t{$src1, $dst|$dst, $src1}",
7260       [(set VR128:$dst,
7261         (int_x86_aesni_aesimc VR128:$src1))]>,
7262       OpSize, VEX;
7263   def VAESIMCrm : AES8I<0xDB, MRMSrcMem, (outs VR128:$dst),
7264       (ins i128mem:$src1),
7265       "vaesimc\t{$src1, $dst|$dst, $src1}",
7266       [(set VR128:$dst, (int_x86_aesni_aesimc (memopv2i64 addr:$src1)))]>,
7267       OpSize, VEX;
7268 }
7269 def AESIMCrr : AES8I<0xDB, MRMSrcReg, (outs VR128:$dst),
7270   (ins VR128:$src1),
7271   "aesimc\t{$src1, $dst|$dst, $src1}",
7272   [(set VR128:$dst,
7273     (int_x86_aesni_aesimc VR128:$src1))]>,
7274   OpSize;
7275 def AESIMCrm : AES8I<0xDB, MRMSrcMem, (outs VR128:$dst),
7276   (ins i128mem:$src1),
7277   "aesimc\t{$src1, $dst|$dst, $src1}",
7278   [(set VR128:$dst, (int_x86_aesni_aesimc (memopv2i64 addr:$src1)))]>,
7279   OpSize;
7280
7281 // AES Round Key Generation Assist
7282 let Predicates = [HasAVX, HasAES] in {
7283   def VAESKEYGENASSIST128rr : AESAI<0xDF, MRMSrcReg, (outs VR128:$dst),
7284       (ins VR128:$src1, i8imm:$src2),
7285       "vaeskeygenassist\t{$src2, $src1, $dst|$dst, $src1, $src2}",
7286       [(set VR128:$dst,
7287         (int_x86_aesni_aeskeygenassist VR128:$src1, imm:$src2))]>,
7288       OpSize, VEX;
7289   def VAESKEYGENASSIST128rm : AESAI<0xDF, MRMSrcMem, (outs VR128:$dst),
7290       (ins i128mem:$src1, i8imm:$src2),
7291       "vaeskeygenassist\t{$src2, $src1, $dst|$dst, $src1, $src2}",
7292       [(set VR128:$dst,
7293         (int_x86_aesni_aeskeygenassist (memopv2i64 addr:$src1), imm:$src2))]>,
7294       OpSize, VEX;
7295 }
7296 def AESKEYGENASSIST128rr : AESAI<0xDF, MRMSrcReg, (outs VR128:$dst),
7297   (ins VR128:$src1, i8imm:$src2),
7298   "aeskeygenassist\t{$src2, $src1, $dst|$dst, $src1, $src2}",
7299   [(set VR128:$dst,
7300     (int_x86_aesni_aeskeygenassist VR128:$src1, imm:$src2))]>,
7301   OpSize;
7302 def AESKEYGENASSIST128rm : AESAI<0xDF, MRMSrcMem, (outs VR128:$dst),
7303   (ins i128mem:$src1, i8imm:$src2),
7304   "aeskeygenassist\t{$src2, $src1, $dst|$dst, $src1, $src2}",
7305   [(set VR128:$dst,
7306     (int_x86_aesni_aeskeygenassist (memopv2i64 addr:$src1), imm:$src2))]>,
7307   OpSize;
7308
7309 //===----------------------------------------------------------------------===//
7310 // CLMUL Instructions
7311 //===----------------------------------------------------------------------===//
7312
7313 // Carry-less Multiplication instructions
7314 let neverHasSideEffects = 1 in {
7315 // AVX carry-less Multiplication instructions
7316 def VPCLMULQDQrr : AVXCLMULIi8<0x44, MRMSrcReg, (outs VR128:$dst),
7317            (ins VR128:$src1, VR128:$src2, i8imm:$src3),
7318            "vpclmulqdq\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
7319            []>;
7320
7321 let mayLoad = 1 in
7322 def VPCLMULQDQrm : AVXCLMULIi8<0x44, MRMSrcMem, (outs VR128:$dst),
7323            (ins VR128:$src1, i128mem:$src2, i8imm:$src3),
7324            "vpclmulqdq\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
7325            []>;
7326
7327 let Constraints = "$src1 = $dst" in {
7328 def PCLMULQDQrr : CLMULIi8<0x44, MRMSrcReg, (outs VR128:$dst),
7329            (ins VR128:$src1, VR128:$src2, i8imm:$src3),
7330            "pclmulqdq\t{$src3, $src2, $dst|$dst, $src2, $src3}",
7331            []>;
7332
7333 let mayLoad = 1 in
7334 def PCLMULQDQrm : CLMULIi8<0x44, MRMSrcMem, (outs VR128:$dst),
7335            (ins VR128:$src1, i128mem:$src2, i8imm:$src3),
7336            "pclmulqdq\t{$src3, $src2, $dst|$dst, $src2, $src3}",
7337            []>;
7338 } // Constraints = "$src1 = $dst"
7339 } // neverHasSideEffects = 1
7340
7341
7342 multiclass pclmul_alias<string asm, int immop> {
7343   def : InstAlias<!strconcat("pclmul", asm, 
7344                            "dq {$src, $dst|$dst, $src}"),
7345                   (PCLMULQDQrr VR128:$dst, VR128:$src, immop)>;
7346
7347   def : InstAlias<!strconcat("pclmul", asm, 
7348                              "dq {$src, $dst|$dst, $src}"),
7349                   (PCLMULQDQrm VR128:$dst, i128mem:$src, immop)>;
7350
7351   def : InstAlias<!strconcat("vpclmul", asm, 
7352                              "dq {$src2, $src1, $dst|$dst, $src1, $src2}"),
7353                   (VPCLMULQDQrr VR128:$dst, VR128:$src1, VR128:$src2, immop)>;
7354
7355   def : InstAlias<!strconcat("vpclmul", asm, 
7356                              "dq {$src2, $src1, $dst|$dst, $src1, $src2}"),
7357                   (VPCLMULQDQrm VR128:$dst, VR128:$src1, i128mem:$src2, immop)>;
7358 }
7359 defm : pclmul_alias<"hqhq", 0x11>;
7360 defm : pclmul_alias<"hqlq", 0x01>;
7361 defm : pclmul_alias<"lqhq", 0x10>;
7362 defm : pclmul_alias<"lqlq", 0x00>;
7363
7364 //===----------------------------------------------------------------------===//
7365 // AVX Instructions
7366 //===----------------------------------------------------------------------===//
7367
7368 //===----------------------------------------------------------------------===//
7369 // VBROADCAST - Load from memory and broadcast to all elements of the
7370 //              destination operand
7371 //
7372 class avx_broadcast<bits<8> opc, string OpcodeStr, RegisterClass RC,
7373                     X86MemOperand x86memop, Intrinsic Int> :
7374   AVX8I<opc, MRMSrcMem, (outs RC:$dst), (ins x86memop:$src),
7375         !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
7376         [(set RC:$dst, (Int addr:$src))]>, VEX;
7377
7378 // AVX2 adds register forms
7379 class avx2_broadcast_reg<bits<8> opc, string OpcodeStr, RegisterClass RC,
7380                          Intrinsic Int> :
7381   AVX28I<opc, MRMSrcReg, (outs RC:$dst), (ins VR128:$src),
7382          !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
7383          [(set RC:$dst, (Int VR128:$src))]>, VEX;
7384
7385 let ExeDomain = SSEPackedSingle in {
7386   def VBROADCASTSSrm  : avx_broadcast<0x18, "vbroadcastss", VR128, f32mem,
7387                                       int_x86_avx_vbroadcast_ss>;
7388   def VBROADCASTSSYrm : avx_broadcast<0x18, "vbroadcastss", VR256, f32mem,
7389                                       int_x86_avx_vbroadcast_ss_256>;
7390 }
7391 let ExeDomain = SSEPackedDouble in
7392 def VBROADCASTSDrm  : avx_broadcast<0x19, "vbroadcastsd", VR256, f64mem,
7393                                     int_x86_avx_vbroadcast_sd_256>;
7394 def VBROADCASTF128 : avx_broadcast<0x1A, "vbroadcastf128", VR256, f128mem,
7395                                    int_x86_avx_vbroadcastf128_pd_256>;
7396
7397 let ExeDomain = SSEPackedSingle in {
7398   def VBROADCASTSSrr  : avx2_broadcast_reg<0x18, "vbroadcastss", VR128,
7399                                            int_x86_avx2_vbroadcast_ss_ps>;
7400   def VBROADCASTSSYrr : avx2_broadcast_reg<0x18, "vbroadcastss", VR256,
7401                                            int_x86_avx2_vbroadcast_ss_ps_256>;
7402 }
7403 let ExeDomain = SSEPackedDouble in
7404 def VBROADCASTSDrr  : avx2_broadcast_reg<0x19, "vbroadcastsd", VR256,
7405                                          int_x86_avx2_vbroadcast_sd_pd_256>;
7406
7407 let Predicates = [HasAVX2] in
7408 def VBROADCASTI128 : avx_broadcast<0x5A, "vbroadcasti128", VR256, i128mem,
7409                                    int_x86_avx2_vbroadcasti128>;
7410
7411 let Predicates = [HasAVX] in
7412 def : Pat<(int_x86_avx_vbroadcastf128_ps_256 addr:$src),
7413           (VBROADCASTF128 addr:$src)>;
7414
7415
7416 //===----------------------------------------------------------------------===//
7417 // VINSERTF128 - Insert packed floating-point values
7418 //
7419 let neverHasSideEffects = 1, ExeDomain = SSEPackedSingle in {
7420 def VINSERTF128rr : AVXAIi8<0x18, MRMSrcReg, (outs VR256:$dst),
7421           (ins VR256:$src1, VR128:$src2, i8imm:$src3),
7422           "vinsertf128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
7423           []>, VEX_4V;
7424 let mayLoad = 1 in
7425 def VINSERTF128rm : AVXAIi8<0x18, MRMSrcMem, (outs VR256:$dst),
7426           (ins VR256:$src1, f128mem:$src2, i8imm:$src3),
7427           "vinsertf128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
7428           []>, VEX_4V;
7429 }
7430
7431 let Predicates = [HasAVX] in {
7432 def : Pat<(int_x86_avx_vinsertf128_pd_256 VR256:$src1, VR128:$src2, imm:$src3),
7433           (VINSERTF128rr VR256:$src1, VR128:$src2, imm:$src3)>;
7434 def : Pat<(int_x86_avx_vinsertf128_ps_256 VR256:$src1, VR128:$src2, imm:$src3),
7435           (VINSERTF128rr VR256:$src1, VR128:$src2, imm:$src3)>;
7436 def : Pat<(int_x86_avx_vinsertf128_si_256 VR256:$src1, VR128:$src2, imm:$src3),
7437           (VINSERTF128rr VR256:$src1, VR128:$src2, imm:$src3)>;
7438 }
7439
7440 //===----------------------------------------------------------------------===//
7441 // VEXTRACTF128 - Extract packed floating-point values
7442 //
7443 let neverHasSideEffects = 1, ExeDomain = SSEPackedSingle in {
7444 def VEXTRACTF128rr : AVXAIi8<0x19, MRMDestReg, (outs VR128:$dst),
7445           (ins VR256:$src1, i8imm:$src2),
7446           "vextractf128\t{$src2, $src1, $dst|$dst, $src1, $src2}",
7447           []>, VEX;
7448 let mayStore = 1 in
7449 def VEXTRACTF128mr : AVXAIi8<0x19, MRMDestMem, (outs),
7450           (ins f128mem:$dst, VR256:$src1, i8imm:$src2),
7451           "vextractf128\t{$src2, $src1, $dst|$dst, $src1, $src2}",
7452           []>, VEX;
7453 }
7454
7455 let Predicates = [HasAVX] in {
7456 def : Pat<(int_x86_avx_vextractf128_pd_256 VR256:$src1, imm:$src2),
7457           (VEXTRACTF128rr VR256:$src1, imm:$src2)>;
7458 def : Pat<(int_x86_avx_vextractf128_ps_256 VR256:$src1, imm:$src2),
7459           (VEXTRACTF128rr VR256:$src1, imm:$src2)>;
7460 def : Pat<(int_x86_avx_vextractf128_si_256 VR256:$src1, imm:$src2),
7461           (VEXTRACTF128rr VR256:$src1, imm:$src2)>;
7462 }
7463
7464 //===----------------------------------------------------------------------===//
7465 // VMASKMOV - Conditional SIMD Packed Loads and Stores
7466 //
7467 multiclass avx_movmask_rm<bits<8> opc_rm, bits<8> opc_mr, string OpcodeStr,
7468                           Intrinsic IntLd, Intrinsic IntLd256,
7469                           Intrinsic IntSt, Intrinsic IntSt256> {
7470   def rm  : AVX8I<opc_rm, MRMSrcMem, (outs VR128:$dst),
7471              (ins VR128:$src1, f128mem:$src2),
7472              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7473              [(set VR128:$dst, (IntLd addr:$src2, VR128:$src1))]>,
7474              VEX_4V;
7475   def Yrm : AVX8I<opc_rm, MRMSrcMem, (outs VR256:$dst),
7476              (ins VR256:$src1, f256mem:$src2),
7477              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7478              [(set VR256:$dst, (IntLd256 addr:$src2, VR256:$src1))]>,
7479              VEX_4V;
7480   def mr  : AVX8I<opc_mr, MRMDestMem, (outs),
7481              (ins f128mem:$dst, VR128:$src1, VR128:$src2),
7482              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7483              [(IntSt addr:$dst, VR128:$src1, VR128:$src2)]>, VEX_4V;
7484   def Ymr : AVX8I<opc_mr, MRMDestMem, (outs),
7485              (ins f256mem:$dst, VR256:$src1, VR256:$src2),
7486              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7487              [(IntSt256 addr:$dst, VR256:$src1, VR256:$src2)]>, VEX_4V;
7488 }
7489
7490 let ExeDomain = SSEPackedSingle in
7491 defm VMASKMOVPS : avx_movmask_rm<0x2C, 0x2E, "vmaskmovps",
7492                                  int_x86_avx_maskload_ps,
7493                                  int_x86_avx_maskload_ps_256,
7494                                  int_x86_avx_maskstore_ps,
7495                                  int_x86_avx_maskstore_ps_256>;
7496 let ExeDomain = SSEPackedDouble in
7497 defm VMASKMOVPD : avx_movmask_rm<0x2D, 0x2F, "vmaskmovpd",
7498                                  int_x86_avx_maskload_pd,
7499                                  int_x86_avx_maskload_pd_256,
7500                                  int_x86_avx_maskstore_pd,
7501                                  int_x86_avx_maskstore_pd_256>;
7502
7503 //===----------------------------------------------------------------------===//
7504 // VPERMIL - Permute Single and Double Floating-Point Values
7505 //
7506 multiclass avx_permil<bits<8> opc_rm, bits<8> opc_rmi, string OpcodeStr,
7507                       RegisterClass RC, X86MemOperand x86memop_f,
7508                       X86MemOperand x86memop_i, PatFrag f_frag, PatFrag i_frag,
7509                       Intrinsic IntVar, Intrinsic IntImm> {
7510   def rr  : AVX8I<opc_rm, MRMSrcReg, (outs RC:$dst),
7511              (ins RC:$src1, RC:$src2),
7512              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7513              [(set RC:$dst, (IntVar RC:$src1, RC:$src2))]>, VEX_4V;
7514   def rm  : AVX8I<opc_rm, MRMSrcMem, (outs RC:$dst),
7515              (ins RC:$src1, x86memop_i:$src2),
7516              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7517              [(set RC:$dst, (IntVar RC:$src1,
7518                              (bitconvert (i_frag addr:$src2))))]>, VEX_4V;
7519
7520   def ri  : AVXAIi8<opc_rmi, MRMSrcReg, (outs RC:$dst),
7521              (ins RC:$src1, i8imm:$src2),
7522              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7523              [(set RC:$dst, (IntImm RC:$src1, imm:$src2))]>, VEX;
7524   def mi  : AVXAIi8<opc_rmi, MRMSrcMem, (outs RC:$dst),
7525              (ins x86memop_f:$src1, i8imm:$src2),
7526              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7527              [(set RC:$dst, (IntImm (f_frag addr:$src1), imm:$src2))]>, VEX;
7528 }
7529
7530 let ExeDomain = SSEPackedSingle in {
7531   defm VPERMILPS  : avx_permil<0x0C, 0x04, "vpermilps", VR128, f128mem, i128mem,
7532                                memopv4f32, memopv2i64,
7533                                int_x86_avx_vpermilvar_ps,
7534                                int_x86_avx_vpermil_ps>;
7535   defm VPERMILPSY : avx_permil<0x0C, 0x04, "vpermilps", VR256, f256mem, i256mem,
7536                                memopv8f32, memopv4i64,
7537                                int_x86_avx_vpermilvar_ps_256,
7538                                int_x86_avx_vpermil_ps_256>;
7539 }
7540 let ExeDomain = SSEPackedDouble in {
7541   defm VPERMILPD  : avx_permil<0x0D, 0x05, "vpermilpd", VR128, f128mem, i128mem,
7542                                memopv2f64, memopv2i64,
7543                                int_x86_avx_vpermilvar_pd,
7544                                int_x86_avx_vpermil_pd>;
7545   defm VPERMILPDY : avx_permil<0x0D, 0x05, "vpermilpd", VR256, f256mem, i256mem,
7546                                memopv4f64, memopv4i64,
7547                                int_x86_avx_vpermilvar_pd_256,
7548                                int_x86_avx_vpermil_pd_256>;
7549 }
7550
7551 let Predicates = [HasAVX] in {
7552 def : Pat<(v8f32 (X86VPermilp VR256:$src1, (i8 imm:$imm))),
7553           (VPERMILPSYri VR256:$src1, imm:$imm)>;
7554 def : Pat<(v4f64 (X86VPermilp VR256:$src1, (i8 imm:$imm))),
7555           (VPERMILPDYri VR256:$src1, imm:$imm)>;
7556 def : Pat<(v8i32 (X86VPermilp VR256:$src1, (i8 imm:$imm))),
7557           (VPERMILPSYri VR256:$src1, imm:$imm)>;
7558 def : Pat<(v4i64 (X86VPermilp VR256:$src1, (i8 imm:$imm))),
7559           (VPERMILPDYri VR256:$src1, imm:$imm)>;
7560 def : Pat<(v8f32 (X86VPermilp (memopv8f32 addr:$src1), (i8 imm:$imm))),
7561           (VPERMILPSYmi addr:$src1, imm:$imm)>;
7562 def : Pat<(v4f64 (X86VPermilp (memopv4f64 addr:$src1), (i8 imm:$imm))),
7563           (VPERMILPDYmi addr:$src1, imm:$imm)>;
7564 def : Pat<(v8i32 (X86VPermilp (bc_v8i32 (memopv4i64 addr:$src1)),
7565                                (i8 imm:$imm))),
7566           (VPERMILPSYmi addr:$src1, imm:$imm)>;
7567 def : Pat<(v4i64 (X86VPermilp (memopv4i64 addr:$src1), (i8 imm:$imm))),
7568           (VPERMILPDYmi addr:$src1, imm:$imm)>;
7569 }
7570
7571 //===----------------------------------------------------------------------===//
7572 // VPERM2F128 - Permute Floating-Point Values in 128-bit chunks
7573 //
7574 let neverHasSideEffects = 1, ExeDomain = SSEPackedSingle in {
7575 def VPERM2F128rr : AVXAIi8<0x06, MRMSrcReg, (outs VR256:$dst),
7576           (ins VR256:$src1, VR256:$src2, i8imm:$src3),
7577           "vperm2f128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
7578           []>, VEX_4V;
7579 let mayLoad = 1 in
7580 def VPERM2F128rm : AVXAIi8<0x06, MRMSrcMem, (outs VR256:$dst),
7581           (ins VR256:$src1, f256mem:$src2, i8imm:$src3),
7582           "vperm2f128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
7583           []>, VEX_4V;
7584 }
7585
7586 let Predicates = [HasAVX] in {
7587 def : Pat<(int_x86_avx_vperm2f128_ps_256 VR256:$src1, VR256:$src2, imm:$src3),
7588           (VPERM2F128rr VR256:$src1, VR256:$src2, imm:$src3)>;
7589 def : Pat<(int_x86_avx_vperm2f128_pd_256 VR256:$src1, VR256:$src2, imm:$src3),
7590           (VPERM2F128rr VR256:$src1, VR256:$src2, imm:$src3)>;
7591 def : Pat<(int_x86_avx_vperm2f128_si_256 VR256:$src1, VR256:$src2, imm:$src3),
7592           (VPERM2F128rr VR256:$src1, VR256:$src2, imm:$src3)>;
7593
7594 def : Pat<(int_x86_avx_vperm2f128_ps_256
7595                   VR256:$src1, (memopv8f32 addr:$src2), imm:$src3),
7596           (VPERM2F128rm VR256:$src1, addr:$src2, imm:$src3)>;
7597 def : Pat<(int_x86_avx_vperm2f128_pd_256
7598                   VR256:$src1, (memopv4f64 addr:$src2), imm:$src3),
7599           (VPERM2F128rm VR256:$src1, addr:$src2, imm:$src3)>;
7600 def : Pat<(int_x86_avx_vperm2f128_si_256
7601                   VR256:$src1, (bc_v8i32 (memopv4i64 addr:$src2)), imm:$src3),
7602           (VPERM2F128rm VR256:$src1, addr:$src2, imm:$src3)>;
7603 }
7604
7605 //===----------------------------------------------------------------------===//
7606 // VZERO - Zero YMM registers
7607 //
7608 let Defs = [YMM0, YMM1, YMM2, YMM3, YMM4, YMM5, YMM6, YMM7,
7609             YMM8, YMM9, YMM10, YMM11, YMM12, YMM13, YMM14, YMM15] in {
7610   // Zero All YMM registers
7611   def VZEROALL : I<0x77, RawFrm, (outs), (ins), "vzeroall",
7612                   [(int_x86_avx_vzeroall)]>, TB, VEX, VEX_L, Requires<[HasAVX]>;
7613
7614   // Zero Upper bits of YMM registers
7615   def VZEROUPPER : I<0x77, RawFrm, (outs), (ins), "vzeroupper",
7616                      [(int_x86_avx_vzeroupper)]>, TB, VEX, Requires<[HasAVX]>;
7617 }
7618
7619 //===----------------------------------------------------------------------===//
7620 // Half precision conversion instructions
7621 //===----------------------------------------------------------------------===//
7622 multiclass f16c_ph2ps<RegisterClass RC, X86MemOperand x86memop, Intrinsic Int> {
7623 let Predicates = [HasAVX, HasF16C] in {
7624   def rr : I<0x13, MRMSrcReg, (outs RC:$dst), (ins VR128:$src),
7625              "vcvtph2ps\t{$src, $dst|$dst, $src}",
7626              [(set RC:$dst, (Int VR128:$src))]>,
7627              T8, OpSize, VEX;
7628   let neverHasSideEffects = 1, mayLoad = 1 in
7629   def rm : I<0x13, MRMSrcMem, (outs RC:$dst), (ins x86memop:$src),
7630              "vcvtph2ps\t{$src, $dst|$dst, $src}", []>, T8, OpSize, VEX;
7631 }
7632 }
7633
7634 multiclass f16c_ps2ph<RegisterClass RC, X86MemOperand x86memop, Intrinsic Int> {
7635 let Predicates = [HasAVX, HasF16C] in {
7636   def rr : Ii8<0x1D, MRMDestReg, (outs VR128:$dst),
7637                (ins RC:$src1, i32i8imm:$src2),
7638                "vcvtps2ph\t{$src2, $src1, $dst|$dst, $src1, $src2}",
7639                [(set VR128:$dst, (Int RC:$src1, imm:$src2))]>,
7640                TA, OpSize, VEX;
7641   let neverHasSideEffects = 1, mayLoad = 1 in
7642   def mr : Ii8<0x1D, MRMDestMem, (outs x86memop:$dst),
7643                (ins RC:$src1, i32i8imm:$src2),
7644                "vcvtps2ph\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>,
7645                TA, OpSize, VEX;
7646 }
7647 }
7648
7649 defm VCVTPH2PS  : f16c_ph2ps<VR128, f64mem, int_x86_vcvtph2ps_128>;
7650 defm VCVTPH2PSY : f16c_ph2ps<VR256, f128mem, int_x86_vcvtph2ps_256>;
7651 defm VCVTPS2PH  : f16c_ps2ph<VR128, f64mem, int_x86_vcvtps2ph_128>;
7652 defm VCVTPS2PHY : f16c_ps2ph<VR256, f128mem, int_x86_vcvtps2ph_256>;
7653
7654 //===----------------------------------------------------------------------===//
7655 // AVX2 Instructions
7656 //===----------------------------------------------------------------------===//
7657
7658 /// AVX2_binop_rmi_int - AVX2 binary operator with 8-bit immediate
7659 multiclass AVX2_binop_rmi_int<bits<8> opc, string OpcodeStr,
7660                  Intrinsic IntId, RegisterClass RC, PatFrag memop_frag,
7661                  X86MemOperand x86memop> {
7662   let isCommutable = 1 in
7663   def rri : AVX2AIi8<opc, MRMSrcReg, (outs RC:$dst),
7664         (ins RC:$src1, RC:$src2, u32u8imm:$src3),
7665         !strconcat(OpcodeStr,
7666             "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
7667         [(set RC:$dst, (IntId RC:$src1, RC:$src2, imm:$src3))]>,
7668         VEX_4V;
7669   def rmi : AVX2AIi8<opc, MRMSrcMem, (outs RC:$dst),
7670         (ins RC:$src1, x86memop:$src2, u32u8imm:$src3),
7671         !strconcat(OpcodeStr,
7672             "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
7673         [(set RC:$dst,
7674           (IntId RC:$src1,
7675            (bitconvert (memop_frag addr:$src2)), imm:$src3))]>,
7676         VEX_4V;
7677 }
7678
7679 let isCommutable = 0 in {
7680 defm VPBLENDD : AVX2_binop_rmi_int<0x02, "vpblendd", int_x86_avx2_pblendd_128,
7681                                    VR128, memopv2i64, i128mem>;
7682 defm VPBLENDDY : AVX2_binop_rmi_int<0x02, "vpblendd", int_x86_avx2_pblendd_256,
7683                                     VR256, memopv4i64, i256mem>;
7684 }
7685
7686 //===----------------------------------------------------------------------===//
7687 // VPBROADCAST - Load from memory and broadcast to all elements of the
7688 //               destination operand
7689 //
7690 multiclass avx2_broadcast<bits<8> opc, string OpcodeStr,
7691                           X86MemOperand x86memop, PatFrag ld_frag,
7692                           Intrinsic Int128, Intrinsic Int256> {
7693   def rr : AVX28I<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
7694                   !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
7695                   [(set VR128:$dst, (Int128 VR128:$src))]>, VEX;
7696   def rm : AVX28I<opc, MRMSrcMem, (outs VR128:$dst), (ins x86memop:$src),
7697                   !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
7698                   [(set VR128:$dst,
7699                     (Int128 (scalar_to_vector (ld_frag addr:$src))))]>, VEX;
7700   def Yrr : AVX28I<opc, MRMSrcReg, (outs VR256:$dst), (ins VR128:$src),
7701                    !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
7702                    [(set VR256:$dst, (Int256 VR128:$src))]>, VEX;
7703   def Yrm : AVX28I<opc, MRMSrcMem, (outs VR256:$dst), (ins x86memop:$src),
7704                    !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
7705                    [(set VR256:$dst,
7706                     (Int256 (scalar_to_vector (ld_frag addr:$src))))]>, VEX;
7707 }
7708
7709 defm VPBROADCASTB  : avx2_broadcast<0x78, "vpbroadcastb", i8mem, loadi8,
7710                                     int_x86_avx2_pbroadcastb_128,
7711                                     int_x86_avx2_pbroadcastb_256>;
7712 defm VPBROADCASTW  : avx2_broadcast<0x79, "vpbroadcastw", i16mem, loadi16,
7713                                     int_x86_avx2_pbroadcastw_128,
7714                                     int_x86_avx2_pbroadcastw_256>;
7715 defm VPBROADCASTD  : avx2_broadcast<0x58, "vpbroadcastd", i32mem, loadi32,
7716                                     int_x86_avx2_pbroadcastd_128,
7717                                     int_x86_avx2_pbroadcastd_256>;
7718 defm VPBROADCASTQ  : avx2_broadcast<0x59, "vpbroadcastq", i64mem, loadi64,
7719                                     int_x86_avx2_pbroadcastq_128,
7720                                     int_x86_avx2_pbroadcastq_256>;
7721
7722 let Predicates = [HasAVX2] in {
7723   def : Pat<(v16i8 (X86VBroadcast (loadi8 addr:$src))),
7724           (VPBROADCASTBrm addr:$src)>;
7725   def : Pat<(v32i8 (X86VBroadcast (loadi8 addr:$src))),
7726           (VPBROADCASTBYrm addr:$src)>;
7727   def : Pat<(v8i16 (X86VBroadcast (loadi16 addr:$src))),
7728           (VPBROADCASTWrm addr:$src)>;
7729   def : Pat<(v16i16 (X86VBroadcast (loadi16 addr:$src))),
7730           (VPBROADCASTWYrm addr:$src)>;
7731   def : Pat<(v4i32 (X86VBroadcast (loadi32 addr:$src))),
7732           (VPBROADCASTDrm addr:$src)>;
7733   def : Pat<(v8i32 (X86VBroadcast (loadi32 addr:$src))),
7734           (VPBROADCASTDYrm addr:$src)>;
7735   def : Pat<(v2i64 (X86VBroadcast (loadi64 addr:$src))),
7736           (VPBROADCASTQrm addr:$src)>;
7737   def : Pat<(v4i64 (X86VBroadcast (loadi64 addr:$src))),
7738           (VPBROADCASTQYrm addr:$src)>;
7739 }
7740
7741 // AVX1 broadcast patterns
7742 let Predicates = [HasAVX] in {
7743 def : Pat<(v8i32 (X86VBroadcast (loadi32 addr:$src))),
7744           (VBROADCASTSSYrm addr:$src)>;
7745 def : Pat<(v4i64 (X86VBroadcast (loadi64 addr:$src))),
7746           (VBROADCASTSDrm addr:$src)>;
7747 def : Pat<(v8f32 (X86VBroadcast (loadf32 addr:$src))),
7748           (VBROADCASTSSYrm addr:$src)>;
7749 def : Pat<(v4f64 (X86VBroadcast (loadf64 addr:$src))),
7750           (VBROADCASTSDrm addr:$src)>;
7751
7752 def : Pat<(v4f32 (X86VBroadcast (loadf32 addr:$src))),
7753           (VBROADCASTSSrm addr:$src)>;
7754 def : Pat<(v4i32 (X86VBroadcast (loadi32 addr:$src))),
7755           (VBROADCASTSSrm addr:$src)>;
7756 }
7757
7758 //===----------------------------------------------------------------------===//
7759 // VPERM - Permute instructions
7760 //
7761
7762 multiclass avx2_perm<bits<8> opc, string OpcodeStr, PatFrag mem_frag,
7763                      Intrinsic Int> {
7764   def Yrr : AVX28I<opc, MRMSrcReg, (outs VR256:$dst),
7765                    (ins VR256:$src1, VR256:$src2),
7766                    !strconcat(OpcodeStr,
7767                        "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7768                    [(set VR256:$dst, (Int VR256:$src1, VR256:$src2))]>, VEX_4V;
7769   def Yrm : AVX28I<opc, MRMSrcMem, (outs VR256:$dst),
7770                    (ins VR256:$src1, i256mem:$src2),
7771                    !strconcat(OpcodeStr,
7772                        "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7773                    [(set VR256:$dst, (Int VR256:$src1,
7774                                       (bitconvert (mem_frag addr:$src2))))]>,
7775                    VEX_4V;
7776 }
7777
7778 defm VPERMD : avx2_perm<0x36, "vpermd", memopv4i64, int_x86_avx2_permd>;
7779 let ExeDomain = SSEPackedSingle in
7780 defm VPERMPS : avx2_perm<0x16, "vpermps", memopv8f32, int_x86_avx2_permps>;
7781
7782 multiclass avx2_perm_imm<bits<8> opc, string OpcodeStr, PatFrag mem_frag,
7783                          Intrinsic Int> {
7784   def Yrr : AVX2AIi8<opc, MRMSrcReg, (outs VR256:$dst),
7785                      (ins VR256:$src1, i8imm:$src2),
7786                      !strconcat(OpcodeStr,
7787                          "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7788                      [(set VR256:$dst, (Int VR256:$src1, imm:$src2))]>, VEX;
7789   def Yrm : AVX2AIi8<opc, MRMSrcMem, (outs VR256:$dst),
7790                      (ins i256mem:$src1, i8imm:$src2),
7791                      !strconcat(OpcodeStr,
7792                          "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7793                      [(set VR256:$dst, (Int (mem_frag addr:$src1), imm:$src2))]>,
7794                      VEX;
7795 }
7796
7797 defm VPERMQ : avx2_perm_imm<0x00, "vpermq", memopv4i64, int_x86_avx2_permq>,
7798                             VEX_W;
7799 let ExeDomain = SSEPackedDouble in
7800 defm VPERMPD : avx2_perm_imm<0x01, "vpermpd", memopv4f64, int_x86_avx2_permpd>,
7801                              VEX_W;
7802
7803 //===----------------------------------------------------------------------===//
7804 // VPERM2I128 - Permute Floating-Point Values in 128-bit chunks
7805 //
7806 def VPERM2I128rr : AVX2AIi8<0x46, MRMSrcReg, (outs VR256:$dst),
7807           (ins VR256:$src1, VR256:$src2, i8imm:$src3),
7808           "vperm2i128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
7809           [(set VR256:$dst,
7810            (int_x86_avx2_vperm2i128 VR256:$src1, VR256:$src2, imm:$src3))]>,
7811           VEX_4V;
7812 def VPERM2I128rm : AVX2AIi8<0x46, MRMSrcMem, (outs VR256:$dst),
7813           (ins VR256:$src1, f256mem:$src2, i8imm:$src3),
7814           "vperm2i128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
7815           [(set VR256:$dst,
7816            (int_x86_avx2_vperm2i128 VR256:$src1, (memopv4i64 addr:$src2),
7817             imm:$src3))]>,
7818           VEX_4V;
7819
7820 let Predicates = [HasAVX2] in {
7821 def : Pat<(v8i32 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
7822           (VPERM2I128rr VR256:$src1, VR256:$src2, imm:$imm)>;
7823 def : Pat<(v4i64 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
7824           (VPERM2I128rr VR256:$src1, VR256:$src2, imm:$imm)>;
7825 def : Pat<(v32i8 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
7826           (VPERM2I128rr VR256:$src1, VR256:$src2, imm:$imm)>;
7827 def : Pat<(v16i16 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
7828           (VPERM2I128rr VR256:$src1, VR256:$src2, imm:$imm)>;
7829
7830 def : Pat<(v32i8 (X86VPerm2x128 VR256:$src1, (bc_v32i8 (memopv4i64 addr:$src2)),
7831                   (i8 imm:$imm))),
7832           (VPERM2I128rm VR256:$src1, addr:$src2, imm:$imm)>;
7833 def : Pat<(v16i16 (X86VPerm2x128 VR256:$src1,
7834                    (bc_v16i16 (memopv4i64 addr:$src2)), (i8 imm:$imm))),
7835           (VPERM2I128rm VR256:$src1, addr:$src2, imm:$imm)>;
7836 def : Pat<(v8i32 (X86VPerm2x128 VR256:$src1, (bc_v8i32 (memopv4i64 addr:$src2)),
7837                   (i8 imm:$imm))),
7838           (VPERM2I128rm VR256:$src1, addr:$src2, imm:$imm)>;
7839 def : Pat<(v4i64 (X86VPerm2x128 VR256:$src1, (memopv4i64 addr:$src2),
7840                   (i8 imm:$imm))),
7841           (VPERM2I128rm VR256:$src1, addr:$src2, imm:$imm)>;
7842 }
7843
7844 // AVX1 patterns
7845 let Predicates = [HasAVX] in {
7846 def : Pat<(v8f32 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
7847           (VPERM2F128rr VR256:$src1, VR256:$src2, imm:$imm)>;
7848 def : Pat<(v8i32 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
7849           (VPERM2F128rr VR256:$src1, VR256:$src2, imm:$imm)>;
7850 def : Pat<(v4i64 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
7851           (VPERM2F128rr VR256:$src1, VR256:$src2, imm:$imm)>;
7852 def : Pat<(v4f64 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
7853           (VPERM2F128rr VR256:$src1, VR256:$src2, imm:$imm)>;
7854 def : Pat<(v32i8 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
7855           (VPERM2F128rr VR256:$src1, VR256:$src2, imm:$imm)>;
7856 def : Pat<(v16i16 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
7857           (VPERM2F128rr VR256:$src1, VR256:$src2, imm:$imm)>;
7858
7859 def : Pat<(v8f32 (X86VPerm2x128 VR256:$src1,
7860                   (memopv8f32 addr:$src2), (i8 imm:$imm))),
7861           (VPERM2F128rm VR256:$src1, addr:$src2, imm:$imm)>;
7862 def : Pat<(v8i32 (X86VPerm2x128 VR256:$src1,
7863                   (bc_v8i32 (memopv4i64 addr:$src2)), (i8 imm:$imm))),
7864           (VPERM2F128rm VR256:$src1, addr:$src2, imm:$imm)>;
7865 def : Pat<(v4i64 (X86VPerm2x128 VR256:$src1,
7866                   (memopv4i64 addr:$src2), (i8 imm:$imm))),
7867           (VPERM2F128rm VR256:$src1, addr:$src2, imm:$imm)>;
7868 def : Pat<(v4f64 (X86VPerm2x128 VR256:$src1,
7869                   (memopv4f64 addr:$src2), (i8 imm:$imm))),
7870           (VPERM2F128rm VR256:$src1, addr:$src2, imm:$imm)>;
7871 def : Pat<(v32i8 (X86VPerm2x128 VR256:$src1,
7872                   (bc_v32i8 (memopv4i64 addr:$src2)), (i8 imm:$imm))),
7873           (VPERM2F128rm VR256:$src1, addr:$src2, imm:$imm)>;
7874 def : Pat<(v16i16 (X86VPerm2x128 VR256:$src1,
7875                   (bc_v16i16 (memopv4i64 addr:$src2)), (i8 imm:$imm))),
7876           (VPERM2F128rm VR256:$src1, addr:$src2, imm:$imm)>;
7877 }
7878
7879
7880 //===----------------------------------------------------------------------===//
7881 // VINSERTI128 - Insert packed integer values
7882 //
7883 def VINSERTI128rr : AVX2AIi8<0x38, MRMSrcReg, (outs VR256:$dst),
7884           (ins VR256:$src1, VR128:$src2, i8imm:$src3),
7885           "vinserti128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
7886           [(set VR256:$dst,
7887             (int_x86_avx2_vinserti128 VR256:$src1, VR128:$src2, imm:$src3))]>,
7888           VEX_4V;
7889 def VINSERTI128rm : AVX2AIi8<0x38, MRMSrcMem, (outs VR256:$dst),
7890           (ins VR256:$src1, i128mem:$src2, i8imm:$src3),
7891           "vinserti128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
7892           [(set VR256:$dst,
7893             (int_x86_avx2_vinserti128 VR256:$src1, (memopv2i64 addr:$src2),
7894              imm:$src3))]>, VEX_4V;
7895
7896 let Predicates = [HasAVX2] in {
7897 def : Pat<(vinsertf128_insert:$ins (v4i64 VR256:$src1), (v2i64 VR128:$src2),
7898                                    (i32 imm)),
7899           (VINSERTI128rr VR256:$src1, VR128:$src2,
7900                          (INSERT_get_vinsertf128_imm VR256:$ins))>;
7901 def : Pat<(vinsertf128_insert:$ins (v8i32 VR256:$src1), (v4i32 VR128:$src2),
7902                                    (i32 imm)),
7903           (VINSERTI128rr VR256:$src1, VR128:$src2,
7904                          (INSERT_get_vinsertf128_imm VR256:$ins))>;
7905 def : Pat<(vinsertf128_insert:$ins (v32i8 VR256:$src1), (v16i8 VR128:$src2),
7906                                    (i32 imm)),
7907           (VINSERTI128rr VR256:$src1, VR128:$src2,
7908                          (INSERT_get_vinsertf128_imm VR256:$ins))>;
7909 def : Pat<(vinsertf128_insert:$ins (v16i16 VR256:$src1), (v8i16 VR128:$src2),
7910                                    (i32 imm)),
7911           (VINSERTI128rr VR256:$src1, VR128:$src2,
7912                          (INSERT_get_vinsertf128_imm VR256:$ins))>;
7913 }
7914
7915 // AVX1 patterns
7916 let Predicates = [HasAVX] in {
7917 def : Pat<(vinsertf128_insert:$ins (v8f32 VR256:$src1), (v4f32 VR128:$src2),
7918                                    (i32 imm)),
7919           (VINSERTF128rr VR256:$src1, VR128:$src2,
7920                          (INSERT_get_vinsertf128_imm VR256:$ins))>;
7921 def : Pat<(vinsertf128_insert:$ins (v4f64 VR256:$src1), (v2f64 VR128:$src2),
7922                                    (i32 imm)),
7923           (VINSERTF128rr VR256:$src1, VR128:$src2,
7924                          (INSERT_get_vinsertf128_imm VR256:$ins))>;
7925 def : Pat<(vinsertf128_insert:$ins (v4i64 VR256:$src1), (v2i64 VR128:$src2),
7926                                    (i32 imm)),
7927           (VINSERTF128rr VR256:$src1, VR128:$src2,
7928                          (INSERT_get_vinsertf128_imm VR256:$ins))>;
7929 def : Pat<(vinsertf128_insert:$ins (v8i32 VR256:$src1), (v4i32 VR128:$src2),
7930                                    (i32 imm)),
7931           (VINSERTF128rr VR256:$src1, VR128:$src2,
7932                          (INSERT_get_vinsertf128_imm VR256:$ins))>;
7933 def : Pat<(vinsertf128_insert:$ins (v32i8 VR256:$src1), (v16i8 VR128:$src2),
7934                                    (i32 imm)),
7935           (VINSERTF128rr VR256:$src1, VR128:$src2,
7936                          (INSERT_get_vinsertf128_imm VR256:$ins))>;
7937 def : Pat<(vinsertf128_insert:$ins (v16i16 VR256:$src1), (v8i16 VR128:$src2),
7938                                    (i32 imm)),
7939           (VINSERTF128rr VR256:$src1, VR128:$src2,
7940                          (INSERT_get_vinsertf128_imm VR256:$ins))>;
7941 }
7942
7943 //===----------------------------------------------------------------------===//
7944 // VEXTRACTI128 - Extract packed integer values
7945 //
7946 def VEXTRACTI128rr : AVX2AIi8<0x39, MRMDestReg, (outs VR128:$dst),
7947           (ins VR256:$src1, i8imm:$src2),
7948           "vextracti128\t{$src2, $src1, $dst|$dst, $src1, $src2}",
7949           [(set VR128:$dst,
7950             (int_x86_avx2_vextracti128 VR256:$src1, imm:$src2))]>,
7951           VEX;
7952 let neverHasSideEffects = 1, mayStore = 1 in
7953 def VEXTRACTI128mr : AVX2AIi8<0x39, MRMDestMem, (outs),
7954           (ins i128mem:$dst, VR256:$src1, i8imm:$src2),
7955           "vextracti128\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>, VEX;
7956
7957 let Predicates = [HasAVX2] in {
7958 def : Pat<(vextractf128_extract:$ext VR256:$src1, (i32 imm)),
7959           (v2i64 (VEXTRACTI128rr
7960                     (v4i64 VR256:$src1),
7961                     (EXTRACT_get_vextractf128_imm VR128:$ext)))>;
7962 def : Pat<(vextractf128_extract:$ext VR256:$src1, (i32 imm)),
7963           (v4i32 (VEXTRACTI128rr
7964                     (v8i32 VR256:$src1),
7965                     (EXTRACT_get_vextractf128_imm VR128:$ext)))>;
7966 def : Pat<(vextractf128_extract:$ext VR256:$src1, (i32 imm)),
7967           (v8i16 (VEXTRACTI128rr
7968                     (v16i16 VR256:$src1),
7969                     (EXTRACT_get_vextractf128_imm VR128:$ext)))>;
7970 def : Pat<(vextractf128_extract:$ext VR256:$src1, (i32 imm)),
7971           (v16i8 (VEXTRACTI128rr
7972                     (v32i8 VR256:$src1),
7973                     (EXTRACT_get_vextractf128_imm VR128:$ext)))>;
7974 }
7975
7976 // AVX1 patterns
7977 let Predicates = [HasAVX] in {
7978 def : Pat<(vextractf128_extract:$ext VR256:$src1, (i32 imm)),
7979           (v4f32 (VEXTRACTF128rr
7980                     (v8f32 VR256:$src1),
7981                     (EXTRACT_get_vextractf128_imm VR128:$ext)))>;
7982 def : Pat<(vextractf128_extract:$ext VR256:$src1, (i32 imm)),
7983           (v2f64 (VEXTRACTF128rr
7984                     (v4f64 VR256:$src1),
7985                     (EXTRACT_get_vextractf128_imm VR128:$ext)))>;
7986 def : Pat<(vextractf128_extract:$ext VR256:$src1, (i32 imm)),
7987           (v2i64 (VEXTRACTF128rr
7988                     (v4i64 VR256:$src1),
7989                     (EXTRACT_get_vextractf128_imm VR128:$ext)))>;
7990 def : Pat<(vextractf128_extract:$ext VR256:$src1, (i32 imm)),
7991           (v4i32 (VEXTRACTF128rr
7992                     (v8i32 VR256:$src1),
7993                     (EXTRACT_get_vextractf128_imm VR128:$ext)))>;
7994 def : Pat<(vextractf128_extract:$ext VR256:$src1, (i32 imm)),
7995           (v8i16 (VEXTRACTF128rr
7996                     (v16i16 VR256:$src1),
7997                     (EXTRACT_get_vextractf128_imm VR128:$ext)))>;
7998 def : Pat<(vextractf128_extract:$ext VR256:$src1, (i32 imm)),
7999           (v16i8 (VEXTRACTF128rr
8000                     (v32i8 VR256:$src1),
8001                     (EXTRACT_get_vextractf128_imm VR128:$ext)))>;
8002 }
8003
8004 //===----------------------------------------------------------------------===//
8005 // VPMASKMOV - Conditional SIMD Integer Packed Loads and Stores
8006 //
8007 multiclass avx2_pmovmask<string OpcodeStr,
8008                          Intrinsic IntLd128, Intrinsic IntLd256,
8009                          Intrinsic IntSt128, Intrinsic IntSt256> {
8010   def rm  : AVX28I<0x8c, MRMSrcMem, (outs VR128:$dst),
8011              (ins VR128:$src1, i128mem:$src2),
8012              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8013              [(set VR128:$dst, (IntLd128 addr:$src2, VR128:$src1))]>, VEX_4V;
8014   def Yrm : AVX28I<0x8c, MRMSrcMem, (outs VR256:$dst),
8015              (ins VR256:$src1, i256mem:$src2),
8016              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8017              [(set VR256:$dst, (IntLd256 addr:$src2, VR256:$src1))]>, VEX_4V;
8018   def mr  : AVX28I<0x8e, MRMDestMem, (outs),
8019              (ins i128mem:$dst, VR128:$src1, VR128:$src2),
8020              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8021              [(IntSt128 addr:$dst, VR128:$src1, VR128:$src2)]>, VEX_4V;
8022   def Ymr : AVX28I<0x8e, MRMDestMem, (outs),
8023              (ins i256mem:$dst, VR256:$src1, VR256:$src2),
8024              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8025              [(IntSt256 addr:$dst, VR256:$src1, VR256:$src2)]>, VEX_4V;
8026 }
8027
8028 defm VPMASKMOVD : avx2_pmovmask<"vpmaskmovd",
8029                                 int_x86_avx2_maskload_d,
8030                                 int_x86_avx2_maskload_d_256,
8031                                 int_x86_avx2_maskstore_d,
8032                                 int_x86_avx2_maskstore_d_256>;
8033 defm VPMASKMOVQ : avx2_pmovmask<"vpmaskmovq",
8034                                 int_x86_avx2_maskload_q,
8035                                 int_x86_avx2_maskload_q_256,
8036                                 int_x86_avx2_maskstore_q,
8037                                 int_x86_avx2_maskstore_q_256>, VEX_W;
8038
8039
8040 //===----------------------------------------------------------------------===//
8041 // Variable Bit Shifts
8042 //
8043 multiclass avx2_var_shift<bits<8> opc, string OpcodeStr, SDNode OpNode,
8044                           ValueType vt128, ValueType vt256> {
8045   def rr  : AVX28I<opc, MRMSrcReg, (outs VR128:$dst),
8046              (ins VR128:$src1, VR128:$src2),
8047              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8048              [(set VR128:$dst,
8049                (vt128 (OpNode VR128:$src1, (vt128 VR128:$src2))))]>,
8050              VEX_4V;
8051   def rm  : AVX28I<opc, MRMSrcMem, (outs VR128:$dst),
8052              (ins VR128:$src1, i128mem:$src2),
8053              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8054              [(set VR128:$dst,
8055                (vt128 (OpNode VR128:$src1,
8056                        (vt128 (bitconvert (memopv2i64 addr:$src2))))))]>,
8057              VEX_4V;
8058   def Yrr : AVX28I<opc, MRMSrcReg, (outs VR256:$dst),
8059              (ins VR256:$src1, VR256:$src2),
8060              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8061              [(set VR256:$dst,
8062                (vt256 (OpNode VR256:$src1, (vt256 VR256:$src2))))]>,
8063              VEX_4V;
8064   def Yrm : AVX28I<opc, MRMSrcMem, (outs VR256:$dst),
8065              (ins VR256:$src1, i256mem:$src2),
8066              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
8067              [(set VR256:$dst,
8068                (vt256 (OpNode VR256:$src1,
8069                        (vt256 (bitconvert (memopv4i64 addr:$src2))))))]>,
8070              VEX_4V;
8071 }
8072
8073 defm VPSLLVD : avx2_var_shift<0x47, "vpsllvd", shl, v4i32, v8i32>;
8074 defm VPSLLVQ : avx2_var_shift<0x47, "vpsllvq", shl, v2i64, v4i64>, VEX_W;
8075 defm VPSRLVD : avx2_var_shift<0x45, "vpsrlvd", srl, v4i32, v8i32>;
8076 defm VPSRLVQ : avx2_var_shift<0x45, "vpsrlvq", srl, v2i64, v4i64>, VEX_W;
8077 defm VPSRAVD : avx2_var_shift<0x46, "vpsravd", sra, v4i32, v8i32>;