Add target specific node for PMULUDQ. Change patterns to use it and custom lower...
[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)))], IIC_DEFAULT, 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)))],
77           IIC_DEFAULT, d>;
78 }
79
80 /// sse12_fp_packed_logical_rm - SSE 1 & 2 packed instructions class
81 multiclass sse12_fp_packed_logical_rm<bits<8> opc, RegisterClass RC, Domain d,
82                                       string OpcodeStr, X86MemOperand x86memop,
83                                       list<dag> pat_rr, list<dag> pat_rm,
84                                       bit Is2Addr = 1,
85                                       bit rr_hasSideEffects = 0> {
86   let isCommutable = 1, neverHasSideEffects = rr_hasSideEffects in
87     def rr : PI<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
88        !if(Is2Addr,
89            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
90            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
91        pat_rr, IIC_DEFAULT, d>;
92   def rm : PI<opc, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
93        !if(Is2Addr,
94            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
95            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
96        pat_rm, IIC_DEFAULT, d>;
97 }
98
99 /// sse12_fp_packed_int - SSE 1 & 2 packed instructions intrinsics class
100 multiclass sse12_fp_packed_int<bits<8> opc, string OpcodeStr, RegisterClass RC,
101                            string asm, string SSEVer, string FPSizeStr,
102                            X86MemOperand x86memop, PatFrag mem_frag,
103                            Domain d, bit Is2Addr = 1> {
104   def rr_Int : PI<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
105        !if(Is2Addr,
106            !strconcat(asm, "\t{$src2, $dst|$dst, $src2}"),
107            !strconcat(asm, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
108            [(set RC:$dst, (!cast<Intrinsic>(
109                      !strconcat("int_x86_", SSEVer, "_", OpcodeStr, FPSizeStr))
110                  RC:$src1, RC:$src2))], IIC_DEFAULT, d>;
111   def rm_Int : PI<opc, MRMSrcMem, (outs RC:$dst), (ins RC:$src1,x86memop:$src2),
112        !if(Is2Addr,
113            !strconcat(asm, "\t{$src2, $dst|$dst, $src2}"),
114            !strconcat(asm, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
115        [(set RC:$dst, (!cast<Intrinsic>(
116                      !strconcat("int_x86_", SSEVer, "_", OpcodeStr, FPSizeStr))
117              RC:$src1, (mem_frag addr:$src2)))], IIC_DEFAULT, d>;
118 }
119
120 //===----------------------------------------------------------------------===//
121 //  Non-instruction patterns
122 //===----------------------------------------------------------------------===//
123
124 // A vector extract of the first f32/f64 position is a subregister copy
125 def : Pat<(f32 (vector_extract (v4f32 VR128:$src), (iPTR 0))),
126           (f32 (EXTRACT_SUBREG (v4f32 VR128:$src), sub_ss))>;
127 def : Pat<(f64 (vector_extract (v2f64 VR128:$src), (iPTR 0))),
128           (f64 (EXTRACT_SUBREG (v2f64 VR128:$src), sub_sd))>;
129
130 // A 128-bit subvector extract from the first 256-bit vector position
131 // is a subregister copy that needs no instruction.
132 def : Pat<(v4i32 (extract_subvector (v8i32 VR256:$src), (i32 0))),
133           (v4i32 (EXTRACT_SUBREG (v8i32 VR256:$src), sub_xmm))>;
134 def : Pat<(v4f32 (extract_subvector (v8f32 VR256:$src), (i32 0))),
135           (v4f32 (EXTRACT_SUBREG (v8f32 VR256:$src), sub_xmm))>;
136
137 def : Pat<(v2i64 (extract_subvector (v4i64 VR256:$src), (i32 0))),
138           (v2i64 (EXTRACT_SUBREG (v4i64 VR256:$src), sub_xmm))>;
139 def : Pat<(v2f64 (extract_subvector (v4f64 VR256:$src), (i32 0))),
140           (v2f64 (EXTRACT_SUBREG (v4f64 VR256:$src), sub_xmm))>;
141
142 def : Pat<(v8i16 (extract_subvector (v16i16 VR256:$src), (i32 0))),
143           (v8i16 (EXTRACT_SUBREG (v16i16 VR256:$src), sub_xmm))>;
144 def : Pat<(v16i8 (extract_subvector (v32i8 VR256:$src), (i32 0))),
145           (v16i8 (EXTRACT_SUBREG (v32i8 VR256:$src), sub_xmm))>;
146
147 // A 128-bit subvector insert to the first 256-bit vector position
148 // is a subregister copy that needs no instruction.
149 def : Pat<(insert_subvector undef, (v2i64 VR128:$src), (i32 0)),
150           (INSERT_SUBREG (v4i64 (IMPLICIT_DEF)), VR128:$src, sub_xmm)>;
151 def : Pat<(insert_subvector undef, (v2f64 VR128:$src), (i32 0)),
152           (INSERT_SUBREG (v4f64 (IMPLICIT_DEF)), VR128:$src, sub_xmm)>;
153 def : Pat<(insert_subvector undef, (v4i32 VR128:$src), (i32 0)),
154           (INSERT_SUBREG (v8i32 (IMPLICIT_DEF)), VR128:$src, sub_xmm)>;
155 def : Pat<(insert_subvector undef, (v4f32 VR128:$src), (i32 0)),
156           (INSERT_SUBREG (v8f32 (IMPLICIT_DEF)), VR128:$src, sub_xmm)>;
157 def : Pat<(insert_subvector undef, (v8i16 VR128:$src), (i32 0)),
158           (INSERT_SUBREG (v16i16 (IMPLICIT_DEF)), VR128:$src, sub_xmm)>;
159 def : Pat<(insert_subvector undef, (v16i8 VR128:$src), (i32 0)),
160           (INSERT_SUBREG (v32i8 (IMPLICIT_DEF)), VR128:$src, sub_xmm)>;
161
162 // Implicitly promote a 32-bit scalar to a vector.
163 def : Pat<(v4f32 (scalar_to_vector FR32:$src)),
164           (INSERT_SUBREG (v4f32 (IMPLICIT_DEF)), FR32:$src, sub_ss)>;
165 def : Pat<(v8f32 (scalar_to_vector FR32:$src)),
166           (INSERT_SUBREG (v8f32 (IMPLICIT_DEF)), FR32:$src, sub_ss)>;
167 // Implicitly promote a 64-bit scalar to a vector.
168 def : Pat<(v2f64 (scalar_to_vector FR64:$src)),
169           (INSERT_SUBREG (v2f64 (IMPLICIT_DEF)), FR64:$src, sub_sd)>;
170 def : Pat<(v4f64 (scalar_to_vector FR64:$src)),
171           (INSERT_SUBREG (v4f64 (IMPLICIT_DEF)), FR64:$src, sub_sd)>;
172
173 // Bitcasts between 128-bit vector types. Return the original type since
174 // no instruction is needed for the conversion
175 let Predicates = [HasSSE2] in {
176   def : Pat<(v2i64 (bitconvert (v4i32 VR128:$src))), (v2i64 VR128:$src)>;
177   def : Pat<(v2i64 (bitconvert (v8i16 VR128:$src))), (v2i64 VR128:$src)>;
178   def : Pat<(v2i64 (bitconvert (v16i8 VR128:$src))), (v2i64 VR128:$src)>;
179   def : Pat<(v2i64 (bitconvert (v2f64 VR128:$src))), (v2i64 VR128:$src)>;
180   def : Pat<(v2i64 (bitconvert (v4f32 VR128:$src))), (v2i64 VR128:$src)>;
181   def : Pat<(v4i32 (bitconvert (v2i64 VR128:$src))), (v4i32 VR128:$src)>;
182   def : Pat<(v4i32 (bitconvert (v8i16 VR128:$src))), (v4i32 VR128:$src)>;
183   def : Pat<(v4i32 (bitconvert (v16i8 VR128:$src))), (v4i32 VR128:$src)>;
184   def : Pat<(v4i32 (bitconvert (v2f64 VR128:$src))), (v4i32 VR128:$src)>;
185   def : Pat<(v4i32 (bitconvert (v4f32 VR128:$src))), (v4i32 VR128:$src)>;
186   def : Pat<(v8i16 (bitconvert (v2i64 VR128:$src))), (v8i16 VR128:$src)>;
187   def : Pat<(v8i16 (bitconvert (v4i32 VR128:$src))), (v8i16 VR128:$src)>;
188   def : Pat<(v8i16 (bitconvert (v16i8 VR128:$src))), (v8i16 VR128:$src)>;
189   def : Pat<(v8i16 (bitconvert (v2f64 VR128:$src))), (v8i16 VR128:$src)>;
190   def : Pat<(v8i16 (bitconvert (v4f32 VR128:$src))), (v8i16 VR128:$src)>;
191   def : Pat<(v16i8 (bitconvert (v2i64 VR128:$src))), (v16i8 VR128:$src)>;
192   def : Pat<(v16i8 (bitconvert (v4i32 VR128:$src))), (v16i8 VR128:$src)>;
193   def : Pat<(v16i8 (bitconvert (v8i16 VR128:$src))), (v16i8 VR128:$src)>;
194   def : Pat<(v16i8 (bitconvert (v2f64 VR128:$src))), (v16i8 VR128:$src)>;
195   def : Pat<(v16i8 (bitconvert (v4f32 VR128:$src))), (v16i8 VR128:$src)>;
196   def : Pat<(v4f32 (bitconvert (v2i64 VR128:$src))), (v4f32 VR128:$src)>;
197   def : Pat<(v4f32 (bitconvert (v4i32 VR128:$src))), (v4f32 VR128:$src)>;
198   def : Pat<(v4f32 (bitconvert (v8i16 VR128:$src))), (v4f32 VR128:$src)>;
199   def : Pat<(v4f32 (bitconvert (v16i8 VR128:$src))), (v4f32 VR128:$src)>;
200   def : Pat<(v4f32 (bitconvert (v2f64 VR128:$src))), (v4f32 VR128:$src)>;
201   def : Pat<(v2f64 (bitconvert (v2i64 VR128:$src))), (v2f64 VR128:$src)>;
202   def : Pat<(v2f64 (bitconvert (v4i32 VR128:$src))), (v2f64 VR128:$src)>;
203   def : Pat<(v2f64 (bitconvert (v8i16 VR128:$src))), (v2f64 VR128:$src)>;
204   def : Pat<(v2f64 (bitconvert (v16i8 VR128:$src))), (v2f64 VR128:$src)>;
205   def : Pat<(v2f64 (bitconvert (v4f32 VR128:$src))), (v2f64 VR128:$src)>;
206 }
207
208 // Bitcasts between 256-bit vector types. Return the original type since
209 // no instruction is needed for the conversion
210 let Predicates = [HasAVX] in {
211   def : Pat<(v4f64  (bitconvert (v8f32 VR256:$src))),  (v4f64 VR256:$src)>;
212   def : Pat<(v4f64  (bitconvert (v8i32 VR256:$src))),  (v4f64 VR256:$src)>;
213   def : Pat<(v4f64  (bitconvert (v4i64 VR256:$src))),  (v4f64 VR256:$src)>;
214   def : Pat<(v4f64  (bitconvert (v16i16 VR256:$src))), (v4f64 VR256:$src)>;
215   def : Pat<(v4f64  (bitconvert (v32i8 VR256:$src))),  (v4f64 VR256:$src)>;
216   def : Pat<(v8f32  (bitconvert (v8i32 VR256:$src))),  (v8f32 VR256:$src)>;
217   def : Pat<(v8f32  (bitconvert (v4i64 VR256:$src))),  (v8f32 VR256:$src)>;
218   def : Pat<(v8f32  (bitconvert (v4f64 VR256:$src))),  (v8f32 VR256:$src)>;
219   def : Pat<(v8f32  (bitconvert (v32i8 VR256:$src))),  (v8f32 VR256:$src)>;
220   def : Pat<(v8f32  (bitconvert (v16i16 VR256:$src))), (v8f32 VR256:$src)>;
221   def : Pat<(v4i64  (bitconvert (v8f32 VR256:$src))),  (v4i64 VR256:$src)>;
222   def : Pat<(v4i64  (bitconvert (v8i32 VR256:$src))),  (v4i64 VR256:$src)>;
223   def : Pat<(v4i64  (bitconvert (v4f64 VR256:$src))),  (v4i64 VR256:$src)>;
224   def : Pat<(v4i64  (bitconvert (v32i8 VR256:$src))),  (v4i64 VR256:$src)>;
225   def : Pat<(v4i64  (bitconvert (v16i16 VR256:$src))), (v4i64 VR256:$src)>;
226   def : Pat<(v32i8  (bitconvert (v4f64 VR256:$src))),  (v32i8 VR256:$src)>;
227   def : Pat<(v32i8  (bitconvert (v4i64 VR256:$src))),  (v32i8 VR256:$src)>;
228   def : Pat<(v32i8  (bitconvert (v8f32 VR256:$src))),  (v32i8 VR256:$src)>;
229   def : Pat<(v32i8  (bitconvert (v8i32 VR256:$src))),  (v32i8 VR256:$src)>;
230   def : Pat<(v32i8  (bitconvert (v16i16 VR256:$src))), (v32i8 VR256:$src)>;
231   def : Pat<(v8i32  (bitconvert (v32i8 VR256:$src))),  (v8i32 VR256:$src)>;
232   def : Pat<(v8i32  (bitconvert (v16i16 VR256:$src))), (v8i32 VR256:$src)>;
233   def : Pat<(v8i32  (bitconvert (v8f32 VR256:$src))),  (v8i32 VR256:$src)>;
234   def : Pat<(v8i32  (bitconvert (v4i64 VR256:$src))),  (v8i32 VR256:$src)>;
235   def : Pat<(v8i32  (bitconvert (v4f64 VR256:$src))),  (v8i32 VR256:$src)>;
236   def : Pat<(v16i16 (bitconvert (v8f32 VR256:$src))),  (v16i16 VR256:$src)>;
237   def : Pat<(v16i16 (bitconvert (v8i32 VR256:$src))),  (v16i16 VR256:$src)>;
238   def : Pat<(v16i16 (bitconvert (v4i64 VR256:$src))),  (v16i16 VR256:$src)>;
239   def : Pat<(v16i16 (bitconvert (v4f64 VR256:$src))),  (v16i16 VR256:$src)>;
240   def : Pat<(v16i16 (bitconvert (v32i8 VR256:$src))),  (v16i16 VR256:$src)>;
241 }
242
243 // Alias instructions that map fld0 to pxor for sse.
244 // This is expanded by ExpandPostRAPseudos.
245 let isReMaterializable = 1, isAsCheapAsAMove = 1, canFoldAsLoad = 1,
246     isPseudo = 1 in {
247   def FsFLD0SS : I<0, Pseudo, (outs FR32:$dst), (ins), "",
248                    [(set FR32:$dst, fp32imm0)]>, Requires<[HasSSE1]>;
249   def FsFLD0SD : I<0, Pseudo, (outs FR64:$dst), (ins), "",
250                    [(set FR64:$dst, fpimm0)]>, Requires<[HasSSE2]>;
251 }
252
253 //===----------------------------------------------------------------------===//
254 // AVX & SSE - Zero/One Vectors
255 //===----------------------------------------------------------------------===//
256
257 // Alias instruction that maps zero vector to pxor / xorp* for sse.
258 // This is expanded by ExpandPostRAPseudos to an xorps / vxorps, and then
259 // swizzled by ExecutionDepsFix to pxor.
260 // We set canFoldAsLoad because this can be converted to a constant-pool
261 // load of an all-zeros value if folding it would be beneficial.
262 let isReMaterializable = 1, isAsCheapAsAMove = 1, canFoldAsLoad = 1,
263     isPseudo = 1, neverHasSideEffects = 1 in {
264 def V_SET0 : I<0, Pseudo, (outs VR128:$dst), (ins), "", []>;
265 }
266
267 def : Pat<(v4f32 immAllZerosV), (V_SET0)>;
268 def : Pat<(v2f64 immAllZerosV), (V_SET0)>;
269 def : Pat<(v4i32 immAllZerosV), (V_SET0)>;
270 def : Pat<(v2i64 immAllZerosV), (V_SET0)>;
271 def : Pat<(v8i16 immAllZerosV), (V_SET0)>;
272 def : Pat<(v16i8 immAllZerosV), (V_SET0)>;
273
274
275 // The same as done above but for AVX.  The 256-bit ISA does not support PI,
276 // and doesn't need it because on sandy bridge the register is set to zero
277 // at the rename stage without using any execution unit, so SET0PSY
278 // and SET0PDY can be used for vector int instructions without penalty
279 // FIXME: Change encoding to pseudo! This is blocked right now by the x86
280 // JIT implementatioan, it does not expand the instructions below like
281 // X86MCInstLower does.
282 let isReMaterializable = 1, isAsCheapAsAMove = 1, canFoldAsLoad = 1,
283     isCodeGenOnly = 1 in {
284 let Predicates = [HasAVX] in {
285 def AVX_SET0PSY : PSI<0x57, MRMInitReg, (outs VR256:$dst), (ins), "",
286                    [(set VR256:$dst, (v8f32 immAllZerosV))]>, VEX_4V;
287 def AVX_SET0PDY : PDI<0x57, MRMInitReg, (outs VR256:$dst), (ins), "",
288                    [(set VR256:$dst, (v4f64 immAllZerosV))]>, VEX_4V;
289 }
290 let Predicates = [HasAVX2], neverHasSideEffects = 1 in
291 def AVX2_SET0   : PDI<0xef, MRMInitReg, (outs VR256:$dst), (ins), "",
292                    []>, VEX_4V;
293 }
294
295 let Predicates = [HasAVX2], AddedComplexity = 5 in {
296   def : Pat<(v4i64 immAllZerosV), (AVX2_SET0)>;
297   def : Pat<(v8i32 immAllZerosV), (AVX2_SET0)>;
298   def : Pat<(v16i16 immAllZerosV), (AVX2_SET0)>;
299   def : Pat<(v32i8 immAllZerosV), (AVX2_SET0)>;
300 }
301
302 // AVX has no support for 256-bit integer instructions, but since the 128-bit
303 // VPXOR instruction writes zero to its upper part, it's safe build zeros.
304 def : Pat<(v32i8 immAllZerosV), (SUBREG_TO_REG (i8 0), (V_SET0), sub_xmm)>;
305 def : Pat<(bc_v32i8 (v8f32 immAllZerosV)),
306           (SUBREG_TO_REG (i8 0), (V_SET0), sub_xmm)>;
307
308 def : Pat<(v16i16 immAllZerosV), (SUBREG_TO_REG (i16 0), (V_SET0), sub_xmm)>;
309 def : Pat<(bc_v16i16 (v8f32 immAllZerosV)),
310           (SUBREG_TO_REG (i16 0), (V_SET0), sub_xmm)>;
311
312 def : Pat<(v8i32 immAllZerosV), (SUBREG_TO_REG (i32 0), (V_SET0), sub_xmm)>;
313 def : Pat<(bc_v8i32 (v8f32 immAllZerosV)),
314           (SUBREG_TO_REG (i32 0), (V_SET0), sub_xmm)>;
315
316 def : Pat<(v4i64 immAllZerosV), (SUBREG_TO_REG (i64 0), (V_SET0), sub_xmm)>;
317 def : Pat<(bc_v4i64 (v8f32 immAllZerosV)),
318           (SUBREG_TO_REG (i64 0), (V_SET0), sub_xmm)>;
319
320 // We set canFoldAsLoad because this can be converted to a constant-pool
321 // load of an all-ones value if folding it would be beneficial.
322 // FIXME: Change encoding to pseudo! This is blocked right now by the x86
323 // JIT implementation, it does not expand the instructions below like
324 // X86MCInstLower does.
325 let isReMaterializable = 1, isAsCheapAsAMove = 1, canFoldAsLoad = 1,
326     isCodeGenOnly = 1, ExeDomain = SSEPackedInt in {
327   let Predicates = [HasAVX] in
328   def AVX_SETALLONES : PDI<0x76, MRMInitReg, (outs VR128:$dst), (ins), "",
329                          [(set VR128:$dst, (v4i32 immAllOnesV))]>, VEX_4V;
330   def V_SETALLONES : PDI<0x76, MRMInitReg, (outs VR128:$dst), (ins), "",
331                          [(set VR128:$dst, (v4i32 immAllOnesV))]>;
332   let Predicates = [HasAVX2] in
333   def AVX2_SETALLONES : PDI<0x76, MRMInitReg, (outs VR256:$dst), (ins), "",
334                           [(set VR256:$dst, (v8i32 immAllOnesV))]>, VEX_4V;
335 }
336
337
338 //===----------------------------------------------------------------------===//
339 // SSE 1 & 2 - Move FP Scalar Instructions
340 //
341 // Move Instructions. Register-to-register movss/movsd is not used for FR32/64
342 // register copies because it's a partial register update; FsMOVAPSrr/FsMOVAPDrr
343 // is used instead. Register-to-register movss/movsd is not modeled as an
344 // INSERT_SUBREG because INSERT_SUBREG requires that the insert be implementable
345 // in terms of a copy, and just mentioned, we don't use movss/movsd for copies.
346 //===----------------------------------------------------------------------===//
347
348 class sse12_move_rr<RegisterClass RC, ValueType vt, string asm> :
349       SI<0x10, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src1, RC:$src2), asm,
350       [(set (vt VR128:$dst), (movl VR128:$src1, (scalar_to_vector RC:$src2)))]>;
351
352 // Loading from memory automatically zeroing upper bits.
353 class sse12_move_rm<RegisterClass RC, X86MemOperand x86memop,
354                     PatFrag mem_pat, string OpcodeStr> :
355       SI<0x10, MRMSrcMem, (outs RC:$dst), (ins x86memop:$src),
356          !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
357                         [(set RC:$dst, (mem_pat addr:$src))]>;
358
359 // AVX
360 def VMOVSSrr : sse12_move_rr<FR32, v4f32,
361                 "movss\t{$src2, $src1, $dst|$dst, $src1, $src2}">, XS, VEX_4V,
362                 VEX_LIG;
363 def VMOVSDrr : sse12_move_rr<FR64, v2f64,
364                 "movsd\t{$src2, $src1, $dst|$dst, $src1, $src2}">, XD, VEX_4V,
365                 VEX_LIG;
366
367 // For the disassembler
368 let isCodeGenOnly = 1 in {
369   def VMOVSSrr_REV : SI<0x11, MRMDestReg, (outs VR128:$dst),
370                         (ins VR128:$src1, FR32:$src2),
371                         "movss\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>,
372                         XS, VEX_4V, VEX_LIG;
373   def VMOVSDrr_REV : SI<0x11, MRMDestReg, (outs VR128:$dst),
374                         (ins VR128:$src1, FR64:$src2),
375                         "movsd\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>,
376                         XD, VEX_4V, VEX_LIG;
377 }
378
379 let canFoldAsLoad = 1, isReMaterializable = 1 in {
380   def VMOVSSrm : sse12_move_rm<FR32, f32mem, loadf32, "movss">, XS, VEX,
381                  VEX_LIG;
382   let AddedComplexity = 20 in
383     def VMOVSDrm : sse12_move_rm<FR64, f64mem, loadf64, "movsd">, XD, VEX,
384                    VEX_LIG;
385 }
386
387 def VMOVSSmr : SI<0x11, MRMDestMem, (outs), (ins f32mem:$dst, FR32:$src),
388                   "movss\t{$src, $dst|$dst, $src}",
389                   [(store FR32:$src, addr:$dst)]>, XS, VEX, VEX_LIG;
390 def VMOVSDmr : SI<0x11, MRMDestMem, (outs), (ins f64mem:$dst, FR64:$src),
391                   "movsd\t{$src, $dst|$dst, $src}",
392                   [(store FR64:$src, addr:$dst)]>, XD, VEX, VEX_LIG;
393
394 // SSE1 & 2
395 let Constraints = "$src1 = $dst" in {
396   def MOVSSrr : sse12_move_rr<FR32, v4f32,
397                           "movss\t{$src2, $dst|$dst, $src2}">, XS;
398   def MOVSDrr : sse12_move_rr<FR64, v2f64,
399                           "movsd\t{$src2, $dst|$dst, $src2}">, XD;
400
401   // For the disassembler
402   let isCodeGenOnly = 1 in {
403     def MOVSSrr_REV : SI<0x11, MRMDestReg, (outs VR128:$dst),
404                          (ins VR128:$src1, FR32:$src2),
405                          "movss\t{$src2, $dst|$dst, $src2}", []>, XS;
406     def MOVSDrr_REV : SI<0x11, MRMDestReg, (outs VR128:$dst),
407                          (ins VR128:$src1, FR64:$src2),
408                          "movsd\t{$src2, $dst|$dst, $src2}", []>, XD;
409   }
410 }
411
412 let canFoldAsLoad = 1, isReMaterializable = 1 in {
413   def MOVSSrm : sse12_move_rm<FR32, f32mem, loadf32, "movss">, XS;
414
415   let AddedComplexity = 20 in
416     def MOVSDrm : sse12_move_rm<FR64, f64mem, loadf64, "movsd">, XD;
417 }
418
419 def MOVSSmr : SSI<0x11, MRMDestMem, (outs), (ins f32mem:$dst, FR32:$src),
420                   "movss\t{$src, $dst|$dst, $src}",
421                   [(store FR32:$src, addr:$dst)]>;
422 def MOVSDmr : SDI<0x11, MRMDestMem, (outs), (ins f64mem:$dst, FR64:$src),
423                   "movsd\t{$src, $dst|$dst, $src}",
424                   [(store FR64:$src, addr:$dst)]>;
425
426 // Patterns
427 let Predicates = [HasAVX] in {
428   let AddedComplexity = 15 in {
429   // Extract the low 32-bit value from one vector and insert it into another.
430   def : Pat<(v4f32 (movl VR128:$src1, VR128:$src2)),
431             (VMOVSSrr (v4f32 VR128:$src1),
432                       (EXTRACT_SUBREG (v4f32 VR128:$src2), sub_ss))>;
433   def : Pat<(v4i32 (movl VR128:$src1, VR128:$src2)),
434             (VMOVSSrr (v4i32 VR128:$src1),
435                       (EXTRACT_SUBREG (v4i32 VR128:$src2), sub_ss))>;
436
437   // Extract the low 64-bit value from one vector and insert it into another.
438   def : Pat<(v2f64 (movl VR128:$src1, VR128:$src2)),
439             (VMOVSDrr (v2f64 VR128:$src1),
440                       (EXTRACT_SUBREG (v2f64 VR128:$src2), sub_sd))>;
441   def : Pat<(v2i64 (movl VR128:$src1, VR128:$src2)),
442             (VMOVSDrr (v2i64 VR128:$src1),
443                       (EXTRACT_SUBREG (v2i64 VR128:$src2), sub_sd))>;
444
445   // vector_shuffle v1, v2 <4, 5, 2, 3> using movsd
446   def : Pat<(v4f32 (movlp VR128:$src1, VR128:$src2)),
447             (VMOVSDrr VR128:$src1, (EXTRACT_SUBREG VR128:$src2, sub_sd))>;
448   def : Pat<(v4i32 (movlp VR128:$src1, VR128:$src2)),
449             (VMOVSDrr VR128:$src1, (EXTRACT_SUBREG VR128:$src2, sub_sd))>;
450
451   // Move scalar to XMM zero-extended, zeroing a VR128 then do a
452   // MOVS{S,D} to the lower bits.
453   def : Pat<(v4f32 (X86vzmovl (v4f32 (scalar_to_vector FR32:$src)))),
454             (VMOVSSrr (v4f32 (V_SET0)), FR32:$src)>;
455   def : Pat<(v4f32 (X86vzmovl (v4f32 VR128:$src))),
456             (VMOVSSrr (v4f32 (V_SET0)),
457                       (f32 (EXTRACT_SUBREG (v4f32 VR128:$src), sub_ss)))>;
458   def : Pat<(v4i32 (X86vzmovl (v4i32 VR128:$src))),
459             (VMOVSSrr (v4i32 (V_SET0)),
460                       (EXTRACT_SUBREG (v4i32 VR128:$src), sub_ss))>;
461   def : Pat<(v2f64 (X86vzmovl (v2f64 (scalar_to_vector FR64:$src)))),
462             (VMOVSDrr (v2f64 (V_SET0)), FR64:$src)>;
463
464   // Move low f32 and clear high bits.
465   def : Pat<(v8f32 (X86vzmovl (v8f32 VR256:$src))),
466             (SUBREG_TO_REG (i32 0),
467               (VMOVSSrr (v4f32 (V_SET0)),
468                         (EXTRACT_SUBREG (v8f32 VR256:$src), sub_ss)), sub_xmm)>;
469   def : Pat<(v8i32 (X86vzmovl (v8i32 VR256:$src))),
470             (SUBREG_TO_REG (i32 0),
471               (VMOVSSrr (v4i32 (V_SET0)),
472                         (EXTRACT_SUBREG (v8i32 VR256:$src), sub_ss)), sub_xmm)>;
473   }
474
475   let AddedComplexity = 20 in {
476   // MOVSSrm zeros the high parts of the register; represent this
477   // with SUBREG_TO_REG. The AVX versions also write: DST[255:128] <- 0
478   def : Pat<(v4f32 (X86vzmovl (v4f32 (scalar_to_vector (loadf32 addr:$src))))),
479             (SUBREG_TO_REG (i32 0), (VMOVSSrm addr:$src), sub_ss)>;
480   def : Pat<(v4f32 (scalar_to_vector (loadf32 addr:$src))),
481             (SUBREG_TO_REG (i32 0), (VMOVSSrm addr:$src), sub_ss)>;
482   def : Pat<(v4f32 (X86vzmovl (loadv4f32 addr:$src))),
483             (SUBREG_TO_REG (i32 0), (VMOVSSrm addr:$src), sub_ss)>;
484
485   // MOVSDrm zeros the high parts of the register; represent this
486   // with SUBREG_TO_REG. The AVX versions also write: DST[255:128] <- 0
487   def : Pat<(v2f64 (X86vzmovl (v2f64 (scalar_to_vector (loadf64 addr:$src))))),
488             (SUBREG_TO_REG (i64 0), (VMOVSDrm addr:$src), sub_sd)>;
489   def : Pat<(v2f64 (scalar_to_vector (loadf64 addr:$src))),
490             (SUBREG_TO_REG (i64 0), (VMOVSDrm addr:$src), sub_sd)>;
491   def : Pat<(v2f64 (X86vzmovl (loadv2f64 addr:$src))),
492             (SUBREG_TO_REG (i64 0), (VMOVSDrm addr:$src), sub_sd)>;
493   def : Pat<(v2f64 (X86vzmovl (bc_v2f64 (loadv4f32 addr:$src)))),
494             (SUBREG_TO_REG (i64 0), (VMOVSDrm addr:$src), sub_sd)>;
495   def : Pat<(v2f64 (X86vzload addr:$src)),
496             (SUBREG_TO_REG (i64 0), (VMOVSDrm addr:$src), sub_sd)>;
497
498   // Represent the same patterns above but in the form they appear for
499   // 256-bit types
500   def : Pat<(v8i32 (X86vzmovl (insert_subvector undef,
501                    (v4i32 (scalar_to_vector (loadi32 addr:$src))), (i32 0)))),
502             (SUBREG_TO_REG (i32 0), (VMOVSSrm addr:$src), sub_ss)>;
503   def : Pat<(v8f32 (X86vzmovl (insert_subvector undef,
504                    (v4f32 (scalar_to_vector (loadf32 addr:$src))), (i32 0)))),
505             (SUBREG_TO_REG (i32 0), (VMOVSSrm addr:$src), sub_ss)>;
506   def : Pat<(v4f64 (X86vzmovl (insert_subvector undef,
507                    (v2f64 (scalar_to_vector (loadf64 addr:$src))), (i32 0)))),
508             (SUBREG_TO_REG (i32 0), (VMOVSDrm addr:$src), sub_sd)>;
509   }
510   def : Pat<(v8f32 (X86vzmovl (insert_subvector undef,
511                    (v4f32 (scalar_to_vector FR32:$src)), (i32 0)))),
512             (SUBREG_TO_REG (i32 0),
513                            (v4f32 (VMOVSSrr (v4f32 (V_SET0)), FR32:$src)),
514                            sub_xmm)>;
515   def : Pat<(v4f64 (X86vzmovl (insert_subvector undef,
516                    (v2f64 (scalar_to_vector FR64:$src)), (i32 0)))),
517             (SUBREG_TO_REG (i64 0),
518                            (v2f64 (VMOVSDrr (v2f64 (V_SET0)), FR64:$src)),
519                            sub_xmm)>;
520   def : Pat<(v4i64 (X86vzmovl (insert_subvector undef,
521                    (v2i64 (scalar_to_vector (loadi64 addr:$src))), (i32 0)))),
522             (SUBREG_TO_REG (i64 0), (VMOVSDrm addr:$src), sub_sd)>;
523
524   // Move low f64 and clear high bits.
525   def : Pat<(v4f64 (X86vzmovl (v4f64 VR256:$src))),
526             (SUBREG_TO_REG (i32 0),
527               (VMOVSDrr (v2f64 (V_SET0)),
528                         (EXTRACT_SUBREG (v4f64 VR256:$src), sub_sd)), sub_xmm)>;
529
530   def : Pat<(v4i64 (X86vzmovl (v4i64 VR256:$src))),
531             (SUBREG_TO_REG (i32 0),
532               (VMOVSDrr (v2i64 (V_SET0)),
533                         (EXTRACT_SUBREG (v4i64 VR256:$src), sub_sd)), sub_xmm)>;
534
535 // Extract and store.
536   def : Pat<(store (f32 (vector_extract (v4f32 VR128:$src), (iPTR 0))),
537                    addr:$dst),
538             (VMOVSSmr addr:$dst,
539                      (EXTRACT_SUBREG (v4f32 VR128:$src), sub_ss))>;
540   def : Pat<(store (f64 (vector_extract (v2f64 VR128:$src), (iPTR 0))),
541                    addr:$dst),
542             (VMOVSDmr addr:$dst,
543                      (EXTRACT_SUBREG (v2f64 VR128:$src), sub_sd))>;
544
545   // Shuffle with VMOVSS
546   def : Pat<(v4f32 (X86Movss VR128:$src1, (scalar_to_vector FR32:$src2))),
547             (VMOVSSrr VR128:$src1, FR32:$src2)>;
548   def : Pat<(v4i32 (X86Movss VR128:$src1, VR128:$src2)),
549             (VMOVSSrr (v4i32 VR128:$src1),
550                       (EXTRACT_SUBREG (v4i32 VR128:$src2), sub_ss))>;
551   def : Pat<(v4f32 (X86Movss VR128:$src1, VR128:$src2)),
552             (VMOVSSrr (v4f32 VR128:$src1),
553                       (EXTRACT_SUBREG (v4f32 VR128:$src2), sub_ss))>;
554
555   // 256-bit variants
556   def : Pat<(v8i32 (X86Movss VR256:$src1, VR256:$src2)),
557             (SUBREG_TO_REG (i32 0),
558                 (VMOVSSrr (EXTRACT_SUBREG (v8i32 VR256:$src1), sub_ss),
559                           (EXTRACT_SUBREG (v8i32 VR256:$src2), sub_ss)), sub_xmm)>;
560   def : Pat<(v8f32 (X86Movss VR256:$src1, VR256:$src2)),
561             (SUBREG_TO_REG (i32 0),
562                 (VMOVSSrr (EXTRACT_SUBREG (v8f32 VR256:$src1), sub_ss),
563                           (EXTRACT_SUBREG (v8f32 VR256:$src2), sub_ss)), sub_xmm)>;
564
565   // Shuffle with VMOVSD
566   def : Pat<(v2f64 (X86Movsd VR128:$src1, (scalar_to_vector FR64:$src2))),
567             (VMOVSDrr VR128:$src1, FR64:$src2)>;
568   def : Pat<(v2i64 (X86Movsd VR128:$src1, VR128:$src2)),
569             (VMOVSDrr (v2i64 VR128:$src1),
570                      (EXTRACT_SUBREG (v2i64 VR128:$src2), sub_sd))>;
571   def : Pat<(v2f64 (X86Movsd VR128:$src1, VR128:$src2)),
572             (VMOVSDrr (v2f64 VR128:$src1),
573                      (EXTRACT_SUBREG (v2f64 VR128:$src2), sub_sd))>;
574   def : Pat<(v4f32 (X86Movsd VR128:$src1, VR128:$src2)),
575             (VMOVSDrr VR128:$src1, (EXTRACT_SUBREG (v4f32 VR128:$src2),
576                                                    sub_sd))>;
577   def : Pat<(v4i32 (X86Movsd VR128:$src1, VR128:$src2)),
578             (VMOVSDrr VR128:$src1, (EXTRACT_SUBREG (v4i32 VR128:$src2),
579                                                    sub_sd))>;
580
581   // 256-bit variants
582   def : Pat<(v4i64 (X86Movsd VR256:$src1, VR256:$src2)),
583             (SUBREG_TO_REG (i32 0),
584                 (VMOVSDrr (EXTRACT_SUBREG (v4i64 VR256:$src1), sub_sd),
585                           (EXTRACT_SUBREG (v4i64 VR256:$src2), sub_sd)), sub_xmm)>;
586   def : Pat<(v4f64 (X86Movsd VR256:$src1, VR256:$src2)),
587             (SUBREG_TO_REG (i32 0),
588                 (VMOVSDrr (EXTRACT_SUBREG (v4f64 VR256:$src1), sub_sd),
589                           (EXTRACT_SUBREG (v4f64 VR256:$src2), sub_sd)), sub_xmm)>;
590
591
592   // FIXME: Instead of a X86Movlps there should be a X86Movsd here, the problem
593   // is during lowering, where it's not possible to recognize the fold cause
594   // it has two uses through a bitcast. One use disappears at isel time and the
595   // fold opportunity reappears.
596   def : Pat<(v2f64 (X86Movlpd VR128:$src1, VR128:$src2)),
597             (VMOVSDrr VR128:$src1, (EXTRACT_SUBREG (v2f64 VR128:$src2),
598                                                    sub_sd))>;
599   def : Pat<(v2i64 (X86Movlpd VR128:$src1, VR128:$src2)),
600             (VMOVSDrr VR128:$src1, (EXTRACT_SUBREG (v2i64 VR128:$src2),
601                                                    sub_sd))>;
602   def : Pat<(v4f32 (X86Movlps VR128:$src1, VR128:$src2)),
603             (VMOVSDrr VR128:$src1, (EXTRACT_SUBREG (v4f32 VR128:$src2),
604                                                    sub_sd))>;
605   def : Pat<(v4i32 (X86Movlps VR128:$src1, VR128:$src2)),
606             (VMOVSDrr VR128:$src1, (EXTRACT_SUBREG (v4i32 VR128:$src2),
607                                                    sub_sd))>;
608 }
609
610 let Predicates = [HasSSE1] in {
611   let AddedComplexity = 15 in {
612   // Extract the low 32-bit value from one vector and insert it into another.
613   def : Pat<(v4f32 (movl VR128:$src1, VR128:$src2)),
614             (MOVSSrr (v4f32 VR128:$src1),
615                      (EXTRACT_SUBREG (v4f32 VR128:$src2), sub_ss))>;
616   def : Pat<(v4i32 (movl VR128:$src1, VR128:$src2)),
617             (MOVSSrr (v4i32 VR128:$src1),
618                      (EXTRACT_SUBREG (v4i32 VR128:$src2), sub_ss))>;
619
620   // Move scalar to XMM zero-extended, zeroing a VR128 then do a
621   // MOVSS to the lower bits.
622   def : Pat<(v4f32 (X86vzmovl (v4f32 (scalar_to_vector FR32:$src)))),
623             (MOVSSrr (v4f32 (V_SET0)), FR32:$src)>;
624   def : Pat<(v4f32 (X86vzmovl (v4f32 VR128:$src))),
625             (MOVSSrr (v4f32 (V_SET0)),
626                      (f32 (EXTRACT_SUBREG (v4f32 VR128:$src), sub_ss)))>;
627   def : Pat<(v4i32 (X86vzmovl (v4i32 VR128:$src))),
628             (MOVSSrr (v4i32 (V_SET0)),
629                      (EXTRACT_SUBREG (v4i32 VR128:$src), sub_ss))>;
630   }
631
632   let AddedComplexity = 20 in {
633   // MOVSSrm zeros the high parts of the register; represent this
634   // with SUBREG_TO_REG.
635   def : Pat<(v4f32 (X86vzmovl (v4f32 (scalar_to_vector (loadf32 addr:$src))))),
636             (SUBREG_TO_REG (i32 0), (MOVSSrm addr:$src), sub_ss)>;
637   def : Pat<(v4f32 (scalar_to_vector (loadf32 addr:$src))),
638             (SUBREG_TO_REG (i32 0), (MOVSSrm addr:$src), sub_ss)>;
639   def : Pat<(v4f32 (X86vzmovl (loadv4f32 addr:$src))),
640             (SUBREG_TO_REG (i32 0), (MOVSSrm addr:$src), sub_ss)>;
641   }
642
643   // Extract and store.
644   def : Pat<(store (f32 (vector_extract (v4f32 VR128:$src), (iPTR 0))),
645                    addr:$dst),
646             (MOVSSmr addr:$dst,
647                      (EXTRACT_SUBREG (v4f32 VR128:$src), sub_ss))>;
648
649   // Shuffle with MOVSS
650   def : Pat<(v4f32 (X86Movss VR128:$src1, (scalar_to_vector FR32:$src2))),
651             (MOVSSrr VR128:$src1, FR32:$src2)>;
652   def : Pat<(v4i32 (X86Movss VR128:$src1, VR128:$src2)),
653             (MOVSSrr (v4i32 VR128:$src1),
654                      (EXTRACT_SUBREG (v4i32 VR128:$src2), sub_ss))>;
655   def : Pat<(v4f32 (X86Movss VR128:$src1, VR128:$src2)),
656             (MOVSSrr (v4f32 VR128:$src1),
657                      (EXTRACT_SUBREG (v4f32 VR128:$src2), sub_ss))>;
658 }
659
660 let Predicates = [HasSSE2] in {
661   let AddedComplexity = 15 in {
662   // Extract the low 64-bit value from one vector and insert it into another.
663   def : Pat<(v2f64 (movl VR128:$src1, VR128:$src2)),
664             (MOVSDrr (v2f64 VR128:$src1),
665                      (EXTRACT_SUBREG (v2f64 VR128:$src2), sub_sd))>;
666   def : Pat<(v2i64 (movl VR128:$src1, VR128:$src2)),
667             (MOVSDrr (v2i64 VR128:$src1),
668                      (EXTRACT_SUBREG (v2i64 VR128:$src2), sub_sd))>;
669
670   // vector_shuffle v1, v2 <4, 5, 2, 3> using movsd
671   def : Pat<(v4f32 (movlp VR128:$src1, VR128:$src2)),
672             (MOVSDrr VR128:$src1, (EXTRACT_SUBREG VR128:$src2, sub_sd))>;
673   def : Pat<(v4i32 (movlp VR128:$src1, VR128:$src2)),
674             (MOVSDrr VR128:$src1, (EXTRACT_SUBREG VR128:$src2, sub_sd))>;
675
676   // Move scalar to XMM zero-extended, zeroing a VR128 then do a
677   // MOVSD to the lower bits.
678   def : Pat<(v2f64 (X86vzmovl (v2f64 (scalar_to_vector FR64:$src)))),
679             (MOVSDrr (v2f64 (V_SET0)), FR64:$src)>;
680   }
681
682   let AddedComplexity = 20 in {
683   // MOVSDrm zeros the high parts of the register; represent this
684   // with SUBREG_TO_REG.
685   def : Pat<(v2f64 (X86vzmovl (v2f64 (scalar_to_vector (loadf64 addr:$src))))),
686             (SUBREG_TO_REG (i64 0), (MOVSDrm addr:$src), sub_sd)>;
687   def : Pat<(v2f64 (scalar_to_vector (loadf64 addr:$src))),
688             (SUBREG_TO_REG (i64 0), (MOVSDrm addr:$src), sub_sd)>;
689   def : Pat<(v2f64 (X86vzmovl (loadv2f64 addr:$src))),
690             (SUBREG_TO_REG (i64 0), (MOVSDrm addr:$src), sub_sd)>;
691   def : Pat<(v2f64 (X86vzmovl (bc_v2f64 (loadv4f32 addr:$src)))),
692             (SUBREG_TO_REG (i64 0), (MOVSDrm addr:$src), sub_sd)>;
693   def : Pat<(v2f64 (X86vzload addr:$src)),
694             (SUBREG_TO_REG (i64 0), (MOVSDrm addr:$src), sub_sd)>;
695   }
696
697   // Extract and store.
698   def : Pat<(store (f64 (vector_extract (v2f64 VR128:$src), (iPTR 0))),
699                    addr:$dst),
700             (MOVSDmr addr:$dst,
701                      (EXTRACT_SUBREG (v2f64 VR128:$src), sub_sd))>;
702
703   // Shuffle with MOVSD
704   def : Pat<(v2f64 (X86Movsd VR128:$src1, (scalar_to_vector FR64:$src2))),
705             (MOVSDrr VR128:$src1, FR64:$src2)>;
706   def : Pat<(v2i64 (X86Movsd VR128:$src1, VR128:$src2)),
707             (MOVSDrr (v2i64 VR128:$src1),
708                      (EXTRACT_SUBREG (v2i64 VR128:$src2), sub_sd))>;
709   def : Pat<(v2f64 (X86Movsd VR128:$src1, VR128:$src2)),
710             (MOVSDrr (v2f64 VR128:$src1),
711                      (EXTRACT_SUBREG (v2f64 VR128:$src2), sub_sd))>;
712   def : Pat<(v4f32 (X86Movsd VR128:$src1, VR128:$src2)),
713             (MOVSDrr VR128:$src1, (EXTRACT_SUBREG (v4f32 VR128:$src2),sub_sd))>;
714   def : Pat<(v4i32 (X86Movsd VR128:$src1, VR128:$src2)),
715             (MOVSDrr VR128:$src1, (EXTRACT_SUBREG (v4i32 VR128:$src2),sub_sd))>;
716
717   // FIXME: Instead of a X86Movlps there should be a X86Movsd here, the problem
718   // is during lowering, where it's not possible to recognize the fold cause
719   // it has two uses through a bitcast. One use disappears at isel time and the
720   // fold opportunity reappears.
721   def : Pat<(v2f64 (X86Movlpd VR128:$src1, VR128:$src2)),
722             (MOVSDrr VR128:$src1, (EXTRACT_SUBREG (v2f64 VR128:$src2),sub_sd))>;
723   def : Pat<(v2i64 (X86Movlpd VR128:$src1, VR128:$src2)),
724             (MOVSDrr VR128:$src1, (EXTRACT_SUBREG (v2i64 VR128:$src2),sub_sd))>;
725   def : Pat<(v4f32 (X86Movlps VR128:$src1, VR128:$src2)),
726             (MOVSDrr VR128:$src1, (EXTRACT_SUBREG (v4f32 VR128:$src2),sub_sd))>;
727   def : Pat<(v4i32 (X86Movlps VR128:$src1, VR128:$src2)),
728             (MOVSDrr VR128:$src1, (EXTRACT_SUBREG (v4i32 VR128:$src2),sub_sd))>;
729 }
730
731 //===----------------------------------------------------------------------===//
732 // SSE 1 & 2 - Move Aligned/Unaligned FP Instructions
733 //===----------------------------------------------------------------------===//
734
735 multiclass sse12_mov_packed<bits<8> opc, RegisterClass RC,
736                             X86MemOperand x86memop, PatFrag ld_frag,
737                             string asm, Domain d,
738                             bit IsReMaterializable = 1> {
739 let neverHasSideEffects = 1 in
740   def rr : PI<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src),
741               !strconcat(asm, "\t{$src, $dst|$dst, $src}"), [], IIC_DEFAULT, d>;
742 let canFoldAsLoad = 1, isReMaterializable = IsReMaterializable in
743   def rm : PI<opc, MRMSrcMem, (outs RC:$dst), (ins x86memop:$src),
744               !strconcat(asm, "\t{$src, $dst|$dst, $src}"),
745                    [(set RC:$dst, (ld_frag addr:$src))], IIC_DEFAULT, d>;
746 }
747
748 defm VMOVAPS : sse12_mov_packed<0x28, VR128, f128mem, alignedloadv4f32,
749                               "movaps", SSEPackedSingle>, TB, VEX;
750 defm VMOVAPD : sse12_mov_packed<0x28, VR128, f128mem, alignedloadv2f64,
751                               "movapd", SSEPackedDouble>, TB, OpSize, VEX;
752 defm VMOVUPS : sse12_mov_packed<0x10, VR128, f128mem, loadv4f32,
753                               "movups", SSEPackedSingle>, TB, VEX;
754 defm VMOVUPD : sse12_mov_packed<0x10, VR128, f128mem, loadv2f64,
755                               "movupd", SSEPackedDouble, 0>, TB, OpSize, VEX;
756
757 defm VMOVAPSY : sse12_mov_packed<0x28, VR256, f256mem, alignedloadv8f32,
758                               "movaps", SSEPackedSingle>, TB, VEX;
759 defm VMOVAPDY : sse12_mov_packed<0x28, VR256, f256mem, alignedloadv4f64,
760                               "movapd", SSEPackedDouble>, TB, OpSize, VEX;
761 defm VMOVUPSY : sse12_mov_packed<0x10, VR256, f256mem, loadv8f32,
762                               "movups", SSEPackedSingle>, TB, VEX;
763 defm VMOVUPDY : sse12_mov_packed<0x10, VR256, f256mem, loadv4f64,
764                               "movupd", SSEPackedDouble, 0>, TB, OpSize, VEX;
765 defm MOVAPS : sse12_mov_packed<0x28, VR128, f128mem, alignedloadv4f32,
766                               "movaps", SSEPackedSingle>, TB;
767 defm MOVAPD : sse12_mov_packed<0x28, VR128, f128mem, alignedloadv2f64,
768                               "movapd", SSEPackedDouble>, TB, OpSize;
769 defm MOVUPS : sse12_mov_packed<0x10, VR128, f128mem, loadv4f32,
770                               "movups", SSEPackedSingle>, TB;
771 defm MOVUPD : sse12_mov_packed<0x10, VR128, f128mem, loadv2f64,
772                               "movupd", SSEPackedDouble, 0>, TB, OpSize;
773
774 def VMOVAPSmr : VPSI<0x29, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
775                    "movaps\t{$src, $dst|$dst, $src}",
776                    [(alignedstore (v4f32 VR128:$src), addr:$dst)]>, VEX;
777 def VMOVAPDmr : VPDI<0x29, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
778                    "movapd\t{$src, $dst|$dst, $src}",
779                    [(alignedstore (v2f64 VR128:$src), addr:$dst)]>, VEX;
780 def VMOVUPSmr : VPSI<0x11, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
781                    "movups\t{$src, $dst|$dst, $src}",
782                    [(store (v4f32 VR128:$src), addr:$dst)]>, VEX;
783 def VMOVUPDmr : VPDI<0x11, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
784                    "movupd\t{$src, $dst|$dst, $src}",
785                    [(store (v2f64 VR128:$src), addr:$dst)]>, VEX;
786 def VMOVAPSYmr : VPSI<0x29, MRMDestMem, (outs), (ins f256mem:$dst, VR256:$src),
787                    "movaps\t{$src, $dst|$dst, $src}",
788                    [(alignedstore256 (v8f32 VR256:$src), addr:$dst)]>, VEX;
789 def VMOVAPDYmr : VPDI<0x29, MRMDestMem, (outs), (ins f256mem:$dst, VR256:$src),
790                    "movapd\t{$src, $dst|$dst, $src}",
791                    [(alignedstore256 (v4f64 VR256:$src), addr:$dst)]>, VEX;
792 def VMOVUPSYmr : VPSI<0x11, MRMDestMem, (outs), (ins f256mem:$dst, VR256:$src),
793                    "movups\t{$src, $dst|$dst, $src}",
794                    [(store (v8f32 VR256:$src), addr:$dst)]>, VEX;
795 def VMOVUPDYmr : VPDI<0x11, MRMDestMem, (outs), (ins f256mem:$dst, VR256:$src),
796                    "movupd\t{$src, $dst|$dst, $src}",
797                    [(store (v4f64 VR256:$src), addr:$dst)]>, VEX;
798
799 // For disassembler
800 let isCodeGenOnly = 1 in {
801   def VMOVAPSrr_REV : VPSI<0x29, MRMDestReg, (outs VR128:$dst),
802                           (ins VR128:$src),
803                           "movaps\t{$src, $dst|$dst, $src}", []>, VEX;
804   def VMOVAPDrr_REV : VPDI<0x29, MRMDestReg, (outs VR128:$dst),
805                            (ins VR128:$src),
806                            "movapd\t{$src, $dst|$dst, $src}", []>, VEX;
807   def VMOVUPSrr_REV : VPSI<0x11, MRMDestReg, (outs VR128:$dst),
808                            (ins VR128:$src),
809                            "movups\t{$src, $dst|$dst, $src}", []>, VEX;
810   def VMOVUPDrr_REV : VPDI<0x11, MRMDestReg, (outs VR128:$dst),
811                            (ins VR128:$src),
812                            "movupd\t{$src, $dst|$dst, $src}", []>, VEX;
813   def VMOVAPSYrr_REV : VPSI<0x29, MRMDestReg, (outs VR256:$dst),
814                             (ins VR256:$src),
815                             "movaps\t{$src, $dst|$dst, $src}", []>, VEX;
816   def VMOVAPDYrr_REV : VPDI<0x29, MRMDestReg, (outs VR256:$dst),
817                             (ins VR256:$src),
818                             "movapd\t{$src, $dst|$dst, $src}", []>, VEX;
819   def VMOVUPSYrr_REV : VPSI<0x11, MRMDestReg, (outs VR256:$dst),
820                             (ins VR256:$src),
821                             "movups\t{$src, $dst|$dst, $src}", []>, VEX;
822   def VMOVUPDYrr_REV : VPDI<0x11, MRMDestReg, (outs VR256:$dst),
823                             (ins VR256:$src),
824                             "movupd\t{$src, $dst|$dst, $src}", []>, VEX;
825 }
826
827 let Predicates = [HasAVX] in {
828 def : Pat<(v8i32 (X86vzmovl
829                         (insert_subvector undef, (v4i32 VR128:$src), (i32 0)))),
830           (SUBREG_TO_REG (i32 0), (VMOVAPSrr VR128:$src), sub_xmm)>;
831 def : Pat<(v4i64 (X86vzmovl
832                         (insert_subvector undef, (v2i64 VR128:$src), (i32 0)))),
833           (SUBREG_TO_REG (i32 0), (VMOVAPSrr VR128:$src), sub_xmm)>;
834 def : Pat<(v8f32 (X86vzmovl
835                         (insert_subvector undef, (v4f32 VR128:$src), (i32 0)))),
836           (SUBREG_TO_REG (i32 0), (VMOVAPSrr VR128:$src), sub_xmm)>;
837 def : Pat<(v4f64 (X86vzmovl
838                         (insert_subvector undef, (v2f64 VR128:$src), (i32 0)))),
839           (SUBREG_TO_REG (i32 0), (VMOVAPSrr VR128:$src), sub_xmm)>;
840 }
841
842
843 def : Pat<(int_x86_avx_storeu_ps_256 addr:$dst, VR256:$src),
844           (VMOVUPSYmr addr:$dst, VR256:$src)>;
845 def : Pat<(int_x86_avx_storeu_pd_256 addr:$dst, VR256:$src),
846           (VMOVUPDYmr addr:$dst, VR256:$src)>;
847
848 def MOVAPSmr : PSI<0x29, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
849                    "movaps\t{$src, $dst|$dst, $src}",
850                    [(alignedstore (v4f32 VR128:$src), addr:$dst)]>;
851 def MOVAPDmr : PDI<0x29, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
852                    "movapd\t{$src, $dst|$dst, $src}",
853                    [(alignedstore (v2f64 VR128:$src), addr:$dst)]>;
854 def MOVUPSmr : PSI<0x11, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
855                    "movups\t{$src, $dst|$dst, $src}",
856                    [(store (v4f32 VR128:$src), addr:$dst)]>;
857 def MOVUPDmr : PDI<0x11, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
858                    "movupd\t{$src, $dst|$dst, $src}",
859                    [(store (v2f64 VR128:$src), addr:$dst)]>;
860
861 // For disassembler
862 let isCodeGenOnly = 1 in {
863   def MOVAPSrr_REV : PSI<0x29, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
864                          "movaps\t{$src, $dst|$dst, $src}", []>;
865   def MOVAPDrr_REV : PDI<0x29, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
866                          "movapd\t{$src, $dst|$dst, $src}", []>;
867   def MOVUPSrr_REV : PSI<0x11, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
868                          "movups\t{$src, $dst|$dst, $src}", []>;
869   def MOVUPDrr_REV : PDI<0x11, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
870                          "movupd\t{$src, $dst|$dst, $src}", []>;
871 }
872
873 let Predicates = [HasAVX] in {
874   def : Pat<(int_x86_sse_storeu_ps addr:$dst, VR128:$src),
875             (VMOVUPSmr addr:$dst, VR128:$src)>;
876   def : Pat<(int_x86_sse2_storeu_pd addr:$dst, VR128:$src),
877             (VMOVUPDmr addr:$dst, VR128:$src)>;
878 }
879
880 let Predicates = [HasSSE1] in
881   def : Pat<(int_x86_sse_storeu_ps addr:$dst, VR128:$src),
882             (MOVUPSmr addr:$dst, VR128:$src)>;
883 let Predicates = [HasSSE2] in
884   def : Pat<(int_x86_sse2_storeu_pd addr:$dst, VR128:$src),
885             (MOVUPDmr addr:$dst, VR128:$src)>;
886
887 // Use vmovaps/vmovups for AVX integer load/store.
888 let Predicates = [HasAVX] in {
889   // 128-bit load/store
890   def : Pat<(alignedloadv2i64 addr:$src),
891             (VMOVAPSrm addr:$src)>;
892   def : Pat<(loadv2i64 addr:$src),
893             (VMOVUPSrm addr:$src)>;
894
895   def : Pat<(alignedstore (v2i64 VR128:$src), addr:$dst),
896             (VMOVAPSmr addr:$dst, VR128:$src)>;
897   def : Pat<(alignedstore (v4i32 VR128:$src), addr:$dst),
898             (VMOVAPSmr addr:$dst, VR128:$src)>;
899   def : Pat<(alignedstore (v8i16 VR128:$src), addr:$dst),
900             (VMOVAPSmr addr:$dst, VR128:$src)>;
901   def : Pat<(alignedstore (v16i8 VR128:$src), addr:$dst),
902             (VMOVAPSmr addr:$dst, VR128:$src)>;
903   def : Pat<(store (v2i64 VR128:$src), addr:$dst),
904             (VMOVUPSmr addr:$dst, VR128:$src)>;
905   def : Pat<(store (v4i32 VR128:$src), addr:$dst),
906             (VMOVUPSmr addr:$dst, VR128:$src)>;
907   def : Pat<(store (v8i16 VR128:$src), addr:$dst),
908             (VMOVUPSmr addr:$dst, VR128:$src)>;
909   def : Pat<(store (v16i8 VR128:$src), addr:$dst),
910             (VMOVUPSmr addr:$dst, VR128:$src)>;
911
912   // 256-bit load/store
913   def : Pat<(alignedloadv4i64 addr:$src),
914             (VMOVAPSYrm addr:$src)>;
915   def : Pat<(loadv4i64 addr:$src),
916             (VMOVUPSYrm addr:$src)>;
917   def : Pat<(alignedstore256 (v4i64 VR256:$src), addr:$dst),
918             (VMOVAPSYmr addr:$dst, VR256:$src)>;
919   def : Pat<(alignedstore256 (v8i32 VR256:$src), addr:$dst),
920             (VMOVAPSYmr addr:$dst, VR256:$src)>;
921   def : Pat<(alignedstore256 (v16i16 VR256:$src), addr:$dst),
922             (VMOVAPSYmr addr:$dst, VR256:$src)>;
923   def : Pat<(alignedstore256 (v32i8 VR256:$src), addr:$dst),
924             (VMOVAPSYmr addr:$dst, VR256:$src)>;
925   def : Pat<(store (v4i64 VR256:$src), addr:$dst),
926             (VMOVUPSYmr addr:$dst, VR256:$src)>;
927   def : Pat<(store (v8i32 VR256:$src), addr:$dst),
928             (VMOVUPSYmr addr:$dst, VR256:$src)>;
929   def : Pat<(store (v16i16 VR256:$src), addr:$dst),
930             (VMOVUPSYmr addr:$dst, VR256:$src)>;
931   def : Pat<(store (v32i8 VR256:$src), addr:$dst),
932             (VMOVUPSYmr addr:$dst, VR256:$src)>;
933 }
934
935 // Use movaps / movups for SSE integer load / store (one byte shorter).
936 // The instructions selected below are then converted to MOVDQA/MOVDQU
937 // during the SSE domain pass.
938 let Predicates = [HasSSE1] in {
939   def : Pat<(alignedloadv2i64 addr:$src),
940             (MOVAPSrm addr:$src)>;
941   def : Pat<(loadv2i64 addr:$src),
942             (MOVUPSrm addr:$src)>;
943
944   def : Pat<(alignedstore (v2i64 VR128:$src), addr:$dst),
945             (MOVAPSmr addr:$dst, VR128:$src)>;
946   def : Pat<(alignedstore (v4i32 VR128:$src), addr:$dst),
947             (MOVAPSmr addr:$dst, VR128:$src)>;
948   def : Pat<(alignedstore (v8i16 VR128:$src), addr:$dst),
949             (MOVAPSmr addr:$dst, VR128:$src)>;
950   def : Pat<(alignedstore (v16i8 VR128:$src), addr:$dst),
951             (MOVAPSmr addr:$dst, VR128:$src)>;
952   def : Pat<(store (v2i64 VR128:$src), addr:$dst),
953             (MOVUPSmr addr:$dst, VR128:$src)>;
954   def : Pat<(store (v4i32 VR128:$src), addr:$dst),
955             (MOVUPSmr addr:$dst, VR128:$src)>;
956   def : Pat<(store (v8i16 VR128:$src), addr:$dst),
957             (MOVUPSmr addr:$dst, VR128:$src)>;
958   def : Pat<(store (v16i8 VR128:$src), addr:$dst),
959             (MOVUPSmr addr:$dst, VR128:$src)>;
960 }
961
962 // Alias instruction to do FR32 or FR64 reg-to-reg copy using movaps. Upper
963 // bits are disregarded. FIXME: Set encoding to pseudo!
964 let neverHasSideEffects = 1 in {
965 def FsVMOVAPSrr : VPSI<0x28, MRMSrcReg, (outs FR32:$dst), (ins FR32:$src),
966                        "movaps\t{$src, $dst|$dst, $src}", []>, VEX;
967 def FsVMOVAPDrr : VPDI<0x28, MRMSrcReg, (outs FR64:$dst), (ins FR64:$src),
968                        "movapd\t{$src, $dst|$dst, $src}", []>, VEX;
969 def FsMOVAPSrr : PSI<0x28, MRMSrcReg, (outs FR32:$dst), (ins FR32:$src),
970                      "movaps\t{$src, $dst|$dst, $src}", []>;
971 def FsMOVAPDrr : PDI<0x28, MRMSrcReg, (outs FR64:$dst), (ins FR64:$src),
972                      "movapd\t{$src, $dst|$dst, $src}", []>;
973 }
974
975 // Alias instruction to load FR32 or FR64 from f128mem using movaps. Upper
976 // bits are disregarded. FIXME: Set encoding to pseudo!
977 let canFoldAsLoad = 1, isReMaterializable = 1 in {
978 let isCodeGenOnly = 1 in {
979   def FsVMOVAPSrm : VPSI<0x28, MRMSrcMem, (outs FR32:$dst), (ins f128mem:$src),
980                          "movaps\t{$src, $dst|$dst, $src}",
981                          [(set FR32:$dst, (alignedloadfsf32 addr:$src))]>, VEX;
982   def FsVMOVAPDrm : VPDI<0x28, MRMSrcMem, (outs FR64:$dst), (ins f128mem:$src),
983                          "movapd\t{$src, $dst|$dst, $src}",
984                          [(set FR64:$dst, (alignedloadfsf64 addr:$src))]>, VEX;
985 }
986 def FsMOVAPSrm : PSI<0x28, MRMSrcMem, (outs FR32:$dst), (ins f128mem:$src),
987                      "movaps\t{$src, $dst|$dst, $src}",
988                      [(set FR32:$dst, (alignedloadfsf32 addr:$src))]>;
989 def FsMOVAPDrm : PDI<0x28, MRMSrcMem, (outs FR64:$dst), (ins f128mem:$src),
990                      "movapd\t{$src, $dst|$dst, $src}",
991                      [(set FR64:$dst, (alignedloadfsf64 addr:$src))]>;
992 }
993
994 //===----------------------------------------------------------------------===//
995 // SSE 1 & 2 - Move Low packed FP Instructions
996 //===----------------------------------------------------------------------===//
997
998 multiclass sse12_mov_hilo_packed<bits<8>opc, RegisterClass RC,
999                                  PatFrag mov_frag, string base_opc,
1000                                  string asm_opr> {
1001   def PSrm : PI<opc, MRMSrcMem,
1002          (outs VR128:$dst), (ins VR128:$src1, f64mem:$src2),
1003          !strconcat(base_opc, "s", asm_opr),
1004      [(set RC:$dst,
1005        (mov_frag RC:$src1,
1006               (bc_v4f32 (v2f64 (scalar_to_vector (loadf64 addr:$src2))))))],
1007               IIC_DEFAULT, SSEPackedSingle>, TB;
1008
1009   def PDrm : PI<opc, MRMSrcMem,
1010          (outs RC:$dst), (ins RC:$src1, f64mem:$src2),
1011          !strconcat(base_opc, "d", asm_opr),
1012      [(set RC:$dst, (v2f64 (mov_frag RC:$src1,
1013                               (scalar_to_vector (loadf64 addr:$src2)))))],
1014               IIC_DEFAULT, SSEPackedDouble>, TB, OpSize;
1015 }
1016
1017 let AddedComplexity = 20 in {
1018   defm VMOVL : sse12_mov_hilo_packed<0x12, VR128, movlp, "movlp",
1019                      "\t{$src2, $src1, $dst|$dst, $src1, $src2}">, VEX_4V;
1020 }
1021 let Constraints = "$src1 = $dst", AddedComplexity = 20 in {
1022   defm MOVL : sse12_mov_hilo_packed<0x12, VR128, movlp, "movlp",
1023                                    "\t{$src2, $dst|$dst, $src2}">;
1024 }
1025
1026 def VMOVLPSmr : VPSI<0x13, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
1027                    "movlps\t{$src, $dst|$dst, $src}",
1028                    [(store (f64 (vector_extract (bc_v2f64 (v4f32 VR128:$src)),
1029                                  (iPTR 0))), addr:$dst)]>, VEX;
1030 def VMOVLPDmr : VPDI<0x13, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
1031                    "movlpd\t{$src, $dst|$dst, $src}",
1032                    [(store (f64 (vector_extract (v2f64 VR128:$src),
1033                                  (iPTR 0))), addr:$dst)]>, VEX;
1034 def MOVLPSmr : PSI<0x13, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
1035                    "movlps\t{$src, $dst|$dst, $src}",
1036                    [(store (f64 (vector_extract (bc_v2f64 (v4f32 VR128:$src)),
1037                                  (iPTR 0))), addr:$dst)]>;
1038 def MOVLPDmr : PDI<0x13, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
1039                    "movlpd\t{$src, $dst|$dst, $src}",
1040                    [(store (f64 (vector_extract (v2f64 VR128:$src),
1041                                  (iPTR 0))), addr:$dst)]>;
1042
1043 let Predicates = [HasAVX] in {
1044   let AddedComplexity = 20 in {
1045     // vector_shuffle v1, (load v2) <4, 5, 2, 3> using MOVLPS
1046     def : Pat<(v4f32 (movlp VR128:$src1, (load addr:$src2))),
1047               (VMOVLPSrm VR128:$src1, addr:$src2)>;
1048     def : Pat<(v4i32 (movlp VR128:$src1, (load addr:$src2))),
1049               (VMOVLPSrm VR128:$src1, addr:$src2)>;
1050     // vector_shuffle v1, (load v2) <2, 1> using MOVLPS
1051     def : Pat<(v2f64 (movlp VR128:$src1, (load addr:$src2))),
1052               (VMOVLPDrm VR128:$src1, addr:$src2)>;
1053     def : Pat<(v2i64 (movlp VR128:$src1, (load addr:$src2))),
1054               (VMOVLPDrm VR128:$src1, addr:$src2)>;
1055   }
1056
1057   // (store (vector_shuffle (load addr), v2, <4, 5, 2, 3>), addr) using MOVLPS
1058   def : Pat<(store (v4f32 (movlp (load addr:$src1), VR128:$src2)), addr:$src1),
1059             (VMOVLPSmr addr:$src1, VR128:$src2)>;
1060   def : Pat<(store (v4i32 (movlp (bc_v4i32 (loadv2i64 addr:$src1)),
1061                                  VR128:$src2)), addr:$src1),
1062             (VMOVLPSmr addr:$src1, VR128:$src2)>;
1063
1064   // (store (vector_shuffle (load addr), v2, <2, 1>), addr) using MOVLPS
1065   def : Pat<(store (v2f64 (movlp (load addr:$src1), VR128:$src2)), addr:$src1),
1066             (VMOVLPDmr addr:$src1, VR128:$src2)>;
1067   def : Pat<(store (v2i64 (movlp (load addr:$src1), VR128:$src2)), addr:$src1),
1068             (VMOVLPDmr addr:$src1, VR128:$src2)>;
1069
1070   // Shuffle with VMOVLPS
1071   def : Pat<(v4f32 (X86Movlps VR128:$src1, (load addr:$src2))),
1072             (VMOVLPSrm VR128:$src1, addr:$src2)>;
1073   def : Pat<(v4i32 (X86Movlps VR128:$src1, (load addr:$src2))),
1074             (VMOVLPSrm VR128:$src1, addr:$src2)>;
1075   def : Pat<(X86Movlps VR128:$src1,
1076                       (bc_v4f32 (v2f64 (scalar_to_vector (loadf64 addr:$src2))))),
1077             (VMOVLPSrm VR128:$src1, addr:$src2)>;
1078
1079   // Shuffle with VMOVLPD
1080   def : Pat<(v2f64 (X86Movlpd VR128:$src1, (load addr:$src2))),
1081             (VMOVLPDrm VR128:$src1, addr:$src2)>;
1082   def : Pat<(v2i64 (X86Movlpd VR128:$src1, (load addr:$src2))),
1083             (VMOVLPDrm VR128:$src1, addr:$src2)>;
1084   def : Pat<(v2f64 (X86Movlpd VR128:$src1,
1085                               (scalar_to_vector (loadf64 addr:$src2)))),
1086             (VMOVLPDrm VR128:$src1, addr:$src2)>;
1087
1088   // Store patterns
1089   def : Pat<(store (v4f32 (X86Movlps (load addr:$src1), VR128:$src2)),
1090                    addr:$src1),
1091             (VMOVLPSmr addr:$src1, VR128:$src2)>;
1092   def : Pat<(store (v4i32 (X86Movlps
1093                    (bc_v4i32 (loadv2i64 addr:$src1)), VR128:$src2)), addr:$src1),
1094             (VMOVLPSmr addr:$src1, VR128:$src2)>;
1095   def : Pat<(store (v2f64 (X86Movlpd (load addr:$src1), VR128:$src2)),
1096                    addr:$src1),
1097             (VMOVLPDmr addr:$src1, VR128:$src2)>;
1098   def : Pat<(store (v2i64 (X86Movlpd (load addr:$src1), VR128:$src2)),
1099                    addr:$src1),
1100             (VMOVLPDmr addr:$src1, VR128:$src2)>;
1101 }
1102
1103 let Predicates = [HasSSE1] in {
1104   let AddedComplexity = 20 in {
1105     // vector_shuffle v1, (load v2) <4, 5, 2, 3> using MOVLPS
1106     def : Pat<(v4f32 (movlp VR128:$src1, (load addr:$src2))),
1107               (MOVLPSrm VR128:$src1, addr:$src2)>;
1108     def : Pat<(v4i32 (movlp VR128:$src1, (load addr:$src2))),
1109               (MOVLPSrm VR128:$src1, addr:$src2)>;
1110   }
1111
1112   // (store (vector_shuffle (load addr), v2, <4, 5, 2, 3>), addr) using MOVLPS
1113   def : Pat<(store (i64 (vector_extract (bc_v2i64 (v4f32 VR128:$src2)),
1114                                  (iPTR 0))), addr:$src1),
1115             (MOVLPSmr addr:$src1, VR128:$src2)>;
1116   def : Pat<(store (v4f32 (movlp (load addr:$src1), VR128:$src2)), addr:$src1),
1117             (MOVLPSmr addr:$src1, VR128:$src2)>;
1118   def : Pat<(store (v4i32 (movlp (bc_v4i32 (loadv2i64 addr:$src1)),
1119                                  VR128:$src2)), addr:$src1),
1120             (MOVLPSmr addr:$src1, VR128:$src2)>;
1121
1122   // Shuffle with MOVLPS
1123   def : Pat<(v4f32 (X86Movlps VR128:$src1, (load addr:$src2))),
1124             (MOVLPSrm VR128:$src1, addr:$src2)>;
1125   def : Pat<(v4i32 (X86Movlps VR128:$src1, (load addr:$src2))),
1126             (MOVLPSrm VR128:$src1, addr:$src2)>;
1127   def : Pat<(X86Movlps VR128:$src1,
1128                       (bc_v4f32 (v2f64 (scalar_to_vector (loadf64 addr:$src2))))),
1129             (MOVLPSrm VR128:$src1, addr:$src2)>;
1130   def : Pat<(X86Movlps VR128:$src1,
1131                       (bc_v4f32 (v2i64 (scalar_to_vector (loadi64 addr:$src2))))),
1132             (MOVLPSrm VR128:$src1, addr:$src2)>;
1133
1134   // Store patterns
1135   def : Pat<(store (v4f32 (X86Movlps (load addr:$src1), VR128:$src2)),
1136                                       addr:$src1),
1137             (MOVLPSmr addr:$src1, VR128:$src2)>;
1138   def : Pat<(store (v4i32 (X86Movlps
1139                    (bc_v4i32 (loadv2i64 addr:$src1)), VR128:$src2)),
1140                               addr:$src1),
1141             (MOVLPSmr addr:$src1, VR128:$src2)>;
1142 }
1143
1144 let Predicates = [HasSSE2] in {
1145   let AddedComplexity = 20 in {
1146     // vector_shuffle v1, (load v2) <2, 1> using MOVLPS
1147     def : Pat<(v2f64 (movlp VR128:$src1, (load addr:$src2))),
1148               (MOVLPDrm VR128:$src1, addr:$src2)>;
1149     def : Pat<(v2i64 (movlp VR128:$src1, (load addr:$src2))),
1150               (MOVLPDrm VR128:$src1, addr:$src2)>;
1151   }
1152
1153   // (store (vector_shuffle (load addr), v2, <2, 1>), addr) using MOVLPS
1154   def : Pat<(store (v2f64 (movlp (load addr:$src1), VR128:$src2)), addr:$src1),
1155             (MOVLPDmr addr:$src1, VR128:$src2)>;
1156   def : Pat<(store (v2i64 (movlp (load addr:$src1), VR128:$src2)), addr:$src1),
1157             (MOVLPDmr addr:$src1, VR128:$src2)>;
1158
1159   // Shuffle with MOVLPD
1160   def : Pat<(v2f64 (X86Movlpd VR128:$src1, (load addr:$src2))),
1161             (MOVLPDrm VR128:$src1, addr:$src2)>;
1162   def : Pat<(v2i64 (X86Movlpd VR128:$src1, (load addr:$src2))),
1163             (MOVLPDrm VR128:$src1, addr:$src2)>;
1164   def : Pat<(v2f64 (X86Movlpd VR128:$src1,
1165                               (scalar_to_vector (loadf64 addr:$src2)))),
1166             (MOVLPDrm VR128:$src1, addr:$src2)>;
1167
1168   // Store patterns
1169   def : Pat<(store (v2f64 (X86Movlpd (load addr:$src1), VR128:$src2)),
1170                            addr:$src1),
1171             (MOVLPDmr addr:$src1, VR128:$src2)>;
1172   def : Pat<(store (v2i64 (X86Movlpd (load addr:$src1), VR128:$src2)),
1173                            addr:$src1),
1174             (MOVLPDmr addr:$src1, VR128:$src2)>;
1175 }
1176
1177 //===----------------------------------------------------------------------===//
1178 // SSE 1 & 2 - Move Hi packed FP Instructions
1179 //===----------------------------------------------------------------------===//
1180
1181 let AddedComplexity = 20 in {
1182   defm VMOVH : sse12_mov_hilo_packed<0x16, VR128, movlhps, "movhp",
1183                      "\t{$src2, $src1, $dst|$dst, $src1, $src2}">, VEX_4V;
1184 }
1185 let Constraints = "$src1 = $dst", AddedComplexity = 20 in {
1186   defm MOVH : sse12_mov_hilo_packed<0x16, VR128, movlhps, "movhp",
1187                                    "\t{$src2, $dst|$dst, $src2}">;
1188 }
1189
1190 // v2f64 extract element 1 is always custom lowered to unpack high to low
1191 // and extract element 0 so the non-store version isn't too horrible.
1192 def VMOVHPSmr : VPSI<0x17, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
1193                    "movhps\t{$src, $dst|$dst, $src}",
1194                    [(store (f64 (vector_extract
1195                                  (unpckh (bc_v2f64 (v4f32 VR128:$src)),
1196                                          (undef)), (iPTR 0))), addr:$dst)]>,
1197                    VEX;
1198 def VMOVHPDmr : VPDI<0x17, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
1199                    "movhpd\t{$src, $dst|$dst, $src}",
1200                    [(store (f64 (vector_extract
1201                                  (v2f64 (unpckh VR128:$src, (undef))),
1202                                  (iPTR 0))), addr:$dst)]>,
1203                    VEX;
1204 def MOVHPSmr : PSI<0x17, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
1205                    "movhps\t{$src, $dst|$dst, $src}",
1206                    [(store (f64 (vector_extract
1207                                  (unpckh (bc_v2f64 (v4f32 VR128:$src)),
1208                                          (undef)), (iPTR 0))), addr:$dst)]>;
1209 def MOVHPDmr : PDI<0x17, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
1210                    "movhpd\t{$src, $dst|$dst, $src}",
1211                    [(store (f64 (vector_extract
1212                                  (v2f64 (unpckh VR128:$src, (undef))),
1213                                  (iPTR 0))), addr:$dst)]>;
1214
1215 let Predicates = [HasAVX] in {
1216   // VMOVHPS patterns
1217   def : Pat<(movlhps VR128:$src1, (bc_v4i32 (v2i64 (X86vzload addr:$src2)))),
1218             (VMOVHPSrm (v4i32 VR128:$src1), addr:$src2)>;
1219   def : Pat<(X86Movlhps VR128:$src1,
1220                  (bc_v4f32 (v2f64 (scalar_to_vector (loadf64 addr:$src2))))),
1221             (VMOVHPSrm VR128:$src1, addr:$src2)>;
1222   def : Pat<(X86Movlhps VR128:$src1,
1223                  (bc_v4f32 (v2i64 (scalar_to_vector (loadi64 addr:$src2))))),
1224             (VMOVHPSrm VR128:$src1, addr:$src2)>;
1225   def : Pat<(X86Movlhps VR128:$src1,
1226                  (bc_v4i32 (v2i64 (X86vzload addr:$src2)))),
1227             (VMOVHPSrm VR128:$src1, addr:$src2)>;
1228
1229   // FIXME: Instead of X86Unpckl, there should be a X86Movlhpd here, the problem
1230   // is during lowering, where it's not possible to recognize the load fold 
1231   // cause it has two uses through a bitcast. One use disappears at isel time
1232   // and the fold opportunity reappears.
1233   def : Pat<(v2f64 (X86Unpckl VR128:$src1,
1234                       (scalar_to_vector (loadf64 addr:$src2)))),
1235             (VMOVHPDrm VR128:$src1, addr:$src2)>;
1236
1237   // FIXME: This should be matched by a X86Movhpd instead. Same as above
1238   def : Pat<(v2f64 (X86Movlhpd VR128:$src1,
1239                       (scalar_to_vector (loadf64 addr:$src2)))),
1240             (VMOVHPDrm VR128:$src1, addr:$src2)>;
1241
1242   // Store patterns
1243   def : Pat<(store (f64 (vector_extract
1244             (X86Unpckh (bc_v2f64 (v4f32 VR128:$src)),
1245                        (bc_v2f64 (v4f32 VR128:$src))), (iPTR 0))), addr:$dst),
1246             (VMOVHPSmr addr:$dst, VR128:$src)>;
1247   def : Pat<(store (f64 (vector_extract
1248             (v2f64 (X86Unpckh VR128:$src, VR128:$src)), (iPTR 0))), addr:$dst),
1249             (VMOVHPDmr addr:$dst, VR128:$src)>;
1250 }
1251
1252 let Predicates = [HasSSE1] in {
1253   // MOVHPS patterns
1254   def : Pat<(movlhps VR128:$src1, (bc_v4i32 (v2i64 (X86vzload addr:$src2)))),
1255             (MOVHPSrm (v4i32 VR128:$src1), addr:$src2)>;
1256   def : Pat<(X86Movlhps VR128:$src1,
1257                  (bc_v4f32 (v2f64 (scalar_to_vector (loadf64 addr:$src2))))),
1258             (MOVHPSrm VR128:$src1, addr:$src2)>;
1259   def : Pat<(X86Movlhps VR128:$src1,
1260                  (bc_v4f32 (v2i64 (scalar_to_vector (loadi64 addr:$src2))))),
1261             (MOVHPSrm VR128:$src1, addr:$src2)>;
1262   def : Pat<(X86Movlhps VR128:$src1,
1263                  (bc_v4f32 (v2i64 (X86vzload addr:$src2)))),
1264             (MOVHPSrm VR128:$src1, addr:$src2)>;
1265
1266   // Store patterns
1267   def : Pat<(store (f64 (vector_extract
1268             (X86Unpckh (bc_v2f64 (v4f32 VR128:$src)),
1269                        (bc_v2f64 (v4f32 VR128:$src))), (iPTR 0))), addr:$dst),
1270             (MOVHPSmr addr:$dst, VR128:$src)>;
1271 }
1272
1273 let Predicates = [HasSSE2] in {
1274   // FIXME: Instead of X86Unpckl, there should be a X86Movlhpd here, the problem
1275   // is during lowering, where it's not possible to recognize the load fold 
1276   // cause it has two uses through a bitcast. One use disappears at isel time
1277   // and the fold opportunity reappears.
1278   def : Pat<(v2f64 (X86Unpckl VR128:$src1,
1279                       (scalar_to_vector (loadf64 addr:$src2)))),
1280             (MOVHPDrm VR128:$src1, addr:$src2)>;
1281
1282   // FIXME: This should be matched by a X86Movhpd instead. Same as above
1283   def : Pat<(v2f64 (X86Movlhpd VR128:$src1,
1284                       (scalar_to_vector (loadf64 addr:$src2)))),
1285             (MOVHPDrm VR128:$src1, addr:$src2)>;
1286
1287   // Store patterns
1288   def : Pat<(store (f64 (vector_extract
1289             (v2f64 (X86Unpckh VR128:$src, VR128:$src)), (iPTR 0))),addr:$dst),
1290             (MOVHPDmr addr:$dst, VR128:$src)>;
1291 }
1292
1293 //===----------------------------------------------------------------------===//
1294 // SSE 1 & 2 - Move Low to High and High to Low packed FP Instructions
1295 //===----------------------------------------------------------------------===//
1296
1297 let AddedComplexity = 20 in {
1298   def VMOVLHPSrr : VPSI<0x16, MRMSrcReg, (outs VR128:$dst),
1299                                        (ins VR128:$src1, VR128:$src2),
1300                       "movlhps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1301                       [(set VR128:$dst,
1302                         (v4f32 (movlhps VR128:$src1, VR128:$src2)))]>,
1303                       VEX_4V;
1304   def VMOVHLPSrr : VPSI<0x12, MRMSrcReg, (outs VR128:$dst),
1305                                        (ins VR128:$src1, VR128:$src2),
1306                       "movhlps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1307                       [(set VR128:$dst,
1308                         (v4f32 (movhlps VR128:$src1, VR128:$src2)))]>,
1309                       VEX_4V;
1310 }
1311 let Constraints = "$src1 = $dst", AddedComplexity = 20 in {
1312   def MOVLHPSrr : PSI<0x16, MRMSrcReg, (outs VR128:$dst),
1313                                        (ins VR128:$src1, VR128:$src2),
1314                       "movlhps\t{$src2, $dst|$dst, $src2}",
1315                       [(set VR128:$dst,
1316                         (v4f32 (movlhps VR128:$src1, VR128:$src2)))]>;
1317   def MOVHLPSrr : PSI<0x12, MRMSrcReg, (outs VR128:$dst),
1318                                        (ins VR128:$src1, VR128:$src2),
1319                       "movhlps\t{$src2, $dst|$dst, $src2}",
1320                       [(set VR128:$dst,
1321                         (v4f32 (movhlps VR128:$src1, VR128:$src2)))]>;
1322 }
1323
1324 let Predicates = [HasAVX] in {
1325   // MOVLHPS patterns
1326   let AddedComplexity = 20 in {
1327     def : Pat<(v4f32 (movddup VR128:$src, (undef))),
1328               (VMOVLHPSrr (v4f32 VR128:$src), (v4f32 VR128:$src))>;
1329     def : Pat<(v2i64 (movddup VR128:$src, (undef))),
1330               (VMOVLHPSrr (v2i64 VR128:$src), (v2i64 VR128:$src))>;
1331
1332     // vector_shuffle v1, v2 <0, 1, 4, 5> using MOVLHPS
1333     def : Pat<(v4i32 (movlhps VR128:$src1, VR128:$src2)),
1334               (VMOVLHPSrr VR128:$src1, VR128:$src2)>;
1335   }
1336   def : Pat<(v4f32 (X86Movlhps VR128:$src1, VR128:$src2)),
1337             (VMOVLHPSrr VR128:$src1, VR128:$src2)>;
1338   def : Pat<(v4i32 (X86Movlhps VR128:$src1, VR128:$src2)),
1339             (VMOVLHPSrr VR128:$src1, VR128:$src2)>;
1340   def : Pat<(v2i64 (X86Movlhps VR128:$src1, VR128:$src2)),
1341             (VMOVLHPSrr (v2i64 VR128:$src1), VR128:$src2)>;
1342
1343   // MOVHLPS patterns
1344   let AddedComplexity = 20 in {
1345     // vector_shuffle v1, v2 <6, 7, 2, 3> using MOVHLPS
1346     def : Pat<(v4i32 (movhlps VR128:$src1, VR128:$src2)),
1347               (VMOVHLPSrr VR128:$src1, VR128:$src2)>;
1348
1349     // vector_shuffle v1, undef <2, ?, ?, ?> using MOVHLPS
1350     def : Pat<(v4f32 (movhlps_undef VR128:$src1, (undef))),
1351               (VMOVHLPSrr VR128:$src1, VR128:$src1)>;
1352     def : Pat<(v4i32 (movhlps_undef VR128:$src1, (undef))),
1353               (VMOVHLPSrr VR128:$src1, VR128:$src1)>;
1354   }
1355
1356   def : Pat<(v4f32 (X86Movhlps VR128:$src1, VR128:$src2)),
1357             (VMOVHLPSrr VR128:$src1, VR128:$src2)>;
1358   def : Pat<(v4i32 (X86Movhlps VR128:$src1, VR128:$src2)),
1359             (VMOVHLPSrr VR128:$src1, VR128:$src2)>;
1360 }
1361
1362 let Predicates = [HasSSE1] in {
1363   // MOVLHPS patterns
1364   let AddedComplexity = 20 in {
1365     def : Pat<(v4f32 (movddup VR128:$src, (undef))),
1366               (MOVLHPSrr (v4f32 VR128:$src), (v4f32 VR128:$src))>;
1367     def : Pat<(v2i64 (movddup VR128:$src, (undef))),
1368               (MOVLHPSrr (v2i64 VR128:$src), (v2i64 VR128:$src))>;
1369
1370     // vector_shuffle v1, v2 <0, 1, 4, 5> using MOVLHPS
1371     def : Pat<(v4i32 (movlhps VR128:$src1, VR128:$src2)),
1372               (MOVLHPSrr VR128:$src1, VR128:$src2)>;
1373   }
1374   def : Pat<(v4f32 (X86Movlhps VR128:$src1, VR128:$src2)),
1375             (MOVLHPSrr VR128:$src1, VR128:$src2)>;
1376   def : Pat<(v4i32 (X86Movlhps VR128:$src1, VR128:$src2)),
1377             (MOVLHPSrr VR128:$src1, VR128:$src2)>;
1378   def : Pat<(v2i64 (X86Movlhps VR128:$src1, VR128:$src2)),
1379             (MOVLHPSrr (v2i64 VR128:$src1), VR128:$src2)>;
1380
1381   // MOVHLPS patterns
1382   let AddedComplexity = 20 in {
1383     // vector_shuffle v1, v2 <6, 7, 2, 3> using MOVHLPS
1384     def : Pat<(v4i32 (movhlps VR128:$src1, VR128:$src2)),
1385               (MOVHLPSrr VR128:$src1, VR128:$src2)>;
1386
1387     // vector_shuffle v1, undef <2, ?, ?, ?> using MOVHLPS
1388     def : Pat<(v4f32 (movhlps_undef VR128:$src1, (undef))),
1389               (MOVHLPSrr VR128:$src1, VR128:$src1)>;
1390     def : Pat<(v4i32 (movhlps_undef VR128:$src1, (undef))),
1391               (MOVHLPSrr VR128:$src1, VR128:$src1)>;
1392   }
1393
1394   def : Pat<(v4f32 (X86Movhlps VR128:$src1, VR128:$src2)),
1395             (MOVHLPSrr VR128:$src1, VR128:$src2)>;
1396   def : Pat<(v4i32 (X86Movhlps VR128:$src1, VR128:$src2)),
1397             (MOVHLPSrr VR128:$src1, VR128:$src2)>;
1398 }
1399
1400 //===----------------------------------------------------------------------===//
1401 // SSE 1 & 2 - Conversion Instructions
1402 //===----------------------------------------------------------------------===//
1403
1404 multiclass sse12_cvt_s<bits<8> opc, RegisterClass SrcRC, RegisterClass DstRC,
1405                      SDNode OpNode, X86MemOperand x86memop, PatFrag ld_frag,
1406                      string asm> {
1407   def rr : SI<opc, MRMSrcReg, (outs DstRC:$dst), (ins SrcRC:$src), asm,
1408                         [(set DstRC:$dst, (OpNode SrcRC:$src))]>;
1409   def rm : SI<opc, MRMSrcMem, (outs DstRC:$dst), (ins x86memop:$src), asm,
1410                         [(set DstRC:$dst, (OpNode (ld_frag addr:$src)))]>;
1411 }
1412
1413 multiclass sse12_cvt_p<bits<8> opc, RegisterClass SrcRC, RegisterClass DstRC,
1414                          SDNode OpNode, X86MemOperand x86memop, PatFrag ld_frag,
1415                          string asm, Domain d> {
1416   def rr : PI<opc, MRMSrcReg, (outs DstRC:$dst), (ins SrcRC:$src), asm,
1417                         [(set DstRC:$dst, (OpNode SrcRC:$src))],
1418                         IIC_DEFAULT, d>;
1419   def rm : PI<opc, MRMSrcMem, (outs DstRC:$dst), (ins x86memop:$src), asm,
1420                         [(set DstRC:$dst, (OpNode (ld_frag addr:$src)))],
1421                         IIC_DEFAULT, d>;
1422 }
1423
1424 multiclass sse12_vcvt_avx<bits<8> opc, RegisterClass SrcRC, RegisterClass DstRC,
1425                           X86MemOperand x86memop, string asm> {
1426 let neverHasSideEffects = 1 in {
1427   def rr : SI<opc, MRMSrcReg, (outs DstRC:$dst), (ins DstRC:$src1, SrcRC:$src),
1428               !strconcat(asm,"\t{$src, $src1, $dst|$dst, $src1, $src}"), []>;
1429   let mayLoad = 1 in
1430   def rm : SI<opc, MRMSrcMem, (outs DstRC:$dst),
1431               (ins DstRC:$src1, x86memop:$src),
1432               !strconcat(asm,"\t{$src, $src1, $dst|$dst, $src1, $src}"), []>;
1433 } // neverHasSideEffects = 1
1434 }
1435
1436 defm VCVTTSS2SI   : sse12_cvt_s<0x2C, FR32, GR32, fp_to_sint, f32mem, loadf32,
1437                                 "cvttss2si\t{$src, $dst|$dst, $src}">, XS, VEX,
1438                                 VEX_LIG;
1439 defm VCVTTSS2SI64 : sse12_cvt_s<0x2C, FR32, GR64, fp_to_sint, f32mem, loadf32,
1440                                 "cvttss2si\t{$src, $dst|$dst, $src}">, XS, VEX,
1441                                 VEX_W, VEX_LIG;
1442 defm VCVTTSD2SI   : sse12_cvt_s<0x2C, FR64, GR32, fp_to_sint, f64mem, loadf64,
1443                                 "cvttsd2si\t{$src, $dst|$dst, $src}">, XD, VEX,
1444                                 VEX_LIG;
1445 defm VCVTTSD2SI64 : sse12_cvt_s<0x2C, FR64, GR64, fp_to_sint, f64mem, loadf64,
1446                                 "cvttsd2si\t{$src, $dst|$dst, $src}">, XD,
1447                                 VEX, VEX_W, VEX_LIG;
1448
1449 // The assembler can recognize rr 64-bit instructions by seeing a rxx
1450 // register, but the same isn't true when only using memory operands,
1451 // provide other assembly "l" and "q" forms to address this explicitly
1452 // where appropriate to do so.
1453 defm VCVTSI2SS   : sse12_vcvt_avx<0x2A, GR32, FR32, i32mem, "cvtsi2ss">, XS,
1454                                   VEX_4V, VEX_LIG;
1455 defm VCVTSI2SS64 : sse12_vcvt_avx<0x2A, GR64, FR32, i64mem, "cvtsi2ss{q}">, XS,
1456                                   VEX_4V, VEX_W, VEX_LIG;
1457 defm VCVTSI2SD   : sse12_vcvt_avx<0x2A, GR32, FR64, i32mem, "cvtsi2sd">, XD,
1458                                   VEX_4V, VEX_LIG;
1459 defm VCVTSI2SDL  : sse12_vcvt_avx<0x2A, GR32, FR64, i32mem, "cvtsi2sd{l}">, XD,
1460                                   VEX_4V, VEX_LIG;
1461 defm VCVTSI2SD64 : sse12_vcvt_avx<0x2A, GR64, FR64, i64mem, "cvtsi2sd{q}">, XD,
1462                                   VEX_4V, VEX_W, VEX_LIG;
1463
1464 let Predicates = [HasAVX], AddedComplexity = 1 in {
1465   def : Pat<(f32 (sint_to_fp (loadi32 addr:$src))),
1466             (VCVTSI2SSrm (f32 (IMPLICIT_DEF)), addr:$src)>;
1467   def : Pat<(f32 (sint_to_fp (loadi64 addr:$src))),
1468             (VCVTSI2SS64rm (f32 (IMPLICIT_DEF)), addr:$src)>;
1469   def : Pat<(f64 (sint_to_fp (loadi32 addr:$src))),
1470             (VCVTSI2SDrm (f64 (IMPLICIT_DEF)), addr:$src)>;
1471   def : Pat<(f64 (sint_to_fp (loadi64 addr:$src))),
1472             (VCVTSI2SD64rm (f64 (IMPLICIT_DEF)), addr:$src)>;
1473
1474   def : Pat<(f32 (sint_to_fp GR32:$src)),
1475             (VCVTSI2SSrr (f32 (IMPLICIT_DEF)), GR32:$src)>;
1476   def : Pat<(f32 (sint_to_fp GR64:$src)),
1477             (VCVTSI2SS64rr (f32 (IMPLICIT_DEF)), GR64:$src)>;
1478   def : Pat<(f64 (sint_to_fp GR32:$src)),
1479             (VCVTSI2SDrr (f64 (IMPLICIT_DEF)), GR32:$src)>;
1480   def : Pat<(f64 (sint_to_fp GR64:$src)),
1481             (VCVTSI2SD64rr (f64 (IMPLICIT_DEF)), GR64:$src)>;
1482 }
1483
1484 defm CVTTSS2SI : sse12_cvt_s<0x2C, FR32, GR32, fp_to_sint, f32mem, loadf32,
1485                       "cvttss2si\t{$src, $dst|$dst, $src}">, XS;
1486 defm CVTTSS2SI64 : sse12_cvt_s<0x2C, FR32, GR64, fp_to_sint, f32mem, loadf32,
1487                       "cvttss2si{q}\t{$src, $dst|$dst, $src}">, XS, REX_W;
1488 defm CVTTSD2SI : sse12_cvt_s<0x2C, FR64, GR32, fp_to_sint, f64mem, loadf64,
1489                       "cvttsd2si\t{$src, $dst|$dst, $src}">, XD;
1490 defm CVTTSD2SI64 : sse12_cvt_s<0x2C, FR64, GR64, fp_to_sint, f64mem, loadf64,
1491                       "cvttsd2si{q}\t{$src, $dst|$dst, $src}">, XD, REX_W;
1492 defm CVTSI2SS  : sse12_cvt_s<0x2A, GR32, FR32, sint_to_fp, i32mem, loadi32,
1493                       "cvtsi2ss\t{$src, $dst|$dst, $src}">, XS;
1494 defm CVTSI2SS64 : sse12_cvt_s<0x2A, GR64, FR32, sint_to_fp, i64mem, loadi64,
1495                       "cvtsi2ss{q}\t{$src, $dst|$dst, $src}">, XS, REX_W;
1496 defm CVTSI2SD  : sse12_cvt_s<0x2A, GR32, FR64, sint_to_fp, i32mem, loadi32,
1497                       "cvtsi2sd\t{$src, $dst|$dst, $src}">, XD;
1498 defm CVTSI2SD64 : sse12_cvt_s<0x2A, GR64, FR64, sint_to_fp, i64mem, loadi64,
1499                       "cvtsi2sd{q}\t{$src, $dst|$dst, $src}">, XD, REX_W;
1500
1501 // Conversion Instructions Intrinsics - Match intrinsics which expect MM
1502 // and/or XMM operand(s).
1503
1504 multiclass sse12_cvt_sint<bits<8> opc, RegisterClass SrcRC, RegisterClass DstRC,
1505                          Intrinsic Int, X86MemOperand x86memop, PatFrag ld_frag,
1506                          string asm> {
1507   def rr : SI<opc, MRMSrcReg, (outs DstRC:$dst), (ins SrcRC:$src),
1508               !strconcat(asm, "\t{$src, $dst|$dst, $src}"),
1509               [(set DstRC:$dst, (Int SrcRC:$src))]>;
1510   def rm : SI<opc, MRMSrcMem, (outs DstRC:$dst), (ins x86memop:$src),
1511               !strconcat(asm, "\t{$src, $dst|$dst, $src}"),
1512               [(set DstRC:$dst, (Int (ld_frag addr:$src)))]>;
1513 }
1514
1515 multiclass sse12_cvt_sint_3addr<bits<8> opc, RegisterClass SrcRC,
1516                     RegisterClass DstRC, Intrinsic Int, X86MemOperand x86memop,
1517                     PatFrag ld_frag, string asm, bit Is2Addr = 1> {
1518   def rr : SI<opc, MRMSrcReg, (outs DstRC:$dst), (ins DstRC:$src1, SrcRC:$src2),
1519               !if(Is2Addr,
1520                   !strconcat(asm, "\t{$src2, $dst|$dst, $src2}"),
1521                   !strconcat(asm, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
1522               [(set DstRC:$dst, (Int DstRC:$src1, SrcRC:$src2))]>;
1523   def rm : SI<opc, MRMSrcMem, (outs DstRC:$dst),
1524               (ins DstRC:$src1, x86memop:$src2),
1525               !if(Is2Addr,
1526                   !strconcat(asm, "\t{$src2, $dst|$dst, $src2}"),
1527                   !strconcat(asm, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
1528               [(set DstRC:$dst, (Int DstRC:$src1, (ld_frag addr:$src2)))]>;
1529 }
1530
1531 defm VCVTSD2SI : sse12_cvt_sint<0x2D, VR128, GR32, int_x86_sse2_cvtsd2si,
1532                   f128mem, load, "cvtsd2si">, XD, VEX, VEX_LIG;
1533 defm VCVTSD2SI64 : sse12_cvt_sint<0x2D, VR128, GR64,
1534                   int_x86_sse2_cvtsd2si64, f128mem, load, "cvtsd2si">,
1535                   XD, VEX, VEX_W, VEX_LIG;
1536
1537 defm CVTSD2SI : sse12_cvt_sint<0x2D, VR128, GR32, int_x86_sse2_cvtsd2si,
1538                 f128mem, load, "cvtsd2si{l}">, XD;
1539 defm CVTSD2SI64 : sse12_cvt_sint<0x2D, VR128, GR64, int_x86_sse2_cvtsd2si64,
1540                   f128mem, load, "cvtsd2si{q}">, XD, REX_W;
1541
1542
1543 defm Int_VCVTSI2SS : sse12_cvt_sint_3addr<0x2A, GR32, VR128,
1544           int_x86_sse_cvtsi2ss, i32mem, loadi32, "cvtsi2ss", 0>, XS, VEX_4V;
1545 defm Int_VCVTSI2SS64 : sse12_cvt_sint_3addr<0x2A, GR64, VR128,
1546           int_x86_sse_cvtsi642ss, i64mem, loadi64, "cvtsi2ss", 0>, XS, VEX_4V,
1547           VEX_W;
1548 defm Int_VCVTSI2SD : sse12_cvt_sint_3addr<0x2A, GR32, VR128,
1549           int_x86_sse2_cvtsi2sd, i32mem, loadi32, "cvtsi2sd", 0>, XD, VEX_4V;
1550 defm Int_VCVTSI2SD64 : sse12_cvt_sint_3addr<0x2A, GR64, VR128,
1551           int_x86_sse2_cvtsi642sd, i64mem, loadi64, "cvtsi2sd", 0>, XD,
1552           VEX_4V, VEX_W;
1553
1554 let Constraints = "$src1 = $dst" in {
1555   defm Int_CVTSI2SS : sse12_cvt_sint_3addr<0x2A, GR32, VR128,
1556                         int_x86_sse_cvtsi2ss, i32mem, loadi32,
1557                         "cvtsi2ss">, XS;
1558   defm Int_CVTSI2SS64 : sse12_cvt_sint_3addr<0x2A, GR64, VR128,
1559                         int_x86_sse_cvtsi642ss, i64mem, loadi64,
1560                         "cvtsi2ss{q}">, XS, REX_W;
1561   defm Int_CVTSI2SD : sse12_cvt_sint_3addr<0x2A, GR32, VR128,
1562                         int_x86_sse2_cvtsi2sd, i32mem, loadi32,
1563                         "cvtsi2sd">, XD;
1564   defm Int_CVTSI2SD64 : sse12_cvt_sint_3addr<0x2A, GR64, VR128,
1565                         int_x86_sse2_cvtsi642sd, i64mem, loadi64,
1566                         "cvtsi2sd">, XD, REX_W;
1567 }
1568
1569 /// SSE 1 Only
1570
1571 // Aliases for intrinsics
1572 defm Int_VCVTTSS2SI : sse12_cvt_sint<0x2C, VR128, GR32, int_x86_sse_cvttss2si,
1573                                     f32mem, load, "cvttss2si">, XS, VEX;
1574 defm Int_VCVTTSS2SI64 : sse12_cvt_sint<0x2C, VR128, GR64,
1575                                     int_x86_sse_cvttss2si64, f32mem, load,
1576                                     "cvttss2si">, XS, VEX, VEX_W;
1577 defm Int_VCVTTSD2SI : sse12_cvt_sint<0x2C, VR128, GR32, int_x86_sse2_cvttsd2si,
1578                                     f128mem, load, "cvttsd2si">, XD, VEX;
1579 defm Int_VCVTTSD2SI64 : sse12_cvt_sint<0x2C, VR128, GR64,
1580                                     int_x86_sse2_cvttsd2si64, f128mem, load,
1581                                     "cvttsd2si">, XD, VEX, VEX_W;
1582 defm Int_CVTTSS2SI : sse12_cvt_sint<0x2C, VR128, GR32, int_x86_sse_cvttss2si,
1583                                     f32mem, load, "cvttss2si">, XS;
1584 defm Int_CVTTSS2SI64 : sse12_cvt_sint<0x2C, VR128, GR64,
1585                                     int_x86_sse_cvttss2si64, f32mem, load,
1586                                     "cvttss2si{q}">, XS, REX_W;
1587 defm Int_CVTTSD2SI : sse12_cvt_sint<0x2C, VR128, GR32, int_x86_sse2_cvttsd2si,
1588                                     f128mem, load, "cvttsd2si">, XD;
1589 defm Int_CVTTSD2SI64 : sse12_cvt_sint<0x2C, VR128, GR64,
1590                                     int_x86_sse2_cvttsd2si64, f128mem, load,
1591                                     "cvttsd2si{q}">, XD, REX_W;
1592
1593 let Pattern = []<dag> in {
1594 defm VCVTSS2SI   : sse12_cvt_s<0x2D, FR32, GR32, undef, f32mem, load,
1595                                "cvtss2si{l}\t{$src, $dst|$dst, $src}">, XS,
1596                                VEX, VEX_LIG;
1597 defm VCVTSS2SI64 : sse12_cvt_s<0x2D, FR32, GR64, undef, f32mem, load,
1598                                "cvtss2si\t{$src, $dst|$dst, $src}">, XS, VEX,
1599                                VEX_W, VEX_LIG;
1600 defm VCVTDQ2PS   : sse12_cvt_p<0x5B, VR128, VR128, undef, i128mem, load,
1601                                "cvtdq2ps\t{$src, $dst|$dst, $src}",
1602                                SSEPackedSingle>, TB, VEX;
1603 defm VCVTDQ2PSY  : sse12_cvt_p<0x5B, VR256, VR256, undef, i256mem, load,
1604                                "cvtdq2ps\t{$src, $dst|$dst, $src}",
1605                                SSEPackedSingle>, TB, VEX;
1606 }
1607
1608 let Pattern = []<dag> in {
1609 defm CVTSS2SI : sse12_cvt_s<0x2D, FR32, GR32, undef, f32mem, load /*dummy*/,
1610                           "cvtss2si{l}\t{$src, $dst|$dst, $src}">, XS;
1611 defm CVTSS2SI64 : sse12_cvt_s<0x2D, FR32, GR64, undef, f32mem, load /*dummy*/,
1612                           "cvtss2si{q}\t{$src, $dst|$dst, $src}">, XS, REX_W;
1613 defm CVTDQ2PS : sse12_cvt_p<0x5B, VR128, VR128, undef, i128mem, load /*dummy*/,
1614                             "cvtdq2ps\t{$src, $dst|$dst, $src}",
1615                             SSEPackedSingle>, TB; /* PD SSE3 form is avaiable */
1616 }
1617
1618 let Predicates = [HasAVX] in {
1619   def : Pat<(int_x86_sse_cvtss2si VR128:$src),
1620             (VCVTSS2SIrr (EXTRACT_SUBREG (v4f32 VR128:$src), sub_ss))>;
1621   def : Pat<(int_x86_sse_cvtss2si (load addr:$src)),
1622             (VCVTSS2SIrm addr:$src)>;
1623   def : Pat<(int_x86_sse_cvtss2si64 VR128:$src),
1624             (VCVTSS2SI64rr (EXTRACT_SUBREG (v4f32 VR128:$src), sub_ss))>;
1625   def : Pat<(int_x86_sse_cvtss2si64 (load addr:$src)),
1626             (VCVTSS2SI64rm addr:$src)>;
1627 }
1628
1629 let Predicates = [HasSSE1] in {
1630   def : Pat<(int_x86_sse_cvtss2si VR128:$src),
1631             (CVTSS2SIrr (EXTRACT_SUBREG (v4f32 VR128:$src), sub_ss))>;
1632   def : Pat<(int_x86_sse_cvtss2si (load addr:$src)),
1633             (CVTSS2SIrm addr:$src)>;
1634   def : Pat<(int_x86_sse_cvtss2si64 VR128:$src),
1635             (CVTSS2SI64rr (EXTRACT_SUBREG (v4f32 VR128:$src), sub_ss))>;
1636   def : Pat<(int_x86_sse_cvtss2si64 (load addr:$src)),
1637             (CVTSS2SI64rm addr:$src)>;
1638 }
1639
1640 /// SSE 2 Only
1641
1642 // Convert scalar double to scalar single
1643 def VCVTSD2SSrr  : VSDI<0x5A, MRMSrcReg, (outs FR32:$dst),
1644                        (ins FR64:$src1, FR64:$src2),
1645                       "cvtsd2ss\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>,
1646                       VEX_4V, VEX_LIG;
1647 let mayLoad = 1 in
1648 def VCVTSD2SSrm  : I<0x5A, MRMSrcMem, (outs FR32:$dst),
1649                        (ins FR64:$src1, f64mem:$src2),
1650                       "vcvtsd2ss\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1651                       []>, XD, Requires<[HasAVX, OptForSize]>, VEX_4V, VEX_LIG;
1652
1653 def : Pat<(f32 (fround FR64:$src)), (VCVTSD2SSrr FR64:$src, FR64:$src)>,
1654           Requires<[HasAVX]>;
1655
1656 def CVTSD2SSrr  : SDI<0x5A, MRMSrcReg, (outs FR32:$dst), (ins FR64:$src),
1657                       "cvtsd2ss\t{$src, $dst|$dst, $src}",
1658                       [(set FR32:$dst, (fround FR64:$src))]>;
1659 def CVTSD2SSrm  : I<0x5A, MRMSrcMem, (outs FR32:$dst), (ins f64mem:$src),
1660                       "cvtsd2ss\t{$src, $dst|$dst, $src}",
1661                       [(set FR32:$dst, (fround (loadf64 addr:$src)))]>, XD,
1662                   Requires<[HasSSE2, OptForSize]>;
1663
1664 defm Int_VCVTSD2SS: sse12_cvt_sint_3addr<0x5A, VR128, VR128,
1665                       int_x86_sse2_cvtsd2ss, f64mem, load, "cvtsd2ss", 0>,
1666                       XS, VEX_4V;
1667 let Constraints = "$src1 = $dst" in
1668 defm Int_CVTSD2SS: sse12_cvt_sint_3addr<0x5A, VR128, VR128,
1669                       int_x86_sse2_cvtsd2ss, f64mem, load, "cvtsd2ss">, XS;
1670
1671 // Convert scalar single to scalar double
1672 // SSE2 instructions with XS prefix
1673 def VCVTSS2SDrr : I<0x5A, MRMSrcReg, (outs FR64:$dst),
1674                     (ins FR32:$src1, FR32:$src2),
1675                     "vcvtss2sd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1676                     []>, XS, Requires<[HasAVX]>, VEX_4V, VEX_LIG;
1677 let mayLoad = 1 in
1678 def VCVTSS2SDrm : I<0x5A, MRMSrcMem, (outs FR64:$dst),
1679                     (ins FR32:$src1, f32mem:$src2),
1680                     "vcvtss2sd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1681                     []>, XS, VEX_4V, VEX_LIG, Requires<[HasAVX, OptForSize]>;
1682
1683 let Predicates = [HasAVX] in {
1684   def : Pat<(f64 (fextend FR32:$src)),
1685             (VCVTSS2SDrr FR32:$src, FR32:$src)>;
1686   def : Pat<(fextend (loadf32 addr:$src)),
1687             (VCVTSS2SDrm (f32 (IMPLICIT_DEF)), addr:$src)>;
1688   def : Pat<(extloadf32 addr:$src),
1689             (VCVTSS2SDrm (f32 (IMPLICIT_DEF)), addr:$src)>;
1690 }
1691
1692 def : Pat<(extloadf32 addr:$src),
1693           (VCVTSS2SDrr (f32 (IMPLICIT_DEF)), (MOVSSrm addr:$src))>,
1694           Requires<[HasAVX, OptForSpeed]>;
1695
1696 def CVTSS2SDrr : I<0x5A, MRMSrcReg, (outs FR64:$dst), (ins FR32:$src),
1697                    "cvtss2sd\t{$src, $dst|$dst, $src}",
1698                    [(set FR64:$dst, (fextend FR32:$src))]>, XS,
1699                  Requires<[HasSSE2]>;
1700 def CVTSS2SDrm : I<0x5A, MRMSrcMem, (outs FR64:$dst), (ins f32mem:$src),
1701                    "cvtss2sd\t{$src, $dst|$dst, $src}",
1702                    [(set FR64:$dst, (extloadf32 addr:$src))]>, XS,
1703                  Requires<[HasSSE2, OptForSize]>;
1704
1705 // extload f32 -> f64.  This matches load+fextend because we have a hack in
1706 // the isel (PreprocessForFPConvert) that can introduce loads after dag
1707 // combine.
1708 // Since these loads aren't folded into the fextend, we have to match it
1709 // explicitly here.
1710 def : Pat<(fextend (loadf32 addr:$src)),
1711           (CVTSS2SDrm addr:$src)>, Requires<[HasSSE2]>;
1712 def : Pat<(extloadf32 addr:$src),
1713           (CVTSS2SDrr (MOVSSrm addr:$src))>, Requires<[HasSSE2, OptForSpeed]>;
1714
1715 def Int_VCVTSS2SDrr: I<0x5A, MRMSrcReg,
1716                       (outs VR128:$dst), (ins VR128:$src1, VR128:$src2),
1717                     "vcvtss2sd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1718                     [(set VR128:$dst, (int_x86_sse2_cvtss2sd VR128:$src1,
1719                                        VR128:$src2))]>, XS, VEX_4V,
1720                     Requires<[HasAVX]>;
1721 def Int_VCVTSS2SDrm: I<0x5A, MRMSrcMem,
1722                       (outs VR128:$dst), (ins VR128:$src1, f32mem:$src2),
1723                     "vcvtss2sd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1724                     [(set VR128:$dst, (int_x86_sse2_cvtss2sd VR128:$src1,
1725                                        (load addr:$src2)))]>, XS, VEX_4V,
1726                     Requires<[HasAVX]>;
1727 let Constraints = "$src1 = $dst" in { // SSE2 instructions with XS prefix
1728 def Int_CVTSS2SDrr: I<0x5A, MRMSrcReg,
1729                       (outs VR128:$dst), (ins VR128:$src1, VR128:$src2),
1730                     "cvtss2sd\t{$src2, $dst|$dst, $src2}",
1731                     [(set VR128:$dst, (int_x86_sse2_cvtss2sd VR128:$src1,
1732                                        VR128:$src2))]>, XS,
1733                     Requires<[HasSSE2]>;
1734 def Int_CVTSS2SDrm: I<0x5A, MRMSrcMem,
1735                       (outs VR128:$dst), (ins VR128:$src1, f32mem:$src2),
1736                     "cvtss2sd\t{$src2, $dst|$dst, $src2}",
1737                     [(set VR128:$dst, (int_x86_sse2_cvtss2sd VR128:$src1,
1738                                        (load addr:$src2)))]>, XS,
1739                     Requires<[HasSSE2]>;
1740 }
1741
1742 // Convert doubleword to packed single/double fp
1743 // SSE2 instructions without OpSize prefix
1744 def Int_VCVTDQ2PSrr : I<0x5B, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1745                        "vcvtdq2ps\t{$src, $dst|$dst, $src}",
1746                        [(set VR128:$dst, (int_x86_sse2_cvtdq2ps VR128:$src))]>,
1747                      TB, VEX, Requires<[HasAVX]>;
1748 def Int_VCVTDQ2PSrm : I<0x5B, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
1749                       "vcvtdq2ps\t{$src, $dst|$dst, $src}",
1750                       [(set VR128:$dst, (int_x86_sse2_cvtdq2ps
1751                                         (bitconvert (memopv2i64 addr:$src))))]>,
1752                      TB, VEX, Requires<[HasAVX]>;
1753 def Int_CVTDQ2PSrr : I<0x5B, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1754                        "cvtdq2ps\t{$src, $dst|$dst, $src}",
1755                        [(set VR128:$dst, (int_x86_sse2_cvtdq2ps VR128:$src))]>,
1756                      TB, Requires<[HasSSE2]>;
1757 def Int_CVTDQ2PSrm : I<0x5B, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
1758                       "cvtdq2ps\t{$src, $dst|$dst, $src}",
1759                       [(set VR128:$dst, (int_x86_sse2_cvtdq2ps
1760                                         (bitconvert (memopv2i64 addr:$src))))]>,
1761                      TB, Requires<[HasSSE2]>;
1762
1763 // FIXME: why the non-intrinsic version is described as SSE3?
1764 // SSE2 instructions with XS prefix
1765 def Int_VCVTDQ2PDrr : I<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1766                        "vcvtdq2pd\t{$src, $dst|$dst, $src}",
1767                        [(set VR128:$dst, (int_x86_sse2_cvtdq2pd VR128:$src))]>,
1768                      XS, VEX, Requires<[HasAVX]>;
1769 def Int_VCVTDQ2PDrm : I<0xE6, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
1770                        "vcvtdq2pd\t{$src, $dst|$dst, $src}",
1771                        [(set VR128:$dst, (int_x86_sse2_cvtdq2pd
1772                                         (bitconvert (memopv2i64 addr:$src))))]>,
1773                      XS, VEX, Requires<[HasAVX]>;
1774 def Int_CVTDQ2PDrr : I<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1775                        "cvtdq2pd\t{$src, $dst|$dst, $src}",
1776                        [(set VR128:$dst, (int_x86_sse2_cvtdq2pd VR128:$src))]>,
1777                      XS, Requires<[HasSSE2]>;
1778 def Int_CVTDQ2PDrm : I<0xE6, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
1779                      "cvtdq2pd\t{$src, $dst|$dst, $src}",
1780                      [(set VR128:$dst, (int_x86_sse2_cvtdq2pd
1781                                         (bitconvert (memopv2i64 addr:$src))))]>,
1782                      XS, Requires<[HasSSE2]>;
1783
1784
1785 // Convert packed single/double fp to doubleword
1786 def VCVTPS2DQrr : VPDI<0x5B, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1787                        "cvtps2dq\t{$src, $dst|$dst, $src}", []>, VEX;
1788 def VCVTPS2DQrm : VPDI<0x5B, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1789                        "cvtps2dq\t{$src, $dst|$dst, $src}", []>, VEX;
1790 def VCVTPS2DQYrr : VPDI<0x5B, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
1791                         "cvtps2dq\t{$src, $dst|$dst, $src}", []>, VEX;
1792 def VCVTPS2DQYrm : VPDI<0x5B, MRMSrcMem, (outs VR256:$dst), (ins f256mem:$src),
1793                         "cvtps2dq\t{$src, $dst|$dst, $src}", []>, VEX;
1794 def CVTPS2DQrr : PDI<0x5B, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1795                      "cvtps2dq\t{$src, $dst|$dst, $src}", []>;
1796 def CVTPS2DQrm : PDI<0x5B, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1797                      "cvtps2dq\t{$src, $dst|$dst, $src}", []>;
1798
1799 def Int_VCVTPS2DQrr : VPDI<0x5B, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1800                         "cvtps2dq\t{$src, $dst|$dst, $src}",
1801                         [(set VR128:$dst, (int_x86_sse2_cvtps2dq VR128:$src))]>,
1802                         VEX;
1803 def Int_VCVTPS2DQrm : VPDI<0x5B, MRMSrcMem, (outs VR128:$dst),
1804                          (ins f128mem:$src),
1805                          "cvtps2dq\t{$src, $dst|$dst, $src}",
1806                          [(set VR128:$dst, (int_x86_sse2_cvtps2dq
1807                                             (memop addr:$src)))]>, VEX;
1808 def Int_CVTPS2DQrr : PDI<0x5B, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1809                         "cvtps2dq\t{$src, $dst|$dst, $src}",
1810                         [(set VR128:$dst, (int_x86_sse2_cvtps2dq VR128:$src))]>;
1811 def Int_CVTPS2DQrm : PDI<0x5B, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1812                          "cvtps2dq\t{$src, $dst|$dst, $src}",
1813                          [(set VR128:$dst, (int_x86_sse2_cvtps2dq
1814                                             (memop addr:$src)))]>;
1815
1816 // SSE2 packed instructions with XD prefix
1817 def Int_VCVTPD2DQrr : I<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1818                        "vcvtpd2dq\t{$src, $dst|$dst, $src}",
1819                        [(set VR128:$dst, (int_x86_sse2_cvtpd2dq VR128:$src))]>,
1820                      XD, VEX, Requires<[HasAVX]>;
1821 def Int_VCVTPD2DQrm : I<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1822                        "vcvtpd2dq\t{$src, $dst|$dst, $src}",
1823                        [(set VR128:$dst, (int_x86_sse2_cvtpd2dq
1824                                           (memop addr:$src)))]>,
1825                      XD, VEX, Requires<[HasAVX]>;
1826 def Int_CVTPD2DQrr : I<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1827                        "cvtpd2dq\t{$src, $dst|$dst, $src}",
1828                        [(set VR128:$dst, (int_x86_sse2_cvtpd2dq VR128:$src))]>,
1829                      XD, Requires<[HasSSE2]>;
1830 def Int_CVTPD2DQrm : I<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1831                        "cvtpd2dq\t{$src, $dst|$dst, $src}",
1832                        [(set VR128:$dst, (int_x86_sse2_cvtpd2dq
1833                                           (memop addr:$src)))]>,
1834                      XD, Requires<[HasSSE2]>;
1835
1836
1837 // Convert with truncation packed single/double fp to doubleword
1838 // SSE2 packed instructions with XS prefix
1839 def VCVTTPS2DQrr : VSSI<0x5B, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1840                         "cvttps2dq\t{$src, $dst|$dst, $src}",
1841                         [(set VR128:$dst,
1842                           (int_x86_sse2_cvttps2dq VR128:$src))]>, VEX;
1843 def VCVTTPS2DQrm : VSSI<0x5B, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1844                         "cvttps2dq\t{$src, $dst|$dst, $src}",
1845                         [(set VR128:$dst, (int_x86_sse2_cvttps2dq
1846                                            (memop addr:$src)))]>, VEX;
1847 def VCVTTPS2DQYrr : VSSI<0x5B, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
1848                          "cvttps2dq\t{$src, $dst|$dst, $src}",
1849                          [(set VR256:$dst,
1850                            (int_x86_avx_cvtt_ps2dq_256 VR256:$src))]>, VEX;
1851 def VCVTTPS2DQYrm : VSSI<0x5B, MRMSrcMem, (outs VR256:$dst), (ins f256mem:$src),
1852                          "cvttps2dq\t{$src, $dst|$dst, $src}",
1853                          [(set VR256:$dst, (int_x86_avx_cvtt_ps2dq_256
1854                                             (memopv8f32 addr:$src)))]>, VEX;
1855
1856 def CVTTPS2DQrr : SSI<0x5B, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1857                       "cvttps2dq\t{$src, $dst|$dst, $src}",
1858                       [(set VR128:$dst,
1859                             (int_x86_sse2_cvttps2dq VR128:$src))]>;
1860 def CVTTPS2DQrm : SSI<0x5B, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1861                       "cvttps2dq\t{$src, $dst|$dst, $src}",
1862                       [(set VR128:$dst,
1863                             (int_x86_sse2_cvttps2dq (memop addr:$src)))]>;
1864
1865 let Predicates = [HasAVX] in {
1866   def : Pat<(v4f32 (sint_to_fp (v4i32 VR128:$src))),
1867             (Int_VCVTDQ2PSrr VR128:$src)>;
1868   def : Pat<(v4f32 (sint_to_fp (bc_v4i32 (memopv2i64 addr:$src)))),
1869             (Int_VCVTDQ2PSrm addr:$src)>;
1870
1871   def : Pat<(v4i32 (fp_to_sint (v4f32 VR128:$src))),
1872             (VCVTTPS2DQrr VR128:$src)>;
1873   def : Pat<(v4i32 (fp_to_sint (memopv4f32 addr:$src))),
1874             (VCVTTPS2DQrm addr:$src)>;
1875
1876   def : Pat<(v8f32 (sint_to_fp (v8i32 VR256:$src))),
1877             (VCVTDQ2PSYrr VR256:$src)>;
1878   def : Pat<(v8f32 (sint_to_fp (bc_v8i32 (memopv4i64 addr:$src)))),
1879             (VCVTDQ2PSYrm addr:$src)>;
1880
1881   def : Pat<(v8i32 (fp_to_sint (v8f32 VR256:$src))),
1882             (VCVTTPS2DQYrr VR256:$src)>;
1883   def : Pat<(v8i32 (fp_to_sint (memopv8f32 addr:$src))),
1884             (VCVTTPS2DQYrm addr:$src)>;
1885 }
1886
1887 let Predicates = [HasSSE2] in {
1888   def : Pat<(v4f32 (sint_to_fp (v4i32 VR128:$src))),
1889             (Int_CVTDQ2PSrr VR128:$src)>;
1890   def : Pat<(v4f32 (sint_to_fp (bc_v4i32 (memopv2i64 addr:$src)))),
1891             (Int_CVTDQ2PSrm addr:$src)>;
1892
1893   def : Pat<(v4i32 (fp_to_sint (v4f32 VR128:$src))),
1894             (CVTTPS2DQrr VR128:$src)>;
1895   def : Pat<(v4i32 (fp_to_sint (memopv4f32 addr:$src))),
1896             (CVTTPS2DQrm addr:$src)>;
1897 }
1898
1899 def VCVTTPD2DQrr : VPDI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1900                         "cvttpd2dq\t{$src, $dst|$dst, $src}",
1901                         [(set VR128:$dst,
1902                               (int_x86_sse2_cvttpd2dq VR128:$src))]>, VEX;
1903 let isCodeGenOnly = 1 in
1904 def VCVTTPD2DQrm : VPDI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1905                         "cvttpd2dq\t{$src, $dst|$dst, $src}",
1906                         [(set VR128:$dst, (int_x86_sse2_cvttpd2dq
1907                                                (memop addr:$src)))]>, VEX;
1908 def CVTTPD2DQrr : PDI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1909                       "cvttpd2dq\t{$src, $dst|$dst, $src}",
1910                       [(set VR128:$dst, (int_x86_sse2_cvttpd2dq VR128:$src))]>;
1911 def CVTTPD2DQrm : PDI<0xE6, MRMSrcMem, (outs VR128:$dst),(ins f128mem:$src),
1912                       "cvttpd2dq\t{$src, $dst|$dst, $src}",
1913                       [(set VR128:$dst, (int_x86_sse2_cvttpd2dq
1914                                         (memop addr:$src)))]>;
1915
1916 // The assembler can recognize rr 256-bit instructions by seeing a ymm
1917 // register, but the same isn't true when using memory operands instead.
1918 // Provide other assembly rr and rm forms to address this explicitly.
1919 def VCVTTPD2DQXrYr : VPDI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR256:$src),
1920                           "cvttpd2dq\t{$src, $dst|$dst, $src}", []>, VEX;
1921
1922 // XMM only
1923 def VCVTTPD2DQXrr : VPDI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1924                          "cvttpd2dqx\t{$src, $dst|$dst, $src}", []>, VEX;
1925 def VCVTTPD2DQXrm : VPDI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1926                          "cvttpd2dqx\t{$src, $dst|$dst, $src}", []>, VEX;
1927
1928 // YMM only
1929 def VCVTTPD2DQYrr : VPDI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR256:$src),
1930                          "cvttpd2dqy\t{$src, $dst|$dst, $src}", []>, VEX;
1931 def VCVTTPD2DQYrm : VPDI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f256mem:$src),
1932                          "cvttpd2dqy\t{$src, $dst|$dst, $src}", []>, VEX, VEX_L;
1933
1934 // Convert packed single to packed double
1935 let Predicates = [HasAVX] in {
1936                   // SSE2 instructions without OpSize prefix
1937 def VCVTPS2PDrr : I<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1938                      "vcvtps2pd\t{$src, $dst|$dst, $src}", []>, TB, VEX;
1939 def VCVTPS2PDrm : I<0x5A, MRMSrcMem, (outs VR128:$dst), (ins f64mem:$src),
1940                      "vcvtps2pd\t{$src, $dst|$dst, $src}", []>, TB, VEX;
1941 def VCVTPS2PDYrr : I<0x5A, MRMSrcReg, (outs VR256:$dst), (ins VR128:$src),
1942                      "vcvtps2pd\t{$src, $dst|$dst, $src}", []>, TB, VEX;
1943 def VCVTPS2PDYrm : I<0x5A, MRMSrcMem, (outs VR256:$dst), (ins f128mem:$src),
1944                      "vcvtps2pd\t{$src, $dst|$dst, $src}", []>, TB, VEX;
1945 }
1946 def CVTPS2PDrr : I<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1947                        "cvtps2pd\t{$src, $dst|$dst, $src}", []>, TB;
1948 def CVTPS2PDrm : I<0x5A, MRMSrcMem, (outs VR128:$dst), (ins f64mem:$src),
1949                        "cvtps2pd\t{$src, $dst|$dst, $src}", []>, TB;
1950
1951 def Int_VCVTPS2PDrr : I<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1952                        "vcvtps2pd\t{$src, $dst|$dst, $src}",
1953                        [(set VR128:$dst, (int_x86_sse2_cvtps2pd VR128:$src))]>,
1954                      TB, VEX, Requires<[HasAVX]>;
1955 def Int_VCVTPS2PDrm : I<0x5A, MRMSrcMem, (outs VR128:$dst), (ins f64mem:$src),
1956                        "vcvtps2pd\t{$src, $dst|$dst, $src}",
1957                        [(set VR128:$dst, (int_x86_sse2_cvtps2pd
1958                                           (load addr:$src)))]>,
1959                      TB, VEX, Requires<[HasAVX]>;
1960 def Int_CVTPS2PDrr : I<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1961                        "cvtps2pd\t{$src, $dst|$dst, $src}",
1962                        [(set VR128:$dst, (int_x86_sse2_cvtps2pd VR128:$src))]>,
1963                      TB, Requires<[HasSSE2]>;
1964 def Int_CVTPS2PDrm : I<0x5A, MRMSrcMem, (outs VR128:$dst), (ins f64mem:$src),
1965                        "cvtps2pd\t{$src, $dst|$dst, $src}",
1966                        [(set VR128:$dst, (int_x86_sse2_cvtps2pd
1967                                           (load addr:$src)))]>,
1968                      TB, Requires<[HasSSE2]>;
1969
1970 // Convert packed double to packed single
1971 // The assembler can recognize rr 256-bit instructions by seeing a ymm
1972 // register, but the same isn't true when using memory operands instead.
1973 // Provide other assembly rr and rm forms to address this explicitly.
1974 def VCVTPD2PSrr : VPDI<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1975                        "cvtpd2ps\t{$src, $dst|$dst, $src}", []>, VEX;
1976 def VCVTPD2PSXrYr : VPDI<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR256:$src),
1977                          "cvtpd2ps\t{$src, $dst|$dst, $src}", []>, VEX;
1978
1979 // XMM only
1980 def VCVTPD2PSXrr : VPDI<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1981                         "cvtpd2psx\t{$src, $dst|$dst, $src}", []>, VEX;
1982 def VCVTPD2PSXrm : VPDI<0x5A, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1983                         "cvtpd2psx\t{$src, $dst|$dst, $src}", []>, VEX;
1984
1985 // YMM only
1986 def VCVTPD2PSYrr : VPDI<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR256:$src),
1987                         "cvtpd2psy\t{$src, $dst|$dst, $src}", []>, VEX;
1988 def VCVTPD2PSYrm : VPDI<0x5A, MRMSrcMem, (outs VR128:$dst), (ins f256mem:$src),
1989                         "cvtpd2psy\t{$src, $dst|$dst, $src}", []>, VEX, VEX_L;
1990 def CVTPD2PSrr : PDI<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1991                      "cvtpd2ps\t{$src, $dst|$dst, $src}", []>;
1992 def CVTPD2PSrm : PDI<0x5A, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1993                      "cvtpd2ps\t{$src, $dst|$dst, $src}", []>;
1994
1995
1996 def Int_VCVTPD2PSrr : VPDI<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1997                          "cvtpd2ps\t{$src, $dst|$dst, $src}",
1998                         [(set VR128:$dst, (int_x86_sse2_cvtpd2ps VR128:$src))]>;
1999 def Int_VCVTPD2PSrm : VPDI<0x5A, MRMSrcMem, (outs VR128:$dst),
2000                          (ins f128mem:$src),
2001                          "cvtpd2ps\t{$src, $dst|$dst, $src}",
2002                          [(set VR128:$dst, (int_x86_sse2_cvtpd2ps
2003                                             (memop addr:$src)))]>;
2004 def Int_CVTPD2PSrr : PDI<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2005                          "cvtpd2ps\t{$src, $dst|$dst, $src}",
2006                         [(set VR128:$dst, (int_x86_sse2_cvtpd2ps VR128:$src))]>;
2007 def Int_CVTPD2PSrm : PDI<0x5A, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
2008                          "cvtpd2ps\t{$src, $dst|$dst, $src}",
2009                          [(set VR128:$dst, (int_x86_sse2_cvtpd2ps
2010                                             (memop addr:$src)))]>;
2011
2012 // AVX 256-bit register conversion intrinsics
2013 // FIXME: Migrate SSE conversion intrinsics matching to use patterns as below
2014 // whenever possible to avoid declaring two versions of each one.
2015 def : Pat<(int_x86_avx_cvtdq2_ps_256 VR256:$src),
2016           (VCVTDQ2PSYrr VR256:$src)>;
2017 def : Pat<(int_x86_avx_cvtdq2_ps_256 (bitconvert (memopv4i64 addr:$src))),
2018           (VCVTDQ2PSYrm addr:$src)>;
2019
2020 def : Pat<(int_x86_avx_cvt_pd2_ps_256 VR256:$src),
2021           (VCVTPD2PSYrr VR256:$src)>;
2022 def : Pat<(int_x86_avx_cvt_pd2_ps_256 (memopv4f64 addr:$src)),
2023           (VCVTPD2PSYrm addr:$src)>;
2024
2025 def : Pat<(int_x86_avx_cvt_ps2dq_256 VR256:$src),
2026           (VCVTPS2DQYrr VR256:$src)>;
2027 def : Pat<(int_x86_avx_cvt_ps2dq_256 (memopv8f32 addr:$src)),
2028           (VCVTPS2DQYrm addr:$src)>;
2029
2030 def : Pat<(int_x86_avx_cvt_ps2_pd_256 VR128:$src),
2031           (VCVTPS2PDYrr VR128:$src)>;
2032 def : Pat<(int_x86_avx_cvt_ps2_pd_256 (memopv4f32 addr:$src)),
2033           (VCVTPS2PDYrm addr:$src)>;
2034
2035 def : Pat<(int_x86_avx_cvtt_pd2dq_256 VR256:$src),
2036           (VCVTTPD2DQYrr VR256:$src)>;
2037 def : Pat<(int_x86_avx_cvtt_pd2dq_256 (memopv4f64 addr:$src)),
2038           (VCVTTPD2DQYrm addr:$src)>;
2039
2040 // Match fround and fextend for 128/256-bit conversions
2041 def : Pat<(v4f32 (fround (v4f64 VR256:$src))),
2042           (VCVTPD2PSYrr VR256:$src)>;
2043 def : Pat<(v4f32 (fround (loadv4f64 addr:$src))),
2044           (VCVTPD2PSYrm addr:$src)>;
2045
2046 def : Pat<(v4f64 (fextend (v4f32 VR128:$src))),
2047           (VCVTPS2PDYrr VR128:$src)>;
2048 def : Pat<(v4f64 (fextend (loadv4f32 addr:$src))),
2049           (VCVTPS2PDYrm addr:$src)>;
2050
2051 //===----------------------------------------------------------------------===//
2052 // SSE 1 & 2 - Compare Instructions
2053 //===----------------------------------------------------------------------===//
2054
2055 // sse12_cmp_scalar - sse 1 & 2 compare scalar instructions
2056 multiclass sse12_cmp_scalar<RegisterClass RC, X86MemOperand x86memop,
2057                             SDNode OpNode, ValueType VT, PatFrag ld_frag,
2058                             string asm, string asm_alt> {
2059   def rr : SIi8<0xC2, MRMSrcReg,
2060                 (outs RC:$dst), (ins RC:$src1, RC:$src2, SSECC:$cc), asm,
2061                 [(set RC:$dst, (OpNode (VT RC:$src1), RC:$src2, imm:$cc))]>;
2062   def rm : SIi8<0xC2, MRMSrcMem,
2063                 (outs RC:$dst), (ins RC:$src1, x86memop:$src2, SSECC:$cc), asm,
2064                 [(set RC:$dst, (OpNode (VT RC:$src1),
2065                                          (ld_frag addr:$src2), imm:$cc))]>;
2066
2067   // Accept explicit immediate argument form instead of comparison code.
2068   let neverHasSideEffects = 1 in {
2069     def rr_alt : SIi8<0xC2, MRMSrcReg, (outs RC:$dst),
2070                       (ins RC:$src1, RC:$src2, i8imm:$cc), asm_alt, []>;
2071     let mayLoad = 1 in
2072     def rm_alt : SIi8<0xC2, MRMSrcMem, (outs RC:$dst),
2073                       (ins RC:$src1, x86memop:$src2, i8imm:$cc), asm_alt, []>;
2074   }
2075 }
2076
2077 defm VCMPSS : sse12_cmp_scalar<FR32, f32mem, X86cmpss, f32, loadf32,
2078                  "cmp${cc}ss\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2079                  "cmpss\t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}">,
2080                  XS, VEX_4V, VEX_LIG;
2081 defm VCMPSD : sse12_cmp_scalar<FR64, f64mem, X86cmpsd, f64, loadf64,
2082                  "cmp${cc}sd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2083                  "cmpsd\t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}">,
2084                  XD, VEX_4V, VEX_LIG;
2085
2086 let Constraints = "$src1 = $dst" in {
2087   defm CMPSS : sse12_cmp_scalar<FR32, f32mem, X86cmpss, f32, loadf32,
2088                   "cmp${cc}ss\t{$src2, $dst|$dst, $src2}",
2089                   "cmpss\t{$cc, $src2, $dst|$dst, $src2, $cc}">,
2090                   XS;
2091   defm CMPSD : sse12_cmp_scalar<FR64, f64mem, X86cmpsd, f64, loadf64,
2092                   "cmp${cc}sd\t{$src2, $dst|$dst, $src2}",
2093                   "cmpsd\t{$cc, $src2, $dst|$dst, $src2, $cc}">,
2094                   XD;
2095 }
2096
2097 multiclass sse12_cmp_scalar_int<RegisterClass RC, X86MemOperand x86memop,
2098                          Intrinsic Int, string asm> {
2099   def rr : SIi8<0xC2, MRMSrcReg, (outs VR128:$dst),
2100                       (ins VR128:$src1, VR128:$src, SSECC:$cc), asm,
2101                         [(set VR128:$dst, (Int VR128:$src1,
2102                                                VR128:$src, imm:$cc))]>;
2103   def rm : SIi8<0xC2, MRMSrcMem, (outs VR128:$dst),
2104                       (ins VR128:$src1, x86memop:$src, SSECC:$cc), asm,
2105                         [(set VR128:$dst, (Int VR128:$src1,
2106                                                (load addr:$src), imm:$cc))]>;
2107 }
2108
2109 // Aliases to match intrinsics which expect XMM operand(s).
2110 defm Int_VCMPSS  : sse12_cmp_scalar_int<VR128, f32mem, int_x86_sse_cmp_ss,
2111                      "cmp${cc}ss\t{$src, $src1, $dst|$dst, $src1, $src}">,
2112                      XS, VEX_4V;
2113 defm Int_VCMPSD  : sse12_cmp_scalar_int<VR128, f64mem, int_x86_sse2_cmp_sd,
2114                      "cmp${cc}sd\t{$src, $src1, $dst|$dst, $src1, $src}">,
2115                      XD, VEX_4V;
2116 let Constraints = "$src1 = $dst" in {
2117   defm Int_CMPSS  : sse12_cmp_scalar_int<VR128, f32mem, int_x86_sse_cmp_ss,
2118                        "cmp${cc}ss\t{$src, $dst|$dst, $src}">, XS;
2119   defm Int_CMPSD  : sse12_cmp_scalar_int<VR128, f64mem, int_x86_sse2_cmp_sd,
2120                        "cmp${cc}sd\t{$src, $dst|$dst, $src}">, XD;
2121 }
2122
2123
2124 // sse12_ord_cmp - Unordered/Ordered scalar fp compare and set EFLAGS
2125 multiclass sse12_ord_cmp<bits<8> opc, RegisterClass RC, SDNode OpNode,
2126                             ValueType vt, X86MemOperand x86memop,
2127                             PatFrag ld_frag, string OpcodeStr, Domain d> {
2128   def rr: PI<opc, MRMSrcReg, (outs), (ins RC:$src1, RC:$src2),
2129                      !strconcat(OpcodeStr, "\t{$src2, $src1|$src1, $src2}"),
2130                      [(set EFLAGS, (OpNode (vt RC:$src1), RC:$src2))],
2131                      IIC_DEFAULT, d>;
2132   def rm: PI<opc, MRMSrcMem, (outs), (ins RC:$src1, x86memop:$src2),
2133                      !strconcat(OpcodeStr, "\t{$src2, $src1|$src1, $src2}"),
2134                      [(set EFLAGS, (OpNode (vt RC:$src1),
2135                                            (ld_frag addr:$src2)))],
2136                                            IIC_DEFAULT, d>;
2137 }
2138
2139 let Defs = [EFLAGS] in {
2140   defm VUCOMISS : sse12_ord_cmp<0x2E, FR32, X86cmp, f32, f32mem, loadf32,
2141                                   "ucomiss", SSEPackedSingle>, TB, VEX, VEX_LIG;
2142   defm VUCOMISD : sse12_ord_cmp<0x2E, FR64, X86cmp, f64, f64mem, loadf64,
2143                                   "ucomisd", SSEPackedDouble>, TB, OpSize, VEX,
2144                                   VEX_LIG;
2145   let Pattern = []<dag> in {
2146     defm VCOMISS  : sse12_ord_cmp<0x2F, VR128, undef, v4f32, f128mem, load,
2147                                     "comiss", SSEPackedSingle>, TB, VEX,
2148                                     VEX_LIG;
2149     defm VCOMISD  : sse12_ord_cmp<0x2F, VR128, undef, v2f64, f128mem, load,
2150                                     "comisd", SSEPackedDouble>, TB, OpSize, VEX,
2151                                     VEX_LIG;
2152   }
2153
2154   defm Int_VUCOMISS  : sse12_ord_cmp<0x2E, VR128, X86ucomi, v4f32, f128mem,
2155                             load, "ucomiss", SSEPackedSingle>, TB, VEX;
2156   defm Int_VUCOMISD  : sse12_ord_cmp<0x2E, VR128, X86ucomi, v2f64, f128mem,
2157                             load, "ucomisd", SSEPackedDouble>, TB, OpSize, VEX;
2158
2159   defm Int_VCOMISS  : sse12_ord_cmp<0x2F, VR128, X86comi, v4f32, f128mem,
2160                             load, "comiss", SSEPackedSingle>, TB, VEX;
2161   defm Int_VCOMISD  : sse12_ord_cmp<0x2F, VR128, X86comi, v2f64, f128mem,
2162                             load, "comisd", SSEPackedDouble>, TB, OpSize, VEX;
2163   defm UCOMISS  : sse12_ord_cmp<0x2E, FR32, X86cmp, f32, f32mem, loadf32,
2164                                   "ucomiss", SSEPackedSingle>, TB;
2165   defm UCOMISD  : sse12_ord_cmp<0x2E, FR64, X86cmp, f64, f64mem, loadf64,
2166                                   "ucomisd", SSEPackedDouble>, TB, OpSize;
2167
2168   let Pattern = []<dag> in {
2169     defm COMISS  : sse12_ord_cmp<0x2F, VR128, undef, v4f32, f128mem, load,
2170                                     "comiss", SSEPackedSingle>, TB;
2171     defm COMISD  : sse12_ord_cmp<0x2F, VR128, undef, v2f64, f128mem, load,
2172                                     "comisd", SSEPackedDouble>, TB, OpSize;
2173   }
2174
2175   defm Int_UCOMISS  : sse12_ord_cmp<0x2E, VR128, X86ucomi, v4f32, f128mem,
2176                               load, "ucomiss", SSEPackedSingle>, TB;
2177   defm Int_UCOMISD  : sse12_ord_cmp<0x2E, VR128, X86ucomi, v2f64, f128mem,
2178                               load, "ucomisd", SSEPackedDouble>, TB, OpSize;
2179
2180   defm Int_COMISS  : sse12_ord_cmp<0x2F, VR128, X86comi, v4f32, f128mem, load,
2181                                   "comiss", SSEPackedSingle>, TB;
2182   defm Int_COMISD  : sse12_ord_cmp<0x2F, VR128, X86comi, v2f64, f128mem, load,
2183                                   "comisd", SSEPackedDouble>, TB, OpSize;
2184 } // Defs = [EFLAGS]
2185
2186 // sse12_cmp_packed - sse 1 & 2 compared packed instructions
2187 multiclass sse12_cmp_packed<RegisterClass RC, X86MemOperand x86memop,
2188                             Intrinsic Int, string asm, string asm_alt,
2189                             Domain d> {
2190   let isAsmParserOnly = 1 in {
2191     def rri : PIi8<0xC2, MRMSrcReg,
2192                (outs RC:$dst), (ins RC:$src1, RC:$src2, SSECC:$cc), asm,
2193                [(set RC:$dst, (Int RC:$src1, RC:$src2, imm:$cc))],
2194                IIC_DEFAULT, d>;
2195     def rmi : PIi8<0xC2, MRMSrcMem,
2196                (outs RC:$dst), (ins RC:$src1, x86memop:$src2, SSECC:$cc), asm,
2197                [(set RC:$dst, (Int RC:$src1, (memop addr:$src2), imm:$cc))],
2198                IIC_DEFAULT, d>;
2199   }
2200
2201   // Accept explicit immediate argument form instead of comparison code.
2202   def rri_alt : PIi8<0xC2, MRMSrcReg,
2203              (outs RC:$dst), (ins RC:$src1, RC:$src2, i8imm:$cc),
2204              asm_alt, [], IIC_DEFAULT, d>;
2205   def rmi_alt : PIi8<0xC2, MRMSrcMem,
2206              (outs RC:$dst), (ins RC:$src1, x86memop:$src2, i8imm:$cc),
2207              asm_alt, [], IIC_DEFAULT, d>;
2208 }
2209
2210 defm VCMPPS : sse12_cmp_packed<VR128, f128mem, int_x86_sse_cmp_ps,
2211                "cmp${cc}ps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2212                "cmpps\t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}",
2213                SSEPackedSingle>, TB, VEX_4V;
2214 defm VCMPPD : sse12_cmp_packed<VR128, f128mem, int_x86_sse2_cmp_pd,
2215                "cmp${cc}pd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2216                "cmppd\t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}",
2217                SSEPackedDouble>, TB, OpSize, VEX_4V;
2218 defm VCMPPSY : sse12_cmp_packed<VR256, f256mem, int_x86_avx_cmp_ps_256,
2219                "cmp${cc}ps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2220                "cmpps\t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}",
2221                SSEPackedSingle>, TB, VEX_4V;
2222 defm VCMPPDY : sse12_cmp_packed<VR256, f256mem, int_x86_avx_cmp_pd_256,
2223                "cmp${cc}pd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2224                "cmppd\t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}",
2225                SSEPackedDouble>, TB, OpSize, VEX_4V;
2226 let Constraints = "$src1 = $dst" in {
2227   defm CMPPS : sse12_cmp_packed<VR128, f128mem, int_x86_sse_cmp_ps,
2228                  "cmp${cc}ps\t{$src2, $dst|$dst, $src2}",
2229                  "cmpps\t{$cc, $src2, $dst|$dst, $src2, $cc}",
2230                  SSEPackedSingle>, TB;
2231   defm CMPPD : sse12_cmp_packed<VR128, f128mem, int_x86_sse2_cmp_pd,
2232                  "cmp${cc}pd\t{$src2, $dst|$dst, $src2}",
2233                  "cmppd\t{$cc, $src2, $dst|$dst, $src2, $cc}",
2234                  SSEPackedDouble>, TB, OpSize;
2235 }
2236
2237 let Predicates = [HasAVX] in {
2238 def : Pat<(v4i32 (X86cmpp (v4f32 VR128:$src1), VR128:$src2, imm:$cc)),
2239           (VCMPPSrri (v4f32 VR128:$src1), (v4f32 VR128:$src2), imm:$cc)>;
2240 def : Pat<(v4i32 (X86cmpp (v4f32 VR128:$src1), (memop addr:$src2), imm:$cc)),
2241           (VCMPPSrmi (v4f32 VR128:$src1), addr:$src2, imm:$cc)>;
2242 def : Pat<(v2i64 (X86cmpp (v2f64 VR128:$src1), VR128:$src2, imm:$cc)),
2243           (VCMPPDrri VR128:$src1, VR128:$src2, imm:$cc)>;
2244 def : Pat<(v2i64 (X86cmpp (v2f64 VR128:$src1), (memop addr:$src2), imm:$cc)),
2245           (VCMPPDrmi VR128:$src1, addr:$src2, imm:$cc)>;
2246
2247 def : Pat<(v8i32 (X86cmpp (v8f32 VR256:$src1), VR256:$src2, imm:$cc)),
2248           (VCMPPSYrri (v8f32 VR256:$src1), (v8f32 VR256:$src2), imm:$cc)>;
2249 def : Pat<(v8i32 (X86cmpp (v8f32 VR256:$src1), (memop addr:$src2), imm:$cc)),
2250           (VCMPPSYrmi (v8f32 VR256:$src1), addr:$src2, imm:$cc)>;
2251 def : Pat<(v4i64 (X86cmpp (v4f64 VR256:$src1), VR256:$src2, imm:$cc)),
2252           (VCMPPDYrri VR256:$src1, VR256:$src2, imm:$cc)>;
2253 def : Pat<(v4i64 (X86cmpp (v4f64 VR256:$src1), (memop addr:$src2), imm:$cc)),
2254           (VCMPPDYrmi VR256:$src1, addr:$src2, imm:$cc)>;
2255 }
2256
2257 let Predicates = [HasSSE1] in {
2258 def : Pat<(v4i32 (X86cmpp (v4f32 VR128:$src1), VR128:$src2, imm:$cc)),
2259           (CMPPSrri (v4f32 VR128:$src1), (v4f32 VR128:$src2), imm:$cc)>;
2260 def : Pat<(v4i32 (X86cmpp (v4f32 VR128:$src1), (memop addr:$src2), imm:$cc)),
2261           (CMPPSrmi (v4f32 VR128:$src1), addr:$src2, imm:$cc)>;
2262 }
2263
2264 let Predicates = [HasSSE2] in {
2265 def : Pat<(v2i64 (X86cmpp (v2f64 VR128:$src1), VR128:$src2, imm:$cc)),
2266           (CMPPDrri VR128:$src1, VR128:$src2, imm:$cc)>;
2267 def : Pat<(v2i64 (X86cmpp (v2f64 VR128:$src1), (memop addr:$src2), imm:$cc)),
2268           (CMPPDrmi VR128:$src1, addr:$src2, imm:$cc)>;
2269 }
2270
2271 //===----------------------------------------------------------------------===//
2272 // SSE 1 & 2 - Shuffle Instructions
2273 //===----------------------------------------------------------------------===//
2274
2275 /// sse12_shuffle - sse 1 & 2 shuffle instructions
2276 multiclass sse12_shuffle<RegisterClass RC, X86MemOperand x86memop,
2277                          ValueType vt, string asm, PatFrag mem_frag,
2278                          Domain d, bit IsConvertibleToThreeAddress = 0> {
2279   def rmi : PIi8<0xC6, MRMSrcMem, (outs RC:$dst),
2280                    (ins RC:$src1, x86memop:$src2, i8imm:$src3), asm,
2281                    [(set RC:$dst, (vt (shufp:$src3
2282                             RC:$src1, (mem_frag addr:$src2))))],
2283                             IIC_DEFAULT, d>;
2284   let isConvertibleToThreeAddress = IsConvertibleToThreeAddress in
2285     def rri : PIi8<0xC6, MRMSrcReg, (outs RC:$dst),
2286                    (ins RC:$src1, RC:$src2, i8imm:$src3), asm,
2287                    [(set RC:$dst,
2288                             (vt (shufp:$src3 RC:$src1, RC:$src2)))],
2289                             IIC_DEFAULT, d>;
2290 }
2291
2292 defm VSHUFPS  : sse12_shuffle<VR128, f128mem, v4f32,
2293            "shufps\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
2294            memopv4f32, SSEPackedSingle>, TB, VEX_4V;
2295 defm VSHUFPSY : sse12_shuffle<VR256, f256mem, v8f32,
2296            "shufps\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
2297            memopv8f32, SSEPackedSingle>, TB, VEX_4V;
2298 defm VSHUFPD  : sse12_shuffle<VR128, f128mem, v2f64,
2299            "shufpd\t{$src3, $src2, $src1, $dst|$dst, $src2, $src2, $src3}",
2300            memopv2f64, SSEPackedDouble>, TB, OpSize, VEX_4V;
2301 defm VSHUFPDY : sse12_shuffle<VR256, f256mem, v4f64,
2302            "shufpd\t{$src3, $src2, $src1, $dst|$dst, $src2, $src2, $src3}",
2303            memopv4f64, SSEPackedDouble>, TB, OpSize, VEX_4V;
2304
2305 let Constraints = "$src1 = $dst" in {
2306   defm SHUFPS : sse12_shuffle<VR128, f128mem, v4f32,
2307                     "shufps\t{$src3, $src2, $dst|$dst, $src2, $src3}",
2308                     memopv4f32, SSEPackedSingle, 1 /* cvt to pshufd */>,
2309                     TB;
2310   defm SHUFPD : sse12_shuffle<VR128, f128mem, v2f64,
2311                     "shufpd\t{$src3, $src2, $dst|$dst, $src2, $src3}",
2312                     memopv2f64, SSEPackedDouble, 1 /* cvt to pshufd */>,
2313                     TB, OpSize;
2314 }
2315
2316 let Predicates = [HasAVX] in {
2317   def : Pat<(v4f32 (X86Shufp VR128:$src1,
2318                        (memopv4f32 addr:$src2), (i8 imm:$imm))),
2319             (VSHUFPSrmi VR128:$src1, addr:$src2, imm:$imm)>;
2320   def : Pat<(v4f32 (X86Shufp VR128:$src1, VR128:$src2, (i8 imm:$imm))),
2321             (VSHUFPSrri VR128:$src1, VR128:$src2, imm:$imm)>;
2322   def : Pat<(v4i32 (X86Shufp VR128:$src1,
2323                        (bc_v4i32 (memopv2i64 addr:$src2)), (i8 imm:$imm))),
2324             (VSHUFPSrmi VR128:$src1, addr:$src2, imm:$imm)>;
2325   def : Pat<(v4i32 (X86Shufp VR128:$src1, VR128:$src2, (i8 imm:$imm))),
2326             (VSHUFPSrri VR128:$src1, VR128:$src2, imm:$imm)>;
2327   // vector_shuffle v1, v2 <4, 5, 2, 3> using SHUFPSrri (we prefer movsd, but
2328   // fall back to this for SSE1)
2329   def : Pat<(v4f32 (movlp:$src3 VR128:$src1, (v4f32 VR128:$src2))),
2330             (VSHUFPSrri VR128:$src2, VR128:$src1,
2331                         (SHUFFLE_get_shuf_imm VR128:$src3))>;
2332   // Special unary SHUFPSrri case.
2333   def : Pat<(v4f32 (pshufd:$src3 VR128:$src1, (undef))),
2334             (VSHUFPSrri VR128:$src1, VR128:$src1,
2335                         (SHUFFLE_get_shuf_imm VR128:$src3))>;
2336   // Special binary v4i32 shuffle cases with SHUFPS.
2337   def : Pat<(v4i32 (shufp:$src3 VR128:$src1, (v4i32 VR128:$src2))),
2338             (VSHUFPSrri VR128:$src1, VR128:$src2,
2339                         (SHUFFLE_get_shuf_imm VR128:$src3))>;
2340   def : Pat<(v4i32 (shufp:$src3 VR128:$src1,
2341                                 (bc_v4i32 (memopv2i64 addr:$src2)))),
2342             (VSHUFPSrmi VR128:$src1, addr:$src2,
2343                         (SHUFFLE_get_shuf_imm VR128:$src3))>;
2344   // Special unary SHUFPDrri cases.
2345   def : Pat<(v2i64 (pshufd:$src3 VR128:$src1, (undef))),
2346             (VSHUFPDrri VR128:$src1, VR128:$src1,
2347                         (SHUFFLE_get_shuf_imm VR128:$src3))>;
2348   def : Pat<(v2f64 (pshufd:$src3 VR128:$src1, (undef))),
2349             (VSHUFPDrri VR128:$src1, VR128:$src1,
2350                         (SHUFFLE_get_shuf_imm VR128:$src3))>;
2351   // Special binary v2i64 shuffle cases using SHUFPDrri.
2352   def : Pat<(v2i64 (shufp:$src3 VR128:$src1, VR128:$src2)),
2353             (VSHUFPDrri VR128:$src1, VR128:$src2,
2354                         (SHUFFLE_get_shuf_imm VR128:$src3))>;
2355
2356   def : Pat<(v2i64 (X86Shufp VR128:$src1,
2357                        (memopv2i64 addr:$src2), (i8 imm:$imm))),
2358             (VSHUFPDrmi VR128:$src1, addr:$src2, imm:$imm)>;
2359   def : Pat<(v2f64 (X86Shufp VR128:$src1,
2360                        (memopv2f64 addr:$src2), (i8 imm:$imm))),
2361             (VSHUFPDrmi VR128:$src1, addr:$src2, imm:$imm)>;
2362   def : Pat<(v2i64 (X86Shufp VR128:$src1, VR128:$src2, (i8 imm:$imm))),
2363             (VSHUFPDrri VR128:$src1, VR128:$src2, imm:$imm)>;
2364   def : Pat<(v2f64 (X86Shufp VR128:$src1, VR128:$src2, (i8 imm:$imm))),
2365             (VSHUFPDrri VR128:$src1, VR128:$src2, imm:$imm)>;
2366
2367   // 256-bit patterns
2368   def : Pat<(v8i32 (X86Shufp VR256:$src1, VR256:$src2, (i8 imm:$imm))),
2369             (VSHUFPSYrri VR256:$src1, VR256:$src2, imm:$imm)>;
2370   def : Pat<(v8i32 (X86Shufp VR256:$src1,
2371                       (bc_v8i32 (memopv4i64 addr:$src2)), (i8 imm:$imm))),
2372             (VSHUFPSYrmi VR256:$src1, addr:$src2, imm:$imm)>;
2373
2374   def : Pat<(v8f32 (X86Shufp VR256:$src1, VR256:$src2, (i8 imm:$imm))),
2375             (VSHUFPSYrri VR256:$src1, VR256:$src2, imm:$imm)>;
2376   def : Pat<(v8f32 (X86Shufp VR256:$src1,
2377                               (memopv8f32 addr:$src2), (i8 imm:$imm))),
2378             (VSHUFPSYrmi VR256:$src1, addr:$src2, imm:$imm)>;
2379
2380   def : Pat<(v4i64 (X86Shufp VR256:$src1, VR256:$src2, (i8 imm:$imm))),
2381             (VSHUFPDYrri VR256:$src1, VR256:$src2, imm:$imm)>;
2382   def : Pat<(v4i64 (X86Shufp VR256:$src1,
2383                               (memopv4i64 addr:$src2), (i8 imm:$imm))),
2384             (VSHUFPDYrmi VR256:$src1, addr:$src2, imm:$imm)>;
2385
2386   def : Pat<(v4f64 (X86Shufp VR256:$src1, VR256:$src2, (i8 imm:$imm))),
2387             (VSHUFPDYrri VR256:$src1, VR256:$src2, imm:$imm)>;
2388   def : Pat<(v4f64 (X86Shufp VR256:$src1,
2389                               (memopv4f64 addr:$src2), (i8 imm:$imm))),
2390             (VSHUFPDYrmi VR256:$src1, addr:$src2, imm:$imm)>;
2391 }
2392
2393 let Predicates = [HasSSE1] in {
2394   def : Pat<(v4f32 (X86Shufp VR128:$src1,
2395                        (memopv4f32 addr:$src2), (i8 imm:$imm))),
2396             (SHUFPSrmi VR128:$src1, addr:$src2, imm:$imm)>;
2397   def : Pat<(v4f32 (X86Shufp VR128:$src1, VR128:$src2, (i8 imm:$imm))),
2398             (SHUFPSrri VR128:$src1, VR128:$src2, imm:$imm)>;
2399   def : Pat<(v4i32 (X86Shufp VR128:$src1,
2400                        (bc_v4i32 (memopv2i64 addr:$src2)), (i8 imm:$imm))),
2401             (SHUFPSrmi VR128:$src1, addr:$src2, imm:$imm)>;
2402   def : Pat<(v4i32 (X86Shufp VR128:$src1, VR128:$src2, (i8 imm:$imm))),
2403             (SHUFPSrri VR128:$src1, VR128:$src2, imm:$imm)>;
2404   // vector_shuffle v1, v2 <4, 5, 2, 3> using SHUFPSrri (we prefer movsd, but
2405   // fall back to this for SSE1)
2406   def : Pat<(v4f32 (movlp:$src3 VR128:$src1, (v4f32 VR128:$src2))),
2407             (SHUFPSrri VR128:$src2, VR128:$src1,
2408                        (SHUFFLE_get_shuf_imm VR128:$src3))>;
2409   // Special unary SHUFPSrri case.
2410   def : Pat<(v4f32 (pshufd:$src3 VR128:$src1, (undef))),
2411             (SHUFPSrri VR128:$src1, VR128:$src1,
2412                        (SHUFFLE_get_shuf_imm VR128:$src3))>;
2413 }
2414
2415 let Predicates = [HasSSE2] in {
2416   // Special binary v4i32 shuffle cases with SHUFPS.
2417   def : Pat<(v4i32 (shufp:$src3 VR128:$src1, (v4i32 VR128:$src2))),
2418             (SHUFPSrri VR128:$src1, VR128:$src2,
2419                        (SHUFFLE_get_shuf_imm VR128:$src3))>;
2420   def : Pat<(v4i32 (shufp:$src3 VR128:$src1,
2421                                 (bc_v4i32 (memopv2i64 addr:$src2)))),
2422             (SHUFPSrmi VR128:$src1, addr:$src2,
2423                       (SHUFFLE_get_shuf_imm VR128:$src3))>;
2424   // Special unary SHUFPDrri cases.
2425   def : Pat<(v2i64 (pshufd:$src3 VR128:$src1, (undef))),
2426             (SHUFPDrri VR128:$src1, VR128:$src1,
2427                        (SHUFFLE_get_shuf_imm VR128:$src3))>;
2428   def : Pat<(v2f64 (pshufd:$src3 VR128:$src1, (undef))),
2429             (SHUFPDrri VR128:$src1, VR128:$src1,
2430                        (SHUFFLE_get_shuf_imm VR128:$src3))>;
2431   // Special binary v2i64 shuffle cases using SHUFPDrri.
2432   def : Pat<(v2i64 (shufp:$src3 VR128:$src1, VR128:$src2)),
2433             (SHUFPDrri VR128:$src1, VR128:$src2,
2434                        (SHUFFLE_get_shuf_imm VR128:$src3))>;
2435   // Generic SHUFPD patterns
2436   def : Pat<(v2i64 (X86Shufp VR128:$src1,
2437                        (memopv2i64 addr:$src2), (i8 imm:$imm))),
2438             (SHUFPDrmi VR128:$src1, addr:$src2, imm:$imm)>;
2439   def : Pat<(v2f64 (X86Shufp VR128:$src1,
2440                        (memopv2f64 addr:$src2), (i8 imm:$imm))),
2441             (SHUFPDrmi VR128:$src1, addr:$src2, imm:$imm)>;
2442   def : Pat<(v2i64 (X86Shufp VR128:$src1, VR128:$src2, (i8 imm:$imm))),
2443             (SHUFPDrri VR128:$src1, VR128:$src2, imm:$imm)>;
2444   def : Pat<(v2f64 (X86Shufp VR128:$src1, VR128:$src2, (i8 imm:$imm))),
2445             (SHUFPDrri VR128:$src1, VR128:$src2, imm:$imm)>;
2446 }
2447
2448 //===----------------------------------------------------------------------===//
2449 // SSE 1 & 2 - Unpack Instructions
2450 //===----------------------------------------------------------------------===//
2451
2452 /// sse12_unpack_interleave - sse 1 & 2 unpack and interleave
2453 multiclass sse12_unpack_interleave<bits<8> opc, PatFrag OpNode, ValueType vt,
2454                                    PatFrag mem_frag, RegisterClass RC,
2455                                    X86MemOperand x86memop, string asm,
2456                                    Domain d> {
2457     def rr : PI<opc, MRMSrcReg,
2458                 (outs RC:$dst), (ins RC:$src1, RC:$src2),
2459                 asm, [(set RC:$dst,
2460                            (vt (OpNode RC:$src1, RC:$src2)))],
2461                            IIC_DEFAULT, d>;
2462     def rm : PI<opc, MRMSrcMem,
2463                 (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
2464                 asm, [(set RC:$dst,
2465                            (vt (OpNode RC:$src1,
2466                                        (mem_frag addr:$src2))))],
2467                                        IIC_DEFAULT, d>;
2468 }
2469
2470 let AddedComplexity = 10 in {
2471   defm VUNPCKHPS: sse12_unpack_interleave<0x15, unpckh, v4f32, memopv4f32,
2472         VR128, f128mem, "unpckhps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2473                        SSEPackedSingle>, TB, VEX_4V;
2474   defm VUNPCKHPD: sse12_unpack_interleave<0x15, unpckh, v2f64, memopv2f64,
2475         VR128, f128mem, "unpckhpd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2476                        SSEPackedDouble>, TB, OpSize, VEX_4V;
2477   defm VUNPCKLPS: sse12_unpack_interleave<0x14, unpckl, v4f32, memopv4f32,
2478         VR128, f128mem, "unpcklps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2479                        SSEPackedSingle>, TB, VEX_4V;
2480   defm VUNPCKLPD: sse12_unpack_interleave<0x14, unpckl, v2f64, memopv2f64,
2481         VR128, f128mem, "unpcklpd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2482                        SSEPackedDouble>, TB, OpSize, VEX_4V;
2483
2484   defm VUNPCKHPSY: sse12_unpack_interleave<0x15, unpckh, v8f32, memopv8f32,
2485         VR256, f256mem, "unpckhps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2486                        SSEPackedSingle>, TB, VEX_4V;
2487   defm VUNPCKHPDY: sse12_unpack_interleave<0x15, unpckh, v4f64, memopv4f64,
2488         VR256, f256mem, "unpckhpd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2489                        SSEPackedDouble>, TB, OpSize, VEX_4V;
2490   defm VUNPCKLPSY: sse12_unpack_interleave<0x14, unpckl, v8f32, memopv8f32,
2491         VR256, f256mem, "unpcklps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2492                        SSEPackedSingle>, TB, VEX_4V;
2493   defm VUNPCKLPDY: sse12_unpack_interleave<0x14, unpckl, v4f64, memopv4f64,
2494         VR256, f256mem, "unpcklpd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2495                        SSEPackedDouble>, TB, OpSize, VEX_4V;
2496
2497   let Constraints = "$src1 = $dst" in {
2498     defm UNPCKHPS: sse12_unpack_interleave<0x15, unpckh, v4f32, memopv4f32,
2499           VR128, f128mem, "unpckhps\t{$src2, $dst|$dst, $src2}",
2500                          SSEPackedSingle>, TB;
2501     defm UNPCKHPD: sse12_unpack_interleave<0x15, unpckh, v2f64, memopv2f64,
2502           VR128, f128mem, "unpckhpd\t{$src2, $dst|$dst, $src2}",
2503                          SSEPackedDouble>, TB, OpSize;
2504     defm UNPCKLPS: sse12_unpack_interleave<0x14, unpckl, v4f32, memopv4f32,
2505           VR128, f128mem, "unpcklps\t{$src2, $dst|$dst, $src2}",
2506                          SSEPackedSingle>, TB;
2507     defm UNPCKLPD: sse12_unpack_interleave<0x14, unpckl, v2f64, memopv2f64,
2508           VR128, f128mem, "unpcklpd\t{$src2, $dst|$dst, $src2}",
2509                          SSEPackedDouble>, TB, OpSize;
2510   } // Constraints = "$src1 = $dst"
2511 } // AddedComplexity
2512
2513 let Predicates = [HasAVX], AddedComplexity = 1 in {
2514   def : Pat<(v4f32 (X86Unpckl VR128:$src1, (memopv4f32 addr:$src2))),
2515             (VUNPCKLPSrm VR128:$src1, addr:$src2)>;
2516   def : Pat<(v4f32 (X86Unpckl VR128:$src1, VR128:$src2)),
2517             (VUNPCKLPSrr VR128:$src1, VR128:$src2)>;
2518   def : Pat<(v4f32 (X86Unpckh VR128:$src1, (memopv4f32 addr:$src2))),
2519             (VUNPCKHPSrm VR128:$src1, addr:$src2)>;
2520   def : Pat<(v4f32 (X86Unpckh VR128:$src1, VR128:$src2)),
2521             (VUNPCKHPSrr VR128:$src1, VR128:$src2)>;
2522
2523   def : Pat<(v8f32 (X86Unpckl VR256:$src1, (memopv8f32 addr:$src2))),
2524             (VUNPCKLPSYrm VR256:$src1, addr:$src2)>;
2525   def : Pat<(v8f32 (X86Unpckl VR256:$src1, VR256:$src2)),
2526             (VUNPCKLPSYrr VR256:$src1, VR256:$src2)>;
2527   def : Pat<(v8f32 (X86Unpckh VR256:$src1, (memopv8f32 addr:$src2))),
2528             (VUNPCKHPSYrm VR256:$src1, addr:$src2)>;
2529   def : Pat<(v8f32 (X86Unpckh VR256:$src1, VR256:$src2)),
2530             (VUNPCKHPSYrr VR256:$src1, VR256:$src2)>;
2531
2532   def : Pat<(v2f64 (X86Unpckl VR128:$src1, (memopv2f64 addr:$src2))),
2533             (VUNPCKLPDrm VR128:$src1, addr:$src2)>;
2534   def : Pat<(v2f64 (X86Unpckl VR128:$src1, VR128:$src2)),
2535             (VUNPCKLPDrr VR128:$src1, VR128:$src2)>;
2536   def : Pat<(v2f64 (X86Unpckh VR128:$src1, (memopv2f64 addr:$src2))),
2537             (VUNPCKHPDrm VR128:$src1, addr:$src2)>;
2538   def : Pat<(v2f64 (X86Unpckh VR128:$src1, VR128:$src2)),
2539             (VUNPCKHPDrr VR128:$src1, VR128:$src2)>;
2540
2541   def : Pat<(v4f64 (X86Unpckl VR256:$src1, (memopv4f64 addr:$src2))),
2542             (VUNPCKLPDYrm VR256:$src1, addr:$src2)>;
2543   def : Pat<(v4f64 (X86Unpckl VR256:$src1, VR256:$src2)),
2544             (VUNPCKLPDYrr VR256:$src1, VR256:$src2)>;
2545   def : Pat<(v4f64 (X86Unpckh VR256:$src1, (memopv4f64 addr:$src2))),
2546             (VUNPCKHPDYrm VR256:$src1, addr:$src2)>;
2547   def : Pat<(v4f64 (X86Unpckh VR256:$src1, VR256:$src2)),
2548             (VUNPCKHPDYrr VR256:$src1, VR256:$src2)>;
2549
2550   // FIXME: Instead of X86Movddup, there should be a X86Unpckl here, the
2551   // problem is during lowering, where it's not possible to recognize the load
2552   // fold cause it has two uses through a bitcast. One use disappears at isel
2553   // time and the fold opportunity reappears.
2554   def : Pat<(v2f64 (X86Movddup VR128:$src)),
2555             (VUNPCKLPDrr VR128:$src, VR128:$src)>;
2556   let AddedComplexity = 10 in
2557   def : Pat<(splat_lo (v2f64 VR128:$src), (undef)),
2558             (VUNPCKLPDrr VR128:$src, VR128:$src)>;
2559 }
2560
2561 let Predicates = [HasSSE1] in {
2562   def : Pat<(v4f32 (X86Unpckl VR128:$src1, (memopv4f32 addr:$src2))),
2563             (UNPCKLPSrm VR128:$src1, addr:$src2)>;
2564   def : Pat<(v4f32 (X86Unpckl VR128:$src1, VR128:$src2)),
2565             (UNPCKLPSrr VR128:$src1, VR128:$src2)>;
2566   def : Pat<(v4f32 (X86Unpckh VR128:$src1, (memopv4f32 addr:$src2))),
2567             (UNPCKHPSrm VR128:$src1, addr:$src2)>;
2568   def : Pat<(v4f32 (X86Unpckh VR128:$src1, VR128:$src2)),
2569             (UNPCKHPSrr VR128:$src1, VR128:$src2)>;
2570 }
2571
2572 let Predicates = [HasSSE2] in {
2573   def : Pat<(v2f64 (X86Unpckl VR128:$src1, (memopv2f64 addr:$src2))),
2574             (UNPCKLPDrm VR128:$src1, addr:$src2)>;
2575   def : Pat<(v2f64 (X86Unpckl VR128:$src1, VR128:$src2)),
2576             (UNPCKLPDrr VR128:$src1, VR128:$src2)>;
2577   def : Pat<(v2f64 (X86Unpckh VR128:$src1, (memopv2f64 addr:$src2))),
2578             (UNPCKHPDrm VR128:$src1, addr:$src2)>;
2579   def : Pat<(v2f64 (X86Unpckh VR128:$src1, VR128:$src2)),
2580             (UNPCKHPDrr VR128:$src1, VR128:$src2)>;
2581
2582   // FIXME: Instead of X86Movddup, there should be a X86Unpckl here, the
2583   // problem is during lowering, where it's not possible to recognize the load
2584   // fold cause it has two uses through a bitcast. One use disappears at isel
2585   // time and the fold opportunity reappears.
2586   def : Pat<(v2f64 (X86Movddup VR128:$src)),
2587             (UNPCKLPDrr VR128:$src, VR128:$src)>;
2588
2589   let AddedComplexity = 10 in
2590   def : Pat<(splat_lo (v2f64 VR128:$src), (undef)),
2591             (UNPCKLPDrr VR128:$src, VR128:$src)>;
2592 }
2593
2594 //===----------------------------------------------------------------------===//
2595 // SSE 1 & 2 - Extract Floating-Point Sign mask
2596 //===----------------------------------------------------------------------===//
2597
2598 /// sse12_extr_sign_mask - sse 1 & 2 unpack and interleave
2599 multiclass sse12_extr_sign_mask<RegisterClass RC, Intrinsic Int, string asm,
2600                                 Domain d> {
2601   def rr32 : PI<0x50, MRMSrcReg, (outs GR32:$dst), (ins RC:$src),
2602                 !strconcat(asm, "\t{$src, $dst|$dst, $src}"),
2603                      [(set GR32:$dst, (Int RC:$src))], IIC_DEFAULT, d>;
2604   def rr64 : PI<0x50, MRMSrcReg, (outs GR64:$dst), (ins RC:$src),
2605                 !strconcat(asm, "\t{$src, $dst|$dst, $src}"), [],
2606                 IIC_DEFAULT, d>, REX_W;
2607 }
2608
2609 let Predicates = [HasAVX] in {
2610   defm VMOVMSKPS : sse12_extr_sign_mask<VR128, int_x86_sse_movmsk_ps,
2611                                         "movmskps", SSEPackedSingle>, TB, VEX;
2612   defm VMOVMSKPD : sse12_extr_sign_mask<VR128, int_x86_sse2_movmsk_pd,
2613                                         "movmskpd", SSEPackedDouble>, TB,
2614                                         OpSize, VEX;
2615   defm VMOVMSKPSY : sse12_extr_sign_mask<VR256, int_x86_avx_movmsk_ps_256,
2616                                         "movmskps", SSEPackedSingle>, TB, VEX;
2617   defm VMOVMSKPDY : sse12_extr_sign_mask<VR256, int_x86_avx_movmsk_pd_256,
2618                                         "movmskpd", SSEPackedDouble>, TB,
2619                                         OpSize, VEX;
2620
2621   def : Pat<(i32 (X86fgetsign FR32:$src)),
2622             (VMOVMSKPSrr32 (INSERT_SUBREG (v4f32 (IMPLICIT_DEF)), FR32:$src,
2623                                           sub_ss))>;
2624   def : Pat<(i64 (X86fgetsign FR32:$src)),
2625             (VMOVMSKPSrr64 (INSERT_SUBREG (v4f32 (IMPLICIT_DEF)), FR32:$src,
2626                                           sub_ss))>;
2627   def : Pat<(i32 (X86fgetsign FR64:$src)),
2628             (VMOVMSKPDrr32 (INSERT_SUBREG (v2f64 (IMPLICIT_DEF)), FR64:$src,
2629                                           sub_sd))>;
2630   def : Pat<(i64 (X86fgetsign FR64:$src)),
2631             (VMOVMSKPDrr64 (INSERT_SUBREG (v2f64 (IMPLICIT_DEF)), FR64:$src,
2632                                           sub_sd))>;
2633
2634   // Assembler Only
2635   def VMOVMSKPSr64r : PI<0x50, MRMSrcReg, (outs GR64:$dst), (ins VR128:$src),
2636              "movmskps\t{$src, $dst|$dst, $src}", [], IIC_DEFAULT,
2637              SSEPackedSingle>, TB, VEX;
2638   def VMOVMSKPDr64r : PI<0x50, MRMSrcReg, (outs GR64:$dst), (ins VR128:$src),
2639              "movmskpd\t{$src, $dst|$dst, $src}", [], IIC_DEFAULT,
2640              SSEPackedDouble>, TB,
2641              OpSize, VEX;
2642   def VMOVMSKPSYr64r : PI<0x50, MRMSrcReg, (outs GR64:$dst), (ins VR256:$src),
2643              "movmskps\t{$src, $dst|$dst, $src}", [], IIC_DEFAULT,
2644              SSEPackedSingle>, TB, VEX;
2645   def VMOVMSKPDYr64r : PI<0x50, MRMSrcReg, (outs GR64:$dst), (ins VR256:$src),
2646              "movmskpd\t{$src, $dst|$dst, $src}", [], IIC_DEFAULT,
2647              SSEPackedDouble>, TB,
2648              OpSize, VEX;
2649 }
2650
2651 defm MOVMSKPS : sse12_extr_sign_mask<VR128, int_x86_sse_movmsk_ps, "movmskps",
2652                                      SSEPackedSingle>, TB;
2653 defm MOVMSKPD : sse12_extr_sign_mask<VR128, int_x86_sse2_movmsk_pd, "movmskpd",
2654                                      SSEPackedDouble>, TB, OpSize;
2655
2656 def : Pat<(i32 (X86fgetsign FR32:$src)),
2657           (MOVMSKPSrr32 (INSERT_SUBREG (v4f32 (IMPLICIT_DEF)), FR32:$src,
2658                                        sub_ss))>, Requires<[HasSSE1]>;
2659 def : Pat<(i64 (X86fgetsign FR32:$src)),
2660           (MOVMSKPSrr64 (INSERT_SUBREG (v4f32 (IMPLICIT_DEF)), FR32:$src,
2661                                        sub_ss))>, Requires<[HasSSE1]>;
2662 def : Pat<(i32 (X86fgetsign FR64:$src)),
2663           (MOVMSKPDrr32 (INSERT_SUBREG (v2f64 (IMPLICIT_DEF)), FR64:$src,
2664                                        sub_sd))>, Requires<[HasSSE2]>;
2665 def : Pat<(i64 (X86fgetsign FR64:$src)),
2666           (MOVMSKPDrr64 (INSERT_SUBREG (v2f64 (IMPLICIT_DEF)), FR64:$src,
2667                                        sub_sd))>, Requires<[HasSSE2]>;
2668
2669 //===---------------------------------------------------------------------===//
2670 // SSE2 - Packed Integer Logical Instructions
2671 //===---------------------------------------------------------------------===//
2672
2673 let ExeDomain = SSEPackedInt in { // SSE integer instructions
2674
2675 /// PDI_binop_rm - Simple SSE2 binary operator.
2676 multiclass PDI_binop_rm<bits<8> opc, string OpcodeStr, SDNode OpNode,
2677                         ValueType OpVT, RegisterClass RC, PatFrag memop_frag,
2678                         X86MemOperand x86memop, bit IsCommutable = 0,
2679                         bit Is2Addr = 1> {
2680   let isCommutable = IsCommutable in
2681   def rr : PDI<opc, MRMSrcReg, (outs RC:$dst),
2682        (ins RC:$src1, RC:$src2),
2683        !if(Is2Addr,
2684            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
2685            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
2686        [(set RC:$dst, (OpVT (OpNode RC:$src1, RC:$src2)))]>;
2687   def rm : PDI<opc, MRMSrcMem, (outs RC:$dst),
2688        (ins RC:$src1, x86memop:$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,
2693                                      (bitconvert (memop_frag addr:$src2)))))]>;
2694 }
2695 } // ExeDomain = SSEPackedInt
2696
2697 // These are ordered here for pattern ordering requirements with the fp versions
2698
2699 let Predicates = [HasAVX] in {
2700 defm VPAND : PDI_binop_rm<0xDB, "vpand", and, v2i64, VR128, memopv2i64,
2701                           i128mem, 1, 0>, VEX_4V;
2702 defm VPOR  : PDI_binop_rm<0xEB, "vpor" , or, v2i64, VR128, memopv2i64,
2703                           i128mem, 1, 0>, VEX_4V;
2704 defm VPXOR : PDI_binop_rm<0xEF, "vpxor", xor, v2i64, VR128, memopv2i64,
2705                           i128mem, 1, 0>, VEX_4V;
2706 defm VPANDN : PDI_binop_rm<0xDF, "vpandn", X86andnp, v2i64, VR128, memopv2i64,
2707                           i128mem, 0, 0>, VEX_4V;
2708 }
2709
2710 let Constraints = "$src1 = $dst" in {
2711 defm PAND : PDI_binop_rm<0xDB, "pand", and, v2i64, VR128, memopv2i64,
2712                          i128mem, 1>;
2713 defm POR  : PDI_binop_rm<0xEB, "por" , or, v2i64, VR128, memopv2i64,
2714                          i128mem, 1>;
2715 defm PXOR : PDI_binop_rm<0xEF, "pxor", xor, v2i64, VR128, memopv2i64,
2716                          i128mem, 1>;
2717 defm PANDN : PDI_binop_rm<0xDF, "pandn", X86andnp, v2i64, VR128, memopv2i64,
2718                           i128mem, 0>;
2719 } // Constraints = "$src1 = $dst"
2720
2721 let Predicates = [HasAVX2] in {
2722 defm VPANDY : PDI_binop_rm<0xDB, "vpand", and, v4i64, VR256, memopv4i64,
2723                            i256mem, 1, 0>, VEX_4V;
2724 defm VPORY  : PDI_binop_rm<0xEB, "vpor", or, v4i64, VR256, memopv4i64,
2725                            i256mem, 1, 0>, VEX_4V;
2726 defm VPXORY : PDI_binop_rm<0xEF, "vpxor", xor, v4i64, VR256, memopv4i64,
2727                            i256mem, 1, 0>, VEX_4V;
2728 defm VPANDNY : PDI_binop_rm<0xDF, "vpandn", X86andnp, v4i64, VR256, memopv4i64,
2729                             i256mem, 0, 0>, VEX_4V;
2730 }
2731
2732 //===----------------------------------------------------------------------===//
2733 // SSE 1 & 2 - Logical Instructions
2734 //===----------------------------------------------------------------------===//
2735
2736 /// sse12_fp_alias_pack_logical - SSE 1 & 2 aliased packed FP logical ops
2737 ///
2738 multiclass sse12_fp_alias_pack_logical<bits<8> opc, string OpcodeStr,
2739                                        SDNode OpNode> {
2740   defm V#NAME#PS : sse12_fp_packed<opc, !strconcat(OpcodeStr, "ps"), OpNode,
2741               FR32, f32, f128mem, memopfsf32, SSEPackedSingle, 0>, TB, VEX_4V;
2742
2743   defm V#NAME#PD : sse12_fp_packed<opc, !strconcat(OpcodeStr, "pd"), OpNode,
2744         FR64, f64, f128mem, memopfsf64, SSEPackedDouble, 0>, TB, OpSize, VEX_4V;
2745
2746   let Constraints = "$src1 = $dst" in {
2747     defm PS : sse12_fp_packed<opc, !strconcat(OpcodeStr, "ps"), OpNode, FR32,
2748                 f32, f128mem, memopfsf32, SSEPackedSingle>, TB;
2749
2750     defm PD : sse12_fp_packed<opc, !strconcat(OpcodeStr, "pd"), OpNode, FR64,
2751                 f64, f128mem, memopfsf64, SSEPackedDouble>, TB, OpSize;
2752   }
2753 }
2754
2755 // Alias bitwise logical operations using SSE logical ops on packed FP values.
2756 let mayLoad = 0 in {
2757   defm FsAND  : sse12_fp_alias_pack_logical<0x54, "and", X86fand>;
2758   defm FsOR   : sse12_fp_alias_pack_logical<0x56, "or", X86for>;
2759   defm FsXOR  : sse12_fp_alias_pack_logical<0x57, "xor", X86fxor>;
2760 }
2761
2762 let neverHasSideEffects = 1, Pattern = []<dag>, isCommutable = 0 in
2763   defm FsANDN : sse12_fp_alias_pack_logical<0x55, "andn", undef>;
2764
2765 /// sse12_fp_packed_logical - SSE 1 & 2 packed FP logical ops
2766 ///
2767 multiclass sse12_fp_packed_logical<bits<8> opc, string OpcodeStr,
2768                                    SDNode OpNode> {
2769   // In AVX no need to add a pattern for 128-bit logical rr ps, because they
2770   // are all promoted to v2i64, and the patterns are covered by the int
2771   // version. This is needed in SSE only, because v2i64 isn't supported on
2772   // SSE1, but only on SSE2.
2773   defm V#NAME#PS : sse12_fp_packed_logical_rm<opc, VR128, SSEPackedSingle,
2774        !strconcat(OpcodeStr, "ps"), f128mem, [],
2775        [(set VR128:$dst, (OpNode (bc_v2i64 (v4f32 VR128:$src1)),
2776                                  (memopv2i64 addr:$src2)))], 0, 1>, TB, VEX_4V;
2777
2778   defm V#NAME#PD : sse12_fp_packed_logical_rm<opc, VR128, SSEPackedDouble,
2779        !strconcat(OpcodeStr, "pd"), f128mem,
2780        [(set VR128:$dst, (OpNode (bc_v2i64 (v2f64 VR128:$src1)),
2781                                  (bc_v2i64 (v2f64 VR128:$src2))))],
2782        [(set VR128:$dst, (OpNode (bc_v2i64 (v2f64 VR128:$src1)),
2783                                  (memopv2i64 addr:$src2)))], 0>,
2784                                                  TB, OpSize, VEX_4V;
2785   let Constraints = "$src1 = $dst" in {
2786     defm PS : sse12_fp_packed_logical_rm<opc, VR128, SSEPackedSingle,
2787          !strconcat(OpcodeStr, "ps"), f128mem,
2788          [(set VR128:$dst, (v2i64 (OpNode VR128:$src1, VR128:$src2)))],
2789          [(set VR128:$dst, (OpNode (bc_v2i64 (v4f32 VR128:$src1)),
2790                                    (memopv2i64 addr:$src2)))]>, TB;
2791
2792     defm PD : sse12_fp_packed_logical_rm<opc, VR128, SSEPackedDouble,
2793          !strconcat(OpcodeStr, "pd"), f128mem,
2794          [(set VR128:$dst, (OpNode (bc_v2i64 (v2f64 VR128:$src1)),
2795                                    (bc_v2i64 (v2f64 VR128:$src2))))],
2796          [(set VR128:$dst, (OpNode (bc_v2i64 (v2f64 VR128:$src1)),
2797                                    (memopv2i64 addr:$src2)))]>, TB, OpSize;
2798   }
2799 }
2800
2801 /// sse12_fp_packed_logical_y - AVX 256-bit SSE 1 & 2 logical ops forms
2802 ///
2803 multiclass sse12_fp_packed_logical_y<bits<8> opc, string OpcodeStr,
2804                                      SDNode OpNode> {
2805     defm PSY : sse12_fp_packed_logical_rm<opc, VR256, SSEPackedSingle,
2806           !strconcat(OpcodeStr, "ps"), f256mem,
2807           [(set VR256:$dst, (v4i64 (OpNode VR256:$src1, VR256:$src2)))],
2808           [(set VR256:$dst, (OpNode (bc_v4i64 (v8f32 VR256:$src1)),
2809                                     (memopv4i64 addr:$src2)))], 0>, TB, VEX_4V;
2810
2811     defm PDY : sse12_fp_packed_logical_rm<opc, VR256, SSEPackedDouble,
2812           !strconcat(OpcodeStr, "pd"), f256mem,
2813           [(set VR256:$dst, (OpNode (bc_v4i64 (v4f64 VR256:$src1)),
2814                                     (bc_v4i64 (v4f64 VR256:$src2))))],
2815           [(set VR256:$dst, (OpNode (bc_v4i64 (v4f64 VR256:$src1)),
2816                                     (memopv4i64 addr:$src2)))], 0>,
2817                                     TB, OpSize, VEX_4V;
2818 }
2819
2820 // AVX 256-bit packed logical ops forms
2821 defm VAND  : sse12_fp_packed_logical_y<0x54, "and", and>;
2822 defm VOR   : sse12_fp_packed_logical_y<0x56, "or", or>;
2823 defm VXOR  : sse12_fp_packed_logical_y<0x57, "xor", xor>;
2824 defm VANDN : sse12_fp_packed_logical_y<0x55, "andn", X86andnp>;
2825
2826 defm AND  : sse12_fp_packed_logical<0x54, "and", and>;
2827 defm OR   : sse12_fp_packed_logical<0x56, "or", or>;
2828 defm XOR  : sse12_fp_packed_logical<0x57, "xor", xor>;
2829 let isCommutable = 0 in
2830   defm ANDN : sse12_fp_packed_logical<0x55, "andn", X86andnp>;
2831
2832 //===----------------------------------------------------------------------===//
2833 // SSE 1 & 2 - Arithmetic Instructions
2834 //===----------------------------------------------------------------------===//
2835
2836 /// basic_sse12_fp_binop_xxx - SSE 1 & 2 binops come in both scalar and
2837 /// vector forms.
2838 ///
2839 /// In addition, we also have a special variant of the scalar form here to
2840 /// represent the associated intrinsic operation.  This form is unlike the
2841 /// plain scalar form, in that it takes an entire vector (instead of a scalar)
2842 /// and leaves the top elements unmodified (therefore these cannot be commuted).
2843 ///
2844 /// These three forms can each be reg+reg or reg+mem.
2845 ///
2846
2847 /// FIXME: once all 256-bit intrinsics are matched, cleanup and refactor those
2848 /// classes below
2849 multiclass basic_sse12_fp_binop_s<bits<8> opc, string OpcodeStr, SDNode OpNode,
2850                                   bit Is2Addr = 1> {
2851   defm SS : sse12_fp_scalar<opc, !strconcat(OpcodeStr, "ss"),
2852                             OpNode, FR32, f32mem, Is2Addr>, XS;
2853   defm SD : sse12_fp_scalar<opc, !strconcat(OpcodeStr, "sd"),
2854                             OpNode, FR64, f64mem, Is2Addr>, XD;
2855 }
2856
2857 multiclass basic_sse12_fp_binop_p<bits<8> opc, string OpcodeStr, SDNode OpNode,
2858                                    bit Is2Addr = 1> {
2859   let mayLoad = 0 in {
2860   defm PS : sse12_fp_packed<opc, !strconcat(OpcodeStr, "ps"), OpNode, VR128,
2861               v4f32, f128mem, memopv4f32, SSEPackedSingle, Is2Addr>, TB;
2862   defm PD : sse12_fp_packed<opc, !strconcat(OpcodeStr, "pd"), OpNode, VR128,
2863               v2f64, f128mem, memopv2f64, SSEPackedDouble, Is2Addr>, TB, OpSize;
2864   }
2865 }
2866
2867 multiclass basic_sse12_fp_binop_p_y<bits<8> opc, string OpcodeStr,
2868                                     SDNode OpNode> {
2869   let mayLoad = 0 in {
2870     defm PSY : sse12_fp_packed<opc, !strconcat(OpcodeStr, "ps"), OpNode, VR256,
2871                 v8f32, f256mem, memopv8f32, SSEPackedSingle, 0>, TB;
2872     defm PDY : sse12_fp_packed<opc, !strconcat(OpcodeStr, "pd"), OpNode, VR256,
2873                 v4f64, f256mem, memopv4f64, SSEPackedDouble, 0>, TB, OpSize;
2874   }
2875 }
2876
2877 multiclass basic_sse12_fp_binop_s_int<bits<8> opc, string OpcodeStr,
2878                                       bit Is2Addr = 1> {
2879   defm SS : sse12_fp_scalar_int<opc, OpcodeStr, VR128,
2880      !strconcat(OpcodeStr, "ss"), "", "_ss", ssmem, sse_load_f32, Is2Addr>, XS;
2881   defm SD : sse12_fp_scalar_int<opc, OpcodeStr, VR128,
2882      !strconcat(OpcodeStr, "sd"), "2", "_sd", sdmem, sse_load_f64, Is2Addr>, XD;
2883 }
2884
2885 multiclass basic_sse12_fp_binop_p_int<bits<8> opc, string OpcodeStr,
2886                                       bit Is2Addr = 1> {
2887   defm PS : sse12_fp_packed_int<opc, OpcodeStr, VR128,
2888      !strconcat(OpcodeStr, "ps"), "sse", "_ps", f128mem, memopv4f32,
2889                                               SSEPackedSingle, Is2Addr>, TB;
2890
2891   defm PD : sse12_fp_packed_int<opc, OpcodeStr, VR128,
2892      !strconcat(OpcodeStr, "pd"), "sse2", "_pd", f128mem, memopv2f64,
2893                                       SSEPackedDouble, Is2Addr>, TB, OpSize;
2894 }
2895
2896 multiclass basic_sse12_fp_binop_p_y_int<bits<8> opc, string OpcodeStr> {
2897   defm PSY : sse12_fp_packed_int<opc, OpcodeStr, VR256,
2898      !strconcat(OpcodeStr, "ps"), "avx", "_ps_256", f256mem, memopv8f32,
2899       SSEPackedSingle, 0>, TB;
2900
2901   defm PDY : sse12_fp_packed_int<opc, OpcodeStr, VR256,
2902      !strconcat(OpcodeStr, "pd"), "avx", "_pd_256", f256mem, memopv4f64,
2903       SSEPackedDouble, 0>, TB, OpSize;
2904 }
2905
2906 // Binary Arithmetic instructions
2907 defm VADD : basic_sse12_fp_binop_s<0x58, "add", fadd, 0>,
2908             basic_sse12_fp_binop_s_int<0x58, "add", 0>, VEX_4V, VEX_LIG;
2909 defm VADD : basic_sse12_fp_binop_p<0x58, "add", fadd, 0>,
2910             basic_sse12_fp_binop_p_y<0x58, "add", fadd>, VEX_4V;
2911 defm VMUL : basic_sse12_fp_binop_s<0x59, "mul", fmul, 0>,
2912             basic_sse12_fp_binop_s_int<0x59, "mul", 0>, VEX_4V, VEX_LIG;
2913 defm VMUL : basic_sse12_fp_binop_p<0x59, "mul", fmul, 0>,
2914             basic_sse12_fp_binop_p_y<0x59, "mul", fmul>, VEX_4V;
2915
2916 let isCommutable = 0 in {
2917   defm VSUB : basic_sse12_fp_binop_s<0x5C, "sub", fsub, 0>,
2918               basic_sse12_fp_binop_s_int<0x5C, "sub", 0>, VEX_4V, VEX_LIG;
2919   defm VSUB : basic_sse12_fp_binop_p<0x5C, "sub", fsub, 0>,
2920               basic_sse12_fp_binop_p_y<0x5C, "sub", fsub>, VEX_4V;
2921   defm VDIV : basic_sse12_fp_binop_s<0x5E, "div", fdiv, 0>,
2922               basic_sse12_fp_binop_s_int<0x5E, "div", 0>, VEX_4V, VEX_LIG;
2923   defm VDIV : basic_sse12_fp_binop_p<0x5E, "div", fdiv, 0>,
2924               basic_sse12_fp_binop_p_y<0x5E, "div", fdiv>, VEX_4V;
2925   defm VMAX : basic_sse12_fp_binop_s<0x5F, "max", X86fmax, 0>,
2926               basic_sse12_fp_binop_s_int<0x5F, "max", 0>, VEX_4V, VEX_LIG;
2927   defm VMAX : basic_sse12_fp_binop_p<0x5F, "max", X86fmax, 0>,
2928               basic_sse12_fp_binop_p_int<0x5F, "max", 0>,
2929               basic_sse12_fp_binop_p_y<0x5F, "max", X86fmax>,
2930               basic_sse12_fp_binop_p_y_int<0x5F, "max">, VEX_4V;
2931   defm VMIN : basic_sse12_fp_binop_s<0x5D, "min", X86fmin, 0>,
2932               basic_sse12_fp_binop_s_int<0x5D, "min", 0>, VEX_4V, VEX_LIG;
2933   defm VMIN : basic_sse12_fp_binop_p<0x5D, "min", X86fmin, 0>,
2934               basic_sse12_fp_binop_p_int<0x5D, "min", 0>,
2935               basic_sse12_fp_binop_p_y_int<0x5D, "min">,
2936               basic_sse12_fp_binop_p_y<0x5D, "min", X86fmin>, VEX_4V;
2937 }
2938
2939 let Constraints = "$src1 = $dst" in {
2940   defm ADD : basic_sse12_fp_binop_s<0x58, "add", fadd>,
2941              basic_sse12_fp_binop_p<0x58, "add", fadd>,
2942              basic_sse12_fp_binop_s_int<0x58, "add">;
2943   defm MUL : basic_sse12_fp_binop_s<0x59, "mul", fmul>,
2944              basic_sse12_fp_binop_p<0x59, "mul", fmul>,
2945              basic_sse12_fp_binop_s_int<0x59, "mul">;
2946
2947   let isCommutable = 0 in {
2948     defm SUB : basic_sse12_fp_binop_s<0x5C, "sub", fsub>,
2949                basic_sse12_fp_binop_p<0x5C, "sub", fsub>,
2950                basic_sse12_fp_binop_s_int<0x5C, "sub">;
2951     defm DIV : basic_sse12_fp_binop_s<0x5E, "div", fdiv>,
2952                basic_sse12_fp_binop_p<0x5E, "div", fdiv>,
2953                basic_sse12_fp_binop_s_int<0x5E, "div">;
2954     defm MAX : basic_sse12_fp_binop_s<0x5F, "max", X86fmax>,
2955                basic_sse12_fp_binop_p<0x5F, "max", X86fmax>,
2956                basic_sse12_fp_binop_s_int<0x5F, "max">,
2957                basic_sse12_fp_binop_p_int<0x5F, "max">;
2958     defm MIN : basic_sse12_fp_binop_s<0x5D, "min", X86fmin>,
2959                basic_sse12_fp_binop_p<0x5D, "min", X86fmin>,
2960                basic_sse12_fp_binop_s_int<0x5D, "min">,
2961                basic_sse12_fp_binop_p_int<0x5D, "min">;
2962   }
2963 }
2964
2965 /// Unop Arithmetic
2966 /// In addition, we also have a special variant of the scalar form here to
2967 /// represent the associated intrinsic operation.  This form is unlike the
2968 /// plain scalar form, in that it takes an entire vector (instead of a
2969 /// scalar) and leaves the top elements undefined.
2970 ///
2971 /// And, we have a special variant form for a full-vector intrinsic form.
2972
2973 /// sse1_fp_unop_s - SSE1 unops in scalar form.
2974 multiclass sse1_fp_unop_s<bits<8> opc, string OpcodeStr,
2975                           SDNode OpNode, Intrinsic F32Int> {
2976   def SSr : SSI<opc, MRMSrcReg, (outs FR32:$dst), (ins FR32:$src),
2977                 !strconcat(OpcodeStr, "ss\t{$src, $dst|$dst, $src}"),
2978                 [(set FR32:$dst, (OpNode FR32:$src))]>;
2979   // For scalar unary operations, fold a load into the operation
2980   // only in OptForSize mode. It eliminates an instruction, but it also
2981   // eliminates a whole-register clobber (the load), so it introduces a
2982   // partial register update condition.
2983   def SSm : I<opc, MRMSrcMem, (outs FR32:$dst), (ins f32mem:$src),
2984                 !strconcat(OpcodeStr, "ss\t{$src, $dst|$dst, $src}"),
2985                 [(set FR32:$dst, (OpNode (load addr:$src)))]>, XS,
2986             Requires<[HasSSE1, OptForSize]>;
2987   def SSr_Int : SSI<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2988                     !strconcat(OpcodeStr, "ss\t{$src, $dst|$dst, $src}"),
2989                     [(set VR128:$dst, (F32Int VR128:$src))]>;
2990   def SSm_Int : SSI<opc, MRMSrcMem, (outs VR128:$dst), (ins ssmem:$src),
2991                     !strconcat(OpcodeStr, "ss\t{$src, $dst|$dst, $src}"),
2992                     [(set VR128:$dst, (F32Int sse_load_f32:$src))]>;
2993 }
2994
2995 /// sse1_fp_unop_s_avx - AVX SSE1 unops in scalar form.
2996 multiclass sse1_fp_unop_s_avx<bits<8> opc, string OpcodeStr> {
2997   def SSr : SSI<opc, MRMSrcReg, (outs FR32:$dst), (ins FR32:$src1, FR32:$src2),
2998                 !strconcat(OpcodeStr,
2999                            "ss\t{$src2, $src1, $dst|$dst, $src1, $src2}"), []>;
3000   let mayLoad = 1 in
3001   def SSm : SSI<opc, MRMSrcMem, (outs FR32:$dst), (ins FR32:$src1,f32mem:$src2),
3002                 !strconcat(OpcodeStr,
3003                            "ss\t{$src2, $src1, $dst|$dst, $src1, $src2}"), []>;
3004   def SSm_Int : SSI<opc, MRMSrcMem, (outs VR128:$dst),
3005                 (ins VR128:$src1, ssmem:$src2),
3006                 !strconcat(OpcodeStr,
3007                            "ss\t{$src2, $src1, $dst|$dst, $src1, $src2}"), []>;
3008 }
3009
3010 /// sse1_fp_unop_p - SSE1 unops in packed form.
3011 multiclass sse1_fp_unop_p<bits<8> opc, string OpcodeStr, SDNode OpNode> {
3012   def PSr : PSI<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3013               !strconcat(OpcodeStr, "ps\t{$src, $dst|$dst, $src}"),
3014               [(set VR128:$dst, (v4f32 (OpNode VR128:$src)))]>;
3015   def PSm : PSI<opc, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
3016                 !strconcat(OpcodeStr, "ps\t{$src, $dst|$dst, $src}"),
3017                 [(set VR128:$dst, (OpNode (memopv4f32 addr:$src)))]>;
3018 }
3019
3020 /// sse1_fp_unop_p_y - AVX 256-bit SSE1 unops in packed form.
3021 multiclass sse1_fp_unop_p_y<bits<8> opc, string OpcodeStr, SDNode OpNode> {
3022   def PSYr : PSI<opc, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
3023               !strconcat(OpcodeStr, "ps\t{$src, $dst|$dst, $src}"),
3024               [(set VR256:$dst, (v8f32 (OpNode VR256:$src)))]>;
3025   def PSYm : PSI<opc, MRMSrcMem, (outs VR256:$dst), (ins f256mem:$src),
3026                 !strconcat(OpcodeStr, "ps\t{$src, $dst|$dst, $src}"),
3027                 [(set VR256:$dst, (OpNode (memopv8f32 addr:$src)))]>;
3028 }
3029
3030 /// sse1_fp_unop_p_int - SSE1 intrinsics unops in packed forms.
3031 multiclass sse1_fp_unop_p_int<bits<8> opc, string OpcodeStr,
3032                               Intrinsic V4F32Int> {
3033   def PSr_Int : PSI<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3034                     !strconcat(OpcodeStr, "ps\t{$src, $dst|$dst, $src}"),
3035                     [(set VR128:$dst, (V4F32Int VR128:$src))]>;
3036   def PSm_Int : PSI<opc, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
3037                     !strconcat(OpcodeStr, "ps\t{$src, $dst|$dst, $src}"),
3038                     [(set VR128:$dst, (V4F32Int (memopv4f32 addr:$src)))]>;
3039 }
3040
3041 /// sse1_fp_unop_p_y_int - AVX 256-bit intrinsics unops in packed forms.
3042 multiclass sse1_fp_unop_p_y_int<bits<8> opc, string OpcodeStr,
3043                                 Intrinsic V4F32Int> {
3044   def PSYr_Int : PSI<opc, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
3045                     !strconcat(OpcodeStr, "ps\t{$src, $dst|$dst, $src}"),
3046                     [(set VR256:$dst, (V4F32Int VR256:$src))]>;
3047   def PSYm_Int : PSI<opc, MRMSrcMem, (outs VR256:$dst), (ins f256mem:$src),
3048                     !strconcat(OpcodeStr, "ps\t{$src, $dst|$dst, $src}"),
3049                     [(set VR256:$dst, (V4F32Int (memopv8f32 addr:$src)))]>;
3050 }
3051
3052 /// sse2_fp_unop_s - SSE2 unops in scalar form.
3053 multiclass sse2_fp_unop_s<bits<8> opc, string OpcodeStr,
3054                           SDNode OpNode, Intrinsic F64Int> {
3055   def SDr : SDI<opc, MRMSrcReg, (outs FR64:$dst), (ins FR64:$src),
3056                 !strconcat(OpcodeStr, "sd\t{$src, $dst|$dst, $src}"),
3057                 [(set FR64:$dst, (OpNode FR64:$src))]>;
3058   // See the comments in sse1_fp_unop_s for why this is OptForSize.
3059   def SDm : I<opc, MRMSrcMem, (outs FR64:$dst), (ins f64mem:$src),
3060                 !strconcat(OpcodeStr, "sd\t{$src, $dst|$dst, $src}"),
3061                 [(set FR64:$dst, (OpNode (load addr:$src)))]>, XD,
3062             Requires<[HasSSE2, OptForSize]>;
3063   def SDr_Int : SDI<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3064                     !strconcat(OpcodeStr, "sd\t{$src, $dst|$dst, $src}"),
3065                     [(set VR128:$dst, (F64Int VR128:$src))]>;
3066   def SDm_Int : SDI<opc, MRMSrcMem, (outs VR128:$dst), (ins sdmem:$src),
3067                     !strconcat(OpcodeStr, "sd\t{$src, $dst|$dst, $src}"),
3068                     [(set VR128:$dst, (F64Int sse_load_f64:$src))]>;
3069 }
3070
3071 /// sse2_fp_unop_s_avx - AVX SSE2 unops in scalar form.
3072 multiclass sse2_fp_unop_s_avx<bits<8> opc, string OpcodeStr> {
3073   let neverHasSideEffects = 1 in {
3074   def SDr : SDI<opc, MRMSrcReg, (outs FR64:$dst), (ins FR64:$src1, FR64:$src2),
3075                !strconcat(OpcodeStr,
3076                           "sd\t{$src2, $src1, $dst|$dst, $src1, $src2}"), []>;
3077   let mayLoad = 1 in
3078   def SDm : SDI<opc, MRMSrcMem, (outs FR64:$dst), (ins FR64:$src1,f64mem:$src2),
3079                !strconcat(OpcodeStr,
3080                           "sd\t{$src2, $src1, $dst|$dst, $src1, $src2}"), []>;
3081   }
3082   def SDm_Int : SDI<opc, MRMSrcMem, (outs VR128:$dst),
3083                (ins VR128:$src1, sdmem:$src2),
3084                !strconcat(OpcodeStr,
3085                           "sd\t{$src2, $src1, $dst|$dst, $src1, $src2}"), []>;
3086 }
3087
3088 /// sse2_fp_unop_p - SSE2 unops in vector forms.
3089 multiclass sse2_fp_unop_p<bits<8> opc, string OpcodeStr,
3090                           SDNode OpNode> {
3091   def PDr : PDI<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3092               !strconcat(OpcodeStr, "pd\t{$src, $dst|$dst, $src}"),
3093               [(set VR128:$dst, (v2f64 (OpNode VR128:$src)))]>;
3094   def PDm : PDI<opc, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
3095                 !strconcat(OpcodeStr, "pd\t{$src, $dst|$dst, $src}"),
3096                 [(set VR128:$dst, (OpNode (memopv2f64 addr:$src)))]>;
3097 }
3098
3099 /// sse2_fp_unop_p_y - AVX SSE2 256-bit unops in vector forms.
3100 multiclass sse2_fp_unop_p_y<bits<8> opc, string OpcodeStr, SDNode OpNode> {
3101   def PDYr : PDI<opc, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
3102               !strconcat(OpcodeStr, "pd\t{$src, $dst|$dst, $src}"),
3103               [(set VR256:$dst, (v4f64 (OpNode VR256:$src)))]>;
3104   def PDYm : PDI<opc, MRMSrcMem, (outs VR256:$dst), (ins f256mem:$src),
3105                 !strconcat(OpcodeStr, "pd\t{$src, $dst|$dst, $src}"),
3106                 [(set VR256:$dst, (OpNode (memopv4f64 addr:$src)))]>;
3107 }
3108
3109 /// sse2_fp_unop_p_int - SSE2 intrinsic unops in vector forms.
3110 multiclass sse2_fp_unop_p_int<bits<8> opc, string OpcodeStr,
3111                               Intrinsic V2F64Int> {
3112   def PDr_Int : PDI<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3113                     !strconcat(OpcodeStr, "pd\t{$src, $dst|$dst, $src}"),
3114                     [(set VR128:$dst, (V2F64Int VR128:$src))]>;
3115   def PDm_Int : PDI<opc, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
3116                     !strconcat(OpcodeStr, "pd\t{$src, $dst|$dst, $src}"),
3117                     [(set VR128:$dst, (V2F64Int (memopv2f64 addr:$src)))]>;
3118 }
3119
3120 /// sse2_fp_unop_p_y_int - AVX 256-bit intrinsic unops in vector forms.
3121 multiclass sse2_fp_unop_p_y_int<bits<8> opc, string OpcodeStr,
3122                                 Intrinsic V2F64Int> {
3123   def PDYr_Int : PDI<opc, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
3124                     !strconcat(OpcodeStr, "pd\t{$src, $dst|$dst, $src}"),
3125                     [(set VR256:$dst, (V2F64Int VR256:$src))]>;
3126   def PDYm_Int : PDI<opc, MRMSrcMem, (outs VR256:$dst), (ins f256mem:$src),
3127                     !strconcat(OpcodeStr, "pd\t{$src, $dst|$dst, $src}"),
3128                     [(set VR256:$dst, (V2F64Int (memopv4f64 addr:$src)))]>;
3129 }
3130
3131 let Predicates = [HasAVX] in {
3132   // Square root.
3133   defm VSQRT  : sse1_fp_unop_s_avx<0x51, "vsqrt">,
3134                 sse2_fp_unop_s_avx<0x51, "vsqrt">, VEX_4V, VEX_LIG;
3135
3136   defm VSQRT  : sse1_fp_unop_p<0x51, "vsqrt", fsqrt>,
3137                 sse2_fp_unop_p<0x51, "vsqrt", fsqrt>,
3138                 sse1_fp_unop_p_y<0x51, "vsqrt", fsqrt>,
3139                 sse2_fp_unop_p_y<0x51, "vsqrt", fsqrt>,
3140                 sse1_fp_unop_p_int<0x51, "vsqrt", int_x86_sse_sqrt_ps>,
3141                 sse2_fp_unop_p_int<0x51, "vsqrt", int_x86_sse2_sqrt_pd>,
3142                 sse1_fp_unop_p_y_int<0x51, "vsqrt", int_x86_avx_sqrt_ps_256>,
3143                 sse2_fp_unop_p_y_int<0x51, "vsqrt", int_x86_avx_sqrt_pd_256>,
3144                 VEX;
3145
3146   // Reciprocal approximations. Note that these typically require refinement
3147   // in order to obtain suitable precision.
3148   defm VRSQRT : sse1_fp_unop_s_avx<0x52, "vrsqrt">, VEX_4V, VEX_LIG;
3149   defm VRSQRT : sse1_fp_unop_p<0x52, "vrsqrt", X86frsqrt>,
3150                 sse1_fp_unop_p_y<0x52, "vrsqrt", X86frsqrt>,
3151                 sse1_fp_unop_p_y_int<0x52, "vrsqrt", int_x86_avx_rsqrt_ps_256>,
3152                 sse1_fp_unop_p_int<0x52, "vrsqrt", int_x86_sse_rsqrt_ps>, VEX;
3153
3154   defm VRCP   : sse1_fp_unop_s_avx<0x53, "vrcp">, VEX_4V, VEX_LIG;
3155   defm VRCP   : sse1_fp_unop_p<0x53, "vrcp", X86frcp>,
3156                 sse1_fp_unop_p_y<0x53, "vrcp", X86frcp>,
3157                 sse1_fp_unop_p_y_int<0x53, "vrcp", int_x86_avx_rcp_ps_256>,
3158                 sse1_fp_unop_p_int<0x53, "vrcp", int_x86_sse_rcp_ps>, VEX;
3159 }
3160
3161 let AddedComplexity = 1 in {
3162 def : Pat<(f32 (fsqrt FR32:$src)),
3163           (VSQRTSSr (f32 (IMPLICIT_DEF)), FR32:$src)>, Requires<[HasAVX]>;
3164 def : Pat<(f32 (fsqrt (load addr:$src))),
3165           (VSQRTSSm (f32 (IMPLICIT_DEF)), addr:$src)>,
3166           Requires<[HasAVX, OptForSize]>;
3167 def : Pat<(f64 (fsqrt FR64:$src)),
3168           (VSQRTSDr (f64 (IMPLICIT_DEF)), FR64:$src)>, Requires<[HasAVX]>;
3169 def : Pat<(f64 (fsqrt (load addr:$src))),
3170           (VSQRTSDm (f64 (IMPLICIT_DEF)), addr:$src)>,
3171           Requires<[HasAVX, OptForSize]>;
3172
3173 def : Pat<(f32 (X86frsqrt FR32:$src)),
3174           (VRSQRTSSr (f32 (IMPLICIT_DEF)), FR32:$src)>, Requires<[HasAVX]>;
3175 def : Pat<(f32 (X86frsqrt (load addr:$src))),
3176           (VRSQRTSSm (f32 (IMPLICIT_DEF)), addr:$src)>,
3177           Requires<[HasAVX, OptForSize]>;
3178
3179 def : Pat<(f32 (X86frcp FR32:$src)),
3180           (VRCPSSr (f32 (IMPLICIT_DEF)), FR32:$src)>, Requires<[HasAVX]>;
3181 def : Pat<(f32 (X86frcp (load addr:$src))),
3182           (VRCPSSm (f32 (IMPLICIT_DEF)), addr:$src)>,
3183           Requires<[HasAVX, OptForSize]>;
3184 }
3185
3186 let Predicates = [HasAVX], AddedComplexity = 1 in {
3187   def : Pat<(int_x86_sse_sqrt_ss VR128:$src),
3188             (INSERT_SUBREG (v4f32 (IMPLICIT_DEF)),
3189                 (VSQRTSSr (f32 (IMPLICIT_DEF)),
3190                           (EXTRACT_SUBREG (v4f32 VR128:$src), sub_ss)),
3191                 sub_ss)>;
3192   def : Pat<(int_x86_sse_sqrt_ss sse_load_f32:$src),
3193             (VSQRTSSm_Int (v4f32 (IMPLICIT_DEF)), sse_load_f32:$src)>;
3194
3195   def : Pat<(int_x86_sse2_sqrt_sd VR128:$src),
3196             (INSERT_SUBREG (v2f64 (IMPLICIT_DEF)),
3197                 (VSQRTSDr (f64 (IMPLICIT_DEF)),
3198                           (EXTRACT_SUBREG (v2f64 VR128:$src), sub_sd)),
3199                 sub_sd)>;
3200   def : Pat<(int_x86_sse2_sqrt_sd sse_load_f64:$src),
3201             (VSQRTSDm_Int (v2f64 (IMPLICIT_DEF)), sse_load_f64:$src)>;
3202
3203   def : Pat<(int_x86_sse_rsqrt_ss VR128:$src),
3204             (INSERT_SUBREG (v4f32 (IMPLICIT_DEF)),
3205                 (VRSQRTSSr (f32 (IMPLICIT_DEF)),
3206                           (EXTRACT_SUBREG (v4f32 VR128:$src), sub_ss)),
3207                 sub_ss)>;
3208   def : Pat<(int_x86_sse_rsqrt_ss sse_load_f32:$src),
3209             (VRSQRTSSm_Int (v4f32 (IMPLICIT_DEF)), sse_load_f32:$src)>;
3210
3211   def : Pat<(int_x86_sse_rcp_ss VR128:$src),
3212             (INSERT_SUBREG (v4f32 (IMPLICIT_DEF)),
3213                 (VRCPSSr (f32 (IMPLICIT_DEF)),
3214                          (EXTRACT_SUBREG (v4f32 VR128:$src), sub_ss)),
3215                 sub_ss)>;
3216   def : Pat<(int_x86_sse_rcp_ss sse_load_f32:$src),
3217             (VRCPSSm_Int (v4f32 (IMPLICIT_DEF)), sse_load_f32:$src)>;
3218 }
3219
3220 // Square root.
3221 defm SQRT  : sse1_fp_unop_s<0x51, "sqrt",  fsqrt, int_x86_sse_sqrt_ss>,
3222              sse1_fp_unop_p<0x51, "sqrt",  fsqrt>,
3223              sse1_fp_unop_p_int<0x51, "sqrt",  int_x86_sse_sqrt_ps>,
3224              sse2_fp_unop_s<0x51, "sqrt",  fsqrt, int_x86_sse2_sqrt_sd>,
3225              sse2_fp_unop_p<0x51, "sqrt",  fsqrt>,
3226              sse2_fp_unop_p_int<0x51, "sqrt", int_x86_sse2_sqrt_pd>;
3227
3228 // Reciprocal approximations. Note that these typically require refinement
3229 // in order to obtain suitable precision.
3230 defm RSQRT : sse1_fp_unop_s<0x52, "rsqrt", X86frsqrt, int_x86_sse_rsqrt_ss>,
3231              sse1_fp_unop_p<0x52, "rsqrt", X86frsqrt>,
3232              sse1_fp_unop_p_int<0x52, "rsqrt", int_x86_sse_rsqrt_ps>;
3233 defm RCP   : sse1_fp_unop_s<0x53, "rcp", X86frcp, int_x86_sse_rcp_ss>,
3234              sse1_fp_unop_p<0x53, "rcp", X86frcp>,
3235              sse1_fp_unop_p_int<0x53, "rcp", int_x86_sse_rcp_ps>;
3236
3237 // There is no f64 version of the reciprocal approximation instructions.
3238
3239 //===----------------------------------------------------------------------===//
3240 // SSE 1 & 2 - Non-temporal stores
3241 //===----------------------------------------------------------------------===//
3242
3243 let AddedComplexity = 400 in { // Prefer non-temporal versions
3244   def VMOVNTPSmr : VPSI<0x2B, MRMDestMem, (outs),
3245                        (ins f128mem:$dst, VR128:$src),
3246                        "movntps\t{$src, $dst|$dst, $src}",
3247                        [(alignednontemporalstore (v4f32 VR128:$src),
3248                                                  addr:$dst)]>, VEX;
3249   def VMOVNTPDmr : VPDI<0x2B, MRMDestMem, (outs),
3250                        (ins f128mem:$dst, VR128:$src),
3251                        "movntpd\t{$src, $dst|$dst, $src}",
3252                        [(alignednontemporalstore (v2f64 VR128:$src),
3253                                                  addr:$dst)]>, VEX;
3254
3255   let ExeDomain = SSEPackedInt in
3256   def VMOVNTDQmr    : VPDI<0xE7, MRMDestMem, (outs),
3257                            (ins f128mem:$dst, VR128:$src),
3258                            "movntdq\t{$src, $dst|$dst, $src}",
3259                            [(alignednontemporalstore (v2i64 VR128:$src),
3260                                                      addr:$dst)]>, VEX;
3261
3262   def : Pat<(alignednontemporalstore (v2i64 VR128:$src), addr:$dst),
3263             (VMOVNTDQmr addr:$dst, VR128:$src)>, Requires<[HasAVX]>;
3264
3265   def VMOVNTPSYmr : VPSI<0x2B, MRMDestMem, (outs),
3266                        (ins f256mem:$dst, VR256:$src),
3267                        "movntps\t{$src, $dst|$dst, $src}",
3268                        [(alignednontemporalstore (v8f32 VR256:$src),
3269                                                  addr:$dst)]>, VEX;
3270   def VMOVNTPDYmr : VPDI<0x2B, MRMDestMem, (outs),
3271                        (ins f256mem:$dst, VR256:$src),
3272                        "movntpd\t{$src, $dst|$dst, $src}",
3273                        [(alignednontemporalstore (v4f64 VR256:$src),
3274                                                  addr:$dst)]>, VEX;
3275   let ExeDomain = SSEPackedInt in
3276   def VMOVNTDQYmr : VPDI<0xE7, MRMDestMem, (outs),
3277                       (ins f256mem:$dst, VR256:$src),
3278                       "movntdq\t{$src, $dst|$dst, $src}",
3279                       [(alignednontemporalstore (v4i64 VR256:$src),
3280                                                 addr:$dst)]>, VEX;
3281 }
3282
3283 def : Pat<(int_x86_avx_movnt_dq_256 addr:$dst, VR256:$src),
3284           (VMOVNTDQYmr addr:$dst, VR256:$src)>;
3285 def : Pat<(int_x86_avx_movnt_pd_256 addr:$dst, VR256:$src),
3286           (VMOVNTPDYmr addr:$dst, VR256:$src)>;
3287 def : Pat<(int_x86_avx_movnt_ps_256 addr:$dst, VR256:$src),
3288           (VMOVNTPSYmr addr:$dst, VR256:$src)>;
3289
3290 let AddedComplexity = 400 in { // Prefer non-temporal versions
3291 def MOVNTPSmr : PSI<0x2B, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
3292                     "movntps\t{$src, $dst|$dst, $src}",
3293                     [(alignednontemporalstore (v4f32 VR128:$src), addr:$dst)]>;
3294 def MOVNTPDmr : PDI<0x2B, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
3295                     "movntpd\t{$src, $dst|$dst, $src}",
3296                     [(alignednontemporalstore(v2f64 VR128:$src), addr:$dst)]>;
3297
3298 let ExeDomain = SSEPackedInt in
3299 def MOVNTDQmr : PDI<0xE7, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
3300                     "movntdq\t{$src, $dst|$dst, $src}",
3301                     [(alignednontemporalstore (v2i64 VR128:$src), addr:$dst)]>;
3302
3303 def : Pat<(alignednontemporalstore (v2i64 VR128:$src), addr:$dst),
3304           (MOVNTDQmr addr:$dst, VR128:$src)>, Requires<[HasSSE2]>;
3305
3306 // There is no AVX form for instructions below this point
3307 def MOVNTImr : I<0xC3, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
3308                  "movnti{l}\t{$src, $dst|$dst, $src}",
3309                  [(nontemporalstore (i32 GR32:$src), addr:$dst)]>,
3310                TB, Requires<[HasSSE2]>;
3311 def MOVNTI_64mr : RI<0xC3, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
3312                      "movnti{q}\t{$src, $dst|$dst, $src}",
3313                      [(nontemporalstore (i64 GR64:$src), addr:$dst)]>,
3314                   TB, Requires<[HasSSE2]>;
3315 }
3316
3317 //===----------------------------------------------------------------------===//
3318 // SSE 1 & 2 - Prefetch and memory fence
3319 //===----------------------------------------------------------------------===//
3320
3321 // Prefetch intrinsic.
3322 let Predicates = [HasSSE1] in {
3323 def PREFETCHT0   : I<0x18, MRM1m, (outs), (ins i8mem:$src),
3324     "prefetcht0\t$src", [(prefetch addr:$src, imm, (i32 3), (i32 1))]>, TB;
3325 def PREFETCHT1   : I<0x18, MRM2m, (outs), (ins i8mem:$src),
3326     "prefetcht1\t$src", [(prefetch addr:$src, imm, (i32 2), (i32 1))]>, TB;
3327 def PREFETCHT2   : I<0x18, MRM3m, (outs), (ins i8mem:$src),
3328     "prefetcht2\t$src", [(prefetch addr:$src, imm, (i32 1), (i32 1))]>, TB;
3329 def PREFETCHNTA  : I<0x18, MRM0m, (outs), (ins i8mem:$src),
3330     "prefetchnta\t$src", [(prefetch addr:$src, imm, (i32 0), (i32 1))]>, TB;
3331 }
3332
3333 // Flush cache
3334 def CLFLUSH : I<0xAE, MRM7m, (outs), (ins i8mem:$src),
3335                "clflush\t$src", [(int_x86_sse2_clflush addr:$src)]>,
3336               TB, Requires<[HasSSE2]>;
3337
3338 // Pause. This "instruction" is encoded as "rep; nop", so even though it
3339 // was introduced with SSE2, it's backward compatible.
3340 def PAUSE : I<0x90, RawFrm, (outs), (ins), "pause", []>, REP;
3341
3342 // Load, store, and memory fence
3343 def SFENCE : I<0xAE, MRM_F8, (outs), (ins),
3344                "sfence", [(int_x86_sse_sfence)]>, TB, Requires<[HasSSE1]>;
3345 def LFENCE : I<0xAE, MRM_E8, (outs), (ins),
3346                "lfence", [(int_x86_sse2_lfence)]>, TB, Requires<[HasSSE2]>;
3347 def MFENCE : I<0xAE, MRM_F0, (outs), (ins),
3348                "mfence", [(int_x86_sse2_mfence)]>, TB, Requires<[HasSSE2]>;
3349
3350 def : Pat<(X86SFence), (SFENCE)>;
3351 def : Pat<(X86LFence), (LFENCE)>;
3352 def : Pat<(X86MFence), (MFENCE)>;
3353
3354 //===----------------------------------------------------------------------===//
3355 // SSE 1 & 2 - Load/Store XCSR register
3356 //===----------------------------------------------------------------------===//
3357
3358 def VLDMXCSR : VPSI<0xAE, MRM2m, (outs), (ins i32mem:$src),
3359                   "ldmxcsr\t$src", [(int_x86_sse_ldmxcsr addr:$src)]>, VEX;
3360 def VSTMXCSR : VPSI<0xAE, MRM3m, (outs), (ins i32mem:$dst),
3361                   "stmxcsr\t$dst", [(int_x86_sse_stmxcsr addr:$dst)]>, VEX;
3362
3363 def LDMXCSR : PSI<0xAE, MRM2m, (outs), (ins i32mem:$src),
3364                   "ldmxcsr\t$src", [(int_x86_sse_ldmxcsr addr:$src)]>;
3365 def STMXCSR : PSI<0xAE, MRM3m, (outs), (ins i32mem:$dst),
3366                   "stmxcsr\t$dst", [(int_x86_sse_stmxcsr addr:$dst)]>;
3367
3368 //===---------------------------------------------------------------------===//
3369 // SSE2 - Move Aligned/Unaligned Packed Integer Instructions
3370 //===---------------------------------------------------------------------===//
3371
3372 let ExeDomain = SSEPackedInt in { // SSE integer instructions
3373
3374 let neverHasSideEffects = 1 in {
3375 def VMOVDQArr  : VPDI<0x6F, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3376                     "movdqa\t{$src, $dst|$dst, $src}", []>, VEX;
3377 def VMOVDQAYrr : VPDI<0x6F, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
3378                     "movdqa\t{$src, $dst|$dst, $src}", []>, VEX;
3379 }
3380 def VMOVDQUrr  : VSSI<0x6F, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3381                     "movdqu\t{$src, $dst|$dst, $src}", []>, VEX;
3382 def VMOVDQUYrr : VSSI<0x6F, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
3383                     "movdqu\t{$src, $dst|$dst, $src}", []>, VEX;
3384
3385 // For Disassembler
3386 let isCodeGenOnly = 1 in {
3387 def VMOVDQArr_REV  : VPDI<0x7F, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
3388                         "movdqa\t{$src, $dst|$dst, $src}", []>, VEX;
3389 def VMOVDQAYrr_REV : VPDI<0x7F, MRMDestReg, (outs VR256:$dst), (ins VR256:$src),
3390                         "movdqa\t{$src, $dst|$dst, $src}", []>, VEX;
3391 def VMOVDQUrr_REV  : VSSI<0x7F, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
3392                         "movdqu\t{$src, $dst|$dst, $src}", []>, VEX;
3393 def VMOVDQUYrr_REV : VSSI<0x7F, MRMDestReg, (outs VR256:$dst), (ins VR256:$src),
3394                         "movdqu\t{$src, $dst|$dst, $src}", []>, VEX;
3395 }
3396
3397 let canFoldAsLoad = 1, mayLoad = 1 in {
3398 def VMOVDQArm  : VPDI<0x6F, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
3399                    "movdqa\t{$src, $dst|$dst, $src}", []>, VEX;
3400 def VMOVDQAYrm : VPDI<0x6F, MRMSrcMem, (outs VR256:$dst), (ins i256mem:$src),
3401                    "movdqa\t{$src, $dst|$dst, $src}", []>, VEX;
3402 let Predicates = [HasAVX] in {
3403   def VMOVDQUrm  : I<0x6F, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
3404                     "vmovdqu\t{$src, $dst|$dst, $src}",[]>, XS, VEX;
3405   def VMOVDQUYrm : I<0x6F, MRMSrcMem, (outs VR256:$dst), (ins i256mem:$src),
3406                     "vmovdqu\t{$src, $dst|$dst, $src}",[]>, XS, VEX;
3407 }
3408 }
3409
3410 let mayStore = 1 in {
3411 def VMOVDQAmr  : VPDI<0x7F, MRMDestMem, (outs),
3412                      (ins i128mem:$dst, VR128:$src),
3413                      "movdqa\t{$src, $dst|$dst, $src}", []>, VEX;
3414 def VMOVDQAYmr : VPDI<0x7F, MRMDestMem, (outs),
3415                      (ins i256mem:$dst, VR256:$src),
3416                      "movdqa\t{$src, $dst|$dst, $src}", []>, VEX;
3417 let Predicates = [HasAVX] in {
3418 def VMOVDQUmr  : I<0x7F, MRMDestMem, (outs), (ins i128mem:$dst, VR128:$src),
3419                   "vmovdqu\t{$src, $dst|$dst, $src}",[]>, XS, VEX;
3420 def VMOVDQUYmr : I<0x7F, MRMDestMem, (outs), (ins i256mem:$dst, VR256:$src),
3421                   "vmovdqu\t{$src, $dst|$dst, $src}",[]>, XS, VEX;
3422 }
3423 }
3424
3425 let neverHasSideEffects = 1 in
3426 def MOVDQArr : PDI<0x6F, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3427                    "movdqa\t{$src, $dst|$dst, $src}", []>;
3428
3429 def MOVDQUrr :   I<0x6F, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3430                    "movdqu\t{$src, $dst|$dst, $src}",
3431                    []>, XS, Requires<[HasSSE2]>;
3432
3433 // For Disassembler
3434 let isCodeGenOnly = 1 in {
3435 def MOVDQArr_REV : PDI<0x7F, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
3436                        "movdqa\t{$src, $dst|$dst, $src}", []>;
3437
3438 def MOVDQUrr_REV :   I<0x7F, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
3439                        "movdqu\t{$src, $dst|$dst, $src}",
3440                        []>, XS, Requires<[HasSSE2]>;
3441 }
3442
3443 let canFoldAsLoad = 1, mayLoad = 1 in {
3444 def MOVDQArm : PDI<0x6F, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
3445                    "movdqa\t{$src, $dst|$dst, $src}",
3446                    [/*(set VR128:$dst, (alignedloadv2i64 addr:$src))*/]>;
3447 def MOVDQUrm :   I<0x6F, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
3448                    "movdqu\t{$src, $dst|$dst, $src}",
3449                    [/*(set VR128:$dst, (loadv2i64 addr:$src))*/]>,
3450                  XS, Requires<[HasSSE2]>;
3451 }
3452
3453 let mayStore = 1 in {
3454 def MOVDQAmr : PDI<0x7F, MRMDestMem, (outs), (ins i128mem:$dst, VR128:$src),
3455                    "movdqa\t{$src, $dst|$dst, $src}",
3456                    [/*(alignedstore (v2i64 VR128:$src), addr:$dst)*/]>;
3457 def MOVDQUmr :   I<0x7F, MRMDestMem, (outs), (ins i128mem:$dst, VR128:$src),
3458                    "movdqu\t{$src, $dst|$dst, $src}",
3459                    [/*(store (v2i64 VR128:$src), addr:$dst)*/]>,
3460                  XS, Requires<[HasSSE2]>;
3461 }
3462
3463 // Intrinsic forms of MOVDQU load and store
3464 def VMOVDQUmr_Int : I<0x7F, MRMDestMem, (outs), (ins i128mem:$dst, VR128:$src),
3465                        "vmovdqu\t{$src, $dst|$dst, $src}",
3466                        [(int_x86_sse2_storeu_dq addr:$dst, VR128:$src)]>,
3467                      XS, VEX, Requires<[HasAVX]>;
3468
3469 def MOVDQUmr_Int :   I<0x7F, MRMDestMem, (outs), (ins i128mem:$dst, VR128:$src),
3470                        "movdqu\t{$src, $dst|$dst, $src}",
3471                        [(int_x86_sse2_storeu_dq addr:$dst, VR128:$src)]>,
3472                      XS, Requires<[HasSSE2]>;
3473
3474 } // ExeDomain = SSEPackedInt
3475
3476 let Predicates = [HasAVX] in {
3477   def : Pat<(int_x86_avx_storeu_dq_256 addr:$dst, VR256:$src),
3478             (VMOVDQUYmr addr:$dst, VR256:$src)>;
3479 }
3480
3481 //===---------------------------------------------------------------------===//
3482 // SSE2 - Packed Integer Arithmetic Instructions
3483 //===---------------------------------------------------------------------===//
3484
3485 let ExeDomain = SSEPackedInt in { // SSE integer instructions
3486
3487 multiclass PDI_binop_rm_int<bits<8> opc, string OpcodeStr, Intrinsic IntId,
3488                             RegisterClass RC, PatFrag memop_frag,
3489                             X86MemOperand x86memop, bit IsCommutable = 0,
3490                             bit Is2Addr = 1> {
3491   let isCommutable = IsCommutable in
3492   def rr : PDI<opc, MRMSrcReg, (outs RC:$dst),
3493        (ins RC:$src1, RC:$src2),
3494        !if(Is2Addr,
3495            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
3496            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
3497        [(set RC:$dst, (IntId RC:$src1, RC:$src2))]>;
3498   def rm : PDI<opc, MRMSrcMem, (outs RC:$dst),
3499        (ins RC:$src1, x86memop:$src2),
3500        !if(Is2Addr,
3501            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
3502            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
3503        [(set RC:$dst, (IntId RC:$src1, (bitconvert (memop_frag addr:$src2))))]>;
3504 }
3505
3506 multiclass PDI_binop_rmi<bits<8> opc, bits<8> opc2, Format ImmForm,
3507                          string OpcodeStr, SDNode OpNode,
3508                          SDNode OpNode2, RegisterClass RC,
3509                          ValueType DstVT, ValueType SrcVT, PatFrag bc_frag,
3510                          bit Is2Addr = 1> {
3511   // src2 is always 128-bit
3512   def rr : PDI<opc, MRMSrcReg, (outs RC:$dst),
3513        (ins RC:$src1, VR128:$src2),
3514        !if(Is2Addr,
3515            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
3516            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
3517        [(set RC:$dst, (DstVT (OpNode RC:$src1, (SrcVT VR128:$src2))))]>;
3518   def rm : PDI<opc, MRMSrcMem, (outs RC:$dst),
3519        (ins RC:$src1, i128mem:$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, (DstVT (OpNode RC:$src1,
3524                        (bc_frag (memopv2i64 addr:$src2)))))]>;
3525   def ri : PDIi8<opc2, ImmForm, (outs RC:$dst),
3526        (ins RC:$src1, i32i8imm:$src2),
3527        !if(Is2Addr,
3528            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
3529            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
3530        [(set RC:$dst, (DstVT (OpNode2 RC:$src1, (i32 imm:$src2))))]>;
3531 }
3532
3533 /// PDI_binop_rm - Simple SSE2 binary operator with different src and dst types
3534 multiclass PDI_binop_rm2<bits<8> opc, string OpcodeStr, SDNode OpNode,
3535                          ValueType DstVT, ValueType SrcVT, RegisterClass RC,
3536                          PatFrag memop_frag, X86MemOperand x86memop,
3537                          bit IsCommutable = 0, bit Is2Addr = 1> {
3538   let isCommutable = IsCommutable in
3539   def rr : PDI<opc, MRMSrcReg, (outs RC:$dst),
3540        (ins RC:$src1, RC:$src2),
3541        !if(Is2Addr,
3542            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
3543            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
3544        [(set RC:$dst, (DstVT (OpNode (SrcVT RC:$src1), RC:$src2)))]>;
3545   def rm : PDI<opc, MRMSrcMem, (outs RC:$dst),
3546        (ins RC:$src1, x86memop:$src2),
3547        !if(Is2Addr,
3548            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
3549            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
3550        [(set RC:$dst, (DstVT (OpNode (SrcVT RC:$src1),
3551                                      (bitconvert (memop_frag addr:$src2)))))]>;
3552 }
3553 } // ExeDomain = SSEPackedInt
3554
3555 // 128-bit Integer Arithmetic
3556
3557 let Predicates = [HasAVX] in {
3558 defm VPADDB  : PDI_binop_rm<0xFC, "vpaddb", add, v16i8, VR128, memopv2i64,
3559                             i128mem, 1, 0 /*3addr*/>, VEX_4V;
3560 defm VPADDW  : PDI_binop_rm<0xFD, "vpaddw", add, v8i16, VR128, memopv2i64,
3561                             i128mem, 1, 0>, VEX_4V;
3562 defm VPADDD  : PDI_binop_rm<0xFE, "vpaddd", add, v4i32, VR128, memopv2i64,
3563                             i128mem, 1, 0>, VEX_4V;
3564 defm VPADDQ  : PDI_binop_rm<0xD4, "vpaddq", add, v2i64, VR128, memopv2i64,
3565                             i128mem, 1, 0>, VEX_4V;
3566 defm VPMULLW : PDI_binop_rm<0xD5, "vpmullw", mul, v8i16, VR128, memopv2i64,
3567                             i128mem, 1, 0>, VEX_4V;
3568 defm VPSUBB : PDI_binop_rm<0xF8, "vpsubb", sub, v16i8, VR128, memopv2i64,
3569                             i128mem, 0, 0>, VEX_4V;
3570 defm VPSUBW : PDI_binop_rm<0xF9, "vpsubw", sub, v8i16, VR128, memopv2i64,
3571                             i128mem, 0, 0>, VEX_4V;
3572 defm VPSUBD : PDI_binop_rm<0xFA, "vpsubd", sub, v4i32, VR128, memopv2i64,
3573                             i128mem, 0, 0>, VEX_4V;
3574 defm VPSUBQ : PDI_binop_rm<0xFB, "vpsubq", sub, v2i64, VR128, memopv2i64,
3575                             i128mem, 0, 0>, VEX_4V;
3576 defm VPMULUDQ : PDI_binop_rm2<0xF4, "vpmuludq", X86pmuludq, v2i64, v4i32, VR128,
3577                               memopv2i64, i128mem, 1, 0>, VEX_4V;
3578
3579 // Intrinsic forms
3580 defm VPSUBSB  : PDI_binop_rm_int<0xE8, "vpsubsb" , int_x86_sse2_psubs_b,
3581                                  VR128, memopv2i64, i128mem, 0, 0>, VEX_4V;
3582 defm VPSUBSW  : PDI_binop_rm_int<0xE9, "vpsubsw" , int_x86_sse2_psubs_w,
3583                                  VR128, memopv2i64, i128mem, 0, 0>, VEX_4V;
3584 defm VPSUBUSB : PDI_binop_rm_int<0xD8, "vpsubusb", int_x86_sse2_psubus_b,
3585                                  VR128, memopv2i64, i128mem, 0, 0>, VEX_4V;
3586 defm VPSUBUSW : PDI_binop_rm_int<0xD9, "vpsubusw", int_x86_sse2_psubus_w,
3587                                  VR128, memopv2i64, i128mem, 0, 0>, VEX_4V;
3588 defm VPADDSB  : PDI_binop_rm_int<0xEC, "vpaddsb" , int_x86_sse2_padds_b,
3589                                  VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3590 defm VPADDSW  : PDI_binop_rm_int<0xED, "vpaddsw" , int_x86_sse2_padds_w,
3591                                  VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3592 defm VPADDUSB : PDI_binop_rm_int<0xDC, "vpaddusb", int_x86_sse2_paddus_b,
3593                                  VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3594 defm VPADDUSW : PDI_binop_rm_int<0xDD, "vpaddusw", int_x86_sse2_paddus_w,
3595                                  VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3596 defm VPMULHUW : PDI_binop_rm_int<0xE4, "vpmulhuw", int_x86_sse2_pmulhu_w,
3597                                  VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3598 defm VPMULHW  : PDI_binop_rm_int<0xE5, "vpmulhw" , int_x86_sse2_pmulh_w,
3599                                  VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3600 defm VPMADDWD : PDI_binop_rm_int<0xF5, "vpmaddwd", int_x86_sse2_pmadd_wd,
3601                                  VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3602 defm VPAVGB   : PDI_binop_rm_int<0xE0, "vpavgb", int_x86_sse2_pavg_b,
3603                                  VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3604 defm VPAVGW   : PDI_binop_rm_int<0xE3, "vpavgw", int_x86_sse2_pavg_w,
3605                                  VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3606 defm VPMINUB  : PDI_binop_rm_int<0xDA, "vpminub", int_x86_sse2_pminu_b,
3607                                  VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3608 defm VPMINSW  : PDI_binop_rm_int<0xEA, "vpminsw", int_x86_sse2_pmins_w,
3609                                  VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3610 defm VPMAXUB  : PDI_binop_rm_int<0xDE, "vpmaxub", int_x86_sse2_pmaxu_b,
3611                                  VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3612 defm VPMAXSW  : PDI_binop_rm_int<0xEE, "vpmaxsw", int_x86_sse2_pmaxs_w,
3613                                  VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3614 defm VPSADBW  : PDI_binop_rm_int<0xF6, "vpsadbw", int_x86_sse2_psad_bw,
3615                                  VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3616 }
3617
3618 let Predicates = [HasAVX2] in {
3619 defm VPADDBY  : PDI_binop_rm<0xFC, "vpaddb", add, v32i8, VR256, memopv4i64,
3620                              i256mem, 1, 0>, VEX_4V;
3621 defm VPADDWY  : PDI_binop_rm<0xFD, "vpaddw", add, v16i16, VR256, memopv4i64,
3622                              i256mem, 1, 0>, VEX_4V;
3623 defm VPADDDY  : PDI_binop_rm<0xFE, "vpaddd", add, v8i32, VR256, memopv4i64,
3624                              i256mem, 1, 0>, VEX_4V;
3625 defm VPADDQY  : PDI_binop_rm<0xD4, "vpaddq", add, v4i64, VR256, memopv4i64,
3626                              i256mem, 1, 0>, VEX_4V;
3627 defm VPMULLWY : PDI_binop_rm<0xD5, "vpmullw", mul, v16i16, VR256, memopv4i64,
3628                              i256mem, 1, 0>, VEX_4V;
3629 defm VPSUBBY  : PDI_binop_rm<0xF8, "vpsubb", sub, v32i8, VR256, memopv4i64,
3630                              i256mem, 0, 0>, VEX_4V;
3631 defm VPSUBWY  : PDI_binop_rm<0xF9, "vpsubw", sub, v16i16,VR256, memopv4i64,
3632                              i256mem, 0, 0>, VEX_4V;
3633 defm VPSUBDY  : PDI_binop_rm<0xFA, "vpsubd", sub, v8i32, VR256, memopv4i64,
3634                              i256mem, 0, 0>, VEX_4V;
3635 defm VPSUBQY  : PDI_binop_rm<0xFB, "vpsubq", sub, v4i64, VR256, memopv4i64,
3636                              i256mem, 0, 0>, VEX_4V;
3637 defm VPMULUDQY : PDI_binop_rm2<0xF4, "vpmuludq", X86pmuludq, v4i64, v8i32,
3638                                VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3639
3640 // Intrinsic forms
3641 defm VPSUBSBY  : PDI_binop_rm_int<0xE8, "vpsubsb" , int_x86_avx2_psubs_b,
3642                                   VR256, memopv4i64, i256mem, 0, 0>, VEX_4V;
3643 defm VPSUBSWY  : PDI_binop_rm_int<0xE9, "vpsubsw" , int_x86_avx2_psubs_w,
3644                                   VR256, memopv4i64, i256mem, 0, 0>, VEX_4V;
3645 defm VPSUBUSBY : PDI_binop_rm_int<0xD8, "vpsubusb", int_x86_avx2_psubus_b,
3646                                   VR256, memopv4i64, i256mem, 0, 0>, VEX_4V;
3647 defm VPSUBUSWY : PDI_binop_rm_int<0xD9, "vpsubusw", int_x86_avx2_psubus_w,
3648                                   VR256, memopv4i64, i256mem, 0, 0>, VEX_4V;
3649 defm VPADDSBY  : PDI_binop_rm_int<0xEC, "vpaddsb" , int_x86_avx2_padds_b,
3650                                   VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3651 defm VPADDSWY  : PDI_binop_rm_int<0xED, "vpaddsw" , int_x86_avx2_padds_w,
3652                                   VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3653 defm VPADDUSBY : PDI_binop_rm_int<0xDC, "vpaddusb", int_x86_avx2_paddus_b,
3654                                   VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3655 defm VPADDUSWY : PDI_binop_rm_int<0xDD, "vpaddusw", int_x86_avx2_paddus_w,
3656                                   VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3657 defm VPMULHUWY : PDI_binop_rm_int<0xE4, "vpmulhuw", int_x86_avx2_pmulhu_w,
3658                                   VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3659 defm VPMULHWY  : PDI_binop_rm_int<0xE5, "vpmulhw" , int_x86_avx2_pmulh_w,
3660                                   VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3661 defm VPMADDWDY : PDI_binop_rm_int<0xF5, "vpmaddwd", int_x86_avx2_pmadd_wd,
3662                                   VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3663 defm VPAVGBY   : PDI_binop_rm_int<0xE0, "vpavgb", int_x86_avx2_pavg_b,
3664                                   VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3665 defm VPAVGWY   : PDI_binop_rm_int<0xE3, "vpavgw", int_x86_avx2_pavg_w,
3666                                   VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3667 defm VPMINUBY  : PDI_binop_rm_int<0xDA, "vpminub", int_x86_avx2_pminu_b,
3668                                   VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3669 defm VPMINSWY  : PDI_binop_rm_int<0xEA, "vpminsw", int_x86_avx2_pmins_w,
3670                                   VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3671 defm VPMAXUBY  : PDI_binop_rm_int<0xDE, "vpmaxub", int_x86_avx2_pmaxu_b,
3672                                   VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3673 defm VPMAXSWY  : PDI_binop_rm_int<0xEE, "vpmaxsw", int_x86_avx2_pmaxs_w,
3674                                   VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3675 defm VPSADBWY  : PDI_binop_rm_int<0xF6, "vpsadbw", int_x86_avx2_psad_bw,
3676                                   VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3677 }
3678
3679 let Constraints = "$src1 = $dst" in {
3680 defm PADDB  : PDI_binop_rm<0xFC, "paddb", add, v16i8, VR128, memopv2i64,
3681                            i128mem, 1>;
3682 defm PADDW  : PDI_binop_rm<0xFD, "paddw", add, v8i16, VR128, memopv2i64,
3683                            i128mem, 1>;
3684 defm PADDD  : PDI_binop_rm<0xFE, "paddd", add, v4i32, VR128, memopv2i64,
3685                            i128mem, 1>;
3686 defm PADDQ  : PDI_binop_rm<0xD4, "paddq", add, v2i64, VR128, memopv2i64,
3687                            i128mem, 1>;
3688 defm PMULLW : PDI_binop_rm<0xD5, "pmullw", mul, v8i16, VR128, memopv2i64,
3689                            i128mem, 1>;
3690 defm PSUBB : PDI_binop_rm<0xF8, "psubb", sub, v16i8, VR128, memopv2i64,
3691                           i128mem>;
3692 defm PSUBW : PDI_binop_rm<0xF9, "psubw", sub, v8i16, VR128, memopv2i64,
3693                           i128mem>;
3694 defm PSUBD : PDI_binop_rm<0xFA, "psubd", sub, v4i32, VR128, memopv2i64,
3695                           i128mem>;
3696 defm PSUBQ : PDI_binop_rm<0xFB, "psubq", sub, v2i64, VR128, memopv2i64,
3697                           i128mem>;
3698 defm PMULUDQ : PDI_binop_rm2<0xF4, "pmuludq", X86pmuludq, v2i64, v4i32, VR128,
3699                              memopv2i64, i128mem, 1>;
3700
3701 // Intrinsic forms
3702 defm PSUBSB  : PDI_binop_rm_int<0xE8, "psubsb" , int_x86_sse2_psubs_b,
3703                                 VR128, memopv2i64, i128mem>;
3704 defm PSUBSW  : PDI_binop_rm_int<0xE9, "psubsw" , int_x86_sse2_psubs_w,
3705                                 VR128, memopv2i64, i128mem>;
3706 defm PSUBUSB : PDI_binop_rm_int<0xD8, "psubusb", int_x86_sse2_psubus_b,
3707                                 VR128, memopv2i64, i128mem>;
3708 defm PSUBUSW : PDI_binop_rm_int<0xD9, "psubusw", int_x86_sse2_psubus_w,
3709                                 VR128, memopv2i64, i128mem>;
3710 defm PADDSB  : PDI_binop_rm_int<0xEC, "paddsb" , int_x86_sse2_padds_b,
3711                                 VR128, memopv2i64, i128mem, 1>;
3712 defm PADDSW  : PDI_binop_rm_int<0xED, "paddsw" , int_x86_sse2_padds_w,
3713                                 VR128, memopv2i64, i128mem, 1>;
3714 defm PADDUSB : PDI_binop_rm_int<0xDC, "paddusb", int_x86_sse2_paddus_b,
3715                                 VR128, memopv2i64, i128mem, 1>;
3716 defm PADDUSW : PDI_binop_rm_int<0xDD, "paddusw", int_x86_sse2_paddus_w,
3717                                 VR128, memopv2i64, i128mem, 1>;
3718 defm PMULHUW : PDI_binop_rm_int<0xE4, "pmulhuw", int_x86_sse2_pmulhu_w,
3719                                 VR128, memopv2i64, i128mem, 1>;
3720 defm PMULHW  : PDI_binop_rm_int<0xE5, "pmulhw" , int_x86_sse2_pmulh_w,
3721                                 VR128, memopv2i64, i128mem, 1>;
3722 defm PMADDWD : PDI_binop_rm_int<0xF5, "pmaddwd", int_x86_sse2_pmadd_wd,
3723                                 VR128, memopv2i64, i128mem, 1>;
3724 defm PAVGB   : PDI_binop_rm_int<0xE0, "pavgb", int_x86_sse2_pavg_b,
3725                                 VR128, memopv2i64, i128mem, 1>;
3726 defm PAVGW   : PDI_binop_rm_int<0xE3, "pavgw", int_x86_sse2_pavg_w,
3727                                 VR128, memopv2i64, i128mem, 1>;
3728 defm PMINUB  : PDI_binop_rm_int<0xDA, "pminub", int_x86_sse2_pminu_b,
3729                                 VR128, memopv2i64, i128mem, 1>;
3730 defm PMINSW  : PDI_binop_rm_int<0xEA, "pminsw", int_x86_sse2_pmins_w,
3731                                 VR128, memopv2i64, i128mem, 1>;
3732 defm PMAXUB  : PDI_binop_rm_int<0xDE, "pmaxub", int_x86_sse2_pmaxu_b,
3733                                 VR128, memopv2i64, i128mem, 1>;
3734 defm PMAXSW  : PDI_binop_rm_int<0xEE, "pmaxsw", int_x86_sse2_pmaxs_w,
3735                                 VR128, memopv2i64, i128mem, 1>;
3736 defm PSADBW  : PDI_binop_rm_int<0xF6, "psadbw", int_x86_sse2_psad_bw,
3737                                 VR128, memopv2i64, i128mem, 1>;
3738
3739 } // Constraints = "$src1 = $dst"
3740
3741 //===---------------------------------------------------------------------===//
3742 // SSE2 - Packed Integer Logical Instructions
3743 //===---------------------------------------------------------------------===//
3744
3745 let Predicates = [HasAVX] in {
3746 defm VPSLLW : PDI_binop_rmi<0xF1, 0x71, MRM6r, "vpsllw", X86vshl, X86vshli,
3747                             VR128, v8i16, v8i16, bc_v8i16, 0>, VEX_4V;
3748 defm VPSLLD : PDI_binop_rmi<0xF2, 0x72, MRM6r, "vpslld", X86vshl, X86vshli,
3749                             VR128, v4i32, v4i32, bc_v4i32, 0>, VEX_4V;
3750 defm VPSLLQ : PDI_binop_rmi<0xF3, 0x73, MRM6r, "vpsllq", X86vshl, X86vshli,
3751                             VR128, v2i64, v2i64, bc_v2i64, 0>, VEX_4V;
3752
3753 defm VPSRLW : PDI_binop_rmi<0xD1, 0x71, MRM2r, "vpsrlw", X86vsrl, X86vsrli,
3754                             VR128, v8i16, v8i16, bc_v8i16, 0>, VEX_4V;
3755 defm VPSRLD : PDI_binop_rmi<0xD2, 0x72, MRM2r, "vpsrld", X86vsrl, X86vsrli,
3756                             VR128, v4i32, v4i32, bc_v4i32, 0>, VEX_4V;
3757 defm VPSRLQ : PDI_binop_rmi<0xD3, 0x73, MRM2r, "vpsrlq", X86vsrl, X86vsrli,
3758                             VR128, v2i64, v2i64, bc_v2i64, 0>, VEX_4V;
3759
3760 defm VPSRAW : PDI_binop_rmi<0xE1, 0x71, MRM4r, "vpsraw", X86vsra, X86vsrai,
3761                             VR128, v8i16, v8i16, bc_v8i16, 0>, VEX_4V;
3762 defm VPSRAD : PDI_binop_rmi<0xE2, 0x72, MRM4r, "vpsrad", X86vsra, X86vsrai,
3763                             VR128, v4i32, v4i32, bc_v4i32, 0>, VEX_4V;
3764
3765 let ExeDomain = SSEPackedInt in {
3766   // 128-bit logical shifts.
3767   def VPSLLDQri : PDIi8<0x73, MRM7r,
3768                     (outs VR128:$dst), (ins VR128:$src1, i32i8imm:$src2),
3769                     "vpslldq\t{$src2, $src1, $dst|$dst, $src1, $src2}",
3770                     [(set VR128:$dst,
3771                       (int_x86_sse2_psll_dq_bs VR128:$src1, imm:$src2))]>,
3772                     VEX_4V;
3773   def VPSRLDQri : PDIi8<0x73, MRM3r,
3774                     (outs VR128:$dst), (ins VR128:$src1, i32i8imm:$src2),
3775                     "vpsrldq\t{$src2, $src1, $dst|$dst, $src1, $src2}",
3776                     [(set VR128:$dst,
3777                       (int_x86_sse2_psrl_dq_bs VR128:$src1, imm:$src2))]>,
3778                     VEX_4V;
3779   // PSRADQri doesn't exist in SSE[1-3].
3780 }
3781 } // Predicates = [HasAVX]
3782
3783 let Predicates = [HasAVX2] in {
3784 defm VPSLLWY : PDI_binop_rmi<0xF1, 0x71, MRM6r, "vpsllw", X86vshl, X86vshli,
3785                              VR256, v16i16, v8i16, bc_v8i16, 0>, VEX_4V;
3786 defm VPSLLDY : PDI_binop_rmi<0xF2, 0x72, MRM6r, "vpslld", X86vshl, X86vshli,
3787                              VR256, v8i32, v4i32, bc_v4i32, 0>, VEX_4V;
3788 defm VPSLLQY : PDI_binop_rmi<0xF3, 0x73, MRM6r, "vpsllq", X86vshl, X86vshli,
3789                              VR256, v4i64, v2i64, bc_v2i64, 0>, VEX_4V;
3790
3791 defm VPSRLWY : PDI_binop_rmi<0xD1, 0x71, MRM2r, "vpsrlw", X86vsrl, X86vsrli,
3792                              VR256, v16i16, v8i16, bc_v8i16, 0>, VEX_4V;
3793 defm VPSRLDY : PDI_binop_rmi<0xD2, 0x72, MRM2r, "vpsrld", X86vsrl, X86vsrli,
3794                              VR256, v8i32, v4i32, bc_v4i32, 0>, VEX_4V;
3795 defm VPSRLQY : PDI_binop_rmi<0xD3, 0x73, MRM2r, "vpsrlq", X86vsrl, X86vsrli,
3796                              VR256, v4i64, v2i64, bc_v2i64, 0>, VEX_4V;
3797
3798 defm VPSRAWY : PDI_binop_rmi<0xE1, 0x71, MRM4r, "vpsraw", X86vsra, X86vsrai,
3799                              VR256, v16i16, v8i16, bc_v8i16, 0>, VEX_4V;
3800 defm VPSRADY : PDI_binop_rmi<0xE2, 0x72, MRM4r, "vpsrad", X86vsra, X86vsrai,
3801                              VR256, v8i32, v4i32, bc_v4i32, 0>, VEX_4V;
3802
3803 let ExeDomain = SSEPackedInt in {
3804   // 256-bit logical shifts.
3805   def VPSLLDQYri : PDIi8<0x73, MRM7r,
3806                     (outs VR256:$dst), (ins VR256:$src1, i32i8imm:$src2),
3807                     "vpslldq\t{$src2, $src1, $dst|$dst, $src1, $src2}",
3808                     [(set VR256:$dst,
3809                       (int_x86_avx2_psll_dq_bs VR256:$src1, imm:$src2))]>,
3810                     VEX_4V;
3811   def VPSRLDQYri : PDIi8<0x73, MRM3r,
3812                     (outs VR256:$dst), (ins VR256:$src1, i32i8imm:$src2),
3813                     "vpsrldq\t{$src2, $src1, $dst|$dst, $src1, $src2}",
3814                     [(set VR256:$dst,
3815                       (int_x86_avx2_psrl_dq_bs VR256:$src1, imm:$src2))]>,
3816                     VEX_4V;
3817   // PSRADQYri doesn't exist in SSE[1-3].
3818 }
3819 } // Predicates = [HasAVX2]
3820
3821 let Constraints = "$src1 = $dst" in {
3822 defm PSLLW : PDI_binop_rmi<0xF1, 0x71, MRM6r, "psllw", X86vshl, X86vshli,
3823                            VR128, v8i16, v8i16, bc_v8i16>;
3824 defm PSLLD : PDI_binop_rmi<0xF2, 0x72, MRM6r, "pslld", X86vshl, X86vshli,
3825                            VR128, v4i32, v4i32, bc_v4i32>;
3826 defm PSLLQ : PDI_binop_rmi<0xF3, 0x73, MRM6r, "psllq", X86vshl, X86vshli,
3827                            VR128, v2i64, v2i64, bc_v2i64>;
3828
3829 defm PSRLW : PDI_binop_rmi<0xD1, 0x71, MRM2r, "psrlw", X86vsrl, X86vsrli,
3830                            VR128, v8i16, v8i16, bc_v8i16>;
3831 defm PSRLD : PDI_binop_rmi<0xD2, 0x72, MRM2r, "psrld", X86vsrl, X86vsrli,
3832                            VR128, v4i32, v4i32, bc_v4i32>;
3833 defm PSRLQ : PDI_binop_rmi<0xD3, 0x73, MRM2r, "psrlq", X86vsrl, X86vsrli,
3834                            VR128, v2i64, v2i64, bc_v2i64>;
3835
3836 defm PSRAW : PDI_binop_rmi<0xE1, 0x71, MRM4r, "psraw", X86vsra, X86vsrai,
3837                            VR128, v8i16, v8i16, bc_v8i16>;
3838 defm PSRAD : PDI_binop_rmi<0xE2, 0x72, MRM4r, "psrad", X86vsra, X86vsrai,
3839                            VR128, v4i32, v4i32, bc_v4i32>;
3840
3841 let ExeDomain = SSEPackedInt in {
3842   // 128-bit logical shifts.
3843   def PSLLDQri : PDIi8<0x73, MRM7r,
3844                        (outs VR128:$dst), (ins VR128:$src1, i32i8imm:$src2),
3845                        "pslldq\t{$src2, $dst|$dst, $src2}",
3846                        [(set VR128:$dst,
3847                          (int_x86_sse2_psll_dq_bs VR128:$src1, imm:$src2))]>;
3848   def PSRLDQri : PDIi8<0x73, MRM3r,
3849                        (outs VR128:$dst), (ins VR128:$src1, i32i8imm:$src2),
3850                        "psrldq\t{$src2, $dst|$dst, $src2}",
3851                        [(set VR128:$dst,
3852                          (int_x86_sse2_psrl_dq_bs VR128:$src1, imm:$src2))]>;
3853   // PSRADQri doesn't exist in SSE[1-3].
3854 }
3855 } // Constraints = "$src1 = $dst"
3856
3857 let Predicates = [HasAVX] in {
3858   def : Pat<(int_x86_sse2_psll_dq VR128:$src1, imm:$src2),
3859             (VPSLLDQri VR128:$src1, (BYTE_imm imm:$src2))>;
3860   def : Pat<(int_x86_sse2_psrl_dq VR128:$src1, imm:$src2),
3861             (VPSRLDQri VR128:$src1, (BYTE_imm imm:$src2))>;
3862   def : Pat<(v2f64 (X86fsrl VR128:$src1, i32immSExt8:$src2)),
3863             (VPSRLDQri VR128:$src1, (BYTE_imm imm:$src2))>;
3864
3865   // Shift up / down and insert zero's.
3866   def : Pat<(v2i64 (X86vshldq VR128:$src, (i8 imm:$amt))),
3867             (VPSLLDQri VR128:$src, (BYTE_imm imm:$amt))>;
3868   def : Pat<(v2i64 (X86vshrdq VR128:$src, (i8 imm:$amt))),
3869             (VPSRLDQri VR128:$src, (BYTE_imm imm:$amt))>;
3870 }
3871
3872 let Predicates = [HasAVX2] in {
3873   def : Pat<(int_x86_avx2_psll_dq VR256:$src1, imm:$src2),
3874             (VPSLLDQYri VR256:$src1, (BYTE_imm imm:$src2))>;
3875   def : Pat<(int_x86_avx2_psrl_dq VR256:$src1, imm:$src2),
3876             (VPSRLDQYri VR256:$src1, (BYTE_imm imm:$src2))>;
3877 }
3878
3879 let Predicates = [HasSSE2] in {
3880   def : Pat<(int_x86_sse2_psll_dq VR128:$src1, imm:$src2),
3881             (PSLLDQri VR128:$src1, (BYTE_imm imm:$src2))>;
3882   def : Pat<(int_x86_sse2_psrl_dq VR128:$src1, imm:$src2),
3883             (PSRLDQri VR128:$src1, (BYTE_imm imm:$src2))>;
3884   def : Pat<(v2f64 (X86fsrl VR128:$src1, i32immSExt8:$src2)),
3885             (PSRLDQri VR128:$src1, (BYTE_imm imm:$src2))>;
3886
3887   // Shift up / down and insert zero's.
3888   def : Pat<(v2i64 (X86vshldq VR128:$src, (i8 imm:$amt))),
3889             (PSLLDQri VR128:$src, (BYTE_imm imm:$amt))>;
3890   def : Pat<(v2i64 (X86vshrdq VR128:$src, (i8 imm:$amt))),
3891             (PSRLDQri VR128:$src, (BYTE_imm imm:$amt))>;
3892 }
3893
3894 //===---------------------------------------------------------------------===//
3895 // SSE2 - Packed Integer Comparison Instructions
3896 //===---------------------------------------------------------------------===//
3897
3898 let Predicates = [HasAVX] in {
3899   defm VPCMPEQB  : PDI_binop_rm<0x74, "vpcmpeqb", X86pcmpeq, v16i8,
3900                                 VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3901   defm VPCMPEQW  : PDI_binop_rm<0x75, "vpcmpeqw", X86pcmpeq, v8i16,
3902                                 VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3903   defm VPCMPEQD  : PDI_binop_rm<0x76, "vpcmpeqd", X86pcmpeq, v4i32,
3904                                 VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3905   defm VPCMPGTB  : PDI_binop_rm<0x64, "vpcmpgtb", X86pcmpgt, v16i8,
3906                                 VR128, memopv2i64, i128mem, 0, 0>, VEX_4V;
3907   defm VPCMPGTW  : PDI_binop_rm<0x65, "vpcmpgtw", X86pcmpgt, v8i16,
3908                                 VR128, memopv2i64, i128mem, 0, 0>, VEX_4V;
3909   defm VPCMPGTD  : PDI_binop_rm<0x66, "vpcmpgtd", X86pcmpgt, v4i32,
3910                                 VR128, memopv2i64, i128mem, 0, 0>, VEX_4V;
3911 }
3912
3913 let Predicates = [HasAVX2] in {
3914   defm VPCMPEQBY : PDI_binop_rm<0x74, "vpcmpeqb", X86pcmpeq, v32i8,
3915                                 VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3916   defm VPCMPEQWY : PDI_binop_rm<0x75, "vpcmpeqw", X86pcmpeq, v16i16,
3917                                 VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3918   defm VPCMPEQDY : PDI_binop_rm<0x76, "vpcmpeqd", X86pcmpeq, v8i32,
3919                                 VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3920   defm VPCMPGTBY : PDI_binop_rm<0x64, "vpcmpgtb", X86pcmpgt, v32i8,
3921                                 VR256, memopv4i64, i256mem, 0, 0>, VEX_4V;
3922   defm VPCMPGTWY : PDI_binop_rm<0x65, "vpcmpgtw", X86pcmpgt, v16i16,
3923                                 VR256, memopv4i64, i256mem, 0, 0>, VEX_4V;
3924   defm VPCMPGTDY : PDI_binop_rm<0x66, "vpcmpgtd", X86pcmpgt, v8i32,
3925                                 VR256, memopv4i64, i256mem, 0, 0>, VEX_4V;
3926 }
3927
3928 let Constraints = "$src1 = $dst" in {
3929   defm PCMPEQB  : PDI_binop_rm<0x74, "pcmpeqb", X86pcmpeq, v16i8,
3930                                VR128, memopv2i64, i128mem, 1>;
3931   defm PCMPEQW  : PDI_binop_rm<0x75, "pcmpeqw", X86pcmpeq, v8i16,
3932                                VR128, memopv2i64, i128mem, 1>;
3933   defm PCMPEQD  : PDI_binop_rm<0x76, "pcmpeqd", X86pcmpeq, v4i32,
3934                                VR128, memopv2i64, i128mem, 1>;
3935   defm PCMPGTB  : PDI_binop_rm<0x64, "pcmpgtb", X86pcmpgt, v16i8,
3936                                VR128, memopv2i64, i128mem>;
3937   defm PCMPGTW  : PDI_binop_rm<0x65, "pcmpgtw", X86pcmpgt, v8i16,
3938                                VR128, memopv2i64, i128mem>;
3939   defm PCMPGTD  : PDI_binop_rm<0x66, "pcmpgtd", X86pcmpgt, v4i32,
3940                                VR128, memopv2i64, i128mem>;
3941 } // Constraints = "$src1 = $dst"
3942
3943 //===---------------------------------------------------------------------===//
3944 // SSE2 - Packed Integer Pack Instructions
3945 //===---------------------------------------------------------------------===//
3946
3947 let Predicates = [HasAVX] in {
3948 defm VPACKSSWB : PDI_binop_rm_int<0x63, "vpacksswb", int_x86_sse2_packsswb_128,
3949                                   VR128, memopv2i64, i128mem, 0, 0>, VEX_4V;
3950 defm VPACKSSDW : PDI_binop_rm_int<0x6B, "vpackssdw", int_x86_sse2_packssdw_128,
3951                                   VR128, memopv2i64, i128mem, 0, 0>, VEX_4V;
3952 defm VPACKUSWB : PDI_binop_rm_int<0x67, "vpackuswb", int_x86_sse2_packuswb_128,
3953                                   VR128, memopv2i64, i128mem, 0, 0>, VEX_4V;
3954 }
3955
3956 let Predicates = [HasAVX2] in {
3957 defm VPACKSSWBY : PDI_binop_rm_int<0x63, "vpacksswb", int_x86_avx2_packsswb,
3958                                    VR256, memopv4i64, i256mem, 0, 0>, VEX_4V;
3959 defm VPACKSSDWY : PDI_binop_rm_int<0x6B, "vpackssdw", int_x86_avx2_packssdw,
3960                                    VR256, memopv4i64, i256mem, 0, 0>, VEX_4V;
3961 defm VPACKUSWBY : PDI_binop_rm_int<0x67, "vpackuswb", int_x86_avx2_packuswb,
3962                                    VR256, memopv4i64, i256mem, 0, 0>, VEX_4V;
3963 }
3964
3965 let Constraints = "$src1 = $dst" in {
3966 defm PACKSSWB : PDI_binop_rm_int<0x63, "packsswb", int_x86_sse2_packsswb_128,
3967                                  VR128, memopv2i64, i128mem>;
3968 defm PACKSSDW : PDI_binop_rm_int<0x6B, "packssdw", int_x86_sse2_packssdw_128,
3969                                  VR128, memopv2i64, i128mem>;
3970 defm PACKUSWB : PDI_binop_rm_int<0x67, "packuswb", int_x86_sse2_packuswb_128,
3971                                  VR128, memopv2i64, i128mem>;
3972 } // Constraints = "$src1 = $dst"
3973
3974 //===---------------------------------------------------------------------===//
3975 // SSE2 - Packed Integer Shuffle Instructions
3976 //===---------------------------------------------------------------------===//
3977
3978 let ExeDomain = SSEPackedInt in {
3979 multiclass sse2_pshuffle<string OpcodeStr, ValueType vt, PatFrag pshuf_frag,
3980                          PatFrag bc_frag> {
3981 def ri : Ii8<0x70, MRMSrcReg,
3982               (outs VR128:$dst), (ins VR128:$src1, i8imm:$src2),
3983               !strconcat(OpcodeStr,
3984                          "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
3985               [(set VR128:$dst, (vt (pshuf_frag:$src2 VR128:$src1,
3986                                                       (undef))))]>;
3987 def mi : Ii8<0x70, MRMSrcMem,
3988               (outs VR128:$dst), (ins i128mem:$src1, i8imm:$src2),
3989               !strconcat(OpcodeStr,
3990                          "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
3991               [(set VR128:$dst, (vt (pshuf_frag:$src2
3992                                       (bc_frag (memopv2i64 addr:$src1)),
3993                                       (undef))))]>;
3994 }
3995
3996 multiclass sse2_pshuffle_y<string OpcodeStr, ValueType vt, PatFrag pshuf_frag,
3997                            PatFrag bc_frag> {
3998 def Yri : Ii8<0x70, MRMSrcReg,
3999               (outs VR256:$dst), (ins VR256:$src1, i8imm:$src2),
4000               !strconcat(OpcodeStr,
4001                          "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4002               [(set VR256:$dst, (vt (pshuf_frag:$src2 VR256:$src1,
4003                                                       (undef))))]>;
4004 def Ymi : Ii8<0x70, MRMSrcMem,
4005               (outs VR256:$dst), (ins i256mem:$src1, i8imm:$src2),
4006               !strconcat(OpcodeStr,
4007                          "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4008               [(set VR256:$dst, (vt (pshuf_frag:$src2
4009                                       (bc_frag (memopv4i64 addr:$src1)),
4010                                       (undef))))]>;
4011 }
4012 } // ExeDomain = SSEPackedInt
4013
4014 let Predicates = [HasAVX] in {
4015   let AddedComplexity = 5 in
4016   defm VPSHUFD : sse2_pshuffle<"vpshufd", v4i32, pshufd, bc_v4i32>, TB, OpSize,
4017                                VEX;
4018
4019   // SSE2 with ImmT == Imm8 and XS prefix.
4020   defm VPSHUFHW : sse2_pshuffle<"vpshufhw", v8i16, pshufhw, bc_v8i16>, XS,
4021                                VEX;
4022
4023   // SSE2 with ImmT == Imm8 and XD prefix.
4024   defm VPSHUFLW : sse2_pshuffle<"vpshuflw", v8i16, pshuflw, bc_v8i16>, XD,
4025                                VEX;
4026
4027   let AddedComplexity = 5 in
4028   def : Pat<(v4f32 (pshufd:$src2 VR128:$src1, (undef))),
4029             (VPSHUFDri VR128:$src1, (SHUFFLE_get_shuf_imm VR128:$src2))>;
4030   // Unary v4f32 shuffle with VPSHUF* in order to fold a load.
4031   def : Pat<(pshufd:$src2 (bc_v4i32 (memopv4f32 addr:$src1)), (undef)),
4032             (VPSHUFDmi addr:$src1, (SHUFFLE_get_shuf_imm VR128:$src2))>;
4033
4034   def : Pat<(v4i32 (X86PShufd (bc_v4i32 (memopv2i64 addr:$src1)),
4035                                    (i8 imm:$imm))),
4036             (VPSHUFDmi addr:$src1, imm:$imm)>;
4037   def : Pat<(v4f32 (X86PShufd (memopv4f32 addr:$src1), (i8 imm:$imm))),
4038             (VPSHUFDmi addr:$src1, imm:$imm)>;
4039   def : Pat<(v4f32 (X86PShufd VR128:$src1, (i8 imm:$imm))),
4040             (VPSHUFDri VR128:$src1, imm:$imm)>;
4041   def : Pat<(v4i32 (X86PShufd VR128:$src1, (i8 imm:$imm))),
4042             (VPSHUFDri VR128:$src1, imm:$imm)>;
4043   def : Pat<(v8i16 (X86PShufhw VR128:$src, (i8 imm:$imm))),
4044             (VPSHUFHWri VR128:$src, imm:$imm)>;
4045   def : Pat<(v8i16 (X86PShufhw (bc_v8i16 (memopv2i64 addr:$src)),
4046                                (i8 imm:$imm))),
4047             (VPSHUFHWmi addr:$src, imm:$imm)>;
4048   def : Pat<(v8i16 (X86PShuflw VR128:$src, (i8 imm:$imm))),
4049             (VPSHUFLWri VR128:$src, imm:$imm)>;
4050   def : Pat<(v8i16 (X86PShuflw (bc_v8i16 (memopv2i64 addr:$src)),
4051                                (i8 imm:$imm))),
4052             (VPSHUFLWmi addr:$src, imm:$imm)>;
4053 }
4054
4055 let Predicates = [HasAVX2] in {
4056   let AddedComplexity = 5 in
4057   defm VPSHUFD : sse2_pshuffle_y<"vpshufd", v8i32, pshufd, bc_v8i32>, TB,
4058                                  OpSize, VEX;
4059
4060   // SSE2 with ImmT == Imm8 and XS prefix.
4061   defm VPSHUFHW : sse2_pshuffle_y<"vpshufhw", v16i16, pshufhw, bc_v16i16>, XS,
4062                                   VEX;
4063
4064   // SSE2 with ImmT == Imm8 and XD prefix.
4065   defm VPSHUFLW : sse2_pshuffle_y<"vpshuflw", v16i16, pshuflw, bc_v16i16>, XD,
4066                                   VEX;
4067 }
4068
4069 let Predicates = [HasSSE2] in {
4070   let AddedComplexity = 5 in
4071   defm PSHUFD : sse2_pshuffle<"pshufd", v4i32, pshufd, bc_v4i32>, TB, OpSize;
4072
4073   // SSE2 with ImmT == Imm8 and XS prefix.
4074   defm PSHUFHW : sse2_pshuffle<"pshufhw", v8i16, pshufhw, bc_v8i16>, XS;
4075
4076   // SSE2 with ImmT == Imm8 and XD prefix.
4077   defm PSHUFLW : sse2_pshuffle<"pshuflw", v8i16, pshuflw, bc_v8i16>, XD;
4078
4079   let AddedComplexity = 5 in
4080   def : Pat<(v4f32 (pshufd:$src2 VR128:$src1, (undef))),
4081             (PSHUFDri VR128:$src1, (SHUFFLE_get_shuf_imm VR128:$src2))>;
4082   // Unary v4f32 shuffle with PSHUF* in order to fold a load.
4083   def : Pat<(pshufd:$src2 (bc_v4i32 (memopv4f32 addr:$src1)), (undef)),
4084             (PSHUFDmi addr:$src1, (SHUFFLE_get_shuf_imm VR128:$src2))>;
4085
4086   def : Pat<(v4i32 (X86PShufd (bc_v4i32 (memopv2i64 addr:$src1)),
4087                                    (i8 imm:$imm))),
4088             (PSHUFDmi addr:$src1, imm:$imm)>;
4089   def : Pat<(v4f32 (X86PShufd (memopv4f32 addr:$src1), (i8 imm:$imm))),
4090             (PSHUFDmi addr:$src1, imm:$imm)>;
4091   def : Pat<(v4f32 (X86PShufd VR128:$src1, (i8 imm:$imm))),
4092             (PSHUFDri VR128:$src1, imm:$imm)>;
4093   def : Pat<(v4i32 (X86PShufd VR128:$src1, (i8 imm:$imm))),
4094             (PSHUFDri VR128:$src1, imm:$imm)>;
4095   def : Pat<(v8i16 (X86PShufhw VR128:$src, (i8 imm:$imm))),
4096             (PSHUFHWri VR128:$src, imm:$imm)>;
4097   def : Pat<(v8i16 (X86PShufhw (bc_v8i16 (memopv2i64 addr:$src)),
4098                                (i8 imm:$imm))),
4099             (PSHUFHWmi addr:$src, imm:$imm)>;
4100   def : Pat<(v8i16 (X86PShuflw VR128:$src, (i8 imm:$imm))),
4101             (PSHUFLWri VR128:$src, imm:$imm)>;
4102   def : Pat<(v8i16 (X86PShuflw (bc_v8i16 (memopv2i64 addr:$src)),
4103                                (i8 imm:$imm))),
4104             (PSHUFLWmi addr:$src, imm:$imm)>;
4105 }
4106
4107 //===---------------------------------------------------------------------===//
4108 // SSE2 - Packed Integer Unpack Instructions
4109 //===---------------------------------------------------------------------===//
4110
4111 let ExeDomain = SSEPackedInt in {
4112 multiclass sse2_unpack<bits<8> opc, string OpcodeStr, ValueType vt,
4113                        SDNode OpNode, PatFrag bc_frag, bit Is2Addr = 1> {
4114   def rr : PDI<opc, MRMSrcReg,
4115       (outs VR128:$dst), (ins VR128:$src1, VR128:$src2),
4116       !if(Is2Addr,
4117           !strconcat(OpcodeStr,"\t{$src2, $dst|$dst, $src2}"),
4118           !strconcat(OpcodeStr,"\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
4119       [(set VR128:$dst, (vt (OpNode VR128:$src1, VR128:$src2)))]>;
4120   def rm : PDI<opc, MRMSrcMem,
4121       (outs VR128:$dst), (ins VR128:$src1, i128mem:$src2),
4122       !if(Is2Addr,
4123           !strconcat(OpcodeStr,"\t{$src2, $dst|$dst, $src2}"),
4124           !strconcat(OpcodeStr,"\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
4125       [(set VR128:$dst, (OpNode VR128:$src1,
4126                                   (bc_frag (memopv2i64
4127                                                addr:$src2))))]>;
4128 }
4129
4130 multiclass sse2_unpack_y<bits<8> opc, string OpcodeStr, ValueType vt,
4131                          SDNode OpNode, PatFrag bc_frag> {
4132   def Yrr : PDI<opc, MRMSrcReg,
4133       (outs VR256:$dst), (ins VR256:$src1, VR256:$src2),
4134       !strconcat(OpcodeStr,"\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4135       [(set VR256:$dst, (vt (OpNode VR256:$src1, VR256:$src2)))]>;
4136   def Yrm : PDI<opc, MRMSrcMem,
4137       (outs VR256:$dst), (ins VR256:$src1, i256mem:$src2),
4138       !strconcat(OpcodeStr,"\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4139       [(set VR256:$dst, (OpNode VR256:$src1,
4140                                   (bc_frag (memopv4i64 addr:$src2))))]>;
4141 }
4142
4143 let Predicates = [HasAVX] in {
4144   defm VPUNPCKLBW  : sse2_unpack<0x60, "vpunpcklbw", v16i8, X86Unpckl,
4145                                  bc_v16i8, 0>, VEX_4V;
4146   defm VPUNPCKLWD  : sse2_unpack<0x61, "vpunpcklwd", v8i16, X86Unpckl,
4147                                  bc_v8i16, 0>, VEX_4V;
4148   defm VPUNPCKLDQ  : sse2_unpack<0x62, "vpunpckldq", v4i32, X86Unpckl,
4149                                  bc_v4i32, 0>, VEX_4V;
4150   defm VPUNPCKLQDQ : sse2_unpack<0x6C, "vpunpcklqdq", v2i64, X86Unpckl,
4151                                  bc_v2i64, 0>, VEX_4V;
4152
4153   defm VPUNPCKHBW  : sse2_unpack<0x68, "vpunpckhbw", v16i8, X86Unpckh,
4154                                  bc_v16i8, 0>, VEX_4V;
4155   defm VPUNPCKHWD  : sse2_unpack<0x69, "vpunpckhwd", v8i16, X86Unpckh,
4156                                  bc_v8i16, 0>, VEX_4V;
4157   defm VPUNPCKHDQ  : sse2_unpack<0x6A, "vpunpckhdq", v4i32, X86Unpckh,
4158                                  bc_v4i32, 0>, VEX_4V;
4159   defm VPUNPCKHQDQ : sse2_unpack<0x6D, "vpunpckhqdq", v2i64, X86Unpckh,
4160                                  bc_v2i64, 0>, VEX_4V;
4161 }
4162
4163 let Predicates = [HasAVX2] in {
4164   defm VPUNPCKLBW  : sse2_unpack_y<0x60, "vpunpcklbw", v32i8, X86Unpckl,
4165                                    bc_v32i8>, VEX_4V;
4166   defm VPUNPCKLWD  : sse2_unpack_y<0x61, "vpunpcklwd", v16i16, X86Unpckl,
4167                                    bc_v16i16>, VEX_4V;
4168   defm VPUNPCKLDQ  : sse2_unpack_y<0x62, "vpunpckldq", v8i32, X86Unpckl,
4169                                    bc_v8i32>, VEX_4V;
4170   defm VPUNPCKLQDQ : sse2_unpack_y<0x6C, "vpunpcklqdq", v4i64, X86Unpckl,
4171                                    bc_v4i64>, VEX_4V;
4172
4173   defm VPUNPCKHBW  : sse2_unpack_y<0x68, "vpunpckhbw", v32i8, X86Unpckh,
4174                                    bc_v32i8>, VEX_4V;
4175   defm VPUNPCKHWD  : sse2_unpack_y<0x69, "vpunpckhwd", v16i16, X86Unpckh,
4176                                    bc_v16i16>, VEX_4V;
4177   defm VPUNPCKHDQ  : sse2_unpack_y<0x6A, "vpunpckhdq", v8i32, X86Unpckh,
4178                                    bc_v8i32>, VEX_4V;
4179   defm VPUNPCKHQDQ : sse2_unpack_y<0x6D, "vpunpckhqdq", v4i64, X86Unpckh,
4180                                    bc_v4i64>, VEX_4V;
4181 }
4182
4183 let Constraints = "$src1 = $dst" in {
4184   defm PUNPCKLBW  : sse2_unpack<0x60, "punpcklbw", v16i8, X86Unpckl,
4185                                 bc_v16i8>;
4186   defm PUNPCKLWD  : sse2_unpack<0x61, "punpcklwd", v8i16, X86Unpckl,
4187                                 bc_v8i16>;
4188   defm PUNPCKLDQ  : sse2_unpack<0x62, "punpckldq", v4i32, X86Unpckl,
4189                                 bc_v4i32>;
4190   defm PUNPCKLQDQ : sse2_unpack<0x6C, "punpcklqdq", v2i64, X86Unpckl,
4191                                 bc_v2i64>;
4192
4193   defm PUNPCKHBW  : sse2_unpack<0x68, "punpckhbw", v16i8, X86Unpckh,
4194                                 bc_v16i8>;
4195   defm PUNPCKHWD  : sse2_unpack<0x69, "punpckhwd", v8i16, X86Unpckh,
4196                                 bc_v8i16>;
4197   defm PUNPCKHDQ  : sse2_unpack<0x6A, "punpckhdq", v4i32, X86Unpckh,
4198                                 bc_v4i32>;
4199   defm PUNPCKHQDQ : sse2_unpack<0x6D, "punpckhqdq", v2i64, X86Unpckh,
4200                                 bc_v2i64>;
4201 }
4202 } // ExeDomain = SSEPackedInt
4203
4204 // Patterns for using AVX1 instructions with integer vectors
4205 // Here to give AVX2 priority
4206 let Predicates = [HasAVX] in {
4207   def : Pat<(v8i32 (X86Unpckl VR256:$src1, (bc_v8i32 (memopv4i64 addr:$src2)))),
4208             (VUNPCKLPSYrm VR256:$src1, addr:$src2)>;
4209   def : Pat<(v8i32 (X86Unpckl VR256:$src1, VR256:$src2)),
4210             (VUNPCKLPSYrr VR256:$src1, VR256:$src2)>;
4211   def : Pat<(v8i32 (X86Unpckh VR256:$src1, (bc_v8i32 (memopv4i64 addr:$src2)))),
4212             (VUNPCKHPSYrm VR256:$src1, addr:$src2)>;
4213   def : Pat<(v8i32 (X86Unpckh VR256:$src1, VR256:$src2)),
4214             (VUNPCKHPSYrr VR256:$src1, VR256:$src2)>;
4215
4216   def : Pat<(v4i64 (X86Unpckl VR256:$src1, (memopv4i64 addr:$src2))),
4217             (VUNPCKLPDYrm VR256:$src1, addr:$src2)>;
4218   def : Pat<(v4i64 (X86Unpckl VR256:$src1, VR256:$src2)),
4219             (VUNPCKLPDYrr VR256:$src1, VR256:$src2)>;
4220   def : Pat<(v4i64 (X86Unpckh VR256:$src1, (memopv4i64 addr:$src2))),
4221             (VUNPCKHPDYrm VR256:$src1, addr:$src2)>;
4222   def : Pat<(v4i64 (X86Unpckh VR256:$src1, VR256:$src2)),
4223             (VUNPCKHPDYrr VR256:$src1, VR256:$src2)>;
4224 }
4225
4226 // Splat v2f64 / v2i64
4227 let AddedComplexity = 10 in {
4228   def : Pat<(splat_lo (v2i64 VR128:$src), (undef)),
4229             (PUNPCKLQDQrr VR128:$src, VR128:$src)>, Requires<[HasSSE2]>;
4230   def : Pat<(splat_lo (v2i64 VR128:$src), (undef)),
4231             (VPUNPCKLQDQrr VR128:$src, VR128:$src)>, Requires<[HasAVX]>;
4232 }
4233
4234 //===---------------------------------------------------------------------===//
4235 // SSE2 - Packed Integer Extract and Insert
4236 //===---------------------------------------------------------------------===//
4237
4238 let ExeDomain = SSEPackedInt in {
4239 multiclass sse2_pinsrw<bit Is2Addr = 1> {
4240   def rri : Ii8<0xC4, MRMSrcReg,
4241        (outs VR128:$dst), (ins VR128:$src1,
4242         GR32:$src2, i32i8imm:$src3),
4243        !if(Is2Addr,
4244            "pinsrw\t{$src3, $src2, $dst|$dst, $src2, $src3}",
4245            "vpinsrw\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
4246        [(set VR128:$dst,
4247          (X86pinsrw VR128:$src1, GR32:$src2, imm:$src3))]>;
4248   def rmi : Ii8<0xC4, MRMSrcMem,
4249                        (outs VR128:$dst), (ins VR128:$src1,
4250                         i16mem:$src2, i32i8imm:$src3),
4251        !if(Is2Addr,
4252            "pinsrw\t{$src3, $src2, $dst|$dst, $src2, $src3}",
4253            "vpinsrw\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
4254        [(set VR128:$dst,
4255          (X86pinsrw VR128:$src1, (extloadi16 addr:$src2),
4256                     imm:$src3))]>;
4257 }
4258
4259 // Extract
4260 let Predicates = [HasAVX] in
4261 def VPEXTRWri : Ii8<0xC5, MRMSrcReg,
4262                     (outs GR32:$dst), (ins VR128:$src1, i32i8imm:$src2),
4263                     "vpextrw\t{$src2, $src1, $dst|$dst, $src1, $src2}",
4264                     [(set GR32:$dst, (X86pextrw (v8i16 VR128:$src1),
4265                                                 imm:$src2))]>, TB, OpSize, VEX;
4266 def PEXTRWri : PDIi8<0xC5, MRMSrcReg,
4267                     (outs GR32:$dst), (ins VR128:$src1, i32i8imm:$src2),
4268                     "pextrw\t{$src2, $src1, $dst|$dst, $src1, $src2}",
4269                     [(set GR32:$dst, (X86pextrw (v8i16 VR128:$src1),
4270                                                 imm:$src2))]>;
4271
4272 // Insert
4273 let Predicates = [HasAVX] in {
4274   defm VPINSRW : sse2_pinsrw<0>, TB, OpSize, VEX_4V;
4275   def  VPINSRWrr64i : Ii8<0xC4, MRMSrcReg, (outs VR128:$dst),
4276        (ins VR128:$src1, GR64:$src2, i32i8imm:$src3),
4277        "vpinsrw\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
4278        []>, TB, OpSize, VEX_4V;
4279 }
4280
4281 let Constraints = "$src1 = $dst" in
4282   defm PINSRW : sse2_pinsrw, TB, OpSize, Requires<[HasSSE2]>;
4283
4284 } // ExeDomain = SSEPackedInt
4285
4286 //===---------------------------------------------------------------------===//
4287 // SSE2 - Packed Mask Creation
4288 //===---------------------------------------------------------------------===//
4289
4290 let ExeDomain = SSEPackedInt in {
4291
4292 def VPMOVMSKBrr  : VPDI<0xD7, MRMSrcReg, (outs GR32:$dst), (ins VR128:$src),
4293            "pmovmskb\t{$src, $dst|$dst, $src}",
4294            [(set GR32:$dst, (int_x86_sse2_pmovmskb_128 VR128:$src))]>, VEX;
4295 def VPMOVMSKBr64r : VPDI<0xD7, MRMSrcReg, (outs GR64:$dst), (ins VR128:$src),
4296            "pmovmskb\t{$src, $dst|$dst, $src}", []>, VEX;
4297
4298 let Predicates = [HasAVX2] in {
4299 def VPMOVMSKBYrr  : VPDI<0xD7, MRMSrcReg, (outs GR32:$dst), (ins VR256:$src),
4300            "pmovmskb\t{$src, $dst|$dst, $src}",
4301            [(set GR32:$dst, (int_x86_avx2_pmovmskb VR256:$src))]>, VEX;
4302 def VPMOVMSKBYr64r : VPDI<0xD7, MRMSrcReg, (outs GR64:$dst), (ins VR256:$src),
4303            "pmovmskb\t{$src, $dst|$dst, $src}", []>, VEX;
4304 }
4305
4306 def PMOVMSKBrr : PDI<0xD7, MRMSrcReg, (outs GR32:$dst), (ins VR128:$src),
4307            "pmovmskb\t{$src, $dst|$dst, $src}",
4308            [(set GR32:$dst, (int_x86_sse2_pmovmskb_128 VR128:$src))]>;
4309
4310 } // ExeDomain = SSEPackedInt
4311
4312 //===---------------------------------------------------------------------===//
4313 // SSE2 - Conditional Store
4314 //===---------------------------------------------------------------------===//
4315
4316 let ExeDomain = SSEPackedInt in {
4317
4318 let Uses = [EDI] in
4319 def VMASKMOVDQU : VPDI<0xF7, MRMSrcReg, (outs),
4320            (ins VR128:$src, VR128:$mask),
4321            "maskmovdqu\t{$mask, $src|$src, $mask}",
4322            [(int_x86_sse2_maskmov_dqu VR128:$src, VR128:$mask, EDI)]>, VEX;
4323 let Uses = [RDI] in
4324 def VMASKMOVDQU64 : VPDI<0xF7, MRMSrcReg, (outs),
4325            (ins VR128:$src, VR128:$mask),
4326            "maskmovdqu\t{$mask, $src|$src, $mask}",
4327            [(int_x86_sse2_maskmov_dqu VR128:$src, VR128:$mask, RDI)]>, VEX;
4328
4329 let Uses = [EDI] in
4330 def MASKMOVDQU : PDI<0xF7, MRMSrcReg, (outs), (ins VR128:$src, VR128:$mask),
4331            "maskmovdqu\t{$mask, $src|$src, $mask}",
4332            [(int_x86_sse2_maskmov_dqu VR128:$src, VR128:$mask, EDI)]>;
4333 let Uses = [RDI] in
4334 def MASKMOVDQU64 : PDI<0xF7, MRMSrcReg, (outs), (ins VR128:$src, VR128:$mask),
4335            "maskmovdqu\t{$mask, $src|$src, $mask}",
4336            [(int_x86_sse2_maskmov_dqu VR128:$src, VR128:$mask, RDI)]>;
4337
4338 } // ExeDomain = SSEPackedInt
4339
4340 //===---------------------------------------------------------------------===//
4341 // SSE2 - Move Doubleword
4342 //===---------------------------------------------------------------------===//
4343
4344 //===---------------------------------------------------------------------===//
4345 // Move Int Doubleword to Packed Double Int
4346 //
4347 def VMOVDI2PDIrr : VPDI<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR32:$src),
4348                       "movd\t{$src, $dst|$dst, $src}",
4349                       [(set VR128:$dst,
4350                         (v4i32 (scalar_to_vector GR32:$src)))]>, VEX;
4351 def VMOVDI2PDIrm : VPDI<0x6E, MRMSrcMem, (outs VR128:$dst), (ins i32mem:$src),
4352                       "movd\t{$src, $dst|$dst, $src}",
4353                       [(set VR128:$dst,
4354                         (v4i32 (scalar_to_vector (loadi32 addr:$src))))]>,
4355                       VEX;
4356 def VMOV64toPQIrr : VRPDI<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR64:$src),
4357                         "mov{d|q}\t{$src, $dst|$dst, $src}",
4358                         [(set VR128:$dst,
4359                           (v2i64 (scalar_to_vector GR64:$src)))]>, VEX;
4360 def VMOV64toSDrr : VRPDI<0x6E, MRMSrcReg, (outs FR64:$dst), (ins GR64:$src),
4361                        "mov{d|q}\t{$src, $dst|$dst, $src}",
4362                        [(set FR64:$dst, (bitconvert GR64:$src))]>, VEX;
4363
4364 def MOVDI2PDIrr : PDI<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR32:$src),
4365                       "movd\t{$src, $dst|$dst, $src}",
4366                       [(set VR128:$dst,
4367                         (v4i32 (scalar_to_vector GR32:$src)))]>;
4368 def MOVDI2PDIrm : PDI<0x6E, MRMSrcMem, (outs VR128:$dst), (ins i32mem:$src),
4369                       "movd\t{$src, $dst|$dst, $src}",
4370                       [(set VR128:$dst,
4371                         (v4i32 (scalar_to_vector (loadi32 addr:$src))))]>;
4372 def MOV64toPQIrr : RPDI<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR64:$src),
4373                         "mov{d|q}\t{$src, $dst|$dst, $src}",
4374                         [(set VR128:$dst,
4375                           (v2i64 (scalar_to_vector GR64:$src)))]>;
4376 def MOV64toSDrr : RPDI<0x6E, MRMSrcReg, (outs FR64:$dst), (ins GR64:$src),
4377                        "mov{d|q}\t{$src, $dst|$dst, $src}",
4378                        [(set FR64:$dst, (bitconvert GR64:$src))]>;
4379
4380 //===---------------------------------------------------------------------===//
4381 // Move Int Doubleword to Single Scalar
4382 //
4383 def VMOVDI2SSrr  : VPDI<0x6E, MRMSrcReg, (outs FR32:$dst), (ins GR32:$src),
4384                       "movd\t{$src, $dst|$dst, $src}",
4385                       [(set FR32:$dst, (bitconvert GR32:$src))]>, VEX;
4386
4387 def VMOVDI2SSrm  : VPDI<0x6E, MRMSrcMem, (outs FR32:$dst), (ins i32mem:$src),
4388                       "movd\t{$src, $dst|$dst, $src}",
4389                       [(set FR32:$dst, (bitconvert (loadi32 addr:$src)))]>,
4390                       VEX;
4391 def MOVDI2SSrr  : PDI<0x6E, MRMSrcReg, (outs FR32:$dst), (ins GR32:$src),
4392                       "movd\t{$src, $dst|$dst, $src}",
4393                       [(set FR32:$dst, (bitconvert GR32:$src))]>;
4394
4395 def MOVDI2SSrm  : PDI<0x6E, MRMSrcMem, (outs FR32:$dst), (ins i32mem:$src),
4396                       "movd\t{$src, $dst|$dst, $src}",
4397                       [(set FR32:$dst, (bitconvert (loadi32 addr:$src)))]>;
4398
4399 //===---------------------------------------------------------------------===//
4400 // Move Packed Doubleword Int to Packed Double Int
4401 //
4402 def VMOVPDI2DIrr  : VPDI<0x7E, MRMDestReg, (outs GR32:$dst), (ins VR128:$src),
4403                        "movd\t{$src, $dst|$dst, $src}",
4404                        [(set GR32:$dst, (vector_extract (v4i32 VR128:$src),
4405                                         (iPTR 0)))]>, VEX;
4406 def VMOVPDI2DImr  : VPDI<0x7E, MRMDestMem, (outs),
4407                        (ins i32mem:$dst, VR128:$src),
4408                        "movd\t{$src, $dst|$dst, $src}",
4409                        [(store (i32 (vector_extract (v4i32 VR128:$src),
4410                                      (iPTR 0))), addr:$dst)]>, VEX;
4411 def MOVPDI2DIrr  : PDI<0x7E, MRMDestReg, (outs GR32:$dst), (ins VR128:$src),
4412                        "movd\t{$src, $dst|$dst, $src}",
4413                        [(set GR32:$dst, (vector_extract (v4i32 VR128:$src),
4414                                         (iPTR 0)))]>;
4415 def MOVPDI2DImr  : PDI<0x7E, MRMDestMem, (outs), (ins i32mem:$dst, VR128:$src),
4416                        "movd\t{$src, $dst|$dst, $src}",
4417                        [(store (i32 (vector_extract (v4i32 VR128:$src),
4418                                      (iPTR 0))), addr:$dst)]>;
4419
4420 //===---------------------------------------------------------------------===//
4421 // Move Packed Doubleword Int first element to Doubleword Int
4422 //
4423 def VMOVPQIto64rr : I<0x7E, MRMDestReg, (outs GR64:$dst), (ins VR128:$src),
4424                           "mov{d|q}\t{$src, $dst|$dst, $src}",
4425                           [(set GR64:$dst, (vector_extract (v2i64 VR128:$src),
4426                                                            (iPTR 0)))]>,
4427                       TB, OpSize, VEX, VEX_W, Requires<[HasAVX, In64BitMode]>;
4428
4429 def MOVPQIto64rr : RPDI<0x7E, MRMDestReg, (outs GR64:$dst), (ins VR128:$src),
4430                         "mov{d|q}\t{$src, $dst|$dst, $src}",
4431                         [(set GR64:$dst, (vector_extract (v2i64 VR128:$src),
4432                                                          (iPTR 0)))]>;
4433
4434 //===---------------------------------------------------------------------===//
4435 // Bitcast FR64 <-> GR64
4436 //
4437 let Predicates = [HasAVX] in
4438 def VMOV64toSDrm : S3SI<0x7E, MRMSrcMem, (outs FR64:$dst), (ins i64mem:$src),
4439                         "vmovq\t{$src, $dst|$dst, $src}",
4440                         [(set FR64:$dst, (bitconvert (loadi64 addr:$src)))]>,
4441                         VEX;
4442 def VMOVSDto64rr : VRPDI<0x7E, MRMDestReg, (outs GR64:$dst), (ins FR64:$src),
4443                          "mov{d|q}\t{$src, $dst|$dst, $src}",
4444                          [(set GR64:$dst, (bitconvert FR64:$src))]>, VEX;
4445 def VMOVSDto64mr : VRPDI<0x7E, MRMDestMem, (outs), (ins i64mem:$dst, FR64:$src),
4446                          "movq\t{$src, $dst|$dst, $src}",
4447                          [(store (i64 (bitconvert FR64:$src)), addr:$dst)]>,
4448                          VEX;
4449
4450 def MOV64toSDrm : S3SI<0x7E, MRMSrcMem, (outs FR64:$dst), (ins i64mem:$src),
4451                        "movq\t{$src, $dst|$dst, $src}",
4452                        [(set FR64:$dst, (bitconvert (loadi64 addr:$src)))]>;
4453 def MOVSDto64rr : RPDI<0x7E, MRMDestReg, (outs GR64:$dst), (ins FR64:$src),
4454                        "mov{d|q}\t{$src, $dst|$dst, $src}",
4455                        [(set GR64:$dst, (bitconvert FR64:$src))]>;
4456 def MOVSDto64mr : RPDI<0x7E, MRMDestMem, (outs), (ins i64mem:$dst, FR64:$src),
4457                        "movq\t{$src, $dst|$dst, $src}",
4458                        [(store (i64 (bitconvert FR64:$src)), addr:$dst)]>;
4459
4460 //===---------------------------------------------------------------------===//
4461 // Move Scalar Single to Double Int
4462 //
4463 def VMOVSS2DIrr  : VPDI<0x7E, MRMDestReg, (outs GR32:$dst), (ins FR32:$src),
4464                       "movd\t{$src, $dst|$dst, $src}",
4465                       [(set GR32:$dst, (bitconvert FR32:$src))]>, VEX;
4466 def VMOVSS2DImr  : VPDI<0x7E, MRMDestMem, (outs), (ins i32mem:$dst, FR32:$src),
4467                       "movd\t{$src, $dst|$dst, $src}",
4468                       [(store (i32 (bitconvert FR32:$src)), addr:$dst)]>, VEX;
4469 def MOVSS2DIrr  : PDI<0x7E, MRMDestReg, (outs GR32:$dst), (ins FR32:$src),
4470                       "movd\t{$src, $dst|$dst, $src}",
4471                       [(set GR32:$dst, (bitconvert FR32:$src))]>;
4472 def MOVSS2DImr  : PDI<0x7E, MRMDestMem, (outs), (ins i32mem:$dst, FR32:$src),
4473                       "movd\t{$src, $dst|$dst, $src}",
4474                       [(store (i32 (bitconvert FR32:$src)), addr:$dst)]>;
4475
4476 //===---------------------------------------------------------------------===//
4477 // Patterns and instructions to describe movd/movq to XMM register zero-extends
4478 //
4479 let AddedComplexity = 15 in {
4480 def VMOVZDI2PDIrr : VPDI<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR32:$src),
4481                        "movd\t{$src, $dst|$dst, $src}",
4482                        [(set VR128:$dst, (v4i32 (X86vzmovl
4483                                       (v4i32 (scalar_to_vector GR32:$src)))))]>,
4484                                       VEX;
4485 def VMOVZQI2PQIrr : VPDI<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR64:$src),
4486                        "mov{d|q}\t{$src, $dst|$dst, $src}", // X86-64 only
4487                        [(set VR128:$dst, (v2i64 (X86vzmovl
4488                                       (v2i64 (scalar_to_vector GR64:$src)))))]>,
4489                                       VEX, VEX_W;
4490 }
4491 let AddedComplexity = 15 in {
4492 def MOVZDI2PDIrr : PDI<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR32:$src),
4493                        "movd\t{$src, $dst|$dst, $src}",
4494                        [(set VR128:$dst, (v4i32 (X86vzmovl
4495                                       (v4i32 (scalar_to_vector GR32:$src)))))]>;
4496 def MOVZQI2PQIrr : RPDI<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR64:$src),
4497                        "mov{d|q}\t{$src, $dst|$dst, $src}", // X86-64 only
4498                        [(set VR128:$dst, (v2i64 (X86vzmovl
4499                                       (v2i64 (scalar_to_vector GR64:$src)))))]>;
4500 }
4501
4502 let AddedComplexity = 20 in {
4503 def VMOVZDI2PDIrm : VPDI<0x6E, MRMSrcMem, (outs VR128:$dst), (ins i32mem:$src),
4504                        "movd\t{$src, $dst|$dst, $src}",
4505                        [(set VR128:$dst,
4506                          (v4i32 (X86vzmovl (v4i32 (scalar_to_vector
4507                                                    (loadi32 addr:$src))))))]>,
4508                                                    VEX;
4509 def MOVZDI2PDIrm : PDI<0x6E, MRMSrcMem, (outs VR128:$dst), (ins i32mem:$src),
4510                        "movd\t{$src, $dst|$dst, $src}",
4511                        [(set VR128:$dst,
4512                          (v4i32 (X86vzmovl (v4i32 (scalar_to_vector
4513                                                    (loadi32 addr:$src))))))]>;
4514 }
4515
4516 let Predicates = [HasAVX] in {
4517   // AVX 128-bit movd/movq instruction write zeros in the high 128-bit part.
4518   let AddedComplexity = 20 in {
4519     def : Pat<(v4i32 (X86vzmovl (bc_v4i32 (loadv4f32 addr:$src)))),
4520               (VMOVZDI2PDIrm addr:$src)>;
4521     def : Pat<(v4i32 (X86vzmovl (bc_v4i32 (loadv2i64 addr:$src)))),
4522               (VMOVZDI2PDIrm addr:$src)>;
4523   }
4524   // Use regular 128-bit instructions to match 256-bit scalar_to_vec+zext.
4525   def : Pat<(v8i32 (X86vzmovl (insert_subvector undef,
4526                                 (v4i32 (scalar_to_vector GR32:$src)),(i32 0)))),
4527             (SUBREG_TO_REG (i32 0), (VMOVZDI2PDIrr GR32:$src), sub_xmm)>;
4528   def : Pat<(v4i64 (X86vzmovl (insert_subvector undef,
4529                                 (v2i64 (scalar_to_vector GR64:$src)),(i32 0)))),
4530             (SUBREG_TO_REG (i64 0), (VMOVZQI2PQIrr GR64:$src), sub_xmm)>;
4531 }
4532
4533 let Predicates = [HasSSE2], AddedComplexity = 20 in {
4534   def : Pat<(v4i32 (X86vzmovl (bc_v4i32 (loadv4f32 addr:$src)))),
4535             (MOVZDI2PDIrm addr:$src)>;
4536   def : Pat<(v4i32 (X86vzmovl (bc_v4i32 (loadv2i64 addr:$src)))),
4537             (MOVZDI2PDIrm addr:$src)>;
4538 }
4539
4540 // These are the correct encodings of the instructions so that we know how to
4541 // read correct assembly, even though we continue to emit the wrong ones for
4542 // compatibility with Darwin's buggy assembler.
4543 def : InstAlias<"movq\t{$src, $dst|$dst, $src}",
4544                 (MOV64toPQIrr VR128:$dst, GR64:$src), 0>;
4545 def : InstAlias<"movq\t{$src, $dst|$dst, $src}",
4546                 (MOV64toSDrr FR64:$dst, GR64:$src), 0>;
4547 def : InstAlias<"movq\t{$src, $dst|$dst, $src}",
4548                 (MOVPQIto64rr GR64:$dst, VR128:$src), 0>;
4549 def : InstAlias<"movq\t{$src, $dst|$dst, $src}",
4550                 (MOVSDto64rr GR64:$dst, FR64:$src), 0>;
4551 def : InstAlias<"movq\t{$src, $dst|$dst, $src}",
4552                 (VMOVZQI2PQIrr VR128:$dst, GR64:$src), 0>;
4553 def : InstAlias<"movq\t{$src, $dst|$dst, $src}",
4554                 (MOVZQI2PQIrr VR128:$dst, GR64:$src), 0>;
4555
4556 //===---------------------------------------------------------------------===//
4557 // SSE2 - Move Quadword
4558 //===---------------------------------------------------------------------===//
4559
4560 //===---------------------------------------------------------------------===//
4561 // Move Quadword Int to Packed Quadword Int
4562 //
4563 def VMOVQI2PQIrm : I<0x7E, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
4564                     "vmovq\t{$src, $dst|$dst, $src}",
4565                     [(set VR128:$dst,
4566                       (v2i64 (scalar_to_vector (loadi64 addr:$src))))]>, XS,
4567                     VEX, Requires<[HasAVX]>;
4568 def MOVQI2PQIrm : I<0x7E, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
4569                     "movq\t{$src, $dst|$dst, $src}",
4570                     [(set VR128:$dst,
4571                       (v2i64 (scalar_to_vector (loadi64 addr:$src))))]>, XS,
4572                     Requires<[HasSSE2]>; // SSE2 instruction with XS Prefix
4573
4574 //===---------------------------------------------------------------------===//
4575 // Move Packed Quadword Int to Quadword Int
4576 //
4577 def VMOVPQI2QImr : VPDI<0xD6, MRMDestMem, (outs), (ins i64mem:$dst, VR128:$src),
4578                       "movq\t{$src, $dst|$dst, $src}",
4579                       [(store (i64 (vector_extract (v2i64 VR128:$src),
4580                                     (iPTR 0))), addr:$dst)]>, VEX;
4581 def MOVPQI2QImr : PDI<0xD6, MRMDestMem, (outs), (ins i64mem:$dst, VR128:$src),
4582                       "movq\t{$src, $dst|$dst, $src}",
4583                       [(store (i64 (vector_extract (v2i64 VR128:$src),
4584                                     (iPTR 0))), addr:$dst)]>;
4585
4586 //===---------------------------------------------------------------------===//
4587 // Store / copy lower 64-bits of a XMM register.
4588 //
4589 def VMOVLQ128mr : VPDI<0xD6, MRMDestMem, (outs), (ins i64mem:$dst, VR128:$src),
4590                      "movq\t{$src, $dst|$dst, $src}",
4591                      [(int_x86_sse2_storel_dq addr:$dst, VR128:$src)]>, VEX;
4592 def MOVLQ128mr : PDI<0xD6, MRMDestMem, (outs), (ins i64mem:$dst, VR128:$src),
4593                      "movq\t{$src, $dst|$dst, $src}",
4594                      [(int_x86_sse2_storel_dq addr:$dst, VR128:$src)]>;
4595
4596 let AddedComplexity = 20 in
4597 def VMOVZQI2PQIrm : I<0x7E, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
4598                      "vmovq\t{$src, $dst|$dst, $src}",
4599                      [(set VR128:$dst,
4600                        (v2i64 (X86vzmovl (v2i64 (scalar_to_vector
4601                                                  (loadi64 addr:$src))))))]>,
4602                      XS, VEX, Requires<[HasAVX]>;
4603
4604 let AddedComplexity = 20 in
4605 def MOVZQI2PQIrm : I<0x7E, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
4606                      "movq\t{$src, $dst|$dst, $src}",
4607                      [(set VR128:$dst,
4608                        (v2i64 (X86vzmovl (v2i64 (scalar_to_vector
4609                                                  (loadi64 addr:$src))))))]>,
4610                      XS, Requires<[HasSSE2]>;
4611
4612 let Predicates = [HasAVX], AddedComplexity = 20 in {
4613   def : Pat<(v2i64 (X86vzmovl (loadv2i64 addr:$src))),
4614             (VMOVZQI2PQIrm addr:$src)>;
4615   def : Pat<(v2i64 (X86vzmovl (bc_v2i64 (loadv4f32 addr:$src)))),
4616             (VMOVZQI2PQIrm addr:$src)>;
4617   def : Pat<(v2i64 (X86vzload addr:$src)),
4618             (VMOVZQI2PQIrm addr:$src)>;
4619 }
4620
4621 let Predicates = [HasSSE2], AddedComplexity = 20 in {
4622   def : Pat<(v2i64 (X86vzmovl (loadv2i64 addr:$src))),
4623             (MOVZQI2PQIrm addr:$src)>;
4624   def : Pat<(v2i64 (X86vzmovl (bc_v2i64 (loadv4f32 addr:$src)))),
4625             (MOVZQI2PQIrm addr:$src)>;
4626   def : Pat<(v2i64 (X86vzload addr:$src)), (MOVZQI2PQIrm addr:$src)>;
4627 }
4628
4629 let Predicates = [HasAVX] in {
4630 def : Pat<(v4i64 (X86vzload addr:$src)),
4631           (SUBREG_TO_REG (i32 0), (VMOVAPSrm addr:$src), sub_xmm)>;
4632 }
4633
4634 //===---------------------------------------------------------------------===//
4635 // Moving from XMM to XMM and clear upper 64 bits. Note, there is a bug in
4636 // IA32 document. movq xmm1, xmm2 does clear the high bits.
4637 //
4638 let AddedComplexity = 15 in
4639 def VMOVZPQILo2PQIrr : I<0x7E, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
4640                         "vmovq\t{$src, $dst|$dst, $src}",
4641                     [(set VR128:$dst, (v2i64 (X86vzmovl (v2i64 VR128:$src))))]>,
4642                       XS, VEX, Requires<[HasAVX]>;
4643 let AddedComplexity = 15 in
4644 def MOVZPQILo2PQIrr : I<0x7E, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
4645                         "movq\t{$src, $dst|$dst, $src}",
4646                     [(set VR128:$dst, (v2i64 (X86vzmovl (v2i64 VR128:$src))))]>,
4647                       XS, Requires<[HasSSE2]>;
4648
4649 let AddedComplexity = 20 in
4650 def VMOVZPQILo2PQIrm : I<0x7E, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
4651                         "vmovq\t{$src, $dst|$dst, $src}",
4652                     [(set VR128:$dst, (v2i64 (X86vzmovl
4653                                              (loadv2i64 addr:$src))))]>,
4654                       XS, VEX, Requires<[HasAVX]>;
4655 let AddedComplexity = 20 in {
4656 def MOVZPQILo2PQIrm : I<0x7E, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
4657                         "movq\t{$src, $dst|$dst, $src}",
4658                     [(set VR128:$dst, (v2i64 (X86vzmovl
4659                                              (loadv2i64 addr:$src))))]>,
4660                       XS, Requires<[HasSSE2]>;
4661 }
4662
4663 let AddedComplexity = 20 in {
4664   let Predicates = [HasAVX] in {
4665     def : Pat<(v2i64 (X86vzmovl (loadv2i64 addr:$src))),
4666               (VMOVZPQILo2PQIrm addr:$src)>;
4667     def : Pat<(v2f64 (X86vzmovl (v2f64 VR128:$src))),
4668               (VMOVZPQILo2PQIrr VR128:$src)>;
4669   }
4670   let Predicates = [HasSSE2] in {
4671     def : Pat<(v2i64 (X86vzmovl (loadv2i64 addr:$src))),
4672               (MOVZPQILo2PQIrm addr:$src)>;
4673     def : Pat<(v2f64 (X86vzmovl (v2f64 VR128:$src))),
4674               (MOVZPQILo2PQIrr VR128:$src)>;
4675   }
4676 }
4677
4678 // Instructions to match in the assembler
4679 def VMOVQs64rr : VPDI<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR64:$src),
4680                       "movq\t{$src, $dst|$dst, $src}", []>, VEX, VEX_W;
4681 def VMOVQd64rr : VPDI<0x7E, MRMDestReg, (outs GR64:$dst), (ins VR128:$src),
4682                       "movq\t{$src, $dst|$dst, $src}", []>, VEX, VEX_W;
4683 // Recognize "movd" with GR64 destination, but encode as a "movq"
4684 def VMOVQd64rr_alt : VPDI<0x7E, MRMDestReg, (outs GR64:$dst), (ins VR128:$src),
4685                           "movd\t{$src, $dst|$dst, $src}", []>, VEX, VEX_W;
4686
4687 // Instructions for the disassembler
4688 // xr = XMM register
4689 // xm = mem64
4690
4691 let Predicates = [HasAVX] in
4692 def VMOVQxrxr: I<0x7E, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
4693                  "vmovq\t{$src, $dst|$dst, $src}", []>, VEX, XS;
4694 def MOVQxrxr : I<0x7E, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
4695                  "movq\t{$src, $dst|$dst, $src}", []>, XS;
4696
4697 //===---------------------------------------------------------------------===//
4698 // SSE3 - Conversion Instructions
4699 //===---------------------------------------------------------------------===//
4700
4701 // Convert Packed Double FP to Packed DW Integers
4702 let Predicates = [HasAVX] in {
4703 // The assembler can recognize rr 256-bit instructions by seeing a ymm
4704 // register, but the same isn't true when using memory operands instead.
4705 // Provide other assembly rr and rm forms to address this explicitly.
4706 def VCVTPD2DQrr  : S3DI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
4707                        "vcvtpd2dq\t{$src, $dst|$dst, $src}", []>, VEX;
4708 def VCVTPD2DQXrYr  : S3DI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR256:$src),
4709                        "vcvtpd2dq\t{$src, $dst|$dst, $src}", []>, VEX;
4710
4711 // XMM only
4712 def VCVTPD2DQXrr : S3DI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
4713                       "vcvtpd2dqx\t{$src, $dst|$dst, $src}", []>, VEX;
4714 def VCVTPD2DQXrm : S3DI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
4715                       "vcvtpd2dqx\t{$src, $dst|$dst, $src}", []>, VEX;
4716
4717 // YMM only
4718 def VCVTPD2DQYrr : S3DI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR256:$src),
4719                       "vcvtpd2dqy\t{$src, $dst|$dst, $src}", []>, VEX;
4720 def VCVTPD2DQYrm : S3DI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f256mem:$src),
4721                       "vcvtpd2dqy\t{$src, $dst|$dst, $src}", []>, VEX, VEX_L;
4722 }
4723
4724 def CVTPD2DQrm  : S3DI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
4725                        "cvtpd2dq\t{$src, $dst|$dst, $src}", []>;
4726 def CVTPD2DQrr  : S3DI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
4727                        "cvtpd2dq\t{$src, $dst|$dst, $src}", []>;
4728
4729 def : Pat<(v4i32 (fp_to_sint (v4f64 VR256:$src))),
4730           (VCVTTPD2DQYrr VR256:$src)>;
4731 def : Pat<(v4i32 (fp_to_sint (memopv4f64 addr:$src))),
4732           (VCVTTPD2DQYrm addr:$src)>;
4733
4734 // Convert Packed DW Integers to Packed Double FP
4735 let Predicates = [HasAVX] in {
4736 def VCVTDQ2PDrm  : S3SI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
4737                      "vcvtdq2pd\t{$src, $dst|$dst, $src}", []>, VEX;
4738 def VCVTDQ2PDrr  : S3SI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
4739                      "vcvtdq2pd\t{$src, $dst|$dst, $src}", []>, VEX;
4740 def VCVTDQ2PDYrm  : S3SI<0xE6, MRMSrcMem, (outs VR256:$dst), (ins f128mem:$src),
4741                      "vcvtdq2pd\t{$src, $dst|$dst, $src}", []>, VEX;
4742 def VCVTDQ2PDYrr  : S3SI<0xE6, MRMSrcReg, (outs VR256:$dst), (ins VR128:$src),
4743                      "vcvtdq2pd\t{$src, $dst|$dst, $src}", []>, VEX;
4744 }
4745
4746 def CVTDQ2PDrm  : S3SI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
4747                        "cvtdq2pd\t{$src, $dst|$dst, $src}", []>;
4748 def CVTDQ2PDrr  : S3SI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
4749                        "cvtdq2pd\t{$src, $dst|$dst, $src}", []>;
4750
4751 // AVX 256-bit register conversion intrinsics
4752 def : Pat<(int_x86_avx_cvtdq2_pd_256 VR128:$src),
4753            (VCVTDQ2PDYrr VR128:$src)>;
4754 def : Pat<(int_x86_avx_cvtdq2_pd_256 (bitconvert (memopv2i64 addr:$src))),
4755            (VCVTDQ2PDYrm addr:$src)>;
4756
4757 def : Pat<(int_x86_avx_cvt_pd2dq_256 VR256:$src),
4758           (VCVTPD2DQYrr VR256:$src)>;
4759 def : Pat<(int_x86_avx_cvt_pd2dq_256 (memopv4f64 addr:$src)),
4760           (VCVTPD2DQYrm addr:$src)>;
4761
4762 def : Pat<(v4f64 (sint_to_fp (v4i32 VR128:$src))),
4763           (VCVTDQ2PDYrr VR128:$src)>;
4764 def : Pat<(v4f64 (sint_to_fp (bc_v4i32 (memopv2i64 addr:$src)))),
4765           (VCVTDQ2PDYrm addr:$src)>;
4766
4767 //===---------------------------------------------------------------------===//
4768 // SSE3 - Replicate Single FP - MOVSHDUP and MOVSLDUP
4769 //===---------------------------------------------------------------------===//
4770 multiclass sse3_replicate_sfp<bits<8> op, SDNode OpNode, string OpcodeStr,
4771                               ValueType vt, RegisterClass RC, PatFrag mem_frag,
4772                               X86MemOperand x86memop> {
4773 def rr : S3SI<op, MRMSrcReg, (outs RC:$dst), (ins RC:$src),
4774                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
4775                       [(set RC:$dst, (vt (OpNode RC:$src)))]>;
4776 def rm : S3SI<op, MRMSrcMem, (outs RC:$dst), (ins x86memop:$src),
4777                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
4778                       [(set RC:$dst, (OpNode (mem_frag addr:$src)))]>;
4779 }
4780
4781 let Predicates = [HasAVX] in {
4782   defm VMOVSHDUP  : sse3_replicate_sfp<0x16, X86Movshdup, "vmovshdup",
4783                                        v4f32, VR128, memopv4f32, f128mem>, VEX;
4784   defm VMOVSLDUP  : sse3_replicate_sfp<0x12, X86Movsldup, "vmovsldup",
4785                                        v4f32, VR128, memopv4f32, f128mem>, VEX;
4786   defm VMOVSHDUPY : sse3_replicate_sfp<0x16, X86Movshdup, "vmovshdup",
4787                                        v8f32, VR256, memopv8f32, f256mem>, VEX;
4788   defm VMOVSLDUPY : sse3_replicate_sfp<0x12, X86Movsldup, "vmovsldup",
4789                                        v8f32, VR256, memopv8f32, f256mem>, VEX;
4790 }
4791 defm MOVSHDUP : sse3_replicate_sfp<0x16, X86Movshdup, "movshdup", v4f32, VR128,
4792                                    memopv4f32, f128mem>;
4793 defm MOVSLDUP : sse3_replicate_sfp<0x12, X86Movsldup, "movsldup", v4f32, VR128,
4794                                    memopv4f32, f128mem>;
4795
4796 let Predicates = [HasAVX] in {
4797   def : Pat<(v4i32 (X86Movshdup VR128:$src)),
4798             (VMOVSHDUPrr VR128:$src)>;
4799   def : Pat<(v4i32 (X86Movshdup (bc_v4i32 (memopv2i64 addr:$src)))),
4800             (VMOVSHDUPrm addr:$src)>;
4801   def : Pat<(v4i32 (X86Movsldup VR128:$src)),
4802             (VMOVSLDUPrr VR128:$src)>;
4803   def : Pat<(v4i32 (X86Movsldup (bc_v4i32 (memopv2i64 addr:$src)))),
4804             (VMOVSLDUPrm addr:$src)>;
4805   def : Pat<(v8i32 (X86Movshdup VR256:$src)),
4806             (VMOVSHDUPYrr VR256:$src)>;
4807   def : Pat<(v8i32 (X86Movshdup (bc_v8i32 (memopv4i64 addr:$src)))),
4808             (VMOVSHDUPYrm addr:$src)>;
4809   def : Pat<(v8i32 (X86Movsldup VR256:$src)),
4810             (VMOVSLDUPYrr VR256:$src)>;
4811   def : Pat<(v8i32 (X86Movsldup (bc_v8i32 (memopv4i64 addr:$src)))),
4812             (VMOVSLDUPYrm addr:$src)>;
4813 }
4814
4815 let Predicates = [HasSSE3] in {
4816   def : Pat<(v4i32 (X86Movshdup VR128:$src)),
4817             (MOVSHDUPrr VR128:$src)>;
4818   def : Pat<(v4i32 (X86Movshdup (bc_v4i32 (memopv2i64 addr:$src)))),
4819             (MOVSHDUPrm addr:$src)>;
4820   def : Pat<(v4i32 (X86Movsldup VR128:$src)),
4821             (MOVSLDUPrr VR128:$src)>;
4822   def : Pat<(v4i32 (X86Movsldup (bc_v4i32 (memopv2i64 addr:$src)))),
4823             (MOVSLDUPrm addr:$src)>;
4824 }
4825
4826 //===---------------------------------------------------------------------===//
4827 // SSE3 - Replicate Double FP - MOVDDUP
4828 //===---------------------------------------------------------------------===//
4829
4830 multiclass sse3_replicate_dfp<string OpcodeStr> {
4831 def rr  : S3DI<0x12, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
4832                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
4833                     [(set VR128:$dst,(v2f64 (movddup VR128:$src, (undef))))]>;
4834 def rm  : S3DI<0x12, MRMSrcMem, (outs VR128:$dst), (ins f64mem:$src),
4835                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
4836                     [(set VR128:$dst,
4837                       (v2f64 (movddup (scalar_to_vector (loadf64 addr:$src)),
4838                                       (undef))))]>;
4839 }
4840
4841 // FIXME: Merge with above classe when there're patterns for the ymm version
4842 multiclass sse3_replicate_dfp_y<string OpcodeStr> {
4843 let Predicates = [HasAVX] in {
4844   def rr  : S3DI<0x12, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
4845                       !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
4846                       []>;
4847   def rm  : S3DI<0x12, MRMSrcMem, (outs VR256:$dst), (ins f256mem:$src),
4848                       !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
4849                       []>;
4850   }
4851 }
4852
4853 defm MOVDDUP : sse3_replicate_dfp<"movddup">;
4854 defm VMOVDDUP  : sse3_replicate_dfp<"vmovddup">, VEX;
4855 defm VMOVDDUPY : sse3_replicate_dfp_y<"vmovddup">, VEX;
4856
4857 let Predicates = [HasAVX] in {
4858   def : Pat<(movddup (bc_v2f64 (v2i64 (scalar_to_vector (loadi64 addr:$src)))),
4859                    (undef)),
4860             (VMOVDDUPrm addr:$src)>;
4861   let AddedComplexity = 5 in {
4862   def : Pat<(movddup (memopv2f64 addr:$src), (undef)), (VMOVDDUPrm addr:$src)>;
4863   def : Pat<(movddup (bc_v4f32 (memopv2f64 addr:$src)), (undef)),
4864             (VMOVDDUPrm addr:$src)>;
4865   def : Pat<(movddup (memopv2i64 addr:$src), (undef)), (VMOVDDUPrm addr:$src)>;
4866   def : Pat<(movddup (bc_v4i32 (memopv2i64 addr:$src)), (undef)),
4867             (VMOVDDUPrm addr:$src)>;
4868   }
4869   def : Pat<(X86Movddup (memopv2f64 addr:$src)),
4870             (VMOVDDUPrm addr:$src)>, Requires<[HasAVX]>;
4871   def : Pat<(X86Movddup (bc_v2f64 (memopv4f32 addr:$src))),
4872             (VMOVDDUPrm addr:$src)>, Requires<[HasAVX]>;
4873   def : Pat<(X86Movddup (bc_v2f64 (memopv2i64 addr:$src))),
4874             (VMOVDDUPrm addr:$src)>, Requires<[HasAVX]>;
4875   def : Pat<(X86Movddup (v2f64 (scalar_to_vector (loadf64 addr:$src)))),
4876             (VMOVDDUPrm addr:$src)>, Requires<[HasAVX]>;
4877   def : Pat<(X86Movddup (bc_v2f64
4878                              (v2i64 (scalar_to_vector (loadi64 addr:$src))))),
4879             (VMOVDDUPrm addr:$src)>, Requires<[HasAVX]>;
4880
4881   // 256-bit version
4882   def : Pat<(X86Movddup (memopv4f64 addr:$src)),
4883             (VMOVDDUPYrm addr:$src)>;
4884   def : Pat<(X86Movddup (memopv4i64 addr:$src)),
4885             (VMOVDDUPYrm addr:$src)>;
4886   def : Pat<(X86Movddup (v4f64 (scalar_to_vector (loadf64 addr:$src)))),
4887             (VMOVDDUPYrm addr:$src)>;
4888   def : Pat<(X86Movddup (v4i64 (scalar_to_vector (loadi64 addr:$src)))),
4889             (VMOVDDUPYrm addr:$src)>;
4890   def : Pat<(X86Movddup (v4f64 VR256:$src)),
4891             (VMOVDDUPYrr VR256:$src)>;
4892   def : Pat<(X86Movddup (v4i64 VR256:$src)),
4893             (VMOVDDUPYrr VR256:$src)>;
4894 }
4895
4896 let Predicates = [HasSSE3] in {
4897   def : Pat<(movddup (bc_v2f64 (v2i64 (scalar_to_vector (loadi64 addr:$src)))),
4898                    (undef)),
4899             (MOVDDUPrm addr:$src)>;
4900   let AddedComplexity = 5 in {
4901   def : Pat<(movddup (memopv2f64 addr:$src), (undef)), (MOVDDUPrm addr:$src)>;
4902   def : Pat<(movddup (bc_v4f32 (memopv2f64 addr:$src)), (undef)),
4903             (MOVDDUPrm addr:$src)>;
4904   def : Pat<(movddup (memopv2i64 addr:$src), (undef)), (MOVDDUPrm addr:$src)>;
4905   def : Pat<(movddup (bc_v4i32 (memopv2i64 addr:$src)), (undef)),
4906             (MOVDDUPrm addr:$src)>;
4907   }
4908   def : Pat<(X86Movddup (memopv2f64 addr:$src)),
4909             (MOVDDUPrm addr:$src)>;
4910   def : Pat<(X86Movddup (bc_v2f64 (memopv4f32 addr:$src))),
4911             (MOVDDUPrm addr:$src)>;
4912   def : Pat<(X86Movddup (bc_v2f64 (memopv2i64 addr:$src))),
4913             (MOVDDUPrm addr:$src)>;
4914   def : Pat<(X86Movddup (v2f64 (scalar_to_vector (loadf64 addr:$src)))),
4915             (MOVDDUPrm addr:$src)>;
4916   def : Pat<(X86Movddup (bc_v2f64
4917                              (v2i64 (scalar_to_vector (loadi64 addr:$src))))),
4918             (MOVDDUPrm addr:$src)>;
4919 }
4920
4921 //===---------------------------------------------------------------------===//
4922 // SSE3 - Move Unaligned Integer
4923 //===---------------------------------------------------------------------===//
4924
4925 let Predicates = [HasAVX] in {
4926   def VLDDQUrm : S3DI<0xF0, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
4927                    "vlddqu\t{$src, $dst|$dst, $src}",
4928                    [(set VR128:$dst, (int_x86_sse3_ldu_dq addr:$src))]>, VEX;
4929   def VLDDQUYrm : S3DI<0xF0, MRMSrcMem, (outs VR256:$dst), (ins i256mem:$src),
4930                    "vlddqu\t{$src, $dst|$dst, $src}",
4931                    [(set VR256:$dst, (int_x86_avx_ldu_dq_256 addr:$src))]>, VEX;
4932 }
4933 def LDDQUrm : S3DI<0xF0, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
4934                    "lddqu\t{$src, $dst|$dst, $src}",
4935                    [(set VR128:$dst, (int_x86_sse3_ldu_dq addr:$src))]>;
4936
4937 //===---------------------------------------------------------------------===//
4938 // SSE3 - Arithmetic
4939 //===---------------------------------------------------------------------===//
4940
4941 multiclass sse3_addsub<Intrinsic Int, string OpcodeStr, RegisterClass RC,
4942                        X86MemOperand x86memop, bit Is2Addr = 1> {
4943   def rr : I<0xD0, MRMSrcReg,
4944        (outs RC:$dst), (ins RC:$src1, RC:$src2),
4945        !if(Is2Addr,
4946            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
4947            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
4948        [(set RC:$dst, (Int RC:$src1, RC:$src2))]>;
4949   def rm : I<0xD0, MRMSrcMem,
4950        (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
4951        !if(Is2Addr,
4952            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
4953            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
4954        [(set RC:$dst, (Int RC:$src1, (memop addr:$src2)))]>;
4955 }
4956
4957 let Predicates = [HasAVX] in {
4958   let ExeDomain = SSEPackedSingle in {
4959     defm VADDSUBPS : sse3_addsub<int_x86_sse3_addsub_ps, "vaddsubps", VR128,
4960                                  f128mem, 0>, TB, XD, VEX_4V;
4961     defm VADDSUBPSY : sse3_addsub<int_x86_avx_addsub_ps_256, "vaddsubps", VR256,
4962                                  f256mem, 0>, TB, XD, VEX_4V;
4963   }
4964   let ExeDomain = SSEPackedDouble in {
4965     defm VADDSUBPD : sse3_addsub<int_x86_sse3_addsub_pd, "vaddsubpd", VR128,
4966                                  f128mem, 0>, TB, OpSize, VEX_4V;
4967     defm VADDSUBPDY : sse3_addsub<int_x86_avx_addsub_pd_256, "vaddsubpd", VR256,
4968                                  f256mem, 0>, TB, OpSize, VEX_4V;
4969   }
4970 }
4971 let Constraints = "$src1 = $dst", Predicates = [HasSSE3] in {
4972   let ExeDomain = SSEPackedSingle in
4973   defm ADDSUBPS : sse3_addsub<int_x86_sse3_addsub_ps, "addsubps", VR128,
4974                               f128mem>, TB, XD;
4975   let ExeDomain = SSEPackedDouble in
4976   defm ADDSUBPD : sse3_addsub<int_x86_sse3_addsub_pd, "addsubpd", VR128,
4977                               f128mem>, TB, OpSize;
4978 }
4979
4980 //===---------------------------------------------------------------------===//
4981 // SSE3 Instructions
4982 //===---------------------------------------------------------------------===//
4983
4984 // Horizontal ops
4985 multiclass S3D_Int<bits<8> o, string OpcodeStr, ValueType vt, RegisterClass RC,
4986                    X86MemOperand x86memop, SDNode OpNode, bit Is2Addr = 1> {
4987   def rr : S3DI<o, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
4988        !if(Is2Addr,
4989          !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
4990          !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
4991       [(set RC:$dst, (vt (OpNode RC:$src1, RC:$src2)))]>;
4992
4993   def rm : S3DI<o, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
4994        !if(Is2Addr,
4995          !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
4996          !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
4997       [(set RC:$dst, (vt (OpNode RC:$src1, (memop addr:$src2))))]>;
4998 }
4999 multiclass S3_Int<bits<8> o, string OpcodeStr, ValueType vt, RegisterClass RC,
5000                   X86MemOperand x86memop, SDNode OpNode, bit Is2Addr = 1> {
5001   def rr : S3I<o, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
5002        !if(Is2Addr,
5003          !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5004          !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5005       [(set RC:$dst, (vt (OpNode RC:$src1, RC:$src2)))]>;
5006
5007   def rm : S3I<o, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
5008        !if(Is2Addr,
5009          !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5010          !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5011       [(set RC:$dst, (vt (OpNode RC:$src1, (memop addr:$src2))))]>;
5012 }
5013
5014 let Predicates = [HasAVX] in {
5015   let ExeDomain = SSEPackedSingle in {
5016     defm VHADDPS  : S3D_Int<0x7C, "vhaddps", v4f32, VR128, f128mem,
5017                             X86fhadd, 0>, VEX_4V;
5018     defm VHSUBPS  : S3D_Int<0x7D, "vhsubps", v4f32, VR128, f128mem,
5019                             X86fhsub, 0>, VEX_4V;
5020     defm VHADDPSY : S3D_Int<0x7C, "vhaddps", v8f32, VR256, f256mem,
5021                             X86fhadd, 0>, VEX_4V;
5022     defm VHSUBPSY : S3D_Int<0x7D, "vhsubps", v8f32, VR256, f256mem,
5023                             X86fhsub, 0>, VEX_4V;
5024   }
5025   let ExeDomain = SSEPackedDouble in {
5026     defm VHADDPD  : S3_Int <0x7C, "vhaddpd", v2f64, VR128, f128mem,
5027                             X86fhadd, 0>, VEX_4V;
5028     defm VHSUBPD  : S3_Int <0x7D, "vhsubpd", v2f64, VR128, f128mem,
5029                             X86fhsub, 0>, VEX_4V;
5030     defm VHADDPDY : S3_Int <0x7C, "vhaddpd", v4f64, VR256, f256mem,
5031                             X86fhadd, 0>, VEX_4V;
5032     defm VHSUBPDY : S3_Int <0x7D, "vhsubpd", v4f64, VR256, f256mem,
5033                             X86fhsub, 0>, VEX_4V;
5034   }
5035 }
5036
5037 let Constraints = "$src1 = $dst" in {
5038   let ExeDomain = SSEPackedSingle in {
5039     defm HADDPS : S3D_Int<0x7C, "haddps", v4f32, VR128, f128mem, X86fhadd>;
5040     defm HSUBPS : S3D_Int<0x7D, "hsubps", v4f32, VR128, f128mem, X86fhsub>;
5041   }
5042   let ExeDomain = SSEPackedDouble in {
5043     defm HADDPD : S3_Int<0x7C, "haddpd", v2f64, VR128, f128mem, X86fhadd>;
5044     defm HSUBPD : S3_Int<0x7D, "hsubpd", v2f64, VR128, f128mem, X86fhsub>;
5045   }
5046 }
5047
5048 //===---------------------------------------------------------------------===//
5049 // SSSE3 - Packed Absolute Instructions
5050 //===---------------------------------------------------------------------===//
5051
5052
5053 /// SS3I_unop_rm_int - Simple SSSE3 unary op whose type can be v*{i8,i16,i32}.
5054 multiclass SS3I_unop_rm_int<bits<8> opc, string OpcodeStr,
5055                             Intrinsic IntId128> {
5056   def rr128 : SS38I<opc, MRMSrcReg, (outs VR128:$dst),
5057                     (ins VR128:$src),
5058                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5059                     [(set VR128:$dst, (IntId128 VR128:$src))]>,
5060                     OpSize;
5061
5062   def rm128 : SS38I<opc, MRMSrcMem, (outs VR128:$dst),
5063                     (ins i128mem:$src),
5064                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5065                     [(set VR128:$dst,
5066                       (IntId128
5067                        (bitconvert (memopv2i64 addr:$src))))]>, OpSize;
5068 }
5069
5070 /// SS3I_unop_rm_int_y - Simple SSSE3 unary op whose type can be v*{i8,i16,i32}.
5071 multiclass SS3I_unop_rm_int_y<bits<8> opc, string OpcodeStr,
5072                               Intrinsic IntId256> {
5073   def rr256 : SS38I<opc, MRMSrcReg, (outs VR256:$dst),
5074                     (ins VR256:$src),
5075                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5076                     [(set VR256:$dst, (IntId256 VR256:$src))]>,
5077                     OpSize;
5078
5079   def rm256 : SS38I<opc, MRMSrcMem, (outs VR256:$dst),
5080                     (ins i256mem:$src),
5081                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5082                     [(set VR256:$dst,
5083                       (IntId256
5084                        (bitconvert (memopv4i64 addr:$src))))]>, OpSize;
5085 }
5086
5087 let Predicates = [HasAVX] in {
5088   defm VPABSB  : SS3I_unop_rm_int<0x1C, "vpabsb",
5089                                   int_x86_ssse3_pabs_b_128>, VEX;
5090   defm VPABSW  : SS3I_unop_rm_int<0x1D, "vpabsw",
5091                                   int_x86_ssse3_pabs_w_128>, VEX;
5092   defm VPABSD  : SS3I_unop_rm_int<0x1E, "vpabsd",
5093                                   int_x86_ssse3_pabs_d_128>, VEX;
5094 }
5095
5096 let Predicates = [HasAVX2] in {
5097   defm VPABSB  : SS3I_unop_rm_int_y<0x1C, "vpabsb",
5098                                     int_x86_avx2_pabs_b>, VEX;
5099   defm VPABSW  : SS3I_unop_rm_int_y<0x1D, "vpabsw",
5100                                     int_x86_avx2_pabs_w>, VEX;
5101   defm VPABSD  : SS3I_unop_rm_int_y<0x1E, "vpabsd",
5102                                     int_x86_avx2_pabs_d>, VEX;
5103 }
5104
5105 defm PABSB : SS3I_unop_rm_int<0x1C, "pabsb",
5106                               int_x86_ssse3_pabs_b_128>;
5107 defm PABSW : SS3I_unop_rm_int<0x1D, "pabsw",
5108                               int_x86_ssse3_pabs_w_128>;
5109 defm PABSD : SS3I_unop_rm_int<0x1E, "pabsd",
5110                               int_x86_ssse3_pabs_d_128>;
5111
5112 //===---------------------------------------------------------------------===//
5113 // SSSE3 - Packed Binary Operator Instructions
5114 //===---------------------------------------------------------------------===//
5115
5116 /// SS3I_binop_rm - Simple SSSE3 bin op
5117 multiclass SS3I_binop_rm<bits<8> opc, string OpcodeStr, SDNode OpNode,
5118                          ValueType OpVT, RegisterClass RC, PatFrag memop_frag,
5119                          X86MemOperand x86memop, bit Is2Addr = 1> {
5120   let isCommutable = 1 in
5121   def rr : SS38I<opc, MRMSrcReg, (outs RC:$dst),
5122        (ins RC:$src1, RC:$src2),
5123        !if(Is2Addr,
5124          !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5125          !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5126        [(set RC:$dst, (OpVT (OpNode RC:$src1, RC:$src2)))]>,
5127        OpSize;
5128   def rm : SS38I<opc, MRMSrcMem, (outs RC:$dst),
5129        (ins RC:$src1, x86memop:$src2),
5130        !if(Is2Addr,
5131          !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5132          !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5133        [(set RC:$dst,
5134          (OpVT (OpNode RC:$src1,
5135           (bitconvert (memop_frag addr:$src2)))))]>, OpSize;
5136 }
5137
5138 /// SS3I_binop_rm_int - Simple SSSE3 bin op whose type can be v*{i8,i16,i32}.
5139 multiclass SS3I_binop_rm_int<bits<8> opc, string OpcodeStr,
5140                              Intrinsic IntId128, bit Is2Addr = 1> {
5141   let isCommutable = 1 in
5142   def rr128 : SS38I<opc, MRMSrcReg, (outs VR128:$dst),
5143        (ins VR128:$src1, VR128:$src2),
5144        !if(Is2Addr,
5145          !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5146          !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5147        [(set VR128:$dst, (IntId128 VR128:$src1, VR128:$src2))]>,
5148        OpSize;
5149   def rm128 : SS38I<opc, MRMSrcMem, (outs VR128:$dst),
5150        (ins VR128:$src1, i128mem:$src2),
5151        !if(Is2Addr,
5152          !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5153          !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5154        [(set VR128:$dst,
5155          (IntId128 VR128:$src1,
5156           (bitconvert (memopv2i64 addr:$src2))))]>, OpSize;
5157 }
5158
5159 multiclass SS3I_binop_rm_int_y<bits<8> opc, string OpcodeStr,
5160                                Intrinsic IntId256> {
5161   let isCommutable = 1 in
5162   def rr256 : SS38I<opc, MRMSrcReg, (outs VR256:$dst),
5163        (ins VR256:$src1, VR256:$src2),
5164        !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5165        [(set VR256:$dst, (IntId256 VR256:$src1, VR256:$src2))]>,
5166        OpSize;
5167   def rm256 : SS38I<opc, MRMSrcMem, (outs VR256:$dst),
5168        (ins VR256:$src1, i256mem:$src2),
5169        !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5170        [(set VR256:$dst,
5171          (IntId256 VR256:$src1,
5172           (bitconvert (memopv4i64 addr:$src2))))]>, OpSize;
5173 }
5174
5175 let ImmT = NoImm, Predicates = [HasAVX] in {
5176 let isCommutable = 0 in {
5177   defm VPHADDW    : SS3I_binop_rm<0x01, "vphaddw", X86hadd, v8i16, VR128,
5178                                   memopv2i64, i128mem, 0>, VEX_4V;
5179   defm VPHADDD    : SS3I_binop_rm<0x02, "vphaddd", X86hadd, v4i32, VR128,
5180                                   memopv2i64, i128mem, 0>, VEX_4V;
5181   defm VPHSUBW    : SS3I_binop_rm<0x05, "vphsubw", X86hsub, v8i16, VR128,
5182                                   memopv2i64, i128mem, 0>, VEX_4V;
5183   defm VPHSUBD    : SS3I_binop_rm<0x06, "vphsubd", X86hsub, v4i32, VR128,
5184                                   memopv2i64, i128mem, 0>, VEX_4V;
5185   defm VPSIGNB    : SS3I_binop_rm<0x08, "vpsignb", X86psign, v16i8, VR128,
5186                                   memopv2i64, i128mem, 0>, VEX_4V;
5187   defm VPSIGNW    : SS3I_binop_rm<0x09, "vpsignw", X86psign, v8i16, VR128,
5188                                   memopv2i64, i128mem, 0>, VEX_4V;
5189   defm VPSIGND    : SS3I_binop_rm<0x0A, "vpsignd", X86psign, v4i32, VR128,
5190                                   memopv2i64, i128mem, 0>, VEX_4V;
5191   defm VPSHUFB    : SS3I_binop_rm<0x00, "vpshufb", X86pshufb, v16i8, VR128,
5192                                   memopv2i64, i128mem, 0>, VEX_4V;
5193   defm VPHADDSW   : SS3I_binop_rm_int<0x03, "vphaddsw",
5194                                       int_x86_ssse3_phadd_sw_128, 0>, VEX_4V;
5195   defm VPHSUBSW   : SS3I_binop_rm_int<0x07, "vphsubsw",
5196                                       int_x86_ssse3_phsub_sw_128, 0>, VEX_4V;
5197   defm VPMADDUBSW : SS3I_binop_rm_int<0x04, "vpmaddubsw",
5198                                       int_x86_ssse3_pmadd_ub_sw_128, 0>, VEX_4V;
5199 }
5200 defm VPMULHRSW    : SS3I_binop_rm_int<0x0B, "vpmulhrsw",
5201                                       int_x86_ssse3_pmul_hr_sw_128, 0>, VEX_4V;
5202 }
5203
5204 let ImmT = NoImm, Predicates = [HasAVX2] in {
5205 let isCommutable = 0 in {
5206   defm VPHADDWY   : SS3I_binop_rm<0x01, "vphaddw", X86hadd, v16i16, VR256,
5207                                   memopv4i64, i256mem, 0>, VEX_4V;
5208   defm VPHADDDY   : SS3I_binop_rm<0x02, "vphaddd", X86hadd, v8i32, VR256,
5209                                   memopv4i64, i256mem, 0>, VEX_4V;
5210   defm VPHSUBWY   : SS3I_binop_rm<0x05, "vphsubw", X86hsub, v16i16, VR256,
5211                                   memopv4i64, i256mem, 0>, VEX_4V;
5212   defm VPHSUBDY   : SS3I_binop_rm<0x06, "vphsubd", X86hsub, v8i32, VR256,
5213                                   memopv4i64, i256mem, 0>, VEX_4V;
5214   defm VPSIGNBY   : SS3I_binop_rm<0x08, "vpsignb", X86psign, v32i8, VR256,
5215                                   memopv4i64, i256mem, 0>, VEX_4V;
5216   defm VPSIGNWY   : SS3I_binop_rm<0x09, "vpsignw", X86psign, v16i16, VR256,
5217                                   memopv4i64, i256mem, 0>, VEX_4V;
5218   defm VPSIGNDY   : SS3I_binop_rm<0x0A, "vpsignd", X86psign, v8i32, VR256,
5219                                   memopv4i64, i256mem, 0>, VEX_4V;
5220   defm VPSHUFBY   : SS3I_binop_rm<0x00, "vpshufb", X86pshufb, v32i8, VR256,
5221                                   memopv4i64, i256mem, 0>, VEX_4V;
5222   defm VPHADDSW   : SS3I_binop_rm_int_y<0x03, "vphaddsw",
5223                                         int_x86_avx2_phadd_sw>, VEX_4V;
5224   defm VPHSUBSW   : SS3I_binop_rm_int_y<0x07, "vphsubsw",
5225                                         int_x86_avx2_phsub_sw>, VEX_4V;
5226   defm VPMADDUBSW : SS3I_binop_rm_int_y<0x04, "vpmaddubsw",
5227                                         int_x86_avx2_pmadd_ub_sw>, VEX_4V;
5228 }
5229 defm VPMULHRSW    : SS3I_binop_rm_int_y<0x0B, "vpmulhrsw",
5230                                         int_x86_avx2_pmul_hr_sw>, VEX_4V;
5231 }
5232
5233 // None of these have i8 immediate fields.
5234 let ImmT = NoImm, Constraints = "$src1 = $dst" in {
5235 let isCommutable = 0 in {
5236   defm PHADDW    : SS3I_binop_rm<0x01, "phaddw", X86hadd, v8i16, VR128,
5237                                  memopv2i64, i128mem>;
5238   defm PHADDD    : SS3I_binop_rm<0x02, "phaddd", X86hadd, v4i32, VR128,
5239                                  memopv2i64, i128mem>;
5240   defm PHSUBW    : SS3I_binop_rm<0x05, "phsubw", X86hsub, v8i16, VR128,
5241                                  memopv2i64, i128mem>;
5242   defm PHSUBD    : SS3I_binop_rm<0x06, "phsubd", X86hsub, v4i32, VR128,
5243                                  memopv2i64, i128mem>;
5244   defm PSIGNB    : SS3I_binop_rm<0x08, "psignb", X86psign, v16i8, VR128,
5245                                  memopv2i64, i128mem>;
5246   defm PSIGNW    : SS3I_binop_rm<0x09, "psignw", X86psign, v8i16, VR128,
5247                                  memopv2i64, i128mem>;
5248   defm PSIGND    : SS3I_binop_rm<0x0A, "psignd", X86psign, v4i32, VR128,
5249                                  memopv2i64, i128mem>;
5250   defm PSHUFB    : SS3I_binop_rm<0x00, "pshufb", X86pshufb, v16i8, VR128,
5251                                  memopv2i64, i128mem>;
5252   defm PHADDSW   : SS3I_binop_rm_int<0x03, "phaddsw",
5253                                      int_x86_ssse3_phadd_sw_128>;
5254   defm PHSUBSW   : SS3I_binop_rm_int<0x07, "phsubsw",
5255                                      int_x86_ssse3_phsub_sw_128>;
5256   defm PMADDUBSW : SS3I_binop_rm_int<0x04, "pmaddubsw",
5257                                      int_x86_ssse3_pmadd_ub_sw_128>;
5258 }
5259 defm PMULHRSW    : SS3I_binop_rm_int<0x0B, "pmulhrsw",
5260                                      int_x86_ssse3_pmul_hr_sw_128>;
5261 }
5262
5263 //===---------------------------------------------------------------------===//
5264 // SSSE3 - Packed Align Instruction Patterns
5265 //===---------------------------------------------------------------------===//
5266
5267 multiclass ssse3_palign<string asm, bit Is2Addr = 1> {
5268   let neverHasSideEffects = 1 in {
5269   def R128rr : SS3AI<0x0F, MRMSrcReg, (outs VR128:$dst),
5270       (ins VR128:$src1, VR128:$src2, i8imm:$src3),
5271       !if(Is2Addr,
5272         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5273         !strconcat(asm,
5274                   "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5275       []>, OpSize;
5276   let mayLoad = 1 in
5277   def R128rm : SS3AI<0x0F, MRMSrcMem, (outs VR128:$dst),
5278       (ins VR128:$src1, i128mem:$src2, i8imm:$src3),
5279       !if(Is2Addr,
5280         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5281         !strconcat(asm,
5282                   "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5283       []>, OpSize;
5284   }
5285 }
5286
5287 multiclass ssse3_palign_y<string asm, bit Is2Addr = 1> {
5288   let neverHasSideEffects = 1 in {
5289   def R256rr : SS3AI<0x0F, MRMSrcReg, (outs VR256:$dst),
5290       (ins VR256:$src1, VR256:$src2, i8imm:$src3),
5291       !strconcat(asm,
5292                  "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
5293       []>, OpSize;
5294   let mayLoad = 1 in
5295   def R256rm : SS3AI<0x0F, MRMSrcMem, (outs VR256:$dst),
5296       (ins VR256:$src1, i256mem:$src2, i8imm:$src3),
5297       !strconcat(asm,
5298                  "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
5299       []>, OpSize;
5300   }
5301 }
5302
5303 let Predicates = [HasAVX] in
5304   defm VPALIGN : ssse3_palign<"vpalignr", 0>, VEX_4V;
5305 let Predicates = [HasAVX2] in
5306   defm VPALIGN : ssse3_palign_y<"vpalignr", 0>, VEX_4V;
5307 let Constraints = "$src1 = $dst", Predicates = [HasSSSE3] in
5308   defm PALIGN : ssse3_palign<"palignr">;
5309
5310 let Predicates = [HasAVX2] in {
5311 def : Pat<(v8i32 (X86PAlign VR256:$src1, VR256:$src2, (i8 imm:$imm))),
5312           (VPALIGNR256rr VR256:$src2, VR256:$src1, imm:$imm)>;
5313 def : Pat<(v8f32 (X86PAlign VR256:$src1, VR256:$src2, (i8 imm:$imm))),
5314           (VPALIGNR256rr VR256:$src2, VR256:$src1, imm:$imm)>;
5315 def : Pat<(v16i16 (X86PAlign VR256:$src1, VR256:$src2, (i8 imm:$imm))),
5316           (VPALIGNR256rr VR256:$src2, VR256:$src1, imm:$imm)>;
5317 def : Pat<(v32i8 (X86PAlign VR256:$src1, VR256:$src2, (i8 imm:$imm))),
5318           (VPALIGNR256rr VR256:$src2, VR256:$src1, imm:$imm)>;
5319 }
5320
5321 let Predicates = [HasAVX] in {
5322 def : Pat<(v4i32 (X86PAlign VR128:$src1, VR128:$src2, (i8 imm:$imm))),
5323           (VPALIGNR128rr VR128:$src2, VR128:$src1, imm:$imm)>;
5324 def : Pat<(v4f32 (X86PAlign VR128:$src1, VR128:$src2, (i8 imm:$imm))),
5325           (VPALIGNR128rr VR128:$src2, VR128:$src1, imm:$imm)>;
5326 def : Pat<(v8i16 (X86PAlign VR128:$src1, VR128:$src2, (i8 imm:$imm))),
5327           (VPALIGNR128rr VR128:$src2, VR128:$src1, imm:$imm)>;
5328 def : Pat<(v16i8 (X86PAlign VR128:$src1, VR128:$src2, (i8 imm:$imm))),
5329           (VPALIGNR128rr VR128:$src2, VR128:$src1, imm:$imm)>;
5330 }
5331
5332 let Predicates = [HasSSSE3] in {
5333 def : Pat<(v4i32 (X86PAlign VR128:$src1, VR128:$src2, (i8 imm:$imm))),
5334           (PALIGNR128rr VR128:$src2, VR128:$src1, imm:$imm)>;
5335 def : Pat<(v4f32 (X86PAlign VR128:$src1, VR128:$src2, (i8 imm:$imm))),
5336           (PALIGNR128rr VR128:$src2, VR128:$src1, imm:$imm)>;
5337 def : Pat<(v8i16 (X86PAlign VR128:$src1, VR128:$src2, (i8 imm:$imm))),
5338           (PALIGNR128rr VR128:$src2, VR128:$src1, imm:$imm)>;
5339 def : Pat<(v16i8 (X86PAlign VR128:$src1, VR128:$src2, (i8 imm:$imm))),
5340           (PALIGNR128rr VR128:$src2, VR128:$src1, imm:$imm)>;
5341 }
5342
5343 //===---------------------------------------------------------------------===//
5344 // SSSE3 - Thread synchronization
5345 //===---------------------------------------------------------------------===//
5346
5347 let usesCustomInserter = 1 in {
5348 def MONITOR : PseudoI<(outs), (ins i32mem:$src1, GR32:$src2, GR32:$src3),
5349                 [(int_x86_sse3_monitor addr:$src1, GR32:$src2, GR32:$src3)]>,
5350                 Requires<[HasSSE3]>;
5351 def MWAIT : PseudoI<(outs), (ins GR32:$src1, GR32:$src2),
5352                 [(int_x86_sse3_mwait GR32:$src1, GR32:$src2)]>,
5353                 Requires<[HasSSE3]>;
5354 }
5355
5356 let Uses = [EAX, ECX, EDX] in
5357 def MONITORrrr : I<0x01, MRM_C8, (outs), (ins), "monitor", []>, TB,
5358                  Requires<[HasSSE3]>;
5359 let Uses = [ECX, EAX] in
5360 def MWAITrr   : I<0x01, MRM_C9, (outs), (ins), "mwait", []>, TB,
5361                 Requires<[HasSSE3]>;
5362
5363 def : InstAlias<"mwait %eax, %ecx", (MWAITrr)>, Requires<[In32BitMode]>;
5364 def : InstAlias<"mwait %rax, %rcx", (MWAITrr)>, Requires<[In64BitMode]>;
5365
5366 def : InstAlias<"monitor %eax, %ecx, %edx", (MONITORrrr)>,
5367       Requires<[In32BitMode]>;
5368 def : InstAlias<"monitor %rax, %rcx, %rdx", (MONITORrrr)>,
5369       Requires<[In64BitMode]>;
5370
5371 //===----------------------------------------------------------------------===//
5372 // SSE4.1 - Packed Move with Sign/Zero Extend
5373 //===----------------------------------------------------------------------===//
5374
5375 multiclass SS41I_binop_rm_int8<bits<8> opc, string OpcodeStr, Intrinsic IntId> {
5376   def rr : SS48I<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
5377                  !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5378                  [(set VR128:$dst, (IntId VR128:$src))]>, OpSize;
5379
5380   def rm : SS48I<opc, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
5381                  !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5382        [(set VR128:$dst,
5383          (IntId (bitconvert (v2i64 (scalar_to_vector (loadi64 addr:$src))))))]>,
5384        OpSize;
5385 }
5386
5387 multiclass SS41I_binop_rm_int16_y<bits<8> opc, string OpcodeStr,
5388                                  Intrinsic IntId> {
5389   def Yrr : SS48I<opc, MRMSrcReg, (outs VR256:$dst), (ins VR128:$src),
5390                   !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5391                   [(set VR256:$dst, (IntId VR128:$src))]>, OpSize;
5392
5393   def Yrm : SS48I<opc, MRMSrcMem, (outs VR256:$dst), (ins i128mem:$src),
5394                   !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5395                   [(set VR256:$dst, (IntId (load addr:$src)))]>, OpSize;
5396 }
5397
5398 let Predicates = [HasAVX] in {
5399 defm VPMOVSXBW : SS41I_binop_rm_int8<0x20, "vpmovsxbw", int_x86_sse41_pmovsxbw>,
5400                                      VEX;
5401 defm VPMOVSXWD : SS41I_binop_rm_int8<0x23, "vpmovsxwd", int_x86_sse41_pmovsxwd>,
5402                                      VEX;
5403 defm VPMOVSXDQ : SS41I_binop_rm_int8<0x25, "vpmovsxdq", int_x86_sse41_pmovsxdq>,
5404                                      VEX;
5405 defm VPMOVZXBW : SS41I_binop_rm_int8<0x30, "vpmovzxbw", int_x86_sse41_pmovzxbw>,
5406                                      VEX;
5407 defm VPMOVZXWD : SS41I_binop_rm_int8<0x33, "vpmovzxwd", int_x86_sse41_pmovzxwd>,
5408                                      VEX;
5409 defm VPMOVZXDQ : SS41I_binop_rm_int8<0x35, "vpmovzxdq", int_x86_sse41_pmovzxdq>,
5410                                      VEX;
5411 }
5412
5413 let Predicates = [HasAVX2] in {
5414 defm VPMOVSXBW : SS41I_binop_rm_int16_y<0x20, "vpmovsxbw",
5415                                         int_x86_avx2_pmovsxbw>, VEX;
5416 defm VPMOVSXWD : SS41I_binop_rm_int16_y<0x23, "vpmovsxwd",
5417                                         int_x86_avx2_pmovsxwd>, VEX;
5418 defm VPMOVSXDQ : SS41I_binop_rm_int16_y<0x25, "vpmovsxdq",
5419                                         int_x86_avx2_pmovsxdq>, VEX;
5420 defm VPMOVZXBW : SS41I_binop_rm_int16_y<0x30, "vpmovzxbw",
5421                                         int_x86_avx2_pmovzxbw>, VEX;
5422 defm VPMOVZXWD : SS41I_binop_rm_int16_y<0x33, "vpmovzxwd",
5423                                         int_x86_avx2_pmovzxwd>, VEX;
5424 defm VPMOVZXDQ : SS41I_binop_rm_int16_y<0x35, "vpmovzxdq",
5425                                         int_x86_avx2_pmovzxdq>, VEX;
5426 }
5427
5428 defm PMOVSXBW   : SS41I_binop_rm_int8<0x20, "pmovsxbw", int_x86_sse41_pmovsxbw>;
5429 defm PMOVSXWD   : SS41I_binop_rm_int8<0x23, "pmovsxwd", int_x86_sse41_pmovsxwd>;
5430 defm PMOVSXDQ   : SS41I_binop_rm_int8<0x25, "pmovsxdq", int_x86_sse41_pmovsxdq>;
5431 defm PMOVZXBW   : SS41I_binop_rm_int8<0x30, "pmovzxbw", int_x86_sse41_pmovzxbw>;
5432 defm PMOVZXWD   : SS41I_binop_rm_int8<0x33, "pmovzxwd", int_x86_sse41_pmovzxwd>;
5433 defm PMOVZXDQ   : SS41I_binop_rm_int8<0x35, "pmovzxdq", int_x86_sse41_pmovzxdq>;
5434
5435 let Predicates = [HasAVX] in {
5436   // Common patterns involving scalar load.
5437   def : Pat<(int_x86_sse41_pmovsxbw (vzmovl_v2i64 addr:$src)),
5438             (VPMOVSXBWrm addr:$src)>;
5439   def : Pat<(int_x86_sse41_pmovsxbw (vzload_v2i64 addr:$src)),
5440             (VPMOVSXBWrm addr:$src)>;
5441
5442   def : Pat<(int_x86_sse41_pmovsxwd (vzmovl_v2i64 addr:$src)),
5443             (VPMOVSXWDrm addr:$src)>;
5444   def : Pat<(int_x86_sse41_pmovsxwd (vzload_v2i64 addr:$src)),
5445             (VPMOVSXWDrm addr:$src)>;
5446
5447   def : Pat<(int_x86_sse41_pmovsxdq (vzmovl_v2i64 addr:$src)),
5448             (VPMOVSXDQrm addr:$src)>;
5449   def : Pat<(int_x86_sse41_pmovsxdq (vzload_v2i64 addr:$src)),
5450             (VPMOVSXDQrm addr:$src)>;
5451
5452   def : Pat<(int_x86_sse41_pmovzxbw (vzmovl_v2i64 addr:$src)),
5453             (VPMOVZXBWrm addr:$src)>;
5454   def : Pat<(int_x86_sse41_pmovzxbw (vzload_v2i64 addr:$src)),
5455             (VPMOVZXBWrm addr:$src)>;
5456
5457   def : Pat<(int_x86_sse41_pmovzxwd (vzmovl_v2i64 addr:$src)),
5458             (VPMOVZXWDrm addr:$src)>;
5459   def : Pat<(int_x86_sse41_pmovzxwd (vzload_v2i64 addr:$src)),
5460             (VPMOVZXWDrm addr:$src)>;
5461
5462   def : Pat<(int_x86_sse41_pmovzxdq (vzmovl_v2i64 addr:$src)),
5463             (VPMOVZXDQrm addr:$src)>;
5464   def : Pat<(int_x86_sse41_pmovzxdq (vzload_v2i64 addr:$src)),
5465             (VPMOVZXDQrm addr:$src)>;
5466 }
5467
5468 let Predicates = [HasSSE41] in {
5469   // Common patterns involving scalar load.
5470   def : Pat<(int_x86_sse41_pmovsxbw (vzmovl_v2i64 addr:$src)),
5471             (PMOVSXBWrm addr:$src)>;
5472   def : Pat<(int_x86_sse41_pmovsxbw (vzload_v2i64 addr:$src)),
5473             (PMOVSXBWrm addr:$src)>;
5474
5475   def : Pat<(int_x86_sse41_pmovsxwd (vzmovl_v2i64 addr:$src)),
5476             (PMOVSXWDrm addr:$src)>;
5477   def : Pat<(int_x86_sse41_pmovsxwd (vzload_v2i64 addr:$src)),
5478             (PMOVSXWDrm addr:$src)>;
5479
5480   def : Pat<(int_x86_sse41_pmovsxdq (vzmovl_v2i64 addr:$src)),
5481             (PMOVSXDQrm addr:$src)>;
5482   def : Pat<(int_x86_sse41_pmovsxdq (vzload_v2i64 addr:$src)),
5483             (PMOVSXDQrm addr:$src)>;
5484
5485   def : Pat<(int_x86_sse41_pmovzxbw (vzmovl_v2i64 addr:$src)),
5486             (PMOVZXBWrm addr:$src)>;
5487   def : Pat<(int_x86_sse41_pmovzxbw (vzload_v2i64 addr:$src)),
5488             (PMOVZXBWrm addr:$src)>;
5489
5490   def : Pat<(int_x86_sse41_pmovzxwd (vzmovl_v2i64 addr:$src)),
5491             (PMOVZXWDrm addr:$src)>;
5492   def : Pat<(int_x86_sse41_pmovzxwd (vzload_v2i64 addr:$src)),
5493             (PMOVZXWDrm addr:$src)>;
5494
5495   def : Pat<(int_x86_sse41_pmovzxdq (vzmovl_v2i64 addr:$src)),
5496             (PMOVZXDQrm addr:$src)>;
5497   def : Pat<(int_x86_sse41_pmovzxdq (vzload_v2i64 addr:$src)),
5498             (PMOVZXDQrm addr:$src)>;
5499 }
5500
5501 let Predicates = [HasAVX] in {
5502 def : Pat<(v2i64 (X86vsmovl (v4i32 VR128:$src))), (VPMOVSXDQrr VR128:$src)>;
5503 def : Pat<(v4i32 (X86vsmovl (v8i16 VR128:$src))), (VPMOVSXWDrr VR128:$src)>;
5504 }
5505
5506 let Predicates = [HasSSE41] in {
5507 def : Pat<(v2i64 (X86vsmovl (v4i32 VR128:$src))), (PMOVSXDQrr VR128:$src)>;
5508 def : Pat<(v4i32 (X86vsmovl (v8i16 VR128:$src))), (PMOVSXWDrr VR128:$src)>;
5509 }
5510
5511
5512 multiclass SS41I_binop_rm_int4<bits<8> opc, string OpcodeStr, Intrinsic IntId> {
5513   def rr : SS48I<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
5514                  !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5515                  [(set VR128:$dst, (IntId VR128:$src))]>, OpSize;
5516
5517   def rm : SS48I<opc, MRMSrcMem, (outs VR128:$dst), (ins i32mem:$src),
5518                  !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5519        [(set VR128:$dst,
5520          (IntId (bitconvert (v4i32 (scalar_to_vector (loadi32 addr:$src))))))]>,
5521           OpSize;
5522 }
5523
5524 multiclass SS41I_binop_rm_int8_y<bits<8> opc, string OpcodeStr,
5525                                  Intrinsic IntId> {
5526   def Yrr : SS48I<opc, MRMSrcReg, (outs VR256:$dst), (ins VR128:$src),
5527                   !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5528                   [(set VR256:$dst, (IntId VR128:$src))]>, OpSize;
5529
5530   def Yrm : SS48I<opc, MRMSrcMem, (outs VR256:$dst), (ins i32mem:$src),
5531                   !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5532        [(set VR256:$dst,
5533          (IntId (bitconvert (v2i64 (scalar_to_vector (loadi64 addr:$src))))))]>,
5534           OpSize;
5535 }
5536
5537 let Predicates = [HasAVX] in {
5538 defm VPMOVSXBD : SS41I_binop_rm_int4<0x21, "vpmovsxbd", int_x86_sse41_pmovsxbd>,
5539                                      VEX;
5540 defm VPMOVSXWQ : SS41I_binop_rm_int4<0x24, "vpmovsxwq", int_x86_sse41_pmovsxwq>,
5541                                      VEX;
5542 defm VPMOVZXBD : SS41I_binop_rm_int4<0x31, "vpmovzxbd", int_x86_sse41_pmovzxbd>,
5543                                      VEX;
5544 defm VPMOVZXWQ : SS41I_binop_rm_int4<0x34, "vpmovzxwq", int_x86_sse41_pmovzxwq>,
5545                                      VEX;
5546 }
5547
5548 let Predicates = [HasAVX2] in {
5549 defm VPMOVSXBD : SS41I_binop_rm_int8_y<0x21, "vpmovsxbd",
5550                                        int_x86_avx2_pmovsxbd>, VEX;
5551 defm VPMOVSXWQ : SS41I_binop_rm_int8_y<0x24, "vpmovsxwq",
5552                                        int_x86_avx2_pmovsxwq>, VEX;
5553 defm VPMOVZXBD : SS41I_binop_rm_int8_y<0x31, "vpmovzxbd",
5554                                        int_x86_avx2_pmovzxbd>, VEX;
5555 defm VPMOVZXWQ : SS41I_binop_rm_int8_y<0x34, "vpmovzxwq",
5556                                        int_x86_avx2_pmovzxwq>, VEX;
5557 }
5558
5559 defm PMOVSXBD   : SS41I_binop_rm_int4<0x21, "pmovsxbd", int_x86_sse41_pmovsxbd>;
5560 defm PMOVSXWQ   : SS41I_binop_rm_int4<0x24, "pmovsxwq", int_x86_sse41_pmovsxwq>;
5561 defm PMOVZXBD   : SS41I_binop_rm_int4<0x31, "pmovzxbd", int_x86_sse41_pmovzxbd>;
5562 defm PMOVZXWQ   : SS41I_binop_rm_int4<0x34, "pmovzxwq", int_x86_sse41_pmovzxwq>;
5563
5564 let Predicates = [HasAVX] in {
5565   // Common patterns involving scalar load
5566   def : Pat<(int_x86_sse41_pmovsxbd (vzmovl_v4i32 addr:$src)),
5567             (VPMOVSXBDrm addr:$src)>;
5568   def : Pat<(int_x86_sse41_pmovsxwq (vzmovl_v4i32 addr:$src)),
5569             (VPMOVSXWQrm addr:$src)>;
5570
5571   def : Pat<(int_x86_sse41_pmovzxbd (vzmovl_v4i32 addr:$src)),
5572             (VPMOVZXBDrm addr:$src)>;
5573   def : Pat<(int_x86_sse41_pmovzxwq (vzmovl_v4i32 addr:$src)),
5574             (VPMOVZXWQrm addr:$src)>;
5575 }
5576
5577 let Predicates = [HasSSE41] in {
5578   // Common patterns involving scalar load
5579   def : Pat<(int_x86_sse41_pmovsxbd (vzmovl_v4i32 addr:$src)),
5580             (PMOVSXBDrm addr:$src)>;
5581   def : Pat<(int_x86_sse41_pmovsxwq (vzmovl_v4i32 addr:$src)),
5582             (PMOVSXWQrm addr:$src)>;
5583
5584   def : Pat<(int_x86_sse41_pmovzxbd (vzmovl_v4i32 addr:$src)),
5585             (PMOVZXBDrm addr:$src)>;
5586   def : Pat<(int_x86_sse41_pmovzxwq (vzmovl_v4i32 addr:$src)),
5587             (PMOVZXWQrm addr:$src)>;
5588 }
5589
5590 multiclass SS41I_binop_rm_int2<bits<8> opc, string OpcodeStr, Intrinsic IntId> {
5591   def rr : SS48I<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
5592                  !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5593                  [(set VR128:$dst, (IntId VR128:$src))]>, OpSize;
5594
5595   // Expecting a i16 load any extended to i32 value.
5596   def rm : SS48I<opc, MRMSrcMem, (outs VR128:$dst), (ins i16mem:$src),
5597                  !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5598                  [(set VR128:$dst, (IntId (bitconvert
5599                      (v4i32 (scalar_to_vector (loadi16_anyext addr:$src))))))]>,
5600                  OpSize;
5601 }
5602
5603 multiclass SS41I_binop_rm_int4_y<bits<8> opc, string OpcodeStr,
5604                                  Intrinsic IntId> {
5605   def Yrr : SS48I<opc, MRMSrcReg, (outs VR256:$dst), (ins VR128:$src),
5606                  !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5607                  [(set VR256:$dst, (IntId VR128:$src))]>, OpSize;
5608
5609   // Expecting a i16 load any extended to i32 value.
5610   def Yrm : SS48I<opc, MRMSrcMem, (outs VR256:$dst), (ins i16mem:$src),
5611                   !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5612                   [(set VR256:$dst, (IntId (bitconvert
5613                       (v4i32 (scalar_to_vector (loadi32 addr:$src))))))]>,
5614                   OpSize;
5615 }
5616
5617 let Predicates = [HasAVX] in {
5618 defm VPMOVSXBQ : SS41I_binop_rm_int2<0x22, "vpmovsxbq", int_x86_sse41_pmovsxbq>,
5619                                      VEX;
5620 defm VPMOVZXBQ : SS41I_binop_rm_int2<0x32, "vpmovzxbq", int_x86_sse41_pmovzxbq>,
5621                                      VEX;
5622 }
5623 let Predicates = [HasAVX2] in {
5624 defm VPMOVSXBQ : SS41I_binop_rm_int4_y<0x22, "vpmovsxbq",
5625                                        int_x86_avx2_pmovsxbq>, VEX;
5626 defm VPMOVZXBQ : SS41I_binop_rm_int4_y<0x32, "vpmovzxbq",
5627                                        int_x86_avx2_pmovzxbq>, VEX;
5628 }
5629 defm PMOVSXBQ   : SS41I_binop_rm_int2<0x22, "pmovsxbq", int_x86_sse41_pmovsxbq>;
5630 defm PMOVZXBQ   : SS41I_binop_rm_int2<0x32, "pmovzxbq", int_x86_sse41_pmovzxbq>;
5631
5632 let Predicates = [HasAVX] in {
5633   // Common patterns involving scalar load
5634   def : Pat<(int_x86_sse41_pmovsxbq
5635               (bitconvert (v4i32 (X86vzmovl
5636                             (v4i32 (scalar_to_vector (loadi32 addr:$src))))))),
5637             (VPMOVSXBQrm addr:$src)>;
5638
5639   def : Pat<(int_x86_sse41_pmovzxbq
5640               (bitconvert (v4i32 (X86vzmovl
5641                             (v4i32 (scalar_to_vector (loadi32 addr:$src))))))),
5642             (VPMOVZXBQrm addr:$src)>;
5643 }
5644
5645 let Predicates = [HasSSE41] in {
5646   // Common patterns involving scalar load
5647   def : Pat<(int_x86_sse41_pmovsxbq
5648               (bitconvert (v4i32 (X86vzmovl
5649                             (v4i32 (scalar_to_vector (loadi32 addr:$src))))))),
5650             (PMOVSXBQrm addr:$src)>;
5651
5652   def : Pat<(int_x86_sse41_pmovzxbq
5653               (bitconvert (v4i32 (X86vzmovl
5654                             (v4i32 (scalar_to_vector (loadi32 addr:$src))))))),
5655             (PMOVZXBQrm addr:$src)>;
5656 }
5657
5658 //===----------------------------------------------------------------------===//
5659 // SSE4.1 - Extract Instructions
5660 //===----------------------------------------------------------------------===//
5661
5662 /// SS41I_binop_ext8 - SSE 4.1 extract 8 bits to 32 bit reg or 8 bit mem
5663 multiclass SS41I_extract8<bits<8> opc, string OpcodeStr> {
5664   def rr : SS4AIi8<opc, MRMDestReg, (outs GR32:$dst),
5665                  (ins VR128:$src1, i32i8imm:$src2),
5666                  !strconcat(OpcodeStr,
5667                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5668                  [(set GR32:$dst, (X86pextrb (v16i8 VR128:$src1), imm:$src2))]>,
5669                  OpSize;
5670   let neverHasSideEffects = 1, mayStore = 1 in
5671   def mr : SS4AIi8<opc, MRMDestMem, (outs),
5672                  (ins i8mem:$dst, VR128:$src1, i32i8imm:$src2),
5673                  !strconcat(OpcodeStr,
5674                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5675                  []>, OpSize;
5676 // FIXME:
5677 // There's an AssertZext in the way of writing the store pattern
5678 // (store (i8 (trunc (X86pextrb (v16i8 VR128:$src1), imm:$src2))), addr:$dst)
5679 }
5680
5681 let Predicates = [HasAVX] in {
5682   defm VPEXTRB : SS41I_extract8<0x14, "vpextrb">, VEX;
5683   def  VPEXTRBrr64 : SS4AIi8<0x14, MRMDestReg, (outs GR64:$dst),
5684          (ins VR128:$src1, i32i8imm:$src2),
5685          "vpextrb\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>, OpSize, VEX;
5686 }
5687
5688 defm PEXTRB      : SS41I_extract8<0x14, "pextrb">;
5689
5690
5691 /// SS41I_extract16 - SSE 4.1 extract 16 bits to memory destination
5692 multiclass SS41I_extract16<bits<8> opc, string OpcodeStr> {
5693   let neverHasSideEffects = 1, mayStore = 1 in
5694   def mr : SS4AIi8<opc, MRMDestMem, (outs),
5695                  (ins i16mem:$dst, VR128:$src1, i32i8imm:$src2),
5696                  !strconcat(OpcodeStr,
5697                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5698                  []>, OpSize;
5699 // FIXME:
5700 // There's an AssertZext in the way of writing the store pattern
5701 // (store (i16 (trunc (X86pextrw (v16i8 VR128:$src1), imm:$src2))), addr:$dst)
5702 }
5703
5704 let Predicates = [HasAVX] in
5705   defm VPEXTRW : SS41I_extract16<0x15, "vpextrw">, VEX;
5706
5707 defm PEXTRW      : SS41I_extract16<0x15, "pextrw">;
5708
5709
5710 /// SS41I_extract32 - SSE 4.1 extract 32 bits to int reg or memory destination
5711 multiclass SS41I_extract32<bits<8> opc, string OpcodeStr> {
5712   def rr : SS4AIi8<opc, MRMDestReg, (outs GR32:$dst),
5713                  (ins VR128:$src1, i32i8imm:$src2),
5714                  !strconcat(OpcodeStr,
5715                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5716                  [(set GR32:$dst,
5717                   (extractelt (v4i32 VR128:$src1), imm:$src2))]>, OpSize;
5718   def mr : SS4AIi8<opc, MRMDestMem, (outs),
5719                  (ins i32mem:$dst, VR128:$src1, i32i8imm:$src2),
5720                  !strconcat(OpcodeStr,
5721                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5722                  [(store (extractelt (v4i32 VR128:$src1), imm:$src2),
5723                           addr:$dst)]>, OpSize;
5724 }
5725
5726 let Predicates = [HasAVX] in
5727   defm VPEXTRD : SS41I_extract32<0x16, "vpextrd">, VEX;
5728
5729 defm PEXTRD      : SS41I_extract32<0x16, "pextrd">;
5730
5731 /// SS41I_extract32 - SSE 4.1 extract 32 bits to int reg or memory destination
5732 multiclass SS41I_extract64<bits<8> opc, string OpcodeStr> {
5733   def rr : SS4AIi8<opc, MRMDestReg, (outs GR64:$dst),
5734                  (ins VR128:$src1, i32i8imm:$src2),
5735                  !strconcat(OpcodeStr,
5736                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5737                  [(set GR64:$dst,
5738                   (extractelt (v2i64 VR128:$src1), imm:$src2))]>, OpSize, REX_W;
5739   def mr : SS4AIi8<opc, MRMDestMem, (outs),
5740                  (ins i64mem:$dst, VR128:$src1, i32i8imm:$src2),
5741                  !strconcat(OpcodeStr,
5742                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5743                  [(store (extractelt (v2i64 VR128:$src1), imm:$src2),
5744                           addr:$dst)]>, OpSize, REX_W;
5745 }
5746
5747 let Predicates = [HasAVX] in
5748   defm VPEXTRQ : SS41I_extract64<0x16, "vpextrq">, VEX, VEX_W;
5749
5750 defm PEXTRQ      : SS41I_extract64<0x16, "pextrq">;
5751
5752 /// SS41I_extractf32 - SSE 4.1 extract 32 bits fp value to int reg or memory
5753 /// destination
5754 multiclass SS41I_extractf32<bits<8> opc, string OpcodeStr> {
5755   def rr : SS4AIi8<opc, MRMDestReg, (outs GR32:$dst),
5756                  (ins VR128:$src1, i32i8imm:$src2),
5757                  !strconcat(OpcodeStr,
5758                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5759                  [(set GR32:$dst,
5760                     (extractelt (bc_v4i32 (v4f32 VR128:$src1)), imm:$src2))]>,
5761            OpSize;
5762   def mr : SS4AIi8<opc, MRMDestMem, (outs),
5763                  (ins f32mem:$dst, VR128:$src1, i32i8imm:$src2),
5764                  !strconcat(OpcodeStr,
5765                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5766                  [(store (extractelt (bc_v4i32 (v4f32 VR128:$src1)), imm:$src2),
5767                           addr:$dst)]>, OpSize;
5768 }
5769
5770 let ExeDomain = SSEPackedSingle in {
5771   let Predicates = [HasAVX] in {
5772     defm VEXTRACTPS : SS41I_extractf32<0x17, "vextractps">, VEX;
5773     def VEXTRACTPSrr64 : SS4AIi8<0x17, MRMDestReg, (outs GR64:$dst),
5774                     (ins VR128:$src1, i32i8imm:$src2),
5775                     "vextractps \t{$src2, $src1, $dst|$dst, $src1, $src2}",
5776                     []>, OpSize, VEX;
5777   }
5778   defm EXTRACTPS   : SS41I_extractf32<0x17, "extractps">;
5779 }
5780
5781 // Also match an EXTRACTPS store when the store is done as f32 instead of i32.
5782 def : Pat<(store (f32 (bitconvert (extractelt (bc_v4i32 (v4f32 VR128:$src1)),
5783                                               imm:$src2))),
5784                  addr:$dst),
5785           (VEXTRACTPSmr addr:$dst, VR128:$src1, imm:$src2)>,
5786           Requires<[HasAVX]>;
5787 def : Pat<(store (f32 (bitconvert (extractelt (bc_v4i32 (v4f32 VR128:$src1)),
5788                                               imm:$src2))),
5789                  addr:$dst),
5790           (EXTRACTPSmr addr:$dst, VR128:$src1, imm:$src2)>,
5791           Requires<[HasSSE41]>;
5792
5793 //===----------------------------------------------------------------------===//
5794 // SSE4.1 - Insert Instructions
5795 //===----------------------------------------------------------------------===//
5796
5797 multiclass SS41I_insert8<bits<8> opc, string asm, bit Is2Addr = 1> {
5798   def rr : SS4AIi8<opc, MRMSrcReg, (outs VR128:$dst),
5799       (ins VR128:$src1, GR32:$src2, i32i8imm:$src3),
5800       !if(Is2Addr,
5801         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5802         !strconcat(asm,
5803                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5804       [(set VR128:$dst,
5805         (X86pinsrb VR128:$src1, GR32:$src2, imm:$src3))]>, OpSize;
5806   def rm : SS4AIi8<opc, MRMSrcMem, (outs VR128:$dst),
5807       (ins VR128:$src1, i8mem:$src2, i32i8imm:$src3),
5808       !if(Is2Addr,
5809         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5810         !strconcat(asm,
5811                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5812       [(set VR128:$dst,
5813         (X86pinsrb VR128:$src1, (extloadi8 addr:$src2),
5814                    imm:$src3))]>, OpSize;
5815 }
5816
5817 let Predicates = [HasAVX] in
5818   defm VPINSRB : SS41I_insert8<0x20, "vpinsrb", 0>, VEX_4V;
5819 let Constraints = "$src1 = $dst" in
5820   defm PINSRB  : SS41I_insert8<0x20, "pinsrb">;
5821
5822 multiclass SS41I_insert32<bits<8> opc, string asm, bit Is2Addr = 1> {
5823   def rr : SS4AIi8<opc, MRMSrcReg, (outs VR128:$dst),
5824       (ins VR128:$src1, GR32:$src2, i32i8imm:$src3),
5825       !if(Is2Addr,
5826         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5827         !strconcat(asm,
5828                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5829       [(set VR128:$dst,
5830         (v4i32 (insertelt VR128:$src1, GR32:$src2, imm:$src3)))]>,
5831       OpSize;
5832   def rm : SS4AIi8<opc, MRMSrcMem, (outs VR128:$dst),
5833       (ins VR128:$src1, i32mem:$src2, i32i8imm:$src3),
5834       !if(Is2Addr,
5835         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5836         !strconcat(asm,
5837                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5838       [(set VR128:$dst,
5839         (v4i32 (insertelt VR128:$src1, (loadi32 addr:$src2),
5840                           imm:$src3)))]>, OpSize;
5841 }
5842
5843 let Predicates = [HasAVX] in
5844   defm VPINSRD : SS41I_insert32<0x22, "vpinsrd", 0>, VEX_4V;
5845 let Constraints = "$src1 = $dst" in
5846   defm PINSRD : SS41I_insert32<0x22, "pinsrd">;
5847
5848 multiclass SS41I_insert64<bits<8> opc, string asm, bit Is2Addr = 1> {
5849   def rr : SS4AIi8<opc, MRMSrcReg, (outs VR128:$dst),
5850       (ins VR128:$src1, GR64:$src2, i32i8imm:$src3),
5851       !if(Is2Addr,
5852         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5853         !strconcat(asm,
5854                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5855       [(set VR128:$dst,
5856         (v2i64 (insertelt VR128:$src1, GR64:$src2, imm:$src3)))]>,
5857       OpSize;
5858   def rm : SS4AIi8<opc, MRMSrcMem, (outs VR128:$dst),
5859       (ins VR128:$src1, i64mem:$src2, i32i8imm:$src3),
5860       !if(Is2Addr,
5861         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5862         !strconcat(asm,
5863                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5864       [(set VR128:$dst,
5865         (v2i64 (insertelt VR128:$src1, (loadi64 addr:$src2),
5866                           imm:$src3)))]>, OpSize;
5867 }
5868
5869 let Predicates = [HasAVX] in
5870   defm VPINSRQ : SS41I_insert64<0x22, "vpinsrq", 0>, VEX_4V, VEX_W;
5871 let Constraints = "$src1 = $dst" in
5872   defm PINSRQ : SS41I_insert64<0x22, "pinsrq">, REX_W;
5873
5874 // insertps has a few different modes, there's the first two here below which
5875 // are optimized inserts that won't zero arbitrary elements in the destination
5876 // vector. The next one matches the intrinsic and could zero arbitrary elements
5877 // in the target vector.
5878 multiclass SS41I_insertf32<bits<8> opc, string asm, bit Is2Addr = 1> {
5879   def rr : SS4AIi8<opc, MRMSrcReg, (outs VR128:$dst),
5880       (ins VR128:$src1, VR128:$src2, u32u8imm:$src3),
5881       !if(Is2Addr,
5882         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5883         !strconcat(asm,
5884                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5885       [(set VR128:$dst,
5886         (X86insrtps VR128:$src1, VR128:$src2, imm:$src3))]>,
5887       OpSize;
5888   def rm : SS4AIi8<opc, MRMSrcMem, (outs VR128:$dst),
5889       (ins VR128:$src1, f32mem:$src2, u32u8imm:$src3),
5890       !if(Is2Addr,
5891         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5892         !strconcat(asm,
5893                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5894       [(set VR128:$dst,
5895         (X86insrtps VR128:$src1,
5896                    (v4f32 (scalar_to_vector (loadf32 addr:$src2))),
5897                     imm:$src3))]>, OpSize;
5898 }
5899
5900 let ExeDomain = SSEPackedSingle in {
5901   let Predicates = [HasAVX] in
5902     defm VINSERTPS : SS41I_insertf32<0x21, "vinsertps", 0>, VEX_4V;
5903   let Constraints = "$src1 = $dst" in
5904     defm INSERTPS : SS41I_insertf32<0x21, "insertps">;
5905 }
5906
5907 //===----------------------------------------------------------------------===//
5908 // SSE4.1 - Round Instructions
5909 //===----------------------------------------------------------------------===//
5910
5911 multiclass sse41_fp_unop_rm<bits<8> opcps, bits<8> opcpd, string OpcodeStr,
5912                             X86MemOperand x86memop, RegisterClass RC,
5913                             PatFrag mem_frag32, PatFrag mem_frag64,
5914                             Intrinsic V4F32Int, Intrinsic V2F64Int> {
5915 let ExeDomain = SSEPackedSingle in {
5916   // Intrinsic operation, reg.
5917   // Vector intrinsic operation, reg
5918   def PSr : SS4AIi8<opcps, MRMSrcReg,
5919                     (outs RC:$dst), (ins RC:$src1, i32i8imm:$src2),
5920                     !strconcat(OpcodeStr,
5921                     "ps\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5922                     [(set RC:$dst, (V4F32Int RC:$src1, imm:$src2))]>,
5923                     OpSize;
5924
5925   // Vector intrinsic operation, mem
5926   def PSm : SS4AIi8<opcps, MRMSrcMem,
5927                     (outs RC:$dst), (ins x86memop:$src1, i32i8imm:$src2),
5928                     !strconcat(OpcodeStr,
5929                     "ps\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5930                     [(set RC:$dst,
5931                           (V4F32Int (mem_frag32 addr:$src1),imm:$src2))]>,
5932                     OpSize;
5933 } // ExeDomain = SSEPackedSingle
5934
5935 let ExeDomain = SSEPackedDouble in {
5936   // Vector intrinsic operation, reg
5937   def PDr : SS4AIi8<opcpd, MRMSrcReg,
5938                     (outs RC:$dst), (ins RC:$src1, i32i8imm:$src2),
5939                     !strconcat(OpcodeStr,
5940                     "pd\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5941                     [(set RC:$dst, (V2F64Int RC:$src1, imm:$src2))]>,
5942                     OpSize;
5943
5944   // Vector intrinsic operation, mem
5945   def PDm : SS4AIi8<opcpd, MRMSrcMem,
5946                     (outs RC:$dst), (ins x86memop:$src1, i32i8imm:$src2),
5947                     !strconcat(OpcodeStr,
5948                     "pd\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5949                     [(set RC:$dst,
5950                           (V2F64Int (mem_frag64 addr:$src1),imm:$src2))]>,
5951                     OpSize;
5952 } // ExeDomain = SSEPackedDouble
5953 }
5954
5955 multiclass sse41_fp_binop_rm<bits<8> opcss, bits<8> opcsd,
5956                             string OpcodeStr,
5957                             Intrinsic F32Int,
5958                             Intrinsic F64Int, bit Is2Addr = 1> {
5959 let ExeDomain = GenericDomain in {
5960   // Operation, reg.
5961   def SSr : SS4AIi8<opcss, MRMSrcReg,
5962       (outs FR32:$dst), (ins FR32:$src1, FR32:$src2, i32i8imm:$src3),
5963       !if(Is2Addr,
5964           !strconcat(OpcodeStr,
5965               "ss\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5966           !strconcat(OpcodeStr,
5967               "ss\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5968       []>, OpSize;
5969
5970   // Intrinsic operation, reg.
5971   def SSr_Int : SS4AIi8<opcss, MRMSrcReg,
5972         (outs VR128:$dst), (ins VR128:$src1, VR128:$src2, i32i8imm:$src3),
5973         !if(Is2Addr,
5974             !strconcat(OpcodeStr,
5975                 "ss\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5976             !strconcat(OpcodeStr,
5977                 "ss\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5978         [(set VR128:$dst, (F32Int VR128:$src1, VR128:$src2, imm:$src3))]>,
5979         OpSize;
5980
5981   // Intrinsic operation, mem.
5982   def SSm : SS4AIi8<opcss, MRMSrcMem,
5983         (outs VR128:$dst), (ins VR128:$src1, ssmem:$src2, i32i8imm:$src3),
5984         !if(Is2Addr,
5985             !strconcat(OpcodeStr,
5986                 "ss\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5987             !strconcat(OpcodeStr,
5988                 "ss\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5989         [(set VR128:$dst,
5990              (F32Int VR128:$src1, sse_load_f32:$src2, imm:$src3))]>,
5991         OpSize;
5992
5993   // Operation, reg.
5994   def SDr : SS4AIi8<opcsd, MRMSrcReg,
5995         (outs FR64:$dst), (ins FR64:$src1, FR64:$src2, i32i8imm:$src3),
5996         !if(Is2Addr,
5997             !strconcat(OpcodeStr,
5998                 "sd\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5999             !strconcat(OpcodeStr,
6000                 "sd\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6001         []>, OpSize;
6002
6003   // Intrinsic operation, reg.
6004   def SDr_Int : SS4AIi8<opcsd, MRMSrcReg,
6005         (outs VR128:$dst), (ins VR128:$src1, VR128:$src2, i32i8imm:$src3),
6006         !if(Is2Addr,
6007             !strconcat(OpcodeStr,
6008                 "sd\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6009             !strconcat(OpcodeStr,
6010                 "sd\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6011         [(set VR128:$dst, (F64Int VR128:$src1, VR128:$src2, imm:$src3))]>,
6012         OpSize;
6013
6014   // Intrinsic operation, mem.
6015   def SDm : SS4AIi8<opcsd, MRMSrcMem,
6016         (outs VR128:$dst), (ins VR128:$src1, sdmem:$src2, i32i8imm:$src3),
6017         !if(Is2Addr,
6018             !strconcat(OpcodeStr,
6019                 "sd\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6020             !strconcat(OpcodeStr,
6021                 "sd\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6022         [(set VR128:$dst,
6023               (F64Int VR128:$src1, sse_load_f64:$src2, imm:$src3))]>,
6024         OpSize;
6025 } // ExeDomain = GenericDomain
6026 }
6027
6028 // FP round - roundss, roundps, roundsd, roundpd
6029 let Predicates = [HasAVX] in {
6030   // Intrinsic form
6031   defm VROUND  : sse41_fp_unop_rm<0x08, 0x09, "vround", f128mem, VR128,
6032                                   memopv4f32, memopv2f64,
6033                                   int_x86_sse41_round_ps,
6034                                   int_x86_sse41_round_pd>, VEX;
6035   defm VROUNDY : sse41_fp_unop_rm<0x08, 0x09, "vround", f256mem, VR256,
6036                                   memopv8f32, memopv4f64,
6037                                   int_x86_avx_round_ps_256,
6038                                   int_x86_avx_round_pd_256>, VEX;
6039   defm VROUND  : sse41_fp_binop_rm<0x0A, 0x0B, "vround",
6040                                   int_x86_sse41_round_ss,
6041                                   int_x86_sse41_round_sd, 0>, VEX_4V, VEX_LIG;
6042
6043   def : Pat<(ffloor FR32:$src),
6044             (VROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x1))>;
6045   def : Pat<(f64 (ffloor FR64:$src)),
6046             (VROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x1))>;
6047   def : Pat<(f32 (fnearbyint FR32:$src)),
6048             (VROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0xC))>;
6049   def : Pat<(f64 (fnearbyint FR64:$src)),
6050             (VROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0xC))>;
6051   def : Pat<(f32 (fceil FR32:$src)),
6052             (VROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x2))>;
6053   def : Pat<(f64 (fceil FR64:$src)),
6054             (VROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x2))>;
6055   def : Pat<(f32 (frint FR32:$src)),
6056             (VROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x4))>;
6057   def : Pat<(f64 (frint FR64:$src)),
6058             (VROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x4))>;
6059   def : Pat<(f32 (ftrunc FR32:$src)),
6060             (VROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x3))>;
6061   def : Pat<(f64 (ftrunc FR64:$src)),
6062             (VROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x3))>;
6063 }
6064
6065 defm ROUND  : sse41_fp_unop_rm<0x08, 0x09, "round", f128mem, VR128,
6066                                memopv4f32, memopv2f64,
6067                                int_x86_sse41_round_ps, int_x86_sse41_round_pd>;
6068 let Constraints = "$src1 = $dst" in
6069 defm ROUND  : sse41_fp_binop_rm<0x0A, 0x0B, "round",
6070                                int_x86_sse41_round_ss, int_x86_sse41_round_sd>;
6071
6072 def : Pat<(ffloor FR32:$src),
6073           (ROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x1))>;
6074 def : Pat<(f64 (ffloor FR64:$src)),
6075           (ROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x1))>;
6076 def : Pat<(f32 (fnearbyint FR32:$src)),
6077           (ROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0xC))>;
6078 def : Pat<(f64 (fnearbyint FR64:$src)),
6079           (ROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0xC))>;
6080 def : Pat<(f32 (fceil FR32:$src)),
6081           (ROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x2))>;
6082 def : Pat<(f64 (fceil FR64:$src)),
6083           (ROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x2))>;
6084 def : Pat<(f32 (frint FR32:$src)),
6085           (ROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x4))>;
6086 def : Pat<(f64 (frint FR64:$src)),
6087           (ROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x4))>;
6088 def : Pat<(f32 (ftrunc FR32:$src)),
6089           (ROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x3))>;
6090 def : Pat<(f64 (ftrunc FR64:$src)),
6091           (ROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x3))>;
6092
6093 //===----------------------------------------------------------------------===//
6094 // SSE4.1 - Packed Bit Test
6095 //===----------------------------------------------------------------------===//
6096
6097 // ptest instruction we'll lower to this in X86ISelLowering primarily from
6098 // the intel intrinsic that corresponds to this.
6099 let Defs = [EFLAGS], Predicates = [HasAVX] in {
6100 def VPTESTrr  : SS48I<0x17, MRMSrcReg, (outs), (ins VR128:$src1, VR128:$src2),
6101                 "vptest\t{$src2, $src1|$src1, $src2}",
6102                 [(set EFLAGS, (X86ptest VR128:$src1, (v4f32 VR128:$src2)))]>,
6103                 OpSize, VEX;
6104 def VPTESTrm  : SS48I<0x17, MRMSrcMem, (outs), (ins VR128:$src1, f128mem:$src2),
6105                 "vptest\t{$src2, $src1|$src1, $src2}",
6106                 [(set EFLAGS,(X86ptest VR128:$src1, (memopv4f32 addr:$src2)))]>,
6107                 OpSize, VEX;
6108
6109 def VPTESTYrr : SS48I<0x17, MRMSrcReg, (outs), (ins VR256:$src1, VR256:$src2),
6110                 "vptest\t{$src2, $src1|$src1, $src2}",
6111                 [(set EFLAGS, (X86ptest VR256:$src1, (v4i64 VR256:$src2)))]>,
6112                 OpSize, VEX;
6113 def VPTESTYrm : SS48I<0x17, MRMSrcMem, (outs), (ins VR256:$src1, i256mem:$src2),
6114                 "vptest\t{$src2, $src1|$src1, $src2}",
6115                 [(set EFLAGS,(X86ptest VR256:$src1, (memopv4i64 addr:$src2)))]>,
6116                 OpSize, VEX;
6117 }
6118
6119 let Defs = [EFLAGS] in {
6120 def PTESTrr : SS48I<0x17, MRMSrcReg, (outs), (ins VR128:$src1, VR128:$src2),
6121               "ptest\t{$src2, $src1|$src1, $src2}",
6122               [(set EFLAGS, (X86ptest VR128:$src1, (v4f32 VR128:$src2)))]>,
6123               OpSize;
6124 def PTESTrm : SS48I<0x17, MRMSrcMem, (outs), (ins VR128:$src1, f128mem:$src2),
6125               "ptest\t{$src2, $src1|$src1, $src2}",
6126               [(set EFLAGS, (X86ptest VR128:$src1, (memopv4f32 addr:$src2)))]>,
6127               OpSize;
6128 }
6129
6130 // The bit test instructions below are AVX only
6131 multiclass avx_bittest<bits<8> opc, string OpcodeStr, RegisterClass RC,
6132                        X86MemOperand x86memop, PatFrag mem_frag, ValueType vt> {
6133   def rr : SS48I<opc, MRMSrcReg, (outs), (ins RC:$src1, RC:$src2),
6134             !strconcat(OpcodeStr, "\t{$src2, $src1|$src1, $src2}"),
6135             [(set EFLAGS, (X86testp RC:$src1, (vt RC:$src2)))]>, OpSize, VEX;
6136   def rm : SS48I<opc, MRMSrcMem, (outs), (ins RC:$src1, x86memop:$src2),
6137             !strconcat(OpcodeStr, "\t{$src2, $src1|$src1, $src2}"),
6138             [(set EFLAGS, (X86testp RC:$src1, (mem_frag addr:$src2)))]>,
6139             OpSize, VEX;
6140 }
6141
6142 let Defs = [EFLAGS], Predicates = [HasAVX] in {
6143 let ExeDomain = SSEPackedSingle in {
6144 defm VTESTPS  : avx_bittest<0x0E, "vtestps", VR128, f128mem, memopv4f32, v4f32>;
6145 defm VTESTPSY : avx_bittest<0x0E, "vtestps", VR256, f256mem, memopv8f32, v8f32>;
6146 }
6147 let ExeDomain = SSEPackedDouble in {
6148 defm VTESTPD  : avx_bittest<0x0F, "vtestpd", VR128, f128mem, memopv2f64, v2f64>;
6149 defm VTESTPDY : avx_bittest<0x0F, "vtestpd", VR256, f256mem, memopv4f64, v4f64>;
6150 }
6151 }
6152
6153 //===----------------------------------------------------------------------===//
6154 // SSE4.1 - Misc Instructions
6155 //===----------------------------------------------------------------------===//
6156
6157 let Defs = [EFLAGS], Predicates = [HasPOPCNT] in {
6158   def POPCNT16rr : I<0xB8, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
6159                      "popcnt{w}\t{$src, $dst|$dst, $src}",
6160                      [(set GR16:$dst, (ctpop GR16:$src)), (implicit EFLAGS)]>,
6161                      OpSize, XS;
6162   def POPCNT16rm : I<0xB8, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
6163                      "popcnt{w}\t{$src, $dst|$dst, $src}",
6164                      [(set GR16:$dst, (ctpop (loadi16 addr:$src))),
6165                       (implicit EFLAGS)]>, OpSize, XS;
6166
6167   def POPCNT32rr : I<0xB8, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
6168                      "popcnt{l}\t{$src, $dst|$dst, $src}",
6169                      [(set GR32:$dst, (ctpop GR32:$src)), (implicit EFLAGS)]>,
6170                      XS;
6171   def POPCNT32rm : I<0xB8, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
6172                      "popcnt{l}\t{$src, $dst|$dst, $src}",
6173                      [(set GR32:$dst, (ctpop (loadi32 addr:$src))),
6174                       (implicit EFLAGS)]>, XS;
6175
6176   def POPCNT64rr : RI<0xB8, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
6177                       "popcnt{q}\t{$src, $dst|$dst, $src}",
6178                       [(set GR64:$dst, (ctpop GR64:$src)), (implicit EFLAGS)]>,
6179                       XS;
6180   def POPCNT64rm : RI<0xB8, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
6181                       "popcnt{q}\t{$src, $dst|$dst, $src}",
6182                       [(set GR64:$dst, (ctpop (loadi64 addr:$src))),
6183                        (implicit EFLAGS)]>, XS;
6184 }
6185
6186
6187
6188 // SS41I_unop_rm_int_v16 - SSE 4.1 unary operator whose type is v8i16.
6189 multiclass SS41I_unop_rm_int_v16<bits<8> opc, string OpcodeStr,
6190                                  Intrinsic IntId128> {
6191   def rr128 : SS48I<opc, MRMSrcReg, (outs VR128:$dst),
6192                     (ins VR128:$src),
6193                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
6194                     [(set VR128:$dst, (IntId128 VR128:$src))]>, OpSize;
6195   def rm128 : SS48I<opc, MRMSrcMem, (outs VR128:$dst),
6196                      (ins i128mem:$src),
6197                      !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
6198                      [(set VR128:$dst,
6199                        (IntId128
6200                         (bitconvert (memopv2i64 addr:$src))))]>, OpSize;
6201 }
6202
6203 let Predicates = [HasAVX] in
6204 defm VPHMINPOSUW : SS41I_unop_rm_int_v16 <0x41, "vphminposuw",
6205                                          int_x86_sse41_phminposuw>, VEX;
6206 defm PHMINPOSUW : SS41I_unop_rm_int_v16 <0x41, "phminposuw",
6207                                          int_x86_sse41_phminposuw>;
6208
6209 /// SS41I_binop_rm_int - Simple SSE 4.1 binary operator
6210 multiclass SS41I_binop_rm_int<bits<8> opc, string OpcodeStr,
6211                               Intrinsic IntId128, bit Is2Addr = 1> {
6212   let isCommutable = 1 in
6213   def rr : SS48I<opc, MRMSrcReg, (outs VR128:$dst),
6214        (ins VR128:$src1, VR128:$src2),
6215        !if(Is2Addr,
6216            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
6217            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
6218        [(set VR128:$dst, (IntId128 VR128:$src1, VR128:$src2))]>, OpSize;
6219   def rm : SS48I<opc, MRMSrcMem, (outs VR128:$dst),
6220        (ins VR128:$src1, i128mem:$src2),
6221        !if(Is2Addr,
6222            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
6223            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
6224        [(set VR128:$dst,
6225          (IntId128 VR128:$src1,
6226           (bitconvert (memopv2i64 addr:$src2))))]>, OpSize;
6227 }
6228
6229 /// SS41I_binop_rm_int - Simple SSE 4.1 binary operator
6230 multiclass SS41I_binop_rm_int_y<bits<8> opc, string OpcodeStr,
6231                                 Intrinsic IntId256> {
6232   let isCommutable = 1 in
6233   def Yrr : SS48I<opc, MRMSrcReg, (outs VR256:$dst),
6234        (ins VR256:$src1, VR256:$src2),
6235        !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6236        [(set VR256:$dst, (IntId256 VR256:$src1, VR256:$src2))]>, OpSize;
6237   def Yrm : SS48I<opc, MRMSrcMem, (outs VR256:$dst),
6238        (ins VR256:$src1, i256mem:$src2),
6239        !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6240        [(set VR256:$dst,
6241          (IntId256 VR256:$src1,
6242           (bitconvert (memopv4i64 addr:$src2))))]>, OpSize;
6243 }
6244
6245 let Predicates = [HasAVX] in {
6246   let isCommutable = 0 in
6247   defm VPACKUSDW : SS41I_binop_rm_int<0x2B, "vpackusdw", int_x86_sse41_packusdw,
6248                                                          0>, VEX_4V;
6249   defm VPMINSB   : SS41I_binop_rm_int<0x38, "vpminsb",   int_x86_sse41_pminsb,
6250                                                          0>, VEX_4V;
6251   defm VPMINSD   : SS41I_binop_rm_int<0x39, "vpminsd",   int_x86_sse41_pminsd,
6252                                                          0>, VEX_4V;
6253   defm VPMINUD   : SS41I_binop_rm_int<0x3B, "vpminud",   int_x86_sse41_pminud,
6254                                                          0>, VEX_4V;
6255   defm VPMINUW   : SS41I_binop_rm_int<0x3A, "vpminuw",   int_x86_sse41_pminuw,
6256                                                          0>, VEX_4V;
6257   defm VPMAXSB   : SS41I_binop_rm_int<0x3C, "vpmaxsb",   int_x86_sse41_pmaxsb,
6258                                                          0>, VEX_4V;
6259   defm VPMAXSD   : SS41I_binop_rm_int<0x3D, "vpmaxsd",   int_x86_sse41_pmaxsd,
6260                                                          0>, VEX_4V;
6261   defm VPMAXUD   : SS41I_binop_rm_int<0x3F, "vpmaxud",   int_x86_sse41_pmaxud,
6262                                                          0>, VEX_4V;
6263   defm VPMAXUW   : SS41I_binop_rm_int<0x3E, "vpmaxuw",   int_x86_sse41_pmaxuw,
6264                                                          0>, VEX_4V;
6265   defm VPMULDQ   : SS41I_binop_rm_int<0x28, "vpmuldq",   int_x86_sse41_pmuldq,
6266                                                          0>, VEX_4V;
6267 }
6268
6269 let Predicates = [HasAVX2] in {
6270   let isCommutable = 0 in
6271   defm VPACKUSDW : SS41I_binop_rm_int_y<0x2B, "vpackusdw",
6272                                         int_x86_avx2_packusdw>, VEX_4V;
6273   defm VPMINSB   : SS41I_binop_rm_int_y<0x38, "vpminsb",
6274                                         int_x86_avx2_pmins_b>, VEX_4V;
6275   defm VPMINSD   : SS41I_binop_rm_int_y<0x39, "vpminsd",
6276                                         int_x86_avx2_pmins_d>, VEX_4V;
6277   defm VPMINUD   : SS41I_binop_rm_int_y<0x3B, "vpminud",
6278                                         int_x86_avx2_pminu_d>, VEX_4V;
6279   defm VPMINUW   : SS41I_binop_rm_int_y<0x3A, "vpminuw",
6280                                         int_x86_avx2_pminu_w>, VEX_4V;
6281   defm VPMAXSB   : SS41I_binop_rm_int_y<0x3C, "vpmaxsb",
6282                                         int_x86_avx2_pmaxs_b>, VEX_4V;
6283   defm VPMAXSD   : SS41I_binop_rm_int_y<0x3D, "vpmaxsd",
6284                                         int_x86_avx2_pmaxs_d>, VEX_4V;
6285   defm VPMAXUD   : SS41I_binop_rm_int_y<0x3F, "vpmaxud",
6286                                         int_x86_avx2_pmaxu_d>, VEX_4V;
6287   defm VPMAXUW   : SS41I_binop_rm_int_y<0x3E, "vpmaxuw",
6288                                         int_x86_avx2_pmaxu_w>, VEX_4V;
6289   defm VPMULDQ   : SS41I_binop_rm_int_y<0x28, "vpmuldq",
6290                                         int_x86_avx2_pmul_dq>, VEX_4V;
6291 }
6292
6293 let Constraints = "$src1 = $dst" in {
6294   let isCommutable = 0 in
6295   defm PACKUSDW : SS41I_binop_rm_int<0x2B, "packusdw", int_x86_sse41_packusdw>;
6296   defm PMINSB   : SS41I_binop_rm_int<0x38, "pminsb",   int_x86_sse41_pminsb>;
6297   defm PMINSD   : SS41I_binop_rm_int<0x39, "pminsd",   int_x86_sse41_pminsd>;
6298   defm PMINUD   : SS41I_binop_rm_int<0x3B, "pminud",   int_x86_sse41_pminud>;
6299   defm PMINUW   : SS41I_binop_rm_int<0x3A, "pminuw",   int_x86_sse41_pminuw>;
6300   defm PMAXSB   : SS41I_binop_rm_int<0x3C, "pmaxsb",   int_x86_sse41_pmaxsb>;
6301   defm PMAXSD   : SS41I_binop_rm_int<0x3D, "pmaxsd",   int_x86_sse41_pmaxsd>;
6302   defm PMAXUD   : SS41I_binop_rm_int<0x3F, "pmaxud",   int_x86_sse41_pmaxud>;
6303   defm PMAXUW   : SS41I_binop_rm_int<0x3E, "pmaxuw",   int_x86_sse41_pmaxuw>;
6304   defm PMULDQ   : SS41I_binop_rm_int<0x28, "pmuldq",   int_x86_sse41_pmuldq>;
6305 }
6306
6307 /// SS48I_binop_rm - Simple SSE41 binary operator.
6308 multiclass SS48I_binop_rm<bits<8> opc, string OpcodeStr, SDNode OpNode,
6309                           ValueType OpVT, RegisterClass RC, PatFrag memop_frag,
6310                           X86MemOperand x86memop, bit Is2Addr = 1> {
6311   let isCommutable = 1 in
6312   def rr : SS48I<opc, MRMSrcReg, (outs RC:$dst),
6313        (ins RC:$src1, RC:$src2),
6314        !if(Is2Addr,
6315            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
6316            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
6317        [(set RC:$dst, (OpVT (OpNode RC:$src1, RC:$src2)))]>, OpSize;
6318   def rm : SS48I<opc, MRMSrcMem, (outs RC:$dst),
6319        (ins RC:$src1, x86memop:$src2),
6320        !if(Is2Addr,
6321            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
6322            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
6323        [(set RC:$dst,
6324          (OpVT (OpNode RC:$src1,
6325           (bitconvert (memop_frag addr:$src2)))))]>, OpSize;
6326 }
6327
6328 let Predicates = [HasAVX] in {
6329   defm VPMULLD  : SS48I_binop_rm<0x40, "vpmulld", mul, v4i32, VR128,
6330                                 memopv2i64, i128mem, 0>, VEX_4V;
6331   defm VPCMPEQQ : SS48I_binop_rm<0x29, "vpcmpeqq", X86pcmpeq, v2i64, VR128,
6332                                  memopv2i64, i128mem, 0>, VEX_4V;
6333 }
6334 let Predicates = [HasAVX2] in {
6335   defm VPMULLDY  : SS48I_binop_rm<0x40, "vpmulld", mul, v8i32, VR256,
6336                                   memopv4i64, i256mem, 0>, VEX_4V;
6337   defm VPCMPEQQY : SS48I_binop_rm<0x29, "vpcmpeqq", X86pcmpeq, v4i64, VR256,
6338                                   memopv4i64, i256mem, 0>, VEX_4V;
6339 }
6340
6341 let Constraints = "$src1 = $dst" in {
6342   defm PMULLD  : SS48I_binop_rm<0x40, "pmulld", mul, v4i32, VR128,
6343                                 memopv2i64, i128mem>;
6344   defm PCMPEQQ : SS48I_binop_rm<0x29, "pcmpeqq", X86pcmpeq, v2i64, VR128,
6345                                 memopv2i64, i128mem>;
6346 }
6347
6348 /// SS41I_binop_rmi_int - SSE 4.1 binary operator with 8-bit immediate
6349 multiclass SS41I_binop_rmi_int<bits<8> opc, string OpcodeStr,
6350                  Intrinsic IntId, RegisterClass RC, PatFrag memop_frag,
6351                  X86MemOperand x86memop, bit Is2Addr = 1> {
6352   let isCommutable = 1 in
6353   def rri : SS4AIi8<opc, MRMSrcReg, (outs RC:$dst),
6354         (ins RC:$src1, RC:$src2, u32u8imm:$src3),
6355         !if(Is2Addr,
6356             !strconcat(OpcodeStr,
6357                 "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6358             !strconcat(OpcodeStr,
6359                 "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6360         [(set RC:$dst, (IntId RC:$src1, RC:$src2, imm:$src3))]>,
6361         OpSize;
6362   def rmi : SS4AIi8<opc, MRMSrcMem, (outs RC:$dst),
6363         (ins RC:$src1, x86memop:$src2, u32u8imm:$src3),
6364         !if(Is2Addr,
6365             !strconcat(OpcodeStr,
6366                 "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6367             !strconcat(OpcodeStr,
6368                 "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6369         [(set RC:$dst,
6370           (IntId RC:$src1,
6371            (bitconvert (memop_frag addr:$src2)), imm:$src3))]>,
6372         OpSize;
6373 }
6374
6375 let Predicates = [HasAVX] in {
6376   let isCommutable = 0 in {
6377     let ExeDomain = SSEPackedSingle in {
6378     defm VBLENDPS : SS41I_binop_rmi_int<0x0C, "vblendps", int_x86_sse41_blendps,
6379                                         VR128, memopv4f32, i128mem, 0>, VEX_4V;
6380     defm VBLENDPSY : SS41I_binop_rmi_int<0x0C, "vblendps",
6381               int_x86_avx_blend_ps_256, VR256, memopv8f32, i256mem, 0>, VEX_4V;
6382     }
6383     let ExeDomain = SSEPackedDouble in {
6384     defm VBLENDPD : SS41I_binop_rmi_int<0x0D, "vblendpd", int_x86_sse41_blendpd,
6385                                         VR128, memopv2f64, i128mem, 0>, VEX_4V;
6386     defm VBLENDPDY : SS41I_binop_rmi_int<0x0D, "vblendpd",
6387               int_x86_avx_blend_pd_256, VR256, memopv4f64, i256mem, 0>, VEX_4V;
6388     }
6389   defm VPBLENDW : SS41I_binop_rmi_int<0x0E, "vpblendw", int_x86_sse41_pblendw,
6390                                       VR128, memopv2i64, i128mem, 0>, VEX_4V;
6391   defm VMPSADBW : SS41I_binop_rmi_int<0x42, "vmpsadbw", int_x86_sse41_mpsadbw,
6392                                       VR128, memopv2i64, i128mem, 0>, VEX_4V;
6393   }
6394   let ExeDomain = SSEPackedSingle in
6395   defm VDPPS : SS41I_binop_rmi_int<0x40, "vdpps", int_x86_sse41_dpps,
6396                                    VR128, memopv4f32, i128mem, 0>, VEX_4V;
6397   let ExeDomain = SSEPackedDouble in
6398   defm VDPPD : SS41I_binop_rmi_int<0x41, "vdppd", int_x86_sse41_dppd,
6399                                    VR128, memopv2f64, i128mem, 0>, VEX_4V;
6400   let ExeDomain = SSEPackedSingle in
6401   defm VDPPSY : SS41I_binop_rmi_int<0x40, "vdpps", int_x86_avx_dp_ps_256,
6402                                    VR256, memopv8f32, i256mem, 0>, VEX_4V;
6403 }
6404
6405 let Predicates = [HasAVX2] in {
6406   let isCommutable = 0 in {
6407   defm VPBLENDWY : SS41I_binop_rmi_int<0x0E, "vpblendw", int_x86_avx2_pblendw,
6408                                        VR256, memopv4i64, i256mem, 0>, VEX_4V;
6409   defm VMPSADBWY : SS41I_binop_rmi_int<0x42, "vmpsadbw", int_x86_avx2_mpsadbw,
6410                                        VR256, memopv4i64, i256mem, 0>, VEX_4V;
6411   }
6412 }
6413
6414 let Constraints = "$src1 = $dst" in {
6415   let isCommutable = 0 in {
6416   let ExeDomain = SSEPackedSingle in
6417   defm BLENDPS : SS41I_binop_rmi_int<0x0C, "blendps", int_x86_sse41_blendps,
6418                                      VR128, memopv4f32, i128mem>;
6419   let ExeDomain = SSEPackedDouble in
6420   defm BLENDPD : SS41I_binop_rmi_int<0x0D, "blendpd", int_x86_sse41_blendpd,
6421                                      VR128, memopv2f64, i128mem>;
6422   defm PBLENDW : SS41I_binop_rmi_int<0x0E, "pblendw", int_x86_sse41_pblendw,
6423                                      VR128, memopv2i64, i128mem>;
6424   defm MPSADBW : SS41I_binop_rmi_int<0x42, "mpsadbw", int_x86_sse41_mpsadbw,
6425                                      VR128, memopv2i64, i128mem>;
6426   }
6427   let ExeDomain = SSEPackedSingle in
6428   defm DPPS : SS41I_binop_rmi_int<0x40, "dpps", int_x86_sse41_dpps,
6429                                   VR128, memopv4f32, i128mem>;
6430   let ExeDomain = SSEPackedDouble in
6431   defm DPPD : SS41I_binop_rmi_int<0x41, "dppd", int_x86_sse41_dppd,
6432                                   VR128, memopv2f64, i128mem>;
6433 }
6434
6435 /// SS41I_quaternary_int_avx - AVX SSE 4.1 with 4 operators
6436 multiclass SS41I_quaternary_int_avx<bits<8> opc, string OpcodeStr,
6437                                     RegisterClass RC, X86MemOperand x86memop,
6438                                     PatFrag mem_frag, Intrinsic IntId> {
6439   def rr : Ii8<opc, MRMSrcReg, (outs RC:$dst),
6440                   (ins RC:$src1, RC:$src2, RC:$src3),
6441                   !strconcat(OpcodeStr,
6442                     "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
6443                   [(set RC:$dst, (IntId RC:$src1, RC:$src2, RC:$src3))],
6444                   IIC_DEFAULT, SSEPackedInt>, OpSize, TA, VEX_4V, VEX_I8IMM;
6445
6446   def rm : Ii8<opc, MRMSrcMem, (outs RC:$dst),
6447                   (ins RC:$src1, x86memop:$src2, RC:$src3),
6448                   !strconcat(OpcodeStr,
6449                     "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
6450                   [(set RC:$dst,
6451                         (IntId RC:$src1, (bitconvert (mem_frag addr:$src2)),
6452                                RC:$src3))],
6453                   IIC_DEFAULT, SSEPackedInt>, OpSize, TA, VEX_4V, VEX_I8IMM;
6454 }
6455
6456 let Predicates = [HasAVX] in {
6457 let ExeDomain = SSEPackedDouble in {
6458 defm VBLENDVPD  : SS41I_quaternary_int_avx<0x4B, "vblendvpd", VR128, i128mem,
6459                                            memopv2f64, int_x86_sse41_blendvpd>;
6460 defm VBLENDVPDY : SS41I_quaternary_int_avx<0x4B, "vblendvpd", VR256, i256mem,
6461                                          memopv4f64, int_x86_avx_blendv_pd_256>;
6462 } // ExeDomain = SSEPackedDouble
6463 let ExeDomain = SSEPackedSingle in {
6464 defm VBLENDVPS  : SS41I_quaternary_int_avx<0x4A, "vblendvps", VR128, i128mem,
6465                                            memopv4f32, int_x86_sse41_blendvps>;
6466 defm VBLENDVPSY : SS41I_quaternary_int_avx<0x4A, "vblendvps", VR256, i256mem,
6467                                          memopv8f32, int_x86_avx_blendv_ps_256>;
6468 } // ExeDomain = SSEPackedSingle
6469 defm VPBLENDVB  : SS41I_quaternary_int_avx<0x4C, "vpblendvb", VR128, i128mem,
6470                                            memopv2i64, int_x86_sse41_pblendvb>;
6471 }
6472
6473 let Predicates = [HasAVX2] in {
6474 defm VPBLENDVBY : SS41I_quaternary_int_avx<0x4C, "vpblendvb", VR256, i256mem,
6475                                            memopv4i64, int_x86_avx2_pblendvb>;
6476 }
6477
6478 let Predicates = [HasAVX] in {
6479   def : Pat<(v16i8 (vselect (v16i8 VR128:$mask), (v16i8 VR128:$src1),
6480                             (v16i8 VR128:$src2))),
6481             (VPBLENDVBrr VR128:$src2, VR128:$src1, VR128:$mask)>;
6482   def : Pat<(v4i32 (vselect (v4i32 VR128:$mask), (v4i32 VR128:$src1),
6483                             (v4i32 VR128:$src2))),
6484             (VBLENDVPSrr VR128:$src2, VR128:$src1, VR128:$mask)>;
6485   def : Pat<(v4f32 (vselect (v4i32 VR128:$mask), (v4f32 VR128:$src1),
6486                             (v4f32 VR128:$src2))),
6487             (VBLENDVPSrr VR128:$src2, VR128:$src1, VR128:$mask)>;
6488   def : Pat<(v2i64 (vselect (v2i64 VR128:$mask), (v2i64 VR128:$src1),
6489                             (v2i64 VR128:$src2))),
6490             (VBLENDVPDrr VR128:$src2, VR128:$src1, VR128:$mask)>;
6491   def : Pat<(v2f64 (vselect (v2i64 VR128:$mask), (v2f64 VR128:$src1),
6492                             (v2f64 VR128:$src2))),
6493             (VBLENDVPDrr VR128:$src2, VR128:$src1, VR128:$mask)>;
6494   def : Pat<(v8i32 (vselect (v8i32 VR256:$mask), (v8i32 VR256:$src1),
6495                             (v8i32 VR256:$src2))),
6496             (VBLENDVPSYrr VR256:$src2, VR256:$src1, VR256:$mask)>;
6497   def : Pat<(v8f32 (vselect (v8i32 VR256:$mask), (v8f32 VR256:$src1),
6498                             (v8f32 VR256:$src2))),
6499             (VBLENDVPSYrr VR256:$src2, VR256:$src1, VR256:$mask)>;
6500   def : Pat<(v4i64 (vselect (v4i64 VR256:$mask), (v4i64 VR256:$src1),
6501                             (v4i64 VR256:$src2))),
6502             (VBLENDVPDYrr VR256:$src2, VR256:$src1, VR256:$mask)>;
6503   def : Pat<(v4f64 (vselect (v4i64 VR256:$mask), (v4f64 VR256:$src1),
6504                             (v4f64 VR256:$src2))),
6505             (VBLENDVPDYrr VR256:$src2, VR256:$src1, VR256:$mask)>;
6506 }
6507
6508 let Predicates = [HasAVX2] in {
6509   def : Pat<(v32i8 (vselect (v32i8 VR256:$mask), (v32i8 VR256:$src1),
6510                             (v32i8 VR256:$src2))),
6511             (VPBLENDVBYrr VR256:$src2, VR256:$src1, VR256:$mask)>;
6512 }
6513
6514 /// SS41I_ternary_int - SSE 4.1 ternary operator
6515 let Uses = [XMM0], Constraints = "$src1 = $dst" in {
6516   multiclass SS41I_ternary_int<bits<8> opc, string OpcodeStr, PatFrag mem_frag,
6517                                Intrinsic IntId> {
6518     def rr0 : SS48I<opc, MRMSrcReg, (outs VR128:$dst),
6519                     (ins VR128:$src1, VR128:$src2),
6520                     !strconcat(OpcodeStr,
6521                      "\t{$src2, $dst|$dst, $src2}"),
6522                     [(set VR128:$dst, (IntId VR128:$src1, VR128:$src2, XMM0))]>,
6523                     OpSize;
6524
6525     def rm0 : SS48I<opc, MRMSrcMem, (outs VR128:$dst),
6526                     (ins VR128:$src1, i128mem:$src2),
6527                     !strconcat(OpcodeStr,
6528                      "\t{$src2, $dst|$dst, $src2}"),
6529                     [(set VR128:$dst,
6530                       (IntId VR128:$src1,
6531                        (bitconvert (mem_frag addr:$src2)), XMM0))]>, OpSize;
6532   }
6533 }
6534
6535 let ExeDomain = SSEPackedDouble in
6536 defm BLENDVPD : SS41I_ternary_int<0x15, "blendvpd", memopv2f64,
6537                                   int_x86_sse41_blendvpd>;
6538 let ExeDomain = SSEPackedSingle in
6539 defm BLENDVPS : SS41I_ternary_int<0x14, "blendvps", memopv4f32,
6540                                   int_x86_sse41_blendvps>;
6541 defm PBLENDVB : SS41I_ternary_int<0x10, "pblendvb", memopv2i64,
6542                                   int_x86_sse41_pblendvb>;
6543
6544 let Predicates = [HasSSE41] in {
6545   def : Pat<(v16i8 (vselect (v16i8 XMM0), (v16i8 VR128:$src1),
6546                             (v16i8 VR128:$src2))),
6547             (PBLENDVBrr0 VR128:$src2, VR128:$src1)>;
6548   def : Pat<(v4i32 (vselect (v4i32 XMM0), (v4i32 VR128:$src1),
6549                             (v4i32 VR128:$src2))),
6550             (BLENDVPSrr0 VR128:$src2, VR128:$src1)>;
6551   def : Pat<(v4f32 (vselect (v4i32 XMM0), (v4f32 VR128:$src1),
6552                             (v4f32 VR128:$src2))),
6553             (BLENDVPSrr0 VR128:$src2, VR128:$src1)>;
6554   def : Pat<(v2i64 (vselect (v2i64 XMM0), (v2i64 VR128:$src1),
6555                             (v2i64 VR128:$src2))),
6556             (BLENDVPDrr0 VR128:$src2, VR128:$src1)>;
6557   def : Pat<(v2f64 (vselect (v2i64 XMM0), (v2f64 VR128:$src1),
6558                             (v2f64 VR128:$src2))),
6559             (BLENDVPDrr0 VR128:$src2, VR128:$src1)>;
6560 }
6561
6562 let Predicates = [HasAVX] in
6563 def VMOVNTDQArm : SS48I<0x2A, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
6564                        "vmovntdqa\t{$src, $dst|$dst, $src}",
6565                        [(set VR128:$dst, (int_x86_sse41_movntdqa addr:$src))]>,
6566                        OpSize, VEX;
6567 let Predicates = [HasAVX2] in
6568 def VMOVNTDQAYrm : SS48I<0x2A, MRMSrcMem, (outs VR256:$dst), (ins i256mem:$src),
6569                          "vmovntdqa\t{$src, $dst|$dst, $src}",
6570                          [(set VR256:$dst, (int_x86_avx2_movntdqa addr:$src))]>,
6571                          OpSize, VEX;
6572 def MOVNTDQArm : SS48I<0x2A, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
6573                        "movntdqa\t{$src, $dst|$dst, $src}",
6574                        [(set VR128:$dst, (int_x86_sse41_movntdqa addr:$src))]>,
6575                        OpSize;
6576
6577 //===----------------------------------------------------------------------===//
6578 // SSE4.2 - Compare Instructions
6579 //===----------------------------------------------------------------------===//
6580
6581 /// SS42I_binop_rm - Simple SSE 4.2 binary operator
6582 multiclass SS42I_binop_rm<bits<8> opc, string OpcodeStr, SDNode OpNode,
6583                           ValueType OpVT, RegisterClass RC, PatFrag memop_frag,
6584                           X86MemOperand x86memop, bit Is2Addr = 1> {
6585   def rr : SS428I<opc, MRMSrcReg, (outs RC:$dst),
6586        (ins RC:$src1, RC:$src2),
6587        !if(Is2Addr,
6588            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
6589            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
6590        [(set RC:$dst, (OpVT (OpNode RC:$src1, RC:$src2)))]>,
6591        OpSize;
6592   def rm : SS428I<opc, MRMSrcMem, (outs RC:$dst),
6593        (ins RC:$src1, x86memop:$src2),
6594        !if(Is2Addr,
6595            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
6596            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
6597        [(set RC:$dst,
6598          (OpVT (OpNode RC:$src1, (memop_frag addr:$src2))))]>, OpSize;
6599 }
6600
6601 let Predicates = [HasAVX] in
6602   defm VPCMPGTQ : SS42I_binop_rm<0x37, "vpcmpgtq", X86pcmpgt, v2i64, VR128,
6603                                  memopv2i64, i128mem, 0>, VEX_4V;
6604
6605 let Predicates = [HasAVX2] in
6606   defm VPCMPGTQY : SS42I_binop_rm<0x37, "vpcmpgtq", X86pcmpgt, v4i64, VR256,
6607                                   memopv4i64, i256mem, 0>, VEX_4V;
6608
6609 let Constraints = "$src1 = $dst" in
6610   defm PCMPGTQ : SS42I_binop_rm<0x37, "pcmpgtq", X86pcmpgt, v2i64, VR128,
6611                                 memopv2i64, i128mem>;
6612
6613 //===----------------------------------------------------------------------===//
6614 // SSE4.2 - String/text Processing Instructions
6615 //===----------------------------------------------------------------------===//
6616
6617 // Packed Compare Implicit Length Strings, Return Mask
6618 multiclass pseudo_pcmpistrm<string asm> {
6619   def REG : PseudoI<(outs VR128:$dst),
6620                     (ins VR128:$src1, VR128:$src2, i8imm:$src3),
6621     [(set VR128:$dst, (int_x86_sse42_pcmpistrm128 VR128:$src1, VR128:$src2,
6622                                                   imm:$src3))]>;
6623   def MEM : PseudoI<(outs VR128:$dst),
6624                     (ins VR128:$src1, i128mem:$src2, i8imm:$src3),
6625     [(set VR128:$dst, (int_x86_sse42_pcmpistrm128
6626                        VR128:$src1, (load addr:$src2), imm:$src3))]>;
6627 }
6628
6629 let Defs = [EFLAGS], usesCustomInserter = 1 in {
6630   let AddedComplexity = 1 in
6631     defm VPCMPISTRM128 : pseudo_pcmpistrm<"#VPCMPISTRM128">, Requires<[HasAVX]>;
6632   defm PCMPISTRM128 : pseudo_pcmpistrm<"#PCMPISTRM128">, Requires<[HasSSE42]>;
6633 }
6634
6635 let Defs = [XMM0, EFLAGS], neverHasSideEffects = 1, Predicates = [HasAVX] in {
6636   def VPCMPISTRM128rr : SS42AI<0x62, MRMSrcReg, (outs),
6637       (ins VR128:$src1, VR128:$src2, i8imm:$src3),
6638       "vpcmpistrm\t{$src3, $src2, $src1|$src1, $src2, $src3}", []>, OpSize, VEX;
6639   let mayLoad = 1 in
6640   def VPCMPISTRM128rm : SS42AI<0x62, MRMSrcMem, (outs),
6641       (ins VR128:$src1, i128mem:$src2, i8imm:$src3),
6642       "vpcmpistrm\t{$src3, $src2, $src1|$src1, $src2, $src3}", []>, OpSize, VEX;
6643 }
6644
6645 let Defs = [XMM0, EFLAGS], neverHasSideEffects = 1 in {
6646   def PCMPISTRM128rr : SS42AI<0x62, MRMSrcReg, (outs),
6647       (ins VR128:$src1, VR128:$src2, i8imm:$src3),
6648       "pcmpistrm\t{$src3, $src2, $src1|$src1, $src2, $src3}", []>, OpSize;
6649   let mayLoad = 1 in
6650   def PCMPISTRM128rm : SS42AI<0x62, MRMSrcMem, (outs),
6651       (ins VR128:$src1, i128mem:$src2, i8imm:$src3),
6652       "pcmpistrm\t{$src3, $src2, $src1|$src1, $src2, $src3}", []>, OpSize;
6653 }
6654
6655 // Packed Compare Explicit Length Strings, Return Mask
6656 multiclass pseudo_pcmpestrm<string asm> {
6657   def REG : PseudoI<(outs VR128:$dst),
6658                     (ins VR128:$src1, VR128:$src3, i8imm:$src5),
6659     [(set VR128:$dst, (int_x86_sse42_pcmpestrm128
6660                        VR128:$src1, EAX, VR128:$src3, EDX, imm:$src5))]>;
6661   def MEM : PseudoI<(outs VR128:$dst),
6662                     (ins VR128:$src1, i128mem:$src3, i8imm:$src5),
6663     [(set VR128:$dst, (int_x86_sse42_pcmpestrm128
6664                        VR128:$src1, EAX, (load addr:$src3), EDX, imm:$src5))]>;
6665 }
6666
6667 let Defs = [EFLAGS], Uses = [EAX, EDX], usesCustomInserter = 1 in {
6668   let AddedComplexity = 1 in
6669     defm VPCMPESTRM128 : pseudo_pcmpestrm<"#VPCMPESTRM128">, Requires<[HasAVX]>;
6670   defm PCMPESTRM128 : pseudo_pcmpestrm<"#PCMPESTRM128">, Requires<[HasSSE42]>;
6671 }
6672
6673 let Predicates = [HasAVX],
6674     Defs = [XMM0, EFLAGS], Uses = [EAX, EDX], neverHasSideEffects = 1 in {
6675   def VPCMPESTRM128rr : SS42AI<0x60, MRMSrcReg, (outs),
6676       (ins VR128:$src1, VR128:$src3, i8imm:$src5),
6677       "vpcmpestrm\t{$src5, $src3, $src1|$src1, $src3, $src5}", []>, OpSize, VEX;
6678   let mayLoad = 1 in
6679   def VPCMPESTRM128rm : SS42AI<0x60, MRMSrcMem, (outs),
6680       (ins VR128:$src1, i128mem:$src3, i8imm:$src5),
6681       "vpcmpestrm\t{$src5, $src3, $src1|$src1, $src3, $src5}", []>, OpSize, VEX;
6682 }
6683
6684 let Defs = [XMM0, EFLAGS], Uses = [EAX, EDX], neverHasSideEffects = 1 in {
6685   def PCMPESTRM128rr : SS42AI<0x60, MRMSrcReg, (outs),
6686       (ins VR128:$src1, VR128:$src3, i8imm:$src5),
6687       "pcmpestrm\t{$src5, $src3, $src1|$src1, $src3, $src5}", []>, OpSize;
6688   let mayLoad = 1 in
6689   def PCMPESTRM128rm : SS42AI<0x60, MRMSrcMem, (outs),
6690       (ins VR128:$src1, i128mem:$src3, i8imm:$src5),
6691       "pcmpestrm\t{$src5, $src3, $src1|$src1, $src3, $src5}", []>, OpSize;
6692 }
6693
6694 // Packed Compare Implicit Length Strings, Return Index
6695 let Defs = [ECX, EFLAGS] in {
6696   multiclass SS42AI_pcmpistri<Intrinsic IntId128, string asm = "pcmpistri"> {
6697     def rr : SS42AI<0x63, MRMSrcReg, (outs),
6698       (ins VR128:$src1, VR128:$src2, i8imm:$src3),
6699       !strconcat(asm, "\t{$src3, $src2, $src1|$src1, $src2, $src3}"),
6700       [(set ECX, (IntId128 VR128:$src1, VR128:$src2, imm:$src3)),
6701        (implicit EFLAGS)]>, OpSize;
6702     def rm : SS42AI<0x63, MRMSrcMem, (outs),
6703       (ins VR128:$src1, i128mem:$src2, i8imm:$src3),
6704       !strconcat(asm, "\t{$src3, $src2, $src1|$src1, $src2, $src3}"),
6705       [(set ECX, (IntId128 VR128:$src1, (load addr:$src2), imm:$src3)),
6706        (implicit EFLAGS)]>, OpSize;
6707   }
6708 }
6709
6710 let Predicates = [HasAVX] in {
6711 defm VPCMPISTRI  : SS42AI_pcmpistri<int_x86_sse42_pcmpistri128, "vpcmpistri">,
6712                                     VEX;
6713 defm VPCMPISTRIA : SS42AI_pcmpistri<int_x86_sse42_pcmpistria128, "vpcmpistri">,
6714                                     VEX;
6715 defm VPCMPISTRIC : SS42AI_pcmpistri<int_x86_sse42_pcmpistric128, "vpcmpistri">,
6716                                     VEX;
6717 defm VPCMPISTRIO : SS42AI_pcmpistri<int_x86_sse42_pcmpistrio128, "vpcmpistri">,
6718                                     VEX;
6719 defm VPCMPISTRIS : SS42AI_pcmpistri<int_x86_sse42_pcmpistris128, "vpcmpistri">,
6720                                     VEX;
6721 defm VPCMPISTRIZ : SS42AI_pcmpistri<int_x86_sse42_pcmpistriz128, "vpcmpistri">,
6722                                     VEX;
6723 }
6724
6725 defm PCMPISTRI  : SS42AI_pcmpistri<int_x86_sse42_pcmpistri128>;
6726 defm PCMPISTRIA : SS42AI_pcmpistri<int_x86_sse42_pcmpistria128>;
6727 defm PCMPISTRIC : SS42AI_pcmpistri<int_x86_sse42_pcmpistric128>;
6728 defm PCMPISTRIO : SS42AI_pcmpistri<int_x86_sse42_pcmpistrio128>;
6729 defm PCMPISTRIS : SS42AI_pcmpistri<int_x86_sse42_pcmpistris128>;
6730 defm PCMPISTRIZ : SS42AI_pcmpistri<int_x86_sse42_pcmpistriz128>;
6731
6732 // Packed Compare Explicit Length Strings, Return Index
6733 let Defs = [ECX, EFLAGS], Uses = [EAX, EDX] in {
6734   multiclass SS42AI_pcmpestri<Intrinsic IntId128, string asm = "pcmpestri"> {
6735     def rr : SS42AI<0x61, MRMSrcReg, (outs),
6736       (ins VR128:$src1, VR128:$src3, i8imm:$src5),
6737       !strconcat(asm, "\t{$src5, $src3, $src1|$src1, $src3, $src5}"),
6738       [(set ECX, (IntId128 VR128:$src1, EAX, VR128:$src3, EDX, imm:$src5)),
6739        (implicit EFLAGS)]>, OpSize;
6740     def rm : SS42AI<0x61, MRMSrcMem, (outs),
6741       (ins VR128:$src1, i128mem:$src3, i8imm:$src5),
6742       !strconcat(asm, "\t{$src5, $src3, $src1|$src1, $src3, $src5}"),
6743        [(set ECX,
6744              (IntId128 VR128:$src1, EAX, (load addr:$src3), EDX, imm:$src5)),
6745         (implicit EFLAGS)]>, OpSize;
6746   }
6747 }
6748
6749 let Predicates = [HasAVX] in {
6750 defm VPCMPESTRI  : SS42AI_pcmpestri<int_x86_sse42_pcmpestri128, "vpcmpestri">,
6751                                     VEX;
6752 defm VPCMPESTRIA : SS42AI_pcmpestri<int_x86_sse42_pcmpestria128, "vpcmpestri">,
6753                                     VEX;
6754 defm VPCMPESTRIC : SS42AI_pcmpestri<int_x86_sse42_pcmpestric128, "vpcmpestri">,
6755                                     VEX;
6756 defm VPCMPESTRIO : SS42AI_pcmpestri<int_x86_sse42_pcmpestrio128, "vpcmpestri">,
6757                                     VEX;
6758 defm VPCMPESTRIS : SS42AI_pcmpestri<int_x86_sse42_pcmpestris128, "vpcmpestri">,
6759                                     VEX;
6760 defm VPCMPESTRIZ : SS42AI_pcmpestri<int_x86_sse42_pcmpestriz128, "vpcmpestri">,
6761                                     VEX;
6762 }
6763
6764 defm PCMPESTRI  : SS42AI_pcmpestri<int_x86_sse42_pcmpestri128>;
6765 defm PCMPESTRIA : SS42AI_pcmpestri<int_x86_sse42_pcmpestria128>;
6766 defm PCMPESTRIC : SS42AI_pcmpestri<int_x86_sse42_pcmpestric128>;
6767 defm PCMPESTRIO : SS42AI_pcmpestri<int_x86_sse42_pcmpestrio128>;
6768 defm PCMPESTRIS : SS42AI_pcmpestri<int_x86_sse42_pcmpestris128>;
6769 defm PCMPESTRIZ : SS42AI_pcmpestri<int_x86_sse42_pcmpestriz128>;
6770
6771 //===----------------------------------------------------------------------===//
6772 // SSE4.2 - CRC Instructions
6773 //===----------------------------------------------------------------------===//
6774
6775 // No CRC instructions have AVX equivalents
6776
6777 // crc intrinsic instruction
6778 // This set of instructions are only rm, the only difference is the size
6779 // of r and m.
6780 let Constraints = "$src1 = $dst" in {
6781   def CRC32r32m8  : SS42FI<0xF0, MRMSrcMem, (outs GR32:$dst),
6782                       (ins GR32:$src1, i8mem:$src2),
6783                       "crc32{b} \t{$src2, $src1|$src1, $src2}",
6784                        [(set GR32:$dst,
6785                          (int_x86_sse42_crc32_32_8 GR32:$src1,
6786                          (load addr:$src2)))]>;
6787   def CRC32r32r8  : SS42FI<0xF0, MRMSrcReg, (outs GR32:$dst),
6788                       (ins GR32:$src1, GR8:$src2),
6789                       "crc32{b} \t{$src2, $src1|$src1, $src2}",
6790                        [(set GR32:$dst,
6791                          (int_x86_sse42_crc32_32_8 GR32:$src1, GR8:$src2))]>;
6792   def CRC32r32m16  : SS42FI<0xF1, MRMSrcMem, (outs GR32:$dst),
6793                       (ins GR32:$src1, i16mem:$src2),
6794                       "crc32{w} \t{$src2, $src1|$src1, $src2}",
6795                        [(set GR32:$dst,
6796                          (int_x86_sse42_crc32_32_16 GR32:$src1,
6797                          (load addr:$src2)))]>,
6798                          OpSize;
6799   def CRC32r32r16  : SS42FI<0xF1, MRMSrcReg, (outs GR32:$dst),
6800                       (ins GR32:$src1, GR16:$src2),
6801                       "crc32{w} \t{$src2, $src1|$src1, $src2}",
6802                        [(set GR32:$dst,
6803                          (int_x86_sse42_crc32_32_16 GR32:$src1, GR16:$src2))]>,
6804                          OpSize;
6805   def CRC32r32m32  : SS42FI<0xF1, MRMSrcMem, (outs GR32:$dst),
6806                       (ins GR32:$src1, i32mem:$src2),
6807                       "crc32{l} \t{$src2, $src1|$src1, $src2}",
6808                        [(set GR32:$dst,
6809                          (int_x86_sse42_crc32_32_32 GR32:$src1,
6810                          (load addr:$src2)))]>;
6811   def CRC32r32r32  : SS42FI<0xF1, MRMSrcReg, (outs GR32:$dst),
6812                       (ins GR32:$src1, GR32:$src2),
6813                       "crc32{l} \t{$src2, $src1|$src1, $src2}",
6814                        [(set GR32:$dst,
6815                          (int_x86_sse42_crc32_32_32 GR32:$src1, GR32:$src2))]>;
6816   def CRC32r64m8  : SS42FI<0xF0, MRMSrcMem, (outs GR64:$dst),
6817                       (ins GR64:$src1, i8mem:$src2),
6818                       "crc32{b} \t{$src2, $src1|$src1, $src2}",
6819                        [(set GR64:$dst,
6820                          (int_x86_sse42_crc32_64_8 GR64:$src1,
6821                          (load addr:$src2)))]>,
6822                          REX_W;
6823   def CRC32r64r8  : SS42FI<0xF0, MRMSrcReg, (outs GR64:$dst),
6824                       (ins GR64:$src1, GR8:$src2),
6825                       "crc32{b} \t{$src2, $src1|$src1, $src2}",
6826                        [(set GR64:$dst,
6827                          (int_x86_sse42_crc32_64_8 GR64:$src1, GR8:$src2))]>,
6828                          REX_W;
6829   def CRC32r64m64  : SS42FI<0xF1, MRMSrcMem, (outs GR64:$dst),
6830                       (ins GR64:$src1, i64mem:$src2),
6831                       "crc32{q} \t{$src2, $src1|$src1, $src2}",
6832                        [(set GR64:$dst,
6833                          (int_x86_sse42_crc32_64_64 GR64:$src1,
6834                          (load addr:$src2)))]>,
6835                          REX_W;
6836   def CRC32r64r64  : SS42FI<0xF1, MRMSrcReg, (outs GR64:$dst),
6837                       (ins GR64:$src1, GR64:$src2),
6838                       "crc32{q} \t{$src2, $src1|$src1, $src2}",
6839                        [(set GR64:$dst,
6840                          (int_x86_sse42_crc32_64_64 GR64:$src1, GR64:$src2))]>,
6841                          REX_W;
6842 }
6843
6844 //===----------------------------------------------------------------------===//
6845 // AES-NI Instructions
6846 //===----------------------------------------------------------------------===//
6847
6848 multiclass AESI_binop_rm_int<bits<8> opc, string OpcodeStr,
6849                               Intrinsic IntId128, bit Is2Addr = 1> {
6850   def rr : AES8I<opc, MRMSrcReg, (outs VR128:$dst),
6851        (ins VR128:$src1, VR128:$src2),
6852        !if(Is2Addr,
6853            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
6854            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
6855        [(set VR128:$dst, (IntId128 VR128:$src1, VR128:$src2))]>,
6856        OpSize;
6857   def rm : AES8I<opc, MRMSrcMem, (outs VR128:$dst),
6858        (ins VR128:$src1, i128mem:$src2),
6859        !if(Is2Addr,
6860            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
6861            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
6862        [(set VR128:$dst,
6863          (IntId128 VR128:$src1, (memopv2i64 addr:$src2)))]>, OpSize;
6864 }
6865
6866 // Perform One Round of an AES Encryption/Decryption Flow
6867 let Predicates = [HasAVX, HasAES] in {
6868   defm VAESENC          : AESI_binop_rm_int<0xDC, "vaesenc",
6869                          int_x86_aesni_aesenc, 0>, VEX_4V;
6870   defm VAESENCLAST      : AESI_binop_rm_int<0xDD, "vaesenclast",
6871                          int_x86_aesni_aesenclast, 0>, VEX_4V;
6872   defm VAESDEC          : AESI_binop_rm_int<0xDE, "vaesdec",
6873                          int_x86_aesni_aesdec, 0>, VEX_4V;
6874   defm VAESDECLAST      : AESI_binop_rm_int<0xDF, "vaesdeclast",
6875                          int_x86_aesni_aesdeclast, 0>, VEX_4V;
6876 }
6877
6878 let Constraints = "$src1 = $dst" in {
6879   defm AESENC          : AESI_binop_rm_int<0xDC, "aesenc",
6880                          int_x86_aesni_aesenc>;
6881   defm AESENCLAST      : AESI_binop_rm_int<0xDD, "aesenclast",
6882                          int_x86_aesni_aesenclast>;
6883   defm AESDEC          : AESI_binop_rm_int<0xDE, "aesdec",
6884                          int_x86_aesni_aesdec>;
6885   defm AESDECLAST      : AESI_binop_rm_int<0xDF, "aesdeclast",
6886                          int_x86_aesni_aesdeclast>;
6887 }
6888
6889 // Perform the AES InvMixColumn Transformation
6890 let Predicates = [HasAVX, HasAES] in {
6891   def VAESIMCrr : AES8I<0xDB, MRMSrcReg, (outs VR128:$dst),
6892       (ins VR128:$src1),
6893       "vaesimc\t{$src1, $dst|$dst, $src1}",
6894       [(set VR128:$dst,
6895         (int_x86_aesni_aesimc VR128:$src1))]>,
6896       OpSize, VEX;
6897   def VAESIMCrm : AES8I<0xDB, MRMSrcMem, (outs VR128:$dst),
6898       (ins i128mem:$src1),
6899       "vaesimc\t{$src1, $dst|$dst, $src1}",
6900       [(set VR128:$dst, (int_x86_aesni_aesimc (memopv2i64 addr:$src1)))]>,
6901       OpSize, VEX;
6902 }
6903 def AESIMCrr : AES8I<0xDB, MRMSrcReg, (outs VR128:$dst),
6904   (ins VR128:$src1),
6905   "aesimc\t{$src1, $dst|$dst, $src1}",
6906   [(set VR128:$dst,
6907     (int_x86_aesni_aesimc VR128:$src1))]>,
6908   OpSize;
6909 def AESIMCrm : AES8I<0xDB, MRMSrcMem, (outs VR128:$dst),
6910   (ins i128mem:$src1),
6911   "aesimc\t{$src1, $dst|$dst, $src1}",
6912   [(set VR128:$dst, (int_x86_aesni_aesimc (memopv2i64 addr:$src1)))]>,
6913   OpSize;
6914
6915 // AES Round Key Generation Assist
6916 let Predicates = [HasAVX, HasAES] in {
6917   def VAESKEYGENASSIST128rr : AESAI<0xDF, MRMSrcReg, (outs VR128:$dst),
6918       (ins VR128:$src1, i8imm:$src2),
6919       "vaeskeygenassist\t{$src2, $src1, $dst|$dst, $src1, $src2}",
6920       [(set VR128:$dst,
6921         (int_x86_aesni_aeskeygenassist VR128:$src1, imm:$src2))]>,
6922       OpSize, VEX;
6923   def VAESKEYGENASSIST128rm : AESAI<0xDF, MRMSrcMem, (outs VR128:$dst),
6924       (ins i128mem:$src1, i8imm:$src2),
6925       "vaeskeygenassist\t{$src2, $src1, $dst|$dst, $src1, $src2}",
6926       [(set VR128:$dst,
6927         (int_x86_aesni_aeskeygenassist (memopv2i64 addr:$src1), imm:$src2))]>,
6928       OpSize, VEX;
6929 }
6930 def AESKEYGENASSIST128rr : AESAI<0xDF, MRMSrcReg, (outs VR128:$dst),
6931   (ins VR128:$src1, i8imm:$src2),
6932   "aeskeygenassist\t{$src2, $src1, $dst|$dst, $src1, $src2}",
6933   [(set VR128:$dst,
6934     (int_x86_aesni_aeskeygenassist VR128:$src1, imm:$src2))]>,
6935   OpSize;
6936 def AESKEYGENASSIST128rm : AESAI<0xDF, MRMSrcMem, (outs VR128:$dst),
6937   (ins i128mem:$src1, i8imm:$src2),
6938   "aeskeygenassist\t{$src2, $src1, $dst|$dst, $src1, $src2}",
6939   [(set VR128:$dst,
6940     (int_x86_aesni_aeskeygenassist (memopv2i64 addr:$src1), imm:$src2))]>,
6941   OpSize;
6942
6943 //===----------------------------------------------------------------------===//
6944 // CLMUL Instructions
6945 //===----------------------------------------------------------------------===//
6946
6947 // Carry-less Multiplication instructions
6948 let neverHasSideEffects = 1 in {
6949 // AVX carry-less Multiplication instructions
6950 def VPCLMULQDQrr : AVXCLMULIi8<0x44, MRMSrcReg, (outs VR128:$dst),
6951            (ins VR128:$src1, VR128:$src2, i8imm:$src3),
6952            "vpclmulqdq\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
6953            []>;
6954
6955 let mayLoad = 1 in
6956 def VPCLMULQDQrm : AVXCLMULIi8<0x44, MRMSrcMem, (outs VR128:$dst),
6957            (ins VR128:$src1, i128mem:$src2, i8imm:$src3),
6958            "vpclmulqdq\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
6959            []>;
6960
6961 let Constraints = "$src1 = $dst" in {
6962 def PCLMULQDQrr : CLMULIi8<0x44, MRMSrcReg, (outs VR128:$dst),
6963            (ins VR128:$src1, VR128:$src2, i8imm:$src3),
6964            "pclmulqdq\t{$src3, $src2, $dst|$dst, $src2, $src3}",
6965            []>;
6966
6967 let mayLoad = 1 in
6968 def PCLMULQDQrm : CLMULIi8<0x44, MRMSrcMem, (outs VR128:$dst),
6969            (ins VR128:$src1, i128mem:$src2, i8imm:$src3),
6970            "pclmulqdq\t{$src3, $src2, $dst|$dst, $src2, $src3}",
6971            []>;
6972 } // Constraints = "$src1 = $dst"
6973 } // neverHasSideEffects = 1
6974
6975
6976 multiclass pclmul_alias<string asm, int immop> {
6977   def : InstAlias<!strconcat("pclmul", asm, 
6978                            "dq {$src, $dst|$dst, $src}"),
6979                   (PCLMULQDQrr VR128:$dst, VR128:$src, immop)>;
6980
6981   def : InstAlias<!strconcat("pclmul", asm, 
6982                              "dq {$src, $dst|$dst, $src}"),
6983                   (PCLMULQDQrm VR128:$dst, i128mem:$src, immop)>;
6984
6985   def : InstAlias<!strconcat("vpclmul", asm, 
6986                              "dq {$src2, $src1, $dst|$dst, $src1, $src2}"),
6987                   (VPCLMULQDQrr VR128:$dst, VR128:$src1, VR128:$src2, immop)>;
6988
6989   def : InstAlias<!strconcat("vpclmul", asm, 
6990                              "dq {$src2, $src1, $dst|$dst, $src1, $src2}"),
6991                   (VPCLMULQDQrm VR128:$dst, VR128:$src1, i128mem:$src2, immop)>;
6992 }
6993 defm : pclmul_alias<"hqhq", 0x11>;
6994 defm : pclmul_alias<"hqlq", 0x01>;
6995 defm : pclmul_alias<"lqhq", 0x10>;
6996 defm : pclmul_alias<"lqlq", 0x00>;
6997
6998 //===----------------------------------------------------------------------===//
6999 // AVX Instructions
7000 //===----------------------------------------------------------------------===//
7001
7002 //===----------------------------------------------------------------------===//
7003 // VBROADCAST - Load from memory and broadcast to all elements of the
7004 //              destination operand
7005 //
7006 class avx_broadcast<bits<8> opc, string OpcodeStr, RegisterClass RC,
7007                     X86MemOperand x86memop, Intrinsic Int> :
7008   AVX8I<opc, MRMSrcMem, (outs RC:$dst), (ins x86memop:$src),
7009         !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
7010         [(set RC:$dst, (Int addr:$src))]>, VEX;
7011
7012 // AVX2 adds register forms
7013 class avx2_broadcast_reg<bits<8> opc, string OpcodeStr, RegisterClass RC,
7014                          Intrinsic Int> :
7015   AVX28I<opc, MRMSrcReg, (outs RC:$dst), (ins VR128:$src),
7016          !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
7017          [(set RC:$dst, (Int VR128:$src))]>, VEX;
7018
7019 let ExeDomain = SSEPackedSingle in {
7020   def VBROADCASTSSrm  : avx_broadcast<0x18, "vbroadcastss", VR128, f32mem,
7021                                       int_x86_avx_vbroadcast_ss>;
7022   def VBROADCASTSSYrm : avx_broadcast<0x18, "vbroadcastss", VR256, f32mem,
7023                                       int_x86_avx_vbroadcast_ss_256>;
7024 }
7025 let ExeDomain = SSEPackedDouble in
7026 def VBROADCASTSDrm  : avx_broadcast<0x19, "vbroadcastsd", VR256, f64mem,
7027                                     int_x86_avx_vbroadcast_sd_256>;
7028 def VBROADCASTF128 : avx_broadcast<0x1A, "vbroadcastf128", VR256, f128mem,
7029                                    int_x86_avx_vbroadcastf128_pd_256>;
7030
7031 let ExeDomain = SSEPackedSingle in {
7032   def VBROADCASTSSrr  : avx2_broadcast_reg<0x18, "vbroadcastss", VR128,
7033                                            int_x86_avx2_vbroadcast_ss_ps>;
7034   def VBROADCASTSSYrr : avx2_broadcast_reg<0x18, "vbroadcastss", VR256,
7035                                            int_x86_avx2_vbroadcast_ss_ps_256>;
7036 }
7037 let ExeDomain = SSEPackedDouble in
7038 def VBROADCASTSDrr  : avx2_broadcast_reg<0x19, "vbroadcastsd", VR256,
7039                                          int_x86_avx2_vbroadcast_sd_pd_256>;
7040
7041 let Predicates = [HasAVX2] in
7042 def VBROADCASTI128 : avx_broadcast<0x5A, "vbroadcasti128", VR256, i128mem,
7043                                    int_x86_avx2_vbroadcasti128>;
7044
7045 let Predicates = [HasAVX] in
7046 def : Pat<(int_x86_avx_vbroadcastf128_ps_256 addr:$src),
7047           (VBROADCASTF128 addr:$src)>;
7048
7049
7050 //===----------------------------------------------------------------------===//
7051 // VINSERTF128 - Insert packed floating-point values
7052 //
7053 let neverHasSideEffects = 1, ExeDomain = SSEPackedSingle in {
7054 def VINSERTF128rr : AVXAIi8<0x18, MRMSrcReg, (outs VR256:$dst),
7055           (ins VR256:$src1, VR128:$src2, i8imm:$src3),
7056           "vinsertf128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
7057           []>, VEX_4V;
7058 let mayLoad = 1 in
7059 def VINSERTF128rm : AVXAIi8<0x18, MRMSrcMem, (outs VR256:$dst),
7060           (ins VR256:$src1, f128mem:$src2, i8imm:$src3),
7061           "vinsertf128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
7062           []>, VEX_4V;
7063 }
7064
7065 let Predicates = [HasAVX] in {
7066 def : Pat<(int_x86_avx_vinsertf128_pd_256 VR256:$src1, VR128:$src2, imm:$src3),
7067           (VINSERTF128rr VR256:$src1, VR128:$src2, imm:$src3)>;
7068 def : Pat<(int_x86_avx_vinsertf128_ps_256 VR256:$src1, VR128:$src2, imm:$src3),
7069           (VINSERTF128rr VR256:$src1, VR128:$src2, imm:$src3)>;
7070 def : Pat<(int_x86_avx_vinsertf128_si_256 VR256:$src1, VR128:$src2, imm:$src3),
7071           (VINSERTF128rr VR256:$src1, VR128:$src2, imm:$src3)>;
7072 }
7073
7074 //===----------------------------------------------------------------------===//
7075 // VEXTRACTF128 - Extract packed floating-point values
7076 //
7077 let neverHasSideEffects = 1, ExeDomain = SSEPackedSingle in {
7078 def VEXTRACTF128rr : AVXAIi8<0x19, MRMDestReg, (outs VR128:$dst),
7079           (ins VR256:$src1, i8imm:$src2),
7080           "vextractf128\t{$src2, $src1, $dst|$dst, $src1, $src2}",
7081           []>, VEX;
7082 let mayStore = 1 in
7083 def VEXTRACTF128mr : AVXAIi8<0x19, MRMDestMem, (outs),
7084           (ins f128mem:$dst, VR256:$src1, i8imm:$src2),
7085           "vextractf128\t{$src2, $src1, $dst|$dst, $src1, $src2}",
7086           []>, VEX;
7087 }
7088
7089 let Predicates = [HasAVX] in {
7090 def : Pat<(int_x86_avx_vextractf128_pd_256 VR256:$src1, imm:$src2),
7091           (VEXTRACTF128rr VR256:$src1, imm:$src2)>;
7092 def : Pat<(int_x86_avx_vextractf128_ps_256 VR256:$src1, imm:$src2),
7093           (VEXTRACTF128rr VR256:$src1, imm:$src2)>;
7094 def : Pat<(int_x86_avx_vextractf128_si_256 VR256:$src1, imm:$src2),
7095           (VEXTRACTF128rr VR256:$src1, imm:$src2)>;
7096 }
7097
7098 //===----------------------------------------------------------------------===//
7099 // VMASKMOV - Conditional SIMD Packed Loads and Stores
7100 //
7101 multiclass avx_movmask_rm<bits<8> opc_rm, bits<8> opc_mr, string OpcodeStr,
7102                           Intrinsic IntLd, Intrinsic IntLd256,
7103                           Intrinsic IntSt, Intrinsic IntSt256> {
7104   def rm  : AVX8I<opc_rm, MRMSrcMem, (outs VR128:$dst),
7105              (ins VR128:$src1, f128mem:$src2),
7106              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7107              [(set VR128:$dst, (IntLd addr:$src2, VR128:$src1))]>,
7108              VEX_4V;
7109   def Yrm : AVX8I<opc_rm, MRMSrcMem, (outs VR256:$dst),
7110              (ins VR256:$src1, f256mem:$src2),
7111              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7112              [(set VR256:$dst, (IntLd256 addr:$src2, VR256:$src1))]>,
7113              VEX_4V;
7114   def mr  : AVX8I<opc_mr, MRMDestMem, (outs),
7115              (ins f128mem:$dst, VR128:$src1, VR128:$src2),
7116              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7117              [(IntSt addr:$dst, VR128:$src1, VR128:$src2)]>, VEX_4V;
7118   def Ymr : AVX8I<opc_mr, MRMDestMem, (outs),
7119              (ins f256mem:$dst, VR256:$src1, VR256:$src2),
7120              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7121              [(IntSt256 addr:$dst, VR256:$src1, VR256:$src2)]>, VEX_4V;
7122 }
7123
7124 let ExeDomain = SSEPackedSingle in
7125 defm VMASKMOVPS : avx_movmask_rm<0x2C, 0x2E, "vmaskmovps",
7126                                  int_x86_avx_maskload_ps,
7127                                  int_x86_avx_maskload_ps_256,
7128                                  int_x86_avx_maskstore_ps,
7129                                  int_x86_avx_maskstore_ps_256>;
7130 let ExeDomain = SSEPackedDouble in
7131 defm VMASKMOVPD : avx_movmask_rm<0x2D, 0x2F, "vmaskmovpd",
7132                                  int_x86_avx_maskload_pd,
7133                                  int_x86_avx_maskload_pd_256,
7134                                  int_x86_avx_maskstore_pd,
7135                                  int_x86_avx_maskstore_pd_256>;
7136
7137 //===----------------------------------------------------------------------===//
7138 // VPERMIL - Permute Single and Double Floating-Point Values
7139 //
7140 multiclass avx_permil<bits<8> opc_rm, bits<8> opc_rmi, string OpcodeStr,
7141                       RegisterClass RC, X86MemOperand x86memop_f,
7142                       X86MemOperand x86memop_i, PatFrag f_frag, PatFrag i_frag,
7143                       Intrinsic IntVar, Intrinsic IntImm> {
7144   def rr  : AVX8I<opc_rm, MRMSrcReg, (outs RC:$dst),
7145              (ins RC:$src1, RC:$src2),
7146              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7147              [(set RC:$dst, (IntVar RC:$src1, RC:$src2))]>, VEX_4V;
7148   def rm  : AVX8I<opc_rm, MRMSrcMem, (outs RC:$dst),
7149              (ins RC:$src1, x86memop_i:$src2),
7150              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7151              [(set RC:$dst, (IntVar RC:$src1,
7152                              (bitconvert (i_frag addr:$src2))))]>, VEX_4V;
7153
7154   def ri  : AVXAIi8<opc_rmi, MRMSrcReg, (outs RC:$dst),
7155              (ins RC:$src1, i8imm:$src2),
7156              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7157              [(set RC:$dst, (IntImm RC:$src1, imm:$src2))]>, VEX;
7158   def mi  : AVXAIi8<opc_rmi, MRMSrcMem, (outs RC:$dst),
7159              (ins x86memop_f:$src1, i8imm:$src2),
7160              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7161              [(set RC:$dst, (IntImm (f_frag addr:$src1), imm:$src2))]>, VEX;
7162 }
7163
7164 let ExeDomain = SSEPackedSingle in {
7165   defm VPERMILPS  : avx_permil<0x0C, 0x04, "vpermilps", VR128, f128mem, i128mem,
7166                                memopv4f32, memopv2i64,
7167                                int_x86_avx_vpermilvar_ps,
7168                                int_x86_avx_vpermil_ps>;
7169   defm VPERMILPSY : avx_permil<0x0C, 0x04, "vpermilps", VR256, f256mem, i256mem,
7170                                memopv8f32, memopv4i64,
7171                                int_x86_avx_vpermilvar_ps_256,
7172                                int_x86_avx_vpermil_ps_256>;
7173 }
7174 let ExeDomain = SSEPackedDouble in {
7175   defm VPERMILPD  : avx_permil<0x0D, 0x05, "vpermilpd", VR128, f128mem, i128mem,
7176                                memopv2f64, memopv2i64,
7177                                int_x86_avx_vpermilvar_pd,
7178                                int_x86_avx_vpermil_pd>;
7179   defm VPERMILPDY : avx_permil<0x0D, 0x05, "vpermilpd", VR256, f256mem, i256mem,
7180                                memopv4f64, memopv4i64,
7181                                int_x86_avx_vpermilvar_pd_256,
7182                                int_x86_avx_vpermil_pd_256>;
7183 }
7184
7185 let Predicates = [HasAVX] in {
7186 def : Pat<(v8f32 (X86VPermilp VR256:$src1, (i8 imm:$imm))),
7187           (VPERMILPSYri VR256:$src1, imm:$imm)>;
7188 def : Pat<(v4f64 (X86VPermilp VR256:$src1, (i8 imm:$imm))),
7189           (VPERMILPDYri VR256:$src1, imm:$imm)>;
7190 def : Pat<(v8i32 (X86VPermilp VR256:$src1, (i8 imm:$imm))),
7191           (VPERMILPSYri VR256:$src1, imm:$imm)>;
7192 def : Pat<(v4i64 (X86VPermilp VR256:$src1, (i8 imm:$imm))),
7193           (VPERMILPDYri VR256:$src1, imm:$imm)>;
7194 def : Pat<(v8f32 (X86VPermilp (memopv8f32 addr:$src1), (i8 imm:$imm))),
7195           (VPERMILPSYmi addr:$src1, imm:$imm)>;
7196 def : Pat<(v4f64 (X86VPermilp (memopv4f64 addr:$src1), (i8 imm:$imm))),
7197           (VPERMILPDYmi addr:$src1, imm:$imm)>;
7198 def : Pat<(v8i32 (X86VPermilp (bc_v8i32 (memopv4i64 addr:$src1)),
7199                                (i8 imm:$imm))),
7200           (VPERMILPSYmi addr:$src1, imm:$imm)>;
7201 def : Pat<(v4i64 (X86VPermilp (memopv4i64 addr:$src1), (i8 imm:$imm))),
7202           (VPERMILPDYmi addr:$src1, imm:$imm)>;
7203 }
7204
7205 //===----------------------------------------------------------------------===//
7206 // VPERM2F128 - Permute Floating-Point Values in 128-bit chunks
7207 //
7208 let ExeDomain = SSEPackedSingle in {
7209 def VPERM2F128rr : AVXAIi8<0x06, MRMSrcReg, (outs VR256:$dst),
7210           (ins VR256:$src1, VR256:$src2, i8imm:$src3),
7211           "vperm2f128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
7212           [(set VR256:$dst, (v8f32 (X86VPerm2x128 VR256:$src1, VR256:$src2,
7213                               (i8 imm:$src3))))]>, VEX_4V;
7214 def VPERM2F128rm : AVXAIi8<0x06, MRMSrcMem, (outs VR256:$dst),
7215           (ins VR256:$src1, f256mem:$src2, i8imm:$src3),
7216           "vperm2f128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
7217           [(set VR256:$dst, (X86VPerm2x128 VR256:$src1, (memopv8f32 addr:$src2),
7218                              (i8 imm:$src3)))]>, VEX_4V;
7219 }
7220
7221 let Predicates = [HasAVX] in {
7222 def : Pat<(int_x86_avx_vperm2f128_si_256 VR256:$src1, VR256:$src2, imm:$src3),
7223           (VPERM2F128rr VR256:$src1, VR256:$src2, imm:$src3)>;
7224 def : Pat<(int_x86_avx_vperm2f128_si_256
7225                   VR256:$src1, (bc_v8i32 (memopv4i64 addr:$src2)), imm:$src3),
7226           (VPERM2F128rm VR256:$src1, addr:$src2, imm:$src3)>;
7227
7228 def : Pat<(v8i32 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
7229           (VPERM2F128rr VR256:$src1, VR256:$src2, imm:$imm)>;
7230 def : Pat<(v4i64 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
7231           (VPERM2F128rr VR256:$src1, VR256:$src2, imm:$imm)>;
7232 def : Pat<(v4f64 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
7233           (VPERM2F128rr VR256:$src1, VR256:$src2, imm:$imm)>;
7234 def : Pat<(v32i8 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
7235           (VPERM2F128rr VR256:$src1, VR256:$src2, imm:$imm)>;
7236 def : Pat<(v16i16 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
7237           (VPERM2F128rr VR256:$src1, VR256:$src2, imm:$imm)>;
7238
7239 def : Pat<(v8f32 (X86VPerm2x128 VR256:$src1,
7240                   (memopv8f32 addr:$src2), (i8 imm:$imm))),
7241           (VPERM2F128rm VR256:$src1, addr:$src2, imm:$imm)>;
7242 def : Pat<(v8i32 (X86VPerm2x128 VR256:$src1,
7243                   (bc_v8i32 (memopv4i64 addr:$src2)), (i8 imm:$imm))),
7244           (VPERM2F128rm VR256:$src1, addr:$src2, imm:$imm)>;
7245 def : Pat<(v4i64 (X86VPerm2x128 VR256:$src1,
7246                   (memopv4i64 addr:$src2), (i8 imm:$imm))),
7247           (VPERM2F128rm VR256:$src1, addr:$src2, imm:$imm)>;
7248 def : Pat<(v4f64 (X86VPerm2x128 VR256:$src1,
7249                   (memopv4f64 addr:$src2), (i8 imm:$imm))),
7250           (VPERM2F128rm VR256:$src1, addr:$src2, imm:$imm)>;
7251 def : Pat<(v32i8 (X86VPerm2x128 VR256:$src1,
7252                   (bc_v32i8 (memopv4i64 addr:$src2)), (i8 imm:$imm))),
7253           (VPERM2F128rm VR256:$src1, addr:$src2, imm:$imm)>;
7254 def : Pat<(v16i16 (X86VPerm2x128 VR256:$src1,
7255                   (bc_v16i16 (memopv4i64 addr:$src2)), (i8 imm:$imm))),
7256           (VPERM2F128rm VR256:$src1, addr:$src2, imm:$imm)>;
7257 }
7258
7259 //===----------------------------------------------------------------------===//
7260 // VZERO - Zero YMM registers
7261 //
7262 let Defs = [YMM0, YMM1, YMM2, YMM3, YMM4, YMM5, YMM6, YMM7,
7263             YMM8, YMM9, YMM10, YMM11, YMM12, YMM13, YMM14, YMM15] in {
7264   // Zero All YMM registers
7265   def VZEROALL : I<0x77, RawFrm, (outs), (ins), "vzeroall",
7266                   [(int_x86_avx_vzeroall)]>, TB, VEX, VEX_L, Requires<[HasAVX]>;
7267
7268   // Zero Upper bits of YMM registers
7269   def VZEROUPPER : I<0x77, RawFrm, (outs), (ins), "vzeroupper",
7270                      [(int_x86_avx_vzeroupper)]>, TB, VEX, Requires<[HasAVX]>;
7271 }
7272
7273 //===----------------------------------------------------------------------===//
7274 // Half precision conversion instructions
7275 //===----------------------------------------------------------------------===//
7276 multiclass f16c_ph2ps<RegisterClass RC, X86MemOperand x86memop, Intrinsic Int> {
7277 let Predicates = [HasAVX, HasF16C] in {
7278   def rr : I<0x13, MRMSrcReg, (outs RC:$dst), (ins VR128:$src),
7279              "vcvtph2ps\t{$src, $dst|$dst, $src}",
7280              [(set RC:$dst, (Int VR128:$src))]>,
7281              T8, OpSize, VEX;
7282   let neverHasSideEffects = 1, mayLoad = 1 in
7283   def rm : I<0x13, MRMSrcMem, (outs RC:$dst), (ins x86memop:$src),
7284              "vcvtph2ps\t{$src, $dst|$dst, $src}", []>, T8, OpSize, VEX;
7285 }
7286 }
7287
7288 multiclass f16c_ps2ph<RegisterClass RC, X86MemOperand x86memop, Intrinsic Int> {
7289 let Predicates = [HasAVX, HasF16C] in {
7290   def rr : Ii8<0x1D, MRMDestReg, (outs VR128:$dst),
7291                (ins RC:$src1, i32i8imm:$src2),
7292                "vcvtps2ph\t{$src2, $src1, $dst|$dst, $src1, $src2}",
7293                [(set VR128:$dst, (Int RC:$src1, imm:$src2))]>,
7294                TA, OpSize, VEX;
7295   let neverHasSideEffects = 1, mayLoad = 1 in
7296   def mr : Ii8<0x1D, MRMDestMem, (outs x86memop:$dst),
7297                (ins RC:$src1, i32i8imm:$src2),
7298                "vcvtps2ph\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>,
7299                TA, OpSize, VEX;
7300 }
7301 }
7302
7303 defm VCVTPH2PS  : f16c_ph2ps<VR128, f64mem, int_x86_vcvtph2ps_128>;
7304 defm VCVTPH2PSY : f16c_ph2ps<VR256, f128mem, int_x86_vcvtph2ps_256>;
7305 defm VCVTPS2PH  : f16c_ps2ph<VR128, f64mem, int_x86_vcvtps2ph_128>;
7306 defm VCVTPS2PHY : f16c_ps2ph<VR256, f128mem, int_x86_vcvtps2ph_256>;
7307
7308 //===----------------------------------------------------------------------===//
7309 // AVX2 Instructions
7310 //===----------------------------------------------------------------------===//
7311
7312 /// AVX2_binop_rmi_int - AVX2 binary operator with 8-bit immediate
7313 multiclass AVX2_binop_rmi_int<bits<8> opc, string OpcodeStr,
7314                  Intrinsic IntId, RegisterClass RC, PatFrag memop_frag,
7315                  X86MemOperand x86memop> {
7316   let isCommutable = 1 in
7317   def rri : AVX2AIi8<opc, MRMSrcReg, (outs RC:$dst),
7318         (ins RC:$src1, RC:$src2, u32u8imm:$src3),
7319         !strconcat(OpcodeStr,
7320             "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
7321         [(set RC:$dst, (IntId RC:$src1, RC:$src2, imm:$src3))]>,
7322         VEX_4V;
7323   def rmi : AVX2AIi8<opc, MRMSrcMem, (outs RC:$dst),
7324         (ins RC:$src1, x86memop:$src2, u32u8imm:$src3),
7325         !strconcat(OpcodeStr,
7326             "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
7327         [(set RC:$dst,
7328           (IntId RC:$src1,
7329            (bitconvert (memop_frag addr:$src2)), imm:$src3))]>,
7330         VEX_4V;
7331 }
7332
7333 let isCommutable = 0 in {
7334 defm VPBLENDD : AVX2_binop_rmi_int<0x02, "vpblendd", int_x86_avx2_pblendd_128,
7335                                    VR128, memopv2i64, i128mem>;
7336 defm VPBLENDDY : AVX2_binop_rmi_int<0x02, "vpblendd", int_x86_avx2_pblendd_256,
7337                                     VR256, memopv4i64, i256mem>;
7338 }
7339
7340 //===----------------------------------------------------------------------===//
7341 // VPBROADCAST - Load from memory and broadcast to all elements of the
7342 //               destination operand
7343 //
7344 multiclass avx2_broadcast<bits<8> opc, string OpcodeStr,
7345                           X86MemOperand x86memop, PatFrag ld_frag,
7346                           Intrinsic Int128, Intrinsic Int256> {
7347   def rr : AVX28I<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
7348                   !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
7349                   [(set VR128:$dst, (Int128 VR128:$src))]>, VEX;
7350   def rm : AVX28I<opc, MRMSrcMem, (outs VR128:$dst), (ins x86memop:$src),
7351                   !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
7352                   [(set VR128:$dst,
7353                     (Int128 (scalar_to_vector (ld_frag addr:$src))))]>, VEX;
7354   def Yrr : AVX28I<opc, MRMSrcReg, (outs VR256:$dst), (ins VR128:$src),
7355                    !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
7356                    [(set VR256:$dst, (Int256 VR128:$src))]>, VEX;
7357   def Yrm : AVX28I<opc, MRMSrcMem, (outs VR256:$dst), (ins x86memop:$src),
7358                    !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
7359                    [(set VR256:$dst,
7360                     (Int256 (scalar_to_vector (ld_frag addr:$src))))]>, VEX;
7361 }
7362
7363 defm VPBROADCASTB  : avx2_broadcast<0x78, "vpbroadcastb", i8mem, loadi8,
7364                                     int_x86_avx2_pbroadcastb_128,
7365                                     int_x86_avx2_pbroadcastb_256>;
7366 defm VPBROADCASTW  : avx2_broadcast<0x79, "vpbroadcastw", i16mem, loadi16,
7367                                     int_x86_avx2_pbroadcastw_128,
7368                                     int_x86_avx2_pbroadcastw_256>;
7369 defm VPBROADCASTD  : avx2_broadcast<0x58, "vpbroadcastd", i32mem, loadi32,
7370                                     int_x86_avx2_pbroadcastd_128,
7371                                     int_x86_avx2_pbroadcastd_256>;
7372 defm VPBROADCASTQ  : avx2_broadcast<0x59, "vpbroadcastq", i64mem, loadi64,
7373                                     int_x86_avx2_pbroadcastq_128,
7374                                     int_x86_avx2_pbroadcastq_256>;
7375
7376 let Predicates = [HasAVX2] in {
7377   def : Pat<(v16i8 (X86VBroadcast (loadi8 addr:$src))),
7378           (VPBROADCASTBrm addr:$src)>;
7379   def : Pat<(v32i8 (X86VBroadcast (loadi8 addr:$src))),
7380           (VPBROADCASTBYrm addr:$src)>;
7381   def : Pat<(v8i16 (X86VBroadcast (loadi16 addr:$src))),
7382           (VPBROADCASTWrm addr:$src)>;
7383   def : Pat<(v16i16 (X86VBroadcast (loadi16 addr:$src))),
7384           (VPBROADCASTWYrm addr:$src)>;
7385   def : Pat<(v4i32 (X86VBroadcast (loadi32 addr:$src))),
7386           (VPBROADCASTDrm addr:$src)>;
7387   def : Pat<(v8i32 (X86VBroadcast (loadi32 addr:$src))),
7388           (VPBROADCASTDYrm addr:$src)>;
7389   def : Pat<(v2i64 (X86VBroadcast (loadi64 addr:$src))),
7390           (VPBROADCASTQrm addr:$src)>;
7391   def : Pat<(v4i64 (X86VBroadcast (loadi64 addr:$src))),
7392           (VPBROADCASTQYrm addr:$src)>;
7393 }
7394
7395 // AVX1 broadcast patterns
7396 let Predicates = [HasAVX] in {
7397 def : Pat<(v8i32 (X86VBroadcast (loadi32 addr:$src))),
7398           (VBROADCASTSSYrm addr:$src)>;
7399 def : Pat<(v4i64 (X86VBroadcast (loadi64 addr:$src))),
7400           (VBROADCASTSDrm addr:$src)>;
7401 def : Pat<(v8f32 (X86VBroadcast (loadf32 addr:$src))),
7402           (VBROADCASTSSYrm addr:$src)>;
7403 def : Pat<(v4f64 (X86VBroadcast (loadf64 addr:$src))),
7404           (VBROADCASTSDrm addr:$src)>;
7405
7406 def : Pat<(v4f32 (X86VBroadcast (loadf32 addr:$src))),
7407           (VBROADCASTSSrm addr:$src)>;
7408 def : Pat<(v4i32 (X86VBroadcast (loadi32 addr:$src))),
7409           (VBROADCASTSSrm addr:$src)>;
7410 }
7411
7412 //===----------------------------------------------------------------------===//
7413 // VPERM - Permute instructions
7414 //
7415
7416 multiclass avx2_perm<bits<8> opc, string OpcodeStr, PatFrag mem_frag,
7417                      Intrinsic Int> {
7418   def Yrr : AVX28I<opc, MRMSrcReg, (outs VR256:$dst),
7419                    (ins VR256:$src1, VR256:$src2),
7420                    !strconcat(OpcodeStr,
7421                        "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7422                    [(set VR256:$dst, (Int VR256:$src1, VR256:$src2))]>, VEX_4V;
7423   def Yrm : AVX28I<opc, MRMSrcMem, (outs VR256:$dst),
7424                    (ins VR256:$src1, i256mem:$src2),
7425                    !strconcat(OpcodeStr,
7426                        "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7427                    [(set VR256:$dst, (Int VR256:$src1,
7428                                       (bitconvert (mem_frag addr:$src2))))]>,
7429                    VEX_4V;
7430 }
7431
7432 defm VPERMD : avx2_perm<0x36, "vpermd", memopv4i64, int_x86_avx2_permd>;
7433 let ExeDomain = SSEPackedSingle in
7434 defm VPERMPS : avx2_perm<0x16, "vpermps", memopv8f32, int_x86_avx2_permps>;
7435
7436 multiclass avx2_perm_imm<bits<8> opc, string OpcodeStr, PatFrag mem_frag,
7437                          Intrinsic Int> {
7438   def Yrr : AVX2AIi8<opc, MRMSrcReg, (outs VR256:$dst),
7439                      (ins VR256:$src1, i8imm:$src2),
7440                      !strconcat(OpcodeStr,
7441                          "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7442                      [(set VR256:$dst, (Int VR256:$src1, imm:$src2))]>, VEX;
7443   def Yrm : AVX2AIi8<opc, MRMSrcMem, (outs VR256:$dst),
7444                      (ins i256mem:$src1, i8imm:$src2),
7445                      !strconcat(OpcodeStr,
7446                          "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7447                      [(set VR256:$dst, (Int (mem_frag addr:$src1), imm:$src2))]>,
7448                      VEX;
7449 }
7450
7451 defm VPERMQ : avx2_perm_imm<0x00, "vpermq", memopv4i64, int_x86_avx2_permq>,
7452                             VEX_W;
7453 let ExeDomain = SSEPackedDouble in
7454 defm VPERMPD : avx2_perm_imm<0x01, "vpermpd", memopv4f64, int_x86_avx2_permpd>,
7455                              VEX_W;
7456
7457 //===----------------------------------------------------------------------===//
7458 // VPERM2I128 - Permute Floating-Point Values in 128-bit chunks
7459 //
7460 let AddedComplexity = 1 in {
7461 def VPERM2I128rr : AVX2AIi8<0x46, MRMSrcReg, (outs VR256:$dst),
7462           (ins VR256:$src1, VR256:$src2, i8imm:$src3),
7463           "vperm2i128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
7464           [(set VR256:$dst, (v4i64 (X86VPerm2x128 VR256:$src1, VR256:$src2,
7465                             (i8 imm:$src3))))]>, VEX_4V;
7466 def VPERM2I128rm : AVX2AIi8<0x46, MRMSrcMem, (outs VR256:$dst),
7467           (ins VR256:$src1, f256mem:$src2, i8imm:$src3),
7468           "vperm2i128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
7469           [(set VR256:$dst, (X86VPerm2x128 VR256:$src1, (memopv4i64 addr:$src2),
7470                              (i8 imm:$src3)))]>, VEX_4V;
7471 }
7472
7473 let Predicates = [HasAVX2], AddedComplexity = 1 in {
7474 def : Pat<(v8i32 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
7475           (VPERM2I128rr VR256:$src1, VR256:$src2, imm:$imm)>;
7476 def : Pat<(v32i8 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
7477           (VPERM2I128rr VR256:$src1, VR256:$src2, imm:$imm)>;
7478 def : Pat<(v16i16 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
7479           (VPERM2I128rr VR256:$src1, VR256:$src2, imm:$imm)>;
7480
7481 def : Pat<(v32i8 (X86VPerm2x128 VR256:$src1, (bc_v32i8 (memopv4i64 addr:$src2)),
7482                   (i8 imm:$imm))),
7483           (VPERM2I128rm VR256:$src1, addr:$src2, imm:$imm)>;
7484 def : Pat<(v16i16 (X86VPerm2x128 VR256:$src1,
7485                    (bc_v16i16 (memopv4i64 addr:$src2)), (i8 imm:$imm))),
7486           (VPERM2I128rm VR256:$src1, addr:$src2, imm:$imm)>;
7487 def : Pat<(v8i32 (X86VPerm2x128 VR256:$src1, (bc_v8i32 (memopv4i64 addr:$src2)),
7488                   (i8 imm:$imm))),
7489           (VPERM2I128rm VR256:$src1, addr:$src2, imm:$imm)>;
7490 }
7491
7492
7493 //===----------------------------------------------------------------------===//
7494 // VINSERTI128 - Insert packed integer values
7495 //
7496 def VINSERTI128rr : AVX2AIi8<0x38, MRMSrcReg, (outs VR256:$dst),
7497           (ins VR256:$src1, VR128:$src2, i8imm:$src3),
7498           "vinserti128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
7499           [(set VR256:$dst,
7500             (int_x86_avx2_vinserti128 VR256:$src1, VR128:$src2, imm:$src3))]>,
7501           VEX_4V;
7502 def VINSERTI128rm : AVX2AIi8<0x38, MRMSrcMem, (outs VR256:$dst),
7503           (ins VR256:$src1, i128mem:$src2, i8imm:$src3),
7504           "vinserti128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
7505           [(set VR256:$dst,
7506             (int_x86_avx2_vinserti128 VR256:$src1, (memopv2i64 addr:$src2),
7507              imm:$src3))]>, VEX_4V;
7508
7509 let Predicates = [HasAVX2] in {
7510 def : Pat<(vinsertf128_insert:$ins (v4i64 VR256:$src1), (v2i64 VR128:$src2),
7511                                    (i32 imm)),
7512           (VINSERTI128rr VR256:$src1, VR128:$src2,
7513                          (INSERT_get_vinsertf128_imm VR256:$ins))>;
7514 def : Pat<(vinsertf128_insert:$ins (v8i32 VR256:$src1), (v4i32 VR128:$src2),
7515                                    (i32 imm)),
7516           (VINSERTI128rr VR256:$src1, VR128:$src2,
7517                          (INSERT_get_vinsertf128_imm VR256:$ins))>;
7518 def : Pat<(vinsertf128_insert:$ins (v32i8 VR256:$src1), (v16i8 VR128:$src2),
7519                                    (i32 imm)),
7520           (VINSERTI128rr VR256:$src1, VR128:$src2,
7521                          (INSERT_get_vinsertf128_imm VR256:$ins))>;
7522 def : Pat<(vinsertf128_insert:$ins (v16i16 VR256:$src1), (v8i16 VR128:$src2),
7523                                    (i32 imm)),
7524           (VINSERTI128rr VR256:$src1, VR128:$src2,
7525                          (INSERT_get_vinsertf128_imm VR256:$ins))>;
7526 }
7527
7528 // AVX1 patterns
7529 let Predicates = [HasAVX] in {
7530 def : Pat<(vinsertf128_insert:$ins (v8f32 VR256:$src1), (v4f32 VR128:$src2),
7531                                    (i32 imm)),
7532           (VINSERTF128rr VR256:$src1, VR128:$src2,
7533                          (INSERT_get_vinsertf128_imm VR256:$ins))>;
7534 def : Pat<(vinsertf128_insert:$ins (v4f64 VR256:$src1), (v2f64 VR128:$src2),
7535                                    (i32 imm)),
7536           (VINSERTF128rr VR256:$src1, VR128:$src2,
7537                          (INSERT_get_vinsertf128_imm VR256:$ins))>;
7538 def : Pat<(vinsertf128_insert:$ins (v4i64 VR256:$src1), (v2i64 VR128:$src2),
7539                                    (i32 imm)),
7540           (VINSERTF128rr VR256:$src1, VR128:$src2,
7541                          (INSERT_get_vinsertf128_imm VR256:$ins))>;
7542 def : Pat<(vinsertf128_insert:$ins (v8i32 VR256:$src1), (v4i32 VR128:$src2),
7543                                    (i32 imm)),
7544           (VINSERTF128rr VR256:$src1, VR128:$src2,
7545                          (INSERT_get_vinsertf128_imm VR256:$ins))>;
7546 def : Pat<(vinsertf128_insert:$ins (v32i8 VR256:$src1), (v16i8 VR128:$src2),
7547                                    (i32 imm)),
7548           (VINSERTF128rr VR256:$src1, VR128:$src2,
7549                          (INSERT_get_vinsertf128_imm VR256:$ins))>;
7550 def : Pat<(vinsertf128_insert:$ins (v16i16 VR256:$src1), (v8i16 VR128:$src2),
7551                                    (i32 imm)),
7552           (VINSERTF128rr VR256:$src1, VR128:$src2,
7553                          (INSERT_get_vinsertf128_imm VR256:$ins))>;
7554 }
7555
7556 //===----------------------------------------------------------------------===//
7557 // VEXTRACTI128 - Extract packed integer values
7558 //
7559 def VEXTRACTI128rr : AVX2AIi8<0x39, MRMDestReg, (outs VR128:$dst),
7560           (ins VR256:$src1, i8imm:$src2),
7561           "vextracti128\t{$src2, $src1, $dst|$dst, $src1, $src2}",
7562           [(set VR128:$dst,
7563             (int_x86_avx2_vextracti128 VR256:$src1, imm:$src2))]>,
7564           VEX;
7565 let neverHasSideEffects = 1, mayStore = 1 in
7566 def VEXTRACTI128mr : AVX2AIi8<0x39, MRMDestMem, (outs),
7567           (ins i128mem:$dst, VR256:$src1, i8imm:$src2),
7568           "vextracti128\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>, VEX;
7569
7570 let Predicates = [HasAVX2] in {
7571 def : Pat<(vextractf128_extract:$ext VR256:$src1, (i32 imm)),
7572           (v2i64 (VEXTRACTI128rr
7573                     (v4i64 VR256:$src1),
7574                     (EXTRACT_get_vextractf128_imm VR128:$ext)))>;
7575 def : Pat<(vextractf128_extract:$ext VR256:$src1, (i32 imm)),
7576           (v4i32 (VEXTRACTI128rr
7577                     (v8i32 VR256:$src1),
7578                     (EXTRACT_get_vextractf128_imm VR128:$ext)))>;
7579 def : Pat<(vextractf128_extract:$ext VR256:$src1, (i32 imm)),
7580           (v8i16 (VEXTRACTI128rr
7581                     (v16i16 VR256:$src1),
7582                     (EXTRACT_get_vextractf128_imm VR128:$ext)))>;
7583 def : Pat<(vextractf128_extract:$ext VR256:$src1, (i32 imm)),
7584           (v16i8 (VEXTRACTI128rr
7585                     (v32i8 VR256:$src1),
7586                     (EXTRACT_get_vextractf128_imm VR128:$ext)))>;
7587 }
7588
7589 // AVX1 patterns
7590 let Predicates = [HasAVX] in {
7591 def : Pat<(vextractf128_extract:$ext VR256:$src1, (i32 imm)),
7592           (v4f32 (VEXTRACTF128rr
7593                     (v8f32 VR256:$src1),
7594                     (EXTRACT_get_vextractf128_imm VR128:$ext)))>;
7595 def : Pat<(vextractf128_extract:$ext VR256:$src1, (i32 imm)),
7596           (v2f64 (VEXTRACTF128rr
7597                     (v4f64 VR256:$src1),
7598                     (EXTRACT_get_vextractf128_imm VR128:$ext)))>;
7599 def : Pat<(vextractf128_extract:$ext VR256:$src1, (i32 imm)),
7600           (v2i64 (VEXTRACTF128rr
7601                     (v4i64 VR256:$src1),
7602                     (EXTRACT_get_vextractf128_imm VR128:$ext)))>;
7603 def : Pat<(vextractf128_extract:$ext VR256:$src1, (i32 imm)),
7604           (v4i32 (VEXTRACTF128rr
7605                     (v8i32 VR256:$src1),
7606                     (EXTRACT_get_vextractf128_imm VR128:$ext)))>;
7607 def : Pat<(vextractf128_extract:$ext VR256:$src1, (i32 imm)),
7608           (v8i16 (VEXTRACTF128rr
7609                     (v16i16 VR256:$src1),
7610                     (EXTRACT_get_vextractf128_imm VR128:$ext)))>;
7611 def : Pat<(vextractf128_extract:$ext VR256:$src1, (i32 imm)),
7612           (v16i8 (VEXTRACTF128rr
7613                     (v32i8 VR256:$src1),
7614                     (EXTRACT_get_vextractf128_imm VR128:$ext)))>;
7615 }
7616
7617 //===----------------------------------------------------------------------===//
7618 // VPMASKMOV - Conditional SIMD Integer Packed Loads and Stores
7619 //
7620 multiclass avx2_pmovmask<string OpcodeStr,
7621                          Intrinsic IntLd128, Intrinsic IntLd256,
7622                          Intrinsic IntSt128, Intrinsic IntSt256> {
7623   def rm  : AVX28I<0x8c, MRMSrcMem, (outs VR128:$dst),
7624              (ins VR128:$src1, i128mem:$src2),
7625              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7626              [(set VR128:$dst, (IntLd128 addr:$src2, VR128:$src1))]>, VEX_4V;
7627   def Yrm : AVX28I<0x8c, MRMSrcMem, (outs VR256:$dst),
7628              (ins VR256:$src1, i256mem:$src2),
7629              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7630              [(set VR256:$dst, (IntLd256 addr:$src2, VR256:$src1))]>, VEX_4V;
7631   def mr  : AVX28I<0x8e, MRMDestMem, (outs),
7632              (ins i128mem:$dst, VR128:$src1, VR128:$src2),
7633              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7634              [(IntSt128 addr:$dst, VR128:$src1, VR128:$src2)]>, VEX_4V;
7635   def Ymr : AVX28I<0x8e, MRMDestMem, (outs),
7636              (ins i256mem:$dst, VR256:$src1, VR256:$src2),
7637              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7638              [(IntSt256 addr:$dst, VR256:$src1, VR256:$src2)]>, VEX_4V;
7639 }
7640
7641 defm VPMASKMOVD : avx2_pmovmask<"vpmaskmovd",
7642                                 int_x86_avx2_maskload_d,
7643                                 int_x86_avx2_maskload_d_256,
7644                                 int_x86_avx2_maskstore_d,
7645                                 int_x86_avx2_maskstore_d_256>;
7646 defm VPMASKMOVQ : avx2_pmovmask<"vpmaskmovq",
7647                                 int_x86_avx2_maskload_q,
7648                                 int_x86_avx2_maskload_q_256,
7649                                 int_x86_avx2_maskstore_q,
7650                                 int_x86_avx2_maskstore_q_256>, VEX_W;
7651
7652
7653 //===----------------------------------------------------------------------===//
7654 // Variable Bit Shifts
7655 //
7656 multiclass avx2_var_shift<bits<8> opc, string OpcodeStr, SDNode OpNode,
7657                           ValueType vt128, ValueType vt256> {
7658   def rr  : AVX28I<opc, MRMSrcReg, (outs VR128:$dst),
7659              (ins VR128:$src1, VR128:$src2),
7660              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7661              [(set VR128:$dst,
7662                (vt128 (OpNode VR128:$src1, (vt128 VR128:$src2))))]>,
7663              VEX_4V;
7664   def rm  : AVX28I<opc, MRMSrcMem, (outs VR128:$dst),
7665              (ins VR128:$src1, i128mem:$src2),
7666              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7667              [(set VR128:$dst,
7668                (vt128 (OpNode VR128:$src1,
7669                        (vt128 (bitconvert (memopv2i64 addr:$src2))))))]>,
7670              VEX_4V;
7671   def Yrr : AVX28I<opc, MRMSrcReg, (outs VR256:$dst),
7672              (ins VR256:$src1, VR256:$src2),
7673              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7674              [(set VR256:$dst,
7675                (vt256 (OpNode VR256:$src1, (vt256 VR256:$src2))))]>,
7676              VEX_4V;
7677   def Yrm : AVX28I<opc, MRMSrcMem, (outs VR256:$dst),
7678              (ins VR256:$src1, i256mem:$src2),
7679              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7680              [(set VR256:$dst,
7681                (vt256 (OpNode VR256:$src1,
7682                        (vt256 (bitconvert (memopv4i64 addr:$src2))))))]>,
7683              VEX_4V;
7684 }
7685
7686 defm VPSLLVD : avx2_var_shift<0x47, "vpsllvd", shl, v4i32, v8i32>;
7687 defm VPSLLVQ : avx2_var_shift<0x47, "vpsllvq", shl, v2i64, v4i64>, VEX_W;
7688 defm VPSRLVD : avx2_var_shift<0x45, "vpsrlvd", srl, v4i32, v8i32>;
7689 defm VPSRLVQ : avx2_var_shift<0x45, "vpsrlvq", srl, v2i64, v4i64>, VEX_W;
7690 defm VPSRAVD : avx2_var_shift<0x46, "vpsravd", sra, v4i32, v8i32>;