Thumb2 range check on CPS mode immediate.
[oota-llvm.git] / lib / Target / X86 / X86InstrSSE.td
1 //====- X86InstrSSE.td - Describe the X86 Instruction Set --*- tablegen -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file describes the X86 SSE instruction set, defining the instructions,
11 // and properties of the instructions which are needed for code generation,
12 // machine code emission, and analysis.
13 //
14 //===----------------------------------------------------------------------===//
15
16
17 //===----------------------------------------------------------------------===//
18 // SSE 1 & 2 Instructions Classes
19 //===----------------------------------------------------------------------===//
20
21 /// sse12_fp_scalar - SSE 1 & 2 scalar instructions class
22 multiclass sse12_fp_scalar<bits<8> opc, string OpcodeStr, SDNode OpNode,
23                            RegisterClass RC, X86MemOperand x86memop,
24                            bit Is2Addr = 1> {
25   let isCommutable = 1 in {
26     def rr : SI<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
27        !if(Is2Addr,
28            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
29            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
30        [(set RC:$dst, (OpNode RC:$src1, RC:$src2))]>;
31   }
32   def rm : SI<opc, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
33        !if(Is2Addr,
34            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
35            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
36        [(set RC:$dst, (OpNode RC:$src1, (load addr:$src2)))]>;
37 }
38
39 /// sse12_fp_scalar_int - SSE 1 & 2 scalar instructions intrinsics class
40 multiclass sse12_fp_scalar_int<bits<8> opc, string OpcodeStr, RegisterClass RC,
41                              string asm, string SSEVer, string FPSizeStr,
42                              Operand memopr, ComplexPattern mem_cpat,
43                              bit Is2Addr = 1> {
44   def rr_Int : SI<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
45        !if(Is2Addr,
46            !strconcat(asm, "\t{$src2, $dst|$dst, $src2}"),
47            !strconcat(asm, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
48        [(set RC:$dst, (!cast<Intrinsic>(
49                  !strconcat("int_x86_sse", SSEVer, "_", OpcodeStr, FPSizeStr))
50              RC:$src1, RC:$src2))]>;
51   def rm_Int : SI<opc, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, memopr:$src2),
52        !if(Is2Addr,
53            !strconcat(asm, "\t{$src2, $dst|$dst, $src2}"),
54            !strconcat(asm, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
55        [(set RC:$dst, (!cast<Intrinsic>(!strconcat("int_x86_sse",
56                                           SSEVer, "_", OpcodeStr, FPSizeStr))
57              RC:$src1, mem_cpat:$src2))]>;
58 }
59
60 /// sse12_fp_packed - SSE 1 & 2 packed instructions class
61 multiclass sse12_fp_packed<bits<8> opc, string OpcodeStr, SDNode OpNode,
62                            RegisterClass RC, ValueType vt,
63                            X86MemOperand x86memop, PatFrag mem_frag,
64                            Domain d, bit Is2Addr = 1> {
65   let isCommutable = 1 in
66     def rr : PI<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
67        !if(Is2Addr,
68            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
69            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
70        [(set RC:$dst, (vt (OpNode RC:$src1, RC:$src2)))], d>;
71   let mayLoad = 1 in
72     def rm : PI<opc, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
73        !if(Is2Addr,
74            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
75            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
76        [(set RC:$dst, (OpNode RC:$src1, (mem_frag addr:$src2)))], d>;
77 }
78
79 /// sse12_fp_packed_logical_rm - SSE 1 & 2 packed instructions class
80 multiclass sse12_fp_packed_logical_rm<bits<8> opc, RegisterClass RC, Domain d,
81                                       string OpcodeStr, X86MemOperand x86memop,
82                                       list<dag> pat_rr, list<dag> pat_rm,
83                                       bit Is2Addr = 1> {
84   let isCommutable = 1 in
85     def rr : PI<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
86        !if(Is2Addr,
87            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
88            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
89        pat_rr, d>;
90   def rm : PI<opc, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
91        !if(Is2Addr,
92            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
93            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
94        pat_rm, d>;
95 }
96
97 /// sse12_fp_packed_int - SSE 1 & 2 packed instructions intrinsics class
98 multiclass sse12_fp_packed_int<bits<8> opc, string OpcodeStr, RegisterClass RC,
99                            string asm, string SSEVer, string FPSizeStr,
100                            X86MemOperand x86memop, PatFrag mem_frag,
101                            Domain d, bit Is2Addr = 1> {
102   def rr_Int : PI<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
103        !if(Is2Addr,
104            !strconcat(asm, "\t{$src2, $dst|$dst, $src2}"),
105            !strconcat(asm, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
106            [(set RC:$dst, (!cast<Intrinsic>(
107                      !strconcat("int_x86_", SSEVer, "_", OpcodeStr, FPSizeStr))
108                  RC:$src1, RC:$src2))], d>;
109   def rm_Int : PI<opc, MRMSrcMem, (outs RC:$dst), (ins RC:$src1,x86memop:$src2),
110        !if(Is2Addr,
111            !strconcat(asm, "\t{$src2, $dst|$dst, $src2}"),
112            !strconcat(asm, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
113        [(set RC:$dst, (!cast<Intrinsic>(
114                      !strconcat("int_x86_", SSEVer, "_", OpcodeStr, FPSizeStr))
115              RC:$src1, (mem_frag addr:$src2)))], d>;
116 }
117
118 //===----------------------------------------------------------------------===//
119 //  Non-instruction patterns
120 //===----------------------------------------------------------------------===//
121
122 // A vector extract of the first f32/f64 position is a subregister copy
123 def : Pat<(f32 (vector_extract (v4f32 VR128:$src), (iPTR 0))),
124           (f32 (EXTRACT_SUBREG (v4f32 VR128:$src), sub_ss))>;
125 def : Pat<(f64 (vector_extract (v2f64 VR128:$src), (iPTR 0))),
126           (f64 (EXTRACT_SUBREG (v2f64 VR128:$src), sub_sd))>;
127
128 // A 128-bit subvector extract from the first 256-bit vector position
129 // is a subregister copy that needs no instruction.
130 def : Pat<(v4i32 (extract_subvector (v8i32 VR256:$src), (i32 0))),
131           (v4i32 (EXTRACT_SUBREG (v8i32 VR256:$src), sub_xmm))>;
132 def : Pat<(v4f32 (extract_subvector (v8f32 VR256:$src), (i32 0))),
133           (v4f32 (EXTRACT_SUBREG (v8f32 VR256:$src), sub_xmm))>;
134
135 def : Pat<(v2i64 (extract_subvector (v4i64 VR256:$src), (i32 0))),
136           (v2i64 (EXTRACT_SUBREG (v4i64 VR256:$src), sub_xmm))>;
137 def : Pat<(v2f64 (extract_subvector (v4f64 VR256:$src), (i32 0))),
138           (v2f64 (EXTRACT_SUBREG (v4f64 VR256:$src), sub_xmm))>;
139
140 def : Pat<(v8i16 (extract_subvector (v16i16 VR256:$src), (i32 0))),
141           (v8i16 (EXTRACT_SUBREG (v16i16 VR256:$src), sub_xmm))>;
142 def : Pat<(v16i8 (extract_subvector (v32i8 VR256:$src), (i32 0))),
143           (v16i8 (EXTRACT_SUBREG (v32i8 VR256:$src), sub_xmm))>;
144
145 // A 128-bit subvector insert to the first 256-bit vector position
146 // is a subregister copy that needs no instruction.
147 def : Pat<(insert_subvector undef, (v2i64 VR128:$src), (i32 0)),
148           (INSERT_SUBREG (v4i64 (IMPLICIT_DEF)), VR128:$src, sub_xmm)>;
149 def : Pat<(insert_subvector undef, (v2f64 VR128:$src), (i32 0)),
150           (INSERT_SUBREG (v4f64 (IMPLICIT_DEF)), VR128:$src, sub_xmm)>;
151 def : Pat<(insert_subvector undef, (v4i32 VR128:$src), (i32 0)),
152           (INSERT_SUBREG (v8i32 (IMPLICIT_DEF)), VR128:$src, sub_xmm)>;
153 def : Pat<(insert_subvector undef, (v4f32 VR128:$src), (i32 0)),
154           (INSERT_SUBREG (v8f32 (IMPLICIT_DEF)), VR128:$src, sub_xmm)>;
155 def : Pat<(insert_subvector undef, (v8i16 VR128:$src), (i32 0)),
156           (INSERT_SUBREG (v16i16 (IMPLICIT_DEF)), VR128:$src, sub_xmm)>;
157 def : Pat<(insert_subvector undef, (v16i8 VR128:$src), (i32 0)),
158           (INSERT_SUBREG (v32i8 (IMPLICIT_DEF)), VR128:$src, sub_xmm)>;
159
160 // Inserting a 128-bit undef vector into the high part of a 256-bit
161 // vector should return the 256-bit vector itself.
162 def : Pat<(insert_subvector (v8i32 VR256:$src), undef, (i32 4)),
163           (v8i32 VR256:$src)>;
164 def : Pat<(insert_subvector (v8f32 VR256:$src), undef, (i32 4)),
165           (v8f32 VR256:$src)>;
166 def : Pat<(insert_subvector (v4i64 VR256:$src), undef, (i32 4)),
167           (v4i64 VR256:$src)>;
168 def : Pat<(insert_subvector (v4f64 VR256:$src), undef, (i32 4)),
169           (v4f64 VR256:$src)>;
170 def : Pat<(insert_subvector (v16i16 VR256:$src), undef, (i32 4)),
171           (v16i16 VR256:$src)>;
172 def : Pat<(insert_subvector (v32i8 VR256:$src), undef, (i32 4)),
173           (v32i8 VR256:$src)>;
174
175 // Implicitly promote a 32-bit scalar to a vector.
176 def : Pat<(v4f32 (scalar_to_vector FR32:$src)),
177           (INSERT_SUBREG (v4f32 (IMPLICIT_DEF)), FR32:$src, sub_ss)>;
178 def : Pat<(v8f32 (scalar_to_vector FR32:$src)),
179           (INSERT_SUBREG (v8f32 (IMPLICIT_DEF)), FR32:$src, sub_ss)>;
180 // Implicitly promote a 64-bit scalar to a vector.
181 def : Pat<(v2f64 (scalar_to_vector FR64:$src)),
182           (INSERT_SUBREG (v2f64 (IMPLICIT_DEF)), FR64:$src, sub_sd)>;
183 def : Pat<(v4f64 (scalar_to_vector FR64:$src)),
184           (INSERT_SUBREG (v4f64 (IMPLICIT_DEF)), FR64:$src, sub_sd)>;
185
186 // Bitcasts between 128-bit vector types. Return the original type since
187 // no instruction is needed for the conversion
188 let Predicates = [HasXMMInt] in {
189   def : Pat<(v2i64 (bitconvert (v4i32 VR128:$src))), (v2i64 VR128:$src)>;
190   def : Pat<(v2i64 (bitconvert (v8i16 VR128:$src))), (v2i64 VR128:$src)>;
191   def : Pat<(v2i64 (bitconvert (v16i8 VR128:$src))), (v2i64 VR128:$src)>;
192   def : Pat<(v2i64 (bitconvert (v2f64 VR128:$src))), (v2i64 VR128:$src)>;
193   def : Pat<(v2i64 (bitconvert (v4f32 VR128:$src))), (v2i64 VR128:$src)>;
194   def : Pat<(v4i32 (bitconvert (v2i64 VR128:$src))), (v4i32 VR128:$src)>;
195   def : Pat<(v4i32 (bitconvert (v8i16 VR128:$src))), (v4i32 VR128:$src)>;
196   def : Pat<(v4i32 (bitconvert (v16i8 VR128:$src))), (v4i32 VR128:$src)>;
197   def : Pat<(v4i32 (bitconvert (v2f64 VR128:$src))), (v4i32 VR128:$src)>;
198   def : Pat<(v4i32 (bitconvert (v4f32 VR128:$src))), (v4i32 VR128:$src)>;
199   def : Pat<(v8i16 (bitconvert (v2i64 VR128:$src))), (v8i16 VR128:$src)>;
200   def : Pat<(v8i16 (bitconvert (v4i32 VR128:$src))), (v8i16 VR128:$src)>;
201   def : Pat<(v8i16 (bitconvert (v16i8 VR128:$src))), (v8i16 VR128:$src)>;
202   def : Pat<(v8i16 (bitconvert (v2f64 VR128:$src))), (v8i16 VR128:$src)>;
203   def : Pat<(v8i16 (bitconvert (v4f32 VR128:$src))), (v8i16 VR128:$src)>;
204   def : Pat<(v16i8 (bitconvert (v2i64 VR128:$src))), (v16i8 VR128:$src)>;
205   def : Pat<(v16i8 (bitconvert (v4i32 VR128:$src))), (v16i8 VR128:$src)>;
206   def : Pat<(v16i8 (bitconvert (v8i16 VR128:$src))), (v16i8 VR128:$src)>;
207   def : Pat<(v16i8 (bitconvert (v2f64 VR128:$src))), (v16i8 VR128:$src)>;
208   def : Pat<(v16i8 (bitconvert (v4f32 VR128:$src))), (v16i8 VR128:$src)>;
209   def : Pat<(v4f32 (bitconvert (v2i64 VR128:$src))), (v4f32 VR128:$src)>;
210   def : Pat<(v4f32 (bitconvert (v4i32 VR128:$src))), (v4f32 VR128:$src)>;
211   def : Pat<(v4f32 (bitconvert (v8i16 VR128:$src))), (v4f32 VR128:$src)>;
212   def : Pat<(v4f32 (bitconvert (v16i8 VR128:$src))), (v4f32 VR128:$src)>;
213   def : Pat<(v4f32 (bitconvert (v2f64 VR128:$src))), (v4f32 VR128:$src)>;
214   def : Pat<(v2f64 (bitconvert (v2i64 VR128:$src))), (v2f64 VR128:$src)>;
215   def : Pat<(v2f64 (bitconvert (v4i32 VR128:$src))), (v2f64 VR128:$src)>;
216   def : Pat<(v2f64 (bitconvert (v8i16 VR128:$src))), (v2f64 VR128:$src)>;
217   def : Pat<(v2f64 (bitconvert (v16i8 VR128:$src))), (v2f64 VR128:$src)>;
218   def : Pat<(v2f64 (bitconvert (v4f32 VR128:$src))), (v2f64 VR128:$src)>;
219 }
220
221 // Bitcasts between 256-bit vector types. Return the original type since
222 // no instruction is needed for the conversion
223 let Predicates = [HasAVX] in {
224   def : Pat<(v4f64  (bitconvert (v8f32 VR256:$src))),  (v4f64 VR256:$src)>;
225   def : Pat<(v4f64  (bitconvert (v8i32 VR256:$src))),  (v4f64 VR256:$src)>;
226   def : Pat<(v4f64  (bitconvert (v4i64 VR256:$src))),  (v4f64 VR256:$src)>;
227   def : Pat<(v4f64  (bitconvert (v16i16 VR256:$src))), (v4f64 VR256:$src)>;
228   def : Pat<(v4f64  (bitconvert (v32i8 VR256:$src))),  (v4f64 VR256:$src)>;
229   def : Pat<(v8f32  (bitconvert (v8i32 VR256:$src))),  (v8f32 VR256:$src)>;
230   def : Pat<(v8f32  (bitconvert (v4i64 VR256:$src))),  (v8f32 VR256:$src)>;
231   def : Pat<(v8f32  (bitconvert (v4f64 VR256:$src))),  (v8f32 VR256:$src)>;
232   def : Pat<(v8f32  (bitconvert (v32i8 VR256:$src))),  (v8f32 VR256:$src)>;
233   def : Pat<(v8f32  (bitconvert (v16i16 VR256:$src))), (v8f32 VR256:$src)>;
234   def : Pat<(v4i64  (bitconvert (v8f32 VR256:$src))),  (v4i64 VR256:$src)>;
235   def : Pat<(v4i64  (bitconvert (v8i32 VR256:$src))),  (v4i64 VR256:$src)>;
236   def : Pat<(v4i64  (bitconvert (v4f64 VR256:$src))),  (v4i64 VR256:$src)>;
237   def : Pat<(v4i64  (bitconvert (v32i8 VR256:$src))),  (v4i64 VR256:$src)>;
238   def : Pat<(v4i64  (bitconvert (v16i16 VR256:$src))), (v4i64 VR256:$src)>;
239   def : Pat<(v32i8  (bitconvert (v4f64 VR256:$src))),  (v32i8 VR256:$src)>;
240   def : Pat<(v32i8  (bitconvert (v4i64 VR256:$src))),  (v32i8 VR256:$src)>;
241   def : Pat<(v32i8  (bitconvert (v8f32 VR256:$src))),  (v32i8 VR256:$src)>;
242   def : Pat<(v32i8  (bitconvert (v8i32 VR256:$src))),  (v32i8 VR256:$src)>;
243   def : Pat<(v32i8  (bitconvert (v16i16 VR256:$src))), (v32i8 VR256:$src)>;
244   def : Pat<(v8i32  (bitconvert (v32i8 VR256:$src))),  (v8i32 VR256:$src)>;
245   def : Pat<(v8i32  (bitconvert (v16i16 VR256:$src))), (v8i32 VR256:$src)>;
246   def : Pat<(v8i32  (bitconvert (v8f32 VR256:$src))),  (v8i32 VR256:$src)>;
247   def : Pat<(v8i32  (bitconvert (v4i64 VR256:$src))),  (v8i32 VR256:$src)>;
248   def : Pat<(v8i32  (bitconvert (v4f64 VR256:$src))),  (v8i32 VR256:$src)>;
249   def : Pat<(v16i16 (bitconvert (v8f32 VR256:$src))),  (v16i16 VR256:$src)>;
250   def : Pat<(v16i16 (bitconvert (v8i32 VR256:$src))),  (v16i16 VR256:$src)>;
251   def : Pat<(v16i16 (bitconvert (v4i64 VR256:$src))),  (v16i16 VR256:$src)>;
252   def : Pat<(v16i16 (bitconvert (v4f64 VR256:$src))),  (v16i16 VR256:$src)>;
253   def : Pat<(v16i16 (bitconvert (v32i8 VR256:$src))),  (v16i16 VR256:$src)>;
254 }
255
256 // Alias instructions that map fld0 to pxor for sse.
257 // FIXME: Set encoding to pseudo!
258 let isReMaterializable = 1, isAsCheapAsAMove = 1, isCodeGenOnly = 1,
259     canFoldAsLoad = 1 in {
260   def FsFLD0SS : I<0xEF, MRMInitReg, (outs FR32:$dst), (ins), "",
261                    [(set FR32:$dst, fp32imm0)]>,
262                    Requires<[HasSSE1]>, TB, OpSize;
263   def FsFLD0SD : I<0xEF, MRMInitReg, (outs FR64:$dst), (ins), "",
264                    [(set FR64:$dst, fpimm0)]>,
265                  Requires<[HasSSE2]>, TB, OpSize;
266   def VFsFLD0SS : I<0xEF, MRMInitReg, (outs FR32:$dst), (ins), "",
267                     [(set FR32:$dst, fp32imm0)]>,
268                     Requires<[HasAVX]>, TB, OpSize, VEX_4V;
269   def VFsFLD0SD : I<0xEF, MRMInitReg, (outs FR64:$dst), (ins), "",
270                     [(set FR64:$dst, fpimm0)]>,
271                     Requires<[HasAVX]>, TB, OpSize, VEX_4V;
272 }
273
274 //===----------------------------------------------------------------------===//
275 // AVX & SSE - Zero/One Vectors
276 //===----------------------------------------------------------------------===//
277
278 // Alias instructions that map zero vector to pxor / xorp* for sse.
279 // We set canFoldAsLoad because this can be converted to a constant-pool
280 // load of an all-zeros value if folding it would be beneficial.
281 // FIXME: Change encoding to pseudo! This is blocked right now by the x86
282 // JIT implementation, it does not expand the instructions below like
283 // X86MCInstLower does.
284 let isReMaterializable = 1, isAsCheapAsAMove = 1, canFoldAsLoad = 1,
285     isCodeGenOnly = 1 in {
286 def V_SET0PS : PSI<0x57, MRMInitReg, (outs VR128:$dst), (ins), "",
287                  [(set VR128:$dst, (v4f32 immAllZerosV))]>;
288 def V_SET0PD : PDI<0x57, MRMInitReg, (outs VR128:$dst), (ins), "",
289                  [(set VR128:$dst, (v2f64 immAllZerosV))]>;
290 let ExeDomain = SSEPackedInt in
291 def V_SET0PI : PDI<0xEF, MRMInitReg, (outs VR128:$dst), (ins), "",
292                  [(set VR128:$dst, (v4i32 immAllZerosV))]>;
293 }
294
295 // The same as done above but for AVX. The 128-bit versions are the
296 // same, but re-encoded. The 256-bit does not support PI version, and
297 // doesn't need it because on sandy bridge the register is set to zero
298 // at the rename stage without using any execution unit, so SET0PSY
299 // and SET0PDY can be used for vector int instructions without penalty
300 // FIXME: Change encoding to pseudo! This is blocked right now by the x86
301 // JIT implementatioan, it does not expand the instructions below like
302 // X86MCInstLower does.
303 let isReMaterializable = 1, isAsCheapAsAMove = 1, canFoldAsLoad = 1,
304     isCodeGenOnly = 1, Predicates = [HasAVX] in {
305 def AVX_SET0PS  : PSI<0x57, MRMInitReg, (outs VR128:$dst), (ins), "",
306                    [(set VR128:$dst, (v4f32 immAllZerosV))]>, VEX_4V;
307 def AVX_SET0PD  : PDI<0x57, MRMInitReg, (outs VR128:$dst), (ins), "",
308                    [(set VR128:$dst, (v2f64 immAllZerosV))]>, VEX_4V;
309 def AVX_SET0PSY : PSI<0x57, MRMInitReg, (outs VR256:$dst), (ins), "",
310                    [(set VR256:$dst, (v8f32 immAllZerosV))]>, VEX_4V;
311 def AVX_SET0PDY : PDI<0x57, MRMInitReg, (outs VR256:$dst), (ins), "",
312                    [(set VR256:$dst, (v4f64 immAllZerosV))]>, VEX_4V;
313 let ExeDomain = SSEPackedInt in
314 def AVX_SET0PI  : PDI<0xEF, MRMInitReg, (outs VR128:$dst), (ins), "",
315                    [(set VR128:$dst, (v4i32 immAllZerosV))]>;
316 }
317
318 def : Pat<(v2i64 immAllZerosV), (V_SET0PI)>;
319 def : Pat<(v8i16 immAllZerosV), (V_SET0PI)>;
320 def : Pat<(v16i8 immAllZerosV), (V_SET0PI)>;
321
322 // AVX has no support for 256-bit integer instructions, but since the 128-bit
323 // VPXOR instruction writes zero to its upper part, it's safe build zeros.
324 def : Pat<(v8i32 immAllZerosV), (SUBREG_TO_REG (i32 0), (AVX_SET0PI), sub_xmm)>;
325 def : Pat<(bc_v8i32 (v8f32 immAllZerosV)),
326           (SUBREG_TO_REG (i32 0), (AVX_SET0PI), sub_xmm)>;
327
328 def : Pat<(v4i64 immAllZerosV), (SUBREG_TO_REG (i64 0), (AVX_SET0PI), sub_xmm)>;
329 def : Pat<(bc_v4i64 (v8f32 immAllZerosV)),
330           (SUBREG_TO_REG (i64 0), (AVX_SET0PI), sub_xmm)>;
331
332 // We set canFoldAsLoad because this can be converted to a constant-pool
333 // load of an all-ones value if folding it would be beneficial.
334 // FIXME: Change encoding to pseudo! This is blocked right now by the x86
335 // JIT implementation, it does not expand the instructions below like
336 // X86MCInstLower does.
337 let isReMaterializable = 1, isAsCheapAsAMove = 1, canFoldAsLoad = 1,
338     isCodeGenOnly = 1, ExeDomain = SSEPackedInt in
339   def V_SETALLONES : PDI<0x76, MRMInitReg, (outs VR128:$dst), (ins), "",
340                          [(set VR128:$dst, (v4i32 immAllOnesV))]>;
341 let isReMaterializable = 1, isAsCheapAsAMove = 1, canFoldAsLoad = 1,
342     isCodeGenOnly = 1, ExeDomain = SSEPackedInt, Predicates = [HasAVX] in
343   def AVX_SETALLONES : PDI<0x76, MRMInitReg, (outs VR128:$dst), (ins), "",
344                          [(set VR128:$dst, (v4i32 immAllOnesV))]>, VEX_4V;
345
346
347 //===----------------------------------------------------------------------===//
348 // SSE 1 & 2 - Move FP Scalar Instructions
349 //
350 // Move Instructions. Register-to-register movss/movsd is not used for FR32/64
351 // register copies because it's a partial register update; FsMOVAPSrr/FsMOVAPDrr
352 // is used instead. Register-to-register movss/movsd is not modeled as an
353 // INSERT_SUBREG because INSERT_SUBREG requires that the insert be implementable
354 // in terms of a copy, and just mentioned, we don't use movss/movsd for copies.
355 //===----------------------------------------------------------------------===//
356
357 class sse12_move_rr<RegisterClass RC, ValueType vt, string asm> :
358       SI<0x10, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src1, RC:$src2), asm,
359       [(set (vt VR128:$dst), (movl VR128:$src1, (scalar_to_vector RC:$src2)))]>;
360
361 // Loading from memory automatically zeroing upper bits.
362 class sse12_move_rm<RegisterClass RC, X86MemOperand x86memop,
363                     PatFrag mem_pat, string OpcodeStr> :
364       SI<0x10, MRMSrcMem, (outs RC:$dst), (ins x86memop:$src),
365          !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
366                         [(set RC:$dst, (mem_pat addr:$src))]>;
367
368 // AVX
369 def VMOVSSrr : sse12_move_rr<FR32, v4f32,
370                 "movss\t{$src2, $src1, $dst|$dst, $src1, $src2}">, XS, VEX_4V;
371 def VMOVSDrr : sse12_move_rr<FR64, v2f64,
372                 "movsd\t{$src2, $src1, $dst|$dst, $src1, $src2}">, XD, VEX_4V;
373
374 // For the disassembler
375 let isCodeGenOnly = 1 in {
376   def VMOVSSrr_REV : SI<0x11, MRMDestReg, (outs VR128:$dst),
377                         (ins VR128:$src1, FR32:$src2),
378                         "movss\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>,
379                         XS, VEX_4V;
380   def VMOVSDrr_REV : SI<0x11, MRMDestReg, (outs VR128:$dst),
381                         (ins VR128:$src1, FR64:$src2),
382                         "movsd\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>,
383                         XD, VEX_4V;
384 }
385
386 let canFoldAsLoad = 1, isReMaterializable = 1 in {
387   def VMOVSSrm : sse12_move_rm<FR32, f32mem, loadf32, "movss">, XS, VEX;
388   let AddedComplexity = 20 in
389     def VMOVSDrm : sse12_move_rm<FR64, f64mem, loadf64, "movsd">, XD, VEX;
390 }
391
392 def VMOVSSmr : SI<0x11, MRMDestMem, (outs), (ins f32mem:$dst, FR32:$src),
393                   "movss\t{$src, $dst|$dst, $src}",
394                   [(store FR32:$src, addr:$dst)]>, XS, VEX;
395 def VMOVSDmr : SI<0x11, MRMDestMem, (outs), (ins f64mem:$dst, FR64:$src),
396                   "movsd\t{$src, $dst|$dst, $src}",
397                   [(store FR64:$src, addr:$dst)]>, XD, VEX;
398
399 // SSE1 & 2
400 let Constraints = "$src1 = $dst" in {
401   def MOVSSrr : sse12_move_rr<FR32, v4f32,
402                           "movss\t{$src2, $dst|$dst, $src2}">, XS;
403   def MOVSDrr : sse12_move_rr<FR64, v2f64,
404                           "movsd\t{$src2, $dst|$dst, $src2}">, XD;
405
406   // For the disassembler
407   let isCodeGenOnly = 1 in {
408     def MOVSSrr_REV : SI<0x11, MRMDestReg, (outs VR128:$dst),
409                          (ins VR128:$src1, FR32:$src2),
410                          "movss\t{$src2, $dst|$dst, $src2}", []>, XS;
411     def MOVSDrr_REV : SI<0x11, MRMDestReg, (outs VR128:$dst),
412                          (ins VR128:$src1, FR64:$src2),
413                          "movsd\t{$src2, $dst|$dst, $src2}", []>, XD;
414   }
415 }
416
417 let canFoldAsLoad = 1, isReMaterializable = 1 in {
418   def MOVSSrm : sse12_move_rm<FR32, f32mem, loadf32, "movss">, XS;
419
420   let AddedComplexity = 20 in
421     def MOVSDrm : sse12_move_rm<FR64, f64mem, loadf64, "movsd">, XD;
422 }
423
424 def MOVSSmr : SSI<0x11, MRMDestMem, (outs), (ins f32mem:$dst, FR32:$src),
425                   "movss\t{$src, $dst|$dst, $src}",
426                   [(store FR32:$src, addr:$dst)]>;
427 def MOVSDmr : SDI<0x11, MRMDestMem, (outs), (ins f64mem:$dst, FR64:$src),
428                   "movsd\t{$src, $dst|$dst, $src}",
429                   [(store FR64:$src, addr:$dst)]>;
430
431 // Patterns
432 let Predicates = [HasSSE1] in {
433   let AddedComplexity = 15 in {
434   // Extract the low 32-bit value from one vector and insert it into another.
435   def : Pat<(v4f32 (movl VR128:$src1, VR128:$src2)),
436             (MOVSSrr (v4f32 VR128:$src1),
437                      (EXTRACT_SUBREG (v4f32 VR128:$src2), sub_ss))>;
438   def : Pat<(v4i32 (movl VR128:$src1, VR128:$src2)),
439             (MOVSSrr (v4i32 VR128:$src1),
440                      (EXTRACT_SUBREG (v4i32 VR128:$src2), sub_ss))>;
441
442   // Move scalar to XMM zero-extended, zeroing a VR128 then do a
443   // MOVSS to the lower bits.
444   def : Pat<(v4f32 (X86vzmovl (v4f32 (scalar_to_vector FR32:$src)))),
445             (MOVSSrr (v4f32 (V_SET0PS)), FR32:$src)>;
446   def : Pat<(v4f32 (X86vzmovl (v4f32 VR128:$src))),
447             (MOVSSrr (v4f32 (V_SET0PS)),
448                      (f32 (EXTRACT_SUBREG (v4f32 VR128:$src), sub_ss)))>;
449   def : Pat<(v4i32 (X86vzmovl (v4i32 VR128:$src))),
450             (MOVSSrr (v4i32 (V_SET0PI)),
451                      (EXTRACT_SUBREG (v4i32 VR128:$src), sub_ss))>;
452   }
453
454   let AddedComplexity = 20 in {
455   // MOVSSrm zeros the high parts of the register; represent this
456   // with SUBREG_TO_REG.
457   def : Pat<(v4f32 (X86vzmovl (v4f32 (scalar_to_vector (loadf32 addr:$src))))),
458             (SUBREG_TO_REG (i32 0), (MOVSSrm addr:$src), sub_ss)>;
459   def : Pat<(v4f32 (scalar_to_vector (loadf32 addr:$src))),
460             (SUBREG_TO_REG (i32 0), (MOVSSrm addr:$src), sub_ss)>;
461   def : Pat<(v4f32 (X86vzmovl (loadv4f32 addr:$src))),
462             (SUBREG_TO_REG (i32 0), (MOVSSrm addr:$src), sub_ss)>;
463   }
464
465   // Extract and store.
466   def : Pat<(store (f32 (vector_extract (v4f32 VR128:$src), (iPTR 0))),
467                    addr:$dst),
468             (MOVSSmr addr:$dst,
469                      (EXTRACT_SUBREG (v4f32 VR128:$src), sub_ss))>;
470
471   // Shuffle with MOVSS
472   def : Pat<(v4f32 (X86Movss VR128:$src1, (scalar_to_vector FR32:$src2))),
473             (MOVSSrr VR128:$src1, FR32:$src2)>;
474   def : Pat<(v4i32 (X86Movss VR128:$src1, VR128:$src2)),
475             (MOVSSrr (v4i32 VR128:$src1),
476                      (EXTRACT_SUBREG (v4i32 VR128:$src2), sub_ss))>;
477   def : Pat<(v4f32 (X86Movss VR128:$src1, VR128:$src2)),
478             (MOVSSrr (v4f32 VR128:$src1),
479                      (EXTRACT_SUBREG (v4f32 VR128:$src2), sub_ss))>;
480 }
481
482 let Predicates = [HasSSE2] in {
483   let AddedComplexity = 15 in {
484   // Extract the low 64-bit value from one vector and insert it into another.
485   def : Pat<(v2f64 (movl VR128:$src1, VR128:$src2)),
486             (MOVSDrr (v2f64 VR128:$src1),
487                      (EXTRACT_SUBREG (v2f64 VR128:$src2), sub_sd))>;
488   def : Pat<(v2i64 (movl VR128:$src1, VR128:$src2)),
489             (MOVSDrr (v2i64 VR128:$src1),
490                      (EXTRACT_SUBREG (v2i64 VR128:$src2), sub_sd))>;
491
492   // vector_shuffle v1, v2 <4, 5, 2, 3> using movsd
493   def : Pat<(v4f32 (movlp VR128:$src1, VR128:$src2)),
494             (MOVSDrr VR128:$src1, (EXTRACT_SUBREG VR128:$src2, sub_sd))>;
495   def : Pat<(v4i32 (movlp VR128:$src1, VR128:$src2)),
496             (MOVSDrr VR128:$src1, (EXTRACT_SUBREG VR128:$src2, sub_sd))>;
497
498   // Move scalar to XMM zero-extended, zeroing a VR128 then do a
499   // MOVSD to the lower bits.
500   def : Pat<(v2f64 (X86vzmovl (v2f64 (scalar_to_vector FR64:$src)))),
501             (MOVSDrr (v2f64 (V_SET0PS)), FR64:$src)>;
502   }
503
504   let AddedComplexity = 20 in {
505   // MOVSDrm zeros the high parts of the register; represent this
506   // with SUBREG_TO_REG.
507   def : Pat<(v2f64 (X86vzmovl (v2f64 (scalar_to_vector (loadf64 addr:$src))))),
508             (SUBREG_TO_REG (i64 0), (MOVSDrm addr:$src), sub_sd)>;
509   def : Pat<(v2f64 (scalar_to_vector (loadf64 addr:$src))),
510             (SUBREG_TO_REG (i64 0), (MOVSDrm addr:$src), sub_sd)>;
511   def : Pat<(v2f64 (X86vzmovl (loadv2f64 addr:$src))),
512             (SUBREG_TO_REG (i64 0), (MOVSDrm addr:$src), sub_sd)>;
513   def : Pat<(v2f64 (X86vzmovl (bc_v2f64 (loadv4f32 addr:$src)))),
514             (SUBREG_TO_REG (i64 0), (MOVSDrm addr:$src), sub_sd)>;
515   def : Pat<(v2f64 (X86vzload addr:$src)),
516             (SUBREG_TO_REG (i64 0), (MOVSDrm addr:$src), sub_sd)>;
517   }
518
519   // Extract and store.
520   def : Pat<(store (f64 (vector_extract (v2f64 VR128:$src), (iPTR 0))),
521                    addr:$dst),
522             (MOVSDmr addr:$dst,
523                      (EXTRACT_SUBREG (v2f64 VR128:$src), sub_sd))>;
524
525   // Shuffle with MOVSD
526   def : Pat<(v2f64 (X86Movsd VR128:$src1, (scalar_to_vector FR64:$src2))),
527             (MOVSDrr VR128:$src1, FR64:$src2)>;
528   def : Pat<(v2i64 (X86Movsd VR128:$src1, VR128:$src2)),
529             (MOVSDrr (v2i64 VR128:$src1),
530                      (EXTRACT_SUBREG (v2i64 VR128:$src2), sub_sd))>;
531   def : Pat<(v2f64 (X86Movsd VR128:$src1, VR128:$src2)),
532             (MOVSDrr (v2f64 VR128:$src1),
533                      (EXTRACT_SUBREG (v2f64 VR128:$src2), sub_sd))>;
534   def : Pat<(v4f32 (X86Movsd VR128:$src1, VR128:$src2)),
535             (MOVSDrr VR128:$src1, (EXTRACT_SUBREG (v4f32 VR128:$src2),sub_sd))>;
536   def : Pat<(v4i32 (X86Movsd VR128:$src1, VR128:$src2)),
537             (MOVSDrr VR128:$src1, (EXTRACT_SUBREG (v4i32 VR128:$src2),sub_sd))>;
538
539   // FIXME: Instead of a X86Movlps there should be a X86Movsd here, the problem
540   // is during lowering, where it's not possible to recognize the fold cause
541   // it has two uses through a bitcast. One use disappears at isel time and the
542   // fold opportunity reappears.
543   def : Pat<(v4f32 (X86Movlps VR128:$src1, VR128:$src2)),
544             (MOVSDrr VR128:$src1, (EXTRACT_SUBREG (v4f32 VR128:$src2),sub_sd))>;
545   def : Pat<(v4i32 (X86Movlps VR128:$src1, VR128:$src2)),
546             (MOVSDrr VR128:$src1, (EXTRACT_SUBREG (v4i32 VR128:$src2),sub_sd))>;
547 }
548
549 let Predicates = [HasAVX] in {
550   let AddedComplexity = 15 in {
551   // Extract the low 32-bit value from one vector and insert it into another.
552   def : Pat<(v4f32 (movl VR128:$src1, VR128:$src2)),
553             (VMOVSSrr (v4f32 VR128:$src1),
554                       (EXTRACT_SUBREG (v4f32 VR128:$src2), sub_ss))>;
555   def : Pat<(v4i32 (movl VR128:$src1, VR128:$src2)),
556             (VMOVSSrr (v4i32 VR128:$src1),
557                       (EXTRACT_SUBREG (v4i32 VR128:$src2), sub_ss))>;
558
559   // Extract the low 64-bit value from one vector and insert it into another.
560   def : Pat<(v2f64 (movl VR128:$src1, VR128:$src2)),
561             (VMOVSDrr (v2f64 VR128:$src1),
562                       (EXTRACT_SUBREG (v2f64 VR128:$src2), sub_sd))>;
563   def : Pat<(v2i64 (movl VR128:$src1, VR128:$src2)),
564             (VMOVSDrr (v2i64 VR128:$src1),
565                       (EXTRACT_SUBREG (v2i64 VR128:$src2), sub_sd))>;
566
567   // vector_shuffle v1, v2 <4, 5, 2, 3> using movsd
568   def : Pat<(v4f32 (movlp VR128:$src1, VR128:$src2)),
569             (VMOVSDrr VR128:$src1, (EXTRACT_SUBREG VR128:$src2, sub_sd))>;
570   def : Pat<(v4i32 (movlp VR128:$src1, VR128:$src2)),
571             (VMOVSDrr VR128:$src1, (EXTRACT_SUBREG VR128:$src2, sub_sd))>;
572
573   // Move scalar to XMM zero-extended, zeroing a VR128 then do a
574   // MOVS{S,D} to the lower bits.
575   def : Pat<(v4f32 (X86vzmovl (v4f32 (scalar_to_vector FR32:$src)))),
576             (VMOVSSrr (v4f32 (AVX_SET0PS)), FR32:$src)>;
577   def : Pat<(v4f32 (X86vzmovl (v4f32 VR128:$src))),
578             (VMOVSSrr (v4f32 (AVX_SET0PS)),
579                       (f32 (EXTRACT_SUBREG (v4f32 VR128:$src), sub_ss)))>;
580   def : Pat<(v4i32 (X86vzmovl (v4i32 VR128:$src))),
581             (VMOVSSrr (v4i32 (AVX_SET0PI)),
582                       (EXTRACT_SUBREG (v4i32 VR128:$src), sub_ss))>;
583   def : Pat<(v2f64 (X86vzmovl (v2f64 (scalar_to_vector FR64:$src)))),
584             (VMOVSDrr (v2f64 (AVX_SET0PS)), FR64:$src)>;
585   }
586
587   let AddedComplexity = 20 in {
588   // MOVSSrm zeros the high parts of the register; represent this
589   // with SUBREG_TO_REG. The AVX versions also write: DST[255:128] <- 0
590   def : Pat<(v4f32 (X86vzmovl (v4f32 (scalar_to_vector (loadf32 addr:$src))))),
591             (SUBREG_TO_REG (i32 0), (VMOVSSrm addr:$src), sub_ss)>;
592   def : Pat<(v4f32 (scalar_to_vector (loadf32 addr:$src))),
593             (SUBREG_TO_REG (i32 0), (VMOVSSrm addr:$src), sub_ss)>;
594   def : Pat<(v4f32 (X86vzmovl (loadv4f32 addr:$src))),
595             (SUBREG_TO_REG (i32 0), (VMOVSSrm addr:$src), sub_ss)>;
596
597   // MOVSDrm zeros the high parts of the register; represent this
598   // with SUBREG_TO_REG. The AVX versions also write: DST[255:128] <- 0
599   def : Pat<(v2f64 (X86vzmovl (v2f64 (scalar_to_vector (loadf64 addr:$src))))),
600             (SUBREG_TO_REG (i64 0), (VMOVSDrm addr:$src), sub_sd)>;
601   def : Pat<(v2f64 (scalar_to_vector (loadf64 addr:$src))),
602             (SUBREG_TO_REG (i64 0), (VMOVSDrm addr:$src), sub_sd)>;
603   def : Pat<(v2f64 (X86vzmovl (loadv2f64 addr:$src))),
604             (SUBREG_TO_REG (i64 0), (VMOVSDrm addr:$src), sub_sd)>;
605   def : Pat<(v2f64 (X86vzmovl (bc_v2f64 (loadv4f32 addr:$src)))),
606             (SUBREG_TO_REG (i64 0), (VMOVSDrm addr:$src), sub_sd)>;
607   def : Pat<(v2f64 (X86vzload addr:$src)),
608             (SUBREG_TO_REG (i64 0), (VMOVSDrm addr:$src), sub_sd)>;
609
610   // Represent the same patterns above but in the form they appear for
611   // 256-bit types
612   def : Pat<(v8f32 (X86vzmovl (insert_subvector undef,
613                    (v4f32 (scalar_to_vector (loadf32 addr:$src))), (i32 0)))),
614             (SUBREG_TO_REG (i32 0), (VMOVSSrm addr:$src), sub_ss)>;
615   def : Pat<(v4f64 (X86vzmovl (insert_subvector undef,
616                    (v2f64 (scalar_to_vector (loadf64 addr:$src))), (i32 0)))),
617             (SUBREG_TO_REG (i32 0), (VMOVSDrm addr:$src), sub_sd)>;
618   }
619   def : Pat<(v8f32 (X86vzmovl (insert_subvector undef,
620                    (v4f32 (scalar_to_vector FR32:$src)), (i32 0)))),
621             (SUBREG_TO_REG (i32 0),
622                            (v4f32 (VMOVSSrr (v4f32 (AVX_SET0PS)), FR32:$src)),
623                            sub_xmm)>;
624   def : Pat<(v4f64 (X86vzmovl (insert_subvector undef,
625                    (v2f64 (scalar_to_vector FR64:$src)), (i32 0)))),
626             (SUBREG_TO_REG (i64 0),
627                            (v2f64 (VMOVSDrr (v2f64 (AVX_SET0PS)), FR64:$src)),
628                            sub_xmm)>;
629
630   // Extract and store.
631   def : Pat<(store (f32 (vector_extract (v4f32 VR128:$src), (iPTR 0))),
632                    addr:$dst),
633             (VMOVSSmr addr:$dst,
634                      (EXTRACT_SUBREG (v4f32 VR128:$src), sub_ss))>;
635   def : Pat<(store (f64 (vector_extract (v2f64 VR128:$src), (iPTR 0))),
636                    addr:$dst),
637             (VMOVSDmr addr:$dst,
638                      (EXTRACT_SUBREG (v2f64 VR128:$src), sub_sd))>;
639
640   // Shuffle with VMOVSS
641   def : Pat<(v4f32 (X86Movss VR128:$src1, (scalar_to_vector FR32:$src2))),
642             (VMOVSSrr VR128:$src1, FR32:$src2)>;
643   def : Pat<(v4i32 (X86Movss VR128:$src1, VR128:$src2)),
644             (VMOVSSrr (v4i32 VR128:$src1),
645                       (EXTRACT_SUBREG (v4i32 VR128:$src2), sub_ss))>;
646   def : Pat<(v4f32 (X86Movss VR128:$src1, VR128:$src2)),
647             (VMOVSSrr (v4f32 VR128:$src1),
648                       (EXTRACT_SUBREG (v4f32 VR128:$src2), sub_ss))>;
649
650   // Shuffle with VMOVSD
651   def : Pat<(v2f64 (X86Movsd VR128:$src1, (scalar_to_vector FR64:$src2))),
652             (VMOVSDrr VR128:$src1, FR64:$src2)>;
653   def : Pat<(v2i64 (X86Movsd VR128:$src1, VR128:$src2)),
654             (VMOVSDrr (v2i64 VR128:$src1),
655                      (EXTRACT_SUBREG (v2i64 VR128:$src2), sub_sd))>;
656   def : Pat<(v2f64 (X86Movsd VR128:$src1, VR128:$src2)),
657             (VMOVSDrr (v2f64 VR128:$src1),
658                      (EXTRACT_SUBREG (v2f64 VR128:$src2), sub_sd))>;
659   def : Pat<(v4f32 (X86Movsd VR128:$src1, VR128:$src2)),
660             (VMOVSDrr VR128:$src1, (EXTRACT_SUBREG (v4f32 VR128:$src2),
661                                                    sub_sd))>;
662   def : Pat<(v4i32 (X86Movsd VR128:$src1, VR128:$src2)),
663             (VMOVSDrr VR128:$src1, (EXTRACT_SUBREG (v4i32 VR128:$src2),
664                                                    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<(v4f32 (X86Movlps VR128:$src1, VR128:$src2)),
671             (VMOVSDrr VR128:$src1, (EXTRACT_SUBREG (v4f32 VR128:$src2),
672                                                    sub_sd))>;
673   def : Pat<(v4i32 (X86Movlps VR128:$src1, VR128:$src2)),
674             (VMOVSDrr VR128:$src1, (EXTRACT_SUBREG (v4i32 VR128:$src2),
675                                                    sub_sd))>;
676 }
677
678 //===----------------------------------------------------------------------===//
679 // SSE 1 & 2 - Move Aligned/Unaligned FP Instructions
680 //===----------------------------------------------------------------------===//
681
682 multiclass sse12_mov_packed<bits<8> opc, RegisterClass RC,
683                             X86MemOperand x86memop, PatFrag ld_frag,
684                             string asm, Domain d,
685                             bit IsReMaterializable = 1> {
686 let neverHasSideEffects = 1 in
687   def rr : PI<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src),
688               !strconcat(asm, "\t{$src, $dst|$dst, $src}"), [], d>;
689 let canFoldAsLoad = 1, isReMaterializable = IsReMaterializable in
690   def rm : PI<opc, MRMSrcMem, (outs RC:$dst), (ins x86memop:$src),
691               !strconcat(asm, "\t{$src, $dst|$dst, $src}"),
692                    [(set RC:$dst, (ld_frag addr:$src))], d>;
693 }
694
695 defm VMOVAPS : sse12_mov_packed<0x28, VR128, f128mem, alignedloadv4f32,
696                               "movaps", SSEPackedSingle>, TB, VEX;
697 defm VMOVAPD : sse12_mov_packed<0x28, VR128, f128mem, alignedloadv2f64,
698                               "movapd", SSEPackedDouble>, TB, OpSize, VEX;
699 defm VMOVUPS : sse12_mov_packed<0x10, VR128, f128mem, loadv4f32,
700                               "movups", SSEPackedSingle>, TB, VEX;
701 defm VMOVUPD : sse12_mov_packed<0x10, VR128, f128mem, loadv2f64,
702                               "movupd", SSEPackedDouble, 0>, TB, OpSize, VEX;
703
704 defm VMOVAPSY : sse12_mov_packed<0x28, VR256, f256mem, alignedloadv8f32,
705                               "movaps", SSEPackedSingle>, TB, VEX;
706 defm VMOVAPDY : sse12_mov_packed<0x28, VR256, f256mem, alignedloadv4f64,
707                               "movapd", SSEPackedDouble>, TB, OpSize, VEX;
708 defm VMOVUPSY : sse12_mov_packed<0x10, VR256, f256mem, loadv8f32,
709                               "movups", SSEPackedSingle>, TB, VEX;
710 defm VMOVUPDY : sse12_mov_packed<0x10, VR256, f256mem, loadv4f64,
711                               "movupd", SSEPackedDouble, 0>, TB, OpSize, VEX;
712 defm MOVAPS : sse12_mov_packed<0x28, VR128, f128mem, alignedloadv4f32,
713                               "movaps", SSEPackedSingle>, TB;
714 defm MOVAPD : sse12_mov_packed<0x28, VR128, f128mem, alignedloadv2f64,
715                               "movapd", SSEPackedDouble>, TB, OpSize;
716 defm MOVUPS : sse12_mov_packed<0x10, VR128, f128mem, loadv4f32,
717                               "movups", SSEPackedSingle>, TB;
718 defm MOVUPD : sse12_mov_packed<0x10, VR128, f128mem, loadv2f64,
719                               "movupd", SSEPackedDouble, 0>, TB, OpSize;
720
721 def VMOVAPSmr : VPSI<0x29, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
722                    "movaps\t{$src, $dst|$dst, $src}",
723                    [(alignedstore (v4f32 VR128:$src), addr:$dst)]>, VEX;
724 def VMOVAPDmr : VPDI<0x29, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
725                    "movapd\t{$src, $dst|$dst, $src}",
726                    [(alignedstore (v2f64 VR128:$src), addr:$dst)]>, VEX;
727 def VMOVUPSmr : VPSI<0x11, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
728                    "movups\t{$src, $dst|$dst, $src}",
729                    [(store (v4f32 VR128:$src), addr:$dst)]>, VEX;
730 def VMOVUPDmr : VPDI<0x11, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
731                    "movupd\t{$src, $dst|$dst, $src}",
732                    [(store (v2f64 VR128:$src), addr:$dst)]>, VEX;
733 def VMOVAPSYmr : VPSI<0x29, MRMDestMem, (outs), (ins f256mem:$dst, VR256:$src),
734                    "movaps\t{$src, $dst|$dst, $src}",
735                    [(alignedstore256 (v8f32 VR256:$src), addr:$dst)]>, VEX;
736 def VMOVAPDYmr : VPDI<0x29, MRMDestMem, (outs), (ins f256mem:$dst, VR256:$src),
737                    "movapd\t{$src, $dst|$dst, $src}",
738                    [(alignedstore256 (v4f64 VR256:$src), addr:$dst)]>, VEX;
739 def VMOVUPSYmr : VPSI<0x11, MRMDestMem, (outs), (ins f256mem:$dst, VR256:$src),
740                    "movups\t{$src, $dst|$dst, $src}",
741                    [(store (v8f32 VR256:$src), addr:$dst)]>, VEX;
742 def VMOVUPDYmr : VPDI<0x11, MRMDestMem, (outs), (ins f256mem:$dst, VR256:$src),
743                    "movupd\t{$src, $dst|$dst, $src}",
744                    [(store (v4f64 VR256:$src), addr:$dst)]>, VEX;
745
746 // For disassembler
747 let isCodeGenOnly = 1 in {
748   def VMOVAPSrr_REV : VPSI<0x29, MRMDestReg, (outs VR128:$dst),
749                           (ins VR128:$src),
750                           "movaps\t{$src, $dst|$dst, $src}", []>, VEX;
751   def VMOVAPDrr_REV : VPDI<0x29, MRMDestReg, (outs VR128:$dst),
752                            (ins VR128:$src),
753                            "movapd\t{$src, $dst|$dst, $src}", []>, VEX;
754   def VMOVUPSrr_REV : VPSI<0x11, MRMDestReg, (outs VR128:$dst),
755                            (ins VR128:$src),
756                            "movups\t{$src, $dst|$dst, $src}", []>, VEX;
757   def VMOVUPDrr_REV : VPDI<0x11, MRMDestReg, (outs VR128:$dst),
758                            (ins VR128:$src),
759                            "movupd\t{$src, $dst|$dst, $src}", []>, VEX;
760   def VMOVAPSYrr_REV : VPSI<0x29, MRMDestReg, (outs VR256:$dst),
761                             (ins VR256:$src),
762                             "movaps\t{$src, $dst|$dst, $src}", []>, VEX;
763   def VMOVAPDYrr_REV : VPDI<0x29, MRMDestReg, (outs VR256:$dst),
764                             (ins VR256:$src),
765                             "movapd\t{$src, $dst|$dst, $src}", []>, VEX;
766   def VMOVUPSYrr_REV : VPSI<0x11, MRMDestReg, (outs VR256:$dst),
767                             (ins VR256:$src),
768                             "movups\t{$src, $dst|$dst, $src}", []>, VEX;
769   def VMOVUPDYrr_REV : VPDI<0x11, MRMDestReg, (outs VR256:$dst),
770                             (ins VR256:$src),
771                             "movupd\t{$src, $dst|$dst, $src}", []>, VEX;
772 }
773
774 def : Pat<(int_x86_avx_loadu_ps_256 addr:$src), (VMOVUPSYrm addr:$src)>;
775 def : Pat<(int_x86_avx_storeu_ps_256 addr:$dst, VR256:$src),
776           (VMOVUPSYmr addr:$dst, VR256:$src)>;
777
778 def : Pat<(int_x86_avx_loadu_pd_256 addr:$src), (VMOVUPDYrm addr:$src)>;
779 def : Pat<(int_x86_avx_storeu_pd_256 addr:$dst, VR256:$src),
780           (VMOVUPDYmr addr:$dst, VR256:$src)>;
781
782 def MOVAPSmr : PSI<0x29, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
783                    "movaps\t{$src, $dst|$dst, $src}",
784                    [(alignedstore (v4f32 VR128:$src), addr:$dst)]>;
785 def MOVAPDmr : PDI<0x29, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
786                    "movapd\t{$src, $dst|$dst, $src}",
787                    [(alignedstore (v2f64 VR128:$src), addr:$dst)]>;
788 def MOVUPSmr : PSI<0x11, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
789                    "movups\t{$src, $dst|$dst, $src}",
790                    [(store (v4f32 VR128:$src), addr:$dst)]>;
791 def MOVUPDmr : PDI<0x11, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
792                    "movupd\t{$src, $dst|$dst, $src}",
793                    [(store (v2f64 VR128:$src), addr:$dst)]>;
794
795 // For disassembler
796 let isCodeGenOnly = 1 in {
797   def MOVAPSrr_REV : PSI<0x29, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
798                          "movaps\t{$src, $dst|$dst, $src}", []>;
799   def MOVAPDrr_REV : PDI<0x29, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
800                          "movapd\t{$src, $dst|$dst, $src}", []>;
801   def MOVUPSrr_REV : PSI<0x11, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
802                          "movups\t{$src, $dst|$dst, $src}", []>;
803   def MOVUPDrr_REV : PDI<0x11, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
804                          "movupd\t{$src, $dst|$dst, $src}", []>;
805 }
806
807 let Predicates = [HasAVX] in {
808   def : Pat<(int_x86_sse_storeu_ps addr:$dst, VR128:$src),
809             (VMOVUPSmr addr:$dst, VR128:$src)>;
810   def : Pat<(int_x86_sse2_storeu_pd addr:$dst, VR128:$src),
811             (VMOVUPDmr addr:$dst, VR128:$src)>;
812 }
813
814 let Predicates = [HasSSE1] in
815   def : Pat<(int_x86_sse_storeu_ps addr:$dst, VR128:$src),
816             (MOVUPSmr addr:$dst, VR128:$src)>;
817 let Predicates = [HasSSE2] in
818   def : Pat<(int_x86_sse2_storeu_pd addr:$dst, VR128:$src),
819             (MOVUPDmr addr:$dst, VR128:$src)>;
820
821 // Use movaps / movups for SSE integer load / store (one byte shorter).
822 // The instructions selected below are then converted to MOVDQA/MOVDQU
823 // during the SSE domain pass.
824 let Predicates = [HasSSE1] in {
825   def : Pat<(alignedloadv4i32 addr:$src),
826             (MOVAPSrm addr:$src)>;
827   def : Pat<(loadv4i32 addr:$src),
828             (MOVUPSrm addr:$src)>;
829   def : Pat<(alignedloadv2i64 addr:$src),
830             (MOVAPSrm addr:$src)>;
831   def : Pat<(loadv2i64 addr:$src),
832             (MOVUPSrm addr:$src)>;
833
834   def : Pat<(alignedstore (v2i64 VR128:$src), addr:$dst),
835             (MOVAPSmr addr:$dst, VR128:$src)>;
836   def : Pat<(alignedstore (v4i32 VR128:$src), addr:$dst),
837             (MOVAPSmr addr:$dst, VR128:$src)>;
838   def : Pat<(alignedstore (v8i16 VR128:$src), addr:$dst),
839             (MOVAPSmr addr:$dst, VR128:$src)>;
840   def : Pat<(alignedstore (v16i8 VR128:$src), addr:$dst),
841             (MOVAPSmr addr:$dst, VR128:$src)>;
842   def : Pat<(store (v2i64 VR128:$src), addr:$dst),
843             (MOVUPSmr addr:$dst, VR128:$src)>;
844   def : Pat<(store (v4i32 VR128:$src), addr:$dst),
845             (MOVUPSmr addr:$dst, VR128:$src)>;
846   def : Pat<(store (v8i16 VR128:$src), addr:$dst),
847             (MOVUPSmr addr:$dst, VR128:$src)>;
848   def : Pat<(store (v16i8 VR128:$src), addr:$dst),
849             (MOVUPSmr addr:$dst, VR128:$src)>;
850 }
851
852 // Use vmovaps/vmovups for AVX integer load/store.
853 let Predicates = [HasAVX] in {
854   // 128-bit load/store
855   def : Pat<(alignedloadv4i32 addr:$src),
856             (VMOVAPSrm addr:$src)>;
857   def : Pat<(loadv4i32 addr:$src),
858             (VMOVUPSrm addr:$src)>;
859   def : Pat<(alignedloadv2i64 addr:$src),
860             (VMOVAPSrm addr:$src)>;
861   def : Pat<(loadv2i64 addr:$src),
862             (VMOVUPSrm addr:$src)>;
863
864   def : Pat<(alignedstore (v2i64 VR128:$src), addr:$dst),
865             (VMOVAPSmr addr:$dst, VR128:$src)>;
866   def : Pat<(alignedstore (v4i32 VR128:$src), addr:$dst),
867             (VMOVAPSmr addr:$dst, VR128:$src)>;
868   def : Pat<(alignedstore (v8i16 VR128:$src), addr:$dst),
869             (VMOVAPSmr addr:$dst, VR128:$src)>;
870   def : Pat<(alignedstore (v16i8 VR128:$src), addr:$dst),
871             (VMOVAPSmr addr:$dst, VR128:$src)>;
872   def : Pat<(store (v2i64 VR128:$src), addr:$dst),
873             (VMOVUPSmr addr:$dst, VR128:$src)>;
874   def : Pat<(store (v4i32 VR128:$src), addr:$dst),
875             (VMOVUPSmr addr:$dst, VR128:$src)>;
876   def : Pat<(store (v8i16 VR128:$src), addr:$dst),
877             (VMOVUPSmr addr:$dst, VR128:$src)>;
878   def : Pat<(store (v16i8 VR128:$src), addr:$dst),
879             (VMOVUPSmr addr:$dst, VR128:$src)>;
880
881   // 256-bit load/store
882   def : Pat<(alignedloadv4i64 addr:$src),
883             (VMOVAPSYrm addr:$src)>;
884   def : Pat<(loadv4i64 addr:$src),
885             (VMOVUPSYrm addr:$src)>;
886   def : Pat<(alignedloadv8i32 addr:$src),
887             (VMOVAPSYrm addr:$src)>;
888   def : Pat<(loadv8i32 addr:$src),
889             (VMOVUPSYrm addr:$src)>;
890   def : Pat<(alignedstore256 (v4i64 VR256:$src), addr:$dst),
891             (VMOVAPSYmr addr:$dst, VR256:$src)>;
892   def : Pat<(alignedstore256 (v8i32 VR256:$src), addr:$dst),
893             (VMOVAPSYmr addr:$dst, VR256:$src)>;
894   def : Pat<(alignedstore256 (v16i16 VR256:$src), addr:$dst),
895             (VMOVAPSYmr addr:$dst, VR256:$src)>;
896   def : Pat<(alignedstore256 (v32i8 VR256:$src), addr:$dst),
897             (VMOVAPSYmr addr:$dst, VR256:$src)>;
898   def : Pat<(store (v4i64 VR256:$src), addr:$dst),
899             (VMOVUPSYmr addr:$dst, VR256:$src)>;
900   def : Pat<(store (v8i32 VR256:$src), addr:$dst),
901             (VMOVUPSYmr addr:$dst, VR256:$src)>;
902   def : Pat<(store (v16i16 VR256:$src), addr:$dst),
903             (VMOVUPSYmr addr:$dst, VR256:$src)>;
904   def : Pat<(store (v32i8 VR256:$src), addr:$dst),
905             (VMOVUPSYmr addr:$dst, VR256:$src)>;
906 }
907
908 // Alias instruction to do FR32 or FR64 reg-to-reg copy using movaps. Upper
909 // bits are disregarded. FIXME: Set encoding to pseudo!
910 let neverHasSideEffects = 1 in {
911 def FsMOVAPSrr : PSI<0x28, MRMSrcReg, (outs FR32:$dst), (ins FR32:$src),
912                      "movaps\t{$src, $dst|$dst, $src}", []>;
913 def FsMOVAPDrr : PDI<0x28, MRMSrcReg, (outs FR64:$dst), (ins FR64:$src),
914                      "movapd\t{$src, $dst|$dst, $src}", []>;
915 def FsVMOVAPSrr : VPSI<0x28, MRMSrcReg, (outs FR32:$dst), (ins FR32:$src),
916                        "movaps\t{$src, $dst|$dst, $src}", []>, VEX;
917 def FsVMOVAPDrr : VPDI<0x28, MRMSrcReg, (outs FR64:$dst), (ins FR64:$src),
918                        "movapd\t{$src, $dst|$dst, $src}", []>, VEX;
919 }
920
921 // Alias instruction to load FR32 or FR64 from f128mem using movaps. Upper
922 // bits are disregarded. FIXME: Set encoding to pseudo!
923 let canFoldAsLoad = 1, isReMaterializable = 1 in {
924 def FsMOVAPSrm : PSI<0x28, MRMSrcMem, (outs FR32:$dst), (ins f128mem:$src),
925                      "movaps\t{$src, $dst|$dst, $src}",
926                      [(set FR32:$dst, (alignedloadfsf32 addr:$src))]>;
927 def FsMOVAPDrm : PDI<0x28, MRMSrcMem, (outs FR64:$dst), (ins f128mem:$src),
928                      "movapd\t{$src, $dst|$dst, $src}",
929                      [(set FR64:$dst, (alignedloadfsf64 addr:$src))]>;
930 let isCodeGenOnly = 1 in {
931   def FsVMOVAPSrm : VPSI<0x28, MRMSrcMem, (outs FR32:$dst), (ins f128mem:$src),
932                          "movaps\t{$src, $dst|$dst, $src}",
933                          [(set FR32:$dst, (alignedloadfsf32 addr:$src))]>, VEX;
934   def FsVMOVAPDrm : VPDI<0x28, MRMSrcMem, (outs FR64:$dst), (ins f128mem:$src),
935                          "movapd\t{$src, $dst|$dst, $src}",
936                          [(set FR64:$dst, (alignedloadfsf64 addr:$src))]>, VEX;
937 }
938 }
939
940 //===----------------------------------------------------------------------===//
941 // SSE 1 & 2 - Move Low packed FP Instructions
942 //===----------------------------------------------------------------------===//
943
944 multiclass sse12_mov_hilo_packed<bits<8>opc, RegisterClass RC,
945                                  PatFrag mov_frag, string base_opc,
946                                  string asm_opr> {
947   def PSrm : PI<opc, MRMSrcMem,
948          (outs VR128:$dst), (ins VR128:$src1, f64mem:$src2),
949          !strconcat(base_opc, "s", asm_opr),
950      [(set RC:$dst,
951        (mov_frag RC:$src1,
952               (bc_v4f32 (v2f64 (scalar_to_vector (loadf64 addr:$src2))))))],
953               SSEPackedSingle>, TB;
954
955   def PDrm : PI<opc, MRMSrcMem,
956          (outs RC:$dst), (ins RC:$src1, f64mem:$src2),
957          !strconcat(base_opc, "d", asm_opr),
958      [(set RC:$dst, (v2f64 (mov_frag RC:$src1,
959                               (scalar_to_vector (loadf64 addr:$src2)))))],
960               SSEPackedDouble>, TB, OpSize;
961 }
962
963 let AddedComplexity = 20 in {
964   defm VMOVL : sse12_mov_hilo_packed<0x12, VR128, movlp, "movlp",
965                      "\t{$src2, $src1, $dst|$dst, $src1, $src2}">, VEX_4V;
966 }
967 let Constraints = "$src1 = $dst", AddedComplexity = 20 in {
968   defm MOVL : sse12_mov_hilo_packed<0x12, VR128, movlp, "movlp",
969                                    "\t{$src2, $dst|$dst, $src2}">;
970 }
971
972 def VMOVLPSmr : VPSI<0x13, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
973                    "movlps\t{$src, $dst|$dst, $src}",
974                    [(store (f64 (vector_extract (bc_v2f64 (v4f32 VR128:$src)),
975                                  (iPTR 0))), addr:$dst)]>, VEX;
976 def VMOVLPDmr : VPDI<0x13, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
977                    "movlpd\t{$src, $dst|$dst, $src}",
978                    [(store (f64 (vector_extract (v2f64 VR128:$src),
979                                  (iPTR 0))), addr:$dst)]>, VEX;
980 def MOVLPSmr : PSI<0x13, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
981                    "movlps\t{$src, $dst|$dst, $src}",
982                    [(store (f64 (vector_extract (bc_v2f64 (v4f32 VR128:$src)),
983                                  (iPTR 0))), addr:$dst)]>;
984 def MOVLPDmr : PDI<0x13, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
985                    "movlpd\t{$src, $dst|$dst, $src}",
986                    [(store (f64 (vector_extract (v2f64 VR128:$src),
987                                  (iPTR 0))), addr:$dst)]>;
988
989 let Predicates = [HasAVX] in {
990   let AddedComplexity = 20 in {
991     // vector_shuffle v1, (load v2) <4, 5, 2, 3> using MOVLPS
992     def : Pat<(v4f32 (movlp VR128:$src1, (load addr:$src2))),
993               (VMOVLPSrm VR128:$src1, addr:$src2)>;
994     def : Pat<(v4i32 (movlp VR128:$src1, (load addr:$src2))),
995               (VMOVLPSrm VR128:$src1, addr:$src2)>;
996     // vector_shuffle v1, (load v2) <2, 1> using MOVLPS
997     def : Pat<(v2f64 (movlp VR128:$src1, (load addr:$src2))),
998               (VMOVLPDrm VR128:$src1, addr:$src2)>;
999     def : Pat<(v2i64 (movlp VR128:$src1, (load addr:$src2))),
1000               (VMOVLPDrm VR128:$src1, addr:$src2)>;
1001   }
1002
1003   // (store (vector_shuffle (load addr), v2, <4, 5, 2, 3>), addr) using MOVLPS
1004   def : Pat<(store (v4f32 (movlp (load addr:$src1), VR128:$src2)), addr:$src1),
1005             (VMOVLPSmr addr:$src1, VR128:$src2)>;
1006   def : Pat<(store (v4i32 (movlp (bc_v4i32 (loadv2i64 addr:$src1)),
1007                                  VR128:$src2)), addr:$src1),
1008             (VMOVLPSmr addr:$src1, VR128:$src2)>;
1009
1010   // (store (vector_shuffle (load addr), v2, <2, 1>), addr) using MOVLPS
1011   def : Pat<(store (v2f64 (movlp (load addr:$src1), VR128:$src2)), addr:$src1),
1012             (VMOVLPDmr addr:$src1, VR128:$src2)>;
1013   def : Pat<(store (v2i64 (movlp (load addr:$src1), VR128:$src2)), addr:$src1),
1014             (VMOVLPDmr addr:$src1, VR128:$src2)>;
1015
1016   // Shuffle with VMOVLPS
1017   def : Pat<(v4f32 (X86Movlps VR128:$src1, (load addr:$src2))),
1018             (VMOVLPSrm VR128:$src1, addr:$src2)>;
1019   def : Pat<(v4i32 (X86Movlps VR128:$src1, (load addr:$src2))),
1020             (VMOVLPSrm VR128:$src1, addr:$src2)>;
1021   def : Pat<(X86Movlps VR128:$src1,
1022                       (bc_v4f32 (v2f64 (scalar_to_vector (loadf64 addr:$src2))))),
1023             (VMOVLPSrm VR128:$src1, addr:$src2)>;
1024
1025   // Shuffle with VMOVLPD
1026   def : Pat<(v2f64 (X86Movlpd VR128:$src1, (load addr:$src2))),
1027             (VMOVLPDrm VR128:$src1, addr:$src2)>;
1028   def : Pat<(v2i64 (X86Movlpd VR128:$src1, (load addr:$src2))),
1029             (VMOVLPDrm VR128:$src1, addr:$src2)>;
1030   def : Pat<(v2f64 (X86Movlpd VR128:$src1,
1031                               (scalar_to_vector (loadf64 addr:$src2)))),
1032             (VMOVLPDrm VR128:$src1, addr:$src2)>;
1033
1034   // Store patterns
1035   def : Pat<(store (v4f32 (X86Movlps (load addr:$src1), VR128:$src2)),
1036                    addr:$src1),
1037             (VMOVLPSmr addr:$src1, VR128:$src2)>;
1038   def : Pat<(store (v4i32 (X86Movlps
1039                    (bc_v4i32 (loadv2i64 addr:$src1)), VR128:$src2)), addr:$src1),
1040             (VMOVLPSmr addr:$src1, VR128:$src2)>;
1041   def : Pat<(store (v2f64 (X86Movlpd (load addr:$src1), VR128:$src2)),
1042                    addr:$src1),
1043             (VMOVLPDmr addr:$src1, VR128:$src2)>;
1044   def : Pat<(store (v2i64 (X86Movlpd (load addr:$src1), VR128:$src2)),
1045                    addr:$src1),
1046             (VMOVLPDmr addr:$src1, VR128:$src2)>;
1047 }
1048
1049 let Predicates = [HasSSE1] in {
1050   let AddedComplexity = 20 in {
1051     // vector_shuffle v1, (load v2) <4, 5, 2, 3> using MOVLPS
1052     def : Pat<(v4f32 (movlp VR128:$src1, (load addr:$src2))),
1053               (MOVLPSrm VR128:$src1, addr:$src2)>;
1054     def : Pat<(v4i32 (movlp VR128:$src1, (load addr:$src2))),
1055               (MOVLPSrm VR128:$src1, addr:$src2)>;
1056   }
1057
1058   // (store (vector_shuffle (load addr), v2, <4, 5, 2, 3>), addr) using MOVLPS
1059   def : Pat<(store (v4f32 (movlp (load addr:$src1), VR128:$src2)), addr:$src1),
1060             (MOVLPSmr addr:$src1, VR128:$src2)>;
1061   def : Pat<(store (v4i32 (movlp (bc_v4i32 (loadv2i64 addr:$src1)),
1062                                  VR128:$src2)), addr:$src1),
1063             (MOVLPSmr addr:$src1, VR128:$src2)>;
1064
1065   // Shuffle with MOVLPS
1066   def : Pat<(v4f32 (X86Movlps VR128:$src1, (load addr:$src2))),
1067             (MOVLPSrm VR128:$src1, addr:$src2)>;
1068   def : Pat<(v4i32 (X86Movlps VR128:$src1, (load addr:$src2))),
1069             (MOVLPSrm VR128:$src1, addr:$src2)>;
1070   def : Pat<(X86Movlps VR128:$src1,
1071                       (bc_v4f32 (v2f64 (scalar_to_vector (loadf64 addr:$src2))))),
1072             (MOVLPSrm VR128:$src1, addr:$src2)>;
1073
1074   // Store patterns
1075   def : Pat<(store (v4f32 (X86Movlps (load addr:$src1), VR128:$src2)),
1076                                       addr:$src1),
1077             (MOVLPSmr addr:$src1, VR128:$src2)>;
1078   def : Pat<(store (v4i32 (X86Movlps
1079                    (bc_v4i32 (loadv2i64 addr:$src1)), VR128:$src2)),
1080                               addr:$src1),
1081             (MOVLPSmr addr:$src1, VR128:$src2)>;
1082 }
1083
1084 let Predicates = [HasSSE2] in {
1085   let AddedComplexity = 20 in {
1086     // vector_shuffle v1, (load v2) <2, 1> using MOVLPS
1087     def : Pat<(v2f64 (movlp VR128:$src1, (load addr:$src2))),
1088               (MOVLPDrm VR128:$src1, addr:$src2)>;
1089     def : Pat<(v2i64 (movlp VR128:$src1, (load addr:$src2))),
1090               (MOVLPDrm VR128:$src1, addr:$src2)>;
1091   }
1092
1093   // (store (vector_shuffle (load addr), v2, <2, 1>), addr) using MOVLPS
1094   def : Pat<(store (v2f64 (movlp (load addr:$src1), VR128:$src2)), addr:$src1),
1095             (MOVLPDmr addr:$src1, VR128:$src2)>;
1096   def : Pat<(store (v2i64 (movlp (load addr:$src1), VR128:$src2)), addr:$src1),
1097             (MOVLPDmr addr:$src1, VR128:$src2)>;
1098
1099   // Shuffle with MOVLPD
1100   def : Pat<(v2f64 (X86Movlpd VR128:$src1, (load addr:$src2))),
1101             (MOVLPDrm VR128:$src1, addr:$src2)>;
1102   def : Pat<(v2i64 (X86Movlpd VR128:$src1, (load addr:$src2))),
1103             (MOVLPDrm VR128:$src1, addr:$src2)>;
1104   def : Pat<(v2f64 (X86Movlpd VR128:$src1,
1105                               (scalar_to_vector (loadf64 addr:$src2)))),
1106             (MOVLPDrm VR128:$src1, addr:$src2)>;
1107
1108   // Store patterns
1109   def : Pat<(store (v2f64 (X86Movlpd (load addr:$src1), VR128:$src2)),
1110                            addr:$src1),
1111             (MOVLPDmr addr:$src1, VR128:$src2)>;
1112   def : Pat<(store (v2i64 (X86Movlpd (load addr:$src1), VR128:$src2)),
1113                            addr:$src1),
1114             (MOVLPDmr addr:$src1, VR128:$src2)>;
1115 }
1116
1117 //===----------------------------------------------------------------------===//
1118 // SSE 1 & 2 - Move Hi packed FP Instructions
1119 //===----------------------------------------------------------------------===//
1120
1121 let AddedComplexity = 20 in {
1122   defm VMOVH : sse12_mov_hilo_packed<0x16, VR128, movlhps, "movhp",
1123                      "\t{$src2, $src1, $dst|$dst, $src1, $src2}">, VEX_4V;
1124 }
1125 let Constraints = "$src1 = $dst", AddedComplexity = 20 in {
1126   defm MOVH : sse12_mov_hilo_packed<0x16, VR128, movlhps, "movhp",
1127                                    "\t{$src2, $dst|$dst, $src2}">;
1128 }
1129
1130 // v2f64 extract element 1 is always custom lowered to unpack high to low
1131 // and extract element 0 so the non-store version isn't too horrible.
1132 def VMOVHPSmr : VPSI<0x17, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
1133                    "movhps\t{$src, $dst|$dst, $src}",
1134                    [(store (f64 (vector_extract
1135                                  (unpckh (bc_v2f64 (v4f32 VR128:$src)),
1136                                          (undef)), (iPTR 0))), addr:$dst)]>,
1137                    VEX;
1138 def VMOVHPDmr : VPDI<0x17, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
1139                    "movhpd\t{$src, $dst|$dst, $src}",
1140                    [(store (f64 (vector_extract
1141                                  (v2f64 (unpckh VR128:$src, (undef))),
1142                                  (iPTR 0))), addr:$dst)]>,
1143                    VEX;
1144 def MOVHPSmr : PSI<0x17, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
1145                    "movhps\t{$src, $dst|$dst, $src}",
1146                    [(store (f64 (vector_extract
1147                                  (unpckh (bc_v2f64 (v4f32 VR128:$src)),
1148                                          (undef)), (iPTR 0))), addr:$dst)]>;
1149 def MOVHPDmr : PDI<0x17, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
1150                    "movhpd\t{$src, $dst|$dst, $src}",
1151                    [(store (f64 (vector_extract
1152                                  (v2f64 (unpckh VR128:$src, (undef))),
1153                                  (iPTR 0))), addr:$dst)]>;
1154
1155 let Predicates = [HasAVX] in {
1156   // VMOVHPS patterns
1157   def : Pat<(movlhps VR128:$src1, (bc_v4i32 (v2i64 (X86vzload addr:$src2)))),
1158             (VMOVHPSrm (v4i32 VR128:$src1), addr:$src2)>;
1159   def : Pat<(X86Movlhps VR128:$src1,
1160                  (bc_v4f32 (v2f64 (scalar_to_vector (loadf64 addr:$src2))))),
1161             (VMOVHPSrm VR128:$src1, addr:$src2)>;
1162   def : Pat<(X86Movlhps VR128:$src1,
1163                  (bc_v4i32 (v2i64 (X86vzload addr:$src2)))),
1164             (VMOVHPSrm VR128:$src1, addr:$src2)>;
1165
1166   // FIXME: Instead of X86Unpcklpd, there should be a X86Movlhpd here, the problem
1167   // is during lowering, where it's not possible to recognize the load fold cause
1168   // it has two uses through a bitcast. One use disappears at isel time and the
1169   // fold opportunity reappears.
1170   def : Pat<(v2f64 (X86Unpcklpd VR128:$src1,
1171                       (scalar_to_vector (loadf64 addr:$src2)))),
1172             (VMOVHPDrm VR128:$src1, addr:$src2)>;
1173
1174   // FIXME: This should be matched by a X86Movhpd instead. Same as above
1175   def : Pat<(v2f64 (X86Movlhpd VR128:$src1,
1176                       (scalar_to_vector (loadf64 addr:$src2)))),
1177             (VMOVHPDrm VR128:$src1, addr:$src2)>;
1178
1179   // Store patterns
1180   def : Pat<(store (f64 (vector_extract
1181             (v2f64 (X86Unpckhps VR128:$src, (undef))), (iPTR 0))), addr:$dst),
1182             (VMOVHPSmr addr:$dst, VR128:$src)>;
1183   def : Pat<(store (f64 (vector_extract
1184             (v2f64 (X86Unpckhpd VR128:$src, (undef))), (iPTR 0))), addr:$dst),
1185             (VMOVHPDmr addr:$dst, VR128:$src)>;
1186 }
1187
1188 let Predicates = [HasSSE1] in {
1189   // MOVHPS patterns
1190   def : Pat<(movlhps VR128:$src1, (bc_v4i32 (v2i64 (X86vzload addr:$src2)))),
1191             (MOVHPSrm (v4i32 VR128:$src1), addr:$src2)>;
1192   def : Pat<(X86Movlhps VR128:$src1,
1193                  (bc_v4f32 (v2f64 (scalar_to_vector (loadf64 addr:$src2))))),
1194             (MOVHPSrm VR128:$src1, addr:$src2)>;
1195   def : Pat<(X86Movlhps VR128:$src1,
1196                  (bc_v4f32 (v2i64 (X86vzload addr:$src2)))),
1197             (MOVHPSrm VR128:$src1, addr:$src2)>;
1198
1199   // Store patterns
1200   def : Pat<(store (f64 (vector_extract
1201             (v2f64 (X86Unpckhps VR128:$src, (undef))), (iPTR 0))), addr:$dst),
1202             (MOVHPSmr addr:$dst, VR128:$src)>;
1203 }
1204
1205 let Predicates = [HasSSE2] in {
1206   // FIXME: Instead of X86Unpcklpd, there should be a X86Movlhpd here, the problem
1207   // is during lowering, where it's not possible to recognize the load fold cause
1208   // it has two uses through a bitcast. One use disappears at isel time and the
1209   // fold opportunity reappears.
1210   def : Pat<(v2f64 (X86Unpcklpd VR128:$src1,
1211                       (scalar_to_vector (loadf64 addr:$src2)))),
1212             (MOVHPDrm VR128:$src1, addr:$src2)>;
1213
1214   // FIXME: This should be matched by a X86Movhpd instead. Same as above
1215   def : Pat<(v2f64 (X86Movlhpd VR128:$src1,
1216                       (scalar_to_vector (loadf64 addr:$src2)))),
1217             (MOVHPDrm VR128:$src1, addr:$src2)>;
1218
1219   // Store patterns
1220   def : Pat<(store (f64 (vector_extract
1221             (v2f64 (X86Unpckhpd VR128:$src, (undef))), (iPTR 0))),addr:$dst),
1222             (MOVHPDmr addr:$dst, VR128:$src)>;
1223 }
1224
1225 //===----------------------------------------------------------------------===//
1226 // SSE 1 & 2 - Move Low to High and High to Low packed FP Instructions
1227 //===----------------------------------------------------------------------===//
1228
1229 let AddedComplexity = 20 in {
1230   def VMOVLHPSrr : VPSI<0x16, MRMSrcReg, (outs VR128:$dst),
1231                                        (ins VR128:$src1, VR128:$src2),
1232                       "movlhps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1233                       [(set VR128:$dst,
1234                         (v4f32 (movlhps VR128:$src1, VR128:$src2)))]>,
1235                       VEX_4V;
1236   def VMOVHLPSrr : VPSI<0x12, MRMSrcReg, (outs VR128:$dst),
1237                                        (ins VR128:$src1, VR128:$src2),
1238                       "movhlps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1239                       [(set VR128:$dst,
1240                         (v4f32 (movhlps VR128:$src1, VR128:$src2)))]>,
1241                       VEX_4V;
1242 }
1243 let Constraints = "$src1 = $dst", AddedComplexity = 20 in {
1244   def MOVLHPSrr : PSI<0x16, MRMSrcReg, (outs VR128:$dst),
1245                                        (ins VR128:$src1, VR128:$src2),
1246                       "movlhps\t{$src2, $dst|$dst, $src2}",
1247                       [(set VR128:$dst,
1248                         (v4f32 (movlhps VR128:$src1, VR128:$src2)))]>;
1249   def MOVHLPSrr : PSI<0x12, MRMSrcReg, (outs VR128:$dst),
1250                                        (ins VR128:$src1, VR128:$src2),
1251                       "movhlps\t{$src2, $dst|$dst, $src2}",
1252                       [(set VR128:$dst,
1253                         (v4f32 (movhlps VR128:$src1, VR128:$src2)))]>;
1254 }
1255
1256 let Predicates = [HasAVX] in {
1257   // MOVLHPS patterns
1258   let AddedComplexity = 20 in {
1259     def : Pat<(v4f32 (movddup VR128:$src, (undef))),
1260               (VMOVLHPSrr (v4f32 VR128:$src), (v4f32 VR128:$src))>;
1261     def : Pat<(v2i64 (movddup VR128:$src, (undef))),
1262               (VMOVLHPSrr (v2i64 VR128:$src), (v2i64 VR128:$src))>;
1263
1264     // vector_shuffle v1, v2 <0, 1, 4, 5> using MOVLHPS
1265     def : Pat<(v4i32 (movlhps VR128:$src1, VR128:$src2)),
1266               (VMOVLHPSrr VR128:$src1, VR128:$src2)>;
1267   }
1268   def : Pat<(v4f32 (X86Movlhps VR128:$src1, VR128:$src2)),
1269             (VMOVLHPSrr VR128:$src1, VR128:$src2)>;
1270   def : Pat<(v4i32 (X86Movlhps VR128:$src1, VR128:$src2)),
1271             (VMOVLHPSrr VR128:$src1, VR128:$src2)>;
1272   def : Pat<(v2i64 (X86Movlhps VR128:$src1, VR128:$src2)),
1273             (VMOVLHPSrr (v2i64 VR128:$src1), VR128:$src2)>;
1274
1275   // MOVHLPS patterns
1276   let AddedComplexity = 20 in {
1277     // vector_shuffle v1, v2 <6, 7, 2, 3> using MOVHLPS
1278     def : Pat<(v4i32 (movhlps VR128:$src1, VR128:$src2)),
1279               (VMOVHLPSrr VR128:$src1, VR128:$src2)>;
1280
1281     // vector_shuffle v1, undef <2, ?, ?, ?> using MOVHLPS
1282     def : Pat<(v4f32 (movhlps_undef VR128:$src1, (undef))),
1283               (VMOVHLPSrr VR128:$src1, VR128:$src1)>;
1284     def : Pat<(v4i32 (movhlps_undef VR128:$src1, (undef))),
1285               (VMOVHLPSrr VR128:$src1, VR128:$src1)>;
1286   }
1287
1288   def : Pat<(v4f32 (X86Movhlps VR128:$src1, VR128:$src2)),
1289             (VMOVHLPSrr VR128:$src1, VR128:$src2)>;
1290   def : Pat<(v4i32 (X86Movhlps VR128:$src1, VR128:$src2)),
1291             (VMOVHLPSrr VR128:$src1, VR128:$src2)>;
1292 }
1293
1294 let Predicates = [HasSSE1] in {
1295   // MOVLHPS patterns
1296   let AddedComplexity = 20 in {
1297     def : Pat<(v4f32 (movddup VR128:$src, (undef))),
1298               (MOVLHPSrr (v4f32 VR128:$src), (v4f32 VR128:$src))>;
1299     def : Pat<(v2i64 (movddup VR128:$src, (undef))),
1300               (MOVLHPSrr (v2i64 VR128:$src), (v2i64 VR128:$src))>;
1301
1302     // vector_shuffle v1, v2 <0, 1, 4, 5> using MOVLHPS
1303     def : Pat<(v4i32 (movlhps VR128:$src1, VR128:$src2)),
1304               (MOVLHPSrr VR128:$src1, VR128:$src2)>;
1305   }
1306   def : Pat<(v4f32 (X86Movlhps VR128:$src1, VR128:$src2)),
1307             (MOVLHPSrr VR128:$src1, VR128:$src2)>;
1308   def : Pat<(v4i32 (X86Movlhps VR128:$src1, VR128:$src2)),
1309             (MOVLHPSrr VR128:$src1, VR128:$src2)>;
1310   def : Pat<(v2i64 (X86Movlhps VR128:$src1, VR128:$src2)),
1311             (MOVLHPSrr (v2i64 VR128:$src1), VR128:$src2)>;
1312
1313   // MOVHLPS patterns
1314   let AddedComplexity = 20 in {
1315     // vector_shuffle v1, v2 <6, 7, 2, 3> using MOVHLPS
1316     def : Pat<(v4i32 (movhlps VR128:$src1, VR128:$src2)),
1317               (MOVHLPSrr VR128:$src1, VR128:$src2)>;
1318
1319     // vector_shuffle v1, undef <2, ?, ?, ?> using MOVHLPS
1320     def : Pat<(v4f32 (movhlps_undef VR128:$src1, (undef))),
1321               (MOVHLPSrr VR128:$src1, VR128:$src1)>;
1322     def : Pat<(v4i32 (movhlps_undef VR128:$src1, (undef))),
1323               (MOVHLPSrr VR128:$src1, VR128:$src1)>;
1324   }
1325
1326   def : Pat<(v4f32 (X86Movhlps VR128:$src1, VR128:$src2)),
1327             (MOVHLPSrr VR128:$src1, VR128:$src2)>;
1328   def : Pat<(v4i32 (X86Movhlps VR128:$src1, VR128:$src2)),
1329             (MOVHLPSrr VR128:$src1, VR128:$src2)>;
1330 }
1331
1332 //===----------------------------------------------------------------------===//
1333 // SSE 1 & 2 - Conversion Instructions
1334 //===----------------------------------------------------------------------===//
1335
1336 multiclass sse12_cvt_s<bits<8> opc, RegisterClass SrcRC, RegisterClass DstRC,
1337                      SDNode OpNode, X86MemOperand x86memop, PatFrag ld_frag,
1338                      string asm> {
1339   def rr : SI<opc, MRMSrcReg, (outs DstRC:$dst), (ins SrcRC:$src), asm,
1340                         [(set DstRC:$dst, (OpNode SrcRC:$src))]>;
1341   def rm : SI<opc, MRMSrcMem, (outs DstRC:$dst), (ins x86memop:$src), asm,
1342                         [(set DstRC:$dst, (OpNode (ld_frag addr:$src)))]>;
1343 }
1344
1345 multiclass sse12_cvt_s_np<bits<8> opc, RegisterClass SrcRC, RegisterClass DstRC,
1346                           X86MemOperand x86memop, string asm> {
1347   def rr : SI<opc, MRMSrcReg, (outs DstRC:$dst), (ins SrcRC:$src), asm, []>;
1348   let mayLoad = 1 in
1349   def rm : SI<opc, MRMSrcMem, (outs DstRC:$dst), (ins x86memop:$src), asm, []>;
1350 }
1351
1352 multiclass sse12_cvt_p<bits<8> opc, RegisterClass SrcRC, RegisterClass DstRC,
1353                          SDNode OpNode, X86MemOperand x86memop, PatFrag ld_frag,
1354                          string asm, Domain d> {
1355   def rr : PI<opc, MRMSrcReg, (outs DstRC:$dst), (ins SrcRC:$src), asm,
1356                         [(set DstRC:$dst, (OpNode SrcRC:$src))], d>;
1357   def rm : PI<opc, MRMSrcMem, (outs DstRC:$dst), (ins x86memop:$src), asm,
1358                         [(set DstRC:$dst, (OpNode (ld_frag addr:$src)))], d>;
1359 }
1360
1361 multiclass sse12_vcvt_avx<bits<8> opc, RegisterClass SrcRC, RegisterClass DstRC,
1362                           X86MemOperand x86memop, string asm> {
1363   def rr : SI<opc, MRMSrcReg, (outs DstRC:$dst), (ins DstRC:$src1, SrcRC:$src),
1364               !strconcat(asm,"\t{$src, $src1, $dst|$dst, $src1, $src}"), []>;
1365   let mayLoad = 1 in
1366   def rm : SI<opc, MRMSrcMem, (outs DstRC:$dst),
1367               (ins DstRC:$src1, x86memop:$src),
1368               !strconcat(asm,"\t{$src, $src1, $dst|$dst, $src1, $src}"), []>;
1369 }
1370
1371 defm VCVTTSS2SI   : sse12_cvt_s<0x2C, FR32, GR32, fp_to_sint, f32mem, loadf32,
1372                                 "cvttss2si\t{$src, $dst|$dst, $src}">, XS, VEX;
1373 defm VCVTTSS2SI64 : sse12_cvt_s<0x2C, FR32, GR64, fp_to_sint, f32mem, loadf32,
1374                                 "cvttss2si\t{$src, $dst|$dst, $src}">, XS, VEX,
1375                                 VEX_W;
1376 defm VCVTTSD2SI   : sse12_cvt_s<0x2C, FR64, GR32, fp_to_sint, f64mem, loadf64,
1377                                 "cvttsd2si\t{$src, $dst|$dst, $src}">, XD, VEX;
1378 defm VCVTTSD2SI64 : sse12_cvt_s<0x2C, FR64, GR64, fp_to_sint, f64mem, loadf64,
1379                                 "cvttsd2si\t{$src, $dst|$dst, $src}">, XD,
1380                                 VEX, VEX_W;
1381
1382 // The assembler can recognize rr 64-bit instructions by seeing a rxx
1383 // register, but the same isn't true when only using memory operands,
1384 // provide other assembly "l" and "q" forms to address this explicitly
1385 // where appropriate to do so.
1386 defm VCVTSI2SS   : sse12_vcvt_avx<0x2A, GR32, FR32, i32mem, "cvtsi2ss">, XS,
1387                                   VEX_4V;
1388 defm VCVTSI2SS64 : sse12_vcvt_avx<0x2A, GR64, FR32, i64mem, "cvtsi2ss{q}">, XS,
1389                                   VEX_4V, VEX_W;
1390 defm VCVTSI2SD   : sse12_vcvt_avx<0x2A, GR32, FR64, i32mem, "cvtsi2sd">, XD,
1391                                   VEX_4V;
1392 defm VCVTSI2SDL  : sse12_vcvt_avx<0x2A, GR32, FR64, i32mem, "cvtsi2sd{l}">, XD,
1393                                   VEX_4V;
1394 defm VCVTSI2SD64 : sse12_vcvt_avx<0x2A, GR64, FR64, i64mem, "cvtsi2sd{q}">, XD,
1395                                   VEX_4V, VEX_W;
1396
1397 let Predicates = [HasAVX] in {
1398   def : Pat<(f32 (sint_to_fp (loadi32 addr:$src))),
1399             (VCVTSI2SSrm (f32 (IMPLICIT_DEF)), addr:$src)>;
1400   def : Pat<(f32 (sint_to_fp (loadi64 addr:$src))),
1401             (VCVTSI2SS64rm (f32 (IMPLICIT_DEF)), addr:$src)>;
1402   def : Pat<(f64 (sint_to_fp (loadi32 addr:$src))),
1403             (VCVTSI2SDrm (f64 (IMPLICIT_DEF)), addr:$src)>;
1404   def : Pat<(f64 (sint_to_fp (loadi64 addr:$src))),
1405             (VCVTSI2SD64rm (f64 (IMPLICIT_DEF)), addr:$src)>;
1406
1407   def : Pat<(f32 (sint_to_fp GR32:$src)),
1408             (VCVTSI2SSrr (f32 (IMPLICIT_DEF)), GR32:$src)>;
1409   def : Pat<(f32 (sint_to_fp GR64:$src)),
1410             (VCVTSI2SS64rr (f32 (IMPLICIT_DEF)), GR64:$src)>;
1411   def : Pat<(f64 (sint_to_fp GR32:$src)),
1412             (VCVTSI2SDrr (f64 (IMPLICIT_DEF)), GR32:$src)>;
1413   def : Pat<(f64 (sint_to_fp GR64:$src)),
1414             (VCVTSI2SD64rr (f64 (IMPLICIT_DEF)), GR64:$src)>;
1415 }
1416
1417 defm CVTTSS2SI : sse12_cvt_s<0x2C, FR32, GR32, fp_to_sint, f32mem, loadf32,
1418                       "cvttss2si\t{$src, $dst|$dst, $src}">, XS;
1419 defm CVTTSS2SI64 : sse12_cvt_s<0x2C, FR32, GR64, fp_to_sint, f32mem, loadf32,
1420                       "cvttss2si{q}\t{$src, $dst|$dst, $src}">, XS, REX_W;
1421 defm CVTTSD2SI : sse12_cvt_s<0x2C, FR64, GR32, fp_to_sint, f64mem, loadf64,
1422                       "cvttsd2si\t{$src, $dst|$dst, $src}">, XD;
1423 defm CVTTSD2SI64 : sse12_cvt_s<0x2C, FR64, GR64, fp_to_sint, f64mem, loadf64,
1424                       "cvttsd2si{q}\t{$src, $dst|$dst, $src}">, XD, REX_W;
1425 defm CVTSI2SS  : sse12_cvt_s<0x2A, GR32, FR32, sint_to_fp, i32mem, loadi32,
1426                       "cvtsi2ss\t{$src, $dst|$dst, $src}">, XS;
1427 defm CVTSI2SS64 : sse12_cvt_s<0x2A, GR64, FR32, sint_to_fp, i64mem, loadi64,
1428                       "cvtsi2ss{q}\t{$src, $dst|$dst, $src}">, XS, REX_W;
1429 defm CVTSI2SD  : sse12_cvt_s<0x2A, GR32, FR64, sint_to_fp, i32mem, loadi32,
1430                       "cvtsi2sd\t{$src, $dst|$dst, $src}">, XD;
1431 defm CVTSI2SD64 : sse12_cvt_s<0x2A, GR64, FR64, sint_to_fp, i64mem, loadi64,
1432                       "cvtsi2sd{q}\t{$src, $dst|$dst, $src}">, XD, REX_W;
1433
1434 // Conversion Instructions Intrinsics - Match intrinsics which expect MM
1435 // and/or XMM operand(s).
1436
1437 multiclass sse12_cvt_sint<bits<8> opc, RegisterClass SrcRC, RegisterClass DstRC,
1438                          Intrinsic Int, X86MemOperand x86memop, PatFrag ld_frag,
1439                          string asm> {
1440   def rr : SI<opc, MRMSrcReg, (outs DstRC:$dst), (ins SrcRC:$src),
1441               !strconcat(asm, "\t{$src, $dst|$dst, $src}"),
1442               [(set DstRC:$dst, (Int SrcRC:$src))]>;
1443   def rm : SI<opc, MRMSrcMem, (outs DstRC:$dst), (ins x86memop:$src),
1444               !strconcat(asm, "\t{$src, $dst|$dst, $src}"),
1445               [(set DstRC:$dst, (Int (ld_frag addr:$src)))]>;
1446 }
1447
1448 multiclass sse12_cvt_sint_3addr<bits<8> opc, RegisterClass SrcRC,
1449                     RegisterClass DstRC, Intrinsic Int, X86MemOperand x86memop,
1450                     PatFrag ld_frag, string asm, bit Is2Addr = 1> {
1451   def rr : SI<opc, MRMSrcReg, (outs DstRC:$dst), (ins DstRC:$src1, SrcRC:$src2),
1452               !if(Is2Addr,
1453                   !strconcat(asm, "\t{$src2, $dst|$dst, $src2}"),
1454                   !strconcat(asm, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
1455               [(set DstRC:$dst, (Int DstRC:$src1, SrcRC:$src2))]>;
1456   def rm : SI<opc, MRMSrcMem, (outs DstRC:$dst),
1457               (ins DstRC:$src1, x86memop:$src2),
1458               !if(Is2Addr,
1459                   !strconcat(asm, "\t{$src2, $dst|$dst, $src2}"),
1460                   !strconcat(asm, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
1461               [(set DstRC:$dst, (Int DstRC:$src1, (ld_frag addr:$src2)))]>;
1462 }
1463
1464 defm Int_VCVTSD2SI : sse12_cvt_sint<0x2D, VR128, GR32, int_x86_sse2_cvtsd2si,
1465                       f128mem, load, "cvtsd2si">, XD, VEX;
1466 defm Int_VCVTSD2SI64 : sse12_cvt_sint<0x2D, VR128, GR64,
1467                       int_x86_sse2_cvtsd2si64, f128mem, load, "cvtsd2si">,
1468                       XD, VEX, VEX_W;
1469
1470 // FIXME: The asm matcher has a hack to ignore instructions with _Int and Int_
1471 // Get rid of this hack or rename the intrinsics, there are several
1472 // intructions that only match with the intrinsic form, why create duplicates
1473 // to let them be recognized by the assembler?
1474 defm VCVTSD2SI     : sse12_cvt_s_np<0x2D, FR64, GR32, f64mem,
1475                       "cvtsd2si\t{$src, $dst|$dst, $src}">, XD, VEX;
1476 defm VCVTSD2SI64   : sse12_cvt_s_np<0x2D, FR64, GR64, f64mem,
1477                       "cvtsd2si\t{$src, $dst|$dst, $src}">, XD, VEX, VEX_W;
1478
1479 defm CVTSD2SI : sse12_cvt_sint<0x2D, VR128, GR32, int_x86_sse2_cvtsd2si,
1480                 f128mem, load, "cvtsd2si{l}">, XD;
1481 defm CVTSD2SI64 : sse12_cvt_sint<0x2D, VR128, GR64, int_x86_sse2_cvtsd2si64,
1482                   f128mem, load, "cvtsd2si{q}">, XD, REX_W;
1483
1484
1485 defm Int_VCVTSI2SS : sse12_cvt_sint_3addr<0x2A, GR32, VR128,
1486           int_x86_sse_cvtsi2ss, i32mem, loadi32, "cvtsi2ss", 0>, XS, VEX_4V;
1487 defm Int_VCVTSI2SS64 : sse12_cvt_sint_3addr<0x2A, GR64, VR128,
1488           int_x86_sse_cvtsi642ss, i64mem, loadi64, "cvtsi2ss", 0>, XS, VEX_4V,
1489           VEX_W;
1490 defm Int_VCVTSI2SD : sse12_cvt_sint_3addr<0x2A, GR32, VR128,
1491           int_x86_sse2_cvtsi2sd, i32mem, loadi32, "cvtsi2sd", 0>, XD, VEX_4V;
1492 defm Int_VCVTSI2SD64 : sse12_cvt_sint_3addr<0x2A, GR64, VR128,
1493           int_x86_sse2_cvtsi642sd, i64mem, loadi64, "cvtsi2sd", 0>, XD,
1494           VEX_4V, VEX_W;
1495
1496 let Constraints = "$src1 = $dst" in {
1497   defm Int_CVTSI2SS : sse12_cvt_sint_3addr<0x2A, GR32, VR128,
1498                         int_x86_sse_cvtsi2ss, i32mem, loadi32,
1499                         "cvtsi2ss">, XS;
1500   defm Int_CVTSI2SS64 : sse12_cvt_sint_3addr<0x2A, GR64, VR128,
1501                         int_x86_sse_cvtsi642ss, i64mem, loadi64,
1502                         "cvtsi2ss{q}">, XS, REX_W;
1503   defm Int_CVTSI2SD : sse12_cvt_sint_3addr<0x2A, GR32, VR128,
1504                         int_x86_sse2_cvtsi2sd, i32mem, loadi32,
1505                         "cvtsi2sd">, XD;
1506   defm Int_CVTSI2SD64 : sse12_cvt_sint_3addr<0x2A, GR64, VR128,
1507                         int_x86_sse2_cvtsi642sd, i64mem, loadi64,
1508                         "cvtsi2sd">, XD, REX_W;
1509 }
1510
1511 /// SSE 1 Only
1512
1513 // Aliases for intrinsics
1514 defm Int_VCVTTSS2SI : sse12_cvt_sint<0x2C, VR128, GR32, int_x86_sse_cvttss2si,
1515                                     f32mem, load, "cvttss2si">, XS, VEX;
1516 defm Int_VCVTTSS2SI64 : sse12_cvt_sint<0x2C, VR128, GR64,
1517                                     int_x86_sse_cvttss2si64, f32mem, load,
1518                                     "cvttss2si">, XS, VEX, VEX_W;
1519 defm Int_VCVTTSD2SI : sse12_cvt_sint<0x2C, VR128, GR32, int_x86_sse2_cvttsd2si,
1520                                     f128mem, load, "cvttsd2si">, XD, VEX;
1521 defm Int_VCVTTSD2SI64 : sse12_cvt_sint<0x2C, VR128, GR64,
1522                                     int_x86_sse2_cvttsd2si64, f128mem, load,
1523                                     "cvttsd2si">, XD, VEX, VEX_W;
1524 defm Int_CVTTSS2SI : sse12_cvt_sint<0x2C, VR128, GR32, int_x86_sse_cvttss2si,
1525                                     f32mem, load, "cvttss2si">, XS;
1526 defm Int_CVTTSS2SI64 : sse12_cvt_sint<0x2C, VR128, GR64,
1527                                     int_x86_sse_cvttss2si64, f32mem, load,
1528                                     "cvttss2si{q}">, XS, REX_W;
1529 defm Int_CVTTSD2SI : sse12_cvt_sint<0x2C, VR128, GR32, int_x86_sse2_cvttsd2si,
1530                                     f128mem, load, "cvttsd2si">, XD;
1531 defm Int_CVTTSD2SI64 : sse12_cvt_sint<0x2C, VR128, GR64,
1532                                     int_x86_sse2_cvttsd2si64, f128mem, load,
1533                                     "cvttsd2si{q}">, XD, REX_W;
1534
1535 let Pattern = []<dag> in {
1536 defm VCVTSS2SI   : sse12_cvt_s<0x2D, FR32, GR32, undef, f32mem, load,
1537                                "cvtss2si{l}\t{$src, $dst|$dst, $src}">, XS, VEX;
1538 defm VCVTSS2SI64 : sse12_cvt_s<0x2D, FR32, GR64, undef, f32mem, load,
1539                                "cvtss2si\t{$src, $dst|$dst, $src}">, XS, VEX,
1540                                VEX_W;
1541 defm VCVTDQ2PS   : sse12_cvt_p<0x5B, VR128, VR128, undef, i128mem, load,
1542                                "cvtdq2ps\t{$src, $dst|$dst, $src}",
1543                                SSEPackedSingle>, TB, VEX;
1544 defm VCVTDQ2PSY  : sse12_cvt_p<0x5B, VR256, VR256, undef, i256mem, load,
1545                                "cvtdq2ps\t{$src, $dst|$dst, $src}",
1546                                SSEPackedSingle>, TB, VEX;
1547 }
1548
1549 let Pattern = []<dag> in {
1550 defm CVTSS2SI : sse12_cvt_s<0x2D, FR32, GR32, undef, f32mem, load /*dummy*/,
1551                           "cvtss2si{l}\t{$src, $dst|$dst, $src}">, XS;
1552 defm CVTSS2SI64 : sse12_cvt_s<0x2D, FR32, GR64, undef, f32mem, load /*dummy*/,
1553                           "cvtss2si{q}\t{$src, $dst|$dst, $src}">, XS, REX_W;
1554 defm CVTDQ2PS : sse12_cvt_p<0x5B, VR128, VR128, undef, i128mem, load /*dummy*/,
1555                             "cvtdq2ps\t{$src, $dst|$dst, $src}",
1556                             SSEPackedSingle>, TB; /* PD SSE3 form is avaiable */
1557 }
1558
1559 let Predicates = [HasSSE1] in {
1560   def : Pat<(int_x86_sse_cvtss2si VR128:$src),
1561             (CVTSS2SIrr (EXTRACT_SUBREG (v4f32 VR128:$src), sub_ss))>;
1562   def : Pat<(int_x86_sse_cvtss2si (load addr:$src)),
1563             (CVTSS2SIrm addr:$src)>;
1564   def : Pat<(int_x86_sse_cvtss2si64 VR128:$src),
1565             (CVTSS2SI64rr (EXTRACT_SUBREG (v4f32 VR128:$src), sub_ss))>;
1566   def : Pat<(int_x86_sse_cvtss2si64 (load addr:$src)),
1567             (CVTSS2SI64rm addr:$src)>;
1568 }
1569
1570 let Predicates = [HasAVX] in {
1571   def : Pat<(int_x86_sse_cvtss2si VR128:$src),
1572             (VCVTSS2SIrr (EXTRACT_SUBREG (v4f32 VR128:$src), sub_ss))>;
1573   def : Pat<(int_x86_sse_cvtss2si (load addr:$src)),
1574             (VCVTSS2SIrm addr:$src)>;
1575   def : Pat<(int_x86_sse_cvtss2si64 VR128:$src),
1576             (VCVTSS2SI64rr (EXTRACT_SUBREG (v4f32 VR128:$src), sub_ss))>;
1577   def : Pat<(int_x86_sse_cvtss2si64 (load addr:$src)),
1578             (VCVTSS2SI64rm addr:$src)>;
1579 }
1580
1581 /// SSE 2 Only
1582
1583 // Convert scalar double to scalar single
1584 def VCVTSD2SSrr  : VSDI<0x5A, MRMSrcReg, (outs FR32:$dst),
1585                        (ins FR64:$src1, FR64:$src2),
1586                       "cvtsd2ss\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>,
1587                       VEX_4V;
1588 let mayLoad = 1 in
1589 def VCVTSD2SSrm  : I<0x5A, MRMSrcMem, (outs FR32:$dst),
1590                        (ins FR64:$src1, f64mem:$src2),
1591                       "vcvtsd2ss\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1592                       []>, XD, Requires<[HasAVX, OptForSize]>, VEX_4V;
1593
1594 def : Pat<(f32 (fround FR64:$src)), (VCVTSD2SSrr FR64:$src, FR64:$src)>,
1595           Requires<[HasAVX]>;
1596
1597 def CVTSD2SSrr  : SDI<0x5A, MRMSrcReg, (outs FR32:$dst), (ins FR64:$src),
1598                       "cvtsd2ss\t{$src, $dst|$dst, $src}",
1599                       [(set FR32:$dst, (fround FR64:$src))]>;
1600 def CVTSD2SSrm  : I<0x5A, MRMSrcMem, (outs FR32:$dst), (ins f64mem:$src),
1601                       "cvtsd2ss\t{$src, $dst|$dst, $src}",
1602                       [(set FR32:$dst, (fround (loadf64 addr:$src)))]>, XD,
1603                   Requires<[HasSSE2, OptForSize]>;
1604
1605 defm Int_VCVTSD2SS: sse12_cvt_sint_3addr<0x5A, VR128, VR128,
1606                       int_x86_sse2_cvtsd2ss, f64mem, load, "cvtsd2ss", 0>,
1607                       XS, VEX_4V;
1608 let Constraints = "$src1 = $dst" in
1609 defm Int_CVTSD2SS: sse12_cvt_sint_3addr<0x5A, VR128, VR128,
1610                       int_x86_sse2_cvtsd2ss, f64mem, load, "cvtsd2ss">, XS;
1611
1612 // Convert scalar single to scalar double
1613 // SSE2 instructions with XS prefix
1614 def VCVTSS2SDrr : I<0x5A, MRMSrcReg, (outs FR64:$dst),
1615                     (ins FR32:$src1, FR32:$src2),
1616                     "vcvtss2sd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1617                     []>, XS, Requires<[HasAVX]>, VEX_4V;
1618 let mayLoad = 1 in
1619 def VCVTSS2SDrm : I<0x5A, MRMSrcMem, (outs FR64:$dst),
1620                     (ins FR32:$src1, f32mem:$src2),
1621                     "vcvtss2sd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1622                     []>, XS, VEX_4V, Requires<[HasAVX, OptForSize]>;
1623
1624 let Predicates = [HasAVX] in {
1625   def : Pat<(f64 (fextend FR32:$src)),
1626             (VCVTSS2SDrr FR32:$src, FR32:$src)>;
1627   def : Pat<(fextend (loadf32 addr:$src)),
1628             (VCVTSS2SDrm (f32 (IMPLICIT_DEF)), addr:$src)>;
1629   def : Pat<(extloadf32 addr:$src),
1630             (VCVTSS2SDrm (f32 (IMPLICIT_DEF)), addr:$src)>;
1631 }
1632
1633 def : Pat<(extloadf32 addr:$src),
1634           (VCVTSS2SDrr (f32 (IMPLICIT_DEF)), (MOVSSrm addr:$src))>,
1635           Requires<[HasAVX, OptForSpeed]>;
1636
1637 def CVTSS2SDrr : I<0x5A, MRMSrcReg, (outs FR64:$dst), (ins FR32:$src),
1638                    "cvtss2sd\t{$src, $dst|$dst, $src}",
1639                    [(set FR64:$dst, (fextend FR32:$src))]>, XS,
1640                  Requires<[HasSSE2]>;
1641 def CVTSS2SDrm : I<0x5A, MRMSrcMem, (outs FR64:$dst), (ins f32mem:$src),
1642                    "cvtss2sd\t{$src, $dst|$dst, $src}",
1643                    [(set FR64:$dst, (extloadf32 addr:$src))]>, XS,
1644                  Requires<[HasSSE2, OptForSize]>;
1645
1646 // extload f32 -> f64.  This matches load+fextend because we have a hack in
1647 // the isel (PreprocessForFPConvert) that can introduce loads after dag
1648 // combine.
1649 // Since these loads aren't folded into the fextend, we have to match it
1650 // explicitly here.
1651 def : Pat<(fextend (loadf32 addr:$src)),
1652           (CVTSS2SDrm addr:$src)>, Requires<[HasSSE2]>;
1653 def : Pat<(extloadf32 addr:$src),
1654           (CVTSS2SDrr (MOVSSrm addr:$src))>, Requires<[HasSSE2, OptForSpeed]>;
1655
1656 def Int_VCVTSS2SDrr: I<0x5A, MRMSrcReg,
1657                       (outs VR128:$dst), (ins VR128:$src1, VR128:$src2),
1658                     "vcvtss2sd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1659                     [(set VR128:$dst, (int_x86_sse2_cvtss2sd VR128:$src1,
1660                                        VR128:$src2))]>, XS, VEX_4V,
1661                     Requires<[HasAVX]>;
1662 def Int_VCVTSS2SDrm: I<0x5A, MRMSrcMem,
1663                       (outs VR128:$dst), (ins VR128:$src1, f32mem:$src2),
1664                     "vcvtss2sd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
1665                     [(set VR128:$dst, (int_x86_sse2_cvtss2sd VR128:$src1,
1666                                        (load addr:$src2)))]>, XS, VEX_4V,
1667                     Requires<[HasAVX]>;
1668 let Constraints = "$src1 = $dst" in { // SSE2 instructions with XS prefix
1669 def Int_CVTSS2SDrr: I<0x5A, MRMSrcReg,
1670                       (outs VR128:$dst), (ins VR128:$src1, VR128:$src2),
1671                     "cvtss2sd\t{$src2, $dst|$dst, $src2}",
1672                     [(set VR128:$dst, (int_x86_sse2_cvtss2sd VR128:$src1,
1673                                        VR128:$src2))]>, XS,
1674                     Requires<[HasSSE2]>;
1675 def Int_CVTSS2SDrm: I<0x5A, MRMSrcMem,
1676                       (outs VR128:$dst), (ins VR128:$src1, f32mem:$src2),
1677                     "cvtss2sd\t{$src2, $dst|$dst, $src2}",
1678                     [(set VR128:$dst, (int_x86_sse2_cvtss2sd VR128:$src1,
1679                                        (load addr:$src2)))]>, XS,
1680                     Requires<[HasSSE2]>;
1681 }
1682
1683 // Convert doubleword to packed single/double fp
1684 // SSE2 instructions without OpSize prefix
1685 def Int_VCVTDQ2PSrr : I<0x5B, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1686                        "vcvtdq2ps\t{$src, $dst|$dst, $src}",
1687                        [(set VR128:$dst, (int_x86_sse2_cvtdq2ps VR128:$src))]>,
1688                      TB, VEX, Requires<[HasAVX]>;
1689 def Int_VCVTDQ2PSrm : I<0x5B, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
1690                       "vcvtdq2ps\t{$src, $dst|$dst, $src}",
1691                       [(set VR128:$dst, (int_x86_sse2_cvtdq2ps
1692                                         (bitconvert (memopv2i64 addr:$src))))]>,
1693                      TB, VEX, Requires<[HasAVX]>;
1694 def Int_CVTDQ2PSrr : I<0x5B, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1695                        "cvtdq2ps\t{$src, $dst|$dst, $src}",
1696                        [(set VR128:$dst, (int_x86_sse2_cvtdq2ps VR128:$src))]>,
1697                      TB, Requires<[HasSSE2]>;
1698 def Int_CVTDQ2PSrm : I<0x5B, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
1699                       "cvtdq2ps\t{$src, $dst|$dst, $src}",
1700                       [(set VR128:$dst, (int_x86_sse2_cvtdq2ps
1701                                         (bitconvert (memopv2i64 addr:$src))))]>,
1702                      TB, Requires<[HasSSE2]>;
1703
1704 // FIXME: why the non-intrinsic version is described as SSE3?
1705 // SSE2 instructions with XS prefix
1706 def Int_VCVTDQ2PDrr : I<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1707                        "vcvtdq2pd\t{$src, $dst|$dst, $src}",
1708                        [(set VR128:$dst, (int_x86_sse2_cvtdq2pd VR128:$src))]>,
1709                      XS, VEX, Requires<[HasAVX]>;
1710 def Int_VCVTDQ2PDrm : I<0xE6, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
1711                        "vcvtdq2pd\t{$src, $dst|$dst, $src}",
1712                        [(set VR128:$dst, (int_x86_sse2_cvtdq2pd
1713                                         (bitconvert (memopv2i64 addr:$src))))]>,
1714                      XS, VEX, Requires<[HasAVX]>;
1715 def Int_CVTDQ2PDrr : I<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1716                        "cvtdq2pd\t{$src, $dst|$dst, $src}",
1717                        [(set VR128:$dst, (int_x86_sse2_cvtdq2pd VR128:$src))]>,
1718                      XS, Requires<[HasSSE2]>;
1719 def Int_CVTDQ2PDrm : I<0xE6, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
1720                      "cvtdq2pd\t{$src, $dst|$dst, $src}",
1721                      [(set VR128:$dst, (int_x86_sse2_cvtdq2pd
1722                                         (bitconvert (memopv2i64 addr:$src))))]>,
1723                      XS, Requires<[HasSSE2]>;
1724
1725
1726 // Convert packed single/double fp to doubleword
1727 def VCVTPS2DQrr : VPDI<0x5B, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1728                        "cvtps2dq\t{$src, $dst|$dst, $src}", []>, VEX;
1729 def VCVTPS2DQrm : VPDI<0x5B, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1730                        "cvtps2dq\t{$src, $dst|$dst, $src}", []>, VEX;
1731 def VCVTPS2DQYrr : VPDI<0x5B, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
1732                         "cvtps2dq\t{$src, $dst|$dst, $src}", []>, VEX;
1733 def VCVTPS2DQYrm : VPDI<0x5B, MRMSrcMem, (outs VR256:$dst), (ins f256mem:$src),
1734                         "cvtps2dq\t{$src, $dst|$dst, $src}", []>, VEX;
1735 def CVTPS2DQrr : PDI<0x5B, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1736                      "cvtps2dq\t{$src, $dst|$dst, $src}", []>;
1737 def CVTPS2DQrm : PDI<0x5B, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1738                      "cvtps2dq\t{$src, $dst|$dst, $src}", []>;
1739
1740 def Int_VCVTPS2DQrr : VPDI<0x5B, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1741                         "cvtps2dq\t{$src, $dst|$dst, $src}",
1742                         [(set VR128:$dst, (int_x86_sse2_cvtps2dq VR128:$src))]>,
1743                         VEX;
1744 def Int_VCVTPS2DQrm : VPDI<0x5B, MRMSrcMem, (outs VR128:$dst),
1745                          (ins f128mem:$src),
1746                          "cvtps2dq\t{$src, $dst|$dst, $src}",
1747                          [(set VR128:$dst, (int_x86_sse2_cvtps2dq
1748                                             (memop addr:$src)))]>, VEX;
1749 def Int_CVTPS2DQrr : PDI<0x5B, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1750                         "cvtps2dq\t{$src, $dst|$dst, $src}",
1751                         [(set VR128:$dst, (int_x86_sse2_cvtps2dq VR128:$src))]>;
1752 def Int_CVTPS2DQrm : PDI<0x5B, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1753                          "cvtps2dq\t{$src, $dst|$dst, $src}",
1754                          [(set VR128:$dst, (int_x86_sse2_cvtps2dq
1755                                             (memop addr:$src)))]>;
1756
1757 // SSE2 packed instructions with XD prefix
1758 def Int_VCVTPD2DQrr : I<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1759                        "vcvtpd2dq\t{$src, $dst|$dst, $src}",
1760                        [(set VR128:$dst, (int_x86_sse2_cvtpd2dq VR128:$src))]>,
1761                      XD, VEX, Requires<[HasAVX]>;
1762 def Int_VCVTPD2DQrm : I<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1763                        "vcvtpd2dq\t{$src, $dst|$dst, $src}",
1764                        [(set VR128:$dst, (int_x86_sse2_cvtpd2dq
1765                                           (memop addr:$src)))]>,
1766                      XD, VEX, Requires<[HasAVX]>;
1767 def Int_CVTPD2DQrr : I<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1768                        "cvtpd2dq\t{$src, $dst|$dst, $src}",
1769                        [(set VR128:$dst, (int_x86_sse2_cvtpd2dq VR128:$src))]>,
1770                      XD, Requires<[HasSSE2]>;
1771 def Int_CVTPD2DQrm : I<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1772                        "cvtpd2dq\t{$src, $dst|$dst, $src}",
1773                        [(set VR128:$dst, (int_x86_sse2_cvtpd2dq
1774                                           (memop addr:$src)))]>,
1775                      XD, Requires<[HasSSE2]>;
1776
1777
1778 // Convert with truncation packed single/double fp to doubleword
1779 // SSE2 packed instructions with XS prefix
1780 def VCVTTPS2DQrr : VSSI<0x5B, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1781                       "cvttps2dq\t{$src, $dst|$dst, $src}", []>, VEX;
1782 let mayLoad = 1 in
1783 def VCVTTPS2DQrm : VSSI<0x5B, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1784                       "cvttps2dq\t{$src, $dst|$dst, $src}", []>, VEX;
1785 def VCVTTPS2DQYrr : VSSI<0x5B, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
1786                       "cvttps2dq\t{$src, $dst|$dst, $src}", []>, VEX;
1787 let mayLoad = 1 in
1788 def VCVTTPS2DQYrm : VSSI<0x5B, MRMSrcMem, (outs VR256:$dst), (ins f256mem:$src),
1789                       "cvttps2dq\t{$src, $dst|$dst, $src}", []>, VEX;
1790 def CVTTPS2DQrr : SSI<0x5B, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1791                       "cvttps2dq\t{$src, $dst|$dst, $src}",
1792                       [(set VR128:$dst,
1793                             (int_x86_sse2_cvttps2dq VR128:$src))]>;
1794 def CVTTPS2DQrm : SSI<0x5B, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1795                       "cvttps2dq\t{$src, $dst|$dst, $src}",
1796                       [(set VR128:$dst,
1797                             (int_x86_sse2_cvttps2dq (memop addr:$src)))]>;
1798
1799 def Int_VCVTTPS2DQrr : I<0x5B, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1800                         "vcvttps2dq\t{$src, $dst|$dst, $src}",
1801                         [(set VR128:$dst,
1802                               (int_x86_sse2_cvttps2dq VR128:$src))]>,
1803                       XS, VEX, Requires<[HasAVX]>;
1804 def Int_VCVTTPS2DQrm : I<0x5B, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1805                         "vcvttps2dq\t{$src, $dst|$dst, $src}",
1806                         [(set VR128:$dst, (int_x86_sse2_cvttps2dq
1807                                            (memop addr:$src)))]>,
1808                       XS, VEX, Requires<[HasAVX]>;
1809
1810 let Predicates = [HasSSE2] in {
1811   def : Pat<(v4f32 (sint_to_fp (v4i32 VR128:$src))),
1812             (Int_CVTDQ2PSrr VR128:$src)>;
1813   def : Pat<(v4i32 (fp_to_sint (v4f32 VR128:$src))),
1814             (CVTTPS2DQrr VR128:$src)>;
1815 }
1816
1817 let Predicates = [HasAVX] in {
1818   def : Pat<(v4f32 (sint_to_fp (v4i32 VR128:$src))),
1819             (Int_VCVTDQ2PSrr VR128:$src)>;
1820   def : Pat<(v4i32 (fp_to_sint (v4f32 VR128:$src))),
1821             (VCVTTPS2DQrr VR128:$src)>;
1822   def : Pat<(v8f32 (sint_to_fp (v8i32 VR256:$src))),
1823             (VCVTDQ2PSYrr VR256:$src)>;
1824   def : Pat<(v8i32 (fp_to_sint (v8f32 VR256:$src))),
1825             (VCVTTPS2DQYrr VR256:$src)>;
1826 }
1827
1828 def VCVTTPD2DQrr : VPDI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1829                         "cvttpd2dq\t{$src, $dst|$dst, $src}",
1830                         [(set VR128:$dst,
1831                               (int_x86_sse2_cvttpd2dq VR128:$src))]>, VEX;
1832 let isCodeGenOnly = 1 in
1833 def VCVTTPD2DQrm : VPDI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1834                         "cvttpd2dq\t{$src, $dst|$dst, $src}",
1835                         [(set VR128:$dst, (int_x86_sse2_cvttpd2dq
1836                                                (memop addr:$src)))]>, VEX;
1837 def CVTTPD2DQrr : PDI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1838                       "cvttpd2dq\t{$src, $dst|$dst, $src}",
1839                       [(set VR128:$dst, (int_x86_sse2_cvttpd2dq VR128:$src))]>;
1840 def CVTTPD2DQrm : PDI<0xE6, MRMSrcMem, (outs VR128:$dst),(ins f128mem:$src),
1841                       "cvttpd2dq\t{$src, $dst|$dst, $src}",
1842                       [(set VR128:$dst, (int_x86_sse2_cvttpd2dq
1843                                         (memop addr:$src)))]>;
1844
1845 // The assembler can recognize rr 256-bit instructions by seeing a ymm
1846 // register, but the same isn't true when using memory operands instead.
1847 // Provide other assembly rr and rm forms to address this explicitly.
1848 def VCVTTPD2DQXrYr : VPDI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR256:$src),
1849                           "cvttpd2dq\t{$src, $dst|$dst, $src}", []>, VEX;
1850
1851 // XMM only
1852 def VCVTTPD2DQXrr : VPDI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1853                          "cvttpd2dqx\t{$src, $dst|$dst, $src}", []>, VEX;
1854 def VCVTTPD2DQXrm : VPDI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1855                          "cvttpd2dqx\t{$src, $dst|$dst, $src}", []>, VEX;
1856
1857 // YMM only
1858 def VCVTTPD2DQYrr : VPDI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR256:$src),
1859                          "cvttpd2dqy\t{$src, $dst|$dst, $src}", []>, VEX;
1860 def VCVTTPD2DQYrm : VPDI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f256mem:$src),
1861                          "cvttpd2dqy\t{$src, $dst|$dst, $src}", []>, VEX, VEX_L;
1862
1863 // Convert packed single to packed double
1864 let Predicates = [HasAVX] in {
1865                   // SSE2 instructions without OpSize prefix
1866 def VCVTPS2PDrr : I<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1867                      "vcvtps2pd\t{$src, $dst|$dst, $src}", []>, TB, VEX;
1868 def VCVTPS2PDrm : I<0x5A, MRMSrcMem, (outs VR128:$dst), (ins f64mem:$src),
1869                      "vcvtps2pd\t{$src, $dst|$dst, $src}", []>, TB, VEX;
1870 def VCVTPS2PDYrr : I<0x5A, MRMSrcReg, (outs VR256:$dst), (ins VR128:$src),
1871                      "vcvtps2pd\t{$src, $dst|$dst, $src}", []>, TB, VEX;
1872 def VCVTPS2PDYrm : I<0x5A, MRMSrcMem, (outs VR256:$dst), (ins f128mem:$src),
1873                      "vcvtps2pd\t{$src, $dst|$dst, $src}", []>, TB, VEX;
1874 }
1875 def CVTPS2PDrr : I<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1876                        "cvtps2pd\t{$src, $dst|$dst, $src}", []>, TB;
1877 def CVTPS2PDrm : I<0x5A, MRMSrcMem, (outs VR128:$dst), (ins f64mem:$src),
1878                        "cvtps2pd\t{$src, $dst|$dst, $src}", []>, TB;
1879
1880 def Int_VCVTPS2PDrr : I<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1881                        "vcvtps2pd\t{$src, $dst|$dst, $src}",
1882                        [(set VR128:$dst, (int_x86_sse2_cvtps2pd VR128:$src))]>,
1883                      TB, VEX, Requires<[HasAVX]>;
1884 def Int_VCVTPS2PDrm : I<0x5A, MRMSrcMem, (outs VR128:$dst), (ins f64mem:$src),
1885                        "vcvtps2pd\t{$src, $dst|$dst, $src}",
1886                        [(set VR128:$dst, (int_x86_sse2_cvtps2pd
1887                                           (load addr:$src)))]>,
1888                      TB, VEX, Requires<[HasAVX]>;
1889 def Int_CVTPS2PDrr : I<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1890                        "cvtps2pd\t{$src, $dst|$dst, $src}",
1891                        [(set VR128:$dst, (int_x86_sse2_cvtps2pd VR128:$src))]>,
1892                      TB, Requires<[HasSSE2]>;
1893 def Int_CVTPS2PDrm : I<0x5A, MRMSrcMem, (outs VR128:$dst), (ins f64mem:$src),
1894                        "cvtps2pd\t{$src, $dst|$dst, $src}",
1895                        [(set VR128:$dst, (int_x86_sse2_cvtps2pd
1896                                           (load addr:$src)))]>,
1897                      TB, Requires<[HasSSE2]>;
1898
1899 // Convert packed double to packed single
1900 // The assembler can recognize rr 256-bit instructions by seeing a ymm
1901 // register, but the same isn't true when using memory operands instead.
1902 // Provide other assembly rr and rm forms to address this explicitly.
1903 def VCVTPD2PSrr : VPDI<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1904                        "cvtpd2ps\t{$src, $dst|$dst, $src}", []>, VEX;
1905 def VCVTPD2PSXrYr : VPDI<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR256:$src),
1906                          "cvtpd2ps\t{$src, $dst|$dst, $src}", []>, VEX;
1907
1908 // XMM only
1909 def VCVTPD2PSXrr : VPDI<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1910                         "cvtpd2psx\t{$src, $dst|$dst, $src}", []>, VEX;
1911 def VCVTPD2PSXrm : VPDI<0x5A, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1912                         "cvtpd2psx\t{$src, $dst|$dst, $src}", []>, VEX;
1913
1914 // YMM only
1915 def VCVTPD2PSYrr : VPDI<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR256:$src),
1916                         "cvtpd2psy\t{$src, $dst|$dst, $src}", []>, VEX;
1917 def VCVTPD2PSYrm : VPDI<0x5A, MRMSrcMem, (outs VR128:$dst), (ins f256mem:$src),
1918                         "cvtpd2psy\t{$src, $dst|$dst, $src}", []>, VEX, VEX_L;
1919 def CVTPD2PSrr : PDI<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1920                      "cvtpd2ps\t{$src, $dst|$dst, $src}", []>;
1921 def CVTPD2PSrm : PDI<0x5A, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1922                      "cvtpd2ps\t{$src, $dst|$dst, $src}", []>;
1923
1924
1925 def Int_VCVTPD2PSrr : VPDI<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1926                          "cvtpd2ps\t{$src, $dst|$dst, $src}",
1927                         [(set VR128:$dst, (int_x86_sse2_cvtpd2ps VR128:$src))]>;
1928 def Int_VCVTPD2PSrm : VPDI<0x5A, MRMSrcMem, (outs VR128:$dst),
1929                          (ins f128mem:$src),
1930                          "cvtpd2ps\t{$src, $dst|$dst, $src}",
1931                          [(set VR128:$dst, (int_x86_sse2_cvtpd2ps
1932                                             (memop addr:$src)))]>;
1933 def Int_CVTPD2PSrr : PDI<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1934                          "cvtpd2ps\t{$src, $dst|$dst, $src}",
1935                         [(set VR128:$dst, (int_x86_sse2_cvtpd2ps VR128:$src))]>;
1936 def Int_CVTPD2PSrm : PDI<0x5A, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1937                          "cvtpd2ps\t{$src, $dst|$dst, $src}",
1938                          [(set VR128:$dst, (int_x86_sse2_cvtpd2ps
1939                                             (memop addr:$src)))]>;
1940
1941 // AVX 256-bit register conversion intrinsics
1942 // FIXME: Migrate SSE conversion intrinsics matching to use patterns as below
1943 // whenever possible to avoid declaring two versions of each one.
1944 def : Pat<(int_x86_avx_cvtdq2_ps_256 VR256:$src),
1945           (VCVTDQ2PSYrr VR256:$src)>;
1946 def : Pat<(int_x86_avx_cvtdq2_ps_256 (memopv8i32 addr:$src)),
1947           (VCVTDQ2PSYrm addr:$src)>;
1948
1949 def : Pat<(int_x86_avx_cvt_pd2_ps_256 VR256:$src),
1950           (VCVTPD2PSYrr VR256:$src)>;
1951 def : Pat<(int_x86_avx_cvt_pd2_ps_256 (memopv4f64 addr:$src)),
1952           (VCVTPD2PSYrm addr:$src)>;
1953
1954 def : Pat<(int_x86_avx_cvt_ps2dq_256 VR256:$src),
1955           (VCVTPS2DQYrr VR256:$src)>;
1956 def : Pat<(int_x86_avx_cvt_ps2dq_256 (memopv8f32 addr:$src)),
1957           (VCVTPS2DQYrm addr:$src)>;
1958
1959 def : Pat<(int_x86_avx_cvt_ps2_pd_256 VR128:$src),
1960           (VCVTPS2PDYrr VR128:$src)>;
1961 def : Pat<(int_x86_avx_cvt_ps2_pd_256 (memopv4f32 addr:$src)),
1962           (VCVTPS2PDYrm addr:$src)>;
1963
1964 def : Pat<(int_x86_avx_cvtt_pd2dq_256 VR256:$src),
1965           (VCVTTPD2DQYrr VR256:$src)>;
1966 def : Pat<(int_x86_avx_cvtt_pd2dq_256 (memopv4f64 addr:$src)),
1967           (VCVTTPD2DQYrm addr:$src)>;
1968
1969 def : Pat<(int_x86_avx_cvtt_ps2dq_256 VR256:$src),
1970           (VCVTTPS2DQYrr VR256:$src)>;
1971 def : Pat<(int_x86_avx_cvtt_ps2dq_256 (memopv8f32 addr:$src)),
1972           (VCVTTPS2DQYrm addr:$src)>;
1973
1974 // Match fround and fextend for 128/256-bit conversions
1975 def : Pat<(v4f32 (fround (v4f64 VR256:$src))),
1976           (VCVTPD2PSYrr VR256:$src)>;
1977 def : Pat<(v4f32 (fround (loadv4f64 addr:$src))),
1978           (VCVTPD2PSYrm addr:$src)>;
1979
1980 def : Pat<(v4f64 (fextend (v4f32 VR128:$src))),
1981           (VCVTPS2PDYrr VR128:$src)>;
1982 def : Pat<(v4f64 (fextend (loadv4f32 addr:$src))),
1983           (VCVTPS2PDYrm addr:$src)>;
1984
1985 //===----------------------------------------------------------------------===//
1986 // SSE 1 & 2 - Compare Instructions
1987 //===----------------------------------------------------------------------===//
1988
1989 // sse12_cmp_scalar - sse 1 & 2 compare scalar instructions
1990 multiclass sse12_cmp_scalar<RegisterClass RC, X86MemOperand x86memop,
1991                             SDNode OpNode, ValueType VT, PatFrag ld_frag,
1992                             string asm, string asm_alt> {
1993   def rr : SIi8<0xC2, MRMSrcReg,
1994                 (outs RC:$dst), (ins RC:$src1, RC:$src2, SSECC:$cc), asm,
1995                 [(set RC:$dst, (OpNode (VT RC:$src1), RC:$src2, imm:$cc))]>;
1996   def rm : SIi8<0xC2, MRMSrcMem,
1997                 (outs RC:$dst), (ins RC:$src1, x86memop:$src2, SSECC:$cc), asm,
1998                 [(set RC:$dst, (OpNode (VT RC:$src1),
1999                                          (ld_frag addr:$src2), imm:$cc))]>;
2000
2001   // Accept explicit immediate argument form instead of comparison code.
2002   let neverHasSideEffects = 1 in {
2003     def rr_alt : SIi8<0xC2, MRMSrcReg, (outs RC:$dst),
2004                       (ins RC:$src1, RC:$src2, i8imm:$cc), asm_alt, []>;
2005     let mayLoad = 1 in
2006     def rm_alt : SIi8<0xC2, MRMSrcMem, (outs RC:$dst),
2007                       (ins RC:$src1, x86memop:$src2, i8imm:$cc), asm_alt, []>;
2008   }
2009 }
2010
2011 defm VCMPSS : sse12_cmp_scalar<FR32, f32mem, X86cmpss, f32, loadf32,
2012                  "cmp${cc}ss\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2013                  "cmpss\t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}">,
2014                  XS, VEX_4V;
2015 defm VCMPSD : sse12_cmp_scalar<FR64, f64mem, X86cmpsd, f64, loadf64,
2016                  "cmp${cc}sd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2017                  "cmpsd\t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}">,
2018                  XD, VEX_4V;
2019
2020 let Constraints = "$src1 = $dst" in {
2021   defm CMPSS : sse12_cmp_scalar<FR32, f32mem, X86cmpss, f32, loadf32,
2022                   "cmp${cc}ss\t{$src2, $dst|$dst, $src2}",
2023                   "cmpss\t{$cc, $src2, $dst|$dst, $src2, $cc}">,
2024                   XS;
2025   defm CMPSD : sse12_cmp_scalar<FR64, f64mem, X86cmpsd, f64, loadf64,
2026                   "cmp${cc}sd\t{$src2, $dst|$dst, $src2}",
2027                   "cmpsd\t{$cc, $src2, $dst|$dst, $src2, $cc}">,
2028                   XD;
2029 }
2030
2031 multiclass sse12_cmp_scalar_int<RegisterClass RC, X86MemOperand x86memop,
2032                          Intrinsic Int, string asm> {
2033   def rr : SIi8<0xC2, MRMSrcReg, (outs VR128:$dst),
2034                       (ins VR128:$src1, VR128:$src, SSECC:$cc), asm,
2035                         [(set VR128:$dst, (Int VR128:$src1,
2036                                                VR128:$src, imm:$cc))]>;
2037   def rm : SIi8<0xC2, MRMSrcMem, (outs VR128:$dst),
2038                       (ins VR128:$src1, f32mem:$src, SSECC:$cc), asm,
2039                         [(set VR128:$dst, (Int VR128:$src1,
2040                                                (load addr:$src), imm:$cc))]>;
2041 }
2042
2043 // Aliases to match intrinsics which expect XMM operand(s).
2044 defm Int_VCMPSS  : sse12_cmp_scalar_int<VR128, f32mem, int_x86_sse_cmp_ss,
2045                      "cmp${cc}ss\t{$src, $src1, $dst|$dst, $src1, $src}">,
2046                      XS, VEX_4V;
2047 defm Int_VCMPSD  : sse12_cmp_scalar_int<VR128, f64mem, int_x86_sse2_cmp_sd,
2048                      "cmp${cc}sd\t{$src, $src1, $dst|$dst, $src1, $src}">,
2049                      XD, VEX_4V;
2050 let Constraints = "$src1 = $dst" in {
2051   defm Int_CMPSS  : sse12_cmp_scalar_int<VR128, f32mem, int_x86_sse_cmp_ss,
2052                        "cmp${cc}ss\t{$src, $dst|$dst, $src}">, XS;
2053   defm Int_CMPSD  : sse12_cmp_scalar_int<VR128, f64mem, int_x86_sse2_cmp_sd,
2054                        "cmp${cc}sd\t{$src, $dst|$dst, $src}">, XD;
2055 }
2056
2057
2058 // sse12_ord_cmp - Unordered/Ordered scalar fp compare and set EFLAGS
2059 multiclass sse12_ord_cmp<bits<8> opc, RegisterClass RC, SDNode OpNode,
2060                             ValueType vt, X86MemOperand x86memop,
2061                             PatFrag ld_frag, string OpcodeStr, Domain d> {
2062   def rr: PI<opc, MRMSrcReg, (outs), (ins RC:$src1, RC:$src2),
2063                      !strconcat(OpcodeStr, "\t{$src2, $src1|$src1, $src2}"),
2064                      [(set EFLAGS, (OpNode (vt RC:$src1), RC:$src2))], d>;
2065   def rm: PI<opc, MRMSrcMem, (outs), (ins RC:$src1, x86memop:$src2),
2066                      !strconcat(OpcodeStr, "\t{$src2, $src1|$src1, $src2}"),
2067                      [(set EFLAGS, (OpNode (vt RC:$src1),
2068                                            (ld_frag addr:$src2)))], d>;
2069 }
2070
2071 let Defs = [EFLAGS] in {
2072   defm VUCOMISS : sse12_ord_cmp<0x2E, FR32, X86cmp, f32, f32mem, loadf32,
2073                                   "ucomiss", SSEPackedSingle>, TB, VEX;
2074   defm VUCOMISD : sse12_ord_cmp<0x2E, FR64, X86cmp, f64, f64mem, loadf64,
2075                                   "ucomisd", SSEPackedDouble>, TB, OpSize, VEX;
2076   let Pattern = []<dag> in {
2077     defm VCOMISS  : sse12_ord_cmp<0x2F, VR128, undef, v4f32, f128mem, load,
2078                                     "comiss", SSEPackedSingle>, TB, VEX;
2079     defm VCOMISD  : sse12_ord_cmp<0x2F, VR128, undef, v2f64, f128mem, load,
2080                                     "comisd", SSEPackedDouble>, TB, OpSize, VEX;
2081   }
2082
2083   defm Int_VUCOMISS  : sse12_ord_cmp<0x2E, VR128, X86ucomi, v4f32, f128mem,
2084                             load, "ucomiss", SSEPackedSingle>, TB, VEX;
2085   defm Int_VUCOMISD  : sse12_ord_cmp<0x2E, VR128, X86ucomi, v2f64, f128mem,
2086                             load, "ucomisd", SSEPackedDouble>, TB, OpSize, VEX;
2087
2088   defm Int_VCOMISS  : sse12_ord_cmp<0x2F, VR128, X86comi, v4f32, f128mem,
2089                             load, "comiss", SSEPackedSingle>, TB, VEX;
2090   defm Int_VCOMISD  : sse12_ord_cmp<0x2F, VR128, X86comi, v2f64, f128mem,
2091                             load, "comisd", SSEPackedDouble>, TB, OpSize, VEX;
2092   defm UCOMISS  : sse12_ord_cmp<0x2E, FR32, X86cmp, f32, f32mem, loadf32,
2093                                   "ucomiss", SSEPackedSingle>, TB;
2094   defm UCOMISD  : sse12_ord_cmp<0x2E, FR64, X86cmp, f64, f64mem, loadf64,
2095                                   "ucomisd", SSEPackedDouble>, TB, OpSize;
2096
2097   let Pattern = []<dag> in {
2098     defm COMISS  : sse12_ord_cmp<0x2F, VR128, undef, v4f32, f128mem, load,
2099                                     "comiss", SSEPackedSingle>, TB;
2100     defm COMISD  : sse12_ord_cmp<0x2F, VR128, undef, v2f64, f128mem, load,
2101                                     "comisd", SSEPackedDouble>, TB, OpSize;
2102   }
2103
2104   defm Int_UCOMISS  : sse12_ord_cmp<0x2E, VR128, X86ucomi, v4f32, f128mem,
2105                               load, "ucomiss", SSEPackedSingle>, TB;
2106   defm Int_UCOMISD  : sse12_ord_cmp<0x2E, VR128, X86ucomi, v2f64, f128mem,
2107                               load, "ucomisd", SSEPackedDouble>, TB, OpSize;
2108
2109   defm Int_COMISS  : sse12_ord_cmp<0x2F, VR128, X86comi, v4f32, f128mem, load,
2110                                   "comiss", SSEPackedSingle>, TB;
2111   defm Int_COMISD  : sse12_ord_cmp<0x2F, VR128, X86comi, v2f64, f128mem, load,
2112                                   "comisd", SSEPackedDouble>, TB, OpSize;
2113 } // Defs = [EFLAGS]
2114
2115 // sse12_cmp_packed - sse 1 & 2 compared packed instructions
2116 multiclass sse12_cmp_packed<RegisterClass RC, X86MemOperand x86memop,
2117                             Intrinsic Int, string asm, string asm_alt,
2118                             Domain d> {
2119   let isAsmParserOnly = 1 in {
2120     def rri : PIi8<0xC2, MRMSrcReg,
2121                (outs RC:$dst), (ins RC:$src1, RC:$src2, SSECC:$cc), asm,
2122                [(set RC:$dst, (Int RC:$src1, RC:$src2, imm:$cc))], d>;
2123     def rmi : PIi8<0xC2, MRMSrcMem,
2124                (outs RC:$dst), (ins RC:$src1, f128mem:$src2, SSECC:$cc), asm,
2125                [(set RC:$dst, (Int RC:$src1, (memop addr:$src2), imm:$cc))], d>;
2126   }
2127
2128   // Accept explicit immediate argument form instead of comparison code.
2129   def rri_alt : PIi8<0xC2, MRMSrcReg,
2130              (outs RC:$dst), (ins RC:$src1, RC:$src2, i8imm:$cc),
2131              asm_alt, [], d>;
2132   def rmi_alt : PIi8<0xC2, MRMSrcMem,
2133              (outs RC:$dst), (ins RC:$src1, f128mem:$src2, i8imm:$cc),
2134              asm_alt, [], d>;
2135 }
2136
2137 defm VCMPPS : sse12_cmp_packed<VR128, f128mem, int_x86_sse_cmp_ps,
2138                "cmp${cc}ps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2139                "cmpps\t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}",
2140                SSEPackedSingle>, TB, VEX_4V;
2141 defm VCMPPD : sse12_cmp_packed<VR128, f128mem, int_x86_sse2_cmp_pd,
2142                "cmp${cc}pd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2143                "cmppd\t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}",
2144                SSEPackedDouble>, TB, OpSize, VEX_4V;
2145 defm VCMPPSY : sse12_cmp_packed<VR256, f256mem, int_x86_avx_cmp_ps_256,
2146                "cmp${cc}ps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2147                "cmpps\t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}",
2148                SSEPackedSingle>, TB, VEX_4V;
2149 defm VCMPPDY : sse12_cmp_packed<VR256, f256mem, int_x86_avx_cmp_pd_256,
2150                "cmp${cc}pd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2151                "cmppd\t{$cc, $src2, $src1, $dst|$dst, $src1, $src2, $cc}",
2152                SSEPackedDouble>, TB, OpSize, VEX_4V;
2153 let Constraints = "$src1 = $dst" in {
2154   defm CMPPS : sse12_cmp_packed<VR128, f128mem, int_x86_sse_cmp_ps,
2155                  "cmp${cc}ps\t{$src2, $dst|$dst, $src2}",
2156                  "cmpps\t{$cc, $src2, $dst|$dst, $src2, $cc}",
2157                  SSEPackedSingle>, TB;
2158   defm CMPPD : sse12_cmp_packed<VR128, f128mem, int_x86_sse2_cmp_pd,
2159                  "cmp${cc}pd\t{$src2, $dst|$dst, $src2}",
2160                  "cmppd\t{$cc, $src2, $dst|$dst, $src2, $cc}",
2161                  SSEPackedDouble>, TB, OpSize;
2162 }
2163
2164 let Predicates = [HasSSE1] in {
2165 def : Pat<(v4i32 (X86cmpps (v4f32 VR128:$src1), VR128:$src2, imm:$cc)),
2166           (CMPPSrri (v4f32 VR128:$src1), (v4f32 VR128:$src2), imm:$cc)>;
2167 def : Pat<(v4i32 (X86cmpps (v4f32 VR128:$src1), (memop addr:$src2), imm:$cc)),
2168           (CMPPSrmi (v4f32 VR128:$src1), addr:$src2, imm:$cc)>;
2169 }
2170
2171 let Predicates = [HasSSE2] in {
2172 def : Pat<(v2i64 (X86cmppd (v2f64 VR128:$src1), VR128:$src2, imm:$cc)),
2173           (CMPPDrri VR128:$src1, VR128:$src2, imm:$cc)>;
2174 def : Pat<(v2i64 (X86cmppd (v2f64 VR128:$src1), (memop addr:$src2), imm:$cc)),
2175           (CMPPDrmi VR128:$src1, addr:$src2, imm:$cc)>;
2176 }
2177
2178 let Predicates = [HasAVX] in {
2179 def : Pat<(v4i32 (X86cmpps (v4f32 VR128:$src1), VR128:$src2, imm:$cc)),
2180           (VCMPPSrri (v4f32 VR128:$src1), (v4f32 VR128:$src2), imm:$cc)>;
2181 def : Pat<(v4i32 (X86cmpps (v4f32 VR128:$src1), (memop addr:$src2), imm:$cc)),
2182           (VCMPPSrmi (v4f32 VR128:$src1), addr:$src2, imm:$cc)>;
2183 def : Pat<(v2i64 (X86cmppd (v2f64 VR128:$src1), VR128:$src2, imm:$cc)),
2184           (VCMPPDrri VR128:$src1, VR128:$src2, imm:$cc)>;
2185 def : Pat<(v2i64 (X86cmppd (v2f64 VR128:$src1), (memop addr:$src2), imm:$cc)),
2186           (VCMPPDrmi VR128:$src1, addr:$src2, imm:$cc)>;
2187
2188 def : Pat<(v8i32 (X86cmpps (v8f32 VR256:$src1), VR256:$src2, imm:$cc)),
2189           (VCMPPSYrri (v8f32 VR256:$src1), (v8f32 VR256:$src2), imm:$cc)>;
2190 def : Pat<(v8i32 (X86cmpps (v8f32 VR256:$src1), (memop addr:$src2), imm:$cc)),
2191           (VCMPPSYrmi (v8f32 VR256:$src1), addr:$src2, imm:$cc)>;
2192 def : Pat<(v4i64 (X86cmppd (v4f64 VR256:$src1), VR256:$src2, imm:$cc)),
2193           (VCMPPDYrri VR256:$src1, VR256:$src2, imm:$cc)>;
2194 def : Pat<(v4i64 (X86cmppd (v4f64 VR256:$src1), (memop addr:$src2), imm:$cc)),
2195           (VCMPPDYrmi VR256:$src1, addr:$src2, imm:$cc)>;
2196 }
2197
2198 //===----------------------------------------------------------------------===//
2199 // SSE 1 & 2 - Shuffle Instructions
2200 //===----------------------------------------------------------------------===//
2201
2202 /// sse12_shuffle - sse 1 & 2 shuffle instructions
2203 multiclass sse12_shuffle<RegisterClass RC, X86MemOperand x86memop,
2204                          ValueType vt, string asm, PatFrag mem_frag,
2205                          Domain d, bit IsConvertibleToThreeAddress = 0> {
2206   def rmi : PIi8<0xC6, MRMSrcMem, (outs RC:$dst),
2207                    (ins RC:$src1, f128mem:$src2, i8imm:$src3), asm,
2208                    [(set RC:$dst, (vt (shufp:$src3
2209                             RC:$src1, (mem_frag addr:$src2))))], d>;
2210   let isConvertibleToThreeAddress = IsConvertibleToThreeAddress in
2211     def rri : PIi8<0xC6, MRMSrcReg, (outs RC:$dst),
2212                    (ins RC:$src1, RC:$src2, i8imm:$src3), asm,
2213                    [(set RC:$dst,
2214                             (vt (shufp:$src3 RC:$src1, RC:$src2)))], d>;
2215 }
2216
2217 defm VSHUFPS  : sse12_shuffle<VR128, f128mem, v4f32,
2218            "shufps\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
2219            memopv4f32, SSEPackedSingle>, TB, VEX_4V;
2220 defm VSHUFPSY : sse12_shuffle<VR256, f256mem, v8f32,
2221            "shufps\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
2222            memopv8f32, SSEPackedSingle>, TB, VEX_4V;
2223 defm VSHUFPD  : sse12_shuffle<VR128, f128mem, v2f64,
2224            "shufpd\t{$src3, $src2, $src1, $dst|$dst, $src2, $src2, $src3}",
2225            memopv2f64, SSEPackedDouble>, TB, OpSize, VEX_4V;
2226 defm VSHUFPDY : sse12_shuffle<VR256, f256mem, v4f64,
2227            "shufpd\t{$src3, $src2, $src1, $dst|$dst, $src2, $src2, $src3}",
2228            memopv4f64, SSEPackedDouble>, TB, OpSize, VEX_4V;
2229
2230 let Constraints = "$src1 = $dst" in {
2231   defm SHUFPS : sse12_shuffle<VR128, f128mem, v4f32,
2232                     "shufps\t{$src3, $src2, $dst|$dst, $src2, $src3}",
2233                     memopv4f32, SSEPackedSingle, 1 /* cvt to pshufd */>,
2234                     TB;
2235   defm SHUFPD : sse12_shuffle<VR128, f128mem, v2f64,
2236                     "shufpd\t{$src3, $src2, $dst|$dst, $src2, $src3}",
2237                     memopv2f64, SSEPackedDouble>, TB, OpSize;
2238 }
2239
2240 let Predicates = [HasSSE1] in {
2241   def : Pat<(v4f32 (X86Shufps VR128:$src1,
2242                        (memopv4f32 addr:$src2), (i8 imm:$imm))),
2243             (SHUFPSrmi VR128:$src1, addr:$src2, imm:$imm)>;
2244   def : Pat<(v4f32 (X86Shufps VR128:$src1, VR128:$src2, (i8 imm:$imm))),
2245             (SHUFPSrri VR128:$src1, VR128:$src2, imm:$imm)>;
2246   def : Pat<(v4i32 (X86Shufps VR128:$src1,
2247                        (bc_v4i32 (memopv2i64 addr:$src2)), (i8 imm:$imm))),
2248             (SHUFPSrmi VR128:$src1, addr:$src2, imm:$imm)>;
2249   def : Pat<(v4i32 (X86Shufps VR128:$src1, VR128:$src2, (i8 imm:$imm))),
2250             (SHUFPSrri VR128:$src1, VR128:$src2, imm:$imm)>;
2251   // vector_shuffle v1, v2 <4, 5, 2, 3> using SHUFPSrri (we prefer movsd, but
2252   // fall back to this for SSE1)
2253   def : Pat<(v4f32 (movlp:$src3 VR128:$src1, (v4f32 VR128:$src2))),
2254             (SHUFPSrri VR128:$src2, VR128:$src1,
2255                        (SHUFFLE_get_shuf_imm VR128:$src3))>;
2256   // Special unary SHUFPSrri case.
2257   def : Pat<(v4f32 (pshufd:$src3 VR128:$src1, (undef))),
2258             (SHUFPSrri VR128:$src1, VR128:$src1,
2259                        (SHUFFLE_get_shuf_imm VR128:$src3))>;
2260 }
2261
2262 let Predicates = [HasSSE2] in {
2263   // Special binary v4i32 shuffle cases with SHUFPS.
2264   def : Pat<(v4i32 (shufp:$src3 VR128:$src1, (v4i32 VR128:$src2))),
2265             (SHUFPSrri VR128:$src1, VR128:$src2,
2266                        (SHUFFLE_get_shuf_imm VR128:$src3))>;
2267   def : Pat<(v4i32 (shufp:$src3 VR128:$src1,
2268                                 (bc_v4i32 (memopv2i64 addr:$src2)))),
2269             (SHUFPSrmi VR128:$src1, addr:$src2,
2270                       (SHUFFLE_get_shuf_imm VR128:$src3))>;
2271   // Special unary SHUFPDrri cases.
2272   def : Pat<(v2i64 (pshufd:$src3 VR128:$src1, (undef))),
2273             (SHUFPDrri VR128:$src1, VR128:$src1,
2274                        (SHUFFLE_get_shuf_imm VR128:$src3))>;
2275   def : Pat<(v2f64 (pshufd:$src3 VR128:$src1, (undef))),
2276             (SHUFPDrri VR128:$src1, VR128:$src1,
2277                        (SHUFFLE_get_shuf_imm VR128:$src3))>;
2278   // Special binary v2i64 shuffle cases using SHUFPDrri.
2279   def : Pat<(v2i64 (shufp:$src3 VR128:$src1, VR128:$src2)),
2280             (SHUFPDrri VR128:$src1, VR128:$src2,
2281                        (SHUFFLE_get_shuf_imm VR128:$src3))>;
2282   // Generic SHUFPD patterns
2283   def : Pat<(v2f64 (X86Shufps VR128:$src1,
2284                        (memopv2f64 addr:$src2), (i8 imm:$imm))),
2285             (SHUFPDrmi VR128:$src1, addr:$src2, imm:$imm)>;
2286   def : Pat<(v2i64 (X86Shufpd VR128:$src1, VR128:$src2, (i8 imm:$imm))),
2287             (SHUFPDrri VR128:$src1, VR128:$src2, imm:$imm)>;
2288   def : Pat<(v2f64 (X86Shufpd VR128:$src1, VR128:$src2, (i8 imm:$imm))),
2289             (SHUFPDrri VR128:$src1, VR128:$src2, imm:$imm)>;
2290 }
2291
2292 let Predicates = [HasAVX] in {
2293   def : Pat<(v4f32 (X86Shufps VR128:$src1,
2294                        (memopv4f32 addr:$src2), (i8 imm:$imm))),
2295             (VSHUFPSrmi VR128:$src1, addr:$src2, imm:$imm)>;
2296   def : Pat<(v4f32 (X86Shufps VR128:$src1, VR128:$src2, (i8 imm:$imm))),
2297             (VSHUFPSrri VR128:$src1, VR128:$src2, imm:$imm)>;
2298   def : Pat<(v4i32 (X86Shufps VR128:$src1,
2299                        (bc_v4i32 (memopv2i64 addr:$src2)), (i8 imm:$imm))),
2300             (VSHUFPSrmi VR128:$src1, addr:$src2, imm:$imm)>;
2301   def : Pat<(v4i32 (X86Shufps VR128:$src1, VR128:$src2, (i8 imm:$imm))),
2302             (VSHUFPSrri VR128:$src1, VR128:$src2, imm:$imm)>;
2303   // vector_shuffle v1, v2 <4, 5, 2, 3> using SHUFPSrri (we prefer movsd, but
2304   // fall back to this for SSE1)
2305   def : Pat<(v4f32 (movlp:$src3 VR128:$src1, (v4f32 VR128:$src2))),
2306             (VSHUFPSrri VR128:$src2, VR128:$src1,
2307                         (SHUFFLE_get_shuf_imm VR128:$src3))>;
2308   // Special unary SHUFPSrri case.
2309   def : Pat<(v4f32 (pshufd:$src3 VR128:$src1, (undef))),
2310             (VSHUFPSrri VR128:$src1, VR128:$src1,
2311                         (SHUFFLE_get_shuf_imm VR128:$src3))>;
2312   // Special binary v4i32 shuffle cases with SHUFPS.
2313   def : Pat<(v4i32 (shufp:$src3 VR128:$src1, (v4i32 VR128:$src2))),
2314             (VSHUFPSrri VR128:$src1, VR128:$src2,
2315                         (SHUFFLE_get_shuf_imm VR128:$src3))>;
2316   def : Pat<(v4i32 (shufp:$src3 VR128:$src1,
2317                                 (bc_v4i32 (memopv2i64 addr:$src2)))),
2318             (VSHUFPSrmi VR128:$src1, addr:$src2,
2319                         (SHUFFLE_get_shuf_imm VR128:$src3))>;
2320   // Special unary SHUFPDrri cases.
2321   def : Pat<(v2i64 (pshufd:$src3 VR128:$src1, (undef))),
2322             (VSHUFPDrri VR128:$src1, VR128:$src1,
2323                         (SHUFFLE_get_shuf_imm VR128:$src3))>;
2324   def : Pat<(v2f64 (pshufd:$src3 VR128:$src1, (undef))),
2325             (VSHUFPDrri VR128:$src1, VR128:$src1,
2326                         (SHUFFLE_get_shuf_imm VR128:$src3))>;
2327   // Special binary v2i64 shuffle cases using SHUFPDrri.
2328   def : Pat<(v2i64 (shufp:$src3 VR128:$src1, VR128:$src2)),
2329             (VSHUFPDrri VR128:$src1, VR128:$src2,
2330                         (SHUFFLE_get_shuf_imm VR128:$src3))>;
2331
2332   def : Pat<(v2f64 (X86Shufps VR128:$src1,
2333                        (memopv2f64 addr:$src2), (i8 imm:$imm))),
2334             (VSHUFPDrmi VR128:$src1, addr:$src2, imm:$imm)>;
2335   def : Pat<(v2i64 (X86Shufpd VR128:$src1, VR128:$src2, (i8 imm:$imm))),
2336             (VSHUFPDrri VR128:$src1, VR128:$src2, imm:$imm)>;
2337   def : Pat<(v2f64 (X86Shufpd VR128:$src1, VR128:$src2, (i8 imm:$imm))),
2338             (VSHUFPDrri VR128:$src1, VR128:$src2, imm:$imm)>;
2339
2340   // 256-bit patterns
2341   def : Pat<(v8i32 (X86Shufps VR256:$src1, VR256:$src2, (i8 imm:$imm))),
2342             (VSHUFPSYrri VR256:$src1, VR256:$src2, imm:$imm)>;
2343   def : Pat<(v8i32 (X86Shufps VR256:$src1,
2344                       (bc_v8i32 (memopv4i64 addr:$src2)), (i8 imm:$imm))),
2345             (VSHUFPSYrmi VR256:$src1, addr:$src2, imm:$imm)>;
2346
2347   def : Pat<(v8f32 (X86Shufps VR256:$src1, VR256:$src2, (i8 imm:$imm))),
2348             (VSHUFPSYrri VR256:$src1, VR256:$src2, imm:$imm)>;
2349   def : Pat<(v8f32 (X86Shufps VR256:$src1,
2350                               (memopv8f32 addr:$src2), (i8 imm:$imm))),
2351             (VSHUFPSYrmi VR256:$src1, addr:$src2, imm:$imm)>;
2352
2353   def : Pat<(v4i64 (X86Shufpd VR256:$src1, VR256:$src2, (i8 imm:$imm))),
2354             (VSHUFPDYrri VR256:$src1, VR256:$src2, imm:$imm)>;
2355   def : Pat<(v4i64 (X86Shufpd VR256:$src1,
2356                               (memopv4i64 addr:$src2), (i8 imm:$imm))),
2357             (VSHUFPDYrmi VR256:$src1, addr:$src2, imm:$imm)>;
2358
2359   def : Pat<(v4f64 (X86Shufpd VR256:$src1, VR256:$src2, (i8 imm:$imm))),
2360             (VSHUFPDYrri VR256:$src1, VR256:$src2, imm:$imm)>;
2361   def : Pat<(v4f64 (X86Shufpd VR256:$src1,
2362                               (memopv4f64 addr:$src2), (i8 imm:$imm))),
2363             (VSHUFPDYrmi VR256:$src1, addr:$src2, imm:$imm)>;
2364 }
2365
2366 //===----------------------------------------------------------------------===//
2367 // SSE 1 & 2 - Unpack Instructions
2368 //===----------------------------------------------------------------------===//
2369
2370 /// sse12_unpack_interleave - sse 1 & 2 unpack and interleave
2371 multiclass sse12_unpack_interleave<bits<8> opc, PatFrag OpNode, ValueType vt,
2372                                    PatFrag mem_frag, RegisterClass RC,
2373                                    X86MemOperand x86memop, string asm,
2374                                    Domain d> {
2375     def rr : PI<opc, MRMSrcReg,
2376                 (outs RC:$dst), (ins RC:$src1, RC:$src2),
2377                 asm, [(set RC:$dst,
2378                            (vt (OpNode RC:$src1, RC:$src2)))], d>;
2379     def rm : PI<opc, MRMSrcMem,
2380                 (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
2381                 asm, [(set RC:$dst,
2382                            (vt (OpNode RC:$src1,
2383                                        (mem_frag addr:$src2))))], d>;
2384 }
2385
2386 let AddedComplexity = 10 in {
2387   defm VUNPCKHPS: sse12_unpack_interleave<0x15, unpckh, v4f32, memopv4f32,
2388         VR128, f128mem, "unpckhps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2389                        SSEPackedSingle>, TB, VEX_4V;
2390   defm VUNPCKHPD: sse12_unpack_interleave<0x15, unpckh, v2f64, memopv2f64,
2391         VR128, f128mem, "unpckhpd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2392                        SSEPackedDouble>, TB, OpSize, VEX_4V;
2393   defm VUNPCKLPS: sse12_unpack_interleave<0x14, unpckl, v4f32, memopv4f32,
2394         VR128, f128mem, "unpcklps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2395                        SSEPackedSingle>, TB, VEX_4V;
2396   defm VUNPCKLPD: sse12_unpack_interleave<0x14, unpckl, v2f64, memopv2f64,
2397         VR128, f128mem, "unpcklpd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2398                        SSEPackedDouble>, TB, OpSize, VEX_4V;
2399
2400   defm VUNPCKHPSY: sse12_unpack_interleave<0x15, unpckh, v8f32, memopv8f32,
2401         VR256, f256mem, "unpckhps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2402                        SSEPackedSingle>, TB, VEX_4V;
2403   defm VUNPCKHPDY: sse12_unpack_interleave<0x15, unpckh, v4f64, memopv4f64,
2404         VR256, f256mem, "unpckhpd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2405                        SSEPackedDouble>, TB, OpSize, VEX_4V;
2406   defm VUNPCKLPSY: sse12_unpack_interleave<0x14, unpckl, v8f32, memopv8f32,
2407         VR256, f256mem, "unpcklps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2408                        SSEPackedSingle>, TB, VEX_4V;
2409   defm VUNPCKLPDY: sse12_unpack_interleave<0x14, unpckl, v4f64, memopv4f64,
2410         VR256, f256mem, "unpcklpd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2411                        SSEPackedDouble>, TB, OpSize, VEX_4V;
2412
2413   let Constraints = "$src1 = $dst" in {
2414     defm UNPCKHPS: sse12_unpack_interleave<0x15, unpckh, v4f32, memopv4f32,
2415           VR128, f128mem, "unpckhps\t{$src2, $dst|$dst, $src2}",
2416                          SSEPackedSingle>, TB;
2417     defm UNPCKHPD: sse12_unpack_interleave<0x15, unpckh, v2f64, memopv2f64,
2418           VR128, f128mem, "unpckhpd\t{$src2, $dst|$dst, $src2}",
2419                          SSEPackedDouble>, TB, OpSize;
2420     defm UNPCKLPS: sse12_unpack_interleave<0x14, unpckl, v4f32, memopv4f32,
2421           VR128, f128mem, "unpcklps\t{$src2, $dst|$dst, $src2}",
2422                          SSEPackedSingle>, TB;
2423     defm UNPCKLPD: sse12_unpack_interleave<0x14, unpckl, v2f64, memopv2f64,
2424           VR128, f128mem, "unpcklpd\t{$src2, $dst|$dst, $src2}",
2425                          SSEPackedDouble>, TB, OpSize;
2426   } // Constraints = "$src1 = $dst"
2427 } // AddedComplexity
2428
2429 let Predicates = [HasSSE1] in {
2430   def : Pat<(v4f32 (X86Unpcklps VR128:$src1, (memopv4f32 addr:$src2))),
2431             (UNPCKLPSrm VR128:$src1, addr:$src2)>;
2432   def : Pat<(v4f32 (X86Unpcklps VR128:$src1, VR128:$src2)),
2433             (UNPCKLPSrr VR128:$src1, VR128:$src2)>;
2434   def : Pat<(v4f32 (X86Unpckhps VR128:$src1, (memopv4f32 addr:$src2))),
2435             (UNPCKHPSrm VR128:$src1, addr:$src2)>;
2436   def : Pat<(v4f32 (X86Unpckhps VR128:$src1, VR128:$src2)),
2437             (UNPCKHPSrr VR128:$src1, VR128:$src2)>;
2438 }
2439
2440 let Predicates = [HasSSE2] in {
2441   def : Pat<(v2f64 (X86Unpcklpd VR128:$src1, (memopv2f64 addr:$src2))),
2442             (UNPCKLPDrm VR128:$src1, addr:$src2)>;
2443   def : Pat<(v2f64 (X86Unpcklpd VR128:$src1, VR128:$src2)),
2444             (UNPCKLPDrr VR128:$src1, VR128:$src2)>;
2445   def : Pat<(v2f64 (X86Unpckhpd VR128:$src1, (memopv2f64 addr:$src2))),
2446             (UNPCKHPDrm VR128:$src1, addr:$src2)>;
2447   def : Pat<(v2f64 (X86Unpckhpd VR128:$src1, VR128:$src2)),
2448             (UNPCKHPDrr VR128:$src1, VR128:$src2)>;
2449
2450   // FIXME: Instead of X86Movddup, there should be a X86Unpcklpd here, the
2451   // problem is during lowering, where it's not possible to recognize the load
2452   // fold cause it has two uses through a bitcast. One use disappears at isel
2453   // time and the fold opportunity reappears.
2454   def : Pat<(v2f64 (X86Movddup VR128:$src)),
2455             (UNPCKLPDrr VR128:$src, VR128:$src)>;
2456
2457   let AddedComplexity = 10 in
2458   def : Pat<(splat_lo (v2f64 VR128:$src), (undef)),
2459             (UNPCKLPDrr VR128:$src, VR128:$src)>;
2460 }
2461
2462 let Predicates = [HasAVX] in {
2463   def : Pat<(v4f32 (X86Unpcklps VR128:$src1, (memopv4f32 addr:$src2))),
2464             (VUNPCKLPSrm VR128:$src1, addr:$src2)>;
2465   def : Pat<(v4f32 (X86Unpcklps VR128:$src1, VR128:$src2)),
2466             (VUNPCKLPSrr VR128:$src1, VR128:$src2)>;
2467   def : Pat<(v4f32 (X86Unpckhps VR128:$src1, (memopv4f32 addr:$src2))),
2468             (VUNPCKHPSrm VR128:$src1, addr:$src2)>;
2469   def : Pat<(v4f32 (X86Unpckhps VR128:$src1, VR128:$src2)),
2470             (VUNPCKHPSrr VR128:$src1, VR128:$src2)>;
2471
2472   def : Pat<(v8f32 (X86Unpcklpsy VR256:$src1, (memopv8f32 addr:$src2))),
2473             (VUNPCKLPSYrm VR256:$src1, addr:$src2)>;
2474   def : Pat<(v8f32 (X86Unpcklpsy VR256:$src1, VR256:$src2)),
2475             (VUNPCKLPSYrr VR256:$src1, VR256:$src2)>;
2476   def : Pat<(v8i32 (X86Unpcklpsy VR256:$src1, VR256:$src2)),
2477             (VUNPCKLPSYrr VR256:$src1, VR256:$src2)>;
2478   def : Pat<(v8i32 (X86Unpcklpsy VR256:$src1, (memopv8i32 addr:$src2))),
2479             (VUNPCKLPSYrm VR256:$src1, addr:$src2)>;
2480   def : Pat<(v8f32 (X86Unpckhpsy VR256:$src1, (memopv8f32 addr:$src2))),
2481             (VUNPCKHPSYrm VR256:$src1, addr:$src2)>;
2482   def : Pat<(v8f32 (X86Unpckhpsy VR256:$src1, VR256:$src2)),
2483             (VUNPCKHPSYrr VR256:$src1, VR256:$src2)>;
2484   def : Pat<(v8i32 (X86Unpckhpsy VR256:$src1, (memopv8i32 addr:$src2))),
2485             (VUNPCKHPSYrm VR256:$src1, addr:$src2)>;
2486   def : Pat<(v8i32 (X86Unpckhpsy VR256:$src1, VR256:$src2)),
2487             (VUNPCKHPSYrr VR256:$src1, VR256:$src2)>;
2488
2489   def : Pat<(v2f64 (X86Unpcklpd VR128:$src1, (memopv2f64 addr:$src2))),
2490             (VUNPCKLPDrm VR128:$src1, addr:$src2)>;
2491   def : Pat<(v2f64 (X86Unpcklpd VR128:$src1, VR128:$src2)),
2492             (VUNPCKLPDrr VR128:$src1, VR128:$src2)>;
2493   def : Pat<(v2f64 (X86Unpckhpd VR128:$src1, (memopv2f64 addr:$src2))),
2494             (VUNPCKHPDrm VR128:$src1, addr:$src2)>;
2495   def : Pat<(v2f64 (X86Unpckhpd VR128:$src1, VR128:$src2)),
2496             (VUNPCKHPDrr VR128:$src1, VR128:$src2)>;
2497
2498   def : Pat<(v4f64 (X86Unpcklpdy VR256:$src1, (memopv4f64 addr:$src2))),
2499             (VUNPCKLPDYrm VR256:$src1, addr:$src2)>;
2500   def : Pat<(v4f64 (X86Unpcklpdy VR256:$src1, VR256:$src2)),
2501             (VUNPCKLPDYrr VR256:$src1, VR256:$src2)>;
2502   def : Pat<(v4i64 (X86Unpcklpdy VR256:$src1, (memopv4i64 addr:$src2))),
2503             (VUNPCKLPDYrm VR256:$src1, addr:$src2)>;
2504   def : Pat<(v4i64 (X86Unpcklpdy VR256:$src1, VR256:$src2)),
2505             (VUNPCKLPDYrr VR256:$src1, VR256:$src2)>;
2506   def : Pat<(v4f64 (X86Unpckhpdy VR256:$src1, (memopv4f64 addr:$src2))),
2507             (VUNPCKHPDYrm VR256:$src1, addr:$src2)>;
2508   def : Pat<(v4f64 (X86Unpckhpdy VR256:$src1, VR256:$src2)),
2509             (VUNPCKHPDYrr VR256:$src1, VR256:$src2)>;
2510   def : Pat<(v4i64 (X86Unpckhpdy VR256:$src1, (memopv4i64 addr:$src2))),
2511             (VUNPCKHPDYrm VR256:$src1, addr:$src2)>;
2512   def : Pat<(v4i64 (X86Unpckhpdy VR256:$src1, VR256:$src2)),
2513             (VUNPCKHPDYrr VR256:$src1, VR256:$src2)>;
2514
2515   // FIXME: Instead of X86Movddup, there should be a X86Unpcklpd here, the
2516   // problem is during lowering, where it's not possible to recognize the load
2517   // fold cause it has two uses through a bitcast. One use disappears at isel
2518   // time and the fold opportunity reappears.
2519   def : Pat<(v2f64 (X86Movddup VR128:$src)),
2520             (VUNPCKLPDrr VR128:$src, VR128:$src)>;
2521   let AddedComplexity = 10 in
2522   def : Pat<(splat_lo (v2f64 VR128:$src), (undef)),
2523             (VUNPCKLPDrr VR128:$src, VR128:$src)>;
2524 }
2525
2526 //===----------------------------------------------------------------------===//
2527 // SSE 1 & 2 - Extract Floating-Point Sign mask
2528 //===----------------------------------------------------------------------===//
2529
2530 /// sse12_extr_sign_mask - sse 1 & 2 unpack and interleave
2531 multiclass sse12_extr_sign_mask<RegisterClass RC, Intrinsic Int, string asm,
2532                                 Domain d> {
2533   def rr32 : PI<0x50, MRMSrcReg, (outs GR32:$dst), (ins RC:$src),
2534                 !strconcat(asm, "\t{$src, $dst|$dst, $src}"),
2535                      [(set GR32:$dst, (Int RC:$src))], d>;
2536   def rr64 : PI<0x50, MRMSrcReg, (outs GR64:$dst), (ins RC:$src),
2537                 !strconcat(asm, "\t{$src, $dst|$dst, $src}"), [], d>, REX_W;
2538 }
2539
2540 defm MOVMSKPS : sse12_extr_sign_mask<VR128, int_x86_sse_movmsk_ps, "movmskps",
2541                                      SSEPackedSingle>, TB;
2542 defm MOVMSKPD : sse12_extr_sign_mask<VR128, int_x86_sse2_movmsk_pd, "movmskpd",
2543                                      SSEPackedDouble>, TB, OpSize;
2544
2545 def : Pat<(i32 (X86fgetsign FR32:$src)),
2546           (MOVMSKPSrr32 (INSERT_SUBREG (v4f32 (IMPLICIT_DEF)), FR32:$src,
2547                                        sub_ss))>, Requires<[HasSSE1]>;
2548 def : Pat<(i64 (X86fgetsign FR32:$src)),
2549           (MOVMSKPSrr64 (INSERT_SUBREG (v4f32 (IMPLICIT_DEF)), FR32:$src,
2550                                        sub_ss))>, Requires<[HasSSE1]>;
2551 def : Pat<(i32 (X86fgetsign FR64:$src)),
2552           (MOVMSKPDrr32 (INSERT_SUBREG (v2f64 (IMPLICIT_DEF)), FR64:$src,
2553                                        sub_sd))>, Requires<[HasSSE2]>;
2554 def : Pat<(i64 (X86fgetsign FR64:$src)),
2555           (MOVMSKPDrr64 (INSERT_SUBREG (v2f64 (IMPLICIT_DEF)), FR64:$src,
2556                                        sub_sd))>, Requires<[HasSSE2]>;
2557
2558 let Predicates = [HasAVX] in {
2559   defm VMOVMSKPS : sse12_extr_sign_mask<VR128, int_x86_sse_movmsk_ps,
2560                                         "movmskps", SSEPackedSingle>, TB, VEX;
2561   defm VMOVMSKPD : sse12_extr_sign_mask<VR128, int_x86_sse2_movmsk_pd,
2562                                         "movmskpd", SSEPackedDouble>, TB,
2563                                         OpSize, VEX;
2564   defm VMOVMSKPSY : sse12_extr_sign_mask<VR256, int_x86_avx_movmsk_ps_256,
2565                                         "movmskps", SSEPackedSingle>, TB, VEX;
2566   defm VMOVMSKPDY : sse12_extr_sign_mask<VR256, int_x86_avx_movmsk_pd_256,
2567                                         "movmskpd", SSEPackedDouble>, TB,
2568                                         OpSize, VEX;
2569
2570   def : Pat<(i32 (X86fgetsign FR32:$src)),
2571             (VMOVMSKPSrr32 (INSERT_SUBREG (v4f32 (IMPLICIT_DEF)), FR32:$src,
2572                                           sub_ss))>;
2573   def : Pat<(i64 (X86fgetsign FR32:$src)),
2574             (VMOVMSKPSrr64 (INSERT_SUBREG (v4f32 (IMPLICIT_DEF)), FR32:$src,
2575                                           sub_ss))>;
2576   def : Pat<(i32 (X86fgetsign FR64:$src)),
2577             (VMOVMSKPDrr32 (INSERT_SUBREG (v2f64 (IMPLICIT_DEF)), FR64:$src,
2578                                           sub_sd))>;
2579   def : Pat<(i64 (X86fgetsign FR64:$src)),
2580             (VMOVMSKPDrr64 (INSERT_SUBREG (v2f64 (IMPLICIT_DEF)), FR64:$src,
2581                                           sub_sd))>;
2582
2583   // Assembler Only
2584   def VMOVMSKPSr64r : PI<0x50, MRMSrcReg, (outs GR64:$dst), (ins VR128:$src),
2585              "movmskps\t{$src, $dst|$dst, $src}", [], SSEPackedSingle>, TB, VEX;
2586   def VMOVMSKPDr64r : PI<0x50, MRMSrcReg, (outs GR64:$dst), (ins VR128:$src),
2587              "movmskpd\t{$src, $dst|$dst, $src}", [], SSEPackedDouble>, TB,
2588              OpSize, VEX;
2589   def VMOVMSKPSYr64r : PI<0x50, MRMSrcReg, (outs GR64:$dst), (ins VR256:$src),
2590              "movmskps\t{$src, $dst|$dst, $src}", [], SSEPackedSingle>, TB, VEX;
2591   def VMOVMSKPDYr64r : PI<0x50, MRMSrcReg, (outs GR64:$dst), (ins VR256:$src),
2592              "movmskpd\t{$src, $dst|$dst, $src}", [], SSEPackedDouble>, TB,
2593              OpSize, VEX;
2594 }
2595
2596 //===----------------------------------------------------------------------===//
2597 // SSE 1 & 2 - Logical Instructions
2598 //===----------------------------------------------------------------------===//
2599
2600 /// sse12_fp_alias_pack_logical - SSE 1 & 2 aliased packed FP logical ops
2601 ///
2602 multiclass sse12_fp_alias_pack_logical<bits<8> opc, string OpcodeStr,
2603                                        SDNode OpNode> {
2604   defm V#NAME#PS : sse12_fp_packed<opc, !strconcat(OpcodeStr, "ps"), OpNode,
2605               FR32, f32, f128mem, memopfsf32, SSEPackedSingle, 0>, TB, VEX_4V;
2606
2607   defm V#NAME#PD : sse12_fp_packed<opc, !strconcat(OpcodeStr, "pd"), OpNode,
2608         FR64, f64, f128mem, memopfsf64, SSEPackedDouble, 0>, TB, OpSize, VEX_4V;
2609
2610   let Constraints = "$src1 = $dst" in {
2611     defm PS : sse12_fp_packed<opc, !strconcat(OpcodeStr, "ps"), OpNode, FR32,
2612                 f32, f128mem, memopfsf32, SSEPackedSingle>, TB;
2613
2614     defm PD : sse12_fp_packed<opc, !strconcat(OpcodeStr, "pd"), OpNode, FR64,
2615                 f64, f128mem, memopfsf64, SSEPackedDouble>, TB, OpSize;
2616   }
2617 }
2618
2619 // Alias bitwise logical operations using SSE logical ops on packed FP values.
2620 let mayLoad = 0 in {
2621   defm FsAND  : sse12_fp_alias_pack_logical<0x54, "and", X86fand>;
2622   defm FsOR   : sse12_fp_alias_pack_logical<0x56, "or", X86for>;
2623   defm FsXOR  : sse12_fp_alias_pack_logical<0x57, "xor", X86fxor>;
2624 }
2625
2626 let neverHasSideEffects = 1, Pattern = []<dag>, isCommutable = 0 in
2627   defm FsANDN : sse12_fp_alias_pack_logical<0x55, "andn", undef>;
2628
2629 /// sse12_fp_packed_logical - SSE 1 & 2 packed FP logical ops
2630 ///
2631 multiclass sse12_fp_packed_logical<bits<8> opc, string OpcodeStr,
2632                                    SDNode OpNode> {
2633   // In AVX no need to add a pattern for 128-bit logical rr ps, because they
2634   // are all promoted to v2i64, and the patterns are covered by the int
2635   // version. This is needed in SSE only, because v2i64 isn't supported on
2636   // SSE1, but only on SSE2.
2637   defm V#NAME#PS : sse12_fp_packed_logical_rm<opc, VR128, SSEPackedSingle,
2638        !strconcat(OpcodeStr, "ps"), f128mem, [],
2639        [(set VR128:$dst, (OpNode (bc_v2i64 (v4f32 VR128:$src1)),
2640                                  (memopv2i64 addr:$src2)))], 0>, TB, VEX_4V;
2641
2642   defm V#NAME#PD : sse12_fp_packed_logical_rm<opc, VR128, SSEPackedDouble,
2643        !strconcat(OpcodeStr, "pd"), f128mem,
2644        [(set VR128:$dst, (OpNode (bc_v2i64 (v2f64 VR128:$src1)),
2645                                  (bc_v2i64 (v2f64 VR128:$src2))))],
2646        [(set VR128:$dst, (OpNode (bc_v2i64 (v2f64 VR128:$src1)),
2647                                  (memopv2i64 addr:$src2)))], 0>,
2648                                                  TB, OpSize, VEX_4V;
2649   let Constraints = "$src1 = $dst" in {
2650     defm PS : sse12_fp_packed_logical_rm<opc, VR128, SSEPackedSingle,
2651          !strconcat(OpcodeStr, "ps"), f128mem,
2652          [(set VR128:$dst, (v2i64 (OpNode VR128:$src1, VR128:$src2)))],
2653          [(set VR128:$dst, (OpNode (bc_v2i64 (v4f32 VR128:$src1)),
2654                                    (memopv2i64 addr:$src2)))]>, TB;
2655
2656     defm PD : sse12_fp_packed_logical_rm<opc, VR128, SSEPackedDouble,
2657          !strconcat(OpcodeStr, "pd"), f128mem,
2658          [(set VR128:$dst, (OpNode (bc_v2i64 (v2f64 VR128:$src1)),
2659                                    (bc_v2i64 (v2f64 VR128:$src2))))],
2660          [(set VR128:$dst, (OpNode (bc_v2i64 (v2f64 VR128:$src1)),
2661                                    (memopv2i64 addr:$src2)))]>, TB, OpSize;
2662   }
2663 }
2664
2665 /// sse12_fp_packed_logical_y - AVX 256-bit SSE 1 & 2 logical ops forms
2666 ///
2667 multiclass sse12_fp_packed_logical_y<bits<8> opc, string OpcodeStr,
2668                                      SDNode OpNode> {
2669     defm PSY : sse12_fp_packed_logical_rm<opc, VR256, SSEPackedSingle,
2670           !strconcat(OpcodeStr, "ps"), f256mem,
2671           [(set VR256:$dst, (v4i64 (OpNode VR256:$src1, VR256:$src2)))],
2672           [(set VR256:$dst, (OpNode (bc_v4i64 (v8f32 VR256:$src1)),
2673                                     (memopv4i64 addr:$src2)))], 0>, TB, VEX_4V;
2674
2675     defm PDY : sse12_fp_packed_logical_rm<opc, VR256, SSEPackedDouble,
2676           !strconcat(OpcodeStr, "pd"), f256mem,
2677           [(set VR256:$dst, (OpNode (bc_v4i64 (v4f64 VR256:$src1)),
2678                                     (bc_v4i64 (v4f64 VR256:$src2))))],
2679           [(set VR256:$dst, (OpNode (bc_v4i64 (v4f64 VR256:$src1)),
2680                                     (memopv4i64 addr:$src2)))], 0>,
2681                                     TB, OpSize, VEX_4V;
2682 }
2683
2684 // AVX 256-bit packed logical ops forms
2685 defm VAND  : sse12_fp_packed_logical_y<0x54, "and", and>;
2686 defm VOR   : sse12_fp_packed_logical_y<0x56, "or", or>;
2687 defm VXOR  : sse12_fp_packed_logical_y<0x57, "xor", xor>;
2688 defm VANDN : sse12_fp_packed_logical_y<0x55, "andn", X86andnp>;
2689
2690 defm AND  : sse12_fp_packed_logical<0x54, "and", and>;
2691 defm OR   : sse12_fp_packed_logical<0x56, "or", or>;
2692 defm XOR  : sse12_fp_packed_logical<0x57, "xor", xor>;
2693 let isCommutable = 0 in
2694   defm ANDN : sse12_fp_packed_logical<0x55, "andn", X86andnp>;
2695
2696 //===----------------------------------------------------------------------===//
2697 // SSE 1 & 2 - Arithmetic Instructions
2698 //===----------------------------------------------------------------------===//
2699
2700 /// basic_sse12_fp_binop_xxx - SSE 1 & 2 binops come in both scalar and
2701 /// vector forms.
2702 ///
2703 /// In addition, we also have a special variant of the scalar form here to
2704 /// represent the associated intrinsic operation.  This form is unlike the
2705 /// plain scalar form, in that it takes an entire vector (instead of a scalar)
2706 /// and leaves the top elements unmodified (therefore these cannot be commuted).
2707 ///
2708 /// These three forms can each be reg+reg or reg+mem.
2709 ///
2710
2711 /// FIXME: once all 256-bit intrinsics are matched, cleanup and refactor those
2712 /// classes below
2713 multiclass basic_sse12_fp_binop_s<bits<8> opc, string OpcodeStr, SDNode OpNode,
2714                                   bit Is2Addr = 1> {
2715   defm SS : sse12_fp_scalar<opc, !strconcat(OpcodeStr, "ss"),
2716                             OpNode, FR32, f32mem, Is2Addr>, XS;
2717   defm SD : sse12_fp_scalar<opc, !strconcat(OpcodeStr, "sd"),
2718                             OpNode, FR64, f64mem, Is2Addr>, XD;
2719 }
2720
2721 multiclass basic_sse12_fp_binop_p<bits<8> opc, string OpcodeStr, SDNode OpNode,
2722                                    bit Is2Addr = 1> {
2723   let mayLoad = 0 in {
2724   defm PS : sse12_fp_packed<opc, !strconcat(OpcodeStr, "ps"), OpNode, VR128,
2725               v4f32, f128mem, memopv4f32, SSEPackedSingle, Is2Addr>, TB;
2726   defm PD : sse12_fp_packed<opc, !strconcat(OpcodeStr, "pd"), OpNode, VR128,
2727               v2f64, f128mem, memopv2f64, SSEPackedDouble, Is2Addr>, TB, OpSize;
2728   }
2729 }
2730
2731 multiclass basic_sse12_fp_binop_p_y<bits<8> opc, string OpcodeStr,
2732                                     SDNode OpNode> {
2733   let mayLoad = 0 in {
2734     defm PSY : sse12_fp_packed<opc, !strconcat(OpcodeStr, "ps"), OpNode, VR256,
2735                 v8f32, f256mem, memopv8f32, SSEPackedSingle, 0>, TB;
2736     defm PDY : sse12_fp_packed<opc, !strconcat(OpcodeStr, "pd"), OpNode, VR256,
2737                 v4f64, f256mem, memopv4f64, SSEPackedDouble, 0>, TB, OpSize;
2738   }
2739 }
2740
2741 multiclass basic_sse12_fp_binop_s_int<bits<8> opc, string OpcodeStr,
2742                                       bit Is2Addr = 1> {
2743   defm SS : sse12_fp_scalar_int<opc, OpcodeStr, VR128,
2744      !strconcat(OpcodeStr, "ss"), "", "_ss", ssmem, sse_load_f32, Is2Addr>, XS;
2745   defm SD : sse12_fp_scalar_int<opc, OpcodeStr, VR128,
2746      !strconcat(OpcodeStr, "sd"), "2", "_sd", sdmem, sse_load_f64, Is2Addr>, XD;
2747 }
2748
2749 multiclass basic_sse12_fp_binop_p_int<bits<8> opc, string OpcodeStr,
2750                                       bit Is2Addr = 1> {
2751   defm PS : sse12_fp_packed_int<opc, OpcodeStr, VR128,
2752      !strconcat(OpcodeStr, "ps"), "sse", "_ps", f128mem, memopv4f32,
2753                                               SSEPackedSingle, Is2Addr>, TB;
2754
2755   defm PD : sse12_fp_packed_int<opc, OpcodeStr, VR128,
2756      !strconcat(OpcodeStr, "pd"), "sse2", "_pd", f128mem, memopv2f64,
2757                                       SSEPackedDouble, Is2Addr>, TB, OpSize;
2758 }
2759
2760 multiclass basic_sse12_fp_binop_p_y_int<bits<8> opc, string OpcodeStr> {
2761   defm PSY : sse12_fp_packed_int<opc, OpcodeStr, VR256,
2762      !strconcat(OpcodeStr, "ps"), "avx", "_ps_256", f256mem, memopv8f32,
2763       SSEPackedSingle, 0>, TB;
2764
2765   defm PDY : sse12_fp_packed_int<opc, OpcodeStr, VR256,
2766      !strconcat(OpcodeStr, "pd"), "avx", "_pd_256", f256mem, memopv4f64,
2767       SSEPackedDouble, 0>, TB, OpSize;
2768 }
2769
2770 // Binary Arithmetic instructions
2771 defm VADD : basic_sse12_fp_binop_s<0x58, "add", fadd, 0>,
2772             basic_sse12_fp_binop_s_int<0x58, "add", 0>,
2773             basic_sse12_fp_binop_p<0x58, "add", fadd, 0>,
2774             basic_sse12_fp_binop_p_y<0x58, "add", fadd>, VEX_4V;
2775 defm VMUL : basic_sse12_fp_binop_s<0x59, "mul", fmul, 0>,
2776             basic_sse12_fp_binop_s_int<0x59, "mul", 0>,
2777             basic_sse12_fp_binop_p<0x59, "mul", fmul, 0>,
2778             basic_sse12_fp_binop_p_y<0x59, "mul", fmul>, VEX_4V;
2779
2780 let isCommutable = 0 in {
2781   defm VSUB : basic_sse12_fp_binop_s<0x5C, "sub", fsub, 0>,
2782               basic_sse12_fp_binop_s_int<0x5C, "sub", 0>,
2783               basic_sse12_fp_binop_p<0x5C, "sub", fsub, 0>,
2784               basic_sse12_fp_binop_p_y<0x5C, "sub", fsub>, VEX_4V;
2785   defm VDIV : basic_sse12_fp_binop_s<0x5E, "div", fdiv, 0>,
2786               basic_sse12_fp_binop_s_int<0x5E, "div", 0>,
2787               basic_sse12_fp_binop_p<0x5E, "div", fdiv, 0>,
2788               basic_sse12_fp_binop_p_y<0x5E, "div", fdiv>, VEX_4V;
2789   defm VMAX : basic_sse12_fp_binop_s<0x5F, "max", X86fmax, 0>,
2790               basic_sse12_fp_binop_s_int<0x5F, "max", 0>,
2791               basic_sse12_fp_binop_p<0x5F, "max", X86fmax, 0>,
2792               basic_sse12_fp_binop_p_int<0x5F, "max", 0>,
2793               basic_sse12_fp_binop_p_y<0x5F, "max", X86fmax>,
2794               basic_sse12_fp_binop_p_y_int<0x5F, "max">, VEX_4V;
2795   defm VMIN : basic_sse12_fp_binop_s<0x5D, "min", X86fmin, 0>,
2796               basic_sse12_fp_binop_s_int<0x5D, "min", 0>,
2797               basic_sse12_fp_binop_p<0x5D, "min", X86fmin, 0>,
2798               basic_sse12_fp_binop_p_int<0x5D, "min", 0>,
2799               basic_sse12_fp_binop_p_y_int<0x5D, "min">,
2800               basic_sse12_fp_binop_p_y<0x5D, "min", X86fmin>, VEX_4V;
2801 }
2802
2803 let Constraints = "$src1 = $dst" in {
2804   defm ADD : basic_sse12_fp_binop_s<0x58, "add", fadd>,
2805              basic_sse12_fp_binop_p<0x58, "add", fadd>,
2806              basic_sse12_fp_binop_s_int<0x58, "add">;
2807   defm MUL : basic_sse12_fp_binop_s<0x59, "mul", fmul>,
2808              basic_sse12_fp_binop_p<0x59, "mul", fmul>,
2809              basic_sse12_fp_binop_s_int<0x59, "mul">;
2810
2811   let isCommutable = 0 in {
2812     defm SUB : basic_sse12_fp_binop_s<0x5C, "sub", fsub>,
2813                basic_sse12_fp_binop_p<0x5C, "sub", fsub>,
2814                basic_sse12_fp_binop_s_int<0x5C, "sub">;
2815     defm DIV : basic_sse12_fp_binop_s<0x5E, "div", fdiv>,
2816                basic_sse12_fp_binop_p<0x5E, "div", fdiv>,
2817                basic_sse12_fp_binop_s_int<0x5E, "div">;
2818     defm MAX : basic_sse12_fp_binop_s<0x5F, "max", X86fmax>,
2819                basic_sse12_fp_binop_p<0x5F, "max", X86fmax>,
2820                basic_sse12_fp_binop_s_int<0x5F, "max">,
2821                basic_sse12_fp_binop_p_int<0x5F, "max">;
2822     defm MIN : basic_sse12_fp_binop_s<0x5D, "min", X86fmin>,
2823                basic_sse12_fp_binop_p<0x5D, "min", X86fmin>,
2824                basic_sse12_fp_binop_s_int<0x5D, "min">,
2825                basic_sse12_fp_binop_p_int<0x5D, "min">;
2826   }
2827 }
2828
2829 /// Unop Arithmetic
2830 /// In addition, we also have a special variant of the scalar form here to
2831 /// represent the associated intrinsic operation.  This form is unlike the
2832 /// plain scalar form, in that it takes an entire vector (instead of a
2833 /// scalar) and leaves the top elements undefined.
2834 ///
2835 /// And, we have a special variant form for a full-vector intrinsic form.
2836
2837 /// sse1_fp_unop_s - SSE1 unops in scalar form.
2838 multiclass sse1_fp_unop_s<bits<8> opc, string OpcodeStr,
2839                           SDNode OpNode, Intrinsic F32Int> {
2840   def SSr : SSI<opc, MRMSrcReg, (outs FR32:$dst), (ins FR32:$src),
2841                 !strconcat(OpcodeStr, "ss\t{$src, $dst|$dst, $src}"),
2842                 [(set FR32:$dst, (OpNode FR32:$src))]>;
2843   // For scalar unary operations, fold a load into the operation
2844   // only in OptForSize mode. It eliminates an instruction, but it also
2845   // eliminates a whole-register clobber (the load), so it introduces a
2846   // partial register update condition.
2847   def SSm : I<opc, MRMSrcMem, (outs FR32:$dst), (ins f32mem:$src),
2848                 !strconcat(OpcodeStr, "ss\t{$src, $dst|$dst, $src}"),
2849                 [(set FR32:$dst, (OpNode (load addr:$src)))]>, XS,
2850             Requires<[HasSSE1, OptForSize]>;
2851   def SSr_Int : SSI<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2852                     !strconcat(OpcodeStr, "ss\t{$src, $dst|$dst, $src}"),
2853                     [(set VR128:$dst, (F32Int VR128:$src))]>;
2854   def SSm_Int : SSI<opc, MRMSrcMem, (outs VR128:$dst), (ins ssmem:$src),
2855                     !strconcat(OpcodeStr, "ss\t{$src, $dst|$dst, $src}"),
2856                     [(set VR128:$dst, (F32Int sse_load_f32:$src))]>;
2857 }
2858
2859 /// sse1_fp_unop_s_avx - AVX SSE1 unops in scalar form.
2860 multiclass sse1_fp_unop_s_avx<bits<8> opc, string OpcodeStr> {
2861   def SSr : SSI<opc, MRMSrcReg, (outs FR32:$dst), (ins FR32:$src1, FR32:$src2),
2862                 !strconcat(OpcodeStr,
2863                            "ss\t{$src2, $src1, $dst|$dst, $src1, $src2}"), []>;
2864   let mayLoad = 1 in
2865   def SSm : SSI<opc, MRMSrcMem, (outs FR32:$dst), (ins FR32:$src1,f32mem:$src2),
2866                 !strconcat(OpcodeStr,
2867                            "ss\t{$src2, $src1, $dst|$dst, $src1, $src2}"), []>;
2868   def SSm_Int : SSI<opc, MRMSrcMem, (outs VR128:$dst),
2869                 (ins ssmem:$src1, VR128:$src2),
2870                 !strconcat(OpcodeStr,
2871                            "ss\t{$src2, $src1, $dst|$dst, $src1, $src2}"), []>;
2872 }
2873
2874 /// sse1_fp_unop_p - SSE1 unops in packed form.
2875 multiclass sse1_fp_unop_p<bits<8> opc, string OpcodeStr, SDNode OpNode> {
2876   def PSr : PSI<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2877               !strconcat(OpcodeStr, "ps\t{$src, $dst|$dst, $src}"),
2878               [(set VR128:$dst, (v4f32 (OpNode VR128:$src)))]>;
2879   def PSm : PSI<opc, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
2880                 !strconcat(OpcodeStr, "ps\t{$src, $dst|$dst, $src}"),
2881                 [(set VR128:$dst, (OpNode (memopv4f32 addr:$src)))]>;
2882 }
2883
2884 /// sse1_fp_unop_p_y - AVX 256-bit SSE1 unops in packed form.
2885 multiclass sse1_fp_unop_p_y<bits<8> opc, string OpcodeStr, SDNode OpNode> {
2886   def PSYr : PSI<opc, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
2887               !strconcat(OpcodeStr, "ps\t{$src, $dst|$dst, $src}"),
2888               [(set VR256:$dst, (v8f32 (OpNode VR256:$src)))]>;
2889   def PSYm : PSI<opc, MRMSrcMem, (outs VR256:$dst), (ins f256mem:$src),
2890                 !strconcat(OpcodeStr, "ps\t{$src, $dst|$dst, $src}"),
2891                 [(set VR256:$dst, (OpNode (memopv8f32 addr:$src)))]>;
2892 }
2893
2894 /// sse1_fp_unop_p_int - SSE1 intrinsics unops in packed forms.
2895 multiclass sse1_fp_unop_p_int<bits<8> opc, string OpcodeStr,
2896                               Intrinsic V4F32Int> {
2897   def PSr_Int : PSI<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2898                     !strconcat(OpcodeStr, "ps\t{$src, $dst|$dst, $src}"),
2899                     [(set VR128:$dst, (V4F32Int VR128:$src))]>;
2900   def PSm_Int : PSI<opc, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
2901                     !strconcat(OpcodeStr, "ps\t{$src, $dst|$dst, $src}"),
2902                     [(set VR128:$dst, (V4F32Int (memopv4f32 addr:$src)))]>;
2903 }
2904
2905 /// sse1_fp_unop_p_y_int - AVX 256-bit intrinsics unops in packed forms.
2906 multiclass sse1_fp_unop_p_y_int<bits<8> opc, string OpcodeStr,
2907                                 Intrinsic V4F32Int> {
2908   def PSYr_Int : PSI<opc, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
2909                     !strconcat(OpcodeStr, "ps\t{$src, $dst|$dst, $src}"),
2910                     [(set VR256:$dst, (V4F32Int VR256:$src))]>;
2911   def PSYm_Int : PSI<opc, MRMSrcMem, (outs VR256:$dst), (ins f256mem:$src),
2912                     !strconcat(OpcodeStr, "ps\t{$src, $dst|$dst, $src}"),
2913                     [(set VR256:$dst, (V4F32Int (memopv8f32 addr:$src)))]>;
2914 }
2915
2916 /// sse2_fp_unop_s - SSE2 unops in scalar form.
2917 multiclass sse2_fp_unop_s<bits<8> opc, string OpcodeStr,
2918                           SDNode OpNode, Intrinsic F64Int> {
2919   def SDr : SDI<opc, MRMSrcReg, (outs FR64:$dst), (ins FR64:$src),
2920                 !strconcat(OpcodeStr, "sd\t{$src, $dst|$dst, $src}"),
2921                 [(set FR64:$dst, (OpNode FR64:$src))]>;
2922   // See the comments in sse1_fp_unop_s for why this is OptForSize.
2923   def SDm : I<opc, MRMSrcMem, (outs FR64:$dst), (ins f64mem:$src),
2924                 !strconcat(OpcodeStr, "sd\t{$src, $dst|$dst, $src}"),
2925                 [(set FR64:$dst, (OpNode (load addr:$src)))]>, XD,
2926             Requires<[HasSSE2, OptForSize]>;
2927   def SDr_Int : SDI<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2928                     !strconcat(OpcodeStr, "sd\t{$src, $dst|$dst, $src}"),
2929                     [(set VR128:$dst, (F64Int VR128:$src))]>;
2930   def SDm_Int : SDI<opc, MRMSrcMem, (outs VR128:$dst), (ins sdmem:$src),
2931                     !strconcat(OpcodeStr, "sd\t{$src, $dst|$dst, $src}"),
2932                     [(set VR128:$dst, (F64Int sse_load_f64:$src))]>;
2933 }
2934
2935 /// sse2_fp_unop_s_avx - AVX SSE2 unops in scalar form.
2936 multiclass sse2_fp_unop_s_avx<bits<8> opc, string OpcodeStr> {
2937   def SDr : SDI<opc, MRMSrcReg, (outs FR64:$dst), (ins FR64:$src1, FR64:$src2),
2938                !strconcat(OpcodeStr,
2939                           "sd\t{$src2, $src1, $dst|$dst, $src1, $src2}"), []>;
2940   def SDm : SDI<opc, MRMSrcMem, (outs FR64:$dst), (ins FR64:$src1,f64mem:$src2),
2941                !strconcat(OpcodeStr,
2942                           "sd\t{$src2, $src1, $dst|$dst, $src1, $src2}"), []>;
2943   def SDm_Int : SDI<opc, MRMSrcMem, (outs VR128:$dst),
2944                (ins VR128:$src1, sdmem:$src2),
2945                !strconcat(OpcodeStr,
2946                           "sd\t{$src2, $src1, $dst|$dst, $src1, $src2}"), []>;
2947 }
2948
2949 /// sse2_fp_unop_p - SSE2 unops in vector forms.
2950 multiclass sse2_fp_unop_p<bits<8> opc, string OpcodeStr,
2951                           SDNode OpNode> {
2952   def PDr : PDI<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2953               !strconcat(OpcodeStr, "pd\t{$src, $dst|$dst, $src}"),
2954               [(set VR128:$dst, (v2f64 (OpNode VR128:$src)))]>;
2955   def PDm : PDI<opc, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
2956                 !strconcat(OpcodeStr, "pd\t{$src, $dst|$dst, $src}"),
2957                 [(set VR128:$dst, (OpNode (memopv2f64 addr:$src)))]>;
2958 }
2959
2960 /// sse2_fp_unop_p_y - AVX SSE2 256-bit unops in vector forms.
2961 multiclass sse2_fp_unop_p_y<bits<8> opc, string OpcodeStr, SDNode OpNode> {
2962   def PDYr : PDI<opc, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
2963               !strconcat(OpcodeStr, "pd\t{$src, $dst|$dst, $src}"),
2964               [(set VR256:$dst, (v4f64 (OpNode VR256:$src)))]>;
2965   def PDYm : PDI<opc, MRMSrcMem, (outs VR256:$dst), (ins f256mem:$src),
2966                 !strconcat(OpcodeStr, "pd\t{$src, $dst|$dst, $src}"),
2967                 [(set VR256:$dst, (OpNode (memopv4f64 addr:$src)))]>;
2968 }
2969
2970 /// sse2_fp_unop_p_int - SSE2 intrinsic unops in vector forms.
2971 multiclass sse2_fp_unop_p_int<bits<8> opc, string OpcodeStr,
2972                               Intrinsic V2F64Int> {
2973   def PDr_Int : PDI<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2974                     !strconcat(OpcodeStr, "pd\t{$src, $dst|$dst, $src}"),
2975                     [(set VR128:$dst, (V2F64Int VR128:$src))]>;
2976   def PDm_Int : PDI<opc, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
2977                     !strconcat(OpcodeStr, "pd\t{$src, $dst|$dst, $src}"),
2978                     [(set VR128:$dst, (V2F64Int (memopv2f64 addr:$src)))]>;
2979 }
2980
2981 /// sse2_fp_unop_p_y_int - AVX 256-bit intrinsic unops in vector forms.
2982 multiclass sse2_fp_unop_p_y_int<bits<8> opc, string OpcodeStr,
2983                                 Intrinsic V2F64Int> {
2984   def PDYr_Int : PDI<opc, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
2985                     !strconcat(OpcodeStr, "pd\t{$src, $dst|$dst, $src}"),
2986                     [(set VR256:$dst, (V2F64Int VR256:$src))]>;
2987   def PDYm_Int : PDI<opc, MRMSrcMem, (outs VR256:$dst), (ins f256mem:$src),
2988                     !strconcat(OpcodeStr, "pd\t{$src, $dst|$dst, $src}"),
2989                     [(set VR256:$dst, (V2F64Int (memopv4f64 addr:$src)))]>;
2990 }
2991
2992 let Predicates = [HasAVX] in {
2993   // Square root.
2994   defm VSQRT  : sse1_fp_unop_s_avx<0x51, "vsqrt">,
2995                 sse2_fp_unop_s_avx<0x51, "vsqrt">, VEX_4V;
2996
2997   defm VSQRT  : sse1_fp_unop_p<0x51, "vsqrt", fsqrt>,
2998                 sse2_fp_unop_p<0x51, "vsqrt", fsqrt>,
2999                 sse1_fp_unop_p_y<0x51, "vsqrt", fsqrt>,
3000                 sse2_fp_unop_p_y<0x51, "vsqrt", fsqrt>,
3001                 sse1_fp_unop_p_int<0x51, "vsqrt", int_x86_sse_sqrt_ps>,
3002                 sse2_fp_unop_p_int<0x51, "vsqrt", int_x86_sse2_sqrt_pd>,
3003                 sse1_fp_unop_p_y_int<0x51, "vsqrt", int_x86_avx_sqrt_ps_256>,
3004                 sse2_fp_unop_p_y_int<0x51, "vsqrt", int_x86_avx_sqrt_pd_256>,
3005                 VEX;
3006
3007   // Reciprocal approximations. Note that these typically require refinement
3008   // in order to obtain suitable precision.
3009   defm VRSQRT : sse1_fp_unop_s_avx<0x52, "vrsqrt">, VEX_4V;
3010   defm VRSQRT : sse1_fp_unop_p<0x52, "vrsqrt", X86frsqrt>,
3011                 sse1_fp_unop_p_y<0x52, "vrsqrt", X86frsqrt>,
3012                 sse1_fp_unop_p_y_int<0x52, "vrsqrt", int_x86_avx_rsqrt_ps_256>,
3013                 sse1_fp_unop_p_int<0x52, "vrsqrt", int_x86_sse_rsqrt_ps>, VEX;
3014
3015   defm VRCP   : sse1_fp_unop_s_avx<0x53, "vrcp">, VEX_4V;
3016   defm VRCP   : sse1_fp_unop_p<0x53, "vrcp", X86frcp>,
3017                 sse1_fp_unop_p_y<0x53, "vrcp", X86frcp>,
3018                 sse1_fp_unop_p_y_int<0x53, "vrcp", int_x86_avx_rcp_ps_256>,
3019                 sse1_fp_unop_p_int<0x53, "vrcp", int_x86_sse_rcp_ps>, VEX;
3020 }
3021
3022 def : Pat<(f32 (fsqrt FR32:$src)),
3023           (VSQRTSSr (f32 (IMPLICIT_DEF)), FR32:$src)>, Requires<[HasAVX]>;
3024 def : Pat<(f32 (fsqrt (load addr:$src))),
3025           (VSQRTSSm (f32 (IMPLICIT_DEF)), addr:$src)>,
3026           Requires<[HasAVX, OptForSize]>;
3027 def : Pat<(f64 (fsqrt FR64:$src)),
3028           (VSQRTSDr (f64 (IMPLICIT_DEF)), FR64:$src)>, Requires<[HasAVX]>;
3029 def : Pat<(f64 (fsqrt (load addr:$src))),
3030           (VSQRTSDm (f64 (IMPLICIT_DEF)), addr:$src)>,
3031           Requires<[HasAVX, OptForSize]>;
3032
3033 def : Pat<(f32 (X86frsqrt FR32:$src)),
3034           (VRSQRTSSr (f32 (IMPLICIT_DEF)), FR32:$src)>, Requires<[HasAVX]>;
3035 def : Pat<(f32 (X86frsqrt (load addr:$src))),
3036           (VRSQRTSSm (f32 (IMPLICIT_DEF)), addr:$src)>,
3037           Requires<[HasAVX, OptForSize]>;
3038
3039 def : Pat<(f32 (X86frcp FR32:$src)),
3040           (VRCPSSr (f32 (IMPLICIT_DEF)), FR32:$src)>, Requires<[HasAVX]>;
3041 def : Pat<(f32 (X86frcp (load addr:$src))),
3042           (VRCPSSm (f32 (IMPLICIT_DEF)), addr:$src)>,
3043           Requires<[HasAVX, OptForSize]>;
3044
3045 let Predicates = [HasAVX] in {
3046   def : Pat<(int_x86_sse_sqrt_ss VR128:$src),
3047             (INSERT_SUBREG (v4f32 (IMPLICIT_DEF)),
3048                 (VSQRTSSr (f32 (IMPLICIT_DEF)),
3049                           (EXTRACT_SUBREG (v4f32 VR128:$src), sub_ss)),
3050                 sub_ss)>;
3051   def : Pat<(int_x86_sse_sqrt_ss sse_load_f32:$src),
3052             (VSQRTSSm_Int (v4f32 (IMPLICIT_DEF)), sse_load_f32:$src)>;
3053
3054   def : Pat<(int_x86_sse2_sqrt_sd VR128:$src),
3055             (INSERT_SUBREG (v2f64 (IMPLICIT_DEF)),
3056                 (VSQRTSDr (f64 (IMPLICIT_DEF)),
3057                           (EXTRACT_SUBREG (v2f64 VR128:$src), sub_sd)),
3058                 sub_sd)>;
3059   def : Pat<(int_x86_sse2_sqrt_sd sse_load_f64:$src),
3060             (VSQRTSDm_Int (v2f64 (IMPLICIT_DEF)), sse_load_f64:$src)>;
3061
3062   def : Pat<(int_x86_sse_rsqrt_ss VR128:$src),
3063             (INSERT_SUBREG (v4f32 (IMPLICIT_DEF)),
3064                 (VRSQRTSSr (f32 (IMPLICIT_DEF)),
3065                           (EXTRACT_SUBREG (v4f32 VR128:$src), sub_ss)),
3066                 sub_ss)>;
3067   def : Pat<(int_x86_sse_rsqrt_ss sse_load_f32:$src),
3068             (VRSQRTSSm_Int (v4f32 (IMPLICIT_DEF)), sse_load_f32:$src)>;
3069
3070   def : Pat<(int_x86_sse_rcp_ss VR128:$src),
3071             (INSERT_SUBREG (v4f32 (IMPLICIT_DEF)),
3072                 (VRCPSSr (f32 (IMPLICIT_DEF)),
3073                          (EXTRACT_SUBREG (v4f32 VR128:$src), sub_ss)),
3074                 sub_ss)>;
3075   def : Pat<(int_x86_sse_rcp_ss sse_load_f32:$src),
3076             (VRCPSSm_Int (v4f32 (IMPLICIT_DEF)), sse_load_f32:$src)>;
3077 }
3078
3079 // Square root.
3080 defm SQRT  : sse1_fp_unop_s<0x51, "sqrt",  fsqrt, int_x86_sse_sqrt_ss>,
3081              sse1_fp_unop_p<0x51, "sqrt",  fsqrt>,
3082              sse1_fp_unop_p_int<0x51, "sqrt",  int_x86_sse_sqrt_ps>,
3083              sse2_fp_unop_s<0x51, "sqrt",  fsqrt, int_x86_sse2_sqrt_sd>,
3084              sse2_fp_unop_p<0x51, "sqrt",  fsqrt>,
3085              sse2_fp_unop_p_int<0x51, "sqrt", int_x86_sse2_sqrt_pd>;
3086
3087 // Reciprocal approximations. Note that these typically require refinement
3088 // in order to obtain suitable precision.
3089 defm RSQRT : sse1_fp_unop_s<0x52, "rsqrt", X86frsqrt, int_x86_sse_rsqrt_ss>,
3090              sse1_fp_unop_p<0x52, "rsqrt", X86frsqrt>,
3091              sse1_fp_unop_p_int<0x52, "rsqrt", int_x86_sse_rsqrt_ps>;
3092 defm RCP   : sse1_fp_unop_s<0x53, "rcp", X86frcp, int_x86_sse_rcp_ss>,
3093              sse1_fp_unop_p<0x53, "rcp", X86frcp>,
3094              sse1_fp_unop_p_int<0x53, "rcp", int_x86_sse_rcp_ps>;
3095
3096 // There is no f64 version of the reciprocal approximation instructions.
3097
3098 //===----------------------------------------------------------------------===//
3099 // SSE 1 & 2 - Non-temporal stores
3100 //===----------------------------------------------------------------------===//
3101
3102 let AddedComplexity = 400 in { // Prefer non-temporal versions
3103   def VMOVNTPSmr : VPSI<0x2B, MRMDestMem, (outs),
3104                        (ins f128mem:$dst, VR128:$src),
3105                        "movntps\t{$src, $dst|$dst, $src}",
3106                        [(alignednontemporalstore (v4f32 VR128:$src),
3107                                                  addr:$dst)]>, VEX;
3108   def VMOVNTPDmr : VPDI<0x2B, MRMDestMem, (outs),
3109                        (ins f128mem:$dst, VR128:$src),
3110                        "movntpd\t{$src, $dst|$dst, $src}",
3111                        [(alignednontemporalstore (v2f64 VR128:$src),
3112                                                  addr:$dst)]>, VEX;
3113   def VMOVNTDQ_64mr : VPDI<0xE7, MRMDestMem, (outs),
3114                         (ins f128mem:$dst, VR128:$src),
3115                         "movntdq\t{$src, $dst|$dst, $src}",
3116                         [(alignednontemporalstore (v2f64 VR128:$src),
3117                                                   addr:$dst)]>, VEX;
3118
3119   let ExeDomain = SSEPackedInt in
3120   def VMOVNTDQmr    : VPDI<0xE7, MRMDestMem, (outs),
3121                            (ins f128mem:$dst, VR128:$src),
3122                            "movntdq\t{$src, $dst|$dst, $src}",
3123                            [(alignednontemporalstore (v4f32 VR128:$src),
3124                                                      addr:$dst)]>, VEX;
3125
3126   def : Pat<(alignednontemporalstore (v2i64 VR128:$src), addr:$dst),
3127             (VMOVNTDQmr addr:$dst, VR128:$src)>, Requires<[HasAVX]>;
3128
3129   def VMOVNTPSYmr : VPSI<0x2B, MRMDestMem, (outs),
3130                        (ins f256mem:$dst, VR256:$src),
3131                        "movntps\t{$src, $dst|$dst, $src}",
3132                        [(alignednontemporalstore (v8f32 VR256:$src),
3133                                                  addr:$dst)]>, VEX;
3134   def VMOVNTPDYmr : VPDI<0x2B, MRMDestMem, (outs),
3135                        (ins f256mem:$dst, VR256:$src),
3136                        "movntpd\t{$src, $dst|$dst, $src}",
3137                        [(alignednontemporalstore (v4f64 VR256:$src),
3138                                                  addr:$dst)]>, VEX;
3139   def VMOVNTDQY_64mr : VPDI<0xE7, MRMDestMem, (outs),
3140                         (ins f256mem:$dst, VR256:$src),
3141                         "movntdq\t{$src, $dst|$dst, $src}",
3142                         [(alignednontemporalstore (v4f64 VR256:$src),
3143                                                   addr:$dst)]>, VEX;
3144   let ExeDomain = SSEPackedInt in
3145   def VMOVNTDQYmr : VPDI<0xE7, MRMDestMem, (outs),
3146                       (ins f256mem:$dst, VR256:$src),
3147                       "movntdq\t{$src, $dst|$dst, $src}",
3148                       [(alignednontemporalstore (v8f32 VR256:$src),
3149                                                 addr:$dst)]>, VEX;
3150 }
3151
3152 def : Pat<(int_x86_avx_movnt_dq_256 addr:$dst, VR256:$src),
3153           (VMOVNTDQYmr addr:$dst, VR256:$src)>;
3154 def : Pat<(int_x86_avx_movnt_pd_256 addr:$dst, VR256:$src),
3155           (VMOVNTPDYmr addr:$dst, VR256:$src)>;
3156 def : Pat<(int_x86_avx_movnt_ps_256 addr:$dst, VR256:$src),
3157           (VMOVNTPSYmr addr:$dst, VR256:$src)>;
3158
3159 let AddedComplexity = 400 in { // Prefer non-temporal versions
3160 def MOVNTPSmr : PSI<0x2B, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
3161                     "movntps\t{$src, $dst|$dst, $src}",
3162                     [(alignednontemporalstore (v4f32 VR128:$src), addr:$dst)]>;
3163 def MOVNTPDmr : PDI<0x2B, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
3164                     "movntpd\t{$src, $dst|$dst, $src}",
3165                     [(alignednontemporalstore(v2f64 VR128:$src), addr:$dst)]>;
3166
3167 def MOVNTDQ_64mr : PDI<0xE7, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
3168                     "movntdq\t{$src, $dst|$dst, $src}",
3169                     [(alignednontemporalstore (v2f64 VR128:$src), addr:$dst)]>;
3170
3171 let ExeDomain = SSEPackedInt in
3172 def MOVNTDQmr : PDI<0xE7, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
3173                     "movntdq\t{$src, $dst|$dst, $src}",
3174                     [(alignednontemporalstore (v4f32 VR128:$src), addr:$dst)]>;
3175
3176 def : Pat<(alignednontemporalstore (v2i64 VR128:$src), addr:$dst),
3177           (MOVNTDQmr addr:$dst, VR128:$src)>, Requires<[HasSSE2]>;
3178
3179 // There is no AVX form for instructions below this point
3180 def MOVNTImr : I<0xC3, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
3181                  "movnti{l}\t{$src, $dst|$dst, $src}",
3182                  [(nontemporalstore (i32 GR32:$src), addr:$dst)]>,
3183                TB, Requires<[HasSSE2]>;
3184 def MOVNTI_64mr : RI<0xC3, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
3185                      "movnti{q}\t{$src, $dst|$dst, $src}",
3186                      [(nontemporalstore (i64 GR64:$src), addr:$dst)]>,
3187                   TB, Requires<[HasSSE2]>;
3188 }
3189
3190 //===----------------------------------------------------------------------===//
3191 // SSE 1 & 2 - Prefetch and memory fence
3192 //===----------------------------------------------------------------------===//
3193
3194 // Prefetch intrinsic.
3195 def PREFETCHT0   : PSI<0x18, MRM1m, (outs), (ins i8mem:$src),
3196     "prefetcht0\t$src", [(prefetch addr:$src, imm, (i32 3), (i32 1))]>;
3197 def PREFETCHT1   : PSI<0x18, MRM2m, (outs), (ins i8mem:$src),
3198     "prefetcht1\t$src", [(prefetch addr:$src, imm, (i32 2), (i32 1))]>;
3199 def PREFETCHT2   : PSI<0x18, MRM3m, (outs), (ins i8mem:$src),
3200     "prefetcht2\t$src", [(prefetch addr:$src, imm, (i32 1), (i32 1))]>;
3201 def PREFETCHNTA  : PSI<0x18, MRM0m, (outs), (ins i8mem:$src),
3202     "prefetchnta\t$src", [(prefetch addr:$src, imm, (i32 0), (i32 1))]>;
3203
3204 // Flush cache
3205 def CLFLUSH : I<0xAE, MRM7m, (outs), (ins i8mem:$src),
3206                "clflush\t$src", [(int_x86_sse2_clflush addr:$src)]>,
3207               TB, Requires<[HasSSE2]>;
3208
3209 // Pause. This "instruction" is encoded as "rep; nop", so even though it
3210 // was introduced with SSE2, it's backward compatible.
3211 def PAUSE : I<0x90, RawFrm, (outs), (ins), "pause", []>, REP;
3212
3213 // Load, store, and memory fence
3214 def SFENCE : I<0xAE, MRM_F8, (outs), (ins),
3215                "sfence", [(int_x86_sse_sfence)]>, TB, Requires<[HasSSE1]>;
3216 def LFENCE : I<0xAE, MRM_E8, (outs), (ins),
3217                "lfence", [(int_x86_sse2_lfence)]>, TB, Requires<[HasSSE2]>;
3218 def MFENCE : I<0xAE, MRM_F0, (outs), (ins),
3219                "mfence", [(int_x86_sse2_mfence)]>, TB, Requires<[HasSSE2]>;
3220
3221 def : Pat<(X86SFence), (SFENCE)>;
3222 def : Pat<(X86LFence), (LFENCE)>;
3223 def : Pat<(X86MFence), (MFENCE)>;
3224
3225 //===----------------------------------------------------------------------===//
3226 // SSE 1 & 2 - Load/Store XCSR register
3227 //===----------------------------------------------------------------------===//
3228
3229 def VLDMXCSR : VPSI<0xAE, MRM2m, (outs), (ins i32mem:$src),
3230                   "ldmxcsr\t$src", [(int_x86_sse_ldmxcsr addr:$src)]>, VEX;
3231 def VSTMXCSR : VPSI<0xAE, MRM3m, (outs), (ins i32mem:$dst),
3232                   "stmxcsr\t$dst", [(int_x86_sse_stmxcsr addr:$dst)]>, VEX;
3233
3234 def LDMXCSR : PSI<0xAE, MRM2m, (outs), (ins i32mem:$src),
3235                   "ldmxcsr\t$src", [(int_x86_sse_ldmxcsr addr:$src)]>;
3236 def STMXCSR : PSI<0xAE, MRM3m, (outs), (ins i32mem:$dst),
3237                   "stmxcsr\t$dst", [(int_x86_sse_stmxcsr addr:$dst)]>;
3238
3239 //===---------------------------------------------------------------------===//
3240 // SSE2 - Move Aligned/Unaligned Packed Integer Instructions
3241 //===---------------------------------------------------------------------===//
3242
3243 let ExeDomain = SSEPackedInt in { // SSE integer instructions
3244
3245 let neverHasSideEffects = 1 in {
3246 def VMOVDQArr  : VPDI<0x6F, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3247                     "movdqa\t{$src, $dst|$dst, $src}", []>, VEX;
3248 def VMOVDQAYrr : VPDI<0x6F, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
3249                     "movdqa\t{$src, $dst|$dst, $src}", []>, VEX;
3250 }
3251 def VMOVDQUrr  : VSSI<0x6F, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3252                     "movdqu\t{$src, $dst|$dst, $src}", []>, VEX;
3253 def VMOVDQUYrr : VSSI<0x6F, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
3254                     "movdqu\t{$src, $dst|$dst, $src}", []>, VEX;
3255
3256 // For Disassembler
3257 let isCodeGenOnly = 1 in {
3258 def VMOVDQArr_REV  : VPDI<0x7F, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
3259                         "movdqa\t{$src, $dst|$dst, $src}", []>, VEX;
3260 def VMOVDQAYrr_REV : VPDI<0x7F, MRMDestReg, (outs VR256:$dst), (ins VR256:$src),
3261                         "movdqa\t{$src, $dst|$dst, $src}", []>, VEX;
3262 def VMOVDQUrr_REV  : VSSI<0x7F, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
3263                         "movdqu\t{$src, $dst|$dst, $src}", []>, VEX;
3264 def VMOVDQUYrr_REV : VSSI<0x7F, MRMDestReg, (outs VR256:$dst), (ins VR256:$src),
3265                         "movdqu\t{$src, $dst|$dst, $src}", []>, VEX;
3266 }
3267
3268 let canFoldAsLoad = 1, mayLoad = 1 in {
3269 def VMOVDQArm  : VPDI<0x6F, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
3270                    "movdqa\t{$src, $dst|$dst, $src}", []>, VEX;
3271 def VMOVDQAYrm : VPDI<0x6F, MRMSrcMem, (outs VR256:$dst), (ins i256mem:$src),
3272                    "movdqa\t{$src, $dst|$dst, $src}", []>, VEX;
3273 let Predicates = [HasAVX] in {
3274   def VMOVDQUrm  : I<0x6F, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
3275                     "vmovdqu\t{$src, $dst|$dst, $src}",[]>, XS, VEX;
3276   def VMOVDQUYrm : I<0x6F, MRMSrcMem, (outs VR256:$dst), (ins i256mem:$src),
3277                     "vmovdqu\t{$src, $dst|$dst, $src}",[]>, XS, VEX;
3278 }
3279 }
3280
3281 let mayStore = 1 in {
3282 def VMOVDQAmr  : VPDI<0x7F, MRMDestMem, (outs),
3283                      (ins i128mem:$dst, VR128:$src),
3284                      "movdqa\t{$src, $dst|$dst, $src}", []>, VEX;
3285 def VMOVDQAYmr : VPDI<0x7F, MRMDestMem, (outs),
3286                      (ins i256mem:$dst, VR256:$src),
3287                      "movdqa\t{$src, $dst|$dst, $src}", []>, VEX;
3288 let Predicates = [HasAVX] in {
3289 def VMOVDQUmr  : I<0x7F, MRMDestMem, (outs), (ins i128mem:$dst, VR128:$src),
3290                   "vmovdqu\t{$src, $dst|$dst, $src}",[]>, XS, VEX;
3291 def VMOVDQUYmr : I<0x7F, MRMDestMem, (outs), (ins i256mem:$dst, VR256:$src),
3292                   "vmovdqu\t{$src, $dst|$dst, $src}",[]>, XS, VEX;
3293 }
3294 }
3295
3296 let neverHasSideEffects = 1 in
3297 def MOVDQArr : PDI<0x6F, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3298                    "movdqa\t{$src, $dst|$dst, $src}", []>;
3299
3300 def MOVDQUrr :   I<0x6F, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3301                    "movdqu\t{$src, $dst|$dst, $src}",
3302                    []>, XS, Requires<[HasSSE2]>;
3303
3304 // For Disassembler
3305 let isCodeGenOnly = 1 in {
3306 def MOVDQArr_REV : PDI<0x7F, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
3307                        "movdqa\t{$src, $dst|$dst, $src}", []>;
3308
3309 def MOVDQUrr_REV :   I<0x7F, MRMDestReg, (outs VR128:$dst), (ins VR128:$src),
3310                        "movdqu\t{$src, $dst|$dst, $src}",
3311                        []>, XS, Requires<[HasSSE2]>;
3312 }
3313
3314 let canFoldAsLoad = 1, mayLoad = 1 in {
3315 def MOVDQArm : PDI<0x6F, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
3316                    "movdqa\t{$src, $dst|$dst, $src}",
3317                    [/*(set VR128:$dst, (alignedloadv2i64 addr:$src))*/]>;
3318 def MOVDQUrm :   I<0x6F, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
3319                    "movdqu\t{$src, $dst|$dst, $src}",
3320                    [/*(set VR128:$dst, (loadv2i64 addr:$src))*/]>,
3321                  XS, Requires<[HasSSE2]>;
3322 }
3323
3324 let mayStore = 1 in {
3325 def MOVDQAmr : PDI<0x7F, MRMDestMem, (outs), (ins i128mem:$dst, VR128:$src),
3326                    "movdqa\t{$src, $dst|$dst, $src}",
3327                    [/*(alignedstore (v2i64 VR128:$src), addr:$dst)*/]>;
3328 def MOVDQUmr :   I<0x7F, MRMDestMem, (outs), (ins i128mem:$dst, VR128:$src),
3329                    "movdqu\t{$src, $dst|$dst, $src}",
3330                    [/*(store (v2i64 VR128:$src), addr:$dst)*/]>,
3331                  XS, Requires<[HasSSE2]>;
3332 }
3333
3334 // Intrinsic forms of MOVDQU load and store
3335 def VMOVDQUmr_Int : I<0x7F, MRMDestMem, (outs), (ins i128mem:$dst, VR128:$src),
3336                        "vmovdqu\t{$src, $dst|$dst, $src}",
3337                        [(int_x86_sse2_storeu_dq addr:$dst, VR128:$src)]>,
3338                      XS, VEX, Requires<[HasAVX]>;
3339
3340 def MOVDQUmr_Int :   I<0x7F, MRMDestMem, (outs), (ins i128mem:$dst, VR128:$src),
3341                        "movdqu\t{$src, $dst|$dst, $src}",
3342                        [(int_x86_sse2_storeu_dq addr:$dst, VR128:$src)]>,
3343                      XS, Requires<[HasSSE2]>;
3344
3345 } // ExeDomain = SSEPackedInt
3346
3347 let Predicates = [HasAVX] in {
3348   def : Pat<(int_x86_avx_loadu_dq_256 addr:$src), (VMOVDQUYrm addr:$src)>;
3349   def : Pat<(int_x86_avx_storeu_dq_256 addr:$dst, VR256:$src),
3350             (VMOVDQUYmr addr:$dst, VR256:$src)>;
3351 }
3352
3353 //===---------------------------------------------------------------------===//
3354 // SSE2 - Packed Integer Arithmetic Instructions
3355 //===---------------------------------------------------------------------===//
3356
3357 let ExeDomain = SSEPackedInt in { // SSE integer instructions
3358
3359 multiclass PDI_binop_rm_int<bits<8> opc, string OpcodeStr, Intrinsic IntId,
3360                             bit IsCommutable = 0, bit Is2Addr = 1> {
3361   let isCommutable = IsCommutable in
3362   def rr : PDI<opc, MRMSrcReg, (outs VR128:$dst),
3363        (ins VR128:$src1, VR128:$src2),
3364        !if(Is2Addr,
3365            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
3366            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
3367        [(set VR128:$dst, (IntId VR128:$src1, VR128:$src2))]>;
3368   def rm : PDI<opc, MRMSrcMem, (outs VR128:$dst),
3369        (ins VR128:$src1, i128mem:$src2),
3370        !if(Is2Addr,
3371            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
3372            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
3373        [(set VR128:$dst, (IntId VR128:$src1,
3374                                 (bitconvert (memopv2i64 addr:$src2))))]>;
3375 }
3376
3377 multiclass PDI_binop_rmi_int<bits<8> opc, bits<8> opc2, Format ImmForm,
3378                              string OpcodeStr, Intrinsic IntId,
3379                              Intrinsic IntId2, bit Is2Addr = 1> {
3380   def rr : PDI<opc, MRMSrcReg, (outs VR128:$dst),
3381        (ins VR128:$src1, VR128:$src2),
3382        !if(Is2Addr,
3383            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
3384            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
3385        [(set VR128:$dst, (IntId VR128:$src1, VR128:$src2))]>;
3386   def rm : PDI<opc, MRMSrcMem, (outs VR128:$dst),
3387        (ins VR128:$src1, i128mem:$src2),
3388        !if(Is2Addr,
3389            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
3390            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
3391        [(set VR128:$dst, (IntId VR128:$src1,
3392                                       (bitconvert (memopv2i64 addr:$src2))))]>;
3393   def ri : PDIi8<opc2, ImmForm, (outs VR128:$dst),
3394        (ins VR128:$src1, i32i8imm:$src2),
3395        !if(Is2Addr,
3396            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
3397            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
3398        [(set VR128:$dst, (IntId2 VR128:$src1, (i32 imm:$src2)))]>;
3399 }
3400
3401 /// PDI_binop_rm - Simple SSE2 binary operator.
3402 multiclass PDI_binop_rm<bits<8> opc, string OpcodeStr, SDNode OpNode,
3403                         ValueType OpVT, bit IsCommutable = 0, bit Is2Addr = 1> {
3404   let isCommutable = IsCommutable in
3405   def rr : PDI<opc, MRMSrcReg, (outs VR128:$dst),
3406        (ins VR128:$src1, VR128:$src2),
3407        !if(Is2Addr,
3408            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
3409            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
3410        [(set VR128:$dst, (OpVT (OpNode VR128:$src1, VR128:$src2)))]>;
3411   def rm : PDI<opc, MRMSrcMem, (outs VR128:$dst),
3412        (ins VR128:$src1, i128mem:$src2),
3413        !if(Is2Addr,
3414            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
3415            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
3416        [(set VR128:$dst, (OpVT (OpNode VR128:$src1,
3417                                      (bitconvert (memopv2i64 addr:$src2)))))]>;
3418 }
3419
3420 /// PDI_binop_rm_v2i64 - Simple SSE2 binary operator whose type is v2i64.
3421 ///
3422 /// FIXME: we could eliminate this and use PDI_binop_rm instead if tblgen knew
3423 /// to collapse (bitconvert VT to VT) into its operand.
3424 ///
3425 multiclass PDI_binop_rm_v2i64<bits<8> opc, string OpcodeStr, SDNode OpNode,
3426                               bit IsCommutable = 0, bit Is2Addr = 1> {
3427   let isCommutable = IsCommutable in
3428   def rr : PDI<opc, MRMSrcReg, (outs VR128:$dst),
3429        (ins VR128:$src1, VR128:$src2),
3430        !if(Is2Addr,
3431            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
3432            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
3433        [(set VR128:$dst, (v2i64 (OpNode VR128:$src1, VR128:$src2)))]>;
3434   def rm : PDI<opc, MRMSrcMem, (outs VR128:$dst),
3435        (ins VR128:$src1, i128mem:$src2),
3436        !if(Is2Addr,
3437            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
3438            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
3439        [(set VR128:$dst, (OpNode VR128:$src1, (memopv2i64 addr:$src2)))]>;
3440 }
3441
3442 } // ExeDomain = SSEPackedInt
3443
3444 // 128-bit Integer Arithmetic
3445
3446 let Predicates = [HasAVX] in {
3447 defm VPADDB  : PDI_binop_rm<0xFC, "vpaddb", add, v16i8, 1, 0 /*3addr*/>, VEX_4V;
3448 defm VPADDW  : PDI_binop_rm<0xFD, "vpaddw", add, v8i16, 1, 0>, VEX_4V;
3449 defm VPADDD  : PDI_binop_rm<0xFE, "vpaddd", add, v4i32, 1, 0>, VEX_4V;
3450 defm VPADDQ  : PDI_binop_rm_v2i64<0xD4, "vpaddq", add, 1, 0>, VEX_4V;
3451 defm VPMULLW : PDI_binop_rm<0xD5, "vpmullw", mul, v8i16, 1, 0>, VEX_4V;
3452 defm VPSUBB : PDI_binop_rm<0xF8, "vpsubb", sub, v16i8, 0, 0>, VEX_4V;
3453 defm VPSUBW : PDI_binop_rm<0xF9, "vpsubw", sub, v8i16, 0, 0>, VEX_4V;
3454 defm VPSUBD : PDI_binop_rm<0xFA, "vpsubd", sub, v4i32, 0, 0>, VEX_4V;
3455 defm VPSUBQ : PDI_binop_rm_v2i64<0xFB, "vpsubq", sub, 0, 0>, VEX_4V;
3456
3457 // Intrinsic forms
3458 defm VPSUBSB  : PDI_binop_rm_int<0xE8, "vpsubsb" , int_x86_sse2_psubs_b, 0, 0>,
3459                                  VEX_4V;
3460 defm VPSUBSW  : PDI_binop_rm_int<0xE9, "vpsubsw" , int_x86_sse2_psubs_w, 0, 0>,
3461                                  VEX_4V;
3462 defm VPSUBUSB : PDI_binop_rm_int<0xD8, "vpsubusb", int_x86_sse2_psubus_b, 0, 0>,
3463                                  VEX_4V;
3464 defm VPSUBUSW : PDI_binop_rm_int<0xD9, "vpsubusw", int_x86_sse2_psubus_w, 0, 0>,
3465                                  VEX_4V;
3466 defm VPADDSB  : PDI_binop_rm_int<0xEC, "vpaddsb" , int_x86_sse2_padds_b, 1, 0>,
3467                                  VEX_4V;
3468 defm VPADDSW  : PDI_binop_rm_int<0xED, "vpaddsw" , int_x86_sse2_padds_w, 1, 0>,
3469                                  VEX_4V;
3470 defm VPADDUSB : PDI_binop_rm_int<0xDC, "vpaddusb", int_x86_sse2_paddus_b, 1, 0>,
3471                                  VEX_4V;
3472 defm VPADDUSW : PDI_binop_rm_int<0xDD, "vpaddusw", int_x86_sse2_paddus_w, 1, 0>,
3473                                  VEX_4V;
3474 defm VPMULHUW : PDI_binop_rm_int<0xE4, "vpmulhuw", int_x86_sse2_pmulhu_w, 1, 0>,
3475                                  VEX_4V;
3476 defm VPMULHW  : PDI_binop_rm_int<0xE5, "vpmulhw" , int_x86_sse2_pmulh_w, 1, 0>,
3477                                  VEX_4V;
3478 defm VPMULUDQ : PDI_binop_rm_int<0xF4, "vpmuludq", int_x86_sse2_pmulu_dq, 1, 0>,
3479                                  VEX_4V;
3480 defm VPMADDWD : PDI_binop_rm_int<0xF5, "vpmaddwd", int_x86_sse2_pmadd_wd, 1, 0>,
3481                                  VEX_4V;
3482 defm VPAVGB   : PDI_binop_rm_int<0xE0, "vpavgb", int_x86_sse2_pavg_b, 1, 0>,
3483                                  VEX_4V;
3484 defm VPAVGW   : PDI_binop_rm_int<0xE3, "vpavgw", int_x86_sse2_pavg_w, 1, 0>,
3485                                  VEX_4V;
3486 defm VPMINUB  : PDI_binop_rm_int<0xDA, "vpminub", int_x86_sse2_pminu_b, 1, 0>,
3487                                  VEX_4V;
3488 defm VPMINSW  : PDI_binop_rm_int<0xEA, "vpminsw", int_x86_sse2_pmins_w, 1, 0>,
3489                                  VEX_4V;
3490 defm VPMAXUB  : PDI_binop_rm_int<0xDE, "vpmaxub", int_x86_sse2_pmaxu_b, 1, 0>,
3491                                  VEX_4V;
3492 defm VPMAXSW  : PDI_binop_rm_int<0xEE, "vpmaxsw", int_x86_sse2_pmaxs_w, 1, 0>,
3493                                  VEX_4V;
3494 defm VPSADBW  : PDI_binop_rm_int<0xF6, "vpsadbw", int_x86_sse2_psad_bw, 1, 0>,
3495                                  VEX_4V;
3496 }
3497
3498 let Constraints = "$src1 = $dst" in {
3499 defm PADDB  : PDI_binop_rm<0xFC, "paddb", add, v16i8, 1>;
3500 defm PADDW  : PDI_binop_rm<0xFD, "paddw", add, v8i16, 1>;
3501 defm PADDD  : PDI_binop_rm<0xFE, "paddd", add, v4i32, 1>;
3502 defm PADDQ  : PDI_binop_rm_v2i64<0xD4, "paddq", add, 1>;
3503 defm PMULLW : PDI_binop_rm<0xD5, "pmullw", mul, v8i16, 1>;
3504 defm PSUBB : PDI_binop_rm<0xF8, "psubb", sub, v16i8>;
3505 defm PSUBW : PDI_binop_rm<0xF9, "psubw", sub, v8i16>;
3506 defm PSUBD : PDI_binop_rm<0xFA, "psubd", sub, v4i32>;
3507 defm PSUBQ : PDI_binop_rm_v2i64<0xFB, "psubq", sub>;
3508
3509 // Intrinsic forms
3510 defm PSUBSB  : PDI_binop_rm_int<0xE8, "psubsb" , int_x86_sse2_psubs_b>;
3511 defm PSUBSW  : PDI_binop_rm_int<0xE9, "psubsw" , int_x86_sse2_psubs_w>;
3512 defm PSUBUSB : PDI_binop_rm_int<0xD8, "psubusb", int_x86_sse2_psubus_b>;
3513 defm PSUBUSW : PDI_binop_rm_int<0xD9, "psubusw", int_x86_sse2_psubus_w>;
3514 defm PADDSB  : PDI_binop_rm_int<0xEC, "paddsb" , int_x86_sse2_padds_b, 1>;
3515 defm PADDSW  : PDI_binop_rm_int<0xED, "paddsw" , int_x86_sse2_padds_w, 1>;
3516 defm PADDUSB : PDI_binop_rm_int<0xDC, "paddusb", int_x86_sse2_paddus_b, 1>;
3517 defm PADDUSW : PDI_binop_rm_int<0xDD, "paddusw", int_x86_sse2_paddus_w, 1>;
3518 defm PMULHUW : PDI_binop_rm_int<0xE4, "pmulhuw", int_x86_sse2_pmulhu_w, 1>;
3519 defm PMULHW  : PDI_binop_rm_int<0xE5, "pmulhw" , int_x86_sse2_pmulh_w, 1>;
3520 defm PMULUDQ : PDI_binop_rm_int<0xF4, "pmuludq", int_x86_sse2_pmulu_dq, 1>;
3521 defm PMADDWD : PDI_binop_rm_int<0xF5, "pmaddwd", int_x86_sse2_pmadd_wd, 1>;
3522 defm PAVGB   : PDI_binop_rm_int<0xE0, "pavgb", int_x86_sse2_pavg_b, 1>;
3523 defm PAVGW   : PDI_binop_rm_int<0xE3, "pavgw", int_x86_sse2_pavg_w, 1>;
3524 defm PMINUB  : PDI_binop_rm_int<0xDA, "pminub", int_x86_sse2_pminu_b, 1>;
3525 defm PMINSW  : PDI_binop_rm_int<0xEA, "pminsw", int_x86_sse2_pmins_w, 1>;
3526 defm PMAXUB  : PDI_binop_rm_int<0xDE, "pmaxub", int_x86_sse2_pmaxu_b, 1>;
3527 defm PMAXSW  : PDI_binop_rm_int<0xEE, "pmaxsw", int_x86_sse2_pmaxs_w, 1>;
3528 defm PSADBW  : PDI_binop_rm_int<0xF6, "psadbw", int_x86_sse2_psad_bw, 1>;
3529
3530 } // Constraints = "$src1 = $dst"
3531
3532 //===---------------------------------------------------------------------===//
3533 // SSE2 - Packed Integer Logical Instructions
3534 //===---------------------------------------------------------------------===//
3535
3536 let Predicates = [HasAVX] in {
3537 defm VPSLLW : PDI_binop_rmi_int<0xF1, 0x71, MRM6r, "vpsllw",
3538                                 int_x86_sse2_psll_w, int_x86_sse2_pslli_w, 0>,
3539                                 VEX_4V;
3540 defm VPSLLD : PDI_binop_rmi_int<0xF2, 0x72, MRM6r, "vpslld",
3541                                 int_x86_sse2_psll_d, int_x86_sse2_pslli_d, 0>,
3542                                 VEX_4V;
3543 defm VPSLLQ : PDI_binop_rmi_int<0xF3, 0x73, MRM6r, "vpsllq",
3544                                 int_x86_sse2_psll_q, int_x86_sse2_pslli_q, 0>,
3545                                 VEX_4V;
3546
3547 defm VPSRLW : PDI_binop_rmi_int<0xD1, 0x71, MRM2r, "vpsrlw",
3548                                 int_x86_sse2_psrl_w, int_x86_sse2_psrli_w, 0>,
3549                                 VEX_4V;
3550 defm VPSRLD : PDI_binop_rmi_int<0xD2, 0x72, MRM2r, "vpsrld",
3551                                 int_x86_sse2_psrl_d, int_x86_sse2_psrli_d, 0>,
3552                                 VEX_4V;
3553 defm VPSRLQ : PDI_binop_rmi_int<0xD3, 0x73, MRM2r, "vpsrlq",
3554                                 int_x86_sse2_psrl_q, int_x86_sse2_psrli_q, 0>,
3555                                 VEX_4V;
3556
3557 defm VPSRAW : PDI_binop_rmi_int<0xE1, 0x71, MRM4r, "vpsraw",
3558                                 int_x86_sse2_psra_w, int_x86_sse2_psrai_w, 0>,
3559                                 VEX_4V;
3560 defm VPSRAD : PDI_binop_rmi_int<0xE2, 0x72, MRM4r, "vpsrad",
3561                                 int_x86_sse2_psra_d, int_x86_sse2_psrai_d, 0>,
3562                                 VEX_4V;
3563
3564 defm VPAND : PDI_binop_rm_v2i64<0xDB, "vpand", and, 1, 0>, VEX_4V;
3565 defm VPOR  : PDI_binop_rm_v2i64<0xEB, "vpor" , or, 1, 0>, VEX_4V;
3566 defm VPXOR : PDI_binop_rm_v2i64<0xEF, "vpxor", xor, 1, 0>, VEX_4V;
3567
3568 let ExeDomain = SSEPackedInt in {
3569   let neverHasSideEffects = 1 in {
3570     // 128-bit logical shifts.
3571     def VPSLLDQri : PDIi8<0x73, MRM7r,
3572                       (outs VR128:$dst), (ins VR128:$src1, i32i8imm:$src2),
3573                       "vpslldq\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>,
3574                       VEX_4V;
3575     def VPSRLDQri : PDIi8<0x73, MRM3r,
3576                       (outs VR128:$dst), (ins VR128:$src1, i32i8imm:$src2),
3577                       "vpsrldq\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>,
3578                       VEX_4V;
3579     // PSRADQri doesn't exist in SSE[1-3].
3580   }
3581   def VPANDNrr : PDI<0xDF, MRMSrcReg,
3582                     (outs VR128:$dst), (ins VR128:$src1, VR128:$src2),
3583                     "vpandn\t{$src2, $src1, $dst|$dst, $src1, $src2}",
3584                     [(set VR128:$dst,
3585                           (v2i64 (X86andnp VR128:$src1, VR128:$src2)))]>,VEX_4V;
3586
3587   def VPANDNrm : PDI<0xDF, MRMSrcMem,
3588                     (outs VR128:$dst), (ins VR128:$src1, i128mem:$src2),
3589                     "vpandn\t{$src2, $src1, $dst|$dst, $src1, $src2}",
3590                     [(set VR128:$dst, (X86andnp VR128:$src1,
3591                                             (memopv2i64 addr:$src2)))]>, VEX_4V;
3592 }
3593 }
3594
3595 let Constraints = "$src1 = $dst" in {
3596 defm PSLLW : PDI_binop_rmi_int<0xF1, 0x71, MRM6r, "psllw",
3597                                int_x86_sse2_psll_w, int_x86_sse2_pslli_w>;
3598 defm PSLLD : PDI_binop_rmi_int<0xF2, 0x72, MRM6r, "pslld",
3599                                int_x86_sse2_psll_d, int_x86_sse2_pslli_d>;
3600 defm PSLLQ : PDI_binop_rmi_int<0xF3, 0x73, MRM6r, "psllq",
3601                                int_x86_sse2_psll_q, int_x86_sse2_pslli_q>;
3602
3603 defm PSRLW : PDI_binop_rmi_int<0xD1, 0x71, MRM2r, "psrlw",
3604                                int_x86_sse2_psrl_w, int_x86_sse2_psrli_w>;
3605 defm PSRLD : PDI_binop_rmi_int<0xD2, 0x72, MRM2r, "psrld",
3606                                int_x86_sse2_psrl_d, int_x86_sse2_psrli_d>;
3607 defm PSRLQ : PDI_binop_rmi_int<0xD3, 0x73, MRM2r, "psrlq",
3608                                int_x86_sse2_psrl_q, int_x86_sse2_psrli_q>;
3609
3610 defm PSRAW : PDI_binop_rmi_int<0xE1, 0x71, MRM4r, "psraw",
3611                                int_x86_sse2_psra_w, int_x86_sse2_psrai_w>;
3612 defm PSRAD : PDI_binop_rmi_int<0xE2, 0x72, MRM4r, "psrad",
3613                                int_x86_sse2_psra_d, int_x86_sse2_psrai_d>;
3614
3615 defm PAND : PDI_binop_rm_v2i64<0xDB, "pand", and, 1>;
3616 defm POR  : PDI_binop_rm_v2i64<0xEB, "por" , or, 1>;
3617 defm PXOR : PDI_binop_rm_v2i64<0xEF, "pxor", xor, 1>;
3618
3619 let ExeDomain = SSEPackedInt in {
3620   let neverHasSideEffects = 1 in {
3621     // 128-bit logical shifts.
3622     def PSLLDQri : PDIi8<0x73, MRM7r,
3623                          (outs VR128:$dst), (ins VR128:$src1, i32i8imm:$src2),
3624                          "pslldq\t{$src2, $dst|$dst, $src2}", []>;
3625     def PSRLDQri : PDIi8<0x73, MRM3r,
3626                          (outs VR128:$dst), (ins VR128:$src1, i32i8imm:$src2),
3627                          "psrldq\t{$src2, $dst|$dst, $src2}", []>;
3628     // PSRADQri doesn't exist in SSE[1-3].
3629   }
3630   def PANDNrr : PDI<0xDF, MRMSrcReg,
3631                     (outs VR128:$dst), (ins VR128:$src1, VR128:$src2),
3632                     "pandn\t{$src2, $dst|$dst, $src2}", []>;
3633
3634   def PANDNrm : PDI<0xDF, MRMSrcMem,
3635                     (outs VR128:$dst), (ins VR128:$src1, i128mem:$src2),
3636                     "pandn\t{$src2, $dst|$dst, $src2}", []>;
3637 }
3638 } // Constraints = "$src1 = $dst"
3639
3640 let Predicates = [HasAVX] in {
3641   def : Pat<(int_x86_sse2_psll_dq VR128:$src1, imm:$src2),
3642             (v2i64 (VPSLLDQri VR128:$src1, (BYTE_imm imm:$src2)))>;
3643   def : Pat<(int_x86_sse2_psrl_dq VR128:$src1, imm:$src2),
3644             (v2i64 (VPSRLDQri VR128:$src1, (BYTE_imm imm:$src2)))>;
3645   def : Pat<(int_x86_sse2_psll_dq_bs VR128:$src1, imm:$src2),
3646             (v2i64 (VPSLLDQri VR128:$src1, imm:$src2))>;
3647   def : Pat<(int_x86_sse2_psrl_dq_bs VR128:$src1, imm:$src2),
3648             (v2i64 (VPSRLDQri VR128:$src1, imm:$src2))>;
3649   def : Pat<(v2f64 (X86fsrl VR128:$src1, i32immSExt8:$src2)),
3650             (v2f64 (VPSRLDQri VR128:$src1, (BYTE_imm imm:$src2)))>;
3651
3652   // Shift up / down and insert zero's.
3653   def : Pat<(v2i64 (X86vshl  VR128:$src, (i8 imm:$amt))),
3654             (v2i64 (VPSLLDQri VR128:$src, (BYTE_imm imm:$amt)))>;
3655   def : Pat<(v2i64 (X86vshr  VR128:$src, (i8 imm:$amt))),
3656             (v2i64 (VPSRLDQri VR128:$src, (BYTE_imm imm:$amt)))>;
3657 }
3658
3659 let Predicates = [HasSSE2] in {
3660   def : Pat<(int_x86_sse2_psll_dq VR128:$src1, imm:$src2),
3661             (v2i64 (PSLLDQri VR128:$src1, (BYTE_imm imm:$src2)))>;
3662   def : Pat<(int_x86_sse2_psrl_dq VR128:$src1, imm:$src2),
3663             (v2i64 (PSRLDQri VR128:$src1, (BYTE_imm imm:$src2)))>;
3664   def : Pat<(int_x86_sse2_psll_dq_bs VR128:$src1, imm:$src2),
3665             (v2i64 (PSLLDQri VR128:$src1, imm:$src2))>;
3666   def : Pat<(int_x86_sse2_psrl_dq_bs VR128:$src1, imm:$src2),
3667             (v2i64 (PSRLDQri VR128:$src1, imm:$src2))>;
3668   def : Pat<(v2f64 (X86fsrl VR128:$src1, i32immSExt8:$src2)),
3669             (v2f64 (PSRLDQri VR128:$src1, (BYTE_imm imm:$src2)))>;
3670
3671   // Shift up / down and insert zero's.
3672   def : Pat<(v2i64 (X86vshl  VR128:$src, (i8 imm:$amt))),
3673             (v2i64 (PSLLDQri VR128:$src, (BYTE_imm imm:$amt)))>;
3674   def : Pat<(v2i64 (X86vshr  VR128:$src, (i8 imm:$amt))),
3675             (v2i64 (PSRLDQri VR128:$src, (BYTE_imm imm:$amt)))>;
3676 }
3677
3678 //===---------------------------------------------------------------------===//
3679 // SSE2 - Packed Integer Comparison Instructions
3680 //===---------------------------------------------------------------------===//
3681
3682 let Predicates = [HasAVX] in {
3683   defm VPCMPEQB  : PDI_binop_rm_int<0x74, "vpcmpeqb", int_x86_sse2_pcmpeq_b, 1,
3684                                     0>, VEX_4V;
3685   defm VPCMPEQW  : PDI_binop_rm_int<0x75, "vpcmpeqw", int_x86_sse2_pcmpeq_w, 1,
3686                                     0>, VEX_4V;
3687   defm VPCMPEQD  : PDI_binop_rm_int<0x76, "vpcmpeqd", int_x86_sse2_pcmpeq_d, 1,
3688                                     0>, VEX_4V;
3689   defm VPCMPGTB  : PDI_binop_rm_int<0x64, "vpcmpgtb", int_x86_sse2_pcmpgt_b, 0,
3690                                     0>, VEX_4V;
3691   defm VPCMPGTW  : PDI_binop_rm_int<0x65, "vpcmpgtw", int_x86_sse2_pcmpgt_w, 0,
3692                                     0>, VEX_4V;
3693   defm VPCMPGTD  : PDI_binop_rm_int<0x66, "vpcmpgtd", int_x86_sse2_pcmpgt_d, 0,
3694                                     0>, VEX_4V;
3695
3696   def : Pat<(v16i8 (X86pcmpeqb VR128:$src1, VR128:$src2)),
3697             (VPCMPEQBrr VR128:$src1, VR128:$src2)>;
3698   def : Pat<(v16i8 (X86pcmpeqb VR128:$src1, (memop addr:$src2))),
3699             (VPCMPEQBrm VR128:$src1, addr:$src2)>;
3700   def : Pat<(v8i16 (X86pcmpeqw VR128:$src1, VR128:$src2)),
3701             (VPCMPEQWrr VR128:$src1, VR128:$src2)>;
3702   def : Pat<(v8i16 (X86pcmpeqw VR128:$src1, (memop addr:$src2))),
3703             (VPCMPEQWrm VR128:$src1, addr:$src2)>;
3704   def : Pat<(v4i32 (X86pcmpeqd VR128:$src1, VR128:$src2)),
3705             (VPCMPEQDrr VR128:$src1, VR128:$src2)>;
3706   def : Pat<(v4i32 (X86pcmpeqd VR128:$src1, (memop addr:$src2))),
3707             (VPCMPEQDrm VR128:$src1, addr:$src2)>;
3708
3709   def : Pat<(v16i8 (X86pcmpgtb VR128:$src1, VR128:$src2)),
3710             (VPCMPGTBrr VR128:$src1, VR128:$src2)>;
3711   def : Pat<(v16i8 (X86pcmpgtb VR128:$src1, (memop addr:$src2))),
3712             (VPCMPGTBrm VR128:$src1, addr:$src2)>;
3713   def : Pat<(v8i16 (X86pcmpgtw VR128:$src1, VR128:$src2)),
3714             (VPCMPGTWrr VR128:$src1, VR128:$src2)>;
3715   def : Pat<(v8i16 (X86pcmpgtw VR128:$src1, (memop addr:$src2))),
3716             (VPCMPGTWrm VR128:$src1, addr:$src2)>;
3717   def : Pat<(v4i32 (X86pcmpgtd VR128:$src1, VR128:$src2)),
3718             (VPCMPGTDrr VR128:$src1, VR128:$src2)>;
3719   def : Pat<(v4i32 (X86pcmpgtd VR128:$src1, (memop addr:$src2))),
3720             (VPCMPGTDrm VR128:$src1, addr:$src2)>;
3721 }
3722
3723 let Constraints = "$src1 = $dst" in {
3724   defm PCMPEQB  : PDI_binop_rm_int<0x74, "pcmpeqb", int_x86_sse2_pcmpeq_b, 1>;
3725   defm PCMPEQW  : PDI_binop_rm_int<0x75, "pcmpeqw", int_x86_sse2_pcmpeq_w, 1>;
3726   defm PCMPEQD  : PDI_binop_rm_int<0x76, "pcmpeqd", int_x86_sse2_pcmpeq_d, 1>;
3727   defm PCMPGTB  : PDI_binop_rm_int<0x64, "pcmpgtb", int_x86_sse2_pcmpgt_b>;
3728   defm PCMPGTW  : PDI_binop_rm_int<0x65, "pcmpgtw", int_x86_sse2_pcmpgt_w>;
3729   defm PCMPGTD  : PDI_binop_rm_int<0x66, "pcmpgtd", int_x86_sse2_pcmpgt_d>;
3730 } // Constraints = "$src1 = $dst"
3731
3732 let Predicates = [HasSSE2] in {
3733   def : Pat<(v16i8 (X86pcmpeqb VR128:$src1, VR128:$src2)),
3734             (PCMPEQBrr VR128:$src1, VR128:$src2)>;
3735   def : Pat<(v16i8 (X86pcmpeqb VR128:$src1, (memop addr:$src2))),
3736             (PCMPEQBrm VR128:$src1, addr:$src2)>;
3737   def : Pat<(v8i16 (X86pcmpeqw VR128:$src1, VR128:$src2)),
3738             (PCMPEQWrr VR128:$src1, VR128:$src2)>;
3739   def : Pat<(v8i16 (X86pcmpeqw VR128:$src1, (memop addr:$src2))),
3740             (PCMPEQWrm VR128:$src1, addr:$src2)>;
3741   def : Pat<(v4i32 (X86pcmpeqd VR128:$src1, VR128:$src2)),
3742             (PCMPEQDrr VR128:$src1, VR128:$src2)>;
3743   def : Pat<(v4i32 (X86pcmpeqd VR128:$src1, (memop addr:$src2))),
3744             (PCMPEQDrm VR128:$src1, addr:$src2)>;
3745
3746   def : Pat<(v16i8 (X86pcmpgtb VR128:$src1, VR128:$src2)),
3747             (PCMPGTBrr VR128:$src1, VR128:$src2)>;
3748   def : Pat<(v16i8 (X86pcmpgtb VR128:$src1, (memop addr:$src2))),
3749             (PCMPGTBrm VR128:$src1, addr:$src2)>;
3750   def : Pat<(v8i16 (X86pcmpgtw VR128:$src1, VR128:$src2)),
3751             (PCMPGTWrr VR128:$src1, VR128:$src2)>;
3752   def : Pat<(v8i16 (X86pcmpgtw VR128:$src1, (memop addr:$src2))),
3753             (PCMPGTWrm VR128:$src1, addr:$src2)>;
3754   def : Pat<(v4i32 (X86pcmpgtd VR128:$src1, VR128:$src2)),
3755             (PCMPGTDrr VR128:$src1, VR128:$src2)>;
3756   def : Pat<(v4i32 (X86pcmpgtd VR128:$src1, (memop addr:$src2))),
3757             (PCMPGTDrm VR128:$src1, addr:$src2)>;
3758 }
3759
3760 //===---------------------------------------------------------------------===//
3761 // SSE2 - Packed Integer Pack Instructions
3762 //===---------------------------------------------------------------------===//
3763
3764 let Predicates = [HasAVX] in {
3765 defm VPACKSSWB : PDI_binop_rm_int<0x63, "vpacksswb", int_x86_sse2_packsswb_128,
3766                                   0, 0>, VEX_4V;
3767 defm VPACKSSDW : PDI_binop_rm_int<0x6B, "vpackssdw", int_x86_sse2_packssdw_128,
3768                                   0, 0>, VEX_4V;
3769 defm VPACKUSWB : PDI_binop_rm_int<0x67, "vpackuswb", int_x86_sse2_packuswb_128,
3770                                   0, 0>, VEX_4V;
3771 }
3772
3773 let Constraints = "$src1 = $dst" in {
3774 defm PACKSSWB : PDI_binop_rm_int<0x63, "packsswb", int_x86_sse2_packsswb_128>;
3775 defm PACKSSDW : PDI_binop_rm_int<0x6B, "packssdw", int_x86_sse2_packssdw_128>;
3776 defm PACKUSWB : PDI_binop_rm_int<0x67, "packuswb", int_x86_sse2_packuswb_128>;
3777 } // Constraints = "$src1 = $dst"
3778
3779 //===---------------------------------------------------------------------===//
3780 // SSE2 - Packed Integer Shuffle Instructions
3781 //===---------------------------------------------------------------------===//
3782
3783 let ExeDomain = SSEPackedInt in {
3784 multiclass sse2_pshuffle<string OpcodeStr, ValueType vt, PatFrag pshuf_frag,
3785                          PatFrag bc_frag> {
3786 def ri : Ii8<0x70, MRMSrcReg,
3787               (outs VR128:$dst), (ins VR128:$src1, i8imm:$src2),
3788               !strconcat(OpcodeStr,
3789                          "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
3790               [(set VR128:$dst, (vt (pshuf_frag:$src2 VR128:$src1,
3791                                                       (undef))))]>;
3792 def mi : Ii8<0x70, MRMSrcMem,
3793               (outs VR128:$dst), (ins i128mem:$src1, i8imm:$src2),
3794               !strconcat(OpcodeStr,
3795                          "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
3796               [(set VR128:$dst, (vt (pshuf_frag:$src2
3797                                       (bc_frag (memopv2i64 addr:$src1)),
3798                                       (undef))))]>;
3799 }
3800 } // ExeDomain = SSEPackedInt
3801
3802 let Predicates = [HasAVX] in {
3803   let AddedComplexity = 5 in
3804   defm VPSHUFD : sse2_pshuffle<"vpshufd", v4i32, pshufd, bc_v4i32>, TB, OpSize,
3805                                VEX;
3806
3807   // SSE2 with ImmT == Imm8 and XS prefix.
3808   defm VPSHUFHW : sse2_pshuffle<"vpshufhw", v8i16, pshufhw, bc_v8i16>, XS,
3809                                VEX;
3810
3811   // SSE2 with ImmT == Imm8 and XD prefix.
3812   defm VPSHUFLW : sse2_pshuffle<"vpshuflw", v8i16, pshuflw, bc_v8i16>, XD,
3813                                VEX;
3814
3815   let AddedComplexity = 5 in
3816   def : Pat<(v4f32 (pshufd:$src2 VR128:$src1, (undef))),
3817             (VPSHUFDri VR128:$src1, (SHUFFLE_get_shuf_imm VR128:$src2))>;
3818   // Unary v4f32 shuffle with VPSHUF* in order to fold a load.
3819   def : Pat<(pshufd:$src2 (bc_v4i32 (memopv4f32 addr:$src1)), (undef)),
3820             (VPSHUFDmi addr:$src1, (SHUFFLE_get_shuf_imm VR128:$src2))>;
3821
3822   def : Pat<(v4i32 (X86PShufd (bc_v4i32 (memopv2i64 addr:$src1)),
3823                                    (i8 imm:$imm))),
3824             (VPSHUFDmi addr:$src1, imm:$imm)>;
3825   def : Pat<(v4i32 (X86PShufd (bc_v4i32 (memopv4f32 addr:$src1)),
3826                                    (i8 imm:$imm))),
3827             (VPSHUFDmi addr:$src1, imm:$imm)>;
3828   def : Pat<(v4f32 (X86PShufd VR128:$src1, (i8 imm:$imm))),
3829             (VPSHUFDri VR128:$src1, imm:$imm)>;
3830   def : Pat<(v4i32 (X86PShufd VR128:$src1, (i8 imm:$imm))),
3831             (VPSHUFDri VR128:$src1, imm:$imm)>;
3832   def : Pat<(v8i16 (X86PShufhw VR128:$src, (i8 imm:$imm))),
3833             (VPSHUFHWri VR128:$src, imm:$imm)>;
3834   def : Pat<(v8i16 (X86PShufhw (bc_v8i16 (memopv2i64 addr:$src)),
3835                                (i8 imm:$imm))),
3836             (VPSHUFHWmi addr:$src, imm:$imm)>;
3837   def : Pat<(v8i16 (X86PShuflw VR128:$src, (i8 imm:$imm))),
3838             (VPSHUFLWri VR128:$src, imm:$imm)>;
3839   def : Pat<(v8i16 (X86PShuflw (bc_v8i16 (memopv2i64 addr:$src)),
3840                                (i8 imm:$imm))),
3841             (VPSHUFLWmi addr:$src, imm:$imm)>;
3842 }
3843
3844 let Predicates = [HasSSE2] in {
3845   let AddedComplexity = 5 in
3846   defm PSHUFD : sse2_pshuffle<"pshufd", v4i32, pshufd, bc_v4i32>, TB, OpSize;
3847
3848   // SSE2 with ImmT == Imm8 and XS prefix.
3849   defm PSHUFHW : sse2_pshuffle<"pshufhw", v8i16, pshufhw, bc_v8i16>, XS;
3850
3851   // SSE2 with ImmT == Imm8 and XD prefix.
3852   defm PSHUFLW : sse2_pshuffle<"pshuflw", v8i16, pshuflw, bc_v8i16>, XD;
3853
3854   let AddedComplexity = 5 in
3855   def : Pat<(v4f32 (pshufd:$src2 VR128:$src1, (undef))),
3856             (PSHUFDri VR128:$src1, (SHUFFLE_get_shuf_imm VR128:$src2))>;
3857   // Unary v4f32 shuffle with PSHUF* in order to fold a load.
3858   def : Pat<(pshufd:$src2 (bc_v4i32 (memopv4f32 addr:$src1)), (undef)),
3859             (PSHUFDmi addr:$src1, (SHUFFLE_get_shuf_imm VR128:$src2))>;
3860
3861   def : Pat<(v4i32 (X86PShufd (bc_v4i32 (memopv2i64 addr:$src1)),
3862                                    (i8 imm:$imm))),
3863             (PSHUFDmi addr:$src1, imm:$imm)>;
3864   def : Pat<(v4i32 (X86PShufd (bc_v4i32 (memopv4f32 addr:$src1)),
3865                                    (i8 imm:$imm))),
3866             (PSHUFDmi addr:$src1, imm:$imm)>;
3867   def : Pat<(v4f32 (X86PShufd VR128:$src1, (i8 imm:$imm))),
3868             (PSHUFDri VR128:$src1, imm:$imm)>;
3869   def : Pat<(v4i32 (X86PShufd VR128:$src1, (i8 imm:$imm))),
3870             (PSHUFDri VR128:$src1, imm:$imm)>;
3871   def : Pat<(v8i16 (X86PShufhw VR128:$src, (i8 imm:$imm))),
3872             (PSHUFHWri VR128:$src, imm:$imm)>;
3873   def : Pat<(v8i16 (X86PShufhw (bc_v8i16 (memopv2i64 addr:$src)),
3874                                (i8 imm:$imm))),
3875             (PSHUFHWmi addr:$src, imm:$imm)>;
3876   def : Pat<(v8i16 (X86PShuflw VR128:$src, (i8 imm:$imm))),
3877             (PSHUFLWri VR128:$src, imm:$imm)>;
3878   def : Pat<(v8i16 (X86PShuflw (bc_v8i16 (memopv2i64 addr:$src)),
3879                                (i8 imm:$imm))),
3880             (PSHUFLWmi addr:$src, imm:$imm)>;
3881 }
3882
3883 //===---------------------------------------------------------------------===//
3884 // SSE2 - Packed Integer Unpack Instructions
3885 //===---------------------------------------------------------------------===//
3886
3887 let ExeDomain = SSEPackedInt in {
3888 multiclass sse2_unpack<bits<8> opc, string OpcodeStr, ValueType vt,
3889                        SDNode OpNode, PatFrag bc_frag, bit Is2Addr = 1> {
3890   def rr : PDI<opc, MRMSrcReg,
3891       (outs VR128:$dst), (ins VR128:$src1, VR128:$src2),
3892       !if(Is2Addr,
3893           !strconcat(OpcodeStr,"\t{$src2, $dst|$dst, $src2}"),
3894           !strconcat(OpcodeStr,"\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
3895       [(set VR128:$dst, (vt (OpNode VR128:$src1, VR128:$src2)))]>;
3896   def rm : PDI<opc, MRMSrcMem,
3897       (outs VR128:$dst), (ins VR128:$src1, i128mem:$src2),
3898       !if(Is2Addr,
3899           !strconcat(OpcodeStr,"\t{$src2, $dst|$dst, $src2}"),
3900           !strconcat(OpcodeStr,"\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
3901       [(set VR128:$dst, (OpNode VR128:$src1,
3902                                   (bc_frag (memopv2i64
3903                                                addr:$src2))))]>;
3904 }
3905
3906 let Predicates = [HasAVX] in {
3907   defm VPUNPCKLBW  : sse2_unpack<0x60, "vpunpcklbw", v16i8, X86Punpcklbw,
3908                                  bc_v16i8, 0>, VEX_4V;
3909   defm VPUNPCKLWD  : sse2_unpack<0x61, "vpunpcklwd", v8i16, X86Punpcklwd,
3910                                  bc_v8i16, 0>, VEX_4V;
3911   defm VPUNPCKLDQ  : sse2_unpack<0x62, "vpunpckldq", v4i32, X86Punpckldq,
3912                                  bc_v4i32, 0>, VEX_4V;
3913
3914   /// FIXME: we could eliminate this and use sse2_unpack instead if tblgen
3915   /// knew to collapse (bitconvert VT to VT) into its operand.
3916   def VPUNPCKLQDQrr : PDI<0x6C, MRMSrcReg,
3917             (outs VR128:$dst), (ins VR128:$src1, VR128:$src2),
3918             "vpunpcklqdq\t{$src2, $src1, $dst|$dst, $src1, $src2}",
3919             [(set VR128:$dst, (v2i64 (X86Punpcklqdq VR128:$src1,
3920                                                     VR128:$src2)))]>, VEX_4V;
3921   def VPUNPCKLQDQrm : PDI<0x6C, MRMSrcMem,
3922             (outs VR128:$dst), (ins VR128:$src1, i128mem:$src2),
3923             "vpunpcklqdq\t{$src2, $src1, $dst|$dst, $src1, $src2}",
3924             [(set VR128:$dst, (v2i64 (X86Punpcklqdq VR128:$src1,
3925                                         (memopv2i64 addr:$src2))))]>, VEX_4V;
3926
3927   defm VPUNPCKHBW  : sse2_unpack<0x68, "vpunpckhbw", v16i8, X86Punpckhbw,
3928                                  bc_v16i8, 0>, VEX_4V;
3929   defm VPUNPCKHWD  : sse2_unpack<0x69, "vpunpckhwd", v8i16, X86Punpckhwd,
3930                                  bc_v8i16, 0>, VEX_4V;
3931   defm VPUNPCKHDQ  : sse2_unpack<0x6A, "vpunpckhdq", v4i32, X86Punpckhdq,
3932                                  bc_v4i32, 0>, VEX_4V;
3933
3934   /// FIXME: we could eliminate this and use sse2_unpack instead if tblgen
3935   /// knew to collapse (bitconvert VT to VT) into its operand.
3936   def VPUNPCKHQDQrr : PDI<0x6D, MRMSrcReg,
3937              (outs VR128:$dst), (ins VR128:$src1, VR128:$src2),
3938              "vpunpckhqdq\t{$src2, $src1, $dst|$dst, $src1, $src2}",
3939              [(set VR128:$dst, (v2i64 (X86Punpckhqdq VR128:$src1,
3940                                                      VR128:$src2)))]>, VEX_4V;
3941   def VPUNPCKHQDQrm : PDI<0x6D, MRMSrcMem,
3942              (outs VR128:$dst), (ins VR128:$src1, i128mem:$src2),
3943              "vpunpckhqdq\t{$src2, $src1, $dst|$dst, $src1, $src2}",
3944              [(set VR128:$dst, (v2i64 (X86Punpckhqdq VR128:$src1,
3945                                         (memopv2i64 addr:$src2))))]>, VEX_4V;
3946 }
3947
3948 let Constraints = "$src1 = $dst" in {
3949   defm PUNPCKLBW  : sse2_unpack<0x60, "punpcklbw", v16i8, X86Punpcklbw, bc_v16i8>;
3950   defm PUNPCKLWD  : sse2_unpack<0x61, "punpcklwd", v8i16, X86Punpcklwd, bc_v8i16>;
3951   defm PUNPCKLDQ  : sse2_unpack<0x62, "punpckldq", v4i32, X86Punpckldq, bc_v4i32>;
3952
3953   /// FIXME: we could eliminate this and use sse2_unpack instead if tblgen
3954   /// knew to collapse (bitconvert VT to VT) into its operand.
3955   def PUNPCKLQDQrr : PDI<0x6C, MRMSrcReg,
3956                          (outs VR128:$dst), (ins VR128:$src1, VR128:$src2),
3957                          "punpcklqdq\t{$src2, $dst|$dst, $src2}",
3958                         [(set VR128:$dst,
3959                           (v2i64 (X86Punpcklqdq VR128:$src1, VR128:$src2)))]>;
3960   def PUNPCKLQDQrm : PDI<0x6C, MRMSrcMem,
3961                          (outs VR128:$dst), (ins VR128:$src1, i128mem:$src2),
3962                          "punpcklqdq\t{$src2, $dst|$dst, $src2}",
3963                         [(set VR128:$dst,
3964                           (v2i64 (X86Punpcklqdq VR128:$src1,
3965                                          (memopv2i64 addr:$src2))))]>;
3966
3967   defm PUNPCKHBW  : sse2_unpack<0x68, "punpckhbw", v16i8, X86Punpckhbw, bc_v16i8>;
3968   defm PUNPCKHWD  : sse2_unpack<0x69, "punpckhwd", v8i16, X86Punpckhwd, bc_v8i16>;
3969   defm PUNPCKHDQ  : sse2_unpack<0x6A, "punpckhdq", v4i32, X86Punpckhdq, bc_v4i32>;
3970
3971   /// FIXME: we could eliminate this and use sse2_unpack instead if tblgen
3972   /// knew to collapse (bitconvert VT to VT) into its operand.
3973   def PUNPCKHQDQrr : PDI<0x6D, MRMSrcReg,
3974                          (outs VR128:$dst), (ins VR128:$src1, VR128:$src2),
3975                          "punpckhqdq\t{$src2, $dst|$dst, $src2}",
3976                         [(set VR128:$dst,
3977                           (v2i64 (X86Punpckhqdq VR128:$src1, VR128:$src2)))]>;
3978   def PUNPCKHQDQrm : PDI<0x6D, MRMSrcMem,
3979                         (outs VR128:$dst), (ins VR128:$src1, i128mem:$src2),
3980                         "punpckhqdq\t{$src2, $dst|$dst, $src2}",
3981                         [(set VR128:$dst,
3982                           (v2i64 (X86Punpckhqdq VR128:$src1,
3983                                          (memopv2i64 addr:$src2))))]>;
3984 }
3985 } // ExeDomain = SSEPackedInt
3986
3987 // Splat v2f64 / v2i64
3988 let AddedComplexity = 10 in {
3989   def : Pat<(splat_lo (v2i64 VR128:$src), (undef)),
3990             (PUNPCKLQDQrr VR128:$src, VR128:$src)>, Requires<[HasSSE2]>;
3991   def : Pat<(splat_lo (v2i64 VR128:$src), (undef)),
3992             (VPUNPCKLQDQrr VR128:$src, VR128:$src)>, Requires<[HasAVX]>;
3993 }
3994
3995 //===---------------------------------------------------------------------===//
3996 // SSE2 - Packed Integer Extract and Insert
3997 //===---------------------------------------------------------------------===//
3998
3999 let ExeDomain = SSEPackedInt in {
4000 multiclass sse2_pinsrw<bit Is2Addr = 1> {
4001   def rri : Ii8<0xC4, MRMSrcReg,
4002        (outs VR128:$dst), (ins VR128:$src1,
4003         GR32:$src2, i32i8imm:$src3),
4004        !if(Is2Addr,
4005            "pinsrw\t{$src3, $src2, $dst|$dst, $src2, $src3}",
4006            "vpinsrw\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
4007        [(set VR128:$dst,
4008          (X86pinsrw VR128:$src1, GR32:$src2, imm:$src3))]>;
4009   def rmi : Ii8<0xC4, MRMSrcMem,
4010                        (outs VR128:$dst), (ins VR128:$src1,
4011                         i16mem:$src2, i32i8imm:$src3),
4012        !if(Is2Addr,
4013            "pinsrw\t{$src3, $src2, $dst|$dst, $src2, $src3}",
4014            "vpinsrw\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
4015        [(set VR128:$dst,
4016          (X86pinsrw VR128:$src1, (extloadi16 addr:$src2),
4017                     imm:$src3))]>;
4018 }
4019
4020 // Extract
4021 let Predicates = [HasAVX] in
4022 def VPEXTRWri : Ii8<0xC5, MRMSrcReg,
4023                     (outs GR32:$dst), (ins VR128:$src1, i32i8imm:$src2),
4024                     "vpextrw\t{$src2, $src1, $dst|$dst, $src1, $src2}",
4025                     [(set GR32:$dst, (X86pextrw (v8i16 VR128:$src1),
4026                                                 imm:$src2))]>, TB, OpSize, VEX;
4027 def PEXTRWri : PDIi8<0xC5, MRMSrcReg,
4028                     (outs GR32:$dst), (ins VR128:$src1, i32i8imm:$src2),
4029                     "pextrw\t{$src2, $src1, $dst|$dst, $src1, $src2}",
4030                     [(set GR32:$dst, (X86pextrw (v8i16 VR128:$src1),
4031                                                 imm:$src2))]>;
4032
4033 // Insert
4034 let Predicates = [HasAVX] in {
4035   defm VPINSRW : sse2_pinsrw<0>, TB, OpSize, VEX_4V;
4036   def  VPINSRWrr64i : Ii8<0xC4, MRMSrcReg, (outs VR128:$dst),
4037        (ins VR128:$src1, GR64:$src2, i32i8imm:$src3),
4038        "vpinsrw\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
4039        []>, TB, OpSize, VEX_4V;
4040 }
4041
4042 let Constraints = "$src1 = $dst" in
4043   defm PINSRW : sse2_pinsrw, TB, OpSize, Requires<[HasSSE2]>;
4044
4045 } // ExeDomain = SSEPackedInt
4046
4047 //===---------------------------------------------------------------------===//
4048 // SSE2 - Packed Mask Creation
4049 //===---------------------------------------------------------------------===//
4050
4051 let ExeDomain = SSEPackedInt in {
4052
4053 def VPMOVMSKBrr  : VPDI<0xD7, MRMSrcReg, (outs GR32:$dst), (ins VR128:$src),
4054            "pmovmskb\t{$src, $dst|$dst, $src}",
4055            [(set GR32:$dst, (int_x86_sse2_pmovmskb_128 VR128:$src))]>, VEX;
4056 def VPMOVMSKBr64r : VPDI<0xD7, MRMSrcReg, (outs GR64:$dst), (ins VR128:$src),
4057            "pmovmskb\t{$src, $dst|$dst, $src}", []>, VEX;
4058 def PMOVMSKBrr : PDI<0xD7, MRMSrcReg, (outs GR32:$dst), (ins VR128:$src),
4059            "pmovmskb\t{$src, $dst|$dst, $src}",
4060            [(set GR32:$dst, (int_x86_sse2_pmovmskb_128 VR128:$src))]>;
4061
4062 } // ExeDomain = SSEPackedInt
4063
4064 //===---------------------------------------------------------------------===//
4065 // SSE2 - Conditional Store
4066 //===---------------------------------------------------------------------===//
4067
4068 let ExeDomain = SSEPackedInt in {
4069
4070 let Uses = [EDI] in
4071 def VMASKMOVDQU : VPDI<0xF7, MRMSrcReg, (outs),
4072            (ins VR128:$src, VR128:$mask),
4073            "maskmovdqu\t{$mask, $src|$src, $mask}",
4074            [(int_x86_sse2_maskmov_dqu VR128:$src, VR128:$mask, EDI)]>, VEX;
4075 let Uses = [RDI] in
4076 def VMASKMOVDQU64 : VPDI<0xF7, MRMSrcReg, (outs),
4077            (ins VR128:$src, VR128:$mask),
4078            "maskmovdqu\t{$mask, $src|$src, $mask}",
4079            [(int_x86_sse2_maskmov_dqu VR128:$src, VR128:$mask, RDI)]>, VEX;
4080
4081 let Uses = [EDI] in
4082 def MASKMOVDQU : PDI<0xF7, MRMSrcReg, (outs), (ins VR128:$src, VR128:$mask),
4083            "maskmovdqu\t{$mask, $src|$src, $mask}",
4084            [(int_x86_sse2_maskmov_dqu VR128:$src, VR128:$mask, EDI)]>;
4085 let Uses = [RDI] in
4086 def MASKMOVDQU64 : PDI<0xF7, MRMSrcReg, (outs), (ins VR128:$src, VR128:$mask),
4087            "maskmovdqu\t{$mask, $src|$src, $mask}",
4088            [(int_x86_sse2_maskmov_dqu VR128:$src, VR128:$mask, RDI)]>;
4089
4090 } // ExeDomain = SSEPackedInt
4091
4092 //===---------------------------------------------------------------------===//
4093 // SSE2 - Move Doubleword
4094 //===---------------------------------------------------------------------===//
4095
4096 //===---------------------------------------------------------------------===//
4097 // Move Int Doubleword to Packed Double Int
4098 //
4099 def VMOVDI2PDIrr : VPDI<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR32:$src),
4100                       "movd\t{$src, $dst|$dst, $src}",
4101                       [(set VR128:$dst,
4102                         (v4i32 (scalar_to_vector GR32:$src)))]>, VEX;
4103 def VMOVDI2PDIrm : VPDI<0x6E, MRMSrcMem, (outs VR128:$dst), (ins i32mem:$src),
4104                       "movd\t{$src, $dst|$dst, $src}",
4105                       [(set VR128:$dst,
4106                         (v4i32 (scalar_to_vector (loadi32 addr:$src))))]>,
4107                       VEX;
4108 def VMOV64toPQIrr : VRPDI<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR64:$src),
4109                         "mov{d|q}\t{$src, $dst|$dst, $src}",
4110                         [(set VR128:$dst,
4111                           (v2i64 (scalar_to_vector GR64:$src)))]>, VEX;
4112 def VMOV64toSDrr : VRPDI<0x6E, MRMSrcReg, (outs FR64:$dst), (ins GR64:$src),
4113                        "mov{d|q}\t{$src, $dst|$dst, $src}",
4114                        [(set FR64:$dst, (bitconvert GR64:$src))]>, VEX;
4115
4116 def MOVDI2PDIrr : PDI<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR32:$src),
4117                       "movd\t{$src, $dst|$dst, $src}",
4118                       [(set VR128:$dst,
4119                         (v4i32 (scalar_to_vector GR32:$src)))]>;
4120 def MOVDI2PDIrm : PDI<0x6E, MRMSrcMem, (outs VR128:$dst), (ins i32mem:$src),
4121                       "movd\t{$src, $dst|$dst, $src}",
4122                       [(set VR128:$dst,
4123                         (v4i32 (scalar_to_vector (loadi32 addr:$src))))]>;
4124 def MOV64toPQIrr : RPDI<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR64:$src),
4125                         "mov{d|q}\t{$src, $dst|$dst, $src}",
4126                         [(set VR128:$dst,
4127                           (v2i64 (scalar_to_vector GR64:$src)))]>;
4128 def MOV64toSDrr : RPDI<0x6E, MRMSrcReg, (outs FR64:$dst), (ins GR64:$src),
4129                        "mov{d|q}\t{$src, $dst|$dst, $src}",
4130                        [(set FR64:$dst, (bitconvert GR64:$src))]>;
4131
4132 //===---------------------------------------------------------------------===//
4133 // Move Int Doubleword to Single Scalar
4134 //
4135 def VMOVDI2SSrr  : VPDI<0x6E, MRMSrcReg, (outs FR32:$dst), (ins GR32:$src),
4136                       "movd\t{$src, $dst|$dst, $src}",
4137                       [(set FR32:$dst, (bitconvert GR32:$src))]>, VEX;
4138
4139 def VMOVDI2SSrm  : VPDI<0x6E, MRMSrcMem, (outs FR32:$dst), (ins i32mem:$src),
4140                       "movd\t{$src, $dst|$dst, $src}",
4141                       [(set FR32:$dst, (bitconvert (loadi32 addr:$src)))]>,
4142                       VEX;
4143 def MOVDI2SSrr  : PDI<0x6E, MRMSrcReg, (outs FR32:$dst), (ins GR32:$src),
4144                       "movd\t{$src, $dst|$dst, $src}",
4145                       [(set FR32:$dst, (bitconvert GR32:$src))]>;
4146
4147 def MOVDI2SSrm  : PDI<0x6E, MRMSrcMem, (outs FR32:$dst), (ins i32mem:$src),
4148                       "movd\t{$src, $dst|$dst, $src}",
4149                       [(set FR32:$dst, (bitconvert (loadi32 addr:$src)))]>;
4150
4151 //===---------------------------------------------------------------------===//
4152 // Move Packed Doubleword Int to Packed Double Int
4153 //
4154 def VMOVPDI2DIrr  : VPDI<0x7E, MRMDestReg, (outs GR32:$dst), (ins VR128:$src),
4155                        "movd\t{$src, $dst|$dst, $src}",
4156                        [(set GR32:$dst, (vector_extract (v4i32 VR128:$src),
4157                                         (iPTR 0)))]>, VEX;
4158 def VMOVPDI2DImr  : VPDI<0x7E, MRMDestMem, (outs),
4159                        (ins i32mem:$dst, VR128:$src),
4160                        "movd\t{$src, $dst|$dst, $src}",
4161                        [(store (i32 (vector_extract (v4i32 VR128:$src),
4162                                      (iPTR 0))), addr:$dst)]>, VEX;
4163 def MOVPDI2DIrr  : PDI<0x7E, MRMDestReg, (outs GR32:$dst), (ins VR128:$src),
4164                        "movd\t{$src, $dst|$dst, $src}",
4165                        [(set GR32:$dst, (vector_extract (v4i32 VR128:$src),
4166                                         (iPTR 0)))]>;
4167 def MOVPDI2DImr  : PDI<0x7E, MRMDestMem, (outs), (ins i32mem:$dst, VR128:$src),
4168                        "movd\t{$src, $dst|$dst, $src}",
4169                        [(store (i32 (vector_extract (v4i32 VR128:$src),
4170                                      (iPTR 0))), addr:$dst)]>;
4171
4172 //===---------------------------------------------------------------------===//
4173 // Move Packed Doubleword Int first element to Doubleword Int
4174 //
4175 def VMOVPQIto64rr : I<0x7E, MRMDestReg, (outs GR64:$dst), (ins VR128:$src),
4176                           "mov{d|q}\t{$src, $dst|$dst, $src}",
4177                           [(set GR64:$dst, (vector_extract (v2i64 VR128:$src),
4178                                                            (iPTR 0)))]>,
4179                       TB, OpSize, VEX, VEX_W, Requires<[HasAVX, In64BitMode]>;
4180
4181 def MOVPQIto64rr : RPDI<0x7E, MRMDestReg, (outs GR64:$dst), (ins VR128:$src),
4182                         "mov{d|q}\t{$src, $dst|$dst, $src}",
4183                         [(set GR64:$dst, (vector_extract (v2i64 VR128:$src),
4184                                                          (iPTR 0)))]>;
4185
4186 //===---------------------------------------------------------------------===//
4187 // Bitcast FR64 <-> GR64
4188 //
4189 let Predicates = [HasAVX] in
4190 def VMOV64toSDrm : S3SI<0x7E, MRMSrcMem, (outs FR64:$dst), (ins i64mem:$src),
4191                         "vmovq\t{$src, $dst|$dst, $src}",
4192                         [(set FR64:$dst, (bitconvert (loadi64 addr:$src)))]>,
4193                         VEX;
4194 def VMOVSDto64rr : VRPDI<0x7E, MRMDestReg, (outs GR64:$dst), (ins FR64:$src),
4195                          "mov{d|q}\t{$src, $dst|$dst, $src}",
4196                          [(set GR64:$dst, (bitconvert FR64:$src))]>;
4197 def VMOVSDto64mr : VRPDI<0x7E, MRMDestMem, (outs), (ins i64mem:$dst, FR64:$src),
4198                          "movq\t{$src, $dst|$dst, $src}",
4199                          [(store (i64 (bitconvert FR64:$src)), addr:$dst)]>;
4200
4201 def MOV64toSDrm : S3SI<0x7E, MRMSrcMem, (outs FR64:$dst), (ins i64mem:$src),
4202                        "movq\t{$src, $dst|$dst, $src}",
4203                        [(set FR64:$dst, (bitconvert (loadi64 addr:$src)))]>;
4204 def MOVSDto64rr : RPDI<0x7E, MRMDestReg, (outs GR64:$dst), (ins FR64:$src),
4205                        "mov{d|q}\t{$src, $dst|$dst, $src}",
4206                        [(set GR64:$dst, (bitconvert FR64:$src))]>;
4207 def MOVSDto64mr : RPDI<0x7E, MRMDestMem, (outs), (ins i64mem:$dst, FR64:$src),
4208                        "movq\t{$src, $dst|$dst, $src}",
4209                        [(store (i64 (bitconvert FR64:$src)), addr:$dst)]>;
4210
4211 //===---------------------------------------------------------------------===//
4212 // Move Scalar Single to Double Int
4213 //
4214 def VMOVSS2DIrr  : VPDI<0x7E, MRMDestReg, (outs GR32:$dst), (ins FR32:$src),
4215                       "movd\t{$src, $dst|$dst, $src}",
4216                       [(set GR32:$dst, (bitconvert FR32:$src))]>, VEX;
4217 def VMOVSS2DImr  : VPDI<0x7E, MRMDestMem, (outs), (ins i32mem:$dst, FR32:$src),
4218                       "movd\t{$src, $dst|$dst, $src}",
4219                       [(store (i32 (bitconvert FR32:$src)), addr:$dst)]>, VEX;
4220 def MOVSS2DIrr  : PDI<0x7E, MRMDestReg, (outs GR32:$dst), (ins FR32:$src),
4221                       "movd\t{$src, $dst|$dst, $src}",
4222                       [(set GR32:$dst, (bitconvert FR32:$src))]>;
4223 def MOVSS2DImr  : PDI<0x7E, MRMDestMem, (outs), (ins i32mem:$dst, FR32:$src),
4224                       "movd\t{$src, $dst|$dst, $src}",
4225                       [(store (i32 (bitconvert FR32:$src)), addr:$dst)]>;
4226
4227 //===---------------------------------------------------------------------===//
4228 // Patterns and instructions to describe movd/movq to XMM register zero-extends
4229 //
4230 let AddedComplexity = 15 in {
4231 def VMOVZDI2PDIrr : VPDI<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR32:$src),
4232                        "movd\t{$src, $dst|$dst, $src}",
4233                        [(set VR128:$dst, (v4i32 (X86vzmovl
4234                                       (v4i32 (scalar_to_vector GR32:$src)))))]>,
4235                                       VEX;
4236 def VMOVZQI2PQIrr : VPDI<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR64:$src),
4237                        "mov{d|q}\t{$src, $dst|$dst, $src}", // X86-64 only
4238                        [(set VR128:$dst, (v2i64 (X86vzmovl
4239                                       (v2i64 (scalar_to_vector GR64:$src)))))]>,
4240                                       VEX, VEX_W;
4241 }
4242 let AddedComplexity = 15 in {
4243 def MOVZDI2PDIrr : PDI<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR32:$src),
4244                        "movd\t{$src, $dst|$dst, $src}",
4245                        [(set VR128:$dst, (v4i32 (X86vzmovl
4246                                       (v4i32 (scalar_to_vector GR32:$src)))))]>;
4247 def MOVZQI2PQIrr : RPDI<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR64:$src),
4248                        "mov{d|q}\t{$src, $dst|$dst, $src}", // X86-64 only
4249                        [(set VR128:$dst, (v2i64 (X86vzmovl
4250                                       (v2i64 (scalar_to_vector GR64:$src)))))]>;
4251 }
4252
4253 let AddedComplexity = 20 in {
4254 def VMOVZDI2PDIrm : VPDI<0x6E, MRMSrcMem, (outs VR128:$dst), (ins i32mem:$src),
4255                        "movd\t{$src, $dst|$dst, $src}",
4256                        [(set VR128:$dst,
4257                          (v4i32 (X86vzmovl (v4i32 (scalar_to_vector
4258                                                    (loadi32 addr:$src))))))]>,
4259                                                    VEX;
4260 def MOVZDI2PDIrm : PDI<0x6E, MRMSrcMem, (outs VR128:$dst), (ins i32mem:$src),
4261                        "movd\t{$src, $dst|$dst, $src}",
4262                        [(set VR128:$dst,
4263                          (v4i32 (X86vzmovl (v4i32 (scalar_to_vector
4264                                                    (loadi32 addr:$src))))))]>;
4265 }
4266
4267 let Predicates = [HasSSE2], AddedComplexity = 20 in {
4268   def : Pat<(v4i32 (X86vzmovl (loadv4i32 addr:$src))),
4269             (MOVZDI2PDIrm addr:$src)>;
4270   def : Pat<(v4i32 (X86vzmovl (bc_v4i32 (loadv4f32 addr:$src)))),
4271             (MOVZDI2PDIrm addr:$src)>;
4272   def : Pat<(v4i32 (X86vzmovl (bc_v4i32 (loadv2i64 addr:$src)))),
4273             (MOVZDI2PDIrm addr:$src)>;
4274 }
4275
4276 let Predicates = [HasAVX] in {
4277   // AVX 128-bit movd/movq instruction write zeros in the high 128-bit part.
4278   let AddedComplexity = 20 in {
4279     def : Pat<(v4i32 (X86vzmovl (loadv4i32 addr:$src))),
4280               (VMOVZDI2PDIrm addr:$src)>;
4281     def : Pat<(v4i32 (X86vzmovl (bc_v4i32 (loadv4f32 addr:$src)))),
4282               (VMOVZDI2PDIrm addr:$src)>;
4283     def : Pat<(v4i32 (X86vzmovl (bc_v4i32 (loadv2i64 addr:$src)))),
4284               (VMOVZDI2PDIrm addr:$src)>;
4285   }
4286   // Use regular 128-bit instructions to match 256-bit scalar_to_vec+zext.
4287   def : Pat<(v8i32 (X86vzmovl (insert_subvector undef,
4288                                 (v4i32 (scalar_to_vector GR32:$src)),(i32 0)))),
4289             (SUBREG_TO_REG (i32 0), (VMOVZDI2PDIrr GR32:$src), sub_xmm)>;
4290   def : Pat<(v4i64 (X86vzmovl (insert_subvector undef,
4291                                 (v2i64 (scalar_to_vector GR64:$src)),(i32 0)))),
4292             (SUBREG_TO_REG (i64 0), (VMOVZQI2PQIrr GR64:$src), sub_xmm)>;
4293 }
4294
4295 // These are the correct encodings of the instructions so that we know how to
4296 // read correct assembly, even though we continue to emit the wrong ones for
4297 // compatibility with Darwin's buggy assembler.
4298 def : InstAlias<"movq\t{$src, $dst|$dst, $src}",
4299                 (MOV64toPQIrr VR128:$dst, GR64:$src), 0>;
4300 def : InstAlias<"movq\t{$src, $dst|$dst, $src}",
4301                 (MOV64toSDrr FR64:$dst, GR64:$src), 0>;
4302 def : InstAlias<"movq\t{$src, $dst|$dst, $src}",
4303                 (MOVPQIto64rr GR64:$dst, VR128:$src), 0>;
4304 def : InstAlias<"movq\t{$src, $dst|$dst, $src}",
4305                 (MOVSDto64rr GR64:$dst, FR64:$src), 0>;
4306 def : InstAlias<"movq\t{$src, $dst|$dst, $src}",
4307                 (VMOVZQI2PQIrr VR128:$dst, GR64:$src), 0>;
4308 def : InstAlias<"movq\t{$src, $dst|$dst, $src}",
4309                 (MOVZQI2PQIrr VR128:$dst, GR64:$src), 0>;
4310
4311 //===---------------------------------------------------------------------===//
4312 // SSE2 - Move Quadword
4313 //===---------------------------------------------------------------------===//
4314
4315 //===---------------------------------------------------------------------===//
4316 // Move Quadword Int to Packed Quadword Int
4317 //
4318 def VMOVQI2PQIrm : I<0x7E, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
4319                     "vmovq\t{$src, $dst|$dst, $src}",
4320                     [(set VR128:$dst,
4321                       (v2i64 (scalar_to_vector (loadi64 addr:$src))))]>, XS,
4322                     VEX, Requires<[HasAVX]>;
4323 def MOVQI2PQIrm : I<0x7E, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
4324                     "movq\t{$src, $dst|$dst, $src}",
4325                     [(set VR128:$dst,
4326                       (v2i64 (scalar_to_vector (loadi64 addr:$src))))]>, XS,
4327                     Requires<[HasSSE2]>; // SSE2 instruction with XS Prefix
4328
4329 //===---------------------------------------------------------------------===//
4330 // Move Packed Quadword Int to Quadword Int
4331 //
4332 def VMOVPQI2QImr : VPDI<0xD6, MRMDestMem, (outs), (ins i64mem:$dst, VR128:$src),
4333                       "movq\t{$src, $dst|$dst, $src}",
4334                       [(store (i64 (vector_extract (v2i64 VR128:$src),
4335                                     (iPTR 0))), addr:$dst)]>, VEX;
4336 def MOVPQI2QImr : PDI<0xD6, MRMDestMem, (outs), (ins i64mem:$dst, VR128:$src),
4337                       "movq\t{$src, $dst|$dst, $src}",
4338                       [(store (i64 (vector_extract (v2i64 VR128:$src),
4339                                     (iPTR 0))), addr:$dst)]>;
4340
4341 //===---------------------------------------------------------------------===//
4342 // Store / copy lower 64-bits of a XMM register.
4343 //
4344 def VMOVLQ128mr : VPDI<0xD6, MRMDestMem, (outs), (ins i64mem:$dst, VR128:$src),
4345                      "movq\t{$src, $dst|$dst, $src}",
4346                      [(int_x86_sse2_storel_dq addr:$dst, VR128:$src)]>, VEX;
4347 def MOVLQ128mr : PDI<0xD6, MRMDestMem, (outs), (ins i64mem:$dst, VR128:$src),
4348                      "movq\t{$src, $dst|$dst, $src}",
4349                      [(int_x86_sse2_storel_dq addr:$dst, VR128:$src)]>;
4350
4351 let AddedComplexity = 20 in
4352 def VMOVZQI2PQIrm : I<0x7E, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
4353                      "vmovq\t{$src, $dst|$dst, $src}",
4354                      [(set VR128:$dst,
4355                        (v2i64 (X86vzmovl (v2i64 (scalar_to_vector
4356                                                  (loadi64 addr:$src))))))]>,
4357                      XS, VEX, Requires<[HasAVX]>;
4358
4359 let AddedComplexity = 20 in
4360 def MOVZQI2PQIrm : I<0x7E, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
4361                      "movq\t{$src, $dst|$dst, $src}",
4362                      [(set VR128:$dst,
4363                        (v2i64 (X86vzmovl (v2i64 (scalar_to_vector
4364                                                  (loadi64 addr:$src))))))]>,
4365                      XS, Requires<[HasSSE2]>;
4366
4367 let Predicates = [HasSSE2], AddedComplexity = 20 in {
4368   def : Pat<(v2i64 (X86vzmovl (loadv2i64 addr:$src))),
4369             (MOVZQI2PQIrm addr:$src)>;
4370   def : Pat<(v2i64 (X86vzmovl (bc_v2i64 (loadv4f32 addr:$src)))),
4371             (MOVZQI2PQIrm addr:$src)>;
4372   def : Pat<(v2i64 (X86vzload addr:$src)), (MOVZQI2PQIrm addr:$src)>;
4373 }
4374
4375 let Predicates = [HasAVX], AddedComplexity = 20 in {
4376   def : Pat<(v2i64 (X86vzmovl (loadv2i64 addr:$src))),
4377             (VMOVZQI2PQIrm addr:$src)>;
4378   def : Pat<(v2i64 (X86vzmovl (bc_v2i64 (loadv4f32 addr:$src)))),
4379             (VMOVZQI2PQIrm addr:$src)>;
4380   def : Pat<(v2i64 (X86vzload addr:$src)),
4381             (VMOVZQI2PQIrm addr:$src)>;
4382 }
4383
4384 //===---------------------------------------------------------------------===//
4385 // Moving from XMM to XMM and clear upper 64 bits. Note, there is a bug in
4386 // IA32 document. movq xmm1, xmm2 does clear the high bits.
4387 //
4388 let AddedComplexity = 15 in
4389 def VMOVZPQILo2PQIrr : I<0x7E, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
4390                         "vmovq\t{$src, $dst|$dst, $src}",
4391                     [(set VR128:$dst, (v2i64 (X86vzmovl (v2i64 VR128:$src))))]>,
4392                       XS, VEX, Requires<[HasAVX]>;
4393 let AddedComplexity = 15 in
4394 def MOVZPQILo2PQIrr : I<0x7E, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
4395                         "movq\t{$src, $dst|$dst, $src}",
4396                     [(set VR128:$dst, (v2i64 (X86vzmovl (v2i64 VR128:$src))))]>,
4397                       XS, Requires<[HasSSE2]>;
4398
4399 let AddedComplexity = 20 in
4400 def VMOVZPQILo2PQIrm : I<0x7E, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
4401                         "vmovq\t{$src, $dst|$dst, $src}",
4402                     [(set VR128:$dst, (v2i64 (X86vzmovl
4403                                              (loadv2i64 addr:$src))))]>,
4404                       XS, VEX, Requires<[HasAVX]>;
4405 let AddedComplexity = 20 in {
4406 def MOVZPQILo2PQIrm : I<0x7E, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
4407                         "movq\t{$src, $dst|$dst, $src}",
4408                     [(set VR128:$dst, (v2i64 (X86vzmovl
4409                                              (loadv2i64 addr:$src))))]>,
4410                       XS, Requires<[HasSSE2]>;
4411 }
4412
4413 let AddedComplexity = 20 in {
4414   let Predicates = [HasSSE2] in {
4415     def : Pat<(v2i64 (X86vzmovl (bc_v2i64 (loadv4i32 addr:$src)))),
4416               (MOVZPQILo2PQIrm addr:$src)>;
4417     def : Pat<(v2f64 (X86vzmovl (v2f64 VR128:$src))),
4418               (MOVZPQILo2PQIrr VR128:$src)>;
4419   }
4420   let Predicates = [HasAVX] in {
4421     def : Pat<(v2i64 (X86vzmovl (bc_v2i64 (loadv4i32 addr:$src)))),
4422               (VMOVZPQILo2PQIrm addr:$src)>;
4423     def : Pat<(v2f64 (X86vzmovl (v2f64 VR128:$src))),
4424               (VMOVZPQILo2PQIrr VR128:$src)>;
4425   }
4426 }
4427
4428 // Instructions to match in the assembler
4429 def VMOVQs64rr : VPDI<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR64:$src),
4430                       "movq\t{$src, $dst|$dst, $src}", []>, VEX, VEX_W;
4431 def VMOVQd64rr : VPDI<0x7E, MRMDestReg, (outs GR64:$dst), (ins VR128:$src),
4432                       "movq\t{$src, $dst|$dst, $src}", []>, VEX, VEX_W;
4433 // Recognize "movd" with GR64 destination, but encode as a "movq"
4434 def VMOVQd64rr_alt : VPDI<0x7E, MRMDestReg, (outs GR64:$dst), (ins VR128:$src),
4435                           "movd\t{$src, $dst|$dst, $src}", []>, VEX, VEX_W;
4436
4437 // Instructions for the disassembler
4438 // xr = XMM register
4439 // xm = mem64
4440
4441 let Predicates = [HasAVX] in
4442 def VMOVQxrxr: I<0x7E, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
4443                  "vmovq\t{$src, $dst|$dst, $src}", []>, VEX, XS;
4444 def MOVQxrxr : I<0x7E, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
4445                  "movq\t{$src, $dst|$dst, $src}", []>, XS;
4446
4447 //===---------------------------------------------------------------------===//
4448 // SSE3 - Conversion Instructions
4449 //===---------------------------------------------------------------------===//
4450
4451 // Convert Packed Double FP to Packed DW Integers
4452 let Predicates = [HasAVX] in {
4453 // The assembler can recognize rr 256-bit instructions by seeing a ymm
4454 // register, but the same isn't true when using memory operands instead.
4455 // Provide other assembly rr and rm forms to address this explicitly.
4456 def VCVTPD2DQrr  : S3DI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
4457                        "vcvtpd2dq\t{$src, $dst|$dst, $src}", []>, VEX;
4458 def VCVTPD2DQXrYr  : S3DI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR256:$src),
4459                        "vcvtpd2dq\t{$src, $dst|$dst, $src}", []>, VEX;
4460
4461 // XMM only
4462 def VCVTPD2DQXrr : S3DI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
4463                       "vcvtpd2dqx\t{$src, $dst|$dst, $src}", []>, VEX;
4464 def VCVTPD2DQXrm : S3DI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
4465                       "vcvtpd2dqx\t{$src, $dst|$dst, $src}", []>, VEX;
4466
4467 // YMM only
4468 def VCVTPD2DQYrr : S3DI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR256:$src),
4469                       "vcvtpd2dqy\t{$src, $dst|$dst, $src}", []>, VEX;
4470 def VCVTPD2DQYrm : S3DI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f256mem:$src),
4471                       "vcvtpd2dqy\t{$src, $dst|$dst, $src}", []>, VEX, VEX_L;
4472 }
4473
4474 def CVTPD2DQrm  : S3DI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
4475                        "cvtpd2dq\t{$src, $dst|$dst, $src}", []>;
4476 def CVTPD2DQrr  : S3DI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
4477                        "cvtpd2dq\t{$src, $dst|$dst, $src}", []>;
4478
4479 def : Pat<(v4i32 (fp_to_sint (v4f64 VR256:$src))),
4480           (VCVTPD2DQYrr VR256:$src)>;
4481 def : Pat<(v4i32 (fp_to_sint (memopv4f64 addr:$src))),
4482           (VCVTPD2DQYrm addr:$src)>;
4483
4484 // Convert Packed DW Integers to Packed Double FP
4485 let Predicates = [HasAVX] in {
4486 def VCVTDQ2PDrm  : S3SI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
4487                      "vcvtdq2pd\t{$src, $dst|$dst, $src}", []>, VEX;
4488 def VCVTDQ2PDrr  : S3SI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
4489                      "vcvtdq2pd\t{$src, $dst|$dst, $src}", []>, VEX;
4490 def VCVTDQ2PDYrm  : S3SI<0xE6, MRMSrcMem, (outs VR256:$dst), (ins f128mem:$src),
4491                      "vcvtdq2pd\t{$src, $dst|$dst, $src}", []>, VEX;
4492 def VCVTDQ2PDYrr  : S3SI<0xE6, MRMSrcReg, (outs VR256:$dst), (ins VR128:$src),
4493                      "vcvtdq2pd\t{$src, $dst|$dst, $src}", []>, VEX;
4494 }
4495
4496 def CVTDQ2PDrm  : S3SI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
4497                        "cvtdq2pd\t{$src, $dst|$dst, $src}", []>;
4498 def CVTDQ2PDrr  : S3SI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
4499                        "cvtdq2pd\t{$src, $dst|$dst, $src}", []>;
4500
4501 // AVX 256-bit register conversion intrinsics
4502 def : Pat<(int_x86_avx_cvtdq2_pd_256 VR128:$src),
4503            (VCVTDQ2PDYrr VR128:$src)>;
4504 def : Pat<(int_x86_avx_cvtdq2_pd_256 (memopv4i32 addr:$src)),
4505            (VCVTDQ2PDYrm addr:$src)>;
4506
4507 def : Pat<(int_x86_avx_cvt_pd2dq_256 VR256:$src),
4508           (VCVTPD2DQYrr VR256:$src)>;
4509 def : Pat<(int_x86_avx_cvt_pd2dq_256 (memopv4f64 addr:$src)),
4510           (VCVTPD2DQYrm addr:$src)>;
4511
4512 def : Pat<(v4f64 (sint_to_fp (v4i32 VR128:$src))),
4513           (VCVTDQ2PDYrr VR128:$src)>;
4514 def : Pat<(v4f64 (sint_to_fp (memopv4i32 addr:$src))),
4515           (VCVTDQ2PDYrm addr:$src)>;
4516
4517 //===---------------------------------------------------------------------===//
4518 // SSE3 - Replicate Single FP - MOVSHDUP and MOVSLDUP
4519 //===---------------------------------------------------------------------===//
4520 multiclass sse3_replicate_sfp<bits<8> op, SDNode OpNode, string OpcodeStr,
4521                               ValueType vt, RegisterClass RC, PatFrag mem_frag,
4522                               X86MemOperand x86memop> {
4523 def rr : S3SI<op, MRMSrcReg, (outs RC:$dst), (ins RC:$src),
4524                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
4525                       [(set RC:$dst, (vt (OpNode RC:$src)))]>;
4526 def rm : S3SI<op, MRMSrcMem, (outs RC:$dst), (ins x86memop:$src),
4527                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
4528                       [(set RC:$dst, (OpNode (mem_frag addr:$src)))]>;
4529 }
4530
4531 let Predicates = [HasAVX] in {
4532   defm VMOVSHDUP  : sse3_replicate_sfp<0x16, X86Movshdup, "vmovshdup",
4533                                        v4f32, VR128, memopv4f32, f128mem>, VEX;
4534   defm VMOVSLDUP  : sse3_replicate_sfp<0x12, X86Movsldup, "vmovsldup",
4535                                        v4f32, VR128, memopv4f32, f128mem>, VEX;
4536   defm VMOVSHDUPY : sse3_replicate_sfp<0x16, X86Movshdup, "vmovshdup",
4537                                        v8f32, VR256, memopv8f32, f256mem>, VEX;
4538   defm VMOVSLDUPY : sse3_replicate_sfp<0x12, X86Movsldup, "vmovsldup",
4539                                        v8f32, VR256, memopv8f32, f256mem>, VEX;
4540 }
4541 defm MOVSHDUP : sse3_replicate_sfp<0x16, X86Movshdup, "movshdup", v4f32, VR128,
4542                                    memopv4f32, f128mem>;
4543 defm MOVSLDUP : sse3_replicate_sfp<0x12, X86Movsldup, "movsldup", v4f32, VR128,
4544                                    memopv4f32, f128mem>;
4545
4546 let Predicates = [HasSSE3] in {
4547   def : Pat<(v4i32 (X86Movshdup VR128:$src)),
4548             (MOVSHDUPrr VR128:$src)>;
4549   def : Pat<(v4i32 (X86Movshdup (bc_v4i32 (memopv2i64 addr:$src)))),
4550             (MOVSHDUPrm addr:$src)>;
4551   def : Pat<(v4i32 (X86Movsldup VR128:$src)),
4552             (MOVSLDUPrr VR128:$src)>;
4553   def : Pat<(v4i32 (X86Movsldup (bc_v4i32 (memopv2i64 addr:$src)))),
4554             (MOVSLDUPrm addr:$src)>;
4555 }
4556
4557 let Predicates = [HasAVX] in {
4558   def : Pat<(v4i32 (X86Movshdup VR128:$src)),
4559             (VMOVSHDUPrr VR128:$src)>;
4560   def : Pat<(v4i32 (X86Movshdup (bc_v4i32 (memopv2i64 addr:$src)))),
4561             (VMOVSHDUPrm addr:$src)>;
4562   def : Pat<(v4i32 (X86Movsldup VR128:$src)),
4563             (VMOVSLDUPrr VR128:$src)>;
4564   def : Pat<(v4i32 (X86Movsldup (bc_v4i32 (memopv2i64 addr:$src)))),
4565             (VMOVSLDUPrm addr:$src)>;
4566   def : Pat<(v8i32 (X86Movshdup VR256:$src)),
4567             (VMOVSHDUPYrr VR256:$src)>;
4568   def : Pat<(v8i32 (X86Movshdup (bc_v8i32 (memopv4i64 addr:$src)))),
4569             (VMOVSHDUPYrm addr:$src)>;
4570   def : Pat<(v8i32 (X86Movsldup VR256:$src)),
4571             (VMOVSLDUPYrr VR256:$src)>;
4572   def : Pat<(v8i32 (X86Movsldup (bc_v8i32 (memopv4i64 addr:$src)))),
4573             (VMOVSLDUPYrm addr:$src)>;
4574 }
4575
4576 //===---------------------------------------------------------------------===//
4577 // SSE3 - Replicate Double FP - MOVDDUP
4578 //===---------------------------------------------------------------------===//
4579
4580 multiclass sse3_replicate_dfp<string OpcodeStr> {
4581 def rr  : S3DI<0x12, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
4582                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
4583                     [(set VR128:$dst,(v2f64 (movddup VR128:$src, (undef))))]>;
4584 def rm  : S3DI<0x12, MRMSrcMem, (outs VR128:$dst), (ins f64mem:$src),
4585                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
4586                     [(set VR128:$dst,
4587                       (v2f64 (movddup (scalar_to_vector (loadf64 addr:$src)),
4588                                       (undef))))]>;
4589 }
4590
4591 // FIXME: Merge with above classe when there're patterns for the ymm version
4592 multiclass sse3_replicate_dfp_y<string OpcodeStr> {
4593 let Predicates = [HasAVX] in {
4594   def rr  : S3DI<0x12, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src),
4595                       !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
4596                       []>;
4597   def rm  : S3DI<0x12, MRMSrcMem, (outs VR256:$dst), (ins f256mem:$src),
4598                       !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
4599                       []>;
4600   }
4601 }
4602
4603 defm MOVDDUP : sse3_replicate_dfp<"movddup">;
4604 defm VMOVDDUP  : sse3_replicate_dfp<"vmovddup">, VEX;
4605 defm VMOVDDUPY : sse3_replicate_dfp_y<"vmovddup">, VEX;
4606
4607 let Predicates = [HasSSE3] in {
4608   def : Pat<(movddup (bc_v2f64 (v2i64 (scalar_to_vector (loadi64 addr:$src)))),
4609                    (undef)),
4610             (MOVDDUPrm addr:$src)>;
4611   let AddedComplexity = 5 in {
4612   def : Pat<(movddup (memopv2f64 addr:$src), (undef)), (MOVDDUPrm addr:$src)>;
4613   def : Pat<(movddup (bc_v4f32 (memopv2f64 addr:$src)), (undef)),
4614             (MOVDDUPrm addr:$src)>;
4615   def : Pat<(movddup (memopv2i64 addr:$src), (undef)), (MOVDDUPrm addr:$src)>;
4616   def : Pat<(movddup (bc_v4i32 (memopv2i64 addr:$src)), (undef)),
4617             (MOVDDUPrm addr:$src)>;
4618   }
4619   def : Pat<(X86Movddup (memopv2f64 addr:$src)),
4620             (MOVDDUPrm addr:$src)>;
4621   def : Pat<(X86Movddup (bc_v2f64 (memopv4f32 addr:$src))),
4622             (MOVDDUPrm addr:$src)>;
4623   def : Pat<(X86Movddup (bc_v2f64 (memopv2i64 addr:$src))),
4624             (MOVDDUPrm addr:$src)>;
4625   def : Pat<(X86Movddup (v2f64 (scalar_to_vector (loadf64 addr:$src)))),
4626             (MOVDDUPrm addr:$src)>;
4627   def : Pat<(X86Movddup (bc_v2f64
4628                              (v2i64 (scalar_to_vector (loadi64 addr:$src))))),
4629             (MOVDDUPrm addr:$src)>;
4630 }
4631
4632 let Predicates = [HasAVX] in {
4633   def : Pat<(movddup (bc_v2f64 (v2i64 (scalar_to_vector (loadi64 addr:$src)))),
4634                    (undef)),
4635             (VMOVDDUPrm addr:$src)>;
4636   let AddedComplexity = 5 in {
4637   def : Pat<(movddup (memopv2f64 addr:$src), (undef)), (VMOVDDUPrm addr:$src)>;
4638   def : Pat<(movddup (bc_v4f32 (memopv2f64 addr:$src)), (undef)),
4639             (VMOVDDUPrm addr:$src)>;
4640   def : Pat<(movddup (memopv2i64 addr:$src), (undef)), (VMOVDDUPrm addr:$src)>;
4641   def : Pat<(movddup (bc_v4i32 (memopv2i64 addr:$src)), (undef)),
4642             (VMOVDDUPrm addr:$src)>;
4643   }
4644   def : Pat<(X86Movddup (memopv2f64 addr:$src)),
4645             (VMOVDDUPrm addr:$src)>, Requires<[HasAVX]>;
4646   def : Pat<(X86Movddup (bc_v2f64 (memopv4f32 addr:$src))),
4647             (VMOVDDUPrm addr:$src)>, Requires<[HasAVX]>;
4648   def : Pat<(X86Movddup (bc_v2f64 (memopv2i64 addr:$src))),
4649             (VMOVDDUPrm addr:$src)>, Requires<[HasAVX]>;
4650   def : Pat<(X86Movddup (v2f64 (scalar_to_vector (loadf64 addr:$src)))),
4651             (VMOVDDUPrm addr:$src)>, Requires<[HasAVX]>;
4652   def : Pat<(X86Movddup (bc_v2f64
4653                              (v2i64 (scalar_to_vector (loadi64 addr:$src))))),
4654             (VMOVDDUPrm addr:$src)>, Requires<[HasAVX]>;
4655
4656   // 256-bit version
4657   def : Pat<(X86Movddup (memopv4f64 addr:$src)),
4658             (VMOVDDUPYrm addr:$src)>;
4659   def : Pat<(X86Movddup (memopv4i64 addr:$src)),
4660             (VMOVDDUPYrm addr:$src)>;
4661   def : Pat<(X86Movddup (v4f64 (scalar_to_vector (loadf64 addr:$src)))),
4662             (VMOVDDUPYrm addr:$src)>;
4663   def : Pat<(X86Movddup (v4i64 (scalar_to_vector (loadi64 addr:$src)))),
4664             (VMOVDDUPYrm addr:$src)>;
4665   def : Pat<(X86Movddup (v4f64 VR256:$src)),
4666             (VMOVDDUPYrr VR256:$src)>;
4667   def : Pat<(X86Movddup (v4i64 VR256:$src)),
4668             (VMOVDDUPYrr VR256:$src)>;
4669 }
4670
4671 //===---------------------------------------------------------------------===//
4672 // SSE3 - Move Unaligned Integer
4673 //===---------------------------------------------------------------------===//
4674
4675 let Predicates = [HasAVX] in {
4676   def VLDDQUrm : S3DI<0xF0, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
4677                    "vlddqu\t{$src, $dst|$dst, $src}",
4678                    [(set VR128:$dst, (int_x86_sse3_ldu_dq addr:$src))]>, VEX;
4679   def VLDDQUYrm : S3DI<0xF0, MRMSrcMem, (outs VR256:$dst), (ins i256mem:$src),
4680                    "vlddqu\t{$src, $dst|$dst, $src}",
4681                    [(set VR256:$dst, (int_x86_avx_ldu_dq_256 addr:$src))]>, VEX;
4682 }
4683 def LDDQUrm : S3DI<0xF0, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
4684                    "lddqu\t{$src, $dst|$dst, $src}",
4685                    [(set VR128:$dst, (int_x86_sse3_ldu_dq addr:$src))]>;
4686
4687 //===---------------------------------------------------------------------===//
4688 // SSE3 - Arithmetic
4689 //===---------------------------------------------------------------------===//
4690
4691 multiclass sse3_addsub<Intrinsic Int, string OpcodeStr, RegisterClass RC,
4692                        X86MemOperand x86memop, bit Is2Addr = 1> {
4693   def rr : I<0xD0, MRMSrcReg,
4694        (outs RC:$dst), (ins RC:$src1, RC:$src2),
4695        !if(Is2Addr,
4696            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
4697            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
4698        [(set RC:$dst, (Int RC:$src1, RC:$src2))]>;
4699   def rm : I<0xD0, MRMSrcMem,
4700        (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
4701        !if(Is2Addr,
4702            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
4703            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
4704        [(set RC:$dst, (Int RC:$src1, (memop addr:$src2)))]>;
4705 }
4706
4707 let Predicates = [HasAVX],
4708   ExeDomain = SSEPackedDouble in {
4709   defm VADDSUBPS : sse3_addsub<int_x86_sse3_addsub_ps, "vaddsubps", VR128,
4710                                f128mem, 0>, TB, XD, VEX_4V;
4711   defm VADDSUBPD : sse3_addsub<int_x86_sse3_addsub_pd, "vaddsubpd", VR128,
4712                                f128mem, 0>, TB, OpSize, VEX_4V;
4713   defm VADDSUBPSY : sse3_addsub<int_x86_avx_addsub_ps_256, "vaddsubps", VR256,
4714                                f256mem, 0>, TB, XD, VEX_4V;
4715   defm VADDSUBPDY : sse3_addsub<int_x86_avx_addsub_pd_256, "vaddsubpd", VR256,
4716                                f256mem, 0>, TB, OpSize, VEX_4V;
4717 }
4718 let Constraints = "$src1 = $dst", Predicates = [HasSSE3],
4719     ExeDomain = SSEPackedDouble in {
4720   defm ADDSUBPS : sse3_addsub<int_x86_sse3_addsub_ps, "addsubps", VR128,
4721                               f128mem>, TB, XD;
4722   defm ADDSUBPD : sse3_addsub<int_x86_sse3_addsub_pd, "addsubpd", VR128,
4723                               f128mem>, TB, OpSize;
4724 }
4725
4726 //===---------------------------------------------------------------------===//
4727 // SSE3 Instructions
4728 //===---------------------------------------------------------------------===//
4729
4730 // Horizontal ops
4731 multiclass S3D_Int<bits<8> o, string OpcodeStr, ValueType vt, RegisterClass RC,
4732                    X86MemOperand x86memop, Intrinsic IntId, bit Is2Addr = 1> {
4733   def rr : S3DI<o, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
4734        !if(Is2Addr,
4735          !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
4736          !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
4737       [(set RC:$dst, (vt (IntId RC:$src1, RC:$src2)))]>;
4738
4739   def rm : S3DI<o, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
4740        !if(Is2Addr,
4741          !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
4742          !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
4743       [(set RC:$dst, (vt (IntId RC:$src1, (memop addr:$src2))))]>;
4744 }
4745 multiclass S3_Int<bits<8> o, string OpcodeStr, ValueType vt, RegisterClass RC,
4746                   X86MemOperand x86memop, Intrinsic IntId, bit Is2Addr = 1> {
4747   def rr : S3I<o, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
4748        !if(Is2Addr,
4749          !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
4750          !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
4751       [(set RC:$dst, (vt (IntId RC:$src1, RC:$src2)))]>;
4752
4753   def rm : S3I<o, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
4754        !if(Is2Addr,
4755          !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
4756          !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
4757       [(set RC:$dst, (vt (IntId RC:$src1, (memop addr:$src2))))]>;
4758 }
4759
4760 let Predicates = [HasAVX] in {
4761   defm VHADDPS  : S3D_Int<0x7C, "vhaddps", v4f32, VR128, f128mem,
4762                           int_x86_sse3_hadd_ps, 0>, VEX_4V;
4763   defm VHADDPD  : S3_Int <0x7C, "vhaddpd", v2f64, VR128, f128mem,
4764                           int_x86_sse3_hadd_pd, 0>, VEX_4V;
4765   defm VHSUBPS  : S3D_Int<0x7D, "vhsubps", v4f32, VR128, f128mem,
4766                           int_x86_sse3_hsub_ps, 0>, VEX_4V;
4767   defm VHSUBPD  : S3_Int <0x7D, "vhsubpd", v2f64, VR128, f128mem,
4768                           int_x86_sse3_hsub_pd, 0>, VEX_4V;
4769   defm VHADDPSY : S3D_Int<0x7C, "vhaddps", v8f32, VR256, f256mem,
4770                           int_x86_avx_hadd_ps_256, 0>, VEX_4V;
4771   defm VHADDPDY : S3_Int <0x7C, "vhaddpd", v4f64, VR256, f256mem,
4772                           int_x86_avx_hadd_pd_256, 0>, VEX_4V;
4773   defm VHSUBPSY : S3D_Int<0x7D, "vhsubps", v8f32, VR256, f256mem,
4774                           int_x86_avx_hsub_ps_256, 0>, VEX_4V;
4775   defm VHSUBPDY : S3_Int <0x7D, "vhsubpd", v4f64, VR256, f256mem,
4776                           int_x86_avx_hsub_pd_256, 0>, VEX_4V;
4777 }
4778
4779 let Constraints = "$src1 = $dst" in {
4780   defm HADDPS : S3D_Int<0x7C, "haddps", v4f32, VR128, f128mem,
4781                         int_x86_sse3_hadd_ps>;
4782   defm HADDPD : S3_Int<0x7C, "haddpd", v2f64, VR128, f128mem,
4783                        int_x86_sse3_hadd_pd>;
4784   defm HSUBPS : S3D_Int<0x7D, "hsubps", v4f32, VR128, f128mem,
4785                         int_x86_sse3_hsub_ps>;
4786   defm HSUBPD : S3_Int<0x7D, "hsubpd", v2f64, VR128, f128mem,
4787                        int_x86_sse3_hsub_pd>;
4788 }
4789
4790 //===---------------------------------------------------------------------===//
4791 // SSSE3 - Packed Absolute Instructions
4792 //===---------------------------------------------------------------------===//
4793
4794
4795 /// SS3I_unop_rm_int - Simple SSSE3 unary op whose type can be v*{i8,i16,i32}.
4796 multiclass SS3I_unop_rm_int<bits<8> opc, string OpcodeStr,
4797                             PatFrag mem_frag128, Intrinsic IntId128> {
4798   def rr128 : SS38I<opc, MRMSrcReg, (outs VR128:$dst),
4799                     (ins VR128:$src),
4800                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
4801                     [(set VR128:$dst, (IntId128 VR128:$src))]>,
4802                     OpSize;
4803
4804   def rm128 : SS38I<opc, MRMSrcMem, (outs VR128:$dst),
4805                     (ins i128mem:$src),
4806                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
4807                     [(set VR128:$dst,
4808                       (IntId128
4809                        (bitconvert (mem_frag128 addr:$src))))]>, OpSize;
4810 }
4811
4812 let Predicates = [HasAVX] in {
4813   defm VPABSB  : SS3I_unop_rm_int<0x1C, "vpabsb", memopv16i8,
4814                                   int_x86_ssse3_pabs_b_128>, VEX;
4815   defm VPABSW  : SS3I_unop_rm_int<0x1D, "vpabsw", memopv8i16,
4816                                   int_x86_ssse3_pabs_w_128>, VEX;
4817   defm VPABSD  : SS3I_unop_rm_int<0x1E, "vpabsd", memopv4i32,
4818                                   int_x86_ssse3_pabs_d_128>, VEX;
4819 }
4820
4821 defm PABSB : SS3I_unop_rm_int<0x1C, "pabsb", memopv16i8,
4822                               int_x86_ssse3_pabs_b_128>;
4823 defm PABSW : SS3I_unop_rm_int<0x1D, "pabsw", memopv8i16,
4824                               int_x86_ssse3_pabs_w_128>;
4825 defm PABSD : SS3I_unop_rm_int<0x1E, "pabsd", memopv4i32,
4826                               int_x86_ssse3_pabs_d_128>;
4827
4828 //===---------------------------------------------------------------------===//
4829 // SSSE3 - Packed Binary Operator Instructions
4830 //===---------------------------------------------------------------------===//
4831
4832 /// SS3I_binop_rm_int - Simple SSSE3 bin op whose type can be v*{i8,i16,i32}.
4833 multiclass SS3I_binop_rm_int<bits<8> opc, string OpcodeStr,
4834                              PatFrag mem_frag128, Intrinsic IntId128,
4835                              bit Is2Addr = 1> {
4836   let isCommutable = 1 in
4837   def rr128 : SS38I<opc, MRMSrcReg, (outs VR128:$dst),
4838        (ins VR128:$src1, VR128:$src2),
4839        !if(Is2Addr,
4840          !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
4841          !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
4842        [(set VR128:$dst, (IntId128 VR128:$src1, VR128:$src2))]>,
4843        OpSize;
4844   def rm128 : SS38I<opc, MRMSrcMem, (outs VR128:$dst),
4845        (ins VR128:$src1, i128mem:$src2),
4846        !if(Is2Addr,
4847          !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
4848          !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
4849        [(set VR128:$dst,
4850          (IntId128 VR128:$src1,
4851           (bitconvert (memopv16i8 addr:$src2))))]>, OpSize;
4852 }
4853
4854 let Predicates = [HasAVX] in {
4855 let isCommutable = 0 in {
4856   defm VPHADDW    : SS3I_binop_rm_int<0x01, "vphaddw", memopv8i16,
4857                                       int_x86_ssse3_phadd_w_128, 0>, VEX_4V;
4858   defm VPHADDD    : SS3I_binop_rm_int<0x02, "vphaddd", memopv4i32,
4859                                       int_x86_ssse3_phadd_d_128, 0>, VEX_4V;
4860   defm VPHADDSW   : SS3I_binop_rm_int<0x03, "vphaddsw", memopv8i16,
4861                                       int_x86_ssse3_phadd_sw_128, 0>, VEX_4V;
4862   defm VPHSUBW    : SS3I_binop_rm_int<0x05, "vphsubw", memopv8i16,
4863                                       int_x86_ssse3_phsub_w_128, 0>, VEX_4V;
4864   defm VPHSUBD    : SS3I_binop_rm_int<0x06, "vphsubd", memopv4i32,
4865                                       int_x86_ssse3_phsub_d_128, 0>, VEX_4V;
4866   defm VPHSUBSW   : SS3I_binop_rm_int<0x07, "vphsubsw", memopv8i16,
4867                                       int_x86_ssse3_phsub_sw_128, 0>, VEX_4V;
4868   defm VPMADDUBSW : SS3I_binop_rm_int<0x04, "vpmaddubsw", memopv16i8,
4869                                       int_x86_ssse3_pmadd_ub_sw_128, 0>, VEX_4V;
4870   defm VPSHUFB    : SS3I_binop_rm_int<0x00, "vpshufb", memopv16i8,
4871                                       int_x86_ssse3_pshuf_b_128, 0>, VEX_4V;
4872   defm VPSIGNB    : SS3I_binop_rm_int<0x08, "vpsignb", memopv16i8,
4873                                       int_x86_ssse3_psign_b_128, 0>, VEX_4V;
4874   defm VPSIGNW    : SS3I_binop_rm_int<0x09, "vpsignw", memopv8i16,
4875                                       int_x86_ssse3_psign_w_128, 0>, VEX_4V;
4876   defm VPSIGND    : SS3I_binop_rm_int<0x0A, "vpsignd", memopv4i32,
4877                                       int_x86_ssse3_psign_d_128, 0>, VEX_4V;
4878 }
4879 defm VPMULHRSW    : SS3I_binop_rm_int<0x0B, "vpmulhrsw", memopv8i16,
4880                                       int_x86_ssse3_pmul_hr_sw_128, 0>, VEX_4V;
4881 }
4882
4883 // None of these have i8 immediate fields.
4884 let ImmT = NoImm, Constraints = "$src1 = $dst" in {
4885 let isCommutable = 0 in {
4886   defm PHADDW    : SS3I_binop_rm_int<0x01, "phaddw", memopv8i16,
4887                                      int_x86_ssse3_phadd_w_128>;
4888   defm PHADDD    : SS3I_binop_rm_int<0x02, "phaddd", memopv4i32,
4889                                      int_x86_ssse3_phadd_d_128>;
4890   defm PHADDSW   : SS3I_binop_rm_int<0x03, "phaddsw", memopv8i16,
4891                                      int_x86_ssse3_phadd_sw_128>;
4892   defm PHSUBW    : SS3I_binop_rm_int<0x05, "phsubw", memopv8i16,
4893                                      int_x86_ssse3_phsub_w_128>;
4894   defm PHSUBD    : SS3I_binop_rm_int<0x06, "phsubd", memopv4i32,
4895                                      int_x86_ssse3_phsub_d_128>;
4896   defm PHSUBSW   : SS3I_binop_rm_int<0x07, "phsubsw", memopv8i16,
4897                                      int_x86_ssse3_phsub_sw_128>;
4898   defm PMADDUBSW : SS3I_binop_rm_int<0x04, "pmaddubsw", memopv16i8,
4899                                      int_x86_ssse3_pmadd_ub_sw_128>;
4900   defm PSHUFB    : SS3I_binop_rm_int<0x00, "pshufb", memopv16i8,
4901                                      int_x86_ssse3_pshuf_b_128>;
4902   defm PSIGNB    : SS3I_binop_rm_int<0x08, "psignb", memopv16i8,
4903                                      int_x86_ssse3_psign_b_128>;
4904   defm PSIGNW    : SS3I_binop_rm_int<0x09, "psignw", memopv8i16,
4905                                      int_x86_ssse3_psign_w_128>;
4906   defm PSIGND    : SS3I_binop_rm_int<0x0A, "psignd", memopv4i32,
4907                                        int_x86_ssse3_psign_d_128>;
4908 }
4909 defm PMULHRSW    : SS3I_binop_rm_int<0x0B, "pmulhrsw", memopv8i16,
4910                                      int_x86_ssse3_pmul_hr_sw_128>;
4911 }
4912
4913 let Predicates = [HasSSSE3] in {
4914   def : Pat<(X86pshufb VR128:$src, VR128:$mask),
4915             (PSHUFBrr128 VR128:$src, VR128:$mask)>;
4916   def : Pat<(X86pshufb VR128:$src, (bc_v16i8 (memopv2i64 addr:$mask))),
4917             (PSHUFBrm128 VR128:$src, addr:$mask)>;
4918
4919   def : Pat<(X86psignb VR128:$src1, VR128:$src2),
4920             (PSIGNBrr128 VR128:$src1, VR128:$src2)>;
4921   def : Pat<(X86psignw VR128:$src1, VR128:$src2),
4922             (PSIGNWrr128 VR128:$src1, VR128:$src2)>;
4923   def : Pat<(X86psignd VR128:$src1, VR128:$src2),
4924             (PSIGNDrr128 VR128:$src1, VR128:$src2)>;
4925 }
4926
4927 let Predicates = [HasAVX] in {
4928   def : Pat<(X86pshufb VR128:$src, VR128:$mask),
4929             (VPSHUFBrr128 VR128:$src, VR128:$mask)>;
4930   def : Pat<(X86pshufb VR128:$src, (bc_v16i8 (memopv2i64 addr:$mask))),
4931             (VPSHUFBrm128 VR128:$src, addr:$mask)>;
4932
4933   def : Pat<(X86psignb VR128:$src1, VR128:$src2),
4934             (VPSIGNBrr128 VR128:$src1, VR128:$src2)>;
4935   def : Pat<(X86psignw VR128:$src1, VR128:$src2),
4936             (VPSIGNWrr128 VR128:$src1, VR128:$src2)>;
4937   def : Pat<(X86psignd VR128:$src1, VR128:$src2),
4938             (VPSIGNDrr128 VR128:$src1, VR128:$src2)>;
4939 }
4940
4941 //===---------------------------------------------------------------------===//
4942 // SSSE3 - Packed Align Instruction Patterns
4943 //===---------------------------------------------------------------------===//
4944
4945 multiclass ssse3_palign<string asm, bit Is2Addr = 1> {
4946   def R128rr : SS3AI<0x0F, MRMSrcReg, (outs VR128:$dst),
4947       (ins VR128:$src1, VR128:$src2, i8imm:$src3),
4948       !if(Is2Addr,
4949         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
4950         !strconcat(asm,
4951                   "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
4952       []>, OpSize;
4953   def R128rm : SS3AI<0x0F, MRMSrcMem, (outs VR128:$dst),
4954       (ins VR128:$src1, i128mem:$src2, i8imm:$src3),
4955       !if(Is2Addr,
4956         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
4957         !strconcat(asm,
4958                   "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
4959       []>, OpSize;
4960 }
4961
4962 let Predicates = [HasAVX] in
4963   defm VPALIGN : ssse3_palign<"vpalignr", 0>, VEX_4V;
4964 let Constraints = "$src1 = $dst", Predicates = [HasSSSE3] in
4965   defm PALIGN : ssse3_palign<"palignr">;
4966
4967 let Predicates = [HasSSSE3] in {
4968 def : Pat<(v4i32 (X86PAlign VR128:$src1, VR128:$src2, (i8 imm:$imm))),
4969           (PALIGNR128rr VR128:$src2, VR128:$src1, imm:$imm)>;
4970 def : Pat<(v4f32 (X86PAlign VR128:$src1, VR128:$src2, (i8 imm:$imm))),
4971           (PALIGNR128rr VR128:$src2, VR128:$src1, imm:$imm)>;
4972 def : Pat<(v8i16 (X86PAlign VR128:$src1, VR128:$src2, (i8 imm:$imm))),
4973           (PALIGNR128rr VR128:$src2, VR128:$src1, imm:$imm)>;
4974 def : Pat<(v16i8 (X86PAlign VR128:$src1, VR128:$src2, (i8 imm:$imm))),
4975           (PALIGNR128rr VR128:$src2, VR128:$src1, imm:$imm)>;
4976 }
4977
4978 let Predicates = [HasAVX] in {
4979 def : Pat<(v4i32 (X86PAlign VR128:$src1, VR128:$src2, (i8 imm:$imm))),
4980           (VPALIGNR128rr VR128:$src2, VR128:$src1, imm:$imm)>;
4981 def : Pat<(v4f32 (X86PAlign VR128:$src1, VR128:$src2, (i8 imm:$imm))),
4982           (VPALIGNR128rr VR128:$src2, VR128:$src1, imm:$imm)>;
4983 def : Pat<(v8i16 (X86PAlign VR128:$src1, VR128:$src2, (i8 imm:$imm))),
4984           (VPALIGNR128rr VR128:$src2, VR128:$src1, imm:$imm)>;
4985 def : Pat<(v16i8 (X86PAlign VR128:$src1, VR128:$src2, (i8 imm:$imm))),
4986           (VPALIGNR128rr VR128:$src2, VR128:$src1, imm:$imm)>;
4987 }
4988
4989 //===---------------------------------------------------------------------===//
4990 // SSSE3 - Thread synchronization
4991 //===---------------------------------------------------------------------===//
4992
4993 let usesCustomInserter = 1 in {
4994 def MONITOR : PseudoI<(outs), (ins i32mem:$src1, GR32:$src2, GR32:$src3),
4995                 [(int_x86_sse3_monitor addr:$src1, GR32:$src2, GR32:$src3)]>;
4996 def MWAIT : PseudoI<(outs), (ins GR32:$src1, GR32:$src2),
4997                 [(int_x86_sse3_mwait GR32:$src1, GR32:$src2)]>;
4998 }
4999
5000 let Uses = [EAX, ECX, EDX] in
5001 def MONITORrrr : I<0x01, MRM_C8, (outs), (ins), "monitor", []>, TB,
5002                  Requires<[HasSSE3]>;
5003 let Uses = [ECX, EAX] in
5004 def MWAITrr   : I<0x01, MRM_C9, (outs), (ins), "mwait", []>, TB,
5005                 Requires<[HasSSE3]>;
5006
5007 def : InstAlias<"mwait %eax, %ecx", (MWAITrr)>, Requires<[In32BitMode]>;
5008 def : InstAlias<"mwait %rax, %rcx", (MWAITrr)>, Requires<[In64BitMode]>;
5009
5010 def : InstAlias<"monitor %eax, %ecx, %edx", (MONITORrrr)>,
5011       Requires<[In32BitMode]>;
5012 def : InstAlias<"monitor %rax, %rcx, %rdx", (MONITORrrr)>,
5013       Requires<[In64BitMode]>;
5014
5015 //===----------------------------------------------------------------------===//
5016 // SSE4.1 - Packed Move with Sign/Zero Extend
5017 //===----------------------------------------------------------------------===//
5018
5019 multiclass SS41I_binop_rm_int8<bits<8> opc, string OpcodeStr, Intrinsic IntId> {
5020   def rr : SS48I<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
5021                  !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5022                  [(set VR128:$dst, (IntId VR128:$src))]>, OpSize;
5023
5024   def rm : SS48I<opc, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
5025                  !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5026        [(set VR128:$dst,
5027          (IntId (bitconvert (v2i64 (scalar_to_vector (loadi64 addr:$src))))))]>,
5028        OpSize;
5029 }
5030
5031 let Predicates = [HasAVX] in {
5032 defm VPMOVSXBW : SS41I_binop_rm_int8<0x20, "vpmovsxbw", int_x86_sse41_pmovsxbw>,
5033                                      VEX;
5034 defm VPMOVSXWD : SS41I_binop_rm_int8<0x23, "vpmovsxwd", int_x86_sse41_pmovsxwd>,
5035                                      VEX;
5036 defm VPMOVSXDQ : SS41I_binop_rm_int8<0x25, "vpmovsxdq", int_x86_sse41_pmovsxdq>,
5037                                      VEX;
5038 defm VPMOVZXBW : SS41I_binop_rm_int8<0x30, "vpmovzxbw", int_x86_sse41_pmovzxbw>,
5039                                      VEX;
5040 defm VPMOVZXWD : SS41I_binop_rm_int8<0x33, "vpmovzxwd", int_x86_sse41_pmovzxwd>,
5041                                      VEX;
5042 defm VPMOVZXDQ : SS41I_binop_rm_int8<0x35, "vpmovzxdq", int_x86_sse41_pmovzxdq>,
5043                                      VEX;
5044 }
5045
5046 defm PMOVSXBW   : SS41I_binop_rm_int8<0x20, "pmovsxbw", int_x86_sse41_pmovsxbw>;
5047 defm PMOVSXWD   : SS41I_binop_rm_int8<0x23, "pmovsxwd", int_x86_sse41_pmovsxwd>;
5048 defm PMOVSXDQ   : SS41I_binop_rm_int8<0x25, "pmovsxdq", int_x86_sse41_pmovsxdq>;
5049 defm PMOVZXBW   : SS41I_binop_rm_int8<0x30, "pmovzxbw", int_x86_sse41_pmovzxbw>;
5050 defm PMOVZXWD   : SS41I_binop_rm_int8<0x33, "pmovzxwd", int_x86_sse41_pmovzxwd>;
5051 defm PMOVZXDQ   : SS41I_binop_rm_int8<0x35, "pmovzxdq", int_x86_sse41_pmovzxdq>;
5052
5053 let Predicates = [HasSSE41] in {
5054   // Common patterns involving scalar load.
5055   def : Pat<(int_x86_sse41_pmovsxbw (vzmovl_v2i64 addr:$src)),
5056             (PMOVSXBWrm addr:$src)>;
5057   def : Pat<(int_x86_sse41_pmovsxbw (vzload_v2i64 addr:$src)),
5058             (PMOVSXBWrm addr:$src)>;
5059
5060   def : Pat<(int_x86_sse41_pmovsxwd (vzmovl_v2i64 addr:$src)),
5061             (PMOVSXWDrm addr:$src)>;
5062   def : Pat<(int_x86_sse41_pmovsxwd (vzload_v2i64 addr:$src)),
5063             (PMOVSXWDrm addr:$src)>;
5064
5065   def : Pat<(int_x86_sse41_pmovsxdq (vzmovl_v2i64 addr:$src)),
5066             (PMOVSXDQrm addr:$src)>;
5067   def : Pat<(int_x86_sse41_pmovsxdq (vzload_v2i64 addr:$src)),
5068             (PMOVSXDQrm addr:$src)>;
5069
5070   def : Pat<(int_x86_sse41_pmovzxbw (vzmovl_v2i64 addr:$src)),
5071             (PMOVZXBWrm addr:$src)>;
5072   def : Pat<(int_x86_sse41_pmovzxbw (vzload_v2i64 addr:$src)),
5073             (PMOVZXBWrm addr:$src)>;
5074
5075   def : Pat<(int_x86_sse41_pmovzxwd (vzmovl_v2i64 addr:$src)),
5076             (PMOVZXWDrm addr:$src)>;
5077   def : Pat<(int_x86_sse41_pmovzxwd (vzload_v2i64 addr:$src)),
5078             (PMOVZXWDrm addr:$src)>;
5079
5080   def : Pat<(int_x86_sse41_pmovzxdq (vzmovl_v2i64 addr:$src)),
5081             (PMOVZXDQrm addr:$src)>;
5082   def : Pat<(int_x86_sse41_pmovzxdq (vzload_v2i64 addr:$src)),
5083             (PMOVZXDQrm addr:$src)>;
5084 }
5085
5086 let Predicates = [HasAVX] in {
5087   // Common patterns involving scalar load.
5088   def : Pat<(int_x86_sse41_pmovsxbw (vzmovl_v2i64 addr:$src)),
5089             (VPMOVSXBWrm addr:$src)>;
5090   def : Pat<(int_x86_sse41_pmovsxbw (vzload_v2i64 addr:$src)),
5091             (VPMOVSXBWrm addr:$src)>;
5092
5093   def : Pat<(int_x86_sse41_pmovsxwd (vzmovl_v2i64 addr:$src)),
5094             (VPMOVSXWDrm addr:$src)>;
5095   def : Pat<(int_x86_sse41_pmovsxwd (vzload_v2i64 addr:$src)),
5096             (VPMOVSXWDrm addr:$src)>;
5097
5098   def : Pat<(int_x86_sse41_pmovsxdq (vzmovl_v2i64 addr:$src)),
5099             (VPMOVSXDQrm addr:$src)>;
5100   def : Pat<(int_x86_sse41_pmovsxdq (vzload_v2i64 addr:$src)),
5101             (VPMOVSXDQrm addr:$src)>;
5102
5103   def : Pat<(int_x86_sse41_pmovzxbw (vzmovl_v2i64 addr:$src)),
5104             (VPMOVZXBWrm addr:$src)>;
5105   def : Pat<(int_x86_sse41_pmovzxbw (vzload_v2i64 addr:$src)),
5106             (VPMOVZXBWrm addr:$src)>;
5107
5108   def : Pat<(int_x86_sse41_pmovzxwd (vzmovl_v2i64 addr:$src)),
5109             (VPMOVZXWDrm addr:$src)>;
5110   def : Pat<(int_x86_sse41_pmovzxwd (vzload_v2i64 addr:$src)),
5111             (VPMOVZXWDrm addr:$src)>;
5112
5113   def : Pat<(int_x86_sse41_pmovzxdq (vzmovl_v2i64 addr:$src)),
5114             (VPMOVZXDQrm addr:$src)>;
5115   def : Pat<(int_x86_sse41_pmovzxdq (vzload_v2i64 addr:$src)),
5116             (VPMOVZXDQrm addr:$src)>;
5117 }
5118
5119
5120 multiclass SS41I_binop_rm_int4<bits<8> opc, string OpcodeStr, Intrinsic IntId> {
5121   def rr : SS48I<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
5122                  !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5123                  [(set VR128:$dst, (IntId VR128:$src))]>, OpSize;
5124
5125   def rm : SS48I<opc, MRMSrcMem, (outs VR128:$dst), (ins i32mem:$src),
5126                  !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5127        [(set VR128:$dst,
5128          (IntId (bitconvert (v4i32 (scalar_to_vector (loadi32 addr:$src))))))]>,
5129           OpSize;
5130 }
5131
5132 let Predicates = [HasAVX] in {
5133 defm VPMOVSXBD : SS41I_binop_rm_int4<0x21, "vpmovsxbd", int_x86_sse41_pmovsxbd>,
5134                                      VEX;
5135 defm VPMOVSXWQ : SS41I_binop_rm_int4<0x24, "vpmovsxwq", int_x86_sse41_pmovsxwq>,
5136                                      VEX;
5137 defm VPMOVZXBD : SS41I_binop_rm_int4<0x31, "vpmovzxbd", int_x86_sse41_pmovzxbd>,
5138                                      VEX;
5139 defm VPMOVZXWQ : SS41I_binop_rm_int4<0x34, "vpmovzxwq", int_x86_sse41_pmovzxwq>,
5140                                      VEX;
5141 }
5142
5143 defm PMOVSXBD   : SS41I_binop_rm_int4<0x21, "pmovsxbd", int_x86_sse41_pmovsxbd>;
5144 defm PMOVSXWQ   : SS41I_binop_rm_int4<0x24, "pmovsxwq", int_x86_sse41_pmovsxwq>;
5145 defm PMOVZXBD   : SS41I_binop_rm_int4<0x31, "pmovzxbd", int_x86_sse41_pmovzxbd>;
5146 defm PMOVZXWQ   : SS41I_binop_rm_int4<0x34, "pmovzxwq", int_x86_sse41_pmovzxwq>;
5147
5148 let Predicates = [HasSSE41] in {
5149   // Common patterns involving scalar load
5150   def : Pat<(int_x86_sse41_pmovsxbd (vzmovl_v4i32 addr:$src)),
5151             (PMOVSXBDrm addr:$src)>;
5152   def : Pat<(int_x86_sse41_pmovsxwq (vzmovl_v4i32 addr:$src)),
5153             (PMOVSXWQrm addr:$src)>;
5154
5155   def : Pat<(int_x86_sse41_pmovzxbd (vzmovl_v4i32 addr:$src)),
5156             (PMOVZXBDrm addr:$src)>;
5157   def : Pat<(int_x86_sse41_pmovzxwq (vzmovl_v4i32 addr:$src)),
5158             (PMOVZXWQrm addr:$src)>;
5159 }
5160
5161 let Predicates = [HasAVX] in {
5162   // Common patterns involving scalar load
5163   def : Pat<(int_x86_sse41_pmovsxbd (vzmovl_v4i32 addr:$src)),
5164             (VPMOVSXBDrm addr:$src)>;
5165   def : Pat<(int_x86_sse41_pmovsxwq (vzmovl_v4i32 addr:$src)),
5166             (VPMOVSXWQrm addr:$src)>;
5167
5168   def : Pat<(int_x86_sse41_pmovzxbd (vzmovl_v4i32 addr:$src)),
5169             (VPMOVZXBDrm addr:$src)>;
5170   def : Pat<(int_x86_sse41_pmovzxwq (vzmovl_v4i32 addr:$src)),
5171             (VPMOVZXWQrm addr:$src)>;
5172 }
5173
5174 multiclass SS41I_binop_rm_int2<bits<8> opc, string OpcodeStr, Intrinsic IntId> {
5175   def rr : SS48I<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
5176                  !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5177                  [(set VR128:$dst, (IntId VR128:$src))]>, OpSize;
5178
5179   // Expecting a i16 load any extended to i32 value.
5180   def rm : SS48I<opc, MRMSrcMem, (outs VR128:$dst), (ins i16mem:$src),
5181                  !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5182                  [(set VR128:$dst, (IntId (bitconvert
5183                      (v4i32 (scalar_to_vector (loadi16_anyext addr:$src))))))]>,
5184                  OpSize;
5185 }
5186
5187 let Predicates = [HasAVX] in {
5188 defm VPMOVSXBQ : SS41I_binop_rm_int2<0x22, "vpmovsxbq", int_x86_sse41_pmovsxbq>,
5189                                      VEX;
5190 defm VPMOVZXBQ : SS41I_binop_rm_int2<0x32, "vpmovzxbq", int_x86_sse41_pmovzxbq>,
5191                                      VEX;
5192 }
5193 defm PMOVSXBQ   : SS41I_binop_rm_int2<0x22, "pmovsxbq", int_x86_sse41_pmovsxbq>;
5194 defm PMOVZXBQ   : SS41I_binop_rm_int2<0x32, "pmovzxbq", int_x86_sse41_pmovzxbq>;
5195
5196 let Predicates = [HasSSE41] in {
5197   // Common patterns involving scalar load
5198   def : Pat<(int_x86_sse41_pmovsxbq
5199               (bitconvert (v4i32 (X86vzmovl
5200                             (v4i32 (scalar_to_vector (loadi32 addr:$src))))))),
5201             (PMOVSXBQrm addr:$src)>;
5202
5203   def : Pat<(int_x86_sse41_pmovzxbq
5204               (bitconvert (v4i32 (X86vzmovl
5205                             (v4i32 (scalar_to_vector (loadi32 addr:$src))))))),
5206             (PMOVZXBQrm addr:$src)>;
5207 }
5208
5209 let Predicates = [HasAVX] in {
5210   // Common patterns involving scalar load
5211   def : Pat<(int_x86_sse41_pmovsxbq
5212               (bitconvert (v4i32 (X86vzmovl
5213                             (v4i32 (scalar_to_vector (loadi32 addr:$src))))))),
5214             (VPMOVSXBQrm addr:$src)>;
5215
5216   def : Pat<(int_x86_sse41_pmovzxbq
5217               (bitconvert (v4i32 (X86vzmovl
5218                             (v4i32 (scalar_to_vector (loadi32 addr:$src))))))),
5219             (VPMOVZXBQrm addr:$src)>;
5220 }
5221
5222 //===----------------------------------------------------------------------===//
5223 // SSE4.1 - Extract Instructions
5224 //===----------------------------------------------------------------------===//
5225
5226 /// SS41I_binop_ext8 - SSE 4.1 extract 8 bits to 32 bit reg or 8 bit mem
5227 multiclass SS41I_extract8<bits<8> opc, string OpcodeStr> {
5228   def rr : SS4AIi8<opc, MRMDestReg, (outs GR32:$dst),
5229                  (ins VR128:$src1, i32i8imm:$src2),
5230                  !strconcat(OpcodeStr,
5231                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5232                  [(set GR32:$dst, (X86pextrb (v16i8 VR128:$src1), imm:$src2))]>,
5233                  OpSize;
5234   def mr : SS4AIi8<opc, MRMDestMem, (outs),
5235                  (ins i8mem:$dst, VR128:$src1, i32i8imm:$src2),
5236                  !strconcat(OpcodeStr,
5237                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5238                  []>, OpSize;
5239 // FIXME:
5240 // There's an AssertZext in the way of writing the store pattern
5241 // (store (i8 (trunc (X86pextrb (v16i8 VR128:$src1), imm:$src2))), addr:$dst)
5242 }
5243
5244 let Predicates = [HasAVX] in {
5245   defm VPEXTRB : SS41I_extract8<0x14, "vpextrb">, VEX;
5246   def  VPEXTRBrr64 : SS4AIi8<0x14, MRMDestReg, (outs GR64:$dst),
5247          (ins VR128:$src1, i32i8imm:$src2),
5248          "vpextrb\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>, OpSize, VEX;
5249 }
5250
5251 defm PEXTRB      : SS41I_extract8<0x14, "pextrb">;
5252
5253
5254 /// SS41I_extract16 - SSE 4.1 extract 16 bits to memory destination
5255 multiclass SS41I_extract16<bits<8> opc, string OpcodeStr> {
5256   def mr : SS4AIi8<opc, MRMDestMem, (outs),
5257                  (ins i16mem:$dst, VR128:$src1, i32i8imm:$src2),
5258                  !strconcat(OpcodeStr,
5259                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5260                  []>, OpSize;
5261 // FIXME:
5262 // There's an AssertZext in the way of writing the store pattern
5263 // (store (i16 (trunc (X86pextrw (v16i8 VR128:$src1), imm:$src2))), addr:$dst)
5264 }
5265
5266 let Predicates = [HasAVX] in
5267   defm VPEXTRW : SS41I_extract16<0x15, "vpextrw">, VEX;
5268
5269 defm PEXTRW      : SS41I_extract16<0x15, "pextrw">;
5270
5271
5272 /// SS41I_extract32 - SSE 4.1 extract 32 bits to int reg or memory destination
5273 multiclass SS41I_extract32<bits<8> opc, string OpcodeStr> {
5274   def rr : SS4AIi8<opc, MRMDestReg, (outs GR32:$dst),
5275                  (ins VR128:$src1, i32i8imm:$src2),
5276                  !strconcat(OpcodeStr,
5277                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5278                  [(set GR32:$dst,
5279                   (extractelt (v4i32 VR128:$src1), imm:$src2))]>, OpSize;
5280   def mr : SS4AIi8<opc, MRMDestMem, (outs),
5281                  (ins i32mem:$dst, VR128:$src1, i32i8imm:$src2),
5282                  !strconcat(OpcodeStr,
5283                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5284                  [(store (extractelt (v4i32 VR128:$src1), imm:$src2),
5285                           addr:$dst)]>, OpSize;
5286 }
5287
5288 let Predicates = [HasAVX] in
5289   defm VPEXTRD : SS41I_extract32<0x16, "vpextrd">, VEX;
5290
5291 defm PEXTRD      : SS41I_extract32<0x16, "pextrd">;
5292
5293 /// SS41I_extract32 - SSE 4.1 extract 32 bits to int reg or memory destination
5294 multiclass SS41I_extract64<bits<8> opc, string OpcodeStr> {
5295   def rr : SS4AIi8<opc, MRMDestReg, (outs GR64:$dst),
5296                  (ins VR128:$src1, i32i8imm:$src2),
5297                  !strconcat(OpcodeStr,
5298                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5299                  [(set GR64:$dst,
5300                   (extractelt (v2i64 VR128:$src1), imm:$src2))]>, OpSize, REX_W;
5301   def mr : SS4AIi8<opc, MRMDestMem, (outs),
5302                  (ins i64mem:$dst, VR128:$src1, i32i8imm:$src2),
5303                  !strconcat(OpcodeStr,
5304                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5305                  [(store (extractelt (v2i64 VR128:$src1), imm:$src2),
5306                           addr:$dst)]>, OpSize, REX_W;
5307 }
5308
5309 let Predicates = [HasAVX] in
5310   defm VPEXTRQ : SS41I_extract64<0x16, "vpextrq">, VEX, VEX_W;
5311
5312 defm PEXTRQ      : SS41I_extract64<0x16, "pextrq">;
5313
5314 /// SS41I_extractf32 - SSE 4.1 extract 32 bits fp value to int reg or memory
5315 /// destination
5316 multiclass SS41I_extractf32<bits<8> opc, string OpcodeStr> {
5317   def rr : SS4AIi8<opc, MRMDestReg, (outs GR32:$dst),
5318                  (ins VR128:$src1, i32i8imm:$src2),
5319                  !strconcat(OpcodeStr,
5320                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5321                  [(set GR32:$dst,
5322                     (extractelt (bc_v4i32 (v4f32 VR128:$src1)), imm:$src2))]>,
5323            OpSize;
5324   def mr : SS4AIi8<opc, MRMDestMem, (outs),
5325                  (ins f32mem:$dst, VR128:$src1, i32i8imm:$src2),
5326                  !strconcat(OpcodeStr,
5327                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5328                  [(store (extractelt (bc_v4i32 (v4f32 VR128:$src1)), imm:$src2),
5329                           addr:$dst)]>, OpSize;
5330 }
5331
5332 let Predicates = [HasAVX] in {
5333   defm VEXTRACTPS : SS41I_extractf32<0x17, "vextractps">, VEX;
5334   def VEXTRACTPSrr64 : SS4AIi8<0x17, MRMDestReg, (outs GR64:$dst),
5335                   (ins VR128:$src1, i32i8imm:$src2),
5336                   "vextractps \t{$src2, $src1, $dst|$dst, $src1, $src2}",
5337                   []>, OpSize, VEX;
5338 }
5339 defm EXTRACTPS   : SS41I_extractf32<0x17, "extractps">;
5340
5341 // Also match an EXTRACTPS store when the store is done as f32 instead of i32.
5342 def : Pat<(store (f32 (bitconvert (extractelt (bc_v4i32 (v4f32 VR128:$src1)),
5343                                               imm:$src2))),
5344                  addr:$dst),
5345           (EXTRACTPSmr addr:$dst, VR128:$src1, imm:$src2)>,
5346           Requires<[HasSSE41]>;
5347 def : Pat<(store (f32 (bitconvert (extractelt (bc_v4i32 (v4f32 VR128:$src1)),
5348                                               imm:$src2))),
5349                  addr:$dst),
5350           (VEXTRACTPSmr addr:$dst, VR128:$src1, imm:$src2)>,
5351           Requires<[HasAVX]>;
5352
5353 //===----------------------------------------------------------------------===//
5354 // SSE4.1 - Insert Instructions
5355 //===----------------------------------------------------------------------===//
5356
5357 multiclass SS41I_insert8<bits<8> opc, string asm, bit Is2Addr = 1> {
5358   def rr : SS4AIi8<opc, MRMSrcReg, (outs VR128:$dst),
5359       (ins VR128:$src1, GR32:$src2, i32i8imm:$src3),
5360       !if(Is2Addr,
5361         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5362         !strconcat(asm,
5363                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5364       [(set VR128:$dst,
5365         (X86pinsrb VR128:$src1, GR32:$src2, imm:$src3))]>, OpSize;
5366   def rm : SS4AIi8<opc, MRMSrcMem, (outs VR128:$dst),
5367       (ins VR128:$src1, i8mem:$src2, i32i8imm:$src3),
5368       !if(Is2Addr,
5369         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5370         !strconcat(asm,
5371                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5372       [(set VR128:$dst,
5373         (X86pinsrb VR128:$src1, (extloadi8 addr:$src2),
5374                    imm:$src3))]>, OpSize;
5375 }
5376
5377 let Predicates = [HasAVX] in
5378   defm VPINSRB : SS41I_insert8<0x20, "vpinsrb", 0>, VEX_4V;
5379 let Constraints = "$src1 = $dst" in
5380   defm PINSRB  : SS41I_insert8<0x20, "pinsrb">;
5381
5382 multiclass SS41I_insert32<bits<8> opc, string asm, bit Is2Addr = 1> {
5383   def rr : SS4AIi8<opc, MRMSrcReg, (outs VR128:$dst),
5384       (ins VR128:$src1, GR32:$src2, i32i8imm:$src3),
5385       !if(Is2Addr,
5386         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5387         !strconcat(asm,
5388                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5389       [(set VR128:$dst,
5390         (v4i32 (insertelt VR128:$src1, GR32:$src2, imm:$src3)))]>,
5391       OpSize;
5392   def rm : SS4AIi8<opc, MRMSrcMem, (outs VR128:$dst),
5393       (ins VR128:$src1, i32mem:$src2, i32i8imm:$src3),
5394       !if(Is2Addr,
5395         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5396         !strconcat(asm,
5397                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5398       [(set VR128:$dst,
5399         (v4i32 (insertelt VR128:$src1, (loadi32 addr:$src2),
5400                           imm:$src3)))]>, OpSize;
5401 }
5402
5403 let Predicates = [HasAVX] in
5404   defm VPINSRD : SS41I_insert32<0x22, "vpinsrd", 0>, VEX_4V;
5405 let Constraints = "$src1 = $dst" in
5406   defm PINSRD : SS41I_insert32<0x22, "pinsrd">;
5407
5408 multiclass SS41I_insert64<bits<8> opc, string asm, bit Is2Addr = 1> {
5409   def rr : SS4AIi8<opc, MRMSrcReg, (outs VR128:$dst),
5410       (ins VR128:$src1, GR64:$src2, i32i8imm:$src3),
5411       !if(Is2Addr,
5412         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5413         !strconcat(asm,
5414                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5415       [(set VR128:$dst,
5416         (v2i64 (insertelt VR128:$src1, GR64:$src2, imm:$src3)))]>,
5417       OpSize;
5418   def rm : SS4AIi8<opc, MRMSrcMem, (outs VR128:$dst),
5419       (ins VR128:$src1, i64mem:$src2, i32i8imm:$src3),
5420       !if(Is2Addr,
5421         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5422         !strconcat(asm,
5423                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5424       [(set VR128:$dst,
5425         (v2i64 (insertelt VR128:$src1, (loadi64 addr:$src2),
5426                           imm:$src3)))]>, OpSize;
5427 }
5428
5429 let Predicates = [HasAVX] in
5430   defm VPINSRQ : SS41I_insert64<0x22, "vpinsrq", 0>, VEX_4V, VEX_W;
5431 let Constraints = "$src1 = $dst" in
5432   defm PINSRQ : SS41I_insert64<0x22, "pinsrq">, REX_W;
5433
5434 // insertps has a few different modes, there's the first two here below which
5435 // are optimized inserts that won't zero arbitrary elements in the destination
5436 // vector. The next one matches the intrinsic and could zero arbitrary elements
5437 // in the target vector.
5438 multiclass SS41I_insertf32<bits<8> opc, string asm, bit Is2Addr = 1> {
5439   def rr : SS4AIi8<opc, MRMSrcReg, (outs VR128:$dst),
5440       (ins VR128:$src1, VR128:$src2, u32u8imm:$src3),
5441       !if(Is2Addr,
5442         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5443         !strconcat(asm,
5444                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5445       [(set VR128:$dst,
5446         (X86insrtps VR128:$src1, VR128:$src2, imm:$src3))]>,
5447       OpSize;
5448   def rm : SS4AIi8<opc, MRMSrcMem, (outs VR128:$dst),
5449       (ins VR128:$src1, f32mem:$src2, u32u8imm:$src3),
5450       !if(Is2Addr,
5451         !strconcat(asm, "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5452         !strconcat(asm,
5453                    "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5454       [(set VR128:$dst,
5455         (X86insrtps VR128:$src1,
5456                    (v4f32 (scalar_to_vector (loadf32 addr:$src2))),
5457                     imm:$src3))]>, OpSize;
5458 }
5459
5460 let Constraints = "$src1 = $dst" in
5461   defm INSERTPS : SS41I_insertf32<0x21, "insertps">;
5462 let Predicates = [HasAVX] in
5463   defm VINSERTPS : SS41I_insertf32<0x21, "vinsertps", 0>, VEX_4V;
5464
5465 def : Pat<(int_x86_sse41_insertps VR128:$src1, VR128:$src2, imm:$src3),
5466           (VINSERTPSrr VR128:$src1, VR128:$src2, imm:$src3)>,
5467           Requires<[HasAVX]>;
5468 def : Pat<(int_x86_sse41_insertps VR128:$src1, VR128:$src2, imm:$src3),
5469           (INSERTPSrr VR128:$src1, VR128:$src2, imm:$src3)>,
5470           Requires<[HasSSE41]>;
5471
5472 //===----------------------------------------------------------------------===//
5473 // SSE4.1 - Round Instructions
5474 //===----------------------------------------------------------------------===//
5475
5476 multiclass sse41_fp_unop_rm<bits<8> opcps, bits<8> opcpd, string OpcodeStr,
5477                             X86MemOperand x86memop, RegisterClass RC,
5478                             PatFrag mem_frag32, PatFrag mem_frag64,
5479                             Intrinsic V4F32Int, Intrinsic V2F64Int> {
5480   // Intrinsic operation, reg.
5481   // Vector intrinsic operation, reg
5482   def PSr : SS4AIi8<opcps, MRMSrcReg,
5483                     (outs RC:$dst), (ins RC:$src1, i32i8imm:$src2),
5484                     !strconcat(OpcodeStr,
5485                     "ps\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5486                     [(set RC:$dst, (V4F32Int RC:$src1, imm:$src2))]>,
5487                     OpSize;
5488
5489   // Vector intrinsic operation, mem
5490   def PSm : Ii8<opcps, MRMSrcMem,
5491                     (outs RC:$dst), (ins x86memop:$src1, i32i8imm:$src2),
5492                     !strconcat(OpcodeStr,
5493                     "ps\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5494                     [(set RC:$dst,
5495                           (V4F32Int (mem_frag32 addr:$src1),imm:$src2))]>,
5496                     TA, OpSize,
5497                 Requires<[HasSSE41]>;
5498
5499   // Vector intrinsic operation, reg
5500   def PDr : SS4AIi8<opcpd, MRMSrcReg,
5501                     (outs RC:$dst), (ins RC:$src1, i32i8imm:$src2),
5502                     !strconcat(OpcodeStr,
5503                     "pd\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5504                     [(set RC:$dst, (V2F64Int RC:$src1, imm:$src2))]>,
5505                     OpSize;
5506
5507   // Vector intrinsic operation, mem
5508   def PDm : SS4AIi8<opcpd, MRMSrcMem,
5509                     (outs RC:$dst), (ins x86memop:$src1, i32i8imm:$src2),
5510                     !strconcat(OpcodeStr,
5511                     "pd\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5512                     [(set RC:$dst,
5513                           (V2F64Int (mem_frag64 addr:$src1),imm:$src2))]>,
5514                     OpSize;
5515 }
5516
5517 multiclass sse41_fp_unop_rm_avx_p<bits<8> opcps, bits<8> opcpd,
5518                    RegisterClass RC, X86MemOperand x86memop, string OpcodeStr> {
5519   // Intrinsic operation, reg.
5520   // Vector intrinsic operation, reg
5521   def PSr_AVX : SS4AIi8<opcps, MRMSrcReg,
5522                     (outs RC:$dst), (ins RC:$src1, i32i8imm:$src2),
5523                     !strconcat(OpcodeStr,
5524                     "ps\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5525                     []>, OpSize;
5526
5527   // Vector intrinsic operation, mem
5528   def PSm_AVX : Ii8<opcps, MRMSrcMem,
5529                     (outs RC:$dst), (ins x86memop:$src1, i32i8imm:$src2),
5530                     !strconcat(OpcodeStr,
5531                     "ps\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5532                     []>, TA, OpSize, Requires<[HasSSE41]>;
5533
5534   // Vector intrinsic operation, reg
5535   def PDr_AVX : SS4AIi8<opcpd, MRMSrcReg,
5536                     (outs RC:$dst), (ins RC:$src1, i32i8imm:$src2),
5537                     !strconcat(OpcodeStr,
5538                     "pd\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5539                     []>, OpSize;
5540
5541   // Vector intrinsic operation, mem
5542   def PDm_AVX : SS4AIi8<opcpd, MRMSrcMem,
5543                     (outs RC:$dst), (ins x86memop:$src1, i32i8imm:$src2),
5544                     !strconcat(OpcodeStr,
5545                     "pd\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
5546                     []>, OpSize;
5547 }
5548
5549 multiclass sse41_fp_binop_rm<bits<8> opcss, bits<8> opcsd,
5550                             string OpcodeStr,
5551                             Intrinsic F32Int,
5552                             Intrinsic F64Int, bit Is2Addr = 1> {
5553   // Intrinsic operation, reg.
5554   def SSr : SS4AIi8<opcss, MRMSrcReg,
5555         (outs VR128:$dst), (ins VR128:$src1, VR128:$src2, i32i8imm:$src3),
5556         !if(Is2Addr,
5557             !strconcat(OpcodeStr,
5558                 "ss\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5559             !strconcat(OpcodeStr,
5560                 "ss\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5561         [(set VR128:$dst, (F32Int VR128:$src1, VR128:$src2, imm:$src3))]>,
5562         OpSize;
5563
5564   // Intrinsic operation, mem.
5565   def SSm : SS4AIi8<opcss, MRMSrcMem,
5566         (outs VR128:$dst), (ins VR128:$src1, ssmem:$src2, i32i8imm:$src3),
5567         !if(Is2Addr,
5568             !strconcat(OpcodeStr,
5569                 "ss\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5570             !strconcat(OpcodeStr,
5571                 "ss\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5572         [(set VR128:$dst,
5573              (F32Int VR128:$src1, sse_load_f32:$src2, imm:$src3))]>,
5574         OpSize;
5575
5576   // Intrinsic operation, reg.
5577   def SDr : SS4AIi8<opcsd, MRMSrcReg,
5578         (outs VR128:$dst), (ins VR128:$src1, VR128:$src2, i32i8imm:$src3),
5579         !if(Is2Addr,
5580             !strconcat(OpcodeStr,
5581                 "sd\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5582             !strconcat(OpcodeStr,
5583                 "sd\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5584         [(set VR128:$dst, (F64Int VR128:$src1, VR128:$src2, imm:$src3))]>,
5585         OpSize;
5586
5587   // Intrinsic operation, mem.
5588   def SDm : SS4AIi8<opcsd, MRMSrcMem,
5589         (outs VR128:$dst), (ins VR128:$src1, sdmem:$src2, i32i8imm:$src3),
5590         !if(Is2Addr,
5591             !strconcat(OpcodeStr,
5592                 "sd\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5593             !strconcat(OpcodeStr,
5594                 "sd\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5595         [(set VR128:$dst,
5596               (F64Int VR128:$src1, sse_load_f64:$src2, imm:$src3))]>,
5597         OpSize;
5598 }
5599
5600 multiclass sse41_fp_binop_rm_avx_s<bits<8> opcss, bits<8> opcsd,
5601                                    string OpcodeStr> {
5602   // Intrinsic operation, reg.
5603   def SSr_AVX : SS4AIi8<opcss, MRMSrcReg,
5604         (outs VR128:$dst), (ins VR128:$src1, VR128:$src2, i32i8imm:$src3),
5605         !strconcat(OpcodeStr,
5606                 "ss\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
5607         []>, OpSize;
5608
5609   // Intrinsic operation, mem.
5610   def SSm_AVX : SS4AIi8<opcss, MRMSrcMem,
5611         (outs VR128:$dst), (ins VR128:$src1, ssmem:$src2, i32i8imm:$src3),
5612         !strconcat(OpcodeStr,
5613                 "ss\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
5614         []>, OpSize;
5615
5616   // Intrinsic operation, reg.
5617   def SDr_AVX : SS4AIi8<opcsd, MRMSrcReg,
5618         (outs VR128:$dst), (ins VR128:$src1, VR128:$src2, i32i8imm:$src3),
5619             !strconcat(OpcodeStr,
5620                 "sd\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
5621         []>, OpSize;
5622
5623   // Intrinsic operation, mem.
5624   def SDm_AVX : SS4AIi8<opcsd, MRMSrcMem,
5625         (outs VR128:$dst), (ins VR128:$src1, sdmem:$src2, i32i8imm:$src3),
5626             !strconcat(OpcodeStr,
5627                 "sd\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
5628         []>, OpSize;
5629 }
5630
5631 // FP round - roundss, roundps, roundsd, roundpd
5632 let Predicates = [HasAVX] in {
5633   // Intrinsic form
5634   defm VROUND  : sse41_fp_unop_rm<0x08, 0x09, "vround", f128mem, VR128,
5635                                   memopv4f32, memopv2f64,
5636                                   int_x86_sse41_round_ps,
5637                                   int_x86_sse41_round_pd>, VEX;
5638   defm VROUNDY : sse41_fp_unop_rm<0x08, 0x09, "vround", f256mem, VR256,
5639                                   memopv8f32, memopv4f64,
5640                                   int_x86_avx_round_ps_256,
5641                                   int_x86_avx_round_pd_256>, VEX;
5642   defm VROUND  : sse41_fp_binop_rm<0x0A, 0x0B, "vround",
5643                                   int_x86_sse41_round_ss,
5644                                   int_x86_sse41_round_sd, 0>, VEX_4V;
5645
5646   // Instructions for the assembler
5647   defm VROUND  : sse41_fp_unop_rm_avx_p<0x08, 0x09, VR128, f128mem, "vround">,
5648                                         VEX;
5649   defm VROUNDY : sse41_fp_unop_rm_avx_p<0x08, 0x09, VR256, f256mem, "vround">,
5650                                         VEX;
5651   defm VROUND  : sse41_fp_binop_rm_avx_s<0x0A, 0x0B, "vround">, VEX_4V;
5652 }
5653
5654 defm ROUND  : sse41_fp_unop_rm<0x08, 0x09, "round", f128mem, VR128,
5655                                memopv4f32, memopv2f64,
5656                                int_x86_sse41_round_ps, int_x86_sse41_round_pd>;
5657 let Constraints = "$src1 = $dst" in
5658 defm ROUND  : sse41_fp_binop_rm<0x0A, 0x0B, "round",
5659                                int_x86_sse41_round_ss, int_x86_sse41_round_sd>;
5660
5661 //===----------------------------------------------------------------------===//
5662 // SSE4.1 - Packed Bit Test
5663 //===----------------------------------------------------------------------===//
5664
5665 // ptest instruction we'll lower to this in X86ISelLowering primarily from
5666 // the intel intrinsic that corresponds to this.
5667 let Defs = [EFLAGS], Predicates = [HasAVX] in {
5668 def VPTESTrr  : SS48I<0x17, MRMSrcReg, (outs), (ins VR128:$src1, VR128:$src2),
5669                 "vptest\t{$src2, $src1|$src1, $src2}",
5670                 [(set EFLAGS, (X86ptest VR128:$src1, (v4f32 VR128:$src2)))]>,
5671                 OpSize, VEX;
5672 def VPTESTrm  : SS48I<0x17, MRMSrcMem, (outs), (ins VR128:$src1, f128mem:$src2),
5673                 "vptest\t{$src2, $src1|$src1, $src2}",
5674                 [(set EFLAGS,(X86ptest VR128:$src1, (memopv4f32 addr:$src2)))]>,
5675                 OpSize, VEX;
5676
5677 def VPTESTYrr : SS48I<0x17, MRMSrcReg, (outs), (ins VR256:$src1, VR256:$src2),
5678                 "vptest\t{$src2, $src1|$src1, $src2}",
5679                 [(set EFLAGS, (X86ptest VR256:$src1, (v4i64 VR256:$src2)))]>,
5680                 OpSize, VEX;
5681 def VPTESTYrm : SS48I<0x17, MRMSrcMem, (outs), (ins VR256:$src1, i256mem:$src2),
5682                 "vptest\t{$src2, $src1|$src1, $src2}",
5683                 [(set EFLAGS,(X86ptest VR256:$src1, (memopv4i64 addr:$src2)))]>,
5684                 OpSize, VEX;
5685 }
5686
5687 let Defs = [EFLAGS] in {
5688 def PTESTrr : SS48I<0x17, MRMSrcReg, (outs), (ins VR128:$src1, VR128:$src2),
5689               "ptest \t{$src2, $src1|$src1, $src2}",
5690               [(set EFLAGS, (X86ptest VR128:$src1, (v4f32 VR128:$src2)))]>,
5691               OpSize;
5692 def PTESTrm : SS48I<0x17, MRMSrcMem, (outs), (ins VR128:$src1, f128mem:$src2),
5693               "ptest \t{$src2, $src1|$src1, $src2}",
5694               [(set EFLAGS, (X86ptest VR128:$src1, (memopv4f32 addr:$src2)))]>,
5695               OpSize;
5696 }
5697
5698 // The bit test instructions below are AVX only
5699 multiclass avx_bittest<bits<8> opc, string OpcodeStr, RegisterClass RC,
5700                        X86MemOperand x86memop, PatFrag mem_frag, ValueType vt> {
5701   def rr : SS48I<opc, MRMSrcReg, (outs), (ins RC:$src1, RC:$src2),
5702             !strconcat(OpcodeStr, "\t{$src2, $src1|$src1, $src2}"),
5703             [(set EFLAGS, (X86testp RC:$src1, (vt RC:$src2)))]>, OpSize, VEX;
5704   def rm : SS48I<opc, MRMSrcMem, (outs), (ins RC:$src1, x86memop:$src2),
5705             !strconcat(OpcodeStr, "\t{$src2, $src1|$src1, $src2}"),
5706             [(set EFLAGS, (X86testp RC:$src1, (mem_frag addr:$src2)))]>,
5707             OpSize, VEX;
5708 }
5709
5710 let Defs = [EFLAGS], Predicates = [HasAVX] in {
5711 defm VTESTPS  : avx_bittest<0x0E, "vtestps", VR128, f128mem, memopv4f32, v4f32>;
5712 defm VTESTPSY : avx_bittest<0x0E, "vtestps", VR256, f256mem, memopv8f32, v8f32>;
5713 defm VTESTPD  : avx_bittest<0x0F, "vtestpd", VR128, f128mem, memopv2f64, v2f64>;
5714 defm VTESTPDY : avx_bittest<0x0F, "vtestpd", VR256, f256mem, memopv4f64, v4f64>;
5715 }
5716
5717 //===----------------------------------------------------------------------===//
5718 // SSE4.1 - Misc Instructions
5719 //===----------------------------------------------------------------------===//
5720
5721 def POPCNT16rr : I<0xB8, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
5722                    "popcnt{w}\t{$src, $dst|$dst, $src}",
5723                    [(set GR16:$dst, (ctpop GR16:$src))]>, OpSize, XS;
5724 def POPCNT16rm : I<0xB8, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
5725                    "popcnt{w}\t{$src, $dst|$dst, $src}",
5726                    [(set GR16:$dst, (ctpop (loadi16 addr:$src)))]>, OpSize, XS;
5727
5728 def POPCNT32rr : I<0xB8, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
5729                    "popcnt{l}\t{$src, $dst|$dst, $src}",
5730                    [(set GR32:$dst, (ctpop GR32:$src))]>, XS;
5731 def POPCNT32rm : I<0xB8, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
5732                    "popcnt{l}\t{$src, $dst|$dst, $src}",
5733                    [(set GR32:$dst, (ctpop (loadi32 addr:$src)))]>, XS;
5734
5735 def POPCNT64rr : RI<0xB8, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
5736                     "popcnt{q}\t{$src, $dst|$dst, $src}",
5737                     [(set GR64:$dst, (ctpop GR64:$src))]>, XS;
5738 def POPCNT64rm : RI<0xB8, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
5739                     "popcnt{q}\t{$src, $dst|$dst, $src}",
5740                     [(set GR64:$dst, (ctpop (loadi64 addr:$src)))]>, XS;
5741
5742
5743
5744 // SS41I_unop_rm_int_v16 - SSE 4.1 unary operator whose type is v8i16.
5745 multiclass SS41I_unop_rm_int_v16<bits<8> opc, string OpcodeStr,
5746                                  Intrinsic IntId128> {
5747   def rr128 : SS48I<opc, MRMSrcReg, (outs VR128:$dst),
5748                     (ins VR128:$src),
5749                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5750                     [(set VR128:$dst, (IntId128 VR128:$src))]>, OpSize;
5751   def rm128 : SS48I<opc, MRMSrcMem, (outs VR128:$dst),
5752                      (ins i128mem:$src),
5753                      !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
5754                      [(set VR128:$dst,
5755                        (IntId128
5756                        (bitconvert (memopv8i16 addr:$src))))]>, OpSize;
5757 }
5758
5759 let Predicates = [HasAVX] in
5760 defm VPHMINPOSUW : SS41I_unop_rm_int_v16 <0x41, "vphminposuw",
5761                                          int_x86_sse41_phminposuw>, VEX;
5762 defm PHMINPOSUW : SS41I_unop_rm_int_v16 <0x41, "phminposuw",
5763                                          int_x86_sse41_phminposuw>;
5764
5765 /// SS41I_binop_rm_int - Simple SSE 4.1 binary operator
5766 multiclass SS41I_binop_rm_int<bits<8> opc, string OpcodeStr,
5767                               Intrinsic IntId128, bit Is2Addr = 1> {
5768   let isCommutable = 1 in
5769   def rr : SS48I<opc, MRMSrcReg, (outs VR128:$dst),
5770        (ins VR128:$src1, VR128:$src2),
5771        !if(Is2Addr,
5772            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5773            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5774        [(set VR128:$dst, (IntId128 VR128:$src1, VR128:$src2))]>, OpSize;
5775   def rm : SS48I<opc, MRMSrcMem, (outs VR128:$dst),
5776        (ins VR128:$src1, i128mem:$src2),
5777        !if(Is2Addr,
5778            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5779            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5780        [(set VR128:$dst,
5781          (IntId128 VR128:$src1,
5782           (bitconvert (memopv16i8 addr:$src2))))]>, OpSize;
5783 }
5784
5785 let Predicates = [HasAVX] in {
5786   let isCommutable = 0 in
5787   defm VPACKUSDW : SS41I_binop_rm_int<0x2B, "vpackusdw", int_x86_sse41_packusdw,
5788                                                          0>, VEX_4V;
5789   defm VPCMPEQQ  : SS41I_binop_rm_int<0x29, "vpcmpeqq",  int_x86_sse41_pcmpeqq,
5790                                                          0>, VEX_4V;
5791   defm VPMINSB   : SS41I_binop_rm_int<0x38, "vpminsb",   int_x86_sse41_pminsb,
5792                                                          0>, VEX_4V;
5793   defm VPMINSD   : SS41I_binop_rm_int<0x39, "vpminsd",   int_x86_sse41_pminsd,
5794                                                          0>, VEX_4V;
5795   defm VPMINUD   : SS41I_binop_rm_int<0x3B, "vpminud",   int_x86_sse41_pminud,
5796                                                          0>, VEX_4V;
5797   defm VPMINUW   : SS41I_binop_rm_int<0x3A, "vpminuw",   int_x86_sse41_pminuw,
5798                                                          0>, VEX_4V;
5799   defm VPMAXSB   : SS41I_binop_rm_int<0x3C, "vpmaxsb",   int_x86_sse41_pmaxsb,
5800                                                          0>, VEX_4V;
5801   defm VPMAXSD   : SS41I_binop_rm_int<0x3D, "vpmaxsd",   int_x86_sse41_pmaxsd,
5802                                                          0>, VEX_4V;
5803   defm VPMAXUD   : SS41I_binop_rm_int<0x3F, "vpmaxud",   int_x86_sse41_pmaxud,
5804                                                          0>, VEX_4V;
5805   defm VPMAXUW   : SS41I_binop_rm_int<0x3E, "vpmaxuw",   int_x86_sse41_pmaxuw,
5806                                                          0>, VEX_4V;
5807   defm VPMULDQ   : SS41I_binop_rm_int<0x28, "vpmuldq",   int_x86_sse41_pmuldq,
5808                                                          0>, VEX_4V;
5809
5810   def : Pat<(v2i64 (X86pcmpeqq VR128:$src1, VR128:$src2)),
5811             (VPCMPEQQrr VR128:$src1, VR128:$src2)>;
5812   def : Pat<(v2i64 (X86pcmpeqq VR128:$src1, (memop addr:$src2))),
5813             (VPCMPEQQrm VR128:$src1, addr:$src2)>;
5814 }
5815
5816 let Constraints = "$src1 = $dst" in {
5817   let isCommutable = 0 in
5818   defm PACKUSDW : SS41I_binop_rm_int<0x2B, "packusdw", int_x86_sse41_packusdw>;
5819   defm PCMPEQQ  : SS41I_binop_rm_int<0x29, "pcmpeqq",  int_x86_sse41_pcmpeqq>;
5820   defm PMINSB   : SS41I_binop_rm_int<0x38, "pminsb",   int_x86_sse41_pminsb>;
5821   defm PMINSD   : SS41I_binop_rm_int<0x39, "pminsd",   int_x86_sse41_pminsd>;
5822   defm PMINUD   : SS41I_binop_rm_int<0x3B, "pminud",   int_x86_sse41_pminud>;
5823   defm PMINUW   : SS41I_binop_rm_int<0x3A, "pminuw",   int_x86_sse41_pminuw>;
5824   defm PMAXSB   : SS41I_binop_rm_int<0x3C, "pmaxsb",   int_x86_sse41_pmaxsb>;
5825   defm PMAXSD   : SS41I_binop_rm_int<0x3D, "pmaxsd",   int_x86_sse41_pmaxsd>;
5826   defm PMAXUD   : SS41I_binop_rm_int<0x3F, "pmaxud",   int_x86_sse41_pmaxud>;
5827   defm PMAXUW   : SS41I_binop_rm_int<0x3E, "pmaxuw",   int_x86_sse41_pmaxuw>;
5828   defm PMULDQ   : SS41I_binop_rm_int<0x28, "pmuldq",   int_x86_sse41_pmuldq>;
5829 }
5830
5831 def : Pat<(v2i64 (X86pcmpeqq VR128:$src1, VR128:$src2)),
5832           (PCMPEQQrr VR128:$src1, VR128:$src2)>;
5833 def : Pat<(v2i64 (X86pcmpeqq VR128:$src1, (memop addr:$src2))),
5834           (PCMPEQQrm VR128:$src1, addr:$src2)>;
5835
5836 /// SS48I_binop_rm - Simple SSE41 binary operator.
5837 multiclass SS48I_binop_rm<bits<8> opc, string OpcodeStr, SDNode OpNode,
5838                         ValueType OpVT, bit Is2Addr = 1> {
5839   let isCommutable = 1 in
5840   def rr : SS48I<opc, MRMSrcReg, (outs VR128:$dst),
5841        (ins VR128:$src1, VR128:$src2),
5842        !if(Is2Addr,
5843            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5844            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5845        [(set VR128:$dst, (OpVT (OpNode VR128:$src1, VR128:$src2)))]>,
5846        OpSize;
5847   def rm : SS48I<opc, MRMSrcMem, (outs VR128:$dst),
5848        (ins VR128:$src1, i128mem:$src2),
5849        !if(Is2Addr,
5850            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
5851            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
5852        [(set VR128:$dst, (OpNode VR128:$src1,
5853                                   (bc_v4i32 (memopv2i64 addr:$src2))))]>,
5854        OpSize;
5855 }
5856
5857 let Predicates = [HasAVX] in
5858   defm VPMULLD : SS48I_binop_rm<0x40, "vpmulld", mul, v4i32, 0>, VEX_4V;
5859 let Constraints = "$src1 = $dst" in
5860   defm PMULLD : SS48I_binop_rm<0x40, "pmulld", mul, v4i32>;
5861
5862 /// SS41I_binop_rmi_int - SSE 4.1 binary operator with 8-bit immediate
5863 multiclass SS41I_binop_rmi_int<bits<8> opc, string OpcodeStr,
5864                  Intrinsic IntId, RegisterClass RC, PatFrag memop_frag,
5865                  X86MemOperand x86memop, bit Is2Addr = 1> {
5866   let isCommutable = 1 in
5867   def rri : SS4AIi8<opc, MRMSrcReg, (outs RC:$dst),
5868         (ins RC:$src1, RC:$src2, u32u8imm:$src3),
5869         !if(Is2Addr,
5870             !strconcat(OpcodeStr,
5871                 "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5872             !strconcat(OpcodeStr,
5873                 "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5874         [(set RC:$dst, (IntId RC:$src1, RC:$src2, imm:$src3))]>,
5875         OpSize;
5876   def rmi : SS4AIi8<opc, MRMSrcMem, (outs RC:$dst),
5877         (ins RC:$src1, x86memop:$src2, u32u8imm:$src3),
5878         !if(Is2Addr,
5879             !strconcat(OpcodeStr,
5880                 "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
5881             !strconcat(OpcodeStr,
5882                 "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}")),
5883         [(set RC:$dst,
5884           (IntId RC:$src1,
5885            (bitconvert (memop_frag addr:$src2)), imm:$src3))]>,
5886         OpSize;
5887 }
5888
5889 let Predicates = [HasAVX] in {
5890   let isCommutable = 0 in {
5891   defm VBLENDPS : SS41I_binop_rmi_int<0x0C, "vblendps", int_x86_sse41_blendps,
5892                                       VR128, memopv16i8, i128mem, 0>, VEX_4V;
5893   defm VBLENDPD : SS41I_binop_rmi_int<0x0D, "vblendpd", int_x86_sse41_blendpd,
5894                                       VR128, memopv16i8, i128mem, 0>, VEX_4V;
5895   defm VBLENDPSY : SS41I_binop_rmi_int<0x0C, "vblendps",
5896             int_x86_avx_blend_ps_256, VR256, memopv32i8, i256mem, 0>, VEX_4V;
5897   defm VBLENDPDY : SS41I_binop_rmi_int<0x0D, "vblendpd",
5898             int_x86_avx_blend_pd_256, VR256, memopv32i8, i256mem, 0>, VEX_4V;
5899   defm VPBLENDW : SS41I_binop_rmi_int<0x0E, "vpblendw", int_x86_sse41_pblendw,
5900                                       VR128, memopv16i8, i128mem, 0>, VEX_4V;
5901   defm VMPSADBW : SS41I_binop_rmi_int<0x42, "vmpsadbw", int_x86_sse41_mpsadbw,
5902                                       VR128, memopv16i8, i128mem, 0>, VEX_4V;
5903   }
5904   defm VDPPS : SS41I_binop_rmi_int<0x40, "vdpps", int_x86_sse41_dpps,
5905                                    VR128, memopv16i8, i128mem, 0>, VEX_4V;
5906   defm VDPPD : SS41I_binop_rmi_int<0x41, "vdppd", int_x86_sse41_dppd,
5907                                    VR128, memopv16i8, i128mem, 0>, VEX_4V;
5908   defm VDPPSY : SS41I_binop_rmi_int<0x40, "vdpps", int_x86_avx_dp_ps_256,
5909                                    VR256, memopv32i8, i256mem, 0>, VEX_4V;
5910 }
5911
5912 let Constraints = "$src1 = $dst" in {
5913   let isCommutable = 0 in {
5914   defm BLENDPS : SS41I_binop_rmi_int<0x0C, "blendps", int_x86_sse41_blendps,
5915                                      VR128, memopv16i8, i128mem>;
5916   defm BLENDPD : SS41I_binop_rmi_int<0x0D, "blendpd", int_x86_sse41_blendpd,
5917                                      VR128, memopv16i8, i128mem>;
5918   defm PBLENDW : SS41I_binop_rmi_int<0x0E, "pblendw", int_x86_sse41_pblendw,
5919                                      VR128, memopv16i8, i128mem>;
5920   defm MPSADBW : SS41I_binop_rmi_int<0x42, "mpsadbw", int_x86_sse41_mpsadbw,
5921                                      VR128, memopv16i8, i128mem>;
5922   }
5923   defm DPPS : SS41I_binop_rmi_int<0x40, "dpps", int_x86_sse41_dpps,
5924                                   VR128, memopv16i8, i128mem>;
5925   defm DPPD : SS41I_binop_rmi_int<0x41, "dppd", int_x86_sse41_dppd,
5926                                   VR128, memopv16i8, i128mem>;
5927 }
5928
5929 /// SS41I_quaternary_int_avx - AVX SSE 4.1 with 4 operators
5930 let Predicates = [HasAVX] in {
5931 multiclass SS41I_quaternary_int_avx<bits<8> opc, string OpcodeStr,
5932                                     RegisterClass RC, X86MemOperand x86memop,
5933                                     PatFrag mem_frag, Intrinsic IntId> {
5934   def rr : I<opc, MRMSrcReg, (outs RC:$dst),
5935                   (ins RC:$src1, RC:$src2, RC:$src3),
5936                   !strconcat(OpcodeStr,
5937                     "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
5938                   [(set RC:$dst, (IntId RC:$src1, RC:$src2, RC:$src3))],
5939                   SSEPackedInt>, OpSize, TA, VEX_4V, VEX_I8IMM;
5940
5941   def rm : I<opc, MRMSrcMem, (outs RC:$dst),
5942                   (ins RC:$src1, x86memop:$src2, RC:$src3),
5943                   !strconcat(OpcodeStr,
5944                     "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"),
5945                   [(set RC:$dst,
5946                         (IntId RC:$src1, (bitconvert (mem_frag addr:$src2)),
5947                                RC:$src3))],
5948                   SSEPackedInt>, OpSize, TA, VEX_4V, VEX_I8IMM;
5949 }
5950 }
5951
5952 defm VBLENDVPD  : SS41I_quaternary_int_avx<0x4B, "vblendvpd", VR128, i128mem,
5953                                            memopv16i8, int_x86_sse41_blendvpd>;
5954 defm VBLENDVPS  : SS41I_quaternary_int_avx<0x4A, "vblendvps", VR128, i128mem,
5955                                            memopv16i8, int_x86_sse41_blendvps>;
5956 defm VPBLENDVB  : SS41I_quaternary_int_avx<0x4C, "vpblendvb", VR128, i128mem,
5957                                            memopv16i8, int_x86_sse41_pblendvb>;
5958 defm VBLENDVPDY : SS41I_quaternary_int_avx<0x4B, "vblendvpd", VR256, i256mem,
5959                                          memopv32i8, int_x86_avx_blendv_pd_256>;
5960 defm VBLENDVPSY : SS41I_quaternary_int_avx<0x4A, "vblendvps", VR256, i256mem,
5961                                          memopv32i8, int_x86_avx_blendv_ps_256>;
5962
5963 let Predicates = [HasAVX] in {
5964   def : Pat<(v16i8 (vselect (v16i8 VR128:$mask), (v16i8 VR128:$src1),
5965                             (v16i8 VR128:$src2))),
5966             (VPBLENDVBrr VR128:$src2, VR128:$src1, VR128:$mask)>;
5967   def : Pat<(v4i32 (vselect (v4i32 VR128:$mask), (v4i32 VR128:$src1),
5968                             (v4i32 VR128:$src2))),
5969             (VBLENDVPSrr VR128:$src2, VR128:$src1, VR128:$mask)>;
5970   def : Pat<(v4f32 (vselect (v4i32 VR128:$mask), (v4f32 VR128:$src1),
5971                             (v4f32 VR128:$src2))),
5972             (VBLENDVPSrr VR128:$src2, VR128:$src1, VR128:$mask)>;
5973   def : Pat<(v2i64 (vselect (v2i64 VR128:$mask), (v2i64 VR128:$src1),
5974                             (v2i64 VR128:$src2))),
5975             (VBLENDVPDrr VR128:$src2, VR128:$src1, VR128:$mask)>;
5976   def : Pat<(v2f64 (vselect (v2i64 VR128:$mask), (v2f64 VR128:$src1),
5977                             (v2f64 VR128:$src2))),
5978             (VBLENDVPDrr VR128:$src2, VR128:$src1, VR128:$mask)>;
5979   def : Pat<(v8i32 (vselect (v8i32 VR256:$mask), (v8i32 VR256:$src1),
5980                             (v8i32 VR256:$src2))),
5981             (VBLENDVPSYrr VR256:$src2, VR256:$src1, VR256:$mask)>;
5982   def : Pat<(v8f32 (vselect (v8i32 VR256:$mask), (v8f32 VR256:$src1),
5983                             (v8f32 VR256:$src2))),
5984             (VBLENDVPSYrr VR256:$src2, VR256:$src1, VR256:$mask)>;
5985   def : Pat<(v4i64 (vselect (v4i64 VR256:$mask), (v4i64 VR256:$src1),
5986                             (v4i64 VR256:$src2))),
5987             (VBLENDVPDYrr VR256:$src2, VR256:$src1, VR256:$mask)>;
5988   def : Pat<(v4f64 (vselect (v4i64 VR256:$mask), (v4f64 VR256:$src1),
5989                             (v4f64 VR256:$src2))),
5990             (VBLENDVPDYrr VR256:$src2, VR256:$src1, VR256:$mask)>;
5991 }
5992
5993 /// SS41I_ternary_int - SSE 4.1 ternary operator
5994 let Uses = [XMM0], Constraints = "$src1 = $dst" in {
5995   multiclass SS41I_ternary_int<bits<8> opc, string OpcodeStr, Intrinsic IntId> {
5996     def rr0 : SS48I<opc, MRMSrcReg, (outs VR128:$dst),
5997                     (ins VR128:$src1, VR128:$src2),
5998                     !strconcat(OpcodeStr,
5999                      "\t{$src2, $dst|$dst, $src2}"),
6000                     [(set VR128:$dst, (IntId VR128:$src1, VR128:$src2, XMM0))]>,
6001                     OpSize;
6002
6003     def rm0 : SS48I<opc, MRMSrcMem, (outs VR128:$dst),
6004                     (ins VR128:$src1, i128mem:$src2),
6005                     !strconcat(OpcodeStr,
6006                      "\t{$src2, $dst|$dst, $src2}"),
6007                     [(set VR128:$dst,
6008                       (IntId VR128:$src1,
6009                        (bitconvert (memopv16i8 addr:$src2)), XMM0))]>, OpSize;
6010   }
6011 }
6012
6013 defm BLENDVPD : SS41I_ternary_int<0x15, "blendvpd", int_x86_sse41_blendvpd>;
6014 defm BLENDVPS : SS41I_ternary_int<0x14, "blendvps", int_x86_sse41_blendvps>;
6015 defm PBLENDVB : SS41I_ternary_int<0x10, "pblendvb", int_x86_sse41_pblendvb>;
6016
6017 let Predicates = [HasSSE41] in {
6018   def : Pat<(v16i8 (vselect (v16i8 XMM0), (v16i8 VR128:$src1),
6019                             (v16i8 VR128:$src2))),
6020             (PBLENDVBrr0 VR128:$src2, VR128:$src1)>;
6021   def : Pat<(v4i32 (vselect (v4i32 XMM0), (v4i32 VR128:$src1),
6022                             (v4i32 VR128:$src2))),
6023             (BLENDVPSrr0 VR128:$src2, VR128:$src1)>;
6024   def : Pat<(v4f32 (vselect (v4i32 XMM0), (v4f32 VR128:$src1),
6025                             (v4f32 VR128:$src2))),
6026             (BLENDVPSrr0 VR128:$src2, VR128:$src1)>;
6027   def : Pat<(v2i64 (vselect (v2i64 XMM0), (v2i64 VR128:$src1),
6028                             (v2i64 VR128:$src2))),
6029             (BLENDVPDrr0 VR128:$src2, VR128:$src1)>;
6030   def : Pat<(v2f64 (vselect (v2i64 XMM0), (v2f64 VR128:$src1),
6031                             (v2f64 VR128:$src2))),
6032             (BLENDVPDrr0 VR128:$src2, VR128:$src1)>;
6033 }
6034
6035 let Predicates = [HasAVX] in
6036 def VMOVNTDQArm : SS48I<0x2A, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
6037                        "vmovntdqa\t{$src, $dst|$dst, $src}",
6038                        [(set VR128:$dst, (int_x86_sse41_movntdqa addr:$src))]>,
6039                        OpSize, VEX;
6040 def MOVNTDQArm : SS48I<0x2A, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
6041                        "movntdqa\t{$src, $dst|$dst, $src}",
6042                        [(set VR128:$dst, (int_x86_sse41_movntdqa addr:$src))]>,
6043                        OpSize;
6044
6045 //===----------------------------------------------------------------------===//
6046 // SSE4.2 - Compare Instructions
6047 //===----------------------------------------------------------------------===//
6048
6049 /// SS42I_binop_rm_int - Simple SSE 4.2 binary operator
6050 multiclass SS42I_binop_rm_int<bits<8> opc, string OpcodeStr,
6051                               Intrinsic IntId128, bit Is2Addr = 1> {
6052   def rr : SS428I<opc, MRMSrcReg, (outs VR128:$dst),
6053        (ins VR128:$src1, VR128:$src2),
6054        !if(Is2Addr,
6055            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
6056            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
6057        [(set VR128:$dst, (IntId128 VR128:$src1, VR128:$src2))]>,
6058        OpSize;
6059   def rm : SS428I<opc, MRMSrcMem, (outs VR128:$dst),
6060        (ins VR128:$src1, i128mem:$src2),
6061        !if(Is2Addr,
6062            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
6063            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
6064        [(set VR128:$dst,
6065          (IntId128 VR128:$src1,
6066           (bitconvert (memopv16i8 addr:$src2))))]>, OpSize;
6067 }
6068
6069 let Predicates = [HasAVX] in {
6070   defm VPCMPGTQ : SS42I_binop_rm_int<0x37, "vpcmpgtq", int_x86_sse42_pcmpgtq,
6071                                      0>, VEX_4V;
6072
6073   def : Pat<(v2i64 (X86pcmpgtq VR128:$src1, VR128:$src2)),
6074             (VPCMPGTQrr VR128:$src1, VR128:$src2)>;
6075   def : Pat<(v2i64 (X86pcmpgtq VR128:$src1, (memop addr:$src2))),
6076             (VPCMPGTQrm VR128:$src1, addr:$src2)>;
6077 }
6078
6079 let Constraints = "$src1 = $dst" in
6080   defm PCMPGTQ : SS42I_binop_rm_int<0x37, "pcmpgtq", int_x86_sse42_pcmpgtq>;
6081
6082 def : Pat<(v2i64 (X86pcmpgtq VR128:$src1, VR128:$src2)),
6083           (PCMPGTQrr VR128:$src1, VR128:$src2)>;
6084 def : Pat<(v2i64 (X86pcmpgtq VR128:$src1, (memop addr:$src2))),
6085           (PCMPGTQrm VR128:$src1, addr:$src2)>;
6086
6087 //===----------------------------------------------------------------------===//
6088 // SSE4.2 - String/text Processing Instructions
6089 //===----------------------------------------------------------------------===//
6090
6091 // Packed Compare Implicit Length Strings, Return Mask
6092 multiclass pseudo_pcmpistrm<string asm> {
6093   def REG : PseudoI<(outs VR128:$dst),
6094                     (ins VR128:$src1, VR128:$src2, i8imm:$src3),
6095     [(set VR128:$dst, (int_x86_sse42_pcmpistrm128 VR128:$src1, VR128:$src2,
6096                                                   imm:$src3))]>;
6097   def MEM : PseudoI<(outs VR128:$dst),
6098                     (ins VR128:$src1, i128mem:$src2, i8imm:$src3),
6099     [(set VR128:$dst, (int_x86_sse42_pcmpistrm128
6100                        VR128:$src1, (load addr:$src2), imm:$src3))]>;
6101 }
6102
6103 let Defs = [EFLAGS], usesCustomInserter = 1 in {
6104   defm PCMPISTRM128 : pseudo_pcmpistrm<"#PCMPISTRM128">, Requires<[HasSSE42]>;
6105   defm VPCMPISTRM128 : pseudo_pcmpistrm<"#VPCMPISTRM128">, Requires<[HasAVX]>;
6106 }
6107
6108 let Defs = [XMM0, EFLAGS], Predicates = [HasAVX] in {
6109   def VPCMPISTRM128rr : SS42AI<0x62, MRMSrcReg, (outs),
6110       (ins VR128:$src1, VR128:$src2, i8imm:$src3),
6111       "vpcmpistrm\t{$src3, $src2, $src1|$src1, $src2, $src3}", []>, OpSize, VEX;
6112   def VPCMPISTRM128rm : SS42AI<0x62, MRMSrcMem, (outs),
6113       (ins VR128:$src1, i128mem:$src2, i8imm:$src3),
6114       "vpcmpistrm\t{$src3, $src2, $src1|$src1, $src2, $src3}", []>, OpSize, VEX;
6115 }
6116
6117 let Defs = [XMM0, EFLAGS] in {
6118   def PCMPISTRM128rr : SS42AI<0x62, MRMSrcReg, (outs),
6119       (ins VR128:$src1, VR128:$src2, i8imm:$src3),
6120       "pcmpistrm\t{$src3, $src2, $src1|$src1, $src2, $src3}", []>, OpSize;
6121   def PCMPISTRM128rm : SS42AI<0x62, MRMSrcMem, (outs),
6122       (ins VR128:$src1, i128mem:$src2, i8imm:$src3),
6123       "pcmpistrm\t{$src3, $src2, $src1|$src1, $src2, $src3}", []>, OpSize;
6124 }
6125
6126 // Packed Compare Explicit Length Strings, Return Mask
6127 multiclass pseudo_pcmpestrm<string asm> {
6128   def REG : PseudoI<(outs VR128:$dst),
6129                     (ins VR128:$src1, VR128:$src3, i8imm:$src5),
6130     [(set VR128:$dst, (int_x86_sse42_pcmpestrm128
6131                        VR128:$src1, EAX, VR128:$src3, EDX, imm:$src5))]>;
6132   def MEM : PseudoI<(outs VR128:$dst),
6133                     (ins VR128:$src1, i128mem:$src3, i8imm:$src5),
6134     [(set VR128:$dst, (int_x86_sse42_pcmpestrm128
6135                        VR128:$src1, EAX, (load addr:$src3), EDX, imm:$src5))]>;
6136 }
6137
6138 let Defs = [EFLAGS], Uses = [EAX, EDX], usesCustomInserter = 1 in {
6139   defm PCMPESTRM128 : pseudo_pcmpestrm<"#PCMPESTRM128">, Requires<[HasSSE42]>;
6140   defm VPCMPESTRM128 : pseudo_pcmpestrm<"#VPCMPESTRM128">, Requires<[HasAVX]>;
6141 }
6142
6143 let Predicates = [HasAVX],
6144     Defs = [XMM0, EFLAGS], Uses = [EAX, EDX] in {
6145   def VPCMPESTRM128rr : SS42AI<0x60, MRMSrcReg, (outs),
6146       (ins VR128:$src1, VR128:$src3, i8imm:$src5),
6147       "vpcmpestrm\t{$src5, $src3, $src1|$src1, $src3, $src5}", []>, OpSize, VEX;
6148   def VPCMPESTRM128rm : SS42AI<0x60, MRMSrcMem, (outs),
6149       (ins VR128:$src1, i128mem:$src3, i8imm:$src5),
6150       "vpcmpestrm\t{$src5, $src3, $src1|$src1, $src3, $src5}", []>, OpSize, VEX;
6151 }
6152
6153 let Defs = [XMM0, EFLAGS], Uses = [EAX, EDX] in {
6154   def PCMPESTRM128rr : SS42AI<0x60, MRMSrcReg, (outs),
6155       (ins VR128:$src1, VR128:$src3, i8imm:$src5),
6156       "pcmpestrm\t{$src5, $src3, $src1|$src1, $src3, $src5}", []>, OpSize;
6157   def PCMPESTRM128rm : SS42AI<0x60, MRMSrcMem, (outs),
6158       (ins VR128:$src1, i128mem:$src3, i8imm:$src5),
6159       "pcmpestrm\t{$src5, $src3, $src1|$src1, $src3, $src5}", []>, OpSize;
6160 }
6161
6162 // Packed Compare Implicit Length Strings, Return Index
6163 let Defs = [ECX, EFLAGS] in {
6164   multiclass SS42AI_pcmpistri<Intrinsic IntId128, string asm = "pcmpistri"> {
6165     def rr : SS42AI<0x63, MRMSrcReg, (outs),
6166       (ins VR128:$src1, VR128:$src2, i8imm:$src3),
6167       !strconcat(asm, "\t{$src3, $src2, $src1|$src1, $src2, $src3}"),
6168       [(set ECX, (IntId128 VR128:$src1, VR128:$src2, imm:$src3)),
6169        (implicit EFLAGS)]>, OpSize;
6170     def rm : SS42AI<0x63, MRMSrcMem, (outs),
6171       (ins VR128:$src1, i128mem:$src2, i8imm:$src3),
6172       !strconcat(asm, "\t{$src3, $src2, $src1|$src1, $src2, $src3}"),
6173       [(set ECX, (IntId128 VR128:$src1, (load addr:$src2), imm:$src3)),
6174        (implicit EFLAGS)]>, OpSize;
6175   }
6176 }
6177
6178 let Predicates = [HasAVX] in {
6179 defm VPCMPISTRI  : SS42AI_pcmpistri<int_x86_sse42_pcmpistri128, "vpcmpistri">,
6180                                     VEX;
6181 defm VPCMPISTRIA : SS42AI_pcmpistri<int_x86_sse42_pcmpistria128, "vpcmpistri">,
6182                                     VEX;
6183 defm VPCMPISTRIC : SS42AI_pcmpistri<int_x86_sse42_pcmpistric128, "vpcmpistri">,
6184                                     VEX;
6185 defm VPCMPISTRIO : SS42AI_pcmpistri<int_x86_sse42_pcmpistrio128, "vpcmpistri">,
6186                                     VEX;
6187 defm VPCMPISTRIS : SS42AI_pcmpistri<int_x86_sse42_pcmpistris128, "vpcmpistri">,
6188                                     VEX;
6189 defm VPCMPISTRIZ : SS42AI_pcmpistri<int_x86_sse42_pcmpistriz128, "vpcmpistri">,
6190                                     VEX;
6191 }
6192
6193 defm PCMPISTRI  : SS42AI_pcmpistri<int_x86_sse42_pcmpistri128>;
6194 defm PCMPISTRIA : SS42AI_pcmpistri<int_x86_sse42_pcmpistria128>;
6195 defm PCMPISTRIC : SS42AI_pcmpistri<int_x86_sse42_pcmpistric128>;
6196 defm PCMPISTRIO : SS42AI_pcmpistri<int_x86_sse42_pcmpistrio128>;
6197 defm PCMPISTRIS : SS42AI_pcmpistri<int_x86_sse42_pcmpistris128>;
6198 defm PCMPISTRIZ : SS42AI_pcmpistri<int_x86_sse42_pcmpistriz128>;
6199
6200 // Packed Compare Explicit Length Strings, Return Index
6201 let Defs = [ECX, EFLAGS], Uses = [EAX, EDX] in {
6202   multiclass SS42AI_pcmpestri<Intrinsic IntId128, string asm = "pcmpestri"> {
6203     def rr : SS42AI<0x61, MRMSrcReg, (outs),
6204       (ins VR128:$src1, VR128:$src3, i8imm:$src5),
6205       !strconcat(asm, "\t{$src5, $src3, $src1|$src1, $src3, $src5}"),
6206       [(set ECX, (IntId128 VR128:$src1, EAX, VR128:$src3, EDX, imm:$src5)),
6207        (implicit EFLAGS)]>, OpSize;
6208     def rm : SS42AI<0x61, MRMSrcMem, (outs),
6209       (ins VR128:$src1, i128mem:$src3, i8imm:$src5),
6210       !strconcat(asm, "\t{$src5, $src3, $src1|$src1, $src3, $src5}"),
6211        [(set ECX,
6212              (IntId128 VR128:$src1, EAX, (load addr:$src3), EDX, imm:$src5)),
6213         (implicit EFLAGS)]>, OpSize;
6214   }
6215 }
6216
6217 let Predicates = [HasAVX] in {
6218 defm VPCMPESTRI  : SS42AI_pcmpestri<int_x86_sse42_pcmpestri128, "vpcmpestri">,
6219                                     VEX;
6220 defm VPCMPESTRIA : SS42AI_pcmpestri<int_x86_sse42_pcmpestria128, "vpcmpestri">,
6221                                     VEX;
6222 defm VPCMPESTRIC : SS42AI_pcmpestri<int_x86_sse42_pcmpestric128, "vpcmpestri">,
6223                                     VEX;
6224 defm VPCMPESTRIO : SS42AI_pcmpestri<int_x86_sse42_pcmpestrio128, "vpcmpestri">,
6225                                     VEX;
6226 defm VPCMPESTRIS : SS42AI_pcmpestri<int_x86_sse42_pcmpestris128, "vpcmpestri">,
6227                                     VEX;
6228 defm VPCMPESTRIZ : SS42AI_pcmpestri<int_x86_sse42_pcmpestriz128, "vpcmpestri">,
6229                                     VEX;
6230 }
6231
6232 defm PCMPESTRI  : SS42AI_pcmpestri<int_x86_sse42_pcmpestri128>;
6233 defm PCMPESTRIA : SS42AI_pcmpestri<int_x86_sse42_pcmpestria128>;
6234 defm PCMPESTRIC : SS42AI_pcmpestri<int_x86_sse42_pcmpestric128>;
6235 defm PCMPESTRIO : SS42AI_pcmpestri<int_x86_sse42_pcmpestrio128>;
6236 defm PCMPESTRIS : SS42AI_pcmpestri<int_x86_sse42_pcmpestris128>;
6237 defm PCMPESTRIZ : SS42AI_pcmpestri<int_x86_sse42_pcmpestriz128>;
6238
6239 //===----------------------------------------------------------------------===//
6240 // SSE4.2 - CRC Instructions
6241 //===----------------------------------------------------------------------===//
6242
6243 // No CRC instructions have AVX equivalents
6244
6245 // crc intrinsic instruction
6246 // This set of instructions are only rm, the only difference is the size
6247 // of r and m.
6248 let Constraints = "$src1 = $dst" in {
6249   def CRC32r32m8  : SS42FI<0xF0, MRMSrcMem, (outs GR32:$dst),
6250                       (ins GR32:$src1, i8mem:$src2),
6251                       "crc32{b} \t{$src2, $src1|$src1, $src2}",
6252                        [(set GR32:$dst,
6253                          (int_x86_sse42_crc32_32_8 GR32:$src1,
6254                          (load addr:$src2)))]>;
6255   def CRC32r32r8  : SS42FI<0xF0, MRMSrcReg, (outs GR32:$dst),
6256                       (ins GR32:$src1, GR8:$src2),
6257                       "crc32{b} \t{$src2, $src1|$src1, $src2}",
6258                        [(set GR32:$dst,
6259                          (int_x86_sse42_crc32_32_8 GR32:$src1, GR8:$src2))]>;
6260   def CRC32r32m16  : SS42FI<0xF1, MRMSrcMem, (outs GR32:$dst),
6261                       (ins GR32:$src1, i16mem:$src2),
6262                       "crc32{w} \t{$src2, $src1|$src1, $src2}",
6263                        [(set GR32:$dst,
6264                          (int_x86_sse42_crc32_32_16 GR32:$src1,
6265                          (load addr:$src2)))]>,
6266                          OpSize;
6267   def CRC32r32r16  : SS42FI<0xF1, MRMSrcReg, (outs GR32:$dst),
6268                       (ins GR32:$src1, GR16:$src2),
6269                       "crc32{w} \t{$src2, $src1|$src1, $src2}",
6270                        [(set GR32:$dst,
6271                          (int_x86_sse42_crc32_32_16 GR32:$src1, GR16:$src2))]>,
6272                          OpSize;
6273   def CRC32r32m32  : SS42FI<0xF1, MRMSrcMem, (outs GR32:$dst),
6274                       (ins GR32:$src1, i32mem:$src2),
6275                       "crc32{l} \t{$src2, $src1|$src1, $src2}",
6276                        [(set GR32:$dst,
6277                          (int_x86_sse42_crc32_32_32 GR32:$src1,
6278                          (load addr:$src2)))]>;
6279   def CRC32r32r32  : SS42FI<0xF1, MRMSrcReg, (outs GR32:$dst),
6280                       (ins GR32:$src1, GR32:$src2),
6281                       "crc32{l} \t{$src2, $src1|$src1, $src2}",
6282                        [(set GR32:$dst,
6283                          (int_x86_sse42_crc32_32_32 GR32:$src1, GR32:$src2))]>;
6284   def CRC32r64m8  : SS42FI<0xF0, MRMSrcMem, (outs GR64:$dst),
6285                       (ins GR64:$src1, i8mem:$src2),
6286                       "crc32{b} \t{$src2, $src1|$src1, $src2}",
6287                        [(set GR64:$dst,
6288                          (int_x86_sse42_crc32_64_8 GR64:$src1,
6289                          (load addr:$src2)))]>,
6290                          REX_W;
6291   def CRC32r64r8  : SS42FI<0xF0, MRMSrcReg, (outs GR64:$dst),
6292                       (ins GR64:$src1, GR8:$src2),
6293                       "crc32{b} \t{$src2, $src1|$src1, $src2}",
6294                        [(set GR64:$dst,
6295                          (int_x86_sse42_crc32_64_8 GR64:$src1, GR8:$src2))]>,
6296                          REX_W;
6297   def CRC32r64m64  : SS42FI<0xF1, MRMSrcMem, (outs GR64:$dst),
6298                       (ins GR64:$src1, i64mem:$src2),
6299                       "crc32{q} \t{$src2, $src1|$src1, $src2}",
6300                        [(set GR64:$dst,
6301                          (int_x86_sse42_crc32_64_64 GR64:$src1,
6302                          (load addr:$src2)))]>,
6303                          REX_W;
6304   def CRC32r64r64  : SS42FI<0xF1, MRMSrcReg, (outs GR64:$dst),
6305                       (ins GR64:$src1, GR64:$src2),
6306                       "crc32{q} \t{$src2, $src1|$src1, $src2}",
6307                        [(set GR64:$dst,
6308                          (int_x86_sse42_crc32_64_64 GR64:$src1, GR64:$src2))]>,
6309                          REX_W;
6310 }
6311
6312 //===----------------------------------------------------------------------===//
6313 // AES-NI Instructions
6314 //===----------------------------------------------------------------------===//
6315
6316 multiclass AESI_binop_rm_int<bits<8> opc, string OpcodeStr,
6317                               Intrinsic IntId128, bit Is2Addr = 1> {
6318   def rr : AES8I<opc, MRMSrcReg, (outs VR128:$dst),
6319        (ins VR128:$src1, VR128:$src2),
6320        !if(Is2Addr,
6321            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
6322            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
6323        [(set VR128:$dst, (IntId128 VR128:$src1, VR128:$src2))]>,
6324        OpSize;
6325   def rm : AES8I<opc, MRMSrcMem, (outs VR128:$dst),
6326        (ins VR128:$src1, i128mem:$src2),
6327        !if(Is2Addr,
6328            !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
6329            !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
6330        [(set VR128:$dst,
6331          (IntId128 VR128:$src1,
6332           (bitconvert (memopv16i8 addr:$src2))))]>, OpSize;
6333 }
6334
6335 // Perform One Round of an AES Encryption/Decryption Flow
6336 let Predicates = [HasAVX, HasAES] in {
6337   defm VAESENC          : AESI_binop_rm_int<0xDC, "vaesenc",
6338                          int_x86_aesni_aesenc, 0>, VEX_4V;
6339   defm VAESENCLAST      : AESI_binop_rm_int<0xDD, "vaesenclast",
6340                          int_x86_aesni_aesenclast, 0>, VEX_4V;
6341   defm VAESDEC          : AESI_binop_rm_int<0xDE, "vaesdec",
6342                          int_x86_aesni_aesdec, 0>, VEX_4V;
6343   defm VAESDECLAST      : AESI_binop_rm_int<0xDF, "vaesdeclast",
6344                          int_x86_aesni_aesdeclast, 0>, VEX_4V;
6345 }
6346
6347 let Constraints = "$src1 = $dst" in {
6348   defm AESENC          : AESI_binop_rm_int<0xDC, "aesenc",
6349                          int_x86_aesni_aesenc>;
6350   defm AESENCLAST      : AESI_binop_rm_int<0xDD, "aesenclast",
6351                          int_x86_aesni_aesenclast>;
6352   defm AESDEC          : AESI_binop_rm_int<0xDE, "aesdec",
6353                          int_x86_aesni_aesdec>;
6354   defm AESDECLAST      : AESI_binop_rm_int<0xDF, "aesdeclast",
6355                          int_x86_aesni_aesdeclast>;
6356 }
6357
6358 let Predicates = [HasAES] in {
6359   def : Pat<(v2i64 (int_x86_aesni_aesenc VR128:$src1, VR128:$src2)),
6360             (AESENCrr VR128:$src1, VR128:$src2)>;
6361   def : Pat<(v2i64 (int_x86_aesni_aesenc VR128:$src1, (memop addr:$src2))),
6362             (AESENCrm VR128:$src1, addr:$src2)>;
6363   def : Pat<(v2i64 (int_x86_aesni_aesenclast VR128:$src1, VR128:$src2)),
6364             (AESENCLASTrr VR128:$src1, VR128:$src2)>;
6365   def : Pat<(v2i64 (int_x86_aesni_aesenclast VR128:$src1, (memop addr:$src2))),
6366             (AESENCLASTrm VR128:$src1, addr:$src2)>;
6367   def : Pat<(v2i64 (int_x86_aesni_aesdec VR128:$src1, VR128:$src2)),
6368             (AESDECrr VR128:$src1, VR128:$src2)>;
6369   def : Pat<(v2i64 (int_x86_aesni_aesdec VR128:$src1, (memop addr:$src2))),
6370             (AESDECrm VR128:$src1, addr:$src2)>;
6371   def : Pat<(v2i64 (int_x86_aesni_aesdeclast VR128:$src1, VR128:$src2)),
6372             (AESDECLASTrr VR128:$src1, VR128:$src2)>;
6373   def : Pat<(v2i64 (int_x86_aesni_aesdeclast VR128:$src1, (memop addr:$src2))),
6374             (AESDECLASTrm VR128:$src1, addr:$src2)>;
6375 }
6376
6377 let Predicates = [HasAVX, HasAES], AddedComplexity = 20 in {
6378   def : Pat<(v2i64 (int_x86_aesni_aesenc VR128:$src1, VR128:$src2)),
6379             (VAESENCrr VR128:$src1, VR128:$src2)>;
6380   def : Pat<(v2i64 (int_x86_aesni_aesenc VR128:$src1, (memop addr:$src2))),
6381             (VAESENCrm VR128:$src1, addr:$src2)>;
6382   def : Pat<(v2i64 (int_x86_aesni_aesenclast VR128:$src1, VR128:$src2)),
6383             (VAESENCLASTrr VR128:$src1, VR128:$src2)>;
6384   def : Pat<(v2i64 (int_x86_aesni_aesenclast VR128:$src1, (memop addr:$src2))),
6385             (VAESENCLASTrm VR128:$src1, addr:$src2)>;
6386   def : Pat<(v2i64 (int_x86_aesni_aesdec VR128:$src1, VR128:$src2)),
6387             (VAESDECrr VR128:$src1, VR128:$src2)>;
6388   def : Pat<(v2i64 (int_x86_aesni_aesdec VR128:$src1, (memop addr:$src2))),
6389             (VAESDECrm VR128:$src1, addr:$src2)>;
6390   def : Pat<(v2i64 (int_x86_aesni_aesdeclast VR128:$src1, VR128:$src2)),
6391             (VAESDECLASTrr VR128:$src1, VR128:$src2)>;
6392   def : Pat<(v2i64 (int_x86_aesni_aesdeclast VR128:$src1, (memop addr:$src2))),
6393             (VAESDECLASTrm VR128:$src1, addr:$src2)>;
6394 }
6395
6396 // Perform the AES InvMixColumn Transformation
6397 let Predicates = [HasAVX, HasAES] in {
6398   def VAESIMCrr : AES8I<0xDB, MRMSrcReg, (outs VR128:$dst),
6399       (ins VR128:$src1),
6400       "vaesimc\t{$src1, $dst|$dst, $src1}",
6401       [(set VR128:$dst,
6402         (int_x86_aesni_aesimc VR128:$src1))]>,
6403       OpSize, VEX;
6404   def VAESIMCrm : AES8I<0xDB, MRMSrcMem, (outs VR128:$dst),
6405       (ins i128mem:$src1),
6406       "vaesimc\t{$src1, $dst|$dst, $src1}",
6407       [(set VR128:$dst,
6408         (int_x86_aesni_aesimc (bitconvert (memopv2i64 addr:$src1))))]>,
6409       OpSize, VEX;
6410 }
6411 def AESIMCrr : AES8I<0xDB, MRMSrcReg, (outs VR128:$dst),
6412   (ins VR128:$src1),
6413   "aesimc\t{$src1, $dst|$dst, $src1}",
6414   [(set VR128:$dst,
6415     (int_x86_aesni_aesimc VR128:$src1))]>,
6416   OpSize;
6417 def AESIMCrm : AES8I<0xDB, MRMSrcMem, (outs VR128:$dst),
6418   (ins i128mem:$src1),
6419   "aesimc\t{$src1, $dst|$dst, $src1}",
6420   [(set VR128:$dst,
6421     (int_x86_aesni_aesimc (bitconvert (memopv2i64 addr:$src1))))]>,
6422   OpSize;
6423
6424 // AES Round Key Generation Assist
6425 let Predicates = [HasAVX, HasAES] in {
6426   def VAESKEYGENASSIST128rr : AESAI<0xDF, MRMSrcReg, (outs VR128:$dst),
6427       (ins VR128:$src1, i8imm:$src2),
6428       "vaeskeygenassist\t{$src2, $src1, $dst|$dst, $src1, $src2}",
6429       [(set VR128:$dst,
6430         (int_x86_aesni_aeskeygenassist VR128:$src1, imm:$src2))]>,
6431       OpSize, VEX;
6432   def VAESKEYGENASSIST128rm : AESAI<0xDF, MRMSrcMem, (outs VR128:$dst),
6433       (ins i128mem:$src1, i8imm:$src2),
6434       "vaeskeygenassist\t{$src2, $src1, $dst|$dst, $src1, $src2}",
6435       [(set VR128:$dst,
6436         (int_x86_aesni_aeskeygenassist (bitconvert (memopv2i64 addr:$src1)),
6437                                         imm:$src2))]>,
6438       OpSize, VEX;
6439 }
6440 def AESKEYGENASSIST128rr : AESAI<0xDF, MRMSrcReg, (outs VR128:$dst),
6441   (ins VR128:$src1, i8imm:$src2),
6442   "aeskeygenassist\t{$src2, $src1, $dst|$dst, $src1, $src2}",
6443   [(set VR128:$dst,
6444     (int_x86_aesni_aeskeygenassist VR128:$src1, imm:$src2))]>,
6445   OpSize;
6446 def AESKEYGENASSIST128rm : AESAI<0xDF, MRMSrcMem, (outs VR128:$dst),
6447   (ins i128mem:$src1, i8imm:$src2),
6448   "aeskeygenassist\t{$src2, $src1, $dst|$dst, $src1, $src2}",
6449   [(set VR128:$dst,
6450     (int_x86_aesni_aeskeygenassist (bitconvert (memopv2i64 addr:$src1)),
6451                                     imm:$src2))]>,
6452   OpSize;
6453
6454 //===----------------------------------------------------------------------===//
6455 // CLMUL Instructions
6456 //===----------------------------------------------------------------------===//
6457
6458 // Carry-less Multiplication instructions
6459 let Constraints = "$src1 = $dst" in {
6460 def PCLMULQDQrr : CLMULIi8<0x44, MRMSrcReg, (outs VR128:$dst),
6461            (ins VR128:$src1, VR128:$src2, i8imm:$src3),
6462            "pclmulqdq\t{$src3, $src2, $dst|$dst, $src2, $src3}",
6463            []>;
6464
6465 def PCLMULQDQrm : CLMULIi8<0x44, MRMSrcMem, (outs VR128:$dst),
6466            (ins VR128:$src1, i128mem:$src2, i8imm:$src3),
6467            "pclmulqdq\t{$src3, $src2, $dst|$dst, $src2, $src3}",
6468            []>;
6469 }
6470
6471 // AVX carry-less Multiplication instructions
6472 def VPCLMULQDQrr : AVXCLMULIi8<0x44, MRMSrcReg, (outs VR128:$dst),
6473            (ins VR128:$src1, VR128:$src2, i8imm:$src3),
6474            "vpclmulqdq\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
6475            []>;
6476
6477 def VPCLMULQDQrm : AVXCLMULIi8<0x44, MRMSrcMem, (outs VR128:$dst),
6478            (ins VR128:$src1, i128mem:$src2, i8imm:$src3),
6479            "vpclmulqdq\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
6480            []>;
6481
6482
6483 multiclass pclmul_alias<string asm, int immop> {
6484   def : InstAlias<!strconcat("pclmul", asm, 
6485                            "dq {$src, $dst|$dst, $src}"),
6486                   (PCLMULQDQrr VR128:$dst, VR128:$src, immop)>;
6487
6488   def : InstAlias<!strconcat("pclmul", asm, 
6489                              "dq {$src, $dst|$dst, $src}"),
6490                   (PCLMULQDQrm VR128:$dst, i128mem:$src, immop)>;
6491
6492   def : InstAlias<!strconcat("vpclmul", asm, 
6493                              "dq {$src2, $src1, $dst|$dst, $src1, $src2}"),
6494                   (VPCLMULQDQrr VR128:$dst, VR128:$src1, VR128:$src2, immop)>;
6495
6496   def : InstAlias<!strconcat("vpclmul", asm, 
6497                              "dq {$src2, $src1, $dst|$dst, $src1, $src2}"),
6498                   (VPCLMULQDQrm VR128:$dst, VR128:$src1, i128mem:$src2, immop)>;
6499 }
6500 defm : pclmul_alias<"hqhq", 0x11>;
6501 defm : pclmul_alias<"hqlq", 0x01>;
6502 defm : pclmul_alias<"lqhq", 0x10>;
6503 defm : pclmul_alias<"lqlq", 0x00>;
6504
6505 //===----------------------------------------------------------------------===//
6506 // AVX Instructions
6507 //===----------------------------------------------------------------------===//
6508
6509 //===----------------------------------------------------------------------===//
6510 // VBROADCAST - Load from memory and broadcast to all elements of the
6511 //              destination operand
6512 //
6513 class avx_broadcast<bits<8> opc, string OpcodeStr, RegisterClass RC,
6514                     X86MemOperand x86memop, Intrinsic Int> :
6515   AVX8I<opc, MRMSrcMem, (outs RC:$dst), (ins x86memop:$src),
6516         !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
6517         [(set RC:$dst, (Int addr:$src))]>, VEX;
6518
6519 def VBROADCASTSS   : avx_broadcast<0x18, "vbroadcastss", VR128, f32mem,
6520                                    int_x86_avx_vbroadcastss>;
6521 def VBROADCASTSSY  : avx_broadcast<0x18, "vbroadcastss", VR256, f32mem,
6522                                    int_x86_avx_vbroadcastss_256>;
6523 def VBROADCASTSD   : avx_broadcast<0x19, "vbroadcastsd", VR256, f64mem,
6524                                    int_x86_avx_vbroadcast_sd_256>;
6525 def VBROADCASTF128 : avx_broadcast<0x1A, "vbroadcastf128", VR256, f128mem,
6526                                    int_x86_avx_vbroadcastf128_pd_256>;
6527
6528 def : Pat<(int_x86_avx_vbroadcastf128_ps_256 addr:$src),
6529           (VBROADCASTF128 addr:$src)>;
6530
6531 def : Pat<(v8i32 (X86VBroadcast (loadi32 addr:$src))),
6532           (VBROADCASTSSY addr:$src)>;
6533 def : Pat<(v4i64 (X86VBroadcast (loadi64 addr:$src))),
6534           (VBROADCASTSD addr:$src)>;
6535 def : Pat<(v8f32 (X86VBroadcast (loadf32 addr:$src))),
6536           (VBROADCASTSSY addr:$src)>;
6537 def : Pat<(v4f64 (X86VBroadcast (loadf64 addr:$src))),
6538           (VBROADCASTSD addr:$src)>;
6539
6540 def : Pat<(v4f32 (X86VBroadcast (loadf32 addr:$src))),
6541           (VBROADCASTSS addr:$src)>;
6542 def : Pat<(v4i32 (X86VBroadcast (loadi32 addr:$src))),
6543           (VBROADCASTSS addr:$src)>;
6544
6545 //===----------------------------------------------------------------------===//
6546 // VINSERTF128 - Insert packed floating-point values
6547 //
6548 def VINSERTF128rr : AVXAIi8<0x18, MRMSrcReg, (outs VR256:$dst),
6549           (ins VR256:$src1, VR128:$src2, i8imm:$src3),
6550           "vinsertf128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
6551           []>, VEX_4V;
6552 def VINSERTF128rm : AVXAIi8<0x18, MRMSrcMem, (outs VR256:$dst),
6553           (ins VR256:$src1, f128mem:$src2, i8imm:$src3),
6554           "vinsertf128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
6555           []>, VEX_4V;
6556
6557 def : Pat<(int_x86_avx_vinsertf128_pd_256 VR256:$src1, VR128:$src2, imm:$src3),
6558           (VINSERTF128rr VR256:$src1, VR128:$src2, imm:$src3)>;
6559 def : Pat<(int_x86_avx_vinsertf128_ps_256 VR256:$src1, VR128:$src2, imm:$src3),
6560           (VINSERTF128rr VR256:$src1, VR128:$src2, imm:$src3)>;
6561 def : Pat<(int_x86_avx_vinsertf128_si_256 VR256:$src1, VR128:$src2, imm:$src3),
6562           (VINSERTF128rr VR256:$src1, VR128:$src2, imm:$src3)>;
6563
6564 def : Pat<(vinsertf128_insert:$ins (v8f32 VR256:$src1), (v4f32 VR128:$src2),
6565                                    (i32 imm)),
6566           (VINSERTF128rr VR256:$src1, VR128:$src2,
6567                          (INSERT_get_vinsertf128_imm VR256:$ins))>;
6568 def : Pat<(vinsertf128_insert:$ins (v4f64 VR256:$src1), (v2f64 VR128:$src2),
6569                                    (i32 imm)),
6570           (VINSERTF128rr VR256:$src1, VR128:$src2,
6571                          (INSERT_get_vinsertf128_imm VR256:$ins))>;
6572 def : Pat<(vinsertf128_insert:$ins (v8i32 VR256:$src1), (v4i32 VR128:$src2),
6573                                    (i32 imm)),
6574           (VINSERTF128rr VR256:$src1, VR128:$src2,
6575                          (INSERT_get_vinsertf128_imm VR256:$ins))>;
6576 def : Pat<(vinsertf128_insert:$ins (v4i64 VR256:$src1), (v2i64 VR128:$src2),
6577                                    (i32 imm)),
6578           (VINSERTF128rr VR256:$src1, VR128:$src2,
6579                          (INSERT_get_vinsertf128_imm VR256:$ins))>;
6580 def : Pat<(vinsertf128_insert:$ins (v32i8 VR256:$src1), (v16i8 VR128:$src2),
6581                                    (i32 imm)),
6582           (VINSERTF128rr VR256:$src1, VR128:$src2,
6583                          (INSERT_get_vinsertf128_imm VR256:$ins))>;
6584 def : Pat<(vinsertf128_insert:$ins (v16i16 VR256:$src1), (v8i16 VR128:$src2),
6585                                    (i32 imm)),
6586           (VINSERTF128rr VR256:$src1, VR128:$src2,
6587                          (INSERT_get_vinsertf128_imm VR256:$ins))>;
6588
6589 //===----------------------------------------------------------------------===//
6590 // VEXTRACTF128 - Extract packed floating-point values
6591 //
6592 def VEXTRACTF128rr : AVXAIi8<0x19, MRMDestReg, (outs VR128:$dst),
6593           (ins VR256:$src1, i8imm:$src2),
6594           "vextractf128\t{$src2, $src1, $dst|$dst, $src1, $src2}",
6595           []>, VEX;
6596 def VEXTRACTF128mr : AVXAIi8<0x19, MRMDestMem, (outs),
6597           (ins f128mem:$dst, VR256:$src1, i8imm:$src2),
6598           "vextractf128\t{$src2, $src1, $dst|$dst, $src1, $src2}",
6599           []>, VEX;
6600
6601 def : Pat<(int_x86_avx_vextractf128_pd_256 VR256:$src1, imm:$src2),
6602           (VEXTRACTF128rr VR256:$src1, imm:$src2)>;
6603 def : Pat<(int_x86_avx_vextractf128_ps_256 VR256:$src1, imm:$src2),
6604           (VEXTRACTF128rr VR256:$src1, imm:$src2)>;
6605 def : Pat<(int_x86_avx_vextractf128_si_256 VR256:$src1, imm:$src2),
6606           (VEXTRACTF128rr VR256:$src1, imm:$src2)>;
6607
6608 def : Pat<(vextractf128_extract:$ext VR256:$src1, (i32 imm)),
6609           (v4f32 (VEXTRACTF128rr
6610                     (v8f32 VR256:$src1),
6611                     (EXTRACT_get_vextractf128_imm VR128:$ext)))>;
6612 def : Pat<(vextractf128_extract:$ext VR256:$src1, (i32 imm)),
6613           (v2f64 (VEXTRACTF128rr
6614                     (v4f64 VR256:$src1),
6615                     (EXTRACT_get_vextractf128_imm VR128:$ext)))>;
6616 def : Pat<(vextractf128_extract:$ext VR256:$src1, (i32 imm)),
6617           (v4i32 (VEXTRACTF128rr
6618                     (v8i32 VR256:$src1),
6619                     (EXTRACT_get_vextractf128_imm VR128:$ext)))>;
6620 def : Pat<(vextractf128_extract:$ext VR256:$src1, (i32 imm)),
6621           (v2i64 (VEXTRACTF128rr
6622                     (v4i64 VR256:$src1),
6623                     (EXTRACT_get_vextractf128_imm VR128:$ext)))>;
6624 def : Pat<(vextractf128_extract:$ext VR256:$src1, (i32 imm)),
6625           (v8i16 (VEXTRACTF128rr
6626                     (v16i16 VR256:$src1),
6627                     (EXTRACT_get_vextractf128_imm VR128:$ext)))>;
6628 def : Pat<(vextractf128_extract:$ext VR256:$src1, (i32 imm)),
6629           (v16i8 (VEXTRACTF128rr
6630                     (v32i8 VR256:$src1),
6631                     (EXTRACT_get_vextractf128_imm VR128:$ext)))>;
6632
6633 //===----------------------------------------------------------------------===//
6634 // VMASKMOV - Conditional SIMD Packed Loads and Stores
6635 //
6636 multiclass avx_movmask_rm<bits<8> opc_rm, bits<8> opc_mr, string OpcodeStr,
6637                           Intrinsic IntLd, Intrinsic IntLd256,
6638                           Intrinsic IntSt, Intrinsic IntSt256,
6639                           PatFrag pf128, PatFrag pf256> {
6640   def rm  : AVX8I<opc_rm, MRMSrcMem, (outs VR128:$dst),
6641              (ins VR128:$src1, f128mem:$src2),
6642              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6643              [(set VR128:$dst, (IntLd addr:$src2, VR128:$src1))]>,
6644              VEX_4V;
6645   def Yrm : AVX8I<opc_rm, MRMSrcMem, (outs VR256:$dst),
6646              (ins VR256:$src1, f256mem:$src2),
6647              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6648              [(set VR256:$dst, (IntLd256 addr:$src2, VR256:$src1))]>,
6649              VEX_4V;
6650   def mr  : AVX8I<opc_mr, MRMDestMem, (outs),
6651              (ins f128mem:$dst, VR128:$src1, VR128:$src2),
6652              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6653              [(IntSt addr:$dst, VR128:$src1, VR128:$src2)]>, VEX_4V;
6654   def Ymr : AVX8I<opc_mr, MRMDestMem, (outs),
6655              (ins f256mem:$dst, VR256:$src1, VR256:$src2),
6656              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6657              [(IntSt256 addr:$dst, VR256:$src1, VR256:$src2)]>, VEX_4V;
6658 }
6659
6660 defm VMASKMOVPS : avx_movmask_rm<0x2C, 0x2E, "vmaskmovps",
6661                                  int_x86_avx_maskload_ps,
6662                                  int_x86_avx_maskload_ps_256,
6663                                  int_x86_avx_maskstore_ps,
6664                                  int_x86_avx_maskstore_ps_256,
6665                                  memopv4f32, memopv8f32>;
6666 defm VMASKMOVPD : avx_movmask_rm<0x2D, 0x2F, "vmaskmovpd",
6667                                  int_x86_avx_maskload_pd,
6668                                  int_x86_avx_maskload_pd_256,
6669                                  int_x86_avx_maskstore_pd,
6670                                  int_x86_avx_maskstore_pd_256,
6671                                  memopv2f64, memopv4f64>;
6672
6673 //===----------------------------------------------------------------------===//
6674 // VPERMIL - Permute Single and Double Floating-Point Values
6675 //
6676 multiclass avx_permil<bits<8> opc_rm, bits<8> opc_rmi, string OpcodeStr,
6677                       RegisterClass RC, X86MemOperand x86memop_f,
6678                       X86MemOperand x86memop_i, PatFrag f_frag, PatFrag i_frag,
6679                       Intrinsic IntVar, Intrinsic IntImm> {
6680   def rr  : AVX8I<opc_rm, MRMSrcReg, (outs RC:$dst),
6681              (ins RC:$src1, RC:$src2),
6682              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6683              [(set RC:$dst, (IntVar RC:$src1, RC:$src2))]>, VEX_4V;
6684   def rm  : AVX8I<opc_rm, MRMSrcMem, (outs RC:$dst),
6685              (ins RC:$src1, x86memop_i:$src2),
6686              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6687              [(set RC:$dst, (IntVar RC:$src1, (i_frag addr:$src2)))]>, VEX_4V;
6688
6689   def ri  : AVXAIi8<opc_rmi, MRMSrcReg, (outs RC:$dst),
6690              (ins RC:$src1, i8imm:$src2),
6691              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6692              [(set RC:$dst, (IntImm RC:$src1, imm:$src2))]>, VEX;
6693   def mi  : AVXAIi8<opc_rmi, MRMSrcMem, (outs RC:$dst),
6694              (ins x86memop_f:$src1, i8imm:$src2),
6695              !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
6696              [(set RC:$dst, (IntImm (f_frag addr:$src1), imm:$src2))]>, VEX;
6697 }
6698
6699 defm VPERMILPS  : avx_permil<0x0C, 0x04, "vpermilps", VR128, f128mem, i128mem,
6700                              memopv4f32, memopv4i32,
6701                              int_x86_avx_vpermilvar_ps,
6702                              int_x86_avx_vpermil_ps>;
6703 defm VPERMILPSY : avx_permil<0x0C, 0x04, "vpermilps", VR256, f256mem, i256mem,
6704                              memopv8f32, memopv8i32,
6705                              int_x86_avx_vpermilvar_ps_256,
6706                              int_x86_avx_vpermil_ps_256>;
6707 defm VPERMILPD  : avx_permil<0x0D, 0x05, "vpermilpd", VR128, f128mem, i128mem,
6708                              memopv2f64, memopv2i64,
6709                              int_x86_avx_vpermilvar_pd,
6710                              int_x86_avx_vpermil_pd>;
6711 defm VPERMILPDY : avx_permil<0x0D, 0x05, "vpermilpd", VR256, f256mem, i256mem,
6712                              memopv4f64, memopv4i64,
6713                              int_x86_avx_vpermilvar_pd_256,
6714                              int_x86_avx_vpermil_pd_256>;
6715
6716 def : Pat<(v8f32 (X86VPermilpsy VR256:$src1, (i8 imm:$imm))),
6717           (VPERMILPSYri VR256:$src1, imm:$imm)>;
6718 def : Pat<(v4f64 (X86VPermilpdy VR256:$src1, (i8 imm:$imm))),
6719           (VPERMILPDYri VR256:$src1, imm:$imm)>;
6720 def : Pat<(v8i32 (X86VPermilpsy VR256:$src1, (i8 imm:$imm))),
6721           (VPERMILPSYri VR256:$src1, imm:$imm)>;
6722 def : Pat<(v4i64 (X86VPermilpdy VR256:$src1, (i8 imm:$imm))),
6723           (VPERMILPDYri VR256:$src1, imm:$imm)>;
6724
6725 //===----------------------------------------------------------------------===//
6726 // VPERM2F128 - Permute Floating-Point Values in 128-bit chunks
6727 //
6728 def VPERM2F128rr : AVXAIi8<0x06, MRMSrcReg, (outs VR256:$dst),
6729           (ins VR256:$src1, VR256:$src2, i8imm:$src3),
6730           "vperm2f128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
6731           []>, VEX_4V;
6732 def VPERM2F128rm : AVXAIi8<0x06, MRMSrcMem, (outs VR256:$dst),
6733           (ins VR256:$src1, f256mem:$src2, i8imm:$src3),
6734           "vperm2f128\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
6735           []>, VEX_4V;
6736
6737 def : Pat<(int_x86_avx_vperm2f128_ps_256 VR256:$src1, VR256:$src2, imm:$src3),
6738           (VPERM2F128rr VR256:$src1, VR256:$src2, imm:$src3)>;
6739 def : Pat<(int_x86_avx_vperm2f128_pd_256 VR256:$src1, VR256:$src2, imm:$src3),
6740           (VPERM2F128rr VR256:$src1, VR256:$src2, imm:$src3)>;
6741 def : Pat<(int_x86_avx_vperm2f128_si_256 VR256:$src1, VR256:$src2, imm:$src3),
6742           (VPERM2F128rr VR256:$src1, VR256:$src2, imm:$src3)>;
6743
6744 def : Pat<(int_x86_avx_vperm2f128_ps_256
6745                   VR256:$src1, (memopv8f32 addr:$src2), imm:$src3),
6746           (VPERM2F128rm VR256:$src1, addr:$src2, imm:$src3)>;
6747 def : Pat<(int_x86_avx_vperm2f128_pd_256
6748                   VR256:$src1, (memopv4f64 addr:$src2), imm:$src3),
6749           (VPERM2F128rm VR256:$src1, addr:$src2, imm:$src3)>;
6750 def : Pat<(int_x86_avx_vperm2f128_si_256
6751                   VR256:$src1, (memopv8i32 addr:$src2), imm:$src3),
6752           (VPERM2F128rm VR256:$src1, addr:$src2, imm:$src3)>;
6753
6754 def : Pat<(v8f32 (X86VPerm2f128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
6755           (VPERM2F128rr VR256:$src1, VR256:$src2, imm:$imm)>;
6756 def : Pat<(v8i32 (X86VPerm2f128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
6757           (VPERM2F128rr VR256:$src1, VR256:$src2, imm:$imm)>;
6758 def : Pat<(v4i64 (X86VPerm2f128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
6759           (VPERM2F128rr VR256:$src1, VR256:$src2, imm:$imm)>;
6760 def : Pat<(v4f64 (X86VPerm2f128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
6761           (VPERM2F128rr VR256:$src1, VR256:$src2, imm:$imm)>;
6762 def : Pat<(v32i8 (X86VPerm2f128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
6763           (VPERM2F128rr VR256:$src1, VR256:$src2, imm:$imm)>;
6764 def : Pat<(v16i16 (X86VPerm2f128 VR256:$src1, VR256:$src2, (i8 imm:$imm))),
6765           (VPERM2F128rr VR256:$src1, VR256:$src2, imm:$imm)>;
6766
6767 //===----------------------------------------------------------------------===//
6768 // VZERO - Zero YMM registers
6769 //
6770 let Defs = [YMM0, YMM1, YMM2, YMM3, YMM4, YMM5, YMM6, YMM7,
6771             YMM8, YMM9, YMM10, YMM11, YMM12, YMM13, YMM14, YMM15] in {
6772   // Zero All YMM registers
6773   def VZEROALL : I<0x77, RawFrm, (outs), (ins), "vzeroall",
6774                    [(int_x86_avx_vzeroall)]>, TB, VEX, VEX_L, Requires<[HasAVX]>;
6775
6776   // Zero Upper bits of YMM registers
6777   def VZEROUPPER : I<0x77, RawFrm, (outs), (ins), "vzeroupper",
6778                      [(int_x86_avx_vzeroupper)]>, TB, VEX, Requires<[HasAVX]>;
6779 }
6780