Custom lower phadd and phsub intrinsics to target specific nodes. Remove the patterns...
[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 - Simple SSSE3 bin op
5083 multiclass SS3I_binop_rm<bits<8> opc, string OpcodeStr, SDNode OpNode,
5084                          ValueType OpVT, RegisterClass RC, PatFrag memop_frag,
5085                          X86MemOperand x86memop, bit Is2Addr = 1> {
5086   let isCommutable = 1 in
5087   def rr : SS38I<opc, MRMSrcReg, (outs RC:$dst),
5088        (ins RC:$src1, RC:$src2),
5089        !if(Is2Addr,
5090          !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5091          !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5092        [(set RC:$dst, (OpVT (OpNode RC:$src1, RC:$src2)))]>,
5093        OpSize;
5094   def rm : SS38I<opc, MRMSrcMem, (outs RC:$dst),
5095        (ins RC:$src1, x86memop:$src2),
5096        !if(Is2Addr,
5097          !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5098          !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5099        [(set RC:$dst,
5100          (OpVT (OpNode RC:$src1,
5101           (bitconvert (memop_frag addr:$src2)))))]>, OpSize;
5102 }
5103
5104 /// SS3I_binop_rm_int - Simple SSSE3 bin op whose type can be v*{i8,i16,i32}.
5105 multiclass SS3I_binop_rm_int<bits<8> opc, string OpcodeStr,
5106                              Intrinsic IntId128, bit Is2Addr = 1> {
5107   let isCommutable = 1 in
5108   def rr128 : SS38I<opc, MRMSrcReg, (outs VR128:$dst),
5109        (ins VR128:$src1, VR128:$src2),
5110        !if(Is2Addr,
5111          !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5112          !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5113        [(set VR128:$dst, (IntId128 VR128:$src1, VR128:$src2))]>,
5114        OpSize;
5115   def rm128 : SS38I<opc, MRMSrcMem, (outs VR128:$dst),
5116        (ins VR128:$src1, i128mem:$src2),
5117        !if(Is2Addr,
5118          !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5119          !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5120        [(set VR128:$dst,
5121          (IntId128 VR128:$src1,
5122           (bitconvert (memopv2i64 addr:$src2))))]>, OpSize;
5123 }
5124
5125 multiclass SS3I_binop_rm_int_y<bits<8> opc, string OpcodeStr,
5126                                Intrinsic IntId256> {
5127   let isCommutable = 1 in
5128   def rr256 : SS38I<opc, MRMSrcReg, (outs VR256:$dst),
5129        (ins VR256:$src1, VR256:$src2),
5130        !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5131        [(set VR256:$dst, (IntId256 VR256:$src1, VR256:$src2))]>,
5132        OpSize;
5133   def rm256 : SS38I<opc, MRMSrcMem, (outs VR256:$dst),
5134        (ins VR256:$src1, i256mem:$src2),
5135        !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5136        [(set VR256:$dst,
5137          (IntId256 VR256:$src1,
5138           (bitconvert (memopv4i64 addr:$src2))))]>, OpSize;
5139 }
5140
5141 let ImmT = NoImm, Predicates = [HasAVX] in {
5142 let isCommutable = 0 in {
5143   defm VPHADDW    : SS3I_binop_rm<0x01, "vphaddw", X86hadd, v8i16, VR128,
5144                                   memopv2i64, i128mem, 0>, VEX_4V;
5145   defm VPHADDD    : SS3I_binop_rm<0x02, "vphaddd", X86hadd, v4i32, VR128,
5146                                   memopv2i64, i128mem, 0>, VEX_4V;
5147   defm VPHSUBW    : SS3I_binop_rm<0x05, "vphsubw", X86hsub, v8i16, VR128,
5148                                   memopv2i64, i128mem, 0>, VEX_4V;
5149   defm VPHSUBD    : SS3I_binop_rm<0x06, "vphsubd", X86hsub, v4i32, VR128,
5150                                   memopv2i64, i128mem, 0>, VEX_4V;
5151   defm VPHADDSW   : SS3I_binop_rm_int<0x03, "vphaddsw",
5152                                       int_x86_ssse3_phadd_sw_128, 0>, VEX_4V;
5153   defm VPHSUBSW   : SS3I_binop_rm_int<0x07, "vphsubsw",
5154                                       int_x86_ssse3_phsub_sw_128, 0>, VEX_4V;
5155   defm VPMADDUBSW : SS3I_binop_rm_int<0x04, "vpmaddubsw",
5156                                       int_x86_ssse3_pmadd_ub_sw_128, 0>, VEX_4V;
5157   defm VPSHUFB    : SS3I_binop_rm_int<0x00, "vpshufb",
5158                                       int_x86_ssse3_pshuf_b_128, 0>, VEX_4V;
5159   defm VPSIGNB    : SS3I_binop_rm_int<0x08, "vpsignb",
5160                                       int_x86_ssse3_psign_b_128, 0>, VEX_4V;
5161   defm VPSIGNW    : SS3I_binop_rm_int<0x09, "vpsignw",
5162                                       int_x86_ssse3_psign_w_128, 0>, VEX_4V;
5163   defm VPSIGND    : SS3I_binop_rm_int<0x0A, "vpsignd",
5164                                       int_x86_ssse3_psign_d_128, 0>, VEX_4V;
5165 }
5166 defm VPMULHRSW    : SS3I_binop_rm_int<0x0B, "vpmulhrsw",
5167                                       int_x86_ssse3_pmul_hr_sw_128, 0>, VEX_4V;
5168 }
5169
5170 let ImmT = NoImm, Predicates = [HasAVX2] in {
5171 let isCommutable = 0 in {
5172   defm VPHADDWY   : SS3I_binop_rm<0x01, "vphaddw", X86hadd, v16i16, VR256,
5173                                   memopv4i64, i256mem, 0>, VEX_4V;
5174   defm VPHADDDY   : SS3I_binop_rm<0x02, "vphaddd", X86hadd, v8i32, VR256,
5175                                   memopv4i64, i256mem, 0>, VEX_4V;
5176   defm VPHSUBWY   : SS3I_binop_rm<0x05, "vphsubw", X86hsub, v16i16, VR256,
5177                                   memopv4i64, i256mem, 0>, VEX_4V;
5178   defm VPHSUBDY   : SS3I_binop_rm<0x06, "vphsubd", X86hsub, v8i32, VR256,
5179                                   memopv4i64, i256mem, 0>, VEX_4V;
5180   defm VPHADDSW   : SS3I_binop_rm_int_y<0x03, "vphaddsw",
5181                                         int_x86_avx2_phadd_sw>, VEX_4V;
5182   defm VPHSUBSW   : SS3I_binop_rm_int_y<0x07, "vphsubsw",
5183                                         int_x86_avx2_phsub_sw>, VEX_4V;
5184   defm VPMADDUBSW : SS3I_binop_rm_int_y<0x04, "vpmaddubsw",
5185                                         int_x86_avx2_pmadd_ub_sw>, VEX_4V;
5186   defm VPSHUFB    : SS3I_binop_rm_int_y<0x00, "vpshufb",
5187                                         int_x86_avx2_pshuf_b>, VEX_4V;
5188   defm VPSIGNB    : SS3I_binop_rm_int_y<0x08, "vpsignb",
5189                                         int_x86_avx2_psign_b>, VEX_4V;
5190   defm VPSIGNW    : SS3I_binop_rm_int_y<0x09, "vpsignw",
5191                                         int_x86_avx2_psign_w>, VEX_4V;
5192   defm VPSIGND    : SS3I_binop_rm_int_y<0x0A, "vpsignd",
5193                                         int_x86_avx2_psign_d>, VEX_4V;
5194 }
5195 defm VPMULHRSW    : SS3I_binop_rm_int_y<0x0B, "vpmulhrsw",
5196                                         int_x86_avx2_pmul_hr_sw>, VEX_4V;
5197 }
5198
5199 // None of these have i8 immediate fields.
5200 let ImmT = NoImm, Constraints = "$src1 = $dst" in {
5201 let isCommutable = 0 in {
5202   defm PHADDW    : SS3I_binop_rm<0x01, "phaddw", X86hadd, v8i16, VR128,
5203                                  memopv2i64, i128mem>;
5204   defm PHADDD    : SS3I_binop_rm<0x02, "phaddd", X86hadd, v4i32, VR128,
5205                                  memopv2i64, i128mem>;
5206   defm PHSUBW    : SS3I_binop_rm<0x05, "phsubw", X86hsub, v8i16, VR128,
5207                                  memopv2i64, i128mem>;
5208   defm PHSUBD    : SS3I_binop_rm<0x06, "phsubd", X86hsub, v4i32, VR128,
5209                                  memopv2i64, i128mem>;
5210   defm PHADDSW   : SS3I_binop_rm_int<0x03, "phaddsw",
5211                                      int_x86_ssse3_phadd_sw_128>;
5212   defm PHSUBSW   : SS3I_binop_rm_int<0x07, "phsubsw",
5213                                      int_x86_ssse3_phsub_sw_128>;
5214   defm PMADDUBSW : SS3I_binop_rm_int<0x04, "pmaddubsw",
5215                                      int_x86_ssse3_pmadd_ub_sw_128>;
5216   defm PSHUFB    : SS3I_binop_rm_int<0x00, "pshufb",
5217                                      int_x86_ssse3_pshuf_b_128>;
5218   defm PSIGNB    : SS3I_binop_rm_int<0x08, "psignb",
5219                                      int_x86_ssse3_psign_b_128>;
5220   defm PSIGNW    : SS3I_binop_rm_int<0x09, "psignw",
5221                                      int_x86_ssse3_psign_w_128>;
5222   defm PSIGND    : SS3I_binop_rm_int<0x0A, "psignd",
5223                                        int_x86_ssse3_psign_d_128>;
5224 }
5225 defm PMULHRSW    : SS3I_binop_rm_int<0x0B, "pmulhrsw",
5226                                      int_x86_ssse3_pmul_hr_sw_128>;
5227 }
5228
5229 let Predicates = [HasAVX] in {
5230   def : Pat<(X86pshufb VR128:$src, VR128:$mask),
5231             (VPSHUFBrr128 VR128:$src, VR128:$mask)>;
5232   def : Pat<(X86pshufb VR128:$src, (bc_v16i8 (memopv2i64 addr:$mask))),
5233             (VPSHUFBrm128 VR128:$src, addr:$mask)>;
5234
5235   def : Pat<(v16i8 (X86psign VR128:$src1, VR128:$src2)),
5236             (VPSIGNBrr128 VR128:$src1, VR128:$src2)>;
5237   def : Pat<(v8i16 (X86psign VR128:$src1, VR128:$src2)),
5238             (VPSIGNWrr128 VR128:$src1, VR128:$src2)>;
5239   def : Pat<(v4i32 (X86psign VR128:$src1, VR128:$src2)),
5240             (VPSIGNDrr128 VR128:$src1, VR128:$src2)>;
5241 }
5242
5243 let Predicates = [HasAVX2] in {
5244   def : Pat<(v32i8 (X86psign VR256:$src1, VR256:$src2)),
5245             (VPSIGNBrr256 VR256:$src1, VR256:$src2)>;
5246   def : Pat<(v16i16 (X86psign VR256:$src1, VR256:$src2)),
5247             (VPSIGNWrr256 VR256:$src1, VR256:$src2)>;
5248   def : Pat<(v8i32 (X86psign VR256:$src1, VR256:$src2)),
5249             (VPSIGNDrr256 VR256:$src1, VR256:$src2)>;
5250 }
5251
5252 let Predicates = [HasSSSE3] in {
5253   def : Pat<(X86pshufb VR128:$src, VR128:$mask),
5254             (PSHUFBrr128 VR128:$src, VR128:$mask)>;
5255   def : Pat<(X86pshufb VR128:$src, (bc_v16i8 (memopv2i64 addr:$mask))),
5256             (PSHUFBrm128 VR128:$src, addr:$mask)>;
5257
5258   def : Pat<(v16i8 (X86psign VR128:$src1, VR128:$src2)),
5259             (PSIGNBrr128 VR128:$src1, VR128:$src2)>;
5260   def : Pat<(v8i16 (X86psign VR128:$src1, VR128:$src2)),
5261             (PSIGNWrr128 VR128:$src1, VR128:$src2)>;
5262   def : Pat<(v4i32 (X86psign VR128:$src1, VR128:$src2)),
5263             (PSIGNDrr128 VR128:$src1, VR128:$src2)>;
5264 }
5265
5266 //===---------------------------------------------------------------------===//
5267 // SSSE3 - Packed Align Instruction Patterns
5268 //===---------------------------------------------------------------------===//
5269
5270 multiclass ssse3_palign<string asm, bit Is2Addr = 1> {
5271   let neverHasSideEffects = 1 in {
5272   def R128rr : SS3AI<0x0F, MRMSrcReg, (outs VR128:$dst),
5273       (ins VR128:$src1, VR128:$src2, i8imm:$src3),
5274       !if(Is2Addr,
5275         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5276         !strconcat(asm,
5277                   "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5278       []>, OpSize;
5279   let mayLoad = 1 in
5280   def R128rm : SS3AI<0x0F, MRMSrcMem, (outs VR128:$dst),
5281       (ins VR128:$src1, i128mem:$src2, i8imm:$src3),
5282       !if(Is2Addr,
5283         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5284         !strconcat(asm,
5285                   "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5286       []>, OpSize;
5287   }
5288 }
5289
5290 multiclass ssse3_palign_y<string asm, bit Is2Addr = 1> {
5291   let neverHasSideEffects = 1 in {
5292   def R256rr : SS3AI<0x0F, MRMSrcReg, (outs VR256:$dst),
5293       (ins VR256:$src1, VR256:$src2, i8imm:$src3),
5294       !strconcat(asm,
5295                  "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
5296       []>, OpSize;
5297   let mayLoad = 1 in
5298   def R256rm : SS3AI<0x0F, MRMSrcMem, (outs VR256:$dst),
5299       (ins VR256:$src1, i256mem:$src2, i8imm:$src3),
5300       !strconcat(asm,
5301                  "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
5302       []>, OpSize;
5303   }
5304 }
5305
5306 let Predicates = [HasAVX] in
5307   defm VPALIGN : ssse3_palign<"vpalignr", 0>, VEX_4V;
5308 let Predicates = [HasAVX2] in
5309   defm VPALIGN : ssse3_palign_y<"vpalignr", 0>, VEX_4V;
5310 let Constraints = "$src1 = $dst", Predicates = [HasSSSE3] in
5311   defm PALIGN : ssse3_palign<"palignr">;
5312
5313 let Predicates = [HasAVX2] in {
5314 def : Pat<(v8i32 (X86PAlign VR256:$src1, VR256:$src2, (i8 imm:$imm))),
5315           (VPALIGNR256rr VR256:$src2, VR256:$src1, imm:$imm)>;
5316 def : Pat<(v8f32 (X86PAlign VR256:$src1, VR256:$src2, (i8 imm:$imm))),
5317           (VPALIGNR256rr VR256:$src2, VR256:$src1, imm:$imm)>;
5318 def : Pat<(v16i16 (X86PAlign VR256:$src1, VR256:$src2, (i8 imm:$imm))),
5319           (VPALIGNR256rr VR256:$src2, VR256:$src1, imm:$imm)>;
5320 def : Pat<(v32i8 (X86PAlign VR256:$src1, VR256:$src2, (i8 imm:$imm))),
5321           (VPALIGNR256rr VR256:$src2, VR256:$src1, imm:$imm)>;
5322 }
5323
5324 let Predicates = [HasAVX] in {
5325 def : Pat<(v4i32 (X86PAlign VR128:$src1, VR128:$src2, (i8 imm:$imm))),
5326           (VPALIGNR128rr VR128:$src2, VR128:$src1, imm:$imm)>;
5327 def : Pat<(v4f32 (X86PAlign VR128:$src1, VR128:$src2, (i8 imm:$imm))),
5328           (VPALIGNR128rr VR128:$src2, VR128:$src1, imm:$imm)>;
5329 def : Pat<(v8i16 (X86PAlign VR128:$src1, VR128:$src2, (i8 imm:$imm))),
5330           (VPALIGNR128rr VR128:$src2, VR128:$src1, imm:$imm)>;
5331 def : Pat<(v16i8 (X86PAlign VR128:$src1, VR128:$src2, (i8 imm:$imm))),
5332           (VPALIGNR128rr VR128:$src2, VR128:$src1, imm:$imm)>;
5333 }
5334
5335 let Predicates = [HasSSSE3] in {
5336 def : Pat<(v4i32 (X86PAlign VR128:$src1, VR128:$src2, (i8 imm:$imm))),
5337           (PALIGNR128rr VR128:$src2, VR128:$src1, imm:$imm)>;
5338 def : Pat<(v4f32 (X86PAlign VR128:$src1, VR128:$src2, (i8 imm:$imm))),
5339           (PALIGNR128rr VR128:$src2, VR128:$src1, imm:$imm)>;
5340 def : Pat<(v8i16 (X86PAlign VR128:$src1, VR128:$src2, (i8 imm:$imm))),
5341           (PALIGNR128rr VR128:$src2, VR128:$src1, imm:$imm)>;
5342 def : Pat<(v16i8 (X86PAlign VR128:$src1, VR128:$src2, (i8 imm:$imm))),
5343           (PALIGNR128rr VR128:$src2, VR128:$src1, imm:$imm)>;
5344 }
5345
5346 //===---------------------------------------------------------------------===//
5347 // SSSE3 - Thread synchronization
5348 //===---------------------------------------------------------------------===//
5349
5350 let usesCustomInserter = 1 in {
5351 def MONITOR : PseudoI<(outs), (ins i32mem:$src1, GR32:$src2, GR32:$src3),
5352                 [(int_x86_sse3_monitor addr:$src1, GR32:$src2, GR32:$src3)]>,
5353                 Requires<[HasSSE3]>;
5354 def MWAIT : PseudoI<(outs), (ins GR32:$src1, GR32:$src2),
5355                 [(int_x86_sse3_mwait GR32:$src1, GR32:$src2)]>,
5356                 Requires<[HasSSE3]>;
5357 }
5358
5359 let Uses = [EAX, ECX, EDX] in
5360 def MONITORrrr : I<0x01, MRM_C8, (outs), (ins), "monitor", []>, TB,
5361                  Requires<[HasSSE3]>;
5362 let Uses = [ECX, EAX] in
5363 def MWAITrr   : I<0x01, MRM_C9, (outs), (ins), "mwait", []>, TB,
5364                 Requires<[HasSSE3]>;
5365
5366 def : InstAlias<"mwait %eax, %ecx", (MWAITrr)>, Requires<[In32BitMode]>;
5367 def : InstAlias<"mwait %rax, %rcx", (MWAITrr)>, Requires<[In64BitMode]>;
5368
5369 def : InstAlias<"monitor %eax, %ecx, %edx", (MONITORrrr)>,
5370       Requires<[In32BitMode]>;
5371 def : InstAlias<"monitor %rax, %rcx, %rdx", (MONITORrrr)>,
5372       Requires<[In64BitMode]>;
5373
5374 //===----------------------------------------------------------------------===//
5375 // SSE4.1 - Packed Move with Sign/Zero Extend
5376 //===----------------------------------------------------------------------===//
5377
5378 multiclass SS41I_binop_rm_int8<bits<8> opc, string OpcodeStr, Intrinsic IntId> {
5379   def rr : SS48I<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
5380                  !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5381                  [(set VR128:$dst, (IntId VR128:$src))]>, OpSize;
5382
5383   def rm : SS48I<opc, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
5384                  !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5385        [(set VR128:$dst,
5386          (IntId (bitconvert (v2i64 (scalar_to_vector (loadi64 addr:$src))))))]>,
5387        OpSize;
5388 }
5389
5390 multiclass SS41I_binop_rm_int16_y<bits<8> opc, string OpcodeStr,
5391                                  Intrinsic IntId> {
5392   def Yrr : SS48I<opc, MRMSrcReg, (outs VR256:$dst), (ins VR128:$src),
5393                   !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5394                   [(set VR256:$dst, (IntId VR128:$src))]>, OpSize;
5395
5396   def Yrm : SS48I<opc, MRMSrcMem, (outs VR256:$dst), (ins i128mem:$src),
5397                   !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5398                   [(set VR256:$dst, (IntId (load addr:$src)))]>, OpSize;
5399 }
5400
5401 let Predicates = [HasAVX] in {
5402 defm VPMOVSXBW : SS41I_binop_rm_int8<0x20, "vpmovsxbw", int_x86_sse41_pmovsxbw>,
5403                                      VEX;
5404 defm VPMOVSXWD : SS41I_binop_rm_int8<0x23, "vpmovsxwd", int_x86_sse41_pmovsxwd>,
5405                                      VEX;
5406 defm VPMOVSXDQ : SS41I_binop_rm_int8<0x25, "vpmovsxdq", int_x86_sse41_pmovsxdq>,
5407                                      VEX;
5408 defm VPMOVZXBW : SS41I_binop_rm_int8<0x30, "vpmovzxbw", int_x86_sse41_pmovzxbw>,
5409                                      VEX;
5410 defm VPMOVZXWD : SS41I_binop_rm_int8<0x33, "vpmovzxwd", int_x86_sse41_pmovzxwd>,
5411                                      VEX;
5412 defm VPMOVZXDQ : SS41I_binop_rm_int8<0x35, "vpmovzxdq", int_x86_sse41_pmovzxdq>,
5413                                      VEX;
5414 }
5415
5416 let Predicates = [HasAVX2] in {
5417 defm VPMOVSXBW : SS41I_binop_rm_int16_y<0x20, "vpmovsxbw",
5418                                         int_x86_avx2_pmovsxbw>, VEX;
5419 defm VPMOVSXWD : SS41I_binop_rm_int16_y<0x23, "vpmovsxwd",
5420                                         int_x86_avx2_pmovsxwd>, VEX;
5421 defm VPMOVSXDQ : SS41I_binop_rm_int16_y<0x25, "vpmovsxdq",
5422                                         int_x86_avx2_pmovsxdq>, VEX;
5423 defm VPMOVZXBW : SS41I_binop_rm_int16_y<0x30, "vpmovzxbw",
5424                                         int_x86_avx2_pmovzxbw>, VEX;
5425 defm VPMOVZXWD : SS41I_binop_rm_int16_y<0x33, "vpmovzxwd",
5426                                         int_x86_avx2_pmovzxwd>, VEX;
5427 defm VPMOVZXDQ : SS41I_binop_rm_int16_y<0x35, "vpmovzxdq",
5428                                         int_x86_avx2_pmovzxdq>, VEX;
5429 }
5430
5431 defm PMOVSXBW   : SS41I_binop_rm_int8<0x20, "pmovsxbw", int_x86_sse41_pmovsxbw>;
5432 defm PMOVSXWD   : SS41I_binop_rm_int8<0x23, "pmovsxwd", int_x86_sse41_pmovsxwd>;
5433 defm PMOVSXDQ   : SS41I_binop_rm_int8<0x25, "pmovsxdq", int_x86_sse41_pmovsxdq>;
5434 defm PMOVZXBW   : SS41I_binop_rm_int8<0x30, "pmovzxbw", int_x86_sse41_pmovzxbw>;
5435 defm PMOVZXWD   : SS41I_binop_rm_int8<0x33, "pmovzxwd", int_x86_sse41_pmovzxwd>;
5436 defm PMOVZXDQ   : SS41I_binop_rm_int8<0x35, "pmovzxdq", int_x86_sse41_pmovzxdq>;
5437
5438 let Predicates = [HasAVX] in {
5439   // Common patterns involving scalar load.
5440   def : Pat<(int_x86_sse41_pmovsxbw (vzmovl_v2i64 addr:$src)),
5441             (VPMOVSXBWrm addr:$src)>;
5442   def : Pat<(int_x86_sse41_pmovsxbw (vzload_v2i64 addr:$src)),
5443             (VPMOVSXBWrm addr:$src)>;
5444
5445   def : Pat<(int_x86_sse41_pmovsxwd (vzmovl_v2i64 addr:$src)),
5446             (VPMOVSXWDrm addr:$src)>;
5447   def : Pat<(int_x86_sse41_pmovsxwd (vzload_v2i64 addr:$src)),
5448             (VPMOVSXWDrm addr:$src)>;
5449
5450   def : Pat<(int_x86_sse41_pmovsxdq (vzmovl_v2i64 addr:$src)),
5451             (VPMOVSXDQrm addr:$src)>;
5452   def : Pat<(int_x86_sse41_pmovsxdq (vzload_v2i64 addr:$src)),
5453             (VPMOVSXDQrm addr:$src)>;
5454
5455   def : Pat<(int_x86_sse41_pmovzxbw (vzmovl_v2i64 addr:$src)),
5456             (VPMOVZXBWrm addr:$src)>;
5457   def : Pat<(int_x86_sse41_pmovzxbw (vzload_v2i64 addr:$src)),
5458             (VPMOVZXBWrm addr:$src)>;
5459
5460   def : Pat<(int_x86_sse41_pmovzxwd (vzmovl_v2i64 addr:$src)),
5461             (VPMOVZXWDrm addr:$src)>;
5462   def : Pat<(int_x86_sse41_pmovzxwd (vzload_v2i64 addr:$src)),
5463             (VPMOVZXWDrm addr:$src)>;
5464
5465   def : Pat<(int_x86_sse41_pmovzxdq (vzmovl_v2i64 addr:$src)),
5466             (VPMOVZXDQrm addr:$src)>;
5467   def : Pat<(int_x86_sse41_pmovzxdq (vzload_v2i64 addr:$src)),
5468             (VPMOVZXDQrm addr:$src)>;
5469 }
5470
5471 let Predicates = [HasSSE41] in {
5472   // Common patterns involving scalar load.
5473   def : Pat<(int_x86_sse41_pmovsxbw (vzmovl_v2i64 addr:$src)),
5474             (PMOVSXBWrm addr:$src)>;
5475   def : Pat<(int_x86_sse41_pmovsxbw (vzload_v2i64 addr:$src)),
5476             (PMOVSXBWrm addr:$src)>;
5477
5478   def : Pat<(int_x86_sse41_pmovsxwd (vzmovl_v2i64 addr:$src)),
5479             (PMOVSXWDrm addr:$src)>;
5480   def : Pat<(int_x86_sse41_pmovsxwd (vzload_v2i64 addr:$src)),
5481             (PMOVSXWDrm addr:$src)>;
5482
5483   def : Pat<(int_x86_sse41_pmovsxdq (vzmovl_v2i64 addr:$src)),
5484             (PMOVSXDQrm addr:$src)>;
5485   def : Pat<(int_x86_sse41_pmovsxdq (vzload_v2i64 addr:$src)),
5486             (PMOVSXDQrm addr:$src)>;
5487
5488   def : Pat<(int_x86_sse41_pmovzxbw (vzmovl_v2i64 addr:$src)),
5489             (PMOVZXBWrm addr:$src)>;
5490   def : Pat<(int_x86_sse41_pmovzxbw (vzload_v2i64 addr:$src)),
5491             (PMOVZXBWrm addr:$src)>;
5492
5493   def : Pat<(int_x86_sse41_pmovzxwd (vzmovl_v2i64 addr:$src)),
5494             (PMOVZXWDrm addr:$src)>;
5495   def : Pat<(int_x86_sse41_pmovzxwd (vzload_v2i64 addr:$src)),
5496             (PMOVZXWDrm addr:$src)>;
5497
5498   def : Pat<(int_x86_sse41_pmovzxdq (vzmovl_v2i64 addr:$src)),
5499             (PMOVZXDQrm addr:$src)>;
5500   def : Pat<(int_x86_sse41_pmovzxdq (vzload_v2i64 addr:$src)),
5501             (PMOVZXDQrm addr:$src)>;
5502 }
5503
5504
5505 multiclass SS41I_binop_rm_int4<bits<8> opc, string OpcodeStr, Intrinsic IntId> {
5506   def rr : SS48I<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
5507                  !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5508                  [(set VR128:$dst, (IntId VR128:$src))]>, OpSize;
5509
5510   def rm : SS48I<opc, MRMSrcMem, (outs VR128:$dst), (ins i32mem:$src),
5511                  !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5512        [(set VR128:$dst,
5513          (IntId (bitconvert (v4i32 (scalar_to_vector (loadi32 addr:$src))))))]>,
5514           OpSize;
5515 }
5516
5517 multiclass SS41I_binop_rm_int8_y<bits<8> opc, string OpcodeStr,
5518                                  Intrinsic IntId> {
5519   def Yrr : SS48I<opc, MRMSrcReg, (outs VR256:$dst), (ins VR128:$src),
5520                   !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5521                   [(set VR256:$dst, (IntId VR128:$src))]>, OpSize;
5522
5523   def Yrm : SS48I<opc, MRMSrcMem, (outs VR256:$dst), (ins i32mem:$src),
5524                   !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5525        [(set VR256:$dst,
5526          (IntId (bitconvert (v2i64 (scalar_to_vector (loadi64 addr:$src))))))]>,
5527           OpSize;
5528 }
5529
5530 let Predicates = [HasAVX] in {
5531 defm VPMOVSXBD : SS41I_binop_rm_int4<0x21, "vpmovsxbd", int_x86_sse41_pmovsxbd>,
5532                                      VEX;
5533 defm VPMOVSXWQ : SS41I_binop_rm_int4<0x24, "vpmovsxwq", int_x86_sse41_pmovsxwq>,
5534                                      VEX;
5535 defm VPMOVZXBD : SS41I_binop_rm_int4<0x31, "vpmovzxbd", int_x86_sse41_pmovzxbd>,
5536                                      VEX;
5537 defm VPMOVZXWQ : SS41I_binop_rm_int4<0x34, "vpmovzxwq", int_x86_sse41_pmovzxwq>,
5538                                      VEX;
5539 }
5540
5541 let Predicates = [HasAVX2] in {
5542 defm VPMOVSXBD : SS41I_binop_rm_int8_y<0x21, "vpmovsxbd",
5543                                        int_x86_avx2_pmovsxbd>, VEX;
5544 defm VPMOVSXWQ : SS41I_binop_rm_int8_y<0x24, "vpmovsxwq",
5545                                        int_x86_avx2_pmovsxwq>, VEX;
5546 defm VPMOVZXBD : SS41I_binop_rm_int8_y<0x31, "vpmovzxbd",
5547                                        int_x86_avx2_pmovzxbd>, VEX;
5548 defm VPMOVZXWQ : SS41I_binop_rm_int8_y<0x34, "vpmovzxwq",
5549                                        int_x86_avx2_pmovzxwq>, VEX;
5550 }
5551
5552 defm PMOVSXBD   : SS41I_binop_rm_int4<0x21, "pmovsxbd", int_x86_sse41_pmovsxbd>;
5553 defm PMOVSXWQ   : SS41I_binop_rm_int4<0x24, "pmovsxwq", int_x86_sse41_pmovsxwq>;
5554 defm PMOVZXBD   : SS41I_binop_rm_int4<0x31, "pmovzxbd", int_x86_sse41_pmovzxbd>;
5555 defm PMOVZXWQ   : SS41I_binop_rm_int4<0x34, "pmovzxwq", int_x86_sse41_pmovzxwq>;
5556
5557 let Predicates = [HasAVX] in {
5558   // Common patterns involving scalar load
5559   def : Pat<(int_x86_sse41_pmovsxbd (vzmovl_v4i32 addr:$src)),
5560             (VPMOVSXBDrm addr:$src)>;
5561   def : Pat<(int_x86_sse41_pmovsxwq (vzmovl_v4i32 addr:$src)),
5562             (VPMOVSXWQrm addr:$src)>;
5563
5564   def : Pat<(int_x86_sse41_pmovzxbd (vzmovl_v4i32 addr:$src)),
5565             (VPMOVZXBDrm addr:$src)>;
5566   def : Pat<(int_x86_sse41_pmovzxwq (vzmovl_v4i32 addr:$src)),
5567             (VPMOVZXWQrm addr:$src)>;
5568 }
5569
5570 let Predicates = [HasSSE41] in {
5571   // Common patterns involving scalar load
5572   def : Pat<(int_x86_sse41_pmovsxbd (vzmovl_v4i32 addr:$src)),
5573             (PMOVSXBDrm addr:$src)>;
5574   def : Pat<(int_x86_sse41_pmovsxwq (vzmovl_v4i32 addr:$src)),
5575             (PMOVSXWQrm addr:$src)>;
5576
5577   def : Pat<(int_x86_sse41_pmovzxbd (vzmovl_v4i32 addr:$src)),
5578             (PMOVZXBDrm addr:$src)>;
5579   def : Pat<(int_x86_sse41_pmovzxwq (vzmovl_v4i32 addr:$src)),
5580             (PMOVZXWQrm addr:$src)>;
5581 }
5582
5583 multiclass SS41I_binop_rm_int2<bits<8> opc, string OpcodeStr, Intrinsic IntId> {
5584   def rr : SS48I<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
5585                  !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5586                  [(set VR128:$dst, (IntId VR128:$src))]>, OpSize;
5587
5588   // Expecting a i16 load any extended to i32 value.
5589   def rm : SS48I<opc, MRMSrcMem, (outs VR128:$dst), (ins i16mem:$src),
5590                  !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5591                  [(set VR128:$dst, (IntId (bitconvert
5592                      (v4i32 (scalar_to_vector (loadi16_anyext addr:$src))))))]>,
5593                  OpSize;
5594 }
5595
5596 multiclass SS41I_binop_rm_int4_y<bits<8> opc, string OpcodeStr,
5597                                  Intrinsic IntId> {
5598   def Yrr : SS48I<opc, MRMSrcReg, (outs VR256:$dst), (ins VR128:$src),
5599                  !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5600                  [(set VR256:$dst, (IntId VR128:$src))]>, OpSize;
5601
5602   // Expecting a i16 load any extended to i32 value.
5603   def Yrm : SS48I<opc, MRMSrcMem, (outs VR256:$dst), (ins i16mem:$src),
5604                   !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5605                   [(set VR256:$dst, (IntId (bitconvert
5606                       (v4i32 (scalar_to_vector (loadi32 addr:$src))))))]>,
5607                   OpSize;
5608 }
5609
5610 let Predicates = [HasAVX] in {
5611 defm VPMOVSXBQ : SS41I_binop_rm_int2<0x22, "vpmovsxbq", int_x86_sse41_pmovsxbq>,
5612                                      VEX;
5613 defm VPMOVZXBQ : SS41I_binop_rm_int2<0x32, "vpmovzxbq", int_x86_sse41_pmovzxbq>,
5614                                      VEX;
5615 }
5616 let Predicates = [HasAVX2] in {
5617 defm VPMOVSXBQ : SS41I_binop_rm_int4_y<0x22, "vpmovsxbq",
5618                                        int_x86_avx2_pmovsxbq>, VEX;
5619 defm VPMOVZXBQ : SS41I_binop_rm_int4_y<0x32, "vpmovzxbq",
5620                                        int_x86_avx2_pmovzxbq>, VEX;
5621 }
5622 defm PMOVSXBQ   : SS41I_binop_rm_int2<0x22, "pmovsxbq", int_x86_sse41_pmovsxbq>;
5623 defm PMOVZXBQ   : SS41I_binop_rm_int2<0x32, "pmovzxbq", int_x86_sse41_pmovzxbq>;
5624
5625 let Predicates = [HasAVX] in {
5626   // Common patterns involving scalar load
5627   def : Pat<(int_x86_sse41_pmovsxbq
5628               (bitconvert (v4i32 (X86vzmovl
5629                             (v4i32 (scalar_to_vector (loadi32 addr:$src))))))),
5630             (VPMOVSXBQrm addr:$src)>;
5631
5632   def : Pat<(int_x86_sse41_pmovzxbq
5633               (bitconvert (v4i32 (X86vzmovl
5634                             (v4i32 (scalar_to_vector (loadi32 addr:$src))))))),
5635             (VPMOVZXBQrm addr:$src)>;
5636 }
5637
5638 let Predicates = [HasSSE41] in {
5639   // Common patterns involving scalar load
5640   def : Pat<(int_x86_sse41_pmovsxbq
5641               (bitconvert (v4i32 (X86vzmovl
5642                             (v4i32 (scalar_to_vector (loadi32 addr:$src))))))),
5643             (PMOVSXBQrm addr:$src)>;
5644
5645   def : Pat<(int_x86_sse41_pmovzxbq
5646               (bitconvert (v4i32 (X86vzmovl
5647                             (v4i32 (scalar_to_vector (loadi32 addr:$src))))))),
5648             (PMOVZXBQrm addr:$src)>;
5649 }
5650
5651 //===----------------------------------------------------------------------===//
5652 // SSE4.1 - Extract Instructions
5653 //===----------------------------------------------------------------------===//
5654
5655 /// SS41I_binop_ext8 - SSE 4.1 extract 8 bits to 32 bit reg or 8 bit mem
5656 multiclass SS41I_extract8<bits<8> opc, string OpcodeStr> {
5657   def rr : SS4AIi8<opc, MRMDestReg, (outs GR32:$dst),
5658                  (ins VR128:$src1, i32i8imm:$src2),
5659                  !strconcat(OpcodeStr,
5660                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5661                  [(set GR32:$dst, (X86pextrb (v16i8 VR128:$src1), imm:$src2))]>,
5662                  OpSize;
5663   let neverHasSideEffects = 1, mayStore = 1 in
5664   def mr : SS4AIi8<opc, MRMDestMem, (outs),
5665                  (ins i8mem:$dst, VR128:$src1, i32i8imm:$src2),
5666                  !strconcat(OpcodeStr,
5667                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5668                  []>, OpSize;
5669 // FIXME:
5670 // There's an AssertZext in the way of writing the store pattern
5671 // (store (i8 (trunc (X86pextrb (v16i8 VR128:$src1), imm:$src2))), addr:$dst)
5672 }
5673
5674 let Predicates = [HasAVX] in {
5675   defm VPEXTRB : SS41I_extract8<0x14, "vpextrb">, VEX;
5676   def  VPEXTRBrr64 : SS4AIi8<0x14, MRMDestReg, (outs GR64:$dst),
5677          (ins VR128:$src1, i32i8imm:$src2),
5678          "vpextrb\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>, OpSize, VEX;
5679 }
5680
5681 defm PEXTRB      : SS41I_extract8<0x14, "pextrb">;
5682
5683
5684 /// SS41I_extract16 - SSE 4.1 extract 16 bits to memory destination
5685 multiclass SS41I_extract16<bits<8> opc, string OpcodeStr> {
5686   let neverHasSideEffects = 1, mayStore = 1 in
5687   def mr : SS4AIi8<opc, MRMDestMem, (outs),
5688                  (ins i16mem:$dst, VR128:$src1, i32i8imm:$src2),
5689                  !strconcat(OpcodeStr,
5690                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5691                  []>, OpSize;
5692 // FIXME:
5693 // There's an AssertZext in the way of writing the store pattern
5694 // (store (i16 (trunc (X86pextrw (v16i8 VR128:$src1), imm:$src2))), addr:$dst)
5695 }
5696
5697 let Predicates = [HasAVX] in
5698   defm VPEXTRW : SS41I_extract16<0x15, "vpextrw">, VEX;
5699
5700 defm PEXTRW      : SS41I_extract16<0x15, "pextrw">;
5701
5702
5703 /// SS41I_extract32 - SSE 4.1 extract 32 bits to int reg or memory destination
5704 multiclass SS41I_extract32<bits<8> opc, string OpcodeStr> {
5705   def rr : SS4AIi8<opc, MRMDestReg, (outs GR32:$dst),
5706                  (ins VR128:$src1, i32i8imm:$src2),
5707                  !strconcat(OpcodeStr,
5708                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5709                  [(set GR32:$dst,
5710                   (extractelt (v4i32 VR128:$src1), imm:$src2))]>, OpSize;
5711   def mr : SS4AIi8<opc, MRMDestMem, (outs),
5712                  (ins i32mem:$dst, VR128:$src1, i32i8imm:$src2),
5713                  !strconcat(OpcodeStr,
5714                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5715                  [(store (extractelt (v4i32 VR128:$src1), imm:$src2),
5716                           addr:$dst)]>, OpSize;
5717 }
5718
5719 let Predicates = [HasAVX] in
5720   defm VPEXTRD : SS41I_extract32<0x16, "vpextrd">, VEX;
5721
5722 defm PEXTRD      : SS41I_extract32<0x16, "pextrd">;
5723
5724 /// SS41I_extract32 - SSE 4.1 extract 32 bits to int reg or memory destination
5725 multiclass SS41I_extract64<bits<8> opc, string OpcodeStr> {
5726   def rr : SS4AIi8<opc, MRMDestReg, (outs GR64:$dst),
5727                  (ins VR128:$src1, i32i8imm:$src2),
5728                  !strconcat(OpcodeStr,
5729                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5730                  [(set GR64:$dst,
5731                   (extractelt (v2i64 VR128:$src1), imm:$src2))]>, OpSize, REX_W;
5732   def mr : SS4AIi8<opc, MRMDestMem, (outs),
5733                  (ins i64mem:$dst, VR128:$src1, i32i8imm:$src2),
5734                  !strconcat(OpcodeStr,
5735                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5736                  [(store (extractelt (v2i64 VR128:$src1), imm:$src2),
5737                           addr:$dst)]>, OpSize, REX_W;
5738 }
5739
5740 let Predicates = [HasAVX] in
5741   defm VPEXTRQ : SS41I_extract64<0x16, "vpextrq">, VEX, VEX_W;
5742
5743 defm PEXTRQ      : SS41I_extract64<0x16, "pextrq">;
5744
5745 /// SS41I_extractf32 - SSE 4.1 extract 32 bits fp value to int reg or memory
5746 /// destination
5747 multiclass SS41I_extractf32<bits<8> opc, string OpcodeStr> {
5748   def rr : SS4AIi8<opc, MRMDestReg, (outs GR32:$dst),
5749                  (ins VR128:$src1, i32i8imm:$src2),
5750                  !strconcat(OpcodeStr,
5751                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5752                  [(set GR32:$dst,
5753                     (extractelt (bc_v4i32 (v4f32 VR128:$src1)), imm:$src2))]>,
5754            OpSize;
5755   def mr : SS4AIi8<opc, MRMDestMem, (outs),
5756                  (ins f32mem:$dst, VR128:$src1, i32i8imm:$src2),
5757                  !strconcat(OpcodeStr,
5758                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5759                  [(store (extractelt (bc_v4i32 (v4f32 VR128:$src1)), imm:$src2),
5760                           addr:$dst)]>, OpSize;
5761 }
5762
5763 let ExeDomain = SSEPackedSingle in {
5764   let Predicates = [HasAVX] in {
5765     defm VEXTRACTPS : SS41I_extractf32<0x17, "vextractps">, VEX;
5766     def VEXTRACTPSrr64 : SS4AIi8<0x17, MRMDestReg, (outs GR64:$dst),
5767                     (ins VR128:$src1, i32i8imm:$src2),
5768                     "vextractps \t{$src2, $src1, $dst|$dst, $src1, $src2}",
5769                     []>, OpSize, VEX;
5770   }
5771   defm EXTRACTPS   : SS41I_extractf32<0x17, "extractps">;
5772 }
5773
5774 // Also match an EXTRACTPS store when the store is done as f32 instead of i32.
5775 def : Pat<(store (f32 (bitconvert (extractelt (bc_v4i32 (v4f32 VR128:$src1)),
5776                                               imm:$src2))),
5777                  addr:$dst),
5778           (VEXTRACTPSmr addr:$dst, VR128:$src1, imm:$src2)>,
5779           Requires<[HasAVX]>;
5780 def : Pat<(store (f32 (bitconvert (extractelt (bc_v4i32 (v4f32 VR128:$src1)),
5781                                               imm:$src2))),
5782                  addr:$dst),
5783           (EXTRACTPSmr addr:$dst, VR128:$src1, imm:$src2)>,
5784           Requires<[HasSSE41]>;
5785
5786 //===----------------------------------------------------------------------===//
5787 // SSE4.1 - Insert Instructions
5788 //===----------------------------------------------------------------------===//
5789
5790 multiclass SS41I_insert8<bits<8> opc, string asm, bit Is2Addr = 1> {
5791   def rr : SS4AIi8<opc, MRMSrcReg, (outs VR128:$dst),
5792       (ins VR128:$src1, GR32:$src2, i32i8imm:$src3),
5793       !if(Is2Addr,
5794         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5795         !strconcat(asm,
5796                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5797       [(set VR128:$dst,
5798         (X86pinsrb VR128:$src1, GR32:$src2, imm:$src3))]>, OpSize;
5799   def rm : SS4AIi8<opc, MRMSrcMem, (outs VR128:$dst),
5800       (ins VR128:$src1, i8mem:$src2, i32i8imm:$src3),
5801       !if(Is2Addr,
5802         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5803         !strconcat(asm,
5804                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5805       [(set VR128:$dst,
5806         (X86pinsrb VR128:$src1, (extloadi8 addr:$src2),
5807                    imm:$src3))]>, OpSize;
5808 }
5809
5810 let Predicates = [HasAVX] in
5811   defm VPINSRB : SS41I_insert8<0x20, "vpinsrb", 0>, VEX_4V;
5812 let Constraints = "$src1 = $dst" in
5813   defm PINSRB  : SS41I_insert8<0x20, "pinsrb">;
5814
5815 multiclass SS41I_insert32<bits<8> opc, string asm, bit Is2Addr = 1> {
5816   def rr : SS4AIi8<opc, MRMSrcReg, (outs VR128:$dst),
5817       (ins VR128:$src1, GR32:$src2, i32i8imm:$src3),
5818       !if(Is2Addr,
5819         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5820         !strconcat(asm,
5821                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5822       [(set VR128:$dst,
5823         (v4i32 (insertelt VR128:$src1, GR32:$src2, imm:$src3)))]>,
5824       OpSize;
5825   def rm : SS4AIi8<opc, MRMSrcMem, (outs VR128:$dst),
5826       (ins VR128:$src1, i32mem:$src2, i32i8imm:$src3),
5827       !if(Is2Addr,
5828         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5829         !strconcat(asm,
5830                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5831       [(set VR128:$dst,
5832         (v4i32 (insertelt VR128:$src1, (loadi32 addr:$src2),
5833                           imm:$src3)))]>, OpSize;
5834 }
5835
5836 let Predicates = [HasAVX] in
5837   defm VPINSRD : SS41I_insert32<0x22, "vpinsrd", 0>, VEX_4V;
5838 let Constraints = "$src1 = $dst" in
5839   defm PINSRD : SS41I_insert32<0x22, "pinsrd">;
5840
5841 multiclass SS41I_insert64<bits<8> opc, string asm, bit Is2Addr = 1> {
5842   def rr : SS4AIi8<opc, MRMSrcReg, (outs VR128:$dst),
5843       (ins VR128:$src1, GR64:$src2, i32i8imm:$src3),
5844       !if(Is2Addr,
5845         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5846         !strconcat(asm,
5847                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5848       [(set VR128:$dst,
5849         (v2i64 (insertelt VR128:$src1, GR64:$src2, imm:$src3)))]>,
5850       OpSize;
5851   def rm : SS4AIi8<opc, MRMSrcMem, (outs VR128:$dst),
5852       (ins VR128:$src1, i64mem:$src2, i32i8imm:$src3),
5853       !if(Is2Addr,
5854         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5855         !strconcat(asm,
5856                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5857       [(set VR128:$dst,
5858         (v2i64 (insertelt VR128:$src1, (loadi64 addr:$src2),
5859                           imm:$src3)))]>, OpSize;
5860 }
5861
5862 let Predicates = [HasAVX] in
5863   defm VPINSRQ : SS41I_insert64<0x22, "vpinsrq", 0>, VEX_4V, VEX_W;
5864 let Constraints = "$src1 = $dst" in
5865   defm PINSRQ : SS41I_insert64<0x22, "pinsrq">, REX_W;
5866
5867 // insertps has a few different modes, there's the first two here below which
5868 // are optimized inserts that won't zero arbitrary elements in the destination
5869 // vector. The next one matches the intrinsic and could zero arbitrary elements
5870 // in the target vector.
5871 multiclass SS41I_insertf32<bits<8> opc, string asm, bit Is2Addr = 1> {
5872   def rr : SS4AIi8<opc, MRMSrcReg, (outs VR128:$dst),
5873       (ins VR128:$src1, VR128:$src2, u32u8imm:$src3),
5874       !if(Is2Addr,
5875         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5876         !strconcat(asm,
5877                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5878       [(set VR128:$dst,
5879         (X86insrtps VR128:$src1, VR128:$src2, imm:$src3))]>,
5880       OpSize;
5881   def rm : SS4AIi8<opc, MRMSrcMem, (outs VR128:$dst),
5882       (ins VR128:$src1, f32mem:$src2, u32u8imm:$src3),
5883       !if(Is2Addr,
5884         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5885         !strconcat(asm,
5886                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5887       [(set VR128:$dst,
5888         (X86insrtps VR128:$src1,
5889                    (v4f32 (scalar_to_vector (loadf32 addr:$src2))),
5890                     imm:$src3))]>, OpSize;
5891 }
5892
5893 let ExeDomain = SSEPackedSingle in {
5894   let Predicates = [HasAVX] in
5895     defm VINSERTPS : SS41I_insertf32<0x21, "vinsertps", 0>, VEX_4V;
5896   let Constraints = "$src1 = $dst" in
5897     defm INSERTPS : SS41I_insertf32<0x21, "insertps">;
5898 }
5899
5900 def : Pat<(int_x86_sse41_insertps VR128:$src1, VR128:$src2, imm:$src3),
5901           (VINSERTPSrr VR128:$src1, VR128:$src2, imm:$src3)>,
5902           Requires<[HasAVX]>;
5903 def : Pat<(int_x86_sse41_insertps VR128:$src1, VR128:$src2, imm:$src3),
5904           (INSERTPSrr VR128:$src1, VR128:$src2, imm:$src3)>,
5905           Requires<[HasSSE41]>;
5906
5907 //===----------------------------------------------------------------------===//
5908 // SSE4.1 - Round Instructions
5909 //===----------------------------------------------------------------------===//
5910
5911 multiclass sse41_fp_unop_rm<bits<8> opcps, bits<8> opcpd, string OpcodeStr,
5912                             X86MemOperand x86memop, RegisterClass RC,
5913                             PatFrag mem_frag32, PatFrag mem_frag64,
5914                             Intrinsic V4F32Int, Intrinsic V2F64Int> {
5915 let ExeDomain = SSEPackedSingle in {
5916   // Intrinsic operation, reg.
5917   // Vector intrinsic operation, reg
5918   def PSr : SS4AIi8<opcps, MRMSrcReg,
5919                     (outs RC:$dst), (ins RC:$src1, i32i8imm:$src2),
5920                     !strconcat(OpcodeStr,
5921                     "ps\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5922                     [(set RC:$dst, (V4F32Int RC:$src1, imm:$src2))]>,
5923                     OpSize;
5924
5925   // Vector intrinsic operation, mem
5926   def PSm : SS4AIi8<opcps, MRMSrcMem,
5927                     (outs RC:$dst), (ins x86memop:$src1, i32i8imm:$src2),
5928                     !strconcat(OpcodeStr,
5929                     "ps\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5930                     [(set RC:$dst,
5931                           (V4F32Int (mem_frag32 addr:$src1),imm:$src2))]>,
5932                     OpSize;
5933 } // ExeDomain = SSEPackedSingle
5934
5935 let ExeDomain = SSEPackedDouble in {
5936   // Vector intrinsic operation, reg
5937   def PDr : SS4AIi8<opcpd, MRMSrcReg,
5938                     (outs RC:$dst), (ins RC:$src1, i32i8imm:$src2),
5939                     !strconcat(OpcodeStr,
5940                     "pd\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5941                     [(set RC:$dst, (V2F64Int RC:$src1, imm:$src2))]>,
5942                     OpSize;
5943
5944   // Vector intrinsic operation, mem
5945   def PDm : SS4AIi8<opcpd, MRMSrcMem,
5946                     (outs RC:$dst), (ins x86memop:$src1, i32i8imm:$src2),
5947                     !strconcat(OpcodeStr,
5948                     "pd\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5949                     [(set RC:$dst,
5950                           (V2F64Int (mem_frag64 addr:$src1),imm:$src2))]>,
5951                     OpSize;
5952 } // ExeDomain = SSEPackedDouble
5953 }
5954
5955 multiclass sse41_fp_binop_rm<bits<8> opcss, bits<8> opcsd,
5956                             string OpcodeStr,
5957                             Intrinsic F32Int,
5958                             Intrinsic F64Int, bit Is2Addr = 1> {
5959 let ExeDomain = GenericDomain in {
5960   // Operation, reg.
5961   def SSr : SS4AIi8<opcss, MRMSrcReg,
5962       (outs FR32:$dst), (ins FR32:$src1, FR32:$src2, i32i8imm:$src3),
5963       !if(Is2Addr,
5964           !strconcat(OpcodeStr,
5965               "ss\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5966           !strconcat(OpcodeStr,
5967               "ss\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5968       []>, OpSize;
5969
5970   // Intrinsic operation, reg.
5971   def SSr_Int : SS4AIi8<opcss, MRMSrcReg,
5972         (outs VR128:$dst), (ins VR128:$src1, VR128:$src2, i32i8imm:$src3),
5973         !if(Is2Addr,
5974             !strconcat(OpcodeStr,
5975                 "ss\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5976             !strconcat(OpcodeStr,
5977                 "ss\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5978         [(set VR128:$dst, (F32Int VR128:$src1, VR128:$src2, imm:$src3))]>,
5979         OpSize;
5980
5981   // Intrinsic operation, mem.
5982   def SSm : SS4AIi8<opcss, MRMSrcMem,
5983         (outs VR128:$dst), (ins VR128:$src1, ssmem:$src2, i32i8imm:$src3),
5984         !if(Is2Addr,
5985             !strconcat(OpcodeStr,
5986                 "ss\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5987             !strconcat(OpcodeStr,
5988                 "ss\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5989         [(set VR128:$dst,
5990              (F32Int VR128:$src1, sse_load_f32:$src2, imm:$src3))]>,
5991         OpSize;
5992
5993   // Operation, reg.
5994   def SDr : SS4AIi8<opcsd, MRMSrcReg,
5995         (outs FR64:$dst), (ins FR64:$src1, FR64:$src2, i32i8imm:$src3),
5996         !if(Is2Addr,
5997             !strconcat(OpcodeStr,
5998                 "sd\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5999             !strconcat(OpcodeStr,
6000                 "sd\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6001         []>, OpSize;
6002
6003   // Intrinsic operation, reg.
6004   def SDr_Int : SS4AIi8<opcsd, MRMSrcReg,
6005         (outs VR128:$dst), (ins VR128:$src1, VR128:$src2, i32i8imm:$src3),
6006         !if(Is2Addr,
6007             !strconcat(OpcodeStr,
6008                 "sd\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6009             !strconcat(OpcodeStr,
6010                 "sd\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6011         [(set VR128:$dst, (F64Int VR128:$src1, VR128:$src2, imm:$src3))]>,
6012         OpSize;
6013
6014   // Intrinsic operation, mem.
6015   def SDm : SS4AIi8<opcsd, MRMSrcMem,
6016         (outs VR128:$dst), (ins VR128:$src1, sdmem:$src2, i32i8imm:$src3),
6017         !if(Is2Addr,
6018             !strconcat(OpcodeStr,
6019                 "sd\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6020             !strconcat(OpcodeStr,
6021                 "sd\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6022         [(set VR128:$dst,
6023               (F64Int VR128:$src1, sse_load_f64:$src2, imm:$src3))]>,
6024         OpSize;
6025 } // ExeDomain = GenericDomain
6026 }
6027
6028 // FP round - roundss, roundps, roundsd, roundpd
6029 let Predicates = [HasAVX] in {
6030   // Intrinsic form
6031   defm VROUND  : sse41_fp_unop_rm<0x08, 0x09, "vround", f128mem, VR128,
6032                                   memopv4f32, memopv2f64,
6033                                   int_x86_sse41_round_ps,
6034                                   int_x86_sse41_round_pd>, VEX;
6035   defm VROUNDY : sse41_fp_unop_rm<0x08, 0x09, "vround", f256mem, VR256,
6036                                   memopv8f32, memopv4f64,
6037                                   int_x86_avx_round_ps_256,
6038                                   int_x86_avx_round_pd_256>, VEX;
6039   defm VROUND  : sse41_fp_binop_rm<0x0A, 0x0B, "vround",
6040                                   int_x86_sse41_round_ss,
6041                                   int_x86_sse41_round_sd, 0>, VEX_4V, VEX_LIG;
6042
6043   def : Pat<(ffloor FR32:$src),
6044             (VROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x1))>;
6045   def : Pat<(f64 (ffloor FR64:$src)),
6046             (VROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x1))>;
6047   def : Pat<(f32 (fnearbyint FR32:$src)),
6048             (VROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0xC))>;
6049   def : Pat<(f64 (fnearbyint FR64:$src)),
6050             (VROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0xC))>;
6051   def : Pat<(f32 (fceil FR32:$src)),
6052             (VROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x2))>;
6053   def : Pat<(f64 (fceil FR64:$src)),
6054             (VROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x2))>;
6055   def : Pat<(f32 (frint FR32:$src)),
6056             (VROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x4))>;
6057   def : Pat<(f64 (frint FR64:$src)),
6058             (VROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x4))>;
6059   def : Pat<(f32 (ftrunc FR32:$src)),
6060             (VROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x3))>;
6061   def : Pat<(f64 (ftrunc FR64:$src)),
6062             (VROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x3))>;
6063 }
6064
6065 defm ROUND  : sse41_fp_unop_rm<0x08, 0x09, "round", f128mem, VR128,
6066                                memopv4f32, memopv2f64,
6067                                int_x86_sse41_round_ps, int_x86_sse41_round_pd>;
6068 let Constraints = "$src1 = $dst" in
6069 defm ROUND  : sse41_fp_binop_rm<0x0A, 0x0B, "round",
6070                                int_x86_sse41_round_ss, int_x86_sse41_round_sd>;
6071
6072 def : Pat<(ffloor FR32:$src),
6073           (ROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x1))>;
6074 def : Pat<(f64 (ffloor FR64:$src)),
6075           (ROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x1))>;
6076 def : Pat<(f32 (fnearbyint FR32:$src)),
6077           (ROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0xC))>;
6078 def : Pat<(f64 (fnearbyint FR64:$src)),
6079           (ROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0xC))>;
6080 def : Pat<(f32 (fceil FR32:$src)),
6081           (ROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x2))>;
6082 def : Pat<(f64 (fceil FR64:$src)),
6083           (ROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x2))>;
6084 def : Pat<(f32 (frint FR32:$src)),
6085           (ROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x4))>;
6086 def : Pat<(f64 (frint FR64:$src)),
6087           (ROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x4))>;
6088 def : Pat<(f32 (ftrunc FR32:$src)),
6089           (ROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x3))>;
6090 def : Pat<(f64 (ftrunc FR64:$src)),
6091           (ROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x3))>;
6092
6093 //===----------------------------------------------------------------------===//
6094 // SSE4.1 - Packed Bit Test
6095 //===----------------------------------------------------------------------===//
6096
6097 // ptest instruction we'll lower to this in X86ISelLowering primarily from
6098 // the intel intrinsic that corresponds to this.
6099 let Defs = [EFLAGS], Predicates = [HasAVX] in {
6100 def VPTESTrr  : SS48I<0x17, MRMSrcReg, (outs), (ins VR128:$src1, VR128:$src2),
6101                 "vptest\t{$src2, $src1|$src1, $src2}",
6102                 [(set EFLAGS, (X86ptest VR128:$src1, (v4f32 VR128:$src2)))]>,
6103                 OpSize, VEX;
6104 def VPTESTrm  : SS48I<0x17, MRMSrcMem, (outs), (ins VR128:$src1, f128mem:$src2),
6105                 "vptest\t{$src2, $src1|$src1, $src2}",
6106                 [(set EFLAGS,(X86ptest VR128:$src1, (memopv4f32 addr:$src2)))]>,
6107                 OpSize, VEX;
6108
6109 def VPTESTYrr : SS48I<0x17, MRMSrcReg, (outs), (ins VR256:$src1, VR256:$src2),
6110                 "vptest\t{$src2, $src1|$src1, $src2}",
6111                 [(set EFLAGS, (X86ptest VR256:$src1, (v4i64 VR256:$src2)))]>,
6112                 OpSize, VEX;
6113 def VPTESTYrm : SS48I<0x17, MRMSrcMem, (outs), (ins VR256:$src1, i256mem:$src2),
6114                 "vptest\t{$src2, $src1|$src1, $src2}",
6115                 [(set EFLAGS,(X86ptest VR256:$src1, (memopv4i64 addr:$src2)))]>,
6116                 OpSize, VEX;
6117 }
6118
6119 let Defs = [EFLAGS] in {
6120 def PTESTrr : SS48I<0x17, MRMSrcReg, (outs), (ins VR128:$src1, VR128:$src2),
6121               "ptest\t{$src2, $src1|$src1, $src2}",
6122               [(set EFLAGS, (X86ptest VR128:$src1, (v4f32 VR128:$src2)))]>,
6123               OpSize;
6124 def PTESTrm : SS48I<0x17, MRMSrcMem, (outs), (ins VR128:$src1, f128mem:$src2),
6125               "ptest\t{$src2, $src1|$src1, $src2}",
6126               [(set EFLAGS, (X86ptest VR128:$src1, (memopv4f32 addr:$src2)))]>,
6127               OpSize;
6128 }
6129
6130 // The bit test instructions below are AVX only
6131 multiclass avx_bittest<bits<8> opc, string OpcodeStr, RegisterClass RC,
6132                        X86MemOperand x86memop, PatFrag mem_frag, ValueType vt> {
6133   def rr : SS48I<opc, MRMSrcReg, (outs), (ins RC:$src1, RC:$src2),
6134             !strconcat(OpcodeStr, "\t{$src2, $src1|$src1, $src2}"),
6135             [(set EFLAGS, (X86testp RC:$src1, (vt RC:$src2)))]>, OpSize, VEX;
6136   def rm : SS48I<opc, MRMSrcMem, (outs), (ins RC:$src1, x86memop:$src2),
6137             !strconcat(OpcodeStr, "\t{$src2, $src1|$src1, $src2}"),
6138             [(set EFLAGS, (X86testp RC:$src1, (mem_frag addr:$src2)))]>,
6139             OpSize, VEX;
6140 }
6141
6142 let Defs = [EFLAGS], Predicates = [HasAVX] in {
6143 let ExeDomain = SSEPackedSingle in {
6144 defm VTESTPS  : avx_bittest<0x0E, "vtestps", VR128, f128mem, memopv4f32, v4f32>;
6145 defm VTESTPSY : avx_bittest<0x0E, "vtestps", VR256, f256mem, memopv8f32, v8f32>;
6146 }
6147 let ExeDomain = SSEPackedDouble in {
6148 defm VTESTPD  : avx_bittest<0x0F, "vtestpd", VR128, f128mem, memopv2f64, v2f64>;
6149 defm VTESTPDY : avx_bittest<0x0F, "vtestpd", VR256, f256mem, memopv4f64, v4f64>;
6150 }
6151 }
6152
6153 //===----------------------------------------------------------------------===//
6154 // SSE4.1 - Misc Instructions
6155 //===----------------------------------------------------------------------===//
6156
6157 let Defs = [EFLAGS], Predicates = [HasPOPCNT] in {
6158   def POPCNT16rr : I<0xB8, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
6159                      "popcnt{w}\t{$src, $dst|$dst, $src}",
6160                      [(set GR16:$dst, (ctpop GR16:$src)), (implicit EFLAGS)]>,
6161                      OpSize, XS;
6162   def POPCNT16rm : I<0xB8, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
6163                      "popcnt{w}\t{$src, $dst|$dst, $src}",
6164                      [(set GR16:$dst, (ctpop (loadi16 addr:$src))),
6165                       (implicit EFLAGS)]>, OpSize, XS;
6166
6167   def POPCNT32rr : I<0xB8, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
6168                      "popcnt{l}\t{$src, $dst|$dst, $src}",
6169                      [(set GR32:$dst, (ctpop GR32:$src)), (implicit EFLAGS)]>,
6170                      XS;
6171   def POPCNT32rm : I<0xB8, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
6172                      "popcnt{l}\t{$src, $dst|$dst, $src}",
6173                      [(set GR32:$dst, (ctpop (loadi32 addr:$src))),
6174                       (implicit EFLAGS)]>, XS;
6175
6176   def POPCNT64rr : RI<0xB8, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
6177                       "popcnt{q}\t{$src, $dst|$dst, $src}",
6178                       [(set GR64:$dst, (ctpop GR64:$src)), (implicit EFLAGS)]>,
6179                       XS;
6180   def POPCNT64rm : RI<0xB8, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
6181                       "popcnt{q}\t{$src, $dst|$dst, $src}",
6182                       [(set GR64:$dst, (ctpop (loadi64 addr:$src))),
6183                        (implicit EFLAGS)]>, XS;
6184 }
6185
6186
6187
6188 // SS41I_unop_rm_int_v16 - SSE 4.1 unary operator whose type is v8i16.
6189 multiclass SS41I_unop_rm_int_v16<bits<8> opc, string OpcodeStr,
6190                                  Intrinsic IntId128> {
6191   def rr128 : SS48I<opc, MRMSrcReg, (outs VR128:$dst),
6192                     (ins VR128:$src),
6193                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
6194                     [(set VR128:$dst, (IntId128 VR128:$src))]>, OpSize;
6195   def rm128 : SS48I<opc, MRMSrcMem, (outs VR128:$dst),
6196                      (ins i128mem:$src),
6197                      !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
6198                      [(set VR128:$dst,
6199                        (IntId128
6200                         (bitconvert (memopv2i64 addr:$src))))]>, OpSize;
6201 }
6202
6203 let Predicates = [HasAVX] in
6204 defm VPHMINPOSUW : SS41I_unop_rm_int_v16 <0x41, "vphminposuw",
6205                                          int_x86_sse41_phminposuw>, VEX;
6206 defm PHMINPOSUW : SS41I_unop_rm_int_v16 <0x41, "phminposuw",
6207                                          int_x86_sse41_phminposuw>;
6208
6209 /// SS41I_binop_rm_int - Simple SSE 4.1 binary operator
6210 multiclass SS41I_binop_rm_int<bits<8> opc, string OpcodeStr,
6211                               Intrinsic IntId128, bit Is2Addr = 1> {
6212   let isCommutable = 1 in
6213   def rr : SS48I<opc, MRMSrcReg, (outs VR128:$dst),
6214        (ins VR128:$src1, VR128:$src2),
6215        !if(Is2Addr,
6216            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
6217            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
6218        [(set VR128:$dst, (IntId128 VR128:$src1, VR128:$src2))]>, OpSize;
6219   def rm : SS48I<opc, MRMSrcMem, (outs VR128:$dst),
6220        (ins VR128:$src1, i128mem:$src2),
6221        !if(Is2Addr,
6222            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
6223            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
6224        [(set VR128:$dst,
6225          (IntId128 VR128:$src1,
6226           (bitconvert (memopv2i64 addr:$src2))))]>, OpSize;
6227 }
6228
6229 /// SS41I_binop_rm_int - Simple SSE 4.1 binary operator
6230 multiclass SS41I_binop_rm_int_y<bits<8> opc, string OpcodeStr,
6231                                 Intrinsic IntId256> {
6232   let isCommutable = 1 in
6233   def Yrr : SS48I<opc, MRMSrcReg, (outs VR256:$dst),
6234        (ins VR256:$src1, VR256:$src2),
6235        !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6236        [(set VR256:$dst, (IntId256 VR256:$src1, VR256:$src2))]>, OpSize;
6237   def Yrm : SS48I<opc, MRMSrcMem, (outs VR256:$dst),
6238        (ins VR256:$src1, i256mem:$src2),
6239        !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6240        [(set VR256:$dst,
6241          (IntId256 VR256:$src1,
6242           (bitconvert (memopv4i64 addr:$src2))))]>, OpSize;
6243 }
6244
6245 let Predicates = [HasAVX] in {
6246   let isCommutable = 0 in
6247   defm VPACKUSDW : SS41I_binop_rm_int<0x2B, "vpackusdw", int_x86_sse41_packusdw,
6248                                                          0>, VEX_4V;
6249   defm VPMINSB   : SS41I_binop_rm_int<0x38, "vpminsb",   int_x86_sse41_pminsb,
6250                                                          0>, VEX_4V;
6251   defm VPMINSD   : SS41I_binop_rm_int<0x39, "vpminsd",   int_x86_sse41_pminsd,
6252                                                          0>, VEX_4V;
6253   defm VPMINUD   : SS41I_binop_rm_int<0x3B, "vpminud",   int_x86_sse41_pminud,
6254                                                          0>, VEX_4V;
6255   defm VPMINUW   : SS41I_binop_rm_int<0x3A, "vpminuw",   int_x86_sse41_pminuw,
6256                                                          0>, VEX_4V;
6257   defm VPMAXSB   : SS41I_binop_rm_int<0x3C, "vpmaxsb",   int_x86_sse41_pmaxsb,
6258                                                          0>, VEX_4V;
6259   defm VPMAXSD   : SS41I_binop_rm_int<0x3D, "vpmaxsd",   int_x86_sse41_pmaxsd,
6260                                                          0>, VEX_4V;
6261   defm VPMAXUD   : SS41I_binop_rm_int<0x3F, "vpmaxud",   int_x86_sse41_pmaxud,
6262                                                          0>, VEX_4V;
6263   defm VPMAXUW   : SS41I_binop_rm_int<0x3E, "vpmaxuw",   int_x86_sse41_pmaxuw,
6264                                                          0>, VEX_4V;
6265   defm VPMULDQ   : SS41I_binop_rm_int<0x28, "vpmuldq",   int_x86_sse41_pmuldq,
6266                                                          0>, VEX_4V;
6267 }
6268
6269 let Predicates = [HasAVX2] in {
6270   let isCommutable = 0 in
6271   defm VPACKUSDW : SS41I_binop_rm_int_y<0x2B, "vpackusdw",
6272                                         int_x86_avx2_packusdw>, VEX_4V;
6273   defm VPMINSB   : SS41I_binop_rm_int_y<0x38, "vpminsb",
6274                                         int_x86_avx2_pmins_b>, VEX_4V;
6275   defm VPMINSD   : SS41I_binop_rm_int_y<0x39, "vpminsd",
6276                                         int_x86_avx2_pmins_d>, VEX_4V;
6277   defm VPMINUD   : SS41I_binop_rm_int_y<0x3B, "vpminud",
6278                                         int_x86_avx2_pminu_d>, VEX_4V;
6279   defm VPMINUW   : SS41I_binop_rm_int_y<0x3A, "vpminuw",
6280                                         int_x86_avx2_pminu_w>, VEX_4V;
6281   defm VPMAXSB   : SS41I_binop_rm_int_y<0x3C, "vpmaxsb",
6282                                         int_x86_avx2_pmaxs_b>, VEX_4V;
6283   defm VPMAXSD   : SS41I_binop_rm_int_y<0x3D, "vpmaxsd",
6284                                         int_x86_avx2_pmaxs_d>, VEX_4V;
6285   defm VPMAXUD   : SS41I_binop_rm_int_y<0x3F, "vpmaxud",
6286                                         int_x86_avx2_pmaxu_d>, VEX_4V;
6287   defm VPMAXUW   : SS41I_binop_rm_int_y<0x3E, "vpmaxuw",
6288                                         int_x86_avx2_pmaxu_w>, VEX_4V;
6289   defm VPMULDQ   : SS41I_binop_rm_int_y<0x28, "vpmuldq",
6290                                         int_x86_avx2_pmul_dq>, VEX_4V;
6291 }
6292
6293 let Constraints = "$src1 = $dst" in {
6294   let isCommutable = 0 in
6295   defm PACKUSDW : SS41I_binop_rm_int<0x2B, "packusdw", int_x86_sse41_packusdw>;
6296   defm PMINSB   : SS41I_binop_rm_int<0x38, "pminsb",   int_x86_sse41_pminsb>;
6297   defm PMINSD   : SS41I_binop_rm_int<0x39, "pminsd",   int_x86_sse41_pminsd>;
6298   defm PMINUD   : SS41I_binop_rm_int<0x3B, "pminud",   int_x86_sse41_pminud>;
6299   defm PMINUW   : SS41I_binop_rm_int<0x3A, "pminuw",   int_x86_sse41_pminuw>;
6300   defm PMAXSB   : SS41I_binop_rm_int<0x3C, "pmaxsb",   int_x86_sse41_pmaxsb>;
6301   defm PMAXSD   : SS41I_binop_rm_int<0x3D, "pmaxsd",   int_x86_sse41_pmaxsd>;
6302   defm PMAXUD   : SS41I_binop_rm_int<0x3F, "pmaxud",   int_x86_sse41_pmaxud>;
6303   defm PMAXUW   : SS41I_binop_rm_int<0x3E, "pmaxuw",   int_x86_sse41_pmaxuw>;
6304   defm PMULDQ   : SS41I_binop_rm_int<0x28, "pmuldq",   int_x86_sse41_pmuldq>;
6305 }
6306
6307 /// SS48I_binop_rm - Simple SSE41 binary operator.
6308 multiclass SS48I_binop_rm<bits<8> opc, string OpcodeStr, SDNode OpNode,
6309                           ValueType OpVT, RegisterClass RC, PatFrag memop_frag,
6310                           X86MemOperand x86memop, bit Is2Addr = 1> {
6311   let isCommutable = 1 in
6312   def rr : SS48I<opc, MRMSrcReg, (outs RC:$dst),
6313        (ins RC:$src1, RC:$src2),
6314        !if(Is2Addr,
6315            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
6316            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
6317        [(set RC:$dst, (OpVT (OpNode RC:$src1, RC:$src2)))]>, OpSize;
6318   def rm : SS48I<opc, MRMSrcMem, (outs RC:$dst),
6319        (ins RC:$src1, x86memop:$src2),
6320        !if(Is2Addr,
6321            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
6322            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
6323        [(set RC:$dst,
6324          (OpVT (OpNode RC:$src1,
6325           (bitconvert (memop_frag addr:$src2)))))]>, OpSize;
6326 }
6327
6328 let Predicates = [HasAVX] in {
6329   defm VPMULLD  : SS48I_binop_rm<0x40, "vpmulld", mul, v4i32, VR128,
6330                                 memopv2i64, i128mem, 0>, VEX_4V;
6331   defm VPCMPEQQ : SS48I_binop_rm<0x29, "vpcmpeqq", X86pcmpeq, v2i64, VR128,
6332                                  memopv2i64, i128mem, 0>, VEX_4V;
6333 }
6334 let Predicates = [HasAVX2] in {
6335   defm VPMULLDY  : SS48I_binop_rm<0x40, "vpmulld", mul, v8i32, VR256,
6336                                   memopv4i64, i256mem, 0>, VEX_4V;
6337   defm VPCMPEQQY : SS48I_binop_rm<0x29, "vpcmpeqq", X86pcmpeq, v4i64, VR256,
6338                                   memopv4i64, i256mem, 0>, VEX_4V;
6339 }
6340
6341 let Constraints = "$src1 = $dst" in {
6342   defm PMULLD  : SS48I_binop_rm<0x40, "pmulld", mul, v4i32, VR128,
6343                                 memopv2i64, i128mem>;
6344   defm PCMPEQQ : SS48I_binop_rm<0x29, "pcmpeqq", X86pcmpeq, v2i64, VR128,
6345                                 memopv2i64, i128mem>;
6346 }
6347
6348 /// SS41I_binop_rmi_int - SSE 4.1 binary operator with 8-bit immediate
6349 multiclass SS41I_binop_rmi_int<bits<8> opc, string OpcodeStr,
6350                  Intrinsic IntId, RegisterClass RC, PatFrag memop_frag,
6351                  X86MemOperand x86memop, bit Is2Addr = 1> {
6352   let isCommutable = 1 in
6353   def rri : SS4AIi8<opc, MRMSrcReg, (outs RC:$dst),
6354         (ins RC:$src1, RC:$src2, u32u8imm:$src3),
6355         !if(Is2Addr,
6356             !strconcat(OpcodeStr,
6357                 "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6358             !strconcat(OpcodeStr,
6359                 "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6360         [(set RC:$dst, (IntId RC:$src1, RC:$src2, imm:$src3))]>,
6361         OpSize;
6362   def rmi : SS4AIi8<opc, MRMSrcMem, (outs RC:$dst),
6363         (ins RC:$src1, x86memop:$src2, u32u8imm:$src3),
6364         !if(Is2Addr,
6365             !strconcat(OpcodeStr,
6366                 "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
6367             !strconcat(OpcodeStr,
6368                 "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
6369         [(set RC:$dst,
6370           (IntId RC:$src1,
6371            (bitconvert (memop_frag addr:$src2)), imm:$src3))]>,
6372         OpSize;
6373 }
6374
6375 let Predicates = [HasAVX] in {
6376   let isCommutable = 0 in {
6377     let ExeDomain = SSEPackedSingle in {
6378     defm VBLENDPS : SS41I_binop_rmi_int<0x0C, "vblendps", int_x86_sse41_blendps,
6379                                         VR128, memopv4f32, i128mem, 0>, VEX_4V;
6380     defm VBLENDPSY : SS41I_binop_rmi_int<0x0C, "vblendps",
6381               int_x86_avx_blend_ps_256, VR256, memopv8f32, i256mem, 0>, VEX_4V;
6382     }
6383     let ExeDomain = SSEPackedDouble in {
6384     defm VBLENDPD : SS41I_binop_rmi_int<0x0D, "vblendpd", int_x86_sse41_blendpd,
6385                                         VR128, memopv2f64, i128mem, 0>, VEX_4V;
6386     defm VBLENDPDY : SS41I_binop_rmi_int<0x0D, "vblendpd",
6387               int_x86_avx_blend_pd_256, VR256, memopv4f64, i256mem, 0>, VEX_4V;
6388     }
6389   defm VPBLENDW : SS41I_binop_rmi_int<0x0E, "vpblendw", int_x86_sse41_pblendw,
6390                                       VR128, memopv2i64, i128mem, 0>, VEX_4V;
6391   defm VMPSADBW : SS41I_binop_rmi_int<0x42, "vmpsadbw", int_x86_sse41_mpsadbw,
6392                                       VR128, memopv2i64, i128mem, 0>, VEX_4V;
6393   }
6394   let ExeDomain = SSEPackedSingle in
6395   defm VDPPS : SS41I_binop_rmi_int<0x40, "vdpps", int_x86_sse41_dpps,
6396                                    VR128, memopv4f32, i128mem, 0>, VEX_4V;
6397   let ExeDomain = SSEPackedDouble in
6398   defm VDPPD : SS41I_binop_rmi_int<0x41, "vdppd", int_x86_sse41_dppd,
6399                                    VR128, memopv2f64, i128mem, 0>, VEX_4V;
6400   let ExeDomain = SSEPackedSingle in
6401   defm VDPPSY : SS41I_binop_rmi_int<0x40, "vdpps", int_x86_avx_dp_ps_256,
6402                                    VR256, memopv8f32, i256mem, 0>, VEX_4V;
6403 }
6404
6405 let Predicates = [HasAVX2] in {
6406   let isCommutable = 0 in {
6407   defm VPBLENDWY : SS41I_binop_rmi_int<0x0E, "vpblendw", int_x86_avx2_pblendw,
6408                                        VR256, memopv4i64, i256mem, 0>, VEX_4V;
6409   defm VMPSADBWY : SS41I_binop_rmi_int<0x42, "vmpsadbw", int_x86_avx2_mpsadbw,
6410                                        VR256, memopv4i64, i256mem, 0>, VEX_4V;
6411   }
6412 }
6413
6414 let Constraints = "$src1 = $dst" in {
6415   let isCommutable = 0 in {
6416   let ExeDomain = SSEPackedSingle in
6417   defm BLENDPS : SS41I_binop_rmi_int<0x0C, "blendps", int_x86_sse41_blendps,
6418                                      VR128, memopv4f32, i128mem>;
6419   let ExeDomain = SSEPackedDouble in
6420   defm BLENDPD : SS41I_binop_rmi_int<0x0D, "blendpd", int_x86_sse41_blendpd,
6421                                      VR128, memopv2f64, i128mem>;
6422   defm PBLENDW : SS41I_binop_rmi_int<0x0E, "pblendw", int_x86_sse41_pblendw,
6423                                      VR128, memopv2i64, i128mem>;
6424   defm MPSADBW : SS41I_binop_rmi_int<0x42, "mpsadbw", int_x86_sse41_mpsadbw,
6425                                      VR128, memopv2i64, i128mem>;
6426   }
6427   let ExeDomain = SSEPackedSingle in
6428   defm DPPS : SS41I_binop_rmi_int<0x40, "dpps", int_x86_sse41_dpps,
6429                                   VR128, memopv4f32, i128mem>;
6430   let ExeDomain = SSEPackedDouble in
6431   defm DPPD : SS41I_binop_rmi_int<0x41, "dppd", int_x86_sse41_dppd,
6432                                   VR128, memopv2f64, i128mem>;
6433 }
6434
6435 /// SS41I_quaternary_int_avx - AVX SSE 4.1 with 4 operators
6436 multiclass SS41I_quaternary_int_avx<bits<8> opc, string OpcodeStr,
6437                                     RegisterClass RC, X86MemOperand x86memop,
6438                                     PatFrag mem_frag, Intrinsic IntId> {
6439   def rr : Ii8<opc, MRMSrcReg, (outs RC:$dst),
6440                   (ins RC:$src1, RC:$src2, RC:$src3),
6441                   !strconcat(OpcodeStr,
6442                     "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
6443                   [(set RC:$dst, (IntId RC:$src1, RC:$src2, RC:$src3))],
6444                   SSEPackedInt>, OpSize, TA, VEX_4V, VEX_I8IMM;
6445
6446   def rm : Ii8<opc, MRMSrcMem, (outs RC:$dst),
6447                   (ins RC:$src1, x86memop:$src2, RC:$src3),
6448                   !strconcat(OpcodeStr,
6449                     "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
6450                   [(set RC:$dst,
6451                         (IntId RC:$src1, (bitconvert (mem_frag addr:$src2)),
6452                                RC:$src3))],
6453                   SSEPackedInt>, OpSize, TA, VEX_4V, VEX_I8IMM;
6454 }
6455
6456 let Predicates = [HasAVX] in {
6457 let ExeDomain = SSEPackedDouble in {
6458 defm VBLENDVPD  : SS41I_quaternary_int_avx<0x4B, "vblendvpd", VR128, i128mem,
6459                                            memopv2f64, int_x86_sse41_blendvpd>;
6460 defm VBLENDVPDY : SS41I_quaternary_int_avx<0x4B, "vblendvpd", VR256, i256mem,
6461                                          memopv4f64, int_x86_avx_blendv_pd_256>;
6462 } // ExeDomain = SSEPackedDouble
6463 let ExeDomain = SSEPackedSingle in {
6464 defm VBLENDVPS  : SS41I_quaternary_int_avx<0x4A, "vblendvps", VR128, i128mem,
6465                                            memopv4f32, int_x86_sse41_blendvps>;
6466 defm VBLENDVPSY : SS41I_quaternary_int_avx<0x4A, "vblendvps", VR256, i256mem,
6467                                          memopv8f32, int_x86_avx_blendv_ps_256>;
6468 } // ExeDomain = SSEPackedSingle
6469 defm VPBLENDVB  : SS41I_quaternary_int_avx<0x4C, "vpblendvb", VR128, i128mem,
6470                                            memopv2i64, int_x86_sse41_pblendvb>;
6471 }
6472
6473 let Predicates = [HasAVX2] in {
6474 defm VPBLENDVBY : SS41I_quaternary_int_avx<0x4C, "vpblendvb", VR256, i256mem,
6475                                            memopv4i64, int_x86_avx2_pblendvb>;
6476 }
6477
6478 let Predicates = [HasAVX] in {
6479   def : Pat<(v16i8 (vselect (v16i8 VR128:$mask), (v16i8 VR128:$src1),
6480                             (v16i8 VR128:$src2))),
6481             (VPBLENDVBrr VR128:$src2, VR128:$src1, VR128:$mask)>;
6482   def : Pat<(v4i32 (vselect (v4i32 VR128:$mask), (v4i32 VR128:$src1),
6483                             (v4i32 VR128:$src2))),
6484             (VBLENDVPSrr VR128:$src2, VR128:$src1, VR128:$mask)>;
6485   def : Pat<(v4f32 (vselect (v4i32 VR128:$mask), (v4f32 VR128:$src1),
6486                             (v4f32 VR128:$src2))),
6487             (VBLENDVPSrr VR128:$src2, VR128:$src1, VR128:$mask)>;
6488   def : Pat<(v2i64 (vselect (v2i64 VR128:$mask), (v2i64 VR128:$src1),
6489                             (v2i64 VR128:$src2))),
6490             (VBLENDVPDrr VR128:$src2, VR128:$src1, VR128:$mask)>;
6491   def : Pat<(v2f64 (vselect (v2i64 VR128:$mask), (v2f64 VR128:$src1),
6492                             (v2f64 VR128:$src2))),
6493             (VBLENDVPDrr VR128:$src2, VR128:$src1, VR128:$mask)>;
6494   def : Pat<(v8i32 (vselect (v8i32 VR256:$mask), (v8i32 VR256:$src1),
6495                             (v8i32 VR256:$src2))),
6496             (VBLENDVPSYrr VR256:$src2, VR256:$src1, VR256:$mask)>;
6497   def : Pat<(v8f32 (vselect (v8i32 VR256:$mask), (v8f32 VR256:$src1),
6498                             (v8f32 VR256:$src2))),
6499             (VBLENDVPSYrr VR256:$src2, VR256:$src1, VR256:$mask)>;
6500   def : Pat<(v4i64 (vselect (v4i64 VR256:$mask), (v4i64 VR256:$src1),
6501                             (v4i64 VR256:$src2))),
6502             (VBLENDVPDYrr VR256:$src2, VR256:$src1, VR256:$mask)>;
6503   def : Pat<(v4f64 (vselect (v4i64 VR256:$mask), (v4f64 VR256:$src1),
6504                             (v4f64 VR256:$src2))),
6505             (VBLENDVPDYrr VR256:$src2, VR256:$src1, VR256:$mask)>;
6506 }
6507
6508 let Predicates = [HasAVX2] in {
6509   def : Pat<(v32i8 (vselect (v32i8 VR256:$mask), (v32i8 VR256:$src1),
6510                             (v32i8 VR256:$src2))),
6511             (VPBLENDVBYrr VR256:$src2, VR256:$src1, VR256:$mask)>;
6512 }
6513
6514 /// SS41I_ternary_int - SSE 4.1 ternary operator
6515 let Uses = [XMM0], Constraints = "$src1 = $dst" in {
6516   multiclass SS41I_ternary_int<bits<8> opc, string OpcodeStr, PatFrag mem_frag,
6517                                Intrinsic IntId> {
6518     def rr0 : SS48I<opc, MRMSrcReg, (outs VR128:$dst),
6519                     (ins VR128:$src1, VR128:$src2),
6520                     !strconcat(OpcodeStr,
6521                      "\t{$src2, $dst|$dst, $src2}"),
6522                     [(set VR128:$dst, (IntId VR128:$src1, VR128:$src2, XMM0))]>,
6523                     OpSize;
6524
6525     def rm0 : SS48I<opc, MRMSrcMem, (outs VR128:$dst),
6526                     (ins VR128:$src1, i128mem:$src2),
6527                     !strconcat(OpcodeStr,
6528                      "\t{$src2, $dst|$dst, $src2}"),
6529                     [(set VR128:$dst,
6530                       (IntId VR128:$src1,
6531                        (bitconvert (mem_frag addr:$src2)), XMM0))]>, OpSize;
6532   }
6533 }
6534
6535 let ExeDomain = SSEPackedDouble in
6536 defm BLENDVPD : SS41I_ternary_int<0x15, "blendvpd", memopv2f64,
6537                                   int_x86_sse41_blendvpd>;
6538 let ExeDomain = SSEPackedSingle in
6539 defm BLENDVPS : SS41I_ternary_int<0x14, "blendvps", memopv4f32,
6540                                   int_x86_sse41_blendvps>;
6541 defm PBLENDVB : SS41I_ternary_int<0x10, "pblendvb", memopv2i64,
6542                                   int_x86_sse41_pblendvb>;
6543
6544 let Predicates = [HasSSE41] in {
6545   def : Pat<(v16i8 (vselect (v16i8 XMM0), (v16i8 VR128:$src1),
6546                             (v16i8 VR128:$src2))),
6547             (PBLENDVBrr0 VR128:$src2, VR128:$src1)>;
6548   def : Pat<(v4i32 (vselect (v4i32 XMM0), (v4i32 VR128:$src1),
6549                             (v4i32 VR128:$src2))),
6550             (BLENDVPSrr0 VR128:$src2, VR128:$src1)>;
6551   def : Pat<(v4f32 (vselect (v4i32 XMM0), (v4f32 VR128:$src1),
6552                             (v4f32 VR128:$src2))),
6553             (BLENDVPSrr0 VR128:$src2, VR128:$src1)>;
6554   def : Pat<(v2i64 (vselect (v2i64 XMM0), (v2i64 VR128:$src1),
6555                             (v2i64 VR128:$src2))),
6556             (BLENDVPDrr0 VR128:$src2, VR128:$src1)>;
6557   def : Pat<(v2f64 (vselect (v2i64 XMM0), (v2f64 VR128:$src1),
6558                             (v2f64 VR128:$src2))),
6559             (BLENDVPDrr0 VR128:$src2, VR128:$src1)>;
6560 }
6561
6562 let Predicates = [HasAVX] in
6563 def VMOVNTDQArm : SS48I<0x2A, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
6564                        "vmovntdqa\t{$src, $dst|$dst, $src}",
6565                        [(set VR128:$dst, (int_x86_sse41_movntdqa addr:$src))]>,
6566                        OpSize, VEX;
6567 let Predicates = [HasAVX2] in
6568 def VMOVNTDQAYrm : SS48I<0x2A, MRMSrcMem, (outs VR256:$dst), (ins i256mem:$src),
6569                          "vmovntdqa\t{$src, $dst|$dst, $src}",
6570                          [(set VR256:$dst, (int_x86_avx2_movntdqa addr:$src))]>,
6571                          OpSize, VEX;
6572 def MOVNTDQArm : SS48I<0x2A, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
6573                        "movntdqa\t{$src, $dst|$dst, $src}",
6574                        [(set VR128:$dst, (int_x86_sse41_movntdqa addr:$src))]>,
6575                        OpSize;
6576
6577 //===----------------------------------------------------------------------===//
6578 // SSE4.2 - Compare Instructions
6579 //===----------------------------------------------------------------------===//
6580
6581 /// SS42I_binop_rm - Simple SSE 4.2 binary operator
6582 multiclass SS42I_binop_rm<bits<8> opc, string OpcodeStr, SDNode OpNode,
6583                           ValueType OpVT, RegisterClass RC, PatFrag memop_frag,
6584                           X86MemOperand x86memop, bit Is2Addr = 1> {
6585   def rr : SS428I<opc, MRMSrcReg, (outs RC:$dst),
6586        (ins RC:$src1, RC:$src2),
6587        !if(Is2Addr,
6588            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
6589            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
6590        [(set RC:$dst, (OpVT (OpNode RC:$src1, RC:$src2)))]>,
6591        OpSize;
6592   def rm : SS428I<opc, MRMSrcMem, (outs RC:$dst),
6593        (ins RC:$src1, x86memop:$src2),
6594        !if(Is2Addr,
6595            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
6596            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
6597        [(set RC:$dst,
6598          (OpVT (OpNode RC:$src1, (memop_frag addr:$src2))))]>, OpSize;
6599 }
6600
6601 let Predicates = [HasAVX] in
6602   defm VPCMPGTQ : SS42I_binop_rm<0x37, "vpcmpgtq", X86pcmpgt, v2i64, VR128,
6603                                  memopv2i64, i128mem, 0>, VEX_4V;
6604
6605 let Predicates = [HasAVX2] in
6606   defm VPCMPGTQY : SS42I_binop_rm<0x37, "vpcmpgtq", X86pcmpgt, v4i64, VR256,
6607                                   memopv4i64, i256mem, 0>, VEX_4V;
6608
6609 let Constraints = "$src1 = $dst" in
6610   defm PCMPGTQ : SS42I_binop_rm<0x37, "pcmpgtq", X86pcmpgt, v2i64, VR128,
6611                                 memopv2i64, i128mem>;
6612
6613 //===----------------------------------------------------------------------===//
6614 // SSE4.2 - String/text Processing Instructions
6615 //===----------------------------------------------------------------------===//
6616
6617 // Packed Compare Implicit Length Strings, Return Mask
6618 multiclass pseudo_pcmpistrm<string asm> {
6619   def REG : PseudoI<(outs VR128:$dst),
6620                     (ins VR128:$src1, VR128:$src2, i8imm:$src3),
6621     [(set VR128:$dst, (int_x86_sse42_pcmpistrm128 VR128:$src1, VR128:$src2,
6622                                                   imm:$src3))]>;
6623   def MEM : PseudoI<(outs VR128:$dst),
6624                     (ins VR128:$src1, i128mem:$src2, i8imm:$src3),
6625     [(set VR128:$dst, (int_x86_sse42_pcmpistrm128
6626                        VR128:$src1, (load addr:$src2), imm:$src3))]>;
6627 }
6628
6629 let Defs = [EFLAGS], usesCustomInserter = 1 in {
6630   defm PCMPISTRM128 : pseudo_pcmpistrm<"#PCMPISTRM128">, Requires<[HasSSE42]>;
6631   defm VPCMPISTRM128 : pseudo_pcmpistrm<"#VPCMPISTRM128">, Requires<[HasAVX]>;
6632 }
6633
6634 let Defs = [XMM0, EFLAGS], neverHasSideEffects = 1, Predicates = [HasAVX] in {
6635   def VPCMPISTRM128rr : SS42AI<0x62, MRMSrcReg, (outs),
6636       (ins VR128:$src1, VR128:$src2, i8imm:$src3),
6637       "vpcmpistrm\t{$src3, $src2, $src1|$src1, $src2, $src3}", []>, OpSize, VEX;
6638   let mayLoad = 1 in
6639   def VPCMPISTRM128rm : SS42AI<0x62, MRMSrcMem, (outs),
6640       (ins VR128:$src1, i128mem:$src2, i8imm:$src3),
6641       "vpcmpistrm\t{$src3, $src2, $src1|$src1, $src2, $src3}", []>, OpSize, VEX;
6642 }
6643
6644 let Defs = [XMM0, EFLAGS], neverHasSideEffects = 1 in {
6645   def PCMPISTRM128rr : SS42AI<0x62, MRMSrcReg, (outs),
6646       (ins VR128:$src1, VR128:$src2, i8imm:$src3),
6647       "pcmpistrm\t{$src3, $src2, $src1|$src1, $src2, $src3}", []>, OpSize;
6648   let mayLoad = 1 in
6649   def PCMPISTRM128rm : SS42AI<0x62, MRMSrcMem, (outs),
6650       (ins VR128:$src1, i128mem:$src2, i8imm:$src3),
6651       "pcmpistrm\t{$src3, $src2, $src1|$src1, $src2, $src3}", []>, OpSize;
6652 }
6653
6654 // Packed Compare Explicit Length Strings, Return Mask
6655 multiclass pseudo_pcmpestrm<string asm> {
6656   def REG : PseudoI<(outs VR128:$dst),
6657                     (ins VR128:$src1, VR128:$src3, i8imm:$src5),
6658     [(set VR128:$dst, (int_x86_sse42_pcmpestrm128
6659                        VR128:$src1, EAX, VR128:$src3, EDX, imm:$src5))]>;
6660   def MEM : PseudoI<(outs VR128:$dst),
6661                     (ins VR128:$src1, i128mem:$src3, i8imm:$src5),
6662     [(set VR128:$dst, (int_x86_sse42_pcmpestrm128
6663                        VR128:$src1, EAX, (load addr:$src3), EDX, imm:$src5))]>;
6664 }
6665
6666 let Defs = [EFLAGS], Uses = [EAX, EDX], usesCustomInserter = 1 in {
6667   defm PCMPESTRM128 : pseudo_pcmpestrm<"#PCMPESTRM128">, Requires<[HasSSE42]>;
6668   defm VPCMPESTRM128 : pseudo_pcmpestrm<"#VPCMPESTRM128">, Requires<[HasAVX]>;
6669 }
6670
6671 let Predicates = [HasAVX],
6672     Defs = [XMM0, EFLAGS], Uses = [EAX, EDX], neverHasSideEffects = 1 in {
6673   def VPCMPESTRM128rr : SS42AI<0x60, MRMSrcReg, (outs),
6674       (ins VR128:$src1, VR128:$src3, i8imm:$src5),
6675       "vpcmpestrm\t{$src5, $src3, $src1|$src1, $src3, $src5}", []>, OpSize, VEX;
6676   let mayLoad = 1 in
6677   def VPCMPESTRM128rm : SS42AI<0x60, MRMSrcMem, (outs),
6678       (ins VR128:$src1, i128mem:$src3, i8imm:$src5),
6679       "vpcmpestrm\t{$src5, $src3, $src1|$src1, $src3, $src5}", []>, OpSize, VEX;
6680 }
6681
6682 let Defs = [XMM0, EFLAGS], Uses = [EAX, EDX], neverHasSideEffects = 1 in {
6683   def PCMPESTRM128rr : SS42AI<0x60, MRMSrcReg, (outs),
6684       (ins VR128:$src1, VR128:$src3, i8imm:$src5),
6685       "pcmpestrm\t{$src5, $src3, $src1|$src1, $src3, $src5}", []>, OpSize;
6686   let mayLoad = 1 in
6687   def PCMPESTRM128rm : SS42AI<0x60, MRMSrcMem, (outs),
6688       (ins VR128:$src1, i128mem:$src3, i8imm:$src5),
6689       "pcmpestrm\t{$src5, $src3, $src1|$src1, $src3, $src5}", []>, OpSize;
6690 }
6691
6692 // Packed Compare Implicit Length Strings, Return Index
6693 let Defs = [ECX, EFLAGS] in {
6694   multiclass SS42AI_pcmpistri<Intrinsic IntId128, string asm = "pcmpistri"> {
6695     def rr : SS42AI<0x63, MRMSrcReg, (outs),
6696       (ins VR128:$src1, VR128:$src2, i8imm:$src3),
6697       !strconcat(asm, "\t{$src3, $src2, $src1|$src1, $src2, $src3}"),
6698       [(set ECX, (IntId128 VR128:$src1, VR128:$src2, imm:$src3)),
6699        (implicit EFLAGS)]>, OpSize;
6700     def rm : SS42AI<0x63, MRMSrcMem, (outs),
6701       (ins VR128:$src1, i128mem:$src2, i8imm:$src3),
6702       !strconcat(asm, "\t{$src3, $src2, $src1|$src1, $src2, $src3}"),
6703       [(set ECX, (IntId128 VR128:$src1, (load addr:$src2), imm:$src3)),
6704        (implicit EFLAGS)]>, OpSize;
6705   }
6706 }
6707
6708 let Predicates = [HasAVX] in {
6709 defm VPCMPISTRI  : SS42AI_pcmpistri<int_x86_sse42_pcmpistri128, "vpcmpistri">,
6710                                     VEX;
6711 defm VPCMPISTRIA : SS42AI_pcmpistri<int_x86_sse42_pcmpistria128, "vpcmpistri">,
6712                                     VEX;
6713 defm VPCMPISTRIC : SS42AI_pcmpistri<int_x86_sse42_pcmpistric128, "vpcmpistri">,
6714                                     VEX;
6715 defm VPCMPISTRIO : SS42AI_pcmpistri<int_x86_sse42_pcmpistrio128, "vpcmpistri">,
6716                                     VEX;
6717 defm VPCMPISTRIS : SS42AI_pcmpistri<int_x86_sse42_pcmpistris128, "vpcmpistri">,
6718                                     VEX;
6719 defm VPCMPISTRIZ : SS42AI_pcmpistri<int_x86_sse42_pcmpistriz128, "vpcmpistri">,
6720                                     VEX;
6721 }
6722
6723 defm PCMPISTRI  : SS42AI_pcmpistri<int_x86_sse42_pcmpistri128>;
6724 defm PCMPISTRIA : SS42AI_pcmpistri<int_x86_sse42_pcmpistria128>;
6725 defm PCMPISTRIC : SS42AI_pcmpistri<int_x86_sse42_pcmpistric128>;
6726 defm PCMPISTRIO : SS42AI_pcmpistri<int_x86_sse42_pcmpistrio128>;
6727 defm PCMPISTRIS : SS42AI_pcmpistri<int_x86_sse42_pcmpistris128>;
6728 defm PCMPISTRIZ : SS42AI_pcmpistri<int_x86_sse42_pcmpistriz128>;
6729
6730 // Packed Compare Explicit Length Strings, Return Index
6731 let Defs = [ECX, EFLAGS], Uses = [EAX, EDX] in {
6732   multiclass SS42AI_pcmpestri<Intrinsic IntId128, string asm = "pcmpestri"> {
6733     def rr : SS42AI<0x61, MRMSrcReg, (outs),
6734       (ins VR128:$src1, VR128:$src3, i8imm:$src5),
6735       !strconcat(asm, "\t{$src5, $src3, $src1|$src1, $src3, $src5}"),
6736       [(set ECX, (IntId128 VR128:$src1, EAX, VR128:$src3, EDX, imm:$src5)),
6737        (implicit EFLAGS)]>, OpSize;
6738     def rm : SS42AI<0x61, MRMSrcMem, (outs),
6739       (ins VR128:$src1, i128mem:$src3, i8imm:$src5),
6740       !strconcat(asm, "\t{$src5, $src3, $src1|$src1, $src3, $src5}"),
6741        [(set ECX,
6742              (IntId128 VR128:$src1, EAX, (load addr:$src3), EDX, imm:$src5)),
6743         (implicit EFLAGS)]>, OpSize;
6744   }
6745 }
6746
6747 let Predicates = [HasAVX] in {
6748 defm VPCMPESTRI  : SS42AI_pcmpestri<int_x86_sse42_pcmpestri128, "vpcmpestri">,
6749                                     VEX;
6750 defm VPCMPESTRIA : SS42AI_pcmpestri<int_x86_sse42_pcmpestria128, "vpcmpestri">,
6751                                     VEX;
6752 defm VPCMPESTRIC : SS42AI_pcmpestri<int_x86_sse42_pcmpestric128, "vpcmpestri">,
6753                                     VEX;
6754 defm VPCMPESTRIO : SS42AI_pcmpestri<int_x86_sse42_pcmpestrio128, "vpcmpestri">,
6755                                     VEX;
6756 defm VPCMPESTRIS : SS42AI_pcmpestri<int_x86_sse42_pcmpestris128, "vpcmpestri">,
6757                                     VEX;
6758 defm VPCMPESTRIZ : SS42AI_pcmpestri<int_x86_sse42_pcmpestriz128, "vpcmpestri">,
6759                                     VEX;
6760 }
6761
6762 defm PCMPESTRI  : SS42AI_pcmpestri<int_x86_sse42_pcmpestri128>;
6763 defm PCMPESTRIA : SS42AI_pcmpestri<int_x86_sse42_pcmpestria128>;
6764 defm PCMPESTRIC : SS42AI_pcmpestri<int_x86_sse42_pcmpestric128>;
6765 defm PCMPESTRIO : SS42AI_pcmpestri<int_x86_sse42_pcmpestrio128>;
6766 defm PCMPESTRIS : SS42AI_pcmpestri<int_x86_sse42_pcmpestris128>;
6767 defm PCMPESTRIZ : SS42AI_pcmpestri<int_x86_sse42_pcmpestriz128>;
6768
6769 //===----------------------------------------------------------------------===//
6770 // SSE4.2 - CRC Instructions
6771 //===----------------------------------------------------------------------===//
6772
6773 // No CRC instructions have AVX equivalents
6774
6775 // crc intrinsic instruction
6776 // This set of instructions are only rm, the only difference is the size
6777 // of r and m.
6778 let Constraints = "$src1 = $dst" in {
6779   def CRC32r32m8  : SS42FI<0xF0, MRMSrcMem, (outs GR32:$dst),
6780                       (ins GR32:$src1, i8mem:$src2),
6781                       "crc32{b} \t{$src2, $src1|$src1, $src2}",
6782                        [(set GR32:$dst,
6783                          (int_x86_sse42_crc32_32_8 GR32:$src1,
6784                          (load addr:$src2)))]>;
6785   def CRC32r32r8  : SS42FI<0xF0, MRMSrcReg, (outs GR32:$dst),
6786                       (ins GR32:$src1, GR8:$src2),
6787                       "crc32{b} \t{$src2, $src1|$src1, $src2}",
6788                        [(set GR32:$dst,
6789                          (int_x86_sse42_crc32_32_8 GR32:$src1, GR8:$src2))]>;
6790   def CRC32r32m16  : SS42FI<0xF1, MRMSrcMem, (outs GR32:$dst),
6791                       (ins GR32:$src1, i16mem:$src2),
6792                       "crc32{w} \t{$src2, $src1|$src1, $src2}",
6793                        [(set GR32:$dst,
6794                          (int_x86_sse42_crc32_32_16 GR32:$src1,
6795                          (load addr:$src2)))]>,
6796                          OpSize;
6797   def CRC32r32r16  : SS42FI<0xF1, MRMSrcReg, (outs GR32:$dst),
6798                       (ins GR32:$src1, GR16:$src2),
6799                       "crc32{w} \t{$src2, $src1|$src1, $src2}",
6800                        [(set GR32:$dst,
6801                          (int_x86_sse42_crc32_32_16 GR32:$src1, GR16:$src2))]>,
6802                          OpSize;
6803   def CRC32r32m32  : SS42FI<0xF1, MRMSrcMem, (outs GR32:$dst),
6804                       (ins GR32:$src1, i32mem:$src2),
6805                       "crc32{l} \t{$src2, $src1|$src1, $src2}",
6806                        [(set GR32:$dst,
6807                          (int_x86_sse42_crc32_32_32 GR32:$src1,
6808                          (load addr:$src2)))]>;
6809   def CRC32r32r32  : SS42FI<0xF1, MRMSrcReg, (outs GR32:$dst),
6810                       (ins GR32:$src1, GR32:$src2),
6811                       "crc32{l} \t{$src2, $src1|$src1, $src2}",
6812                        [(set GR32:$dst,
6813                          (int_x86_sse42_crc32_32_32 GR32:$src1, GR32:$src2))]>;
6814   def CRC32r64m8  : SS42FI<0xF0, MRMSrcMem, (outs GR64:$dst),
6815                       (ins GR64:$src1, i8mem:$src2),
6816                       "crc32{b} \t{$src2, $src1|$src1, $src2}",
6817                        [(set GR64:$dst,
6818                          (int_x86_sse42_crc32_64_8 GR64:$src1,
6819                          (load addr:$src2)))]>,
6820                          REX_W;
6821   def CRC32r64r8  : SS42FI<0xF0, MRMSrcReg, (outs GR64:$dst),
6822                       (ins GR64:$src1, GR8:$src2),
6823                       "crc32{b} \t{$src2, $src1|$src1, $src2}",
6824                        [(set GR64:$dst,
6825                          (int_x86_sse42_crc32_64_8 GR64:$src1, GR8:$src2))]>,
6826                          REX_W;
6827   def CRC32r64m64  : SS42FI<0xF1, MRMSrcMem, (outs GR64:$dst),
6828                       (ins GR64:$src1, i64mem:$src2),
6829                       "crc32{q} \t{$src2, $src1|$src1, $src2}",
6830                        [(set GR64:$dst,
6831                          (int_x86_sse42_crc32_64_64 GR64:$src1,
6832                          (load addr:$src2)))]>,
6833                          REX_W;
6834   def CRC32r64r64  : SS42FI<0xF1, MRMSrcReg, (outs GR64:$dst),
6835                       (ins GR64:$src1, GR64:$src2),
6836                       "crc32{q} \t{$src2, $src1|$src1, $src2}",
6837                        [(set GR64:$dst,
6838                          (int_x86_sse42_crc32_64_64 GR64:$src1, GR64:$src2))]>,
6839                          REX_W;
6840 }
6841
6842 //===----------------------------------------------------------------------===//
6843 // AES-NI Instructions
6844 //===----------------------------------------------------------------------===//
6845
6846 multiclass AESI_binop_rm_int<bits<8> opc, string OpcodeStr,
6847                               Intrinsic IntId128, bit Is2Addr = 1> {
6848   def rr : AES8I<opc, MRMSrcReg, (outs VR128:$dst),
6849        (ins VR128:$src1, VR128:$src2),
6850        !if(Is2Addr,
6851            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
6852            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
6853        [(set VR128:$dst, (IntId128 VR128:$src1, VR128:$src2))]>,
6854        OpSize;
6855   def rm : AES8I<opc, MRMSrcMem, (outs VR128:$dst),
6856        (ins VR128:$src1, i128mem:$src2),
6857        !if(Is2Addr,
6858            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
6859            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
6860        [(set VR128:$dst,
6861          (IntId128 VR128:$src1, (memopv2i64 addr:$src2)))]>, OpSize;
6862 }
6863
6864 // Perform One Round of an AES Encryption/Decryption Flow
6865 let Predicates = [HasAVX, HasAES] in {
6866   defm VAESENC          : AESI_binop_rm_int<0xDC, "vaesenc",
6867                          int_x86_aesni_aesenc, 0>, VEX_4V;
6868   defm VAESENCLAST      : AESI_binop_rm_int<0xDD, "vaesenclast",
6869                          int_x86_aesni_aesenclast, 0>, VEX_4V;
6870   defm VAESDEC          : AESI_binop_rm_int<0xDE, "vaesdec",
6871                          int_x86_aesni_aesdec, 0>, VEX_4V;
6872   defm VAESDECLAST      : AESI_binop_rm_int<0xDF, "vaesdeclast",
6873                          int_x86_aesni_aesdeclast, 0>, VEX_4V;
6874 }
6875
6876 let Constraints = "$src1 = $dst" in {
6877   defm AESENC          : AESI_binop_rm_int<0xDC, "aesenc",
6878                          int_x86_aesni_aesenc>;
6879   defm AESENCLAST      : AESI_binop_rm_int<0xDD, "aesenclast",
6880                          int_x86_aesni_aesenclast>;
6881   defm AESDEC          : AESI_binop_rm_int<0xDE, "aesdec",
6882                          int_x86_aesni_aesdec>;
6883   defm AESDECLAST      : AESI_binop_rm_int<0xDF, "aesdeclast",
6884                          int_x86_aesni_aesdeclast>;
6885 }
6886
6887 // Perform the AES InvMixColumn Transformation
6888 let Predicates = [HasAVX, HasAES] in {
6889   def VAESIMCrr : AES8I<0xDB, MRMSrcReg, (outs VR128:$dst),
6890       (ins VR128:$src1),
6891       "vaesimc\t{$src1, $dst|$dst, $src1}",
6892       [(set VR128:$dst,
6893         (int_x86_aesni_aesimc VR128:$src1))]>,
6894       OpSize, VEX;
6895   def VAESIMCrm : AES8I<0xDB, MRMSrcMem, (outs VR128:$dst),
6896       (ins i128mem:$src1),
6897       "vaesimc\t{$src1, $dst|$dst, $src1}",
6898       [(set VR128:$dst, (int_x86_aesni_aesimc (memopv2i64 addr:$src1)))]>,
6899       OpSize, VEX;
6900 }
6901 def AESIMCrr : AES8I<0xDB, MRMSrcReg, (outs VR128:$dst),
6902   (ins VR128:$src1),
6903   "aesimc\t{$src1, $dst|$dst, $src1}",
6904   [(set VR128:$dst,
6905     (int_x86_aesni_aesimc VR128:$src1))]>,
6906   OpSize;
6907 def AESIMCrm : AES8I<0xDB, MRMSrcMem, (outs VR128:$dst),
6908   (ins i128mem:$src1),
6909   "aesimc\t{$src1, $dst|$dst, $src1}",
6910   [(set VR128:$dst, (int_x86_aesni_aesimc (memopv2i64 addr:$src1)))]>,
6911   OpSize;
6912
6913 // AES Round Key Generation Assist
6914 let Predicates = [HasAVX, HasAES] in {
6915   def VAESKEYGENASSIST128rr : AESAI<0xDF, MRMSrcReg, (outs VR128:$dst),
6916       (ins VR128:$src1, i8imm:$src2),
6917       "vaeskeygenassist\t{$src2, $src1, $dst|$dst, $src1, $src2}",
6918       [(set VR128:$dst,
6919         (int_x86_aesni_aeskeygenassist VR128:$src1, imm:$src2))]>,
6920       OpSize, VEX;
6921   def VAESKEYGENASSIST128rm : AESAI<0xDF, MRMSrcMem, (outs VR128:$dst),
6922       (ins i128mem:$src1, i8imm:$src2),
6923       "vaeskeygenassist\t{$src2, $src1, $dst|$dst, $src1, $src2}",
6924       [(set VR128:$dst,
6925         (int_x86_aesni_aeskeygenassist (memopv2i64 addr:$src1), imm:$src2))]>,
6926       OpSize, VEX;
6927 }
6928 def AESKEYGENASSIST128rr : AESAI<0xDF, MRMSrcReg, (outs VR128:$dst),
6929   (ins VR128:$src1, i8imm:$src2),
6930   "aeskeygenassist\t{$src2, $src1, $dst|$dst, $src1, $src2}",
6931   [(set VR128:$dst,
6932     (int_x86_aesni_aeskeygenassist VR128:$src1, imm:$src2))]>,
6933   OpSize;
6934 def AESKEYGENASSIST128rm : AESAI<0xDF, MRMSrcMem, (outs VR128:$dst),
6935   (ins i128mem:$src1, i8imm:$src2),
6936   "aeskeygenassist\t{$src2, $src1, $dst|$dst, $src1, $src2}",
6937   [(set VR128:$dst,
6938     (int_x86_aesni_aeskeygenassist (memopv2i64 addr:$src1), imm:$src2))]>,
6939   OpSize;
6940
6941 //===----------------------------------------------------------------------===//
6942 // CLMUL Instructions
6943 //===----------------------------------------------------------------------===//
6944
6945 // Carry-less Multiplication instructions
6946 let neverHasSideEffects = 1 in {
6947 // AVX carry-less Multiplication instructions
6948 def VPCLMULQDQrr : AVXCLMULIi8<0x44, MRMSrcReg, (outs VR128:$dst),
6949            (ins VR128:$src1, VR128:$src2, i8imm:$src3),
6950            "vpclmulqdq\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
6951            []>;
6952
6953 let mayLoad = 1 in
6954 def VPCLMULQDQrm : AVXCLMULIi8<0x44, MRMSrcMem, (outs VR128:$dst),
6955            (ins VR128:$src1, i128mem:$src2, i8imm:$src3),
6956            "vpclmulqdq\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
6957            []>;
6958
6959 let Constraints = "$src1 = $dst" in {
6960 def PCLMULQDQrr : CLMULIi8<0x44, MRMSrcReg, (outs VR128:$dst),
6961            (ins VR128:$src1, VR128:$src2, i8imm:$src3),
6962            "pclmulqdq\t{$src3, $src2, $dst|$dst, $src2, $src3}",
6963            []>;
6964
6965 let mayLoad = 1 in
6966 def PCLMULQDQrm : CLMULIi8<0x44, MRMSrcMem, (outs VR128:$dst),
6967            (ins VR128:$src1, i128mem:$src2, i8imm:$src3),
6968            "pclmulqdq\t{$src3, $src2, $dst|$dst, $src2, $src3}",
6969            []>;
6970 } // Constraints = "$src1 = $dst"
6971 } // neverHasSideEffects = 1
6972
6973
6974 multiclass pclmul_alias<string asm, int immop> {
6975   def : InstAlias<!strconcat("pclmul", asm, 
6976                            "dq {$src, $dst|$dst, $src}"),
6977                   (PCLMULQDQrr VR128:$dst, VR128:$src, immop)>;
6978
6979   def : InstAlias<!strconcat("pclmul", asm, 
6980                              "dq {$src, $dst|$dst, $src}"),
6981                   (PCLMULQDQrm VR128:$dst, i128mem:$src, immop)>;
6982
6983   def : InstAlias<!strconcat("vpclmul", asm, 
6984                              "dq {$src2, $src1, $dst|$dst, $src1, $src2}"),
6985                   (VPCLMULQDQrr VR128:$dst, VR128:$src1, VR128:$src2, immop)>;
6986
6987   def : InstAlias<!strconcat("vpclmul", asm, 
6988                              "dq {$src2, $src1, $dst|$dst, $src1, $src2}"),
6989                   (VPCLMULQDQrm VR128:$dst, VR128:$src1, i128mem:$src2, immop)>;
6990 }
6991 defm : pclmul_alias<"hqhq", 0x11>;
6992 defm : pclmul_alias<"hqlq", 0x01>;
6993 defm : pclmul_alias<"lqhq", 0x10>;
6994 defm : pclmul_alias<"lqlq", 0x00>;
6995
6996 //===----------------------------------------------------------------------===//
6997 // AVX Instructions
6998 //===----------------------------------------------------------------------===//
6999
7000 //===----------------------------------------------------------------------===//
7001 // VBROADCAST - Load from memory and broadcast to all elements of the
7002 //              destination operand
7003 //
7004 class avx_broadcast<bits<8> opc, string OpcodeStr, RegisterClass RC,
7005                     X86MemOperand x86memop, Intrinsic Int> :
7006   AVX8I<opc, MRMSrcMem, (outs RC:$dst), (ins x86memop:$src),
7007         !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
7008         [(set RC:$dst, (Int addr:$src))]>, VEX;
7009
7010 // AVX2 adds register forms
7011 class avx2_broadcast_reg<bits<8> opc, string OpcodeStr, RegisterClass RC,
7012                          Intrinsic Int> :
7013   AVX28I<opc, MRMSrcReg, (outs RC:$dst), (ins VR128:$src),
7014          !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
7015          [(set RC:$dst, (Int VR128:$src))]>, VEX;
7016
7017 let ExeDomain = SSEPackedSingle in {
7018   def VBROADCASTSSrm  : avx_broadcast<0x18, "vbroadcastss", VR128, f32mem,
7019                                       int_x86_avx_vbroadcast_ss>;
7020   def VBROADCASTSSYrm : avx_broadcast<0x18, "vbroadcastss", VR256, f32mem,
7021                                       int_x86_avx_vbroadcast_ss_256>;
7022 }
7023 let ExeDomain = SSEPackedDouble in
7024 def VBROADCASTSDrm  : avx_broadcast<0x19, "vbroadcastsd", VR256, f64mem,
7025                                     int_x86_avx_vbroadcast_sd_256>;
7026 def VBROADCASTF128 : avx_broadcast<0x1A, "vbroadcastf128", VR256, f128mem,
7027                                    int_x86_avx_vbroadcastf128_pd_256>;
7028
7029 let ExeDomain = SSEPackedSingle in {
7030   def VBROADCASTSSrr  : avx2_broadcast_reg<0x18, "vbroadcastss", VR128,
7031                                            int_x86_avx2_vbroadcast_ss_ps>;
7032   def VBROADCASTSSYrr : avx2_broadcast_reg<0x18, "vbroadcastss", VR256,
7033                                            int_x86_avx2_vbroadcast_ss_ps_256>;
7034 }
7035 let ExeDomain = SSEPackedDouble in
7036 def VBROADCASTSDrr  : avx2_broadcast_reg<0x19, "vbroadcastsd", VR256,
7037                                          int_x86_avx2_vbroadcast_sd_pd_256>;
7038
7039 let Predicates = [HasAVX2] in
7040 def VBROADCASTI128 : avx_broadcast<0x5A, "vbroadcasti128", VR256, i128mem,
7041                                    int_x86_avx2_vbroadcasti128>;
7042
7043 let Predicates = [HasAVX] in
7044 def : Pat<(int_x86_avx_vbroadcastf128_ps_256 addr:$src),
7045           (VBROADCASTF128 addr:$src)>;
7046
7047
7048 //===----------------------------------------------------------------------===//
7049 // VINSERTF128 - Insert packed floating-point values
7050 //
7051 let neverHasSideEffects = 1, ExeDomain = SSEPackedSingle in {
7052 def VINSERTF128rr : AVXAIi8<0x18, MRMSrcReg, (outs VR256:$dst),
7053           (ins VR256:$src1, VR128:$src2, i8imm:$src3),
7054           "vinsertf128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
7055           []>, VEX_4V;
7056 let mayLoad = 1 in
7057 def VINSERTF128rm : AVXAIi8<0x18, MRMSrcMem, (outs VR256:$dst),
7058           (ins VR256:$src1, f128mem:$src2, i8imm:$src3),
7059           "vinsertf128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
7060           []>, VEX_4V;
7061 }
7062
7063 let Predicates = [HasAVX] in {
7064 def : Pat<(int_x86_avx_vinsertf128_pd_256 VR256:$src1, VR128:$src2, imm:$src3),
7065           (VINSERTF128rr VR256:$src1, VR128:$src2, imm:$src3)>;
7066 def : Pat<(int_x86_avx_vinsertf128_ps_256 VR256:$src1, VR128:$src2, imm:$src3),
7067           (VINSERTF128rr VR256:$src1, VR128:$src2, imm:$src3)>;
7068 def : Pat<(int_x86_avx_vinsertf128_si_256 VR256:$src1, VR128:$src2, imm:$src3),
7069           (VINSERTF128rr VR256:$src1, VR128:$src2, imm:$src3)>;
7070 }
7071
7072 //===----------------------------------------------------------------------===//
7073 // VEXTRACTF128 - Extract packed floating-point values
7074 //
7075 let neverHasSideEffects = 1, ExeDomain = SSEPackedSingle in {
7076 def VEXTRACTF128rr : AVXAIi8<0x19, MRMDestReg, (outs VR128:$dst),
7077           (ins VR256:$src1, i8imm:$src2),
7078           "vextractf128\t{$src2, $src1, $dst|$dst, $src1, $src2}",
7079           []>, VEX;
7080 let mayStore = 1 in
7081 def VEXTRACTF128mr : AVXAIi8<0x19, MRMDestMem, (outs),
7082           (ins f128mem:$dst, VR256:$src1, i8imm:$src2),
7083           "vextractf128\t{$src2, $src1, $dst|$dst, $src1, $src2}",
7084           []>, VEX;
7085 }
7086
7087 let Predicates = [HasAVX] in {
7088 def : Pat<(int_x86_avx_vextractf128_pd_256 VR256:$src1, imm:$src2),
7089           (VEXTRACTF128rr VR256:$src1, imm:$src2)>;
7090 def : Pat<(int_x86_avx_vextractf128_ps_256 VR256:$src1, imm:$src2),
7091           (VEXTRACTF128rr VR256:$src1, imm:$src2)>;
7092 def : Pat<(int_x86_avx_vextractf128_si_256 VR256:$src1, imm:$src2),
7093           (VEXTRACTF128rr VR256:$src1, imm:$src2)>;
7094 }
7095
7096 //===----------------------------------------------------------------------===//
7097 // VMASKMOV - Conditional SIMD Packed Loads and Stores
7098 //
7099 multiclass avx_movmask_rm<bits<8> opc_rm, bits<8> opc_mr, string OpcodeStr,
7100                           Intrinsic IntLd, Intrinsic IntLd256,
7101                           Intrinsic IntSt, Intrinsic IntSt256> {
7102   def rm  : AVX8I<opc_rm, MRMSrcMem, (outs VR128:$dst),
7103              (ins VR128:$src1, f128mem:$src2),
7104              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7105              [(set VR128:$dst, (IntLd addr:$src2, VR128:$src1))]>,
7106              VEX_4V;
7107   def Yrm : AVX8I<opc_rm, MRMSrcMem, (outs VR256:$dst),
7108              (ins VR256:$src1, f256mem:$src2),
7109              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7110              [(set VR256:$dst, (IntLd256 addr:$src2, VR256:$src1))]>,
7111              VEX_4V;
7112   def mr  : AVX8I<opc_mr, MRMDestMem, (outs),
7113              (ins f128mem:$dst, VR128:$src1, VR128:$src2),
7114              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7115              [(IntSt addr:$dst, VR128:$src1, VR128:$src2)]>, VEX_4V;
7116   def Ymr : AVX8I<opc_mr, MRMDestMem, (outs),
7117              (ins f256mem:$dst, VR256:$src1, VR256:$src2),
7118              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7119              [(IntSt256 addr:$dst, VR256:$src1, VR256:$src2)]>, VEX_4V;
7120 }
7121
7122 let ExeDomain = SSEPackedSingle in
7123 defm VMASKMOVPS : avx_movmask_rm<0x2C, 0x2E, "vmaskmovps",
7124                                  int_x86_avx_maskload_ps,
7125                                  int_x86_avx_maskload_ps_256,
7126                                  int_x86_avx_maskstore_ps,
7127                                  int_x86_avx_maskstore_ps_256>;
7128 let ExeDomain = SSEPackedDouble in
7129 defm VMASKMOVPD : avx_movmask_rm<0x2D, 0x2F, "vmaskmovpd",
7130                                  int_x86_avx_maskload_pd,
7131                                  int_x86_avx_maskload_pd_256,
7132                                  int_x86_avx_maskstore_pd,
7133                                  int_x86_avx_maskstore_pd_256>;
7134
7135 //===----------------------------------------------------------------------===//
7136 // VPERMIL - Permute Single and Double Floating-Point Values
7137 //
7138 multiclass avx_permil<bits<8> opc_rm, bits<8> opc_rmi, string OpcodeStr,
7139                       RegisterClass RC, X86MemOperand x86memop_f,
7140                       X86MemOperand x86memop_i, PatFrag f_frag, PatFrag i_frag,
7141                       Intrinsic IntVar, Intrinsic IntImm> {
7142   def rr  : AVX8I<opc_rm, MRMSrcReg, (outs RC:$dst),
7143              (ins RC:$src1, RC:$src2),
7144              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7145              [(set RC:$dst, (IntVar RC:$src1, RC:$src2))]>, VEX_4V;
7146   def rm  : AVX8I<opc_rm, MRMSrcMem, (outs RC:$dst),
7147              (ins RC:$src1, x86memop_i:$src2),
7148              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7149              [(set RC:$dst, (IntVar RC:$src1,
7150                              (bitconvert (i_frag addr:$src2))))]>, VEX_4V;
7151
7152   def ri  : AVXAIi8<opc_rmi, MRMSrcReg, (outs RC:$dst),
7153              (ins RC:$src1, i8imm:$src2),
7154              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7155              [(set RC:$dst, (IntImm RC:$src1, imm:$src2))]>, VEX;
7156   def mi  : AVXAIi8<opc_rmi, MRMSrcMem, (outs RC:$dst),
7157              (ins x86memop_f:$src1, i8imm:$src2),
7158              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7159              [(set RC:$dst, (IntImm (f_frag addr:$src1), imm:$src2))]>, VEX;
7160 }
7161
7162 let ExeDomain = SSEPackedSingle in {
7163   defm VPERMILPS  : avx_permil<0x0C, 0x04, "vpermilps", VR128, f128mem, i128mem,
7164                                memopv4f32, memopv2i64,
7165                                int_x86_avx_vpermilvar_ps,
7166                                int_x86_avx_vpermil_ps>;
7167   defm VPERMILPSY : avx_permil<0x0C, 0x04, "vpermilps", VR256, f256mem, i256mem,
7168                                memopv8f32, memopv4i64,
7169                                int_x86_avx_vpermilvar_ps_256,
7170                                int_x86_avx_vpermil_ps_256>;
7171 }
7172 let ExeDomain = SSEPackedDouble in {
7173   defm VPERMILPD  : avx_permil<0x0D, 0x05, "vpermilpd", VR128, f128mem, i128mem,
7174                                memopv2f64, memopv2i64,
7175                                int_x86_avx_vpermilvar_pd,
7176                                int_x86_avx_vpermil_pd>;
7177   defm VPERMILPDY : avx_permil<0x0D, 0x05, "vpermilpd", VR256, f256mem, i256mem,
7178                                memopv4f64, memopv4i64,
7179                                int_x86_avx_vpermilvar_pd_256,
7180                                int_x86_avx_vpermil_pd_256>;
7181 }
7182
7183 let Predicates = [HasAVX] in {
7184 def : Pat<(v8f32 (X86VPermilp VR256:$src1, (i8 imm:$imm))),
7185           (VPERMILPSYri VR256:$src1, imm:$imm)>;
7186 def : Pat<(v4f64 (X86VPermilp VR256:$src1, (i8 imm:$imm))),
7187           (VPERMILPDYri VR256:$src1, imm:$imm)>;
7188 def : Pat<(v8i32 (X86VPermilp VR256:$src1, (i8 imm:$imm))),
7189           (VPERMILPSYri VR256:$src1, imm:$imm)>;
7190 def : Pat<(v4i64 (X86VPermilp VR256:$src1, (i8 imm:$imm))),
7191           (VPERMILPDYri VR256:$src1, imm:$imm)>;
7192 def : Pat<(v8f32 (X86VPermilp (memopv8f32 addr:$src1), (i8 imm:$imm))),
7193           (VPERMILPSYmi addr:$src1, imm:$imm)>;
7194 def : Pat<(v4f64 (X86VPermilp (memopv4f64 addr:$src1), (i8 imm:$imm))),
7195           (VPERMILPDYmi addr:$src1, imm:$imm)>;
7196 def : Pat<(v8i32 (X86VPermilp (bc_v8i32 (memopv4i64 addr:$src1)),
7197                                (i8 imm:$imm))),
7198           (VPERMILPSYmi addr:$src1, imm:$imm)>;
7199 def : Pat<(v4i64 (X86VPermilp (memopv4i64 addr:$src1), (i8 imm:$imm))),
7200           (VPERMILPDYmi addr:$src1, imm:$imm)>;
7201 }
7202
7203 //===----------------------------------------------------------------------===//
7204 // VPERM2F128 - Permute Floating-Point Values in 128-bit chunks
7205 //
7206 let neverHasSideEffects = 1, ExeDomain = SSEPackedSingle in {
7207 def VPERM2F128rr : AVXAIi8<0x06, MRMSrcReg, (outs VR256:$dst),
7208           (ins VR256:$src1, VR256:$src2, i8imm:$src3),
7209           "vperm2f128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
7210           []>, VEX_4V;
7211 let mayLoad = 1 in
7212 def VPERM2F128rm : AVXAIi8<0x06, MRMSrcMem, (outs VR256:$dst),
7213           (ins VR256:$src1, f256mem:$src2, i8imm:$src3),
7214           "vperm2f128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
7215           []>, VEX_4V;
7216 }
7217
7218 let Predicates = [HasAVX] in {
7219 def : Pat<(int_x86_avx_vperm2f128_ps_256 VR256:$src1, VR256:$src2, imm:$src3),
7220           (VPERM2F128rr VR256:$src1, VR256:$src2, imm:$src3)>;
7221 def : Pat<(int_x86_avx_vperm2f128_pd_256 VR256:$src1, VR256:$src2, imm:$src3),
7222           (VPERM2F128rr VR256:$src1, VR256:$src2, imm:$src3)>;
7223 def : Pat<(int_x86_avx_vperm2f128_si_256 VR256:$src1, VR256:$src2, imm:$src3),
7224           (VPERM2F128rr VR256:$src1, VR256:$src2, imm:$src3)>;
7225
7226 def : Pat<(int_x86_avx_vperm2f128_ps_256
7227                   VR256:$src1, (memopv8f32 addr:$src2), imm:$src3),
7228           (VPERM2F128rm VR256:$src1, addr:$src2, imm:$src3)>;
7229 def : Pat<(int_x86_avx_vperm2f128_pd_256
7230                   VR256:$src1, (memopv4f64 addr:$src2), imm:$src3),
7231           (VPERM2F128rm VR256:$src1, addr:$src2, imm:$src3)>;
7232 def : Pat<(int_x86_avx_vperm2f128_si_256
7233                   VR256:$src1, (bc_v8i32 (memopv4i64 addr:$src2)), imm:$src3),
7234           (VPERM2F128rm VR256:$src1, addr:$src2, imm:$src3)>;
7235 }
7236
7237 //===----------------------------------------------------------------------===//
7238 // VZERO - Zero YMM registers
7239 //
7240 let Defs = [YMM0, YMM1, YMM2, YMM3, YMM4, YMM5, YMM6, YMM7,
7241             YMM8, YMM9, YMM10, YMM11, YMM12, YMM13, YMM14, YMM15] in {
7242   // Zero All YMM registers
7243   def VZEROALL : I<0x77, RawFrm, (outs), (ins), "vzeroall",
7244                   [(int_x86_avx_vzeroall)]>, TB, VEX, VEX_L, Requires<[HasAVX]>;
7245
7246   // Zero Upper bits of YMM registers
7247   def VZEROUPPER : I<0x77, RawFrm, (outs), (ins), "vzeroupper",
7248                      [(int_x86_avx_vzeroupper)]>, TB, VEX, Requires<[HasAVX]>;
7249 }
7250
7251 //===----------------------------------------------------------------------===//
7252 // Half precision conversion instructions
7253 //===----------------------------------------------------------------------===//
7254 multiclass f16c_ph2ps<RegisterClass RC, X86MemOperand x86memop, Intrinsic Int> {
7255 let Predicates = [HasAVX, HasF16C] in {
7256   def rr : I<0x13, MRMSrcReg, (outs RC:$dst), (ins VR128:$src),
7257              "vcvtph2ps\t{$src, $dst|$dst, $src}",
7258              [(set RC:$dst, (Int VR128:$src))]>,
7259              T8, OpSize, VEX;
7260   let neverHasSideEffects = 1, mayLoad = 1 in
7261   def rm : I<0x13, MRMSrcMem, (outs RC:$dst), (ins x86memop:$src),
7262              "vcvtph2ps\t{$src, $dst|$dst, $src}", []>, T8, OpSize, VEX;
7263 }
7264 }
7265
7266 multiclass f16c_ps2ph<RegisterClass RC, X86MemOperand x86memop, Intrinsic Int> {
7267 let Predicates = [HasAVX, HasF16C] in {
7268   def rr : Ii8<0x1D, MRMDestReg, (outs VR128:$dst),
7269                (ins RC:$src1, i32i8imm:$src2),
7270                "vcvtps2ph\t{$src2, $src1, $dst|$dst, $src1, $src2}",
7271                [(set VR128:$dst, (Int RC:$src1, imm:$src2))]>,
7272                TA, OpSize, VEX;
7273   let neverHasSideEffects = 1, mayLoad = 1 in
7274   def mr : Ii8<0x1D, MRMDestMem, (outs x86memop:$dst),
7275                (ins RC:$src1, i32i8imm:$src2),
7276                "vcvtps2ph\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>,
7277                TA, OpSize, VEX;
7278 }
7279 }
7280
7281 defm VCVTPH2PS  : f16c_ph2ps<VR128, f64mem, int_x86_vcvtph2ps_128>;
7282 defm VCVTPH2PSY : f16c_ph2ps<VR256, f128mem, int_x86_vcvtph2ps_256>;
7283 defm VCVTPS2PH  : f16c_ps2ph<VR128, f64mem, int_x86_vcvtps2ph_128>;
7284 defm VCVTPS2PHY : f16c_ps2ph<VR256, f128mem, int_x86_vcvtps2ph_256>;
7285
7286 //===----------------------------------------------------------------------===//
7287 // AVX2 Instructions
7288 //===----------------------------------------------------------------------===//
7289
7290 /// AVX2_binop_rmi_int - AVX2 binary operator with 8-bit immediate
7291 multiclass AVX2_binop_rmi_int<bits<8> opc, string OpcodeStr,
7292                  Intrinsic IntId, RegisterClass RC, PatFrag memop_frag,
7293                  X86MemOperand x86memop> {
7294   let isCommutable = 1 in
7295   def rri : AVX2AIi8<opc, MRMSrcReg, (outs RC:$dst),
7296         (ins RC:$src1, RC:$src2, u32u8imm:$src3),
7297         !strconcat(OpcodeStr,
7298             "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
7299         [(set RC:$dst, (IntId RC:$src1, RC:$src2, imm:$src3))]>,
7300         VEX_4V;
7301   def rmi : AVX2AIi8<opc, MRMSrcMem, (outs RC:$dst),
7302         (ins RC:$src1, x86memop:$src2, u32u8imm:$src3),
7303         !strconcat(OpcodeStr,
7304             "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
7305         [(set RC:$dst,
7306           (IntId RC:$src1,
7307            (bitconvert (memop_frag addr:$src2)), imm:$src3))]>,
7308         VEX_4V;
7309 }
7310
7311 let isCommutable = 0 in {
7312 defm VPBLENDD : AVX2_binop_rmi_int<0x02, "vpblendd", int_x86_avx2_pblendd_128,
7313                                    VR128, memopv2i64, i128mem>;
7314 defm VPBLENDDY : AVX2_binop_rmi_int<0x02, "vpblendd", int_x86_avx2_pblendd_256,
7315                                     VR256, memopv4i64, i256mem>;
7316 }
7317
7318 //===----------------------------------------------------------------------===//
7319 // VPBROADCAST - Load from memory and broadcast to all elements of the
7320 //               destination operand
7321 //
7322 multiclass avx2_broadcast<bits<8> opc, string OpcodeStr,
7323                           X86MemOperand x86memop, PatFrag ld_frag,
7324                           Intrinsic Int128, Intrinsic Int256> {
7325   def rr : AVX28I<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
7326                   !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
7327                   [(set VR128:$dst, (Int128 VR128:$src))]>, VEX;
7328   def rm : AVX28I<opc, MRMSrcMem, (outs VR128:$dst), (ins x86memop:$src),
7329                   !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
7330                   [(set VR128:$dst,
7331                     (Int128 (scalar_to_vector (ld_frag addr:$src))))]>, VEX;
7332   def Yrr : AVX28I<opc, MRMSrcReg, (outs VR256:$dst), (ins VR128:$src),
7333                    !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
7334                    [(set VR256:$dst, (Int256 VR128:$src))]>, VEX;
7335   def Yrm : AVX28I<opc, MRMSrcMem, (outs VR256:$dst), (ins x86memop:$src),
7336                    !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
7337                    [(set VR256:$dst,
7338                     (Int256 (scalar_to_vector (ld_frag addr:$src))))]>, VEX;
7339 }
7340
7341 defm VPBROADCASTB  : avx2_broadcast<0x78, "vpbroadcastb", i8mem, loadi8,
7342                                     int_x86_avx2_pbroadcastb_128,
7343                                     int_x86_avx2_pbroadcastb_256>;
7344 defm VPBROADCASTW  : avx2_broadcast<0x79, "vpbroadcastw", i16mem, loadi16,
7345                                     int_x86_avx2_pbroadcastw_128,
7346                                     int_x86_avx2_pbroadcastw_256>;
7347 defm VPBROADCASTD  : avx2_broadcast<0x58, "vpbroadcastd", i32mem, loadi32,
7348                                     int_x86_avx2_pbroadcastd_128,
7349                                     int_x86_avx2_pbroadcastd_256>;
7350 defm VPBROADCASTQ  : avx2_broadcast<0x59, "vpbroadcastq", i64mem, loadi64,
7351                                     int_x86_avx2_pbroadcastq_128,
7352                                     int_x86_avx2_pbroadcastq_256>;
7353
7354 let Predicates = [HasAVX2] in {
7355   def : Pat<(v16i8 (X86VBroadcast (loadi8 addr:$src))),
7356           (VPBROADCASTBrm addr:$src)>;
7357   def : Pat<(v32i8 (X86VBroadcast (loadi8 addr:$src))),
7358           (VPBROADCASTBYrm addr:$src)>;
7359   def : Pat<(v8i16 (X86VBroadcast (loadi16 addr:$src))),
7360           (VPBROADCASTWrm addr:$src)>;
7361   def : Pat<(v16i16 (X86VBroadcast (loadi16 addr:$src))),
7362           (VPBROADCASTWYrm addr:$src)>;
7363   def : Pat<(v4i32 (X86VBroadcast (loadi32 addr:$src))),
7364           (VPBROADCASTDrm addr:$src)>;
7365   def : Pat<(v8i32 (X86VBroadcast (loadi32 addr:$src))),
7366           (VPBROADCASTDYrm addr:$src)>;
7367   def : Pat<(v2i64 (X86VBroadcast (loadi64 addr:$src))),
7368           (VPBROADCASTQrm addr:$src)>;
7369   def : Pat<(v4i64 (X86VBroadcast (loadi64 addr:$src))),
7370           (VPBROADCASTQYrm addr:$src)>;
7371 }
7372
7373 // AVX1 broadcast patterns
7374 let Predicates = [HasAVX] in {
7375 def : Pat<(v8i32 (X86VBroadcast (loadi32 addr:$src))),
7376           (VBROADCASTSSYrm addr:$src)>;
7377 def : Pat<(v4i64 (X86VBroadcast (loadi64 addr:$src))),
7378           (VBROADCASTSDrm addr:$src)>;
7379 def : Pat<(v8f32 (X86VBroadcast (loadf32 addr:$src))),
7380           (VBROADCASTSSYrm addr:$src)>;
7381 def : Pat<(v4f64 (X86VBroadcast (loadf64 addr:$src))),
7382           (VBROADCASTSDrm addr:$src)>;
7383
7384 def : Pat<(v4f32 (X86VBroadcast (loadf32 addr:$src))),
7385           (VBROADCASTSSrm addr:$src)>;
7386 def : Pat<(v4i32 (X86VBroadcast (loadi32 addr:$src))),
7387           (VBROADCASTSSrm addr:$src)>;
7388 }
7389
7390 //===----------------------------------------------------------------------===//
7391 // VPERM - Permute instructions
7392 //
7393
7394 multiclass avx2_perm<bits<8> opc, string OpcodeStr, PatFrag mem_frag,
7395                      Intrinsic Int> {
7396   def Yrr : AVX28I<opc, MRMSrcReg, (outs VR256:$dst),
7397                    (ins VR256:$src1, VR256:$src2),
7398                    !strconcat(OpcodeStr,
7399                        "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7400                    [(set VR256:$dst, (Int VR256:$src1, VR256:$src2))]>, VEX_4V;
7401   def Yrm : AVX28I<opc, MRMSrcMem, (outs VR256:$dst),
7402                    (ins VR256:$src1, i256mem:$src2),
7403                    !strconcat(OpcodeStr,
7404                        "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7405                    [(set VR256:$dst, (Int VR256:$src1,
7406                                       (bitconvert (mem_frag addr:$src2))))]>,
7407                    VEX_4V;
7408 }
7409
7410 defm VPERMD : avx2_perm<0x36, "vpermd", memopv4i64, int_x86_avx2_permd>;
7411 let ExeDomain = SSEPackedSingle in
7412 defm VPERMPS : avx2_perm<0x16, "vpermps", memopv8f32, int_x86_avx2_permps>;
7413
7414 multiclass avx2_perm_imm<bits<8> opc, string OpcodeStr, PatFrag mem_frag,
7415                          Intrinsic Int> {
7416   def Yrr : AVX2AIi8<opc, MRMSrcReg, (outs VR256:$dst),
7417                      (ins VR256:$src1, i8imm:$src2),
7418                      !strconcat(OpcodeStr,
7419                          "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7420                      [(set VR256:$dst, (Int VR256:$src1, imm:$src2))]>, VEX;
7421   def Yrm : AVX2AIi8<opc, MRMSrcMem, (outs VR256:$dst),
7422                      (ins i256mem:$src1, i8imm:$src2),
7423                      !strconcat(OpcodeStr,
7424                          "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7425                      [(set VR256:$dst, (Int (mem_frag addr:$src1), imm:$src2))]>,
7426                      VEX;
7427 }
7428
7429 defm VPERMQ : avx2_perm_imm<0x00, "vpermq", memopv4i64, int_x86_avx2_permq>,
7430                             VEX_W;
7431 let ExeDomain = SSEPackedDouble in
7432 defm VPERMPD : avx2_perm_imm<0x01, "vpermpd", memopv4f64, int_x86_avx2_permpd>,
7433                              VEX_W;
7434
7435 //===----------------------------------------------------------------------===//
7436 // VPERM2I128 - Permute Floating-Point Values in 128-bit chunks
7437 //
7438 def VPERM2I128rr : AVX2AIi8<0x46, MRMSrcReg, (outs VR256:$dst),
7439           (ins VR256:$src1, VR256:$src2, i8imm:$src3),
7440           "vperm2i128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
7441           [(set VR256:$dst,
7442            (int_x86_avx2_vperm2i128 VR256:$src1, VR256:$src2, imm:$src3))]>,
7443           VEX_4V;
7444 def VPERM2I128rm : AVX2AIi8<0x46, MRMSrcMem, (outs VR256:$dst),
7445           (ins VR256:$src1, f256mem:$src2, i8imm:$src3),
7446           "vperm2i128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
7447           [(set VR256:$dst,
7448            (int_x86_avx2_vperm2i128 VR256:$src1, (memopv4i64 addr:$src2),
7449             imm:$src3))]>,
7450           VEX_4V;
7451
7452 let Predicates = [HasAVX2] in {
7453 def : Pat<(v8i32 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
7454           (VPERM2I128rr VR256:$src1, VR256:$src2, imm:$imm)>;
7455 def : Pat<(v4i64 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
7456           (VPERM2I128rr VR256:$src1, VR256:$src2, imm:$imm)>;
7457 def : Pat<(v32i8 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
7458           (VPERM2I128rr VR256:$src1, VR256:$src2, imm:$imm)>;
7459 def : Pat<(v16i16 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
7460           (VPERM2I128rr VR256:$src1, VR256:$src2, imm:$imm)>;
7461
7462 def : Pat<(v32i8 (X86VPerm2x128 VR256:$src1, (bc_v32i8 (memopv4i64 addr:$src2)),
7463                   (i8 imm:$imm))),
7464           (VPERM2I128rm VR256:$src1, addr:$src2, imm:$imm)>;
7465 def : Pat<(v16i16 (X86VPerm2x128 VR256:$src1,
7466                    (bc_v16i16 (memopv4i64 addr:$src2)), (i8 imm:$imm))),
7467           (VPERM2I128rm VR256:$src1, addr:$src2, imm:$imm)>;
7468 def : Pat<(v8i32 (X86VPerm2x128 VR256:$src1, (bc_v8i32 (memopv4i64 addr:$src2)),
7469                   (i8 imm:$imm))),
7470           (VPERM2I128rm VR256:$src1, addr:$src2, imm:$imm)>;
7471 def : Pat<(v4i64 (X86VPerm2x128 VR256:$src1, (memopv4i64 addr:$src2),
7472                   (i8 imm:$imm))),
7473           (VPERM2I128rm VR256:$src1, addr:$src2, imm:$imm)>;
7474 }
7475
7476 // AVX1 patterns
7477 let Predicates = [HasAVX] in {
7478 def : Pat<(v8f32 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
7479           (VPERM2F128rr VR256:$src1, VR256:$src2, imm:$imm)>;
7480 def : Pat<(v8i32 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
7481           (VPERM2F128rr VR256:$src1, VR256:$src2, imm:$imm)>;
7482 def : Pat<(v4i64 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
7483           (VPERM2F128rr VR256:$src1, VR256:$src2, imm:$imm)>;
7484 def : Pat<(v4f64 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
7485           (VPERM2F128rr VR256:$src1, VR256:$src2, imm:$imm)>;
7486 def : Pat<(v32i8 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
7487           (VPERM2F128rr VR256:$src1, VR256:$src2, imm:$imm)>;
7488 def : Pat<(v16i16 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
7489           (VPERM2F128rr VR256:$src1, VR256:$src2, imm:$imm)>;
7490
7491 def : Pat<(v8f32 (X86VPerm2x128 VR256:$src1,
7492                   (memopv8f32 addr:$src2), (i8 imm:$imm))),
7493           (VPERM2F128rm VR256:$src1, addr:$src2, imm:$imm)>;
7494 def : Pat<(v8i32 (X86VPerm2x128 VR256:$src1,
7495                   (bc_v8i32 (memopv4i64 addr:$src2)), (i8 imm:$imm))),
7496           (VPERM2F128rm VR256:$src1, addr:$src2, imm:$imm)>;
7497 def : Pat<(v4i64 (X86VPerm2x128 VR256:$src1,
7498                   (memopv4i64 addr:$src2), (i8 imm:$imm))),
7499           (VPERM2F128rm VR256:$src1, addr:$src2, imm:$imm)>;
7500 def : Pat<(v4f64 (X86VPerm2x128 VR256:$src1,
7501                   (memopv4f64 addr:$src2), (i8 imm:$imm))),
7502           (VPERM2F128rm VR256:$src1, addr:$src2, imm:$imm)>;
7503 def : Pat<(v32i8 (X86VPerm2x128 VR256:$src1,
7504                   (bc_v32i8 (memopv4i64 addr:$src2)), (i8 imm:$imm))),
7505           (VPERM2F128rm VR256:$src1, addr:$src2, imm:$imm)>;
7506 def : Pat<(v16i16 (X86VPerm2x128 VR256:$src1,
7507                   (bc_v16i16 (memopv4i64 addr:$src2)), (i8 imm:$imm))),
7508           (VPERM2F128rm VR256:$src1, addr:$src2, imm:$imm)>;
7509 }
7510
7511
7512 //===----------------------------------------------------------------------===//
7513 // VINSERTI128 - Insert packed integer values
7514 //
7515 def VINSERTI128rr : AVX2AIi8<0x38, MRMSrcReg, (outs VR256:$dst),
7516           (ins VR256:$src1, VR128:$src2, i8imm:$src3),
7517           "vinserti128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
7518           [(set VR256:$dst,
7519             (int_x86_avx2_vinserti128 VR256:$src1, VR128:$src2, imm:$src3))]>,
7520           VEX_4V;
7521 def VINSERTI128rm : AVX2AIi8<0x38, MRMSrcMem, (outs VR256:$dst),
7522           (ins VR256:$src1, i128mem:$src2, i8imm:$src3),
7523           "vinserti128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
7524           [(set VR256:$dst,
7525             (int_x86_avx2_vinserti128 VR256:$src1, (memopv2i64 addr:$src2),
7526              imm:$src3))]>, VEX_4V;
7527
7528 let Predicates = [HasAVX2] in {
7529 def : Pat<(vinsertf128_insert:$ins (v4i64 VR256:$src1), (v2i64 VR128:$src2),
7530                                    (i32 imm)),
7531           (VINSERTI128rr VR256:$src1, VR128:$src2,
7532                          (INSERT_get_vinsertf128_imm VR256:$ins))>;
7533 def : Pat<(vinsertf128_insert:$ins (v8i32 VR256:$src1), (v4i32 VR128:$src2),
7534                                    (i32 imm)),
7535           (VINSERTI128rr VR256:$src1, VR128:$src2,
7536                          (INSERT_get_vinsertf128_imm VR256:$ins))>;
7537 def : Pat<(vinsertf128_insert:$ins (v32i8 VR256:$src1), (v16i8 VR128:$src2),
7538                                    (i32 imm)),
7539           (VINSERTI128rr VR256:$src1, VR128:$src2,
7540                          (INSERT_get_vinsertf128_imm VR256:$ins))>;
7541 def : Pat<(vinsertf128_insert:$ins (v16i16 VR256:$src1), (v8i16 VR128:$src2),
7542                                    (i32 imm)),
7543           (VINSERTI128rr VR256:$src1, VR128:$src2,
7544                          (INSERT_get_vinsertf128_imm VR256:$ins))>;
7545 }
7546
7547 // AVX1 patterns
7548 let Predicates = [HasAVX] in {
7549 def : Pat<(vinsertf128_insert:$ins (v8f32 VR256:$src1), (v4f32 VR128:$src2),
7550                                    (i32 imm)),
7551           (VINSERTF128rr VR256:$src1, VR128:$src2,
7552                          (INSERT_get_vinsertf128_imm VR256:$ins))>;
7553 def : Pat<(vinsertf128_insert:$ins (v4f64 VR256:$src1), (v2f64 VR128:$src2),
7554                                    (i32 imm)),
7555           (VINSERTF128rr VR256:$src1, VR128:$src2,
7556                          (INSERT_get_vinsertf128_imm VR256:$ins))>;
7557 def : Pat<(vinsertf128_insert:$ins (v4i64 VR256:$src1), (v2i64 VR128:$src2),
7558                                    (i32 imm)),
7559           (VINSERTF128rr VR256:$src1, VR128:$src2,
7560                          (INSERT_get_vinsertf128_imm VR256:$ins))>;
7561 def : Pat<(vinsertf128_insert:$ins (v8i32 VR256:$src1), (v4i32 VR128:$src2),
7562                                    (i32 imm)),
7563           (VINSERTF128rr VR256:$src1, VR128:$src2,
7564                          (INSERT_get_vinsertf128_imm VR256:$ins))>;
7565 def : Pat<(vinsertf128_insert:$ins (v32i8 VR256:$src1), (v16i8 VR128:$src2),
7566                                    (i32 imm)),
7567           (VINSERTF128rr VR256:$src1, VR128:$src2,
7568                          (INSERT_get_vinsertf128_imm VR256:$ins))>;
7569 def : Pat<(vinsertf128_insert:$ins (v16i16 VR256:$src1), (v8i16 VR128:$src2),
7570                                    (i32 imm)),
7571           (VINSERTF128rr VR256:$src1, VR128:$src2,
7572                          (INSERT_get_vinsertf128_imm VR256:$ins))>;
7573 }
7574
7575 //===----------------------------------------------------------------------===//
7576 // VEXTRACTI128 - Extract packed integer values
7577 //
7578 def VEXTRACTI128rr : AVX2AIi8<0x39, MRMDestReg, (outs VR128:$dst),
7579           (ins VR256:$src1, i8imm:$src2),
7580           "vextracti128\t{$src2, $src1, $dst|$dst, $src1, $src2}",
7581           [(set VR128:$dst,
7582             (int_x86_avx2_vextracti128 VR256:$src1, imm:$src2))]>,
7583           VEX;
7584 let neverHasSideEffects = 1, mayStore = 1 in
7585 def VEXTRACTI128mr : AVX2AIi8<0x39, MRMDestMem, (outs),
7586           (ins i128mem:$dst, VR256:$src1, i8imm:$src2),
7587           "vextracti128\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>, VEX;
7588
7589 let Predicates = [HasAVX2] in {
7590 def : Pat<(vextractf128_extract:$ext VR256:$src1, (i32 imm)),
7591           (v2i64 (VEXTRACTI128rr
7592                     (v4i64 VR256:$src1),
7593                     (EXTRACT_get_vextractf128_imm VR128:$ext)))>;
7594 def : Pat<(vextractf128_extract:$ext VR256:$src1, (i32 imm)),
7595           (v4i32 (VEXTRACTI128rr
7596                     (v8i32 VR256:$src1),
7597                     (EXTRACT_get_vextractf128_imm VR128:$ext)))>;
7598 def : Pat<(vextractf128_extract:$ext VR256:$src1, (i32 imm)),
7599           (v8i16 (VEXTRACTI128rr
7600                     (v16i16 VR256:$src1),
7601                     (EXTRACT_get_vextractf128_imm VR128:$ext)))>;
7602 def : Pat<(vextractf128_extract:$ext VR256:$src1, (i32 imm)),
7603           (v16i8 (VEXTRACTI128rr
7604                     (v32i8 VR256:$src1),
7605                     (EXTRACT_get_vextractf128_imm VR128:$ext)))>;
7606 }
7607
7608 // AVX1 patterns
7609 let Predicates = [HasAVX] in {
7610 def : Pat<(vextractf128_extract:$ext VR256:$src1, (i32 imm)),
7611           (v4f32 (VEXTRACTF128rr
7612                     (v8f32 VR256:$src1),
7613                     (EXTRACT_get_vextractf128_imm VR128:$ext)))>;
7614 def : Pat<(vextractf128_extract:$ext VR256:$src1, (i32 imm)),
7615           (v2f64 (VEXTRACTF128rr
7616                     (v4f64 VR256:$src1),
7617                     (EXTRACT_get_vextractf128_imm VR128:$ext)))>;
7618 def : Pat<(vextractf128_extract:$ext VR256:$src1, (i32 imm)),
7619           (v2i64 (VEXTRACTF128rr
7620                     (v4i64 VR256:$src1),
7621                     (EXTRACT_get_vextractf128_imm VR128:$ext)))>;
7622 def : Pat<(vextractf128_extract:$ext VR256:$src1, (i32 imm)),
7623           (v4i32 (VEXTRACTF128rr
7624                     (v8i32 VR256:$src1),
7625                     (EXTRACT_get_vextractf128_imm VR128:$ext)))>;
7626 def : Pat<(vextractf128_extract:$ext VR256:$src1, (i32 imm)),
7627           (v8i16 (VEXTRACTF128rr
7628                     (v16i16 VR256:$src1),
7629                     (EXTRACT_get_vextractf128_imm VR128:$ext)))>;
7630 def : Pat<(vextractf128_extract:$ext VR256:$src1, (i32 imm)),
7631           (v16i8 (VEXTRACTF128rr
7632                     (v32i8 VR256:$src1),
7633                     (EXTRACT_get_vextractf128_imm VR128:$ext)))>;
7634 }
7635
7636 //===----------------------------------------------------------------------===//
7637 // VPMASKMOV - Conditional SIMD Integer Packed Loads and Stores
7638 //
7639 multiclass avx2_pmovmask<string OpcodeStr,
7640                          Intrinsic IntLd128, Intrinsic IntLd256,
7641                          Intrinsic IntSt128, Intrinsic IntSt256> {
7642   def rm  : AVX28I<0x8c, MRMSrcMem, (outs VR128:$dst),
7643              (ins VR128:$src1, i128mem:$src2),
7644              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7645              [(set VR128:$dst, (IntLd128 addr:$src2, VR128:$src1))]>, VEX_4V;
7646   def Yrm : AVX28I<0x8c, MRMSrcMem, (outs VR256:$dst),
7647              (ins VR256:$src1, i256mem:$src2),
7648              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7649              [(set VR256:$dst, (IntLd256 addr:$src2, VR256:$src1))]>, VEX_4V;
7650   def mr  : AVX28I<0x8e, MRMDestMem, (outs),
7651              (ins i128mem:$dst, VR128:$src1, VR128:$src2),
7652              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7653              [(IntSt128 addr:$dst, VR128:$src1, VR128:$src2)]>, VEX_4V;
7654   def Ymr : AVX28I<0x8e, MRMDestMem, (outs),
7655              (ins i256mem:$dst, VR256:$src1, VR256:$src2),
7656              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7657              [(IntSt256 addr:$dst, VR256:$src1, VR256:$src2)]>, VEX_4V;
7658 }
7659
7660 defm VPMASKMOVD : avx2_pmovmask<"vpmaskmovd",
7661                                 int_x86_avx2_maskload_d,
7662                                 int_x86_avx2_maskload_d_256,
7663                                 int_x86_avx2_maskstore_d,
7664                                 int_x86_avx2_maskstore_d_256>;
7665 defm VPMASKMOVQ : avx2_pmovmask<"vpmaskmovq",
7666                                 int_x86_avx2_maskload_q,
7667                                 int_x86_avx2_maskload_q_256,
7668                                 int_x86_avx2_maskstore_q,
7669                                 int_x86_avx2_maskstore_q_256>, VEX_W;
7670
7671
7672 //===----------------------------------------------------------------------===//
7673 // Variable Bit Shifts
7674 //
7675 multiclass avx2_var_shift<bits<8> opc, string OpcodeStr, SDNode OpNode,
7676                           ValueType vt128, ValueType vt256> {
7677   def rr  : AVX28I<opc, MRMSrcReg, (outs VR128:$dst),
7678              (ins VR128:$src1, VR128:$src2),
7679              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7680              [(set VR128:$dst,
7681                (vt128 (OpNode VR128:$src1, (vt128 VR128:$src2))))]>,
7682              VEX_4V;
7683   def rm  : AVX28I<opc, MRMSrcMem, (outs VR128:$dst),
7684              (ins VR128:$src1, i128mem:$src2),
7685              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7686              [(set VR128:$dst,
7687                (vt128 (OpNode VR128:$src1,
7688                        (vt128 (bitconvert (memopv2i64 addr:$src2))))))]>,
7689              VEX_4V;
7690   def Yrr : AVX28I<opc, MRMSrcReg, (outs VR256:$dst),
7691              (ins VR256:$src1, VR256:$src2),
7692              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7693              [(set VR256:$dst,
7694                (vt256 (OpNode VR256:$src1, (vt256 VR256:$src2))))]>,
7695              VEX_4V;
7696   def Yrm : AVX28I<opc, MRMSrcMem, (outs VR256:$dst),
7697              (ins VR256:$src1, i256mem:$src2),
7698              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7699              [(set VR256:$dst,
7700                (vt256 (OpNode VR256:$src1,
7701                        (vt256 (bitconvert (memopv4i64 addr:$src2))))))]>,
7702              VEX_4V;
7703 }
7704
7705 defm VPSLLVD : avx2_var_shift<0x47, "vpsllvd", shl, v4i32, v8i32>;
7706 defm VPSLLVQ : avx2_var_shift<0x47, "vpsllvq", shl, v2i64, v4i64>, VEX_W;
7707 defm VPSRLVD : avx2_var_shift<0x45, "vpsrlvd", srl, v4i32, v8i32>;
7708 defm VPSRLVQ : avx2_var_shift<0x45, "vpsrlvq", srl, v2i64, v4i64>, VEX_W;
7709 defm VPSRAVD : avx2_var_shift<0x46, "vpsravd", sra, v4i32, v8i32>;