Move old movl vector_shuffle patterns. Not needed anymore since vector_shuffles shoul...
[oota-llvm.git] / lib / Target / X86 / X86InstrSSE.td
1 //====- X86InstrSSE.td - Describe the X86 Instruction Set --*- tablegen -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file describes the X86 SSE instruction set, defining the instructions,
11 // and properties of the instructions which are needed for code generation,
12 // machine code emission, and analysis.
13 //
14 //===----------------------------------------------------------------------===//
15
16
17 //===----------------------------------------------------------------------===//
18 // SSE 1 & 2 Instructions Classes
19 //===----------------------------------------------------------------------===//
20
21 /// sse12_fp_scalar - SSE 1 & 2 scalar instructions class
22 multiclass sse12_fp_scalar<bits<8> opc, string OpcodeStr, SDNode OpNode,
23                            RegisterClass RC, X86MemOperand x86memop,
24                            bit Is2Addr = 1> {
25   let isCommutable = 1 in {
26     def rr : SI<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
27        !if(Is2Addr,
28            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
29            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
30        [(set RC:$dst, (OpNode RC:$src1, RC:$src2))]>;
31   }
32   def rm : SI<opc, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
33        !if(Is2Addr,
34            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
35            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
36        [(set RC:$dst, (OpNode RC:$src1, (load addr:$src2)))]>;
37 }
38
39 /// sse12_fp_scalar_int - SSE 1 & 2 scalar instructions intrinsics class
40 multiclass sse12_fp_scalar_int<bits<8> opc, string OpcodeStr, RegisterClass RC,
41                              string asm, string SSEVer, string FPSizeStr,
42                              Operand memopr, ComplexPattern mem_cpat,
43                              bit Is2Addr = 1> {
44   def rr_Int : SI<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
45        !if(Is2Addr,
46            !strconcat(asm, "\t{$src2, $dst|$dst, $src2}"),
47            !strconcat(asm, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
48        [(set RC:$dst, (!cast<Intrinsic>(
49                  !strconcat("int_x86_sse", SSEVer, "_", OpcodeStr, FPSizeStr))
50              RC:$src1, RC:$src2))]>;
51   def rm_Int : SI<opc, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, memopr:$src2),
52        !if(Is2Addr,
53            !strconcat(asm, "\t{$src2, $dst|$dst, $src2}"),
54            !strconcat(asm, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
55        [(set RC:$dst, (!cast<Intrinsic>(!strconcat("int_x86_sse",
56                                           SSEVer, "_", OpcodeStr, FPSizeStr))
57              RC:$src1, mem_cpat:$src2))]>;
58 }
59
60 /// sse12_fp_packed - SSE 1 & 2 packed instructions class
61 multiclass sse12_fp_packed<bits<8> opc, string OpcodeStr, SDNode OpNode,
62                            RegisterClass RC, ValueType vt,
63                            X86MemOperand x86memop, PatFrag mem_frag,
64                            Domain d, bit Is2Addr = 1> {
65   let isCommutable = 1 in
66     def rr : PI<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
67        !if(Is2Addr,
68            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
69            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
70        [(set RC:$dst, (vt (OpNode RC:$src1, RC:$src2)))], IIC_DEFAULT, d>;
71   let mayLoad = 1 in
72     def rm : PI<opc, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
73        !if(Is2Addr,
74            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
75            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
76        [(set RC:$dst, (OpNode RC:$src1, (mem_frag addr:$src2)))],
77           IIC_DEFAULT, d>;
78 }
79
80 /// sse12_fp_packed_logical_rm - SSE 1 & 2 packed instructions class
81 multiclass sse12_fp_packed_logical_rm<bits<8> opc, RegisterClass RC, Domain d,
82                                       string OpcodeStr, X86MemOperand x86memop,
83                                       list<dag> pat_rr, list<dag> pat_rm,
84                                       bit Is2Addr = 1,
85                                       bit rr_hasSideEffects = 0> {
86   let isCommutable = 1, neverHasSideEffects = rr_hasSideEffects in
87     def rr : PI<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
88        !if(Is2Addr,
89            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
90            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
91        pat_rr, IIC_DEFAULT, d>;
92   def rm : PI<opc, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
93        !if(Is2Addr,
94            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
95            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
96        pat_rm, IIC_DEFAULT, d>;
97 }
98
99 /// sse12_fp_packed_int - SSE 1 & 2 packed instructions intrinsics class
100 multiclass sse12_fp_packed_int<bits<8> opc, string OpcodeStr, RegisterClass RC,
101                            string asm, string SSEVer, string FPSizeStr,
102                            X86MemOperand x86memop, PatFrag mem_frag,
103                            Domain d, bit Is2Addr = 1> {
104   def rr_Int : PI<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
105        !if(Is2Addr,
106            !strconcat(asm, "\t{$src2, $dst|$dst, $src2}"),
107            !strconcat(asm, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
108            [(set RC:$dst, (!cast<Intrinsic>(
109                      !strconcat("int_x86_", SSEVer, "_", OpcodeStr, FPSizeStr))
110                  RC:$src1, RC:$src2))], IIC_DEFAULT, d>;
111   def rm_Int : PI<opc, MRMSrcMem, (outs RC:$dst), (ins RC:$src1,x86memop:$src2),
112        !if(Is2Addr,
113            !strconcat(asm, "\t{$src2, $dst|$dst, $src2}"),
114            !strconcat(asm, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
115        [(set RC:$dst, (!cast<Intrinsic>(
116                      !strconcat("int_x86_", SSEVer, "_", OpcodeStr, FPSizeStr))
117              RC:$src1, (mem_frag addr:$src2)))], IIC_DEFAULT, d>;
118 }
119
120 //===----------------------------------------------------------------------===//
121 //  Non-instruction patterns
122 //===----------------------------------------------------------------------===//
123
124 // A vector extract of the first f32/f64 position is a subregister copy
125 def : Pat<(f32 (vector_extract (v4f32 VR128:$src), (iPTR 0))),
126           (f32 (EXTRACT_SUBREG (v4f32 VR128:$src), sub_ss))>;
127 def : Pat<(f64 (vector_extract (v2f64 VR128:$src), (iPTR 0))),
128           (f64 (EXTRACT_SUBREG (v2f64 VR128:$src), sub_sd))>;
129
130 // A 128-bit subvector extract from the first 256-bit vector position
131 // is a subregister copy that needs no instruction.
132 def : Pat<(v4i32 (extract_subvector (v8i32 VR256:$src), (i32 0))),
133           (v4i32 (EXTRACT_SUBREG (v8i32 VR256:$src), sub_xmm))>;
134 def : Pat<(v4f32 (extract_subvector (v8f32 VR256:$src), (i32 0))),
135           (v4f32 (EXTRACT_SUBREG (v8f32 VR256:$src), sub_xmm))>;
136
137 def : Pat<(v2i64 (extract_subvector (v4i64 VR256:$src), (i32 0))),
138           (v2i64 (EXTRACT_SUBREG (v4i64 VR256:$src), sub_xmm))>;
139 def : Pat<(v2f64 (extract_subvector (v4f64 VR256:$src), (i32 0))),
140           (v2f64 (EXTRACT_SUBREG (v4f64 VR256:$src), sub_xmm))>;
141
142 def : Pat<(v8i16 (extract_subvector (v16i16 VR256:$src), (i32 0))),
143           (v8i16 (EXTRACT_SUBREG (v16i16 VR256:$src), sub_xmm))>;
144 def : Pat<(v16i8 (extract_subvector (v32i8 VR256:$src), (i32 0))),
145           (v16i8 (EXTRACT_SUBREG (v32i8 VR256:$src), sub_xmm))>;
146
147 // A 128-bit subvector insert to the first 256-bit vector position
148 // is a subregister copy that needs no instruction.
149 def : Pat<(insert_subvector undef, (v2i64 VR128:$src), (i32 0)),
150           (INSERT_SUBREG (v4i64 (IMPLICIT_DEF)), VR128:$src, sub_xmm)>;
151 def : Pat<(insert_subvector undef, (v2f64 VR128:$src), (i32 0)),
152           (INSERT_SUBREG (v4f64 (IMPLICIT_DEF)), VR128:$src, sub_xmm)>;
153 def : Pat<(insert_subvector undef, (v4i32 VR128:$src), (i32 0)),
154           (INSERT_SUBREG (v8i32 (IMPLICIT_DEF)), VR128:$src, sub_xmm)>;
155 def : Pat<(insert_subvector undef, (v4f32 VR128:$src), (i32 0)),
156           (INSERT_SUBREG (v8f32 (IMPLICIT_DEF)), VR128:$src, sub_xmm)>;
157 def : Pat<(insert_subvector undef, (v8i16 VR128:$src), (i32 0)),
158           (INSERT_SUBREG (v16i16 (IMPLICIT_DEF)), VR128:$src, sub_xmm)>;
159 def : Pat<(insert_subvector undef, (v16i8 VR128:$src), (i32 0)),
160           (INSERT_SUBREG (v32i8 (IMPLICIT_DEF)), VR128:$src, sub_xmm)>;
161
162 // Implicitly promote a 32-bit scalar to a vector.
163 def : Pat<(v4f32 (scalar_to_vector FR32:$src)),
164           (INSERT_SUBREG (v4f32 (IMPLICIT_DEF)), FR32:$src, sub_ss)>;
165 def : Pat<(v8f32 (scalar_to_vector FR32:$src)),
166           (INSERT_SUBREG (v8f32 (IMPLICIT_DEF)), FR32:$src, sub_ss)>;
167 // Implicitly promote a 64-bit scalar to a vector.
168 def : Pat<(v2f64 (scalar_to_vector FR64:$src)),
169           (INSERT_SUBREG (v2f64 (IMPLICIT_DEF)), FR64:$src, sub_sd)>;
170 def : Pat<(v4f64 (scalar_to_vector FR64:$src)),
171           (INSERT_SUBREG (v4f64 (IMPLICIT_DEF)), FR64:$src, sub_sd)>;
172
173 // Bitcasts between 128-bit vector types. Return the original type since
174 // no instruction is needed for the conversion
175 let Predicates = [HasSSE2] in {
176   def : Pat<(v2i64 (bitconvert (v4i32 VR128:$src))), (v2i64 VR128:$src)>;
177   def : Pat<(v2i64 (bitconvert (v8i16 VR128:$src))), (v2i64 VR128:$src)>;
178   def : Pat<(v2i64 (bitconvert (v16i8 VR128:$src))), (v2i64 VR128:$src)>;
179   def : Pat<(v2i64 (bitconvert (v2f64 VR128:$src))), (v2i64 VR128:$src)>;
180   def : Pat<(v2i64 (bitconvert (v4f32 VR128:$src))), (v2i64 VR128:$src)>;
181   def : Pat<(v4i32 (bitconvert (v2i64 VR128:$src))), (v4i32 VR128:$src)>;
182   def : Pat<(v4i32 (bitconvert (v8i16 VR128:$src))), (v4i32 VR128:$src)>;
183   def : Pat<(v4i32 (bitconvert (v16i8 VR128:$src))), (v4i32 VR128:$src)>;
184   def : Pat<(v4i32 (bitconvert (v2f64 VR128:$src))), (v4i32 VR128:$src)>;
185   def : Pat<(v4i32 (bitconvert (v4f32 VR128:$src))), (v4i32 VR128:$src)>;
186   def : Pat<(v8i16 (bitconvert (v2i64 VR128:$src))), (v8i16 VR128:$src)>;
187   def : Pat<(v8i16 (bitconvert (v4i32 VR128:$src))), (v8i16 VR128:$src)>;
188   def : Pat<(v8i16 (bitconvert (v16i8 VR128:$src))), (v8i16 VR128:$src)>;
189   def : Pat<(v8i16 (bitconvert (v2f64 VR128:$src))), (v8i16 VR128:$src)>;
190   def : Pat<(v8i16 (bitconvert (v4f32 VR128:$src))), (v8i16 VR128:$src)>;
191   def : Pat<(v16i8 (bitconvert (v2i64 VR128:$src))), (v16i8 VR128:$src)>;
192   def : Pat<(v16i8 (bitconvert (v4i32 VR128:$src))), (v16i8 VR128:$src)>;
193   def : Pat<(v16i8 (bitconvert (v8i16 VR128:$src))), (v16i8 VR128:$src)>;
194   def : Pat<(v16i8 (bitconvert (v2f64 VR128:$src))), (v16i8 VR128:$src)>;
195   def : Pat<(v16i8 (bitconvert (v4f32 VR128:$src))), (v16i8 VR128:$src)>;
196   def : Pat<(v4f32 (bitconvert (v2i64 VR128:$src))), (v4f32 VR128:$src)>;
197   def : Pat<(v4f32 (bitconvert (v4i32 VR128:$src))), (v4f32 VR128:$src)>;
198   def : Pat<(v4f32 (bitconvert (v8i16 VR128:$src))), (v4f32 VR128:$src)>;
199   def : Pat<(v4f32 (bitconvert (v16i8 VR128:$src))), (v4f32 VR128:$src)>;
200   def : Pat<(v4f32 (bitconvert (v2f64 VR128:$src))), (v4f32 VR128:$src)>;
201   def : Pat<(v2f64 (bitconvert (v2i64 VR128:$src))), (v2f64 VR128:$src)>;
202   def : Pat<(v2f64 (bitconvert (v4i32 VR128:$src))), (v2f64 VR128:$src)>;
203   def : Pat<(v2f64 (bitconvert (v8i16 VR128:$src))), (v2f64 VR128:$src)>;
204   def : Pat<(v2f64 (bitconvert (v16i8 VR128:$src))), (v2f64 VR128:$src)>;
205   def : Pat<(v2f64 (bitconvert (v4f32 VR128:$src))), (v2f64 VR128:$src)>;
206 }
207
208 // Bitcasts between 256-bit vector types. Return the original type since
209 // no instruction is needed for the conversion
210 let Predicates = [HasAVX] in {
211   def : Pat<(v4f64  (bitconvert (v8f32 VR256:$src))),  (v4f64 VR256:$src)>;
212   def : Pat<(v4f64  (bitconvert (v8i32 VR256:$src))),  (v4f64 VR256:$src)>;
213   def : Pat<(v4f64  (bitconvert (v4i64 VR256:$src))),  (v4f64 VR256:$src)>;
214   def : Pat<(v4f64  (bitconvert (v16i16 VR256:$src))), (v4f64 VR256:$src)>;
215   def : Pat<(v4f64  (bitconvert (v32i8 VR256:$src))),  (v4f64 VR256:$src)>;
216   def : Pat<(v8f32  (bitconvert (v8i32 VR256:$src))),  (v8f32 VR256:$src)>;
217   def : Pat<(v8f32  (bitconvert (v4i64 VR256:$src))),  (v8f32 VR256:$src)>;
218   def : Pat<(v8f32  (bitconvert (v4f64 VR256:$src))),  (v8f32 VR256:$src)>;
219   def : Pat<(v8f32  (bitconvert (v32i8 VR256:$src))),  (v8f32 VR256:$src)>;
220   def : Pat<(v8f32  (bitconvert (v16i16 VR256:$src))), (v8f32 VR256:$src)>;
221   def : Pat<(v4i64  (bitconvert (v8f32 VR256:$src))),  (v4i64 VR256:$src)>;
222   def : Pat<(v4i64  (bitconvert (v8i32 VR256:$src))),  (v4i64 VR256:$src)>;
223   def : Pat<(v4i64  (bitconvert (v4f64 VR256:$src))),  (v4i64 VR256:$src)>;
224   def : Pat<(v4i64  (bitconvert (v32i8 VR256:$src))),  (v4i64 VR256:$src)>;
225   def : Pat<(v4i64  (bitconvert (v16i16 VR256:$src))), (v4i64 VR256:$src)>;
226   def : Pat<(v32i8  (bitconvert (v4f64 VR256:$src))),  (v32i8 VR256:$src)>;
227   def : Pat<(v32i8  (bitconvert (v4i64 VR256:$src))),  (v32i8 VR256:$src)>;
228   def : Pat<(v32i8  (bitconvert (v8f32 VR256:$src))),  (v32i8 VR256:$src)>;
229   def : Pat<(v32i8  (bitconvert (v8i32 VR256:$src))),  (v32i8 VR256:$src)>;
230   def : Pat<(v32i8  (bitconvert (v16i16 VR256:$src))), (v32i8 VR256:$src)>;
231   def : Pat<(v8i32  (bitconvert (v32i8 VR256:$src))),  (v8i32 VR256:$src)>;
232   def : Pat<(v8i32  (bitconvert (v16i16 VR256:$src))), (v8i32 VR256:$src)>;
233   def : Pat<(v8i32  (bitconvert (v8f32 VR256:$src))),  (v8i32 VR256:$src)>;
234   def : Pat<(v8i32  (bitconvert (v4i64 VR256:$src))),  (v8i32 VR256:$src)>;
235   def : Pat<(v8i32  (bitconvert (v4f64 VR256:$src))),  (v8i32 VR256:$src)>;
236   def : Pat<(v16i16 (bitconvert (v8f32 VR256:$src))),  (v16i16 VR256:$src)>;
237   def : Pat<(v16i16 (bitconvert (v8i32 VR256:$src))),  (v16i16 VR256:$src)>;
238   def : Pat<(v16i16 (bitconvert (v4i64 VR256:$src))),  (v16i16 VR256:$src)>;
239   def : Pat<(v16i16 (bitconvert (v4f64 VR256:$src))),  (v16i16 VR256:$src)>;
240   def : Pat<(v16i16 (bitconvert (v32i8 VR256:$src))),  (v16i16 VR256:$src)>;
241 }
242
243 // Alias instructions that map fld0 to pxor for sse.
244 // This is expanded by ExpandPostRAPseudos.
245 let isReMaterializable = 1, isAsCheapAsAMove = 1, canFoldAsLoad = 1,
246     isPseudo = 1 in {
247   def FsFLD0SS : I<0, Pseudo, (outs FR32:$dst), (ins), "",
248                    [(set FR32:$dst, fp32imm0)]>, Requires<[HasSSE1]>;
249   def FsFLD0SD : I<0, Pseudo, (outs FR64:$dst), (ins), "",
250                    [(set FR64:$dst, fpimm0)]>, Requires<[HasSSE2]>;
251 }
252
253 //===----------------------------------------------------------------------===//
254 // AVX & SSE - Zero/One Vectors
255 //===----------------------------------------------------------------------===//
256
257 // Alias instruction that maps zero vector to pxor / xorp* for sse.
258 // This is expanded by ExpandPostRAPseudos to an xorps / vxorps, and then
259 // swizzled by ExecutionDepsFix to pxor.
260 // We set canFoldAsLoad because this can be converted to a constant-pool
261 // load of an all-zeros value if folding it would be beneficial.
262 let isReMaterializable = 1, isAsCheapAsAMove = 1, canFoldAsLoad = 1,
263     isPseudo = 1, neverHasSideEffects = 1 in {
264 def V_SET0 : I<0, Pseudo, (outs VR128:$dst), (ins), "", []>;
265 }
266
267 def : Pat<(v4f32 immAllZerosV), (V_SET0)>;
268 def : Pat<(v2f64 immAllZerosV), (V_SET0)>;
269 def : Pat<(v4i32 immAllZerosV), (V_SET0)>;
270 def : Pat<(v2i64 immAllZerosV), (V_SET0)>;
271 def : Pat<(v8i16 immAllZerosV), (V_SET0)>;
272 def : Pat<(v16i8 immAllZerosV), (V_SET0)>;
273
274
275 // The same as done above but for AVX.  The 256-bit ISA does not support PI,
276 // and doesn't need it because on sandy bridge the register is set to zero
277 // at the rename stage without using any execution unit, so SET0PSY
278 // and SET0PDY can be used for vector int instructions without penalty
279 // FIXME: Change encoding to pseudo! This is blocked right now by the x86
280 // JIT implementatioan, it does not expand the instructions below like
281 // X86MCInstLower does.
282 let isReMaterializable = 1, isAsCheapAsAMove = 1, canFoldAsLoad = 1,
283     isCodeGenOnly = 1 in {
284 let Predicates = [HasAVX] in {
285 def AVX_SET0PSY : PSI<0x57, MRMInitReg, (outs VR256:$dst), (ins), "",
286                    [(set VR256:$dst, (v8f32 immAllZerosV))]>, VEX_4V;
287 def AVX_SET0PDY : PDI<0x57, MRMInitReg, (outs VR256:$dst), (ins), "",
288                    [(set VR256:$dst, (v4f64 immAllZerosV))]>, VEX_4V;
289 }
290 let Predicates = [HasAVX2], neverHasSideEffects = 1 in
291 def AVX2_SET0   : PDI<0xef, MRMInitReg, (outs VR256:$dst), (ins), "",
292                    []>, VEX_4V;
293 }
294
295 let Predicates = [HasAVX2], AddedComplexity = 5 in {
296   def : Pat<(v4i64 immAllZerosV), (AVX2_SET0)>;
297   def : Pat<(v8i32 immAllZerosV), (AVX2_SET0)>;
298   def : Pat<(v16i16 immAllZerosV), (AVX2_SET0)>;
299   def : Pat<(v32i8 immAllZerosV), (AVX2_SET0)>;
300 }
301
302 // AVX has no support for 256-bit integer instructions, but since the 128-bit
303 // VPXOR instruction writes zero to its upper part, it's safe build zeros.
304 def : Pat<(v32i8 immAllZerosV), (SUBREG_TO_REG (i8 0), (V_SET0), sub_xmm)>;
305 def : Pat<(bc_v32i8 (v8f32 immAllZerosV)),
306           (SUBREG_TO_REG (i8 0), (V_SET0), sub_xmm)>;
307
308 def : Pat<(v16i16 immAllZerosV), (SUBREG_TO_REG (i16 0), (V_SET0), sub_xmm)>;
309 def : Pat<(bc_v16i16 (v8f32 immAllZerosV)),
310           (SUBREG_TO_REG (i16 0), (V_SET0), sub_xmm)>;
311
312 def : Pat<(v8i32 immAllZerosV), (SUBREG_TO_REG (i32 0), (V_SET0), sub_xmm)>;
313 def : Pat<(bc_v8i32 (v8f32 immAllZerosV)),
314           (SUBREG_TO_REG (i32 0), (V_SET0), sub_xmm)>;
315
316 def : Pat<(v4i64 immAllZerosV), (SUBREG_TO_REG (i64 0), (V_SET0), sub_xmm)>;
317 def : Pat<(bc_v4i64 (v8f32 immAllZerosV)),
318           (SUBREG_TO_REG (i64 0), (V_SET0), sub_xmm)>;
319
320 // We set canFoldAsLoad because this can be converted to a constant-pool
321 // load of an all-ones value if folding it would be beneficial.
322 // FIXME: Change encoding to pseudo! This is blocked right now by the x86
323 // JIT implementation, it does not expand the instructions below like
324 // X86MCInstLower does.
325 let isReMaterializable = 1, isAsCheapAsAMove = 1, canFoldAsLoad = 1,
326     isCodeGenOnly = 1, ExeDomain = SSEPackedInt in {
327   let Predicates = [HasAVX] in
328   def AVX_SETALLONES : PDI<0x76, MRMInitReg, (outs VR128:$dst), (ins), "",
329                          [(set VR128:$dst, (v4i32 immAllOnesV))]>, VEX_4V;
330   def V_SETALLONES : PDI<0x76, MRMInitReg, (outs VR128:$dst), (ins), "",
331                          [(set VR128:$dst, (v4i32 immAllOnesV))]>;
332   let Predicates = [HasAVX2] in
333   def AVX2_SETALLONES : PDI<0x76, MRMInitReg, (outs VR256:$dst), (ins), "",
334                           [(set VR256:$dst, (v8i32 immAllOnesV))]>, VEX_4V;
335 }
336
337
338 //===----------------------------------------------------------------------===//
339 // SSE 1 & 2 - Move FP Scalar Instructions
340 //
341 // Move Instructions. Register-to-register movss/movsd is not used for FR32/64
342 // register copies because it's a partial register update; FsMOVAPSrr/FsMOVAPDrr
343 // is used instead. Register-to-register movss/movsd is not modeled as an
344 // INSERT_SUBREG because INSERT_SUBREG requires that the insert be implementable
345 // in terms of a copy, and just mentioned, we don't use movss/movsd for copies.
346 //===----------------------------------------------------------------------===//
347
348 class sse12_move_rr<RegisterClass RC, SDNode OpNode, ValueType vt, string asm> :
349       SI<0x10, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src1, RC:$src2), asm,
350       [(set VR128:$dst, (vt (OpNode VR128:$src1,
351                              (scalar_to_vector RC:$src2))))]>;
352
353 // Loading from memory automatically zeroing upper bits.
354 class sse12_move_rm<RegisterClass RC, X86MemOperand x86memop,
355                     PatFrag mem_pat, string OpcodeStr> :
356       SI<0x10, MRMSrcMem, (outs RC:$dst), (ins x86memop:$src),
357          !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
358                         [(set RC:$dst, (mem_pat addr:$src))]>;
359
360 // AVX
361 def VMOVSSrr : sse12_move_rr<FR32, X86Movss, v4f32,
362                 "movss\t{$src2, $src1, $dst|$dst, $src1, $src2}">, XS, VEX_4V,
363                 VEX_LIG;
364 def VMOVSDrr : sse12_move_rr<FR64, X86Movsd, v2f64,
365                 "movsd\t{$src2, $src1, $dst|$dst, $src1, $src2}">, XD, VEX_4V,
366                 VEX_LIG;
367
368 // For the disassembler
369 let isCodeGenOnly = 1 in {
370   def VMOVSSrr_REV : SI<0x11, MRMDestReg, (outs VR128:$dst),
371                         (ins VR128:$src1, FR32:$src2),
372                         "movss\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>,
373                         XS, VEX_4V, VEX_LIG;
374   def VMOVSDrr_REV : SI<0x11, MRMDestReg, (outs VR128:$dst),
375                         (ins VR128:$src1, FR64:$src2),
376                         "movsd\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>,
377                         XD, VEX_4V, VEX_LIG;
378 }
379
380 let canFoldAsLoad = 1, isReMaterializable = 1 in {
381   def VMOVSSrm : sse12_move_rm<FR32, f32mem, loadf32, "movss">, XS, VEX,
382                  VEX_LIG;
383   let AddedComplexity = 20 in
384     def VMOVSDrm : sse12_move_rm<FR64, f64mem, loadf64, "movsd">, XD, VEX,
385                    VEX_LIG;
386 }
387
388 def VMOVSSmr : SI<0x11, MRMDestMem, (outs), (ins f32mem:$dst, FR32:$src),
389                   "movss\t{$src, $dst|$dst, $src}",
390                   [(store FR32:$src, addr:$dst)]>, XS, VEX, VEX_LIG;
391 def VMOVSDmr : SI<0x11, MRMDestMem, (outs), (ins f64mem:$dst, FR64:$src),
392                   "movsd\t{$src, $dst|$dst, $src}",
393                   [(store FR64:$src, addr:$dst)]>, XD, VEX, VEX_LIG;
394
395 // SSE1 & 2
396 let Constraints = "$src1 = $dst" in {
397   def MOVSSrr : sse12_move_rr<FR32, X86Movss, v4f32,
398                           "movss\t{$src2, $dst|$dst, $src2}">, XS;
399   def MOVSDrr : sse12_move_rr<FR64, X86Movsd, v2f64,
400                           "movsd\t{$src2, $dst|$dst, $src2}">, XD;
401
402   // For the disassembler
403   let isCodeGenOnly = 1 in {
404     def MOVSSrr_REV : SI<0x11, MRMDestReg, (outs VR128:$dst),
405                          (ins VR128:$src1, FR32:$src2),
406                          "movss\t{$src2, $dst|$dst, $src2}", []>, XS;
407     def MOVSDrr_REV : SI<0x11, MRMDestReg, (outs VR128:$dst),
408                          (ins VR128:$src1, FR64:$src2),
409                          "movsd\t{$src2, $dst|$dst, $src2}", []>, XD;
410   }
411 }
412
413 let canFoldAsLoad = 1, isReMaterializable = 1 in {
414   def MOVSSrm : sse12_move_rm<FR32, f32mem, loadf32, "movss">, XS;
415
416   let AddedComplexity = 20 in
417     def MOVSDrm : sse12_move_rm<FR64, f64mem, loadf64, "movsd">, XD;
418 }
419
420 def MOVSSmr : SSI<0x11, MRMDestMem, (outs), (ins f32mem:$dst, FR32:$src),
421                   "movss\t{$src, $dst|$dst, $src}",
422                   [(store FR32:$src, addr:$dst)]>;
423 def MOVSDmr : SDI<0x11, MRMDestMem, (outs), (ins f64mem:$dst, FR64:$src),
424                   "movsd\t{$src, $dst|$dst, $src}",
425                   [(store FR64:$src, addr:$dst)]>;
426
427 // Patterns
428 let Predicates = [HasAVX] in {
429   let AddedComplexity = 15 in {
430   // Move scalar to XMM zero-extended, zeroing a VR128 then do a
431   // MOVS{S,D} to the lower bits.
432   def : Pat<(v4f32 (X86vzmovl (v4f32 (scalar_to_vector FR32:$src)))),
433             (VMOVSSrr (v4f32 (V_SET0)), FR32:$src)>;
434   def : Pat<(v4f32 (X86vzmovl (v4f32 VR128:$src))),
435             (VMOVSSrr (v4f32 (V_SET0)),
436                       (f32 (EXTRACT_SUBREG (v4f32 VR128:$src), sub_ss)))>;
437   def : Pat<(v4i32 (X86vzmovl (v4i32 VR128:$src))),
438             (VMOVSSrr (v4i32 (V_SET0)),
439                       (EXTRACT_SUBREG (v4i32 VR128:$src), sub_ss))>;
440   def : Pat<(v2f64 (X86vzmovl (v2f64 (scalar_to_vector FR64:$src)))),
441             (VMOVSDrr (v2f64 (V_SET0)), FR64:$src)>;
442
443   // Move low f32 and clear high bits.
444   def : Pat<(v8f32 (X86vzmovl (v8f32 VR256:$src))),
445             (SUBREG_TO_REG (i32 0),
446               (VMOVSSrr (v4f32 (V_SET0)),
447                         (EXTRACT_SUBREG (v8f32 VR256:$src), sub_ss)), sub_xmm)>;
448   def : Pat<(v8i32 (X86vzmovl (v8i32 VR256:$src))),
449             (SUBREG_TO_REG (i32 0),
450               (VMOVSSrr (v4i32 (V_SET0)),
451                         (EXTRACT_SUBREG (v8i32 VR256:$src), sub_ss)), sub_xmm)>;
452   }
453
454   let AddedComplexity = 20 in {
455   // MOVSSrm zeros the high parts of the register; represent this
456   // with SUBREG_TO_REG. The AVX versions also write: DST[255:128] <- 0
457   def : Pat<(v4f32 (X86vzmovl (v4f32 (scalar_to_vector (loadf32 addr:$src))))),
458             (SUBREG_TO_REG (i32 0), (VMOVSSrm addr:$src), sub_ss)>;
459   def : Pat<(v4f32 (scalar_to_vector (loadf32 addr:$src))),
460             (SUBREG_TO_REG (i32 0), (VMOVSSrm addr:$src), sub_ss)>;
461   def : Pat<(v4f32 (X86vzmovl (loadv4f32 addr:$src))),
462             (SUBREG_TO_REG (i32 0), (VMOVSSrm addr:$src), sub_ss)>;
463
464   // MOVSDrm zeros the high parts of the register; represent this
465   // with SUBREG_TO_REG. The AVX versions also write: DST[255:128] <- 0
466   def : Pat<(v2f64 (X86vzmovl (v2f64 (scalar_to_vector (loadf64 addr:$src))))),
467             (SUBREG_TO_REG (i64 0), (VMOVSDrm addr:$src), sub_sd)>;
468   def : Pat<(v2f64 (scalar_to_vector (loadf64 addr:$src))),
469             (SUBREG_TO_REG (i64 0), (VMOVSDrm addr:$src), sub_sd)>;
470   def : Pat<(v2f64 (X86vzmovl (loadv2f64 addr:$src))),
471             (SUBREG_TO_REG (i64 0), (VMOVSDrm addr:$src), sub_sd)>;
472   def : Pat<(v2f64 (X86vzmovl (bc_v2f64 (loadv4f32 addr:$src)))),
473             (SUBREG_TO_REG (i64 0), (VMOVSDrm addr:$src), sub_sd)>;
474   def : Pat<(v2f64 (X86vzload addr:$src)),
475             (SUBREG_TO_REG (i64 0), (VMOVSDrm addr:$src), sub_sd)>;
476
477   // Represent the same patterns above but in the form they appear for
478   // 256-bit types
479   def : Pat<(v8i32 (X86vzmovl (insert_subvector undef,
480                    (v4i32 (scalar_to_vector (loadi32 addr:$src))), (i32 0)))),
481             (SUBREG_TO_REG (i32 0), (VMOVSSrm addr:$src), sub_ss)>;
482   def : Pat<(v8f32 (X86vzmovl (insert_subvector undef,
483                    (v4f32 (scalar_to_vector (loadf32 addr:$src))), (i32 0)))),
484             (SUBREG_TO_REG (i32 0), (VMOVSSrm addr:$src), sub_ss)>;
485   def : Pat<(v4f64 (X86vzmovl (insert_subvector undef,
486                    (v2f64 (scalar_to_vector (loadf64 addr:$src))), (i32 0)))),
487             (SUBREG_TO_REG (i32 0), (VMOVSDrm addr:$src), sub_sd)>;
488   }
489   def : Pat<(v8f32 (X86vzmovl (insert_subvector undef,
490                    (v4f32 (scalar_to_vector FR32:$src)), (i32 0)))),
491             (SUBREG_TO_REG (i32 0),
492                            (v4f32 (VMOVSSrr (v4f32 (V_SET0)), FR32:$src)),
493                            sub_xmm)>;
494   def : Pat<(v4f64 (X86vzmovl (insert_subvector undef,
495                    (v2f64 (scalar_to_vector FR64:$src)), (i32 0)))),
496             (SUBREG_TO_REG (i64 0),
497                            (v2f64 (VMOVSDrr (v2f64 (V_SET0)), FR64:$src)),
498                            sub_xmm)>;
499   def : Pat<(v4i64 (X86vzmovl (insert_subvector undef,
500                    (v2i64 (scalar_to_vector (loadi64 addr:$src))), (i32 0)))),
501             (SUBREG_TO_REG (i64 0), (VMOVSDrm addr:$src), sub_sd)>;
502
503   // Move low f64 and clear high bits.
504   def : Pat<(v4f64 (X86vzmovl (v4f64 VR256:$src))),
505             (SUBREG_TO_REG (i32 0),
506               (VMOVSDrr (v2f64 (V_SET0)),
507                         (EXTRACT_SUBREG (v4f64 VR256:$src), sub_sd)), sub_xmm)>;
508
509   def : Pat<(v4i64 (X86vzmovl (v4i64 VR256:$src))),
510             (SUBREG_TO_REG (i32 0),
511               (VMOVSDrr (v2i64 (V_SET0)),
512                         (EXTRACT_SUBREG (v4i64 VR256:$src), sub_sd)), sub_xmm)>;
513
514 // Extract and store.
515   def : Pat<(store (f32 (vector_extract (v4f32 VR128:$src), (iPTR 0))),
516                    addr:$dst),
517             (VMOVSSmr addr:$dst,
518                      (EXTRACT_SUBREG (v4f32 VR128:$src), sub_ss))>;
519   def : Pat<(store (f64 (vector_extract (v2f64 VR128:$src), (iPTR 0))),
520                    addr:$dst),
521             (VMOVSDmr addr:$dst,
522                      (EXTRACT_SUBREG (v2f64 VR128:$src), sub_sd))>;
523
524   // Shuffle with VMOVSS
525   def : Pat<(v4i32 (X86Movss VR128:$src1, VR128:$src2)),
526             (VMOVSSrr (v4i32 VR128:$src1),
527                       (EXTRACT_SUBREG (v4i32 VR128:$src2), sub_ss))>;
528   def : Pat<(v4f32 (X86Movss VR128:$src1, VR128:$src2)),
529             (VMOVSSrr (v4f32 VR128:$src1),
530                       (EXTRACT_SUBREG (v4f32 VR128:$src2), sub_ss))>;
531
532   // 256-bit variants
533   def : Pat<(v8i32 (X86Movss VR256:$src1, VR256:$src2)),
534             (SUBREG_TO_REG (i32 0),
535                 (VMOVSSrr (EXTRACT_SUBREG (v8i32 VR256:$src1), sub_ss),
536                           (EXTRACT_SUBREG (v8i32 VR256:$src2), sub_ss)), sub_xmm)>;
537   def : Pat<(v8f32 (X86Movss VR256:$src1, VR256:$src2)),
538             (SUBREG_TO_REG (i32 0),
539                 (VMOVSSrr (EXTRACT_SUBREG (v8f32 VR256:$src1), sub_ss),
540                           (EXTRACT_SUBREG (v8f32 VR256:$src2), sub_ss)), sub_xmm)>;
541
542   // Shuffle with VMOVSD
543   def : Pat<(v2i64 (X86Movsd VR128:$src1, VR128:$src2)),
544             (VMOVSDrr (v2i64 VR128:$src1),
545                      (EXTRACT_SUBREG (v2i64 VR128:$src2), sub_sd))>;
546   def : Pat<(v2f64 (X86Movsd VR128:$src1, VR128:$src2)),
547             (VMOVSDrr (v2f64 VR128:$src1),
548                      (EXTRACT_SUBREG (v2f64 VR128:$src2), sub_sd))>;
549   def : Pat<(v4f32 (X86Movsd VR128:$src1, VR128:$src2)),
550             (VMOVSDrr VR128:$src1, (EXTRACT_SUBREG (v4f32 VR128:$src2),
551                                                    sub_sd))>;
552   def : Pat<(v4i32 (X86Movsd VR128:$src1, VR128:$src2)),
553             (VMOVSDrr VR128:$src1, (EXTRACT_SUBREG (v4i32 VR128:$src2),
554                                                    sub_sd))>;
555
556   // 256-bit variants
557   def : Pat<(v4i64 (X86Movsd VR256:$src1, VR256:$src2)),
558             (SUBREG_TO_REG (i32 0),
559                 (VMOVSDrr (EXTRACT_SUBREG (v4i64 VR256:$src1), sub_sd),
560                           (EXTRACT_SUBREG (v4i64 VR256:$src2), sub_sd)), sub_xmm)>;
561   def : Pat<(v4f64 (X86Movsd VR256:$src1, VR256:$src2)),
562             (SUBREG_TO_REG (i32 0),
563                 (VMOVSDrr (EXTRACT_SUBREG (v4f64 VR256:$src1), sub_sd),
564                           (EXTRACT_SUBREG (v4f64 VR256:$src2), sub_sd)), sub_xmm)>;
565
566
567   // FIXME: Instead of a X86Movlps there should be a X86Movsd here, the problem
568   // is during lowering, where it's not possible to recognize the fold cause
569   // it has two uses through a bitcast. One use disappears at isel time and the
570   // fold opportunity reappears.
571   def : Pat<(v2f64 (X86Movlpd VR128:$src1, VR128:$src2)),
572             (VMOVSDrr VR128:$src1, (EXTRACT_SUBREG (v2f64 VR128:$src2),
573                                                    sub_sd))>;
574   def : Pat<(v2i64 (X86Movlpd VR128:$src1, VR128:$src2)),
575             (VMOVSDrr VR128:$src1, (EXTRACT_SUBREG (v2i64 VR128:$src2),
576                                                    sub_sd))>;
577   def : Pat<(v4f32 (X86Movlps VR128:$src1, VR128:$src2)),
578             (VMOVSDrr VR128:$src1, (EXTRACT_SUBREG (v4f32 VR128:$src2),
579                                                    sub_sd))>;
580   def : Pat<(v4i32 (X86Movlps VR128:$src1, VR128:$src2)),
581             (VMOVSDrr VR128:$src1, (EXTRACT_SUBREG (v4i32 VR128:$src2),
582                                                    sub_sd))>;
583 }
584
585 let Predicates = [HasSSE1] in {
586   let AddedComplexity = 15 in {
587   // Move scalar to XMM zero-extended, zeroing a VR128 then do a
588   // MOVSS to the lower bits.
589   def : Pat<(v4f32 (X86vzmovl (v4f32 (scalar_to_vector FR32:$src)))),
590             (MOVSSrr (v4f32 (V_SET0)), FR32:$src)>;
591   def : Pat<(v4f32 (X86vzmovl (v4f32 VR128:$src))),
592             (MOVSSrr (v4f32 (V_SET0)),
593                      (f32 (EXTRACT_SUBREG (v4f32 VR128:$src), sub_ss)))>;
594   def : Pat<(v4i32 (X86vzmovl (v4i32 VR128:$src))),
595             (MOVSSrr (v4i32 (V_SET0)),
596                      (EXTRACT_SUBREG (v4i32 VR128:$src), sub_ss))>;
597   }
598
599   let AddedComplexity = 20 in {
600   // MOVSSrm zeros the high parts of the register; represent this
601   // with SUBREG_TO_REG.
602   def : Pat<(v4f32 (X86vzmovl (v4f32 (scalar_to_vector (loadf32 addr:$src))))),
603             (SUBREG_TO_REG (i32 0), (MOVSSrm addr:$src), sub_ss)>;
604   def : Pat<(v4f32 (scalar_to_vector (loadf32 addr:$src))),
605             (SUBREG_TO_REG (i32 0), (MOVSSrm addr:$src), sub_ss)>;
606   def : Pat<(v4f32 (X86vzmovl (loadv4f32 addr:$src))),
607             (SUBREG_TO_REG (i32 0), (MOVSSrm addr:$src), sub_ss)>;
608   }
609
610   // Extract and store.
611   def : Pat<(store (f32 (vector_extract (v4f32 VR128:$src), (iPTR 0))),
612                    addr:$dst),
613             (MOVSSmr addr:$dst,
614                      (EXTRACT_SUBREG (v4f32 VR128:$src), sub_ss))>;
615
616   // Shuffle with MOVSS
617   def : Pat<(v4i32 (X86Movss VR128:$src1, VR128:$src2)),
618             (MOVSSrr (v4i32 VR128:$src1),
619                      (EXTRACT_SUBREG (v4i32 VR128:$src2), sub_ss))>;
620   def : Pat<(v4f32 (X86Movss VR128:$src1, VR128:$src2)),
621             (MOVSSrr (v4f32 VR128:$src1),
622                      (EXTRACT_SUBREG (v4f32 VR128:$src2), sub_ss))>;
623 }
624
625 let Predicates = [HasSSE2] in {
626   let AddedComplexity = 15 in {
627   // Move scalar to XMM zero-extended, zeroing a VR128 then do a
628   // MOVSD to the lower bits.
629   def : Pat<(v2f64 (X86vzmovl (v2f64 (scalar_to_vector FR64:$src)))),
630             (MOVSDrr (v2f64 (V_SET0)), FR64:$src)>;
631   }
632
633   let AddedComplexity = 20 in {
634   // MOVSDrm zeros the high parts of the register; represent this
635   // with SUBREG_TO_REG.
636   def : Pat<(v2f64 (X86vzmovl (v2f64 (scalar_to_vector (loadf64 addr:$src))))),
637             (SUBREG_TO_REG (i64 0), (MOVSDrm addr:$src), sub_sd)>;
638   def : Pat<(v2f64 (scalar_to_vector (loadf64 addr:$src))),
639             (SUBREG_TO_REG (i64 0), (MOVSDrm addr:$src), sub_sd)>;
640   def : Pat<(v2f64 (X86vzmovl (loadv2f64 addr:$src))),
641             (SUBREG_TO_REG (i64 0), (MOVSDrm addr:$src), sub_sd)>;
642   def : Pat<(v2f64 (X86vzmovl (bc_v2f64 (loadv4f32 addr:$src)))),
643             (SUBREG_TO_REG (i64 0), (MOVSDrm addr:$src), sub_sd)>;
644   def : Pat<(v2f64 (X86vzload addr:$src)),
645             (SUBREG_TO_REG (i64 0), (MOVSDrm addr:$src), sub_sd)>;
646   }
647
648   // Extract and store.
649   def : Pat<(store (f64 (vector_extract (v2f64 VR128:$src), (iPTR 0))),
650                    addr:$dst),
651             (MOVSDmr addr:$dst,
652                      (EXTRACT_SUBREG (v2f64 VR128:$src), sub_sd))>;
653
654   // Shuffle with MOVSD
655   def : Pat<(v2i64 (X86Movsd VR128:$src1, VR128:$src2)),
656             (MOVSDrr (v2i64 VR128:$src1),
657                      (EXTRACT_SUBREG (v2i64 VR128:$src2), sub_sd))>;
658   def : Pat<(v2f64 (X86Movsd VR128:$src1, VR128:$src2)),
659             (MOVSDrr (v2f64 VR128:$src1),
660                      (EXTRACT_SUBREG (v2f64 VR128:$src2), sub_sd))>;
661   def : Pat<(v4f32 (X86Movsd VR128:$src1, VR128:$src2)),
662             (MOVSDrr VR128:$src1, (EXTRACT_SUBREG (v4f32 VR128:$src2),sub_sd))>;
663   def : Pat<(v4i32 (X86Movsd VR128:$src1, VR128:$src2)),
664             (MOVSDrr VR128:$src1, (EXTRACT_SUBREG (v4i32 VR128:$src2),sub_sd))>;
665
666   // FIXME: Instead of a X86Movlps there should be a X86Movsd here, the problem
667   // is during lowering, where it's not possible to recognize the fold cause
668   // it has two uses through a bitcast. One use disappears at isel time and the
669   // fold opportunity reappears.
670   def : Pat<(v2f64 (X86Movlpd VR128:$src1, VR128:$src2)),
671             (MOVSDrr VR128:$src1, (EXTRACT_SUBREG (v2f64 VR128:$src2),sub_sd))>;
672   def : Pat<(v2i64 (X86Movlpd VR128:$src1, VR128:$src2)),
673             (MOVSDrr VR128:$src1, (EXTRACT_SUBREG (v2i64 VR128:$src2),sub_sd))>;
674   def : Pat<(v4f32 (X86Movlps VR128:$src1, VR128:$src2)),
675             (MOVSDrr VR128:$src1, (EXTRACT_SUBREG (v4f32 VR128:$src2),sub_sd))>;
676   def : Pat<(v4i32 (X86Movlps VR128:$src1, VR128:$src2)),
677             (MOVSDrr VR128:$src1, (EXTRACT_SUBREG (v4i32 VR128:$src2),sub_sd))>;
678 }
679
680 //===----------------------------------------------------------------------===//
681 // SSE 1 & 2 - Move Aligned/Unaligned FP Instructions
682 //===----------------------------------------------------------------------===//
683
684 multiclass sse12_mov_packed<bits<8> opc, RegisterClass RC,
685                             X86MemOperand x86memop, PatFrag ld_frag,
686                             string asm, Domain d,
687                             bit IsReMaterializable = 1> {
688 let neverHasSideEffects = 1 in
689   def rr : PI<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src),
690               !strconcat(asm, "\t{$src, $dst|$dst, $src}"), [], IIC_DEFAULT, d>;
691 let canFoldAsLoad = 1, isReMaterializable = IsReMaterializable in
692   def rm : PI<opc, MRMSrcMem, (outs RC:$dst), (ins x86memop:$src),
693               !strconcat(asm, "\t{$src, $dst|$dst, $src}"),
694                    [(set RC:$dst, (ld_frag addr:$src))], IIC_DEFAULT, d>;
695 }
696
697 defm VMOVAPS : sse12_mov_packed<0x28, VR128, f128mem, alignedloadv4f32,
698                               "movaps", SSEPackedSingle>, TB, VEX;
699 defm VMOVAPD : sse12_mov_packed<0x28, VR128, f128mem, alignedloadv2f64,
700                               "movapd", SSEPackedDouble>, TB, OpSize, VEX;
701 defm VMOVUPS : sse12_mov_packed<0x10, VR128, f128mem, loadv4f32,
702                               "movups", SSEPackedSingle>, TB, VEX;
703 defm VMOVUPD : sse12_mov_packed<0x10, VR128, f128mem, loadv2f64,
704                               "movupd", SSEPackedDouble, 0>, TB, OpSize, VEX;
705
706 defm VMOVAPSY : sse12_mov_packed<0x28, VR256, f256mem, alignedloadv8f32,
707                               "movaps", SSEPackedSingle>, TB, VEX;
708 defm VMOVAPDY : sse12_mov_packed<0x28, VR256, f256mem, alignedloadv4f64,
709                               "movapd", SSEPackedDouble>, TB, OpSize, VEX;
710 defm VMOVUPSY : sse12_mov_packed<0x10, VR256, f256mem, loadv8f32,
711                               "movups", SSEPackedSingle>, TB, VEX;
712 defm VMOVUPDY : sse12_mov_packed<0x10, VR256, f256mem, loadv4f64,
713                               "movupd", SSEPackedDouble, 0>, TB, OpSize, VEX;
714 defm MOVAPS : sse12_mov_packed<0x28, VR128, f128mem, alignedloadv4f32,
715                               "movaps", SSEPackedSingle>, TB;
716 defm MOVAPD : sse12_mov_packed<0x28, VR128, f128mem, alignedloadv2f64,
717                               "movapd", SSEPackedDouble>, TB, OpSize;
718 defm MOVUPS : sse12_mov_packed<0x10, VR128, f128mem, loadv4f32,
719                               "movups", SSEPackedSingle>, TB;
720 defm MOVUPD : sse12_mov_packed<0x10, VR128, f128mem, loadv2f64,
721                               "movupd", SSEPackedDouble, 0>, TB, OpSize;
722
723 def VMOVAPSmr : VPSI<0x29, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
724                    "movaps\t{$src, $dst|$dst, $src}",
725                    [(alignedstore (v4f32 VR128:$src), addr:$dst)]>, VEX;
726 def VMOVAPDmr : VPDI<0x29, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
727                    "movapd\t{$src, $dst|$dst, $src}",
728                    [(alignedstore (v2f64 VR128:$src), addr:$dst)]>, VEX;
729 def VMOVUPSmr : VPSI<0x11, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
730                    "movups\t{$src, $dst|$dst, $src}",
731                    [(store (v4f32 VR128:$src), addr:$dst)]>, VEX;
732 def VMOVUPDmr : VPDI<0x11, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
733                    "movupd\t{$src, $dst|$dst, $src}",
734                    [(store (v2f64 VR128:$src), addr:$dst)]>, VEX;
735 def VMOVAPSYmr : VPSI<0x29, MRMDestMem, (outs), (ins f256mem:$dst, VR256:$src),
736                    "movaps\t{$src, $dst|$dst, $src}",
737                    [(alignedstore256 (v8f32 VR256:$src), addr:$dst)]>, VEX;
738 def VMOVAPDYmr : VPDI<0x29, MRMDestMem, (outs), (ins f256mem:$dst, VR256:$src),
739                    "movapd\t{$src, $dst|$dst, $src}",
740                    [(alignedstore256 (v4f64 VR256:$src), addr:$dst)]>, VEX;
741 def VMOVUPSYmr : VPSI<0x11, MRMDestMem, (outs), (ins f256mem:$dst, VR256:$src),
742                    "movups\t{$src, $dst|$dst, $src}",
743                    [(store (v8f32 VR256:$src), addr:$dst)]>, VEX;
744 def VMOVUPDYmr : VPDI<0x11, MRMDestMem, (outs), (ins f256mem:$dst, VR256:$src),
745                    "movupd\t{$src, $dst|$dst, $src}",
746                    [(store (v4f64 VR256:$src), addr:$dst)]>, VEX;
747
748 // For disassembler
749 let isCodeGenOnly = 1 in {
750   def VMOVAPSrr_REV : VPSI<0x29, MRMDestReg, (outs VR128:$dst),
751                           (ins VR128:$src),
752                           "movaps\t{$src, $dst|$dst, $src}", []>, VEX;
753   def VMOVAPDrr_REV : VPDI<0x29, MRMDestReg, (outs VR128:$dst),
754                            (ins VR128:$src),
755                            "movapd\t{$src, $dst|$dst, $src}", []>, VEX;
756   def VMOVUPSrr_REV : VPSI<0x11, MRMDestReg, (outs VR128:$dst),
757                            (ins VR128:$src),
758                            "movups\t{$src, $dst|$dst, $src}", []>, VEX;
759   def VMOVUPDrr_REV : VPDI<0x11, MRMDestReg, (outs VR128:$dst),
760                            (ins VR128:$src),
761                            "movupd\t{$src, $dst|$dst, $src}", []>, VEX;
762   def VMOVAPSYrr_REV : VPSI<0x29, MRMDestReg, (outs VR256:$dst),
763                             (ins VR256:$src),
764                             "movaps\t{$src, $dst|$dst, $src}", []>, VEX;
765   def VMOVAPDYrr_REV : VPDI<0x29, MRMDestReg, (outs VR256:$dst),
766                             (ins VR256:$src),
767                             "movapd\t{$src, $dst|$dst, $src}", []>, VEX;
768   def VMOVUPSYrr_REV : VPSI<0x11, MRMDestReg, (outs VR256:$dst),
769                             (ins VR256:$src),
770                             "movups\t{$src, $dst|$dst, $src}", []>, VEX;
771   def VMOVUPDYrr_REV : VPDI<0x11, MRMDestReg, (outs VR256:$dst),
772                             (ins VR256:$src),
773                             "movupd\t{$src, $dst|$dst, $src}", []>, VEX;
774 }
775
776 let Predicates = [HasAVX] in {
777 def : Pat<(v8i32 (X86vzmovl
778                         (insert_subvector undef, (v4i32 VR128:$src), (i32 0)))),
779           (SUBREG_TO_REG (i32 0), (VMOVAPSrr VR128:$src), sub_xmm)>;
780 def : Pat<(v4i64 (X86vzmovl
781                         (insert_subvector undef, (v2i64 VR128:$src), (i32 0)))),
782           (SUBREG_TO_REG (i32 0), (VMOVAPSrr VR128:$src), sub_xmm)>;
783 def : Pat<(v8f32 (X86vzmovl
784                         (insert_subvector undef, (v4f32 VR128:$src), (i32 0)))),
785           (SUBREG_TO_REG (i32 0), (VMOVAPSrr VR128:$src), sub_xmm)>;
786 def : Pat<(v4f64 (X86vzmovl
787                         (insert_subvector undef, (v2f64 VR128:$src), (i32 0)))),
788           (SUBREG_TO_REG (i32 0), (VMOVAPSrr VR128:$src), sub_xmm)>;
789 }
790
791
792 def : Pat<(int_x86_avx_storeu_ps_256 addr:$dst, VR256:$src),
793           (VMOVUPSYmr addr:$dst, VR256:$src)>;
794 def : Pat<(int_x86_avx_storeu_pd_256 addr:$dst, VR256:$src),
795           (VMOVUPDYmr addr:$dst, VR256:$src)>;
796
797 def MOVAPSmr : PSI<0x29, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
798                    "movaps\t{$src, $dst|$dst, $src}",
799                    [(alignedstore (v4f32 VR128:$src), addr:$dst)]>;
800 def MOVAPDmr : PDI<0x29, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
801                    "movapd\t{$src, $dst|$dst, $src}",
802                    [(alignedstore (v2f64 VR128:$src), addr:$dst)]>;
803 def MOVUPSmr : PSI<0x11, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
804                    "movups\t{$src, $dst|$dst, $src}",
805                    [(store (v4f32 VR128:$src), addr:$dst)]>;
806 def MOVUPDmr : PDI<0x11, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
807                    "movupd\t{$src, $dst|$dst, $src}",
808                    [(store (v2f64 VR128:$src), addr:$dst)]>;
809
810 // For disassembler
811 let isCodeGenOnly = 1 in {
812   def MOVAPSrr_REV : PSI<0x29, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
813                          "movaps\t{$src, $dst|$dst, $src}", []>;
814   def MOVAPDrr_REV : PDI<0x29, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
815                          "movapd\t{$src, $dst|$dst, $src}", []>;
816   def MOVUPSrr_REV : PSI<0x11, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
817                          "movups\t{$src, $dst|$dst, $src}", []>;
818   def MOVUPDrr_REV : PDI<0x11, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
819                          "movupd\t{$src, $dst|$dst, $src}", []>;
820 }
821
822 let Predicates = [HasAVX] in {
823   def : Pat<(int_x86_sse_storeu_ps addr:$dst, VR128:$src),
824             (VMOVUPSmr addr:$dst, VR128:$src)>;
825   def : Pat<(int_x86_sse2_storeu_pd addr:$dst, VR128:$src),
826             (VMOVUPDmr addr:$dst, VR128:$src)>;
827 }
828
829 let Predicates = [HasSSE1] in
830   def : Pat<(int_x86_sse_storeu_ps addr:$dst, VR128:$src),
831             (MOVUPSmr addr:$dst, VR128:$src)>;
832 let Predicates = [HasSSE2] in
833   def : Pat<(int_x86_sse2_storeu_pd addr:$dst, VR128:$src),
834             (MOVUPDmr addr:$dst, VR128:$src)>;
835
836 // Use vmovaps/vmovups for AVX integer load/store.
837 let Predicates = [HasAVX] in {
838   // 128-bit load/store
839   def : Pat<(alignedloadv2i64 addr:$src),
840             (VMOVAPSrm addr:$src)>;
841   def : Pat<(loadv2i64 addr:$src),
842             (VMOVUPSrm addr:$src)>;
843
844   def : Pat<(alignedstore (v2i64 VR128:$src), addr:$dst),
845             (VMOVAPSmr addr:$dst, VR128:$src)>;
846   def : Pat<(alignedstore (v4i32 VR128:$src), addr:$dst),
847             (VMOVAPSmr addr:$dst, VR128:$src)>;
848   def : Pat<(alignedstore (v8i16 VR128:$src), addr:$dst),
849             (VMOVAPSmr addr:$dst, VR128:$src)>;
850   def : Pat<(alignedstore (v16i8 VR128:$src), addr:$dst),
851             (VMOVAPSmr addr:$dst, VR128:$src)>;
852   def : Pat<(store (v2i64 VR128:$src), addr:$dst),
853             (VMOVUPSmr addr:$dst, VR128:$src)>;
854   def : Pat<(store (v4i32 VR128:$src), addr:$dst),
855             (VMOVUPSmr addr:$dst, VR128:$src)>;
856   def : Pat<(store (v8i16 VR128:$src), addr:$dst),
857             (VMOVUPSmr addr:$dst, VR128:$src)>;
858   def : Pat<(store (v16i8 VR128:$src), addr:$dst),
859             (VMOVUPSmr addr:$dst, VR128:$src)>;
860
861   // 256-bit load/store
862   def : Pat<(alignedloadv4i64 addr:$src),
863             (VMOVAPSYrm addr:$src)>;
864   def : Pat<(loadv4i64 addr:$src),
865             (VMOVUPSYrm addr:$src)>;
866   def : Pat<(alignedstore256 (v4i64 VR256:$src), addr:$dst),
867             (VMOVAPSYmr addr:$dst, VR256:$src)>;
868   def : Pat<(alignedstore256 (v8i32 VR256:$src), addr:$dst),
869             (VMOVAPSYmr addr:$dst, VR256:$src)>;
870   def : Pat<(alignedstore256 (v16i16 VR256:$src), addr:$dst),
871             (VMOVAPSYmr addr:$dst, VR256:$src)>;
872   def : Pat<(alignedstore256 (v32i8 VR256:$src), addr:$dst),
873             (VMOVAPSYmr addr:$dst, VR256:$src)>;
874   def : Pat<(store (v4i64 VR256:$src), addr:$dst),
875             (VMOVUPSYmr addr:$dst, VR256:$src)>;
876   def : Pat<(store (v8i32 VR256:$src), addr:$dst),
877             (VMOVUPSYmr addr:$dst, VR256:$src)>;
878   def : Pat<(store (v16i16 VR256:$src), addr:$dst),
879             (VMOVUPSYmr addr:$dst, VR256:$src)>;
880   def : Pat<(store (v32i8 VR256:$src), addr:$dst),
881             (VMOVUPSYmr addr:$dst, VR256:$src)>;
882 }
883
884 // Use movaps / movups for SSE integer load / store (one byte shorter).
885 // The instructions selected below are then converted to MOVDQA/MOVDQU
886 // during the SSE domain pass.
887 let Predicates = [HasSSE1] in {
888   def : Pat<(alignedloadv2i64 addr:$src),
889             (MOVAPSrm addr:$src)>;
890   def : Pat<(loadv2i64 addr:$src),
891             (MOVUPSrm addr:$src)>;
892
893   def : Pat<(alignedstore (v2i64 VR128:$src), addr:$dst),
894             (MOVAPSmr addr:$dst, VR128:$src)>;
895   def : Pat<(alignedstore (v4i32 VR128:$src), addr:$dst),
896             (MOVAPSmr addr:$dst, VR128:$src)>;
897   def : Pat<(alignedstore (v8i16 VR128:$src), addr:$dst),
898             (MOVAPSmr addr:$dst, VR128:$src)>;
899   def : Pat<(alignedstore (v16i8 VR128:$src), addr:$dst),
900             (MOVAPSmr addr:$dst, VR128:$src)>;
901   def : Pat<(store (v2i64 VR128:$src), addr:$dst),
902             (MOVUPSmr addr:$dst, VR128:$src)>;
903   def : Pat<(store (v4i32 VR128:$src), addr:$dst),
904             (MOVUPSmr addr:$dst, VR128:$src)>;
905   def : Pat<(store (v8i16 VR128:$src), addr:$dst),
906             (MOVUPSmr addr:$dst, VR128:$src)>;
907   def : Pat<(store (v16i8 VR128:$src), addr:$dst),
908             (MOVUPSmr addr:$dst, VR128:$src)>;
909 }
910
911 // Alias instruction to do FR32 or FR64 reg-to-reg copy using movaps. Upper
912 // bits are disregarded. FIXME: Set encoding to pseudo!
913 let neverHasSideEffects = 1 in {
914 def FsVMOVAPSrr : VPSI<0x28, MRMSrcReg, (outs FR32:$dst), (ins FR32:$src),
915                        "movaps\t{$src, $dst|$dst, $src}", []>, VEX;
916 def FsVMOVAPDrr : VPDI<0x28, MRMSrcReg, (outs FR64:$dst), (ins FR64:$src),
917                        "movapd\t{$src, $dst|$dst, $src}", []>, VEX;
918 def FsMOVAPSrr : PSI<0x28, MRMSrcReg, (outs FR32:$dst), (ins FR32:$src),
919                      "movaps\t{$src, $dst|$dst, $src}", []>;
920 def FsMOVAPDrr : PDI<0x28, MRMSrcReg, (outs FR64:$dst), (ins FR64:$src),
921                      "movapd\t{$src, $dst|$dst, $src}", []>;
922 }
923
924 // Alias instruction to load FR32 or FR64 from f128mem using movaps. Upper
925 // bits are disregarded. FIXME: Set encoding to pseudo!
926 let canFoldAsLoad = 1, isReMaterializable = 1 in {
927 let isCodeGenOnly = 1 in {
928   def FsVMOVAPSrm : VPSI<0x28, MRMSrcMem, (outs FR32:$dst), (ins f128mem:$src),
929                          "movaps\t{$src, $dst|$dst, $src}",
930                          [(set FR32:$dst, (alignedloadfsf32 addr:$src))]>, VEX;
931   def FsVMOVAPDrm : VPDI<0x28, MRMSrcMem, (outs FR64:$dst), (ins f128mem:$src),
932                          "movapd\t{$src, $dst|$dst, $src}",
933                          [(set FR64:$dst, (alignedloadfsf64 addr:$src))]>, VEX;
934 }
935 def FsMOVAPSrm : PSI<0x28, MRMSrcMem, (outs FR32:$dst), (ins f128mem:$src),
936                      "movaps\t{$src, $dst|$dst, $src}",
937                      [(set FR32:$dst, (alignedloadfsf32 addr:$src))]>;
938 def FsMOVAPDrm : PDI<0x28, MRMSrcMem, (outs FR64:$dst), (ins f128mem:$src),
939                      "movapd\t{$src, $dst|$dst, $src}",
940                      [(set FR64:$dst, (alignedloadfsf64 addr:$src))]>;
941 }
942
943 //===----------------------------------------------------------------------===//
944 // SSE 1 & 2 - Move Low packed FP Instructions
945 //===----------------------------------------------------------------------===//
946
947 multiclass sse12_mov_hilo_packed<bits<8>opc, RegisterClass RC,
948                                  PatFrag mov_frag, string base_opc,
949                                  string asm_opr> {
950   def PSrm : PI<opc, MRMSrcMem,
951          (outs VR128:$dst), (ins VR128:$src1, f64mem:$src2),
952          !strconcat(base_opc, "s", asm_opr),
953      [(set RC:$dst,
954        (mov_frag RC:$src1,
955               (bc_v4f32 (v2f64 (scalar_to_vector (loadf64 addr:$src2))))))],
956               IIC_DEFAULT, SSEPackedSingle>, TB;
957
958   def PDrm : PI<opc, MRMSrcMem,
959          (outs RC:$dst), (ins RC:$src1, f64mem:$src2),
960          !strconcat(base_opc, "d", asm_opr),
961      [(set RC:$dst, (v2f64 (mov_frag RC:$src1,
962                               (scalar_to_vector (loadf64 addr:$src2)))))],
963               IIC_DEFAULT, SSEPackedDouble>, TB, OpSize;
964 }
965
966 let AddedComplexity = 20 in {
967   defm VMOVL : sse12_mov_hilo_packed<0x12, VR128, movlp, "movlp",
968                      "\t{$src2, $src1, $dst|$dst, $src1, $src2}">, VEX_4V;
969 }
970 let Constraints = "$src1 = $dst", AddedComplexity = 20 in {
971   defm MOVL : sse12_mov_hilo_packed<0x12, VR128, movlp, "movlp",
972                                    "\t{$src2, $dst|$dst, $src2}">;
973 }
974
975 def VMOVLPSmr : VPSI<0x13, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
976                    "movlps\t{$src, $dst|$dst, $src}",
977                    [(store (f64 (vector_extract (bc_v2f64 (v4f32 VR128:$src)),
978                                  (iPTR 0))), addr:$dst)]>, VEX;
979 def VMOVLPDmr : VPDI<0x13, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
980                    "movlpd\t{$src, $dst|$dst, $src}",
981                    [(store (f64 (vector_extract (v2f64 VR128:$src),
982                                  (iPTR 0))), addr:$dst)]>, VEX;
983 def MOVLPSmr : PSI<0x13, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
984                    "movlps\t{$src, $dst|$dst, $src}",
985                    [(store (f64 (vector_extract (bc_v2f64 (v4f32 VR128:$src)),
986                                  (iPTR 0))), addr:$dst)]>;
987 def MOVLPDmr : PDI<0x13, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
988                    "movlpd\t{$src, $dst|$dst, $src}",
989                    [(store (f64 (vector_extract (v2f64 VR128:$src),
990                                  (iPTR 0))), addr:$dst)]>;
991
992 let Predicates = [HasAVX] in {
993   let AddedComplexity = 20 in {
994     // vector_shuffle v1, (load v2) <4, 5, 2, 3> using MOVLPS
995     def : Pat<(v4f32 (movlp VR128:$src1, (load addr:$src2))),
996               (VMOVLPSrm VR128:$src1, addr:$src2)>;
997     def : Pat<(v4i32 (movlp VR128:$src1, (load addr:$src2))),
998               (VMOVLPSrm VR128:$src1, addr:$src2)>;
999     // vector_shuffle v1, (load v2) <2, 1> using MOVLPS
1000     def : Pat<(v2f64 (movlp VR128:$src1, (load addr:$src2))),
1001               (VMOVLPDrm VR128:$src1, addr:$src2)>;
1002     def : Pat<(v2i64 (movlp VR128:$src1, (load addr:$src2))),
1003               (VMOVLPDrm VR128:$src1, addr:$src2)>;
1004   }
1005
1006   // (store (vector_shuffle (load addr), v2, <4, 5, 2, 3>), addr) using MOVLPS
1007   def : Pat<(store (v4f32 (movlp (load addr:$src1), VR128:$src2)), addr:$src1),
1008             (VMOVLPSmr addr:$src1, VR128:$src2)>;
1009   def : Pat<(store (v4i32 (movlp (bc_v4i32 (loadv2i64 addr:$src1)),
1010                                  VR128:$src2)), addr:$src1),
1011             (VMOVLPSmr addr:$src1, VR128:$src2)>;
1012
1013   // (store (vector_shuffle (load addr), v2, <2, 1>), addr) using MOVLPS
1014   def : Pat<(store (v2f64 (movlp (load addr:$src1), VR128:$src2)), addr:$src1),
1015             (VMOVLPDmr addr:$src1, VR128:$src2)>;
1016   def : Pat<(store (v2i64 (movlp (load addr:$src1), VR128:$src2)), addr:$src1),
1017             (VMOVLPDmr addr:$src1, VR128:$src2)>;
1018
1019   // Shuffle with VMOVLPS
1020   def : Pat<(v4f32 (X86Movlps VR128:$src1, (load addr:$src2))),
1021             (VMOVLPSrm VR128:$src1, addr:$src2)>;
1022   def : Pat<(v4i32 (X86Movlps VR128:$src1, (load addr:$src2))),
1023             (VMOVLPSrm VR128:$src1, addr:$src2)>;
1024   def : Pat<(X86Movlps VR128:$src1,
1025                       (bc_v4f32 (v2f64 (scalar_to_vector (loadf64 addr:$src2))))),
1026             (VMOVLPSrm VR128:$src1, addr:$src2)>;
1027
1028   // Shuffle with VMOVLPD
1029   def : Pat<(v2f64 (X86Movlpd VR128:$src1, (load addr:$src2))),
1030             (VMOVLPDrm VR128:$src1, addr:$src2)>;
1031   def : Pat<(v2i64 (X86Movlpd VR128:$src1, (load addr:$src2))),
1032             (VMOVLPDrm VR128:$src1, addr:$src2)>;
1033   def : Pat<(v2f64 (X86Movlpd VR128:$src1,
1034                               (scalar_to_vector (loadf64 addr:$src2)))),
1035             (VMOVLPDrm VR128:$src1, addr:$src2)>;
1036
1037   // Store patterns
1038   def : Pat<(store (v4f32 (X86Movlps (load addr:$src1), VR128:$src2)),
1039                    addr:$src1),
1040             (VMOVLPSmr addr:$src1, VR128:$src2)>;
1041   def : Pat<(store (v4i32 (X86Movlps
1042                    (bc_v4i32 (loadv2i64 addr:$src1)), VR128:$src2)), addr:$src1),
1043             (VMOVLPSmr addr:$src1, VR128:$src2)>;
1044   def : Pat<(store (v2f64 (X86Movlpd (load addr:$src1), VR128:$src2)),
1045                    addr:$src1),
1046             (VMOVLPDmr addr:$src1, VR128:$src2)>;
1047   def : Pat<(store (v2i64 (X86Movlpd (load addr:$src1), VR128:$src2)),
1048                    addr:$src1),
1049             (VMOVLPDmr addr:$src1, VR128:$src2)>;
1050 }
1051
1052 let Predicates = [HasSSE1] in {
1053   let AddedComplexity = 20 in {
1054     // vector_shuffle v1, (load v2) <4, 5, 2, 3> using MOVLPS
1055     def : Pat<(v4f32 (movlp VR128:$src1, (load addr:$src2))),
1056               (MOVLPSrm VR128:$src1, addr:$src2)>;
1057     def : Pat<(v4i32 (movlp VR128:$src1, (load addr:$src2))),
1058               (MOVLPSrm VR128:$src1, addr:$src2)>;
1059   }
1060
1061   // (store (vector_shuffle (load addr), v2, <4, 5, 2, 3>), addr) using MOVLPS
1062   def : Pat<(store (i64 (vector_extract (bc_v2i64 (v4f32 VR128:$src2)),
1063                                  (iPTR 0))), addr:$src1),
1064             (MOVLPSmr addr:$src1, VR128:$src2)>;
1065   def : Pat<(store (v4f32 (movlp (load addr:$src1), VR128:$src2)), addr:$src1),
1066             (MOVLPSmr addr:$src1, VR128:$src2)>;
1067   def : Pat<(store (v4i32 (movlp (bc_v4i32 (loadv2i64 addr:$src1)),
1068                                  VR128:$src2)), addr:$src1),
1069             (MOVLPSmr addr:$src1, VR128:$src2)>;
1070
1071   // Shuffle with MOVLPS
1072   def : Pat<(v4f32 (X86Movlps VR128:$src1, (load addr:$src2))),
1073             (MOVLPSrm VR128:$src1, addr:$src2)>;
1074   def : Pat<(v4i32 (X86Movlps VR128:$src1, (load addr:$src2))),
1075             (MOVLPSrm VR128:$src1, addr:$src2)>;
1076   def : Pat<(X86Movlps VR128:$src1,
1077                       (bc_v4f32 (v2f64 (scalar_to_vector (loadf64 addr:$src2))))),
1078             (MOVLPSrm VR128:$src1, addr:$src2)>;
1079   def : Pat<(X86Movlps VR128:$src1,
1080                       (bc_v4f32 (v2i64 (scalar_to_vector (loadi64 addr:$src2))))),
1081             (MOVLPSrm VR128:$src1, addr:$src2)>;
1082
1083   // Store patterns
1084   def : Pat<(store (v4f32 (X86Movlps (load addr:$src1), VR128:$src2)),
1085                                       addr:$src1),
1086             (MOVLPSmr addr:$src1, VR128:$src2)>;
1087   def : Pat<(store (v4i32 (X86Movlps
1088                    (bc_v4i32 (loadv2i64 addr:$src1)), VR128:$src2)),
1089                               addr:$src1),
1090             (MOVLPSmr addr:$src1, VR128:$src2)>;
1091 }
1092
1093 let Predicates = [HasSSE2] in {
1094   let AddedComplexity = 20 in {
1095     // vector_shuffle v1, (load v2) <2, 1> using MOVLPS
1096     def : Pat<(v2f64 (movlp VR128:$src1, (load addr:$src2))),
1097               (MOVLPDrm VR128:$src1, addr:$src2)>;
1098     def : Pat<(v2i64 (movlp VR128:$src1, (load addr:$src2))),
1099               (MOVLPDrm VR128:$src1, addr:$src2)>;
1100   }
1101
1102   // (store (vector_shuffle (load addr), v2, <2, 1>), addr) using MOVLPS
1103   def : Pat<(store (v2f64 (movlp (load addr:$src1), VR128:$src2)), addr:$src1),
1104             (MOVLPDmr addr:$src1, VR128:$src2)>;
1105   def : Pat<(store (v2i64 (movlp (load addr:$src1), VR128:$src2)), addr:$src1),
1106             (MOVLPDmr addr:$src1, VR128:$src2)>;
1107
1108   // Shuffle with MOVLPD
1109   def : Pat<(v2f64 (X86Movlpd VR128:$src1, (load addr:$src2))),
1110             (MOVLPDrm VR128:$src1, addr:$src2)>;
1111   def : Pat<(v2i64 (X86Movlpd VR128:$src1, (load addr:$src2))),
1112             (MOVLPDrm VR128:$src1, addr:$src2)>;
1113   def : Pat<(v2f64 (X86Movlpd VR128:$src1,
1114                               (scalar_to_vector (loadf64 addr:$src2)))),
1115             (MOVLPDrm VR128:$src1, addr:$src2)>;
1116
1117   // Store patterns
1118   def : Pat<(store (v2f64 (X86Movlpd (load addr:$src1), VR128:$src2)),
1119                            addr:$src1),
1120             (MOVLPDmr addr:$src1, VR128:$src2)>;
1121   def : Pat<(store (v2i64 (X86Movlpd (load addr:$src1), VR128:$src2)),
1122                            addr:$src1),
1123             (MOVLPDmr addr:$src1, VR128:$src2)>;
1124 }
1125
1126 //===----------------------------------------------------------------------===//
1127 // SSE 1 & 2 - Move Hi packed FP Instructions
1128 //===----------------------------------------------------------------------===//
1129
1130 let AddedComplexity = 20 in {
1131   defm VMOVH : sse12_mov_hilo_packed<0x16, VR128, movlhps, "movhp",
1132                      "\t{$src2, $src1, $dst|$dst, $src1, $src2}">, VEX_4V;
1133 }
1134 let Constraints = "$src1 = $dst", AddedComplexity = 20 in {
1135   defm MOVH : sse12_mov_hilo_packed<0x16, VR128, movlhps, "movhp",
1136                                    "\t{$src2, $dst|$dst, $src2}">;
1137 }
1138
1139 // v2f64 extract element 1 is always custom lowered to unpack high to low
1140 // and extract element 0 so the non-store version isn't too horrible.
1141 def VMOVHPSmr : VPSI<0x17, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
1142                    "movhps\t{$src, $dst|$dst, $src}",
1143                    [(store (f64 (vector_extract
1144                                  (X86Unpckh (bc_v2f64 (v4f32 VR128:$src)),
1145                                             (bc_v2f64 (v4f32 VR128:$src))),
1146                                  (iPTR 0))), addr:$dst)]>, VEX;
1147 def VMOVHPDmr : VPDI<0x17, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
1148                    "movhpd\t{$src, $dst|$dst, $src}",
1149                    [(store (f64 (vector_extract
1150                                  (v2f64 (X86Unpckh VR128:$src, VR128:$src)),
1151                                  (iPTR 0))), addr:$dst)]>, VEX;
1152 def MOVHPSmr : PSI<0x17, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
1153                    "movhps\t{$src, $dst|$dst, $src}",
1154                    [(store (f64 (vector_extract
1155                                  (X86Unpckh (bc_v2f64 (v4f32 VR128:$src)),
1156                                             (bc_v2f64 (v4f32 VR128:$src))),
1157                                  (iPTR 0))), addr:$dst)]>;
1158 def MOVHPDmr : PDI<0x17, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
1159                    "movhpd\t{$src, $dst|$dst, $src}",
1160                    [(store (f64 (vector_extract
1161                                  (v2f64 (X86Unpckh VR128:$src, VR128:$src)),
1162                                  (iPTR 0))), addr:$dst)]>;
1163
1164 let Predicates = [HasAVX] in {
1165   // VMOVHPS patterns
1166   def : Pat<(movlhps VR128:$src1, (bc_v4i32 (v2i64 (X86vzload addr:$src2)))),
1167             (VMOVHPSrm (v4i32 VR128:$src1), addr:$src2)>;
1168   def : Pat<(X86Movlhps VR128:$src1,
1169                  (bc_v4f32 (v2f64 (scalar_to_vector (loadf64 addr:$src2))))),
1170             (VMOVHPSrm VR128:$src1, addr:$src2)>;
1171   def : Pat<(X86Movlhps VR128:$src1,
1172                  (bc_v4f32 (v2i64 (scalar_to_vector (loadi64 addr:$src2))))),
1173             (VMOVHPSrm VR128:$src1, addr:$src2)>;
1174   def : Pat<(X86Movlhps VR128:$src1,
1175                  (bc_v4i32 (v2i64 (X86vzload addr:$src2)))),
1176             (VMOVHPSrm VR128:$src1, addr:$src2)>;
1177
1178   // FIXME: Instead of X86Unpckl, there should be a X86Movlhpd here, the problem
1179   // is during lowering, where it's not possible to recognize the load fold 
1180   // cause it has two uses through a bitcast. One use disappears at isel time
1181   // and the fold opportunity reappears.
1182   def : Pat<(v2f64 (X86Unpckl VR128:$src1,
1183                       (scalar_to_vector (loadf64 addr:$src2)))),
1184             (VMOVHPDrm VR128:$src1, addr:$src2)>;
1185
1186   // FIXME: This should be matched by a X86Movhpd instead. Same as above
1187   def : Pat<(v2f64 (X86Movlhpd VR128:$src1,
1188                       (scalar_to_vector (loadf64 addr:$src2)))),
1189             (VMOVHPDrm VR128:$src1, addr:$src2)>;
1190 }
1191
1192 let Predicates = [HasSSE1] in {
1193   // MOVHPS patterns
1194   def : Pat<(movlhps VR128:$src1, (bc_v4i32 (v2i64 (X86vzload addr:$src2)))),
1195             (MOVHPSrm (v4i32 VR128:$src1), addr:$src2)>;
1196   def : Pat<(X86Movlhps VR128:$src1,
1197                  (bc_v4f32 (v2f64 (scalar_to_vector (loadf64 addr:$src2))))),
1198             (MOVHPSrm VR128:$src1, addr:$src2)>;
1199   def : Pat<(X86Movlhps VR128:$src1,
1200                  (bc_v4f32 (v2i64 (scalar_to_vector (loadi64 addr:$src2))))),
1201             (MOVHPSrm VR128:$src1, addr:$src2)>;
1202   def : Pat<(X86Movlhps VR128:$src1,
1203                  (bc_v4f32 (v2i64 (X86vzload addr:$src2)))),
1204             (MOVHPSrm VR128:$src1, addr:$src2)>;
1205 }
1206
1207 let Predicates = [HasSSE2] in {
1208   // FIXME: Instead of X86Unpckl, there should be a X86Movlhpd here, the problem
1209   // is during lowering, where it's not possible to recognize the load fold 
1210   // cause it has two uses through a bitcast. One use disappears at isel time
1211   // and the fold opportunity reappears.
1212   def : Pat<(v2f64 (X86Unpckl VR128:$src1,
1213                       (scalar_to_vector (loadf64 addr:$src2)))),
1214             (MOVHPDrm VR128:$src1, addr:$src2)>;
1215
1216   // FIXME: This should be matched by a X86Movhpd instead. Same as above
1217   def : Pat<(v2f64 (X86Movlhpd VR128:$src1,
1218                       (scalar_to_vector (loadf64 addr:$src2)))),
1219             (MOVHPDrm VR128:$src1, addr:$src2)>;
1220 }
1221
1222 //===----------------------------------------------------------------------===//
1223 // SSE 1 & 2 - Move Low to High and High to Low packed FP Instructions
1224 //===----------------------------------------------------------------------===//
1225
1226 let AddedComplexity = 20 in {
1227   def VMOVLHPSrr : VPSI<0x16, MRMSrcReg, (outs VR128:$dst),
1228                                        (ins VR128:$src1, VR128:$src2),
1229                       "movlhps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1230                       [(set VR128:$dst,
1231                         (v4f32 (X86Movlhps VR128:$src1, VR128:$src2)))]>,
1232                       VEX_4V;
1233   def VMOVHLPSrr : VPSI<0x12, MRMSrcReg, (outs VR128:$dst),
1234                                        (ins VR128:$src1, VR128:$src2),
1235                       "movhlps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1236                       [(set VR128:$dst,
1237                         (v4f32 (X86Movhlps VR128:$src1, VR128:$src2)))]>,
1238                       VEX_4V;
1239 }
1240 let Constraints = "$src1 = $dst", AddedComplexity = 20 in {
1241   def MOVLHPSrr : PSI<0x16, MRMSrcReg, (outs VR128:$dst),
1242                                        (ins VR128:$src1, VR128:$src2),
1243                       "movlhps\t{$src2, $dst|$dst, $src2}",
1244                       [(set VR128:$dst,
1245                         (v4f32 (X86Movlhps VR128:$src1, VR128:$src2)))]>;
1246   def MOVHLPSrr : PSI<0x12, MRMSrcReg, (outs VR128:$dst),
1247                                        (ins VR128:$src1, VR128:$src2),
1248                       "movhlps\t{$src2, $dst|$dst, $src2}",
1249                       [(set VR128:$dst,
1250                         (v4f32 (X86Movhlps VR128:$src1, VR128:$src2)))]>;
1251 }
1252
1253 let Predicates = [HasAVX] in {
1254   // MOVLHPS patterns
1255   def : Pat<(v4i32 (X86Movlhps VR128:$src1, VR128:$src2)),
1256             (VMOVLHPSrr VR128:$src1, VR128:$src2)>;
1257   def : Pat<(v2i64 (X86Movlhps VR128:$src1, VR128:$src2)),
1258             (VMOVLHPSrr (v2i64 VR128:$src1), VR128:$src2)>;
1259
1260   // MOVHLPS patterns
1261   def : Pat<(v4i32 (X86Movhlps VR128:$src1, VR128:$src2)),
1262             (VMOVHLPSrr VR128:$src1, VR128:$src2)>;
1263 }
1264
1265 let Predicates = [HasSSE1] in {
1266   // MOVLHPS patterns
1267   def : Pat<(v4i32 (X86Movlhps VR128:$src1, VR128:$src2)),
1268             (MOVLHPSrr VR128:$src1, VR128:$src2)>;
1269   def : Pat<(v2i64 (X86Movlhps VR128:$src1, VR128:$src2)),
1270             (MOVLHPSrr (v2i64 VR128:$src1), VR128:$src2)>;
1271
1272   // MOVHLPS patterns
1273   def : Pat<(v4i32 (X86Movhlps VR128:$src1, VR128:$src2)),
1274             (MOVHLPSrr VR128:$src1, VR128:$src2)>;
1275 }
1276
1277 //===----------------------------------------------------------------------===//
1278 // SSE 1 & 2 - Conversion Instructions
1279 //===----------------------------------------------------------------------===//
1280
1281 multiclass sse12_cvt_s<bits<8> opc, RegisterClass SrcRC, RegisterClass DstRC,
1282                      SDNode OpNode, X86MemOperand x86memop, PatFrag ld_frag,
1283                      string asm> {
1284   def rr : SI<opc, MRMSrcReg, (outs DstRC:$dst), (ins SrcRC:$src), asm,
1285                         [(set DstRC:$dst, (OpNode SrcRC:$src))]>;
1286   def rm : SI<opc, MRMSrcMem, (outs DstRC:$dst), (ins x86memop:$src), asm,
1287                         [(set DstRC:$dst, (OpNode (ld_frag addr:$src)))]>;
1288 }
1289
1290 multiclass sse12_cvt_p<bits<8> opc, RegisterClass SrcRC, RegisterClass DstRC,
1291                          SDNode OpNode, X86MemOperand x86memop, PatFrag ld_frag,
1292                          string asm, Domain d> {
1293   def rr : PI<opc, MRMSrcReg, (outs DstRC:$dst), (ins SrcRC:$src), asm,
1294                         [(set DstRC:$dst, (OpNode SrcRC:$src))],
1295                         IIC_DEFAULT, d>;
1296   def rm : PI<opc, MRMSrcMem, (outs DstRC:$dst), (ins x86memop:$src), asm,
1297                         [(set DstRC:$dst, (OpNode (ld_frag addr:$src)))],
1298                         IIC_DEFAULT, d>;
1299 }
1300
1301 multiclass sse12_vcvt_avx<bits<8> opc, RegisterClass SrcRC, RegisterClass DstRC,
1302                           X86MemOperand x86memop, string asm> {
1303 let neverHasSideEffects = 1 in {
1304   def rr : SI<opc, MRMSrcReg, (outs DstRC:$dst), (ins DstRC:$src1, SrcRC:$src),
1305               !strconcat(asm,"\t{$src, $src1, $dst|$dst, $src1, $src}"), []>;
1306   let mayLoad = 1 in
1307   def rm : SI<opc, MRMSrcMem, (outs DstRC:$dst),
1308               (ins DstRC:$src1, x86memop:$src),
1309               !strconcat(asm,"\t{$src, $src1, $dst|$dst, $src1, $src}"), []>;
1310 } // neverHasSideEffects = 1
1311 }
1312
1313 defm VCVTTSS2SI   : sse12_cvt_s<0x2C, FR32, GR32, fp_to_sint, f32mem, loadf32,
1314                                 "cvttss2si\t{$src, $dst|$dst, $src}">, XS, VEX,
1315                                 VEX_LIG;
1316 defm VCVTTSS2SI64 : sse12_cvt_s<0x2C, FR32, GR64, fp_to_sint, f32mem, loadf32,
1317                                 "cvttss2si\t{$src, $dst|$dst, $src}">, XS, VEX,
1318                                 VEX_W, VEX_LIG;
1319 defm VCVTTSD2SI   : sse12_cvt_s<0x2C, FR64, GR32, fp_to_sint, f64mem, loadf64,
1320                                 "cvttsd2si\t{$src, $dst|$dst, $src}">, XD, VEX,
1321                                 VEX_LIG;
1322 defm VCVTTSD2SI64 : sse12_cvt_s<0x2C, FR64, GR64, fp_to_sint, f64mem, loadf64,
1323                                 "cvttsd2si\t{$src, $dst|$dst, $src}">, XD,
1324                                 VEX, VEX_W, VEX_LIG;
1325
1326 // The assembler can recognize rr 64-bit instructions by seeing a rxx
1327 // register, but the same isn't true when only using memory operands,
1328 // provide other assembly "l" and "q" forms to address this explicitly
1329 // where appropriate to do so.
1330 defm VCVTSI2SS   : sse12_vcvt_avx<0x2A, GR32, FR32, i32mem, "cvtsi2ss">, XS,
1331                                   VEX_4V, VEX_LIG;
1332 defm VCVTSI2SS64 : sse12_vcvt_avx<0x2A, GR64, FR32, i64mem, "cvtsi2ss{q}">, XS,
1333                                   VEX_4V, VEX_W, VEX_LIG;
1334 defm VCVTSI2SD   : sse12_vcvt_avx<0x2A, GR32, FR64, i32mem, "cvtsi2sd">, XD,
1335                                   VEX_4V, VEX_LIG;
1336 defm VCVTSI2SDL  : sse12_vcvt_avx<0x2A, GR32, FR64, i32mem, "cvtsi2sd{l}">, XD,
1337                                   VEX_4V, VEX_LIG;
1338 defm VCVTSI2SD64 : sse12_vcvt_avx<0x2A, GR64, FR64, i64mem, "cvtsi2sd{q}">, XD,
1339                                   VEX_4V, VEX_W, VEX_LIG;
1340
1341 let Predicates = [HasAVX], AddedComplexity = 1 in {
1342   def : Pat<(f32 (sint_to_fp (loadi32 addr:$src))),
1343             (VCVTSI2SSrm (f32 (IMPLICIT_DEF)), addr:$src)>;
1344   def : Pat<(f32 (sint_to_fp (loadi64 addr:$src))),
1345             (VCVTSI2SS64rm (f32 (IMPLICIT_DEF)), addr:$src)>;
1346   def : Pat<(f64 (sint_to_fp (loadi32 addr:$src))),
1347             (VCVTSI2SDrm (f64 (IMPLICIT_DEF)), addr:$src)>;
1348   def : Pat<(f64 (sint_to_fp (loadi64 addr:$src))),
1349             (VCVTSI2SD64rm (f64 (IMPLICIT_DEF)), addr:$src)>;
1350
1351   def : Pat<(f32 (sint_to_fp GR32:$src)),
1352             (VCVTSI2SSrr (f32 (IMPLICIT_DEF)), GR32:$src)>;
1353   def : Pat<(f32 (sint_to_fp GR64:$src)),
1354             (VCVTSI2SS64rr (f32 (IMPLICIT_DEF)), GR64:$src)>;
1355   def : Pat<(f64 (sint_to_fp GR32:$src)),
1356             (VCVTSI2SDrr (f64 (IMPLICIT_DEF)), GR32:$src)>;
1357   def : Pat<(f64 (sint_to_fp GR64:$src)),
1358             (VCVTSI2SD64rr (f64 (IMPLICIT_DEF)), GR64:$src)>;
1359 }
1360
1361 defm CVTTSS2SI : sse12_cvt_s<0x2C, FR32, GR32, fp_to_sint, f32mem, loadf32,
1362                       "cvttss2si\t{$src, $dst|$dst, $src}">, XS;
1363 defm CVTTSS2SI64 : sse12_cvt_s<0x2C, FR32, GR64, fp_to_sint, f32mem, loadf32,
1364                       "cvttss2si{q}\t{$src, $dst|$dst, $src}">, XS, REX_W;
1365 defm CVTTSD2SI : sse12_cvt_s<0x2C, FR64, GR32, fp_to_sint, f64mem, loadf64,
1366                       "cvttsd2si\t{$src, $dst|$dst, $src}">, XD;
1367 defm CVTTSD2SI64 : sse12_cvt_s<0x2C, FR64, GR64, fp_to_sint, f64mem, loadf64,
1368                       "cvttsd2si{q}\t{$src, $dst|$dst, $src}">, XD, REX_W;
1369 defm CVTSI2SS  : sse12_cvt_s<0x2A, GR32, FR32, sint_to_fp, i32mem, loadi32,
1370                       "cvtsi2ss\t{$src, $dst|$dst, $src}">, XS;
1371 defm CVTSI2SS64 : sse12_cvt_s<0x2A, GR64, FR32, sint_to_fp, i64mem, loadi64,
1372                       "cvtsi2ss{q}\t{$src, $dst|$dst, $src}">, XS, REX_W;
1373 defm CVTSI2SD  : sse12_cvt_s<0x2A, GR32, FR64, sint_to_fp, i32mem, loadi32,
1374                       "cvtsi2sd\t{$src, $dst|$dst, $src}">, XD;
1375 defm CVTSI2SD64 : sse12_cvt_s<0x2A, GR64, FR64, sint_to_fp, i64mem, loadi64,
1376                       "cvtsi2sd{q}\t{$src, $dst|$dst, $src}">, XD, REX_W;
1377
1378 // Conversion Instructions Intrinsics - Match intrinsics which expect MM
1379 // and/or XMM operand(s).
1380
1381 multiclass sse12_cvt_sint<bits<8> opc, RegisterClass SrcRC, RegisterClass DstRC,
1382                          Intrinsic Int, X86MemOperand x86memop, PatFrag ld_frag,
1383                          string asm> {
1384   def rr : SI<opc, MRMSrcReg, (outs DstRC:$dst), (ins SrcRC:$src),
1385               !strconcat(asm, "\t{$src, $dst|$dst, $src}"),
1386               [(set DstRC:$dst, (Int SrcRC:$src))]>;
1387   def rm : SI<opc, MRMSrcMem, (outs DstRC:$dst), (ins x86memop:$src),
1388               !strconcat(asm, "\t{$src, $dst|$dst, $src}"),
1389               [(set DstRC:$dst, (Int (ld_frag addr:$src)))]>;
1390 }
1391
1392 multiclass sse12_cvt_sint_3addr<bits<8> opc, RegisterClass SrcRC,
1393                     RegisterClass DstRC, Intrinsic Int, X86MemOperand x86memop,
1394                     PatFrag ld_frag, string asm, bit Is2Addr = 1> {
1395   def rr : SI<opc, MRMSrcReg, (outs DstRC:$dst), (ins DstRC:$src1, SrcRC:$src2),
1396               !if(Is2Addr,
1397                   !strconcat(asm, "\t{$src2, $dst|$dst, $src2}"),
1398                   !strconcat(asm, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
1399               [(set DstRC:$dst, (Int DstRC:$src1, SrcRC:$src2))]>;
1400   def rm : SI<opc, MRMSrcMem, (outs DstRC:$dst),
1401               (ins DstRC:$src1, x86memop:$src2),
1402               !if(Is2Addr,
1403                   !strconcat(asm, "\t{$src2, $dst|$dst, $src2}"),
1404                   !strconcat(asm, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
1405               [(set DstRC:$dst, (Int DstRC:$src1, (ld_frag addr:$src2)))]>;
1406 }
1407
1408 defm VCVTSD2SI : sse12_cvt_sint<0x2D, VR128, GR32, int_x86_sse2_cvtsd2si,
1409                   f128mem, load, "cvtsd2si">, XD, VEX, VEX_LIG;
1410 defm VCVTSD2SI64 : sse12_cvt_sint<0x2D, VR128, GR64,
1411                   int_x86_sse2_cvtsd2si64, f128mem, load, "cvtsd2si">,
1412                   XD, VEX, VEX_W, VEX_LIG;
1413
1414 defm CVTSD2SI : sse12_cvt_sint<0x2D, VR128, GR32, int_x86_sse2_cvtsd2si,
1415                 f128mem, load, "cvtsd2si{l}">, XD;
1416 defm CVTSD2SI64 : sse12_cvt_sint<0x2D, VR128, GR64, int_x86_sse2_cvtsd2si64,
1417                   f128mem, load, "cvtsd2si{q}">, XD, REX_W;
1418
1419
1420 defm Int_VCVTSI2SS : sse12_cvt_sint_3addr<0x2A, GR32, VR128,
1421           int_x86_sse_cvtsi2ss, i32mem, loadi32, "cvtsi2ss", 0>, XS, VEX_4V;
1422 defm Int_VCVTSI2SS64 : sse12_cvt_sint_3addr<0x2A, GR64, VR128,
1423           int_x86_sse_cvtsi642ss, i64mem, loadi64, "cvtsi2ss", 0>, XS, VEX_4V,
1424           VEX_W;
1425 defm Int_VCVTSI2SD : sse12_cvt_sint_3addr<0x2A, GR32, VR128,
1426           int_x86_sse2_cvtsi2sd, i32mem, loadi32, "cvtsi2sd", 0>, XD, VEX_4V;
1427 defm Int_VCVTSI2SD64 : sse12_cvt_sint_3addr<0x2A, GR64, VR128,
1428           int_x86_sse2_cvtsi642sd, i64mem, loadi64, "cvtsi2sd", 0>, XD,
1429           VEX_4V, VEX_W;
1430
1431 let Constraints = "$src1 = $dst" in {
1432   defm Int_CVTSI2SS : sse12_cvt_sint_3addr<0x2A, GR32, VR128,
1433                         int_x86_sse_cvtsi2ss, i32mem, loadi32,
1434                         "cvtsi2ss">, XS;
1435   defm Int_CVTSI2SS64 : sse12_cvt_sint_3addr<0x2A, GR64, VR128,
1436                         int_x86_sse_cvtsi642ss, i64mem, loadi64,
1437                         "cvtsi2ss{q}">, XS, REX_W;
1438   defm Int_CVTSI2SD : sse12_cvt_sint_3addr<0x2A, GR32, VR128,
1439                         int_x86_sse2_cvtsi2sd, i32mem, loadi32,
1440                         "cvtsi2sd">, XD;
1441   defm Int_CVTSI2SD64 : sse12_cvt_sint_3addr<0x2A, GR64, VR128,
1442                         int_x86_sse2_cvtsi642sd, i64mem, loadi64,
1443                         "cvtsi2sd">, XD, REX_W;
1444 }
1445
1446 /// SSE 1 Only
1447
1448 // Aliases for intrinsics
1449 defm Int_VCVTTSS2SI : sse12_cvt_sint<0x2C, VR128, GR32, int_x86_sse_cvttss2si,
1450                                     f32mem, load, "cvttss2si">, XS, VEX;
1451 defm Int_VCVTTSS2SI64 : sse12_cvt_sint<0x2C, VR128, GR64,
1452                                     int_x86_sse_cvttss2si64, f32mem, load,
1453                                     "cvttss2si">, XS, VEX, VEX_W;
1454 defm Int_VCVTTSD2SI : sse12_cvt_sint<0x2C, VR128, GR32, int_x86_sse2_cvttsd2si,
1455                                     f128mem, load, "cvttsd2si">, XD, VEX;
1456 defm Int_VCVTTSD2SI64 : sse12_cvt_sint<0x2C, VR128, GR64,
1457                                     int_x86_sse2_cvttsd2si64, f128mem, load,
1458                                     "cvttsd2si">, XD, VEX, VEX_W;
1459 defm Int_CVTTSS2SI : sse12_cvt_sint<0x2C, VR128, GR32, int_x86_sse_cvttss2si,
1460                                     f32mem, load, "cvttss2si">, XS;
1461 defm Int_CVTTSS2SI64 : sse12_cvt_sint<0x2C, VR128, GR64,
1462                                     int_x86_sse_cvttss2si64, f32mem, load,
1463                                     "cvttss2si{q}">, XS, REX_W;
1464 defm Int_CVTTSD2SI : sse12_cvt_sint<0x2C, VR128, GR32, int_x86_sse2_cvttsd2si,
1465                                     f128mem, load, "cvttsd2si">, XD;
1466 defm Int_CVTTSD2SI64 : sse12_cvt_sint<0x2C, VR128, GR64,
1467                                     int_x86_sse2_cvttsd2si64, f128mem, load,
1468                                     "cvttsd2si{q}">, XD, REX_W;
1469
1470 let Pattern = []<dag> in {
1471 defm VCVTSS2SI   : sse12_cvt_s<0x2D, FR32, GR32, undef, f32mem, load,
1472                                "cvtss2si{l}\t{$src, $dst|$dst, $src}">, XS,
1473                                VEX, VEX_LIG;
1474 defm VCVTSS2SI64 : sse12_cvt_s<0x2D, FR32, GR64, undef, f32mem, load,
1475                                "cvtss2si\t{$src, $dst|$dst, $src}">, XS, VEX,
1476                                VEX_W, VEX_LIG;
1477 defm VCVTDQ2PS   : sse12_cvt_p<0x5B, VR128, VR128, undef, i128mem, load,
1478                                "cvtdq2ps\t{$src, $dst|$dst, $src}",
1479                                SSEPackedSingle>, TB, VEX;
1480 defm VCVTDQ2PSY  : sse12_cvt_p<0x5B, VR256, VR256, undef, i256mem, load,
1481                                "cvtdq2ps\t{$src, $dst|$dst, $src}",
1482                                SSEPackedSingle>, TB, VEX;
1483 }
1484
1485 let Pattern = []<dag> in {
1486 defm CVTSS2SI : sse12_cvt_s<0x2D, FR32, GR32, undef, f32mem, load /*dummy*/,
1487                           "cvtss2si{l}\t{$src, $dst|$dst, $src}">, XS;
1488 defm CVTSS2SI64 : sse12_cvt_s<0x2D, FR32, GR64, undef, f32mem, load /*dummy*/,
1489                           "cvtss2si{q}\t{$src, $dst|$dst, $src}">, XS, REX_W;
1490 defm CVTDQ2PS : sse12_cvt_p<0x5B, VR128, VR128, undef, i128mem, load /*dummy*/,
1491                             "cvtdq2ps\t{$src, $dst|$dst, $src}",
1492                             SSEPackedSingle>, TB; /* PD SSE3 form is avaiable */
1493 }
1494
1495 let Predicates = [HasAVX] in {
1496   def : Pat<(int_x86_sse_cvtss2si VR128:$src),
1497             (VCVTSS2SIrr (EXTRACT_SUBREG (v4f32 VR128:$src), sub_ss))>;
1498   def : Pat<(int_x86_sse_cvtss2si (load addr:$src)),
1499             (VCVTSS2SIrm addr:$src)>;
1500   def : Pat<(int_x86_sse_cvtss2si64 VR128:$src),
1501             (VCVTSS2SI64rr (EXTRACT_SUBREG (v4f32 VR128:$src), sub_ss))>;
1502   def : Pat<(int_x86_sse_cvtss2si64 (load addr:$src)),
1503             (VCVTSS2SI64rm addr:$src)>;
1504 }
1505
1506 let Predicates = [HasSSE1] in {
1507   def : Pat<(int_x86_sse_cvtss2si VR128:$src),
1508             (CVTSS2SIrr (EXTRACT_SUBREG (v4f32 VR128:$src), sub_ss))>;
1509   def : Pat<(int_x86_sse_cvtss2si (load addr:$src)),
1510             (CVTSS2SIrm addr:$src)>;
1511   def : Pat<(int_x86_sse_cvtss2si64 VR128:$src),
1512             (CVTSS2SI64rr (EXTRACT_SUBREG (v4f32 VR128:$src), sub_ss))>;
1513   def : Pat<(int_x86_sse_cvtss2si64 (load addr:$src)),
1514             (CVTSS2SI64rm addr:$src)>;
1515 }
1516
1517 /// SSE 2 Only
1518
1519 // Convert scalar double to scalar single
1520 def VCVTSD2SSrr  : VSDI<0x5A, MRMSrcReg, (outs FR32:$dst),
1521                        (ins FR64:$src1, FR64:$src2),
1522                       "cvtsd2ss\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>,
1523                       VEX_4V, VEX_LIG;
1524 let mayLoad = 1 in
1525 def VCVTSD2SSrm  : I<0x5A, MRMSrcMem, (outs FR32:$dst),
1526                        (ins FR64:$src1, f64mem:$src2),
1527                       "vcvtsd2ss\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1528                       []>, XD, Requires<[HasAVX, OptForSize]>, VEX_4V, VEX_LIG;
1529
1530 def : Pat<(f32 (fround FR64:$src)), (VCVTSD2SSrr FR64:$src, FR64:$src)>,
1531           Requires<[HasAVX]>;
1532
1533 def CVTSD2SSrr  : SDI<0x5A, MRMSrcReg, (outs FR32:$dst), (ins FR64:$src),
1534                       "cvtsd2ss\t{$src, $dst|$dst, $src}",
1535                       [(set FR32:$dst, (fround FR64:$src))]>;
1536 def CVTSD2SSrm  : I<0x5A, MRMSrcMem, (outs FR32:$dst), (ins f64mem:$src),
1537                       "cvtsd2ss\t{$src, $dst|$dst, $src}",
1538                       [(set FR32:$dst, (fround (loadf64 addr:$src)))]>, XD,
1539                   Requires<[HasSSE2, OptForSize]>;
1540
1541 defm Int_VCVTSD2SS: sse12_cvt_sint_3addr<0x5A, VR128, VR128,
1542                       int_x86_sse2_cvtsd2ss, f64mem, load, "cvtsd2ss", 0>,
1543                       XS, VEX_4V;
1544 let Constraints = "$src1 = $dst" in
1545 defm Int_CVTSD2SS: sse12_cvt_sint_3addr<0x5A, VR128, VR128,
1546                       int_x86_sse2_cvtsd2ss, f64mem, load, "cvtsd2ss">, XS;
1547
1548 // Convert scalar single to scalar double
1549 // SSE2 instructions with XS prefix
1550 def VCVTSS2SDrr : I<0x5A, MRMSrcReg, (outs FR64:$dst),
1551                     (ins FR32:$src1, FR32:$src2),
1552                     "vcvtss2sd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1553                     []>, XS, Requires<[HasAVX]>, VEX_4V, VEX_LIG;
1554 let mayLoad = 1 in
1555 def VCVTSS2SDrm : I<0x5A, MRMSrcMem, (outs FR64:$dst),
1556                     (ins FR32:$src1, f32mem:$src2),
1557                     "vcvtss2sd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1558                     []>, XS, VEX_4V, VEX_LIG, Requires<[HasAVX, OptForSize]>;
1559
1560 let Predicates = [HasAVX] in {
1561   def : Pat<(f64 (fextend FR32:$src)),
1562             (VCVTSS2SDrr FR32:$src, FR32:$src)>;
1563   def : Pat<(fextend (loadf32 addr:$src)),
1564             (VCVTSS2SDrm (f32 (IMPLICIT_DEF)), addr:$src)>;
1565   def : Pat<(extloadf32 addr:$src),
1566             (VCVTSS2SDrm (f32 (IMPLICIT_DEF)), addr:$src)>;
1567 }
1568
1569 def : Pat<(extloadf32 addr:$src),
1570           (VCVTSS2SDrr (f32 (IMPLICIT_DEF)), (MOVSSrm addr:$src))>,
1571           Requires<[HasAVX, OptForSpeed]>;
1572
1573 def CVTSS2SDrr : I<0x5A, MRMSrcReg, (outs FR64:$dst), (ins FR32:$src),
1574                    "cvtss2sd\t{$src, $dst|$dst, $src}",
1575                    [(set FR64:$dst, (fextend FR32:$src))]>, XS,
1576                  Requires<[HasSSE2]>;
1577 def CVTSS2SDrm : I<0x5A, MRMSrcMem, (outs FR64:$dst), (ins f32mem:$src),
1578                    "cvtss2sd\t{$src, $dst|$dst, $src}",
1579                    [(set FR64:$dst, (extloadf32 addr:$src))]>, XS,
1580                  Requires<[HasSSE2, OptForSize]>;
1581
1582 // extload f32 -> f64.  This matches load+fextend because we have a hack in
1583 // the isel (PreprocessForFPConvert) that can introduce loads after dag
1584 // combine.
1585 // Since these loads aren't folded into the fextend, we have to match it
1586 // explicitly here.
1587 def : Pat<(fextend (loadf32 addr:$src)),
1588           (CVTSS2SDrm addr:$src)>, Requires<[HasSSE2]>;
1589 def : Pat<(extloadf32 addr:$src),
1590           (CVTSS2SDrr (MOVSSrm addr:$src))>, Requires<[HasSSE2, OptForSpeed]>;
1591
1592 def Int_VCVTSS2SDrr: I<0x5A, MRMSrcReg,
1593                       (outs VR128:$dst), (ins VR128:$src1, VR128:$src2),
1594                     "vcvtss2sd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1595                     [(set VR128:$dst, (int_x86_sse2_cvtss2sd VR128:$src1,
1596                                        VR128:$src2))]>, XS, VEX_4V,
1597                     Requires<[HasAVX]>;
1598 def Int_VCVTSS2SDrm: I<0x5A, MRMSrcMem,
1599                       (outs VR128:$dst), (ins VR128:$src1, f32mem:$src2),
1600                     "vcvtss2sd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1601                     [(set VR128:$dst, (int_x86_sse2_cvtss2sd VR128:$src1,
1602                                        (load addr:$src2)))]>, XS, VEX_4V,
1603                     Requires<[HasAVX]>;
1604 let Constraints = "$src1 = $dst" in { // SSE2 instructions with XS prefix
1605 def Int_CVTSS2SDrr: I<0x5A, MRMSrcReg,
1606                       (outs VR128:$dst), (ins VR128:$src1, VR128:$src2),
1607                     "cvtss2sd\t{$src2, $dst|$dst, $src2}",
1608                     [(set VR128:$dst, (int_x86_sse2_cvtss2sd VR128:$src1,
1609                                        VR128:$src2))]>, XS,
1610                     Requires<[HasSSE2]>;
1611 def Int_CVTSS2SDrm: I<0x5A, MRMSrcMem,
1612                       (outs VR128:$dst), (ins VR128:$src1, f32mem:$src2),
1613                     "cvtss2sd\t{$src2, $dst|$dst, $src2}",
1614                     [(set VR128:$dst, (int_x86_sse2_cvtss2sd VR128:$src1,
1615                                        (load addr:$src2)))]>, XS,
1616                     Requires<[HasSSE2]>;
1617 }
1618
1619 // Convert doubleword to packed single/double fp
1620 // SSE2 instructions without OpSize prefix
1621 def Int_VCVTDQ2PSrr : I<0x5B, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1622                        "vcvtdq2ps\t{$src, $dst|$dst, $src}",
1623                        [(set VR128:$dst, (int_x86_sse2_cvtdq2ps VR128:$src))]>,
1624                      TB, VEX, Requires<[HasAVX]>;
1625 def Int_VCVTDQ2PSrm : I<0x5B, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
1626                       "vcvtdq2ps\t{$src, $dst|$dst, $src}",
1627                       [(set VR128:$dst, (int_x86_sse2_cvtdq2ps
1628                                         (bitconvert (memopv2i64 addr:$src))))]>,
1629                      TB, VEX, Requires<[HasAVX]>;
1630 def Int_CVTDQ2PSrr : I<0x5B, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1631                        "cvtdq2ps\t{$src, $dst|$dst, $src}",
1632                        [(set VR128:$dst, (int_x86_sse2_cvtdq2ps VR128:$src))]>,
1633                      TB, Requires<[HasSSE2]>;
1634 def Int_CVTDQ2PSrm : I<0x5B, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
1635                       "cvtdq2ps\t{$src, $dst|$dst, $src}",
1636                       [(set VR128:$dst, (int_x86_sse2_cvtdq2ps
1637                                         (bitconvert (memopv2i64 addr:$src))))]>,
1638                      TB, Requires<[HasSSE2]>;
1639
1640 // FIXME: why the non-intrinsic version is described as SSE3?
1641 // SSE2 instructions with XS prefix
1642 def Int_VCVTDQ2PDrr : I<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1643                        "vcvtdq2pd\t{$src, $dst|$dst, $src}",
1644                        [(set VR128:$dst, (int_x86_sse2_cvtdq2pd VR128:$src))]>,
1645                      XS, VEX, Requires<[HasAVX]>;
1646 def Int_VCVTDQ2PDrm : I<0xE6, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
1647                        "vcvtdq2pd\t{$src, $dst|$dst, $src}",
1648                        [(set VR128:$dst, (int_x86_sse2_cvtdq2pd
1649                                         (bitconvert (memopv2i64 addr:$src))))]>,
1650                      XS, VEX, Requires<[HasAVX]>;
1651 def Int_CVTDQ2PDrr : I<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1652                        "cvtdq2pd\t{$src, $dst|$dst, $src}",
1653                        [(set VR128:$dst, (int_x86_sse2_cvtdq2pd VR128:$src))]>,
1654                      XS, Requires<[HasSSE2]>;
1655 def Int_CVTDQ2PDrm : I<0xE6, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
1656                      "cvtdq2pd\t{$src, $dst|$dst, $src}",
1657                      [(set VR128:$dst, (int_x86_sse2_cvtdq2pd
1658                                         (bitconvert (memopv2i64 addr:$src))))]>,
1659                      XS, Requires<[HasSSE2]>;
1660
1661
1662 // Convert packed single/double fp to doubleword
1663 def VCVTPS2DQrr : VPDI<0x5B, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1664                        "cvtps2dq\t{$src, $dst|$dst, $src}", []>, VEX;
1665 def VCVTPS2DQrm : VPDI<0x5B, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1666                        "cvtps2dq\t{$src, $dst|$dst, $src}", []>, VEX;
1667 def VCVTPS2DQYrr : VPDI<0x5B, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
1668                         "cvtps2dq\t{$src, $dst|$dst, $src}", []>, VEX;
1669 def VCVTPS2DQYrm : VPDI<0x5B, MRMSrcMem, (outs VR256:$dst), (ins f256mem:$src),
1670                         "cvtps2dq\t{$src, $dst|$dst, $src}", []>, VEX;
1671 def CVTPS2DQrr : PDI<0x5B, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1672                      "cvtps2dq\t{$src, $dst|$dst, $src}", []>;
1673 def CVTPS2DQrm : PDI<0x5B, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1674                      "cvtps2dq\t{$src, $dst|$dst, $src}", []>;
1675
1676 def Int_VCVTPS2DQrr : VPDI<0x5B, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1677                         "cvtps2dq\t{$src, $dst|$dst, $src}",
1678                         [(set VR128:$dst, (int_x86_sse2_cvtps2dq VR128:$src))]>,
1679                         VEX;
1680 def Int_VCVTPS2DQrm : VPDI<0x5B, MRMSrcMem, (outs VR128:$dst),
1681                          (ins f128mem:$src),
1682                          "cvtps2dq\t{$src, $dst|$dst, $src}",
1683                          [(set VR128:$dst, (int_x86_sse2_cvtps2dq
1684                                             (memop addr:$src)))]>, VEX;
1685 def Int_CVTPS2DQrr : PDI<0x5B, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1686                         "cvtps2dq\t{$src, $dst|$dst, $src}",
1687                         [(set VR128:$dst, (int_x86_sse2_cvtps2dq VR128:$src))]>;
1688 def Int_CVTPS2DQrm : PDI<0x5B, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1689                          "cvtps2dq\t{$src, $dst|$dst, $src}",
1690                          [(set VR128:$dst, (int_x86_sse2_cvtps2dq
1691                                             (memop addr:$src)))]>;
1692
1693 // SSE2 packed instructions with XD prefix
1694 def Int_VCVTPD2DQrr : I<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1695                        "vcvtpd2dq\t{$src, $dst|$dst, $src}",
1696                        [(set VR128:$dst, (int_x86_sse2_cvtpd2dq VR128:$src))]>,
1697                      XD, VEX, Requires<[HasAVX]>;
1698 def Int_VCVTPD2DQrm : I<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1699                        "vcvtpd2dq\t{$src, $dst|$dst, $src}",
1700                        [(set VR128:$dst, (int_x86_sse2_cvtpd2dq
1701                                           (memop addr:$src)))]>,
1702                      XD, VEX, Requires<[HasAVX]>;
1703 def Int_CVTPD2DQrr : I<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1704                        "cvtpd2dq\t{$src, $dst|$dst, $src}",
1705                        [(set VR128:$dst, (int_x86_sse2_cvtpd2dq VR128:$src))]>,
1706                      XD, Requires<[HasSSE2]>;
1707 def Int_CVTPD2DQrm : I<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1708                        "cvtpd2dq\t{$src, $dst|$dst, $src}",
1709                        [(set VR128:$dst, (int_x86_sse2_cvtpd2dq
1710                                           (memop addr:$src)))]>,
1711                      XD, Requires<[HasSSE2]>;
1712
1713
1714 // Convert with truncation packed single/double fp to doubleword
1715 // SSE2 packed instructions with XS prefix
1716 def VCVTTPS2DQrr : VSSI<0x5B, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1717                         "cvttps2dq\t{$src, $dst|$dst, $src}",
1718                         [(set VR128:$dst,
1719                           (int_x86_sse2_cvttps2dq VR128:$src))]>, VEX;
1720 def VCVTTPS2DQrm : VSSI<0x5B, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1721                         "cvttps2dq\t{$src, $dst|$dst, $src}",
1722                         [(set VR128:$dst, (int_x86_sse2_cvttps2dq
1723                                            (memop addr:$src)))]>, VEX;
1724 def VCVTTPS2DQYrr : VSSI<0x5B, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
1725                          "cvttps2dq\t{$src, $dst|$dst, $src}",
1726                          [(set VR256:$dst,
1727                            (int_x86_avx_cvtt_ps2dq_256 VR256:$src))]>, VEX;
1728 def VCVTTPS2DQYrm : VSSI<0x5B, MRMSrcMem, (outs VR256:$dst), (ins f256mem:$src),
1729                          "cvttps2dq\t{$src, $dst|$dst, $src}",
1730                          [(set VR256:$dst, (int_x86_avx_cvtt_ps2dq_256
1731                                             (memopv8f32 addr:$src)))]>, VEX;
1732
1733 def CVTTPS2DQrr : SSI<0x5B, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1734                       "cvttps2dq\t{$src, $dst|$dst, $src}",
1735                       [(set VR128:$dst,
1736                             (int_x86_sse2_cvttps2dq VR128:$src))]>;
1737 def CVTTPS2DQrm : SSI<0x5B, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1738                       "cvttps2dq\t{$src, $dst|$dst, $src}",
1739                       [(set VR128:$dst,
1740                             (int_x86_sse2_cvttps2dq (memop addr:$src)))]>;
1741
1742 let Predicates = [HasAVX] in {
1743   def : Pat<(v4f32 (sint_to_fp (v4i32 VR128:$src))),
1744             (Int_VCVTDQ2PSrr VR128:$src)>;
1745   def : Pat<(v4f32 (sint_to_fp (bc_v4i32 (memopv2i64 addr:$src)))),
1746             (Int_VCVTDQ2PSrm addr:$src)>;
1747
1748   def : Pat<(v4i32 (fp_to_sint (v4f32 VR128:$src))),
1749             (VCVTTPS2DQrr VR128:$src)>;
1750   def : Pat<(v4i32 (fp_to_sint (memopv4f32 addr:$src))),
1751             (VCVTTPS2DQrm addr:$src)>;
1752
1753   def : Pat<(v8f32 (sint_to_fp (v8i32 VR256:$src))),
1754             (VCVTDQ2PSYrr VR256:$src)>;
1755   def : Pat<(v8f32 (sint_to_fp (bc_v8i32 (memopv4i64 addr:$src)))),
1756             (VCVTDQ2PSYrm addr:$src)>;
1757
1758   def : Pat<(v8i32 (fp_to_sint (v8f32 VR256:$src))),
1759             (VCVTTPS2DQYrr VR256:$src)>;
1760   def : Pat<(v8i32 (fp_to_sint (memopv8f32 addr:$src))),
1761             (VCVTTPS2DQYrm addr:$src)>;
1762 }
1763
1764 let Predicates = [HasSSE2] in {
1765   def : Pat<(v4f32 (sint_to_fp (v4i32 VR128:$src))),
1766             (Int_CVTDQ2PSrr VR128:$src)>;
1767   def : Pat<(v4f32 (sint_to_fp (bc_v4i32 (memopv2i64 addr:$src)))),
1768             (Int_CVTDQ2PSrm addr:$src)>;
1769
1770   def : Pat<(v4i32 (fp_to_sint (v4f32 VR128:$src))),
1771             (CVTTPS2DQrr VR128:$src)>;
1772   def : Pat<(v4i32 (fp_to_sint (memopv4f32 addr:$src))),
1773             (CVTTPS2DQrm addr:$src)>;
1774 }
1775
1776 def VCVTTPD2DQrr : VPDI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1777                         "cvttpd2dq\t{$src, $dst|$dst, $src}",
1778                         [(set VR128:$dst,
1779                               (int_x86_sse2_cvttpd2dq VR128:$src))]>, VEX;
1780 let isCodeGenOnly = 1 in
1781 def VCVTTPD2DQrm : VPDI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1782                         "cvttpd2dq\t{$src, $dst|$dst, $src}",
1783                         [(set VR128:$dst, (int_x86_sse2_cvttpd2dq
1784                                                (memop addr:$src)))]>, VEX;
1785 def CVTTPD2DQrr : PDI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1786                       "cvttpd2dq\t{$src, $dst|$dst, $src}",
1787                       [(set VR128:$dst, (int_x86_sse2_cvttpd2dq VR128:$src))]>;
1788 def CVTTPD2DQrm : PDI<0xE6, MRMSrcMem, (outs VR128:$dst),(ins f128mem:$src),
1789                       "cvttpd2dq\t{$src, $dst|$dst, $src}",
1790                       [(set VR128:$dst, (int_x86_sse2_cvttpd2dq
1791                                         (memop addr:$src)))]>;
1792
1793 // The assembler can recognize rr 256-bit instructions by seeing a ymm
1794 // register, but the same isn't true when using memory operands instead.
1795 // Provide other assembly rr and rm forms to address this explicitly.
1796 def VCVTTPD2DQXrYr : VPDI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR256:$src),
1797                           "cvttpd2dq\t{$src, $dst|$dst, $src}", []>, VEX;
1798
1799 // XMM only
1800 def VCVTTPD2DQXrr : VPDI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1801                          "cvttpd2dqx\t{$src, $dst|$dst, $src}", []>, VEX;
1802 def VCVTTPD2DQXrm : VPDI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1803                          "cvttpd2dqx\t{$src, $dst|$dst, $src}", []>, VEX;
1804
1805 // YMM only
1806 def VCVTTPD2DQYrr : VPDI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR256:$src),
1807                          "cvttpd2dqy\t{$src, $dst|$dst, $src}", []>, VEX;
1808 def VCVTTPD2DQYrm : VPDI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f256mem:$src),
1809                          "cvttpd2dqy\t{$src, $dst|$dst, $src}", []>, VEX, VEX_L;
1810
1811 // Convert packed single to packed double
1812 let Predicates = [HasAVX] in {
1813                   // SSE2 instructions without OpSize prefix
1814 def VCVTPS2PDrr : I<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1815                      "vcvtps2pd\t{$src, $dst|$dst, $src}", []>, TB, VEX;
1816 def VCVTPS2PDrm : I<0x5A, MRMSrcMem, (outs VR128:$dst), (ins f64mem:$src),
1817                      "vcvtps2pd\t{$src, $dst|$dst, $src}", []>, TB, VEX;
1818 def VCVTPS2PDYrr : I<0x5A, MRMSrcReg, (outs VR256:$dst), (ins VR128:$src),
1819                      "vcvtps2pd\t{$src, $dst|$dst, $src}", []>, TB, VEX;
1820 def VCVTPS2PDYrm : I<0x5A, MRMSrcMem, (outs VR256:$dst), (ins f128mem:$src),
1821                      "vcvtps2pd\t{$src, $dst|$dst, $src}", []>, TB, VEX;
1822 }
1823 def CVTPS2PDrr : I<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1824                        "cvtps2pd\t{$src, $dst|$dst, $src}", []>, TB;
1825 def CVTPS2PDrm : I<0x5A, MRMSrcMem, (outs VR128:$dst), (ins f64mem:$src),
1826                        "cvtps2pd\t{$src, $dst|$dst, $src}", []>, TB;
1827
1828 def Int_VCVTPS2PDrr : I<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1829                        "vcvtps2pd\t{$src, $dst|$dst, $src}",
1830                        [(set VR128:$dst, (int_x86_sse2_cvtps2pd VR128:$src))]>,
1831                      TB, VEX, Requires<[HasAVX]>;
1832 def Int_VCVTPS2PDrm : I<0x5A, MRMSrcMem, (outs VR128:$dst), (ins f64mem:$src),
1833                        "vcvtps2pd\t{$src, $dst|$dst, $src}",
1834                        [(set VR128:$dst, (int_x86_sse2_cvtps2pd
1835                                           (load addr:$src)))]>,
1836                      TB, VEX, Requires<[HasAVX]>;
1837 def Int_CVTPS2PDrr : I<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1838                        "cvtps2pd\t{$src, $dst|$dst, $src}",
1839                        [(set VR128:$dst, (int_x86_sse2_cvtps2pd VR128:$src))]>,
1840                      TB, Requires<[HasSSE2]>;
1841 def Int_CVTPS2PDrm : I<0x5A, MRMSrcMem, (outs VR128:$dst), (ins f64mem:$src),
1842                        "cvtps2pd\t{$src, $dst|$dst, $src}",
1843                        [(set VR128:$dst, (int_x86_sse2_cvtps2pd
1844                                           (load addr:$src)))]>,
1845                      TB, Requires<[HasSSE2]>;
1846
1847 // Convert packed double to packed single
1848 // The assembler can recognize rr 256-bit instructions by seeing a ymm
1849 // register, but the same isn't true when using memory operands instead.
1850 // Provide other assembly rr and rm forms to address this explicitly.
1851 def VCVTPD2PSrr : VPDI<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1852                        "cvtpd2ps\t{$src, $dst|$dst, $src}", []>, VEX;
1853 def VCVTPD2PSXrYr : VPDI<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR256:$src),
1854                          "cvtpd2ps\t{$src, $dst|$dst, $src}", []>, VEX;
1855
1856 // XMM only
1857 def VCVTPD2PSXrr : VPDI<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1858                         "cvtpd2psx\t{$src, $dst|$dst, $src}", []>, VEX;
1859 def VCVTPD2PSXrm : VPDI<0x5A, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1860                         "cvtpd2psx\t{$src, $dst|$dst, $src}", []>, VEX;
1861
1862 // YMM only
1863 def VCVTPD2PSYrr : VPDI<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR256:$src),
1864                         "cvtpd2psy\t{$src, $dst|$dst, $src}", []>, VEX;
1865 def VCVTPD2PSYrm : VPDI<0x5A, MRMSrcMem, (outs VR128:$dst), (ins f256mem:$src),
1866                         "cvtpd2psy\t{$src, $dst|$dst, $src}", []>, VEX, VEX_L;
1867 def CVTPD2PSrr : PDI<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1868                      "cvtpd2ps\t{$src, $dst|$dst, $src}", []>;
1869 def CVTPD2PSrm : PDI<0x5A, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1870                      "cvtpd2ps\t{$src, $dst|$dst, $src}", []>;
1871
1872
1873 def Int_VCVTPD2PSrr : VPDI<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1874                          "cvtpd2ps\t{$src, $dst|$dst, $src}",
1875                         [(set VR128:$dst, (int_x86_sse2_cvtpd2ps VR128:$src))]>;
1876 def Int_VCVTPD2PSrm : VPDI<0x5A, MRMSrcMem, (outs VR128:$dst),
1877                          (ins f128mem:$src),
1878                          "cvtpd2ps\t{$src, $dst|$dst, $src}",
1879                          [(set VR128:$dst, (int_x86_sse2_cvtpd2ps
1880                                             (memop addr:$src)))]>;
1881 def Int_CVTPD2PSrr : PDI<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1882                          "cvtpd2ps\t{$src, $dst|$dst, $src}",
1883                         [(set VR128:$dst, (int_x86_sse2_cvtpd2ps VR128:$src))]>;
1884 def Int_CVTPD2PSrm : PDI<0x5A, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1885                          "cvtpd2ps\t{$src, $dst|$dst, $src}",
1886                          [(set VR128:$dst, (int_x86_sse2_cvtpd2ps
1887                                             (memop addr:$src)))]>;
1888
1889 // AVX 256-bit register conversion intrinsics
1890 // FIXME: Migrate SSE conversion intrinsics matching to use patterns as below
1891 // whenever possible to avoid declaring two versions of each one.
1892 def : Pat<(int_x86_avx_cvtdq2_ps_256 VR256:$src),
1893           (VCVTDQ2PSYrr VR256:$src)>;
1894 def : Pat<(int_x86_avx_cvtdq2_ps_256 (bitconvert (memopv4i64 addr:$src))),
1895           (VCVTDQ2PSYrm addr:$src)>;
1896
1897 def : Pat<(int_x86_avx_cvt_pd2_ps_256 VR256:$src),
1898           (VCVTPD2PSYrr VR256:$src)>;
1899 def : Pat<(int_x86_avx_cvt_pd2_ps_256 (memopv4f64 addr:$src)),
1900           (VCVTPD2PSYrm addr:$src)>;
1901
1902 def : Pat<(int_x86_avx_cvt_ps2dq_256 VR256:$src),
1903           (VCVTPS2DQYrr VR256:$src)>;
1904 def : Pat<(int_x86_avx_cvt_ps2dq_256 (memopv8f32 addr:$src)),
1905           (VCVTPS2DQYrm addr:$src)>;
1906
1907 def : Pat<(int_x86_avx_cvt_ps2_pd_256 VR128:$src),
1908           (VCVTPS2PDYrr VR128:$src)>;
1909 def : Pat<(int_x86_avx_cvt_ps2_pd_256 (memopv4f32 addr:$src)),
1910           (VCVTPS2PDYrm addr:$src)>;
1911
1912 def : Pat<(int_x86_avx_cvtt_pd2dq_256 VR256:$src),
1913           (VCVTTPD2DQYrr VR256:$src)>;
1914 def : Pat<(int_x86_avx_cvtt_pd2dq_256 (memopv4f64 addr:$src)),
1915           (VCVTTPD2DQYrm addr:$src)>;
1916
1917 // Match fround and fextend for 128/256-bit conversions
1918 def : Pat<(v4f32 (fround (v4f64 VR256:$src))),
1919           (VCVTPD2PSYrr VR256:$src)>;
1920 def : Pat<(v4f32 (fround (loadv4f64 addr:$src))),
1921           (VCVTPD2PSYrm addr:$src)>;
1922
1923 def : Pat<(v4f64 (fextend (v4f32 VR128:$src))),
1924           (VCVTPS2PDYrr VR128:$src)>;
1925 def : Pat<(v4f64 (fextend (loadv4f32 addr:$src))),
1926           (VCVTPS2PDYrm addr:$src)>;
1927
1928 //===----------------------------------------------------------------------===//
1929 // SSE 1 & 2 - Compare Instructions
1930 //===----------------------------------------------------------------------===//
1931
1932 // sse12_cmp_scalar - sse 1 & 2 compare scalar instructions
1933 multiclass sse12_cmp_scalar<RegisterClass RC, X86MemOperand x86memop,
1934                             SDNode OpNode, ValueType VT, PatFrag ld_frag,
1935                             string asm, string asm_alt> {
1936   def rr : SIi8<0xC2, MRMSrcReg,
1937                 (outs RC:$dst), (ins RC:$src1, RC:$src2, SSECC:$cc), asm,
1938                 [(set RC:$dst, (OpNode (VT RC:$src1), RC:$src2, imm:$cc))]>;
1939   def rm : SIi8<0xC2, MRMSrcMem,
1940                 (outs RC:$dst), (ins RC:$src1, x86memop:$src2, SSECC:$cc), asm,
1941                 [(set RC:$dst, (OpNode (VT RC:$src1),
1942                                          (ld_frag addr:$src2), imm:$cc))]>;
1943
1944   // Accept explicit immediate argument form instead of comparison code.
1945   let neverHasSideEffects = 1 in {
1946     def rr_alt : SIi8<0xC2, MRMSrcReg, (outs RC:$dst),
1947                       (ins RC:$src1, RC:$src2, i8imm:$cc), asm_alt, []>;
1948     let mayLoad = 1 in
1949     def rm_alt : SIi8<0xC2, MRMSrcMem, (outs RC:$dst),
1950                       (ins RC:$src1, x86memop:$src2, i8imm:$cc), asm_alt, []>;
1951   }
1952 }
1953
1954 defm VCMPSS : sse12_cmp_scalar<FR32, f32mem, X86cmpss, f32, loadf32,
1955                  "cmp${cc}ss\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1956                  "cmpss\t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}">,
1957                  XS, VEX_4V, VEX_LIG;
1958 defm VCMPSD : sse12_cmp_scalar<FR64, f64mem, X86cmpsd, f64, loadf64,
1959                  "cmp${cc}sd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1960                  "cmpsd\t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}">,
1961                  XD, VEX_4V, VEX_LIG;
1962
1963 let Constraints = "$src1 = $dst" in {
1964   defm CMPSS : sse12_cmp_scalar<FR32, f32mem, X86cmpss, f32, loadf32,
1965                   "cmp${cc}ss\t{$src2, $dst|$dst, $src2}",
1966                   "cmpss\t{$cc, $src2, $dst|$dst, $src2, $cc}">,
1967                   XS;
1968   defm CMPSD : sse12_cmp_scalar<FR64, f64mem, X86cmpsd, f64, loadf64,
1969                   "cmp${cc}sd\t{$src2, $dst|$dst, $src2}",
1970                   "cmpsd\t{$cc, $src2, $dst|$dst, $src2, $cc}">,
1971                   XD;
1972 }
1973
1974 multiclass sse12_cmp_scalar_int<RegisterClass RC, X86MemOperand x86memop,
1975                          Intrinsic Int, string asm> {
1976   def rr : SIi8<0xC2, MRMSrcReg, (outs VR128:$dst),
1977                       (ins VR128:$src1, VR128:$src, SSECC:$cc), asm,
1978                         [(set VR128:$dst, (Int VR128:$src1,
1979                                                VR128:$src, imm:$cc))]>;
1980   def rm : SIi8<0xC2, MRMSrcMem, (outs VR128:$dst),
1981                       (ins VR128:$src1, x86memop:$src, SSECC:$cc), asm,
1982                         [(set VR128:$dst, (Int VR128:$src1,
1983                                                (load addr:$src), imm:$cc))]>;
1984 }
1985
1986 // Aliases to match intrinsics which expect XMM operand(s).
1987 defm Int_VCMPSS  : sse12_cmp_scalar_int<VR128, f32mem, int_x86_sse_cmp_ss,
1988                      "cmp${cc}ss\t{$src, $src1, $dst|$dst, $src1, $src}">,
1989                      XS, VEX_4V;
1990 defm Int_VCMPSD  : sse12_cmp_scalar_int<VR128, f64mem, int_x86_sse2_cmp_sd,
1991                      "cmp${cc}sd\t{$src, $src1, $dst|$dst, $src1, $src}">,
1992                      XD, VEX_4V;
1993 let Constraints = "$src1 = $dst" in {
1994   defm Int_CMPSS  : sse12_cmp_scalar_int<VR128, f32mem, int_x86_sse_cmp_ss,
1995                        "cmp${cc}ss\t{$src, $dst|$dst, $src}">, XS;
1996   defm Int_CMPSD  : sse12_cmp_scalar_int<VR128, f64mem, int_x86_sse2_cmp_sd,
1997                        "cmp${cc}sd\t{$src, $dst|$dst, $src}">, XD;
1998 }
1999
2000
2001 // sse12_ord_cmp - Unordered/Ordered scalar fp compare and set EFLAGS
2002 multiclass sse12_ord_cmp<bits<8> opc, RegisterClass RC, SDNode OpNode,
2003                             ValueType vt, X86MemOperand x86memop,
2004                             PatFrag ld_frag, string OpcodeStr, Domain d> {
2005   def rr: PI<opc, MRMSrcReg, (outs), (ins RC:$src1, RC:$src2),
2006                      !strconcat(OpcodeStr, "\t{$src2, $src1|$src1, $src2}"),
2007                      [(set EFLAGS, (OpNode (vt RC:$src1), RC:$src2))],
2008                      IIC_DEFAULT, d>;
2009   def rm: PI<opc, MRMSrcMem, (outs), (ins RC:$src1, x86memop:$src2),
2010                      !strconcat(OpcodeStr, "\t{$src2, $src1|$src1, $src2}"),
2011                      [(set EFLAGS, (OpNode (vt RC:$src1),
2012                                            (ld_frag addr:$src2)))],
2013                                            IIC_DEFAULT, d>;
2014 }
2015
2016 let Defs = [EFLAGS] in {
2017   defm VUCOMISS : sse12_ord_cmp<0x2E, FR32, X86cmp, f32, f32mem, loadf32,
2018                                   "ucomiss", SSEPackedSingle>, TB, VEX, VEX_LIG;
2019   defm VUCOMISD : sse12_ord_cmp<0x2E, FR64, X86cmp, f64, f64mem, loadf64,
2020                                   "ucomisd", SSEPackedDouble>, TB, OpSize, VEX,
2021                                   VEX_LIG;
2022   let Pattern = []<dag> in {
2023     defm VCOMISS  : sse12_ord_cmp<0x2F, VR128, undef, v4f32, f128mem, load,
2024                                     "comiss", SSEPackedSingle>, TB, VEX,
2025                                     VEX_LIG;
2026     defm VCOMISD  : sse12_ord_cmp<0x2F, VR128, undef, v2f64, f128mem, load,
2027                                     "comisd", SSEPackedDouble>, TB, OpSize, VEX,
2028                                     VEX_LIG;
2029   }
2030
2031   defm Int_VUCOMISS  : sse12_ord_cmp<0x2E, VR128, X86ucomi, v4f32, f128mem,
2032                             load, "ucomiss", SSEPackedSingle>, TB, VEX;
2033   defm Int_VUCOMISD  : sse12_ord_cmp<0x2E, VR128, X86ucomi, v2f64, f128mem,
2034                             load, "ucomisd", SSEPackedDouble>, TB, OpSize, VEX;
2035
2036   defm Int_VCOMISS  : sse12_ord_cmp<0x2F, VR128, X86comi, v4f32, f128mem,
2037                             load, "comiss", SSEPackedSingle>, TB, VEX;
2038   defm Int_VCOMISD  : sse12_ord_cmp<0x2F, VR128, X86comi, v2f64, f128mem,
2039                             load, "comisd", SSEPackedDouble>, TB, OpSize, VEX;
2040   defm UCOMISS  : sse12_ord_cmp<0x2E, FR32, X86cmp, f32, f32mem, loadf32,
2041                                   "ucomiss", SSEPackedSingle>, TB;
2042   defm UCOMISD  : sse12_ord_cmp<0x2E, FR64, X86cmp, f64, f64mem, loadf64,
2043                                   "ucomisd", SSEPackedDouble>, TB, OpSize;
2044
2045   let Pattern = []<dag> in {
2046     defm COMISS  : sse12_ord_cmp<0x2F, VR128, undef, v4f32, f128mem, load,
2047                                     "comiss", SSEPackedSingle>, TB;
2048     defm COMISD  : sse12_ord_cmp<0x2F, VR128, undef, v2f64, f128mem, load,
2049                                     "comisd", SSEPackedDouble>, TB, OpSize;
2050   }
2051
2052   defm Int_UCOMISS  : sse12_ord_cmp<0x2E, VR128, X86ucomi, v4f32, f128mem,
2053                               load, "ucomiss", SSEPackedSingle>, TB;
2054   defm Int_UCOMISD  : sse12_ord_cmp<0x2E, VR128, X86ucomi, v2f64, f128mem,
2055                               load, "ucomisd", SSEPackedDouble>, TB, OpSize;
2056
2057   defm Int_COMISS  : sse12_ord_cmp<0x2F, VR128, X86comi, v4f32, f128mem, load,
2058                                   "comiss", SSEPackedSingle>, TB;
2059   defm Int_COMISD  : sse12_ord_cmp<0x2F, VR128, X86comi, v2f64, f128mem, load,
2060                                   "comisd", SSEPackedDouble>, TB, OpSize;
2061 } // Defs = [EFLAGS]
2062
2063 // sse12_cmp_packed - sse 1 & 2 compared packed instructions
2064 multiclass sse12_cmp_packed<RegisterClass RC, X86MemOperand x86memop,
2065                             Intrinsic Int, string asm, string asm_alt,
2066                             Domain d> {
2067   let isAsmParserOnly = 1 in {
2068     def rri : PIi8<0xC2, MRMSrcReg,
2069                (outs RC:$dst), (ins RC:$src1, RC:$src2, SSECC:$cc), asm,
2070                [(set RC:$dst, (Int RC:$src1, RC:$src2, imm:$cc))],
2071                IIC_DEFAULT, d>;
2072     def rmi : PIi8<0xC2, MRMSrcMem,
2073                (outs RC:$dst), (ins RC:$src1, x86memop:$src2, SSECC:$cc), asm,
2074                [(set RC:$dst, (Int RC:$src1, (memop addr:$src2), imm:$cc))],
2075                IIC_DEFAULT, d>;
2076   }
2077
2078   // Accept explicit immediate argument form instead of comparison code.
2079   def rri_alt : PIi8<0xC2, MRMSrcReg,
2080              (outs RC:$dst), (ins RC:$src1, RC:$src2, i8imm:$cc),
2081              asm_alt, [], IIC_DEFAULT, d>;
2082   def rmi_alt : PIi8<0xC2, MRMSrcMem,
2083              (outs RC:$dst), (ins RC:$src1, x86memop:$src2, i8imm:$cc),
2084              asm_alt, [], IIC_DEFAULT, d>;
2085 }
2086
2087 defm VCMPPS : sse12_cmp_packed<VR128, f128mem, int_x86_sse_cmp_ps,
2088                "cmp${cc}ps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2089                "cmpps\t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}",
2090                SSEPackedSingle>, TB, VEX_4V;
2091 defm VCMPPD : sse12_cmp_packed<VR128, f128mem, int_x86_sse2_cmp_pd,
2092                "cmp${cc}pd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2093                "cmppd\t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}",
2094                SSEPackedDouble>, TB, OpSize, VEX_4V;
2095 defm VCMPPSY : sse12_cmp_packed<VR256, f256mem, int_x86_avx_cmp_ps_256,
2096                "cmp${cc}ps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2097                "cmpps\t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}",
2098                SSEPackedSingle>, TB, VEX_4V;
2099 defm VCMPPDY : sse12_cmp_packed<VR256, f256mem, int_x86_avx_cmp_pd_256,
2100                "cmp${cc}pd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2101                "cmppd\t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}",
2102                SSEPackedDouble>, TB, OpSize, VEX_4V;
2103 let Constraints = "$src1 = $dst" in {
2104   defm CMPPS : sse12_cmp_packed<VR128, f128mem, int_x86_sse_cmp_ps,
2105                  "cmp${cc}ps\t{$src2, $dst|$dst, $src2}",
2106                  "cmpps\t{$cc, $src2, $dst|$dst, $src2, $cc}",
2107                  SSEPackedSingle>, TB;
2108   defm CMPPD : sse12_cmp_packed<VR128, f128mem, int_x86_sse2_cmp_pd,
2109                  "cmp${cc}pd\t{$src2, $dst|$dst, $src2}",
2110                  "cmppd\t{$cc, $src2, $dst|$dst, $src2, $cc}",
2111                  SSEPackedDouble>, TB, OpSize;
2112 }
2113
2114 let Predicates = [HasAVX] in {
2115 def : Pat<(v4i32 (X86cmpp (v4f32 VR128:$src1), VR128:$src2, imm:$cc)),
2116           (VCMPPSrri (v4f32 VR128:$src1), (v4f32 VR128:$src2), imm:$cc)>;
2117 def : Pat<(v4i32 (X86cmpp (v4f32 VR128:$src1), (memop addr:$src2), imm:$cc)),
2118           (VCMPPSrmi (v4f32 VR128:$src1), addr:$src2, imm:$cc)>;
2119 def : Pat<(v2i64 (X86cmpp (v2f64 VR128:$src1), VR128:$src2, imm:$cc)),
2120           (VCMPPDrri VR128:$src1, VR128:$src2, imm:$cc)>;
2121 def : Pat<(v2i64 (X86cmpp (v2f64 VR128:$src1), (memop addr:$src2), imm:$cc)),
2122           (VCMPPDrmi VR128:$src1, addr:$src2, imm:$cc)>;
2123
2124 def : Pat<(v8i32 (X86cmpp (v8f32 VR256:$src1), VR256:$src2, imm:$cc)),
2125           (VCMPPSYrri (v8f32 VR256:$src1), (v8f32 VR256:$src2), imm:$cc)>;
2126 def : Pat<(v8i32 (X86cmpp (v8f32 VR256:$src1), (memop addr:$src2), imm:$cc)),
2127           (VCMPPSYrmi (v8f32 VR256:$src1), addr:$src2, imm:$cc)>;
2128 def : Pat<(v4i64 (X86cmpp (v4f64 VR256:$src1), VR256:$src2, imm:$cc)),
2129           (VCMPPDYrri VR256:$src1, VR256:$src2, imm:$cc)>;
2130 def : Pat<(v4i64 (X86cmpp (v4f64 VR256:$src1), (memop addr:$src2), imm:$cc)),
2131           (VCMPPDYrmi VR256:$src1, addr:$src2, imm:$cc)>;
2132 }
2133
2134 let Predicates = [HasSSE1] in {
2135 def : Pat<(v4i32 (X86cmpp (v4f32 VR128:$src1), VR128:$src2, imm:$cc)),
2136           (CMPPSrri (v4f32 VR128:$src1), (v4f32 VR128:$src2), imm:$cc)>;
2137 def : Pat<(v4i32 (X86cmpp (v4f32 VR128:$src1), (memop addr:$src2), imm:$cc)),
2138           (CMPPSrmi (v4f32 VR128:$src1), addr:$src2, imm:$cc)>;
2139 }
2140
2141 let Predicates = [HasSSE2] in {
2142 def : Pat<(v2i64 (X86cmpp (v2f64 VR128:$src1), VR128:$src2, imm:$cc)),
2143           (CMPPDrri VR128:$src1, VR128:$src2, imm:$cc)>;
2144 def : Pat<(v2i64 (X86cmpp (v2f64 VR128:$src1), (memop addr:$src2), imm:$cc)),
2145           (CMPPDrmi VR128:$src1, addr:$src2, imm:$cc)>;
2146 }
2147
2148 //===----------------------------------------------------------------------===//
2149 // SSE 1 & 2 - Shuffle Instructions
2150 //===----------------------------------------------------------------------===//
2151
2152 /// sse12_shuffle - sse 1 & 2 shuffle instructions
2153 multiclass sse12_shuffle<RegisterClass RC, X86MemOperand x86memop,
2154                          ValueType vt, string asm, PatFrag mem_frag,
2155                          Domain d, bit IsConvertibleToThreeAddress = 0> {
2156   def rmi : PIi8<0xC6, MRMSrcMem, (outs RC:$dst),
2157                    (ins RC:$src1, x86memop:$src2, i8imm:$src3), asm,
2158                    [(set RC:$dst, (vt (X86Shufp RC:$src1, (mem_frag addr:$src2),
2159                                        (i8 imm:$src3))))], IIC_DEFAULT, d>;
2160   let isConvertibleToThreeAddress = IsConvertibleToThreeAddress in
2161     def rri : PIi8<0xC6, MRMSrcReg, (outs RC:$dst),
2162                    (ins RC:$src1, RC:$src2, i8imm:$src3), asm,
2163                    [(set RC:$dst, (vt (X86Shufp RC:$src1, RC:$src2,
2164                                        (i8 imm:$src3))))], IIC_DEFAULT, d>;
2165 }
2166
2167 defm VSHUFPS  : sse12_shuffle<VR128, f128mem, v4f32,
2168            "shufps\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
2169            memopv4f32, SSEPackedSingle>, TB, VEX_4V;
2170 defm VSHUFPSY : sse12_shuffle<VR256, f256mem, v8f32,
2171            "shufps\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
2172            memopv8f32, SSEPackedSingle>, TB, VEX_4V;
2173 defm VSHUFPD  : sse12_shuffle<VR128, f128mem, v2f64,
2174            "shufpd\t{$src3, $src2, $src1, $dst|$dst, $src2, $src2, $src3}",
2175            memopv2f64, SSEPackedDouble>, TB, OpSize, VEX_4V;
2176 defm VSHUFPDY : sse12_shuffle<VR256, f256mem, v4f64,
2177            "shufpd\t{$src3, $src2, $src1, $dst|$dst, $src2, $src2, $src3}",
2178            memopv4f64, SSEPackedDouble>, TB, OpSize, VEX_4V;
2179
2180 let Constraints = "$src1 = $dst" in {
2181   defm SHUFPS : sse12_shuffle<VR128, f128mem, v4f32,
2182                     "shufps\t{$src3, $src2, $dst|$dst, $src2, $src3}",
2183                     memopv4f32, SSEPackedSingle, 1 /* cvt to pshufd */>,
2184                     TB;
2185   defm SHUFPD : sse12_shuffle<VR128, f128mem, v2f64,
2186                     "shufpd\t{$src3, $src2, $dst|$dst, $src2, $src3}",
2187                     memopv2f64, SSEPackedDouble, 1 /* cvt to pshufd */>,
2188                     TB, OpSize;
2189 }
2190
2191 let Predicates = [HasAVX] in {
2192   def : Pat<(v4i32 (X86Shufp VR128:$src1,
2193                        (bc_v4i32 (memopv2i64 addr:$src2)), (i8 imm:$imm))),
2194             (VSHUFPSrmi VR128:$src1, addr:$src2, imm:$imm)>;
2195   def : Pat<(v4i32 (X86Shufp VR128:$src1, VR128:$src2, (i8 imm:$imm))),
2196             (VSHUFPSrri VR128:$src1, VR128:$src2, imm:$imm)>;
2197
2198   def : Pat<(v2i64 (X86Shufp VR128:$src1,
2199                        (memopv2i64 addr:$src2), (i8 imm:$imm))),
2200             (VSHUFPDrmi VR128:$src1, addr:$src2, imm:$imm)>;
2201   def : Pat<(v2i64 (X86Shufp VR128:$src1, VR128:$src2, (i8 imm:$imm))),
2202             (VSHUFPDrri VR128:$src1, VR128:$src2, imm:$imm)>;
2203
2204   // 256-bit patterns
2205   def : Pat<(v8i32 (X86Shufp VR256:$src1, VR256:$src2, (i8 imm:$imm))),
2206             (VSHUFPSYrri VR256:$src1, VR256:$src2, imm:$imm)>;
2207   def : Pat<(v8i32 (X86Shufp VR256:$src1,
2208                       (bc_v8i32 (memopv4i64 addr:$src2)), (i8 imm:$imm))),
2209             (VSHUFPSYrmi VR256:$src1, addr:$src2, imm:$imm)>;
2210
2211   def : Pat<(v4i64 (X86Shufp VR256:$src1, VR256:$src2, (i8 imm:$imm))),
2212             (VSHUFPDYrri VR256:$src1, VR256:$src2, imm:$imm)>;
2213   def : Pat<(v4i64 (X86Shufp VR256:$src1,
2214                               (memopv4i64 addr:$src2), (i8 imm:$imm))),
2215             (VSHUFPDYrmi VR256:$src1, addr:$src2, imm:$imm)>;
2216 }
2217
2218 let Predicates = [HasSSE1] in {
2219   def : Pat<(v4i32 (X86Shufp VR128:$src1,
2220                        (bc_v4i32 (memopv2i64 addr:$src2)), (i8 imm:$imm))),
2221             (SHUFPSrmi VR128:$src1, addr:$src2, imm:$imm)>;
2222   def : Pat<(v4i32 (X86Shufp VR128:$src1, VR128:$src2, (i8 imm:$imm))),
2223             (SHUFPSrri VR128:$src1, VR128:$src2, imm:$imm)>;
2224 }
2225
2226 let Predicates = [HasSSE2] in {
2227   // Generic SHUFPD patterns
2228   def : Pat<(v2i64 (X86Shufp VR128:$src1,
2229                        (memopv2i64 addr:$src2), (i8 imm:$imm))),
2230             (SHUFPDrmi VR128:$src1, addr:$src2, imm:$imm)>;
2231   def : Pat<(v2i64 (X86Shufp VR128:$src1, VR128:$src2, (i8 imm:$imm))),
2232             (SHUFPDrri VR128:$src1, VR128:$src2, imm:$imm)>;
2233 }
2234
2235 //===----------------------------------------------------------------------===//
2236 // SSE 1 & 2 - Unpack Instructions
2237 //===----------------------------------------------------------------------===//
2238
2239 /// sse12_unpack_interleave - sse 1 & 2 unpack and interleave
2240 multiclass sse12_unpack_interleave<bits<8> opc, SDNode OpNode, ValueType vt,
2241                                    PatFrag mem_frag, RegisterClass RC,
2242                                    X86MemOperand x86memop, string asm,
2243                                    Domain d> {
2244     def rr : PI<opc, MRMSrcReg,
2245                 (outs RC:$dst), (ins RC:$src1, RC:$src2),
2246                 asm, [(set RC:$dst,
2247                            (vt (OpNode RC:$src1, RC:$src2)))],
2248                            IIC_DEFAULT, d>;
2249     def rm : PI<opc, MRMSrcMem,
2250                 (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
2251                 asm, [(set RC:$dst,
2252                            (vt (OpNode RC:$src1,
2253                                        (mem_frag addr:$src2))))],
2254                                        IIC_DEFAULT, d>;
2255 }
2256
2257 defm VUNPCKHPS: sse12_unpack_interleave<0x15, X86Unpckh, v4f32, memopv4f32,
2258       VR128, f128mem, "unpckhps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2259                      SSEPackedSingle>, TB, VEX_4V;
2260 defm VUNPCKHPD: sse12_unpack_interleave<0x15, X86Unpckh, v2f64, memopv2f64,
2261       VR128, f128mem, "unpckhpd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2262                      SSEPackedDouble>, TB, OpSize, VEX_4V;
2263 defm VUNPCKLPS: sse12_unpack_interleave<0x14, X86Unpckl, v4f32, memopv4f32,
2264       VR128, f128mem, "unpcklps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2265                      SSEPackedSingle>, TB, VEX_4V;
2266 defm VUNPCKLPD: sse12_unpack_interleave<0x14, X86Unpckl, v2f64, memopv2f64,
2267       VR128, f128mem, "unpcklpd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2268                      SSEPackedDouble>, TB, OpSize, VEX_4V;
2269
2270 defm VUNPCKHPSY: sse12_unpack_interleave<0x15, X86Unpckh, v8f32, memopv8f32,
2271       VR256, f256mem, "unpckhps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2272                      SSEPackedSingle>, TB, VEX_4V;
2273 defm VUNPCKHPDY: sse12_unpack_interleave<0x15, X86Unpckh, v4f64, memopv4f64,
2274       VR256, f256mem, "unpckhpd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2275                      SSEPackedDouble>, TB, OpSize, VEX_4V;
2276 defm VUNPCKLPSY: sse12_unpack_interleave<0x14, X86Unpckl, v8f32, memopv8f32,
2277       VR256, f256mem, "unpcklps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2278                      SSEPackedSingle>, TB, VEX_4V;
2279 defm VUNPCKLPDY: sse12_unpack_interleave<0x14, X86Unpckl, v4f64, memopv4f64,
2280       VR256, f256mem, "unpcklpd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2281                      SSEPackedDouble>, TB, OpSize, VEX_4V;
2282
2283 let Constraints = "$src1 = $dst" in {
2284   defm UNPCKHPS: sse12_unpack_interleave<0x15, X86Unpckh, v4f32, memopv4f32,
2285         VR128, f128mem, "unpckhps\t{$src2, $dst|$dst, $src2}",
2286                        SSEPackedSingle>, TB;
2287   defm UNPCKHPD: sse12_unpack_interleave<0x15, X86Unpckh, v2f64, memopv2f64,
2288         VR128, f128mem, "unpckhpd\t{$src2, $dst|$dst, $src2}",
2289                        SSEPackedDouble>, TB, OpSize;
2290   defm UNPCKLPS: sse12_unpack_interleave<0x14, X86Unpckl, v4f32, memopv4f32,
2291         VR128, f128mem, "unpcklps\t{$src2, $dst|$dst, $src2}",
2292                        SSEPackedSingle>, TB;
2293   defm UNPCKLPD: sse12_unpack_interleave<0x14, X86Unpckl, v2f64, memopv2f64,
2294         VR128, f128mem, "unpcklpd\t{$src2, $dst|$dst, $src2}",
2295                        SSEPackedDouble>, TB, OpSize;
2296 } // Constraints = "$src1 = $dst"
2297
2298 let Predicates = [HasAVX], AddedComplexity = 1 in {
2299   // FIXME: Instead of X86Movddup, there should be a X86Unpckl here, the
2300   // problem is during lowering, where it's not possible to recognize the load
2301   // fold cause it has two uses through a bitcast. One use disappears at isel
2302   // time and the fold opportunity reappears.
2303   def : Pat<(v2f64 (X86Movddup VR128:$src)),
2304             (VUNPCKLPDrr VR128:$src, VR128:$src)>;
2305 }
2306
2307 let Predicates = [HasSSE2] in {
2308   // FIXME: Instead of X86Movddup, there should be a X86Unpckl here, the
2309   // problem is during lowering, where it's not possible to recognize the load
2310   // fold cause it has two uses through a bitcast. One use disappears at isel
2311   // time and the fold opportunity reappears.
2312   def : Pat<(v2f64 (X86Movddup VR128:$src)),
2313             (UNPCKLPDrr VR128:$src, VR128:$src)>;
2314 }
2315
2316 //===----------------------------------------------------------------------===//
2317 // SSE 1 & 2 - Extract Floating-Point Sign mask
2318 //===----------------------------------------------------------------------===//
2319
2320 /// sse12_extr_sign_mask - sse 1 & 2 unpack and interleave
2321 multiclass sse12_extr_sign_mask<RegisterClass RC, Intrinsic Int, string asm,
2322                                 Domain d> {
2323   def rr32 : PI<0x50, MRMSrcReg, (outs GR32:$dst), (ins RC:$src),
2324                 !strconcat(asm, "\t{$src, $dst|$dst, $src}"),
2325                      [(set GR32:$dst, (Int RC:$src))], IIC_DEFAULT, d>;
2326   def rr64 : PI<0x50, MRMSrcReg, (outs GR64:$dst), (ins RC:$src),
2327                 !strconcat(asm, "\t{$src, $dst|$dst, $src}"), [],
2328                 IIC_DEFAULT, d>, REX_W;
2329 }
2330
2331 let Predicates = [HasAVX] in {
2332   defm VMOVMSKPS : sse12_extr_sign_mask<VR128, int_x86_sse_movmsk_ps,
2333                                         "movmskps", SSEPackedSingle>, TB, VEX;
2334   defm VMOVMSKPD : sse12_extr_sign_mask<VR128, int_x86_sse2_movmsk_pd,
2335                                         "movmskpd", SSEPackedDouble>, TB,
2336                                         OpSize, VEX;
2337   defm VMOVMSKPSY : sse12_extr_sign_mask<VR256, int_x86_avx_movmsk_ps_256,
2338                                         "movmskps", SSEPackedSingle>, TB, VEX;
2339   defm VMOVMSKPDY : sse12_extr_sign_mask<VR256, int_x86_avx_movmsk_pd_256,
2340                                         "movmskpd", SSEPackedDouble>, TB,
2341                                         OpSize, VEX;
2342
2343   def : Pat<(i32 (X86fgetsign FR32:$src)),
2344             (VMOVMSKPSrr32 (INSERT_SUBREG (v4f32 (IMPLICIT_DEF)), FR32:$src,
2345                                           sub_ss))>;
2346   def : Pat<(i64 (X86fgetsign FR32:$src)),
2347             (VMOVMSKPSrr64 (INSERT_SUBREG (v4f32 (IMPLICIT_DEF)), FR32:$src,
2348                                           sub_ss))>;
2349   def : Pat<(i32 (X86fgetsign FR64:$src)),
2350             (VMOVMSKPDrr32 (INSERT_SUBREG (v2f64 (IMPLICIT_DEF)), FR64:$src,
2351                                           sub_sd))>;
2352   def : Pat<(i64 (X86fgetsign FR64:$src)),
2353             (VMOVMSKPDrr64 (INSERT_SUBREG (v2f64 (IMPLICIT_DEF)), FR64:$src,
2354                                           sub_sd))>;
2355
2356   // Assembler Only
2357   def VMOVMSKPSr64r : PI<0x50, MRMSrcReg, (outs GR64:$dst), (ins VR128:$src),
2358              "movmskps\t{$src, $dst|$dst, $src}", [], IIC_DEFAULT,
2359              SSEPackedSingle>, TB, VEX;
2360   def VMOVMSKPDr64r : PI<0x50, MRMSrcReg, (outs GR64:$dst), (ins VR128:$src),
2361              "movmskpd\t{$src, $dst|$dst, $src}", [], IIC_DEFAULT,
2362              SSEPackedDouble>, TB,
2363              OpSize, VEX;
2364   def VMOVMSKPSYr64r : PI<0x50, MRMSrcReg, (outs GR64:$dst), (ins VR256:$src),
2365              "movmskps\t{$src, $dst|$dst, $src}", [], IIC_DEFAULT,
2366              SSEPackedSingle>, TB, VEX;
2367   def VMOVMSKPDYr64r : PI<0x50, MRMSrcReg, (outs GR64:$dst), (ins VR256:$src),
2368              "movmskpd\t{$src, $dst|$dst, $src}", [], IIC_DEFAULT,
2369              SSEPackedDouble>, TB,
2370              OpSize, VEX;
2371 }
2372
2373 defm MOVMSKPS : sse12_extr_sign_mask<VR128, int_x86_sse_movmsk_ps, "movmskps",
2374                                      SSEPackedSingle>, TB;
2375 defm MOVMSKPD : sse12_extr_sign_mask<VR128, int_x86_sse2_movmsk_pd, "movmskpd",
2376                                      SSEPackedDouble>, TB, OpSize;
2377
2378 def : Pat<(i32 (X86fgetsign FR32:$src)),
2379           (MOVMSKPSrr32 (INSERT_SUBREG (v4f32 (IMPLICIT_DEF)), FR32:$src,
2380                                        sub_ss))>, Requires<[HasSSE1]>;
2381 def : Pat<(i64 (X86fgetsign FR32:$src)),
2382           (MOVMSKPSrr64 (INSERT_SUBREG (v4f32 (IMPLICIT_DEF)), FR32:$src,
2383                                        sub_ss))>, Requires<[HasSSE1]>;
2384 def : Pat<(i32 (X86fgetsign FR64:$src)),
2385           (MOVMSKPDrr32 (INSERT_SUBREG (v2f64 (IMPLICIT_DEF)), FR64:$src,
2386                                        sub_sd))>, Requires<[HasSSE2]>;
2387 def : Pat<(i64 (X86fgetsign FR64:$src)),
2388           (MOVMSKPDrr64 (INSERT_SUBREG (v2f64 (IMPLICIT_DEF)), FR64:$src,
2389                                        sub_sd))>, Requires<[HasSSE2]>;
2390
2391 //===---------------------------------------------------------------------===//
2392 // SSE2 - Packed Integer Logical Instructions
2393 //===---------------------------------------------------------------------===//
2394
2395 let ExeDomain = SSEPackedInt in { // SSE integer instructions
2396
2397 /// PDI_binop_rm - Simple SSE2 binary operator.
2398 multiclass PDI_binop_rm<bits<8> opc, string OpcodeStr, SDNode OpNode,
2399                         ValueType OpVT, RegisterClass RC, PatFrag memop_frag,
2400                         X86MemOperand x86memop, bit IsCommutable = 0,
2401                         bit Is2Addr = 1> {
2402   let isCommutable = IsCommutable in
2403   def rr : PDI<opc, MRMSrcReg, (outs RC:$dst),
2404        (ins RC:$src1, RC:$src2),
2405        !if(Is2Addr,
2406            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
2407            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
2408        [(set RC:$dst, (OpVT (OpNode RC:$src1, RC:$src2)))]>;
2409   def rm : PDI<opc, MRMSrcMem, (outs RC:$dst),
2410        (ins RC:$src1, x86memop:$src2),
2411        !if(Is2Addr,
2412            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
2413            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
2414        [(set RC:$dst, (OpVT (OpNode RC:$src1,
2415                                      (bitconvert (memop_frag addr:$src2)))))]>;
2416 }
2417 } // ExeDomain = SSEPackedInt
2418
2419 // These are ordered here for pattern ordering requirements with the fp versions
2420
2421 let Predicates = [HasAVX] in {
2422 defm VPAND : PDI_binop_rm<0xDB, "vpand", and, v2i64, VR128, memopv2i64,
2423                           i128mem, 1, 0>, VEX_4V;
2424 defm VPOR  : PDI_binop_rm<0xEB, "vpor" , or, v2i64, VR128, memopv2i64,
2425                           i128mem, 1, 0>, VEX_4V;
2426 defm VPXOR : PDI_binop_rm<0xEF, "vpxor", xor, v2i64, VR128, memopv2i64,
2427                           i128mem, 1, 0>, VEX_4V;
2428 defm VPANDN : PDI_binop_rm<0xDF, "vpandn", X86andnp, v2i64, VR128, memopv2i64,
2429                           i128mem, 0, 0>, VEX_4V;
2430 }
2431
2432 let Constraints = "$src1 = $dst" in {
2433 defm PAND : PDI_binop_rm<0xDB, "pand", and, v2i64, VR128, memopv2i64,
2434                          i128mem, 1>;
2435 defm POR  : PDI_binop_rm<0xEB, "por" , or, v2i64, VR128, memopv2i64,
2436                          i128mem, 1>;
2437 defm PXOR : PDI_binop_rm<0xEF, "pxor", xor, v2i64, VR128, memopv2i64,
2438                          i128mem, 1>;
2439 defm PANDN : PDI_binop_rm<0xDF, "pandn", X86andnp, v2i64, VR128, memopv2i64,
2440                           i128mem, 0>;
2441 } // Constraints = "$src1 = $dst"
2442
2443 let Predicates = [HasAVX2] in {
2444 defm VPANDY : PDI_binop_rm<0xDB, "vpand", and, v4i64, VR256, memopv4i64,
2445                            i256mem, 1, 0>, VEX_4V;
2446 defm VPORY  : PDI_binop_rm<0xEB, "vpor", or, v4i64, VR256, memopv4i64,
2447                            i256mem, 1, 0>, VEX_4V;
2448 defm VPXORY : PDI_binop_rm<0xEF, "vpxor", xor, v4i64, VR256, memopv4i64,
2449                            i256mem, 1, 0>, VEX_4V;
2450 defm VPANDNY : PDI_binop_rm<0xDF, "vpandn", X86andnp, v4i64, VR256, memopv4i64,
2451                             i256mem, 0, 0>, VEX_4V;
2452 }
2453
2454 //===----------------------------------------------------------------------===//
2455 // SSE 1 & 2 - Logical Instructions
2456 //===----------------------------------------------------------------------===//
2457
2458 /// sse12_fp_alias_pack_logical - SSE 1 & 2 aliased packed FP logical ops
2459 ///
2460 multiclass sse12_fp_alias_pack_logical<bits<8> opc, string OpcodeStr,
2461                                        SDNode OpNode> {
2462   defm V#NAME#PS : sse12_fp_packed<opc, !strconcat(OpcodeStr, "ps"), OpNode,
2463               FR32, f32, f128mem, memopfsf32, SSEPackedSingle, 0>, TB, VEX_4V;
2464
2465   defm V#NAME#PD : sse12_fp_packed<opc, !strconcat(OpcodeStr, "pd"), OpNode,
2466         FR64, f64, f128mem, memopfsf64, SSEPackedDouble, 0>, TB, OpSize, VEX_4V;
2467
2468   let Constraints = "$src1 = $dst" in {
2469     defm PS : sse12_fp_packed<opc, !strconcat(OpcodeStr, "ps"), OpNode, FR32,
2470                 f32, f128mem, memopfsf32, SSEPackedSingle>, TB;
2471
2472     defm PD : sse12_fp_packed<opc, !strconcat(OpcodeStr, "pd"), OpNode, FR64,
2473                 f64, f128mem, memopfsf64, SSEPackedDouble>, TB, OpSize;
2474   }
2475 }
2476
2477 // Alias bitwise logical operations using SSE logical ops on packed FP values.
2478 let mayLoad = 0 in {
2479   defm FsAND  : sse12_fp_alias_pack_logical<0x54, "and", X86fand>;
2480   defm FsOR   : sse12_fp_alias_pack_logical<0x56, "or", X86for>;
2481   defm FsXOR  : sse12_fp_alias_pack_logical<0x57, "xor", X86fxor>;
2482 }
2483
2484 let neverHasSideEffects = 1, Pattern = []<dag>, isCommutable = 0 in
2485   defm FsANDN : sse12_fp_alias_pack_logical<0x55, "andn", undef>;
2486
2487 /// sse12_fp_packed_logical - SSE 1 & 2 packed FP logical ops
2488 ///
2489 multiclass sse12_fp_packed_logical<bits<8> opc, string OpcodeStr,
2490                                    SDNode OpNode> {
2491   // In AVX no need to add a pattern for 128-bit logical rr ps, because they
2492   // are all promoted to v2i64, and the patterns are covered by the int
2493   // version. This is needed in SSE only, because v2i64 isn't supported on
2494   // SSE1, but only on SSE2.
2495   defm V#NAME#PS : sse12_fp_packed_logical_rm<opc, VR128, SSEPackedSingle,
2496        !strconcat(OpcodeStr, "ps"), f128mem, [],
2497        [(set VR128:$dst, (OpNode (bc_v2i64 (v4f32 VR128:$src1)),
2498                                  (memopv2i64 addr:$src2)))], 0, 1>, TB, VEX_4V;
2499
2500   defm V#NAME#PD : sse12_fp_packed_logical_rm<opc, VR128, SSEPackedDouble,
2501        !strconcat(OpcodeStr, "pd"), f128mem,
2502        [(set VR128:$dst, (OpNode (bc_v2i64 (v2f64 VR128:$src1)),
2503                                  (bc_v2i64 (v2f64 VR128:$src2))))],
2504        [(set VR128:$dst, (OpNode (bc_v2i64 (v2f64 VR128:$src1)),
2505                                  (memopv2i64 addr:$src2)))], 0>,
2506                                                  TB, OpSize, VEX_4V;
2507   let Constraints = "$src1 = $dst" in {
2508     defm PS : sse12_fp_packed_logical_rm<opc, VR128, SSEPackedSingle,
2509          !strconcat(OpcodeStr, "ps"), f128mem,
2510          [(set VR128:$dst, (v2i64 (OpNode VR128:$src1, VR128:$src2)))],
2511          [(set VR128:$dst, (OpNode (bc_v2i64 (v4f32 VR128:$src1)),
2512                                    (memopv2i64 addr:$src2)))]>, TB;
2513
2514     defm PD : sse12_fp_packed_logical_rm<opc, VR128, SSEPackedDouble,
2515          !strconcat(OpcodeStr, "pd"), f128mem,
2516          [(set VR128:$dst, (OpNode (bc_v2i64 (v2f64 VR128:$src1)),
2517                                    (bc_v2i64 (v2f64 VR128:$src2))))],
2518          [(set VR128:$dst, (OpNode (bc_v2i64 (v2f64 VR128:$src1)),
2519                                    (memopv2i64 addr:$src2)))]>, TB, OpSize;
2520   }
2521 }
2522
2523 /// sse12_fp_packed_logical_y - AVX 256-bit SSE 1 & 2 logical ops forms
2524 ///
2525 multiclass sse12_fp_packed_logical_y<bits<8> opc, string OpcodeStr,
2526                                      SDNode OpNode> {
2527     defm PSY : sse12_fp_packed_logical_rm<opc, VR256, SSEPackedSingle,
2528           !strconcat(OpcodeStr, "ps"), f256mem,
2529           [(set VR256:$dst, (v4i64 (OpNode VR256:$src1, VR256:$src2)))],
2530           [(set VR256:$dst, (OpNode (bc_v4i64 (v8f32 VR256:$src1)),
2531                                     (memopv4i64 addr:$src2)))], 0>, TB, VEX_4V;
2532
2533     defm PDY : sse12_fp_packed_logical_rm<opc, VR256, SSEPackedDouble,
2534           !strconcat(OpcodeStr, "pd"), f256mem,
2535           [(set VR256:$dst, (OpNode (bc_v4i64 (v4f64 VR256:$src1)),
2536                                     (bc_v4i64 (v4f64 VR256:$src2))))],
2537           [(set VR256:$dst, (OpNode (bc_v4i64 (v4f64 VR256:$src1)),
2538                                     (memopv4i64 addr:$src2)))], 0>,
2539                                     TB, OpSize, VEX_4V;
2540 }
2541
2542 // AVX 256-bit packed logical ops forms
2543 defm VAND  : sse12_fp_packed_logical_y<0x54, "and", and>;
2544 defm VOR   : sse12_fp_packed_logical_y<0x56, "or", or>;
2545 defm VXOR  : sse12_fp_packed_logical_y<0x57, "xor", xor>;
2546 defm VANDN : sse12_fp_packed_logical_y<0x55, "andn", X86andnp>;
2547
2548 defm AND  : sse12_fp_packed_logical<0x54, "and", and>;
2549 defm OR   : sse12_fp_packed_logical<0x56, "or", or>;
2550 defm XOR  : sse12_fp_packed_logical<0x57, "xor", xor>;
2551 let isCommutable = 0 in
2552   defm ANDN : sse12_fp_packed_logical<0x55, "andn", X86andnp>;
2553
2554 //===----------------------------------------------------------------------===//
2555 // SSE 1 & 2 - Arithmetic Instructions
2556 //===----------------------------------------------------------------------===//
2557
2558 /// basic_sse12_fp_binop_xxx - SSE 1 & 2 binops come in both scalar and
2559 /// vector forms.
2560 ///
2561 /// In addition, we also have a special variant of the scalar form here to
2562 /// represent the associated intrinsic operation.  This form is unlike the
2563 /// plain scalar form, in that it takes an entire vector (instead of a scalar)
2564 /// and leaves the top elements unmodified (therefore these cannot be commuted).
2565 ///
2566 /// These three forms can each be reg+reg or reg+mem.
2567 ///
2568
2569 /// FIXME: once all 256-bit intrinsics are matched, cleanup and refactor those
2570 /// classes below
2571 multiclass basic_sse12_fp_binop_s<bits<8> opc, string OpcodeStr, SDNode OpNode,
2572                                   bit Is2Addr = 1> {
2573   defm SS : sse12_fp_scalar<opc, !strconcat(OpcodeStr, "ss"),
2574                             OpNode, FR32, f32mem, Is2Addr>, XS;
2575   defm SD : sse12_fp_scalar<opc, !strconcat(OpcodeStr, "sd"),
2576                             OpNode, FR64, f64mem, Is2Addr>, XD;
2577 }
2578
2579 multiclass basic_sse12_fp_binop_p<bits<8> opc, string OpcodeStr, SDNode OpNode,
2580                                    bit Is2Addr = 1> {
2581   let mayLoad = 0 in {
2582   defm PS : sse12_fp_packed<opc, !strconcat(OpcodeStr, "ps"), OpNode, VR128,
2583               v4f32, f128mem, memopv4f32, SSEPackedSingle, Is2Addr>, TB;
2584   defm PD : sse12_fp_packed<opc, !strconcat(OpcodeStr, "pd"), OpNode, VR128,
2585               v2f64, f128mem, memopv2f64, SSEPackedDouble, Is2Addr>, TB, OpSize;
2586   }
2587 }
2588
2589 multiclass basic_sse12_fp_binop_p_y<bits<8> opc, string OpcodeStr,
2590                                     SDNode OpNode> {
2591   let mayLoad = 0 in {
2592     defm PSY : sse12_fp_packed<opc, !strconcat(OpcodeStr, "ps"), OpNode, VR256,
2593                 v8f32, f256mem, memopv8f32, SSEPackedSingle, 0>, TB;
2594     defm PDY : sse12_fp_packed<opc, !strconcat(OpcodeStr, "pd"), OpNode, VR256,
2595                 v4f64, f256mem, memopv4f64, SSEPackedDouble, 0>, TB, OpSize;
2596   }
2597 }
2598
2599 multiclass basic_sse12_fp_binop_s_int<bits<8> opc, string OpcodeStr,
2600                                       bit Is2Addr = 1> {
2601   defm SS : sse12_fp_scalar_int<opc, OpcodeStr, VR128,
2602      !strconcat(OpcodeStr, "ss"), "", "_ss", ssmem, sse_load_f32, Is2Addr>, XS;
2603   defm SD : sse12_fp_scalar_int<opc, OpcodeStr, VR128,
2604      !strconcat(OpcodeStr, "sd"), "2", "_sd", sdmem, sse_load_f64, Is2Addr>, XD;
2605 }
2606
2607 multiclass basic_sse12_fp_binop_p_int<bits<8> opc, string OpcodeStr,
2608                                       bit Is2Addr = 1> {
2609   defm PS : sse12_fp_packed_int<opc, OpcodeStr, VR128,
2610      !strconcat(OpcodeStr, "ps"), "sse", "_ps", f128mem, memopv4f32,
2611                                               SSEPackedSingle, Is2Addr>, TB;
2612
2613   defm PD : sse12_fp_packed_int<opc, OpcodeStr, VR128,
2614      !strconcat(OpcodeStr, "pd"), "sse2", "_pd", f128mem, memopv2f64,
2615                                       SSEPackedDouble, Is2Addr>, TB, OpSize;
2616 }
2617
2618 multiclass basic_sse12_fp_binop_p_y_int<bits<8> opc, string OpcodeStr> {
2619   defm PSY : sse12_fp_packed_int<opc, OpcodeStr, VR256,
2620      !strconcat(OpcodeStr, "ps"), "avx", "_ps_256", f256mem, memopv8f32,
2621       SSEPackedSingle, 0>, TB;
2622
2623   defm PDY : sse12_fp_packed_int<opc, OpcodeStr, VR256,
2624      !strconcat(OpcodeStr, "pd"), "avx", "_pd_256", f256mem, memopv4f64,
2625       SSEPackedDouble, 0>, TB, OpSize;
2626 }
2627
2628 // Binary Arithmetic instructions
2629 defm VADD : basic_sse12_fp_binop_s<0x58, "add", fadd, 0>,
2630             basic_sse12_fp_binop_s_int<0x58, "add", 0>, VEX_4V, VEX_LIG;
2631 defm VADD : basic_sse12_fp_binop_p<0x58, "add", fadd, 0>,
2632             basic_sse12_fp_binop_p_y<0x58, "add", fadd>, VEX_4V;
2633 defm VMUL : basic_sse12_fp_binop_s<0x59, "mul", fmul, 0>,
2634             basic_sse12_fp_binop_s_int<0x59, "mul", 0>, VEX_4V, VEX_LIG;
2635 defm VMUL : basic_sse12_fp_binop_p<0x59, "mul", fmul, 0>,
2636             basic_sse12_fp_binop_p_y<0x59, "mul", fmul>, VEX_4V;
2637
2638 let isCommutable = 0 in {
2639   defm VSUB : basic_sse12_fp_binop_s<0x5C, "sub", fsub, 0>,
2640               basic_sse12_fp_binop_s_int<0x5C, "sub", 0>, VEX_4V, VEX_LIG;
2641   defm VSUB : basic_sse12_fp_binop_p<0x5C, "sub", fsub, 0>,
2642               basic_sse12_fp_binop_p_y<0x5C, "sub", fsub>, VEX_4V;
2643   defm VDIV : basic_sse12_fp_binop_s<0x5E, "div", fdiv, 0>,
2644               basic_sse12_fp_binop_s_int<0x5E, "div", 0>, VEX_4V, VEX_LIG;
2645   defm VDIV : basic_sse12_fp_binop_p<0x5E, "div", fdiv, 0>,
2646               basic_sse12_fp_binop_p_y<0x5E, "div", fdiv>, VEX_4V;
2647   defm VMAX : basic_sse12_fp_binop_s<0x5F, "max", X86fmax, 0>,
2648               basic_sse12_fp_binop_s_int<0x5F, "max", 0>, VEX_4V, VEX_LIG;
2649   defm VMAX : basic_sse12_fp_binop_p<0x5F, "max", X86fmax, 0>,
2650               basic_sse12_fp_binop_p_int<0x5F, "max", 0>,
2651               basic_sse12_fp_binop_p_y<0x5F, "max", X86fmax>,
2652               basic_sse12_fp_binop_p_y_int<0x5F, "max">, VEX_4V;
2653   defm VMIN : basic_sse12_fp_binop_s<0x5D, "min", X86fmin, 0>,
2654               basic_sse12_fp_binop_s_int<0x5D, "min", 0>, VEX_4V, VEX_LIG;
2655   defm VMIN : basic_sse12_fp_binop_p<0x5D, "min", X86fmin, 0>,
2656               basic_sse12_fp_binop_p_int<0x5D, "min", 0>,
2657               basic_sse12_fp_binop_p_y_int<0x5D, "min">,
2658               basic_sse12_fp_binop_p_y<0x5D, "min", X86fmin>, VEX_4V;
2659 }
2660
2661 let Constraints = "$src1 = $dst" in {
2662   defm ADD : basic_sse12_fp_binop_s<0x58, "add", fadd>,
2663              basic_sse12_fp_binop_p<0x58, "add", fadd>,
2664              basic_sse12_fp_binop_s_int<0x58, "add">;
2665   defm MUL : basic_sse12_fp_binop_s<0x59, "mul", fmul>,
2666              basic_sse12_fp_binop_p<0x59, "mul", fmul>,
2667              basic_sse12_fp_binop_s_int<0x59, "mul">;
2668
2669   let isCommutable = 0 in {
2670     defm SUB : basic_sse12_fp_binop_s<0x5C, "sub", fsub>,
2671                basic_sse12_fp_binop_p<0x5C, "sub", fsub>,
2672                basic_sse12_fp_binop_s_int<0x5C, "sub">;
2673     defm DIV : basic_sse12_fp_binop_s<0x5E, "div", fdiv>,
2674                basic_sse12_fp_binop_p<0x5E, "div", fdiv>,
2675                basic_sse12_fp_binop_s_int<0x5E, "div">;
2676     defm MAX : basic_sse12_fp_binop_s<0x5F, "max", X86fmax>,
2677                basic_sse12_fp_binop_p<0x5F, "max", X86fmax>,
2678                basic_sse12_fp_binop_s_int<0x5F, "max">,
2679                basic_sse12_fp_binop_p_int<0x5F, "max">;
2680     defm MIN : basic_sse12_fp_binop_s<0x5D, "min", X86fmin>,
2681                basic_sse12_fp_binop_p<0x5D, "min", X86fmin>,
2682                basic_sse12_fp_binop_s_int<0x5D, "min">,
2683                basic_sse12_fp_binop_p_int<0x5D, "min">;
2684   }
2685 }
2686
2687 /// Unop Arithmetic
2688 /// In addition, we also have a special variant of the scalar form here to
2689 /// represent the associated intrinsic operation.  This form is unlike the
2690 /// plain scalar form, in that it takes an entire vector (instead of a
2691 /// scalar) and leaves the top elements undefined.
2692 ///
2693 /// And, we have a special variant form for a full-vector intrinsic form.
2694
2695 /// sse1_fp_unop_s - SSE1 unops in scalar form.
2696 multiclass sse1_fp_unop_s<bits<8> opc, string OpcodeStr,
2697                           SDNode OpNode, Intrinsic F32Int> {
2698   def SSr : SSI<opc, MRMSrcReg, (outs FR32:$dst), (ins FR32:$src),
2699                 !strconcat(OpcodeStr, "ss\t{$src, $dst|$dst, $src}"),
2700                 [(set FR32:$dst, (OpNode FR32:$src))]>;
2701   // For scalar unary operations, fold a load into the operation
2702   // only in OptForSize mode. It eliminates an instruction, but it also
2703   // eliminates a whole-register clobber (the load), so it introduces a
2704   // partial register update condition.
2705   def SSm : I<opc, MRMSrcMem, (outs FR32:$dst), (ins f32mem:$src),
2706                 !strconcat(OpcodeStr, "ss\t{$src, $dst|$dst, $src}"),
2707                 [(set FR32:$dst, (OpNode (load addr:$src)))]>, XS,
2708             Requires<[HasSSE1, OptForSize]>;
2709   def SSr_Int : SSI<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2710                     !strconcat(OpcodeStr, "ss\t{$src, $dst|$dst, $src}"),
2711                     [(set VR128:$dst, (F32Int VR128:$src))]>;
2712   def SSm_Int : SSI<opc, MRMSrcMem, (outs VR128:$dst), (ins ssmem:$src),
2713                     !strconcat(OpcodeStr, "ss\t{$src, $dst|$dst, $src}"),
2714                     [(set VR128:$dst, (F32Int sse_load_f32:$src))]>;
2715 }
2716
2717 /// sse1_fp_unop_s_avx - AVX SSE1 unops in scalar form.
2718 multiclass sse1_fp_unop_s_avx<bits<8> opc, string OpcodeStr> {
2719   def SSr : SSI<opc, MRMSrcReg, (outs FR32:$dst), (ins FR32:$src1, FR32:$src2),
2720                 !strconcat(OpcodeStr,
2721                            "ss\t{$src2, $src1, $dst|$dst, $src1, $src2}"), []>;
2722   let mayLoad = 1 in
2723   def SSm : SSI<opc, MRMSrcMem, (outs FR32:$dst), (ins FR32:$src1,f32mem:$src2),
2724                 !strconcat(OpcodeStr,
2725                            "ss\t{$src2, $src1, $dst|$dst, $src1, $src2}"), []>;
2726   def SSm_Int : SSI<opc, MRMSrcMem, (outs VR128:$dst),
2727                 (ins VR128:$src1, ssmem:$src2),
2728                 !strconcat(OpcodeStr,
2729                            "ss\t{$src2, $src1, $dst|$dst, $src1, $src2}"), []>;
2730 }
2731
2732 /// sse1_fp_unop_p - SSE1 unops in packed form.
2733 multiclass sse1_fp_unop_p<bits<8> opc, string OpcodeStr, SDNode OpNode> {
2734   def PSr : PSI<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2735               !strconcat(OpcodeStr, "ps\t{$src, $dst|$dst, $src}"),
2736               [(set VR128:$dst, (v4f32 (OpNode VR128:$src)))]>;
2737   def PSm : PSI<opc, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
2738                 !strconcat(OpcodeStr, "ps\t{$src, $dst|$dst, $src}"),
2739                 [(set VR128:$dst, (OpNode (memopv4f32 addr:$src)))]>;
2740 }
2741
2742 /// sse1_fp_unop_p_y - AVX 256-bit SSE1 unops in packed form.
2743 multiclass sse1_fp_unop_p_y<bits<8> opc, string OpcodeStr, SDNode OpNode> {
2744   def PSYr : PSI<opc, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
2745               !strconcat(OpcodeStr, "ps\t{$src, $dst|$dst, $src}"),
2746               [(set VR256:$dst, (v8f32 (OpNode VR256:$src)))]>;
2747   def PSYm : PSI<opc, MRMSrcMem, (outs VR256:$dst), (ins f256mem:$src),
2748                 !strconcat(OpcodeStr, "ps\t{$src, $dst|$dst, $src}"),
2749                 [(set VR256:$dst, (OpNode (memopv8f32 addr:$src)))]>;
2750 }
2751
2752 /// sse1_fp_unop_p_int - SSE1 intrinsics unops in packed forms.
2753 multiclass sse1_fp_unop_p_int<bits<8> opc, string OpcodeStr,
2754                               Intrinsic V4F32Int> {
2755   def PSr_Int : PSI<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2756                     !strconcat(OpcodeStr, "ps\t{$src, $dst|$dst, $src}"),
2757                     [(set VR128:$dst, (V4F32Int VR128:$src))]>;
2758   def PSm_Int : PSI<opc, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
2759                     !strconcat(OpcodeStr, "ps\t{$src, $dst|$dst, $src}"),
2760                     [(set VR128:$dst, (V4F32Int (memopv4f32 addr:$src)))]>;
2761 }
2762
2763 /// sse1_fp_unop_p_y_int - AVX 256-bit intrinsics unops in packed forms.
2764 multiclass sse1_fp_unop_p_y_int<bits<8> opc, string OpcodeStr,
2765                                 Intrinsic V4F32Int> {
2766   def PSYr_Int : PSI<opc, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
2767                     !strconcat(OpcodeStr, "ps\t{$src, $dst|$dst, $src}"),
2768                     [(set VR256:$dst, (V4F32Int VR256:$src))]>;
2769   def PSYm_Int : PSI<opc, MRMSrcMem, (outs VR256:$dst), (ins f256mem:$src),
2770                     !strconcat(OpcodeStr, "ps\t{$src, $dst|$dst, $src}"),
2771                     [(set VR256:$dst, (V4F32Int (memopv8f32 addr:$src)))]>;
2772 }
2773
2774 /// sse2_fp_unop_s - SSE2 unops in scalar form.
2775 multiclass sse2_fp_unop_s<bits<8> opc, string OpcodeStr,
2776                           SDNode OpNode, Intrinsic F64Int> {
2777   def SDr : SDI<opc, MRMSrcReg, (outs FR64:$dst), (ins FR64:$src),
2778                 !strconcat(OpcodeStr, "sd\t{$src, $dst|$dst, $src}"),
2779                 [(set FR64:$dst, (OpNode FR64:$src))]>;
2780   // See the comments in sse1_fp_unop_s for why this is OptForSize.
2781   def SDm : I<opc, MRMSrcMem, (outs FR64:$dst), (ins f64mem:$src),
2782                 !strconcat(OpcodeStr, "sd\t{$src, $dst|$dst, $src}"),
2783                 [(set FR64:$dst, (OpNode (load addr:$src)))]>, XD,
2784             Requires<[HasSSE2, OptForSize]>;
2785   def SDr_Int : SDI<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2786                     !strconcat(OpcodeStr, "sd\t{$src, $dst|$dst, $src}"),
2787                     [(set VR128:$dst, (F64Int VR128:$src))]>;
2788   def SDm_Int : SDI<opc, MRMSrcMem, (outs VR128:$dst), (ins sdmem:$src),
2789                     !strconcat(OpcodeStr, "sd\t{$src, $dst|$dst, $src}"),
2790                     [(set VR128:$dst, (F64Int sse_load_f64:$src))]>;
2791 }
2792
2793 /// sse2_fp_unop_s_avx - AVX SSE2 unops in scalar form.
2794 multiclass sse2_fp_unop_s_avx<bits<8> opc, string OpcodeStr> {
2795   let neverHasSideEffects = 1 in {
2796   def SDr : SDI<opc, MRMSrcReg, (outs FR64:$dst), (ins FR64:$src1, FR64:$src2),
2797                !strconcat(OpcodeStr,
2798                           "sd\t{$src2, $src1, $dst|$dst, $src1, $src2}"), []>;
2799   let mayLoad = 1 in
2800   def SDm : SDI<opc, MRMSrcMem, (outs FR64:$dst), (ins FR64:$src1,f64mem:$src2),
2801                !strconcat(OpcodeStr,
2802                           "sd\t{$src2, $src1, $dst|$dst, $src1, $src2}"), []>;
2803   }
2804   def SDm_Int : SDI<opc, MRMSrcMem, (outs VR128:$dst),
2805                (ins VR128:$src1, sdmem:$src2),
2806                !strconcat(OpcodeStr,
2807                           "sd\t{$src2, $src1, $dst|$dst, $src1, $src2}"), []>;
2808 }
2809
2810 /// sse2_fp_unop_p - SSE2 unops in vector forms.
2811 multiclass sse2_fp_unop_p<bits<8> opc, string OpcodeStr,
2812                           SDNode OpNode> {
2813   def PDr : PDI<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2814               !strconcat(OpcodeStr, "pd\t{$src, $dst|$dst, $src}"),
2815               [(set VR128:$dst, (v2f64 (OpNode VR128:$src)))]>;
2816   def PDm : PDI<opc, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
2817                 !strconcat(OpcodeStr, "pd\t{$src, $dst|$dst, $src}"),
2818                 [(set VR128:$dst, (OpNode (memopv2f64 addr:$src)))]>;
2819 }
2820
2821 /// sse2_fp_unop_p_y - AVX SSE2 256-bit unops in vector forms.
2822 multiclass sse2_fp_unop_p_y<bits<8> opc, string OpcodeStr, SDNode OpNode> {
2823   def PDYr : PDI<opc, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
2824               !strconcat(OpcodeStr, "pd\t{$src, $dst|$dst, $src}"),
2825               [(set VR256:$dst, (v4f64 (OpNode VR256:$src)))]>;
2826   def PDYm : PDI<opc, MRMSrcMem, (outs VR256:$dst), (ins f256mem:$src),
2827                 !strconcat(OpcodeStr, "pd\t{$src, $dst|$dst, $src}"),
2828                 [(set VR256:$dst, (OpNode (memopv4f64 addr:$src)))]>;
2829 }
2830
2831 /// sse2_fp_unop_p_int - SSE2 intrinsic unops in vector forms.
2832 multiclass sse2_fp_unop_p_int<bits<8> opc, string OpcodeStr,
2833                               Intrinsic V2F64Int> {
2834   def PDr_Int : PDI<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2835                     !strconcat(OpcodeStr, "pd\t{$src, $dst|$dst, $src}"),
2836                     [(set VR128:$dst, (V2F64Int VR128:$src))]>;
2837   def PDm_Int : PDI<opc, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
2838                     !strconcat(OpcodeStr, "pd\t{$src, $dst|$dst, $src}"),
2839                     [(set VR128:$dst, (V2F64Int (memopv2f64 addr:$src)))]>;
2840 }
2841
2842 /// sse2_fp_unop_p_y_int - AVX 256-bit intrinsic unops in vector forms.
2843 multiclass sse2_fp_unop_p_y_int<bits<8> opc, string OpcodeStr,
2844                                 Intrinsic V2F64Int> {
2845   def PDYr_Int : PDI<opc, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
2846                     !strconcat(OpcodeStr, "pd\t{$src, $dst|$dst, $src}"),
2847                     [(set VR256:$dst, (V2F64Int VR256:$src))]>;
2848   def PDYm_Int : PDI<opc, MRMSrcMem, (outs VR256:$dst), (ins f256mem:$src),
2849                     !strconcat(OpcodeStr, "pd\t{$src, $dst|$dst, $src}"),
2850                     [(set VR256:$dst, (V2F64Int (memopv4f64 addr:$src)))]>;
2851 }
2852
2853 let Predicates = [HasAVX] in {
2854   // Square root.
2855   defm VSQRT  : sse1_fp_unop_s_avx<0x51, "vsqrt">,
2856                 sse2_fp_unop_s_avx<0x51, "vsqrt">, VEX_4V, VEX_LIG;
2857
2858   defm VSQRT  : sse1_fp_unop_p<0x51, "vsqrt", fsqrt>,
2859                 sse2_fp_unop_p<0x51, "vsqrt", fsqrt>,
2860                 sse1_fp_unop_p_y<0x51, "vsqrt", fsqrt>,
2861                 sse2_fp_unop_p_y<0x51, "vsqrt", fsqrt>,
2862                 sse1_fp_unop_p_int<0x51, "vsqrt", int_x86_sse_sqrt_ps>,
2863                 sse2_fp_unop_p_int<0x51, "vsqrt", int_x86_sse2_sqrt_pd>,
2864                 sse1_fp_unop_p_y_int<0x51, "vsqrt", int_x86_avx_sqrt_ps_256>,
2865                 sse2_fp_unop_p_y_int<0x51, "vsqrt", int_x86_avx_sqrt_pd_256>,
2866                 VEX;
2867
2868   // Reciprocal approximations. Note that these typically require refinement
2869   // in order to obtain suitable precision.
2870   defm VRSQRT : sse1_fp_unop_s_avx<0x52, "vrsqrt">, VEX_4V, VEX_LIG;
2871   defm VRSQRT : sse1_fp_unop_p<0x52, "vrsqrt", X86frsqrt>,
2872                 sse1_fp_unop_p_y<0x52, "vrsqrt", X86frsqrt>,
2873                 sse1_fp_unop_p_y_int<0x52, "vrsqrt", int_x86_avx_rsqrt_ps_256>,
2874                 sse1_fp_unop_p_int<0x52, "vrsqrt", int_x86_sse_rsqrt_ps>, VEX;
2875
2876   defm VRCP   : sse1_fp_unop_s_avx<0x53, "vrcp">, VEX_4V, VEX_LIG;
2877   defm VRCP   : sse1_fp_unop_p<0x53, "vrcp", X86frcp>,
2878                 sse1_fp_unop_p_y<0x53, "vrcp", X86frcp>,
2879                 sse1_fp_unop_p_y_int<0x53, "vrcp", int_x86_avx_rcp_ps_256>,
2880                 sse1_fp_unop_p_int<0x53, "vrcp", int_x86_sse_rcp_ps>, VEX;
2881 }
2882
2883 let AddedComplexity = 1 in {
2884 def : Pat<(f32 (fsqrt FR32:$src)),
2885           (VSQRTSSr (f32 (IMPLICIT_DEF)), FR32:$src)>, Requires<[HasAVX]>;
2886 def : Pat<(f32 (fsqrt (load addr:$src))),
2887           (VSQRTSSm (f32 (IMPLICIT_DEF)), addr:$src)>,
2888           Requires<[HasAVX, OptForSize]>;
2889 def : Pat<(f64 (fsqrt FR64:$src)),
2890           (VSQRTSDr (f64 (IMPLICIT_DEF)), FR64:$src)>, Requires<[HasAVX]>;
2891 def : Pat<(f64 (fsqrt (load addr:$src))),
2892           (VSQRTSDm (f64 (IMPLICIT_DEF)), addr:$src)>,
2893           Requires<[HasAVX, OptForSize]>;
2894
2895 def : Pat<(f32 (X86frsqrt FR32:$src)),
2896           (VRSQRTSSr (f32 (IMPLICIT_DEF)), FR32:$src)>, Requires<[HasAVX]>;
2897 def : Pat<(f32 (X86frsqrt (load addr:$src))),
2898           (VRSQRTSSm (f32 (IMPLICIT_DEF)), addr:$src)>,
2899           Requires<[HasAVX, OptForSize]>;
2900
2901 def : Pat<(f32 (X86frcp FR32:$src)),
2902           (VRCPSSr (f32 (IMPLICIT_DEF)), FR32:$src)>, Requires<[HasAVX]>;
2903 def : Pat<(f32 (X86frcp (load addr:$src))),
2904           (VRCPSSm (f32 (IMPLICIT_DEF)), addr:$src)>,
2905           Requires<[HasAVX, OptForSize]>;
2906 }
2907
2908 let Predicates = [HasAVX], AddedComplexity = 1 in {
2909   def : Pat<(int_x86_sse_sqrt_ss VR128:$src),
2910             (INSERT_SUBREG (v4f32 (IMPLICIT_DEF)),
2911                 (VSQRTSSr (f32 (IMPLICIT_DEF)),
2912                           (EXTRACT_SUBREG (v4f32 VR128:$src), sub_ss)),
2913                 sub_ss)>;
2914   def : Pat<(int_x86_sse_sqrt_ss sse_load_f32:$src),
2915             (VSQRTSSm_Int (v4f32 (IMPLICIT_DEF)), sse_load_f32:$src)>;
2916
2917   def : Pat<(int_x86_sse2_sqrt_sd VR128:$src),
2918             (INSERT_SUBREG (v2f64 (IMPLICIT_DEF)),
2919                 (VSQRTSDr (f64 (IMPLICIT_DEF)),
2920                           (EXTRACT_SUBREG (v2f64 VR128:$src), sub_sd)),
2921                 sub_sd)>;
2922   def : Pat<(int_x86_sse2_sqrt_sd sse_load_f64:$src),
2923             (VSQRTSDm_Int (v2f64 (IMPLICIT_DEF)), sse_load_f64:$src)>;
2924
2925   def : Pat<(int_x86_sse_rsqrt_ss VR128:$src),
2926             (INSERT_SUBREG (v4f32 (IMPLICIT_DEF)),
2927                 (VRSQRTSSr (f32 (IMPLICIT_DEF)),
2928                           (EXTRACT_SUBREG (v4f32 VR128:$src), sub_ss)),
2929                 sub_ss)>;
2930   def : Pat<(int_x86_sse_rsqrt_ss sse_load_f32:$src),
2931             (VRSQRTSSm_Int (v4f32 (IMPLICIT_DEF)), sse_load_f32:$src)>;
2932
2933   def : Pat<(int_x86_sse_rcp_ss VR128:$src),
2934             (INSERT_SUBREG (v4f32 (IMPLICIT_DEF)),
2935                 (VRCPSSr (f32 (IMPLICIT_DEF)),
2936                          (EXTRACT_SUBREG (v4f32 VR128:$src), sub_ss)),
2937                 sub_ss)>;
2938   def : Pat<(int_x86_sse_rcp_ss sse_load_f32:$src),
2939             (VRCPSSm_Int (v4f32 (IMPLICIT_DEF)), sse_load_f32:$src)>;
2940 }
2941
2942 // Square root.
2943 defm SQRT  : sse1_fp_unop_s<0x51, "sqrt",  fsqrt, int_x86_sse_sqrt_ss>,
2944              sse1_fp_unop_p<0x51, "sqrt",  fsqrt>,
2945              sse1_fp_unop_p_int<0x51, "sqrt",  int_x86_sse_sqrt_ps>,
2946              sse2_fp_unop_s<0x51, "sqrt",  fsqrt, int_x86_sse2_sqrt_sd>,
2947              sse2_fp_unop_p<0x51, "sqrt",  fsqrt>,
2948              sse2_fp_unop_p_int<0x51, "sqrt", int_x86_sse2_sqrt_pd>;
2949
2950 // Reciprocal approximations. Note that these typically require refinement
2951 // in order to obtain suitable precision.
2952 defm RSQRT : sse1_fp_unop_s<0x52, "rsqrt", X86frsqrt, int_x86_sse_rsqrt_ss>,
2953              sse1_fp_unop_p<0x52, "rsqrt", X86frsqrt>,
2954              sse1_fp_unop_p_int<0x52, "rsqrt", int_x86_sse_rsqrt_ps>;
2955 defm RCP   : sse1_fp_unop_s<0x53, "rcp", X86frcp, int_x86_sse_rcp_ss>,
2956              sse1_fp_unop_p<0x53, "rcp", X86frcp>,
2957              sse1_fp_unop_p_int<0x53, "rcp", int_x86_sse_rcp_ps>;
2958
2959 // There is no f64 version of the reciprocal approximation instructions.
2960
2961 //===----------------------------------------------------------------------===//
2962 // SSE 1 & 2 - Non-temporal stores
2963 //===----------------------------------------------------------------------===//
2964
2965 let AddedComplexity = 400 in { // Prefer non-temporal versions
2966   def VMOVNTPSmr : VPSI<0x2B, MRMDestMem, (outs),
2967                        (ins f128mem:$dst, VR128:$src),
2968                        "movntps\t{$src, $dst|$dst, $src}",
2969                        [(alignednontemporalstore (v4f32 VR128:$src),
2970                                                  addr:$dst)]>, VEX;
2971   def VMOVNTPDmr : VPDI<0x2B, MRMDestMem, (outs),
2972                        (ins f128mem:$dst, VR128:$src),
2973                        "movntpd\t{$src, $dst|$dst, $src}",
2974                        [(alignednontemporalstore (v2f64 VR128:$src),
2975                                                  addr:$dst)]>, VEX;
2976
2977   let ExeDomain = SSEPackedInt in
2978   def VMOVNTDQmr    : VPDI<0xE7, MRMDestMem, (outs),
2979                            (ins f128mem:$dst, VR128:$src),
2980                            "movntdq\t{$src, $dst|$dst, $src}",
2981                            [(alignednontemporalstore (v2i64 VR128:$src),
2982                                                      addr:$dst)]>, VEX;
2983
2984   def : Pat<(alignednontemporalstore (v2i64 VR128:$src), addr:$dst),
2985             (VMOVNTDQmr addr:$dst, VR128:$src)>, Requires<[HasAVX]>;
2986
2987   def VMOVNTPSYmr : VPSI<0x2B, MRMDestMem, (outs),
2988                        (ins f256mem:$dst, VR256:$src),
2989                        "movntps\t{$src, $dst|$dst, $src}",
2990                        [(alignednontemporalstore (v8f32 VR256:$src),
2991                                                  addr:$dst)]>, VEX;
2992   def VMOVNTPDYmr : VPDI<0x2B, MRMDestMem, (outs),
2993                        (ins f256mem:$dst, VR256:$src),
2994                        "movntpd\t{$src, $dst|$dst, $src}",
2995                        [(alignednontemporalstore (v4f64 VR256:$src),
2996                                                  addr:$dst)]>, VEX;
2997   let ExeDomain = SSEPackedInt in
2998   def VMOVNTDQYmr : VPDI<0xE7, MRMDestMem, (outs),
2999                       (ins f256mem:$dst, VR256:$src),
3000                       "movntdq\t{$src, $dst|$dst, $src}",
3001                       [(alignednontemporalstore (v4i64 VR256:$src),
3002                                                 addr:$dst)]>, VEX;
3003 }
3004
3005 def : Pat<(int_x86_avx_movnt_dq_256 addr:$dst, VR256:$src),
3006           (VMOVNTDQYmr addr:$dst, VR256:$src)>;
3007 def : Pat<(int_x86_avx_movnt_pd_256 addr:$dst, VR256:$src),
3008           (VMOVNTPDYmr addr:$dst, VR256:$src)>;
3009 def : Pat<(int_x86_avx_movnt_ps_256 addr:$dst, VR256:$src),
3010           (VMOVNTPSYmr addr:$dst, VR256:$src)>;
3011
3012 let AddedComplexity = 400 in { // Prefer non-temporal versions
3013 def MOVNTPSmr : PSI<0x2B, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
3014                     "movntps\t{$src, $dst|$dst, $src}",
3015                     [(alignednontemporalstore (v4f32 VR128:$src), addr:$dst)]>;
3016 def MOVNTPDmr : PDI<0x2B, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
3017                     "movntpd\t{$src, $dst|$dst, $src}",
3018                     [(alignednontemporalstore(v2f64 VR128:$src), addr:$dst)]>;
3019
3020 let ExeDomain = SSEPackedInt in
3021 def MOVNTDQmr : PDI<0xE7, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
3022                     "movntdq\t{$src, $dst|$dst, $src}",
3023                     [(alignednontemporalstore (v2i64 VR128:$src), addr:$dst)]>;
3024
3025 def : Pat<(alignednontemporalstore (v2i64 VR128:$src), addr:$dst),
3026           (MOVNTDQmr addr:$dst, VR128:$src)>, Requires<[HasSSE2]>;
3027
3028 // There is no AVX form for instructions below this point
3029 def MOVNTImr : I<0xC3, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
3030                  "movnti{l}\t{$src, $dst|$dst, $src}",
3031                  [(nontemporalstore (i32 GR32:$src), addr:$dst)]>,
3032                TB, Requires<[HasSSE2]>;
3033 def MOVNTI_64mr : RI<0xC3, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
3034                      "movnti{q}\t{$src, $dst|$dst, $src}",
3035                      [(nontemporalstore (i64 GR64:$src), addr:$dst)]>,
3036                   TB, Requires<[HasSSE2]>;
3037 }
3038
3039 //===----------------------------------------------------------------------===//
3040 // SSE 1 & 2 - Prefetch and memory fence
3041 //===----------------------------------------------------------------------===//
3042
3043 // Prefetch intrinsic.
3044 let Predicates = [HasSSE1] in {
3045 def PREFETCHT0   : I<0x18, MRM1m, (outs), (ins i8mem:$src),
3046     "prefetcht0\t$src", [(prefetch addr:$src, imm, (i32 3), (i32 1))]>, TB;
3047 def PREFETCHT1   : I<0x18, MRM2m, (outs), (ins i8mem:$src),
3048     "prefetcht1\t$src", [(prefetch addr:$src, imm, (i32 2), (i32 1))]>, TB;
3049 def PREFETCHT2   : I<0x18, MRM3m, (outs), (ins i8mem:$src),
3050     "prefetcht2\t$src", [(prefetch addr:$src, imm, (i32 1), (i32 1))]>, TB;
3051 def PREFETCHNTA  : I<0x18, MRM0m, (outs), (ins i8mem:$src),
3052     "prefetchnta\t$src", [(prefetch addr:$src, imm, (i32 0), (i32 1))]>, TB;
3053 }
3054
3055 // Flush cache
3056 def CLFLUSH : I<0xAE, MRM7m, (outs), (ins i8mem:$src),
3057                "clflush\t$src", [(int_x86_sse2_clflush addr:$src)]>,
3058               TB, Requires<[HasSSE2]>;
3059
3060 // Pause. This "instruction" is encoded as "rep; nop", so even though it
3061 // was introduced with SSE2, it's backward compatible.
3062 def PAUSE : I<0x90, RawFrm, (outs), (ins), "pause", []>, REP;
3063
3064 // Load, store, and memory fence
3065 def SFENCE : I<0xAE, MRM_F8, (outs), (ins),
3066                "sfence", [(int_x86_sse_sfence)]>, TB, Requires<[HasSSE1]>;
3067 def LFENCE : I<0xAE, MRM_E8, (outs), (ins),
3068                "lfence", [(int_x86_sse2_lfence)]>, TB, Requires<[HasSSE2]>;
3069 def MFENCE : I<0xAE, MRM_F0, (outs), (ins),
3070                "mfence", [(int_x86_sse2_mfence)]>, TB, Requires<[HasSSE2]>;
3071
3072 def : Pat<(X86SFence), (SFENCE)>;
3073 def : Pat<(X86LFence), (LFENCE)>;
3074 def : Pat<(X86MFence), (MFENCE)>;
3075
3076 //===----------------------------------------------------------------------===//
3077 // SSE 1 & 2 - Load/Store XCSR register
3078 //===----------------------------------------------------------------------===//
3079
3080 def VLDMXCSR : VPSI<0xAE, MRM2m, (outs), (ins i32mem:$src),
3081                   "ldmxcsr\t$src", [(int_x86_sse_ldmxcsr addr:$src)]>, VEX;
3082 def VSTMXCSR : VPSI<0xAE, MRM3m, (outs), (ins i32mem:$dst),
3083                   "stmxcsr\t$dst", [(int_x86_sse_stmxcsr addr:$dst)]>, VEX;
3084
3085 def LDMXCSR : PSI<0xAE, MRM2m, (outs), (ins i32mem:$src),
3086                   "ldmxcsr\t$src", [(int_x86_sse_ldmxcsr addr:$src)]>;
3087 def STMXCSR : PSI<0xAE, MRM3m, (outs), (ins i32mem:$dst),
3088                   "stmxcsr\t$dst", [(int_x86_sse_stmxcsr addr:$dst)]>;
3089
3090 //===---------------------------------------------------------------------===//
3091 // SSE2 - Move Aligned/Unaligned Packed Integer Instructions
3092 //===---------------------------------------------------------------------===//
3093
3094 let ExeDomain = SSEPackedInt in { // SSE integer instructions
3095
3096 let neverHasSideEffects = 1 in {
3097 def VMOVDQArr  : VPDI<0x6F, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3098                     "movdqa\t{$src, $dst|$dst, $src}", []>, VEX;
3099 def VMOVDQAYrr : VPDI<0x6F, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
3100                     "movdqa\t{$src, $dst|$dst, $src}", []>, VEX;
3101 }
3102 def VMOVDQUrr  : VSSI<0x6F, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3103                     "movdqu\t{$src, $dst|$dst, $src}", []>, VEX;
3104 def VMOVDQUYrr : VSSI<0x6F, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
3105                     "movdqu\t{$src, $dst|$dst, $src}", []>, VEX;
3106
3107 // For Disassembler
3108 let isCodeGenOnly = 1 in {
3109 def VMOVDQArr_REV  : VPDI<0x7F, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
3110                         "movdqa\t{$src, $dst|$dst, $src}", []>, VEX;
3111 def VMOVDQAYrr_REV : VPDI<0x7F, MRMDestReg, (outs VR256:$dst), (ins VR256:$src),
3112                         "movdqa\t{$src, $dst|$dst, $src}", []>, VEX;
3113 def VMOVDQUrr_REV  : VSSI<0x7F, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
3114                         "movdqu\t{$src, $dst|$dst, $src}", []>, VEX;
3115 def VMOVDQUYrr_REV : VSSI<0x7F, MRMDestReg, (outs VR256:$dst), (ins VR256:$src),
3116                         "movdqu\t{$src, $dst|$dst, $src}", []>, VEX;
3117 }
3118
3119 let canFoldAsLoad = 1, mayLoad = 1 in {
3120 def VMOVDQArm  : VPDI<0x6F, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
3121                    "movdqa\t{$src, $dst|$dst, $src}", []>, VEX;
3122 def VMOVDQAYrm : VPDI<0x6F, MRMSrcMem, (outs VR256:$dst), (ins i256mem:$src),
3123                    "movdqa\t{$src, $dst|$dst, $src}", []>, VEX;
3124 let Predicates = [HasAVX] in {
3125   def VMOVDQUrm  : I<0x6F, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
3126                     "vmovdqu\t{$src, $dst|$dst, $src}",[]>, XS, VEX;
3127   def VMOVDQUYrm : I<0x6F, MRMSrcMem, (outs VR256:$dst), (ins i256mem:$src),
3128                     "vmovdqu\t{$src, $dst|$dst, $src}",[]>, XS, VEX;
3129 }
3130 }
3131
3132 let mayStore = 1 in {
3133 def VMOVDQAmr  : VPDI<0x7F, MRMDestMem, (outs),
3134                      (ins i128mem:$dst, VR128:$src),
3135                      "movdqa\t{$src, $dst|$dst, $src}", []>, VEX;
3136 def VMOVDQAYmr : VPDI<0x7F, MRMDestMem, (outs),
3137                      (ins i256mem:$dst, VR256:$src),
3138                      "movdqa\t{$src, $dst|$dst, $src}", []>, VEX;
3139 let Predicates = [HasAVX] in {
3140 def VMOVDQUmr  : I<0x7F, MRMDestMem, (outs), (ins i128mem:$dst, VR128:$src),
3141                   "vmovdqu\t{$src, $dst|$dst, $src}",[]>, XS, VEX;
3142 def VMOVDQUYmr : I<0x7F, MRMDestMem, (outs), (ins i256mem:$dst, VR256:$src),
3143                   "vmovdqu\t{$src, $dst|$dst, $src}",[]>, XS, VEX;
3144 }
3145 }
3146
3147 let neverHasSideEffects = 1 in
3148 def MOVDQArr : PDI<0x6F, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3149                    "movdqa\t{$src, $dst|$dst, $src}", []>;
3150
3151 def MOVDQUrr :   I<0x6F, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3152                    "movdqu\t{$src, $dst|$dst, $src}",
3153                    []>, XS, Requires<[HasSSE2]>;
3154
3155 // For Disassembler
3156 let isCodeGenOnly = 1 in {
3157 def MOVDQArr_REV : PDI<0x7F, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
3158                        "movdqa\t{$src, $dst|$dst, $src}", []>;
3159
3160 def MOVDQUrr_REV :   I<0x7F, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
3161                        "movdqu\t{$src, $dst|$dst, $src}",
3162                        []>, XS, Requires<[HasSSE2]>;
3163 }
3164
3165 let canFoldAsLoad = 1, mayLoad = 1 in {
3166 def MOVDQArm : PDI<0x6F, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
3167                    "movdqa\t{$src, $dst|$dst, $src}",
3168                    [/*(set VR128:$dst, (alignedloadv2i64 addr:$src))*/]>;
3169 def MOVDQUrm :   I<0x6F, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
3170                    "movdqu\t{$src, $dst|$dst, $src}",
3171                    [/*(set VR128:$dst, (loadv2i64 addr:$src))*/]>,
3172                  XS, Requires<[HasSSE2]>;
3173 }
3174
3175 let mayStore = 1 in {
3176 def MOVDQAmr : PDI<0x7F, MRMDestMem, (outs), (ins i128mem:$dst, VR128:$src),
3177                    "movdqa\t{$src, $dst|$dst, $src}",
3178                    [/*(alignedstore (v2i64 VR128:$src), addr:$dst)*/]>;
3179 def MOVDQUmr :   I<0x7F, MRMDestMem, (outs), (ins i128mem:$dst, VR128:$src),
3180                    "movdqu\t{$src, $dst|$dst, $src}",
3181                    [/*(store (v2i64 VR128:$src), addr:$dst)*/]>,
3182                  XS, Requires<[HasSSE2]>;
3183 }
3184
3185 // Intrinsic forms of MOVDQU load and store
3186 def VMOVDQUmr_Int : I<0x7F, MRMDestMem, (outs), (ins i128mem:$dst, VR128:$src),
3187                        "vmovdqu\t{$src, $dst|$dst, $src}",
3188                        [(int_x86_sse2_storeu_dq addr:$dst, VR128:$src)]>,
3189                      XS, VEX, Requires<[HasAVX]>;
3190
3191 def MOVDQUmr_Int :   I<0x7F, MRMDestMem, (outs), (ins i128mem:$dst, VR128:$src),
3192                        "movdqu\t{$src, $dst|$dst, $src}",
3193                        [(int_x86_sse2_storeu_dq addr:$dst, VR128:$src)]>,
3194                      XS, Requires<[HasSSE2]>;
3195
3196 } // ExeDomain = SSEPackedInt
3197
3198 let Predicates = [HasAVX] in {
3199   def : Pat<(int_x86_avx_storeu_dq_256 addr:$dst, VR256:$src),
3200             (VMOVDQUYmr addr:$dst, VR256:$src)>;
3201 }
3202
3203 //===---------------------------------------------------------------------===//
3204 // SSE2 - Packed Integer Arithmetic Instructions
3205 //===---------------------------------------------------------------------===//
3206
3207 let ExeDomain = SSEPackedInt in { // SSE integer instructions
3208
3209 multiclass PDI_binop_rm_int<bits<8> opc, string OpcodeStr, Intrinsic IntId,
3210                             RegisterClass RC, PatFrag memop_frag,
3211                             X86MemOperand x86memop, bit IsCommutable = 0,
3212                             bit Is2Addr = 1> {
3213   let isCommutable = IsCommutable in
3214   def rr : PDI<opc, MRMSrcReg, (outs RC:$dst),
3215        (ins RC:$src1, RC:$src2),
3216        !if(Is2Addr,
3217            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
3218            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
3219        [(set RC:$dst, (IntId RC:$src1, RC:$src2))]>;
3220   def rm : PDI<opc, MRMSrcMem, (outs RC:$dst),
3221        (ins RC:$src1, x86memop:$src2),
3222        !if(Is2Addr,
3223            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
3224            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
3225        [(set RC:$dst, (IntId RC:$src1, (bitconvert (memop_frag addr:$src2))))]>;
3226 }
3227
3228 multiclass PDI_binop_rmi<bits<8> opc, bits<8> opc2, Format ImmForm,
3229                          string OpcodeStr, SDNode OpNode,
3230                          SDNode OpNode2, RegisterClass RC,
3231                          ValueType DstVT, ValueType SrcVT, PatFrag bc_frag,
3232                          bit Is2Addr = 1> {
3233   // src2 is always 128-bit
3234   def rr : PDI<opc, MRMSrcReg, (outs RC:$dst),
3235        (ins RC:$src1, VR128:$src2),
3236        !if(Is2Addr,
3237            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
3238            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
3239        [(set RC:$dst, (DstVT (OpNode RC:$src1, (SrcVT VR128:$src2))))]>;
3240   def rm : PDI<opc, MRMSrcMem, (outs RC:$dst),
3241        (ins RC:$src1, i128mem:$src2),
3242        !if(Is2Addr,
3243            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
3244            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
3245        [(set RC:$dst, (DstVT (OpNode RC:$src1,
3246                        (bc_frag (memopv2i64 addr:$src2)))))]>;
3247   def ri : PDIi8<opc2, ImmForm, (outs RC:$dst),
3248        (ins RC:$src1, i32i8imm:$src2),
3249        !if(Is2Addr,
3250            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
3251            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
3252        [(set RC:$dst, (DstVT (OpNode2 RC:$src1, (i32 imm:$src2))))]>;
3253 }
3254
3255 /// PDI_binop_rm - Simple SSE2 binary operator with different src and dst types
3256 multiclass PDI_binop_rm2<bits<8> opc, string OpcodeStr, SDNode OpNode,
3257                          ValueType DstVT, ValueType SrcVT, RegisterClass RC,
3258                          PatFrag memop_frag, X86MemOperand x86memop,
3259                          bit IsCommutable = 0, bit Is2Addr = 1> {
3260   let isCommutable = IsCommutable in
3261   def rr : PDI<opc, MRMSrcReg, (outs RC:$dst),
3262        (ins RC:$src1, RC:$src2),
3263        !if(Is2Addr,
3264            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
3265            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
3266        [(set RC:$dst, (DstVT (OpNode (SrcVT RC:$src1), RC:$src2)))]>;
3267   def rm : PDI<opc, MRMSrcMem, (outs RC:$dst),
3268        (ins RC:$src1, x86memop:$src2),
3269        !if(Is2Addr,
3270            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
3271            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
3272        [(set RC:$dst, (DstVT (OpNode (SrcVT RC:$src1),
3273                                      (bitconvert (memop_frag addr:$src2)))))]>;
3274 }
3275 } // ExeDomain = SSEPackedInt
3276
3277 // 128-bit Integer Arithmetic
3278
3279 let Predicates = [HasAVX] in {
3280 defm VPADDB  : PDI_binop_rm<0xFC, "vpaddb", add, v16i8, VR128, memopv2i64,
3281                             i128mem, 1, 0 /*3addr*/>, VEX_4V;
3282 defm VPADDW  : PDI_binop_rm<0xFD, "vpaddw", add, v8i16, VR128, memopv2i64,
3283                             i128mem, 1, 0>, VEX_4V;
3284 defm VPADDD  : PDI_binop_rm<0xFE, "vpaddd", add, v4i32, VR128, memopv2i64,
3285                             i128mem, 1, 0>, VEX_4V;
3286 defm VPADDQ  : PDI_binop_rm<0xD4, "vpaddq", add, v2i64, VR128, memopv2i64,
3287                             i128mem, 1, 0>, VEX_4V;
3288 defm VPMULLW : PDI_binop_rm<0xD5, "vpmullw", mul, v8i16, VR128, memopv2i64,
3289                             i128mem, 1, 0>, VEX_4V;
3290 defm VPSUBB : PDI_binop_rm<0xF8, "vpsubb", sub, v16i8, VR128, memopv2i64,
3291                             i128mem, 0, 0>, VEX_4V;
3292 defm VPSUBW : PDI_binop_rm<0xF9, "vpsubw", sub, v8i16, VR128, memopv2i64,
3293                             i128mem, 0, 0>, VEX_4V;
3294 defm VPSUBD : PDI_binop_rm<0xFA, "vpsubd", sub, v4i32, VR128, memopv2i64,
3295                             i128mem, 0, 0>, VEX_4V;
3296 defm VPSUBQ : PDI_binop_rm<0xFB, "vpsubq", sub, v2i64, VR128, memopv2i64,
3297                             i128mem, 0, 0>, VEX_4V;
3298 defm VPMULUDQ : PDI_binop_rm2<0xF4, "vpmuludq", X86pmuludq, v2i64, v4i32, VR128,
3299                               memopv2i64, i128mem, 1, 0>, VEX_4V;
3300
3301 // Intrinsic forms
3302 defm VPSUBSB  : PDI_binop_rm_int<0xE8, "vpsubsb" , int_x86_sse2_psubs_b,
3303                                  VR128, memopv2i64, i128mem, 0, 0>, VEX_4V;
3304 defm VPSUBSW  : PDI_binop_rm_int<0xE9, "vpsubsw" , int_x86_sse2_psubs_w,
3305                                  VR128, memopv2i64, i128mem, 0, 0>, VEX_4V;
3306 defm VPSUBUSB : PDI_binop_rm_int<0xD8, "vpsubusb", int_x86_sse2_psubus_b,
3307                                  VR128, memopv2i64, i128mem, 0, 0>, VEX_4V;
3308 defm VPSUBUSW : PDI_binop_rm_int<0xD9, "vpsubusw", int_x86_sse2_psubus_w,
3309                                  VR128, memopv2i64, i128mem, 0, 0>, VEX_4V;
3310 defm VPADDSB  : PDI_binop_rm_int<0xEC, "vpaddsb" , int_x86_sse2_padds_b,
3311                                  VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3312 defm VPADDSW  : PDI_binop_rm_int<0xED, "vpaddsw" , int_x86_sse2_padds_w,
3313                                  VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3314 defm VPADDUSB : PDI_binop_rm_int<0xDC, "vpaddusb", int_x86_sse2_paddus_b,
3315                                  VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3316 defm VPADDUSW : PDI_binop_rm_int<0xDD, "vpaddusw", int_x86_sse2_paddus_w,
3317                                  VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3318 defm VPMULHUW : PDI_binop_rm_int<0xE4, "vpmulhuw", int_x86_sse2_pmulhu_w,
3319                                  VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3320 defm VPMULHW  : PDI_binop_rm_int<0xE5, "vpmulhw" , int_x86_sse2_pmulh_w,
3321                                  VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3322 defm VPMADDWD : PDI_binop_rm_int<0xF5, "vpmaddwd", int_x86_sse2_pmadd_wd,
3323                                  VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3324 defm VPAVGB   : PDI_binop_rm_int<0xE0, "vpavgb", int_x86_sse2_pavg_b,
3325                                  VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3326 defm VPAVGW   : PDI_binop_rm_int<0xE3, "vpavgw", int_x86_sse2_pavg_w,
3327                                  VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3328 defm VPMINUB  : PDI_binop_rm_int<0xDA, "vpminub", int_x86_sse2_pminu_b,
3329                                  VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3330 defm VPMINSW  : PDI_binop_rm_int<0xEA, "vpminsw", int_x86_sse2_pmins_w,
3331                                  VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3332 defm VPMAXUB  : PDI_binop_rm_int<0xDE, "vpmaxub", int_x86_sse2_pmaxu_b,
3333                                  VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3334 defm VPMAXSW  : PDI_binop_rm_int<0xEE, "vpmaxsw", int_x86_sse2_pmaxs_w,
3335                                  VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3336 defm VPSADBW  : PDI_binop_rm_int<0xF6, "vpsadbw", int_x86_sse2_psad_bw,
3337                                  VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3338 }
3339
3340 let Predicates = [HasAVX2] in {
3341 defm VPADDBY  : PDI_binop_rm<0xFC, "vpaddb", add, v32i8, VR256, memopv4i64,
3342                              i256mem, 1, 0>, VEX_4V;
3343 defm VPADDWY  : PDI_binop_rm<0xFD, "vpaddw", add, v16i16, VR256, memopv4i64,
3344                              i256mem, 1, 0>, VEX_4V;
3345 defm VPADDDY  : PDI_binop_rm<0xFE, "vpaddd", add, v8i32, VR256, memopv4i64,
3346                              i256mem, 1, 0>, VEX_4V;
3347 defm VPADDQY  : PDI_binop_rm<0xD4, "vpaddq", add, v4i64, VR256, memopv4i64,
3348                              i256mem, 1, 0>, VEX_4V;
3349 defm VPMULLWY : PDI_binop_rm<0xD5, "vpmullw", mul, v16i16, VR256, memopv4i64,
3350                              i256mem, 1, 0>, VEX_4V;
3351 defm VPSUBBY  : PDI_binop_rm<0xF8, "vpsubb", sub, v32i8, VR256, memopv4i64,
3352                              i256mem, 0, 0>, VEX_4V;
3353 defm VPSUBWY  : PDI_binop_rm<0xF9, "vpsubw", sub, v16i16,VR256, memopv4i64,
3354                              i256mem, 0, 0>, VEX_4V;
3355 defm VPSUBDY  : PDI_binop_rm<0xFA, "vpsubd", sub, v8i32, VR256, memopv4i64,
3356                              i256mem, 0, 0>, VEX_4V;
3357 defm VPSUBQY  : PDI_binop_rm<0xFB, "vpsubq", sub, v4i64, VR256, memopv4i64,
3358                              i256mem, 0, 0>, VEX_4V;
3359 defm VPMULUDQY : PDI_binop_rm2<0xF4, "vpmuludq", X86pmuludq, v4i64, v8i32,
3360                                VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3361
3362 // Intrinsic forms
3363 defm VPSUBSBY  : PDI_binop_rm_int<0xE8, "vpsubsb" , int_x86_avx2_psubs_b,
3364                                   VR256, memopv4i64, i256mem, 0, 0>, VEX_4V;
3365 defm VPSUBSWY  : PDI_binop_rm_int<0xE9, "vpsubsw" , int_x86_avx2_psubs_w,
3366                                   VR256, memopv4i64, i256mem, 0, 0>, VEX_4V;
3367 defm VPSUBUSBY : PDI_binop_rm_int<0xD8, "vpsubusb", int_x86_avx2_psubus_b,
3368                                   VR256, memopv4i64, i256mem, 0, 0>, VEX_4V;
3369 defm VPSUBUSWY : PDI_binop_rm_int<0xD9, "vpsubusw", int_x86_avx2_psubus_w,
3370                                   VR256, memopv4i64, i256mem, 0, 0>, VEX_4V;
3371 defm VPADDSBY  : PDI_binop_rm_int<0xEC, "vpaddsb" , int_x86_avx2_padds_b,
3372                                   VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3373 defm VPADDSWY  : PDI_binop_rm_int<0xED, "vpaddsw" , int_x86_avx2_padds_w,
3374                                   VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3375 defm VPADDUSBY : PDI_binop_rm_int<0xDC, "vpaddusb", int_x86_avx2_paddus_b,
3376                                   VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3377 defm VPADDUSWY : PDI_binop_rm_int<0xDD, "vpaddusw", int_x86_avx2_paddus_w,
3378                                   VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3379 defm VPMULHUWY : PDI_binop_rm_int<0xE4, "vpmulhuw", int_x86_avx2_pmulhu_w,
3380                                   VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3381 defm VPMULHWY  : PDI_binop_rm_int<0xE5, "vpmulhw" , int_x86_avx2_pmulh_w,
3382                                   VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3383 defm VPMADDWDY : PDI_binop_rm_int<0xF5, "vpmaddwd", int_x86_avx2_pmadd_wd,
3384                                   VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3385 defm VPAVGBY   : PDI_binop_rm_int<0xE0, "vpavgb", int_x86_avx2_pavg_b,
3386                                   VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3387 defm VPAVGWY   : PDI_binop_rm_int<0xE3, "vpavgw", int_x86_avx2_pavg_w,
3388                                   VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3389 defm VPMINUBY  : PDI_binop_rm_int<0xDA, "vpminub", int_x86_avx2_pminu_b,
3390                                   VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3391 defm VPMINSWY  : PDI_binop_rm_int<0xEA, "vpminsw", int_x86_avx2_pmins_w,
3392                                   VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3393 defm VPMAXUBY  : PDI_binop_rm_int<0xDE, "vpmaxub", int_x86_avx2_pmaxu_b,
3394                                   VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3395 defm VPMAXSWY  : PDI_binop_rm_int<0xEE, "vpmaxsw", int_x86_avx2_pmaxs_w,
3396                                   VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3397 defm VPSADBWY  : PDI_binop_rm_int<0xF6, "vpsadbw", int_x86_avx2_psad_bw,
3398                                   VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3399 }
3400
3401 let Constraints = "$src1 = $dst" in {
3402 defm PADDB  : PDI_binop_rm<0xFC, "paddb", add, v16i8, VR128, memopv2i64,
3403                            i128mem, 1>;
3404 defm PADDW  : PDI_binop_rm<0xFD, "paddw", add, v8i16, VR128, memopv2i64,
3405                            i128mem, 1>;
3406 defm PADDD  : PDI_binop_rm<0xFE, "paddd", add, v4i32, VR128, memopv2i64,
3407                            i128mem, 1>;
3408 defm PADDQ  : PDI_binop_rm<0xD4, "paddq", add, v2i64, VR128, memopv2i64,
3409                            i128mem, 1>;
3410 defm PMULLW : PDI_binop_rm<0xD5, "pmullw", mul, v8i16, VR128, memopv2i64,
3411                            i128mem, 1>;
3412 defm PSUBB : PDI_binop_rm<0xF8, "psubb", sub, v16i8, VR128, memopv2i64,
3413                           i128mem>;
3414 defm PSUBW : PDI_binop_rm<0xF9, "psubw", sub, v8i16, VR128, memopv2i64,
3415                           i128mem>;
3416 defm PSUBD : PDI_binop_rm<0xFA, "psubd", sub, v4i32, VR128, memopv2i64,
3417                           i128mem>;
3418 defm PSUBQ : PDI_binop_rm<0xFB, "psubq", sub, v2i64, VR128, memopv2i64,
3419                           i128mem>;
3420 defm PMULUDQ : PDI_binop_rm2<0xF4, "pmuludq", X86pmuludq, v2i64, v4i32, VR128,
3421                              memopv2i64, i128mem, 1>;
3422
3423 // Intrinsic forms
3424 defm PSUBSB  : PDI_binop_rm_int<0xE8, "psubsb" , int_x86_sse2_psubs_b,
3425                                 VR128, memopv2i64, i128mem>;
3426 defm PSUBSW  : PDI_binop_rm_int<0xE9, "psubsw" , int_x86_sse2_psubs_w,
3427                                 VR128, memopv2i64, i128mem>;
3428 defm PSUBUSB : PDI_binop_rm_int<0xD8, "psubusb", int_x86_sse2_psubus_b,
3429                                 VR128, memopv2i64, i128mem>;
3430 defm PSUBUSW : PDI_binop_rm_int<0xD9, "psubusw", int_x86_sse2_psubus_w,
3431                                 VR128, memopv2i64, i128mem>;
3432 defm PADDSB  : PDI_binop_rm_int<0xEC, "paddsb" , int_x86_sse2_padds_b,
3433                                 VR128, memopv2i64, i128mem, 1>;
3434 defm PADDSW  : PDI_binop_rm_int<0xED, "paddsw" , int_x86_sse2_padds_w,
3435                                 VR128, memopv2i64, i128mem, 1>;
3436 defm PADDUSB : PDI_binop_rm_int<0xDC, "paddusb", int_x86_sse2_paddus_b,
3437                                 VR128, memopv2i64, i128mem, 1>;
3438 defm PADDUSW : PDI_binop_rm_int<0xDD, "paddusw", int_x86_sse2_paddus_w,
3439                                 VR128, memopv2i64, i128mem, 1>;
3440 defm PMULHUW : PDI_binop_rm_int<0xE4, "pmulhuw", int_x86_sse2_pmulhu_w,
3441                                 VR128, memopv2i64, i128mem, 1>;
3442 defm PMULHW  : PDI_binop_rm_int<0xE5, "pmulhw" , int_x86_sse2_pmulh_w,
3443                                 VR128, memopv2i64, i128mem, 1>;
3444 defm PMADDWD : PDI_binop_rm_int<0xF5, "pmaddwd", int_x86_sse2_pmadd_wd,
3445                                 VR128, memopv2i64, i128mem, 1>;
3446 defm PAVGB   : PDI_binop_rm_int<0xE0, "pavgb", int_x86_sse2_pavg_b,
3447                                 VR128, memopv2i64, i128mem, 1>;
3448 defm PAVGW   : PDI_binop_rm_int<0xE3, "pavgw", int_x86_sse2_pavg_w,
3449                                 VR128, memopv2i64, i128mem, 1>;
3450 defm PMINUB  : PDI_binop_rm_int<0xDA, "pminub", int_x86_sse2_pminu_b,
3451                                 VR128, memopv2i64, i128mem, 1>;
3452 defm PMINSW  : PDI_binop_rm_int<0xEA, "pminsw", int_x86_sse2_pmins_w,
3453                                 VR128, memopv2i64, i128mem, 1>;
3454 defm PMAXUB  : PDI_binop_rm_int<0xDE, "pmaxub", int_x86_sse2_pmaxu_b,
3455                                 VR128, memopv2i64, i128mem, 1>;
3456 defm PMAXSW  : PDI_binop_rm_int<0xEE, "pmaxsw", int_x86_sse2_pmaxs_w,
3457                                 VR128, memopv2i64, i128mem, 1>;
3458 defm PSADBW  : PDI_binop_rm_int<0xF6, "psadbw", int_x86_sse2_psad_bw,
3459                                 VR128, memopv2i64, i128mem, 1>;
3460
3461 } // Constraints = "$src1 = $dst"
3462
3463 //===---------------------------------------------------------------------===//
3464 // SSE2 - Packed Integer Logical Instructions
3465 //===---------------------------------------------------------------------===//
3466
3467 let Predicates = [HasAVX] in {
3468 defm VPSLLW : PDI_binop_rmi<0xF1, 0x71, MRM6r, "vpsllw", X86vshl, X86vshli,
3469                             VR128, v8i16, v8i16, bc_v8i16, 0>, VEX_4V;
3470 defm VPSLLD : PDI_binop_rmi<0xF2, 0x72, MRM6r, "vpslld", X86vshl, X86vshli,
3471                             VR128, v4i32, v4i32, bc_v4i32, 0>, VEX_4V;
3472 defm VPSLLQ : PDI_binop_rmi<0xF3, 0x73, MRM6r, "vpsllq", X86vshl, X86vshli,
3473                             VR128, v2i64, v2i64, bc_v2i64, 0>, VEX_4V;
3474
3475 defm VPSRLW : PDI_binop_rmi<0xD1, 0x71, MRM2r, "vpsrlw", X86vsrl, X86vsrli,
3476                             VR128, v8i16, v8i16, bc_v8i16, 0>, VEX_4V;
3477 defm VPSRLD : PDI_binop_rmi<0xD2, 0x72, MRM2r, "vpsrld", X86vsrl, X86vsrli,
3478                             VR128, v4i32, v4i32, bc_v4i32, 0>, VEX_4V;
3479 defm VPSRLQ : PDI_binop_rmi<0xD3, 0x73, MRM2r, "vpsrlq", X86vsrl, X86vsrli,
3480                             VR128, v2i64, v2i64, bc_v2i64, 0>, VEX_4V;
3481
3482 defm VPSRAW : PDI_binop_rmi<0xE1, 0x71, MRM4r, "vpsraw", X86vsra, X86vsrai,
3483                             VR128, v8i16, v8i16, bc_v8i16, 0>, VEX_4V;
3484 defm VPSRAD : PDI_binop_rmi<0xE2, 0x72, MRM4r, "vpsrad", X86vsra, X86vsrai,
3485                             VR128, v4i32, v4i32, bc_v4i32, 0>, VEX_4V;
3486
3487 let ExeDomain = SSEPackedInt in {
3488   // 128-bit logical shifts.
3489   def VPSLLDQri : PDIi8<0x73, MRM7r,
3490                     (outs VR128:$dst), (ins VR128:$src1, i32i8imm:$src2),
3491                     "vpslldq\t{$src2, $src1, $dst|$dst, $src1, $src2}",
3492                     [(set VR128:$dst,
3493                       (int_x86_sse2_psll_dq_bs VR128:$src1, imm:$src2))]>,
3494                     VEX_4V;
3495   def VPSRLDQri : PDIi8<0x73, MRM3r,
3496                     (outs VR128:$dst), (ins VR128:$src1, i32i8imm:$src2),
3497                     "vpsrldq\t{$src2, $src1, $dst|$dst, $src1, $src2}",
3498                     [(set VR128:$dst,
3499                       (int_x86_sse2_psrl_dq_bs VR128:$src1, imm:$src2))]>,
3500                     VEX_4V;
3501   // PSRADQri doesn't exist in SSE[1-3].
3502 }
3503 } // Predicates = [HasAVX]
3504
3505 let Predicates = [HasAVX2] in {
3506 defm VPSLLWY : PDI_binop_rmi<0xF1, 0x71, MRM6r, "vpsllw", X86vshl, X86vshli,
3507                              VR256, v16i16, v8i16, bc_v8i16, 0>, VEX_4V;
3508 defm VPSLLDY : PDI_binop_rmi<0xF2, 0x72, MRM6r, "vpslld", X86vshl, X86vshli,
3509                              VR256, v8i32, v4i32, bc_v4i32, 0>, VEX_4V;
3510 defm VPSLLQY : PDI_binop_rmi<0xF3, 0x73, MRM6r, "vpsllq", X86vshl, X86vshli,
3511                              VR256, v4i64, v2i64, bc_v2i64, 0>, VEX_4V;
3512
3513 defm VPSRLWY : PDI_binop_rmi<0xD1, 0x71, MRM2r, "vpsrlw", X86vsrl, X86vsrli,
3514                              VR256, v16i16, v8i16, bc_v8i16, 0>, VEX_4V;
3515 defm VPSRLDY : PDI_binop_rmi<0xD2, 0x72, MRM2r, "vpsrld", X86vsrl, X86vsrli,
3516                              VR256, v8i32, v4i32, bc_v4i32, 0>, VEX_4V;
3517 defm VPSRLQY : PDI_binop_rmi<0xD3, 0x73, MRM2r, "vpsrlq", X86vsrl, X86vsrli,
3518                              VR256, v4i64, v2i64, bc_v2i64, 0>, VEX_4V;
3519
3520 defm VPSRAWY : PDI_binop_rmi<0xE1, 0x71, MRM4r, "vpsraw", X86vsra, X86vsrai,
3521                              VR256, v16i16, v8i16, bc_v8i16, 0>, VEX_4V;
3522 defm VPSRADY : PDI_binop_rmi<0xE2, 0x72, MRM4r, "vpsrad", X86vsra, X86vsrai,
3523                              VR256, v8i32, v4i32, bc_v4i32, 0>, VEX_4V;
3524
3525 let ExeDomain = SSEPackedInt in {
3526   // 256-bit logical shifts.
3527   def VPSLLDQYri : PDIi8<0x73, MRM7r,
3528                     (outs VR256:$dst), (ins VR256:$src1, i32i8imm:$src2),
3529                     "vpslldq\t{$src2, $src1, $dst|$dst, $src1, $src2}",
3530                     [(set VR256:$dst,
3531                       (int_x86_avx2_psll_dq_bs VR256:$src1, imm:$src2))]>,
3532                     VEX_4V;
3533   def VPSRLDQYri : PDIi8<0x73, MRM3r,
3534                     (outs VR256:$dst), (ins VR256:$src1, i32i8imm:$src2),
3535                     "vpsrldq\t{$src2, $src1, $dst|$dst, $src1, $src2}",
3536                     [(set VR256:$dst,
3537                       (int_x86_avx2_psrl_dq_bs VR256:$src1, imm:$src2))]>,
3538                     VEX_4V;
3539   // PSRADQYri doesn't exist in SSE[1-3].
3540 }
3541 } // Predicates = [HasAVX2]
3542
3543 let Constraints = "$src1 = $dst" in {
3544 defm PSLLW : PDI_binop_rmi<0xF1, 0x71, MRM6r, "psllw", X86vshl, X86vshli,
3545                            VR128, v8i16, v8i16, bc_v8i16>;
3546 defm PSLLD : PDI_binop_rmi<0xF2, 0x72, MRM6r, "pslld", X86vshl, X86vshli,
3547                            VR128, v4i32, v4i32, bc_v4i32>;
3548 defm PSLLQ : PDI_binop_rmi<0xF3, 0x73, MRM6r, "psllq", X86vshl, X86vshli,
3549                            VR128, v2i64, v2i64, bc_v2i64>;
3550
3551 defm PSRLW : PDI_binop_rmi<0xD1, 0x71, MRM2r, "psrlw", X86vsrl, X86vsrli,
3552                            VR128, v8i16, v8i16, bc_v8i16>;
3553 defm PSRLD : PDI_binop_rmi<0xD2, 0x72, MRM2r, "psrld", X86vsrl, X86vsrli,
3554                            VR128, v4i32, v4i32, bc_v4i32>;
3555 defm PSRLQ : PDI_binop_rmi<0xD3, 0x73, MRM2r, "psrlq", X86vsrl, X86vsrli,
3556                            VR128, v2i64, v2i64, bc_v2i64>;
3557
3558 defm PSRAW : PDI_binop_rmi<0xE1, 0x71, MRM4r, "psraw", X86vsra, X86vsrai,
3559                            VR128, v8i16, v8i16, bc_v8i16>;
3560 defm PSRAD : PDI_binop_rmi<0xE2, 0x72, MRM4r, "psrad", X86vsra, X86vsrai,
3561                            VR128, v4i32, v4i32, bc_v4i32>;
3562
3563 let ExeDomain = SSEPackedInt in {
3564   // 128-bit logical shifts.
3565   def PSLLDQri : PDIi8<0x73, MRM7r,
3566                        (outs VR128:$dst), (ins VR128:$src1, i32i8imm:$src2),
3567                        "pslldq\t{$src2, $dst|$dst, $src2}",
3568                        [(set VR128:$dst,
3569                          (int_x86_sse2_psll_dq_bs VR128:$src1, imm:$src2))]>;
3570   def PSRLDQri : PDIi8<0x73, MRM3r,
3571                        (outs VR128:$dst), (ins VR128:$src1, i32i8imm:$src2),
3572                        "psrldq\t{$src2, $dst|$dst, $src2}",
3573                        [(set VR128:$dst,
3574                          (int_x86_sse2_psrl_dq_bs VR128:$src1, imm:$src2))]>;
3575   // PSRADQri doesn't exist in SSE[1-3].
3576 }
3577 } // Constraints = "$src1 = $dst"
3578
3579 let Predicates = [HasAVX] in {
3580   def : Pat<(int_x86_sse2_psll_dq VR128:$src1, imm:$src2),
3581             (VPSLLDQri VR128:$src1, (BYTE_imm imm:$src2))>;
3582   def : Pat<(int_x86_sse2_psrl_dq VR128:$src1, imm:$src2),
3583             (VPSRLDQri VR128:$src1, (BYTE_imm imm:$src2))>;
3584   def : Pat<(v2f64 (X86fsrl VR128:$src1, i32immSExt8:$src2)),
3585             (VPSRLDQri VR128:$src1, (BYTE_imm imm:$src2))>;
3586
3587   // Shift up / down and insert zero's.
3588   def : Pat<(v2i64 (X86vshldq VR128:$src, (i8 imm:$amt))),
3589             (VPSLLDQri VR128:$src, (BYTE_imm imm:$amt))>;
3590   def : Pat<(v2i64 (X86vshrdq VR128:$src, (i8 imm:$amt))),
3591             (VPSRLDQri VR128:$src, (BYTE_imm imm:$amt))>;
3592 }
3593
3594 let Predicates = [HasAVX2] in {
3595   def : Pat<(int_x86_avx2_psll_dq VR256:$src1, imm:$src2),
3596             (VPSLLDQYri VR256:$src1, (BYTE_imm imm:$src2))>;
3597   def : Pat<(int_x86_avx2_psrl_dq VR256:$src1, imm:$src2),
3598             (VPSRLDQYri VR256:$src1, (BYTE_imm imm:$src2))>;
3599 }
3600
3601 let Predicates = [HasSSE2] in {
3602   def : Pat<(int_x86_sse2_psll_dq VR128:$src1, imm:$src2),
3603             (PSLLDQri VR128:$src1, (BYTE_imm imm:$src2))>;
3604   def : Pat<(int_x86_sse2_psrl_dq VR128:$src1, imm:$src2),
3605             (PSRLDQri VR128:$src1, (BYTE_imm imm:$src2))>;
3606   def : Pat<(v2f64 (X86fsrl VR128:$src1, i32immSExt8:$src2)),
3607             (PSRLDQri VR128:$src1, (BYTE_imm imm:$src2))>;
3608
3609   // Shift up / down and insert zero's.
3610   def : Pat<(v2i64 (X86vshldq VR128:$src, (i8 imm:$amt))),
3611             (PSLLDQri VR128:$src, (BYTE_imm imm:$amt))>;
3612   def : Pat<(v2i64 (X86vshrdq VR128:$src, (i8 imm:$amt))),
3613             (PSRLDQri VR128:$src, (BYTE_imm imm:$amt))>;
3614 }
3615
3616 //===---------------------------------------------------------------------===//
3617 // SSE2 - Packed Integer Comparison Instructions
3618 //===---------------------------------------------------------------------===//
3619
3620 let Predicates = [HasAVX] in {
3621   defm VPCMPEQB  : PDI_binop_rm<0x74, "vpcmpeqb", X86pcmpeq, v16i8,
3622                                 VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3623   defm VPCMPEQW  : PDI_binop_rm<0x75, "vpcmpeqw", X86pcmpeq, v8i16,
3624                                 VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3625   defm VPCMPEQD  : PDI_binop_rm<0x76, "vpcmpeqd", X86pcmpeq, v4i32,
3626                                 VR128, memopv2i64, i128mem, 1, 0>, VEX_4V;
3627   defm VPCMPGTB  : PDI_binop_rm<0x64, "vpcmpgtb", X86pcmpgt, v16i8,
3628                                 VR128, memopv2i64, i128mem, 0, 0>, VEX_4V;
3629   defm VPCMPGTW  : PDI_binop_rm<0x65, "vpcmpgtw", X86pcmpgt, v8i16,
3630                                 VR128, memopv2i64, i128mem, 0, 0>, VEX_4V;
3631   defm VPCMPGTD  : PDI_binop_rm<0x66, "vpcmpgtd", X86pcmpgt, v4i32,
3632                                 VR128, memopv2i64, i128mem, 0, 0>, VEX_4V;
3633 }
3634
3635 let Predicates = [HasAVX2] in {
3636   defm VPCMPEQBY : PDI_binop_rm<0x74, "vpcmpeqb", X86pcmpeq, v32i8,
3637                                 VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3638   defm VPCMPEQWY : PDI_binop_rm<0x75, "vpcmpeqw", X86pcmpeq, v16i16,
3639                                 VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3640   defm VPCMPEQDY : PDI_binop_rm<0x76, "vpcmpeqd", X86pcmpeq, v8i32,
3641                                 VR256, memopv4i64, i256mem, 1, 0>, VEX_4V;
3642   defm VPCMPGTBY : PDI_binop_rm<0x64, "vpcmpgtb", X86pcmpgt, v32i8,
3643                                 VR256, memopv4i64, i256mem, 0, 0>, VEX_4V;
3644   defm VPCMPGTWY : PDI_binop_rm<0x65, "vpcmpgtw", X86pcmpgt, v16i16,
3645                                 VR256, memopv4i64, i256mem, 0, 0>, VEX_4V;
3646   defm VPCMPGTDY : PDI_binop_rm<0x66, "vpcmpgtd", X86pcmpgt, v8i32,
3647                                 VR256, memopv4i64, i256mem, 0, 0>, VEX_4V;
3648 }
3649
3650 let Constraints = "$src1 = $dst" in {
3651   defm PCMPEQB  : PDI_binop_rm<0x74, "pcmpeqb", X86pcmpeq, v16i8,
3652                                VR128, memopv2i64, i128mem, 1>;
3653   defm PCMPEQW  : PDI_binop_rm<0x75, "pcmpeqw", X86pcmpeq, v8i16,
3654                                VR128, memopv2i64, i128mem, 1>;
3655   defm PCMPEQD  : PDI_binop_rm<0x76, "pcmpeqd", X86pcmpeq, v4i32,
3656                                VR128, memopv2i64, i128mem, 1>;
3657   defm PCMPGTB  : PDI_binop_rm<0x64, "pcmpgtb", X86pcmpgt, v16i8,
3658                                VR128, memopv2i64, i128mem>;
3659   defm PCMPGTW  : PDI_binop_rm<0x65, "pcmpgtw", X86pcmpgt, v8i16,
3660                                VR128, memopv2i64, i128mem>;
3661   defm PCMPGTD  : PDI_binop_rm<0x66, "pcmpgtd", X86pcmpgt, v4i32,
3662                                VR128, memopv2i64, i128mem>;
3663 } // Constraints = "$src1 = $dst"
3664
3665 //===---------------------------------------------------------------------===//
3666 // SSE2 - Packed Integer Pack Instructions
3667 //===---------------------------------------------------------------------===//
3668
3669 let Predicates = [HasAVX] in {
3670 defm VPACKSSWB : PDI_binop_rm_int<0x63, "vpacksswb", int_x86_sse2_packsswb_128,
3671                                   VR128, memopv2i64, i128mem, 0, 0>, VEX_4V;
3672 defm VPACKSSDW : PDI_binop_rm_int<0x6B, "vpackssdw", int_x86_sse2_packssdw_128,
3673                                   VR128, memopv2i64, i128mem, 0, 0>, VEX_4V;
3674 defm VPACKUSWB : PDI_binop_rm_int<0x67, "vpackuswb", int_x86_sse2_packuswb_128,
3675                                   VR128, memopv2i64, i128mem, 0, 0>, VEX_4V;
3676 }
3677
3678 let Predicates = [HasAVX2] in {
3679 defm VPACKSSWBY : PDI_binop_rm_int<0x63, "vpacksswb", int_x86_avx2_packsswb,
3680                                    VR256, memopv4i64, i256mem, 0, 0>, VEX_4V;
3681 defm VPACKSSDWY : PDI_binop_rm_int<0x6B, "vpackssdw", int_x86_avx2_packssdw,
3682                                    VR256, memopv4i64, i256mem, 0, 0>, VEX_4V;
3683 defm VPACKUSWBY : PDI_binop_rm_int<0x67, "vpackuswb", int_x86_avx2_packuswb,
3684                                    VR256, memopv4i64, i256mem, 0, 0>, VEX_4V;
3685 }
3686
3687 let Constraints = "$src1 = $dst" in {
3688 defm PACKSSWB : PDI_binop_rm_int<0x63, "packsswb", int_x86_sse2_packsswb_128,
3689                                  VR128, memopv2i64, i128mem>;
3690 defm PACKSSDW : PDI_binop_rm_int<0x6B, "packssdw", int_x86_sse2_packssdw_128,
3691                                  VR128, memopv2i64, i128mem>;
3692 defm PACKUSWB : PDI_binop_rm_int<0x67, "packuswb", int_x86_sse2_packuswb_128,
3693                                  VR128, memopv2i64, i128mem>;
3694 } // Constraints = "$src1 = $dst"
3695
3696 //===---------------------------------------------------------------------===//
3697 // SSE2 - Packed Integer Shuffle Instructions
3698 //===---------------------------------------------------------------------===//
3699
3700 let ExeDomain = SSEPackedInt in {
3701 multiclass sse2_pshuffle<string OpcodeStr, ValueType vt, SDNode OpNode> {
3702 def ri : Ii8<0x70, MRMSrcReg,
3703              (outs VR128:$dst), (ins VR128:$src1, i8imm:$src2),
3704              !strconcat(OpcodeStr,
3705                         "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
3706               [(set VR128:$dst, (vt (OpNode VR128:$src1, (i8 imm:$src2))))]>;
3707 def mi : Ii8<0x70, MRMSrcMem,
3708              (outs VR128:$dst), (ins i128mem:$src1, i8imm:$src2),
3709              !strconcat(OpcodeStr,
3710                         "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
3711               [(set VR128:$dst,
3712                 (vt (OpNode (bitconvert (memopv2i64 addr:$src1)),
3713                              (i8 imm:$src2))))]>;
3714 }
3715
3716 multiclass sse2_pshuffle_y<string OpcodeStr, ValueType vt, SDNode OpNode> {
3717 def Yri : Ii8<0x70, MRMSrcReg,
3718               (outs VR256:$dst), (ins VR256:$src1, i8imm:$src2),
3719               !strconcat(OpcodeStr,
3720                          "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
3721               [(set VR256:$dst, (vt (OpNode VR256:$src1, (i8 imm:$src2))))]>;
3722 def Ymi : Ii8<0x70, MRMSrcMem,
3723               (outs VR256:$dst), (ins i256mem:$src1, i8imm:$src2),
3724               !strconcat(OpcodeStr,
3725                          "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
3726               [(set VR256:$dst,
3727                 (vt (OpNode (bitconvert (memopv4i64 addr:$src1)),
3728                              (i8 imm:$src2))))]>;
3729 }
3730 } // ExeDomain = SSEPackedInt
3731
3732 let Predicates = [HasAVX] in {
3733  let AddedComplexity = 5 in
3734   defm VPSHUFD : sse2_pshuffle<"vpshufd", v4i32, X86PShufd>, TB, OpSize, VEX;
3735
3736  // SSE2 with ImmT == Imm8 and XS prefix.
3737   defm VPSHUFHW : sse2_pshuffle<"vpshufhw", v8i16, X86PShufhw>, XS, VEX;
3738
3739  // SSE2 with ImmT == Imm8 and XD prefix.
3740   defm VPSHUFLW : sse2_pshuffle<"vpshuflw", v8i16, X86PShuflw>, XD, VEX;
3741
3742  def : Pat<(v4f32 (X86PShufd (memopv4f32 addr:$src1), (i8 imm:$imm))),
3743            (VPSHUFDmi addr:$src1, imm:$imm)>;
3744  def : Pat<(v4f32 (X86PShufd VR128:$src1, (i8 imm:$imm))),
3745            (VPSHUFDri VR128:$src1, imm:$imm)>;
3746 }
3747
3748 let Predicates = [HasAVX2] in {
3749   defm VPSHUFD : sse2_pshuffle_y<"vpshufd", v8i32, X86PShufd>, TB, OpSize, VEX;
3750   defm VPSHUFHW : sse2_pshuffle_y<"vpshufhw", v16i16, X86PShufhw>, XS, VEX;
3751   defm VPSHUFLW : sse2_pshuffle_y<"vpshuflw", v16i16, X86PShuflw>, XD, VEX;
3752 }
3753
3754 let Predicates = [HasSSE2] in {
3755  let AddedComplexity = 5 in
3756   defm PSHUFD : sse2_pshuffle<"pshufd", v4i32, X86PShufd>, TB, OpSize;
3757
3758  // SSE2 with ImmT == Imm8 and XS prefix.
3759   defm PSHUFHW : sse2_pshuffle<"pshufhw", v8i16, X86PShufhw>, XS;
3760
3761  // SSE2 with ImmT == Imm8 and XD prefix.
3762   defm PSHUFLW : sse2_pshuffle<"pshuflw", v8i16, X86PShuflw>, XD;
3763
3764  def : Pat<(v4f32 (X86PShufd (memopv4f32 addr:$src1), (i8 imm:$imm))),
3765            (PSHUFDmi addr:$src1, imm:$imm)>;
3766  def : Pat<(v4f32 (X86PShufd VR128:$src1, (i8 imm:$imm))),
3767            (PSHUFDri VR128:$src1, imm:$imm)>;
3768 }
3769
3770 //===---------------------------------------------------------------------===//
3771 // SSE2 - Packed Integer Unpack Instructions
3772 //===---------------------------------------------------------------------===//
3773
3774 let ExeDomain = SSEPackedInt in {
3775 multiclass sse2_unpack<bits<8> opc, string OpcodeStr, ValueType vt,
3776                        SDNode OpNode, PatFrag bc_frag, bit Is2Addr = 1> {
3777   def rr : PDI<opc, MRMSrcReg,
3778       (outs VR128:$dst), (ins VR128:$src1, VR128:$src2),
3779       !if(Is2Addr,
3780           !strconcat(OpcodeStr,"\t{$src2, $dst|$dst, $src2}"),
3781           !strconcat(OpcodeStr,"\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
3782       [(set VR128:$dst, (vt (OpNode VR128:$src1, VR128:$src2)))]>;
3783   def rm : PDI<opc, MRMSrcMem,
3784       (outs VR128:$dst), (ins VR128:$src1, i128mem:$src2),
3785       !if(Is2Addr,
3786           !strconcat(OpcodeStr,"\t{$src2, $dst|$dst, $src2}"),
3787           !strconcat(OpcodeStr,"\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
3788       [(set VR128:$dst, (OpNode VR128:$src1,
3789                                   (bc_frag (memopv2i64
3790                                                addr:$src2))))]>;
3791 }
3792
3793 multiclass sse2_unpack_y<bits<8> opc, string OpcodeStr, ValueType vt,
3794                          SDNode OpNode, PatFrag bc_frag> {
3795   def Yrr : PDI<opc, MRMSrcReg,
3796       (outs VR256:$dst), (ins VR256:$src1, VR256:$src2),
3797       !strconcat(OpcodeStr,"\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
3798       [(set VR256:$dst, (vt (OpNode VR256:$src1, VR256:$src2)))]>;
3799   def Yrm : PDI<opc, MRMSrcMem,
3800       (outs VR256:$dst), (ins VR256:$src1, i256mem:$src2),
3801       !strconcat(OpcodeStr,"\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
3802       [(set VR256:$dst, (OpNode VR256:$src1,
3803                                   (bc_frag (memopv4i64 addr:$src2))))]>;
3804 }
3805
3806 let Predicates = [HasAVX] in {
3807   defm VPUNPCKLBW  : sse2_unpack<0x60, "vpunpcklbw", v16i8, X86Unpckl,
3808                                  bc_v16i8, 0>, VEX_4V;
3809   defm VPUNPCKLWD  : sse2_unpack<0x61, "vpunpcklwd", v8i16, X86Unpckl,
3810                                  bc_v8i16, 0>, VEX_4V;
3811   defm VPUNPCKLDQ  : sse2_unpack<0x62, "vpunpckldq", v4i32, X86Unpckl,
3812                                  bc_v4i32, 0>, VEX_4V;
3813   defm VPUNPCKLQDQ : sse2_unpack<0x6C, "vpunpcklqdq", v2i64, X86Unpckl,
3814                                  bc_v2i64, 0>, VEX_4V;
3815
3816   defm VPUNPCKHBW  : sse2_unpack<0x68, "vpunpckhbw", v16i8, X86Unpckh,
3817                                  bc_v16i8, 0>, VEX_4V;
3818   defm VPUNPCKHWD  : sse2_unpack<0x69, "vpunpckhwd", v8i16, X86Unpckh,
3819                                  bc_v8i16, 0>, VEX_4V;
3820   defm VPUNPCKHDQ  : sse2_unpack<0x6A, "vpunpckhdq", v4i32, X86Unpckh,
3821                                  bc_v4i32, 0>, VEX_4V;
3822   defm VPUNPCKHQDQ : sse2_unpack<0x6D, "vpunpckhqdq", v2i64, X86Unpckh,
3823                                  bc_v2i64, 0>, VEX_4V;
3824 }
3825
3826 let Predicates = [HasAVX2] in {
3827   defm VPUNPCKLBW  : sse2_unpack_y<0x60, "vpunpcklbw", v32i8, X86Unpckl,
3828                                    bc_v32i8>, VEX_4V;
3829   defm VPUNPCKLWD  : sse2_unpack_y<0x61, "vpunpcklwd", v16i16, X86Unpckl,
3830                                    bc_v16i16>, VEX_4V;
3831   defm VPUNPCKLDQ  : sse2_unpack_y<0x62, "vpunpckldq", v8i32, X86Unpckl,
3832                                    bc_v8i32>, VEX_4V;
3833   defm VPUNPCKLQDQ : sse2_unpack_y<0x6C, "vpunpcklqdq", v4i64, X86Unpckl,
3834                                    bc_v4i64>, VEX_4V;
3835
3836   defm VPUNPCKHBW  : sse2_unpack_y<0x68, "vpunpckhbw", v32i8, X86Unpckh,
3837                                    bc_v32i8>, VEX_4V;
3838   defm VPUNPCKHWD  : sse2_unpack_y<0x69, "vpunpckhwd", v16i16, X86Unpckh,
3839                                    bc_v16i16>, VEX_4V;
3840   defm VPUNPCKHDQ  : sse2_unpack_y<0x6A, "vpunpckhdq", v8i32, X86Unpckh,
3841                                    bc_v8i32>, VEX_4V;
3842   defm VPUNPCKHQDQ : sse2_unpack_y<0x6D, "vpunpckhqdq", v4i64, X86Unpckh,
3843                                    bc_v4i64>, VEX_4V;
3844 }
3845
3846 let Constraints = "$src1 = $dst" in {
3847   defm PUNPCKLBW  : sse2_unpack<0x60, "punpcklbw", v16i8, X86Unpckl,
3848                                 bc_v16i8>;
3849   defm PUNPCKLWD  : sse2_unpack<0x61, "punpcklwd", v8i16, X86Unpckl,
3850                                 bc_v8i16>;
3851   defm PUNPCKLDQ  : sse2_unpack<0x62, "punpckldq", v4i32, X86Unpckl,
3852                                 bc_v4i32>;
3853   defm PUNPCKLQDQ : sse2_unpack<0x6C, "punpcklqdq", v2i64, X86Unpckl,
3854                                 bc_v2i64>;
3855
3856   defm PUNPCKHBW  : sse2_unpack<0x68, "punpckhbw", v16i8, X86Unpckh,
3857                                 bc_v16i8>;
3858   defm PUNPCKHWD  : sse2_unpack<0x69, "punpckhwd", v8i16, X86Unpckh,
3859                                 bc_v8i16>;
3860   defm PUNPCKHDQ  : sse2_unpack<0x6A, "punpckhdq", v4i32, X86Unpckh,
3861                                 bc_v4i32>;
3862   defm PUNPCKHQDQ : sse2_unpack<0x6D, "punpckhqdq", v2i64, X86Unpckh,
3863                                 bc_v2i64>;
3864 }
3865 } // ExeDomain = SSEPackedInt
3866
3867 // Patterns for using AVX1 instructions with integer vectors
3868 // Here to give AVX2 priority
3869 let Predicates = [HasAVX] in {
3870   def : Pat<(v8i32 (X86Unpckl VR256:$src1, (bc_v8i32 (memopv4i64 addr:$src2)))),
3871             (VUNPCKLPSYrm VR256:$src1, addr:$src2)>;
3872   def : Pat<(v8i32 (X86Unpckl VR256:$src1, VR256:$src2)),
3873             (VUNPCKLPSYrr VR256:$src1, VR256:$src2)>;
3874   def : Pat<(v8i32 (X86Unpckh VR256:$src1, (bc_v8i32 (memopv4i64 addr:$src2)))),
3875             (VUNPCKHPSYrm VR256:$src1, addr:$src2)>;
3876   def : Pat<(v8i32 (X86Unpckh VR256:$src1, VR256:$src2)),
3877             (VUNPCKHPSYrr VR256:$src1, VR256:$src2)>;
3878
3879   def : Pat<(v4i64 (X86Unpckl VR256:$src1, (memopv4i64 addr:$src2))),
3880             (VUNPCKLPDYrm VR256:$src1, addr:$src2)>;
3881   def : Pat<(v4i64 (X86Unpckl VR256:$src1, VR256:$src2)),
3882             (VUNPCKLPDYrr VR256:$src1, VR256:$src2)>;
3883   def : Pat<(v4i64 (X86Unpckh VR256:$src1, (memopv4i64 addr:$src2))),
3884             (VUNPCKHPDYrm VR256:$src1, addr:$src2)>;
3885   def : Pat<(v4i64 (X86Unpckh VR256:$src1, VR256:$src2)),
3886             (VUNPCKHPDYrr VR256:$src1, VR256:$src2)>;
3887 }
3888
3889 //===---------------------------------------------------------------------===//
3890 // SSE2 - Packed Integer Extract and Insert
3891 //===---------------------------------------------------------------------===//
3892
3893 let ExeDomain = SSEPackedInt in {
3894 multiclass sse2_pinsrw<bit Is2Addr = 1> {
3895   def rri : Ii8<0xC4, MRMSrcReg,
3896        (outs VR128:$dst), (ins VR128:$src1,
3897         GR32:$src2, i32i8imm:$src3),
3898        !if(Is2Addr,
3899            "pinsrw\t{$src3, $src2, $dst|$dst, $src2, $src3}",
3900            "vpinsrw\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
3901        [(set VR128:$dst,
3902          (X86pinsrw VR128:$src1, GR32:$src2, imm:$src3))]>;
3903   def rmi : Ii8<0xC4, MRMSrcMem,
3904                        (outs VR128:$dst), (ins VR128:$src1,
3905                         i16mem:$src2, i32i8imm:$src3),
3906        !if(Is2Addr,
3907            "pinsrw\t{$src3, $src2, $dst|$dst, $src2, $src3}",
3908            "vpinsrw\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
3909        [(set VR128:$dst,
3910          (X86pinsrw VR128:$src1, (extloadi16 addr:$src2),
3911                     imm:$src3))]>;
3912 }
3913
3914 // Extract
3915 let Predicates = [HasAVX] in
3916 def VPEXTRWri : Ii8<0xC5, MRMSrcReg,
3917                     (outs GR32:$dst), (ins VR128:$src1, i32i8imm:$src2),
3918                     "vpextrw\t{$src2, $src1, $dst|$dst, $src1, $src2}",
3919                     [(set GR32:$dst, (X86pextrw (v8i16 VR128:$src1),
3920                                                 imm:$src2))]>, TB, OpSize, VEX;
3921 def PEXTRWri : PDIi8<0xC5, MRMSrcReg,
3922                     (outs GR32:$dst), (ins VR128:$src1, i32i8imm:$src2),
3923                     "pextrw\t{$src2, $src1, $dst|$dst, $src1, $src2}",
3924                     [(set GR32:$dst, (X86pextrw (v8i16 VR128:$src1),
3925                                                 imm:$src2))]>;
3926
3927 // Insert
3928 let Predicates = [HasAVX] in {
3929   defm VPINSRW : sse2_pinsrw<0>, TB, OpSize, VEX_4V;
3930   def  VPINSRWrr64i : Ii8<0xC4, MRMSrcReg, (outs VR128:$dst),
3931        (ins VR128:$src1, GR64:$src2, i32i8imm:$src3),
3932        "vpinsrw\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
3933        []>, TB, OpSize, VEX_4V;
3934 }
3935
3936 let Constraints = "$src1 = $dst" in
3937   defm PINSRW : sse2_pinsrw, TB, OpSize, Requires<[HasSSE2]>;
3938
3939 } // ExeDomain = SSEPackedInt
3940
3941 //===---------------------------------------------------------------------===//
3942 // SSE2 - Packed Mask Creation
3943 //===---------------------------------------------------------------------===//
3944
3945 let ExeDomain = SSEPackedInt in {
3946
3947 def VPMOVMSKBrr  : VPDI<0xD7, MRMSrcReg, (outs GR32:$dst), (ins VR128:$src),
3948            "pmovmskb\t{$src, $dst|$dst, $src}",
3949            [(set GR32:$dst, (int_x86_sse2_pmovmskb_128 VR128:$src))]>, VEX;
3950 def VPMOVMSKBr64r : VPDI<0xD7, MRMSrcReg, (outs GR64:$dst), (ins VR128:$src),
3951            "pmovmskb\t{$src, $dst|$dst, $src}", []>, VEX;
3952
3953 let Predicates = [HasAVX2] in {
3954 def VPMOVMSKBYrr  : VPDI<0xD7, MRMSrcReg, (outs GR32:$dst), (ins VR256:$src),
3955            "pmovmskb\t{$src, $dst|$dst, $src}",
3956            [(set GR32:$dst, (int_x86_avx2_pmovmskb VR256:$src))]>, VEX;
3957 def VPMOVMSKBYr64r : VPDI<0xD7, MRMSrcReg, (outs GR64:$dst), (ins VR256:$src),
3958            "pmovmskb\t{$src, $dst|$dst, $src}", []>, VEX;
3959 }
3960
3961 def PMOVMSKBrr : PDI<0xD7, MRMSrcReg, (outs GR32:$dst), (ins VR128:$src),
3962            "pmovmskb\t{$src, $dst|$dst, $src}",
3963            [(set GR32:$dst, (int_x86_sse2_pmovmskb_128 VR128:$src))]>;
3964
3965 } // ExeDomain = SSEPackedInt
3966
3967 //===---------------------------------------------------------------------===//
3968 // SSE2 - Conditional Store
3969 //===---------------------------------------------------------------------===//
3970
3971 let ExeDomain = SSEPackedInt in {
3972
3973 let Uses = [EDI] in
3974 def VMASKMOVDQU : VPDI<0xF7, MRMSrcReg, (outs),
3975            (ins VR128:$src, VR128:$mask),
3976            "maskmovdqu\t{$mask, $src|$src, $mask}",
3977            [(int_x86_sse2_maskmov_dqu VR128:$src, VR128:$mask, EDI)]>, VEX;
3978 let Uses = [RDI] in
3979 def VMASKMOVDQU64 : VPDI<0xF7, MRMSrcReg, (outs),
3980            (ins VR128:$src, VR128:$mask),
3981            "maskmovdqu\t{$mask, $src|$src, $mask}",
3982            [(int_x86_sse2_maskmov_dqu VR128:$src, VR128:$mask, RDI)]>, VEX;
3983
3984 let Uses = [EDI] in
3985 def MASKMOVDQU : PDI<0xF7, MRMSrcReg, (outs), (ins VR128:$src, VR128:$mask),
3986            "maskmovdqu\t{$mask, $src|$src, $mask}",
3987            [(int_x86_sse2_maskmov_dqu VR128:$src, VR128:$mask, EDI)]>;
3988 let Uses = [RDI] in
3989 def MASKMOVDQU64 : PDI<0xF7, MRMSrcReg, (outs), (ins VR128:$src, VR128:$mask),
3990            "maskmovdqu\t{$mask, $src|$src, $mask}",
3991            [(int_x86_sse2_maskmov_dqu VR128:$src, VR128:$mask, RDI)]>;
3992
3993 } // ExeDomain = SSEPackedInt
3994
3995 //===---------------------------------------------------------------------===//
3996 // SSE2 - Move Doubleword
3997 //===---------------------------------------------------------------------===//
3998
3999 //===---------------------------------------------------------------------===//
4000 // Move Int Doubleword to Packed Double Int
4001 //
4002 def VMOVDI2PDIrr : VPDI<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR32:$src),
4003                       "movd\t{$src, $dst|$dst, $src}",
4004                       [(set VR128:$dst,
4005                         (v4i32 (scalar_to_vector GR32:$src)))]>, VEX;
4006 def VMOVDI2PDIrm : VPDI<0x6E, MRMSrcMem, (outs VR128:$dst), (ins i32mem:$src),
4007                       "movd\t{$src, $dst|$dst, $src}",
4008                       [(set VR128:$dst,
4009                         (v4i32 (scalar_to_vector (loadi32 addr:$src))))]>,
4010                       VEX;
4011 def VMOV64toPQIrr : VRPDI<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR64:$src),
4012                         "mov{d|q}\t{$src, $dst|$dst, $src}",
4013                         [(set VR128:$dst,
4014                           (v2i64 (scalar_to_vector GR64:$src)))]>, VEX;
4015 def VMOV64toSDrr : VRPDI<0x6E, MRMSrcReg, (outs FR64:$dst), (ins GR64:$src),
4016                        "mov{d|q}\t{$src, $dst|$dst, $src}",
4017                        [(set FR64:$dst, (bitconvert GR64:$src))]>, VEX;
4018
4019 def MOVDI2PDIrr : PDI<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR32:$src),
4020                       "movd\t{$src, $dst|$dst, $src}",
4021                       [(set VR128:$dst,
4022                         (v4i32 (scalar_to_vector GR32:$src)))]>;
4023 def MOVDI2PDIrm : PDI<0x6E, MRMSrcMem, (outs VR128:$dst), (ins i32mem:$src),
4024                       "movd\t{$src, $dst|$dst, $src}",
4025                       [(set VR128:$dst,
4026                         (v4i32 (scalar_to_vector (loadi32 addr:$src))))]>;
4027 def MOV64toPQIrr : RPDI<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR64:$src),
4028                         "mov{d|q}\t{$src, $dst|$dst, $src}",
4029                         [(set VR128:$dst,
4030                           (v2i64 (scalar_to_vector GR64:$src)))]>;
4031 def MOV64toSDrr : RPDI<0x6E, MRMSrcReg, (outs FR64:$dst), (ins GR64:$src),
4032                        "mov{d|q}\t{$src, $dst|$dst, $src}",
4033                        [(set FR64:$dst, (bitconvert GR64:$src))]>;
4034
4035 //===---------------------------------------------------------------------===//
4036 // Move Int Doubleword to Single Scalar
4037 //
4038 def VMOVDI2SSrr  : VPDI<0x6E, MRMSrcReg, (outs FR32:$dst), (ins GR32:$src),
4039                       "movd\t{$src, $dst|$dst, $src}",
4040                       [(set FR32:$dst, (bitconvert GR32:$src))]>, VEX;
4041
4042 def VMOVDI2SSrm  : VPDI<0x6E, MRMSrcMem, (outs FR32:$dst), (ins i32mem:$src),
4043                       "movd\t{$src, $dst|$dst, $src}",
4044                       [(set FR32:$dst, (bitconvert (loadi32 addr:$src)))]>,
4045                       VEX;
4046 def MOVDI2SSrr  : PDI<0x6E, MRMSrcReg, (outs FR32:$dst), (ins GR32:$src),
4047                       "movd\t{$src, $dst|$dst, $src}",
4048                       [(set FR32:$dst, (bitconvert GR32:$src))]>;
4049
4050 def MOVDI2SSrm  : PDI<0x6E, MRMSrcMem, (outs FR32:$dst), (ins i32mem:$src),
4051                       "movd\t{$src, $dst|$dst, $src}",
4052                       [(set FR32:$dst, (bitconvert (loadi32 addr:$src)))]>;
4053
4054 //===---------------------------------------------------------------------===//
4055 // Move Packed Doubleword Int to Packed Double Int
4056 //
4057 def VMOVPDI2DIrr  : VPDI<0x7E, MRMDestReg, (outs GR32:$dst), (ins VR128:$src),
4058                        "movd\t{$src, $dst|$dst, $src}",
4059                        [(set GR32:$dst, (vector_extract (v4i32 VR128:$src),
4060                                         (iPTR 0)))]>, VEX;
4061 def VMOVPDI2DImr  : VPDI<0x7E, MRMDestMem, (outs),
4062                        (ins i32mem:$dst, VR128:$src),
4063                        "movd\t{$src, $dst|$dst, $src}",
4064                        [(store (i32 (vector_extract (v4i32 VR128:$src),
4065                                      (iPTR 0))), addr:$dst)]>, VEX;
4066 def MOVPDI2DIrr  : PDI<0x7E, MRMDestReg, (outs GR32:$dst), (ins VR128:$src),
4067                        "movd\t{$src, $dst|$dst, $src}",
4068                        [(set GR32:$dst, (vector_extract (v4i32 VR128:$src),
4069                                         (iPTR 0)))]>;
4070 def MOVPDI2DImr  : PDI<0x7E, MRMDestMem, (outs), (ins i32mem:$dst, VR128:$src),
4071                        "movd\t{$src, $dst|$dst, $src}",
4072                        [(store (i32 (vector_extract (v4i32 VR128:$src),
4073                                      (iPTR 0))), addr:$dst)]>;
4074
4075 //===---------------------------------------------------------------------===//
4076 // Move Packed Doubleword Int first element to Doubleword Int
4077 //
4078 def VMOVPQIto64rr : I<0x7E, MRMDestReg, (outs GR64:$dst), (ins VR128:$src),
4079                           "mov{d|q}\t{$src, $dst|$dst, $src}",
4080                           [(set GR64:$dst, (vector_extract (v2i64 VR128:$src),
4081                                                            (iPTR 0)))]>,
4082                       TB, OpSize, VEX, VEX_W, Requires<[HasAVX, In64BitMode]>;
4083
4084 def MOVPQIto64rr : RPDI<0x7E, MRMDestReg, (outs GR64:$dst), (ins VR128:$src),
4085                         "mov{d|q}\t{$src, $dst|$dst, $src}",
4086                         [(set GR64:$dst, (vector_extract (v2i64 VR128:$src),
4087                                                          (iPTR 0)))]>;
4088
4089 //===---------------------------------------------------------------------===//
4090 // Bitcast FR64 <-> GR64
4091 //
4092 let Predicates = [HasAVX] in
4093 def VMOV64toSDrm : S3SI<0x7E, MRMSrcMem, (outs FR64:$dst), (ins i64mem:$src),
4094                         "vmovq\t{$src, $dst|$dst, $src}",
4095                         [(set FR64:$dst, (bitconvert (loadi64 addr:$src)))]>,
4096                         VEX;
4097 def VMOVSDto64rr : VRPDI<0x7E, MRMDestReg, (outs GR64:$dst), (ins FR64:$src),
4098                          "mov{d|q}\t{$src, $dst|$dst, $src}",
4099                          [(set GR64:$dst, (bitconvert FR64:$src))]>, VEX;
4100 def VMOVSDto64mr : VRPDI<0x7E, MRMDestMem, (outs), (ins i64mem:$dst, FR64:$src),
4101                          "movq\t{$src, $dst|$dst, $src}",
4102                          [(store (i64 (bitconvert FR64:$src)), addr:$dst)]>,
4103                          VEX;
4104
4105 def MOV64toSDrm : S3SI<0x7E, MRMSrcMem, (outs FR64:$dst), (ins i64mem:$src),
4106                        "movq\t{$src, $dst|$dst, $src}",
4107                        [(set FR64:$dst, (bitconvert (loadi64 addr:$src)))]>;
4108 def MOVSDto64rr : RPDI<0x7E, MRMDestReg, (outs GR64:$dst), (ins FR64:$src),
4109                        "mov{d|q}\t{$src, $dst|$dst, $src}",
4110                        [(set GR64:$dst, (bitconvert FR64:$src))]>;
4111 def MOVSDto64mr : RPDI<0x7E, MRMDestMem, (outs), (ins i64mem:$dst, FR64:$src),
4112                        "movq\t{$src, $dst|$dst, $src}",
4113                        [(store (i64 (bitconvert FR64:$src)), addr:$dst)]>;
4114
4115 //===---------------------------------------------------------------------===//
4116 // Move Scalar Single to Double Int
4117 //
4118 def VMOVSS2DIrr  : VPDI<0x7E, MRMDestReg, (outs GR32:$dst), (ins FR32:$src),
4119                       "movd\t{$src, $dst|$dst, $src}",
4120                       [(set GR32:$dst, (bitconvert FR32:$src))]>, VEX;
4121 def VMOVSS2DImr  : VPDI<0x7E, MRMDestMem, (outs), (ins i32mem:$dst, FR32:$src),
4122                       "movd\t{$src, $dst|$dst, $src}",
4123                       [(store (i32 (bitconvert FR32:$src)), addr:$dst)]>, VEX;
4124 def MOVSS2DIrr  : PDI<0x7E, MRMDestReg, (outs GR32:$dst), (ins FR32:$src),
4125                       "movd\t{$src, $dst|$dst, $src}",
4126                       [(set GR32:$dst, (bitconvert FR32:$src))]>;
4127 def MOVSS2DImr  : PDI<0x7E, MRMDestMem, (outs), (ins i32mem:$dst, FR32:$src),
4128                       "movd\t{$src, $dst|$dst, $src}",
4129                       [(store (i32 (bitconvert FR32:$src)), addr:$dst)]>;
4130
4131 //===---------------------------------------------------------------------===//
4132 // Patterns and instructions to describe movd/movq to XMM register zero-extends
4133 //
4134 let AddedComplexity = 15 in {
4135 def VMOVZDI2PDIrr : VPDI<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR32:$src),
4136                        "movd\t{$src, $dst|$dst, $src}",
4137                        [(set VR128:$dst, (v4i32 (X86vzmovl
4138                                       (v4i32 (scalar_to_vector GR32:$src)))))]>,
4139                                       VEX;
4140 def VMOVZQI2PQIrr : VPDI<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR64:$src),
4141                        "mov{d|q}\t{$src, $dst|$dst, $src}", // X86-64 only
4142                        [(set VR128:$dst, (v2i64 (X86vzmovl
4143                                       (v2i64 (scalar_to_vector GR64:$src)))))]>,
4144                                       VEX, VEX_W;
4145 }
4146 let AddedComplexity = 15 in {
4147 def MOVZDI2PDIrr : PDI<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR32:$src),
4148                        "movd\t{$src, $dst|$dst, $src}",
4149                        [(set VR128:$dst, (v4i32 (X86vzmovl
4150                                       (v4i32 (scalar_to_vector GR32:$src)))))]>;
4151 def MOVZQI2PQIrr : RPDI<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR64:$src),
4152                        "mov{d|q}\t{$src, $dst|$dst, $src}", // X86-64 only
4153                        [(set VR128:$dst, (v2i64 (X86vzmovl
4154                                       (v2i64 (scalar_to_vector GR64:$src)))))]>;
4155 }
4156
4157 let AddedComplexity = 20 in {
4158 def VMOVZDI2PDIrm : VPDI<0x6E, MRMSrcMem, (outs VR128:$dst), (ins i32mem:$src),
4159                        "movd\t{$src, $dst|$dst, $src}",
4160                        [(set VR128:$dst,
4161                          (v4i32 (X86vzmovl (v4i32 (scalar_to_vector
4162                                                    (loadi32 addr:$src))))))]>,
4163                                                    VEX;
4164 def MOVZDI2PDIrm : PDI<0x6E, MRMSrcMem, (outs VR128:$dst), (ins i32mem:$src),
4165                        "movd\t{$src, $dst|$dst, $src}",
4166                        [(set VR128:$dst,
4167                          (v4i32 (X86vzmovl (v4i32 (scalar_to_vector
4168                                                    (loadi32 addr:$src))))))]>;
4169 }
4170
4171 let Predicates = [HasAVX] in {
4172   // AVX 128-bit movd/movq instruction write zeros in the high 128-bit part.
4173   let AddedComplexity = 20 in {
4174     def : Pat<(v4i32 (X86vzmovl (bc_v4i32 (loadv4f32 addr:$src)))),
4175               (VMOVZDI2PDIrm addr:$src)>;
4176     def : Pat<(v4i32 (X86vzmovl (bc_v4i32 (loadv2i64 addr:$src)))),
4177               (VMOVZDI2PDIrm addr:$src)>;
4178   }
4179   // Use regular 128-bit instructions to match 256-bit scalar_to_vec+zext.
4180   def : Pat<(v8i32 (X86vzmovl (insert_subvector undef,
4181                                 (v4i32 (scalar_to_vector GR32:$src)),(i32 0)))),
4182             (SUBREG_TO_REG (i32 0), (VMOVZDI2PDIrr GR32:$src), sub_xmm)>;
4183   def : Pat<(v4i64 (X86vzmovl (insert_subvector undef,
4184                                 (v2i64 (scalar_to_vector GR64:$src)),(i32 0)))),
4185             (SUBREG_TO_REG (i64 0), (VMOVZQI2PQIrr GR64:$src), sub_xmm)>;
4186 }
4187
4188 let Predicates = [HasSSE2], AddedComplexity = 20 in {
4189   def : Pat<(v4i32 (X86vzmovl (bc_v4i32 (loadv4f32 addr:$src)))),
4190             (MOVZDI2PDIrm addr:$src)>;
4191   def : Pat<(v4i32 (X86vzmovl (bc_v4i32 (loadv2i64 addr:$src)))),
4192             (MOVZDI2PDIrm addr:$src)>;
4193 }
4194
4195 // These are the correct encodings of the instructions so that we know how to
4196 // read correct assembly, even though we continue to emit the wrong ones for
4197 // compatibility with Darwin's buggy assembler.
4198 def : InstAlias<"movq\t{$src, $dst|$dst, $src}",
4199                 (MOV64toPQIrr VR128:$dst, GR64:$src), 0>;
4200 def : InstAlias<"movq\t{$src, $dst|$dst, $src}",
4201                 (MOV64toSDrr FR64:$dst, GR64:$src), 0>;
4202 def : InstAlias<"movq\t{$src, $dst|$dst, $src}",
4203                 (MOVPQIto64rr GR64:$dst, VR128:$src), 0>;
4204 def : InstAlias<"movq\t{$src, $dst|$dst, $src}",
4205                 (MOVSDto64rr GR64:$dst, FR64:$src), 0>;
4206 def : InstAlias<"movq\t{$src, $dst|$dst, $src}",
4207                 (VMOVZQI2PQIrr VR128:$dst, GR64:$src), 0>;
4208 def : InstAlias<"movq\t{$src, $dst|$dst, $src}",
4209                 (MOVZQI2PQIrr VR128:$dst, GR64:$src), 0>;
4210
4211 //===---------------------------------------------------------------------===//
4212 // SSE2 - Move Quadword
4213 //===---------------------------------------------------------------------===//
4214
4215 //===---------------------------------------------------------------------===//
4216 // Move Quadword Int to Packed Quadword Int
4217 //
4218 def VMOVQI2PQIrm : I<0x7E, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
4219                     "vmovq\t{$src, $dst|$dst, $src}",
4220                     [(set VR128:$dst,
4221                       (v2i64 (scalar_to_vector (loadi64 addr:$src))))]>, XS,
4222                     VEX, Requires<[HasAVX]>;
4223 def MOVQI2PQIrm : I<0x7E, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
4224                     "movq\t{$src, $dst|$dst, $src}",
4225                     [(set VR128:$dst,
4226                       (v2i64 (scalar_to_vector (loadi64 addr:$src))))]>, XS,
4227                     Requires<[HasSSE2]>; // SSE2 instruction with XS Prefix
4228
4229 //===---------------------------------------------------------------------===//
4230 // Move Packed Quadword Int to Quadword Int
4231 //
4232 def VMOVPQI2QImr : VPDI<0xD6, MRMDestMem, (outs), (ins i64mem:$dst, VR128:$src),
4233                       "movq\t{$src, $dst|$dst, $src}",
4234                       [(store (i64 (vector_extract (v2i64 VR128:$src),
4235                                     (iPTR 0))), addr:$dst)]>, VEX;
4236 def MOVPQI2QImr : PDI<0xD6, MRMDestMem, (outs), (ins i64mem:$dst, VR128:$src),
4237                       "movq\t{$src, $dst|$dst, $src}",
4238                       [(store (i64 (vector_extract (v2i64 VR128:$src),
4239                                     (iPTR 0))), addr:$dst)]>;
4240
4241 //===---------------------------------------------------------------------===//
4242 // Store / copy lower 64-bits of a XMM register.
4243 //
4244 def VMOVLQ128mr : VPDI<0xD6, MRMDestMem, (outs), (ins i64mem:$dst, VR128:$src),
4245                      "movq\t{$src, $dst|$dst, $src}",
4246                      [(int_x86_sse2_storel_dq addr:$dst, VR128:$src)]>, VEX;
4247 def MOVLQ128mr : PDI<0xD6, MRMDestMem, (outs), (ins i64mem:$dst, VR128:$src),
4248                      "movq\t{$src, $dst|$dst, $src}",
4249                      [(int_x86_sse2_storel_dq addr:$dst, VR128:$src)]>;
4250
4251 let AddedComplexity = 20 in
4252 def VMOVZQI2PQIrm : I<0x7E, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
4253                      "vmovq\t{$src, $dst|$dst, $src}",
4254                      [(set VR128:$dst,
4255                        (v2i64 (X86vzmovl (v2i64 (scalar_to_vector
4256                                                  (loadi64 addr:$src))))))]>,
4257                      XS, VEX, Requires<[HasAVX]>;
4258
4259 let AddedComplexity = 20 in
4260 def MOVZQI2PQIrm : I<0x7E, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
4261                      "movq\t{$src, $dst|$dst, $src}",
4262                      [(set VR128:$dst,
4263                        (v2i64 (X86vzmovl (v2i64 (scalar_to_vector
4264                                                  (loadi64 addr:$src))))))]>,
4265                      XS, Requires<[HasSSE2]>;
4266
4267 let Predicates = [HasAVX], AddedComplexity = 20 in {
4268   def : Pat<(v2i64 (X86vzmovl (loadv2i64 addr:$src))),
4269             (VMOVZQI2PQIrm addr:$src)>;
4270   def : Pat<(v2i64 (X86vzmovl (bc_v2i64 (loadv4f32 addr:$src)))),
4271             (VMOVZQI2PQIrm addr:$src)>;
4272   def : Pat<(v2i64 (X86vzload addr:$src)),
4273             (VMOVZQI2PQIrm addr:$src)>;
4274 }
4275
4276 let Predicates = [HasSSE2], AddedComplexity = 20 in {
4277   def : Pat<(v2i64 (X86vzmovl (loadv2i64 addr:$src))),
4278             (MOVZQI2PQIrm addr:$src)>;
4279   def : Pat<(v2i64 (X86vzmovl (bc_v2i64 (loadv4f32 addr:$src)))),
4280             (MOVZQI2PQIrm addr:$src)>;
4281   def : Pat<(v2i64 (X86vzload addr:$src)), (MOVZQI2PQIrm addr:$src)>;
4282 }
4283
4284 let Predicates = [HasAVX] in {
4285 def : Pat<(v4i64 (X86vzload addr:$src)),
4286           (SUBREG_TO_REG (i32 0), (VMOVAPSrm addr:$src), sub_xmm)>;
4287 }
4288
4289 //===---------------------------------------------------------------------===//
4290 // Moving from XMM to XMM and clear upper 64 bits. Note, there is a bug in
4291 // IA32 document. movq xmm1, xmm2 does clear the high bits.
4292 //
4293 let AddedComplexity = 15 in
4294 def VMOVZPQILo2PQIrr : I<0x7E, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
4295                         "vmovq\t{$src, $dst|$dst, $src}",
4296                     [(set VR128:$dst, (v2i64 (X86vzmovl (v2i64 VR128:$src))))]>,
4297                       XS, VEX, Requires<[HasAVX]>;
4298 let AddedComplexity = 15 in
4299 def MOVZPQILo2PQIrr : I<0x7E, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
4300                         "movq\t{$src, $dst|$dst, $src}",
4301                     [(set VR128:$dst, (v2i64 (X86vzmovl (v2i64 VR128:$src))))]>,
4302                       XS, Requires<[HasSSE2]>;
4303
4304 let AddedComplexity = 20 in
4305 def VMOVZPQILo2PQIrm : I<0x7E, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
4306                         "vmovq\t{$src, $dst|$dst, $src}",
4307                     [(set VR128:$dst, (v2i64 (X86vzmovl
4308                                              (loadv2i64 addr:$src))))]>,
4309                       XS, VEX, Requires<[HasAVX]>;
4310 let AddedComplexity = 20 in {
4311 def MOVZPQILo2PQIrm : I<0x7E, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
4312                         "movq\t{$src, $dst|$dst, $src}",
4313                     [(set VR128:$dst, (v2i64 (X86vzmovl
4314                                              (loadv2i64 addr:$src))))]>,
4315                       XS, Requires<[HasSSE2]>;
4316 }
4317
4318 let AddedComplexity = 20 in {
4319   let Predicates = [HasAVX] in {
4320     def : Pat<(v2i64 (X86vzmovl (loadv2i64 addr:$src))),
4321               (VMOVZPQILo2PQIrm addr:$src)>;
4322     def : Pat<(v2f64 (X86vzmovl (v2f64 VR128:$src))),
4323               (VMOVZPQILo2PQIrr VR128:$src)>;
4324   }
4325   let Predicates = [HasSSE2] in {
4326     def : Pat<(v2i64 (X86vzmovl (loadv2i64 addr:$src))),
4327               (MOVZPQILo2PQIrm addr:$src)>;
4328     def : Pat<(v2f64 (X86vzmovl (v2f64 VR128:$src))),
4329               (MOVZPQILo2PQIrr VR128:$src)>;
4330   }
4331 }
4332
4333 // Instructions to match in the assembler
4334 def VMOVQs64rr : VPDI<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR64:$src),
4335                       "movq\t{$src, $dst|$dst, $src}", []>, VEX, VEX_W;
4336 def VMOVQd64rr : VPDI<0x7E, MRMDestReg, (outs GR64:$dst), (ins VR128:$src),
4337                       "movq\t{$src, $dst|$dst, $src}", []>, VEX, VEX_W;
4338 // Recognize "movd" with GR64 destination, but encode as a "movq"
4339 def VMOVQd64rr_alt : VPDI<0x7E, MRMDestReg, (outs GR64:$dst), (ins VR128:$src),
4340                           "movd\t{$src, $dst|$dst, $src}", []>, VEX, VEX_W;
4341
4342 // Instructions for the disassembler
4343 // xr = XMM register
4344 // xm = mem64
4345
4346 let Predicates = [HasAVX] in
4347 def VMOVQxrxr: I<0x7E, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
4348                  "vmovq\t{$src, $dst|$dst, $src}", []>, VEX, XS;
4349 def MOVQxrxr : I<0x7E, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
4350                  "movq\t{$src, $dst|$dst, $src}", []>, XS;
4351
4352 //===---------------------------------------------------------------------===//
4353 // SSE3 - Conversion Instructions
4354 //===---------------------------------------------------------------------===//
4355
4356 // Convert Packed Double FP to Packed DW Integers
4357 let Predicates = [HasAVX] in {
4358 // The assembler can recognize rr 256-bit instructions by seeing a ymm
4359 // register, but the same isn't true when using memory operands instead.
4360 // Provide other assembly rr and rm forms to address this explicitly.
4361 def VCVTPD2DQrr  : S3DI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
4362                        "vcvtpd2dq\t{$src, $dst|$dst, $src}", []>, VEX;
4363 def VCVTPD2DQXrYr  : S3DI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR256:$src),
4364                        "vcvtpd2dq\t{$src, $dst|$dst, $src}", []>, VEX;
4365
4366 // XMM only
4367 def VCVTPD2DQXrr : S3DI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
4368                       "vcvtpd2dqx\t{$src, $dst|$dst, $src}", []>, VEX;
4369 def VCVTPD2DQXrm : S3DI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
4370                       "vcvtpd2dqx\t{$src, $dst|$dst, $src}", []>, VEX;
4371
4372 // YMM only
4373 def VCVTPD2DQYrr : S3DI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR256:$src),
4374                       "vcvtpd2dqy\t{$src, $dst|$dst, $src}", []>, VEX;
4375 def VCVTPD2DQYrm : S3DI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f256mem:$src),
4376                       "vcvtpd2dqy\t{$src, $dst|$dst, $src}", []>, VEX, VEX_L;
4377 }
4378
4379 def CVTPD2DQrm  : S3DI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
4380                        "cvtpd2dq\t{$src, $dst|$dst, $src}", []>;
4381 def CVTPD2DQrr  : S3DI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
4382                        "cvtpd2dq\t{$src, $dst|$dst, $src}", []>;
4383
4384 def : Pat<(v4i32 (fp_to_sint (v4f64 VR256:$src))),
4385           (VCVTTPD2DQYrr VR256:$src)>;
4386 def : Pat<(v4i32 (fp_to_sint (memopv4f64 addr:$src))),
4387           (VCVTTPD2DQYrm addr:$src)>;
4388
4389 // Convert Packed DW Integers to Packed Double FP
4390 let Predicates = [HasAVX] in {
4391 def VCVTDQ2PDrm  : S3SI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
4392                      "vcvtdq2pd\t{$src, $dst|$dst, $src}", []>, VEX;
4393 def VCVTDQ2PDrr  : S3SI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
4394                      "vcvtdq2pd\t{$src, $dst|$dst, $src}", []>, VEX;
4395 def VCVTDQ2PDYrm  : S3SI<0xE6, MRMSrcMem, (outs VR256:$dst), (ins f128mem:$src),
4396                      "vcvtdq2pd\t{$src, $dst|$dst, $src}", []>, VEX;
4397 def VCVTDQ2PDYrr  : S3SI<0xE6, MRMSrcReg, (outs VR256:$dst), (ins VR128:$src),
4398                      "vcvtdq2pd\t{$src, $dst|$dst, $src}", []>, VEX;
4399 }
4400
4401 def CVTDQ2PDrm  : S3SI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
4402                        "cvtdq2pd\t{$src, $dst|$dst, $src}", []>;
4403 def CVTDQ2PDrr  : S3SI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
4404                        "cvtdq2pd\t{$src, $dst|$dst, $src}", []>;
4405
4406 // AVX 256-bit register conversion intrinsics
4407 def : Pat<(int_x86_avx_cvtdq2_pd_256 VR128:$src),
4408            (VCVTDQ2PDYrr VR128:$src)>;
4409 def : Pat<(int_x86_avx_cvtdq2_pd_256 (bitconvert (memopv2i64 addr:$src))),
4410            (VCVTDQ2PDYrm addr:$src)>;
4411
4412 def : Pat<(int_x86_avx_cvt_pd2dq_256 VR256:$src),
4413           (VCVTPD2DQYrr VR256:$src)>;
4414 def : Pat<(int_x86_avx_cvt_pd2dq_256 (memopv4f64 addr:$src)),
4415           (VCVTPD2DQYrm addr:$src)>;
4416
4417 def : Pat<(v4f64 (sint_to_fp (v4i32 VR128:$src))),
4418           (VCVTDQ2PDYrr VR128:$src)>;
4419 def : Pat<(v4f64 (sint_to_fp (bc_v4i32 (memopv2i64 addr:$src)))),
4420           (VCVTDQ2PDYrm addr:$src)>;
4421
4422 //===---------------------------------------------------------------------===//
4423 // SSE3 - Replicate Single FP - MOVSHDUP and MOVSLDUP
4424 //===---------------------------------------------------------------------===//
4425 multiclass sse3_replicate_sfp<bits<8> op, SDNode OpNode, string OpcodeStr,
4426                               ValueType vt, RegisterClass RC, PatFrag mem_frag,
4427                               X86MemOperand x86memop> {
4428 def rr : S3SI<op, MRMSrcReg, (outs RC:$dst), (ins RC:$src),
4429                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
4430                       [(set RC:$dst, (vt (OpNode RC:$src)))]>;
4431 def rm : S3SI<op, MRMSrcMem, (outs RC:$dst), (ins x86memop:$src),
4432                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
4433                       [(set RC:$dst, (OpNode (mem_frag addr:$src)))]>;
4434 }
4435
4436 let Predicates = [HasAVX] in {
4437   defm VMOVSHDUP  : sse3_replicate_sfp<0x16, X86Movshdup, "vmovshdup",
4438                                        v4f32, VR128, memopv4f32, f128mem>, VEX;
4439   defm VMOVSLDUP  : sse3_replicate_sfp<0x12, X86Movsldup, "vmovsldup",
4440                                        v4f32, VR128, memopv4f32, f128mem>, VEX;
4441   defm VMOVSHDUPY : sse3_replicate_sfp<0x16, X86Movshdup, "vmovshdup",
4442                                        v8f32, VR256, memopv8f32, f256mem>, VEX;
4443   defm VMOVSLDUPY : sse3_replicate_sfp<0x12, X86Movsldup, "vmovsldup",
4444                                        v8f32, VR256, memopv8f32, f256mem>, VEX;
4445 }
4446 defm MOVSHDUP : sse3_replicate_sfp<0x16, X86Movshdup, "movshdup", v4f32, VR128,
4447                                    memopv4f32, f128mem>;
4448 defm MOVSLDUP : sse3_replicate_sfp<0x12, X86Movsldup, "movsldup", v4f32, VR128,
4449                                    memopv4f32, f128mem>;
4450
4451 let Predicates = [HasAVX] in {
4452   def : Pat<(v4i32 (X86Movshdup VR128:$src)),
4453             (VMOVSHDUPrr VR128:$src)>;
4454   def : Pat<(v4i32 (X86Movshdup (bc_v4i32 (memopv2i64 addr:$src)))),
4455             (VMOVSHDUPrm addr:$src)>;
4456   def : Pat<(v4i32 (X86Movsldup VR128:$src)),
4457             (VMOVSLDUPrr VR128:$src)>;
4458   def : Pat<(v4i32 (X86Movsldup (bc_v4i32 (memopv2i64 addr:$src)))),
4459             (VMOVSLDUPrm addr:$src)>;
4460   def : Pat<(v8i32 (X86Movshdup VR256:$src)),
4461             (VMOVSHDUPYrr VR256:$src)>;
4462   def : Pat<(v8i32 (X86Movshdup (bc_v8i32 (memopv4i64 addr:$src)))),
4463             (VMOVSHDUPYrm addr:$src)>;
4464   def : Pat<(v8i32 (X86Movsldup VR256:$src)),
4465             (VMOVSLDUPYrr VR256:$src)>;
4466   def : Pat<(v8i32 (X86Movsldup (bc_v8i32 (memopv4i64 addr:$src)))),
4467             (VMOVSLDUPYrm addr:$src)>;
4468 }
4469
4470 let Predicates = [HasSSE3] in {
4471   def : Pat<(v4i32 (X86Movshdup VR128:$src)),
4472             (MOVSHDUPrr VR128:$src)>;
4473   def : Pat<(v4i32 (X86Movshdup (bc_v4i32 (memopv2i64 addr:$src)))),
4474             (MOVSHDUPrm addr:$src)>;
4475   def : Pat<(v4i32 (X86Movsldup VR128:$src)),
4476             (MOVSLDUPrr VR128:$src)>;
4477   def : Pat<(v4i32 (X86Movsldup (bc_v4i32 (memopv2i64 addr:$src)))),
4478             (MOVSLDUPrm addr:$src)>;
4479 }
4480
4481 //===---------------------------------------------------------------------===//
4482 // SSE3 - Replicate Double FP - MOVDDUP
4483 //===---------------------------------------------------------------------===//
4484
4485 multiclass sse3_replicate_dfp<string OpcodeStr> {
4486 let neverHasSideEffects = 1 in
4487 def rr  : S3DI<0x12, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
4488                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
4489                     []>;
4490 def rm  : S3DI<0x12, MRMSrcMem, (outs VR128:$dst), (ins f64mem:$src),
4491                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
4492                     [(set VR128:$dst,
4493                       (v2f64 (X86Movddup
4494                               (scalar_to_vector (loadf64 addr:$src)))))]>;
4495 }
4496
4497 // FIXME: Merge with above classe when there're patterns for the ymm version
4498 multiclass sse3_replicate_dfp_y<string OpcodeStr> {
4499 def rr  : S3DI<0x12, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
4500                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
4501                     [(set VR256:$dst, (v4f64 (X86Movddup VR256:$src)))]>;
4502 def rm  : S3DI<0x12, MRMSrcMem, (outs VR256:$dst), (ins f256mem:$src),
4503                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
4504                     [(set VR256:$dst,
4505                       (v4f64 (X86Movddup
4506                               (scalar_to_vector (loadf64 addr:$src)))))]>;
4507 }
4508
4509 let Predicates = [HasAVX] in {
4510   defm VMOVDDUP  : sse3_replicate_dfp<"vmovddup">, VEX;
4511   defm VMOVDDUPY : sse3_replicate_dfp_y<"vmovddup">, VEX;
4512 }
4513
4514 defm MOVDDUP : sse3_replicate_dfp<"movddup">;
4515
4516 let Predicates = [HasAVX] in {
4517   def : Pat<(X86Movddup (memopv2f64 addr:$src)),
4518             (VMOVDDUPrm addr:$src)>, Requires<[HasAVX]>;
4519   def : Pat<(X86Movddup (bc_v2f64 (memopv4f32 addr:$src))),
4520             (VMOVDDUPrm addr:$src)>, Requires<[HasAVX]>;
4521   def : Pat<(X86Movddup (bc_v2f64 (memopv2i64 addr:$src))),
4522             (VMOVDDUPrm addr:$src)>, Requires<[HasAVX]>;
4523   def : Pat<(X86Movddup (bc_v2f64
4524                              (v2i64 (scalar_to_vector (loadi64 addr:$src))))),
4525             (VMOVDDUPrm addr:$src)>, Requires<[HasAVX]>;
4526
4527   // 256-bit version
4528   def : Pat<(X86Movddup (memopv4f64 addr:$src)),
4529             (VMOVDDUPYrm addr:$src)>;
4530   def : Pat<(X86Movddup (memopv4i64 addr:$src)),
4531             (VMOVDDUPYrm addr:$src)>;
4532   def : Pat<(X86Movddup (v4i64 (scalar_to_vector (loadi64 addr:$src)))),
4533             (VMOVDDUPYrm addr:$src)>;
4534   def : Pat<(X86Movddup (v4i64 VR256:$src)),
4535             (VMOVDDUPYrr VR256:$src)>;
4536 }
4537
4538 let Predicates = [HasSSE3] in {
4539   def : Pat<(X86Movddup (memopv2f64 addr:$src)),
4540             (MOVDDUPrm addr:$src)>;
4541   def : Pat<(X86Movddup (bc_v2f64 (memopv4f32 addr:$src))),
4542             (MOVDDUPrm addr:$src)>;
4543   def : Pat<(X86Movddup (bc_v2f64 (memopv2i64 addr:$src))),
4544             (MOVDDUPrm addr:$src)>;
4545   def : Pat<(X86Movddup (bc_v2f64
4546                              (v2i64 (scalar_to_vector (loadi64 addr:$src))))),
4547             (MOVDDUPrm addr:$src)>;
4548 }
4549
4550 //===---------------------------------------------------------------------===//
4551 // SSE3 - Move Unaligned Integer
4552 //===---------------------------------------------------------------------===//
4553
4554 let Predicates = [HasAVX] in {
4555   def VLDDQUrm : S3DI<0xF0, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
4556                    "vlddqu\t{$src, $dst|$dst, $src}",
4557                    [(set VR128:$dst, (int_x86_sse3_ldu_dq addr:$src))]>, VEX;
4558   def VLDDQUYrm : S3DI<0xF0, MRMSrcMem, (outs VR256:$dst), (ins i256mem:$src),
4559                    "vlddqu\t{$src, $dst|$dst, $src}",
4560                    [(set VR256:$dst, (int_x86_avx_ldu_dq_256 addr:$src))]>, VEX;
4561 }
4562 def LDDQUrm : S3DI<0xF0, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
4563                    "lddqu\t{$src, $dst|$dst, $src}",
4564                    [(set VR128:$dst, (int_x86_sse3_ldu_dq addr:$src))]>;
4565
4566 //===---------------------------------------------------------------------===//
4567 // SSE3 - Arithmetic
4568 //===---------------------------------------------------------------------===//
4569
4570 multiclass sse3_addsub<Intrinsic Int, string OpcodeStr, RegisterClass RC,
4571                        X86MemOperand x86memop, bit Is2Addr = 1> {
4572   def rr : I<0xD0, MRMSrcReg,
4573        (outs RC:$dst), (ins RC:$src1, RC:$src2),
4574        !if(Is2Addr,
4575            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
4576            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
4577        [(set RC:$dst, (Int RC:$src1, RC:$src2))]>;
4578   def rm : I<0xD0, MRMSrcMem,
4579        (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
4580        !if(Is2Addr,
4581            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
4582            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
4583        [(set RC:$dst, (Int RC:$src1, (memop addr:$src2)))]>;
4584 }
4585
4586 let Predicates = [HasAVX] in {
4587   let ExeDomain = SSEPackedSingle in {
4588     defm VADDSUBPS : sse3_addsub<int_x86_sse3_addsub_ps, "vaddsubps", VR128,
4589                                  f128mem, 0>, TB, XD, VEX_4V;
4590     defm VADDSUBPSY : sse3_addsub<int_x86_avx_addsub_ps_256, "vaddsubps", VR256,
4591                                  f256mem, 0>, TB, XD, VEX_4V;
4592   }
4593   let ExeDomain = SSEPackedDouble in {
4594     defm VADDSUBPD : sse3_addsub<int_x86_sse3_addsub_pd, "vaddsubpd", VR128,
4595                                  f128mem, 0>, TB, OpSize, VEX_4V;
4596     defm VADDSUBPDY : sse3_addsub<int_x86_avx_addsub_pd_256, "vaddsubpd", VR256,
4597                                  f256mem, 0>, TB, OpSize, VEX_4V;
4598   }
4599 }
4600 let Constraints = "$src1 = $dst", Predicates = [HasSSE3] in {
4601   let ExeDomain = SSEPackedSingle in
4602   defm ADDSUBPS : sse3_addsub<int_x86_sse3_addsub_ps, "addsubps", VR128,
4603                               f128mem>, TB, XD;
4604   let ExeDomain = SSEPackedDouble in
4605   defm ADDSUBPD : sse3_addsub<int_x86_sse3_addsub_pd, "addsubpd", VR128,
4606                               f128mem>, TB, OpSize;
4607 }
4608
4609 //===---------------------------------------------------------------------===//
4610 // SSE3 Instructions
4611 //===---------------------------------------------------------------------===//
4612
4613 // Horizontal ops
4614 multiclass S3D_Int<bits<8> o, string OpcodeStr, ValueType vt, RegisterClass RC,
4615                    X86MemOperand x86memop, SDNode OpNode, bit Is2Addr = 1> {
4616   def rr : S3DI<o, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
4617        !if(Is2Addr,
4618          !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
4619          !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
4620       [(set RC:$dst, (vt (OpNode RC:$src1, RC:$src2)))]>;
4621
4622   def rm : S3DI<o, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
4623        !if(Is2Addr,
4624          !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
4625          !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
4626       [(set RC:$dst, (vt (OpNode RC:$src1, (memop addr:$src2))))]>;
4627 }
4628 multiclass S3_Int<bits<8> o, string OpcodeStr, ValueType vt, RegisterClass RC,
4629                   X86MemOperand x86memop, SDNode OpNode, bit Is2Addr = 1> {
4630   def rr : S3I<o, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
4631        !if(Is2Addr,
4632          !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
4633          !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
4634       [(set RC:$dst, (vt (OpNode RC:$src1, RC:$src2)))]>;
4635
4636   def rm : S3I<o, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
4637        !if(Is2Addr,
4638          !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
4639          !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
4640       [(set RC:$dst, (vt (OpNode RC:$src1, (memop addr:$src2))))]>;
4641 }
4642
4643 let Predicates = [HasAVX] in {
4644   let ExeDomain = SSEPackedSingle in {
4645     defm VHADDPS  : S3D_Int<0x7C, "vhaddps", v4f32, VR128, f128mem,
4646                             X86fhadd, 0>, VEX_4V;
4647     defm VHSUBPS  : S3D_Int<0x7D, "vhsubps", v4f32, VR128, f128mem,
4648                             X86fhsub, 0>, VEX_4V;
4649     defm VHADDPSY : S3D_Int<0x7C, "vhaddps", v8f32, VR256, f256mem,
4650                             X86fhadd, 0>, VEX_4V;
4651     defm VHSUBPSY : S3D_Int<0x7D, "vhsubps", v8f32, VR256, f256mem,
4652                             X86fhsub, 0>, VEX_4V;
4653   }
4654   let ExeDomain = SSEPackedDouble in {
4655     defm VHADDPD  : S3_Int <0x7C, "vhaddpd", v2f64, VR128, f128mem,
4656                             X86fhadd, 0>, VEX_4V;
4657     defm VHSUBPD  : S3_Int <0x7D, "vhsubpd", v2f64, VR128, f128mem,
4658                             X86fhsub, 0>, VEX_4V;
4659     defm VHADDPDY : S3_Int <0x7C, "vhaddpd", v4f64, VR256, f256mem,
4660                             X86fhadd, 0>, VEX_4V;
4661     defm VHSUBPDY : S3_Int <0x7D, "vhsubpd", v4f64, VR256, f256mem,
4662                             X86fhsub, 0>, VEX_4V;
4663   }
4664 }
4665
4666 let Constraints = "$src1 = $dst" in {
4667   let ExeDomain = SSEPackedSingle in {
4668     defm HADDPS : S3D_Int<0x7C, "haddps", v4f32, VR128, f128mem, X86fhadd>;
4669     defm HSUBPS : S3D_Int<0x7D, "hsubps", v4f32, VR128, f128mem, X86fhsub>;
4670   }
4671   let ExeDomain = SSEPackedDouble in {
4672     defm HADDPD : S3_Int<0x7C, "haddpd", v2f64, VR128, f128mem, X86fhadd>;
4673     defm HSUBPD : S3_Int<0x7D, "hsubpd", v2f64, VR128, f128mem, X86fhsub>;
4674   }
4675 }
4676
4677 //===---------------------------------------------------------------------===//
4678 // SSSE3 - Packed Absolute Instructions
4679 //===---------------------------------------------------------------------===//
4680
4681
4682 /// SS3I_unop_rm_int - Simple SSSE3 unary op whose type can be v*{i8,i16,i32}.
4683 multiclass SS3I_unop_rm_int<bits<8> opc, string OpcodeStr,
4684                             Intrinsic IntId128> {
4685   def rr128 : SS38I<opc, MRMSrcReg, (outs VR128:$dst),
4686                     (ins VR128:$src),
4687                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
4688                     [(set VR128:$dst, (IntId128 VR128:$src))]>,
4689                     OpSize;
4690
4691   def rm128 : SS38I<opc, MRMSrcMem, (outs VR128:$dst),
4692                     (ins i128mem:$src),
4693                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
4694                     [(set VR128:$dst,
4695                       (IntId128
4696                        (bitconvert (memopv2i64 addr:$src))))]>, OpSize;
4697 }
4698
4699 /// SS3I_unop_rm_int_y - Simple SSSE3 unary op whose type can be v*{i8,i16,i32}.
4700 multiclass SS3I_unop_rm_int_y<bits<8> opc, string OpcodeStr,
4701                               Intrinsic IntId256> {
4702   def rr256 : SS38I<opc, MRMSrcReg, (outs VR256:$dst),
4703                     (ins VR256:$src),
4704                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
4705                     [(set VR256:$dst, (IntId256 VR256:$src))]>,
4706                     OpSize;
4707
4708   def rm256 : SS38I<opc, MRMSrcMem, (outs VR256:$dst),
4709                     (ins i256mem:$src),
4710                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
4711                     [(set VR256:$dst,
4712                       (IntId256
4713                        (bitconvert (memopv4i64 addr:$src))))]>, OpSize;
4714 }
4715
4716 let Predicates = [HasAVX] in {
4717   defm VPABSB  : SS3I_unop_rm_int<0x1C, "vpabsb",
4718                                   int_x86_ssse3_pabs_b_128>, VEX;
4719   defm VPABSW  : SS3I_unop_rm_int<0x1D, "vpabsw",
4720                                   int_x86_ssse3_pabs_w_128>, VEX;
4721   defm VPABSD  : SS3I_unop_rm_int<0x1E, "vpabsd",
4722                                   int_x86_ssse3_pabs_d_128>, VEX;
4723 }
4724
4725 let Predicates = [HasAVX2] in {
4726   defm VPABSB  : SS3I_unop_rm_int_y<0x1C, "vpabsb",
4727                                     int_x86_avx2_pabs_b>, VEX;
4728   defm VPABSW  : SS3I_unop_rm_int_y<0x1D, "vpabsw",
4729                                     int_x86_avx2_pabs_w>, VEX;
4730   defm VPABSD  : SS3I_unop_rm_int_y<0x1E, "vpabsd",
4731                                     int_x86_avx2_pabs_d>, VEX;
4732 }
4733
4734 defm PABSB : SS3I_unop_rm_int<0x1C, "pabsb",
4735                               int_x86_ssse3_pabs_b_128>;
4736 defm PABSW : SS3I_unop_rm_int<0x1D, "pabsw",
4737                               int_x86_ssse3_pabs_w_128>;
4738 defm PABSD : SS3I_unop_rm_int<0x1E, "pabsd",
4739                               int_x86_ssse3_pabs_d_128>;
4740
4741 //===---------------------------------------------------------------------===//
4742 // SSSE3 - Packed Binary Operator Instructions
4743 //===---------------------------------------------------------------------===//
4744
4745 /// SS3I_binop_rm - Simple SSSE3 bin op
4746 multiclass SS3I_binop_rm<bits<8> opc, string OpcodeStr, SDNode OpNode,
4747                          ValueType OpVT, RegisterClass RC, PatFrag memop_frag,
4748                          X86MemOperand x86memop, bit Is2Addr = 1> {
4749   let isCommutable = 1 in
4750   def rr : SS38I<opc, MRMSrcReg, (outs RC:$dst),
4751        (ins RC:$src1, RC:$src2),
4752        !if(Is2Addr,
4753          !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
4754          !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
4755        [(set RC:$dst, (OpVT (OpNode RC:$src1, RC:$src2)))]>,
4756        OpSize;
4757   def rm : SS38I<opc, MRMSrcMem, (outs RC:$dst),
4758        (ins RC:$src1, x86memop:$src2),
4759        !if(Is2Addr,
4760          !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
4761          !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
4762        [(set RC:$dst,
4763          (OpVT (OpNode RC:$src1,
4764           (bitconvert (memop_frag addr:$src2)))))]>, OpSize;
4765 }
4766
4767 /// SS3I_binop_rm_int - Simple SSSE3 bin op whose type can be v*{i8,i16,i32}.
4768 multiclass SS3I_binop_rm_int<bits<8> opc, string OpcodeStr,
4769                              Intrinsic IntId128, bit Is2Addr = 1> {
4770   let isCommutable = 1 in
4771   def rr128 : SS38I<opc, MRMSrcReg, (outs VR128:$dst),
4772        (ins VR128:$src1, VR128:$src2),
4773        !if(Is2Addr,
4774          !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
4775          !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
4776        [(set VR128:$dst, (IntId128 VR128:$src1, VR128:$src2))]>,
4777        OpSize;
4778   def rm128 : SS38I<opc, MRMSrcMem, (outs VR128:$dst),
4779        (ins VR128:$src1, i128mem:$src2),
4780        !if(Is2Addr,
4781          !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
4782          !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
4783        [(set VR128:$dst,
4784          (IntId128 VR128:$src1,
4785           (bitconvert (memopv2i64 addr:$src2))))]>, OpSize;
4786 }
4787
4788 multiclass SS3I_binop_rm_int_y<bits<8> opc, string OpcodeStr,
4789                                Intrinsic IntId256> {
4790   let isCommutable = 1 in
4791   def rr256 : SS38I<opc, MRMSrcReg, (outs VR256:$dst),
4792        (ins VR256:$src1, VR256:$src2),
4793        !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4794        [(set VR256:$dst, (IntId256 VR256:$src1, VR256:$src2))]>,
4795        OpSize;
4796   def rm256 : SS38I<opc, MRMSrcMem, (outs VR256:$dst),
4797        (ins VR256:$src1, i256mem:$src2),
4798        !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
4799        [(set VR256:$dst,
4800          (IntId256 VR256:$src1,
4801           (bitconvert (memopv4i64 addr:$src2))))]>, OpSize;
4802 }
4803
4804 let ImmT = NoImm, Predicates = [HasAVX] in {
4805 let isCommutable = 0 in {
4806   defm VPHADDW    : SS3I_binop_rm<0x01, "vphaddw", X86hadd, v8i16, VR128,
4807                                   memopv2i64, i128mem, 0>, VEX_4V;
4808   defm VPHADDD    : SS3I_binop_rm<0x02, "vphaddd", X86hadd, v4i32, VR128,
4809                                   memopv2i64, i128mem, 0>, VEX_4V;
4810   defm VPHSUBW    : SS3I_binop_rm<0x05, "vphsubw", X86hsub, v8i16, VR128,
4811                                   memopv2i64, i128mem, 0>, VEX_4V;
4812   defm VPHSUBD    : SS3I_binop_rm<0x06, "vphsubd", X86hsub, v4i32, VR128,
4813                                   memopv2i64, i128mem, 0>, VEX_4V;
4814   defm VPSIGNB    : SS3I_binop_rm<0x08, "vpsignb", X86psign, v16i8, VR128,
4815                                   memopv2i64, i128mem, 0>, VEX_4V;
4816   defm VPSIGNW    : SS3I_binop_rm<0x09, "vpsignw", X86psign, v8i16, VR128,
4817                                   memopv2i64, i128mem, 0>, VEX_4V;
4818   defm VPSIGND    : SS3I_binop_rm<0x0A, "vpsignd", X86psign, v4i32, VR128,
4819                                   memopv2i64, i128mem, 0>, VEX_4V;
4820   defm VPSHUFB    : SS3I_binop_rm<0x00, "vpshufb", X86pshufb, v16i8, VR128,
4821                                   memopv2i64, i128mem, 0>, VEX_4V;
4822   defm VPHADDSW   : SS3I_binop_rm_int<0x03, "vphaddsw",
4823                                       int_x86_ssse3_phadd_sw_128, 0>, VEX_4V;
4824   defm VPHSUBSW   : SS3I_binop_rm_int<0x07, "vphsubsw",
4825                                       int_x86_ssse3_phsub_sw_128, 0>, VEX_4V;
4826   defm VPMADDUBSW : SS3I_binop_rm_int<0x04, "vpmaddubsw",
4827                                       int_x86_ssse3_pmadd_ub_sw_128, 0>, VEX_4V;
4828 }
4829 defm VPMULHRSW    : SS3I_binop_rm_int<0x0B, "vpmulhrsw",
4830                                       int_x86_ssse3_pmul_hr_sw_128, 0>, VEX_4V;
4831 }
4832
4833 let ImmT = NoImm, Predicates = [HasAVX2] in {
4834 let isCommutable = 0 in {
4835   defm VPHADDWY   : SS3I_binop_rm<0x01, "vphaddw", X86hadd, v16i16, VR256,
4836                                   memopv4i64, i256mem, 0>, VEX_4V;
4837   defm VPHADDDY   : SS3I_binop_rm<0x02, "vphaddd", X86hadd, v8i32, VR256,
4838                                   memopv4i64, i256mem, 0>, VEX_4V;
4839   defm VPHSUBWY   : SS3I_binop_rm<0x05, "vphsubw", X86hsub, v16i16, VR256,
4840                                   memopv4i64, i256mem, 0>, VEX_4V;
4841   defm VPHSUBDY   : SS3I_binop_rm<0x06, "vphsubd", X86hsub, v8i32, VR256,
4842                                   memopv4i64, i256mem, 0>, VEX_4V;
4843   defm VPSIGNBY   : SS3I_binop_rm<0x08, "vpsignb", X86psign, v32i8, VR256,
4844                                   memopv4i64, i256mem, 0>, VEX_4V;
4845   defm VPSIGNWY   : SS3I_binop_rm<0x09, "vpsignw", X86psign, v16i16, VR256,
4846                                   memopv4i64, i256mem, 0>, VEX_4V;
4847   defm VPSIGNDY   : SS3I_binop_rm<0x0A, "vpsignd", X86psign, v8i32, VR256,
4848                                   memopv4i64, i256mem, 0>, VEX_4V;
4849   defm VPSHUFBY   : SS3I_binop_rm<0x00, "vpshufb", X86pshufb, v32i8, VR256,
4850                                   memopv4i64, i256mem, 0>, VEX_4V;
4851   defm VPHADDSW   : SS3I_binop_rm_int_y<0x03, "vphaddsw",
4852                                         int_x86_avx2_phadd_sw>, VEX_4V;
4853   defm VPHSUBSW   : SS3I_binop_rm_int_y<0x07, "vphsubsw",
4854                                         int_x86_avx2_phsub_sw>, VEX_4V;
4855   defm VPMADDUBSW : SS3I_binop_rm_int_y<0x04, "vpmaddubsw",
4856                                         int_x86_avx2_pmadd_ub_sw>, VEX_4V;
4857 }
4858 defm VPMULHRSW    : SS3I_binop_rm_int_y<0x0B, "vpmulhrsw",
4859                                         int_x86_avx2_pmul_hr_sw>, VEX_4V;
4860 }
4861
4862 // None of these have i8 immediate fields.
4863 let ImmT = NoImm, Constraints = "$src1 = $dst" in {
4864 let isCommutable = 0 in {
4865   defm PHADDW    : SS3I_binop_rm<0x01, "phaddw", X86hadd, v8i16, VR128,
4866                                  memopv2i64, i128mem>;
4867   defm PHADDD    : SS3I_binop_rm<0x02, "phaddd", X86hadd, v4i32, VR128,
4868                                  memopv2i64, i128mem>;
4869   defm PHSUBW    : SS3I_binop_rm<0x05, "phsubw", X86hsub, v8i16, VR128,
4870                                  memopv2i64, i128mem>;
4871   defm PHSUBD    : SS3I_binop_rm<0x06, "phsubd", X86hsub, v4i32, VR128,
4872                                  memopv2i64, i128mem>;
4873   defm PSIGNB    : SS3I_binop_rm<0x08, "psignb", X86psign, v16i8, VR128,
4874                                  memopv2i64, i128mem>;
4875   defm PSIGNW    : SS3I_binop_rm<0x09, "psignw", X86psign, v8i16, VR128,
4876                                  memopv2i64, i128mem>;
4877   defm PSIGND    : SS3I_binop_rm<0x0A, "psignd", X86psign, v4i32, VR128,
4878                                  memopv2i64, i128mem>;
4879   defm PSHUFB    : SS3I_binop_rm<0x00, "pshufb", X86pshufb, v16i8, VR128,
4880                                  memopv2i64, i128mem>;
4881   defm PHADDSW   : SS3I_binop_rm_int<0x03, "phaddsw",
4882                                      int_x86_ssse3_phadd_sw_128>;
4883   defm PHSUBSW   : SS3I_binop_rm_int<0x07, "phsubsw",
4884                                      int_x86_ssse3_phsub_sw_128>;
4885   defm PMADDUBSW : SS3I_binop_rm_int<0x04, "pmaddubsw",
4886                                      int_x86_ssse3_pmadd_ub_sw_128>;
4887 }
4888 defm PMULHRSW    : SS3I_binop_rm_int<0x0B, "pmulhrsw",
4889                                      int_x86_ssse3_pmul_hr_sw_128>;
4890 }
4891
4892 //===---------------------------------------------------------------------===//
4893 // SSSE3 - Packed Align Instruction Patterns
4894 //===---------------------------------------------------------------------===//
4895
4896 multiclass ssse3_palign<string asm, bit Is2Addr = 1> {
4897   let neverHasSideEffects = 1 in {
4898   def R128rr : SS3AI<0x0F, MRMSrcReg, (outs VR128:$dst),
4899       (ins VR128:$src1, VR128:$src2, i8imm:$src3),
4900       !if(Is2Addr,
4901         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
4902         !strconcat(asm,
4903                   "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
4904       []>, OpSize;
4905   let mayLoad = 1 in
4906   def R128rm : SS3AI<0x0F, MRMSrcMem, (outs VR128:$dst),
4907       (ins VR128:$src1, i128mem:$src2, i8imm:$src3),
4908       !if(Is2Addr,
4909         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
4910         !strconcat(asm,
4911                   "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
4912       []>, OpSize;
4913   }
4914 }
4915
4916 multiclass ssse3_palign_y<string asm, bit Is2Addr = 1> {
4917   let neverHasSideEffects = 1 in {
4918   def R256rr : SS3AI<0x0F, MRMSrcReg, (outs VR256:$dst),
4919       (ins VR256:$src1, VR256:$src2, i8imm:$src3),
4920       !strconcat(asm,
4921                  "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
4922       []>, OpSize;
4923   let mayLoad = 1 in
4924   def R256rm : SS3AI<0x0F, MRMSrcMem, (outs VR256:$dst),
4925       (ins VR256:$src1, i256mem:$src2, i8imm:$src3),
4926       !strconcat(asm,
4927                  "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
4928       []>, OpSize;
4929   }
4930 }
4931
4932 let Predicates = [HasAVX] in
4933   defm VPALIGN : ssse3_palign<"vpalignr", 0>, VEX_4V;
4934 let Predicates = [HasAVX2] in
4935   defm VPALIGN : ssse3_palign_y<"vpalignr", 0>, VEX_4V;
4936 let Constraints = "$src1 = $dst", Predicates = [HasSSSE3] in
4937   defm PALIGN : ssse3_palign<"palignr">;
4938
4939 let Predicates = [HasAVX2] in {
4940 def : Pat<(v8i32 (X86PAlign VR256:$src1, VR256:$src2, (i8 imm:$imm))),
4941           (VPALIGNR256rr VR256:$src2, VR256:$src1, imm:$imm)>;
4942 def : Pat<(v8f32 (X86PAlign VR256:$src1, VR256:$src2, (i8 imm:$imm))),
4943           (VPALIGNR256rr VR256:$src2, VR256:$src1, imm:$imm)>;
4944 def : Pat<(v16i16 (X86PAlign VR256:$src1, VR256:$src2, (i8 imm:$imm))),
4945           (VPALIGNR256rr VR256:$src2, VR256:$src1, imm:$imm)>;
4946 def : Pat<(v32i8 (X86PAlign VR256:$src1, VR256:$src2, (i8 imm:$imm))),
4947           (VPALIGNR256rr VR256:$src2, VR256:$src1, imm:$imm)>;
4948 }
4949
4950 let Predicates = [HasAVX] in {
4951 def : Pat<(v4i32 (X86PAlign VR128:$src1, VR128:$src2, (i8 imm:$imm))),
4952           (VPALIGNR128rr VR128:$src2, VR128:$src1, imm:$imm)>;
4953 def : Pat<(v4f32 (X86PAlign VR128:$src1, VR128:$src2, (i8 imm:$imm))),
4954           (VPALIGNR128rr VR128:$src2, VR128:$src1, imm:$imm)>;
4955 def : Pat<(v8i16 (X86PAlign VR128:$src1, VR128:$src2, (i8 imm:$imm))),
4956           (VPALIGNR128rr VR128:$src2, VR128:$src1, imm:$imm)>;
4957 def : Pat<(v16i8 (X86PAlign VR128:$src1, VR128:$src2, (i8 imm:$imm))),
4958           (VPALIGNR128rr VR128:$src2, VR128:$src1, imm:$imm)>;
4959 }
4960
4961 let Predicates = [HasSSSE3] in {
4962 def : Pat<(v4i32 (X86PAlign VR128:$src1, VR128:$src2, (i8 imm:$imm))),
4963           (PALIGNR128rr VR128:$src2, VR128:$src1, imm:$imm)>;
4964 def : Pat<(v4f32 (X86PAlign VR128:$src1, VR128:$src2, (i8 imm:$imm))),
4965           (PALIGNR128rr VR128:$src2, VR128:$src1, imm:$imm)>;
4966 def : Pat<(v8i16 (X86PAlign VR128:$src1, VR128:$src2, (i8 imm:$imm))),
4967           (PALIGNR128rr VR128:$src2, VR128:$src1, imm:$imm)>;
4968 def : Pat<(v16i8 (X86PAlign VR128:$src1, VR128:$src2, (i8 imm:$imm))),
4969           (PALIGNR128rr VR128:$src2, VR128:$src1, imm:$imm)>;
4970 }
4971
4972 //===---------------------------------------------------------------------===//
4973 // SSSE3 - Thread synchronization
4974 //===---------------------------------------------------------------------===//
4975
4976 let usesCustomInserter = 1 in {
4977 def MONITOR : PseudoI<(outs), (ins i32mem:$src1, GR32:$src2, GR32:$src3),
4978                 [(int_x86_sse3_monitor addr:$src1, GR32:$src2, GR32:$src3)]>,
4979                 Requires<[HasSSE3]>;
4980 def MWAIT : PseudoI<(outs), (ins GR32:$src1, GR32:$src2),
4981                 [(int_x86_sse3_mwait GR32:$src1, GR32:$src2)]>,
4982                 Requires<[HasSSE3]>;
4983 }
4984
4985 let Uses = [EAX, ECX, EDX] in
4986 def MONITORrrr : I<0x01, MRM_C8, (outs), (ins), "monitor", []>, TB,
4987                  Requires<[HasSSE3]>;
4988 let Uses = [ECX, EAX] in
4989 def MWAITrr   : I<0x01, MRM_C9, (outs), (ins), "mwait", []>, TB,
4990                 Requires<[HasSSE3]>;
4991
4992 def : InstAlias<"mwait %eax, %ecx", (MWAITrr)>, Requires<[In32BitMode]>;
4993 def : InstAlias<"mwait %rax, %rcx", (MWAITrr)>, Requires<[In64BitMode]>;
4994
4995 def : InstAlias<"monitor %eax, %ecx, %edx", (MONITORrrr)>,
4996       Requires<[In32BitMode]>;
4997 def : InstAlias<"monitor %rax, %rcx, %rdx", (MONITORrrr)>,
4998       Requires<[In64BitMode]>;
4999
5000 //===----------------------------------------------------------------------===//
5001 // SSE4.1 - Packed Move with Sign/Zero Extend
5002 //===----------------------------------------------------------------------===//
5003
5004 multiclass SS41I_binop_rm_int8<bits<8> opc, string OpcodeStr, Intrinsic IntId> {
5005   def rr : SS48I<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
5006                  !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5007                  [(set VR128:$dst, (IntId VR128:$src))]>, OpSize;
5008
5009   def rm : SS48I<opc, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
5010                  !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5011        [(set VR128:$dst,
5012          (IntId (bitconvert (v2i64 (scalar_to_vector (loadi64 addr:$src))))))]>,
5013        OpSize;
5014 }
5015
5016 multiclass SS41I_binop_rm_int16_y<bits<8> opc, string OpcodeStr,
5017                                  Intrinsic IntId> {
5018   def Yrr : SS48I<opc, MRMSrcReg, (outs VR256:$dst), (ins VR128:$src),
5019                   !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5020                   [(set VR256:$dst, (IntId VR128:$src))]>, OpSize;
5021
5022   def Yrm : SS48I<opc, MRMSrcMem, (outs VR256:$dst), (ins i128mem:$src),
5023                   !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5024                   [(set VR256:$dst, (IntId (load addr:$src)))]>, OpSize;
5025 }
5026
5027 let Predicates = [HasAVX] in {
5028 defm VPMOVSXBW : SS41I_binop_rm_int8<0x20, "vpmovsxbw", int_x86_sse41_pmovsxbw>,
5029                                      VEX;
5030 defm VPMOVSXWD : SS41I_binop_rm_int8<0x23, "vpmovsxwd", int_x86_sse41_pmovsxwd>,
5031                                      VEX;
5032 defm VPMOVSXDQ : SS41I_binop_rm_int8<0x25, "vpmovsxdq", int_x86_sse41_pmovsxdq>,
5033                                      VEX;
5034 defm VPMOVZXBW : SS41I_binop_rm_int8<0x30, "vpmovzxbw", int_x86_sse41_pmovzxbw>,
5035                                      VEX;
5036 defm VPMOVZXWD : SS41I_binop_rm_int8<0x33, "vpmovzxwd", int_x86_sse41_pmovzxwd>,
5037                                      VEX;
5038 defm VPMOVZXDQ : SS41I_binop_rm_int8<0x35, "vpmovzxdq", int_x86_sse41_pmovzxdq>,
5039                                      VEX;
5040 }
5041
5042 let Predicates = [HasAVX2] in {
5043 defm VPMOVSXBW : SS41I_binop_rm_int16_y<0x20, "vpmovsxbw",
5044                                         int_x86_avx2_pmovsxbw>, VEX;
5045 defm VPMOVSXWD : SS41I_binop_rm_int16_y<0x23, "vpmovsxwd",
5046                                         int_x86_avx2_pmovsxwd>, VEX;
5047 defm VPMOVSXDQ : SS41I_binop_rm_int16_y<0x25, "vpmovsxdq",
5048                                         int_x86_avx2_pmovsxdq>, VEX;
5049 defm VPMOVZXBW : SS41I_binop_rm_int16_y<0x30, "vpmovzxbw",
5050                                         int_x86_avx2_pmovzxbw>, VEX;
5051 defm VPMOVZXWD : SS41I_binop_rm_int16_y<0x33, "vpmovzxwd",
5052                                         int_x86_avx2_pmovzxwd>, VEX;
5053 defm VPMOVZXDQ : SS41I_binop_rm_int16_y<0x35, "vpmovzxdq",
5054                                         int_x86_avx2_pmovzxdq>, VEX;
5055 }
5056
5057 defm PMOVSXBW   : SS41I_binop_rm_int8<0x20, "pmovsxbw", int_x86_sse41_pmovsxbw>;
5058 defm PMOVSXWD   : SS41I_binop_rm_int8<0x23, "pmovsxwd", int_x86_sse41_pmovsxwd>;
5059 defm PMOVSXDQ   : SS41I_binop_rm_int8<0x25, "pmovsxdq", int_x86_sse41_pmovsxdq>;
5060 defm PMOVZXBW   : SS41I_binop_rm_int8<0x30, "pmovzxbw", int_x86_sse41_pmovzxbw>;
5061 defm PMOVZXWD   : SS41I_binop_rm_int8<0x33, "pmovzxwd", int_x86_sse41_pmovzxwd>;
5062 defm PMOVZXDQ   : SS41I_binop_rm_int8<0x35, "pmovzxdq", int_x86_sse41_pmovzxdq>;
5063
5064 let Predicates = [HasAVX] in {
5065   // Common patterns involving scalar load.
5066   def : Pat<(int_x86_sse41_pmovsxbw (vzmovl_v2i64 addr:$src)),
5067             (VPMOVSXBWrm addr:$src)>;
5068   def : Pat<(int_x86_sse41_pmovsxbw (vzload_v2i64 addr:$src)),
5069             (VPMOVSXBWrm addr:$src)>;
5070
5071   def : Pat<(int_x86_sse41_pmovsxwd (vzmovl_v2i64 addr:$src)),
5072             (VPMOVSXWDrm addr:$src)>;
5073   def : Pat<(int_x86_sse41_pmovsxwd (vzload_v2i64 addr:$src)),
5074             (VPMOVSXWDrm addr:$src)>;
5075
5076   def : Pat<(int_x86_sse41_pmovsxdq (vzmovl_v2i64 addr:$src)),
5077             (VPMOVSXDQrm addr:$src)>;
5078   def : Pat<(int_x86_sse41_pmovsxdq (vzload_v2i64 addr:$src)),
5079             (VPMOVSXDQrm addr:$src)>;
5080
5081   def : Pat<(int_x86_sse41_pmovzxbw (vzmovl_v2i64 addr:$src)),
5082             (VPMOVZXBWrm addr:$src)>;
5083   def : Pat<(int_x86_sse41_pmovzxbw (vzload_v2i64 addr:$src)),
5084             (VPMOVZXBWrm addr:$src)>;
5085
5086   def : Pat<(int_x86_sse41_pmovzxwd (vzmovl_v2i64 addr:$src)),
5087             (VPMOVZXWDrm addr:$src)>;
5088   def : Pat<(int_x86_sse41_pmovzxwd (vzload_v2i64 addr:$src)),
5089             (VPMOVZXWDrm addr:$src)>;
5090
5091   def : Pat<(int_x86_sse41_pmovzxdq (vzmovl_v2i64 addr:$src)),
5092             (VPMOVZXDQrm addr:$src)>;
5093   def : Pat<(int_x86_sse41_pmovzxdq (vzload_v2i64 addr:$src)),
5094             (VPMOVZXDQrm addr:$src)>;
5095 }
5096
5097 let Predicates = [HasSSE41] in {
5098   // Common patterns involving scalar load.
5099   def : Pat<(int_x86_sse41_pmovsxbw (vzmovl_v2i64 addr:$src)),
5100             (PMOVSXBWrm addr:$src)>;
5101   def : Pat<(int_x86_sse41_pmovsxbw (vzload_v2i64 addr:$src)),
5102             (PMOVSXBWrm addr:$src)>;
5103
5104   def : Pat<(int_x86_sse41_pmovsxwd (vzmovl_v2i64 addr:$src)),
5105             (PMOVSXWDrm addr:$src)>;
5106   def : Pat<(int_x86_sse41_pmovsxwd (vzload_v2i64 addr:$src)),
5107             (PMOVSXWDrm addr:$src)>;
5108
5109   def : Pat<(int_x86_sse41_pmovsxdq (vzmovl_v2i64 addr:$src)),
5110             (PMOVSXDQrm addr:$src)>;
5111   def : Pat<(int_x86_sse41_pmovsxdq (vzload_v2i64 addr:$src)),
5112             (PMOVSXDQrm addr:$src)>;
5113
5114   def : Pat<(int_x86_sse41_pmovzxbw (vzmovl_v2i64 addr:$src)),
5115             (PMOVZXBWrm addr:$src)>;
5116   def : Pat<(int_x86_sse41_pmovzxbw (vzload_v2i64 addr:$src)),
5117             (PMOVZXBWrm addr:$src)>;
5118
5119   def : Pat<(int_x86_sse41_pmovzxwd (vzmovl_v2i64 addr:$src)),
5120             (PMOVZXWDrm addr:$src)>;
5121   def : Pat<(int_x86_sse41_pmovzxwd (vzload_v2i64 addr:$src)),
5122             (PMOVZXWDrm addr:$src)>;
5123
5124   def : Pat<(int_x86_sse41_pmovzxdq (vzmovl_v2i64 addr:$src)),
5125             (PMOVZXDQrm addr:$src)>;
5126   def : Pat<(int_x86_sse41_pmovzxdq (vzload_v2i64 addr:$src)),
5127             (PMOVZXDQrm addr:$src)>;
5128 }
5129
5130 let Predicates = [HasAVX] in {
5131 def : Pat<(v2i64 (X86vsmovl (v4i32 VR128:$src))), (VPMOVSXDQrr VR128:$src)>;
5132 def : Pat<(v4i32 (X86vsmovl (v8i16 VR128:$src))), (VPMOVSXWDrr VR128:$src)>;
5133 }
5134
5135 let Predicates = [HasSSE41] in {
5136 def : Pat<(v2i64 (X86vsmovl (v4i32 VR128:$src))), (PMOVSXDQrr VR128:$src)>;
5137 def : Pat<(v4i32 (X86vsmovl (v8i16 VR128:$src))), (PMOVSXWDrr VR128:$src)>;
5138 }
5139
5140
5141 multiclass SS41I_binop_rm_int4<bits<8> opc, string OpcodeStr, Intrinsic IntId> {
5142   def rr : SS48I<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
5143                  !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5144                  [(set VR128:$dst, (IntId VR128:$src))]>, OpSize;
5145
5146   def rm : SS48I<opc, MRMSrcMem, (outs VR128:$dst), (ins i32mem:$src),
5147                  !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5148        [(set VR128:$dst,
5149          (IntId (bitconvert (v4i32 (scalar_to_vector (loadi32 addr:$src))))))]>,
5150           OpSize;
5151 }
5152
5153 multiclass SS41I_binop_rm_int8_y<bits<8> opc, string OpcodeStr,
5154                                  Intrinsic IntId> {
5155   def Yrr : SS48I<opc, MRMSrcReg, (outs VR256:$dst), (ins VR128:$src),
5156                   !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5157                   [(set VR256:$dst, (IntId VR128:$src))]>, OpSize;
5158
5159   def Yrm : SS48I<opc, MRMSrcMem, (outs VR256:$dst), (ins i32mem:$src),
5160                   !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5161        [(set VR256:$dst,
5162          (IntId (bitconvert (v2i64 (scalar_to_vector (loadi64 addr:$src))))))]>,
5163           OpSize;
5164 }
5165
5166 let Predicates = [HasAVX] in {
5167 defm VPMOVSXBD : SS41I_binop_rm_int4<0x21, "vpmovsxbd", int_x86_sse41_pmovsxbd>,
5168                                      VEX;
5169 defm VPMOVSXWQ : SS41I_binop_rm_int4<0x24, "vpmovsxwq", int_x86_sse41_pmovsxwq>,
5170                                      VEX;
5171 defm VPMOVZXBD : SS41I_binop_rm_int4<0x31, "vpmovzxbd", int_x86_sse41_pmovzxbd>,
5172                                      VEX;
5173 defm VPMOVZXWQ : SS41I_binop_rm_int4<0x34, "vpmovzxwq", int_x86_sse41_pmovzxwq>,
5174                                      VEX;
5175 }
5176
5177 let Predicates = [HasAVX2] in {
5178 defm VPMOVSXBD : SS41I_binop_rm_int8_y<0x21, "vpmovsxbd",
5179                                        int_x86_avx2_pmovsxbd>, VEX;
5180 defm VPMOVSXWQ : SS41I_binop_rm_int8_y<0x24, "vpmovsxwq",
5181                                        int_x86_avx2_pmovsxwq>, VEX;
5182 defm VPMOVZXBD : SS41I_binop_rm_int8_y<0x31, "vpmovzxbd",
5183                                        int_x86_avx2_pmovzxbd>, VEX;
5184 defm VPMOVZXWQ : SS41I_binop_rm_int8_y<0x34, "vpmovzxwq",
5185                                        int_x86_avx2_pmovzxwq>, VEX;
5186 }
5187
5188 defm PMOVSXBD   : SS41I_binop_rm_int4<0x21, "pmovsxbd", int_x86_sse41_pmovsxbd>;
5189 defm PMOVSXWQ   : SS41I_binop_rm_int4<0x24, "pmovsxwq", int_x86_sse41_pmovsxwq>;
5190 defm PMOVZXBD   : SS41I_binop_rm_int4<0x31, "pmovzxbd", int_x86_sse41_pmovzxbd>;
5191 defm PMOVZXWQ   : SS41I_binop_rm_int4<0x34, "pmovzxwq", int_x86_sse41_pmovzxwq>;
5192
5193 let Predicates = [HasAVX] in {
5194   // Common patterns involving scalar load
5195   def : Pat<(int_x86_sse41_pmovsxbd (vzmovl_v4i32 addr:$src)),
5196             (VPMOVSXBDrm addr:$src)>;
5197   def : Pat<(int_x86_sse41_pmovsxwq (vzmovl_v4i32 addr:$src)),
5198             (VPMOVSXWQrm addr:$src)>;
5199
5200   def : Pat<(int_x86_sse41_pmovzxbd (vzmovl_v4i32 addr:$src)),
5201             (VPMOVZXBDrm addr:$src)>;
5202   def : Pat<(int_x86_sse41_pmovzxwq (vzmovl_v4i32 addr:$src)),
5203             (VPMOVZXWQrm addr:$src)>;
5204 }
5205
5206 let Predicates = [HasSSE41] in {
5207   // Common patterns involving scalar load
5208   def : Pat<(int_x86_sse41_pmovsxbd (vzmovl_v4i32 addr:$src)),
5209             (PMOVSXBDrm addr:$src)>;
5210   def : Pat<(int_x86_sse41_pmovsxwq (vzmovl_v4i32 addr:$src)),
5211             (PMOVSXWQrm addr:$src)>;
5212
5213   def : Pat<(int_x86_sse41_pmovzxbd (vzmovl_v4i32 addr:$src)),
5214             (PMOVZXBDrm addr:$src)>;
5215   def : Pat<(int_x86_sse41_pmovzxwq (vzmovl_v4i32 addr:$src)),
5216             (PMOVZXWQrm addr:$src)>;
5217 }
5218
5219 multiclass SS41I_binop_rm_int2<bits<8> opc, string OpcodeStr, Intrinsic IntId> {
5220   def rr : SS48I<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
5221                  !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5222                  [(set VR128:$dst, (IntId VR128:$src))]>, OpSize;
5223
5224   // Expecting a i16 load any extended to i32 value.
5225   def rm : SS48I<opc, MRMSrcMem, (outs VR128:$dst), (ins i16mem:$src),
5226                  !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5227                  [(set VR128:$dst, (IntId (bitconvert
5228                      (v4i32 (scalar_to_vector (loadi16_anyext addr:$src))))))]>,
5229                  OpSize;
5230 }
5231
5232 multiclass SS41I_binop_rm_int4_y<bits<8> opc, string OpcodeStr,
5233                                  Intrinsic IntId> {
5234   def Yrr : SS48I<opc, MRMSrcReg, (outs VR256:$dst), (ins VR128:$src),
5235                  !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5236                  [(set VR256:$dst, (IntId VR128:$src))]>, OpSize;
5237
5238   // Expecting a i16 load any extended to i32 value.
5239   def Yrm : SS48I<opc, MRMSrcMem, (outs VR256:$dst), (ins i16mem:$src),
5240                   !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5241                   [(set VR256:$dst, (IntId (bitconvert
5242                       (v4i32 (scalar_to_vector (loadi32 addr:$src))))))]>,
5243                   OpSize;
5244 }
5245
5246 let Predicates = [HasAVX] in {
5247 defm VPMOVSXBQ : SS41I_binop_rm_int2<0x22, "vpmovsxbq", int_x86_sse41_pmovsxbq>,
5248                                      VEX;
5249 defm VPMOVZXBQ : SS41I_binop_rm_int2<0x32, "vpmovzxbq", int_x86_sse41_pmovzxbq>,
5250                                      VEX;
5251 }
5252 let Predicates = [HasAVX2] in {
5253 defm VPMOVSXBQ : SS41I_binop_rm_int4_y<0x22, "vpmovsxbq",
5254                                        int_x86_avx2_pmovsxbq>, VEX;
5255 defm VPMOVZXBQ : SS41I_binop_rm_int4_y<0x32, "vpmovzxbq",
5256                                        int_x86_avx2_pmovzxbq>, VEX;
5257 }
5258 defm PMOVSXBQ   : SS41I_binop_rm_int2<0x22, "pmovsxbq", int_x86_sse41_pmovsxbq>;
5259 defm PMOVZXBQ   : SS41I_binop_rm_int2<0x32, "pmovzxbq", int_x86_sse41_pmovzxbq>;
5260
5261 let Predicates = [HasAVX] in {
5262   // Common patterns involving scalar load
5263   def : Pat<(int_x86_sse41_pmovsxbq
5264               (bitconvert (v4i32 (X86vzmovl
5265                             (v4i32 (scalar_to_vector (loadi32 addr:$src))))))),
5266             (VPMOVSXBQrm addr:$src)>;
5267
5268   def : Pat<(int_x86_sse41_pmovzxbq
5269               (bitconvert (v4i32 (X86vzmovl
5270                             (v4i32 (scalar_to_vector (loadi32 addr:$src))))))),
5271             (VPMOVZXBQrm addr:$src)>;
5272 }
5273
5274 let Predicates = [HasSSE41] in {
5275   // Common patterns involving scalar load
5276   def : Pat<(int_x86_sse41_pmovsxbq
5277               (bitconvert (v4i32 (X86vzmovl
5278                             (v4i32 (scalar_to_vector (loadi32 addr:$src))))))),
5279             (PMOVSXBQrm addr:$src)>;
5280
5281   def : Pat<(int_x86_sse41_pmovzxbq
5282               (bitconvert (v4i32 (X86vzmovl
5283                             (v4i32 (scalar_to_vector (loadi32 addr:$src))))))),
5284             (PMOVZXBQrm addr:$src)>;
5285 }
5286
5287 //===----------------------------------------------------------------------===//
5288 // SSE4.1 - Extract Instructions
5289 //===----------------------------------------------------------------------===//
5290
5291 /// SS41I_binop_ext8 - SSE 4.1 extract 8 bits to 32 bit reg or 8 bit mem
5292 multiclass SS41I_extract8<bits<8> opc, string OpcodeStr> {
5293   def rr : SS4AIi8<opc, MRMDestReg, (outs GR32:$dst),
5294                  (ins VR128:$src1, i32i8imm:$src2),
5295                  !strconcat(OpcodeStr,
5296                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5297                  [(set GR32:$dst, (X86pextrb (v16i8 VR128:$src1), imm:$src2))]>,
5298                  OpSize;
5299   let neverHasSideEffects = 1, mayStore = 1 in
5300   def mr : SS4AIi8<opc, MRMDestMem, (outs),
5301                  (ins i8mem:$dst, VR128:$src1, i32i8imm:$src2),
5302                  !strconcat(OpcodeStr,
5303                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5304                  []>, OpSize;
5305 // FIXME:
5306 // There's an AssertZext in the way of writing the store pattern
5307 // (store (i8 (trunc (X86pextrb (v16i8 VR128:$src1), imm:$src2))), addr:$dst)
5308 }
5309
5310 let Predicates = [HasAVX] in {
5311   defm VPEXTRB : SS41I_extract8<0x14, "vpextrb">, VEX;
5312   def  VPEXTRBrr64 : SS4AIi8<0x14, MRMDestReg, (outs GR64:$dst),
5313          (ins VR128:$src1, i32i8imm:$src2),
5314          "vpextrb\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>, OpSize, VEX;
5315 }
5316
5317 defm PEXTRB      : SS41I_extract8<0x14, "pextrb">;
5318
5319
5320 /// SS41I_extract16 - SSE 4.1 extract 16 bits to memory destination
5321 multiclass SS41I_extract16<bits<8> opc, string OpcodeStr> {
5322   let neverHasSideEffects = 1, mayStore = 1 in
5323   def mr : SS4AIi8<opc, MRMDestMem, (outs),
5324                  (ins i16mem:$dst, VR128:$src1, i32i8imm:$src2),
5325                  !strconcat(OpcodeStr,
5326                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5327                  []>, OpSize;
5328 // FIXME:
5329 // There's an AssertZext in the way of writing the store pattern
5330 // (store (i16 (trunc (X86pextrw (v16i8 VR128:$src1), imm:$src2))), addr:$dst)
5331 }
5332
5333 let Predicates = [HasAVX] in
5334   defm VPEXTRW : SS41I_extract16<0x15, "vpextrw">, VEX;
5335
5336 defm PEXTRW      : SS41I_extract16<0x15, "pextrw">;
5337
5338
5339 /// SS41I_extract32 - SSE 4.1 extract 32 bits to int reg or memory destination
5340 multiclass SS41I_extract32<bits<8> opc, string OpcodeStr> {
5341   def rr : SS4AIi8<opc, MRMDestReg, (outs GR32:$dst),
5342                  (ins VR128:$src1, i32i8imm:$src2),
5343                  !strconcat(OpcodeStr,
5344                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5345                  [(set GR32:$dst,
5346                   (extractelt (v4i32 VR128:$src1), imm:$src2))]>, OpSize;
5347   def mr : SS4AIi8<opc, MRMDestMem, (outs),
5348                  (ins i32mem:$dst, VR128:$src1, i32i8imm:$src2),
5349                  !strconcat(OpcodeStr,
5350                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5351                  [(store (extractelt (v4i32 VR128:$src1), imm:$src2),
5352                           addr:$dst)]>, OpSize;
5353 }
5354
5355 let Predicates = [HasAVX] in
5356   defm VPEXTRD : SS41I_extract32<0x16, "vpextrd">, VEX;
5357
5358 defm PEXTRD      : SS41I_extract32<0x16, "pextrd">;
5359
5360 /// SS41I_extract32 - SSE 4.1 extract 32 bits to int reg or memory destination
5361 multiclass SS41I_extract64<bits<8> opc, string OpcodeStr> {
5362   def rr : SS4AIi8<opc, MRMDestReg, (outs GR64:$dst),
5363                  (ins VR128:$src1, i32i8imm:$src2),
5364                  !strconcat(OpcodeStr,
5365                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5366                  [(set GR64:$dst,
5367                   (extractelt (v2i64 VR128:$src1), imm:$src2))]>, OpSize, REX_W;
5368   def mr : SS4AIi8<opc, MRMDestMem, (outs),
5369                  (ins i64mem:$dst, VR128:$src1, i32i8imm:$src2),
5370                  !strconcat(OpcodeStr,
5371                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5372                  [(store (extractelt (v2i64 VR128:$src1), imm:$src2),
5373                           addr:$dst)]>, OpSize, REX_W;
5374 }
5375
5376 let Predicates = [HasAVX] in
5377   defm VPEXTRQ : SS41I_extract64<0x16, "vpextrq">, VEX, VEX_W;
5378
5379 defm PEXTRQ      : SS41I_extract64<0x16, "pextrq">;
5380
5381 /// SS41I_extractf32 - SSE 4.1 extract 32 bits fp value to int reg or memory
5382 /// destination
5383 multiclass SS41I_extractf32<bits<8> opc, string OpcodeStr> {
5384   def rr : SS4AIi8<opc, MRMDestReg, (outs GR32:$dst),
5385                  (ins VR128:$src1, i32i8imm:$src2),
5386                  !strconcat(OpcodeStr,
5387                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5388                  [(set GR32:$dst,
5389                     (extractelt (bc_v4i32 (v4f32 VR128:$src1)), imm:$src2))]>,
5390            OpSize;
5391   def mr : SS4AIi8<opc, MRMDestMem, (outs),
5392                  (ins f32mem:$dst, VR128:$src1, i32i8imm:$src2),
5393                  !strconcat(OpcodeStr,
5394                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5395                  [(store (extractelt (bc_v4i32 (v4f32 VR128:$src1)), imm:$src2),
5396                           addr:$dst)]>, OpSize;
5397 }
5398
5399 let ExeDomain = SSEPackedSingle in {
5400   let Predicates = [HasAVX] in {
5401     defm VEXTRACTPS : SS41I_extractf32<0x17, "vextractps">, VEX;
5402     def VEXTRACTPSrr64 : SS4AIi8<0x17, MRMDestReg, (outs GR64:$dst),
5403                     (ins VR128:$src1, i32i8imm:$src2),
5404                     "vextractps \t{$src2, $src1, $dst|$dst, $src1, $src2}",
5405                     []>, OpSize, VEX;
5406   }
5407   defm EXTRACTPS   : SS41I_extractf32<0x17, "extractps">;
5408 }
5409
5410 // Also match an EXTRACTPS store when the store is done as f32 instead of i32.
5411 def : Pat<(store (f32 (bitconvert (extractelt (bc_v4i32 (v4f32 VR128:$src1)),
5412                                               imm:$src2))),
5413                  addr:$dst),
5414           (VEXTRACTPSmr addr:$dst, VR128:$src1, imm:$src2)>,
5415           Requires<[HasAVX]>;
5416 def : Pat<(store (f32 (bitconvert (extractelt (bc_v4i32 (v4f32 VR128:$src1)),
5417                                               imm:$src2))),
5418                  addr:$dst),
5419           (EXTRACTPSmr addr:$dst, VR128:$src1, imm:$src2)>,
5420           Requires<[HasSSE41]>;
5421
5422 //===----------------------------------------------------------------------===//
5423 // SSE4.1 - Insert Instructions
5424 //===----------------------------------------------------------------------===//
5425
5426 multiclass SS41I_insert8<bits<8> opc, string asm, bit Is2Addr = 1> {
5427   def rr : SS4AIi8<opc, MRMSrcReg, (outs VR128:$dst),
5428       (ins VR128:$src1, GR32:$src2, i32i8imm:$src3),
5429       !if(Is2Addr,
5430         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5431         !strconcat(asm,
5432                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5433       [(set VR128:$dst,
5434         (X86pinsrb VR128:$src1, GR32:$src2, imm:$src3))]>, OpSize;
5435   def rm : SS4AIi8<opc, MRMSrcMem, (outs VR128:$dst),
5436       (ins VR128:$src1, i8mem:$src2, i32i8imm:$src3),
5437       !if(Is2Addr,
5438         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5439         !strconcat(asm,
5440                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5441       [(set VR128:$dst,
5442         (X86pinsrb VR128:$src1, (extloadi8 addr:$src2),
5443                    imm:$src3))]>, OpSize;
5444 }
5445
5446 let Predicates = [HasAVX] in
5447   defm VPINSRB : SS41I_insert8<0x20, "vpinsrb", 0>, VEX_4V;
5448 let Constraints = "$src1 = $dst" in
5449   defm PINSRB  : SS41I_insert8<0x20, "pinsrb">;
5450
5451 multiclass SS41I_insert32<bits<8> opc, string asm, bit Is2Addr = 1> {
5452   def rr : SS4AIi8<opc, MRMSrcReg, (outs VR128:$dst),
5453       (ins VR128:$src1, GR32:$src2, i32i8imm:$src3),
5454       !if(Is2Addr,
5455         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5456         !strconcat(asm,
5457                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5458       [(set VR128:$dst,
5459         (v4i32 (insertelt VR128:$src1, GR32:$src2, imm:$src3)))]>,
5460       OpSize;
5461   def rm : SS4AIi8<opc, MRMSrcMem, (outs VR128:$dst),
5462       (ins VR128:$src1, i32mem:$src2, i32i8imm:$src3),
5463       !if(Is2Addr,
5464         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5465         !strconcat(asm,
5466                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5467       [(set VR128:$dst,
5468         (v4i32 (insertelt VR128:$src1, (loadi32 addr:$src2),
5469                           imm:$src3)))]>, OpSize;
5470 }
5471
5472 let Predicates = [HasAVX] in
5473   defm VPINSRD : SS41I_insert32<0x22, "vpinsrd", 0>, VEX_4V;
5474 let Constraints = "$src1 = $dst" in
5475   defm PINSRD : SS41I_insert32<0x22, "pinsrd">;
5476
5477 multiclass SS41I_insert64<bits<8> opc, string asm, bit Is2Addr = 1> {
5478   def rr : SS4AIi8<opc, MRMSrcReg, (outs VR128:$dst),
5479       (ins VR128:$src1, GR64:$src2, i32i8imm:$src3),
5480       !if(Is2Addr,
5481         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5482         !strconcat(asm,
5483                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5484       [(set VR128:$dst,
5485         (v2i64 (insertelt VR128:$src1, GR64:$src2, imm:$src3)))]>,
5486       OpSize;
5487   def rm : SS4AIi8<opc, MRMSrcMem, (outs VR128:$dst),
5488       (ins VR128:$src1, i64mem:$src2, i32i8imm:$src3),
5489       !if(Is2Addr,
5490         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5491         !strconcat(asm,
5492                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5493       [(set VR128:$dst,
5494         (v2i64 (insertelt VR128:$src1, (loadi64 addr:$src2),
5495                           imm:$src3)))]>, OpSize;
5496 }
5497
5498 let Predicates = [HasAVX] in
5499   defm VPINSRQ : SS41I_insert64<0x22, "vpinsrq", 0>, VEX_4V, VEX_W;
5500 let Constraints = "$src1 = $dst" in
5501   defm PINSRQ : SS41I_insert64<0x22, "pinsrq">, REX_W;
5502
5503 // insertps has a few different modes, there's the first two here below which
5504 // are optimized inserts that won't zero arbitrary elements in the destination
5505 // vector. The next one matches the intrinsic and could zero arbitrary elements
5506 // in the target vector.
5507 multiclass SS41I_insertf32<bits<8> opc, string asm, bit Is2Addr = 1> {
5508   def rr : SS4AIi8<opc, MRMSrcReg, (outs VR128:$dst),
5509       (ins VR128:$src1, VR128:$src2, u32u8imm:$src3),
5510       !if(Is2Addr,
5511         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5512         !strconcat(asm,
5513                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5514       [(set VR128:$dst,
5515         (X86insrtps VR128:$src1, VR128:$src2, imm:$src3))]>,
5516       OpSize;
5517   def rm : SS4AIi8<opc, MRMSrcMem, (outs VR128:$dst),
5518       (ins VR128:$src1, f32mem:$src2, u32u8imm:$src3),
5519       !if(Is2Addr,
5520         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5521         !strconcat(asm,
5522                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5523       [(set VR128:$dst,
5524         (X86insrtps VR128:$src1,
5525                    (v4f32 (scalar_to_vector (loadf32 addr:$src2))),
5526                     imm:$src3))]>, OpSize;
5527 }
5528
5529 let ExeDomain = SSEPackedSingle in {
5530   let Predicates = [HasAVX] in
5531     defm VINSERTPS : SS41I_insertf32<0x21, "vinsertps", 0>, VEX_4V;
5532   let Constraints = "$src1 = $dst" in
5533     defm INSERTPS : SS41I_insertf32<0x21, "insertps">;
5534 }
5535
5536 //===----------------------------------------------------------------------===//
5537 // SSE4.1 - Round Instructions
5538 //===----------------------------------------------------------------------===//
5539
5540 multiclass sse41_fp_unop_rm<bits<8> opcps, bits<8> opcpd, string OpcodeStr,
5541                             X86MemOperand x86memop, RegisterClass RC,
5542                             PatFrag mem_frag32, PatFrag mem_frag64,
5543                             Intrinsic V4F32Int, Intrinsic V2F64Int> {
5544 let ExeDomain = SSEPackedSingle in {
5545   // Intrinsic operation, reg.
5546   // Vector intrinsic operation, reg
5547   def PSr : SS4AIi8<opcps, MRMSrcReg,
5548                     (outs RC:$dst), (ins RC:$src1, i32i8imm:$src2),
5549                     !strconcat(OpcodeStr,
5550                     "ps\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5551                     [(set RC:$dst, (V4F32Int RC:$src1, imm:$src2))]>,
5552                     OpSize;
5553
5554   // Vector intrinsic operation, mem
5555   def PSm : SS4AIi8<opcps, MRMSrcMem,
5556                     (outs RC:$dst), (ins x86memop:$src1, i32i8imm:$src2),
5557                     !strconcat(OpcodeStr,
5558                     "ps\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5559                     [(set RC:$dst,
5560                           (V4F32Int (mem_frag32 addr:$src1),imm:$src2))]>,
5561                     OpSize;
5562 } // ExeDomain = SSEPackedSingle
5563
5564 let ExeDomain = SSEPackedDouble in {
5565   // Vector intrinsic operation, reg
5566   def PDr : SS4AIi8<opcpd, MRMSrcReg,
5567                     (outs RC:$dst), (ins RC:$src1, i32i8imm:$src2),
5568                     !strconcat(OpcodeStr,
5569                     "pd\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5570                     [(set RC:$dst, (V2F64Int RC:$src1, imm:$src2))]>,
5571                     OpSize;
5572
5573   // Vector intrinsic operation, mem
5574   def PDm : SS4AIi8<opcpd, MRMSrcMem,
5575                     (outs RC:$dst), (ins x86memop:$src1, i32i8imm:$src2),
5576                     !strconcat(OpcodeStr,
5577                     "pd\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5578                     [(set RC:$dst,
5579                           (V2F64Int (mem_frag64 addr:$src1),imm:$src2))]>,
5580                     OpSize;
5581 } // ExeDomain = SSEPackedDouble
5582 }
5583
5584 multiclass sse41_fp_binop_rm<bits<8> opcss, bits<8> opcsd,
5585                             string OpcodeStr,
5586                             Intrinsic F32Int,
5587                             Intrinsic F64Int, bit Is2Addr = 1> {
5588 let ExeDomain = GenericDomain in {
5589   // Operation, reg.
5590   def SSr : SS4AIi8<opcss, MRMSrcReg,
5591       (outs FR32:$dst), (ins FR32:$src1, FR32:$src2, i32i8imm:$src3),
5592       !if(Is2Addr,
5593           !strconcat(OpcodeStr,
5594               "ss\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5595           !strconcat(OpcodeStr,
5596               "ss\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5597       []>, OpSize;
5598
5599   // Intrinsic operation, reg.
5600   def SSr_Int : SS4AIi8<opcss, MRMSrcReg,
5601         (outs VR128:$dst), (ins VR128:$src1, VR128:$src2, i32i8imm:$src3),
5602         !if(Is2Addr,
5603             !strconcat(OpcodeStr,
5604                 "ss\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5605             !strconcat(OpcodeStr,
5606                 "ss\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5607         [(set VR128:$dst, (F32Int VR128:$src1, VR128:$src2, imm:$src3))]>,
5608         OpSize;
5609
5610   // Intrinsic operation, mem.
5611   def SSm : SS4AIi8<opcss, MRMSrcMem,
5612         (outs VR128:$dst), (ins VR128:$src1, ssmem:$src2, i32i8imm:$src3),
5613         !if(Is2Addr,
5614             !strconcat(OpcodeStr,
5615                 "ss\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5616             !strconcat(OpcodeStr,
5617                 "ss\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5618         [(set VR128:$dst,
5619              (F32Int VR128:$src1, sse_load_f32:$src2, imm:$src3))]>,
5620         OpSize;
5621
5622   // Operation, reg.
5623   def SDr : SS4AIi8<opcsd, MRMSrcReg,
5624         (outs FR64:$dst), (ins FR64:$src1, FR64:$src2, i32i8imm:$src3),
5625         !if(Is2Addr,
5626             !strconcat(OpcodeStr,
5627                 "sd\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5628             !strconcat(OpcodeStr,
5629                 "sd\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5630         []>, OpSize;
5631
5632   // Intrinsic operation, reg.
5633   def SDr_Int : SS4AIi8<opcsd, MRMSrcReg,
5634         (outs VR128:$dst), (ins VR128:$src1, VR128:$src2, i32i8imm:$src3),
5635         !if(Is2Addr,
5636             !strconcat(OpcodeStr,
5637                 "sd\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5638             !strconcat(OpcodeStr,
5639                 "sd\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5640         [(set VR128:$dst, (F64Int VR128:$src1, VR128:$src2, imm:$src3))]>,
5641         OpSize;
5642
5643   // Intrinsic operation, mem.
5644   def SDm : SS4AIi8<opcsd, MRMSrcMem,
5645         (outs VR128:$dst), (ins VR128:$src1, sdmem:$src2, i32i8imm:$src3),
5646         !if(Is2Addr,
5647             !strconcat(OpcodeStr,
5648                 "sd\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5649             !strconcat(OpcodeStr,
5650                 "sd\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5651         [(set VR128:$dst,
5652               (F64Int VR128:$src1, sse_load_f64:$src2, imm:$src3))]>,
5653         OpSize;
5654 } // ExeDomain = GenericDomain
5655 }
5656
5657 // FP round - roundss, roundps, roundsd, roundpd
5658 let Predicates = [HasAVX] in {
5659   // Intrinsic form
5660   defm VROUND  : sse41_fp_unop_rm<0x08, 0x09, "vround", f128mem, VR128,
5661                                   memopv4f32, memopv2f64,
5662                                   int_x86_sse41_round_ps,
5663                                   int_x86_sse41_round_pd>, VEX;
5664   defm VROUNDY : sse41_fp_unop_rm<0x08, 0x09, "vround", f256mem, VR256,
5665                                   memopv8f32, memopv4f64,
5666                                   int_x86_avx_round_ps_256,
5667                                   int_x86_avx_round_pd_256>, VEX;
5668   defm VROUND  : sse41_fp_binop_rm<0x0A, 0x0B, "vround",
5669                                   int_x86_sse41_round_ss,
5670                                   int_x86_sse41_round_sd, 0>, VEX_4V, VEX_LIG;
5671
5672   def : Pat<(ffloor FR32:$src),
5673             (VROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x1))>;
5674   def : Pat<(f64 (ffloor FR64:$src)),
5675             (VROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x1))>;
5676   def : Pat<(f32 (fnearbyint FR32:$src)),
5677             (VROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0xC))>;
5678   def : Pat<(f64 (fnearbyint FR64:$src)),
5679             (VROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0xC))>;
5680   def : Pat<(f32 (fceil FR32:$src)),
5681             (VROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x2))>;
5682   def : Pat<(f64 (fceil FR64:$src)),
5683             (VROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x2))>;
5684   def : Pat<(f32 (frint FR32:$src)),
5685             (VROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x4))>;
5686   def : Pat<(f64 (frint FR64:$src)),
5687             (VROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x4))>;
5688   def : Pat<(f32 (ftrunc FR32:$src)),
5689             (VROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x3))>;
5690   def : Pat<(f64 (ftrunc FR64:$src)),
5691             (VROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x3))>;
5692 }
5693
5694 defm ROUND  : sse41_fp_unop_rm<0x08, 0x09, "round", f128mem, VR128,
5695                                memopv4f32, memopv2f64,
5696                                int_x86_sse41_round_ps, int_x86_sse41_round_pd>;
5697 let Constraints = "$src1 = $dst" in
5698 defm ROUND  : sse41_fp_binop_rm<0x0A, 0x0B, "round",
5699                                int_x86_sse41_round_ss, int_x86_sse41_round_sd>;
5700
5701 def : Pat<(ffloor FR32:$src),
5702           (ROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x1))>;
5703 def : Pat<(f64 (ffloor FR64:$src)),
5704           (ROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x1))>;
5705 def : Pat<(f32 (fnearbyint FR32:$src)),
5706           (ROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0xC))>;
5707 def : Pat<(f64 (fnearbyint FR64:$src)),
5708           (ROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0xC))>;
5709 def : Pat<(f32 (fceil FR32:$src)),
5710           (ROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x2))>;
5711 def : Pat<(f64 (fceil FR64:$src)),
5712           (ROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x2))>;
5713 def : Pat<(f32 (frint FR32:$src)),
5714           (ROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x4))>;
5715 def : Pat<(f64 (frint FR64:$src)),
5716           (ROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x4))>;
5717 def : Pat<(f32 (ftrunc FR32:$src)),
5718           (ROUNDSSr (f32 (IMPLICIT_DEF)), FR32:$src, (i32 0x3))>;
5719 def : Pat<(f64 (ftrunc FR64:$src)),
5720           (ROUNDSDr (f64 (IMPLICIT_DEF)), FR64:$src, (i32 0x3))>;
5721
5722 //===----------------------------------------------------------------------===//
5723 // SSE4.1 - Packed Bit Test
5724 //===----------------------------------------------------------------------===//
5725
5726 // ptest instruction we'll lower to this in X86ISelLowering primarily from
5727 // the intel intrinsic that corresponds to this.
5728 let Defs = [EFLAGS], Predicates = [HasAVX] in {
5729 def VPTESTrr  : SS48I<0x17, MRMSrcReg, (outs), (ins VR128:$src1, VR128:$src2),
5730                 "vptest\t{$src2, $src1|$src1, $src2}",
5731                 [(set EFLAGS, (X86ptest VR128:$src1, (v4f32 VR128:$src2)))]>,
5732                 OpSize, VEX;
5733 def VPTESTrm  : SS48I<0x17, MRMSrcMem, (outs), (ins VR128:$src1, f128mem:$src2),
5734                 "vptest\t{$src2, $src1|$src1, $src2}",
5735                 [(set EFLAGS,(X86ptest VR128:$src1, (memopv4f32 addr:$src2)))]>,
5736                 OpSize, VEX;
5737
5738 def VPTESTYrr : SS48I<0x17, MRMSrcReg, (outs), (ins VR256:$src1, VR256:$src2),
5739                 "vptest\t{$src2, $src1|$src1, $src2}",
5740                 [(set EFLAGS, (X86ptest VR256:$src1, (v4i64 VR256:$src2)))]>,
5741                 OpSize, VEX;
5742 def VPTESTYrm : SS48I<0x17, MRMSrcMem, (outs), (ins VR256:$src1, i256mem:$src2),
5743                 "vptest\t{$src2, $src1|$src1, $src2}",
5744                 [(set EFLAGS,(X86ptest VR256:$src1, (memopv4i64 addr:$src2)))]>,
5745                 OpSize, VEX;
5746 }
5747
5748 let Defs = [EFLAGS] in {
5749 def PTESTrr : SS48I<0x17, MRMSrcReg, (outs), (ins VR128:$src1, VR128:$src2),
5750               "ptest\t{$src2, $src1|$src1, $src2}",
5751               [(set EFLAGS, (X86ptest VR128:$src1, (v4f32 VR128:$src2)))]>,
5752               OpSize;
5753 def PTESTrm : SS48I<0x17, MRMSrcMem, (outs), (ins VR128:$src1, f128mem:$src2),
5754               "ptest\t{$src2, $src1|$src1, $src2}",
5755               [(set EFLAGS, (X86ptest VR128:$src1, (memopv4f32 addr:$src2)))]>,
5756               OpSize;
5757 }
5758
5759 // The bit test instructions below are AVX only
5760 multiclass avx_bittest<bits<8> opc, string OpcodeStr, RegisterClass RC,
5761                        X86MemOperand x86memop, PatFrag mem_frag, ValueType vt> {
5762   def rr : SS48I<opc, MRMSrcReg, (outs), (ins RC:$src1, RC:$src2),
5763             !strconcat(OpcodeStr, "\t{$src2, $src1|$src1, $src2}"),
5764             [(set EFLAGS, (X86testp RC:$src1, (vt RC:$src2)))]>, OpSize, VEX;
5765   def rm : SS48I<opc, MRMSrcMem, (outs), (ins RC:$src1, x86memop:$src2),
5766             !strconcat(OpcodeStr, "\t{$src2, $src1|$src1, $src2}"),
5767             [(set EFLAGS, (X86testp RC:$src1, (mem_frag addr:$src2)))]>,
5768             OpSize, VEX;
5769 }
5770
5771 let Defs = [EFLAGS], Predicates = [HasAVX] in {
5772 let ExeDomain = SSEPackedSingle in {
5773 defm VTESTPS  : avx_bittest<0x0E, "vtestps", VR128, f128mem, memopv4f32, v4f32>;
5774 defm VTESTPSY : avx_bittest<0x0E, "vtestps", VR256, f256mem, memopv8f32, v8f32>;
5775 }
5776 let ExeDomain = SSEPackedDouble in {
5777 defm VTESTPD  : avx_bittest<0x0F, "vtestpd", VR128, f128mem, memopv2f64, v2f64>;
5778 defm VTESTPDY : avx_bittest<0x0F, "vtestpd", VR256, f256mem, memopv4f64, v4f64>;
5779 }
5780 }
5781
5782 //===----------------------------------------------------------------------===//
5783 // SSE4.1 - Misc Instructions
5784 //===----------------------------------------------------------------------===//
5785
5786 let Defs = [EFLAGS], Predicates = [HasPOPCNT] in {
5787   def POPCNT16rr : I<0xB8, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
5788                      "popcnt{w}\t{$src, $dst|$dst, $src}",
5789                      [(set GR16:$dst, (ctpop GR16:$src)), (implicit EFLAGS)]>,
5790                      OpSize, XS;
5791   def POPCNT16rm : I<0xB8, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
5792                      "popcnt{w}\t{$src, $dst|$dst, $src}",
5793                      [(set GR16:$dst, (ctpop (loadi16 addr:$src))),
5794                       (implicit EFLAGS)]>, OpSize, XS;
5795
5796   def POPCNT32rr : I<0xB8, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
5797                      "popcnt{l}\t{$src, $dst|$dst, $src}",
5798                      [(set GR32:$dst, (ctpop GR32:$src)), (implicit EFLAGS)]>,
5799                      XS;
5800   def POPCNT32rm : I<0xB8, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
5801                      "popcnt{l}\t{$src, $dst|$dst, $src}",
5802                      [(set GR32:$dst, (ctpop (loadi32 addr:$src))),
5803                       (implicit EFLAGS)]>, XS;
5804
5805   def POPCNT64rr : RI<0xB8, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
5806                       "popcnt{q}\t{$src, $dst|$dst, $src}",
5807                       [(set GR64:$dst, (ctpop GR64:$src)), (implicit EFLAGS)]>,
5808                       XS;
5809   def POPCNT64rm : RI<0xB8, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
5810                       "popcnt{q}\t{$src, $dst|$dst, $src}",
5811                       [(set GR64:$dst, (ctpop (loadi64 addr:$src))),
5812                        (implicit EFLAGS)]>, XS;
5813 }
5814
5815
5816
5817 // SS41I_unop_rm_int_v16 - SSE 4.1 unary operator whose type is v8i16.
5818 multiclass SS41I_unop_rm_int_v16<bits<8> opc, string OpcodeStr,
5819                                  Intrinsic IntId128> {
5820   def rr128 : SS48I<opc, MRMSrcReg, (outs VR128:$dst),
5821                     (ins VR128:$src),
5822                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5823                     [(set VR128:$dst, (IntId128 VR128:$src))]>, OpSize;
5824   def rm128 : SS48I<opc, MRMSrcMem, (outs VR128:$dst),
5825                      (ins i128mem:$src),
5826                      !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5827                      [(set VR128:$dst,
5828                        (IntId128
5829                         (bitconvert (memopv2i64 addr:$src))))]>, OpSize;
5830 }
5831
5832 let Predicates = [HasAVX] in
5833 defm VPHMINPOSUW : SS41I_unop_rm_int_v16 <0x41, "vphminposuw",
5834                                          int_x86_sse41_phminposuw>, VEX;
5835 defm PHMINPOSUW : SS41I_unop_rm_int_v16 <0x41, "phminposuw",
5836                                          int_x86_sse41_phminposuw>;
5837
5838 /// SS41I_binop_rm_int - Simple SSE 4.1 binary operator
5839 multiclass SS41I_binop_rm_int<bits<8> opc, string OpcodeStr,
5840                               Intrinsic IntId128, bit Is2Addr = 1> {
5841   let isCommutable = 1 in
5842   def rr : SS48I<opc, MRMSrcReg, (outs VR128:$dst),
5843        (ins VR128:$src1, VR128:$src2),
5844        !if(Is2Addr,
5845            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5846            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5847        [(set VR128:$dst, (IntId128 VR128:$src1, VR128:$src2))]>, OpSize;
5848   def rm : SS48I<opc, MRMSrcMem, (outs VR128:$dst),
5849        (ins VR128:$src1, i128mem:$src2),
5850        !if(Is2Addr,
5851            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5852            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5853        [(set VR128:$dst,
5854          (IntId128 VR128:$src1,
5855           (bitconvert (memopv2i64 addr:$src2))))]>, OpSize;
5856 }
5857
5858 /// SS41I_binop_rm_int - Simple SSE 4.1 binary operator
5859 multiclass SS41I_binop_rm_int_y<bits<8> opc, string OpcodeStr,
5860                                 Intrinsic IntId256> {
5861   let isCommutable = 1 in
5862   def Yrr : SS48I<opc, MRMSrcReg, (outs VR256:$dst),
5863        (ins VR256:$src1, VR256:$src2),
5864        !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5865        [(set VR256:$dst, (IntId256 VR256:$src1, VR256:$src2))]>, OpSize;
5866   def Yrm : SS48I<opc, MRMSrcMem, (outs VR256:$dst),
5867        (ins VR256:$src1, i256mem:$src2),
5868        !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5869        [(set VR256:$dst,
5870          (IntId256 VR256:$src1,
5871           (bitconvert (memopv4i64 addr:$src2))))]>, OpSize;
5872 }
5873
5874 let Predicates = [HasAVX] in {
5875   let isCommutable = 0 in
5876   defm VPACKUSDW : SS41I_binop_rm_int<0x2B, "vpackusdw", int_x86_sse41_packusdw,
5877                                                          0>, VEX_4V;
5878   defm VPMINSB   : SS41I_binop_rm_int<0x38, "vpminsb",   int_x86_sse41_pminsb,
5879                                                          0>, VEX_4V;
5880   defm VPMINSD   : SS41I_binop_rm_int<0x39, "vpminsd",   int_x86_sse41_pminsd,
5881                                                          0>, VEX_4V;
5882   defm VPMINUD   : SS41I_binop_rm_int<0x3B, "vpminud",   int_x86_sse41_pminud,
5883                                                          0>, VEX_4V;
5884   defm VPMINUW   : SS41I_binop_rm_int<0x3A, "vpminuw",   int_x86_sse41_pminuw,
5885                                                          0>, VEX_4V;
5886   defm VPMAXSB   : SS41I_binop_rm_int<0x3C, "vpmaxsb",   int_x86_sse41_pmaxsb,
5887                                                          0>, VEX_4V;
5888   defm VPMAXSD   : SS41I_binop_rm_int<0x3D, "vpmaxsd",   int_x86_sse41_pmaxsd,
5889                                                          0>, VEX_4V;
5890   defm VPMAXUD   : SS41I_binop_rm_int<0x3F, "vpmaxud",   int_x86_sse41_pmaxud,
5891                                                          0>, VEX_4V;
5892   defm VPMAXUW   : SS41I_binop_rm_int<0x3E, "vpmaxuw",   int_x86_sse41_pmaxuw,
5893                                                          0>, VEX_4V;
5894   defm VPMULDQ   : SS41I_binop_rm_int<0x28, "vpmuldq",   int_x86_sse41_pmuldq,
5895                                                          0>, VEX_4V;
5896 }
5897
5898 let Predicates = [HasAVX2] in {
5899   let isCommutable = 0 in
5900   defm VPACKUSDW : SS41I_binop_rm_int_y<0x2B, "vpackusdw",
5901                                         int_x86_avx2_packusdw>, VEX_4V;
5902   defm VPMINSB   : SS41I_binop_rm_int_y<0x38, "vpminsb",
5903                                         int_x86_avx2_pmins_b>, VEX_4V;
5904   defm VPMINSD   : SS41I_binop_rm_int_y<0x39, "vpminsd",
5905                                         int_x86_avx2_pmins_d>, VEX_4V;
5906   defm VPMINUD   : SS41I_binop_rm_int_y<0x3B, "vpminud",
5907                                         int_x86_avx2_pminu_d>, VEX_4V;
5908   defm VPMINUW   : SS41I_binop_rm_int_y<0x3A, "vpminuw",
5909                                         int_x86_avx2_pminu_w>, VEX_4V;
5910   defm VPMAXSB   : SS41I_binop_rm_int_y<0x3C, "vpmaxsb",
5911                                         int_x86_avx2_pmaxs_b>, VEX_4V;
5912   defm VPMAXSD   : SS41I_binop_rm_int_y<0x3D, "vpmaxsd",
5913                                         int_x86_avx2_pmaxs_d>, VEX_4V;
5914   defm VPMAXUD   : SS41I_binop_rm_int_y<0x3F, "vpmaxud",
5915                                         int_x86_avx2_pmaxu_d>, VEX_4V;
5916   defm VPMAXUW   : SS41I_binop_rm_int_y<0x3E, "vpmaxuw",
5917                                         int_x86_avx2_pmaxu_w>, VEX_4V;
5918   defm VPMULDQ   : SS41I_binop_rm_int_y<0x28, "vpmuldq",
5919                                         int_x86_avx2_pmul_dq>, VEX_4V;
5920 }
5921
5922 let Constraints = "$src1 = $dst" in {
5923   let isCommutable = 0 in
5924   defm PACKUSDW : SS41I_binop_rm_int<0x2B, "packusdw", int_x86_sse41_packusdw>;
5925   defm PMINSB   : SS41I_binop_rm_int<0x38, "pminsb",   int_x86_sse41_pminsb>;
5926   defm PMINSD   : SS41I_binop_rm_int<0x39, "pminsd",   int_x86_sse41_pminsd>;
5927   defm PMINUD   : SS41I_binop_rm_int<0x3B, "pminud",   int_x86_sse41_pminud>;
5928   defm PMINUW   : SS41I_binop_rm_int<0x3A, "pminuw",   int_x86_sse41_pminuw>;
5929   defm PMAXSB   : SS41I_binop_rm_int<0x3C, "pmaxsb",   int_x86_sse41_pmaxsb>;
5930   defm PMAXSD   : SS41I_binop_rm_int<0x3D, "pmaxsd",   int_x86_sse41_pmaxsd>;
5931   defm PMAXUD   : SS41I_binop_rm_int<0x3F, "pmaxud",   int_x86_sse41_pmaxud>;
5932   defm PMAXUW   : SS41I_binop_rm_int<0x3E, "pmaxuw",   int_x86_sse41_pmaxuw>;
5933   defm PMULDQ   : SS41I_binop_rm_int<0x28, "pmuldq",   int_x86_sse41_pmuldq>;
5934 }
5935
5936 /// SS48I_binop_rm - Simple SSE41 binary operator.
5937 multiclass SS48I_binop_rm<bits<8> opc, string OpcodeStr, SDNode OpNode,
5938                           ValueType OpVT, RegisterClass RC, PatFrag memop_frag,
5939                           X86MemOperand x86memop, bit Is2Addr = 1> {
5940   let isCommutable = 1 in
5941   def rr : SS48I<opc, MRMSrcReg, (outs RC:$dst),
5942        (ins RC:$src1, RC:$src2),
5943        !if(Is2Addr,
5944            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5945            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5946        [(set RC:$dst, (OpVT (OpNode RC:$src1, RC:$src2)))]>, OpSize;
5947   def rm : SS48I<opc, MRMSrcMem, (outs RC:$dst),
5948        (ins RC:$src1, x86memop:$src2),
5949        !if(Is2Addr,
5950            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5951            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5952        [(set RC:$dst,
5953          (OpVT (OpNode RC:$src1,
5954           (bitconvert (memop_frag addr:$src2)))))]>, OpSize;
5955 }
5956
5957 let Predicates = [HasAVX] in {
5958   defm VPMULLD  : SS48I_binop_rm<0x40, "vpmulld", mul, v4i32, VR128,
5959                                 memopv2i64, i128mem, 0>, VEX_4V;
5960   defm VPCMPEQQ : SS48I_binop_rm<0x29, "vpcmpeqq", X86pcmpeq, v2i64, VR128,
5961                                  memopv2i64, i128mem, 0>, VEX_4V;
5962 }
5963 let Predicates = [HasAVX2] in {
5964   defm VPMULLDY  : SS48I_binop_rm<0x40, "vpmulld", mul, v8i32, VR256,
5965                                   memopv4i64, i256mem, 0>, VEX_4V;
5966   defm VPCMPEQQY : SS48I_binop_rm<0x29, "vpcmpeqq", X86pcmpeq, v4i64, VR256,
5967                                   memopv4i64, i256mem, 0>, VEX_4V;
5968 }
5969
5970 let Constraints = "$src1 = $dst" in {
5971   defm PMULLD  : SS48I_binop_rm<0x40, "pmulld", mul, v4i32, VR128,
5972                                 memopv2i64, i128mem>;
5973   defm PCMPEQQ : SS48I_binop_rm<0x29, "pcmpeqq", X86pcmpeq, v2i64, VR128,
5974                                 memopv2i64, i128mem>;
5975 }
5976
5977 /// SS41I_binop_rmi_int - SSE 4.1 binary operator with 8-bit immediate
5978 multiclass SS41I_binop_rmi_int<bits<8> opc, string OpcodeStr,
5979                  Intrinsic IntId, RegisterClass RC, PatFrag memop_frag,
5980                  X86MemOperand x86memop, bit Is2Addr = 1> {
5981   let isCommutable = 1 in
5982   def rri : SS4AIi8<opc, MRMSrcReg, (outs RC:$dst),
5983         (ins RC:$src1, RC:$src2, u32u8imm:$src3),
5984         !if(Is2Addr,
5985             !strconcat(OpcodeStr,
5986                 "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5987             !strconcat(OpcodeStr,
5988                 "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5989         [(set RC:$dst, (IntId RC:$src1, RC:$src2, imm:$src3))]>,
5990         OpSize;
5991   def rmi : SS4AIi8<opc, MRMSrcMem, (outs RC:$dst),
5992         (ins RC:$src1, x86memop:$src2, u32u8imm:$src3),
5993         !if(Is2Addr,
5994             !strconcat(OpcodeStr,
5995                 "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5996             !strconcat(OpcodeStr,
5997                 "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5998         [(set RC:$dst,
5999           (IntId RC:$src1,
6000            (bitconvert (memop_frag addr:$src2)), imm:$src3))]>,
6001         OpSize;
6002 }
6003
6004 let Predicates = [HasAVX] in {
6005   let isCommutable = 0 in {
6006     let ExeDomain = SSEPackedSingle in {
6007     defm VBLENDPS : SS41I_binop_rmi_int<0x0C, "vblendps", int_x86_sse41_blendps,
6008                                         VR128, memopv4f32, i128mem, 0>, VEX_4V;
6009     defm VBLENDPSY : SS41I_binop_rmi_int<0x0C, "vblendps",
6010               int_x86_avx_blend_ps_256, VR256, memopv8f32, i256mem, 0>, VEX_4V;
6011     }
6012     let ExeDomain = SSEPackedDouble in {
6013     defm VBLENDPD : SS41I_binop_rmi_int<0x0D, "vblendpd", int_x86_sse41_blendpd,
6014                                         VR128, memopv2f64, i128mem, 0>, VEX_4V;
6015     defm VBLENDPDY : SS41I_binop_rmi_int<0x0D, "vblendpd",
6016               int_x86_avx_blend_pd_256, VR256, memopv4f64, i256mem, 0>, VEX_4V;
6017     }
6018   defm VPBLENDW : SS41I_binop_rmi_int<0x0E, "vpblendw", int_x86_sse41_pblendw,
6019                                       VR128, memopv2i64, i128mem, 0>, VEX_4V;
6020   defm VMPSADBW : SS41I_binop_rmi_int<0x42, "vmpsadbw", int_x86_sse41_mpsadbw,
6021                                       VR128, memopv2i64, i128mem, 0>, VEX_4V;
6022   }
6023   let ExeDomain = SSEPackedSingle in
6024   defm VDPPS : SS41I_binop_rmi_int<0x40, "vdpps", int_x86_sse41_dpps,
6025                                    VR128, memopv4f32, i128mem, 0>, VEX_4V;
6026   let ExeDomain = SSEPackedDouble in
6027   defm VDPPD : SS41I_binop_rmi_int<0x41, "vdppd", int_x86_sse41_dppd,
6028                                    VR128, memopv2f64, i128mem, 0>, VEX_4V;
6029   let ExeDomain = SSEPackedSingle in
6030   defm VDPPSY : SS41I_binop_rmi_int<0x40, "vdpps", int_x86_avx_dp_ps_256,
6031                                    VR256, memopv8f32, i256mem, 0>, VEX_4V;
6032 }
6033
6034 let Predicates = [HasAVX2] in {
6035   let isCommutable = 0 in {
6036   defm VPBLENDWY : SS41I_binop_rmi_int<0x0E, "vpblendw", int_x86_avx2_pblendw,
6037                                        VR256, memopv4i64, i256mem, 0>, VEX_4V;
6038   defm VMPSADBWY : SS41I_binop_rmi_int<0x42, "vmpsadbw", int_x86_avx2_mpsadbw,
6039                                        VR256, memopv4i64, i256mem, 0>, VEX_4V;
6040   }
6041 }
6042
6043 let Constraints = "$src1 = $dst" in {
6044   let isCommutable = 0 in {
6045   let ExeDomain = SSEPackedSingle in
6046   defm BLENDPS : SS41I_binop_rmi_int<0x0C, "blendps", int_x86_sse41_blendps,
6047                                      VR128, memopv4f32, i128mem>;
6048   let ExeDomain = SSEPackedDouble in
6049   defm BLENDPD : SS41I_binop_rmi_int<0x0D, "blendpd", int_x86_sse41_blendpd,
6050                                      VR128, memopv2f64, i128mem>;
6051   defm PBLENDW : SS41I_binop_rmi_int<0x0E, "pblendw", int_x86_sse41_pblendw,
6052                                      VR128, memopv2i64, i128mem>;
6053   defm MPSADBW : SS41I_binop_rmi_int<0x42, "mpsadbw", int_x86_sse41_mpsadbw,
6054                                      VR128, memopv2i64, i128mem>;
6055   }
6056   let ExeDomain = SSEPackedSingle in
6057   defm DPPS : SS41I_binop_rmi_int<0x40, "dpps", int_x86_sse41_dpps,
6058                                   VR128, memopv4f32, i128mem>;
6059   let ExeDomain = SSEPackedDouble in
6060   defm DPPD : SS41I_binop_rmi_int<0x41, "dppd", int_x86_sse41_dppd,
6061                                   VR128, memopv2f64, i128mem>;
6062 }
6063
6064 /// SS41I_quaternary_int_avx - AVX SSE 4.1 with 4 operators
6065 multiclass SS41I_quaternary_int_avx<bits<8> opc, string OpcodeStr,
6066                                     RegisterClass RC, X86MemOperand x86memop,
6067                                     PatFrag mem_frag, Intrinsic IntId> {
6068   def rr : Ii8<opc, MRMSrcReg, (outs RC:$dst),
6069                   (ins RC:$src1, RC:$src2, RC:$src3),
6070                   !strconcat(OpcodeStr,
6071                     "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
6072                   [(set RC:$dst, (IntId RC:$src1, RC:$src2, RC:$src3))],
6073                   IIC_DEFAULT, SSEPackedInt>, OpSize, TA, VEX_4V, VEX_I8IMM;
6074
6075   def rm : Ii8<opc, MRMSrcMem, (outs RC:$dst),
6076                   (ins RC:$src1, x86memop:$src2, RC:$src3),
6077                   !strconcat(OpcodeStr,
6078                     "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
6079                   [(set RC:$dst,
6080                         (IntId RC:$src1, (bitconvert (mem_frag addr:$src2)),
6081                                RC:$src3))],
6082                   IIC_DEFAULT, SSEPackedInt>, OpSize, TA, VEX_4V, VEX_I8IMM;
6083 }
6084
6085 let Predicates = [HasAVX] in {
6086 let ExeDomain = SSEPackedDouble in {
6087 defm VBLENDVPD  : SS41I_quaternary_int_avx<0x4B, "vblendvpd", VR128, i128mem,
6088                                            memopv2f64, int_x86_sse41_blendvpd>;
6089 defm VBLENDVPDY : SS41I_quaternary_int_avx<0x4B, "vblendvpd", VR256, i256mem,
6090                                          memopv4f64, int_x86_avx_blendv_pd_256>;
6091 } // ExeDomain = SSEPackedDouble
6092 let ExeDomain = SSEPackedSingle in {
6093 defm VBLENDVPS  : SS41I_quaternary_int_avx<0x4A, "vblendvps", VR128, i128mem,
6094                                            memopv4f32, int_x86_sse41_blendvps>;
6095 defm VBLENDVPSY : SS41I_quaternary_int_avx<0x4A, "vblendvps", VR256, i256mem,
6096                                          memopv8f32, int_x86_avx_blendv_ps_256>;
6097 } // ExeDomain = SSEPackedSingle
6098 defm VPBLENDVB  : SS41I_quaternary_int_avx<0x4C, "vpblendvb", VR128, i128mem,
6099                                            memopv2i64, int_x86_sse41_pblendvb>;
6100 }
6101
6102 let Predicates = [HasAVX2] in {
6103 defm VPBLENDVBY : SS41I_quaternary_int_avx<0x4C, "vpblendvb", VR256, i256mem,
6104                                            memopv4i64, int_x86_avx2_pblendvb>;
6105 }
6106
6107 let Predicates = [HasAVX] in {
6108   def : Pat<(v16i8 (vselect (v16i8 VR128:$mask), (v16i8 VR128:$src1),
6109                             (v16i8 VR128:$src2))),
6110             (VPBLENDVBrr VR128:$src2, VR128:$src1, VR128:$mask)>;
6111   def : Pat<(v4i32 (vselect (v4i32 VR128:$mask), (v4i32 VR128:$src1),
6112                             (v4i32 VR128:$src2))),
6113             (VBLENDVPSrr VR128:$src2, VR128:$src1, VR128:$mask)>;
6114   def : Pat<(v4f32 (vselect (v4i32 VR128:$mask), (v4f32 VR128:$src1),
6115                             (v4f32 VR128:$src2))),
6116             (VBLENDVPSrr VR128:$src2, VR128:$src1, VR128:$mask)>;
6117   def : Pat<(v2i64 (vselect (v2i64 VR128:$mask), (v2i64 VR128:$src1),
6118                             (v2i64 VR128:$src2))),
6119             (VBLENDVPDrr VR128:$src2, VR128:$src1, VR128:$mask)>;
6120   def : Pat<(v2f64 (vselect (v2i64 VR128:$mask), (v2f64 VR128:$src1),
6121                             (v2f64 VR128:$src2))),
6122             (VBLENDVPDrr VR128:$src2, VR128:$src1, VR128:$mask)>;
6123   def : Pat<(v8i32 (vselect (v8i32 VR256:$mask), (v8i32 VR256:$src1),
6124                             (v8i32 VR256:$src2))),
6125             (VBLENDVPSYrr VR256:$src2, VR256:$src1, VR256:$mask)>;
6126   def : Pat<(v8f32 (vselect (v8i32 VR256:$mask), (v8f32 VR256:$src1),
6127                             (v8f32 VR256:$src2))),
6128             (VBLENDVPSYrr VR256:$src2, VR256:$src1, VR256:$mask)>;
6129   def : Pat<(v4i64 (vselect (v4i64 VR256:$mask), (v4i64 VR256:$src1),
6130                             (v4i64 VR256:$src2))),
6131             (VBLENDVPDYrr VR256:$src2, VR256:$src1, VR256:$mask)>;
6132   def : Pat<(v4f64 (vselect (v4i64 VR256:$mask), (v4f64 VR256:$src1),
6133                             (v4f64 VR256:$src2))),
6134             (VBLENDVPDYrr VR256:$src2, VR256:$src1, VR256:$mask)>;
6135 }
6136
6137 let Predicates = [HasAVX2] in {
6138   def : Pat<(v32i8 (vselect (v32i8 VR256:$mask), (v32i8 VR256:$src1),
6139                             (v32i8 VR256:$src2))),
6140             (VPBLENDVBYrr VR256:$src2, VR256:$src1, VR256:$mask)>;
6141 }
6142
6143 /// SS41I_ternary_int - SSE 4.1 ternary operator
6144 let Uses = [XMM0], Constraints = "$src1 = $dst" in {
6145   multiclass SS41I_ternary_int<bits<8> opc, string OpcodeStr, PatFrag mem_frag,
6146                                Intrinsic IntId> {
6147     def rr0 : SS48I<opc, MRMSrcReg, (outs VR128:$dst),
6148                     (ins VR128:$src1, VR128:$src2),
6149                     !strconcat(OpcodeStr,
6150                      "\t{$src2, $dst|$dst, $src2}"),
6151                     [(set VR128:$dst, (IntId VR128:$src1, VR128:$src2, XMM0))]>,
6152                     OpSize;
6153
6154     def rm0 : SS48I<opc, MRMSrcMem, (outs VR128:$dst),
6155                     (ins VR128:$src1, i128mem:$src2),
6156                     !strconcat(OpcodeStr,
6157                      "\t{$src2, $dst|$dst, $src2}"),
6158                     [(set VR128:$dst,
6159                       (IntId VR128:$src1,
6160                        (bitconvert (mem_frag addr:$src2)), XMM0))]>, OpSize;
6161   }
6162 }
6163
6164 let ExeDomain = SSEPackedDouble in
6165 defm BLENDVPD : SS41I_ternary_int<0x15, "blendvpd", memopv2f64,
6166                                   int_x86_sse41_blendvpd>;
6167 let ExeDomain = SSEPackedSingle in
6168 defm BLENDVPS : SS41I_ternary_int<0x14, "blendvps", memopv4f32,
6169                                   int_x86_sse41_blendvps>;
6170 defm PBLENDVB : SS41I_ternary_int<0x10, "pblendvb", memopv2i64,
6171                                   int_x86_sse41_pblendvb>;
6172
6173 let Predicates = [HasSSE41] in {
6174   def : Pat<(v16i8 (vselect (v16i8 XMM0), (v16i8 VR128:$src1),
6175                             (v16i8 VR128:$src2))),
6176             (PBLENDVBrr0 VR128:$src2, VR128:$src1)>;
6177   def : Pat<(v4i32 (vselect (v4i32 XMM0), (v4i32 VR128:$src1),
6178                             (v4i32 VR128:$src2))),
6179             (BLENDVPSrr0 VR128:$src2, VR128:$src1)>;
6180   def : Pat<(v4f32 (vselect (v4i32 XMM0), (v4f32 VR128:$src1),
6181                             (v4f32 VR128:$src2))),
6182             (BLENDVPSrr0 VR128:$src2, VR128:$src1)>;
6183   def : Pat<(v2i64 (vselect (v2i64 XMM0), (v2i64 VR128:$src1),
6184                             (v2i64 VR128:$src2))),
6185             (BLENDVPDrr0 VR128:$src2, VR128:$src1)>;
6186   def : Pat<(v2f64 (vselect (v2i64 XMM0), (v2f64 VR128:$src1),
6187                             (v2f64 VR128:$src2))),
6188             (BLENDVPDrr0 VR128:$src2, VR128:$src1)>;
6189 }
6190
6191 let Predicates = [HasAVX] in
6192 def VMOVNTDQArm : SS48I<0x2A, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
6193                        "vmovntdqa\t{$src, $dst|$dst, $src}",
6194                        [(set VR128:$dst, (int_x86_sse41_movntdqa addr:$src))]>,
6195                        OpSize, VEX;
6196 let Predicates = [HasAVX2] in
6197 def VMOVNTDQAYrm : SS48I<0x2A, MRMSrcMem, (outs VR256:$dst), (ins i256mem:$src),
6198                          "vmovntdqa\t{$src, $dst|$dst, $src}",
6199                          [(set VR256:$dst, (int_x86_avx2_movntdqa addr:$src))]>,
6200                          OpSize, VEX;
6201 def MOVNTDQArm : SS48I<0x2A, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
6202                        "movntdqa\t{$src, $dst|$dst, $src}",
6203                        [(set VR128:$dst, (int_x86_sse41_movntdqa addr:$src))]>,
6204                        OpSize;
6205
6206 //===----------------------------------------------------------------------===//
6207 // SSE4.2 - Compare Instructions
6208 //===----------------------------------------------------------------------===//
6209
6210 /// SS42I_binop_rm - Simple SSE 4.2 binary operator
6211 multiclass SS42I_binop_rm<bits<8> opc, string OpcodeStr, SDNode OpNode,
6212                           ValueType OpVT, RegisterClass RC, PatFrag memop_frag,
6213                           X86MemOperand x86memop, bit Is2Addr = 1> {
6214   def rr : SS428I<opc, MRMSrcReg, (outs RC:$dst),
6215        (ins RC:$src1, RC:$src2),
6216        !if(Is2Addr,
6217            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
6218            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
6219        [(set RC:$dst, (OpVT (OpNode RC:$src1, RC:$src2)))]>,
6220        OpSize;
6221   def rm : SS428I<opc, MRMSrcMem, (outs RC:$dst),
6222        (ins RC:$src1, x86memop:$src2),
6223        !if(Is2Addr,
6224            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
6225            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
6226        [(set RC:$dst,
6227          (OpVT (OpNode RC:$src1, (memop_frag addr:$src2))))]>, OpSize;
6228 }
6229
6230 let Predicates = [HasAVX] in
6231   defm VPCMPGTQ : SS42I_binop_rm<0x37, "vpcmpgtq", X86pcmpgt, v2i64, VR128,
6232                                  memopv2i64, i128mem, 0>, VEX_4V;
6233
6234 let Predicates = [HasAVX2] in
6235   defm VPCMPGTQY : SS42I_binop_rm<0x37, "vpcmpgtq", X86pcmpgt, v4i64, VR256,
6236                                   memopv4i64, i256mem, 0>, VEX_4V;
6237
6238 let Constraints = "$src1 = $dst" in
6239   defm PCMPGTQ : SS42I_binop_rm<0x37, "pcmpgtq", X86pcmpgt, v2i64, VR128,
6240                                 memopv2i64, i128mem>;
6241
6242 //===----------------------------------------------------------------------===//
6243 // SSE4.2 - String/text Processing Instructions
6244 //===----------------------------------------------------------------------===//
6245
6246 // Packed Compare Implicit Length Strings, Return Mask
6247 multiclass pseudo_pcmpistrm<string asm> {
6248   def REG : PseudoI<(outs VR128:$dst),
6249                     (ins VR128:$src1, VR128:$src2, i8imm:$src3),
6250     [(set VR128:$dst, (int_x86_sse42_pcmpistrm128 VR128:$src1, VR128:$src2,
6251                                                   imm:$src3))]>;
6252   def MEM : PseudoI<(outs VR128:$dst),
6253                     (ins VR128:$src1, i128mem:$src2, i8imm:$src3),
6254     [(set VR128:$dst, (int_x86_sse42_pcmpistrm128
6255                        VR128:$src1, (load addr:$src2), imm:$src3))]>;
6256 }
6257
6258 let Defs = [EFLAGS], usesCustomInserter = 1 in {
6259   let AddedComplexity = 1 in
6260     defm VPCMPISTRM128 : pseudo_pcmpistrm<"#VPCMPISTRM128">, Requires<[HasAVX]>;
6261   defm PCMPISTRM128 : pseudo_pcmpistrm<"#PCMPISTRM128">, Requires<[HasSSE42]>;
6262 }
6263
6264 let Defs = [XMM0, EFLAGS], neverHasSideEffects = 1, Predicates = [HasAVX] in {
6265   def VPCMPISTRM128rr : SS42AI<0x62, MRMSrcReg, (outs),
6266       (ins VR128:$src1, VR128:$src2, i8imm:$src3),
6267       "vpcmpistrm\t{$src3, $src2, $src1|$src1, $src2, $src3}", []>, OpSize, VEX;
6268   let mayLoad = 1 in
6269   def VPCMPISTRM128rm : SS42AI<0x62, MRMSrcMem, (outs),
6270       (ins VR128:$src1, i128mem:$src2, i8imm:$src3),
6271       "vpcmpistrm\t{$src3, $src2, $src1|$src1, $src2, $src3}", []>, OpSize, VEX;
6272 }
6273
6274 let Defs = [XMM0, EFLAGS], neverHasSideEffects = 1 in {
6275   def PCMPISTRM128rr : SS42AI<0x62, MRMSrcReg, (outs),
6276       (ins VR128:$src1, VR128:$src2, i8imm:$src3),
6277       "pcmpistrm\t{$src3, $src2, $src1|$src1, $src2, $src3}", []>, OpSize;
6278   let mayLoad = 1 in
6279   def PCMPISTRM128rm : SS42AI<0x62, MRMSrcMem, (outs),
6280       (ins VR128:$src1, i128mem:$src2, i8imm:$src3),
6281       "pcmpistrm\t{$src3, $src2, $src1|$src1, $src2, $src3}", []>, OpSize;
6282 }
6283
6284 // Packed Compare Explicit Length Strings, Return Mask
6285 multiclass pseudo_pcmpestrm<string asm> {
6286   def REG : PseudoI<(outs VR128:$dst),
6287                     (ins VR128:$src1, VR128:$src3, i8imm:$src5),
6288     [(set VR128:$dst, (int_x86_sse42_pcmpestrm128
6289                        VR128:$src1, EAX, VR128:$src3, EDX, imm:$src5))]>;
6290   def MEM : PseudoI<(outs VR128:$dst),
6291                     (ins VR128:$src1, i128mem:$src3, i8imm:$src5),
6292     [(set VR128:$dst, (int_x86_sse42_pcmpestrm128
6293                        VR128:$src1, EAX, (load addr:$src3), EDX, imm:$src5))]>;
6294 }
6295
6296 let Defs = [EFLAGS], Uses = [EAX, EDX], usesCustomInserter = 1 in {
6297   let AddedComplexity = 1 in
6298     defm VPCMPESTRM128 : pseudo_pcmpestrm<"#VPCMPESTRM128">, Requires<[HasAVX]>;
6299   defm PCMPESTRM128 : pseudo_pcmpestrm<"#PCMPESTRM128">, Requires<[HasSSE42]>;
6300 }
6301
6302 let Predicates = [HasAVX],
6303     Defs = [XMM0, EFLAGS], Uses = [EAX, EDX], neverHasSideEffects = 1 in {
6304   def VPCMPESTRM128rr : SS42AI<0x60, MRMSrcReg, (outs),
6305       (ins VR128:$src1, VR128:$src3, i8imm:$src5),
6306       "vpcmpestrm\t{$src5, $src3, $src1|$src1, $src3, $src5}", []>, OpSize, VEX;
6307   let mayLoad = 1 in
6308   def VPCMPESTRM128rm : SS42AI<0x60, MRMSrcMem, (outs),
6309       (ins VR128:$src1, i128mem:$src3, i8imm:$src5),
6310       "vpcmpestrm\t{$src5, $src3, $src1|$src1, $src3, $src5}", []>, OpSize, VEX;
6311 }
6312
6313 let Defs = [XMM0, EFLAGS], Uses = [EAX, EDX], neverHasSideEffects = 1 in {
6314   def PCMPESTRM128rr : SS42AI<0x60, MRMSrcReg, (outs),
6315       (ins VR128:$src1, VR128:$src3, i8imm:$src5),
6316       "pcmpestrm\t{$src5, $src3, $src1|$src1, $src3, $src5}", []>, OpSize;
6317   let mayLoad = 1 in
6318   def PCMPESTRM128rm : SS42AI<0x60, MRMSrcMem, (outs),
6319       (ins VR128:$src1, i128mem:$src3, i8imm:$src5),
6320       "pcmpestrm\t{$src5, $src3, $src1|$src1, $src3, $src5}", []>, OpSize;
6321 }
6322
6323 // Packed Compare Implicit Length Strings, Return Index
6324 let Defs = [ECX, EFLAGS] in {
6325   multiclass SS42AI_pcmpistri<Intrinsic IntId128, string asm = "pcmpistri"> {
6326     def rr : SS42AI<0x63, MRMSrcReg, (outs),
6327       (ins VR128:$src1, VR128:$src2, i8imm:$src3),
6328       !strconcat(asm, "\t{$src3, $src2, $src1|$src1, $src2, $src3}"),
6329       [(set ECX, (IntId128 VR128:$src1, VR128:$src2, imm:$src3)),
6330        (implicit EFLAGS)]>, OpSize;
6331     def rm : SS42AI<0x63, MRMSrcMem, (outs),
6332       (ins VR128:$src1, i128mem:$src2, i8imm:$src3),
6333       !strconcat(asm, "\t{$src3, $src2, $src1|$src1, $src2, $src3}"),
6334       [(set ECX, (IntId128 VR128:$src1, (load addr:$src2), imm:$src3)),
6335        (implicit EFLAGS)]>, OpSize;
6336   }
6337 }
6338
6339 let Predicates = [HasAVX] in {
6340 defm VPCMPISTRI  : SS42AI_pcmpistri<int_x86_sse42_pcmpistri128, "vpcmpistri">,
6341                                     VEX;
6342 defm VPCMPISTRIA : SS42AI_pcmpistri<int_x86_sse42_pcmpistria128, "vpcmpistri">,
6343                                     VEX;
6344 defm VPCMPISTRIC : SS42AI_pcmpistri<int_x86_sse42_pcmpistric128, "vpcmpistri">,
6345                                     VEX;
6346 defm VPCMPISTRIO : SS42AI_pcmpistri<int_x86_sse42_pcmpistrio128, "vpcmpistri">,
6347                                     VEX;
6348 defm VPCMPISTRIS : SS42AI_pcmpistri<int_x86_sse42_pcmpistris128, "vpcmpistri">,
6349                                     VEX;
6350 defm VPCMPISTRIZ : SS42AI_pcmpistri<int_x86_sse42_pcmpistriz128, "vpcmpistri">,
6351                                     VEX;
6352 }
6353
6354 defm PCMPISTRI  : SS42AI_pcmpistri<int_x86_sse42_pcmpistri128>;
6355 defm PCMPISTRIA : SS42AI_pcmpistri<int_x86_sse42_pcmpistria128>;
6356 defm PCMPISTRIC : SS42AI_pcmpistri<int_x86_sse42_pcmpistric128>;
6357 defm PCMPISTRIO : SS42AI_pcmpistri<int_x86_sse42_pcmpistrio128>;
6358 defm PCMPISTRIS : SS42AI_pcmpistri<int_x86_sse42_pcmpistris128>;
6359 defm PCMPISTRIZ : SS42AI_pcmpistri<int_x86_sse42_pcmpistriz128>;
6360
6361 // Packed Compare Explicit Length Strings, Return Index
6362 let Defs = [ECX, EFLAGS], Uses = [EAX, EDX] in {
6363   multiclass SS42AI_pcmpestri<Intrinsic IntId128, string asm = "pcmpestri"> {
6364     def rr : SS42AI<0x61, MRMSrcReg, (outs),
6365       (ins VR128:$src1, VR128:$src3, i8imm:$src5),
6366       !strconcat(asm, "\t{$src5, $src3, $src1|$src1, $src3, $src5}"),
6367       [(set ECX, (IntId128 VR128:$src1, EAX, VR128:$src3, EDX, imm:$src5)),
6368        (implicit EFLAGS)]>, OpSize;
6369     def rm : SS42AI<0x61, MRMSrcMem, (outs),
6370       (ins VR128:$src1, i128mem:$src3, i8imm:$src5),
6371       !strconcat(asm, "\t{$src5, $src3, $src1|$src1, $src3, $src5}"),
6372        [(set ECX,
6373              (IntId128 VR128:$src1, EAX, (load addr:$src3), EDX, imm:$src5)),
6374         (implicit EFLAGS)]>, OpSize;
6375   }
6376 }
6377
6378 let Predicates = [HasAVX] in {
6379 defm VPCMPESTRI  : SS42AI_pcmpestri<int_x86_sse42_pcmpestri128, "vpcmpestri">,
6380                                     VEX;
6381 defm VPCMPESTRIA : SS42AI_pcmpestri<int_x86_sse42_pcmpestria128, "vpcmpestri">,
6382                                     VEX;
6383 defm VPCMPESTRIC : SS42AI_pcmpestri<int_x86_sse42_pcmpestric128, "vpcmpestri">,
6384                                     VEX;
6385 defm VPCMPESTRIO : SS42AI_pcmpestri<int_x86_sse42_pcmpestrio128, "vpcmpestri">,
6386                                     VEX;
6387 defm VPCMPESTRIS : SS42AI_pcmpestri<int_x86_sse42_pcmpestris128, "vpcmpestri">,
6388                                     VEX;
6389 defm VPCMPESTRIZ : SS42AI_pcmpestri<int_x86_sse42_pcmpestriz128, "vpcmpestri">,
6390                                     VEX;
6391 }
6392
6393 defm PCMPESTRI  : SS42AI_pcmpestri<int_x86_sse42_pcmpestri128>;
6394 defm PCMPESTRIA : SS42AI_pcmpestri<int_x86_sse42_pcmpestria128>;
6395 defm PCMPESTRIC : SS42AI_pcmpestri<int_x86_sse42_pcmpestric128>;
6396 defm PCMPESTRIO : SS42AI_pcmpestri<int_x86_sse42_pcmpestrio128>;
6397 defm PCMPESTRIS : SS42AI_pcmpestri<int_x86_sse42_pcmpestris128>;
6398 defm PCMPESTRIZ : SS42AI_pcmpestri<int_x86_sse42_pcmpestriz128>;
6399
6400 //===----------------------------------------------------------------------===//
6401 // SSE4.2 - CRC Instructions
6402 //===----------------------------------------------------------------------===//
6403
6404 // No CRC instructions have AVX equivalents
6405
6406 // crc intrinsic instruction
6407 // This set of instructions are only rm, the only difference is the size
6408 // of r and m.
6409 let Constraints = "$src1 = $dst" in {
6410   def CRC32r32m8  : SS42FI<0xF0, MRMSrcMem, (outs GR32:$dst),
6411                       (ins GR32:$src1, i8mem:$src2),
6412                       "crc32{b} \t{$src2, $src1|$src1, $src2}",
6413                        [(set GR32:$dst,
6414                          (int_x86_sse42_crc32_32_8 GR32:$src1,
6415                          (load addr:$src2)))]>;
6416   def CRC32r32r8  : SS42FI<0xF0, MRMSrcReg, (outs GR32:$dst),
6417                       (ins GR32:$src1, GR8:$src2),
6418                       "crc32{b} \t{$src2, $src1|$src1, $src2}",
6419                        [(set GR32:$dst,
6420                          (int_x86_sse42_crc32_32_8 GR32:$src1, GR8:$src2))]>;
6421   def CRC32r32m16  : SS42FI<0xF1, MRMSrcMem, (outs GR32:$dst),
6422                       (ins GR32:$src1, i16mem:$src2),
6423                       "crc32{w} \t{$src2, $src1|$src1, $src2}",
6424                        [(set GR32:$dst,
6425                          (int_x86_sse42_crc32_32_16 GR32:$src1,
6426                          (load addr:$src2)))]>,
6427                          OpSize;
6428   def CRC32r32r16  : SS42FI<0xF1, MRMSrcReg, (outs GR32:$dst),
6429                       (ins GR32:$src1, GR16:$src2),
6430                       "crc32{w} \t{$src2, $src1|$src1, $src2}",
6431                        [(set GR32:$dst,
6432                          (int_x86_sse42_crc32_32_16 GR32:$src1, GR16:$src2))]>,
6433                          OpSize;
6434   def CRC32r32m32  : SS42FI<0xF1, MRMSrcMem, (outs GR32:$dst),
6435                       (ins GR32:$src1, i32mem:$src2),
6436                       "crc32{l} \t{$src2, $src1|$src1, $src2}",
6437                        [(set GR32:$dst,
6438                          (int_x86_sse42_crc32_32_32 GR32:$src1,
6439                          (load addr:$src2)))]>;
6440   def CRC32r32r32  : SS42FI<0xF1, MRMSrcReg, (outs GR32:$dst),
6441                       (ins GR32:$src1, GR32:$src2),
6442                       "crc32{l} \t{$src2, $src1|$src1, $src2}",
6443                        [(set GR32:$dst,
6444                          (int_x86_sse42_crc32_32_32 GR32:$src1, GR32:$src2))]>;
6445   def CRC32r64m8  : SS42FI<0xF0, MRMSrcMem, (outs GR64:$dst),
6446                       (ins GR64:$src1, i8mem:$src2),
6447                       "crc32{b} \t{$src2, $src1|$src1, $src2}",
6448                        [(set GR64:$dst,
6449                          (int_x86_sse42_crc32_64_8 GR64:$src1,
6450                          (load addr:$src2)))]>,
6451                          REX_W;
6452   def CRC32r64r8  : SS42FI<0xF0, MRMSrcReg, (outs GR64:$dst),
6453                       (ins GR64:$src1, GR8:$src2),
6454                       "crc32{b} \t{$src2, $src1|$src1, $src2}",
6455                        [(set GR64:$dst,
6456                          (int_x86_sse42_crc32_64_8 GR64:$src1, GR8:$src2))]>,
6457                          REX_W;
6458   def CRC32r64m64  : SS42FI<0xF1, MRMSrcMem, (outs GR64:$dst),
6459                       (ins GR64:$src1, i64mem:$src2),
6460                       "crc32{q} \t{$src2, $src1|$src1, $src2}",
6461                        [(set GR64:$dst,
6462                          (int_x86_sse42_crc32_64_64 GR64:$src1,
6463                          (load addr:$src2)))]>,
6464                          REX_W;
6465   def CRC32r64r64  : SS42FI<0xF1, MRMSrcReg, (outs GR64:$dst),
6466                       (ins GR64:$src1, GR64:$src2),
6467                       "crc32{q} \t{$src2, $src1|$src1, $src2}",
6468                        [(set GR64:$dst,
6469                          (int_x86_sse42_crc32_64_64 GR64:$src1, GR64:$src2))]>,
6470                          REX_W;
6471 }
6472
6473 //===----------------------------------------------------------------------===//
6474 // AES-NI Instructions
6475 //===----------------------------------------------------------------------===//
6476
6477 multiclass AESI_binop_rm_int<bits<8> opc, string OpcodeStr,
6478                               Intrinsic IntId128, bit Is2Addr = 1> {
6479   def rr : AES8I<opc, MRMSrcReg, (outs VR128:$dst),
6480        (ins VR128:$src1, VR128:$src2),
6481        !if(Is2Addr,
6482            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
6483            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
6484        [(set VR128:$dst, (IntId128 VR128:$src1, VR128:$src2))]>,
6485        OpSize;
6486   def rm : AES8I<opc, MRMSrcMem, (outs VR128:$dst),
6487        (ins VR128:$src1, i128mem:$src2),
6488        !if(Is2Addr,
6489            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
6490            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
6491        [(set VR128:$dst,
6492          (IntId128 VR128:$src1, (memopv2i64 addr:$src2)))]>, OpSize;
6493 }
6494
6495 // Perform One Round of an AES Encryption/Decryption Flow
6496 let Predicates = [HasAVX, HasAES] in {
6497   defm VAESENC          : AESI_binop_rm_int<0xDC, "vaesenc",
6498                          int_x86_aesni_aesenc, 0>, VEX_4V;
6499   defm VAESENCLAST      : AESI_binop_rm_int<0xDD, "vaesenclast",
6500                          int_x86_aesni_aesenclast, 0>, VEX_4V;
6501   defm VAESDEC          : AESI_binop_rm_int<0xDE, "vaesdec",
6502                          int_x86_aesni_aesdec, 0>, VEX_4V;
6503   defm VAESDECLAST      : AESI_binop_rm_int<0xDF, "vaesdeclast",
6504                          int_x86_aesni_aesdeclast, 0>, VEX_4V;
6505 }
6506
6507 let Constraints = "$src1 = $dst" in {
6508   defm AESENC          : AESI_binop_rm_int<0xDC, "aesenc",
6509                          int_x86_aesni_aesenc>;
6510   defm AESENCLAST      : AESI_binop_rm_int<0xDD, "aesenclast",
6511                          int_x86_aesni_aesenclast>;
6512   defm AESDEC          : AESI_binop_rm_int<0xDE, "aesdec",
6513                          int_x86_aesni_aesdec>;
6514   defm AESDECLAST      : AESI_binop_rm_int<0xDF, "aesdeclast",
6515                          int_x86_aesni_aesdeclast>;
6516 }
6517
6518 // Perform the AES InvMixColumn Transformation
6519 let Predicates = [HasAVX, HasAES] in {
6520   def VAESIMCrr : AES8I<0xDB, MRMSrcReg, (outs VR128:$dst),
6521       (ins VR128:$src1),
6522       "vaesimc\t{$src1, $dst|$dst, $src1}",
6523       [(set VR128:$dst,
6524         (int_x86_aesni_aesimc VR128:$src1))]>,
6525       OpSize, VEX;
6526   def VAESIMCrm : AES8I<0xDB, MRMSrcMem, (outs VR128:$dst),
6527       (ins i128mem:$src1),
6528       "vaesimc\t{$src1, $dst|$dst, $src1}",
6529       [(set VR128:$dst, (int_x86_aesni_aesimc (memopv2i64 addr:$src1)))]>,
6530       OpSize, VEX;
6531 }
6532 def AESIMCrr : AES8I<0xDB, MRMSrcReg, (outs VR128:$dst),
6533   (ins VR128:$src1),
6534   "aesimc\t{$src1, $dst|$dst, $src1}",
6535   [(set VR128:$dst,
6536     (int_x86_aesni_aesimc VR128:$src1))]>,
6537   OpSize;
6538 def AESIMCrm : AES8I<0xDB, MRMSrcMem, (outs VR128:$dst),
6539   (ins i128mem:$src1),
6540   "aesimc\t{$src1, $dst|$dst, $src1}",
6541   [(set VR128:$dst, (int_x86_aesni_aesimc (memopv2i64 addr:$src1)))]>,
6542   OpSize;
6543
6544 // AES Round Key Generation Assist
6545 let Predicates = [HasAVX, HasAES] in {
6546   def VAESKEYGENASSIST128rr : AESAI<0xDF, MRMSrcReg, (outs VR128:$dst),
6547       (ins VR128:$src1, i8imm:$src2),
6548       "vaeskeygenassist\t{$src2, $src1, $dst|$dst, $src1, $src2}",
6549       [(set VR128:$dst,
6550         (int_x86_aesni_aeskeygenassist VR128:$src1, imm:$src2))]>,
6551       OpSize, VEX;
6552   def VAESKEYGENASSIST128rm : AESAI<0xDF, MRMSrcMem, (outs VR128:$dst),
6553       (ins i128mem:$src1, i8imm:$src2),
6554       "vaeskeygenassist\t{$src2, $src1, $dst|$dst, $src1, $src2}",
6555       [(set VR128:$dst,
6556         (int_x86_aesni_aeskeygenassist (memopv2i64 addr:$src1), imm:$src2))]>,
6557       OpSize, VEX;
6558 }
6559 def AESKEYGENASSIST128rr : AESAI<0xDF, MRMSrcReg, (outs VR128:$dst),
6560   (ins VR128:$src1, i8imm:$src2),
6561   "aeskeygenassist\t{$src2, $src1, $dst|$dst, $src1, $src2}",
6562   [(set VR128:$dst,
6563     (int_x86_aesni_aeskeygenassist VR128:$src1, imm:$src2))]>,
6564   OpSize;
6565 def AESKEYGENASSIST128rm : AESAI<0xDF, MRMSrcMem, (outs VR128:$dst),
6566   (ins i128mem:$src1, i8imm:$src2),
6567   "aeskeygenassist\t{$src2, $src1, $dst|$dst, $src1, $src2}",
6568   [(set VR128:$dst,
6569     (int_x86_aesni_aeskeygenassist (memopv2i64 addr:$src1), imm:$src2))]>,
6570   OpSize;
6571
6572 //===----------------------------------------------------------------------===//
6573 // CLMUL Instructions
6574 //===----------------------------------------------------------------------===//
6575
6576 // Carry-less Multiplication instructions
6577 let neverHasSideEffects = 1 in {
6578 // AVX carry-less Multiplication instructions
6579 def VPCLMULQDQrr : AVXCLMULIi8<0x44, MRMSrcReg, (outs VR128:$dst),
6580            (ins VR128:$src1, VR128:$src2, i8imm:$src3),
6581            "vpclmulqdq\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
6582            []>;
6583
6584 let mayLoad = 1 in
6585 def VPCLMULQDQrm : AVXCLMULIi8<0x44, MRMSrcMem, (outs VR128:$dst),
6586            (ins VR128:$src1, i128mem:$src2, i8imm:$src3),
6587            "vpclmulqdq\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
6588            []>;
6589
6590 let Constraints = "$src1 = $dst" in {
6591 def PCLMULQDQrr : CLMULIi8<0x44, MRMSrcReg, (outs VR128:$dst),
6592            (ins VR128:$src1, VR128:$src2, i8imm:$src3),
6593            "pclmulqdq\t{$src3, $src2, $dst|$dst, $src2, $src3}",
6594            []>;
6595
6596 let mayLoad = 1 in
6597 def PCLMULQDQrm : CLMULIi8<0x44, MRMSrcMem, (outs VR128:$dst),
6598            (ins VR128:$src1, i128mem:$src2, i8imm:$src3),
6599            "pclmulqdq\t{$src3, $src2, $dst|$dst, $src2, $src3}",
6600            []>;
6601 } // Constraints = "$src1 = $dst"
6602 } // neverHasSideEffects = 1
6603
6604
6605 multiclass pclmul_alias<string asm, int immop> {
6606   def : InstAlias<!strconcat("pclmul", asm, 
6607                            "dq {$src, $dst|$dst, $src}"),
6608                   (PCLMULQDQrr VR128:$dst, VR128:$src, immop)>;
6609
6610   def : InstAlias<!strconcat("pclmul", asm, 
6611                              "dq {$src, $dst|$dst, $src}"),
6612                   (PCLMULQDQrm VR128:$dst, i128mem:$src, immop)>;
6613
6614   def : InstAlias<!strconcat("vpclmul", asm, 
6615                              "dq {$src2, $src1, $dst|$dst, $src1, $src2}"),
6616                   (VPCLMULQDQrr VR128:$dst, VR128:$src1, VR128:$src2, immop)>;
6617
6618   def : InstAlias<!strconcat("vpclmul", asm, 
6619                              "dq {$src2, $src1, $dst|$dst, $src1, $src2}"),
6620                   (VPCLMULQDQrm VR128:$dst, VR128:$src1, i128mem:$src2, immop)>;
6621 }
6622 defm : pclmul_alias<"hqhq", 0x11>;
6623 defm : pclmul_alias<"hqlq", 0x01>;
6624 defm : pclmul_alias<"lqhq", 0x10>;
6625 defm : pclmul_alias<"lqlq", 0x00>;
6626
6627 //===----------------------------------------------------------------------===//
6628 // AVX Instructions
6629 //===----------------------------------------------------------------------===//
6630
6631 //===----------------------------------------------------------------------===//
6632 // VBROADCAST - Load from memory and broadcast to all elements of the
6633 //              destination operand
6634 //
6635 class avx_broadcast<bits<8> opc, string OpcodeStr, RegisterClass RC,
6636                     X86MemOperand x86memop, Intrinsic Int> :
6637   AVX8I<opc, MRMSrcMem, (outs RC:$dst), (ins x86memop:$src),
6638         !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
6639         [(set RC:$dst, (Int addr:$src))]>, VEX;
6640
6641 // AVX2 adds register forms
6642 class avx2_broadcast_reg<bits<8> opc, string OpcodeStr, RegisterClass RC,
6643                          Intrinsic Int> :
6644   AVX28I<opc, MRMSrcReg, (outs RC:$dst), (ins VR128:$src),
6645          !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
6646          [(set RC:$dst, (Int VR128:$src))]>, VEX;
6647
6648 let ExeDomain = SSEPackedSingle in {
6649   def VBROADCASTSSrm  : avx_broadcast<0x18, "vbroadcastss", VR128, f32mem,
6650                                       int_x86_avx_vbroadcast_ss>;
6651   def VBROADCASTSSYrm : avx_broadcast<0x18, "vbroadcastss", VR256, f32mem,
6652                                       int_x86_avx_vbroadcast_ss_256>;
6653 }
6654 let ExeDomain = SSEPackedDouble in
6655 def VBROADCASTSDrm  : avx_broadcast<0x19, "vbroadcastsd", VR256, f64mem,
6656                                     int_x86_avx_vbroadcast_sd_256>;
6657 def VBROADCASTF128 : avx_broadcast<0x1A, "vbroadcastf128", VR256, f128mem,
6658                                    int_x86_avx_vbroadcastf128_pd_256>;
6659
6660 let ExeDomain = SSEPackedSingle in {
6661   def VBROADCASTSSrr  : avx2_broadcast_reg<0x18, "vbroadcastss", VR128,
6662                                            int_x86_avx2_vbroadcast_ss_ps>;
6663   def VBROADCASTSSYrr : avx2_broadcast_reg<0x18, "vbroadcastss", VR256,
6664                                            int_x86_avx2_vbroadcast_ss_ps_256>;
6665 }
6666 let ExeDomain = SSEPackedDouble in
6667 def VBROADCASTSDrr  : avx2_broadcast_reg<0x19, "vbroadcastsd", VR256,
6668                                          int_x86_avx2_vbroadcast_sd_pd_256>;
6669
6670 let Predicates = [HasAVX2] in
6671 def VBROADCASTI128 : avx_broadcast<0x5A, "vbroadcasti128", VR256, i128mem,
6672                                    int_x86_avx2_vbroadcasti128>;
6673
6674 let Predicates = [HasAVX] in
6675 def : Pat<(int_x86_avx_vbroadcastf128_ps_256 addr:$src),
6676           (VBROADCASTF128 addr:$src)>;
6677
6678
6679 //===----------------------------------------------------------------------===//
6680 // VINSERTF128 - Insert packed floating-point values
6681 //
6682 let neverHasSideEffects = 1, ExeDomain = SSEPackedSingle in {
6683 def VINSERTF128rr : AVXAIi8<0x18, MRMSrcReg, (outs VR256:$dst),
6684           (ins VR256:$src1, VR128:$src2, i8imm:$src3),
6685           "vinsertf128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
6686           []>, VEX_4V;
6687 let mayLoad = 1 in
6688 def VINSERTF128rm : AVXAIi8<0x18, MRMSrcMem, (outs VR256:$dst),
6689           (ins VR256:$src1, f128mem:$src2, i8imm:$src3),
6690           "vinsertf128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
6691           []>, VEX_4V;
6692 }
6693
6694 let Predicates = [HasAVX] in {
6695 def : Pat<(int_x86_avx_vinsertf128_pd_256 VR256:$src1, VR128:$src2, imm:$src3),
6696           (VINSERTF128rr VR256:$src1, VR128:$src2, imm:$src3)>;
6697 def : Pat<(int_x86_avx_vinsertf128_ps_256 VR256:$src1, VR128:$src2, imm:$src3),
6698           (VINSERTF128rr VR256:$src1, VR128:$src2, imm:$src3)>;
6699 def : Pat<(int_x86_avx_vinsertf128_si_256 VR256:$src1, VR128:$src2, imm:$src3),
6700           (VINSERTF128rr VR256:$src1, VR128:$src2, imm:$src3)>;
6701 }
6702
6703 //===----------------------------------------------------------------------===//
6704 // VEXTRACTF128 - Extract packed floating-point values
6705 //
6706 let neverHasSideEffects = 1, ExeDomain = SSEPackedSingle in {
6707 def VEXTRACTF128rr : AVXAIi8<0x19, MRMDestReg, (outs VR128:$dst),
6708           (ins VR256:$src1, i8imm:$src2),
6709           "vextractf128\t{$src2, $src1, $dst|$dst, $src1, $src2}",
6710           []>, VEX;
6711 let mayStore = 1 in
6712 def VEXTRACTF128mr : AVXAIi8<0x19, MRMDestMem, (outs),
6713           (ins f128mem:$dst, VR256:$src1, i8imm:$src2),
6714           "vextractf128\t{$src2, $src1, $dst|$dst, $src1, $src2}",
6715           []>, VEX;
6716 }
6717
6718 let Predicates = [HasAVX] in {
6719 def : Pat<(int_x86_avx_vextractf128_pd_256 VR256:$src1, imm:$src2),
6720           (VEXTRACTF128rr VR256:$src1, imm:$src2)>;
6721 def : Pat<(int_x86_avx_vextractf128_ps_256 VR256:$src1, imm:$src2),
6722           (VEXTRACTF128rr VR256:$src1, imm:$src2)>;
6723 def : Pat<(int_x86_avx_vextractf128_si_256 VR256:$src1, imm:$src2),
6724           (VEXTRACTF128rr VR256:$src1, imm:$src2)>;
6725 }
6726
6727 //===----------------------------------------------------------------------===//
6728 // VMASKMOV - Conditional SIMD Packed Loads and Stores
6729 //
6730 multiclass avx_movmask_rm<bits<8> opc_rm, bits<8> opc_mr, string OpcodeStr,
6731                           Intrinsic IntLd, Intrinsic IntLd256,
6732                           Intrinsic IntSt, Intrinsic IntSt256> {
6733   def rm  : AVX8I<opc_rm, MRMSrcMem, (outs VR128:$dst),
6734              (ins VR128:$src1, f128mem:$src2),
6735              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6736              [(set VR128:$dst, (IntLd addr:$src2, VR128:$src1))]>,
6737              VEX_4V;
6738   def Yrm : AVX8I<opc_rm, MRMSrcMem, (outs VR256:$dst),
6739              (ins VR256:$src1, f256mem:$src2),
6740              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6741              [(set VR256:$dst, (IntLd256 addr:$src2, VR256:$src1))]>,
6742              VEX_4V;
6743   def mr  : AVX8I<opc_mr, MRMDestMem, (outs),
6744              (ins f128mem:$dst, VR128:$src1, VR128:$src2),
6745              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6746              [(IntSt addr:$dst, VR128:$src1, VR128:$src2)]>, VEX_4V;
6747   def Ymr : AVX8I<opc_mr, MRMDestMem, (outs),
6748              (ins f256mem:$dst, VR256:$src1, VR256:$src2),
6749              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6750              [(IntSt256 addr:$dst, VR256:$src1, VR256:$src2)]>, VEX_4V;
6751 }
6752
6753 let ExeDomain = SSEPackedSingle in
6754 defm VMASKMOVPS : avx_movmask_rm<0x2C, 0x2E, "vmaskmovps",
6755                                  int_x86_avx_maskload_ps,
6756                                  int_x86_avx_maskload_ps_256,
6757                                  int_x86_avx_maskstore_ps,
6758                                  int_x86_avx_maskstore_ps_256>;
6759 let ExeDomain = SSEPackedDouble in
6760 defm VMASKMOVPD : avx_movmask_rm<0x2D, 0x2F, "vmaskmovpd",
6761                                  int_x86_avx_maskload_pd,
6762                                  int_x86_avx_maskload_pd_256,
6763                                  int_x86_avx_maskstore_pd,
6764                                  int_x86_avx_maskstore_pd_256>;
6765
6766 //===----------------------------------------------------------------------===//
6767 // VPERMIL - Permute Single and Double Floating-Point Values
6768 //
6769 multiclass avx_permil<bits<8> opc_rm, bits<8> opc_rmi, string OpcodeStr,
6770                       RegisterClass RC, X86MemOperand x86memop_f,
6771                       X86MemOperand x86memop_i, PatFrag i_frag,
6772                       Intrinsic IntVar, ValueType vt> {
6773   def rr  : AVX8I<opc_rm, MRMSrcReg, (outs RC:$dst),
6774              (ins RC:$src1, RC:$src2),
6775              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6776              [(set RC:$dst, (IntVar RC:$src1, RC:$src2))]>, VEX_4V;
6777   def rm  : AVX8I<opc_rm, MRMSrcMem, (outs RC:$dst),
6778              (ins RC:$src1, x86memop_i:$src2),
6779              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6780              [(set RC:$dst, (IntVar RC:$src1,
6781                              (bitconvert (i_frag addr:$src2))))]>, VEX_4V;
6782
6783   def ri  : AVXAIi8<opc_rmi, MRMSrcReg, (outs RC:$dst),
6784              (ins RC:$src1, i8imm:$src2),
6785              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6786              [(set RC:$dst, (vt (X86VPermilp RC:$src1, (i8 imm:$src2))))]>, VEX;
6787   def mi  : AVXAIi8<opc_rmi, MRMSrcMem, (outs RC:$dst),
6788              (ins x86memop_f:$src1, i8imm:$src2),
6789              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6790              [(set RC:$dst,
6791                (vt (X86VPermilp (memop addr:$src1), (i8 imm:$src2))))]>, VEX;
6792 }
6793
6794 let ExeDomain = SSEPackedSingle in {
6795   defm VPERMILPS  : avx_permil<0x0C, 0x04, "vpermilps", VR128, f128mem, i128mem,
6796                                memopv2i64, int_x86_avx_vpermilvar_ps, v4f32>;
6797   defm VPERMILPSY : avx_permil<0x0C, 0x04, "vpermilps", VR256, f256mem, i256mem,
6798                               memopv4i64, int_x86_avx_vpermilvar_ps_256, v8f32>;
6799 }
6800 let ExeDomain = SSEPackedDouble in {
6801   defm VPERMILPD  : avx_permil<0x0D, 0x05, "vpermilpd", VR128, f128mem, i128mem,
6802                                memopv2i64, int_x86_avx_vpermilvar_pd, v2f64>;
6803   defm VPERMILPDY : avx_permil<0x0D, 0x05, "vpermilpd", VR256, f256mem, i256mem,
6804                               memopv4i64, int_x86_avx_vpermilvar_pd_256, v4f64>;
6805 }
6806
6807 let Predicates = [HasAVX] in {
6808 def : Pat<(v8i32 (X86VPermilp VR256:$src1, (i8 imm:$imm))),
6809           (VPERMILPSYri VR256:$src1, imm:$imm)>;
6810 def : Pat<(v4i64 (X86VPermilp VR256:$src1, (i8 imm:$imm))),
6811           (VPERMILPDYri VR256:$src1, imm:$imm)>;
6812 def : Pat<(v8i32 (X86VPermilp (bc_v8i32 (memopv4i64 addr:$src1)),
6813                                (i8 imm:$imm))),
6814           (VPERMILPSYmi addr:$src1, imm:$imm)>;
6815 def : Pat<(v4i64 (X86VPermilp (memopv4i64 addr:$src1), (i8 imm:$imm))),
6816           (VPERMILPDYmi addr:$src1, imm:$imm)>;
6817
6818 def : Pat<(v2i64 (X86VPermilp VR128:$src1, (i8 imm:$imm))),
6819           (VPERMILPDri VR128:$src1, imm:$imm)>;
6820 def : Pat<(v2i64 (X86VPermilp (memopv2i64 addr:$src1), (i8 imm:$imm))),
6821           (VPERMILPDmi addr:$src1, imm:$imm)>;
6822 }
6823
6824 //===----------------------------------------------------------------------===//
6825 // VPERM2F128 - Permute Floating-Point Values in 128-bit chunks
6826 //
6827 let ExeDomain = SSEPackedSingle in {
6828 def VPERM2F128rr : AVXAIi8<0x06, MRMSrcReg, (outs VR256:$dst),
6829           (ins VR256:$src1, VR256:$src2, i8imm:$src3),
6830           "vperm2f128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
6831           [(set VR256:$dst, (v8f32 (X86VPerm2x128 VR256:$src1, VR256:$src2,
6832                               (i8 imm:$src3))))]>, VEX_4V;
6833 def VPERM2F128rm : AVXAIi8<0x06, MRMSrcMem, (outs VR256:$dst),
6834           (ins VR256:$src1, f256mem:$src2, i8imm:$src3),
6835           "vperm2f128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
6836           [(set VR256:$dst, (X86VPerm2x128 VR256:$src1, (memopv8f32 addr:$src2),
6837                              (i8 imm:$src3)))]>, VEX_4V;
6838 }
6839
6840 let Predicates = [HasAVX] in {
6841 def : Pat<(v8i32 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
6842           (VPERM2F128rr VR256:$src1, VR256:$src2, imm:$imm)>;
6843 def : Pat<(v4i64 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
6844           (VPERM2F128rr VR256:$src1, VR256:$src2, imm:$imm)>;
6845 def : Pat<(v4f64 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
6846           (VPERM2F128rr VR256:$src1, VR256:$src2, imm:$imm)>;
6847 def : Pat<(v32i8 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
6848           (VPERM2F128rr VR256:$src1, VR256:$src2, imm:$imm)>;
6849 def : Pat<(v16i16 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
6850           (VPERM2F128rr VR256:$src1, VR256:$src2, imm:$imm)>;
6851
6852 def : Pat<(v8f32 (X86VPerm2x128 VR256:$src1,
6853                   (memopv8f32 addr:$src2), (i8 imm:$imm))),
6854           (VPERM2F128rm VR256:$src1, addr:$src2, imm:$imm)>;
6855 def : Pat<(v8i32 (X86VPerm2x128 VR256:$src1,
6856                   (bc_v8i32 (memopv4i64 addr:$src2)), (i8 imm:$imm))),
6857           (VPERM2F128rm VR256:$src1, addr:$src2, imm:$imm)>;
6858 def : Pat<(v4i64 (X86VPerm2x128 VR256:$src1,
6859                   (memopv4i64 addr:$src2), (i8 imm:$imm))),
6860           (VPERM2F128rm VR256:$src1, addr:$src2, imm:$imm)>;
6861 def : Pat<(v4f64 (X86VPerm2x128 VR256:$src1,
6862                   (memopv4f64 addr:$src2), (i8 imm:$imm))),
6863           (VPERM2F128rm VR256:$src1, addr:$src2, imm:$imm)>;
6864 def : Pat<(v32i8 (X86VPerm2x128 VR256:$src1,
6865                   (bc_v32i8 (memopv4i64 addr:$src2)), (i8 imm:$imm))),
6866           (VPERM2F128rm VR256:$src1, addr:$src2, imm:$imm)>;
6867 def : Pat<(v16i16 (X86VPerm2x128 VR256:$src1,
6868                   (bc_v16i16 (memopv4i64 addr:$src2)), (i8 imm:$imm))),
6869           (VPERM2F128rm VR256:$src1, addr:$src2, imm:$imm)>;
6870 }
6871
6872 //===----------------------------------------------------------------------===//
6873 // VZERO - Zero YMM registers
6874 //
6875 let Defs = [YMM0, YMM1, YMM2, YMM3, YMM4, YMM5, YMM6, YMM7,
6876             YMM8, YMM9, YMM10, YMM11, YMM12, YMM13, YMM14, YMM15] in {
6877   // Zero All YMM registers
6878   def VZEROALL : I<0x77, RawFrm, (outs), (ins), "vzeroall",
6879                   [(int_x86_avx_vzeroall)]>, TB, VEX, VEX_L, Requires<[HasAVX]>;
6880
6881   // Zero Upper bits of YMM registers
6882   def VZEROUPPER : I<0x77, RawFrm, (outs), (ins), "vzeroupper",
6883                      [(int_x86_avx_vzeroupper)]>, TB, VEX, Requires<[HasAVX]>;
6884 }
6885
6886 //===----------------------------------------------------------------------===//
6887 // Half precision conversion instructions
6888 //===----------------------------------------------------------------------===//
6889 multiclass f16c_ph2ps<RegisterClass RC, X86MemOperand x86memop, Intrinsic Int> {
6890 let Predicates = [HasAVX, HasF16C] in {
6891   def rr : I<0x13, MRMSrcReg, (outs RC:$dst), (ins VR128:$src),
6892              "vcvtph2ps\t{$src, $dst|$dst, $src}",
6893              [(set RC:$dst, (Int VR128:$src))]>,
6894              T8, OpSize, VEX;
6895   let neverHasSideEffects = 1, mayLoad = 1 in
6896   def rm : I<0x13, MRMSrcMem, (outs RC:$dst), (ins x86memop:$src),
6897              "vcvtph2ps\t{$src, $dst|$dst, $src}", []>, T8, OpSize, VEX;
6898 }
6899 }
6900
6901 multiclass f16c_ps2ph<RegisterClass RC, X86MemOperand x86memop, Intrinsic Int> {
6902 let Predicates = [HasAVX, HasF16C] in {
6903   def rr : Ii8<0x1D, MRMDestReg, (outs VR128:$dst),
6904                (ins RC:$src1, i32i8imm:$src2),
6905                "vcvtps2ph\t{$src2, $src1, $dst|$dst, $src1, $src2}",
6906                [(set VR128:$dst, (Int RC:$src1, imm:$src2))]>,
6907                TA, OpSize, VEX;
6908   let neverHasSideEffects = 1, mayLoad = 1 in
6909   def mr : Ii8<0x1D, MRMDestMem, (outs x86memop:$dst),
6910                (ins RC:$src1, i32i8imm:$src2),
6911                "vcvtps2ph\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>,
6912                TA, OpSize, VEX;
6913 }
6914 }
6915
6916 defm VCVTPH2PS  : f16c_ph2ps<VR128, f64mem, int_x86_vcvtph2ps_128>;
6917 defm VCVTPH2PSY : f16c_ph2ps<VR256, f128mem, int_x86_vcvtph2ps_256>;
6918 defm VCVTPS2PH  : f16c_ps2ph<VR128, f64mem, int_x86_vcvtps2ph_128>;
6919 defm VCVTPS2PHY : f16c_ps2ph<VR256, f128mem, int_x86_vcvtps2ph_256>;
6920
6921 //===----------------------------------------------------------------------===//
6922 // AVX2 Instructions
6923 //===----------------------------------------------------------------------===//
6924
6925 /// AVX2_binop_rmi_int - AVX2 binary operator with 8-bit immediate
6926 multiclass AVX2_binop_rmi_int<bits<8> opc, string OpcodeStr,
6927                  Intrinsic IntId, RegisterClass RC, PatFrag memop_frag,
6928                  X86MemOperand x86memop> {
6929   let isCommutable = 1 in
6930   def rri : AVX2AIi8<opc, MRMSrcReg, (outs RC:$dst),
6931         (ins RC:$src1, RC:$src2, u32u8imm:$src3),
6932         !strconcat(OpcodeStr,
6933             "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
6934         [(set RC:$dst, (IntId RC:$src1, RC:$src2, imm:$src3))]>,
6935         VEX_4V;
6936   def rmi : AVX2AIi8<opc, MRMSrcMem, (outs RC:$dst),
6937         (ins RC:$src1, x86memop:$src2, u32u8imm:$src3),
6938         !strconcat(OpcodeStr,
6939             "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
6940         [(set RC:$dst,
6941           (IntId RC:$src1,
6942            (bitconvert (memop_frag addr:$src2)), imm:$src3))]>,
6943         VEX_4V;
6944 }
6945
6946 let isCommutable = 0 in {
6947 defm VPBLENDD : AVX2_binop_rmi_int<0x02, "vpblendd", int_x86_avx2_pblendd_128,
6948                                    VR128, memopv2i64, i128mem>;
6949 defm VPBLENDDY : AVX2_binop_rmi_int<0x02, "vpblendd", int_x86_avx2_pblendd_256,
6950                                     VR256, memopv4i64, i256mem>;
6951 }
6952
6953 //===----------------------------------------------------------------------===//
6954 // VPBROADCAST - Load from memory and broadcast to all elements of the
6955 //               destination operand
6956 //
6957 multiclass avx2_broadcast<bits<8> opc, string OpcodeStr,
6958                           X86MemOperand x86memop, PatFrag ld_frag,
6959                           Intrinsic Int128, Intrinsic Int256> {
6960   def rr : AVX28I<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
6961                   !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
6962                   [(set VR128:$dst, (Int128 VR128:$src))]>, VEX;
6963   def rm : AVX28I<opc, MRMSrcMem, (outs VR128:$dst), (ins x86memop:$src),
6964                   !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
6965                   [(set VR128:$dst,
6966                     (Int128 (scalar_to_vector (ld_frag addr:$src))))]>, VEX;
6967   def Yrr : AVX28I<opc, MRMSrcReg, (outs VR256:$dst), (ins VR128:$src),
6968                    !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
6969                    [(set VR256:$dst, (Int256 VR128:$src))]>, VEX;
6970   def Yrm : AVX28I<opc, MRMSrcMem, (outs VR256:$dst), (ins x86memop:$src),
6971                    !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
6972                    [(set VR256:$dst,
6973                     (Int256 (scalar_to_vector (ld_frag addr:$src))))]>, VEX;
6974 }
6975
6976 defm VPBROADCASTB  : avx2_broadcast<0x78, "vpbroadcastb", i8mem, loadi8,
6977                                     int_x86_avx2_pbroadcastb_128,
6978                                     int_x86_avx2_pbroadcastb_256>;
6979 defm VPBROADCASTW  : avx2_broadcast<0x79, "vpbroadcastw", i16mem, loadi16,
6980                                     int_x86_avx2_pbroadcastw_128,
6981                                     int_x86_avx2_pbroadcastw_256>;
6982 defm VPBROADCASTD  : avx2_broadcast<0x58, "vpbroadcastd", i32mem, loadi32,
6983                                     int_x86_avx2_pbroadcastd_128,
6984                                     int_x86_avx2_pbroadcastd_256>;
6985 defm VPBROADCASTQ  : avx2_broadcast<0x59, "vpbroadcastq", i64mem, loadi64,
6986                                     int_x86_avx2_pbroadcastq_128,
6987                                     int_x86_avx2_pbroadcastq_256>;
6988
6989 let Predicates = [HasAVX2] in {
6990   def : Pat<(v16i8 (X86VBroadcast (loadi8 addr:$src))),
6991           (VPBROADCASTBrm addr:$src)>;
6992   def : Pat<(v32i8 (X86VBroadcast (loadi8 addr:$src))),
6993           (VPBROADCASTBYrm addr:$src)>;
6994   def : Pat<(v8i16 (X86VBroadcast (loadi16 addr:$src))),
6995           (VPBROADCASTWrm addr:$src)>;
6996   def : Pat<(v16i16 (X86VBroadcast (loadi16 addr:$src))),
6997           (VPBROADCASTWYrm addr:$src)>;
6998   def : Pat<(v4i32 (X86VBroadcast (loadi32 addr:$src))),
6999           (VPBROADCASTDrm addr:$src)>;
7000   def : Pat<(v8i32 (X86VBroadcast (loadi32 addr:$src))),
7001           (VPBROADCASTDYrm addr:$src)>;
7002   def : Pat<(v2i64 (X86VBroadcast (loadi64 addr:$src))),
7003           (VPBROADCASTQrm addr:$src)>;
7004   def : Pat<(v4i64 (X86VBroadcast (loadi64 addr:$src))),
7005           (VPBROADCASTQYrm addr:$src)>;
7006 }
7007
7008 // AVX1 broadcast patterns
7009 let Predicates = [HasAVX] in {
7010 def : Pat<(v8i32 (X86VBroadcast (loadi32 addr:$src))),
7011           (VBROADCASTSSYrm addr:$src)>;
7012 def : Pat<(v4i64 (X86VBroadcast (loadi64 addr:$src))),
7013           (VBROADCASTSDrm addr:$src)>;
7014 def : Pat<(v8f32 (X86VBroadcast (loadf32 addr:$src))),
7015           (VBROADCASTSSYrm addr:$src)>;
7016 def : Pat<(v4f64 (X86VBroadcast (loadf64 addr:$src))),
7017           (VBROADCASTSDrm addr:$src)>;
7018
7019 def : Pat<(v4f32 (X86VBroadcast (loadf32 addr:$src))),
7020           (VBROADCASTSSrm addr:$src)>;
7021 def : Pat<(v4i32 (X86VBroadcast (loadi32 addr:$src))),
7022           (VBROADCASTSSrm addr:$src)>;
7023 }
7024
7025 //===----------------------------------------------------------------------===//
7026 // VPERM - Permute instructions
7027 //
7028
7029 multiclass avx2_perm<bits<8> opc, string OpcodeStr, PatFrag mem_frag,
7030                      Intrinsic Int> {
7031   def Yrr : AVX28I<opc, MRMSrcReg, (outs VR256:$dst),
7032                    (ins VR256:$src1, VR256:$src2),
7033                    !strconcat(OpcodeStr,
7034                        "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7035                    [(set VR256:$dst, (Int VR256:$src1, VR256:$src2))]>, VEX_4V;
7036   def Yrm : AVX28I<opc, MRMSrcMem, (outs VR256:$dst),
7037                    (ins VR256:$src1, i256mem:$src2),
7038                    !strconcat(OpcodeStr,
7039                        "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7040                    [(set VR256:$dst, (Int VR256:$src1,
7041                                       (bitconvert (mem_frag addr:$src2))))]>,
7042                    VEX_4V;
7043 }
7044
7045 defm VPERMD : avx2_perm<0x36, "vpermd", memopv4i64, int_x86_avx2_permd>;
7046 let ExeDomain = SSEPackedSingle in
7047 defm VPERMPS : avx2_perm<0x16, "vpermps", memopv8f32, int_x86_avx2_permps>;
7048
7049 multiclass avx2_perm_imm<bits<8> opc, string OpcodeStr, PatFrag mem_frag,
7050                          Intrinsic Int> {
7051   def Yrr : AVX2AIi8<opc, MRMSrcReg, (outs VR256:$dst),
7052                      (ins VR256:$src1, i8imm:$src2),
7053                      !strconcat(OpcodeStr,
7054                          "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7055                      [(set VR256:$dst, (Int VR256:$src1, imm:$src2))]>, VEX;
7056   def Yrm : AVX2AIi8<opc, MRMSrcMem, (outs VR256:$dst),
7057                      (ins i256mem:$src1, i8imm:$src2),
7058                      !strconcat(OpcodeStr,
7059                          "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7060                      [(set VR256:$dst, (Int (mem_frag addr:$src1), imm:$src2))]>,
7061                      VEX;
7062 }
7063
7064 defm VPERMQ : avx2_perm_imm<0x00, "vpermq", memopv4i64, int_x86_avx2_permq>,
7065                             VEX_W;
7066 let ExeDomain = SSEPackedDouble in
7067 defm VPERMPD : avx2_perm_imm<0x01, "vpermpd", memopv4f64, int_x86_avx2_permpd>,
7068                              VEX_W;
7069
7070 //===----------------------------------------------------------------------===//
7071 // VPERM2I128 - Permute Floating-Point Values in 128-bit chunks
7072 //
7073 let AddedComplexity = 1 in {
7074 def VPERM2I128rr : AVX2AIi8<0x46, MRMSrcReg, (outs VR256:$dst),
7075           (ins VR256:$src1, VR256:$src2, i8imm:$src3),
7076           "vperm2i128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
7077           [(set VR256:$dst, (v4i64 (X86VPerm2x128 VR256:$src1, VR256:$src2,
7078                             (i8 imm:$src3))))]>, VEX_4V;
7079 def VPERM2I128rm : AVX2AIi8<0x46, MRMSrcMem, (outs VR256:$dst),
7080           (ins VR256:$src1, f256mem:$src2, i8imm:$src3),
7081           "vperm2i128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
7082           [(set VR256:$dst, (X86VPerm2x128 VR256:$src1, (memopv4i64 addr:$src2),
7083                              (i8 imm:$src3)))]>, VEX_4V;
7084 }
7085
7086 let Predicates = [HasAVX2], AddedComplexity = 1 in {
7087 def : Pat<(v8i32 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
7088           (VPERM2I128rr VR256:$src1, VR256:$src2, imm:$imm)>;
7089 def : Pat<(v32i8 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
7090           (VPERM2I128rr VR256:$src1, VR256:$src2, imm:$imm)>;
7091 def : Pat<(v16i16 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
7092           (VPERM2I128rr VR256:$src1, VR256:$src2, imm:$imm)>;
7093
7094 def : Pat<(v32i8 (X86VPerm2x128 VR256:$src1, (bc_v32i8 (memopv4i64 addr:$src2)),
7095                   (i8 imm:$imm))),
7096           (VPERM2I128rm VR256:$src1, addr:$src2, imm:$imm)>;
7097 def : Pat<(v16i16 (X86VPerm2x128 VR256:$src1,
7098                    (bc_v16i16 (memopv4i64 addr:$src2)), (i8 imm:$imm))),
7099           (VPERM2I128rm VR256:$src1, addr:$src2, imm:$imm)>;
7100 def : Pat<(v8i32 (X86VPerm2x128 VR256:$src1, (bc_v8i32 (memopv4i64 addr:$src2)),
7101                   (i8 imm:$imm))),
7102           (VPERM2I128rm VR256:$src1, addr:$src2, imm:$imm)>;
7103 }
7104
7105
7106 //===----------------------------------------------------------------------===//
7107 // VINSERTI128 - Insert packed integer values
7108 //
7109 def VINSERTI128rr : AVX2AIi8<0x38, MRMSrcReg, (outs VR256:$dst),
7110           (ins VR256:$src1, VR128:$src2, i8imm:$src3),
7111           "vinserti128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
7112           [(set VR256:$dst,
7113             (int_x86_avx2_vinserti128 VR256:$src1, VR128:$src2, imm:$src3))]>,
7114           VEX_4V;
7115 def VINSERTI128rm : AVX2AIi8<0x38, MRMSrcMem, (outs VR256:$dst),
7116           (ins VR256:$src1, i128mem:$src2, i8imm:$src3),
7117           "vinserti128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
7118           [(set VR256:$dst,
7119             (int_x86_avx2_vinserti128 VR256:$src1, (memopv2i64 addr:$src2),
7120              imm:$src3))]>, VEX_4V;
7121
7122 let Predicates = [HasAVX2] in {
7123 def : Pat<(vinsertf128_insert:$ins (v4i64 VR256:$src1), (v2i64 VR128:$src2),
7124                                    (i32 imm)),
7125           (VINSERTI128rr VR256:$src1, VR128:$src2,
7126                          (INSERT_get_vinsertf128_imm VR256:$ins))>;
7127 def : Pat<(vinsertf128_insert:$ins (v8i32 VR256:$src1), (v4i32 VR128:$src2),
7128                                    (i32 imm)),
7129           (VINSERTI128rr VR256:$src1, VR128:$src2,
7130                          (INSERT_get_vinsertf128_imm VR256:$ins))>;
7131 def : Pat<(vinsertf128_insert:$ins (v32i8 VR256:$src1), (v16i8 VR128:$src2),
7132                                    (i32 imm)),
7133           (VINSERTI128rr VR256:$src1, VR128:$src2,
7134                          (INSERT_get_vinsertf128_imm VR256:$ins))>;
7135 def : Pat<(vinsertf128_insert:$ins (v16i16 VR256:$src1), (v8i16 VR128:$src2),
7136                                    (i32 imm)),
7137           (VINSERTI128rr VR256:$src1, VR128:$src2,
7138                          (INSERT_get_vinsertf128_imm VR256:$ins))>;
7139 }
7140
7141 // AVX1 patterns
7142 let Predicates = [HasAVX] in {
7143 def : Pat<(vinsertf128_insert:$ins (v8f32 VR256:$src1), (v4f32 VR128:$src2),
7144                                    (i32 imm)),
7145           (VINSERTF128rr VR256:$src1, VR128:$src2,
7146                          (INSERT_get_vinsertf128_imm VR256:$ins))>;
7147 def : Pat<(vinsertf128_insert:$ins (v4f64 VR256:$src1), (v2f64 VR128:$src2),
7148                                    (i32 imm)),
7149           (VINSERTF128rr VR256:$src1, VR128:$src2,
7150                          (INSERT_get_vinsertf128_imm VR256:$ins))>;
7151 def : Pat<(vinsertf128_insert:$ins (v4i64 VR256:$src1), (v2i64 VR128:$src2),
7152                                    (i32 imm)),
7153           (VINSERTF128rr VR256:$src1, VR128:$src2,
7154                          (INSERT_get_vinsertf128_imm VR256:$ins))>;
7155 def : Pat<(vinsertf128_insert:$ins (v8i32 VR256:$src1), (v4i32 VR128:$src2),
7156                                    (i32 imm)),
7157           (VINSERTF128rr VR256:$src1, VR128:$src2,
7158                          (INSERT_get_vinsertf128_imm VR256:$ins))>;
7159 def : Pat<(vinsertf128_insert:$ins (v32i8 VR256:$src1), (v16i8 VR128:$src2),
7160                                    (i32 imm)),
7161           (VINSERTF128rr VR256:$src1, VR128:$src2,
7162                          (INSERT_get_vinsertf128_imm VR256:$ins))>;
7163 def : Pat<(vinsertf128_insert:$ins (v16i16 VR256:$src1), (v8i16 VR128:$src2),
7164                                    (i32 imm)),
7165           (VINSERTF128rr VR256:$src1, VR128:$src2,
7166                          (INSERT_get_vinsertf128_imm VR256:$ins))>;
7167 }
7168
7169 //===----------------------------------------------------------------------===//
7170 // VEXTRACTI128 - Extract packed integer values
7171 //
7172 def VEXTRACTI128rr : AVX2AIi8<0x39, MRMDestReg, (outs VR128:$dst),
7173           (ins VR256:$src1, i8imm:$src2),
7174           "vextracti128\t{$src2, $src1, $dst|$dst, $src1, $src2}",
7175           [(set VR128:$dst,
7176             (int_x86_avx2_vextracti128 VR256:$src1, imm:$src2))]>,
7177           VEX;
7178 let neverHasSideEffects = 1, mayStore = 1 in
7179 def VEXTRACTI128mr : AVX2AIi8<0x39, MRMDestMem, (outs),
7180           (ins i128mem:$dst, VR256:$src1, i8imm:$src2),
7181           "vextracti128\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>, VEX;
7182
7183 let Predicates = [HasAVX2] in {
7184 def : Pat<(vextractf128_extract:$ext VR256:$src1, (i32 imm)),
7185           (v2i64 (VEXTRACTI128rr
7186                     (v4i64 VR256:$src1),
7187                     (EXTRACT_get_vextractf128_imm VR128:$ext)))>;
7188 def : Pat<(vextractf128_extract:$ext VR256:$src1, (i32 imm)),
7189           (v4i32 (VEXTRACTI128rr
7190                     (v8i32 VR256:$src1),
7191                     (EXTRACT_get_vextractf128_imm VR128:$ext)))>;
7192 def : Pat<(vextractf128_extract:$ext VR256:$src1, (i32 imm)),
7193           (v8i16 (VEXTRACTI128rr
7194                     (v16i16 VR256:$src1),
7195                     (EXTRACT_get_vextractf128_imm VR128:$ext)))>;
7196 def : Pat<(vextractf128_extract:$ext VR256:$src1, (i32 imm)),
7197           (v16i8 (VEXTRACTI128rr
7198                     (v32i8 VR256:$src1),
7199                     (EXTRACT_get_vextractf128_imm VR128:$ext)))>;
7200 }
7201
7202 // AVX1 patterns
7203 let Predicates = [HasAVX] in {
7204 def : Pat<(vextractf128_extract:$ext VR256:$src1, (i32 imm)),
7205           (v4f32 (VEXTRACTF128rr
7206                     (v8f32 VR256:$src1),
7207                     (EXTRACT_get_vextractf128_imm VR128:$ext)))>;
7208 def : Pat<(vextractf128_extract:$ext VR256:$src1, (i32 imm)),
7209           (v2f64 (VEXTRACTF128rr
7210                     (v4f64 VR256:$src1),
7211                     (EXTRACT_get_vextractf128_imm VR128:$ext)))>;
7212 def : Pat<(vextractf128_extract:$ext VR256:$src1, (i32 imm)),
7213           (v2i64 (VEXTRACTF128rr
7214                     (v4i64 VR256:$src1),
7215                     (EXTRACT_get_vextractf128_imm VR128:$ext)))>;
7216 def : Pat<(vextractf128_extract:$ext VR256:$src1, (i32 imm)),
7217           (v4i32 (VEXTRACTF128rr
7218                     (v8i32 VR256:$src1),
7219                     (EXTRACT_get_vextractf128_imm VR128:$ext)))>;
7220 def : Pat<(vextractf128_extract:$ext VR256:$src1, (i32 imm)),
7221           (v8i16 (VEXTRACTF128rr
7222                     (v16i16 VR256:$src1),
7223                     (EXTRACT_get_vextractf128_imm VR128:$ext)))>;
7224 def : Pat<(vextractf128_extract:$ext VR256:$src1, (i32 imm)),
7225           (v16i8 (VEXTRACTF128rr
7226                     (v32i8 VR256:$src1),
7227                     (EXTRACT_get_vextractf128_imm VR128:$ext)))>;
7228 }
7229
7230 //===----------------------------------------------------------------------===//
7231 // VPMASKMOV - Conditional SIMD Integer Packed Loads and Stores
7232 //
7233 multiclass avx2_pmovmask<string OpcodeStr,
7234                          Intrinsic IntLd128, Intrinsic IntLd256,
7235                          Intrinsic IntSt128, Intrinsic IntSt256> {
7236   def rm  : AVX28I<0x8c, MRMSrcMem, (outs VR128:$dst),
7237              (ins VR128:$src1, i128mem:$src2),
7238              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7239              [(set VR128:$dst, (IntLd128 addr:$src2, VR128:$src1))]>, VEX_4V;
7240   def Yrm : AVX28I<0x8c, MRMSrcMem, (outs VR256:$dst),
7241              (ins VR256:$src1, i256mem:$src2),
7242              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7243              [(set VR256:$dst, (IntLd256 addr:$src2, VR256:$src1))]>, VEX_4V;
7244   def mr  : AVX28I<0x8e, MRMDestMem, (outs),
7245              (ins i128mem:$dst, VR128:$src1, VR128:$src2),
7246              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7247              [(IntSt128 addr:$dst, VR128:$src1, VR128:$src2)]>, VEX_4V;
7248   def Ymr : AVX28I<0x8e, MRMDestMem, (outs),
7249              (ins i256mem:$dst, VR256:$src1, VR256:$src2),
7250              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7251              [(IntSt256 addr:$dst, VR256:$src1, VR256:$src2)]>, VEX_4V;
7252 }
7253
7254 defm VPMASKMOVD : avx2_pmovmask<"vpmaskmovd",
7255                                 int_x86_avx2_maskload_d,
7256                                 int_x86_avx2_maskload_d_256,
7257                                 int_x86_avx2_maskstore_d,
7258                                 int_x86_avx2_maskstore_d_256>;
7259 defm VPMASKMOVQ : avx2_pmovmask<"vpmaskmovq",
7260                                 int_x86_avx2_maskload_q,
7261                                 int_x86_avx2_maskload_q_256,
7262                                 int_x86_avx2_maskstore_q,
7263                                 int_x86_avx2_maskstore_q_256>, VEX_W;
7264
7265
7266 //===----------------------------------------------------------------------===//
7267 // Variable Bit Shifts
7268 //
7269 multiclass avx2_var_shift<bits<8> opc, string OpcodeStr, SDNode OpNode,
7270                           ValueType vt128, ValueType vt256> {
7271   def rr  : AVX28I<opc, MRMSrcReg, (outs VR128:$dst),
7272              (ins VR128:$src1, VR128:$src2),
7273              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7274              [(set VR128:$dst,
7275                (vt128 (OpNode VR128:$src1, (vt128 VR128:$src2))))]>,
7276              VEX_4V;
7277   def rm  : AVX28I<opc, MRMSrcMem, (outs VR128:$dst),
7278              (ins VR128:$src1, i128mem:$src2),
7279              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7280              [(set VR128:$dst,
7281                (vt128 (OpNode VR128:$src1,
7282                        (vt128 (bitconvert (memopv2i64 addr:$src2))))))]>,
7283              VEX_4V;
7284   def Yrr : AVX28I<opc, MRMSrcReg, (outs VR256:$dst),
7285              (ins VR256:$src1, VR256:$src2),
7286              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7287              [(set VR256:$dst,
7288                (vt256 (OpNode VR256:$src1, (vt256 VR256:$src2))))]>,
7289              VEX_4V;
7290   def Yrm : AVX28I<opc, MRMSrcMem, (outs VR256:$dst),
7291              (ins VR256:$src1, i256mem:$src2),
7292              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
7293              [(set VR256:$dst,
7294                (vt256 (OpNode VR256:$src1,
7295                        (vt256 (bitconvert (memopv4i64 addr:$src2))))))]>,
7296              VEX_4V;
7297 }
7298
7299 defm VPSLLVD : avx2_var_shift<0x47, "vpsllvd", shl, v4i32, v8i32>;
7300 defm VPSLLVQ : avx2_var_shift<0x47, "vpsllvq", shl, v2i64, v4i64>, VEX_W;
7301 defm VPSRLVD : avx2_var_shift<0x45, "vpsrlvd", srl, v4i32, v8i32>;
7302 defm VPSRLVQ : avx2_var_shift<0x45, "vpsrlvq", srl, v2i64, v4i64>, VEX_W;
7303 defm VPSRAVD : avx2_var_shift<0x46, "vpsravd", sra, v4i32, v8i32>;