Convert SHUFPD with the same register for both sources to PSHUFD if it would prevent...
[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, 1 /* cvt to pshufd */>,
2334                     TB, OpSize;
2335 }
2336
2337 let Predicates = [HasAVX] in {
2338   def : Pat<(v4f32 (X86Shufp VR128:$src1,
2339                        (memopv4f32 addr:$src2), (i8 imm:$imm))),
2340             (VSHUFPSrmi VR128:$src1, addr:$src2, imm:$imm)>;
2341   def : Pat<(v4f32 (X86Shufp VR128:$src1, VR128:$src2, (i8 imm:$imm))),
2342             (VSHUFPSrri VR128:$src1, VR128:$src2, imm:$imm)>;
2343   def : Pat<(v4i32 (X86Shufp VR128:$src1,
2344                        (bc_v4i32 (memopv2i64 addr:$src2)), (i8 imm:$imm))),
2345             (VSHUFPSrmi VR128:$src1, addr:$src2, imm:$imm)>;
2346   def : Pat<(v4i32 (X86Shufp VR128:$src1, VR128:$src2, (i8 imm:$imm))),
2347             (VSHUFPSrri VR128:$src1, VR128:$src2, imm:$imm)>;
2348   // vector_shuffle v1, v2 <4, 5, 2, 3> using SHUFPSrri (we prefer movsd, but
2349   // fall back to this for SSE1)
2350   def : Pat<(v4f32 (movlp:$src3 VR128:$src1, (v4f32 VR128:$src2))),
2351             (VSHUFPSrri VR128:$src2, VR128:$src1,
2352                         (SHUFFLE_get_shuf_imm VR128:$src3))>;
2353   // Special unary SHUFPSrri case.
2354   def : Pat<(v4f32 (pshufd:$src3 VR128:$src1, (undef))),
2355             (VSHUFPSrri VR128:$src1, VR128:$src1,
2356                         (SHUFFLE_get_shuf_imm VR128:$src3))>;
2357   // Special binary v4i32 shuffle cases with SHUFPS.
2358   def : Pat<(v4i32 (shufp:$src3 VR128:$src1, (v4i32 VR128:$src2))),
2359             (VSHUFPSrri VR128:$src1, VR128:$src2,
2360                         (SHUFFLE_get_shuf_imm VR128:$src3))>;
2361   def : Pat<(v4i32 (shufp:$src3 VR128:$src1,
2362                                 (bc_v4i32 (memopv2i64 addr:$src2)))),
2363             (VSHUFPSrmi VR128:$src1, addr:$src2,
2364                         (SHUFFLE_get_shuf_imm VR128:$src3))>;
2365   // Special unary SHUFPDrri cases.
2366   def : Pat<(v2i64 (pshufd:$src3 VR128:$src1, (undef))),
2367             (VSHUFPDrri VR128:$src1, VR128:$src1,
2368                         (SHUFFLE_get_shuf_imm VR128:$src3))>;
2369   def : Pat<(v2f64 (pshufd:$src3 VR128:$src1, (undef))),
2370             (VSHUFPDrri VR128:$src1, VR128:$src1,
2371                         (SHUFFLE_get_shuf_imm VR128:$src3))>;
2372   // Special binary v2i64 shuffle cases using SHUFPDrri.
2373   def : Pat<(v2i64 (shufp:$src3 VR128:$src1, VR128:$src2)),
2374             (VSHUFPDrri VR128:$src1, VR128:$src2,
2375                         (SHUFFLE_get_shuf_imm VR128:$src3))>;
2376
2377   def : Pat<(v2i64 (X86Shufp VR128:$src1,
2378                        (memopv2i64 addr:$src2), (i8 imm:$imm))),
2379             (VSHUFPDrmi VR128:$src1, addr:$src2, imm:$imm)>;
2380   def : Pat<(v2f64 (X86Shufp VR128:$src1,
2381                        (memopv2f64 addr:$src2), (i8 imm:$imm))),
2382             (VSHUFPDrmi VR128:$src1, addr:$src2, imm:$imm)>;
2383   def : Pat<(v2i64 (X86Shufp VR128:$src1, VR128:$src2, (i8 imm:$imm))),
2384             (VSHUFPDrri VR128:$src1, VR128:$src2, imm:$imm)>;
2385   def : Pat<(v2f64 (X86Shufp VR128:$src1, VR128:$src2, (i8 imm:$imm))),
2386             (VSHUFPDrri VR128:$src1, VR128:$src2, imm:$imm)>;
2387
2388   // 256-bit patterns
2389   def : Pat<(v8i32 (X86Shufp VR256:$src1, VR256:$src2, (i8 imm:$imm))),
2390             (VSHUFPSYrri VR256:$src1, VR256:$src2, imm:$imm)>;
2391   def : Pat<(v8i32 (X86Shufp VR256:$src1,
2392                       (bc_v8i32 (memopv4i64 addr:$src2)), (i8 imm:$imm))),
2393             (VSHUFPSYrmi VR256:$src1, addr:$src2, imm:$imm)>;
2394
2395   def : Pat<(v8f32 (X86Shufp VR256:$src1, VR256:$src2, (i8 imm:$imm))),
2396             (VSHUFPSYrri VR256:$src1, VR256:$src2, imm:$imm)>;
2397   def : Pat<(v8f32 (X86Shufp VR256:$src1,
2398                               (memopv8f32 addr:$src2), (i8 imm:$imm))),
2399             (VSHUFPSYrmi VR256:$src1, addr:$src2, imm:$imm)>;
2400
2401   def : Pat<(v4i64 (X86Shufp VR256:$src1, VR256:$src2, (i8 imm:$imm))),
2402             (VSHUFPDYrri VR256:$src1, VR256:$src2, imm:$imm)>;
2403   def : Pat<(v4i64 (X86Shufp VR256:$src1,
2404                               (memopv4i64 addr:$src2), (i8 imm:$imm))),
2405             (VSHUFPDYrmi VR256:$src1, addr:$src2, imm:$imm)>;
2406
2407   def : Pat<(v4f64 (X86Shufp VR256:$src1, VR256:$src2, (i8 imm:$imm))),
2408             (VSHUFPDYrri VR256:$src1, VR256:$src2, imm:$imm)>;
2409   def : Pat<(v4f64 (X86Shufp VR256:$src1,
2410                               (memopv4f64 addr:$src2), (i8 imm:$imm))),
2411             (VSHUFPDYrmi VR256:$src1, addr:$src2, imm:$imm)>;
2412 }
2413
2414 let Predicates = [HasSSE1] in {
2415   def : Pat<(v4f32 (X86Shufp VR128:$src1,
2416                        (memopv4f32 addr:$src2), (i8 imm:$imm))),
2417             (SHUFPSrmi VR128:$src1, addr:$src2, imm:$imm)>;
2418   def : Pat<(v4f32 (X86Shufp VR128:$src1, VR128:$src2, (i8 imm:$imm))),
2419             (SHUFPSrri VR128:$src1, VR128:$src2, imm:$imm)>;
2420   def : Pat<(v4i32 (X86Shufp VR128:$src1,
2421                        (bc_v4i32 (memopv2i64 addr:$src2)), (i8 imm:$imm))),
2422             (SHUFPSrmi VR128:$src1, addr:$src2, imm:$imm)>;
2423   def : Pat<(v4i32 (X86Shufp VR128:$src1, VR128:$src2, (i8 imm:$imm))),
2424             (SHUFPSrri VR128:$src1, VR128:$src2, imm:$imm)>;
2425   // vector_shuffle v1, v2 <4, 5, 2, 3> using SHUFPSrri (we prefer movsd, but
2426   // fall back to this for SSE1)
2427   def : Pat<(v4f32 (movlp:$src3 VR128:$src1, (v4f32 VR128:$src2))),
2428             (SHUFPSrri VR128:$src2, VR128:$src1,
2429                        (SHUFFLE_get_shuf_imm VR128:$src3))>;
2430   // Special unary SHUFPSrri case.
2431   def : Pat<(v4f32 (pshufd:$src3 VR128:$src1, (undef))),
2432             (SHUFPSrri VR128:$src1, VR128:$src1,
2433                        (SHUFFLE_get_shuf_imm VR128:$src3))>;
2434 }
2435
2436 let Predicates = [HasSSE2] in {
2437   // Special binary v4i32 shuffle cases with SHUFPS.
2438   def : Pat<(v4i32 (shufp:$src3 VR128:$src1, (v4i32 VR128:$src2))),
2439             (SHUFPSrri VR128:$src1, VR128:$src2,
2440                        (SHUFFLE_get_shuf_imm VR128:$src3))>;
2441   def : Pat<(v4i32 (shufp:$src3 VR128:$src1,
2442                                 (bc_v4i32 (memopv2i64 addr:$src2)))),
2443             (SHUFPSrmi VR128:$src1, addr:$src2,
2444                       (SHUFFLE_get_shuf_imm VR128:$src3))>;
2445   // Special unary SHUFPDrri cases.
2446   def : Pat<(v2i64 (pshufd:$src3 VR128:$src1, (undef))),
2447             (SHUFPDrri VR128:$src1, VR128:$src1,
2448                        (SHUFFLE_get_shuf_imm VR128:$src3))>;
2449   def : Pat<(v2f64 (pshufd:$src3 VR128:$src1, (undef))),
2450             (SHUFPDrri VR128:$src1, VR128:$src1,
2451                        (SHUFFLE_get_shuf_imm VR128:$src3))>;
2452   // Special binary v2i64 shuffle cases using SHUFPDrri.
2453   def : Pat<(v2i64 (shufp:$src3 VR128:$src1, VR128:$src2)),
2454             (SHUFPDrri VR128:$src1, VR128:$src2,
2455                        (SHUFFLE_get_shuf_imm VR128:$src3))>;
2456   // Generic SHUFPD patterns
2457   def : Pat<(v2i64 (X86Shufp VR128:$src1,
2458                        (memopv2i64 addr:$src2), (i8 imm:$imm))),
2459             (SHUFPDrmi VR128:$src1, addr:$src2, imm:$imm)>;
2460   def : Pat<(v2f64 (X86Shufp VR128:$src1,
2461                        (memopv2f64 addr:$src2), (i8 imm:$imm))),
2462             (SHUFPDrmi VR128:$src1, addr:$src2, imm:$imm)>;
2463   def : Pat<(v2i64 (X86Shufp VR128:$src1, VR128:$src2, (i8 imm:$imm))),
2464             (SHUFPDrri VR128:$src1, VR128:$src2, imm:$imm)>;
2465   def : Pat<(v2f64 (X86Shufp VR128:$src1, VR128:$src2, (i8 imm:$imm))),
2466             (SHUFPDrri VR128:$src1, VR128:$src2, imm:$imm)>;
2467 }
2468
2469 //===----------------------------------------------------------------------===//
2470 // SSE 1 & 2 - Unpack Instructions
2471 //===----------------------------------------------------------------------===//
2472
2473 /// sse12_unpack_interleave - sse 1 & 2 unpack and interleave
2474 multiclass sse12_unpack_interleave<bits<8> opc, PatFrag OpNode, ValueType vt,
2475                                    PatFrag mem_frag, RegisterClass RC,
2476                                    X86MemOperand x86memop, string asm,
2477                                    Domain d> {
2478     def rr : PI<opc, MRMSrcReg,
2479                 (outs RC:$dst), (ins RC:$src1, RC:$src2),
2480                 asm, [(set RC:$dst,
2481                            (vt (OpNode RC:$src1, RC:$src2)))], d>;
2482     def rm : PI<opc, MRMSrcMem,
2483                 (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
2484                 asm, [(set RC:$dst,
2485                            (vt (OpNode RC:$src1,
2486                                        (mem_frag addr:$src2))))], d>;
2487 }
2488
2489 let AddedComplexity = 10 in {
2490   defm VUNPCKHPS: sse12_unpack_interleave<0x15, unpckh, v4f32, memopv4f32,
2491         VR128, f128mem, "unpckhps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2492                        SSEPackedSingle>, TB, VEX_4V;
2493   defm VUNPCKHPD: sse12_unpack_interleave<0x15, unpckh, v2f64, memopv2f64,
2494         VR128, f128mem, "unpckhpd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2495                        SSEPackedDouble>, TB, OpSize, VEX_4V;
2496   defm VUNPCKLPS: sse12_unpack_interleave<0x14, unpckl, v4f32, memopv4f32,
2497         VR128, f128mem, "unpcklps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2498                        SSEPackedSingle>, TB, VEX_4V;
2499   defm VUNPCKLPD: sse12_unpack_interleave<0x14, unpckl, v2f64, memopv2f64,
2500         VR128, f128mem, "unpcklpd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2501                        SSEPackedDouble>, TB, OpSize, VEX_4V;
2502
2503   defm VUNPCKHPSY: sse12_unpack_interleave<0x15, unpckh, v8f32, memopv8f32,
2504         VR256, f256mem, "unpckhps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2505                        SSEPackedSingle>, TB, VEX_4V;
2506   defm VUNPCKHPDY: sse12_unpack_interleave<0x15, unpckh, v4f64, memopv4f64,
2507         VR256, f256mem, "unpckhpd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2508                        SSEPackedDouble>, TB, OpSize, VEX_4V;
2509   defm VUNPCKLPSY: sse12_unpack_interleave<0x14, unpckl, v8f32, memopv8f32,
2510         VR256, f256mem, "unpcklps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2511                        SSEPackedSingle>, TB, VEX_4V;
2512   defm VUNPCKLPDY: sse12_unpack_interleave<0x14, unpckl, v4f64, memopv4f64,
2513         VR256, f256mem, "unpcklpd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2514                        SSEPackedDouble>, TB, OpSize, VEX_4V;
2515
2516   let Constraints = "$src1 = $dst" in {
2517     defm UNPCKHPS: sse12_unpack_interleave<0x15, unpckh, v4f32, memopv4f32,
2518           VR128, f128mem, "unpckhps\t{$src2, $dst|$dst, $src2}",
2519                          SSEPackedSingle>, TB;
2520     defm UNPCKHPD: sse12_unpack_interleave<0x15, unpckh, v2f64, memopv2f64,
2521           VR128, f128mem, "unpckhpd\t{$src2, $dst|$dst, $src2}",
2522                          SSEPackedDouble>, TB, OpSize;
2523     defm UNPCKLPS: sse12_unpack_interleave<0x14, unpckl, v4f32, memopv4f32,
2524           VR128, f128mem, "unpcklps\t{$src2, $dst|$dst, $src2}",
2525                          SSEPackedSingle>, TB;
2526     defm UNPCKLPD: sse12_unpack_interleave<0x14, unpckl, v2f64, memopv2f64,
2527           VR128, f128mem, "unpcklpd\t{$src2, $dst|$dst, $src2}",
2528                          SSEPackedDouble>, TB, OpSize;
2529   } // Constraints = "$src1 = $dst"
2530 } // AddedComplexity
2531
2532 let Predicates = [HasSSE1] in {
2533   def : Pat<(v4f32 (X86Unpckl VR128:$src1, (memopv4f32 addr:$src2))),
2534             (UNPCKLPSrm VR128:$src1, addr:$src2)>;
2535   def : Pat<(v4f32 (X86Unpckl VR128:$src1, VR128:$src2)),
2536             (UNPCKLPSrr VR128:$src1, VR128:$src2)>;
2537   def : Pat<(v4f32 (X86Unpckh VR128:$src1, (memopv4f32 addr:$src2))),
2538             (UNPCKHPSrm VR128:$src1, addr:$src2)>;
2539   def : Pat<(v4f32 (X86Unpckh VR128:$src1, VR128:$src2)),
2540             (UNPCKHPSrr VR128:$src1, VR128:$src2)>;
2541 }
2542
2543 let Predicates = [HasSSE2] in {
2544   def : Pat<(v2f64 (X86Unpckl VR128:$src1, (memopv2f64 addr:$src2))),
2545             (UNPCKLPDrm VR128:$src1, addr:$src2)>;
2546   def : Pat<(v2f64 (X86Unpckl VR128:$src1, VR128:$src2)),
2547             (UNPCKLPDrr VR128:$src1, VR128:$src2)>;
2548   def : Pat<(v2f64 (X86Unpckh VR128:$src1, (memopv2f64 addr:$src2))),
2549             (UNPCKHPDrm VR128:$src1, addr:$src2)>;
2550   def : Pat<(v2f64 (X86Unpckh VR128:$src1, VR128:$src2)),
2551             (UNPCKHPDrr VR128:$src1, VR128:$src2)>;
2552
2553   // FIXME: Instead of X86Movddup, there should be a X86Unpckl here, the
2554   // problem is during lowering, where it's not possible to recognize the load
2555   // fold cause it has two uses through a bitcast. One use disappears at isel
2556   // time and the fold opportunity reappears.
2557   def : Pat<(v2f64 (X86Movddup VR128:$src)),
2558             (UNPCKLPDrr VR128:$src, VR128:$src)>;
2559
2560   let AddedComplexity = 10 in
2561   def : Pat<(splat_lo (v2f64 VR128:$src), (undef)),
2562             (UNPCKLPDrr VR128:$src, VR128:$src)>;
2563 }
2564
2565 let Predicates = [HasAVX] in {
2566   def : Pat<(v4f32 (X86Unpckl VR128:$src1, (memopv4f32 addr:$src2))),
2567             (VUNPCKLPSrm VR128:$src1, addr:$src2)>;
2568   def : Pat<(v4f32 (X86Unpckl VR128:$src1, VR128:$src2)),
2569             (VUNPCKLPSrr VR128:$src1, VR128:$src2)>;
2570   def : Pat<(v4f32 (X86Unpckh VR128:$src1, (memopv4f32 addr:$src2))),
2571             (VUNPCKHPSrm VR128:$src1, addr:$src2)>;
2572   def : Pat<(v4f32 (X86Unpckh VR128:$src1, VR128:$src2)),
2573             (VUNPCKHPSrr VR128:$src1, VR128:$src2)>;
2574
2575   def : Pat<(v8f32 (X86Unpckl VR256:$src1, (memopv8f32 addr:$src2))),
2576             (VUNPCKLPSYrm VR256:$src1, addr:$src2)>;
2577   def : Pat<(v8f32 (X86Unpckl VR256:$src1, VR256:$src2)),
2578             (VUNPCKLPSYrr VR256:$src1, VR256:$src2)>;
2579   def : Pat<(v8f32 (X86Unpckh VR256:$src1, (memopv8f32 addr:$src2))),
2580             (VUNPCKHPSYrm VR256:$src1, addr:$src2)>;
2581   def : Pat<(v8f32 (X86Unpckh VR256:$src1, VR256:$src2)),
2582             (VUNPCKHPSYrr VR256:$src1, VR256:$src2)>;
2583
2584   def : Pat<(v2f64 (X86Unpckl VR128:$src1, (memopv2f64 addr:$src2))),
2585             (VUNPCKLPDrm VR128:$src1, addr:$src2)>;
2586   def : Pat<(v2f64 (X86Unpckl VR128:$src1, VR128:$src2)),
2587             (VUNPCKLPDrr VR128:$src1, VR128:$src2)>;
2588   def : Pat<(v2f64 (X86Unpckh VR128:$src1, (memopv2f64 addr:$src2))),
2589             (VUNPCKHPDrm VR128:$src1, addr:$src2)>;
2590   def : Pat<(v2f64 (X86Unpckh VR128:$src1, VR128:$src2)),
2591             (VUNPCKHPDrr VR128:$src1, VR128:$src2)>;
2592
2593   def : Pat<(v4f64 (X86Unpckl VR256:$src1, (memopv4f64 addr:$src2))),
2594             (VUNPCKLPDYrm VR256:$src1, addr:$src2)>;
2595   def : Pat<(v4f64 (X86Unpckl VR256:$src1, VR256:$src2)),
2596             (VUNPCKLPDYrr VR256:$src1, VR256:$src2)>;
2597   def : Pat<(v4f64 (X86Unpckh VR256:$src1, (memopv4f64 addr:$src2))),
2598             (VUNPCKHPDYrm VR256:$src1, addr:$src2)>;
2599   def : Pat<(v4f64 (X86Unpckh VR256:$src1, VR256:$src2)),
2600             (VUNPCKHPDYrr VR256:$src1, VR256:$src2)>;
2601
2602   // FIXME: Instead of X86Movddup, there should be a X86Unpckl here, the
2603   // problem is during lowering, where it's not possible to recognize the load
2604   // fold cause it has two uses through a bitcast. One use disappears at isel
2605   // time and the fold opportunity reappears.
2606   def : Pat<(v2f64 (X86Movddup VR128:$src)),
2607             (VUNPCKLPDrr VR128:$src, VR128:$src)>;
2608   let AddedComplexity = 10 in
2609   def : Pat<(splat_lo (v2f64 VR128:$src), (undef)),
2610             (VUNPCKLPDrr VR128:$src, VR128:$src)>;
2611 }
2612
2613 //===----------------------------------------------------------------------===//
2614 // SSE 1 & 2 - Extract Floating-Point Sign mask
2615 //===----------------------------------------------------------------------===//
2616
2617 /// sse12_extr_sign_mask - sse 1 & 2 unpack and interleave
2618 multiclass sse12_extr_sign_mask<RegisterClass RC, Intrinsic Int, string asm,
2619                                 Domain d> {
2620   def rr32 : PI<0x50, MRMSrcReg, (outs GR32:$dst), (ins RC:$src),
2621                 !strconcat(asm, "\t{$src, $dst|$dst, $src}"),
2622                      [(set GR32:$dst, (Int RC:$src))], d>;
2623   def rr64 : PI<0x50, MRMSrcReg, (outs GR64:$dst), (ins RC:$src),
2624                 !strconcat(asm, "\t{$src, $dst|$dst, $src}"), [], d>, REX_W;
2625 }
2626
2627 let Predicates = [HasAVX] in {
2628   defm VMOVMSKPS : sse12_extr_sign_mask<VR128, int_x86_sse_movmsk_ps,
2629                                         "movmskps", SSEPackedSingle>, TB, VEX;
2630   defm VMOVMSKPD : sse12_extr_sign_mask<VR128, int_x86_sse2_movmsk_pd,
2631                                         "movmskpd", SSEPackedDouble>, TB,
2632                                         OpSize, VEX;
2633   defm VMOVMSKPSY : sse12_extr_sign_mask<VR256, int_x86_avx_movmsk_ps_256,
2634                                         "movmskps", SSEPackedSingle>, TB, VEX;
2635   defm VMOVMSKPDY : sse12_extr_sign_mask<VR256, int_x86_avx_movmsk_pd_256,
2636                                         "movmskpd", SSEPackedDouble>, TB,
2637                                         OpSize, VEX;
2638
2639   def : Pat<(i32 (X86fgetsign FR32:$src)),
2640             (VMOVMSKPSrr32 (INSERT_SUBREG (v4f32 (IMPLICIT_DEF)), FR32:$src,
2641                                           sub_ss))>;
2642   def : Pat<(i64 (X86fgetsign FR32:$src)),
2643             (VMOVMSKPSrr64 (INSERT_SUBREG (v4f32 (IMPLICIT_DEF)), FR32:$src,
2644                                           sub_ss))>;
2645   def : Pat<(i32 (X86fgetsign FR64:$src)),
2646             (VMOVMSKPDrr32 (INSERT_SUBREG (v2f64 (IMPLICIT_DEF)), FR64:$src,
2647                                           sub_sd))>;
2648   def : Pat<(i64 (X86fgetsign FR64:$src)),
2649             (VMOVMSKPDrr64 (INSERT_SUBREG (v2f64 (IMPLICIT_DEF)), FR64:$src,
2650                                           sub_sd))>;
2651
2652   // Assembler Only
2653   def VMOVMSKPSr64r : PI<0x50, MRMSrcReg, (outs GR64:$dst), (ins VR128:$src),
2654              "movmskps\t{$src, $dst|$dst, $src}", [], SSEPackedSingle>, TB, VEX;
2655   def VMOVMSKPDr64r : PI<0x50, MRMSrcReg, (outs GR64:$dst), (ins VR128:$src),
2656              "movmskpd\t{$src, $dst|$dst, $src}", [], SSEPackedDouble>, TB,
2657              OpSize, VEX;
2658   def VMOVMSKPSYr64r : PI<0x50, MRMSrcReg, (outs GR64:$dst), (ins VR256:$src),
2659              "movmskps\t{$src, $dst|$dst, $src}", [], SSEPackedSingle>, TB, VEX;
2660   def VMOVMSKPDYr64r : PI<0x50, MRMSrcReg, (outs GR64:$dst), (ins VR256:$src),
2661              "movmskpd\t{$src, $dst|$dst, $src}", [], SSEPackedDouble>, TB,
2662              OpSize, VEX;
2663 }
2664
2665 defm MOVMSKPS : sse12_extr_sign_mask<VR128, int_x86_sse_movmsk_ps, "movmskps",
2666                                      SSEPackedSingle>, TB;
2667 defm MOVMSKPD : sse12_extr_sign_mask<VR128, int_x86_sse2_movmsk_pd, "movmskpd",
2668                                      SSEPackedDouble>, TB, OpSize;
2669
2670 def : Pat<(i32 (X86fgetsign FR32:$src)),
2671           (MOVMSKPSrr32 (INSERT_SUBREG (v4f32 (IMPLICIT_DEF)), FR32:$src,
2672                                        sub_ss))>, Requires<[HasSSE1]>;
2673 def : Pat<(i64 (X86fgetsign FR32:$src)),
2674           (MOVMSKPSrr64 (INSERT_SUBREG (v4f32 (IMPLICIT_DEF)), FR32:$src,
2675                                        sub_ss))>, Requires<[HasSSE1]>;
2676 def : Pat<(i32 (X86fgetsign FR64:$src)),
2677           (MOVMSKPDrr32 (INSERT_SUBREG (v2f64 (IMPLICIT_DEF)), FR64:$src,
2678                                        sub_sd))>, Requires<[HasSSE2]>;
2679 def : Pat<(i64 (X86fgetsign FR64:$src)),
2680           (MOVMSKPDrr64 (INSERT_SUBREG (v2f64 (IMPLICIT_DEF)), FR64:$src,
2681                                        sub_sd))>, Requires<[HasSSE2]>;
2682
2683 //===---------------------------------------------------------------------===//
2684 // SSE2 - Packed Integer Logical Instructions
2685 //===---------------------------------------------------------------------===//
2686
2687 let ExeDomain = SSEPackedInt in { // SSE integer instructions
2688
2689 /// PDI_binop_rm - Simple SSE2 binary operator.
2690 multiclass PDI_binop_rm<bits<8> opc, string OpcodeStr, SDNode OpNode,
2691                         ValueType OpVT, RegisterClass RC, PatFrag memop_frag,
2692                         X86MemOperand x86memop, bit IsCommutable = 0,
2693                         bit Is2Addr = 1> {
2694   let isCommutable = IsCommutable in
2695   def rr : PDI<opc, MRMSrcReg, (outs RC:$dst),
2696        (ins RC:$src1, RC:$src2),
2697        !if(Is2Addr,
2698            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
2699            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
2700        [(set RC:$dst, (OpVT (OpNode RC:$src1, RC:$src2)))]>;
2701   def rm : PDI<opc, MRMSrcMem, (outs RC:$dst),
2702        (ins RC:$src1, x86memop:$src2),
2703        !if(Is2Addr,
2704            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
2705            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
2706        [(set RC:$dst, (OpVT (OpNode RC:$src1,
2707                                      (bitconvert (memop_frag addr:$src2)))))]>;
2708 }
2709 } // ExeDomain = SSEPackedInt
2710
2711 // These are ordered here for pattern ordering requirements with the fp versions
2712
2713 let Predicates = [HasAVX] in {
2714 defm VPAND : PDI_binop_rm<0xDB, "vpand", and, v2i64, VR128, memopv2i64,
2715                           i128mem, 1, 0>, VEX_4V;
2716 defm VPOR  : PDI_binop_rm<0xEB, "vpor" , or, v2i64, VR128, memopv2i64,
2717                           i128mem, 1, 0>, VEX_4V;
2718 defm VPXOR : PDI_binop_rm<0xEF, "vpxor", xor, v2i64, VR128, memopv2i64,
2719                           i128mem, 1, 0>, VEX_4V;
2720 defm VPANDN : PDI_binop_rm<0xDF, "vpandn", X86andnp, v2i64, VR128, memopv2i64,
2721                           i128mem, 0, 0>, VEX_4V;
2722 }
2723
2724 let Constraints = "$src1 = $dst" in {
2725 defm PAND : PDI_binop_rm<0xDB, "pand", and, v2i64, VR128, memopv2i64,
2726                          i128mem, 1>;
2727 defm POR  : PDI_binop_rm<0xEB, "por" , or, v2i64, VR128, memopv2i64,
2728                          i128mem, 1>;
2729 defm PXOR : PDI_binop_rm<0xEF, "pxor", xor, v2i64, VR128, memopv2i64,
2730                          i128mem, 1>;
2731 defm PANDN : PDI_binop_rm<0xDF, "pandn", X86andnp, v2i64, VR128, memopv2i64,
2732                           i128mem, 0>;
2733 } // Constraints = "$src1 = $dst"
2734
2735 let Predicates = [HasAVX2] in {
2736 defm VPANDY : PDI_binop_rm<0xDB, "vpand", and, v4i64, VR256, memopv4i64,
2737                            i256mem, 1, 0>, VEX_4V;
2738 defm VPORY  : PDI_binop_rm<0xEB, "vpor", or, v4i64, VR256, memopv4i64,
2739                            i256mem, 1, 0>, VEX_4V;
2740 defm VPXORY : PDI_binop_rm<0xEF, "vpxor", xor, v4i64, VR256, memopv4i64,
2741                            i256mem, 1, 0>, VEX_4V;
2742 defm VPANDNY : PDI_binop_rm<0xDF, "vpandn", X86andnp, v4i64, VR256, memopv4i64,
2743                             i256mem, 0, 0>, VEX_4V;
2744 }
2745
2746 //===----------------------------------------------------------------------===//
2747 // SSE 1 & 2 - Logical Instructions
2748 //===----------------------------------------------------------------------===//
2749
2750 /// sse12_fp_alias_pack_logical - SSE 1 & 2 aliased packed FP logical ops
2751 ///
2752 multiclass sse12_fp_alias_pack_logical<bits<8> opc, string OpcodeStr,
2753                                        SDNode OpNode> {
2754   defm V#NAME#PS : sse12_fp_packed<opc, !strconcat(OpcodeStr, "ps"), OpNode,
2755               FR32, f32, f128mem, memopfsf32, SSEPackedSingle, 0>, TB, VEX_4V;
2756
2757   defm V#NAME#PD : sse12_fp_packed<opc, !strconcat(OpcodeStr, "pd"), OpNode,
2758         FR64, f64, f128mem, memopfsf64, SSEPackedDouble, 0>, TB, OpSize, VEX_4V;
2759
2760   let Constraints = "$src1 = $dst" in {
2761     defm PS : sse12_fp_packed<opc, !strconcat(OpcodeStr, "ps"), OpNode, FR32,
2762                 f32, f128mem, memopfsf32, SSEPackedSingle>, TB;
2763
2764     defm PD : sse12_fp_packed<opc, !strconcat(OpcodeStr, "pd"), OpNode, FR64,
2765                 f64, f128mem, memopfsf64, SSEPackedDouble>, TB, OpSize;
2766   }
2767 }
2768
2769 // Alias bitwise logical operations using SSE logical ops on packed FP values.
2770 let mayLoad = 0 in {
2771   defm FsAND  : sse12_fp_alias_pack_logical<0x54, "and", X86fand>;
2772   defm FsOR   : sse12_fp_alias_pack_logical<0x56, "or", X86for>;
2773   defm FsXOR  : sse12_fp_alias_pack_logical<0x57, "xor", X86fxor>;
2774 }
2775
2776 let neverHasSideEffects = 1, Pattern = []<dag>, isCommutable = 0 in
2777   defm FsANDN : sse12_fp_alias_pack_logical<0x55, "andn", undef>;
2778
2779 /// sse12_fp_packed_logical - SSE 1 & 2 packed FP logical ops
2780 ///
2781 multiclass sse12_fp_packed_logical<bits<8> opc, string OpcodeStr,
2782                                    SDNode OpNode> {
2783   // In AVX no need to add a pattern for 128-bit logical rr ps, because they
2784   // are all promoted to v2i64, and the patterns are covered by the int
2785   // version. This is needed in SSE only, because v2i64 isn't supported on
2786   // SSE1, but only on SSE2.
2787   defm V#NAME#PS : sse12_fp_packed_logical_rm<opc, VR128, SSEPackedSingle,
2788        !strconcat(OpcodeStr, "ps"), f128mem, [],
2789        [(set VR128:$dst, (OpNode (bc_v2i64 (v4f32 VR128:$src1)),
2790                                  (memopv2i64 addr:$src2)))], 0, 1>, TB, VEX_4V;
2791
2792   defm V#NAME#PD : sse12_fp_packed_logical_rm<opc, VR128, SSEPackedDouble,
2793        !strconcat(OpcodeStr, "pd"), f128mem,
2794        [(set VR128:$dst, (OpNode (bc_v2i64 (v2f64 VR128:$src1)),
2795                                  (bc_v2i64 (v2f64 VR128:$src2))))],
2796        [(set VR128:$dst, (OpNode (bc_v2i64 (v2f64 VR128:$src1)),
2797                                  (memopv2i64 addr:$src2)))], 0>,
2798                                                  TB, OpSize, VEX_4V;
2799   let Constraints = "$src1 = $dst" in {
2800     defm PS : sse12_fp_packed_logical_rm<opc, VR128, SSEPackedSingle,
2801          !strconcat(OpcodeStr, "ps"), f128mem,
2802          [(set VR128:$dst, (v2i64 (OpNode VR128:$src1, VR128:$src2)))],
2803          [(set VR128:$dst, (OpNode (bc_v2i64 (v4f32 VR128:$src1)),
2804                                    (memopv2i64 addr:$src2)))]>, TB;
2805
2806     defm PD : sse12_fp_packed_logical_rm<opc, VR128, SSEPackedDouble,
2807          !strconcat(OpcodeStr, "pd"), f128mem,
2808          [(set VR128:$dst, (OpNode (bc_v2i64 (v2f64 VR128:$src1)),
2809                                    (bc_v2i64 (v2f64 VR128:$src2))))],
2810          [(set VR128:$dst, (OpNode (bc_v2i64 (v2f64 VR128:$src1)),
2811                                    (memopv2i64 addr:$src2)))]>, TB, OpSize;
2812   }
2813 }
2814
2815 /// sse12_fp_packed_logical_y - AVX 256-bit SSE 1 & 2 logical ops forms
2816 ///
2817 multiclass sse12_fp_packed_logical_y<bits<8> opc, string OpcodeStr,
2818                                      SDNode OpNode> {
2819     defm PSY : sse12_fp_packed_logical_rm<opc, VR256, SSEPackedSingle,
2820           !strconcat(OpcodeStr, "ps"), f256mem,
2821           [(set VR256:$dst, (v4i64 (OpNode VR256:$src1, VR256:$src2)))],
2822           [(set VR256:$dst, (OpNode (bc_v4i64 (v8f32 VR256:$src1)),
2823                                     (memopv4i64 addr:$src2)))], 0>, TB, VEX_4V;
2824
2825     defm PDY : sse12_fp_packed_logical_rm<opc, VR256, SSEPackedDouble,
2826           !strconcat(OpcodeStr, "pd"), f256mem,
2827           [(set VR256:$dst, (OpNode (bc_v4i64 (v4f64 VR256:$src1)),
2828                                     (bc_v4i64 (v4f64 VR256:$src2))))],
2829           [(set VR256:$dst, (OpNode (bc_v4i64 (v4f64 VR256:$src1)),
2830                                     (memopv4i64 addr:$src2)))], 0>,
2831                                     TB, OpSize, VEX_4V;
2832 }
2833
2834 // AVX 256-bit packed logical ops forms
2835 defm VAND  : sse12_fp_packed_logical_y<0x54, "and", and>;
2836 defm VOR   : sse12_fp_packed_logical_y<0x56, "or", or>;
2837 defm VXOR  : sse12_fp_packed_logical_y<0x57, "xor", xor>;
2838 defm VANDN : sse12_fp_packed_logical_y<0x55, "andn", X86andnp>;
2839
2840 defm AND  : sse12_fp_packed_logical<0x54, "and", and>;
2841 defm OR   : sse12_fp_packed_logical<0x56, "or", or>;
2842 defm XOR  : sse12_fp_packed_logical<0x57, "xor", xor>;
2843 let isCommutable = 0 in
2844   defm ANDN : sse12_fp_packed_logical<0x55, "andn", X86andnp>;
2845
2846 //===----------------------------------------------------------------------===//
2847 // SSE 1 & 2 - Arithmetic Instructions
2848 //===----------------------------------------------------------------------===//
2849
2850 /// basic_sse12_fp_binop_xxx - SSE 1 & 2 binops come in both scalar and
2851 /// vector forms.
2852 ///
2853 /// In addition, we also have a special variant of the scalar form here to
2854 /// represent the associated intrinsic operation.  This form is unlike the
2855 /// plain scalar form, in that it takes an entire vector (instead of a scalar)
2856 /// and leaves the top elements unmodified (therefore these cannot be commuted).
2857 ///
2858 /// These three forms can each be reg+reg or reg+mem.
2859 ///
2860
2861 /// FIXME: once all 256-bit intrinsics are matched, cleanup and refactor those
2862 /// classes below
2863 multiclass basic_sse12_fp_binop_s<bits<8> opc, string OpcodeStr, SDNode OpNode,
2864                                   bit Is2Addr = 1> {
2865   defm SS : sse12_fp_scalar<opc, !strconcat(OpcodeStr, "ss"),
2866                             OpNode, FR32, f32mem, Is2Addr>, XS;
2867   defm SD : sse12_fp_scalar<opc, !strconcat(OpcodeStr, "sd"),
2868                             OpNode, FR64, f64mem, Is2Addr>, XD;
2869 }
2870
2871 multiclass basic_sse12_fp_binop_p<bits<8> opc, string OpcodeStr, SDNode OpNode,
2872                                    bit Is2Addr = 1> {
2873   let mayLoad = 0 in {
2874   defm PS : sse12_fp_packed<opc, !strconcat(OpcodeStr, "ps"), OpNode, VR128,
2875               v4f32, f128mem, memopv4f32, SSEPackedSingle, Is2Addr>, TB;
2876   defm PD : sse12_fp_packed<opc, !strconcat(OpcodeStr, "pd"), OpNode, VR128,
2877               v2f64, f128mem, memopv2f64, SSEPackedDouble, Is2Addr>, TB, OpSize;
2878   }
2879 }
2880
2881 multiclass basic_sse12_fp_binop_p_y<bits<8> opc, string OpcodeStr,
2882                                     SDNode OpNode> {
2883   let mayLoad = 0 in {
2884     defm PSY : sse12_fp_packed<opc, !strconcat(OpcodeStr, "ps"), OpNode, VR256,
2885                 v8f32, f256mem, memopv8f32, SSEPackedSingle, 0>, TB;
2886     defm PDY : sse12_fp_packed<opc, !strconcat(OpcodeStr, "pd"), OpNode, VR256,
2887                 v4f64, f256mem, memopv4f64, SSEPackedDouble, 0>, TB, OpSize;
2888   }
2889 }
2890
2891 multiclass basic_sse12_fp_binop_s_int<bits<8> opc, string OpcodeStr,
2892                                       bit Is2Addr = 1> {
2893   defm SS : sse12_fp_scalar_int<opc, OpcodeStr, VR128,
2894      !strconcat(OpcodeStr, "ss"), "", "_ss", ssmem, sse_load_f32, Is2Addr>, XS;
2895   defm SD : sse12_fp_scalar_int<opc, OpcodeStr, VR128,
2896      !strconcat(OpcodeStr, "sd"), "2", "_sd", sdmem, sse_load_f64, Is2Addr>, XD;
2897 }
2898
2899 multiclass basic_sse12_fp_binop_p_int<bits<8> opc, string OpcodeStr,
2900                                       bit Is2Addr = 1> {
2901   defm PS : sse12_fp_packed_int<opc, OpcodeStr, VR128,
2902      !strconcat(OpcodeStr, "ps"), "sse", "_ps", f128mem, memopv4f32,
2903                                               SSEPackedSingle, Is2Addr>, TB;
2904
2905   defm PD : sse12_fp_packed_int<opc, OpcodeStr, VR128,
2906      !strconcat(OpcodeStr, "pd"), "sse2", "_pd", f128mem, memopv2f64,
2907                                       SSEPackedDouble, Is2Addr>, TB, OpSize;
2908 }
2909
2910 multiclass basic_sse12_fp_binop_p_y_int<bits<8> opc, string OpcodeStr> {
2911   defm PSY : sse12_fp_packed_int<opc, OpcodeStr, VR256,
2912      !strconcat(OpcodeStr, "ps"), "avx", "_ps_256", f256mem, memopv8f32,
2913       SSEPackedSingle, 0>, TB;
2914
2915   defm PDY : sse12_fp_packed_int<opc, OpcodeStr, VR256,
2916      !strconcat(OpcodeStr, "pd"), "avx", "_pd_256", f256mem, memopv4f64,
2917       SSEPackedDouble, 0>, TB, OpSize;
2918 }
2919
2920 // Binary Arithmetic instructions
2921 defm VADD : basic_sse12_fp_binop_s<0x58, "add", fadd, 0>,
2922             basic_sse12_fp_binop_s_int<0x58, "add", 0>, VEX_4V, VEX_LIG;
2923 defm VADD : basic_sse12_fp_binop_p<0x58, "add", fadd, 0>,
2924             basic_sse12_fp_binop_p_y<0x58, "add", fadd>, VEX_4V;
2925 defm VMUL : basic_sse12_fp_binop_s<0x59, "mul", fmul, 0>,
2926             basic_sse12_fp_binop_s_int<0x59, "mul", 0>, VEX_4V, VEX_LIG;
2927 defm VMUL : basic_sse12_fp_binop_p<0x59, "mul", fmul, 0>,
2928             basic_sse12_fp_binop_p_y<0x59, "mul", fmul>, VEX_4V;
2929
2930 let isCommutable = 0 in {
2931   defm VSUB : basic_sse12_fp_binop_s<0x5C, "sub", fsub, 0>,
2932               basic_sse12_fp_binop_s_int<0x5C, "sub", 0>, VEX_4V, VEX_LIG;
2933   defm VSUB : basic_sse12_fp_binop_p<0x5C, "sub", fsub, 0>,
2934               basic_sse12_fp_binop_p_y<0x5C, "sub", fsub>, VEX_4V;
2935   defm VDIV : basic_sse12_fp_binop_s<0x5E, "div", fdiv, 0>,
2936               basic_sse12_fp_binop_s_int<0x5E, "div", 0>, VEX_4V, VEX_LIG;
2937   defm VDIV : basic_sse12_fp_binop_p<0x5E, "div", fdiv, 0>,
2938               basic_sse12_fp_binop_p_y<0x5E, "div", fdiv>, VEX_4V;
2939   defm VMAX : basic_sse12_fp_binop_s<0x5F, "max", X86fmax, 0>,
2940               basic_sse12_fp_binop_s_int<0x5F, "max", 0>, VEX_4V, VEX_LIG;
2941   defm VMAX : basic_sse12_fp_binop_p<0x5F, "max", X86fmax, 0>,
2942               basic_sse12_fp_binop_p_int<0x5F, "max", 0>,
2943               basic_sse12_fp_binop_p_y<0x5F, "max", X86fmax>,
2944               basic_sse12_fp_binop_p_y_int<0x5F, "max">, VEX_4V;
2945   defm VMIN : basic_sse12_fp_binop_s<0x5D, "min", X86fmin, 0>,
2946               basic_sse12_fp_binop_s_int<0x5D, "min", 0>, VEX_4V, VEX_LIG;
2947   defm VMIN : basic_sse12_fp_binop_p<0x5D, "min", X86fmin, 0>,
2948               basic_sse12_fp_binop_p_int<0x5D, "min", 0>,
2949               basic_sse12_fp_binop_p_y_int<0x5D, "min">,
2950               basic_sse12_fp_binop_p_y<0x5D, "min", X86fmin>, VEX_4V;
2951 }
2952
2953 let Constraints = "$src1 = $dst" in {
2954   defm ADD : basic_sse12_fp_binop_s<0x58, "add", fadd>,
2955              basic_sse12_fp_binop_p<0x58, "add", fadd>,
2956              basic_sse12_fp_binop_s_int<0x58, "add">;
2957   defm MUL : basic_sse12_fp_binop_s<0x59, "mul", fmul>,
2958              basic_sse12_fp_binop_p<0x59, "mul", fmul>,
2959              basic_sse12_fp_binop_s_int<0x59, "mul">;
2960
2961   let isCommutable = 0 in {
2962     defm SUB : basic_sse12_fp_binop_s<0x5C, "sub", fsub>,
2963                basic_sse12_fp_binop_p<0x5C, "sub", fsub>,
2964                basic_sse12_fp_binop_s_int<0x5C, "sub">;
2965     defm DIV : basic_sse12_fp_binop_s<0x5E, "div", fdiv>,
2966                basic_sse12_fp_binop_p<0x5E, "div", fdiv>,
2967                basic_sse12_fp_binop_s_int<0x5E, "div">;
2968     defm MAX : basic_sse12_fp_binop_s<0x5F, "max", X86fmax>,
2969                basic_sse12_fp_binop_p<0x5F, "max", X86fmax>,
2970                basic_sse12_fp_binop_s_int<0x5F, "max">,
2971                basic_sse12_fp_binop_p_int<0x5F, "max">;
2972     defm MIN : basic_sse12_fp_binop_s<0x5D, "min", X86fmin>,
2973                basic_sse12_fp_binop_p<0x5D, "min", X86fmin>,
2974                basic_sse12_fp_binop_s_int<0x5D, "min">,
2975                basic_sse12_fp_binop_p_int<0x5D, "min">;
2976   }
2977 }
2978
2979 /// Unop Arithmetic
2980 /// In addition, we also have a special variant of the scalar form here to
2981 /// represent the associated intrinsic operation.  This form is unlike the
2982 /// plain scalar form, in that it takes an entire vector (instead of a
2983 /// scalar) and leaves the top elements undefined.
2984 ///
2985 /// And, we have a special variant form for a full-vector intrinsic form.
2986
2987 /// sse1_fp_unop_s - SSE1 unops in scalar form.
2988 multiclass sse1_fp_unop_s<bits<8> opc, string OpcodeStr,
2989                           SDNode OpNode, Intrinsic F32Int> {
2990   def SSr : SSI<opc, MRMSrcReg, (outs FR32:$dst), (ins FR32:$src),
2991                 !strconcat(OpcodeStr, "ss\t{$src, $dst|$dst, $src}"),
2992                 [(set FR32:$dst, (OpNode FR32:$src))]>;
2993   // For scalar unary operations, fold a load into the operation
2994   // only in OptForSize mode. It eliminates an instruction, but it also
2995   // eliminates a whole-register clobber (the load), so it introduces a
2996   // partial register update condition.
2997   def SSm : I<opc, MRMSrcMem, (outs FR32:$dst), (ins f32mem:$src),
2998                 !strconcat(OpcodeStr, "ss\t{$src, $dst|$dst, $src}"),
2999                 [(set FR32:$dst, (OpNode (load addr:$src)))]>, XS,
3000             Requires<[HasSSE1, OptForSize]>;
3001   def SSr_Int : SSI<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3002                     !strconcat(OpcodeStr, "ss\t{$src, $dst|$dst, $src}"),
3003                     [(set VR128:$dst, (F32Int VR128:$src))]>;
3004   def SSm_Int : SSI<opc, MRMSrcMem, (outs VR128:$dst), (ins ssmem:$src),
3005                     !strconcat(OpcodeStr, "ss\t{$src, $dst|$dst, $src}"),
3006                     [(set VR128:$dst, (F32Int sse_load_f32:$src))]>;
3007 }
3008
3009 /// sse1_fp_unop_s_avx - AVX SSE1 unops in scalar form.
3010 multiclass sse1_fp_unop_s_avx<bits<8> opc, string OpcodeStr> {
3011   def SSr : SSI<opc, MRMSrcReg, (outs FR32:$dst), (ins FR32:$src1, FR32:$src2),
3012                 !strconcat(OpcodeStr,
3013                            "ss\t{$src2, $src1, $dst|$dst, $src1, $src2}"), []>;
3014   let mayLoad = 1 in
3015   def SSm : SSI<opc, MRMSrcMem, (outs FR32:$dst), (ins FR32:$src1,f32mem:$src2),
3016                 !strconcat(OpcodeStr,
3017                            "ss\t{$src2, $src1, $dst|$dst, $src1, $src2}"), []>;
3018   def SSm_Int : SSI<opc, MRMSrcMem, (outs VR128:$dst),
3019                 (ins VR128:$src1, ssmem:$src2),
3020                 !strconcat(OpcodeStr,
3021                            "ss\t{$src2, $src1, $dst|$dst, $src1, $src2}"), []>;
3022 }
3023
3024 /// sse1_fp_unop_p - SSE1 unops in packed form.
3025 multiclass sse1_fp_unop_p<bits<8> opc, string OpcodeStr, SDNode OpNode> {
3026   def PSr : PSI<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3027               !strconcat(OpcodeStr, "ps\t{$src, $dst|$dst, $src}"),
3028               [(set VR128:$dst, (v4f32 (OpNode VR128:$src)))]>;
3029   def PSm : PSI<opc, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
3030                 !strconcat(OpcodeStr, "ps\t{$src, $dst|$dst, $src}"),
3031                 [(set VR128:$dst, (OpNode (memopv4f32 addr:$src)))]>;
3032 }
3033
3034 /// sse1_fp_unop_p_y - AVX 256-bit SSE1 unops in packed form.
3035 multiclass sse1_fp_unop_p_y<bits<8> opc, string OpcodeStr, SDNode OpNode> {
3036   def PSYr : PSI<opc, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
3037               !strconcat(OpcodeStr, "ps\t{$src, $dst|$dst, $src}"),
3038               [(set VR256:$dst, (v8f32 (OpNode VR256:$src)))]>;
3039   def PSYm : PSI<opc, MRMSrcMem, (outs VR256:$dst), (ins f256mem:$src),
3040                 !strconcat(OpcodeStr, "ps\t{$src, $dst|$dst, $src}"),
3041                 [(set VR256:$dst, (OpNode (memopv8f32 addr:$src)))]>;
3042 }
3043
3044 /// sse1_fp_unop_p_int - SSE1 intrinsics unops in packed forms.
3045 multiclass sse1_fp_unop_p_int<bits<8> opc, string OpcodeStr,
3046                               Intrinsic V4F32Int> {
3047   def PSr_Int : PSI<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3048                     !strconcat(OpcodeStr, "ps\t{$src, $dst|$dst, $src}"),
3049                     [(set VR128:$dst, (V4F32Int VR128:$src))]>;
3050   def PSm_Int : PSI<opc, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
3051                     !strconcat(OpcodeStr, "ps\t{$src, $dst|$dst, $src}"),
3052                     [(set VR128:$dst, (V4F32Int (memopv4f32 addr:$src)))]>;
3053 }
3054
3055 /// sse1_fp_unop_p_y_int - AVX 256-bit intrinsics unops in packed forms.
3056 multiclass sse1_fp_unop_p_y_int<bits<8> opc, string OpcodeStr,
3057                                 Intrinsic V4F32Int> {
3058   def PSYr_Int : PSI<opc, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
3059                     !strconcat(OpcodeStr, "ps\t{$src, $dst|$dst, $src}"),
3060                     [(set VR256:$dst, (V4F32Int VR256:$src))]>;
3061   def PSYm_Int : PSI<opc, MRMSrcMem, (outs VR256:$dst), (ins f256mem:$src),
3062                     !strconcat(OpcodeStr, "ps\t{$src, $dst|$dst, $src}"),
3063                     [(set VR256:$dst, (V4F32Int (memopv8f32 addr:$src)))]>;
3064 }
3065
3066 /// sse2_fp_unop_s - SSE2 unops in scalar form.
3067 multiclass sse2_fp_unop_s<bits<8> opc, string OpcodeStr,
3068                           SDNode OpNode, Intrinsic F64Int> {
3069   def SDr : SDI<opc, MRMSrcReg, (outs FR64:$dst), (ins FR64:$src),
3070                 !strconcat(OpcodeStr, "sd\t{$src, $dst|$dst, $src}"),
3071                 [(set FR64:$dst, (OpNode FR64:$src))]>;
3072   // See the comments in sse1_fp_unop_s for why this is OptForSize.
3073   def SDm : I<opc, MRMSrcMem, (outs FR64:$dst), (ins f64mem:$src),
3074                 !strconcat(OpcodeStr, "sd\t{$src, $dst|$dst, $src}"),
3075                 [(set FR64:$dst, (OpNode (load addr:$src)))]>, XD,
3076             Requires<[HasSSE2, OptForSize]>;
3077   def SDr_Int : SDI<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3078                     !strconcat(OpcodeStr, "sd\t{$src, $dst|$dst, $src}"),
3079                     [(set VR128:$dst, (F64Int VR128:$src))]>;
3080   def SDm_Int : SDI<opc, MRMSrcMem, (outs VR128:$dst), (ins sdmem:$src),
3081                     !strconcat(OpcodeStr, "sd\t{$src, $dst|$dst, $src}"),
3082                     [(set VR128:$dst, (F64Int sse_load_f64:$src))]>;
3083 }
3084
3085 /// sse2_fp_unop_s_avx - AVX SSE2 unops in scalar form.
3086 multiclass sse2_fp_unop_s_avx<bits<8> opc, string OpcodeStr> {
3087   let neverHasSideEffects = 1 in {
3088   def SDr : SDI<opc, MRMSrcReg, (outs FR64:$dst), (ins FR64:$src1, FR64:$src2),
3089                !strconcat(OpcodeStr,
3090                           "sd\t{$src2, $src1, $dst|$dst, $src1, $src2}"), []>;
3091   let mayLoad = 1 in
3092   def SDm : SDI<opc, MRMSrcMem, (outs FR64:$dst), (ins FR64:$src1,f64mem:$src2),
3093                !strconcat(OpcodeStr,
3094                           "sd\t{$src2, $src1, $dst|$dst, $src1, $src2}"), []>;
3095   }
3096   def SDm_Int : SDI<opc, MRMSrcMem, (outs VR128:$dst),
3097                (ins VR128:$src1, sdmem:$src2),
3098                !strconcat(OpcodeStr,
3099                           "sd\t{$src2, $src1, $dst|$dst, $src1, $src2}"), []>;
3100 }
3101
3102 /// sse2_fp_unop_p - SSE2 unops in vector forms.
3103 multiclass sse2_fp_unop_p<bits<8> opc, string OpcodeStr,
3104                           SDNode OpNode> {
3105   def PDr : PDI<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3106               !strconcat(OpcodeStr, "pd\t{$src, $dst|$dst, $src}"),
3107               [(set VR128:$dst, (v2f64 (OpNode VR128:$src)))]>;
3108   def PDm : PDI<opc, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
3109                 !strconcat(OpcodeStr, "pd\t{$src, $dst|$dst, $src}"),
3110                 [(set VR128:$dst, (OpNode (memopv2f64 addr:$src)))]>;
3111 }
3112
3113 /// sse2_fp_unop_p_y - AVX SSE2 256-bit unops in vector forms.
3114 multiclass sse2_fp_unop_p_y<bits<8> opc, string OpcodeStr, SDNode OpNode> {
3115   def PDYr : PDI<opc, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
3116               !strconcat(OpcodeStr, "pd\t{$src, $dst|$dst, $src}"),
3117               [(set VR256:$dst, (v4f64 (OpNode VR256:$src)))]>;
3118   def PDYm : PDI<opc, MRMSrcMem, (outs VR256:$dst), (ins f256mem:$src),
3119                 !strconcat(OpcodeStr, "pd\t{$src, $dst|$dst, $src}"),
3120                 [(set VR256:$dst, (OpNode (memopv4f64 addr:$src)))]>;
3121 }
3122
3123 /// sse2_fp_unop_p_int - SSE2 intrinsic unops in vector forms.
3124 multiclass sse2_fp_unop_p_int<bits<8> opc, string OpcodeStr,
3125                               Intrinsic V2F64Int> {
3126   def PDr_Int : PDI<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3127                     !strconcat(OpcodeStr, "pd\t{$src, $dst|$dst, $src}"),
3128                     [(set VR128:$dst, (V2F64Int VR128:$src))]>;
3129   def PDm_Int : PDI<opc, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
3130                     !strconcat(OpcodeStr, "pd\t{$src, $dst|$dst, $src}"),
3131                     [(set VR128:$dst, (V2F64Int (memopv2f64 addr:$src)))]>;
3132 }
3133
3134 /// sse2_fp_unop_p_y_int - AVX 256-bit intrinsic unops in vector forms.
3135 multiclass sse2_fp_unop_p_y_int<bits<8> opc, string OpcodeStr,
3136                                 Intrinsic V2F64Int> {
3137   def PDYr_Int : PDI<opc, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
3138                     !strconcat(OpcodeStr, "pd\t{$src, $dst|$dst, $src}"),
3139                     [(set VR256:$dst, (V2F64Int VR256:$src))]>;
3140   def PDYm_Int : PDI<opc, MRMSrcMem, (outs VR256:$dst), (ins f256mem:$src),
3141                     !strconcat(OpcodeStr, "pd\t{$src, $dst|$dst, $src}"),
3142                     [(set VR256:$dst, (V2F64Int (memopv4f64 addr:$src)))]>;
3143 }
3144
3145 let Predicates = [HasAVX] in {
3146   // Square root.
3147   defm VSQRT  : sse1_fp_unop_s_avx<0x51, "vsqrt">,
3148                 sse2_fp_unop_s_avx<0x51, "vsqrt">, VEX_4V, VEX_LIG;
3149
3150   defm VSQRT  : sse1_fp_unop_p<0x51, "vsqrt", fsqrt>,
3151                 sse2_fp_unop_p<0x51, "vsqrt", fsqrt>,
3152                 sse1_fp_unop_p_y<0x51, "vsqrt", fsqrt>,
3153                 sse2_fp_unop_p_y<0x51, "vsqrt", fsqrt>,
3154                 sse1_fp_unop_p_int<0x51, "vsqrt", int_x86_sse_sqrt_ps>,
3155                 sse2_fp_unop_p_int<0x51, "vsqrt", int_x86_sse2_sqrt_pd>,
3156                 sse1_fp_unop_p_y_int<0x51, "vsqrt", int_x86_avx_sqrt_ps_256>,
3157                 sse2_fp_unop_p_y_int<0x51, "vsqrt", int_x86_avx_sqrt_pd_256>,
3158                 VEX;
3159
3160   // Reciprocal approximations. Note that these typically require refinement
3161   // in order to obtain suitable precision.
3162   defm VRSQRT : sse1_fp_unop_s_avx<0x52, "vrsqrt">, VEX_4V, VEX_LIG;
3163   defm VRSQRT : sse1_fp_unop_p<0x52, "vrsqrt", X86frsqrt>,
3164                 sse1_fp_unop_p_y<0x52, "vrsqrt", X86frsqrt>,
3165                 sse1_fp_unop_p_y_int<0x52, "vrsqrt", int_x86_avx_rsqrt_ps_256>,
3166                 sse1_fp_unop_p_int<0x52, "vrsqrt", int_x86_sse_rsqrt_ps>, VEX;
3167
3168   defm VRCP   : sse1_fp_unop_s_avx<0x53, "vrcp">, VEX_4V, VEX_LIG;
3169   defm VRCP   : sse1_fp_unop_p<0x53, "vrcp", X86frcp>,
3170                 sse1_fp_unop_p_y<0x53, "vrcp", X86frcp>,
3171                 sse1_fp_unop_p_y_int<0x53, "vrcp", int_x86_avx_rcp_ps_256>,
3172                 sse1_fp_unop_p_int<0x53, "vrcp", int_x86_sse_rcp_ps>, VEX;
3173 }
3174
3175 let AddedComplexity = 1 in {
3176 def : Pat<(f32 (fsqrt FR32:$src)),
3177           (VSQRTSSr (f32 (IMPLICIT_DEF)), FR32:$src)>, Requires<[HasAVX]>;
3178 def : Pat<(f32 (fsqrt (load addr:$src))),
3179           (VSQRTSSm (f32 (IMPLICIT_DEF)), addr:$src)>,
3180           Requires<[HasAVX, OptForSize]>;
3181 def : Pat<(f64 (fsqrt FR64:$src)),
3182           (VSQRTSDr (f64 (IMPLICIT_DEF)), FR64:$src)>, Requires<[HasAVX]>;
3183 def : Pat<(f64 (fsqrt (load addr:$src))),
3184           (VSQRTSDm (f64 (IMPLICIT_DEF)), addr:$src)>,
3185           Requires<[HasAVX, OptForSize]>;
3186
3187 def : Pat<(f32 (X86frsqrt FR32:$src)),
3188           (VRSQRTSSr (f32 (IMPLICIT_DEF)), FR32:$src)>, Requires<[HasAVX]>;
3189 def : Pat<(f32 (X86frsqrt (load addr:$src))),
3190           (VRSQRTSSm (f32 (IMPLICIT_DEF)), addr:$src)>,
3191           Requires<[HasAVX, OptForSize]>;
3192
3193 def : Pat<(f32 (X86frcp FR32:$src)),
3194           (VRCPSSr (f32 (IMPLICIT_DEF)), FR32:$src)>, Requires<[HasAVX]>;
3195 def : Pat<(f32 (X86frcp (load addr:$src))),
3196           (VRCPSSm (f32 (IMPLICIT_DEF)), addr:$src)>,
3197           Requires<[HasAVX, OptForSize]>;
3198 }
3199
3200 let Predicates = [HasAVX], AddedComplexity = 1 in {
3201   def : Pat<(int_x86_sse_sqrt_ss VR128:$src),
3202             (INSERT_SUBREG (v4f32 (IMPLICIT_DEF)),
3203                 (VSQRTSSr (f32 (IMPLICIT_DEF)),
3204                           (EXTRACT_SUBREG (v4f32 VR128:$src), sub_ss)),
3205                 sub_ss)>;
3206   def : Pat<(int_x86_sse_sqrt_ss sse_load_f32:$src),
3207             (VSQRTSSm_Int (v4f32 (IMPLICIT_DEF)), sse_load_f32:$src)>;
3208
3209   def : Pat<(int_x86_sse2_sqrt_sd VR128:$src),
3210             (INSERT_SUBREG (v2f64 (IMPLICIT_DEF)),
3211                 (VSQRTSDr (f64 (IMPLICIT_DEF)),
3212                           (EXTRACT_SUBREG (v2f64 VR128:$src), sub_sd)),
3213                 sub_sd)>;
3214   def : Pat<(int_x86_sse2_sqrt_sd sse_load_f64:$src),
3215             (VSQRTSDm_Int (v2f64 (IMPLICIT_DEF)), sse_load_f64:$src)>;
3216
3217   def : Pat<(int_x86_sse_rsqrt_ss VR128:$src),
3218             (INSERT_SUBREG (v4f32 (IMPLICIT_DEF)),
3219                 (VRSQRTSSr (f32 (IMPLICIT_DEF)),
3220                           (EXTRACT_SUBREG (v4f32 VR128:$src), sub_ss)),
3221                 sub_ss)>;
3222   def : Pat<(int_x86_sse_rsqrt_ss sse_load_f32:$src),
3223             (VRSQRTSSm_Int (v4f32 (IMPLICIT_DEF)), sse_load_f32:$src)>;
3224
3225   def : Pat<(int_x86_sse_rcp_ss VR128:$src),
3226             (INSERT_SUBREG (v4f32 (IMPLICIT_DEF)),
3227                 (VRCPSSr (f32 (IMPLICIT_DEF)),
3228                          (EXTRACT_SUBREG (v4f32 VR128:$src), sub_ss)),
3229                 sub_ss)>;
3230   def : Pat<(int_x86_sse_rcp_ss sse_load_f32:$src),
3231             (VRCPSSm_Int (v4f32 (IMPLICIT_DEF)), sse_load_f32:$src)>;
3232 }
3233
3234 // Square root.
3235 defm SQRT  : sse1_fp_unop_s<0x51, "sqrt",  fsqrt, int_x86_sse_sqrt_ss>,
3236              sse1_fp_unop_p<0x51, "sqrt",  fsqrt>,
3237              sse1_fp_unop_p_int<0x51, "sqrt",  int_x86_sse_sqrt_ps>,
3238              sse2_fp_unop_s<0x51, "sqrt",  fsqrt, int_x86_sse2_sqrt_sd>,
3239              sse2_fp_unop_p<0x51, "sqrt",  fsqrt>,
3240              sse2_fp_unop_p_int<0x51, "sqrt", int_x86_sse2_sqrt_pd>;
3241
3242 // Reciprocal approximations. Note that these typically require refinement
3243 // in order to obtain suitable precision.
3244 defm RSQRT : sse1_fp_unop_s<0x52, "rsqrt", X86frsqrt, int_x86_sse_rsqrt_ss>,
3245              sse1_fp_unop_p<0x52, "rsqrt", X86frsqrt>,
3246              sse1_fp_unop_p_int<0x52, "rsqrt", int_x86_sse_rsqrt_ps>;
3247 defm RCP   : sse1_fp_unop_s<0x53, "rcp", X86frcp, int_x86_sse_rcp_ss>,
3248              sse1_fp_unop_p<0x53, "rcp", X86frcp>,
3249              sse1_fp_unop_p_int<0x53, "rcp", int_x86_sse_rcp_ps>;
3250
3251 // There is no f64 version of the reciprocal approximation instructions.
3252
3253 //===----------------------------------------------------------------------===//
3254 // SSE 1 & 2 - Non-temporal stores
3255 //===----------------------------------------------------------------------===//
3256
3257 let AddedComplexity = 400 in { // Prefer non-temporal versions
3258   def VMOVNTPSmr : VPSI<0x2B, MRMDestMem, (outs),
3259                        (ins f128mem:$dst, VR128:$src),
3260                        "movntps\t{$src, $dst|$dst, $src}",
3261                        [(alignednontemporalstore (v4f32 VR128:$src),
3262                                                  addr:$dst)]>, VEX;
3263   def VMOVNTPDmr : VPDI<0x2B, MRMDestMem, (outs),
3264                        (ins f128mem:$dst, VR128:$src),
3265                        "movntpd\t{$src, $dst|$dst, $src}",
3266                        [(alignednontemporalstore (v2f64 VR128:$src),
3267                                                  addr:$dst)]>, VEX;
3268
3269   let ExeDomain = SSEPackedInt in
3270   def VMOVNTDQmr    : VPDI<0xE7, MRMDestMem, (outs),
3271                            (ins f128mem:$dst, VR128:$src),
3272                            "movntdq\t{$src, $dst|$dst, $src}",
3273                            [(alignednontemporalstore (v2i64 VR128:$src),
3274                                                      addr:$dst)]>, VEX;
3275
3276   def : Pat<(alignednontemporalstore (v2i64 VR128:$src), addr:$dst),
3277             (VMOVNTDQmr addr:$dst, VR128:$src)>, Requires<[HasAVX]>;
3278
3279   def VMOVNTPSYmr : VPSI<0x2B, MRMDestMem, (outs),
3280                        (ins f256mem:$dst, VR256:$src),
3281                        "movntps\t{$src, $dst|$dst, $src}",
3282                        [(alignednontemporalstore (v8f32 VR256:$src),
3283                                                  addr:$dst)]>, VEX;
3284   def VMOVNTPDYmr : VPDI<0x2B, MRMDestMem, (outs),
3285                        (ins f256mem:$dst, VR256:$src),
3286                        "movntpd\t{$src, $dst|$dst, $src}",
3287                        [(alignednontemporalstore (v4f64 VR256:$src),
3288                                                  addr:$dst)]>, VEX;
3289   let ExeDomain = SSEPackedInt in
3290   def VMOVNTDQYmr : VPDI<0xE7, MRMDestMem, (outs),
3291                       (ins f256mem:$dst, VR256:$src),
3292                       "movntdq\t{$src, $dst|$dst, $src}",
3293                       [(alignednontemporalstore (v4i64 VR256:$src),
3294                                                 addr:$dst)]>, VEX;
3295 }
3296
3297 def : Pat<(int_x86_avx_movnt_dq_256 addr:$dst, VR256:$src),
3298           (VMOVNTDQYmr addr:$dst, VR256:$src)>;
3299 def : Pat<(int_x86_avx_movnt_pd_256 addr:$dst, VR256:$src),
3300           (VMOVNTPDYmr addr:$dst, VR256:$src)>;
3301 def : Pat<(int_x86_avx_movnt_ps_256 addr:$dst, VR256:$src),
3302           (VMOVNTPSYmr addr:$dst, VR256:$src)>;
3303
3304 let AddedComplexity = 400 in { // Prefer non-temporal versions
3305 def MOVNTPSmr : PSI<0x2B, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
3306                     "movntps\t{$src, $dst|$dst, $src}",
3307                     [(alignednontemporalstore (v4f32 VR128:$src), addr:$dst)]>;
3308 def MOVNTPDmr : PDI<0x2B, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
3309                     "movntpd\t{$src, $dst|$dst, $src}",
3310                     [(alignednontemporalstore(v2f64 VR128:$src), addr:$dst)]>;
3311
3312 let ExeDomain = SSEPackedInt in
3313 def MOVNTDQmr : PDI<0xE7, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
3314                     "movntdq\t{$src, $dst|$dst, $src}",
3315                     [(alignednontemporalstore (v2i64 VR128:$src), addr:$dst)]>;
3316
3317 def : Pat<(alignednontemporalstore (v2i64 VR128:$src), addr:$dst),
3318           (MOVNTDQmr addr:$dst, VR128:$src)>, Requires<[HasSSE2]>;
3319
3320 // There is no AVX form for instructions below this point
3321 def MOVNTImr : I<0xC3, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
3322                  "movnti{l}\t{$src, $dst|$dst, $src}",
3323                  [(nontemporalstore (i32 GR32:$src), addr:$dst)]>,
3324                TB, Requires<[HasSSE2]>;
3325 def MOVNTI_64mr : RI<0xC3, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
3326                      "movnti{q}\t{$src, $dst|$dst, $src}",
3327                      [(nontemporalstore (i64 GR64:$src), addr:$dst)]>,
3328                   TB, Requires<[HasSSE2]>;
3329 }
3330
3331 //===----------------------------------------------------------------------===//
3332 // SSE 1 & 2 - Prefetch and memory fence
3333 //===----------------------------------------------------------------------===//
3334
3335 // Prefetch intrinsic.
3336 let Predicates = [HasSSE1] in {
3337 def PREFETCHT0   : I<0x18, MRM1m, (outs), (ins i8mem:$src),
3338     "prefetcht0\t$src", [(prefetch addr:$src, imm, (i32 3), (i32 1))]>, TB;
3339 def PREFETCHT1   : I<0x18, MRM2m, (outs), (ins i8mem:$src),
3340     "prefetcht1\t$src", [(prefetch addr:$src, imm, (i32 2), (i32 1))]>, TB;
3341 def PREFETCHT2   : I<0x18, MRM3m, (outs), (ins i8mem:$src),
3342     "prefetcht2\t$src", [(prefetch addr:$src, imm, (i32 1), (i32 1))]>, TB;
3343 def PREFETCHNTA  : I<0x18, MRM0m, (outs), (ins i8mem:$src),
3344     "prefetchnta\t$src", [(prefetch addr:$src, imm, (i32 0), (i32 1))]>, TB;
3345 }
3346
3347 // Flush cache
3348 def CLFLUSH : I<0xAE, MRM7m, (outs), (ins i8mem:$src),
3349                "clflush\t$src", [(int_x86_sse2_clflush addr:$src)]>,
3350               TB, Requires<[HasSSE2]>;
3351
3352 // Pause. This "instruction" is encoded as "rep; nop", so even though it
3353 // was introduced with SSE2, it's backward compatible.
3354 def PAUSE : I<0x90, RawFrm, (outs), (ins), "pause", []>, REP;
3355
3356 // Load, store, and memory fence
3357 def SFENCE : I<0xAE, MRM_F8, (outs), (ins),
3358                "sfence", [(int_x86_sse_sfence)]>, TB, Requires<[HasSSE1]>;
3359 def LFENCE : I<0xAE, MRM_E8, (outs), (ins),
3360                "lfence", [(int_x86_sse2_lfence)]>, TB, Requires<[HasSSE2]>;
3361 def MFENCE : I<0xAE, MRM_F0, (outs), (ins),
3362                "mfence", [(int_x86_sse2_mfence)]>, TB, Requires<[HasSSE2]>;
3363
3364 def : Pat<(X86SFence), (SFENCE)>;
3365 def : Pat<(X86LFence), (LFENCE)>;
3366 def : Pat<(X86MFence), (MFENCE)>;
3367
3368 //===----------------------------------------------------------------------===//
3369 // SSE 1 & 2 - Load/Store XCSR register
3370 //===----------------------------------------------------------------------===//
3371
3372 def VLDMXCSR : VPSI<0xAE, MRM2m, (outs), (ins i32mem:$src),
3373                   "ldmxcsr\t$src", [(int_x86_sse_ldmxcsr addr:$src)]>, VEX;
3374 def VSTMXCSR : VPSI<0xAE, MRM3m, (outs), (ins i32mem:$dst),
3375                   "stmxcsr\t$dst", [(int_x86_sse_stmxcsr addr:$dst)]>, VEX;
3376
3377 def LDMXCSR : PSI<0xAE, MRM2m, (outs), (ins i32mem:$src),
3378                   "ldmxcsr\t$src", [(int_x86_sse_ldmxcsr addr:$src)]>;
3379 def STMXCSR : PSI<0xAE, MRM3m, (outs), (ins i32mem:$dst),
3380                   "stmxcsr\t$dst", [(int_x86_sse_stmxcsr addr:$dst)]>;
3381
3382 //===---------------------------------------------------------------------===//
3383 // SSE2 - Move Aligned/Unaligned Packed Integer Instructions
3384 //===---------------------------------------------------------------------===//
3385
3386 let ExeDomain = SSEPackedInt in { // SSE integer instructions
3387
3388 let neverHasSideEffects = 1 in {
3389 def VMOVDQArr  : VPDI<0x6F, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3390                     "movdqa\t{$src, $dst|$dst, $src}", []>, VEX;
3391 def VMOVDQAYrr : VPDI<0x6F, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
3392                     "movdqa\t{$src, $dst|$dst, $src}", []>, VEX;
3393 }
3394 def VMOVDQUrr  : VSSI<0x6F, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3395                     "movdqu\t{$src, $dst|$dst, $src}", []>, VEX;
3396 def VMOVDQUYrr : VSSI<0x6F, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
3397                     "movdqu\t{$src, $dst|$dst, $src}", []>, VEX;
3398
3399 // For Disassembler
3400 let isCodeGenOnly = 1 in {
3401 def VMOVDQArr_REV  : VPDI<0x7F, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
3402                         "movdqa\t{$src, $dst|$dst, $src}", []>, VEX;
3403 def VMOVDQAYrr_REV : VPDI<0x7F, MRMDestReg, (outs VR256:$dst), (ins VR256:$src),
3404                         "movdqa\t{$src, $dst|$dst, $src}", []>, VEX;
3405 def VMOVDQUrr_REV  : VSSI<0x7F, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
3406                         "movdqu\t{$src, $dst|$dst, $src}", []>, VEX;
3407 def VMOVDQUYrr_REV : VSSI<0x7F, MRMDestReg, (outs VR256:$dst), (ins VR256:$src),
3408                         "movdqu\t{$src, $dst|$dst, $src}", []>, VEX;
3409 }
3410
3411 let canFoldAsLoad = 1, mayLoad = 1 in {
3412 def VMOVDQArm  : VPDI<0x6F, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
3413                    "movdqa\t{$src, $dst|$dst, $src}", []>, VEX;
3414 def VMOVDQAYrm : VPDI<0x6F, MRMSrcMem, (outs VR256:$dst), (ins i256mem:$src),
3415                    "movdqa\t{$src, $dst|$dst, $src}", []>, VEX;
3416 let Predicates = [HasAVX] in {
3417   def VMOVDQUrm  : I<0x6F, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
3418                     "vmovdqu\t{$src, $dst|$dst, $src}",[]>, XS, VEX;
3419   def VMOVDQUYrm : I<0x6F, MRMSrcMem, (outs VR256:$dst), (ins i256mem:$src),
3420                     "vmovdqu\t{$src, $dst|$dst, $src}",[]>, XS, VEX;
3421 }
3422 }
3423
3424 let mayStore = 1 in {
3425 def VMOVDQAmr  : VPDI<0x7F, MRMDestMem, (outs),
3426                      (ins i128mem:$dst, VR128:$src),
3427                      "movdqa\t{$src, $dst|$dst, $src}", []>, VEX;
3428 def VMOVDQAYmr : VPDI<0x7F, MRMDestMem, (outs),
3429                      (ins i256mem:$dst, VR256:$src),
3430                      "movdqa\t{$src, $dst|$dst, $src}", []>, VEX;
3431 let Predicates = [HasAVX] in {
3432 def VMOVDQUmr  : I<0x7F, MRMDestMem, (outs), (ins i128mem:$dst, VR128:$src),
3433                   "vmovdqu\t{$src, $dst|$dst, $src}",[]>, XS, VEX;
3434 def VMOVDQUYmr : I<0x7F, MRMDestMem, (outs), (ins i256mem:$dst, VR256:$src),
3435                   "vmovdqu\t{$src, $dst|$dst, $src}",[]>, XS, VEX;
3436 }
3437 }
3438
3439 let neverHasSideEffects = 1 in
3440 def MOVDQArr : PDI<0x6F, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3441                    "movdqa\t{$src, $dst|$dst, $src}", []>;
3442
3443 def MOVDQUrr :   I<0x6F, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3444                    "movdqu\t{$src, $dst|$dst, $src}",
3445                    []>, XS, Requires<[HasSSE2]>;
3446
3447 // For Disassembler
3448 let isCodeGenOnly = 1 in {
3449 def MOVDQArr_REV : PDI<0x7F, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
3450                        "movdqa\t{$src, $dst|$dst, $src}", []>;
3451
3452 def MOVDQUrr_REV :   I<0x7F, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
3453                        "movdqu\t{$src, $dst|$dst, $src}",
3454                        []>, XS, Requires<[HasSSE2]>;
3455 }
3456
3457 let canFoldAsLoad = 1, mayLoad = 1 in {
3458 def MOVDQArm : PDI<0x6F, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
3459                    "movdqa\t{$src, $dst|$dst, $src}",
3460                    [/*(set VR128:$dst, (alignedloadv2i64 addr:$src))*/]>;
3461 def MOVDQUrm :   I<0x6F, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
3462                    "movdqu\t{$src, $dst|$dst, $src}",
3463                    [/*(set VR128:$dst, (loadv2i64 addr:$src))*/]>,
3464                  XS, Requires<[HasSSE2]>;
3465 }
3466
3467 let mayStore = 1 in {
3468 def MOVDQAmr : PDI<0x7F, MRMDestMem, (outs), (ins i128mem:$dst, VR128:$src),
3469                    "movdqa\t{$src, $dst|$dst, $src}",
3470                    [/*(alignedstore (v2i64 VR128:$src), addr:$dst)*/]>;
3471 def MOVDQUmr :   I<0x7F, MRMDestMem, (outs), (ins i128mem:$dst, VR128:$src),
3472                    "movdqu\t{$src, $dst|$dst, $src}",
3473                    [/*(store (v2i64 VR128:$src), addr:$dst)*/]>,
3474                  XS, Requires<[HasSSE2]>;
3475 }
3476
3477 // Intrinsic forms of MOVDQU load and store
3478 def VMOVDQUmr_Int : I<0x7F, MRMDestMem, (outs), (ins i128mem:$dst, VR128:$src),
3479                        "vmovdqu\t{$src, $dst|$dst, $src}",
3480                        [(int_x86_sse2_storeu_dq addr:$dst, VR128:$src)]>,
3481                      XS, VEX, Requires<[HasAVX]>;
3482
3483 def MOVDQUmr_Int :   I<0x7F, MRMDestMem, (outs), (ins i128mem:$dst, VR128:$src),
3484                        "movdqu\t{$src, $dst|$dst, $src}",
3485                        [(int_x86_sse2_storeu_dq addr:$dst, VR128:$src)]>,
3486                      XS, Requires<[HasSSE2]>;
3487
3488 } // ExeDomain = SSEPackedInt
3489
3490 let Predicates = [HasAVX] in {
3491   def : Pat<(int_x86_avx_loadu_dq_256 addr:$src), (VMOVDQUYrm addr:$src)>;
3492   def : Pat<(int_x86_avx_storeu_dq_256 addr:$dst, VR256:$src),
3493             (VMOVDQUYmr addr:$dst, VR256:$src)>;
3494 }
3495
3496 //===---------------------------------------------------------------------===//
3497 // SSE2 - Packed Integer Arithmetic Instructions
3498 //===---------------------------------------------------------------------===//
3499
3500 let ExeDomain = SSEPackedInt in { // SSE integer instructions
3501
3502 multiclass PDI_binop_rm_int<bits<8> opc, string OpcodeStr, Intrinsic IntId,
3503                             RegisterClass RC, PatFrag memop_frag,
3504                             X86MemOperand x86memop, bit IsCommutable = 0,
3505                             bit Is2Addr = 1> {
3506   let isCommutable = IsCommutable in
3507   def rr : PDI<opc, MRMSrcReg, (outs RC:$dst),
3508        (ins RC:$src1, RC:$src2),
3509        !if(Is2Addr,
3510            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
3511            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
3512        [(set RC:$dst, (IntId RC:$src1, RC:$src2))]>;
3513   def rm : PDI<opc, MRMSrcMem, (outs RC:$dst),
3514        (ins RC:$src1, x86memop:$src2),
3515        !if(Is2Addr,
3516            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
3517            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
3518        [(set RC:$dst, (IntId RC:$src1, (bitconvert (memop_frag addr:$src2))))]>;
3519 }
3520
3521 multiclass PDI_binop_rmi_int<bits<8> opc, bits<8> opc2, Format ImmForm,
3522                              string OpcodeStr, Intrinsic IntId,
3523                              Intrinsic IntId2, RegisterClass RC,
3524                              bit Is2Addr = 1> {
3525   // src2 is always 128-bit
3526   def rr : PDI<opc, MRMSrcReg, (outs RC:$dst),
3527        (ins RC:$src1, VR128:$src2),
3528        !if(Is2Addr,
3529            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
3530            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
3531        [(set RC:$dst, (IntId RC:$src1, VR128:$src2))]>;
3532   def rm : PDI<opc, MRMSrcMem, (outs RC:$dst),
3533        (ins RC:$src1, i128mem:$src2),
3534        !if(Is2Addr,
3535            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
3536            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
3537        [(set RC:$dst, (IntId RC:$src1, (bitconvert (memopv2i64 addr:$src2))))]>;
3538   def ri : PDIi8<opc2, ImmForm, (outs RC:$dst),
3539        (ins RC:$src1, i32i8imm:$src2),
3540        !if(Is2Addr,
3541            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
3542            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
3543        [(set RC:$dst, (IntId2 RC:$src1, (i32 imm:$src2)))]>;
3544 }
3545
3546 } // ExeDomain = SSEPackedInt
3547
3548 // 128-bit Integer Arithmetic
3549
3550 let Predicates = [HasAVX] in {
3551 defm VPADDB  : PDI_binop_rm<0xFC, "vpaddb", add, v16i8, VR128, memopv2i64,
3552                             i128mem, 1, 0 /*3addr*/>, VEX_4V;
3553 defm VPADDW  : PDI_binop_rm<0xFD, "vpaddw", add, v8i16, VR128, memopv2i64,
3554                             i128mem, 1, 0>, VEX_4V;
3555 defm VPADDD  : PDI_binop_rm<0xFE, "vpaddd", add, v4i32, VR128, memopv2i64,
3556                             i128mem, 1, 0>, VEX_4V;
3557 defm VPADDQ  : PDI_binop_rm<0xD4, "vpaddq", add, v2i64, VR128, memopv2i64,
3558                             i128mem, 1, 0>, VEX_4V;
3559 defm VPMULLW : PDI_binop_rm<0xD5, "vpmullw", mul, v8i16, VR128, memopv2i64,
3560                             i128mem, 1, 0>, VEX_4V;
3561 defm VPSUBB : PDI_binop_rm<0xF8, "vpsubb", sub, v16i8, VR128, memopv2i64,
3562                             i128mem, 0, 0>, VEX_4V;
3563 defm VPSUBW : PDI_binop_rm<0xF9, "vpsubw", sub, v8i16, VR128, memopv2i64,
3564                             i128mem, 0, 0>, VEX_4V;
3565 defm VPSUBD : PDI_binop_rm<0xFA, "vpsubd", sub, v4i32, VR128, memopv2i64,
3566                             i128mem, 0, 0>, VEX_4V;
3567 defm VPSUBQ : PDI_binop_rm<0xFB, "vpsubq", sub, v2i64, VR128, memopv2i64,
3568                             i128mem, 0, 0>, VEX_4V;
3569
3570 // Intrinsic forms
3571 defm VPSUBSB  : PDI_binop_rm_int<0xE8, "vpsubsb" , int_x86_sse2_psubs_b,
3572                                  VR128, memopv2i64, i128mem, 0, 0>, VEX_4V;
3573 defm VPSUBSW  : PDI_binop_rm_int<0xE9, "vpsubsw" , int_x86_sse2_psubs_w,
3574                                  VR128, memopv2i64, i128mem, 0, 0>, VEX_4V;
3575 defm VPSUBUSB : PDI_binop_rm_int<0xD8, "vpsubusb", int_x86_sse2_psubus_b,
3576                                  VR128, memopv2i64, i128mem, 0, 0>, VEX_4V;
3577 defm VPSUBUSW : PDI_binop_rm_int<0xD9, "vpsubusw", int_x86_sse2_psubus_w,
3578                                  VR128, memopv2i64, i128mem, 0, 0>, VEX_4V;
3579 defm VPADDSB  : PDI_binop_rm_int<0xEC, "vpaddsb" , int_x86_sse2_padds_b,
3580                                  VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3581 defm VPADDSW  : PDI_binop_rm_int<0xED, "vpaddsw" , int_x86_sse2_padds_w,
3582                                  VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3583 defm VPADDUSB : PDI_binop_rm_int<0xDC, "vpaddusb", int_x86_sse2_paddus_b,
3584                                  VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3585 defm VPADDUSW : PDI_binop_rm_int<0xDD, "vpaddusw", int_x86_sse2_paddus_w,
3586                                  VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3587 defm VPMULHUW : PDI_binop_rm_int<0xE4, "vpmulhuw", int_x86_sse2_pmulhu_w,
3588                                  VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3589 defm VPMULHW  : PDI_binop_rm_int<0xE5, "vpmulhw" , int_x86_sse2_pmulh_w,
3590                                  VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3591 defm VPMULUDQ : PDI_binop_rm_int<0xF4, "vpmuludq", int_x86_sse2_pmulu_dq,
3592                                  VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3593 defm VPMADDWD : PDI_binop_rm_int<0xF5, "vpmaddwd", int_x86_sse2_pmadd_wd,
3594                                  VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3595 defm VPAVGB   : PDI_binop_rm_int<0xE0, "vpavgb", int_x86_sse2_pavg_b,
3596                                  VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3597 defm VPAVGW   : PDI_binop_rm_int<0xE3, "vpavgw", int_x86_sse2_pavg_w,
3598                                  VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3599 defm VPMINUB  : PDI_binop_rm_int<0xDA, "vpminub", int_x86_sse2_pminu_b,
3600                                  VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3601 defm VPMINSW  : PDI_binop_rm_int<0xEA, "vpminsw", int_x86_sse2_pmins_w,
3602                                  VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3603 defm VPMAXUB  : PDI_binop_rm_int<0xDE, "vpmaxub", int_x86_sse2_pmaxu_b,
3604                                  VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3605 defm VPMAXSW  : PDI_binop_rm_int<0xEE, "vpmaxsw", int_x86_sse2_pmaxs_w,
3606                                  VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3607 defm VPSADBW  : PDI_binop_rm_int<0xF6, "vpsadbw", int_x86_sse2_psad_bw,
3608                                  VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3609 }
3610
3611 let Predicates = [HasAVX2] in {
3612 defm VPADDBY  : PDI_binop_rm<0xFC, "vpaddb", add, v32i8, VR256, memopv4i64,
3613                              i256mem, 1, 0>, VEX_4V;
3614 defm VPADDWY  : PDI_binop_rm<0xFD, "vpaddw", add, v16i16, VR256, memopv4i64,
3615                              i256mem, 1, 0>, VEX_4V;
3616 defm VPADDDY  : PDI_binop_rm<0xFE, "vpaddd", add, v8i32, VR256, memopv4i64,
3617                              i256mem, 1, 0>, VEX_4V;
3618 defm VPADDQY  : PDI_binop_rm<0xD4, "vpaddq", add, v4i64, VR256, memopv4i64,
3619                              i256mem, 1, 0>, VEX_4V;
3620 defm VPMULLWY : PDI_binop_rm<0xD5, "vpmullw", mul, v16i16, VR256, memopv4i64,
3621                              i256mem, 1, 0>, VEX_4V;
3622 defm VPSUBBY  : PDI_binop_rm<0xF8, "vpsubb", sub, v32i8, VR256, memopv4i64,
3623                              i256mem, 0, 0>, VEX_4V;
3624 defm VPSUBWY  : PDI_binop_rm<0xF9, "vpsubw", sub, v16i16,VR256, memopv4i64,
3625                              i256mem, 0, 0>, VEX_4V;
3626 defm VPSUBDY  : PDI_binop_rm<0xFA, "vpsubd", sub, v8i32, VR256, memopv4i64,
3627                              i256mem, 0, 0>, VEX_4V;
3628 defm VPSUBQY  : PDI_binop_rm<0xFB, "vpsubq", sub, v4i64, VR256, memopv4i64,
3629                              i256mem, 0, 0>, VEX_4V;
3630
3631 // Intrinsic forms
3632 defm VPSUBSBY  : PDI_binop_rm_int<0xE8, "vpsubsb" , int_x86_avx2_psubs_b,
3633                                   VR256, memopv4i64, i256mem, 0, 0>, VEX_4V;
3634 defm VPSUBSWY  : PDI_binop_rm_int<0xE9, "vpsubsw" , int_x86_avx2_psubs_w,
3635                                   VR256, memopv4i64, i256mem, 0, 0>, VEX_4V;
3636 defm VPSUBUSBY : PDI_binop_rm_int<0xD8, "vpsubusb", int_x86_avx2_psubus_b,
3637                                   VR256, memopv4i64, i256mem, 0, 0>, VEX_4V;
3638 defm VPSUBUSWY : PDI_binop_rm_int<0xD9, "vpsubusw", int_x86_avx2_psubus_w,
3639                                   VR256, memopv4i64, i256mem, 0, 0>, VEX_4V;
3640 defm VPADDSBY  : PDI_binop_rm_int<0xEC, "vpaddsb" , int_x86_avx2_padds_b,
3641                                   VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3642 defm VPADDSWY  : PDI_binop_rm_int<0xED, "vpaddsw" , int_x86_avx2_padds_w,
3643                                   VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3644 defm VPADDUSBY : PDI_binop_rm_int<0xDC, "vpaddusb", int_x86_avx2_paddus_b,
3645                                   VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3646 defm VPADDUSWY : PDI_binop_rm_int<0xDD, "vpaddusw", int_x86_avx2_paddus_w,
3647                                   VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3648 defm VPMULHUWY : PDI_binop_rm_int<0xE4, "vpmulhuw", int_x86_avx2_pmulhu_w,
3649                                   VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3650 defm VPMULHWY  : PDI_binop_rm_int<0xE5, "vpmulhw" , int_x86_avx2_pmulh_w,
3651                                   VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3652 defm VPMULUDQY : PDI_binop_rm_int<0xF4, "vpmuludq", int_x86_avx2_pmulu_dq,
3653                                   VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3654 defm VPMADDWDY : PDI_binop_rm_int<0xF5, "vpmaddwd", int_x86_avx2_pmadd_wd,
3655                                   VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3656 defm VPAVGBY   : PDI_binop_rm_int<0xE0, "vpavgb", int_x86_avx2_pavg_b,
3657                                   VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3658 defm VPAVGWY   : PDI_binop_rm_int<0xE3, "vpavgw", int_x86_avx2_pavg_w,
3659                                   VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3660 defm VPMINUBY  : PDI_binop_rm_int<0xDA, "vpminub", int_x86_avx2_pminu_b,
3661                                   VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3662 defm VPMINSWY  : PDI_binop_rm_int<0xEA, "vpminsw", int_x86_avx2_pmins_w,
3663                                   VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3664 defm VPMAXUBY  : PDI_binop_rm_int<0xDE, "vpmaxub", int_x86_avx2_pmaxu_b,
3665                                   VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3666 defm VPMAXSWY  : PDI_binop_rm_int<0xEE, "vpmaxsw", int_x86_avx2_pmaxs_w,
3667                                   VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3668 defm VPSADBWY  : PDI_binop_rm_int<0xF6, "vpsadbw", int_x86_avx2_psad_bw,
3669                                   VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3670 }
3671
3672 let Constraints = "$src1 = $dst" in {
3673 defm PADDB  : PDI_binop_rm<0xFC, "paddb", add, v16i8, VR128, memopv2i64,
3674                            i128mem, 1>;
3675 defm PADDW  : PDI_binop_rm<0xFD, "paddw", add, v8i16, VR128, memopv2i64,
3676                            i128mem, 1>;
3677 defm PADDD  : PDI_binop_rm<0xFE, "paddd", add, v4i32, VR128, memopv2i64,
3678                            i128mem, 1>;
3679 defm PADDQ  : PDI_binop_rm<0xD4, "paddq", add, v2i64, VR128, memopv2i64,
3680                            i128mem, 1>;
3681 defm PMULLW : PDI_binop_rm<0xD5, "pmullw", mul, v8i16, VR128, memopv2i64,
3682                            i128mem, 1>;
3683 defm PSUBB : PDI_binop_rm<0xF8, "psubb", sub, v16i8, VR128, memopv2i64,
3684                           i128mem>;
3685 defm PSUBW : PDI_binop_rm<0xF9, "psubw", sub, v8i16, VR128, memopv2i64,
3686                           i128mem>;
3687 defm PSUBD : PDI_binop_rm<0xFA, "psubd", sub, v4i32, VR128, memopv2i64,
3688                           i128mem>;
3689 defm PSUBQ : PDI_binop_rm<0xFB, "psubq", sub, v2i64, VR128, memopv2i64,
3690                           i128mem>;
3691
3692 // Intrinsic forms
3693 defm PSUBSB  : PDI_binop_rm_int<0xE8, "psubsb" , int_x86_sse2_psubs_b,
3694                                 VR128, memopv2i64, i128mem>;
3695 defm PSUBSW  : PDI_binop_rm_int<0xE9, "psubsw" , int_x86_sse2_psubs_w,
3696                                 VR128, memopv2i64, i128mem>;
3697 defm PSUBUSB : PDI_binop_rm_int<0xD8, "psubusb", int_x86_sse2_psubus_b,
3698                                 VR128, memopv2i64, i128mem>;
3699 defm PSUBUSW : PDI_binop_rm_int<0xD9, "psubusw", int_x86_sse2_psubus_w,
3700                                 VR128, memopv2i64, i128mem>;
3701 defm PADDSB  : PDI_binop_rm_int<0xEC, "paddsb" , int_x86_sse2_padds_b,
3702                                 VR128, memopv2i64, i128mem, 1>;
3703 defm PADDSW  : PDI_binop_rm_int<0xED, "paddsw" , int_x86_sse2_padds_w,
3704                                 VR128, memopv2i64, i128mem, 1>;
3705 defm PADDUSB : PDI_binop_rm_int<0xDC, "paddusb", int_x86_sse2_paddus_b,
3706                                 VR128, memopv2i64, i128mem, 1>;
3707 defm PADDUSW : PDI_binop_rm_int<0xDD, "paddusw", int_x86_sse2_paddus_w,
3708                                 VR128, memopv2i64, i128mem, 1>;
3709 defm PMULHUW : PDI_binop_rm_int<0xE4, "pmulhuw", int_x86_sse2_pmulhu_w,
3710                                 VR128, memopv2i64, i128mem, 1>;
3711 defm PMULHW  : PDI_binop_rm_int<0xE5, "pmulhw" , int_x86_sse2_pmulh_w,
3712                                 VR128, memopv2i64, i128mem, 1>;
3713 defm PMULUDQ : PDI_binop_rm_int<0xF4, "pmuludq", int_x86_sse2_pmulu_dq,
3714                                 VR128, memopv2i64, i128mem, 1>;
3715 defm PMADDWD : PDI_binop_rm_int<0xF5, "pmaddwd", int_x86_sse2_pmadd_wd,
3716                                 VR128, memopv2i64, i128mem, 1>;
3717 defm PAVGB   : PDI_binop_rm_int<0xE0, "pavgb", int_x86_sse2_pavg_b,
3718                                 VR128, memopv2i64, i128mem, 1>;
3719 defm PAVGW   : PDI_binop_rm_int<0xE3, "pavgw", int_x86_sse2_pavg_w,
3720                                 VR128, memopv2i64, i128mem, 1>;
3721 defm PMINUB  : PDI_binop_rm_int<0xDA, "pminub", int_x86_sse2_pminu_b,
3722                                 VR128, memopv2i64, i128mem, 1>;
3723 defm PMINSW  : PDI_binop_rm_int<0xEA, "pminsw", int_x86_sse2_pmins_w,
3724                                 VR128, memopv2i64, i128mem, 1>;
3725 defm PMAXUB  : PDI_binop_rm_int<0xDE, "pmaxub", int_x86_sse2_pmaxu_b,
3726                                 VR128, memopv2i64, i128mem, 1>;
3727 defm PMAXSW  : PDI_binop_rm_int<0xEE, "pmaxsw", int_x86_sse2_pmaxs_w,
3728                                 VR128, memopv2i64, i128mem, 1>;
3729 defm PSADBW  : PDI_binop_rm_int<0xF6, "psadbw", int_x86_sse2_psad_bw,
3730                                 VR128, memopv2i64, i128mem, 1>;
3731
3732 } // Constraints = "$src1 = $dst"
3733
3734 //===---------------------------------------------------------------------===//
3735 // SSE2 - Packed Integer Logical Instructions
3736 //===---------------------------------------------------------------------===//
3737
3738 let Predicates = [HasAVX] in {
3739 defm VPSLLW : PDI_binop_rmi_int<0xF1, 0x71, MRM6r, "vpsllw",
3740                                 int_x86_sse2_psll_w, int_x86_sse2_pslli_w,
3741                                 VR128, 0>, VEX_4V;
3742 defm VPSLLD : PDI_binop_rmi_int<0xF2, 0x72, MRM6r, "vpslld",
3743                                 int_x86_sse2_psll_d, int_x86_sse2_pslli_d,
3744                                 VR128, 0>, VEX_4V;
3745 defm VPSLLQ : PDI_binop_rmi_int<0xF3, 0x73, MRM6r, "vpsllq",
3746                                 int_x86_sse2_psll_q, int_x86_sse2_pslli_q,
3747                                 VR128, 0>, VEX_4V;
3748
3749 defm VPSRLW : PDI_binop_rmi_int<0xD1, 0x71, MRM2r, "vpsrlw",
3750                                 int_x86_sse2_psrl_w, int_x86_sse2_psrli_w,
3751                                 VR128, 0>, VEX_4V;
3752 defm VPSRLD : PDI_binop_rmi_int<0xD2, 0x72, MRM2r, "vpsrld",
3753                                 int_x86_sse2_psrl_d, int_x86_sse2_psrli_d,
3754                                 VR128, 0>, VEX_4V;
3755 defm VPSRLQ : PDI_binop_rmi_int<0xD3, 0x73, MRM2r, "vpsrlq",
3756                                 int_x86_sse2_psrl_q, int_x86_sse2_psrli_q,
3757                                 VR128, 0>, VEX_4V;
3758
3759 defm VPSRAW : PDI_binop_rmi_int<0xE1, 0x71, MRM4r, "vpsraw",
3760                                 int_x86_sse2_psra_w, int_x86_sse2_psrai_w,
3761                                 VR128, 0>, VEX_4V;
3762 defm VPSRAD : PDI_binop_rmi_int<0xE2, 0x72, MRM4r, "vpsrad",
3763                                 int_x86_sse2_psra_d, int_x86_sse2_psrai_d,
3764                                 VR128, 0>, VEX_4V;
3765
3766 let ExeDomain = SSEPackedInt in {
3767   let neverHasSideEffects = 1 in {
3768     // 128-bit logical shifts.
3769     def VPSLLDQri : PDIi8<0x73, MRM7r,
3770                       (outs VR128:$dst), (ins VR128:$src1, i32i8imm:$src2),
3771                       "vpslldq\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>,
3772                       VEX_4V;
3773     def VPSRLDQri : PDIi8<0x73, MRM3r,
3774                       (outs VR128:$dst), (ins VR128:$src1, i32i8imm:$src2),
3775                       "vpsrldq\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>,
3776                       VEX_4V;
3777     // PSRADQri doesn't exist in SSE[1-3].
3778   }
3779 }
3780 }
3781
3782 let Predicates = [HasAVX2] in {
3783 defm VPSLLWY : PDI_binop_rmi_int<0xF1, 0x71, MRM6r, "vpsllw",
3784                                  int_x86_avx2_psll_w, int_x86_avx2_pslli_w,
3785                                  VR256, 0>, VEX_4V;
3786 defm VPSLLDY : PDI_binop_rmi_int<0xF2, 0x72, MRM6r, "vpslld",
3787                                  int_x86_avx2_psll_d, int_x86_avx2_pslli_d,
3788                                  VR256, 0>, VEX_4V;
3789 defm VPSLLQY : PDI_binop_rmi_int<0xF3, 0x73, MRM6r, "vpsllq",
3790                                  int_x86_avx2_psll_q, int_x86_avx2_pslli_q,
3791                                  VR256, 0>, VEX_4V;
3792
3793 defm VPSRLWY : PDI_binop_rmi_int<0xD1, 0x71, MRM2r, "vpsrlw",
3794                                  int_x86_avx2_psrl_w, int_x86_avx2_psrli_w,
3795                                  VR256, 0>, VEX_4V;
3796 defm VPSRLDY : PDI_binop_rmi_int<0xD2, 0x72, MRM2r, "vpsrld",
3797                                  int_x86_avx2_psrl_d, int_x86_avx2_psrli_d,
3798                                  VR256, 0>, VEX_4V;
3799 defm VPSRLQY : PDI_binop_rmi_int<0xD3, 0x73, MRM2r, "vpsrlq",
3800                                  int_x86_avx2_psrl_q, int_x86_avx2_psrli_q,
3801                                  VR256, 0>, VEX_4V;
3802
3803 defm VPSRAWY : PDI_binop_rmi_int<0xE1, 0x71, MRM4r, "vpsraw",
3804                                  int_x86_avx2_psra_w, int_x86_avx2_psrai_w,
3805                                  VR256, 0>, VEX_4V;
3806 defm VPSRADY : PDI_binop_rmi_int<0xE2, 0x72, MRM4r, "vpsrad",
3807                                  int_x86_avx2_psra_d, int_x86_avx2_psrai_d,
3808                                  VR256, 0>, VEX_4V;
3809
3810 let ExeDomain = SSEPackedInt in {
3811   let neverHasSideEffects = 1 in {
3812     // 128-bit logical shifts.
3813     def VPSLLDQYri : PDIi8<0x73, MRM7r,
3814                       (outs VR256:$dst), (ins VR256:$src1, i32i8imm:$src2),
3815                       "vpslldq\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>,
3816                       VEX_4V;
3817     def VPSRLDQYri : PDIi8<0x73, MRM3r,
3818                       (outs VR256:$dst), (ins VR256:$src1, i32i8imm:$src2),
3819                       "vpsrldq\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>,
3820                       VEX_4V;
3821     // PSRADQYri doesn't exist in SSE[1-3].
3822   }
3823 }
3824 }
3825
3826 let Constraints = "$src1 = $dst" in {
3827 defm PSLLW : PDI_binop_rmi_int<0xF1, 0x71, MRM6r, "psllw",
3828                                int_x86_sse2_psll_w, int_x86_sse2_pslli_w,
3829                                VR128>;
3830 defm PSLLD : PDI_binop_rmi_int<0xF2, 0x72, MRM6r, "pslld",
3831                                int_x86_sse2_psll_d, int_x86_sse2_pslli_d,
3832                                VR128>;
3833 defm PSLLQ : PDI_binop_rmi_int<0xF3, 0x73, MRM6r, "psllq",
3834                                int_x86_sse2_psll_q, int_x86_sse2_pslli_q,
3835                                VR128>;
3836
3837 defm PSRLW : PDI_binop_rmi_int<0xD1, 0x71, MRM2r, "psrlw",
3838                                int_x86_sse2_psrl_w, int_x86_sse2_psrli_w,
3839                                VR128>;
3840 defm PSRLD : PDI_binop_rmi_int<0xD2, 0x72, MRM2r, "psrld",
3841                                int_x86_sse2_psrl_d, int_x86_sse2_psrli_d,
3842                                VR128>;
3843 defm PSRLQ : PDI_binop_rmi_int<0xD3, 0x73, MRM2r, "psrlq",
3844                                int_x86_sse2_psrl_q, int_x86_sse2_psrli_q,
3845                                VR128>;
3846
3847 defm PSRAW : PDI_binop_rmi_int<0xE1, 0x71, MRM4r, "psraw",
3848                                int_x86_sse2_psra_w, int_x86_sse2_psrai_w,
3849                                VR128>;
3850 defm PSRAD : PDI_binop_rmi_int<0xE2, 0x72, MRM4r, "psrad",
3851                                int_x86_sse2_psra_d, int_x86_sse2_psrai_d,
3852                                VR128>;
3853
3854 let ExeDomain = SSEPackedInt in {
3855   let neverHasSideEffects = 1 in {
3856     // 128-bit logical shifts.
3857     def PSLLDQri : PDIi8<0x73, MRM7r,
3858                          (outs VR128:$dst), (ins VR128:$src1, i32i8imm:$src2),
3859                          "pslldq\t{$src2, $dst|$dst, $src2}", []>;
3860     def PSRLDQri : PDIi8<0x73, MRM3r,
3861                          (outs VR128:$dst), (ins VR128:$src1, i32i8imm:$src2),
3862                          "psrldq\t{$src2, $dst|$dst, $src2}", []>;
3863     // PSRADQri doesn't exist in SSE[1-3].
3864   }
3865 }
3866 } // Constraints = "$src1 = $dst"
3867
3868 let Predicates = [HasAVX] in {
3869   def : Pat<(int_x86_sse2_psll_dq VR128:$src1, imm:$src2),
3870             (VPSLLDQri VR128:$src1, (BYTE_imm imm:$src2))>;
3871   def : Pat<(int_x86_sse2_psrl_dq VR128:$src1, imm:$src2),
3872             (VPSRLDQri VR128:$src1, (BYTE_imm imm:$src2))>;
3873   def : Pat<(int_x86_sse2_psll_dq_bs VR128:$src1, imm:$src2),
3874             (VPSLLDQri VR128:$src1, imm:$src2)>;
3875   def : Pat<(int_x86_sse2_psrl_dq_bs VR128:$src1, imm:$src2),
3876             (VPSRLDQri VR128:$src1, imm:$src2)>;
3877   def : Pat<(v2f64 (X86fsrl VR128:$src1, i32immSExt8:$src2)),
3878             (VPSRLDQri VR128:$src1, (BYTE_imm imm:$src2))>;
3879
3880   // Shift up / down and insert zero's.
3881   def : Pat<(v2i64 (X86vshl  VR128:$src, (i8 imm:$amt))),
3882             (VPSLLDQri VR128:$src, (BYTE_imm imm:$amt))>;
3883   def : Pat<(v2i64 (X86vshr  VR128:$src, (i8 imm:$amt))),
3884             (VPSRLDQri VR128:$src, (BYTE_imm imm:$amt))>;
3885 }
3886
3887 let Predicates = [HasAVX2] in {
3888   def : Pat<(int_x86_avx2_psll_dq VR256:$src1, imm:$src2),
3889             (VPSLLDQYri VR256:$src1, (BYTE_imm imm:$src2))>;
3890   def : Pat<(int_x86_avx2_psrl_dq VR256:$src1, imm:$src2),
3891             (VPSRLDQYri VR256:$src1, (BYTE_imm imm:$src2))>;
3892   def : Pat<(int_x86_avx2_psll_dq_bs VR256:$src1, imm:$src2),
3893             (VPSLLDQYri VR256:$src1, imm:$src2)>;
3894   def : Pat<(int_x86_avx2_psrl_dq_bs VR256:$src1, imm:$src2),
3895             (VPSRLDQYri VR256:$src1, imm:$src2)>;
3896 }
3897
3898 let Predicates = [HasSSE2] in {
3899   def : Pat<(int_x86_sse2_psll_dq VR128:$src1, imm:$src2),
3900             (PSLLDQri VR128:$src1, (BYTE_imm imm:$src2))>;
3901   def : Pat<(int_x86_sse2_psrl_dq VR128:$src1, imm:$src2),
3902             (PSRLDQri VR128:$src1, (BYTE_imm imm:$src2))>;
3903   def : Pat<(int_x86_sse2_psll_dq_bs VR128:$src1, imm:$src2),
3904             (PSLLDQri VR128:$src1, imm:$src2)>;
3905   def : Pat<(int_x86_sse2_psrl_dq_bs VR128:$src1, imm:$src2),
3906             (PSRLDQri VR128:$src1, imm:$src2)>;
3907   def : Pat<(v2f64 (X86fsrl VR128:$src1, i32immSExt8:$src2)),
3908             (PSRLDQri VR128:$src1, (BYTE_imm imm:$src2))>;
3909
3910   // Shift up / down and insert zero's.
3911   def : Pat<(v2i64 (X86vshl  VR128:$src, (i8 imm:$amt))),
3912             (PSLLDQri VR128:$src, (BYTE_imm imm:$amt))>;
3913   def : Pat<(v2i64 (X86vshr  VR128:$src, (i8 imm:$amt))),
3914             (PSRLDQri VR128:$src, (BYTE_imm imm:$amt))>;
3915 }
3916
3917 //===---------------------------------------------------------------------===//
3918 // SSE2 - Packed Integer Comparison Instructions
3919 //===---------------------------------------------------------------------===//
3920
3921 let Predicates = [HasAVX] in {
3922   defm VPCMPEQB  : PDI_binop_rm_int<0x74, "vpcmpeqb", int_x86_sse2_pcmpeq_b,
3923                                     VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3924   defm VPCMPEQW  : PDI_binop_rm_int<0x75, "vpcmpeqw", int_x86_sse2_pcmpeq_w,
3925                                     VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3926   defm VPCMPEQD  : PDI_binop_rm_int<0x76, "vpcmpeqd", int_x86_sse2_pcmpeq_d,
3927                                     VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3928   defm VPCMPGTB  : PDI_binop_rm_int<0x64, "vpcmpgtb", int_x86_sse2_pcmpgt_b,
3929                                     VR128, memopv2i64, i128mem, 0, 0>, VEX_4V;
3930   defm VPCMPGTW  : PDI_binop_rm_int<0x65, "vpcmpgtw", int_x86_sse2_pcmpgt_w,
3931                                     VR128, memopv2i64, i128mem, 0, 0>, VEX_4V;
3932   defm VPCMPGTD  : PDI_binop_rm_int<0x66, "vpcmpgtd", int_x86_sse2_pcmpgt_d,
3933                                     VR128, memopv2i64, i128mem, 0, 0>, VEX_4V;
3934
3935   def : Pat<(v16i8 (X86pcmpeqb VR128:$src1, VR128:$src2)),
3936             (VPCMPEQBrr VR128:$src1, VR128:$src2)>;
3937   def : Pat<(v16i8 (X86pcmpeqb VR128:$src1,
3938                     (bc_v16i8 (memopv2i64 addr:$src2)))),
3939             (VPCMPEQBrm VR128:$src1, addr:$src2)>;
3940   def : Pat<(v8i16 (X86pcmpeqw VR128:$src1, VR128:$src2)),
3941             (VPCMPEQWrr VR128:$src1, VR128:$src2)>;
3942   def : Pat<(v8i16 (X86pcmpeqw VR128:$src1,
3943                     (bc_v8i16 (memopv2i64 addr:$src2)))),
3944             (VPCMPEQWrm VR128:$src1, addr:$src2)>;
3945   def : Pat<(v4i32 (X86pcmpeqd VR128:$src1, VR128:$src2)),
3946             (VPCMPEQDrr VR128:$src1, VR128:$src2)>;
3947   def : Pat<(v4i32 (X86pcmpeqd VR128:$src1,
3948                     (bc_v4i32 (memopv2i64 addr:$src2)))),
3949             (VPCMPEQDrm VR128:$src1, addr:$src2)>;
3950
3951   def : Pat<(v16i8 (X86pcmpgtb VR128:$src1, VR128:$src2)),
3952             (VPCMPGTBrr VR128:$src1, VR128:$src2)>;
3953   def : Pat<(v16i8 (X86pcmpgtb VR128:$src1,
3954                     (bc_v16i8 (memopv2i64 addr:$src2)))),
3955             (VPCMPGTBrm VR128:$src1, addr:$src2)>;
3956   def : Pat<(v8i16 (X86pcmpgtw VR128:$src1, VR128:$src2)),
3957             (VPCMPGTWrr VR128:$src1, VR128:$src2)>;
3958   def : Pat<(v8i16 (X86pcmpgtw VR128:$src1,
3959                     (bc_v8i16 (memopv2i64 addr:$src2)))),
3960             (VPCMPGTWrm VR128:$src1, addr:$src2)>;
3961   def : Pat<(v4i32 (X86pcmpgtd VR128:$src1, VR128:$src2)),
3962             (VPCMPGTDrr VR128:$src1, VR128:$src2)>;
3963   def : Pat<(v4i32 (X86pcmpgtd VR128:$src1,
3964                     (bc_v4i32 (memopv2i64 addr:$src2)))),
3965             (VPCMPGTDrm VR128:$src1, addr:$src2)>;
3966 }
3967
3968 let Predicates = [HasAVX2] in {
3969   defm VPCMPEQBY : PDI_binop_rm_int<0x74, "vpcmpeqb", int_x86_avx2_pcmpeq_b,
3970                                     VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3971   defm VPCMPEQWY : PDI_binop_rm_int<0x75, "vpcmpeqw", int_x86_avx2_pcmpeq_w,
3972                                     VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3973   defm VPCMPEQDY : PDI_binop_rm_int<0x76, "vpcmpeqd", int_x86_avx2_pcmpeq_d,
3974                                     VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3975   defm VPCMPGTBY : PDI_binop_rm_int<0x64, "vpcmpgtb", int_x86_avx2_pcmpgt_b,
3976                                     VR256, memopv4i64, i256mem, 0, 0>, VEX_4V;
3977   defm VPCMPGTWY : PDI_binop_rm_int<0x65, "vpcmpgtw", int_x86_avx2_pcmpgt_w,
3978                                     VR256, memopv4i64, i256mem, 0, 0>, VEX_4V;
3979   defm VPCMPGTDY : PDI_binop_rm_int<0x66, "vpcmpgtd", int_x86_avx2_pcmpgt_d,
3980                                     VR256, memopv4i64, i256mem, 0, 0>, VEX_4V;
3981
3982   def : Pat<(v32i8 (X86pcmpeqb VR256:$src1, VR256:$src2)),
3983             (VPCMPEQBYrr VR256:$src1, VR256:$src2)>;
3984   def : Pat<(v32i8 (X86pcmpeqb VR256:$src1,
3985                     (bc_v32i8 (memopv4i64 addr:$src2)))),
3986             (VPCMPEQBYrm VR256:$src1, addr:$src2)>;
3987   def : Pat<(v16i16 (X86pcmpeqw VR256:$src1, VR256:$src2)),
3988             (VPCMPEQWYrr VR256:$src1, VR256:$src2)>;
3989   def : Pat<(v16i16 (X86pcmpeqw VR256:$src1,
3990                      (bc_v16i16 (memopv4i64 addr:$src2)))),
3991             (VPCMPEQWYrm VR256:$src1, addr:$src2)>;
3992   def : Pat<(v8i32 (X86pcmpeqd VR256:$src1, VR256:$src2)),
3993             (VPCMPEQDYrr VR256:$src1, VR256:$src2)>;
3994   def : Pat<(v8i32 (X86pcmpeqd VR256:$src1,
3995                     (bc_v8i32 (memopv4i64 addr:$src2)))),
3996             (VPCMPEQDYrm VR256:$src1, addr:$src2)>;
3997
3998   def : Pat<(v32i8 (X86pcmpgtb VR256:$src1, VR256:$src2)),
3999             (VPCMPGTBYrr VR256:$src1, VR256:$src2)>;
4000   def : Pat<(v32i8 (X86pcmpgtb VR256:$src1,
4001                     (bc_v32i8 (memopv4i64 addr:$src2)))),
4002             (VPCMPGTBYrm VR256:$src1, addr:$src2)>;
4003   def : Pat<(v16i16 (X86pcmpgtw VR256:$src1, VR256:$src2)),
4004             (VPCMPGTWYrr VR256:$src1, VR256:$src2)>;
4005   def : Pat<(v16i16 (X86pcmpgtw VR256:$src1,
4006                      (bc_v16i16 (memopv4i64 addr:$src2)))),
4007             (VPCMPGTWYrm VR256:$src1, addr:$src2)>;
4008   def : Pat<(v8i32 (X86pcmpgtd VR256:$src1, VR256:$src2)),
4009             (VPCMPGTDYrr VR256:$src1, VR256:$src2)>;
4010   def : Pat<(v8i32 (X86pcmpgtd VR256:$src1,
4011                     (bc_v8i32 (memopv4i64 addr:$src2)))),
4012             (VPCMPGTDYrm VR256:$src1, addr:$src2)>;
4013 }
4014
4015 let Constraints = "$src1 = $dst" in {
4016   defm PCMPEQB  : PDI_binop_rm_int<0x74, "pcmpeqb", int_x86_sse2_pcmpeq_b,
4017                                    VR128, memopv2i64, i128mem, 1>;
4018   defm PCMPEQW  : PDI_binop_rm_int<0x75, "pcmpeqw", int_x86_sse2_pcmpeq_w,
4019                                    VR128, memopv2i64, i128mem, 1>;
4020   defm PCMPEQD  : PDI_binop_rm_int<0x76, "pcmpeqd", int_x86_sse2_pcmpeq_d,
4021                                    VR128, memopv2i64, i128mem, 1>;
4022   defm PCMPGTB  : PDI_binop_rm_int<0x64, "pcmpgtb", int_x86_sse2_pcmpgt_b,
4023                                    VR128, memopv2i64, i128mem>;
4024   defm PCMPGTW  : PDI_binop_rm_int<0x65, "pcmpgtw", int_x86_sse2_pcmpgt_w,
4025                                    VR128, memopv2i64, i128mem>;
4026   defm PCMPGTD  : PDI_binop_rm_int<0x66, "pcmpgtd", int_x86_sse2_pcmpgt_d,
4027                                    VR128, memopv2i64, i128mem>;
4028 } // Constraints = "$src1 = $dst"
4029
4030 let Predicates = [HasSSE2] in {
4031   def : Pat<(v16i8 (X86pcmpeqb VR128:$src1, VR128:$src2)),
4032             (PCMPEQBrr VR128:$src1, VR128:$src2)>;
4033   def : Pat<(v16i8 (X86pcmpeqb VR128:$src1,
4034                     (bc_v16i8 (memopv2i64 addr:$src2)))),
4035             (PCMPEQBrm VR128:$src1, addr:$src2)>;
4036   def : Pat<(v8i16 (X86pcmpeqw VR128:$src1, VR128:$src2)),
4037             (PCMPEQWrr VR128:$src1, VR128:$src2)>;
4038   def : Pat<(v8i16 (X86pcmpeqw VR128:$src1,
4039                     (bc_v8i16 (memopv2i64 addr:$src2)))),
4040             (PCMPEQWrm VR128:$src1, addr:$src2)>;
4041   def : Pat<(v4i32 (X86pcmpeqd VR128:$src1, VR128:$src2)),
4042             (PCMPEQDrr VR128:$src1, VR128:$src2)>;
4043   def : Pat<(v4i32 (X86pcmpeqd VR128:$src1,
4044                     (bc_v4i32 (memopv2i64 addr:$src2)))),
4045             (PCMPEQDrm VR128:$src1, addr:$src2)>;
4046
4047   def : Pat<(v16i8 (X86pcmpgtb VR128:$src1, VR128:$src2)),
4048             (PCMPGTBrr VR128:$src1, VR128:$src2)>;
4049   def : Pat<(v16i8 (X86pcmpgtb VR128:$src1,
4050              (bc_v16i8 (memopv2i64 addr:$src2)))),
4051             (PCMPGTBrm VR128:$src1, addr:$src2)>;
4052   def : Pat<(v8i16 (X86pcmpgtw VR128:$src1, VR128:$src2)),
4053             (PCMPGTWrr VR128:$src1, VR128:$src2)>;
4054   def : Pat<(v8i16 (X86pcmpgtw VR128:$src1,
4055                     (bc_v8i16 (memopv2i64 addr:$src2)))),
4056             (PCMPGTWrm VR128:$src1, addr:$src2)>;
4057   def : Pat<(v4i32 (X86pcmpgtd VR128:$src1, VR128:$src2)),
4058             (PCMPGTDrr VR128:$src1, VR128:$src2)>;
4059   def : Pat<(v4i32 (X86pcmpgtd VR128:$src1,
4060                     (bc_v4i32 (memopv2i64 addr:$src2)))),
4061             (PCMPGTDrm VR128:$src1, addr:$src2)>;
4062 }
4063
4064 //===---------------------------------------------------------------------===//
4065 // SSE2 - Packed Integer Pack Instructions
4066 //===---------------------------------------------------------------------===//
4067
4068 let Predicates = [HasAVX] in {
4069 defm VPACKSSWB : PDI_binop_rm_int<0x63, "vpacksswb", int_x86_sse2_packsswb_128,
4070                                   VR128, memopv2i64, i128mem, 0, 0>, VEX_4V;
4071 defm VPACKSSDW : PDI_binop_rm_int<0x6B, "vpackssdw", int_x86_sse2_packssdw_128,
4072                                   VR128, memopv2i64, i128mem, 0, 0>, VEX_4V;
4073 defm VPACKUSWB : PDI_binop_rm_int<0x67, "vpackuswb", int_x86_sse2_packuswb_128,
4074                                   VR128, memopv2i64, i128mem, 0, 0>, VEX_4V;
4075 }
4076
4077 let Predicates = [HasAVX2] in {
4078 defm VPACKSSWBY : PDI_binop_rm_int<0x63, "vpacksswb", int_x86_avx2_packsswb,
4079                                    VR256, memopv4i64, i256mem, 0, 0>, VEX_4V;
4080 defm VPACKSSDWY : PDI_binop_rm_int<0x6B, "vpackssdw", int_x86_avx2_packssdw,
4081                                    VR256, memopv4i64, i256mem, 0, 0>, VEX_4V;
4082 defm VPACKUSWBY : PDI_binop_rm_int<0x67, "vpackuswb", int_x86_avx2_packuswb,
4083                                    VR256, memopv4i64, i256mem, 0, 0>, VEX_4V;
4084 }
4085
4086 let Constraints = "$src1 = $dst" in {
4087 defm PACKSSWB : PDI_binop_rm_int<0x63, "packsswb", int_x86_sse2_packsswb_128,
4088                                  VR128, memopv2i64, i128mem>;
4089 defm PACKSSDW : PDI_binop_rm_int<0x6B, "packssdw", int_x86_sse2_packssdw_128,
4090                                  VR128, memopv2i64, i128mem>;
4091 defm PACKUSWB : PDI_binop_rm_int<0x67, "packuswb", int_x86_sse2_packuswb_128,
4092                                  VR128, memopv2i64, i128mem>;
4093 } // Constraints = "$src1 = $dst"
4094
4095 //===---------------------------------------------------------------------===//
4096 // SSE2 - Packed Integer Shuffle Instructions
4097 //===---------------------------------------------------------------------===//
4098
4099 let ExeDomain = SSEPackedInt in {
4100 multiclass sse2_pshuffle<string OpcodeStr, ValueType vt, PatFrag pshuf_frag,
4101                          PatFrag bc_frag> {
4102 def ri : Ii8<0x70, MRMSrcReg,
4103               (outs VR128:$dst), (ins VR128:$src1, i8imm:$src2),
4104               !strconcat(OpcodeStr,
4105                          "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4106               [(set VR128:$dst, (vt (pshuf_frag:$src2 VR128:$src1,
4107                                                       (undef))))]>;
4108 def mi : Ii8<0x70, MRMSrcMem,
4109               (outs VR128:$dst), (ins i128mem:$src1, i8imm:$src2),
4110               !strconcat(OpcodeStr,
4111                          "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4112               [(set VR128:$dst, (vt (pshuf_frag:$src2
4113                                       (bc_frag (memopv2i64 addr:$src1)),
4114                                       (undef))))]>;
4115 }
4116
4117 multiclass sse2_pshuffle_y<string OpcodeStr, ValueType vt, PatFrag pshuf_frag,
4118                            PatFrag bc_frag> {
4119 def Yri : Ii8<0x70, MRMSrcReg,
4120               (outs VR256:$dst), (ins VR256:$src1, i8imm:$src2),
4121               !strconcat(OpcodeStr,
4122                          "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4123               [(set VR256:$dst, (vt (pshuf_frag:$src2 VR256:$src1,
4124                                                       (undef))))]>;
4125 def Ymi : Ii8<0x70, MRMSrcMem,
4126               (outs VR256:$dst), (ins i256mem:$src1, i8imm:$src2),
4127               !strconcat(OpcodeStr,
4128                          "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4129               [(set VR256:$dst, (vt (pshuf_frag:$src2
4130                                       (bc_frag (memopv4i64 addr:$src1)),
4131                                       (undef))))]>;
4132 }
4133 } // ExeDomain = SSEPackedInt
4134
4135 let Predicates = [HasAVX] in {
4136   let AddedComplexity = 5 in
4137   defm VPSHUFD : sse2_pshuffle<"vpshufd", v4i32, pshufd, bc_v4i32>, TB, OpSize,
4138                                VEX;
4139
4140   // SSE2 with ImmT == Imm8 and XS prefix.
4141   defm VPSHUFHW : sse2_pshuffle<"vpshufhw", v8i16, pshufhw, bc_v8i16>, XS,
4142                                VEX;
4143
4144   // SSE2 with ImmT == Imm8 and XD prefix.
4145   defm VPSHUFLW : sse2_pshuffle<"vpshuflw", v8i16, pshuflw, bc_v8i16>, XD,
4146                                VEX;
4147
4148   let AddedComplexity = 5 in
4149   def : Pat<(v4f32 (pshufd:$src2 VR128:$src1, (undef))),
4150             (VPSHUFDri VR128:$src1, (SHUFFLE_get_shuf_imm VR128:$src2))>;
4151   // Unary v4f32 shuffle with VPSHUF* in order to fold a load.
4152   def : Pat<(pshufd:$src2 (bc_v4i32 (memopv4f32 addr:$src1)), (undef)),
4153             (VPSHUFDmi addr:$src1, (SHUFFLE_get_shuf_imm VR128:$src2))>;
4154
4155   def : Pat<(v4i32 (X86PShufd (bc_v4i32 (memopv2i64 addr:$src1)),
4156                                    (i8 imm:$imm))),
4157             (VPSHUFDmi addr:$src1, imm:$imm)>;
4158   def : Pat<(v4i32 (X86PShufd (bc_v4i32 (memopv4f32 addr:$src1)),
4159                                    (i8 imm:$imm))),
4160             (VPSHUFDmi addr:$src1, imm:$imm)>;
4161   def : Pat<(v4f32 (X86PShufd VR128:$src1, (i8 imm:$imm))),
4162             (VPSHUFDri VR128:$src1, imm:$imm)>;
4163   def : Pat<(v4i32 (X86PShufd VR128:$src1, (i8 imm:$imm))),
4164             (VPSHUFDri VR128:$src1, imm:$imm)>;
4165   def : Pat<(v8i16 (X86PShufhw VR128:$src, (i8 imm:$imm))),
4166             (VPSHUFHWri VR128:$src, imm:$imm)>;
4167   def : Pat<(v8i16 (X86PShufhw (bc_v8i16 (memopv2i64 addr:$src)),
4168                                (i8 imm:$imm))),
4169             (VPSHUFHWmi addr:$src, imm:$imm)>;
4170   def : Pat<(v8i16 (X86PShuflw VR128:$src, (i8 imm:$imm))),
4171             (VPSHUFLWri VR128:$src, imm:$imm)>;
4172   def : Pat<(v8i16 (X86PShuflw (bc_v8i16 (memopv2i64 addr:$src)),
4173                                (i8 imm:$imm))),
4174             (VPSHUFLWmi addr:$src, imm:$imm)>;
4175 }
4176
4177 let Predicates = [HasAVX2] in {
4178   let AddedComplexity = 5 in
4179   defm VPSHUFD : sse2_pshuffle_y<"vpshufd", v8i32, pshufd, bc_v8i32>, TB,
4180                                  OpSize, VEX;
4181
4182   // SSE2 with ImmT == Imm8 and XS prefix.
4183   defm VPSHUFHW : sse2_pshuffle_y<"vpshufhw", v16i16, pshufhw, bc_v16i16>, XS,
4184                                   VEX;
4185
4186   // SSE2 with ImmT == Imm8 and XD prefix.
4187   defm VPSHUFLW : sse2_pshuffle_y<"vpshuflw", v16i16, pshuflw, bc_v16i16>, XD,
4188                                   VEX;
4189 }
4190
4191 let Predicates = [HasSSE2] in {
4192   let AddedComplexity = 5 in
4193   defm PSHUFD : sse2_pshuffle<"pshufd", v4i32, pshufd, bc_v4i32>, TB, OpSize;
4194
4195   // SSE2 with ImmT == Imm8 and XS prefix.
4196   defm PSHUFHW : sse2_pshuffle<"pshufhw", v8i16, pshufhw, bc_v8i16>, XS;
4197
4198   // SSE2 with ImmT == Imm8 and XD prefix.
4199   defm PSHUFLW : sse2_pshuffle<"pshuflw", v8i16, pshuflw, bc_v8i16>, XD;
4200
4201   let AddedComplexity = 5 in
4202   def : Pat<(v4f32 (pshufd:$src2 VR128:$src1, (undef))),
4203             (PSHUFDri VR128:$src1, (SHUFFLE_get_shuf_imm VR128:$src2))>;
4204   // Unary v4f32 shuffle with PSHUF* in order to fold a load.
4205   def : Pat<(pshufd:$src2 (bc_v4i32 (memopv4f32 addr:$src1)), (undef)),
4206             (PSHUFDmi addr:$src1, (SHUFFLE_get_shuf_imm VR128:$src2))>;
4207
4208   def : Pat<(v4i32 (X86PShufd (bc_v4i32 (memopv2i64 addr:$src1)),
4209                                    (i8 imm:$imm))),
4210             (PSHUFDmi addr:$src1, imm:$imm)>;
4211   def : Pat<(v4i32 (X86PShufd (bc_v4i32 (memopv4f32 addr:$src1)),
4212                                    (i8 imm:$imm))),
4213             (PSHUFDmi addr:$src1, imm:$imm)>;
4214   def : Pat<(v4f32 (X86PShufd VR128:$src1, (i8 imm:$imm))),
4215             (PSHUFDri VR128:$src1, imm:$imm)>;
4216   def : Pat<(v4i32 (X86PShufd VR128:$src1, (i8 imm:$imm))),
4217             (PSHUFDri VR128:$src1, imm:$imm)>;
4218   def : Pat<(v8i16 (X86PShufhw VR128:$src, (i8 imm:$imm))),
4219             (PSHUFHWri VR128:$src, imm:$imm)>;
4220   def : Pat<(v8i16 (X86PShufhw (bc_v8i16 (memopv2i64 addr:$src)),
4221                                (i8 imm:$imm))),
4222             (PSHUFHWmi addr:$src, imm:$imm)>;
4223   def : Pat<(v8i16 (X86PShuflw VR128:$src, (i8 imm:$imm))),
4224             (PSHUFLWri VR128:$src, imm:$imm)>;
4225   def : Pat<(v8i16 (X86PShuflw (bc_v8i16 (memopv2i64 addr:$src)),
4226                                (i8 imm:$imm))),
4227             (PSHUFLWmi addr:$src, imm:$imm)>;
4228 }
4229
4230 //===---------------------------------------------------------------------===//
4231 // SSE2 - Packed Integer Unpack Instructions
4232 //===---------------------------------------------------------------------===//
4233
4234 let ExeDomain = SSEPackedInt in {
4235 multiclass sse2_unpack<bits<8> opc, string OpcodeStr, ValueType vt,
4236                        SDNode OpNode, PatFrag bc_frag, bit Is2Addr = 1> {
4237   def rr : PDI<opc, MRMSrcReg,
4238       (outs VR128:$dst), (ins VR128:$src1, VR128:$src2),
4239       !if(Is2Addr,
4240           !strconcat(OpcodeStr,"\t{$src2, $dst|$dst, $src2}"),
4241           !strconcat(OpcodeStr,"\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
4242       [(set VR128:$dst, (vt (OpNode VR128:$src1, VR128:$src2)))]>;
4243   def rm : PDI<opc, MRMSrcMem,
4244       (outs VR128:$dst), (ins VR128:$src1, i128mem:$src2),
4245       !if(Is2Addr,
4246           !strconcat(OpcodeStr,"\t{$src2, $dst|$dst, $src2}"),
4247           !strconcat(OpcodeStr,"\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
4248       [(set VR128:$dst, (OpNode VR128:$src1,
4249                                   (bc_frag (memopv2i64
4250                                                addr:$src2))))]>;
4251 }
4252
4253 multiclass sse2_unpack_y<bits<8> opc, string OpcodeStr, ValueType vt,
4254                          SDNode OpNode, PatFrag bc_frag> {
4255   def Yrr : PDI<opc, MRMSrcReg,
4256       (outs VR256:$dst), (ins VR256:$src1, VR256:$src2),
4257       !strconcat(OpcodeStr,"\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4258       [(set VR256:$dst, (vt (OpNode VR256:$src1, VR256:$src2)))]>;
4259   def Yrm : PDI<opc, MRMSrcMem,
4260       (outs VR256:$dst), (ins VR256:$src1, i256mem:$src2),
4261       !strconcat(OpcodeStr,"\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4262       [(set VR256:$dst, (OpNode VR256:$src1,
4263                                   (bc_frag (memopv4i64 addr:$src2))))]>;
4264 }
4265
4266 let Predicates = [HasAVX] in {
4267   defm VPUNPCKLBW  : sse2_unpack<0x60, "vpunpcklbw", v16i8, X86Unpckl,
4268                                  bc_v16i8, 0>, VEX_4V;
4269   defm VPUNPCKLWD  : sse2_unpack<0x61, "vpunpcklwd", v8i16, X86Unpckl,
4270                                  bc_v8i16, 0>, VEX_4V;
4271   defm VPUNPCKLDQ  : sse2_unpack<0x62, "vpunpckldq", v4i32, X86Unpckl,
4272                                  bc_v4i32, 0>, VEX_4V;
4273   defm VPUNPCKLQDQ : sse2_unpack<0x6C, "vpunpcklqdq", v2i64, X86Unpckl,
4274                                  bc_v2i64, 0>, VEX_4V;
4275
4276   defm VPUNPCKHBW  : sse2_unpack<0x68, "vpunpckhbw", v16i8, X86Unpckh,
4277                                  bc_v16i8, 0>, VEX_4V;
4278   defm VPUNPCKHWD  : sse2_unpack<0x69, "vpunpckhwd", v8i16, X86Unpckh,
4279                                  bc_v8i16, 0>, VEX_4V;
4280   defm VPUNPCKHDQ  : sse2_unpack<0x6A, "vpunpckhdq", v4i32, X86Unpckh,
4281                                  bc_v4i32, 0>, VEX_4V;
4282   defm VPUNPCKHQDQ : sse2_unpack<0x6D, "vpunpckhqdq", v2i64, X86Unpckh,
4283                                  bc_v2i64, 0>, VEX_4V;
4284 }
4285
4286 let Predicates = [HasAVX2] in {
4287   defm VPUNPCKLBW  : sse2_unpack_y<0x60, "vpunpcklbw", v32i8, X86Unpckl,
4288                                    bc_v32i8>, VEX_4V;
4289   defm VPUNPCKLWD  : sse2_unpack_y<0x61, "vpunpcklwd", v16i16, X86Unpckl,
4290                                    bc_v16i16>, VEX_4V;
4291   defm VPUNPCKLDQ  : sse2_unpack_y<0x62, "vpunpckldq", v8i32, X86Unpckl,
4292                                    bc_v8i32>, VEX_4V;
4293   defm VPUNPCKLQDQ : sse2_unpack_y<0x6C, "vpunpcklqdq", v4i64, X86Unpckl,
4294                                    bc_v4i64>, VEX_4V;
4295
4296   defm VPUNPCKHBW  : sse2_unpack_y<0x68, "vpunpckhbw", v32i8, X86Unpckh,
4297                                    bc_v32i8>, VEX_4V;
4298   defm VPUNPCKHWD  : sse2_unpack_y<0x69, "vpunpckhwd", v16i16, X86Unpckh,
4299                                    bc_v16i16>, VEX_4V;
4300   defm VPUNPCKHDQ  : sse2_unpack_y<0x6A, "vpunpckhdq", v8i32, X86Unpckh,
4301                                    bc_v8i32>, VEX_4V;
4302   defm VPUNPCKHQDQ : sse2_unpack_y<0x6D, "vpunpckhqdq", v4i64, X86Unpckh,
4303                                    bc_v4i64>, VEX_4V;
4304 }
4305
4306 let Constraints = "$src1 = $dst" in {
4307   defm PUNPCKLBW  : sse2_unpack<0x60, "punpcklbw", v16i8, X86Unpckl,
4308                                 bc_v16i8>;
4309   defm PUNPCKLWD  : sse2_unpack<0x61, "punpcklwd", v8i16, X86Unpckl,
4310                                 bc_v8i16>;
4311   defm PUNPCKLDQ  : sse2_unpack<0x62, "punpckldq", v4i32, X86Unpckl,
4312                                 bc_v4i32>;
4313   defm PUNPCKLQDQ : sse2_unpack<0x6C, "punpcklqdq", v2i64, X86Unpckl,
4314                                 bc_v2i64>;
4315
4316   defm PUNPCKHBW  : sse2_unpack<0x68, "punpckhbw", v16i8, X86Unpckh,
4317                                 bc_v16i8>;
4318   defm PUNPCKHWD  : sse2_unpack<0x69, "punpckhwd", v8i16, X86Unpckh,
4319                                 bc_v8i16>;
4320   defm PUNPCKHDQ  : sse2_unpack<0x6A, "punpckhdq", v4i32, X86Unpckh,
4321                                 bc_v4i32>;
4322   defm PUNPCKHQDQ : sse2_unpack<0x6D, "punpckhqdq", v2i64, X86Unpckh,
4323                                 bc_v2i64>;
4324 }
4325 } // ExeDomain = SSEPackedInt
4326
4327 // Patterns for using AVX1 instructions with integer vectors
4328 // Here to give AVX2 priority
4329 let Predicates = [HasAVX] in {
4330   def : Pat<(v8i32 (X86Unpckl VR256:$src1, (bc_v8i32 (memopv4i64 addr:$src2)))),
4331             (VUNPCKLPSYrm VR256:$src1, addr:$src2)>;
4332   def : Pat<(v8i32 (X86Unpckl VR256:$src1, VR256:$src2)),
4333             (VUNPCKLPSYrr VR256:$src1, VR256:$src2)>;
4334   def : Pat<(v8i32 (X86Unpckh VR256:$src1, (bc_v8i32 (memopv4i64 addr:$src2)))),
4335             (VUNPCKHPSYrm VR256:$src1, addr:$src2)>;
4336   def : Pat<(v8i32 (X86Unpckh VR256:$src1, VR256:$src2)),
4337             (VUNPCKHPSYrr VR256:$src1, VR256:$src2)>;
4338
4339   def : Pat<(v4i64 (X86Unpckl VR256:$src1, (memopv4i64 addr:$src2))),
4340             (VUNPCKLPDYrm VR256:$src1, addr:$src2)>;
4341   def : Pat<(v4i64 (X86Unpckl VR256:$src1, VR256:$src2)),
4342             (VUNPCKLPDYrr VR256:$src1, VR256:$src2)>;
4343   def : Pat<(v4i64 (X86Unpckh VR256:$src1, (memopv4i64 addr:$src2))),
4344             (VUNPCKHPDYrm VR256:$src1, addr:$src2)>;
4345   def : Pat<(v4i64 (X86Unpckh VR256:$src1, VR256:$src2)),
4346             (VUNPCKHPDYrr VR256:$src1, VR256:$src2)>;
4347 }
4348
4349 // Splat v2f64 / v2i64
4350 let AddedComplexity = 10 in {
4351   def : Pat<(splat_lo (v2i64 VR128:$src), (undef)),
4352             (PUNPCKLQDQrr VR128:$src, VR128:$src)>, Requires<[HasSSE2]>;
4353   def : Pat<(splat_lo (v2i64 VR128:$src), (undef)),
4354             (VPUNPCKLQDQrr VR128:$src, VR128:$src)>, Requires<[HasAVX]>;
4355 }
4356
4357 //===---------------------------------------------------------------------===//
4358 // SSE2 - Packed Integer Extract and Insert
4359 //===---------------------------------------------------------------------===//
4360
4361 let ExeDomain = SSEPackedInt in {
4362 multiclass sse2_pinsrw<bit Is2Addr = 1> {
4363   def rri : Ii8<0xC4, MRMSrcReg,
4364        (outs VR128:$dst), (ins VR128:$src1,
4365         GR32:$src2, i32i8imm:$src3),
4366        !if(Is2Addr,
4367            "pinsrw\t{$src3, $src2, $dst|$dst, $src2, $src3}",
4368            "vpinsrw\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
4369        [(set VR128:$dst,
4370          (X86pinsrw VR128:$src1, GR32:$src2, imm:$src3))]>;
4371   def rmi : Ii8<0xC4, MRMSrcMem,
4372                        (outs VR128:$dst), (ins VR128:$src1,
4373                         i16mem:$src2, i32i8imm:$src3),
4374        !if(Is2Addr,
4375            "pinsrw\t{$src3, $src2, $dst|$dst, $src2, $src3}",
4376            "vpinsrw\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
4377        [(set VR128:$dst,
4378          (X86pinsrw VR128:$src1, (extloadi16 addr:$src2),
4379                     imm:$src3))]>;
4380 }
4381
4382 // Extract
4383 let Predicates = [HasAVX] in
4384 def VPEXTRWri : Ii8<0xC5, MRMSrcReg,
4385                     (outs GR32:$dst), (ins VR128:$src1, i32i8imm:$src2),
4386                     "vpextrw\t{$src2, $src1, $dst|$dst, $src1, $src2}",
4387                     [(set GR32:$dst, (X86pextrw (v8i16 VR128:$src1),
4388                                                 imm:$src2))]>, TB, OpSize, VEX;
4389 def PEXTRWri : PDIi8<0xC5, MRMSrcReg,
4390                     (outs GR32:$dst), (ins VR128:$src1, i32i8imm:$src2),
4391                     "pextrw\t{$src2, $src1, $dst|$dst, $src1, $src2}",
4392                     [(set GR32:$dst, (X86pextrw (v8i16 VR128:$src1),
4393                                                 imm:$src2))]>;
4394
4395 // Insert
4396 let Predicates = [HasAVX] in {
4397   defm VPINSRW : sse2_pinsrw<0>, TB, OpSize, VEX_4V;
4398   def  VPINSRWrr64i : Ii8<0xC4, MRMSrcReg, (outs VR128:$dst),
4399        (ins VR128:$src1, GR64:$src2, i32i8imm:$src3),
4400        "vpinsrw\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
4401        []>, TB, OpSize, VEX_4V;
4402 }
4403
4404 let Constraints = "$src1 = $dst" in
4405   defm PINSRW : sse2_pinsrw, TB, OpSize, Requires<[HasSSE2]>;
4406
4407 } // ExeDomain = SSEPackedInt
4408
4409 //===---------------------------------------------------------------------===//
4410 // SSE2 - Packed Mask Creation
4411 //===---------------------------------------------------------------------===//
4412
4413 let ExeDomain = SSEPackedInt in {
4414
4415 def VPMOVMSKBrr  : VPDI<0xD7, MRMSrcReg, (outs GR32:$dst), (ins VR128:$src),
4416            "pmovmskb\t{$src, $dst|$dst, $src}",
4417            [(set GR32:$dst, (int_x86_sse2_pmovmskb_128 VR128:$src))]>, VEX;
4418 def VPMOVMSKBr64r : VPDI<0xD7, MRMSrcReg, (outs GR64:$dst), (ins VR128:$src),
4419            "pmovmskb\t{$src, $dst|$dst, $src}", []>, VEX;
4420
4421 let Predicates = [HasAVX2] in {
4422 def VPMOVMSKBYrr  : VPDI<0xD7, MRMSrcReg, (outs GR32:$dst), (ins VR256:$src),
4423            "pmovmskb\t{$src, $dst|$dst, $src}",
4424            [(set GR32:$dst, (int_x86_avx2_pmovmskb VR256:$src))]>, VEX;
4425 def VPMOVMSKBYr64r : VPDI<0xD7, MRMSrcReg, (outs GR64:$dst), (ins VR256:$src),
4426            "pmovmskb\t{$src, $dst|$dst, $src}", []>, VEX;
4427 }
4428
4429 def PMOVMSKBrr : PDI<0xD7, MRMSrcReg, (outs GR32:$dst), (ins VR128:$src),
4430            "pmovmskb\t{$src, $dst|$dst, $src}",
4431            [(set GR32:$dst, (int_x86_sse2_pmovmskb_128 VR128:$src))]>;
4432
4433 } // ExeDomain = SSEPackedInt
4434
4435 //===---------------------------------------------------------------------===//
4436 // SSE2 - Conditional Store
4437 //===---------------------------------------------------------------------===//
4438
4439 let ExeDomain = SSEPackedInt in {
4440
4441 let Uses = [EDI] in
4442 def VMASKMOVDQU : VPDI<0xF7, MRMSrcReg, (outs),
4443            (ins VR128:$src, VR128:$mask),
4444            "maskmovdqu\t{$mask, $src|$src, $mask}",
4445            [(int_x86_sse2_maskmov_dqu VR128:$src, VR128:$mask, EDI)]>, VEX;
4446 let Uses = [RDI] in
4447 def VMASKMOVDQU64 : VPDI<0xF7, MRMSrcReg, (outs),
4448            (ins VR128:$src, VR128:$mask),
4449            "maskmovdqu\t{$mask, $src|$src, $mask}",
4450            [(int_x86_sse2_maskmov_dqu VR128:$src, VR128:$mask, RDI)]>, VEX;
4451
4452 let Uses = [EDI] in
4453 def MASKMOVDQU : PDI<0xF7, MRMSrcReg, (outs), (ins VR128:$src, VR128:$mask),
4454            "maskmovdqu\t{$mask, $src|$src, $mask}",
4455            [(int_x86_sse2_maskmov_dqu VR128:$src, VR128:$mask, EDI)]>;
4456 let Uses = [RDI] in
4457 def MASKMOVDQU64 : PDI<0xF7, MRMSrcReg, (outs), (ins VR128:$src, VR128:$mask),
4458            "maskmovdqu\t{$mask, $src|$src, $mask}",
4459            [(int_x86_sse2_maskmov_dqu VR128:$src, VR128:$mask, RDI)]>;
4460
4461 } // ExeDomain = SSEPackedInt
4462
4463 //===---------------------------------------------------------------------===//
4464 // SSE2 - Move Doubleword
4465 //===---------------------------------------------------------------------===//
4466
4467 //===---------------------------------------------------------------------===//
4468 // Move Int Doubleword to Packed Double Int
4469 //
4470 def VMOVDI2PDIrr : VPDI<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR32:$src),
4471                       "movd\t{$src, $dst|$dst, $src}",
4472                       [(set VR128:$dst,
4473                         (v4i32 (scalar_to_vector GR32:$src)))]>, VEX;
4474 def VMOVDI2PDIrm : VPDI<0x6E, MRMSrcMem, (outs VR128:$dst), (ins i32mem:$src),
4475                       "movd\t{$src, $dst|$dst, $src}",
4476                       [(set VR128:$dst,
4477                         (v4i32 (scalar_to_vector (loadi32 addr:$src))))]>,
4478                       VEX;
4479 def VMOV64toPQIrr : VRPDI<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR64:$src),
4480                         "mov{d|q}\t{$src, $dst|$dst, $src}",
4481                         [(set VR128:$dst,
4482                           (v2i64 (scalar_to_vector GR64:$src)))]>, VEX;
4483 def VMOV64toSDrr : VRPDI<0x6E, MRMSrcReg, (outs FR64:$dst), (ins GR64:$src),
4484                        "mov{d|q}\t{$src, $dst|$dst, $src}",
4485                        [(set FR64:$dst, (bitconvert GR64:$src))]>, VEX;
4486
4487 def MOVDI2PDIrr : PDI<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR32:$src),
4488                       "movd\t{$src, $dst|$dst, $src}",
4489                       [(set VR128:$dst,
4490                         (v4i32 (scalar_to_vector GR32:$src)))]>;
4491 def MOVDI2PDIrm : PDI<0x6E, MRMSrcMem, (outs VR128:$dst), (ins i32mem:$src),
4492                       "movd\t{$src, $dst|$dst, $src}",
4493                       [(set VR128:$dst,
4494                         (v4i32 (scalar_to_vector (loadi32 addr:$src))))]>;
4495 def MOV64toPQIrr : RPDI<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR64:$src),
4496                         "mov{d|q}\t{$src, $dst|$dst, $src}",
4497                         [(set VR128:$dst,
4498                           (v2i64 (scalar_to_vector GR64:$src)))]>;
4499 def MOV64toSDrr : RPDI<0x6E, MRMSrcReg, (outs FR64:$dst), (ins GR64:$src),
4500                        "mov{d|q}\t{$src, $dst|$dst, $src}",
4501                        [(set FR64:$dst, (bitconvert GR64:$src))]>;
4502
4503 //===---------------------------------------------------------------------===//
4504 // Move Int Doubleword to Single Scalar
4505 //
4506 def VMOVDI2SSrr  : VPDI<0x6E, MRMSrcReg, (outs FR32:$dst), (ins GR32:$src),
4507                       "movd\t{$src, $dst|$dst, $src}",
4508                       [(set FR32:$dst, (bitconvert GR32:$src))]>, VEX;
4509
4510 def VMOVDI2SSrm  : VPDI<0x6E, MRMSrcMem, (outs FR32:$dst), (ins i32mem:$src),
4511                       "movd\t{$src, $dst|$dst, $src}",
4512                       [(set FR32:$dst, (bitconvert (loadi32 addr:$src)))]>,
4513                       VEX;
4514 def MOVDI2SSrr  : PDI<0x6E, MRMSrcReg, (outs FR32:$dst), (ins GR32:$src),
4515                       "movd\t{$src, $dst|$dst, $src}",
4516                       [(set FR32:$dst, (bitconvert GR32:$src))]>;
4517
4518 def MOVDI2SSrm  : PDI<0x6E, MRMSrcMem, (outs FR32:$dst), (ins i32mem:$src),
4519                       "movd\t{$src, $dst|$dst, $src}",
4520                       [(set FR32:$dst, (bitconvert (loadi32 addr:$src)))]>;
4521
4522 //===---------------------------------------------------------------------===//
4523 // Move Packed Doubleword Int to Packed Double Int
4524 //
4525 def VMOVPDI2DIrr  : VPDI<0x7E, MRMDestReg, (outs GR32:$dst), (ins VR128:$src),
4526                        "movd\t{$src, $dst|$dst, $src}",
4527                        [(set GR32:$dst, (vector_extract (v4i32 VR128:$src),
4528                                         (iPTR 0)))]>, VEX;
4529 def VMOVPDI2DImr  : VPDI<0x7E, MRMDestMem, (outs),
4530                        (ins i32mem:$dst, VR128:$src),
4531                        "movd\t{$src, $dst|$dst, $src}",
4532                        [(store (i32 (vector_extract (v4i32 VR128:$src),
4533                                      (iPTR 0))), addr:$dst)]>, VEX;
4534 def MOVPDI2DIrr  : PDI<0x7E, MRMDestReg, (outs GR32:$dst), (ins VR128:$src),
4535                        "movd\t{$src, $dst|$dst, $src}",
4536                        [(set GR32:$dst, (vector_extract (v4i32 VR128:$src),
4537                                         (iPTR 0)))]>;
4538 def MOVPDI2DImr  : PDI<0x7E, MRMDestMem, (outs), (ins i32mem:$dst, VR128:$src),
4539                        "movd\t{$src, $dst|$dst, $src}",
4540                        [(store (i32 (vector_extract (v4i32 VR128:$src),
4541                                      (iPTR 0))), addr:$dst)]>;
4542
4543 //===---------------------------------------------------------------------===//
4544 // Move Packed Doubleword Int first element to Doubleword Int
4545 //
4546 def VMOVPQIto64rr : I<0x7E, MRMDestReg, (outs GR64:$dst), (ins VR128:$src),
4547                           "mov{d|q}\t{$src, $dst|$dst, $src}",
4548                           [(set GR64:$dst, (vector_extract (v2i64 VR128:$src),
4549                                                            (iPTR 0)))]>,
4550                       TB, OpSize, VEX, VEX_W, Requires<[HasAVX, In64BitMode]>;
4551
4552 def MOVPQIto64rr : RPDI<0x7E, MRMDestReg, (outs GR64:$dst), (ins VR128:$src),
4553                         "mov{d|q}\t{$src, $dst|$dst, $src}",
4554                         [(set GR64:$dst, (vector_extract (v2i64 VR128:$src),
4555                                                          (iPTR 0)))]>;
4556
4557 //===---------------------------------------------------------------------===//
4558 // Bitcast FR64 <-> GR64
4559 //
4560 let Predicates = [HasAVX] in
4561 def VMOV64toSDrm : S3SI<0x7E, MRMSrcMem, (outs FR64:$dst), (ins i64mem:$src),
4562                         "vmovq\t{$src, $dst|$dst, $src}",
4563                         [(set FR64:$dst, (bitconvert (loadi64 addr:$src)))]>,
4564                         VEX;
4565 def VMOVSDto64rr : VRPDI<0x7E, MRMDestReg, (outs GR64:$dst), (ins FR64:$src),
4566                          "mov{d|q}\t{$src, $dst|$dst, $src}",
4567                          [(set GR64:$dst, (bitconvert FR64:$src))]>, VEX;
4568 def VMOVSDto64mr : VRPDI<0x7E, MRMDestMem, (outs), (ins i64mem:$dst, FR64:$src),
4569                          "movq\t{$src, $dst|$dst, $src}",
4570                          [(store (i64 (bitconvert FR64:$src)), addr:$dst)]>,
4571                          VEX;
4572
4573 def MOV64toSDrm : S3SI<0x7E, MRMSrcMem, (outs FR64:$dst), (ins i64mem:$src),
4574                        "movq\t{$src, $dst|$dst, $src}",
4575                        [(set FR64:$dst, (bitconvert (loadi64 addr:$src)))]>;
4576 def MOVSDto64rr : RPDI<0x7E, MRMDestReg, (outs GR64:$dst), (ins FR64:$src),
4577                        "mov{d|q}\t{$src, $dst|$dst, $src}",
4578                        [(set GR64:$dst, (bitconvert FR64:$src))]>;
4579 def MOVSDto64mr : RPDI<0x7E, MRMDestMem, (outs), (ins i64mem:$dst, FR64:$src),
4580                        "movq\t{$src, $dst|$dst, $src}",
4581                        [(store (i64 (bitconvert FR64:$src)), addr:$dst)]>;
4582
4583 //===---------------------------------------------------------------------===//
4584 // Move Scalar Single to Double Int
4585 //
4586 def VMOVSS2DIrr  : VPDI<0x7E, MRMDestReg, (outs GR32:$dst), (ins FR32:$src),
4587                       "movd\t{$src, $dst|$dst, $src}",
4588                       [(set GR32:$dst, (bitconvert FR32:$src))]>, VEX;
4589 def VMOVSS2DImr  : VPDI<0x7E, MRMDestMem, (outs), (ins i32mem:$dst, FR32:$src),
4590                       "movd\t{$src, $dst|$dst, $src}",
4591                       [(store (i32 (bitconvert FR32:$src)), addr:$dst)]>, VEX;
4592 def MOVSS2DIrr  : PDI<0x7E, MRMDestReg, (outs GR32:$dst), (ins FR32:$src),
4593                       "movd\t{$src, $dst|$dst, $src}",
4594                       [(set GR32:$dst, (bitconvert FR32:$src))]>;
4595 def MOVSS2DImr  : PDI<0x7E, MRMDestMem, (outs), (ins i32mem:$dst, FR32:$src),
4596                       "movd\t{$src, $dst|$dst, $src}",
4597                       [(store (i32 (bitconvert FR32:$src)), addr:$dst)]>;
4598
4599 //===---------------------------------------------------------------------===//
4600 // Patterns and instructions to describe movd/movq to XMM register zero-extends
4601 //
4602 let AddedComplexity = 15 in {
4603 def VMOVZDI2PDIrr : VPDI<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR32:$src),
4604                        "movd\t{$src, $dst|$dst, $src}",
4605                        [(set VR128:$dst, (v4i32 (X86vzmovl
4606                                       (v4i32 (scalar_to_vector GR32:$src)))))]>,
4607                                       VEX;
4608 def VMOVZQI2PQIrr : VPDI<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR64:$src),
4609                        "mov{d|q}\t{$src, $dst|$dst, $src}", // X86-64 only
4610                        [(set VR128:$dst, (v2i64 (X86vzmovl
4611                                       (v2i64 (scalar_to_vector GR64:$src)))))]>,
4612                                       VEX, VEX_W;
4613 }
4614 let AddedComplexity = 15 in {
4615 def MOVZDI2PDIrr : PDI<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR32:$src),
4616                        "movd\t{$src, $dst|$dst, $src}",
4617                        [(set VR128:$dst, (v4i32 (X86vzmovl
4618                                       (v4i32 (scalar_to_vector GR32:$src)))))]>;
4619 def MOVZQI2PQIrr : RPDI<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR64:$src),
4620                        "mov{d|q}\t{$src, $dst|$dst, $src}", // X86-64 only
4621                        [(set VR128:$dst, (v2i64 (X86vzmovl
4622                                       (v2i64 (scalar_to_vector GR64:$src)))))]>;
4623 }
4624
4625 let AddedComplexity = 20 in {
4626 def VMOVZDI2PDIrm : VPDI<0x6E, MRMSrcMem, (outs VR128:$dst), (ins i32mem:$src),
4627                        "movd\t{$src, $dst|$dst, $src}",
4628                        [(set VR128:$dst,
4629                          (v4i32 (X86vzmovl (v4i32 (scalar_to_vector
4630                                                    (loadi32 addr:$src))))))]>,
4631                                                    VEX;
4632 def MOVZDI2PDIrm : PDI<0x6E, MRMSrcMem, (outs VR128:$dst), (ins i32mem:$src),
4633                        "movd\t{$src, $dst|$dst, $src}",
4634                        [(set VR128:$dst,
4635                          (v4i32 (X86vzmovl (v4i32 (scalar_to_vector
4636                                                    (loadi32 addr:$src))))))]>;
4637 }
4638
4639 let Predicates = [HasAVX] in {
4640   // AVX 128-bit movd/movq instruction write zeros in the high 128-bit part.
4641   let AddedComplexity = 20 in {
4642     def : Pat<(v4i32 (X86vzmovl (loadv4i32 addr:$src))),
4643               (VMOVZDI2PDIrm addr:$src)>;
4644     def : Pat<(v4i32 (X86vzmovl (bc_v4i32 (loadv4f32 addr:$src)))),
4645               (VMOVZDI2PDIrm addr:$src)>;
4646     def : Pat<(v4i32 (X86vzmovl (bc_v4i32 (loadv2i64 addr:$src)))),
4647               (VMOVZDI2PDIrm addr:$src)>;
4648   }
4649   // Use regular 128-bit instructions to match 256-bit scalar_to_vec+zext.
4650   def : Pat<(v8i32 (X86vzmovl (insert_subvector undef,
4651                                 (v4i32 (scalar_to_vector GR32:$src)),(i32 0)))),
4652             (SUBREG_TO_REG (i32 0), (VMOVZDI2PDIrr GR32:$src), sub_xmm)>;
4653   def : Pat<(v4i64 (X86vzmovl (insert_subvector undef,
4654                                 (v2i64 (scalar_to_vector GR64:$src)),(i32 0)))),
4655             (SUBREG_TO_REG (i64 0), (VMOVZQI2PQIrr GR64:$src), sub_xmm)>;
4656 }
4657
4658 let Predicates = [HasSSE2], AddedComplexity = 20 in {
4659   def : Pat<(v4i32 (X86vzmovl (loadv4i32 addr:$src))),
4660             (MOVZDI2PDIrm addr:$src)>;
4661   def : Pat<(v4i32 (X86vzmovl (bc_v4i32 (loadv4f32 addr:$src)))),
4662             (MOVZDI2PDIrm addr:$src)>;
4663   def : Pat<(v4i32 (X86vzmovl (bc_v4i32 (loadv2i64 addr:$src)))),
4664             (MOVZDI2PDIrm addr:$src)>;
4665 }
4666
4667 // These are the correct encodings of the instructions so that we know how to
4668 // read correct assembly, even though we continue to emit the wrong ones for
4669 // compatibility with Darwin's buggy assembler.
4670 def : InstAlias<"movq\t{$src, $dst|$dst, $src}",
4671                 (MOV64toPQIrr VR128:$dst, GR64:$src), 0>;
4672 def : InstAlias<"movq\t{$src, $dst|$dst, $src}",
4673                 (MOV64toSDrr FR64:$dst, GR64:$src), 0>;
4674 def : InstAlias<"movq\t{$src, $dst|$dst, $src}",
4675                 (MOVPQIto64rr GR64:$dst, VR128:$src), 0>;
4676 def : InstAlias<"movq\t{$src, $dst|$dst, $src}",
4677                 (MOVSDto64rr GR64:$dst, FR64:$src), 0>;
4678 def : InstAlias<"movq\t{$src, $dst|$dst, $src}",
4679                 (VMOVZQI2PQIrr VR128:$dst, GR64:$src), 0>;
4680 def : InstAlias<"movq\t{$src, $dst|$dst, $src}",
4681                 (MOVZQI2PQIrr VR128:$dst, GR64:$src), 0>;
4682
4683 //===---------------------------------------------------------------------===//
4684 // SSE2 - Move Quadword
4685 //===---------------------------------------------------------------------===//
4686
4687 //===---------------------------------------------------------------------===//
4688 // Move Quadword Int to Packed Quadword Int
4689 //
4690 def VMOVQI2PQIrm : I<0x7E, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
4691                     "vmovq\t{$src, $dst|$dst, $src}",
4692                     [(set VR128:$dst,
4693                       (v2i64 (scalar_to_vector (loadi64 addr:$src))))]>, XS,
4694                     VEX, Requires<[HasAVX]>;
4695 def MOVQI2PQIrm : I<0x7E, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
4696                     "movq\t{$src, $dst|$dst, $src}",
4697                     [(set VR128:$dst,
4698                       (v2i64 (scalar_to_vector (loadi64 addr:$src))))]>, XS,
4699                     Requires<[HasSSE2]>; // SSE2 instruction with XS Prefix
4700
4701 //===---------------------------------------------------------------------===//
4702 // Move Packed Quadword Int to Quadword Int
4703 //
4704 def VMOVPQI2QImr : VPDI<0xD6, MRMDestMem, (outs), (ins i64mem:$dst, VR128:$src),
4705                       "movq\t{$src, $dst|$dst, $src}",
4706                       [(store (i64 (vector_extract (v2i64 VR128:$src),
4707                                     (iPTR 0))), addr:$dst)]>, VEX;
4708 def MOVPQI2QImr : PDI<0xD6, MRMDestMem, (outs), (ins i64mem:$dst, VR128:$src),
4709                       "movq\t{$src, $dst|$dst, $src}",
4710                       [(store (i64 (vector_extract (v2i64 VR128:$src),
4711                                     (iPTR 0))), addr:$dst)]>;
4712
4713 //===---------------------------------------------------------------------===//
4714 // Store / copy lower 64-bits of a XMM register.
4715 //
4716 def VMOVLQ128mr : VPDI<0xD6, MRMDestMem, (outs), (ins i64mem:$dst, VR128:$src),
4717                      "movq\t{$src, $dst|$dst, $src}",
4718                      [(int_x86_sse2_storel_dq addr:$dst, VR128:$src)]>, VEX;
4719 def MOVLQ128mr : PDI<0xD6, MRMDestMem, (outs), (ins i64mem:$dst, VR128:$src),
4720                      "movq\t{$src, $dst|$dst, $src}",
4721                      [(int_x86_sse2_storel_dq addr:$dst, VR128:$src)]>;
4722
4723 let AddedComplexity = 20 in
4724 def VMOVZQI2PQIrm : I<0x7E, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
4725                      "vmovq\t{$src, $dst|$dst, $src}",
4726                      [(set VR128:$dst,
4727                        (v2i64 (X86vzmovl (v2i64 (scalar_to_vector
4728                                                  (loadi64 addr:$src))))))]>,
4729                      XS, VEX, Requires<[HasAVX]>;
4730
4731 let AddedComplexity = 20 in
4732 def MOVZQI2PQIrm : I<0x7E, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
4733                      "movq\t{$src, $dst|$dst, $src}",
4734                      [(set VR128:$dst,
4735                        (v2i64 (X86vzmovl (v2i64 (scalar_to_vector
4736                                                  (loadi64 addr:$src))))))]>,
4737                      XS, Requires<[HasSSE2]>;
4738
4739 let Predicates = [HasAVX], AddedComplexity = 20 in {
4740   def : Pat<(v2i64 (X86vzmovl (loadv2i64 addr:$src))),
4741             (VMOVZQI2PQIrm addr:$src)>;
4742   def : Pat<(v2i64 (X86vzmovl (bc_v2i64 (loadv4f32 addr:$src)))),
4743             (VMOVZQI2PQIrm addr:$src)>;
4744   def : Pat<(v2i64 (X86vzload addr:$src)),
4745             (VMOVZQI2PQIrm addr:$src)>;
4746 }
4747
4748 let Predicates = [HasSSE2], AddedComplexity = 20 in {
4749   def : Pat<(v2i64 (X86vzmovl (loadv2i64 addr:$src))),
4750             (MOVZQI2PQIrm addr:$src)>;
4751   def : Pat<(v2i64 (X86vzmovl (bc_v2i64 (loadv4f32 addr:$src)))),
4752             (MOVZQI2PQIrm addr:$src)>;
4753   def : Pat<(v2i64 (X86vzload addr:$src)), (MOVZQI2PQIrm addr:$src)>;
4754 }
4755
4756 let Predicates = [HasAVX] in {
4757 def : Pat<(v4i64 (X86vzload addr:$src)),
4758           (SUBREG_TO_REG (i32 0), (VMOVAPSrm addr:$src), sub_xmm)>;
4759 }
4760
4761 //===---------------------------------------------------------------------===//
4762 // Moving from XMM to XMM and clear upper 64 bits. Note, there is a bug in
4763 // IA32 document. movq xmm1, xmm2 does clear the high bits.
4764 //
4765 let AddedComplexity = 15 in
4766 def VMOVZPQILo2PQIrr : I<0x7E, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
4767                         "vmovq\t{$src, $dst|$dst, $src}",
4768                     [(set VR128:$dst, (v2i64 (X86vzmovl (v2i64 VR128:$src))))]>,
4769                       XS, VEX, Requires<[HasAVX]>;
4770 let AddedComplexity = 15 in
4771 def MOVZPQILo2PQIrr : I<0x7E, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
4772                         "movq\t{$src, $dst|$dst, $src}",
4773                     [(set VR128:$dst, (v2i64 (X86vzmovl (v2i64 VR128:$src))))]>,
4774                       XS, Requires<[HasSSE2]>;
4775
4776 let AddedComplexity = 20 in
4777 def VMOVZPQILo2PQIrm : I<0x7E, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
4778                         "vmovq\t{$src, $dst|$dst, $src}",
4779                     [(set VR128:$dst, (v2i64 (X86vzmovl
4780                                              (loadv2i64 addr:$src))))]>,
4781                       XS, VEX, Requires<[HasAVX]>;
4782 let AddedComplexity = 20 in {
4783 def MOVZPQILo2PQIrm : I<0x7E, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
4784                         "movq\t{$src, $dst|$dst, $src}",
4785                     [(set VR128:$dst, (v2i64 (X86vzmovl
4786                                              (loadv2i64 addr:$src))))]>,
4787                       XS, Requires<[HasSSE2]>;
4788 }
4789
4790 let AddedComplexity = 20 in {
4791   let Predicates = [HasAVX] in {
4792     def : Pat<(v2i64 (X86vzmovl (bc_v2i64 (loadv4i32 addr:$src)))),
4793               (VMOVZPQILo2PQIrm addr:$src)>;
4794     def : Pat<(v2f64 (X86vzmovl (v2f64 VR128:$src))),
4795               (VMOVZPQILo2PQIrr VR128:$src)>;
4796   }
4797   let Predicates = [HasSSE2] in {
4798     def : Pat<(v2i64 (X86vzmovl (bc_v2i64 (loadv4i32 addr:$src)))),
4799               (MOVZPQILo2PQIrm addr:$src)>;
4800     def : Pat<(v2f64 (X86vzmovl (v2f64 VR128:$src))),
4801               (MOVZPQILo2PQIrr VR128:$src)>;
4802   }
4803 }
4804
4805 // Instructions to match in the assembler
4806 def VMOVQs64rr : VPDI<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR64:$src),
4807                       "movq\t{$src, $dst|$dst, $src}", []>, VEX, VEX_W;
4808 def VMOVQd64rr : VPDI<0x7E, MRMDestReg, (outs GR64:$dst), (ins VR128:$src),
4809                       "movq\t{$src, $dst|$dst, $src}", []>, VEX, VEX_W;
4810 // Recognize "movd" with GR64 destination, but encode as a "movq"
4811 def VMOVQd64rr_alt : VPDI<0x7E, MRMDestReg, (outs GR64:$dst), (ins VR128:$src),
4812                           "movd\t{$src, $dst|$dst, $src}", []>, VEX, VEX_W;
4813
4814 // Instructions for the disassembler
4815 // xr = XMM register
4816 // xm = mem64
4817
4818 let Predicates = [HasAVX] in
4819 def VMOVQxrxr: I<0x7E, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
4820                  "vmovq\t{$src, $dst|$dst, $src}", []>, VEX, XS;
4821 def MOVQxrxr : I<0x7E, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
4822                  "movq\t{$src, $dst|$dst, $src}", []>, XS;
4823
4824 //===---------------------------------------------------------------------===//
4825 // SSE3 - Conversion Instructions
4826 //===---------------------------------------------------------------------===//
4827
4828 // Convert Packed Double FP to Packed DW Integers
4829 let Predicates = [HasAVX] in {
4830 // The assembler can recognize rr 256-bit instructions by seeing a ymm
4831 // register, but the same isn't true when using memory operands instead.
4832 // Provide other assembly rr and rm forms to address this explicitly.
4833 def VCVTPD2DQrr  : S3DI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
4834                        "vcvtpd2dq\t{$src, $dst|$dst, $src}", []>, VEX;
4835 def VCVTPD2DQXrYr  : S3DI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR256:$src),
4836                        "vcvtpd2dq\t{$src, $dst|$dst, $src}", []>, VEX;
4837
4838 // XMM only
4839 def VCVTPD2DQXrr : S3DI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
4840                       "vcvtpd2dqx\t{$src, $dst|$dst, $src}", []>, VEX;
4841 def VCVTPD2DQXrm : S3DI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
4842                       "vcvtpd2dqx\t{$src, $dst|$dst, $src}", []>, VEX;
4843
4844 // YMM only
4845 def VCVTPD2DQYrr : S3DI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR256:$src),
4846                       "vcvtpd2dqy\t{$src, $dst|$dst, $src}", []>, VEX;
4847 def VCVTPD2DQYrm : S3DI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f256mem:$src),
4848                       "vcvtpd2dqy\t{$src, $dst|$dst, $src}", []>, VEX, VEX_L;
4849 }
4850
4851 def CVTPD2DQrm  : S3DI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
4852                        "cvtpd2dq\t{$src, $dst|$dst, $src}", []>;
4853 def CVTPD2DQrr  : S3DI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
4854                        "cvtpd2dq\t{$src, $dst|$dst, $src}", []>;
4855
4856 def : Pat<(v4i32 (fp_to_sint (v4f64 VR256:$src))),
4857           (VCVTPD2DQYrr VR256:$src)>;
4858 def : Pat<(v4i32 (fp_to_sint (memopv4f64 addr:$src))),
4859           (VCVTPD2DQYrm addr:$src)>;
4860
4861 // Convert Packed DW Integers to Packed Double FP
4862 let Predicates = [HasAVX] in {
4863 def VCVTDQ2PDrm  : S3SI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
4864                      "vcvtdq2pd\t{$src, $dst|$dst, $src}", []>, VEX;
4865 def VCVTDQ2PDrr  : S3SI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
4866                      "vcvtdq2pd\t{$src, $dst|$dst, $src}", []>, VEX;
4867 def VCVTDQ2PDYrm  : S3SI<0xE6, MRMSrcMem, (outs VR256:$dst), (ins f128mem:$src),
4868                      "vcvtdq2pd\t{$src, $dst|$dst, $src}", []>, VEX;
4869 def VCVTDQ2PDYrr  : S3SI<0xE6, MRMSrcReg, (outs VR256:$dst), (ins VR128:$src),
4870                      "vcvtdq2pd\t{$src, $dst|$dst, $src}", []>, VEX;
4871 }
4872
4873 def CVTDQ2PDrm  : S3SI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
4874                        "cvtdq2pd\t{$src, $dst|$dst, $src}", []>;
4875 def CVTDQ2PDrr  : S3SI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
4876                        "cvtdq2pd\t{$src, $dst|$dst, $src}", []>;
4877
4878 // AVX 256-bit register conversion intrinsics
4879 def : Pat<(int_x86_avx_cvtdq2_pd_256 VR128:$src),
4880            (VCVTDQ2PDYrr VR128:$src)>;
4881 def : Pat<(int_x86_avx_cvtdq2_pd_256 (bitconvert (memopv2i64 addr:$src))),
4882            (VCVTDQ2PDYrm addr:$src)>;
4883
4884 def : Pat<(int_x86_avx_cvt_pd2dq_256 VR256:$src),
4885           (VCVTPD2DQYrr VR256:$src)>;
4886 def : Pat<(int_x86_avx_cvt_pd2dq_256 (memopv4f64 addr:$src)),
4887           (VCVTPD2DQYrm addr:$src)>;
4888
4889 def : Pat<(v4f64 (sint_to_fp (v4i32 VR128:$src))),
4890           (VCVTDQ2PDYrr VR128:$src)>;
4891 def : Pat<(v4f64 (sint_to_fp (bc_v4i32 (memopv2i64 addr:$src)))),
4892           (VCVTDQ2PDYrm addr:$src)>;
4893
4894 //===---------------------------------------------------------------------===//
4895 // SSE3 - Replicate Single FP - MOVSHDUP and MOVSLDUP
4896 //===---------------------------------------------------------------------===//
4897 multiclass sse3_replicate_sfp<bits<8> op, SDNode OpNode, string OpcodeStr,
4898                               ValueType vt, RegisterClass RC, PatFrag mem_frag,
4899                               X86MemOperand x86memop> {
4900 def rr : S3SI<op, MRMSrcReg, (outs RC:$dst), (ins RC:$src),
4901                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
4902                       [(set RC:$dst, (vt (OpNode RC:$src)))]>;
4903 def rm : S3SI<op, MRMSrcMem, (outs RC:$dst), (ins x86memop:$src),
4904                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
4905                       [(set RC:$dst, (OpNode (mem_frag addr:$src)))]>;
4906 }
4907
4908 let Predicates = [HasAVX] in {
4909   defm VMOVSHDUP  : sse3_replicate_sfp<0x16, X86Movshdup, "vmovshdup",
4910                                        v4f32, VR128, memopv4f32, f128mem>, VEX;
4911   defm VMOVSLDUP  : sse3_replicate_sfp<0x12, X86Movsldup, "vmovsldup",
4912                                        v4f32, VR128, memopv4f32, f128mem>, VEX;
4913   defm VMOVSHDUPY : sse3_replicate_sfp<0x16, X86Movshdup, "vmovshdup",
4914                                        v8f32, VR256, memopv8f32, f256mem>, VEX;
4915   defm VMOVSLDUPY : sse3_replicate_sfp<0x12, X86Movsldup, "vmovsldup",
4916                                        v8f32, VR256, memopv8f32, f256mem>, VEX;
4917 }
4918 defm MOVSHDUP : sse3_replicate_sfp<0x16, X86Movshdup, "movshdup", v4f32, VR128,
4919                                    memopv4f32, f128mem>;
4920 defm MOVSLDUP : sse3_replicate_sfp<0x12, X86Movsldup, "movsldup", v4f32, VR128,
4921                                    memopv4f32, f128mem>;
4922
4923 let Predicates = [HasAVX] in {
4924   def : Pat<(v4i32 (X86Movshdup VR128:$src)),
4925             (VMOVSHDUPrr VR128:$src)>;
4926   def : Pat<(v4i32 (X86Movshdup (bc_v4i32 (memopv2i64 addr:$src)))),
4927             (VMOVSHDUPrm addr:$src)>;
4928   def : Pat<(v4i32 (X86Movsldup VR128:$src)),
4929             (VMOVSLDUPrr VR128:$src)>;
4930   def : Pat<(v4i32 (X86Movsldup (bc_v4i32 (memopv2i64 addr:$src)))),
4931             (VMOVSLDUPrm addr:$src)>;
4932   def : Pat<(v8i32 (X86Movshdup VR256:$src)),
4933             (VMOVSHDUPYrr VR256:$src)>;
4934   def : Pat<(v8i32 (X86Movshdup (bc_v8i32 (memopv4i64 addr:$src)))),
4935             (VMOVSHDUPYrm addr:$src)>;
4936   def : Pat<(v8i32 (X86Movsldup VR256:$src)),
4937             (VMOVSLDUPYrr VR256:$src)>;
4938   def : Pat<(v8i32 (X86Movsldup (bc_v8i32 (memopv4i64 addr:$src)))),
4939             (VMOVSLDUPYrm addr:$src)>;
4940 }
4941
4942 let Predicates = [HasSSE3] in {
4943   def : Pat<(v4i32 (X86Movshdup VR128:$src)),
4944             (MOVSHDUPrr VR128:$src)>;
4945   def : Pat<(v4i32 (X86Movshdup (bc_v4i32 (memopv2i64 addr:$src)))),
4946             (MOVSHDUPrm addr:$src)>;
4947   def : Pat<(v4i32 (X86Movsldup VR128:$src)),
4948             (MOVSLDUPrr VR128:$src)>;
4949   def : Pat<(v4i32 (X86Movsldup (bc_v4i32 (memopv2i64 addr:$src)))),
4950             (MOVSLDUPrm addr:$src)>;
4951 }
4952
4953 //===---------------------------------------------------------------------===//
4954 // SSE3 - Replicate Double FP - MOVDDUP
4955 //===---------------------------------------------------------------------===//
4956
4957 multiclass sse3_replicate_dfp<string OpcodeStr> {
4958 def rr  : S3DI<0x12, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
4959                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
4960                     [(set VR128:$dst,(v2f64 (movddup VR128:$src, (undef))))]>;
4961 def rm  : S3DI<0x12, MRMSrcMem, (outs VR128:$dst), (ins f64mem:$src),
4962                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
4963                     [(set VR128:$dst,
4964                       (v2f64 (movddup (scalar_to_vector (loadf64 addr:$src)),
4965                                       (undef))))]>;
4966 }
4967
4968 // FIXME: Merge with above classe when there're patterns for the ymm version
4969 multiclass sse3_replicate_dfp_y<string OpcodeStr> {
4970 let Predicates = [HasAVX] in {
4971   def rr  : S3DI<0x12, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
4972                       !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
4973                       []>;
4974   def rm  : S3DI<0x12, MRMSrcMem, (outs VR256:$dst), (ins f256mem:$src),
4975                       !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
4976                       []>;
4977   }
4978 }
4979
4980 defm MOVDDUP : sse3_replicate_dfp<"movddup">;
4981 defm VMOVDDUP  : sse3_replicate_dfp<"vmovddup">, VEX;
4982 defm VMOVDDUPY : sse3_replicate_dfp_y<"vmovddup">, VEX;
4983
4984 let Predicates = [HasAVX] in {
4985   def : Pat<(movddup (bc_v2f64 (v2i64 (scalar_to_vector (loadi64 addr:$src)))),
4986                    (undef)),
4987             (VMOVDDUPrm addr:$src)>;
4988   let AddedComplexity = 5 in {
4989   def : Pat<(movddup (memopv2f64 addr:$src), (undef)), (VMOVDDUPrm addr:$src)>;
4990   def : Pat<(movddup (bc_v4f32 (memopv2f64 addr:$src)), (undef)),
4991             (VMOVDDUPrm addr:$src)>;
4992   def : Pat<(movddup (memopv2i64 addr:$src), (undef)), (VMOVDDUPrm addr:$src)>;
4993   def : Pat<(movddup (bc_v4i32 (memopv2i64 addr:$src)), (undef)),
4994             (VMOVDDUPrm addr:$src)>;
4995   }
4996   def : Pat<(X86Movddup (memopv2f64 addr:$src)),
4997             (VMOVDDUPrm addr:$src)>, Requires<[HasAVX]>;
4998   def : Pat<(X86Movddup (bc_v2f64 (memopv4f32 addr:$src))),
4999             (VMOVDDUPrm addr:$src)>, Requires<[HasAVX]>;
5000   def : Pat<(X86Movddup (bc_v2f64 (memopv2i64 addr:$src))),
5001             (VMOVDDUPrm addr:$src)>, Requires<[HasAVX]>;
5002   def : Pat<(X86Movddup (v2f64 (scalar_to_vector (loadf64 addr:$src)))),
5003             (VMOVDDUPrm addr:$src)>, Requires<[HasAVX]>;
5004   def : Pat<(X86Movddup (bc_v2f64
5005                              (v2i64 (scalar_to_vector (loadi64 addr:$src))))),
5006             (VMOVDDUPrm addr:$src)>, Requires<[HasAVX]>;
5007
5008   // 256-bit version
5009   def : Pat<(X86Movddup (memopv4f64 addr:$src)),
5010             (VMOVDDUPYrm addr:$src)>;
5011   def : Pat<(X86Movddup (memopv4i64 addr:$src)),
5012             (VMOVDDUPYrm addr:$src)>;
5013   def : Pat<(X86Movddup (v4f64 (scalar_to_vector (loadf64 addr:$src)))),
5014             (VMOVDDUPYrm addr:$src)>;
5015   def : Pat<(X86Movddup (v4i64 (scalar_to_vector (loadi64 addr:$src)))),
5016             (VMOVDDUPYrm addr:$src)>;
5017   def : Pat<(X86Movddup (v4f64 VR256:$src)),
5018             (VMOVDDUPYrr VR256:$src)>;
5019   def : Pat<(X86Movddup (v4i64 VR256:$src)),
5020             (VMOVDDUPYrr VR256:$src)>;
5021 }
5022
5023 let Predicates = [HasSSE3] in {
5024   def : Pat<(movddup (bc_v2f64 (v2i64 (scalar_to_vector (loadi64 addr:$src)))),
5025                    (undef)),
5026             (MOVDDUPrm addr:$src)>;
5027   let AddedComplexity = 5 in {
5028   def : Pat<(movddup (memopv2f64 addr:$src), (undef)), (MOVDDUPrm addr:$src)>;
5029   def : Pat<(movddup (bc_v4f32 (memopv2f64 addr:$src)), (undef)),
5030             (MOVDDUPrm addr:$src)>;
5031   def : Pat<(movddup (memopv2i64 addr:$src), (undef)), (MOVDDUPrm addr:$src)>;
5032   def : Pat<(movddup (bc_v4i32 (memopv2i64 addr:$src)), (undef)),
5033             (MOVDDUPrm addr:$src)>;
5034   }
5035   def : Pat<(X86Movddup (memopv2f64 addr:$src)),
5036             (MOVDDUPrm addr:$src)>;
5037   def : Pat<(X86Movddup (bc_v2f64 (memopv4f32 addr:$src))),
5038             (MOVDDUPrm addr:$src)>;
5039   def : Pat<(X86Movddup (bc_v2f64 (memopv2i64 addr:$src))),
5040             (MOVDDUPrm addr:$src)>;
5041   def : Pat<(X86Movddup (v2f64 (scalar_to_vector (loadf64 addr:$src)))),
5042             (MOVDDUPrm addr:$src)>;
5043   def : Pat<(X86Movddup (bc_v2f64
5044                              (v2i64 (scalar_to_vector (loadi64 addr:$src))))),
5045             (MOVDDUPrm addr:$src)>;
5046 }
5047
5048 //===---------------------------------------------------------------------===//
5049 // SSE3 - Move Unaligned Integer
5050 //===---------------------------------------------------------------------===//
5051
5052 let Predicates = [HasAVX] in {
5053   def VLDDQUrm : S3DI<0xF0, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
5054                    "vlddqu\t{$src, $dst|$dst, $src}",
5055                    [(set VR128:$dst, (int_x86_sse3_ldu_dq addr:$src))]>, VEX;
5056   def VLDDQUYrm : S3DI<0xF0, MRMSrcMem, (outs VR256:$dst), (ins i256mem:$src),
5057                    "vlddqu\t{$src, $dst|$dst, $src}",
5058                    [(set VR256:$dst, (int_x86_avx_ldu_dq_256 addr:$src))]>, VEX;
5059 }
5060 def LDDQUrm : S3DI<0xF0, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
5061                    "lddqu\t{$src, $dst|$dst, $src}",
5062                    [(set VR128:$dst, (int_x86_sse3_ldu_dq addr:$src))]>;
5063
5064 //===---------------------------------------------------------------------===//
5065 // SSE3 - Arithmetic
5066 //===---------------------------------------------------------------------===//
5067
5068 multiclass sse3_addsub<Intrinsic Int, string OpcodeStr, RegisterClass RC,
5069                        X86MemOperand x86memop, bit Is2Addr = 1> {
5070   def rr : I<0xD0, MRMSrcReg,
5071        (outs RC:$dst), (ins RC:$src1, RC:$src2),
5072        !if(Is2Addr,
5073            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5074            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5075        [(set RC:$dst, (Int RC:$src1, RC:$src2))]>;
5076   def rm : I<0xD0, MRMSrcMem,
5077        (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
5078        !if(Is2Addr,
5079            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5080            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5081        [(set RC:$dst, (Int RC:$src1, (memop addr:$src2)))]>;
5082 }
5083
5084 let Predicates = [HasAVX] in {
5085   let ExeDomain = SSEPackedSingle in {
5086     defm VADDSUBPS : sse3_addsub<int_x86_sse3_addsub_ps, "vaddsubps", VR128,
5087                                  f128mem, 0>, TB, XD, VEX_4V;
5088     defm VADDSUBPSY : sse3_addsub<int_x86_avx_addsub_ps_256, "vaddsubps", VR256,
5089                                  f256mem, 0>, TB, XD, VEX_4V;
5090   }
5091   let ExeDomain = SSEPackedDouble in {
5092     defm VADDSUBPD : sse3_addsub<int_x86_sse3_addsub_pd, "vaddsubpd", VR128,
5093                                  f128mem, 0>, TB, OpSize, VEX_4V;
5094     defm VADDSUBPDY : sse3_addsub<int_x86_avx_addsub_pd_256, "vaddsubpd", VR256,
5095                                  f256mem, 0>, TB, OpSize, VEX_4V;
5096   }
5097 }
5098 let Constraints = "$src1 = $dst", Predicates = [HasSSE3] in {
5099   let ExeDomain = SSEPackedSingle in
5100   defm ADDSUBPS : sse3_addsub<int_x86_sse3_addsub_ps, "addsubps", VR128,
5101                               f128mem>, TB, XD;
5102   let ExeDomain = SSEPackedDouble in
5103   defm ADDSUBPD : sse3_addsub<int_x86_sse3_addsub_pd, "addsubpd", VR128,
5104                               f128mem>, TB, OpSize;
5105 }
5106
5107 //===---------------------------------------------------------------------===//
5108 // SSE3 Instructions
5109 //===---------------------------------------------------------------------===//
5110
5111 // Horizontal ops
5112 multiclass S3D_Int<bits<8> o, string OpcodeStr, ValueType vt, RegisterClass RC,
5113                    X86MemOperand x86memop, SDNode OpNode, bit Is2Addr = 1> {
5114   def rr : S3DI<o, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
5115        !if(Is2Addr,
5116          !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5117          !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5118       [(set RC:$dst, (vt (OpNode RC:$src1, RC:$src2)))]>;
5119
5120   def rm : S3DI<o, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
5121        !if(Is2Addr,
5122          !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5123          !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5124       [(set RC:$dst, (vt (OpNode RC:$src1, (memop addr:$src2))))]>;
5125 }
5126 multiclass S3_Int<bits<8> o, string OpcodeStr, ValueType vt, RegisterClass RC,
5127                   X86MemOperand x86memop, SDNode OpNode, bit Is2Addr = 1> {
5128   def rr : S3I<o, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
5129        !if(Is2Addr,
5130          !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5131          !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5132       [(set RC:$dst, (vt (OpNode RC:$src1, RC:$src2)))]>;
5133
5134   def rm : S3I<o, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
5135        !if(Is2Addr,
5136          !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5137          !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5138       [(set RC:$dst, (vt (OpNode RC:$src1, (memop addr:$src2))))]>;
5139 }
5140
5141 let Predicates = [HasAVX] in {
5142   let ExeDomain = SSEPackedSingle in {
5143     defm VHADDPS  : S3D_Int<0x7C, "vhaddps", v4f32, VR128, f128mem,
5144                             X86fhadd, 0>, VEX_4V;
5145     defm VHSUBPS  : S3D_Int<0x7D, "vhsubps", v4f32, VR128, f128mem,
5146                             X86fhsub, 0>, VEX_4V;
5147     defm VHADDPSY : S3D_Int<0x7C, "vhaddps", v8f32, VR256, f256mem,
5148                             X86fhadd, 0>, VEX_4V;
5149     defm VHSUBPSY : S3D_Int<0x7D, "vhsubps", v8f32, VR256, f256mem,
5150                             X86fhsub, 0>, VEX_4V;
5151   }
5152   let ExeDomain = SSEPackedDouble in {
5153     defm VHADDPD  : S3_Int <0x7C, "vhaddpd", v2f64, VR128, f128mem,
5154                             X86fhadd, 0>, VEX_4V;
5155     defm VHSUBPD  : S3_Int <0x7D, "vhsubpd", v2f64, VR128, f128mem,
5156                             X86fhsub, 0>, VEX_4V;
5157     defm VHADDPDY : S3_Int <0x7C, "vhaddpd", v4f64, VR256, f256mem,
5158                             X86fhadd, 0>, VEX_4V;
5159     defm VHSUBPDY : S3_Int <0x7D, "vhsubpd", v4f64, VR256, f256mem,
5160                             X86fhsub, 0>, VEX_4V;
5161   }
5162 }
5163
5164 let Constraints = "$src1 = $dst" in {
5165   let ExeDomain = SSEPackedSingle in {
5166     defm HADDPS : S3D_Int<0x7C, "haddps", v4f32, VR128, f128mem, X86fhadd>;
5167     defm HSUBPS : S3D_Int<0x7D, "hsubps", v4f32, VR128, f128mem, X86fhsub>;
5168   }
5169   let ExeDomain = SSEPackedDouble in {
5170     defm HADDPD : S3_Int<0x7C, "haddpd", v2f64, VR128, f128mem, X86fhadd>;
5171     defm HSUBPD : S3_Int<0x7D, "hsubpd", v2f64, VR128, f128mem, X86fhsub>;
5172   }
5173 }
5174
5175 //===---------------------------------------------------------------------===//
5176 // SSSE3 - Packed Absolute Instructions
5177 //===---------------------------------------------------------------------===//
5178
5179
5180 /// SS3I_unop_rm_int - Simple SSSE3 unary op whose type can be v*{i8,i16,i32}.
5181 multiclass SS3I_unop_rm_int<bits<8> opc, string OpcodeStr,
5182                             Intrinsic IntId128> {
5183   def rr128 : SS38I<opc, MRMSrcReg, (outs VR128:$dst),
5184                     (ins VR128:$src),
5185                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5186                     [(set VR128:$dst, (IntId128 VR128:$src))]>,
5187                     OpSize;
5188
5189   def rm128 : SS38I<opc, MRMSrcMem, (outs VR128:$dst),
5190                     (ins i128mem:$src),
5191                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5192                     [(set VR128:$dst,
5193                       (IntId128
5194                        (bitconvert (memopv2i64 addr:$src))))]>, OpSize;
5195 }
5196
5197 /// SS3I_unop_rm_int_y - Simple SSSE3 unary op whose type can be v*{i8,i16,i32}.
5198 multiclass SS3I_unop_rm_int_y<bits<8> opc, string OpcodeStr,
5199                               Intrinsic IntId256> {
5200   def rr256 : SS38I<opc, MRMSrcReg, (outs VR256:$dst),
5201                     (ins VR256:$src),
5202                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5203                     [(set VR256:$dst, (IntId256 VR256:$src))]>,
5204                     OpSize;
5205
5206   def rm256 : SS38I<opc, MRMSrcMem, (outs VR256:$dst),
5207                     (ins i256mem:$src),
5208                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5209                     [(set VR256:$dst,
5210                       (IntId256
5211                        (bitconvert (memopv4i64 addr:$src))))]>, OpSize;
5212 }
5213
5214 let Predicates = [HasAVX] in {
5215   defm VPABSB  : SS3I_unop_rm_int<0x1C, "vpabsb",
5216                                   int_x86_ssse3_pabs_b_128>, VEX;
5217   defm VPABSW  : SS3I_unop_rm_int<0x1D, "vpabsw",
5218                                   int_x86_ssse3_pabs_w_128>, VEX;
5219   defm VPABSD  : SS3I_unop_rm_int<0x1E, "vpabsd",
5220                                   int_x86_ssse3_pabs_d_128>, VEX;
5221 }
5222
5223 let Predicates = [HasAVX2] in {
5224   defm VPABSB  : SS3I_unop_rm_int_y<0x1C, "vpabsb",
5225                                     int_x86_avx2_pabs_b>, VEX;
5226   defm VPABSW  : SS3I_unop_rm_int_y<0x1D, "vpabsw",
5227                                     int_x86_avx2_pabs_w>, VEX;
5228   defm VPABSD  : SS3I_unop_rm_int_y<0x1E, "vpabsd",
5229                                     int_x86_avx2_pabs_d>, VEX;
5230 }
5231
5232 defm PABSB : SS3I_unop_rm_int<0x1C, "pabsb",
5233                               int_x86_ssse3_pabs_b_128>;
5234 defm PABSW : SS3I_unop_rm_int<0x1D, "pabsw",
5235                               int_x86_ssse3_pabs_w_128>;
5236 defm PABSD : SS3I_unop_rm_int<0x1E, "pabsd",
5237                               int_x86_ssse3_pabs_d_128>;
5238
5239 //===---------------------------------------------------------------------===//
5240 // SSSE3 - Packed Binary Operator Instructions
5241 //===---------------------------------------------------------------------===//
5242
5243 /// SS3I_binop_rm_int - Simple SSSE3 bin op whose type can be v*{i8,i16,i32}.
5244 multiclass SS3I_binop_rm_int<bits<8> opc, string OpcodeStr,
5245                              Intrinsic IntId128, bit Is2Addr = 1> {
5246   let isCommutable = 1 in
5247   def rr128 : SS38I<opc, MRMSrcReg, (outs VR128:$dst),
5248        (ins VR128:$src1, VR128:$src2),
5249        !if(Is2Addr,
5250          !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5251          !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5252        [(set VR128:$dst, (IntId128 VR128:$src1, VR128:$src2))]>,
5253        OpSize;
5254   def rm128 : SS38I<opc, MRMSrcMem, (outs VR128:$dst),
5255        (ins VR128:$src1, i128mem:$src2),
5256        !if(Is2Addr,
5257          !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5258          !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5259        [(set VR128:$dst,
5260          (IntId128 VR128:$src1,
5261           (bitconvert (memopv2i64 addr:$src2))))]>, OpSize;
5262 }
5263
5264 multiclass SS3I_binop_rm_int_y<bits<8> opc, string OpcodeStr,
5265                                Intrinsic IntId256> {
5266   let isCommutable = 1 in
5267   def rr256 : SS38I<opc, MRMSrcReg, (outs VR256:$dst),
5268        (ins VR256:$src1, VR256:$src2),
5269        !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5270        [(set VR256:$dst, (IntId256 VR256:$src1, VR256:$src2))]>,
5271        OpSize;
5272   def rm256 : SS38I<opc, MRMSrcMem, (outs VR256:$dst),
5273        (ins VR256:$src1, i256mem:$src2),
5274        !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5275        [(set VR256:$dst,
5276          (IntId256 VR256:$src1,
5277           (bitconvert (memopv4i64 addr:$src2))))]>, OpSize;
5278 }
5279
5280 let ImmT = NoImm, Predicates = [HasAVX] in {
5281 let isCommutable = 0 in {
5282   defm VPHADDW    : SS3I_binop_rm_int<0x01, "vphaddw",
5283                                       int_x86_ssse3_phadd_w_128, 0>, VEX_4V;
5284   defm VPHADDD    : SS3I_binop_rm_int<0x02, "vphaddd",
5285                                       int_x86_ssse3_phadd_d_128, 0>, VEX_4V;
5286   defm VPHADDSW   : SS3I_binop_rm_int<0x03, "vphaddsw",
5287                                       int_x86_ssse3_phadd_sw_128, 0>, VEX_4V;
5288   defm VPHSUBW    : SS3I_binop_rm_int<0x05, "vphsubw",
5289                                       int_x86_ssse3_phsub_w_128, 0>, VEX_4V;
5290   defm VPHSUBD    : SS3I_binop_rm_int<0x06, "vphsubd",
5291                                       int_x86_ssse3_phsub_d_128, 0>, VEX_4V;
5292   defm VPHSUBSW   : SS3I_binop_rm_int<0x07, "vphsubsw",
5293                                       int_x86_ssse3_phsub_sw_128, 0>, VEX_4V;
5294   defm VPMADDUBSW : SS3I_binop_rm_int<0x04, "vpmaddubsw",
5295                                       int_x86_ssse3_pmadd_ub_sw_128, 0>, VEX_4V;
5296   defm VPSHUFB    : SS3I_binop_rm_int<0x00, "vpshufb",
5297                                       int_x86_ssse3_pshuf_b_128, 0>, VEX_4V;
5298   defm VPSIGNB    : SS3I_binop_rm_int<0x08, "vpsignb",
5299                                       int_x86_ssse3_psign_b_128, 0>, VEX_4V;
5300   defm VPSIGNW    : SS3I_binop_rm_int<0x09, "vpsignw",
5301                                       int_x86_ssse3_psign_w_128, 0>, VEX_4V;
5302   defm VPSIGND    : SS3I_binop_rm_int<0x0A, "vpsignd",
5303                                       int_x86_ssse3_psign_d_128, 0>, VEX_4V;
5304 }
5305 defm VPMULHRSW    : SS3I_binop_rm_int<0x0B, "vpmulhrsw",
5306                                       int_x86_ssse3_pmul_hr_sw_128, 0>, VEX_4V;
5307 }
5308
5309 let ImmT = NoImm, Predicates = [HasAVX2] in {
5310 let isCommutable = 0 in {
5311   defm VPHADDW    : SS3I_binop_rm_int_y<0x01, "vphaddw",
5312                                         int_x86_avx2_phadd_w>, VEX_4V;
5313   defm VPHADDD    : SS3I_binop_rm_int_y<0x02, "vphaddd",
5314                                         int_x86_avx2_phadd_d>, VEX_4V;
5315   defm VPHADDSW   : SS3I_binop_rm_int_y<0x03, "vphaddsw",
5316                                         int_x86_avx2_phadd_sw>, VEX_4V;
5317   defm VPHSUBW    : SS3I_binop_rm_int_y<0x05, "vphsubw",
5318                                         int_x86_avx2_phsub_w>, VEX_4V;
5319   defm VPHSUBD    : SS3I_binop_rm_int_y<0x06, "vphsubd",
5320                                         int_x86_avx2_phsub_d>, VEX_4V;
5321   defm VPHSUBSW   : SS3I_binop_rm_int_y<0x07, "vphsubsw",
5322                                         int_x86_avx2_phsub_sw>, VEX_4V;
5323   defm VPMADDUBSW : SS3I_binop_rm_int_y<0x04, "vpmaddubsw",
5324                                         int_x86_avx2_pmadd_ub_sw>, VEX_4V;
5325   defm VPSHUFB    : SS3I_binop_rm_int_y<0x00, "vpshufb",
5326                                         int_x86_avx2_pshuf_b>, VEX_4V;
5327   defm VPSIGNB    : SS3I_binop_rm_int_y<0x08, "vpsignb",
5328                                         int_x86_avx2_psign_b>, VEX_4V;
5329   defm VPSIGNW    : SS3I_binop_rm_int_y<0x09, "vpsignw",
5330                                         int_x86_avx2_psign_w>, VEX_4V;
5331   defm VPSIGND    : SS3I_binop_rm_int_y<0x0A, "vpsignd",
5332                                         int_x86_avx2_psign_d>, VEX_4V;
5333 }
5334 defm VPMULHRSW    : SS3I_binop_rm_int_y<0x0B, "vpmulhrsw",
5335                                         int_x86_avx2_pmul_hr_sw>, VEX_4V;
5336 }
5337
5338 // None of these have i8 immediate fields.
5339 let ImmT = NoImm, Constraints = "$src1 = $dst" in {
5340 let isCommutable = 0 in {
5341   defm PHADDW    : SS3I_binop_rm_int<0x01, "phaddw",
5342                                      int_x86_ssse3_phadd_w_128>;
5343   defm PHADDD    : SS3I_binop_rm_int<0x02, "phaddd",
5344                                      int_x86_ssse3_phadd_d_128>;
5345   defm PHADDSW   : SS3I_binop_rm_int<0x03, "phaddsw",
5346                                      int_x86_ssse3_phadd_sw_128>;
5347   defm PHSUBW    : SS3I_binop_rm_int<0x05, "phsubw",
5348                                      int_x86_ssse3_phsub_w_128>;
5349   defm PHSUBD    : SS3I_binop_rm_int<0x06, "phsubd",
5350                                      int_x86_ssse3_phsub_d_128>;
5351   defm PHSUBSW   : SS3I_binop_rm_int<0x07, "phsubsw",
5352                                      int_x86_ssse3_phsub_sw_128>;
5353   defm PMADDUBSW : SS3I_binop_rm_int<0x04, "pmaddubsw",
5354                                      int_x86_ssse3_pmadd_ub_sw_128>;
5355   defm PSHUFB    : SS3I_binop_rm_int<0x00, "pshufb",
5356                                      int_x86_ssse3_pshuf_b_128>;
5357   defm PSIGNB    : SS3I_binop_rm_int<0x08, "psignb",
5358                                      int_x86_ssse3_psign_b_128>;
5359   defm PSIGNW    : SS3I_binop_rm_int<0x09, "psignw",
5360                                      int_x86_ssse3_psign_w_128>;
5361   defm PSIGND    : SS3I_binop_rm_int<0x0A, "psignd",
5362                                        int_x86_ssse3_psign_d_128>;
5363 }
5364 defm PMULHRSW    : SS3I_binop_rm_int<0x0B, "pmulhrsw",
5365                                      int_x86_ssse3_pmul_hr_sw_128>;
5366 }
5367
5368 let Predicates = [HasAVX] in {
5369   def : Pat<(X86pshufb VR128:$src, VR128:$mask),
5370             (VPSHUFBrr128 VR128:$src, VR128:$mask)>;
5371   def : Pat<(X86pshufb VR128:$src, (bc_v16i8 (memopv2i64 addr:$mask))),
5372             (VPSHUFBrm128 VR128:$src, addr:$mask)>;
5373
5374   def : Pat<(v16i8 (X86psign VR128:$src1, VR128:$src2)),
5375             (VPSIGNBrr128 VR128:$src1, VR128:$src2)>;
5376   def : Pat<(v8i16 (X86psign VR128:$src1, VR128:$src2)),
5377             (VPSIGNWrr128 VR128:$src1, VR128:$src2)>;
5378   def : Pat<(v4i32 (X86psign VR128:$src1, VR128:$src2)),
5379             (VPSIGNDrr128 VR128:$src1, VR128:$src2)>;
5380
5381   def : Pat<(v8i16 (X86hadd VR128:$src1, VR128:$src2)),
5382             (VPHADDWrr128 VR128:$src1, VR128:$src2)>;
5383   def : Pat<(v4i32 (X86hadd VR128:$src1, VR128:$src2)),
5384             (VPHADDDrr128 VR128:$src1, VR128:$src2)>;
5385   def : Pat<(v8i16 (X86hsub VR128:$src1, VR128:$src2)),
5386             (VPHSUBWrr128 VR128:$src1, VR128:$src2)>;
5387   def : Pat<(v4i32 (X86hsub VR128:$src1, VR128:$src2)),
5388             (VPHSUBDrr128 VR128:$src1, VR128:$src2)>;
5389 }
5390
5391 let Predicates = [HasAVX2] in {
5392   def : Pat<(v32i8 (X86psign VR256:$src1, VR256:$src2)),
5393             (VPSIGNBrr256 VR256:$src1, VR256:$src2)>;
5394   def : Pat<(v16i16 (X86psign VR256:$src1, VR256:$src2)),
5395             (VPSIGNWrr256 VR256:$src1, VR256:$src2)>;
5396   def : Pat<(v8i32 (X86psign VR256:$src1, VR256:$src2)),
5397             (VPSIGNDrr256 VR256:$src1, VR256:$src2)>;
5398
5399   def : Pat<(v16i16 (X86hadd VR256:$src1, VR256:$src2)),
5400             (VPHADDWrr256 VR256:$src1, VR256:$src2)>;
5401   def : Pat<(v8i32 (X86hadd VR256:$src1, VR256:$src2)),
5402             (VPHADDDrr256 VR256:$src1, VR256:$src2)>;
5403   def : Pat<(v16i16 (X86hsub VR256:$src1, VR256:$src2)),
5404             (VPHSUBWrr256 VR256:$src1, VR256:$src2)>;
5405   def : Pat<(v8i32 (X86hsub VR256:$src1, VR256:$src2)),
5406             (VPHSUBDrr256 VR256:$src1, VR256:$src2)>;
5407 }
5408
5409 let Predicates = [HasSSSE3] in {
5410   def : Pat<(X86pshufb VR128:$src, VR128:$mask),
5411             (PSHUFBrr128 VR128:$src, VR128:$mask)>;
5412   def : Pat<(X86pshufb VR128:$src, (bc_v16i8 (memopv2i64 addr:$mask))),
5413             (PSHUFBrm128 VR128:$src, addr:$mask)>;
5414
5415   def : Pat<(v16i8 (X86psign VR128:$src1, VR128:$src2)),
5416             (PSIGNBrr128 VR128:$src1, VR128:$src2)>;
5417   def : Pat<(v8i16 (X86psign VR128:$src1, VR128:$src2)),
5418             (PSIGNWrr128 VR128:$src1, VR128:$src2)>;
5419   def : Pat<(v4i32 (X86psign VR128:$src1, VR128:$src2)),
5420             (PSIGNDrr128 VR128:$src1, VR128:$src2)>;
5421
5422   def : Pat<(v8i16 (X86hadd VR128:$src1, VR128:$src2)),
5423             (PHADDWrr128 VR128:$src1, VR128:$src2)>;
5424   def : Pat<(v4i32 (X86hadd VR128:$src1, VR128:$src2)),
5425             (PHADDDrr128 VR128:$src1, VR128:$src2)>;
5426   def : Pat<(v8i16 (X86hsub VR128:$src1, VR128:$src2)),
5427             (PHSUBWrr128 VR128:$src1, VR128:$src2)>;
5428   def : Pat<(v4i32 (X86hsub VR128:$src1, VR128:$src2)),
5429             (PHSUBDrr128 VR128:$src1, VR128:$src2)>;
5430 }
5431
5432 //===---------------------------------------------------------------------===//
5433 // SSSE3 - Packed Align Instruction Patterns
5434 //===---------------------------------------------------------------------===//
5435
5436 multiclass ssse3_palign<string asm, bit Is2Addr = 1> {
5437   let neverHasSideEffects = 1 in {
5438   def R128rr : SS3AI<0x0F, MRMSrcReg, (outs VR128:$dst),
5439       (ins VR128:$src1, VR128:$src2, i8imm:$src3),
5440       !if(Is2Addr,
5441         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5442         !strconcat(asm,
5443                   "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5444       []>, OpSize;
5445   let mayLoad = 1 in
5446   def R128rm : SS3AI<0x0F, MRMSrcMem, (outs VR128:$dst),
5447       (ins VR128:$src1, i128mem:$src2, i8imm:$src3),
5448       !if(Is2Addr,
5449         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5450         !strconcat(asm,
5451                   "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5452       []>, OpSize;
5453   }
5454 }
5455
5456 multiclass ssse3_palign_y<string asm, bit Is2Addr = 1> {
5457   let neverHasSideEffects = 1 in {
5458   def R256rr : SS3AI<0x0F, MRMSrcReg, (outs VR256:$dst),
5459       (ins VR256:$src1, VR256:$src2, i8imm:$src3),
5460       !strconcat(asm,
5461                  "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
5462       []>, OpSize;
5463   let mayLoad = 1 in
5464   def R256rm : SS3AI<0x0F, MRMSrcMem, (outs VR256:$dst),
5465       (ins VR256:$src1, i256mem:$src2, i8imm:$src3),
5466       !strconcat(asm,
5467                  "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
5468       []>, OpSize;
5469   }
5470 }
5471
5472 let Predicates = [HasAVX] in
5473   defm VPALIGN : ssse3_palign<"vpalignr", 0>, VEX_4V;
5474 let Predicates = [HasAVX2] in
5475   defm VPALIGN : ssse3_palign_y<"vpalignr", 0>, VEX_4V;
5476 let Constraints = "$src1 = $dst", Predicates = [HasSSSE3] in
5477   defm PALIGN : ssse3_palign<"palignr">;
5478
5479 let Predicates = [HasAVX] in {
5480 def : Pat<(v4i32 (X86PAlign VR128:$src1, VR128:$src2, (i8 imm:$imm))),
5481           (VPALIGNR128rr VR128:$src2, VR128:$src1, imm:$imm)>;
5482 def : Pat<(v4f32 (X86PAlign VR128:$src1, VR128:$src2, (i8 imm:$imm))),
5483           (VPALIGNR128rr VR128:$src2, VR128:$src1, imm:$imm)>;
5484 def : Pat<(v8i16 (X86PAlign VR128:$src1, VR128:$src2, (i8 imm:$imm))),
5485           (VPALIGNR128rr VR128:$src2, VR128:$src1, imm:$imm)>;
5486 def : Pat<(v16i8 (X86PAlign VR128:$src1, VR128:$src2, (i8 imm:$imm))),
5487           (VPALIGNR128rr VR128:$src2, VR128:$src1, imm:$imm)>;
5488 }
5489
5490 let Predicates = [HasSSSE3] in {
5491 def : Pat<(v4i32 (X86PAlign VR128:$src1, VR128:$src2, (i8 imm:$imm))),
5492           (PALIGNR128rr VR128:$src2, VR128:$src1, imm:$imm)>;
5493 def : Pat<(v4f32 (X86PAlign VR128:$src1, VR128:$src2, (i8 imm:$imm))),
5494           (PALIGNR128rr VR128:$src2, VR128:$src1, imm:$imm)>;
5495 def : Pat<(v8i16 (X86PAlign VR128:$src1, VR128:$src2, (i8 imm:$imm))),
5496           (PALIGNR128rr VR128:$src2, VR128:$src1, imm:$imm)>;
5497 def : Pat<(v16i8 (X86PAlign VR128:$src1, VR128:$src2, (i8 imm:$imm))),
5498           (PALIGNR128rr VR128:$src2, VR128:$src1, imm:$imm)>;
5499 }
5500
5501 //===---------------------------------------------------------------------===//
5502 // SSSE3 - Thread synchronization
5503 //===---------------------------------------------------------------------===//
5504
5505 let usesCustomInserter = 1 in {
5506 def MONITOR : PseudoI<(outs), (ins i32mem:$src1, GR32:$src2, GR32:$src3),
5507                 [(int_x86_sse3_monitor addr:$src1, GR32:$src2, GR32:$src3)]>,
5508                 Requires<[HasSSE3]>;
5509 def MWAIT : PseudoI<(outs), (ins GR32:$src1, GR32:$src2),
5510                 [(int_x86_sse3_mwait GR32:$src1, GR32:$src2)]>,
5511                 Requires<[HasSSE3]>;
5512 }
5513
5514 let Uses = [EAX, ECX, EDX] in
5515 def MONITORrrr : I<0x01, MRM_C8, (outs), (ins), "monitor", []>, TB,
5516                  Requires<[HasSSE3]>;
5517 let Uses = [ECX, EAX] in
5518 def MWAITrr   : I<0x01, MRM_C9, (outs), (ins), "mwait", []>, TB,
5519                 Requires<[HasSSE3]>;
5520
5521 def : InstAlias<"mwait %eax, %ecx", (MWAITrr)>, Requires<[In32BitMode]>;
5522 def : InstAlias<"mwait %rax, %rcx", (MWAITrr)>, Requires<[In64BitMode]>;
5523
5524 def : InstAlias<"monitor %eax, %ecx, %edx", (MONITORrrr)>,
5525       Requires<[In32BitMode]>;
5526 def : InstAlias<"monitor %rax, %rcx, %rdx", (MONITORrrr)>,
5527       Requires<[In64BitMode]>;
5528
5529 //===----------------------------------------------------------------------===//
5530 // SSE4.1 - Packed Move with Sign/Zero Extend
5531 //===----------------------------------------------------------------------===//
5532
5533 multiclass SS41I_binop_rm_int8<bits<8> opc, string OpcodeStr, Intrinsic IntId> {
5534   def rr : SS48I<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
5535                  !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5536                  [(set VR128:$dst, (IntId VR128:$src))]>, OpSize;
5537
5538   def rm : SS48I<opc, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
5539                  !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5540        [(set VR128:$dst,
5541          (IntId (bitconvert (v2i64 (scalar_to_vector (loadi64 addr:$src))))))]>,
5542        OpSize;
5543 }
5544
5545 multiclass SS41I_binop_rm_int16_y<bits<8> opc, string OpcodeStr,
5546                                  Intrinsic IntId> {
5547   def Yrr : SS48I<opc, MRMSrcReg, (outs VR256:$dst), (ins VR128:$src),
5548                   !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5549                   [(set VR256:$dst, (IntId VR128:$src))]>, OpSize;
5550
5551   def Yrm : SS48I<opc, MRMSrcMem, (outs VR256:$dst), (ins i128mem:$src),
5552                   !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5553                   [(set VR256:$dst, (IntId (load addr:$src)))]>, OpSize;
5554 }
5555
5556 let Predicates = [HasAVX] in {
5557 defm VPMOVSXBW : SS41I_binop_rm_int8<0x20, "vpmovsxbw", int_x86_sse41_pmovsxbw>,
5558                                      VEX;
5559 defm VPMOVSXWD : SS41I_binop_rm_int8<0x23, "vpmovsxwd", int_x86_sse41_pmovsxwd>,
5560                                      VEX;
5561 defm VPMOVSXDQ : SS41I_binop_rm_int8<0x25, "vpmovsxdq", int_x86_sse41_pmovsxdq>,
5562                                      VEX;
5563 defm VPMOVZXBW : SS41I_binop_rm_int8<0x30, "vpmovzxbw", int_x86_sse41_pmovzxbw>,
5564                                      VEX;
5565 defm VPMOVZXWD : SS41I_binop_rm_int8<0x33, "vpmovzxwd", int_x86_sse41_pmovzxwd>,
5566                                      VEX;
5567 defm VPMOVZXDQ : SS41I_binop_rm_int8<0x35, "vpmovzxdq", int_x86_sse41_pmovzxdq>,
5568                                      VEX;
5569 }
5570
5571 let Predicates = [HasAVX2] in {
5572 defm VPMOVSXBW : SS41I_binop_rm_int16_y<0x20, "vpmovsxbw",
5573                                         int_x86_avx2_pmovsxbw>, VEX;
5574 defm VPMOVSXWD : SS41I_binop_rm_int16_y<0x23, "vpmovsxwd",
5575                                         int_x86_avx2_pmovsxwd>, VEX;
5576 defm VPMOVSXDQ : SS41I_binop_rm_int16_y<0x25, "vpmovsxdq",
5577                                         int_x86_avx2_pmovsxdq>, VEX;
5578 defm VPMOVZXBW : SS41I_binop_rm_int16_y<0x30, "vpmovzxbw",
5579                                         int_x86_avx2_pmovzxbw>, VEX;
5580 defm VPMOVZXWD : SS41I_binop_rm_int16_y<0x33, "vpmovzxwd",
5581                                         int_x86_avx2_pmovzxwd>, VEX;
5582 defm VPMOVZXDQ : SS41I_binop_rm_int16_y<0x35, "vpmovzxdq",
5583                                         int_x86_avx2_pmovzxdq>, VEX;
5584 }
5585
5586 defm PMOVSXBW   : SS41I_binop_rm_int8<0x20, "pmovsxbw", int_x86_sse41_pmovsxbw>;
5587 defm PMOVSXWD   : SS41I_binop_rm_int8<0x23, "pmovsxwd", int_x86_sse41_pmovsxwd>;
5588 defm PMOVSXDQ   : SS41I_binop_rm_int8<0x25, "pmovsxdq", int_x86_sse41_pmovsxdq>;
5589 defm PMOVZXBW   : SS41I_binop_rm_int8<0x30, "pmovzxbw", int_x86_sse41_pmovzxbw>;
5590 defm PMOVZXWD   : SS41I_binop_rm_int8<0x33, "pmovzxwd", int_x86_sse41_pmovzxwd>;
5591 defm PMOVZXDQ   : SS41I_binop_rm_int8<0x35, "pmovzxdq", int_x86_sse41_pmovzxdq>;
5592
5593 let Predicates = [HasAVX] in {
5594   // Common patterns involving scalar load.
5595   def : Pat<(int_x86_sse41_pmovsxbw (vzmovl_v2i64 addr:$src)),
5596             (VPMOVSXBWrm addr:$src)>;
5597   def : Pat<(int_x86_sse41_pmovsxbw (vzload_v2i64 addr:$src)),
5598             (VPMOVSXBWrm addr:$src)>;
5599
5600   def : Pat<(int_x86_sse41_pmovsxwd (vzmovl_v2i64 addr:$src)),
5601             (VPMOVSXWDrm addr:$src)>;
5602   def : Pat<(int_x86_sse41_pmovsxwd (vzload_v2i64 addr:$src)),
5603             (VPMOVSXWDrm addr:$src)>;
5604
5605   def : Pat<(int_x86_sse41_pmovsxdq (vzmovl_v2i64 addr:$src)),
5606             (VPMOVSXDQrm addr:$src)>;
5607   def : Pat<(int_x86_sse41_pmovsxdq (vzload_v2i64 addr:$src)),
5608             (VPMOVSXDQrm addr:$src)>;
5609
5610   def : Pat<(int_x86_sse41_pmovzxbw (vzmovl_v2i64 addr:$src)),
5611             (VPMOVZXBWrm addr:$src)>;
5612   def : Pat<(int_x86_sse41_pmovzxbw (vzload_v2i64 addr:$src)),
5613             (VPMOVZXBWrm addr:$src)>;
5614
5615   def : Pat<(int_x86_sse41_pmovzxwd (vzmovl_v2i64 addr:$src)),
5616             (VPMOVZXWDrm addr:$src)>;
5617   def : Pat<(int_x86_sse41_pmovzxwd (vzload_v2i64 addr:$src)),
5618             (VPMOVZXWDrm addr:$src)>;
5619
5620   def : Pat<(int_x86_sse41_pmovzxdq (vzmovl_v2i64 addr:$src)),
5621             (VPMOVZXDQrm addr:$src)>;
5622   def : Pat<(int_x86_sse41_pmovzxdq (vzload_v2i64 addr:$src)),
5623             (VPMOVZXDQrm addr:$src)>;
5624 }
5625
5626 let Predicates = [HasSSE41] in {
5627   // Common patterns involving scalar load.
5628   def : Pat<(int_x86_sse41_pmovsxbw (vzmovl_v2i64 addr:$src)),
5629             (PMOVSXBWrm addr:$src)>;
5630   def : Pat<(int_x86_sse41_pmovsxbw (vzload_v2i64 addr:$src)),
5631             (PMOVSXBWrm addr:$src)>;
5632
5633   def : Pat<(int_x86_sse41_pmovsxwd (vzmovl_v2i64 addr:$src)),
5634             (PMOVSXWDrm addr:$src)>;
5635   def : Pat<(int_x86_sse41_pmovsxwd (vzload_v2i64 addr:$src)),
5636             (PMOVSXWDrm addr:$src)>;
5637
5638   def : Pat<(int_x86_sse41_pmovsxdq (vzmovl_v2i64 addr:$src)),
5639             (PMOVSXDQrm addr:$src)>;
5640   def : Pat<(int_x86_sse41_pmovsxdq (vzload_v2i64 addr:$src)),
5641             (PMOVSXDQrm addr:$src)>;
5642
5643   def : Pat<(int_x86_sse41_pmovzxbw (vzmovl_v2i64 addr:$src)),
5644             (PMOVZXBWrm addr:$src)>;
5645   def : Pat<(int_x86_sse41_pmovzxbw (vzload_v2i64 addr:$src)),
5646             (PMOVZXBWrm addr:$src)>;
5647
5648   def : Pat<(int_x86_sse41_pmovzxwd (vzmovl_v2i64 addr:$src)),
5649             (PMOVZXWDrm addr:$src)>;
5650   def : Pat<(int_x86_sse41_pmovzxwd (vzload_v2i64 addr:$src)),
5651             (PMOVZXWDrm addr:$src)>;
5652
5653   def : Pat<(int_x86_sse41_pmovzxdq (vzmovl_v2i64 addr:$src)),
5654             (PMOVZXDQrm addr:$src)>;
5655   def : Pat<(int_x86_sse41_pmovzxdq (vzload_v2i64 addr:$src)),
5656             (PMOVZXDQrm addr:$src)>;
5657 }
5658
5659
5660 multiclass SS41I_binop_rm_int4<bits<8> opc, string OpcodeStr, Intrinsic IntId> {
5661   def rr : SS48I<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
5662                  !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5663                  [(set VR128:$dst, (IntId VR128:$src))]>, OpSize;
5664
5665   def rm : SS48I<opc, MRMSrcMem, (outs VR128:$dst), (ins i32mem:$src),
5666                  !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5667        [(set VR128:$dst,
5668          (IntId (bitconvert (v4i32 (scalar_to_vector (loadi32 addr:$src))))))]>,
5669           OpSize;
5670 }
5671
5672 multiclass SS41I_binop_rm_int8_y<bits<8> opc, string OpcodeStr,
5673                                  Intrinsic IntId> {
5674   def Yrr : SS48I<opc, MRMSrcReg, (outs VR256:$dst), (ins VR128:$src),
5675                   !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5676                   [(set VR256:$dst, (IntId VR128:$src))]>, OpSize;
5677
5678   def Yrm : SS48I<opc, MRMSrcMem, (outs VR256:$dst), (ins i32mem:$src),
5679                   !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5680        [(set VR256:$dst,
5681          (IntId (bitconvert (v2i64 (scalar_to_vector (loadi64 addr:$src))))))]>,
5682           OpSize;
5683 }
5684
5685 let Predicates = [HasAVX] in {
5686 defm VPMOVSXBD : SS41I_binop_rm_int4<0x21, "vpmovsxbd", int_x86_sse41_pmovsxbd>,
5687                                      VEX;
5688 defm VPMOVSXWQ : SS41I_binop_rm_int4<0x24, "vpmovsxwq", int_x86_sse41_pmovsxwq>,
5689                                      VEX;
5690 defm VPMOVZXBD : SS41I_binop_rm_int4<0x31, "vpmovzxbd", int_x86_sse41_pmovzxbd>,
5691                                      VEX;
5692 defm VPMOVZXWQ : SS41I_binop_rm_int4<0x34, "vpmovzxwq", int_x86_sse41_pmovzxwq>,
5693                                      VEX;
5694 }
5695
5696 let Predicates = [HasAVX2] in {
5697 defm VPMOVSXBD : SS41I_binop_rm_int8_y<0x21, "vpmovsxbd",
5698                                        int_x86_avx2_pmovsxbd>, VEX;
5699 defm VPMOVSXWQ : SS41I_binop_rm_int8_y<0x24, "vpmovsxwq",
5700                                        int_x86_avx2_pmovsxwq>, VEX;
5701 defm VPMOVZXBD : SS41I_binop_rm_int8_y<0x31, "vpmovzxbd",
5702                                        int_x86_avx2_pmovzxbd>, VEX;
5703 defm VPMOVZXWQ : SS41I_binop_rm_int8_y<0x34, "vpmovzxwq",
5704                                        int_x86_avx2_pmovzxwq>, VEX;
5705 }
5706
5707 defm PMOVSXBD   : SS41I_binop_rm_int4<0x21, "pmovsxbd", int_x86_sse41_pmovsxbd>;
5708 defm PMOVSXWQ   : SS41I_binop_rm_int4<0x24, "pmovsxwq", int_x86_sse41_pmovsxwq>;
5709 defm PMOVZXBD   : SS41I_binop_rm_int4<0x31, "pmovzxbd", int_x86_sse41_pmovzxbd>;
5710 defm PMOVZXWQ   : SS41I_binop_rm_int4<0x34, "pmovzxwq", int_x86_sse41_pmovzxwq>;
5711
5712 let Predicates = [HasAVX] in {
5713   // Common patterns involving scalar load
5714   def : Pat<(int_x86_sse41_pmovsxbd (vzmovl_v4i32 addr:$src)),
5715             (VPMOVSXBDrm addr:$src)>;
5716   def : Pat<(int_x86_sse41_pmovsxwq (vzmovl_v4i32 addr:$src)),
5717             (VPMOVSXWQrm addr:$src)>;
5718
5719   def : Pat<(int_x86_sse41_pmovzxbd (vzmovl_v4i32 addr:$src)),
5720             (VPMOVZXBDrm addr:$src)>;
5721   def : Pat<(int_x86_sse41_pmovzxwq (vzmovl_v4i32 addr:$src)),
5722             (VPMOVZXWQrm addr:$src)>;
5723 }
5724
5725 let Predicates = [HasSSE41] in {
5726   // Common patterns involving scalar load
5727   def : Pat<(int_x86_sse41_pmovsxbd (vzmovl_v4i32 addr:$src)),
5728             (PMOVSXBDrm addr:$src)>;
5729   def : Pat<(int_x86_sse41_pmovsxwq (vzmovl_v4i32 addr:$src)),
5730             (PMOVSXWQrm addr:$src)>;
5731
5732   def : Pat<(int_x86_sse41_pmovzxbd (vzmovl_v4i32 addr:$src)),
5733             (PMOVZXBDrm addr:$src)>;
5734   def : Pat<(int_x86_sse41_pmovzxwq (vzmovl_v4i32 addr:$src)),
5735             (PMOVZXWQrm addr:$src)>;
5736 }
5737
5738 multiclass SS41I_binop_rm_int2<bits<8> opc, string OpcodeStr, Intrinsic IntId> {
5739   def rr : SS48I<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
5740                  !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5741                  [(set VR128:$dst, (IntId VR128:$src))]>, OpSize;
5742
5743   // Expecting a i16 load any extended to i32 value.
5744   def rm : SS48I<opc, MRMSrcMem, (outs VR128:$dst), (ins i16mem:$src),
5745                  !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5746                  [(set VR128:$dst, (IntId (bitconvert
5747                      (v4i32 (scalar_to_vector (loadi16_anyext addr:$src))))))]>,
5748                  OpSize;
5749 }
5750
5751 multiclass SS41I_binop_rm_int4_y<bits<8> opc, string OpcodeStr,
5752                                  Intrinsic IntId> {
5753   def Yrr : SS48I<opc, MRMSrcReg, (outs VR256:$dst), (ins VR128:$src),
5754                  !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5755                  [(set VR256:$dst, (IntId VR128:$src))]>, OpSize;
5756
5757   // Expecting a i16 load any extended to i32 value.
5758   def Yrm : SS48I<opc, MRMSrcMem, (outs VR256:$dst), (ins i16mem:$src),
5759                   !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5760                   [(set VR256:$dst, (IntId (bitconvert
5761                       (v4i32 (scalar_to_vector (loadi32 addr:$src))))))]>,
5762                   OpSize;
5763 }
5764
5765 let Predicates = [HasAVX] in {
5766 defm VPMOVSXBQ : SS41I_binop_rm_int2<0x22, "vpmovsxbq", int_x86_sse41_pmovsxbq>,
5767                                      VEX;
5768 defm VPMOVZXBQ : SS41I_binop_rm_int2<0x32, "vpmovzxbq", int_x86_sse41_pmovzxbq>,
5769                                      VEX;
5770 }
5771 let Predicates = [HasAVX2] in {
5772 defm VPMOVSXBQ : SS41I_binop_rm_int4_y<0x22, "vpmovsxbq",
5773                                        int_x86_avx2_pmovsxbq>, VEX;
5774 defm VPMOVZXBQ : SS41I_binop_rm_int4_y<0x32, "vpmovzxbq",
5775                                        int_x86_avx2_pmovzxbq>, VEX;
5776 }
5777 defm PMOVSXBQ   : SS41I_binop_rm_int2<0x22, "pmovsxbq", int_x86_sse41_pmovsxbq>;
5778 defm PMOVZXBQ   : SS41I_binop_rm_int2<0x32, "pmovzxbq", int_x86_sse41_pmovzxbq>;
5779
5780 let Predicates = [HasAVX] in {
5781   // Common patterns involving scalar load
5782   def : Pat<(int_x86_sse41_pmovsxbq
5783               (bitconvert (v4i32 (X86vzmovl
5784                             (v4i32 (scalar_to_vector (loadi32 addr:$src))))))),
5785             (VPMOVSXBQrm addr:$src)>;
5786
5787   def : Pat<(int_x86_sse41_pmovzxbq
5788               (bitconvert (v4i32 (X86vzmovl
5789                             (v4i32 (scalar_to_vector (loadi32 addr:$src))))))),
5790             (VPMOVZXBQrm addr:$src)>;
5791 }
5792
5793 let Predicates = [HasSSE41] in {
5794   // Common patterns involving scalar load
5795   def : Pat<(int_x86_sse41_pmovsxbq
5796               (bitconvert (v4i32 (X86vzmovl
5797                             (v4i32 (scalar_to_vector (loadi32 addr:$src))))))),
5798             (PMOVSXBQrm addr:$src)>;
5799
5800   def : Pat<(int_x86_sse41_pmovzxbq
5801               (bitconvert (v4i32 (X86vzmovl
5802                             (v4i32 (scalar_to_vector (loadi32 addr:$src))))))),
5803             (PMOVZXBQrm addr:$src)>;
5804 }
5805
5806 //===----------------------------------------------------------------------===//
5807 // SSE4.1 - Extract Instructions
5808 //===----------------------------------------------------------------------===//
5809
5810 /// SS41I_binop_ext8 - SSE 4.1 extract 8 bits to 32 bit reg or 8 bit mem
5811 multiclass SS41I_extract8<bits<8> opc, string OpcodeStr> {
5812   def rr : SS4AIi8<opc, MRMDestReg, (outs GR32:$dst),
5813                  (ins VR128:$src1, i32i8imm:$src2),
5814                  !strconcat(OpcodeStr,
5815                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5816                  [(set GR32:$dst, (X86pextrb (v16i8 VR128:$src1), imm:$src2))]>,
5817                  OpSize;
5818   let neverHasSideEffects = 1, mayStore = 1 in
5819   def mr : SS4AIi8<opc, MRMDestMem, (outs),
5820                  (ins i8mem:$dst, VR128:$src1, i32i8imm:$src2),
5821                  !strconcat(OpcodeStr,
5822                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5823                  []>, OpSize;
5824 // FIXME:
5825 // There's an AssertZext in the way of writing the store pattern
5826 // (store (i8 (trunc (X86pextrb (v16i8 VR128:$src1), imm:$src2))), addr:$dst)
5827 }
5828
5829 let Predicates = [HasAVX] in {
5830   defm VPEXTRB : SS41I_extract8<0x14, "vpextrb">, VEX;
5831   def  VPEXTRBrr64 : SS4AIi8<0x14, MRMDestReg, (outs GR64:$dst),
5832          (ins VR128:$src1, i32i8imm:$src2),
5833          "vpextrb\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>, OpSize, VEX;
5834 }
5835
5836 defm PEXTRB      : SS41I_extract8<0x14, "pextrb">;
5837
5838
5839 /// SS41I_extract16 - SSE 4.1 extract 16 bits to memory destination
5840 multiclass SS41I_extract16<bits<8> opc, string OpcodeStr> {
5841   let neverHasSideEffects = 1, mayStore = 1 in
5842   def mr : SS4AIi8<opc, MRMDestMem, (outs),
5843                  (ins i16mem:$dst, VR128:$src1, i32i8imm:$src2),
5844                  !strconcat(OpcodeStr,
5845                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5846                  []>, OpSize;
5847 // FIXME:
5848 // There's an AssertZext in the way of writing the store pattern
5849 // (store (i16 (trunc (X86pextrw (v16i8 VR128:$src1), imm:$src2))), addr:$dst)
5850 }
5851
5852 let Predicates = [HasAVX] in
5853   defm VPEXTRW : SS41I_extract16<0x15, "vpextrw">, VEX;
5854
5855 defm PEXTRW      : SS41I_extract16<0x15, "pextrw">;
5856
5857
5858 /// SS41I_extract32 - SSE 4.1 extract 32 bits to int reg or memory destination
5859 multiclass SS41I_extract32<bits<8> opc, string OpcodeStr> {
5860   def rr : SS4AIi8<opc, MRMDestReg, (outs GR32:$dst),
5861                  (ins VR128:$src1, i32i8imm:$src2),
5862                  !strconcat(OpcodeStr,
5863                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5864                  [(set GR32:$dst,
5865                   (extractelt (v4i32 VR128:$src1), imm:$src2))]>, OpSize;
5866   def mr : SS4AIi8<opc, MRMDestMem, (outs),
5867                  (ins i32mem:$dst, VR128:$src1, i32i8imm:$src2),
5868                  !strconcat(OpcodeStr,
5869                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5870                  [(store (extractelt (v4i32 VR128:$src1), imm:$src2),
5871                           addr:$dst)]>, OpSize;
5872 }
5873
5874 let Predicates = [HasAVX] in
5875   defm VPEXTRD : SS41I_extract32<0x16, "vpextrd">, VEX;
5876
5877 defm PEXTRD      : SS41I_extract32<0x16, "pextrd">;
5878
5879 /// SS41I_extract32 - SSE 4.1 extract 32 bits to int reg or memory destination
5880 multiclass SS41I_extract64<bits<8> opc, string OpcodeStr> {
5881   def rr : SS4AIi8<opc, MRMDestReg, (outs GR64:$dst),
5882                  (ins VR128:$src1, i32i8imm:$src2),
5883                  !strconcat(OpcodeStr,
5884                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5885                  [(set GR64:$dst,
5886                   (extractelt (v2i64 VR128:$src1), imm:$src2))]>, OpSize, REX_W;
5887   def mr : SS4AIi8<opc, MRMDestMem, (outs),
5888                  (ins i64mem:$dst, VR128:$src1, i32i8imm:$src2),
5889                  !strconcat(OpcodeStr,
5890                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5891                  [(store (extractelt (v2i64 VR128:$src1), imm:$src2),
5892                           addr:$dst)]>, OpSize, REX_W;
5893 }
5894
5895 let Predicates = [HasAVX] in
5896   defm VPEXTRQ : SS41I_extract64<0x16, "vpextrq">, VEX, VEX_W;
5897
5898 defm PEXTRQ      : SS41I_extract64<0x16, "pextrq">;
5899
5900 /// SS41I_extractf32 - SSE 4.1 extract 32 bits fp value to int reg or memory
5901 /// destination
5902 multiclass SS41I_extractf32<bits<8> opc, string OpcodeStr> {
5903   def rr : SS4AIi8<opc, MRMDestReg, (outs GR32:$dst),
5904                  (ins VR128:$src1, i32i8imm:$src2),
5905                  !strconcat(OpcodeStr,
5906                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5907                  [(set GR32:$dst,
5908                     (extractelt (bc_v4i32 (v4f32 VR128:$src1)), imm:$src2))]>,
5909            OpSize;
5910   def mr : SS4AIi8<opc, MRMDestMem, (outs),
5911                  (ins f32mem:$dst, VR128:$src1, i32i8imm:$src2),
5912                  !strconcat(OpcodeStr,
5913                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5914                  [(store (extractelt (bc_v4i32 (v4f32 VR128:$src1)), imm:$src2),
5915                           addr:$dst)]>, OpSize;
5916 }
5917
5918 let ExeDomain = SSEPackedSingle in {
5919   let Predicates = [HasAVX] in {
5920     defm VEXTRACTPS : SS41I_extractf32<0x17, "vextractps">, VEX;
5921     def VEXTRACTPSrr64 : SS4AIi8<0x17, MRMDestReg, (outs GR64:$dst),
5922                     (ins VR128:$src1, i32i8imm:$src2),
5923                     "vextractps \t{$src2, $src1, $dst|$dst, $src1, $src2}",
5924                     []>, OpSize, VEX;
5925   }
5926   defm EXTRACTPS   : SS41I_extractf32<0x17, "extractps">;
5927 }
5928
5929 // Also match an EXTRACTPS store when the store is done as f32 instead of i32.
5930 def : Pat<(store (f32 (bitconvert (extractelt (bc_v4i32 (v4f32 VR128:$src1)),
5931                                               imm:$src2))),
5932                  addr:$dst),
5933           (VEXTRACTPSmr addr:$dst, VR128:$src1, imm:$src2)>,
5934           Requires<[HasAVX]>;
5935 def : Pat<(store (f32 (bitconvert (extractelt (bc_v4i32 (v4f32 VR128:$src1)),
5936                                               imm:$src2))),
5937                  addr:$dst),
5938           (EXTRACTPSmr addr:$dst, VR128:$src1, imm:$src2)>,
5939           Requires<[HasSSE41]>;
5940
5941 //===----------------------------------------------------------------------===//
5942 // SSE4.1 - Insert Instructions
5943 //===----------------------------------------------------------------------===//
5944
5945 multiclass SS41I_insert8<bits<8> opc, string asm, bit Is2Addr = 1> {
5946   def rr : SS4AIi8<opc, MRMSrcReg, (outs VR128:$dst),
5947       (ins VR128:$src1, GR32:$src2, i32i8imm:$src3),
5948       !if(Is2Addr,
5949         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5950         !strconcat(asm,
5951                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5952       [(set VR128:$dst,
5953         (X86pinsrb VR128:$src1, GR32:$src2, imm:$src3))]>, OpSize;
5954   def rm : SS4AIi8<opc, MRMSrcMem, (outs VR128:$dst),
5955       (ins VR128:$src1, i8mem:$src2, i32i8imm:$src3),
5956       !if(Is2Addr,
5957         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5958         !strconcat(asm,
5959                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5960       [(set VR128:$dst,
5961         (X86pinsrb VR128:$src1, (extloadi8 addr:$src2),
5962                    imm:$src3))]>, OpSize;
5963 }
5964
5965 let Predicates = [HasAVX] in
5966   defm VPINSRB : SS41I_insert8<0x20, "vpinsrb", 0>, VEX_4V;
5967 let Constraints = "$src1 = $dst" in
5968   defm PINSRB  : SS41I_insert8<0x20, "pinsrb">;
5969
5970 multiclass SS41I_insert32<bits<8> opc, string asm, bit Is2Addr = 1> {
5971   def rr : SS4AIi8<opc, MRMSrcReg, (outs VR128:$dst),
5972       (ins VR128:$src1, GR32:$src2, i32i8imm:$src3),
5973       !if(Is2Addr,
5974         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5975         !strconcat(asm,
5976                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5977       [(set VR128:$dst,
5978         (v4i32 (insertelt VR128:$src1, GR32:$src2, imm:$src3)))]>,
5979       OpSize;
5980   def rm : SS4AIi8<opc, MRMSrcMem, (outs VR128:$dst),
5981       (ins VR128:$src1, i32mem:$src2, i32i8imm:$src3),
5982       !if(Is2Addr,
5983         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5984         !strconcat(asm,
5985                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5986       [(set VR128:$dst,
5987         (v4i32 (insertelt VR128:$src1, (loadi32 addr:$src2),
5988                           imm:$src3)))]>, OpSize;
5989 }
5990
5991 let Predicates = [HasAVX] in
5992   defm VPINSRD : SS41I_insert32<0x22, "vpinsrd", 0>, VEX_4V;
5993 let Constraints = "$src1 = $dst" in
5994   defm PINSRD : SS41I_insert32<0x22, "pinsrd">;
5995
5996 multiclass SS41I_insert64<bits<8> opc, string asm, bit Is2Addr = 1> {
5997   def rr : SS4AIi8<opc, MRMSrcReg, (outs VR128:$dst),
5998       (ins VR128:$src1, GR64:$src2, i32i8imm:$src3),
5999       !if(Is2Addr,
6000         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6001         !strconcat(asm,
6002                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6003       [(set VR128:$dst,
6004         (v2i64 (insertelt VR128:$src1, GR64:$src2, imm:$src3)))]>,
6005       OpSize;
6006   def rm : SS4AIi8<opc, MRMSrcMem, (outs VR128:$dst),
6007       (ins VR128:$src1, i64mem:$src2, i32i8imm:$src3),
6008       !if(Is2Addr,
6009         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6010         !strconcat(asm,
6011                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6012       [(set VR128:$dst,
6013         (v2i64 (insertelt VR128:$src1, (loadi64 addr:$src2),
6014                           imm:$src3)))]>, OpSize;
6015 }
6016
6017 let Predicates = [HasAVX] in
6018   defm VPINSRQ : SS41I_insert64<0x22, "vpinsrq", 0>, VEX_4V, VEX_W;
6019 let Constraints = "$src1 = $dst" in
6020   defm PINSRQ : SS41I_insert64<0x22, "pinsrq">, REX_W;
6021
6022 // insertps has a few different modes, there's the first two here below which
6023 // are optimized inserts that won't zero arbitrary elements in the destination
6024 // vector. The next one matches the intrinsic and could zero arbitrary elements
6025 // in the target vector.
6026 multiclass SS41I_insertf32<bits<8> opc, string asm, bit Is2Addr = 1> {
6027   def rr : SS4AIi8<opc, MRMSrcReg, (outs VR128:$dst),
6028       (ins VR128:$src1, VR128:$src2, u32u8imm:$src3),
6029       !if(Is2Addr,
6030         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6031         !strconcat(asm,
6032                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6033       [(set VR128:$dst,
6034         (X86insrtps VR128:$src1, VR128:$src2, imm:$src3))]>,
6035       OpSize;
6036   def rm : SS4AIi8<opc, MRMSrcMem, (outs VR128:$dst),
6037       (ins VR128:$src1, f32mem:$src2, u32u8imm:$src3),
6038       !if(Is2Addr,
6039         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6040         !strconcat(asm,
6041                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6042       [(set VR128:$dst,
6043         (X86insrtps VR128:$src1,
6044                    (v4f32 (scalar_to_vector (loadf32 addr:$src2))),
6045                     imm:$src3))]>, OpSize;
6046 }
6047
6048 let ExeDomain = SSEPackedSingle in {
6049   let Predicates = [HasAVX] in
6050     defm VINSERTPS : SS41I_insertf32<0x21, "vinsertps", 0>, VEX_4V;
6051   let Constraints = "$src1 = $dst" in
6052     defm INSERTPS : SS41I_insertf32<0x21, "insertps">;
6053 }
6054
6055 def : Pat<(int_x86_sse41_insertps VR128:$src1, VR128:$src2, imm:$src3),
6056           (VINSERTPSrr VR128:$src1, VR128:$src2, imm:$src3)>,
6057           Requires<[HasAVX]>;
6058 def : Pat<(int_x86_sse41_insertps VR128:$src1, VR128:$src2, imm:$src3),
6059           (INSERTPSrr VR128:$src1, VR128:$src2, imm:$src3)>,
6060           Requires<[HasSSE41]>;
6061
6062 //===----------------------------------------------------------------------===//
6063 // SSE4.1 - Round Instructions
6064 //===----------------------------------------------------------------------===//
6065
6066 multiclass sse41_fp_unop_rm<bits<8> opcps, bits<8> opcpd, string OpcodeStr,
6067                             X86MemOperand x86memop, RegisterClass RC,
6068                             PatFrag mem_frag32, PatFrag mem_frag64,
6069                             Intrinsic V4F32Int, Intrinsic V2F64Int> {
6070 let ExeDomain = SSEPackedSingle in {
6071   // Intrinsic operation, reg.
6072   // Vector intrinsic operation, reg
6073   def PSr : SS4AIi8<opcps, MRMSrcReg,
6074                     (outs RC:$dst), (ins RC:$src1, i32i8imm:$src2),
6075                     !strconcat(OpcodeStr,
6076                     "ps\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6077                     [(set RC:$dst, (V4F32Int RC:$src1, imm:$src2))]>,
6078                     OpSize;
6079
6080   // Vector intrinsic operation, mem
6081   def PSm : SS4AIi8<opcps, MRMSrcMem,
6082                     (outs RC:$dst), (ins x86memop:$src1, i32i8imm:$src2),
6083                     !strconcat(OpcodeStr,
6084                     "ps\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6085                     [(set RC:$dst,
6086                           (V4F32Int (mem_frag32 addr:$src1),imm:$src2))]>,
6087                     OpSize;
6088 } // ExeDomain = SSEPackedSingle
6089
6090 let ExeDomain = SSEPackedDouble in {
6091   // Vector intrinsic operation, reg
6092   def PDr : SS4AIi8<opcpd, MRMSrcReg,
6093                     (outs RC:$dst), (ins RC:$src1, i32i8imm:$src2),
6094                     !strconcat(OpcodeStr,
6095                     "pd\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6096                     [(set RC:$dst, (V2F64Int RC:$src1, imm:$src2))]>,
6097                     OpSize;
6098
6099   // Vector intrinsic operation, mem
6100   def PDm : SS4AIi8<opcpd, MRMSrcMem,
6101                     (outs RC:$dst), (ins x86memop:$src1, i32i8imm:$src2),
6102                     !strconcat(OpcodeStr,
6103                     "pd\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6104                     [(set RC:$dst,
6105                           (V2F64Int (mem_frag64 addr:$src1),imm:$src2))]>,
6106                     OpSize;
6107 } // ExeDomain = SSEPackedDouble
6108 }
6109
6110 multiclass sse41_fp_binop_rm<bits<8> opcss, bits<8> opcsd,
6111                             string OpcodeStr,
6112                             Intrinsic F32Int,
6113                             Intrinsic F64Int, bit Is2Addr = 1> {
6114 let ExeDomain = GenericDomain in {
6115   // Operation, reg.
6116   def SSr : SS4AIi8<opcss, MRMSrcReg,
6117       (outs FR32:$dst), (ins FR32:$src1, FR32:$src2, i32i8imm:$src3),
6118       !if(Is2Addr,
6119           !strconcat(OpcodeStr,
6120               "ss\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6121           !strconcat(OpcodeStr,
6122               "ss\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6123       []>, OpSize;
6124
6125   // Intrinsic operation, reg.
6126   def SSr_Int : SS4AIi8<opcss, MRMSrcReg,
6127         (outs VR128:$dst), (ins VR128:$src1, VR128:$src2, i32i8imm:$src3),
6128         !if(Is2Addr,
6129             !strconcat(OpcodeStr,
6130                 "ss\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6131             !strconcat(OpcodeStr,
6132                 "ss\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6133         [(set VR128:$dst, (F32Int VR128:$src1, VR128:$src2, imm:$src3))]>,
6134         OpSize;
6135
6136   // Intrinsic operation, mem.
6137   def SSm : SS4AIi8<opcss, MRMSrcMem,
6138         (outs VR128:$dst), (ins VR128:$src1, ssmem:$src2, i32i8imm:$src3),
6139         !if(Is2Addr,
6140             !strconcat(OpcodeStr,
6141                 "ss\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6142             !strconcat(OpcodeStr,
6143                 "ss\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6144         [(set VR128:$dst,
6145              (F32Int VR128:$src1, sse_load_f32:$src2, imm:$src3))]>,
6146         OpSize;
6147
6148   // Operation, reg.
6149   def SDr : SS4AIi8<opcsd, MRMSrcReg,
6150         (outs FR64:$dst), (ins FR64:$src1, FR64:$src2, i32i8imm:$src3),
6151         !if(Is2Addr,
6152             !strconcat(OpcodeStr,
6153                 "sd\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6154             !strconcat(OpcodeStr,
6155                 "sd\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6156         []>, OpSize;
6157
6158   // Intrinsic operation, reg.
6159   def SDr_Int : SS4AIi8<opcsd, MRMSrcReg,
6160         (outs VR128:$dst), (ins VR128:$src1, VR128:$src2, i32i8imm:$src3),
6161         !if(Is2Addr,
6162             !strconcat(OpcodeStr,
6163                 "sd\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6164             !strconcat(OpcodeStr,
6165                 "sd\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6166         [(set VR128:$dst, (F64Int VR128:$src1, VR128:$src2, imm:$src3))]>,
6167         OpSize;
6168
6169   // Intrinsic operation, mem.
6170   def SDm : SS4AIi8<opcsd, MRMSrcMem,
6171         (outs VR128:$dst), (ins VR128:$src1, sdmem:$src2, i32i8imm:$src3),
6172         !if(Is2Addr,
6173             !strconcat(OpcodeStr,
6174                 "sd\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6175             !strconcat(OpcodeStr,
6176                 "sd\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6177         [(set VR128:$dst,
6178               (F64Int VR128:$src1, sse_load_f64:$src2, imm:$src3))]>,
6179         OpSize;
6180 } // ExeDomain = GenericDomain
6181 }
6182
6183 // FP round - roundss, roundps, roundsd, roundpd
6184 let Predicates = [HasAVX] in {
6185   // Intrinsic form
6186   defm VROUND  : sse41_fp_unop_rm<0x08, 0x09, "vround", f128mem, VR128,
6187                                   memopv4f32, memopv2f64,
6188                                   int_x86_sse41_round_ps,
6189                                   int_x86_sse41_round_pd>, VEX;
6190   defm VROUNDY : sse41_fp_unop_rm<0x08, 0x09, "vround", f256mem, VR256,
6191                                   memopv8f32, memopv4f64,
6192                                   int_x86_avx_round_ps_256,
6193                                   int_x86_avx_round_pd_256>, VEX;
6194   defm VROUND  : sse41_fp_binop_rm<0x0A, 0x0B, "vround",
6195                                   int_x86_sse41_round_ss,
6196                                   int_x86_sse41_round_sd, 0>, VEX_4V, VEX_LIG;
6197
6198   def : Pat<(ffloor FR32:$src),
6199             (VROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x1))>;
6200   def : Pat<(f64 (ffloor FR64:$src)),
6201             (VROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x1))>;
6202   def : Pat<(f32 (fnearbyint FR32:$src)),
6203             (VROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0xC))>;
6204   def : Pat<(f64 (fnearbyint FR64:$src)),
6205             (VROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0xC))>;
6206   def : Pat<(f32 (fceil FR32:$src)),
6207             (VROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x2))>;
6208   def : Pat<(f64 (fceil FR64:$src)),
6209             (VROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x2))>;
6210   def : Pat<(f32 (frint FR32:$src)),
6211             (VROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x4))>;
6212   def : Pat<(f64 (frint FR64:$src)),
6213             (VROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x4))>;
6214   def : Pat<(f32 (ftrunc FR32:$src)),
6215             (VROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x3))>;
6216   def : Pat<(f64 (ftrunc FR64:$src)),
6217             (VROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x3))>;
6218 }
6219
6220 defm ROUND  : sse41_fp_unop_rm<0x08, 0x09, "round", f128mem, VR128,
6221                                memopv4f32, memopv2f64,
6222                                int_x86_sse41_round_ps, int_x86_sse41_round_pd>;
6223 let Constraints = "$src1 = $dst" in
6224 defm ROUND  : sse41_fp_binop_rm<0x0A, 0x0B, "round",
6225                                int_x86_sse41_round_ss, int_x86_sse41_round_sd>;
6226
6227 def : Pat<(ffloor FR32:$src),
6228           (ROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x1))>;
6229 def : Pat<(f64 (ffloor FR64:$src)),
6230           (ROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x1))>;
6231 def : Pat<(f32 (fnearbyint FR32:$src)),
6232           (ROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0xC))>;
6233 def : Pat<(f64 (fnearbyint FR64:$src)),
6234           (ROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0xC))>;
6235 def : Pat<(f32 (fceil FR32:$src)),
6236           (ROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x2))>;
6237 def : Pat<(f64 (fceil FR64:$src)),
6238           (ROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x2))>;
6239 def : Pat<(f32 (frint FR32:$src)),
6240           (ROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x4))>;
6241 def : Pat<(f64 (frint FR64:$src)),
6242           (ROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x4))>;
6243 def : Pat<(f32 (ftrunc FR32:$src)),
6244           (ROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x3))>;
6245 def : Pat<(f64 (ftrunc FR64:$src)),
6246           (ROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x3))>;
6247
6248 //===----------------------------------------------------------------------===//
6249 // SSE4.1 - Packed Bit Test
6250 //===----------------------------------------------------------------------===//
6251
6252 // ptest instruction we'll lower to this in X86ISelLowering primarily from
6253 // the intel intrinsic that corresponds to this.
6254 let Defs = [EFLAGS], Predicates = [HasAVX] in {
6255 def VPTESTrr  : SS48I<0x17, MRMSrcReg, (outs), (ins VR128:$src1, VR128:$src2),
6256                 "vptest\t{$src2, $src1|$src1, $src2}",
6257                 [(set EFLAGS, (X86ptest VR128:$src1, (v4f32 VR128:$src2)))]>,
6258                 OpSize, VEX;
6259 def VPTESTrm  : SS48I<0x17, MRMSrcMem, (outs), (ins VR128:$src1, f128mem:$src2),
6260                 "vptest\t{$src2, $src1|$src1, $src2}",
6261                 [(set EFLAGS,(X86ptest VR128:$src1, (memopv4f32 addr:$src2)))]>,
6262                 OpSize, VEX;
6263
6264 def VPTESTYrr : SS48I<0x17, MRMSrcReg, (outs), (ins VR256:$src1, VR256:$src2),
6265                 "vptest\t{$src2, $src1|$src1, $src2}",
6266                 [(set EFLAGS, (X86ptest VR256:$src1, (v4i64 VR256:$src2)))]>,
6267                 OpSize, VEX;
6268 def VPTESTYrm : SS48I<0x17, MRMSrcMem, (outs), (ins VR256:$src1, i256mem:$src2),
6269                 "vptest\t{$src2, $src1|$src1, $src2}",
6270                 [(set EFLAGS,(X86ptest VR256:$src1, (memopv4i64 addr:$src2)))]>,
6271                 OpSize, VEX;
6272 }
6273
6274 let Defs = [EFLAGS] in {
6275 def PTESTrr : SS48I<0x17, MRMSrcReg, (outs), (ins VR128:$src1, VR128:$src2),
6276               "ptest\t{$src2, $src1|$src1, $src2}",
6277               [(set EFLAGS, (X86ptest VR128:$src1, (v4f32 VR128:$src2)))]>,
6278               OpSize;
6279 def PTESTrm : SS48I<0x17, MRMSrcMem, (outs), (ins VR128:$src1, f128mem:$src2),
6280               "ptest\t{$src2, $src1|$src1, $src2}",
6281               [(set EFLAGS, (X86ptest VR128:$src1, (memopv4f32 addr:$src2)))]>,
6282               OpSize;
6283 }
6284
6285 // The bit test instructions below are AVX only
6286 multiclass avx_bittest<bits<8> opc, string OpcodeStr, RegisterClass RC,
6287                        X86MemOperand x86memop, PatFrag mem_frag, ValueType vt> {
6288   def rr : SS48I<opc, MRMSrcReg, (outs), (ins RC:$src1, RC:$src2),
6289             !strconcat(OpcodeStr, "\t{$src2, $src1|$src1, $src2}"),
6290             [(set EFLAGS, (X86testp RC:$src1, (vt RC:$src2)))]>, OpSize, VEX;
6291   def rm : SS48I<opc, MRMSrcMem, (outs), (ins RC:$src1, x86memop:$src2),
6292             !strconcat(OpcodeStr, "\t{$src2, $src1|$src1, $src2}"),
6293             [(set EFLAGS, (X86testp RC:$src1, (mem_frag addr:$src2)))]>,
6294             OpSize, VEX;
6295 }
6296
6297 let Defs = [EFLAGS], Predicates = [HasAVX] in {
6298 let ExeDomain = SSEPackedSingle in {
6299 defm VTESTPS  : avx_bittest<0x0E, "vtestps", VR128, f128mem, memopv4f32, v4f32>;
6300 defm VTESTPSY : avx_bittest<0x0E, "vtestps", VR256, f256mem, memopv8f32, v8f32>;
6301 }
6302 let ExeDomain = SSEPackedDouble in {
6303 defm VTESTPD  : avx_bittest<0x0F, "vtestpd", VR128, f128mem, memopv2f64, v2f64>;
6304 defm VTESTPDY : avx_bittest<0x0F, "vtestpd", VR256, f256mem, memopv4f64, v4f64>;
6305 }
6306 }
6307
6308 //===----------------------------------------------------------------------===//
6309 // SSE4.1 - Misc Instructions
6310 //===----------------------------------------------------------------------===//
6311
6312 let Defs = [EFLAGS], Predicates = [HasPOPCNT] in {
6313   def POPCNT16rr : I<0xB8, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
6314                      "popcnt{w}\t{$src, $dst|$dst, $src}",
6315                      [(set GR16:$dst, (ctpop GR16:$src)), (implicit EFLAGS)]>,
6316                      OpSize, XS;
6317   def POPCNT16rm : I<0xB8, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
6318                      "popcnt{w}\t{$src, $dst|$dst, $src}",
6319                      [(set GR16:$dst, (ctpop (loadi16 addr:$src))),
6320                       (implicit EFLAGS)]>, OpSize, XS;
6321
6322   def POPCNT32rr : I<0xB8, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
6323                      "popcnt{l}\t{$src, $dst|$dst, $src}",
6324                      [(set GR32:$dst, (ctpop GR32:$src)), (implicit EFLAGS)]>,
6325                      XS;
6326   def POPCNT32rm : I<0xB8, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
6327                      "popcnt{l}\t{$src, $dst|$dst, $src}",
6328                      [(set GR32:$dst, (ctpop (loadi32 addr:$src))),
6329                       (implicit EFLAGS)]>, XS;
6330
6331   def POPCNT64rr : RI<0xB8, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
6332                       "popcnt{q}\t{$src, $dst|$dst, $src}",
6333                       [(set GR64:$dst, (ctpop GR64:$src)), (implicit EFLAGS)]>,
6334                       XS;
6335   def POPCNT64rm : RI<0xB8, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
6336                       "popcnt{q}\t{$src, $dst|$dst, $src}",
6337                       [(set GR64:$dst, (ctpop (loadi64 addr:$src))),
6338                        (implicit EFLAGS)]>, XS;
6339 }
6340
6341
6342
6343 // SS41I_unop_rm_int_v16 - SSE 4.1 unary operator whose type is v8i16.
6344 multiclass SS41I_unop_rm_int_v16<bits<8> opc, string OpcodeStr,
6345                                  Intrinsic IntId128> {
6346   def rr128 : SS48I<opc, MRMSrcReg, (outs VR128:$dst),
6347                     (ins VR128:$src),
6348                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
6349                     [(set VR128:$dst, (IntId128 VR128:$src))]>, OpSize;
6350   def rm128 : SS48I<opc, MRMSrcMem, (outs VR128:$dst),
6351                      (ins i128mem:$src),
6352                      !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
6353                      [(set VR128:$dst,
6354                        (IntId128
6355                         (bitconvert (memopv2i64 addr:$src))))]>, OpSize;
6356 }
6357
6358 let Predicates = [HasAVX] in
6359 defm VPHMINPOSUW : SS41I_unop_rm_int_v16 <0x41, "vphminposuw",
6360                                          int_x86_sse41_phminposuw>, VEX;
6361 defm PHMINPOSUW : SS41I_unop_rm_int_v16 <0x41, "phminposuw",
6362                                          int_x86_sse41_phminposuw>;
6363
6364 /// SS41I_binop_rm_int - Simple SSE 4.1 binary operator
6365 multiclass SS41I_binop_rm_int<bits<8> opc, string OpcodeStr,
6366                               Intrinsic IntId128, bit Is2Addr = 1> {
6367   let isCommutable = 1 in
6368   def rr : SS48I<opc, MRMSrcReg, (outs VR128:$dst),
6369        (ins VR128:$src1, VR128:$src2),
6370        !if(Is2Addr,
6371            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
6372            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
6373        [(set VR128:$dst, (IntId128 VR128:$src1, VR128:$src2))]>, OpSize;
6374   def rm : SS48I<opc, MRMSrcMem, (outs VR128:$dst),
6375        (ins VR128:$src1, i128mem:$src2),
6376        !if(Is2Addr,
6377            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
6378            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
6379        [(set VR128:$dst,
6380          (IntId128 VR128:$src1,
6381           (bitconvert (memopv2i64 addr:$src2))))]>, OpSize;
6382 }
6383
6384 /// SS41I_binop_rm_int - Simple SSE 4.1 binary operator
6385 multiclass SS41I_binop_rm_int_y<bits<8> opc, string OpcodeStr,
6386                                 Intrinsic IntId256> {
6387   let isCommutable = 1 in
6388   def Yrr : SS48I<opc, MRMSrcReg, (outs VR256:$dst),
6389        (ins VR256:$src1, VR256:$src2),
6390        !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6391        [(set VR256:$dst, (IntId256 VR256:$src1, VR256:$src2))]>, OpSize;
6392   def Yrm : SS48I<opc, MRMSrcMem, (outs VR256:$dst),
6393        (ins VR256:$src1, i256mem:$src2),
6394        !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6395        [(set VR256:$dst,
6396          (IntId256 VR256:$src1,
6397           (bitconvert (memopv4i64 addr:$src2))))]>, OpSize;
6398 }
6399
6400 let Predicates = [HasAVX] in {
6401   let isCommutable = 0 in
6402   defm VPACKUSDW : SS41I_binop_rm_int<0x2B, "vpackusdw", int_x86_sse41_packusdw,
6403                                                          0>, VEX_4V;
6404   defm VPCMPEQQ  : SS41I_binop_rm_int<0x29, "vpcmpeqq",  int_x86_sse41_pcmpeqq,
6405                                                          0>, VEX_4V;
6406   defm VPMINSB   : SS41I_binop_rm_int<0x38, "vpminsb",   int_x86_sse41_pminsb,
6407                                                          0>, VEX_4V;
6408   defm VPMINSD   : SS41I_binop_rm_int<0x39, "vpminsd",   int_x86_sse41_pminsd,
6409                                                          0>, VEX_4V;
6410   defm VPMINUD   : SS41I_binop_rm_int<0x3B, "vpminud",   int_x86_sse41_pminud,
6411                                                          0>, VEX_4V;
6412   defm VPMINUW   : SS41I_binop_rm_int<0x3A, "vpminuw",   int_x86_sse41_pminuw,
6413                                                          0>, VEX_4V;
6414   defm VPMAXSB   : SS41I_binop_rm_int<0x3C, "vpmaxsb",   int_x86_sse41_pmaxsb,
6415                                                          0>, VEX_4V;
6416   defm VPMAXSD   : SS41I_binop_rm_int<0x3D, "vpmaxsd",   int_x86_sse41_pmaxsd,
6417                                                          0>, VEX_4V;
6418   defm VPMAXUD   : SS41I_binop_rm_int<0x3F, "vpmaxud",   int_x86_sse41_pmaxud,
6419                                                          0>, VEX_4V;
6420   defm VPMAXUW   : SS41I_binop_rm_int<0x3E, "vpmaxuw",   int_x86_sse41_pmaxuw,
6421                                                          0>, VEX_4V;
6422   defm VPMULDQ   : SS41I_binop_rm_int<0x28, "vpmuldq",   int_x86_sse41_pmuldq,
6423                                                          0>, VEX_4V;
6424
6425   def : Pat<(v2i64 (X86pcmpeqq VR128:$src1, VR128:$src2)),
6426             (VPCMPEQQrr VR128:$src1, VR128:$src2)>;
6427   def : Pat<(v2i64 (X86pcmpeqq VR128:$src1, (memop addr:$src2))),
6428             (VPCMPEQQrm VR128:$src1, addr:$src2)>;
6429 }
6430
6431 let Predicates = [HasAVX2] in {
6432   let isCommutable = 0 in
6433   defm VPACKUSDW : SS41I_binop_rm_int_y<0x2B, "vpackusdw",
6434                                         int_x86_avx2_packusdw>, VEX_4V;
6435   defm VPCMPEQQ  : SS41I_binop_rm_int_y<0x29, "vpcmpeqq",
6436                                         int_x86_avx2_pcmpeq_q>, VEX_4V;
6437   defm VPMINSB   : SS41I_binop_rm_int_y<0x38, "vpminsb",
6438                                         int_x86_avx2_pmins_b>, VEX_4V;
6439   defm VPMINSD   : SS41I_binop_rm_int_y<0x39, "vpminsd",
6440                                         int_x86_avx2_pmins_d>, VEX_4V;
6441   defm VPMINUD   : SS41I_binop_rm_int_y<0x3B, "vpminud",
6442                                         int_x86_avx2_pminu_d>, VEX_4V;
6443   defm VPMINUW   : SS41I_binop_rm_int_y<0x3A, "vpminuw",
6444                                         int_x86_avx2_pminu_w>, VEX_4V;
6445   defm VPMAXSB   : SS41I_binop_rm_int_y<0x3C, "vpmaxsb",
6446                                         int_x86_avx2_pmaxs_b>, VEX_4V;
6447   defm VPMAXSD   : SS41I_binop_rm_int_y<0x3D, "vpmaxsd",
6448                                         int_x86_avx2_pmaxs_d>, VEX_4V;
6449   defm VPMAXUD   : SS41I_binop_rm_int_y<0x3F, "vpmaxud",
6450                                         int_x86_avx2_pmaxu_d>, VEX_4V;
6451   defm VPMAXUW   : SS41I_binop_rm_int_y<0x3E, "vpmaxuw",
6452                                         int_x86_avx2_pmaxu_w>, VEX_4V;
6453   defm VPMULDQ   : SS41I_binop_rm_int_y<0x28, "vpmuldq",
6454                                         int_x86_avx2_pmul_dq>, VEX_4V;
6455
6456   def : Pat<(v4i64 (X86pcmpeqq VR256:$src1, VR256:$src2)),
6457             (VPCMPEQQYrr VR256:$src1, VR256:$src2)>;
6458   def : Pat<(v4i64 (X86pcmpeqq VR256:$src1, (memop addr:$src2))),
6459             (VPCMPEQQYrm VR256:$src1, addr:$src2)>;
6460 }
6461
6462 let Constraints = "$src1 = $dst" in {
6463   let isCommutable = 0 in
6464   defm PACKUSDW : SS41I_binop_rm_int<0x2B, "packusdw", int_x86_sse41_packusdw>;
6465   defm PCMPEQQ  : SS41I_binop_rm_int<0x29, "pcmpeqq",  int_x86_sse41_pcmpeqq>;
6466   defm PMINSB   : SS41I_binop_rm_int<0x38, "pminsb",   int_x86_sse41_pminsb>;
6467   defm PMINSD   : SS41I_binop_rm_int<0x39, "pminsd",   int_x86_sse41_pminsd>;
6468   defm PMINUD   : SS41I_binop_rm_int<0x3B, "pminud",   int_x86_sse41_pminud>;
6469   defm PMINUW   : SS41I_binop_rm_int<0x3A, "pminuw",   int_x86_sse41_pminuw>;
6470   defm PMAXSB   : SS41I_binop_rm_int<0x3C, "pmaxsb",   int_x86_sse41_pmaxsb>;
6471   defm PMAXSD   : SS41I_binop_rm_int<0x3D, "pmaxsd",   int_x86_sse41_pmaxsd>;
6472   defm PMAXUD   : SS41I_binop_rm_int<0x3F, "pmaxud",   int_x86_sse41_pmaxud>;
6473   defm PMAXUW   : SS41I_binop_rm_int<0x3E, "pmaxuw",   int_x86_sse41_pmaxuw>;
6474   defm PMULDQ   : SS41I_binop_rm_int<0x28, "pmuldq",   int_x86_sse41_pmuldq>;
6475 }
6476
6477 let Predicates = [HasSSE41] in {
6478   def : Pat<(v2i64 (X86pcmpeqq VR128:$src1, VR128:$src2)),
6479             (PCMPEQQrr VR128:$src1, VR128:$src2)>;
6480   def : Pat<(v2i64 (X86pcmpeqq VR128:$src1, (memop addr:$src2))),
6481             (PCMPEQQrm VR128:$src1, addr:$src2)>;
6482 }
6483
6484 /// SS48I_binop_rm - Simple SSE41 binary operator.
6485 multiclass SS48I_binop_rm<bits<8> opc, string OpcodeStr, SDNode OpNode,
6486                           ValueType OpVT, bit Is2Addr = 1> {
6487   let isCommutable = 1 in
6488   def rr : SS48I<opc, MRMSrcReg, (outs VR128:$dst),
6489        (ins VR128:$src1, VR128:$src2),
6490        !if(Is2Addr,
6491            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
6492            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
6493        [(set VR128:$dst, (OpVT (OpNode VR128:$src1, VR128:$src2)))]>,
6494        OpSize;
6495   def rm : SS48I<opc, MRMSrcMem, (outs VR128:$dst),
6496        (ins VR128:$src1, i128mem:$src2),
6497        !if(Is2Addr,
6498            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
6499            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
6500        [(set VR128:$dst, (OpNode VR128:$src1,
6501                                   (bc_v4i32 (memopv2i64 addr:$src2))))]>,
6502        OpSize;
6503 }
6504
6505 /// SS48I_binop_rm - Simple SSE41 binary operator.
6506 multiclass SS48I_binop_rm_y<bits<8> opc, string OpcodeStr, SDNode OpNode,
6507                             ValueType OpVT> {
6508   let isCommutable = 1 in
6509   def Yrr : SS48I<opc, MRMSrcReg, (outs VR256:$dst),
6510        (ins VR256:$src1, VR256:$src2),
6511        !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6512        [(set VR256:$dst, (OpVT (OpNode VR256:$src1, VR256:$src2)))]>,
6513        OpSize;
6514   def Yrm : SS48I<opc, MRMSrcMem, (outs VR256:$dst),
6515        (ins VR256:$src1, i256mem:$src2),
6516        !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6517        [(set VR256:$dst, (OpNode VR256:$src1,
6518                                   (bc_v8i32 (memopv4i64 addr:$src2))))]>,
6519        OpSize;
6520 }
6521
6522 let Predicates = [HasAVX] in
6523   defm VPMULLD : SS48I_binop_rm<0x40, "vpmulld", mul, v4i32, 0>, VEX_4V;
6524 let Predicates = [HasAVX2] in
6525   defm VPMULLD : SS48I_binop_rm_y<0x40, "vpmulld", mul, v8i32>, VEX_4V;
6526 let Constraints = "$src1 = $dst" in
6527   defm PMULLD : SS48I_binop_rm<0x40, "pmulld", mul, v4i32>;
6528
6529 /// SS41I_binop_rmi_int - SSE 4.1 binary operator with 8-bit immediate
6530 multiclass SS41I_binop_rmi_int<bits<8> opc, string OpcodeStr,
6531                  Intrinsic IntId, RegisterClass RC, PatFrag memop_frag,
6532                  X86MemOperand x86memop, bit Is2Addr = 1> {
6533   let isCommutable = 1 in
6534   def rri : SS4AIi8<opc, MRMSrcReg, (outs RC:$dst),
6535         (ins RC:$src1, RC:$src2, u32u8imm:$src3),
6536         !if(Is2Addr,
6537             !strconcat(OpcodeStr,
6538                 "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6539             !strconcat(OpcodeStr,
6540                 "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6541         [(set RC:$dst, (IntId RC:$src1, RC:$src2, imm:$src3))]>,
6542         OpSize;
6543   def rmi : SS4AIi8<opc, MRMSrcMem, (outs RC:$dst),
6544         (ins RC:$src1, x86memop:$src2, u32u8imm:$src3),
6545         !if(Is2Addr,
6546             !strconcat(OpcodeStr,
6547                 "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6548             !strconcat(OpcodeStr,
6549                 "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6550         [(set RC:$dst,
6551           (IntId RC:$src1,
6552            (bitconvert (memop_frag addr:$src2)), imm:$src3))]>,
6553         OpSize;
6554 }
6555
6556 let Predicates = [HasAVX] in {
6557   let isCommutable = 0 in {
6558     let ExeDomain = SSEPackedSingle in {
6559     defm VBLENDPS : SS41I_binop_rmi_int<0x0C, "vblendps", int_x86_sse41_blendps,
6560                                         VR128, memopv4f32, i128mem, 0>, VEX_4V;
6561     defm VBLENDPSY : SS41I_binop_rmi_int<0x0C, "vblendps",
6562               int_x86_avx_blend_ps_256, VR256, memopv8f32, i256mem, 0>, VEX_4V;
6563     }
6564     let ExeDomain = SSEPackedDouble in {
6565     defm VBLENDPD : SS41I_binop_rmi_int<0x0D, "vblendpd", int_x86_sse41_blendpd,
6566                                         VR128, memopv2f64, i128mem, 0>, VEX_4V;
6567     defm VBLENDPDY : SS41I_binop_rmi_int<0x0D, "vblendpd",
6568               int_x86_avx_blend_pd_256, VR256, memopv4f64, i256mem, 0>, VEX_4V;
6569     }
6570   defm VPBLENDW : SS41I_binop_rmi_int<0x0E, "vpblendw", int_x86_sse41_pblendw,
6571                                       VR128, memopv2i64, i128mem, 0>, VEX_4V;
6572   defm VMPSADBW : SS41I_binop_rmi_int<0x42, "vmpsadbw", int_x86_sse41_mpsadbw,
6573                                       VR128, memopv2i64, i128mem, 0>, VEX_4V;
6574   }
6575   let ExeDomain = SSEPackedSingle in
6576   defm VDPPS : SS41I_binop_rmi_int<0x40, "vdpps", int_x86_sse41_dpps,
6577                                    VR128, memopv4f32, i128mem, 0>, VEX_4V;
6578   let ExeDomain = SSEPackedDouble in
6579   defm VDPPD : SS41I_binop_rmi_int<0x41, "vdppd", int_x86_sse41_dppd,
6580                                    VR128, memopv2f64, i128mem, 0>, VEX_4V;
6581   let ExeDomain = SSEPackedSingle in
6582   defm VDPPSY : SS41I_binop_rmi_int<0x40, "vdpps", int_x86_avx_dp_ps_256,
6583                                    VR256, memopv8f32, i256mem, 0>, VEX_4V;
6584 }
6585
6586 let Predicates = [HasAVX2] in {
6587   let isCommutable = 0 in {
6588   defm VPBLENDWY : SS41I_binop_rmi_int<0x0E, "vpblendw", int_x86_avx2_pblendw,
6589                                        VR256, memopv4i64, i256mem, 0>, VEX_4V;
6590   defm VMPSADBWY : SS41I_binop_rmi_int<0x42, "vmpsadbw", int_x86_avx2_mpsadbw,
6591                                        VR256, memopv4i64, i256mem, 0>, VEX_4V;
6592   }
6593 }
6594
6595 let Constraints = "$src1 = $dst" in {
6596   let isCommutable = 0 in {
6597   let ExeDomain = SSEPackedSingle in
6598   defm BLENDPS : SS41I_binop_rmi_int<0x0C, "blendps", int_x86_sse41_blendps,
6599                                      VR128, memopv4f32, i128mem>;
6600   let ExeDomain = SSEPackedDouble in
6601   defm BLENDPD : SS41I_binop_rmi_int<0x0D, "blendpd", int_x86_sse41_blendpd,
6602                                      VR128, memopv2f64, i128mem>;
6603   defm PBLENDW : SS41I_binop_rmi_int<0x0E, "pblendw", int_x86_sse41_pblendw,
6604                                      VR128, memopv2i64, i128mem>;
6605   defm MPSADBW : SS41I_binop_rmi_int<0x42, "mpsadbw", int_x86_sse41_mpsadbw,
6606                                      VR128, memopv2i64, i128mem>;
6607   }
6608   let ExeDomain = SSEPackedSingle in
6609   defm DPPS : SS41I_binop_rmi_int<0x40, "dpps", int_x86_sse41_dpps,
6610                                   VR128, memopv4f32, i128mem>;
6611   let ExeDomain = SSEPackedDouble in
6612   defm DPPD : SS41I_binop_rmi_int<0x41, "dppd", int_x86_sse41_dppd,
6613                                   VR128, memopv2f64, i128mem>;
6614 }
6615
6616 /// SS41I_quaternary_int_avx - AVX SSE 4.1 with 4 operators
6617 multiclass SS41I_quaternary_int_avx<bits<8> opc, string OpcodeStr,
6618                                     RegisterClass RC, X86MemOperand x86memop,
6619                                     PatFrag mem_frag, Intrinsic IntId> {
6620   def rr : Ii8<opc, MRMSrcReg, (outs RC:$dst),
6621                   (ins RC:$src1, RC:$src2, RC:$src3),
6622                   !strconcat(OpcodeStr,
6623                     "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
6624                   [(set RC:$dst, (IntId RC:$src1, RC:$src2, RC:$src3))],
6625                   SSEPackedInt>, OpSize, TA, VEX_4V, VEX_I8IMM;
6626
6627   def rm : Ii8<opc, MRMSrcMem, (outs RC:$dst),
6628                   (ins RC:$src1, x86memop:$src2, RC:$src3),
6629                   !strconcat(OpcodeStr,
6630                     "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
6631                   [(set RC:$dst,
6632                         (IntId RC:$src1, (bitconvert (mem_frag addr:$src2)),
6633                                RC:$src3))],
6634                   SSEPackedInt>, OpSize, TA, VEX_4V, VEX_I8IMM;
6635 }
6636
6637 let Predicates = [HasAVX] in {
6638 let ExeDomain = SSEPackedDouble in {
6639 defm VBLENDVPD  : SS41I_quaternary_int_avx<0x4B, "vblendvpd", VR128, i128mem,
6640                                            memopv2f64, int_x86_sse41_blendvpd>;
6641 defm VBLENDVPDY : SS41I_quaternary_int_avx<0x4B, "vblendvpd", VR256, i256mem,
6642                                          memopv4f64, int_x86_avx_blendv_pd_256>;
6643 } // ExeDomain = SSEPackedDouble
6644 let ExeDomain = SSEPackedSingle in {
6645 defm VBLENDVPS  : SS41I_quaternary_int_avx<0x4A, "vblendvps", VR128, i128mem,
6646                                            memopv4f32, int_x86_sse41_blendvps>;
6647 defm VBLENDVPSY : SS41I_quaternary_int_avx<0x4A, "vblendvps", VR256, i256mem,
6648                                          memopv8f32, int_x86_avx_blendv_ps_256>;
6649 } // ExeDomain = SSEPackedSingle
6650 defm VPBLENDVB  : SS41I_quaternary_int_avx<0x4C, "vpblendvb", VR128, i128mem,
6651                                            memopv2i64, int_x86_sse41_pblendvb>;
6652 }
6653
6654 let Predicates = [HasAVX2] in {
6655 defm VPBLENDVBY : SS41I_quaternary_int_avx<0x4C, "vpblendvb", VR256, i256mem,
6656                                            memopv4i64, int_x86_avx2_pblendvb>;
6657 }
6658
6659 let Predicates = [HasAVX] in {
6660   def : Pat<(v16i8 (vselect (v16i8 VR128:$mask), (v16i8 VR128:$src1),
6661                             (v16i8 VR128:$src2))),
6662             (VPBLENDVBrr VR128:$src2, VR128:$src1, VR128:$mask)>;
6663   def : Pat<(v4i32 (vselect (v4i32 VR128:$mask), (v4i32 VR128:$src1),
6664                             (v4i32 VR128:$src2))),
6665             (VBLENDVPSrr VR128:$src2, VR128:$src1, VR128:$mask)>;
6666   def : Pat<(v4f32 (vselect (v4i32 VR128:$mask), (v4f32 VR128:$src1),
6667                             (v4f32 VR128:$src2))),
6668             (VBLENDVPSrr VR128:$src2, VR128:$src1, VR128:$mask)>;
6669   def : Pat<(v2i64 (vselect (v2i64 VR128:$mask), (v2i64 VR128:$src1),
6670                             (v2i64 VR128:$src2))),
6671             (VBLENDVPDrr VR128:$src2, VR128:$src1, VR128:$mask)>;
6672   def : Pat<(v2f64 (vselect (v2i64 VR128:$mask), (v2f64 VR128:$src1),
6673                             (v2f64 VR128:$src2))),
6674             (VBLENDVPDrr VR128:$src2, VR128:$src1, VR128:$mask)>;
6675   def : Pat<(v8i32 (vselect (v8i32 VR256:$mask), (v8i32 VR256:$src1),
6676                             (v8i32 VR256:$src2))),
6677             (VBLENDVPSYrr VR256:$src2, VR256:$src1, VR256:$mask)>;
6678   def : Pat<(v8f32 (vselect (v8i32 VR256:$mask), (v8f32 VR256:$src1),
6679                             (v8f32 VR256:$src2))),
6680             (VBLENDVPSYrr VR256:$src2, VR256:$src1, VR256:$mask)>;
6681   def : Pat<(v4i64 (vselect (v4i64 VR256:$mask), (v4i64 VR256:$src1),
6682                             (v4i64 VR256:$src2))),
6683             (VBLENDVPDYrr VR256:$src2, VR256:$src1, VR256:$mask)>;
6684   def : Pat<(v4f64 (vselect (v4i64 VR256:$mask), (v4f64 VR256:$src1),
6685                             (v4f64 VR256:$src2))),
6686             (VBLENDVPDYrr VR256:$src2, VR256:$src1, VR256:$mask)>;
6687 }
6688
6689 let Predicates = [HasAVX2] in {
6690   def : Pat<(v32i8 (vselect (v32i8 VR256:$mask), (v32i8 VR256:$src1),
6691                             (v32i8 VR256:$src2))),
6692             (VPBLENDVBYrr VR256:$src2, VR256:$src1, VR256:$mask)>;
6693 }
6694
6695 /// SS41I_ternary_int - SSE 4.1 ternary operator
6696 let Uses = [XMM0], Constraints = "$src1 = $dst" in {
6697   multiclass SS41I_ternary_int<bits<8> opc, string OpcodeStr, PatFrag mem_frag,
6698                                Intrinsic IntId> {
6699     def rr0 : SS48I<opc, MRMSrcReg, (outs VR128:$dst),
6700                     (ins VR128:$src1, VR128:$src2),
6701                     !strconcat(OpcodeStr,
6702                      "\t{$src2, $dst|$dst, $src2}"),
6703                     [(set VR128:$dst, (IntId VR128:$src1, VR128:$src2, XMM0))]>,
6704                     OpSize;
6705
6706     def rm0 : SS48I<opc, MRMSrcMem, (outs VR128:$dst),
6707                     (ins VR128:$src1, i128mem:$src2),
6708                     !strconcat(OpcodeStr,
6709                      "\t{$src2, $dst|$dst, $src2}"),
6710                     [(set VR128:$dst,
6711                       (IntId VR128:$src1,
6712                        (bitconvert (mem_frag addr:$src2)), XMM0))]>, OpSize;
6713   }
6714 }
6715
6716 let ExeDomain = SSEPackedDouble in
6717 defm BLENDVPD : SS41I_ternary_int<0x15, "blendvpd", memopv2f64,
6718                                   int_x86_sse41_blendvpd>;
6719 let ExeDomain = SSEPackedSingle in
6720 defm BLENDVPS : SS41I_ternary_int<0x14, "blendvps", memopv4f32,
6721                                   int_x86_sse41_blendvps>;
6722 defm PBLENDVB : SS41I_ternary_int<0x10, "pblendvb", memopv2i64,
6723                                   int_x86_sse41_pblendvb>;
6724
6725 let Predicates = [HasSSE41] in {
6726   def : Pat<(v16i8 (vselect (v16i8 XMM0), (v16i8 VR128:$src1),
6727                             (v16i8 VR128:$src2))),
6728             (PBLENDVBrr0 VR128:$src2, VR128:$src1)>;
6729   def : Pat<(v4i32 (vselect (v4i32 XMM0), (v4i32 VR128:$src1),
6730                             (v4i32 VR128:$src2))),
6731             (BLENDVPSrr0 VR128:$src2, VR128:$src1)>;
6732   def : Pat<(v4f32 (vselect (v4i32 XMM0), (v4f32 VR128:$src1),
6733                             (v4f32 VR128:$src2))),
6734             (BLENDVPSrr0 VR128:$src2, VR128:$src1)>;
6735   def : Pat<(v2i64 (vselect (v2i64 XMM0), (v2i64 VR128:$src1),
6736                             (v2i64 VR128:$src2))),
6737             (BLENDVPDrr0 VR128:$src2, VR128:$src1)>;
6738   def : Pat<(v2f64 (vselect (v2i64 XMM0), (v2f64 VR128:$src1),
6739                             (v2f64 VR128:$src2))),
6740             (BLENDVPDrr0 VR128:$src2, VR128:$src1)>;
6741 }
6742
6743 let Predicates = [HasAVX] in
6744 def VMOVNTDQArm : SS48I<0x2A, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
6745                        "vmovntdqa\t{$src, $dst|$dst, $src}",
6746                        [(set VR128:$dst, (int_x86_sse41_movntdqa addr:$src))]>,
6747                        OpSize, VEX;
6748 let Predicates = [HasAVX2] in
6749 def VMOVNTDQAYrm : SS48I<0x2A, MRMSrcMem, (outs VR256:$dst), (ins i256mem:$src),
6750                          "vmovntdqa\t{$src, $dst|$dst, $src}",
6751                          [(set VR256:$dst, (int_x86_avx2_movntdqa addr:$src))]>,
6752                          OpSize, VEX;
6753 def MOVNTDQArm : SS48I<0x2A, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
6754                        "movntdqa\t{$src, $dst|$dst, $src}",
6755                        [(set VR128:$dst, (int_x86_sse41_movntdqa addr:$src))]>,
6756                        OpSize;
6757
6758 //===----------------------------------------------------------------------===//
6759 // SSE4.2 - Compare Instructions
6760 //===----------------------------------------------------------------------===//
6761
6762 /// SS42I_binop_rm_int - Simple SSE 4.2 binary operator
6763 multiclass SS42I_binop_rm_int<bits<8> opc, string OpcodeStr,
6764                               Intrinsic IntId128, bit Is2Addr = 1> {
6765   def rr : SS428I<opc, MRMSrcReg, (outs VR128:$dst),
6766        (ins VR128:$src1, VR128:$src2),
6767        !if(Is2Addr,
6768            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
6769            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
6770        [(set VR128:$dst, (IntId128 VR128:$src1, VR128:$src2))]>,
6771        OpSize;
6772   def rm : SS428I<opc, MRMSrcMem, (outs VR128:$dst),
6773        (ins VR128:$src1, i128mem:$src2),
6774        !if(Is2Addr,
6775            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
6776            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
6777        [(set VR128:$dst,
6778          (IntId128 VR128:$src1, (memopv2i64 addr:$src2)))]>, OpSize;
6779 }
6780
6781 /// SS42I_binop_rm_int - Simple SSE 4.2 binary operator
6782 multiclass SS42I_binop_rm_int_y<bits<8> opc, string OpcodeStr,
6783                                 Intrinsic IntId256> {
6784   def Yrr : SS428I<opc, MRMSrcReg, (outs VR256:$dst),
6785        (ins VR256:$src1, VR256:$src2),
6786        !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6787        [(set VR256:$dst, (IntId256 VR256:$src1, VR256:$src2))]>,
6788        OpSize;
6789   def Yrm : SS428I<opc, MRMSrcMem, (outs VR256:$dst),
6790        (ins VR256:$src1, i256mem:$src2),
6791        !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6792        [(set VR256:$dst,
6793          (IntId256 VR256:$src1, (memopv4i64 addr:$src2)))]>, OpSize;
6794 }
6795
6796 let Predicates = [HasAVX] in {
6797   defm VPCMPGTQ : SS42I_binop_rm_int<0x37, "vpcmpgtq", int_x86_sse42_pcmpgtq,
6798                                      0>, VEX_4V;
6799
6800   def : Pat<(v2i64 (X86pcmpgtq VR128:$src1, VR128:$src2)),
6801             (VPCMPGTQrr VR128:$src1, VR128:$src2)>;
6802   def : Pat<(v2i64 (X86pcmpgtq VR128:$src1, (memop addr:$src2))),
6803             (VPCMPGTQrm VR128:$src1, addr:$src2)>;
6804 }
6805
6806 let Predicates = [HasAVX2] in {
6807   defm VPCMPGTQ : SS42I_binop_rm_int_y<0x37, "vpcmpgtq", int_x86_avx2_pcmpgt_q>,
6808                                        VEX_4V;
6809
6810   def : Pat<(v4i64 (X86pcmpgtq VR256:$src1, VR256:$src2)),
6811             (VPCMPGTQYrr VR256:$src1, VR256:$src2)>;
6812   def : Pat<(v4i64 (X86pcmpgtq VR256:$src1, (memop addr:$src2))),
6813             (VPCMPGTQYrm VR256:$src1, addr:$src2)>;
6814 }
6815
6816 let Constraints = "$src1 = $dst" in
6817   defm PCMPGTQ : SS42I_binop_rm_int<0x37, "pcmpgtq", int_x86_sse42_pcmpgtq>;
6818
6819 let Predicates = [HasSSE42] in {
6820   def : Pat<(v2i64 (X86pcmpgtq VR128:$src1, VR128:$src2)),
6821             (PCMPGTQrr VR128:$src1, VR128:$src2)>;
6822   def : Pat<(v2i64 (X86pcmpgtq VR128:$src1, (memop addr:$src2))),
6823             (PCMPGTQrm VR128:$src1, addr:$src2)>;
6824 }
6825
6826 //===----------------------------------------------------------------------===//
6827 // SSE4.2 - String/text Processing Instructions
6828 //===----------------------------------------------------------------------===//
6829
6830 // Packed Compare Implicit Length Strings, Return Mask
6831 multiclass pseudo_pcmpistrm<string asm> {
6832   def REG : PseudoI<(outs VR128:$dst),
6833                     (ins VR128:$src1, VR128:$src2, i8imm:$src3),
6834     [(set VR128:$dst, (int_x86_sse42_pcmpistrm128 VR128:$src1, VR128:$src2,
6835                                                   imm:$src3))]>;
6836   def MEM : PseudoI<(outs VR128:$dst),
6837                     (ins VR128:$src1, i128mem:$src2, i8imm:$src3),
6838     [(set VR128:$dst, (int_x86_sse42_pcmpistrm128
6839                        VR128:$src1, (load addr:$src2), imm:$src3))]>;
6840 }
6841
6842 let Defs = [EFLAGS], usesCustomInserter = 1 in {
6843   defm PCMPISTRM128 : pseudo_pcmpistrm<"#PCMPISTRM128">, Requires<[HasSSE42]>;
6844   defm VPCMPISTRM128 : pseudo_pcmpistrm<"#VPCMPISTRM128">, Requires<[HasAVX]>;
6845 }
6846
6847 let Defs = [XMM0, EFLAGS], neverHasSideEffects = 1, Predicates = [HasAVX] in {
6848   def VPCMPISTRM128rr : SS42AI<0x62, MRMSrcReg, (outs),
6849       (ins VR128:$src1, VR128:$src2, i8imm:$src3),
6850       "vpcmpistrm\t{$src3, $src2, $src1|$src1, $src2, $src3}", []>, OpSize, VEX;
6851   let mayLoad = 1 in
6852   def VPCMPISTRM128rm : SS42AI<0x62, MRMSrcMem, (outs),
6853       (ins VR128:$src1, i128mem:$src2, i8imm:$src3),
6854       "vpcmpistrm\t{$src3, $src2, $src1|$src1, $src2, $src3}", []>, OpSize, VEX;
6855 }
6856
6857 let Defs = [XMM0, EFLAGS], neverHasSideEffects = 1 in {
6858   def PCMPISTRM128rr : SS42AI<0x62, MRMSrcReg, (outs),
6859       (ins VR128:$src1, VR128:$src2, i8imm:$src3),
6860       "pcmpistrm\t{$src3, $src2, $src1|$src1, $src2, $src3}", []>, OpSize;
6861   let mayLoad = 1 in
6862   def PCMPISTRM128rm : SS42AI<0x62, MRMSrcMem, (outs),
6863       (ins VR128:$src1, i128mem:$src2, i8imm:$src3),
6864       "pcmpistrm\t{$src3, $src2, $src1|$src1, $src2, $src3}", []>, OpSize;
6865 }
6866
6867 // Packed Compare Explicit Length Strings, Return Mask
6868 multiclass pseudo_pcmpestrm<string asm> {
6869   def REG : PseudoI<(outs VR128:$dst),
6870                     (ins VR128:$src1, VR128:$src3, i8imm:$src5),
6871     [(set VR128:$dst, (int_x86_sse42_pcmpestrm128
6872                        VR128:$src1, EAX, VR128:$src3, EDX, imm:$src5))]>;
6873   def MEM : PseudoI<(outs VR128:$dst),
6874                     (ins VR128:$src1, i128mem:$src3, i8imm:$src5),
6875     [(set VR128:$dst, (int_x86_sse42_pcmpestrm128
6876                        VR128:$src1, EAX, (load addr:$src3), EDX, imm:$src5))]>;
6877 }
6878
6879 let Defs = [EFLAGS], Uses = [EAX, EDX], usesCustomInserter = 1 in {
6880   defm PCMPESTRM128 : pseudo_pcmpestrm<"#PCMPESTRM128">, Requires<[HasSSE42]>;
6881   defm VPCMPESTRM128 : pseudo_pcmpestrm<"#VPCMPESTRM128">, Requires<[HasAVX]>;
6882 }
6883
6884 let Predicates = [HasAVX],
6885     Defs = [XMM0, EFLAGS], Uses = [EAX, EDX], neverHasSideEffects = 1 in {
6886   def VPCMPESTRM128rr : SS42AI<0x60, MRMSrcReg, (outs),
6887       (ins VR128:$src1, VR128:$src3, i8imm:$src5),
6888       "vpcmpestrm\t{$src5, $src3, $src1|$src1, $src3, $src5}", []>, OpSize, VEX;
6889   let mayLoad = 1 in
6890   def VPCMPESTRM128rm : SS42AI<0x60, MRMSrcMem, (outs),
6891       (ins VR128:$src1, i128mem:$src3, i8imm:$src5),
6892       "vpcmpestrm\t{$src5, $src3, $src1|$src1, $src3, $src5}", []>, OpSize, VEX;
6893 }
6894
6895 let Defs = [XMM0, EFLAGS], Uses = [EAX, EDX], neverHasSideEffects = 1 in {
6896   def PCMPESTRM128rr : SS42AI<0x60, MRMSrcReg, (outs),
6897       (ins VR128:$src1, VR128:$src3, i8imm:$src5),
6898       "pcmpestrm\t{$src5, $src3, $src1|$src1, $src3, $src5}", []>, OpSize;
6899   let mayLoad = 1 in
6900   def PCMPESTRM128rm : SS42AI<0x60, MRMSrcMem, (outs),
6901       (ins VR128:$src1, i128mem:$src3, i8imm:$src5),
6902       "pcmpestrm\t{$src5, $src3, $src1|$src1, $src3, $src5}", []>, OpSize;
6903 }
6904
6905 // Packed Compare Implicit Length Strings, Return Index
6906 let Defs = [ECX, EFLAGS] in {
6907   multiclass SS42AI_pcmpistri<Intrinsic IntId128, string asm = "pcmpistri"> {
6908     def rr : SS42AI<0x63, MRMSrcReg, (outs),
6909       (ins VR128:$src1, VR128:$src2, i8imm:$src3),
6910       !strconcat(asm, "\t{$src3, $src2, $src1|$src1, $src2, $src3}"),
6911       [(set ECX, (IntId128 VR128:$src1, VR128:$src2, imm:$src3)),
6912        (implicit EFLAGS)]>, OpSize;
6913     def rm : SS42AI<0x63, MRMSrcMem, (outs),
6914       (ins VR128:$src1, i128mem:$src2, i8imm:$src3),
6915       !strconcat(asm, "\t{$src3, $src2, $src1|$src1, $src2, $src3}"),
6916       [(set ECX, (IntId128 VR128:$src1, (load addr:$src2), imm:$src3)),
6917        (implicit EFLAGS)]>, OpSize;
6918   }
6919 }
6920
6921 let Predicates = [HasAVX] in {
6922 defm VPCMPISTRI  : SS42AI_pcmpistri<int_x86_sse42_pcmpistri128, "vpcmpistri">,
6923                                     VEX;
6924 defm VPCMPISTRIA : SS42AI_pcmpistri<int_x86_sse42_pcmpistria128, "vpcmpistri">,
6925                                     VEX;
6926 defm VPCMPISTRIC : SS42AI_pcmpistri<int_x86_sse42_pcmpistric128, "vpcmpistri">,
6927                                     VEX;
6928 defm VPCMPISTRIO : SS42AI_pcmpistri<int_x86_sse42_pcmpistrio128, "vpcmpistri">,
6929                                     VEX;
6930 defm VPCMPISTRIS : SS42AI_pcmpistri<int_x86_sse42_pcmpistris128, "vpcmpistri">,
6931                                     VEX;
6932 defm VPCMPISTRIZ : SS42AI_pcmpistri<int_x86_sse42_pcmpistriz128, "vpcmpistri">,
6933                                     VEX;
6934 }
6935
6936 defm PCMPISTRI  : SS42AI_pcmpistri<int_x86_sse42_pcmpistri128>;
6937 defm PCMPISTRIA : SS42AI_pcmpistri<int_x86_sse42_pcmpistria128>;
6938 defm PCMPISTRIC : SS42AI_pcmpistri<int_x86_sse42_pcmpistric128>;
6939 defm PCMPISTRIO : SS42AI_pcmpistri<int_x86_sse42_pcmpistrio128>;
6940 defm PCMPISTRIS : SS42AI_pcmpistri<int_x86_sse42_pcmpistris128>;
6941 defm PCMPISTRIZ : SS42AI_pcmpistri<int_x86_sse42_pcmpistriz128>;
6942
6943 // Packed Compare Explicit Length Strings, Return Index
6944 let Defs = [ECX, EFLAGS], Uses = [EAX, EDX] in {
6945   multiclass SS42AI_pcmpestri<Intrinsic IntId128, string asm = "pcmpestri"> {
6946     def rr : SS42AI<0x61, MRMSrcReg, (outs),
6947       (ins VR128:$src1, VR128:$src3, i8imm:$src5),
6948       !strconcat(asm, "\t{$src5, $src3, $src1|$src1, $src3, $src5}"),
6949       [(set ECX, (IntId128 VR128:$src1, EAX, VR128:$src3, EDX, imm:$src5)),
6950        (implicit EFLAGS)]>, OpSize;
6951     def rm : SS42AI<0x61, MRMSrcMem, (outs),
6952       (ins VR128:$src1, i128mem:$src3, i8imm:$src5),
6953       !strconcat(asm, "\t{$src5, $src3, $src1|$src1, $src3, $src5}"),
6954        [(set ECX,
6955              (IntId128 VR128:$src1, EAX, (load addr:$src3), EDX, imm:$src5)),
6956         (implicit EFLAGS)]>, OpSize;
6957   }
6958 }
6959
6960 let Predicates = [HasAVX] in {
6961 defm VPCMPESTRI  : SS42AI_pcmpestri<int_x86_sse42_pcmpestri128, "vpcmpestri">,
6962                                     VEX;
6963 defm VPCMPESTRIA : SS42AI_pcmpestri<int_x86_sse42_pcmpestria128, "vpcmpestri">,
6964                                     VEX;
6965 defm VPCMPESTRIC : SS42AI_pcmpestri<int_x86_sse42_pcmpestric128, "vpcmpestri">,
6966                                     VEX;
6967 defm VPCMPESTRIO : SS42AI_pcmpestri<int_x86_sse42_pcmpestrio128, "vpcmpestri">,
6968                                     VEX;
6969 defm VPCMPESTRIS : SS42AI_pcmpestri<int_x86_sse42_pcmpestris128, "vpcmpestri">,
6970                                     VEX;
6971 defm VPCMPESTRIZ : SS42AI_pcmpestri<int_x86_sse42_pcmpestriz128, "vpcmpestri">,
6972                                     VEX;
6973 }
6974
6975 defm PCMPESTRI  : SS42AI_pcmpestri<int_x86_sse42_pcmpestri128>;
6976 defm PCMPESTRIA : SS42AI_pcmpestri<int_x86_sse42_pcmpestria128>;
6977 defm PCMPESTRIC : SS42AI_pcmpestri<int_x86_sse42_pcmpestric128>;
6978 defm PCMPESTRIO : SS42AI_pcmpestri<int_x86_sse42_pcmpestrio128>;
6979 defm PCMPESTRIS : SS42AI_pcmpestri<int_x86_sse42_pcmpestris128>;
6980 defm PCMPESTRIZ : SS42AI_pcmpestri<int_x86_sse42_pcmpestriz128>;
6981
6982 //===----------------------------------------------------------------------===//
6983 // SSE4.2 - CRC Instructions
6984 //===----------------------------------------------------------------------===//
6985
6986 // No CRC instructions have AVX equivalents
6987
6988 // crc intrinsic instruction
6989 // This set of instructions are only rm, the only difference is the size
6990 // of r and m.
6991 let Constraints = "$src1 = $dst" in {
6992   def CRC32r32m8  : SS42FI<0xF0, MRMSrcMem, (outs GR32:$dst),
6993                       (ins GR32:$src1, i8mem:$src2),
6994                       "crc32{b} \t{$src2, $src1|$src1, $src2}",
6995                        [(set GR32:$dst,
6996                          (int_x86_sse42_crc32_32_8 GR32:$src1,
6997                          (load addr:$src2)))]>;
6998   def CRC32r32r8  : SS42FI<0xF0, MRMSrcReg, (outs GR32:$dst),
6999                       (ins GR32:$src1, GR8:$src2),
7000                       "crc32{b} \t{$src2, $src1|$src1, $src2}",
7001                        [(set GR32:$dst,
7002                          (int_x86_sse42_crc32_32_8 GR32:$src1, GR8:$src2))]>;
7003   def CRC32r32m16  : SS42FI<0xF1, MRMSrcMem, (outs GR32:$dst),
7004                       (ins GR32:$src1, i16mem:$src2),
7005                       "crc32{w} \t{$src2, $src1|$src1, $src2}",
7006                        [(set GR32:$dst,
7007                          (int_x86_sse42_crc32_32_16 GR32:$src1,
7008                          (load addr:$src2)))]>,
7009                          OpSize;
7010   def CRC32r32r16  : SS42FI<0xF1, MRMSrcReg, (outs GR32:$dst),
7011                       (ins GR32:$src1, GR16:$src2),
7012                       "crc32{w} \t{$src2, $src1|$src1, $src2}",
7013                        [(set GR32:$dst,
7014                          (int_x86_sse42_crc32_32_16 GR32:$src1, GR16:$src2))]>,
7015                          OpSize;
7016   def CRC32r32m32  : SS42FI<0xF1, MRMSrcMem, (outs GR32:$dst),
7017                       (ins GR32:$src1, i32mem:$src2),
7018                       "crc32{l} \t{$src2, $src1|$src1, $src2}",
7019                        [(set GR32:$dst,
7020                          (int_x86_sse42_crc32_32_32 GR32:$src1,
7021                          (load addr:$src2)))]>;
7022   def CRC32r32r32  : SS42FI<0xF1, MRMSrcReg, (outs GR32:$dst),
7023                       (ins GR32:$src1, GR32:$src2),
7024                       "crc32{l} \t{$src2, $src1|$src1, $src2}",
7025                        [(set GR32:$dst,
7026                          (int_x86_sse42_crc32_32_32 GR32:$src1, GR32:$src2))]>;
7027   def CRC32r64m8  : SS42FI<0xF0, MRMSrcMem, (outs GR64:$dst),
7028                       (ins GR64:$src1, i8mem:$src2),
7029                       "crc32{b} \t{$src2, $src1|$src1, $src2}",
7030                        [(set GR64:$dst,
7031                          (int_x86_sse42_crc32_64_8 GR64:$src1,
7032                          (load addr:$src2)))]>,
7033                          REX_W;
7034   def CRC32r64r8  : SS42FI<0xF0, MRMSrcReg, (outs GR64:$dst),
7035                       (ins GR64:$src1, GR8:$src2),
7036                       "crc32{b} \t{$src2, $src1|$src1, $src2}",
7037                        [(set GR64:$dst,
7038                          (int_x86_sse42_crc32_64_8 GR64:$src1, GR8:$src2))]>,
7039                          REX_W;
7040   def CRC32r64m64  : SS42FI<0xF1, MRMSrcMem, (outs GR64:$dst),
7041                       (ins GR64:$src1, i64mem:$src2),
7042                       "crc32{q} \t{$src2, $src1|$src1, $src2}",
7043                        [(set GR64:$dst,
7044                          (int_x86_sse42_crc32_64_64 GR64:$src1,
7045                          (load addr:$src2)))]>,
7046                          REX_W;
7047   def CRC32r64r64  : SS42FI<0xF1, MRMSrcReg, (outs GR64:$dst),
7048                       (ins GR64:$src1, GR64:$src2),
7049                       "crc32{q} \t{$src2, $src1|$src1, $src2}",
7050                        [(set GR64:$dst,
7051                          (int_x86_sse42_crc32_64_64 GR64:$src1, GR64:$src2))]>,
7052                          REX_W;
7053 }
7054
7055 //===----------------------------------------------------------------------===//
7056 // AES-NI Instructions
7057 //===----------------------------------------------------------------------===//
7058
7059 multiclass AESI_binop_rm_int<bits<8> opc, string OpcodeStr,
7060                               Intrinsic IntId128, bit Is2Addr = 1> {
7061   def rr : AES8I<opc, MRMSrcReg, (outs VR128:$dst),
7062        (ins VR128:$src1, VR128:$src2),
7063        !if(Is2Addr,
7064            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
7065            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
7066        [(set VR128:$dst, (IntId128 VR128:$src1, VR128:$src2))]>,
7067        OpSize;
7068   def rm : AES8I<opc, MRMSrcMem, (outs VR128:$dst),
7069        (ins VR128:$src1, i128mem:$src2),
7070        !if(Is2Addr,
7071            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
7072            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
7073        [(set VR128:$dst,
7074          (IntId128 VR128:$src1, (memopv2i64 addr:$src2)))]>, OpSize;
7075 }
7076
7077 // Perform One Round of an AES Encryption/Decryption Flow
7078 let Predicates = [HasAVX, HasAES] in {
7079   defm VAESENC          : AESI_binop_rm_int<0xDC, "vaesenc",
7080                          int_x86_aesni_aesenc, 0>, VEX_4V;
7081   defm VAESENCLAST      : AESI_binop_rm_int<0xDD, "vaesenclast",
7082                          int_x86_aesni_aesenclast, 0>, VEX_4V;
7083   defm VAESDEC          : AESI_binop_rm_int<0xDE, "vaesdec",
7084                          int_x86_aesni_aesdec, 0>, VEX_4V;
7085   defm VAESDECLAST      : AESI_binop_rm_int<0xDF, "vaesdeclast",
7086                          int_x86_aesni_aesdeclast, 0>, VEX_4V;
7087 }
7088
7089 let Constraints = "$src1 = $dst" in {
7090   defm AESENC          : AESI_binop_rm_int<0xDC, "aesenc",
7091                          int_x86_aesni_aesenc>;
7092   defm AESENCLAST      : AESI_binop_rm_int<0xDD, "aesenclast",
7093                          int_x86_aesni_aesenclast>;
7094   defm AESDEC          : AESI_binop_rm_int<0xDE, "aesdec",
7095                          int_x86_aesni_aesdec>;
7096   defm AESDECLAST      : AESI_binop_rm_int<0xDF, "aesdeclast",
7097                          int_x86_aesni_aesdeclast>;
7098 }
7099
7100 // Perform the AES InvMixColumn Transformation
7101 let Predicates = [HasAVX, HasAES] in {
7102   def VAESIMCrr : AES8I<0xDB, MRMSrcReg, (outs VR128:$dst),
7103       (ins VR128:$src1),
7104       "vaesimc\t{$src1, $dst|$dst, $src1}",
7105       [(set VR128:$dst,
7106         (int_x86_aesni_aesimc VR128:$src1))]>,
7107       OpSize, VEX;
7108   def VAESIMCrm : AES8I<0xDB, MRMSrcMem, (outs VR128:$dst),
7109       (ins i128mem:$src1),
7110       "vaesimc\t{$src1, $dst|$dst, $src1}",
7111       [(set VR128:$dst, (int_x86_aesni_aesimc (memopv2i64 addr:$src1)))]>,
7112       OpSize, VEX;
7113 }
7114 def AESIMCrr : AES8I<0xDB, MRMSrcReg, (outs VR128:$dst),
7115   (ins VR128:$src1),
7116   "aesimc\t{$src1, $dst|$dst, $src1}",
7117   [(set VR128:$dst,
7118     (int_x86_aesni_aesimc VR128:$src1))]>,
7119   OpSize;
7120 def AESIMCrm : AES8I<0xDB, MRMSrcMem, (outs VR128:$dst),
7121   (ins i128mem:$src1),
7122   "aesimc\t{$src1, $dst|$dst, $src1}",
7123   [(set VR128:$dst, (int_x86_aesni_aesimc (memopv2i64 addr:$src1)))]>,
7124   OpSize;
7125
7126 // AES Round Key Generation Assist
7127 let Predicates = [HasAVX, HasAES] in {
7128   def VAESKEYGENASSIST128rr : AESAI<0xDF, MRMSrcReg, (outs VR128:$dst),
7129       (ins VR128:$src1, i8imm:$src2),
7130       "vaeskeygenassist\t{$src2, $src1, $dst|$dst, $src1, $src2}",
7131       [(set VR128:$dst,
7132         (int_x86_aesni_aeskeygenassist VR128:$src1, imm:$src2))]>,
7133       OpSize, VEX;
7134   def VAESKEYGENASSIST128rm : AESAI<0xDF, MRMSrcMem, (outs VR128:$dst),
7135       (ins i128mem:$src1, i8imm:$src2),
7136       "vaeskeygenassist\t{$src2, $src1, $dst|$dst, $src1, $src2}",
7137       [(set VR128:$dst,
7138         (int_x86_aesni_aeskeygenassist (memopv2i64 addr:$src1), imm:$src2))]>,
7139       OpSize, VEX;
7140 }
7141 def AESKEYGENASSIST128rr : AESAI<0xDF, MRMSrcReg, (outs VR128:$dst),
7142   (ins VR128:$src1, i8imm:$src2),
7143   "aeskeygenassist\t{$src2, $src1, $dst|$dst, $src1, $src2}",
7144   [(set VR128:$dst,
7145     (int_x86_aesni_aeskeygenassist VR128:$src1, imm:$src2))]>,
7146   OpSize;
7147 def AESKEYGENASSIST128rm : AESAI<0xDF, MRMSrcMem, (outs VR128:$dst),
7148   (ins i128mem:$src1, i8imm:$src2),
7149   "aeskeygenassist\t{$src2, $src1, $dst|$dst, $src1, $src2}",
7150   [(set VR128:$dst,
7151     (int_x86_aesni_aeskeygenassist (memopv2i64 addr:$src1), imm:$src2))]>,
7152   OpSize;
7153
7154 //===----------------------------------------------------------------------===//
7155 // CLMUL Instructions
7156 //===----------------------------------------------------------------------===//
7157
7158 // Carry-less Multiplication instructions
7159 let neverHasSideEffects = 1 in {
7160 // AVX carry-less Multiplication instructions
7161 def VPCLMULQDQrr : AVXCLMULIi8<0x44, MRMSrcReg, (outs VR128:$dst),
7162            (ins VR128:$src1, VR128:$src2, i8imm:$src3),
7163            "vpclmulqdq\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
7164            []>;
7165
7166 let mayLoad = 1 in
7167 def VPCLMULQDQrm : AVXCLMULIi8<0x44, MRMSrcMem, (outs VR128:$dst),
7168            (ins VR128:$src1, i128mem:$src2, i8imm:$src3),
7169            "vpclmulqdq\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
7170            []>;
7171
7172 let Constraints = "$src1 = $dst" in {
7173 def PCLMULQDQrr : CLMULIi8<0x44, MRMSrcReg, (outs VR128:$dst),
7174            (ins VR128:$src1, VR128:$src2, i8imm:$src3),
7175            "pclmulqdq\t{$src3, $src2, $dst|$dst, $src2, $src3}",
7176            []>;
7177
7178 let mayLoad = 1 in
7179 def PCLMULQDQrm : CLMULIi8<0x44, MRMSrcMem, (outs VR128:$dst),
7180            (ins VR128:$src1, i128mem:$src2, i8imm:$src3),
7181            "pclmulqdq\t{$src3, $src2, $dst|$dst, $src2, $src3}",
7182            []>;
7183 } // Constraints = "$src1 = $dst"
7184 } // neverHasSideEffects = 1
7185
7186
7187 multiclass pclmul_alias<string asm, int immop> {
7188   def : InstAlias<!strconcat("pclmul", asm, 
7189                            "dq {$src, $dst|$dst, $src}"),
7190                   (PCLMULQDQrr VR128:$dst, VR128:$src, immop)>;
7191
7192   def : InstAlias<!strconcat("pclmul", asm, 
7193                              "dq {$src, $dst|$dst, $src}"),
7194                   (PCLMULQDQrm VR128:$dst, i128mem:$src, immop)>;
7195
7196   def : InstAlias<!strconcat("vpclmul", asm, 
7197                              "dq {$src2, $src1, $dst|$dst, $src1, $src2}"),
7198                   (VPCLMULQDQrr VR128:$dst, VR128:$src1, VR128:$src2, immop)>;
7199
7200   def : InstAlias<!strconcat("vpclmul", asm, 
7201                              "dq {$src2, $src1, $dst|$dst, $src1, $src2}"),
7202                   (VPCLMULQDQrm VR128:$dst, VR128:$src1, i128mem:$src2, immop)>;
7203 }
7204 defm : pclmul_alias<"hqhq", 0x11>;
7205 defm : pclmul_alias<"hqlq", 0x01>;
7206 defm : pclmul_alias<"lqhq", 0x10>;
7207 defm : pclmul_alias<"lqlq", 0x00>;
7208
7209 //===----------------------------------------------------------------------===//
7210 // AVX Instructions
7211 //===----------------------------------------------------------------------===//
7212
7213 //===----------------------------------------------------------------------===//
7214 // VBROADCAST - Load from memory and broadcast to all elements of the
7215 //              destination operand
7216 //
7217 class avx_broadcast<bits<8> opc, string OpcodeStr, RegisterClass RC,
7218                     X86MemOperand x86memop, Intrinsic Int> :
7219   AVX8I<opc, MRMSrcMem, (outs RC:$dst), (ins x86memop:$src),
7220         !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
7221         [(set RC:$dst, (Int addr:$src))]>, VEX;
7222
7223 // AVX2 adds register forms
7224 class avx2_broadcast_reg<bits<8> opc, string OpcodeStr, RegisterClass RC,
7225                          Intrinsic Int> :
7226   AVX28I<opc, MRMSrcReg, (outs RC:$dst), (ins VR128:$src),
7227          !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
7228          [(set RC:$dst, (Int VR128:$src))]>, VEX;
7229
7230 let ExeDomain = SSEPackedSingle in {
7231   def VBROADCASTSSrm  : avx_broadcast<0x18, "vbroadcastss", VR128, f32mem,
7232                                       int_x86_avx_vbroadcast_ss>;
7233   def VBROADCASTSSYrm : avx_broadcast<0x18, "vbroadcastss", VR256, f32mem,
7234                                       int_x86_avx_vbroadcast_ss_256>;
7235 }
7236 let ExeDomain = SSEPackedDouble in
7237 def VBROADCASTSDrm  : avx_broadcast<0x19, "vbroadcastsd", VR256, f64mem,
7238                                     int_x86_avx_vbroadcast_sd_256>;
7239 def VBROADCASTF128 : avx_broadcast<0x1A, "vbroadcastf128", VR256, f128mem,
7240                                    int_x86_avx_vbroadcastf128_pd_256>;
7241
7242 let ExeDomain = SSEPackedSingle in {
7243   def VBROADCASTSSrr  : avx2_broadcast_reg<0x18, "vbroadcastss", VR128,
7244                                            int_x86_avx2_vbroadcast_ss_ps>;
7245   def VBROADCASTSSYrr : avx2_broadcast_reg<0x18, "vbroadcastss", VR256,
7246                                            int_x86_avx2_vbroadcast_ss_ps_256>;
7247 }
7248 let ExeDomain = SSEPackedDouble in
7249 def VBROADCASTSDrr  : avx2_broadcast_reg<0x19, "vbroadcastsd", VR256,
7250                                          int_x86_avx2_vbroadcast_sd_pd_256>;
7251
7252 let Predicates = [HasAVX2] in
7253 def VBROADCASTI128 : avx_broadcast<0x5A, "vbroadcasti128", VR256, i128mem,
7254                                    int_x86_avx2_vbroadcasti128>;
7255
7256 let Predicates = [HasAVX] in
7257 def : Pat<(int_x86_avx_vbroadcastf128_ps_256 addr:$src),
7258           (VBROADCASTF128 addr:$src)>;
7259
7260
7261 //===----------------------------------------------------------------------===//
7262 // VINSERTF128 - Insert packed floating-point values
7263 //
7264 let neverHasSideEffects = 1, ExeDomain = SSEPackedSingle in {
7265 def VINSERTF128rr : AVXAIi8<0x18, MRMSrcReg, (outs VR256:$dst),
7266           (ins VR256:$src1, VR128:$src2, i8imm:$src3),
7267           "vinsertf128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
7268           []>, VEX_4V;
7269 let mayLoad = 1 in
7270 def VINSERTF128rm : AVXAIi8<0x18, MRMSrcMem, (outs VR256:$dst),
7271           (ins VR256:$src1, f128mem:$src2, i8imm:$src3),
7272           "vinsertf128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
7273           []>, VEX_4V;
7274 }
7275
7276 let Predicates = [HasAVX] in {
7277 def : Pat<(int_x86_avx_vinsertf128_pd_256 VR256:$src1, VR128:$src2, imm:$src3),
7278           (VINSERTF128rr VR256:$src1, VR128:$src2, imm:$src3)>;
7279 def : Pat<(int_x86_avx_vinsertf128_ps_256 VR256:$src1, VR128:$src2, imm:$src3),
7280           (VINSERTF128rr VR256:$src1, VR128:$src2, imm:$src3)>;
7281 def : Pat<(int_x86_avx_vinsertf128_si_256 VR256:$src1, VR128:$src2, imm:$src3),
7282           (VINSERTF128rr VR256:$src1, VR128:$src2, imm:$src3)>;
7283 }
7284
7285 //===----------------------------------------------------------------------===//
7286 // VEXTRACTF128 - Extract packed floating-point values
7287 //
7288 let neverHasSideEffects = 1, ExeDomain = SSEPackedSingle in {
7289 def VEXTRACTF128rr : AVXAIi8<0x19, MRMDestReg, (outs VR128:$dst),
7290           (ins VR256:$src1, i8imm:$src2),
7291           "vextractf128\t{$src2, $src1, $dst|$dst, $src1, $src2}",
7292           []>, VEX;
7293 let mayStore = 1 in
7294 def VEXTRACTF128mr : AVXAIi8<0x19, MRMDestMem, (outs),
7295           (ins f128mem:$dst, VR256:$src1, i8imm:$src2),
7296           "vextractf128\t{$src2, $src1, $dst|$dst, $src1, $src2}",
7297           []>, VEX;
7298 }
7299
7300 let Predicates = [HasAVX] in {
7301 def : Pat<(int_x86_avx_vextractf128_pd_256 VR256:$src1, imm:$src2),
7302           (VEXTRACTF128rr VR256:$src1, imm:$src2)>;
7303 def : Pat<(int_x86_avx_vextractf128_ps_256 VR256:$src1, imm:$src2),
7304           (VEXTRACTF128rr VR256:$src1, imm:$src2)>;
7305 def : Pat<(int_x86_avx_vextractf128_si_256 VR256:$src1, imm:$src2),
7306           (VEXTRACTF128rr VR256:$src1, imm:$src2)>;
7307 }
7308
7309 //===----------------------------------------------------------------------===//
7310 // VMASKMOV - Conditional SIMD Packed Loads and Stores
7311 //
7312 multiclass avx_movmask_rm<bits<8> opc_rm, bits<8> opc_mr, string OpcodeStr,
7313                           Intrinsic IntLd, Intrinsic IntLd256,
7314                           Intrinsic IntSt, Intrinsic IntSt256> {
7315   def rm  : AVX8I<opc_rm, MRMSrcMem, (outs VR128:$dst),
7316              (ins VR128:$src1, f128mem:$src2),
7317              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7318              [(set VR128:$dst, (IntLd addr:$src2, VR128:$src1))]>,
7319              VEX_4V;
7320   def Yrm : AVX8I<opc_rm, MRMSrcMem, (outs VR256:$dst),
7321              (ins VR256:$src1, f256mem:$src2),
7322              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7323              [(set VR256:$dst, (IntLd256 addr:$src2, VR256:$src1))]>,
7324              VEX_4V;
7325   def mr  : AVX8I<opc_mr, MRMDestMem, (outs),
7326              (ins f128mem:$dst, VR128:$src1, VR128:$src2),
7327              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7328              [(IntSt addr:$dst, VR128:$src1, VR128:$src2)]>, VEX_4V;
7329   def Ymr : AVX8I<opc_mr, MRMDestMem, (outs),
7330              (ins f256mem:$dst, VR256:$src1, VR256:$src2),
7331              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7332              [(IntSt256 addr:$dst, VR256:$src1, VR256:$src2)]>, VEX_4V;
7333 }
7334
7335 let ExeDomain = SSEPackedSingle in
7336 defm VMASKMOVPS : avx_movmask_rm<0x2C, 0x2E, "vmaskmovps",
7337                                  int_x86_avx_maskload_ps,
7338                                  int_x86_avx_maskload_ps_256,
7339                                  int_x86_avx_maskstore_ps,
7340                                  int_x86_avx_maskstore_ps_256>;
7341 let ExeDomain = SSEPackedDouble in
7342 defm VMASKMOVPD : avx_movmask_rm<0x2D, 0x2F, "vmaskmovpd",
7343                                  int_x86_avx_maskload_pd,
7344                                  int_x86_avx_maskload_pd_256,
7345                                  int_x86_avx_maskstore_pd,
7346                                  int_x86_avx_maskstore_pd_256>;
7347
7348 //===----------------------------------------------------------------------===//
7349 // VPERMIL - Permute Single and Double Floating-Point Values
7350 //
7351 multiclass avx_permil<bits<8> opc_rm, bits<8> opc_rmi, string OpcodeStr,
7352                       RegisterClass RC, X86MemOperand x86memop_f,
7353                       X86MemOperand x86memop_i, PatFrag f_frag, PatFrag i_frag,
7354                       Intrinsic IntVar, Intrinsic IntImm> {
7355   def rr  : AVX8I<opc_rm, MRMSrcReg, (outs RC:$dst),
7356              (ins RC:$src1, RC:$src2),
7357              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7358              [(set RC:$dst, (IntVar RC:$src1, RC:$src2))]>, VEX_4V;
7359   def rm  : AVX8I<opc_rm, MRMSrcMem, (outs RC:$dst),
7360              (ins RC:$src1, x86memop_i:$src2),
7361              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7362              [(set RC:$dst, (IntVar RC:$src1,
7363                              (bitconvert (i_frag addr:$src2))))]>, VEX_4V;
7364
7365   def ri  : AVXAIi8<opc_rmi, MRMSrcReg, (outs RC:$dst),
7366              (ins RC:$src1, i8imm:$src2),
7367              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7368              [(set RC:$dst, (IntImm RC:$src1, imm:$src2))]>, VEX;
7369   def mi  : AVXAIi8<opc_rmi, MRMSrcMem, (outs RC:$dst),
7370              (ins x86memop_f:$src1, i8imm:$src2),
7371              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7372              [(set RC:$dst, (IntImm (f_frag addr:$src1), imm:$src2))]>, VEX;
7373 }
7374
7375 let ExeDomain = SSEPackedSingle in {
7376   defm VPERMILPS  : avx_permil<0x0C, 0x04, "vpermilps", VR128, f128mem, i128mem,
7377                                memopv4f32, memopv2i64,
7378                                int_x86_avx_vpermilvar_ps,
7379                                int_x86_avx_vpermil_ps>;
7380   defm VPERMILPSY : avx_permil<0x0C, 0x04, "vpermilps", VR256, f256mem, i256mem,
7381                                memopv8f32, memopv4i64,
7382                                int_x86_avx_vpermilvar_ps_256,
7383                                int_x86_avx_vpermil_ps_256>;
7384 }
7385 let ExeDomain = SSEPackedDouble in {
7386   defm VPERMILPD  : avx_permil<0x0D, 0x05, "vpermilpd", VR128, f128mem, i128mem,
7387                                memopv2f64, memopv2i64,
7388                                int_x86_avx_vpermilvar_pd,
7389                                int_x86_avx_vpermil_pd>;
7390   defm VPERMILPDY : avx_permil<0x0D, 0x05, "vpermilpd", VR256, f256mem, i256mem,
7391                                memopv4f64, memopv4i64,
7392                                int_x86_avx_vpermilvar_pd_256,
7393                                int_x86_avx_vpermil_pd_256>;
7394 }
7395
7396 let Predicates = [HasAVX] in {
7397 def : Pat<(v8f32 (X86VPermilp VR256:$src1, (i8 imm:$imm))),
7398           (VPERMILPSYri VR256:$src1, imm:$imm)>;
7399 def : Pat<(v4f64 (X86VPermilp VR256:$src1, (i8 imm:$imm))),
7400           (VPERMILPDYri VR256:$src1, imm:$imm)>;
7401 def : Pat<(v8i32 (X86VPermilp VR256:$src1, (i8 imm:$imm))),
7402           (VPERMILPSYri VR256:$src1, imm:$imm)>;
7403 def : Pat<(v4i64 (X86VPermilp VR256:$src1, (i8 imm:$imm))),
7404           (VPERMILPDYri VR256:$src1, imm:$imm)>;
7405 def : Pat<(v8f32 (X86VPermilp (memopv8f32 addr:$src1), (i8 imm:$imm))),
7406           (VPERMILPSYmi addr:$src1, imm:$imm)>;
7407 def : Pat<(v4f64 (X86VPermilp (memopv4f64 addr:$src1), (i8 imm:$imm))),
7408           (VPERMILPDYmi addr:$src1, imm:$imm)>;
7409 def : Pat<(v8i32 (X86VPermilp (bc_v8i32 (memopv4i64 addr:$src1)),
7410                                (i8 imm:$imm))),
7411           (VPERMILPSYmi addr:$src1, imm:$imm)>;
7412 def : Pat<(v4i64 (X86VPermilp (memopv4i64 addr:$src1), (i8 imm:$imm))),
7413           (VPERMILPDYmi addr:$src1, imm:$imm)>;
7414 }
7415
7416 //===----------------------------------------------------------------------===//
7417 // VPERM2F128 - Permute Floating-Point Values in 128-bit chunks
7418 //
7419 let neverHasSideEffects = 1, ExeDomain = SSEPackedSingle in {
7420 def VPERM2F128rr : AVXAIi8<0x06, MRMSrcReg, (outs VR256:$dst),
7421           (ins VR256:$src1, VR256:$src2, i8imm:$src3),
7422           "vperm2f128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
7423           []>, VEX_4V;
7424 let mayLoad = 1 in
7425 def VPERM2F128rm : AVXAIi8<0x06, MRMSrcMem, (outs VR256:$dst),
7426           (ins VR256:$src1, f256mem:$src2, i8imm:$src3),
7427           "vperm2f128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
7428           []>, VEX_4V;
7429 }
7430
7431 let Predicates = [HasAVX] in {
7432 def : Pat<(int_x86_avx_vperm2f128_ps_256 VR256:$src1, VR256:$src2, imm:$src3),
7433           (VPERM2F128rr VR256:$src1, VR256:$src2, imm:$src3)>;
7434 def : Pat<(int_x86_avx_vperm2f128_pd_256 VR256:$src1, VR256:$src2, imm:$src3),
7435           (VPERM2F128rr VR256:$src1, VR256:$src2, imm:$src3)>;
7436 def : Pat<(int_x86_avx_vperm2f128_si_256 VR256:$src1, VR256:$src2, imm:$src3),
7437           (VPERM2F128rr VR256:$src1, VR256:$src2, imm:$src3)>;
7438
7439 def : Pat<(int_x86_avx_vperm2f128_ps_256
7440                   VR256:$src1, (memopv8f32 addr:$src2), imm:$src3),
7441           (VPERM2F128rm VR256:$src1, addr:$src2, imm:$src3)>;
7442 def : Pat<(int_x86_avx_vperm2f128_pd_256
7443                   VR256:$src1, (memopv4f64 addr:$src2), imm:$src3),
7444           (VPERM2F128rm VR256:$src1, addr:$src2, imm:$src3)>;
7445 def : Pat<(int_x86_avx_vperm2f128_si_256
7446                   VR256:$src1, (bc_v8i32 (memopv4i64 addr:$src2)), imm:$src3),
7447           (VPERM2F128rm VR256:$src1, addr:$src2, imm:$src3)>;
7448 }
7449
7450 //===----------------------------------------------------------------------===//
7451 // VZERO - Zero YMM registers
7452 //
7453 let Defs = [YMM0, YMM1, YMM2, YMM3, YMM4, YMM5, YMM6, YMM7,
7454             YMM8, YMM9, YMM10, YMM11, YMM12, YMM13, YMM14, YMM15] in {
7455   // Zero All YMM registers
7456   def VZEROALL : I<0x77, RawFrm, (outs), (ins), "vzeroall",
7457                   [(int_x86_avx_vzeroall)]>, TB, VEX, VEX_L, Requires<[HasAVX]>;
7458
7459   // Zero Upper bits of YMM registers
7460   def VZEROUPPER : I<0x77, RawFrm, (outs), (ins), "vzeroupper",
7461                      [(int_x86_avx_vzeroupper)]>, TB, VEX, Requires<[HasAVX]>;
7462 }
7463
7464 //===----------------------------------------------------------------------===//
7465 // Half precision conversion instructions
7466 //===----------------------------------------------------------------------===//
7467 multiclass f16c_ph2ps<RegisterClass RC, X86MemOperand x86memop, Intrinsic Int> {
7468 let Predicates = [HasAVX, HasF16C] in {
7469   def rr : I<0x13, MRMSrcReg, (outs RC:$dst), (ins VR128:$src),
7470              "vcvtph2ps\t{$src, $dst|$dst, $src}",
7471              [(set RC:$dst, (Int VR128:$src))]>,
7472              T8, OpSize, VEX;
7473   let neverHasSideEffects = 1, mayLoad = 1 in
7474   def rm : I<0x13, MRMSrcMem, (outs RC:$dst), (ins x86memop:$src),
7475              "vcvtph2ps\t{$src, $dst|$dst, $src}", []>, T8, OpSize, VEX;
7476 }
7477 }
7478
7479 multiclass f16c_ps2ph<RegisterClass RC, X86MemOperand x86memop, Intrinsic Int> {
7480 let Predicates = [HasAVX, HasF16C] in {
7481   def rr : Ii8<0x1D, MRMDestReg, (outs VR128:$dst),
7482                (ins RC:$src1, i32i8imm:$src2),
7483                "vcvtps2ph\t{$src2, $src1, $dst|$dst, $src1, $src2}",
7484                [(set VR128:$dst, (Int RC:$src1, imm:$src2))]>,
7485                TA, OpSize, VEX;
7486   let neverHasSideEffects = 1, mayLoad = 1 in
7487   def mr : Ii8<0x1D, MRMDestMem, (outs x86memop:$dst),
7488                (ins RC:$src1, i32i8imm:$src2),
7489                "vcvtps2ph\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>,
7490                TA, OpSize, VEX;
7491 }
7492 }
7493
7494 defm VCVTPH2PS  : f16c_ph2ps<VR128, f64mem, int_x86_vcvtph2ps_128>;
7495 defm VCVTPH2PSY : f16c_ph2ps<VR256, f128mem, int_x86_vcvtph2ps_256>;
7496 defm VCVTPS2PH  : f16c_ps2ph<VR128, f64mem, int_x86_vcvtps2ph_128>;
7497 defm VCVTPS2PHY : f16c_ps2ph<VR256, f128mem, int_x86_vcvtps2ph_256>;
7498
7499 //===----------------------------------------------------------------------===//
7500 // AVX2 Instructions
7501 //===----------------------------------------------------------------------===//
7502
7503 /// AVX2_binop_rmi_int - AVX2 binary operator with 8-bit immediate
7504 multiclass AVX2_binop_rmi_int<bits<8> opc, string OpcodeStr,
7505                  Intrinsic IntId, RegisterClass RC, PatFrag memop_frag,
7506                  X86MemOperand x86memop> {
7507   let isCommutable = 1 in
7508   def rri : AVX2AIi8<opc, MRMSrcReg, (outs RC:$dst),
7509         (ins RC:$src1, RC:$src2, u32u8imm:$src3),
7510         !strconcat(OpcodeStr,
7511             "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
7512         [(set RC:$dst, (IntId RC:$src1, RC:$src2, imm:$src3))]>,
7513         VEX_4V;
7514   def rmi : AVX2AIi8<opc, MRMSrcMem, (outs RC:$dst),
7515         (ins RC:$src1, x86memop:$src2, u32u8imm:$src3),
7516         !strconcat(OpcodeStr,
7517             "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
7518         [(set RC:$dst,
7519           (IntId RC:$src1,
7520            (bitconvert (memop_frag addr:$src2)), imm:$src3))]>,
7521         VEX_4V;
7522 }
7523
7524 let isCommutable = 0 in {
7525 defm VPBLENDD : AVX2_binop_rmi_int<0x02, "vpblendd", int_x86_avx2_pblendd_128,
7526                                    VR128, memopv2i64, i128mem>;
7527 defm VPBLENDDY : AVX2_binop_rmi_int<0x02, "vpblendd", int_x86_avx2_pblendd_256,
7528                                     VR256, memopv4i64, i256mem>;
7529 }
7530
7531 //===----------------------------------------------------------------------===//
7532 // VPBROADCAST - Load from memory and broadcast to all elements of the
7533 //               destination operand
7534 //
7535 multiclass avx2_broadcast<bits<8> opc, string OpcodeStr,
7536                           X86MemOperand x86memop, PatFrag ld_frag,
7537                           Intrinsic Int128, Intrinsic Int256> {
7538   def rr : AVX28I<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
7539                   !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
7540                   [(set VR128:$dst, (Int128 VR128:$src))]>, VEX;
7541   def rm : AVX28I<opc, MRMSrcMem, (outs VR128:$dst), (ins x86memop:$src),
7542                   !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
7543                   [(set VR128:$dst,
7544                     (Int128 (scalar_to_vector (ld_frag addr:$src))))]>, VEX;
7545   def Yrr : AVX28I<opc, MRMSrcReg, (outs VR256:$dst), (ins VR128:$src),
7546                    !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
7547                    [(set VR256:$dst, (Int256 VR128:$src))]>, VEX;
7548   def Yrm : AVX28I<opc, MRMSrcMem, (outs VR256:$dst), (ins x86memop:$src),
7549                    !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
7550                    [(set VR256:$dst,
7551                     (Int256 (scalar_to_vector (ld_frag addr:$src))))]>, VEX;
7552 }
7553
7554 defm VPBROADCASTB  : avx2_broadcast<0x78, "vpbroadcastb", i8mem, loadi8,
7555                                     int_x86_avx2_pbroadcastb_128,
7556                                     int_x86_avx2_pbroadcastb_256>;
7557 defm VPBROADCASTW  : avx2_broadcast<0x79, "vpbroadcastw", i16mem, loadi16,
7558                                     int_x86_avx2_pbroadcastw_128,
7559                                     int_x86_avx2_pbroadcastw_256>;
7560 defm VPBROADCASTD  : avx2_broadcast<0x58, "vpbroadcastd", i32mem, loadi32,
7561                                     int_x86_avx2_pbroadcastd_128,
7562                                     int_x86_avx2_pbroadcastd_256>;
7563 defm VPBROADCASTQ  : avx2_broadcast<0x59, "vpbroadcastq", i64mem, loadi64,
7564                                     int_x86_avx2_pbroadcastq_128,
7565                                     int_x86_avx2_pbroadcastq_256>;
7566
7567 let Predicates = [HasAVX2] in {
7568   def : Pat<(v16i8 (X86VBroadcast (loadi8 addr:$src))),
7569           (VPBROADCASTBrm addr:$src)>;
7570   def : Pat<(v32i8 (X86VBroadcast (loadi8 addr:$src))),
7571           (VPBROADCASTBYrm addr:$src)>;
7572   def : Pat<(v8i16 (X86VBroadcast (loadi16 addr:$src))),
7573           (VPBROADCASTWrm addr:$src)>;
7574   def : Pat<(v16i16 (X86VBroadcast (loadi16 addr:$src))),
7575           (VPBROADCASTWYrm addr:$src)>;
7576   def : Pat<(v4i32 (X86VBroadcast (loadi32 addr:$src))),
7577           (VPBROADCASTDrm addr:$src)>;
7578   def : Pat<(v8i32 (X86VBroadcast (loadi32 addr:$src))),
7579           (VPBROADCASTDYrm addr:$src)>;
7580   def : Pat<(v2i64 (X86VBroadcast (loadi64 addr:$src))),
7581           (VPBROADCASTQrm addr:$src)>;
7582   def : Pat<(v4i64 (X86VBroadcast (loadi64 addr:$src))),
7583           (VPBROADCASTQYrm addr:$src)>;
7584 }
7585
7586 // AVX1 broadcast patterns
7587 let Predicates = [HasAVX] in {
7588 def : Pat<(v8i32 (X86VBroadcast (loadi32 addr:$src))),
7589           (VBROADCASTSSYrm addr:$src)>;
7590 def : Pat<(v4i64 (X86VBroadcast (loadi64 addr:$src))),
7591           (VBROADCASTSDrm addr:$src)>;
7592 def : Pat<(v8f32 (X86VBroadcast (loadf32 addr:$src))),
7593           (VBROADCASTSSYrm addr:$src)>;
7594 def : Pat<(v4f64 (X86VBroadcast (loadf64 addr:$src))),
7595           (VBROADCASTSDrm addr:$src)>;
7596
7597 def : Pat<(v4f32 (X86VBroadcast (loadf32 addr:$src))),
7598           (VBROADCASTSSrm addr:$src)>;
7599 def : Pat<(v4i32 (X86VBroadcast (loadi32 addr:$src))),
7600           (VBROADCASTSSrm addr:$src)>;
7601 }
7602
7603 //===----------------------------------------------------------------------===//
7604 // VPERM - Permute instructions
7605 //
7606
7607 multiclass avx2_perm<bits<8> opc, string OpcodeStr, PatFrag mem_frag,
7608                      Intrinsic Int> {
7609   def Yrr : AVX28I<opc, MRMSrcReg, (outs VR256:$dst),
7610                    (ins VR256:$src1, VR256:$src2),
7611                    !strconcat(OpcodeStr,
7612                        "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7613                    [(set VR256:$dst, (Int VR256:$src1, VR256:$src2))]>, VEX_4V;
7614   def Yrm : AVX28I<opc, MRMSrcMem, (outs VR256:$dst),
7615                    (ins VR256:$src1, i256mem:$src2),
7616                    !strconcat(OpcodeStr,
7617                        "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7618                    [(set VR256:$dst, (Int VR256:$src1,
7619                                       (bitconvert (mem_frag addr:$src2))))]>,
7620                    VEX_4V;
7621 }
7622
7623 defm VPERMD : avx2_perm<0x36, "vpermd", memopv4i64, int_x86_avx2_permd>;
7624 let ExeDomain = SSEPackedSingle in
7625 defm VPERMPS : avx2_perm<0x16, "vpermps", memopv8f32, int_x86_avx2_permps>;
7626
7627 multiclass avx2_perm_imm<bits<8> opc, string OpcodeStr, PatFrag mem_frag,
7628                          Intrinsic Int> {
7629   def Yrr : AVX2AIi8<opc, MRMSrcReg, (outs VR256:$dst),
7630                      (ins VR256:$src1, i8imm:$src2),
7631                      !strconcat(OpcodeStr,
7632                          "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7633                      [(set VR256:$dst, (Int VR256:$src1, imm:$src2))]>, VEX;
7634   def Yrm : AVX2AIi8<opc, MRMSrcMem, (outs VR256:$dst),
7635                      (ins i256mem:$src1, i8imm:$src2),
7636                      !strconcat(OpcodeStr,
7637                          "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7638                      [(set VR256:$dst, (Int (mem_frag addr:$src1), imm:$src2))]>,
7639                      VEX;
7640 }
7641
7642 defm VPERMQ : avx2_perm_imm<0x00, "vpermq", memopv4i64, int_x86_avx2_permq>,
7643                             VEX_W;
7644 let ExeDomain = SSEPackedDouble in
7645 defm VPERMPD : avx2_perm_imm<0x01, "vpermpd", memopv4f64, int_x86_avx2_permpd>,
7646                              VEX_W;
7647
7648 //===----------------------------------------------------------------------===//
7649 // VPERM2I128 - Permute Floating-Point Values in 128-bit chunks
7650 //
7651 def VPERM2I128rr : AVX2AIi8<0x46, MRMSrcReg, (outs VR256:$dst),
7652           (ins VR256:$src1, VR256:$src2, i8imm:$src3),
7653           "vperm2i128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
7654           [(set VR256:$dst,
7655            (int_x86_avx2_vperm2i128 VR256:$src1, VR256:$src2, imm:$src3))]>,
7656           VEX_4V;
7657 def VPERM2I128rm : AVX2AIi8<0x46, MRMSrcMem, (outs VR256:$dst),
7658           (ins VR256:$src1, f256mem:$src2, i8imm:$src3),
7659           "vperm2i128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
7660           [(set VR256:$dst,
7661            (int_x86_avx2_vperm2i128 VR256:$src1, (memopv4i64 addr:$src2),
7662             imm:$src3))]>,
7663           VEX_4V;
7664
7665 let Predicates = [HasAVX2] in {
7666 def : Pat<(v8i32 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
7667           (VPERM2I128rr VR256:$src1, VR256:$src2, imm:$imm)>;
7668 def : Pat<(v4i64 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
7669           (VPERM2I128rr VR256:$src1, VR256:$src2, imm:$imm)>;
7670 def : Pat<(v32i8 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
7671           (VPERM2I128rr VR256:$src1, VR256:$src2, imm:$imm)>;
7672 def : Pat<(v16i16 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
7673           (VPERM2I128rr VR256:$src1, VR256:$src2, imm:$imm)>;
7674
7675 def : Pat<(v32i8 (X86VPerm2x128 VR256:$src1, (bc_v32i8 (memopv4i64 addr:$src2)),
7676                   (i8 imm:$imm))),
7677           (VPERM2I128rm VR256:$src1, addr:$src2, imm:$imm)>;
7678 def : Pat<(v16i16 (X86VPerm2x128 VR256:$src1,
7679                    (bc_v16i16 (memopv4i64 addr:$src2)), (i8 imm:$imm))),
7680           (VPERM2I128rm VR256:$src1, addr:$src2, imm:$imm)>;
7681 def : Pat<(v8i32 (X86VPerm2x128 VR256:$src1, (bc_v8i32 (memopv4i64 addr:$src2)),
7682                   (i8 imm:$imm))),
7683           (VPERM2I128rm VR256:$src1, addr:$src2, imm:$imm)>;
7684 def : Pat<(v4i64 (X86VPerm2x128 VR256:$src1, (memopv4i64 addr:$src2),
7685                   (i8 imm:$imm))),
7686           (VPERM2I128rm VR256:$src1, addr:$src2, imm:$imm)>;
7687 }
7688
7689 // AVX1 patterns
7690 let Predicates = [HasAVX] in {
7691 def : Pat<(v8f32 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
7692           (VPERM2F128rr VR256:$src1, VR256:$src2, imm:$imm)>;
7693 def : Pat<(v8i32 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
7694           (VPERM2F128rr VR256:$src1, VR256:$src2, imm:$imm)>;
7695 def : Pat<(v4i64 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
7696           (VPERM2F128rr VR256:$src1, VR256:$src2, imm:$imm)>;
7697 def : Pat<(v4f64 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
7698           (VPERM2F128rr VR256:$src1, VR256:$src2, imm:$imm)>;
7699 def : Pat<(v32i8 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
7700           (VPERM2F128rr VR256:$src1, VR256:$src2, imm:$imm)>;
7701 def : Pat<(v16i16 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
7702           (VPERM2F128rr VR256:$src1, VR256:$src2, imm:$imm)>;
7703
7704 def : Pat<(v8f32 (X86VPerm2x128 VR256:$src1,
7705                   (memopv8f32 addr:$src2), (i8 imm:$imm))),
7706           (VPERM2F128rm VR256:$src1, addr:$src2, imm:$imm)>;
7707 def : Pat<(v8i32 (X86VPerm2x128 VR256:$src1,
7708                   (bc_v8i32 (memopv4i64 addr:$src2)), (i8 imm:$imm))),
7709           (VPERM2F128rm VR256:$src1, addr:$src2, imm:$imm)>;
7710 def : Pat<(v4i64 (X86VPerm2x128 VR256:$src1,
7711                   (memopv4i64 addr:$src2), (i8 imm:$imm))),
7712           (VPERM2F128rm VR256:$src1, addr:$src2, imm:$imm)>;
7713 def : Pat<(v4f64 (X86VPerm2x128 VR256:$src1,
7714                   (memopv4f64 addr:$src2), (i8 imm:$imm))),
7715           (VPERM2F128rm VR256:$src1, addr:$src2, imm:$imm)>;
7716 def : Pat<(v32i8 (X86VPerm2x128 VR256:$src1,
7717                   (bc_v32i8 (memopv4i64 addr:$src2)), (i8 imm:$imm))),
7718           (VPERM2F128rm VR256:$src1, addr:$src2, imm:$imm)>;
7719 def : Pat<(v16i16 (X86VPerm2x128 VR256:$src1,
7720                   (bc_v16i16 (memopv4i64 addr:$src2)), (i8 imm:$imm))),
7721           (VPERM2F128rm VR256:$src1, addr:$src2, imm:$imm)>;
7722 }
7723
7724
7725 //===----------------------------------------------------------------------===//
7726 // VINSERTI128 - Insert packed integer values
7727 //
7728 def VINSERTI128rr : AVX2AIi8<0x38, MRMSrcReg, (outs VR256:$dst),
7729           (ins VR256:$src1, VR128:$src2, i8imm:$src3),
7730           "vinserti128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
7731           [(set VR256:$dst,
7732             (int_x86_avx2_vinserti128 VR256:$src1, VR128:$src2, imm:$src3))]>,
7733           VEX_4V;
7734 def VINSERTI128rm : AVX2AIi8<0x38, MRMSrcMem, (outs VR256:$dst),
7735           (ins VR256:$src1, i128mem:$src2, i8imm:$src3),
7736           "vinserti128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
7737           [(set VR256:$dst,
7738             (int_x86_avx2_vinserti128 VR256:$src1, (memopv2i64 addr:$src2),
7739              imm:$src3))]>, VEX_4V;
7740
7741 let Predicates = [HasAVX2] in {
7742 def : Pat<(vinsertf128_insert:$ins (v4i64 VR256:$src1), (v2i64 VR128:$src2),
7743                                    (i32 imm)),
7744           (VINSERTI128rr VR256:$src1, VR128:$src2,
7745                          (INSERT_get_vinsertf128_imm VR256:$ins))>;
7746 def : Pat<(vinsertf128_insert:$ins (v8i32 VR256:$src1), (v4i32 VR128:$src2),
7747                                    (i32 imm)),
7748           (VINSERTI128rr VR256:$src1, VR128:$src2,
7749                          (INSERT_get_vinsertf128_imm VR256:$ins))>;
7750 def : Pat<(vinsertf128_insert:$ins (v32i8 VR256:$src1), (v16i8 VR128:$src2),
7751                                    (i32 imm)),
7752           (VINSERTI128rr VR256:$src1, VR128:$src2,
7753                          (INSERT_get_vinsertf128_imm VR256:$ins))>;
7754 def : Pat<(vinsertf128_insert:$ins (v16i16 VR256:$src1), (v8i16 VR128:$src2),
7755                                    (i32 imm)),
7756           (VINSERTI128rr VR256:$src1, VR128:$src2,
7757                          (INSERT_get_vinsertf128_imm VR256:$ins))>;
7758 }
7759
7760 // AVX1 patterns
7761 let Predicates = [HasAVX] in {
7762 def : Pat<(vinsertf128_insert:$ins (v8f32 VR256:$src1), (v4f32 VR128:$src2),
7763                                    (i32 imm)),
7764           (VINSERTF128rr VR256:$src1, VR128:$src2,
7765                          (INSERT_get_vinsertf128_imm VR256:$ins))>;
7766 def : Pat<(vinsertf128_insert:$ins (v4f64 VR256:$src1), (v2f64 VR128:$src2),
7767                                    (i32 imm)),
7768           (VINSERTF128rr VR256:$src1, VR128:$src2,
7769                          (INSERT_get_vinsertf128_imm VR256:$ins))>;
7770 def : Pat<(vinsertf128_insert:$ins (v4i64 VR256:$src1), (v2i64 VR128:$src2),
7771                                    (i32 imm)),
7772           (VINSERTF128rr VR256:$src1, VR128:$src2,
7773                          (INSERT_get_vinsertf128_imm VR256:$ins))>;
7774 def : Pat<(vinsertf128_insert:$ins (v8i32 VR256:$src1), (v4i32 VR128:$src2),
7775                                    (i32 imm)),
7776           (VINSERTF128rr VR256:$src1, VR128:$src2,
7777                          (INSERT_get_vinsertf128_imm VR256:$ins))>;
7778 def : Pat<(vinsertf128_insert:$ins (v32i8 VR256:$src1), (v16i8 VR128:$src2),
7779                                    (i32 imm)),
7780           (VINSERTF128rr VR256:$src1, VR128:$src2,
7781                          (INSERT_get_vinsertf128_imm VR256:$ins))>;
7782 def : Pat<(vinsertf128_insert:$ins (v16i16 VR256:$src1), (v8i16 VR128:$src2),
7783                                    (i32 imm)),
7784           (VINSERTF128rr VR256:$src1, VR128:$src2,
7785                          (INSERT_get_vinsertf128_imm VR256:$ins))>;
7786 }
7787
7788 //===----------------------------------------------------------------------===//
7789 // VEXTRACTI128 - Extract packed integer values
7790 //
7791 def VEXTRACTI128rr : AVX2AIi8<0x39, MRMDestReg, (outs VR128:$dst),
7792           (ins VR256:$src1, i8imm:$src2),
7793           "vextracti128\t{$src2, $src1, $dst|$dst, $src1, $src2}",
7794           [(set VR128:$dst,
7795             (int_x86_avx2_vextracti128 VR256:$src1, imm:$src2))]>,
7796           VEX;
7797 let neverHasSideEffects = 1, mayStore = 1 in
7798 def VEXTRACTI128mr : AVX2AIi8<0x39, MRMDestMem, (outs),
7799           (ins i128mem:$dst, VR256:$src1, i8imm:$src2),
7800           "vextracti128\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>, VEX;
7801
7802 let Predicates = [HasAVX2] in {
7803 def : Pat<(vextractf128_extract:$ext VR256:$src1, (i32 imm)),
7804           (v2i64 (VEXTRACTI128rr
7805                     (v4i64 VR256:$src1),
7806                     (EXTRACT_get_vextractf128_imm VR128:$ext)))>;
7807 def : Pat<(vextractf128_extract:$ext VR256:$src1, (i32 imm)),
7808           (v4i32 (VEXTRACTI128rr
7809                     (v8i32 VR256:$src1),
7810                     (EXTRACT_get_vextractf128_imm VR128:$ext)))>;
7811 def : Pat<(vextractf128_extract:$ext VR256:$src1, (i32 imm)),
7812           (v8i16 (VEXTRACTI128rr
7813                     (v16i16 VR256:$src1),
7814                     (EXTRACT_get_vextractf128_imm VR128:$ext)))>;
7815 def : Pat<(vextractf128_extract:$ext VR256:$src1, (i32 imm)),
7816           (v16i8 (VEXTRACTI128rr
7817                     (v32i8 VR256:$src1),
7818                     (EXTRACT_get_vextractf128_imm VR128:$ext)))>;
7819 }
7820
7821 // AVX1 patterns
7822 let Predicates = [HasAVX] in {
7823 def : Pat<(vextractf128_extract:$ext VR256:$src1, (i32 imm)),
7824           (v4f32 (VEXTRACTF128rr
7825                     (v8f32 VR256:$src1),
7826                     (EXTRACT_get_vextractf128_imm VR128:$ext)))>;
7827 def : Pat<(vextractf128_extract:$ext VR256:$src1, (i32 imm)),
7828           (v2f64 (VEXTRACTF128rr
7829                     (v4f64 VR256:$src1),
7830                     (EXTRACT_get_vextractf128_imm VR128:$ext)))>;
7831 def : Pat<(vextractf128_extract:$ext VR256:$src1, (i32 imm)),
7832           (v2i64 (VEXTRACTF128rr
7833                     (v4i64 VR256:$src1),
7834                     (EXTRACT_get_vextractf128_imm VR128:$ext)))>;
7835 def : Pat<(vextractf128_extract:$ext VR256:$src1, (i32 imm)),
7836           (v4i32 (VEXTRACTF128rr
7837                     (v8i32 VR256:$src1),
7838                     (EXTRACT_get_vextractf128_imm VR128:$ext)))>;
7839 def : Pat<(vextractf128_extract:$ext VR256:$src1, (i32 imm)),
7840           (v8i16 (VEXTRACTF128rr
7841                     (v16i16 VR256:$src1),
7842                     (EXTRACT_get_vextractf128_imm VR128:$ext)))>;
7843 def : Pat<(vextractf128_extract:$ext VR256:$src1, (i32 imm)),
7844           (v16i8 (VEXTRACTF128rr
7845                     (v32i8 VR256:$src1),
7846                     (EXTRACT_get_vextractf128_imm VR128:$ext)))>;
7847 }
7848
7849 //===----------------------------------------------------------------------===//
7850 // VPMASKMOV - Conditional SIMD Integer Packed Loads and Stores
7851 //
7852 multiclass avx2_pmovmask<string OpcodeStr,
7853                          Intrinsic IntLd128, Intrinsic IntLd256,
7854                          Intrinsic IntSt128, Intrinsic IntSt256> {
7855   def rm  : AVX28I<0x8c, MRMSrcMem, (outs VR128:$dst),
7856              (ins VR128:$src1, i128mem:$src2),
7857              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7858              [(set VR128:$dst, (IntLd128 addr:$src2, VR128:$src1))]>, VEX_4V;
7859   def Yrm : AVX28I<0x8c, MRMSrcMem, (outs VR256:$dst),
7860              (ins VR256:$src1, i256mem:$src2),
7861              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7862              [(set VR256:$dst, (IntLd256 addr:$src2, VR256:$src1))]>, VEX_4V;
7863   def mr  : AVX28I<0x8e, MRMDestMem, (outs),
7864              (ins i128mem:$dst, VR128:$src1, VR128:$src2),
7865              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7866              [(IntSt128 addr:$dst, VR128:$src1, VR128:$src2)]>, VEX_4V;
7867   def Ymr : AVX28I<0x8e, MRMDestMem, (outs),
7868              (ins i256mem:$dst, VR256:$src1, VR256:$src2),
7869              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7870              [(IntSt256 addr:$dst, VR256:$src1, VR256:$src2)]>, VEX_4V;
7871 }
7872
7873 defm VPMASKMOVD : avx2_pmovmask<"vpmaskmovd",
7874                                 int_x86_avx2_maskload_d,
7875                                 int_x86_avx2_maskload_d_256,
7876                                 int_x86_avx2_maskstore_d,
7877                                 int_x86_avx2_maskstore_d_256>;
7878 defm VPMASKMOVQ : avx2_pmovmask<"vpmaskmovq",
7879                                 int_x86_avx2_maskload_q,
7880                                 int_x86_avx2_maskload_q_256,
7881                                 int_x86_avx2_maskstore_q,
7882                                 int_x86_avx2_maskstore_q_256>, VEX_W;
7883
7884
7885 //===----------------------------------------------------------------------===//
7886 // Variable Bit Shifts
7887 //
7888 multiclass avx2_var_shift<bits<8> opc, string OpcodeStr, SDNode OpNode,
7889                           ValueType vt128, ValueType vt256> {
7890   def rr  : AVX28I<opc, MRMSrcReg, (outs VR128:$dst),
7891              (ins VR128:$src1, VR128:$src2),
7892              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7893              [(set VR128:$dst,
7894                (vt128 (OpNode VR128:$src1, (vt128 VR128:$src2))))]>,
7895              VEX_4V;
7896   def rm  : AVX28I<opc, MRMSrcMem, (outs VR128:$dst),
7897              (ins VR128:$src1, i128mem:$src2),
7898              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7899              [(set VR128:$dst,
7900                (vt128 (OpNode VR128:$src1,
7901                        (vt128 (bitconvert (memopv2i64 addr:$src2))))))]>,
7902              VEX_4V;
7903   def Yrr : AVX28I<opc, MRMSrcReg, (outs VR256:$dst),
7904              (ins VR256:$src1, VR256:$src2),
7905              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7906              [(set VR256:$dst,
7907                (vt256 (OpNode VR256:$src1, (vt256 VR256:$src2))))]>,
7908              VEX_4V;
7909   def Yrm : AVX28I<opc, MRMSrcMem, (outs VR256:$dst),
7910              (ins VR256:$src1, i256mem:$src2),
7911              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7912              [(set VR256:$dst,
7913                (vt256 (OpNode VR256:$src1,
7914                        (vt256 (bitconvert (memopv4i64 addr:$src2))))))]>,
7915              VEX_4V;
7916 }
7917
7918 defm VPSLLVD : avx2_var_shift<0x47, "vpsllvd", shl, v4i32, v8i32>;
7919 defm VPSLLVQ : avx2_var_shift<0x47, "vpsllvq", shl, v2i64, v4i64>, VEX_W;
7920 defm VPSRLVD : avx2_var_shift<0x45, "vpsrlvd", srl, v4i32, v8i32>;
7921 defm VPSRLVQ : avx2_var_shift<0x45, "vpsrlvq", srl, v2i64, v4i64>, VEX_W;
7922 defm VPSRAVD : avx2_var_shift<0x46, "vpsravd", sra, v4i32, v8i32>;