Remove AVX 256-bit unaligned load intrinsics. 128-bit versions had been removed a...
[oota-llvm.git] / lib / Target / X86 / X86InstrSSE.td
1 //====- X86InstrSSE.td - Describe the X86 Instruction Set --*- tablegen -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file describes the X86 SSE instruction set, defining the instructions,
11 // and properties of the instructions which are needed for code generation,
12 // machine code emission, and analysis.
13 //
14 //===----------------------------------------------------------------------===//
15
16
17 //===----------------------------------------------------------------------===//
18 // SSE 1 & 2 Instructions Classes
19 //===----------------------------------------------------------------------===//
20
21 /// sse12_fp_scalar - SSE 1 & 2 scalar instructions class
22 multiclass sse12_fp_scalar<bits<8> opc, string OpcodeStr, SDNode OpNode,
23                            RegisterClass RC, X86MemOperand x86memop,
24                            bit Is2Addr = 1> {
25   let isCommutable = 1 in {
26     def rr : SI<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
27        !if(Is2Addr,
28            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
29            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
30        [(set RC:$dst, (OpNode RC:$src1, RC:$src2))]>;
31   }
32   def rm : SI<opc, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
33        !if(Is2Addr,
34            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
35            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
36        [(set RC:$dst, (OpNode RC:$src1, (load addr:$src2)))]>;
37 }
38
39 /// sse12_fp_scalar_int - SSE 1 & 2 scalar instructions intrinsics class
40 multiclass sse12_fp_scalar_int<bits<8> opc, string OpcodeStr, RegisterClass RC,
41                              string asm, string SSEVer, string FPSizeStr,
42                              Operand memopr, ComplexPattern mem_cpat,
43                              bit Is2Addr = 1> {
44   def rr_Int : SI<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
45        !if(Is2Addr,
46            !strconcat(asm, "\t{$src2, $dst|$dst, $src2}"),
47            !strconcat(asm, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
48        [(set RC:$dst, (!cast<Intrinsic>(
49                  !strconcat("int_x86_sse", SSEVer, "_", OpcodeStr, FPSizeStr))
50              RC:$src1, RC:$src2))]>;
51   def rm_Int : SI<opc, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, memopr:$src2),
52        !if(Is2Addr,
53            !strconcat(asm, "\t{$src2, $dst|$dst, $src2}"),
54            !strconcat(asm, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
55        [(set RC:$dst, (!cast<Intrinsic>(!strconcat("int_x86_sse",
56                                           SSEVer, "_", OpcodeStr, FPSizeStr))
57              RC:$src1, mem_cpat:$src2))]>;
58 }
59
60 /// sse12_fp_packed - SSE 1 & 2 packed instructions class
61 multiclass sse12_fp_packed<bits<8> opc, string OpcodeStr, SDNode OpNode,
62                            RegisterClass RC, ValueType vt,
63                            X86MemOperand x86memop, PatFrag mem_frag,
64                            Domain d, bit Is2Addr = 1> {
65   let isCommutable = 1 in
66     def rr : PI<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
67        !if(Is2Addr,
68            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
69            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
70        [(set RC:$dst, (vt (OpNode RC:$src1, RC:$src2)))], d>;
71   let mayLoad = 1 in
72     def rm : PI<opc, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
73        !if(Is2Addr,
74            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
75            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
76        [(set RC:$dst, (OpNode RC:$src1, (mem_frag addr:$src2)))], d>;
77 }
78
79 /// sse12_fp_packed_logical_rm - SSE 1 & 2 packed instructions class
80 multiclass sse12_fp_packed_logical_rm<bits<8> opc, RegisterClass RC, Domain d,
81                                       string OpcodeStr, X86MemOperand x86memop,
82                                       list<dag> pat_rr, list<dag> pat_rm,
83                                       bit Is2Addr = 1,
84                                       bit rr_hasSideEffects = 0> {
85   let isCommutable = 1, neverHasSideEffects = rr_hasSideEffects in
86     def rr : PI<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
87        !if(Is2Addr,
88            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
89            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
90        pat_rr, d>;
91   def rm : PI<opc, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
92        !if(Is2Addr,
93            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
94            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
95        pat_rm, d>;
96 }
97
98 /// sse12_fp_packed_int - SSE 1 & 2 packed instructions intrinsics class
99 multiclass sse12_fp_packed_int<bits<8> opc, string OpcodeStr, RegisterClass RC,
100                            string asm, string SSEVer, string FPSizeStr,
101                            X86MemOperand x86memop, PatFrag mem_frag,
102                            Domain d, bit Is2Addr = 1> {
103   def rr_Int : PI<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
104        !if(Is2Addr,
105            !strconcat(asm, "\t{$src2, $dst|$dst, $src2}"),
106            !strconcat(asm, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
107            [(set RC:$dst, (!cast<Intrinsic>(
108                      !strconcat("int_x86_", SSEVer, "_", OpcodeStr, FPSizeStr))
109                  RC:$src1, RC:$src2))], d>;
110   def rm_Int : PI<opc, MRMSrcMem, (outs RC:$dst), (ins RC:$src1,x86memop:$src2),
111        !if(Is2Addr,
112            !strconcat(asm, "\t{$src2, $dst|$dst, $src2}"),
113            !strconcat(asm, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
114        [(set RC:$dst, (!cast<Intrinsic>(
115                      !strconcat("int_x86_", SSEVer, "_", OpcodeStr, FPSizeStr))
116              RC:$src1, (mem_frag addr:$src2)))], d>;
117 }
118
119 //===----------------------------------------------------------------------===//
120 //  Non-instruction patterns
121 //===----------------------------------------------------------------------===//
122
123 // A vector extract of the first f32/f64 position is a subregister copy
124 def : Pat<(f32 (vector_extract (v4f32 VR128:$src), (iPTR 0))),
125           (f32 (EXTRACT_SUBREG (v4f32 VR128:$src), sub_ss))>;
126 def : Pat<(f64 (vector_extract (v2f64 VR128:$src), (iPTR 0))),
127           (f64 (EXTRACT_SUBREG (v2f64 VR128:$src), sub_sd))>;
128
129 // A 128-bit subvector extract from the first 256-bit vector position
130 // is a subregister copy that needs no instruction.
131 def : Pat<(v4i32 (extract_subvector (v8i32 VR256:$src), (i32 0))),
132           (v4i32 (EXTRACT_SUBREG (v8i32 VR256:$src), sub_xmm))>;
133 def : Pat<(v4f32 (extract_subvector (v8f32 VR256:$src), (i32 0))),
134           (v4f32 (EXTRACT_SUBREG (v8f32 VR256:$src), sub_xmm))>;
135
136 def : Pat<(v2i64 (extract_subvector (v4i64 VR256:$src), (i32 0))),
137           (v2i64 (EXTRACT_SUBREG (v4i64 VR256:$src), sub_xmm))>;
138 def : Pat<(v2f64 (extract_subvector (v4f64 VR256:$src), (i32 0))),
139           (v2f64 (EXTRACT_SUBREG (v4f64 VR256:$src), sub_xmm))>;
140
141 def : Pat<(v8i16 (extract_subvector (v16i16 VR256:$src), (i32 0))),
142           (v8i16 (EXTRACT_SUBREG (v16i16 VR256:$src), sub_xmm))>;
143 def : Pat<(v16i8 (extract_subvector (v32i8 VR256:$src), (i32 0))),
144           (v16i8 (EXTRACT_SUBREG (v32i8 VR256:$src), sub_xmm))>;
145
146 // A 128-bit subvector insert to the first 256-bit vector position
147 // is a subregister copy that needs no instruction.
148 def : Pat<(insert_subvector undef, (v2i64 VR128:$src), (i32 0)),
149           (INSERT_SUBREG (v4i64 (IMPLICIT_DEF)), VR128:$src, sub_xmm)>;
150 def : Pat<(insert_subvector undef, (v2f64 VR128:$src), (i32 0)),
151           (INSERT_SUBREG (v4f64 (IMPLICIT_DEF)), VR128:$src, sub_xmm)>;
152 def : Pat<(insert_subvector undef, (v4i32 VR128:$src), (i32 0)),
153           (INSERT_SUBREG (v8i32 (IMPLICIT_DEF)), VR128:$src, sub_xmm)>;
154 def : Pat<(insert_subvector undef, (v4f32 VR128:$src), (i32 0)),
155           (INSERT_SUBREG (v8f32 (IMPLICIT_DEF)), VR128:$src, sub_xmm)>;
156 def : Pat<(insert_subvector undef, (v8i16 VR128:$src), (i32 0)),
157           (INSERT_SUBREG (v16i16 (IMPLICIT_DEF)), VR128:$src, sub_xmm)>;
158 def : Pat<(insert_subvector undef, (v16i8 VR128:$src), (i32 0)),
159           (INSERT_SUBREG (v32i8 (IMPLICIT_DEF)), VR128:$src, sub_xmm)>;
160
161 // Implicitly promote a 32-bit scalar to a vector.
162 def : Pat<(v4f32 (scalar_to_vector FR32:$src)),
163           (INSERT_SUBREG (v4f32 (IMPLICIT_DEF)), FR32:$src, sub_ss)>;
164 def : Pat<(v8f32 (scalar_to_vector FR32:$src)),
165           (INSERT_SUBREG (v8f32 (IMPLICIT_DEF)), FR32:$src, sub_ss)>;
166 // Implicitly promote a 64-bit scalar to a vector.
167 def : Pat<(v2f64 (scalar_to_vector FR64:$src)),
168           (INSERT_SUBREG (v2f64 (IMPLICIT_DEF)), FR64:$src, sub_sd)>;
169 def : Pat<(v4f64 (scalar_to_vector FR64:$src)),
170           (INSERT_SUBREG (v4f64 (IMPLICIT_DEF)), FR64:$src, sub_sd)>;
171
172 // Bitcasts between 128-bit vector types. Return the original type since
173 // no instruction is needed for the conversion
174 let Predicates = [HasSSE2] in {
175   def : Pat<(v2i64 (bitconvert (v4i32 VR128:$src))), (v2i64 VR128:$src)>;
176   def : Pat<(v2i64 (bitconvert (v8i16 VR128:$src))), (v2i64 VR128:$src)>;
177   def : Pat<(v2i64 (bitconvert (v16i8 VR128:$src))), (v2i64 VR128:$src)>;
178   def : Pat<(v2i64 (bitconvert (v2f64 VR128:$src))), (v2i64 VR128:$src)>;
179   def : Pat<(v2i64 (bitconvert (v4f32 VR128:$src))), (v2i64 VR128:$src)>;
180   def : Pat<(v4i32 (bitconvert (v2i64 VR128:$src))), (v4i32 VR128:$src)>;
181   def : Pat<(v4i32 (bitconvert (v8i16 VR128:$src))), (v4i32 VR128:$src)>;
182   def : Pat<(v4i32 (bitconvert (v16i8 VR128:$src))), (v4i32 VR128:$src)>;
183   def : Pat<(v4i32 (bitconvert (v2f64 VR128:$src))), (v4i32 VR128:$src)>;
184   def : Pat<(v4i32 (bitconvert (v4f32 VR128:$src))), (v4i32 VR128:$src)>;
185   def : Pat<(v8i16 (bitconvert (v2i64 VR128:$src))), (v8i16 VR128:$src)>;
186   def : Pat<(v8i16 (bitconvert (v4i32 VR128:$src))), (v8i16 VR128:$src)>;
187   def : Pat<(v8i16 (bitconvert (v16i8 VR128:$src))), (v8i16 VR128:$src)>;
188   def : Pat<(v8i16 (bitconvert (v2f64 VR128:$src))), (v8i16 VR128:$src)>;
189   def : Pat<(v8i16 (bitconvert (v4f32 VR128:$src))), (v8i16 VR128:$src)>;
190   def : Pat<(v16i8 (bitconvert (v2i64 VR128:$src))), (v16i8 VR128:$src)>;
191   def : Pat<(v16i8 (bitconvert (v4i32 VR128:$src))), (v16i8 VR128:$src)>;
192   def : Pat<(v16i8 (bitconvert (v8i16 VR128:$src))), (v16i8 VR128:$src)>;
193   def : Pat<(v16i8 (bitconvert (v2f64 VR128:$src))), (v16i8 VR128:$src)>;
194   def : Pat<(v16i8 (bitconvert (v4f32 VR128:$src))), (v16i8 VR128:$src)>;
195   def : Pat<(v4f32 (bitconvert (v2i64 VR128:$src))), (v4f32 VR128:$src)>;
196   def : Pat<(v4f32 (bitconvert (v4i32 VR128:$src))), (v4f32 VR128:$src)>;
197   def : Pat<(v4f32 (bitconvert (v8i16 VR128:$src))), (v4f32 VR128:$src)>;
198   def : Pat<(v4f32 (bitconvert (v16i8 VR128:$src))), (v4f32 VR128:$src)>;
199   def : Pat<(v4f32 (bitconvert (v2f64 VR128:$src))), (v4f32 VR128:$src)>;
200   def : Pat<(v2f64 (bitconvert (v2i64 VR128:$src))), (v2f64 VR128:$src)>;
201   def : Pat<(v2f64 (bitconvert (v4i32 VR128:$src))), (v2f64 VR128:$src)>;
202   def : Pat<(v2f64 (bitconvert (v8i16 VR128:$src))), (v2f64 VR128:$src)>;
203   def : Pat<(v2f64 (bitconvert (v16i8 VR128:$src))), (v2f64 VR128:$src)>;
204   def : Pat<(v2f64 (bitconvert (v4f32 VR128:$src))), (v2f64 VR128:$src)>;
205 }
206
207 // Bitcasts between 256-bit vector types. Return the original type since
208 // no instruction is needed for the conversion
209 let Predicates = [HasAVX] in {
210   def : Pat<(v4f64  (bitconvert (v8f32 VR256:$src))),  (v4f64 VR256:$src)>;
211   def : Pat<(v4f64  (bitconvert (v8i32 VR256:$src))),  (v4f64 VR256:$src)>;
212   def : Pat<(v4f64  (bitconvert (v4i64 VR256:$src))),  (v4f64 VR256:$src)>;
213   def : Pat<(v4f64  (bitconvert (v16i16 VR256:$src))), (v4f64 VR256:$src)>;
214   def : Pat<(v4f64  (bitconvert (v32i8 VR256:$src))),  (v4f64 VR256:$src)>;
215   def : Pat<(v8f32  (bitconvert (v8i32 VR256:$src))),  (v8f32 VR256:$src)>;
216   def : Pat<(v8f32  (bitconvert (v4i64 VR256:$src))),  (v8f32 VR256:$src)>;
217   def : Pat<(v8f32  (bitconvert (v4f64 VR256:$src))),  (v8f32 VR256:$src)>;
218   def : Pat<(v8f32  (bitconvert (v32i8 VR256:$src))),  (v8f32 VR256:$src)>;
219   def : Pat<(v8f32  (bitconvert (v16i16 VR256:$src))), (v8f32 VR256:$src)>;
220   def : Pat<(v4i64  (bitconvert (v8f32 VR256:$src))),  (v4i64 VR256:$src)>;
221   def : Pat<(v4i64  (bitconvert (v8i32 VR256:$src))),  (v4i64 VR256:$src)>;
222   def : Pat<(v4i64  (bitconvert (v4f64 VR256:$src))),  (v4i64 VR256:$src)>;
223   def : Pat<(v4i64  (bitconvert (v32i8 VR256:$src))),  (v4i64 VR256:$src)>;
224   def : Pat<(v4i64  (bitconvert (v16i16 VR256:$src))), (v4i64 VR256:$src)>;
225   def : Pat<(v32i8  (bitconvert (v4f64 VR256:$src))),  (v32i8 VR256:$src)>;
226   def : Pat<(v32i8  (bitconvert (v4i64 VR256:$src))),  (v32i8 VR256:$src)>;
227   def : Pat<(v32i8  (bitconvert (v8f32 VR256:$src))),  (v32i8 VR256:$src)>;
228   def : Pat<(v32i8  (bitconvert (v8i32 VR256:$src))),  (v32i8 VR256:$src)>;
229   def : Pat<(v32i8  (bitconvert (v16i16 VR256:$src))), (v32i8 VR256:$src)>;
230   def : Pat<(v8i32  (bitconvert (v32i8 VR256:$src))),  (v8i32 VR256:$src)>;
231   def : Pat<(v8i32  (bitconvert (v16i16 VR256:$src))), (v8i32 VR256:$src)>;
232   def : Pat<(v8i32  (bitconvert (v8f32 VR256:$src))),  (v8i32 VR256:$src)>;
233   def : Pat<(v8i32  (bitconvert (v4i64 VR256:$src))),  (v8i32 VR256:$src)>;
234   def : Pat<(v8i32  (bitconvert (v4f64 VR256:$src))),  (v8i32 VR256:$src)>;
235   def : Pat<(v16i16 (bitconvert (v8f32 VR256:$src))),  (v16i16 VR256:$src)>;
236   def : Pat<(v16i16 (bitconvert (v8i32 VR256:$src))),  (v16i16 VR256:$src)>;
237   def : Pat<(v16i16 (bitconvert (v4i64 VR256:$src))),  (v16i16 VR256:$src)>;
238   def : Pat<(v16i16 (bitconvert (v4f64 VR256:$src))),  (v16i16 VR256:$src)>;
239   def : Pat<(v16i16 (bitconvert (v32i8 VR256:$src))),  (v16i16 VR256:$src)>;
240 }
241
242 // Alias instructions that map fld0 to pxor for sse.
243 // This is expanded by ExpandPostRAPseudos.
244 let isReMaterializable = 1, isAsCheapAsAMove = 1, canFoldAsLoad = 1,
245     isPseudo = 1 in {
246   def FsFLD0SS : I<0, Pseudo, (outs FR32:$dst), (ins), "",
247                    [(set FR32:$dst, fp32imm0)]>, Requires<[HasSSE1]>;
248   def FsFLD0SD : I<0, Pseudo, (outs FR64:$dst), (ins), "",
249                    [(set FR64:$dst, fpimm0)]>, Requires<[HasSSE2]>;
250 }
251
252 //===----------------------------------------------------------------------===//
253 // AVX & SSE - Zero/One Vectors
254 //===----------------------------------------------------------------------===//
255
256 // Alias instruction that maps zero vector to pxor / xorp* for sse.
257 // This is expanded by ExpandPostRAPseudos to an xorps / vxorps, and then
258 // swizzled by ExecutionDepsFix to pxor.
259 // We set canFoldAsLoad because this can be converted to a constant-pool
260 // load of an all-zeros value if folding it would be beneficial.
261 let isReMaterializable = 1, isAsCheapAsAMove = 1, canFoldAsLoad = 1,
262     isPseudo = 1, neverHasSideEffects = 1 in {
263 def V_SET0 : I<0, Pseudo, (outs VR128:$dst), (ins), "", []>;
264 }
265
266 def : Pat<(v4f32 immAllZerosV), (V_SET0)>;
267 def : Pat<(v2f64 immAllZerosV), (V_SET0)>;
268 def : Pat<(v4i32 immAllZerosV), (V_SET0)>;
269 def : Pat<(v2i64 immAllZerosV), (V_SET0)>;
270 def : Pat<(v8i16 immAllZerosV), (V_SET0)>;
271 def : Pat<(v16i8 immAllZerosV), (V_SET0)>;
272
273
274 // The same as done above but for AVX.  The 256-bit ISA does not support PI,
275 // and doesn't need it because on sandy bridge the register is set to zero
276 // at the rename stage without using any execution unit, so SET0PSY
277 // and SET0PDY can be used for vector int instructions without penalty
278 // FIXME: Change encoding to pseudo! This is blocked right now by the x86
279 // JIT implementatioan, it does not expand the instructions below like
280 // X86MCInstLower does.
281 let isReMaterializable = 1, isAsCheapAsAMove = 1, canFoldAsLoad = 1,
282     isCodeGenOnly = 1 in {
283 let Predicates = [HasAVX] in {
284 def AVX_SET0PSY : PSI<0x57, MRMInitReg, (outs VR256:$dst), (ins), "",
285                    [(set VR256:$dst, (v8f32 immAllZerosV))]>, VEX_4V;
286 def AVX_SET0PDY : PDI<0x57, MRMInitReg, (outs VR256:$dst), (ins), "",
287                    [(set VR256:$dst, (v4f64 immAllZerosV))]>, VEX_4V;
288 }
289 let Predicates = [HasAVX2], neverHasSideEffects = 1 in
290 def AVX2_SET0   : PDI<0xef, MRMInitReg, (outs VR256:$dst), (ins), "",
291                    []>, VEX_4V;
292 }
293
294 let Predicates = [HasAVX2], AddedComplexity = 5 in {
295   def : Pat<(v4i64 immAllZerosV), (AVX2_SET0)>;
296   def : Pat<(v8i32 immAllZerosV), (AVX2_SET0)>;
297   def : Pat<(v16i16 immAllZerosV), (AVX2_SET0)>;
298   def : Pat<(v32i8 immAllZerosV), (AVX2_SET0)>;
299 }
300
301 // AVX has no support for 256-bit integer instructions, but since the 128-bit
302 // VPXOR instruction writes zero to its upper part, it's safe build zeros.
303 def : Pat<(v32i8 immAllZerosV), (SUBREG_TO_REG (i8 0), (V_SET0), sub_xmm)>;
304 def : Pat<(bc_v32i8 (v8f32 immAllZerosV)),
305           (SUBREG_TO_REG (i8 0), (V_SET0), sub_xmm)>;
306
307 def : Pat<(v16i16 immAllZerosV), (SUBREG_TO_REG (i16 0), (V_SET0), sub_xmm)>;
308 def : Pat<(bc_v16i16 (v8f32 immAllZerosV)),
309           (SUBREG_TO_REG (i16 0), (V_SET0), sub_xmm)>;
310
311 def : Pat<(v8i32 immAllZerosV), (SUBREG_TO_REG (i32 0), (V_SET0), sub_xmm)>;
312 def : Pat<(bc_v8i32 (v8f32 immAllZerosV)),
313           (SUBREG_TO_REG (i32 0), (V_SET0), sub_xmm)>;
314
315 def : Pat<(v4i64 immAllZerosV), (SUBREG_TO_REG (i64 0), (V_SET0), sub_xmm)>;
316 def : Pat<(bc_v4i64 (v8f32 immAllZerosV)),
317           (SUBREG_TO_REG (i64 0), (V_SET0), sub_xmm)>;
318
319 // We set canFoldAsLoad because this can be converted to a constant-pool
320 // load of an all-ones value if folding it would be beneficial.
321 // FIXME: Change encoding to pseudo! This is blocked right now by the x86
322 // JIT implementation, it does not expand the instructions below like
323 // X86MCInstLower does.
324 let isReMaterializable = 1, isAsCheapAsAMove = 1, canFoldAsLoad = 1,
325     isCodeGenOnly = 1, ExeDomain = SSEPackedInt in {
326   let Predicates = [HasAVX] in
327   def AVX_SETALLONES : PDI<0x76, MRMInitReg, (outs VR128:$dst), (ins), "",
328                          [(set VR128:$dst, (v4i32 immAllOnesV))]>, VEX_4V;
329   def V_SETALLONES : PDI<0x76, MRMInitReg, (outs VR128:$dst), (ins), "",
330                          [(set VR128:$dst, (v4i32 immAllOnesV))]>;
331   let Predicates = [HasAVX2] in
332   def AVX2_SETALLONES : PDI<0x76, MRMInitReg, (outs VR256:$dst), (ins), "",
333                           [(set VR256:$dst, (v8i32 immAllOnesV))]>, VEX_4V;
334 }
335
336
337 //===----------------------------------------------------------------------===//
338 // SSE 1 & 2 - Move FP Scalar Instructions
339 //
340 // Move Instructions. Register-to-register movss/movsd is not used for FR32/64
341 // register copies because it's a partial register update; FsMOVAPSrr/FsMOVAPDrr
342 // is used instead. Register-to-register movss/movsd is not modeled as an
343 // INSERT_SUBREG because INSERT_SUBREG requires that the insert be implementable
344 // in terms of a copy, and just mentioned, we don't use movss/movsd for copies.
345 //===----------------------------------------------------------------------===//
346
347 class sse12_move_rr<RegisterClass RC, ValueType vt, string asm> :
348       SI<0x10, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src1, RC:$src2), asm,
349       [(set (vt VR128:$dst), (movl VR128:$src1, (scalar_to_vector RC:$src2)))]>;
350
351 // Loading from memory automatically zeroing upper bits.
352 class sse12_move_rm<RegisterClass RC, X86MemOperand x86memop,
353                     PatFrag mem_pat, string OpcodeStr> :
354       SI<0x10, MRMSrcMem, (outs RC:$dst), (ins x86memop:$src),
355          !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
356                         [(set RC:$dst, (mem_pat addr:$src))]>;
357
358 // AVX
359 def VMOVSSrr : sse12_move_rr<FR32, v4f32,
360                 "movss\t{$src2, $src1, $dst|$dst, $src1, $src2}">, XS, VEX_4V,
361                 VEX_LIG;
362 def VMOVSDrr : sse12_move_rr<FR64, v2f64,
363                 "movsd\t{$src2, $src1, $dst|$dst, $src1, $src2}">, XD, VEX_4V,
364                 VEX_LIG;
365
366 // For the disassembler
367 let isCodeGenOnly = 1 in {
368   def VMOVSSrr_REV : SI<0x11, MRMDestReg, (outs VR128:$dst),
369                         (ins VR128:$src1, FR32:$src2),
370                         "movss\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>,
371                         XS, VEX_4V, VEX_LIG;
372   def VMOVSDrr_REV : SI<0x11, MRMDestReg, (outs VR128:$dst),
373                         (ins VR128:$src1, FR64:$src2),
374                         "movsd\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>,
375                         XD, VEX_4V, VEX_LIG;
376 }
377
378 let canFoldAsLoad = 1, isReMaterializable = 1 in {
379   def VMOVSSrm : sse12_move_rm<FR32, f32mem, loadf32, "movss">, XS, VEX,
380                  VEX_LIG;
381   let AddedComplexity = 20 in
382     def VMOVSDrm : sse12_move_rm<FR64, f64mem, loadf64, "movsd">, XD, VEX,
383                    VEX_LIG;
384 }
385
386 def VMOVSSmr : SI<0x11, MRMDestMem, (outs), (ins f32mem:$dst, FR32:$src),
387                   "movss\t{$src, $dst|$dst, $src}",
388                   [(store FR32:$src, addr:$dst)]>, XS, VEX, VEX_LIG;
389 def VMOVSDmr : SI<0x11, MRMDestMem, (outs), (ins f64mem:$dst, FR64:$src),
390                   "movsd\t{$src, $dst|$dst, $src}",
391                   [(store FR64:$src, addr:$dst)]>, XD, VEX, VEX_LIG;
392
393 // SSE1 & 2
394 let Constraints = "$src1 = $dst" in {
395   def MOVSSrr : sse12_move_rr<FR32, v4f32,
396                           "movss\t{$src2, $dst|$dst, $src2}">, XS;
397   def MOVSDrr : sse12_move_rr<FR64, v2f64,
398                           "movsd\t{$src2, $dst|$dst, $src2}">, XD;
399
400   // For the disassembler
401   let isCodeGenOnly = 1 in {
402     def MOVSSrr_REV : SI<0x11, MRMDestReg, (outs VR128:$dst),
403                          (ins VR128:$src1, FR32:$src2),
404                          "movss\t{$src2, $dst|$dst, $src2}", []>, XS;
405     def MOVSDrr_REV : SI<0x11, MRMDestReg, (outs VR128:$dst),
406                          (ins VR128:$src1, FR64:$src2),
407                          "movsd\t{$src2, $dst|$dst, $src2}", []>, XD;
408   }
409 }
410
411 let canFoldAsLoad = 1, isReMaterializable = 1 in {
412   def MOVSSrm : sse12_move_rm<FR32, f32mem, loadf32, "movss">, XS;
413
414   let AddedComplexity = 20 in
415     def MOVSDrm : sse12_move_rm<FR64, f64mem, loadf64, "movsd">, XD;
416 }
417
418 def MOVSSmr : SSI<0x11, MRMDestMem, (outs), (ins f32mem:$dst, FR32:$src),
419                   "movss\t{$src, $dst|$dst, $src}",
420                   [(store FR32:$src, addr:$dst)]>;
421 def MOVSDmr : SDI<0x11, MRMDestMem, (outs), (ins f64mem:$dst, FR64:$src),
422                   "movsd\t{$src, $dst|$dst, $src}",
423                   [(store FR64:$src, addr:$dst)]>;
424
425 // Patterns
426 let Predicates = [HasAVX] in {
427   let AddedComplexity = 15 in {
428   // Extract the low 32-bit value from one vector and insert it into another.
429   def : Pat<(v4f32 (movl VR128:$src1, VR128:$src2)),
430             (VMOVSSrr (v4f32 VR128:$src1),
431                       (EXTRACT_SUBREG (v4f32 VR128:$src2), sub_ss))>;
432   def : Pat<(v4i32 (movl VR128:$src1, VR128:$src2)),
433             (VMOVSSrr (v4i32 VR128:$src1),
434                       (EXTRACT_SUBREG (v4i32 VR128:$src2), sub_ss))>;
435
436   // Extract the low 64-bit value from one vector and insert it into another.
437   def : Pat<(v2f64 (movl VR128:$src1, VR128:$src2)),
438             (VMOVSDrr (v2f64 VR128:$src1),
439                       (EXTRACT_SUBREG (v2f64 VR128:$src2), sub_sd))>;
440   def : Pat<(v2i64 (movl VR128:$src1, VR128:$src2)),
441             (VMOVSDrr (v2i64 VR128:$src1),
442                       (EXTRACT_SUBREG (v2i64 VR128:$src2), sub_sd))>;
443
444   // vector_shuffle v1, v2 <4, 5, 2, 3> using movsd
445   def : Pat<(v4f32 (movlp VR128:$src1, VR128:$src2)),
446             (VMOVSDrr VR128:$src1, (EXTRACT_SUBREG VR128:$src2, sub_sd))>;
447   def : Pat<(v4i32 (movlp VR128:$src1, VR128:$src2)),
448             (VMOVSDrr VR128:$src1, (EXTRACT_SUBREG VR128:$src2, sub_sd))>;
449
450   // Move scalar to XMM zero-extended, zeroing a VR128 then do a
451   // MOVS{S,D} to the lower bits.
452   def : Pat<(v4f32 (X86vzmovl (v4f32 (scalar_to_vector FR32:$src)))),
453             (VMOVSSrr (v4f32 (V_SET0)), FR32:$src)>;
454   def : Pat<(v4f32 (X86vzmovl (v4f32 VR128:$src))),
455             (VMOVSSrr (v4f32 (V_SET0)),
456                       (f32 (EXTRACT_SUBREG (v4f32 VR128:$src), sub_ss)))>;
457   def : Pat<(v4i32 (X86vzmovl (v4i32 VR128:$src))),
458             (VMOVSSrr (v4i32 (V_SET0)),
459                       (EXTRACT_SUBREG (v4i32 VR128:$src), sub_ss))>;
460   def : Pat<(v2f64 (X86vzmovl (v2f64 (scalar_to_vector FR64:$src)))),
461             (VMOVSDrr (v2f64 (V_SET0)), FR64:$src)>;
462
463   // Move low f32 and clear high bits.
464   def : Pat<(v8f32 (X86vzmovl (v8f32 VR256:$src))),
465             (SUBREG_TO_REG (i32 0),
466               (VMOVSSrr (v4f32 (V_SET0)),
467                         (EXTRACT_SUBREG (v8f32 VR256:$src), sub_ss)), sub_xmm)>;
468   def : Pat<(v8i32 (X86vzmovl (v8i32 VR256:$src))),
469             (SUBREG_TO_REG (i32 0),
470               (VMOVSSrr (v4i32 (V_SET0)),
471                         (EXTRACT_SUBREG (v8i32 VR256:$src), sub_ss)), sub_xmm)>;
472   }
473
474   let AddedComplexity = 20 in {
475   // MOVSSrm zeros the high parts of the register; represent this
476   // with SUBREG_TO_REG. The AVX versions also write: DST[255:128] <- 0
477   def : Pat<(v4f32 (X86vzmovl (v4f32 (scalar_to_vector (loadf32 addr:$src))))),
478             (SUBREG_TO_REG (i32 0), (VMOVSSrm addr:$src), sub_ss)>;
479   def : Pat<(v4f32 (scalar_to_vector (loadf32 addr:$src))),
480             (SUBREG_TO_REG (i32 0), (VMOVSSrm addr:$src), sub_ss)>;
481   def : Pat<(v4f32 (X86vzmovl (loadv4f32 addr:$src))),
482             (SUBREG_TO_REG (i32 0), (VMOVSSrm addr:$src), sub_ss)>;
483
484   // MOVSDrm zeros the high parts of the register; represent this
485   // with SUBREG_TO_REG. The AVX versions also write: DST[255:128] <- 0
486   def : Pat<(v2f64 (X86vzmovl (v2f64 (scalar_to_vector (loadf64 addr:$src))))),
487             (SUBREG_TO_REG (i64 0), (VMOVSDrm addr:$src), sub_sd)>;
488   def : Pat<(v2f64 (scalar_to_vector (loadf64 addr:$src))),
489             (SUBREG_TO_REG (i64 0), (VMOVSDrm addr:$src), sub_sd)>;
490   def : Pat<(v2f64 (X86vzmovl (loadv2f64 addr:$src))),
491             (SUBREG_TO_REG (i64 0), (VMOVSDrm addr:$src), sub_sd)>;
492   def : Pat<(v2f64 (X86vzmovl (bc_v2f64 (loadv4f32 addr:$src)))),
493             (SUBREG_TO_REG (i64 0), (VMOVSDrm addr:$src), sub_sd)>;
494   def : Pat<(v2f64 (X86vzload addr:$src)),
495             (SUBREG_TO_REG (i64 0), (VMOVSDrm addr:$src), sub_sd)>;
496
497   // Represent the same patterns above but in the form they appear for
498   // 256-bit types
499   def : Pat<(v8i32 (X86vzmovl (insert_subvector undef,
500                    (v4i32 (scalar_to_vector (loadi32 addr:$src))), (i32 0)))),
501             (SUBREG_TO_REG (i32 0), (VMOVSSrm addr:$src), sub_ss)>;
502   def : Pat<(v8f32 (X86vzmovl (insert_subvector undef,
503                    (v4f32 (scalar_to_vector (loadf32 addr:$src))), (i32 0)))),
504             (SUBREG_TO_REG (i32 0), (VMOVSSrm addr:$src), sub_ss)>;
505   def : Pat<(v4f64 (X86vzmovl (insert_subvector undef,
506                    (v2f64 (scalar_to_vector (loadf64 addr:$src))), (i32 0)))),
507             (SUBREG_TO_REG (i32 0), (VMOVSDrm addr:$src), sub_sd)>;
508   }
509   def : Pat<(v8f32 (X86vzmovl (insert_subvector undef,
510                    (v4f32 (scalar_to_vector FR32:$src)), (i32 0)))),
511             (SUBREG_TO_REG (i32 0),
512                            (v4f32 (VMOVSSrr (v4f32 (V_SET0)), FR32:$src)),
513                            sub_xmm)>;
514   def : Pat<(v4f64 (X86vzmovl (insert_subvector undef,
515                    (v2f64 (scalar_to_vector FR64:$src)), (i32 0)))),
516             (SUBREG_TO_REG (i64 0),
517                            (v2f64 (VMOVSDrr (v2f64 (V_SET0)), FR64:$src)),
518                            sub_xmm)>;
519   def : Pat<(v4i64 (X86vzmovl (insert_subvector undef,
520                    (v2i64 (scalar_to_vector (loadi64 addr:$src))), (i32 0)))),
521             (SUBREG_TO_REG (i64 0), (VMOVSDrm addr:$src), sub_sd)>;
522
523   // Move low f64 and clear high bits.
524   def : Pat<(v4f64 (X86vzmovl (v4f64 VR256:$src))),
525             (SUBREG_TO_REG (i32 0),
526               (VMOVSDrr (v2f64 (V_SET0)),
527                         (EXTRACT_SUBREG (v4f64 VR256:$src), sub_sd)), sub_xmm)>;
528
529   def : Pat<(v4i64 (X86vzmovl (v4i64 VR256:$src))),
530             (SUBREG_TO_REG (i32 0),
531               (VMOVSDrr (v2i64 (V_SET0)),
532                         (EXTRACT_SUBREG (v4i64 VR256:$src), sub_sd)), sub_xmm)>;
533
534 // Extract and store.
535   def : Pat<(store (f32 (vector_extract (v4f32 VR128:$src), (iPTR 0))),
536                    addr:$dst),
537             (VMOVSSmr addr:$dst,
538                      (EXTRACT_SUBREG (v4f32 VR128:$src), sub_ss))>;
539   def : Pat<(store (f64 (vector_extract (v2f64 VR128:$src), (iPTR 0))),
540                    addr:$dst),
541             (VMOVSDmr addr:$dst,
542                      (EXTRACT_SUBREG (v2f64 VR128:$src), sub_sd))>;
543
544   // Shuffle with VMOVSS
545   def : Pat<(v4f32 (X86Movss VR128:$src1, (scalar_to_vector FR32:$src2))),
546             (VMOVSSrr VR128:$src1, FR32:$src2)>;
547   def : Pat<(v4i32 (X86Movss VR128:$src1, VR128:$src2)),
548             (VMOVSSrr (v4i32 VR128:$src1),
549                       (EXTRACT_SUBREG (v4i32 VR128:$src2), sub_ss))>;
550   def : Pat<(v4f32 (X86Movss VR128:$src1, VR128:$src2)),
551             (VMOVSSrr (v4f32 VR128:$src1),
552                       (EXTRACT_SUBREG (v4f32 VR128:$src2), sub_ss))>;
553
554   // 256-bit variants
555   def : Pat<(v8i32 (X86Movss VR256:$src1, VR256:$src2)),
556             (SUBREG_TO_REG (i32 0),
557                 (VMOVSSrr (EXTRACT_SUBREG (v8i32 VR256:$src1), sub_ss),
558                           (EXTRACT_SUBREG (v8i32 VR256:$src2), sub_ss)), sub_xmm)>;
559   def : Pat<(v8f32 (X86Movss VR256:$src1, VR256:$src2)),
560             (SUBREG_TO_REG (i32 0),
561                 (VMOVSSrr (EXTRACT_SUBREG (v8f32 VR256:$src1), sub_ss),
562                           (EXTRACT_SUBREG (v8f32 VR256:$src2), sub_ss)), sub_xmm)>;
563
564   // Shuffle with VMOVSD
565   def : Pat<(v2f64 (X86Movsd VR128:$src1, (scalar_to_vector FR64:$src2))),
566             (VMOVSDrr VR128:$src1, FR64:$src2)>;
567   def : Pat<(v2i64 (X86Movsd VR128:$src1, VR128:$src2)),
568             (VMOVSDrr (v2i64 VR128:$src1),
569                      (EXTRACT_SUBREG (v2i64 VR128:$src2), sub_sd))>;
570   def : Pat<(v2f64 (X86Movsd VR128:$src1, VR128:$src2)),
571             (VMOVSDrr (v2f64 VR128:$src1),
572                      (EXTRACT_SUBREG (v2f64 VR128:$src2), sub_sd))>;
573   def : Pat<(v4f32 (X86Movsd VR128:$src1, VR128:$src2)),
574             (VMOVSDrr VR128:$src1, (EXTRACT_SUBREG (v4f32 VR128:$src2),
575                                                    sub_sd))>;
576   def : Pat<(v4i32 (X86Movsd VR128:$src1, VR128:$src2)),
577             (VMOVSDrr VR128:$src1, (EXTRACT_SUBREG (v4i32 VR128:$src2),
578                                                    sub_sd))>;
579
580   // 256-bit variants
581   def : Pat<(v4i64 (X86Movsd VR256:$src1, VR256:$src2)),
582             (SUBREG_TO_REG (i32 0),
583                 (VMOVSDrr (EXTRACT_SUBREG (v4i64 VR256:$src1), sub_sd),
584                           (EXTRACT_SUBREG (v4i64 VR256:$src2), sub_sd)), sub_xmm)>;
585   def : Pat<(v4f64 (X86Movsd VR256:$src1, VR256:$src2)),
586             (SUBREG_TO_REG (i32 0),
587                 (VMOVSDrr (EXTRACT_SUBREG (v4f64 VR256:$src1), sub_sd),
588                           (EXTRACT_SUBREG (v4f64 VR256:$src2), sub_sd)), sub_xmm)>;
589
590
591   // FIXME: Instead of a X86Movlps there should be a X86Movsd here, the problem
592   // is during lowering, where it's not possible to recognize the fold cause
593   // it has two uses through a bitcast. One use disappears at isel time and the
594   // fold opportunity reappears.
595   def : Pat<(v2f64 (X86Movlpd VR128:$src1, VR128:$src2)),
596             (VMOVSDrr VR128:$src1, (EXTRACT_SUBREG (v2f64 VR128:$src2),
597                                                    sub_sd))>;
598   def : Pat<(v2i64 (X86Movlpd VR128:$src1, VR128:$src2)),
599             (VMOVSDrr VR128:$src1, (EXTRACT_SUBREG (v2i64 VR128:$src2),
600                                                    sub_sd))>;
601   def : Pat<(v4f32 (X86Movlps VR128:$src1, VR128:$src2)),
602             (VMOVSDrr VR128:$src1, (EXTRACT_SUBREG (v4f32 VR128:$src2),
603                                                    sub_sd))>;
604   def : Pat<(v4i32 (X86Movlps VR128:$src1, VR128:$src2)),
605             (VMOVSDrr VR128:$src1, (EXTRACT_SUBREG (v4i32 VR128:$src2),
606                                                    sub_sd))>;
607 }
608
609 let Predicates = [HasSSE1] in {
610   let AddedComplexity = 15 in {
611   // Extract the low 32-bit value from one vector and insert it into another.
612   def : Pat<(v4f32 (movl VR128:$src1, VR128:$src2)),
613             (MOVSSrr (v4f32 VR128:$src1),
614                      (EXTRACT_SUBREG (v4f32 VR128:$src2), sub_ss))>;
615   def : Pat<(v4i32 (movl VR128:$src1, VR128:$src2)),
616             (MOVSSrr (v4i32 VR128:$src1),
617                      (EXTRACT_SUBREG (v4i32 VR128:$src2), sub_ss))>;
618
619   // Move scalar to XMM zero-extended, zeroing a VR128 then do a
620   // MOVSS to the lower bits.
621   def : Pat<(v4f32 (X86vzmovl (v4f32 (scalar_to_vector FR32:$src)))),
622             (MOVSSrr (v4f32 (V_SET0)), FR32:$src)>;
623   def : Pat<(v4f32 (X86vzmovl (v4f32 VR128:$src))),
624             (MOVSSrr (v4f32 (V_SET0)),
625                      (f32 (EXTRACT_SUBREG (v4f32 VR128:$src), sub_ss)))>;
626   def : Pat<(v4i32 (X86vzmovl (v4i32 VR128:$src))),
627             (MOVSSrr (v4i32 (V_SET0)),
628                      (EXTRACT_SUBREG (v4i32 VR128:$src), sub_ss))>;
629   }
630
631   let AddedComplexity = 20 in {
632   // MOVSSrm zeros the high parts of the register; represent this
633   // with SUBREG_TO_REG.
634   def : Pat<(v4f32 (X86vzmovl (v4f32 (scalar_to_vector (loadf32 addr:$src))))),
635             (SUBREG_TO_REG (i32 0), (MOVSSrm addr:$src), sub_ss)>;
636   def : Pat<(v4f32 (scalar_to_vector (loadf32 addr:$src))),
637             (SUBREG_TO_REG (i32 0), (MOVSSrm addr:$src), sub_ss)>;
638   def : Pat<(v4f32 (X86vzmovl (loadv4f32 addr:$src))),
639             (SUBREG_TO_REG (i32 0), (MOVSSrm addr:$src), sub_ss)>;
640   }
641
642   // Extract and store.
643   def : Pat<(store (f32 (vector_extract (v4f32 VR128:$src), (iPTR 0))),
644                    addr:$dst),
645             (MOVSSmr addr:$dst,
646                      (EXTRACT_SUBREG (v4f32 VR128:$src), sub_ss))>;
647
648   // Shuffle with MOVSS
649   def : Pat<(v4f32 (X86Movss VR128:$src1, (scalar_to_vector FR32:$src2))),
650             (MOVSSrr VR128:$src1, FR32:$src2)>;
651   def : Pat<(v4i32 (X86Movss VR128:$src1, VR128:$src2)),
652             (MOVSSrr (v4i32 VR128:$src1),
653                      (EXTRACT_SUBREG (v4i32 VR128:$src2), sub_ss))>;
654   def : Pat<(v4f32 (X86Movss VR128:$src1, VR128:$src2)),
655             (MOVSSrr (v4f32 VR128:$src1),
656                      (EXTRACT_SUBREG (v4f32 VR128:$src2), sub_ss))>;
657 }
658
659 let Predicates = [HasSSE2] in {
660   let AddedComplexity = 15 in {
661   // Extract the low 64-bit value from one vector and insert it into another.
662   def : Pat<(v2f64 (movl VR128:$src1, VR128:$src2)),
663             (MOVSDrr (v2f64 VR128:$src1),
664                      (EXTRACT_SUBREG (v2f64 VR128:$src2), sub_sd))>;
665   def : Pat<(v2i64 (movl VR128:$src1, VR128:$src2)),
666             (MOVSDrr (v2i64 VR128:$src1),
667                      (EXTRACT_SUBREG (v2i64 VR128:$src2), sub_sd))>;
668
669   // vector_shuffle v1, v2 <4, 5, 2, 3> using movsd
670   def : Pat<(v4f32 (movlp VR128:$src1, VR128:$src2)),
671             (MOVSDrr VR128:$src1, (EXTRACT_SUBREG VR128:$src2, sub_sd))>;
672   def : Pat<(v4i32 (movlp VR128:$src1, VR128:$src2)),
673             (MOVSDrr VR128:$src1, (EXTRACT_SUBREG VR128:$src2, sub_sd))>;
674
675   // Move scalar to XMM zero-extended, zeroing a VR128 then do a
676   // MOVSD to the lower bits.
677   def : Pat<(v2f64 (X86vzmovl (v2f64 (scalar_to_vector FR64:$src)))),
678             (MOVSDrr (v2f64 (V_SET0)), FR64:$src)>;
679   }
680
681   let AddedComplexity = 20 in {
682   // MOVSDrm zeros the high parts of the register; represent this
683   // with SUBREG_TO_REG.
684   def : Pat<(v2f64 (X86vzmovl (v2f64 (scalar_to_vector (loadf64 addr:$src))))),
685             (SUBREG_TO_REG (i64 0), (MOVSDrm addr:$src), sub_sd)>;
686   def : Pat<(v2f64 (scalar_to_vector (loadf64 addr:$src))),
687             (SUBREG_TO_REG (i64 0), (MOVSDrm addr:$src), sub_sd)>;
688   def : Pat<(v2f64 (X86vzmovl (loadv2f64 addr:$src))),
689             (SUBREG_TO_REG (i64 0), (MOVSDrm addr:$src), sub_sd)>;
690   def : Pat<(v2f64 (X86vzmovl (bc_v2f64 (loadv4f32 addr:$src)))),
691             (SUBREG_TO_REG (i64 0), (MOVSDrm addr:$src), sub_sd)>;
692   def : Pat<(v2f64 (X86vzload addr:$src)),
693             (SUBREG_TO_REG (i64 0), (MOVSDrm addr:$src), sub_sd)>;
694   }
695
696   // Extract and store.
697   def : Pat<(store (f64 (vector_extract (v2f64 VR128:$src), (iPTR 0))),
698                    addr:$dst),
699             (MOVSDmr addr:$dst,
700                      (EXTRACT_SUBREG (v2f64 VR128:$src), sub_sd))>;
701
702   // Shuffle with MOVSD
703   def : Pat<(v2f64 (X86Movsd VR128:$src1, (scalar_to_vector FR64:$src2))),
704             (MOVSDrr VR128:$src1, FR64:$src2)>;
705   def : Pat<(v2i64 (X86Movsd VR128:$src1, VR128:$src2)),
706             (MOVSDrr (v2i64 VR128:$src1),
707                      (EXTRACT_SUBREG (v2i64 VR128:$src2), sub_sd))>;
708   def : Pat<(v2f64 (X86Movsd VR128:$src1, VR128:$src2)),
709             (MOVSDrr (v2f64 VR128:$src1),
710                      (EXTRACT_SUBREG (v2f64 VR128:$src2), sub_sd))>;
711   def : Pat<(v4f32 (X86Movsd VR128:$src1, VR128:$src2)),
712             (MOVSDrr VR128:$src1, (EXTRACT_SUBREG (v4f32 VR128:$src2),sub_sd))>;
713   def : Pat<(v4i32 (X86Movsd VR128:$src1, VR128:$src2)),
714             (MOVSDrr VR128:$src1, (EXTRACT_SUBREG (v4i32 VR128:$src2),sub_sd))>;
715
716   // FIXME: Instead of a X86Movlps there should be a X86Movsd here, the problem
717   // is during lowering, where it's not possible to recognize the fold cause
718   // it has two uses through a bitcast. One use disappears at isel time and the
719   // fold opportunity reappears.
720   def : Pat<(v2f64 (X86Movlpd VR128:$src1, VR128:$src2)),
721             (MOVSDrr VR128:$src1, (EXTRACT_SUBREG (v2f64 VR128:$src2),sub_sd))>;
722   def : Pat<(v2i64 (X86Movlpd VR128:$src1, VR128:$src2)),
723             (MOVSDrr VR128:$src1, (EXTRACT_SUBREG (v2i64 VR128:$src2),sub_sd))>;
724   def : Pat<(v4f32 (X86Movlps VR128:$src1, VR128:$src2)),
725             (MOVSDrr VR128:$src1, (EXTRACT_SUBREG (v4f32 VR128:$src2),sub_sd))>;
726   def : Pat<(v4i32 (X86Movlps VR128:$src1, VR128:$src2)),
727             (MOVSDrr VR128:$src1, (EXTRACT_SUBREG (v4i32 VR128:$src2),sub_sd))>;
728 }
729
730 //===----------------------------------------------------------------------===//
731 // SSE 1 & 2 - Move Aligned/Unaligned FP Instructions
732 //===----------------------------------------------------------------------===//
733
734 multiclass sse12_mov_packed<bits<8> opc, RegisterClass RC,
735                             X86MemOperand x86memop, PatFrag ld_frag,
736                             string asm, Domain d,
737                             bit IsReMaterializable = 1> {
738 let neverHasSideEffects = 1 in
739   def rr : PI<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src),
740               !strconcat(asm, "\t{$src, $dst|$dst, $src}"), [], d>;
741 let canFoldAsLoad = 1, isReMaterializable = IsReMaterializable in
742   def rm : PI<opc, MRMSrcMem, (outs RC:$dst), (ins x86memop:$src),
743               !strconcat(asm, "\t{$src, $dst|$dst, $src}"),
744                    [(set RC:$dst, (ld_frag addr:$src))], d>;
745 }
746
747 defm VMOVAPS : sse12_mov_packed<0x28, VR128, f128mem, alignedloadv4f32,
748                               "movaps", SSEPackedSingle>, TB, VEX;
749 defm VMOVAPD : sse12_mov_packed<0x28, VR128, f128mem, alignedloadv2f64,
750                               "movapd", SSEPackedDouble>, TB, OpSize, VEX;
751 defm VMOVUPS : sse12_mov_packed<0x10, VR128, f128mem, loadv4f32,
752                               "movups", SSEPackedSingle>, TB, VEX;
753 defm VMOVUPD : sse12_mov_packed<0x10, VR128, f128mem, loadv2f64,
754                               "movupd", SSEPackedDouble, 0>, TB, OpSize, VEX;
755
756 defm VMOVAPSY : sse12_mov_packed<0x28, VR256, f256mem, alignedloadv8f32,
757                               "movaps", SSEPackedSingle>, TB, VEX;
758 defm VMOVAPDY : sse12_mov_packed<0x28, VR256, f256mem, alignedloadv4f64,
759                               "movapd", SSEPackedDouble>, TB, OpSize, VEX;
760 defm VMOVUPSY : sse12_mov_packed<0x10, VR256, f256mem, loadv8f32,
761                               "movups", SSEPackedSingle>, TB, VEX;
762 defm VMOVUPDY : sse12_mov_packed<0x10, VR256, f256mem, loadv4f64,
763                               "movupd", SSEPackedDouble, 0>, TB, OpSize, VEX;
764 defm MOVAPS : sse12_mov_packed<0x28, VR128, f128mem, alignedloadv4f32,
765                               "movaps", SSEPackedSingle>, TB;
766 defm MOVAPD : sse12_mov_packed<0x28, VR128, f128mem, alignedloadv2f64,
767                               "movapd", SSEPackedDouble>, TB, OpSize;
768 defm MOVUPS : sse12_mov_packed<0x10, VR128, f128mem, loadv4f32,
769                               "movups", SSEPackedSingle>, TB;
770 defm MOVUPD : sse12_mov_packed<0x10, VR128, f128mem, loadv2f64,
771                               "movupd", SSEPackedDouble, 0>, TB, OpSize;
772
773 def VMOVAPSmr : VPSI<0x29, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
774                    "movaps\t{$src, $dst|$dst, $src}",
775                    [(alignedstore (v4f32 VR128:$src), addr:$dst)]>, VEX;
776 def VMOVAPDmr : VPDI<0x29, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
777                    "movapd\t{$src, $dst|$dst, $src}",
778                    [(alignedstore (v2f64 VR128:$src), addr:$dst)]>, VEX;
779 def VMOVUPSmr : VPSI<0x11, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
780                    "movups\t{$src, $dst|$dst, $src}",
781                    [(store (v4f32 VR128:$src), addr:$dst)]>, VEX;
782 def VMOVUPDmr : VPDI<0x11, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
783                    "movupd\t{$src, $dst|$dst, $src}",
784                    [(store (v2f64 VR128:$src), addr:$dst)]>, VEX;
785 def VMOVAPSYmr : VPSI<0x29, MRMDestMem, (outs), (ins f256mem:$dst, VR256:$src),
786                    "movaps\t{$src, $dst|$dst, $src}",
787                    [(alignedstore256 (v8f32 VR256:$src), addr:$dst)]>, VEX;
788 def VMOVAPDYmr : VPDI<0x29, MRMDestMem, (outs), (ins f256mem:$dst, VR256:$src),
789                    "movapd\t{$src, $dst|$dst, $src}",
790                    [(alignedstore256 (v4f64 VR256:$src), addr:$dst)]>, VEX;
791 def VMOVUPSYmr : VPSI<0x11, MRMDestMem, (outs), (ins f256mem:$dst, VR256:$src),
792                    "movups\t{$src, $dst|$dst, $src}",
793                    [(store (v8f32 VR256:$src), addr:$dst)]>, VEX;
794 def VMOVUPDYmr : VPDI<0x11, MRMDestMem, (outs), (ins f256mem:$dst, VR256:$src),
795                    "movupd\t{$src, $dst|$dst, $src}",
796                    [(store (v4f64 VR256:$src), addr:$dst)]>, VEX;
797
798 // For disassembler
799 let isCodeGenOnly = 1 in {
800   def VMOVAPSrr_REV : VPSI<0x29, MRMDestReg, (outs VR128:$dst),
801                           (ins VR128:$src),
802                           "movaps\t{$src, $dst|$dst, $src}", []>, VEX;
803   def VMOVAPDrr_REV : VPDI<0x29, MRMDestReg, (outs VR128:$dst),
804                            (ins VR128:$src),
805                            "movapd\t{$src, $dst|$dst, $src}", []>, VEX;
806   def VMOVUPSrr_REV : VPSI<0x11, MRMDestReg, (outs VR128:$dst),
807                            (ins VR128:$src),
808                            "movups\t{$src, $dst|$dst, $src}", []>, VEX;
809   def VMOVUPDrr_REV : VPDI<0x11, MRMDestReg, (outs VR128:$dst),
810                            (ins VR128:$src),
811                            "movupd\t{$src, $dst|$dst, $src}", []>, VEX;
812   def VMOVAPSYrr_REV : VPSI<0x29, MRMDestReg, (outs VR256:$dst),
813                             (ins VR256:$src),
814                             "movaps\t{$src, $dst|$dst, $src}", []>, VEX;
815   def VMOVAPDYrr_REV : VPDI<0x29, MRMDestReg, (outs VR256:$dst),
816                             (ins VR256:$src),
817                             "movapd\t{$src, $dst|$dst, $src}", []>, VEX;
818   def VMOVUPSYrr_REV : VPSI<0x11, MRMDestReg, (outs VR256:$dst),
819                             (ins VR256:$src),
820                             "movups\t{$src, $dst|$dst, $src}", []>, VEX;
821   def VMOVUPDYrr_REV : VPDI<0x11, MRMDestReg, (outs VR256:$dst),
822                             (ins VR256:$src),
823                             "movupd\t{$src, $dst|$dst, $src}", []>, VEX;
824 }
825
826 let Predicates = [HasAVX] in {
827 def : Pat<(v8i32 (X86vzmovl
828                         (insert_subvector undef, (v4i32 VR128:$src), (i32 0)))),
829           (SUBREG_TO_REG (i32 0), (VMOVAPSrr VR128:$src), sub_xmm)>;
830 def : Pat<(v4i64 (X86vzmovl
831                         (insert_subvector undef, (v2i64 VR128:$src), (i32 0)))),
832           (SUBREG_TO_REG (i32 0), (VMOVAPSrr VR128:$src), sub_xmm)>;
833 def : Pat<(v8f32 (X86vzmovl
834                         (insert_subvector undef, (v4f32 VR128:$src), (i32 0)))),
835           (SUBREG_TO_REG (i32 0), (VMOVAPSrr VR128:$src), sub_xmm)>;
836 def : Pat<(v4f64 (X86vzmovl
837                         (insert_subvector undef, (v2f64 VR128:$src), (i32 0)))),
838           (SUBREG_TO_REG (i32 0), (VMOVAPSrr VR128:$src), sub_xmm)>;
839 }
840
841
842 def : Pat<(int_x86_avx_storeu_ps_256 addr:$dst, VR256:$src),
843           (VMOVUPSYmr addr:$dst, VR256:$src)>;
844 def : Pat<(int_x86_avx_storeu_pd_256 addr:$dst, VR256:$src),
845           (VMOVUPDYmr addr:$dst, VR256:$src)>;
846
847 def MOVAPSmr : PSI<0x29, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
848                    "movaps\t{$src, $dst|$dst, $src}",
849                    [(alignedstore (v4f32 VR128:$src), addr:$dst)]>;
850 def MOVAPDmr : PDI<0x29, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
851                    "movapd\t{$src, $dst|$dst, $src}",
852                    [(alignedstore (v2f64 VR128:$src), addr:$dst)]>;
853 def MOVUPSmr : PSI<0x11, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
854                    "movups\t{$src, $dst|$dst, $src}",
855                    [(store (v4f32 VR128:$src), addr:$dst)]>;
856 def MOVUPDmr : PDI<0x11, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
857                    "movupd\t{$src, $dst|$dst, $src}",
858                    [(store (v2f64 VR128:$src), addr:$dst)]>;
859
860 // For disassembler
861 let isCodeGenOnly = 1 in {
862   def MOVAPSrr_REV : PSI<0x29, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
863                          "movaps\t{$src, $dst|$dst, $src}", []>;
864   def MOVAPDrr_REV : PDI<0x29, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
865                          "movapd\t{$src, $dst|$dst, $src}", []>;
866   def MOVUPSrr_REV : PSI<0x11, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
867                          "movups\t{$src, $dst|$dst, $src}", []>;
868   def MOVUPDrr_REV : PDI<0x11, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
869                          "movupd\t{$src, $dst|$dst, $src}", []>;
870 }
871
872 let Predicates = [HasAVX] in {
873   def : Pat<(int_x86_sse_storeu_ps addr:$dst, VR128:$src),
874             (VMOVUPSmr addr:$dst, VR128:$src)>;
875   def : Pat<(int_x86_sse2_storeu_pd addr:$dst, VR128:$src),
876             (VMOVUPDmr addr:$dst, VR128:$src)>;
877 }
878
879 let Predicates = [HasSSE1] in
880   def : Pat<(int_x86_sse_storeu_ps addr:$dst, VR128:$src),
881             (MOVUPSmr addr:$dst, VR128:$src)>;
882 let Predicates = [HasSSE2] in
883   def : Pat<(int_x86_sse2_storeu_pd addr:$dst, VR128:$src),
884             (MOVUPDmr addr:$dst, VR128:$src)>;
885
886 // Use vmovaps/vmovups for AVX integer load/store.
887 let Predicates = [HasAVX] in {
888   // 128-bit load/store
889   def : Pat<(alignedloadv2i64 addr:$src),
890             (VMOVAPSrm addr:$src)>;
891   def : Pat<(loadv2i64 addr:$src),
892             (VMOVUPSrm addr:$src)>;
893
894   def : Pat<(alignedstore (v2i64 VR128:$src), addr:$dst),
895             (VMOVAPSmr addr:$dst, VR128:$src)>;
896   def : Pat<(alignedstore (v4i32 VR128:$src), addr:$dst),
897             (VMOVAPSmr addr:$dst, VR128:$src)>;
898   def : Pat<(alignedstore (v8i16 VR128:$src), addr:$dst),
899             (VMOVAPSmr addr:$dst, VR128:$src)>;
900   def : Pat<(alignedstore (v16i8 VR128:$src), addr:$dst),
901             (VMOVAPSmr addr:$dst, VR128:$src)>;
902   def : Pat<(store (v2i64 VR128:$src), addr:$dst),
903             (VMOVUPSmr addr:$dst, VR128:$src)>;
904   def : Pat<(store (v4i32 VR128:$src), addr:$dst),
905             (VMOVUPSmr addr:$dst, VR128:$src)>;
906   def : Pat<(store (v8i16 VR128:$src), addr:$dst),
907             (VMOVUPSmr addr:$dst, VR128:$src)>;
908   def : Pat<(store (v16i8 VR128:$src), addr:$dst),
909             (VMOVUPSmr addr:$dst, VR128:$src)>;
910
911   // 256-bit load/store
912   def : Pat<(alignedloadv4i64 addr:$src),
913             (VMOVAPSYrm addr:$src)>;
914   def : Pat<(loadv4i64 addr:$src),
915             (VMOVUPSYrm addr:$src)>;
916   def : Pat<(alignedstore256 (v4i64 VR256:$src), addr:$dst),
917             (VMOVAPSYmr addr:$dst, VR256:$src)>;
918   def : Pat<(alignedstore256 (v8i32 VR256:$src), addr:$dst),
919             (VMOVAPSYmr addr:$dst, VR256:$src)>;
920   def : Pat<(alignedstore256 (v16i16 VR256:$src), addr:$dst),
921             (VMOVAPSYmr addr:$dst, VR256:$src)>;
922   def : Pat<(alignedstore256 (v32i8 VR256:$src), addr:$dst),
923             (VMOVAPSYmr addr:$dst, VR256:$src)>;
924   def : Pat<(store (v4i64 VR256:$src), addr:$dst),
925             (VMOVUPSYmr addr:$dst, VR256:$src)>;
926   def : Pat<(store (v8i32 VR256:$src), addr:$dst),
927             (VMOVUPSYmr addr:$dst, VR256:$src)>;
928   def : Pat<(store (v16i16 VR256:$src), addr:$dst),
929             (VMOVUPSYmr addr:$dst, VR256:$src)>;
930   def : Pat<(store (v32i8 VR256:$src), addr:$dst),
931             (VMOVUPSYmr addr:$dst, VR256:$src)>;
932 }
933
934 // Use movaps / movups for SSE integer load / store (one byte shorter).
935 // The instructions selected below are then converted to MOVDQA/MOVDQU
936 // during the SSE domain pass.
937 let Predicates = [HasSSE1] in {
938   def : Pat<(alignedloadv2i64 addr:$src),
939             (MOVAPSrm addr:$src)>;
940   def : Pat<(loadv2i64 addr:$src),
941             (MOVUPSrm addr:$src)>;
942
943   def : Pat<(alignedstore (v2i64 VR128:$src), addr:$dst),
944             (MOVAPSmr addr:$dst, VR128:$src)>;
945   def : Pat<(alignedstore (v4i32 VR128:$src), addr:$dst),
946             (MOVAPSmr addr:$dst, VR128:$src)>;
947   def : Pat<(alignedstore (v8i16 VR128:$src), addr:$dst),
948             (MOVAPSmr addr:$dst, VR128:$src)>;
949   def : Pat<(alignedstore (v16i8 VR128:$src), addr:$dst),
950             (MOVAPSmr addr:$dst, VR128:$src)>;
951   def : Pat<(store (v2i64 VR128:$src), addr:$dst),
952             (MOVUPSmr addr:$dst, VR128:$src)>;
953   def : Pat<(store (v4i32 VR128:$src), addr:$dst),
954             (MOVUPSmr addr:$dst, VR128:$src)>;
955   def : Pat<(store (v8i16 VR128:$src), addr:$dst),
956             (MOVUPSmr addr:$dst, VR128:$src)>;
957   def : Pat<(store (v16i8 VR128:$src), addr:$dst),
958             (MOVUPSmr addr:$dst, VR128:$src)>;
959 }
960
961 // Alias instruction to do FR32 or FR64 reg-to-reg copy using movaps. Upper
962 // bits are disregarded. FIXME: Set encoding to pseudo!
963 let neverHasSideEffects = 1 in {
964 def FsVMOVAPSrr : VPSI<0x28, MRMSrcReg, (outs FR32:$dst), (ins FR32:$src),
965                        "movaps\t{$src, $dst|$dst, $src}", []>, VEX;
966 def FsVMOVAPDrr : VPDI<0x28, MRMSrcReg, (outs FR64:$dst), (ins FR64:$src),
967                        "movapd\t{$src, $dst|$dst, $src}", []>, VEX;
968 def FsMOVAPSrr : PSI<0x28, MRMSrcReg, (outs FR32:$dst), (ins FR32:$src),
969                      "movaps\t{$src, $dst|$dst, $src}", []>;
970 def FsMOVAPDrr : PDI<0x28, MRMSrcReg, (outs FR64:$dst), (ins FR64:$src),
971                      "movapd\t{$src, $dst|$dst, $src}", []>;
972 }
973
974 // Alias instruction to load FR32 or FR64 from f128mem using movaps. Upper
975 // bits are disregarded. FIXME: Set encoding to pseudo!
976 let canFoldAsLoad = 1, isReMaterializable = 1 in {
977 let isCodeGenOnly = 1 in {
978   def FsVMOVAPSrm : VPSI<0x28, MRMSrcMem, (outs FR32:$dst), (ins f128mem:$src),
979                          "movaps\t{$src, $dst|$dst, $src}",
980                          [(set FR32:$dst, (alignedloadfsf32 addr:$src))]>, VEX;
981   def FsVMOVAPDrm : VPDI<0x28, MRMSrcMem, (outs FR64:$dst), (ins f128mem:$src),
982                          "movapd\t{$src, $dst|$dst, $src}",
983                          [(set FR64:$dst, (alignedloadfsf64 addr:$src))]>, VEX;
984 }
985 def FsMOVAPSrm : PSI<0x28, MRMSrcMem, (outs FR32:$dst), (ins f128mem:$src),
986                      "movaps\t{$src, $dst|$dst, $src}",
987                      [(set FR32:$dst, (alignedloadfsf32 addr:$src))]>;
988 def FsMOVAPDrm : PDI<0x28, MRMSrcMem, (outs FR64:$dst), (ins f128mem:$src),
989                      "movapd\t{$src, $dst|$dst, $src}",
990                      [(set FR64:$dst, (alignedloadfsf64 addr:$src))]>;
991 }
992
993 //===----------------------------------------------------------------------===//
994 // SSE 1 & 2 - Move Low packed FP Instructions
995 //===----------------------------------------------------------------------===//
996
997 multiclass sse12_mov_hilo_packed<bits<8>opc, RegisterClass RC,
998                                  PatFrag mov_frag, string base_opc,
999                                  string asm_opr> {
1000   def PSrm : PI<opc, MRMSrcMem,
1001          (outs VR128:$dst), (ins VR128:$src1, f64mem:$src2),
1002          !strconcat(base_opc, "s", asm_opr),
1003      [(set RC:$dst,
1004        (mov_frag RC:$src1,
1005               (bc_v4f32 (v2f64 (scalar_to_vector (loadf64 addr:$src2))))))],
1006               SSEPackedSingle>, TB;
1007
1008   def PDrm : PI<opc, MRMSrcMem,
1009          (outs RC:$dst), (ins RC:$src1, f64mem:$src2),
1010          !strconcat(base_opc, "d", asm_opr),
1011      [(set RC:$dst, (v2f64 (mov_frag RC:$src1,
1012                               (scalar_to_vector (loadf64 addr:$src2)))))],
1013               SSEPackedDouble>, TB, OpSize;
1014 }
1015
1016 let AddedComplexity = 20 in {
1017   defm VMOVL : sse12_mov_hilo_packed<0x12, VR128, movlp, "movlp",
1018                      "\t{$src2, $src1, $dst|$dst, $src1, $src2}">, VEX_4V;
1019 }
1020 let Constraints = "$src1 = $dst", AddedComplexity = 20 in {
1021   defm MOVL : sse12_mov_hilo_packed<0x12, VR128, movlp, "movlp",
1022                                    "\t{$src2, $dst|$dst, $src2}">;
1023 }
1024
1025 def VMOVLPSmr : VPSI<0x13, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
1026                    "movlps\t{$src, $dst|$dst, $src}",
1027                    [(store (f64 (vector_extract (bc_v2f64 (v4f32 VR128:$src)),
1028                                  (iPTR 0))), addr:$dst)]>, VEX;
1029 def VMOVLPDmr : VPDI<0x13, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
1030                    "movlpd\t{$src, $dst|$dst, $src}",
1031                    [(store (f64 (vector_extract (v2f64 VR128:$src),
1032                                  (iPTR 0))), addr:$dst)]>, VEX;
1033 def MOVLPSmr : PSI<0x13, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
1034                    "movlps\t{$src, $dst|$dst, $src}",
1035                    [(store (f64 (vector_extract (bc_v2f64 (v4f32 VR128:$src)),
1036                                  (iPTR 0))), addr:$dst)]>;
1037 def MOVLPDmr : PDI<0x13, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
1038                    "movlpd\t{$src, $dst|$dst, $src}",
1039                    [(store (f64 (vector_extract (v2f64 VR128:$src),
1040                                  (iPTR 0))), addr:$dst)]>;
1041
1042 let Predicates = [HasAVX] in {
1043   let AddedComplexity = 20 in {
1044     // vector_shuffle v1, (load v2) <4, 5, 2, 3> using MOVLPS
1045     def : Pat<(v4f32 (movlp VR128:$src1, (load addr:$src2))),
1046               (VMOVLPSrm VR128:$src1, addr:$src2)>;
1047     def : Pat<(v4i32 (movlp VR128:$src1, (load addr:$src2))),
1048               (VMOVLPSrm VR128:$src1, addr:$src2)>;
1049     // vector_shuffle v1, (load v2) <2, 1> using MOVLPS
1050     def : Pat<(v2f64 (movlp VR128:$src1, (load addr:$src2))),
1051               (VMOVLPDrm VR128:$src1, addr:$src2)>;
1052     def : Pat<(v2i64 (movlp VR128:$src1, (load addr:$src2))),
1053               (VMOVLPDrm VR128:$src1, addr:$src2)>;
1054   }
1055
1056   // (store (vector_shuffle (load addr), v2, <4, 5, 2, 3>), addr) using MOVLPS
1057   def : Pat<(store (v4f32 (movlp (load addr:$src1), VR128:$src2)), addr:$src1),
1058             (VMOVLPSmr addr:$src1, VR128:$src2)>;
1059   def : Pat<(store (v4i32 (movlp (bc_v4i32 (loadv2i64 addr:$src1)),
1060                                  VR128:$src2)), addr:$src1),
1061             (VMOVLPSmr addr:$src1, VR128:$src2)>;
1062
1063   // (store (vector_shuffle (load addr), v2, <2, 1>), addr) using MOVLPS
1064   def : Pat<(store (v2f64 (movlp (load addr:$src1), VR128:$src2)), addr:$src1),
1065             (VMOVLPDmr addr:$src1, VR128:$src2)>;
1066   def : Pat<(store (v2i64 (movlp (load addr:$src1), VR128:$src2)), addr:$src1),
1067             (VMOVLPDmr addr:$src1, VR128:$src2)>;
1068
1069   // Shuffle with VMOVLPS
1070   def : Pat<(v4f32 (X86Movlps VR128:$src1, (load addr:$src2))),
1071             (VMOVLPSrm VR128:$src1, addr:$src2)>;
1072   def : Pat<(v4i32 (X86Movlps VR128:$src1, (load addr:$src2))),
1073             (VMOVLPSrm VR128:$src1, addr:$src2)>;
1074   def : Pat<(X86Movlps VR128:$src1,
1075                       (bc_v4f32 (v2f64 (scalar_to_vector (loadf64 addr:$src2))))),
1076             (VMOVLPSrm VR128:$src1, addr:$src2)>;
1077
1078   // Shuffle with VMOVLPD
1079   def : Pat<(v2f64 (X86Movlpd VR128:$src1, (load addr:$src2))),
1080             (VMOVLPDrm VR128:$src1, addr:$src2)>;
1081   def : Pat<(v2i64 (X86Movlpd VR128:$src1, (load addr:$src2))),
1082             (VMOVLPDrm VR128:$src1, addr:$src2)>;
1083   def : Pat<(v2f64 (X86Movlpd VR128:$src1,
1084                               (scalar_to_vector (loadf64 addr:$src2)))),
1085             (VMOVLPDrm VR128:$src1, addr:$src2)>;
1086
1087   // Store patterns
1088   def : Pat<(store (v4f32 (X86Movlps (load addr:$src1), VR128:$src2)),
1089                    addr:$src1),
1090             (VMOVLPSmr addr:$src1, VR128:$src2)>;
1091   def : Pat<(store (v4i32 (X86Movlps
1092                    (bc_v4i32 (loadv2i64 addr:$src1)), VR128:$src2)), addr:$src1),
1093             (VMOVLPSmr addr:$src1, VR128:$src2)>;
1094   def : Pat<(store (v2f64 (X86Movlpd (load addr:$src1), VR128:$src2)),
1095                    addr:$src1),
1096             (VMOVLPDmr addr:$src1, VR128:$src2)>;
1097   def : Pat<(store (v2i64 (X86Movlpd (load addr:$src1), VR128:$src2)),
1098                    addr:$src1),
1099             (VMOVLPDmr addr:$src1, VR128:$src2)>;
1100 }
1101
1102 let Predicates = [HasSSE1] in {
1103   let AddedComplexity = 20 in {
1104     // vector_shuffle v1, (load v2) <4, 5, 2, 3> using MOVLPS
1105     def : Pat<(v4f32 (movlp VR128:$src1, (load addr:$src2))),
1106               (MOVLPSrm VR128:$src1, addr:$src2)>;
1107     def : Pat<(v4i32 (movlp VR128:$src1, (load addr:$src2))),
1108               (MOVLPSrm VR128:$src1, addr:$src2)>;
1109   }
1110
1111   // (store (vector_shuffle (load addr), v2, <4, 5, 2, 3>), addr) using MOVLPS
1112   def : Pat<(store (i64 (vector_extract (bc_v2i64 (v4f32 VR128:$src2)),
1113                                  (iPTR 0))), addr:$src1),
1114             (MOVLPSmr addr:$src1, VR128:$src2)>;
1115   def : Pat<(store (v4f32 (movlp (load addr:$src1), VR128:$src2)), addr:$src1),
1116             (MOVLPSmr addr:$src1, VR128:$src2)>;
1117   def : Pat<(store (v4i32 (movlp (bc_v4i32 (loadv2i64 addr:$src1)),
1118                                  VR128:$src2)), addr:$src1),
1119             (MOVLPSmr addr:$src1, VR128:$src2)>;
1120
1121   // Shuffle with MOVLPS
1122   def : Pat<(v4f32 (X86Movlps VR128:$src1, (load addr:$src2))),
1123             (MOVLPSrm VR128:$src1, addr:$src2)>;
1124   def : Pat<(v4i32 (X86Movlps VR128:$src1, (load addr:$src2))),
1125             (MOVLPSrm VR128:$src1, addr:$src2)>;
1126   def : Pat<(X86Movlps VR128:$src1,
1127                       (bc_v4f32 (v2f64 (scalar_to_vector (loadf64 addr:$src2))))),
1128             (MOVLPSrm VR128:$src1, addr:$src2)>;
1129   def : Pat<(X86Movlps VR128:$src1,
1130                       (bc_v4f32 (v2i64 (scalar_to_vector (loadi64 addr:$src2))))),
1131             (MOVLPSrm VR128:$src1, addr:$src2)>;
1132
1133   // Store patterns
1134   def : Pat<(store (v4f32 (X86Movlps (load addr:$src1), VR128:$src2)),
1135                                       addr:$src1),
1136             (MOVLPSmr addr:$src1, VR128:$src2)>;
1137   def : Pat<(store (v4i32 (X86Movlps
1138                    (bc_v4i32 (loadv2i64 addr:$src1)), VR128:$src2)),
1139                               addr:$src1),
1140             (MOVLPSmr addr:$src1, VR128:$src2)>;
1141 }
1142
1143 let Predicates = [HasSSE2] in {
1144   let AddedComplexity = 20 in {
1145     // vector_shuffle v1, (load v2) <2, 1> using MOVLPS
1146     def : Pat<(v2f64 (movlp VR128:$src1, (load addr:$src2))),
1147               (MOVLPDrm VR128:$src1, addr:$src2)>;
1148     def : Pat<(v2i64 (movlp VR128:$src1, (load addr:$src2))),
1149               (MOVLPDrm VR128:$src1, addr:$src2)>;
1150   }
1151
1152   // (store (vector_shuffle (load addr), v2, <2, 1>), addr) using MOVLPS
1153   def : Pat<(store (v2f64 (movlp (load addr:$src1), VR128:$src2)), addr:$src1),
1154             (MOVLPDmr addr:$src1, VR128:$src2)>;
1155   def : Pat<(store (v2i64 (movlp (load addr:$src1), VR128:$src2)), addr:$src1),
1156             (MOVLPDmr addr:$src1, VR128:$src2)>;
1157
1158   // Shuffle with MOVLPD
1159   def : Pat<(v2f64 (X86Movlpd VR128:$src1, (load addr:$src2))),
1160             (MOVLPDrm VR128:$src1, addr:$src2)>;
1161   def : Pat<(v2i64 (X86Movlpd VR128:$src1, (load addr:$src2))),
1162             (MOVLPDrm VR128:$src1, addr:$src2)>;
1163   def : Pat<(v2f64 (X86Movlpd VR128:$src1,
1164                               (scalar_to_vector (loadf64 addr:$src2)))),
1165             (MOVLPDrm VR128:$src1, addr:$src2)>;
1166
1167   // Store patterns
1168   def : Pat<(store (v2f64 (X86Movlpd (load addr:$src1), VR128:$src2)),
1169                            addr:$src1),
1170             (MOVLPDmr addr:$src1, VR128:$src2)>;
1171   def : Pat<(store (v2i64 (X86Movlpd (load addr:$src1), VR128:$src2)),
1172                            addr:$src1),
1173             (MOVLPDmr addr:$src1, VR128:$src2)>;
1174 }
1175
1176 //===----------------------------------------------------------------------===//
1177 // SSE 1 & 2 - Move Hi packed FP Instructions
1178 //===----------------------------------------------------------------------===//
1179
1180 let AddedComplexity = 20 in {
1181   defm VMOVH : sse12_mov_hilo_packed<0x16, VR128, movlhps, "movhp",
1182                      "\t{$src2, $src1, $dst|$dst, $src1, $src2}">, VEX_4V;
1183 }
1184 let Constraints = "$src1 = $dst", AddedComplexity = 20 in {
1185   defm MOVH : sse12_mov_hilo_packed<0x16, VR128, movlhps, "movhp",
1186                                    "\t{$src2, $dst|$dst, $src2}">;
1187 }
1188
1189 // v2f64 extract element 1 is always custom lowered to unpack high to low
1190 // and extract element 0 so the non-store version isn't too horrible.
1191 def VMOVHPSmr : VPSI<0x17, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
1192                    "movhps\t{$src, $dst|$dst, $src}",
1193                    [(store (f64 (vector_extract
1194                                  (unpckh (bc_v2f64 (v4f32 VR128:$src)),
1195                                          (undef)), (iPTR 0))), addr:$dst)]>,
1196                    VEX;
1197 def VMOVHPDmr : VPDI<0x17, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
1198                    "movhpd\t{$src, $dst|$dst, $src}",
1199                    [(store (f64 (vector_extract
1200                                  (v2f64 (unpckh VR128:$src, (undef))),
1201                                  (iPTR 0))), addr:$dst)]>,
1202                    VEX;
1203 def MOVHPSmr : PSI<0x17, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
1204                    "movhps\t{$src, $dst|$dst, $src}",
1205                    [(store (f64 (vector_extract
1206                                  (unpckh (bc_v2f64 (v4f32 VR128:$src)),
1207                                          (undef)), (iPTR 0))), addr:$dst)]>;
1208 def MOVHPDmr : PDI<0x17, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
1209                    "movhpd\t{$src, $dst|$dst, $src}",
1210                    [(store (f64 (vector_extract
1211                                  (v2f64 (unpckh VR128:$src, (undef))),
1212                                  (iPTR 0))), addr:$dst)]>;
1213
1214 let Predicates = [HasAVX] in {
1215   // VMOVHPS patterns
1216   def : Pat<(movlhps VR128:$src1, (bc_v4i32 (v2i64 (X86vzload addr:$src2)))),
1217             (VMOVHPSrm (v4i32 VR128:$src1), addr:$src2)>;
1218   def : Pat<(X86Movlhps VR128:$src1,
1219                  (bc_v4f32 (v2f64 (scalar_to_vector (loadf64 addr:$src2))))),
1220             (VMOVHPSrm VR128:$src1, addr:$src2)>;
1221   def : Pat<(X86Movlhps VR128:$src1,
1222                  (bc_v4f32 (v2i64 (scalar_to_vector (loadi64 addr:$src2))))),
1223             (VMOVHPSrm VR128:$src1, addr:$src2)>;
1224   def : Pat<(X86Movlhps VR128:$src1,
1225                  (bc_v4i32 (v2i64 (X86vzload addr:$src2)))),
1226             (VMOVHPSrm VR128:$src1, addr:$src2)>;
1227
1228   // FIXME: Instead of X86Unpckl, there should be a X86Movlhpd here, the problem
1229   // is during lowering, where it's not possible to recognize the load fold 
1230   // cause it has two uses through a bitcast. One use disappears at isel time
1231   // and the fold opportunity reappears.
1232   def : Pat<(v2f64 (X86Unpckl VR128:$src1,
1233                       (scalar_to_vector (loadf64 addr:$src2)))),
1234             (VMOVHPDrm VR128:$src1, addr:$src2)>;
1235
1236   // FIXME: This should be matched by a X86Movhpd instead. Same as above
1237   def : Pat<(v2f64 (X86Movlhpd VR128:$src1,
1238                       (scalar_to_vector (loadf64 addr:$src2)))),
1239             (VMOVHPDrm VR128:$src1, addr:$src2)>;
1240
1241   // Store patterns
1242   def : Pat<(store (f64 (vector_extract
1243             (X86Unpckh (bc_v2f64 (v4f32 VR128:$src)),
1244                        (bc_v2f64 (v4f32 VR128:$src))), (iPTR 0))), addr:$dst),
1245             (VMOVHPSmr addr:$dst, VR128:$src)>;
1246   def : Pat<(store (f64 (vector_extract
1247             (v2f64 (X86Unpckh VR128:$src, VR128:$src)), (iPTR 0))), addr:$dst),
1248             (VMOVHPDmr addr:$dst, VR128:$src)>;
1249 }
1250
1251 let Predicates = [HasSSE1] in {
1252   // MOVHPS patterns
1253   def : Pat<(movlhps VR128:$src1, (bc_v4i32 (v2i64 (X86vzload addr:$src2)))),
1254             (MOVHPSrm (v4i32 VR128:$src1), addr:$src2)>;
1255   def : Pat<(X86Movlhps VR128:$src1,
1256                  (bc_v4f32 (v2f64 (scalar_to_vector (loadf64 addr:$src2))))),
1257             (MOVHPSrm VR128:$src1, addr:$src2)>;
1258   def : Pat<(X86Movlhps VR128:$src1,
1259                  (bc_v4f32 (v2i64 (scalar_to_vector (loadi64 addr:$src2))))),
1260             (MOVHPSrm VR128:$src1, addr:$src2)>;
1261   def : Pat<(X86Movlhps VR128:$src1,
1262                  (bc_v4f32 (v2i64 (X86vzload addr:$src2)))),
1263             (MOVHPSrm VR128:$src1, addr:$src2)>;
1264
1265   // Store patterns
1266   def : Pat<(store (f64 (vector_extract
1267             (X86Unpckh (bc_v2f64 (v4f32 VR128:$src)),
1268                        (bc_v2f64 (v4f32 VR128:$src))), (iPTR 0))), addr:$dst),
1269             (MOVHPSmr addr:$dst, VR128:$src)>;
1270 }
1271
1272 let Predicates = [HasSSE2] in {
1273   // FIXME: Instead of X86Unpckl, there should be a X86Movlhpd here, the problem
1274   // is during lowering, where it's not possible to recognize the load fold 
1275   // cause it has two uses through a bitcast. One use disappears at isel time
1276   // and the fold opportunity reappears.
1277   def : Pat<(v2f64 (X86Unpckl VR128:$src1,
1278                       (scalar_to_vector (loadf64 addr:$src2)))),
1279             (MOVHPDrm VR128:$src1, addr:$src2)>;
1280
1281   // FIXME: This should be matched by a X86Movhpd instead. Same as above
1282   def : Pat<(v2f64 (X86Movlhpd VR128:$src1,
1283                       (scalar_to_vector (loadf64 addr:$src2)))),
1284             (MOVHPDrm VR128:$src1, addr:$src2)>;
1285
1286   // Store patterns
1287   def : Pat<(store (f64 (vector_extract
1288             (v2f64 (X86Unpckh VR128:$src, VR128:$src)), (iPTR 0))),addr:$dst),
1289             (MOVHPDmr addr:$dst, VR128:$src)>;
1290 }
1291
1292 //===----------------------------------------------------------------------===//
1293 // SSE 1 & 2 - Move Low to High and High to Low packed FP Instructions
1294 //===----------------------------------------------------------------------===//
1295
1296 let AddedComplexity = 20 in {
1297   def VMOVLHPSrr : VPSI<0x16, MRMSrcReg, (outs VR128:$dst),
1298                                        (ins VR128:$src1, VR128:$src2),
1299                       "movlhps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1300                       [(set VR128:$dst,
1301                         (v4f32 (movlhps VR128:$src1, VR128:$src2)))]>,
1302                       VEX_4V;
1303   def VMOVHLPSrr : VPSI<0x12, MRMSrcReg, (outs VR128:$dst),
1304                                        (ins VR128:$src1, VR128:$src2),
1305                       "movhlps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1306                       [(set VR128:$dst,
1307                         (v4f32 (movhlps VR128:$src1, VR128:$src2)))]>,
1308                       VEX_4V;
1309 }
1310 let Constraints = "$src1 = $dst", AddedComplexity = 20 in {
1311   def MOVLHPSrr : PSI<0x16, MRMSrcReg, (outs VR128:$dst),
1312                                        (ins VR128:$src1, VR128:$src2),
1313                       "movlhps\t{$src2, $dst|$dst, $src2}",
1314                       [(set VR128:$dst,
1315                         (v4f32 (movlhps VR128:$src1, VR128:$src2)))]>;
1316   def MOVHLPSrr : PSI<0x12, MRMSrcReg, (outs VR128:$dst),
1317                                        (ins VR128:$src1, VR128:$src2),
1318                       "movhlps\t{$src2, $dst|$dst, $src2}",
1319                       [(set VR128:$dst,
1320                         (v4f32 (movhlps VR128:$src1, VR128:$src2)))]>;
1321 }
1322
1323 let Predicates = [HasAVX] in {
1324   // MOVLHPS patterns
1325   let AddedComplexity = 20 in {
1326     def : Pat<(v4f32 (movddup VR128:$src, (undef))),
1327               (VMOVLHPSrr (v4f32 VR128:$src), (v4f32 VR128:$src))>;
1328     def : Pat<(v2i64 (movddup VR128:$src, (undef))),
1329               (VMOVLHPSrr (v2i64 VR128:$src), (v2i64 VR128:$src))>;
1330
1331     // vector_shuffle v1, v2 <0, 1, 4, 5> using MOVLHPS
1332     def : Pat<(v4i32 (movlhps VR128:$src1, VR128:$src2)),
1333               (VMOVLHPSrr VR128:$src1, VR128:$src2)>;
1334   }
1335   def : Pat<(v4f32 (X86Movlhps VR128:$src1, VR128:$src2)),
1336             (VMOVLHPSrr VR128:$src1, VR128:$src2)>;
1337   def : Pat<(v4i32 (X86Movlhps VR128:$src1, VR128:$src2)),
1338             (VMOVLHPSrr VR128:$src1, VR128:$src2)>;
1339   def : Pat<(v2i64 (X86Movlhps VR128:$src1, VR128:$src2)),
1340             (VMOVLHPSrr (v2i64 VR128:$src1), VR128:$src2)>;
1341
1342   // MOVHLPS patterns
1343   let AddedComplexity = 20 in {
1344     // vector_shuffle v1, v2 <6, 7, 2, 3> using MOVHLPS
1345     def : Pat<(v4i32 (movhlps VR128:$src1, VR128:$src2)),
1346               (VMOVHLPSrr VR128:$src1, VR128:$src2)>;
1347
1348     // vector_shuffle v1, undef <2, ?, ?, ?> using MOVHLPS
1349     def : Pat<(v4f32 (movhlps_undef VR128:$src1, (undef))),
1350               (VMOVHLPSrr VR128:$src1, VR128:$src1)>;
1351     def : Pat<(v4i32 (movhlps_undef VR128:$src1, (undef))),
1352               (VMOVHLPSrr VR128:$src1, VR128:$src1)>;
1353   }
1354
1355   def : Pat<(v4f32 (X86Movhlps VR128:$src1, VR128:$src2)),
1356             (VMOVHLPSrr VR128:$src1, VR128:$src2)>;
1357   def : Pat<(v4i32 (X86Movhlps VR128:$src1, VR128:$src2)),
1358             (VMOVHLPSrr VR128:$src1, VR128:$src2)>;
1359 }
1360
1361 let Predicates = [HasSSE1] in {
1362   // MOVLHPS patterns
1363   let AddedComplexity = 20 in {
1364     def : Pat<(v4f32 (movddup VR128:$src, (undef))),
1365               (MOVLHPSrr (v4f32 VR128:$src), (v4f32 VR128:$src))>;
1366     def : Pat<(v2i64 (movddup VR128:$src, (undef))),
1367               (MOVLHPSrr (v2i64 VR128:$src), (v2i64 VR128:$src))>;
1368
1369     // vector_shuffle v1, v2 <0, 1, 4, 5> using MOVLHPS
1370     def : Pat<(v4i32 (movlhps VR128:$src1, VR128:$src2)),
1371               (MOVLHPSrr VR128:$src1, VR128:$src2)>;
1372   }
1373   def : Pat<(v4f32 (X86Movlhps VR128:$src1, VR128:$src2)),
1374             (MOVLHPSrr VR128:$src1, VR128:$src2)>;
1375   def : Pat<(v4i32 (X86Movlhps VR128:$src1, VR128:$src2)),
1376             (MOVLHPSrr VR128:$src1, VR128:$src2)>;
1377   def : Pat<(v2i64 (X86Movlhps VR128:$src1, VR128:$src2)),
1378             (MOVLHPSrr (v2i64 VR128:$src1), VR128:$src2)>;
1379
1380   // MOVHLPS patterns
1381   let AddedComplexity = 20 in {
1382     // vector_shuffle v1, v2 <6, 7, 2, 3> using MOVHLPS
1383     def : Pat<(v4i32 (movhlps VR128:$src1, VR128:$src2)),
1384               (MOVHLPSrr VR128:$src1, VR128:$src2)>;
1385
1386     // vector_shuffle v1, undef <2, ?, ?, ?> using MOVHLPS
1387     def : Pat<(v4f32 (movhlps_undef VR128:$src1, (undef))),
1388               (MOVHLPSrr VR128:$src1, VR128:$src1)>;
1389     def : Pat<(v4i32 (movhlps_undef VR128:$src1, (undef))),
1390               (MOVHLPSrr VR128:$src1, VR128:$src1)>;
1391   }
1392
1393   def : Pat<(v4f32 (X86Movhlps VR128:$src1, VR128:$src2)),
1394             (MOVHLPSrr VR128:$src1, VR128:$src2)>;
1395   def : Pat<(v4i32 (X86Movhlps VR128:$src1, VR128:$src2)),
1396             (MOVHLPSrr VR128:$src1, VR128:$src2)>;
1397 }
1398
1399 //===----------------------------------------------------------------------===//
1400 // SSE 1 & 2 - Conversion Instructions
1401 //===----------------------------------------------------------------------===//
1402
1403 multiclass sse12_cvt_s<bits<8> opc, RegisterClass SrcRC, RegisterClass DstRC,
1404                      SDNode OpNode, X86MemOperand x86memop, PatFrag ld_frag,
1405                      string asm> {
1406   def rr : SI<opc, MRMSrcReg, (outs DstRC:$dst), (ins SrcRC:$src), asm,
1407                         [(set DstRC:$dst, (OpNode SrcRC:$src))]>;
1408   def rm : SI<opc, MRMSrcMem, (outs DstRC:$dst), (ins x86memop:$src), asm,
1409                         [(set DstRC:$dst, (OpNode (ld_frag addr:$src)))]>;
1410 }
1411
1412 multiclass sse12_cvt_p<bits<8> opc, RegisterClass SrcRC, RegisterClass DstRC,
1413                          SDNode OpNode, X86MemOperand x86memop, PatFrag ld_frag,
1414                          string asm, Domain d> {
1415   def rr : PI<opc, MRMSrcReg, (outs DstRC:$dst), (ins SrcRC:$src), asm,
1416                         [(set DstRC:$dst, (OpNode SrcRC:$src))], d>;
1417   def rm : PI<opc, MRMSrcMem, (outs DstRC:$dst), (ins x86memop:$src), asm,
1418                         [(set DstRC:$dst, (OpNode (ld_frag addr:$src)))], d>;
1419 }
1420
1421 multiclass sse12_vcvt_avx<bits<8> opc, RegisterClass SrcRC, RegisterClass DstRC,
1422                           X86MemOperand x86memop, string asm> {
1423 let neverHasSideEffects = 1 in {
1424   def rr : SI<opc, MRMSrcReg, (outs DstRC:$dst), (ins DstRC:$src1, SrcRC:$src),
1425               !strconcat(asm,"\t{$src, $src1, $dst|$dst, $src1, $src}"), []>;
1426   let mayLoad = 1 in
1427   def rm : SI<opc, MRMSrcMem, (outs DstRC:$dst),
1428               (ins DstRC:$src1, x86memop:$src),
1429               !strconcat(asm,"\t{$src, $src1, $dst|$dst, $src1, $src}"), []>;
1430 } // neverHasSideEffects = 1
1431 }
1432
1433 defm VCVTTSS2SI   : sse12_cvt_s<0x2C, FR32, GR32, fp_to_sint, f32mem, loadf32,
1434                                 "cvttss2si\t{$src, $dst|$dst, $src}">, XS, VEX,
1435                                 VEX_LIG;
1436 defm VCVTTSS2SI64 : sse12_cvt_s<0x2C, FR32, GR64, fp_to_sint, f32mem, loadf32,
1437                                 "cvttss2si\t{$src, $dst|$dst, $src}">, XS, VEX,
1438                                 VEX_W, VEX_LIG;
1439 defm VCVTTSD2SI   : sse12_cvt_s<0x2C, FR64, GR32, fp_to_sint, f64mem, loadf64,
1440                                 "cvttsd2si\t{$src, $dst|$dst, $src}">, XD, VEX,
1441                                 VEX_LIG;
1442 defm VCVTTSD2SI64 : sse12_cvt_s<0x2C, FR64, GR64, fp_to_sint, f64mem, loadf64,
1443                                 "cvttsd2si\t{$src, $dst|$dst, $src}">, XD,
1444                                 VEX, VEX_W, VEX_LIG;
1445
1446 // The assembler can recognize rr 64-bit instructions by seeing a rxx
1447 // register, but the same isn't true when only using memory operands,
1448 // provide other assembly "l" and "q" forms to address this explicitly
1449 // where appropriate to do so.
1450 defm VCVTSI2SS   : sse12_vcvt_avx<0x2A, GR32, FR32, i32mem, "cvtsi2ss">, XS,
1451                                   VEX_4V, VEX_LIG;
1452 defm VCVTSI2SS64 : sse12_vcvt_avx<0x2A, GR64, FR32, i64mem, "cvtsi2ss{q}">, XS,
1453                                   VEX_4V, VEX_W, VEX_LIG;
1454 defm VCVTSI2SD   : sse12_vcvt_avx<0x2A, GR32, FR64, i32mem, "cvtsi2sd">, XD,
1455                                   VEX_4V, VEX_LIG;
1456 defm VCVTSI2SDL  : sse12_vcvt_avx<0x2A, GR32, FR64, i32mem, "cvtsi2sd{l}">, XD,
1457                                   VEX_4V, VEX_LIG;
1458 defm VCVTSI2SD64 : sse12_vcvt_avx<0x2A, GR64, FR64, i64mem, "cvtsi2sd{q}">, XD,
1459                                   VEX_4V, VEX_W, VEX_LIG;
1460
1461 let Predicates = [HasAVX], AddedComplexity = 1 in {
1462   def : Pat<(f32 (sint_to_fp (loadi32 addr:$src))),
1463             (VCVTSI2SSrm (f32 (IMPLICIT_DEF)), addr:$src)>;
1464   def : Pat<(f32 (sint_to_fp (loadi64 addr:$src))),
1465             (VCVTSI2SS64rm (f32 (IMPLICIT_DEF)), addr:$src)>;
1466   def : Pat<(f64 (sint_to_fp (loadi32 addr:$src))),
1467             (VCVTSI2SDrm (f64 (IMPLICIT_DEF)), addr:$src)>;
1468   def : Pat<(f64 (sint_to_fp (loadi64 addr:$src))),
1469             (VCVTSI2SD64rm (f64 (IMPLICIT_DEF)), addr:$src)>;
1470
1471   def : Pat<(f32 (sint_to_fp GR32:$src)),
1472             (VCVTSI2SSrr (f32 (IMPLICIT_DEF)), GR32:$src)>;
1473   def : Pat<(f32 (sint_to_fp GR64:$src)),
1474             (VCVTSI2SS64rr (f32 (IMPLICIT_DEF)), GR64:$src)>;
1475   def : Pat<(f64 (sint_to_fp GR32:$src)),
1476             (VCVTSI2SDrr (f64 (IMPLICIT_DEF)), GR32:$src)>;
1477   def : Pat<(f64 (sint_to_fp GR64:$src)),
1478             (VCVTSI2SD64rr (f64 (IMPLICIT_DEF)), GR64:$src)>;
1479 }
1480
1481 defm CVTTSS2SI : sse12_cvt_s<0x2C, FR32, GR32, fp_to_sint, f32mem, loadf32,
1482                       "cvttss2si\t{$src, $dst|$dst, $src}">, XS;
1483 defm CVTTSS2SI64 : sse12_cvt_s<0x2C, FR32, GR64, fp_to_sint, f32mem, loadf32,
1484                       "cvttss2si{q}\t{$src, $dst|$dst, $src}">, XS, REX_W;
1485 defm CVTTSD2SI : sse12_cvt_s<0x2C, FR64, GR32, fp_to_sint, f64mem, loadf64,
1486                       "cvttsd2si\t{$src, $dst|$dst, $src}">, XD;
1487 defm CVTTSD2SI64 : sse12_cvt_s<0x2C, FR64, GR64, fp_to_sint, f64mem, loadf64,
1488                       "cvttsd2si{q}\t{$src, $dst|$dst, $src}">, XD, REX_W;
1489 defm CVTSI2SS  : sse12_cvt_s<0x2A, GR32, FR32, sint_to_fp, i32mem, loadi32,
1490                       "cvtsi2ss\t{$src, $dst|$dst, $src}">, XS;
1491 defm CVTSI2SS64 : sse12_cvt_s<0x2A, GR64, FR32, sint_to_fp, i64mem, loadi64,
1492                       "cvtsi2ss{q}\t{$src, $dst|$dst, $src}">, XS, REX_W;
1493 defm CVTSI2SD  : sse12_cvt_s<0x2A, GR32, FR64, sint_to_fp, i32mem, loadi32,
1494                       "cvtsi2sd\t{$src, $dst|$dst, $src}">, XD;
1495 defm CVTSI2SD64 : sse12_cvt_s<0x2A, GR64, FR64, sint_to_fp, i64mem, loadi64,
1496                       "cvtsi2sd{q}\t{$src, $dst|$dst, $src}">, XD, REX_W;
1497
1498 // Conversion Instructions Intrinsics - Match intrinsics which expect MM
1499 // and/or XMM operand(s).
1500
1501 multiclass sse12_cvt_sint<bits<8> opc, RegisterClass SrcRC, RegisterClass DstRC,
1502                          Intrinsic Int, X86MemOperand x86memop, PatFrag ld_frag,
1503                          string asm> {
1504   def rr : SI<opc, MRMSrcReg, (outs DstRC:$dst), (ins SrcRC:$src),
1505               !strconcat(asm, "\t{$src, $dst|$dst, $src}"),
1506               [(set DstRC:$dst, (Int SrcRC:$src))]>;
1507   def rm : SI<opc, MRMSrcMem, (outs DstRC:$dst), (ins x86memop:$src),
1508               !strconcat(asm, "\t{$src, $dst|$dst, $src}"),
1509               [(set DstRC:$dst, (Int (ld_frag addr:$src)))]>;
1510 }
1511
1512 multiclass sse12_cvt_sint_3addr<bits<8> opc, RegisterClass SrcRC,
1513                     RegisterClass DstRC, Intrinsic Int, X86MemOperand x86memop,
1514                     PatFrag ld_frag, string asm, bit Is2Addr = 1> {
1515   def rr : SI<opc, MRMSrcReg, (outs DstRC:$dst), (ins DstRC:$src1, SrcRC:$src2),
1516               !if(Is2Addr,
1517                   !strconcat(asm, "\t{$src2, $dst|$dst, $src2}"),
1518                   !strconcat(asm, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
1519               [(set DstRC:$dst, (Int DstRC:$src1, SrcRC:$src2))]>;
1520   def rm : SI<opc, MRMSrcMem, (outs DstRC:$dst),
1521               (ins DstRC:$src1, x86memop:$src2),
1522               !if(Is2Addr,
1523                   !strconcat(asm, "\t{$src2, $dst|$dst, $src2}"),
1524                   !strconcat(asm, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
1525               [(set DstRC:$dst, (Int DstRC:$src1, (ld_frag addr:$src2)))]>;
1526 }
1527
1528 defm VCVTSD2SI : sse12_cvt_sint<0x2D, VR128, GR32, int_x86_sse2_cvtsd2si,
1529                   f128mem, load, "cvtsd2si">, XD, VEX, VEX_LIG;
1530 defm VCVTSD2SI64 : sse12_cvt_sint<0x2D, VR128, GR64,
1531                   int_x86_sse2_cvtsd2si64, f128mem, load, "cvtsd2si">,
1532                   XD, VEX, VEX_W, VEX_LIG;
1533
1534 defm CVTSD2SI : sse12_cvt_sint<0x2D, VR128, GR32, int_x86_sse2_cvtsd2si,
1535                 f128mem, load, "cvtsd2si{l}">, XD;
1536 defm CVTSD2SI64 : sse12_cvt_sint<0x2D, VR128, GR64, int_x86_sse2_cvtsd2si64,
1537                   f128mem, load, "cvtsd2si{q}">, XD, REX_W;
1538
1539
1540 defm Int_VCVTSI2SS : sse12_cvt_sint_3addr<0x2A, GR32, VR128,
1541           int_x86_sse_cvtsi2ss, i32mem, loadi32, "cvtsi2ss", 0>, XS, VEX_4V;
1542 defm Int_VCVTSI2SS64 : sse12_cvt_sint_3addr<0x2A, GR64, VR128,
1543           int_x86_sse_cvtsi642ss, i64mem, loadi64, "cvtsi2ss", 0>, XS, VEX_4V,
1544           VEX_W;
1545 defm Int_VCVTSI2SD : sse12_cvt_sint_3addr<0x2A, GR32, VR128,
1546           int_x86_sse2_cvtsi2sd, i32mem, loadi32, "cvtsi2sd", 0>, XD, VEX_4V;
1547 defm Int_VCVTSI2SD64 : sse12_cvt_sint_3addr<0x2A, GR64, VR128,
1548           int_x86_sse2_cvtsi642sd, i64mem, loadi64, "cvtsi2sd", 0>, XD,
1549           VEX_4V, VEX_W;
1550
1551 let Constraints = "$src1 = $dst" in {
1552   defm Int_CVTSI2SS : sse12_cvt_sint_3addr<0x2A, GR32, VR128,
1553                         int_x86_sse_cvtsi2ss, i32mem, loadi32,
1554                         "cvtsi2ss">, XS;
1555   defm Int_CVTSI2SS64 : sse12_cvt_sint_3addr<0x2A, GR64, VR128,
1556                         int_x86_sse_cvtsi642ss, i64mem, loadi64,
1557                         "cvtsi2ss{q}">, XS, REX_W;
1558   defm Int_CVTSI2SD : sse12_cvt_sint_3addr<0x2A, GR32, VR128,
1559                         int_x86_sse2_cvtsi2sd, i32mem, loadi32,
1560                         "cvtsi2sd">, XD;
1561   defm Int_CVTSI2SD64 : sse12_cvt_sint_3addr<0x2A, GR64, VR128,
1562                         int_x86_sse2_cvtsi642sd, i64mem, loadi64,
1563                         "cvtsi2sd">, XD, REX_W;
1564 }
1565
1566 /// SSE 1 Only
1567
1568 // Aliases for intrinsics
1569 defm Int_VCVTTSS2SI : sse12_cvt_sint<0x2C, VR128, GR32, int_x86_sse_cvttss2si,
1570                                     f32mem, load, "cvttss2si">, XS, VEX;
1571 defm Int_VCVTTSS2SI64 : sse12_cvt_sint<0x2C, VR128, GR64,
1572                                     int_x86_sse_cvttss2si64, f32mem, load,
1573                                     "cvttss2si">, XS, VEX, VEX_W;
1574 defm Int_VCVTTSD2SI : sse12_cvt_sint<0x2C, VR128, GR32, int_x86_sse2_cvttsd2si,
1575                                     f128mem, load, "cvttsd2si">, XD, VEX;
1576 defm Int_VCVTTSD2SI64 : sse12_cvt_sint<0x2C, VR128, GR64,
1577                                     int_x86_sse2_cvttsd2si64, f128mem, load,
1578                                     "cvttsd2si">, XD, VEX, VEX_W;
1579 defm Int_CVTTSS2SI : sse12_cvt_sint<0x2C, VR128, GR32, int_x86_sse_cvttss2si,
1580                                     f32mem, load, "cvttss2si">, XS;
1581 defm Int_CVTTSS2SI64 : sse12_cvt_sint<0x2C, VR128, GR64,
1582                                     int_x86_sse_cvttss2si64, f32mem, load,
1583                                     "cvttss2si{q}">, XS, REX_W;
1584 defm Int_CVTTSD2SI : sse12_cvt_sint<0x2C, VR128, GR32, int_x86_sse2_cvttsd2si,
1585                                     f128mem, load, "cvttsd2si">, XD;
1586 defm Int_CVTTSD2SI64 : sse12_cvt_sint<0x2C, VR128, GR64,
1587                                     int_x86_sse2_cvttsd2si64, f128mem, load,
1588                                     "cvttsd2si{q}">, XD, REX_W;
1589
1590 let Pattern = []<dag> in {
1591 defm VCVTSS2SI   : sse12_cvt_s<0x2D, FR32, GR32, undef, f32mem, load,
1592                                "cvtss2si{l}\t{$src, $dst|$dst, $src}">, XS,
1593                                VEX, VEX_LIG;
1594 defm VCVTSS2SI64 : sse12_cvt_s<0x2D, FR32, GR64, undef, f32mem, load,
1595                                "cvtss2si\t{$src, $dst|$dst, $src}">, XS, VEX,
1596                                VEX_W, VEX_LIG;
1597 defm VCVTDQ2PS   : sse12_cvt_p<0x5B, VR128, VR128, undef, i128mem, load,
1598                                "cvtdq2ps\t{$src, $dst|$dst, $src}",
1599                                SSEPackedSingle>, TB, VEX;
1600 defm VCVTDQ2PSY  : sse12_cvt_p<0x5B, VR256, VR256, undef, i256mem, load,
1601                                "cvtdq2ps\t{$src, $dst|$dst, $src}",
1602                                SSEPackedSingle>, TB, VEX;
1603 }
1604
1605 let Pattern = []<dag> in {
1606 defm CVTSS2SI : sse12_cvt_s<0x2D, FR32, GR32, undef, f32mem, load /*dummy*/,
1607                           "cvtss2si{l}\t{$src, $dst|$dst, $src}">, XS;
1608 defm CVTSS2SI64 : sse12_cvt_s<0x2D, FR32, GR64, undef, f32mem, load /*dummy*/,
1609                           "cvtss2si{q}\t{$src, $dst|$dst, $src}">, XS, REX_W;
1610 defm CVTDQ2PS : sse12_cvt_p<0x5B, VR128, VR128, undef, i128mem, load /*dummy*/,
1611                             "cvtdq2ps\t{$src, $dst|$dst, $src}",
1612                             SSEPackedSingle>, TB; /* PD SSE3 form is avaiable */
1613 }
1614
1615 let Predicates = [HasAVX] in {
1616   def : Pat<(int_x86_sse_cvtss2si VR128:$src),
1617             (VCVTSS2SIrr (EXTRACT_SUBREG (v4f32 VR128:$src), sub_ss))>;
1618   def : Pat<(int_x86_sse_cvtss2si (load addr:$src)),
1619             (VCVTSS2SIrm addr:$src)>;
1620   def : Pat<(int_x86_sse_cvtss2si64 VR128:$src),
1621             (VCVTSS2SI64rr (EXTRACT_SUBREG (v4f32 VR128:$src), sub_ss))>;
1622   def : Pat<(int_x86_sse_cvtss2si64 (load addr:$src)),
1623             (VCVTSS2SI64rm addr:$src)>;
1624 }
1625
1626 let Predicates = [HasSSE1] in {
1627   def : Pat<(int_x86_sse_cvtss2si VR128:$src),
1628             (CVTSS2SIrr (EXTRACT_SUBREG (v4f32 VR128:$src), sub_ss))>;
1629   def : Pat<(int_x86_sse_cvtss2si (load addr:$src)),
1630             (CVTSS2SIrm addr:$src)>;
1631   def : Pat<(int_x86_sse_cvtss2si64 VR128:$src),
1632             (CVTSS2SI64rr (EXTRACT_SUBREG (v4f32 VR128:$src), sub_ss))>;
1633   def : Pat<(int_x86_sse_cvtss2si64 (load addr:$src)),
1634             (CVTSS2SI64rm addr:$src)>;
1635 }
1636
1637 /// SSE 2 Only
1638
1639 // Convert scalar double to scalar single
1640 def VCVTSD2SSrr  : VSDI<0x5A, MRMSrcReg, (outs FR32:$dst),
1641                        (ins FR64:$src1, FR64:$src2),
1642                       "cvtsd2ss\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>,
1643                       VEX_4V, VEX_LIG;
1644 let mayLoad = 1 in
1645 def VCVTSD2SSrm  : I<0x5A, MRMSrcMem, (outs FR32:$dst),
1646                        (ins FR64:$src1, f64mem:$src2),
1647                       "vcvtsd2ss\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1648                       []>, XD, Requires<[HasAVX, OptForSize]>, VEX_4V, VEX_LIG;
1649
1650 def : Pat<(f32 (fround FR64:$src)), (VCVTSD2SSrr FR64:$src, FR64:$src)>,
1651           Requires<[HasAVX]>;
1652
1653 def CVTSD2SSrr  : SDI<0x5A, MRMSrcReg, (outs FR32:$dst), (ins FR64:$src),
1654                       "cvtsd2ss\t{$src, $dst|$dst, $src}",
1655                       [(set FR32:$dst, (fround FR64:$src))]>;
1656 def CVTSD2SSrm  : I<0x5A, MRMSrcMem, (outs FR32:$dst), (ins f64mem:$src),
1657                       "cvtsd2ss\t{$src, $dst|$dst, $src}",
1658                       [(set FR32:$dst, (fround (loadf64 addr:$src)))]>, XD,
1659                   Requires<[HasSSE2, OptForSize]>;
1660
1661 defm Int_VCVTSD2SS: sse12_cvt_sint_3addr<0x5A, VR128, VR128,
1662                       int_x86_sse2_cvtsd2ss, f64mem, load, "cvtsd2ss", 0>,
1663                       XS, VEX_4V;
1664 let Constraints = "$src1 = $dst" in
1665 defm Int_CVTSD2SS: sse12_cvt_sint_3addr<0x5A, VR128, VR128,
1666                       int_x86_sse2_cvtsd2ss, f64mem, load, "cvtsd2ss">, XS;
1667
1668 // Convert scalar single to scalar double
1669 // SSE2 instructions with XS prefix
1670 def VCVTSS2SDrr : I<0x5A, MRMSrcReg, (outs FR64:$dst),
1671                     (ins FR32:$src1, FR32:$src2),
1672                     "vcvtss2sd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1673                     []>, XS, Requires<[HasAVX]>, VEX_4V, VEX_LIG;
1674 let mayLoad = 1 in
1675 def VCVTSS2SDrm : I<0x5A, MRMSrcMem, (outs FR64:$dst),
1676                     (ins FR32:$src1, f32mem:$src2),
1677                     "vcvtss2sd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1678                     []>, XS, VEX_4V, VEX_LIG, Requires<[HasAVX, OptForSize]>;
1679
1680 let Predicates = [HasAVX] in {
1681   def : Pat<(f64 (fextend FR32:$src)),
1682             (VCVTSS2SDrr FR32:$src, FR32:$src)>;
1683   def : Pat<(fextend (loadf32 addr:$src)),
1684             (VCVTSS2SDrm (f32 (IMPLICIT_DEF)), addr:$src)>;
1685   def : Pat<(extloadf32 addr:$src),
1686             (VCVTSS2SDrm (f32 (IMPLICIT_DEF)), addr:$src)>;
1687 }
1688
1689 def : Pat<(extloadf32 addr:$src),
1690           (VCVTSS2SDrr (f32 (IMPLICIT_DEF)), (MOVSSrm addr:$src))>,
1691           Requires<[HasAVX, OptForSpeed]>;
1692
1693 def CVTSS2SDrr : I<0x5A, MRMSrcReg, (outs FR64:$dst), (ins FR32:$src),
1694                    "cvtss2sd\t{$src, $dst|$dst, $src}",
1695                    [(set FR64:$dst, (fextend FR32:$src))]>, XS,
1696                  Requires<[HasSSE2]>;
1697 def CVTSS2SDrm : I<0x5A, MRMSrcMem, (outs FR64:$dst), (ins f32mem:$src),
1698                    "cvtss2sd\t{$src, $dst|$dst, $src}",
1699                    [(set FR64:$dst, (extloadf32 addr:$src))]>, XS,
1700                  Requires<[HasSSE2, OptForSize]>;
1701
1702 // extload f32 -> f64.  This matches load+fextend because we have a hack in
1703 // the isel (PreprocessForFPConvert) that can introduce loads after dag
1704 // combine.
1705 // Since these loads aren't folded into the fextend, we have to match it
1706 // explicitly here.
1707 def : Pat<(fextend (loadf32 addr:$src)),
1708           (CVTSS2SDrm addr:$src)>, Requires<[HasSSE2]>;
1709 def : Pat<(extloadf32 addr:$src),
1710           (CVTSS2SDrr (MOVSSrm addr:$src))>, Requires<[HasSSE2, OptForSpeed]>;
1711
1712 def Int_VCVTSS2SDrr: I<0x5A, MRMSrcReg,
1713                       (outs VR128:$dst), (ins VR128:$src1, VR128:$src2),
1714                     "vcvtss2sd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1715                     [(set VR128:$dst, (int_x86_sse2_cvtss2sd VR128:$src1,
1716                                        VR128:$src2))]>, XS, VEX_4V,
1717                     Requires<[HasAVX]>;
1718 def Int_VCVTSS2SDrm: I<0x5A, MRMSrcMem,
1719                       (outs VR128:$dst), (ins VR128:$src1, f32mem:$src2),
1720                     "vcvtss2sd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1721                     [(set VR128:$dst, (int_x86_sse2_cvtss2sd VR128:$src1,
1722                                        (load addr:$src2)))]>, XS, VEX_4V,
1723                     Requires<[HasAVX]>;
1724 let Constraints = "$src1 = $dst" in { // SSE2 instructions with XS prefix
1725 def Int_CVTSS2SDrr: I<0x5A, MRMSrcReg,
1726                       (outs VR128:$dst), (ins VR128:$src1, VR128:$src2),
1727                     "cvtss2sd\t{$src2, $dst|$dst, $src2}",
1728                     [(set VR128:$dst, (int_x86_sse2_cvtss2sd VR128:$src1,
1729                                        VR128:$src2))]>, XS,
1730                     Requires<[HasSSE2]>;
1731 def Int_CVTSS2SDrm: I<0x5A, MRMSrcMem,
1732                       (outs VR128:$dst), (ins VR128:$src1, f32mem:$src2),
1733                     "cvtss2sd\t{$src2, $dst|$dst, $src2}",
1734                     [(set VR128:$dst, (int_x86_sse2_cvtss2sd VR128:$src1,
1735                                        (load addr:$src2)))]>, XS,
1736                     Requires<[HasSSE2]>;
1737 }
1738
1739 // Convert doubleword to packed single/double fp
1740 // SSE2 instructions without OpSize prefix
1741 def Int_VCVTDQ2PSrr : I<0x5B, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1742                        "vcvtdq2ps\t{$src, $dst|$dst, $src}",
1743                        [(set VR128:$dst, (int_x86_sse2_cvtdq2ps VR128:$src))]>,
1744                      TB, VEX, Requires<[HasAVX]>;
1745 def Int_VCVTDQ2PSrm : I<0x5B, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
1746                       "vcvtdq2ps\t{$src, $dst|$dst, $src}",
1747                       [(set VR128:$dst, (int_x86_sse2_cvtdq2ps
1748                                         (bitconvert (memopv2i64 addr:$src))))]>,
1749                      TB, VEX, Requires<[HasAVX]>;
1750 def Int_CVTDQ2PSrr : I<0x5B, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1751                        "cvtdq2ps\t{$src, $dst|$dst, $src}",
1752                        [(set VR128:$dst, (int_x86_sse2_cvtdq2ps VR128:$src))]>,
1753                      TB, Requires<[HasSSE2]>;
1754 def Int_CVTDQ2PSrm : I<0x5B, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
1755                       "cvtdq2ps\t{$src, $dst|$dst, $src}",
1756                       [(set VR128:$dst, (int_x86_sse2_cvtdq2ps
1757                                         (bitconvert (memopv2i64 addr:$src))))]>,
1758                      TB, Requires<[HasSSE2]>;
1759
1760 // FIXME: why the non-intrinsic version is described as SSE3?
1761 // SSE2 instructions with XS prefix
1762 def Int_VCVTDQ2PDrr : I<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1763                        "vcvtdq2pd\t{$src, $dst|$dst, $src}",
1764                        [(set VR128:$dst, (int_x86_sse2_cvtdq2pd VR128:$src))]>,
1765                      XS, VEX, Requires<[HasAVX]>;
1766 def Int_VCVTDQ2PDrm : I<0xE6, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
1767                        "vcvtdq2pd\t{$src, $dst|$dst, $src}",
1768                        [(set VR128:$dst, (int_x86_sse2_cvtdq2pd
1769                                         (bitconvert (memopv2i64 addr:$src))))]>,
1770                      XS, VEX, Requires<[HasAVX]>;
1771 def Int_CVTDQ2PDrr : I<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1772                        "cvtdq2pd\t{$src, $dst|$dst, $src}",
1773                        [(set VR128:$dst, (int_x86_sse2_cvtdq2pd VR128:$src))]>,
1774                      XS, Requires<[HasSSE2]>;
1775 def Int_CVTDQ2PDrm : I<0xE6, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
1776                      "cvtdq2pd\t{$src, $dst|$dst, $src}",
1777                      [(set VR128:$dst, (int_x86_sse2_cvtdq2pd
1778                                         (bitconvert (memopv2i64 addr:$src))))]>,
1779                      XS, Requires<[HasSSE2]>;
1780
1781
1782 // Convert packed single/double fp to doubleword
1783 def VCVTPS2DQrr : VPDI<0x5B, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1784                        "cvtps2dq\t{$src, $dst|$dst, $src}", []>, VEX;
1785 def VCVTPS2DQrm : VPDI<0x5B, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1786                        "cvtps2dq\t{$src, $dst|$dst, $src}", []>, VEX;
1787 def VCVTPS2DQYrr : VPDI<0x5B, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
1788                         "cvtps2dq\t{$src, $dst|$dst, $src}", []>, VEX;
1789 def VCVTPS2DQYrm : VPDI<0x5B, MRMSrcMem, (outs VR256:$dst), (ins f256mem:$src),
1790                         "cvtps2dq\t{$src, $dst|$dst, $src}", []>, VEX;
1791 def CVTPS2DQrr : PDI<0x5B, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1792                      "cvtps2dq\t{$src, $dst|$dst, $src}", []>;
1793 def CVTPS2DQrm : PDI<0x5B, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1794                      "cvtps2dq\t{$src, $dst|$dst, $src}", []>;
1795
1796 def Int_VCVTPS2DQrr : VPDI<0x5B, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1797                         "cvtps2dq\t{$src, $dst|$dst, $src}",
1798                         [(set VR128:$dst, (int_x86_sse2_cvtps2dq VR128:$src))]>,
1799                         VEX;
1800 def Int_VCVTPS2DQrm : VPDI<0x5B, MRMSrcMem, (outs VR128:$dst),
1801                          (ins f128mem:$src),
1802                          "cvtps2dq\t{$src, $dst|$dst, $src}",
1803                          [(set VR128:$dst, (int_x86_sse2_cvtps2dq
1804                                             (memop addr:$src)))]>, VEX;
1805 def Int_CVTPS2DQrr : PDI<0x5B, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1806                         "cvtps2dq\t{$src, $dst|$dst, $src}",
1807                         [(set VR128:$dst, (int_x86_sse2_cvtps2dq VR128:$src))]>;
1808 def Int_CVTPS2DQrm : PDI<0x5B, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1809                          "cvtps2dq\t{$src, $dst|$dst, $src}",
1810                          [(set VR128:$dst, (int_x86_sse2_cvtps2dq
1811                                             (memop addr:$src)))]>;
1812
1813 // SSE2 packed instructions with XD prefix
1814 def Int_VCVTPD2DQrr : I<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1815                        "vcvtpd2dq\t{$src, $dst|$dst, $src}",
1816                        [(set VR128:$dst, (int_x86_sse2_cvtpd2dq VR128:$src))]>,
1817                      XD, VEX, Requires<[HasAVX]>;
1818 def Int_VCVTPD2DQrm : I<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1819                        "vcvtpd2dq\t{$src, $dst|$dst, $src}",
1820                        [(set VR128:$dst, (int_x86_sse2_cvtpd2dq
1821                                           (memop addr:$src)))]>,
1822                      XD, VEX, Requires<[HasAVX]>;
1823 def Int_CVTPD2DQrr : I<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1824                        "cvtpd2dq\t{$src, $dst|$dst, $src}",
1825                        [(set VR128:$dst, (int_x86_sse2_cvtpd2dq VR128:$src))]>,
1826                      XD, Requires<[HasSSE2]>;
1827 def Int_CVTPD2DQrm : I<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1828                        "cvtpd2dq\t{$src, $dst|$dst, $src}",
1829                        [(set VR128:$dst, (int_x86_sse2_cvtpd2dq
1830                                           (memop addr:$src)))]>,
1831                      XD, Requires<[HasSSE2]>;
1832
1833
1834 // Convert with truncation packed single/double fp to doubleword
1835 // SSE2 packed instructions with XS prefix
1836 def VCVTTPS2DQrr : VSSI<0x5B, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1837                         "cvttps2dq\t{$src, $dst|$dst, $src}",
1838                         [(set VR128:$dst,
1839                           (int_x86_sse2_cvttps2dq VR128:$src))]>, VEX;
1840 def VCVTTPS2DQrm : VSSI<0x5B, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1841                         "cvttps2dq\t{$src, $dst|$dst, $src}",
1842                         [(set VR128:$dst, (int_x86_sse2_cvttps2dq
1843                                            (memop addr:$src)))]>, VEX;
1844 def VCVTTPS2DQYrr : VSSI<0x5B, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
1845                          "cvttps2dq\t{$src, $dst|$dst, $src}",
1846                          [(set VR256:$dst,
1847                            (int_x86_avx_cvtt_ps2dq_256 VR256:$src))]>, VEX;
1848 def VCVTTPS2DQYrm : VSSI<0x5B, MRMSrcMem, (outs VR256:$dst), (ins f256mem:$src),
1849                          "cvttps2dq\t{$src, $dst|$dst, $src}",
1850                          [(set VR256:$dst, (int_x86_avx_cvtt_ps2dq_256
1851                                             (memopv8f32 addr:$src)))]>, VEX;
1852
1853 def CVTTPS2DQrr : SSI<0x5B, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1854                       "cvttps2dq\t{$src, $dst|$dst, $src}",
1855                       [(set VR128:$dst,
1856                             (int_x86_sse2_cvttps2dq VR128:$src))]>;
1857 def CVTTPS2DQrm : SSI<0x5B, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1858                       "cvttps2dq\t{$src, $dst|$dst, $src}",
1859                       [(set VR128:$dst,
1860                             (int_x86_sse2_cvttps2dq (memop addr:$src)))]>;
1861
1862 let Predicates = [HasAVX] in {
1863   def : Pat<(v4f32 (sint_to_fp (v4i32 VR128:$src))),
1864             (Int_VCVTDQ2PSrr VR128:$src)>;
1865   def : Pat<(v4f32 (sint_to_fp (bc_v4i32 (memopv2i64 addr:$src)))),
1866             (Int_VCVTDQ2PSrm addr:$src)>;
1867
1868   def : Pat<(v4i32 (fp_to_sint (v4f32 VR128:$src))),
1869             (VCVTTPS2DQrr VR128:$src)>;
1870   def : Pat<(v4i32 (fp_to_sint (memopv4f32 addr:$src))),
1871             (VCVTTPS2DQrm addr:$src)>;
1872
1873   def : Pat<(v8f32 (sint_to_fp (v8i32 VR256:$src))),
1874             (VCVTDQ2PSYrr VR256:$src)>;
1875   def : Pat<(v8f32 (sint_to_fp (bc_v8i32 (memopv4i64 addr:$src)))),
1876             (VCVTDQ2PSYrm addr:$src)>;
1877
1878   def : Pat<(v8i32 (fp_to_sint (v8f32 VR256:$src))),
1879             (VCVTTPS2DQYrr VR256:$src)>;
1880   def : Pat<(v8i32 (fp_to_sint (memopv8f32 addr:$src))),
1881             (VCVTTPS2DQYrm addr:$src)>;
1882 }
1883
1884 let Predicates = [HasSSE2] in {
1885   def : Pat<(v4f32 (sint_to_fp (v4i32 VR128:$src))),
1886             (Int_CVTDQ2PSrr VR128:$src)>;
1887   def : Pat<(v4f32 (sint_to_fp (bc_v4i32 (memopv2i64 addr:$src)))),
1888             (Int_CVTDQ2PSrm addr:$src)>;
1889
1890   def : Pat<(v4i32 (fp_to_sint (v4f32 VR128:$src))),
1891             (CVTTPS2DQrr VR128:$src)>;
1892   def : Pat<(v4i32 (fp_to_sint (memopv4f32 addr:$src))),
1893             (CVTTPS2DQrm addr:$src)>;
1894 }
1895
1896 def VCVTTPD2DQrr : VPDI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1897                         "cvttpd2dq\t{$src, $dst|$dst, $src}",
1898                         [(set VR128:$dst,
1899                               (int_x86_sse2_cvttpd2dq VR128:$src))]>, VEX;
1900 let isCodeGenOnly = 1 in
1901 def VCVTTPD2DQrm : VPDI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1902                         "cvttpd2dq\t{$src, $dst|$dst, $src}",
1903                         [(set VR128:$dst, (int_x86_sse2_cvttpd2dq
1904                                                (memop addr:$src)))]>, VEX;
1905 def CVTTPD2DQrr : PDI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1906                       "cvttpd2dq\t{$src, $dst|$dst, $src}",
1907                       [(set VR128:$dst, (int_x86_sse2_cvttpd2dq VR128:$src))]>;
1908 def CVTTPD2DQrm : PDI<0xE6, MRMSrcMem, (outs VR128:$dst),(ins f128mem:$src),
1909                       "cvttpd2dq\t{$src, $dst|$dst, $src}",
1910                       [(set VR128:$dst, (int_x86_sse2_cvttpd2dq
1911                                         (memop addr:$src)))]>;
1912
1913 // The assembler can recognize rr 256-bit instructions by seeing a ymm
1914 // register, but the same isn't true when using memory operands instead.
1915 // Provide other assembly rr and rm forms to address this explicitly.
1916 def VCVTTPD2DQXrYr : VPDI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR256:$src),
1917                           "cvttpd2dq\t{$src, $dst|$dst, $src}", []>, VEX;
1918
1919 // XMM only
1920 def VCVTTPD2DQXrr : VPDI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1921                          "cvttpd2dqx\t{$src, $dst|$dst, $src}", []>, VEX;
1922 def VCVTTPD2DQXrm : VPDI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1923                          "cvttpd2dqx\t{$src, $dst|$dst, $src}", []>, VEX;
1924
1925 // YMM only
1926 def VCVTTPD2DQYrr : VPDI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR256:$src),
1927                          "cvttpd2dqy\t{$src, $dst|$dst, $src}", []>, VEX;
1928 def VCVTTPD2DQYrm : VPDI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f256mem:$src),
1929                          "cvttpd2dqy\t{$src, $dst|$dst, $src}", []>, VEX, VEX_L;
1930
1931 // Convert packed single to packed double
1932 let Predicates = [HasAVX] in {
1933                   // SSE2 instructions without OpSize prefix
1934 def VCVTPS2PDrr : I<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1935                      "vcvtps2pd\t{$src, $dst|$dst, $src}", []>, TB, VEX;
1936 def VCVTPS2PDrm : I<0x5A, MRMSrcMem, (outs VR128:$dst), (ins f64mem:$src),
1937                      "vcvtps2pd\t{$src, $dst|$dst, $src}", []>, TB, VEX;
1938 def VCVTPS2PDYrr : I<0x5A, MRMSrcReg, (outs VR256:$dst), (ins VR128:$src),
1939                      "vcvtps2pd\t{$src, $dst|$dst, $src}", []>, TB, VEX;
1940 def VCVTPS2PDYrm : I<0x5A, MRMSrcMem, (outs VR256:$dst), (ins f128mem:$src),
1941                      "vcvtps2pd\t{$src, $dst|$dst, $src}", []>, TB, VEX;
1942 }
1943 def CVTPS2PDrr : I<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1944                        "cvtps2pd\t{$src, $dst|$dst, $src}", []>, TB;
1945 def CVTPS2PDrm : I<0x5A, MRMSrcMem, (outs VR128:$dst), (ins f64mem:$src),
1946                        "cvtps2pd\t{$src, $dst|$dst, $src}", []>, TB;
1947
1948 def Int_VCVTPS2PDrr : I<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1949                        "vcvtps2pd\t{$src, $dst|$dst, $src}",
1950                        [(set VR128:$dst, (int_x86_sse2_cvtps2pd VR128:$src))]>,
1951                      TB, VEX, Requires<[HasAVX]>;
1952 def Int_VCVTPS2PDrm : I<0x5A, MRMSrcMem, (outs VR128:$dst), (ins f64mem:$src),
1953                        "vcvtps2pd\t{$src, $dst|$dst, $src}",
1954                        [(set VR128:$dst, (int_x86_sse2_cvtps2pd
1955                                           (load addr:$src)))]>,
1956                      TB, VEX, Requires<[HasAVX]>;
1957 def Int_CVTPS2PDrr : I<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1958                        "cvtps2pd\t{$src, $dst|$dst, $src}",
1959                        [(set VR128:$dst, (int_x86_sse2_cvtps2pd VR128:$src))]>,
1960                      TB, Requires<[HasSSE2]>;
1961 def Int_CVTPS2PDrm : I<0x5A, MRMSrcMem, (outs VR128:$dst), (ins f64mem:$src),
1962                        "cvtps2pd\t{$src, $dst|$dst, $src}",
1963                        [(set VR128:$dst, (int_x86_sse2_cvtps2pd
1964                                           (load addr:$src)))]>,
1965                      TB, Requires<[HasSSE2]>;
1966
1967 // Convert packed double to packed single
1968 // The assembler can recognize rr 256-bit instructions by seeing a ymm
1969 // register, but the same isn't true when using memory operands instead.
1970 // Provide other assembly rr and rm forms to address this explicitly.
1971 def VCVTPD2PSrr : VPDI<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1972                        "cvtpd2ps\t{$src, $dst|$dst, $src}", []>, VEX;
1973 def VCVTPD2PSXrYr : VPDI<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR256:$src),
1974                          "cvtpd2ps\t{$src, $dst|$dst, $src}", []>, VEX;
1975
1976 // XMM only
1977 def VCVTPD2PSXrr : VPDI<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1978                         "cvtpd2psx\t{$src, $dst|$dst, $src}", []>, VEX;
1979 def VCVTPD2PSXrm : VPDI<0x5A, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1980                         "cvtpd2psx\t{$src, $dst|$dst, $src}", []>, VEX;
1981
1982 // YMM only
1983 def VCVTPD2PSYrr : VPDI<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR256:$src),
1984                         "cvtpd2psy\t{$src, $dst|$dst, $src}", []>, VEX;
1985 def VCVTPD2PSYrm : VPDI<0x5A, MRMSrcMem, (outs VR128:$dst), (ins f256mem:$src),
1986                         "cvtpd2psy\t{$src, $dst|$dst, $src}", []>, VEX, VEX_L;
1987 def CVTPD2PSrr : PDI<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1988                      "cvtpd2ps\t{$src, $dst|$dst, $src}", []>;
1989 def CVTPD2PSrm : PDI<0x5A, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1990                      "cvtpd2ps\t{$src, $dst|$dst, $src}", []>;
1991
1992
1993 def Int_VCVTPD2PSrr : VPDI<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1994                          "cvtpd2ps\t{$src, $dst|$dst, $src}",
1995                         [(set VR128:$dst, (int_x86_sse2_cvtpd2ps VR128:$src))]>;
1996 def Int_VCVTPD2PSrm : VPDI<0x5A, MRMSrcMem, (outs VR128:$dst),
1997                          (ins f128mem:$src),
1998                          "cvtpd2ps\t{$src, $dst|$dst, $src}",
1999                          [(set VR128:$dst, (int_x86_sse2_cvtpd2ps
2000                                             (memop addr:$src)))]>;
2001 def Int_CVTPD2PSrr : PDI<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2002                          "cvtpd2ps\t{$src, $dst|$dst, $src}",
2003                         [(set VR128:$dst, (int_x86_sse2_cvtpd2ps VR128:$src))]>;
2004 def Int_CVTPD2PSrm : PDI<0x5A, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
2005                          "cvtpd2ps\t{$src, $dst|$dst, $src}",
2006                          [(set VR128:$dst, (int_x86_sse2_cvtpd2ps
2007                                             (memop addr:$src)))]>;
2008
2009 // AVX 256-bit register conversion intrinsics
2010 // FIXME: Migrate SSE conversion intrinsics matching to use patterns as below
2011 // whenever possible to avoid declaring two versions of each one.
2012 def : Pat<(int_x86_avx_cvtdq2_ps_256 VR256:$src),
2013           (VCVTDQ2PSYrr VR256:$src)>;
2014 def : Pat<(int_x86_avx_cvtdq2_ps_256 (bitconvert (memopv4i64 addr:$src))),
2015           (VCVTDQ2PSYrm addr:$src)>;
2016
2017 def : Pat<(int_x86_avx_cvt_pd2_ps_256 VR256:$src),
2018           (VCVTPD2PSYrr VR256:$src)>;
2019 def : Pat<(int_x86_avx_cvt_pd2_ps_256 (memopv4f64 addr:$src)),
2020           (VCVTPD2PSYrm addr:$src)>;
2021
2022 def : Pat<(int_x86_avx_cvt_ps2dq_256 VR256:$src),
2023           (VCVTPS2DQYrr VR256:$src)>;
2024 def : Pat<(int_x86_avx_cvt_ps2dq_256 (memopv8f32 addr:$src)),
2025           (VCVTPS2DQYrm addr:$src)>;
2026
2027 def : Pat<(int_x86_avx_cvt_ps2_pd_256 VR128:$src),
2028           (VCVTPS2PDYrr VR128:$src)>;
2029 def : Pat<(int_x86_avx_cvt_ps2_pd_256 (memopv4f32 addr:$src)),
2030           (VCVTPS2PDYrm addr:$src)>;
2031
2032 def : Pat<(int_x86_avx_cvtt_pd2dq_256 VR256:$src),
2033           (VCVTTPD2DQYrr VR256:$src)>;
2034 def : Pat<(int_x86_avx_cvtt_pd2dq_256 (memopv4f64 addr:$src)),
2035           (VCVTTPD2DQYrm addr:$src)>;
2036
2037 // Match fround and fextend for 128/256-bit conversions
2038 def : Pat<(v4f32 (fround (v4f64 VR256:$src))),
2039           (VCVTPD2PSYrr VR256:$src)>;
2040 def : Pat<(v4f32 (fround (loadv4f64 addr:$src))),
2041           (VCVTPD2PSYrm addr:$src)>;
2042
2043 def : Pat<(v4f64 (fextend (v4f32 VR128:$src))),
2044           (VCVTPS2PDYrr VR128:$src)>;
2045 def : Pat<(v4f64 (fextend (loadv4f32 addr:$src))),
2046           (VCVTPS2PDYrm addr:$src)>;
2047
2048 //===----------------------------------------------------------------------===//
2049 // SSE 1 & 2 - Compare Instructions
2050 //===----------------------------------------------------------------------===//
2051
2052 // sse12_cmp_scalar - sse 1 & 2 compare scalar instructions
2053 multiclass sse12_cmp_scalar<RegisterClass RC, X86MemOperand x86memop,
2054                             SDNode OpNode, ValueType VT, PatFrag ld_frag,
2055                             string asm, string asm_alt> {
2056   def rr : SIi8<0xC2, MRMSrcReg,
2057                 (outs RC:$dst), (ins RC:$src1, RC:$src2, SSECC:$cc), asm,
2058                 [(set RC:$dst, (OpNode (VT RC:$src1), RC:$src2, imm:$cc))]>;
2059   def rm : SIi8<0xC2, MRMSrcMem,
2060                 (outs RC:$dst), (ins RC:$src1, x86memop:$src2, SSECC:$cc), asm,
2061                 [(set RC:$dst, (OpNode (VT RC:$src1),
2062                                          (ld_frag addr:$src2), imm:$cc))]>;
2063
2064   // Accept explicit immediate argument form instead of comparison code.
2065   let neverHasSideEffects = 1 in {
2066     def rr_alt : SIi8<0xC2, MRMSrcReg, (outs RC:$dst),
2067                       (ins RC:$src1, RC:$src2, i8imm:$cc), asm_alt, []>;
2068     let mayLoad = 1 in
2069     def rm_alt : SIi8<0xC2, MRMSrcMem, (outs RC:$dst),
2070                       (ins RC:$src1, x86memop:$src2, i8imm:$cc), asm_alt, []>;
2071   }
2072 }
2073
2074 defm VCMPSS : sse12_cmp_scalar<FR32, f32mem, X86cmpss, f32, loadf32,
2075                  "cmp${cc}ss\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2076                  "cmpss\t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}">,
2077                  XS, VEX_4V, VEX_LIG;
2078 defm VCMPSD : sse12_cmp_scalar<FR64, f64mem, X86cmpsd, f64, loadf64,
2079                  "cmp${cc}sd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2080                  "cmpsd\t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}">,
2081                  XD, VEX_4V, VEX_LIG;
2082
2083 let Constraints = "$src1 = $dst" in {
2084   defm CMPSS : sse12_cmp_scalar<FR32, f32mem, X86cmpss, f32, loadf32,
2085                   "cmp${cc}ss\t{$src2, $dst|$dst, $src2}",
2086                   "cmpss\t{$cc, $src2, $dst|$dst, $src2, $cc}">,
2087                   XS;
2088   defm CMPSD : sse12_cmp_scalar<FR64, f64mem, X86cmpsd, f64, loadf64,
2089                   "cmp${cc}sd\t{$src2, $dst|$dst, $src2}",
2090                   "cmpsd\t{$cc, $src2, $dst|$dst, $src2, $cc}">,
2091                   XD;
2092 }
2093
2094 multiclass sse12_cmp_scalar_int<RegisterClass RC, X86MemOperand x86memop,
2095                          Intrinsic Int, string asm> {
2096   def rr : SIi8<0xC2, MRMSrcReg, (outs VR128:$dst),
2097                       (ins VR128:$src1, VR128:$src, SSECC:$cc), asm,
2098                         [(set VR128:$dst, (Int VR128:$src1,
2099                                                VR128:$src, imm:$cc))]>;
2100   def rm : SIi8<0xC2, MRMSrcMem, (outs VR128:$dst),
2101                       (ins VR128:$src1, x86memop:$src, SSECC:$cc), asm,
2102                         [(set VR128:$dst, (Int VR128:$src1,
2103                                                (load addr:$src), imm:$cc))]>;
2104 }
2105
2106 // Aliases to match intrinsics which expect XMM operand(s).
2107 defm Int_VCMPSS  : sse12_cmp_scalar_int<VR128, f32mem, int_x86_sse_cmp_ss,
2108                      "cmp${cc}ss\t{$src, $src1, $dst|$dst, $src1, $src}">,
2109                      XS, VEX_4V;
2110 defm Int_VCMPSD  : sse12_cmp_scalar_int<VR128, f64mem, int_x86_sse2_cmp_sd,
2111                      "cmp${cc}sd\t{$src, $src1, $dst|$dst, $src1, $src}">,
2112                      XD, VEX_4V;
2113 let Constraints = "$src1 = $dst" in {
2114   defm Int_CMPSS  : sse12_cmp_scalar_int<VR128, f32mem, int_x86_sse_cmp_ss,
2115                        "cmp${cc}ss\t{$src, $dst|$dst, $src}">, XS;
2116   defm Int_CMPSD  : sse12_cmp_scalar_int<VR128, f64mem, int_x86_sse2_cmp_sd,
2117                        "cmp${cc}sd\t{$src, $dst|$dst, $src}">, XD;
2118 }
2119
2120
2121 // sse12_ord_cmp - Unordered/Ordered scalar fp compare and set EFLAGS
2122 multiclass sse12_ord_cmp<bits<8> opc, RegisterClass RC, SDNode OpNode,
2123                             ValueType vt, X86MemOperand x86memop,
2124                             PatFrag ld_frag, string OpcodeStr, Domain d> {
2125   def rr: PI<opc, MRMSrcReg, (outs), (ins RC:$src1, RC:$src2),
2126                      !strconcat(OpcodeStr, "\t{$src2, $src1|$src1, $src2}"),
2127                      [(set EFLAGS, (OpNode (vt RC:$src1), RC:$src2))], d>;
2128   def rm: PI<opc, MRMSrcMem, (outs), (ins RC:$src1, x86memop:$src2),
2129                      !strconcat(OpcodeStr, "\t{$src2, $src1|$src1, $src2}"),
2130                      [(set EFLAGS, (OpNode (vt RC:$src1),
2131                                            (ld_frag addr:$src2)))], d>;
2132 }
2133
2134 let Defs = [EFLAGS] in {
2135   defm VUCOMISS : sse12_ord_cmp<0x2E, FR32, X86cmp, f32, f32mem, loadf32,
2136                                   "ucomiss", SSEPackedSingle>, TB, VEX, VEX_LIG;
2137   defm VUCOMISD : sse12_ord_cmp<0x2E, FR64, X86cmp, f64, f64mem, loadf64,
2138                                   "ucomisd", SSEPackedDouble>, TB, OpSize, VEX,
2139                                   VEX_LIG;
2140   let Pattern = []<dag> in {
2141     defm VCOMISS  : sse12_ord_cmp<0x2F, VR128, undef, v4f32, f128mem, load,
2142                                     "comiss", SSEPackedSingle>, TB, VEX,
2143                                     VEX_LIG;
2144     defm VCOMISD  : sse12_ord_cmp<0x2F, VR128, undef, v2f64, f128mem, load,
2145                                     "comisd", SSEPackedDouble>, TB, OpSize, VEX,
2146                                     VEX_LIG;
2147   }
2148
2149   defm Int_VUCOMISS  : sse12_ord_cmp<0x2E, VR128, X86ucomi, v4f32, f128mem,
2150                             load, "ucomiss", SSEPackedSingle>, TB, VEX;
2151   defm Int_VUCOMISD  : sse12_ord_cmp<0x2E, VR128, X86ucomi, v2f64, f128mem,
2152                             load, "ucomisd", SSEPackedDouble>, TB, OpSize, VEX;
2153
2154   defm Int_VCOMISS  : sse12_ord_cmp<0x2F, VR128, X86comi, v4f32, f128mem,
2155                             load, "comiss", SSEPackedSingle>, TB, VEX;
2156   defm Int_VCOMISD  : sse12_ord_cmp<0x2F, VR128, X86comi, v2f64, f128mem,
2157                             load, "comisd", SSEPackedDouble>, TB, OpSize, VEX;
2158   defm UCOMISS  : sse12_ord_cmp<0x2E, FR32, X86cmp, f32, f32mem, loadf32,
2159                                   "ucomiss", SSEPackedSingle>, TB;
2160   defm UCOMISD  : sse12_ord_cmp<0x2E, FR64, X86cmp, f64, f64mem, loadf64,
2161                                   "ucomisd", SSEPackedDouble>, TB, OpSize;
2162
2163   let Pattern = []<dag> in {
2164     defm COMISS  : sse12_ord_cmp<0x2F, VR128, undef, v4f32, f128mem, load,
2165                                     "comiss", SSEPackedSingle>, TB;
2166     defm COMISD  : sse12_ord_cmp<0x2F, VR128, undef, v2f64, f128mem, load,
2167                                     "comisd", SSEPackedDouble>, TB, OpSize;
2168   }
2169
2170   defm Int_UCOMISS  : sse12_ord_cmp<0x2E, VR128, X86ucomi, v4f32, f128mem,
2171                               load, "ucomiss", SSEPackedSingle>, TB;
2172   defm Int_UCOMISD  : sse12_ord_cmp<0x2E, VR128, X86ucomi, v2f64, f128mem,
2173                               load, "ucomisd", SSEPackedDouble>, TB, OpSize;
2174
2175   defm Int_COMISS  : sse12_ord_cmp<0x2F, VR128, X86comi, v4f32, f128mem, load,
2176                                   "comiss", SSEPackedSingle>, TB;
2177   defm Int_COMISD  : sse12_ord_cmp<0x2F, VR128, X86comi, v2f64, f128mem, load,
2178                                   "comisd", SSEPackedDouble>, TB, OpSize;
2179 } // Defs = [EFLAGS]
2180
2181 // sse12_cmp_packed - sse 1 & 2 compared packed instructions
2182 multiclass sse12_cmp_packed<RegisterClass RC, X86MemOperand x86memop,
2183                             Intrinsic Int, string asm, string asm_alt,
2184                             Domain d> {
2185   let isAsmParserOnly = 1 in {
2186     def rri : PIi8<0xC2, MRMSrcReg,
2187                (outs RC:$dst), (ins RC:$src1, RC:$src2, SSECC:$cc), asm,
2188                [(set RC:$dst, (Int RC:$src1, RC:$src2, imm:$cc))], d>;
2189     def rmi : PIi8<0xC2, MRMSrcMem,
2190                (outs RC:$dst), (ins RC:$src1, x86memop:$src2, SSECC:$cc), asm,
2191                [(set RC:$dst, (Int RC:$src1, (memop addr:$src2), imm:$cc))], d>;
2192   }
2193
2194   // Accept explicit immediate argument form instead of comparison code.
2195   def rri_alt : PIi8<0xC2, MRMSrcReg,
2196              (outs RC:$dst), (ins RC:$src1, RC:$src2, i8imm:$cc),
2197              asm_alt, [], d>;
2198   def rmi_alt : PIi8<0xC2, MRMSrcMem,
2199              (outs RC:$dst), (ins RC:$src1, x86memop:$src2, i8imm:$cc),
2200              asm_alt, [], d>;
2201 }
2202
2203 defm VCMPPS : sse12_cmp_packed<VR128, f128mem, int_x86_sse_cmp_ps,
2204                "cmp${cc}ps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2205                "cmpps\t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}",
2206                SSEPackedSingle>, TB, VEX_4V;
2207 defm VCMPPD : sse12_cmp_packed<VR128, f128mem, int_x86_sse2_cmp_pd,
2208                "cmp${cc}pd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2209                "cmppd\t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}",
2210                SSEPackedDouble>, TB, OpSize, VEX_4V;
2211 defm VCMPPSY : sse12_cmp_packed<VR256, f256mem, int_x86_avx_cmp_ps_256,
2212                "cmp${cc}ps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2213                "cmpps\t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}",
2214                SSEPackedSingle>, TB, VEX_4V;
2215 defm VCMPPDY : sse12_cmp_packed<VR256, f256mem, int_x86_avx_cmp_pd_256,
2216                "cmp${cc}pd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2217                "cmppd\t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}",
2218                SSEPackedDouble>, TB, OpSize, VEX_4V;
2219 let Constraints = "$src1 = $dst" in {
2220   defm CMPPS : sse12_cmp_packed<VR128, f128mem, int_x86_sse_cmp_ps,
2221                  "cmp${cc}ps\t{$src2, $dst|$dst, $src2}",
2222                  "cmpps\t{$cc, $src2, $dst|$dst, $src2, $cc}",
2223                  SSEPackedSingle>, TB;
2224   defm CMPPD : sse12_cmp_packed<VR128, f128mem, int_x86_sse2_cmp_pd,
2225                  "cmp${cc}pd\t{$src2, $dst|$dst, $src2}",
2226                  "cmppd\t{$cc, $src2, $dst|$dst, $src2, $cc}",
2227                  SSEPackedDouble>, TB, OpSize;
2228 }
2229
2230 let Predicates = [HasAVX] in {
2231 def : Pat<(v4i32 (X86cmpp (v4f32 VR128:$src1), VR128:$src2, imm:$cc)),
2232           (VCMPPSrri (v4f32 VR128:$src1), (v4f32 VR128:$src2), imm:$cc)>;
2233 def : Pat<(v4i32 (X86cmpp (v4f32 VR128:$src1), (memop addr:$src2), imm:$cc)),
2234           (VCMPPSrmi (v4f32 VR128:$src1), addr:$src2, imm:$cc)>;
2235 def : Pat<(v2i64 (X86cmpp (v2f64 VR128:$src1), VR128:$src2, imm:$cc)),
2236           (VCMPPDrri VR128:$src1, VR128:$src2, imm:$cc)>;
2237 def : Pat<(v2i64 (X86cmpp (v2f64 VR128:$src1), (memop addr:$src2), imm:$cc)),
2238           (VCMPPDrmi VR128:$src1, addr:$src2, imm:$cc)>;
2239
2240 def : Pat<(v8i32 (X86cmpp (v8f32 VR256:$src1), VR256:$src2, imm:$cc)),
2241           (VCMPPSYrri (v8f32 VR256:$src1), (v8f32 VR256:$src2), imm:$cc)>;
2242 def : Pat<(v8i32 (X86cmpp (v8f32 VR256:$src1), (memop addr:$src2), imm:$cc)),
2243           (VCMPPSYrmi (v8f32 VR256:$src1), addr:$src2, imm:$cc)>;
2244 def : Pat<(v4i64 (X86cmpp (v4f64 VR256:$src1), VR256:$src2, imm:$cc)),
2245           (VCMPPDYrri VR256:$src1, VR256:$src2, imm:$cc)>;
2246 def : Pat<(v4i64 (X86cmpp (v4f64 VR256:$src1), (memop addr:$src2), imm:$cc)),
2247           (VCMPPDYrmi VR256:$src1, addr:$src2, imm:$cc)>;
2248 }
2249
2250 let Predicates = [HasSSE1] in {
2251 def : Pat<(v4i32 (X86cmpp (v4f32 VR128:$src1), VR128:$src2, imm:$cc)),
2252           (CMPPSrri (v4f32 VR128:$src1), (v4f32 VR128:$src2), imm:$cc)>;
2253 def : Pat<(v4i32 (X86cmpp (v4f32 VR128:$src1), (memop addr:$src2), imm:$cc)),
2254           (CMPPSrmi (v4f32 VR128:$src1), addr:$src2, imm:$cc)>;
2255 }
2256
2257 let Predicates = [HasSSE2] in {
2258 def : Pat<(v2i64 (X86cmpp (v2f64 VR128:$src1), VR128:$src2, imm:$cc)),
2259           (CMPPDrri VR128:$src1, VR128:$src2, imm:$cc)>;
2260 def : Pat<(v2i64 (X86cmpp (v2f64 VR128:$src1), (memop addr:$src2), imm:$cc)),
2261           (CMPPDrmi VR128:$src1, addr:$src2, imm:$cc)>;
2262 }
2263
2264 //===----------------------------------------------------------------------===//
2265 // SSE 1 & 2 - Shuffle Instructions
2266 //===----------------------------------------------------------------------===//
2267
2268 /// sse12_shuffle - sse 1 & 2 shuffle instructions
2269 multiclass sse12_shuffle<RegisterClass RC, X86MemOperand x86memop,
2270                          ValueType vt, string asm, PatFrag mem_frag,
2271                          Domain d, bit IsConvertibleToThreeAddress = 0> {
2272   def rmi : PIi8<0xC6, MRMSrcMem, (outs RC:$dst),
2273                    (ins RC:$src1, x86memop:$src2, i8imm:$src3), asm,
2274                    [(set RC:$dst, (vt (shufp:$src3
2275                             RC:$src1, (mem_frag addr:$src2))))], d>;
2276   let isConvertibleToThreeAddress = IsConvertibleToThreeAddress in
2277     def rri : PIi8<0xC6, MRMSrcReg, (outs RC:$dst),
2278                    (ins RC:$src1, RC:$src2, i8imm:$src3), asm,
2279                    [(set RC:$dst,
2280                             (vt (shufp:$src3 RC:$src1, RC:$src2)))], d>;
2281 }
2282
2283 defm VSHUFPS  : sse12_shuffle<VR128, f128mem, v4f32,
2284            "shufps\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
2285            memopv4f32, SSEPackedSingle>, TB, VEX_4V;
2286 defm VSHUFPSY : sse12_shuffle<VR256, f256mem, v8f32,
2287            "shufps\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
2288            memopv8f32, SSEPackedSingle>, TB, VEX_4V;
2289 defm VSHUFPD  : sse12_shuffle<VR128, f128mem, v2f64,
2290            "shufpd\t{$src3, $src2, $src1, $dst|$dst, $src2, $src2, $src3}",
2291            memopv2f64, SSEPackedDouble>, TB, OpSize, VEX_4V;
2292 defm VSHUFPDY : sse12_shuffle<VR256, f256mem, v4f64,
2293            "shufpd\t{$src3, $src2, $src1, $dst|$dst, $src2, $src2, $src3}",
2294            memopv4f64, SSEPackedDouble>, TB, OpSize, VEX_4V;
2295
2296 let Constraints = "$src1 = $dst" in {
2297   defm SHUFPS : sse12_shuffle<VR128, f128mem, v4f32,
2298                     "shufps\t{$src3, $src2, $dst|$dst, $src2, $src3}",
2299                     memopv4f32, SSEPackedSingle, 1 /* cvt to pshufd */>,
2300                     TB;
2301   defm SHUFPD : sse12_shuffle<VR128, f128mem, v2f64,
2302                     "shufpd\t{$src3, $src2, $dst|$dst, $src2, $src3}",
2303                     memopv2f64, SSEPackedDouble, 1 /* cvt to pshufd */>,
2304                     TB, OpSize;
2305 }
2306
2307 let Predicates = [HasAVX] in {
2308   def : Pat<(v4f32 (X86Shufp VR128:$src1,
2309                        (memopv4f32 addr:$src2), (i8 imm:$imm))),
2310             (VSHUFPSrmi VR128:$src1, addr:$src2, imm:$imm)>;
2311   def : Pat<(v4f32 (X86Shufp VR128:$src1, VR128:$src2, (i8 imm:$imm))),
2312             (VSHUFPSrri VR128:$src1, VR128:$src2, imm:$imm)>;
2313   def : Pat<(v4i32 (X86Shufp VR128:$src1,
2314                        (bc_v4i32 (memopv2i64 addr:$src2)), (i8 imm:$imm))),
2315             (VSHUFPSrmi VR128:$src1, addr:$src2, imm:$imm)>;
2316   def : Pat<(v4i32 (X86Shufp VR128:$src1, VR128:$src2, (i8 imm:$imm))),
2317             (VSHUFPSrri VR128:$src1, VR128:$src2, imm:$imm)>;
2318   // vector_shuffle v1, v2 <4, 5, 2, 3> using SHUFPSrri (we prefer movsd, but
2319   // fall back to this for SSE1)
2320   def : Pat<(v4f32 (movlp:$src3 VR128:$src1, (v4f32 VR128:$src2))),
2321             (VSHUFPSrri VR128:$src2, VR128:$src1,
2322                         (SHUFFLE_get_shuf_imm VR128:$src3))>;
2323   // Special unary SHUFPSrri case.
2324   def : Pat<(v4f32 (pshufd:$src3 VR128:$src1, (undef))),
2325             (VSHUFPSrri VR128:$src1, VR128:$src1,
2326                         (SHUFFLE_get_shuf_imm VR128:$src3))>;
2327   // Special binary v4i32 shuffle cases with SHUFPS.
2328   def : Pat<(v4i32 (shufp:$src3 VR128:$src1, (v4i32 VR128:$src2))),
2329             (VSHUFPSrri VR128:$src1, VR128:$src2,
2330                         (SHUFFLE_get_shuf_imm VR128:$src3))>;
2331   def : Pat<(v4i32 (shufp:$src3 VR128:$src1,
2332                                 (bc_v4i32 (memopv2i64 addr:$src2)))),
2333             (VSHUFPSrmi VR128:$src1, addr:$src2,
2334                         (SHUFFLE_get_shuf_imm VR128:$src3))>;
2335   // Special unary SHUFPDrri cases.
2336   def : Pat<(v2i64 (pshufd:$src3 VR128:$src1, (undef))),
2337             (VSHUFPDrri VR128:$src1, VR128:$src1,
2338                         (SHUFFLE_get_shuf_imm VR128:$src3))>;
2339   def : Pat<(v2f64 (pshufd:$src3 VR128:$src1, (undef))),
2340             (VSHUFPDrri VR128:$src1, VR128:$src1,
2341                         (SHUFFLE_get_shuf_imm VR128:$src3))>;
2342   // Special binary v2i64 shuffle cases using SHUFPDrri.
2343   def : Pat<(v2i64 (shufp:$src3 VR128:$src1, VR128:$src2)),
2344             (VSHUFPDrri VR128:$src1, VR128:$src2,
2345                         (SHUFFLE_get_shuf_imm VR128:$src3))>;
2346
2347   def : Pat<(v2i64 (X86Shufp VR128:$src1,
2348                        (memopv2i64 addr:$src2), (i8 imm:$imm))),
2349             (VSHUFPDrmi VR128:$src1, addr:$src2, imm:$imm)>;
2350   def : Pat<(v2f64 (X86Shufp VR128:$src1,
2351                        (memopv2f64 addr:$src2), (i8 imm:$imm))),
2352             (VSHUFPDrmi VR128:$src1, addr:$src2, imm:$imm)>;
2353   def : Pat<(v2i64 (X86Shufp VR128:$src1, VR128:$src2, (i8 imm:$imm))),
2354             (VSHUFPDrri VR128:$src1, VR128:$src2, imm:$imm)>;
2355   def : Pat<(v2f64 (X86Shufp VR128:$src1, VR128:$src2, (i8 imm:$imm))),
2356             (VSHUFPDrri VR128:$src1, VR128:$src2, imm:$imm)>;
2357
2358   // 256-bit patterns
2359   def : Pat<(v8i32 (X86Shufp VR256:$src1, VR256:$src2, (i8 imm:$imm))),
2360             (VSHUFPSYrri VR256:$src1, VR256:$src2, imm:$imm)>;
2361   def : Pat<(v8i32 (X86Shufp VR256:$src1,
2362                       (bc_v8i32 (memopv4i64 addr:$src2)), (i8 imm:$imm))),
2363             (VSHUFPSYrmi VR256:$src1, addr:$src2, imm:$imm)>;
2364
2365   def : Pat<(v8f32 (X86Shufp VR256:$src1, VR256:$src2, (i8 imm:$imm))),
2366             (VSHUFPSYrri VR256:$src1, VR256:$src2, imm:$imm)>;
2367   def : Pat<(v8f32 (X86Shufp VR256:$src1,
2368                               (memopv8f32 addr:$src2), (i8 imm:$imm))),
2369             (VSHUFPSYrmi VR256:$src1, addr:$src2, imm:$imm)>;
2370
2371   def : Pat<(v4i64 (X86Shufp VR256:$src1, VR256:$src2, (i8 imm:$imm))),
2372             (VSHUFPDYrri VR256:$src1, VR256:$src2, imm:$imm)>;
2373   def : Pat<(v4i64 (X86Shufp VR256:$src1,
2374                               (memopv4i64 addr:$src2), (i8 imm:$imm))),
2375             (VSHUFPDYrmi VR256:$src1, addr:$src2, imm:$imm)>;
2376
2377   def : Pat<(v4f64 (X86Shufp VR256:$src1, VR256:$src2, (i8 imm:$imm))),
2378             (VSHUFPDYrri VR256:$src1, VR256:$src2, imm:$imm)>;
2379   def : Pat<(v4f64 (X86Shufp VR256:$src1,
2380                               (memopv4f64 addr:$src2), (i8 imm:$imm))),
2381             (VSHUFPDYrmi VR256:$src1, addr:$src2, imm:$imm)>;
2382 }
2383
2384 let Predicates = [HasSSE1] in {
2385   def : Pat<(v4f32 (X86Shufp VR128:$src1,
2386                        (memopv4f32 addr:$src2), (i8 imm:$imm))),
2387             (SHUFPSrmi VR128:$src1, addr:$src2, imm:$imm)>;
2388   def : Pat<(v4f32 (X86Shufp VR128:$src1, VR128:$src2, (i8 imm:$imm))),
2389             (SHUFPSrri VR128:$src1, VR128:$src2, imm:$imm)>;
2390   def : Pat<(v4i32 (X86Shufp VR128:$src1,
2391                        (bc_v4i32 (memopv2i64 addr:$src2)), (i8 imm:$imm))),
2392             (SHUFPSrmi VR128:$src1, addr:$src2, imm:$imm)>;
2393   def : Pat<(v4i32 (X86Shufp VR128:$src1, VR128:$src2, (i8 imm:$imm))),
2394             (SHUFPSrri VR128:$src1, VR128:$src2, imm:$imm)>;
2395   // vector_shuffle v1, v2 <4, 5, 2, 3> using SHUFPSrri (we prefer movsd, but
2396   // fall back to this for SSE1)
2397   def : Pat<(v4f32 (movlp:$src3 VR128:$src1, (v4f32 VR128:$src2))),
2398             (SHUFPSrri VR128:$src2, VR128:$src1,
2399                        (SHUFFLE_get_shuf_imm VR128:$src3))>;
2400   // Special unary SHUFPSrri case.
2401   def : Pat<(v4f32 (pshufd:$src3 VR128:$src1, (undef))),
2402             (SHUFPSrri VR128:$src1, VR128:$src1,
2403                        (SHUFFLE_get_shuf_imm VR128:$src3))>;
2404 }
2405
2406 let Predicates = [HasSSE2] in {
2407   // Special binary v4i32 shuffle cases with SHUFPS.
2408   def : Pat<(v4i32 (shufp:$src3 VR128:$src1, (v4i32 VR128:$src2))),
2409             (SHUFPSrri VR128:$src1, VR128:$src2,
2410                        (SHUFFLE_get_shuf_imm VR128:$src3))>;
2411   def : Pat<(v4i32 (shufp:$src3 VR128:$src1,
2412                                 (bc_v4i32 (memopv2i64 addr:$src2)))),
2413             (SHUFPSrmi VR128:$src1, addr:$src2,
2414                       (SHUFFLE_get_shuf_imm VR128:$src3))>;
2415   // Special unary SHUFPDrri cases.
2416   def : Pat<(v2i64 (pshufd:$src3 VR128:$src1, (undef))),
2417             (SHUFPDrri VR128:$src1, VR128:$src1,
2418                        (SHUFFLE_get_shuf_imm VR128:$src3))>;
2419   def : Pat<(v2f64 (pshufd:$src3 VR128:$src1, (undef))),
2420             (SHUFPDrri VR128:$src1, VR128:$src1,
2421                        (SHUFFLE_get_shuf_imm VR128:$src3))>;
2422   // Special binary v2i64 shuffle cases using SHUFPDrri.
2423   def : Pat<(v2i64 (shufp:$src3 VR128:$src1, VR128:$src2)),
2424             (SHUFPDrri VR128:$src1, VR128:$src2,
2425                        (SHUFFLE_get_shuf_imm VR128:$src3))>;
2426   // Generic SHUFPD patterns
2427   def : Pat<(v2i64 (X86Shufp VR128:$src1,
2428                        (memopv2i64 addr:$src2), (i8 imm:$imm))),
2429             (SHUFPDrmi VR128:$src1, addr:$src2, imm:$imm)>;
2430   def : Pat<(v2f64 (X86Shufp VR128:$src1,
2431                        (memopv2f64 addr:$src2), (i8 imm:$imm))),
2432             (SHUFPDrmi VR128:$src1, addr:$src2, imm:$imm)>;
2433   def : Pat<(v2i64 (X86Shufp VR128:$src1, VR128:$src2, (i8 imm:$imm))),
2434             (SHUFPDrri VR128:$src1, VR128:$src2, imm:$imm)>;
2435   def : Pat<(v2f64 (X86Shufp VR128:$src1, VR128:$src2, (i8 imm:$imm))),
2436             (SHUFPDrri VR128:$src1, VR128:$src2, imm:$imm)>;
2437 }
2438
2439 //===----------------------------------------------------------------------===//
2440 // SSE 1 & 2 - Unpack Instructions
2441 //===----------------------------------------------------------------------===//
2442
2443 /// sse12_unpack_interleave - sse 1 & 2 unpack and interleave
2444 multiclass sse12_unpack_interleave<bits<8> opc, PatFrag OpNode, ValueType vt,
2445                                    PatFrag mem_frag, RegisterClass RC,
2446                                    X86MemOperand x86memop, string asm,
2447                                    Domain d> {
2448     def rr : PI<opc, MRMSrcReg,
2449                 (outs RC:$dst), (ins RC:$src1, RC:$src2),
2450                 asm, [(set RC:$dst,
2451                            (vt (OpNode RC:$src1, RC:$src2)))], d>;
2452     def rm : PI<opc, MRMSrcMem,
2453                 (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
2454                 asm, [(set RC:$dst,
2455                            (vt (OpNode RC:$src1,
2456                                        (mem_frag addr:$src2))))], d>;
2457 }
2458
2459 let AddedComplexity = 10 in {
2460   defm VUNPCKHPS: sse12_unpack_interleave<0x15, unpckh, v4f32, memopv4f32,
2461         VR128, f128mem, "unpckhps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2462                        SSEPackedSingle>, TB, VEX_4V;
2463   defm VUNPCKHPD: sse12_unpack_interleave<0x15, unpckh, v2f64, memopv2f64,
2464         VR128, f128mem, "unpckhpd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2465                        SSEPackedDouble>, TB, OpSize, VEX_4V;
2466   defm VUNPCKLPS: sse12_unpack_interleave<0x14, unpckl, v4f32, memopv4f32,
2467         VR128, f128mem, "unpcklps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2468                        SSEPackedSingle>, TB, VEX_4V;
2469   defm VUNPCKLPD: sse12_unpack_interleave<0x14, unpckl, v2f64, memopv2f64,
2470         VR128, f128mem, "unpcklpd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2471                        SSEPackedDouble>, TB, OpSize, VEX_4V;
2472
2473   defm VUNPCKHPSY: sse12_unpack_interleave<0x15, unpckh, v8f32, memopv8f32,
2474         VR256, f256mem, "unpckhps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2475                        SSEPackedSingle>, TB, VEX_4V;
2476   defm VUNPCKHPDY: sse12_unpack_interleave<0x15, unpckh, v4f64, memopv4f64,
2477         VR256, f256mem, "unpckhpd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2478                        SSEPackedDouble>, TB, OpSize, VEX_4V;
2479   defm VUNPCKLPSY: sse12_unpack_interleave<0x14, unpckl, v8f32, memopv8f32,
2480         VR256, f256mem, "unpcklps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2481                        SSEPackedSingle>, TB, VEX_4V;
2482   defm VUNPCKLPDY: sse12_unpack_interleave<0x14, unpckl, v4f64, memopv4f64,
2483         VR256, f256mem, "unpcklpd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2484                        SSEPackedDouble>, TB, OpSize, VEX_4V;
2485
2486   let Constraints = "$src1 = $dst" in {
2487     defm UNPCKHPS: sse12_unpack_interleave<0x15, unpckh, v4f32, memopv4f32,
2488           VR128, f128mem, "unpckhps\t{$src2, $dst|$dst, $src2}",
2489                          SSEPackedSingle>, TB;
2490     defm UNPCKHPD: sse12_unpack_interleave<0x15, unpckh, v2f64, memopv2f64,
2491           VR128, f128mem, "unpckhpd\t{$src2, $dst|$dst, $src2}",
2492                          SSEPackedDouble>, TB, OpSize;
2493     defm UNPCKLPS: sse12_unpack_interleave<0x14, unpckl, v4f32, memopv4f32,
2494           VR128, f128mem, "unpcklps\t{$src2, $dst|$dst, $src2}",
2495                          SSEPackedSingle>, TB;
2496     defm UNPCKLPD: sse12_unpack_interleave<0x14, unpckl, v2f64, memopv2f64,
2497           VR128, f128mem, "unpcklpd\t{$src2, $dst|$dst, $src2}",
2498                          SSEPackedDouble>, TB, OpSize;
2499   } // Constraints = "$src1 = $dst"
2500 } // AddedComplexity
2501
2502 let Predicates = [HasAVX], AddedComplexity = 1 in {
2503   def : Pat<(v4f32 (X86Unpckl VR128:$src1, (memopv4f32 addr:$src2))),
2504             (VUNPCKLPSrm VR128:$src1, addr:$src2)>;
2505   def : Pat<(v4f32 (X86Unpckl VR128:$src1, VR128:$src2)),
2506             (VUNPCKLPSrr VR128:$src1, VR128:$src2)>;
2507   def : Pat<(v4f32 (X86Unpckh VR128:$src1, (memopv4f32 addr:$src2))),
2508             (VUNPCKHPSrm VR128:$src1, addr:$src2)>;
2509   def : Pat<(v4f32 (X86Unpckh VR128:$src1, VR128:$src2)),
2510             (VUNPCKHPSrr VR128:$src1, VR128:$src2)>;
2511
2512   def : Pat<(v8f32 (X86Unpckl VR256:$src1, (memopv8f32 addr:$src2))),
2513             (VUNPCKLPSYrm VR256:$src1, addr:$src2)>;
2514   def : Pat<(v8f32 (X86Unpckl VR256:$src1, VR256:$src2)),
2515             (VUNPCKLPSYrr VR256:$src1, VR256:$src2)>;
2516   def : Pat<(v8f32 (X86Unpckh VR256:$src1, (memopv8f32 addr:$src2))),
2517             (VUNPCKHPSYrm VR256:$src1, addr:$src2)>;
2518   def : Pat<(v8f32 (X86Unpckh VR256:$src1, VR256:$src2)),
2519             (VUNPCKHPSYrr VR256:$src1, VR256:$src2)>;
2520
2521   def : Pat<(v2f64 (X86Unpckl VR128:$src1, (memopv2f64 addr:$src2))),
2522             (VUNPCKLPDrm VR128:$src1, addr:$src2)>;
2523   def : Pat<(v2f64 (X86Unpckl VR128:$src1, VR128:$src2)),
2524             (VUNPCKLPDrr VR128:$src1, VR128:$src2)>;
2525   def : Pat<(v2f64 (X86Unpckh VR128:$src1, (memopv2f64 addr:$src2))),
2526             (VUNPCKHPDrm VR128:$src1, addr:$src2)>;
2527   def : Pat<(v2f64 (X86Unpckh VR128:$src1, VR128:$src2)),
2528             (VUNPCKHPDrr VR128:$src1, VR128:$src2)>;
2529
2530   def : Pat<(v4f64 (X86Unpckl VR256:$src1, (memopv4f64 addr:$src2))),
2531             (VUNPCKLPDYrm VR256:$src1, addr:$src2)>;
2532   def : Pat<(v4f64 (X86Unpckl VR256:$src1, VR256:$src2)),
2533             (VUNPCKLPDYrr VR256:$src1, VR256:$src2)>;
2534   def : Pat<(v4f64 (X86Unpckh VR256:$src1, (memopv4f64 addr:$src2))),
2535             (VUNPCKHPDYrm VR256:$src1, addr:$src2)>;
2536   def : Pat<(v4f64 (X86Unpckh VR256:$src1, VR256:$src2)),
2537             (VUNPCKHPDYrr VR256:$src1, VR256:$src2)>;
2538
2539   // FIXME: Instead of X86Movddup, there should be a X86Unpckl here, the
2540   // problem is during lowering, where it's not possible to recognize the load
2541   // fold cause it has two uses through a bitcast. One use disappears at isel
2542   // time and the fold opportunity reappears.
2543   def : Pat<(v2f64 (X86Movddup VR128:$src)),
2544             (VUNPCKLPDrr VR128:$src, VR128:$src)>;
2545   let AddedComplexity = 10 in
2546   def : Pat<(splat_lo (v2f64 VR128:$src), (undef)),
2547             (VUNPCKLPDrr VR128:$src, VR128:$src)>;
2548 }
2549
2550 let Predicates = [HasSSE1] in {
2551   def : Pat<(v4f32 (X86Unpckl VR128:$src1, (memopv4f32 addr:$src2))),
2552             (UNPCKLPSrm VR128:$src1, addr:$src2)>;
2553   def : Pat<(v4f32 (X86Unpckl VR128:$src1, VR128:$src2)),
2554             (UNPCKLPSrr VR128:$src1, VR128:$src2)>;
2555   def : Pat<(v4f32 (X86Unpckh VR128:$src1, (memopv4f32 addr:$src2))),
2556             (UNPCKHPSrm VR128:$src1, addr:$src2)>;
2557   def : Pat<(v4f32 (X86Unpckh VR128:$src1, VR128:$src2)),
2558             (UNPCKHPSrr VR128:$src1, VR128:$src2)>;
2559 }
2560
2561 let Predicates = [HasSSE2] in {
2562   def : Pat<(v2f64 (X86Unpckl VR128:$src1, (memopv2f64 addr:$src2))),
2563             (UNPCKLPDrm VR128:$src1, addr:$src2)>;
2564   def : Pat<(v2f64 (X86Unpckl VR128:$src1, VR128:$src2)),
2565             (UNPCKLPDrr VR128:$src1, VR128:$src2)>;
2566   def : Pat<(v2f64 (X86Unpckh VR128:$src1, (memopv2f64 addr:$src2))),
2567             (UNPCKHPDrm VR128:$src1, addr:$src2)>;
2568   def : Pat<(v2f64 (X86Unpckh VR128:$src1, VR128:$src2)),
2569             (UNPCKHPDrr VR128:$src1, VR128:$src2)>;
2570
2571   // FIXME: Instead of X86Movddup, there should be a X86Unpckl here, the
2572   // problem is during lowering, where it's not possible to recognize the load
2573   // fold cause it has two uses through a bitcast. One use disappears at isel
2574   // time and the fold opportunity reappears.
2575   def : Pat<(v2f64 (X86Movddup VR128:$src)),
2576             (UNPCKLPDrr VR128:$src, VR128:$src)>;
2577
2578   let AddedComplexity = 10 in
2579   def : Pat<(splat_lo (v2f64 VR128:$src), (undef)),
2580             (UNPCKLPDrr VR128:$src, VR128:$src)>;
2581 }
2582
2583 //===----------------------------------------------------------------------===//
2584 // SSE 1 & 2 - Extract Floating-Point Sign mask
2585 //===----------------------------------------------------------------------===//
2586
2587 /// sse12_extr_sign_mask - sse 1 & 2 unpack and interleave
2588 multiclass sse12_extr_sign_mask<RegisterClass RC, Intrinsic Int, string asm,
2589                                 Domain d> {
2590   def rr32 : PI<0x50, MRMSrcReg, (outs GR32:$dst), (ins RC:$src),
2591                 !strconcat(asm, "\t{$src, $dst|$dst, $src}"),
2592                      [(set GR32:$dst, (Int RC:$src))], d>;
2593   def rr64 : PI<0x50, MRMSrcReg, (outs GR64:$dst), (ins RC:$src),
2594                 !strconcat(asm, "\t{$src, $dst|$dst, $src}"), [], d>, REX_W;
2595 }
2596
2597 let Predicates = [HasAVX] in {
2598   defm VMOVMSKPS : sse12_extr_sign_mask<VR128, int_x86_sse_movmsk_ps,
2599                                         "movmskps", SSEPackedSingle>, TB, VEX;
2600   defm VMOVMSKPD : sse12_extr_sign_mask<VR128, int_x86_sse2_movmsk_pd,
2601                                         "movmskpd", SSEPackedDouble>, TB,
2602                                         OpSize, VEX;
2603   defm VMOVMSKPSY : sse12_extr_sign_mask<VR256, int_x86_avx_movmsk_ps_256,
2604                                         "movmskps", SSEPackedSingle>, TB, VEX;
2605   defm VMOVMSKPDY : sse12_extr_sign_mask<VR256, int_x86_avx_movmsk_pd_256,
2606                                         "movmskpd", SSEPackedDouble>, TB,
2607                                         OpSize, VEX;
2608
2609   def : Pat<(i32 (X86fgetsign FR32:$src)),
2610             (VMOVMSKPSrr32 (INSERT_SUBREG (v4f32 (IMPLICIT_DEF)), FR32:$src,
2611                                           sub_ss))>;
2612   def : Pat<(i64 (X86fgetsign FR32:$src)),
2613             (VMOVMSKPSrr64 (INSERT_SUBREG (v4f32 (IMPLICIT_DEF)), FR32:$src,
2614                                           sub_ss))>;
2615   def : Pat<(i32 (X86fgetsign FR64:$src)),
2616             (VMOVMSKPDrr32 (INSERT_SUBREG (v2f64 (IMPLICIT_DEF)), FR64:$src,
2617                                           sub_sd))>;
2618   def : Pat<(i64 (X86fgetsign FR64:$src)),
2619             (VMOVMSKPDrr64 (INSERT_SUBREG (v2f64 (IMPLICIT_DEF)), FR64:$src,
2620                                           sub_sd))>;
2621
2622   // Assembler Only
2623   def VMOVMSKPSr64r : PI<0x50, MRMSrcReg, (outs GR64:$dst), (ins VR128:$src),
2624              "movmskps\t{$src, $dst|$dst, $src}", [], SSEPackedSingle>, TB, VEX;
2625   def VMOVMSKPDr64r : PI<0x50, MRMSrcReg, (outs GR64:$dst), (ins VR128:$src),
2626              "movmskpd\t{$src, $dst|$dst, $src}", [], SSEPackedDouble>, TB,
2627              OpSize, VEX;
2628   def VMOVMSKPSYr64r : PI<0x50, MRMSrcReg, (outs GR64:$dst), (ins VR256:$src),
2629              "movmskps\t{$src, $dst|$dst, $src}", [], SSEPackedSingle>, TB, VEX;
2630   def VMOVMSKPDYr64r : PI<0x50, MRMSrcReg, (outs GR64:$dst), (ins VR256:$src),
2631              "movmskpd\t{$src, $dst|$dst, $src}", [], SSEPackedDouble>, TB,
2632              OpSize, VEX;
2633 }
2634
2635 defm MOVMSKPS : sse12_extr_sign_mask<VR128, int_x86_sse_movmsk_ps, "movmskps",
2636                                      SSEPackedSingle>, TB;
2637 defm MOVMSKPD : sse12_extr_sign_mask<VR128, int_x86_sse2_movmsk_pd, "movmskpd",
2638                                      SSEPackedDouble>, TB, OpSize;
2639
2640 def : Pat<(i32 (X86fgetsign FR32:$src)),
2641           (MOVMSKPSrr32 (INSERT_SUBREG (v4f32 (IMPLICIT_DEF)), FR32:$src,
2642                                        sub_ss))>, Requires<[HasSSE1]>;
2643 def : Pat<(i64 (X86fgetsign FR32:$src)),
2644           (MOVMSKPSrr64 (INSERT_SUBREG (v4f32 (IMPLICIT_DEF)), FR32:$src,
2645                                        sub_ss))>, Requires<[HasSSE1]>;
2646 def : Pat<(i32 (X86fgetsign FR64:$src)),
2647           (MOVMSKPDrr32 (INSERT_SUBREG (v2f64 (IMPLICIT_DEF)), FR64:$src,
2648                                        sub_sd))>, Requires<[HasSSE2]>;
2649 def : Pat<(i64 (X86fgetsign FR64:$src)),
2650           (MOVMSKPDrr64 (INSERT_SUBREG (v2f64 (IMPLICIT_DEF)), FR64:$src,
2651                                        sub_sd))>, Requires<[HasSSE2]>;
2652
2653 //===---------------------------------------------------------------------===//
2654 // SSE2 - Packed Integer Logical Instructions
2655 //===---------------------------------------------------------------------===//
2656
2657 let ExeDomain = SSEPackedInt in { // SSE integer instructions
2658
2659 /// PDI_binop_rm - Simple SSE2 binary operator.
2660 multiclass PDI_binop_rm<bits<8> opc, string OpcodeStr, SDNode OpNode,
2661                         ValueType OpVT, RegisterClass RC, PatFrag memop_frag,
2662                         X86MemOperand x86memop, bit IsCommutable = 0,
2663                         bit Is2Addr = 1> {
2664   let isCommutable = IsCommutable in
2665   def rr : PDI<opc, MRMSrcReg, (outs RC:$dst),
2666        (ins RC:$src1, RC:$src2),
2667        !if(Is2Addr,
2668            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
2669            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
2670        [(set RC:$dst, (OpVT (OpNode RC:$src1, RC:$src2)))]>;
2671   def rm : PDI<opc, MRMSrcMem, (outs RC:$dst),
2672        (ins RC:$src1, x86memop:$src2),
2673        !if(Is2Addr,
2674            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
2675            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
2676        [(set RC:$dst, (OpVT (OpNode RC:$src1,
2677                                      (bitconvert (memop_frag addr:$src2)))))]>;
2678 }
2679 } // ExeDomain = SSEPackedInt
2680
2681 // These are ordered here for pattern ordering requirements with the fp versions
2682
2683 let Predicates = [HasAVX] in {
2684 defm VPAND : PDI_binop_rm<0xDB, "vpand", and, v2i64, VR128, memopv2i64,
2685                           i128mem, 1, 0>, VEX_4V;
2686 defm VPOR  : PDI_binop_rm<0xEB, "vpor" , or, v2i64, VR128, memopv2i64,
2687                           i128mem, 1, 0>, VEX_4V;
2688 defm VPXOR : PDI_binop_rm<0xEF, "vpxor", xor, v2i64, VR128, memopv2i64,
2689                           i128mem, 1, 0>, VEX_4V;
2690 defm VPANDN : PDI_binop_rm<0xDF, "vpandn", X86andnp, v2i64, VR128, memopv2i64,
2691                           i128mem, 0, 0>, VEX_4V;
2692 }
2693
2694 let Constraints = "$src1 = $dst" in {
2695 defm PAND : PDI_binop_rm<0xDB, "pand", and, v2i64, VR128, memopv2i64,
2696                          i128mem, 1>;
2697 defm POR  : PDI_binop_rm<0xEB, "por" , or, v2i64, VR128, memopv2i64,
2698                          i128mem, 1>;
2699 defm PXOR : PDI_binop_rm<0xEF, "pxor", xor, v2i64, VR128, memopv2i64,
2700                          i128mem, 1>;
2701 defm PANDN : PDI_binop_rm<0xDF, "pandn", X86andnp, v2i64, VR128, memopv2i64,
2702                           i128mem, 0>;
2703 } // Constraints = "$src1 = $dst"
2704
2705 let Predicates = [HasAVX2] in {
2706 defm VPANDY : PDI_binop_rm<0xDB, "vpand", and, v4i64, VR256, memopv4i64,
2707                            i256mem, 1, 0>, VEX_4V;
2708 defm VPORY  : PDI_binop_rm<0xEB, "vpor", or, v4i64, VR256, memopv4i64,
2709                            i256mem, 1, 0>, VEX_4V;
2710 defm VPXORY : PDI_binop_rm<0xEF, "vpxor", xor, v4i64, VR256, memopv4i64,
2711                            i256mem, 1, 0>, VEX_4V;
2712 defm VPANDNY : PDI_binop_rm<0xDF, "vpandn", X86andnp, v4i64, VR256, memopv4i64,
2713                             i256mem, 0, 0>, VEX_4V;
2714 }
2715
2716 //===----------------------------------------------------------------------===//
2717 // SSE 1 & 2 - Logical Instructions
2718 //===----------------------------------------------------------------------===//
2719
2720 /// sse12_fp_alias_pack_logical - SSE 1 & 2 aliased packed FP logical ops
2721 ///
2722 multiclass sse12_fp_alias_pack_logical<bits<8> opc, string OpcodeStr,
2723                                        SDNode OpNode> {
2724   defm V#NAME#PS : sse12_fp_packed<opc, !strconcat(OpcodeStr, "ps"), OpNode,
2725               FR32, f32, f128mem, memopfsf32, SSEPackedSingle, 0>, TB, VEX_4V;
2726
2727   defm V#NAME#PD : sse12_fp_packed<opc, !strconcat(OpcodeStr, "pd"), OpNode,
2728         FR64, f64, f128mem, memopfsf64, SSEPackedDouble, 0>, TB, OpSize, VEX_4V;
2729
2730   let Constraints = "$src1 = $dst" in {
2731     defm PS : sse12_fp_packed<opc, !strconcat(OpcodeStr, "ps"), OpNode, FR32,
2732                 f32, f128mem, memopfsf32, SSEPackedSingle>, TB;
2733
2734     defm PD : sse12_fp_packed<opc, !strconcat(OpcodeStr, "pd"), OpNode, FR64,
2735                 f64, f128mem, memopfsf64, SSEPackedDouble>, TB, OpSize;
2736   }
2737 }
2738
2739 // Alias bitwise logical operations using SSE logical ops on packed FP values.
2740 let mayLoad = 0 in {
2741   defm FsAND  : sse12_fp_alias_pack_logical<0x54, "and", X86fand>;
2742   defm FsOR   : sse12_fp_alias_pack_logical<0x56, "or", X86for>;
2743   defm FsXOR  : sse12_fp_alias_pack_logical<0x57, "xor", X86fxor>;
2744 }
2745
2746 let neverHasSideEffects = 1, Pattern = []<dag>, isCommutable = 0 in
2747   defm FsANDN : sse12_fp_alias_pack_logical<0x55, "andn", undef>;
2748
2749 /// sse12_fp_packed_logical - SSE 1 & 2 packed FP logical ops
2750 ///
2751 multiclass sse12_fp_packed_logical<bits<8> opc, string OpcodeStr,
2752                                    SDNode OpNode> {
2753   // In AVX no need to add a pattern for 128-bit logical rr ps, because they
2754   // are all promoted to v2i64, and the patterns are covered by the int
2755   // version. This is needed in SSE only, because v2i64 isn't supported on
2756   // SSE1, but only on SSE2.
2757   defm V#NAME#PS : sse12_fp_packed_logical_rm<opc, VR128, SSEPackedSingle,
2758        !strconcat(OpcodeStr, "ps"), f128mem, [],
2759        [(set VR128:$dst, (OpNode (bc_v2i64 (v4f32 VR128:$src1)),
2760                                  (memopv2i64 addr:$src2)))], 0, 1>, TB, VEX_4V;
2761
2762   defm V#NAME#PD : sse12_fp_packed_logical_rm<opc, VR128, SSEPackedDouble,
2763        !strconcat(OpcodeStr, "pd"), f128mem,
2764        [(set VR128:$dst, (OpNode (bc_v2i64 (v2f64 VR128:$src1)),
2765                                  (bc_v2i64 (v2f64 VR128:$src2))))],
2766        [(set VR128:$dst, (OpNode (bc_v2i64 (v2f64 VR128:$src1)),
2767                                  (memopv2i64 addr:$src2)))], 0>,
2768                                                  TB, OpSize, VEX_4V;
2769   let Constraints = "$src1 = $dst" in {
2770     defm PS : sse12_fp_packed_logical_rm<opc, VR128, SSEPackedSingle,
2771          !strconcat(OpcodeStr, "ps"), f128mem,
2772          [(set VR128:$dst, (v2i64 (OpNode VR128:$src1, VR128:$src2)))],
2773          [(set VR128:$dst, (OpNode (bc_v2i64 (v4f32 VR128:$src1)),
2774                                    (memopv2i64 addr:$src2)))]>, TB;
2775
2776     defm PD : sse12_fp_packed_logical_rm<opc, VR128, SSEPackedDouble,
2777          !strconcat(OpcodeStr, "pd"), f128mem,
2778          [(set VR128:$dst, (OpNode (bc_v2i64 (v2f64 VR128:$src1)),
2779                                    (bc_v2i64 (v2f64 VR128:$src2))))],
2780          [(set VR128:$dst, (OpNode (bc_v2i64 (v2f64 VR128:$src1)),
2781                                    (memopv2i64 addr:$src2)))]>, TB, OpSize;
2782   }
2783 }
2784
2785 /// sse12_fp_packed_logical_y - AVX 256-bit SSE 1 & 2 logical ops forms
2786 ///
2787 multiclass sse12_fp_packed_logical_y<bits<8> opc, string OpcodeStr,
2788                                      SDNode OpNode> {
2789     defm PSY : sse12_fp_packed_logical_rm<opc, VR256, SSEPackedSingle,
2790           !strconcat(OpcodeStr, "ps"), f256mem,
2791           [(set VR256:$dst, (v4i64 (OpNode VR256:$src1, VR256:$src2)))],
2792           [(set VR256:$dst, (OpNode (bc_v4i64 (v8f32 VR256:$src1)),
2793                                     (memopv4i64 addr:$src2)))], 0>, TB, VEX_4V;
2794
2795     defm PDY : sse12_fp_packed_logical_rm<opc, VR256, SSEPackedDouble,
2796           !strconcat(OpcodeStr, "pd"), f256mem,
2797           [(set VR256:$dst, (OpNode (bc_v4i64 (v4f64 VR256:$src1)),
2798                                     (bc_v4i64 (v4f64 VR256:$src2))))],
2799           [(set VR256:$dst, (OpNode (bc_v4i64 (v4f64 VR256:$src1)),
2800                                     (memopv4i64 addr:$src2)))], 0>,
2801                                     TB, OpSize, VEX_4V;
2802 }
2803
2804 // AVX 256-bit packed logical ops forms
2805 defm VAND  : sse12_fp_packed_logical_y<0x54, "and", and>;
2806 defm VOR   : sse12_fp_packed_logical_y<0x56, "or", or>;
2807 defm VXOR  : sse12_fp_packed_logical_y<0x57, "xor", xor>;
2808 defm VANDN : sse12_fp_packed_logical_y<0x55, "andn", X86andnp>;
2809
2810 defm AND  : sse12_fp_packed_logical<0x54, "and", and>;
2811 defm OR   : sse12_fp_packed_logical<0x56, "or", or>;
2812 defm XOR  : sse12_fp_packed_logical<0x57, "xor", xor>;
2813 let isCommutable = 0 in
2814   defm ANDN : sse12_fp_packed_logical<0x55, "andn", X86andnp>;
2815
2816 //===----------------------------------------------------------------------===//
2817 // SSE 1 & 2 - Arithmetic Instructions
2818 //===----------------------------------------------------------------------===//
2819
2820 /// basic_sse12_fp_binop_xxx - SSE 1 & 2 binops come in both scalar and
2821 /// vector forms.
2822 ///
2823 /// In addition, we also have a special variant of the scalar form here to
2824 /// represent the associated intrinsic operation.  This form is unlike the
2825 /// plain scalar form, in that it takes an entire vector (instead of a scalar)
2826 /// and leaves the top elements unmodified (therefore these cannot be commuted).
2827 ///
2828 /// These three forms can each be reg+reg or reg+mem.
2829 ///
2830
2831 /// FIXME: once all 256-bit intrinsics are matched, cleanup and refactor those
2832 /// classes below
2833 multiclass basic_sse12_fp_binop_s<bits<8> opc, string OpcodeStr, SDNode OpNode,
2834                                   bit Is2Addr = 1> {
2835   defm SS : sse12_fp_scalar<opc, !strconcat(OpcodeStr, "ss"),
2836                             OpNode, FR32, f32mem, Is2Addr>, XS;
2837   defm SD : sse12_fp_scalar<opc, !strconcat(OpcodeStr, "sd"),
2838                             OpNode, FR64, f64mem, Is2Addr>, XD;
2839 }
2840
2841 multiclass basic_sse12_fp_binop_p<bits<8> opc, string OpcodeStr, SDNode OpNode,
2842                                    bit Is2Addr = 1> {
2843   let mayLoad = 0 in {
2844   defm PS : sse12_fp_packed<opc, !strconcat(OpcodeStr, "ps"), OpNode, VR128,
2845               v4f32, f128mem, memopv4f32, SSEPackedSingle, Is2Addr>, TB;
2846   defm PD : sse12_fp_packed<opc, !strconcat(OpcodeStr, "pd"), OpNode, VR128,
2847               v2f64, f128mem, memopv2f64, SSEPackedDouble, Is2Addr>, TB, OpSize;
2848   }
2849 }
2850
2851 multiclass basic_sse12_fp_binop_p_y<bits<8> opc, string OpcodeStr,
2852                                     SDNode OpNode> {
2853   let mayLoad = 0 in {
2854     defm PSY : sse12_fp_packed<opc, !strconcat(OpcodeStr, "ps"), OpNode, VR256,
2855                 v8f32, f256mem, memopv8f32, SSEPackedSingle, 0>, TB;
2856     defm PDY : sse12_fp_packed<opc, !strconcat(OpcodeStr, "pd"), OpNode, VR256,
2857                 v4f64, f256mem, memopv4f64, SSEPackedDouble, 0>, TB, OpSize;
2858   }
2859 }
2860
2861 multiclass basic_sse12_fp_binop_s_int<bits<8> opc, string OpcodeStr,
2862                                       bit Is2Addr = 1> {
2863   defm SS : sse12_fp_scalar_int<opc, OpcodeStr, VR128,
2864      !strconcat(OpcodeStr, "ss"), "", "_ss", ssmem, sse_load_f32, Is2Addr>, XS;
2865   defm SD : sse12_fp_scalar_int<opc, OpcodeStr, VR128,
2866      !strconcat(OpcodeStr, "sd"), "2", "_sd", sdmem, sse_load_f64, Is2Addr>, XD;
2867 }
2868
2869 multiclass basic_sse12_fp_binop_p_int<bits<8> opc, string OpcodeStr,
2870                                       bit Is2Addr = 1> {
2871   defm PS : sse12_fp_packed_int<opc, OpcodeStr, VR128,
2872      !strconcat(OpcodeStr, "ps"), "sse", "_ps", f128mem, memopv4f32,
2873                                               SSEPackedSingle, Is2Addr>, TB;
2874
2875   defm PD : sse12_fp_packed_int<opc, OpcodeStr, VR128,
2876      !strconcat(OpcodeStr, "pd"), "sse2", "_pd", f128mem, memopv2f64,
2877                                       SSEPackedDouble, Is2Addr>, TB, OpSize;
2878 }
2879
2880 multiclass basic_sse12_fp_binop_p_y_int<bits<8> opc, string OpcodeStr> {
2881   defm PSY : sse12_fp_packed_int<opc, OpcodeStr, VR256,
2882      !strconcat(OpcodeStr, "ps"), "avx", "_ps_256", f256mem, memopv8f32,
2883       SSEPackedSingle, 0>, TB;
2884
2885   defm PDY : sse12_fp_packed_int<opc, OpcodeStr, VR256,
2886      !strconcat(OpcodeStr, "pd"), "avx", "_pd_256", f256mem, memopv4f64,
2887       SSEPackedDouble, 0>, TB, OpSize;
2888 }
2889
2890 // Binary Arithmetic instructions
2891 defm VADD : basic_sse12_fp_binop_s<0x58, "add", fadd, 0>,
2892             basic_sse12_fp_binop_s_int<0x58, "add", 0>, VEX_4V, VEX_LIG;
2893 defm VADD : basic_sse12_fp_binop_p<0x58, "add", fadd, 0>,
2894             basic_sse12_fp_binop_p_y<0x58, "add", fadd>, VEX_4V;
2895 defm VMUL : basic_sse12_fp_binop_s<0x59, "mul", fmul, 0>,
2896             basic_sse12_fp_binop_s_int<0x59, "mul", 0>, VEX_4V, VEX_LIG;
2897 defm VMUL : basic_sse12_fp_binop_p<0x59, "mul", fmul, 0>,
2898             basic_sse12_fp_binop_p_y<0x59, "mul", fmul>, VEX_4V;
2899
2900 let isCommutable = 0 in {
2901   defm VSUB : basic_sse12_fp_binop_s<0x5C, "sub", fsub, 0>,
2902               basic_sse12_fp_binop_s_int<0x5C, "sub", 0>, VEX_4V, VEX_LIG;
2903   defm VSUB : basic_sse12_fp_binop_p<0x5C, "sub", fsub, 0>,
2904               basic_sse12_fp_binop_p_y<0x5C, "sub", fsub>, VEX_4V;
2905   defm VDIV : basic_sse12_fp_binop_s<0x5E, "div", fdiv, 0>,
2906               basic_sse12_fp_binop_s_int<0x5E, "div", 0>, VEX_4V, VEX_LIG;
2907   defm VDIV : basic_sse12_fp_binop_p<0x5E, "div", fdiv, 0>,
2908               basic_sse12_fp_binop_p_y<0x5E, "div", fdiv>, VEX_4V;
2909   defm VMAX : basic_sse12_fp_binop_s<0x5F, "max", X86fmax, 0>,
2910               basic_sse12_fp_binop_s_int<0x5F, "max", 0>, VEX_4V, VEX_LIG;
2911   defm VMAX : basic_sse12_fp_binop_p<0x5F, "max", X86fmax, 0>,
2912               basic_sse12_fp_binop_p_int<0x5F, "max", 0>,
2913               basic_sse12_fp_binop_p_y<0x5F, "max", X86fmax>,
2914               basic_sse12_fp_binop_p_y_int<0x5F, "max">, VEX_4V;
2915   defm VMIN : basic_sse12_fp_binop_s<0x5D, "min", X86fmin, 0>,
2916               basic_sse12_fp_binop_s_int<0x5D, "min", 0>, VEX_4V, VEX_LIG;
2917   defm VMIN : basic_sse12_fp_binop_p<0x5D, "min", X86fmin, 0>,
2918               basic_sse12_fp_binop_p_int<0x5D, "min", 0>,
2919               basic_sse12_fp_binop_p_y_int<0x5D, "min">,
2920               basic_sse12_fp_binop_p_y<0x5D, "min", X86fmin>, VEX_4V;
2921 }
2922
2923 let Constraints = "$src1 = $dst" in {
2924   defm ADD : basic_sse12_fp_binop_s<0x58, "add", fadd>,
2925              basic_sse12_fp_binop_p<0x58, "add", fadd>,
2926              basic_sse12_fp_binop_s_int<0x58, "add">;
2927   defm MUL : basic_sse12_fp_binop_s<0x59, "mul", fmul>,
2928              basic_sse12_fp_binop_p<0x59, "mul", fmul>,
2929              basic_sse12_fp_binop_s_int<0x59, "mul">;
2930
2931   let isCommutable = 0 in {
2932     defm SUB : basic_sse12_fp_binop_s<0x5C, "sub", fsub>,
2933                basic_sse12_fp_binop_p<0x5C, "sub", fsub>,
2934                basic_sse12_fp_binop_s_int<0x5C, "sub">;
2935     defm DIV : basic_sse12_fp_binop_s<0x5E, "div", fdiv>,
2936                basic_sse12_fp_binop_p<0x5E, "div", fdiv>,
2937                basic_sse12_fp_binop_s_int<0x5E, "div">;
2938     defm MAX : basic_sse12_fp_binop_s<0x5F, "max", X86fmax>,
2939                basic_sse12_fp_binop_p<0x5F, "max", X86fmax>,
2940                basic_sse12_fp_binop_s_int<0x5F, "max">,
2941                basic_sse12_fp_binop_p_int<0x5F, "max">;
2942     defm MIN : basic_sse12_fp_binop_s<0x5D, "min", X86fmin>,
2943                basic_sse12_fp_binop_p<0x5D, "min", X86fmin>,
2944                basic_sse12_fp_binop_s_int<0x5D, "min">,
2945                basic_sse12_fp_binop_p_int<0x5D, "min">;
2946   }
2947 }
2948
2949 /// Unop Arithmetic
2950 /// In addition, we also have a special variant of the scalar form here to
2951 /// represent the associated intrinsic operation.  This form is unlike the
2952 /// plain scalar form, in that it takes an entire vector (instead of a
2953 /// scalar) and leaves the top elements undefined.
2954 ///
2955 /// And, we have a special variant form for a full-vector intrinsic form.
2956
2957 /// sse1_fp_unop_s - SSE1 unops in scalar form.
2958 multiclass sse1_fp_unop_s<bits<8> opc, string OpcodeStr,
2959                           SDNode OpNode, Intrinsic F32Int> {
2960   def SSr : SSI<opc, MRMSrcReg, (outs FR32:$dst), (ins FR32:$src),
2961                 !strconcat(OpcodeStr, "ss\t{$src, $dst|$dst, $src}"),
2962                 [(set FR32:$dst, (OpNode FR32:$src))]>;
2963   // For scalar unary operations, fold a load into the operation
2964   // only in OptForSize mode. It eliminates an instruction, but it also
2965   // eliminates a whole-register clobber (the load), so it introduces a
2966   // partial register update condition.
2967   def SSm : I<opc, MRMSrcMem, (outs FR32:$dst), (ins f32mem:$src),
2968                 !strconcat(OpcodeStr, "ss\t{$src, $dst|$dst, $src}"),
2969                 [(set FR32:$dst, (OpNode (load addr:$src)))]>, XS,
2970             Requires<[HasSSE1, OptForSize]>;
2971   def SSr_Int : SSI<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2972                     !strconcat(OpcodeStr, "ss\t{$src, $dst|$dst, $src}"),
2973                     [(set VR128:$dst, (F32Int VR128:$src))]>;
2974   def SSm_Int : SSI<opc, MRMSrcMem, (outs VR128:$dst), (ins ssmem:$src),
2975                     !strconcat(OpcodeStr, "ss\t{$src, $dst|$dst, $src}"),
2976                     [(set VR128:$dst, (F32Int sse_load_f32:$src))]>;
2977 }
2978
2979 /// sse1_fp_unop_s_avx - AVX SSE1 unops in scalar form.
2980 multiclass sse1_fp_unop_s_avx<bits<8> opc, string OpcodeStr> {
2981   def SSr : SSI<opc, MRMSrcReg, (outs FR32:$dst), (ins FR32:$src1, FR32:$src2),
2982                 !strconcat(OpcodeStr,
2983                            "ss\t{$src2, $src1, $dst|$dst, $src1, $src2}"), []>;
2984   let mayLoad = 1 in
2985   def SSm : SSI<opc, MRMSrcMem, (outs FR32:$dst), (ins FR32:$src1,f32mem:$src2),
2986                 !strconcat(OpcodeStr,
2987                            "ss\t{$src2, $src1, $dst|$dst, $src1, $src2}"), []>;
2988   def SSm_Int : SSI<opc, MRMSrcMem, (outs VR128:$dst),
2989                 (ins VR128:$src1, ssmem:$src2),
2990                 !strconcat(OpcodeStr,
2991                            "ss\t{$src2, $src1, $dst|$dst, $src1, $src2}"), []>;
2992 }
2993
2994 /// sse1_fp_unop_p - SSE1 unops in packed form.
2995 multiclass sse1_fp_unop_p<bits<8> opc, string OpcodeStr, SDNode OpNode> {
2996   def PSr : PSI<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2997               !strconcat(OpcodeStr, "ps\t{$src, $dst|$dst, $src}"),
2998               [(set VR128:$dst, (v4f32 (OpNode VR128:$src)))]>;
2999   def PSm : PSI<opc, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
3000                 !strconcat(OpcodeStr, "ps\t{$src, $dst|$dst, $src}"),
3001                 [(set VR128:$dst, (OpNode (memopv4f32 addr:$src)))]>;
3002 }
3003
3004 /// sse1_fp_unop_p_y - AVX 256-bit SSE1 unops in packed form.
3005 multiclass sse1_fp_unop_p_y<bits<8> opc, string OpcodeStr, SDNode OpNode> {
3006   def PSYr : PSI<opc, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
3007               !strconcat(OpcodeStr, "ps\t{$src, $dst|$dst, $src}"),
3008               [(set VR256:$dst, (v8f32 (OpNode VR256:$src)))]>;
3009   def PSYm : PSI<opc, MRMSrcMem, (outs VR256:$dst), (ins f256mem:$src),
3010                 !strconcat(OpcodeStr, "ps\t{$src, $dst|$dst, $src}"),
3011                 [(set VR256:$dst, (OpNode (memopv8f32 addr:$src)))]>;
3012 }
3013
3014 /// sse1_fp_unop_p_int - SSE1 intrinsics unops in packed forms.
3015 multiclass sse1_fp_unop_p_int<bits<8> opc, string OpcodeStr,
3016                               Intrinsic V4F32Int> {
3017   def PSr_Int : PSI<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3018                     !strconcat(OpcodeStr, "ps\t{$src, $dst|$dst, $src}"),
3019                     [(set VR128:$dst, (V4F32Int VR128:$src))]>;
3020   def PSm_Int : PSI<opc, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
3021                     !strconcat(OpcodeStr, "ps\t{$src, $dst|$dst, $src}"),
3022                     [(set VR128:$dst, (V4F32Int (memopv4f32 addr:$src)))]>;
3023 }
3024
3025 /// sse1_fp_unop_p_y_int - AVX 256-bit intrinsics unops in packed forms.
3026 multiclass sse1_fp_unop_p_y_int<bits<8> opc, string OpcodeStr,
3027                                 Intrinsic V4F32Int> {
3028   def PSYr_Int : PSI<opc, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
3029                     !strconcat(OpcodeStr, "ps\t{$src, $dst|$dst, $src}"),
3030                     [(set VR256:$dst, (V4F32Int VR256:$src))]>;
3031   def PSYm_Int : PSI<opc, MRMSrcMem, (outs VR256:$dst), (ins f256mem:$src),
3032                     !strconcat(OpcodeStr, "ps\t{$src, $dst|$dst, $src}"),
3033                     [(set VR256:$dst, (V4F32Int (memopv8f32 addr:$src)))]>;
3034 }
3035
3036 /// sse2_fp_unop_s - SSE2 unops in scalar form.
3037 multiclass sse2_fp_unop_s<bits<8> opc, string OpcodeStr,
3038                           SDNode OpNode, Intrinsic F64Int> {
3039   def SDr : SDI<opc, MRMSrcReg, (outs FR64:$dst), (ins FR64:$src),
3040                 !strconcat(OpcodeStr, "sd\t{$src, $dst|$dst, $src}"),
3041                 [(set FR64:$dst, (OpNode FR64:$src))]>;
3042   // See the comments in sse1_fp_unop_s for why this is OptForSize.
3043   def SDm : I<opc, MRMSrcMem, (outs FR64:$dst), (ins f64mem:$src),
3044                 !strconcat(OpcodeStr, "sd\t{$src, $dst|$dst, $src}"),
3045                 [(set FR64:$dst, (OpNode (load addr:$src)))]>, XD,
3046             Requires<[HasSSE2, OptForSize]>;
3047   def SDr_Int : SDI<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3048                     !strconcat(OpcodeStr, "sd\t{$src, $dst|$dst, $src}"),
3049                     [(set VR128:$dst, (F64Int VR128:$src))]>;
3050   def SDm_Int : SDI<opc, MRMSrcMem, (outs VR128:$dst), (ins sdmem:$src),
3051                     !strconcat(OpcodeStr, "sd\t{$src, $dst|$dst, $src}"),
3052                     [(set VR128:$dst, (F64Int sse_load_f64:$src))]>;
3053 }
3054
3055 /// sse2_fp_unop_s_avx - AVX SSE2 unops in scalar form.
3056 multiclass sse2_fp_unop_s_avx<bits<8> opc, string OpcodeStr> {
3057   let neverHasSideEffects = 1 in {
3058   def SDr : SDI<opc, MRMSrcReg, (outs FR64:$dst), (ins FR64:$src1, FR64:$src2),
3059                !strconcat(OpcodeStr,
3060                           "sd\t{$src2, $src1, $dst|$dst, $src1, $src2}"), []>;
3061   let mayLoad = 1 in
3062   def SDm : SDI<opc, MRMSrcMem, (outs FR64:$dst), (ins FR64:$src1,f64mem:$src2),
3063                !strconcat(OpcodeStr,
3064                           "sd\t{$src2, $src1, $dst|$dst, $src1, $src2}"), []>;
3065   }
3066   def SDm_Int : SDI<opc, MRMSrcMem, (outs VR128:$dst),
3067                (ins VR128:$src1, sdmem:$src2),
3068                !strconcat(OpcodeStr,
3069                           "sd\t{$src2, $src1, $dst|$dst, $src1, $src2}"), []>;
3070 }
3071
3072 /// sse2_fp_unop_p - SSE2 unops in vector forms.
3073 multiclass sse2_fp_unop_p<bits<8> opc, string OpcodeStr,
3074                           SDNode OpNode> {
3075   def PDr : PDI<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3076               !strconcat(OpcodeStr, "pd\t{$src, $dst|$dst, $src}"),
3077               [(set VR128:$dst, (v2f64 (OpNode VR128:$src)))]>;
3078   def PDm : PDI<opc, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
3079                 !strconcat(OpcodeStr, "pd\t{$src, $dst|$dst, $src}"),
3080                 [(set VR128:$dst, (OpNode (memopv2f64 addr:$src)))]>;
3081 }
3082
3083 /// sse2_fp_unop_p_y - AVX SSE2 256-bit unops in vector forms.
3084 multiclass sse2_fp_unop_p_y<bits<8> opc, string OpcodeStr, SDNode OpNode> {
3085   def PDYr : PDI<opc, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
3086               !strconcat(OpcodeStr, "pd\t{$src, $dst|$dst, $src}"),
3087               [(set VR256:$dst, (v4f64 (OpNode VR256:$src)))]>;
3088   def PDYm : PDI<opc, MRMSrcMem, (outs VR256:$dst), (ins f256mem:$src),
3089                 !strconcat(OpcodeStr, "pd\t{$src, $dst|$dst, $src}"),
3090                 [(set VR256:$dst, (OpNode (memopv4f64 addr:$src)))]>;
3091 }
3092
3093 /// sse2_fp_unop_p_int - SSE2 intrinsic unops in vector forms.
3094 multiclass sse2_fp_unop_p_int<bits<8> opc, string OpcodeStr,
3095                               Intrinsic V2F64Int> {
3096   def PDr_Int : PDI<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3097                     !strconcat(OpcodeStr, "pd\t{$src, $dst|$dst, $src}"),
3098                     [(set VR128:$dst, (V2F64Int VR128:$src))]>;
3099   def PDm_Int : PDI<opc, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
3100                     !strconcat(OpcodeStr, "pd\t{$src, $dst|$dst, $src}"),
3101                     [(set VR128:$dst, (V2F64Int (memopv2f64 addr:$src)))]>;
3102 }
3103
3104 /// sse2_fp_unop_p_y_int - AVX 256-bit intrinsic unops in vector forms.
3105 multiclass sse2_fp_unop_p_y_int<bits<8> opc, string OpcodeStr,
3106                                 Intrinsic V2F64Int> {
3107   def PDYr_Int : PDI<opc, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
3108                     !strconcat(OpcodeStr, "pd\t{$src, $dst|$dst, $src}"),
3109                     [(set VR256:$dst, (V2F64Int VR256:$src))]>;
3110   def PDYm_Int : PDI<opc, MRMSrcMem, (outs VR256:$dst), (ins f256mem:$src),
3111                     !strconcat(OpcodeStr, "pd\t{$src, $dst|$dst, $src}"),
3112                     [(set VR256:$dst, (V2F64Int (memopv4f64 addr:$src)))]>;
3113 }
3114
3115 let Predicates = [HasAVX] in {
3116   // Square root.
3117   defm VSQRT  : sse1_fp_unop_s_avx<0x51, "vsqrt">,
3118                 sse2_fp_unop_s_avx<0x51, "vsqrt">, VEX_4V, VEX_LIG;
3119
3120   defm VSQRT  : sse1_fp_unop_p<0x51, "vsqrt", fsqrt>,
3121                 sse2_fp_unop_p<0x51, "vsqrt", fsqrt>,
3122                 sse1_fp_unop_p_y<0x51, "vsqrt", fsqrt>,
3123                 sse2_fp_unop_p_y<0x51, "vsqrt", fsqrt>,
3124                 sse1_fp_unop_p_int<0x51, "vsqrt", int_x86_sse_sqrt_ps>,
3125                 sse2_fp_unop_p_int<0x51, "vsqrt", int_x86_sse2_sqrt_pd>,
3126                 sse1_fp_unop_p_y_int<0x51, "vsqrt", int_x86_avx_sqrt_ps_256>,
3127                 sse2_fp_unop_p_y_int<0x51, "vsqrt", int_x86_avx_sqrt_pd_256>,
3128                 VEX;
3129
3130   // Reciprocal approximations. Note that these typically require refinement
3131   // in order to obtain suitable precision.
3132   defm VRSQRT : sse1_fp_unop_s_avx<0x52, "vrsqrt">, VEX_4V, VEX_LIG;
3133   defm VRSQRT : sse1_fp_unop_p<0x52, "vrsqrt", X86frsqrt>,
3134                 sse1_fp_unop_p_y<0x52, "vrsqrt", X86frsqrt>,
3135                 sse1_fp_unop_p_y_int<0x52, "vrsqrt", int_x86_avx_rsqrt_ps_256>,
3136                 sse1_fp_unop_p_int<0x52, "vrsqrt", int_x86_sse_rsqrt_ps>, VEX;
3137
3138   defm VRCP   : sse1_fp_unop_s_avx<0x53, "vrcp">, VEX_4V, VEX_LIG;
3139   defm VRCP   : sse1_fp_unop_p<0x53, "vrcp", X86frcp>,
3140                 sse1_fp_unop_p_y<0x53, "vrcp", X86frcp>,
3141                 sse1_fp_unop_p_y_int<0x53, "vrcp", int_x86_avx_rcp_ps_256>,
3142                 sse1_fp_unop_p_int<0x53, "vrcp", int_x86_sse_rcp_ps>, VEX;
3143 }
3144
3145 let AddedComplexity = 1 in {
3146 def : Pat<(f32 (fsqrt FR32:$src)),
3147           (VSQRTSSr (f32 (IMPLICIT_DEF)), FR32:$src)>, Requires<[HasAVX]>;
3148 def : Pat<(f32 (fsqrt (load addr:$src))),
3149           (VSQRTSSm (f32 (IMPLICIT_DEF)), addr:$src)>,
3150           Requires<[HasAVX, OptForSize]>;
3151 def : Pat<(f64 (fsqrt FR64:$src)),
3152           (VSQRTSDr (f64 (IMPLICIT_DEF)), FR64:$src)>, Requires<[HasAVX]>;
3153 def : Pat<(f64 (fsqrt (load addr:$src))),
3154           (VSQRTSDm (f64 (IMPLICIT_DEF)), addr:$src)>,
3155           Requires<[HasAVX, OptForSize]>;
3156
3157 def : Pat<(f32 (X86frsqrt FR32:$src)),
3158           (VRSQRTSSr (f32 (IMPLICIT_DEF)), FR32:$src)>, Requires<[HasAVX]>;
3159 def : Pat<(f32 (X86frsqrt (load addr:$src))),
3160           (VRSQRTSSm (f32 (IMPLICIT_DEF)), addr:$src)>,
3161           Requires<[HasAVX, OptForSize]>;
3162
3163 def : Pat<(f32 (X86frcp FR32:$src)),
3164           (VRCPSSr (f32 (IMPLICIT_DEF)), FR32:$src)>, Requires<[HasAVX]>;
3165 def : Pat<(f32 (X86frcp (load addr:$src))),
3166           (VRCPSSm (f32 (IMPLICIT_DEF)), addr:$src)>,
3167           Requires<[HasAVX, OptForSize]>;
3168 }
3169
3170 let Predicates = [HasAVX], AddedComplexity = 1 in {
3171   def : Pat<(int_x86_sse_sqrt_ss VR128:$src),
3172             (INSERT_SUBREG (v4f32 (IMPLICIT_DEF)),
3173                 (VSQRTSSr (f32 (IMPLICIT_DEF)),
3174                           (EXTRACT_SUBREG (v4f32 VR128:$src), sub_ss)),
3175                 sub_ss)>;
3176   def : Pat<(int_x86_sse_sqrt_ss sse_load_f32:$src),
3177             (VSQRTSSm_Int (v4f32 (IMPLICIT_DEF)), sse_load_f32:$src)>;
3178
3179   def : Pat<(int_x86_sse2_sqrt_sd VR128:$src),
3180             (INSERT_SUBREG (v2f64 (IMPLICIT_DEF)),
3181                 (VSQRTSDr (f64 (IMPLICIT_DEF)),
3182                           (EXTRACT_SUBREG (v2f64 VR128:$src), sub_sd)),
3183                 sub_sd)>;
3184   def : Pat<(int_x86_sse2_sqrt_sd sse_load_f64:$src),
3185             (VSQRTSDm_Int (v2f64 (IMPLICIT_DEF)), sse_load_f64:$src)>;
3186
3187   def : Pat<(int_x86_sse_rsqrt_ss VR128:$src),
3188             (INSERT_SUBREG (v4f32 (IMPLICIT_DEF)),
3189                 (VRSQRTSSr (f32 (IMPLICIT_DEF)),
3190                           (EXTRACT_SUBREG (v4f32 VR128:$src), sub_ss)),
3191                 sub_ss)>;
3192   def : Pat<(int_x86_sse_rsqrt_ss sse_load_f32:$src),
3193             (VRSQRTSSm_Int (v4f32 (IMPLICIT_DEF)), sse_load_f32:$src)>;
3194
3195   def : Pat<(int_x86_sse_rcp_ss VR128:$src),
3196             (INSERT_SUBREG (v4f32 (IMPLICIT_DEF)),
3197                 (VRCPSSr (f32 (IMPLICIT_DEF)),
3198                          (EXTRACT_SUBREG (v4f32 VR128:$src), sub_ss)),
3199                 sub_ss)>;
3200   def : Pat<(int_x86_sse_rcp_ss sse_load_f32:$src),
3201             (VRCPSSm_Int (v4f32 (IMPLICIT_DEF)), sse_load_f32:$src)>;
3202 }
3203
3204 // Square root.
3205 defm SQRT  : sse1_fp_unop_s<0x51, "sqrt",  fsqrt, int_x86_sse_sqrt_ss>,
3206              sse1_fp_unop_p<0x51, "sqrt",  fsqrt>,
3207              sse1_fp_unop_p_int<0x51, "sqrt",  int_x86_sse_sqrt_ps>,
3208              sse2_fp_unop_s<0x51, "sqrt",  fsqrt, int_x86_sse2_sqrt_sd>,
3209              sse2_fp_unop_p<0x51, "sqrt",  fsqrt>,
3210              sse2_fp_unop_p_int<0x51, "sqrt", int_x86_sse2_sqrt_pd>;
3211
3212 // Reciprocal approximations. Note that these typically require refinement
3213 // in order to obtain suitable precision.
3214 defm RSQRT : sse1_fp_unop_s<0x52, "rsqrt", X86frsqrt, int_x86_sse_rsqrt_ss>,
3215              sse1_fp_unop_p<0x52, "rsqrt", X86frsqrt>,
3216              sse1_fp_unop_p_int<0x52, "rsqrt", int_x86_sse_rsqrt_ps>;
3217 defm RCP   : sse1_fp_unop_s<0x53, "rcp", X86frcp, int_x86_sse_rcp_ss>,
3218              sse1_fp_unop_p<0x53, "rcp", X86frcp>,
3219              sse1_fp_unop_p_int<0x53, "rcp", int_x86_sse_rcp_ps>;
3220
3221 // There is no f64 version of the reciprocal approximation instructions.
3222
3223 //===----------------------------------------------------------------------===//
3224 // SSE 1 & 2 - Non-temporal stores
3225 //===----------------------------------------------------------------------===//
3226
3227 let AddedComplexity = 400 in { // Prefer non-temporal versions
3228   def VMOVNTPSmr : VPSI<0x2B, MRMDestMem, (outs),
3229                        (ins f128mem:$dst, VR128:$src),
3230                        "movntps\t{$src, $dst|$dst, $src}",
3231                        [(alignednontemporalstore (v4f32 VR128:$src),
3232                                                  addr:$dst)]>, VEX;
3233   def VMOVNTPDmr : VPDI<0x2B, MRMDestMem, (outs),
3234                        (ins f128mem:$dst, VR128:$src),
3235                        "movntpd\t{$src, $dst|$dst, $src}",
3236                        [(alignednontemporalstore (v2f64 VR128:$src),
3237                                                  addr:$dst)]>, VEX;
3238
3239   let ExeDomain = SSEPackedInt in
3240   def VMOVNTDQmr    : VPDI<0xE7, MRMDestMem, (outs),
3241                            (ins f128mem:$dst, VR128:$src),
3242                            "movntdq\t{$src, $dst|$dst, $src}",
3243                            [(alignednontemporalstore (v2i64 VR128:$src),
3244                                                      addr:$dst)]>, VEX;
3245
3246   def : Pat<(alignednontemporalstore (v2i64 VR128:$src), addr:$dst),
3247             (VMOVNTDQmr addr:$dst, VR128:$src)>, Requires<[HasAVX]>;
3248
3249   def VMOVNTPSYmr : VPSI<0x2B, MRMDestMem, (outs),
3250                        (ins f256mem:$dst, VR256:$src),
3251                        "movntps\t{$src, $dst|$dst, $src}",
3252                        [(alignednontemporalstore (v8f32 VR256:$src),
3253                                                  addr:$dst)]>, VEX;
3254   def VMOVNTPDYmr : VPDI<0x2B, MRMDestMem, (outs),
3255                        (ins f256mem:$dst, VR256:$src),
3256                        "movntpd\t{$src, $dst|$dst, $src}",
3257                        [(alignednontemporalstore (v4f64 VR256:$src),
3258                                                  addr:$dst)]>, VEX;
3259   let ExeDomain = SSEPackedInt in
3260   def VMOVNTDQYmr : VPDI<0xE7, MRMDestMem, (outs),
3261                       (ins f256mem:$dst, VR256:$src),
3262                       "movntdq\t{$src, $dst|$dst, $src}",
3263                       [(alignednontemporalstore (v4i64 VR256:$src),
3264                                                 addr:$dst)]>, VEX;
3265 }
3266
3267 def : Pat<(int_x86_avx_movnt_dq_256 addr:$dst, VR256:$src),
3268           (VMOVNTDQYmr addr:$dst, VR256:$src)>;
3269 def : Pat<(int_x86_avx_movnt_pd_256 addr:$dst, VR256:$src),
3270           (VMOVNTPDYmr addr:$dst, VR256:$src)>;
3271 def : Pat<(int_x86_avx_movnt_ps_256 addr:$dst, VR256:$src),
3272           (VMOVNTPSYmr addr:$dst, VR256:$src)>;
3273
3274 let AddedComplexity = 400 in { // Prefer non-temporal versions
3275 def MOVNTPSmr : PSI<0x2B, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
3276                     "movntps\t{$src, $dst|$dst, $src}",
3277                     [(alignednontemporalstore (v4f32 VR128:$src), addr:$dst)]>;
3278 def MOVNTPDmr : PDI<0x2B, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
3279                     "movntpd\t{$src, $dst|$dst, $src}",
3280                     [(alignednontemporalstore(v2f64 VR128:$src), addr:$dst)]>;
3281
3282 let ExeDomain = SSEPackedInt in
3283 def MOVNTDQmr : PDI<0xE7, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
3284                     "movntdq\t{$src, $dst|$dst, $src}",
3285                     [(alignednontemporalstore (v2i64 VR128:$src), addr:$dst)]>;
3286
3287 def : Pat<(alignednontemporalstore (v2i64 VR128:$src), addr:$dst),
3288           (MOVNTDQmr addr:$dst, VR128:$src)>, Requires<[HasSSE2]>;
3289
3290 // There is no AVX form for instructions below this point
3291 def MOVNTImr : I<0xC3, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
3292                  "movnti{l}\t{$src, $dst|$dst, $src}",
3293                  [(nontemporalstore (i32 GR32:$src), addr:$dst)]>,
3294                TB, Requires<[HasSSE2]>;
3295 def MOVNTI_64mr : RI<0xC3, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
3296                      "movnti{q}\t{$src, $dst|$dst, $src}",
3297                      [(nontemporalstore (i64 GR64:$src), addr:$dst)]>,
3298                   TB, Requires<[HasSSE2]>;
3299 }
3300
3301 //===----------------------------------------------------------------------===//
3302 // SSE 1 & 2 - Prefetch and memory fence
3303 //===----------------------------------------------------------------------===//
3304
3305 // Prefetch intrinsic.
3306 let Predicates = [HasSSE1] in {
3307 def PREFETCHT0   : I<0x18, MRM1m, (outs), (ins i8mem:$src),
3308     "prefetcht0\t$src", [(prefetch addr:$src, imm, (i32 3), (i32 1))]>, TB;
3309 def PREFETCHT1   : I<0x18, MRM2m, (outs), (ins i8mem:$src),
3310     "prefetcht1\t$src", [(prefetch addr:$src, imm, (i32 2), (i32 1))]>, TB;
3311 def PREFETCHT2   : I<0x18, MRM3m, (outs), (ins i8mem:$src),
3312     "prefetcht2\t$src", [(prefetch addr:$src, imm, (i32 1), (i32 1))]>, TB;
3313 def PREFETCHNTA  : I<0x18, MRM0m, (outs), (ins i8mem:$src),
3314     "prefetchnta\t$src", [(prefetch addr:$src, imm, (i32 0), (i32 1))]>, TB;
3315 }
3316
3317 // Flush cache
3318 def CLFLUSH : I<0xAE, MRM7m, (outs), (ins i8mem:$src),
3319                "clflush\t$src", [(int_x86_sse2_clflush addr:$src)]>,
3320               TB, Requires<[HasSSE2]>;
3321
3322 // Pause. This "instruction" is encoded as "rep; nop", so even though it
3323 // was introduced with SSE2, it's backward compatible.
3324 def PAUSE : I<0x90, RawFrm, (outs), (ins), "pause", []>, REP;
3325
3326 // Load, store, and memory fence
3327 def SFENCE : I<0xAE, MRM_F8, (outs), (ins),
3328                "sfence", [(int_x86_sse_sfence)]>, TB, Requires<[HasSSE1]>;
3329 def LFENCE : I<0xAE, MRM_E8, (outs), (ins),
3330                "lfence", [(int_x86_sse2_lfence)]>, TB, Requires<[HasSSE2]>;
3331 def MFENCE : I<0xAE, MRM_F0, (outs), (ins),
3332                "mfence", [(int_x86_sse2_mfence)]>, TB, Requires<[HasSSE2]>;
3333
3334 def : Pat<(X86SFence), (SFENCE)>;
3335 def : Pat<(X86LFence), (LFENCE)>;
3336 def : Pat<(X86MFence), (MFENCE)>;
3337
3338 //===----------------------------------------------------------------------===//
3339 // SSE 1 & 2 - Load/Store XCSR register
3340 //===----------------------------------------------------------------------===//
3341
3342 def VLDMXCSR : VPSI<0xAE, MRM2m, (outs), (ins i32mem:$src),
3343                   "ldmxcsr\t$src", [(int_x86_sse_ldmxcsr addr:$src)]>, VEX;
3344 def VSTMXCSR : VPSI<0xAE, MRM3m, (outs), (ins i32mem:$dst),
3345                   "stmxcsr\t$dst", [(int_x86_sse_stmxcsr addr:$dst)]>, VEX;
3346
3347 def LDMXCSR : PSI<0xAE, MRM2m, (outs), (ins i32mem:$src),
3348                   "ldmxcsr\t$src", [(int_x86_sse_ldmxcsr addr:$src)]>;
3349 def STMXCSR : PSI<0xAE, MRM3m, (outs), (ins i32mem:$dst),
3350                   "stmxcsr\t$dst", [(int_x86_sse_stmxcsr addr:$dst)]>;
3351
3352 //===---------------------------------------------------------------------===//
3353 // SSE2 - Move Aligned/Unaligned Packed Integer Instructions
3354 //===---------------------------------------------------------------------===//
3355
3356 let ExeDomain = SSEPackedInt in { // SSE integer instructions
3357
3358 let neverHasSideEffects = 1 in {
3359 def VMOVDQArr  : VPDI<0x6F, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3360                     "movdqa\t{$src, $dst|$dst, $src}", []>, VEX;
3361 def VMOVDQAYrr : VPDI<0x6F, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
3362                     "movdqa\t{$src, $dst|$dst, $src}", []>, VEX;
3363 }
3364 def VMOVDQUrr  : VSSI<0x6F, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3365                     "movdqu\t{$src, $dst|$dst, $src}", []>, VEX;
3366 def VMOVDQUYrr : VSSI<0x6F, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
3367                     "movdqu\t{$src, $dst|$dst, $src}", []>, VEX;
3368
3369 // For Disassembler
3370 let isCodeGenOnly = 1 in {
3371 def VMOVDQArr_REV  : VPDI<0x7F, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
3372                         "movdqa\t{$src, $dst|$dst, $src}", []>, VEX;
3373 def VMOVDQAYrr_REV : VPDI<0x7F, MRMDestReg, (outs VR256:$dst), (ins VR256:$src),
3374                         "movdqa\t{$src, $dst|$dst, $src}", []>, VEX;
3375 def VMOVDQUrr_REV  : VSSI<0x7F, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
3376                         "movdqu\t{$src, $dst|$dst, $src}", []>, VEX;
3377 def VMOVDQUYrr_REV : VSSI<0x7F, MRMDestReg, (outs VR256:$dst), (ins VR256:$src),
3378                         "movdqu\t{$src, $dst|$dst, $src}", []>, VEX;
3379 }
3380
3381 let canFoldAsLoad = 1, mayLoad = 1 in {
3382 def VMOVDQArm  : VPDI<0x6F, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
3383                    "movdqa\t{$src, $dst|$dst, $src}", []>, VEX;
3384 def VMOVDQAYrm : VPDI<0x6F, MRMSrcMem, (outs VR256:$dst), (ins i256mem:$src),
3385                    "movdqa\t{$src, $dst|$dst, $src}", []>, VEX;
3386 let Predicates = [HasAVX] in {
3387   def VMOVDQUrm  : I<0x6F, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
3388                     "vmovdqu\t{$src, $dst|$dst, $src}",[]>, XS, VEX;
3389   def VMOVDQUYrm : I<0x6F, MRMSrcMem, (outs VR256:$dst), (ins i256mem:$src),
3390                     "vmovdqu\t{$src, $dst|$dst, $src}",[]>, XS, VEX;
3391 }
3392 }
3393
3394 let mayStore = 1 in {
3395 def VMOVDQAmr  : VPDI<0x7F, MRMDestMem, (outs),
3396                      (ins i128mem:$dst, VR128:$src),
3397                      "movdqa\t{$src, $dst|$dst, $src}", []>, VEX;
3398 def VMOVDQAYmr : VPDI<0x7F, MRMDestMem, (outs),
3399                      (ins i256mem:$dst, VR256:$src),
3400                      "movdqa\t{$src, $dst|$dst, $src}", []>, VEX;
3401 let Predicates = [HasAVX] in {
3402 def VMOVDQUmr  : I<0x7F, MRMDestMem, (outs), (ins i128mem:$dst, VR128:$src),
3403                   "vmovdqu\t{$src, $dst|$dst, $src}",[]>, XS, VEX;
3404 def VMOVDQUYmr : I<0x7F, MRMDestMem, (outs), (ins i256mem:$dst, VR256:$src),
3405                   "vmovdqu\t{$src, $dst|$dst, $src}",[]>, XS, VEX;
3406 }
3407 }
3408
3409 let neverHasSideEffects = 1 in
3410 def MOVDQArr : PDI<0x6F, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3411                    "movdqa\t{$src, $dst|$dst, $src}", []>;
3412
3413 def MOVDQUrr :   I<0x6F, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3414                    "movdqu\t{$src, $dst|$dst, $src}",
3415                    []>, XS, Requires<[HasSSE2]>;
3416
3417 // For Disassembler
3418 let isCodeGenOnly = 1 in {
3419 def MOVDQArr_REV : PDI<0x7F, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
3420                        "movdqa\t{$src, $dst|$dst, $src}", []>;
3421
3422 def MOVDQUrr_REV :   I<0x7F, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
3423                        "movdqu\t{$src, $dst|$dst, $src}",
3424                        []>, XS, Requires<[HasSSE2]>;
3425 }
3426
3427 let canFoldAsLoad = 1, mayLoad = 1 in {
3428 def MOVDQArm : PDI<0x6F, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
3429                    "movdqa\t{$src, $dst|$dst, $src}",
3430                    [/*(set VR128:$dst, (alignedloadv2i64 addr:$src))*/]>;
3431 def MOVDQUrm :   I<0x6F, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
3432                    "movdqu\t{$src, $dst|$dst, $src}",
3433                    [/*(set VR128:$dst, (loadv2i64 addr:$src))*/]>,
3434                  XS, Requires<[HasSSE2]>;
3435 }
3436
3437 let mayStore = 1 in {
3438 def MOVDQAmr : PDI<0x7F, MRMDestMem, (outs), (ins i128mem:$dst, VR128:$src),
3439                    "movdqa\t{$src, $dst|$dst, $src}",
3440                    [/*(alignedstore (v2i64 VR128:$src), addr:$dst)*/]>;
3441 def MOVDQUmr :   I<0x7F, MRMDestMem, (outs), (ins i128mem:$dst, VR128:$src),
3442                    "movdqu\t{$src, $dst|$dst, $src}",
3443                    [/*(store (v2i64 VR128:$src), addr:$dst)*/]>,
3444                  XS, Requires<[HasSSE2]>;
3445 }
3446
3447 // Intrinsic forms of MOVDQU load and store
3448 def VMOVDQUmr_Int : I<0x7F, MRMDestMem, (outs), (ins i128mem:$dst, VR128:$src),
3449                        "vmovdqu\t{$src, $dst|$dst, $src}",
3450                        [(int_x86_sse2_storeu_dq addr:$dst, VR128:$src)]>,
3451                      XS, VEX, Requires<[HasAVX]>;
3452
3453 def MOVDQUmr_Int :   I<0x7F, MRMDestMem, (outs), (ins i128mem:$dst, VR128:$src),
3454                        "movdqu\t{$src, $dst|$dst, $src}",
3455                        [(int_x86_sse2_storeu_dq addr:$dst, VR128:$src)]>,
3456                      XS, Requires<[HasSSE2]>;
3457
3458 } // ExeDomain = SSEPackedInt
3459
3460 let Predicates = [HasAVX] in {
3461   def : Pat<(int_x86_avx_storeu_dq_256 addr:$dst, VR256:$src),
3462             (VMOVDQUYmr addr:$dst, VR256:$src)>;
3463 }
3464
3465 //===---------------------------------------------------------------------===//
3466 // SSE2 - Packed Integer Arithmetic Instructions
3467 //===---------------------------------------------------------------------===//
3468
3469 let ExeDomain = SSEPackedInt in { // SSE integer instructions
3470
3471 multiclass PDI_binop_rm_int<bits<8> opc, string OpcodeStr, Intrinsic IntId,
3472                             RegisterClass RC, PatFrag memop_frag,
3473                             X86MemOperand x86memop, bit IsCommutable = 0,
3474                             bit Is2Addr = 1> {
3475   let isCommutable = IsCommutable in
3476   def rr : PDI<opc, MRMSrcReg, (outs RC:$dst),
3477        (ins RC:$src1, RC:$src2),
3478        !if(Is2Addr,
3479            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
3480            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
3481        [(set RC:$dst, (IntId RC:$src1, RC:$src2))]>;
3482   def rm : PDI<opc, MRMSrcMem, (outs RC:$dst),
3483        (ins RC:$src1, x86memop:$src2),
3484        !if(Is2Addr,
3485            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
3486            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
3487        [(set RC:$dst, (IntId RC:$src1, (bitconvert (memop_frag addr:$src2))))]>;
3488 }
3489
3490 multiclass PDI_binop_rmi<bits<8> opc, bits<8> opc2, Format ImmForm,
3491                          string OpcodeStr, SDNode OpNode,
3492                          SDNode OpNode2, RegisterClass RC,
3493                          ValueType DstVT, ValueType SrcVT, PatFrag bc_frag,
3494                          bit Is2Addr = 1> {
3495   // src2 is always 128-bit
3496   def rr : PDI<opc, MRMSrcReg, (outs RC:$dst),
3497        (ins RC:$src1, VR128:$src2),
3498        !if(Is2Addr,
3499            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
3500            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
3501        [(set RC:$dst, (DstVT (OpNode RC:$src1, (SrcVT VR128:$src2))))]>;
3502   def rm : PDI<opc, MRMSrcMem, (outs RC:$dst),
3503        (ins RC:$src1, i128mem:$src2),
3504        !if(Is2Addr,
3505            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
3506            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
3507        [(set RC:$dst, (DstVT (OpNode RC:$src1,
3508                        (bc_frag (memopv2i64 addr:$src2)))))]>;
3509   def ri : PDIi8<opc2, ImmForm, (outs RC:$dst),
3510        (ins RC:$src1, i32i8imm:$src2),
3511        !if(Is2Addr,
3512            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
3513            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
3514        [(set RC:$dst, (DstVT (OpNode2 RC:$src1, (i32 imm:$src2))))]>;
3515 }
3516
3517 } // ExeDomain = SSEPackedInt
3518
3519 // 128-bit Integer Arithmetic
3520
3521 let Predicates = [HasAVX] in {
3522 defm VPADDB  : PDI_binop_rm<0xFC, "vpaddb", add, v16i8, VR128, memopv2i64,
3523                             i128mem, 1, 0 /*3addr*/>, VEX_4V;
3524 defm VPADDW  : PDI_binop_rm<0xFD, "vpaddw", add, v8i16, VR128, memopv2i64,
3525                             i128mem, 1, 0>, VEX_4V;
3526 defm VPADDD  : PDI_binop_rm<0xFE, "vpaddd", add, v4i32, VR128, memopv2i64,
3527                             i128mem, 1, 0>, VEX_4V;
3528 defm VPADDQ  : PDI_binop_rm<0xD4, "vpaddq", add, v2i64, VR128, memopv2i64,
3529                             i128mem, 1, 0>, VEX_4V;
3530 defm VPMULLW : PDI_binop_rm<0xD5, "vpmullw", mul, v8i16, VR128, memopv2i64,
3531                             i128mem, 1, 0>, VEX_4V;
3532 defm VPSUBB : PDI_binop_rm<0xF8, "vpsubb", sub, v16i8, VR128, memopv2i64,
3533                             i128mem, 0, 0>, VEX_4V;
3534 defm VPSUBW : PDI_binop_rm<0xF9, "vpsubw", sub, v8i16, VR128, memopv2i64,
3535                             i128mem, 0, 0>, VEX_4V;
3536 defm VPSUBD : PDI_binop_rm<0xFA, "vpsubd", sub, v4i32, VR128, memopv2i64,
3537                             i128mem, 0, 0>, VEX_4V;
3538 defm VPSUBQ : PDI_binop_rm<0xFB, "vpsubq", sub, v2i64, VR128, memopv2i64,
3539                             i128mem, 0, 0>, VEX_4V;
3540
3541 // Intrinsic forms
3542 defm VPSUBSB  : PDI_binop_rm_int<0xE8, "vpsubsb" , int_x86_sse2_psubs_b,
3543                                  VR128, memopv2i64, i128mem, 0, 0>, VEX_4V;
3544 defm VPSUBSW  : PDI_binop_rm_int<0xE9, "vpsubsw" , int_x86_sse2_psubs_w,
3545                                  VR128, memopv2i64, i128mem, 0, 0>, VEX_4V;
3546 defm VPSUBUSB : PDI_binop_rm_int<0xD8, "vpsubusb", int_x86_sse2_psubus_b,
3547                                  VR128, memopv2i64, i128mem, 0, 0>, VEX_4V;
3548 defm VPSUBUSW : PDI_binop_rm_int<0xD9, "vpsubusw", int_x86_sse2_psubus_w,
3549                                  VR128, memopv2i64, i128mem, 0, 0>, VEX_4V;
3550 defm VPADDSB  : PDI_binop_rm_int<0xEC, "vpaddsb" , int_x86_sse2_padds_b,
3551                                  VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3552 defm VPADDSW  : PDI_binop_rm_int<0xED, "vpaddsw" , int_x86_sse2_padds_w,
3553                                  VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3554 defm VPADDUSB : PDI_binop_rm_int<0xDC, "vpaddusb", int_x86_sse2_paddus_b,
3555                                  VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3556 defm VPADDUSW : PDI_binop_rm_int<0xDD, "vpaddusw", int_x86_sse2_paddus_w,
3557                                  VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3558 defm VPMULHUW : PDI_binop_rm_int<0xE4, "vpmulhuw", int_x86_sse2_pmulhu_w,
3559                                  VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3560 defm VPMULHW  : PDI_binop_rm_int<0xE5, "vpmulhw" , int_x86_sse2_pmulh_w,
3561                                  VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3562 defm VPMULUDQ : PDI_binop_rm_int<0xF4, "vpmuludq", int_x86_sse2_pmulu_dq,
3563                                  VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3564 defm VPMADDWD : PDI_binop_rm_int<0xF5, "vpmaddwd", int_x86_sse2_pmadd_wd,
3565                                  VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3566 defm VPAVGB   : PDI_binop_rm_int<0xE0, "vpavgb", int_x86_sse2_pavg_b,
3567                                  VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3568 defm VPAVGW   : PDI_binop_rm_int<0xE3, "vpavgw", int_x86_sse2_pavg_w,
3569                                  VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3570 defm VPMINUB  : PDI_binop_rm_int<0xDA, "vpminub", int_x86_sse2_pminu_b,
3571                                  VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3572 defm VPMINSW  : PDI_binop_rm_int<0xEA, "vpminsw", int_x86_sse2_pmins_w,
3573                                  VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3574 defm VPMAXUB  : PDI_binop_rm_int<0xDE, "vpmaxub", int_x86_sse2_pmaxu_b,
3575                                  VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3576 defm VPMAXSW  : PDI_binop_rm_int<0xEE, "vpmaxsw", int_x86_sse2_pmaxs_w,
3577                                  VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3578 defm VPSADBW  : PDI_binop_rm_int<0xF6, "vpsadbw", int_x86_sse2_psad_bw,
3579                                  VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3580 }
3581
3582 let Predicates = [HasAVX2] in {
3583 defm VPADDBY  : PDI_binop_rm<0xFC, "vpaddb", add, v32i8, VR256, memopv4i64,
3584                              i256mem, 1, 0>, VEX_4V;
3585 defm VPADDWY  : PDI_binop_rm<0xFD, "vpaddw", add, v16i16, VR256, memopv4i64,
3586                              i256mem, 1, 0>, VEX_4V;
3587 defm VPADDDY  : PDI_binop_rm<0xFE, "vpaddd", add, v8i32, VR256, memopv4i64,
3588                              i256mem, 1, 0>, VEX_4V;
3589 defm VPADDQY  : PDI_binop_rm<0xD4, "vpaddq", add, v4i64, VR256, memopv4i64,
3590                              i256mem, 1, 0>, VEX_4V;
3591 defm VPMULLWY : PDI_binop_rm<0xD5, "vpmullw", mul, v16i16, VR256, memopv4i64,
3592                              i256mem, 1, 0>, VEX_4V;
3593 defm VPSUBBY  : PDI_binop_rm<0xF8, "vpsubb", sub, v32i8, VR256, memopv4i64,
3594                              i256mem, 0, 0>, VEX_4V;
3595 defm VPSUBWY  : PDI_binop_rm<0xF9, "vpsubw", sub, v16i16,VR256, memopv4i64,
3596                              i256mem, 0, 0>, VEX_4V;
3597 defm VPSUBDY  : PDI_binop_rm<0xFA, "vpsubd", sub, v8i32, VR256, memopv4i64,
3598                              i256mem, 0, 0>, VEX_4V;
3599 defm VPSUBQY  : PDI_binop_rm<0xFB, "vpsubq", sub, v4i64, VR256, memopv4i64,
3600                              i256mem, 0, 0>, VEX_4V;
3601
3602 // Intrinsic forms
3603 defm VPSUBSBY  : PDI_binop_rm_int<0xE8, "vpsubsb" , int_x86_avx2_psubs_b,
3604                                   VR256, memopv4i64, i256mem, 0, 0>, VEX_4V;
3605 defm VPSUBSWY  : PDI_binop_rm_int<0xE9, "vpsubsw" , int_x86_avx2_psubs_w,
3606                                   VR256, memopv4i64, i256mem, 0, 0>, VEX_4V;
3607 defm VPSUBUSBY : PDI_binop_rm_int<0xD8, "vpsubusb", int_x86_avx2_psubus_b,
3608                                   VR256, memopv4i64, i256mem, 0, 0>, VEX_4V;
3609 defm VPSUBUSWY : PDI_binop_rm_int<0xD9, "vpsubusw", int_x86_avx2_psubus_w,
3610                                   VR256, memopv4i64, i256mem, 0, 0>, VEX_4V;
3611 defm VPADDSBY  : PDI_binop_rm_int<0xEC, "vpaddsb" , int_x86_avx2_padds_b,
3612                                   VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3613 defm VPADDSWY  : PDI_binop_rm_int<0xED, "vpaddsw" , int_x86_avx2_padds_w,
3614                                   VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3615 defm VPADDUSBY : PDI_binop_rm_int<0xDC, "vpaddusb", int_x86_avx2_paddus_b,
3616                                   VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3617 defm VPADDUSWY : PDI_binop_rm_int<0xDD, "vpaddusw", int_x86_avx2_paddus_w,
3618                                   VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3619 defm VPMULHUWY : PDI_binop_rm_int<0xE4, "vpmulhuw", int_x86_avx2_pmulhu_w,
3620                                   VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3621 defm VPMULHWY  : PDI_binop_rm_int<0xE5, "vpmulhw" , int_x86_avx2_pmulh_w,
3622                                   VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3623 defm VPMULUDQY : PDI_binop_rm_int<0xF4, "vpmuludq", int_x86_avx2_pmulu_dq,
3624                                   VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3625 defm VPMADDWDY : PDI_binop_rm_int<0xF5, "vpmaddwd", int_x86_avx2_pmadd_wd,
3626                                   VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3627 defm VPAVGBY   : PDI_binop_rm_int<0xE0, "vpavgb", int_x86_avx2_pavg_b,
3628                                   VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3629 defm VPAVGWY   : PDI_binop_rm_int<0xE3, "vpavgw", int_x86_avx2_pavg_w,
3630                                   VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3631 defm VPMINUBY  : PDI_binop_rm_int<0xDA, "vpminub", int_x86_avx2_pminu_b,
3632                                   VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3633 defm VPMINSWY  : PDI_binop_rm_int<0xEA, "vpminsw", int_x86_avx2_pmins_w,
3634                                   VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3635 defm VPMAXUBY  : PDI_binop_rm_int<0xDE, "vpmaxub", int_x86_avx2_pmaxu_b,
3636                                   VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3637 defm VPMAXSWY  : PDI_binop_rm_int<0xEE, "vpmaxsw", int_x86_avx2_pmaxs_w,
3638                                   VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3639 defm VPSADBWY  : PDI_binop_rm_int<0xF6, "vpsadbw", int_x86_avx2_psad_bw,
3640                                   VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3641 }
3642
3643 let Constraints = "$src1 = $dst" in {
3644 defm PADDB  : PDI_binop_rm<0xFC, "paddb", add, v16i8, VR128, memopv2i64,
3645                            i128mem, 1>;
3646 defm PADDW  : PDI_binop_rm<0xFD, "paddw", add, v8i16, VR128, memopv2i64,
3647                            i128mem, 1>;
3648 defm PADDD  : PDI_binop_rm<0xFE, "paddd", add, v4i32, VR128, memopv2i64,
3649                            i128mem, 1>;
3650 defm PADDQ  : PDI_binop_rm<0xD4, "paddq", add, v2i64, VR128, memopv2i64,
3651                            i128mem, 1>;
3652 defm PMULLW : PDI_binop_rm<0xD5, "pmullw", mul, v8i16, VR128, memopv2i64,
3653                            i128mem, 1>;
3654 defm PSUBB : PDI_binop_rm<0xF8, "psubb", sub, v16i8, VR128, memopv2i64,
3655                           i128mem>;
3656 defm PSUBW : PDI_binop_rm<0xF9, "psubw", sub, v8i16, VR128, memopv2i64,
3657                           i128mem>;
3658 defm PSUBD : PDI_binop_rm<0xFA, "psubd", sub, v4i32, VR128, memopv2i64,
3659                           i128mem>;
3660 defm PSUBQ : PDI_binop_rm<0xFB, "psubq", sub, v2i64, VR128, memopv2i64,
3661                           i128mem>;
3662
3663 // Intrinsic forms
3664 defm PSUBSB  : PDI_binop_rm_int<0xE8, "psubsb" , int_x86_sse2_psubs_b,
3665                                 VR128, memopv2i64, i128mem>;
3666 defm PSUBSW  : PDI_binop_rm_int<0xE9, "psubsw" , int_x86_sse2_psubs_w,
3667                                 VR128, memopv2i64, i128mem>;
3668 defm PSUBUSB : PDI_binop_rm_int<0xD8, "psubusb", int_x86_sse2_psubus_b,
3669                                 VR128, memopv2i64, i128mem>;
3670 defm PSUBUSW : PDI_binop_rm_int<0xD9, "psubusw", int_x86_sse2_psubus_w,
3671                                 VR128, memopv2i64, i128mem>;
3672 defm PADDSB  : PDI_binop_rm_int<0xEC, "paddsb" , int_x86_sse2_padds_b,
3673                                 VR128, memopv2i64, i128mem, 1>;
3674 defm PADDSW  : PDI_binop_rm_int<0xED, "paddsw" , int_x86_sse2_padds_w,
3675                                 VR128, memopv2i64, i128mem, 1>;
3676 defm PADDUSB : PDI_binop_rm_int<0xDC, "paddusb", int_x86_sse2_paddus_b,
3677                                 VR128, memopv2i64, i128mem, 1>;
3678 defm PADDUSW : PDI_binop_rm_int<0xDD, "paddusw", int_x86_sse2_paddus_w,
3679                                 VR128, memopv2i64, i128mem, 1>;
3680 defm PMULHUW : PDI_binop_rm_int<0xE4, "pmulhuw", int_x86_sse2_pmulhu_w,
3681                                 VR128, memopv2i64, i128mem, 1>;
3682 defm PMULHW  : PDI_binop_rm_int<0xE5, "pmulhw" , int_x86_sse2_pmulh_w,
3683                                 VR128, memopv2i64, i128mem, 1>;
3684 defm PMULUDQ : PDI_binop_rm_int<0xF4, "pmuludq", int_x86_sse2_pmulu_dq,
3685                                 VR128, memopv2i64, i128mem, 1>;
3686 defm PMADDWD : PDI_binop_rm_int<0xF5, "pmaddwd", int_x86_sse2_pmadd_wd,
3687                                 VR128, memopv2i64, i128mem, 1>;
3688 defm PAVGB   : PDI_binop_rm_int<0xE0, "pavgb", int_x86_sse2_pavg_b,
3689                                 VR128, memopv2i64, i128mem, 1>;
3690 defm PAVGW   : PDI_binop_rm_int<0xE3, "pavgw", int_x86_sse2_pavg_w,
3691                                 VR128, memopv2i64, i128mem, 1>;
3692 defm PMINUB  : PDI_binop_rm_int<0xDA, "pminub", int_x86_sse2_pminu_b,
3693                                 VR128, memopv2i64, i128mem, 1>;
3694 defm PMINSW  : PDI_binop_rm_int<0xEA, "pminsw", int_x86_sse2_pmins_w,
3695                                 VR128, memopv2i64, i128mem, 1>;
3696 defm PMAXUB  : PDI_binop_rm_int<0xDE, "pmaxub", int_x86_sse2_pmaxu_b,
3697                                 VR128, memopv2i64, i128mem, 1>;
3698 defm PMAXSW  : PDI_binop_rm_int<0xEE, "pmaxsw", int_x86_sse2_pmaxs_w,
3699                                 VR128, memopv2i64, i128mem, 1>;
3700 defm PSADBW  : PDI_binop_rm_int<0xF6, "psadbw", int_x86_sse2_psad_bw,
3701                                 VR128, memopv2i64, i128mem, 1>;
3702
3703 } // Constraints = "$src1 = $dst"
3704
3705 //===---------------------------------------------------------------------===//
3706 // SSE2 - Packed Integer Logical Instructions
3707 //===---------------------------------------------------------------------===//
3708
3709 let Predicates = [HasAVX] in {
3710 defm VPSLLW : PDI_binop_rmi<0xF1, 0x71, MRM6r, "vpsllw", X86vshl, X86vshli,
3711                             VR128, v8i16, v8i16, bc_v8i16, 0>, VEX_4V;
3712 defm VPSLLD : PDI_binop_rmi<0xF2, 0x72, MRM6r, "vpslld", X86vshl, X86vshli,
3713                             VR128, v4i32, v4i32, bc_v4i32, 0>, VEX_4V;
3714 defm VPSLLQ : PDI_binop_rmi<0xF3, 0x73, MRM6r, "vpsllq", X86vshl, X86vshli,
3715                             VR128, v2i64, v2i64, bc_v2i64, 0>, VEX_4V;
3716
3717 defm VPSRLW : PDI_binop_rmi<0xD1, 0x71, MRM2r, "vpsrlw", X86vsrl, X86vsrli,
3718                             VR128, v8i16, v8i16, bc_v8i16, 0>, VEX_4V;
3719 defm VPSRLD : PDI_binop_rmi<0xD2, 0x72, MRM2r, "vpsrld", X86vsrl, X86vsrli,
3720                             VR128, v4i32, v4i32, bc_v4i32, 0>, VEX_4V;
3721 defm VPSRLQ : PDI_binop_rmi<0xD3, 0x73, MRM2r, "vpsrlq", X86vsrl, X86vsrli,
3722                             VR128, v2i64, v2i64, bc_v2i64, 0>, VEX_4V;
3723
3724 defm VPSRAW : PDI_binop_rmi<0xE1, 0x71, MRM4r, "vpsraw", X86vsra, X86vsrai,
3725                             VR128, v8i16, v8i16, bc_v8i16, 0>, VEX_4V;
3726 defm VPSRAD : PDI_binop_rmi<0xE2, 0x72, MRM4r, "vpsrad", X86vsra, X86vsrai,
3727                             VR128, v4i32, v4i32, bc_v4i32, 0>, VEX_4V;
3728
3729 let ExeDomain = SSEPackedInt in {
3730   // 128-bit logical shifts.
3731   def VPSLLDQri : PDIi8<0x73, MRM7r,
3732                     (outs VR128:$dst), (ins VR128:$src1, i32i8imm:$src2),
3733                     "vpslldq\t{$src2, $src1, $dst|$dst, $src1, $src2}",
3734                     [(set VR128:$dst,
3735                       (int_x86_sse2_psll_dq_bs VR128:$src1, imm:$src2))]>,
3736                     VEX_4V;
3737   def VPSRLDQri : PDIi8<0x73, MRM3r,
3738                     (outs VR128:$dst), (ins VR128:$src1, i32i8imm:$src2),
3739                     "vpsrldq\t{$src2, $src1, $dst|$dst, $src1, $src2}",
3740                     [(set VR128:$dst,
3741                       (int_x86_sse2_psrl_dq_bs VR128:$src1, imm:$src2))]>,
3742                     VEX_4V;
3743   // PSRADQri doesn't exist in SSE[1-3].
3744 }
3745 } // Predicates = [HasAVX]
3746
3747 let Predicates = [HasAVX2] in {
3748 defm VPSLLWY : PDI_binop_rmi<0xF1, 0x71, MRM6r, "vpsllw", X86vshl, X86vshli,
3749                              VR256, v16i16, v8i16, bc_v8i16, 0>, VEX_4V;
3750 defm VPSLLDY : PDI_binop_rmi<0xF2, 0x72, MRM6r, "vpslld", X86vshl, X86vshli,
3751                              VR256, v8i32, v4i32, bc_v4i32, 0>, VEX_4V;
3752 defm VPSLLQY : PDI_binop_rmi<0xF3, 0x73, MRM6r, "vpsllq", X86vshl, X86vshli,
3753                              VR256, v4i64, v2i64, bc_v2i64, 0>, VEX_4V;
3754
3755 defm VPSRLWY : PDI_binop_rmi<0xD1, 0x71, MRM2r, "vpsrlw", X86vsrl, X86vsrli,
3756                              VR256, v16i16, v8i16, bc_v8i16, 0>, VEX_4V;
3757 defm VPSRLDY : PDI_binop_rmi<0xD2, 0x72, MRM2r, "vpsrld", X86vsrl, X86vsrli,
3758                              VR256, v8i32, v4i32, bc_v4i32, 0>, VEX_4V;
3759 defm VPSRLQY : PDI_binop_rmi<0xD3, 0x73, MRM2r, "vpsrlq", X86vsrl, X86vsrli,
3760                              VR256, v4i64, v2i64, bc_v2i64, 0>, VEX_4V;
3761
3762 defm VPSRAWY : PDI_binop_rmi<0xE1, 0x71, MRM4r, "vpsraw", X86vsra, X86vsrai,
3763                              VR256, v16i16, v8i16, bc_v8i16, 0>, VEX_4V;
3764 defm VPSRADY : PDI_binop_rmi<0xE2, 0x72, MRM4r, "vpsrad", X86vsra, X86vsrai,
3765                              VR256, v8i32, v4i32, bc_v4i32, 0>, VEX_4V;
3766
3767 let ExeDomain = SSEPackedInt in {
3768   // 256-bit logical shifts.
3769   def VPSLLDQYri : PDIi8<0x73, MRM7r,
3770                     (outs VR256:$dst), (ins VR256:$src1, i32i8imm:$src2),
3771                     "vpslldq\t{$src2, $src1, $dst|$dst, $src1, $src2}",
3772                     [(set VR256:$dst,
3773                       (int_x86_avx2_psll_dq_bs VR256:$src1, imm:$src2))]>,
3774                     VEX_4V;
3775   def VPSRLDQYri : PDIi8<0x73, MRM3r,
3776                     (outs VR256:$dst), (ins VR256:$src1, i32i8imm:$src2),
3777                     "vpsrldq\t{$src2, $src1, $dst|$dst, $src1, $src2}",
3778                     [(set VR256:$dst,
3779                       (int_x86_avx2_psrl_dq_bs VR256:$src1, imm:$src2))]>,
3780                     VEX_4V;
3781   // PSRADQYri doesn't exist in SSE[1-3].
3782 }
3783 } // Predicates = [HasAVX2]
3784
3785 let Constraints = "$src1 = $dst" in {
3786 defm PSLLW : PDI_binop_rmi<0xF1, 0x71, MRM6r, "psllw", X86vshl, X86vshli,
3787                            VR128, v8i16, v8i16, bc_v8i16>;
3788 defm PSLLD : PDI_binop_rmi<0xF2, 0x72, MRM6r, "pslld", X86vshl, X86vshli,
3789                            VR128, v4i32, v4i32, bc_v4i32>;
3790 defm PSLLQ : PDI_binop_rmi<0xF3, 0x73, MRM6r, "psllq", X86vshl, X86vshli,
3791                            VR128, v2i64, v2i64, bc_v2i64>;
3792
3793 defm PSRLW : PDI_binop_rmi<0xD1, 0x71, MRM2r, "psrlw", X86vsrl, X86vsrli,
3794                            VR128, v8i16, v8i16, bc_v8i16>;
3795 defm PSRLD : PDI_binop_rmi<0xD2, 0x72, MRM2r, "psrld", X86vsrl, X86vsrli,
3796                            VR128, v4i32, v4i32, bc_v4i32>;
3797 defm PSRLQ : PDI_binop_rmi<0xD3, 0x73, MRM2r, "psrlq", X86vsrl, X86vsrli,
3798                            VR128, v2i64, v2i64, bc_v2i64>;
3799
3800 defm PSRAW : PDI_binop_rmi<0xE1, 0x71, MRM4r, "psraw", X86vsra, X86vsrai,
3801                            VR128, v8i16, v8i16, bc_v8i16>;
3802 defm PSRAD : PDI_binop_rmi<0xE2, 0x72, MRM4r, "psrad", X86vsra, X86vsrai,
3803                            VR128, v4i32, v4i32, bc_v4i32>;
3804
3805 let ExeDomain = SSEPackedInt in {
3806   // 128-bit logical shifts.
3807   def PSLLDQri : PDIi8<0x73, MRM7r,
3808                        (outs VR128:$dst), (ins VR128:$src1, i32i8imm:$src2),
3809                        "pslldq\t{$src2, $dst|$dst, $src2}",
3810                        [(set VR128:$dst,
3811                          (int_x86_sse2_psll_dq_bs VR128:$src1, imm:$src2))]>;
3812   def PSRLDQri : PDIi8<0x73, MRM3r,
3813                        (outs VR128:$dst), (ins VR128:$src1, i32i8imm:$src2),
3814                        "psrldq\t{$src2, $dst|$dst, $src2}",
3815                        [(set VR128:$dst,
3816                          (int_x86_sse2_psrl_dq_bs VR128:$src1, imm:$src2))]>;
3817   // PSRADQri doesn't exist in SSE[1-3].
3818 }
3819 } // Constraints = "$src1 = $dst"
3820
3821 let Predicates = [HasAVX] in {
3822   def : Pat<(int_x86_sse2_psll_dq VR128:$src1, imm:$src2),
3823             (VPSLLDQri VR128:$src1, (BYTE_imm imm:$src2))>;
3824   def : Pat<(int_x86_sse2_psrl_dq VR128:$src1, imm:$src2),
3825             (VPSRLDQri VR128:$src1, (BYTE_imm imm:$src2))>;
3826   def : Pat<(v2f64 (X86fsrl VR128:$src1, i32immSExt8:$src2)),
3827             (VPSRLDQri VR128:$src1, (BYTE_imm imm:$src2))>;
3828
3829   // Shift up / down and insert zero's.
3830   def : Pat<(v2i64 (X86vshldq VR128:$src, (i8 imm:$amt))),
3831             (VPSLLDQri VR128:$src, (BYTE_imm imm:$amt))>;
3832   def : Pat<(v2i64 (X86vshrdq VR128:$src, (i8 imm:$amt))),
3833             (VPSRLDQri VR128:$src, (BYTE_imm imm:$amt))>;
3834 }
3835
3836 let Predicates = [HasAVX2] in {
3837   def : Pat<(int_x86_avx2_psll_dq VR256:$src1, imm:$src2),
3838             (VPSLLDQYri VR256:$src1, (BYTE_imm imm:$src2))>;
3839   def : Pat<(int_x86_avx2_psrl_dq VR256:$src1, imm:$src2),
3840             (VPSRLDQYri VR256:$src1, (BYTE_imm imm:$src2))>;
3841 }
3842
3843 let Predicates = [HasSSE2] in {
3844   def : Pat<(int_x86_sse2_psll_dq VR128:$src1, imm:$src2),
3845             (PSLLDQri VR128:$src1, (BYTE_imm imm:$src2))>;
3846   def : Pat<(int_x86_sse2_psrl_dq VR128:$src1, imm:$src2),
3847             (PSRLDQri VR128:$src1, (BYTE_imm imm:$src2))>;
3848   def : Pat<(v2f64 (X86fsrl VR128:$src1, i32immSExt8:$src2)),
3849             (PSRLDQri VR128:$src1, (BYTE_imm imm:$src2))>;
3850
3851   // Shift up / down and insert zero's.
3852   def : Pat<(v2i64 (X86vshldq VR128:$src, (i8 imm:$amt))),
3853             (PSLLDQri VR128:$src, (BYTE_imm imm:$amt))>;
3854   def : Pat<(v2i64 (X86vshrdq VR128:$src, (i8 imm:$amt))),
3855             (PSRLDQri VR128:$src, (BYTE_imm imm:$amt))>;
3856 }
3857
3858 //===---------------------------------------------------------------------===//
3859 // SSE2 - Packed Integer Comparison Instructions
3860 //===---------------------------------------------------------------------===//
3861
3862 let Predicates = [HasAVX] in {
3863   defm VPCMPEQB  : PDI_binop_rm<0x74, "vpcmpeqb", X86pcmpeq, v16i8,
3864                                 VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3865   defm VPCMPEQW  : PDI_binop_rm<0x75, "vpcmpeqw", X86pcmpeq, v8i16,
3866                                 VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3867   defm VPCMPEQD  : PDI_binop_rm<0x76, "vpcmpeqd", X86pcmpeq, v4i32,
3868                                 VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3869   defm VPCMPGTB  : PDI_binop_rm<0x64, "vpcmpgtb", X86pcmpgt, v16i8,
3870                                 VR128, memopv2i64, i128mem, 0, 0>, VEX_4V;
3871   defm VPCMPGTW  : PDI_binop_rm<0x65, "vpcmpgtw", X86pcmpgt, v8i16,
3872                                 VR128, memopv2i64, i128mem, 0, 0>, VEX_4V;
3873   defm VPCMPGTD  : PDI_binop_rm<0x66, "vpcmpgtd", X86pcmpgt, v4i32,
3874                                 VR128, memopv2i64, i128mem, 0, 0>, VEX_4V;
3875 }
3876
3877 let Predicates = [HasAVX2] in {
3878   defm VPCMPEQBY : PDI_binop_rm<0x74, "vpcmpeqb", X86pcmpeq, v32i8,
3879                                 VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3880   defm VPCMPEQWY : PDI_binop_rm<0x75, "vpcmpeqw", X86pcmpeq, v16i16,
3881                                 VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3882   defm VPCMPEQDY : PDI_binop_rm<0x76, "vpcmpeqd", X86pcmpeq, v8i32,
3883                                 VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3884   defm VPCMPGTBY : PDI_binop_rm<0x64, "vpcmpgtb", X86pcmpgt, v32i8,
3885                                 VR256, memopv4i64, i256mem, 0, 0>, VEX_4V;
3886   defm VPCMPGTWY : PDI_binop_rm<0x65, "vpcmpgtw", X86pcmpgt, v16i16,
3887                                 VR256, memopv4i64, i256mem, 0, 0>, VEX_4V;
3888   defm VPCMPGTDY : PDI_binop_rm<0x66, "vpcmpgtd", X86pcmpgt, v8i32,
3889                                 VR256, memopv4i64, i256mem, 0, 0>, VEX_4V;
3890 }
3891
3892 let Constraints = "$src1 = $dst" in {
3893   defm PCMPEQB  : PDI_binop_rm<0x74, "pcmpeqb", X86pcmpeq, v16i8,
3894                                VR128, memopv2i64, i128mem, 1>;
3895   defm PCMPEQW  : PDI_binop_rm<0x75, "pcmpeqw", X86pcmpeq, v8i16,
3896                                VR128, memopv2i64, i128mem, 1>;
3897   defm PCMPEQD  : PDI_binop_rm<0x76, "pcmpeqd", X86pcmpeq, v4i32,
3898                                VR128, memopv2i64, i128mem, 1>;
3899   defm PCMPGTB  : PDI_binop_rm<0x64, "pcmpgtb", X86pcmpgt, v16i8,
3900                                VR128, memopv2i64, i128mem>;
3901   defm PCMPGTW  : PDI_binop_rm<0x65, "pcmpgtw", X86pcmpgt, v8i16,
3902                                VR128, memopv2i64, i128mem>;
3903   defm PCMPGTD  : PDI_binop_rm<0x66, "pcmpgtd", X86pcmpgt, v4i32,
3904                                VR128, memopv2i64, i128mem>;
3905 } // Constraints = "$src1 = $dst"
3906
3907 //===---------------------------------------------------------------------===//
3908 // SSE2 - Packed Integer Pack Instructions
3909 //===---------------------------------------------------------------------===//
3910
3911 let Predicates = [HasAVX] in {
3912 defm VPACKSSWB : PDI_binop_rm_int<0x63, "vpacksswb", int_x86_sse2_packsswb_128,
3913                                   VR128, memopv2i64, i128mem, 0, 0>, VEX_4V;
3914 defm VPACKSSDW : PDI_binop_rm_int<0x6B, "vpackssdw", int_x86_sse2_packssdw_128,
3915                                   VR128, memopv2i64, i128mem, 0, 0>, VEX_4V;
3916 defm VPACKUSWB : PDI_binop_rm_int<0x67, "vpackuswb", int_x86_sse2_packuswb_128,
3917                                   VR128, memopv2i64, i128mem, 0, 0>, VEX_4V;
3918 }
3919
3920 let Predicates = [HasAVX2] in {
3921 defm VPACKSSWBY : PDI_binop_rm_int<0x63, "vpacksswb", int_x86_avx2_packsswb,
3922                                    VR256, memopv4i64, i256mem, 0, 0>, VEX_4V;
3923 defm VPACKSSDWY : PDI_binop_rm_int<0x6B, "vpackssdw", int_x86_avx2_packssdw,
3924                                    VR256, memopv4i64, i256mem, 0, 0>, VEX_4V;
3925 defm VPACKUSWBY : PDI_binop_rm_int<0x67, "vpackuswb", int_x86_avx2_packuswb,
3926                                    VR256, memopv4i64, i256mem, 0, 0>, VEX_4V;
3927 }
3928
3929 let Constraints = "$src1 = $dst" in {
3930 defm PACKSSWB : PDI_binop_rm_int<0x63, "packsswb", int_x86_sse2_packsswb_128,
3931                                  VR128, memopv2i64, i128mem>;
3932 defm PACKSSDW : PDI_binop_rm_int<0x6B, "packssdw", int_x86_sse2_packssdw_128,
3933                                  VR128, memopv2i64, i128mem>;
3934 defm PACKUSWB : PDI_binop_rm_int<0x67, "packuswb", int_x86_sse2_packuswb_128,
3935                                  VR128, memopv2i64, i128mem>;
3936 } // Constraints = "$src1 = $dst"
3937
3938 //===---------------------------------------------------------------------===//
3939 // SSE2 - Packed Integer Shuffle Instructions
3940 //===---------------------------------------------------------------------===//
3941
3942 let ExeDomain = SSEPackedInt in {
3943 multiclass sse2_pshuffle<string OpcodeStr, ValueType vt, PatFrag pshuf_frag,
3944                          PatFrag bc_frag> {
3945 def ri : Ii8<0x70, MRMSrcReg,
3946               (outs VR128:$dst), (ins VR128:$src1, i8imm:$src2),
3947               !strconcat(OpcodeStr,
3948                          "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
3949               [(set VR128:$dst, (vt (pshuf_frag:$src2 VR128:$src1,
3950                                                       (undef))))]>;
3951 def mi : Ii8<0x70, MRMSrcMem,
3952               (outs VR128:$dst), (ins i128mem:$src1, i8imm:$src2),
3953               !strconcat(OpcodeStr,
3954                          "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
3955               [(set VR128:$dst, (vt (pshuf_frag:$src2
3956                                       (bc_frag (memopv2i64 addr:$src1)),
3957                                       (undef))))]>;
3958 }
3959
3960 multiclass sse2_pshuffle_y<string OpcodeStr, ValueType vt, PatFrag pshuf_frag,
3961                            PatFrag bc_frag> {
3962 def Yri : Ii8<0x70, MRMSrcReg,
3963               (outs VR256:$dst), (ins VR256:$src1, i8imm:$src2),
3964               !strconcat(OpcodeStr,
3965                          "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
3966               [(set VR256:$dst, (vt (pshuf_frag:$src2 VR256:$src1,
3967                                                       (undef))))]>;
3968 def Ymi : Ii8<0x70, MRMSrcMem,
3969               (outs VR256:$dst), (ins i256mem:$src1, i8imm:$src2),
3970               !strconcat(OpcodeStr,
3971                          "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
3972               [(set VR256:$dst, (vt (pshuf_frag:$src2
3973                                       (bc_frag (memopv4i64 addr:$src1)),
3974                                       (undef))))]>;
3975 }
3976 } // ExeDomain = SSEPackedInt
3977
3978 let Predicates = [HasAVX] in {
3979   let AddedComplexity = 5 in
3980   defm VPSHUFD : sse2_pshuffle<"vpshufd", v4i32, pshufd, bc_v4i32>, TB, OpSize,
3981                                VEX;
3982
3983   // SSE2 with ImmT == Imm8 and XS prefix.
3984   defm VPSHUFHW : sse2_pshuffle<"vpshufhw", v8i16, pshufhw, bc_v8i16>, XS,
3985                                VEX;
3986
3987   // SSE2 with ImmT == Imm8 and XD prefix.
3988   defm VPSHUFLW : sse2_pshuffle<"vpshuflw", v8i16, pshuflw, bc_v8i16>, XD,
3989                                VEX;
3990
3991   let AddedComplexity = 5 in
3992   def : Pat<(v4f32 (pshufd:$src2 VR128:$src1, (undef))),
3993             (VPSHUFDri VR128:$src1, (SHUFFLE_get_shuf_imm VR128:$src2))>;
3994   // Unary v4f32 shuffle with VPSHUF* in order to fold a load.
3995   def : Pat<(pshufd:$src2 (bc_v4i32 (memopv4f32 addr:$src1)), (undef)),
3996             (VPSHUFDmi addr:$src1, (SHUFFLE_get_shuf_imm VR128:$src2))>;
3997
3998   def : Pat<(v4i32 (X86PShufd (bc_v4i32 (memopv2i64 addr:$src1)),
3999                                    (i8 imm:$imm))),
4000             (VPSHUFDmi addr:$src1, imm:$imm)>;
4001   def : Pat<(v4i32 (X86PShufd (bc_v4i32 (memopv4f32 addr:$src1)),
4002                                    (i8 imm:$imm))),
4003             (VPSHUFDmi addr:$src1, imm:$imm)>;
4004   def : Pat<(v4f32 (X86PShufd VR128:$src1, (i8 imm:$imm))),
4005             (VPSHUFDri VR128:$src1, imm:$imm)>;
4006   def : Pat<(v4i32 (X86PShufd VR128:$src1, (i8 imm:$imm))),
4007             (VPSHUFDri VR128:$src1, imm:$imm)>;
4008   def : Pat<(v8i16 (X86PShufhw VR128:$src, (i8 imm:$imm))),
4009             (VPSHUFHWri VR128:$src, imm:$imm)>;
4010   def : Pat<(v8i16 (X86PShufhw (bc_v8i16 (memopv2i64 addr:$src)),
4011                                (i8 imm:$imm))),
4012             (VPSHUFHWmi addr:$src, imm:$imm)>;
4013   def : Pat<(v8i16 (X86PShuflw VR128:$src, (i8 imm:$imm))),
4014             (VPSHUFLWri VR128:$src, imm:$imm)>;
4015   def : Pat<(v8i16 (X86PShuflw (bc_v8i16 (memopv2i64 addr:$src)),
4016                                (i8 imm:$imm))),
4017             (VPSHUFLWmi addr:$src, imm:$imm)>;
4018 }
4019
4020 let Predicates = [HasAVX2] in {
4021   let AddedComplexity = 5 in
4022   defm VPSHUFD : sse2_pshuffle_y<"vpshufd", v8i32, pshufd, bc_v8i32>, TB,
4023                                  OpSize, VEX;
4024
4025   // SSE2 with ImmT == Imm8 and XS prefix.
4026   defm VPSHUFHW : sse2_pshuffle_y<"vpshufhw", v16i16, pshufhw, bc_v16i16>, XS,
4027                                   VEX;
4028
4029   // SSE2 with ImmT == Imm8 and XD prefix.
4030   defm VPSHUFLW : sse2_pshuffle_y<"vpshuflw", v16i16, pshuflw, bc_v16i16>, XD,
4031                                   VEX;
4032 }
4033
4034 let Predicates = [HasSSE2] in {
4035   let AddedComplexity = 5 in
4036   defm PSHUFD : sse2_pshuffle<"pshufd", v4i32, pshufd, bc_v4i32>, TB, OpSize;
4037
4038   // SSE2 with ImmT == Imm8 and XS prefix.
4039   defm PSHUFHW : sse2_pshuffle<"pshufhw", v8i16, pshufhw, bc_v8i16>, XS;
4040
4041   // SSE2 with ImmT == Imm8 and XD prefix.
4042   defm PSHUFLW : sse2_pshuffle<"pshuflw", v8i16, pshuflw, bc_v8i16>, XD;
4043
4044   let AddedComplexity = 5 in
4045   def : Pat<(v4f32 (pshufd:$src2 VR128:$src1, (undef))),
4046             (PSHUFDri VR128:$src1, (SHUFFLE_get_shuf_imm VR128:$src2))>;
4047   // Unary v4f32 shuffle with PSHUF* in order to fold a load.
4048   def : Pat<(pshufd:$src2 (bc_v4i32 (memopv4f32 addr:$src1)), (undef)),
4049             (PSHUFDmi addr:$src1, (SHUFFLE_get_shuf_imm VR128:$src2))>;
4050
4051   def : Pat<(v4i32 (X86PShufd (bc_v4i32 (memopv2i64 addr:$src1)),
4052                                    (i8 imm:$imm))),
4053             (PSHUFDmi addr:$src1, imm:$imm)>;
4054   def : Pat<(v4i32 (X86PShufd (bc_v4i32 (memopv4f32 addr:$src1)),
4055                                    (i8 imm:$imm))),
4056             (PSHUFDmi addr:$src1, imm:$imm)>;
4057   def : Pat<(v4f32 (X86PShufd VR128:$src1, (i8 imm:$imm))),
4058             (PSHUFDri VR128:$src1, imm:$imm)>;
4059   def : Pat<(v4i32 (X86PShufd VR128:$src1, (i8 imm:$imm))),
4060             (PSHUFDri VR128:$src1, imm:$imm)>;
4061   def : Pat<(v8i16 (X86PShufhw VR128:$src, (i8 imm:$imm))),
4062             (PSHUFHWri VR128:$src, imm:$imm)>;
4063   def : Pat<(v8i16 (X86PShufhw (bc_v8i16 (memopv2i64 addr:$src)),
4064                                (i8 imm:$imm))),
4065             (PSHUFHWmi addr:$src, imm:$imm)>;
4066   def : Pat<(v8i16 (X86PShuflw VR128:$src, (i8 imm:$imm))),
4067             (PSHUFLWri VR128:$src, imm:$imm)>;
4068   def : Pat<(v8i16 (X86PShuflw (bc_v8i16 (memopv2i64 addr:$src)),
4069                                (i8 imm:$imm))),
4070             (PSHUFLWmi addr:$src, imm:$imm)>;
4071 }
4072
4073 //===---------------------------------------------------------------------===//
4074 // SSE2 - Packed Integer Unpack Instructions
4075 //===---------------------------------------------------------------------===//
4076
4077 let ExeDomain = SSEPackedInt in {
4078 multiclass sse2_unpack<bits<8> opc, string OpcodeStr, ValueType vt,
4079                        SDNode OpNode, PatFrag bc_frag, bit Is2Addr = 1> {
4080   def rr : PDI<opc, MRMSrcReg,
4081       (outs VR128:$dst), (ins VR128:$src1, VR128:$src2),
4082       !if(Is2Addr,
4083           !strconcat(OpcodeStr,"\t{$src2, $dst|$dst, $src2}"),
4084           !strconcat(OpcodeStr,"\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
4085       [(set VR128:$dst, (vt (OpNode VR128:$src1, VR128:$src2)))]>;
4086   def rm : PDI<opc, MRMSrcMem,
4087       (outs VR128:$dst), (ins VR128:$src1, i128mem:$src2),
4088       !if(Is2Addr,
4089           !strconcat(OpcodeStr,"\t{$src2, $dst|$dst, $src2}"),
4090           !strconcat(OpcodeStr,"\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
4091       [(set VR128:$dst, (OpNode VR128:$src1,
4092                                   (bc_frag (memopv2i64
4093                                                addr:$src2))))]>;
4094 }
4095
4096 multiclass sse2_unpack_y<bits<8> opc, string OpcodeStr, ValueType vt,
4097                          SDNode OpNode, PatFrag bc_frag> {
4098   def Yrr : PDI<opc, MRMSrcReg,
4099       (outs VR256:$dst), (ins VR256:$src1, VR256:$src2),
4100       !strconcat(OpcodeStr,"\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4101       [(set VR256:$dst, (vt (OpNode VR256:$src1, VR256:$src2)))]>;
4102   def Yrm : PDI<opc, MRMSrcMem,
4103       (outs VR256:$dst), (ins VR256:$src1, i256mem:$src2),
4104       !strconcat(OpcodeStr,"\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4105       [(set VR256:$dst, (OpNode VR256:$src1,
4106                                   (bc_frag (memopv4i64 addr:$src2))))]>;
4107 }
4108
4109 let Predicates = [HasAVX] in {
4110   defm VPUNPCKLBW  : sse2_unpack<0x60, "vpunpcklbw", v16i8, X86Unpckl,
4111                                  bc_v16i8, 0>, VEX_4V;
4112   defm VPUNPCKLWD  : sse2_unpack<0x61, "vpunpcklwd", v8i16, X86Unpckl,
4113                                  bc_v8i16, 0>, VEX_4V;
4114   defm VPUNPCKLDQ  : sse2_unpack<0x62, "vpunpckldq", v4i32, X86Unpckl,
4115                                  bc_v4i32, 0>, VEX_4V;
4116   defm VPUNPCKLQDQ : sse2_unpack<0x6C, "vpunpcklqdq", v2i64, X86Unpckl,
4117                                  bc_v2i64, 0>, VEX_4V;
4118
4119   defm VPUNPCKHBW  : sse2_unpack<0x68, "vpunpckhbw", v16i8, X86Unpckh,
4120                                  bc_v16i8, 0>, VEX_4V;
4121   defm VPUNPCKHWD  : sse2_unpack<0x69, "vpunpckhwd", v8i16, X86Unpckh,
4122                                  bc_v8i16, 0>, VEX_4V;
4123   defm VPUNPCKHDQ  : sse2_unpack<0x6A, "vpunpckhdq", v4i32, X86Unpckh,
4124                                  bc_v4i32, 0>, VEX_4V;
4125   defm VPUNPCKHQDQ : sse2_unpack<0x6D, "vpunpckhqdq", v2i64, X86Unpckh,
4126                                  bc_v2i64, 0>, VEX_4V;
4127 }
4128
4129 let Predicates = [HasAVX2] in {
4130   defm VPUNPCKLBW  : sse2_unpack_y<0x60, "vpunpcklbw", v32i8, X86Unpckl,
4131                                    bc_v32i8>, VEX_4V;
4132   defm VPUNPCKLWD  : sse2_unpack_y<0x61, "vpunpcklwd", v16i16, X86Unpckl,
4133                                    bc_v16i16>, VEX_4V;
4134   defm VPUNPCKLDQ  : sse2_unpack_y<0x62, "vpunpckldq", v8i32, X86Unpckl,
4135                                    bc_v8i32>, VEX_4V;
4136   defm VPUNPCKLQDQ : sse2_unpack_y<0x6C, "vpunpcklqdq", v4i64, X86Unpckl,
4137                                    bc_v4i64>, VEX_4V;
4138
4139   defm VPUNPCKHBW  : sse2_unpack_y<0x68, "vpunpckhbw", v32i8, X86Unpckh,
4140                                    bc_v32i8>, VEX_4V;
4141   defm VPUNPCKHWD  : sse2_unpack_y<0x69, "vpunpckhwd", v16i16, X86Unpckh,
4142                                    bc_v16i16>, VEX_4V;
4143   defm VPUNPCKHDQ  : sse2_unpack_y<0x6A, "vpunpckhdq", v8i32, X86Unpckh,
4144                                    bc_v8i32>, VEX_4V;
4145   defm VPUNPCKHQDQ : sse2_unpack_y<0x6D, "vpunpckhqdq", v4i64, X86Unpckh,
4146                                    bc_v4i64>, VEX_4V;
4147 }
4148
4149 let Constraints = "$src1 = $dst" in {
4150   defm PUNPCKLBW  : sse2_unpack<0x60, "punpcklbw", v16i8, X86Unpckl,
4151                                 bc_v16i8>;
4152   defm PUNPCKLWD  : sse2_unpack<0x61, "punpcklwd", v8i16, X86Unpckl,
4153                                 bc_v8i16>;
4154   defm PUNPCKLDQ  : sse2_unpack<0x62, "punpckldq", v4i32, X86Unpckl,
4155                                 bc_v4i32>;
4156   defm PUNPCKLQDQ : sse2_unpack<0x6C, "punpcklqdq", v2i64, X86Unpckl,
4157                                 bc_v2i64>;
4158
4159   defm PUNPCKHBW  : sse2_unpack<0x68, "punpckhbw", v16i8, X86Unpckh,
4160                                 bc_v16i8>;
4161   defm PUNPCKHWD  : sse2_unpack<0x69, "punpckhwd", v8i16, X86Unpckh,
4162                                 bc_v8i16>;
4163   defm PUNPCKHDQ  : sse2_unpack<0x6A, "punpckhdq", v4i32, X86Unpckh,
4164                                 bc_v4i32>;
4165   defm PUNPCKHQDQ : sse2_unpack<0x6D, "punpckhqdq", v2i64, X86Unpckh,
4166                                 bc_v2i64>;
4167 }
4168 } // ExeDomain = SSEPackedInt
4169
4170 // Patterns for using AVX1 instructions with integer vectors
4171 // Here to give AVX2 priority
4172 let Predicates = [HasAVX] in {
4173   def : Pat<(v8i32 (X86Unpckl VR256:$src1, (bc_v8i32 (memopv4i64 addr:$src2)))),
4174             (VUNPCKLPSYrm VR256:$src1, addr:$src2)>;
4175   def : Pat<(v8i32 (X86Unpckl VR256:$src1, VR256:$src2)),
4176             (VUNPCKLPSYrr VR256:$src1, VR256:$src2)>;
4177   def : Pat<(v8i32 (X86Unpckh VR256:$src1, (bc_v8i32 (memopv4i64 addr:$src2)))),
4178             (VUNPCKHPSYrm VR256:$src1, addr:$src2)>;
4179   def : Pat<(v8i32 (X86Unpckh VR256:$src1, VR256:$src2)),
4180             (VUNPCKHPSYrr VR256:$src1, VR256:$src2)>;
4181
4182   def : Pat<(v4i64 (X86Unpckl VR256:$src1, (memopv4i64 addr:$src2))),
4183             (VUNPCKLPDYrm VR256:$src1, addr:$src2)>;
4184   def : Pat<(v4i64 (X86Unpckl VR256:$src1, VR256:$src2)),
4185             (VUNPCKLPDYrr VR256:$src1, VR256:$src2)>;
4186   def : Pat<(v4i64 (X86Unpckh VR256:$src1, (memopv4i64 addr:$src2))),
4187             (VUNPCKHPDYrm VR256:$src1, addr:$src2)>;
4188   def : Pat<(v4i64 (X86Unpckh VR256:$src1, VR256:$src2)),
4189             (VUNPCKHPDYrr VR256:$src1, VR256:$src2)>;
4190 }
4191
4192 // Splat v2f64 / v2i64
4193 let AddedComplexity = 10 in {
4194   def : Pat<(splat_lo (v2i64 VR128:$src), (undef)),
4195             (PUNPCKLQDQrr VR128:$src, VR128:$src)>, Requires<[HasSSE2]>;
4196   def : Pat<(splat_lo (v2i64 VR128:$src), (undef)),
4197             (VPUNPCKLQDQrr VR128:$src, VR128:$src)>, Requires<[HasAVX]>;
4198 }
4199
4200 //===---------------------------------------------------------------------===//
4201 // SSE2 - Packed Integer Extract and Insert
4202 //===---------------------------------------------------------------------===//
4203
4204 let ExeDomain = SSEPackedInt in {
4205 multiclass sse2_pinsrw<bit Is2Addr = 1> {
4206   def rri : Ii8<0xC4, MRMSrcReg,
4207        (outs VR128:$dst), (ins VR128:$src1,
4208         GR32:$src2, i32i8imm:$src3),
4209        !if(Is2Addr,
4210            "pinsrw\t{$src3, $src2, $dst|$dst, $src2, $src3}",
4211            "vpinsrw\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
4212        [(set VR128:$dst,
4213          (X86pinsrw VR128:$src1, GR32:$src2, imm:$src3))]>;
4214   def rmi : Ii8<0xC4, MRMSrcMem,
4215                        (outs VR128:$dst), (ins VR128:$src1,
4216                         i16mem:$src2, i32i8imm:$src3),
4217        !if(Is2Addr,
4218            "pinsrw\t{$src3, $src2, $dst|$dst, $src2, $src3}",
4219            "vpinsrw\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
4220        [(set VR128:$dst,
4221          (X86pinsrw VR128:$src1, (extloadi16 addr:$src2),
4222                     imm:$src3))]>;
4223 }
4224
4225 // Extract
4226 let Predicates = [HasAVX] in
4227 def VPEXTRWri : Ii8<0xC5, MRMSrcReg,
4228                     (outs GR32:$dst), (ins VR128:$src1, i32i8imm:$src2),
4229                     "vpextrw\t{$src2, $src1, $dst|$dst, $src1, $src2}",
4230                     [(set GR32:$dst, (X86pextrw (v8i16 VR128:$src1),
4231                                                 imm:$src2))]>, TB, OpSize, VEX;
4232 def PEXTRWri : PDIi8<0xC5, MRMSrcReg,
4233                     (outs GR32:$dst), (ins VR128:$src1, i32i8imm:$src2),
4234                     "pextrw\t{$src2, $src1, $dst|$dst, $src1, $src2}",
4235                     [(set GR32:$dst, (X86pextrw (v8i16 VR128:$src1),
4236                                                 imm:$src2))]>;
4237
4238 // Insert
4239 let Predicates = [HasAVX] in {
4240   defm VPINSRW : sse2_pinsrw<0>, TB, OpSize, VEX_4V;
4241   def  VPINSRWrr64i : Ii8<0xC4, MRMSrcReg, (outs VR128:$dst),
4242        (ins VR128:$src1, GR64:$src2, i32i8imm:$src3),
4243        "vpinsrw\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
4244        []>, TB, OpSize, VEX_4V;
4245 }
4246
4247 let Constraints = "$src1 = $dst" in
4248   defm PINSRW : sse2_pinsrw, TB, OpSize, Requires<[HasSSE2]>;
4249
4250 } // ExeDomain = SSEPackedInt
4251
4252 //===---------------------------------------------------------------------===//
4253 // SSE2 - Packed Mask Creation
4254 //===---------------------------------------------------------------------===//
4255
4256 let ExeDomain = SSEPackedInt in {
4257
4258 def VPMOVMSKBrr  : VPDI<0xD7, MRMSrcReg, (outs GR32:$dst), (ins VR128:$src),
4259            "pmovmskb\t{$src, $dst|$dst, $src}",
4260            [(set GR32:$dst, (int_x86_sse2_pmovmskb_128 VR128:$src))]>, VEX;
4261 def VPMOVMSKBr64r : VPDI<0xD7, MRMSrcReg, (outs GR64:$dst), (ins VR128:$src),
4262            "pmovmskb\t{$src, $dst|$dst, $src}", []>, VEX;
4263
4264 let Predicates = [HasAVX2] in {
4265 def VPMOVMSKBYrr  : VPDI<0xD7, MRMSrcReg, (outs GR32:$dst), (ins VR256:$src),
4266            "pmovmskb\t{$src, $dst|$dst, $src}",
4267            [(set GR32:$dst, (int_x86_avx2_pmovmskb VR256:$src))]>, VEX;
4268 def VPMOVMSKBYr64r : VPDI<0xD7, MRMSrcReg, (outs GR64:$dst), (ins VR256:$src),
4269            "pmovmskb\t{$src, $dst|$dst, $src}", []>, VEX;
4270 }
4271
4272 def PMOVMSKBrr : PDI<0xD7, MRMSrcReg, (outs GR32:$dst), (ins VR128:$src),
4273            "pmovmskb\t{$src, $dst|$dst, $src}",
4274            [(set GR32:$dst, (int_x86_sse2_pmovmskb_128 VR128:$src))]>;
4275
4276 } // ExeDomain = SSEPackedInt
4277
4278 //===---------------------------------------------------------------------===//
4279 // SSE2 - Conditional Store
4280 //===---------------------------------------------------------------------===//
4281
4282 let ExeDomain = SSEPackedInt in {
4283
4284 let Uses = [EDI] in
4285 def VMASKMOVDQU : VPDI<0xF7, MRMSrcReg, (outs),
4286            (ins VR128:$src, VR128:$mask),
4287            "maskmovdqu\t{$mask, $src|$src, $mask}",
4288            [(int_x86_sse2_maskmov_dqu VR128:$src, VR128:$mask, EDI)]>, VEX;
4289 let Uses = [RDI] in
4290 def VMASKMOVDQU64 : VPDI<0xF7, MRMSrcReg, (outs),
4291            (ins VR128:$src, VR128:$mask),
4292            "maskmovdqu\t{$mask, $src|$src, $mask}",
4293            [(int_x86_sse2_maskmov_dqu VR128:$src, VR128:$mask, RDI)]>, VEX;
4294
4295 let Uses = [EDI] in
4296 def MASKMOVDQU : PDI<0xF7, MRMSrcReg, (outs), (ins VR128:$src, VR128:$mask),
4297            "maskmovdqu\t{$mask, $src|$src, $mask}",
4298            [(int_x86_sse2_maskmov_dqu VR128:$src, VR128:$mask, EDI)]>;
4299 let Uses = [RDI] in
4300 def MASKMOVDQU64 : PDI<0xF7, MRMSrcReg, (outs), (ins VR128:$src, VR128:$mask),
4301            "maskmovdqu\t{$mask, $src|$src, $mask}",
4302            [(int_x86_sse2_maskmov_dqu VR128:$src, VR128:$mask, RDI)]>;
4303
4304 } // ExeDomain = SSEPackedInt
4305
4306 //===---------------------------------------------------------------------===//
4307 // SSE2 - Move Doubleword
4308 //===---------------------------------------------------------------------===//
4309
4310 //===---------------------------------------------------------------------===//
4311 // Move Int Doubleword to Packed Double Int
4312 //
4313 def VMOVDI2PDIrr : VPDI<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR32:$src),
4314                       "movd\t{$src, $dst|$dst, $src}",
4315                       [(set VR128:$dst,
4316                         (v4i32 (scalar_to_vector GR32:$src)))]>, VEX;
4317 def VMOVDI2PDIrm : VPDI<0x6E, MRMSrcMem, (outs VR128:$dst), (ins i32mem:$src),
4318                       "movd\t{$src, $dst|$dst, $src}",
4319                       [(set VR128:$dst,
4320                         (v4i32 (scalar_to_vector (loadi32 addr:$src))))]>,
4321                       VEX;
4322 def VMOV64toPQIrr : VRPDI<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR64:$src),
4323                         "mov{d|q}\t{$src, $dst|$dst, $src}",
4324                         [(set VR128:$dst,
4325                           (v2i64 (scalar_to_vector GR64:$src)))]>, VEX;
4326 def VMOV64toSDrr : VRPDI<0x6E, MRMSrcReg, (outs FR64:$dst), (ins GR64:$src),
4327                        "mov{d|q}\t{$src, $dst|$dst, $src}",
4328                        [(set FR64:$dst, (bitconvert GR64:$src))]>, VEX;
4329
4330 def MOVDI2PDIrr : PDI<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR32:$src),
4331                       "movd\t{$src, $dst|$dst, $src}",
4332                       [(set VR128:$dst,
4333                         (v4i32 (scalar_to_vector GR32:$src)))]>;
4334 def MOVDI2PDIrm : PDI<0x6E, MRMSrcMem, (outs VR128:$dst), (ins i32mem:$src),
4335                       "movd\t{$src, $dst|$dst, $src}",
4336                       [(set VR128:$dst,
4337                         (v4i32 (scalar_to_vector (loadi32 addr:$src))))]>;
4338 def MOV64toPQIrr : RPDI<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR64:$src),
4339                         "mov{d|q}\t{$src, $dst|$dst, $src}",
4340                         [(set VR128:$dst,
4341                           (v2i64 (scalar_to_vector GR64:$src)))]>;
4342 def MOV64toSDrr : RPDI<0x6E, MRMSrcReg, (outs FR64:$dst), (ins GR64:$src),
4343                        "mov{d|q}\t{$src, $dst|$dst, $src}",
4344                        [(set FR64:$dst, (bitconvert GR64:$src))]>;
4345
4346 //===---------------------------------------------------------------------===//
4347 // Move Int Doubleword to Single Scalar
4348 //
4349 def VMOVDI2SSrr  : VPDI<0x6E, MRMSrcReg, (outs FR32:$dst), (ins GR32:$src),
4350                       "movd\t{$src, $dst|$dst, $src}",
4351                       [(set FR32:$dst, (bitconvert GR32:$src))]>, VEX;
4352
4353 def VMOVDI2SSrm  : VPDI<0x6E, MRMSrcMem, (outs FR32:$dst), (ins i32mem:$src),
4354                       "movd\t{$src, $dst|$dst, $src}",
4355                       [(set FR32:$dst, (bitconvert (loadi32 addr:$src)))]>,
4356                       VEX;
4357 def MOVDI2SSrr  : PDI<0x6E, MRMSrcReg, (outs FR32:$dst), (ins GR32:$src),
4358                       "movd\t{$src, $dst|$dst, $src}",
4359                       [(set FR32:$dst, (bitconvert GR32:$src))]>;
4360
4361 def MOVDI2SSrm  : PDI<0x6E, MRMSrcMem, (outs FR32:$dst), (ins i32mem:$src),
4362                       "movd\t{$src, $dst|$dst, $src}",
4363                       [(set FR32:$dst, (bitconvert (loadi32 addr:$src)))]>;
4364
4365 //===---------------------------------------------------------------------===//
4366 // Move Packed Doubleword Int to Packed Double Int
4367 //
4368 def VMOVPDI2DIrr  : VPDI<0x7E, MRMDestReg, (outs GR32:$dst), (ins VR128:$src),
4369                        "movd\t{$src, $dst|$dst, $src}",
4370                        [(set GR32:$dst, (vector_extract (v4i32 VR128:$src),
4371                                         (iPTR 0)))]>, VEX;
4372 def VMOVPDI2DImr  : VPDI<0x7E, MRMDestMem, (outs),
4373                        (ins i32mem:$dst, VR128:$src),
4374                        "movd\t{$src, $dst|$dst, $src}",
4375                        [(store (i32 (vector_extract (v4i32 VR128:$src),
4376                                      (iPTR 0))), addr:$dst)]>, VEX;
4377 def MOVPDI2DIrr  : PDI<0x7E, MRMDestReg, (outs GR32:$dst), (ins VR128:$src),
4378                        "movd\t{$src, $dst|$dst, $src}",
4379                        [(set GR32:$dst, (vector_extract (v4i32 VR128:$src),
4380                                         (iPTR 0)))]>;
4381 def MOVPDI2DImr  : PDI<0x7E, MRMDestMem, (outs), (ins i32mem:$dst, VR128:$src),
4382                        "movd\t{$src, $dst|$dst, $src}",
4383                        [(store (i32 (vector_extract (v4i32 VR128:$src),
4384                                      (iPTR 0))), addr:$dst)]>;
4385
4386 //===---------------------------------------------------------------------===//
4387 // Move Packed Doubleword Int first element to Doubleword Int
4388 //
4389 def VMOVPQIto64rr : I<0x7E, MRMDestReg, (outs GR64:$dst), (ins VR128:$src),
4390                           "mov{d|q}\t{$src, $dst|$dst, $src}",
4391                           [(set GR64:$dst, (vector_extract (v2i64 VR128:$src),
4392                                                            (iPTR 0)))]>,
4393                       TB, OpSize, VEX, VEX_W, Requires<[HasAVX, In64BitMode]>;
4394
4395 def MOVPQIto64rr : RPDI<0x7E, MRMDestReg, (outs GR64:$dst), (ins VR128:$src),
4396                         "mov{d|q}\t{$src, $dst|$dst, $src}",
4397                         [(set GR64:$dst, (vector_extract (v2i64 VR128:$src),
4398                                                          (iPTR 0)))]>;
4399
4400 //===---------------------------------------------------------------------===//
4401 // Bitcast FR64 <-> GR64
4402 //
4403 let Predicates = [HasAVX] in
4404 def VMOV64toSDrm : S3SI<0x7E, MRMSrcMem, (outs FR64:$dst), (ins i64mem:$src),
4405                         "vmovq\t{$src, $dst|$dst, $src}",
4406                         [(set FR64:$dst, (bitconvert (loadi64 addr:$src)))]>,
4407                         VEX;
4408 def VMOVSDto64rr : VRPDI<0x7E, MRMDestReg, (outs GR64:$dst), (ins FR64:$src),
4409                          "mov{d|q}\t{$src, $dst|$dst, $src}",
4410                          [(set GR64:$dst, (bitconvert FR64:$src))]>, VEX;
4411 def VMOVSDto64mr : VRPDI<0x7E, MRMDestMem, (outs), (ins i64mem:$dst, FR64:$src),
4412                          "movq\t{$src, $dst|$dst, $src}",
4413                          [(store (i64 (bitconvert FR64:$src)), addr:$dst)]>,
4414                          VEX;
4415
4416 def MOV64toSDrm : S3SI<0x7E, MRMSrcMem, (outs FR64:$dst), (ins i64mem:$src),
4417                        "movq\t{$src, $dst|$dst, $src}",
4418                        [(set FR64:$dst, (bitconvert (loadi64 addr:$src)))]>;
4419 def MOVSDto64rr : RPDI<0x7E, MRMDestReg, (outs GR64:$dst), (ins FR64:$src),
4420                        "mov{d|q}\t{$src, $dst|$dst, $src}",
4421                        [(set GR64:$dst, (bitconvert FR64:$src))]>;
4422 def MOVSDto64mr : RPDI<0x7E, MRMDestMem, (outs), (ins i64mem:$dst, FR64:$src),
4423                        "movq\t{$src, $dst|$dst, $src}",
4424                        [(store (i64 (bitconvert FR64:$src)), addr:$dst)]>;
4425
4426 //===---------------------------------------------------------------------===//
4427 // Move Scalar Single to Double Int
4428 //
4429 def VMOVSS2DIrr  : VPDI<0x7E, MRMDestReg, (outs GR32:$dst), (ins FR32:$src),
4430                       "movd\t{$src, $dst|$dst, $src}",
4431                       [(set GR32:$dst, (bitconvert FR32:$src))]>, VEX;
4432 def VMOVSS2DImr  : VPDI<0x7E, MRMDestMem, (outs), (ins i32mem:$dst, FR32:$src),
4433                       "movd\t{$src, $dst|$dst, $src}",
4434                       [(store (i32 (bitconvert FR32:$src)), addr:$dst)]>, VEX;
4435 def MOVSS2DIrr  : PDI<0x7E, MRMDestReg, (outs GR32:$dst), (ins FR32:$src),
4436                       "movd\t{$src, $dst|$dst, $src}",
4437                       [(set GR32:$dst, (bitconvert FR32:$src))]>;
4438 def MOVSS2DImr  : PDI<0x7E, MRMDestMem, (outs), (ins i32mem:$dst, FR32:$src),
4439                       "movd\t{$src, $dst|$dst, $src}",
4440                       [(store (i32 (bitconvert FR32:$src)), addr:$dst)]>;
4441
4442 //===---------------------------------------------------------------------===//
4443 // Patterns and instructions to describe movd/movq to XMM register zero-extends
4444 //
4445 let AddedComplexity = 15 in {
4446 def VMOVZDI2PDIrr : VPDI<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR32:$src),
4447                        "movd\t{$src, $dst|$dst, $src}",
4448                        [(set VR128:$dst, (v4i32 (X86vzmovl
4449                                       (v4i32 (scalar_to_vector GR32:$src)))))]>,
4450                                       VEX;
4451 def VMOVZQI2PQIrr : VPDI<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR64:$src),
4452                        "mov{d|q}\t{$src, $dst|$dst, $src}", // X86-64 only
4453                        [(set VR128:$dst, (v2i64 (X86vzmovl
4454                                       (v2i64 (scalar_to_vector GR64:$src)))))]>,
4455                                       VEX, VEX_W;
4456 }
4457 let AddedComplexity = 15 in {
4458 def MOVZDI2PDIrr : PDI<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR32:$src),
4459                        "movd\t{$src, $dst|$dst, $src}",
4460                        [(set VR128:$dst, (v4i32 (X86vzmovl
4461                                       (v4i32 (scalar_to_vector GR32:$src)))))]>;
4462 def MOVZQI2PQIrr : RPDI<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR64:$src),
4463                        "mov{d|q}\t{$src, $dst|$dst, $src}", // X86-64 only
4464                        [(set VR128:$dst, (v2i64 (X86vzmovl
4465                                       (v2i64 (scalar_to_vector GR64:$src)))))]>;
4466 }
4467
4468 let AddedComplexity = 20 in {
4469 def VMOVZDI2PDIrm : VPDI<0x6E, MRMSrcMem, (outs VR128:$dst), (ins i32mem:$src),
4470                        "movd\t{$src, $dst|$dst, $src}",
4471                        [(set VR128:$dst,
4472                          (v4i32 (X86vzmovl (v4i32 (scalar_to_vector
4473                                                    (loadi32 addr:$src))))))]>,
4474                                                    VEX;
4475 def MOVZDI2PDIrm : PDI<0x6E, MRMSrcMem, (outs VR128:$dst), (ins i32mem:$src),
4476                        "movd\t{$src, $dst|$dst, $src}",
4477                        [(set VR128:$dst,
4478                          (v4i32 (X86vzmovl (v4i32 (scalar_to_vector
4479                                                    (loadi32 addr:$src))))))]>;
4480 }
4481
4482 let Predicates = [HasAVX] in {
4483   // AVX 128-bit movd/movq instruction write zeros in the high 128-bit part.
4484   let AddedComplexity = 20 in {
4485     def : Pat<(v4i32 (X86vzmovl (bc_v4i32 (loadv4f32 addr:$src)))),
4486               (VMOVZDI2PDIrm addr:$src)>;
4487     def : Pat<(v4i32 (X86vzmovl (bc_v4i32 (loadv2i64 addr:$src)))),
4488               (VMOVZDI2PDIrm addr:$src)>;
4489   }
4490   // Use regular 128-bit instructions to match 256-bit scalar_to_vec+zext.
4491   def : Pat<(v8i32 (X86vzmovl (insert_subvector undef,
4492                                 (v4i32 (scalar_to_vector GR32:$src)),(i32 0)))),
4493             (SUBREG_TO_REG (i32 0), (VMOVZDI2PDIrr GR32:$src), sub_xmm)>;
4494   def : Pat<(v4i64 (X86vzmovl (insert_subvector undef,
4495                                 (v2i64 (scalar_to_vector GR64:$src)),(i32 0)))),
4496             (SUBREG_TO_REG (i64 0), (VMOVZQI2PQIrr GR64:$src), sub_xmm)>;
4497 }
4498
4499 let Predicates = [HasSSE2], AddedComplexity = 20 in {
4500   def : Pat<(v4i32 (X86vzmovl (bc_v4i32 (loadv4f32 addr:$src)))),
4501             (MOVZDI2PDIrm addr:$src)>;
4502   def : Pat<(v4i32 (X86vzmovl (bc_v4i32 (loadv2i64 addr:$src)))),
4503             (MOVZDI2PDIrm addr:$src)>;
4504 }
4505
4506 // These are the correct encodings of the instructions so that we know how to
4507 // read correct assembly, even though we continue to emit the wrong ones for
4508 // compatibility with Darwin's buggy assembler.
4509 def : InstAlias<"movq\t{$src, $dst|$dst, $src}",
4510                 (MOV64toPQIrr VR128:$dst, GR64:$src), 0>;
4511 def : InstAlias<"movq\t{$src, $dst|$dst, $src}",
4512                 (MOV64toSDrr FR64:$dst, GR64:$src), 0>;
4513 def : InstAlias<"movq\t{$src, $dst|$dst, $src}",
4514                 (MOVPQIto64rr GR64:$dst, VR128:$src), 0>;
4515 def : InstAlias<"movq\t{$src, $dst|$dst, $src}",
4516                 (MOVSDto64rr GR64:$dst, FR64:$src), 0>;
4517 def : InstAlias<"movq\t{$src, $dst|$dst, $src}",
4518                 (VMOVZQI2PQIrr VR128:$dst, GR64:$src), 0>;
4519 def : InstAlias<"movq\t{$src, $dst|$dst, $src}",
4520                 (MOVZQI2PQIrr VR128:$dst, GR64:$src), 0>;
4521
4522 //===---------------------------------------------------------------------===//
4523 // SSE2 - Move Quadword
4524 //===---------------------------------------------------------------------===//
4525
4526 //===---------------------------------------------------------------------===//
4527 // Move Quadword Int to Packed Quadword Int
4528 //
4529 def VMOVQI2PQIrm : I<0x7E, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
4530                     "vmovq\t{$src, $dst|$dst, $src}",
4531                     [(set VR128:$dst,
4532                       (v2i64 (scalar_to_vector (loadi64 addr:$src))))]>, XS,
4533                     VEX, Requires<[HasAVX]>;
4534 def MOVQI2PQIrm : I<0x7E, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
4535                     "movq\t{$src, $dst|$dst, $src}",
4536                     [(set VR128:$dst,
4537                       (v2i64 (scalar_to_vector (loadi64 addr:$src))))]>, XS,
4538                     Requires<[HasSSE2]>; // SSE2 instruction with XS Prefix
4539
4540 //===---------------------------------------------------------------------===//
4541 // Move Packed Quadword Int to Quadword Int
4542 //
4543 def VMOVPQI2QImr : VPDI<0xD6, MRMDestMem, (outs), (ins i64mem:$dst, VR128:$src),
4544                       "movq\t{$src, $dst|$dst, $src}",
4545                       [(store (i64 (vector_extract (v2i64 VR128:$src),
4546                                     (iPTR 0))), addr:$dst)]>, VEX;
4547 def MOVPQI2QImr : PDI<0xD6, MRMDestMem, (outs), (ins i64mem:$dst, VR128:$src),
4548                       "movq\t{$src, $dst|$dst, $src}",
4549                       [(store (i64 (vector_extract (v2i64 VR128:$src),
4550                                     (iPTR 0))), addr:$dst)]>;
4551
4552 //===---------------------------------------------------------------------===//
4553 // Store / copy lower 64-bits of a XMM register.
4554 //
4555 def VMOVLQ128mr : VPDI<0xD6, MRMDestMem, (outs), (ins i64mem:$dst, VR128:$src),
4556                      "movq\t{$src, $dst|$dst, $src}",
4557                      [(int_x86_sse2_storel_dq addr:$dst, VR128:$src)]>, VEX;
4558 def MOVLQ128mr : PDI<0xD6, MRMDestMem, (outs), (ins i64mem:$dst, VR128:$src),
4559                      "movq\t{$src, $dst|$dst, $src}",
4560                      [(int_x86_sse2_storel_dq addr:$dst, VR128:$src)]>;
4561
4562 let AddedComplexity = 20 in
4563 def VMOVZQI2PQIrm : I<0x7E, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
4564                      "vmovq\t{$src, $dst|$dst, $src}",
4565                      [(set VR128:$dst,
4566                        (v2i64 (X86vzmovl (v2i64 (scalar_to_vector
4567                                                  (loadi64 addr:$src))))))]>,
4568                      XS, VEX, Requires<[HasAVX]>;
4569
4570 let AddedComplexity = 20 in
4571 def MOVZQI2PQIrm : I<0x7E, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
4572                      "movq\t{$src, $dst|$dst, $src}",
4573                      [(set VR128:$dst,
4574                        (v2i64 (X86vzmovl (v2i64 (scalar_to_vector
4575                                                  (loadi64 addr:$src))))))]>,
4576                      XS, Requires<[HasSSE2]>;
4577
4578 let Predicates = [HasAVX], AddedComplexity = 20 in {
4579   def : Pat<(v2i64 (X86vzmovl (loadv2i64 addr:$src))),
4580             (VMOVZQI2PQIrm addr:$src)>;
4581   def : Pat<(v2i64 (X86vzmovl (bc_v2i64 (loadv4f32 addr:$src)))),
4582             (VMOVZQI2PQIrm addr:$src)>;
4583   def : Pat<(v2i64 (X86vzload addr:$src)),
4584             (VMOVZQI2PQIrm addr:$src)>;
4585 }
4586
4587 let Predicates = [HasSSE2], AddedComplexity = 20 in {
4588   def : Pat<(v2i64 (X86vzmovl (loadv2i64 addr:$src))),
4589             (MOVZQI2PQIrm addr:$src)>;
4590   def : Pat<(v2i64 (X86vzmovl (bc_v2i64 (loadv4f32 addr:$src)))),
4591             (MOVZQI2PQIrm addr:$src)>;
4592   def : Pat<(v2i64 (X86vzload addr:$src)), (MOVZQI2PQIrm addr:$src)>;
4593 }
4594
4595 let Predicates = [HasAVX] in {
4596 def : Pat<(v4i64 (X86vzload addr:$src)),
4597           (SUBREG_TO_REG (i32 0), (VMOVAPSrm addr:$src), sub_xmm)>;
4598 }
4599
4600 //===---------------------------------------------------------------------===//
4601 // Moving from XMM to XMM and clear upper 64 bits. Note, there is a bug in
4602 // IA32 document. movq xmm1, xmm2 does clear the high bits.
4603 //
4604 let AddedComplexity = 15 in
4605 def VMOVZPQILo2PQIrr : I<0x7E, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
4606                         "vmovq\t{$src, $dst|$dst, $src}",
4607                     [(set VR128:$dst, (v2i64 (X86vzmovl (v2i64 VR128:$src))))]>,
4608                       XS, VEX, Requires<[HasAVX]>;
4609 let AddedComplexity = 15 in
4610 def MOVZPQILo2PQIrr : I<0x7E, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
4611                         "movq\t{$src, $dst|$dst, $src}",
4612                     [(set VR128:$dst, (v2i64 (X86vzmovl (v2i64 VR128:$src))))]>,
4613                       XS, Requires<[HasSSE2]>;
4614
4615 let AddedComplexity = 20 in
4616 def VMOVZPQILo2PQIrm : I<0x7E, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
4617                         "vmovq\t{$src, $dst|$dst, $src}",
4618                     [(set VR128:$dst, (v2i64 (X86vzmovl
4619                                              (loadv2i64 addr:$src))))]>,
4620                       XS, VEX, Requires<[HasAVX]>;
4621 let AddedComplexity = 20 in {
4622 def MOVZPQILo2PQIrm : I<0x7E, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
4623                         "movq\t{$src, $dst|$dst, $src}",
4624                     [(set VR128:$dst, (v2i64 (X86vzmovl
4625                                              (loadv2i64 addr:$src))))]>,
4626                       XS, Requires<[HasSSE2]>;
4627 }
4628
4629 let AddedComplexity = 20 in {
4630   let Predicates = [HasAVX] in {
4631     def : Pat<(v2i64 (X86vzmovl (loadv2i64 addr:$src))),
4632               (VMOVZPQILo2PQIrm addr:$src)>;
4633     def : Pat<(v2f64 (X86vzmovl (v2f64 VR128:$src))),
4634               (VMOVZPQILo2PQIrr VR128:$src)>;
4635   }
4636   let Predicates = [HasSSE2] in {
4637     def : Pat<(v2i64 (X86vzmovl (loadv2i64 addr:$src))),
4638               (MOVZPQILo2PQIrm addr:$src)>;
4639     def : Pat<(v2f64 (X86vzmovl (v2f64 VR128:$src))),
4640               (MOVZPQILo2PQIrr VR128:$src)>;
4641   }
4642 }
4643
4644 // Instructions to match in the assembler
4645 def VMOVQs64rr : VPDI<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR64:$src),
4646                       "movq\t{$src, $dst|$dst, $src}", []>, VEX, VEX_W;
4647 def VMOVQd64rr : VPDI<0x7E, MRMDestReg, (outs GR64:$dst), (ins VR128:$src),
4648                       "movq\t{$src, $dst|$dst, $src}", []>, VEX, VEX_W;
4649 // Recognize "movd" with GR64 destination, but encode as a "movq"
4650 def VMOVQd64rr_alt : VPDI<0x7E, MRMDestReg, (outs GR64:$dst), (ins VR128:$src),
4651                           "movd\t{$src, $dst|$dst, $src}", []>, VEX, VEX_W;
4652
4653 // Instructions for the disassembler
4654 // xr = XMM register
4655 // xm = mem64
4656
4657 let Predicates = [HasAVX] in
4658 def VMOVQxrxr: I<0x7E, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
4659                  "vmovq\t{$src, $dst|$dst, $src}", []>, VEX, XS;
4660 def MOVQxrxr : I<0x7E, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
4661                  "movq\t{$src, $dst|$dst, $src}", []>, XS;
4662
4663 //===---------------------------------------------------------------------===//
4664 // SSE3 - Conversion Instructions
4665 //===---------------------------------------------------------------------===//
4666
4667 // Convert Packed Double FP to Packed DW Integers
4668 let Predicates = [HasAVX] in {
4669 // The assembler can recognize rr 256-bit instructions by seeing a ymm
4670 // register, but the same isn't true when using memory operands instead.
4671 // Provide other assembly rr and rm forms to address this explicitly.
4672 def VCVTPD2DQrr  : S3DI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
4673                        "vcvtpd2dq\t{$src, $dst|$dst, $src}", []>, VEX;
4674 def VCVTPD2DQXrYr  : S3DI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR256:$src),
4675                        "vcvtpd2dq\t{$src, $dst|$dst, $src}", []>, VEX;
4676
4677 // XMM only
4678 def VCVTPD2DQXrr : S3DI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
4679                       "vcvtpd2dqx\t{$src, $dst|$dst, $src}", []>, VEX;
4680 def VCVTPD2DQXrm : S3DI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
4681                       "vcvtpd2dqx\t{$src, $dst|$dst, $src}", []>, VEX;
4682
4683 // YMM only
4684 def VCVTPD2DQYrr : S3DI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR256:$src),
4685                       "vcvtpd2dqy\t{$src, $dst|$dst, $src}", []>, VEX;
4686 def VCVTPD2DQYrm : S3DI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f256mem:$src),
4687                       "vcvtpd2dqy\t{$src, $dst|$dst, $src}", []>, VEX, VEX_L;
4688 }
4689
4690 def CVTPD2DQrm  : S3DI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
4691                        "cvtpd2dq\t{$src, $dst|$dst, $src}", []>;
4692 def CVTPD2DQrr  : S3DI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
4693                        "cvtpd2dq\t{$src, $dst|$dst, $src}", []>;
4694
4695 def : Pat<(v4i32 (fp_to_sint (v4f64 VR256:$src))),
4696           (VCVTPD2DQYrr VR256:$src)>;
4697 def : Pat<(v4i32 (fp_to_sint (memopv4f64 addr:$src))),
4698           (VCVTPD2DQYrm addr:$src)>;
4699
4700 // Convert Packed DW Integers to Packed Double FP
4701 let Predicates = [HasAVX] in {
4702 def VCVTDQ2PDrm  : S3SI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
4703                      "vcvtdq2pd\t{$src, $dst|$dst, $src}", []>, VEX;
4704 def VCVTDQ2PDrr  : S3SI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
4705                      "vcvtdq2pd\t{$src, $dst|$dst, $src}", []>, VEX;
4706 def VCVTDQ2PDYrm  : S3SI<0xE6, MRMSrcMem, (outs VR256:$dst), (ins f128mem:$src),
4707                      "vcvtdq2pd\t{$src, $dst|$dst, $src}", []>, VEX;
4708 def VCVTDQ2PDYrr  : S3SI<0xE6, MRMSrcReg, (outs VR256:$dst), (ins VR128:$src),
4709                      "vcvtdq2pd\t{$src, $dst|$dst, $src}", []>, VEX;
4710 }
4711
4712 def CVTDQ2PDrm  : S3SI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
4713                        "cvtdq2pd\t{$src, $dst|$dst, $src}", []>;
4714 def CVTDQ2PDrr  : S3SI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
4715                        "cvtdq2pd\t{$src, $dst|$dst, $src}", []>;
4716
4717 // AVX 256-bit register conversion intrinsics
4718 def : Pat<(int_x86_avx_cvtdq2_pd_256 VR128:$src),
4719            (VCVTDQ2PDYrr VR128:$src)>;
4720 def : Pat<(int_x86_avx_cvtdq2_pd_256 (bitconvert (memopv2i64 addr:$src))),
4721            (VCVTDQ2PDYrm addr:$src)>;
4722
4723 def : Pat<(int_x86_avx_cvt_pd2dq_256 VR256:$src),
4724           (VCVTPD2DQYrr VR256:$src)>;
4725 def : Pat<(int_x86_avx_cvt_pd2dq_256 (memopv4f64 addr:$src)),
4726           (VCVTPD2DQYrm addr:$src)>;
4727
4728 def : Pat<(v4f64 (sint_to_fp (v4i32 VR128:$src))),
4729           (VCVTDQ2PDYrr VR128:$src)>;
4730 def : Pat<(v4f64 (sint_to_fp (bc_v4i32 (memopv2i64 addr:$src)))),
4731           (VCVTDQ2PDYrm addr:$src)>;
4732
4733 //===---------------------------------------------------------------------===//
4734 // SSE3 - Replicate Single FP - MOVSHDUP and MOVSLDUP
4735 //===---------------------------------------------------------------------===//
4736 multiclass sse3_replicate_sfp<bits<8> op, SDNode OpNode, string OpcodeStr,
4737                               ValueType vt, RegisterClass RC, PatFrag mem_frag,
4738                               X86MemOperand x86memop> {
4739 def rr : S3SI<op, MRMSrcReg, (outs RC:$dst), (ins RC:$src),
4740                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
4741                       [(set RC:$dst, (vt (OpNode RC:$src)))]>;
4742 def rm : S3SI<op, MRMSrcMem, (outs RC:$dst), (ins x86memop:$src),
4743                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
4744                       [(set RC:$dst, (OpNode (mem_frag addr:$src)))]>;
4745 }
4746
4747 let Predicates = [HasAVX] in {
4748   defm VMOVSHDUP  : sse3_replicate_sfp<0x16, X86Movshdup, "vmovshdup",
4749                                        v4f32, VR128, memopv4f32, f128mem>, VEX;
4750   defm VMOVSLDUP  : sse3_replicate_sfp<0x12, X86Movsldup, "vmovsldup",
4751                                        v4f32, VR128, memopv4f32, f128mem>, VEX;
4752   defm VMOVSHDUPY : sse3_replicate_sfp<0x16, X86Movshdup, "vmovshdup",
4753                                        v8f32, VR256, memopv8f32, f256mem>, VEX;
4754   defm VMOVSLDUPY : sse3_replicate_sfp<0x12, X86Movsldup, "vmovsldup",
4755                                        v8f32, VR256, memopv8f32, f256mem>, VEX;
4756 }
4757 defm MOVSHDUP : sse3_replicate_sfp<0x16, X86Movshdup, "movshdup", v4f32, VR128,
4758                                    memopv4f32, f128mem>;
4759 defm MOVSLDUP : sse3_replicate_sfp<0x12, X86Movsldup, "movsldup", v4f32, VR128,
4760                                    memopv4f32, f128mem>;
4761
4762 let Predicates = [HasAVX] in {
4763   def : Pat<(v4i32 (X86Movshdup VR128:$src)),
4764             (VMOVSHDUPrr VR128:$src)>;
4765   def : Pat<(v4i32 (X86Movshdup (bc_v4i32 (memopv2i64 addr:$src)))),
4766             (VMOVSHDUPrm addr:$src)>;
4767   def : Pat<(v4i32 (X86Movsldup VR128:$src)),
4768             (VMOVSLDUPrr VR128:$src)>;
4769   def : Pat<(v4i32 (X86Movsldup (bc_v4i32 (memopv2i64 addr:$src)))),
4770             (VMOVSLDUPrm addr:$src)>;
4771   def : Pat<(v8i32 (X86Movshdup VR256:$src)),
4772             (VMOVSHDUPYrr VR256:$src)>;
4773   def : Pat<(v8i32 (X86Movshdup (bc_v8i32 (memopv4i64 addr:$src)))),
4774             (VMOVSHDUPYrm addr:$src)>;
4775   def : Pat<(v8i32 (X86Movsldup VR256:$src)),
4776             (VMOVSLDUPYrr VR256:$src)>;
4777   def : Pat<(v8i32 (X86Movsldup (bc_v8i32 (memopv4i64 addr:$src)))),
4778             (VMOVSLDUPYrm addr:$src)>;
4779 }
4780
4781 let Predicates = [HasSSE3] in {
4782   def : Pat<(v4i32 (X86Movshdup VR128:$src)),
4783             (MOVSHDUPrr VR128:$src)>;
4784   def : Pat<(v4i32 (X86Movshdup (bc_v4i32 (memopv2i64 addr:$src)))),
4785             (MOVSHDUPrm addr:$src)>;
4786   def : Pat<(v4i32 (X86Movsldup VR128:$src)),
4787             (MOVSLDUPrr VR128:$src)>;
4788   def : Pat<(v4i32 (X86Movsldup (bc_v4i32 (memopv2i64 addr:$src)))),
4789             (MOVSLDUPrm addr:$src)>;
4790 }
4791
4792 //===---------------------------------------------------------------------===//
4793 // SSE3 - Replicate Double FP - MOVDDUP
4794 //===---------------------------------------------------------------------===//
4795
4796 multiclass sse3_replicate_dfp<string OpcodeStr> {
4797 def rr  : S3DI<0x12, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
4798                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
4799                     [(set VR128:$dst,(v2f64 (movddup VR128:$src, (undef))))]>;
4800 def rm  : S3DI<0x12, MRMSrcMem, (outs VR128:$dst), (ins f64mem:$src),
4801                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
4802                     [(set VR128:$dst,
4803                       (v2f64 (movddup (scalar_to_vector (loadf64 addr:$src)),
4804                                       (undef))))]>;
4805 }
4806
4807 // FIXME: Merge with above classe when there're patterns for the ymm version
4808 multiclass sse3_replicate_dfp_y<string OpcodeStr> {
4809 let Predicates = [HasAVX] in {
4810   def rr  : S3DI<0x12, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
4811                       !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
4812                       []>;
4813   def rm  : S3DI<0x12, MRMSrcMem, (outs VR256:$dst), (ins f256mem:$src),
4814                       !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
4815                       []>;
4816   }
4817 }
4818
4819 defm MOVDDUP : sse3_replicate_dfp<"movddup">;
4820 defm VMOVDDUP  : sse3_replicate_dfp<"vmovddup">, VEX;
4821 defm VMOVDDUPY : sse3_replicate_dfp_y<"vmovddup">, VEX;
4822
4823 let Predicates = [HasAVX] in {
4824   def : Pat<(movddup (bc_v2f64 (v2i64 (scalar_to_vector (loadi64 addr:$src)))),
4825                    (undef)),
4826             (VMOVDDUPrm addr:$src)>;
4827   let AddedComplexity = 5 in {
4828   def : Pat<(movddup (memopv2f64 addr:$src), (undef)), (VMOVDDUPrm addr:$src)>;
4829   def : Pat<(movddup (bc_v4f32 (memopv2f64 addr:$src)), (undef)),
4830             (VMOVDDUPrm addr:$src)>;
4831   def : Pat<(movddup (memopv2i64 addr:$src), (undef)), (VMOVDDUPrm addr:$src)>;
4832   def : Pat<(movddup (bc_v4i32 (memopv2i64 addr:$src)), (undef)),
4833             (VMOVDDUPrm addr:$src)>;
4834   }
4835   def : Pat<(X86Movddup (memopv2f64 addr:$src)),
4836             (VMOVDDUPrm addr:$src)>, Requires<[HasAVX]>;
4837   def : Pat<(X86Movddup (bc_v2f64 (memopv4f32 addr:$src))),
4838             (VMOVDDUPrm addr:$src)>, Requires<[HasAVX]>;
4839   def : Pat<(X86Movddup (bc_v2f64 (memopv2i64 addr:$src))),
4840             (VMOVDDUPrm addr:$src)>, Requires<[HasAVX]>;
4841   def : Pat<(X86Movddup (v2f64 (scalar_to_vector (loadf64 addr:$src)))),
4842             (VMOVDDUPrm addr:$src)>, Requires<[HasAVX]>;
4843   def : Pat<(X86Movddup (bc_v2f64
4844                              (v2i64 (scalar_to_vector (loadi64 addr:$src))))),
4845             (VMOVDDUPrm addr:$src)>, Requires<[HasAVX]>;
4846
4847   // 256-bit version
4848   def : Pat<(X86Movddup (memopv4f64 addr:$src)),
4849             (VMOVDDUPYrm addr:$src)>;
4850   def : Pat<(X86Movddup (memopv4i64 addr:$src)),
4851             (VMOVDDUPYrm addr:$src)>;
4852   def : Pat<(X86Movddup (v4f64 (scalar_to_vector (loadf64 addr:$src)))),
4853             (VMOVDDUPYrm addr:$src)>;
4854   def : Pat<(X86Movddup (v4i64 (scalar_to_vector (loadi64 addr:$src)))),
4855             (VMOVDDUPYrm addr:$src)>;
4856   def : Pat<(X86Movddup (v4f64 VR256:$src)),
4857             (VMOVDDUPYrr VR256:$src)>;
4858   def : Pat<(X86Movddup (v4i64 VR256:$src)),
4859             (VMOVDDUPYrr VR256:$src)>;
4860 }
4861
4862 let Predicates = [HasSSE3] in {
4863   def : Pat<(movddup (bc_v2f64 (v2i64 (scalar_to_vector (loadi64 addr:$src)))),
4864                    (undef)),
4865             (MOVDDUPrm addr:$src)>;
4866   let AddedComplexity = 5 in {
4867   def : Pat<(movddup (memopv2f64 addr:$src), (undef)), (MOVDDUPrm addr:$src)>;
4868   def : Pat<(movddup (bc_v4f32 (memopv2f64 addr:$src)), (undef)),
4869             (MOVDDUPrm addr:$src)>;
4870   def : Pat<(movddup (memopv2i64 addr:$src), (undef)), (MOVDDUPrm addr:$src)>;
4871   def : Pat<(movddup (bc_v4i32 (memopv2i64 addr:$src)), (undef)),
4872             (MOVDDUPrm addr:$src)>;
4873   }
4874   def : Pat<(X86Movddup (memopv2f64 addr:$src)),
4875             (MOVDDUPrm addr:$src)>;
4876   def : Pat<(X86Movddup (bc_v2f64 (memopv4f32 addr:$src))),
4877             (MOVDDUPrm addr:$src)>;
4878   def : Pat<(X86Movddup (bc_v2f64 (memopv2i64 addr:$src))),
4879             (MOVDDUPrm addr:$src)>;
4880   def : Pat<(X86Movddup (v2f64 (scalar_to_vector (loadf64 addr:$src)))),
4881             (MOVDDUPrm addr:$src)>;
4882   def : Pat<(X86Movddup (bc_v2f64
4883                              (v2i64 (scalar_to_vector (loadi64 addr:$src))))),
4884             (MOVDDUPrm addr:$src)>;
4885 }
4886
4887 //===---------------------------------------------------------------------===//
4888 // SSE3 - Move Unaligned Integer
4889 //===---------------------------------------------------------------------===//
4890
4891 let Predicates = [HasAVX] in {
4892   def VLDDQUrm : S3DI<0xF0, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
4893                    "vlddqu\t{$src, $dst|$dst, $src}",
4894                    [(set VR128:$dst, (int_x86_sse3_ldu_dq addr:$src))]>, VEX;
4895   def VLDDQUYrm : S3DI<0xF0, MRMSrcMem, (outs VR256:$dst), (ins i256mem:$src),
4896                    "vlddqu\t{$src, $dst|$dst, $src}",
4897                    [(set VR256:$dst, (int_x86_avx_ldu_dq_256 addr:$src))]>, VEX;
4898 }
4899 def LDDQUrm : S3DI<0xF0, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
4900                    "lddqu\t{$src, $dst|$dst, $src}",
4901                    [(set VR128:$dst, (int_x86_sse3_ldu_dq addr:$src))]>;
4902
4903 //===---------------------------------------------------------------------===//
4904 // SSE3 - Arithmetic
4905 //===---------------------------------------------------------------------===//
4906
4907 multiclass sse3_addsub<Intrinsic Int, string OpcodeStr, RegisterClass RC,
4908                        X86MemOperand x86memop, bit Is2Addr = 1> {
4909   def rr : I<0xD0, MRMSrcReg,
4910        (outs RC:$dst), (ins RC:$src1, RC:$src2),
4911        !if(Is2Addr,
4912            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
4913            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
4914        [(set RC:$dst, (Int RC:$src1, RC:$src2))]>;
4915   def rm : I<0xD0, MRMSrcMem,
4916        (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
4917        !if(Is2Addr,
4918            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
4919            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
4920        [(set RC:$dst, (Int RC:$src1, (memop addr:$src2)))]>;
4921 }
4922
4923 let Predicates = [HasAVX] in {
4924   let ExeDomain = SSEPackedSingle in {
4925     defm VADDSUBPS : sse3_addsub<int_x86_sse3_addsub_ps, "vaddsubps", VR128,
4926                                  f128mem, 0>, TB, XD, VEX_4V;
4927     defm VADDSUBPSY : sse3_addsub<int_x86_avx_addsub_ps_256, "vaddsubps", VR256,
4928                                  f256mem, 0>, TB, XD, VEX_4V;
4929   }
4930   let ExeDomain = SSEPackedDouble in {
4931     defm VADDSUBPD : sse3_addsub<int_x86_sse3_addsub_pd, "vaddsubpd", VR128,
4932                                  f128mem, 0>, TB, OpSize, VEX_4V;
4933     defm VADDSUBPDY : sse3_addsub<int_x86_avx_addsub_pd_256, "vaddsubpd", VR256,
4934                                  f256mem, 0>, TB, OpSize, VEX_4V;
4935   }
4936 }
4937 let Constraints = "$src1 = $dst", Predicates = [HasSSE3] in {
4938   let ExeDomain = SSEPackedSingle in
4939   defm ADDSUBPS : sse3_addsub<int_x86_sse3_addsub_ps, "addsubps", VR128,
4940                               f128mem>, TB, XD;
4941   let ExeDomain = SSEPackedDouble in
4942   defm ADDSUBPD : sse3_addsub<int_x86_sse3_addsub_pd, "addsubpd", VR128,
4943                               f128mem>, TB, OpSize;
4944 }
4945
4946 //===---------------------------------------------------------------------===//
4947 // SSE3 Instructions
4948 //===---------------------------------------------------------------------===//
4949
4950 // Horizontal ops
4951 multiclass S3D_Int<bits<8> o, string OpcodeStr, ValueType vt, RegisterClass RC,
4952                    X86MemOperand x86memop, SDNode OpNode, bit Is2Addr = 1> {
4953   def rr : S3DI<o, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
4954        !if(Is2Addr,
4955          !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
4956          !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
4957       [(set RC:$dst, (vt (OpNode RC:$src1, RC:$src2)))]>;
4958
4959   def rm : S3DI<o, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
4960        !if(Is2Addr,
4961          !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
4962          !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
4963       [(set RC:$dst, (vt (OpNode RC:$src1, (memop addr:$src2))))]>;
4964 }
4965 multiclass S3_Int<bits<8> o, string OpcodeStr, ValueType vt, RegisterClass RC,
4966                   X86MemOperand x86memop, SDNode OpNode, bit Is2Addr = 1> {
4967   def rr : S3I<o, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
4968        !if(Is2Addr,
4969          !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
4970          !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
4971       [(set RC:$dst, (vt (OpNode RC:$src1, RC:$src2)))]>;
4972
4973   def rm : S3I<o, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
4974        !if(Is2Addr,
4975          !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
4976          !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
4977       [(set RC:$dst, (vt (OpNode RC:$src1, (memop addr:$src2))))]>;
4978 }
4979
4980 let Predicates = [HasAVX] in {
4981   let ExeDomain = SSEPackedSingle in {
4982     defm VHADDPS  : S3D_Int<0x7C, "vhaddps", v4f32, VR128, f128mem,
4983                             X86fhadd, 0>, VEX_4V;
4984     defm VHSUBPS  : S3D_Int<0x7D, "vhsubps", v4f32, VR128, f128mem,
4985                             X86fhsub, 0>, VEX_4V;
4986     defm VHADDPSY : S3D_Int<0x7C, "vhaddps", v8f32, VR256, f256mem,
4987                             X86fhadd, 0>, VEX_4V;
4988     defm VHSUBPSY : S3D_Int<0x7D, "vhsubps", v8f32, VR256, f256mem,
4989                             X86fhsub, 0>, VEX_4V;
4990   }
4991   let ExeDomain = SSEPackedDouble in {
4992     defm VHADDPD  : S3_Int <0x7C, "vhaddpd", v2f64, VR128, f128mem,
4993                             X86fhadd, 0>, VEX_4V;
4994     defm VHSUBPD  : S3_Int <0x7D, "vhsubpd", v2f64, VR128, f128mem,
4995                             X86fhsub, 0>, VEX_4V;
4996     defm VHADDPDY : S3_Int <0x7C, "vhaddpd", v4f64, VR256, f256mem,
4997                             X86fhadd, 0>, VEX_4V;
4998     defm VHSUBPDY : S3_Int <0x7D, "vhsubpd", v4f64, VR256, f256mem,
4999                             X86fhsub, 0>, VEX_4V;
5000   }
5001 }
5002
5003 let Constraints = "$src1 = $dst" in {
5004   let ExeDomain = SSEPackedSingle in {
5005     defm HADDPS : S3D_Int<0x7C, "haddps", v4f32, VR128, f128mem, X86fhadd>;
5006     defm HSUBPS : S3D_Int<0x7D, "hsubps", v4f32, VR128, f128mem, X86fhsub>;
5007   }
5008   let ExeDomain = SSEPackedDouble in {
5009     defm HADDPD : S3_Int<0x7C, "haddpd", v2f64, VR128, f128mem, X86fhadd>;
5010     defm HSUBPD : S3_Int<0x7D, "hsubpd", v2f64, VR128, f128mem, X86fhsub>;
5011   }
5012 }
5013
5014 //===---------------------------------------------------------------------===//
5015 // SSSE3 - Packed Absolute Instructions
5016 //===---------------------------------------------------------------------===//
5017
5018
5019 /// SS3I_unop_rm_int - Simple SSSE3 unary op whose type can be v*{i8,i16,i32}.
5020 multiclass SS3I_unop_rm_int<bits<8> opc, string OpcodeStr,
5021                             Intrinsic IntId128> {
5022   def rr128 : SS38I<opc, MRMSrcReg, (outs VR128:$dst),
5023                     (ins VR128:$src),
5024                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5025                     [(set VR128:$dst, (IntId128 VR128:$src))]>,
5026                     OpSize;
5027
5028   def rm128 : SS38I<opc, MRMSrcMem, (outs VR128:$dst),
5029                     (ins i128mem:$src),
5030                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5031                     [(set VR128:$dst,
5032                       (IntId128
5033                        (bitconvert (memopv2i64 addr:$src))))]>, OpSize;
5034 }
5035
5036 /// SS3I_unop_rm_int_y - Simple SSSE3 unary op whose type can be v*{i8,i16,i32}.
5037 multiclass SS3I_unop_rm_int_y<bits<8> opc, string OpcodeStr,
5038                               Intrinsic IntId256> {
5039   def rr256 : SS38I<opc, MRMSrcReg, (outs VR256:$dst),
5040                     (ins VR256:$src),
5041                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5042                     [(set VR256:$dst, (IntId256 VR256:$src))]>,
5043                     OpSize;
5044
5045   def rm256 : SS38I<opc, MRMSrcMem, (outs VR256:$dst),
5046                     (ins i256mem:$src),
5047                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5048                     [(set VR256:$dst,
5049                       (IntId256
5050                        (bitconvert (memopv4i64 addr:$src))))]>, OpSize;
5051 }
5052
5053 let Predicates = [HasAVX] in {
5054   defm VPABSB  : SS3I_unop_rm_int<0x1C, "vpabsb",
5055                                   int_x86_ssse3_pabs_b_128>, VEX;
5056   defm VPABSW  : SS3I_unop_rm_int<0x1D, "vpabsw",
5057                                   int_x86_ssse3_pabs_w_128>, VEX;
5058   defm VPABSD  : SS3I_unop_rm_int<0x1E, "vpabsd",
5059                                   int_x86_ssse3_pabs_d_128>, VEX;
5060 }
5061
5062 let Predicates = [HasAVX2] in {
5063   defm VPABSB  : SS3I_unop_rm_int_y<0x1C, "vpabsb",
5064                                     int_x86_avx2_pabs_b>, VEX;
5065   defm VPABSW  : SS3I_unop_rm_int_y<0x1D, "vpabsw",
5066                                     int_x86_avx2_pabs_w>, VEX;
5067   defm VPABSD  : SS3I_unop_rm_int_y<0x1E, "vpabsd",
5068                                     int_x86_avx2_pabs_d>, VEX;
5069 }
5070
5071 defm PABSB : SS3I_unop_rm_int<0x1C, "pabsb",
5072                               int_x86_ssse3_pabs_b_128>;
5073 defm PABSW : SS3I_unop_rm_int<0x1D, "pabsw",
5074                               int_x86_ssse3_pabs_w_128>;
5075 defm PABSD : SS3I_unop_rm_int<0x1E, "pabsd",
5076                               int_x86_ssse3_pabs_d_128>;
5077
5078 //===---------------------------------------------------------------------===//
5079 // SSSE3 - Packed Binary Operator Instructions
5080 //===---------------------------------------------------------------------===//
5081
5082 /// SS3I_binop_rm_int - Simple SSSE3 bin op whose type can be v*{i8,i16,i32}.
5083 multiclass SS3I_binop_rm_int<bits<8> opc, string OpcodeStr,
5084                              Intrinsic IntId128, bit Is2Addr = 1> {
5085   let isCommutable = 1 in
5086   def rr128 : SS38I<opc, MRMSrcReg, (outs VR128:$dst),
5087        (ins VR128:$src1, VR128:$src2),
5088        !if(Is2Addr,
5089          !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5090          !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5091        [(set VR128:$dst, (IntId128 VR128:$src1, VR128:$src2))]>,
5092        OpSize;
5093   def rm128 : SS38I<opc, MRMSrcMem, (outs VR128:$dst),
5094        (ins VR128:$src1, i128mem:$src2),
5095        !if(Is2Addr,
5096          !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5097          !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5098        [(set VR128:$dst,
5099          (IntId128 VR128:$src1,
5100           (bitconvert (memopv2i64 addr:$src2))))]>, OpSize;
5101 }
5102
5103 multiclass SS3I_binop_rm_int_y<bits<8> opc, string OpcodeStr,
5104                                Intrinsic IntId256> {
5105   let isCommutable = 1 in
5106   def rr256 : SS38I<opc, MRMSrcReg, (outs VR256:$dst),
5107        (ins VR256:$src1, VR256:$src2),
5108        !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5109        [(set VR256:$dst, (IntId256 VR256:$src1, VR256:$src2))]>,
5110        OpSize;
5111   def rm256 : SS38I<opc, MRMSrcMem, (outs VR256:$dst),
5112        (ins VR256:$src1, i256mem:$src2),
5113        !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5114        [(set VR256:$dst,
5115          (IntId256 VR256:$src1,
5116           (bitconvert (memopv4i64 addr:$src2))))]>, OpSize;
5117 }
5118
5119 let ImmT = NoImm, Predicates = [HasAVX] in {
5120 let isCommutable = 0 in {
5121   defm VPHADDW    : SS3I_binop_rm_int<0x01, "vphaddw",
5122                                       int_x86_ssse3_phadd_w_128, 0>, VEX_4V;
5123   defm VPHADDD    : SS3I_binop_rm_int<0x02, "vphaddd",
5124                                       int_x86_ssse3_phadd_d_128, 0>, VEX_4V;
5125   defm VPHADDSW   : SS3I_binop_rm_int<0x03, "vphaddsw",
5126                                       int_x86_ssse3_phadd_sw_128, 0>, VEX_4V;
5127   defm VPHSUBW    : SS3I_binop_rm_int<0x05, "vphsubw",
5128                                       int_x86_ssse3_phsub_w_128, 0>, VEX_4V;
5129   defm VPHSUBD    : SS3I_binop_rm_int<0x06, "vphsubd",
5130                                       int_x86_ssse3_phsub_d_128, 0>, VEX_4V;
5131   defm VPHSUBSW   : SS3I_binop_rm_int<0x07, "vphsubsw",
5132                                       int_x86_ssse3_phsub_sw_128, 0>, VEX_4V;
5133   defm VPMADDUBSW : SS3I_binop_rm_int<0x04, "vpmaddubsw",
5134                                       int_x86_ssse3_pmadd_ub_sw_128, 0>, VEX_4V;
5135   defm VPSHUFB    : SS3I_binop_rm_int<0x00, "vpshufb",
5136                                       int_x86_ssse3_pshuf_b_128, 0>, VEX_4V;
5137   defm VPSIGNB    : SS3I_binop_rm_int<0x08, "vpsignb",
5138                                       int_x86_ssse3_psign_b_128, 0>, VEX_4V;
5139   defm VPSIGNW    : SS3I_binop_rm_int<0x09, "vpsignw",
5140                                       int_x86_ssse3_psign_w_128, 0>, VEX_4V;
5141   defm VPSIGND    : SS3I_binop_rm_int<0x0A, "vpsignd",
5142                                       int_x86_ssse3_psign_d_128, 0>, VEX_4V;
5143 }
5144 defm VPMULHRSW    : SS3I_binop_rm_int<0x0B, "vpmulhrsw",
5145                                       int_x86_ssse3_pmul_hr_sw_128, 0>, VEX_4V;
5146 }
5147
5148 let ImmT = NoImm, Predicates = [HasAVX2] in {
5149 let isCommutable = 0 in {
5150   defm VPHADDW    : SS3I_binop_rm_int_y<0x01, "vphaddw",
5151                                         int_x86_avx2_phadd_w>, VEX_4V;
5152   defm VPHADDD    : SS3I_binop_rm_int_y<0x02, "vphaddd",
5153                                         int_x86_avx2_phadd_d>, VEX_4V;
5154   defm VPHADDSW   : SS3I_binop_rm_int_y<0x03, "vphaddsw",
5155                                         int_x86_avx2_phadd_sw>, VEX_4V;
5156   defm VPHSUBW    : SS3I_binop_rm_int_y<0x05, "vphsubw",
5157                                         int_x86_avx2_phsub_w>, VEX_4V;
5158   defm VPHSUBD    : SS3I_binop_rm_int_y<0x06, "vphsubd",
5159                                         int_x86_avx2_phsub_d>, VEX_4V;
5160   defm VPHSUBSW   : SS3I_binop_rm_int_y<0x07, "vphsubsw",
5161                                         int_x86_avx2_phsub_sw>, VEX_4V;
5162   defm VPMADDUBSW : SS3I_binop_rm_int_y<0x04, "vpmaddubsw",
5163                                         int_x86_avx2_pmadd_ub_sw>, VEX_4V;
5164   defm VPSHUFB    : SS3I_binop_rm_int_y<0x00, "vpshufb",
5165                                         int_x86_avx2_pshuf_b>, VEX_4V;
5166   defm VPSIGNB    : SS3I_binop_rm_int_y<0x08, "vpsignb",
5167                                         int_x86_avx2_psign_b>, VEX_4V;
5168   defm VPSIGNW    : SS3I_binop_rm_int_y<0x09, "vpsignw",
5169                                         int_x86_avx2_psign_w>, VEX_4V;
5170   defm VPSIGND    : SS3I_binop_rm_int_y<0x0A, "vpsignd",
5171                                         int_x86_avx2_psign_d>, VEX_4V;
5172 }
5173 defm VPMULHRSW    : SS3I_binop_rm_int_y<0x0B, "vpmulhrsw",
5174                                         int_x86_avx2_pmul_hr_sw>, VEX_4V;
5175 }
5176
5177 // None of these have i8 immediate fields.
5178 let ImmT = NoImm, Constraints = "$src1 = $dst" in {
5179 let isCommutable = 0 in {
5180   defm PHADDW    : SS3I_binop_rm_int<0x01, "phaddw",
5181                                      int_x86_ssse3_phadd_w_128>;
5182   defm PHADDD    : SS3I_binop_rm_int<0x02, "phaddd",
5183                                      int_x86_ssse3_phadd_d_128>;
5184   defm PHADDSW   : SS3I_binop_rm_int<0x03, "phaddsw",
5185                                      int_x86_ssse3_phadd_sw_128>;
5186   defm PHSUBW    : SS3I_binop_rm_int<0x05, "phsubw",
5187                                      int_x86_ssse3_phsub_w_128>;
5188   defm PHSUBD    : SS3I_binop_rm_int<0x06, "phsubd",
5189                                      int_x86_ssse3_phsub_d_128>;
5190   defm PHSUBSW   : SS3I_binop_rm_int<0x07, "phsubsw",
5191                                      int_x86_ssse3_phsub_sw_128>;
5192   defm PMADDUBSW : SS3I_binop_rm_int<0x04, "pmaddubsw",
5193                                      int_x86_ssse3_pmadd_ub_sw_128>;
5194   defm PSHUFB    : SS3I_binop_rm_int<0x00, "pshufb",
5195                                      int_x86_ssse3_pshuf_b_128>;
5196   defm PSIGNB    : SS3I_binop_rm_int<0x08, "psignb",
5197                                      int_x86_ssse3_psign_b_128>;
5198   defm PSIGNW    : SS3I_binop_rm_int<0x09, "psignw",
5199                                      int_x86_ssse3_psign_w_128>;
5200   defm PSIGND    : SS3I_binop_rm_int<0x0A, "psignd",
5201                                        int_x86_ssse3_psign_d_128>;
5202 }
5203 defm PMULHRSW    : SS3I_binop_rm_int<0x0B, "pmulhrsw",
5204                                      int_x86_ssse3_pmul_hr_sw_128>;
5205 }
5206
5207 let Predicates = [HasAVX] in {
5208   def : Pat<(X86pshufb VR128:$src, VR128:$mask),
5209             (VPSHUFBrr128 VR128:$src, VR128:$mask)>;
5210   def : Pat<(X86pshufb VR128:$src, (bc_v16i8 (memopv2i64 addr:$mask))),
5211             (VPSHUFBrm128 VR128:$src, addr:$mask)>;
5212
5213   def : Pat<(v16i8 (X86psign VR128:$src1, VR128:$src2)),
5214             (VPSIGNBrr128 VR128:$src1, VR128:$src2)>;
5215   def : Pat<(v8i16 (X86psign VR128:$src1, VR128:$src2)),
5216             (VPSIGNWrr128 VR128:$src1, VR128:$src2)>;
5217   def : Pat<(v4i32 (X86psign VR128:$src1, VR128:$src2)),
5218             (VPSIGNDrr128 VR128:$src1, VR128:$src2)>;
5219
5220   def : Pat<(v8i16 (X86hadd VR128:$src1, VR128:$src2)),
5221             (VPHADDWrr128 VR128:$src1, VR128:$src2)>;
5222   def : Pat<(v4i32 (X86hadd VR128:$src1, VR128:$src2)),
5223             (VPHADDDrr128 VR128:$src1, VR128:$src2)>;
5224   def : Pat<(v8i16 (X86hsub VR128:$src1, VR128:$src2)),
5225             (VPHSUBWrr128 VR128:$src1, VR128:$src2)>;
5226   def : Pat<(v4i32 (X86hsub VR128:$src1, VR128:$src2)),
5227             (VPHSUBDrr128 VR128:$src1, VR128:$src2)>;
5228 }
5229
5230 let Predicates = [HasAVX2] in {
5231   def : Pat<(v32i8 (X86psign VR256:$src1, VR256:$src2)),
5232             (VPSIGNBrr256 VR256:$src1, VR256:$src2)>;
5233   def : Pat<(v16i16 (X86psign VR256:$src1, VR256:$src2)),
5234             (VPSIGNWrr256 VR256:$src1, VR256:$src2)>;
5235   def : Pat<(v8i32 (X86psign VR256:$src1, VR256:$src2)),
5236             (VPSIGNDrr256 VR256:$src1, VR256:$src2)>;
5237
5238   def : Pat<(v16i16 (X86hadd VR256:$src1, VR256:$src2)),
5239             (VPHADDWrr256 VR256:$src1, VR256:$src2)>;
5240   def : Pat<(v8i32 (X86hadd VR256:$src1, VR256:$src2)),
5241             (VPHADDDrr256 VR256:$src1, VR256:$src2)>;
5242   def : Pat<(v16i16 (X86hsub VR256:$src1, VR256:$src2)),
5243             (VPHSUBWrr256 VR256:$src1, VR256:$src2)>;
5244   def : Pat<(v8i32 (X86hsub VR256:$src1, VR256:$src2)),
5245             (VPHSUBDrr256 VR256:$src1, VR256:$src2)>;
5246 }
5247
5248 let Predicates = [HasSSSE3] in {
5249   def : Pat<(X86pshufb VR128:$src, VR128:$mask),
5250             (PSHUFBrr128 VR128:$src, VR128:$mask)>;
5251   def : Pat<(X86pshufb VR128:$src, (bc_v16i8 (memopv2i64 addr:$mask))),
5252             (PSHUFBrm128 VR128:$src, addr:$mask)>;
5253
5254   def : Pat<(v16i8 (X86psign VR128:$src1, VR128:$src2)),
5255             (PSIGNBrr128 VR128:$src1, VR128:$src2)>;
5256   def : Pat<(v8i16 (X86psign VR128:$src1, VR128:$src2)),
5257             (PSIGNWrr128 VR128:$src1, VR128:$src2)>;
5258   def : Pat<(v4i32 (X86psign VR128:$src1, VR128:$src2)),
5259             (PSIGNDrr128 VR128:$src1, VR128:$src2)>;
5260
5261   def : Pat<(v8i16 (X86hadd VR128:$src1, VR128:$src2)),
5262             (PHADDWrr128 VR128:$src1, VR128:$src2)>;
5263   def : Pat<(v4i32 (X86hadd VR128:$src1, VR128:$src2)),
5264             (PHADDDrr128 VR128:$src1, VR128:$src2)>;
5265   def : Pat<(v8i16 (X86hsub VR128:$src1, VR128:$src2)),
5266             (PHSUBWrr128 VR128:$src1, VR128:$src2)>;
5267   def : Pat<(v4i32 (X86hsub VR128:$src1, VR128:$src2)),
5268             (PHSUBDrr128 VR128:$src1, VR128:$src2)>;
5269 }
5270
5271 //===---------------------------------------------------------------------===//
5272 // SSSE3 - Packed Align Instruction Patterns
5273 //===---------------------------------------------------------------------===//
5274
5275 multiclass ssse3_palign<string asm, bit Is2Addr = 1> {
5276   let neverHasSideEffects = 1 in {
5277   def R128rr : SS3AI<0x0F, MRMSrcReg, (outs VR128:$dst),
5278       (ins VR128:$src1, VR128:$src2, i8imm:$src3),
5279       !if(Is2Addr,
5280         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5281         !strconcat(asm,
5282                   "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5283       []>, OpSize;
5284   let mayLoad = 1 in
5285   def R128rm : SS3AI<0x0F, MRMSrcMem, (outs VR128:$dst),
5286       (ins VR128:$src1, i128mem:$src2, i8imm:$src3),
5287       !if(Is2Addr,
5288         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5289         !strconcat(asm,
5290                   "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5291       []>, OpSize;
5292   }
5293 }
5294
5295 multiclass ssse3_palign_y<string asm, bit Is2Addr = 1> {
5296   let neverHasSideEffects = 1 in {
5297   def R256rr : SS3AI<0x0F, MRMSrcReg, (outs VR256:$dst),
5298       (ins VR256:$src1, VR256:$src2, i8imm:$src3),
5299       !strconcat(asm,
5300                  "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
5301       []>, OpSize;
5302   let mayLoad = 1 in
5303   def R256rm : SS3AI<0x0F, MRMSrcMem, (outs VR256:$dst),
5304       (ins VR256:$src1, i256mem:$src2, i8imm:$src3),
5305       !strconcat(asm,
5306                  "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
5307       []>, OpSize;
5308   }
5309 }
5310
5311 let Predicates = [HasAVX] in
5312   defm VPALIGN : ssse3_palign<"vpalignr", 0>, VEX_4V;
5313 let Predicates = [HasAVX2] in
5314   defm VPALIGN : ssse3_palign_y<"vpalignr", 0>, VEX_4V;
5315 let Constraints = "$src1 = $dst", Predicates = [HasSSSE3] in
5316   defm PALIGN : ssse3_palign<"palignr">;
5317
5318 let Predicates = [HasAVX2] in {
5319 def : Pat<(v8i32 (X86PAlign VR256:$src1, VR256:$src2, (i8 imm:$imm))),
5320           (VPALIGNR256rr VR256:$src2, VR256:$src1, imm:$imm)>;
5321 def : Pat<(v8f32 (X86PAlign VR256:$src1, VR256:$src2, (i8 imm:$imm))),
5322           (VPALIGNR256rr VR256:$src2, VR256:$src1, imm:$imm)>;
5323 def : Pat<(v16i16 (X86PAlign VR256:$src1, VR256:$src2, (i8 imm:$imm))),
5324           (VPALIGNR256rr VR256:$src2, VR256:$src1, imm:$imm)>;
5325 def : Pat<(v32i8 (X86PAlign VR256:$src1, VR256:$src2, (i8 imm:$imm))),
5326           (VPALIGNR256rr VR256:$src2, VR256:$src1, imm:$imm)>;
5327 }
5328
5329 let Predicates = [HasAVX] in {
5330 def : Pat<(v4i32 (X86PAlign VR128:$src1, VR128:$src2, (i8 imm:$imm))),
5331           (VPALIGNR128rr VR128:$src2, VR128:$src1, imm:$imm)>;
5332 def : Pat<(v4f32 (X86PAlign VR128:$src1, VR128:$src2, (i8 imm:$imm))),
5333           (VPALIGNR128rr VR128:$src2, VR128:$src1, imm:$imm)>;
5334 def : Pat<(v8i16 (X86PAlign VR128:$src1, VR128:$src2, (i8 imm:$imm))),
5335           (VPALIGNR128rr VR128:$src2, VR128:$src1, imm:$imm)>;
5336 def : Pat<(v16i8 (X86PAlign VR128:$src1, VR128:$src2, (i8 imm:$imm))),
5337           (VPALIGNR128rr VR128:$src2, VR128:$src1, imm:$imm)>;
5338 }
5339
5340 let Predicates = [HasSSSE3] in {
5341 def : Pat<(v4i32 (X86PAlign VR128:$src1, VR128:$src2, (i8 imm:$imm))),
5342           (PALIGNR128rr VR128:$src2, VR128:$src1, imm:$imm)>;
5343 def : Pat<(v4f32 (X86PAlign VR128:$src1, VR128:$src2, (i8 imm:$imm))),
5344           (PALIGNR128rr VR128:$src2, VR128:$src1, imm:$imm)>;
5345 def : Pat<(v8i16 (X86PAlign VR128:$src1, VR128:$src2, (i8 imm:$imm))),
5346           (PALIGNR128rr VR128:$src2, VR128:$src1, imm:$imm)>;
5347 def : Pat<(v16i8 (X86PAlign VR128:$src1, VR128:$src2, (i8 imm:$imm))),
5348           (PALIGNR128rr VR128:$src2, VR128:$src1, imm:$imm)>;
5349 }
5350
5351 //===---------------------------------------------------------------------===//
5352 // SSSE3 - Thread synchronization
5353 //===---------------------------------------------------------------------===//
5354
5355 let usesCustomInserter = 1 in {
5356 def MONITOR : PseudoI<(outs), (ins i32mem:$src1, GR32:$src2, GR32:$src3),
5357                 [(int_x86_sse3_monitor addr:$src1, GR32:$src2, GR32:$src3)]>,
5358                 Requires<[HasSSE3]>;
5359 def MWAIT : PseudoI<(outs), (ins GR32:$src1, GR32:$src2),
5360                 [(int_x86_sse3_mwait GR32:$src1, GR32:$src2)]>,
5361                 Requires<[HasSSE3]>;
5362 }
5363
5364 let Uses = [EAX, ECX, EDX] in
5365 def MONITORrrr : I<0x01, MRM_C8, (outs), (ins), "monitor", []>, TB,
5366                  Requires<[HasSSE3]>;
5367 let Uses = [ECX, EAX] in
5368 def MWAITrr   : I<0x01, MRM_C9, (outs), (ins), "mwait", []>, TB,
5369                 Requires<[HasSSE3]>;
5370
5371 def : InstAlias<"mwait %eax, %ecx", (MWAITrr)>, Requires<[In32BitMode]>;
5372 def : InstAlias<"mwait %rax, %rcx", (MWAITrr)>, Requires<[In64BitMode]>;
5373
5374 def : InstAlias<"monitor %eax, %ecx, %edx", (MONITORrrr)>,
5375       Requires<[In32BitMode]>;
5376 def : InstAlias<"monitor %rax, %rcx, %rdx", (MONITORrrr)>,
5377       Requires<[In64BitMode]>;
5378
5379 //===----------------------------------------------------------------------===//
5380 // SSE4.1 - Packed Move with Sign/Zero Extend
5381 //===----------------------------------------------------------------------===//
5382
5383 multiclass SS41I_binop_rm_int8<bits<8> opc, string OpcodeStr, Intrinsic IntId> {
5384   def rr : SS48I<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
5385                  !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5386                  [(set VR128:$dst, (IntId VR128:$src))]>, OpSize;
5387
5388   def rm : SS48I<opc, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
5389                  !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5390        [(set VR128:$dst,
5391          (IntId (bitconvert (v2i64 (scalar_to_vector (loadi64 addr:$src))))))]>,
5392        OpSize;
5393 }
5394
5395 multiclass SS41I_binop_rm_int16_y<bits<8> opc, string OpcodeStr,
5396                                  Intrinsic IntId> {
5397   def Yrr : SS48I<opc, MRMSrcReg, (outs VR256:$dst), (ins VR128:$src),
5398                   !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5399                   [(set VR256:$dst, (IntId VR128:$src))]>, OpSize;
5400
5401   def Yrm : SS48I<opc, MRMSrcMem, (outs VR256:$dst), (ins i128mem:$src),
5402                   !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5403                   [(set VR256:$dst, (IntId (load addr:$src)))]>, OpSize;
5404 }
5405
5406 let Predicates = [HasAVX] in {
5407 defm VPMOVSXBW : SS41I_binop_rm_int8<0x20, "vpmovsxbw", int_x86_sse41_pmovsxbw>,
5408                                      VEX;
5409 defm VPMOVSXWD : SS41I_binop_rm_int8<0x23, "vpmovsxwd", int_x86_sse41_pmovsxwd>,
5410                                      VEX;
5411 defm VPMOVSXDQ : SS41I_binop_rm_int8<0x25, "vpmovsxdq", int_x86_sse41_pmovsxdq>,
5412                                      VEX;
5413 defm VPMOVZXBW : SS41I_binop_rm_int8<0x30, "vpmovzxbw", int_x86_sse41_pmovzxbw>,
5414                                      VEX;
5415 defm VPMOVZXWD : SS41I_binop_rm_int8<0x33, "vpmovzxwd", int_x86_sse41_pmovzxwd>,
5416                                      VEX;
5417 defm VPMOVZXDQ : SS41I_binop_rm_int8<0x35, "vpmovzxdq", int_x86_sse41_pmovzxdq>,
5418                                      VEX;
5419 }
5420
5421 let Predicates = [HasAVX2] in {
5422 defm VPMOVSXBW : SS41I_binop_rm_int16_y<0x20, "vpmovsxbw",
5423                                         int_x86_avx2_pmovsxbw>, VEX;
5424 defm VPMOVSXWD : SS41I_binop_rm_int16_y<0x23, "vpmovsxwd",
5425                                         int_x86_avx2_pmovsxwd>, VEX;
5426 defm VPMOVSXDQ : SS41I_binop_rm_int16_y<0x25, "vpmovsxdq",
5427                                         int_x86_avx2_pmovsxdq>, VEX;
5428 defm VPMOVZXBW : SS41I_binop_rm_int16_y<0x30, "vpmovzxbw",
5429                                         int_x86_avx2_pmovzxbw>, VEX;
5430 defm VPMOVZXWD : SS41I_binop_rm_int16_y<0x33, "vpmovzxwd",
5431                                         int_x86_avx2_pmovzxwd>, VEX;
5432 defm VPMOVZXDQ : SS41I_binop_rm_int16_y<0x35, "vpmovzxdq",
5433                                         int_x86_avx2_pmovzxdq>, VEX;
5434 }
5435
5436 defm PMOVSXBW   : SS41I_binop_rm_int8<0x20, "pmovsxbw", int_x86_sse41_pmovsxbw>;
5437 defm PMOVSXWD   : SS41I_binop_rm_int8<0x23, "pmovsxwd", int_x86_sse41_pmovsxwd>;
5438 defm PMOVSXDQ   : SS41I_binop_rm_int8<0x25, "pmovsxdq", int_x86_sse41_pmovsxdq>;
5439 defm PMOVZXBW   : SS41I_binop_rm_int8<0x30, "pmovzxbw", int_x86_sse41_pmovzxbw>;
5440 defm PMOVZXWD   : SS41I_binop_rm_int8<0x33, "pmovzxwd", int_x86_sse41_pmovzxwd>;
5441 defm PMOVZXDQ   : SS41I_binop_rm_int8<0x35, "pmovzxdq", int_x86_sse41_pmovzxdq>;
5442
5443 let Predicates = [HasAVX] in {
5444   // Common patterns involving scalar load.
5445   def : Pat<(int_x86_sse41_pmovsxbw (vzmovl_v2i64 addr:$src)),
5446             (VPMOVSXBWrm addr:$src)>;
5447   def : Pat<(int_x86_sse41_pmovsxbw (vzload_v2i64 addr:$src)),
5448             (VPMOVSXBWrm addr:$src)>;
5449
5450   def : Pat<(int_x86_sse41_pmovsxwd (vzmovl_v2i64 addr:$src)),
5451             (VPMOVSXWDrm addr:$src)>;
5452   def : Pat<(int_x86_sse41_pmovsxwd (vzload_v2i64 addr:$src)),
5453             (VPMOVSXWDrm addr:$src)>;
5454
5455   def : Pat<(int_x86_sse41_pmovsxdq (vzmovl_v2i64 addr:$src)),
5456             (VPMOVSXDQrm addr:$src)>;
5457   def : Pat<(int_x86_sse41_pmovsxdq (vzload_v2i64 addr:$src)),
5458             (VPMOVSXDQrm addr:$src)>;
5459
5460   def : Pat<(int_x86_sse41_pmovzxbw (vzmovl_v2i64 addr:$src)),
5461             (VPMOVZXBWrm addr:$src)>;
5462   def : Pat<(int_x86_sse41_pmovzxbw (vzload_v2i64 addr:$src)),
5463             (VPMOVZXBWrm addr:$src)>;
5464
5465   def : Pat<(int_x86_sse41_pmovzxwd (vzmovl_v2i64 addr:$src)),
5466             (VPMOVZXWDrm addr:$src)>;
5467   def : Pat<(int_x86_sse41_pmovzxwd (vzload_v2i64 addr:$src)),
5468             (VPMOVZXWDrm addr:$src)>;
5469
5470   def : Pat<(int_x86_sse41_pmovzxdq (vzmovl_v2i64 addr:$src)),
5471             (VPMOVZXDQrm addr:$src)>;
5472   def : Pat<(int_x86_sse41_pmovzxdq (vzload_v2i64 addr:$src)),
5473             (VPMOVZXDQrm addr:$src)>;
5474 }
5475
5476 let Predicates = [HasSSE41] in {
5477   // Common patterns involving scalar load.
5478   def : Pat<(int_x86_sse41_pmovsxbw (vzmovl_v2i64 addr:$src)),
5479             (PMOVSXBWrm addr:$src)>;
5480   def : Pat<(int_x86_sse41_pmovsxbw (vzload_v2i64 addr:$src)),
5481             (PMOVSXBWrm addr:$src)>;
5482
5483   def : Pat<(int_x86_sse41_pmovsxwd (vzmovl_v2i64 addr:$src)),
5484             (PMOVSXWDrm addr:$src)>;
5485   def : Pat<(int_x86_sse41_pmovsxwd (vzload_v2i64 addr:$src)),
5486             (PMOVSXWDrm addr:$src)>;
5487
5488   def : Pat<(int_x86_sse41_pmovsxdq (vzmovl_v2i64 addr:$src)),
5489             (PMOVSXDQrm addr:$src)>;
5490   def : Pat<(int_x86_sse41_pmovsxdq (vzload_v2i64 addr:$src)),
5491             (PMOVSXDQrm addr:$src)>;
5492
5493   def : Pat<(int_x86_sse41_pmovzxbw (vzmovl_v2i64 addr:$src)),
5494             (PMOVZXBWrm addr:$src)>;
5495   def : Pat<(int_x86_sse41_pmovzxbw (vzload_v2i64 addr:$src)),
5496             (PMOVZXBWrm addr:$src)>;
5497
5498   def : Pat<(int_x86_sse41_pmovzxwd (vzmovl_v2i64 addr:$src)),
5499             (PMOVZXWDrm addr:$src)>;
5500   def : Pat<(int_x86_sse41_pmovzxwd (vzload_v2i64 addr:$src)),
5501             (PMOVZXWDrm addr:$src)>;
5502
5503   def : Pat<(int_x86_sse41_pmovzxdq (vzmovl_v2i64 addr:$src)),
5504             (PMOVZXDQrm addr:$src)>;
5505   def : Pat<(int_x86_sse41_pmovzxdq (vzload_v2i64 addr:$src)),
5506             (PMOVZXDQrm addr:$src)>;
5507 }
5508
5509
5510 multiclass SS41I_binop_rm_int4<bits<8> opc, string OpcodeStr, Intrinsic IntId> {
5511   def rr : SS48I<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
5512                  !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5513                  [(set VR128:$dst, (IntId VR128:$src))]>, OpSize;
5514
5515   def rm : SS48I<opc, MRMSrcMem, (outs VR128:$dst), (ins i32mem:$src),
5516                  !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5517        [(set VR128:$dst,
5518          (IntId (bitconvert (v4i32 (scalar_to_vector (loadi32 addr:$src))))))]>,
5519           OpSize;
5520 }
5521
5522 multiclass SS41I_binop_rm_int8_y<bits<8> opc, string OpcodeStr,
5523                                  Intrinsic IntId> {
5524   def Yrr : SS48I<opc, MRMSrcReg, (outs VR256:$dst), (ins VR128:$src),
5525                   !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5526                   [(set VR256:$dst, (IntId VR128:$src))]>, OpSize;
5527
5528   def Yrm : SS48I<opc, MRMSrcMem, (outs VR256:$dst), (ins i32mem:$src),
5529                   !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5530        [(set VR256:$dst,
5531          (IntId (bitconvert (v2i64 (scalar_to_vector (loadi64 addr:$src))))))]>,
5532           OpSize;
5533 }
5534
5535 let Predicates = [HasAVX] in {
5536 defm VPMOVSXBD : SS41I_binop_rm_int4<0x21, "vpmovsxbd", int_x86_sse41_pmovsxbd>,
5537                                      VEX;
5538 defm VPMOVSXWQ : SS41I_binop_rm_int4<0x24, "vpmovsxwq", int_x86_sse41_pmovsxwq>,
5539                                      VEX;
5540 defm VPMOVZXBD : SS41I_binop_rm_int4<0x31, "vpmovzxbd", int_x86_sse41_pmovzxbd>,
5541                                      VEX;
5542 defm VPMOVZXWQ : SS41I_binop_rm_int4<0x34, "vpmovzxwq", int_x86_sse41_pmovzxwq>,
5543                                      VEX;
5544 }
5545
5546 let Predicates = [HasAVX2] in {
5547 defm VPMOVSXBD : SS41I_binop_rm_int8_y<0x21, "vpmovsxbd",
5548                                        int_x86_avx2_pmovsxbd>, VEX;
5549 defm VPMOVSXWQ : SS41I_binop_rm_int8_y<0x24, "vpmovsxwq",
5550                                        int_x86_avx2_pmovsxwq>, VEX;
5551 defm VPMOVZXBD : SS41I_binop_rm_int8_y<0x31, "vpmovzxbd",
5552                                        int_x86_avx2_pmovzxbd>, VEX;
5553 defm VPMOVZXWQ : SS41I_binop_rm_int8_y<0x34, "vpmovzxwq",
5554                                        int_x86_avx2_pmovzxwq>, VEX;
5555 }
5556
5557 defm PMOVSXBD   : SS41I_binop_rm_int4<0x21, "pmovsxbd", int_x86_sse41_pmovsxbd>;
5558 defm PMOVSXWQ   : SS41I_binop_rm_int4<0x24, "pmovsxwq", int_x86_sse41_pmovsxwq>;
5559 defm PMOVZXBD   : SS41I_binop_rm_int4<0x31, "pmovzxbd", int_x86_sse41_pmovzxbd>;
5560 defm PMOVZXWQ   : SS41I_binop_rm_int4<0x34, "pmovzxwq", int_x86_sse41_pmovzxwq>;
5561
5562 let Predicates = [HasAVX] in {
5563   // Common patterns involving scalar load
5564   def : Pat<(int_x86_sse41_pmovsxbd (vzmovl_v4i32 addr:$src)),
5565             (VPMOVSXBDrm addr:$src)>;
5566   def : Pat<(int_x86_sse41_pmovsxwq (vzmovl_v4i32 addr:$src)),
5567             (VPMOVSXWQrm addr:$src)>;
5568
5569   def : Pat<(int_x86_sse41_pmovzxbd (vzmovl_v4i32 addr:$src)),
5570             (VPMOVZXBDrm addr:$src)>;
5571   def : Pat<(int_x86_sse41_pmovzxwq (vzmovl_v4i32 addr:$src)),
5572             (VPMOVZXWQrm addr:$src)>;
5573 }
5574
5575 let Predicates = [HasSSE41] in {
5576   // Common patterns involving scalar load
5577   def : Pat<(int_x86_sse41_pmovsxbd (vzmovl_v4i32 addr:$src)),
5578             (PMOVSXBDrm addr:$src)>;
5579   def : Pat<(int_x86_sse41_pmovsxwq (vzmovl_v4i32 addr:$src)),
5580             (PMOVSXWQrm addr:$src)>;
5581
5582   def : Pat<(int_x86_sse41_pmovzxbd (vzmovl_v4i32 addr:$src)),
5583             (PMOVZXBDrm addr:$src)>;
5584   def : Pat<(int_x86_sse41_pmovzxwq (vzmovl_v4i32 addr:$src)),
5585             (PMOVZXWQrm addr:$src)>;
5586 }
5587
5588 multiclass SS41I_binop_rm_int2<bits<8> opc, string OpcodeStr, Intrinsic IntId> {
5589   def rr : SS48I<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
5590                  !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5591                  [(set VR128:$dst, (IntId VR128:$src))]>, OpSize;
5592
5593   // Expecting a i16 load any extended to i32 value.
5594   def rm : SS48I<opc, MRMSrcMem, (outs VR128:$dst), (ins i16mem:$src),
5595                  !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5596                  [(set VR128:$dst, (IntId (bitconvert
5597                      (v4i32 (scalar_to_vector (loadi16_anyext addr:$src))))))]>,
5598                  OpSize;
5599 }
5600
5601 multiclass SS41I_binop_rm_int4_y<bits<8> opc, string OpcodeStr,
5602                                  Intrinsic IntId> {
5603   def Yrr : SS48I<opc, MRMSrcReg, (outs VR256:$dst), (ins VR128:$src),
5604                  !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5605                  [(set VR256:$dst, (IntId VR128:$src))]>, OpSize;
5606
5607   // Expecting a i16 load any extended to i32 value.
5608   def Yrm : SS48I<opc, MRMSrcMem, (outs VR256:$dst), (ins i16mem:$src),
5609                   !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5610                   [(set VR256:$dst, (IntId (bitconvert
5611                       (v4i32 (scalar_to_vector (loadi32 addr:$src))))))]>,
5612                   OpSize;
5613 }
5614
5615 let Predicates = [HasAVX] in {
5616 defm VPMOVSXBQ : SS41I_binop_rm_int2<0x22, "vpmovsxbq", int_x86_sse41_pmovsxbq>,
5617                                      VEX;
5618 defm VPMOVZXBQ : SS41I_binop_rm_int2<0x32, "vpmovzxbq", int_x86_sse41_pmovzxbq>,
5619                                      VEX;
5620 }
5621 let Predicates = [HasAVX2] in {
5622 defm VPMOVSXBQ : SS41I_binop_rm_int4_y<0x22, "vpmovsxbq",
5623                                        int_x86_avx2_pmovsxbq>, VEX;
5624 defm VPMOVZXBQ : SS41I_binop_rm_int4_y<0x32, "vpmovzxbq",
5625                                        int_x86_avx2_pmovzxbq>, VEX;
5626 }
5627 defm PMOVSXBQ   : SS41I_binop_rm_int2<0x22, "pmovsxbq", int_x86_sse41_pmovsxbq>;
5628 defm PMOVZXBQ   : SS41I_binop_rm_int2<0x32, "pmovzxbq", int_x86_sse41_pmovzxbq>;
5629
5630 let Predicates = [HasAVX] in {
5631   // Common patterns involving scalar load
5632   def : Pat<(int_x86_sse41_pmovsxbq
5633               (bitconvert (v4i32 (X86vzmovl
5634                             (v4i32 (scalar_to_vector (loadi32 addr:$src))))))),
5635             (VPMOVSXBQrm addr:$src)>;
5636
5637   def : Pat<(int_x86_sse41_pmovzxbq
5638               (bitconvert (v4i32 (X86vzmovl
5639                             (v4i32 (scalar_to_vector (loadi32 addr:$src))))))),
5640             (VPMOVZXBQrm addr:$src)>;
5641 }
5642
5643 let Predicates = [HasSSE41] in {
5644   // Common patterns involving scalar load
5645   def : Pat<(int_x86_sse41_pmovsxbq
5646               (bitconvert (v4i32 (X86vzmovl
5647                             (v4i32 (scalar_to_vector (loadi32 addr:$src))))))),
5648             (PMOVSXBQrm addr:$src)>;
5649
5650   def : Pat<(int_x86_sse41_pmovzxbq
5651               (bitconvert (v4i32 (X86vzmovl
5652                             (v4i32 (scalar_to_vector (loadi32 addr:$src))))))),
5653             (PMOVZXBQrm addr:$src)>;
5654 }
5655
5656 //===----------------------------------------------------------------------===//
5657 // SSE4.1 - Extract Instructions
5658 //===----------------------------------------------------------------------===//
5659
5660 /// SS41I_binop_ext8 - SSE 4.1 extract 8 bits to 32 bit reg or 8 bit mem
5661 multiclass SS41I_extract8<bits<8> opc, string OpcodeStr> {
5662   def rr : SS4AIi8<opc, MRMDestReg, (outs GR32:$dst),
5663                  (ins VR128:$src1, i32i8imm:$src2),
5664                  !strconcat(OpcodeStr,
5665                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5666                  [(set GR32:$dst, (X86pextrb (v16i8 VR128:$src1), imm:$src2))]>,
5667                  OpSize;
5668   let neverHasSideEffects = 1, mayStore = 1 in
5669   def mr : SS4AIi8<opc, MRMDestMem, (outs),
5670                  (ins i8mem:$dst, VR128:$src1, i32i8imm:$src2),
5671                  !strconcat(OpcodeStr,
5672                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5673                  []>, OpSize;
5674 // FIXME:
5675 // There's an AssertZext in the way of writing the store pattern
5676 // (store (i8 (trunc (X86pextrb (v16i8 VR128:$src1), imm:$src2))), addr:$dst)
5677 }
5678
5679 let Predicates = [HasAVX] in {
5680   defm VPEXTRB : SS41I_extract8<0x14, "vpextrb">, VEX;
5681   def  VPEXTRBrr64 : SS4AIi8<0x14, MRMDestReg, (outs GR64:$dst),
5682          (ins VR128:$src1, i32i8imm:$src2),
5683          "vpextrb\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>, OpSize, VEX;
5684 }
5685
5686 defm PEXTRB      : SS41I_extract8<0x14, "pextrb">;
5687
5688
5689 /// SS41I_extract16 - SSE 4.1 extract 16 bits to memory destination
5690 multiclass SS41I_extract16<bits<8> opc, string OpcodeStr> {
5691   let neverHasSideEffects = 1, mayStore = 1 in
5692   def mr : SS4AIi8<opc, MRMDestMem, (outs),
5693                  (ins i16mem:$dst, VR128:$src1, i32i8imm:$src2),
5694                  !strconcat(OpcodeStr,
5695                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5696                  []>, OpSize;
5697 // FIXME:
5698 // There's an AssertZext in the way of writing the store pattern
5699 // (store (i16 (trunc (X86pextrw (v16i8 VR128:$src1), imm:$src2))), addr:$dst)
5700 }
5701
5702 let Predicates = [HasAVX] in
5703   defm VPEXTRW : SS41I_extract16<0x15, "vpextrw">, VEX;
5704
5705 defm PEXTRW      : SS41I_extract16<0x15, "pextrw">;
5706
5707
5708 /// SS41I_extract32 - SSE 4.1 extract 32 bits to int reg or memory destination
5709 multiclass SS41I_extract32<bits<8> opc, string OpcodeStr> {
5710   def rr : SS4AIi8<opc, MRMDestReg, (outs GR32:$dst),
5711                  (ins VR128:$src1, i32i8imm:$src2),
5712                  !strconcat(OpcodeStr,
5713                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5714                  [(set GR32:$dst,
5715                   (extractelt (v4i32 VR128:$src1), imm:$src2))]>, OpSize;
5716   def mr : SS4AIi8<opc, MRMDestMem, (outs),
5717                  (ins i32mem:$dst, VR128:$src1, i32i8imm:$src2),
5718                  !strconcat(OpcodeStr,
5719                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5720                  [(store (extractelt (v4i32 VR128:$src1), imm:$src2),
5721                           addr:$dst)]>, OpSize;
5722 }
5723
5724 let Predicates = [HasAVX] in
5725   defm VPEXTRD : SS41I_extract32<0x16, "vpextrd">, VEX;
5726
5727 defm PEXTRD      : SS41I_extract32<0x16, "pextrd">;
5728
5729 /// SS41I_extract32 - SSE 4.1 extract 32 bits to int reg or memory destination
5730 multiclass SS41I_extract64<bits<8> opc, string OpcodeStr> {
5731   def rr : SS4AIi8<opc, MRMDestReg, (outs GR64:$dst),
5732                  (ins VR128:$src1, i32i8imm:$src2),
5733                  !strconcat(OpcodeStr,
5734                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5735                  [(set GR64:$dst,
5736                   (extractelt (v2i64 VR128:$src1), imm:$src2))]>, OpSize, REX_W;
5737   def mr : SS4AIi8<opc, MRMDestMem, (outs),
5738                  (ins i64mem:$dst, VR128:$src1, i32i8imm:$src2),
5739                  !strconcat(OpcodeStr,
5740                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5741                  [(store (extractelt (v2i64 VR128:$src1), imm:$src2),
5742                           addr:$dst)]>, OpSize, REX_W;
5743 }
5744
5745 let Predicates = [HasAVX] in
5746   defm VPEXTRQ : SS41I_extract64<0x16, "vpextrq">, VEX, VEX_W;
5747
5748 defm PEXTRQ      : SS41I_extract64<0x16, "pextrq">;
5749
5750 /// SS41I_extractf32 - SSE 4.1 extract 32 bits fp value to int reg or memory
5751 /// destination
5752 multiclass SS41I_extractf32<bits<8> opc, string OpcodeStr> {
5753   def rr : SS4AIi8<opc, MRMDestReg, (outs GR32:$dst),
5754                  (ins VR128:$src1, i32i8imm:$src2),
5755                  !strconcat(OpcodeStr,
5756                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5757                  [(set GR32:$dst,
5758                     (extractelt (bc_v4i32 (v4f32 VR128:$src1)), imm:$src2))]>,
5759            OpSize;
5760   def mr : SS4AIi8<opc, MRMDestMem, (outs),
5761                  (ins f32mem:$dst, VR128:$src1, i32i8imm:$src2),
5762                  !strconcat(OpcodeStr,
5763                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5764                  [(store (extractelt (bc_v4i32 (v4f32 VR128:$src1)), imm:$src2),
5765                           addr:$dst)]>, OpSize;
5766 }
5767
5768 let ExeDomain = SSEPackedSingle in {
5769   let Predicates = [HasAVX] in {
5770     defm VEXTRACTPS : SS41I_extractf32<0x17, "vextractps">, VEX;
5771     def VEXTRACTPSrr64 : SS4AIi8<0x17, MRMDestReg, (outs GR64:$dst),
5772                     (ins VR128:$src1, i32i8imm:$src2),
5773                     "vextractps \t{$src2, $src1, $dst|$dst, $src1, $src2}",
5774                     []>, OpSize, VEX;
5775   }
5776   defm EXTRACTPS   : SS41I_extractf32<0x17, "extractps">;
5777 }
5778
5779 // Also match an EXTRACTPS store when the store is done as f32 instead of i32.
5780 def : Pat<(store (f32 (bitconvert (extractelt (bc_v4i32 (v4f32 VR128:$src1)),
5781                                               imm:$src2))),
5782                  addr:$dst),
5783           (VEXTRACTPSmr addr:$dst, VR128:$src1, imm:$src2)>,
5784           Requires<[HasAVX]>;
5785 def : Pat<(store (f32 (bitconvert (extractelt (bc_v4i32 (v4f32 VR128:$src1)),
5786                                               imm:$src2))),
5787                  addr:$dst),
5788           (EXTRACTPSmr addr:$dst, VR128:$src1, imm:$src2)>,
5789           Requires<[HasSSE41]>;
5790
5791 //===----------------------------------------------------------------------===//
5792 // SSE4.1 - Insert Instructions
5793 //===----------------------------------------------------------------------===//
5794
5795 multiclass SS41I_insert8<bits<8> opc, string asm, bit Is2Addr = 1> {
5796   def rr : SS4AIi8<opc, MRMSrcReg, (outs VR128:$dst),
5797       (ins VR128:$src1, GR32:$src2, i32i8imm:$src3),
5798       !if(Is2Addr,
5799         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5800         !strconcat(asm,
5801                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5802       [(set VR128:$dst,
5803         (X86pinsrb VR128:$src1, GR32:$src2, imm:$src3))]>, OpSize;
5804   def rm : SS4AIi8<opc, MRMSrcMem, (outs VR128:$dst),
5805       (ins VR128:$src1, i8mem:$src2, i32i8imm:$src3),
5806       !if(Is2Addr,
5807         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5808         !strconcat(asm,
5809                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5810       [(set VR128:$dst,
5811         (X86pinsrb VR128:$src1, (extloadi8 addr:$src2),
5812                    imm:$src3))]>, OpSize;
5813 }
5814
5815 let Predicates = [HasAVX] in
5816   defm VPINSRB : SS41I_insert8<0x20, "vpinsrb", 0>, VEX_4V;
5817 let Constraints = "$src1 = $dst" in
5818   defm PINSRB  : SS41I_insert8<0x20, "pinsrb">;
5819
5820 multiclass SS41I_insert32<bits<8> opc, string asm, bit Is2Addr = 1> {
5821   def rr : SS4AIi8<opc, MRMSrcReg, (outs VR128:$dst),
5822       (ins VR128:$src1, GR32:$src2, i32i8imm:$src3),
5823       !if(Is2Addr,
5824         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5825         !strconcat(asm,
5826                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5827       [(set VR128:$dst,
5828         (v4i32 (insertelt VR128:$src1, GR32:$src2, imm:$src3)))]>,
5829       OpSize;
5830   def rm : SS4AIi8<opc, MRMSrcMem, (outs VR128:$dst),
5831       (ins VR128:$src1, i32mem:$src2, i32i8imm:$src3),
5832       !if(Is2Addr,
5833         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5834         !strconcat(asm,
5835                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5836       [(set VR128:$dst,
5837         (v4i32 (insertelt VR128:$src1, (loadi32 addr:$src2),
5838                           imm:$src3)))]>, OpSize;
5839 }
5840
5841 let Predicates = [HasAVX] in
5842   defm VPINSRD : SS41I_insert32<0x22, "vpinsrd", 0>, VEX_4V;
5843 let Constraints = "$src1 = $dst" in
5844   defm PINSRD : SS41I_insert32<0x22, "pinsrd">;
5845
5846 multiclass SS41I_insert64<bits<8> opc, string asm, bit Is2Addr = 1> {
5847   def rr : SS4AIi8<opc, MRMSrcReg, (outs VR128:$dst),
5848       (ins VR128:$src1, GR64:$src2, i32i8imm:$src3),
5849       !if(Is2Addr,
5850         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5851         !strconcat(asm,
5852                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5853       [(set VR128:$dst,
5854         (v2i64 (insertelt VR128:$src1, GR64:$src2, imm:$src3)))]>,
5855       OpSize;
5856   def rm : SS4AIi8<opc, MRMSrcMem, (outs VR128:$dst),
5857       (ins VR128:$src1, i64mem:$src2, i32i8imm:$src3),
5858       !if(Is2Addr,
5859         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5860         !strconcat(asm,
5861                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5862       [(set VR128:$dst,
5863         (v2i64 (insertelt VR128:$src1, (loadi64 addr:$src2),
5864                           imm:$src3)))]>, OpSize;
5865 }
5866
5867 let Predicates = [HasAVX] in
5868   defm VPINSRQ : SS41I_insert64<0x22, "vpinsrq", 0>, VEX_4V, VEX_W;
5869 let Constraints = "$src1 = $dst" in
5870   defm PINSRQ : SS41I_insert64<0x22, "pinsrq">, REX_W;
5871
5872 // insertps has a few different modes, there's the first two here below which
5873 // are optimized inserts that won't zero arbitrary elements in the destination
5874 // vector. The next one matches the intrinsic and could zero arbitrary elements
5875 // in the target vector.
5876 multiclass SS41I_insertf32<bits<8> opc, string asm, bit Is2Addr = 1> {
5877   def rr : SS4AIi8<opc, MRMSrcReg, (outs VR128:$dst),
5878       (ins VR128:$src1, VR128:$src2, u32u8imm:$src3),
5879       !if(Is2Addr,
5880         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5881         !strconcat(asm,
5882                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5883       [(set VR128:$dst,
5884         (X86insrtps VR128:$src1, VR128:$src2, imm:$src3))]>,
5885       OpSize;
5886   def rm : SS4AIi8<opc, MRMSrcMem, (outs VR128:$dst),
5887       (ins VR128:$src1, f32mem:$src2, u32u8imm:$src3),
5888       !if(Is2Addr,
5889         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5890         !strconcat(asm,
5891                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5892       [(set VR128:$dst,
5893         (X86insrtps VR128:$src1,
5894                    (v4f32 (scalar_to_vector (loadf32 addr:$src2))),
5895                     imm:$src3))]>, OpSize;
5896 }
5897
5898 let ExeDomain = SSEPackedSingle in {
5899   let Predicates = [HasAVX] in
5900     defm VINSERTPS : SS41I_insertf32<0x21, "vinsertps", 0>, VEX_4V;
5901   let Constraints = "$src1 = $dst" in
5902     defm INSERTPS : SS41I_insertf32<0x21, "insertps">;
5903 }
5904
5905 def : Pat<(int_x86_sse41_insertps VR128:$src1, VR128:$src2, imm:$src3),
5906           (VINSERTPSrr VR128:$src1, VR128:$src2, imm:$src3)>,
5907           Requires<[HasAVX]>;
5908 def : Pat<(int_x86_sse41_insertps VR128:$src1, VR128:$src2, imm:$src3),
5909           (INSERTPSrr VR128:$src1, VR128:$src2, imm:$src3)>,
5910           Requires<[HasSSE41]>;
5911
5912 //===----------------------------------------------------------------------===//
5913 // SSE4.1 - Round Instructions
5914 //===----------------------------------------------------------------------===//
5915
5916 multiclass sse41_fp_unop_rm<bits<8> opcps, bits<8> opcpd, string OpcodeStr,
5917                             X86MemOperand x86memop, RegisterClass RC,
5918                             PatFrag mem_frag32, PatFrag mem_frag64,
5919                             Intrinsic V4F32Int, Intrinsic V2F64Int> {
5920 let ExeDomain = SSEPackedSingle in {
5921   // Intrinsic operation, reg.
5922   // Vector intrinsic operation, reg
5923   def PSr : SS4AIi8<opcps, MRMSrcReg,
5924                     (outs RC:$dst), (ins RC:$src1, i32i8imm:$src2),
5925                     !strconcat(OpcodeStr,
5926                     "ps\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5927                     [(set RC:$dst, (V4F32Int RC:$src1, imm:$src2))]>,
5928                     OpSize;
5929
5930   // Vector intrinsic operation, mem
5931   def PSm : SS4AIi8<opcps, MRMSrcMem,
5932                     (outs RC:$dst), (ins x86memop:$src1, i32i8imm:$src2),
5933                     !strconcat(OpcodeStr,
5934                     "ps\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5935                     [(set RC:$dst,
5936                           (V4F32Int (mem_frag32 addr:$src1),imm:$src2))]>,
5937                     OpSize;
5938 } // ExeDomain = SSEPackedSingle
5939
5940 let ExeDomain = SSEPackedDouble in {
5941   // Vector intrinsic operation, reg
5942   def PDr : SS4AIi8<opcpd, MRMSrcReg,
5943                     (outs RC:$dst), (ins RC:$src1, i32i8imm:$src2),
5944                     !strconcat(OpcodeStr,
5945                     "pd\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5946                     [(set RC:$dst, (V2F64Int RC:$src1, imm:$src2))]>,
5947                     OpSize;
5948
5949   // Vector intrinsic operation, mem
5950   def PDm : SS4AIi8<opcpd, MRMSrcMem,
5951                     (outs RC:$dst), (ins x86memop:$src1, i32i8imm:$src2),
5952                     !strconcat(OpcodeStr,
5953                     "pd\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5954                     [(set RC:$dst,
5955                           (V2F64Int (mem_frag64 addr:$src1),imm:$src2))]>,
5956                     OpSize;
5957 } // ExeDomain = SSEPackedDouble
5958 }
5959
5960 multiclass sse41_fp_binop_rm<bits<8> opcss, bits<8> opcsd,
5961                             string OpcodeStr,
5962                             Intrinsic F32Int,
5963                             Intrinsic F64Int, bit Is2Addr = 1> {
5964 let ExeDomain = GenericDomain in {
5965   // Operation, reg.
5966   def SSr : SS4AIi8<opcss, MRMSrcReg,
5967       (outs FR32:$dst), (ins FR32:$src1, FR32:$src2, i32i8imm:$src3),
5968       !if(Is2Addr,
5969           !strconcat(OpcodeStr,
5970               "ss\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5971           !strconcat(OpcodeStr,
5972               "ss\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5973       []>, OpSize;
5974
5975   // Intrinsic operation, reg.
5976   def SSr_Int : SS4AIi8<opcss, MRMSrcReg,
5977         (outs VR128:$dst), (ins VR128:$src1, VR128:$src2, i32i8imm:$src3),
5978         !if(Is2Addr,
5979             !strconcat(OpcodeStr,
5980                 "ss\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5981             !strconcat(OpcodeStr,
5982                 "ss\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5983         [(set VR128:$dst, (F32Int VR128:$src1, VR128:$src2, imm:$src3))]>,
5984         OpSize;
5985
5986   // Intrinsic operation, mem.
5987   def SSm : SS4AIi8<opcss, MRMSrcMem,
5988         (outs VR128:$dst), (ins VR128:$src1, ssmem:$src2, i32i8imm:$src3),
5989         !if(Is2Addr,
5990             !strconcat(OpcodeStr,
5991                 "ss\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5992             !strconcat(OpcodeStr,
5993                 "ss\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5994         [(set VR128:$dst,
5995              (F32Int VR128:$src1, sse_load_f32:$src2, imm:$src3))]>,
5996         OpSize;
5997
5998   // Operation, reg.
5999   def SDr : SS4AIi8<opcsd, MRMSrcReg,
6000         (outs FR64:$dst), (ins FR64:$src1, FR64:$src2, i32i8imm:$src3),
6001         !if(Is2Addr,
6002             !strconcat(OpcodeStr,
6003                 "sd\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6004             !strconcat(OpcodeStr,
6005                 "sd\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6006         []>, OpSize;
6007
6008   // Intrinsic operation, reg.
6009   def SDr_Int : SS4AIi8<opcsd, MRMSrcReg,
6010         (outs VR128:$dst), (ins VR128:$src1, VR128:$src2, i32i8imm:$src3),
6011         !if(Is2Addr,
6012             !strconcat(OpcodeStr,
6013                 "sd\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6014             !strconcat(OpcodeStr,
6015                 "sd\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6016         [(set VR128:$dst, (F64Int VR128:$src1, VR128:$src2, imm:$src3))]>,
6017         OpSize;
6018
6019   // Intrinsic operation, mem.
6020   def SDm : SS4AIi8<opcsd, MRMSrcMem,
6021         (outs VR128:$dst), (ins VR128:$src1, sdmem:$src2, i32i8imm:$src3),
6022         !if(Is2Addr,
6023             !strconcat(OpcodeStr,
6024                 "sd\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6025             !strconcat(OpcodeStr,
6026                 "sd\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6027         [(set VR128:$dst,
6028               (F64Int VR128:$src1, sse_load_f64:$src2, imm:$src3))]>,
6029         OpSize;
6030 } // ExeDomain = GenericDomain
6031 }
6032
6033 // FP round - roundss, roundps, roundsd, roundpd
6034 let Predicates = [HasAVX] in {
6035   // Intrinsic form
6036   defm VROUND  : sse41_fp_unop_rm<0x08, 0x09, "vround", f128mem, VR128,
6037                                   memopv4f32, memopv2f64,
6038                                   int_x86_sse41_round_ps,
6039                                   int_x86_sse41_round_pd>, VEX;
6040   defm VROUNDY : sse41_fp_unop_rm<0x08, 0x09, "vround", f256mem, VR256,
6041                                   memopv8f32, memopv4f64,
6042                                   int_x86_avx_round_ps_256,
6043                                   int_x86_avx_round_pd_256>, VEX;
6044   defm VROUND  : sse41_fp_binop_rm<0x0A, 0x0B, "vround",
6045                                   int_x86_sse41_round_ss,
6046                                   int_x86_sse41_round_sd, 0>, VEX_4V, VEX_LIG;
6047
6048   def : Pat<(ffloor FR32:$src),
6049             (VROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x1))>;
6050   def : Pat<(f64 (ffloor FR64:$src)),
6051             (VROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x1))>;
6052   def : Pat<(f32 (fnearbyint FR32:$src)),
6053             (VROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0xC))>;
6054   def : Pat<(f64 (fnearbyint FR64:$src)),
6055             (VROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0xC))>;
6056   def : Pat<(f32 (fceil FR32:$src)),
6057             (VROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x2))>;
6058   def : Pat<(f64 (fceil FR64:$src)),
6059             (VROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x2))>;
6060   def : Pat<(f32 (frint FR32:$src)),
6061             (VROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x4))>;
6062   def : Pat<(f64 (frint FR64:$src)),
6063             (VROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x4))>;
6064   def : Pat<(f32 (ftrunc FR32:$src)),
6065             (VROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x3))>;
6066   def : Pat<(f64 (ftrunc FR64:$src)),
6067             (VROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x3))>;
6068 }
6069
6070 defm ROUND  : sse41_fp_unop_rm<0x08, 0x09, "round", f128mem, VR128,
6071                                memopv4f32, memopv2f64,
6072                                int_x86_sse41_round_ps, int_x86_sse41_round_pd>;
6073 let Constraints = "$src1 = $dst" in
6074 defm ROUND  : sse41_fp_binop_rm<0x0A, 0x0B, "round",
6075                                int_x86_sse41_round_ss, int_x86_sse41_round_sd>;
6076
6077 def : Pat<(ffloor FR32:$src),
6078           (ROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x1))>;
6079 def : Pat<(f64 (ffloor FR64:$src)),
6080           (ROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x1))>;
6081 def : Pat<(f32 (fnearbyint FR32:$src)),
6082           (ROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0xC))>;
6083 def : Pat<(f64 (fnearbyint FR64:$src)),
6084           (ROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0xC))>;
6085 def : Pat<(f32 (fceil FR32:$src)),
6086           (ROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x2))>;
6087 def : Pat<(f64 (fceil FR64:$src)),
6088           (ROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x2))>;
6089 def : Pat<(f32 (frint FR32:$src)),
6090           (ROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x4))>;
6091 def : Pat<(f64 (frint FR64:$src)),
6092           (ROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x4))>;
6093 def : Pat<(f32 (ftrunc FR32:$src)),
6094           (ROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x3))>;
6095 def : Pat<(f64 (ftrunc FR64:$src)),
6096           (ROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x3))>;
6097
6098 //===----------------------------------------------------------------------===//
6099 // SSE4.1 - Packed Bit Test
6100 //===----------------------------------------------------------------------===//
6101
6102 // ptest instruction we'll lower to this in X86ISelLowering primarily from
6103 // the intel intrinsic that corresponds to this.
6104 let Defs = [EFLAGS], Predicates = [HasAVX] in {
6105 def VPTESTrr  : SS48I<0x17, MRMSrcReg, (outs), (ins VR128:$src1, VR128:$src2),
6106                 "vptest\t{$src2, $src1|$src1, $src2}",
6107                 [(set EFLAGS, (X86ptest VR128:$src1, (v4f32 VR128:$src2)))]>,
6108                 OpSize, VEX;
6109 def VPTESTrm  : SS48I<0x17, MRMSrcMem, (outs), (ins VR128:$src1, f128mem:$src2),
6110                 "vptest\t{$src2, $src1|$src1, $src2}",
6111                 [(set EFLAGS,(X86ptest VR128:$src1, (memopv4f32 addr:$src2)))]>,
6112                 OpSize, VEX;
6113
6114 def VPTESTYrr : SS48I<0x17, MRMSrcReg, (outs), (ins VR256:$src1, VR256:$src2),
6115                 "vptest\t{$src2, $src1|$src1, $src2}",
6116                 [(set EFLAGS, (X86ptest VR256:$src1, (v4i64 VR256:$src2)))]>,
6117                 OpSize, VEX;
6118 def VPTESTYrm : SS48I<0x17, MRMSrcMem, (outs), (ins VR256:$src1, i256mem:$src2),
6119                 "vptest\t{$src2, $src1|$src1, $src2}",
6120                 [(set EFLAGS,(X86ptest VR256:$src1, (memopv4i64 addr:$src2)))]>,
6121                 OpSize, VEX;
6122 }
6123
6124 let Defs = [EFLAGS] in {
6125 def PTESTrr : SS48I<0x17, MRMSrcReg, (outs), (ins VR128:$src1, VR128:$src2),
6126               "ptest\t{$src2, $src1|$src1, $src2}",
6127               [(set EFLAGS, (X86ptest VR128:$src1, (v4f32 VR128:$src2)))]>,
6128               OpSize;
6129 def PTESTrm : SS48I<0x17, MRMSrcMem, (outs), (ins VR128:$src1, f128mem:$src2),
6130               "ptest\t{$src2, $src1|$src1, $src2}",
6131               [(set EFLAGS, (X86ptest VR128:$src1, (memopv4f32 addr:$src2)))]>,
6132               OpSize;
6133 }
6134
6135 // The bit test instructions below are AVX only
6136 multiclass avx_bittest<bits<8> opc, string OpcodeStr, RegisterClass RC,
6137                        X86MemOperand x86memop, PatFrag mem_frag, ValueType vt> {
6138   def rr : SS48I<opc, MRMSrcReg, (outs), (ins RC:$src1, RC:$src2),
6139             !strconcat(OpcodeStr, "\t{$src2, $src1|$src1, $src2}"),
6140             [(set EFLAGS, (X86testp RC:$src1, (vt RC:$src2)))]>, OpSize, VEX;
6141   def rm : SS48I<opc, MRMSrcMem, (outs), (ins RC:$src1, x86memop:$src2),
6142             !strconcat(OpcodeStr, "\t{$src2, $src1|$src1, $src2}"),
6143             [(set EFLAGS, (X86testp RC:$src1, (mem_frag addr:$src2)))]>,
6144             OpSize, VEX;
6145 }
6146
6147 let Defs = [EFLAGS], Predicates = [HasAVX] in {
6148 let ExeDomain = SSEPackedSingle in {
6149 defm VTESTPS  : avx_bittest<0x0E, "vtestps", VR128, f128mem, memopv4f32, v4f32>;
6150 defm VTESTPSY : avx_bittest<0x0E, "vtestps", VR256, f256mem, memopv8f32, v8f32>;
6151 }
6152 let ExeDomain = SSEPackedDouble in {
6153 defm VTESTPD  : avx_bittest<0x0F, "vtestpd", VR128, f128mem, memopv2f64, v2f64>;
6154 defm VTESTPDY : avx_bittest<0x0F, "vtestpd", VR256, f256mem, memopv4f64, v4f64>;
6155 }
6156 }
6157
6158 //===----------------------------------------------------------------------===//
6159 // SSE4.1 - Misc Instructions
6160 //===----------------------------------------------------------------------===//
6161
6162 let Defs = [EFLAGS], Predicates = [HasPOPCNT] in {
6163   def POPCNT16rr : I<0xB8, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
6164                      "popcnt{w}\t{$src, $dst|$dst, $src}",
6165                      [(set GR16:$dst, (ctpop GR16:$src)), (implicit EFLAGS)]>,
6166                      OpSize, XS;
6167   def POPCNT16rm : I<0xB8, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
6168                      "popcnt{w}\t{$src, $dst|$dst, $src}",
6169                      [(set GR16:$dst, (ctpop (loadi16 addr:$src))),
6170                       (implicit EFLAGS)]>, OpSize, XS;
6171
6172   def POPCNT32rr : I<0xB8, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
6173                      "popcnt{l}\t{$src, $dst|$dst, $src}",
6174                      [(set GR32:$dst, (ctpop GR32:$src)), (implicit EFLAGS)]>,
6175                      XS;
6176   def POPCNT32rm : I<0xB8, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
6177                      "popcnt{l}\t{$src, $dst|$dst, $src}",
6178                      [(set GR32:$dst, (ctpop (loadi32 addr:$src))),
6179                       (implicit EFLAGS)]>, XS;
6180
6181   def POPCNT64rr : RI<0xB8, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
6182                       "popcnt{q}\t{$src, $dst|$dst, $src}",
6183                       [(set GR64:$dst, (ctpop GR64:$src)), (implicit EFLAGS)]>,
6184                       XS;
6185   def POPCNT64rm : RI<0xB8, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
6186                       "popcnt{q}\t{$src, $dst|$dst, $src}",
6187                       [(set GR64:$dst, (ctpop (loadi64 addr:$src))),
6188                        (implicit EFLAGS)]>, XS;
6189 }
6190
6191
6192
6193 // SS41I_unop_rm_int_v16 - SSE 4.1 unary operator whose type is v8i16.
6194 multiclass SS41I_unop_rm_int_v16<bits<8> opc, string OpcodeStr,
6195                                  Intrinsic IntId128> {
6196   def rr128 : SS48I<opc, MRMSrcReg, (outs VR128:$dst),
6197                     (ins VR128:$src),
6198                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
6199                     [(set VR128:$dst, (IntId128 VR128:$src))]>, OpSize;
6200   def rm128 : SS48I<opc, MRMSrcMem, (outs VR128:$dst),
6201                      (ins i128mem:$src),
6202                      !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
6203                      [(set VR128:$dst,
6204                        (IntId128
6205                         (bitconvert (memopv2i64 addr:$src))))]>, OpSize;
6206 }
6207
6208 let Predicates = [HasAVX] in
6209 defm VPHMINPOSUW : SS41I_unop_rm_int_v16 <0x41, "vphminposuw",
6210                                          int_x86_sse41_phminposuw>, VEX;
6211 defm PHMINPOSUW : SS41I_unop_rm_int_v16 <0x41, "phminposuw",
6212                                          int_x86_sse41_phminposuw>;
6213
6214 /// SS41I_binop_rm_int - Simple SSE 4.1 binary operator
6215 multiclass SS41I_binop_rm_int<bits<8> opc, string OpcodeStr,
6216                               Intrinsic IntId128, bit Is2Addr = 1> {
6217   let isCommutable = 1 in
6218   def rr : SS48I<opc, MRMSrcReg, (outs VR128:$dst),
6219        (ins VR128:$src1, VR128:$src2),
6220        !if(Is2Addr,
6221            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
6222            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
6223        [(set VR128:$dst, (IntId128 VR128:$src1, VR128:$src2))]>, OpSize;
6224   def rm : SS48I<opc, MRMSrcMem, (outs VR128:$dst),
6225        (ins VR128:$src1, i128mem:$src2),
6226        !if(Is2Addr,
6227            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
6228            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
6229        [(set VR128:$dst,
6230          (IntId128 VR128:$src1,
6231           (bitconvert (memopv2i64 addr:$src2))))]>, OpSize;
6232 }
6233
6234 /// SS41I_binop_rm_int - Simple SSE 4.1 binary operator
6235 multiclass SS41I_binop_rm_int_y<bits<8> opc, string OpcodeStr,
6236                                 Intrinsic IntId256> {
6237   let isCommutable = 1 in
6238   def Yrr : SS48I<opc, MRMSrcReg, (outs VR256:$dst),
6239        (ins VR256:$src1, VR256:$src2),
6240        !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6241        [(set VR256:$dst, (IntId256 VR256:$src1, VR256:$src2))]>, OpSize;
6242   def Yrm : SS48I<opc, MRMSrcMem, (outs VR256:$dst),
6243        (ins VR256:$src1, i256mem:$src2),
6244        !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6245        [(set VR256:$dst,
6246          (IntId256 VR256:$src1,
6247           (bitconvert (memopv4i64 addr:$src2))))]>, OpSize;
6248 }
6249
6250 let Predicates = [HasAVX] in {
6251   let isCommutable = 0 in
6252   defm VPACKUSDW : SS41I_binop_rm_int<0x2B, "vpackusdw", int_x86_sse41_packusdw,
6253                                                          0>, VEX_4V;
6254   defm VPMINSB   : SS41I_binop_rm_int<0x38, "vpminsb",   int_x86_sse41_pminsb,
6255                                                          0>, VEX_4V;
6256   defm VPMINSD   : SS41I_binop_rm_int<0x39, "vpminsd",   int_x86_sse41_pminsd,
6257                                                          0>, VEX_4V;
6258   defm VPMINUD   : SS41I_binop_rm_int<0x3B, "vpminud",   int_x86_sse41_pminud,
6259                                                          0>, VEX_4V;
6260   defm VPMINUW   : SS41I_binop_rm_int<0x3A, "vpminuw",   int_x86_sse41_pminuw,
6261                                                          0>, VEX_4V;
6262   defm VPMAXSB   : SS41I_binop_rm_int<0x3C, "vpmaxsb",   int_x86_sse41_pmaxsb,
6263                                                          0>, VEX_4V;
6264   defm VPMAXSD   : SS41I_binop_rm_int<0x3D, "vpmaxsd",   int_x86_sse41_pmaxsd,
6265                                                          0>, VEX_4V;
6266   defm VPMAXUD   : SS41I_binop_rm_int<0x3F, "vpmaxud",   int_x86_sse41_pmaxud,
6267                                                          0>, VEX_4V;
6268   defm VPMAXUW   : SS41I_binop_rm_int<0x3E, "vpmaxuw",   int_x86_sse41_pmaxuw,
6269                                                          0>, VEX_4V;
6270   defm VPMULDQ   : SS41I_binop_rm_int<0x28, "vpmuldq",   int_x86_sse41_pmuldq,
6271                                                          0>, VEX_4V;
6272 }
6273
6274 let Predicates = [HasAVX2] in {
6275   let isCommutable = 0 in
6276   defm VPACKUSDW : SS41I_binop_rm_int_y<0x2B, "vpackusdw",
6277                                         int_x86_avx2_packusdw>, VEX_4V;
6278   defm VPMINSB   : SS41I_binop_rm_int_y<0x38, "vpminsb",
6279                                         int_x86_avx2_pmins_b>, VEX_4V;
6280   defm VPMINSD   : SS41I_binop_rm_int_y<0x39, "vpminsd",
6281                                         int_x86_avx2_pmins_d>, VEX_4V;
6282   defm VPMINUD   : SS41I_binop_rm_int_y<0x3B, "vpminud",
6283                                         int_x86_avx2_pminu_d>, VEX_4V;
6284   defm VPMINUW   : SS41I_binop_rm_int_y<0x3A, "vpminuw",
6285                                         int_x86_avx2_pminu_w>, VEX_4V;
6286   defm VPMAXSB   : SS41I_binop_rm_int_y<0x3C, "vpmaxsb",
6287                                         int_x86_avx2_pmaxs_b>, VEX_4V;
6288   defm VPMAXSD   : SS41I_binop_rm_int_y<0x3D, "vpmaxsd",
6289                                         int_x86_avx2_pmaxs_d>, VEX_4V;
6290   defm VPMAXUD   : SS41I_binop_rm_int_y<0x3F, "vpmaxud",
6291                                         int_x86_avx2_pmaxu_d>, VEX_4V;
6292   defm VPMAXUW   : SS41I_binop_rm_int_y<0x3E, "vpmaxuw",
6293                                         int_x86_avx2_pmaxu_w>, VEX_4V;
6294   defm VPMULDQ   : SS41I_binop_rm_int_y<0x28, "vpmuldq",
6295                                         int_x86_avx2_pmul_dq>, VEX_4V;
6296 }
6297
6298 let Constraints = "$src1 = $dst" in {
6299   let isCommutable = 0 in
6300   defm PACKUSDW : SS41I_binop_rm_int<0x2B, "packusdw", int_x86_sse41_packusdw>;
6301   defm PMINSB   : SS41I_binop_rm_int<0x38, "pminsb",   int_x86_sse41_pminsb>;
6302   defm PMINSD   : SS41I_binop_rm_int<0x39, "pminsd",   int_x86_sse41_pminsd>;
6303   defm PMINUD   : SS41I_binop_rm_int<0x3B, "pminud",   int_x86_sse41_pminud>;
6304   defm PMINUW   : SS41I_binop_rm_int<0x3A, "pminuw",   int_x86_sse41_pminuw>;
6305   defm PMAXSB   : SS41I_binop_rm_int<0x3C, "pmaxsb",   int_x86_sse41_pmaxsb>;
6306   defm PMAXSD   : SS41I_binop_rm_int<0x3D, "pmaxsd",   int_x86_sse41_pmaxsd>;
6307   defm PMAXUD   : SS41I_binop_rm_int<0x3F, "pmaxud",   int_x86_sse41_pmaxud>;
6308   defm PMAXUW   : SS41I_binop_rm_int<0x3E, "pmaxuw",   int_x86_sse41_pmaxuw>;
6309   defm PMULDQ   : SS41I_binop_rm_int<0x28, "pmuldq",   int_x86_sse41_pmuldq>;
6310 }
6311
6312 /// SS48I_binop_rm - Simple SSE41 binary operator.
6313 multiclass SS48I_binop_rm<bits<8> opc, string OpcodeStr, SDNode OpNode,
6314                           ValueType OpVT, RegisterClass RC, PatFrag memop_frag,
6315                           X86MemOperand x86memop, bit Is2Addr = 1> {
6316   let isCommutable = 1 in
6317   def rr : SS48I<opc, MRMSrcReg, (outs RC:$dst),
6318        (ins RC:$src1, RC:$src2),
6319        !if(Is2Addr,
6320            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
6321            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
6322        [(set RC:$dst, (OpVT (OpNode RC:$src1, RC:$src2)))]>, OpSize;
6323   def rm : SS48I<opc, MRMSrcMem, (outs RC:$dst),
6324        (ins RC:$src1, x86memop:$src2),
6325        !if(Is2Addr,
6326            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
6327            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
6328        [(set RC:$dst,
6329          (OpVT (OpNode RC:$src1,
6330           (bitconvert (memop_frag addr:$src2)))))]>, OpSize;
6331 }
6332
6333 let Predicates = [HasAVX] in {
6334   defm VPMULLD  : SS48I_binop_rm<0x40, "vpmulld", mul, v4i32, VR128,
6335                                 memopv2i64, i128mem, 0>, VEX_4V;
6336   defm VPCMPEQQ : SS48I_binop_rm<0x29, "vpcmpeqq", X86pcmpeq, v2i64, VR128,
6337                                  memopv2i64, i128mem, 0>, VEX_4V;
6338 }
6339 let Predicates = [HasAVX2] in {
6340   defm VPMULLDY  : SS48I_binop_rm<0x40, "vpmulld", mul, v8i32, VR256,
6341                                   memopv4i64, i256mem, 0>, VEX_4V;
6342   defm VPCMPEQQY : SS48I_binop_rm<0x29, "vpcmpeqq", X86pcmpeq, v4i64, VR256,
6343                                   memopv4i64, i256mem, 0>, VEX_4V;
6344 }
6345
6346 let Constraints = "$src1 = $dst" in {
6347   defm PMULLD  : SS48I_binop_rm<0x40, "pmulld", mul, v4i32, VR128,
6348                                 memopv2i64, i128mem>;
6349   defm PCMPEQQ : SS48I_binop_rm<0x29, "pcmpeqq", X86pcmpeq, v2i64, VR128,
6350                                 memopv2i64, i128mem>;
6351 }
6352
6353 /// SS41I_binop_rmi_int - SSE 4.1 binary operator with 8-bit immediate
6354 multiclass SS41I_binop_rmi_int<bits<8> opc, string OpcodeStr,
6355                  Intrinsic IntId, RegisterClass RC, PatFrag memop_frag,
6356                  X86MemOperand x86memop, bit Is2Addr = 1> {
6357   let isCommutable = 1 in
6358   def rri : SS4AIi8<opc, MRMSrcReg, (outs RC:$dst),
6359         (ins RC:$src1, RC:$src2, u32u8imm:$src3),
6360         !if(Is2Addr,
6361             !strconcat(OpcodeStr,
6362                 "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6363             !strconcat(OpcodeStr,
6364                 "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6365         [(set RC:$dst, (IntId RC:$src1, RC:$src2, imm:$src3))]>,
6366         OpSize;
6367   def rmi : SS4AIi8<opc, MRMSrcMem, (outs RC:$dst),
6368         (ins RC:$src1, x86memop:$src2, u32u8imm:$src3),
6369         !if(Is2Addr,
6370             !strconcat(OpcodeStr,
6371                 "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6372             !strconcat(OpcodeStr,
6373                 "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6374         [(set RC:$dst,
6375           (IntId RC:$src1,
6376            (bitconvert (memop_frag addr:$src2)), imm:$src3))]>,
6377         OpSize;
6378 }
6379
6380 let Predicates = [HasAVX] in {
6381   let isCommutable = 0 in {
6382     let ExeDomain = SSEPackedSingle in {
6383     defm VBLENDPS : SS41I_binop_rmi_int<0x0C, "vblendps", int_x86_sse41_blendps,
6384                                         VR128, memopv4f32, i128mem, 0>, VEX_4V;
6385     defm VBLENDPSY : SS41I_binop_rmi_int<0x0C, "vblendps",
6386               int_x86_avx_blend_ps_256, VR256, memopv8f32, i256mem, 0>, VEX_4V;
6387     }
6388     let ExeDomain = SSEPackedDouble in {
6389     defm VBLENDPD : SS41I_binop_rmi_int<0x0D, "vblendpd", int_x86_sse41_blendpd,
6390                                         VR128, memopv2f64, i128mem, 0>, VEX_4V;
6391     defm VBLENDPDY : SS41I_binop_rmi_int<0x0D, "vblendpd",
6392               int_x86_avx_blend_pd_256, VR256, memopv4f64, i256mem, 0>, VEX_4V;
6393     }
6394   defm VPBLENDW : SS41I_binop_rmi_int<0x0E, "vpblendw", int_x86_sse41_pblendw,
6395                                       VR128, memopv2i64, i128mem, 0>, VEX_4V;
6396   defm VMPSADBW : SS41I_binop_rmi_int<0x42, "vmpsadbw", int_x86_sse41_mpsadbw,
6397                                       VR128, memopv2i64, i128mem, 0>, VEX_4V;
6398   }
6399   let ExeDomain = SSEPackedSingle in
6400   defm VDPPS : SS41I_binop_rmi_int<0x40, "vdpps", int_x86_sse41_dpps,
6401                                    VR128, memopv4f32, i128mem, 0>, VEX_4V;
6402   let ExeDomain = SSEPackedDouble in
6403   defm VDPPD : SS41I_binop_rmi_int<0x41, "vdppd", int_x86_sse41_dppd,
6404                                    VR128, memopv2f64, i128mem, 0>, VEX_4V;
6405   let ExeDomain = SSEPackedSingle in
6406   defm VDPPSY : SS41I_binop_rmi_int<0x40, "vdpps", int_x86_avx_dp_ps_256,
6407                                    VR256, memopv8f32, i256mem, 0>, VEX_4V;
6408 }
6409
6410 let Predicates = [HasAVX2] in {
6411   let isCommutable = 0 in {
6412   defm VPBLENDWY : SS41I_binop_rmi_int<0x0E, "vpblendw", int_x86_avx2_pblendw,
6413                                        VR256, memopv4i64, i256mem, 0>, VEX_4V;
6414   defm VMPSADBWY : SS41I_binop_rmi_int<0x42, "vmpsadbw", int_x86_avx2_mpsadbw,
6415                                        VR256, memopv4i64, i256mem, 0>, VEX_4V;
6416   }
6417 }
6418
6419 let Constraints = "$src1 = $dst" in {
6420   let isCommutable = 0 in {
6421   let ExeDomain = SSEPackedSingle in
6422   defm BLENDPS : SS41I_binop_rmi_int<0x0C, "blendps", int_x86_sse41_blendps,
6423                                      VR128, memopv4f32, i128mem>;
6424   let ExeDomain = SSEPackedDouble in
6425   defm BLENDPD : SS41I_binop_rmi_int<0x0D, "blendpd", int_x86_sse41_blendpd,
6426                                      VR128, memopv2f64, i128mem>;
6427   defm PBLENDW : SS41I_binop_rmi_int<0x0E, "pblendw", int_x86_sse41_pblendw,
6428                                      VR128, memopv2i64, i128mem>;
6429   defm MPSADBW : SS41I_binop_rmi_int<0x42, "mpsadbw", int_x86_sse41_mpsadbw,
6430                                      VR128, memopv2i64, i128mem>;
6431   }
6432   let ExeDomain = SSEPackedSingle in
6433   defm DPPS : SS41I_binop_rmi_int<0x40, "dpps", int_x86_sse41_dpps,
6434                                   VR128, memopv4f32, i128mem>;
6435   let ExeDomain = SSEPackedDouble in
6436   defm DPPD : SS41I_binop_rmi_int<0x41, "dppd", int_x86_sse41_dppd,
6437                                   VR128, memopv2f64, i128mem>;
6438 }
6439
6440 /// SS41I_quaternary_int_avx - AVX SSE 4.1 with 4 operators
6441 multiclass SS41I_quaternary_int_avx<bits<8> opc, string OpcodeStr,
6442                                     RegisterClass RC, X86MemOperand x86memop,
6443                                     PatFrag mem_frag, Intrinsic IntId> {
6444   def rr : Ii8<opc, MRMSrcReg, (outs RC:$dst),
6445                   (ins RC:$src1, RC:$src2, RC:$src3),
6446                   !strconcat(OpcodeStr,
6447                     "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
6448                   [(set RC:$dst, (IntId RC:$src1, RC:$src2, RC:$src3))],
6449                   SSEPackedInt>, OpSize, TA, VEX_4V, VEX_I8IMM;
6450
6451   def rm : Ii8<opc, MRMSrcMem, (outs RC:$dst),
6452                   (ins RC:$src1, x86memop:$src2, RC:$src3),
6453                   !strconcat(OpcodeStr,
6454                     "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
6455                   [(set RC:$dst,
6456                         (IntId RC:$src1, (bitconvert (mem_frag addr:$src2)),
6457                                RC:$src3))],
6458                   SSEPackedInt>, OpSize, TA, VEX_4V, VEX_I8IMM;
6459 }
6460
6461 let Predicates = [HasAVX] in {
6462 let ExeDomain = SSEPackedDouble in {
6463 defm VBLENDVPD  : SS41I_quaternary_int_avx<0x4B, "vblendvpd", VR128, i128mem,
6464                                            memopv2f64, int_x86_sse41_blendvpd>;
6465 defm VBLENDVPDY : SS41I_quaternary_int_avx<0x4B, "vblendvpd", VR256, i256mem,
6466                                          memopv4f64, int_x86_avx_blendv_pd_256>;
6467 } // ExeDomain = SSEPackedDouble
6468 let ExeDomain = SSEPackedSingle in {
6469 defm VBLENDVPS  : SS41I_quaternary_int_avx<0x4A, "vblendvps", VR128, i128mem,
6470                                            memopv4f32, int_x86_sse41_blendvps>;
6471 defm VBLENDVPSY : SS41I_quaternary_int_avx<0x4A, "vblendvps", VR256, i256mem,
6472                                          memopv8f32, int_x86_avx_blendv_ps_256>;
6473 } // ExeDomain = SSEPackedSingle
6474 defm VPBLENDVB  : SS41I_quaternary_int_avx<0x4C, "vpblendvb", VR128, i128mem,
6475                                            memopv2i64, int_x86_sse41_pblendvb>;
6476 }
6477
6478 let Predicates = [HasAVX2] in {
6479 defm VPBLENDVBY : SS41I_quaternary_int_avx<0x4C, "vpblendvb", VR256, i256mem,
6480                                            memopv4i64, int_x86_avx2_pblendvb>;
6481 }
6482
6483 let Predicates = [HasAVX] in {
6484   def : Pat<(v16i8 (vselect (v16i8 VR128:$mask), (v16i8 VR128:$src1),
6485                             (v16i8 VR128:$src2))),
6486             (VPBLENDVBrr VR128:$src2, VR128:$src1, VR128:$mask)>;
6487   def : Pat<(v4i32 (vselect (v4i32 VR128:$mask), (v4i32 VR128:$src1),
6488                             (v4i32 VR128:$src2))),
6489             (VBLENDVPSrr VR128:$src2, VR128:$src1, VR128:$mask)>;
6490   def : Pat<(v4f32 (vselect (v4i32 VR128:$mask), (v4f32 VR128:$src1),
6491                             (v4f32 VR128:$src2))),
6492             (VBLENDVPSrr VR128:$src2, VR128:$src1, VR128:$mask)>;
6493   def : Pat<(v2i64 (vselect (v2i64 VR128:$mask), (v2i64 VR128:$src1),
6494                             (v2i64 VR128:$src2))),
6495             (VBLENDVPDrr VR128:$src2, VR128:$src1, VR128:$mask)>;
6496   def : Pat<(v2f64 (vselect (v2i64 VR128:$mask), (v2f64 VR128:$src1),
6497                             (v2f64 VR128:$src2))),
6498             (VBLENDVPDrr VR128:$src2, VR128:$src1, VR128:$mask)>;
6499   def : Pat<(v8i32 (vselect (v8i32 VR256:$mask), (v8i32 VR256:$src1),
6500                             (v8i32 VR256:$src2))),
6501             (VBLENDVPSYrr VR256:$src2, VR256:$src1, VR256:$mask)>;
6502   def : Pat<(v8f32 (vselect (v8i32 VR256:$mask), (v8f32 VR256:$src1),
6503                             (v8f32 VR256:$src2))),
6504             (VBLENDVPSYrr VR256:$src2, VR256:$src1, VR256:$mask)>;
6505   def : Pat<(v4i64 (vselect (v4i64 VR256:$mask), (v4i64 VR256:$src1),
6506                             (v4i64 VR256:$src2))),
6507             (VBLENDVPDYrr VR256:$src2, VR256:$src1, VR256:$mask)>;
6508   def : Pat<(v4f64 (vselect (v4i64 VR256:$mask), (v4f64 VR256:$src1),
6509                             (v4f64 VR256:$src2))),
6510             (VBLENDVPDYrr VR256:$src2, VR256:$src1, VR256:$mask)>;
6511 }
6512
6513 let Predicates = [HasAVX2] in {
6514   def : Pat<(v32i8 (vselect (v32i8 VR256:$mask), (v32i8 VR256:$src1),
6515                             (v32i8 VR256:$src2))),
6516             (VPBLENDVBYrr VR256:$src2, VR256:$src1, VR256:$mask)>;
6517 }
6518
6519 /// SS41I_ternary_int - SSE 4.1 ternary operator
6520 let Uses = [XMM0], Constraints = "$src1 = $dst" in {
6521   multiclass SS41I_ternary_int<bits<8> opc, string OpcodeStr, PatFrag mem_frag,
6522                                Intrinsic IntId> {
6523     def rr0 : SS48I<opc, MRMSrcReg, (outs VR128:$dst),
6524                     (ins VR128:$src1, VR128:$src2),
6525                     !strconcat(OpcodeStr,
6526                      "\t{$src2, $dst|$dst, $src2}"),
6527                     [(set VR128:$dst, (IntId VR128:$src1, VR128:$src2, XMM0))]>,
6528                     OpSize;
6529
6530     def rm0 : SS48I<opc, MRMSrcMem, (outs VR128:$dst),
6531                     (ins VR128:$src1, i128mem:$src2),
6532                     !strconcat(OpcodeStr,
6533                      "\t{$src2, $dst|$dst, $src2}"),
6534                     [(set VR128:$dst,
6535                       (IntId VR128:$src1,
6536                        (bitconvert (mem_frag addr:$src2)), XMM0))]>, OpSize;
6537   }
6538 }
6539
6540 let ExeDomain = SSEPackedDouble in
6541 defm BLENDVPD : SS41I_ternary_int<0x15, "blendvpd", memopv2f64,
6542                                   int_x86_sse41_blendvpd>;
6543 let ExeDomain = SSEPackedSingle in
6544 defm BLENDVPS : SS41I_ternary_int<0x14, "blendvps", memopv4f32,
6545                                   int_x86_sse41_blendvps>;
6546 defm PBLENDVB : SS41I_ternary_int<0x10, "pblendvb", memopv2i64,
6547                                   int_x86_sse41_pblendvb>;
6548
6549 let Predicates = [HasSSE41] in {
6550   def : Pat<(v16i8 (vselect (v16i8 XMM0), (v16i8 VR128:$src1),
6551                             (v16i8 VR128:$src2))),
6552             (PBLENDVBrr0 VR128:$src2, VR128:$src1)>;
6553   def : Pat<(v4i32 (vselect (v4i32 XMM0), (v4i32 VR128:$src1),
6554                             (v4i32 VR128:$src2))),
6555             (BLENDVPSrr0 VR128:$src2, VR128:$src1)>;
6556   def : Pat<(v4f32 (vselect (v4i32 XMM0), (v4f32 VR128:$src1),
6557                             (v4f32 VR128:$src2))),
6558             (BLENDVPSrr0 VR128:$src2, VR128:$src1)>;
6559   def : Pat<(v2i64 (vselect (v2i64 XMM0), (v2i64 VR128:$src1),
6560                             (v2i64 VR128:$src2))),
6561             (BLENDVPDrr0 VR128:$src2, VR128:$src1)>;
6562   def : Pat<(v2f64 (vselect (v2i64 XMM0), (v2f64 VR128:$src1),
6563                             (v2f64 VR128:$src2))),
6564             (BLENDVPDrr0 VR128:$src2, VR128:$src1)>;
6565 }
6566
6567 let Predicates = [HasAVX] in
6568 def VMOVNTDQArm : SS48I<0x2A, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
6569                        "vmovntdqa\t{$src, $dst|$dst, $src}",
6570                        [(set VR128:$dst, (int_x86_sse41_movntdqa addr:$src))]>,
6571                        OpSize, VEX;
6572 let Predicates = [HasAVX2] in
6573 def VMOVNTDQAYrm : SS48I<0x2A, MRMSrcMem, (outs VR256:$dst), (ins i256mem:$src),
6574                          "vmovntdqa\t{$src, $dst|$dst, $src}",
6575                          [(set VR256:$dst, (int_x86_avx2_movntdqa addr:$src))]>,
6576                          OpSize, VEX;
6577 def MOVNTDQArm : SS48I<0x2A, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
6578                        "movntdqa\t{$src, $dst|$dst, $src}",
6579                        [(set VR128:$dst, (int_x86_sse41_movntdqa addr:$src))]>,
6580                        OpSize;
6581
6582 //===----------------------------------------------------------------------===//
6583 // SSE4.2 - Compare Instructions
6584 //===----------------------------------------------------------------------===//
6585
6586 /// SS42I_binop_rm - Simple SSE 4.2 binary operator
6587 multiclass SS42I_binop_rm<bits<8> opc, string OpcodeStr, SDNode OpNode,
6588                           ValueType OpVT, RegisterClass RC, PatFrag memop_frag,
6589                           X86MemOperand x86memop, bit Is2Addr = 1> {
6590   def rr : SS428I<opc, MRMSrcReg, (outs RC:$dst),
6591        (ins RC:$src1, RC:$src2),
6592        !if(Is2Addr,
6593            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
6594            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
6595        [(set RC:$dst, (OpVT (OpNode RC:$src1, RC:$src2)))]>,
6596        OpSize;
6597   def rm : SS428I<opc, MRMSrcMem, (outs RC:$dst),
6598        (ins RC:$src1, x86memop:$src2),
6599        !if(Is2Addr,
6600            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
6601            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
6602        [(set RC:$dst,
6603          (OpVT (OpNode RC:$src1, (memop_frag addr:$src2))))]>, OpSize;
6604 }
6605
6606 let Predicates = [HasAVX] in
6607   defm VPCMPGTQ : SS42I_binop_rm<0x37, "vpcmpgtq", X86pcmpgt, v2i64, VR128,
6608                                  memopv2i64, i128mem, 0>, VEX_4V;
6609
6610 let Predicates = [HasAVX2] in
6611   defm VPCMPGTQY : SS42I_binop_rm<0x37, "vpcmpgtq", X86pcmpgt, v4i64, VR256,
6612                                   memopv4i64, i256mem, 0>, VEX_4V;
6613
6614 let Constraints = "$src1 = $dst" in
6615   defm PCMPGTQ : SS42I_binop_rm<0x37, "pcmpgtq", X86pcmpgt, v2i64, VR128,
6616                                 memopv2i64, i128mem>;
6617
6618 //===----------------------------------------------------------------------===//
6619 // SSE4.2 - String/text Processing Instructions
6620 //===----------------------------------------------------------------------===//
6621
6622 // Packed Compare Implicit Length Strings, Return Mask
6623 multiclass pseudo_pcmpistrm<string asm> {
6624   def REG : PseudoI<(outs VR128:$dst),
6625                     (ins VR128:$src1, VR128:$src2, i8imm:$src3),
6626     [(set VR128:$dst, (int_x86_sse42_pcmpistrm128 VR128:$src1, VR128:$src2,
6627                                                   imm:$src3))]>;
6628   def MEM : PseudoI<(outs VR128:$dst),
6629                     (ins VR128:$src1, i128mem:$src2, i8imm:$src3),
6630     [(set VR128:$dst, (int_x86_sse42_pcmpistrm128
6631                        VR128:$src1, (load addr:$src2), imm:$src3))]>;
6632 }
6633
6634 let Defs = [EFLAGS], usesCustomInserter = 1 in {
6635   defm PCMPISTRM128 : pseudo_pcmpistrm<"#PCMPISTRM128">, Requires<[HasSSE42]>;
6636   defm VPCMPISTRM128 : pseudo_pcmpistrm<"#VPCMPISTRM128">, Requires<[HasAVX]>;
6637 }
6638
6639 let Defs = [XMM0, EFLAGS], neverHasSideEffects = 1, Predicates = [HasAVX] in {
6640   def VPCMPISTRM128rr : SS42AI<0x62, MRMSrcReg, (outs),
6641       (ins VR128:$src1, VR128:$src2, i8imm:$src3),
6642       "vpcmpistrm\t{$src3, $src2, $src1|$src1, $src2, $src3}", []>, OpSize, VEX;
6643   let mayLoad = 1 in
6644   def VPCMPISTRM128rm : SS42AI<0x62, MRMSrcMem, (outs),
6645       (ins VR128:$src1, i128mem:$src2, i8imm:$src3),
6646       "vpcmpistrm\t{$src3, $src2, $src1|$src1, $src2, $src3}", []>, OpSize, VEX;
6647 }
6648
6649 let Defs = [XMM0, EFLAGS], neverHasSideEffects = 1 in {
6650   def PCMPISTRM128rr : SS42AI<0x62, MRMSrcReg, (outs),
6651       (ins VR128:$src1, VR128:$src2, i8imm:$src3),
6652       "pcmpistrm\t{$src3, $src2, $src1|$src1, $src2, $src3}", []>, OpSize;
6653   let mayLoad = 1 in
6654   def PCMPISTRM128rm : SS42AI<0x62, MRMSrcMem, (outs),
6655       (ins VR128:$src1, i128mem:$src2, i8imm:$src3),
6656       "pcmpistrm\t{$src3, $src2, $src1|$src1, $src2, $src3}", []>, OpSize;
6657 }
6658
6659 // Packed Compare Explicit Length Strings, Return Mask
6660 multiclass pseudo_pcmpestrm<string asm> {
6661   def REG : PseudoI<(outs VR128:$dst),
6662                     (ins VR128:$src1, VR128:$src3, i8imm:$src5),
6663     [(set VR128:$dst, (int_x86_sse42_pcmpestrm128
6664                        VR128:$src1, EAX, VR128:$src3, EDX, imm:$src5))]>;
6665   def MEM : PseudoI<(outs VR128:$dst),
6666                     (ins VR128:$src1, i128mem:$src3, i8imm:$src5),
6667     [(set VR128:$dst, (int_x86_sse42_pcmpestrm128
6668                        VR128:$src1, EAX, (load addr:$src3), EDX, imm:$src5))]>;
6669 }
6670
6671 let Defs = [EFLAGS], Uses = [EAX, EDX], usesCustomInserter = 1 in {
6672   defm PCMPESTRM128 : pseudo_pcmpestrm<"#PCMPESTRM128">, Requires<[HasSSE42]>;
6673   defm VPCMPESTRM128 : pseudo_pcmpestrm<"#VPCMPESTRM128">, Requires<[HasAVX]>;
6674 }
6675
6676 let Predicates = [HasAVX],
6677     Defs = [XMM0, EFLAGS], Uses = [EAX, EDX], neverHasSideEffects = 1 in {
6678   def VPCMPESTRM128rr : SS42AI<0x60, MRMSrcReg, (outs),
6679       (ins VR128:$src1, VR128:$src3, i8imm:$src5),
6680       "vpcmpestrm\t{$src5, $src3, $src1|$src1, $src3, $src5}", []>, OpSize, VEX;
6681   let mayLoad = 1 in
6682   def VPCMPESTRM128rm : SS42AI<0x60, MRMSrcMem, (outs),
6683       (ins VR128:$src1, i128mem:$src3, i8imm:$src5),
6684       "vpcmpestrm\t{$src5, $src3, $src1|$src1, $src3, $src5}", []>, OpSize, VEX;
6685 }
6686
6687 let Defs = [XMM0, EFLAGS], Uses = [EAX, EDX], neverHasSideEffects = 1 in {
6688   def PCMPESTRM128rr : SS42AI<0x60, MRMSrcReg, (outs),
6689       (ins VR128:$src1, VR128:$src3, i8imm:$src5),
6690       "pcmpestrm\t{$src5, $src3, $src1|$src1, $src3, $src5}", []>, OpSize;
6691   let mayLoad = 1 in
6692   def PCMPESTRM128rm : SS42AI<0x60, MRMSrcMem, (outs),
6693       (ins VR128:$src1, i128mem:$src3, i8imm:$src5),
6694       "pcmpestrm\t{$src5, $src3, $src1|$src1, $src3, $src5}", []>, OpSize;
6695 }
6696
6697 // Packed Compare Implicit Length Strings, Return Index
6698 let Defs = [ECX, EFLAGS] in {
6699   multiclass SS42AI_pcmpistri<Intrinsic IntId128, string asm = "pcmpistri"> {
6700     def rr : SS42AI<0x63, MRMSrcReg, (outs),
6701       (ins VR128:$src1, VR128:$src2, i8imm:$src3),
6702       !strconcat(asm, "\t{$src3, $src2, $src1|$src1, $src2, $src3}"),
6703       [(set ECX, (IntId128 VR128:$src1, VR128:$src2, imm:$src3)),
6704        (implicit EFLAGS)]>, OpSize;
6705     def rm : SS42AI<0x63, MRMSrcMem, (outs),
6706       (ins VR128:$src1, i128mem:$src2, i8imm:$src3),
6707       !strconcat(asm, "\t{$src3, $src2, $src1|$src1, $src2, $src3}"),
6708       [(set ECX, (IntId128 VR128:$src1, (load addr:$src2), imm:$src3)),
6709        (implicit EFLAGS)]>, OpSize;
6710   }
6711 }
6712
6713 let Predicates = [HasAVX] in {
6714 defm VPCMPISTRI  : SS42AI_pcmpistri<int_x86_sse42_pcmpistri128, "vpcmpistri">,
6715                                     VEX;
6716 defm VPCMPISTRIA : SS42AI_pcmpistri<int_x86_sse42_pcmpistria128, "vpcmpistri">,
6717                                     VEX;
6718 defm VPCMPISTRIC : SS42AI_pcmpistri<int_x86_sse42_pcmpistric128, "vpcmpistri">,
6719                                     VEX;
6720 defm VPCMPISTRIO : SS42AI_pcmpistri<int_x86_sse42_pcmpistrio128, "vpcmpistri">,
6721                                     VEX;
6722 defm VPCMPISTRIS : SS42AI_pcmpistri<int_x86_sse42_pcmpistris128, "vpcmpistri">,
6723                                     VEX;
6724 defm VPCMPISTRIZ : SS42AI_pcmpistri<int_x86_sse42_pcmpistriz128, "vpcmpistri">,
6725                                     VEX;
6726 }
6727
6728 defm PCMPISTRI  : SS42AI_pcmpistri<int_x86_sse42_pcmpistri128>;
6729 defm PCMPISTRIA : SS42AI_pcmpistri<int_x86_sse42_pcmpistria128>;
6730 defm PCMPISTRIC : SS42AI_pcmpistri<int_x86_sse42_pcmpistric128>;
6731 defm PCMPISTRIO : SS42AI_pcmpistri<int_x86_sse42_pcmpistrio128>;
6732 defm PCMPISTRIS : SS42AI_pcmpistri<int_x86_sse42_pcmpistris128>;
6733 defm PCMPISTRIZ : SS42AI_pcmpistri<int_x86_sse42_pcmpistriz128>;
6734
6735 // Packed Compare Explicit Length Strings, Return Index
6736 let Defs = [ECX, EFLAGS], Uses = [EAX, EDX] in {
6737   multiclass SS42AI_pcmpestri<Intrinsic IntId128, string asm = "pcmpestri"> {
6738     def rr : SS42AI<0x61, MRMSrcReg, (outs),
6739       (ins VR128:$src1, VR128:$src3, i8imm:$src5),
6740       !strconcat(asm, "\t{$src5, $src3, $src1|$src1, $src3, $src5}"),
6741       [(set ECX, (IntId128 VR128:$src1, EAX, VR128:$src3, EDX, imm:$src5)),
6742        (implicit EFLAGS)]>, OpSize;
6743     def rm : SS42AI<0x61, MRMSrcMem, (outs),
6744       (ins VR128:$src1, i128mem:$src3, i8imm:$src5),
6745       !strconcat(asm, "\t{$src5, $src3, $src1|$src1, $src3, $src5}"),
6746        [(set ECX,
6747              (IntId128 VR128:$src1, EAX, (load addr:$src3), EDX, imm:$src5)),
6748         (implicit EFLAGS)]>, OpSize;
6749   }
6750 }
6751
6752 let Predicates = [HasAVX] in {
6753 defm VPCMPESTRI  : SS42AI_pcmpestri<int_x86_sse42_pcmpestri128, "vpcmpestri">,
6754                                     VEX;
6755 defm VPCMPESTRIA : SS42AI_pcmpestri<int_x86_sse42_pcmpestria128, "vpcmpestri">,
6756                                     VEX;
6757 defm VPCMPESTRIC : SS42AI_pcmpestri<int_x86_sse42_pcmpestric128, "vpcmpestri">,
6758                                     VEX;
6759 defm VPCMPESTRIO : SS42AI_pcmpestri<int_x86_sse42_pcmpestrio128, "vpcmpestri">,
6760                                     VEX;
6761 defm VPCMPESTRIS : SS42AI_pcmpestri<int_x86_sse42_pcmpestris128, "vpcmpestri">,
6762                                     VEX;
6763 defm VPCMPESTRIZ : SS42AI_pcmpestri<int_x86_sse42_pcmpestriz128, "vpcmpestri">,
6764                                     VEX;
6765 }
6766
6767 defm PCMPESTRI  : SS42AI_pcmpestri<int_x86_sse42_pcmpestri128>;
6768 defm PCMPESTRIA : SS42AI_pcmpestri<int_x86_sse42_pcmpestria128>;
6769 defm PCMPESTRIC : SS42AI_pcmpestri<int_x86_sse42_pcmpestric128>;
6770 defm PCMPESTRIO : SS42AI_pcmpestri<int_x86_sse42_pcmpestrio128>;
6771 defm PCMPESTRIS : SS42AI_pcmpestri<int_x86_sse42_pcmpestris128>;
6772 defm PCMPESTRIZ : SS42AI_pcmpestri<int_x86_sse42_pcmpestriz128>;
6773
6774 //===----------------------------------------------------------------------===//
6775 // SSE4.2 - CRC Instructions
6776 //===----------------------------------------------------------------------===//
6777
6778 // No CRC instructions have AVX equivalents
6779
6780 // crc intrinsic instruction
6781 // This set of instructions are only rm, the only difference is the size
6782 // of r and m.
6783 let Constraints = "$src1 = $dst" in {
6784   def CRC32r32m8  : SS42FI<0xF0, MRMSrcMem, (outs GR32:$dst),
6785                       (ins GR32:$src1, i8mem:$src2),
6786                       "crc32{b} \t{$src2, $src1|$src1, $src2}",
6787                        [(set GR32:$dst,
6788                          (int_x86_sse42_crc32_32_8 GR32:$src1,
6789                          (load addr:$src2)))]>;
6790   def CRC32r32r8  : SS42FI<0xF0, MRMSrcReg, (outs GR32:$dst),
6791                       (ins GR32:$src1, GR8:$src2),
6792                       "crc32{b} \t{$src2, $src1|$src1, $src2}",
6793                        [(set GR32:$dst,
6794                          (int_x86_sse42_crc32_32_8 GR32:$src1, GR8:$src2))]>;
6795   def CRC32r32m16  : SS42FI<0xF1, MRMSrcMem, (outs GR32:$dst),
6796                       (ins GR32:$src1, i16mem:$src2),
6797                       "crc32{w} \t{$src2, $src1|$src1, $src2}",
6798                        [(set GR32:$dst,
6799                          (int_x86_sse42_crc32_32_16 GR32:$src1,
6800                          (load addr:$src2)))]>,
6801                          OpSize;
6802   def CRC32r32r16  : SS42FI<0xF1, MRMSrcReg, (outs GR32:$dst),
6803                       (ins GR32:$src1, GR16:$src2),
6804                       "crc32{w} \t{$src2, $src1|$src1, $src2}",
6805                        [(set GR32:$dst,
6806                          (int_x86_sse42_crc32_32_16 GR32:$src1, GR16:$src2))]>,
6807                          OpSize;
6808   def CRC32r32m32  : SS42FI<0xF1, MRMSrcMem, (outs GR32:$dst),
6809                       (ins GR32:$src1, i32mem:$src2),
6810                       "crc32{l} \t{$src2, $src1|$src1, $src2}",
6811                        [(set GR32:$dst,
6812                          (int_x86_sse42_crc32_32_32 GR32:$src1,
6813                          (load addr:$src2)))]>;
6814   def CRC32r32r32  : SS42FI<0xF1, MRMSrcReg, (outs GR32:$dst),
6815                       (ins GR32:$src1, GR32:$src2),
6816                       "crc32{l} \t{$src2, $src1|$src1, $src2}",
6817                        [(set GR32:$dst,
6818                          (int_x86_sse42_crc32_32_32 GR32:$src1, GR32:$src2))]>;
6819   def CRC32r64m8  : SS42FI<0xF0, MRMSrcMem, (outs GR64:$dst),
6820                       (ins GR64:$src1, i8mem:$src2),
6821                       "crc32{b} \t{$src2, $src1|$src1, $src2}",
6822                        [(set GR64:$dst,
6823                          (int_x86_sse42_crc32_64_8 GR64:$src1,
6824                          (load addr:$src2)))]>,
6825                          REX_W;
6826   def CRC32r64r8  : SS42FI<0xF0, MRMSrcReg, (outs GR64:$dst),
6827                       (ins GR64:$src1, GR8:$src2),
6828                       "crc32{b} \t{$src2, $src1|$src1, $src2}",
6829                        [(set GR64:$dst,
6830                          (int_x86_sse42_crc32_64_8 GR64:$src1, GR8:$src2))]>,
6831                          REX_W;
6832   def CRC32r64m64  : SS42FI<0xF1, MRMSrcMem, (outs GR64:$dst),
6833                       (ins GR64:$src1, i64mem:$src2),
6834                       "crc32{q} \t{$src2, $src1|$src1, $src2}",
6835                        [(set GR64:$dst,
6836                          (int_x86_sse42_crc32_64_64 GR64:$src1,
6837                          (load addr:$src2)))]>,
6838                          REX_W;
6839   def CRC32r64r64  : SS42FI<0xF1, MRMSrcReg, (outs GR64:$dst),
6840                       (ins GR64:$src1, GR64:$src2),
6841                       "crc32{q} \t{$src2, $src1|$src1, $src2}",
6842                        [(set GR64:$dst,
6843                          (int_x86_sse42_crc32_64_64 GR64:$src1, GR64:$src2))]>,
6844                          REX_W;
6845 }
6846
6847 //===----------------------------------------------------------------------===//
6848 // AES-NI Instructions
6849 //===----------------------------------------------------------------------===//
6850
6851 multiclass AESI_binop_rm_int<bits<8> opc, string OpcodeStr,
6852                               Intrinsic IntId128, bit Is2Addr = 1> {
6853   def rr : AES8I<opc, MRMSrcReg, (outs VR128:$dst),
6854        (ins VR128:$src1, VR128:$src2),
6855        !if(Is2Addr,
6856            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
6857            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
6858        [(set VR128:$dst, (IntId128 VR128:$src1, VR128:$src2))]>,
6859        OpSize;
6860   def rm : AES8I<opc, MRMSrcMem, (outs VR128:$dst),
6861        (ins VR128:$src1, i128mem:$src2),
6862        !if(Is2Addr,
6863            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
6864            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
6865        [(set VR128:$dst,
6866          (IntId128 VR128:$src1, (memopv2i64 addr:$src2)))]>, OpSize;
6867 }
6868
6869 // Perform One Round of an AES Encryption/Decryption Flow
6870 let Predicates = [HasAVX, HasAES] in {
6871   defm VAESENC          : AESI_binop_rm_int<0xDC, "vaesenc",
6872                          int_x86_aesni_aesenc, 0>, VEX_4V;
6873   defm VAESENCLAST      : AESI_binop_rm_int<0xDD, "vaesenclast",
6874                          int_x86_aesni_aesenclast, 0>, VEX_4V;
6875   defm VAESDEC          : AESI_binop_rm_int<0xDE, "vaesdec",
6876                          int_x86_aesni_aesdec, 0>, VEX_4V;
6877   defm VAESDECLAST      : AESI_binop_rm_int<0xDF, "vaesdeclast",
6878                          int_x86_aesni_aesdeclast, 0>, VEX_4V;
6879 }
6880
6881 let Constraints = "$src1 = $dst" in {
6882   defm AESENC          : AESI_binop_rm_int<0xDC, "aesenc",
6883                          int_x86_aesni_aesenc>;
6884   defm AESENCLAST      : AESI_binop_rm_int<0xDD, "aesenclast",
6885                          int_x86_aesni_aesenclast>;
6886   defm AESDEC          : AESI_binop_rm_int<0xDE, "aesdec",
6887                          int_x86_aesni_aesdec>;
6888   defm AESDECLAST      : AESI_binop_rm_int<0xDF, "aesdeclast",
6889                          int_x86_aesni_aesdeclast>;
6890 }
6891
6892 // Perform the AES InvMixColumn Transformation
6893 let Predicates = [HasAVX, HasAES] in {
6894   def VAESIMCrr : AES8I<0xDB, MRMSrcReg, (outs VR128:$dst),
6895       (ins VR128:$src1),
6896       "vaesimc\t{$src1, $dst|$dst, $src1}",
6897       [(set VR128:$dst,
6898         (int_x86_aesni_aesimc VR128:$src1))]>,
6899       OpSize, VEX;
6900   def VAESIMCrm : AES8I<0xDB, MRMSrcMem, (outs VR128:$dst),
6901       (ins i128mem:$src1),
6902       "vaesimc\t{$src1, $dst|$dst, $src1}",
6903       [(set VR128:$dst, (int_x86_aesni_aesimc (memopv2i64 addr:$src1)))]>,
6904       OpSize, VEX;
6905 }
6906 def AESIMCrr : AES8I<0xDB, MRMSrcReg, (outs VR128:$dst),
6907   (ins VR128:$src1),
6908   "aesimc\t{$src1, $dst|$dst, $src1}",
6909   [(set VR128:$dst,
6910     (int_x86_aesni_aesimc VR128:$src1))]>,
6911   OpSize;
6912 def AESIMCrm : AES8I<0xDB, MRMSrcMem, (outs VR128:$dst),
6913   (ins i128mem:$src1),
6914   "aesimc\t{$src1, $dst|$dst, $src1}",
6915   [(set VR128:$dst, (int_x86_aesni_aesimc (memopv2i64 addr:$src1)))]>,
6916   OpSize;
6917
6918 // AES Round Key Generation Assist
6919 let Predicates = [HasAVX, HasAES] in {
6920   def VAESKEYGENASSIST128rr : AESAI<0xDF, MRMSrcReg, (outs VR128:$dst),
6921       (ins VR128:$src1, i8imm:$src2),
6922       "vaeskeygenassist\t{$src2, $src1, $dst|$dst, $src1, $src2}",
6923       [(set VR128:$dst,
6924         (int_x86_aesni_aeskeygenassist VR128:$src1, imm:$src2))]>,
6925       OpSize, VEX;
6926   def VAESKEYGENASSIST128rm : AESAI<0xDF, MRMSrcMem, (outs VR128:$dst),
6927       (ins i128mem:$src1, i8imm:$src2),
6928       "vaeskeygenassist\t{$src2, $src1, $dst|$dst, $src1, $src2}",
6929       [(set VR128:$dst,
6930         (int_x86_aesni_aeskeygenassist (memopv2i64 addr:$src1), imm:$src2))]>,
6931       OpSize, VEX;
6932 }
6933 def AESKEYGENASSIST128rr : AESAI<0xDF, MRMSrcReg, (outs VR128:$dst),
6934   (ins VR128:$src1, i8imm:$src2),
6935   "aeskeygenassist\t{$src2, $src1, $dst|$dst, $src1, $src2}",
6936   [(set VR128:$dst,
6937     (int_x86_aesni_aeskeygenassist VR128:$src1, imm:$src2))]>,
6938   OpSize;
6939 def AESKEYGENASSIST128rm : AESAI<0xDF, MRMSrcMem, (outs VR128:$dst),
6940   (ins i128mem:$src1, i8imm:$src2),
6941   "aeskeygenassist\t{$src2, $src1, $dst|$dst, $src1, $src2}",
6942   [(set VR128:$dst,
6943     (int_x86_aesni_aeskeygenassist (memopv2i64 addr:$src1), imm:$src2))]>,
6944   OpSize;
6945
6946 //===----------------------------------------------------------------------===//
6947 // CLMUL Instructions
6948 //===----------------------------------------------------------------------===//
6949
6950 // Carry-less Multiplication instructions
6951 let neverHasSideEffects = 1 in {
6952 // AVX carry-less Multiplication instructions
6953 def VPCLMULQDQrr : AVXCLMULIi8<0x44, MRMSrcReg, (outs VR128:$dst),
6954            (ins VR128:$src1, VR128:$src2, i8imm:$src3),
6955            "vpclmulqdq\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
6956            []>;
6957
6958 let mayLoad = 1 in
6959 def VPCLMULQDQrm : AVXCLMULIi8<0x44, MRMSrcMem, (outs VR128:$dst),
6960            (ins VR128:$src1, i128mem:$src2, i8imm:$src3),
6961            "vpclmulqdq\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
6962            []>;
6963
6964 let Constraints = "$src1 = $dst" in {
6965 def PCLMULQDQrr : CLMULIi8<0x44, MRMSrcReg, (outs VR128:$dst),
6966            (ins VR128:$src1, VR128:$src2, i8imm:$src3),
6967            "pclmulqdq\t{$src3, $src2, $dst|$dst, $src2, $src3}",
6968            []>;
6969
6970 let mayLoad = 1 in
6971 def PCLMULQDQrm : CLMULIi8<0x44, MRMSrcMem, (outs VR128:$dst),
6972            (ins VR128:$src1, i128mem:$src2, i8imm:$src3),
6973            "pclmulqdq\t{$src3, $src2, $dst|$dst, $src2, $src3}",
6974            []>;
6975 } // Constraints = "$src1 = $dst"
6976 } // neverHasSideEffects = 1
6977
6978
6979 multiclass pclmul_alias<string asm, int immop> {
6980   def : InstAlias<!strconcat("pclmul", asm, 
6981                            "dq {$src, $dst|$dst, $src}"),
6982                   (PCLMULQDQrr VR128:$dst, VR128:$src, immop)>;
6983
6984   def : InstAlias<!strconcat("pclmul", asm, 
6985                              "dq {$src, $dst|$dst, $src}"),
6986                   (PCLMULQDQrm VR128:$dst, i128mem:$src, immop)>;
6987
6988   def : InstAlias<!strconcat("vpclmul", asm, 
6989                              "dq {$src2, $src1, $dst|$dst, $src1, $src2}"),
6990                   (VPCLMULQDQrr VR128:$dst, VR128:$src1, VR128:$src2, immop)>;
6991
6992   def : InstAlias<!strconcat("vpclmul", asm, 
6993                              "dq {$src2, $src1, $dst|$dst, $src1, $src2}"),
6994                   (VPCLMULQDQrm VR128:$dst, VR128:$src1, i128mem:$src2, immop)>;
6995 }
6996 defm : pclmul_alias<"hqhq", 0x11>;
6997 defm : pclmul_alias<"hqlq", 0x01>;
6998 defm : pclmul_alias<"lqhq", 0x10>;
6999 defm : pclmul_alias<"lqlq", 0x00>;
7000
7001 //===----------------------------------------------------------------------===//
7002 // AVX Instructions
7003 //===----------------------------------------------------------------------===//
7004
7005 //===----------------------------------------------------------------------===//
7006 // VBROADCAST - Load from memory and broadcast to all elements of the
7007 //              destination operand
7008 //
7009 class avx_broadcast<bits<8> opc, string OpcodeStr, RegisterClass RC,
7010                     X86MemOperand x86memop, Intrinsic Int> :
7011   AVX8I<opc, MRMSrcMem, (outs RC:$dst), (ins x86memop:$src),
7012         !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
7013         [(set RC:$dst, (Int addr:$src))]>, VEX;
7014
7015 // AVX2 adds register forms
7016 class avx2_broadcast_reg<bits<8> opc, string OpcodeStr, RegisterClass RC,
7017                          Intrinsic Int> :
7018   AVX28I<opc, MRMSrcReg, (outs RC:$dst), (ins VR128:$src),
7019          !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
7020          [(set RC:$dst, (Int VR128:$src))]>, VEX;
7021
7022 let ExeDomain = SSEPackedSingle in {
7023   def VBROADCASTSSrm  : avx_broadcast<0x18, "vbroadcastss", VR128, f32mem,
7024                                       int_x86_avx_vbroadcast_ss>;
7025   def VBROADCASTSSYrm : avx_broadcast<0x18, "vbroadcastss", VR256, f32mem,
7026                                       int_x86_avx_vbroadcast_ss_256>;
7027 }
7028 let ExeDomain = SSEPackedDouble in
7029 def VBROADCASTSDrm  : avx_broadcast<0x19, "vbroadcastsd", VR256, f64mem,
7030                                     int_x86_avx_vbroadcast_sd_256>;
7031 def VBROADCASTF128 : avx_broadcast<0x1A, "vbroadcastf128", VR256, f128mem,
7032                                    int_x86_avx_vbroadcastf128_pd_256>;
7033
7034 let ExeDomain = SSEPackedSingle in {
7035   def VBROADCASTSSrr  : avx2_broadcast_reg<0x18, "vbroadcastss", VR128,
7036                                            int_x86_avx2_vbroadcast_ss_ps>;
7037   def VBROADCASTSSYrr : avx2_broadcast_reg<0x18, "vbroadcastss", VR256,
7038                                            int_x86_avx2_vbroadcast_ss_ps_256>;
7039 }
7040 let ExeDomain = SSEPackedDouble in
7041 def VBROADCASTSDrr  : avx2_broadcast_reg<0x19, "vbroadcastsd", VR256,
7042                                          int_x86_avx2_vbroadcast_sd_pd_256>;
7043
7044 let Predicates = [HasAVX2] in
7045 def VBROADCASTI128 : avx_broadcast<0x5A, "vbroadcasti128", VR256, i128mem,
7046                                    int_x86_avx2_vbroadcasti128>;
7047
7048 let Predicates = [HasAVX] in
7049 def : Pat<(int_x86_avx_vbroadcastf128_ps_256 addr:$src),
7050           (VBROADCASTF128 addr:$src)>;
7051
7052
7053 //===----------------------------------------------------------------------===//
7054 // VINSERTF128 - Insert packed floating-point values
7055 //
7056 let neverHasSideEffects = 1, ExeDomain = SSEPackedSingle in {
7057 def VINSERTF128rr : AVXAIi8<0x18, MRMSrcReg, (outs VR256:$dst),
7058           (ins VR256:$src1, VR128:$src2, i8imm:$src3),
7059           "vinsertf128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
7060           []>, VEX_4V;
7061 let mayLoad = 1 in
7062 def VINSERTF128rm : AVXAIi8<0x18, MRMSrcMem, (outs VR256:$dst),
7063           (ins VR256:$src1, f128mem:$src2, i8imm:$src3),
7064           "vinsertf128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
7065           []>, VEX_4V;
7066 }
7067
7068 let Predicates = [HasAVX] in {
7069 def : Pat<(int_x86_avx_vinsertf128_pd_256 VR256:$src1, VR128:$src2, imm:$src3),
7070           (VINSERTF128rr VR256:$src1, VR128:$src2, imm:$src3)>;
7071 def : Pat<(int_x86_avx_vinsertf128_ps_256 VR256:$src1, VR128:$src2, imm:$src3),
7072           (VINSERTF128rr VR256:$src1, VR128:$src2, imm:$src3)>;
7073 def : Pat<(int_x86_avx_vinsertf128_si_256 VR256:$src1, VR128:$src2, imm:$src3),
7074           (VINSERTF128rr VR256:$src1, VR128:$src2, imm:$src3)>;
7075 }
7076
7077 //===----------------------------------------------------------------------===//
7078 // VEXTRACTF128 - Extract packed floating-point values
7079 //
7080 let neverHasSideEffects = 1, ExeDomain = SSEPackedSingle in {
7081 def VEXTRACTF128rr : AVXAIi8<0x19, MRMDestReg, (outs VR128:$dst),
7082           (ins VR256:$src1, i8imm:$src2),
7083           "vextractf128\t{$src2, $src1, $dst|$dst, $src1, $src2}",
7084           []>, VEX;
7085 let mayStore = 1 in
7086 def VEXTRACTF128mr : AVXAIi8<0x19, MRMDestMem, (outs),
7087           (ins f128mem:$dst, VR256:$src1, i8imm:$src2),
7088           "vextractf128\t{$src2, $src1, $dst|$dst, $src1, $src2}",
7089           []>, VEX;
7090 }
7091
7092 let Predicates = [HasAVX] in {
7093 def : Pat<(int_x86_avx_vextractf128_pd_256 VR256:$src1, imm:$src2),
7094           (VEXTRACTF128rr VR256:$src1, imm:$src2)>;
7095 def : Pat<(int_x86_avx_vextractf128_ps_256 VR256:$src1, imm:$src2),
7096           (VEXTRACTF128rr VR256:$src1, imm:$src2)>;
7097 def : Pat<(int_x86_avx_vextractf128_si_256 VR256:$src1, imm:$src2),
7098           (VEXTRACTF128rr VR256:$src1, imm:$src2)>;
7099 }
7100
7101 //===----------------------------------------------------------------------===//
7102 // VMASKMOV - Conditional SIMD Packed Loads and Stores
7103 //
7104 multiclass avx_movmask_rm<bits<8> opc_rm, bits<8> opc_mr, string OpcodeStr,
7105                           Intrinsic IntLd, Intrinsic IntLd256,
7106                           Intrinsic IntSt, Intrinsic IntSt256> {
7107   def rm  : AVX8I<opc_rm, MRMSrcMem, (outs VR128:$dst),
7108              (ins VR128:$src1, f128mem:$src2),
7109              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7110              [(set VR128:$dst, (IntLd addr:$src2, VR128:$src1))]>,
7111              VEX_4V;
7112   def Yrm : AVX8I<opc_rm, MRMSrcMem, (outs VR256:$dst),
7113              (ins VR256:$src1, f256mem:$src2),
7114              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7115              [(set VR256:$dst, (IntLd256 addr:$src2, VR256:$src1))]>,
7116              VEX_4V;
7117   def mr  : AVX8I<opc_mr, MRMDestMem, (outs),
7118              (ins f128mem:$dst, VR128:$src1, VR128:$src2),
7119              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7120              [(IntSt addr:$dst, VR128:$src1, VR128:$src2)]>, VEX_4V;
7121   def Ymr : AVX8I<opc_mr, MRMDestMem, (outs),
7122              (ins f256mem:$dst, VR256:$src1, VR256:$src2),
7123              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7124              [(IntSt256 addr:$dst, VR256:$src1, VR256:$src2)]>, VEX_4V;
7125 }
7126
7127 let ExeDomain = SSEPackedSingle in
7128 defm VMASKMOVPS : avx_movmask_rm<0x2C, 0x2E, "vmaskmovps",
7129                                  int_x86_avx_maskload_ps,
7130                                  int_x86_avx_maskload_ps_256,
7131                                  int_x86_avx_maskstore_ps,
7132                                  int_x86_avx_maskstore_ps_256>;
7133 let ExeDomain = SSEPackedDouble in
7134 defm VMASKMOVPD : avx_movmask_rm<0x2D, 0x2F, "vmaskmovpd",
7135                                  int_x86_avx_maskload_pd,
7136                                  int_x86_avx_maskload_pd_256,
7137                                  int_x86_avx_maskstore_pd,
7138                                  int_x86_avx_maskstore_pd_256>;
7139
7140 //===----------------------------------------------------------------------===//
7141 // VPERMIL - Permute Single and Double Floating-Point Values
7142 //
7143 multiclass avx_permil<bits<8> opc_rm, bits<8> opc_rmi, string OpcodeStr,
7144                       RegisterClass RC, X86MemOperand x86memop_f,
7145                       X86MemOperand x86memop_i, PatFrag f_frag, PatFrag i_frag,
7146                       Intrinsic IntVar, Intrinsic IntImm> {
7147   def rr  : AVX8I<opc_rm, MRMSrcReg, (outs RC:$dst),
7148              (ins RC:$src1, RC:$src2),
7149              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7150              [(set RC:$dst, (IntVar RC:$src1, RC:$src2))]>, VEX_4V;
7151   def rm  : AVX8I<opc_rm, MRMSrcMem, (outs RC:$dst),
7152              (ins RC:$src1, x86memop_i:$src2),
7153              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7154              [(set RC:$dst, (IntVar RC:$src1,
7155                              (bitconvert (i_frag addr:$src2))))]>, VEX_4V;
7156
7157   def ri  : AVXAIi8<opc_rmi, MRMSrcReg, (outs RC:$dst),
7158              (ins RC:$src1, i8imm:$src2),
7159              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7160              [(set RC:$dst, (IntImm RC:$src1, imm:$src2))]>, VEX;
7161   def mi  : AVXAIi8<opc_rmi, MRMSrcMem, (outs RC:$dst),
7162              (ins x86memop_f:$src1, i8imm:$src2),
7163              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7164              [(set RC:$dst, (IntImm (f_frag addr:$src1), imm:$src2))]>, VEX;
7165 }
7166
7167 let ExeDomain = SSEPackedSingle in {
7168   defm VPERMILPS  : avx_permil<0x0C, 0x04, "vpermilps", VR128, f128mem, i128mem,
7169                                memopv4f32, memopv2i64,
7170                                int_x86_avx_vpermilvar_ps,
7171                                int_x86_avx_vpermil_ps>;
7172   defm VPERMILPSY : avx_permil<0x0C, 0x04, "vpermilps", VR256, f256mem, i256mem,
7173                                memopv8f32, memopv4i64,
7174                                int_x86_avx_vpermilvar_ps_256,
7175                                int_x86_avx_vpermil_ps_256>;
7176 }
7177 let ExeDomain = SSEPackedDouble in {
7178   defm VPERMILPD  : avx_permil<0x0D, 0x05, "vpermilpd", VR128, f128mem, i128mem,
7179                                memopv2f64, memopv2i64,
7180                                int_x86_avx_vpermilvar_pd,
7181                                int_x86_avx_vpermil_pd>;
7182   defm VPERMILPDY : avx_permil<0x0D, 0x05, "vpermilpd", VR256, f256mem, i256mem,
7183                                memopv4f64, memopv4i64,
7184                                int_x86_avx_vpermilvar_pd_256,
7185                                int_x86_avx_vpermil_pd_256>;
7186 }
7187
7188 let Predicates = [HasAVX] in {
7189 def : Pat<(v8f32 (X86VPermilp VR256:$src1, (i8 imm:$imm))),
7190           (VPERMILPSYri VR256:$src1, imm:$imm)>;
7191 def : Pat<(v4f64 (X86VPermilp VR256:$src1, (i8 imm:$imm))),
7192           (VPERMILPDYri VR256:$src1, imm:$imm)>;
7193 def : Pat<(v8i32 (X86VPermilp VR256:$src1, (i8 imm:$imm))),
7194           (VPERMILPSYri VR256:$src1, imm:$imm)>;
7195 def : Pat<(v4i64 (X86VPermilp VR256:$src1, (i8 imm:$imm))),
7196           (VPERMILPDYri VR256:$src1, imm:$imm)>;
7197 def : Pat<(v8f32 (X86VPermilp (memopv8f32 addr:$src1), (i8 imm:$imm))),
7198           (VPERMILPSYmi addr:$src1, imm:$imm)>;
7199 def : Pat<(v4f64 (X86VPermilp (memopv4f64 addr:$src1), (i8 imm:$imm))),
7200           (VPERMILPDYmi addr:$src1, imm:$imm)>;
7201 def : Pat<(v8i32 (X86VPermilp (bc_v8i32 (memopv4i64 addr:$src1)),
7202                                (i8 imm:$imm))),
7203           (VPERMILPSYmi addr:$src1, imm:$imm)>;
7204 def : Pat<(v4i64 (X86VPermilp (memopv4i64 addr:$src1), (i8 imm:$imm))),
7205           (VPERMILPDYmi addr:$src1, imm:$imm)>;
7206 }
7207
7208 //===----------------------------------------------------------------------===//
7209 // VPERM2F128 - Permute Floating-Point Values in 128-bit chunks
7210 //
7211 let neverHasSideEffects = 1, ExeDomain = SSEPackedSingle in {
7212 def VPERM2F128rr : AVXAIi8<0x06, MRMSrcReg, (outs VR256:$dst),
7213           (ins VR256:$src1, VR256:$src2, i8imm:$src3),
7214           "vperm2f128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
7215           []>, VEX_4V;
7216 let mayLoad = 1 in
7217 def VPERM2F128rm : AVXAIi8<0x06, MRMSrcMem, (outs VR256:$dst),
7218           (ins VR256:$src1, f256mem:$src2, i8imm:$src3),
7219           "vperm2f128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
7220           []>, VEX_4V;
7221 }
7222
7223 let Predicates = [HasAVX] in {
7224 def : Pat<(int_x86_avx_vperm2f128_ps_256 VR256:$src1, VR256:$src2, imm:$src3),
7225           (VPERM2F128rr VR256:$src1, VR256:$src2, imm:$src3)>;
7226 def : Pat<(int_x86_avx_vperm2f128_pd_256 VR256:$src1, VR256:$src2, imm:$src3),
7227           (VPERM2F128rr VR256:$src1, VR256:$src2, imm:$src3)>;
7228 def : Pat<(int_x86_avx_vperm2f128_si_256 VR256:$src1, VR256:$src2, imm:$src3),
7229           (VPERM2F128rr VR256:$src1, VR256:$src2, imm:$src3)>;
7230
7231 def : Pat<(int_x86_avx_vperm2f128_ps_256
7232                   VR256:$src1, (memopv8f32 addr:$src2), imm:$src3),
7233           (VPERM2F128rm VR256:$src1, addr:$src2, imm:$src3)>;
7234 def : Pat<(int_x86_avx_vperm2f128_pd_256
7235                   VR256:$src1, (memopv4f64 addr:$src2), imm:$src3),
7236           (VPERM2F128rm VR256:$src1, addr:$src2, imm:$src3)>;
7237 def : Pat<(int_x86_avx_vperm2f128_si_256
7238                   VR256:$src1, (bc_v8i32 (memopv4i64 addr:$src2)), imm:$src3),
7239           (VPERM2F128rm VR256:$src1, addr:$src2, imm:$src3)>;
7240 }
7241
7242 //===----------------------------------------------------------------------===//
7243 // VZERO - Zero YMM registers
7244 //
7245 let Defs = [YMM0, YMM1, YMM2, YMM3, YMM4, YMM5, YMM6, YMM7,
7246             YMM8, YMM9, YMM10, YMM11, YMM12, YMM13, YMM14, YMM15] in {
7247   // Zero All YMM registers
7248   def VZEROALL : I<0x77, RawFrm, (outs), (ins), "vzeroall",
7249                   [(int_x86_avx_vzeroall)]>, TB, VEX, VEX_L, Requires<[HasAVX]>;
7250
7251   // Zero Upper bits of YMM registers
7252   def VZEROUPPER : I<0x77, RawFrm, (outs), (ins), "vzeroupper",
7253                      [(int_x86_avx_vzeroupper)]>, TB, VEX, Requires<[HasAVX]>;
7254 }
7255
7256 //===----------------------------------------------------------------------===//
7257 // Half precision conversion instructions
7258 //===----------------------------------------------------------------------===//
7259 multiclass f16c_ph2ps<RegisterClass RC, X86MemOperand x86memop, Intrinsic Int> {
7260 let Predicates = [HasAVX, HasF16C] in {
7261   def rr : I<0x13, MRMSrcReg, (outs RC:$dst), (ins VR128:$src),
7262              "vcvtph2ps\t{$src, $dst|$dst, $src}",
7263              [(set RC:$dst, (Int VR128:$src))]>,
7264              T8, OpSize, VEX;
7265   let neverHasSideEffects = 1, mayLoad = 1 in
7266   def rm : I<0x13, MRMSrcMem, (outs RC:$dst), (ins x86memop:$src),
7267              "vcvtph2ps\t{$src, $dst|$dst, $src}", []>, T8, OpSize, VEX;
7268 }
7269 }
7270
7271 multiclass f16c_ps2ph<RegisterClass RC, X86MemOperand x86memop, Intrinsic Int> {
7272 let Predicates = [HasAVX, HasF16C] in {
7273   def rr : Ii8<0x1D, MRMDestReg, (outs VR128:$dst),
7274                (ins RC:$src1, i32i8imm:$src2),
7275                "vcvtps2ph\t{$src2, $src1, $dst|$dst, $src1, $src2}",
7276                [(set VR128:$dst, (Int RC:$src1, imm:$src2))]>,
7277                TA, OpSize, VEX;
7278   let neverHasSideEffects = 1, mayLoad = 1 in
7279   def mr : Ii8<0x1D, MRMDestMem, (outs x86memop:$dst),
7280                (ins RC:$src1, i32i8imm:$src2),
7281                "vcvtps2ph\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>,
7282                TA, OpSize, VEX;
7283 }
7284 }
7285
7286 defm VCVTPH2PS  : f16c_ph2ps<VR128, f64mem, int_x86_vcvtph2ps_128>;
7287 defm VCVTPH2PSY : f16c_ph2ps<VR256, f128mem, int_x86_vcvtph2ps_256>;
7288 defm VCVTPS2PH  : f16c_ps2ph<VR128, f64mem, int_x86_vcvtps2ph_128>;
7289 defm VCVTPS2PHY : f16c_ps2ph<VR256, f128mem, int_x86_vcvtps2ph_256>;
7290
7291 //===----------------------------------------------------------------------===//
7292 // AVX2 Instructions
7293 //===----------------------------------------------------------------------===//
7294
7295 /// AVX2_binop_rmi_int - AVX2 binary operator with 8-bit immediate
7296 multiclass AVX2_binop_rmi_int<bits<8> opc, string OpcodeStr,
7297                  Intrinsic IntId, RegisterClass RC, PatFrag memop_frag,
7298                  X86MemOperand x86memop> {
7299   let isCommutable = 1 in
7300   def rri : AVX2AIi8<opc, MRMSrcReg, (outs RC:$dst),
7301         (ins RC:$src1, RC:$src2, u32u8imm:$src3),
7302         !strconcat(OpcodeStr,
7303             "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
7304         [(set RC:$dst, (IntId RC:$src1, RC:$src2, imm:$src3))]>,
7305         VEX_4V;
7306   def rmi : AVX2AIi8<opc, MRMSrcMem, (outs RC:$dst),
7307         (ins RC:$src1, x86memop:$src2, u32u8imm:$src3),
7308         !strconcat(OpcodeStr,
7309             "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
7310         [(set RC:$dst,
7311           (IntId RC:$src1,
7312            (bitconvert (memop_frag addr:$src2)), imm:$src3))]>,
7313         VEX_4V;
7314 }
7315
7316 let isCommutable = 0 in {
7317 defm VPBLENDD : AVX2_binop_rmi_int<0x02, "vpblendd", int_x86_avx2_pblendd_128,
7318                                    VR128, memopv2i64, i128mem>;
7319 defm VPBLENDDY : AVX2_binop_rmi_int<0x02, "vpblendd", int_x86_avx2_pblendd_256,
7320                                     VR256, memopv4i64, i256mem>;
7321 }
7322
7323 //===----------------------------------------------------------------------===//
7324 // VPBROADCAST - Load from memory and broadcast to all elements of the
7325 //               destination operand
7326 //
7327 multiclass avx2_broadcast<bits<8> opc, string OpcodeStr,
7328                           X86MemOperand x86memop, PatFrag ld_frag,
7329                           Intrinsic Int128, Intrinsic Int256> {
7330   def rr : AVX28I<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
7331                   !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
7332                   [(set VR128:$dst, (Int128 VR128:$src))]>, VEX;
7333   def rm : AVX28I<opc, MRMSrcMem, (outs VR128:$dst), (ins x86memop:$src),
7334                   !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
7335                   [(set VR128:$dst,
7336                     (Int128 (scalar_to_vector (ld_frag addr:$src))))]>, VEX;
7337   def Yrr : AVX28I<opc, MRMSrcReg, (outs VR256:$dst), (ins VR128:$src),
7338                    !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
7339                    [(set VR256:$dst, (Int256 VR128:$src))]>, VEX;
7340   def Yrm : AVX28I<opc, MRMSrcMem, (outs VR256:$dst), (ins x86memop:$src),
7341                    !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
7342                    [(set VR256:$dst,
7343                     (Int256 (scalar_to_vector (ld_frag addr:$src))))]>, VEX;
7344 }
7345
7346 defm VPBROADCASTB  : avx2_broadcast<0x78, "vpbroadcastb", i8mem, loadi8,
7347                                     int_x86_avx2_pbroadcastb_128,
7348                                     int_x86_avx2_pbroadcastb_256>;
7349 defm VPBROADCASTW  : avx2_broadcast<0x79, "vpbroadcastw", i16mem, loadi16,
7350                                     int_x86_avx2_pbroadcastw_128,
7351                                     int_x86_avx2_pbroadcastw_256>;
7352 defm VPBROADCASTD  : avx2_broadcast<0x58, "vpbroadcastd", i32mem, loadi32,
7353                                     int_x86_avx2_pbroadcastd_128,
7354                                     int_x86_avx2_pbroadcastd_256>;
7355 defm VPBROADCASTQ  : avx2_broadcast<0x59, "vpbroadcastq", i64mem, loadi64,
7356                                     int_x86_avx2_pbroadcastq_128,
7357                                     int_x86_avx2_pbroadcastq_256>;
7358
7359 let Predicates = [HasAVX2] in {
7360   def : Pat<(v16i8 (X86VBroadcast (loadi8 addr:$src))),
7361           (VPBROADCASTBrm addr:$src)>;
7362   def : Pat<(v32i8 (X86VBroadcast (loadi8 addr:$src))),
7363           (VPBROADCASTBYrm addr:$src)>;
7364   def : Pat<(v8i16 (X86VBroadcast (loadi16 addr:$src))),
7365           (VPBROADCASTWrm addr:$src)>;
7366   def : Pat<(v16i16 (X86VBroadcast (loadi16 addr:$src))),
7367           (VPBROADCASTWYrm addr:$src)>;
7368   def : Pat<(v4i32 (X86VBroadcast (loadi32 addr:$src))),
7369           (VPBROADCASTDrm addr:$src)>;
7370   def : Pat<(v8i32 (X86VBroadcast (loadi32 addr:$src))),
7371           (VPBROADCASTDYrm addr:$src)>;
7372   def : Pat<(v2i64 (X86VBroadcast (loadi64 addr:$src))),
7373           (VPBROADCASTQrm addr:$src)>;
7374   def : Pat<(v4i64 (X86VBroadcast (loadi64 addr:$src))),
7375           (VPBROADCASTQYrm addr:$src)>;
7376 }
7377
7378 // AVX1 broadcast patterns
7379 let Predicates = [HasAVX] in {
7380 def : Pat<(v8i32 (X86VBroadcast (loadi32 addr:$src))),
7381           (VBROADCASTSSYrm addr:$src)>;
7382 def : Pat<(v4i64 (X86VBroadcast (loadi64 addr:$src))),
7383           (VBROADCASTSDrm addr:$src)>;
7384 def : Pat<(v8f32 (X86VBroadcast (loadf32 addr:$src))),
7385           (VBROADCASTSSYrm addr:$src)>;
7386 def : Pat<(v4f64 (X86VBroadcast (loadf64 addr:$src))),
7387           (VBROADCASTSDrm addr:$src)>;
7388
7389 def : Pat<(v4f32 (X86VBroadcast (loadf32 addr:$src))),
7390           (VBROADCASTSSrm addr:$src)>;
7391 def : Pat<(v4i32 (X86VBroadcast (loadi32 addr:$src))),
7392           (VBROADCASTSSrm addr:$src)>;
7393 }
7394
7395 //===----------------------------------------------------------------------===//
7396 // VPERM - Permute instructions
7397 //
7398
7399 multiclass avx2_perm<bits<8> opc, string OpcodeStr, PatFrag mem_frag,
7400                      Intrinsic Int> {
7401   def Yrr : AVX28I<opc, MRMSrcReg, (outs VR256:$dst),
7402                    (ins VR256:$src1, VR256:$src2),
7403                    !strconcat(OpcodeStr,
7404                        "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7405                    [(set VR256:$dst, (Int VR256:$src1, VR256:$src2))]>, VEX_4V;
7406   def Yrm : AVX28I<opc, MRMSrcMem, (outs VR256:$dst),
7407                    (ins VR256:$src1, i256mem:$src2),
7408                    !strconcat(OpcodeStr,
7409                        "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7410                    [(set VR256:$dst, (Int VR256:$src1,
7411                                       (bitconvert (mem_frag addr:$src2))))]>,
7412                    VEX_4V;
7413 }
7414
7415 defm VPERMD : avx2_perm<0x36, "vpermd", memopv4i64, int_x86_avx2_permd>;
7416 let ExeDomain = SSEPackedSingle in
7417 defm VPERMPS : avx2_perm<0x16, "vpermps", memopv8f32, int_x86_avx2_permps>;
7418
7419 multiclass avx2_perm_imm<bits<8> opc, string OpcodeStr, PatFrag mem_frag,
7420                          Intrinsic Int> {
7421   def Yrr : AVX2AIi8<opc, MRMSrcReg, (outs VR256:$dst),
7422                      (ins VR256:$src1, i8imm:$src2),
7423                      !strconcat(OpcodeStr,
7424                          "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7425                      [(set VR256:$dst, (Int VR256:$src1, imm:$src2))]>, VEX;
7426   def Yrm : AVX2AIi8<opc, MRMSrcMem, (outs VR256:$dst),
7427                      (ins i256mem:$src1, i8imm:$src2),
7428                      !strconcat(OpcodeStr,
7429                          "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7430                      [(set VR256:$dst, (Int (mem_frag addr:$src1), imm:$src2))]>,
7431                      VEX;
7432 }
7433
7434 defm VPERMQ : avx2_perm_imm<0x00, "vpermq", memopv4i64, int_x86_avx2_permq>,
7435                             VEX_W;
7436 let ExeDomain = SSEPackedDouble in
7437 defm VPERMPD : avx2_perm_imm<0x01, "vpermpd", memopv4f64, int_x86_avx2_permpd>,
7438                              VEX_W;
7439
7440 //===----------------------------------------------------------------------===//
7441 // VPERM2I128 - Permute Floating-Point Values in 128-bit chunks
7442 //
7443 def VPERM2I128rr : AVX2AIi8<0x46, MRMSrcReg, (outs VR256:$dst),
7444           (ins VR256:$src1, VR256:$src2, i8imm:$src3),
7445           "vperm2i128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
7446           [(set VR256:$dst,
7447            (int_x86_avx2_vperm2i128 VR256:$src1, VR256:$src2, imm:$src3))]>,
7448           VEX_4V;
7449 def VPERM2I128rm : AVX2AIi8<0x46, MRMSrcMem, (outs VR256:$dst),
7450           (ins VR256:$src1, f256mem:$src2, i8imm:$src3),
7451           "vperm2i128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
7452           [(set VR256:$dst,
7453            (int_x86_avx2_vperm2i128 VR256:$src1, (memopv4i64 addr:$src2),
7454             imm:$src3))]>,
7455           VEX_4V;
7456
7457 let Predicates = [HasAVX2] in {
7458 def : Pat<(v8i32 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
7459           (VPERM2I128rr VR256:$src1, VR256:$src2, imm:$imm)>;
7460 def : Pat<(v4i64 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
7461           (VPERM2I128rr VR256:$src1, VR256:$src2, imm:$imm)>;
7462 def : Pat<(v32i8 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
7463           (VPERM2I128rr VR256:$src1, VR256:$src2, imm:$imm)>;
7464 def : Pat<(v16i16 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
7465           (VPERM2I128rr VR256:$src1, VR256:$src2, imm:$imm)>;
7466
7467 def : Pat<(v32i8 (X86VPerm2x128 VR256:$src1, (bc_v32i8 (memopv4i64 addr:$src2)),
7468                   (i8 imm:$imm))),
7469           (VPERM2I128rm VR256:$src1, addr:$src2, imm:$imm)>;
7470 def : Pat<(v16i16 (X86VPerm2x128 VR256:$src1,
7471                    (bc_v16i16 (memopv4i64 addr:$src2)), (i8 imm:$imm))),
7472           (VPERM2I128rm VR256:$src1, addr:$src2, imm:$imm)>;
7473 def : Pat<(v8i32 (X86VPerm2x128 VR256:$src1, (bc_v8i32 (memopv4i64 addr:$src2)),
7474                   (i8 imm:$imm))),
7475           (VPERM2I128rm VR256:$src1, addr:$src2, imm:$imm)>;
7476 def : Pat<(v4i64 (X86VPerm2x128 VR256:$src1, (memopv4i64 addr:$src2),
7477                   (i8 imm:$imm))),
7478           (VPERM2I128rm VR256:$src1, addr:$src2, imm:$imm)>;
7479 }
7480
7481 // AVX1 patterns
7482 let Predicates = [HasAVX] in {
7483 def : Pat<(v8f32 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
7484           (VPERM2F128rr VR256:$src1, VR256:$src2, imm:$imm)>;
7485 def : Pat<(v8i32 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
7486           (VPERM2F128rr VR256:$src1, VR256:$src2, imm:$imm)>;
7487 def : Pat<(v4i64 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
7488           (VPERM2F128rr VR256:$src1, VR256:$src2, imm:$imm)>;
7489 def : Pat<(v4f64 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
7490           (VPERM2F128rr VR256:$src1, VR256:$src2, imm:$imm)>;
7491 def : Pat<(v32i8 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
7492           (VPERM2F128rr VR256:$src1, VR256:$src2, imm:$imm)>;
7493 def : Pat<(v16i16 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
7494           (VPERM2F128rr VR256:$src1, VR256:$src2, imm:$imm)>;
7495
7496 def : Pat<(v8f32 (X86VPerm2x128 VR256:$src1,
7497                   (memopv8f32 addr:$src2), (i8 imm:$imm))),
7498           (VPERM2F128rm VR256:$src1, addr:$src2, imm:$imm)>;
7499 def : Pat<(v8i32 (X86VPerm2x128 VR256:$src1,
7500                   (bc_v8i32 (memopv4i64 addr:$src2)), (i8 imm:$imm))),
7501           (VPERM2F128rm VR256:$src1, addr:$src2, imm:$imm)>;
7502 def : Pat<(v4i64 (X86VPerm2x128 VR256:$src1,
7503                   (memopv4i64 addr:$src2), (i8 imm:$imm))),
7504           (VPERM2F128rm VR256:$src1, addr:$src2, imm:$imm)>;
7505 def : Pat<(v4f64 (X86VPerm2x128 VR256:$src1,
7506                   (memopv4f64 addr:$src2), (i8 imm:$imm))),
7507           (VPERM2F128rm VR256:$src1, addr:$src2, imm:$imm)>;
7508 def : Pat<(v32i8 (X86VPerm2x128 VR256:$src1,
7509                   (bc_v32i8 (memopv4i64 addr:$src2)), (i8 imm:$imm))),
7510           (VPERM2F128rm VR256:$src1, addr:$src2, imm:$imm)>;
7511 def : Pat<(v16i16 (X86VPerm2x128 VR256:$src1,
7512                   (bc_v16i16 (memopv4i64 addr:$src2)), (i8 imm:$imm))),
7513           (VPERM2F128rm VR256:$src1, addr:$src2, imm:$imm)>;
7514 }
7515
7516
7517 //===----------------------------------------------------------------------===//
7518 // VINSERTI128 - Insert packed integer values
7519 //
7520 def VINSERTI128rr : AVX2AIi8<0x38, MRMSrcReg, (outs VR256:$dst),
7521           (ins VR256:$src1, VR128:$src2, i8imm:$src3),
7522           "vinserti128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
7523           [(set VR256:$dst,
7524             (int_x86_avx2_vinserti128 VR256:$src1, VR128:$src2, imm:$src3))]>,
7525           VEX_4V;
7526 def VINSERTI128rm : AVX2AIi8<0x38, MRMSrcMem, (outs VR256:$dst),
7527           (ins VR256:$src1, i128mem:$src2, i8imm:$src3),
7528           "vinserti128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
7529           [(set VR256:$dst,
7530             (int_x86_avx2_vinserti128 VR256:$src1, (memopv2i64 addr:$src2),
7531              imm:$src3))]>, VEX_4V;
7532
7533 let Predicates = [HasAVX2] in {
7534 def : Pat<(vinsertf128_insert:$ins (v4i64 VR256:$src1), (v2i64 VR128:$src2),
7535                                    (i32 imm)),
7536           (VINSERTI128rr VR256:$src1, VR128:$src2,
7537                          (INSERT_get_vinsertf128_imm VR256:$ins))>;
7538 def : Pat<(vinsertf128_insert:$ins (v8i32 VR256:$src1), (v4i32 VR128:$src2),
7539                                    (i32 imm)),
7540           (VINSERTI128rr VR256:$src1, VR128:$src2,
7541                          (INSERT_get_vinsertf128_imm VR256:$ins))>;
7542 def : Pat<(vinsertf128_insert:$ins (v32i8 VR256:$src1), (v16i8 VR128:$src2),
7543                                    (i32 imm)),
7544           (VINSERTI128rr VR256:$src1, VR128:$src2,
7545                          (INSERT_get_vinsertf128_imm VR256:$ins))>;
7546 def : Pat<(vinsertf128_insert:$ins (v16i16 VR256:$src1), (v8i16 VR128:$src2),
7547                                    (i32 imm)),
7548           (VINSERTI128rr VR256:$src1, VR128:$src2,
7549                          (INSERT_get_vinsertf128_imm VR256:$ins))>;
7550 }
7551
7552 // AVX1 patterns
7553 let Predicates = [HasAVX] in {
7554 def : Pat<(vinsertf128_insert:$ins (v8f32 VR256:$src1), (v4f32 VR128:$src2),
7555                                    (i32 imm)),
7556           (VINSERTF128rr VR256:$src1, VR128:$src2,
7557                          (INSERT_get_vinsertf128_imm VR256:$ins))>;
7558 def : Pat<(vinsertf128_insert:$ins (v4f64 VR256:$src1), (v2f64 VR128:$src2),
7559                                    (i32 imm)),
7560           (VINSERTF128rr VR256:$src1, VR128:$src2,
7561                          (INSERT_get_vinsertf128_imm VR256:$ins))>;
7562 def : Pat<(vinsertf128_insert:$ins (v4i64 VR256:$src1), (v2i64 VR128:$src2),
7563                                    (i32 imm)),
7564           (VINSERTF128rr VR256:$src1, VR128:$src2,
7565                          (INSERT_get_vinsertf128_imm VR256:$ins))>;
7566 def : Pat<(vinsertf128_insert:$ins (v8i32 VR256:$src1), (v4i32 VR128:$src2),
7567                                    (i32 imm)),
7568           (VINSERTF128rr VR256:$src1, VR128:$src2,
7569                          (INSERT_get_vinsertf128_imm VR256:$ins))>;
7570 def : Pat<(vinsertf128_insert:$ins (v32i8 VR256:$src1), (v16i8 VR128:$src2),
7571                                    (i32 imm)),
7572           (VINSERTF128rr VR256:$src1, VR128:$src2,
7573                          (INSERT_get_vinsertf128_imm VR256:$ins))>;
7574 def : Pat<(vinsertf128_insert:$ins (v16i16 VR256:$src1), (v8i16 VR128:$src2),
7575                                    (i32 imm)),
7576           (VINSERTF128rr VR256:$src1, VR128:$src2,
7577                          (INSERT_get_vinsertf128_imm VR256:$ins))>;
7578 }
7579
7580 //===----------------------------------------------------------------------===//
7581 // VEXTRACTI128 - Extract packed integer values
7582 //
7583 def VEXTRACTI128rr : AVX2AIi8<0x39, MRMDestReg, (outs VR128:$dst),
7584           (ins VR256:$src1, i8imm:$src2),
7585           "vextracti128\t{$src2, $src1, $dst|$dst, $src1, $src2}",
7586           [(set VR128:$dst,
7587             (int_x86_avx2_vextracti128 VR256:$src1, imm:$src2))]>,
7588           VEX;
7589 let neverHasSideEffects = 1, mayStore = 1 in
7590 def VEXTRACTI128mr : AVX2AIi8<0x39, MRMDestMem, (outs),
7591           (ins i128mem:$dst, VR256:$src1, i8imm:$src2),
7592           "vextracti128\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>, VEX;
7593
7594 let Predicates = [HasAVX2] in {
7595 def : Pat<(vextractf128_extract:$ext VR256:$src1, (i32 imm)),
7596           (v2i64 (VEXTRACTI128rr
7597                     (v4i64 VR256:$src1),
7598                     (EXTRACT_get_vextractf128_imm VR128:$ext)))>;
7599 def : Pat<(vextractf128_extract:$ext VR256:$src1, (i32 imm)),
7600           (v4i32 (VEXTRACTI128rr
7601                     (v8i32 VR256:$src1),
7602                     (EXTRACT_get_vextractf128_imm VR128:$ext)))>;
7603 def : Pat<(vextractf128_extract:$ext VR256:$src1, (i32 imm)),
7604           (v8i16 (VEXTRACTI128rr
7605                     (v16i16 VR256:$src1),
7606                     (EXTRACT_get_vextractf128_imm VR128:$ext)))>;
7607 def : Pat<(vextractf128_extract:$ext VR256:$src1, (i32 imm)),
7608           (v16i8 (VEXTRACTI128rr
7609                     (v32i8 VR256:$src1),
7610                     (EXTRACT_get_vextractf128_imm VR128:$ext)))>;
7611 }
7612
7613 // AVX1 patterns
7614 let Predicates = [HasAVX] in {
7615 def : Pat<(vextractf128_extract:$ext VR256:$src1, (i32 imm)),
7616           (v4f32 (VEXTRACTF128rr
7617                     (v8f32 VR256:$src1),
7618                     (EXTRACT_get_vextractf128_imm VR128:$ext)))>;
7619 def : Pat<(vextractf128_extract:$ext VR256:$src1, (i32 imm)),
7620           (v2f64 (VEXTRACTF128rr
7621                     (v4f64 VR256:$src1),
7622                     (EXTRACT_get_vextractf128_imm VR128:$ext)))>;
7623 def : Pat<(vextractf128_extract:$ext VR256:$src1, (i32 imm)),
7624           (v2i64 (VEXTRACTF128rr
7625                     (v4i64 VR256:$src1),
7626                     (EXTRACT_get_vextractf128_imm VR128:$ext)))>;
7627 def : Pat<(vextractf128_extract:$ext VR256:$src1, (i32 imm)),
7628           (v4i32 (VEXTRACTF128rr
7629                     (v8i32 VR256:$src1),
7630                     (EXTRACT_get_vextractf128_imm VR128:$ext)))>;
7631 def : Pat<(vextractf128_extract:$ext VR256:$src1, (i32 imm)),
7632           (v8i16 (VEXTRACTF128rr
7633                     (v16i16 VR256:$src1),
7634                     (EXTRACT_get_vextractf128_imm VR128:$ext)))>;
7635 def : Pat<(vextractf128_extract:$ext VR256:$src1, (i32 imm)),
7636           (v16i8 (VEXTRACTF128rr
7637                     (v32i8 VR256:$src1),
7638                     (EXTRACT_get_vextractf128_imm VR128:$ext)))>;
7639 }
7640
7641 //===----------------------------------------------------------------------===//
7642 // VPMASKMOV - Conditional SIMD Integer Packed Loads and Stores
7643 //
7644 multiclass avx2_pmovmask<string OpcodeStr,
7645                          Intrinsic IntLd128, Intrinsic IntLd256,
7646                          Intrinsic IntSt128, Intrinsic IntSt256> {
7647   def rm  : AVX28I<0x8c, MRMSrcMem, (outs VR128:$dst),
7648              (ins VR128:$src1, i128mem:$src2),
7649              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7650              [(set VR128:$dst, (IntLd128 addr:$src2, VR128:$src1))]>, VEX_4V;
7651   def Yrm : AVX28I<0x8c, MRMSrcMem, (outs VR256:$dst),
7652              (ins VR256:$src1, i256mem:$src2),
7653              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7654              [(set VR256:$dst, (IntLd256 addr:$src2, VR256:$src1))]>, VEX_4V;
7655   def mr  : AVX28I<0x8e, MRMDestMem, (outs),
7656              (ins i128mem:$dst, VR128:$src1, VR128:$src2),
7657              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7658              [(IntSt128 addr:$dst, VR128:$src1, VR128:$src2)]>, VEX_4V;
7659   def Ymr : AVX28I<0x8e, MRMDestMem, (outs),
7660              (ins i256mem:$dst, VR256:$src1, VR256:$src2),
7661              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7662              [(IntSt256 addr:$dst, VR256:$src1, VR256:$src2)]>, VEX_4V;
7663 }
7664
7665 defm VPMASKMOVD : avx2_pmovmask<"vpmaskmovd",
7666                                 int_x86_avx2_maskload_d,
7667                                 int_x86_avx2_maskload_d_256,
7668                                 int_x86_avx2_maskstore_d,
7669                                 int_x86_avx2_maskstore_d_256>;
7670 defm VPMASKMOVQ : avx2_pmovmask<"vpmaskmovq",
7671                                 int_x86_avx2_maskload_q,
7672                                 int_x86_avx2_maskload_q_256,
7673                                 int_x86_avx2_maskstore_q,
7674                                 int_x86_avx2_maskstore_q_256>, VEX_W;
7675
7676
7677 //===----------------------------------------------------------------------===//
7678 // Variable Bit Shifts
7679 //
7680 multiclass avx2_var_shift<bits<8> opc, string OpcodeStr, SDNode OpNode,
7681                           ValueType vt128, ValueType vt256> {
7682   def rr  : AVX28I<opc, MRMSrcReg, (outs VR128:$dst),
7683              (ins VR128:$src1, VR128:$src2),
7684              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7685              [(set VR128:$dst,
7686                (vt128 (OpNode VR128:$src1, (vt128 VR128:$src2))))]>,
7687              VEX_4V;
7688   def rm  : AVX28I<opc, MRMSrcMem, (outs VR128:$dst),
7689              (ins VR128:$src1, i128mem:$src2),
7690              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7691              [(set VR128:$dst,
7692                (vt128 (OpNode VR128:$src1,
7693                        (vt128 (bitconvert (memopv2i64 addr:$src2))))))]>,
7694              VEX_4V;
7695   def Yrr : AVX28I<opc, MRMSrcReg, (outs VR256:$dst),
7696              (ins VR256:$src1, VR256:$src2),
7697              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7698              [(set VR256:$dst,
7699                (vt256 (OpNode VR256:$src1, (vt256 VR256:$src2))))]>,
7700              VEX_4V;
7701   def Yrm : AVX28I<opc, MRMSrcMem, (outs VR256:$dst),
7702              (ins VR256:$src1, i256mem:$src2),
7703              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7704              [(set VR256:$dst,
7705                (vt256 (OpNode VR256:$src1,
7706                        (vt256 (bitconvert (memopv4i64 addr:$src2))))))]>,
7707              VEX_4V;
7708 }
7709
7710 defm VPSLLVD : avx2_var_shift<0x47, "vpsllvd", shl, v4i32, v8i32>;
7711 defm VPSLLVQ : avx2_var_shift<0x47, "vpsllvq", shl, v2i64, v4i64>, VEX_W;
7712 defm VPSRLVD : avx2_var_shift<0x45, "vpsrlvd", srl, v4i32, v8i32>;
7713 defm VPSRLVQ : avx2_var_shift<0x45, "vpsrlvq", srl, v2i64, v4i64>, VEX_W;
7714 defm VPSRAVD : avx2_var_shift<0x46, "vpsravd", sra, v4i32, v8i32>;