Make X86 instruction selection use 256-bit VPXOR for build_vector of all ones if...
[oota-llvm.git] / lib / Target / X86 / X86InstrSSE.td
1 //====- X86InstrSSE.td - Describe the X86 Instruction Set --*- tablegen -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file describes the X86 SSE instruction set, defining the instructions,
11 // and properties of the instructions which are needed for code generation,
12 // machine code emission, and analysis.
13 //
14 //===----------------------------------------------------------------------===//
15
16
17 //===----------------------------------------------------------------------===//
18 // SSE 1 & 2 Instructions Classes
19 //===----------------------------------------------------------------------===//
20
21 /// sse12_fp_scalar - SSE 1 & 2 scalar instructions class
22 multiclass sse12_fp_scalar<bits<8> opc, string OpcodeStr, SDNode OpNode,
23                            RegisterClass RC, X86MemOperand x86memop,
24                            bit Is2Addr = 1> {
25   let isCommutable = 1 in {
26     def rr : SI<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
27        !if(Is2Addr,
28            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
29            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
30        [(set RC:$dst, (OpNode RC:$src1, RC:$src2))]>;
31   }
32   def rm : SI<opc, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
33        !if(Is2Addr,
34            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
35            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
36        [(set RC:$dst, (OpNode RC:$src1, (load addr:$src2)))]>;
37 }
38
39 /// sse12_fp_scalar_int - SSE 1 & 2 scalar instructions intrinsics class
40 multiclass sse12_fp_scalar_int<bits<8> opc, string OpcodeStr, RegisterClass RC,
41                              string asm, string SSEVer, string FPSizeStr,
42                              Operand memopr, ComplexPattern mem_cpat,
43                              bit Is2Addr = 1> {
44   def rr_Int : SI<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
45        !if(Is2Addr,
46            !strconcat(asm, "\t{$src2, $dst|$dst, $src2}"),
47            !strconcat(asm, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
48        [(set RC:$dst, (!cast<Intrinsic>(
49                  !strconcat("int_x86_sse", SSEVer, "_", OpcodeStr, FPSizeStr))
50              RC:$src1, RC:$src2))]>;
51   def rm_Int : SI<opc, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, memopr:$src2),
52        !if(Is2Addr,
53            !strconcat(asm, "\t{$src2, $dst|$dst, $src2}"),
54            !strconcat(asm, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
55        [(set RC:$dst, (!cast<Intrinsic>(!strconcat("int_x86_sse",
56                                           SSEVer, "_", OpcodeStr, FPSizeStr))
57              RC:$src1, mem_cpat:$src2))]>;
58 }
59
60 /// sse12_fp_packed - SSE 1 & 2 packed instructions class
61 multiclass sse12_fp_packed<bits<8> opc, string OpcodeStr, SDNode OpNode,
62                            RegisterClass RC, ValueType vt,
63                            X86MemOperand x86memop, PatFrag mem_frag,
64                            Domain d, bit Is2Addr = 1> {
65   let isCommutable = 1 in
66     def rr : PI<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
67        !if(Is2Addr,
68            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
69            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
70        [(set RC:$dst, (vt (OpNode RC:$src1, RC:$src2)))], d>;
71   let mayLoad = 1 in
72     def rm : PI<opc, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
73        !if(Is2Addr,
74            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
75            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
76        [(set RC:$dst, (OpNode RC:$src1, (mem_frag addr:$src2)))], d>;
77 }
78
79 /// sse12_fp_packed_logical_rm - SSE 1 & 2 packed instructions class
80 multiclass sse12_fp_packed_logical_rm<bits<8> opc, RegisterClass RC, Domain d,
81                                       string OpcodeStr, X86MemOperand x86memop,
82                                       list<dag> pat_rr, list<dag> pat_rm,
83                                       bit Is2Addr = 1,
84                                       bit rr_hasSideEffects = 0> {
85   let isCommutable = 1, neverHasSideEffects = rr_hasSideEffects in
86     def rr : PI<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
87        !if(Is2Addr,
88            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
89            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
90        pat_rr, d>;
91   def rm : PI<opc, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
92        !if(Is2Addr,
93            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
94            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
95        pat_rm, d>;
96 }
97
98 /// sse12_fp_packed_int - SSE 1 & 2 packed instructions intrinsics class
99 multiclass sse12_fp_packed_int<bits<8> opc, string OpcodeStr, RegisterClass RC,
100                            string asm, string SSEVer, string FPSizeStr,
101                            X86MemOperand x86memop, PatFrag mem_frag,
102                            Domain d, bit Is2Addr = 1> {
103   def rr_Int : PI<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
104        !if(Is2Addr,
105            !strconcat(asm, "\t{$src2, $dst|$dst, $src2}"),
106            !strconcat(asm, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
107            [(set RC:$dst, (!cast<Intrinsic>(
108                      !strconcat("int_x86_", SSEVer, "_", OpcodeStr, FPSizeStr))
109                  RC:$src1, RC:$src2))], d>;
110   def rm_Int : PI<opc, MRMSrcMem, (outs RC:$dst), (ins RC:$src1,x86memop:$src2),
111        !if(Is2Addr,
112            !strconcat(asm, "\t{$src2, $dst|$dst, $src2}"),
113            !strconcat(asm, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
114        [(set RC:$dst, (!cast<Intrinsic>(
115                      !strconcat("int_x86_", SSEVer, "_", OpcodeStr, FPSizeStr))
116              RC:$src1, (mem_frag addr:$src2)))], d>;
117 }
118
119 //===----------------------------------------------------------------------===//
120 //  Non-instruction patterns
121 //===----------------------------------------------------------------------===//
122
123 // A vector extract of the first f32/f64 position is a subregister copy
124 def : Pat<(f32 (vector_extract (v4f32 VR128:$src), (iPTR 0))),
125           (f32 (EXTRACT_SUBREG (v4f32 VR128:$src), sub_ss))>;
126 def : Pat<(f64 (vector_extract (v2f64 VR128:$src), (iPTR 0))),
127           (f64 (EXTRACT_SUBREG (v2f64 VR128:$src), sub_sd))>;
128
129 // A 128-bit subvector extract from the first 256-bit vector position
130 // is a subregister copy that needs no instruction.
131 def : Pat<(v4i32 (extract_subvector (v8i32 VR256:$src), (i32 0))),
132           (v4i32 (EXTRACT_SUBREG (v8i32 VR256:$src), sub_xmm))>;
133 def : Pat<(v4f32 (extract_subvector (v8f32 VR256:$src), (i32 0))),
134           (v4f32 (EXTRACT_SUBREG (v8f32 VR256:$src), sub_xmm))>;
135
136 def : Pat<(v2i64 (extract_subvector (v4i64 VR256:$src), (i32 0))),
137           (v2i64 (EXTRACT_SUBREG (v4i64 VR256:$src), sub_xmm))>;
138 def : Pat<(v2f64 (extract_subvector (v4f64 VR256:$src), (i32 0))),
139           (v2f64 (EXTRACT_SUBREG (v4f64 VR256:$src), sub_xmm))>;
140
141 def : Pat<(v8i16 (extract_subvector (v16i16 VR256:$src), (i32 0))),
142           (v8i16 (EXTRACT_SUBREG (v16i16 VR256:$src), sub_xmm))>;
143 def : Pat<(v16i8 (extract_subvector (v32i8 VR256:$src), (i32 0))),
144           (v16i8 (EXTRACT_SUBREG (v32i8 VR256:$src), sub_xmm))>;
145
146 // A 128-bit subvector insert to the first 256-bit vector position
147 // is a subregister copy that needs no instruction.
148 def : Pat<(insert_subvector undef, (v2i64 VR128:$src), (i32 0)),
149           (INSERT_SUBREG (v4i64 (IMPLICIT_DEF)), VR128:$src, sub_xmm)>;
150 def : Pat<(insert_subvector undef, (v2f64 VR128:$src), (i32 0)),
151           (INSERT_SUBREG (v4f64 (IMPLICIT_DEF)), VR128:$src, sub_xmm)>;
152 def : Pat<(insert_subvector undef, (v4i32 VR128:$src), (i32 0)),
153           (INSERT_SUBREG (v8i32 (IMPLICIT_DEF)), VR128:$src, sub_xmm)>;
154 def : Pat<(insert_subvector undef, (v4f32 VR128:$src), (i32 0)),
155           (INSERT_SUBREG (v8f32 (IMPLICIT_DEF)), VR128:$src, sub_xmm)>;
156 def : Pat<(insert_subvector undef, (v8i16 VR128:$src), (i32 0)),
157           (INSERT_SUBREG (v16i16 (IMPLICIT_DEF)), VR128:$src, sub_xmm)>;
158 def : Pat<(insert_subvector undef, (v16i8 VR128:$src), (i32 0)),
159           (INSERT_SUBREG (v32i8 (IMPLICIT_DEF)), VR128:$src, sub_xmm)>;
160
161 // Implicitly promote a 32-bit scalar to a vector.
162 def : Pat<(v4f32 (scalar_to_vector FR32:$src)),
163           (INSERT_SUBREG (v4f32 (IMPLICIT_DEF)), FR32:$src, sub_ss)>;
164 def : Pat<(v8f32 (scalar_to_vector FR32:$src)),
165           (INSERT_SUBREG (v8f32 (IMPLICIT_DEF)), FR32:$src, sub_ss)>;
166 // Implicitly promote a 64-bit scalar to a vector.
167 def : Pat<(v2f64 (scalar_to_vector FR64:$src)),
168           (INSERT_SUBREG (v2f64 (IMPLICIT_DEF)), FR64:$src, sub_sd)>;
169 def : Pat<(v4f64 (scalar_to_vector FR64:$src)),
170           (INSERT_SUBREG (v4f64 (IMPLICIT_DEF)), FR64:$src, sub_sd)>;
171
172 // Bitcasts between 128-bit vector types. Return the original type since
173 // no instruction is needed for the conversion
174 let Predicates = [HasSSE2] in {
175   def : Pat<(v2i64 (bitconvert (v4i32 VR128:$src))), (v2i64 VR128:$src)>;
176   def : Pat<(v2i64 (bitconvert (v8i16 VR128:$src))), (v2i64 VR128:$src)>;
177   def : Pat<(v2i64 (bitconvert (v16i8 VR128:$src))), (v2i64 VR128:$src)>;
178   def : Pat<(v2i64 (bitconvert (v2f64 VR128:$src))), (v2i64 VR128:$src)>;
179   def : Pat<(v2i64 (bitconvert (v4f32 VR128:$src))), (v2i64 VR128:$src)>;
180   def : Pat<(v4i32 (bitconvert (v2i64 VR128:$src))), (v4i32 VR128:$src)>;
181   def : Pat<(v4i32 (bitconvert (v8i16 VR128:$src))), (v4i32 VR128:$src)>;
182   def : Pat<(v4i32 (bitconvert (v16i8 VR128:$src))), (v4i32 VR128:$src)>;
183   def : Pat<(v4i32 (bitconvert (v2f64 VR128:$src))), (v4i32 VR128:$src)>;
184   def : Pat<(v4i32 (bitconvert (v4f32 VR128:$src))), (v4i32 VR128:$src)>;
185   def : Pat<(v8i16 (bitconvert (v2i64 VR128:$src))), (v8i16 VR128:$src)>;
186   def : Pat<(v8i16 (bitconvert (v4i32 VR128:$src))), (v8i16 VR128:$src)>;
187   def : Pat<(v8i16 (bitconvert (v16i8 VR128:$src))), (v8i16 VR128:$src)>;
188   def : Pat<(v8i16 (bitconvert (v2f64 VR128:$src))), (v8i16 VR128:$src)>;
189   def : Pat<(v8i16 (bitconvert (v4f32 VR128:$src))), (v8i16 VR128:$src)>;
190   def : Pat<(v16i8 (bitconvert (v2i64 VR128:$src))), (v16i8 VR128:$src)>;
191   def : Pat<(v16i8 (bitconvert (v4i32 VR128:$src))), (v16i8 VR128:$src)>;
192   def : Pat<(v16i8 (bitconvert (v8i16 VR128:$src))), (v16i8 VR128:$src)>;
193   def : Pat<(v16i8 (bitconvert (v2f64 VR128:$src))), (v16i8 VR128:$src)>;
194   def : Pat<(v16i8 (bitconvert (v4f32 VR128:$src))), (v16i8 VR128:$src)>;
195   def : Pat<(v4f32 (bitconvert (v2i64 VR128:$src))), (v4f32 VR128:$src)>;
196   def : Pat<(v4f32 (bitconvert (v4i32 VR128:$src))), (v4f32 VR128:$src)>;
197   def : Pat<(v4f32 (bitconvert (v8i16 VR128:$src))), (v4f32 VR128:$src)>;
198   def : Pat<(v4f32 (bitconvert (v16i8 VR128:$src))), (v4f32 VR128:$src)>;
199   def : Pat<(v4f32 (bitconvert (v2f64 VR128:$src))), (v4f32 VR128:$src)>;
200   def : Pat<(v2f64 (bitconvert (v2i64 VR128:$src))), (v2f64 VR128:$src)>;
201   def : Pat<(v2f64 (bitconvert (v4i32 VR128:$src))), (v2f64 VR128:$src)>;
202   def : Pat<(v2f64 (bitconvert (v8i16 VR128:$src))), (v2f64 VR128:$src)>;
203   def : Pat<(v2f64 (bitconvert (v16i8 VR128:$src))), (v2f64 VR128:$src)>;
204   def : Pat<(v2f64 (bitconvert (v4f32 VR128:$src))), (v2f64 VR128:$src)>;
205 }
206
207 // Bitcasts between 256-bit vector types. Return the original type since
208 // no instruction is needed for the conversion
209 let Predicates = [HasAVX] in {
210   def : Pat<(v4f64  (bitconvert (v8f32 VR256:$src))),  (v4f64 VR256:$src)>;
211   def : Pat<(v4f64  (bitconvert (v8i32 VR256:$src))),  (v4f64 VR256:$src)>;
212   def : Pat<(v4f64  (bitconvert (v4i64 VR256:$src))),  (v4f64 VR256:$src)>;
213   def : Pat<(v4f64  (bitconvert (v16i16 VR256:$src))), (v4f64 VR256:$src)>;
214   def : Pat<(v4f64  (bitconvert (v32i8 VR256:$src))),  (v4f64 VR256:$src)>;
215   def : Pat<(v8f32  (bitconvert (v8i32 VR256:$src))),  (v8f32 VR256:$src)>;
216   def : Pat<(v8f32  (bitconvert (v4i64 VR256:$src))),  (v8f32 VR256:$src)>;
217   def : Pat<(v8f32  (bitconvert (v4f64 VR256:$src))),  (v8f32 VR256:$src)>;
218   def : Pat<(v8f32  (bitconvert (v32i8 VR256:$src))),  (v8f32 VR256:$src)>;
219   def : Pat<(v8f32  (bitconvert (v16i16 VR256:$src))), (v8f32 VR256:$src)>;
220   def : Pat<(v4i64  (bitconvert (v8f32 VR256:$src))),  (v4i64 VR256:$src)>;
221   def : Pat<(v4i64  (bitconvert (v8i32 VR256:$src))),  (v4i64 VR256:$src)>;
222   def : Pat<(v4i64  (bitconvert (v4f64 VR256:$src))),  (v4i64 VR256:$src)>;
223   def : Pat<(v4i64  (bitconvert (v32i8 VR256:$src))),  (v4i64 VR256:$src)>;
224   def : Pat<(v4i64  (bitconvert (v16i16 VR256:$src))), (v4i64 VR256:$src)>;
225   def : Pat<(v32i8  (bitconvert (v4f64 VR256:$src))),  (v32i8 VR256:$src)>;
226   def : Pat<(v32i8  (bitconvert (v4i64 VR256:$src))),  (v32i8 VR256:$src)>;
227   def : Pat<(v32i8  (bitconvert (v8f32 VR256:$src))),  (v32i8 VR256:$src)>;
228   def : Pat<(v32i8  (bitconvert (v8i32 VR256:$src))),  (v32i8 VR256:$src)>;
229   def : Pat<(v32i8  (bitconvert (v16i16 VR256:$src))), (v32i8 VR256:$src)>;
230   def : Pat<(v8i32  (bitconvert (v32i8 VR256:$src))),  (v8i32 VR256:$src)>;
231   def : Pat<(v8i32  (bitconvert (v16i16 VR256:$src))), (v8i32 VR256:$src)>;
232   def : Pat<(v8i32  (bitconvert (v8f32 VR256:$src))),  (v8i32 VR256:$src)>;
233   def : Pat<(v8i32  (bitconvert (v4i64 VR256:$src))),  (v8i32 VR256:$src)>;
234   def : Pat<(v8i32  (bitconvert (v4f64 VR256:$src))),  (v8i32 VR256:$src)>;
235   def : Pat<(v16i16 (bitconvert (v8f32 VR256:$src))),  (v16i16 VR256:$src)>;
236   def : Pat<(v16i16 (bitconvert (v8i32 VR256:$src))),  (v16i16 VR256:$src)>;
237   def : Pat<(v16i16 (bitconvert (v4i64 VR256:$src))),  (v16i16 VR256:$src)>;
238   def : Pat<(v16i16 (bitconvert (v4f64 VR256:$src))),  (v16i16 VR256:$src)>;
239   def : Pat<(v16i16 (bitconvert (v32i8 VR256:$src))),  (v16i16 VR256:$src)>;
240 }
241
242 // Alias instructions that map fld0 to pxor for sse.
243 // This is expanded by ExpandPostRAPseudos.
244 let isReMaterializable = 1, isAsCheapAsAMove = 1, canFoldAsLoad = 1,
245     isPseudo = 1 in {
246   def FsFLD0SS : I<0, Pseudo, (outs FR32:$dst), (ins), "",
247                    [(set FR32:$dst, fp32imm0)]>, Requires<[HasSSE1]>;
248   def FsFLD0SD : I<0, Pseudo, (outs FR64:$dst), (ins), "",
249                    [(set FR64:$dst, fpimm0)]>, Requires<[HasSSE2]>;
250 }
251
252 //===----------------------------------------------------------------------===//
253 // AVX & SSE - Zero/One Vectors
254 //===----------------------------------------------------------------------===//
255
256 // Alias instruction that maps zero vector to pxor / xorp* for sse.
257 // This is expanded by ExpandPostRAPseudos to an xorps / vxorps, and then
258 // swizzled by ExecutionDepsFix to pxor.
259 // We set canFoldAsLoad because this can be converted to a constant-pool
260 // load of an all-zeros value if folding it would be beneficial.
261 let isReMaterializable = 1, isAsCheapAsAMove = 1, canFoldAsLoad = 1,
262     isPseudo = 1, neverHasSideEffects = 1 in {
263 def V_SET0 : I<0, Pseudo, (outs VR128:$dst), (ins), "", []>;
264 }
265
266 def : Pat<(v4f32 immAllZerosV), (V_SET0)>;
267 def : Pat<(v2f64 immAllZerosV), (V_SET0)>;
268 def : Pat<(v4i32 immAllZerosV), (V_SET0)>;
269 def : Pat<(v2i64 immAllZerosV), (V_SET0)>;
270 def : Pat<(v8i16 immAllZerosV), (V_SET0)>;
271 def : Pat<(v16i8 immAllZerosV), (V_SET0)>;
272
273
274 // The same as done above but for AVX.  The 256-bit ISA does not support PI,
275 // and doesn't need it because on sandy bridge the register is set to zero
276 // at the rename stage without using any execution unit, so SET0PSY
277 // and SET0PDY can be used for vector int instructions without penalty
278 // FIXME: Change encoding to pseudo! This is blocked right now by the x86
279 // JIT implementatioan, it does not expand the instructions below like
280 // X86MCInstLower does.
281 let isReMaterializable = 1, isAsCheapAsAMove = 1, canFoldAsLoad = 1,
282     isCodeGenOnly = 1 in {
283 let Predicates = [HasAVX] in {
284 def AVX_SET0PSY : PSI<0x57, MRMInitReg, (outs VR256:$dst), (ins), "",
285                    [(set VR256:$dst, (v8f32 immAllZerosV))]>, VEX_4V;
286 def AVX_SET0PDY : PDI<0x57, MRMInitReg, (outs VR256:$dst), (ins), "",
287                    [(set VR256:$dst, (v4f64 immAllZerosV))]>, VEX_4V;
288 }
289 let Predicates = [HasAVX2], neverHasSideEffects = 1 in
290 def AVX2_SET0   : PDI<0xef, MRMInitReg, (outs VR256:$dst), (ins), "",
291                    []>, VEX_4V;
292 }
293
294 let Predicates = [HasAVX2], AddedComplexity = 5 in {
295   def : Pat<(v4i64 immAllZerosV), (AVX2_SET0)>;
296   def : Pat<(v8i32 immAllZerosV), (AVX2_SET0)>;
297   def : Pat<(v16i16 immAllZerosV), (AVX2_SET0)>;
298   def : Pat<(v32i8 immAllZerosV), (AVX2_SET0)>;
299 }
300
301 // AVX has no support for 256-bit integer instructions, but since the 128-bit
302 // VPXOR instruction writes zero to its upper part, it's safe build zeros.
303 def : Pat<(v32i8 immAllZerosV), (SUBREG_TO_REG (i8 0), (V_SET0), sub_xmm)>;
304 def : Pat<(bc_v32i8 (v8f32 immAllZerosV)),
305           (SUBREG_TO_REG (i8 0), (V_SET0), sub_xmm)>;
306
307 def : Pat<(v16i16 immAllZerosV), (SUBREG_TO_REG (i16 0), (V_SET0), sub_xmm)>;
308 def : Pat<(bc_v16i16 (v8f32 immAllZerosV)),
309           (SUBREG_TO_REG (i16 0), (V_SET0), sub_xmm)>;
310
311 def : Pat<(v8i32 immAllZerosV), (SUBREG_TO_REG (i32 0), (V_SET0), sub_xmm)>;
312 def : Pat<(bc_v8i32 (v8f32 immAllZerosV)),
313           (SUBREG_TO_REG (i32 0), (V_SET0), sub_xmm)>;
314
315 def : Pat<(v4i64 immAllZerosV), (SUBREG_TO_REG (i64 0), (V_SET0), sub_xmm)>;
316 def : Pat<(bc_v4i64 (v8f32 immAllZerosV)),
317           (SUBREG_TO_REG (i64 0), (V_SET0), sub_xmm)>;
318
319 // We set canFoldAsLoad because this can be converted to a constant-pool
320 // load of an all-ones value if folding it would be beneficial.
321 // FIXME: Change encoding to pseudo! This is blocked right now by the x86
322 // JIT implementation, it does not expand the instructions below like
323 // X86MCInstLower does.
324 let isReMaterializable = 1, isAsCheapAsAMove = 1, canFoldAsLoad = 1,
325     isCodeGenOnly = 1, ExeDomain = SSEPackedInt in {
326   let Predicates = [HasAVX] in
327   def AVX_SETALLONES : PDI<0x76, MRMInitReg, (outs VR128:$dst), (ins), "",
328                          [(set VR128:$dst, (v4i32 immAllOnesV))]>, VEX_4V;
329   def V_SETALLONES : PDI<0x76, MRMInitReg, (outs VR128:$dst), (ins), "",
330                          [(set VR128:$dst, (v4i32 immAllOnesV))]>;
331   let Predicates = [HasAVX2] in
332   def AVX2_SETALLONES : PDI<0x76, MRMInitReg, (outs VR256:$dst), (ins), "",
333                           [(set VR256:$dst, (v8i32 immAllOnesV))]>, VEX_4V;
334 }
335
336
337 //===----------------------------------------------------------------------===//
338 // SSE 1 & 2 - Move FP Scalar Instructions
339 //
340 // Move Instructions. Register-to-register movss/movsd is not used for FR32/64
341 // register copies because it's a partial register update; FsMOVAPSrr/FsMOVAPDrr
342 // is used instead. Register-to-register movss/movsd is not modeled as an
343 // INSERT_SUBREG because INSERT_SUBREG requires that the insert be implementable
344 // in terms of a copy, and just mentioned, we don't use movss/movsd for copies.
345 //===----------------------------------------------------------------------===//
346
347 class sse12_move_rr<RegisterClass RC, ValueType vt, string asm> :
348       SI<0x10, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src1, RC:$src2), asm,
349       [(set (vt VR128:$dst), (movl VR128:$src1, (scalar_to_vector RC:$src2)))]>;
350
351 // Loading from memory automatically zeroing upper bits.
352 class sse12_move_rm<RegisterClass RC, X86MemOperand x86memop,
353                     PatFrag mem_pat, string OpcodeStr> :
354       SI<0x10, MRMSrcMem, (outs RC:$dst), (ins x86memop:$src),
355          !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
356                         [(set RC:$dst, (mem_pat addr:$src))]>;
357
358 // AVX
359 def VMOVSSrr : sse12_move_rr<FR32, v4f32,
360                 "movss\t{$src2, $src1, $dst|$dst, $src1, $src2}">, XS, VEX_4V,
361                 VEX_LIG;
362 def VMOVSDrr : sse12_move_rr<FR64, v2f64,
363                 "movsd\t{$src2, $src1, $dst|$dst, $src1, $src2}">, XD, VEX_4V,
364                 VEX_LIG;
365
366 // For the disassembler
367 let isCodeGenOnly = 1 in {
368   def VMOVSSrr_REV : SI<0x11, MRMDestReg, (outs VR128:$dst),
369                         (ins VR128:$src1, FR32:$src2),
370                         "movss\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>,
371                         XS, VEX_4V, VEX_LIG;
372   def VMOVSDrr_REV : SI<0x11, MRMDestReg, (outs VR128:$dst),
373                         (ins VR128:$src1, FR64:$src2),
374                         "movsd\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>,
375                         XD, VEX_4V, VEX_LIG;
376 }
377
378 let canFoldAsLoad = 1, isReMaterializable = 1 in {
379   def VMOVSSrm : sse12_move_rm<FR32, f32mem, loadf32, "movss">, XS, VEX,
380                  VEX_LIG;
381   let AddedComplexity = 20 in
382     def VMOVSDrm : sse12_move_rm<FR64, f64mem, loadf64, "movsd">, XD, VEX,
383                    VEX_LIG;
384 }
385
386 def VMOVSSmr : SI<0x11, MRMDestMem, (outs), (ins f32mem:$dst, FR32:$src),
387                   "movss\t{$src, $dst|$dst, $src}",
388                   [(store FR32:$src, addr:$dst)]>, XS, VEX, VEX_LIG;
389 def VMOVSDmr : SI<0x11, MRMDestMem, (outs), (ins f64mem:$dst, FR64:$src),
390                   "movsd\t{$src, $dst|$dst, $src}",
391                   [(store FR64:$src, addr:$dst)]>, XD, VEX, VEX_LIG;
392
393 // SSE1 & 2
394 let Constraints = "$src1 = $dst" in {
395   def MOVSSrr : sse12_move_rr<FR32, v4f32,
396                           "movss\t{$src2, $dst|$dst, $src2}">, XS;
397   def MOVSDrr : sse12_move_rr<FR64, v2f64,
398                           "movsd\t{$src2, $dst|$dst, $src2}">, XD;
399
400   // For the disassembler
401   let isCodeGenOnly = 1 in {
402     def MOVSSrr_REV : SI<0x11, MRMDestReg, (outs VR128:$dst),
403                          (ins VR128:$src1, FR32:$src2),
404                          "movss\t{$src2, $dst|$dst, $src2}", []>, XS;
405     def MOVSDrr_REV : SI<0x11, MRMDestReg, (outs VR128:$dst),
406                          (ins VR128:$src1, FR64:$src2),
407                          "movsd\t{$src2, $dst|$dst, $src2}", []>, XD;
408   }
409 }
410
411 let canFoldAsLoad = 1, isReMaterializable = 1 in {
412   def MOVSSrm : sse12_move_rm<FR32, f32mem, loadf32, "movss">, XS;
413
414   let AddedComplexity = 20 in
415     def MOVSDrm : sse12_move_rm<FR64, f64mem, loadf64, "movsd">, XD;
416 }
417
418 def MOVSSmr : SSI<0x11, MRMDestMem, (outs), (ins f32mem:$dst, FR32:$src),
419                   "movss\t{$src, $dst|$dst, $src}",
420                   [(store FR32:$src, addr:$dst)]>;
421 def MOVSDmr : SDI<0x11, MRMDestMem, (outs), (ins f64mem:$dst, FR64:$src),
422                   "movsd\t{$src, $dst|$dst, $src}",
423                   [(store FR64:$src, addr:$dst)]>;
424
425 // Patterns
426 let Predicates = [HasAVX] in {
427   let AddedComplexity = 15 in {
428   // Extract the low 32-bit value from one vector and insert it into another.
429   def : Pat<(v4f32 (movl VR128:$src1, VR128:$src2)),
430             (VMOVSSrr (v4f32 VR128:$src1),
431                       (EXTRACT_SUBREG (v4f32 VR128:$src2), sub_ss))>;
432   def : Pat<(v4i32 (movl VR128:$src1, VR128:$src2)),
433             (VMOVSSrr (v4i32 VR128:$src1),
434                       (EXTRACT_SUBREG (v4i32 VR128:$src2), sub_ss))>;
435
436   // Extract the low 64-bit value from one vector and insert it into another.
437   def : Pat<(v2f64 (movl VR128:$src1, VR128:$src2)),
438             (VMOVSDrr (v2f64 VR128:$src1),
439                       (EXTRACT_SUBREG (v2f64 VR128:$src2), sub_sd))>;
440   def : Pat<(v2i64 (movl VR128:$src1, VR128:$src2)),
441             (VMOVSDrr (v2i64 VR128:$src1),
442                       (EXTRACT_SUBREG (v2i64 VR128:$src2), sub_sd))>;
443
444   // vector_shuffle v1, v2 <4, 5, 2, 3> using movsd
445   def : Pat<(v4f32 (movlp VR128:$src1, VR128:$src2)),
446             (VMOVSDrr VR128:$src1, (EXTRACT_SUBREG VR128:$src2, sub_sd))>;
447   def : Pat<(v4i32 (movlp VR128:$src1, VR128:$src2)),
448             (VMOVSDrr VR128:$src1, (EXTRACT_SUBREG VR128:$src2, sub_sd))>;
449
450   // Move scalar to XMM zero-extended, zeroing a VR128 then do a
451   // MOVS{S,D} to the lower bits.
452   def : Pat<(v4f32 (X86vzmovl (v4f32 (scalar_to_vector FR32:$src)))),
453             (VMOVSSrr (v4f32 (V_SET0)), FR32:$src)>;
454   def : Pat<(v4f32 (X86vzmovl (v4f32 VR128:$src))),
455             (VMOVSSrr (v4f32 (V_SET0)),
456                       (f32 (EXTRACT_SUBREG (v4f32 VR128:$src), sub_ss)))>;
457   def : Pat<(v4i32 (X86vzmovl (v4i32 VR128:$src))),
458             (VMOVSSrr (v4i32 (V_SET0)),
459                       (EXTRACT_SUBREG (v4i32 VR128:$src), sub_ss))>;
460   def : Pat<(v2f64 (X86vzmovl (v2f64 (scalar_to_vector FR64:$src)))),
461             (VMOVSDrr (v2f64 (V_SET0)), FR64:$src)>;
462
463   // Move low f32 and clear high bits.
464   def : Pat<(v8f32 (X86vzmovl (v8f32 VR256:$src))),
465             (SUBREG_TO_REG (i32 0),
466               (VMOVSSrr (v4f32 (V_SET0)),
467                         (EXTRACT_SUBREG (v8f32 VR256:$src), sub_ss)), sub_xmm)>;
468   def : Pat<(v8i32 (X86vzmovl (v8i32 VR256:$src))),
469             (SUBREG_TO_REG (i32 0),
470               (VMOVSSrr (v4i32 (V_SET0)),
471                         (EXTRACT_SUBREG (v8i32 VR256:$src), sub_ss)), sub_xmm)>;
472   }
473
474   let AddedComplexity = 20 in {
475   // MOVSSrm zeros the high parts of the register; represent this
476   // with SUBREG_TO_REG. The AVX versions also write: DST[255:128] <- 0
477   def : Pat<(v4f32 (X86vzmovl (v4f32 (scalar_to_vector (loadf32 addr:$src))))),
478             (SUBREG_TO_REG (i32 0), (VMOVSSrm addr:$src), sub_ss)>;
479   def : Pat<(v4f32 (scalar_to_vector (loadf32 addr:$src))),
480             (SUBREG_TO_REG (i32 0), (VMOVSSrm addr:$src), sub_ss)>;
481   def : Pat<(v4f32 (X86vzmovl (loadv4f32 addr:$src))),
482             (SUBREG_TO_REG (i32 0), (VMOVSSrm addr:$src), sub_ss)>;
483
484   // MOVSDrm zeros the high parts of the register; represent this
485   // with SUBREG_TO_REG. The AVX versions also write: DST[255:128] <- 0
486   def : Pat<(v2f64 (X86vzmovl (v2f64 (scalar_to_vector (loadf64 addr:$src))))),
487             (SUBREG_TO_REG (i64 0), (VMOVSDrm addr:$src), sub_sd)>;
488   def : Pat<(v2f64 (scalar_to_vector (loadf64 addr:$src))),
489             (SUBREG_TO_REG (i64 0), (VMOVSDrm addr:$src), sub_sd)>;
490   def : Pat<(v2f64 (X86vzmovl (loadv2f64 addr:$src))),
491             (SUBREG_TO_REG (i64 0), (VMOVSDrm addr:$src), sub_sd)>;
492   def : Pat<(v2f64 (X86vzmovl (bc_v2f64 (loadv4f32 addr:$src)))),
493             (SUBREG_TO_REG (i64 0), (VMOVSDrm addr:$src), sub_sd)>;
494   def : Pat<(v2f64 (X86vzload addr:$src)),
495             (SUBREG_TO_REG (i64 0), (VMOVSDrm addr:$src), sub_sd)>;
496
497   // Represent the same patterns above but in the form they appear for
498   // 256-bit types
499   def : Pat<(v8i32 (X86vzmovl (insert_subvector undef,
500                    (v4i32 (scalar_to_vector (loadi32 addr:$src))), (i32 0)))),
501             (SUBREG_TO_REG (i32 0), (VMOVSSrm addr:$src), sub_ss)>;
502   def : Pat<(v8f32 (X86vzmovl (insert_subvector undef,
503                    (v4f32 (scalar_to_vector (loadf32 addr:$src))), (i32 0)))),
504             (SUBREG_TO_REG (i32 0), (VMOVSSrm addr:$src), sub_ss)>;
505   def : Pat<(v4f64 (X86vzmovl (insert_subvector undef,
506                    (v2f64 (scalar_to_vector (loadf64 addr:$src))), (i32 0)))),
507             (SUBREG_TO_REG (i32 0), (VMOVSDrm addr:$src), sub_sd)>;
508   }
509   def : Pat<(v8f32 (X86vzmovl (insert_subvector undef,
510                    (v4f32 (scalar_to_vector FR32:$src)), (i32 0)))),
511             (SUBREG_TO_REG (i32 0),
512                            (v4f32 (VMOVSSrr (v4f32 (V_SET0)), FR32:$src)),
513                            sub_xmm)>;
514   def : Pat<(v4f64 (X86vzmovl (insert_subvector undef,
515                    (v2f64 (scalar_to_vector FR64:$src)), (i32 0)))),
516             (SUBREG_TO_REG (i64 0),
517                            (v2f64 (VMOVSDrr (v2f64 (V_SET0)), FR64:$src)),
518                            sub_xmm)>;
519   def : Pat<(v4i64 (X86vzmovl (insert_subvector undef,
520                    (v2i64 (scalar_to_vector (loadi64 addr:$src))), (i32 0)))),
521             (SUBREG_TO_REG (i64 0), (VMOVSDrm addr:$src), sub_sd)>;
522
523   // Move low f64 and clear high bits.
524   def : Pat<(v4f64 (X86vzmovl (v4f64 VR256:$src))),
525             (SUBREG_TO_REG (i32 0),
526               (VMOVSDrr (v2f64 (V_SET0)),
527                         (EXTRACT_SUBREG (v4f64 VR256:$src), sub_sd)), sub_xmm)>;
528
529   def : Pat<(v4i64 (X86vzmovl (v4i64 VR256:$src))),
530             (SUBREG_TO_REG (i32 0),
531               (VMOVSDrr (v2i64 (V_SET0)),
532                         (EXTRACT_SUBREG (v4i64 VR256:$src), sub_sd)), sub_xmm)>;
533
534 // Extract and store.
535   def : Pat<(store (f32 (vector_extract (v4f32 VR128:$src), (iPTR 0))),
536                    addr:$dst),
537             (VMOVSSmr addr:$dst,
538                      (EXTRACT_SUBREG (v4f32 VR128:$src), sub_ss))>;
539   def : Pat<(store (f64 (vector_extract (v2f64 VR128:$src), (iPTR 0))),
540                    addr:$dst),
541             (VMOVSDmr addr:$dst,
542                      (EXTRACT_SUBREG (v2f64 VR128:$src), sub_sd))>;
543
544   // Shuffle with VMOVSS
545   def : Pat<(v4f32 (X86Movss VR128:$src1, (scalar_to_vector FR32:$src2))),
546             (VMOVSSrr VR128:$src1, FR32:$src2)>;
547   def : Pat<(v4i32 (X86Movss VR128:$src1, VR128:$src2)),
548             (VMOVSSrr (v4i32 VR128:$src1),
549                       (EXTRACT_SUBREG (v4i32 VR128:$src2), sub_ss))>;
550   def : Pat<(v4f32 (X86Movss VR128:$src1, VR128:$src2)),
551             (VMOVSSrr (v4f32 VR128:$src1),
552                       (EXTRACT_SUBREG (v4f32 VR128:$src2), sub_ss))>;
553
554   // 256-bit variants
555   def : Pat<(v8i32 (X86Movsd VR256:$src1, VR256:$src2)),
556             (SUBREG_TO_REG (i32 0),
557                 (VMOVSSrr (EXTRACT_SUBREG (v8i32 VR256:$src1), sub_ss),
558                           (EXTRACT_SUBREG (v8i32 VR256:$src2), sub_ss)), sub_xmm)>;
559   def : Pat<(v8f32 (X86Movsd VR256:$src1, VR256:$src2)),
560             (SUBREG_TO_REG (i32 0),
561                 (VMOVSSrr (EXTRACT_SUBREG (v8f32 VR256:$src1), sub_ss),
562                           (EXTRACT_SUBREG (v8f32 VR256:$src2), sub_ss)), sub_xmm)>;
563
564   // Shuffle with VMOVSD
565   def : Pat<(v2f64 (X86Movsd VR128:$src1, (scalar_to_vector FR64:$src2))),
566             (VMOVSDrr VR128:$src1, FR64:$src2)>;
567   def : Pat<(v2i64 (X86Movsd VR128:$src1, VR128:$src2)),
568             (VMOVSDrr (v2i64 VR128:$src1),
569                      (EXTRACT_SUBREG (v2i64 VR128:$src2), sub_sd))>;
570   def : Pat<(v2f64 (X86Movsd VR128:$src1, VR128:$src2)),
571             (VMOVSDrr (v2f64 VR128:$src1),
572                      (EXTRACT_SUBREG (v2f64 VR128:$src2), sub_sd))>;
573   def : Pat<(v4f32 (X86Movsd VR128:$src1, VR128:$src2)),
574             (VMOVSDrr VR128:$src1, (EXTRACT_SUBREG (v4f32 VR128:$src2),
575                                                    sub_sd))>;
576   def : Pat<(v4i32 (X86Movsd VR128:$src1, VR128:$src2)),
577             (VMOVSDrr VR128:$src1, (EXTRACT_SUBREG (v4i32 VR128:$src2),
578                                                    sub_sd))>;
579
580   // 256-bit variants
581   def : Pat<(v4i64 (X86Movsd VR256:$src1, VR256:$src2)),
582             (SUBREG_TO_REG (i32 0),
583                 (VMOVSDrr (EXTRACT_SUBREG (v4i64 VR256:$src1), sub_sd),
584                           (EXTRACT_SUBREG (v4i64 VR256:$src2), sub_sd)), sub_xmm)>;
585   def : Pat<(v4f64 (X86Movsd VR256:$src1, VR256:$src2)),
586             (SUBREG_TO_REG (i32 0),
587                 (VMOVSDrr (EXTRACT_SUBREG (v4f64 VR256:$src1), sub_sd),
588                           (EXTRACT_SUBREG (v4f64 VR256:$src2), sub_sd)), sub_xmm)>;
589
590
591   // FIXME: Instead of a X86Movlps there should be a X86Movsd here, the problem
592   // is during lowering, where it's not possible to recognize the fold cause
593   // it has two uses through a bitcast. One use disappears at isel time and the
594   // fold opportunity reappears.
595   def : Pat<(v2f64 (X86Movlpd VR128:$src1, VR128:$src2)),
596             (VMOVSDrr VR128:$src1, (EXTRACT_SUBREG (v2f64 VR128:$src2),
597                                                    sub_sd))>;
598   def : Pat<(v2i64 (X86Movlpd VR128:$src1, VR128:$src2)),
599             (VMOVSDrr VR128:$src1, (EXTRACT_SUBREG (v2i64 VR128:$src2),
600                                                    sub_sd))>;
601   def : Pat<(v4f32 (X86Movlps VR128:$src1, VR128:$src2)),
602             (VMOVSDrr VR128:$src1, (EXTRACT_SUBREG (v4f32 VR128:$src2),
603                                                    sub_sd))>;
604   def : Pat<(v4i32 (X86Movlps VR128:$src1, VR128:$src2)),
605             (VMOVSDrr VR128:$src1, (EXTRACT_SUBREG (v4i32 VR128:$src2),
606                                                    sub_sd))>;
607 }
608
609 let Predicates = [HasSSE1] in {
610   let AddedComplexity = 15 in {
611   // Extract the low 32-bit value from one vector and insert it into another.
612   def : Pat<(v4f32 (movl VR128:$src1, VR128:$src2)),
613             (MOVSSrr (v4f32 VR128:$src1),
614                      (EXTRACT_SUBREG (v4f32 VR128:$src2), sub_ss))>;
615   def : Pat<(v4i32 (movl VR128:$src1, VR128:$src2)),
616             (MOVSSrr (v4i32 VR128:$src1),
617                      (EXTRACT_SUBREG (v4i32 VR128:$src2), sub_ss))>;
618
619   // Move scalar to XMM zero-extended, zeroing a VR128 then do a
620   // MOVSS to the lower bits.
621   def : Pat<(v4f32 (X86vzmovl (v4f32 (scalar_to_vector FR32:$src)))),
622             (MOVSSrr (v4f32 (V_SET0)), FR32:$src)>;
623   def : Pat<(v4f32 (X86vzmovl (v4f32 VR128:$src))),
624             (MOVSSrr (v4f32 (V_SET0)),
625                      (f32 (EXTRACT_SUBREG (v4f32 VR128:$src), sub_ss)))>;
626   def : Pat<(v4i32 (X86vzmovl (v4i32 VR128:$src))),
627             (MOVSSrr (v4i32 (V_SET0)),
628                      (EXTRACT_SUBREG (v4i32 VR128:$src), sub_ss))>;
629   }
630
631   let AddedComplexity = 20 in {
632   // MOVSSrm zeros the high parts of the register; represent this
633   // with SUBREG_TO_REG.
634   def : Pat<(v4f32 (X86vzmovl (v4f32 (scalar_to_vector (loadf32 addr:$src))))),
635             (SUBREG_TO_REG (i32 0), (MOVSSrm addr:$src), sub_ss)>;
636   def : Pat<(v4f32 (scalar_to_vector (loadf32 addr:$src))),
637             (SUBREG_TO_REG (i32 0), (MOVSSrm addr:$src), sub_ss)>;
638   def : Pat<(v4f32 (X86vzmovl (loadv4f32 addr:$src))),
639             (SUBREG_TO_REG (i32 0), (MOVSSrm addr:$src), sub_ss)>;
640   }
641
642   // Extract and store.
643   def : Pat<(store (f32 (vector_extract (v4f32 VR128:$src), (iPTR 0))),
644                    addr:$dst),
645             (MOVSSmr addr:$dst,
646                      (EXTRACT_SUBREG (v4f32 VR128:$src), sub_ss))>;
647
648   // Shuffle with MOVSS
649   def : Pat<(v4f32 (X86Movss VR128:$src1, (scalar_to_vector FR32:$src2))),
650             (MOVSSrr VR128:$src1, FR32:$src2)>;
651   def : Pat<(v4i32 (X86Movss VR128:$src1, VR128:$src2)),
652             (MOVSSrr (v4i32 VR128:$src1),
653                      (EXTRACT_SUBREG (v4i32 VR128:$src2), sub_ss))>;
654   def : Pat<(v4f32 (X86Movss VR128:$src1, VR128:$src2)),
655             (MOVSSrr (v4f32 VR128:$src1),
656                      (EXTRACT_SUBREG (v4f32 VR128:$src2), sub_ss))>;
657 }
658
659 let Predicates = [HasSSE2] in {
660   let AddedComplexity = 15 in {
661   // Extract the low 64-bit value from one vector and insert it into another.
662   def : Pat<(v2f64 (movl VR128:$src1, VR128:$src2)),
663             (MOVSDrr (v2f64 VR128:$src1),
664                      (EXTRACT_SUBREG (v2f64 VR128:$src2), sub_sd))>;
665   def : Pat<(v2i64 (movl VR128:$src1, VR128:$src2)),
666             (MOVSDrr (v2i64 VR128:$src1),
667                      (EXTRACT_SUBREG (v2i64 VR128:$src2), sub_sd))>;
668
669   // vector_shuffle v1, v2 <4, 5, 2, 3> using movsd
670   def : Pat<(v4f32 (movlp VR128:$src1, VR128:$src2)),
671             (MOVSDrr VR128:$src1, (EXTRACT_SUBREG VR128:$src2, sub_sd))>;
672   def : Pat<(v4i32 (movlp VR128:$src1, VR128:$src2)),
673             (MOVSDrr VR128:$src1, (EXTRACT_SUBREG VR128:$src2, sub_sd))>;
674
675   // Move scalar to XMM zero-extended, zeroing a VR128 then do a
676   // MOVSD to the lower bits.
677   def : Pat<(v2f64 (X86vzmovl (v2f64 (scalar_to_vector FR64:$src)))),
678             (MOVSDrr (v2f64 (V_SET0)), FR64:$src)>;
679   }
680
681   let AddedComplexity = 20 in {
682   // MOVSDrm zeros the high parts of the register; represent this
683   // with SUBREG_TO_REG.
684   def : Pat<(v2f64 (X86vzmovl (v2f64 (scalar_to_vector (loadf64 addr:$src))))),
685             (SUBREG_TO_REG (i64 0), (MOVSDrm addr:$src), sub_sd)>;
686   def : Pat<(v2f64 (scalar_to_vector (loadf64 addr:$src))),
687             (SUBREG_TO_REG (i64 0), (MOVSDrm addr:$src), sub_sd)>;
688   def : Pat<(v2f64 (X86vzmovl (loadv2f64 addr:$src))),
689             (SUBREG_TO_REG (i64 0), (MOVSDrm addr:$src), sub_sd)>;
690   def : Pat<(v2f64 (X86vzmovl (bc_v2f64 (loadv4f32 addr:$src)))),
691             (SUBREG_TO_REG (i64 0), (MOVSDrm addr:$src), sub_sd)>;
692   def : Pat<(v2f64 (X86vzload addr:$src)),
693             (SUBREG_TO_REG (i64 0), (MOVSDrm addr:$src), sub_sd)>;
694   }
695
696   // Extract and store.
697   def : Pat<(store (f64 (vector_extract (v2f64 VR128:$src), (iPTR 0))),
698                    addr:$dst),
699             (MOVSDmr addr:$dst,
700                      (EXTRACT_SUBREG (v2f64 VR128:$src), sub_sd))>;
701
702   // Shuffle with MOVSD
703   def : Pat<(v2f64 (X86Movsd VR128:$src1, (scalar_to_vector FR64:$src2))),
704             (MOVSDrr VR128:$src1, FR64:$src2)>;
705   def : Pat<(v2i64 (X86Movsd VR128:$src1, VR128:$src2)),
706             (MOVSDrr (v2i64 VR128:$src1),
707                      (EXTRACT_SUBREG (v2i64 VR128:$src2), sub_sd))>;
708   def : Pat<(v2f64 (X86Movsd VR128:$src1, VR128:$src2)),
709             (MOVSDrr (v2f64 VR128:$src1),
710                      (EXTRACT_SUBREG (v2f64 VR128:$src2), sub_sd))>;
711   def : Pat<(v4f32 (X86Movsd VR128:$src1, VR128:$src2)),
712             (MOVSDrr VR128:$src1, (EXTRACT_SUBREG (v4f32 VR128:$src2),sub_sd))>;
713   def : Pat<(v4i32 (X86Movsd VR128:$src1, VR128:$src2)),
714             (MOVSDrr VR128:$src1, (EXTRACT_SUBREG (v4i32 VR128:$src2),sub_sd))>;
715
716   // FIXME: Instead of a X86Movlps there should be a X86Movsd here, the problem
717   // is during lowering, where it's not possible to recognize the fold cause
718   // it has two uses through a bitcast. One use disappears at isel time and the
719   // fold opportunity reappears.
720   def : Pat<(v2f64 (X86Movlpd VR128:$src1, VR128:$src2)),
721             (MOVSDrr VR128:$src1, (EXTRACT_SUBREG (v2f64 VR128:$src2),sub_sd))>;
722   def : Pat<(v2i64 (X86Movlpd VR128:$src1, VR128:$src2)),
723             (MOVSDrr VR128:$src1, (EXTRACT_SUBREG (v2i64 VR128:$src2),sub_sd))>;
724   def : Pat<(v4f32 (X86Movlps VR128:$src1, VR128:$src2)),
725             (MOVSDrr VR128:$src1, (EXTRACT_SUBREG (v4f32 VR128:$src2),sub_sd))>;
726   def : Pat<(v4i32 (X86Movlps VR128:$src1, VR128:$src2)),
727             (MOVSDrr VR128:$src1, (EXTRACT_SUBREG (v4i32 VR128:$src2),sub_sd))>;
728 }
729
730 //===----------------------------------------------------------------------===//
731 // SSE 1 & 2 - Move Aligned/Unaligned FP Instructions
732 //===----------------------------------------------------------------------===//
733
734 multiclass sse12_mov_packed<bits<8> opc, RegisterClass RC,
735                             X86MemOperand x86memop, PatFrag ld_frag,
736                             string asm, Domain d,
737                             bit IsReMaterializable = 1> {
738 let neverHasSideEffects = 1 in
739   def rr : PI<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src),
740               !strconcat(asm, "\t{$src, $dst|$dst, $src}"), [], d>;
741 let canFoldAsLoad = 1, isReMaterializable = IsReMaterializable in
742   def rm : PI<opc, MRMSrcMem, (outs RC:$dst), (ins x86memop:$src),
743               !strconcat(asm, "\t{$src, $dst|$dst, $src}"),
744                    [(set RC:$dst, (ld_frag addr:$src))], d>;
745 }
746
747 defm VMOVAPS : sse12_mov_packed<0x28, VR128, f128mem, alignedloadv4f32,
748                               "movaps", SSEPackedSingle>, TB, VEX;
749 defm VMOVAPD : sse12_mov_packed<0x28, VR128, f128mem, alignedloadv2f64,
750                               "movapd", SSEPackedDouble>, TB, OpSize, VEX;
751 defm VMOVUPS : sse12_mov_packed<0x10, VR128, f128mem, loadv4f32,
752                               "movups", SSEPackedSingle>, TB, VEX;
753 defm VMOVUPD : sse12_mov_packed<0x10, VR128, f128mem, loadv2f64,
754                               "movupd", SSEPackedDouble, 0>, TB, OpSize, VEX;
755
756 defm VMOVAPSY : sse12_mov_packed<0x28, VR256, f256mem, alignedloadv8f32,
757                               "movaps", SSEPackedSingle>, TB, VEX;
758 defm VMOVAPDY : sse12_mov_packed<0x28, VR256, f256mem, alignedloadv4f64,
759                               "movapd", SSEPackedDouble>, TB, OpSize, VEX;
760 defm VMOVUPSY : sse12_mov_packed<0x10, VR256, f256mem, loadv8f32,
761                               "movups", SSEPackedSingle>, TB, VEX;
762 defm VMOVUPDY : sse12_mov_packed<0x10, VR256, f256mem, loadv4f64,
763                               "movupd", SSEPackedDouble, 0>, TB, OpSize, VEX;
764 defm MOVAPS : sse12_mov_packed<0x28, VR128, f128mem, alignedloadv4f32,
765                               "movaps", SSEPackedSingle>, TB;
766 defm MOVAPD : sse12_mov_packed<0x28, VR128, f128mem, alignedloadv2f64,
767                               "movapd", SSEPackedDouble>, TB, OpSize;
768 defm MOVUPS : sse12_mov_packed<0x10, VR128, f128mem, loadv4f32,
769                               "movups", SSEPackedSingle>, TB;
770 defm MOVUPD : sse12_mov_packed<0x10, VR128, f128mem, loadv2f64,
771                               "movupd", SSEPackedDouble, 0>, TB, OpSize;
772
773 def VMOVAPSmr : VPSI<0x29, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
774                    "movaps\t{$src, $dst|$dst, $src}",
775                    [(alignedstore (v4f32 VR128:$src), addr:$dst)]>, VEX;
776 def VMOVAPDmr : VPDI<0x29, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
777                    "movapd\t{$src, $dst|$dst, $src}",
778                    [(alignedstore (v2f64 VR128:$src), addr:$dst)]>, VEX;
779 def VMOVUPSmr : VPSI<0x11, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
780                    "movups\t{$src, $dst|$dst, $src}",
781                    [(store (v4f32 VR128:$src), addr:$dst)]>, VEX;
782 def VMOVUPDmr : VPDI<0x11, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
783                    "movupd\t{$src, $dst|$dst, $src}",
784                    [(store (v2f64 VR128:$src), addr:$dst)]>, VEX;
785 def VMOVAPSYmr : VPSI<0x29, MRMDestMem, (outs), (ins f256mem:$dst, VR256:$src),
786                    "movaps\t{$src, $dst|$dst, $src}",
787                    [(alignedstore256 (v8f32 VR256:$src), addr:$dst)]>, VEX;
788 def VMOVAPDYmr : VPDI<0x29, MRMDestMem, (outs), (ins f256mem:$dst, VR256:$src),
789                    "movapd\t{$src, $dst|$dst, $src}",
790                    [(alignedstore256 (v4f64 VR256:$src), addr:$dst)]>, VEX;
791 def VMOVUPSYmr : VPSI<0x11, MRMDestMem, (outs), (ins f256mem:$dst, VR256:$src),
792                    "movups\t{$src, $dst|$dst, $src}",
793                    [(store (v8f32 VR256:$src), addr:$dst)]>, VEX;
794 def VMOVUPDYmr : VPDI<0x11, MRMDestMem, (outs), (ins f256mem:$dst, VR256:$src),
795                    "movupd\t{$src, $dst|$dst, $src}",
796                    [(store (v4f64 VR256:$src), addr:$dst)]>, VEX;
797
798 // For disassembler
799 let isCodeGenOnly = 1 in {
800   def VMOVAPSrr_REV : VPSI<0x29, MRMDestReg, (outs VR128:$dst),
801                           (ins VR128:$src),
802                           "movaps\t{$src, $dst|$dst, $src}", []>, VEX;
803   def VMOVAPDrr_REV : VPDI<0x29, MRMDestReg, (outs VR128:$dst),
804                            (ins VR128:$src),
805                            "movapd\t{$src, $dst|$dst, $src}", []>, VEX;
806   def VMOVUPSrr_REV : VPSI<0x11, MRMDestReg, (outs VR128:$dst),
807                            (ins VR128:$src),
808                            "movups\t{$src, $dst|$dst, $src}", []>, VEX;
809   def VMOVUPDrr_REV : VPDI<0x11, MRMDestReg, (outs VR128:$dst),
810                            (ins VR128:$src),
811                            "movupd\t{$src, $dst|$dst, $src}", []>, VEX;
812   def VMOVAPSYrr_REV : VPSI<0x29, MRMDestReg, (outs VR256:$dst),
813                             (ins VR256:$src),
814                             "movaps\t{$src, $dst|$dst, $src}", []>, VEX;
815   def VMOVAPDYrr_REV : VPDI<0x29, MRMDestReg, (outs VR256:$dst),
816                             (ins VR256:$src),
817                             "movapd\t{$src, $dst|$dst, $src}", []>, VEX;
818   def VMOVUPSYrr_REV : VPSI<0x11, MRMDestReg, (outs VR256:$dst),
819                             (ins VR256:$src),
820                             "movups\t{$src, $dst|$dst, $src}", []>, VEX;
821   def VMOVUPDYrr_REV : VPDI<0x11, MRMDestReg, (outs VR256:$dst),
822                             (ins VR256:$src),
823                             "movupd\t{$src, $dst|$dst, $src}", []>, VEX;
824 }
825
826 let Predicates = [HasAVX] in {
827 def : Pat<(v8i32 (X86vzmovl
828                         (insert_subvector undef, (v4i32 VR128:$src), (i32 0)))),
829           (SUBREG_TO_REG (i32 0), (VMOVAPSrr VR128:$src), sub_xmm)>;
830 def : Pat<(v4i64 (X86vzmovl
831                         (insert_subvector undef, (v2i64 VR128:$src), (i32 0)))),
832           (SUBREG_TO_REG (i32 0), (VMOVAPSrr VR128:$src), sub_xmm)>;
833 def : Pat<(v8f32 (X86vzmovl
834                         (insert_subvector undef, (v4f32 VR128:$src), (i32 0)))),
835           (SUBREG_TO_REG (i32 0), (VMOVAPSrr VR128:$src), sub_xmm)>;
836 def : Pat<(v4f64 (X86vzmovl
837                         (insert_subvector undef, (v2f64 VR128:$src), (i32 0)))),
838           (SUBREG_TO_REG (i32 0), (VMOVAPSrr VR128:$src), sub_xmm)>;
839 }
840
841
842 def : Pat<(int_x86_avx_loadu_ps_256 addr:$src), (VMOVUPSYrm addr:$src)>;
843 def : Pat<(int_x86_avx_storeu_ps_256 addr:$dst, VR256:$src),
844           (VMOVUPSYmr addr:$dst, VR256:$src)>;
845
846 def : Pat<(int_x86_avx_loadu_pd_256 addr:$src), (VMOVUPDYrm addr:$src)>;
847 def : Pat<(int_x86_avx_storeu_pd_256 addr:$dst, VR256:$src),
848           (VMOVUPDYmr addr:$dst, VR256:$src)>;
849
850 def MOVAPSmr : PSI<0x29, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
851                    "movaps\t{$src, $dst|$dst, $src}",
852                    [(alignedstore (v4f32 VR128:$src), addr:$dst)]>;
853 def MOVAPDmr : PDI<0x29, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
854                    "movapd\t{$src, $dst|$dst, $src}",
855                    [(alignedstore (v2f64 VR128:$src), addr:$dst)]>;
856 def MOVUPSmr : PSI<0x11, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
857                    "movups\t{$src, $dst|$dst, $src}",
858                    [(store (v4f32 VR128:$src), addr:$dst)]>;
859 def MOVUPDmr : PDI<0x11, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
860                    "movupd\t{$src, $dst|$dst, $src}",
861                    [(store (v2f64 VR128:$src), addr:$dst)]>;
862
863 // For disassembler
864 let isCodeGenOnly = 1 in {
865   def MOVAPSrr_REV : PSI<0x29, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
866                          "movaps\t{$src, $dst|$dst, $src}", []>;
867   def MOVAPDrr_REV : PDI<0x29, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
868                          "movapd\t{$src, $dst|$dst, $src}", []>;
869   def MOVUPSrr_REV : PSI<0x11, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
870                          "movups\t{$src, $dst|$dst, $src}", []>;
871   def MOVUPDrr_REV : PDI<0x11, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
872                          "movupd\t{$src, $dst|$dst, $src}", []>;
873 }
874
875 let Predicates = [HasAVX] in {
876   def : Pat<(int_x86_sse_storeu_ps addr:$dst, VR128:$src),
877             (VMOVUPSmr addr:$dst, VR128:$src)>;
878   def : Pat<(int_x86_sse2_storeu_pd addr:$dst, VR128:$src),
879             (VMOVUPDmr addr:$dst, VR128:$src)>;
880 }
881
882 let Predicates = [HasSSE1] in
883   def : Pat<(int_x86_sse_storeu_ps addr:$dst, VR128:$src),
884             (MOVUPSmr addr:$dst, VR128:$src)>;
885 let Predicates = [HasSSE2] in
886   def : Pat<(int_x86_sse2_storeu_pd addr:$dst, VR128:$src),
887             (MOVUPDmr addr:$dst, VR128:$src)>;
888
889 // Use vmovaps/vmovups for AVX integer load/store.
890 let Predicates = [HasAVX] in {
891   // 128-bit load/store
892   def : Pat<(alignedloadv4i32 addr:$src),
893             (VMOVAPSrm addr:$src)>;
894   def : Pat<(loadv4i32 addr:$src),
895             (VMOVUPSrm addr:$src)>;
896   def : Pat<(alignedloadv2i64 addr:$src),
897             (VMOVAPSrm addr:$src)>;
898   def : Pat<(loadv2i64 addr:$src),
899             (VMOVUPSrm addr:$src)>;
900
901   def : Pat<(alignedstore (v2i64 VR128:$src), addr:$dst),
902             (VMOVAPSmr addr:$dst, VR128:$src)>;
903   def : Pat<(alignedstore (v4i32 VR128:$src), addr:$dst),
904             (VMOVAPSmr addr:$dst, VR128:$src)>;
905   def : Pat<(alignedstore (v8i16 VR128:$src), addr:$dst),
906             (VMOVAPSmr addr:$dst, VR128:$src)>;
907   def : Pat<(alignedstore (v16i8 VR128:$src), addr:$dst),
908             (VMOVAPSmr addr:$dst, VR128:$src)>;
909   def : Pat<(store (v2i64 VR128:$src), addr:$dst),
910             (VMOVUPSmr addr:$dst, VR128:$src)>;
911   def : Pat<(store (v4i32 VR128:$src), addr:$dst),
912             (VMOVUPSmr addr:$dst, VR128:$src)>;
913   def : Pat<(store (v8i16 VR128:$src), addr:$dst),
914             (VMOVUPSmr addr:$dst, VR128:$src)>;
915   def : Pat<(store (v16i8 VR128:$src), addr:$dst),
916             (VMOVUPSmr addr:$dst, VR128:$src)>;
917
918   // 256-bit load/store
919   def : Pat<(alignedloadv4i64 addr:$src),
920             (VMOVAPSYrm addr:$src)>;
921   def : Pat<(loadv4i64 addr:$src),
922             (VMOVUPSYrm addr:$src)>;
923   def : Pat<(alignedloadv8i32 addr:$src),
924             (VMOVAPSYrm addr:$src)>;
925   def : Pat<(loadv8i32 addr:$src),
926             (VMOVUPSYrm addr:$src)>;
927   def : Pat<(alignedstore256 (v4i64 VR256:$src), addr:$dst),
928             (VMOVAPSYmr addr:$dst, VR256:$src)>;
929   def : Pat<(alignedstore256 (v8i32 VR256:$src), addr:$dst),
930             (VMOVAPSYmr addr:$dst, VR256:$src)>;
931   def : Pat<(alignedstore256 (v16i16 VR256:$src), addr:$dst),
932             (VMOVAPSYmr addr:$dst, VR256:$src)>;
933   def : Pat<(alignedstore256 (v32i8 VR256:$src), addr:$dst),
934             (VMOVAPSYmr addr:$dst, VR256:$src)>;
935   def : Pat<(store (v4i64 VR256:$src), addr:$dst),
936             (VMOVUPSYmr addr:$dst, VR256:$src)>;
937   def : Pat<(store (v8i32 VR256:$src), addr:$dst),
938             (VMOVUPSYmr addr:$dst, VR256:$src)>;
939   def : Pat<(store (v16i16 VR256:$src), addr:$dst),
940             (VMOVUPSYmr addr:$dst, VR256:$src)>;
941   def : Pat<(store (v32i8 VR256:$src), addr:$dst),
942             (VMOVUPSYmr addr:$dst, VR256:$src)>;
943 }
944
945 // Use movaps / movups for SSE integer load / store (one byte shorter).
946 // The instructions selected below are then converted to MOVDQA/MOVDQU
947 // during the SSE domain pass.
948 let Predicates = [HasSSE1] in {
949   def : Pat<(alignedloadv4i32 addr:$src),
950             (MOVAPSrm addr:$src)>;
951   def : Pat<(loadv4i32 addr:$src),
952             (MOVUPSrm addr:$src)>;
953   def : Pat<(alignedloadv2i64 addr:$src),
954             (MOVAPSrm addr:$src)>;
955   def : Pat<(loadv2i64 addr:$src),
956             (MOVUPSrm addr:$src)>;
957
958   def : Pat<(alignedstore (v2i64 VR128:$src), addr:$dst),
959             (MOVAPSmr addr:$dst, VR128:$src)>;
960   def : Pat<(alignedstore (v4i32 VR128:$src), addr:$dst),
961             (MOVAPSmr addr:$dst, VR128:$src)>;
962   def : Pat<(alignedstore (v8i16 VR128:$src), addr:$dst),
963             (MOVAPSmr addr:$dst, VR128:$src)>;
964   def : Pat<(alignedstore (v16i8 VR128:$src), addr:$dst),
965             (MOVAPSmr addr:$dst, VR128:$src)>;
966   def : Pat<(store (v2i64 VR128:$src), addr:$dst),
967             (MOVUPSmr addr:$dst, VR128:$src)>;
968   def : Pat<(store (v4i32 VR128:$src), addr:$dst),
969             (MOVUPSmr addr:$dst, VR128:$src)>;
970   def : Pat<(store (v8i16 VR128:$src), addr:$dst),
971             (MOVUPSmr addr:$dst, VR128:$src)>;
972   def : Pat<(store (v16i8 VR128:$src), addr:$dst),
973             (MOVUPSmr addr:$dst, VR128:$src)>;
974 }
975
976 // Alias instruction to do FR32 or FR64 reg-to-reg copy using movaps. Upper
977 // bits are disregarded. FIXME: Set encoding to pseudo!
978 let neverHasSideEffects = 1 in {
979 def FsVMOVAPSrr : VPSI<0x28, MRMSrcReg, (outs FR32:$dst), (ins FR32:$src),
980                        "movaps\t{$src, $dst|$dst, $src}", []>, VEX;
981 def FsVMOVAPDrr : VPDI<0x28, MRMSrcReg, (outs FR64:$dst), (ins FR64:$src),
982                        "movapd\t{$src, $dst|$dst, $src}", []>, VEX;
983 def FsMOVAPSrr : PSI<0x28, MRMSrcReg, (outs FR32:$dst), (ins FR32:$src),
984                      "movaps\t{$src, $dst|$dst, $src}", []>;
985 def FsMOVAPDrr : PDI<0x28, MRMSrcReg, (outs FR64:$dst), (ins FR64:$src),
986                      "movapd\t{$src, $dst|$dst, $src}", []>;
987 }
988
989 // Alias instruction to load FR32 or FR64 from f128mem using movaps. Upper
990 // bits are disregarded. FIXME: Set encoding to pseudo!
991 let canFoldAsLoad = 1, isReMaterializable = 1 in {
992 let isCodeGenOnly = 1 in {
993   def FsVMOVAPSrm : VPSI<0x28, MRMSrcMem, (outs FR32:$dst), (ins f128mem:$src),
994                          "movaps\t{$src, $dst|$dst, $src}",
995                          [(set FR32:$dst, (alignedloadfsf32 addr:$src))]>, VEX;
996   def FsVMOVAPDrm : VPDI<0x28, MRMSrcMem, (outs FR64:$dst), (ins f128mem:$src),
997                          "movapd\t{$src, $dst|$dst, $src}",
998                          [(set FR64:$dst, (alignedloadfsf64 addr:$src))]>, VEX;
999 }
1000 def FsMOVAPSrm : PSI<0x28, MRMSrcMem, (outs FR32:$dst), (ins f128mem:$src),
1001                      "movaps\t{$src, $dst|$dst, $src}",
1002                      [(set FR32:$dst, (alignedloadfsf32 addr:$src))]>;
1003 def FsMOVAPDrm : PDI<0x28, MRMSrcMem, (outs FR64:$dst), (ins f128mem:$src),
1004                      "movapd\t{$src, $dst|$dst, $src}",
1005                      [(set FR64:$dst, (alignedloadfsf64 addr:$src))]>;
1006 }
1007
1008 //===----------------------------------------------------------------------===//
1009 // SSE 1 & 2 - Move Low packed FP Instructions
1010 //===----------------------------------------------------------------------===//
1011
1012 multiclass sse12_mov_hilo_packed<bits<8>opc, RegisterClass RC,
1013                                  PatFrag mov_frag, string base_opc,
1014                                  string asm_opr> {
1015   def PSrm : PI<opc, MRMSrcMem,
1016          (outs VR128:$dst), (ins VR128:$src1, f64mem:$src2),
1017          !strconcat(base_opc, "s", asm_opr),
1018      [(set RC:$dst,
1019        (mov_frag RC:$src1,
1020               (bc_v4f32 (v2f64 (scalar_to_vector (loadf64 addr:$src2))))))],
1021               SSEPackedSingle>, TB;
1022
1023   def PDrm : PI<opc, MRMSrcMem,
1024          (outs RC:$dst), (ins RC:$src1, f64mem:$src2),
1025          !strconcat(base_opc, "d", asm_opr),
1026      [(set RC:$dst, (v2f64 (mov_frag RC:$src1,
1027                               (scalar_to_vector (loadf64 addr:$src2)))))],
1028               SSEPackedDouble>, TB, OpSize;
1029 }
1030
1031 let AddedComplexity = 20 in {
1032   defm VMOVL : sse12_mov_hilo_packed<0x12, VR128, movlp, "movlp",
1033                      "\t{$src2, $src1, $dst|$dst, $src1, $src2}">, VEX_4V;
1034 }
1035 let Constraints = "$src1 = $dst", AddedComplexity = 20 in {
1036   defm MOVL : sse12_mov_hilo_packed<0x12, VR128, movlp, "movlp",
1037                                    "\t{$src2, $dst|$dst, $src2}">;
1038 }
1039
1040 def VMOVLPSmr : VPSI<0x13, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
1041                    "movlps\t{$src, $dst|$dst, $src}",
1042                    [(store (f64 (vector_extract (bc_v2f64 (v4f32 VR128:$src)),
1043                                  (iPTR 0))), addr:$dst)]>, VEX;
1044 def VMOVLPDmr : VPDI<0x13, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
1045                    "movlpd\t{$src, $dst|$dst, $src}",
1046                    [(store (f64 (vector_extract (v2f64 VR128:$src),
1047                                  (iPTR 0))), addr:$dst)]>, VEX;
1048 def MOVLPSmr : PSI<0x13, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
1049                    "movlps\t{$src, $dst|$dst, $src}",
1050                    [(store (f64 (vector_extract (bc_v2f64 (v4f32 VR128:$src)),
1051                                  (iPTR 0))), addr:$dst)]>;
1052 def MOVLPDmr : PDI<0x13, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
1053                    "movlpd\t{$src, $dst|$dst, $src}",
1054                    [(store (f64 (vector_extract (v2f64 VR128:$src),
1055                                  (iPTR 0))), addr:$dst)]>;
1056
1057 let Predicates = [HasAVX] in {
1058   let AddedComplexity = 20 in {
1059     // vector_shuffle v1, (load v2) <4, 5, 2, 3> using MOVLPS
1060     def : Pat<(v4f32 (movlp VR128:$src1, (load addr:$src2))),
1061               (VMOVLPSrm VR128:$src1, addr:$src2)>;
1062     def : Pat<(v4i32 (movlp VR128:$src1, (load addr:$src2))),
1063               (VMOVLPSrm VR128:$src1, addr:$src2)>;
1064     // vector_shuffle v1, (load v2) <2, 1> using MOVLPS
1065     def : Pat<(v2f64 (movlp VR128:$src1, (load addr:$src2))),
1066               (VMOVLPDrm VR128:$src1, addr:$src2)>;
1067     def : Pat<(v2i64 (movlp VR128:$src1, (load addr:$src2))),
1068               (VMOVLPDrm VR128:$src1, addr:$src2)>;
1069   }
1070
1071   // (store (vector_shuffle (load addr), v2, <4, 5, 2, 3>), addr) using MOVLPS
1072   def : Pat<(store (v4f32 (movlp (load addr:$src1), VR128:$src2)), addr:$src1),
1073             (VMOVLPSmr addr:$src1, VR128:$src2)>;
1074   def : Pat<(store (v4i32 (movlp (bc_v4i32 (loadv2i64 addr:$src1)),
1075                                  VR128:$src2)), addr:$src1),
1076             (VMOVLPSmr addr:$src1, VR128:$src2)>;
1077
1078   // (store (vector_shuffle (load addr), v2, <2, 1>), addr) using MOVLPS
1079   def : Pat<(store (v2f64 (movlp (load addr:$src1), VR128:$src2)), addr:$src1),
1080             (VMOVLPDmr addr:$src1, VR128:$src2)>;
1081   def : Pat<(store (v2i64 (movlp (load addr:$src1), VR128:$src2)), addr:$src1),
1082             (VMOVLPDmr addr:$src1, VR128:$src2)>;
1083
1084   // Shuffle with VMOVLPS
1085   def : Pat<(v4f32 (X86Movlps VR128:$src1, (load addr:$src2))),
1086             (VMOVLPSrm VR128:$src1, addr:$src2)>;
1087   def : Pat<(v4i32 (X86Movlps VR128:$src1, (load addr:$src2))),
1088             (VMOVLPSrm VR128:$src1, addr:$src2)>;
1089   def : Pat<(X86Movlps VR128:$src1,
1090                       (bc_v4f32 (v2f64 (scalar_to_vector (loadf64 addr:$src2))))),
1091             (VMOVLPSrm VR128:$src1, addr:$src2)>;
1092
1093   // Shuffle with VMOVLPD
1094   def : Pat<(v2f64 (X86Movlpd VR128:$src1, (load addr:$src2))),
1095             (VMOVLPDrm VR128:$src1, addr:$src2)>;
1096   def : Pat<(v2i64 (X86Movlpd VR128:$src1, (load addr:$src2))),
1097             (VMOVLPDrm VR128:$src1, addr:$src2)>;
1098   def : Pat<(v2f64 (X86Movlpd VR128:$src1,
1099                               (scalar_to_vector (loadf64 addr:$src2)))),
1100             (VMOVLPDrm VR128:$src1, addr:$src2)>;
1101
1102   // Store patterns
1103   def : Pat<(store (v4f32 (X86Movlps (load addr:$src1), VR128:$src2)),
1104                    addr:$src1),
1105             (VMOVLPSmr addr:$src1, VR128:$src2)>;
1106   def : Pat<(store (v4i32 (X86Movlps
1107                    (bc_v4i32 (loadv2i64 addr:$src1)), VR128:$src2)), addr:$src1),
1108             (VMOVLPSmr addr:$src1, VR128:$src2)>;
1109   def : Pat<(store (v2f64 (X86Movlpd (load addr:$src1), VR128:$src2)),
1110                    addr:$src1),
1111             (VMOVLPDmr addr:$src1, VR128:$src2)>;
1112   def : Pat<(store (v2i64 (X86Movlpd (load addr:$src1), VR128:$src2)),
1113                    addr:$src1),
1114             (VMOVLPDmr addr:$src1, VR128:$src2)>;
1115 }
1116
1117 let Predicates = [HasSSE1] in {
1118   let AddedComplexity = 20 in {
1119     // vector_shuffle v1, (load v2) <4, 5, 2, 3> using MOVLPS
1120     def : Pat<(v4f32 (movlp VR128:$src1, (load addr:$src2))),
1121               (MOVLPSrm VR128:$src1, addr:$src2)>;
1122     def : Pat<(v4i32 (movlp VR128:$src1, (load addr:$src2))),
1123               (MOVLPSrm VR128:$src1, addr:$src2)>;
1124   }
1125
1126   // (store (vector_shuffle (load addr), v2, <4, 5, 2, 3>), addr) using MOVLPS
1127   def : Pat<(store (i64 (vector_extract (bc_v2i64 (v4f32 VR128:$src2)),
1128                                  (iPTR 0))), addr:$src1),
1129             (MOVLPSmr addr:$src1, VR128:$src2)>;
1130   def : Pat<(store (v4f32 (movlp (load addr:$src1), VR128:$src2)), addr:$src1),
1131             (MOVLPSmr addr:$src1, VR128:$src2)>;
1132   def : Pat<(store (v4i32 (movlp (bc_v4i32 (loadv2i64 addr:$src1)),
1133                                  VR128:$src2)), addr:$src1),
1134             (MOVLPSmr addr:$src1, VR128:$src2)>;
1135
1136   // Shuffle with MOVLPS
1137   def : Pat<(v4f32 (X86Movlps VR128:$src1, (load addr:$src2))),
1138             (MOVLPSrm VR128:$src1, addr:$src2)>;
1139   def : Pat<(v4i32 (X86Movlps VR128:$src1, (load addr:$src2))),
1140             (MOVLPSrm VR128:$src1, addr:$src2)>;
1141   def : Pat<(X86Movlps VR128:$src1,
1142                       (bc_v4f32 (v2f64 (scalar_to_vector (loadf64 addr:$src2))))),
1143             (MOVLPSrm VR128:$src1, addr:$src2)>;
1144   def : Pat<(X86Movlps VR128:$src1,
1145                       (bc_v4f32 (v2i64 (scalar_to_vector (loadi64 addr:$src2))))),
1146             (MOVLPSrm VR128:$src1, addr:$src2)>;
1147
1148   // Store patterns
1149   def : Pat<(store (v4f32 (X86Movlps (load addr:$src1), VR128:$src2)),
1150                                       addr:$src1),
1151             (MOVLPSmr addr:$src1, VR128:$src2)>;
1152   def : Pat<(store (v4i32 (X86Movlps
1153                    (bc_v4i32 (loadv2i64 addr:$src1)), VR128:$src2)),
1154                               addr:$src1),
1155             (MOVLPSmr addr:$src1, VR128:$src2)>;
1156 }
1157
1158 let Predicates = [HasSSE2] in {
1159   let AddedComplexity = 20 in {
1160     // vector_shuffle v1, (load v2) <2, 1> using MOVLPS
1161     def : Pat<(v2f64 (movlp VR128:$src1, (load addr:$src2))),
1162               (MOVLPDrm VR128:$src1, addr:$src2)>;
1163     def : Pat<(v2i64 (movlp VR128:$src1, (load addr:$src2))),
1164               (MOVLPDrm VR128:$src1, addr:$src2)>;
1165   }
1166
1167   // (store (vector_shuffle (load addr), v2, <2, 1>), addr) using MOVLPS
1168   def : Pat<(store (v2f64 (movlp (load addr:$src1), VR128:$src2)), addr:$src1),
1169             (MOVLPDmr addr:$src1, VR128:$src2)>;
1170   def : Pat<(store (v2i64 (movlp (load addr:$src1), VR128:$src2)), addr:$src1),
1171             (MOVLPDmr addr:$src1, VR128:$src2)>;
1172
1173   // Shuffle with MOVLPD
1174   def : Pat<(v2f64 (X86Movlpd VR128:$src1, (load addr:$src2))),
1175             (MOVLPDrm VR128:$src1, addr:$src2)>;
1176   def : Pat<(v2i64 (X86Movlpd VR128:$src1, (load addr:$src2))),
1177             (MOVLPDrm VR128:$src1, addr:$src2)>;
1178   def : Pat<(v2f64 (X86Movlpd VR128:$src1,
1179                               (scalar_to_vector (loadf64 addr:$src2)))),
1180             (MOVLPDrm VR128:$src1, addr:$src2)>;
1181
1182   // Store patterns
1183   def : Pat<(store (v2f64 (X86Movlpd (load addr:$src1), VR128:$src2)),
1184                            addr:$src1),
1185             (MOVLPDmr addr:$src1, VR128:$src2)>;
1186   def : Pat<(store (v2i64 (X86Movlpd (load addr:$src1), VR128:$src2)),
1187                            addr:$src1),
1188             (MOVLPDmr addr:$src1, VR128:$src2)>;
1189 }
1190
1191 //===----------------------------------------------------------------------===//
1192 // SSE 1 & 2 - Move Hi packed FP Instructions
1193 //===----------------------------------------------------------------------===//
1194
1195 let AddedComplexity = 20 in {
1196   defm VMOVH : sse12_mov_hilo_packed<0x16, VR128, movlhps, "movhp",
1197                      "\t{$src2, $src1, $dst|$dst, $src1, $src2}">, VEX_4V;
1198 }
1199 let Constraints = "$src1 = $dst", AddedComplexity = 20 in {
1200   defm MOVH : sse12_mov_hilo_packed<0x16, VR128, movlhps, "movhp",
1201                                    "\t{$src2, $dst|$dst, $src2}">;
1202 }
1203
1204 // v2f64 extract element 1 is always custom lowered to unpack high to low
1205 // and extract element 0 so the non-store version isn't too horrible.
1206 def VMOVHPSmr : VPSI<0x17, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
1207                    "movhps\t{$src, $dst|$dst, $src}",
1208                    [(store (f64 (vector_extract
1209                                  (unpckh (bc_v2f64 (v4f32 VR128:$src)),
1210                                          (undef)), (iPTR 0))), addr:$dst)]>,
1211                    VEX;
1212 def VMOVHPDmr : VPDI<0x17, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
1213                    "movhpd\t{$src, $dst|$dst, $src}",
1214                    [(store (f64 (vector_extract
1215                                  (v2f64 (unpckh VR128:$src, (undef))),
1216                                  (iPTR 0))), addr:$dst)]>,
1217                    VEX;
1218 def MOVHPSmr : PSI<0x17, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
1219                    "movhps\t{$src, $dst|$dst, $src}",
1220                    [(store (f64 (vector_extract
1221                                  (unpckh (bc_v2f64 (v4f32 VR128:$src)),
1222                                          (undef)), (iPTR 0))), addr:$dst)]>;
1223 def MOVHPDmr : PDI<0x17, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
1224                    "movhpd\t{$src, $dst|$dst, $src}",
1225                    [(store (f64 (vector_extract
1226                                  (v2f64 (unpckh VR128:$src, (undef))),
1227                                  (iPTR 0))), addr:$dst)]>;
1228
1229 let Predicates = [HasAVX] in {
1230   // VMOVHPS patterns
1231   def : Pat<(movlhps VR128:$src1, (bc_v4i32 (v2i64 (X86vzload addr:$src2)))),
1232             (VMOVHPSrm (v4i32 VR128:$src1), addr:$src2)>;
1233   def : Pat<(X86Movlhps VR128:$src1,
1234                  (bc_v4f32 (v2f64 (scalar_to_vector (loadf64 addr:$src2))))),
1235             (VMOVHPSrm VR128:$src1, addr:$src2)>;
1236   def : Pat<(X86Movlhps VR128:$src1,
1237                  (bc_v4f32 (v2i64 (scalar_to_vector (loadi64 addr:$src2))))),
1238             (VMOVHPSrm VR128:$src1, addr:$src2)>;
1239   def : Pat<(X86Movlhps VR128:$src1,
1240                  (bc_v4i32 (v2i64 (X86vzload addr:$src2)))),
1241             (VMOVHPSrm VR128:$src1, addr:$src2)>;
1242
1243   // FIXME: Instead of X86Unpckl, there should be a X86Movlhpd here, the problem
1244   // is during lowering, where it's not possible to recognize the load fold 
1245   // cause it has two uses through a bitcast. One use disappears at isel time
1246   // and the fold opportunity reappears.
1247   def : Pat<(v2f64 (X86Unpckl VR128:$src1,
1248                       (scalar_to_vector (loadf64 addr:$src2)))),
1249             (VMOVHPDrm VR128:$src1, addr:$src2)>;
1250
1251   // FIXME: This should be matched by a X86Movhpd instead. Same as above
1252   def : Pat<(v2f64 (X86Movlhpd VR128:$src1,
1253                       (scalar_to_vector (loadf64 addr:$src2)))),
1254             (VMOVHPDrm VR128:$src1, addr:$src2)>;
1255
1256   // Store patterns
1257   def : Pat<(store (f64 (vector_extract
1258             (X86Unpckh (bc_v2f64 (v4f32 VR128:$src)),
1259                        (bc_v2f64 (v4f32 VR128:$src))), (iPTR 0))), addr:$dst),
1260             (VMOVHPSmr addr:$dst, VR128:$src)>;
1261   def : Pat<(store (f64 (vector_extract
1262             (v2f64 (X86Unpckh VR128:$src, VR128:$src)), (iPTR 0))), addr:$dst),
1263             (VMOVHPDmr addr:$dst, VR128:$src)>;
1264 }
1265
1266 let Predicates = [HasSSE1] in {
1267   // MOVHPS patterns
1268   def : Pat<(movlhps VR128:$src1, (bc_v4i32 (v2i64 (X86vzload addr:$src2)))),
1269             (MOVHPSrm (v4i32 VR128:$src1), addr:$src2)>;
1270   def : Pat<(X86Movlhps VR128:$src1,
1271                  (bc_v4f32 (v2f64 (scalar_to_vector (loadf64 addr:$src2))))),
1272             (MOVHPSrm VR128:$src1, addr:$src2)>;
1273   def : Pat<(X86Movlhps VR128:$src1,
1274                  (bc_v4f32 (v2i64 (scalar_to_vector (loadi64 addr:$src2))))),
1275             (MOVHPSrm VR128:$src1, addr:$src2)>;
1276   def : Pat<(X86Movlhps VR128:$src1,
1277                  (bc_v4f32 (v2i64 (X86vzload addr:$src2)))),
1278             (MOVHPSrm VR128:$src1, addr:$src2)>;
1279
1280   // Store patterns
1281   def : Pat<(store (f64 (vector_extract
1282             (X86Unpckh (bc_v2f64 (v4f32 VR128:$src)),
1283                        (bc_v2f64 (v4f32 VR128:$src))), (iPTR 0))), addr:$dst),
1284             (MOVHPSmr addr:$dst, VR128:$src)>;
1285 }
1286
1287 let Predicates = [HasSSE2] in {
1288   // FIXME: Instead of X86Unpckl, there should be a X86Movlhpd here, the problem
1289   // is during lowering, where it's not possible to recognize the load fold 
1290   // cause it has two uses through a bitcast. One use disappears at isel time
1291   // and the fold opportunity reappears.
1292   def : Pat<(v2f64 (X86Unpckl VR128:$src1,
1293                       (scalar_to_vector (loadf64 addr:$src2)))),
1294             (MOVHPDrm VR128:$src1, addr:$src2)>;
1295
1296   // FIXME: This should be matched by a X86Movhpd instead. Same as above
1297   def : Pat<(v2f64 (X86Movlhpd VR128:$src1,
1298                       (scalar_to_vector (loadf64 addr:$src2)))),
1299             (MOVHPDrm VR128:$src1, addr:$src2)>;
1300
1301   // Store patterns
1302   def : Pat<(store (f64 (vector_extract
1303             (v2f64 (X86Unpckh VR128:$src, VR128:$src)), (iPTR 0))),addr:$dst),
1304             (MOVHPDmr addr:$dst, VR128:$src)>;
1305 }
1306
1307 //===----------------------------------------------------------------------===//
1308 // SSE 1 & 2 - Move Low to High and High to Low packed FP Instructions
1309 //===----------------------------------------------------------------------===//
1310
1311 let AddedComplexity = 20 in {
1312   def VMOVLHPSrr : VPSI<0x16, MRMSrcReg, (outs VR128:$dst),
1313                                        (ins VR128:$src1, VR128:$src2),
1314                       "movlhps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1315                       [(set VR128:$dst,
1316                         (v4f32 (movlhps VR128:$src1, VR128:$src2)))]>,
1317                       VEX_4V;
1318   def VMOVHLPSrr : VPSI<0x12, MRMSrcReg, (outs VR128:$dst),
1319                                        (ins VR128:$src1, VR128:$src2),
1320                       "movhlps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1321                       [(set VR128:$dst,
1322                         (v4f32 (movhlps VR128:$src1, VR128:$src2)))]>,
1323                       VEX_4V;
1324 }
1325 let Constraints = "$src1 = $dst", AddedComplexity = 20 in {
1326   def MOVLHPSrr : PSI<0x16, MRMSrcReg, (outs VR128:$dst),
1327                                        (ins VR128:$src1, VR128:$src2),
1328                       "movlhps\t{$src2, $dst|$dst, $src2}",
1329                       [(set VR128:$dst,
1330                         (v4f32 (movlhps VR128:$src1, VR128:$src2)))]>;
1331   def MOVHLPSrr : PSI<0x12, MRMSrcReg, (outs VR128:$dst),
1332                                        (ins VR128:$src1, VR128:$src2),
1333                       "movhlps\t{$src2, $dst|$dst, $src2}",
1334                       [(set VR128:$dst,
1335                         (v4f32 (movhlps VR128:$src1, VR128:$src2)))]>;
1336 }
1337
1338 let Predicates = [HasAVX] in {
1339   // MOVLHPS patterns
1340   let AddedComplexity = 20 in {
1341     def : Pat<(v4f32 (movddup VR128:$src, (undef))),
1342               (VMOVLHPSrr (v4f32 VR128:$src), (v4f32 VR128:$src))>;
1343     def : Pat<(v2i64 (movddup VR128:$src, (undef))),
1344               (VMOVLHPSrr (v2i64 VR128:$src), (v2i64 VR128:$src))>;
1345
1346     // vector_shuffle v1, v2 <0, 1, 4, 5> using MOVLHPS
1347     def : Pat<(v4i32 (movlhps VR128:$src1, VR128:$src2)),
1348               (VMOVLHPSrr VR128:$src1, VR128:$src2)>;
1349   }
1350   def : Pat<(v4f32 (X86Movlhps VR128:$src1, VR128:$src2)),
1351             (VMOVLHPSrr VR128:$src1, VR128:$src2)>;
1352   def : Pat<(v4i32 (X86Movlhps VR128:$src1, VR128:$src2)),
1353             (VMOVLHPSrr VR128:$src1, VR128:$src2)>;
1354   def : Pat<(v2i64 (X86Movlhps VR128:$src1, VR128:$src2)),
1355             (VMOVLHPSrr (v2i64 VR128:$src1), VR128:$src2)>;
1356
1357   // MOVHLPS patterns
1358   let AddedComplexity = 20 in {
1359     // vector_shuffle v1, v2 <6, 7, 2, 3> using MOVHLPS
1360     def : Pat<(v4i32 (movhlps VR128:$src1, VR128:$src2)),
1361               (VMOVHLPSrr VR128:$src1, VR128:$src2)>;
1362
1363     // vector_shuffle v1, undef <2, ?, ?, ?> using MOVHLPS
1364     def : Pat<(v4f32 (movhlps_undef VR128:$src1, (undef))),
1365               (VMOVHLPSrr VR128:$src1, VR128:$src1)>;
1366     def : Pat<(v4i32 (movhlps_undef VR128:$src1, (undef))),
1367               (VMOVHLPSrr VR128:$src1, VR128:$src1)>;
1368   }
1369
1370   def : Pat<(v4f32 (X86Movhlps VR128:$src1, VR128:$src2)),
1371             (VMOVHLPSrr VR128:$src1, VR128:$src2)>;
1372   def : Pat<(v4i32 (X86Movhlps VR128:$src1, VR128:$src2)),
1373             (VMOVHLPSrr VR128:$src1, VR128:$src2)>;
1374 }
1375
1376 let Predicates = [HasSSE1] in {
1377   // MOVLHPS patterns
1378   let AddedComplexity = 20 in {
1379     def : Pat<(v4f32 (movddup VR128:$src, (undef))),
1380               (MOVLHPSrr (v4f32 VR128:$src), (v4f32 VR128:$src))>;
1381     def : Pat<(v2i64 (movddup VR128:$src, (undef))),
1382               (MOVLHPSrr (v2i64 VR128:$src), (v2i64 VR128:$src))>;
1383
1384     // vector_shuffle v1, v2 <0, 1, 4, 5> using MOVLHPS
1385     def : Pat<(v4i32 (movlhps VR128:$src1, VR128:$src2)),
1386               (MOVLHPSrr VR128:$src1, VR128:$src2)>;
1387   }
1388   def : Pat<(v4f32 (X86Movlhps VR128:$src1, VR128:$src2)),
1389             (MOVLHPSrr VR128:$src1, VR128:$src2)>;
1390   def : Pat<(v4i32 (X86Movlhps VR128:$src1, VR128:$src2)),
1391             (MOVLHPSrr VR128:$src1, VR128:$src2)>;
1392   def : Pat<(v2i64 (X86Movlhps VR128:$src1, VR128:$src2)),
1393             (MOVLHPSrr (v2i64 VR128:$src1), VR128:$src2)>;
1394
1395   // MOVHLPS patterns
1396   let AddedComplexity = 20 in {
1397     // vector_shuffle v1, v2 <6, 7, 2, 3> using MOVHLPS
1398     def : Pat<(v4i32 (movhlps VR128:$src1, VR128:$src2)),
1399               (MOVHLPSrr VR128:$src1, VR128:$src2)>;
1400
1401     // vector_shuffle v1, undef <2, ?, ?, ?> using MOVHLPS
1402     def : Pat<(v4f32 (movhlps_undef VR128:$src1, (undef))),
1403               (MOVHLPSrr VR128:$src1, VR128:$src1)>;
1404     def : Pat<(v4i32 (movhlps_undef VR128:$src1, (undef))),
1405               (MOVHLPSrr VR128:$src1, VR128:$src1)>;
1406   }
1407
1408   def : Pat<(v4f32 (X86Movhlps VR128:$src1, VR128:$src2)),
1409             (MOVHLPSrr VR128:$src1, VR128:$src2)>;
1410   def : Pat<(v4i32 (X86Movhlps VR128:$src1, VR128:$src2)),
1411             (MOVHLPSrr VR128:$src1, VR128:$src2)>;
1412 }
1413
1414 //===----------------------------------------------------------------------===//
1415 // SSE 1 & 2 - Conversion Instructions
1416 //===----------------------------------------------------------------------===//
1417
1418 multiclass sse12_cvt_s<bits<8> opc, RegisterClass SrcRC, RegisterClass DstRC,
1419                      SDNode OpNode, X86MemOperand x86memop, PatFrag ld_frag,
1420                      string asm> {
1421   def rr : SI<opc, MRMSrcReg, (outs DstRC:$dst), (ins SrcRC:$src), asm,
1422                         [(set DstRC:$dst, (OpNode SrcRC:$src))]>;
1423   def rm : SI<opc, MRMSrcMem, (outs DstRC:$dst), (ins x86memop:$src), asm,
1424                         [(set DstRC:$dst, (OpNode (ld_frag addr:$src)))]>;
1425 }
1426
1427 multiclass sse12_cvt_s_np<bits<8> opc, RegisterClass SrcRC, RegisterClass DstRC,
1428                           X86MemOperand x86memop, string asm> {
1429 let neverHasSideEffects = 1 in {
1430   def rr : SI<opc, MRMSrcReg, (outs DstRC:$dst), (ins SrcRC:$src), asm, []>;
1431   let mayLoad = 1 in
1432   def rm : SI<opc, MRMSrcMem, (outs DstRC:$dst), (ins x86memop:$src), asm, []>;
1433 } // neverHasSideEffects = 1
1434 }
1435
1436 multiclass sse12_cvt_p<bits<8> opc, RegisterClass SrcRC, RegisterClass DstRC,
1437                          SDNode OpNode, X86MemOperand x86memop, PatFrag ld_frag,
1438                          string asm, Domain d> {
1439   def rr : PI<opc, MRMSrcReg, (outs DstRC:$dst), (ins SrcRC:$src), asm,
1440                         [(set DstRC:$dst, (OpNode SrcRC:$src))], d>;
1441   def rm : PI<opc, MRMSrcMem, (outs DstRC:$dst), (ins x86memop:$src), asm,
1442                         [(set DstRC:$dst, (OpNode (ld_frag addr:$src)))], d>;
1443 }
1444
1445 multiclass sse12_vcvt_avx<bits<8> opc, RegisterClass SrcRC, RegisterClass DstRC,
1446                           X86MemOperand x86memop, string asm> {
1447 let neverHasSideEffects = 1 in {
1448   def rr : SI<opc, MRMSrcReg, (outs DstRC:$dst), (ins DstRC:$src1, SrcRC:$src),
1449               !strconcat(asm,"\t{$src, $src1, $dst|$dst, $src1, $src}"), []>;
1450   let mayLoad = 1 in
1451   def rm : SI<opc, MRMSrcMem, (outs DstRC:$dst),
1452               (ins DstRC:$src1, x86memop:$src),
1453               !strconcat(asm,"\t{$src, $src1, $dst|$dst, $src1, $src}"), []>;
1454 } // neverHasSideEffects = 1
1455 }
1456
1457 defm VCVTTSS2SI   : sse12_cvt_s<0x2C, FR32, GR32, fp_to_sint, f32mem, loadf32,
1458                                 "cvttss2si\t{$src, $dst|$dst, $src}">, XS, VEX,
1459                                 VEX_LIG;
1460 defm VCVTTSS2SI64 : sse12_cvt_s<0x2C, FR32, GR64, fp_to_sint, f32mem, loadf32,
1461                                 "cvttss2si\t{$src, $dst|$dst, $src}">, XS, VEX,
1462                                 VEX_W, VEX_LIG;
1463 defm VCVTTSD2SI   : sse12_cvt_s<0x2C, FR64, GR32, fp_to_sint, f64mem, loadf64,
1464                                 "cvttsd2si\t{$src, $dst|$dst, $src}">, XD, VEX,
1465                                 VEX_LIG;
1466 defm VCVTTSD2SI64 : sse12_cvt_s<0x2C, FR64, GR64, fp_to_sint, f64mem, loadf64,
1467                                 "cvttsd2si\t{$src, $dst|$dst, $src}">, XD,
1468                                 VEX, VEX_W, VEX_LIG;
1469
1470 // The assembler can recognize rr 64-bit instructions by seeing a rxx
1471 // register, but the same isn't true when only using memory operands,
1472 // provide other assembly "l" and "q" forms to address this explicitly
1473 // where appropriate to do so.
1474 defm VCVTSI2SS   : sse12_vcvt_avx<0x2A, GR32, FR32, i32mem, "cvtsi2ss">, XS,
1475                                   VEX_4V, VEX_LIG;
1476 defm VCVTSI2SS64 : sse12_vcvt_avx<0x2A, GR64, FR32, i64mem, "cvtsi2ss{q}">, XS,
1477                                   VEX_4V, VEX_W, VEX_LIG;
1478 defm VCVTSI2SD   : sse12_vcvt_avx<0x2A, GR32, FR64, i32mem, "cvtsi2sd">, XD,
1479                                   VEX_4V, VEX_LIG;
1480 defm VCVTSI2SDL  : sse12_vcvt_avx<0x2A, GR32, FR64, i32mem, "cvtsi2sd{l}">, XD,
1481                                   VEX_4V, VEX_LIG;
1482 defm VCVTSI2SD64 : sse12_vcvt_avx<0x2A, GR64, FR64, i64mem, "cvtsi2sd{q}">, XD,
1483                                   VEX_4V, VEX_W, VEX_LIG;
1484
1485 let Predicates = [HasAVX], AddedComplexity = 1 in {
1486   def : Pat<(f32 (sint_to_fp (loadi32 addr:$src))),
1487             (VCVTSI2SSrm (f32 (IMPLICIT_DEF)), addr:$src)>;
1488   def : Pat<(f32 (sint_to_fp (loadi64 addr:$src))),
1489             (VCVTSI2SS64rm (f32 (IMPLICIT_DEF)), addr:$src)>;
1490   def : Pat<(f64 (sint_to_fp (loadi32 addr:$src))),
1491             (VCVTSI2SDrm (f64 (IMPLICIT_DEF)), addr:$src)>;
1492   def : Pat<(f64 (sint_to_fp (loadi64 addr:$src))),
1493             (VCVTSI2SD64rm (f64 (IMPLICIT_DEF)), addr:$src)>;
1494
1495   def : Pat<(f32 (sint_to_fp GR32:$src)),
1496             (VCVTSI2SSrr (f32 (IMPLICIT_DEF)), GR32:$src)>;
1497   def : Pat<(f32 (sint_to_fp GR64:$src)),
1498             (VCVTSI2SS64rr (f32 (IMPLICIT_DEF)), GR64:$src)>;
1499   def : Pat<(f64 (sint_to_fp GR32:$src)),
1500             (VCVTSI2SDrr (f64 (IMPLICIT_DEF)), GR32:$src)>;
1501   def : Pat<(f64 (sint_to_fp GR64:$src)),
1502             (VCVTSI2SD64rr (f64 (IMPLICIT_DEF)), GR64:$src)>;
1503 }
1504
1505 defm CVTTSS2SI : sse12_cvt_s<0x2C, FR32, GR32, fp_to_sint, f32mem, loadf32,
1506                       "cvttss2si\t{$src, $dst|$dst, $src}">, XS;
1507 defm CVTTSS2SI64 : sse12_cvt_s<0x2C, FR32, GR64, fp_to_sint, f32mem, loadf32,
1508                       "cvttss2si{q}\t{$src, $dst|$dst, $src}">, XS, REX_W;
1509 defm CVTTSD2SI : sse12_cvt_s<0x2C, FR64, GR32, fp_to_sint, f64mem, loadf64,
1510                       "cvttsd2si\t{$src, $dst|$dst, $src}">, XD;
1511 defm CVTTSD2SI64 : sse12_cvt_s<0x2C, FR64, GR64, fp_to_sint, f64mem, loadf64,
1512                       "cvttsd2si{q}\t{$src, $dst|$dst, $src}">, XD, REX_W;
1513 defm CVTSI2SS  : sse12_cvt_s<0x2A, GR32, FR32, sint_to_fp, i32mem, loadi32,
1514                       "cvtsi2ss\t{$src, $dst|$dst, $src}">, XS;
1515 defm CVTSI2SS64 : sse12_cvt_s<0x2A, GR64, FR32, sint_to_fp, i64mem, loadi64,
1516                       "cvtsi2ss{q}\t{$src, $dst|$dst, $src}">, XS, REX_W;
1517 defm CVTSI2SD  : sse12_cvt_s<0x2A, GR32, FR64, sint_to_fp, i32mem, loadi32,
1518                       "cvtsi2sd\t{$src, $dst|$dst, $src}">, XD;
1519 defm CVTSI2SD64 : sse12_cvt_s<0x2A, GR64, FR64, sint_to_fp, i64mem, loadi64,
1520                       "cvtsi2sd{q}\t{$src, $dst|$dst, $src}">, XD, REX_W;
1521
1522 // Conversion Instructions Intrinsics - Match intrinsics which expect MM
1523 // and/or XMM operand(s).
1524
1525 multiclass sse12_cvt_sint<bits<8> opc, RegisterClass SrcRC, RegisterClass DstRC,
1526                          Intrinsic Int, X86MemOperand x86memop, PatFrag ld_frag,
1527                          string asm> {
1528   def rr : SI<opc, MRMSrcReg, (outs DstRC:$dst), (ins SrcRC:$src),
1529               !strconcat(asm, "\t{$src, $dst|$dst, $src}"),
1530               [(set DstRC:$dst, (Int SrcRC:$src))]>;
1531   def rm : SI<opc, MRMSrcMem, (outs DstRC:$dst), (ins x86memop:$src),
1532               !strconcat(asm, "\t{$src, $dst|$dst, $src}"),
1533               [(set DstRC:$dst, (Int (ld_frag addr:$src)))]>;
1534 }
1535
1536 multiclass sse12_cvt_sint_3addr<bits<8> opc, RegisterClass SrcRC,
1537                     RegisterClass DstRC, Intrinsic Int, X86MemOperand x86memop,
1538                     PatFrag ld_frag, string asm, bit Is2Addr = 1> {
1539   def rr : SI<opc, MRMSrcReg, (outs DstRC:$dst), (ins DstRC:$src1, SrcRC:$src2),
1540               !if(Is2Addr,
1541                   !strconcat(asm, "\t{$src2, $dst|$dst, $src2}"),
1542                   !strconcat(asm, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
1543               [(set DstRC:$dst, (Int DstRC:$src1, SrcRC:$src2))]>;
1544   def rm : SI<opc, MRMSrcMem, (outs DstRC:$dst),
1545               (ins DstRC:$src1, x86memop:$src2),
1546               !if(Is2Addr,
1547                   !strconcat(asm, "\t{$src2, $dst|$dst, $src2}"),
1548                   !strconcat(asm, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
1549               [(set DstRC:$dst, (Int DstRC:$src1, (ld_frag addr:$src2)))]>;
1550 }
1551
1552 defm Int_VCVTSD2SI : sse12_cvt_sint<0x2D, VR128, GR32, int_x86_sse2_cvtsd2si,
1553                       f128mem, load, "cvtsd2si">, XD, VEX;
1554 defm Int_VCVTSD2SI64 : sse12_cvt_sint<0x2D, VR128, GR64,
1555                       int_x86_sse2_cvtsd2si64, f128mem, load, "cvtsd2si">,
1556                       XD, VEX, VEX_W;
1557
1558 // FIXME: The asm matcher has a hack to ignore instructions with _Int and Int_
1559 // Get rid of this hack or rename the intrinsics, there are several
1560 // intructions that only match with the intrinsic form, why create duplicates
1561 // to let them be recognized by the assembler?
1562 defm VCVTSD2SI     : sse12_cvt_s_np<0x2D, FR64, GR32, f64mem,
1563                       "cvtsd2si\t{$src, $dst|$dst, $src}">, XD, VEX, VEX_LIG;
1564 defm VCVTSD2SI64   : sse12_cvt_s_np<0x2D, FR64, GR64, f64mem,
1565                       "cvtsd2si\t{$src, $dst|$dst, $src}">, XD, VEX, VEX_W,
1566                       VEX_LIG;
1567
1568 defm CVTSD2SI : sse12_cvt_sint<0x2D, VR128, GR32, int_x86_sse2_cvtsd2si,
1569                 f128mem, load, "cvtsd2si{l}">, XD;
1570 defm CVTSD2SI64 : sse12_cvt_sint<0x2D, VR128, GR64, int_x86_sse2_cvtsd2si64,
1571                   f128mem, load, "cvtsd2si{q}">, XD, REX_W;
1572
1573
1574 defm Int_VCVTSI2SS : sse12_cvt_sint_3addr<0x2A, GR32, VR128,
1575           int_x86_sse_cvtsi2ss, i32mem, loadi32, "cvtsi2ss", 0>, XS, VEX_4V;
1576 defm Int_VCVTSI2SS64 : sse12_cvt_sint_3addr<0x2A, GR64, VR128,
1577           int_x86_sse_cvtsi642ss, i64mem, loadi64, "cvtsi2ss", 0>, XS, VEX_4V,
1578           VEX_W;
1579 defm Int_VCVTSI2SD : sse12_cvt_sint_3addr<0x2A, GR32, VR128,
1580           int_x86_sse2_cvtsi2sd, i32mem, loadi32, "cvtsi2sd", 0>, XD, VEX_4V;
1581 defm Int_VCVTSI2SD64 : sse12_cvt_sint_3addr<0x2A, GR64, VR128,
1582           int_x86_sse2_cvtsi642sd, i64mem, loadi64, "cvtsi2sd", 0>, XD,
1583           VEX_4V, VEX_W;
1584
1585 let Constraints = "$src1 = $dst" in {
1586   defm Int_CVTSI2SS : sse12_cvt_sint_3addr<0x2A, GR32, VR128,
1587                         int_x86_sse_cvtsi2ss, i32mem, loadi32,
1588                         "cvtsi2ss">, XS;
1589   defm Int_CVTSI2SS64 : sse12_cvt_sint_3addr<0x2A, GR64, VR128,
1590                         int_x86_sse_cvtsi642ss, i64mem, loadi64,
1591                         "cvtsi2ss{q}">, XS, REX_W;
1592   defm Int_CVTSI2SD : sse12_cvt_sint_3addr<0x2A, GR32, VR128,
1593                         int_x86_sse2_cvtsi2sd, i32mem, loadi32,
1594                         "cvtsi2sd">, XD;
1595   defm Int_CVTSI2SD64 : sse12_cvt_sint_3addr<0x2A, GR64, VR128,
1596                         int_x86_sse2_cvtsi642sd, i64mem, loadi64,
1597                         "cvtsi2sd">, XD, REX_W;
1598 }
1599
1600 /// SSE 1 Only
1601
1602 // Aliases for intrinsics
1603 defm Int_VCVTTSS2SI : sse12_cvt_sint<0x2C, VR128, GR32, int_x86_sse_cvttss2si,
1604                                     f32mem, load, "cvttss2si">, XS, VEX;
1605 defm Int_VCVTTSS2SI64 : sse12_cvt_sint<0x2C, VR128, GR64,
1606                                     int_x86_sse_cvttss2si64, f32mem, load,
1607                                     "cvttss2si">, XS, VEX, VEX_W;
1608 defm Int_VCVTTSD2SI : sse12_cvt_sint<0x2C, VR128, GR32, int_x86_sse2_cvttsd2si,
1609                                     f128mem, load, "cvttsd2si">, XD, VEX;
1610 defm Int_VCVTTSD2SI64 : sse12_cvt_sint<0x2C, VR128, GR64,
1611                                     int_x86_sse2_cvttsd2si64, f128mem, load,
1612                                     "cvttsd2si">, XD, VEX, VEX_W;
1613 defm Int_CVTTSS2SI : sse12_cvt_sint<0x2C, VR128, GR32, int_x86_sse_cvttss2si,
1614                                     f32mem, load, "cvttss2si">, XS;
1615 defm Int_CVTTSS2SI64 : sse12_cvt_sint<0x2C, VR128, GR64,
1616                                     int_x86_sse_cvttss2si64, f32mem, load,
1617                                     "cvttss2si{q}">, XS, REX_W;
1618 defm Int_CVTTSD2SI : sse12_cvt_sint<0x2C, VR128, GR32, int_x86_sse2_cvttsd2si,
1619                                     f128mem, load, "cvttsd2si">, XD;
1620 defm Int_CVTTSD2SI64 : sse12_cvt_sint<0x2C, VR128, GR64,
1621                                     int_x86_sse2_cvttsd2si64, f128mem, load,
1622                                     "cvttsd2si{q}">, XD, REX_W;
1623
1624 let Pattern = []<dag> in {
1625 defm VCVTSS2SI   : sse12_cvt_s<0x2D, FR32, GR32, undef, f32mem, load,
1626                                "cvtss2si{l}\t{$src, $dst|$dst, $src}">, XS,
1627                                VEX, VEX_LIG;
1628 defm VCVTSS2SI64 : sse12_cvt_s<0x2D, FR32, GR64, undef, f32mem, load,
1629                                "cvtss2si\t{$src, $dst|$dst, $src}">, XS, VEX,
1630                                VEX_W, VEX_LIG;
1631 defm VCVTDQ2PS   : sse12_cvt_p<0x5B, VR128, VR128, undef, i128mem, load,
1632                                "cvtdq2ps\t{$src, $dst|$dst, $src}",
1633                                SSEPackedSingle>, TB, VEX;
1634 defm VCVTDQ2PSY  : sse12_cvt_p<0x5B, VR256, VR256, undef, i256mem, load,
1635                                "cvtdq2ps\t{$src, $dst|$dst, $src}",
1636                                SSEPackedSingle>, TB, VEX;
1637 }
1638
1639 let Pattern = []<dag> in {
1640 defm CVTSS2SI : sse12_cvt_s<0x2D, FR32, GR32, undef, f32mem, load /*dummy*/,
1641                           "cvtss2si{l}\t{$src, $dst|$dst, $src}">, XS;
1642 defm CVTSS2SI64 : sse12_cvt_s<0x2D, FR32, GR64, undef, f32mem, load /*dummy*/,
1643                           "cvtss2si{q}\t{$src, $dst|$dst, $src}">, XS, REX_W;
1644 defm CVTDQ2PS : sse12_cvt_p<0x5B, VR128, VR128, undef, i128mem, load /*dummy*/,
1645                             "cvtdq2ps\t{$src, $dst|$dst, $src}",
1646                             SSEPackedSingle>, TB; /* PD SSE3 form is avaiable */
1647 }
1648
1649 let Predicates = [HasAVX] in {
1650   def : Pat<(int_x86_sse_cvtss2si VR128:$src),
1651             (VCVTSS2SIrr (EXTRACT_SUBREG (v4f32 VR128:$src), sub_ss))>;
1652   def : Pat<(int_x86_sse_cvtss2si (load addr:$src)),
1653             (VCVTSS2SIrm addr:$src)>;
1654   def : Pat<(int_x86_sse_cvtss2si64 VR128:$src),
1655             (VCVTSS2SI64rr (EXTRACT_SUBREG (v4f32 VR128:$src), sub_ss))>;
1656   def : Pat<(int_x86_sse_cvtss2si64 (load addr:$src)),
1657             (VCVTSS2SI64rm addr:$src)>;
1658 }
1659
1660 let Predicates = [HasSSE1] in {
1661   def : Pat<(int_x86_sse_cvtss2si VR128:$src),
1662             (CVTSS2SIrr (EXTRACT_SUBREG (v4f32 VR128:$src), sub_ss))>;
1663   def : Pat<(int_x86_sse_cvtss2si (load addr:$src)),
1664             (CVTSS2SIrm addr:$src)>;
1665   def : Pat<(int_x86_sse_cvtss2si64 VR128:$src),
1666             (CVTSS2SI64rr (EXTRACT_SUBREG (v4f32 VR128:$src), sub_ss))>;
1667   def : Pat<(int_x86_sse_cvtss2si64 (load addr:$src)),
1668             (CVTSS2SI64rm addr:$src)>;
1669 }
1670
1671 /// SSE 2 Only
1672
1673 // Convert scalar double to scalar single
1674 def VCVTSD2SSrr  : VSDI<0x5A, MRMSrcReg, (outs FR32:$dst),
1675                        (ins FR64:$src1, FR64:$src2),
1676                       "cvtsd2ss\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>,
1677                       VEX_4V, VEX_LIG;
1678 let mayLoad = 1 in
1679 def VCVTSD2SSrm  : I<0x5A, MRMSrcMem, (outs FR32:$dst),
1680                        (ins FR64:$src1, f64mem:$src2),
1681                       "vcvtsd2ss\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1682                       []>, XD, Requires<[HasAVX, OptForSize]>, VEX_4V, VEX_LIG;
1683
1684 def : Pat<(f32 (fround FR64:$src)), (VCVTSD2SSrr FR64:$src, FR64:$src)>,
1685           Requires<[HasAVX]>;
1686
1687 def CVTSD2SSrr  : SDI<0x5A, MRMSrcReg, (outs FR32:$dst), (ins FR64:$src),
1688                       "cvtsd2ss\t{$src, $dst|$dst, $src}",
1689                       [(set FR32:$dst, (fround FR64:$src))]>;
1690 def CVTSD2SSrm  : I<0x5A, MRMSrcMem, (outs FR32:$dst), (ins f64mem:$src),
1691                       "cvtsd2ss\t{$src, $dst|$dst, $src}",
1692                       [(set FR32:$dst, (fround (loadf64 addr:$src)))]>, XD,
1693                   Requires<[HasSSE2, OptForSize]>;
1694
1695 defm Int_VCVTSD2SS: sse12_cvt_sint_3addr<0x5A, VR128, VR128,
1696                       int_x86_sse2_cvtsd2ss, f64mem, load, "cvtsd2ss", 0>,
1697                       XS, VEX_4V;
1698 let Constraints = "$src1 = $dst" in
1699 defm Int_CVTSD2SS: sse12_cvt_sint_3addr<0x5A, VR128, VR128,
1700                       int_x86_sse2_cvtsd2ss, f64mem, load, "cvtsd2ss">, XS;
1701
1702 // Convert scalar single to scalar double
1703 // SSE2 instructions with XS prefix
1704 def VCVTSS2SDrr : I<0x5A, MRMSrcReg, (outs FR64:$dst),
1705                     (ins FR32:$src1, FR32:$src2),
1706                     "vcvtss2sd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1707                     []>, XS, Requires<[HasAVX]>, VEX_4V, VEX_LIG;
1708 let mayLoad = 1 in
1709 def VCVTSS2SDrm : I<0x5A, MRMSrcMem, (outs FR64:$dst),
1710                     (ins FR32:$src1, f32mem:$src2),
1711                     "vcvtss2sd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1712                     []>, XS, VEX_4V, VEX_LIG, Requires<[HasAVX, OptForSize]>;
1713
1714 let Predicates = [HasAVX] in {
1715   def : Pat<(f64 (fextend FR32:$src)),
1716             (VCVTSS2SDrr FR32:$src, FR32:$src)>;
1717   def : Pat<(fextend (loadf32 addr:$src)),
1718             (VCVTSS2SDrm (f32 (IMPLICIT_DEF)), addr:$src)>;
1719   def : Pat<(extloadf32 addr:$src),
1720             (VCVTSS2SDrm (f32 (IMPLICIT_DEF)), addr:$src)>;
1721 }
1722
1723 def : Pat<(extloadf32 addr:$src),
1724           (VCVTSS2SDrr (f32 (IMPLICIT_DEF)), (MOVSSrm addr:$src))>,
1725           Requires<[HasAVX, OptForSpeed]>;
1726
1727 def CVTSS2SDrr : I<0x5A, MRMSrcReg, (outs FR64:$dst), (ins FR32:$src),
1728                    "cvtss2sd\t{$src, $dst|$dst, $src}",
1729                    [(set FR64:$dst, (fextend FR32:$src))]>, XS,
1730                  Requires<[HasSSE2]>;
1731 def CVTSS2SDrm : I<0x5A, MRMSrcMem, (outs FR64:$dst), (ins f32mem:$src),
1732                    "cvtss2sd\t{$src, $dst|$dst, $src}",
1733                    [(set FR64:$dst, (extloadf32 addr:$src))]>, XS,
1734                  Requires<[HasSSE2, OptForSize]>;
1735
1736 // extload f32 -> f64.  This matches load+fextend because we have a hack in
1737 // the isel (PreprocessForFPConvert) that can introduce loads after dag
1738 // combine.
1739 // Since these loads aren't folded into the fextend, we have to match it
1740 // explicitly here.
1741 def : Pat<(fextend (loadf32 addr:$src)),
1742           (CVTSS2SDrm addr:$src)>, Requires<[HasSSE2]>;
1743 def : Pat<(extloadf32 addr:$src),
1744           (CVTSS2SDrr (MOVSSrm addr:$src))>, Requires<[HasSSE2, OptForSpeed]>;
1745
1746 def Int_VCVTSS2SDrr: I<0x5A, MRMSrcReg,
1747                       (outs VR128:$dst), (ins VR128:$src1, VR128:$src2),
1748                     "vcvtss2sd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1749                     [(set VR128:$dst, (int_x86_sse2_cvtss2sd VR128:$src1,
1750                                        VR128:$src2))]>, XS, VEX_4V,
1751                     Requires<[HasAVX]>;
1752 def Int_VCVTSS2SDrm: I<0x5A, MRMSrcMem,
1753                       (outs VR128:$dst), (ins VR128:$src1, f32mem:$src2),
1754                     "vcvtss2sd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1755                     [(set VR128:$dst, (int_x86_sse2_cvtss2sd VR128:$src1,
1756                                        (load addr:$src2)))]>, XS, VEX_4V,
1757                     Requires<[HasAVX]>;
1758 let Constraints = "$src1 = $dst" in { // SSE2 instructions with XS prefix
1759 def Int_CVTSS2SDrr: I<0x5A, MRMSrcReg,
1760                       (outs VR128:$dst), (ins VR128:$src1, VR128:$src2),
1761                     "cvtss2sd\t{$src2, $dst|$dst, $src2}",
1762                     [(set VR128:$dst, (int_x86_sse2_cvtss2sd VR128:$src1,
1763                                        VR128:$src2))]>, XS,
1764                     Requires<[HasSSE2]>;
1765 def Int_CVTSS2SDrm: I<0x5A, MRMSrcMem,
1766                       (outs VR128:$dst), (ins VR128:$src1, f32mem:$src2),
1767                     "cvtss2sd\t{$src2, $dst|$dst, $src2}",
1768                     [(set VR128:$dst, (int_x86_sse2_cvtss2sd VR128:$src1,
1769                                        (load addr:$src2)))]>, XS,
1770                     Requires<[HasSSE2]>;
1771 }
1772
1773 // Convert doubleword to packed single/double fp
1774 // SSE2 instructions without OpSize prefix
1775 def Int_VCVTDQ2PSrr : I<0x5B, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1776                        "vcvtdq2ps\t{$src, $dst|$dst, $src}",
1777                        [(set VR128:$dst, (int_x86_sse2_cvtdq2ps VR128:$src))]>,
1778                      TB, VEX, Requires<[HasAVX]>;
1779 def Int_VCVTDQ2PSrm : I<0x5B, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
1780                       "vcvtdq2ps\t{$src, $dst|$dst, $src}",
1781                       [(set VR128:$dst, (int_x86_sse2_cvtdq2ps
1782                                         (bitconvert (memopv2i64 addr:$src))))]>,
1783                      TB, VEX, Requires<[HasAVX]>;
1784 def Int_CVTDQ2PSrr : I<0x5B, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1785                        "cvtdq2ps\t{$src, $dst|$dst, $src}",
1786                        [(set VR128:$dst, (int_x86_sse2_cvtdq2ps VR128:$src))]>,
1787                      TB, Requires<[HasSSE2]>;
1788 def Int_CVTDQ2PSrm : I<0x5B, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
1789                       "cvtdq2ps\t{$src, $dst|$dst, $src}",
1790                       [(set VR128:$dst, (int_x86_sse2_cvtdq2ps
1791                                         (bitconvert (memopv2i64 addr:$src))))]>,
1792                      TB, Requires<[HasSSE2]>;
1793
1794 // FIXME: why the non-intrinsic version is described as SSE3?
1795 // SSE2 instructions with XS prefix
1796 def Int_VCVTDQ2PDrr : I<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1797                        "vcvtdq2pd\t{$src, $dst|$dst, $src}",
1798                        [(set VR128:$dst, (int_x86_sse2_cvtdq2pd VR128:$src))]>,
1799                      XS, VEX, Requires<[HasAVX]>;
1800 def Int_VCVTDQ2PDrm : I<0xE6, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
1801                        "vcvtdq2pd\t{$src, $dst|$dst, $src}",
1802                        [(set VR128:$dst, (int_x86_sse2_cvtdq2pd
1803                                         (bitconvert (memopv2i64 addr:$src))))]>,
1804                      XS, VEX, Requires<[HasAVX]>;
1805 def Int_CVTDQ2PDrr : I<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1806                        "cvtdq2pd\t{$src, $dst|$dst, $src}",
1807                        [(set VR128:$dst, (int_x86_sse2_cvtdq2pd VR128:$src))]>,
1808                      XS, Requires<[HasSSE2]>;
1809 def Int_CVTDQ2PDrm : I<0xE6, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
1810                      "cvtdq2pd\t{$src, $dst|$dst, $src}",
1811                      [(set VR128:$dst, (int_x86_sse2_cvtdq2pd
1812                                         (bitconvert (memopv2i64 addr:$src))))]>,
1813                      XS, Requires<[HasSSE2]>;
1814
1815
1816 // Convert packed single/double fp to doubleword
1817 def VCVTPS2DQrr : VPDI<0x5B, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1818                        "cvtps2dq\t{$src, $dst|$dst, $src}", []>, VEX;
1819 def VCVTPS2DQrm : VPDI<0x5B, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1820                        "cvtps2dq\t{$src, $dst|$dst, $src}", []>, VEX;
1821 def VCVTPS2DQYrr : VPDI<0x5B, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
1822                         "cvtps2dq\t{$src, $dst|$dst, $src}", []>, VEX;
1823 def VCVTPS2DQYrm : VPDI<0x5B, MRMSrcMem, (outs VR256:$dst), (ins f256mem:$src),
1824                         "cvtps2dq\t{$src, $dst|$dst, $src}", []>, VEX;
1825 def CVTPS2DQrr : PDI<0x5B, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1826                      "cvtps2dq\t{$src, $dst|$dst, $src}", []>;
1827 def CVTPS2DQrm : PDI<0x5B, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1828                      "cvtps2dq\t{$src, $dst|$dst, $src}", []>;
1829
1830 def Int_VCVTPS2DQrr : VPDI<0x5B, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1831                         "cvtps2dq\t{$src, $dst|$dst, $src}",
1832                         [(set VR128:$dst, (int_x86_sse2_cvtps2dq VR128:$src))]>,
1833                         VEX;
1834 def Int_VCVTPS2DQrm : VPDI<0x5B, MRMSrcMem, (outs VR128:$dst),
1835                          (ins f128mem:$src),
1836                          "cvtps2dq\t{$src, $dst|$dst, $src}",
1837                          [(set VR128:$dst, (int_x86_sse2_cvtps2dq
1838                                             (memop addr:$src)))]>, VEX;
1839 def Int_CVTPS2DQrr : PDI<0x5B, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1840                         "cvtps2dq\t{$src, $dst|$dst, $src}",
1841                         [(set VR128:$dst, (int_x86_sse2_cvtps2dq VR128:$src))]>;
1842 def Int_CVTPS2DQrm : PDI<0x5B, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1843                          "cvtps2dq\t{$src, $dst|$dst, $src}",
1844                          [(set VR128:$dst, (int_x86_sse2_cvtps2dq
1845                                             (memop addr:$src)))]>;
1846
1847 // SSE2 packed instructions with XD prefix
1848 def Int_VCVTPD2DQrr : I<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1849                        "vcvtpd2dq\t{$src, $dst|$dst, $src}",
1850                        [(set VR128:$dst, (int_x86_sse2_cvtpd2dq VR128:$src))]>,
1851                      XD, VEX, Requires<[HasAVX]>;
1852 def Int_VCVTPD2DQrm : I<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1853                        "vcvtpd2dq\t{$src, $dst|$dst, $src}",
1854                        [(set VR128:$dst, (int_x86_sse2_cvtpd2dq
1855                                           (memop addr:$src)))]>,
1856                      XD, VEX, Requires<[HasAVX]>;
1857 def Int_CVTPD2DQrr : I<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1858                        "cvtpd2dq\t{$src, $dst|$dst, $src}",
1859                        [(set VR128:$dst, (int_x86_sse2_cvtpd2dq VR128:$src))]>,
1860                      XD, Requires<[HasSSE2]>;
1861 def Int_CVTPD2DQrm : I<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1862                        "cvtpd2dq\t{$src, $dst|$dst, $src}",
1863                        [(set VR128:$dst, (int_x86_sse2_cvtpd2dq
1864                                           (memop addr:$src)))]>,
1865                      XD, Requires<[HasSSE2]>;
1866
1867
1868 // Convert with truncation packed single/double fp to doubleword
1869 // SSE2 packed instructions with XS prefix
1870 let neverHasSideEffects = 1 in {
1871 def VCVTTPS2DQrr : VSSI<0x5B, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1872                       "cvttps2dq\t{$src, $dst|$dst, $src}", []>, VEX;
1873 let mayLoad = 1 in
1874 def VCVTTPS2DQrm : VSSI<0x5B, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1875                       "cvttps2dq\t{$src, $dst|$dst, $src}", []>, VEX;
1876 def VCVTTPS2DQYrr : VSSI<0x5B, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
1877                       "cvttps2dq\t{$src, $dst|$dst, $src}", []>, VEX;
1878 let mayLoad = 1 in
1879 def VCVTTPS2DQYrm : VSSI<0x5B, MRMSrcMem, (outs VR256:$dst), (ins f256mem:$src),
1880                       "cvttps2dq\t{$src, $dst|$dst, $src}", []>, VEX;
1881 } // neverHasSideEffects = 1
1882
1883 def Int_VCVTTPS2DQrr : I<0x5B, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1884                         "vcvttps2dq\t{$src, $dst|$dst, $src}",
1885                         [(set VR128:$dst,
1886                               (int_x86_sse2_cvttps2dq VR128:$src))]>,
1887                       XS, VEX, Requires<[HasAVX]>;
1888 def Int_VCVTTPS2DQrm : I<0x5B, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1889                         "vcvttps2dq\t{$src, $dst|$dst, $src}",
1890                         [(set VR128:$dst, (int_x86_sse2_cvttps2dq
1891                                            (memop addr:$src)))]>,
1892                       XS, VEX, Requires<[HasAVX]>;
1893
1894 def CVTTPS2DQrr : SSI<0x5B, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1895                       "cvttps2dq\t{$src, $dst|$dst, $src}",
1896                       [(set VR128:$dst,
1897                             (int_x86_sse2_cvttps2dq VR128:$src))]>;
1898 def CVTTPS2DQrm : SSI<0x5B, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1899                       "cvttps2dq\t{$src, $dst|$dst, $src}",
1900                       [(set VR128:$dst,
1901                             (int_x86_sse2_cvttps2dq (memop addr:$src)))]>;
1902
1903 let Predicates = [HasAVX] in {
1904   def : Pat<(v4f32 (sint_to_fp (v4i32 VR128:$src))),
1905             (Int_VCVTDQ2PSrr VR128:$src)>;
1906   def : Pat<(v4i32 (fp_to_sint (v4f32 VR128:$src))),
1907             (VCVTTPS2DQrr VR128:$src)>;
1908   def : Pat<(v8f32 (sint_to_fp (v8i32 VR256:$src))),
1909             (VCVTDQ2PSYrr VR256:$src)>;
1910   def : Pat<(v8i32 (fp_to_sint (v8f32 VR256:$src))),
1911             (VCVTTPS2DQYrr VR256:$src)>;
1912 }
1913
1914 let Predicates = [HasSSE2] in {
1915   def : Pat<(v4f32 (sint_to_fp (v4i32 VR128:$src))),
1916             (Int_CVTDQ2PSrr VR128:$src)>;
1917   def : Pat<(v4i32 (fp_to_sint (v4f32 VR128:$src))),
1918             (CVTTPS2DQrr VR128:$src)>;
1919 }
1920
1921 def VCVTTPD2DQrr : VPDI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1922                         "cvttpd2dq\t{$src, $dst|$dst, $src}",
1923                         [(set VR128:$dst,
1924                               (int_x86_sse2_cvttpd2dq VR128:$src))]>, VEX;
1925 let isCodeGenOnly = 1 in
1926 def VCVTTPD2DQrm : VPDI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1927                         "cvttpd2dq\t{$src, $dst|$dst, $src}",
1928                         [(set VR128:$dst, (int_x86_sse2_cvttpd2dq
1929                                                (memop addr:$src)))]>, VEX;
1930 def CVTTPD2DQrr : PDI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1931                       "cvttpd2dq\t{$src, $dst|$dst, $src}",
1932                       [(set VR128:$dst, (int_x86_sse2_cvttpd2dq VR128:$src))]>;
1933 def CVTTPD2DQrm : PDI<0xE6, MRMSrcMem, (outs VR128:$dst),(ins f128mem:$src),
1934                       "cvttpd2dq\t{$src, $dst|$dst, $src}",
1935                       [(set VR128:$dst, (int_x86_sse2_cvttpd2dq
1936                                         (memop addr:$src)))]>;
1937
1938 // The assembler can recognize rr 256-bit instructions by seeing a ymm
1939 // register, but the same isn't true when using memory operands instead.
1940 // Provide other assembly rr and rm forms to address this explicitly.
1941 def VCVTTPD2DQXrYr : VPDI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR256:$src),
1942                           "cvttpd2dq\t{$src, $dst|$dst, $src}", []>, VEX;
1943
1944 // XMM only
1945 def VCVTTPD2DQXrr : VPDI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1946                          "cvttpd2dqx\t{$src, $dst|$dst, $src}", []>, VEX;
1947 def VCVTTPD2DQXrm : VPDI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1948                          "cvttpd2dqx\t{$src, $dst|$dst, $src}", []>, VEX;
1949
1950 // YMM only
1951 def VCVTTPD2DQYrr : VPDI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR256:$src),
1952                          "cvttpd2dqy\t{$src, $dst|$dst, $src}", []>, VEX;
1953 def VCVTTPD2DQYrm : VPDI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f256mem:$src),
1954                          "cvttpd2dqy\t{$src, $dst|$dst, $src}", []>, VEX, VEX_L;
1955
1956 // Convert packed single to packed double
1957 let Predicates = [HasAVX] in {
1958                   // SSE2 instructions without OpSize prefix
1959 def VCVTPS2PDrr : I<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1960                      "vcvtps2pd\t{$src, $dst|$dst, $src}", []>, TB, VEX;
1961 def VCVTPS2PDrm : I<0x5A, MRMSrcMem, (outs VR128:$dst), (ins f64mem:$src),
1962                      "vcvtps2pd\t{$src, $dst|$dst, $src}", []>, TB, VEX;
1963 def VCVTPS2PDYrr : I<0x5A, MRMSrcReg, (outs VR256:$dst), (ins VR128:$src),
1964                      "vcvtps2pd\t{$src, $dst|$dst, $src}", []>, TB, VEX;
1965 def VCVTPS2PDYrm : I<0x5A, MRMSrcMem, (outs VR256:$dst), (ins f128mem:$src),
1966                      "vcvtps2pd\t{$src, $dst|$dst, $src}", []>, TB, VEX;
1967 }
1968 def CVTPS2PDrr : I<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1969                        "cvtps2pd\t{$src, $dst|$dst, $src}", []>, TB;
1970 def CVTPS2PDrm : I<0x5A, MRMSrcMem, (outs VR128:$dst), (ins f64mem:$src),
1971                        "cvtps2pd\t{$src, $dst|$dst, $src}", []>, TB;
1972
1973 def Int_VCVTPS2PDrr : I<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1974                        "vcvtps2pd\t{$src, $dst|$dst, $src}",
1975                        [(set VR128:$dst, (int_x86_sse2_cvtps2pd VR128:$src))]>,
1976                      TB, VEX, Requires<[HasAVX]>;
1977 def Int_VCVTPS2PDrm : I<0x5A, MRMSrcMem, (outs VR128:$dst), (ins f64mem:$src),
1978                        "vcvtps2pd\t{$src, $dst|$dst, $src}",
1979                        [(set VR128:$dst, (int_x86_sse2_cvtps2pd
1980                                           (load addr:$src)))]>,
1981                      TB, VEX, Requires<[HasAVX]>;
1982 def Int_CVTPS2PDrr : I<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1983                        "cvtps2pd\t{$src, $dst|$dst, $src}",
1984                        [(set VR128:$dst, (int_x86_sse2_cvtps2pd VR128:$src))]>,
1985                      TB, Requires<[HasSSE2]>;
1986 def Int_CVTPS2PDrm : I<0x5A, MRMSrcMem, (outs VR128:$dst), (ins f64mem:$src),
1987                        "cvtps2pd\t{$src, $dst|$dst, $src}",
1988                        [(set VR128:$dst, (int_x86_sse2_cvtps2pd
1989                                           (load addr:$src)))]>,
1990                      TB, Requires<[HasSSE2]>;
1991
1992 // Convert packed double to packed single
1993 // The assembler can recognize rr 256-bit instructions by seeing a ymm
1994 // register, but the same isn't true when using memory operands instead.
1995 // Provide other assembly rr and rm forms to address this explicitly.
1996 def VCVTPD2PSrr : VPDI<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1997                        "cvtpd2ps\t{$src, $dst|$dst, $src}", []>, VEX;
1998 def VCVTPD2PSXrYr : VPDI<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR256:$src),
1999                          "cvtpd2ps\t{$src, $dst|$dst, $src}", []>, VEX;
2000
2001 // XMM only
2002 def VCVTPD2PSXrr : VPDI<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2003                         "cvtpd2psx\t{$src, $dst|$dst, $src}", []>, VEX;
2004 def VCVTPD2PSXrm : VPDI<0x5A, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
2005                         "cvtpd2psx\t{$src, $dst|$dst, $src}", []>, VEX;
2006
2007 // YMM only
2008 def VCVTPD2PSYrr : VPDI<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR256:$src),
2009                         "cvtpd2psy\t{$src, $dst|$dst, $src}", []>, VEX;
2010 def VCVTPD2PSYrm : VPDI<0x5A, MRMSrcMem, (outs VR128:$dst), (ins f256mem:$src),
2011                         "cvtpd2psy\t{$src, $dst|$dst, $src}", []>, VEX, VEX_L;
2012 def CVTPD2PSrr : PDI<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2013                      "cvtpd2ps\t{$src, $dst|$dst, $src}", []>;
2014 def CVTPD2PSrm : PDI<0x5A, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
2015                      "cvtpd2ps\t{$src, $dst|$dst, $src}", []>;
2016
2017
2018 def Int_VCVTPD2PSrr : VPDI<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2019                          "cvtpd2ps\t{$src, $dst|$dst, $src}",
2020                         [(set VR128:$dst, (int_x86_sse2_cvtpd2ps VR128:$src))]>;
2021 def Int_VCVTPD2PSrm : VPDI<0x5A, MRMSrcMem, (outs VR128:$dst),
2022                          (ins f128mem:$src),
2023                          "cvtpd2ps\t{$src, $dst|$dst, $src}",
2024                          [(set VR128:$dst, (int_x86_sse2_cvtpd2ps
2025                                             (memop addr:$src)))]>;
2026 def Int_CVTPD2PSrr : PDI<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2027                          "cvtpd2ps\t{$src, $dst|$dst, $src}",
2028                         [(set VR128:$dst, (int_x86_sse2_cvtpd2ps VR128:$src))]>;
2029 def Int_CVTPD2PSrm : PDI<0x5A, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
2030                          "cvtpd2ps\t{$src, $dst|$dst, $src}",
2031                          [(set VR128:$dst, (int_x86_sse2_cvtpd2ps
2032                                             (memop addr:$src)))]>;
2033
2034 // AVX 256-bit register conversion intrinsics
2035 // FIXME: Migrate SSE conversion intrinsics matching to use patterns as below
2036 // whenever possible to avoid declaring two versions of each one.
2037 def : Pat<(int_x86_avx_cvtdq2_ps_256 VR256:$src),
2038           (VCVTDQ2PSYrr VR256:$src)>;
2039 def : Pat<(int_x86_avx_cvtdq2_ps_256 (bitconvert (memopv4i64 addr:$src))),
2040           (VCVTDQ2PSYrm addr:$src)>;
2041
2042 def : Pat<(int_x86_avx_cvt_pd2_ps_256 VR256:$src),
2043           (VCVTPD2PSYrr VR256:$src)>;
2044 def : Pat<(int_x86_avx_cvt_pd2_ps_256 (memopv4f64 addr:$src)),
2045           (VCVTPD2PSYrm addr:$src)>;
2046
2047 def : Pat<(int_x86_avx_cvt_ps2dq_256 VR256:$src),
2048           (VCVTPS2DQYrr VR256:$src)>;
2049 def : Pat<(int_x86_avx_cvt_ps2dq_256 (memopv8f32 addr:$src)),
2050           (VCVTPS2DQYrm addr:$src)>;
2051
2052 def : Pat<(int_x86_avx_cvt_ps2_pd_256 VR128:$src),
2053           (VCVTPS2PDYrr VR128:$src)>;
2054 def : Pat<(int_x86_avx_cvt_ps2_pd_256 (memopv4f32 addr:$src)),
2055           (VCVTPS2PDYrm addr:$src)>;
2056
2057 def : Pat<(int_x86_avx_cvtt_pd2dq_256 VR256:$src),
2058           (VCVTTPD2DQYrr VR256:$src)>;
2059 def : Pat<(int_x86_avx_cvtt_pd2dq_256 (memopv4f64 addr:$src)),
2060           (VCVTTPD2DQYrm addr:$src)>;
2061
2062 def : Pat<(int_x86_avx_cvtt_ps2dq_256 VR256:$src),
2063           (VCVTTPS2DQYrr VR256:$src)>;
2064 def : Pat<(int_x86_avx_cvtt_ps2dq_256 (memopv8f32 addr:$src)),
2065           (VCVTTPS2DQYrm addr:$src)>;
2066
2067 // Match fround and fextend for 128/256-bit conversions
2068 def : Pat<(v4f32 (fround (v4f64 VR256:$src))),
2069           (VCVTPD2PSYrr VR256:$src)>;
2070 def : Pat<(v4f32 (fround (loadv4f64 addr:$src))),
2071           (VCVTPD2PSYrm addr:$src)>;
2072
2073 def : Pat<(v4f64 (fextend (v4f32 VR128:$src))),
2074           (VCVTPS2PDYrr VR128:$src)>;
2075 def : Pat<(v4f64 (fextend (loadv4f32 addr:$src))),
2076           (VCVTPS2PDYrm addr:$src)>;
2077
2078 //===----------------------------------------------------------------------===//
2079 // SSE 1 & 2 - Compare Instructions
2080 //===----------------------------------------------------------------------===//
2081
2082 // sse12_cmp_scalar - sse 1 & 2 compare scalar instructions
2083 multiclass sse12_cmp_scalar<RegisterClass RC, X86MemOperand x86memop,
2084                             SDNode OpNode, ValueType VT, PatFrag ld_frag,
2085                             string asm, string asm_alt> {
2086   def rr : SIi8<0xC2, MRMSrcReg,
2087                 (outs RC:$dst), (ins RC:$src1, RC:$src2, SSECC:$cc), asm,
2088                 [(set RC:$dst, (OpNode (VT RC:$src1), RC:$src2, imm:$cc))]>;
2089   def rm : SIi8<0xC2, MRMSrcMem,
2090                 (outs RC:$dst), (ins RC:$src1, x86memop:$src2, SSECC:$cc), asm,
2091                 [(set RC:$dst, (OpNode (VT RC:$src1),
2092                                          (ld_frag addr:$src2), imm:$cc))]>;
2093
2094   // Accept explicit immediate argument form instead of comparison code.
2095   let neverHasSideEffects = 1 in {
2096     def rr_alt : SIi8<0xC2, MRMSrcReg, (outs RC:$dst),
2097                       (ins RC:$src1, RC:$src2, i8imm:$cc), asm_alt, []>;
2098     let mayLoad = 1 in
2099     def rm_alt : SIi8<0xC2, MRMSrcMem, (outs RC:$dst),
2100                       (ins RC:$src1, x86memop:$src2, i8imm:$cc), asm_alt, []>;
2101   }
2102 }
2103
2104 defm VCMPSS : sse12_cmp_scalar<FR32, f32mem, X86cmpss, f32, loadf32,
2105                  "cmp${cc}ss\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2106                  "cmpss\t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}">,
2107                  XS, VEX_4V, VEX_LIG;
2108 defm VCMPSD : sse12_cmp_scalar<FR64, f64mem, X86cmpsd, f64, loadf64,
2109                  "cmp${cc}sd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2110                  "cmpsd\t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}">,
2111                  XD, VEX_4V, VEX_LIG;
2112
2113 let Constraints = "$src1 = $dst" in {
2114   defm CMPSS : sse12_cmp_scalar<FR32, f32mem, X86cmpss, f32, loadf32,
2115                   "cmp${cc}ss\t{$src2, $dst|$dst, $src2}",
2116                   "cmpss\t{$cc, $src2, $dst|$dst, $src2, $cc}">,
2117                   XS;
2118   defm CMPSD : sse12_cmp_scalar<FR64, f64mem, X86cmpsd, f64, loadf64,
2119                   "cmp${cc}sd\t{$src2, $dst|$dst, $src2}",
2120                   "cmpsd\t{$cc, $src2, $dst|$dst, $src2, $cc}">,
2121                   XD;
2122 }
2123
2124 multiclass sse12_cmp_scalar_int<RegisterClass RC, X86MemOperand x86memop,
2125                          Intrinsic Int, string asm> {
2126   def rr : SIi8<0xC2, MRMSrcReg, (outs VR128:$dst),
2127                       (ins VR128:$src1, VR128:$src, SSECC:$cc), asm,
2128                         [(set VR128:$dst, (Int VR128:$src1,
2129                                                VR128:$src, imm:$cc))]>;
2130   def rm : SIi8<0xC2, MRMSrcMem, (outs VR128:$dst),
2131                       (ins VR128:$src1, f32mem:$src, SSECC:$cc), asm,
2132                         [(set VR128:$dst, (Int VR128:$src1,
2133                                                (load addr:$src), imm:$cc))]>;
2134 }
2135
2136 // Aliases to match intrinsics which expect XMM operand(s).
2137 defm Int_VCMPSS  : sse12_cmp_scalar_int<VR128, f32mem, int_x86_sse_cmp_ss,
2138                      "cmp${cc}ss\t{$src, $src1, $dst|$dst, $src1, $src}">,
2139                      XS, VEX_4V;
2140 defm Int_VCMPSD  : sse12_cmp_scalar_int<VR128, f64mem, int_x86_sse2_cmp_sd,
2141                      "cmp${cc}sd\t{$src, $src1, $dst|$dst, $src1, $src}">,
2142                      XD, VEX_4V;
2143 let Constraints = "$src1 = $dst" in {
2144   defm Int_CMPSS  : sse12_cmp_scalar_int<VR128, f32mem, int_x86_sse_cmp_ss,
2145                        "cmp${cc}ss\t{$src, $dst|$dst, $src}">, XS;
2146   defm Int_CMPSD  : sse12_cmp_scalar_int<VR128, f64mem, int_x86_sse2_cmp_sd,
2147                        "cmp${cc}sd\t{$src, $dst|$dst, $src}">, XD;
2148 }
2149
2150
2151 // sse12_ord_cmp - Unordered/Ordered scalar fp compare and set EFLAGS
2152 multiclass sse12_ord_cmp<bits<8> opc, RegisterClass RC, SDNode OpNode,
2153                             ValueType vt, X86MemOperand x86memop,
2154                             PatFrag ld_frag, string OpcodeStr, Domain d> {
2155   def rr: PI<opc, MRMSrcReg, (outs), (ins RC:$src1, RC:$src2),
2156                      !strconcat(OpcodeStr, "\t{$src2, $src1|$src1, $src2}"),
2157                      [(set EFLAGS, (OpNode (vt RC:$src1), RC:$src2))], d>;
2158   def rm: PI<opc, MRMSrcMem, (outs), (ins RC:$src1, x86memop:$src2),
2159                      !strconcat(OpcodeStr, "\t{$src2, $src1|$src1, $src2}"),
2160                      [(set EFLAGS, (OpNode (vt RC:$src1),
2161                                            (ld_frag addr:$src2)))], d>;
2162 }
2163
2164 let Defs = [EFLAGS] in {
2165   defm VUCOMISS : sse12_ord_cmp<0x2E, FR32, X86cmp, f32, f32mem, loadf32,
2166                                   "ucomiss", SSEPackedSingle>, TB, VEX, VEX_LIG;
2167   defm VUCOMISD : sse12_ord_cmp<0x2E, FR64, X86cmp, f64, f64mem, loadf64,
2168                                   "ucomisd", SSEPackedDouble>, TB, OpSize, VEX,
2169                                   VEX_LIG;
2170   let Pattern = []<dag> in {
2171     defm VCOMISS  : sse12_ord_cmp<0x2F, VR128, undef, v4f32, f128mem, load,
2172                                     "comiss", SSEPackedSingle>, TB, VEX,
2173                                     VEX_LIG;
2174     defm VCOMISD  : sse12_ord_cmp<0x2F, VR128, undef, v2f64, f128mem, load,
2175                                     "comisd", SSEPackedDouble>, TB, OpSize, VEX,
2176                                     VEX_LIG;
2177   }
2178
2179   defm Int_VUCOMISS  : sse12_ord_cmp<0x2E, VR128, X86ucomi, v4f32, f128mem,
2180                             load, "ucomiss", SSEPackedSingle>, TB, VEX;
2181   defm Int_VUCOMISD  : sse12_ord_cmp<0x2E, VR128, X86ucomi, v2f64, f128mem,
2182                             load, "ucomisd", SSEPackedDouble>, TB, OpSize, VEX;
2183
2184   defm Int_VCOMISS  : sse12_ord_cmp<0x2F, VR128, X86comi, v4f32, f128mem,
2185                             load, "comiss", SSEPackedSingle>, TB, VEX;
2186   defm Int_VCOMISD  : sse12_ord_cmp<0x2F, VR128, X86comi, v2f64, f128mem,
2187                             load, "comisd", SSEPackedDouble>, TB, OpSize, VEX;
2188   defm UCOMISS  : sse12_ord_cmp<0x2E, FR32, X86cmp, f32, f32mem, loadf32,
2189                                   "ucomiss", SSEPackedSingle>, TB;
2190   defm UCOMISD  : sse12_ord_cmp<0x2E, FR64, X86cmp, f64, f64mem, loadf64,
2191                                   "ucomisd", SSEPackedDouble>, TB, OpSize;
2192
2193   let Pattern = []<dag> in {
2194     defm COMISS  : sse12_ord_cmp<0x2F, VR128, undef, v4f32, f128mem, load,
2195                                     "comiss", SSEPackedSingle>, TB;
2196     defm COMISD  : sse12_ord_cmp<0x2F, VR128, undef, v2f64, f128mem, load,
2197                                     "comisd", SSEPackedDouble>, TB, OpSize;
2198   }
2199
2200   defm Int_UCOMISS  : sse12_ord_cmp<0x2E, VR128, X86ucomi, v4f32, f128mem,
2201                               load, "ucomiss", SSEPackedSingle>, TB;
2202   defm Int_UCOMISD  : sse12_ord_cmp<0x2E, VR128, X86ucomi, v2f64, f128mem,
2203                               load, "ucomisd", SSEPackedDouble>, TB, OpSize;
2204
2205   defm Int_COMISS  : sse12_ord_cmp<0x2F, VR128, X86comi, v4f32, f128mem, load,
2206                                   "comiss", SSEPackedSingle>, TB;
2207   defm Int_COMISD  : sse12_ord_cmp<0x2F, VR128, X86comi, v2f64, f128mem, load,
2208                                   "comisd", SSEPackedDouble>, TB, OpSize;
2209 } // Defs = [EFLAGS]
2210
2211 // sse12_cmp_packed - sse 1 & 2 compared packed instructions
2212 multiclass sse12_cmp_packed<RegisterClass RC, X86MemOperand x86memop,
2213                             Intrinsic Int, string asm, string asm_alt,
2214                             Domain d> {
2215   let isAsmParserOnly = 1 in {
2216     def rri : PIi8<0xC2, MRMSrcReg,
2217                (outs RC:$dst), (ins RC:$src1, RC:$src2, SSECC:$cc), asm,
2218                [(set RC:$dst, (Int RC:$src1, RC:$src2, imm:$cc))], d>;
2219     def rmi : PIi8<0xC2, MRMSrcMem,
2220                (outs RC:$dst), (ins RC:$src1, f128mem:$src2, SSECC:$cc), asm,
2221                [(set RC:$dst, (Int RC:$src1, (memop addr:$src2), imm:$cc))], d>;
2222   }
2223
2224   // Accept explicit immediate argument form instead of comparison code.
2225   def rri_alt : PIi8<0xC2, MRMSrcReg,
2226              (outs RC:$dst), (ins RC:$src1, RC:$src2, i8imm:$cc),
2227              asm_alt, [], d>;
2228   def rmi_alt : PIi8<0xC2, MRMSrcMem,
2229              (outs RC:$dst), (ins RC:$src1, f128mem:$src2, i8imm:$cc),
2230              asm_alt, [], d>;
2231 }
2232
2233 defm VCMPPS : sse12_cmp_packed<VR128, f128mem, int_x86_sse_cmp_ps,
2234                "cmp${cc}ps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2235                "cmpps\t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}",
2236                SSEPackedSingle>, TB, VEX_4V;
2237 defm VCMPPD : sse12_cmp_packed<VR128, f128mem, int_x86_sse2_cmp_pd,
2238                "cmp${cc}pd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2239                "cmppd\t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}",
2240                SSEPackedDouble>, TB, OpSize, VEX_4V;
2241 defm VCMPPSY : sse12_cmp_packed<VR256, f256mem, int_x86_avx_cmp_ps_256,
2242                "cmp${cc}ps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2243                "cmpps\t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}",
2244                SSEPackedSingle>, TB, VEX_4V;
2245 defm VCMPPDY : sse12_cmp_packed<VR256, f256mem, int_x86_avx_cmp_pd_256,
2246                "cmp${cc}pd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2247                "cmppd\t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}",
2248                SSEPackedDouble>, TB, OpSize, VEX_4V;
2249 let Constraints = "$src1 = $dst" in {
2250   defm CMPPS : sse12_cmp_packed<VR128, f128mem, int_x86_sse_cmp_ps,
2251                  "cmp${cc}ps\t{$src2, $dst|$dst, $src2}",
2252                  "cmpps\t{$cc, $src2, $dst|$dst, $src2, $cc}",
2253                  SSEPackedSingle>, TB;
2254   defm CMPPD : sse12_cmp_packed<VR128, f128mem, int_x86_sse2_cmp_pd,
2255                  "cmp${cc}pd\t{$src2, $dst|$dst, $src2}",
2256                  "cmppd\t{$cc, $src2, $dst|$dst, $src2, $cc}",
2257                  SSEPackedDouble>, TB, OpSize;
2258 }
2259
2260 let Predicates = [HasAVX] in {
2261 def : Pat<(v4i32 (X86cmpps (v4f32 VR128:$src1), VR128:$src2, imm:$cc)),
2262           (VCMPPSrri (v4f32 VR128:$src1), (v4f32 VR128:$src2), imm:$cc)>;
2263 def : Pat<(v4i32 (X86cmpps (v4f32 VR128:$src1), (memop addr:$src2), imm:$cc)),
2264           (VCMPPSrmi (v4f32 VR128:$src1), addr:$src2, imm:$cc)>;
2265 def : Pat<(v2i64 (X86cmppd (v2f64 VR128:$src1), VR128:$src2, imm:$cc)),
2266           (VCMPPDrri VR128:$src1, VR128:$src2, imm:$cc)>;
2267 def : Pat<(v2i64 (X86cmppd (v2f64 VR128:$src1), (memop addr:$src2), imm:$cc)),
2268           (VCMPPDrmi VR128:$src1, addr:$src2, imm:$cc)>;
2269
2270 def : Pat<(v8i32 (X86cmpps (v8f32 VR256:$src1), VR256:$src2, imm:$cc)),
2271           (VCMPPSYrri (v8f32 VR256:$src1), (v8f32 VR256:$src2), imm:$cc)>;
2272 def : Pat<(v8i32 (X86cmpps (v8f32 VR256:$src1), (memop addr:$src2), imm:$cc)),
2273           (VCMPPSYrmi (v8f32 VR256:$src1), addr:$src2, imm:$cc)>;
2274 def : Pat<(v4i64 (X86cmppd (v4f64 VR256:$src1), VR256:$src2, imm:$cc)),
2275           (VCMPPDYrri VR256:$src1, VR256:$src2, imm:$cc)>;
2276 def : Pat<(v4i64 (X86cmppd (v4f64 VR256:$src1), (memop addr:$src2), imm:$cc)),
2277           (VCMPPDYrmi VR256:$src1, addr:$src2, imm:$cc)>;
2278 }
2279
2280 let Predicates = [HasSSE1] in {
2281 def : Pat<(v4i32 (X86cmpps (v4f32 VR128:$src1), VR128:$src2, imm:$cc)),
2282           (CMPPSrri (v4f32 VR128:$src1), (v4f32 VR128:$src2), imm:$cc)>;
2283 def : Pat<(v4i32 (X86cmpps (v4f32 VR128:$src1), (memop addr:$src2), imm:$cc)),
2284           (CMPPSrmi (v4f32 VR128:$src1), addr:$src2, imm:$cc)>;
2285 }
2286
2287 let Predicates = [HasSSE2] in {
2288 def : Pat<(v2i64 (X86cmppd (v2f64 VR128:$src1), VR128:$src2, imm:$cc)),
2289           (CMPPDrri VR128:$src1, VR128:$src2, imm:$cc)>;
2290 def : Pat<(v2i64 (X86cmppd (v2f64 VR128:$src1), (memop addr:$src2), imm:$cc)),
2291           (CMPPDrmi VR128:$src1, addr:$src2, imm:$cc)>;
2292 }
2293
2294 //===----------------------------------------------------------------------===//
2295 // SSE 1 & 2 - Shuffle Instructions
2296 //===----------------------------------------------------------------------===//
2297
2298 /// sse12_shuffle - sse 1 & 2 shuffle instructions
2299 multiclass sse12_shuffle<RegisterClass RC, X86MemOperand x86memop,
2300                          ValueType vt, string asm, PatFrag mem_frag,
2301                          Domain d, bit IsConvertibleToThreeAddress = 0> {
2302   def rmi : PIi8<0xC6, MRMSrcMem, (outs RC:$dst),
2303                    (ins RC:$src1, f128mem:$src2, i8imm:$src3), asm,
2304                    [(set RC:$dst, (vt (shufp:$src3
2305                             RC:$src1, (mem_frag addr:$src2))))], d>;
2306   let isConvertibleToThreeAddress = IsConvertibleToThreeAddress in
2307     def rri : PIi8<0xC6, MRMSrcReg, (outs RC:$dst),
2308                    (ins RC:$src1, RC:$src2, i8imm:$src3), asm,
2309                    [(set RC:$dst,
2310                             (vt (shufp:$src3 RC:$src1, RC:$src2)))], d>;
2311 }
2312
2313 defm VSHUFPS  : sse12_shuffle<VR128, f128mem, v4f32,
2314            "shufps\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
2315            memopv4f32, SSEPackedSingle>, TB, VEX_4V;
2316 defm VSHUFPSY : sse12_shuffle<VR256, f256mem, v8f32,
2317            "shufps\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
2318            memopv8f32, SSEPackedSingle>, TB, VEX_4V;
2319 defm VSHUFPD  : sse12_shuffle<VR128, f128mem, v2f64,
2320            "shufpd\t{$src3, $src2, $src1, $dst|$dst, $src2, $src2, $src3}",
2321            memopv2f64, SSEPackedDouble>, TB, OpSize, VEX_4V;
2322 defm VSHUFPDY : sse12_shuffle<VR256, f256mem, v4f64,
2323            "shufpd\t{$src3, $src2, $src1, $dst|$dst, $src2, $src2, $src3}",
2324            memopv4f64, SSEPackedDouble>, TB, OpSize, VEX_4V;
2325
2326 let Constraints = "$src1 = $dst" in {
2327   defm SHUFPS : sse12_shuffle<VR128, f128mem, v4f32,
2328                     "shufps\t{$src3, $src2, $dst|$dst, $src2, $src3}",
2329                     memopv4f32, SSEPackedSingle, 1 /* cvt to pshufd */>,
2330                     TB;
2331   defm SHUFPD : sse12_shuffle<VR128, f128mem, v2f64,
2332                     "shufpd\t{$src3, $src2, $dst|$dst, $src2, $src3}",
2333                     memopv2f64, SSEPackedDouble>, TB, OpSize;
2334 }
2335
2336 let Predicates = [HasAVX] in {
2337   def : Pat<(v4f32 (X86Shufp VR128:$src1,
2338                        (memopv4f32 addr:$src2), (i8 imm:$imm))),
2339             (VSHUFPSrmi VR128:$src1, addr:$src2, imm:$imm)>;
2340   def : Pat<(v4f32 (X86Shufp VR128:$src1, VR128:$src2, (i8 imm:$imm))),
2341             (VSHUFPSrri VR128:$src1, VR128:$src2, imm:$imm)>;
2342   def : Pat<(v4i32 (X86Shufp VR128:$src1,
2343                        (bc_v4i32 (memopv2i64 addr:$src2)), (i8 imm:$imm))),
2344             (VSHUFPSrmi VR128:$src1, addr:$src2, imm:$imm)>;
2345   def : Pat<(v4i32 (X86Shufp VR128:$src1, VR128:$src2, (i8 imm:$imm))),
2346             (VSHUFPSrri VR128:$src1, VR128:$src2, imm:$imm)>;
2347   // vector_shuffle v1, v2 <4, 5, 2, 3> using SHUFPSrri (we prefer movsd, but
2348   // fall back to this for SSE1)
2349   def : Pat<(v4f32 (movlp:$src3 VR128:$src1, (v4f32 VR128:$src2))),
2350             (VSHUFPSrri VR128:$src2, VR128:$src1,
2351                         (SHUFFLE_get_shuf_imm VR128:$src3))>;
2352   // Special unary SHUFPSrri case.
2353   def : Pat<(v4f32 (pshufd:$src3 VR128:$src1, (undef))),
2354             (VSHUFPSrri VR128:$src1, VR128:$src1,
2355                         (SHUFFLE_get_shuf_imm VR128:$src3))>;
2356   // Special binary v4i32 shuffle cases with SHUFPS.
2357   def : Pat<(v4i32 (shufp:$src3 VR128:$src1, (v4i32 VR128:$src2))),
2358             (VSHUFPSrri VR128:$src1, VR128:$src2,
2359                         (SHUFFLE_get_shuf_imm VR128:$src3))>;
2360   def : Pat<(v4i32 (shufp:$src3 VR128:$src1,
2361                                 (bc_v4i32 (memopv2i64 addr:$src2)))),
2362             (VSHUFPSrmi VR128:$src1, addr:$src2,
2363                         (SHUFFLE_get_shuf_imm VR128:$src3))>;
2364   // Special unary SHUFPDrri cases.
2365   def : Pat<(v2i64 (pshufd:$src3 VR128:$src1, (undef))),
2366             (VSHUFPDrri VR128:$src1, VR128:$src1,
2367                         (SHUFFLE_get_shuf_imm VR128:$src3))>;
2368   def : Pat<(v2f64 (pshufd:$src3 VR128:$src1, (undef))),
2369             (VSHUFPDrri VR128:$src1, VR128:$src1,
2370                         (SHUFFLE_get_shuf_imm VR128:$src3))>;
2371   // Special binary v2i64 shuffle cases using SHUFPDrri.
2372   def : Pat<(v2i64 (shufp:$src3 VR128:$src1, VR128:$src2)),
2373             (VSHUFPDrri VR128:$src1, VR128:$src2,
2374                         (SHUFFLE_get_shuf_imm VR128:$src3))>;
2375
2376   def : Pat<(v2i64 (X86Shufp VR128:$src1,
2377                        (memopv2i64 addr:$src2), (i8 imm:$imm))),
2378             (VSHUFPDrmi VR128:$src1, addr:$src2, imm:$imm)>;
2379   def : Pat<(v2f64 (X86Shufp VR128:$src1,
2380                        (memopv2f64 addr:$src2), (i8 imm:$imm))),
2381             (VSHUFPDrmi VR128:$src1, addr:$src2, imm:$imm)>;
2382   def : Pat<(v2i64 (X86Shufp VR128:$src1, VR128:$src2, (i8 imm:$imm))),
2383             (VSHUFPDrri VR128:$src1, VR128:$src2, imm:$imm)>;
2384   def : Pat<(v2f64 (X86Shufp VR128:$src1, VR128:$src2, (i8 imm:$imm))),
2385             (VSHUFPDrri VR128:$src1, VR128:$src2, imm:$imm)>;
2386
2387   // 256-bit patterns
2388   def : Pat<(v8i32 (X86Shufp VR256:$src1, VR256:$src2, (i8 imm:$imm))),
2389             (VSHUFPSYrri VR256:$src1, VR256:$src2, imm:$imm)>;
2390   def : Pat<(v8i32 (X86Shufp VR256:$src1,
2391                       (bc_v8i32 (memopv4i64 addr:$src2)), (i8 imm:$imm))),
2392             (VSHUFPSYrmi VR256:$src1, addr:$src2, imm:$imm)>;
2393
2394   def : Pat<(v8f32 (X86Shufp VR256:$src1, VR256:$src2, (i8 imm:$imm))),
2395             (VSHUFPSYrri VR256:$src1, VR256:$src2, imm:$imm)>;
2396   def : Pat<(v8f32 (X86Shufp VR256:$src1,
2397                               (memopv8f32 addr:$src2), (i8 imm:$imm))),
2398             (VSHUFPSYrmi VR256:$src1, addr:$src2, imm:$imm)>;
2399
2400   def : Pat<(v4i64 (X86Shufp VR256:$src1, VR256:$src2, (i8 imm:$imm))),
2401             (VSHUFPDYrri VR256:$src1, VR256:$src2, imm:$imm)>;
2402   def : Pat<(v4i64 (X86Shufp VR256:$src1,
2403                               (memopv4i64 addr:$src2), (i8 imm:$imm))),
2404             (VSHUFPDYrmi VR256:$src1, addr:$src2, imm:$imm)>;
2405
2406   def : Pat<(v4f64 (X86Shufp VR256:$src1, VR256:$src2, (i8 imm:$imm))),
2407             (VSHUFPDYrri VR256:$src1, VR256:$src2, imm:$imm)>;
2408   def : Pat<(v4f64 (X86Shufp VR256:$src1,
2409                               (memopv4f64 addr:$src2), (i8 imm:$imm))),
2410             (VSHUFPDYrmi VR256:$src1, addr:$src2, imm:$imm)>;
2411 }
2412
2413 let Predicates = [HasSSE1] in {
2414   def : Pat<(v4f32 (X86Shufp VR128:$src1,
2415                        (memopv4f32 addr:$src2), (i8 imm:$imm))),
2416             (SHUFPSrmi VR128:$src1, addr:$src2, imm:$imm)>;
2417   def : Pat<(v4f32 (X86Shufp VR128:$src1, VR128:$src2, (i8 imm:$imm))),
2418             (SHUFPSrri VR128:$src1, VR128:$src2, imm:$imm)>;
2419   def : Pat<(v4i32 (X86Shufp VR128:$src1,
2420                        (bc_v4i32 (memopv2i64 addr:$src2)), (i8 imm:$imm))),
2421             (SHUFPSrmi VR128:$src1, addr:$src2, imm:$imm)>;
2422   def : Pat<(v4i32 (X86Shufp VR128:$src1, VR128:$src2, (i8 imm:$imm))),
2423             (SHUFPSrri VR128:$src1, VR128:$src2, imm:$imm)>;
2424   // vector_shuffle v1, v2 <4, 5, 2, 3> using SHUFPSrri (we prefer movsd, but
2425   // fall back to this for SSE1)
2426   def : Pat<(v4f32 (movlp:$src3 VR128:$src1, (v4f32 VR128:$src2))),
2427             (SHUFPSrri VR128:$src2, VR128:$src1,
2428                        (SHUFFLE_get_shuf_imm VR128:$src3))>;
2429   // Special unary SHUFPSrri case.
2430   def : Pat<(v4f32 (pshufd:$src3 VR128:$src1, (undef))),
2431             (SHUFPSrri VR128:$src1, VR128:$src1,
2432                        (SHUFFLE_get_shuf_imm VR128:$src3))>;
2433 }
2434
2435 let Predicates = [HasSSE2] in {
2436   // Special binary v4i32 shuffle cases with SHUFPS.
2437   def : Pat<(v4i32 (shufp:$src3 VR128:$src1, (v4i32 VR128:$src2))),
2438             (SHUFPSrri VR128:$src1, VR128:$src2,
2439                        (SHUFFLE_get_shuf_imm VR128:$src3))>;
2440   def : Pat<(v4i32 (shufp:$src3 VR128:$src1,
2441                                 (bc_v4i32 (memopv2i64 addr:$src2)))),
2442             (SHUFPSrmi VR128:$src1, addr:$src2,
2443                       (SHUFFLE_get_shuf_imm VR128:$src3))>;
2444   // Special unary SHUFPDrri cases.
2445   def : Pat<(v2i64 (pshufd:$src3 VR128:$src1, (undef))),
2446             (SHUFPDrri VR128:$src1, VR128:$src1,
2447                        (SHUFFLE_get_shuf_imm VR128:$src3))>;
2448   def : Pat<(v2f64 (pshufd:$src3 VR128:$src1, (undef))),
2449             (SHUFPDrri VR128:$src1, VR128:$src1,
2450                        (SHUFFLE_get_shuf_imm VR128:$src3))>;
2451   // Special binary v2i64 shuffle cases using SHUFPDrri.
2452   def : Pat<(v2i64 (shufp:$src3 VR128:$src1, VR128:$src2)),
2453             (SHUFPDrri VR128:$src1, VR128:$src2,
2454                        (SHUFFLE_get_shuf_imm VR128:$src3))>;
2455   // Generic SHUFPD patterns
2456   def : Pat<(v2i64 (X86Shufp VR128:$src1,
2457                        (memopv2i64 addr:$src2), (i8 imm:$imm))),
2458             (SHUFPDrmi VR128:$src1, addr:$src2, imm:$imm)>;
2459   def : Pat<(v2f64 (X86Shufp VR128:$src1,
2460                        (memopv2f64 addr:$src2), (i8 imm:$imm))),
2461             (SHUFPDrmi VR128:$src1, addr:$src2, imm:$imm)>;
2462   def : Pat<(v2i64 (X86Shufp VR128:$src1, VR128:$src2, (i8 imm:$imm))),
2463             (SHUFPDrri VR128:$src1, VR128:$src2, imm:$imm)>;
2464   def : Pat<(v2f64 (X86Shufp VR128:$src1, VR128:$src2, (i8 imm:$imm))),
2465             (SHUFPDrri VR128:$src1, VR128:$src2, imm:$imm)>;
2466 }
2467
2468 //===----------------------------------------------------------------------===//
2469 // SSE 1 & 2 - Unpack Instructions
2470 //===----------------------------------------------------------------------===//
2471
2472 /// sse12_unpack_interleave - sse 1 & 2 unpack and interleave
2473 multiclass sse12_unpack_interleave<bits<8> opc, PatFrag OpNode, ValueType vt,
2474                                    PatFrag mem_frag, RegisterClass RC,
2475                                    X86MemOperand x86memop, string asm,
2476                                    Domain d> {
2477     def rr : PI<opc, MRMSrcReg,
2478                 (outs RC:$dst), (ins RC:$src1, RC:$src2),
2479                 asm, [(set RC:$dst,
2480                            (vt (OpNode RC:$src1, RC:$src2)))], d>;
2481     def rm : PI<opc, MRMSrcMem,
2482                 (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
2483                 asm, [(set RC:$dst,
2484                            (vt (OpNode RC:$src1,
2485                                        (mem_frag addr:$src2))))], d>;
2486 }
2487
2488 let AddedComplexity = 10 in {
2489   defm VUNPCKHPS: sse12_unpack_interleave<0x15, unpckh, v4f32, memopv4f32,
2490         VR128, f128mem, "unpckhps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2491                        SSEPackedSingle>, TB, VEX_4V;
2492   defm VUNPCKHPD: sse12_unpack_interleave<0x15, unpckh, v2f64, memopv2f64,
2493         VR128, f128mem, "unpckhpd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2494                        SSEPackedDouble>, TB, OpSize, VEX_4V;
2495   defm VUNPCKLPS: sse12_unpack_interleave<0x14, unpckl, v4f32, memopv4f32,
2496         VR128, f128mem, "unpcklps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2497                        SSEPackedSingle>, TB, VEX_4V;
2498   defm VUNPCKLPD: sse12_unpack_interleave<0x14, unpckl, v2f64, memopv2f64,
2499         VR128, f128mem, "unpcklpd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2500                        SSEPackedDouble>, TB, OpSize, VEX_4V;
2501
2502   defm VUNPCKHPSY: sse12_unpack_interleave<0x15, unpckh, v8f32, memopv8f32,
2503         VR256, f256mem, "unpckhps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2504                        SSEPackedSingle>, TB, VEX_4V;
2505   defm VUNPCKHPDY: sse12_unpack_interleave<0x15, unpckh, v4f64, memopv4f64,
2506         VR256, f256mem, "unpckhpd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2507                        SSEPackedDouble>, TB, OpSize, VEX_4V;
2508   defm VUNPCKLPSY: sse12_unpack_interleave<0x14, unpckl, v8f32, memopv8f32,
2509         VR256, f256mem, "unpcklps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2510                        SSEPackedSingle>, TB, VEX_4V;
2511   defm VUNPCKLPDY: sse12_unpack_interleave<0x14, unpckl, v4f64, memopv4f64,
2512         VR256, f256mem, "unpcklpd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2513                        SSEPackedDouble>, TB, OpSize, VEX_4V;
2514
2515   let Constraints = "$src1 = $dst" in {
2516     defm UNPCKHPS: sse12_unpack_interleave<0x15, unpckh, v4f32, memopv4f32,
2517           VR128, f128mem, "unpckhps\t{$src2, $dst|$dst, $src2}",
2518                          SSEPackedSingle>, TB;
2519     defm UNPCKHPD: sse12_unpack_interleave<0x15, unpckh, v2f64, memopv2f64,
2520           VR128, f128mem, "unpckhpd\t{$src2, $dst|$dst, $src2}",
2521                          SSEPackedDouble>, TB, OpSize;
2522     defm UNPCKLPS: sse12_unpack_interleave<0x14, unpckl, v4f32, memopv4f32,
2523           VR128, f128mem, "unpcklps\t{$src2, $dst|$dst, $src2}",
2524                          SSEPackedSingle>, TB;
2525     defm UNPCKLPD: sse12_unpack_interleave<0x14, unpckl, v2f64, memopv2f64,
2526           VR128, f128mem, "unpcklpd\t{$src2, $dst|$dst, $src2}",
2527                          SSEPackedDouble>, TB, OpSize;
2528   } // Constraints = "$src1 = $dst"
2529 } // AddedComplexity
2530
2531 let Predicates = [HasSSE1] in {
2532   def : Pat<(v4f32 (X86Unpckl VR128:$src1, (memopv4f32 addr:$src2))),
2533             (UNPCKLPSrm VR128:$src1, addr:$src2)>;
2534   def : Pat<(v4f32 (X86Unpckl VR128:$src1, VR128:$src2)),
2535             (UNPCKLPSrr VR128:$src1, VR128:$src2)>;
2536   def : Pat<(v4f32 (X86Unpckh VR128:$src1, (memopv4f32 addr:$src2))),
2537             (UNPCKHPSrm VR128:$src1, addr:$src2)>;
2538   def : Pat<(v4f32 (X86Unpckh VR128:$src1, VR128:$src2)),
2539             (UNPCKHPSrr VR128:$src1, VR128:$src2)>;
2540 }
2541
2542 let Predicates = [HasSSE2] in {
2543   def : Pat<(v2f64 (X86Unpckl VR128:$src1, (memopv2f64 addr:$src2))),
2544             (UNPCKLPDrm VR128:$src1, addr:$src2)>;
2545   def : Pat<(v2f64 (X86Unpckl VR128:$src1, VR128:$src2)),
2546             (UNPCKLPDrr VR128:$src1, VR128:$src2)>;
2547   def : Pat<(v2f64 (X86Unpckh VR128:$src1, (memopv2f64 addr:$src2))),
2548             (UNPCKHPDrm VR128:$src1, addr:$src2)>;
2549   def : Pat<(v2f64 (X86Unpckh VR128:$src1, VR128:$src2)),
2550             (UNPCKHPDrr VR128:$src1, VR128:$src2)>;
2551
2552   // FIXME: Instead of X86Movddup, there should be a X86Unpckl here, the
2553   // problem is during lowering, where it's not possible to recognize the load
2554   // fold cause it has two uses through a bitcast. One use disappears at isel
2555   // time and the fold opportunity reappears.
2556   def : Pat<(v2f64 (X86Movddup VR128:$src)),
2557             (UNPCKLPDrr VR128:$src, VR128:$src)>;
2558
2559   let AddedComplexity = 10 in
2560   def : Pat<(splat_lo (v2f64 VR128:$src), (undef)),
2561             (UNPCKLPDrr VR128:$src, VR128:$src)>;
2562 }
2563
2564 let Predicates = [HasAVX] in {
2565   def : Pat<(v4f32 (X86Unpckl VR128:$src1, (memopv4f32 addr:$src2))),
2566             (VUNPCKLPSrm VR128:$src1, addr:$src2)>;
2567   def : Pat<(v4f32 (X86Unpckl VR128:$src1, VR128:$src2)),
2568             (VUNPCKLPSrr VR128:$src1, VR128:$src2)>;
2569   def : Pat<(v4f32 (X86Unpckh VR128:$src1, (memopv4f32 addr:$src2))),
2570             (VUNPCKHPSrm VR128:$src1, addr:$src2)>;
2571   def : Pat<(v4f32 (X86Unpckh VR128:$src1, VR128:$src2)),
2572             (VUNPCKHPSrr VR128:$src1, VR128:$src2)>;
2573
2574   def : Pat<(v8f32 (X86Unpckl VR256:$src1, (memopv8f32 addr:$src2))),
2575             (VUNPCKLPSYrm VR256:$src1, addr:$src2)>;
2576   def : Pat<(v8f32 (X86Unpckl VR256:$src1, VR256:$src2)),
2577             (VUNPCKLPSYrr VR256:$src1, VR256:$src2)>;
2578   def : Pat<(v8f32 (X86Unpckh VR256:$src1, (memopv8f32 addr:$src2))),
2579             (VUNPCKHPSYrm VR256:$src1, addr:$src2)>;
2580   def : Pat<(v8f32 (X86Unpckh VR256:$src1, VR256:$src2)),
2581             (VUNPCKHPSYrr VR256:$src1, VR256:$src2)>;
2582
2583   def : Pat<(v2f64 (X86Unpckl VR128:$src1, (memopv2f64 addr:$src2))),
2584             (VUNPCKLPDrm VR128:$src1, addr:$src2)>;
2585   def : Pat<(v2f64 (X86Unpckl VR128:$src1, VR128:$src2)),
2586             (VUNPCKLPDrr VR128:$src1, VR128:$src2)>;
2587   def : Pat<(v2f64 (X86Unpckh VR128:$src1, (memopv2f64 addr:$src2))),
2588             (VUNPCKHPDrm VR128:$src1, addr:$src2)>;
2589   def : Pat<(v2f64 (X86Unpckh VR128:$src1, VR128:$src2)),
2590             (VUNPCKHPDrr VR128:$src1, VR128:$src2)>;
2591
2592   def : Pat<(v4f64 (X86Unpckl VR256:$src1, (memopv4f64 addr:$src2))),
2593             (VUNPCKLPDYrm VR256:$src1, addr:$src2)>;
2594   def : Pat<(v4f64 (X86Unpckl VR256:$src1, VR256:$src2)),
2595             (VUNPCKLPDYrr VR256:$src1, VR256:$src2)>;
2596   def : Pat<(v4f64 (X86Unpckh VR256:$src1, (memopv4f64 addr:$src2))),
2597             (VUNPCKHPDYrm VR256:$src1, addr:$src2)>;
2598   def : Pat<(v4f64 (X86Unpckh VR256:$src1, VR256:$src2)),
2599             (VUNPCKHPDYrr VR256:$src1, VR256:$src2)>;
2600
2601   // FIXME: Instead of X86Movddup, there should be a X86Unpckl here, the
2602   // problem is during lowering, where it's not possible to recognize the load
2603   // fold cause it has two uses through a bitcast. One use disappears at isel
2604   // time and the fold opportunity reappears.
2605   def : Pat<(v2f64 (X86Movddup VR128:$src)),
2606             (VUNPCKLPDrr VR128:$src, VR128:$src)>;
2607   let AddedComplexity = 10 in
2608   def : Pat<(splat_lo (v2f64 VR128:$src), (undef)),
2609             (VUNPCKLPDrr VR128:$src, VR128:$src)>;
2610 }
2611
2612 //===----------------------------------------------------------------------===//
2613 // SSE 1 & 2 - Extract Floating-Point Sign mask
2614 //===----------------------------------------------------------------------===//
2615
2616 /// sse12_extr_sign_mask - sse 1 & 2 unpack and interleave
2617 multiclass sse12_extr_sign_mask<RegisterClass RC, Intrinsic Int, string asm,
2618                                 Domain d> {
2619   def rr32 : PI<0x50, MRMSrcReg, (outs GR32:$dst), (ins RC:$src),
2620                 !strconcat(asm, "\t{$src, $dst|$dst, $src}"),
2621                      [(set GR32:$dst, (Int RC:$src))], d>;
2622   def rr64 : PI<0x50, MRMSrcReg, (outs GR64:$dst), (ins RC:$src),
2623                 !strconcat(asm, "\t{$src, $dst|$dst, $src}"), [], d>, REX_W;
2624 }
2625
2626 let Predicates = [HasAVX] in {
2627   defm VMOVMSKPS : sse12_extr_sign_mask<VR128, int_x86_sse_movmsk_ps,
2628                                         "movmskps", SSEPackedSingle>, TB, VEX;
2629   defm VMOVMSKPD : sse12_extr_sign_mask<VR128, int_x86_sse2_movmsk_pd,
2630                                         "movmskpd", SSEPackedDouble>, TB,
2631                                         OpSize, VEX;
2632   defm VMOVMSKPSY : sse12_extr_sign_mask<VR256, int_x86_avx_movmsk_ps_256,
2633                                         "movmskps", SSEPackedSingle>, TB, VEX;
2634   defm VMOVMSKPDY : sse12_extr_sign_mask<VR256, int_x86_avx_movmsk_pd_256,
2635                                         "movmskpd", SSEPackedDouble>, TB,
2636                                         OpSize, VEX;
2637
2638   def : Pat<(i32 (X86fgetsign FR32:$src)),
2639             (VMOVMSKPSrr32 (INSERT_SUBREG (v4f32 (IMPLICIT_DEF)), FR32:$src,
2640                                           sub_ss))>;
2641   def : Pat<(i64 (X86fgetsign FR32:$src)),
2642             (VMOVMSKPSrr64 (INSERT_SUBREG (v4f32 (IMPLICIT_DEF)), FR32:$src,
2643                                           sub_ss))>;
2644   def : Pat<(i32 (X86fgetsign FR64:$src)),
2645             (VMOVMSKPDrr32 (INSERT_SUBREG (v2f64 (IMPLICIT_DEF)), FR64:$src,
2646                                           sub_sd))>;
2647   def : Pat<(i64 (X86fgetsign FR64:$src)),
2648             (VMOVMSKPDrr64 (INSERT_SUBREG (v2f64 (IMPLICIT_DEF)), FR64:$src,
2649                                           sub_sd))>;
2650
2651   // Assembler Only
2652   def VMOVMSKPSr64r : PI<0x50, MRMSrcReg, (outs GR64:$dst), (ins VR128:$src),
2653              "movmskps\t{$src, $dst|$dst, $src}", [], SSEPackedSingle>, TB, VEX;
2654   def VMOVMSKPDr64r : PI<0x50, MRMSrcReg, (outs GR64:$dst), (ins VR128:$src),
2655              "movmskpd\t{$src, $dst|$dst, $src}", [], SSEPackedDouble>, TB,
2656              OpSize, VEX;
2657   def VMOVMSKPSYr64r : PI<0x50, MRMSrcReg, (outs GR64:$dst), (ins VR256:$src),
2658              "movmskps\t{$src, $dst|$dst, $src}", [], SSEPackedSingle>, TB, VEX;
2659   def VMOVMSKPDYr64r : PI<0x50, MRMSrcReg, (outs GR64:$dst), (ins VR256:$src),
2660              "movmskpd\t{$src, $dst|$dst, $src}", [], SSEPackedDouble>, TB,
2661              OpSize, VEX;
2662 }
2663
2664 defm MOVMSKPS : sse12_extr_sign_mask<VR128, int_x86_sse_movmsk_ps, "movmskps",
2665                                      SSEPackedSingle>, TB;
2666 defm MOVMSKPD : sse12_extr_sign_mask<VR128, int_x86_sse2_movmsk_pd, "movmskpd",
2667                                      SSEPackedDouble>, TB, OpSize;
2668
2669 def : Pat<(i32 (X86fgetsign FR32:$src)),
2670           (MOVMSKPSrr32 (INSERT_SUBREG (v4f32 (IMPLICIT_DEF)), FR32:$src,
2671                                        sub_ss))>, Requires<[HasSSE1]>;
2672 def : Pat<(i64 (X86fgetsign FR32:$src)),
2673           (MOVMSKPSrr64 (INSERT_SUBREG (v4f32 (IMPLICIT_DEF)), FR32:$src,
2674                                        sub_ss))>, Requires<[HasSSE1]>;
2675 def : Pat<(i32 (X86fgetsign FR64:$src)),
2676           (MOVMSKPDrr32 (INSERT_SUBREG (v2f64 (IMPLICIT_DEF)), FR64:$src,
2677                                        sub_sd))>, Requires<[HasSSE2]>;
2678 def : Pat<(i64 (X86fgetsign FR64:$src)),
2679           (MOVMSKPDrr64 (INSERT_SUBREG (v2f64 (IMPLICIT_DEF)), FR64:$src,
2680                                        sub_sd))>, Requires<[HasSSE2]>;
2681
2682 //===---------------------------------------------------------------------===//
2683 // SSE2 - Packed Integer Logical Instructions
2684 //===---------------------------------------------------------------------===//
2685
2686 let ExeDomain = SSEPackedInt in { // SSE integer instructions
2687
2688 /// PDI_binop_rm - Simple SSE2 binary operator.
2689 multiclass PDI_binop_rm<bits<8> opc, string OpcodeStr, SDNode OpNode,
2690                         ValueType OpVT, RegisterClass RC, PatFrag memop_frag,
2691                         X86MemOperand x86memop, bit IsCommutable = 0,
2692                         bit Is2Addr = 1> {
2693   let isCommutable = IsCommutable in
2694   def rr : PDI<opc, MRMSrcReg, (outs RC:$dst),
2695        (ins RC:$src1, RC:$src2),
2696        !if(Is2Addr,
2697            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
2698            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
2699        [(set RC:$dst, (OpVT (OpNode RC:$src1, RC:$src2)))]>;
2700   def rm : PDI<opc, MRMSrcMem, (outs RC:$dst),
2701        (ins RC:$src1, x86memop:$src2),
2702        !if(Is2Addr,
2703            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
2704            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
2705        [(set RC:$dst, (OpVT (OpNode RC:$src1,
2706                                      (bitconvert (memop_frag addr:$src2)))))]>;
2707 }
2708 } // ExeDomain = SSEPackedInt
2709
2710 // These are ordered here for pattern ordering requirements with the fp versions
2711
2712 let Predicates = [HasAVX] in {
2713 defm VPAND : PDI_binop_rm<0xDB, "vpand", and, v2i64, VR128, memopv2i64,
2714                           i128mem, 1, 0>, VEX_4V;
2715 defm VPOR  : PDI_binop_rm<0xEB, "vpor" , or, v2i64, VR128, memopv2i64,
2716                           i128mem, 1, 0>, VEX_4V;
2717 defm VPXOR : PDI_binop_rm<0xEF, "vpxor", xor, v2i64, VR128, memopv2i64,
2718                           i128mem, 1, 0>, VEX_4V;
2719 defm VPANDN : PDI_binop_rm<0xDF, "vpandn", X86andnp, v2i64, VR128, memopv2i64,
2720                           i128mem, 0, 0>, VEX_4V;
2721 }
2722
2723 let Constraints = "$src1 = $dst" in {
2724 defm PAND : PDI_binop_rm<0xDB, "pand", and, v2i64, VR128, memopv2i64,
2725                          i128mem, 1>;
2726 defm POR  : PDI_binop_rm<0xEB, "por" , or, v2i64, VR128, memopv2i64,
2727                          i128mem, 1>;
2728 defm PXOR : PDI_binop_rm<0xEF, "pxor", xor, v2i64, VR128, memopv2i64,
2729                          i128mem, 1>;
2730 defm PANDN : PDI_binop_rm<0xDF, "pandn", X86andnp, v2i64, VR128, memopv2i64,
2731                           i128mem, 0>;
2732 } // Constraints = "$src1 = $dst"
2733
2734 let Predicates = [HasAVX2] in {
2735 defm VPANDY : PDI_binop_rm<0xDB, "vpand", and, v4i64, VR256, memopv4i64,
2736                            i256mem, 1, 0>, VEX_4V;
2737 defm VPORY  : PDI_binop_rm<0xEB, "vpor", or, v4i64, VR256, memopv4i64,
2738                            i256mem, 1, 0>, VEX_4V;
2739 defm VPXORY : PDI_binop_rm<0xEF, "vpxor", xor, v4i64, VR256, memopv4i64,
2740                            i256mem, 1, 0>, VEX_4V;
2741 defm VPANDNY : PDI_binop_rm<0xDF, "vpandn", X86andnp, v4i64, VR256, memopv4i64,
2742                             i256mem, 0, 0>, VEX_4V;
2743 }
2744
2745 //===----------------------------------------------------------------------===//
2746 // SSE 1 & 2 - Logical Instructions
2747 //===----------------------------------------------------------------------===//
2748
2749 /// sse12_fp_alias_pack_logical - SSE 1 & 2 aliased packed FP logical ops
2750 ///
2751 multiclass sse12_fp_alias_pack_logical<bits<8> opc, string OpcodeStr,
2752                                        SDNode OpNode> {
2753   defm V#NAME#PS : sse12_fp_packed<opc, !strconcat(OpcodeStr, "ps"), OpNode,
2754               FR32, f32, f128mem, memopfsf32, SSEPackedSingle, 0>, TB, VEX_4V;
2755
2756   defm V#NAME#PD : sse12_fp_packed<opc, !strconcat(OpcodeStr, "pd"), OpNode,
2757         FR64, f64, f128mem, memopfsf64, SSEPackedDouble, 0>, TB, OpSize, VEX_4V;
2758
2759   let Constraints = "$src1 = $dst" in {
2760     defm PS : sse12_fp_packed<opc, !strconcat(OpcodeStr, "ps"), OpNode, FR32,
2761                 f32, f128mem, memopfsf32, SSEPackedSingle>, TB;
2762
2763     defm PD : sse12_fp_packed<opc, !strconcat(OpcodeStr, "pd"), OpNode, FR64,
2764                 f64, f128mem, memopfsf64, SSEPackedDouble>, TB, OpSize;
2765   }
2766 }
2767
2768 // Alias bitwise logical operations using SSE logical ops on packed FP values.
2769 let mayLoad = 0 in {
2770   defm FsAND  : sse12_fp_alias_pack_logical<0x54, "and", X86fand>;
2771   defm FsOR   : sse12_fp_alias_pack_logical<0x56, "or", X86for>;
2772   defm FsXOR  : sse12_fp_alias_pack_logical<0x57, "xor", X86fxor>;
2773 }
2774
2775 let neverHasSideEffects = 1, Pattern = []<dag>, isCommutable = 0 in
2776   defm FsANDN : sse12_fp_alias_pack_logical<0x55, "andn", undef>;
2777
2778 /// sse12_fp_packed_logical - SSE 1 & 2 packed FP logical ops
2779 ///
2780 multiclass sse12_fp_packed_logical<bits<8> opc, string OpcodeStr,
2781                                    SDNode OpNode> {
2782   // In AVX no need to add a pattern for 128-bit logical rr ps, because they
2783   // are all promoted to v2i64, and the patterns are covered by the int
2784   // version. This is needed in SSE only, because v2i64 isn't supported on
2785   // SSE1, but only on SSE2.
2786   defm V#NAME#PS : sse12_fp_packed_logical_rm<opc, VR128, SSEPackedSingle,
2787        !strconcat(OpcodeStr, "ps"), f128mem, [],
2788        [(set VR128:$dst, (OpNode (bc_v2i64 (v4f32 VR128:$src1)),
2789                                  (memopv2i64 addr:$src2)))], 0, 1>, TB, VEX_4V;
2790
2791   defm V#NAME#PD : sse12_fp_packed_logical_rm<opc, VR128, SSEPackedDouble,
2792        !strconcat(OpcodeStr, "pd"), f128mem,
2793        [(set VR128:$dst, (OpNode (bc_v2i64 (v2f64 VR128:$src1)),
2794                                  (bc_v2i64 (v2f64 VR128:$src2))))],
2795        [(set VR128:$dst, (OpNode (bc_v2i64 (v2f64 VR128:$src1)),
2796                                  (memopv2i64 addr:$src2)))], 0>,
2797                                                  TB, OpSize, VEX_4V;
2798   let Constraints = "$src1 = $dst" in {
2799     defm PS : sse12_fp_packed_logical_rm<opc, VR128, SSEPackedSingle,
2800          !strconcat(OpcodeStr, "ps"), f128mem,
2801          [(set VR128:$dst, (v2i64 (OpNode VR128:$src1, VR128:$src2)))],
2802          [(set VR128:$dst, (OpNode (bc_v2i64 (v4f32 VR128:$src1)),
2803                                    (memopv2i64 addr:$src2)))]>, TB;
2804
2805     defm PD : sse12_fp_packed_logical_rm<opc, VR128, SSEPackedDouble,
2806          !strconcat(OpcodeStr, "pd"), f128mem,
2807          [(set VR128:$dst, (OpNode (bc_v2i64 (v2f64 VR128:$src1)),
2808                                    (bc_v2i64 (v2f64 VR128:$src2))))],
2809          [(set VR128:$dst, (OpNode (bc_v2i64 (v2f64 VR128:$src1)),
2810                                    (memopv2i64 addr:$src2)))]>, TB, OpSize;
2811   }
2812 }
2813
2814 /// sse12_fp_packed_logical_y - AVX 256-bit SSE 1 & 2 logical ops forms
2815 ///
2816 multiclass sse12_fp_packed_logical_y<bits<8> opc, string OpcodeStr,
2817                                      SDNode OpNode> {
2818     defm PSY : sse12_fp_packed_logical_rm<opc, VR256, SSEPackedSingle,
2819           !strconcat(OpcodeStr, "ps"), f256mem,
2820           [(set VR256:$dst, (v4i64 (OpNode VR256:$src1, VR256:$src2)))],
2821           [(set VR256:$dst, (OpNode (bc_v4i64 (v8f32 VR256:$src1)),
2822                                     (memopv4i64 addr:$src2)))], 0>, TB, VEX_4V;
2823
2824     defm PDY : sse12_fp_packed_logical_rm<opc, VR256, SSEPackedDouble,
2825           !strconcat(OpcodeStr, "pd"), f256mem,
2826           [(set VR256:$dst, (OpNode (bc_v4i64 (v4f64 VR256:$src1)),
2827                                     (bc_v4i64 (v4f64 VR256:$src2))))],
2828           [(set VR256:$dst, (OpNode (bc_v4i64 (v4f64 VR256:$src1)),
2829                                     (memopv4i64 addr:$src2)))], 0>,
2830                                     TB, OpSize, VEX_4V;
2831 }
2832
2833 // AVX 256-bit packed logical ops forms
2834 defm VAND  : sse12_fp_packed_logical_y<0x54, "and", and>;
2835 defm VOR   : sse12_fp_packed_logical_y<0x56, "or", or>;
2836 defm VXOR  : sse12_fp_packed_logical_y<0x57, "xor", xor>;
2837 defm VANDN : sse12_fp_packed_logical_y<0x55, "andn", X86andnp>;
2838
2839 defm AND  : sse12_fp_packed_logical<0x54, "and", and>;
2840 defm OR   : sse12_fp_packed_logical<0x56, "or", or>;
2841 defm XOR  : sse12_fp_packed_logical<0x57, "xor", xor>;
2842 let isCommutable = 0 in
2843   defm ANDN : sse12_fp_packed_logical<0x55, "andn", X86andnp>;
2844
2845 //===----------------------------------------------------------------------===//
2846 // SSE 1 & 2 - Arithmetic Instructions
2847 //===----------------------------------------------------------------------===//
2848
2849 /// basic_sse12_fp_binop_xxx - SSE 1 & 2 binops come in both scalar and
2850 /// vector forms.
2851 ///
2852 /// In addition, we also have a special variant of the scalar form here to
2853 /// represent the associated intrinsic operation.  This form is unlike the
2854 /// plain scalar form, in that it takes an entire vector (instead of a scalar)
2855 /// and leaves the top elements unmodified (therefore these cannot be commuted).
2856 ///
2857 /// These three forms can each be reg+reg or reg+mem.
2858 ///
2859
2860 /// FIXME: once all 256-bit intrinsics are matched, cleanup and refactor those
2861 /// classes below
2862 multiclass basic_sse12_fp_binop_s<bits<8> opc, string OpcodeStr, SDNode OpNode,
2863                                   bit Is2Addr = 1> {
2864   defm SS : sse12_fp_scalar<opc, !strconcat(OpcodeStr, "ss"),
2865                             OpNode, FR32, f32mem, Is2Addr>, XS;
2866   defm SD : sse12_fp_scalar<opc, !strconcat(OpcodeStr, "sd"),
2867                             OpNode, FR64, f64mem, Is2Addr>, XD;
2868 }
2869
2870 multiclass basic_sse12_fp_binop_p<bits<8> opc, string OpcodeStr, SDNode OpNode,
2871                                    bit Is2Addr = 1> {
2872   let mayLoad = 0 in {
2873   defm PS : sse12_fp_packed<opc, !strconcat(OpcodeStr, "ps"), OpNode, VR128,
2874               v4f32, f128mem, memopv4f32, SSEPackedSingle, Is2Addr>, TB;
2875   defm PD : sse12_fp_packed<opc, !strconcat(OpcodeStr, "pd"), OpNode, VR128,
2876               v2f64, f128mem, memopv2f64, SSEPackedDouble, Is2Addr>, TB, OpSize;
2877   }
2878 }
2879
2880 multiclass basic_sse12_fp_binop_p_y<bits<8> opc, string OpcodeStr,
2881                                     SDNode OpNode> {
2882   let mayLoad = 0 in {
2883     defm PSY : sse12_fp_packed<opc, !strconcat(OpcodeStr, "ps"), OpNode, VR256,
2884                 v8f32, f256mem, memopv8f32, SSEPackedSingle, 0>, TB;
2885     defm PDY : sse12_fp_packed<opc, !strconcat(OpcodeStr, "pd"), OpNode, VR256,
2886                 v4f64, f256mem, memopv4f64, SSEPackedDouble, 0>, TB, OpSize;
2887   }
2888 }
2889
2890 multiclass basic_sse12_fp_binop_s_int<bits<8> opc, string OpcodeStr,
2891                                       bit Is2Addr = 1> {
2892   defm SS : sse12_fp_scalar_int<opc, OpcodeStr, VR128,
2893      !strconcat(OpcodeStr, "ss"), "", "_ss", ssmem, sse_load_f32, Is2Addr>, XS;
2894   defm SD : sse12_fp_scalar_int<opc, OpcodeStr, VR128,
2895      !strconcat(OpcodeStr, "sd"), "2", "_sd", sdmem, sse_load_f64, Is2Addr>, XD;
2896 }
2897
2898 multiclass basic_sse12_fp_binop_p_int<bits<8> opc, string OpcodeStr,
2899                                       bit Is2Addr = 1> {
2900   defm PS : sse12_fp_packed_int<opc, OpcodeStr, VR128,
2901      !strconcat(OpcodeStr, "ps"), "sse", "_ps", f128mem, memopv4f32,
2902                                               SSEPackedSingle, Is2Addr>, TB;
2903
2904   defm PD : sse12_fp_packed_int<opc, OpcodeStr, VR128,
2905      !strconcat(OpcodeStr, "pd"), "sse2", "_pd", f128mem, memopv2f64,
2906                                       SSEPackedDouble, Is2Addr>, TB, OpSize;
2907 }
2908
2909 multiclass basic_sse12_fp_binop_p_y_int<bits<8> opc, string OpcodeStr> {
2910   defm PSY : sse12_fp_packed_int<opc, OpcodeStr, VR256,
2911      !strconcat(OpcodeStr, "ps"), "avx", "_ps_256", f256mem, memopv8f32,
2912       SSEPackedSingle, 0>, TB;
2913
2914   defm PDY : sse12_fp_packed_int<opc, OpcodeStr, VR256,
2915      !strconcat(OpcodeStr, "pd"), "avx", "_pd_256", f256mem, memopv4f64,
2916       SSEPackedDouble, 0>, TB, OpSize;
2917 }
2918
2919 // Binary Arithmetic instructions
2920 defm VADD : basic_sse12_fp_binop_s<0x58, "add", fadd, 0>,
2921             basic_sse12_fp_binop_s_int<0x58, "add", 0>, VEX_4V, VEX_LIG;
2922 defm VADD : basic_sse12_fp_binop_p<0x58, "add", fadd, 0>,
2923             basic_sse12_fp_binop_p_y<0x58, "add", fadd>, VEX_4V;
2924 defm VMUL : basic_sse12_fp_binop_s<0x59, "mul", fmul, 0>,
2925             basic_sse12_fp_binop_s_int<0x59, "mul", 0>, VEX_4V, VEX_LIG;
2926 defm VMUL : basic_sse12_fp_binop_p<0x59, "mul", fmul, 0>,
2927             basic_sse12_fp_binop_p_y<0x59, "mul", fmul>, VEX_4V;
2928
2929 let isCommutable = 0 in {
2930   defm VSUB : basic_sse12_fp_binop_s<0x5C, "sub", fsub, 0>,
2931               basic_sse12_fp_binop_s_int<0x5C, "sub", 0>, VEX_4V, VEX_LIG;
2932   defm VSUB : basic_sse12_fp_binop_p<0x5C, "sub", fsub, 0>,
2933               basic_sse12_fp_binop_p_y<0x5C, "sub", fsub>, VEX_4V;
2934   defm VDIV : basic_sse12_fp_binop_s<0x5E, "div", fdiv, 0>,
2935               basic_sse12_fp_binop_s_int<0x5E, "div", 0>, VEX_4V, VEX_LIG;
2936   defm VDIV : basic_sse12_fp_binop_p<0x5E, "div", fdiv, 0>,
2937               basic_sse12_fp_binop_p_y<0x5E, "div", fdiv>, VEX_4V;
2938   defm VMAX : basic_sse12_fp_binop_s<0x5F, "max", X86fmax, 0>,
2939               basic_sse12_fp_binop_s_int<0x5F, "max", 0>, VEX_4V, VEX_LIG;
2940   defm VMAX : basic_sse12_fp_binop_p<0x5F, "max", X86fmax, 0>,
2941               basic_sse12_fp_binop_p_int<0x5F, "max", 0>,
2942               basic_sse12_fp_binop_p_y<0x5F, "max", X86fmax>,
2943               basic_sse12_fp_binop_p_y_int<0x5F, "max">, VEX_4V;
2944   defm VMIN : basic_sse12_fp_binop_s<0x5D, "min", X86fmin, 0>,
2945               basic_sse12_fp_binop_s_int<0x5D, "min", 0>, VEX_4V, VEX_LIG;
2946   defm VMIN : basic_sse12_fp_binop_p<0x5D, "min", X86fmin, 0>,
2947               basic_sse12_fp_binop_p_int<0x5D, "min", 0>,
2948               basic_sse12_fp_binop_p_y_int<0x5D, "min">,
2949               basic_sse12_fp_binop_p_y<0x5D, "min", X86fmin>, VEX_4V;
2950 }
2951
2952 let Constraints = "$src1 = $dst" in {
2953   defm ADD : basic_sse12_fp_binop_s<0x58, "add", fadd>,
2954              basic_sse12_fp_binop_p<0x58, "add", fadd>,
2955              basic_sse12_fp_binop_s_int<0x58, "add">;
2956   defm MUL : basic_sse12_fp_binop_s<0x59, "mul", fmul>,
2957              basic_sse12_fp_binop_p<0x59, "mul", fmul>,
2958              basic_sse12_fp_binop_s_int<0x59, "mul">;
2959
2960   let isCommutable = 0 in {
2961     defm SUB : basic_sse12_fp_binop_s<0x5C, "sub", fsub>,
2962                basic_sse12_fp_binop_p<0x5C, "sub", fsub>,
2963                basic_sse12_fp_binop_s_int<0x5C, "sub">;
2964     defm DIV : basic_sse12_fp_binop_s<0x5E, "div", fdiv>,
2965                basic_sse12_fp_binop_p<0x5E, "div", fdiv>,
2966                basic_sse12_fp_binop_s_int<0x5E, "div">;
2967     defm MAX : basic_sse12_fp_binop_s<0x5F, "max", X86fmax>,
2968                basic_sse12_fp_binop_p<0x5F, "max", X86fmax>,
2969                basic_sse12_fp_binop_s_int<0x5F, "max">,
2970                basic_sse12_fp_binop_p_int<0x5F, "max">;
2971     defm MIN : basic_sse12_fp_binop_s<0x5D, "min", X86fmin>,
2972                basic_sse12_fp_binop_p<0x5D, "min", X86fmin>,
2973                basic_sse12_fp_binop_s_int<0x5D, "min">,
2974                basic_sse12_fp_binop_p_int<0x5D, "min">;
2975   }
2976 }
2977
2978 /// Unop Arithmetic
2979 /// In addition, we also have a special variant of the scalar form here to
2980 /// represent the associated intrinsic operation.  This form is unlike the
2981 /// plain scalar form, in that it takes an entire vector (instead of a
2982 /// scalar) and leaves the top elements undefined.
2983 ///
2984 /// And, we have a special variant form for a full-vector intrinsic form.
2985
2986 /// sse1_fp_unop_s - SSE1 unops in scalar form.
2987 multiclass sse1_fp_unop_s<bits<8> opc, string OpcodeStr,
2988                           SDNode OpNode, Intrinsic F32Int> {
2989   def SSr : SSI<opc, MRMSrcReg, (outs FR32:$dst), (ins FR32:$src),
2990                 !strconcat(OpcodeStr, "ss\t{$src, $dst|$dst, $src}"),
2991                 [(set FR32:$dst, (OpNode FR32:$src))]>;
2992   // For scalar unary operations, fold a load into the operation
2993   // only in OptForSize mode. It eliminates an instruction, but it also
2994   // eliminates a whole-register clobber (the load), so it introduces a
2995   // partial register update condition.
2996   def SSm : I<opc, MRMSrcMem, (outs FR32:$dst), (ins f32mem:$src),
2997                 !strconcat(OpcodeStr, "ss\t{$src, $dst|$dst, $src}"),
2998                 [(set FR32:$dst, (OpNode (load addr:$src)))]>, XS,
2999             Requires<[HasSSE1, OptForSize]>;
3000   def SSr_Int : SSI<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3001                     !strconcat(OpcodeStr, "ss\t{$src, $dst|$dst, $src}"),
3002                     [(set VR128:$dst, (F32Int VR128:$src))]>;
3003   def SSm_Int : SSI<opc, MRMSrcMem, (outs VR128:$dst), (ins ssmem:$src),
3004                     !strconcat(OpcodeStr, "ss\t{$src, $dst|$dst, $src}"),
3005                     [(set VR128:$dst, (F32Int sse_load_f32:$src))]>;
3006 }
3007
3008 /// sse1_fp_unop_s_avx - AVX SSE1 unops in scalar form.
3009 multiclass sse1_fp_unop_s_avx<bits<8> opc, string OpcodeStr> {
3010   def SSr : SSI<opc, MRMSrcReg, (outs FR32:$dst), (ins FR32:$src1, FR32:$src2),
3011                 !strconcat(OpcodeStr,
3012                            "ss\t{$src2, $src1, $dst|$dst, $src1, $src2}"), []>;
3013   let mayLoad = 1 in
3014   def SSm : SSI<opc, MRMSrcMem, (outs FR32:$dst), (ins FR32:$src1,f32mem:$src2),
3015                 !strconcat(OpcodeStr,
3016                            "ss\t{$src2, $src1, $dst|$dst, $src1, $src2}"), []>;
3017   def SSm_Int : SSI<opc, MRMSrcMem, (outs VR128:$dst),
3018                 (ins VR128:$src1, ssmem:$src2),
3019                 !strconcat(OpcodeStr,
3020                            "ss\t{$src2, $src1, $dst|$dst, $src1, $src2}"), []>;
3021 }
3022
3023 /// sse1_fp_unop_p - SSE1 unops in packed form.
3024 multiclass sse1_fp_unop_p<bits<8> opc, string OpcodeStr, SDNode OpNode> {
3025   def PSr : PSI<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3026               !strconcat(OpcodeStr, "ps\t{$src, $dst|$dst, $src}"),
3027               [(set VR128:$dst, (v4f32 (OpNode VR128:$src)))]>;
3028   def PSm : PSI<opc, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
3029                 !strconcat(OpcodeStr, "ps\t{$src, $dst|$dst, $src}"),
3030                 [(set VR128:$dst, (OpNode (memopv4f32 addr:$src)))]>;
3031 }
3032
3033 /// sse1_fp_unop_p_y - AVX 256-bit SSE1 unops in packed form.
3034 multiclass sse1_fp_unop_p_y<bits<8> opc, string OpcodeStr, SDNode OpNode> {
3035   def PSYr : PSI<opc, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
3036               !strconcat(OpcodeStr, "ps\t{$src, $dst|$dst, $src}"),
3037               [(set VR256:$dst, (v8f32 (OpNode VR256:$src)))]>;
3038   def PSYm : PSI<opc, MRMSrcMem, (outs VR256:$dst), (ins f256mem:$src),
3039                 !strconcat(OpcodeStr, "ps\t{$src, $dst|$dst, $src}"),
3040                 [(set VR256:$dst, (OpNode (memopv8f32 addr:$src)))]>;
3041 }
3042
3043 /// sse1_fp_unop_p_int - SSE1 intrinsics unops in packed forms.
3044 multiclass sse1_fp_unop_p_int<bits<8> opc, string OpcodeStr,
3045                               Intrinsic V4F32Int> {
3046   def PSr_Int : PSI<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3047                     !strconcat(OpcodeStr, "ps\t{$src, $dst|$dst, $src}"),
3048                     [(set VR128:$dst, (V4F32Int VR128:$src))]>;
3049   def PSm_Int : PSI<opc, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
3050                     !strconcat(OpcodeStr, "ps\t{$src, $dst|$dst, $src}"),
3051                     [(set VR128:$dst, (V4F32Int (memopv4f32 addr:$src)))]>;
3052 }
3053
3054 /// sse1_fp_unop_p_y_int - AVX 256-bit intrinsics unops in packed forms.
3055 multiclass sse1_fp_unop_p_y_int<bits<8> opc, string OpcodeStr,
3056                                 Intrinsic V4F32Int> {
3057   def PSYr_Int : PSI<opc, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
3058                     !strconcat(OpcodeStr, "ps\t{$src, $dst|$dst, $src}"),
3059                     [(set VR256:$dst, (V4F32Int VR256:$src))]>;
3060   def PSYm_Int : PSI<opc, MRMSrcMem, (outs VR256:$dst), (ins f256mem:$src),
3061                     !strconcat(OpcodeStr, "ps\t{$src, $dst|$dst, $src}"),
3062                     [(set VR256:$dst, (V4F32Int (memopv8f32 addr:$src)))]>;
3063 }
3064
3065 /// sse2_fp_unop_s - SSE2 unops in scalar form.
3066 multiclass sse2_fp_unop_s<bits<8> opc, string OpcodeStr,
3067                           SDNode OpNode, Intrinsic F64Int> {
3068   def SDr : SDI<opc, MRMSrcReg, (outs FR64:$dst), (ins FR64:$src),
3069                 !strconcat(OpcodeStr, "sd\t{$src, $dst|$dst, $src}"),
3070                 [(set FR64:$dst, (OpNode FR64:$src))]>;
3071   // See the comments in sse1_fp_unop_s for why this is OptForSize.
3072   def SDm : I<opc, MRMSrcMem, (outs FR64:$dst), (ins f64mem:$src),
3073                 !strconcat(OpcodeStr, "sd\t{$src, $dst|$dst, $src}"),
3074                 [(set FR64:$dst, (OpNode (load addr:$src)))]>, XD,
3075             Requires<[HasSSE2, OptForSize]>;
3076   def SDr_Int : SDI<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3077                     !strconcat(OpcodeStr, "sd\t{$src, $dst|$dst, $src}"),
3078                     [(set VR128:$dst, (F64Int VR128:$src))]>;
3079   def SDm_Int : SDI<opc, MRMSrcMem, (outs VR128:$dst), (ins sdmem:$src),
3080                     !strconcat(OpcodeStr, "sd\t{$src, $dst|$dst, $src}"),
3081                     [(set VR128:$dst, (F64Int sse_load_f64:$src))]>;
3082 }
3083
3084 /// sse2_fp_unop_s_avx - AVX SSE2 unops in scalar form.
3085 multiclass sse2_fp_unop_s_avx<bits<8> opc, string OpcodeStr> {
3086   let neverHasSideEffects = 1 in {
3087   def SDr : SDI<opc, MRMSrcReg, (outs FR64:$dst), (ins FR64:$src1, FR64:$src2),
3088                !strconcat(OpcodeStr,
3089                           "sd\t{$src2, $src1, $dst|$dst, $src1, $src2}"), []>;
3090   let mayLoad = 1 in
3091   def SDm : SDI<opc, MRMSrcMem, (outs FR64:$dst), (ins FR64:$src1,f64mem:$src2),
3092                !strconcat(OpcodeStr,
3093                           "sd\t{$src2, $src1, $dst|$dst, $src1, $src2}"), []>;
3094   }
3095   def SDm_Int : SDI<opc, MRMSrcMem, (outs VR128:$dst),
3096                (ins VR128:$src1, sdmem:$src2),
3097                !strconcat(OpcodeStr,
3098                           "sd\t{$src2, $src1, $dst|$dst, $src1, $src2}"), []>;
3099 }
3100
3101 /// sse2_fp_unop_p - SSE2 unops in vector forms.
3102 multiclass sse2_fp_unop_p<bits<8> opc, string OpcodeStr,
3103                           SDNode OpNode> {
3104   def PDr : PDI<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3105               !strconcat(OpcodeStr, "pd\t{$src, $dst|$dst, $src}"),
3106               [(set VR128:$dst, (v2f64 (OpNode VR128:$src)))]>;
3107   def PDm : PDI<opc, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
3108                 !strconcat(OpcodeStr, "pd\t{$src, $dst|$dst, $src}"),
3109                 [(set VR128:$dst, (OpNode (memopv2f64 addr:$src)))]>;
3110 }
3111
3112 /// sse2_fp_unop_p_y - AVX SSE2 256-bit unops in vector forms.
3113 multiclass sse2_fp_unop_p_y<bits<8> opc, string OpcodeStr, SDNode OpNode> {
3114   def PDYr : PDI<opc, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
3115               !strconcat(OpcodeStr, "pd\t{$src, $dst|$dst, $src}"),
3116               [(set VR256:$dst, (v4f64 (OpNode VR256:$src)))]>;
3117   def PDYm : PDI<opc, MRMSrcMem, (outs VR256:$dst), (ins f256mem:$src),
3118                 !strconcat(OpcodeStr, "pd\t{$src, $dst|$dst, $src}"),
3119                 [(set VR256:$dst, (OpNode (memopv4f64 addr:$src)))]>;
3120 }
3121
3122 /// sse2_fp_unop_p_int - SSE2 intrinsic unops in vector forms.
3123 multiclass sse2_fp_unop_p_int<bits<8> opc, string OpcodeStr,
3124                               Intrinsic V2F64Int> {
3125   def PDr_Int : PDI<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3126                     !strconcat(OpcodeStr, "pd\t{$src, $dst|$dst, $src}"),
3127                     [(set VR128:$dst, (V2F64Int VR128:$src))]>;
3128   def PDm_Int : PDI<opc, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
3129                     !strconcat(OpcodeStr, "pd\t{$src, $dst|$dst, $src}"),
3130                     [(set VR128:$dst, (V2F64Int (memopv2f64 addr:$src)))]>;
3131 }
3132
3133 /// sse2_fp_unop_p_y_int - AVX 256-bit intrinsic unops in vector forms.
3134 multiclass sse2_fp_unop_p_y_int<bits<8> opc, string OpcodeStr,
3135                                 Intrinsic V2F64Int> {
3136   def PDYr_Int : PDI<opc, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
3137                     !strconcat(OpcodeStr, "pd\t{$src, $dst|$dst, $src}"),
3138                     [(set VR256:$dst, (V2F64Int VR256:$src))]>;
3139   def PDYm_Int : PDI<opc, MRMSrcMem, (outs VR256:$dst), (ins f256mem:$src),
3140                     !strconcat(OpcodeStr, "pd\t{$src, $dst|$dst, $src}"),
3141                     [(set VR256:$dst, (V2F64Int (memopv4f64 addr:$src)))]>;
3142 }
3143
3144 let Predicates = [HasAVX] in {
3145   // Square root.
3146   defm VSQRT  : sse1_fp_unop_s_avx<0x51, "vsqrt">,
3147                 sse2_fp_unop_s_avx<0x51, "vsqrt">, VEX_4V, VEX_LIG;
3148
3149   defm VSQRT  : sse1_fp_unop_p<0x51, "vsqrt", fsqrt>,
3150                 sse2_fp_unop_p<0x51, "vsqrt", fsqrt>,
3151                 sse1_fp_unop_p_y<0x51, "vsqrt", fsqrt>,
3152                 sse2_fp_unop_p_y<0x51, "vsqrt", fsqrt>,
3153                 sse1_fp_unop_p_int<0x51, "vsqrt", int_x86_sse_sqrt_ps>,
3154                 sse2_fp_unop_p_int<0x51, "vsqrt", int_x86_sse2_sqrt_pd>,
3155                 sse1_fp_unop_p_y_int<0x51, "vsqrt", int_x86_avx_sqrt_ps_256>,
3156                 sse2_fp_unop_p_y_int<0x51, "vsqrt", int_x86_avx_sqrt_pd_256>,
3157                 VEX;
3158
3159   // Reciprocal approximations. Note that these typically require refinement
3160   // in order to obtain suitable precision.
3161   defm VRSQRT : sse1_fp_unop_s_avx<0x52, "vrsqrt">, VEX_4V, VEX_LIG;
3162   defm VRSQRT : sse1_fp_unop_p<0x52, "vrsqrt", X86frsqrt>,
3163                 sse1_fp_unop_p_y<0x52, "vrsqrt", X86frsqrt>,
3164                 sse1_fp_unop_p_y_int<0x52, "vrsqrt", int_x86_avx_rsqrt_ps_256>,
3165                 sse1_fp_unop_p_int<0x52, "vrsqrt", int_x86_sse_rsqrt_ps>, VEX;
3166
3167   defm VRCP   : sse1_fp_unop_s_avx<0x53, "vrcp">, VEX_4V, VEX_LIG;
3168   defm VRCP   : sse1_fp_unop_p<0x53, "vrcp", X86frcp>,
3169                 sse1_fp_unop_p_y<0x53, "vrcp", X86frcp>,
3170                 sse1_fp_unop_p_y_int<0x53, "vrcp", int_x86_avx_rcp_ps_256>,
3171                 sse1_fp_unop_p_int<0x53, "vrcp", int_x86_sse_rcp_ps>, VEX;
3172 }
3173
3174 let AddedComplexity = 1 in {
3175 def : Pat<(f32 (fsqrt FR32:$src)),
3176           (VSQRTSSr (f32 (IMPLICIT_DEF)), FR32:$src)>, Requires<[HasAVX]>;
3177 def : Pat<(f32 (fsqrt (load addr:$src))),
3178           (VSQRTSSm (f32 (IMPLICIT_DEF)), addr:$src)>,
3179           Requires<[HasAVX, OptForSize]>;
3180 def : Pat<(f64 (fsqrt FR64:$src)),
3181           (VSQRTSDr (f64 (IMPLICIT_DEF)), FR64:$src)>, Requires<[HasAVX]>;
3182 def : Pat<(f64 (fsqrt (load addr:$src))),
3183           (VSQRTSDm (f64 (IMPLICIT_DEF)), addr:$src)>,
3184           Requires<[HasAVX, OptForSize]>;
3185
3186 def : Pat<(f32 (X86frsqrt FR32:$src)),
3187           (VRSQRTSSr (f32 (IMPLICIT_DEF)), FR32:$src)>, Requires<[HasAVX]>;
3188 def : Pat<(f32 (X86frsqrt (load addr:$src))),
3189           (VRSQRTSSm (f32 (IMPLICIT_DEF)), addr:$src)>,
3190           Requires<[HasAVX, OptForSize]>;
3191
3192 def : Pat<(f32 (X86frcp FR32:$src)),
3193           (VRCPSSr (f32 (IMPLICIT_DEF)), FR32:$src)>, Requires<[HasAVX]>;
3194 def : Pat<(f32 (X86frcp (load addr:$src))),
3195           (VRCPSSm (f32 (IMPLICIT_DEF)), addr:$src)>,
3196           Requires<[HasAVX, OptForSize]>;
3197 }
3198
3199 let Predicates = [HasAVX], AddedComplexity = 1 in {
3200   def : Pat<(int_x86_sse_sqrt_ss VR128:$src),
3201             (INSERT_SUBREG (v4f32 (IMPLICIT_DEF)),
3202                 (VSQRTSSr (f32 (IMPLICIT_DEF)),
3203                           (EXTRACT_SUBREG (v4f32 VR128:$src), sub_ss)),
3204                 sub_ss)>;
3205   def : Pat<(int_x86_sse_sqrt_ss sse_load_f32:$src),
3206             (VSQRTSSm_Int (v4f32 (IMPLICIT_DEF)), sse_load_f32:$src)>;
3207
3208   def : Pat<(int_x86_sse2_sqrt_sd VR128:$src),
3209             (INSERT_SUBREG (v2f64 (IMPLICIT_DEF)),
3210                 (VSQRTSDr (f64 (IMPLICIT_DEF)),
3211                           (EXTRACT_SUBREG (v2f64 VR128:$src), sub_sd)),
3212                 sub_sd)>;
3213   def : Pat<(int_x86_sse2_sqrt_sd sse_load_f64:$src),
3214             (VSQRTSDm_Int (v2f64 (IMPLICIT_DEF)), sse_load_f64:$src)>;
3215
3216   def : Pat<(int_x86_sse_rsqrt_ss VR128:$src),
3217             (INSERT_SUBREG (v4f32 (IMPLICIT_DEF)),
3218                 (VRSQRTSSr (f32 (IMPLICIT_DEF)),
3219                           (EXTRACT_SUBREG (v4f32 VR128:$src), sub_ss)),
3220                 sub_ss)>;
3221   def : Pat<(int_x86_sse_rsqrt_ss sse_load_f32:$src),
3222             (VRSQRTSSm_Int (v4f32 (IMPLICIT_DEF)), sse_load_f32:$src)>;
3223
3224   def : Pat<(int_x86_sse_rcp_ss VR128:$src),
3225             (INSERT_SUBREG (v4f32 (IMPLICIT_DEF)),
3226                 (VRCPSSr (f32 (IMPLICIT_DEF)),
3227                          (EXTRACT_SUBREG (v4f32 VR128:$src), sub_ss)),
3228                 sub_ss)>;
3229   def : Pat<(int_x86_sse_rcp_ss sse_load_f32:$src),
3230             (VRCPSSm_Int (v4f32 (IMPLICIT_DEF)), sse_load_f32:$src)>;
3231 }
3232
3233 // Square root.
3234 defm SQRT  : sse1_fp_unop_s<0x51, "sqrt",  fsqrt, int_x86_sse_sqrt_ss>,
3235              sse1_fp_unop_p<0x51, "sqrt",  fsqrt>,
3236              sse1_fp_unop_p_int<0x51, "sqrt",  int_x86_sse_sqrt_ps>,
3237              sse2_fp_unop_s<0x51, "sqrt",  fsqrt, int_x86_sse2_sqrt_sd>,
3238              sse2_fp_unop_p<0x51, "sqrt",  fsqrt>,
3239              sse2_fp_unop_p_int<0x51, "sqrt", int_x86_sse2_sqrt_pd>;
3240
3241 // Reciprocal approximations. Note that these typically require refinement
3242 // in order to obtain suitable precision.
3243 defm RSQRT : sse1_fp_unop_s<0x52, "rsqrt", X86frsqrt, int_x86_sse_rsqrt_ss>,
3244              sse1_fp_unop_p<0x52, "rsqrt", X86frsqrt>,
3245              sse1_fp_unop_p_int<0x52, "rsqrt", int_x86_sse_rsqrt_ps>;
3246 defm RCP   : sse1_fp_unop_s<0x53, "rcp", X86frcp, int_x86_sse_rcp_ss>,
3247              sse1_fp_unop_p<0x53, "rcp", X86frcp>,
3248              sse1_fp_unop_p_int<0x53, "rcp", int_x86_sse_rcp_ps>;
3249
3250 // There is no f64 version of the reciprocal approximation instructions.
3251
3252 //===----------------------------------------------------------------------===//
3253 // SSE 1 & 2 - Non-temporal stores
3254 //===----------------------------------------------------------------------===//
3255
3256 let AddedComplexity = 400 in { // Prefer non-temporal versions
3257   def VMOVNTPSmr : VPSI<0x2B, MRMDestMem, (outs),
3258                        (ins f128mem:$dst, VR128:$src),
3259                        "movntps\t{$src, $dst|$dst, $src}",
3260                        [(alignednontemporalstore (v4f32 VR128:$src),
3261                                                  addr:$dst)]>, VEX;
3262   def VMOVNTPDmr : VPDI<0x2B, MRMDestMem, (outs),
3263                        (ins f128mem:$dst, VR128:$src),
3264                        "movntpd\t{$src, $dst|$dst, $src}",
3265                        [(alignednontemporalstore (v2f64 VR128:$src),
3266                                                  addr:$dst)]>, VEX;
3267
3268   let ExeDomain = SSEPackedInt in
3269   def VMOVNTDQmr    : VPDI<0xE7, MRMDestMem, (outs),
3270                            (ins f128mem:$dst, VR128:$src),
3271                            "movntdq\t{$src, $dst|$dst, $src}",
3272                            [(alignednontemporalstore (v2i64 VR128:$src),
3273                                                      addr:$dst)]>, VEX;
3274
3275   def : Pat<(alignednontemporalstore (v2i64 VR128:$src), addr:$dst),
3276             (VMOVNTDQmr addr:$dst, VR128:$src)>, Requires<[HasAVX]>;
3277
3278   def VMOVNTPSYmr : VPSI<0x2B, MRMDestMem, (outs),
3279                        (ins f256mem:$dst, VR256:$src),
3280                        "movntps\t{$src, $dst|$dst, $src}",
3281                        [(alignednontemporalstore (v8f32 VR256:$src),
3282                                                  addr:$dst)]>, VEX;
3283   def VMOVNTPDYmr : VPDI<0x2B, MRMDestMem, (outs),
3284                        (ins f256mem:$dst, VR256:$src),
3285                        "movntpd\t{$src, $dst|$dst, $src}",
3286                        [(alignednontemporalstore (v4f64 VR256:$src),
3287                                                  addr:$dst)]>, VEX;
3288   let ExeDomain = SSEPackedInt in
3289   def VMOVNTDQYmr : VPDI<0xE7, MRMDestMem, (outs),
3290                       (ins f256mem:$dst, VR256:$src),
3291                       "movntdq\t{$src, $dst|$dst, $src}",
3292                       [(alignednontemporalstore (v4i64 VR256:$src),
3293                                                 addr:$dst)]>, VEX;
3294 }
3295
3296 def : Pat<(int_x86_avx_movnt_dq_256 addr:$dst, VR256:$src),
3297           (VMOVNTDQYmr addr:$dst, VR256:$src)>;
3298 def : Pat<(int_x86_avx_movnt_pd_256 addr:$dst, VR256:$src),
3299           (VMOVNTPDYmr addr:$dst, VR256:$src)>;
3300 def : Pat<(int_x86_avx_movnt_ps_256 addr:$dst, VR256:$src),
3301           (VMOVNTPSYmr addr:$dst, VR256:$src)>;
3302
3303 let AddedComplexity = 400 in { // Prefer non-temporal versions
3304 def MOVNTPSmr : PSI<0x2B, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
3305                     "movntps\t{$src, $dst|$dst, $src}",
3306                     [(alignednontemporalstore (v4f32 VR128:$src), addr:$dst)]>;
3307 def MOVNTPDmr : PDI<0x2B, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
3308                     "movntpd\t{$src, $dst|$dst, $src}",
3309                     [(alignednontemporalstore(v2f64 VR128:$src), addr:$dst)]>;
3310
3311 let ExeDomain = SSEPackedInt in
3312 def MOVNTDQmr : PDI<0xE7, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
3313                     "movntdq\t{$src, $dst|$dst, $src}",
3314                     [(alignednontemporalstore (v2i64 VR128:$src), addr:$dst)]>;
3315
3316 def : Pat<(alignednontemporalstore (v2i64 VR128:$src), addr:$dst),
3317           (MOVNTDQmr addr:$dst, VR128:$src)>, Requires<[HasSSE2]>;
3318
3319 // There is no AVX form for instructions below this point
3320 def MOVNTImr : I<0xC3, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
3321                  "movnti{l}\t{$src, $dst|$dst, $src}",
3322                  [(nontemporalstore (i32 GR32:$src), addr:$dst)]>,
3323                TB, Requires<[HasSSE2]>;
3324 def MOVNTI_64mr : RI<0xC3, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
3325                      "movnti{q}\t{$src, $dst|$dst, $src}",
3326                      [(nontemporalstore (i64 GR64:$src), addr:$dst)]>,
3327                   TB, Requires<[HasSSE2]>;
3328 }
3329
3330 //===----------------------------------------------------------------------===//
3331 // SSE 1 & 2 - Prefetch and memory fence
3332 //===----------------------------------------------------------------------===//
3333
3334 // Prefetch intrinsic.
3335 let Predicates = [HasSSE1] in {
3336 def PREFETCHT0   : I<0x18, MRM1m, (outs), (ins i8mem:$src),
3337     "prefetcht0\t$src", [(prefetch addr:$src, imm, (i32 3), (i32 1))]>, TB;
3338 def PREFETCHT1   : I<0x18, MRM2m, (outs), (ins i8mem:$src),
3339     "prefetcht1\t$src", [(prefetch addr:$src, imm, (i32 2), (i32 1))]>, TB;
3340 def PREFETCHT2   : I<0x18, MRM3m, (outs), (ins i8mem:$src),
3341     "prefetcht2\t$src", [(prefetch addr:$src, imm, (i32 1), (i32 1))]>, TB;
3342 def PREFETCHNTA  : I<0x18, MRM0m, (outs), (ins i8mem:$src),
3343     "prefetchnta\t$src", [(prefetch addr:$src, imm, (i32 0), (i32 1))]>, TB;
3344 }
3345
3346 // Flush cache
3347 def CLFLUSH : I<0xAE, MRM7m, (outs), (ins i8mem:$src),
3348                "clflush\t$src", [(int_x86_sse2_clflush addr:$src)]>,
3349               TB, Requires<[HasSSE2]>;
3350
3351 // Pause. This "instruction" is encoded as "rep; nop", so even though it
3352 // was introduced with SSE2, it's backward compatible.
3353 def PAUSE : I<0x90, RawFrm, (outs), (ins), "pause", []>, REP;
3354
3355 // Load, store, and memory fence
3356 def SFENCE : I<0xAE, MRM_F8, (outs), (ins),
3357                "sfence", [(int_x86_sse_sfence)]>, TB, Requires<[HasSSE1]>;
3358 def LFENCE : I<0xAE, MRM_E8, (outs), (ins),
3359                "lfence", [(int_x86_sse2_lfence)]>, TB, Requires<[HasSSE2]>;
3360 def MFENCE : I<0xAE, MRM_F0, (outs), (ins),
3361                "mfence", [(int_x86_sse2_mfence)]>, TB, Requires<[HasSSE2]>;
3362
3363 def : Pat<(X86SFence), (SFENCE)>;
3364 def : Pat<(X86LFence), (LFENCE)>;
3365 def : Pat<(X86MFence), (MFENCE)>;
3366
3367 //===----------------------------------------------------------------------===//
3368 // SSE 1 & 2 - Load/Store XCSR register
3369 //===----------------------------------------------------------------------===//
3370
3371 def VLDMXCSR : VPSI<0xAE, MRM2m, (outs), (ins i32mem:$src),
3372                   "ldmxcsr\t$src", [(int_x86_sse_ldmxcsr addr:$src)]>, VEX;
3373 def VSTMXCSR : VPSI<0xAE, MRM3m, (outs), (ins i32mem:$dst),
3374                   "stmxcsr\t$dst", [(int_x86_sse_stmxcsr addr:$dst)]>, VEX;
3375
3376 def LDMXCSR : PSI<0xAE, MRM2m, (outs), (ins i32mem:$src),
3377                   "ldmxcsr\t$src", [(int_x86_sse_ldmxcsr addr:$src)]>;
3378 def STMXCSR : PSI<0xAE, MRM3m, (outs), (ins i32mem:$dst),
3379                   "stmxcsr\t$dst", [(int_x86_sse_stmxcsr addr:$dst)]>;
3380
3381 //===---------------------------------------------------------------------===//
3382 // SSE2 - Move Aligned/Unaligned Packed Integer Instructions
3383 //===---------------------------------------------------------------------===//
3384
3385 let ExeDomain = SSEPackedInt in { // SSE integer instructions
3386
3387 let neverHasSideEffects = 1 in {
3388 def VMOVDQArr  : VPDI<0x6F, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3389                     "movdqa\t{$src, $dst|$dst, $src}", []>, VEX;
3390 def VMOVDQAYrr : VPDI<0x6F, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
3391                     "movdqa\t{$src, $dst|$dst, $src}", []>, VEX;
3392 }
3393 def VMOVDQUrr  : VSSI<0x6F, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3394                     "movdqu\t{$src, $dst|$dst, $src}", []>, VEX;
3395 def VMOVDQUYrr : VSSI<0x6F, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
3396                     "movdqu\t{$src, $dst|$dst, $src}", []>, VEX;
3397
3398 // For Disassembler
3399 let isCodeGenOnly = 1 in {
3400 def VMOVDQArr_REV  : VPDI<0x7F, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
3401                         "movdqa\t{$src, $dst|$dst, $src}", []>, VEX;
3402 def VMOVDQAYrr_REV : VPDI<0x7F, MRMDestReg, (outs VR256:$dst), (ins VR256:$src),
3403                         "movdqa\t{$src, $dst|$dst, $src}", []>, VEX;
3404 def VMOVDQUrr_REV  : VSSI<0x7F, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
3405                         "movdqu\t{$src, $dst|$dst, $src}", []>, VEX;
3406 def VMOVDQUYrr_REV : VSSI<0x7F, MRMDestReg, (outs VR256:$dst), (ins VR256:$src),
3407                         "movdqu\t{$src, $dst|$dst, $src}", []>, VEX;
3408 }
3409
3410 let canFoldAsLoad = 1, mayLoad = 1 in {
3411 def VMOVDQArm  : VPDI<0x6F, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
3412                    "movdqa\t{$src, $dst|$dst, $src}", []>, VEX;
3413 def VMOVDQAYrm : VPDI<0x6F, MRMSrcMem, (outs VR256:$dst), (ins i256mem:$src),
3414                    "movdqa\t{$src, $dst|$dst, $src}", []>, VEX;
3415 let Predicates = [HasAVX] in {
3416   def VMOVDQUrm  : I<0x6F, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
3417                     "vmovdqu\t{$src, $dst|$dst, $src}",[]>, XS, VEX;
3418   def VMOVDQUYrm : I<0x6F, MRMSrcMem, (outs VR256:$dst), (ins i256mem:$src),
3419                     "vmovdqu\t{$src, $dst|$dst, $src}",[]>, XS, VEX;
3420 }
3421 }
3422
3423 let mayStore = 1 in {
3424 def VMOVDQAmr  : VPDI<0x7F, MRMDestMem, (outs),
3425                      (ins i128mem:$dst, VR128:$src),
3426                      "movdqa\t{$src, $dst|$dst, $src}", []>, VEX;
3427 def VMOVDQAYmr : VPDI<0x7F, MRMDestMem, (outs),
3428                      (ins i256mem:$dst, VR256:$src),
3429                      "movdqa\t{$src, $dst|$dst, $src}", []>, VEX;
3430 let Predicates = [HasAVX] in {
3431 def VMOVDQUmr  : I<0x7F, MRMDestMem, (outs), (ins i128mem:$dst, VR128:$src),
3432                   "vmovdqu\t{$src, $dst|$dst, $src}",[]>, XS, VEX;
3433 def VMOVDQUYmr : I<0x7F, MRMDestMem, (outs), (ins i256mem:$dst, VR256:$src),
3434                   "vmovdqu\t{$src, $dst|$dst, $src}",[]>, XS, VEX;
3435 }
3436 }
3437
3438 let neverHasSideEffects = 1 in
3439 def MOVDQArr : PDI<0x6F, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3440                    "movdqa\t{$src, $dst|$dst, $src}", []>;
3441
3442 def MOVDQUrr :   I<0x6F, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3443                    "movdqu\t{$src, $dst|$dst, $src}",
3444                    []>, XS, Requires<[HasSSE2]>;
3445
3446 // For Disassembler
3447 let isCodeGenOnly = 1 in {
3448 def MOVDQArr_REV : PDI<0x7F, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
3449                        "movdqa\t{$src, $dst|$dst, $src}", []>;
3450
3451 def MOVDQUrr_REV :   I<0x7F, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
3452                        "movdqu\t{$src, $dst|$dst, $src}",
3453                        []>, XS, Requires<[HasSSE2]>;
3454 }
3455
3456 let canFoldAsLoad = 1, mayLoad = 1 in {
3457 def MOVDQArm : PDI<0x6F, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
3458                    "movdqa\t{$src, $dst|$dst, $src}",
3459                    [/*(set VR128:$dst, (alignedloadv2i64 addr:$src))*/]>;
3460 def MOVDQUrm :   I<0x6F, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
3461                    "movdqu\t{$src, $dst|$dst, $src}",
3462                    [/*(set VR128:$dst, (loadv2i64 addr:$src))*/]>,
3463                  XS, Requires<[HasSSE2]>;
3464 }
3465
3466 let mayStore = 1 in {
3467 def MOVDQAmr : PDI<0x7F, MRMDestMem, (outs), (ins i128mem:$dst, VR128:$src),
3468                    "movdqa\t{$src, $dst|$dst, $src}",
3469                    [/*(alignedstore (v2i64 VR128:$src), addr:$dst)*/]>;
3470 def MOVDQUmr :   I<0x7F, MRMDestMem, (outs), (ins i128mem:$dst, VR128:$src),
3471                    "movdqu\t{$src, $dst|$dst, $src}",
3472                    [/*(store (v2i64 VR128:$src), addr:$dst)*/]>,
3473                  XS, Requires<[HasSSE2]>;
3474 }
3475
3476 // Intrinsic forms of MOVDQU load and store
3477 def VMOVDQUmr_Int : I<0x7F, MRMDestMem, (outs), (ins i128mem:$dst, VR128:$src),
3478                        "vmovdqu\t{$src, $dst|$dst, $src}",
3479                        [(int_x86_sse2_storeu_dq addr:$dst, VR128:$src)]>,
3480                      XS, VEX, Requires<[HasAVX]>;
3481
3482 def MOVDQUmr_Int :   I<0x7F, MRMDestMem, (outs), (ins i128mem:$dst, VR128:$src),
3483                        "movdqu\t{$src, $dst|$dst, $src}",
3484                        [(int_x86_sse2_storeu_dq addr:$dst, VR128:$src)]>,
3485                      XS, Requires<[HasSSE2]>;
3486
3487 } // ExeDomain = SSEPackedInt
3488
3489 let Predicates = [HasAVX] in {
3490   def : Pat<(int_x86_avx_loadu_dq_256 addr:$src), (VMOVDQUYrm addr:$src)>;
3491   def : Pat<(int_x86_avx_storeu_dq_256 addr:$dst, VR256:$src),
3492             (VMOVDQUYmr addr:$dst, VR256:$src)>;
3493 }
3494
3495 //===---------------------------------------------------------------------===//
3496 // SSE2 - Packed Integer Arithmetic Instructions
3497 //===---------------------------------------------------------------------===//
3498
3499 let ExeDomain = SSEPackedInt in { // SSE integer instructions
3500
3501 multiclass PDI_binop_rm_int<bits<8> opc, string OpcodeStr, Intrinsic IntId,
3502                             RegisterClass RC, PatFrag memop_frag,
3503                             X86MemOperand x86memop, bit IsCommutable = 0,
3504                             bit Is2Addr = 1> {
3505   let isCommutable = IsCommutable in
3506   def rr : PDI<opc, MRMSrcReg, (outs RC:$dst),
3507        (ins RC:$src1, RC:$src2),
3508        !if(Is2Addr,
3509            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
3510            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
3511        [(set RC:$dst, (IntId RC:$src1, RC:$src2))]>;
3512   def rm : PDI<opc, MRMSrcMem, (outs RC:$dst),
3513        (ins RC:$src1, x86memop:$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, (IntId RC:$src1, (bitconvert (memop_frag addr:$src2))))]>;
3518 }
3519
3520 multiclass PDI_binop_rmi_int<bits<8> opc, bits<8> opc2, Format ImmForm,
3521                              string OpcodeStr, Intrinsic IntId,
3522                              Intrinsic IntId2, RegisterClass RC,
3523                              bit Is2Addr = 1> {
3524   // src2 is always 128-bit
3525   def rr : PDI<opc, MRMSrcReg, (outs RC:$dst),
3526        (ins RC:$src1, VR128:$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, (IntId RC:$src1, VR128:$src2))]>;
3531   def rm : PDI<opc, MRMSrcMem, (outs RC:$dst),
3532        (ins RC:$src1, i128mem:$src2),
3533        !if(Is2Addr,
3534            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
3535            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
3536        [(set RC:$dst, (IntId RC:$src1, (bitconvert (memopv2i64 addr:$src2))))]>;
3537   def ri : PDIi8<opc2, ImmForm, (outs RC:$dst),
3538        (ins RC:$src1, i32i8imm:$src2),
3539        !if(Is2Addr,
3540            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
3541            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
3542        [(set RC:$dst, (IntId2 RC:$src1, (i32 imm:$src2)))]>;
3543 }
3544
3545 } // ExeDomain = SSEPackedInt
3546
3547 // 128-bit Integer Arithmetic
3548
3549 let Predicates = [HasAVX] in {
3550 defm VPADDB  : PDI_binop_rm<0xFC, "vpaddb", add, v16i8, VR128, memopv2i64,
3551                             i128mem, 1, 0 /*3addr*/>, VEX_4V;
3552 defm VPADDW  : PDI_binop_rm<0xFD, "vpaddw", add, v8i16, VR128, memopv2i64,
3553                             i128mem, 1, 0>, VEX_4V;
3554 defm VPADDD  : PDI_binop_rm<0xFE, "vpaddd", add, v4i32, VR128, memopv2i64,
3555                             i128mem, 1, 0>, VEX_4V;
3556 defm VPADDQ  : PDI_binop_rm<0xD4, "vpaddq", add, v2i64, VR128, memopv2i64,
3557                             i128mem, 1, 0>, VEX_4V;
3558 defm VPMULLW : PDI_binop_rm<0xD5, "vpmullw", mul, v8i16, VR128, memopv2i64,
3559                             i128mem, 1, 0>, VEX_4V;
3560 defm VPSUBB : PDI_binop_rm<0xF8, "vpsubb", sub, v16i8, VR128, memopv2i64,
3561                             i128mem, 0, 0>, VEX_4V;
3562 defm VPSUBW : PDI_binop_rm<0xF9, "vpsubw", sub, v8i16, VR128, memopv2i64,
3563                             i128mem, 0, 0>, VEX_4V;
3564 defm VPSUBD : PDI_binop_rm<0xFA, "vpsubd", sub, v4i32, VR128, memopv2i64,
3565                             i128mem, 0, 0>, VEX_4V;
3566 defm VPSUBQ : PDI_binop_rm<0xFB, "vpsubq", sub, v2i64, VR128, memopv2i64,
3567                             i128mem, 0, 0>, VEX_4V;
3568
3569 // Intrinsic forms
3570 defm VPSUBSB  : PDI_binop_rm_int<0xE8, "vpsubsb" , int_x86_sse2_psubs_b,
3571                                  VR128, memopv2i64, i128mem, 0, 0>, VEX_4V;
3572 defm VPSUBSW  : PDI_binop_rm_int<0xE9, "vpsubsw" , int_x86_sse2_psubs_w,
3573                                  VR128, memopv2i64, i128mem, 0, 0>, VEX_4V;
3574 defm VPSUBUSB : PDI_binop_rm_int<0xD8, "vpsubusb", int_x86_sse2_psubus_b,
3575                                  VR128, memopv2i64, i128mem, 0, 0>, VEX_4V;
3576 defm VPSUBUSW : PDI_binop_rm_int<0xD9, "vpsubusw", int_x86_sse2_psubus_w,
3577                                  VR128, memopv2i64, i128mem, 0, 0>, VEX_4V;
3578 defm VPADDSB  : PDI_binop_rm_int<0xEC, "vpaddsb" , int_x86_sse2_padds_b,
3579                                  VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3580 defm VPADDSW  : PDI_binop_rm_int<0xED, "vpaddsw" , int_x86_sse2_padds_w,
3581                                  VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3582 defm VPADDUSB : PDI_binop_rm_int<0xDC, "vpaddusb", int_x86_sse2_paddus_b,
3583                                  VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3584 defm VPADDUSW : PDI_binop_rm_int<0xDD, "vpaddusw", int_x86_sse2_paddus_w,
3585                                  VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3586 defm VPMULHUW : PDI_binop_rm_int<0xE4, "vpmulhuw", int_x86_sse2_pmulhu_w,
3587                                  VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3588 defm VPMULHW  : PDI_binop_rm_int<0xE5, "vpmulhw" , int_x86_sse2_pmulh_w,
3589                                  VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3590 defm VPMULUDQ : PDI_binop_rm_int<0xF4, "vpmuludq", int_x86_sse2_pmulu_dq,
3591                                  VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3592 defm VPMADDWD : PDI_binop_rm_int<0xF5, "vpmaddwd", int_x86_sse2_pmadd_wd,
3593                                  VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3594 defm VPAVGB   : PDI_binop_rm_int<0xE0, "vpavgb", int_x86_sse2_pavg_b,
3595                                  VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3596 defm VPAVGW   : PDI_binop_rm_int<0xE3, "vpavgw", int_x86_sse2_pavg_w,
3597                                  VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3598 defm VPMINUB  : PDI_binop_rm_int<0xDA, "vpminub", int_x86_sse2_pminu_b,
3599                                  VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3600 defm VPMINSW  : PDI_binop_rm_int<0xEA, "vpminsw", int_x86_sse2_pmins_w,
3601                                  VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3602 defm VPMAXUB  : PDI_binop_rm_int<0xDE, "vpmaxub", int_x86_sse2_pmaxu_b,
3603                                  VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3604 defm VPMAXSW  : PDI_binop_rm_int<0xEE, "vpmaxsw", int_x86_sse2_pmaxs_w,
3605                                  VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3606 defm VPSADBW  : PDI_binop_rm_int<0xF6, "vpsadbw", int_x86_sse2_psad_bw,
3607                                  VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3608 }
3609
3610 let Predicates = [HasAVX2] in {
3611 defm VPADDBY  : PDI_binop_rm<0xFC, "vpaddb", add, v32i8, VR256, memopv4i64,
3612                              i256mem, 1, 0>, VEX_4V;
3613 defm VPADDWY  : PDI_binop_rm<0xFD, "vpaddw", add, v16i16, VR256, memopv4i64,
3614                              i256mem, 1, 0>, VEX_4V;
3615 defm VPADDDY  : PDI_binop_rm<0xFE, "vpaddd", add, v8i32, VR256, memopv4i64,
3616                              i256mem, 1, 0>, VEX_4V;
3617 defm VPADDQY  : PDI_binop_rm<0xD4, "vpaddq", add, v4i64, VR256, memopv4i64,
3618                              i256mem, 1, 0>, VEX_4V;
3619 defm VPMULLWY : PDI_binop_rm<0xD5, "vpmullw", mul, v16i16, VR256, memopv4i64,
3620                              i256mem, 1, 0>, VEX_4V;
3621 defm VPSUBBY  : PDI_binop_rm<0xF8, "vpsubb", sub, v32i8, VR256, memopv4i64,
3622                              i256mem, 0, 0>, VEX_4V;
3623 defm VPSUBWY  : PDI_binop_rm<0xF9, "vpsubw", sub, v16i16,VR256, memopv4i64,
3624                              i256mem, 0, 0>, VEX_4V;
3625 defm VPSUBDY  : PDI_binop_rm<0xFA, "vpsubd", sub, v8i32, VR256, memopv4i64,
3626                              i256mem, 0, 0>, VEX_4V;
3627 defm VPSUBQY  : PDI_binop_rm<0xFB, "vpsubq", sub, v4i64, VR256, memopv4i64,
3628                              i256mem, 0, 0>, VEX_4V;
3629
3630 // Intrinsic forms
3631 defm VPSUBSBY  : PDI_binop_rm_int<0xE8, "vpsubsb" , int_x86_avx2_psubs_b,
3632                                   VR256, memopv4i64, i256mem, 0, 0>, VEX_4V;
3633 defm VPSUBSWY  : PDI_binop_rm_int<0xE9, "vpsubsw" , int_x86_avx2_psubs_w,
3634                                   VR256, memopv4i64, i256mem, 0, 0>, VEX_4V;
3635 defm VPSUBUSBY : PDI_binop_rm_int<0xD8, "vpsubusb", int_x86_avx2_psubus_b,
3636                                   VR256, memopv4i64, i256mem, 0, 0>, VEX_4V;
3637 defm VPSUBUSWY : PDI_binop_rm_int<0xD9, "vpsubusw", int_x86_avx2_psubus_w,
3638                                   VR256, memopv4i64, i256mem, 0, 0>, VEX_4V;
3639 defm VPADDSBY  : PDI_binop_rm_int<0xEC, "vpaddsb" , int_x86_avx2_padds_b,
3640                                   VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3641 defm VPADDSWY  : PDI_binop_rm_int<0xED, "vpaddsw" , int_x86_avx2_padds_w,
3642                                   VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3643 defm VPADDUSBY : PDI_binop_rm_int<0xDC, "vpaddusb", int_x86_avx2_paddus_b,
3644                                   VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3645 defm VPADDUSWY : PDI_binop_rm_int<0xDD, "vpaddusw", int_x86_avx2_paddus_w,
3646                                   VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3647 defm VPMULHUWY : PDI_binop_rm_int<0xE4, "vpmulhuw", int_x86_avx2_pmulhu_w,
3648                                   VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3649 defm VPMULHWY  : PDI_binop_rm_int<0xE5, "vpmulhw" , int_x86_avx2_pmulh_w,
3650                                   VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3651 defm VPMULUDQY : PDI_binop_rm_int<0xF4, "vpmuludq", int_x86_avx2_pmulu_dq,
3652                                   VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3653 defm VPMADDWDY : PDI_binop_rm_int<0xF5, "vpmaddwd", int_x86_avx2_pmadd_wd,
3654                                   VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3655 defm VPAVGBY   : PDI_binop_rm_int<0xE0, "vpavgb", int_x86_avx2_pavg_b,
3656                                   VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3657 defm VPAVGWY   : PDI_binop_rm_int<0xE3, "vpavgw", int_x86_avx2_pavg_w,
3658                                   VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3659 defm VPMINUBY  : PDI_binop_rm_int<0xDA, "vpminub", int_x86_avx2_pminu_b,
3660                                   VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3661 defm VPMINSWY  : PDI_binop_rm_int<0xEA, "vpminsw", int_x86_avx2_pmins_w,
3662                                   VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3663 defm VPMAXUBY  : PDI_binop_rm_int<0xDE, "vpmaxub", int_x86_avx2_pmaxu_b,
3664                                   VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3665 defm VPMAXSWY  : PDI_binop_rm_int<0xEE, "vpmaxsw", int_x86_avx2_pmaxs_w,
3666                                   VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3667 defm VPSADBWY  : PDI_binop_rm_int<0xF6, "vpsadbw", int_x86_avx2_psad_bw,
3668                                   VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3669 }
3670
3671 let Constraints = "$src1 = $dst" in {
3672 defm PADDB  : PDI_binop_rm<0xFC, "paddb", add, v16i8, VR128, memopv2i64,
3673                            i128mem, 1>;
3674 defm PADDW  : PDI_binop_rm<0xFD, "paddw", add, v8i16, VR128, memopv2i64,
3675                            i128mem, 1>;
3676 defm PADDD  : PDI_binop_rm<0xFE, "paddd", add, v4i32, VR128, memopv2i64,
3677                            i128mem, 1>;
3678 defm PADDQ  : PDI_binop_rm<0xD4, "paddq", add, v2i64, VR128, memopv2i64,
3679                            i128mem, 1>;
3680 defm PMULLW : PDI_binop_rm<0xD5, "pmullw", mul, v8i16, VR128, memopv2i64,
3681                            i128mem, 1>;
3682 defm PSUBB : PDI_binop_rm<0xF8, "psubb", sub, v16i8, VR128, memopv2i64,
3683                           i128mem>;
3684 defm PSUBW : PDI_binop_rm<0xF9, "psubw", sub, v8i16, VR128, memopv2i64,
3685                           i128mem>;
3686 defm PSUBD : PDI_binop_rm<0xFA, "psubd", sub, v4i32, VR128, memopv2i64,
3687                           i128mem>;
3688 defm PSUBQ : PDI_binop_rm<0xFB, "psubq", sub, v2i64, VR128, memopv2i64,
3689                           i128mem>;
3690
3691 // Intrinsic forms
3692 defm PSUBSB  : PDI_binop_rm_int<0xE8, "psubsb" , int_x86_sse2_psubs_b,
3693                                 VR128, memopv2i64, i128mem>;
3694 defm PSUBSW  : PDI_binop_rm_int<0xE9, "psubsw" , int_x86_sse2_psubs_w,
3695                                 VR128, memopv2i64, i128mem>;
3696 defm PSUBUSB : PDI_binop_rm_int<0xD8, "psubusb", int_x86_sse2_psubus_b,
3697                                 VR128, memopv2i64, i128mem>;
3698 defm PSUBUSW : PDI_binop_rm_int<0xD9, "psubusw", int_x86_sse2_psubus_w,
3699                                 VR128, memopv2i64, i128mem>;
3700 defm PADDSB  : PDI_binop_rm_int<0xEC, "paddsb" , int_x86_sse2_padds_b,
3701                                 VR128, memopv2i64, i128mem, 1>;
3702 defm PADDSW  : PDI_binop_rm_int<0xED, "paddsw" , int_x86_sse2_padds_w,
3703                                 VR128, memopv2i64, i128mem, 1>;
3704 defm PADDUSB : PDI_binop_rm_int<0xDC, "paddusb", int_x86_sse2_paddus_b,
3705                                 VR128, memopv2i64, i128mem, 1>;
3706 defm PADDUSW : PDI_binop_rm_int<0xDD, "paddusw", int_x86_sse2_paddus_w,
3707                                 VR128, memopv2i64, i128mem, 1>;
3708 defm PMULHUW : PDI_binop_rm_int<0xE4, "pmulhuw", int_x86_sse2_pmulhu_w,
3709                                 VR128, memopv2i64, i128mem, 1>;
3710 defm PMULHW  : PDI_binop_rm_int<0xE5, "pmulhw" , int_x86_sse2_pmulh_w,
3711                                 VR128, memopv2i64, i128mem, 1>;
3712 defm PMULUDQ : PDI_binop_rm_int<0xF4, "pmuludq", int_x86_sse2_pmulu_dq,
3713                                 VR128, memopv2i64, i128mem, 1>;
3714 defm PMADDWD : PDI_binop_rm_int<0xF5, "pmaddwd", int_x86_sse2_pmadd_wd,
3715                                 VR128, memopv2i64, i128mem, 1>;
3716 defm PAVGB   : PDI_binop_rm_int<0xE0, "pavgb", int_x86_sse2_pavg_b,
3717                                 VR128, memopv2i64, i128mem, 1>;
3718 defm PAVGW   : PDI_binop_rm_int<0xE3, "pavgw", int_x86_sse2_pavg_w,
3719                                 VR128, memopv2i64, i128mem, 1>;
3720 defm PMINUB  : PDI_binop_rm_int<0xDA, "pminub", int_x86_sse2_pminu_b,
3721                                 VR128, memopv2i64, i128mem, 1>;
3722 defm PMINSW  : PDI_binop_rm_int<0xEA, "pminsw", int_x86_sse2_pmins_w,
3723                                 VR128, memopv2i64, i128mem, 1>;
3724 defm PMAXUB  : PDI_binop_rm_int<0xDE, "pmaxub", int_x86_sse2_pmaxu_b,
3725                                 VR128, memopv2i64, i128mem, 1>;
3726 defm PMAXSW  : PDI_binop_rm_int<0xEE, "pmaxsw", int_x86_sse2_pmaxs_w,
3727                                 VR128, memopv2i64, i128mem, 1>;
3728 defm PSADBW  : PDI_binop_rm_int<0xF6, "psadbw", int_x86_sse2_psad_bw,
3729                                 VR128, memopv2i64, i128mem, 1>;
3730
3731 } // Constraints = "$src1 = $dst"
3732
3733 //===---------------------------------------------------------------------===//
3734 // SSE2 - Packed Integer Logical Instructions
3735 //===---------------------------------------------------------------------===//
3736
3737 let Predicates = [HasAVX] in {
3738 defm VPSLLW : PDI_binop_rmi_int<0xF1, 0x71, MRM6r, "vpsllw",
3739                                 int_x86_sse2_psll_w, int_x86_sse2_pslli_w,
3740                                 VR128, 0>, VEX_4V;
3741 defm VPSLLD : PDI_binop_rmi_int<0xF2, 0x72, MRM6r, "vpslld",
3742                                 int_x86_sse2_psll_d, int_x86_sse2_pslli_d,
3743                                 VR128, 0>, VEX_4V;
3744 defm VPSLLQ : PDI_binop_rmi_int<0xF3, 0x73, MRM6r, "vpsllq",
3745                                 int_x86_sse2_psll_q, int_x86_sse2_pslli_q,
3746                                 VR128, 0>, VEX_4V;
3747
3748 defm VPSRLW : PDI_binop_rmi_int<0xD1, 0x71, MRM2r, "vpsrlw",
3749                                 int_x86_sse2_psrl_w, int_x86_sse2_psrli_w,
3750                                 VR128, 0>, VEX_4V;
3751 defm VPSRLD : PDI_binop_rmi_int<0xD2, 0x72, MRM2r, "vpsrld",
3752                                 int_x86_sse2_psrl_d, int_x86_sse2_psrli_d,
3753                                 VR128, 0>, VEX_4V;
3754 defm VPSRLQ : PDI_binop_rmi_int<0xD3, 0x73, MRM2r, "vpsrlq",
3755                                 int_x86_sse2_psrl_q, int_x86_sse2_psrli_q,
3756                                 VR128, 0>, VEX_4V;
3757
3758 defm VPSRAW : PDI_binop_rmi_int<0xE1, 0x71, MRM4r, "vpsraw",
3759                                 int_x86_sse2_psra_w, int_x86_sse2_psrai_w,
3760                                 VR128, 0>, VEX_4V;
3761 defm VPSRAD : PDI_binop_rmi_int<0xE2, 0x72, MRM4r, "vpsrad",
3762                                 int_x86_sse2_psra_d, int_x86_sse2_psrai_d,
3763                                 VR128, 0>, VEX_4V;
3764
3765 let ExeDomain = SSEPackedInt in {
3766   let neverHasSideEffects = 1 in {
3767     // 128-bit logical shifts.
3768     def VPSLLDQri : PDIi8<0x73, MRM7r,
3769                       (outs VR128:$dst), (ins VR128:$src1, i32i8imm:$src2),
3770                       "vpslldq\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>,
3771                       VEX_4V;
3772     def VPSRLDQri : PDIi8<0x73, MRM3r,
3773                       (outs VR128:$dst), (ins VR128:$src1, i32i8imm:$src2),
3774                       "vpsrldq\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>,
3775                       VEX_4V;
3776     // PSRADQri doesn't exist in SSE[1-3].
3777   }
3778 }
3779 }
3780
3781 let Predicates = [HasAVX2] in {
3782 defm VPSLLWY : PDI_binop_rmi_int<0xF1, 0x71, MRM6r, "vpsllw",
3783                                  int_x86_avx2_psll_w, int_x86_avx2_pslli_w,
3784                                  VR256, 0>, VEX_4V;
3785 defm VPSLLDY : PDI_binop_rmi_int<0xF2, 0x72, MRM6r, "vpslld",
3786                                  int_x86_avx2_psll_d, int_x86_avx2_pslli_d,
3787                                  VR256, 0>, VEX_4V;
3788 defm VPSLLQY : PDI_binop_rmi_int<0xF3, 0x73, MRM6r, "vpsllq",
3789                                  int_x86_avx2_psll_q, int_x86_avx2_pslli_q,
3790                                  VR256, 0>, VEX_4V;
3791
3792 defm VPSRLWY : PDI_binop_rmi_int<0xD1, 0x71, MRM2r, "vpsrlw",
3793                                  int_x86_avx2_psrl_w, int_x86_avx2_psrli_w,
3794                                  VR256, 0>, VEX_4V;
3795 defm VPSRLDY : PDI_binop_rmi_int<0xD2, 0x72, MRM2r, "vpsrld",
3796                                  int_x86_avx2_psrl_d, int_x86_avx2_psrli_d,
3797                                  VR256, 0>, VEX_4V;
3798 defm VPSRLQY : PDI_binop_rmi_int<0xD3, 0x73, MRM2r, "vpsrlq",
3799                                  int_x86_avx2_psrl_q, int_x86_avx2_psrli_q,
3800                                  VR256, 0>, VEX_4V;
3801
3802 defm VPSRAWY : PDI_binop_rmi_int<0xE1, 0x71, MRM4r, "vpsraw",
3803                                  int_x86_avx2_psra_w, int_x86_avx2_psrai_w,
3804                                  VR256, 0>, VEX_4V;
3805 defm VPSRADY : PDI_binop_rmi_int<0xE2, 0x72, MRM4r, "vpsrad",
3806                                  int_x86_avx2_psra_d, int_x86_avx2_psrai_d,
3807                                  VR256, 0>, VEX_4V;
3808
3809 let ExeDomain = SSEPackedInt in {
3810   let neverHasSideEffects = 1 in {
3811     // 128-bit logical shifts.
3812     def VPSLLDQYri : PDIi8<0x73, MRM7r,
3813                       (outs VR256:$dst), (ins VR256:$src1, i32i8imm:$src2),
3814                       "vpslldq\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>,
3815                       VEX_4V;
3816     def VPSRLDQYri : PDIi8<0x73, MRM3r,
3817                       (outs VR256:$dst), (ins VR256:$src1, i32i8imm:$src2),
3818                       "vpsrldq\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>,
3819                       VEX_4V;
3820     // PSRADQYri doesn't exist in SSE[1-3].
3821   }
3822 }
3823 }
3824
3825 let Constraints = "$src1 = $dst" in {
3826 defm PSLLW : PDI_binop_rmi_int<0xF1, 0x71, MRM6r, "psllw",
3827                                int_x86_sse2_psll_w, int_x86_sse2_pslli_w,
3828                                VR128>;
3829 defm PSLLD : PDI_binop_rmi_int<0xF2, 0x72, MRM6r, "pslld",
3830                                int_x86_sse2_psll_d, int_x86_sse2_pslli_d,
3831                                VR128>;
3832 defm PSLLQ : PDI_binop_rmi_int<0xF3, 0x73, MRM6r, "psllq",
3833                                int_x86_sse2_psll_q, int_x86_sse2_pslli_q,
3834                                VR128>;
3835
3836 defm PSRLW : PDI_binop_rmi_int<0xD1, 0x71, MRM2r, "psrlw",
3837                                int_x86_sse2_psrl_w, int_x86_sse2_psrli_w,
3838                                VR128>;
3839 defm PSRLD : PDI_binop_rmi_int<0xD2, 0x72, MRM2r, "psrld",
3840                                int_x86_sse2_psrl_d, int_x86_sse2_psrli_d,
3841                                VR128>;
3842 defm PSRLQ : PDI_binop_rmi_int<0xD3, 0x73, MRM2r, "psrlq",
3843                                int_x86_sse2_psrl_q, int_x86_sse2_psrli_q,
3844                                VR128>;
3845
3846 defm PSRAW : PDI_binop_rmi_int<0xE1, 0x71, MRM4r, "psraw",
3847                                int_x86_sse2_psra_w, int_x86_sse2_psrai_w,
3848                                VR128>;
3849 defm PSRAD : PDI_binop_rmi_int<0xE2, 0x72, MRM4r, "psrad",
3850                                int_x86_sse2_psra_d, int_x86_sse2_psrai_d,
3851                                VR128>;
3852
3853 let ExeDomain = SSEPackedInt in {
3854   let neverHasSideEffects = 1 in {
3855     // 128-bit logical shifts.
3856     def PSLLDQri : PDIi8<0x73, MRM7r,
3857                          (outs VR128:$dst), (ins VR128:$src1, i32i8imm:$src2),
3858                          "pslldq\t{$src2, $dst|$dst, $src2}", []>;
3859     def PSRLDQri : PDIi8<0x73, MRM3r,
3860                          (outs VR128:$dst), (ins VR128:$src1, i32i8imm:$src2),
3861                          "psrldq\t{$src2, $dst|$dst, $src2}", []>;
3862     // PSRADQri doesn't exist in SSE[1-3].
3863   }
3864 }
3865 } // Constraints = "$src1 = $dst"
3866
3867 let Predicates = [HasAVX] in {
3868   def : Pat<(int_x86_sse2_psll_dq VR128:$src1, imm:$src2),
3869             (VPSLLDQri VR128:$src1, (BYTE_imm imm:$src2))>;
3870   def : Pat<(int_x86_sse2_psrl_dq VR128:$src1, imm:$src2),
3871             (VPSRLDQri VR128:$src1, (BYTE_imm imm:$src2))>;
3872   def : Pat<(int_x86_sse2_psll_dq_bs VR128:$src1, imm:$src2),
3873             (VPSLLDQri VR128:$src1, imm:$src2)>;
3874   def : Pat<(int_x86_sse2_psrl_dq_bs VR128:$src1, imm:$src2),
3875             (VPSRLDQri VR128:$src1, imm:$src2)>;
3876   def : Pat<(v2f64 (X86fsrl VR128:$src1, i32immSExt8:$src2)),
3877             (VPSRLDQri VR128:$src1, (BYTE_imm imm:$src2))>;
3878
3879   // Shift up / down and insert zero's.
3880   def : Pat<(v2i64 (X86vshl  VR128:$src, (i8 imm:$amt))),
3881             (VPSLLDQri VR128:$src, (BYTE_imm imm:$amt))>;
3882   def : Pat<(v2i64 (X86vshr  VR128:$src, (i8 imm:$amt))),
3883             (VPSRLDQri VR128:$src, (BYTE_imm imm:$amt))>;
3884 }
3885
3886 let Predicates = [HasAVX2] in {
3887   def : Pat<(int_x86_avx2_psll_dq VR256:$src1, imm:$src2),
3888             (VPSLLDQYri VR256:$src1, (BYTE_imm imm:$src2))>;
3889   def : Pat<(int_x86_avx2_psrl_dq VR256:$src1, imm:$src2),
3890             (VPSRLDQYri VR256:$src1, (BYTE_imm imm:$src2))>;
3891   def : Pat<(int_x86_avx2_psll_dq_bs VR256:$src1, imm:$src2),
3892             (VPSLLDQYri VR256:$src1, imm:$src2)>;
3893   def : Pat<(int_x86_avx2_psrl_dq_bs VR256:$src1, imm:$src2),
3894             (VPSRLDQYri VR256:$src1, imm:$src2)>;
3895 }
3896
3897 let Predicates = [HasSSE2] in {
3898   def : Pat<(int_x86_sse2_psll_dq VR128:$src1, imm:$src2),
3899             (PSLLDQri VR128:$src1, (BYTE_imm imm:$src2))>;
3900   def : Pat<(int_x86_sse2_psrl_dq VR128:$src1, imm:$src2),
3901             (PSRLDQri VR128:$src1, (BYTE_imm imm:$src2))>;
3902   def : Pat<(int_x86_sse2_psll_dq_bs VR128:$src1, imm:$src2),
3903             (PSLLDQri VR128:$src1, imm:$src2)>;
3904   def : Pat<(int_x86_sse2_psrl_dq_bs VR128:$src1, imm:$src2),
3905             (PSRLDQri VR128:$src1, imm:$src2)>;
3906   def : Pat<(v2f64 (X86fsrl VR128:$src1, i32immSExt8:$src2)),
3907             (PSRLDQri VR128:$src1, (BYTE_imm imm:$src2))>;
3908
3909   // Shift up / down and insert zero's.
3910   def : Pat<(v2i64 (X86vshl  VR128:$src, (i8 imm:$amt))),
3911             (PSLLDQri VR128:$src, (BYTE_imm imm:$amt))>;
3912   def : Pat<(v2i64 (X86vshr  VR128:$src, (i8 imm:$amt))),
3913             (PSRLDQri VR128:$src, (BYTE_imm imm:$amt))>;
3914 }
3915
3916 //===---------------------------------------------------------------------===//
3917 // SSE2 - Packed Integer Comparison Instructions
3918 //===---------------------------------------------------------------------===//
3919
3920 let Predicates = [HasAVX] in {
3921   defm VPCMPEQB  : PDI_binop_rm_int<0x74, "vpcmpeqb", int_x86_sse2_pcmpeq_b,
3922                                     VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3923   defm VPCMPEQW  : PDI_binop_rm_int<0x75, "vpcmpeqw", int_x86_sse2_pcmpeq_w,
3924                                     VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3925   defm VPCMPEQD  : PDI_binop_rm_int<0x76, "vpcmpeqd", int_x86_sse2_pcmpeq_d,
3926                                     VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3927   defm VPCMPGTB  : PDI_binop_rm_int<0x64, "vpcmpgtb", int_x86_sse2_pcmpgt_b,
3928                                     VR128, memopv2i64, i128mem, 0, 0>, VEX_4V;
3929   defm VPCMPGTW  : PDI_binop_rm_int<0x65, "vpcmpgtw", int_x86_sse2_pcmpgt_w,
3930                                     VR128, memopv2i64, i128mem, 0, 0>, VEX_4V;
3931   defm VPCMPGTD  : PDI_binop_rm_int<0x66, "vpcmpgtd", int_x86_sse2_pcmpgt_d,
3932                                     VR128, memopv2i64, i128mem, 0, 0>, VEX_4V;
3933
3934   def : Pat<(v16i8 (X86pcmpeqb VR128:$src1, VR128:$src2)),
3935             (VPCMPEQBrr VR128:$src1, VR128:$src2)>;
3936   def : Pat<(v16i8 (X86pcmpeqb VR128:$src1,
3937                     (bc_v16i8 (memopv2i64 addr:$src2)))),
3938             (VPCMPEQBrm VR128:$src1, addr:$src2)>;
3939   def : Pat<(v8i16 (X86pcmpeqw VR128:$src1, VR128:$src2)),
3940             (VPCMPEQWrr VR128:$src1, VR128:$src2)>;
3941   def : Pat<(v8i16 (X86pcmpeqw VR128:$src1,
3942                     (bc_v8i16 (memopv2i64 addr:$src2)))),
3943             (VPCMPEQWrm VR128:$src1, addr:$src2)>;
3944   def : Pat<(v4i32 (X86pcmpeqd VR128:$src1, VR128:$src2)),
3945             (VPCMPEQDrr VR128:$src1, VR128:$src2)>;
3946   def : Pat<(v4i32 (X86pcmpeqd VR128:$src1,
3947                     (bc_v4i32 (memopv2i64 addr:$src2)))),
3948             (VPCMPEQDrm VR128:$src1, addr:$src2)>;
3949
3950   def : Pat<(v16i8 (X86pcmpgtb VR128:$src1, VR128:$src2)),
3951             (VPCMPGTBrr VR128:$src1, VR128:$src2)>;
3952   def : Pat<(v16i8 (X86pcmpgtb VR128:$src1,
3953                     (bc_v16i8 (memopv2i64 addr:$src2)))),
3954             (VPCMPGTBrm VR128:$src1, addr:$src2)>;
3955   def : Pat<(v8i16 (X86pcmpgtw VR128:$src1, VR128:$src2)),
3956             (VPCMPGTWrr VR128:$src1, VR128:$src2)>;
3957   def : Pat<(v8i16 (X86pcmpgtw VR128:$src1,
3958                     (bc_v8i16 (memopv2i64 addr:$src2)))),
3959             (VPCMPGTWrm VR128:$src1, addr:$src2)>;
3960   def : Pat<(v4i32 (X86pcmpgtd VR128:$src1, VR128:$src2)),
3961             (VPCMPGTDrr VR128:$src1, VR128:$src2)>;
3962   def : Pat<(v4i32 (X86pcmpgtd VR128:$src1,
3963                     (bc_v4i32 (memopv2i64 addr:$src2)))),
3964             (VPCMPGTDrm VR128:$src1, addr:$src2)>;
3965 }
3966
3967 let Predicates = [HasAVX2] in {
3968   defm VPCMPEQBY : PDI_binop_rm_int<0x74, "vpcmpeqb", int_x86_avx2_pcmpeq_b,
3969                                     VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3970   defm VPCMPEQWY : PDI_binop_rm_int<0x75, "vpcmpeqw", int_x86_avx2_pcmpeq_w,
3971                                     VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3972   defm VPCMPEQDY : PDI_binop_rm_int<0x76, "vpcmpeqd", int_x86_avx2_pcmpeq_d,
3973                                     VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3974   defm VPCMPGTBY : PDI_binop_rm_int<0x64, "vpcmpgtb", int_x86_avx2_pcmpgt_b,
3975                                     VR256, memopv4i64, i256mem, 0, 0>, VEX_4V;
3976   defm VPCMPGTWY : PDI_binop_rm_int<0x65, "vpcmpgtw", int_x86_avx2_pcmpgt_w,
3977                                     VR256, memopv4i64, i256mem, 0, 0>, VEX_4V;
3978   defm VPCMPGTDY : PDI_binop_rm_int<0x66, "vpcmpgtd", int_x86_avx2_pcmpgt_d,
3979                                     VR256, memopv4i64, i256mem, 0, 0>, VEX_4V;
3980
3981   def : Pat<(v32i8 (X86pcmpeqb VR256:$src1, VR256:$src2)),
3982             (VPCMPEQBYrr VR256:$src1, VR256:$src2)>;
3983   def : Pat<(v32i8 (X86pcmpeqb VR256:$src1,
3984                     (bc_v32i8 (memopv4i64 addr:$src2)))),
3985             (VPCMPEQBYrm VR256:$src1, addr:$src2)>;
3986   def : Pat<(v16i16 (X86pcmpeqw VR256:$src1, VR256:$src2)),
3987             (VPCMPEQWYrr VR256:$src1, VR256:$src2)>;
3988   def : Pat<(v16i16 (X86pcmpeqw VR256:$src1,
3989                      (bc_v16i16 (memopv4i64 addr:$src2)))),
3990             (VPCMPEQWYrm VR256:$src1, addr:$src2)>;
3991   def : Pat<(v8i32 (X86pcmpeqd VR256:$src1, VR256:$src2)),
3992             (VPCMPEQDYrr VR256:$src1, VR256:$src2)>;
3993   def : Pat<(v8i32 (X86pcmpeqd VR256:$src1,
3994                     (bc_v8i32 (memopv4i64 addr:$src2)))),
3995             (VPCMPEQDYrm VR256:$src1, addr:$src2)>;
3996
3997   def : Pat<(v32i8 (X86pcmpgtb VR256:$src1, VR256:$src2)),
3998             (VPCMPGTBYrr VR256:$src1, VR256:$src2)>;
3999   def : Pat<(v32i8 (X86pcmpgtb VR256:$src1,
4000                     (bc_v32i8 (memopv4i64 addr:$src2)))),
4001             (VPCMPGTBYrm VR256:$src1, addr:$src2)>;
4002   def : Pat<(v16i16 (X86pcmpgtw VR256:$src1, VR256:$src2)),
4003             (VPCMPGTWYrr VR256:$src1, VR256:$src2)>;
4004   def : Pat<(v16i16 (X86pcmpgtw VR256:$src1,
4005                      (bc_v16i16 (memopv4i64 addr:$src2)))),
4006             (VPCMPGTWYrm VR256:$src1, addr:$src2)>;
4007   def : Pat<(v8i32 (X86pcmpgtd VR256:$src1, VR256:$src2)),
4008             (VPCMPGTDYrr VR256:$src1, VR256:$src2)>;
4009   def : Pat<(v8i32 (X86pcmpgtd VR256:$src1,
4010                     (bc_v8i32 (memopv4i64 addr:$src2)))),
4011             (VPCMPGTDYrm VR256:$src1, addr:$src2)>;
4012 }
4013
4014 let Constraints = "$src1 = $dst" in {
4015   defm PCMPEQB  : PDI_binop_rm_int<0x74, "pcmpeqb", int_x86_sse2_pcmpeq_b,
4016                                    VR128, memopv2i64, i128mem, 1>;
4017   defm PCMPEQW  : PDI_binop_rm_int<0x75, "pcmpeqw", int_x86_sse2_pcmpeq_w,
4018                                    VR128, memopv2i64, i128mem, 1>;
4019   defm PCMPEQD  : PDI_binop_rm_int<0x76, "pcmpeqd", int_x86_sse2_pcmpeq_d,
4020                                    VR128, memopv2i64, i128mem, 1>;
4021   defm PCMPGTB  : PDI_binop_rm_int<0x64, "pcmpgtb", int_x86_sse2_pcmpgt_b,
4022                                    VR128, memopv2i64, i128mem>;
4023   defm PCMPGTW  : PDI_binop_rm_int<0x65, "pcmpgtw", int_x86_sse2_pcmpgt_w,
4024                                    VR128, memopv2i64, i128mem>;
4025   defm PCMPGTD  : PDI_binop_rm_int<0x66, "pcmpgtd", int_x86_sse2_pcmpgt_d,
4026                                    VR128, memopv2i64, i128mem>;
4027 } // Constraints = "$src1 = $dst"
4028
4029 let Predicates = [HasSSE2] in {
4030   def : Pat<(v16i8 (X86pcmpeqb VR128:$src1, VR128:$src2)),
4031             (PCMPEQBrr VR128:$src1, VR128:$src2)>;
4032   def : Pat<(v16i8 (X86pcmpeqb VR128:$src1,
4033                     (bc_v16i8 (memopv2i64 addr:$src2)))),
4034             (PCMPEQBrm VR128:$src1, addr:$src2)>;
4035   def : Pat<(v8i16 (X86pcmpeqw VR128:$src1, VR128:$src2)),
4036             (PCMPEQWrr VR128:$src1, VR128:$src2)>;
4037   def : Pat<(v8i16 (X86pcmpeqw VR128:$src1,
4038                     (bc_v8i16 (memopv2i64 addr:$src2)))),
4039             (PCMPEQWrm VR128:$src1, addr:$src2)>;
4040   def : Pat<(v4i32 (X86pcmpeqd VR128:$src1, VR128:$src2)),
4041             (PCMPEQDrr VR128:$src1, VR128:$src2)>;
4042   def : Pat<(v4i32 (X86pcmpeqd VR128:$src1,
4043                     (bc_v4i32 (memopv2i64 addr:$src2)))),
4044             (PCMPEQDrm VR128:$src1, addr:$src2)>;
4045
4046   def : Pat<(v16i8 (X86pcmpgtb VR128:$src1, VR128:$src2)),
4047             (PCMPGTBrr VR128:$src1, VR128:$src2)>;
4048   def : Pat<(v16i8 (X86pcmpgtb VR128:$src1,
4049              (bc_v16i8 (memopv2i64 addr:$src2)))),
4050             (PCMPGTBrm VR128:$src1, addr:$src2)>;
4051   def : Pat<(v8i16 (X86pcmpgtw VR128:$src1, VR128:$src2)),
4052             (PCMPGTWrr VR128:$src1, VR128:$src2)>;
4053   def : Pat<(v8i16 (X86pcmpgtw VR128:$src1,
4054                     (bc_v8i16 (memopv2i64 addr:$src2)))),
4055             (PCMPGTWrm VR128:$src1, addr:$src2)>;
4056   def : Pat<(v4i32 (X86pcmpgtd VR128:$src1, VR128:$src2)),
4057             (PCMPGTDrr VR128:$src1, VR128:$src2)>;
4058   def : Pat<(v4i32 (X86pcmpgtd VR128:$src1,
4059                     (bc_v4i32 (memopv2i64 addr:$src2)))),
4060             (PCMPGTDrm VR128:$src1, addr:$src2)>;
4061 }
4062
4063 //===---------------------------------------------------------------------===//
4064 // SSE2 - Packed Integer Pack Instructions
4065 //===---------------------------------------------------------------------===//
4066
4067 let Predicates = [HasAVX] in {
4068 defm VPACKSSWB : PDI_binop_rm_int<0x63, "vpacksswb", int_x86_sse2_packsswb_128,
4069                                   VR128, memopv2i64, i128mem, 0, 0>, VEX_4V;
4070 defm VPACKSSDW : PDI_binop_rm_int<0x6B, "vpackssdw", int_x86_sse2_packssdw_128,
4071                                   VR128, memopv2i64, i128mem, 0, 0>, VEX_4V;
4072 defm VPACKUSWB : PDI_binop_rm_int<0x67, "vpackuswb", int_x86_sse2_packuswb_128,
4073                                   VR128, memopv2i64, i128mem, 0, 0>, VEX_4V;
4074 }
4075
4076 let Predicates = [HasAVX2] in {
4077 defm VPACKSSWBY : PDI_binop_rm_int<0x63, "vpacksswb", int_x86_avx2_packsswb,
4078                                    VR256, memopv4i64, i256mem, 0, 0>, VEX_4V;
4079 defm VPACKSSDWY : PDI_binop_rm_int<0x6B, "vpackssdw", int_x86_avx2_packssdw,
4080                                    VR256, memopv4i64, i256mem, 0, 0>, VEX_4V;
4081 defm VPACKUSWBY : PDI_binop_rm_int<0x67, "vpackuswb", int_x86_avx2_packuswb,
4082                                    VR256, memopv4i64, i256mem, 0, 0>, VEX_4V;
4083 }
4084
4085 let Constraints = "$src1 = $dst" in {
4086 defm PACKSSWB : PDI_binop_rm_int<0x63, "packsswb", int_x86_sse2_packsswb_128,
4087                                  VR128, memopv2i64, i128mem>;
4088 defm PACKSSDW : PDI_binop_rm_int<0x6B, "packssdw", int_x86_sse2_packssdw_128,
4089                                  VR128, memopv2i64, i128mem>;
4090 defm PACKUSWB : PDI_binop_rm_int<0x67, "packuswb", int_x86_sse2_packuswb_128,
4091                                  VR128, memopv2i64, i128mem>;
4092 } // Constraints = "$src1 = $dst"
4093
4094 //===---------------------------------------------------------------------===//
4095 // SSE2 - Packed Integer Shuffle Instructions
4096 //===---------------------------------------------------------------------===//
4097
4098 let ExeDomain = SSEPackedInt in {
4099 multiclass sse2_pshuffle<string OpcodeStr, ValueType vt, PatFrag pshuf_frag,
4100                          PatFrag bc_frag> {
4101 def ri : Ii8<0x70, MRMSrcReg,
4102               (outs VR128:$dst), (ins VR128:$src1, i8imm:$src2),
4103               !strconcat(OpcodeStr,
4104                          "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4105               [(set VR128:$dst, (vt (pshuf_frag:$src2 VR128:$src1,
4106                                                       (undef))))]>;
4107 def mi : Ii8<0x70, MRMSrcMem,
4108               (outs VR128:$dst), (ins i128mem:$src1, i8imm:$src2),
4109               !strconcat(OpcodeStr,
4110                          "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4111               [(set VR128:$dst, (vt (pshuf_frag:$src2
4112                                       (bc_frag (memopv2i64 addr:$src1)),
4113                                       (undef))))]>;
4114 }
4115
4116 multiclass sse2_pshuffle_y<string OpcodeStr, ValueType vt, PatFrag pshuf_frag,
4117                            PatFrag bc_frag> {
4118 def Yri : Ii8<0x70, MRMSrcReg,
4119               (outs VR256:$dst), (ins VR256:$src1, i8imm:$src2),
4120               !strconcat(OpcodeStr,
4121                          "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4122               [(set VR256:$dst, (vt (pshuf_frag:$src2 VR256:$src1,
4123                                                       (undef))))]>;
4124 def Ymi : Ii8<0x70, MRMSrcMem,
4125               (outs VR256:$dst), (ins i256mem:$src1, i8imm:$src2),
4126               !strconcat(OpcodeStr,
4127                          "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4128               [(set VR256:$dst, (vt (pshuf_frag:$src2
4129                                       (bc_frag (memopv4i64 addr:$src1)),
4130                                       (undef))))]>;
4131 }
4132 } // ExeDomain = SSEPackedInt
4133
4134 let Predicates = [HasAVX] in {
4135   let AddedComplexity = 5 in
4136   defm VPSHUFD : sse2_pshuffle<"vpshufd", v4i32, pshufd, bc_v4i32>, TB, OpSize,
4137                                VEX;
4138
4139   // SSE2 with ImmT == Imm8 and XS prefix.
4140   defm VPSHUFHW : sse2_pshuffle<"vpshufhw", v8i16, pshufhw, bc_v8i16>, XS,
4141                                VEX;
4142
4143   // SSE2 with ImmT == Imm8 and XD prefix.
4144   defm VPSHUFLW : sse2_pshuffle<"vpshuflw", v8i16, pshuflw, bc_v8i16>, XD,
4145                                VEX;
4146
4147   let AddedComplexity = 5 in
4148   def : Pat<(v4f32 (pshufd:$src2 VR128:$src1, (undef))),
4149             (VPSHUFDri VR128:$src1, (SHUFFLE_get_shuf_imm VR128:$src2))>;
4150   // Unary v4f32 shuffle with VPSHUF* in order to fold a load.
4151   def : Pat<(pshufd:$src2 (bc_v4i32 (memopv4f32 addr:$src1)), (undef)),
4152             (VPSHUFDmi addr:$src1, (SHUFFLE_get_shuf_imm VR128:$src2))>;
4153
4154   def : Pat<(v4i32 (X86PShufd (bc_v4i32 (memopv2i64 addr:$src1)),
4155                                    (i8 imm:$imm))),
4156             (VPSHUFDmi addr:$src1, imm:$imm)>;
4157   def : Pat<(v4i32 (X86PShufd (bc_v4i32 (memopv4f32 addr:$src1)),
4158                                    (i8 imm:$imm))),
4159             (VPSHUFDmi addr:$src1, imm:$imm)>;
4160   def : Pat<(v4f32 (X86PShufd VR128:$src1, (i8 imm:$imm))),
4161             (VPSHUFDri VR128:$src1, imm:$imm)>;
4162   def : Pat<(v4i32 (X86PShufd VR128:$src1, (i8 imm:$imm))),
4163             (VPSHUFDri VR128:$src1, imm:$imm)>;
4164   def : Pat<(v8i16 (X86PShufhw VR128:$src, (i8 imm:$imm))),
4165             (VPSHUFHWri VR128:$src, imm:$imm)>;
4166   def : Pat<(v8i16 (X86PShufhw (bc_v8i16 (memopv2i64 addr:$src)),
4167                                (i8 imm:$imm))),
4168             (VPSHUFHWmi addr:$src, imm:$imm)>;
4169   def : Pat<(v8i16 (X86PShuflw VR128:$src, (i8 imm:$imm))),
4170             (VPSHUFLWri VR128:$src, imm:$imm)>;
4171   def : Pat<(v8i16 (X86PShuflw (bc_v8i16 (memopv2i64 addr:$src)),
4172                                (i8 imm:$imm))),
4173             (VPSHUFLWmi addr:$src, imm:$imm)>;
4174 }
4175
4176 let Predicates = [HasAVX2] in {
4177   let AddedComplexity = 5 in
4178   defm VPSHUFD : sse2_pshuffle_y<"vpshufd", v8i32, pshufd, bc_v8i32>, TB,
4179                                  OpSize, VEX;
4180
4181   // SSE2 with ImmT == Imm8 and XS prefix.
4182   defm VPSHUFHW : sse2_pshuffle_y<"vpshufhw", v16i16, pshufhw, bc_v16i16>, XS,
4183                                   VEX;
4184
4185   // SSE2 with ImmT == Imm8 and XD prefix.
4186   defm VPSHUFLW : sse2_pshuffle_y<"vpshuflw", v16i16, pshuflw, bc_v16i16>, XD,
4187                                   VEX;
4188 }
4189
4190 let Predicates = [HasSSE2] in {
4191   let AddedComplexity = 5 in
4192   defm PSHUFD : sse2_pshuffle<"pshufd", v4i32, pshufd, bc_v4i32>, TB, OpSize;
4193
4194   // SSE2 with ImmT == Imm8 and XS prefix.
4195   defm PSHUFHW : sse2_pshuffle<"pshufhw", v8i16, pshufhw, bc_v8i16>, XS;
4196
4197   // SSE2 with ImmT == Imm8 and XD prefix.
4198   defm PSHUFLW : sse2_pshuffle<"pshuflw", v8i16, pshuflw, bc_v8i16>, XD;
4199
4200   let AddedComplexity = 5 in
4201   def : Pat<(v4f32 (pshufd:$src2 VR128:$src1, (undef))),
4202             (PSHUFDri VR128:$src1, (SHUFFLE_get_shuf_imm VR128:$src2))>;
4203   // Unary v4f32 shuffle with PSHUF* in order to fold a load.
4204   def : Pat<(pshufd:$src2 (bc_v4i32 (memopv4f32 addr:$src1)), (undef)),
4205             (PSHUFDmi addr:$src1, (SHUFFLE_get_shuf_imm VR128:$src2))>;
4206
4207   def : Pat<(v4i32 (X86PShufd (bc_v4i32 (memopv2i64 addr:$src1)),
4208                                    (i8 imm:$imm))),
4209             (PSHUFDmi addr:$src1, imm:$imm)>;
4210   def : Pat<(v4i32 (X86PShufd (bc_v4i32 (memopv4f32 addr:$src1)),
4211                                    (i8 imm:$imm))),
4212             (PSHUFDmi addr:$src1, imm:$imm)>;
4213   def : Pat<(v4f32 (X86PShufd VR128:$src1, (i8 imm:$imm))),
4214             (PSHUFDri VR128:$src1, imm:$imm)>;
4215   def : Pat<(v4i32 (X86PShufd VR128:$src1, (i8 imm:$imm))),
4216             (PSHUFDri VR128:$src1, imm:$imm)>;
4217   def : Pat<(v8i16 (X86PShufhw VR128:$src, (i8 imm:$imm))),
4218             (PSHUFHWri VR128:$src, imm:$imm)>;
4219   def : Pat<(v8i16 (X86PShufhw (bc_v8i16 (memopv2i64 addr:$src)),
4220                                (i8 imm:$imm))),
4221             (PSHUFHWmi addr:$src, imm:$imm)>;
4222   def : Pat<(v8i16 (X86PShuflw VR128:$src, (i8 imm:$imm))),
4223             (PSHUFLWri VR128:$src, imm:$imm)>;
4224   def : Pat<(v8i16 (X86PShuflw (bc_v8i16 (memopv2i64 addr:$src)),
4225                                (i8 imm:$imm))),
4226             (PSHUFLWmi addr:$src, imm:$imm)>;
4227 }
4228
4229 //===---------------------------------------------------------------------===//
4230 // SSE2 - Packed Integer Unpack Instructions
4231 //===---------------------------------------------------------------------===//
4232
4233 let ExeDomain = SSEPackedInt in {
4234 multiclass sse2_unpack<bits<8> opc, string OpcodeStr, ValueType vt,
4235                        SDNode OpNode, PatFrag bc_frag, bit Is2Addr = 1> {
4236   def rr : PDI<opc, MRMSrcReg,
4237       (outs VR128:$dst), (ins VR128:$src1, VR128:$src2),
4238       !if(Is2Addr,
4239           !strconcat(OpcodeStr,"\t{$src2, $dst|$dst, $src2}"),
4240           !strconcat(OpcodeStr,"\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
4241       [(set VR128:$dst, (vt (OpNode VR128:$src1, VR128:$src2)))]>;
4242   def rm : PDI<opc, MRMSrcMem,
4243       (outs VR128:$dst), (ins VR128:$src1, i128mem:$src2),
4244       !if(Is2Addr,
4245           !strconcat(OpcodeStr,"\t{$src2, $dst|$dst, $src2}"),
4246           !strconcat(OpcodeStr,"\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
4247       [(set VR128:$dst, (OpNode VR128:$src1,
4248                                   (bc_frag (memopv2i64
4249                                                addr:$src2))))]>;
4250 }
4251
4252 multiclass sse2_unpack_y<bits<8> opc, string OpcodeStr, ValueType vt,
4253                          SDNode OpNode, PatFrag bc_frag> {
4254   def Yrr : PDI<opc, MRMSrcReg,
4255       (outs VR256:$dst), (ins VR256:$src1, VR256:$src2),
4256       !strconcat(OpcodeStr,"\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4257       [(set VR256:$dst, (vt (OpNode VR256:$src1, VR256:$src2)))]>;
4258   def Yrm : PDI<opc, MRMSrcMem,
4259       (outs VR256:$dst), (ins VR256:$src1, i256mem:$src2),
4260       !strconcat(OpcodeStr,"\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4261       [(set VR256:$dst, (OpNode VR256:$src1,
4262                                   (bc_frag (memopv4i64 addr:$src2))))]>;
4263 }
4264
4265 let Predicates = [HasAVX] in {
4266   defm VPUNPCKLBW  : sse2_unpack<0x60, "vpunpcklbw", v16i8, X86Unpckl,
4267                                  bc_v16i8, 0>, VEX_4V;
4268   defm VPUNPCKLWD  : sse2_unpack<0x61, "vpunpcklwd", v8i16, X86Unpckl,
4269                                  bc_v8i16, 0>, VEX_4V;
4270   defm VPUNPCKLDQ  : sse2_unpack<0x62, "vpunpckldq", v4i32, X86Unpckl,
4271                                  bc_v4i32, 0>, VEX_4V;
4272   defm VPUNPCKLQDQ : sse2_unpack<0x6C, "vpunpcklqdq", v2i64, X86Unpckl,
4273                                  bc_v2i64, 0>, VEX_4V;
4274
4275   defm VPUNPCKHBW  : sse2_unpack<0x68, "vpunpckhbw", v16i8, X86Unpckh,
4276                                  bc_v16i8, 0>, VEX_4V;
4277   defm VPUNPCKHWD  : sse2_unpack<0x69, "vpunpckhwd", v8i16, X86Unpckh,
4278                                  bc_v8i16, 0>, VEX_4V;
4279   defm VPUNPCKHDQ  : sse2_unpack<0x6A, "vpunpckhdq", v4i32, X86Unpckh,
4280                                  bc_v4i32, 0>, VEX_4V;
4281   defm VPUNPCKHQDQ : sse2_unpack<0x6D, "vpunpckhqdq", v2i64, X86Unpckh,
4282                                  bc_v2i64, 0>, VEX_4V;
4283 }
4284
4285 let Predicates = [HasAVX2] in {
4286   defm VPUNPCKLBW  : sse2_unpack_y<0x60, "vpunpcklbw", v32i8, X86Unpckl,
4287                                    bc_v32i8>, VEX_4V;
4288   defm VPUNPCKLWD  : sse2_unpack_y<0x61, "vpunpcklwd", v16i16, X86Unpckl,
4289                                    bc_v16i16>, VEX_4V;
4290   defm VPUNPCKLDQ  : sse2_unpack_y<0x62, "vpunpckldq", v8i32, X86Unpckl,
4291                                    bc_v8i32>, VEX_4V;
4292   defm VPUNPCKLQDQ : sse2_unpack_y<0x6C, "vpunpcklqdq", v4i64, X86Unpckl,
4293                                    bc_v4i64>, VEX_4V;
4294
4295   defm VPUNPCKHBW  : sse2_unpack_y<0x68, "vpunpckhbw", v32i8, X86Unpckh,
4296                                    bc_v32i8>, VEX_4V;
4297   defm VPUNPCKHWD  : sse2_unpack_y<0x69, "vpunpckhwd", v16i16, X86Unpckh,
4298                                    bc_v16i16>, VEX_4V;
4299   defm VPUNPCKHDQ  : sse2_unpack_y<0x6A, "vpunpckhdq", v8i32, X86Unpckh,
4300                                    bc_v8i32>, VEX_4V;
4301   defm VPUNPCKHQDQ : sse2_unpack_y<0x6D, "vpunpckhqdq", v4i64, X86Unpckh,
4302                                    bc_v4i64>, VEX_4V;
4303 }
4304
4305 let Constraints = "$src1 = $dst" in {
4306   defm PUNPCKLBW  : sse2_unpack<0x60, "punpcklbw", v16i8, X86Unpckl,
4307                                 bc_v16i8>;
4308   defm PUNPCKLWD  : sse2_unpack<0x61, "punpcklwd", v8i16, X86Unpckl,
4309                                 bc_v8i16>;
4310   defm PUNPCKLDQ  : sse2_unpack<0x62, "punpckldq", v4i32, X86Unpckl,
4311                                 bc_v4i32>;
4312   defm PUNPCKLQDQ : sse2_unpack<0x6C, "punpcklqdq", v2i64, X86Unpckl,
4313                                 bc_v2i64>;
4314
4315   defm PUNPCKHBW  : sse2_unpack<0x68, "punpckhbw", v16i8, X86Unpckh,
4316                                 bc_v16i8>;
4317   defm PUNPCKHWD  : sse2_unpack<0x69, "punpckhwd", v8i16, X86Unpckh,
4318                                 bc_v8i16>;
4319   defm PUNPCKHDQ  : sse2_unpack<0x6A, "punpckhdq", v4i32, X86Unpckh,
4320                                 bc_v4i32>;
4321   defm PUNPCKHQDQ : sse2_unpack<0x6D, "punpckhqdq", v2i64, X86Unpckh,
4322                                 bc_v2i64>;
4323 }
4324 } // ExeDomain = SSEPackedInt
4325
4326 // Patterns for using AVX1 instructions with integer vectors
4327 // Here to give AVX2 priority
4328 let Predicates = [HasAVX] in {
4329   def : Pat<(v8i32 (X86Unpckl VR256:$src1, (bc_v8i32 (memopv4i64 addr:$src2)))),
4330             (VUNPCKLPSYrm VR256:$src1, addr:$src2)>;
4331   def : Pat<(v8i32 (X86Unpckl VR256:$src1, VR256:$src2)),
4332             (VUNPCKLPSYrr VR256:$src1, VR256:$src2)>;
4333   def : Pat<(v8i32 (X86Unpckh VR256:$src1, (bc_v8i32 (memopv4i64 addr:$src2)))),
4334             (VUNPCKHPSYrm VR256:$src1, addr:$src2)>;
4335   def : Pat<(v8i32 (X86Unpckh VR256:$src1, VR256:$src2)),
4336             (VUNPCKHPSYrr VR256:$src1, VR256:$src2)>;
4337
4338   def : Pat<(v4i64 (X86Unpckl VR256:$src1, (memopv4i64 addr:$src2))),
4339             (VUNPCKLPDYrm VR256:$src1, addr:$src2)>;
4340   def : Pat<(v4i64 (X86Unpckl VR256:$src1, VR256:$src2)),
4341             (VUNPCKLPDYrr VR256:$src1, VR256:$src2)>;
4342   def : Pat<(v4i64 (X86Unpckh VR256:$src1, (memopv4i64 addr:$src2))),
4343             (VUNPCKHPDYrm VR256:$src1, addr:$src2)>;
4344   def : Pat<(v4i64 (X86Unpckh VR256:$src1, VR256:$src2)),
4345             (VUNPCKHPDYrr VR256:$src1, VR256:$src2)>;
4346 }
4347
4348 // Splat v2f64 / v2i64
4349 let AddedComplexity = 10 in {
4350   def : Pat<(splat_lo (v2i64 VR128:$src), (undef)),
4351             (PUNPCKLQDQrr VR128:$src, VR128:$src)>, Requires<[HasSSE2]>;
4352   def : Pat<(splat_lo (v2i64 VR128:$src), (undef)),
4353             (VPUNPCKLQDQrr VR128:$src, VR128:$src)>, Requires<[HasAVX]>;
4354 }
4355
4356 //===---------------------------------------------------------------------===//
4357 // SSE2 - Packed Integer Extract and Insert
4358 //===---------------------------------------------------------------------===//
4359
4360 let ExeDomain = SSEPackedInt in {
4361 multiclass sse2_pinsrw<bit Is2Addr = 1> {
4362   def rri : Ii8<0xC4, MRMSrcReg,
4363        (outs VR128:$dst), (ins VR128:$src1,
4364         GR32:$src2, i32i8imm:$src3),
4365        !if(Is2Addr,
4366            "pinsrw\t{$src3, $src2, $dst|$dst, $src2, $src3}",
4367            "vpinsrw\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
4368        [(set VR128:$dst,
4369          (X86pinsrw VR128:$src1, GR32:$src2, imm:$src3))]>;
4370   def rmi : Ii8<0xC4, MRMSrcMem,
4371                        (outs VR128:$dst), (ins VR128:$src1,
4372                         i16mem:$src2, i32i8imm:$src3),
4373        !if(Is2Addr,
4374            "pinsrw\t{$src3, $src2, $dst|$dst, $src2, $src3}",
4375            "vpinsrw\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
4376        [(set VR128:$dst,
4377          (X86pinsrw VR128:$src1, (extloadi16 addr:$src2),
4378                     imm:$src3))]>;
4379 }
4380
4381 // Extract
4382 let Predicates = [HasAVX] in
4383 def VPEXTRWri : Ii8<0xC5, MRMSrcReg,
4384                     (outs GR32:$dst), (ins VR128:$src1, i32i8imm:$src2),
4385                     "vpextrw\t{$src2, $src1, $dst|$dst, $src1, $src2}",
4386                     [(set GR32:$dst, (X86pextrw (v8i16 VR128:$src1),
4387                                                 imm:$src2))]>, TB, OpSize, VEX;
4388 def PEXTRWri : PDIi8<0xC5, MRMSrcReg,
4389                     (outs GR32:$dst), (ins VR128:$src1, i32i8imm:$src2),
4390                     "pextrw\t{$src2, $src1, $dst|$dst, $src1, $src2}",
4391                     [(set GR32:$dst, (X86pextrw (v8i16 VR128:$src1),
4392                                                 imm:$src2))]>;
4393
4394 // Insert
4395 let Predicates = [HasAVX] in {
4396   defm VPINSRW : sse2_pinsrw<0>, TB, OpSize, VEX_4V;
4397   def  VPINSRWrr64i : Ii8<0xC4, MRMSrcReg, (outs VR128:$dst),
4398        (ins VR128:$src1, GR64:$src2, i32i8imm:$src3),
4399        "vpinsrw\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
4400        []>, TB, OpSize, VEX_4V;
4401 }
4402
4403 let Constraints = "$src1 = $dst" in
4404   defm PINSRW : sse2_pinsrw, TB, OpSize, Requires<[HasSSE2]>;
4405
4406 } // ExeDomain = SSEPackedInt
4407
4408 //===---------------------------------------------------------------------===//
4409 // SSE2 - Packed Mask Creation
4410 //===---------------------------------------------------------------------===//
4411
4412 let ExeDomain = SSEPackedInt in {
4413
4414 def VPMOVMSKBrr  : VPDI<0xD7, MRMSrcReg, (outs GR32:$dst), (ins VR128:$src),
4415            "pmovmskb\t{$src, $dst|$dst, $src}",
4416            [(set GR32:$dst, (int_x86_sse2_pmovmskb_128 VR128:$src))]>, VEX;
4417 def VPMOVMSKBr64r : VPDI<0xD7, MRMSrcReg, (outs GR64:$dst), (ins VR128:$src),
4418            "pmovmskb\t{$src, $dst|$dst, $src}", []>, VEX;
4419
4420 let Predicates = [HasAVX2] in {
4421 def VPMOVMSKBYrr  : VPDI<0xD7, MRMSrcReg, (outs GR32:$dst), (ins VR256:$src),
4422            "pmovmskb\t{$src, $dst|$dst, $src}",
4423            [(set GR32:$dst, (int_x86_avx2_pmovmskb VR256:$src))]>, VEX;
4424 def VPMOVMSKBYr64r : VPDI<0xD7, MRMSrcReg, (outs GR64:$dst), (ins VR256:$src),
4425            "pmovmskb\t{$src, $dst|$dst, $src}", []>, VEX;
4426 }
4427
4428 def PMOVMSKBrr : PDI<0xD7, MRMSrcReg, (outs GR32:$dst), (ins VR128:$src),
4429            "pmovmskb\t{$src, $dst|$dst, $src}",
4430            [(set GR32:$dst, (int_x86_sse2_pmovmskb_128 VR128:$src))]>;
4431
4432 } // ExeDomain = SSEPackedInt
4433
4434 //===---------------------------------------------------------------------===//
4435 // SSE2 - Conditional Store
4436 //===---------------------------------------------------------------------===//
4437
4438 let ExeDomain = SSEPackedInt in {
4439
4440 let Uses = [EDI] in
4441 def VMASKMOVDQU : VPDI<0xF7, MRMSrcReg, (outs),
4442            (ins VR128:$src, VR128:$mask),
4443            "maskmovdqu\t{$mask, $src|$src, $mask}",
4444            [(int_x86_sse2_maskmov_dqu VR128:$src, VR128:$mask, EDI)]>, VEX;
4445 let Uses = [RDI] in
4446 def VMASKMOVDQU64 : VPDI<0xF7, MRMSrcReg, (outs),
4447            (ins VR128:$src, VR128:$mask),
4448            "maskmovdqu\t{$mask, $src|$src, $mask}",
4449            [(int_x86_sse2_maskmov_dqu VR128:$src, VR128:$mask, RDI)]>, VEX;
4450
4451 let Uses = [EDI] in
4452 def MASKMOVDQU : PDI<0xF7, MRMSrcReg, (outs), (ins VR128:$src, VR128:$mask),
4453            "maskmovdqu\t{$mask, $src|$src, $mask}",
4454            [(int_x86_sse2_maskmov_dqu VR128:$src, VR128:$mask, EDI)]>;
4455 let Uses = [RDI] in
4456 def MASKMOVDQU64 : PDI<0xF7, MRMSrcReg, (outs), (ins VR128:$src, VR128:$mask),
4457            "maskmovdqu\t{$mask, $src|$src, $mask}",
4458            [(int_x86_sse2_maskmov_dqu VR128:$src, VR128:$mask, RDI)]>;
4459
4460 } // ExeDomain = SSEPackedInt
4461
4462 //===---------------------------------------------------------------------===//
4463 // SSE2 - Move Doubleword
4464 //===---------------------------------------------------------------------===//
4465
4466 //===---------------------------------------------------------------------===//
4467 // Move Int Doubleword to Packed Double Int
4468 //
4469 def VMOVDI2PDIrr : VPDI<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR32:$src),
4470                       "movd\t{$src, $dst|$dst, $src}",
4471                       [(set VR128:$dst,
4472                         (v4i32 (scalar_to_vector GR32:$src)))]>, VEX;
4473 def VMOVDI2PDIrm : VPDI<0x6E, MRMSrcMem, (outs VR128:$dst), (ins i32mem:$src),
4474                       "movd\t{$src, $dst|$dst, $src}",
4475                       [(set VR128:$dst,
4476                         (v4i32 (scalar_to_vector (loadi32 addr:$src))))]>,
4477                       VEX;
4478 def VMOV64toPQIrr : VRPDI<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR64:$src),
4479                         "mov{d|q}\t{$src, $dst|$dst, $src}",
4480                         [(set VR128:$dst,
4481                           (v2i64 (scalar_to_vector GR64:$src)))]>, VEX;
4482 def VMOV64toSDrr : VRPDI<0x6E, MRMSrcReg, (outs FR64:$dst), (ins GR64:$src),
4483                        "mov{d|q}\t{$src, $dst|$dst, $src}",
4484                        [(set FR64:$dst, (bitconvert GR64:$src))]>, VEX;
4485
4486 def MOVDI2PDIrr : PDI<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR32:$src),
4487                       "movd\t{$src, $dst|$dst, $src}",
4488                       [(set VR128:$dst,
4489                         (v4i32 (scalar_to_vector GR32:$src)))]>;
4490 def MOVDI2PDIrm : PDI<0x6E, MRMSrcMem, (outs VR128:$dst), (ins i32mem:$src),
4491                       "movd\t{$src, $dst|$dst, $src}",
4492                       [(set VR128:$dst,
4493                         (v4i32 (scalar_to_vector (loadi32 addr:$src))))]>;
4494 def MOV64toPQIrr : RPDI<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR64:$src),
4495                         "mov{d|q}\t{$src, $dst|$dst, $src}",
4496                         [(set VR128:$dst,
4497                           (v2i64 (scalar_to_vector GR64:$src)))]>;
4498 def MOV64toSDrr : RPDI<0x6E, MRMSrcReg, (outs FR64:$dst), (ins GR64:$src),
4499                        "mov{d|q}\t{$src, $dst|$dst, $src}",
4500                        [(set FR64:$dst, (bitconvert GR64:$src))]>;
4501
4502 //===---------------------------------------------------------------------===//
4503 // Move Int Doubleword to Single Scalar
4504 //
4505 def VMOVDI2SSrr  : VPDI<0x6E, MRMSrcReg, (outs FR32:$dst), (ins GR32:$src),
4506                       "movd\t{$src, $dst|$dst, $src}",
4507                       [(set FR32:$dst, (bitconvert GR32:$src))]>, VEX;
4508
4509 def VMOVDI2SSrm  : VPDI<0x6E, MRMSrcMem, (outs FR32:$dst), (ins i32mem:$src),
4510                       "movd\t{$src, $dst|$dst, $src}",
4511                       [(set FR32:$dst, (bitconvert (loadi32 addr:$src)))]>,
4512                       VEX;
4513 def MOVDI2SSrr  : PDI<0x6E, MRMSrcReg, (outs FR32:$dst), (ins GR32:$src),
4514                       "movd\t{$src, $dst|$dst, $src}",
4515                       [(set FR32:$dst, (bitconvert GR32:$src))]>;
4516
4517 def MOVDI2SSrm  : PDI<0x6E, MRMSrcMem, (outs FR32:$dst), (ins i32mem:$src),
4518                       "movd\t{$src, $dst|$dst, $src}",
4519                       [(set FR32:$dst, (bitconvert (loadi32 addr:$src)))]>;
4520
4521 //===---------------------------------------------------------------------===//
4522 // Move Packed Doubleword Int to Packed Double Int
4523 //
4524 def VMOVPDI2DIrr  : VPDI<0x7E, MRMDestReg, (outs GR32:$dst), (ins VR128:$src),
4525                        "movd\t{$src, $dst|$dst, $src}",
4526                        [(set GR32:$dst, (vector_extract (v4i32 VR128:$src),
4527                                         (iPTR 0)))]>, VEX;
4528 def VMOVPDI2DImr  : VPDI<0x7E, MRMDestMem, (outs),
4529                        (ins i32mem:$dst, VR128:$src),
4530                        "movd\t{$src, $dst|$dst, $src}",
4531                        [(store (i32 (vector_extract (v4i32 VR128:$src),
4532                                      (iPTR 0))), addr:$dst)]>, VEX;
4533 def MOVPDI2DIrr  : PDI<0x7E, MRMDestReg, (outs GR32:$dst), (ins VR128:$src),
4534                        "movd\t{$src, $dst|$dst, $src}",
4535                        [(set GR32:$dst, (vector_extract (v4i32 VR128:$src),
4536                                         (iPTR 0)))]>;
4537 def MOVPDI2DImr  : PDI<0x7E, MRMDestMem, (outs), (ins i32mem:$dst, VR128:$src),
4538                        "movd\t{$src, $dst|$dst, $src}",
4539                        [(store (i32 (vector_extract (v4i32 VR128:$src),
4540                                      (iPTR 0))), addr:$dst)]>;
4541
4542 //===---------------------------------------------------------------------===//
4543 // Move Packed Doubleword Int first element to Doubleword Int
4544 //
4545 def VMOVPQIto64rr : I<0x7E, MRMDestReg, (outs GR64:$dst), (ins VR128:$src),
4546                           "mov{d|q}\t{$src, $dst|$dst, $src}",
4547                           [(set GR64:$dst, (vector_extract (v2i64 VR128:$src),
4548                                                            (iPTR 0)))]>,
4549                       TB, OpSize, VEX, VEX_W, Requires<[HasAVX, In64BitMode]>;
4550
4551 def MOVPQIto64rr : RPDI<0x7E, MRMDestReg, (outs GR64:$dst), (ins VR128:$src),
4552                         "mov{d|q}\t{$src, $dst|$dst, $src}",
4553                         [(set GR64:$dst, (vector_extract (v2i64 VR128:$src),
4554                                                          (iPTR 0)))]>;
4555
4556 //===---------------------------------------------------------------------===//
4557 // Bitcast FR64 <-> GR64
4558 //
4559 let Predicates = [HasAVX] in
4560 def VMOV64toSDrm : S3SI<0x7E, MRMSrcMem, (outs FR64:$dst), (ins i64mem:$src),
4561                         "vmovq\t{$src, $dst|$dst, $src}",
4562                         [(set FR64:$dst, (bitconvert (loadi64 addr:$src)))]>,
4563                         VEX;
4564 def VMOVSDto64rr : VRPDI<0x7E, MRMDestReg, (outs GR64:$dst), (ins FR64:$src),
4565                          "mov{d|q}\t{$src, $dst|$dst, $src}",
4566                          [(set GR64:$dst, (bitconvert FR64:$src))]>, VEX;
4567 def VMOVSDto64mr : VRPDI<0x7E, MRMDestMem, (outs), (ins i64mem:$dst, FR64:$src),
4568                          "movq\t{$src, $dst|$dst, $src}",
4569                          [(store (i64 (bitconvert FR64:$src)), addr:$dst)]>,
4570                          VEX;
4571
4572 def MOV64toSDrm : S3SI<0x7E, MRMSrcMem, (outs FR64:$dst), (ins i64mem:$src),
4573                        "movq\t{$src, $dst|$dst, $src}",
4574                        [(set FR64:$dst, (bitconvert (loadi64 addr:$src)))]>;
4575 def MOVSDto64rr : RPDI<0x7E, MRMDestReg, (outs GR64:$dst), (ins FR64:$src),
4576                        "mov{d|q}\t{$src, $dst|$dst, $src}",
4577                        [(set GR64:$dst, (bitconvert FR64:$src))]>;
4578 def MOVSDto64mr : RPDI<0x7E, MRMDestMem, (outs), (ins i64mem:$dst, FR64:$src),
4579                        "movq\t{$src, $dst|$dst, $src}",
4580                        [(store (i64 (bitconvert FR64:$src)), addr:$dst)]>;
4581
4582 //===---------------------------------------------------------------------===//
4583 // Move Scalar Single to Double Int
4584 //
4585 def VMOVSS2DIrr  : VPDI<0x7E, MRMDestReg, (outs GR32:$dst), (ins FR32:$src),
4586                       "movd\t{$src, $dst|$dst, $src}",
4587                       [(set GR32:$dst, (bitconvert FR32:$src))]>, VEX;
4588 def VMOVSS2DImr  : VPDI<0x7E, MRMDestMem, (outs), (ins i32mem:$dst, FR32:$src),
4589                       "movd\t{$src, $dst|$dst, $src}",
4590                       [(store (i32 (bitconvert FR32:$src)), addr:$dst)]>, VEX;
4591 def MOVSS2DIrr  : PDI<0x7E, MRMDestReg, (outs GR32:$dst), (ins FR32:$src),
4592                       "movd\t{$src, $dst|$dst, $src}",
4593                       [(set GR32:$dst, (bitconvert FR32:$src))]>;
4594 def MOVSS2DImr  : PDI<0x7E, MRMDestMem, (outs), (ins i32mem:$dst, FR32:$src),
4595                       "movd\t{$src, $dst|$dst, $src}",
4596                       [(store (i32 (bitconvert FR32:$src)), addr:$dst)]>;
4597
4598 //===---------------------------------------------------------------------===//
4599 // Patterns and instructions to describe movd/movq to XMM register zero-extends
4600 //
4601 let AddedComplexity = 15 in {
4602 def VMOVZDI2PDIrr : VPDI<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR32:$src),
4603                        "movd\t{$src, $dst|$dst, $src}",
4604                        [(set VR128:$dst, (v4i32 (X86vzmovl
4605                                       (v4i32 (scalar_to_vector GR32:$src)))))]>,
4606                                       VEX;
4607 def VMOVZQI2PQIrr : VPDI<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR64:$src),
4608                        "mov{d|q}\t{$src, $dst|$dst, $src}", // X86-64 only
4609                        [(set VR128:$dst, (v2i64 (X86vzmovl
4610                                       (v2i64 (scalar_to_vector GR64:$src)))))]>,
4611                                       VEX, VEX_W;
4612 }
4613 let AddedComplexity = 15 in {
4614 def MOVZDI2PDIrr : PDI<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR32:$src),
4615                        "movd\t{$src, $dst|$dst, $src}",
4616                        [(set VR128:$dst, (v4i32 (X86vzmovl
4617                                       (v4i32 (scalar_to_vector GR32:$src)))))]>;
4618 def MOVZQI2PQIrr : RPDI<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR64:$src),
4619                        "mov{d|q}\t{$src, $dst|$dst, $src}", // X86-64 only
4620                        [(set VR128:$dst, (v2i64 (X86vzmovl
4621                                       (v2i64 (scalar_to_vector GR64:$src)))))]>;
4622 }
4623
4624 let AddedComplexity = 20 in {
4625 def VMOVZDI2PDIrm : VPDI<0x6E, MRMSrcMem, (outs VR128:$dst), (ins i32mem:$src),
4626                        "movd\t{$src, $dst|$dst, $src}",
4627                        [(set VR128:$dst,
4628                          (v4i32 (X86vzmovl (v4i32 (scalar_to_vector
4629                                                    (loadi32 addr:$src))))))]>,
4630                                                    VEX;
4631 def MOVZDI2PDIrm : PDI<0x6E, MRMSrcMem, (outs VR128:$dst), (ins i32mem:$src),
4632                        "movd\t{$src, $dst|$dst, $src}",
4633                        [(set VR128:$dst,
4634                          (v4i32 (X86vzmovl (v4i32 (scalar_to_vector
4635                                                    (loadi32 addr:$src))))))]>;
4636 }
4637
4638 let Predicates = [HasAVX] in {
4639   // AVX 128-bit movd/movq instruction write zeros in the high 128-bit part.
4640   let AddedComplexity = 20 in {
4641     def : Pat<(v4i32 (X86vzmovl (loadv4i32 addr:$src))),
4642               (VMOVZDI2PDIrm addr:$src)>;
4643     def : Pat<(v4i32 (X86vzmovl (bc_v4i32 (loadv4f32 addr:$src)))),
4644               (VMOVZDI2PDIrm addr:$src)>;
4645     def : Pat<(v4i32 (X86vzmovl (bc_v4i32 (loadv2i64 addr:$src)))),
4646               (VMOVZDI2PDIrm addr:$src)>;
4647   }
4648   // Use regular 128-bit instructions to match 256-bit scalar_to_vec+zext.
4649   def : Pat<(v8i32 (X86vzmovl (insert_subvector undef,
4650                                 (v4i32 (scalar_to_vector GR32:$src)),(i32 0)))),
4651             (SUBREG_TO_REG (i32 0), (VMOVZDI2PDIrr GR32:$src), sub_xmm)>;
4652   def : Pat<(v4i64 (X86vzmovl (insert_subvector undef,
4653                                 (v2i64 (scalar_to_vector GR64:$src)),(i32 0)))),
4654             (SUBREG_TO_REG (i64 0), (VMOVZQI2PQIrr GR64:$src), sub_xmm)>;
4655 }
4656
4657 let Predicates = [HasSSE2], AddedComplexity = 20 in {
4658   def : Pat<(v4i32 (X86vzmovl (loadv4i32 addr:$src))),
4659             (MOVZDI2PDIrm addr:$src)>;
4660   def : Pat<(v4i32 (X86vzmovl (bc_v4i32 (loadv4f32 addr:$src)))),
4661             (MOVZDI2PDIrm addr:$src)>;
4662   def : Pat<(v4i32 (X86vzmovl (bc_v4i32 (loadv2i64 addr:$src)))),
4663             (MOVZDI2PDIrm addr:$src)>;
4664 }
4665
4666 // These are the correct encodings of the instructions so that we know how to
4667 // read correct assembly, even though we continue to emit the wrong ones for
4668 // compatibility with Darwin's buggy assembler.
4669 def : InstAlias<"movq\t{$src, $dst|$dst, $src}",
4670                 (MOV64toPQIrr VR128:$dst, GR64:$src), 0>;
4671 def : InstAlias<"movq\t{$src, $dst|$dst, $src}",
4672                 (MOV64toSDrr FR64:$dst, GR64:$src), 0>;
4673 def : InstAlias<"movq\t{$src, $dst|$dst, $src}",
4674                 (MOVPQIto64rr GR64:$dst, VR128:$src), 0>;
4675 def : InstAlias<"movq\t{$src, $dst|$dst, $src}",
4676                 (MOVSDto64rr GR64:$dst, FR64:$src), 0>;
4677 def : InstAlias<"movq\t{$src, $dst|$dst, $src}",
4678                 (VMOVZQI2PQIrr VR128:$dst, GR64:$src), 0>;
4679 def : InstAlias<"movq\t{$src, $dst|$dst, $src}",
4680                 (MOVZQI2PQIrr VR128:$dst, GR64:$src), 0>;
4681
4682 //===---------------------------------------------------------------------===//
4683 // SSE2 - Move Quadword
4684 //===---------------------------------------------------------------------===//
4685
4686 //===---------------------------------------------------------------------===//
4687 // Move Quadword Int to Packed Quadword Int
4688 //
4689 def VMOVQI2PQIrm : I<0x7E, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
4690                     "vmovq\t{$src, $dst|$dst, $src}",
4691                     [(set VR128:$dst,
4692                       (v2i64 (scalar_to_vector (loadi64 addr:$src))))]>, XS,
4693                     VEX, Requires<[HasAVX]>;
4694 def MOVQI2PQIrm : I<0x7E, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
4695                     "movq\t{$src, $dst|$dst, $src}",
4696                     [(set VR128:$dst,
4697                       (v2i64 (scalar_to_vector (loadi64 addr:$src))))]>, XS,
4698                     Requires<[HasSSE2]>; // SSE2 instruction with XS Prefix
4699
4700 //===---------------------------------------------------------------------===//
4701 // Move Packed Quadword Int to Quadword Int
4702 //
4703 def VMOVPQI2QImr : VPDI<0xD6, MRMDestMem, (outs), (ins i64mem:$dst, VR128:$src),
4704                       "movq\t{$src, $dst|$dst, $src}",
4705                       [(store (i64 (vector_extract (v2i64 VR128:$src),
4706                                     (iPTR 0))), addr:$dst)]>, VEX;
4707 def MOVPQI2QImr : PDI<0xD6, MRMDestMem, (outs), (ins i64mem:$dst, VR128:$src),
4708                       "movq\t{$src, $dst|$dst, $src}",
4709                       [(store (i64 (vector_extract (v2i64 VR128:$src),
4710                                     (iPTR 0))), addr:$dst)]>;
4711
4712 //===---------------------------------------------------------------------===//
4713 // Store / copy lower 64-bits of a XMM register.
4714 //
4715 def VMOVLQ128mr : VPDI<0xD6, MRMDestMem, (outs), (ins i64mem:$dst, VR128:$src),
4716                      "movq\t{$src, $dst|$dst, $src}",
4717                      [(int_x86_sse2_storel_dq addr:$dst, VR128:$src)]>, VEX;
4718 def MOVLQ128mr : PDI<0xD6, MRMDestMem, (outs), (ins i64mem:$dst, VR128:$src),
4719                      "movq\t{$src, $dst|$dst, $src}",
4720                      [(int_x86_sse2_storel_dq addr:$dst, VR128:$src)]>;
4721
4722 let AddedComplexity = 20 in
4723 def VMOVZQI2PQIrm : I<0x7E, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
4724                      "vmovq\t{$src, $dst|$dst, $src}",
4725                      [(set VR128:$dst,
4726                        (v2i64 (X86vzmovl (v2i64 (scalar_to_vector
4727                                                  (loadi64 addr:$src))))))]>,
4728                      XS, VEX, Requires<[HasAVX]>;
4729
4730 let AddedComplexity = 20 in
4731 def MOVZQI2PQIrm : I<0x7E, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
4732                      "movq\t{$src, $dst|$dst, $src}",
4733                      [(set VR128:$dst,
4734                        (v2i64 (X86vzmovl (v2i64 (scalar_to_vector
4735                                                  (loadi64 addr:$src))))))]>,
4736                      XS, Requires<[HasSSE2]>;
4737
4738 let Predicates = [HasAVX], AddedComplexity = 20 in {
4739   def : Pat<(v2i64 (X86vzmovl (loadv2i64 addr:$src))),
4740             (VMOVZQI2PQIrm addr:$src)>;
4741   def : Pat<(v2i64 (X86vzmovl (bc_v2i64 (loadv4f32 addr:$src)))),
4742             (VMOVZQI2PQIrm addr:$src)>;
4743   def : Pat<(v2i64 (X86vzload addr:$src)),
4744             (VMOVZQI2PQIrm addr:$src)>;
4745 }
4746
4747 let Predicates = [HasSSE2], AddedComplexity = 20 in {
4748   def : Pat<(v2i64 (X86vzmovl (loadv2i64 addr:$src))),
4749             (MOVZQI2PQIrm addr:$src)>;
4750   def : Pat<(v2i64 (X86vzmovl (bc_v2i64 (loadv4f32 addr:$src)))),
4751             (MOVZQI2PQIrm addr:$src)>;
4752   def : Pat<(v2i64 (X86vzload addr:$src)), (MOVZQI2PQIrm addr:$src)>;
4753 }
4754
4755 let Predicates = [HasAVX] in {
4756 def : Pat<(v4i64 (X86vzload addr:$src)),
4757           (SUBREG_TO_REG (i32 0), (VMOVAPSrm addr:$src), sub_xmm)>;
4758 }
4759
4760 //===---------------------------------------------------------------------===//
4761 // Moving from XMM to XMM and clear upper 64 bits. Note, there is a bug in
4762 // IA32 document. movq xmm1, xmm2 does clear the high bits.
4763 //
4764 let AddedComplexity = 15 in
4765 def VMOVZPQILo2PQIrr : I<0x7E, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
4766                         "vmovq\t{$src, $dst|$dst, $src}",
4767                     [(set VR128:$dst, (v2i64 (X86vzmovl (v2i64 VR128:$src))))]>,
4768                       XS, VEX, Requires<[HasAVX]>;
4769 let AddedComplexity = 15 in
4770 def MOVZPQILo2PQIrr : I<0x7E, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
4771                         "movq\t{$src, $dst|$dst, $src}",
4772                     [(set VR128:$dst, (v2i64 (X86vzmovl (v2i64 VR128:$src))))]>,
4773                       XS, Requires<[HasSSE2]>;
4774
4775 let AddedComplexity = 20 in
4776 def VMOVZPQILo2PQIrm : I<0x7E, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
4777                         "vmovq\t{$src, $dst|$dst, $src}",
4778                     [(set VR128:$dst, (v2i64 (X86vzmovl
4779                                              (loadv2i64 addr:$src))))]>,
4780                       XS, VEX, Requires<[HasAVX]>;
4781 let AddedComplexity = 20 in {
4782 def MOVZPQILo2PQIrm : I<0x7E, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
4783                         "movq\t{$src, $dst|$dst, $src}",
4784                     [(set VR128:$dst, (v2i64 (X86vzmovl
4785                                              (loadv2i64 addr:$src))))]>,
4786                       XS, Requires<[HasSSE2]>;
4787 }
4788
4789 let AddedComplexity = 20 in {
4790   let Predicates = [HasAVX] in {
4791     def : Pat<(v2i64 (X86vzmovl (bc_v2i64 (loadv4i32 addr:$src)))),
4792               (VMOVZPQILo2PQIrm addr:$src)>;
4793     def : Pat<(v2f64 (X86vzmovl (v2f64 VR128:$src))),
4794               (VMOVZPQILo2PQIrr VR128:$src)>;
4795   }
4796   let Predicates = [HasSSE2] in {
4797     def : Pat<(v2i64 (X86vzmovl (bc_v2i64 (loadv4i32 addr:$src)))),
4798               (MOVZPQILo2PQIrm addr:$src)>;
4799     def : Pat<(v2f64 (X86vzmovl (v2f64 VR128:$src))),
4800               (MOVZPQILo2PQIrr VR128:$src)>;
4801   }
4802 }
4803
4804 // Instructions to match in the assembler
4805 def VMOVQs64rr : VPDI<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR64:$src),
4806                       "movq\t{$src, $dst|$dst, $src}", []>, VEX, VEX_W;
4807 def VMOVQd64rr : VPDI<0x7E, MRMDestReg, (outs GR64:$dst), (ins VR128:$src),
4808                       "movq\t{$src, $dst|$dst, $src}", []>, VEX, VEX_W;
4809 // Recognize "movd" with GR64 destination, but encode as a "movq"
4810 def VMOVQd64rr_alt : VPDI<0x7E, MRMDestReg, (outs GR64:$dst), (ins VR128:$src),
4811                           "movd\t{$src, $dst|$dst, $src}", []>, VEX, VEX_W;
4812
4813 // Instructions for the disassembler
4814 // xr = XMM register
4815 // xm = mem64
4816
4817 let Predicates = [HasAVX] in
4818 def VMOVQxrxr: I<0x7E, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
4819                  "vmovq\t{$src, $dst|$dst, $src}", []>, VEX, XS;
4820 def MOVQxrxr : I<0x7E, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
4821                  "movq\t{$src, $dst|$dst, $src}", []>, XS;
4822
4823 //===---------------------------------------------------------------------===//
4824 // SSE3 - Conversion Instructions
4825 //===---------------------------------------------------------------------===//
4826
4827 // Convert Packed Double FP to Packed DW Integers
4828 let Predicates = [HasAVX] in {
4829 // The assembler can recognize rr 256-bit instructions by seeing a ymm
4830 // register, but the same isn't true when using memory operands instead.
4831 // Provide other assembly rr and rm forms to address this explicitly.
4832 def VCVTPD2DQrr  : S3DI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
4833                        "vcvtpd2dq\t{$src, $dst|$dst, $src}", []>, VEX;
4834 def VCVTPD2DQXrYr  : S3DI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR256:$src),
4835                        "vcvtpd2dq\t{$src, $dst|$dst, $src}", []>, VEX;
4836
4837 // XMM only
4838 def VCVTPD2DQXrr : S3DI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
4839                       "vcvtpd2dqx\t{$src, $dst|$dst, $src}", []>, VEX;
4840 def VCVTPD2DQXrm : S3DI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
4841                       "vcvtpd2dqx\t{$src, $dst|$dst, $src}", []>, VEX;
4842
4843 // YMM only
4844 def VCVTPD2DQYrr : S3DI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR256:$src),
4845                       "vcvtpd2dqy\t{$src, $dst|$dst, $src}", []>, VEX;
4846 def VCVTPD2DQYrm : S3DI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f256mem:$src),
4847                       "vcvtpd2dqy\t{$src, $dst|$dst, $src}", []>, VEX, VEX_L;
4848 }
4849
4850 def CVTPD2DQrm  : S3DI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
4851                        "cvtpd2dq\t{$src, $dst|$dst, $src}", []>;
4852 def CVTPD2DQrr  : S3DI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
4853                        "cvtpd2dq\t{$src, $dst|$dst, $src}", []>;
4854
4855 def : Pat<(v4i32 (fp_to_sint (v4f64 VR256:$src))),
4856           (VCVTPD2DQYrr VR256:$src)>;
4857 def : Pat<(v4i32 (fp_to_sint (memopv4f64 addr:$src))),
4858           (VCVTPD2DQYrm addr:$src)>;
4859
4860 // Convert Packed DW Integers to Packed Double FP
4861 let Predicates = [HasAVX] in {
4862 def VCVTDQ2PDrm  : S3SI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
4863                      "vcvtdq2pd\t{$src, $dst|$dst, $src}", []>, VEX;
4864 def VCVTDQ2PDrr  : S3SI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
4865                      "vcvtdq2pd\t{$src, $dst|$dst, $src}", []>, VEX;
4866 def VCVTDQ2PDYrm  : S3SI<0xE6, MRMSrcMem, (outs VR256:$dst), (ins f128mem:$src),
4867                      "vcvtdq2pd\t{$src, $dst|$dst, $src}", []>, VEX;
4868 def VCVTDQ2PDYrr  : S3SI<0xE6, MRMSrcReg, (outs VR256:$dst), (ins VR128:$src),
4869                      "vcvtdq2pd\t{$src, $dst|$dst, $src}", []>, VEX;
4870 }
4871
4872 def CVTDQ2PDrm  : S3SI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
4873                        "cvtdq2pd\t{$src, $dst|$dst, $src}", []>;
4874 def CVTDQ2PDrr  : S3SI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
4875                        "cvtdq2pd\t{$src, $dst|$dst, $src}", []>;
4876
4877 // AVX 256-bit register conversion intrinsics
4878 def : Pat<(int_x86_avx_cvtdq2_pd_256 VR128:$src),
4879            (VCVTDQ2PDYrr VR128:$src)>;
4880 def : Pat<(int_x86_avx_cvtdq2_pd_256 (bitconvert (memopv2i64 addr:$src))),
4881            (VCVTDQ2PDYrm addr:$src)>;
4882
4883 def : Pat<(int_x86_avx_cvt_pd2dq_256 VR256:$src),
4884           (VCVTPD2DQYrr VR256:$src)>;
4885 def : Pat<(int_x86_avx_cvt_pd2dq_256 (memopv4f64 addr:$src)),
4886           (VCVTPD2DQYrm addr:$src)>;
4887
4888 def : Pat<(v4f64 (sint_to_fp (v4i32 VR128:$src))),
4889           (VCVTDQ2PDYrr VR128:$src)>;
4890 def : Pat<(v4f64 (sint_to_fp (bc_v4i32 (memopv2i64 addr:$src)))),
4891           (VCVTDQ2PDYrm addr:$src)>;
4892
4893 //===---------------------------------------------------------------------===//
4894 // SSE3 - Replicate Single FP - MOVSHDUP and MOVSLDUP
4895 //===---------------------------------------------------------------------===//
4896 multiclass sse3_replicate_sfp<bits<8> op, SDNode OpNode, string OpcodeStr,
4897                               ValueType vt, RegisterClass RC, PatFrag mem_frag,
4898                               X86MemOperand x86memop> {
4899 def rr : S3SI<op, MRMSrcReg, (outs RC:$dst), (ins RC:$src),
4900                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
4901                       [(set RC:$dst, (vt (OpNode RC:$src)))]>;
4902 def rm : S3SI<op, MRMSrcMem, (outs RC:$dst), (ins x86memop:$src),
4903                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
4904                       [(set RC:$dst, (OpNode (mem_frag addr:$src)))]>;
4905 }
4906
4907 let Predicates = [HasAVX] in {
4908   defm VMOVSHDUP  : sse3_replicate_sfp<0x16, X86Movshdup, "vmovshdup",
4909                                        v4f32, VR128, memopv4f32, f128mem>, VEX;
4910   defm VMOVSLDUP  : sse3_replicate_sfp<0x12, X86Movsldup, "vmovsldup",
4911                                        v4f32, VR128, memopv4f32, f128mem>, VEX;
4912   defm VMOVSHDUPY : sse3_replicate_sfp<0x16, X86Movshdup, "vmovshdup",
4913                                        v8f32, VR256, memopv8f32, f256mem>, VEX;
4914   defm VMOVSLDUPY : sse3_replicate_sfp<0x12, X86Movsldup, "vmovsldup",
4915                                        v8f32, VR256, memopv8f32, f256mem>, VEX;
4916 }
4917 defm MOVSHDUP : sse3_replicate_sfp<0x16, X86Movshdup, "movshdup", v4f32, VR128,
4918                                    memopv4f32, f128mem>;
4919 defm MOVSLDUP : sse3_replicate_sfp<0x12, X86Movsldup, "movsldup", v4f32, VR128,
4920                                    memopv4f32, f128mem>;
4921
4922 let Predicates = [HasAVX] in {
4923   def : Pat<(v4i32 (X86Movshdup VR128:$src)),
4924             (VMOVSHDUPrr VR128:$src)>;
4925   def : Pat<(v4i32 (X86Movshdup (bc_v4i32 (memopv2i64 addr:$src)))),
4926             (VMOVSHDUPrm addr:$src)>;
4927   def : Pat<(v4i32 (X86Movsldup VR128:$src)),
4928             (VMOVSLDUPrr VR128:$src)>;
4929   def : Pat<(v4i32 (X86Movsldup (bc_v4i32 (memopv2i64 addr:$src)))),
4930             (VMOVSLDUPrm addr:$src)>;
4931   def : Pat<(v8i32 (X86Movshdup VR256:$src)),
4932             (VMOVSHDUPYrr VR256:$src)>;
4933   def : Pat<(v8i32 (X86Movshdup (bc_v8i32 (memopv4i64 addr:$src)))),
4934             (VMOVSHDUPYrm addr:$src)>;
4935   def : Pat<(v8i32 (X86Movsldup VR256:$src)),
4936             (VMOVSLDUPYrr VR256:$src)>;
4937   def : Pat<(v8i32 (X86Movsldup (bc_v8i32 (memopv4i64 addr:$src)))),
4938             (VMOVSLDUPYrm addr:$src)>;
4939 }
4940
4941 let Predicates = [HasSSE3] in {
4942   def : Pat<(v4i32 (X86Movshdup VR128:$src)),
4943             (MOVSHDUPrr VR128:$src)>;
4944   def : Pat<(v4i32 (X86Movshdup (bc_v4i32 (memopv2i64 addr:$src)))),
4945             (MOVSHDUPrm addr:$src)>;
4946   def : Pat<(v4i32 (X86Movsldup VR128:$src)),
4947             (MOVSLDUPrr VR128:$src)>;
4948   def : Pat<(v4i32 (X86Movsldup (bc_v4i32 (memopv2i64 addr:$src)))),
4949             (MOVSLDUPrm addr:$src)>;
4950 }
4951
4952 //===---------------------------------------------------------------------===//
4953 // SSE3 - Replicate Double FP - MOVDDUP
4954 //===---------------------------------------------------------------------===//
4955
4956 multiclass sse3_replicate_dfp<string OpcodeStr> {
4957 def rr  : S3DI<0x12, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
4958                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
4959                     [(set VR128:$dst,(v2f64 (movddup VR128:$src, (undef))))]>;
4960 def rm  : S3DI<0x12, MRMSrcMem, (outs VR128:$dst), (ins f64mem:$src),
4961                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
4962                     [(set VR128:$dst,
4963                       (v2f64 (movddup (scalar_to_vector (loadf64 addr:$src)),
4964                                       (undef))))]>;
4965 }
4966
4967 // FIXME: Merge with above classe when there're patterns for the ymm version
4968 multiclass sse3_replicate_dfp_y<string OpcodeStr> {
4969 let Predicates = [HasAVX] in {
4970   def rr  : S3DI<0x12, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
4971                       !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
4972                       []>;
4973   def rm  : S3DI<0x12, MRMSrcMem, (outs VR256:$dst), (ins f256mem:$src),
4974                       !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
4975                       []>;
4976   }
4977 }
4978
4979 defm MOVDDUP : sse3_replicate_dfp<"movddup">;
4980 defm VMOVDDUP  : sse3_replicate_dfp<"vmovddup">, VEX;
4981 defm VMOVDDUPY : sse3_replicate_dfp_y<"vmovddup">, VEX;
4982
4983 let Predicates = [HasAVX] in {
4984   def : Pat<(movddup (bc_v2f64 (v2i64 (scalar_to_vector (loadi64 addr:$src)))),
4985                    (undef)),
4986             (VMOVDDUPrm addr:$src)>;
4987   let AddedComplexity = 5 in {
4988   def : Pat<(movddup (memopv2f64 addr:$src), (undef)), (VMOVDDUPrm addr:$src)>;
4989   def : Pat<(movddup (bc_v4f32 (memopv2f64 addr:$src)), (undef)),
4990             (VMOVDDUPrm addr:$src)>;
4991   def : Pat<(movddup (memopv2i64 addr:$src), (undef)), (VMOVDDUPrm addr:$src)>;
4992   def : Pat<(movddup (bc_v4i32 (memopv2i64 addr:$src)), (undef)),
4993             (VMOVDDUPrm addr:$src)>;
4994   }
4995   def : Pat<(X86Movddup (memopv2f64 addr:$src)),
4996             (VMOVDDUPrm addr:$src)>, Requires<[HasAVX]>;
4997   def : Pat<(X86Movddup (bc_v2f64 (memopv4f32 addr:$src))),
4998             (VMOVDDUPrm addr:$src)>, Requires<[HasAVX]>;
4999   def : Pat<(X86Movddup (bc_v2f64 (memopv2i64 addr:$src))),
5000             (VMOVDDUPrm addr:$src)>, Requires<[HasAVX]>;
5001   def : Pat<(X86Movddup (v2f64 (scalar_to_vector (loadf64 addr:$src)))),
5002             (VMOVDDUPrm addr:$src)>, Requires<[HasAVX]>;
5003   def : Pat<(X86Movddup (bc_v2f64
5004                              (v2i64 (scalar_to_vector (loadi64 addr:$src))))),
5005             (VMOVDDUPrm addr:$src)>, Requires<[HasAVX]>;
5006
5007   // 256-bit version
5008   def : Pat<(X86Movddup (memopv4f64 addr:$src)),
5009             (VMOVDDUPYrm addr:$src)>;
5010   def : Pat<(X86Movddup (memopv4i64 addr:$src)),
5011             (VMOVDDUPYrm addr:$src)>;
5012   def : Pat<(X86Movddup (v4f64 (scalar_to_vector (loadf64 addr:$src)))),
5013             (VMOVDDUPYrm addr:$src)>;
5014   def : Pat<(X86Movddup (v4i64 (scalar_to_vector (loadi64 addr:$src)))),
5015             (VMOVDDUPYrm addr:$src)>;
5016   def : Pat<(X86Movddup (v4f64 VR256:$src)),
5017             (VMOVDDUPYrr VR256:$src)>;
5018   def : Pat<(X86Movddup (v4i64 VR256:$src)),
5019             (VMOVDDUPYrr VR256:$src)>;
5020 }
5021
5022 let Predicates = [HasSSE3] in {
5023   def : Pat<(movddup (bc_v2f64 (v2i64 (scalar_to_vector (loadi64 addr:$src)))),
5024                    (undef)),
5025             (MOVDDUPrm addr:$src)>;
5026   let AddedComplexity = 5 in {
5027   def : Pat<(movddup (memopv2f64 addr:$src), (undef)), (MOVDDUPrm addr:$src)>;
5028   def : Pat<(movddup (bc_v4f32 (memopv2f64 addr:$src)), (undef)),
5029             (MOVDDUPrm addr:$src)>;
5030   def : Pat<(movddup (memopv2i64 addr:$src), (undef)), (MOVDDUPrm addr:$src)>;
5031   def : Pat<(movddup (bc_v4i32 (memopv2i64 addr:$src)), (undef)),
5032             (MOVDDUPrm addr:$src)>;
5033   }
5034   def : Pat<(X86Movddup (memopv2f64 addr:$src)),
5035             (MOVDDUPrm addr:$src)>;
5036   def : Pat<(X86Movddup (bc_v2f64 (memopv4f32 addr:$src))),
5037             (MOVDDUPrm addr:$src)>;
5038   def : Pat<(X86Movddup (bc_v2f64 (memopv2i64 addr:$src))),
5039             (MOVDDUPrm addr:$src)>;
5040   def : Pat<(X86Movddup (v2f64 (scalar_to_vector (loadf64 addr:$src)))),
5041             (MOVDDUPrm addr:$src)>;
5042   def : Pat<(X86Movddup (bc_v2f64
5043                              (v2i64 (scalar_to_vector (loadi64 addr:$src))))),
5044             (MOVDDUPrm addr:$src)>;
5045 }
5046
5047 //===---------------------------------------------------------------------===//
5048 // SSE3 - Move Unaligned Integer
5049 //===---------------------------------------------------------------------===//
5050
5051 let Predicates = [HasAVX] in {
5052   def VLDDQUrm : S3DI<0xF0, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
5053                    "vlddqu\t{$src, $dst|$dst, $src}",
5054                    [(set VR128:$dst, (int_x86_sse3_ldu_dq addr:$src))]>, VEX;
5055   def VLDDQUYrm : S3DI<0xF0, MRMSrcMem, (outs VR256:$dst), (ins i256mem:$src),
5056                    "vlddqu\t{$src, $dst|$dst, $src}",
5057                    [(set VR256:$dst, (int_x86_avx_ldu_dq_256 addr:$src))]>, VEX;
5058 }
5059 def LDDQUrm : S3DI<0xF0, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
5060                    "lddqu\t{$src, $dst|$dst, $src}",
5061                    [(set VR128:$dst, (int_x86_sse3_ldu_dq addr:$src))]>;
5062
5063 //===---------------------------------------------------------------------===//
5064 // SSE3 - Arithmetic
5065 //===---------------------------------------------------------------------===//
5066
5067 multiclass sse3_addsub<Intrinsic Int, string OpcodeStr, RegisterClass RC,
5068                        X86MemOperand x86memop, bit Is2Addr = 1> {
5069   def rr : I<0xD0, MRMSrcReg,
5070        (outs RC:$dst), (ins RC:$src1, RC:$src2),
5071        !if(Is2Addr,
5072            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5073            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5074        [(set RC:$dst, (Int RC:$src1, RC:$src2))]>;
5075   def rm : I<0xD0, MRMSrcMem,
5076        (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
5077        !if(Is2Addr,
5078            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5079            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5080        [(set RC:$dst, (Int RC:$src1, (memop addr:$src2)))]>;
5081 }
5082
5083 let Predicates = [HasAVX] in {
5084   let ExeDomain = SSEPackedSingle in {
5085     defm VADDSUBPS : sse3_addsub<int_x86_sse3_addsub_ps, "vaddsubps", VR128,
5086                                  f128mem, 0>, TB, XD, VEX_4V;
5087     defm VADDSUBPSY : sse3_addsub<int_x86_avx_addsub_ps_256, "vaddsubps", VR256,
5088                                  f256mem, 0>, TB, XD, VEX_4V;
5089   }
5090   let ExeDomain = SSEPackedDouble in {
5091     defm VADDSUBPD : sse3_addsub<int_x86_sse3_addsub_pd, "vaddsubpd", VR128,
5092                                  f128mem, 0>, TB, OpSize, VEX_4V;
5093     defm VADDSUBPDY : sse3_addsub<int_x86_avx_addsub_pd_256, "vaddsubpd", VR256,
5094                                  f256mem, 0>, TB, OpSize, VEX_4V;
5095   }
5096 }
5097 let Constraints = "$src1 = $dst", Predicates = [HasSSE3] in {
5098   let ExeDomain = SSEPackedSingle in
5099   defm ADDSUBPS : sse3_addsub<int_x86_sse3_addsub_ps, "addsubps", VR128,
5100                               f128mem>, TB, XD;
5101   let ExeDomain = SSEPackedDouble in
5102   defm ADDSUBPD : sse3_addsub<int_x86_sse3_addsub_pd, "addsubpd", VR128,
5103                               f128mem>, TB, OpSize;
5104 }
5105
5106 //===---------------------------------------------------------------------===//
5107 // SSE3 Instructions
5108 //===---------------------------------------------------------------------===//
5109
5110 // Horizontal ops
5111 multiclass S3D_Int<bits<8> o, string OpcodeStr, ValueType vt, RegisterClass RC,
5112                    X86MemOperand x86memop, SDNode OpNode, bit Is2Addr = 1> {
5113   def rr : S3DI<o, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
5114        !if(Is2Addr,
5115          !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5116          !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5117       [(set RC:$dst, (vt (OpNode RC:$src1, RC:$src2)))]>;
5118
5119   def rm : S3DI<o, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
5120        !if(Is2Addr,
5121          !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5122          !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5123       [(set RC:$dst, (vt (OpNode RC:$src1, (memop addr:$src2))))]>;
5124 }
5125 multiclass S3_Int<bits<8> o, string OpcodeStr, ValueType vt, RegisterClass RC,
5126                   X86MemOperand x86memop, SDNode OpNode, bit Is2Addr = 1> {
5127   def rr : S3I<o, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
5128        !if(Is2Addr,
5129          !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5130          !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5131       [(set RC:$dst, (vt (OpNode RC:$src1, RC:$src2)))]>;
5132
5133   def rm : S3I<o, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
5134        !if(Is2Addr,
5135          !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5136          !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5137       [(set RC:$dst, (vt (OpNode RC:$src1, (memop addr:$src2))))]>;
5138 }
5139
5140 let Predicates = [HasAVX] in {
5141   let ExeDomain = SSEPackedSingle in {
5142     defm VHADDPS  : S3D_Int<0x7C, "vhaddps", v4f32, VR128, f128mem,
5143                             X86fhadd, 0>, VEX_4V;
5144     defm VHSUBPS  : S3D_Int<0x7D, "vhsubps", v4f32, VR128, f128mem,
5145                             X86fhsub, 0>, VEX_4V;
5146     defm VHADDPSY : S3D_Int<0x7C, "vhaddps", v8f32, VR256, f256mem,
5147                             X86fhadd, 0>, VEX_4V;
5148     defm VHSUBPSY : S3D_Int<0x7D, "vhsubps", v8f32, VR256, f256mem,
5149                             X86fhsub, 0>, VEX_4V;
5150   }
5151   let ExeDomain = SSEPackedDouble in {
5152     defm VHADDPD  : S3_Int <0x7C, "vhaddpd", v2f64, VR128, f128mem,
5153                             X86fhadd, 0>, VEX_4V;
5154     defm VHSUBPD  : S3_Int <0x7D, "vhsubpd", v2f64, VR128, f128mem,
5155                             X86fhsub, 0>, VEX_4V;
5156     defm VHADDPDY : S3_Int <0x7C, "vhaddpd", v4f64, VR256, f256mem,
5157                             X86fhadd, 0>, VEX_4V;
5158     defm VHSUBPDY : S3_Int <0x7D, "vhsubpd", v4f64, VR256, f256mem,
5159                             X86fhsub, 0>, VEX_4V;
5160   }
5161 }
5162
5163 let Constraints = "$src1 = $dst" in {
5164   let ExeDomain = SSEPackedSingle in {
5165     defm HADDPS : S3D_Int<0x7C, "haddps", v4f32, VR128, f128mem, X86fhadd>;
5166     defm HSUBPS : S3D_Int<0x7D, "hsubps", v4f32, VR128, f128mem, X86fhsub>;
5167   }
5168   let ExeDomain = SSEPackedDouble in {
5169     defm HADDPD : S3_Int<0x7C, "haddpd", v2f64, VR128, f128mem, X86fhadd>;
5170     defm HSUBPD : S3_Int<0x7D, "hsubpd", v2f64, VR128, f128mem, X86fhsub>;
5171   }
5172 }
5173
5174 //===---------------------------------------------------------------------===//
5175 // SSSE3 - Packed Absolute Instructions
5176 //===---------------------------------------------------------------------===//
5177
5178
5179 /// SS3I_unop_rm_int - Simple SSSE3 unary op whose type can be v*{i8,i16,i32}.
5180 multiclass SS3I_unop_rm_int<bits<8> opc, string OpcodeStr,
5181                             Intrinsic IntId128> {
5182   def rr128 : SS38I<opc, MRMSrcReg, (outs VR128:$dst),
5183                     (ins VR128:$src),
5184                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5185                     [(set VR128:$dst, (IntId128 VR128:$src))]>,
5186                     OpSize;
5187
5188   def rm128 : SS38I<opc, MRMSrcMem, (outs VR128:$dst),
5189                     (ins i128mem:$src),
5190                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5191                     [(set VR128:$dst,
5192                       (IntId128
5193                        (bitconvert (memopv2i64 addr:$src))))]>, OpSize;
5194 }
5195
5196 /// SS3I_unop_rm_int_y - Simple SSSE3 unary op whose type can be v*{i8,i16,i32}.
5197 multiclass SS3I_unop_rm_int_y<bits<8> opc, string OpcodeStr,
5198                               Intrinsic IntId256> {
5199   def rr256 : SS38I<opc, MRMSrcReg, (outs VR256:$dst),
5200                     (ins VR256:$src),
5201                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5202                     [(set VR256:$dst, (IntId256 VR256:$src))]>,
5203                     OpSize;
5204
5205   def rm256 : SS38I<opc, MRMSrcMem, (outs VR256:$dst),
5206                     (ins i256mem:$src),
5207                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5208                     [(set VR256:$dst,
5209                       (IntId256
5210                        (bitconvert (memopv4i64 addr:$src))))]>, OpSize;
5211 }
5212
5213 let Predicates = [HasAVX] in {
5214   defm VPABSB  : SS3I_unop_rm_int<0x1C, "vpabsb",
5215                                   int_x86_ssse3_pabs_b_128>, VEX;
5216   defm VPABSW  : SS3I_unop_rm_int<0x1D, "vpabsw",
5217                                   int_x86_ssse3_pabs_w_128>, VEX;
5218   defm VPABSD  : SS3I_unop_rm_int<0x1E, "vpabsd",
5219                                   int_x86_ssse3_pabs_d_128>, VEX;
5220 }
5221
5222 let Predicates = [HasAVX2] in {
5223   defm VPABSB  : SS3I_unop_rm_int_y<0x1C, "vpabsb",
5224                                     int_x86_avx2_pabs_b>, VEX;
5225   defm VPABSW  : SS3I_unop_rm_int_y<0x1D, "vpabsw",
5226                                     int_x86_avx2_pabs_w>, VEX;
5227   defm VPABSD  : SS3I_unop_rm_int_y<0x1E, "vpabsd",
5228                                     int_x86_avx2_pabs_d>, VEX;
5229 }
5230
5231 defm PABSB : SS3I_unop_rm_int<0x1C, "pabsb",
5232                               int_x86_ssse3_pabs_b_128>;
5233 defm PABSW : SS3I_unop_rm_int<0x1D, "pabsw",
5234                               int_x86_ssse3_pabs_w_128>;
5235 defm PABSD : SS3I_unop_rm_int<0x1E, "pabsd",
5236                               int_x86_ssse3_pabs_d_128>;
5237
5238 //===---------------------------------------------------------------------===//
5239 // SSSE3 - Packed Binary Operator Instructions
5240 //===---------------------------------------------------------------------===//
5241
5242 /// SS3I_binop_rm_int - Simple SSSE3 bin op whose type can be v*{i8,i16,i32}.
5243 multiclass SS3I_binop_rm_int<bits<8> opc, string OpcodeStr,
5244                              Intrinsic IntId128, bit Is2Addr = 1> {
5245   let isCommutable = 1 in
5246   def rr128 : SS38I<opc, MRMSrcReg, (outs VR128:$dst),
5247        (ins VR128:$src1, VR128:$src2),
5248        !if(Is2Addr,
5249          !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5250          !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5251        [(set VR128:$dst, (IntId128 VR128:$src1, VR128:$src2))]>,
5252        OpSize;
5253   def rm128 : SS38I<opc, MRMSrcMem, (outs VR128:$dst),
5254        (ins VR128:$src1, i128mem:$src2),
5255        !if(Is2Addr,
5256          !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5257          !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5258        [(set VR128:$dst,
5259          (IntId128 VR128:$src1,
5260           (bitconvert (memopv2i64 addr:$src2))))]>, OpSize;
5261 }
5262
5263 multiclass SS3I_binop_rm_int_y<bits<8> opc, string OpcodeStr,
5264                                Intrinsic IntId256> {
5265   let isCommutable = 1 in
5266   def rr256 : SS38I<opc, MRMSrcReg, (outs VR256:$dst),
5267        (ins VR256:$src1, VR256:$src2),
5268        !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5269        [(set VR256:$dst, (IntId256 VR256:$src1, VR256:$src2))]>,
5270        OpSize;
5271   def rm256 : SS38I<opc, MRMSrcMem, (outs VR256:$dst),
5272        (ins VR256:$src1, i256mem:$src2),
5273        !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5274        [(set VR256:$dst,
5275          (IntId256 VR256:$src1,
5276           (bitconvert (memopv4i64 addr:$src2))))]>, OpSize;
5277 }
5278
5279 let ImmT = NoImm, Predicates = [HasAVX] in {
5280 let isCommutable = 0 in {
5281   defm VPHADDW    : SS3I_binop_rm_int<0x01, "vphaddw",
5282                                       int_x86_ssse3_phadd_w_128, 0>, VEX_4V;
5283   defm VPHADDD    : SS3I_binop_rm_int<0x02, "vphaddd",
5284                                       int_x86_ssse3_phadd_d_128, 0>, VEX_4V;
5285   defm VPHADDSW   : SS3I_binop_rm_int<0x03, "vphaddsw",
5286                                       int_x86_ssse3_phadd_sw_128, 0>, VEX_4V;
5287   defm VPHSUBW    : SS3I_binop_rm_int<0x05, "vphsubw",
5288                                       int_x86_ssse3_phsub_w_128, 0>, VEX_4V;
5289   defm VPHSUBD    : SS3I_binop_rm_int<0x06, "vphsubd",
5290                                       int_x86_ssse3_phsub_d_128, 0>, VEX_4V;
5291   defm VPHSUBSW   : SS3I_binop_rm_int<0x07, "vphsubsw",
5292                                       int_x86_ssse3_phsub_sw_128, 0>, VEX_4V;
5293   defm VPMADDUBSW : SS3I_binop_rm_int<0x04, "vpmaddubsw",
5294                                       int_x86_ssse3_pmadd_ub_sw_128, 0>, VEX_4V;
5295   defm VPSHUFB    : SS3I_binop_rm_int<0x00, "vpshufb",
5296                                       int_x86_ssse3_pshuf_b_128, 0>, VEX_4V;
5297   defm VPSIGNB    : SS3I_binop_rm_int<0x08, "vpsignb",
5298                                       int_x86_ssse3_psign_b_128, 0>, VEX_4V;
5299   defm VPSIGNW    : SS3I_binop_rm_int<0x09, "vpsignw",
5300                                       int_x86_ssse3_psign_w_128, 0>, VEX_4V;
5301   defm VPSIGND    : SS3I_binop_rm_int<0x0A, "vpsignd",
5302                                       int_x86_ssse3_psign_d_128, 0>, VEX_4V;
5303 }
5304 defm VPMULHRSW    : SS3I_binop_rm_int<0x0B, "vpmulhrsw",
5305                                       int_x86_ssse3_pmul_hr_sw_128, 0>, VEX_4V;
5306 }
5307
5308 let ImmT = NoImm, Predicates = [HasAVX2] in {
5309 let isCommutable = 0 in {
5310   defm VPHADDW    : SS3I_binop_rm_int_y<0x01, "vphaddw",
5311                                         int_x86_avx2_phadd_w>, VEX_4V;
5312   defm VPHADDD    : SS3I_binop_rm_int_y<0x02, "vphaddd",
5313                                         int_x86_avx2_phadd_d>, VEX_4V;
5314   defm VPHADDSW   : SS3I_binop_rm_int_y<0x03, "vphaddsw",
5315                                         int_x86_avx2_phadd_sw>, VEX_4V;
5316   defm VPHSUBW    : SS3I_binop_rm_int_y<0x05, "vphsubw",
5317                                         int_x86_avx2_phsub_w>, VEX_4V;
5318   defm VPHSUBD    : SS3I_binop_rm_int_y<0x06, "vphsubd",
5319                                         int_x86_avx2_phsub_d>, VEX_4V;
5320   defm VPHSUBSW   : SS3I_binop_rm_int_y<0x07, "vphsubsw",
5321                                         int_x86_avx2_phsub_sw>, VEX_4V;
5322   defm VPMADDUBSW : SS3I_binop_rm_int_y<0x04, "vpmaddubsw",
5323                                         int_x86_avx2_pmadd_ub_sw>, VEX_4V;
5324   defm VPSHUFB    : SS3I_binop_rm_int_y<0x00, "vpshufb",
5325                                         int_x86_avx2_pshuf_b>, VEX_4V;
5326   defm VPSIGNB    : SS3I_binop_rm_int_y<0x08, "vpsignb",
5327                                         int_x86_avx2_psign_b>, VEX_4V;
5328   defm VPSIGNW    : SS3I_binop_rm_int_y<0x09, "vpsignw",
5329                                         int_x86_avx2_psign_w>, VEX_4V;
5330   defm VPSIGND    : SS3I_binop_rm_int_y<0x0A, "vpsignd",
5331                                         int_x86_avx2_psign_d>, VEX_4V;
5332 }
5333 defm VPMULHRSW    : SS3I_binop_rm_int_y<0x0B, "vpmulhrsw",
5334                                         int_x86_avx2_pmul_hr_sw>, VEX_4V;
5335 }
5336
5337 // None of these have i8 immediate fields.
5338 let ImmT = NoImm, Constraints = "$src1 = $dst" in {
5339 let isCommutable = 0 in {
5340   defm PHADDW    : SS3I_binop_rm_int<0x01, "phaddw",
5341                                      int_x86_ssse3_phadd_w_128>;
5342   defm PHADDD    : SS3I_binop_rm_int<0x02, "phaddd",
5343                                      int_x86_ssse3_phadd_d_128>;
5344   defm PHADDSW   : SS3I_binop_rm_int<0x03, "phaddsw",
5345                                      int_x86_ssse3_phadd_sw_128>;
5346   defm PHSUBW    : SS3I_binop_rm_int<0x05, "phsubw",
5347                                      int_x86_ssse3_phsub_w_128>;
5348   defm PHSUBD    : SS3I_binop_rm_int<0x06, "phsubd",
5349                                      int_x86_ssse3_phsub_d_128>;
5350   defm PHSUBSW   : SS3I_binop_rm_int<0x07, "phsubsw",
5351                                      int_x86_ssse3_phsub_sw_128>;
5352   defm PMADDUBSW : SS3I_binop_rm_int<0x04, "pmaddubsw",
5353                                      int_x86_ssse3_pmadd_ub_sw_128>;
5354   defm PSHUFB    : SS3I_binop_rm_int<0x00, "pshufb",
5355                                      int_x86_ssse3_pshuf_b_128>;
5356   defm PSIGNB    : SS3I_binop_rm_int<0x08, "psignb",
5357                                      int_x86_ssse3_psign_b_128>;
5358   defm PSIGNW    : SS3I_binop_rm_int<0x09, "psignw",
5359                                      int_x86_ssse3_psign_w_128>;
5360   defm PSIGND    : SS3I_binop_rm_int<0x0A, "psignd",
5361                                        int_x86_ssse3_psign_d_128>;
5362 }
5363 defm PMULHRSW    : SS3I_binop_rm_int<0x0B, "pmulhrsw",
5364                                      int_x86_ssse3_pmul_hr_sw_128>;
5365 }
5366
5367 let Predicates = [HasAVX] in {
5368   def : Pat<(X86pshufb VR128:$src, VR128:$mask),
5369             (VPSHUFBrr128 VR128:$src, VR128:$mask)>;
5370   def : Pat<(X86pshufb VR128:$src, (bc_v16i8 (memopv2i64 addr:$mask))),
5371             (VPSHUFBrm128 VR128:$src, addr:$mask)>;
5372
5373   def : Pat<(v16i8 (X86psign VR128:$src1, VR128:$src2)),
5374             (VPSIGNBrr128 VR128:$src1, VR128:$src2)>;
5375   def : Pat<(v8i16 (X86psign VR128:$src1, VR128:$src2)),
5376             (VPSIGNWrr128 VR128:$src1, VR128:$src2)>;
5377   def : Pat<(v4i32 (X86psign VR128:$src1, VR128:$src2)),
5378             (VPSIGNDrr128 VR128:$src1, VR128:$src2)>;
5379
5380   def : Pat<(v8i16 (X86hadd VR128:$src1, VR128:$src2)),
5381             (VPHADDWrr128 VR128:$src1, VR128:$src2)>;
5382   def : Pat<(v4i32 (X86hadd VR128:$src1, VR128:$src2)),
5383             (VPHADDDrr128 VR128:$src1, VR128:$src2)>;
5384   def : Pat<(v8i16 (X86hsub VR128:$src1, VR128:$src2)),
5385             (VPHSUBWrr128 VR128:$src1, VR128:$src2)>;
5386   def : Pat<(v4i32 (X86hsub VR128:$src1, VR128:$src2)),
5387             (VPHSUBDrr128 VR128:$src1, VR128:$src2)>;
5388 }
5389
5390 let Predicates = [HasAVX2] in {
5391   def : Pat<(v32i8 (X86psign VR256:$src1, VR256:$src2)),
5392             (VPSIGNBrr256 VR256:$src1, VR256:$src2)>;
5393   def : Pat<(v16i16 (X86psign VR256:$src1, VR256:$src2)),
5394             (VPSIGNWrr256 VR256:$src1, VR256:$src2)>;
5395   def : Pat<(v8i32 (X86psign VR256:$src1, VR256:$src2)),
5396             (VPSIGNDrr256 VR256:$src1, VR256:$src2)>;
5397
5398   def : Pat<(v16i16 (X86hadd VR256:$src1, VR256:$src2)),
5399             (VPHADDWrr256 VR256:$src1, VR256:$src2)>;
5400   def : Pat<(v8i32 (X86hadd VR256:$src1, VR256:$src2)),
5401             (VPHADDDrr256 VR256:$src1, VR256:$src2)>;
5402   def : Pat<(v16i16 (X86hsub VR256:$src1, VR256:$src2)),
5403             (VPHSUBWrr256 VR256:$src1, VR256:$src2)>;
5404   def : Pat<(v8i32 (X86hsub VR256:$src1, VR256:$src2)),
5405             (VPHSUBDrr256 VR256:$src1, VR256:$src2)>;
5406 }
5407
5408 let Predicates = [HasSSSE3] in {
5409   def : Pat<(X86pshufb VR128:$src, VR128:$mask),
5410             (PSHUFBrr128 VR128:$src, VR128:$mask)>;
5411   def : Pat<(X86pshufb VR128:$src, (bc_v16i8 (memopv2i64 addr:$mask))),
5412             (PSHUFBrm128 VR128:$src, addr:$mask)>;
5413
5414   def : Pat<(v16i8 (X86psign VR128:$src1, VR128:$src2)),
5415             (PSIGNBrr128 VR128:$src1, VR128:$src2)>;
5416   def : Pat<(v8i16 (X86psign VR128:$src1, VR128:$src2)),
5417             (PSIGNWrr128 VR128:$src1, VR128:$src2)>;
5418   def : Pat<(v4i32 (X86psign VR128:$src1, VR128:$src2)),
5419             (PSIGNDrr128 VR128:$src1, VR128:$src2)>;
5420
5421   def : Pat<(v8i16 (X86hadd VR128:$src1, VR128:$src2)),
5422             (PHADDWrr128 VR128:$src1, VR128:$src2)>;
5423   def : Pat<(v4i32 (X86hadd VR128:$src1, VR128:$src2)),
5424             (PHADDDrr128 VR128:$src1, VR128:$src2)>;
5425   def : Pat<(v8i16 (X86hsub VR128:$src1, VR128:$src2)),
5426             (PHSUBWrr128 VR128:$src1, VR128:$src2)>;
5427   def : Pat<(v4i32 (X86hsub VR128:$src1, VR128:$src2)),
5428             (PHSUBDrr128 VR128:$src1, VR128:$src2)>;
5429 }
5430
5431 //===---------------------------------------------------------------------===//
5432 // SSSE3 - Packed Align Instruction Patterns
5433 //===---------------------------------------------------------------------===//
5434
5435 multiclass ssse3_palign<string asm, bit Is2Addr = 1> {
5436   let neverHasSideEffects = 1 in {
5437   def R128rr : SS3AI<0x0F, MRMSrcReg, (outs VR128:$dst),
5438       (ins VR128:$src1, VR128:$src2, i8imm:$src3),
5439       !if(Is2Addr,
5440         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5441         !strconcat(asm,
5442                   "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5443       []>, OpSize;
5444   let mayLoad = 1 in
5445   def R128rm : SS3AI<0x0F, MRMSrcMem, (outs VR128:$dst),
5446       (ins VR128:$src1, i128mem:$src2, i8imm:$src3),
5447       !if(Is2Addr,
5448         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5449         !strconcat(asm,
5450                   "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5451       []>, OpSize;
5452   }
5453 }
5454
5455 multiclass ssse3_palign_y<string asm, bit Is2Addr = 1> {
5456   let neverHasSideEffects = 1 in {
5457   def R256rr : SS3AI<0x0F, MRMSrcReg, (outs VR256:$dst),
5458       (ins VR256:$src1, VR256:$src2, i8imm:$src3),
5459       !strconcat(asm,
5460                  "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
5461       []>, OpSize;
5462   let mayLoad = 1 in
5463   def R256rm : SS3AI<0x0F, MRMSrcMem, (outs VR256:$dst),
5464       (ins VR256:$src1, i256mem:$src2, i8imm:$src3),
5465       !strconcat(asm,
5466                  "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
5467       []>, OpSize;
5468   }
5469 }
5470
5471 let Predicates = [HasAVX] in
5472   defm VPALIGN : ssse3_palign<"vpalignr", 0>, VEX_4V;
5473 let Predicates = [HasAVX2] in
5474   defm VPALIGN : ssse3_palign_y<"vpalignr", 0>, VEX_4V;
5475 let Constraints = "$src1 = $dst", Predicates = [HasSSSE3] in
5476   defm PALIGN : ssse3_palign<"palignr">;
5477
5478 let Predicates = [HasAVX] in {
5479 def : Pat<(v4i32 (X86PAlign VR128:$src1, VR128:$src2, (i8 imm:$imm))),
5480           (VPALIGNR128rr VR128:$src2, VR128:$src1, imm:$imm)>;
5481 def : Pat<(v4f32 (X86PAlign VR128:$src1, VR128:$src2, (i8 imm:$imm))),
5482           (VPALIGNR128rr VR128:$src2, VR128:$src1, imm:$imm)>;
5483 def : Pat<(v8i16 (X86PAlign VR128:$src1, VR128:$src2, (i8 imm:$imm))),
5484           (VPALIGNR128rr VR128:$src2, VR128:$src1, imm:$imm)>;
5485 def : Pat<(v16i8 (X86PAlign VR128:$src1, VR128:$src2, (i8 imm:$imm))),
5486           (VPALIGNR128rr VR128:$src2, VR128:$src1, imm:$imm)>;
5487 }
5488
5489 let Predicates = [HasSSSE3] in {
5490 def : Pat<(v4i32 (X86PAlign VR128:$src1, VR128:$src2, (i8 imm:$imm))),
5491           (PALIGNR128rr VR128:$src2, VR128:$src1, imm:$imm)>;
5492 def : Pat<(v4f32 (X86PAlign VR128:$src1, VR128:$src2, (i8 imm:$imm))),
5493           (PALIGNR128rr VR128:$src2, VR128:$src1, imm:$imm)>;
5494 def : Pat<(v8i16 (X86PAlign VR128:$src1, VR128:$src2, (i8 imm:$imm))),
5495           (PALIGNR128rr VR128:$src2, VR128:$src1, imm:$imm)>;
5496 def : Pat<(v16i8 (X86PAlign VR128:$src1, VR128:$src2, (i8 imm:$imm))),
5497           (PALIGNR128rr VR128:$src2, VR128:$src1, imm:$imm)>;
5498 }
5499
5500 //===---------------------------------------------------------------------===//
5501 // SSSE3 - Thread synchronization
5502 //===---------------------------------------------------------------------===//
5503
5504 let usesCustomInserter = 1 in {
5505 def MONITOR : PseudoI<(outs), (ins i32mem:$src1, GR32:$src2, GR32:$src3),
5506                 [(int_x86_sse3_monitor addr:$src1, GR32:$src2, GR32:$src3)]>,
5507                 Requires<[HasSSE3]>;
5508 def MWAIT : PseudoI<(outs), (ins GR32:$src1, GR32:$src2),
5509                 [(int_x86_sse3_mwait GR32:$src1, GR32:$src2)]>,
5510                 Requires<[HasSSE3]>;
5511 }
5512
5513 let Uses = [EAX, ECX, EDX] in
5514 def MONITORrrr : I<0x01, MRM_C8, (outs), (ins), "monitor", []>, TB,
5515                  Requires<[HasSSE3]>;
5516 let Uses = [ECX, EAX] in
5517 def MWAITrr   : I<0x01, MRM_C9, (outs), (ins), "mwait", []>, TB,
5518                 Requires<[HasSSE3]>;
5519
5520 def : InstAlias<"mwait %eax, %ecx", (MWAITrr)>, Requires<[In32BitMode]>;
5521 def : InstAlias<"mwait %rax, %rcx", (MWAITrr)>, Requires<[In64BitMode]>;
5522
5523 def : InstAlias<"monitor %eax, %ecx, %edx", (MONITORrrr)>,
5524       Requires<[In32BitMode]>;
5525 def : InstAlias<"monitor %rax, %rcx, %rdx", (MONITORrrr)>,
5526       Requires<[In64BitMode]>;
5527
5528 //===----------------------------------------------------------------------===//
5529 // SSE4.1 - Packed Move with Sign/Zero Extend
5530 //===----------------------------------------------------------------------===//
5531
5532 multiclass SS41I_binop_rm_int8<bits<8> opc, string OpcodeStr, Intrinsic IntId> {
5533   def rr : SS48I<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
5534                  !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5535                  [(set VR128:$dst, (IntId VR128:$src))]>, OpSize;
5536
5537   def rm : SS48I<opc, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
5538                  !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5539        [(set VR128:$dst,
5540          (IntId (bitconvert (v2i64 (scalar_to_vector (loadi64 addr:$src))))))]>,
5541        OpSize;
5542 }
5543
5544 multiclass SS41I_binop_rm_int16_y<bits<8> opc, string OpcodeStr,
5545                                  Intrinsic IntId> {
5546   def Yrr : SS48I<opc, MRMSrcReg, (outs VR256:$dst), (ins VR128:$src),
5547                   !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5548                   [(set VR256:$dst, (IntId VR128:$src))]>, OpSize;
5549
5550   def Yrm : SS48I<opc, MRMSrcMem, (outs VR256:$dst), (ins i128mem:$src),
5551                   !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5552                   [(set VR256:$dst, (IntId (load addr:$src)))]>, OpSize;
5553 }
5554
5555 let Predicates = [HasAVX] in {
5556 defm VPMOVSXBW : SS41I_binop_rm_int8<0x20, "vpmovsxbw", int_x86_sse41_pmovsxbw>,
5557                                      VEX;
5558 defm VPMOVSXWD : SS41I_binop_rm_int8<0x23, "vpmovsxwd", int_x86_sse41_pmovsxwd>,
5559                                      VEX;
5560 defm VPMOVSXDQ : SS41I_binop_rm_int8<0x25, "vpmovsxdq", int_x86_sse41_pmovsxdq>,
5561                                      VEX;
5562 defm VPMOVZXBW : SS41I_binop_rm_int8<0x30, "vpmovzxbw", int_x86_sse41_pmovzxbw>,
5563                                      VEX;
5564 defm VPMOVZXWD : SS41I_binop_rm_int8<0x33, "vpmovzxwd", int_x86_sse41_pmovzxwd>,
5565                                      VEX;
5566 defm VPMOVZXDQ : SS41I_binop_rm_int8<0x35, "vpmovzxdq", int_x86_sse41_pmovzxdq>,
5567                                      VEX;
5568 }
5569
5570 let Predicates = [HasAVX2] in {
5571 defm VPMOVSXBW : SS41I_binop_rm_int16_y<0x20, "vpmovsxbw",
5572                                         int_x86_avx2_pmovsxbw>, VEX;
5573 defm VPMOVSXWD : SS41I_binop_rm_int16_y<0x23, "vpmovsxwd",
5574                                         int_x86_avx2_pmovsxwd>, VEX;
5575 defm VPMOVSXDQ : SS41I_binop_rm_int16_y<0x25, "vpmovsxdq",
5576                                         int_x86_avx2_pmovsxdq>, VEX;
5577 defm VPMOVZXBW : SS41I_binop_rm_int16_y<0x30, "vpmovzxbw",
5578                                         int_x86_avx2_pmovzxbw>, VEX;
5579 defm VPMOVZXWD : SS41I_binop_rm_int16_y<0x33, "vpmovzxwd",
5580                                         int_x86_avx2_pmovzxwd>, VEX;
5581 defm VPMOVZXDQ : SS41I_binop_rm_int16_y<0x35, "vpmovzxdq",
5582                                         int_x86_avx2_pmovzxdq>, VEX;
5583 }
5584
5585 defm PMOVSXBW   : SS41I_binop_rm_int8<0x20, "pmovsxbw", int_x86_sse41_pmovsxbw>;
5586 defm PMOVSXWD   : SS41I_binop_rm_int8<0x23, "pmovsxwd", int_x86_sse41_pmovsxwd>;
5587 defm PMOVSXDQ   : SS41I_binop_rm_int8<0x25, "pmovsxdq", int_x86_sse41_pmovsxdq>;
5588 defm PMOVZXBW   : SS41I_binop_rm_int8<0x30, "pmovzxbw", int_x86_sse41_pmovzxbw>;
5589 defm PMOVZXWD   : SS41I_binop_rm_int8<0x33, "pmovzxwd", int_x86_sse41_pmovzxwd>;
5590 defm PMOVZXDQ   : SS41I_binop_rm_int8<0x35, "pmovzxdq", int_x86_sse41_pmovzxdq>;
5591
5592 let Predicates = [HasAVX] in {
5593   // Common patterns involving scalar load.
5594   def : Pat<(int_x86_sse41_pmovsxbw (vzmovl_v2i64 addr:$src)),
5595             (VPMOVSXBWrm addr:$src)>;
5596   def : Pat<(int_x86_sse41_pmovsxbw (vzload_v2i64 addr:$src)),
5597             (VPMOVSXBWrm addr:$src)>;
5598
5599   def : Pat<(int_x86_sse41_pmovsxwd (vzmovl_v2i64 addr:$src)),
5600             (VPMOVSXWDrm addr:$src)>;
5601   def : Pat<(int_x86_sse41_pmovsxwd (vzload_v2i64 addr:$src)),
5602             (VPMOVSXWDrm addr:$src)>;
5603
5604   def : Pat<(int_x86_sse41_pmovsxdq (vzmovl_v2i64 addr:$src)),
5605             (VPMOVSXDQrm addr:$src)>;
5606   def : Pat<(int_x86_sse41_pmovsxdq (vzload_v2i64 addr:$src)),
5607             (VPMOVSXDQrm addr:$src)>;
5608
5609   def : Pat<(int_x86_sse41_pmovzxbw (vzmovl_v2i64 addr:$src)),
5610             (VPMOVZXBWrm addr:$src)>;
5611   def : Pat<(int_x86_sse41_pmovzxbw (vzload_v2i64 addr:$src)),
5612             (VPMOVZXBWrm addr:$src)>;
5613
5614   def : Pat<(int_x86_sse41_pmovzxwd (vzmovl_v2i64 addr:$src)),
5615             (VPMOVZXWDrm addr:$src)>;
5616   def : Pat<(int_x86_sse41_pmovzxwd (vzload_v2i64 addr:$src)),
5617             (VPMOVZXWDrm addr:$src)>;
5618
5619   def : Pat<(int_x86_sse41_pmovzxdq (vzmovl_v2i64 addr:$src)),
5620             (VPMOVZXDQrm addr:$src)>;
5621   def : Pat<(int_x86_sse41_pmovzxdq (vzload_v2i64 addr:$src)),
5622             (VPMOVZXDQrm addr:$src)>;
5623 }
5624
5625 let Predicates = [HasSSE41] in {
5626   // Common patterns involving scalar load.
5627   def : Pat<(int_x86_sse41_pmovsxbw (vzmovl_v2i64 addr:$src)),
5628             (PMOVSXBWrm addr:$src)>;
5629   def : Pat<(int_x86_sse41_pmovsxbw (vzload_v2i64 addr:$src)),
5630             (PMOVSXBWrm addr:$src)>;
5631
5632   def : Pat<(int_x86_sse41_pmovsxwd (vzmovl_v2i64 addr:$src)),
5633             (PMOVSXWDrm addr:$src)>;
5634   def : Pat<(int_x86_sse41_pmovsxwd (vzload_v2i64 addr:$src)),
5635             (PMOVSXWDrm addr:$src)>;
5636
5637   def : Pat<(int_x86_sse41_pmovsxdq (vzmovl_v2i64 addr:$src)),
5638             (PMOVSXDQrm addr:$src)>;
5639   def : Pat<(int_x86_sse41_pmovsxdq (vzload_v2i64 addr:$src)),
5640             (PMOVSXDQrm addr:$src)>;
5641
5642   def : Pat<(int_x86_sse41_pmovzxbw (vzmovl_v2i64 addr:$src)),
5643             (PMOVZXBWrm addr:$src)>;
5644   def : Pat<(int_x86_sse41_pmovzxbw (vzload_v2i64 addr:$src)),
5645             (PMOVZXBWrm addr:$src)>;
5646
5647   def : Pat<(int_x86_sse41_pmovzxwd (vzmovl_v2i64 addr:$src)),
5648             (PMOVZXWDrm addr:$src)>;
5649   def : Pat<(int_x86_sse41_pmovzxwd (vzload_v2i64 addr:$src)),
5650             (PMOVZXWDrm addr:$src)>;
5651
5652   def : Pat<(int_x86_sse41_pmovzxdq (vzmovl_v2i64 addr:$src)),
5653             (PMOVZXDQrm addr:$src)>;
5654   def : Pat<(int_x86_sse41_pmovzxdq (vzload_v2i64 addr:$src)),
5655             (PMOVZXDQrm addr:$src)>;
5656 }
5657
5658
5659 multiclass SS41I_binop_rm_int4<bits<8> opc, string OpcodeStr, Intrinsic IntId> {
5660   def rr : SS48I<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
5661                  !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5662                  [(set VR128:$dst, (IntId VR128:$src))]>, OpSize;
5663
5664   def rm : SS48I<opc, MRMSrcMem, (outs VR128:$dst), (ins i32mem:$src),
5665                  !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5666        [(set VR128:$dst,
5667          (IntId (bitconvert (v4i32 (scalar_to_vector (loadi32 addr:$src))))))]>,
5668           OpSize;
5669 }
5670
5671 multiclass SS41I_binop_rm_int8_y<bits<8> opc, string OpcodeStr,
5672                                  Intrinsic IntId> {
5673   def Yrr : SS48I<opc, MRMSrcReg, (outs VR256:$dst), (ins VR128:$src),
5674                   !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5675                   [(set VR256:$dst, (IntId VR128:$src))]>, OpSize;
5676
5677   def Yrm : SS48I<opc, MRMSrcMem, (outs VR256:$dst), (ins i32mem:$src),
5678                   !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5679        [(set VR256:$dst,
5680          (IntId (bitconvert (v2i64 (scalar_to_vector (loadi64 addr:$src))))))]>,
5681           OpSize;
5682 }
5683
5684 let Predicates = [HasAVX] in {
5685 defm VPMOVSXBD : SS41I_binop_rm_int4<0x21, "vpmovsxbd", int_x86_sse41_pmovsxbd>,
5686                                      VEX;
5687 defm VPMOVSXWQ : SS41I_binop_rm_int4<0x24, "vpmovsxwq", int_x86_sse41_pmovsxwq>,
5688                                      VEX;
5689 defm VPMOVZXBD : SS41I_binop_rm_int4<0x31, "vpmovzxbd", int_x86_sse41_pmovzxbd>,
5690                                      VEX;
5691 defm VPMOVZXWQ : SS41I_binop_rm_int4<0x34, "vpmovzxwq", int_x86_sse41_pmovzxwq>,
5692                                      VEX;
5693 }
5694
5695 let Predicates = [HasAVX2] in {
5696 defm VPMOVSXBD : SS41I_binop_rm_int8_y<0x21, "vpmovsxbd",
5697                                        int_x86_avx2_pmovsxbd>, VEX;
5698 defm VPMOVSXWQ : SS41I_binop_rm_int8_y<0x24, "vpmovsxwq",
5699                                        int_x86_avx2_pmovsxwq>, VEX;
5700 defm VPMOVZXBD : SS41I_binop_rm_int8_y<0x31, "vpmovzxbd",
5701                                        int_x86_avx2_pmovzxbd>, VEX;
5702 defm VPMOVZXWQ : SS41I_binop_rm_int8_y<0x34, "vpmovzxwq",
5703                                        int_x86_avx2_pmovzxwq>, VEX;
5704 }
5705
5706 defm PMOVSXBD   : SS41I_binop_rm_int4<0x21, "pmovsxbd", int_x86_sse41_pmovsxbd>;
5707 defm PMOVSXWQ   : SS41I_binop_rm_int4<0x24, "pmovsxwq", int_x86_sse41_pmovsxwq>;
5708 defm PMOVZXBD   : SS41I_binop_rm_int4<0x31, "pmovzxbd", int_x86_sse41_pmovzxbd>;
5709 defm PMOVZXWQ   : SS41I_binop_rm_int4<0x34, "pmovzxwq", int_x86_sse41_pmovzxwq>;
5710
5711 let Predicates = [HasAVX] in {
5712   // Common patterns involving scalar load
5713   def : Pat<(int_x86_sse41_pmovsxbd (vzmovl_v4i32 addr:$src)),
5714             (VPMOVSXBDrm addr:$src)>;
5715   def : Pat<(int_x86_sse41_pmovsxwq (vzmovl_v4i32 addr:$src)),
5716             (VPMOVSXWQrm addr:$src)>;
5717
5718   def : Pat<(int_x86_sse41_pmovzxbd (vzmovl_v4i32 addr:$src)),
5719             (VPMOVZXBDrm addr:$src)>;
5720   def : Pat<(int_x86_sse41_pmovzxwq (vzmovl_v4i32 addr:$src)),
5721             (VPMOVZXWQrm addr:$src)>;
5722 }
5723
5724 let Predicates = [HasSSE41] in {
5725   // Common patterns involving scalar load
5726   def : Pat<(int_x86_sse41_pmovsxbd (vzmovl_v4i32 addr:$src)),
5727             (PMOVSXBDrm addr:$src)>;
5728   def : Pat<(int_x86_sse41_pmovsxwq (vzmovl_v4i32 addr:$src)),
5729             (PMOVSXWQrm addr:$src)>;
5730
5731   def : Pat<(int_x86_sse41_pmovzxbd (vzmovl_v4i32 addr:$src)),
5732             (PMOVZXBDrm addr:$src)>;
5733   def : Pat<(int_x86_sse41_pmovzxwq (vzmovl_v4i32 addr:$src)),
5734             (PMOVZXWQrm addr:$src)>;
5735 }
5736
5737 multiclass SS41I_binop_rm_int2<bits<8> opc, string OpcodeStr, Intrinsic IntId> {
5738   def rr : SS48I<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
5739                  !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5740                  [(set VR128:$dst, (IntId VR128:$src))]>, OpSize;
5741
5742   // Expecting a i16 load any extended to i32 value.
5743   def rm : SS48I<opc, MRMSrcMem, (outs VR128:$dst), (ins i16mem:$src),
5744                  !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5745                  [(set VR128:$dst, (IntId (bitconvert
5746                      (v4i32 (scalar_to_vector (loadi16_anyext addr:$src))))))]>,
5747                  OpSize;
5748 }
5749
5750 multiclass SS41I_binop_rm_int4_y<bits<8> opc, string OpcodeStr,
5751                                  Intrinsic IntId> {
5752   def Yrr : SS48I<opc, MRMSrcReg, (outs VR256:$dst), (ins VR128:$src),
5753                  !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5754                  [(set VR256:$dst, (IntId VR128:$src))]>, OpSize;
5755
5756   // Expecting a i16 load any extended to i32 value.
5757   def Yrm : SS48I<opc, MRMSrcMem, (outs VR256:$dst), (ins i16mem:$src),
5758                   !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5759                   [(set VR256:$dst, (IntId (bitconvert
5760                       (v4i32 (scalar_to_vector (loadi32 addr:$src))))))]>,
5761                   OpSize;
5762 }
5763
5764 let Predicates = [HasAVX] in {
5765 defm VPMOVSXBQ : SS41I_binop_rm_int2<0x22, "vpmovsxbq", int_x86_sse41_pmovsxbq>,
5766                                      VEX;
5767 defm VPMOVZXBQ : SS41I_binop_rm_int2<0x32, "vpmovzxbq", int_x86_sse41_pmovzxbq>,
5768                                      VEX;
5769 }
5770 let Predicates = [HasAVX2] in {
5771 defm VPMOVSXBQ : SS41I_binop_rm_int4_y<0x22, "vpmovsxbq",
5772                                        int_x86_avx2_pmovsxbq>, VEX;
5773 defm VPMOVZXBQ : SS41I_binop_rm_int4_y<0x32, "vpmovzxbq",
5774                                        int_x86_avx2_pmovzxbq>, VEX;
5775 }
5776 defm PMOVSXBQ   : SS41I_binop_rm_int2<0x22, "pmovsxbq", int_x86_sse41_pmovsxbq>;
5777 defm PMOVZXBQ   : SS41I_binop_rm_int2<0x32, "pmovzxbq", int_x86_sse41_pmovzxbq>;
5778
5779 let Predicates = [HasAVX] in {
5780   // Common patterns involving scalar load
5781   def : Pat<(int_x86_sse41_pmovsxbq
5782               (bitconvert (v4i32 (X86vzmovl
5783                             (v4i32 (scalar_to_vector (loadi32 addr:$src))))))),
5784             (VPMOVSXBQrm addr:$src)>;
5785
5786   def : Pat<(int_x86_sse41_pmovzxbq
5787               (bitconvert (v4i32 (X86vzmovl
5788                             (v4i32 (scalar_to_vector (loadi32 addr:$src))))))),
5789             (VPMOVZXBQrm addr:$src)>;
5790 }
5791
5792 let Predicates = [HasSSE41] in {
5793   // Common patterns involving scalar load
5794   def : Pat<(int_x86_sse41_pmovsxbq
5795               (bitconvert (v4i32 (X86vzmovl
5796                             (v4i32 (scalar_to_vector (loadi32 addr:$src))))))),
5797             (PMOVSXBQrm addr:$src)>;
5798
5799   def : Pat<(int_x86_sse41_pmovzxbq
5800               (bitconvert (v4i32 (X86vzmovl
5801                             (v4i32 (scalar_to_vector (loadi32 addr:$src))))))),
5802             (PMOVZXBQrm addr:$src)>;
5803 }
5804
5805 //===----------------------------------------------------------------------===//
5806 // SSE4.1 - Extract Instructions
5807 //===----------------------------------------------------------------------===//
5808
5809 /// SS41I_binop_ext8 - SSE 4.1 extract 8 bits to 32 bit reg or 8 bit mem
5810 multiclass SS41I_extract8<bits<8> opc, string OpcodeStr> {
5811   def rr : SS4AIi8<opc, MRMDestReg, (outs GR32:$dst),
5812                  (ins VR128:$src1, i32i8imm:$src2),
5813                  !strconcat(OpcodeStr,
5814                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5815                  [(set GR32:$dst, (X86pextrb (v16i8 VR128:$src1), imm:$src2))]>,
5816                  OpSize;
5817   let neverHasSideEffects = 1, mayStore = 1 in
5818   def mr : SS4AIi8<opc, MRMDestMem, (outs),
5819                  (ins i8mem:$dst, VR128:$src1, i32i8imm:$src2),
5820                  !strconcat(OpcodeStr,
5821                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5822                  []>, OpSize;
5823 // FIXME:
5824 // There's an AssertZext in the way of writing the store pattern
5825 // (store (i8 (trunc (X86pextrb (v16i8 VR128:$src1), imm:$src2))), addr:$dst)
5826 }
5827
5828 let Predicates = [HasAVX] in {
5829   defm VPEXTRB : SS41I_extract8<0x14, "vpextrb">, VEX;
5830   def  VPEXTRBrr64 : SS4AIi8<0x14, MRMDestReg, (outs GR64:$dst),
5831          (ins VR128:$src1, i32i8imm:$src2),
5832          "vpextrb\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>, OpSize, VEX;
5833 }
5834
5835 defm PEXTRB      : SS41I_extract8<0x14, "pextrb">;
5836
5837
5838 /// SS41I_extract16 - SSE 4.1 extract 16 bits to memory destination
5839 multiclass SS41I_extract16<bits<8> opc, string OpcodeStr> {
5840   let neverHasSideEffects = 1, mayStore = 1 in
5841   def mr : SS4AIi8<opc, MRMDestMem, (outs),
5842                  (ins i16mem:$dst, VR128:$src1, i32i8imm:$src2),
5843                  !strconcat(OpcodeStr,
5844                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5845                  []>, OpSize;
5846 // FIXME:
5847 // There's an AssertZext in the way of writing the store pattern
5848 // (store (i16 (trunc (X86pextrw (v16i8 VR128:$src1), imm:$src2))), addr:$dst)
5849 }
5850
5851 let Predicates = [HasAVX] in
5852   defm VPEXTRW : SS41I_extract16<0x15, "vpextrw">, VEX;
5853
5854 defm PEXTRW      : SS41I_extract16<0x15, "pextrw">;
5855
5856
5857 /// SS41I_extract32 - SSE 4.1 extract 32 bits to int reg or memory destination
5858 multiclass SS41I_extract32<bits<8> opc, string OpcodeStr> {
5859   def rr : SS4AIi8<opc, MRMDestReg, (outs GR32:$dst),
5860                  (ins VR128:$src1, i32i8imm:$src2),
5861                  !strconcat(OpcodeStr,
5862                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5863                  [(set GR32:$dst,
5864                   (extractelt (v4i32 VR128:$src1), imm:$src2))]>, OpSize;
5865   def mr : SS4AIi8<opc, MRMDestMem, (outs),
5866                  (ins i32mem:$dst, VR128:$src1, i32i8imm:$src2),
5867                  !strconcat(OpcodeStr,
5868                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5869                  [(store (extractelt (v4i32 VR128:$src1), imm:$src2),
5870                           addr:$dst)]>, OpSize;
5871 }
5872
5873 let Predicates = [HasAVX] in
5874   defm VPEXTRD : SS41I_extract32<0x16, "vpextrd">, VEX;
5875
5876 defm PEXTRD      : SS41I_extract32<0x16, "pextrd">;
5877
5878 /// SS41I_extract32 - SSE 4.1 extract 32 bits to int reg or memory destination
5879 multiclass SS41I_extract64<bits<8> opc, string OpcodeStr> {
5880   def rr : SS4AIi8<opc, MRMDestReg, (outs GR64:$dst),
5881                  (ins VR128:$src1, i32i8imm:$src2),
5882                  !strconcat(OpcodeStr,
5883                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5884                  [(set GR64:$dst,
5885                   (extractelt (v2i64 VR128:$src1), imm:$src2))]>, OpSize, REX_W;
5886   def mr : SS4AIi8<opc, MRMDestMem, (outs),
5887                  (ins i64mem:$dst, VR128:$src1, i32i8imm:$src2),
5888                  !strconcat(OpcodeStr,
5889                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5890                  [(store (extractelt (v2i64 VR128:$src1), imm:$src2),
5891                           addr:$dst)]>, OpSize, REX_W;
5892 }
5893
5894 let Predicates = [HasAVX] in
5895   defm VPEXTRQ : SS41I_extract64<0x16, "vpextrq">, VEX, VEX_W;
5896
5897 defm PEXTRQ      : SS41I_extract64<0x16, "pextrq">;
5898
5899 /// SS41I_extractf32 - SSE 4.1 extract 32 bits fp value to int reg or memory
5900 /// destination
5901 multiclass SS41I_extractf32<bits<8> opc, string OpcodeStr> {
5902   def rr : SS4AIi8<opc, MRMDestReg, (outs GR32:$dst),
5903                  (ins VR128:$src1, i32i8imm:$src2),
5904                  !strconcat(OpcodeStr,
5905                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5906                  [(set GR32:$dst,
5907                     (extractelt (bc_v4i32 (v4f32 VR128:$src1)), imm:$src2))]>,
5908            OpSize;
5909   def mr : SS4AIi8<opc, MRMDestMem, (outs),
5910                  (ins f32mem:$dst, VR128:$src1, i32i8imm:$src2),
5911                  !strconcat(OpcodeStr,
5912                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5913                  [(store (extractelt (bc_v4i32 (v4f32 VR128:$src1)), imm:$src2),
5914                           addr:$dst)]>, OpSize;
5915 }
5916
5917 let ExeDomain = SSEPackedSingle in {
5918   let Predicates = [HasAVX] in {
5919     defm VEXTRACTPS : SS41I_extractf32<0x17, "vextractps">, VEX;
5920     def VEXTRACTPSrr64 : SS4AIi8<0x17, MRMDestReg, (outs GR64:$dst),
5921                     (ins VR128:$src1, i32i8imm:$src2),
5922                     "vextractps \t{$src2, $src1, $dst|$dst, $src1, $src2}",
5923                     []>, OpSize, VEX;
5924   }
5925   defm EXTRACTPS   : SS41I_extractf32<0x17, "extractps">;
5926 }
5927
5928 // Also match an EXTRACTPS store when the store is done as f32 instead of i32.
5929 def : Pat<(store (f32 (bitconvert (extractelt (bc_v4i32 (v4f32 VR128:$src1)),
5930                                               imm:$src2))),
5931                  addr:$dst),
5932           (VEXTRACTPSmr addr:$dst, VR128:$src1, imm:$src2)>,
5933           Requires<[HasAVX]>;
5934 def : Pat<(store (f32 (bitconvert (extractelt (bc_v4i32 (v4f32 VR128:$src1)),
5935                                               imm:$src2))),
5936                  addr:$dst),
5937           (EXTRACTPSmr addr:$dst, VR128:$src1, imm:$src2)>,
5938           Requires<[HasSSE41]>;
5939
5940 //===----------------------------------------------------------------------===//
5941 // SSE4.1 - Insert Instructions
5942 //===----------------------------------------------------------------------===//
5943
5944 multiclass SS41I_insert8<bits<8> opc, string asm, bit Is2Addr = 1> {
5945   def rr : SS4AIi8<opc, MRMSrcReg, (outs VR128:$dst),
5946       (ins VR128:$src1, GR32:$src2, i32i8imm:$src3),
5947       !if(Is2Addr,
5948         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5949         !strconcat(asm,
5950                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5951       [(set VR128:$dst,
5952         (X86pinsrb VR128:$src1, GR32:$src2, imm:$src3))]>, OpSize;
5953   def rm : SS4AIi8<opc, MRMSrcMem, (outs VR128:$dst),
5954       (ins VR128:$src1, i8mem:$src2, i32i8imm:$src3),
5955       !if(Is2Addr,
5956         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5957         !strconcat(asm,
5958                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5959       [(set VR128:$dst,
5960         (X86pinsrb VR128:$src1, (extloadi8 addr:$src2),
5961                    imm:$src3))]>, OpSize;
5962 }
5963
5964 let Predicates = [HasAVX] in
5965   defm VPINSRB : SS41I_insert8<0x20, "vpinsrb", 0>, VEX_4V;
5966 let Constraints = "$src1 = $dst" in
5967   defm PINSRB  : SS41I_insert8<0x20, "pinsrb">;
5968
5969 multiclass SS41I_insert32<bits<8> opc, string asm, bit Is2Addr = 1> {
5970   def rr : SS4AIi8<opc, MRMSrcReg, (outs VR128:$dst),
5971       (ins VR128:$src1, GR32:$src2, i32i8imm:$src3),
5972       !if(Is2Addr,
5973         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5974         !strconcat(asm,
5975                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5976       [(set VR128:$dst,
5977         (v4i32 (insertelt VR128:$src1, GR32:$src2, imm:$src3)))]>,
5978       OpSize;
5979   def rm : SS4AIi8<opc, MRMSrcMem, (outs VR128:$dst),
5980       (ins VR128:$src1, i32mem:$src2, i32i8imm:$src3),
5981       !if(Is2Addr,
5982         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5983         !strconcat(asm,
5984                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5985       [(set VR128:$dst,
5986         (v4i32 (insertelt VR128:$src1, (loadi32 addr:$src2),
5987                           imm:$src3)))]>, OpSize;
5988 }
5989
5990 let Predicates = [HasAVX] in
5991   defm VPINSRD : SS41I_insert32<0x22, "vpinsrd", 0>, VEX_4V;
5992 let Constraints = "$src1 = $dst" in
5993   defm PINSRD : SS41I_insert32<0x22, "pinsrd">;
5994
5995 multiclass SS41I_insert64<bits<8> opc, string asm, bit Is2Addr = 1> {
5996   def rr : SS4AIi8<opc, MRMSrcReg, (outs VR128:$dst),
5997       (ins VR128:$src1, GR64:$src2, i32i8imm:$src3),
5998       !if(Is2Addr,
5999         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6000         !strconcat(asm,
6001                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6002       [(set VR128:$dst,
6003         (v2i64 (insertelt VR128:$src1, GR64:$src2, imm:$src3)))]>,
6004       OpSize;
6005   def rm : SS4AIi8<opc, MRMSrcMem, (outs VR128:$dst),
6006       (ins VR128:$src1, i64mem:$src2, i32i8imm:$src3),
6007       !if(Is2Addr,
6008         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6009         !strconcat(asm,
6010                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6011       [(set VR128:$dst,
6012         (v2i64 (insertelt VR128:$src1, (loadi64 addr:$src2),
6013                           imm:$src3)))]>, OpSize;
6014 }
6015
6016 let Predicates = [HasAVX] in
6017   defm VPINSRQ : SS41I_insert64<0x22, "vpinsrq", 0>, VEX_4V, VEX_W;
6018 let Constraints = "$src1 = $dst" in
6019   defm PINSRQ : SS41I_insert64<0x22, "pinsrq">, REX_W;
6020
6021 // insertps has a few different modes, there's the first two here below which
6022 // are optimized inserts that won't zero arbitrary elements in the destination
6023 // vector. The next one matches the intrinsic and could zero arbitrary elements
6024 // in the target vector.
6025 multiclass SS41I_insertf32<bits<8> opc, string asm, bit Is2Addr = 1> {
6026   def rr : SS4AIi8<opc, MRMSrcReg, (outs VR128:$dst),
6027       (ins VR128:$src1, VR128:$src2, u32u8imm:$src3),
6028       !if(Is2Addr,
6029         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6030         !strconcat(asm,
6031                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6032       [(set VR128:$dst,
6033         (X86insrtps VR128:$src1, VR128:$src2, imm:$src3))]>,
6034       OpSize;
6035   def rm : SS4AIi8<opc, MRMSrcMem, (outs VR128:$dst),
6036       (ins VR128:$src1, f32mem:$src2, u32u8imm:$src3),
6037       !if(Is2Addr,
6038         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6039         !strconcat(asm,
6040                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6041       [(set VR128:$dst,
6042         (X86insrtps VR128:$src1,
6043                    (v4f32 (scalar_to_vector (loadf32 addr:$src2))),
6044                     imm:$src3))]>, OpSize;
6045 }
6046
6047 let ExeDomain = SSEPackedSingle in {
6048   let Predicates = [HasAVX] in
6049     defm VINSERTPS : SS41I_insertf32<0x21, "vinsertps", 0>, VEX_4V;
6050   let Constraints = "$src1 = $dst" in
6051     defm INSERTPS : SS41I_insertf32<0x21, "insertps">;
6052 }
6053
6054 def : Pat<(int_x86_sse41_insertps VR128:$src1, VR128:$src2, imm:$src3),
6055           (VINSERTPSrr VR128:$src1, VR128:$src2, imm:$src3)>,
6056           Requires<[HasAVX]>;
6057 def : Pat<(int_x86_sse41_insertps VR128:$src1, VR128:$src2, imm:$src3),
6058           (INSERTPSrr VR128:$src1, VR128:$src2, imm:$src3)>,
6059           Requires<[HasSSE41]>;
6060
6061 //===----------------------------------------------------------------------===//
6062 // SSE4.1 - Round Instructions
6063 //===----------------------------------------------------------------------===//
6064
6065 multiclass sse41_fp_unop_rm<bits<8> opcps, bits<8> opcpd, string OpcodeStr,
6066                             X86MemOperand x86memop, RegisterClass RC,
6067                             PatFrag mem_frag32, PatFrag mem_frag64,
6068                             Intrinsic V4F32Int, Intrinsic V2F64Int> {
6069 let ExeDomain = SSEPackedSingle in {
6070   // Intrinsic operation, reg.
6071   // Vector intrinsic operation, reg
6072   def PSr : SS4AIi8<opcps, MRMSrcReg,
6073                     (outs RC:$dst), (ins RC:$src1, i32i8imm:$src2),
6074                     !strconcat(OpcodeStr,
6075                     "ps\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6076                     [(set RC:$dst, (V4F32Int RC:$src1, imm:$src2))]>,
6077                     OpSize;
6078
6079   // Vector intrinsic operation, mem
6080   def PSm : SS4AIi8<opcps, MRMSrcMem,
6081                     (outs RC:$dst), (ins x86memop:$src1, i32i8imm:$src2),
6082                     !strconcat(OpcodeStr,
6083                     "ps\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6084                     [(set RC:$dst,
6085                           (V4F32Int (mem_frag32 addr:$src1),imm:$src2))]>,
6086                     OpSize;
6087 } // ExeDomain = SSEPackedSingle
6088
6089 let ExeDomain = SSEPackedDouble in {
6090   // Vector intrinsic operation, reg
6091   def PDr : SS4AIi8<opcpd, MRMSrcReg,
6092                     (outs RC:$dst), (ins RC:$src1, i32i8imm:$src2),
6093                     !strconcat(OpcodeStr,
6094                     "pd\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6095                     [(set RC:$dst, (V2F64Int RC:$src1, imm:$src2))]>,
6096                     OpSize;
6097
6098   // Vector intrinsic operation, mem
6099   def PDm : SS4AIi8<opcpd, MRMSrcMem,
6100                     (outs RC:$dst), (ins x86memop:$src1, i32i8imm:$src2),
6101                     !strconcat(OpcodeStr,
6102                     "pd\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6103                     [(set RC:$dst,
6104                           (V2F64Int (mem_frag64 addr:$src1),imm:$src2))]>,
6105                     OpSize;
6106 } // ExeDomain = SSEPackedDouble
6107 }
6108
6109 multiclass sse41_fp_binop_rm<bits<8> opcss, bits<8> opcsd,
6110                             string OpcodeStr,
6111                             Intrinsic F32Int,
6112                             Intrinsic F64Int, bit Is2Addr = 1> {
6113 let ExeDomain = GenericDomain in {
6114   // Operation, reg.
6115   def SSr : SS4AIi8<opcss, MRMSrcReg,
6116       (outs FR32:$dst), (ins FR32:$src1, FR32:$src2, i32i8imm:$src3),
6117       !if(Is2Addr,
6118           !strconcat(OpcodeStr,
6119               "ss\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6120           !strconcat(OpcodeStr,
6121               "ss\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6122       []>, OpSize;
6123
6124   // Intrinsic operation, reg.
6125   def SSr_Int : SS4AIi8<opcss, MRMSrcReg,
6126         (outs VR128:$dst), (ins VR128:$src1, VR128:$src2, i32i8imm:$src3),
6127         !if(Is2Addr,
6128             !strconcat(OpcodeStr,
6129                 "ss\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6130             !strconcat(OpcodeStr,
6131                 "ss\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6132         [(set VR128:$dst, (F32Int VR128:$src1, VR128:$src2, imm:$src3))]>,
6133         OpSize;
6134
6135   // Intrinsic operation, mem.
6136   def SSm : SS4AIi8<opcss, MRMSrcMem,
6137         (outs VR128:$dst), (ins VR128:$src1, ssmem:$src2, i32i8imm:$src3),
6138         !if(Is2Addr,
6139             !strconcat(OpcodeStr,
6140                 "ss\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6141             !strconcat(OpcodeStr,
6142                 "ss\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6143         [(set VR128:$dst,
6144              (F32Int VR128:$src1, sse_load_f32:$src2, imm:$src3))]>,
6145         OpSize;
6146
6147   // Operation, reg.
6148   def SDr : SS4AIi8<opcsd, MRMSrcReg,
6149         (outs FR64:$dst), (ins FR64:$src1, FR64:$src2, i32i8imm:$src3),
6150         !if(Is2Addr,
6151             !strconcat(OpcodeStr,
6152                 "sd\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6153             !strconcat(OpcodeStr,
6154                 "sd\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6155         []>, OpSize;
6156
6157   // Intrinsic operation, reg.
6158   def SDr_Int : SS4AIi8<opcsd, MRMSrcReg,
6159         (outs VR128:$dst), (ins VR128:$src1, VR128:$src2, i32i8imm:$src3),
6160         !if(Is2Addr,
6161             !strconcat(OpcodeStr,
6162                 "sd\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6163             !strconcat(OpcodeStr,
6164                 "sd\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6165         [(set VR128:$dst, (F64Int VR128:$src1, VR128:$src2, imm:$src3))]>,
6166         OpSize;
6167
6168   // Intrinsic operation, mem.
6169   def SDm : SS4AIi8<opcsd, MRMSrcMem,
6170         (outs VR128:$dst), (ins VR128:$src1, sdmem:$src2, i32i8imm:$src3),
6171         !if(Is2Addr,
6172             !strconcat(OpcodeStr,
6173                 "sd\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6174             !strconcat(OpcodeStr,
6175                 "sd\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6176         [(set VR128:$dst,
6177               (F64Int VR128:$src1, sse_load_f64:$src2, imm:$src3))]>,
6178         OpSize;
6179 } // ExeDomain = GenericDomain
6180 }
6181
6182 // FP round - roundss, roundps, roundsd, roundpd
6183 let Predicates = [HasAVX] in {
6184   // Intrinsic form
6185   defm VROUND  : sse41_fp_unop_rm<0x08, 0x09, "vround", f128mem, VR128,
6186                                   memopv4f32, memopv2f64,
6187                                   int_x86_sse41_round_ps,
6188                                   int_x86_sse41_round_pd>, VEX;
6189   defm VROUNDY : sse41_fp_unop_rm<0x08, 0x09, "vround", f256mem, VR256,
6190                                   memopv8f32, memopv4f64,
6191                                   int_x86_avx_round_ps_256,
6192                                   int_x86_avx_round_pd_256>, VEX;
6193   defm VROUND  : sse41_fp_binop_rm<0x0A, 0x0B, "vround",
6194                                   int_x86_sse41_round_ss,
6195                                   int_x86_sse41_round_sd, 0>, VEX_4V, VEX_LIG;
6196
6197   def : Pat<(ffloor FR32:$src),
6198             (VROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x1))>;
6199   def : Pat<(f64 (ffloor FR64:$src)),
6200             (VROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x1))>;
6201   def : Pat<(f32 (fnearbyint FR32:$src)),
6202             (VROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0xC))>;
6203   def : Pat<(f64 (fnearbyint FR64:$src)),
6204             (VROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0xC))>;
6205   def : Pat<(f32 (fceil FR32:$src)),
6206             (VROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x2))>;
6207   def : Pat<(f64 (fceil FR64:$src)),
6208             (VROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x2))>;
6209   def : Pat<(f32 (frint FR32:$src)),
6210             (VROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x4))>;
6211   def : Pat<(f64 (frint FR64:$src)),
6212             (VROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x4))>;
6213   def : Pat<(f32 (ftrunc FR32:$src)),
6214             (VROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x3))>;
6215   def : Pat<(f64 (ftrunc FR64:$src)),
6216             (VROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x3))>;
6217 }
6218
6219 defm ROUND  : sse41_fp_unop_rm<0x08, 0x09, "round", f128mem, VR128,
6220                                memopv4f32, memopv2f64,
6221                                int_x86_sse41_round_ps, int_x86_sse41_round_pd>;
6222 let Constraints = "$src1 = $dst" in
6223 defm ROUND  : sse41_fp_binop_rm<0x0A, 0x0B, "round",
6224                                int_x86_sse41_round_ss, int_x86_sse41_round_sd>;
6225
6226 def : Pat<(ffloor FR32:$src),
6227           (ROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x1))>;
6228 def : Pat<(f64 (ffloor FR64:$src)),
6229           (ROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x1))>;
6230 def : Pat<(f32 (fnearbyint FR32:$src)),
6231           (ROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0xC))>;
6232 def : Pat<(f64 (fnearbyint FR64:$src)),
6233           (ROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0xC))>;
6234 def : Pat<(f32 (fceil FR32:$src)),
6235           (ROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x2))>;
6236 def : Pat<(f64 (fceil FR64:$src)),
6237           (ROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x2))>;
6238 def : Pat<(f32 (frint FR32:$src)),
6239           (ROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x4))>;
6240 def : Pat<(f64 (frint FR64:$src)),
6241           (ROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x4))>;
6242 def : Pat<(f32 (ftrunc FR32:$src)),
6243           (ROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x3))>;
6244 def : Pat<(f64 (ftrunc FR64:$src)),
6245           (ROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x3))>;
6246
6247 //===----------------------------------------------------------------------===//
6248 // SSE4.1 - Packed Bit Test
6249 //===----------------------------------------------------------------------===//
6250
6251 // ptest instruction we'll lower to this in X86ISelLowering primarily from
6252 // the intel intrinsic that corresponds to this.
6253 let Defs = [EFLAGS], Predicates = [HasAVX] in {
6254 def VPTESTrr  : SS48I<0x17, MRMSrcReg, (outs), (ins VR128:$src1, VR128:$src2),
6255                 "vptest\t{$src2, $src1|$src1, $src2}",
6256                 [(set EFLAGS, (X86ptest VR128:$src1, (v4f32 VR128:$src2)))]>,
6257                 OpSize, VEX;
6258 def VPTESTrm  : SS48I<0x17, MRMSrcMem, (outs), (ins VR128:$src1, f128mem:$src2),
6259                 "vptest\t{$src2, $src1|$src1, $src2}",
6260                 [(set EFLAGS,(X86ptest VR128:$src1, (memopv4f32 addr:$src2)))]>,
6261                 OpSize, VEX;
6262
6263 def VPTESTYrr : SS48I<0x17, MRMSrcReg, (outs), (ins VR256:$src1, VR256:$src2),
6264                 "vptest\t{$src2, $src1|$src1, $src2}",
6265                 [(set EFLAGS, (X86ptest VR256:$src1, (v4i64 VR256:$src2)))]>,
6266                 OpSize, VEX;
6267 def VPTESTYrm : SS48I<0x17, MRMSrcMem, (outs), (ins VR256:$src1, i256mem:$src2),
6268                 "vptest\t{$src2, $src1|$src1, $src2}",
6269                 [(set EFLAGS,(X86ptest VR256:$src1, (memopv4i64 addr:$src2)))]>,
6270                 OpSize, VEX;
6271 }
6272
6273 let Defs = [EFLAGS] in {
6274 def PTESTrr : SS48I<0x17, MRMSrcReg, (outs), (ins VR128:$src1, VR128:$src2),
6275               "ptest\t{$src2, $src1|$src1, $src2}",
6276               [(set EFLAGS, (X86ptest VR128:$src1, (v4f32 VR128:$src2)))]>,
6277               OpSize;
6278 def PTESTrm : SS48I<0x17, MRMSrcMem, (outs), (ins VR128:$src1, f128mem:$src2),
6279               "ptest\t{$src2, $src1|$src1, $src2}",
6280               [(set EFLAGS, (X86ptest VR128:$src1, (memopv4f32 addr:$src2)))]>,
6281               OpSize;
6282 }
6283
6284 // The bit test instructions below are AVX only
6285 multiclass avx_bittest<bits<8> opc, string OpcodeStr, RegisterClass RC,
6286                        X86MemOperand x86memop, PatFrag mem_frag, ValueType vt> {
6287   def rr : SS48I<opc, MRMSrcReg, (outs), (ins RC:$src1, RC:$src2),
6288             !strconcat(OpcodeStr, "\t{$src2, $src1|$src1, $src2}"),
6289             [(set EFLAGS, (X86testp RC:$src1, (vt RC:$src2)))]>, OpSize, VEX;
6290   def rm : SS48I<opc, MRMSrcMem, (outs), (ins RC:$src1, x86memop:$src2),
6291             !strconcat(OpcodeStr, "\t{$src2, $src1|$src1, $src2}"),
6292             [(set EFLAGS, (X86testp RC:$src1, (mem_frag addr:$src2)))]>,
6293             OpSize, VEX;
6294 }
6295
6296 let Defs = [EFLAGS], Predicates = [HasAVX] in {
6297 let ExeDomain = SSEPackedSingle in {
6298 defm VTESTPS  : avx_bittest<0x0E, "vtestps", VR128, f128mem, memopv4f32, v4f32>;
6299 defm VTESTPSY : avx_bittest<0x0E, "vtestps", VR256, f256mem, memopv8f32, v8f32>;
6300 }
6301 let ExeDomain = SSEPackedDouble in {
6302 defm VTESTPD  : avx_bittest<0x0F, "vtestpd", VR128, f128mem, memopv2f64, v2f64>;
6303 defm VTESTPDY : avx_bittest<0x0F, "vtestpd", VR256, f256mem, memopv4f64, v4f64>;
6304 }
6305 }
6306
6307 //===----------------------------------------------------------------------===//
6308 // SSE4.1 - Misc Instructions
6309 //===----------------------------------------------------------------------===//
6310
6311 let Defs = [EFLAGS], Predicates = [HasPOPCNT] in {
6312   def POPCNT16rr : I<0xB8, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
6313                      "popcnt{w}\t{$src, $dst|$dst, $src}",
6314                      [(set GR16:$dst, (ctpop GR16:$src)), (implicit EFLAGS)]>,
6315                      OpSize, XS;
6316   def POPCNT16rm : I<0xB8, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
6317                      "popcnt{w}\t{$src, $dst|$dst, $src}",
6318                      [(set GR16:$dst, (ctpop (loadi16 addr:$src))),
6319                       (implicit EFLAGS)]>, OpSize, XS;
6320
6321   def POPCNT32rr : I<0xB8, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
6322                      "popcnt{l}\t{$src, $dst|$dst, $src}",
6323                      [(set GR32:$dst, (ctpop GR32:$src)), (implicit EFLAGS)]>,
6324                      XS;
6325   def POPCNT32rm : I<0xB8, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
6326                      "popcnt{l}\t{$src, $dst|$dst, $src}",
6327                      [(set GR32:$dst, (ctpop (loadi32 addr:$src))),
6328                       (implicit EFLAGS)]>, XS;
6329
6330   def POPCNT64rr : RI<0xB8, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
6331                       "popcnt{q}\t{$src, $dst|$dst, $src}",
6332                       [(set GR64:$dst, (ctpop GR64:$src)), (implicit EFLAGS)]>,
6333                       XS;
6334   def POPCNT64rm : RI<0xB8, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
6335                       "popcnt{q}\t{$src, $dst|$dst, $src}",
6336                       [(set GR64:$dst, (ctpop (loadi64 addr:$src))),
6337                        (implicit EFLAGS)]>, XS;
6338 }
6339
6340
6341
6342 // SS41I_unop_rm_int_v16 - SSE 4.1 unary operator whose type is v8i16.
6343 multiclass SS41I_unop_rm_int_v16<bits<8> opc, string OpcodeStr,
6344                                  Intrinsic IntId128> {
6345   def rr128 : SS48I<opc, MRMSrcReg, (outs VR128:$dst),
6346                     (ins VR128:$src),
6347                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
6348                     [(set VR128:$dst, (IntId128 VR128:$src))]>, OpSize;
6349   def rm128 : SS48I<opc, MRMSrcMem, (outs VR128:$dst),
6350                      (ins i128mem:$src),
6351                      !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
6352                      [(set VR128:$dst,
6353                        (IntId128
6354                         (bitconvert (memopv2i64 addr:$src))))]>, OpSize;
6355 }
6356
6357 let Predicates = [HasAVX] in
6358 defm VPHMINPOSUW : SS41I_unop_rm_int_v16 <0x41, "vphminposuw",
6359                                          int_x86_sse41_phminposuw>, VEX;
6360 defm PHMINPOSUW : SS41I_unop_rm_int_v16 <0x41, "phminposuw",
6361                                          int_x86_sse41_phminposuw>;
6362
6363 /// SS41I_binop_rm_int - Simple SSE 4.1 binary operator
6364 multiclass SS41I_binop_rm_int<bits<8> opc, string OpcodeStr,
6365                               Intrinsic IntId128, bit Is2Addr = 1> {
6366   let isCommutable = 1 in
6367   def rr : SS48I<opc, MRMSrcReg, (outs VR128:$dst),
6368        (ins VR128:$src1, VR128:$src2),
6369        !if(Is2Addr,
6370            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
6371            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
6372        [(set VR128:$dst, (IntId128 VR128:$src1, VR128:$src2))]>, OpSize;
6373   def rm : SS48I<opc, MRMSrcMem, (outs VR128:$dst),
6374        (ins VR128:$src1, i128mem:$src2),
6375        !if(Is2Addr,
6376            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
6377            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
6378        [(set VR128:$dst,
6379          (IntId128 VR128:$src1,
6380           (bitconvert (memopv2i64 addr:$src2))))]>, OpSize;
6381 }
6382
6383 /// SS41I_binop_rm_int - Simple SSE 4.1 binary operator
6384 multiclass SS41I_binop_rm_int_y<bits<8> opc, string OpcodeStr,
6385                                 Intrinsic IntId256> {
6386   let isCommutable = 1 in
6387   def Yrr : SS48I<opc, MRMSrcReg, (outs VR256:$dst),
6388        (ins VR256:$src1, VR256:$src2),
6389        !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6390        [(set VR256:$dst, (IntId256 VR256:$src1, VR256:$src2))]>, OpSize;
6391   def Yrm : SS48I<opc, MRMSrcMem, (outs VR256:$dst),
6392        (ins VR256:$src1, i256mem:$src2),
6393        !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6394        [(set VR256:$dst,
6395          (IntId256 VR256:$src1,
6396           (bitconvert (memopv4i64 addr:$src2))))]>, OpSize;
6397 }
6398
6399 let Predicates = [HasAVX] in {
6400   let isCommutable = 0 in
6401   defm VPACKUSDW : SS41I_binop_rm_int<0x2B, "vpackusdw", int_x86_sse41_packusdw,
6402                                                          0>, VEX_4V;
6403   defm VPCMPEQQ  : SS41I_binop_rm_int<0x29, "vpcmpeqq",  int_x86_sse41_pcmpeqq,
6404                                                          0>, VEX_4V;
6405   defm VPMINSB   : SS41I_binop_rm_int<0x38, "vpminsb",   int_x86_sse41_pminsb,
6406                                                          0>, VEX_4V;
6407   defm VPMINSD   : SS41I_binop_rm_int<0x39, "vpminsd",   int_x86_sse41_pminsd,
6408                                                          0>, VEX_4V;
6409   defm VPMINUD   : SS41I_binop_rm_int<0x3B, "vpminud",   int_x86_sse41_pminud,
6410                                                          0>, VEX_4V;
6411   defm VPMINUW   : SS41I_binop_rm_int<0x3A, "vpminuw",   int_x86_sse41_pminuw,
6412                                                          0>, VEX_4V;
6413   defm VPMAXSB   : SS41I_binop_rm_int<0x3C, "vpmaxsb",   int_x86_sse41_pmaxsb,
6414                                                          0>, VEX_4V;
6415   defm VPMAXSD   : SS41I_binop_rm_int<0x3D, "vpmaxsd",   int_x86_sse41_pmaxsd,
6416                                                          0>, VEX_4V;
6417   defm VPMAXUD   : SS41I_binop_rm_int<0x3F, "vpmaxud",   int_x86_sse41_pmaxud,
6418                                                          0>, VEX_4V;
6419   defm VPMAXUW   : SS41I_binop_rm_int<0x3E, "vpmaxuw",   int_x86_sse41_pmaxuw,
6420                                                          0>, VEX_4V;
6421   defm VPMULDQ   : SS41I_binop_rm_int<0x28, "vpmuldq",   int_x86_sse41_pmuldq,
6422                                                          0>, VEX_4V;
6423
6424   def : Pat<(v2i64 (X86pcmpeqq VR128:$src1, VR128:$src2)),
6425             (VPCMPEQQrr VR128:$src1, VR128:$src2)>;
6426   def : Pat<(v2i64 (X86pcmpeqq VR128:$src1, (memop addr:$src2))),
6427             (VPCMPEQQrm VR128:$src1, addr:$src2)>;
6428 }
6429
6430 let Predicates = [HasAVX2] in {
6431   let isCommutable = 0 in
6432   defm VPACKUSDW : SS41I_binop_rm_int_y<0x2B, "vpackusdw",
6433                                         int_x86_avx2_packusdw>, VEX_4V;
6434   defm VPCMPEQQ  : SS41I_binop_rm_int_y<0x29, "vpcmpeqq",
6435                                         int_x86_avx2_pcmpeq_q>, VEX_4V;
6436   defm VPMINSB   : SS41I_binop_rm_int_y<0x38, "vpminsb",
6437                                         int_x86_avx2_pmins_b>, VEX_4V;
6438   defm VPMINSD   : SS41I_binop_rm_int_y<0x39, "vpminsd",
6439                                         int_x86_avx2_pmins_d>, VEX_4V;
6440   defm VPMINUD   : SS41I_binop_rm_int_y<0x3B, "vpminud",
6441                                         int_x86_avx2_pminu_d>, VEX_4V;
6442   defm VPMINUW   : SS41I_binop_rm_int_y<0x3A, "vpminuw",
6443                                         int_x86_avx2_pminu_w>, VEX_4V;
6444   defm VPMAXSB   : SS41I_binop_rm_int_y<0x3C, "vpmaxsb",
6445                                         int_x86_avx2_pmaxs_b>, VEX_4V;
6446   defm VPMAXSD   : SS41I_binop_rm_int_y<0x3D, "vpmaxsd",
6447                                         int_x86_avx2_pmaxs_d>, VEX_4V;
6448   defm VPMAXUD   : SS41I_binop_rm_int_y<0x3F, "vpmaxud",
6449                                         int_x86_avx2_pmaxu_d>, VEX_4V;
6450   defm VPMAXUW   : SS41I_binop_rm_int_y<0x3E, "vpmaxuw",
6451                                         int_x86_avx2_pmaxu_w>, VEX_4V;
6452   defm VPMULDQ   : SS41I_binop_rm_int_y<0x28, "vpmuldq",
6453                                         int_x86_avx2_pmul_dq>, VEX_4V;
6454
6455   def : Pat<(v4i64 (X86pcmpeqq VR256:$src1, VR256:$src2)),
6456             (VPCMPEQQYrr VR256:$src1, VR256:$src2)>;
6457   def : Pat<(v4i64 (X86pcmpeqq VR256:$src1, (memop addr:$src2))),
6458             (VPCMPEQQYrm VR256:$src1, addr:$src2)>;
6459 }
6460
6461 let Constraints = "$src1 = $dst" in {
6462   let isCommutable = 0 in
6463   defm PACKUSDW : SS41I_binop_rm_int<0x2B, "packusdw", int_x86_sse41_packusdw>;
6464   defm PCMPEQQ  : SS41I_binop_rm_int<0x29, "pcmpeqq",  int_x86_sse41_pcmpeqq>;
6465   defm PMINSB   : SS41I_binop_rm_int<0x38, "pminsb",   int_x86_sse41_pminsb>;
6466   defm PMINSD   : SS41I_binop_rm_int<0x39, "pminsd",   int_x86_sse41_pminsd>;
6467   defm PMINUD   : SS41I_binop_rm_int<0x3B, "pminud",   int_x86_sse41_pminud>;
6468   defm PMINUW   : SS41I_binop_rm_int<0x3A, "pminuw",   int_x86_sse41_pminuw>;
6469   defm PMAXSB   : SS41I_binop_rm_int<0x3C, "pmaxsb",   int_x86_sse41_pmaxsb>;
6470   defm PMAXSD   : SS41I_binop_rm_int<0x3D, "pmaxsd",   int_x86_sse41_pmaxsd>;
6471   defm PMAXUD   : SS41I_binop_rm_int<0x3F, "pmaxud",   int_x86_sse41_pmaxud>;
6472   defm PMAXUW   : SS41I_binop_rm_int<0x3E, "pmaxuw",   int_x86_sse41_pmaxuw>;
6473   defm PMULDQ   : SS41I_binop_rm_int<0x28, "pmuldq",   int_x86_sse41_pmuldq>;
6474 }
6475
6476 let Predicates = [HasSSE41] in {
6477   def : Pat<(v2i64 (X86pcmpeqq VR128:$src1, VR128:$src2)),
6478             (PCMPEQQrr VR128:$src1, VR128:$src2)>;
6479   def : Pat<(v2i64 (X86pcmpeqq VR128:$src1, (memop addr:$src2))),
6480             (PCMPEQQrm VR128:$src1, addr:$src2)>;
6481 }
6482
6483 /// SS48I_binop_rm - Simple SSE41 binary operator.
6484 multiclass SS48I_binop_rm<bits<8> opc, string OpcodeStr, SDNode OpNode,
6485                           ValueType OpVT, bit Is2Addr = 1> {
6486   let isCommutable = 1 in
6487   def rr : SS48I<opc, MRMSrcReg, (outs VR128:$dst),
6488        (ins VR128:$src1, VR128:$src2),
6489        !if(Is2Addr,
6490            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
6491            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
6492        [(set VR128:$dst, (OpVT (OpNode VR128:$src1, VR128:$src2)))]>,
6493        OpSize;
6494   def rm : SS48I<opc, MRMSrcMem, (outs VR128:$dst),
6495        (ins VR128:$src1, i128mem:$src2),
6496        !if(Is2Addr,
6497            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
6498            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
6499        [(set VR128:$dst, (OpNode VR128:$src1,
6500                                   (bc_v4i32 (memopv2i64 addr:$src2))))]>,
6501        OpSize;
6502 }
6503
6504 /// SS48I_binop_rm - Simple SSE41 binary operator.
6505 multiclass SS48I_binop_rm_y<bits<8> opc, string OpcodeStr, SDNode OpNode,
6506                             ValueType OpVT> {
6507   let isCommutable = 1 in
6508   def Yrr : SS48I<opc, MRMSrcReg, (outs VR256:$dst),
6509        (ins VR256:$src1, VR256:$src2),
6510        !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6511        [(set VR256:$dst, (OpVT (OpNode VR256:$src1, VR256:$src2)))]>,
6512        OpSize;
6513   def Yrm : SS48I<opc, MRMSrcMem, (outs VR256:$dst),
6514        (ins VR256:$src1, i256mem:$src2),
6515        !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6516        [(set VR256:$dst, (OpNode VR256:$src1,
6517                                   (bc_v8i32 (memopv4i64 addr:$src2))))]>,
6518        OpSize;
6519 }
6520
6521 let Predicates = [HasAVX] in
6522   defm VPMULLD : SS48I_binop_rm<0x40, "vpmulld", mul, v4i32, 0>, VEX_4V;
6523 let Predicates = [HasAVX2] in
6524   defm VPMULLD : SS48I_binop_rm_y<0x40, "vpmulld", mul, v8i32>, VEX_4V;
6525 let Constraints = "$src1 = $dst" in
6526   defm PMULLD : SS48I_binop_rm<0x40, "pmulld", mul, v4i32>;
6527
6528 /// SS41I_binop_rmi_int - SSE 4.1 binary operator with 8-bit immediate
6529 multiclass SS41I_binop_rmi_int<bits<8> opc, string OpcodeStr,
6530                  Intrinsic IntId, RegisterClass RC, PatFrag memop_frag,
6531                  X86MemOperand x86memop, bit Is2Addr = 1> {
6532   let isCommutable = 1 in
6533   def rri : SS4AIi8<opc, MRMSrcReg, (outs RC:$dst),
6534         (ins RC:$src1, RC:$src2, u32u8imm:$src3),
6535         !if(Is2Addr,
6536             !strconcat(OpcodeStr,
6537                 "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6538             !strconcat(OpcodeStr,
6539                 "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6540         [(set RC:$dst, (IntId RC:$src1, RC:$src2, imm:$src3))]>,
6541         OpSize;
6542   def rmi : SS4AIi8<opc, MRMSrcMem, (outs RC:$dst),
6543         (ins RC:$src1, x86memop:$src2, u32u8imm:$src3),
6544         !if(Is2Addr,
6545             !strconcat(OpcodeStr,
6546                 "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6547             !strconcat(OpcodeStr,
6548                 "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6549         [(set RC:$dst,
6550           (IntId RC:$src1,
6551            (bitconvert (memop_frag addr:$src2)), imm:$src3))]>,
6552         OpSize;
6553 }
6554
6555 let Predicates = [HasAVX] in {
6556   let isCommutable = 0 in {
6557     let ExeDomain = SSEPackedSingle in {
6558     defm VBLENDPS : SS41I_binop_rmi_int<0x0C, "vblendps", int_x86_sse41_blendps,
6559                                         VR128, memopv4f32, i128mem, 0>, VEX_4V;
6560     defm VBLENDPSY : SS41I_binop_rmi_int<0x0C, "vblendps",
6561               int_x86_avx_blend_ps_256, VR256, memopv8f32, i256mem, 0>, VEX_4V;
6562     }
6563     let ExeDomain = SSEPackedDouble in {
6564     defm VBLENDPD : SS41I_binop_rmi_int<0x0D, "vblendpd", int_x86_sse41_blendpd,
6565                                         VR128, memopv2f64, i128mem, 0>, VEX_4V;
6566     defm VBLENDPDY : SS41I_binop_rmi_int<0x0D, "vblendpd",
6567               int_x86_avx_blend_pd_256, VR256, memopv4f64, i256mem, 0>, VEX_4V;
6568     }
6569   defm VPBLENDW : SS41I_binop_rmi_int<0x0E, "vpblendw", int_x86_sse41_pblendw,
6570                                       VR128, memopv2i64, i128mem, 0>, VEX_4V;
6571   defm VMPSADBW : SS41I_binop_rmi_int<0x42, "vmpsadbw", int_x86_sse41_mpsadbw,
6572                                       VR128, memopv2i64, i128mem, 0>, VEX_4V;
6573   }
6574   let ExeDomain = SSEPackedSingle in
6575   defm VDPPS : SS41I_binop_rmi_int<0x40, "vdpps", int_x86_sse41_dpps,
6576                                    VR128, memopv4f32, i128mem, 0>, VEX_4V;
6577   let ExeDomain = SSEPackedDouble in
6578   defm VDPPD : SS41I_binop_rmi_int<0x41, "vdppd", int_x86_sse41_dppd,
6579                                    VR128, memopv2f64, i128mem, 0>, VEX_4V;
6580   let ExeDomain = SSEPackedSingle in
6581   defm VDPPSY : SS41I_binop_rmi_int<0x40, "vdpps", int_x86_avx_dp_ps_256,
6582                                    VR256, memopv8f32, i256mem, 0>, VEX_4V;
6583 }
6584
6585 let Predicates = [HasAVX2] in {
6586   let isCommutable = 0 in {
6587   defm VPBLENDWY : SS41I_binop_rmi_int<0x0E, "vpblendw", int_x86_avx2_pblendw,
6588                                        VR256, memopv4i64, i256mem, 0>, VEX_4V;
6589   defm VMPSADBWY : SS41I_binop_rmi_int<0x42, "vmpsadbw", int_x86_avx2_mpsadbw,
6590                                        VR256, memopv4i64, i256mem, 0>, VEX_4V;
6591   }
6592 }
6593
6594 let Constraints = "$src1 = $dst" in {
6595   let isCommutable = 0 in {
6596   let ExeDomain = SSEPackedSingle in
6597   defm BLENDPS : SS41I_binop_rmi_int<0x0C, "blendps", int_x86_sse41_blendps,
6598                                      VR128, memopv4f32, i128mem>;
6599   let ExeDomain = SSEPackedDouble in
6600   defm BLENDPD : SS41I_binop_rmi_int<0x0D, "blendpd", int_x86_sse41_blendpd,
6601                                      VR128, memopv2f64, i128mem>;
6602   defm PBLENDW : SS41I_binop_rmi_int<0x0E, "pblendw", int_x86_sse41_pblendw,
6603                                      VR128, memopv2i64, i128mem>;
6604   defm MPSADBW : SS41I_binop_rmi_int<0x42, "mpsadbw", int_x86_sse41_mpsadbw,
6605                                      VR128, memopv2i64, i128mem>;
6606   }
6607   let ExeDomain = SSEPackedSingle in
6608   defm DPPS : SS41I_binop_rmi_int<0x40, "dpps", int_x86_sse41_dpps,
6609                                   VR128, memopv4f32, i128mem>;
6610   let ExeDomain = SSEPackedDouble in
6611   defm DPPD : SS41I_binop_rmi_int<0x41, "dppd", int_x86_sse41_dppd,
6612                                   VR128, memopv2f64, i128mem>;
6613 }
6614
6615 /// SS41I_quaternary_int_avx - AVX SSE 4.1 with 4 operators
6616 multiclass SS41I_quaternary_int_avx<bits<8> opc, string OpcodeStr,
6617                                     RegisterClass RC, X86MemOperand x86memop,
6618                                     PatFrag mem_frag, Intrinsic IntId> {
6619   def rr : Ii8<opc, MRMSrcReg, (outs RC:$dst),
6620                   (ins RC:$src1, RC:$src2, RC:$src3),
6621                   !strconcat(OpcodeStr,
6622                     "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
6623                   [(set RC:$dst, (IntId RC:$src1, RC:$src2, RC:$src3))],
6624                   SSEPackedInt>, OpSize, TA, VEX_4V, VEX_I8IMM;
6625
6626   def rm : Ii8<opc, MRMSrcMem, (outs RC:$dst),
6627                   (ins RC:$src1, x86memop:$src2, RC:$src3),
6628                   !strconcat(OpcodeStr,
6629                     "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
6630                   [(set RC:$dst,
6631                         (IntId RC:$src1, (bitconvert (mem_frag addr:$src2)),
6632                                RC:$src3))],
6633                   SSEPackedInt>, OpSize, TA, VEX_4V, VEX_I8IMM;
6634 }
6635
6636 let Predicates = [HasAVX] in {
6637 let ExeDomain = SSEPackedDouble in {
6638 defm VBLENDVPD  : SS41I_quaternary_int_avx<0x4B, "vblendvpd", VR128, i128mem,
6639                                            memopv2f64, int_x86_sse41_blendvpd>;
6640 defm VBLENDVPDY : SS41I_quaternary_int_avx<0x4B, "vblendvpd", VR256, i256mem,
6641                                          memopv4f64, int_x86_avx_blendv_pd_256>;
6642 } // ExeDomain = SSEPackedDouble
6643 let ExeDomain = SSEPackedSingle in {
6644 defm VBLENDVPS  : SS41I_quaternary_int_avx<0x4A, "vblendvps", VR128, i128mem,
6645                                            memopv4f32, int_x86_sse41_blendvps>;
6646 defm VBLENDVPSY : SS41I_quaternary_int_avx<0x4A, "vblendvps", VR256, i256mem,
6647                                          memopv8f32, int_x86_avx_blendv_ps_256>;
6648 } // ExeDomain = SSEPackedSingle
6649 defm VPBLENDVB  : SS41I_quaternary_int_avx<0x4C, "vpblendvb", VR128, i128mem,
6650                                            memopv2i64, int_x86_sse41_pblendvb>;
6651 }
6652
6653 let Predicates = [HasAVX2] in {
6654 defm VPBLENDVBY : SS41I_quaternary_int_avx<0x4C, "vpblendvb", VR256, i256mem,
6655                                            memopv4i64, int_x86_avx2_pblendvb>;
6656 }
6657
6658 let Predicates = [HasAVX] in {
6659   def : Pat<(v16i8 (vselect (v16i8 VR128:$mask), (v16i8 VR128:$src1),
6660                             (v16i8 VR128:$src2))),
6661             (VPBLENDVBrr VR128:$src2, VR128:$src1, VR128:$mask)>;
6662   def : Pat<(v4i32 (vselect (v4i32 VR128:$mask), (v4i32 VR128:$src1),
6663                             (v4i32 VR128:$src2))),
6664             (VBLENDVPSrr VR128:$src2, VR128:$src1, VR128:$mask)>;
6665   def : Pat<(v4f32 (vselect (v4i32 VR128:$mask), (v4f32 VR128:$src1),
6666                             (v4f32 VR128:$src2))),
6667             (VBLENDVPSrr VR128:$src2, VR128:$src1, VR128:$mask)>;
6668   def : Pat<(v2i64 (vselect (v2i64 VR128:$mask), (v2i64 VR128:$src1),
6669                             (v2i64 VR128:$src2))),
6670             (VBLENDVPDrr VR128:$src2, VR128:$src1, VR128:$mask)>;
6671   def : Pat<(v2f64 (vselect (v2i64 VR128:$mask), (v2f64 VR128:$src1),
6672                             (v2f64 VR128:$src2))),
6673             (VBLENDVPDrr VR128:$src2, VR128:$src1, VR128:$mask)>;
6674   def : Pat<(v8i32 (vselect (v8i32 VR256:$mask), (v8i32 VR256:$src1),
6675                             (v8i32 VR256:$src2))),
6676             (VBLENDVPSYrr VR256:$src2, VR256:$src1, VR256:$mask)>;
6677   def : Pat<(v8f32 (vselect (v8i32 VR256:$mask), (v8f32 VR256:$src1),
6678                             (v8f32 VR256:$src2))),
6679             (VBLENDVPSYrr VR256:$src2, VR256:$src1, VR256:$mask)>;
6680   def : Pat<(v4i64 (vselect (v4i64 VR256:$mask), (v4i64 VR256:$src1),
6681                             (v4i64 VR256:$src2))),
6682             (VBLENDVPDYrr VR256:$src2, VR256:$src1, VR256:$mask)>;
6683   def : Pat<(v4f64 (vselect (v4i64 VR256:$mask), (v4f64 VR256:$src1),
6684                             (v4f64 VR256:$src2))),
6685             (VBLENDVPDYrr VR256:$src2, VR256:$src1, VR256:$mask)>;
6686 }
6687
6688 let Predicates = [HasAVX2] in {
6689   def : Pat<(v32i8 (vselect (v32i8 VR256:$mask), (v32i8 VR256:$src1),
6690                             (v32i8 VR256:$src2))),
6691             (VPBLENDVBYrr VR256:$src2, VR256:$src1, VR256:$mask)>;
6692 }
6693
6694 /// SS41I_ternary_int - SSE 4.1 ternary operator
6695 let Uses = [XMM0], Constraints = "$src1 = $dst" in {
6696   multiclass SS41I_ternary_int<bits<8> opc, string OpcodeStr, PatFrag mem_frag,
6697                                Intrinsic IntId> {
6698     def rr0 : SS48I<opc, MRMSrcReg, (outs VR128:$dst),
6699                     (ins VR128:$src1, VR128:$src2),
6700                     !strconcat(OpcodeStr,
6701                      "\t{$src2, $dst|$dst, $src2}"),
6702                     [(set VR128:$dst, (IntId VR128:$src1, VR128:$src2, XMM0))]>,
6703                     OpSize;
6704
6705     def rm0 : SS48I<opc, MRMSrcMem, (outs VR128:$dst),
6706                     (ins VR128:$src1, i128mem:$src2),
6707                     !strconcat(OpcodeStr,
6708                      "\t{$src2, $dst|$dst, $src2}"),
6709                     [(set VR128:$dst,
6710                       (IntId VR128:$src1,
6711                        (bitconvert (mem_frag addr:$src2)), XMM0))]>, OpSize;
6712   }
6713 }
6714
6715 let ExeDomain = SSEPackedDouble in
6716 defm BLENDVPD : SS41I_ternary_int<0x15, "blendvpd", memopv2f64,
6717                                   int_x86_sse41_blendvpd>;
6718 let ExeDomain = SSEPackedSingle in
6719 defm BLENDVPS : SS41I_ternary_int<0x14, "blendvps", memopv4f32,
6720                                   int_x86_sse41_blendvps>;
6721 defm PBLENDVB : SS41I_ternary_int<0x10, "pblendvb", memopv2i64,
6722                                   int_x86_sse41_pblendvb>;
6723
6724 let Predicates = [HasSSE41] in {
6725   def : Pat<(v16i8 (vselect (v16i8 XMM0), (v16i8 VR128:$src1),
6726                             (v16i8 VR128:$src2))),
6727             (PBLENDVBrr0 VR128:$src2, VR128:$src1)>;
6728   def : Pat<(v4i32 (vselect (v4i32 XMM0), (v4i32 VR128:$src1),
6729                             (v4i32 VR128:$src2))),
6730             (BLENDVPSrr0 VR128:$src2, VR128:$src1)>;
6731   def : Pat<(v4f32 (vselect (v4i32 XMM0), (v4f32 VR128:$src1),
6732                             (v4f32 VR128:$src2))),
6733             (BLENDVPSrr0 VR128:$src2, VR128:$src1)>;
6734   def : Pat<(v2i64 (vselect (v2i64 XMM0), (v2i64 VR128:$src1),
6735                             (v2i64 VR128:$src2))),
6736             (BLENDVPDrr0 VR128:$src2, VR128:$src1)>;
6737   def : Pat<(v2f64 (vselect (v2i64 XMM0), (v2f64 VR128:$src1),
6738                             (v2f64 VR128:$src2))),
6739             (BLENDVPDrr0 VR128:$src2, VR128:$src1)>;
6740 }
6741
6742 let Predicates = [HasAVX] in
6743 def VMOVNTDQArm : SS48I<0x2A, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
6744                        "vmovntdqa\t{$src, $dst|$dst, $src}",
6745                        [(set VR128:$dst, (int_x86_sse41_movntdqa addr:$src))]>,
6746                        OpSize, VEX;
6747 let Predicates = [HasAVX2] in
6748 def VMOVNTDQAYrm : SS48I<0x2A, MRMSrcMem, (outs VR256:$dst), (ins i256mem:$src),
6749                          "vmovntdqa\t{$src, $dst|$dst, $src}",
6750                          [(set VR256:$dst, (int_x86_avx2_movntdqa addr:$src))]>,
6751                          OpSize, VEX;
6752 def MOVNTDQArm : SS48I<0x2A, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
6753                        "movntdqa\t{$src, $dst|$dst, $src}",
6754                        [(set VR128:$dst, (int_x86_sse41_movntdqa addr:$src))]>,
6755                        OpSize;
6756
6757 //===----------------------------------------------------------------------===//
6758 // SSE4.2 - Compare Instructions
6759 //===----------------------------------------------------------------------===//
6760
6761 /// SS42I_binop_rm_int - Simple SSE 4.2 binary operator
6762 multiclass SS42I_binop_rm_int<bits<8> opc, string OpcodeStr,
6763                               Intrinsic IntId128, bit Is2Addr = 1> {
6764   def rr : SS428I<opc, MRMSrcReg, (outs VR128:$dst),
6765        (ins VR128:$src1, VR128:$src2),
6766        !if(Is2Addr,
6767            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
6768            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
6769        [(set VR128:$dst, (IntId128 VR128:$src1, VR128:$src2))]>,
6770        OpSize;
6771   def rm : SS428I<opc, MRMSrcMem, (outs VR128:$dst),
6772        (ins VR128:$src1, i128mem:$src2),
6773        !if(Is2Addr,
6774            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
6775            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
6776        [(set VR128:$dst,
6777          (IntId128 VR128:$src1, (memopv2i64 addr:$src2)))]>, OpSize;
6778 }
6779
6780 /// SS42I_binop_rm_int - Simple SSE 4.2 binary operator
6781 multiclass SS42I_binop_rm_int_y<bits<8> opc, string OpcodeStr,
6782                                 Intrinsic IntId256> {
6783   def Yrr : SS428I<opc, MRMSrcReg, (outs VR256:$dst),
6784        (ins VR256:$src1, VR256:$src2),
6785        !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6786        [(set VR256:$dst, (IntId256 VR256:$src1, VR256:$src2))]>,
6787        OpSize;
6788   def Yrm : SS428I<opc, MRMSrcMem, (outs VR256:$dst),
6789        (ins VR256:$src1, i256mem:$src2),
6790        !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6791        [(set VR256:$dst,
6792          (IntId256 VR256:$src1, (memopv4i64 addr:$src2)))]>, OpSize;
6793 }
6794
6795 let Predicates = [HasAVX] in {
6796   defm VPCMPGTQ : SS42I_binop_rm_int<0x37, "vpcmpgtq", int_x86_sse42_pcmpgtq,
6797                                      0>, VEX_4V;
6798
6799   def : Pat<(v2i64 (X86pcmpgtq VR128:$src1, VR128:$src2)),
6800             (VPCMPGTQrr VR128:$src1, VR128:$src2)>;
6801   def : Pat<(v2i64 (X86pcmpgtq VR128:$src1, (memop addr:$src2))),
6802             (VPCMPGTQrm VR128:$src1, addr:$src2)>;
6803 }
6804
6805 let Predicates = [HasAVX2] in {
6806   defm VPCMPGTQ : SS42I_binop_rm_int_y<0x37, "vpcmpgtq", int_x86_avx2_pcmpgt_q>,
6807                                        VEX_4V;
6808
6809   def : Pat<(v4i64 (X86pcmpgtq VR256:$src1, VR256:$src2)),
6810             (VPCMPGTQYrr VR256:$src1, VR256:$src2)>;
6811   def : Pat<(v4i64 (X86pcmpgtq VR256:$src1, (memop addr:$src2))),
6812             (VPCMPGTQYrm VR256:$src1, addr:$src2)>;
6813 }
6814
6815 let Constraints = "$src1 = $dst" in
6816   defm PCMPGTQ : SS42I_binop_rm_int<0x37, "pcmpgtq", int_x86_sse42_pcmpgtq>;
6817
6818 let Predicates = [HasSSE42] in {
6819   def : Pat<(v2i64 (X86pcmpgtq VR128:$src1, VR128:$src2)),
6820             (PCMPGTQrr VR128:$src1, VR128:$src2)>;
6821   def : Pat<(v2i64 (X86pcmpgtq VR128:$src1, (memop addr:$src2))),
6822             (PCMPGTQrm VR128:$src1, addr:$src2)>;
6823 }
6824
6825 //===----------------------------------------------------------------------===//
6826 // SSE4.2 - String/text Processing Instructions
6827 //===----------------------------------------------------------------------===//
6828
6829 // Packed Compare Implicit Length Strings, Return Mask
6830 multiclass pseudo_pcmpistrm<string asm> {
6831   def REG : PseudoI<(outs VR128:$dst),
6832                     (ins VR128:$src1, VR128:$src2, i8imm:$src3),
6833     [(set VR128:$dst, (int_x86_sse42_pcmpistrm128 VR128:$src1, VR128:$src2,
6834                                                   imm:$src3))]>;
6835   def MEM : PseudoI<(outs VR128:$dst),
6836                     (ins VR128:$src1, i128mem:$src2, i8imm:$src3),
6837     [(set VR128:$dst, (int_x86_sse42_pcmpistrm128
6838                        VR128:$src1, (load addr:$src2), imm:$src3))]>;
6839 }
6840
6841 let Defs = [EFLAGS], usesCustomInserter = 1 in {
6842   defm PCMPISTRM128 : pseudo_pcmpistrm<"#PCMPISTRM128">, Requires<[HasSSE42]>;
6843   defm VPCMPISTRM128 : pseudo_pcmpistrm<"#VPCMPISTRM128">, Requires<[HasAVX]>;
6844 }
6845
6846 let Defs = [XMM0, EFLAGS], neverHasSideEffects = 1, Predicates = [HasAVX] in {
6847   def VPCMPISTRM128rr : SS42AI<0x62, MRMSrcReg, (outs),
6848       (ins VR128:$src1, VR128:$src2, i8imm:$src3),
6849       "vpcmpistrm\t{$src3, $src2, $src1|$src1, $src2, $src3}", []>, OpSize, VEX;
6850   let mayLoad = 1 in
6851   def VPCMPISTRM128rm : SS42AI<0x62, MRMSrcMem, (outs),
6852       (ins VR128:$src1, i128mem:$src2, i8imm:$src3),
6853       "vpcmpistrm\t{$src3, $src2, $src1|$src1, $src2, $src3}", []>, OpSize, VEX;
6854 }
6855
6856 let Defs = [XMM0, EFLAGS], neverHasSideEffects = 1 in {
6857   def PCMPISTRM128rr : SS42AI<0x62, MRMSrcReg, (outs),
6858       (ins VR128:$src1, VR128:$src2, i8imm:$src3),
6859       "pcmpistrm\t{$src3, $src2, $src1|$src1, $src2, $src3}", []>, OpSize;
6860   let mayLoad = 1 in
6861   def PCMPISTRM128rm : SS42AI<0x62, MRMSrcMem, (outs),
6862       (ins VR128:$src1, i128mem:$src2, i8imm:$src3),
6863       "pcmpistrm\t{$src3, $src2, $src1|$src1, $src2, $src3}", []>, OpSize;
6864 }
6865
6866 // Packed Compare Explicit Length Strings, Return Mask
6867 multiclass pseudo_pcmpestrm<string asm> {
6868   def REG : PseudoI<(outs VR128:$dst),
6869                     (ins VR128:$src1, VR128:$src3, i8imm:$src5),
6870     [(set VR128:$dst, (int_x86_sse42_pcmpestrm128
6871                        VR128:$src1, EAX, VR128:$src3, EDX, imm:$src5))]>;
6872   def MEM : PseudoI<(outs VR128:$dst),
6873                     (ins VR128:$src1, i128mem:$src3, i8imm:$src5),
6874     [(set VR128:$dst, (int_x86_sse42_pcmpestrm128
6875                        VR128:$src1, EAX, (load addr:$src3), EDX, imm:$src5))]>;
6876 }
6877
6878 let Defs = [EFLAGS], Uses = [EAX, EDX], usesCustomInserter = 1 in {
6879   defm PCMPESTRM128 : pseudo_pcmpestrm<"#PCMPESTRM128">, Requires<[HasSSE42]>;
6880   defm VPCMPESTRM128 : pseudo_pcmpestrm<"#VPCMPESTRM128">, Requires<[HasAVX]>;
6881 }
6882
6883 let Predicates = [HasAVX],
6884     Defs = [XMM0, EFLAGS], Uses = [EAX, EDX], neverHasSideEffects = 1 in {
6885   def VPCMPESTRM128rr : SS42AI<0x60, MRMSrcReg, (outs),
6886       (ins VR128:$src1, VR128:$src3, i8imm:$src5),
6887       "vpcmpestrm\t{$src5, $src3, $src1|$src1, $src3, $src5}", []>, OpSize, VEX;
6888   let mayLoad = 1 in
6889   def VPCMPESTRM128rm : SS42AI<0x60, MRMSrcMem, (outs),
6890       (ins VR128:$src1, i128mem:$src3, i8imm:$src5),
6891       "vpcmpestrm\t{$src5, $src3, $src1|$src1, $src3, $src5}", []>, OpSize, VEX;
6892 }
6893
6894 let Defs = [XMM0, EFLAGS], Uses = [EAX, EDX], neverHasSideEffects = 1 in {
6895   def PCMPESTRM128rr : SS42AI<0x60, MRMSrcReg, (outs),
6896       (ins VR128:$src1, VR128:$src3, i8imm:$src5),
6897       "pcmpestrm\t{$src5, $src3, $src1|$src1, $src3, $src5}", []>, OpSize;
6898   let mayLoad = 1 in
6899   def PCMPESTRM128rm : SS42AI<0x60, MRMSrcMem, (outs),
6900       (ins VR128:$src1, i128mem:$src3, i8imm:$src5),
6901       "pcmpestrm\t{$src5, $src3, $src1|$src1, $src3, $src5}", []>, OpSize;
6902 }
6903
6904 // Packed Compare Implicit Length Strings, Return Index
6905 let Defs = [ECX, EFLAGS] in {
6906   multiclass SS42AI_pcmpistri<Intrinsic IntId128, string asm = "pcmpistri"> {
6907     def rr : SS42AI<0x63, MRMSrcReg, (outs),
6908       (ins VR128:$src1, VR128:$src2, i8imm:$src3),
6909       !strconcat(asm, "\t{$src3, $src2, $src1|$src1, $src2, $src3}"),
6910       [(set ECX, (IntId128 VR128:$src1, VR128:$src2, imm:$src3)),
6911        (implicit EFLAGS)]>, OpSize;
6912     def rm : SS42AI<0x63, MRMSrcMem, (outs),
6913       (ins VR128:$src1, i128mem:$src2, i8imm:$src3),
6914       !strconcat(asm, "\t{$src3, $src2, $src1|$src1, $src2, $src3}"),
6915       [(set ECX, (IntId128 VR128:$src1, (load addr:$src2), imm:$src3)),
6916        (implicit EFLAGS)]>, OpSize;
6917   }
6918 }
6919
6920 let Predicates = [HasAVX] in {
6921 defm VPCMPISTRI  : SS42AI_pcmpistri<int_x86_sse42_pcmpistri128, "vpcmpistri">,
6922                                     VEX;
6923 defm VPCMPISTRIA : SS42AI_pcmpistri<int_x86_sse42_pcmpistria128, "vpcmpistri">,
6924                                     VEX;
6925 defm VPCMPISTRIC : SS42AI_pcmpistri<int_x86_sse42_pcmpistric128, "vpcmpistri">,
6926                                     VEX;
6927 defm VPCMPISTRIO : SS42AI_pcmpistri<int_x86_sse42_pcmpistrio128, "vpcmpistri">,
6928                                     VEX;
6929 defm VPCMPISTRIS : SS42AI_pcmpistri<int_x86_sse42_pcmpistris128, "vpcmpistri">,
6930                                     VEX;
6931 defm VPCMPISTRIZ : SS42AI_pcmpistri<int_x86_sse42_pcmpistriz128, "vpcmpistri">,
6932                                     VEX;
6933 }
6934
6935 defm PCMPISTRI  : SS42AI_pcmpistri<int_x86_sse42_pcmpistri128>;
6936 defm PCMPISTRIA : SS42AI_pcmpistri<int_x86_sse42_pcmpistria128>;
6937 defm PCMPISTRIC : SS42AI_pcmpistri<int_x86_sse42_pcmpistric128>;
6938 defm PCMPISTRIO : SS42AI_pcmpistri<int_x86_sse42_pcmpistrio128>;
6939 defm PCMPISTRIS : SS42AI_pcmpistri<int_x86_sse42_pcmpistris128>;
6940 defm PCMPISTRIZ : SS42AI_pcmpistri<int_x86_sse42_pcmpistriz128>;
6941
6942 // Packed Compare Explicit Length Strings, Return Index
6943 let Defs = [ECX, EFLAGS], Uses = [EAX, EDX] in {
6944   multiclass SS42AI_pcmpestri<Intrinsic IntId128, string asm = "pcmpestri"> {
6945     def rr : SS42AI<0x61, MRMSrcReg, (outs),
6946       (ins VR128:$src1, VR128:$src3, i8imm:$src5),
6947       !strconcat(asm, "\t{$src5, $src3, $src1|$src1, $src3, $src5}"),
6948       [(set ECX, (IntId128 VR128:$src1, EAX, VR128:$src3, EDX, imm:$src5)),
6949        (implicit EFLAGS)]>, OpSize;
6950     def rm : SS42AI<0x61, MRMSrcMem, (outs),
6951       (ins VR128:$src1, i128mem:$src3, i8imm:$src5),
6952       !strconcat(asm, "\t{$src5, $src3, $src1|$src1, $src3, $src5}"),
6953        [(set ECX,
6954              (IntId128 VR128:$src1, EAX, (load addr:$src3), EDX, imm:$src5)),
6955         (implicit EFLAGS)]>, OpSize;
6956   }
6957 }
6958
6959 let Predicates = [HasAVX] in {
6960 defm VPCMPESTRI  : SS42AI_pcmpestri<int_x86_sse42_pcmpestri128, "vpcmpestri">,
6961                                     VEX;
6962 defm VPCMPESTRIA : SS42AI_pcmpestri<int_x86_sse42_pcmpestria128, "vpcmpestri">,
6963                                     VEX;
6964 defm VPCMPESTRIC : SS42AI_pcmpestri<int_x86_sse42_pcmpestric128, "vpcmpestri">,
6965                                     VEX;
6966 defm VPCMPESTRIO : SS42AI_pcmpestri<int_x86_sse42_pcmpestrio128, "vpcmpestri">,
6967                                     VEX;
6968 defm VPCMPESTRIS : SS42AI_pcmpestri<int_x86_sse42_pcmpestris128, "vpcmpestri">,
6969                                     VEX;
6970 defm VPCMPESTRIZ : SS42AI_pcmpestri<int_x86_sse42_pcmpestriz128, "vpcmpestri">,
6971                                     VEX;
6972 }
6973
6974 defm PCMPESTRI  : SS42AI_pcmpestri<int_x86_sse42_pcmpestri128>;
6975 defm PCMPESTRIA : SS42AI_pcmpestri<int_x86_sse42_pcmpestria128>;
6976 defm PCMPESTRIC : SS42AI_pcmpestri<int_x86_sse42_pcmpestric128>;
6977 defm PCMPESTRIO : SS42AI_pcmpestri<int_x86_sse42_pcmpestrio128>;
6978 defm PCMPESTRIS : SS42AI_pcmpestri<int_x86_sse42_pcmpestris128>;
6979 defm PCMPESTRIZ : SS42AI_pcmpestri<int_x86_sse42_pcmpestriz128>;
6980
6981 //===----------------------------------------------------------------------===//
6982 // SSE4.2 - CRC Instructions
6983 //===----------------------------------------------------------------------===//
6984
6985 // No CRC instructions have AVX equivalents
6986
6987 // crc intrinsic instruction
6988 // This set of instructions are only rm, the only difference is the size
6989 // of r and m.
6990 let Constraints = "$src1 = $dst" in {
6991   def CRC32r32m8  : SS42FI<0xF0, MRMSrcMem, (outs GR32:$dst),
6992                       (ins GR32:$src1, i8mem:$src2),
6993                       "crc32{b} \t{$src2, $src1|$src1, $src2}",
6994                        [(set GR32:$dst,
6995                          (int_x86_sse42_crc32_32_8 GR32:$src1,
6996                          (load addr:$src2)))]>;
6997   def CRC32r32r8  : SS42FI<0xF0, MRMSrcReg, (outs GR32:$dst),
6998                       (ins GR32:$src1, GR8:$src2),
6999                       "crc32{b} \t{$src2, $src1|$src1, $src2}",
7000                        [(set GR32:$dst,
7001                          (int_x86_sse42_crc32_32_8 GR32:$src1, GR8:$src2))]>;
7002   def CRC32r32m16  : SS42FI<0xF1, MRMSrcMem, (outs GR32:$dst),
7003                       (ins GR32:$src1, i16mem:$src2),
7004                       "crc32{w} \t{$src2, $src1|$src1, $src2}",
7005                        [(set GR32:$dst,
7006                          (int_x86_sse42_crc32_32_16 GR32:$src1,
7007                          (load addr:$src2)))]>,
7008                          OpSize;
7009   def CRC32r32r16  : SS42FI<0xF1, MRMSrcReg, (outs GR32:$dst),
7010                       (ins GR32:$src1, GR16:$src2),
7011                       "crc32{w} \t{$src2, $src1|$src1, $src2}",
7012                        [(set GR32:$dst,
7013                          (int_x86_sse42_crc32_32_16 GR32:$src1, GR16:$src2))]>,
7014                          OpSize;
7015   def CRC32r32m32  : SS42FI<0xF1, MRMSrcMem, (outs GR32:$dst),
7016                       (ins GR32:$src1, i32mem:$src2),
7017                       "crc32{l} \t{$src2, $src1|$src1, $src2}",
7018                        [(set GR32:$dst,
7019                          (int_x86_sse42_crc32_32_32 GR32:$src1,
7020                          (load addr:$src2)))]>;
7021   def CRC32r32r32  : SS42FI<0xF1, MRMSrcReg, (outs GR32:$dst),
7022                       (ins GR32:$src1, GR32:$src2),
7023                       "crc32{l} \t{$src2, $src1|$src1, $src2}",
7024                        [(set GR32:$dst,
7025                          (int_x86_sse42_crc32_32_32 GR32:$src1, GR32:$src2))]>;
7026   def CRC32r64m8  : SS42FI<0xF0, MRMSrcMem, (outs GR64:$dst),
7027                       (ins GR64:$src1, i8mem:$src2),
7028                       "crc32{b} \t{$src2, $src1|$src1, $src2}",
7029                        [(set GR64:$dst,
7030                          (int_x86_sse42_crc32_64_8 GR64:$src1,
7031                          (load addr:$src2)))]>,
7032                          REX_W;
7033   def CRC32r64r8  : SS42FI<0xF0, MRMSrcReg, (outs GR64:$dst),
7034                       (ins GR64:$src1, GR8:$src2),
7035                       "crc32{b} \t{$src2, $src1|$src1, $src2}",
7036                        [(set GR64:$dst,
7037                          (int_x86_sse42_crc32_64_8 GR64:$src1, GR8:$src2))]>,
7038                          REX_W;
7039   def CRC32r64m64  : SS42FI<0xF1, MRMSrcMem, (outs GR64:$dst),
7040                       (ins GR64:$src1, i64mem:$src2),
7041                       "crc32{q} \t{$src2, $src1|$src1, $src2}",
7042                        [(set GR64:$dst,
7043                          (int_x86_sse42_crc32_64_64 GR64:$src1,
7044                          (load addr:$src2)))]>,
7045                          REX_W;
7046   def CRC32r64r64  : SS42FI<0xF1, MRMSrcReg, (outs GR64:$dst),
7047                       (ins GR64:$src1, GR64:$src2),
7048                       "crc32{q} \t{$src2, $src1|$src1, $src2}",
7049                        [(set GR64:$dst,
7050                          (int_x86_sse42_crc32_64_64 GR64:$src1, GR64:$src2))]>,
7051                          REX_W;
7052 }
7053
7054 //===----------------------------------------------------------------------===//
7055 // AES-NI Instructions
7056 //===----------------------------------------------------------------------===//
7057
7058 multiclass AESI_binop_rm_int<bits<8> opc, string OpcodeStr,
7059                               Intrinsic IntId128, bit Is2Addr = 1> {
7060   def rr : AES8I<opc, MRMSrcReg, (outs VR128:$dst),
7061        (ins VR128:$src1, VR128:$src2),
7062        !if(Is2Addr,
7063            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
7064            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
7065        [(set VR128:$dst, (IntId128 VR128:$src1, VR128:$src2))]>,
7066        OpSize;
7067   def rm : AES8I<opc, MRMSrcMem, (outs VR128:$dst),
7068        (ins VR128:$src1, i128mem:$src2),
7069        !if(Is2Addr,
7070            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
7071            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
7072        [(set VR128:$dst,
7073          (IntId128 VR128:$src1, (memopv2i64 addr:$src2)))]>, OpSize;
7074 }
7075
7076 // Perform One Round of an AES Encryption/Decryption Flow
7077 let Predicates = [HasAVX, HasAES] in {
7078   defm VAESENC          : AESI_binop_rm_int<0xDC, "vaesenc",
7079                          int_x86_aesni_aesenc, 0>, VEX_4V;
7080   defm VAESENCLAST      : AESI_binop_rm_int<0xDD, "vaesenclast",
7081                          int_x86_aesni_aesenclast, 0>, VEX_4V;
7082   defm VAESDEC          : AESI_binop_rm_int<0xDE, "vaesdec",
7083                          int_x86_aesni_aesdec, 0>, VEX_4V;
7084   defm VAESDECLAST      : AESI_binop_rm_int<0xDF, "vaesdeclast",
7085                          int_x86_aesni_aesdeclast, 0>, VEX_4V;
7086 }
7087
7088 let Constraints = "$src1 = $dst" in {
7089   defm AESENC          : AESI_binop_rm_int<0xDC, "aesenc",
7090                          int_x86_aesni_aesenc>;
7091   defm AESENCLAST      : AESI_binop_rm_int<0xDD, "aesenclast",
7092                          int_x86_aesni_aesenclast>;
7093   defm AESDEC          : AESI_binop_rm_int<0xDE, "aesdec",
7094                          int_x86_aesni_aesdec>;
7095   defm AESDECLAST      : AESI_binop_rm_int<0xDF, "aesdeclast",
7096                          int_x86_aesni_aesdeclast>;
7097 }
7098
7099 // Perform the AES InvMixColumn Transformation
7100 let Predicates = [HasAVX, HasAES] in {
7101   def VAESIMCrr : AES8I<0xDB, MRMSrcReg, (outs VR128:$dst),
7102       (ins VR128:$src1),
7103       "vaesimc\t{$src1, $dst|$dst, $src1}",
7104       [(set VR128:$dst,
7105         (int_x86_aesni_aesimc VR128:$src1))]>,
7106       OpSize, VEX;
7107   def VAESIMCrm : AES8I<0xDB, MRMSrcMem, (outs VR128:$dst),
7108       (ins i128mem:$src1),
7109       "vaesimc\t{$src1, $dst|$dst, $src1}",
7110       [(set VR128:$dst, (int_x86_aesni_aesimc (memopv2i64 addr:$src1)))]>,
7111       OpSize, VEX;
7112 }
7113 def AESIMCrr : AES8I<0xDB, MRMSrcReg, (outs VR128:$dst),
7114   (ins VR128:$src1),
7115   "aesimc\t{$src1, $dst|$dst, $src1}",
7116   [(set VR128:$dst,
7117     (int_x86_aesni_aesimc VR128:$src1))]>,
7118   OpSize;
7119 def AESIMCrm : AES8I<0xDB, MRMSrcMem, (outs VR128:$dst),
7120   (ins i128mem:$src1),
7121   "aesimc\t{$src1, $dst|$dst, $src1}",
7122   [(set VR128:$dst, (int_x86_aesni_aesimc (memopv2i64 addr:$src1)))]>,
7123   OpSize;
7124
7125 // AES Round Key Generation Assist
7126 let Predicates = [HasAVX, HasAES] in {
7127   def VAESKEYGENASSIST128rr : AESAI<0xDF, MRMSrcReg, (outs VR128:$dst),
7128       (ins VR128:$src1, i8imm:$src2),
7129       "vaeskeygenassist\t{$src2, $src1, $dst|$dst, $src1, $src2}",
7130       [(set VR128:$dst,
7131         (int_x86_aesni_aeskeygenassist VR128:$src1, imm:$src2))]>,
7132       OpSize, VEX;
7133   def VAESKEYGENASSIST128rm : AESAI<0xDF, MRMSrcMem, (outs VR128:$dst),
7134       (ins i128mem:$src1, i8imm:$src2),
7135       "vaeskeygenassist\t{$src2, $src1, $dst|$dst, $src1, $src2}",
7136       [(set VR128:$dst,
7137         (int_x86_aesni_aeskeygenassist (memopv2i64 addr:$src1), imm:$src2))]>,
7138       OpSize, VEX;
7139 }
7140 def AESKEYGENASSIST128rr : AESAI<0xDF, MRMSrcReg, (outs VR128:$dst),
7141   (ins VR128:$src1, i8imm:$src2),
7142   "aeskeygenassist\t{$src2, $src1, $dst|$dst, $src1, $src2}",
7143   [(set VR128:$dst,
7144     (int_x86_aesni_aeskeygenassist VR128:$src1, imm:$src2))]>,
7145   OpSize;
7146 def AESKEYGENASSIST128rm : AESAI<0xDF, MRMSrcMem, (outs VR128:$dst),
7147   (ins i128mem:$src1, i8imm:$src2),
7148   "aeskeygenassist\t{$src2, $src1, $dst|$dst, $src1, $src2}",
7149   [(set VR128:$dst,
7150     (int_x86_aesni_aeskeygenassist (memopv2i64 addr:$src1), imm:$src2))]>,
7151   OpSize;
7152
7153 //===----------------------------------------------------------------------===//
7154 // CLMUL Instructions
7155 //===----------------------------------------------------------------------===//
7156
7157 // Carry-less Multiplication instructions
7158 let neverHasSideEffects = 1 in {
7159 // AVX carry-less Multiplication instructions
7160 def VPCLMULQDQrr : AVXCLMULIi8<0x44, MRMSrcReg, (outs VR128:$dst),
7161            (ins VR128:$src1, VR128:$src2, i8imm:$src3),
7162            "vpclmulqdq\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
7163            []>;
7164
7165 let mayLoad = 1 in
7166 def VPCLMULQDQrm : AVXCLMULIi8<0x44, MRMSrcMem, (outs VR128:$dst),
7167            (ins VR128:$src1, i128mem:$src2, i8imm:$src3),
7168            "vpclmulqdq\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
7169            []>;
7170
7171 let Constraints = "$src1 = $dst" in {
7172 def PCLMULQDQrr : CLMULIi8<0x44, MRMSrcReg, (outs VR128:$dst),
7173            (ins VR128:$src1, VR128:$src2, i8imm:$src3),
7174            "pclmulqdq\t{$src3, $src2, $dst|$dst, $src2, $src3}",
7175            []>;
7176
7177 let mayLoad = 1 in
7178 def PCLMULQDQrm : CLMULIi8<0x44, MRMSrcMem, (outs VR128:$dst),
7179            (ins VR128:$src1, i128mem:$src2, i8imm:$src3),
7180            "pclmulqdq\t{$src3, $src2, $dst|$dst, $src2, $src3}",
7181            []>;
7182 } // Constraints = "$src1 = $dst"
7183 } // neverHasSideEffects = 1
7184
7185
7186 multiclass pclmul_alias<string asm, int immop> {
7187   def : InstAlias<!strconcat("pclmul", asm, 
7188                            "dq {$src, $dst|$dst, $src}"),
7189                   (PCLMULQDQrr VR128:$dst, VR128:$src, immop)>;
7190
7191   def : InstAlias<!strconcat("pclmul", asm, 
7192                              "dq {$src, $dst|$dst, $src}"),
7193                   (PCLMULQDQrm VR128:$dst, i128mem:$src, immop)>;
7194
7195   def : InstAlias<!strconcat("vpclmul", asm, 
7196                              "dq {$src2, $src1, $dst|$dst, $src1, $src2}"),
7197                   (VPCLMULQDQrr VR128:$dst, VR128:$src1, VR128:$src2, immop)>;
7198
7199   def : InstAlias<!strconcat("vpclmul", asm, 
7200                              "dq {$src2, $src1, $dst|$dst, $src1, $src2}"),
7201                   (VPCLMULQDQrm VR128:$dst, VR128:$src1, i128mem:$src2, immop)>;
7202 }
7203 defm : pclmul_alias<"hqhq", 0x11>;
7204 defm : pclmul_alias<"hqlq", 0x01>;
7205 defm : pclmul_alias<"lqhq", 0x10>;
7206 defm : pclmul_alias<"lqlq", 0x00>;
7207
7208 //===----------------------------------------------------------------------===//
7209 // AVX Instructions
7210 //===----------------------------------------------------------------------===//
7211
7212 //===----------------------------------------------------------------------===//
7213 // VBROADCAST - Load from memory and broadcast to all elements of the
7214 //              destination operand
7215 //
7216 class avx_broadcast<bits<8> opc, string OpcodeStr, RegisterClass RC,
7217                     X86MemOperand x86memop, Intrinsic Int> :
7218   AVX8I<opc, MRMSrcMem, (outs RC:$dst), (ins x86memop:$src),
7219         !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
7220         [(set RC:$dst, (Int addr:$src))]>, VEX;
7221
7222 // AVX2 adds register forms
7223 class avx2_broadcast_reg<bits<8> opc, string OpcodeStr, RegisterClass RC,
7224                          Intrinsic Int> :
7225   AVX28I<opc, MRMSrcReg, (outs RC:$dst), (ins VR128:$src),
7226          !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
7227          [(set RC:$dst, (Int VR128:$src))]>, VEX;
7228
7229 let ExeDomain = SSEPackedSingle in {
7230   def VBROADCASTSSrm  : avx_broadcast<0x18, "vbroadcastss", VR128, f32mem,
7231                                       int_x86_avx_vbroadcast_ss>;
7232   def VBROADCASTSSYrm : avx_broadcast<0x18, "vbroadcastss", VR256, f32mem,
7233                                       int_x86_avx_vbroadcast_ss_256>;
7234 }
7235 let ExeDomain = SSEPackedDouble in
7236 def VBROADCASTSDrm  : avx_broadcast<0x19, "vbroadcastsd", VR256, f64mem,
7237                                     int_x86_avx_vbroadcast_sd_256>;
7238 def VBROADCASTF128 : avx_broadcast<0x1A, "vbroadcastf128", VR256, f128mem,
7239                                    int_x86_avx_vbroadcastf128_pd_256>;
7240
7241 let ExeDomain = SSEPackedSingle in {
7242   def VBROADCASTSSrr  : avx2_broadcast_reg<0x18, "vbroadcastss", VR128,
7243                                            int_x86_avx2_vbroadcast_ss_ps>;
7244   def VBROADCASTSSYrr : avx2_broadcast_reg<0x18, "vbroadcastss", VR256,
7245                                            int_x86_avx2_vbroadcast_ss_ps_256>;
7246 }
7247 let ExeDomain = SSEPackedDouble in
7248 def VBROADCASTSDrr  : avx2_broadcast_reg<0x19, "vbroadcastsd", VR256,
7249                                          int_x86_avx2_vbroadcast_sd_pd_256>;
7250
7251 let Predicates = [HasAVX2] in
7252 def VBROADCASTI128 : avx_broadcast<0x5A, "vbroadcasti128", VR256, i128mem,
7253                                    int_x86_avx2_vbroadcasti128>;
7254
7255 let Predicates = [HasAVX] in
7256 def : Pat<(int_x86_avx_vbroadcastf128_ps_256 addr:$src),
7257           (VBROADCASTF128 addr:$src)>;
7258
7259
7260 //===----------------------------------------------------------------------===//
7261 // VINSERTF128 - Insert packed floating-point values
7262 //
7263 let neverHasSideEffects = 1, ExeDomain = SSEPackedSingle in {
7264 def VINSERTF128rr : AVXAIi8<0x18, MRMSrcReg, (outs VR256:$dst),
7265           (ins VR256:$src1, VR128:$src2, i8imm:$src3),
7266           "vinsertf128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
7267           []>, VEX_4V;
7268 let mayLoad = 1 in
7269 def VINSERTF128rm : AVXAIi8<0x18, MRMSrcMem, (outs VR256:$dst),
7270           (ins VR256:$src1, f128mem:$src2, i8imm:$src3),
7271           "vinsertf128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
7272           []>, VEX_4V;
7273 }
7274
7275 let Predicates = [HasAVX] in {
7276 def : Pat<(int_x86_avx_vinsertf128_pd_256 VR256:$src1, VR128:$src2, imm:$src3),
7277           (VINSERTF128rr VR256:$src1, VR128:$src2, imm:$src3)>;
7278 def : Pat<(int_x86_avx_vinsertf128_ps_256 VR256:$src1, VR128:$src2, imm:$src3),
7279           (VINSERTF128rr VR256:$src1, VR128:$src2, imm:$src3)>;
7280 def : Pat<(int_x86_avx_vinsertf128_si_256 VR256:$src1, VR128:$src2, imm:$src3),
7281           (VINSERTF128rr VR256:$src1, VR128:$src2, imm:$src3)>;
7282 }
7283
7284 //===----------------------------------------------------------------------===//
7285 // VEXTRACTF128 - Extract packed floating-point values
7286 //
7287 let neverHasSideEffects = 1, ExeDomain = SSEPackedSingle in {
7288 def VEXTRACTF128rr : AVXAIi8<0x19, MRMDestReg, (outs VR128:$dst),
7289           (ins VR256:$src1, i8imm:$src2),
7290           "vextractf128\t{$src2, $src1, $dst|$dst, $src1, $src2}",
7291           []>, VEX;
7292 let mayStore = 1 in
7293 def VEXTRACTF128mr : AVXAIi8<0x19, MRMDestMem, (outs),
7294           (ins f128mem:$dst, VR256:$src1, i8imm:$src2),
7295           "vextractf128\t{$src2, $src1, $dst|$dst, $src1, $src2}",
7296           []>, VEX;
7297 }
7298
7299 let Predicates = [HasAVX] in {
7300 def : Pat<(int_x86_avx_vextractf128_pd_256 VR256:$src1, imm:$src2),
7301           (VEXTRACTF128rr VR256:$src1, imm:$src2)>;
7302 def : Pat<(int_x86_avx_vextractf128_ps_256 VR256:$src1, imm:$src2),
7303           (VEXTRACTF128rr VR256:$src1, imm:$src2)>;
7304 def : Pat<(int_x86_avx_vextractf128_si_256 VR256:$src1, imm:$src2),
7305           (VEXTRACTF128rr VR256:$src1, imm:$src2)>;
7306 }
7307
7308 //===----------------------------------------------------------------------===//
7309 // VMASKMOV - Conditional SIMD Packed Loads and Stores
7310 //
7311 multiclass avx_movmask_rm<bits<8> opc_rm, bits<8> opc_mr, string OpcodeStr,
7312                           Intrinsic IntLd, Intrinsic IntLd256,
7313                           Intrinsic IntSt, Intrinsic IntSt256> {
7314   def rm  : AVX8I<opc_rm, MRMSrcMem, (outs VR128:$dst),
7315              (ins VR128:$src1, f128mem:$src2),
7316              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7317              [(set VR128:$dst, (IntLd addr:$src2, VR128:$src1))]>,
7318              VEX_4V;
7319   def Yrm : AVX8I<opc_rm, MRMSrcMem, (outs VR256:$dst),
7320              (ins VR256:$src1, f256mem:$src2),
7321              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7322              [(set VR256:$dst, (IntLd256 addr:$src2, VR256:$src1))]>,
7323              VEX_4V;
7324   def mr  : AVX8I<opc_mr, MRMDestMem, (outs),
7325              (ins f128mem:$dst, VR128:$src1, VR128:$src2),
7326              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7327              [(IntSt addr:$dst, VR128:$src1, VR128:$src2)]>, VEX_4V;
7328   def Ymr : AVX8I<opc_mr, MRMDestMem, (outs),
7329              (ins f256mem:$dst, VR256:$src1, VR256:$src2),
7330              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7331              [(IntSt256 addr:$dst, VR256:$src1, VR256:$src2)]>, VEX_4V;
7332 }
7333
7334 let ExeDomain = SSEPackedSingle in
7335 defm VMASKMOVPS : avx_movmask_rm<0x2C, 0x2E, "vmaskmovps",
7336                                  int_x86_avx_maskload_ps,
7337                                  int_x86_avx_maskload_ps_256,
7338                                  int_x86_avx_maskstore_ps,
7339                                  int_x86_avx_maskstore_ps_256>;
7340 let ExeDomain = SSEPackedDouble in
7341 defm VMASKMOVPD : avx_movmask_rm<0x2D, 0x2F, "vmaskmovpd",
7342                                  int_x86_avx_maskload_pd,
7343                                  int_x86_avx_maskload_pd_256,
7344                                  int_x86_avx_maskstore_pd,
7345                                  int_x86_avx_maskstore_pd_256>;
7346
7347 //===----------------------------------------------------------------------===//
7348 // VPERMIL - Permute Single and Double Floating-Point Values
7349 //
7350 multiclass avx_permil<bits<8> opc_rm, bits<8> opc_rmi, string OpcodeStr,
7351                       RegisterClass RC, X86MemOperand x86memop_f,
7352                       X86MemOperand x86memop_i, PatFrag f_frag, PatFrag i_frag,
7353                       Intrinsic IntVar, Intrinsic IntImm> {
7354   def rr  : AVX8I<opc_rm, MRMSrcReg, (outs RC:$dst),
7355              (ins RC:$src1, RC:$src2),
7356              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7357              [(set RC:$dst, (IntVar RC:$src1, RC:$src2))]>, VEX_4V;
7358   def rm  : AVX8I<opc_rm, MRMSrcMem, (outs RC:$dst),
7359              (ins RC:$src1, x86memop_i:$src2),
7360              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7361              [(set RC:$dst, (IntVar RC:$src1,
7362                              (bitconvert (i_frag addr:$src2))))]>, VEX_4V;
7363
7364   def ri  : AVXAIi8<opc_rmi, MRMSrcReg, (outs RC:$dst),
7365              (ins RC:$src1, i8imm:$src2),
7366              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7367              [(set RC:$dst, (IntImm RC:$src1, imm:$src2))]>, VEX;
7368   def mi  : AVXAIi8<opc_rmi, MRMSrcMem, (outs RC:$dst),
7369              (ins x86memop_f:$src1, i8imm:$src2),
7370              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7371              [(set RC:$dst, (IntImm (f_frag addr:$src1), imm:$src2))]>, VEX;
7372 }
7373
7374 let ExeDomain = SSEPackedSingle in {
7375   defm VPERMILPS  : avx_permil<0x0C, 0x04, "vpermilps", VR128, f128mem, i128mem,
7376                                memopv4f32, memopv2i64,
7377                                int_x86_avx_vpermilvar_ps,
7378                                int_x86_avx_vpermil_ps>;
7379   defm VPERMILPSY : avx_permil<0x0C, 0x04, "vpermilps", VR256, f256mem, i256mem,
7380                                memopv8f32, memopv4i64,
7381                                int_x86_avx_vpermilvar_ps_256,
7382                                int_x86_avx_vpermil_ps_256>;
7383 }
7384 let ExeDomain = SSEPackedDouble in {
7385   defm VPERMILPD  : avx_permil<0x0D, 0x05, "vpermilpd", VR128, f128mem, i128mem,
7386                                memopv2f64, memopv2i64,
7387                                int_x86_avx_vpermilvar_pd,
7388                                int_x86_avx_vpermil_pd>;
7389   defm VPERMILPDY : avx_permil<0x0D, 0x05, "vpermilpd", VR256, f256mem, i256mem,
7390                                memopv4f64, memopv4i64,
7391                                int_x86_avx_vpermilvar_pd_256,
7392                                int_x86_avx_vpermil_pd_256>;
7393 }
7394
7395 let Predicates = [HasAVX] in {
7396 def : Pat<(v8f32 (X86VPermilp VR256:$src1, (i8 imm:$imm))),
7397           (VPERMILPSYri VR256:$src1, imm:$imm)>;
7398 def : Pat<(v4f64 (X86VPermilp VR256:$src1, (i8 imm:$imm))),
7399           (VPERMILPDYri VR256:$src1, imm:$imm)>;
7400 def : Pat<(v8i32 (X86VPermilp VR256:$src1, (i8 imm:$imm))),
7401           (VPERMILPSYri VR256:$src1, imm:$imm)>;
7402 def : Pat<(v4i64 (X86VPermilp VR256:$src1, (i8 imm:$imm))),
7403           (VPERMILPDYri VR256:$src1, imm:$imm)>;
7404 def : Pat<(v8f32 (X86VPermilp (memopv8f32 addr:$src1), (i8 imm:$imm))),
7405           (VPERMILPSYmi addr:$src1, imm:$imm)>;
7406 def : Pat<(v4f64 (X86VPermilp (memopv4f64 addr:$src1), (i8 imm:$imm))),
7407           (VPERMILPDYmi addr:$src1, imm:$imm)>;
7408 def : Pat<(v8i32 (X86VPermilp (bc_v8i32 (memopv4i64 addr:$src1)),
7409                                (i8 imm:$imm))),
7410           (VPERMILPSYmi addr:$src1, imm:$imm)>;
7411 def : Pat<(v4i64 (X86VPermilp (memopv4i64 addr:$src1), (i8 imm:$imm))),
7412           (VPERMILPDYmi addr:$src1, imm:$imm)>;
7413 }
7414
7415 //===----------------------------------------------------------------------===//
7416 // VPERM2F128 - Permute Floating-Point Values in 128-bit chunks
7417 //
7418 let neverHasSideEffects = 1, ExeDomain = SSEPackedSingle in {
7419 def VPERM2F128rr : AVXAIi8<0x06, MRMSrcReg, (outs VR256:$dst),
7420           (ins VR256:$src1, VR256:$src2, i8imm:$src3),
7421           "vperm2f128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
7422           []>, VEX_4V;
7423 let mayLoad = 1 in
7424 def VPERM2F128rm : AVXAIi8<0x06, MRMSrcMem, (outs VR256:$dst),
7425           (ins VR256:$src1, f256mem:$src2, i8imm:$src3),
7426           "vperm2f128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
7427           []>, VEX_4V;
7428 }
7429
7430 let Predicates = [HasAVX] in {
7431 def : Pat<(int_x86_avx_vperm2f128_ps_256 VR256:$src1, VR256:$src2, imm:$src3),
7432           (VPERM2F128rr VR256:$src1, VR256:$src2, imm:$src3)>;
7433 def : Pat<(int_x86_avx_vperm2f128_pd_256 VR256:$src1, VR256:$src2, imm:$src3),
7434           (VPERM2F128rr VR256:$src1, VR256:$src2, imm:$src3)>;
7435 def : Pat<(int_x86_avx_vperm2f128_si_256 VR256:$src1, VR256:$src2, imm:$src3),
7436           (VPERM2F128rr VR256:$src1, VR256:$src2, imm:$src3)>;
7437
7438 def : Pat<(int_x86_avx_vperm2f128_ps_256
7439                   VR256:$src1, (memopv8f32 addr:$src2), imm:$src3),
7440           (VPERM2F128rm VR256:$src1, addr:$src2, imm:$src3)>;
7441 def : Pat<(int_x86_avx_vperm2f128_pd_256
7442                   VR256:$src1, (memopv4f64 addr:$src2), imm:$src3),
7443           (VPERM2F128rm VR256:$src1, addr:$src2, imm:$src3)>;
7444 def : Pat<(int_x86_avx_vperm2f128_si_256
7445                   VR256:$src1, (bc_v8i32 (memopv4i64 addr:$src2)), imm:$src3),
7446           (VPERM2F128rm VR256:$src1, addr:$src2, imm:$src3)>;
7447 }
7448
7449 //===----------------------------------------------------------------------===//
7450 // VZERO - Zero YMM registers
7451 //
7452 let Defs = [YMM0, YMM1, YMM2, YMM3, YMM4, YMM5, YMM6, YMM7,
7453             YMM8, YMM9, YMM10, YMM11, YMM12, YMM13, YMM14, YMM15] in {
7454   // Zero All YMM registers
7455   def VZEROALL : I<0x77, RawFrm, (outs), (ins), "vzeroall",
7456                   [(int_x86_avx_vzeroall)]>, TB, VEX, VEX_L, Requires<[HasAVX]>;
7457
7458   // Zero Upper bits of YMM registers
7459   def VZEROUPPER : I<0x77, RawFrm, (outs), (ins), "vzeroupper",
7460                      [(int_x86_avx_vzeroupper)]>, TB, VEX, Requires<[HasAVX]>;
7461 }
7462
7463 //===----------------------------------------------------------------------===//
7464 // Half precision conversion instructions
7465 //===----------------------------------------------------------------------===//
7466 multiclass f16c_ph2ps<RegisterClass RC, X86MemOperand x86memop, Intrinsic Int> {
7467 let Predicates = [HasAVX, HasF16C] in {
7468   def rr : I<0x13, MRMSrcReg, (outs RC:$dst), (ins VR128:$src),
7469              "vcvtph2ps\t{$src, $dst|$dst, $src}",
7470              [(set RC:$dst, (Int VR128:$src))]>,
7471              T8, OpSize, VEX;
7472   let neverHasSideEffects = 1, mayLoad = 1 in
7473   def rm : I<0x13, MRMSrcMem, (outs RC:$dst), (ins x86memop:$src),
7474              "vcvtph2ps\t{$src, $dst|$dst, $src}", []>, T8, OpSize, VEX;
7475 }
7476 }
7477
7478 multiclass f16c_ps2ph<RegisterClass RC, X86MemOperand x86memop, Intrinsic Int> {
7479 let Predicates = [HasAVX, HasF16C] in {
7480   def rr : Ii8<0x1D, MRMDestReg, (outs VR128:$dst),
7481                (ins RC:$src1, i32i8imm:$src2),
7482                "vcvtps2ph\t{$src2, $src1, $dst|$dst, $src1, $src2}",
7483                [(set VR128:$dst, (Int RC:$src1, imm:$src2))]>,
7484                TA, OpSize, VEX;
7485   let neverHasSideEffects = 1, mayLoad = 1 in
7486   def mr : Ii8<0x1D, MRMDestMem, (outs x86memop:$dst),
7487                (ins RC:$src1, i32i8imm:$src2),
7488                "vcvtps2ph\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>,
7489                TA, OpSize, VEX;
7490 }
7491 }
7492
7493 defm VCVTPH2PS  : f16c_ph2ps<VR128, f64mem, int_x86_vcvtph2ps_128>;
7494 defm VCVTPH2PSY : f16c_ph2ps<VR256, f128mem, int_x86_vcvtph2ps_256>;
7495 defm VCVTPS2PH  : f16c_ps2ph<VR128, f64mem, int_x86_vcvtps2ph_128>;
7496 defm VCVTPS2PHY : f16c_ps2ph<VR256, f128mem, int_x86_vcvtps2ph_256>;
7497
7498 //===----------------------------------------------------------------------===//
7499 // AVX2 Instructions
7500 //===----------------------------------------------------------------------===//
7501
7502 /// AVX2_binop_rmi_int - AVX2 binary operator with 8-bit immediate
7503 multiclass AVX2_binop_rmi_int<bits<8> opc, string OpcodeStr,
7504                  Intrinsic IntId, RegisterClass RC, PatFrag memop_frag,
7505                  X86MemOperand x86memop> {
7506   let isCommutable = 1 in
7507   def rri : AVX2AIi8<opc, MRMSrcReg, (outs RC:$dst),
7508         (ins RC:$src1, RC:$src2, u32u8imm:$src3),
7509         !strconcat(OpcodeStr,
7510             "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
7511         [(set RC:$dst, (IntId RC:$src1, RC:$src2, imm:$src3))]>,
7512         VEX_4V;
7513   def rmi : AVX2AIi8<opc, MRMSrcMem, (outs RC:$dst),
7514         (ins RC:$src1, x86memop:$src2, u32u8imm:$src3),
7515         !strconcat(OpcodeStr,
7516             "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
7517         [(set RC:$dst,
7518           (IntId RC:$src1,
7519            (bitconvert (memop_frag addr:$src2)), imm:$src3))]>,
7520         VEX_4V;
7521 }
7522
7523 let isCommutable = 0 in {
7524 defm VPBLENDD : AVX2_binop_rmi_int<0x02, "vpblendd", int_x86_avx2_pblendd_128,
7525                                    VR128, memopv2i64, i128mem>;
7526 defm VPBLENDDY : AVX2_binop_rmi_int<0x02, "vpblendd", int_x86_avx2_pblendd_256,
7527                                     VR256, memopv4i64, i256mem>;
7528 }
7529
7530 //===----------------------------------------------------------------------===//
7531 // VPBROADCAST - Load from memory and broadcast to all elements of the
7532 //               destination operand
7533 //
7534 multiclass avx2_broadcast<bits<8> opc, string OpcodeStr,
7535                           X86MemOperand x86memop, PatFrag ld_frag,
7536                           Intrinsic Int128, Intrinsic Int256> {
7537   def rr : AVX28I<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
7538                   !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
7539                   [(set VR128:$dst, (Int128 VR128:$src))]>, VEX;
7540   def rm : AVX28I<opc, MRMSrcMem, (outs VR128:$dst), (ins x86memop:$src),
7541                   !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
7542                   [(set VR128:$dst,
7543                     (Int128 (scalar_to_vector (ld_frag addr:$src))))]>, VEX;
7544   def Yrr : AVX28I<opc, MRMSrcReg, (outs VR256:$dst), (ins VR128:$src),
7545                    !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
7546                    [(set VR256:$dst, (Int256 VR128:$src))]>, VEX;
7547   def Yrm : AVX28I<opc, MRMSrcMem, (outs VR256:$dst), (ins x86memop:$src),
7548                    !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
7549                    [(set VR256:$dst,
7550                     (Int256 (scalar_to_vector (ld_frag addr:$src))))]>, VEX;
7551 }
7552
7553 defm VPBROADCASTB  : avx2_broadcast<0x78, "vpbroadcastb", i8mem, loadi8,
7554                                     int_x86_avx2_pbroadcastb_128,
7555                                     int_x86_avx2_pbroadcastb_256>;
7556 defm VPBROADCASTW  : avx2_broadcast<0x79, "vpbroadcastw", i16mem, loadi16,
7557                                     int_x86_avx2_pbroadcastw_128,
7558                                     int_x86_avx2_pbroadcastw_256>;
7559 defm VPBROADCASTD  : avx2_broadcast<0x58, "vpbroadcastd", i32mem, loadi32,
7560                                     int_x86_avx2_pbroadcastd_128,
7561                                     int_x86_avx2_pbroadcastd_256>;
7562 defm VPBROADCASTQ  : avx2_broadcast<0x59, "vpbroadcastq", i64mem, loadi64,
7563                                     int_x86_avx2_pbroadcastq_128,
7564                                     int_x86_avx2_pbroadcastq_256>;
7565
7566 let Predicates = [HasAVX2] in {
7567   def : Pat<(v16i8 (X86VBroadcast (loadi8 addr:$src))),
7568           (VPBROADCASTBrm addr:$src)>;
7569   def : Pat<(v32i8 (X86VBroadcast (loadi8 addr:$src))),
7570           (VPBROADCASTBYrm addr:$src)>;
7571   def : Pat<(v8i16 (X86VBroadcast (loadi16 addr:$src))),
7572           (VPBROADCASTWrm addr:$src)>;
7573   def : Pat<(v16i16 (X86VBroadcast (loadi16 addr:$src))),
7574           (VPBROADCASTWYrm addr:$src)>;
7575   def : Pat<(v4i32 (X86VBroadcast (loadi32 addr:$src))),
7576           (VPBROADCASTDrm addr:$src)>;
7577   def : Pat<(v8i32 (X86VBroadcast (loadi32 addr:$src))),
7578           (VPBROADCASTDYrm addr:$src)>;
7579   def : Pat<(v2i64 (X86VBroadcast (loadi64 addr:$src))),
7580           (VPBROADCASTQrm addr:$src)>;
7581   def : Pat<(v4i64 (X86VBroadcast (loadi64 addr:$src))),
7582           (VPBROADCASTQYrm addr:$src)>;
7583 }
7584
7585 // AVX1 broadcast patterns
7586 let Predicates = [HasAVX] in {
7587 def : Pat<(v8i32 (X86VBroadcast (loadi32 addr:$src))),
7588           (VBROADCASTSSYrm addr:$src)>;
7589 def : Pat<(v4i64 (X86VBroadcast (loadi64 addr:$src))),
7590           (VBROADCASTSDrm addr:$src)>;
7591 def : Pat<(v8f32 (X86VBroadcast (loadf32 addr:$src))),
7592           (VBROADCASTSSYrm addr:$src)>;
7593 def : Pat<(v4f64 (X86VBroadcast (loadf64 addr:$src))),
7594           (VBROADCASTSDrm addr:$src)>;
7595
7596 def : Pat<(v4f32 (X86VBroadcast (loadf32 addr:$src))),
7597           (VBROADCASTSSrm addr:$src)>;
7598 def : Pat<(v4i32 (X86VBroadcast (loadi32 addr:$src))),
7599           (VBROADCASTSSrm addr:$src)>;
7600 }
7601
7602 //===----------------------------------------------------------------------===//
7603 // VPERM - Permute instructions
7604 //
7605
7606 multiclass avx2_perm<bits<8> opc, string OpcodeStr, PatFrag mem_frag,
7607                      Intrinsic Int> {
7608   def Yrr : AVX28I<opc, MRMSrcReg, (outs VR256:$dst),
7609                    (ins VR256:$src1, VR256:$src2),
7610                    !strconcat(OpcodeStr,
7611                        "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7612                    [(set VR256:$dst, (Int VR256:$src1, VR256:$src2))]>, VEX_4V;
7613   def Yrm : AVX28I<opc, MRMSrcMem, (outs VR256:$dst),
7614                    (ins VR256:$src1, i256mem:$src2),
7615                    !strconcat(OpcodeStr,
7616                        "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7617                    [(set VR256:$dst, (Int VR256:$src1,
7618                                       (bitconvert (mem_frag addr:$src2))))]>,
7619                    VEX_4V;
7620 }
7621
7622 defm VPERMD : avx2_perm<0x36, "vpermd", memopv4i64, int_x86_avx2_permd>;
7623 let ExeDomain = SSEPackedSingle in
7624 defm VPERMPS : avx2_perm<0x16, "vpermps", memopv8f32, int_x86_avx2_permps>;
7625
7626 multiclass avx2_perm_imm<bits<8> opc, string OpcodeStr, PatFrag mem_frag,
7627                          Intrinsic Int> {
7628   def Yrr : AVX2AIi8<opc, MRMSrcReg, (outs VR256:$dst),
7629                      (ins VR256:$src1, i8imm:$src2),
7630                      !strconcat(OpcodeStr,
7631                          "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7632                      [(set VR256:$dst, (Int VR256:$src1, imm:$src2))]>, VEX;
7633   def Yrm : AVX2AIi8<opc, MRMSrcMem, (outs VR256:$dst),
7634                      (ins i256mem:$src1, i8imm:$src2),
7635                      !strconcat(OpcodeStr,
7636                          "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7637                      [(set VR256:$dst, (Int (mem_frag addr:$src1), imm:$src2))]>,
7638                      VEX;
7639 }
7640
7641 defm VPERMQ : avx2_perm_imm<0x00, "vpermq", memopv4i64, int_x86_avx2_permq>,
7642                             VEX_W;
7643 let ExeDomain = SSEPackedDouble in
7644 defm VPERMPD : avx2_perm_imm<0x01, "vpermpd", memopv4f64, int_x86_avx2_permpd>,
7645                              VEX_W;
7646
7647 //===----------------------------------------------------------------------===//
7648 // VPERM2I128 - Permute Floating-Point Values in 128-bit chunks
7649 //
7650 def VPERM2I128rr : AVX2AIi8<0x46, MRMSrcReg, (outs VR256:$dst),
7651           (ins VR256:$src1, VR256:$src2, i8imm:$src3),
7652           "vperm2i128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
7653           [(set VR256:$dst,
7654            (int_x86_avx2_vperm2i128 VR256:$src1, VR256:$src2, imm:$src3))]>,
7655           VEX_4V;
7656 def VPERM2I128rm : AVX2AIi8<0x46, MRMSrcMem, (outs VR256:$dst),
7657           (ins VR256:$src1, f256mem:$src2, i8imm:$src3),
7658           "vperm2i128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
7659           [(set VR256:$dst,
7660            (int_x86_avx2_vperm2i128 VR256:$src1, (memopv4i64 addr:$src2),
7661             imm:$src3))]>,
7662           VEX_4V;
7663
7664 let Predicates = [HasAVX2] in {
7665 def : Pat<(v8i32 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
7666           (VPERM2I128rr VR256:$src1, VR256:$src2, imm:$imm)>;
7667 def : Pat<(v4i64 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
7668           (VPERM2I128rr VR256:$src1, VR256:$src2, imm:$imm)>;
7669 def : Pat<(v32i8 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
7670           (VPERM2I128rr VR256:$src1, VR256:$src2, imm:$imm)>;
7671 def : Pat<(v16i16 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
7672           (VPERM2I128rr VR256:$src1, VR256:$src2, imm:$imm)>;
7673
7674 def : Pat<(v32i8 (X86VPerm2x128 VR256:$src1, (bc_v32i8 (memopv4i64 addr:$src2)),
7675                   (i8 imm:$imm))),
7676           (VPERM2I128rm VR256:$src1, addr:$src2, imm:$imm)>;
7677 def : Pat<(v16i16 (X86VPerm2x128 VR256:$src1,
7678                    (bc_v16i16 (memopv4i64 addr:$src2)), (i8 imm:$imm))),
7679           (VPERM2I128rm VR256:$src1, addr:$src2, imm:$imm)>;
7680 def : Pat<(v8i32 (X86VPerm2x128 VR256:$src1, (bc_v8i32 (memopv4i64 addr:$src2)),
7681                   (i8 imm:$imm))),
7682           (VPERM2I128rm VR256:$src1, addr:$src2, imm:$imm)>;
7683 def : Pat<(v4i64 (X86VPerm2x128 VR256:$src1, (memopv4i64 addr:$src2),
7684                   (i8 imm:$imm))),
7685           (VPERM2I128rm VR256:$src1, addr:$src2, imm:$imm)>;
7686 }
7687
7688 // AVX1 patterns
7689 let Predicates = [HasAVX] in {
7690 def : Pat<(v8f32 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
7691           (VPERM2F128rr VR256:$src1, VR256:$src2, imm:$imm)>;
7692 def : Pat<(v8i32 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
7693           (VPERM2F128rr VR256:$src1, VR256:$src2, imm:$imm)>;
7694 def : Pat<(v4i64 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
7695           (VPERM2F128rr VR256:$src1, VR256:$src2, imm:$imm)>;
7696 def : Pat<(v4f64 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
7697           (VPERM2F128rr VR256:$src1, VR256:$src2, imm:$imm)>;
7698 def : Pat<(v32i8 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
7699           (VPERM2F128rr VR256:$src1, VR256:$src2, imm:$imm)>;
7700 def : Pat<(v16i16 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
7701           (VPERM2F128rr VR256:$src1, VR256:$src2, imm:$imm)>;
7702
7703 def : Pat<(v8f32 (X86VPerm2x128 VR256:$src1,
7704                   (memopv8f32 addr:$src2), (i8 imm:$imm))),
7705           (VPERM2F128rm VR256:$src1, addr:$src2, imm:$imm)>;
7706 def : Pat<(v8i32 (X86VPerm2x128 VR256:$src1,
7707                   (bc_v8i32 (memopv4i64 addr:$src2)), (i8 imm:$imm))),
7708           (VPERM2F128rm VR256:$src1, addr:$src2, imm:$imm)>;
7709 def : Pat<(v4i64 (X86VPerm2x128 VR256:$src1,
7710                   (memopv4i64 addr:$src2), (i8 imm:$imm))),
7711           (VPERM2F128rm VR256:$src1, addr:$src2, imm:$imm)>;
7712 def : Pat<(v4f64 (X86VPerm2x128 VR256:$src1,
7713                   (memopv4f64 addr:$src2), (i8 imm:$imm))),
7714           (VPERM2F128rm VR256:$src1, addr:$src2, imm:$imm)>;
7715 def : Pat<(v32i8 (X86VPerm2x128 VR256:$src1,
7716                   (bc_v32i8 (memopv4i64 addr:$src2)), (i8 imm:$imm))),
7717           (VPERM2F128rm VR256:$src1, addr:$src2, imm:$imm)>;
7718 def : Pat<(v16i16 (X86VPerm2x128 VR256:$src1,
7719                   (bc_v16i16 (memopv4i64 addr:$src2)), (i8 imm:$imm))),
7720           (VPERM2F128rm VR256:$src1, addr:$src2, imm:$imm)>;
7721 }
7722
7723
7724 //===----------------------------------------------------------------------===//
7725 // VINSERTI128 - Insert packed integer values
7726 //
7727 def VINSERTI128rr : AVX2AIi8<0x38, MRMSrcReg, (outs VR256:$dst),
7728           (ins VR256:$src1, VR128:$src2, i8imm:$src3),
7729           "vinserti128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
7730           [(set VR256:$dst,
7731             (int_x86_avx2_vinserti128 VR256:$src1, VR128:$src2, imm:$src3))]>,
7732           VEX_4V;
7733 def VINSERTI128rm : AVX2AIi8<0x38, MRMSrcMem, (outs VR256:$dst),
7734           (ins VR256:$src1, i128mem:$src2, i8imm:$src3),
7735           "vinserti128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
7736           [(set VR256:$dst,
7737             (int_x86_avx2_vinserti128 VR256:$src1, (memopv2i64 addr:$src2),
7738              imm:$src3))]>, VEX_4V;
7739
7740 let Predicates = [HasAVX2] in {
7741 def : Pat<(vinsertf128_insert:$ins (v4i64 VR256:$src1), (v2i64 VR128:$src2),
7742                                    (i32 imm)),
7743           (VINSERTI128rr VR256:$src1, VR128:$src2,
7744                          (INSERT_get_vinsertf128_imm VR256:$ins))>;
7745 def : Pat<(vinsertf128_insert:$ins (v8i32 VR256:$src1), (v4i32 VR128:$src2),
7746                                    (i32 imm)),
7747           (VINSERTI128rr VR256:$src1, VR128:$src2,
7748                          (INSERT_get_vinsertf128_imm VR256:$ins))>;
7749 def : Pat<(vinsertf128_insert:$ins (v32i8 VR256:$src1), (v16i8 VR128:$src2),
7750                                    (i32 imm)),
7751           (VINSERTI128rr VR256:$src1, VR128:$src2,
7752                          (INSERT_get_vinsertf128_imm VR256:$ins))>;
7753 def : Pat<(vinsertf128_insert:$ins (v16i16 VR256:$src1), (v8i16 VR128:$src2),
7754                                    (i32 imm)),
7755           (VINSERTI128rr VR256:$src1, VR128:$src2,
7756                          (INSERT_get_vinsertf128_imm VR256:$ins))>;
7757 }
7758
7759 // AVX1 patterns
7760 let Predicates = [HasAVX] in {
7761 def : Pat<(vinsertf128_insert:$ins (v8f32 VR256:$src1), (v4f32 VR128:$src2),
7762                                    (i32 imm)),
7763           (VINSERTF128rr VR256:$src1, VR128:$src2,
7764                          (INSERT_get_vinsertf128_imm VR256:$ins))>;
7765 def : Pat<(vinsertf128_insert:$ins (v4f64 VR256:$src1), (v2f64 VR128:$src2),
7766                                    (i32 imm)),
7767           (VINSERTF128rr VR256:$src1, VR128:$src2,
7768                          (INSERT_get_vinsertf128_imm VR256:$ins))>;
7769 def : Pat<(vinsertf128_insert:$ins (v4i64 VR256:$src1), (v2i64 VR128:$src2),
7770                                    (i32 imm)),
7771           (VINSERTF128rr VR256:$src1, VR128:$src2,
7772                          (INSERT_get_vinsertf128_imm VR256:$ins))>;
7773 def : Pat<(vinsertf128_insert:$ins (v8i32 VR256:$src1), (v4i32 VR128:$src2),
7774                                    (i32 imm)),
7775           (VINSERTF128rr VR256:$src1, VR128:$src2,
7776                          (INSERT_get_vinsertf128_imm VR256:$ins))>;
7777 def : Pat<(vinsertf128_insert:$ins (v32i8 VR256:$src1), (v16i8 VR128:$src2),
7778                                    (i32 imm)),
7779           (VINSERTF128rr VR256:$src1, VR128:$src2,
7780                          (INSERT_get_vinsertf128_imm VR256:$ins))>;
7781 def : Pat<(vinsertf128_insert:$ins (v16i16 VR256:$src1), (v8i16 VR128:$src2),
7782                                    (i32 imm)),
7783           (VINSERTF128rr VR256:$src1, VR128:$src2,
7784                          (INSERT_get_vinsertf128_imm VR256:$ins))>;
7785 }
7786
7787 //===----------------------------------------------------------------------===//
7788 // VEXTRACTI128 - Extract packed integer values
7789 //
7790 def VEXTRACTI128rr : AVX2AIi8<0x39, MRMDestReg, (outs VR128:$dst),
7791           (ins VR256:$src1, i8imm:$src2),
7792           "vextracti128\t{$src2, $src1, $dst|$dst, $src1, $src2}",
7793           [(set VR128:$dst,
7794             (int_x86_avx2_vextracti128 VR256:$src1, imm:$src2))]>,
7795           VEX;
7796 let neverHasSideEffects = 1, mayStore = 1 in
7797 def VEXTRACTI128mr : AVX2AIi8<0x39, MRMDestMem, (outs),
7798           (ins i128mem:$dst, VR256:$src1, i8imm:$src2),
7799           "vextracti128\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>, VEX;
7800
7801 let Predicates = [HasAVX2] in {
7802 def : Pat<(vextractf128_extract:$ext VR256:$src1, (i32 imm)),
7803           (v2i64 (VEXTRACTI128rr
7804                     (v4i64 VR256:$src1),
7805                     (EXTRACT_get_vextractf128_imm VR128:$ext)))>;
7806 def : Pat<(vextractf128_extract:$ext VR256:$src1, (i32 imm)),
7807           (v4i32 (VEXTRACTI128rr
7808                     (v8i32 VR256:$src1),
7809                     (EXTRACT_get_vextractf128_imm VR128:$ext)))>;
7810 def : Pat<(vextractf128_extract:$ext VR256:$src1, (i32 imm)),
7811           (v8i16 (VEXTRACTI128rr
7812                     (v16i16 VR256:$src1),
7813                     (EXTRACT_get_vextractf128_imm VR128:$ext)))>;
7814 def : Pat<(vextractf128_extract:$ext VR256:$src1, (i32 imm)),
7815           (v16i8 (VEXTRACTI128rr
7816                     (v32i8 VR256:$src1),
7817                     (EXTRACT_get_vextractf128_imm VR128:$ext)))>;
7818 }
7819
7820 // AVX1 patterns
7821 let Predicates = [HasAVX] in {
7822 def : Pat<(vextractf128_extract:$ext VR256:$src1, (i32 imm)),
7823           (v4f32 (VEXTRACTF128rr
7824                     (v8f32 VR256:$src1),
7825                     (EXTRACT_get_vextractf128_imm VR128:$ext)))>;
7826 def : Pat<(vextractf128_extract:$ext VR256:$src1, (i32 imm)),
7827           (v2f64 (VEXTRACTF128rr
7828                     (v4f64 VR256:$src1),
7829                     (EXTRACT_get_vextractf128_imm VR128:$ext)))>;
7830 def : Pat<(vextractf128_extract:$ext VR256:$src1, (i32 imm)),
7831           (v2i64 (VEXTRACTF128rr
7832                     (v4i64 VR256:$src1),
7833                     (EXTRACT_get_vextractf128_imm VR128:$ext)))>;
7834 def : Pat<(vextractf128_extract:$ext VR256:$src1, (i32 imm)),
7835           (v4i32 (VEXTRACTF128rr
7836                     (v8i32 VR256:$src1),
7837                     (EXTRACT_get_vextractf128_imm VR128:$ext)))>;
7838 def : Pat<(vextractf128_extract:$ext VR256:$src1, (i32 imm)),
7839           (v8i16 (VEXTRACTF128rr
7840                     (v16i16 VR256:$src1),
7841                     (EXTRACT_get_vextractf128_imm VR128:$ext)))>;
7842 def : Pat<(vextractf128_extract:$ext VR256:$src1, (i32 imm)),
7843           (v16i8 (VEXTRACTF128rr
7844                     (v32i8 VR256:$src1),
7845                     (EXTRACT_get_vextractf128_imm VR128:$ext)))>;
7846 }
7847
7848 //===----------------------------------------------------------------------===//
7849 // VPMASKMOV - Conditional SIMD Integer Packed Loads and Stores
7850 //
7851 multiclass avx2_pmovmask<string OpcodeStr,
7852                          Intrinsic IntLd128, Intrinsic IntLd256,
7853                          Intrinsic IntSt128, Intrinsic IntSt256> {
7854   def rm  : AVX28I<0x8c, MRMSrcMem, (outs VR128:$dst),
7855              (ins VR128:$src1, i128mem:$src2),
7856              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7857              [(set VR128:$dst, (IntLd128 addr:$src2, VR128:$src1))]>, VEX_4V;
7858   def Yrm : AVX28I<0x8c, MRMSrcMem, (outs VR256:$dst),
7859              (ins VR256:$src1, i256mem:$src2),
7860              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7861              [(set VR256:$dst, (IntLd256 addr:$src2, VR256:$src1))]>, VEX_4V;
7862   def mr  : AVX28I<0x8e, MRMDestMem, (outs),
7863              (ins i128mem:$dst, VR128:$src1, VR128:$src2),
7864              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7865              [(IntSt128 addr:$dst, VR128:$src1, VR128:$src2)]>, VEX_4V;
7866   def Ymr : AVX28I<0x8e, MRMDestMem, (outs),
7867              (ins i256mem:$dst, VR256:$src1, VR256:$src2),
7868              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7869              [(IntSt256 addr:$dst, VR256:$src1, VR256:$src2)]>, VEX_4V;
7870 }
7871
7872 defm VPMASKMOVD : avx2_pmovmask<"vpmaskmovd",
7873                                 int_x86_avx2_maskload_d,
7874                                 int_x86_avx2_maskload_d_256,
7875                                 int_x86_avx2_maskstore_d,
7876                                 int_x86_avx2_maskstore_d_256>;
7877 defm VPMASKMOVQ : avx2_pmovmask<"vpmaskmovq",
7878                                 int_x86_avx2_maskload_q,
7879                                 int_x86_avx2_maskload_q_256,
7880                                 int_x86_avx2_maskstore_q,
7881                                 int_x86_avx2_maskstore_q_256>, VEX_W;
7882
7883
7884 //===----------------------------------------------------------------------===//
7885 // Variable Bit Shifts
7886 //
7887 multiclass avx2_var_shift<bits<8> opc, string OpcodeStr, SDNode OpNode,
7888                           ValueType vt128, ValueType vt256> {
7889   def rr  : AVX28I<opc, MRMSrcReg, (outs VR128:$dst),
7890              (ins VR128:$src1, VR128:$src2),
7891              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7892              [(set VR128:$dst,
7893                (vt128 (OpNode VR128:$src1, (vt128 VR128:$src2))))]>,
7894              VEX_4V;
7895   def rm  : AVX28I<opc, MRMSrcMem, (outs VR128:$dst),
7896              (ins VR128:$src1, i128mem:$src2),
7897              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7898              [(set VR128:$dst,
7899                (vt128 (OpNode VR128:$src1,
7900                        (vt128 (bitconvert (memopv2i64 addr:$src2))))))]>,
7901              VEX_4V;
7902   def Yrr : AVX28I<opc, MRMSrcReg, (outs VR256:$dst),
7903              (ins VR256:$src1, VR256:$src2),
7904              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7905              [(set VR256:$dst,
7906                (vt256 (OpNode VR256:$src1, (vt256 VR256:$src2))))]>,
7907              VEX_4V;
7908   def Yrm : AVX28I<opc, MRMSrcMem, (outs VR256:$dst),
7909              (ins VR256:$src1, i256mem:$src2),
7910              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7911              [(set VR256:$dst,
7912                (vt256 (OpNode VR256:$src1,
7913                        (vt256 (bitconvert (memopv4i64 addr:$src2))))))]>,
7914              VEX_4V;
7915 }
7916
7917 defm VPSLLVD : avx2_var_shift<0x47, "vpsllvd", shl, v4i32, v8i32>;
7918 defm VPSLLVQ : avx2_var_shift<0x47, "vpsllvq", shl, v2i64, v4i64>, VEX_W;
7919 defm VPSRLVD : avx2_var_shift<0x45, "vpsrlvd", srl, v4i32, v8i32>;
7920 defm VPSRLVQ : avx2_var_shift<0x45, "vpsrlvq", srl, v2i64, v4i64>, VEX_W;
7921 defm VPSRAVD : avx2_var_shift<0x46, "vpsravd", sra, v4i32, v8i32>;