3ea7ca99434ddf08714831e32663e07385f82fe5
[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 specific DAG Nodes.
19 //===----------------------------------------------------------------------===//
20
21 def SDTX86FPShiftOp : SDTypeProfile<1, 2, [ SDTCisSameAs<0, 1>,
22                                             SDTCisFP<0>, SDTCisInt<2> ]>;
23 def SDTX86VFCMP : SDTypeProfile<1, 3, [SDTCisInt<0>, SDTCisSameAs<1, 2>,
24                                        SDTCisFP<1>, SDTCisVT<3, i8>]>;
25
26 def X86fmin    : SDNode<"X86ISD::FMIN",      SDTFPBinOp>;
27 def X86fmax    : SDNode<"X86ISD::FMAX",      SDTFPBinOp>;
28 def X86fand    : SDNode<"X86ISD::FAND",      SDTFPBinOp,
29                         [SDNPCommutative, SDNPAssociative]>;
30 def X86for     : SDNode<"X86ISD::FOR",       SDTFPBinOp,
31                         [SDNPCommutative, SDNPAssociative]>;
32 def X86fxor    : SDNode<"X86ISD::FXOR",      SDTFPBinOp,
33                         [SDNPCommutative, SDNPAssociative]>;
34 def X86frsqrt  : SDNode<"X86ISD::FRSQRT",    SDTFPUnaryOp>;
35 def X86frcp    : SDNode<"X86ISD::FRCP",      SDTFPUnaryOp>;
36 def X86fsrl    : SDNode<"X86ISD::FSRL",      SDTX86FPShiftOp>;
37 def X86comi    : SDNode<"X86ISD::COMI",      SDTX86CmpTest>;
38 def X86ucomi   : SDNode<"X86ISD::UCOMI",     SDTX86CmpTest>;
39 def X86pshufb  : SDNode<"X86ISD::PSHUFB",
40                  SDTypeProfile<1, 2, [SDTCisVT<0, v16i8>, SDTCisSameAs<0,1>,
41                                       SDTCisSameAs<0,2>]>>;
42 def X86pextrb  : SDNode<"X86ISD::PEXTRB",
43                  SDTypeProfile<1, 2, [SDTCisVT<0, i32>, SDTCisPtrTy<2>]>>;
44 def X86pextrw  : SDNode<"X86ISD::PEXTRW",
45                  SDTypeProfile<1, 2, [SDTCisVT<0, i32>, SDTCisPtrTy<2>]>>;
46 def X86pinsrb  : SDNode<"X86ISD::PINSRB",
47                  SDTypeProfile<1, 3, [SDTCisVT<0, v16i8>, SDTCisSameAs<0,1>,
48                                       SDTCisVT<2, i32>, SDTCisPtrTy<3>]>>;
49 def X86pinsrw  : SDNode<"X86ISD::PINSRW",
50                  SDTypeProfile<1, 3, [SDTCisVT<0, v8i16>, SDTCisSameAs<0,1>,
51                                       SDTCisVT<2, i32>, SDTCisPtrTy<3>]>>;
52 def X86insrtps : SDNode<"X86ISD::INSERTPS",
53                  SDTypeProfile<1, 3, [SDTCisVT<0, v4f32>, SDTCisSameAs<0,1>,
54                                       SDTCisVT<2, v4f32>, SDTCisPtrTy<3>]>>;
55 def X86vzmovl  : SDNode<"X86ISD::VZEXT_MOVL",
56                  SDTypeProfile<1, 1, [SDTCisSameAs<0,1>]>>;
57 def X86vzload  : SDNode<"X86ISD::VZEXT_LOAD", SDTLoad,
58                         [SDNPHasChain, SDNPMayLoad]>;
59 def X86vshl    : SDNode<"X86ISD::VSHL",      SDTIntShiftOp>;
60 def X86vshr    : SDNode<"X86ISD::VSRL",      SDTIntShiftOp>;
61 def X86cmpps   : SDNode<"X86ISD::CMPPS",     SDTX86VFCMP>;
62 def X86cmppd   : SDNode<"X86ISD::CMPPD",     SDTX86VFCMP>;
63 def X86pcmpeqb : SDNode<"X86ISD::PCMPEQB", SDTIntBinOp, [SDNPCommutative]>;
64 def X86pcmpeqw : SDNode<"X86ISD::PCMPEQW", SDTIntBinOp, [SDNPCommutative]>;
65 def X86pcmpeqd : SDNode<"X86ISD::PCMPEQD", SDTIntBinOp, [SDNPCommutative]>;
66 def X86pcmpeqq : SDNode<"X86ISD::PCMPEQQ", SDTIntBinOp, [SDNPCommutative]>;
67 def X86pcmpgtb : SDNode<"X86ISD::PCMPGTB", SDTIntBinOp>;
68 def X86pcmpgtw : SDNode<"X86ISD::PCMPGTW", SDTIntBinOp>;
69 def X86pcmpgtd : SDNode<"X86ISD::PCMPGTD", SDTIntBinOp>;
70 def X86pcmpgtq : SDNode<"X86ISD::PCMPGTQ", SDTIntBinOp>;
71
72 def SDTX86CmpPTest : SDTypeProfile<1, 2, [SDTCisVT<0, i32>,
73                                           SDTCisVT<1, v4f32>,
74                                           SDTCisVT<2, v4f32>]>;
75 def X86ptest   : SDNode<"X86ISD::PTEST", SDTX86CmpPTest>;
76
77 //===----------------------------------------------------------------------===//
78 // SSE Complex Patterns
79 //===----------------------------------------------------------------------===//
80
81 // These are 'extloads' from a scalar to the low element of a vector, zeroing
82 // the top elements.  These are used for the SSE 'ss' and 'sd' instruction
83 // forms.
84 def sse_load_f32 : ComplexPattern<v4f32, 5, "SelectScalarSSELoad", [],
85                                   [SDNPHasChain, SDNPMayLoad]>;
86 def sse_load_f64 : ComplexPattern<v2f64, 5, "SelectScalarSSELoad", [],
87                                   [SDNPHasChain, SDNPMayLoad]>;
88
89 def ssmem : Operand<v4f32> {
90   let PrintMethod = "printf32mem";
91   let MIOperandInfo = (ops ptr_rc, i8imm, ptr_rc_nosp, i32imm, i8imm);
92   let ParserMatchClass = X86MemAsmOperand;
93 }
94 def sdmem : Operand<v2f64> {
95   let PrintMethod = "printf64mem";
96   let MIOperandInfo = (ops ptr_rc, i8imm, ptr_rc_nosp, i32imm, i8imm);
97   let ParserMatchClass = X86MemAsmOperand;
98 }
99
100 //===----------------------------------------------------------------------===//
101 // SSE pattern fragments
102 //===----------------------------------------------------------------------===//
103
104 def loadv4f32    : PatFrag<(ops node:$ptr), (v4f32 (load node:$ptr))>;
105 def loadv2f64    : PatFrag<(ops node:$ptr), (v2f64 (load node:$ptr))>;
106 def loadv4i32    : PatFrag<(ops node:$ptr), (v4i32 (load node:$ptr))>;
107 def loadv2i64    : PatFrag<(ops node:$ptr), (v2i64 (load node:$ptr))>;
108
109 // Like 'store', but always requires vector alignment.
110 def alignedstore : PatFrag<(ops node:$val, node:$ptr),
111                            (store node:$val, node:$ptr), [{
112   return cast<StoreSDNode>(N)->getAlignment() >= 16;
113 }]>;
114
115 // Like 'load', but always requires vector alignment.
116 def alignedload : PatFrag<(ops node:$ptr), (load node:$ptr), [{
117   return cast<LoadSDNode>(N)->getAlignment() >= 16;
118 }]>;
119
120 def alignedloadfsf32 : PatFrag<(ops node:$ptr),
121                                (f32 (alignedload node:$ptr))>;
122 def alignedloadfsf64 : PatFrag<(ops node:$ptr),
123                                (f64 (alignedload node:$ptr))>;
124 def alignedloadv4f32 : PatFrag<(ops node:$ptr),
125                                (v4f32 (alignedload node:$ptr))>;
126 def alignedloadv2f64 : PatFrag<(ops node:$ptr),
127                                (v2f64 (alignedload node:$ptr))>;
128 def alignedloadv4i32 : PatFrag<(ops node:$ptr),
129                                (v4i32 (alignedload node:$ptr))>;
130 def alignedloadv2i64 : PatFrag<(ops node:$ptr),
131                                (v2i64 (alignedload node:$ptr))>;
132
133 // Like 'load', but uses special alignment checks suitable for use in
134 // memory operands in most SSE instructions, which are required to
135 // be naturally aligned on some targets but not on others.  If the subtarget
136 // allows unaligned accesses, match any load, though this may require
137 // setting a feature bit in the processor (on startup, for example).
138 // Opteron 10h and later implement such a feature.
139 def memop : PatFrag<(ops node:$ptr), (load node:$ptr), [{
140   return    Subtarget->hasVectorUAMem()
141          || cast<LoadSDNode>(N)->getAlignment() >= 16;
142 }]>;
143
144 def memopfsf32 : PatFrag<(ops node:$ptr), (f32   (memop node:$ptr))>;
145 def memopfsf64 : PatFrag<(ops node:$ptr), (f64   (memop node:$ptr))>;
146 def memopv4f32 : PatFrag<(ops node:$ptr), (v4f32 (memop node:$ptr))>;
147 def memopv2f64 : PatFrag<(ops node:$ptr), (v2f64 (memop node:$ptr))>;
148 def memopv4i32 : PatFrag<(ops node:$ptr), (v4i32 (memop node:$ptr))>;
149 def memopv2i64 : PatFrag<(ops node:$ptr), (v2i64 (memop node:$ptr))>;
150 def memopv16i8 : PatFrag<(ops node:$ptr), (v16i8 (memop node:$ptr))>;
151
152 // SSSE3 uses MMX registers for some instructions. They aren't aligned on a
153 // 16-byte boundary.
154 // FIXME: 8 byte alignment for mmx reads is not required
155 def memop64 : PatFrag<(ops node:$ptr), (load node:$ptr), [{
156   return cast<LoadSDNode>(N)->getAlignment() >= 8;
157 }]>;
158
159 def memopv8i8  : PatFrag<(ops node:$ptr), (v8i8  (memop64 node:$ptr))>;
160 def memopv4i16 : PatFrag<(ops node:$ptr), (v4i16 (memop64 node:$ptr))>;
161 def memopv8i16 : PatFrag<(ops node:$ptr), (v8i16 (memop64 node:$ptr))>;
162 def memopv2i32 : PatFrag<(ops node:$ptr), (v2i32 (memop64 node:$ptr))>;
163
164 // MOVNT Support
165 // Like 'store', but requires the non-temporal bit to be set
166 def nontemporalstore : PatFrag<(ops node:$val, node:$ptr),
167                            (st node:$val, node:$ptr), [{
168   if (StoreSDNode *ST = dyn_cast<StoreSDNode>(N))
169     return ST->isNonTemporal();
170   return false;
171 }]>;
172
173 def alignednontemporalstore : PatFrag<(ops node:$val, node:$ptr),
174                                    (st node:$val, node:$ptr), [{
175   if (StoreSDNode *ST = dyn_cast<StoreSDNode>(N))
176     return ST->isNonTemporal() && !ST->isTruncatingStore() &&
177            ST->getAddressingMode() == ISD::UNINDEXED &&
178            ST->getAlignment() >= 16;
179   return false;
180 }]>;
181
182 def unalignednontemporalstore : PatFrag<(ops node:$val, node:$ptr),
183                                    (st node:$val, node:$ptr), [{
184   if (StoreSDNode *ST = dyn_cast<StoreSDNode>(N))
185     return ST->isNonTemporal() &&
186            ST->getAlignment() < 16;
187   return false;
188 }]>;
189
190 def bc_v4f32 : PatFrag<(ops node:$in), (v4f32 (bitconvert node:$in))>;
191 def bc_v2f64 : PatFrag<(ops node:$in), (v2f64 (bitconvert node:$in))>;
192 def bc_v16i8 : PatFrag<(ops node:$in), (v16i8 (bitconvert node:$in))>;
193 def bc_v8i16 : PatFrag<(ops node:$in), (v8i16 (bitconvert node:$in))>;
194 def bc_v4i32 : PatFrag<(ops node:$in), (v4i32 (bitconvert node:$in))>;
195 def bc_v2i64 : PatFrag<(ops node:$in), (v2i64 (bitconvert node:$in))>;
196
197 def vzmovl_v2i64 : PatFrag<(ops node:$src),
198                            (bitconvert (v2i64 (X86vzmovl
199                              (v2i64 (scalar_to_vector (loadi64 node:$src))))))>;
200 def vzmovl_v4i32 : PatFrag<(ops node:$src),
201                            (bitconvert (v4i32 (X86vzmovl
202                              (v4i32 (scalar_to_vector (loadi32 node:$src))))))>;
203
204 def vzload_v2i64 : PatFrag<(ops node:$src),
205                            (bitconvert (v2i64 (X86vzload node:$src)))>;
206
207
208 def fp32imm0 : PatLeaf<(f32 fpimm), [{
209   return N->isExactlyValue(+0.0);
210 }]>;
211
212 // BYTE_imm - Transform bit immediates into byte immediates.
213 def BYTE_imm  : SDNodeXForm<imm, [{
214   // Transformation function: imm >> 3
215   return getI32Imm(N->getZExtValue() >> 3);
216 }]>;
217
218 // SHUFFLE_get_shuf_imm xform function: convert vector_shuffle mask to PSHUF*,
219 // SHUFP* etc. imm.
220 def SHUFFLE_get_shuf_imm : SDNodeXForm<vector_shuffle, [{
221   return getI8Imm(X86::getShuffleSHUFImmediate(N));
222 }]>;
223
224 // SHUFFLE_get_pshufhw_imm xform function: convert vector_shuffle mask to
225 // PSHUFHW imm.
226 def SHUFFLE_get_pshufhw_imm : SDNodeXForm<vector_shuffle, [{
227   return getI8Imm(X86::getShufflePSHUFHWImmediate(N));
228 }]>;
229
230 // SHUFFLE_get_pshuflw_imm xform function: convert vector_shuffle mask to
231 // PSHUFLW imm.
232 def SHUFFLE_get_pshuflw_imm : SDNodeXForm<vector_shuffle, [{
233   return getI8Imm(X86::getShufflePSHUFLWImmediate(N));
234 }]>;
235
236 // SHUFFLE_get_palign_imm xform function: convert vector_shuffle mask to
237 // a PALIGNR imm.
238 def SHUFFLE_get_palign_imm : SDNodeXForm<vector_shuffle, [{
239   return getI8Imm(X86::getShufflePALIGNRImmediate(N));
240 }]>;
241
242 def splat_lo : PatFrag<(ops node:$lhs, node:$rhs),
243                        (vector_shuffle node:$lhs, node:$rhs), [{
244   ShuffleVectorSDNode *SVOp = cast<ShuffleVectorSDNode>(N);
245   return SVOp->isSplat() && SVOp->getSplatIndex() == 0;
246 }]>;
247
248 def movddup : PatFrag<(ops node:$lhs, node:$rhs),
249                       (vector_shuffle node:$lhs, node:$rhs), [{
250   return X86::isMOVDDUPMask(cast<ShuffleVectorSDNode>(N));
251 }]>;
252
253 def movhlps : PatFrag<(ops node:$lhs, node:$rhs),
254                       (vector_shuffle node:$lhs, node:$rhs), [{
255   return X86::isMOVHLPSMask(cast<ShuffleVectorSDNode>(N));
256 }]>;
257
258 def movhlps_undef : PatFrag<(ops node:$lhs, node:$rhs),
259                             (vector_shuffle node:$lhs, node:$rhs), [{
260   return X86::isMOVHLPS_v_undef_Mask(cast<ShuffleVectorSDNode>(N));
261 }]>;
262
263 def movlhps : PatFrag<(ops node:$lhs, node:$rhs),
264                       (vector_shuffle node:$lhs, node:$rhs), [{
265   return X86::isMOVLHPSMask(cast<ShuffleVectorSDNode>(N));
266 }]>;
267
268 def movlp : PatFrag<(ops node:$lhs, node:$rhs),
269                     (vector_shuffle node:$lhs, node:$rhs), [{
270   return X86::isMOVLPMask(cast<ShuffleVectorSDNode>(N));
271 }]>;
272
273 def movl : PatFrag<(ops node:$lhs, node:$rhs),
274                    (vector_shuffle node:$lhs, node:$rhs), [{
275   return X86::isMOVLMask(cast<ShuffleVectorSDNode>(N));
276 }]>;
277
278 def movshdup : PatFrag<(ops node:$lhs, node:$rhs),
279                        (vector_shuffle node:$lhs, node:$rhs), [{
280   return X86::isMOVSHDUPMask(cast<ShuffleVectorSDNode>(N));
281 }]>;
282
283 def movsldup : PatFrag<(ops node:$lhs, node:$rhs),
284                        (vector_shuffle node:$lhs, node:$rhs), [{
285   return X86::isMOVSLDUPMask(cast<ShuffleVectorSDNode>(N));
286 }]>;
287
288 def unpckl : PatFrag<(ops node:$lhs, node:$rhs),
289                      (vector_shuffle node:$lhs, node:$rhs), [{
290   return X86::isUNPCKLMask(cast<ShuffleVectorSDNode>(N));
291 }]>;
292
293 def unpckh : PatFrag<(ops node:$lhs, node:$rhs),
294                      (vector_shuffle node:$lhs, node:$rhs), [{
295   return X86::isUNPCKHMask(cast<ShuffleVectorSDNode>(N));
296 }]>;
297
298 def unpckl_undef : PatFrag<(ops node:$lhs, node:$rhs),
299                            (vector_shuffle node:$lhs, node:$rhs), [{
300   return X86::isUNPCKL_v_undef_Mask(cast<ShuffleVectorSDNode>(N));
301 }]>;
302
303 def unpckh_undef : PatFrag<(ops node:$lhs, node:$rhs),
304                            (vector_shuffle node:$lhs, node:$rhs), [{
305   return X86::isUNPCKH_v_undef_Mask(cast<ShuffleVectorSDNode>(N));
306 }]>;
307
308 def pshufd : PatFrag<(ops node:$lhs, node:$rhs),
309                      (vector_shuffle node:$lhs, node:$rhs), [{
310   return X86::isPSHUFDMask(cast<ShuffleVectorSDNode>(N));
311 }], SHUFFLE_get_shuf_imm>;
312
313 def shufp : PatFrag<(ops node:$lhs, node:$rhs),
314                     (vector_shuffle node:$lhs, node:$rhs), [{
315   return X86::isSHUFPMask(cast<ShuffleVectorSDNode>(N));
316 }], SHUFFLE_get_shuf_imm>;
317
318 def pshufhw : PatFrag<(ops node:$lhs, node:$rhs),
319                       (vector_shuffle node:$lhs, node:$rhs), [{
320   return X86::isPSHUFHWMask(cast<ShuffleVectorSDNode>(N));
321 }], SHUFFLE_get_pshufhw_imm>;
322
323 def pshuflw : PatFrag<(ops node:$lhs, node:$rhs),
324                       (vector_shuffle node:$lhs, node:$rhs), [{
325   return X86::isPSHUFLWMask(cast<ShuffleVectorSDNode>(N));
326 }], SHUFFLE_get_pshuflw_imm>;
327
328 def palign : PatFrag<(ops node:$lhs, node:$rhs),
329                      (vector_shuffle node:$lhs, node:$rhs), [{
330   return X86::isPALIGNRMask(cast<ShuffleVectorSDNode>(N));
331 }], SHUFFLE_get_palign_imm>;
332
333 //===----------------------------------------------------------------------===//
334 // SSE scalar FP Instructions
335 //===----------------------------------------------------------------------===//
336
337 // CMOV* - Used to implement the SSE SELECT DAG operation.  Expanded after
338 // instruction selection into a branch sequence.
339 let Uses = [EFLAGS], usesCustomInserter = 1 in {
340   def CMOV_FR32 : I<0, Pseudo,
341                     (outs FR32:$dst), (ins FR32:$t, FR32:$f, i8imm:$cond),
342                     "#CMOV_FR32 PSEUDO!",
343                     [(set FR32:$dst, (X86cmov FR32:$t, FR32:$f, imm:$cond,
344                                                   EFLAGS))]>;
345   def CMOV_FR64 : I<0, Pseudo,
346                     (outs FR64:$dst), (ins FR64:$t, FR64:$f, i8imm:$cond),
347                     "#CMOV_FR64 PSEUDO!",
348                     [(set FR64:$dst, (X86cmov FR64:$t, FR64:$f, imm:$cond,
349                                                   EFLAGS))]>;
350   def CMOV_V4F32 : I<0, Pseudo,
351                     (outs VR128:$dst), (ins VR128:$t, VR128:$f, i8imm:$cond),
352                     "#CMOV_V4F32 PSEUDO!",
353                     [(set VR128:$dst,
354                       (v4f32 (X86cmov VR128:$t, VR128:$f, imm:$cond,
355                                           EFLAGS)))]>;
356   def CMOV_V2F64 : I<0, Pseudo,
357                     (outs VR128:$dst), (ins VR128:$t, VR128:$f, i8imm:$cond),
358                     "#CMOV_V2F64 PSEUDO!",
359                     [(set VR128:$dst,
360                       (v2f64 (X86cmov VR128:$t, VR128:$f, imm:$cond,
361                                           EFLAGS)))]>;
362   def CMOV_V2I64 : I<0, Pseudo,
363                     (outs VR128:$dst), (ins VR128:$t, VR128:$f, i8imm:$cond),
364                     "#CMOV_V2I64 PSEUDO!",
365                     [(set VR128:$dst,
366                       (v2i64 (X86cmov VR128:$t, VR128:$f, imm:$cond,
367                                           EFLAGS)))]>;
368 }
369
370 //===----------------------------------------------------------------------===//
371 // SSE 1 & 2 Instructions Classes
372 //===----------------------------------------------------------------------===//
373
374 /// sse12_fp_scalar - SSE 1 & 2 scalar instructions class
375 multiclass sse12_fp_scalar<bits<8> opc, string OpcodeStr, SDNode OpNode,
376                            RegisterClass RC, X86MemOperand x86memop> {
377   let isCommutable = 1 in {
378     def rr : SI<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
379                 OpcodeStr, [(set RC:$dst, (OpNode RC:$src1, RC:$src2))]>;
380   }
381   def rm : SI<opc, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
382               OpcodeStr, [(set RC:$dst, (OpNode RC:$src1, (load addr:$src2)))]>;
383 }
384
385 /// sse12_fp_scalar_int - SSE 1 & 2 scalar instructions intrinsics class
386 multiclass sse12_fp_scalar_int<bits<8> opc, string OpcodeStr, RegisterClass RC,
387                                string asm, string SSEVer, string FPSizeStr,
388                                Operand memopr, ComplexPattern mem_cpat> {
389   def rr_Int : SI<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
390                   asm, [(set RC:$dst, (
391                                 !nameconcat<Intrinsic>("int_x86_sse",
392                                 !strconcat(SSEVer, !strconcat("_",
393                                 !strconcat(OpcodeStr, FPSizeStr))))
394                          RC:$src1, RC:$src2))]>;
395   def rm_Int : SI<opc, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, memopr:$src2),
396                   asm, [(set RC:$dst, (
397                                 !nameconcat<Intrinsic>("int_x86_sse",
398                                 !strconcat(SSEVer, !strconcat("_",
399                                 !strconcat(OpcodeStr, FPSizeStr))))
400                          RC:$src1, mem_cpat:$src2))]>;
401 }
402
403 /// sse12_fp_packed - SSE 1 & 2 packed instructions class
404 multiclass sse12_fp_packed<bits<8> opc, string OpcodeStr, SDNode OpNode,
405                            RegisterClass RC, ValueType vt,
406                            X86MemOperand x86memop, PatFrag mem_frag,
407                            Domain d, bit MayLoad = 0> {
408   let isCommutable = 1 in
409     def rr : PI<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
410                 OpcodeStr, [(set RC:$dst, (vt (OpNode RC:$src1, RC:$src2)))],d>;
411   let mayLoad = MayLoad in
412     def rm : PI<opc, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
413                 OpcodeStr, [(set RC:$dst, (OpNode RC:$src1,
414                                                   (mem_frag addr:$src2)))],d>;
415 }
416
417 /// sse12_fp_packed_logical_rm - SSE 1 & 2 packed instructions class
418 multiclass sse12_fp_packed_logical_rm<bits<8> opc, RegisterClass RC, Domain d,
419                                       string OpcodeStr, X86MemOperand x86memop,
420                                       list<dag> pat_rr, list<dag> pat_rm> {
421   let isCommutable = 1 in
422     def rr : PI<opc, MRMSrcReg, (outs RC:$dst),
423                 (ins RC:$src1, RC:$src2), OpcodeStr, pat_rr, d>;
424   def rm : PI<opc, MRMSrcMem, (outs RC:$dst),
425                 (ins RC:$src1, x86memop:$src2), OpcodeStr, pat_rm, d>;
426 }
427
428 /// sse12_fp_packed_int - SSE 1 & 2 packed instructions intrinsics class
429 multiclass sse12_fp_packed_int<bits<8> opc, string OpcodeStr, RegisterClass RC,
430                                string asm, string SSEVer, string FPSizeStr,
431                                X86MemOperand x86memop, PatFrag mem_frag,
432                                Domain d> {
433   def rr_Int : PI<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
434                   asm, [(set RC:$dst, (
435                                 !nameconcat<Intrinsic>("int_x86_sse",
436                                 !strconcat(SSEVer, !strconcat("_",
437                                 !strconcat(OpcodeStr, FPSizeStr))))
438                          RC:$src1, RC:$src2))], d>;
439   def rm_Int : PI<opc, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
440                   asm, [(set RC:$dst, (
441                                 !nameconcat<Intrinsic>("int_x86_sse",
442                                 !strconcat(SSEVer, !strconcat("_",
443                                 !strconcat(OpcodeStr, FPSizeStr))))
444                          RC:$src1, (mem_frag addr:$src2)))], d>;
445 }
446
447 //===----------------------------------------------------------------------===//
448 // SSE1 Instructions
449 //===----------------------------------------------------------------------===//
450
451 // Conversion Instructions
452
453 // Match intrinsics which expect XMM operand(s).
454 def CVTSS2SIrr: SSI<0x2D, MRMSrcReg, (outs GR32:$dst), (ins FR32:$src),
455                     "cvtss2si{l}\t{$src, $dst|$dst, $src}", []>;
456 def CVTSS2SIrm: SSI<0x2D, MRMSrcMem, (outs GR32:$dst), (ins f32mem:$src),
457                     "cvtss2si{l}\t{$src, $dst|$dst, $src}", []>;
458
459 def CVTDQ2PSrr : PSI<0x5B, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
460                      "cvtdq2ps\t{$src, $dst|$dst, $src}", []>;
461 def CVTDQ2PSrm : PSI<0x5B, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
462                      "cvtdq2ps\t{$src, $dst|$dst, $src}", []>;
463
464 // Aliases for intrinsics
465 def Int_CVTTSS2SIrr : SSI<0x2C, MRMSrcReg, (outs GR32:$dst), (ins VR128:$src),
466                           "cvttss2si\t{$src, $dst|$dst, $src}",
467                           [(set GR32:$dst,
468                             (int_x86_sse_cvttss2si VR128:$src))]>;
469 def Int_CVTTSS2SIrm : SSI<0x2C, MRMSrcMem, (outs GR32:$dst), (ins f32mem:$src),
470                           "cvttss2si\t{$src, $dst|$dst, $src}",
471                           [(set GR32:$dst,
472                             (int_x86_sse_cvttss2si(load addr:$src)))]>;
473
474 let Constraints = "$src1 = $dst" in {
475   def Int_CVTSI2SSrr : SSI<0x2A, MRMSrcReg,
476                            (outs VR128:$dst), (ins VR128:$src1, GR32:$src2),
477                            "cvtsi2ss\t{$src2, $dst|$dst, $src2}",
478                            [(set VR128:$dst, (int_x86_sse_cvtsi2ss VR128:$src1,
479                                               GR32:$src2))]>;
480   def Int_CVTSI2SSrm : SSI<0x2A, MRMSrcMem,
481                            (outs VR128:$dst), (ins VR128:$src1, i32mem:$src2),
482                            "cvtsi2ss\t{$src2, $dst|$dst, $src2}",
483                            [(set VR128:$dst, (int_x86_sse_cvtsi2ss VR128:$src1,
484                                               (loadi32 addr:$src2)))]>;
485 }
486
487 // Compare Instructions
488 let Defs = [EFLAGS] in {
489 def COMISSrr: PSI<0x2F, MRMSrcReg, (outs), (ins VR128:$src1, VR128:$src2),
490                   "comiss\t{$src2, $src1|$src1, $src2}", []>;
491 def COMISSrm: PSI<0x2F, MRMSrcMem, (outs), (ins VR128:$src1, f128mem:$src2),
492                   "comiss\t{$src2, $src1|$src1, $src2}", []>;
493 } // Defs = [EFLAGS]
494
495 //===----------------------------------------------------------------------===//
496 // SSE 1 & 2 - Move Instructions
497 //===----------------------------------------------------------------------===//
498
499 class sse12_move_rr<RegisterClass RC, ValueType vt, string asm> :
500       SI<0x10, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src1, RC:$src2), asm,
501       [(set (vt VR128:$dst), (movl VR128:$src1, (scalar_to_vector RC:$src2)))]>;
502
503 // Loading from memory automatically zeroing upper bits.
504 class sse12_move_rm<RegisterClass RC, X86MemOperand x86memop,
505                     PatFrag mem_pat, string OpcodeStr> :
506       SI<0x10, MRMSrcMem, (outs RC:$dst), (ins x86memop:$src),
507          !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
508                         [(set RC:$dst, (mem_pat addr:$src))]>;
509
510 // Move Instructions. Register-to-register movss/movsd is not used for FR32/64
511 // register copies because it's a partial register update; FsMOVAPSrr/FsMOVAPDrr
512 // is used instead. Register-to-register movss/movsd is not modeled as an
513 // INSERT_SUBREG because INSERT_SUBREG requires that the insert be implementable
514 // in terms of a copy, and just mentioned, we don't use movss/movsd for copies.
515 let isAsmParserOnly = 1 in {
516   def VMOVSSrr : sse12_move_rr<FR32, v4f32,
517                   "movss\t{$src2, $src1, $dst|$dst, $src1, $src2}">, XS, VEX_4V;
518   def VMOVSDrr : sse12_move_rr<FR64, v2f64,
519                   "movsd\t{$src2, $src1, $dst|$dst, $src1, $src2}">, XD, VEX_4V;
520
521   let canFoldAsLoad = 1, isReMaterializable = 1 in {
522     def VMOVSSrm : sse12_move_rm<FR32, f32mem, loadf32, "movss">, XS, VEX;
523
524     let AddedComplexity = 20 in
525       def VMOVSDrm : sse12_move_rm<FR64, f64mem, loadf64, "movsd">, XD, VEX;
526   }
527 }
528
529 let Constraints = "$src1 = $dst" in {
530   def MOVSSrr : sse12_move_rr<FR32, v4f32,
531                           "movss\t{$src2, $dst|$dst, $src2}">, XS;
532   def MOVSDrr : sse12_move_rr<FR64, v2f64,
533                           "movsd\t{$src2, $dst|$dst, $src2}">, XD;
534 }
535
536 let canFoldAsLoad = 1, isReMaterializable = 1 in {
537   def MOVSSrm : sse12_move_rm<FR32, f32mem, loadf32, "movss">, XS;
538
539   let AddedComplexity = 20 in
540     def MOVSDrm : sse12_move_rm<FR64, f64mem, loadf64, "movsd">, XD;
541 }
542
543 let AddedComplexity = 15 in {
544 // Extract the low 32-bit value from one vector and insert it into another.
545 def : Pat<(v4f32 (movl VR128:$src1, VR128:$src2)),
546           (MOVSSrr (v4f32 VR128:$src1),
547                    (EXTRACT_SUBREG (v4f32 VR128:$src2), sub_ss))>;
548 // Extract the low 64-bit value from one vector and insert it into another.
549 def : Pat<(v2f64 (movl VR128:$src1, VR128:$src2)),
550           (MOVSDrr (v2f64 VR128:$src1),
551                    (EXTRACT_SUBREG (v2f64 VR128:$src2), sub_sd))>;
552 }
553
554 // Implicitly promote a 32-bit scalar to a vector.
555 def : Pat<(v4f32 (scalar_to_vector FR32:$src)),
556           (INSERT_SUBREG (v4f32 (IMPLICIT_DEF)), FR32:$src, sub_ss)>;
557 // Implicitly promote a 64-bit scalar to a vector.
558 def : Pat<(v2f64 (scalar_to_vector FR64:$src)),
559           (INSERT_SUBREG (v2f64 (IMPLICIT_DEF)), FR64:$src, sub_sd)>;
560
561 let AddedComplexity = 20 in {
562 // MOVSSrm zeros the high parts of the register; represent this
563 // with SUBREG_TO_REG.
564 def : Pat<(v4f32 (X86vzmovl (v4f32 (scalar_to_vector (loadf32 addr:$src))))),
565           (SUBREG_TO_REG (i32 0), (MOVSSrm addr:$src), sub_ss)>;
566 def : Pat<(v4f32 (scalar_to_vector (loadf32 addr:$src))),
567           (SUBREG_TO_REG (i32 0), (MOVSSrm addr:$src), sub_ss)>;
568 def : Pat<(v4f32 (X86vzmovl (loadv4f32 addr:$src))),
569           (SUBREG_TO_REG (i32 0), (MOVSSrm addr:$src), sub_ss)>;
570 // MOVSDrm zeros the high parts of the register; represent this
571 // with SUBREG_TO_REG.
572 def : Pat<(v2f64 (X86vzmovl (v2f64 (scalar_to_vector (loadf64 addr:$src))))),
573           (SUBREG_TO_REG (i64 0), (MOVSDrm addr:$src), sub_sd)>;
574 def : Pat<(v2f64 (scalar_to_vector (loadf64 addr:$src))),
575           (SUBREG_TO_REG (i64 0), (MOVSDrm addr:$src), sub_sd)>;
576 def : Pat<(v2f64 (X86vzmovl (loadv2f64 addr:$src))),
577           (SUBREG_TO_REG (i64 0), (MOVSDrm addr:$src), sub_sd)>;
578 def : Pat<(v2f64 (X86vzmovl (bc_v2f64 (loadv4f32 addr:$src)))),
579           (SUBREG_TO_REG (i64 0), (MOVSDrm addr:$src), sub_sd)>;
580 def : Pat<(v2f64 (X86vzload addr:$src)),
581           (SUBREG_TO_REG (i64 0), (MOVSDrm addr:$src), sub_sd)>;
582 }
583
584 // Store scalar value to memory.
585 def MOVSSmr : SSI<0x11, MRMDestMem, (outs), (ins f32mem:$dst, FR32:$src),
586                   "movss\t{$src, $dst|$dst, $src}",
587                   [(store FR32:$src, addr:$dst)]>;
588 def MOVSDmr : SDI<0x11, MRMDestMem, (outs), (ins f64mem:$dst, FR64:$src),
589                   "movsd\t{$src, $dst|$dst, $src}",
590                   [(store FR64:$src, addr:$dst)]>;
591
592 let isAsmParserOnly = 1 in {
593 def VMOVSSmr : SI<0x11, MRMDestMem, (outs), (ins f32mem:$dst, FR32:$src),
594                   "movss\t{$src, $dst|$dst, $src}",
595                   [(store FR32:$src, addr:$dst)]>, XS, VEX_4V;
596 def VMOVSDmr : SI<0x11, MRMDestMem, (outs), (ins f64mem:$dst, FR64:$src),
597                   "movsd\t{$src, $dst|$dst, $src}",
598                   [(store FR64:$src, addr:$dst)]>, XD, VEX_4V;
599 }
600
601 // Extract and store.
602 def : Pat<(store (f32 (vector_extract (v4f32 VR128:$src), (iPTR 0))),
603                  addr:$dst),
604           (MOVSSmr addr:$dst,
605                    (EXTRACT_SUBREG (v4f32 VR128:$src), sub_ss))>;
606 def : Pat<(store (f64 (vector_extract (v2f64 VR128:$src), (iPTR 0))),
607                  addr:$dst),
608           (MOVSDmr addr:$dst,
609                    (EXTRACT_SUBREG (v2f64 VR128:$src), sub_sd))>;
610
611 //===----------------------------------------------------------------------===//
612 // SSE 1 & 2 - Conversion Instructions
613 //===----------------------------------------------------------------------===//
614
615 // Conversion instructions
616 def CVTTSS2SIrr : SSI<0x2C, MRMSrcReg, (outs GR32:$dst), (ins FR32:$src),
617                       "cvttss2si\t{$src, $dst|$dst, $src}",
618                       [(set GR32:$dst, (fp_to_sint FR32:$src))]>;
619 def CVTTSS2SIrm : SSI<0x2C, MRMSrcMem, (outs GR32:$dst), (ins f32mem:$src),
620                       "cvttss2si\t{$src, $dst|$dst, $src}",
621                       [(set GR32:$dst, (fp_to_sint (loadf32 addr:$src)))]>;
622 def CVTTSD2SIrr : SDI<0x2C, MRMSrcReg, (outs GR32:$dst), (ins FR64:$src),
623                       "cvttsd2si\t{$src, $dst|$dst, $src}",
624                       [(set GR32:$dst, (fp_to_sint FR64:$src))]>;
625 def CVTTSD2SIrm : SDI<0x2C, MRMSrcMem, (outs GR32:$dst), (ins f64mem:$src),
626                       "cvttsd2si\t{$src, $dst|$dst, $src}",
627                       [(set GR32:$dst, (fp_to_sint (loadf64 addr:$src)))]>;
628
629 def CVTSI2SSrr  : SSI<0x2A, MRMSrcReg, (outs FR32:$dst), (ins GR32:$src),
630                       "cvtsi2ss\t{$src, $dst|$dst, $src}",
631                       [(set FR32:$dst, (sint_to_fp GR32:$src))]>;
632 def CVTSI2SSrm  : SSI<0x2A, MRMSrcMem, (outs FR32:$dst), (ins i32mem:$src),
633                       "cvtsi2ss\t{$src, $dst|$dst, $src}",
634                       [(set FR32:$dst, (sint_to_fp (loadi32 addr:$src)))]>;
635 def CVTSI2SDrr  : SDI<0x2A, MRMSrcReg, (outs FR64:$dst), (ins GR32:$src),
636                       "cvtsi2sd\t{$src, $dst|$dst, $src}",
637                       [(set FR64:$dst, (sint_to_fp GR32:$src))]>;
638 def CVTSI2SDrm  : SDI<0x2A, MRMSrcMem, (outs FR64:$dst), (ins i32mem:$src),
639                       "cvtsi2sd\t{$src, $dst|$dst, $src}",
640                       [(set FR64:$dst, (sint_to_fp (loadi32 addr:$src)))]>;
641
642 // Match intrinsics which expect XMM operand(s).
643 def Int_CVTSS2SIrr : SSI<0x2D, MRMSrcReg, (outs GR32:$dst), (ins VR128:$src),
644                          "cvtss2si\t{$src, $dst|$dst, $src}",
645                          [(set GR32:$dst, (int_x86_sse_cvtss2si VR128:$src))]>;
646 def Int_CVTSS2SIrm : SSI<0x2D, MRMSrcMem, (outs GR32:$dst), (ins f32mem:$src),
647                          "cvtss2si\t{$src, $dst|$dst, $src}",
648                          [(set GR32:$dst, (int_x86_sse_cvtss2si
649                                            (load addr:$src)))]>;
650 def Int_CVTSD2SIrr : SDI<0x2D, MRMSrcReg, (outs GR32:$dst), (ins VR128:$src),
651                          "cvtsd2si\t{$src, $dst|$dst, $src}",
652                          [(set GR32:$dst, (int_x86_sse2_cvtsd2si VR128:$src))]>;
653 def Int_CVTSD2SIrm : SDI<0x2D, MRMSrcMem, (outs GR32:$dst), (ins f128mem:$src),
654                          "cvtsd2si\t{$src, $dst|$dst, $src}",
655                          [(set GR32:$dst, (int_x86_sse2_cvtsd2si
656                                            (load addr:$src)))]>;
657
658 // Match intrinsics which expect MM and XMM operand(s).
659 def Int_CVTPS2PIrr : PSI<0x2D, MRMSrcReg, (outs VR64:$dst), (ins VR128:$src),
660                          "cvtps2pi\t{$src, $dst|$dst, $src}",
661                          [(set VR64:$dst, (int_x86_sse_cvtps2pi VR128:$src))]>;
662 def Int_CVTPS2PIrm : PSI<0x2D, MRMSrcMem, (outs VR64:$dst), (ins f64mem:$src),
663                          "cvtps2pi\t{$src, $dst|$dst, $src}",
664                          [(set VR64:$dst, (int_x86_sse_cvtps2pi
665                                            (load addr:$src)))]>;
666 def Int_CVTPD2PIrr : PDI<0x2D, MRMSrcReg, (outs VR64:$dst), (ins VR128:$src),
667                          "cvtpd2pi\t{$src, $dst|$dst, $src}",
668                          [(set VR64:$dst, (int_x86_sse_cvtpd2pi VR128:$src))]>;
669 def Int_CVTPD2PIrm : PDI<0x2D, MRMSrcMem, (outs VR64:$dst), (ins f128mem:$src),
670                          "cvtpd2pi\t{$src, $dst|$dst, $src}",
671                          [(set VR64:$dst, (int_x86_sse_cvtpd2pi
672                                            (memop addr:$src)))]>;
673
674 // Match intrinsics which expect MM and XMM operand(s).
675 def Int_CVTTPS2PIrr: PSI<0x2C, MRMSrcReg, (outs VR64:$dst), (ins VR128:$src),
676                          "cvttps2pi\t{$src, $dst|$dst, $src}",
677                          [(set VR64:$dst, (int_x86_sse_cvttps2pi VR128:$src))]>;
678 def Int_CVTTPS2PIrm: PSI<0x2C, MRMSrcMem, (outs VR64:$dst), (ins f64mem:$src),
679                          "cvttps2pi\t{$src, $dst|$dst, $src}",
680                          [(set VR64:$dst, (int_x86_sse_cvttps2pi
681                                            (load addr:$src)))]>;
682 def Int_CVTTPD2PIrr: PDI<0x2C, MRMSrcReg, (outs VR64:$dst), (ins VR128:$src),
683                          "cvttpd2pi\t{$src, $dst|$dst, $src}",
684                          [(set VR64:$dst, (int_x86_sse_cvttpd2pi VR128:$src))]>;
685 def Int_CVTTPD2PIrm: PDI<0x2C, MRMSrcMem, (outs VR64:$dst), (ins f128mem:$src),
686                          "cvttpd2pi\t{$src, $dst|$dst, $src}",
687                          [(set VR64:$dst, (int_x86_sse_cvttpd2pi
688                                            (memop addr:$src)))]>;
689
690 let Constraints = "$src1 = $dst" in {
691   def Int_CVTPI2PSrr : PSI<0x2A, MRMSrcReg,
692                            (outs VR128:$dst), (ins VR128:$src1, VR64:$src2),
693                         "cvtpi2ps\t{$src2, $dst|$dst, $src2}",
694                         [(set VR128:$dst, (int_x86_sse_cvtpi2ps VR128:$src1,
695                                            VR64:$src2))]>;
696   def Int_CVTPI2PSrm : PSI<0x2A, MRMSrcMem,
697                            (outs VR128:$dst), (ins VR128:$src1, i64mem:$src2),
698                         "cvtpi2ps\t{$src2, $dst|$dst, $src2}",
699                         [(set VR128:$dst, (int_x86_sse_cvtpi2ps VR128:$src1,
700                                             (load addr:$src2)))]>;
701 }
702
703 //===----------------------------------------------------------------------===//
704 // SSE 1 & 2 - Compare Instructions
705 //===----------------------------------------------------------------------===//
706
707 multiclass sse12_cmp<RegisterClass RC, X86MemOperand x86memop, Intrinsic Int,
708                      string asm, Domain d, Operand sse_imm_op> {
709   def rri : PIi8<0xC2, MRMSrcReg,
710              (outs RC:$dst), (ins RC:$src1, RC:$src, sse_imm_op:$cc), asm,
711              [(set RC:$dst, (Int RC:$src1, RC:$src, imm:$cc))], d>;
712   def rmi : PIi8<0xC2, MRMSrcMem,
713              (outs RC:$dst), (ins RC:$src1, f128mem:$src, sse_imm_op:$cc), asm,
714              [(set RC:$dst, (Int RC:$src1, (memop addr:$src), imm:$cc))], d>;
715 }
716
717 // FIXME: rename instructions to only use the class above
718 multiclass sse12_cmp_alt<RegisterClass RC, string asm, Domain d,
719                          Operand sse_imm_op> {
720   def rri_alt : PIi8<0xC2, MRMSrcReg,
721             (outs RC:$dst), (ins RC:$src1, RC:$src, sse_imm_op:$src2), asm,
722             [], d>;
723   def rmi_alt : PIi8<0xC2, MRMSrcMem,
724             (outs RC:$dst), (ins RC:$src1, f128mem:$src, sse_imm_op:$src2), asm,
725             [], d>;
726 }
727
728 // Comparison instructions
729 let Constraints = "$src1 = $dst", neverHasSideEffects = 1 in {
730   def CMPSSrr : SSIi8<0xC2, MRMSrcReg,
731                     (outs FR32:$dst), (ins FR32:$src1, FR32:$src, SSECC:$cc),
732                     "cmp${cc}ss\t{$src, $dst|$dst, $src}", []>;
733   let mayLoad = 1 in
734   def CMPSSrm : SSIi8<0xC2, MRMSrcMem,
735                     (outs FR32:$dst), (ins FR32:$src1, f32mem:$src, SSECC:$cc),
736                     "cmp${cc}ss\t{$src, $dst|$dst, $src}", []>;
737
738   def CMPSDrr : SDIi8<0xC2, MRMSrcReg,
739                     (outs FR64:$dst), (ins FR64:$src1, FR64:$src, SSECC:$cc),
740                     "cmp${cc}sd\t{$src, $dst|$dst, $src}", []>;
741   let mayLoad = 1 in
742   def CMPSDrm : SDIi8<0xC2, MRMSrcMem,
743                     (outs FR64:$dst), (ins FR64:$src1, f64mem:$src, SSECC:$cc),
744                     "cmp${cc}sd\t{$src, $dst|$dst, $src}", []>;
745
746 // Accept explicit immediate argument form instead of comparison code.
747 let isAsmParserOnly = 1 in {
748   def CMPSSrr_alt : SSIi8<0xC2, MRMSrcReg,
749                     (outs FR32:$dst), (ins FR32:$src1, FR32:$src, i8imm:$src2),
750                     "cmpss\t{$src2, $src, $dst|$dst, $src, $src2}", []>;
751   let mayLoad = 1 in
752   def CMPSSrm_alt : SSIi8<0xC2, MRMSrcMem,
753                     (outs FR32:$dst), (ins FR32:$src1, f32mem:$src, i8imm:$src2),
754                     "cmpss\t{$src2, $src, $dst|$dst, $src, $src2}", []>;
755
756   def CMPSDrr_alt : SDIi8<0xC2, MRMSrcReg,
757                     (outs FR64:$dst), (ins FR64:$src1, FR64:$src, i8imm:$src2),
758                     "cmpsd\t{$src2, $src, $dst|$dst, $src, $src2}", []>;
759   let mayLoad = 1 in
760   def CMPSDrm_alt : SDIi8<0xC2, MRMSrcMem,
761                     (outs FR64:$dst), (ins FR64:$src1, f64mem:$src, i8imm:$src2),
762                     "cmpsd\t{$src2, $src, $dst|$dst, $src, $src2}", []>;
763 }
764 }
765
766 let Defs = [EFLAGS] in {
767 def UCOMISSrr: PSI<0x2E, MRMSrcReg, (outs), (ins FR32:$src1, FR32:$src2),
768                    "ucomiss\t{$src2, $src1|$src1, $src2}",
769                    [(set EFLAGS, (X86cmp FR32:$src1, FR32:$src2))]>;
770 def UCOMISSrm: PSI<0x2E, MRMSrcMem, (outs), (ins FR32:$src1, f32mem:$src2),
771                    "ucomiss\t{$src2, $src1|$src1, $src2}",
772                    [(set EFLAGS, (X86cmp FR32:$src1, (loadf32 addr:$src2)))]>;
773 def UCOMISDrr: PDI<0x2E, MRMSrcReg, (outs), (ins FR64:$src1, FR64:$src2),
774                    "ucomisd\t{$src2, $src1|$src1, $src2}",
775                    [(set EFLAGS, (X86cmp FR64:$src1, FR64:$src2))]>;
776 def UCOMISDrm: PDI<0x2E, MRMSrcMem, (outs), (ins FR64:$src1, f64mem:$src2),
777                    "ucomisd\t{$src2, $src1|$src1, $src2}",
778                    [(set EFLAGS, (X86cmp FR64:$src1, (loadf64 addr:$src2)))]>;
779 } // Defs = [EFLAGS]
780
781 // Aliases to match intrinsics which expect XMM operand(s).
782 let Constraints = "$src1 = $dst" in {
783   def Int_CMPSSrr : SSIi8<0xC2, MRMSrcReg,
784                         (outs VR128:$dst),
785                         (ins VR128:$src1, VR128:$src, SSECC:$cc),
786                         "cmp${cc}ss\t{$src, $dst|$dst, $src}",
787                         [(set VR128:$dst, (int_x86_sse_cmp_ss
788                                              VR128:$src1,
789                                              VR128:$src, imm:$cc))]>;
790   def Int_CMPSSrm : SSIi8<0xC2, MRMSrcMem,
791                         (outs VR128:$dst),
792                         (ins VR128:$src1, f32mem:$src, SSECC:$cc),
793                         "cmp${cc}ss\t{$src, $dst|$dst, $src}",
794                         [(set VR128:$dst, (int_x86_sse_cmp_ss VR128:$src1,
795                                            (load addr:$src), imm:$cc))]>;
796
797   def Int_CMPSDrr : SDIi8<0xC2, MRMSrcReg,
798                         (outs VR128:$dst),
799                         (ins VR128:$src1, VR128:$src, SSECC:$cc),
800                         "cmp${cc}sd\t{$src, $dst|$dst, $src}",
801                         [(set VR128:$dst, (int_x86_sse2_cmp_sd VR128:$src1,
802                                            VR128:$src, imm:$cc))]>;
803   def Int_CMPSDrm : SDIi8<0xC2, MRMSrcMem,
804                         (outs VR128:$dst),
805                         (ins VR128:$src1, f64mem:$src, SSECC:$cc),
806                         "cmp${cc}sd\t{$src, $dst|$dst, $src}",
807                         [(set VR128:$dst, (int_x86_sse2_cmp_sd VR128:$src1,
808                                            (load addr:$src), imm:$cc))]>;
809 }
810
811 let Defs = [EFLAGS] in {
812 def Int_UCOMISSrr: PSI<0x2E, MRMSrcReg, (outs), (ins VR128:$src1, VR128:$src2),
813                        "ucomiss\t{$src2, $src1|$src1, $src2}",
814                        [(set EFLAGS, (X86ucomi (v4f32 VR128:$src1),
815                                                VR128:$src2))]>;
816 def Int_UCOMISSrm: PSI<0x2E, MRMSrcMem, (outs),(ins VR128:$src1, f128mem:$src2),
817                        "ucomiss\t{$src2, $src1|$src1, $src2}",
818                        [(set EFLAGS, (X86ucomi (v4f32 VR128:$src1),
819                                                (load addr:$src2)))]>;
820 def Int_UCOMISDrr: PDI<0x2E, MRMSrcReg, (outs), (ins VR128:$src1, VR128:$src2),
821                        "ucomisd\t{$src2, $src1|$src1, $src2}",
822                        [(set EFLAGS, (X86ucomi (v2f64 VR128:$src1),
823                                                VR128:$src2))]>;
824 def Int_UCOMISDrm: PDI<0x2E, MRMSrcMem, (outs),(ins VR128:$src1, f128mem:$src2),
825                        "ucomisd\t{$src2, $src1|$src1, $src2}",
826                        [(set EFLAGS, (X86ucomi (v2f64 VR128:$src1),
827                                                (load addr:$src2)))]>;
828
829 def Int_COMISSrr: PSI<0x2F, MRMSrcReg, (outs), (ins VR128:$src1, VR128:$src2),
830                       "comiss\t{$src2, $src1|$src1, $src2}",
831                       [(set EFLAGS, (X86comi (v4f32 VR128:$src1),
832                                              VR128:$src2))]>;
833 def Int_COMISSrm: PSI<0x2F, MRMSrcMem, (outs), (ins VR128:$src1, f128mem:$src2),
834                       "comiss\t{$src2, $src1|$src1, $src2}",
835                       [(set EFLAGS, (X86comi (v4f32 VR128:$src1),
836                                              (load addr:$src2)))]>;
837 def Int_COMISDrr: PDI<0x2F, MRMSrcReg, (outs), (ins VR128:$src1, VR128:$src2),
838                       "comisd\t{$src2, $src1|$src1, $src2}",
839                       [(set EFLAGS, (X86comi (v2f64 VR128:$src1),
840                                              VR128:$src2))]>;
841 def Int_COMISDrm: PDI<0x2F, MRMSrcMem, (outs), (ins VR128:$src1, f128mem:$src2),
842                       "comisd\t{$src2, $src1|$src1, $src2}",
843                       [(set EFLAGS, (X86comi (v2f64 VR128:$src1),
844                                              (load addr:$src2)))]>;
845 } // Defs = [EFLAGS]
846
847 let Constraints = "$src1 = $dst" in {
848   defm CMPPS : sse12_cmp<VR128, f128mem, int_x86_sse_cmp_ps,
849                  "cmp${cc}ps\t{$src, $dst|$dst, $src}", SSEPackedSingle, SSECC>,
850                  TB;
851   defm CMPPD : sse12_cmp<VR128, f128mem, int_x86_sse2_cmp_pd,
852                  "cmp${cc}pd\t{$src, $dst|$dst, $src}", SSEPackedDouble, SSECC>,
853                  TB, OpSize;
854 }
855 let isAsmParserOnly = 1 in {
856   defm VCMPPS : sse12_cmp<VR128, f128mem, int_x86_sse_cmp_ps,
857                  "cmp${cc}ps\t{$src, $src1, $dst|$dst, $src1, $src}",
858                  SSEPackedSingle, SSECC>, VEX_4V;
859   defm VCMPPD : sse12_cmp<VR128, f128mem, int_x86_sse2_cmp_pd,
860                  "cmp${cc}pd\t{$src, $src1, $dst|$dst, $src1, $src}",
861                  SSEPackedSingle, SSECC>, OpSize, VEX_4V;
862 }
863
864 let isAsmParserOnly = 1, Pattern = []<dag> in {
865   // Accept explicit immediate argument form instead of comparison code.
866   let Constraints = "$src1 = $dst" in {
867     defm CMPPS : sse12_cmp_alt<VR128,
868                    "cmpps\t{$src2, $src, $dst|$dst, $src, $src2}",
869                    SSEPackedSingle, i8imm>, TB;
870     defm CMPPD : sse12_cmp_alt<VR128,
871                    "cmppd\t{$src2, $src, $dst|$dst, $src, $src2}",
872                    SSEPackedDouble, i8imm>, TB, OpSize;
873   }
874   defm VCMPPS : sse12_cmp_alt<VR128,
875                  "cmpps\t{$src2, $src, $src1, $dst|$dst, $src1, $src, $src}",
876                  SSEPackedSingle, i8imm>, VEX_4V;
877   defm VCMPPD : sse12_cmp_alt<VR128,
878                  "cmppd\t{$src2, $src, $src1, $dst|$dst, $src1, $src, $src2}",
879                  SSEPackedSingle, i8imm>, OpSize, VEX_4V;
880 }
881
882 def : Pat<(v4i32 (X86cmpps (v4f32 VR128:$src1), VR128:$src2, imm:$cc)),
883           (CMPPSrri (v4f32 VR128:$src1), (v4f32 VR128:$src2), imm:$cc)>;
884 def : Pat<(v4i32 (X86cmpps (v4f32 VR128:$src1), (memop addr:$src2), imm:$cc)),
885           (CMPPSrmi (v4f32 VR128:$src1), addr:$src2, imm:$cc)>;
886 def : Pat<(v2i64 (X86cmppd (v2f64 VR128:$src1), VR128:$src2, imm:$cc)),
887           (CMPPDrri VR128:$src1, VR128:$src2, imm:$cc)>;
888 def : Pat<(v2i64 (X86cmppd (v2f64 VR128:$src1), (memop addr:$src2), imm:$cc)),
889           (CMPPDrmi VR128:$src1, addr:$src2, imm:$cc)>;
890
891 //===----------------------------------------------------------------------===//
892 // SSE 1 & 2 - Shuffle Instructions
893 //===----------------------------------------------------------------------===//
894
895 /// sse12_shuffle - sse 1 & 2 shuffle instructions
896 multiclass sse12_shuffle<RegisterClass RC, X86MemOperand x86memop,
897                          ValueType vt, string asm, PatFrag mem_frag,
898                          Domain d, bit IsConvertibleToThreeAddress = 0> {
899   def rmi : PIi8<0xC6, MRMSrcMem, (outs VR128:$dst),
900                    (ins VR128:$src1, f128mem:$src2, i8imm:$src3), asm,
901                    [(set VR128:$dst, (vt (shufp:$src3
902                             VR128:$src1, (mem_frag addr:$src2))))], d>;
903   let isConvertibleToThreeAddress = IsConvertibleToThreeAddress in
904     def rri : PIi8<0xC6, MRMSrcReg, (outs VR128:$dst),
905                    (ins VR128:$src1, VR128:$src2, i8imm:$src3), asm,
906                    [(set VR128:$dst,
907                             (vt (shufp:$src3 VR128:$src1, VR128:$src2)))], d>;
908 }
909
910 let isAsmParserOnly = 1 in {
911   defm VSHUFPS : sse12_shuffle<VR128, f128mem, v4f32,
912             "shufps\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}",
913             memopv4f32, SSEPackedSingle>, VEX_4V;
914   defm VSHUFPD : sse12_shuffle<VR128, f128mem, v2f64,
915             "shufpd\t{$src3, $src2, $src1, $dst|$dst, $src2, $src2, $src3}",
916             memopv2f64, SSEPackedDouble>, OpSize, VEX_4V;
917 }
918
919 let Constraints = "$src1 = $dst" in {
920   defm SHUFPS : sse12_shuffle<VR128, f128mem, v4f32,
921                     "shufps\t{$src3, $src2, $dst|$dst, $src2, $src3}",
922                     memopv4f32, SSEPackedSingle, 1 /* cvt to pshufd */>,
923                     TB;
924   defm SHUFPD : sse12_shuffle<VR128, f128mem, v2f64,
925                     "shufpd\t{$src3, $src2, $dst|$dst, $src2, $src3}",
926                     memopv2f64, SSEPackedDouble>, TB, OpSize;
927 }
928
929 //===----------------------------------------------------------------------===//
930 // SSE 1 & 2 - Unpack Instructions
931 //===----------------------------------------------------------------------===//
932
933 /// sse12_unpack_interleave - sse 1 & 2 unpack and interleave
934 multiclass sse12_unpack_interleave<bits<8> opc, PatFrag OpNode, ValueType vt,
935                                    PatFrag mem_frag, RegisterClass RC,
936                                    X86MemOperand x86memop, string asm,
937                                    Domain d> {
938     def rr : PI<opc, MRMSrcReg,
939                 (outs RC:$dst), (ins RC:$src1, RC:$src2),
940                 asm, [(set RC:$dst,
941                            (vt (OpNode RC:$src1, RC:$src2)))], d>;
942     def rm : PI<opc, MRMSrcMem,
943                 (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
944                 asm, [(set RC:$dst,
945                            (vt (OpNode RC:$src1,
946                                        (mem_frag addr:$src2))))], d>;
947 }
948
949 let AddedComplexity = 10 in {
950   let isAsmParserOnly = 1 in {
951     defm VUNPCKHPS: sse12_unpack_interleave<0x15, unpckh, v4f32, memopv4f32,
952           VR128, f128mem, "unpckhps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
953                          SSEPackedSingle>, VEX_4V;
954     defm VUNPCKHPD: sse12_unpack_interleave<0x15, unpckh, v2f64, memopv2f64,
955           VR128, f128mem, "unpckhpd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
956                          SSEPackedDouble>, OpSize, VEX_4V;
957     defm VUNPCKLPS: sse12_unpack_interleave<0x14, unpckl, v4f32, memopv4f32,
958           VR128, f128mem, "unpcklps\t{$src2, $src1, $dst|$dst, $src1, $src2}",
959                          SSEPackedSingle>, VEX_4V;
960     defm VUNPCKLPD: sse12_unpack_interleave<0x14, unpckl, v2f64, memopv2f64,
961           VR128, f128mem, "unpcklpd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
962                          SSEPackedDouble>, OpSize, VEX_4V;
963   }
964
965   let Constraints = "$src1 = $dst" in {
966     defm UNPCKHPS: sse12_unpack_interleave<0x15, unpckh, v4f32, memopv4f32,
967           VR128, f128mem, "unpckhps\t{$src2, $dst|$dst, $src2}",
968                          SSEPackedSingle>, TB;
969     defm UNPCKHPD: sse12_unpack_interleave<0x15, unpckh, v2f64, memopv2f64,
970           VR128, f128mem, "unpckhpd\t{$src2, $dst|$dst, $src2}",
971                          SSEPackedDouble>, TB, OpSize;
972     defm UNPCKLPS: sse12_unpack_interleave<0x14, unpckl, v4f32, memopv4f32,
973           VR128, f128mem, "unpcklps\t{$src2, $dst|$dst, $src2}",
974                          SSEPackedSingle>, TB;
975     defm UNPCKLPD: sse12_unpack_interleave<0x14, unpckl, v2f64, memopv2f64,
976           VR128, f128mem, "unpcklpd\t{$src2, $dst|$dst, $src2}",
977                          SSEPackedDouble>, TB, OpSize;
978   } // Constraints = "$src1 = $dst"
979 } // AddedComplexity
980
981 //===----------------------------------------------------------------------===//
982 // SSE 1 & 2 - Extract Floating-Point Sign mask
983 //===----------------------------------------------------------------------===//
984
985 /// sse12_extr_sign_mask - sse 1 & 2 unpack and interleave
986 multiclass sse12_extr_sign_mask<RegisterClass RC, Intrinsic Int, string asm,
987                                 Domain d> {
988   def rr : PI<0x50, MRMSrcReg, (outs GR32:$dst), (ins RC:$src),
989               !strconcat(asm, "\t{$src, $dst|$dst, $src}"),
990                      [(set GR32:$dst, (Int RC:$src))], d>;
991 }
992
993 // Mask creation
994 defm MOVMSKPS : sse12_extr_sign_mask<VR128, int_x86_sse_movmsk_ps, "movmskps",
995                                      SSEPackedSingle>, TB;
996 defm MOVMSKPD : sse12_extr_sign_mask<VR128, int_x86_sse2_movmsk_pd, "movmskpd",
997                                      SSEPackedDouble>, TB, OpSize;
998
999 let isAsmParserOnly = 1 in {
1000   defm VMOVMSKPS : sse12_extr_sign_mask<VR128, int_x86_sse_movmsk_ps,
1001                                         "movmskps", SSEPackedSingle>, VEX;
1002   defm VMOVMSKPD : sse12_extr_sign_mask<VR128, int_x86_sse2_movmsk_pd,
1003                                         "movmskpd", SSEPackedDouble>, OpSize,
1004                                         VEX;
1005 }
1006
1007 //===----------------------------------------------------------------------===//
1008 // SSE 1 & 2 - Misc aliasing of packed SSE 1 & 2 instructions
1009 //===----------------------------------------------------------------------===//
1010
1011 // Aliases of packed SSE1 & SSE2 instructions for scalar use. These all have
1012 // names that start with 'Fs'.
1013
1014 // Alias instructions that map fld0 to pxor for sse.
1015 let isReMaterializable = 1, isAsCheapAsAMove = 1, isCodeGenOnly = 1,
1016     canFoldAsLoad = 1 in {
1017   // FIXME: Set encoding to pseudo!
1018 def FsFLD0SS : I<0xEF, MRMInitReg, (outs FR32:$dst), (ins), "",
1019                  [(set FR32:$dst, fp32imm0)]>,
1020                  Requires<[HasSSE1]>, TB, OpSize;
1021 def FsFLD0SD : I<0xEF, MRMInitReg, (outs FR64:$dst), (ins), "",
1022                  [(set FR64:$dst, fpimm0)]>,
1023                Requires<[HasSSE2]>, TB, OpSize;
1024 }
1025
1026 // Alias instruction to do FR32 or FR64 reg-to-reg copy using movaps. Upper
1027 // bits are disregarded.
1028 let neverHasSideEffects = 1 in {
1029 def FsMOVAPSrr : PSI<0x28, MRMSrcReg, (outs FR32:$dst), (ins FR32:$src),
1030                      "movaps\t{$src, $dst|$dst, $src}", []>;
1031 def FsMOVAPDrr : PDI<0x28, MRMSrcReg, (outs FR64:$dst), (ins FR64:$src),
1032                      "movapd\t{$src, $dst|$dst, $src}", []>;
1033 }
1034
1035 // Alias instruction to load FR32 or FR64 from f128mem using movaps. Upper
1036 // bits are disregarded.
1037 let canFoldAsLoad = 1, isReMaterializable = 1 in {
1038 def FsMOVAPSrm : PSI<0x28, MRMSrcMem, (outs FR32:$dst), (ins f128mem:$src),
1039                      "movaps\t{$src, $dst|$dst, $src}",
1040                      [(set FR32:$dst, (alignedloadfsf32 addr:$src))]>;
1041 def FsMOVAPDrm : PDI<0x28, MRMSrcMem, (outs FR64:$dst), (ins f128mem:$src),
1042                      "movapd\t{$src, $dst|$dst, $src}",
1043                      [(set FR64:$dst, (alignedloadfsf64 addr:$src))]>;
1044 }
1045
1046 //===----------------------------------------------------------------------===//
1047 // SSE 1 & 2 - Logical Instructions
1048 //===----------------------------------------------------------------------===//
1049
1050 /// sse12_fp_alias_pack_logical - SSE 1 & 2 aliased packed FP logical ops
1051 ///
1052 multiclass sse12_fp_alias_pack_logical<bits<8> opc, string OpcodeStr,
1053                                        SDNode OpNode, bit MayLoad = 0> {
1054   let isAsmParserOnly = 1 in {
1055     defm V#NAME#PS : sse12_fp_packed<opc, !strconcat(OpcodeStr,
1056                 "ps\t{$src2, $src1, $dst|$dst, $src1, $src2}"), OpNode, FR32,
1057                 f32, f128mem, memopfsf32, SSEPackedSingle, MayLoad>, VEX_4V;
1058
1059     defm V#NAME#PD : sse12_fp_packed<opc, !strconcat(OpcodeStr,
1060                 "pd\t{$src2, $src1, $dst|$dst, $src1, $src2}"), OpNode, FR64,
1061                 f64, f128mem, memopfsf64, SSEPackedDouble, MayLoad>, OpSize,
1062                 VEX_4V;
1063   }
1064
1065   let Constraints = "$src1 = $dst" in {
1066     defm PS : sse12_fp_packed<opc, !strconcat(OpcodeStr,
1067                 "ps\t{$src2, $dst|$dst, $src2}"), OpNode, FR32, f32,
1068                 f128mem, memopfsf32, SSEPackedSingle, MayLoad>, TB;
1069
1070     defm PD : sse12_fp_packed<opc, !strconcat(OpcodeStr,
1071                 "pd\t{$src2, $dst|$dst, $src2}"), OpNode, FR64, f64,
1072                 f128mem, memopfsf64, SSEPackedDouble, MayLoad>, TB, OpSize;
1073   }
1074 }
1075
1076 // Alias bitwise logical operations using SSE logical ops on packed FP values.
1077 defm FsAND  : sse12_fp_alias_pack_logical<0x54, "and", X86fand>;
1078 defm FsOR   : sse12_fp_alias_pack_logical<0x56, "or", X86for>;
1079 defm FsXOR  : sse12_fp_alias_pack_logical<0x57, "xor", X86fxor>;
1080
1081 let neverHasSideEffects = 1, Pattern = []<dag>, isCommutable = 0 in
1082   defm FsANDN : sse12_fp_alias_pack_logical<0x55, "andn", undef, 1>;
1083
1084 /// sse12_fp_packed_logical - SSE 1 & 2 packed FP logical ops
1085 ///
1086 multiclass sse12_fp_packed_logical<bits<8> opc, string OpcodeStr,
1087                                  SDNode OpNode, int HasPat = 0,
1088                                  list<list<dag>> Pattern = []> {
1089   let isAsmParserOnly = 1 in {
1090     defm V#NAME#PS : sse12_fp_packed_logical_rm<opc, VR128, SSEPackedSingle,
1091          !strconcat(OpcodeStr, "ps\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
1092          f128mem,
1093          !if(HasPat, Pattern[0], // rr
1094                      [(set VR128:$dst, (v2i64 (OpNode VR128:$src1,
1095                                                       VR128:$src2)))]),
1096          !if(HasPat, Pattern[2], // rm
1097                      [(set VR128:$dst, (OpNode (bc_v2i64 (v4f32 VR128:$src1)),
1098                                                (memopv2i64 addr:$src2)))])>,
1099                                                VEX_4V;
1100
1101     defm V#NAME#PD : sse12_fp_packed_logical_rm<opc, VR128, SSEPackedDouble,
1102          !strconcat(OpcodeStr, "pd\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
1103          f128mem,
1104          !if(HasPat, Pattern[1], // rr
1105                      [(set VR128:$dst, (OpNode (bc_v2i64 (v2f64 VR128:$src1)),
1106                                                (bc_v2i64 (v2f64
1107                                                VR128:$src2))))]),
1108          !if(HasPat, Pattern[3], // rm
1109                      [(set VR128:$dst, (OpNode (bc_v2i64 (v2f64 VR128:$src1)),
1110                                                (memopv2i64 addr:$src2)))])>,
1111                                                                OpSize, VEX_4V;
1112   }
1113   let Constraints = "$src1 = $dst" in {
1114     defm PS : sse12_fp_packed_logical_rm<opc, VR128, SSEPackedSingle,
1115          !strconcat(OpcodeStr, "ps\t{$src2, $dst|$dst, $src2}"), f128mem,
1116          !if(HasPat, Pattern[0], // rr
1117                      [(set VR128:$dst, (v2i64 (OpNode VR128:$src1,
1118                                                       VR128:$src2)))]),
1119          !if(HasPat, Pattern[2], // rm
1120                      [(set VR128:$dst, (OpNode (bc_v2i64 (v4f32 VR128:$src1)),
1121                                                (memopv2i64 addr:$src2)))])>, TB;
1122
1123     defm PD : sse12_fp_packed_logical_rm<opc, VR128, SSEPackedDouble,
1124          !strconcat(OpcodeStr, "pd\t{$src2, $dst|$dst, $src2}"), f128mem,
1125          !if(HasPat, Pattern[1], // rr
1126                      [(set VR128:$dst, (OpNode (bc_v2i64 (v2f64 VR128:$src1)),
1127                                                (bc_v2i64 (v2f64
1128                                                VR128:$src2))))]),
1129          !if(HasPat, Pattern[3], // rm
1130                      [(set VR128:$dst, (OpNode (bc_v2i64 (v2f64 VR128:$src1)),
1131                                                (memopv2i64 addr:$src2)))])>,
1132                                                                     TB, OpSize;
1133   }
1134 }
1135
1136 defm AND  : sse12_fp_packed_logical<0x54, "and", and>;
1137 defm OR   : sse12_fp_packed_logical<0x56, "or", or>;
1138 defm XOR  : sse12_fp_packed_logical<0x57, "xor", xor>;
1139 let isCommutable = 0 in
1140   defm ANDN : sse12_fp_packed_logical<0x55, "andn", undef /* dummy */, 1, [
1141     // single r+r
1142     [(set VR128:$dst, (v2i64 (and (xor VR128:$src1,
1143                                        (bc_v2i64 (v4i32 immAllOnesV))),
1144                                    VR128:$src2)))],
1145     // double r+r
1146     [(set VR128:$dst, (and (vnot (bc_v2i64 (v2f64 VR128:$src1))),
1147                                  (bc_v2i64 (v2f64 VR128:$src2))))],
1148     // single r+m
1149     [(set VR128:$dst, (v2i64 (and (xor (bc_v2i64 (v4f32 VR128:$src1)),
1150                                        (bc_v2i64 (v4i32 immAllOnesV))),
1151                                   (memopv2i64 addr:$src2))))],
1152     // double r+m
1153     [(set VR128:$dst, (and (vnot (bc_v2i64 (v2f64 VR128:$src1))),
1154                            (memopv2i64 addr:$src2)))]]>;
1155
1156 //===----------------------------------------------------------------------===//
1157 // SSE 1 & 2 - Arithmetic Instructions
1158 //===----------------------------------------------------------------------===//
1159
1160 /// basic_sse12_fp_binop_rm - SSE 1 & 2 binops come in both scalar and
1161 /// vector forms.
1162 ///
1163 /// In addition, we also have a special variant of the scalar form here to
1164 /// represent the associated intrinsic operation.  This form is unlike the
1165 /// plain scalar form, in that it takes an entire vector (instead of a scalar)
1166 /// and leaves the top elements unmodified (therefore these cannot be commuted).
1167 ///
1168 /// These three forms can each be reg+reg or reg+mem.
1169 ///
1170 multiclass basic_sse12_fp_binop_rm<bits<8> opc, string OpcodeStr,
1171                                    SDNode OpNode> {
1172
1173   let isAsmParserOnly = 1 in {
1174     defm V#NAME#SS : sse12_fp_scalar<opc,
1175         !strconcat(OpcodeStr, "ss\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
1176                    OpNode, FR32, f32mem>, XS, VEX_4V;
1177
1178     defm V#NAME#SD : sse12_fp_scalar<opc,
1179         !strconcat(OpcodeStr, "sd\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
1180                    OpNode, FR64, f64mem>, XD, VEX_4V;
1181
1182     defm V#NAME#PS : sse12_fp_packed<opc, !strconcat(OpcodeStr,
1183                       "ps\t{$src2, $src1, $dst|$dst, $src1, $src2}"), OpNode,
1184                       VR128, v4f32, f128mem, memopv4f32, SSEPackedSingle>,
1185                       VEX_4V;
1186
1187     defm V#NAME#PD : sse12_fp_packed<opc, !strconcat(OpcodeStr,
1188                       "pd\t{$src2, $src1, $dst|$dst, $src1, $src2}"), OpNode,
1189                       VR128, v2f64, f128mem, memopv2f64, SSEPackedDouble>,
1190                       OpSize, VEX_4V;
1191
1192     defm V#NAME#SS : sse12_fp_scalar_int<opc, OpcodeStr, VR128,
1193        !strconcat(OpcodeStr, "ss\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
1194                   "", "_ss", ssmem, sse_load_f32>, XS, VEX_4V;
1195
1196     defm V#NAME#SD : sse12_fp_scalar_int<opc, OpcodeStr, VR128,
1197        !strconcat(OpcodeStr, "sd\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
1198                   "2", "_sd", sdmem, sse_load_f64>, XD, VEX_4V;
1199   }
1200
1201   let Constraints = "$src1 = $dst" in {
1202     defm SS : sse12_fp_scalar<opc,
1203                     !strconcat(OpcodeStr, "ss\t{$src2, $dst|$dst, $src2}"),
1204                     OpNode, FR32, f32mem>, XS;
1205
1206     defm SD : sse12_fp_scalar<opc,
1207                     !strconcat(OpcodeStr, "sd\t{$src2, $dst|$dst, $src2}"),
1208                     OpNode, FR64, f64mem>, XD;
1209
1210     defm PS : sse12_fp_packed<opc, !strconcat(OpcodeStr,
1211                 "ps\t{$src2, $dst|$dst, $src2}"), OpNode, VR128, v4f32,
1212                 f128mem, memopv4f32, SSEPackedSingle>, TB;
1213
1214     defm PD : sse12_fp_packed<opc, !strconcat(OpcodeStr,
1215                 "pd\t{$src2, $dst|$dst, $src2}"), OpNode, VR128, v2f64,
1216                 f128mem, memopv2f64, SSEPackedDouble>, TB, OpSize;
1217
1218     defm SS : sse12_fp_scalar_int<opc, OpcodeStr, VR128,
1219        !strconcat(OpcodeStr, "ss\t{$src2, $dst|$dst, $src2}"),
1220                   "", "_ss", ssmem, sse_load_f32>, XS;
1221
1222     defm SD : sse12_fp_scalar_int<opc, OpcodeStr, VR128,
1223        !strconcat(OpcodeStr, "sd\t{$src2, $dst|$dst, $src2}"),
1224                   "2", "_sd", sdmem, sse_load_f64>, XD;
1225   }
1226 }
1227
1228 // Arithmetic instructions
1229 defm ADD : basic_sse12_fp_binop_rm<0x58, "add", fadd>;
1230 defm MUL : basic_sse12_fp_binop_rm<0x59, "mul", fmul>;
1231
1232 let isCommutable = 0 in {
1233   defm SUB : basic_sse12_fp_binop_rm<0x5C, "sub", fsub>;
1234   defm DIV : basic_sse12_fp_binop_rm<0x5E, "div", fdiv>;
1235 }
1236
1237 /// sse12_fp_binop_rm - Other SSE 1 & 2 binops
1238 ///
1239 /// This multiclass is like basic_sse12_fp_binop_rm, with the addition of
1240 /// instructions for a full-vector intrinsic form.  Operations that map
1241 /// onto C operators don't use this form since they just use the plain
1242 /// vector form instead of having a separate vector intrinsic form.
1243 ///
1244 multiclass sse12_fp_binop_rm<bits<8> opc, string OpcodeStr,
1245                              SDNode OpNode> {
1246
1247   let isAsmParserOnly = 1 in {
1248     // Scalar operation, reg+reg.
1249     defm V#NAME#SS : sse12_fp_scalar<opc,
1250       !strconcat(OpcodeStr, "ss\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
1251                  OpNode, FR32, f32mem>, XS, VEX_4V;
1252
1253     defm V#NAME#SD : sse12_fp_scalar<opc,
1254       !strconcat(OpcodeStr, "sd\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
1255                  OpNode, FR64, f64mem>, XD, VEX_4V;
1256
1257     defm V#NAME#PS : sse12_fp_packed<opc, !strconcat(OpcodeStr,
1258                       "ps\t{$src2, $src1, $dst|$dst, $src1, $src2}"), OpNode,
1259                       VR128, v4f32, f128mem, memopv4f32, SSEPackedSingle>,
1260                       VEX_4V;
1261
1262     defm V#NAME#PD : sse12_fp_packed<opc, !strconcat(OpcodeStr,
1263                       "pd\t{$src2, $src1, $dst|$dst, $src1, $src2}"), OpNode,
1264                       VR128, v2f64, f128mem, memopv2f64, SSEPackedDouble>,
1265                       OpSize, VEX_4V;
1266
1267     defm V#NAME#SS : sse12_fp_scalar_int<opc, OpcodeStr, VR128,
1268        !strconcat(OpcodeStr, "ss\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
1269                   "", "_ss", ssmem, sse_load_f32>, XS, VEX_4V;
1270
1271     defm V#NAME#SD : sse12_fp_scalar_int<opc, OpcodeStr, VR128,
1272        !strconcat(OpcodeStr, "sd\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
1273                   "2", "_sd", sdmem, sse_load_f64>, XD, VEX_4V;
1274
1275     defm V#NAME#PS : sse12_fp_packed_int<opc, OpcodeStr, VR128,
1276        !strconcat(OpcodeStr, "ps\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
1277                   "", "_ps", f128mem, memopv4f32, SSEPackedSingle>, VEX_4V;
1278
1279     defm V#NAME#PD : sse12_fp_packed_int<opc, OpcodeStr, VR128,
1280        !strconcat(OpcodeStr, "pd\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
1281                   "2", "_pd", f128mem, memopv2f64, SSEPackedDouble>, OpSize,
1282                   VEX_4V;
1283   }
1284
1285   let Constraints = "$src1 = $dst" in {
1286     // Scalar operation, reg+reg.
1287     defm SS : sse12_fp_scalar<opc,
1288                     !strconcat(OpcodeStr, "ss\t{$src2, $dst|$dst, $src2}"),
1289                     OpNode, FR32, f32mem>, XS;
1290     defm SD : sse12_fp_scalar<opc,
1291                     !strconcat(OpcodeStr, "sd\t{$src2, $dst|$dst, $src2}"),
1292                     OpNode, FR64, f64mem>, XD;
1293     defm PS : sse12_fp_packed<opc, !strconcat(OpcodeStr,
1294                 "ps\t{$src2, $dst|$dst, $src2}"), OpNode, VR128, v4f32,
1295                 f128mem, memopv4f32, SSEPackedSingle>, TB;
1296
1297     defm PD : sse12_fp_packed<opc, !strconcat(OpcodeStr,
1298                 "pd\t{$src2, $dst|$dst, $src2}"), OpNode, VR128, v2f64,
1299                 f128mem, memopv2f64, SSEPackedDouble>, TB, OpSize;
1300
1301     defm SS : sse12_fp_scalar_int<opc, OpcodeStr, VR128,
1302        !strconcat(OpcodeStr, "ss\t{$src2, $dst|$dst, $src2}"),
1303                   "", "_ss", ssmem, sse_load_f32>, XS;
1304
1305     defm SD : sse12_fp_scalar_int<opc, OpcodeStr, VR128,
1306        !strconcat(OpcodeStr, "sd\t{$src2, $dst|$dst, $src2}"),
1307                   "2", "_sd", sdmem, sse_load_f64>, XD;
1308
1309     defm PS : sse12_fp_packed_int<opc, OpcodeStr, VR128,
1310        !strconcat(OpcodeStr, "ps\t{$src2, $dst|$dst, $src2}"),
1311                   "", "_ps", f128mem, memopv4f32, SSEPackedSingle>, TB;
1312
1313     defm PD : sse12_fp_packed_int<opc, OpcodeStr, VR128,
1314        !strconcat(OpcodeStr, "pd\t{$src2, $dst|$dst, $src2}"),
1315                   "2", "_pd", f128mem, memopv2f64, SSEPackedDouble>, TB, OpSize;
1316   }
1317 }
1318
1319 let isCommutable = 0 in {
1320   defm MAX : sse12_fp_binop_rm<0x5F, "max", X86fmax>;
1321   defm MIN : sse12_fp_binop_rm<0x5D, "min", X86fmin>;
1322 }
1323
1324 //===----------------------------------------------------------------------===//
1325 // SSE packed FP Instructions
1326
1327 // Move Instructions
1328 let neverHasSideEffects = 1 in
1329 def MOVAPSrr : PSI<0x28, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1330                    "movaps\t{$src, $dst|$dst, $src}", []>;
1331 let canFoldAsLoad = 1, isReMaterializable = 1 in
1332 def MOVAPSrm : PSI<0x28, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1333                    "movaps\t{$src, $dst|$dst, $src}",
1334                    [(set VR128:$dst, (alignedloadv4f32 addr:$src))]>;
1335
1336 def MOVAPSmr : PSI<0x29, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
1337                    "movaps\t{$src, $dst|$dst, $src}",
1338                    [(alignedstore (v4f32 VR128:$src), addr:$dst)]>;
1339
1340 let neverHasSideEffects = 1 in
1341 def MOVUPSrr : PSI<0x10, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1342                    "movups\t{$src, $dst|$dst, $src}", []>;
1343 let canFoldAsLoad = 1, isReMaterializable = 1 in
1344 def MOVUPSrm : PSI<0x10, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1345                    "movups\t{$src, $dst|$dst, $src}",
1346                    [(set VR128:$dst, (loadv4f32 addr:$src))]>;
1347 def MOVUPSmr : PSI<0x11, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
1348                    "movups\t{$src, $dst|$dst, $src}",
1349                    [(store (v4f32 VR128:$src), addr:$dst)]>;
1350
1351 // Intrinsic forms of MOVUPS load and store
1352 let canFoldAsLoad = 1, isReMaterializable = 1 in
1353 def MOVUPSrm_Int : PSI<0x10, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1354                        "movups\t{$src, $dst|$dst, $src}",
1355                        [(set VR128:$dst, (int_x86_sse_loadu_ps addr:$src))]>;
1356 def MOVUPSmr_Int : PSI<0x11, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
1357                        "movups\t{$src, $dst|$dst, $src}",
1358                        [(int_x86_sse_storeu_ps addr:$dst, VR128:$src)]>;
1359
1360 let Constraints = "$src1 = $dst" in {
1361   let AddedComplexity = 20 in {
1362     def MOVLPSrm : PSI<0x12, MRMSrcMem,
1363                        (outs VR128:$dst), (ins VR128:$src1, f64mem:$src2),
1364                        "movlps\t{$src2, $dst|$dst, $src2}",
1365        [(set VR128:$dst,
1366          (movlp VR128:$src1,
1367                 (bc_v4f32 (v2f64 (scalar_to_vector (loadf64 addr:$src2))))))]>;
1368     def MOVHPSrm : PSI<0x16, MRMSrcMem,
1369                        (outs VR128:$dst), (ins VR128:$src1, f64mem:$src2),
1370                        "movhps\t{$src2, $dst|$dst, $src2}",
1371        [(set VR128:$dst,
1372          (movlhps VR128:$src1,
1373                 (bc_v4f32 (v2f64 (scalar_to_vector (loadf64 addr:$src2))))))]>;
1374   } // AddedComplexity
1375 } // Constraints = "$src1 = $dst"
1376
1377
1378 def : Pat<(movlhps VR128:$src1, (bc_v4i32 (v2i64 (X86vzload addr:$src2)))),
1379           (MOVHPSrm (v4i32 VR128:$src1), addr:$src2)>;
1380
1381 def MOVLPSmr : PSI<0x13, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
1382                    "movlps\t{$src, $dst|$dst, $src}",
1383                    [(store (f64 (vector_extract (bc_v2f64 (v4f32 VR128:$src)),
1384                                  (iPTR 0))), addr:$dst)]>;
1385
1386 // v2f64 extract element 1 is always custom lowered to unpack high to low
1387 // and extract element 0 so the non-store version isn't too horrible.
1388 def MOVHPSmr : PSI<0x17, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
1389                    "movhps\t{$src, $dst|$dst, $src}",
1390                    [(store (f64 (vector_extract
1391                                  (unpckh (bc_v2f64 (v4f32 VR128:$src)),
1392                                          (undef)), (iPTR 0))), addr:$dst)]>;
1393
1394 let Constraints = "$src1 = $dst" in {
1395 let AddedComplexity = 20 in {
1396 def MOVLHPSrr : PSI<0x16, MRMSrcReg, (outs VR128:$dst),
1397                                      (ins VR128:$src1, VR128:$src2),
1398                     "movlhps\t{$src2, $dst|$dst, $src2}",
1399                     [(set VR128:$dst,
1400                       (v4f32 (movlhps VR128:$src1, VR128:$src2)))]>;
1401
1402 def MOVHLPSrr : PSI<0x12, MRMSrcReg, (outs VR128:$dst),
1403                                      (ins VR128:$src1, VR128:$src2),
1404                     "movhlps\t{$src2, $dst|$dst, $src2}",
1405                     [(set VR128:$dst,
1406                       (v4f32 (movhlps VR128:$src1, VR128:$src2)))]>;
1407 } // AddedComplexity
1408 } // Constraints = "$src1 = $dst"
1409
1410 let AddedComplexity = 20 in {
1411 def : Pat<(v4f32 (movddup VR128:$src, (undef))),
1412           (MOVLHPSrr (v4f32 VR128:$src), (v4f32 VR128:$src))>;
1413 def : Pat<(v2i64 (movddup VR128:$src, (undef))),
1414           (MOVLHPSrr (v2i64 VR128:$src), (v2i64 VR128:$src))>;
1415 }
1416
1417
1418
1419 // Arithmetic
1420
1421 /// sse1_fp_unop_rm - SSE1 unops come in both scalar and vector forms.
1422 ///
1423 /// In addition, we also have a special variant of the scalar form here to
1424 /// represent the associated intrinsic operation.  This form is unlike the
1425 /// plain scalar form, in that it takes an entire vector (instead of a
1426 /// scalar) and leaves the top elements undefined.
1427 ///
1428 /// And, we have a special variant form for a full-vector intrinsic form.
1429 ///
1430 /// These four forms can each have a reg or a mem operand, so there are a
1431 /// total of eight "instructions".
1432 ///
1433 multiclass sse1_fp_unop_rm<bits<8> opc, string OpcodeStr,
1434                            SDNode OpNode,
1435                            Intrinsic F32Int,
1436                            Intrinsic V4F32Int,
1437                            bit Commutable = 0> {
1438   // Scalar operation, reg.
1439   def SSr : SSI<opc, MRMSrcReg, (outs FR32:$dst), (ins FR32:$src),
1440                 !strconcat(OpcodeStr, "ss\t{$src, $dst|$dst, $src}"),
1441                 [(set FR32:$dst, (OpNode FR32:$src))]> {
1442     let isCommutable = Commutable;
1443   }
1444
1445   // Scalar operation, mem.
1446   def SSm : I<opc, MRMSrcMem, (outs FR32:$dst), (ins f32mem:$src),
1447                 !strconcat(OpcodeStr, "ss\t{$src, $dst|$dst, $src}"),
1448                 [(set FR32:$dst, (OpNode (load addr:$src)))]>, XS,
1449             Requires<[HasSSE1, OptForSize]>;
1450
1451   // Vector operation, reg.
1452   def PSr : PSI<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1453               !strconcat(OpcodeStr, "ps\t{$src, $dst|$dst, $src}"),
1454               [(set VR128:$dst, (v4f32 (OpNode VR128:$src)))]> {
1455     let isCommutable = Commutable;
1456   }
1457
1458   // Vector operation, mem.
1459   def PSm : PSI<opc, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1460                 !strconcat(OpcodeStr, "ps\t{$src, $dst|$dst, $src}"),
1461                 [(set VR128:$dst, (OpNode (memopv4f32 addr:$src)))]>;
1462
1463   // Intrinsic operation, reg.
1464   def SSr_Int : SSI<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1465                     !strconcat(OpcodeStr, "ss\t{$src, $dst|$dst, $src}"),
1466                     [(set VR128:$dst, (F32Int VR128:$src))]> {
1467     let isCommutable = Commutable;
1468   }
1469
1470   // Intrinsic operation, mem.
1471   def SSm_Int : SSI<opc, MRMSrcMem, (outs VR128:$dst), (ins ssmem:$src),
1472                     !strconcat(OpcodeStr, "ss\t{$src, $dst|$dst, $src}"),
1473                     [(set VR128:$dst, (F32Int sse_load_f32:$src))]>;
1474
1475   // Vector intrinsic operation, reg
1476   def PSr_Int : PSI<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1477                     !strconcat(OpcodeStr, "ps\t{$src, $dst|$dst, $src}"),
1478                     [(set VR128:$dst, (V4F32Int VR128:$src))]> {
1479     let isCommutable = Commutable;
1480   }
1481
1482   // Vector intrinsic operation, mem
1483   def PSm_Int : PSI<opc, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1484                     !strconcat(OpcodeStr, "ps\t{$src, $dst|$dst, $src}"),
1485                     [(set VR128:$dst, (V4F32Int (memopv4f32 addr:$src)))]>;
1486 }
1487
1488 // Square root.
1489 defm SQRT  : sse1_fp_unop_rm<0x51, "sqrt",  fsqrt,
1490                              int_x86_sse_sqrt_ss, int_x86_sse_sqrt_ps>;
1491
1492 // Reciprocal approximations. Note that these typically require refinement
1493 // in order to obtain suitable precision.
1494 defm RSQRT : sse1_fp_unop_rm<0x52, "rsqrt", X86frsqrt,
1495                              int_x86_sse_rsqrt_ss, int_x86_sse_rsqrt_ps>;
1496 defm RCP   : sse1_fp_unop_rm<0x53, "rcp",   X86frcp,
1497                              int_x86_sse_rcp_ss, int_x86_sse_rcp_ps>;
1498
1499 // Prefetch intrinsic.
1500 def PREFETCHT0   : PSI<0x18, MRM1m, (outs), (ins i8mem:$src),
1501     "prefetcht0\t$src", [(prefetch addr:$src, imm, (i32 3))]>;
1502 def PREFETCHT1   : PSI<0x18, MRM2m, (outs), (ins i8mem:$src),
1503     "prefetcht1\t$src", [(prefetch addr:$src, imm, (i32 2))]>;
1504 def PREFETCHT2   : PSI<0x18, MRM3m, (outs), (ins i8mem:$src),
1505     "prefetcht2\t$src", [(prefetch addr:$src, imm, (i32 1))]>;
1506 def PREFETCHNTA  : PSI<0x18, MRM0m, (outs), (ins i8mem:$src),
1507     "prefetchnta\t$src", [(prefetch addr:$src, imm, (i32 0))]>;
1508
1509 // Non-temporal stores
1510 def MOVNTPSmr_Int : PSI<0x2B, MRMDestMem, (outs), (ins i128mem:$dst, VR128:$src),
1511                     "movntps\t{$src, $dst|$dst, $src}",
1512                     [(int_x86_sse_movnt_ps addr:$dst, VR128:$src)]>;
1513
1514 let AddedComplexity = 400 in { // Prefer non-temporal versions
1515 def MOVNTPSmr : PSI<0x2B, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
1516                     "movntps\t{$src, $dst|$dst, $src}",
1517                     [(alignednontemporalstore (v4f32 VR128:$src), addr:$dst)]>;
1518
1519 def MOVNTDQ_64mr : PDI<0xE7, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
1520                     "movntdq\t{$src, $dst|$dst, $src}",
1521                     [(alignednontemporalstore (v2f64 VR128:$src), addr:$dst)]>;
1522
1523 def MOVNTImr : I<0xC3, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
1524                  "movnti\t{$src, $dst|$dst, $src}",
1525                  [(nontemporalstore (i32 GR32:$src), addr:$dst)]>,
1526                TB, Requires<[HasSSE2]>;
1527
1528 def MOVNTI_64mr : RI<0xC3, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
1529                      "movnti\t{$src, $dst|$dst, $src}",
1530                      [(nontemporalstore (i64 GR64:$src), addr:$dst)]>,
1531                   TB, Requires<[HasSSE2]>;
1532 }
1533
1534 // Load, store, and memory fence
1535 def SFENCE : I<0xAE, MRM_F8, (outs), (ins), "sfence", [(int_x86_sse_sfence)]>,
1536              TB, Requires<[HasSSE1]>;
1537
1538 // MXCSR register
1539 def LDMXCSR : PSI<0xAE, MRM2m, (outs), (ins i32mem:$src),
1540                   "ldmxcsr\t$src", [(int_x86_sse_ldmxcsr addr:$src)]>;
1541 def STMXCSR : PSI<0xAE, MRM3m, (outs), (ins i32mem:$dst),
1542                   "stmxcsr\t$dst", [(int_x86_sse_stmxcsr addr:$dst)]>;
1543
1544 // Alias instructions that map zero vector to pxor / xorp* for sse.
1545 // We set canFoldAsLoad because this can be converted to a constant-pool
1546 // load of an all-zeros value if folding it would be beneficial.
1547 // FIXME: Change encoding to pseudo!
1548 let isReMaterializable = 1, isAsCheapAsAMove = 1, canFoldAsLoad = 1,
1549     isCodeGenOnly = 1 in {
1550 def V_SET0PS : PSI<0x57, MRMInitReg, (outs VR128:$dst), (ins), "",
1551                  [(set VR128:$dst, (v4f32 immAllZerosV))]>;
1552 def V_SET0PD : PDI<0x57, MRMInitReg, (outs VR128:$dst), (ins), "",
1553                  [(set VR128:$dst, (v2f64 immAllZerosV))]>;
1554 let ExeDomain = SSEPackedInt in
1555 def V_SET0PI : PDI<0xEF, MRMInitReg, (outs VR128:$dst), (ins), "",
1556                  [(set VR128:$dst, (v4i32 immAllZerosV))]>;
1557 }
1558
1559 def : Pat<(v2i64 immAllZerosV), (V_SET0PI)>;
1560 def : Pat<(v8i16 immAllZerosV), (V_SET0PI)>;
1561 def : Pat<(v16i8 immAllZerosV), (V_SET0PI)>;
1562
1563 def : Pat<(f32 (vector_extract (v4f32 VR128:$src), (iPTR 0))),
1564           (f32 (EXTRACT_SUBREG (v4f32 VR128:$src), sub_ss))>;
1565
1566 //===---------------------------------------------------------------------===//
1567 // SSE2 Instructions
1568 //===---------------------------------------------------------------------===//
1569
1570 // Conversion instructions
1571 def CVTSD2SSrr  : SDI<0x5A, MRMSrcReg, (outs FR32:$dst), (ins FR64:$src),
1572                       "cvtsd2ss\t{$src, $dst|$dst, $src}",
1573                       [(set FR32:$dst, (fround FR64:$src))]>;
1574 def CVTSD2SSrm  : I<0x5A, MRMSrcMem, (outs FR32:$dst), (ins f64mem:$src),
1575                       "cvtsd2ss\t{$src, $dst|$dst, $src}",
1576                       [(set FR32:$dst, (fround (loadf64 addr:$src)))]>, XD,
1577                   Requires<[HasSSE2, OptForSize]>;
1578
1579 def CVTPS2DQrr : PDI<0x5B, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1580                      "cvtps2dq\t{$src, $dst|$dst, $src}", []>;
1581 def CVTPS2DQrm : PDI<0x5B, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1582                      "cvtps2dq\t{$src, $dst|$dst, $src}", []>;
1583 def COMISDrr: PDI<0x2F, MRMSrcReg, (outs), (ins VR128:$src1, VR128:$src2),
1584                   "comisd\t{$src2, $src1|$src1, $src2}", []>;
1585 def COMISDrm: PDI<0x2F, MRMSrcMem, (outs), (ins VR128:$src1, f128mem:$src2),
1586                       "comisd\t{$src2, $src1|$src1, $src2}", []>;
1587
1588 // SSE2 instructions with XS prefix
1589 def CVTSS2SDrr : I<0x5A, MRMSrcReg, (outs FR64:$dst), (ins FR32:$src),
1590                    "cvtss2sd\t{$src, $dst|$dst, $src}",
1591                    [(set FR64:$dst, (fextend FR32:$src))]>, XS,
1592                  Requires<[HasSSE2]>;
1593 def CVTSS2SDrm : I<0x5A, MRMSrcMem, (outs FR64:$dst), (ins f32mem:$src),
1594                    "cvtss2sd\t{$src, $dst|$dst, $src}",
1595                    [(set FR64:$dst, (extloadf32 addr:$src))]>, XS,
1596                  Requires<[HasSSE2, OptForSize]>;
1597
1598 def : Pat<(extloadf32 addr:$src),
1599           (CVTSS2SDrr (MOVSSrm addr:$src))>,
1600       Requires<[HasSSE2, OptForSpeed]>;
1601
1602 // Match intrinsics which expect MM and XMM operand(s).
1603 def Int_CVTPI2PDrr : PDI<0x2A, MRMSrcReg, (outs VR128:$dst), (ins VR64:$src),
1604                          "cvtpi2pd\t{$src, $dst|$dst, $src}",
1605                          [(set VR128:$dst, (int_x86_sse_cvtpi2pd VR64:$src))]>;
1606 def Int_CVTPI2PDrm : PDI<0x2A, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
1607                          "cvtpi2pd\t{$src, $dst|$dst, $src}",
1608                          [(set VR128:$dst, (int_x86_sse_cvtpi2pd
1609                                             (load addr:$src)))]>;
1610
1611 // Aliases for intrinsics
1612 def Int_CVTTSD2SIrr : SDI<0x2C, MRMSrcReg, (outs GR32:$dst), (ins VR128:$src),
1613                           "cvttsd2si\t{$src, $dst|$dst, $src}",
1614                           [(set GR32:$dst,
1615                             (int_x86_sse2_cvttsd2si VR128:$src))]>;
1616 def Int_CVTTSD2SIrm : SDI<0x2C, MRMSrcMem, (outs GR32:$dst), (ins f128mem:$src),
1617                           "cvttsd2si\t{$src, $dst|$dst, $src}",
1618                           [(set GR32:$dst, (int_x86_sse2_cvttsd2si
1619                                             (load addr:$src)))]>;
1620
1621 //===---------------------------------------------------------------------===//
1622 // SSE packed FP Instructions
1623
1624 // Move Instructions
1625 let neverHasSideEffects = 1 in
1626 def MOVAPDrr : PDI<0x28, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1627                    "movapd\t{$src, $dst|$dst, $src}", []>;
1628 let canFoldAsLoad = 1, isReMaterializable = 1 in
1629 def MOVAPDrm : PDI<0x28, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1630                    "movapd\t{$src, $dst|$dst, $src}",
1631                    [(set VR128:$dst, (alignedloadv2f64 addr:$src))]>;
1632
1633 def MOVAPDmr : PDI<0x29, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
1634                    "movapd\t{$src, $dst|$dst, $src}",
1635                    [(alignedstore (v2f64 VR128:$src), addr:$dst)]>;
1636
1637 let neverHasSideEffects = 1 in
1638 def MOVUPDrr : PDI<0x10, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1639                    "movupd\t{$src, $dst|$dst, $src}", []>;
1640 let canFoldAsLoad = 1 in
1641 def MOVUPDrm : PDI<0x10, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1642                    "movupd\t{$src, $dst|$dst, $src}",
1643                    [(set VR128:$dst, (loadv2f64 addr:$src))]>;
1644 def MOVUPDmr : PDI<0x11, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
1645                    "movupd\t{$src, $dst|$dst, $src}",
1646                    [(store (v2f64 VR128:$src), addr:$dst)]>;
1647
1648 // Intrinsic forms of MOVUPD load and store
1649 def MOVUPDrm_Int : PDI<0x10, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1650                        "movupd\t{$src, $dst|$dst, $src}",
1651                        [(set VR128:$dst, (int_x86_sse2_loadu_pd addr:$src))]>;
1652 def MOVUPDmr_Int : PDI<0x11, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
1653                        "movupd\t{$src, $dst|$dst, $src}",
1654                        [(int_x86_sse2_storeu_pd addr:$dst, VR128:$src)]>;
1655
1656 let Constraints = "$src1 = $dst" in {
1657   let AddedComplexity = 20 in {
1658     def MOVLPDrm : PDI<0x12, MRMSrcMem,
1659                        (outs VR128:$dst), (ins VR128:$src1, f64mem:$src2),
1660                        "movlpd\t{$src2, $dst|$dst, $src2}",
1661                        [(set VR128:$dst,
1662                          (v2f64 (movlp VR128:$src1,
1663                                  (scalar_to_vector (loadf64 addr:$src2)))))]>;
1664     def MOVHPDrm : PDI<0x16, MRMSrcMem,
1665                        (outs VR128:$dst), (ins VR128:$src1, f64mem:$src2),
1666                        "movhpd\t{$src2, $dst|$dst, $src2}",
1667                        [(set VR128:$dst,
1668                          (v2f64 (movlhps VR128:$src1,
1669                                  (scalar_to_vector (loadf64 addr:$src2)))))]>;
1670   } // AddedComplexity
1671 } // Constraints = "$src1 = $dst"
1672
1673 def MOVLPDmr : PDI<0x13, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
1674                    "movlpd\t{$src, $dst|$dst, $src}",
1675                    [(store (f64 (vector_extract (v2f64 VR128:$src),
1676                                  (iPTR 0))), addr:$dst)]>;
1677
1678 // v2f64 extract element 1 is always custom lowered to unpack high to low
1679 // and extract element 0 so the non-store version isn't too horrible.
1680 def MOVHPDmr : PDI<0x17, MRMDestMem, (outs), (ins f64mem:$dst, VR128:$src),
1681                    "movhpd\t{$src, $dst|$dst, $src}",
1682                    [(store (f64 (vector_extract
1683                                  (v2f64 (unpckh VR128:$src, (undef))),
1684                                  (iPTR 0))), addr:$dst)]>;
1685
1686 // SSE2 instructions without OpSize prefix
1687 def Int_CVTDQ2PSrr : I<0x5B, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1688                        "cvtdq2ps\t{$src, $dst|$dst, $src}",
1689                        [(set VR128:$dst, (int_x86_sse2_cvtdq2ps VR128:$src))]>,
1690                      TB, Requires<[HasSSE2]>;
1691 def Int_CVTDQ2PSrm : I<0x5B, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
1692                       "cvtdq2ps\t{$src, $dst|$dst, $src}",
1693                       [(set VR128:$dst, (int_x86_sse2_cvtdq2ps
1694                                         (bitconvert (memopv2i64 addr:$src))))]>,
1695                      TB, Requires<[HasSSE2]>;
1696
1697 // SSE2 instructions with XS prefix
1698 def Int_CVTDQ2PDrr : I<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1699                        "cvtdq2pd\t{$src, $dst|$dst, $src}",
1700                        [(set VR128:$dst, (int_x86_sse2_cvtdq2pd VR128:$src))]>,
1701                      XS, Requires<[HasSSE2]>;
1702 def Int_CVTDQ2PDrm : I<0xE6, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
1703                      "cvtdq2pd\t{$src, $dst|$dst, $src}",
1704                      [(set VR128:$dst, (int_x86_sse2_cvtdq2pd
1705                                         (bitconvert (memopv2i64 addr:$src))))]>,
1706                      XS, Requires<[HasSSE2]>;
1707
1708 def Int_CVTPS2DQrr : PDI<0x5B, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1709                         "cvtps2dq\t{$src, $dst|$dst, $src}",
1710                         [(set VR128:$dst, (int_x86_sse2_cvtps2dq VR128:$src))]>;
1711 def Int_CVTPS2DQrm : PDI<0x5B, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1712                          "cvtps2dq\t{$src, $dst|$dst, $src}",
1713                          [(set VR128:$dst, (int_x86_sse2_cvtps2dq
1714                                             (memop addr:$src)))]>;
1715 // SSE2 packed instructions with XS prefix
1716 def CVTTPS2DQrr : SSI<0x5B, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1717                       "cvttps2dq\t{$src, $dst|$dst, $src}", []>;
1718 def CVTTPS2DQrm : SSI<0x5B, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1719                       "cvttps2dq\t{$src, $dst|$dst, $src}", []>;
1720
1721 def Int_CVTTPS2DQrr : I<0x5B, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1722                         "cvttps2dq\t{$src, $dst|$dst, $src}",
1723                         [(set VR128:$dst,
1724                               (int_x86_sse2_cvttps2dq VR128:$src))]>,
1725                       XS, Requires<[HasSSE2]>;
1726 def Int_CVTTPS2DQrm : I<0x5B, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1727                         "cvttps2dq\t{$src, $dst|$dst, $src}",
1728                         [(set VR128:$dst, (int_x86_sse2_cvttps2dq
1729                                            (memop addr:$src)))]>,
1730                       XS, Requires<[HasSSE2]>;
1731
1732 // SSE2 packed instructions with XD prefix
1733 def Int_CVTPD2DQrr : I<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1734                        "cvtpd2dq\t{$src, $dst|$dst, $src}",
1735                        [(set VR128:$dst, (int_x86_sse2_cvtpd2dq VR128:$src))]>,
1736                      XD, Requires<[HasSSE2]>;
1737 def Int_CVTPD2DQrm : I<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1738                        "cvtpd2dq\t{$src, $dst|$dst, $src}",
1739                        [(set VR128:$dst, (int_x86_sse2_cvtpd2dq
1740                                           (memop addr:$src)))]>,
1741                      XD, Requires<[HasSSE2]>;
1742
1743 def Int_CVTTPD2DQrr : PDI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1744                           "cvttpd2dq\t{$src, $dst|$dst, $src}",
1745                        [(set VR128:$dst, (int_x86_sse2_cvttpd2dq VR128:$src))]>;
1746 def Int_CVTTPD2DQrm : PDI<0xE6, MRMSrcMem, (outs VR128:$dst),(ins f128mem:$src),
1747                           "cvttpd2dq\t{$src, $dst|$dst, $src}",
1748                           [(set VR128:$dst, (int_x86_sse2_cvttpd2dq
1749                                              (memop addr:$src)))]>;
1750
1751 // SSE2 instructions without OpSize prefix
1752 def CVTPS2PDrr : I<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1753                        "cvtps2pd\t{$src, $dst|$dst, $src}", []>, TB;
1754 def CVTPS2PDrm : I<0x5A, MRMSrcMem, (outs VR128:$dst), (ins f64mem:$src),
1755                        "cvtps2pd\t{$src, $dst|$dst, $src}", []>, TB;
1756
1757 def Int_CVTPS2PDrr : I<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1758                        "cvtps2pd\t{$src, $dst|$dst, $src}",
1759                        [(set VR128:$dst, (int_x86_sse2_cvtps2pd VR128:$src))]>,
1760                      TB, Requires<[HasSSE2]>;
1761 def Int_CVTPS2PDrm : I<0x5A, MRMSrcMem, (outs VR128:$dst), (ins f64mem:$src),
1762                        "cvtps2pd\t{$src, $dst|$dst, $src}",
1763                        [(set VR128:$dst, (int_x86_sse2_cvtps2pd
1764                                           (load addr:$src)))]>,
1765                      TB, Requires<[HasSSE2]>;
1766
1767 def CVTPD2PSrr : PDI<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1768                      "cvtpd2ps\t{$src, $dst|$dst, $src}", []>;
1769 def CVTPD2PSrm : PDI<0x5A, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1770                      "cvtpd2ps\t{$src, $dst|$dst, $src}", []>;
1771
1772
1773 def Int_CVTPD2PSrr : PDI<0x5A, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1774                          "cvtpd2ps\t{$src, $dst|$dst, $src}",
1775                         [(set VR128:$dst, (int_x86_sse2_cvtpd2ps VR128:$src))]>;
1776 def Int_CVTPD2PSrm : PDI<0x5A, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1777                          "cvtpd2ps\t{$src, $dst|$dst, $src}",
1778                          [(set VR128:$dst, (int_x86_sse2_cvtpd2ps
1779                                             (memop addr:$src)))]>;
1780
1781 // Match intrinsics which expect XMM operand(s).
1782 // Aliases for intrinsics
1783 let Constraints = "$src1 = $dst" in {
1784 def Int_CVTSI2SDrr: SDI<0x2A, MRMSrcReg,
1785                         (outs VR128:$dst), (ins VR128:$src1, GR32:$src2),
1786                         "cvtsi2sd\t{$src2, $dst|$dst, $src2}",
1787                         [(set VR128:$dst, (int_x86_sse2_cvtsi2sd VR128:$src1,
1788                                            GR32:$src2))]>;
1789 def Int_CVTSI2SDrm: SDI<0x2A, MRMSrcMem,
1790                         (outs VR128:$dst), (ins VR128:$src1, i32mem:$src2),
1791                         "cvtsi2sd\t{$src2, $dst|$dst, $src2}",
1792                         [(set VR128:$dst, (int_x86_sse2_cvtsi2sd VR128:$src1,
1793                                            (loadi32 addr:$src2)))]>;
1794 def Int_CVTSD2SSrr: SDI<0x5A, MRMSrcReg,
1795                         (outs VR128:$dst), (ins VR128:$src1, VR128:$src2),
1796                    "cvtsd2ss\t{$src2, $dst|$dst, $src2}",
1797                    [(set VR128:$dst, (int_x86_sse2_cvtsd2ss VR128:$src1,
1798                                       VR128:$src2))]>;
1799 def Int_CVTSD2SSrm: SDI<0x5A, MRMSrcMem,
1800                         (outs VR128:$dst), (ins VR128:$src1, f64mem:$src2),
1801                    "cvtsd2ss\t{$src2, $dst|$dst, $src2}",
1802                    [(set VR128:$dst, (int_x86_sse2_cvtsd2ss VR128:$src1,
1803                                       (load addr:$src2)))]>;
1804 def Int_CVTSS2SDrr: I<0x5A, MRMSrcReg,
1805                       (outs VR128:$dst), (ins VR128:$src1, VR128:$src2),
1806                     "cvtss2sd\t{$src2, $dst|$dst, $src2}",
1807                     [(set VR128:$dst, (int_x86_sse2_cvtss2sd VR128:$src1,
1808                                        VR128:$src2))]>, XS,
1809                     Requires<[HasSSE2]>;
1810 def Int_CVTSS2SDrm: I<0x5A, MRMSrcMem,
1811                       (outs VR128:$dst), (ins VR128:$src1, f32mem:$src2),
1812                     "cvtss2sd\t{$src2, $dst|$dst, $src2}",
1813                     [(set VR128:$dst, (int_x86_sse2_cvtss2sd VR128:$src1,
1814                                        (load addr:$src2)))]>, XS,
1815                     Requires<[HasSSE2]>;
1816 }
1817
1818 // Arithmetic
1819
1820 /// sse2_fp_unop_rm - SSE2 unops come in both scalar and vector forms.
1821 ///
1822 /// In addition, we also have a special variant of the scalar form here to
1823 /// represent the associated intrinsic operation.  This form is unlike the
1824 /// plain scalar form, in that it takes an entire vector (instead of a
1825 /// scalar) and leaves the top elements undefined.
1826 ///
1827 /// And, we have a special variant form for a full-vector intrinsic form.
1828 ///
1829 /// These four forms can each have a reg or a mem operand, so there are a
1830 /// total of eight "instructions".
1831 ///
1832 multiclass sse2_fp_unop_rm<bits<8> opc, string OpcodeStr,
1833                            SDNode OpNode,
1834                            Intrinsic F64Int,
1835                            Intrinsic V2F64Int,
1836                            bit Commutable = 0> {
1837   // Scalar operation, reg.
1838   def SDr : SDI<opc, MRMSrcReg, (outs FR64:$dst), (ins FR64:$src),
1839                 !strconcat(OpcodeStr, "sd\t{$src, $dst|$dst, $src}"),
1840                 [(set FR64:$dst, (OpNode FR64:$src))]> {
1841     let isCommutable = Commutable;
1842   }
1843
1844   // Scalar operation, mem.
1845   def SDm : SDI<opc, MRMSrcMem, (outs FR64:$dst), (ins f64mem:$src),
1846                 !strconcat(OpcodeStr, "sd\t{$src, $dst|$dst, $src}"),
1847                 [(set FR64:$dst, (OpNode (load addr:$src)))]>;
1848
1849   // Vector operation, reg.
1850   def PDr : PDI<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1851               !strconcat(OpcodeStr, "pd\t{$src, $dst|$dst, $src}"),
1852               [(set VR128:$dst, (v2f64 (OpNode VR128:$src)))]> {
1853     let isCommutable = Commutable;
1854   }
1855
1856   // Vector operation, mem.
1857   def PDm : PDI<opc, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1858                 !strconcat(OpcodeStr, "pd\t{$src, $dst|$dst, $src}"),
1859                 [(set VR128:$dst, (OpNode (memopv2f64 addr:$src)))]>;
1860
1861   // Intrinsic operation, reg.
1862   def SDr_Int : SDI<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1863                     !strconcat(OpcodeStr, "sd\t{$src, $dst|$dst, $src}"),
1864                     [(set VR128:$dst, (F64Int VR128:$src))]> {
1865     let isCommutable = Commutable;
1866   }
1867
1868   // Intrinsic operation, mem.
1869   def SDm_Int : SDI<opc, MRMSrcMem, (outs VR128:$dst), (ins sdmem:$src),
1870                     !strconcat(OpcodeStr, "sd\t{$src, $dst|$dst, $src}"),
1871                     [(set VR128:$dst, (F64Int sse_load_f64:$src))]>;
1872
1873   // Vector intrinsic operation, reg
1874   def PDr_Int : PDI<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1875                     !strconcat(OpcodeStr, "pd\t{$src, $dst|$dst, $src}"),
1876                     [(set VR128:$dst, (V2F64Int VR128:$src))]> {
1877     let isCommutable = Commutable;
1878   }
1879
1880   // Vector intrinsic operation, mem
1881   def PDm_Int : PDI<opc, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
1882                     !strconcat(OpcodeStr, "pd\t{$src, $dst|$dst, $src}"),
1883                     [(set VR128:$dst, (V2F64Int (memopv2f64 addr:$src)))]>;
1884 }
1885
1886 // Square root.
1887 defm SQRT  : sse2_fp_unop_rm<0x51, "sqrt",  fsqrt,
1888                              int_x86_sse2_sqrt_sd, int_x86_sse2_sqrt_pd>;
1889
1890 // There is no f64 version of the reciprocal approximation instructions.
1891
1892 //===---------------------------------------------------------------------===//
1893 // SSE integer instructions
1894 let ExeDomain = SSEPackedInt in {
1895
1896 // Move Instructions
1897 let neverHasSideEffects = 1 in
1898 def MOVDQArr : PDI<0x6F, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
1899                    "movdqa\t{$src, $dst|$dst, $src}", []>;
1900 let canFoldAsLoad = 1, mayLoad = 1 in
1901 def MOVDQArm : PDI<0x6F, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
1902                    "movdqa\t{$src, $dst|$dst, $src}",
1903                    [/*(set VR128:$dst, (alignedloadv2i64 addr:$src))*/]>;
1904 let mayStore = 1 in
1905 def MOVDQAmr : PDI<0x7F, MRMDestMem, (outs), (ins i128mem:$dst, VR128:$src),
1906                    "movdqa\t{$src, $dst|$dst, $src}",
1907                    [/*(alignedstore (v2i64 VR128:$src), addr:$dst)*/]>;
1908 let canFoldAsLoad = 1, mayLoad = 1 in
1909 def MOVDQUrm :   I<0x6F, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
1910                    "movdqu\t{$src, $dst|$dst, $src}",
1911                    [/*(set VR128:$dst, (loadv2i64 addr:$src))*/]>,
1912                  XS, Requires<[HasSSE2]>;
1913 let mayStore = 1 in
1914 def MOVDQUmr :   I<0x7F, MRMDestMem, (outs), (ins i128mem:$dst, VR128:$src),
1915                    "movdqu\t{$src, $dst|$dst, $src}",
1916                    [/*(store (v2i64 VR128:$src), addr:$dst)*/]>,
1917                  XS, Requires<[HasSSE2]>;
1918
1919 // Intrinsic forms of MOVDQU load and store
1920 let canFoldAsLoad = 1 in
1921 def MOVDQUrm_Int :   I<0x6F, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
1922                        "movdqu\t{$src, $dst|$dst, $src}",
1923                        [(set VR128:$dst, (int_x86_sse2_loadu_dq addr:$src))]>,
1924                  XS, Requires<[HasSSE2]>;
1925 def MOVDQUmr_Int :   I<0x7F, MRMDestMem, (outs), (ins i128mem:$dst, VR128:$src),
1926                        "movdqu\t{$src, $dst|$dst, $src}",
1927                        [(int_x86_sse2_storeu_dq addr:$dst, VR128:$src)]>,
1928                      XS, Requires<[HasSSE2]>;
1929
1930 let Constraints = "$src1 = $dst" in {
1931
1932 multiclass PDI_binop_rm_int<bits<8> opc, string OpcodeStr, Intrinsic IntId,
1933                             bit Commutable = 0> {
1934   def rr : PDI<opc, MRMSrcReg, (outs VR128:$dst),
1935                                (ins VR128:$src1, VR128:$src2),
1936                !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
1937                [(set VR128:$dst, (IntId VR128:$src1, VR128:$src2))]> {
1938     let isCommutable = Commutable;
1939   }
1940   def rm : PDI<opc, MRMSrcMem, (outs VR128:$dst),
1941                                (ins VR128:$src1, i128mem:$src2),
1942                !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
1943                [(set VR128:$dst, (IntId VR128:$src1,
1944                                         (bitconvert (memopv2i64
1945                                                      addr:$src2))))]>;
1946 }
1947
1948 multiclass PDI_binop_rmi_int<bits<8> opc, bits<8> opc2, Format ImmForm,
1949                              string OpcodeStr,
1950                              Intrinsic IntId, Intrinsic IntId2> {
1951   def rr : PDI<opc, MRMSrcReg, (outs VR128:$dst),
1952                                (ins VR128:$src1, VR128:$src2),
1953                !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
1954                [(set VR128:$dst, (IntId VR128:$src1, VR128:$src2))]>;
1955   def rm : PDI<opc, MRMSrcMem, (outs VR128:$dst),
1956                                (ins VR128:$src1, i128mem:$src2),
1957                !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
1958                [(set VR128:$dst, (IntId VR128:$src1,
1959                                       (bitconvert (memopv2i64 addr:$src2))))]>;
1960   def ri : PDIi8<opc2, ImmForm, (outs VR128:$dst),
1961                                 (ins VR128:$src1, i32i8imm:$src2),
1962                !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
1963                [(set VR128:$dst, (IntId2 VR128:$src1, (i32 imm:$src2)))]>;
1964 }
1965
1966 /// PDI_binop_rm - Simple SSE2 binary operator.
1967 multiclass PDI_binop_rm<bits<8> opc, string OpcodeStr, SDNode OpNode,
1968                         ValueType OpVT, bit Commutable = 0> {
1969   def rr : PDI<opc, MRMSrcReg, (outs VR128:$dst),
1970                                (ins VR128:$src1, VR128:$src2),
1971                !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
1972                [(set VR128:$dst, (OpVT (OpNode VR128:$src1, VR128:$src2)))]> {
1973     let isCommutable = Commutable;
1974   }
1975   def rm : PDI<opc, MRMSrcMem, (outs VR128:$dst),
1976                                (ins VR128:$src1, i128mem:$src2),
1977                !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
1978                [(set VR128:$dst, (OpVT (OpNode VR128:$src1,
1979                                      (bitconvert (memopv2i64 addr:$src2)))))]>;
1980 }
1981
1982 /// PDI_binop_rm_v2i64 - Simple SSE2 binary operator whose type is v2i64.
1983 ///
1984 /// FIXME: we could eliminate this and use PDI_binop_rm instead if tblgen knew
1985 /// to collapse (bitconvert VT to VT) into its operand.
1986 ///
1987 multiclass PDI_binop_rm_v2i64<bits<8> opc, string OpcodeStr, SDNode OpNode,
1988                               bit Commutable = 0> {
1989   def rr : PDI<opc, MRMSrcReg, (outs VR128:$dst),
1990                (ins VR128:$src1, VR128:$src2),
1991                !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
1992                [(set VR128:$dst, (v2i64 (OpNode VR128:$src1, VR128:$src2)))]> {
1993     let isCommutable = Commutable;
1994   }
1995   def rm : PDI<opc, MRMSrcMem, (outs VR128:$dst),
1996                (ins VR128:$src1, i128mem:$src2),
1997                !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
1998                [(set VR128:$dst, (OpNode VR128:$src1,
1999                (memopv2i64 addr:$src2)))]>;
2000 }
2001
2002 } // Constraints = "$src1 = $dst"
2003 } // ExeDomain = SSEPackedInt
2004
2005 // 128-bit Integer Arithmetic
2006
2007 defm PADDB : PDI_binop_rm<0xFC, "paddb", add, v16i8, 1>;
2008 defm PADDW : PDI_binop_rm<0xFD, "paddw", add, v8i16, 1>;
2009 defm PADDD : PDI_binop_rm<0xFE, "paddd", add, v4i32, 1>;
2010 defm PADDQ : PDI_binop_rm_v2i64<0xD4, "paddq", add, 1>;
2011
2012 defm PADDSB  : PDI_binop_rm_int<0xEC, "paddsb" , int_x86_sse2_padds_b, 1>;
2013 defm PADDSW  : PDI_binop_rm_int<0xED, "paddsw" , int_x86_sse2_padds_w, 1>;
2014 defm PADDUSB : PDI_binop_rm_int<0xDC, "paddusb", int_x86_sse2_paddus_b, 1>;
2015 defm PADDUSW : PDI_binop_rm_int<0xDD, "paddusw", int_x86_sse2_paddus_w, 1>;
2016
2017 defm PSUBB : PDI_binop_rm<0xF8, "psubb", sub, v16i8>;
2018 defm PSUBW : PDI_binop_rm<0xF9, "psubw", sub, v8i16>;
2019 defm PSUBD : PDI_binop_rm<0xFA, "psubd", sub, v4i32>;
2020 defm PSUBQ : PDI_binop_rm_v2i64<0xFB, "psubq", sub>;
2021
2022 defm PSUBSB  : PDI_binop_rm_int<0xE8, "psubsb" , int_x86_sse2_psubs_b>;
2023 defm PSUBSW  : PDI_binop_rm_int<0xE9, "psubsw" , int_x86_sse2_psubs_w>;
2024 defm PSUBUSB : PDI_binop_rm_int<0xD8, "psubusb", int_x86_sse2_psubus_b>;
2025 defm PSUBUSW : PDI_binop_rm_int<0xD9, "psubusw", int_x86_sse2_psubus_w>;
2026
2027 defm PMULLW : PDI_binop_rm<0xD5, "pmullw", mul, v8i16, 1>;
2028
2029 defm PMULHUW : PDI_binop_rm_int<0xE4, "pmulhuw", int_x86_sse2_pmulhu_w, 1>;
2030 defm PMULHW  : PDI_binop_rm_int<0xE5, "pmulhw" , int_x86_sse2_pmulh_w , 1>;
2031 defm PMULUDQ : PDI_binop_rm_int<0xF4, "pmuludq", int_x86_sse2_pmulu_dq, 1>;
2032
2033 defm PMADDWD : PDI_binop_rm_int<0xF5, "pmaddwd", int_x86_sse2_pmadd_wd, 1>;
2034
2035 defm PAVGB  : PDI_binop_rm_int<0xE0, "pavgb", int_x86_sse2_pavg_b, 1>;
2036 defm PAVGW  : PDI_binop_rm_int<0xE3, "pavgw", int_x86_sse2_pavg_w, 1>;
2037
2038
2039 defm PMINUB : PDI_binop_rm_int<0xDA, "pminub", int_x86_sse2_pminu_b, 1>;
2040 defm PMINSW : PDI_binop_rm_int<0xEA, "pminsw", int_x86_sse2_pmins_w, 1>;
2041 defm PMAXUB : PDI_binop_rm_int<0xDE, "pmaxub", int_x86_sse2_pmaxu_b, 1>;
2042 defm PMAXSW : PDI_binop_rm_int<0xEE, "pmaxsw", int_x86_sse2_pmaxs_w, 1>;
2043 defm PSADBW : PDI_binop_rm_int<0xF6, "psadbw", int_x86_sse2_psad_bw, 1>;
2044
2045
2046 defm PSLLW : PDI_binop_rmi_int<0xF1, 0x71, MRM6r, "psllw",
2047                                int_x86_sse2_psll_w, int_x86_sse2_pslli_w>;
2048 defm PSLLD : PDI_binop_rmi_int<0xF2, 0x72, MRM6r, "pslld",
2049                                int_x86_sse2_psll_d, int_x86_sse2_pslli_d>;
2050 defm PSLLQ : PDI_binop_rmi_int<0xF3, 0x73, MRM6r, "psllq",
2051                                int_x86_sse2_psll_q, int_x86_sse2_pslli_q>;
2052
2053 defm PSRLW : PDI_binop_rmi_int<0xD1, 0x71, MRM2r, "psrlw",
2054                                int_x86_sse2_psrl_w, int_x86_sse2_psrli_w>;
2055 defm PSRLD : PDI_binop_rmi_int<0xD2, 0x72, MRM2r, "psrld",
2056                                int_x86_sse2_psrl_d, int_x86_sse2_psrli_d>;
2057 defm PSRLQ : PDI_binop_rmi_int<0xD3, 0x73, MRM2r, "psrlq",
2058                                int_x86_sse2_psrl_q, int_x86_sse2_psrli_q>;
2059
2060 defm PSRAW : PDI_binop_rmi_int<0xE1, 0x71, MRM4r, "psraw",
2061                                int_x86_sse2_psra_w, int_x86_sse2_psrai_w>;
2062 defm PSRAD : PDI_binop_rmi_int<0xE2, 0x72, MRM4r, "psrad",
2063                                int_x86_sse2_psra_d, int_x86_sse2_psrai_d>;
2064
2065 // 128-bit logical shifts.
2066 let Constraints = "$src1 = $dst", neverHasSideEffects = 1,
2067     ExeDomain = SSEPackedInt in {
2068   def PSLLDQri : PDIi8<0x73, MRM7r,
2069                        (outs VR128:$dst), (ins VR128:$src1, i32i8imm:$src2),
2070                        "pslldq\t{$src2, $dst|$dst, $src2}", []>;
2071   def PSRLDQri : PDIi8<0x73, MRM3r,
2072                        (outs VR128:$dst), (ins VR128:$src1, i32i8imm:$src2),
2073                        "psrldq\t{$src2, $dst|$dst, $src2}", []>;
2074   // PSRADQri doesn't exist in SSE[1-3].
2075 }
2076
2077 let Predicates = [HasSSE2] in {
2078   def : Pat<(int_x86_sse2_psll_dq VR128:$src1, imm:$src2),
2079             (v2i64 (PSLLDQri VR128:$src1, (BYTE_imm imm:$src2)))>;
2080   def : Pat<(int_x86_sse2_psrl_dq VR128:$src1, imm:$src2),
2081             (v2i64 (PSRLDQri VR128:$src1, (BYTE_imm imm:$src2)))>;
2082   def : Pat<(int_x86_sse2_psll_dq_bs VR128:$src1, imm:$src2),
2083             (v2i64 (PSLLDQri VR128:$src1, imm:$src2))>;
2084   def : Pat<(int_x86_sse2_psrl_dq_bs VR128:$src1, imm:$src2),
2085             (v2i64 (PSRLDQri VR128:$src1, imm:$src2))>;
2086   def : Pat<(v2f64 (X86fsrl VR128:$src1, i32immSExt8:$src2)),
2087             (v2f64 (PSRLDQri VR128:$src1, (BYTE_imm imm:$src2)))>;
2088
2089   // Shift up / down and insert zero's.
2090   def : Pat<(v2i64 (X86vshl  VR128:$src, (i8 imm:$amt))),
2091             (v2i64 (PSLLDQri VR128:$src, (BYTE_imm imm:$amt)))>;
2092   def : Pat<(v2i64 (X86vshr  VR128:$src, (i8 imm:$amt))),
2093             (v2i64 (PSRLDQri VR128:$src, (BYTE_imm imm:$amt)))>;
2094 }
2095
2096 // Logical
2097 defm PAND : PDI_binop_rm_v2i64<0xDB, "pand", and, 1>;
2098 defm POR  : PDI_binop_rm_v2i64<0xEB, "por" , or , 1>;
2099 defm PXOR : PDI_binop_rm_v2i64<0xEF, "pxor", xor, 1>;
2100
2101 let Constraints = "$src1 = $dst", ExeDomain = SSEPackedInt in {
2102   def PANDNrr : PDI<0xDF, MRMSrcReg,
2103                     (outs VR128:$dst), (ins VR128:$src1, VR128:$src2),
2104                     "pandn\t{$src2, $dst|$dst, $src2}",
2105                     [(set VR128:$dst, (v2i64 (and (vnot VR128:$src1),
2106                                               VR128:$src2)))]>;
2107
2108   def PANDNrm : PDI<0xDF, MRMSrcMem,
2109                     (outs VR128:$dst), (ins VR128:$src1, i128mem:$src2),
2110                     "pandn\t{$src2, $dst|$dst, $src2}",
2111                     [(set VR128:$dst, (v2i64 (and (vnot VR128:$src1),
2112                                               (memopv2i64 addr:$src2))))]>;
2113 }
2114
2115 // SSE2 Integer comparison
2116 defm PCMPEQB  : PDI_binop_rm_int<0x74, "pcmpeqb", int_x86_sse2_pcmpeq_b>;
2117 defm PCMPEQW  : PDI_binop_rm_int<0x75, "pcmpeqw", int_x86_sse2_pcmpeq_w>;
2118 defm PCMPEQD  : PDI_binop_rm_int<0x76, "pcmpeqd", int_x86_sse2_pcmpeq_d>;
2119 defm PCMPGTB  : PDI_binop_rm_int<0x64, "pcmpgtb", int_x86_sse2_pcmpgt_b>;
2120 defm PCMPGTW  : PDI_binop_rm_int<0x65, "pcmpgtw", int_x86_sse2_pcmpgt_w>;
2121 defm PCMPGTD  : PDI_binop_rm_int<0x66, "pcmpgtd", int_x86_sse2_pcmpgt_d>;
2122
2123 def : Pat<(v16i8 (X86pcmpeqb VR128:$src1, VR128:$src2)),
2124           (PCMPEQBrr VR128:$src1, VR128:$src2)>;
2125 def : Pat<(v16i8 (X86pcmpeqb VR128:$src1, (memop addr:$src2))),
2126           (PCMPEQBrm VR128:$src1, addr:$src2)>;
2127 def : Pat<(v8i16 (X86pcmpeqw VR128:$src1, VR128:$src2)),
2128           (PCMPEQWrr VR128:$src1, VR128:$src2)>;
2129 def : Pat<(v8i16 (X86pcmpeqw VR128:$src1, (memop addr:$src2))),
2130           (PCMPEQWrm VR128:$src1, addr:$src2)>;
2131 def : Pat<(v4i32 (X86pcmpeqd VR128:$src1, VR128:$src2)),
2132           (PCMPEQDrr VR128:$src1, VR128:$src2)>;
2133 def : Pat<(v4i32 (X86pcmpeqd VR128:$src1, (memop addr:$src2))),
2134           (PCMPEQDrm VR128:$src1, addr:$src2)>;
2135
2136 def : Pat<(v16i8 (X86pcmpgtb VR128:$src1, VR128:$src2)),
2137           (PCMPGTBrr VR128:$src1, VR128:$src2)>;
2138 def : Pat<(v16i8 (X86pcmpgtb VR128:$src1, (memop addr:$src2))),
2139           (PCMPGTBrm VR128:$src1, addr:$src2)>;
2140 def : Pat<(v8i16 (X86pcmpgtw VR128:$src1, VR128:$src2)),
2141           (PCMPGTWrr VR128:$src1, VR128:$src2)>;
2142 def : Pat<(v8i16 (X86pcmpgtw VR128:$src1, (memop addr:$src2))),
2143           (PCMPGTWrm VR128:$src1, addr:$src2)>;
2144 def : Pat<(v4i32 (X86pcmpgtd VR128:$src1, VR128:$src2)),
2145           (PCMPGTDrr VR128:$src1, VR128:$src2)>;
2146 def : Pat<(v4i32 (X86pcmpgtd VR128:$src1, (memop addr:$src2))),
2147           (PCMPGTDrm VR128:$src1, addr:$src2)>;
2148
2149
2150 // Pack instructions
2151 defm PACKSSWB : PDI_binop_rm_int<0x63, "packsswb", int_x86_sse2_packsswb_128>;
2152 defm PACKSSDW : PDI_binop_rm_int<0x6B, "packssdw", int_x86_sse2_packssdw_128>;
2153 defm PACKUSWB : PDI_binop_rm_int<0x67, "packuswb", int_x86_sse2_packuswb_128>;
2154
2155 let ExeDomain = SSEPackedInt in {
2156
2157 // Shuffle and unpack instructions
2158 let AddedComplexity = 5 in {
2159 def PSHUFDri : PDIi8<0x70, MRMSrcReg,
2160                      (outs VR128:$dst), (ins VR128:$src1, i8imm:$src2),
2161                      "pshufd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2162                      [(set VR128:$dst, (v4i32 (pshufd:$src2
2163                                                VR128:$src1, (undef))))]>;
2164 def PSHUFDmi : PDIi8<0x70, MRMSrcMem,
2165                      (outs VR128:$dst), (ins i128mem:$src1, i8imm:$src2),
2166                      "pshufd\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2167                      [(set VR128:$dst, (v4i32 (pshufd:$src2
2168                                              (bc_v4i32 (memopv2i64 addr:$src1)),
2169                                              (undef))))]>;
2170 }
2171
2172 // SSE2 with ImmT == Imm8 and XS prefix.
2173 def PSHUFHWri : Ii8<0x70, MRMSrcReg,
2174                     (outs VR128:$dst), (ins VR128:$src1, i8imm:$src2),
2175                     "pshufhw\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2176                     [(set VR128:$dst, (v8i16 (pshufhw:$src2 VR128:$src1,
2177                                                             (undef))))]>,
2178                 XS, Requires<[HasSSE2]>;
2179 def PSHUFHWmi : Ii8<0x70, MRMSrcMem,
2180                     (outs VR128:$dst), (ins i128mem:$src1, i8imm:$src2),
2181                     "pshufhw\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2182                     [(set VR128:$dst, (v8i16 (pshufhw:$src2
2183                                             (bc_v8i16 (memopv2i64 addr:$src1)),
2184                                             (undef))))]>,
2185                 XS, Requires<[HasSSE2]>;
2186
2187 // SSE2 with ImmT == Imm8 and XD prefix.
2188 def PSHUFLWri : Ii8<0x70, MRMSrcReg,
2189                     (outs VR128:$dst), (ins VR128:$src1, i8imm:$src2),
2190                     "pshuflw\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2191                     [(set VR128:$dst, (v8i16 (pshuflw:$src2 VR128:$src1,
2192                                                             (undef))))]>,
2193                 XD, Requires<[HasSSE2]>;
2194 def PSHUFLWmi : Ii8<0x70, MRMSrcMem,
2195                     (outs VR128:$dst), (ins i128mem:$src1, i8imm:$src2),
2196                     "pshuflw\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2197                     [(set VR128:$dst, (v8i16 (pshuflw:$src2
2198                                              (bc_v8i16 (memopv2i64 addr:$src1)),
2199                                              (undef))))]>,
2200                 XD, Requires<[HasSSE2]>;
2201
2202 // Unpack instructions
2203 multiclass sse2_unpack<bits<8> opc, string OpcodeStr, ValueType vt,
2204                        PatFrag unp_frag, PatFrag bc_frag> {
2205   def rr : PDI<opc, MRMSrcReg,
2206                (outs VR128:$dst), (ins VR128:$src1, VR128:$src2),
2207                !strconcat(OpcodeStr,"\t{$src2, $dst|$dst, $src2}"),
2208                [(set VR128:$dst, (vt (unp_frag VR128:$src1, VR128:$src2)))]>;
2209   def rm : PDI<opc, MRMSrcMem,
2210                (outs VR128:$dst), (ins VR128:$src1, i128mem:$src2),
2211                !strconcat(OpcodeStr,"\t{$src2, $dst|$dst, $src2}"),
2212                [(set VR128:$dst, (unp_frag VR128:$src1,
2213                                            (bc_frag (memopv2i64
2214                                                         addr:$src2))))]>;
2215 }
2216
2217 let Constraints = "$src1 = $dst" in {
2218   defm PUNPCKLBW  : sse2_unpack<0x60, "punpcklbw", v16i8, unpckl, bc_v16i8>;
2219   defm PUNPCKLWD  : sse2_unpack<0x61, "punpcklwd", v8i16, unpckl, bc_v8i16>;
2220   defm PUNPCKLDQ  : sse2_unpack<0x62, "punpckldq", v4i32, unpckl, bc_v4i32>;
2221
2222   /// FIXME: we could eliminate this and use sse2_unpack instead if tblgen
2223   /// knew to collapse (bitconvert VT to VT) into its operand.
2224   def PUNPCKLQDQrr : PDI<0x6C, MRMSrcReg,
2225                          (outs VR128:$dst), (ins VR128:$src1, VR128:$src2),
2226                          "punpcklqdq\t{$src2, $dst|$dst, $src2}",
2227                         [(set VR128:$dst,
2228                           (v2i64 (unpckl VR128:$src1, VR128:$src2)))]>;
2229   def PUNPCKLQDQrm : PDI<0x6C, MRMSrcMem,
2230                          (outs VR128:$dst), (ins VR128:$src1, i128mem:$src2),
2231                          "punpcklqdq\t{$src2, $dst|$dst, $src2}",
2232                         [(set VR128:$dst,
2233                           (v2i64 (unpckl VR128:$src1,
2234                                          (memopv2i64 addr:$src2))))]>;
2235
2236   defm PUNPCKHBW  : sse2_unpack<0x68, "punpckhbw", v16i8, unpckh, bc_v16i8>;
2237   defm PUNPCKHWD  : sse2_unpack<0x69, "punpckhwd", v8i16, unpckh, bc_v8i16>;
2238   defm PUNPCKHDQ  : sse2_unpack<0x6A, "punpckhdq", v4i32, unpckh, bc_v4i32>;
2239
2240   /// FIXME: we could eliminate this and use sse2_unpack instead if tblgen
2241   /// knew to collapse (bitconvert VT to VT) into its operand.
2242   def PUNPCKHQDQrr : PDI<0x6D, MRMSrcReg,
2243                          (outs VR128:$dst), (ins VR128:$src1, VR128:$src2),
2244                          "punpckhqdq\t{$src2, $dst|$dst, $src2}",
2245                         [(set VR128:$dst,
2246                           (v2i64 (unpckh VR128:$src1, VR128:$src2)))]>;
2247   def PUNPCKHQDQrm : PDI<0x6D, MRMSrcMem,
2248                         (outs VR128:$dst), (ins VR128:$src1, i128mem:$src2),
2249                         "punpckhqdq\t{$src2, $dst|$dst, $src2}",
2250                         [(set VR128:$dst,
2251                           (v2i64 (unpckh VR128:$src1,
2252                                          (memopv2i64 addr:$src2))))]>;
2253 }
2254
2255 // Extract / Insert
2256 def PEXTRWri : PDIi8<0xC5, MRMSrcReg,
2257                     (outs GR32:$dst), (ins VR128:$src1, i32i8imm:$src2),
2258                     "pextrw\t{$src2, $src1, $dst|$dst, $src1, $src2}",
2259                     [(set GR32:$dst, (X86pextrw (v8i16 VR128:$src1),
2260                                                 imm:$src2))]>;
2261 let Constraints = "$src1 = $dst" in {
2262   def PINSRWrri : PDIi8<0xC4, MRMSrcReg,
2263                        (outs VR128:$dst), (ins VR128:$src1,
2264                         GR32:$src2, i32i8imm:$src3),
2265                        "pinsrw\t{$src3, $src2, $dst|$dst, $src2, $src3}",
2266                        [(set VR128:$dst,
2267                          (X86pinsrw VR128:$src1, GR32:$src2, imm:$src3))]>;
2268   def PINSRWrmi : PDIi8<0xC4, MRMSrcMem,
2269                        (outs VR128:$dst), (ins VR128:$src1,
2270                         i16mem:$src2, i32i8imm:$src3),
2271                        "pinsrw\t{$src3, $src2, $dst|$dst, $src2, $src3}",
2272                        [(set VR128:$dst,
2273                          (X86pinsrw VR128:$src1, (extloadi16 addr:$src2),
2274                                     imm:$src3))]>;
2275 }
2276
2277 // Mask creation
2278 def PMOVMSKBrr : PDI<0xD7, MRMSrcReg, (outs GR32:$dst), (ins VR128:$src),
2279                      "pmovmskb\t{$src, $dst|$dst, $src}",
2280                      [(set GR32:$dst, (int_x86_sse2_pmovmskb_128 VR128:$src))]>;
2281
2282 // Conditional store
2283 let Uses = [EDI] in
2284 def MASKMOVDQU : PDI<0xF7, MRMSrcReg, (outs), (ins VR128:$src, VR128:$mask),
2285                      "maskmovdqu\t{$mask, $src|$src, $mask}",
2286                      [(int_x86_sse2_maskmov_dqu VR128:$src, VR128:$mask, EDI)]>;
2287
2288 let Uses = [RDI] in
2289 def MASKMOVDQU64 : PDI<0xF7, MRMSrcReg, (outs), (ins VR128:$src, VR128:$mask),
2290                      "maskmovdqu\t{$mask, $src|$src, $mask}",
2291                      [(int_x86_sse2_maskmov_dqu VR128:$src, VR128:$mask, RDI)]>;
2292
2293 } // ExeDomain = SSEPackedInt
2294
2295 // Non-temporal stores
2296 def MOVNTPDmr_Int : PDI<0x2B, MRMDestMem, (outs), (ins i128mem:$dst, VR128:$src),
2297                         "movntpd\t{$src, $dst|$dst, $src}",
2298                         [(int_x86_sse2_movnt_pd addr:$dst, VR128:$src)]>;
2299 let ExeDomain = SSEPackedInt in
2300 def MOVNTDQmr_Int : PDI<0xE7, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
2301                         "movntdq\t{$src, $dst|$dst, $src}",
2302                         [(int_x86_sse2_movnt_dq addr:$dst, VR128:$src)]>;
2303 def MOVNTImr_Int  :   I<0xC3, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
2304                     "movnti\t{$src, $dst|$dst, $src}",
2305                     [(int_x86_sse2_movnt_i addr:$dst, GR32:$src)]>,
2306                   TB, Requires<[HasSSE2]>;
2307
2308 let AddedComplexity = 400 in { // Prefer non-temporal versions
2309 def MOVNTPDmr : PDI<0x2B, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
2310                     "movntpd\t{$src, $dst|$dst, $src}",
2311                     [(alignednontemporalstore(v2f64 VR128:$src), addr:$dst)]>;
2312
2313 let ExeDomain = SSEPackedInt in
2314 def MOVNTDQmr : PDI<0xE7, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src),
2315                     "movntdq\t{$src, $dst|$dst, $src}",
2316                     [(alignednontemporalstore (v4f32 VR128:$src), addr:$dst)]>;
2317 }
2318
2319 // Flush cache
2320 def CLFLUSH : I<0xAE, MRM7m, (outs), (ins i8mem:$src),
2321                "clflush\t$src", [(int_x86_sse2_clflush addr:$src)]>,
2322               TB, Requires<[HasSSE2]>;
2323
2324 // Load, store, and memory fence
2325 def LFENCE : I<0xAE, MRM_E8, (outs), (ins),
2326                "lfence", [(int_x86_sse2_lfence)]>, TB, Requires<[HasSSE2]>;
2327 def MFENCE : I<0xAE, MRM_F0, (outs), (ins),
2328                "mfence", [(int_x86_sse2_mfence)]>, TB, Requires<[HasSSE2]>;
2329
2330 // Pause. This "instruction" is encoded as "rep; nop", so even though it
2331 // was introduced with SSE2, it's backward compatible.
2332 def PAUSE : I<0x90, RawFrm, (outs), (ins), "pause", []>, REP;
2333
2334 //TODO: custom lower this so as to never even generate the noop
2335 def : Pat<(membarrier (i8 imm), (i8 imm), (i8 imm), (i8 imm),
2336            (i8 0)), (NOOP)>;
2337 def : Pat<(membarrier (i8 0), (i8 0), (i8 0), (i8 1), (i8 1)), (SFENCE)>;
2338 def : Pat<(membarrier (i8 1), (i8 0), (i8 0), (i8 0), (i8 1)), (LFENCE)>;
2339 def : Pat<(membarrier (i8 imm), (i8 imm), (i8 imm), (i8 imm),
2340            (i8 1)), (MFENCE)>;
2341
2342 // Alias instructions that map zero vector to pxor / xorp* for sse.
2343 // We set canFoldAsLoad because this can be converted to a constant-pool
2344 // load of an all-ones value if folding it would be beneficial.
2345 let isReMaterializable = 1, isAsCheapAsAMove = 1, canFoldAsLoad = 1,
2346     isCodeGenOnly = 1, ExeDomain = SSEPackedInt in
2347   // FIXME: Change encoding to pseudo.
2348   def V_SETALLONES : PDI<0x76, MRMInitReg, (outs VR128:$dst), (ins), "",
2349                          [(set VR128:$dst, (v4i32 immAllOnesV))]>;
2350
2351 def MOVDI2PDIrr : PDI<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR32:$src),
2352                       "movd\t{$src, $dst|$dst, $src}",
2353                       [(set VR128:$dst,
2354                         (v4i32 (scalar_to_vector GR32:$src)))]>;
2355 def MOVDI2PDIrm : PDI<0x6E, MRMSrcMem, (outs VR128:$dst), (ins i32mem:$src),
2356                       "movd\t{$src, $dst|$dst, $src}",
2357                       [(set VR128:$dst,
2358                         (v4i32 (scalar_to_vector (loadi32 addr:$src))))]>;
2359
2360 def MOVDI2SSrr  : PDI<0x6E, MRMSrcReg, (outs FR32:$dst), (ins GR32:$src),
2361                       "movd\t{$src, $dst|$dst, $src}",
2362                       [(set FR32:$dst, (bitconvert GR32:$src))]>;
2363
2364 def MOVDI2SSrm  : PDI<0x6E, MRMSrcMem, (outs FR32:$dst), (ins i32mem:$src),
2365                       "movd\t{$src, $dst|$dst, $src}",
2366                       [(set FR32:$dst, (bitconvert (loadi32 addr:$src)))]>;
2367
2368 // SSE2 instructions with XS prefix
2369 def MOVQI2PQIrm : I<0x7E, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
2370                     "movq\t{$src, $dst|$dst, $src}",
2371                     [(set VR128:$dst,
2372                       (v2i64 (scalar_to_vector (loadi64 addr:$src))))]>, XS,
2373                   Requires<[HasSSE2]>;
2374 def MOVPQI2QImr : PDI<0xD6, MRMDestMem, (outs), (ins i64mem:$dst, VR128:$src),
2375                       "movq\t{$src, $dst|$dst, $src}",
2376                       [(store (i64 (vector_extract (v2i64 VR128:$src),
2377                                     (iPTR 0))), addr:$dst)]>;
2378
2379 def : Pat<(f64 (vector_extract (v2f64 VR128:$src), (iPTR 0))),
2380           (f64 (EXTRACT_SUBREG (v2f64 VR128:$src), sub_sd))>;
2381
2382 def MOVPDI2DIrr  : PDI<0x7E, MRMDestReg, (outs GR32:$dst), (ins VR128:$src),
2383                        "movd\t{$src, $dst|$dst, $src}",
2384                        [(set GR32:$dst, (vector_extract (v4i32 VR128:$src),
2385                                         (iPTR 0)))]>;
2386 def MOVPDI2DImr  : PDI<0x7E, MRMDestMem, (outs), (ins i32mem:$dst, VR128:$src),
2387                        "movd\t{$src, $dst|$dst, $src}",
2388                        [(store (i32 (vector_extract (v4i32 VR128:$src),
2389                                      (iPTR 0))), addr:$dst)]>;
2390
2391 def MOVSS2DIrr  : PDI<0x7E, MRMDestReg, (outs GR32:$dst), (ins FR32:$src),
2392                       "movd\t{$src, $dst|$dst, $src}",
2393                       [(set GR32:$dst, (bitconvert FR32:$src))]>;
2394 def MOVSS2DImr  : PDI<0x7E, MRMDestMem, (outs), (ins i32mem:$dst, FR32:$src),
2395                       "movd\t{$src, $dst|$dst, $src}",
2396                       [(store (i32 (bitconvert FR32:$src)), addr:$dst)]>;
2397
2398 // Store / copy lower 64-bits of a XMM register.
2399 def MOVLQ128mr : PDI<0xD6, MRMDestMem, (outs), (ins i64mem:$dst, VR128:$src),
2400                      "movq\t{$src, $dst|$dst, $src}",
2401                      [(int_x86_sse2_storel_dq addr:$dst, VR128:$src)]>;
2402
2403 // movd / movq to XMM register zero-extends
2404 let AddedComplexity = 15 in {
2405 def MOVZDI2PDIrr : PDI<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR32:$src),
2406                        "movd\t{$src, $dst|$dst, $src}",
2407                        [(set VR128:$dst, (v4i32 (X86vzmovl
2408                                       (v4i32 (scalar_to_vector GR32:$src)))))]>;
2409 // This is X86-64 only.
2410 def MOVZQI2PQIrr : RPDI<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR64:$src),
2411                        "mov{d|q}\t{$src, $dst|$dst, $src}",
2412                        [(set VR128:$dst, (v2i64 (X86vzmovl
2413                                       (v2i64 (scalar_to_vector GR64:$src)))))]>;
2414 }
2415
2416 let AddedComplexity = 20 in {
2417 def MOVZDI2PDIrm : PDI<0x6E, MRMSrcMem, (outs VR128:$dst), (ins i32mem:$src),
2418                        "movd\t{$src, $dst|$dst, $src}",
2419                        [(set VR128:$dst,
2420                          (v4i32 (X86vzmovl (v4i32 (scalar_to_vector
2421                                                    (loadi32 addr:$src))))))]>;
2422
2423 def : Pat<(v4i32 (X86vzmovl (loadv4i32 addr:$src))),
2424             (MOVZDI2PDIrm addr:$src)>;
2425 def : Pat<(v4i32 (X86vzmovl (bc_v4i32 (loadv4f32 addr:$src)))),
2426             (MOVZDI2PDIrm addr:$src)>;
2427 def : Pat<(v4i32 (X86vzmovl (bc_v4i32 (loadv2i64 addr:$src)))),
2428             (MOVZDI2PDIrm addr:$src)>;
2429
2430 def MOVZQI2PQIrm : I<0x7E, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
2431                      "movq\t{$src, $dst|$dst, $src}",
2432                      [(set VR128:$dst,
2433                        (v2i64 (X86vzmovl (v2i64 (scalar_to_vector
2434                                                  (loadi64 addr:$src))))))]>, XS,
2435                    Requires<[HasSSE2]>;
2436
2437 def : Pat<(v2i64 (X86vzmovl (loadv2i64 addr:$src))),
2438             (MOVZQI2PQIrm addr:$src)>;
2439 def : Pat<(v2i64 (X86vzmovl (bc_v2i64 (loadv4f32 addr:$src)))),
2440             (MOVZQI2PQIrm addr:$src)>;
2441 def : Pat<(v2i64 (X86vzload addr:$src)), (MOVZQI2PQIrm addr:$src)>;
2442 }
2443
2444 // Moving from XMM to XMM and clear upper 64 bits. Note, there is a bug in
2445 // IA32 document. movq xmm1, xmm2 does clear the high bits.
2446 let AddedComplexity = 15 in
2447 def MOVZPQILo2PQIrr : I<0x7E, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2448                         "movq\t{$src, $dst|$dst, $src}",
2449                     [(set VR128:$dst, (v2i64 (X86vzmovl (v2i64 VR128:$src))))]>,
2450                       XS, Requires<[HasSSE2]>;
2451
2452 let AddedComplexity = 20 in {
2453 def MOVZPQILo2PQIrm : I<0x7E, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
2454                         "movq\t{$src, $dst|$dst, $src}",
2455                     [(set VR128:$dst, (v2i64 (X86vzmovl
2456                                              (loadv2i64 addr:$src))))]>,
2457                       XS, Requires<[HasSSE2]>;
2458
2459 def : Pat<(v2i64 (X86vzmovl (bc_v2i64 (loadv4i32 addr:$src)))),
2460             (MOVZPQILo2PQIrm addr:$src)>;
2461 }
2462
2463 // Instructions for the disassembler
2464 // xr = XMM register
2465 // xm = mem64
2466
2467 def MOVQxrxr : I<0x7E, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2468                  "movq\t{$src, $dst|$dst, $src}", []>, XS;
2469
2470 //===---------------------------------------------------------------------===//
2471 // SSE3 Instructions
2472 //===---------------------------------------------------------------------===//
2473
2474 // Conversion Instructions
2475 def CVTPD2DQrm  : S3DI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
2476                        "cvtpd2dq\t{$src, $dst|$dst, $src}", []>;
2477 def CVTPD2DQrr  : S3DI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2478                        "cvtpd2dq\t{$src, $dst|$dst, $src}", []>;
2479 def CVTDQ2PDrm  : S3SI<0xE6, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
2480                        "cvtdq2pd\t{$src, $dst|$dst, $src}", []>;
2481 def CVTDQ2PDrr  : S3SI<0xE6, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2482                        "cvtdq2pd\t{$src, $dst|$dst, $src}", []>;
2483
2484 // Move Instructions
2485 def MOVSHDUPrr : S3SI<0x16, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2486                       "movshdup\t{$src, $dst|$dst, $src}",
2487                       [(set VR128:$dst, (v4f32 (movshdup
2488                                                 VR128:$src, (undef))))]>;
2489 def MOVSHDUPrm : S3SI<0x16, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
2490                       "movshdup\t{$src, $dst|$dst, $src}",
2491                       [(set VR128:$dst, (movshdup
2492                                          (memopv4f32 addr:$src), (undef)))]>;
2493
2494 def MOVSLDUPrr : S3SI<0x12, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2495                       "movsldup\t{$src, $dst|$dst, $src}",
2496                       [(set VR128:$dst, (v4f32 (movsldup
2497                                                 VR128:$src, (undef))))]>;
2498 def MOVSLDUPrm : S3SI<0x12, MRMSrcMem, (outs VR128:$dst), (ins f128mem:$src),
2499                       "movsldup\t{$src, $dst|$dst, $src}",
2500                       [(set VR128:$dst, (movsldup
2501                                          (memopv4f32 addr:$src), (undef)))]>;
2502
2503 def MOVDDUPrr  : S3DI<0x12, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
2504                       "movddup\t{$src, $dst|$dst, $src}",
2505                       [(set VR128:$dst,(v2f64 (movddup VR128:$src, (undef))))]>;
2506 def MOVDDUPrm  : S3DI<0x12, MRMSrcMem, (outs VR128:$dst), (ins f64mem:$src),
2507                       "movddup\t{$src, $dst|$dst, $src}",
2508                     [(set VR128:$dst,
2509                       (v2f64 (movddup (scalar_to_vector (loadf64 addr:$src)),
2510                                       (undef))))]>;
2511
2512 def : Pat<(movddup (bc_v2f64 (v2i64 (scalar_to_vector (loadi64 addr:$src)))),
2513                    (undef)),
2514           (MOVDDUPrm addr:$src)>, Requires<[HasSSE3]>;
2515
2516 let AddedComplexity = 5 in {
2517 def : Pat<(movddup (memopv2f64 addr:$src), (undef)),
2518           (MOVDDUPrm addr:$src)>, Requires<[HasSSE3]>;
2519 def : Pat<(movddup (bc_v4f32 (memopv2f64 addr:$src)), (undef)),
2520           (MOVDDUPrm addr:$src)>, Requires<[HasSSE3]>;
2521 def : Pat<(movddup (memopv2i64 addr:$src), (undef)),
2522           (MOVDDUPrm addr:$src)>, Requires<[HasSSE3]>;
2523 def : Pat<(movddup (bc_v4i32 (memopv2i64 addr:$src)), (undef)),
2524           (MOVDDUPrm addr:$src)>, Requires<[HasSSE3]>;
2525 }
2526
2527 // Arithmetic
2528 let Constraints = "$src1 = $dst" in {
2529   def ADDSUBPSrr : S3DI<0xD0, MRMSrcReg,
2530                         (outs VR128:$dst), (ins VR128:$src1, VR128:$src2),
2531                         "addsubps\t{$src2, $dst|$dst, $src2}",
2532                         [(set VR128:$dst, (int_x86_sse3_addsub_ps VR128:$src1,
2533                                            VR128:$src2))]>;
2534   def ADDSUBPSrm : S3DI<0xD0, MRMSrcMem,
2535                         (outs VR128:$dst), (ins VR128:$src1, f128mem:$src2),
2536                         "addsubps\t{$src2, $dst|$dst, $src2}",
2537                         [(set VR128:$dst, (int_x86_sse3_addsub_ps VR128:$src1,
2538                                            (memop addr:$src2)))]>;
2539   def ADDSUBPDrr : S3I<0xD0, MRMSrcReg,
2540                        (outs VR128:$dst), (ins VR128:$src1, VR128:$src2),
2541                        "addsubpd\t{$src2, $dst|$dst, $src2}",
2542                        [(set VR128:$dst, (int_x86_sse3_addsub_pd VR128:$src1,
2543                                           VR128:$src2))]>;
2544   def ADDSUBPDrm : S3I<0xD0, MRMSrcMem,
2545                        (outs VR128:$dst), (ins VR128:$src1, f128mem:$src2),
2546                        "addsubpd\t{$src2, $dst|$dst, $src2}",
2547                        [(set VR128:$dst, (int_x86_sse3_addsub_pd VR128:$src1,
2548                                           (memop addr:$src2)))]>;
2549 }
2550
2551 def LDDQUrm : S3DI<0xF0, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
2552                    "lddqu\t{$src, $dst|$dst, $src}",
2553                    [(set VR128:$dst, (int_x86_sse3_ldu_dq addr:$src))]>;
2554
2555 // Horizontal ops
2556 class S3D_Intrr<bits<8> o, string OpcodeStr, Intrinsic IntId>
2557   : S3DI<o, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src1, VR128:$src2),
2558          !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
2559          [(set VR128:$dst, (v4f32 (IntId VR128:$src1, VR128:$src2)))]>;
2560 class S3D_Intrm<bits<8> o, string OpcodeStr, Intrinsic IntId>
2561   : S3DI<o, MRMSrcMem, (outs VR128:$dst), (ins VR128:$src1, f128mem:$src2),
2562          !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
2563          [(set VR128:$dst, (v4f32 (IntId VR128:$src1, (memop addr:$src2))))]>;
2564 class S3_Intrr<bits<8> o, string OpcodeStr, Intrinsic IntId>
2565   : S3I<o, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src1, VR128:$src2),
2566         !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
2567         [(set VR128:$dst, (v2f64 (IntId VR128:$src1, VR128:$src2)))]>;
2568 class S3_Intrm<bits<8> o, string OpcodeStr, Intrinsic IntId>
2569   : S3I<o, MRMSrcMem, (outs VR128:$dst), (ins VR128:$src1, f128mem:$src2),
2570         !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
2571       [(set VR128:$dst, (v2f64 (IntId VR128:$src1, (memopv2f64 addr:$src2))))]>;
2572
2573 let Constraints = "$src1 = $dst" in {
2574   def HADDPSrr : S3D_Intrr<0x7C, "haddps", int_x86_sse3_hadd_ps>;
2575   def HADDPSrm : S3D_Intrm<0x7C, "haddps", int_x86_sse3_hadd_ps>;
2576   def HADDPDrr : S3_Intrr <0x7C, "haddpd", int_x86_sse3_hadd_pd>;
2577   def HADDPDrm : S3_Intrm <0x7C, "haddpd", int_x86_sse3_hadd_pd>;
2578   def HSUBPSrr : S3D_Intrr<0x7D, "hsubps", int_x86_sse3_hsub_ps>;
2579   def HSUBPSrm : S3D_Intrm<0x7D, "hsubps", int_x86_sse3_hsub_ps>;
2580   def HSUBPDrr : S3_Intrr <0x7D, "hsubpd", int_x86_sse3_hsub_pd>;
2581   def HSUBPDrm : S3_Intrm <0x7D, "hsubpd", int_x86_sse3_hsub_pd>;
2582 }
2583
2584 // Thread synchronization
2585 def MONITOR : I<0x01, MRM_C8, (outs), (ins), "monitor",
2586                 [(int_x86_sse3_monitor EAX, ECX, EDX)]>,TB, Requires<[HasSSE3]>;
2587 def MWAIT   : I<0x01, MRM_C9, (outs), (ins), "mwait",
2588                 [(int_x86_sse3_mwait ECX, EAX)]>, TB, Requires<[HasSSE3]>;
2589
2590 // vector_shuffle v1, <undef> <1, 1, 3, 3>
2591 let AddedComplexity = 15 in
2592 def : Pat<(v4i32 (movshdup VR128:$src, (undef))),
2593           (MOVSHDUPrr VR128:$src)>, Requires<[HasSSE3]>;
2594 let AddedComplexity = 20 in
2595 def : Pat<(v4i32 (movshdup (bc_v4i32 (memopv2i64 addr:$src)), (undef))),
2596           (MOVSHDUPrm addr:$src)>, Requires<[HasSSE3]>;
2597
2598 // vector_shuffle v1, <undef> <0, 0, 2, 2>
2599 let AddedComplexity = 15 in
2600   def : Pat<(v4i32 (movsldup VR128:$src, (undef))),
2601             (MOVSLDUPrr VR128:$src)>, Requires<[HasSSE3]>;
2602 let AddedComplexity = 20 in
2603   def : Pat<(v4i32 (movsldup (bc_v4i32 (memopv2i64 addr:$src)), (undef))),
2604             (MOVSLDUPrm addr:$src)>, Requires<[HasSSE3]>;
2605
2606 //===---------------------------------------------------------------------===//
2607 // SSSE3 Instructions
2608 //===---------------------------------------------------------------------===//
2609
2610 /// SS3I_unop_rm_int_8 - Simple SSSE3 unary operator whose type is v*i8.
2611 multiclass SS3I_unop_rm_int_8<bits<8> opc, string OpcodeStr,
2612                               Intrinsic IntId64, Intrinsic IntId128> {
2613   def rr64 : SS38I<opc, MRMSrcReg, (outs VR64:$dst), (ins VR64:$src),
2614                    !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
2615                    [(set VR64:$dst, (IntId64 VR64:$src))]>;
2616
2617   def rm64 : SS38I<opc, MRMSrcMem, (outs VR64:$dst), (ins i64mem:$src),
2618                    !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
2619                    [(set VR64:$dst,
2620                      (IntId64 (bitconvert (memopv8i8 addr:$src))))]>;
2621
2622   def rr128 : SS38I<opc, MRMSrcReg, (outs VR128:$dst),
2623                     (ins VR128:$src),
2624                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
2625                     [(set VR128:$dst, (IntId128 VR128:$src))]>,
2626                     OpSize;
2627
2628   def rm128 : SS38I<opc, MRMSrcMem, (outs VR128:$dst),
2629                     (ins i128mem:$src),
2630                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
2631                     [(set VR128:$dst,
2632                       (IntId128
2633                        (bitconvert (memopv16i8 addr:$src))))]>, OpSize;
2634 }
2635
2636 /// SS3I_unop_rm_int_16 - Simple SSSE3 unary operator whose type is v*i16.
2637 multiclass SS3I_unop_rm_int_16<bits<8> opc, string OpcodeStr,
2638                                Intrinsic IntId64, Intrinsic IntId128> {
2639   def rr64 : SS38I<opc, MRMSrcReg, (outs VR64:$dst),
2640                    (ins VR64:$src),
2641                    !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
2642                    [(set VR64:$dst, (IntId64 VR64:$src))]>;
2643
2644   def rm64 : SS38I<opc, MRMSrcMem, (outs VR64:$dst),
2645                    (ins i64mem:$src),
2646                    !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
2647                    [(set VR64:$dst,
2648                      (IntId64
2649                       (bitconvert (memopv4i16 addr:$src))))]>;
2650
2651   def rr128 : SS38I<opc, MRMSrcReg, (outs VR128:$dst),
2652                     (ins VR128:$src),
2653                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
2654                     [(set VR128:$dst, (IntId128 VR128:$src))]>,
2655                     OpSize;
2656
2657   def rm128 : SS38I<opc, MRMSrcMem, (outs VR128:$dst),
2658                     (ins i128mem:$src),
2659                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
2660                     [(set VR128:$dst,
2661                       (IntId128
2662                        (bitconvert (memopv8i16 addr:$src))))]>, OpSize;
2663 }
2664
2665 /// SS3I_unop_rm_int_32 - Simple SSSE3 unary operator whose type is v*i32.
2666 multiclass SS3I_unop_rm_int_32<bits<8> opc, string OpcodeStr,
2667                                Intrinsic IntId64, Intrinsic IntId128> {
2668   def rr64 : SS38I<opc, MRMSrcReg, (outs VR64:$dst),
2669                    (ins VR64:$src),
2670                    !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
2671                    [(set VR64:$dst, (IntId64 VR64:$src))]>;
2672
2673   def rm64 : SS38I<opc, MRMSrcMem, (outs VR64:$dst),
2674                    (ins i64mem:$src),
2675                    !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
2676                    [(set VR64:$dst,
2677                      (IntId64
2678                       (bitconvert (memopv2i32 addr:$src))))]>;
2679
2680   def rr128 : SS38I<opc, MRMSrcReg, (outs VR128:$dst),
2681                     (ins VR128:$src),
2682                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
2683                     [(set VR128:$dst, (IntId128 VR128:$src))]>,
2684                     OpSize;
2685
2686   def rm128 : SS38I<opc, MRMSrcMem, (outs VR128:$dst),
2687                     (ins i128mem:$src),
2688                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
2689                     [(set VR128:$dst,
2690                       (IntId128
2691                        (bitconvert (memopv4i32 addr:$src))))]>, OpSize;
2692 }
2693
2694 defm PABSB       : SS3I_unop_rm_int_8 <0x1C, "pabsb",
2695                                        int_x86_ssse3_pabs_b,
2696                                        int_x86_ssse3_pabs_b_128>;
2697 defm PABSW       : SS3I_unop_rm_int_16<0x1D, "pabsw",
2698                                        int_x86_ssse3_pabs_w,
2699                                        int_x86_ssse3_pabs_w_128>;
2700 defm PABSD       : SS3I_unop_rm_int_32<0x1E, "pabsd",
2701                                        int_x86_ssse3_pabs_d,
2702                                        int_x86_ssse3_pabs_d_128>;
2703
2704 /// SS3I_binop_rm_int_8 - Simple SSSE3 binary operator whose type is v*i8.
2705 let Constraints = "$src1 = $dst" in {
2706   multiclass SS3I_binop_rm_int_8<bits<8> opc, string OpcodeStr,
2707                                  Intrinsic IntId64, Intrinsic IntId128,
2708                                  bit Commutable = 0> {
2709     def rr64 : SS38I<opc, MRMSrcReg, (outs VR64:$dst),
2710                      (ins VR64:$src1, VR64:$src2),
2711                      !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
2712                      [(set VR64:$dst, (IntId64 VR64:$src1, VR64:$src2))]> {
2713       let isCommutable = Commutable;
2714     }
2715     def rm64 : SS38I<opc, MRMSrcMem, (outs VR64:$dst),
2716                      (ins VR64:$src1, i64mem:$src2),
2717                      !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
2718                      [(set VR64:$dst,
2719                        (IntId64 VR64:$src1,
2720                         (bitconvert (memopv8i8 addr:$src2))))]>;
2721
2722     def rr128 : SS38I<opc, MRMSrcReg, (outs VR128:$dst),
2723                       (ins VR128:$src1, VR128:$src2),
2724                       !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
2725                       [(set VR128:$dst, (IntId128 VR128:$src1, VR128:$src2))]>,
2726                       OpSize {
2727       let isCommutable = Commutable;
2728     }
2729     def rm128 : SS38I<opc, MRMSrcMem, (outs VR128:$dst),
2730                       (ins VR128:$src1, i128mem:$src2),
2731                       !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
2732                       [(set VR128:$dst,
2733                         (IntId128 VR128:$src1,
2734                          (bitconvert (memopv16i8 addr:$src2))))]>, OpSize;
2735   }
2736 }
2737
2738 /// SS3I_binop_rm_int_16 - Simple SSSE3 binary operator whose type is v*i16.
2739 let Constraints = "$src1 = $dst" in {
2740   multiclass SS3I_binop_rm_int_16<bits<8> opc, string OpcodeStr,
2741                                   Intrinsic IntId64, Intrinsic IntId128,
2742                                   bit Commutable = 0> {
2743     def rr64 : SS38I<opc, MRMSrcReg, (outs VR64:$dst),
2744                      (ins VR64:$src1, VR64:$src2),
2745                      !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
2746                      [(set VR64:$dst, (IntId64 VR64:$src1, VR64:$src2))]> {
2747       let isCommutable = Commutable;
2748     }
2749     def rm64 : SS38I<opc, MRMSrcMem, (outs VR64:$dst),
2750                      (ins VR64:$src1, i64mem:$src2),
2751                      !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
2752                      [(set VR64:$dst,
2753                        (IntId64 VR64:$src1,
2754                         (bitconvert (memopv4i16 addr:$src2))))]>;
2755
2756     def rr128 : SS38I<opc, MRMSrcReg, (outs VR128:$dst),
2757                       (ins VR128:$src1, VR128:$src2),
2758                       !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
2759                       [(set VR128:$dst, (IntId128 VR128:$src1, VR128:$src2))]>,
2760                       OpSize {
2761       let isCommutable = Commutable;
2762     }
2763     def rm128 : SS38I<opc, MRMSrcMem, (outs VR128:$dst),
2764                       (ins VR128:$src1, i128mem:$src2),
2765                       !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
2766                       [(set VR128:$dst,
2767                         (IntId128 VR128:$src1,
2768                          (bitconvert (memopv8i16 addr:$src2))))]>, OpSize;
2769   }
2770 }
2771
2772 /// SS3I_binop_rm_int_32 - Simple SSSE3 binary operator whose type is v*i32.
2773 let Constraints = "$src1 = $dst" in {
2774   multiclass SS3I_binop_rm_int_32<bits<8> opc, string OpcodeStr,
2775                                   Intrinsic IntId64, Intrinsic IntId128,
2776                                   bit Commutable = 0> {
2777     def rr64 : SS38I<opc, MRMSrcReg, (outs VR64:$dst),
2778                      (ins VR64:$src1, VR64:$src2),
2779                      !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
2780                      [(set VR64:$dst, (IntId64 VR64:$src1, VR64:$src2))]> {
2781       let isCommutable = Commutable;
2782     }
2783     def rm64 : SS38I<opc, MRMSrcMem, (outs VR64:$dst),
2784                      (ins VR64:$src1, i64mem:$src2),
2785                      !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
2786                      [(set VR64:$dst,
2787                        (IntId64 VR64:$src1,
2788                         (bitconvert (memopv2i32 addr:$src2))))]>;
2789
2790     def rr128 : SS38I<opc, MRMSrcReg, (outs VR128:$dst),
2791                       (ins VR128:$src1, VR128:$src2),
2792                       !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
2793                       [(set VR128:$dst, (IntId128 VR128:$src1, VR128:$src2))]>,
2794                       OpSize {
2795       let isCommutable = Commutable;
2796     }
2797     def rm128 : SS38I<opc, MRMSrcMem, (outs VR128:$dst),
2798                       (ins VR128:$src1, i128mem:$src2),
2799                       !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
2800                       [(set VR128:$dst,
2801                         (IntId128 VR128:$src1,
2802                          (bitconvert (memopv4i32 addr:$src2))))]>, OpSize;
2803   }
2804 }
2805
2806 let ImmT = NoImm in {  // None of these have i8 immediate fields.
2807 defm PHADDW      : SS3I_binop_rm_int_16<0x01, "phaddw",
2808                                         int_x86_ssse3_phadd_w,
2809                                         int_x86_ssse3_phadd_w_128>;
2810 defm PHADDD      : SS3I_binop_rm_int_32<0x02, "phaddd",
2811                                         int_x86_ssse3_phadd_d,
2812                                         int_x86_ssse3_phadd_d_128>;
2813 defm PHADDSW     : SS3I_binop_rm_int_16<0x03, "phaddsw",
2814                                         int_x86_ssse3_phadd_sw,
2815                                         int_x86_ssse3_phadd_sw_128>;
2816 defm PHSUBW      : SS3I_binop_rm_int_16<0x05, "phsubw",
2817                                         int_x86_ssse3_phsub_w,
2818                                         int_x86_ssse3_phsub_w_128>;
2819 defm PHSUBD      : SS3I_binop_rm_int_32<0x06, "phsubd",
2820                                         int_x86_ssse3_phsub_d,
2821                                         int_x86_ssse3_phsub_d_128>;
2822 defm PHSUBSW     : SS3I_binop_rm_int_16<0x07, "phsubsw",
2823                                         int_x86_ssse3_phsub_sw,
2824                                         int_x86_ssse3_phsub_sw_128>;
2825 defm PMADDUBSW   : SS3I_binop_rm_int_8 <0x04, "pmaddubsw",
2826                                         int_x86_ssse3_pmadd_ub_sw,
2827                                         int_x86_ssse3_pmadd_ub_sw_128>;
2828 defm PMULHRSW    : SS3I_binop_rm_int_16<0x0B, "pmulhrsw",
2829                                         int_x86_ssse3_pmul_hr_sw,
2830                                         int_x86_ssse3_pmul_hr_sw_128, 1>;
2831
2832 defm PSHUFB      : SS3I_binop_rm_int_8 <0x00, "pshufb",
2833                                         int_x86_ssse3_pshuf_b,
2834                                         int_x86_ssse3_pshuf_b_128>;
2835 defm PSIGNB      : SS3I_binop_rm_int_8 <0x08, "psignb",
2836                                         int_x86_ssse3_psign_b,
2837                                         int_x86_ssse3_psign_b_128>;
2838 defm PSIGNW      : SS3I_binop_rm_int_16<0x09, "psignw",
2839                                         int_x86_ssse3_psign_w,
2840                                         int_x86_ssse3_psign_w_128>;
2841 defm PSIGND      : SS3I_binop_rm_int_32<0x0A, "psignd",
2842                                         int_x86_ssse3_psign_d,
2843                                         int_x86_ssse3_psign_d_128>;
2844 }
2845
2846 // palignr patterns.
2847 let Constraints = "$src1 = $dst" in {
2848   def PALIGNR64rr  : SS3AI<0x0F, MRMSrcReg, (outs VR64:$dst),
2849                            (ins VR64:$src1, VR64:$src2, i8imm:$src3),
2850                            "palignr\t{$src3, $src2, $dst|$dst, $src2, $src3}",
2851                            []>;
2852   def PALIGNR64rm  : SS3AI<0x0F, MRMSrcMem, (outs VR64:$dst),
2853                            (ins VR64:$src1, i64mem:$src2, i8imm:$src3),
2854                            "palignr\t{$src3, $src2, $dst|$dst, $src2, $src3}",
2855                            []>;
2856
2857   def PALIGNR128rr : SS3AI<0x0F, MRMSrcReg, (outs VR128:$dst),
2858                            (ins VR128:$src1, VR128:$src2, i8imm:$src3),
2859                            "palignr\t{$src3, $src2, $dst|$dst, $src2, $src3}",
2860                            []>, OpSize;
2861   def PALIGNR128rm : SS3AI<0x0F, MRMSrcMem, (outs VR128:$dst),
2862                            (ins VR128:$src1, i128mem:$src2, i8imm:$src3),
2863                            "palignr\t{$src3, $src2, $dst|$dst, $src2, $src3}",
2864                            []>, OpSize;
2865 }
2866
2867 let AddedComplexity = 5 in {
2868
2869 def : Pat<(v1i64 (palign:$src3 VR64:$src1, VR64:$src2)),
2870           (PALIGNR64rr VR64:$src2, VR64:$src1,
2871                        (SHUFFLE_get_palign_imm VR64:$src3))>,
2872           Requires<[HasSSSE3]>;
2873 def : Pat<(v2i32 (palign:$src3 VR64:$src1, VR64:$src2)),
2874           (PALIGNR64rr VR64:$src2, VR64:$src1,
2875                        (SHUFFLE_get_palign_imm VR64:$src3))>,
2876           Requires<[HasSSSE3]>;
2877 def : Pat<(v2f32 (palign:$src3 VR64:$src1, VR64:$src2)),
2878           (PALIGNR64rr VR64:$src2, VR64:$src1,
2879                        (SHUFFLE_get_palign_imm VR64:$src3))>,
2880           Requires<[HasSSSE3]>;
2881 def : Pat<(v4i16 (palign:$src3 VR64:$src1, VR64:$src2)),
2882           (PALIGNR64rr VR64:$src2, VR64:$src1,
2883                        (SHUFFLE_get_palign_imm VR64:$src3))>,
2884           Requires<[HasSSSE3]>;
2885 def : Pat<(v8i8 (palign:$src3 VR64:$src1, VR64:$src2)),
2886           (PALIGNR64rr VR64:$src2, VR64:$src1,
2887                        (SHUFFLE_get_palign_imm VR64:$src3))>,
2888           Requires<[HasSSSE3]>;
2889
2890 def : Pat<(v4i32 (palign:$src3 VR128:$src1, VR128:$src2)),
2891           (PALIGNR128rr VR128:$src2, VR128:$src1,
2892                         (SHUFFLE_get_palign_imm VR128:$src3))>,
2893       Requires<[HasSSSE3]>;
2894 def : Pat<(v4f32 (palign:$src3 VR128:$src1, VR128:$src2)),
2895           (PALIGNR128rr VR128:$src2, VR128:$src1,
2896                         (SHUFFLE_get_palign_imm VR128:$src3))>,
2897       Requires<[HasSSSE3]>;
2898 def : Pat<(v8i16 (palign:$src3 VR128:$src1, VR128:$src2)),
2899           (PALIGNR128rr VR128:$src2, VR128:$src1,
2900                         (SHUFFLE_get_palign_imm VR128:$src3))>,
2901       Requires<[HasSSSE3]>;
2902 def : Pat<(v16i8 (palign:$src3 VR128:$src1, VR128:$src2)),
2903           (PALIGNR128rr VR128:$src2, VR128:$src1,
2904                         (SHUFFLE_get_palign_imm VR128:$src3))>,
2905       Requires<[HasSSSE3]>;
2906 }
2907
2908 def : Pat<(X86pshufb VR128:$src, VR128:$mask),
2909           (PSHUFBrr128 VR128:$src, VR128:$mask)>, Requires<[HasSSSE3]>;
2910 def : Pat<(X86pshufb VR128:$src, (bc_v16i8 (memopv2i64 addr:$mask))),
2911           (PSHUFBrm128 VR128:$src, addr:$mask)>, Requires<[HasSSSE3]>;
2912
2913 //===---------------------------------------------------------------------===//
2914 // Non-Instruction Patterns
2915 //===---------------------------------------------------------------------===//
2916
2917 // extload f32 -> f64.  This matches load+fextend because we have a hack in
2918 // the isel (PreprocessForFPConvert) that can introduce loads after dag
2919 // combine.
2920 // Since these loads aren't folded into the fextend, we have to match it
2921 // explicitly here.
2922 let Predicates = [HasSSE2] in
2923  def : Pat<(fextend (loadf32 addr:$src)),
2924            (CVTSS2SDrm addr:$src)>;
2925
2926 // bit_convert
2927 let Predicates = [HasSSE2] in {
2928   def : Pat<(v2i64 (bitconvert (v4i32 VR128:$src))), (v2i64 VR128:$src)>;
2929   def : Pat<(v2i64 (bitconvert (v8i16 VR128:$src))), (v2i64 VR128:$src)>;
2930   def : Pat<(v2i64 (bitconvert (v16i8 VR128:$src))), (v2i64 VR128:$src)>;
2931   def : Pat<(v2i64 (bitconvert (v2f64 VR128:$src))), (v2i64 VR128:$src)>;
2932   def : Pat<(v2i64 (bitconvert (v4f32 VR128:$src))), (v2i64 VR128:$src)>;
2933   def : Pat<(v4i32 (bitconvert (v2i64 VR128:$src))), (v4i32 VR128:$src)>;
2934   def : Pat<(v4i32 (bitconvert (v8i16 VR128:$src))), (v4i32 VR128:$src)>;
2935   def : Pat<(v4i32 (bitconvert (v16i8 VR128:$src))), (v4i32 VR128:$src)>;
2936   def : Pat<(v4i32 (bitconvert (v2f64 VR128:$src))), (v4i32 VR128:$src)>;
2937   def : Pat<(v4i32 (bitconvert (v4f32 VR128:$src))), (v4i32 VR128:$src)>;
2938   def : Pat<(v8i16 (bitconvert (v2i64 VR128:$src))), (v8i16 VR128:$src)>;
2939   def : Pat<(v8i16 (bitconvert (v4i32 VR128:$src))), (v8i16 VR128:$src)>;
2940   def : Pat<(v8i16 (bitconvert (v16i8 VR128:$src))), (v8i16 VR128:$src)>;
2941   def : Pat<(v8i16 (bitconvert (v2f64 VR128:$src))), (v8i16 VR128:$src)>;
2942   def : Pat<(v8i16 (bitconvert (v4f32 VR128:$src))), (v8i16 VR128:$src)>;
2943   def : Pat<(v16i8 (bitconvert (v2i64 VR128:$src))), (v16i8 VR128:$src)>;
2944   def : Pat<(v16i8 (bitconvert (v4i32 VR128:$src))), (v16i8 VR128:$src)>;
2945   def : Pat<(v16i8 (bitconvert (v8i16 VR128:$src))), (v16i8 VR128:$src)>;
2946   def : Pat<(v16i8 (bitconvert (v2f64 VR128:$src))), (v16i8 VR128:$src)>;
2947   def : Pat<(v16i8 (bitconvert (v4f32 VR128:$src))), (v16i8 VR128:$src)>;
2948   def : Pat<(v4f32 (bitconvert (v2i64 VR128:$src))), (v4f32 VR128:$src)>;
2949   def : Pat<(v4f32 (bitconvert (v4i32 VR128:$src))), (v4f32 VR128:$src)>;
2950   def : Pat<(v4f32 (bitconvert (v8i16 VR128:$src))), (v4f32 VR128:$src)>;
2951   def : Pat<(v4f32 (bitconvert (v16i8 VR128:$src))), (v4f32 VR128:$src)>;
2952   def : Pat<(v4f32 (bitconvert (v2f64 VR128:$src))), (v4f32 VR128:$src)>;
2953   def : Pat<(v2f64 (bitconvert (v2i64 VR128:$src))), (v2f64 VR128:$src)>;
2954   def : Pat<(v2f64 (bitconvert (v4i32 VR128:$src))), (v2f64 VR128:$src)>;
2955   def : Pat<(v2f64 (bitconvert (v8i16 VR128:$src))), (v2f64 VR128:$src)>;
2956   def : Pat<(v2f64 (bitconvert (v16i8 VR128:$src))), (v2f64 VR128:$src)>;
2957   def : Pat<(v2f64 (bitconvert (v4f32 VR128:$src))), (v2f64 VR128:$src)>;
2958 }
2959
2960 // Move scalar to XMM zero-extended
2961 // movd to XMM register zero-extends
2962 let AddedComplexity = 15 in {
2963 // Zeroing a VR128 then do a MOVS{S|D} to the lower bits.
2964 def : Pat<(v2f64 (X86vzmovl (v2f64 (scalar_to_vector FR64:$src)))),
2965           (MOVSDrr (v2f64 (V_SET0PS)), FR64:$src)>;
2966 def : Pat<(v4f32 (X86vzmovl (v4f32 (scalar_to_vector FR32:$src)))),
2967           (MOVSSrr (v4f32 (V_SET0PS)), FR32:$src)>;
2968 def : Pat<(v4f32 (X86vzmovl (v4f32 VR128:$src))),
2969           (MOVSSrr (v4f32 (V_SET0PS)),
2970                    (f32 (EXTRACT_SUBREG (v4f32 VR128:$src), sub_ss)))>;
2971 def : Pat<(v4i32 (X86vzmovl (v4i32 VR128:$src))),
2972           (MOVSSrr (v4i32 (V_SET0PI)),
2973                    (EXTRACT_SUBREG (v4i32 VR128:$src), sub_ss))>;
2974 }
2975
2976 // Splat v2f64 / v2i64
2977 let AddedComplexity = 10 in {
2978 def : Pat<(splat_lo (v2f64 VR128:$src), (undef)),
2979           (UNPCKLPDrr VR128:$src, VR128:$src)>,   Requires<[HasSSE2]>;
2980 def : Pat<(unpckh (v2f64 VR128:$src), (undef)),
2981           (UNPCKHPDrr VR128:$src, VR128:$src)>,   Requires<[HasSSE2]>;
2982 def : Pat<(splat_lo (v2i64 VR128:$src), (undef)),
2983           (PUNPCKLQDQrr VR128:$src, VR128:$src)>, Requires<[HasSSE2]>;
2984 def : Pat<(unpckh (v2i64 VR128:$src), (undef)),
2985           (PUNPCKHQDQrr VR128:$src, VR128:$src)>, Requires<[HasSSE2]>;
2986 }
2987
2988 // Special unary SHUFPSrri case.
2989 def : Pat<(v4f32 (pshufd:$src3 VR128:$src1, (undef))),
2990           (SHUFPSrri VR128:$src1, VR128:$src1,
2991                      (SHUFFLE_get_shuf_imm VR128:$src3))>;
2992 let AddedComplexity = 5 in
2993 def : Pat<(v4f32 (pshufd:$src2 VR128:$src1, (undef))),
2994           (PSHUFDri VR128:$src1, (SHUFFLE_get_shuf_imm VR128:$src2))>,
2995       Requires<[HasSSE2]>;
2996 // Special unary SHUFPDrri case.
2997 def : Pat<(v2i64 (pshufd:$src3 VR128:$src1, (undef))),
2998           (SHUFPDrri VR128:$src1, VR128:$src1,
2999                      (SHUFFLE_get_shuf_imm VR128:$src3))>,
3000       Requires<[HasSSE2]>;
3001 // Special unary SHUFPDrri case.
3002 def : Pat<(v2f64 (pshufd:$src3 VR128:$src1, (undef))),
3003           (SHUFPDrri VR128:$src1, VR128:$src1,
3004                      (SHUFFLE_get_shuf_imm VR128:$src3))>,
3005       Requires<[HasSSE2]>;
3006 // Unary v4f32 shuffle with PSHUF* in order to fold a load.
3007 def : Pat<(pshufd:$src2 (bc_v4i32 (memopv4f32 addr:$src1)), (undef)),
3008           (PSHUFDmi addr:$src1, (SHUFFLE_get_shuf_imm VR128:$src2))>,
3009       Requires<[HasSSE2]>;
3010
3011 // Special binary v4i32 shuffle cases with SHUFPS.
3012 def : Pat<(v4i32 (shufp:$src3 VR128:$src1, (v4i32 VR128:$src2))),
3013           (SHUFPSrri VR128:$src1, VR128:$src2,
3014                      (SHUFFLE_get_shuf_imm VR128:$src3))>,
3015            Requires<[HasSSE2]>;
3016 def : Pat<(v4i32 (shufp:$src3 VR128:$src1, (bc_v4i32 (memopv2i64 addr:$src2)))),
3017           (SHUFPSrmi VR128:$src1, addr:$src2,
3018                     (SHUFFLE_get_shuf_imm VR128:$src3))>,
3019            Requires<[HasSSE2]>;
3020 // Special binary v2i64 shuffle cases using SHUFPDrri.
3021 def : Pat<(v2i64 (shufp:$src3 VR128:$src1, VR128:$src2)),
3022           (SHUFPDrri VR128:$src1, VR128:$src2,
3023                      (SHUFFLE_get_shuf_imm VR128:$src3))>,
3024           Requires<[HasSSE2]>;
3025
3026 // vector_shuffle v1, <undef>, <0, 0, 1, 1, ...>
3027 let AddedComplexity = 15 in {
3028 def : Pat<(v4i32 (unpckl_undef:$src2 VR128:$src, (undef))),
3029           (PSHUFDri VR128:$src, (SHUFFLE_get_shuf_imm VR128:$src2))>,
3030           Requires<[OptForSpeed, HasSSE2]>;
3031 def : Pat<(v4f32 (unpckl_undef:$src2 VR128:$src, (undef))),
3032           (PSHUFDri VR128:$src, (SHUFFLE_get_shuf_imm VR128:$src2))>,
3033           Requires<[OptForSpeed, HasSSE2]>;
3034 }
3035 let AddedComplexity = 10 in {
3036 def : Pat<(v4f32 (unpckl_undef VR128:$src, (undef))),
3037           (UNPCKLPSrr VR128:$src, VR128:$src)>;
3038 def : Pat<(v16i8 (unpckl_undef VR128:$src, (undef))),
3039           (PUNPCKLBWrr VR128:$src, VR128:$src)>;
3040 def : Pat<(v8i16 (unpckl_undef VR128:$src, (undef))),
3041           (PUNPCKLWDrr VR128:$src, VR128:$src)>;
3042 def : Pat<(v4i32 (unpckl_undef VR128:$src, (undef))),
3043           (PUNPCKLDQrr VR128:$src, VR128:$src)>;
3044 }
3045
3046 // vector_shuffle v1, <undef>, <2, 2, 3, 3, ...>
3047 let AddedComplexity = 15 in {
3048 def : Pat<(v4i32 (unpckh_undef:$src2 VR128:$src, (undef))),
3049           (PSHUFDri VR128:$src, (SHUFFLE_get_shuf_imm VR128:$src2))>,
3050           Requires<[OptForSpeed, HasSSE2]>;
3051 def : Pat<(v4f32 (unpckh_undef:$src2 VR128:$src, (undef))),
3052           (PSHUFDri VR128:$src, (SHUFFLE_get_shuf_imm VR128:$src2))>,
3053           Requires<[OptForSpeed, HasSSE2]>;
3054 }
3055 let AddedComplexity = 10 in {
3056 def : Pat<(v4f32 (unpckh_undef VR128:$src, (undef))),
3057           (UNPCKHPSrr VR128:$src, VR128:$src)>;
3058 def : Pat<(v16i8 (unpckh_undef VR128:$src, (undef))),
3059           (PUNPCKHBWrr VR128:$src, VR128:$src)>;
3060 def : Pat<(v8i16 (unpckh_undef VR128:$src, (undef))),
3061           (PUNPCKHWDrr VR128:$src, VR128:$src)>;
3062 def : Pat<(v4i32 (unpckh_undef VR128:$src, (undef))),
3063           (PUNPCKHDQrr VR128:$src, VR128:$src)>;
3064 }
3065
3066 let AddedComplexity = 20 in {
3067 // vector_shuffle v1, v2 <0, 1, 4, 5> using MOVLHPS
3068 def : Pat<(v4i32 (movlhps VR128:$src1, VR128:$src2)),
3069           (MOVLHPSrr VR128:$src1, VR128:$src2)>;
3070
3071 // vector_shuffle v1, v2 <6, 7, 2, 3> using MOVHLPS
3072 def : Pat<(v4i32 (movhlps VR128:$src1, VR128:$src2)),
3073           (MOVHLPSrr VR128:$src1, VR128:$src2)>;
3074
3075 // vector_shuffle v1, undef <2, ?, ?, ?> using MOVHLPS
3076 def : Pat<(v4f32 (movhlps_undef VR128:$src1, (undef))),
3077           (MOVHLPSrr VR128:$src1, VR128:$src1)>;
3078 def : Pat<(v4i32 (movhlps_undef VR128:$src1, (undef))),
3079           (MOVHLPSrr VR128:$src1, VR128:$src1)>;
3080 }
3081
3082 let AddedComplexity = 20 in {
3083 // vector_shuffle v1, (load v2) <4, 5, 2, 3> using MOVLPS
3084 def : Pat<(v4f32 (movlp VR128:$src1, (load addr:$src2))),
3085           (MOVLPSrm VR128:$src1, addr:$src2)>;
3086 def : Pat<(v2f64 (movlp VR128:$src1, (load addr:$src2))),
3087           (MOVLPDrm VR128:$src1, addr:$src2)>;
3088 def : Pat<(v4i32 (movlp VR128:$src1, (load addr:$src2))),
3089           (MOVLPSrm VR128:$src1, addr:$src2)>;
3090 def : Pat<(v2i64 (movlp VR128:$src1, (load addr:$src2))),
3091           (MOVLPDrm VR128:$src1, addr:$src2)>;
3092 }
3093
3094 // (store (vector_shuffle (load addr), v2, <4, 5, 2, 3>), addr) using MOVLPS
3095 def : Pat<(store (v4f32 (movlp (load addr:$src1), VR128:$src2)), addr:$src1),
3096           (MOVLPSmr addr:$src1, VR128:$src2)>;
3097 def : Pat<(store (v2f64 (movlp (load addr:$src1), VR128:$src2)), addr:$src1),
3098           (MOVLPDmr addr:$src1, VR128:$src2)>;
3099 def : Pat<(store (v4i32 (movlp (bc_v4i32 (loadv2i64 addr:$src1)), VR128:$src2)),
3100                  addr:$src1),
3101           (MOVLPSmr addr:$src1, VR128:$src2)>;
3102 def : Pat<(store (v2i64 (movlp (load addr:$src1), VR128:$src2)), addr:$src1),
3103           (MOVLPDmr addr:$src1, VR128:$src2)>;
3104
3105 let AddedComplexity = 15 in {
3106 // Setting the lowest element in the vector.
3107 def : Pat<(v4i32 (movl VR128:$src1, VR128:$src2)),
3108           (MOVSSrr (v4i32 VR128:$src1),
3109                    (EXTRACT_SUBREG (v4i32 VR128:$src2), sub_ss))>;
3110 def : Pat<(v2i64 (movl VR128:$src1, VR128:$src2)),
3111           (MOVSDrr (v2i64 VR128:$src1),
3112                    (EXTRACT_SUBREG (v2i64 VR128:$src2), sub_sd))>;
3113
3114 // vector_shuffle v1, v2 <4, 5, 2, 3> using movsd
3115 def : Pat<(v4f32 (movlp VR128:$src1, VR128:$src2)),
3116           (MOVSDrr VR128:$src1, (EXTRACT_SUBREG VR128:$src2, sub_sd))>,
3117       Requires<[HasSSE2]>;
3118 def : Pat<(v4i32 (movlp VR128:$src1, VR128:$src2)),
3119           (MOVSDrr VR128:$src1, (EXTRACT_SUBREG VR128:$src2, sub_sd))>,
3120       Requires<[HasSSE2]>;
3121 }
3122
3123 // vector_shuffle v1, v2 <4, 5, 2, 3> using SHUFPSrri (we prefer movsd, but
3124 // fall back to this for SSE1)
3125 def : Pat<(v4f32 (movlp:$src3 VR128:$src1, (v4f32 VR128:$src2))),
3126           (SHUFPSrri VR128:$src2, VR128:$src1,
3127                      (SHUFFLE_get_shuf_imm VR128:$src3))>;
3128
3129 // Set lowest element and zero upper elements.
3130 def : Pat<(v2f64 (X86vzmovl (v2f64 VR128:$src))),
3131           (MOVZPQILo2PQIrr VR128:$src)>, Requires<[HasSSE2]>;
3132
3133 // Some special case pandn patterns.
3134 def : Pat<(v2i64 (and (xor VR128:$src1, (bc_v2i64 (v4i32 immAllOnesV))),
3135                   VR128:$src2)),
3136           (PANDNrr VR128:$src1, VR128:$src2)>, Requires<[HasSSE2]>;
3137 def : Pat<(v2i64 (and (xor VR128:$src1, (bc_v2i64 (v8i16 immAllOnesV))),
3138                   VR128:$src2)),
3139           (PANDNrr VR128:$src1, VR128:$src2)>, Requires<[HasSSE2]>;
3140 def : Pat<(v2i64 (and (xor VR128:$src1, (bc_v2i64 (v16i8 immAllOnesV))),
3141                   VR128:$src2)),
3142           (PANDNrr VR128:$src1, VR128:$src2)>, Requires<[HasSSE2]>;
3143
3144 def : Pat<(v2i64 (and (xor VR128:$src1, (bc_v2i64 (v4i32 immAllOnesV))),
3145                   (memop addr:$src2))),
3146           (PANDNrm VR128:$src1, addr:$src2)>, Requires<[HasSSE2]>;
3147 def : Pat<(v2i64 (and (xor VR128:$src1, (bc_v2i64 (v8i16 immAllOnesV))),
3148                   (memop addr:$src2))),
3149           (PANDNrm VR128:$src1, addr:$src2)>, Requires<[HasSSE2]>;
3150 def : Pat<(v2i64 (and (xor VR128:$src1, (bc_v2i64 (v16i8 immAllOnesV))),
3151                   (memop addr:$src2))),
3152           (PANDNrm VR128:$src1, addr:$src2)>, Requires<[HasSSE2]>;
3153
3154 // vector -> vector casts
3155 def : Pat<(v4f32 (sint_to_fp (v4i32 VR128:$src))),
3156           (Int_CVTDQ2PSrr VR128:$src)>, Requires<[HasSSE2]>;
3157 def : Pat<(v4i32 (fp_to_sint (v4f32 VR128:$src))),
3158           (Int_CVTTPS2DQrr VR128:$src)>, Requires<[HasSSE2]>;
3159 def : Pat<(v2f64 (sint_to_fp (v2i32 VR64:$src))),
3160           (Int_CVTPI2PDrr VR64:$src)>, Requires<[HasSSE2]>;
3161 def : Pat<(v2i32 (fp_to_sint (v2f64 VR128:$src))),
3162           (Int_CVTTPD2PIrr VR128:$src)>, Requires<[HasSSE2]>;
3163
3164 // Use movaps / movups for SSE integer load / store (one byte shorter).
3165 def : Pat<(alignedloadv4i32 addr:$src),
3166           (MOVAPSrm addr:$src)>;
3167 def : Pat<(loadv4i32 addr:$src),
3168           (MOVUPSrm addr:$src)>;
3169 def : Pat<(alignedloadv2i64 addr:$src),
3170           (MOVAPSrm addr:$src)>;
3171 def : Pat<(loadv2i64 addr:$src),
3172           (MOVUPSrm addr:$src)>;
3173
3174 def : Pat<(alignedstore (v2i64 VR128:$src), addr:$dst),
3175           (MOVAPSmr addr:$dst, VR128:$src)>;
3176 def : Pat<(alignedstore (v4i32 VR128:$src), addr:$dst),
3177           (MOVAPSmr addr:$dst, VR128:$src)>;
3178 def : Pat<(alignedstore (v8i16 VR128:$src), addr:$dst),
3179           (MOVAPSmr addr:$dst, VR128:$src)>;
3180 def : Pat<(alignedstore (v16i8 VR128:$src), addr:$dst),
3181           (MOVAPSmr addr:$dst, VR128:$src)>;
3182 def : Pat<(store (v2i64 VR128:$src), addr:$dst),
3183           (MOVUPSmr addr:$dst, VR128:$src)>;
3184 def : Pat<(store (v4i32 VR128:$src), addr:$dst),
3185           (MOVUPSmr addr:$dst, VR128:$src)>;
3186 def : Pat<(store (v8i16 VR128:$src), addr:$dst),
3187           (MOVUPSmr addr:$dst, VR128:$src)>;
3188 def : Pat<(store (v16i8 VR128:$src), addr:$dst),
3189           (MOVUPSmr addr:$dst, VR128:$src)>;
3190
3191 //===----------------------------------------------------------------------===//
3192 // SSE4.1 Instructions
3193 //===----------------------------------------------------------------------===//
3194
3195 multiclass sse41_fp_unop_rm<bits<8> opcps, bits<8> opcpd,
3196                             string OpcodeStr,
3197                             Intrinsic V4F32Int,
3198                             Intrinsic V2F64Int> {
3199   // Intrinsic operation, reg.
3200   // Vector intrinsic operation, reg
3201   def PSr_Int : SS4AIi8<opcps, MRMSrcReg,
3202                     (outs VR128:$dst), (ins VR128:$src1, i32i8imm:$src2),
3203                     !strconcat(OpcodeStr,
3204                     "ps\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
3205                     [(set VR128:$dst, (V4F32Int VR128:$src1, imm:$src2))]>,
3206                     OpSize;
3207
3208   // Vector intrinsic operation, mem
3209   def PSm_Int : Ii8<opcps, MRMSrcMem,
3210                     (outs VR128:$dst), (ins f128mem:$src1, i32i8imm:$src2),
3211                     !strconcat(OpcodeStr,
3212                     "ps\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
3213                     [(set VR128:$dst,
3214                           (V4F32Int (memopv4f32 addr:$src1),imm:$src2))]>,
3215                     TA, OpSize,
3216                 Requires<[HasSSE41]>;
3217
3218   // Vector intrinsic operation, reg
3219   def PDr_Int : SS4AIi8<opcpd, MRMSrcReg,
3220                     (outs VR128:$dst), (ins VR128:$src1, i32i8imm:$src2),
3221                     !strconcat(OpcodeStr,
3222                     "pd\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
3223                     [(set VR128:$dst, (V2F64Int VR128:$src1, imm:$src2))]>,
3224                     OpSize;
3225
3226   // Vector intrinsic operation, mem
3227   def PDm_Int : SS4AIi8<opcpd, MRMSrcMem,
3228                     (outs VR128:$dst), (ins f128mem:$src1, i32i8imm:$src2),
3229                     !strconcat(OpcodeStr,
3230                     "pd\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
3231                     [(set VR128:$dst,
3232                           (V2F64Int (memopv2f64 addr:$src1),imm:$src2))]>,
3233                     OpSize;
3234 }
3235
3236 let Constraints = "$src1 = $dst" in {
3237 multiclass sse41_fp_binop_rm<bits<8> opcss, bits<8> opcsd,
3238                             string OpcodeStr,
3239                             Intrinsic F32Int,
3240                             Intrinsic F64Int> {
3241   // Intrinsic operation, reg.
3242   def SSr_Int : SS4AIi8<opcss, MRMSrcReg,
3243                     (outs VR128:$dst),
3244                                  (ins VR128:$src1, VR128:$src2, i32i8imm:$src3),
3245                     !strconcat(OpcodeStr,
3246                     "ss\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
3247                     [(set VR128:$dst,
3248                             (F32Int VR128:$src1, VR128:$src2, imm:$src3))]>,
3249                     OpSize;
3250
3251   // Intrinsic operation, mem.
3252   def SSm_Int : SS4AIi8<opcss, MRMSrcMem,
3253                     (outs VR128:$dst),
3254                                 (ins VR128:$src1, ssmem:$src2, i32i8imm:$src3),
3255                     !strconcat(OpcodeStr,
3256                     "ss\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
3257                     [(set VR128:$dst,
3258                          (F32Int VR128:$src1, sse_load_f32:$src2, imm:$src3))]>,
3259                     OpSize;
3260
3261   // Intrinsic operation, reg.
3262   def SDr_Int : SS4AIi8<opcsd, MRMSrcReg,
3263                     (outs VR128:$dst),
3264                             (ins VR128:$src1, VR128:$src2, i32i8imm:$src3),
3265                     !strconcat(OpcodeStr,
3266                     "sd\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
3267                     [(set VR128:$dst,
3268                             (F64Int VR128:$src1, VR128:$src2, imm:$src3))]>,
3269                     OpSize;
3270
3271   // Intrinsic operation, mem.
3272   def SDm_Int : SS4AIi8<opcsd, MRMSrcMem,
3273                     (outs VR128:$dst),
3274                             (ins VR128:$src1, sdmem:$src2, i32i8imm:$src3),
3275                     !strconcat(OpcodeStr,
3276                     "sd\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
3277                     [(set VR128:$dst,
3278                         (F64Int VR128:$src1, sse_load_f64:$src2, imm:$src3))]>,
3279                     OpSize;
3280 }
3281 }
3282
3283 // FP round - roundss, roundps, roundsd, roundpd
3284 defm ROUND  : sse41_fp_unop_rm<0x08, 0x09, "round",
3285                                int_x86_sse41_round_ps, int_x86_sse41_round_pd>;
3286 defm ROUND  : sse41_fp_binop_rm<0x0A, 0x0B, "round",
3287                                int_x86_sse41_round_ss, int_x86_sse41_round_sd>;
3288
3289 // SS41I_unop_rm_int_v16 - SSE 4.1 unary operator whose type is v8i16.
3290 multiclass SS41I_unop_rm_int_v16<bits<8> opc, string OpcodeStr,
3291                                  Intrinsic IntId128> {
3292   def rr128 : SS48I<opc, MRMSrcReg, (outs VR128:$dst),
3293                     (ins VR128:$src),
3294                     !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
3295                     [(set VR128:$dst, (IntId128 VR128:$src))]>, OpSize;
3296   def rm128 : SS48I<opc, MRMSrcMem, (outs VR128:$dst),
3297                      (ins i128mem:$src),
3298                      !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
3299                      [(set VR128:$dst,
3300                        (IntId128
3301                        (bitconvert (memopv8i16 addr:$src))))]>, OpSize;
3302 }
3303
3304 defm PHMINPOSUW : SS41I_unop_rm_int_v16 <0x41, "phminposuw",
3305                                          int_x86_sse41_phminposuw>;
3306
3307 /// SS41I_binop_rm_int - Simple SSE 4.1 binary operator
3308 let Constraints = "$src1 = $dst" in {
3309   multiclass SS41I_binop_rm_int<bits<8> opc, string OpcodeStr,
3310                                 Intrinsic IntId128, bit Commutable = 0> {
3311     def rr : SS48I<opc, MRMSrcReg, (outs VR128:$dst),
3312                    (ins VR128:$src1, VR128:$src2),
3313                    !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
3314                    [(set VR128:$dst, (IntId128 VR128:$src1, VR128:$src2))]>,
3315                    OpSize {
3316       let isCommutable = Commutable;
3317     }
3318     def rm : SS48I<opc, MRMSrcMem, (outs VR128:$dst),
3319                    (ins VR128:$src1, i128mem:$src2),
3320                    !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
3321                    [(set VR128:$dst,
3322                      (IntId128 VR128:$src1,
3323                       (bitconvert (memopv16i8 addr:$src2))))]>, OpSize;
3324   }
3325 }
3326
3327 defm PCMPEQQ      : SS41I_binop_rm_int<0x29, "pcmpeqq",
3328                                        int_x86_sse41_pcmpeqq, 1>;
3329 defm PACKUSDW     : SS41I_binop_rm_int<0x2B, "packusdw",
3330                                        int_x86_sse41_packusdw, 0>;
3331 defm PMINSB       : SS41I_binop_rm_int<0x38, "pminsb",
3332                                        int_x86_sse41_pminsb, 1>;
3333 defm PMINSD       : SS41I_binop_rm_int<0x39, "pminsd",
3334                                        int_x86_sse41_pminsd, 1>;
3335 defm PMINUD       : SS41I_binop_rm_int<0x3B, "pminud",
3336                                        int_x86_sse41_pminud, 1>;
3337 defm PMINUW       : SS41I_binop_rm_int<0x3A, "pminuw",
3338                                        int_x86_sse41_pminuw, 1>;
3339 defm PMAXSB       : SS41I_binop_rm_int<0x3C, "pmaxsb",
3340                                        int_x86_sse41_pmaxsb, 1>;
3341 defm PMAXSD       : SS41I_binop_rm_int<0x3D, "pmaxsd",
3342                                        int_x86_sse41_pmaxsd, 1>;
3343 defm PMAXUD       : SS41I_binop_rm_int<0x3F, "pmaxud",
3344                                        int_x86_sse41_pmaxud, 1>;
3345 defm PMAXUW       : SS41I_binop_rm_int<0x3E, "pmaxuw",
3346                                        int_x86_sse41_pmaxuw, 1>;
3347
3348 defm PMULDQ       : SS41I_binop_rm_int<0x28, "pmuldq", int_x86_sse41_pmuldq, 1>;
3349
3350 def : Pat<(v2i64 (X86pcmpeqq VR128:$src1, VR128:$src2)),
3351           (PCMPEQQrr VR128:$src1, VR128:$src2)>;
3352 def : Pat<(v2i64 (X86pcmpeqq VR128:$src1, (memop addr:$src2))),
3353           (PCMPEQQrm VR128:$src1, addr:$src2)>;
3354
3355 /// SS41I_binop_rm_int - Simple SSE 4.1 binary operator
3356 let Constraints = "$src1 = $dst" in {
3357   multiclass SS41I_binop_patint<bits<8> opc, string OpcodeStr, ValueType OpVT,
3358                                 SDNode OpNode, Intrinsic IntId128,
3359                                 bit Commutable = 0> {
3360     def rr : SS48I<opc, MRMSrcReg, (outs VR128:$dst),
3361                    (ins VR128:$src1, VR128:$src2),
3362                    !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
3363                    [(set VR128:$dst, (OpNode (OpVT VR128:$src1),
3364                                                    VR128:$src2))]>, OpSize {
3365       let isCommutable = Commutable;
3366     }
3367     def rr_int : SS48I<opc, MRMSrcReg, (outs VR128:$dst),
3368                       (ins VR128:$src1, VR128:$src2),
3369                       !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
3370                       [(set VR128:$dst, (IntId128 VR128:$src1, VR128:$src2))]>,
3371                       OpSize {
3372       let isCommutable = Commutable;
3373     }
3374     def rm : SS48I<opc, MRMSrcMem, (outs VR128:$dst),
3375                    (ins VR128:$src1, i128mem:$src2),
3376                    !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
3377                    [(set VR128:$dst,
3378                      (OpVT (OpNode VR128:$src1, (memop addr:$src2))))]>, OpSize;
3379     def rm_int : SS48I<opc, MRMSrcMem, (outs VR128:$dst),
3380                        (ins VR128:$src1, i128mem:$src2),
3381                        !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
3382                        [(set VR128:$dst,
3383                         (IntId128 VR128:$src1, (memop addr:$src2)))]>,
3384                        OpSize;
3385   }
3386 }
3387
3388 /// SS48I_binop_rm - Simple SSE41 binary operator.
3389 let Constraints = "$src1 = $dst" in {
3390 multiclass SS48I_binop_rm<bits<8> opc, string OpcodeStr, SDNode OpNode,
3391                         ValueType OpVT, bit Commutable = 0> {
3392   def rr : SS48I<opc, MRMSrcReg, (outs VR128:$dst),
3393                                  (ins VR128:$src1, VR128:$src2),
3394                !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
3395                [(set VR128:$dst, (OpVT (OpNode VR128:$src1, VR128:$src2)))]>,
3396                OpSize {
3397     let isCommutable = Commutable;
3398   }
3399   def rm : SS48I<opc, MRMSrcMem, (outs VR128:$dst),
3400                                  (ins VR128:$src1, i128mem:$src2),
3401                !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
3402                [(set VR128:$dst, (OpNode VR128:$src1,
3403                                   (bc_v4i32 (memopv2i64 addr:$src2))))]>,
3404                OpSize;
3405 }
3406 }
3407
3408 defm PMULLD         : SS48I_binop_rm<0x40, "pmulld", mul, v4i32, 1>;
3409
3410 /// SS41I_binop_rmi_int - SSE 4.1 binary operator with 8-bit immediate
3411 let Constraints = "$src1 = $dst" in {
3412   multiclass SS41I_binop_rmi_int<bits<8> opc, string OpcodeStr,
3413                                  Intrinsic IntId128, bit Commutable = 0> {
3414     def rri : SS4AIi8<opc, MRMSrcReg, (outs VR128:$dst),
3415                     (ins VR128:$src1, VR128:$src2, i32i8imm:$src3),
3416                     !strconcat(OpcodeStr,
3417                      "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
3418                     [(set VR128:$dst,
3419                       (IntId128 VR128:$src1, VR128:$src2, imm:$src3))]>,
3420                     OpSize {
3421       let isCommutable = Commutable;
3422     }
3423     def rmi : SS4AIi8<opc, MRMSrcMem, (outs VR128:$dst),
3424                     (ins VR128:$src1, i128mem:$src2, i32i8imm:$src3),
3425                     !strconcat(OpcodeStr,
3426                      "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
3427                     [(set VR128:$dst,
3428                       (IntId128 VR128:$src1,
3429                        (bitconvert (memopv16i8 addr:$src2)), imm:$src3))]>,
3430                     OpSize;
3431   }
3432 }
3433
3434 defm BLENDPS      : SS41I_binop_rmi_int<0x0C, "blendps",
3435                                         int_x86_sse41_blendps, 0>;
3436 defm BLENDPD      : SS41I_binop_rmi_int<0x0D, "blendpd",
3437                                         int_x86_sse41_blendpd, 0>;
3438 defm PBLENDW      : SS41I_binop_rmi_int<0x0E, "pblendw",
3439                                         int_x86_sse41_pblendw, 0>;
3440 defm DPPS         : SS41I_binop_rmi_int<0x40, "dpps",
3441                                         int_x86_sse41_dpps, 1>;
3442 defm DPPD         : SS41I_binop_rmi_int<0x41, "dppd",
3443                                         int_x86_sse41_dppd, 1>;
3444 defm MPSADBW      : SS41I_binop_rmi_int<0x42, "mpsadbw",
3445                                         int_x86_sse41_mpsadbw, 0>;
3446
3447
3448 /// SS41I_ternary_int - SSE 4.1 ternary operator
3449 let Uses = [XMM0], Constraints = "$src1 = $dst" in {
3450   multiclass SS41I_ternary_int<bits<8> opc, string OpcodeStr, Intrinsic IntId> {
3451     def rr0 : SS48I<opc, MRMSrcReg, (outs VR128:$dst),
3452                     (ins VR128:$src1, VR128:$src2),
3453                     !strconcat(OpcodeStr,
3454                      "\t{%xmm0, $src2, $dst|$dst, $src2, %xmm0}"),
3455                     [(set VR128:$dst, (IntId VR128:$src1, VR128:$src2, XMM0))]>,
3456                     OpSize;
3457
3458     def rm0 : SS48I<opc, MRMSrcMem, (outs VR128:$dst),
3459                     (ins VR128:$src1, i128mem:$src2),
3460                     !strconcat(OpcodeStr,
3461                      "\t{%xmm0, $src2, $dst|$dst, $src2, %xmm0}"),
3462                     [(set VR128:$dst,
3463                       (IntId VR128:$src1,
3464                        (bitconvert (memopv16i8 addr:$src2)), XMM0))]>, OpSize;
3465   }
3466 }
3467
3468 defm BLENDVPD     : SS41I_ternary_int<0x15, "blendvpd", int_x86_sse41_blendvpd>;
3469 defm BLENDVPS     : SS41I_ternary_int<0x14, "blendvps", int_x86_sse41_blendvps>;
3470 defm PBLENDVB     : SS41I_ternary_int<0x10, "pblendvb", int_x86_sse41_pblendvb>;
3471
3472
3473 multiclass SS41I_binop_rm_int8<bits<8> opc, string OpcodeStr, Intrinsic IntId> {
3474   def rr : SS48I<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3475                  !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
3476                  [(set VR128:$dst, (IntId VR128:$src))]>, OpSize;
3477
3478   def rm : SS48I<opc, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
3479                  !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
3480        [(set VR128:$dst,
3481          (IntId (bitconvert (v2i64 (scalar_to_vector (loadi64 addr:$src))))))]>,
3482        OpSize;
3483 }
3484
3485 defm PMOVSXBW   : SS41I_binop_rm_int8<0x20, "pmovsxbw", int_x86_sse41_pmovsxbw>;
3486 defm PMOVSXWD   : SS41I_binop_rm_int8<0x23, "pmovsxwd", int_x86_sse41_pmovsxwd>;
3487 defm PMOVSXDQ   : SS41I_binop_rm_int8<0x25, "pmovsxdq", int_x86_sse41_pmovsxdq>;
3488 defm PMOVZXBW   : SS41I_binop_rm_int8<0x30, "pmovzxbw", int_x86_sse41_pmovzxbw>;
3489 defm PMOVZXWD   : SS41I_binop_rm_int8<0x33, "pmovzxwd", int_x86_sse41_pmovzxwd>;
3490 defm PMOVZXDQ   : SS41I_binop_rm_int8<0x35, "pmovzxdq", int_x86_sse41_pmovzxdq>;
3491
3492 // Common patterns involving scalar load.
3493 def : Pat<(int_x86_sse41_pmovsxbw (vzmovl_v2i64 addr:$src)),
3494           (PMOVSXBWrm addr:$src)>, Requires<[HasSSE41]>;
3495 def : Pat<(int_x86_sse41_pmovsxbw (vzload_v2i64 addr:$src)),
3496           (PMOVSXBWrm addr:$src)>, Requires<[HasSSE41]>;
3497
3498 def : Pat<(int_x86_sse41_pmovsxwd (vzmovl_v2i64 addr:$src)),
3499           (PMOVSXWDrm addr:$src)>, Requires<[HasSSE41]>;
3500 def : Pat<(int_x86_sse41_pmovsxwd (vzload_v2i64 addr:$src)),
3501           (PMOVSXWDrm addr:$src)>, Requires<[HasSSE41]>;
3502
3503 def : Pat<(int_x86_sse41_pmovsxdq (vzmovl_v2i64 addr:$src)),
3504           (PMOVSXDQrm addr:$src)>, Requires<[HasSSE41]>;
3505 def : Pat<(int_x86_sse41_pmovsxdq (vzload_v2i64 addr:$src)),
3506           (PMOVSXDQrm addr:$src)>, Requires<[HasSSE41]>;
3507
3508 def : Pat<(int_x86_sse41_pmovzxbw (vzmovl_v2i64 addr:$src)),
3509           (PMOVZXBWrm addr:$src)>, Requires<[HasSSE41]>;
3510 def : Pat<(int_x86_sse41_pmovzxbw (vzload_v2i64 addr:$src)),
3511           (PMOVZXBWrm addr:$src)>, Requires<[HasSSE41]>;
3512
3513 def : Pat<(int_x86_sse41_pmovzxwd (vzmovl_v2i64 addr:$src)),
3514           (PMOVZXWDrm addr:$src)>, Requires<[HasSSE41]>;
3515 def : Pat<(int_x86_sse41_pmovzxwd (vzload_v2i64 addr:$src)),
3516           (PMOVZXWDrm addr:$src)>, Requires<[HasSSE41]>;
3517
3518 def : Pat<(int_x86_sse41_pmovzxdq (vzmovl_v2i64 addr:$src)),
3519           (PMOVZXDQrm addr:$src)>, Requires<[HasSSE41]>;
3520 def : Pat<(int_x86_sse41_pmovzxdq (vzload_v2i64 addr:$src)),
3521           (PMOVZXDQrm addr:$src)>, Requires<[HasSSE41]>;
3522
3523
3524 multiclass SS41I_binop_rm_int4<bits<8> opc, string OpcodeStr, Intrinsic IntId> {
3525   def rr : SS48I<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3526                  !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
3527                  [(set VR128:$dst, (IntId VR128:$src))]>, OpSize;
3528
3529   def rm : SS48I<opc, MRMSrcMem, (outs VR128:$dst), (ins i32mem:$src),
3530                  !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
3531        [(set VR128:$dst,
3532          (IntId (bitconvert (v4i32 (scalar_to_vector (loadi32 addr:$src))))))]>,
3533           OpSize;
3534 }
3535
3536 defm PMOVSXBD   : SS41I_binop_rm_int4<0x21, "pmovsxbd", int_x86_sse41_pmovsxbd>;
3537 defm PMOVSXWQ   : SS41I_binop_rm_int4<0x24, "pmovsxwq", int_x86_sse41_pmovsxwq>;
3538 defm PMOVZXBD   : SS41I_binop_rm_int4<0x31, "pmovzxbd", int_x86_sse41_pmovzxbd>;
3539 defm PMOVZXWQ   : SS41I_binop_rm_int4<0x34, "pmovzxwq", int_x86_sse41_pmovzxwq>;
3540
3541 // Common patterns involving scalar load
3542 def : Pat<(int_x86_sse41_pmovsxbd (vzmovl_v4i32 addr:$src)),
3543           (PMOVSXBDrm addr:$src)>, Requires<[HasSSE41]>;
3544 def : Pat<(int_x86_sse41_pmovsxwq (vzmovl_v4i32 addr:$src)),
3545           (PMOVSXWQrm addr:$src)>, Requires<[HasSSE41]>;
3546
3547 def : Pat<(int_x86_sse41_pmovzxbd (vzmovl_v4i32 addr:$src)),
3548           (PMOVZXBDrm addr:$src)>, Requires<[HasSSE41]>;
3549 def : Pat<(int_x86_sse41_pmovzxwq (vzmovl_v4i32 addr:$src)),
3550           (PMOVZXWQrm addr:$src)>, Requires<[HasSSE41]>;
3551
3552
3553 multiclass SS41I_binop_rm_int2<bits<8> opc, string OpcodeStr, Intrinsic IntId> {
3554   def rr : SS48I<opc, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
3555                  !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
3556                  [(set VR128:$dst, (IntId VR128:$src))]>, OpSize;
3557
3558   // Expecting a i16 load any extended to i32 value.
3559   def rm : SS48I<opc, MRMSrcMem, (outs VR128:$dst), (ins i16mem:$src),
3560                  !strconcat(OpcodeStr, "\t{$src, $dst|$dst, $src}"),
3561                  [(set VR128:$dst, (IntId (bitconvert
3562                      (v4i32 (scalar_to_vector (loadi16_anyext addr:$src))))))]>,
3563                  OpSize;
3564 }
3565
3566 defm PMOVSXBQ   : SS41I_binop_rm_int2<0x22, "pmovsxbq", int_x86_sse41_pmovsxbq>;
3567 defm PMOVZXBQ   : SS41I_binop_rm_int2<0x32, "pmovzxbq", int_x86_sse41_pmovzxbq>;
3568
3569 // Common patterns involving scalar load
3570 def : Pat<(int_x86_sse41_pmovsxbq
3571             (bitconvert (v4i32 (X86vzmovl
3572                              (v4i32 (scalar_to_vector (loadi32 addr:$src))))))),
3573           (PMOVSXBQrm addr:$src)>, Requires<[HasSSE41]>;
3574
3575 def : Pat<(int_x86_sse41_pmovzxbq
3576             (bitconvert (v4i32 (X86vzmovl
3577                              (v4i32 (scalar_to_vector (loadi32 addr:$src))))))),
3578           (PMOVZXBQrm addr:$src)>, Requires<[HasSSE41]>;
3579
3580
3581 /// SS41I_binop_ext8 - SSE 4.1 extract 8 bits to 32 bit reg or 8 bit mem
3582 multiclass SS41I_extract8<bits<8> opc, string OpcodeStr> {
3583   def rr : SS4AIi8<opc, MRMDestReg, (outs GR32:$dst),
3584                  (ins VR128:$src1, i32i8imm:$src2),
3585                  !strconcat(OpcodeStr,
3586                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
3587                  [(set GR32:$dst, (X86pextrb (v16i8 VR128:$src1), imm:$src2))]>,
3588                  OpSize;
3589   def mr : SS4AIi8<opc, MRMDestMem, (outs),
3590                  (ins i8mem:$dst, VR128:$src1, i32i8imm:$src2),
3591                  !strconcat(OpcodeStr,
3592                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
3593                  []>, OpSize;
3594 // FIXME:
3595 // There's an AssertZext in the way of writing the store pattern
3596 // (store (i8 (trunc (X86pextrb (v16i8 VR128:$src1), imm:$src2))), addr:$dst)
3597 }
3598
3599 defm PEXTRB      : SS41I_extract8<0x14, "pextrb">;
3600
3601
3602 /// SS41I_extract16 - SSE 4.1 extract 16 bits to memory destination
3603 multiclass SS41I_extract16<bits<8> opc, string OpcodeStr> {
3604   def mr : SS4AIi8<opc, MRMDestMem, (outs),
3605                  (ins i16mem:$dst, VR128:$src1, i32i8imm:$src2),
3606                  !strconcat(OpcodeStr,
3607                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
3608                  []>, OpSize;
3609 // FIXME:
3610 // There's an AssertZext in the way of writing the store pattern
3611 // (store (i16 (trunc (X86pextrw (v16i8 VR128:$src1), imm:$src2))), addr:$dst)
3612 }
3613
3614 defm PEXTRW      : SS41I_extract16<0x15, "pextrw">;
3615
3616
3617 /// SS41I_extract32 - SSE 4.1 extract 32 bits to int reg or memory destination
3618 multiclass SS41I_extract32<bits<8> opc, string OpcodeStr> {
3619   def rr : SS4AIi8<opc, MRMDestReg, (outs GR32:$dst),
3620                  (ins VR128:$src1, i32i8imm:$src2),
3621                  !strconcat(OpcodeStr,
3622                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
3623                  [(set GR32:$dst,
3624                   (extractelt (v4i32 VR128:$src1), imm:$src2))]>, OpSize;
3625   def mr : SS4AIi8<opc, MRMDestMem, (outs),
3626                  (ins i32mem:$dst, VR128:$src1, i32i8imm:$src2),
3627                  !strconcat(OpcodeStr,
3628                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
3629                  [(store (extractelt (v4i32 VR128:$src1), imm:$src2),
3630                           addr:$dst)]>, OpSize;
3631 }
3632
3633 defm PEXTRD      : SS41I_extract32<0x16, "pextrd">;
3634
3635
3636 /// SS41I_extractf32 - SSE 4.1 extract 32 bits fp value to int reg or memory
3637 /// destination
3638 multiclass SS41I_extractf32<bits<8> opc, string OpcodeStr> {
3639   def rr : SS4AIi8<opc, MRMDestReg, (outs GR32:$dst),
3640                  (ins VR128:$src1, i32i8imm:$src2),
3641                  !strconcat(OpcodeStr,
3642                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
3643                  [(set GR32:$dst,
3644                     (extractelt (bc_v4i32 (v4f32 VR128:$src1)), imm:$src2))]>,
3645            OpSize;
3646   def mr : SS4AIi8<opc, MRMDestMem, (outs),
3647                  (ins f32mem:$dst, VR128:$src1, i32i8imm:$src2),
3648                  !strconcat(OpcodeStr,
3649                   "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
3650                  [(store (extractelt (bc_v4i32 (v4f32 VR128:$src1)), imm:$src2),
3651                           addr:$dst)]>, OpSize;
3652 }
3653
3654 defm EXTRACTPS   : SS41I_extractf32<0x17, "extractps">;
3655
3656 // Also match an EXTRACTPS store when the store is done as f32 instead of i32.
3657 def : Pat<(store (f32 (bitconvert (extractelt (bc_v4i32 (v4f32 VR128:$src1)),
3658                                               imm:$src2))),
3659                  addr:$dst),
3660           (EXTRACTPSmr addr:$dst, VR128:$src1, imm:$src2)>,
3661          Requires<[HasSSE41]>;
3662
3663 let Constraints = "$src1 = $dst" in {
3664   multiclass SS41I_insert8<bits<8> opc, string OpcodeStr> {
3665     def rr : SS4AIi8<opc, MRMSrcReg, (outs VR128:$dst),
3666                    (ins VR128:$src1, GR32:$src2, i32i8imm:$src3),
3667                    !strconcat(OpcodeStr,
3668                     "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
3669                    [(set VR128:$dst,
3670                      (X86pinsrb VR128:$src1, GR32:$src2, imm:$src3))]>, OpSize;
3671     def rm : SS4AIi8<opc, MRMSrcMem, (outs VR128:$dst),
3672                    (ins VR128:$src1, i8mem:$src2, i32i8imm:$src3),
3673                    !strconcat(OpcodeStr,
3674                     "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
3675                    [(set VR128:$dst,
3676                      (X86pinsrb VR128:$src1, (extloadi8 addr:$src2),
3677                                 imm:$src3))]>, OpSize;
3678   }
3679 }
3680
3681 defm PINSRB      : SS41I_insert8<0x20, "pinsrb">;
3682
3683 let Constraints = "$src1 = $dst" in {
3684   multiclass SS41I_insert32<bits<8> opc, string OpcodeStr> {
3685     def rr : SS4AIi8<opc, MRMSrcReg, (outs VR128:$dst),
3686                    (ins VR128:$src1, GR32:$src2, i32i8imm:$src3),
3687                    !strconcat(OpcodeStr,
3688                     "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
3689                    [(set VR128:$dst,
3690                      (v4i32 (insertelt VR128:$src1, GR32:$src2, imm:$src3)))]>,
3691                    OpSize;
3692     def rm : SS4AIi8<opc, MRMSrcMem, (outs VR128:$dst),
3693                    (ins VR128:$src1, i32mem:$src2, i32i8imm:$src3),
3694                    !strconcat(OpcodeStr,
3695                     "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
3696                    [(set VR128:$dst,
3697                      (v4i32 (insertelt VR128:$src1, (loadi32 addr:$src2),
3698                                        imm:$src3)))]>, OpSize;
3699   }
3700 }
3701
3702 defm PINSRD      : SS41I_insert32<0x22, "pinsrd">;
3703
3704 // insertps has a few different modes, there's the first two here below which
3705 // are optimized inserts that won't zero arbitrary elements in the destination
3706 // vector. The next one matches the intrinsic and could zero arbitrary elements
3707 // in the target vector.
3708 let Constraints = "$src1 = $dst" in {
3709   multiclass SS41I_insertf32<bits<8> opc, string OpcodeStr> {
3710     def rr : SS4AIi8<opc, MRMSrcReg, (outs VR128:$dst),
3711                    (ins VR128:$src1, VR128:$src2, i32i8imm:$src3),
3712                    !strconcat(OpcodeStr,
3713                     "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
3714                    [(set VR128:$dst,
3715                      (X86insrtps VR128:$src1, VR128:$src2, imm:$src3))]>,
3716       OpSize;
3717     def rm : SS4AIi8<opc, MRMSrcMem, (outs VR128:$dst),
3718                    (ins VR128:$src1, f32mem:$src2, i32i8imm:$src3),
3719                    !strconcat(OpcodeStr,
3720                     "\t{$src3, $src2, $dst|$dst, $src2, $src3}"),
3721                    [(set VR128:$dst,
3722                      (X86insrtps VR128:$src1,
3723                                 (v4f32 (scalar_to_vector (loadf32 addr:$src2))),
3724                                  imm:$src3))]>, OpSize;
3725   }
3726 }
3727
3728 defm INSERTPS    : SS41I_insertf32<0x21, "insertps">;
3729
3730 def : Pat<(int_x86_sse41_insertps VR128:$src1, VR128:$src2, imm:$src3),
3731           (INSERTPSrr VR128:$src1, VR128:$src2, imm:$src3)>;
3732
3733 // ptest instruction we'll lower to this in X86ISelLowering primarily from
3734 // the intel intrinsic that corresponds to this.
3735 let Defs = [EFLAGS] in {
3736 def PTESTrr : SS48I<0x17, MRMSrcReg, (outs), (ins VR128:$src1, VR128:$src2),
3737                     "ptest \t{$src2, $src1|$src1, $src2}",
3738                     [(set EFLAGS, (X86ptest VR128:$src1, VR128:$src2))]>,
3739               OpSize;
3740 def PTESTrm : SS48I<0x17, MRMSrcMem, (outs), (ins VR128:$src1, i128mem:$src2),
3741                     "ptest \t{$src2, $src1|$src1, $src2}",
3742                     [(set EFLAGS, (X86ptest VR128:$src1, (load addr:$src2)))]>,
3743               OpSize;
3744 }
3745
3746 def MOVNTDQArm : SS48I<0x2A, MRMSrcMem, (outs VR128:$dst), (ins i128mem:$src),
3747                        "movntdqa\t{$src, $dst|$dst, $src}",
3748                        [(set VR128:$dst, (int_x86_sse41_movntdqa addr:$src))]>,
3749                        OpSize;
3750
3751
3752 //===----------------------------------------------------------------------===//
3753 // SSE4.2 Instructions
3754 //===----------------------------------------------------------------------===//
3755
3756 /// SS42I_binop_rm_int - Simple SSE 4.2 binary operator
3757 let Constraints = "$src1 = $dst" in {
3758   multiclass SS42I_binop_rm_int<bits<8> opc, string OpcodeStr,
3759                                 Intrinsic IntId128, bit Commutable = 0> {
3760     def rr : SS428I<opc, MRMSrcReg, (outs VR128:$dst),
3761                    (ins VR128:$src1, VR128:$src2),
3762                    !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
3763                    [(set VR128:$dst, (IntId128 VR128:$src1, VR128:$src2))]>,
3764                    OpSize {
3765       let isCommutable = Commutable;
3766     }
3767     def rm : SS428I<opc, MRMSrcMem, (outs VR128:$dst),
3768                    (ins VR128:$src1, i128mem:$src2),
3769                    !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
3770                    [(set VR128:$dst,
3771                      (IntId128 VR128:$src1,
3772                       (bitconvert (memopv16i8 addr:$src2))))]>, OpSize;
3773   }
3774 }
3775
3776 defm PCMPGTQ      : SS42I_binop_rm_int<0x37, "pcmpgtq", int_x86_sse42_pcmpgtq>;
3777
3778 def : Pat<(v2i64 (X86pcmpgtq VR128:$src1, VR128:$src2)),
3779           (PCMPGTQrr VR128:$src1, VR128:$src2)>;
3780 def : Pat<(v2i64 (X86pcmpgtq VR128:$src1, (memop addr:$src2))),
3781           (PCMPGTQrm VR128:$src1, addr:$src2)>;
3782
3783 // crc intrinsic instruction
3784 // This set of instructions are only rm, the only difference is the size
3785 // of r and m.
3786 let Constraints = "$src1 = $dst" in {
3787   def CRC32m8  : SS42FI<0xF0, MRMSrcMem, (outs GR32:$dst),
3788                       (ins GR32:$src1, i8mem:$src2),
3789                       "crc32{b} \t{$src2, $src1|$src1, $src2}",
3790                        [(set GR32:$dst,
3791                          (int_x86_sse42_crc32_8 GR32:$src1,
3792                          (load addr:$src2)))]>;
3793   def CRC32r8  : SS42FI<0xF0, MRMSrcReg, (outs GR32:$dst),
3794                       (ins GR32:$src1, GR8:$src2),
3795                       "crc32{b} \t{$src2, $src1|$src1, $src2}",
3796                        [(set GR32:$dst,
3797                          (int_x86_sse42_crc32_8 GR32:$src1, GR8:$src2))]>;
3798   def CRC32m16  : SS42FI<0xF1, MRMSrcMem, (outs GR32:$dst),
3799                       (ins GR32:$src1, i16mem:$src2),
3800                       "crc32{w} \t{$src2, $src1|$src1, $src2}",
3801                        [(set GR32:$dst,
3802                          (int_x86_sse42_crc32_16 GR32:$src1,
3803                          (load addr:$src2)))]>,
3804                          OpSize;
3805   def CRC32r16  : SS42FI<0xF1, MRMSrcReg, (outs GR32:$dst),
3806                       (ins GR32:$src1, GR16:$src2),
3807                       "crc32{w} \t{$src2, $src1|$src1, $src2}",
3808                        [(set GR32:$dst,
3809                          (int_x86_sse42_crc32_16 GR32:$src1, GR16:$src2))]>,
3810                          OpSize;
3811   def CRC32m32  : SS42FI<0xF1, MRMSrcMem, (outs GR32:$dst),
3812                       (ins GR32:$src1, i32mem:$src2),
3813                       "crc32{l} \t{$src2, $src1|$src1, $src2}",
3814                        [(set GR32:$dst,
3815                          (int_x86_sse42_crc32_32 GR32:$src1,
3816                          (load addr:$src2)))]>;
3817   def CRC32r32  : SS42FI<0xF1, MRMSrcReg, (outs GR32:$dst),
3818                       (ins GR32:$src1, GR32:$src2),
3819                       "crc32{l} \t{$src2, $src1|$src1, $src2}",
3820                        [(set GR32:$dst,
3821                          (int_x86_sse42_crc32_32 GR32:$src1, GR32:$src2))]>;
3822   def CRC64m8  : SS42FI<0xF0, MRMSrcMem, (outs GR64:$dst),
3823                       (ins GR64:$src1, i8mem:$src2),
3824                       "crc32{b} \t{$src2, $src1|$src1, $src2}",
3825                        [(set GR64:$dst,
3826                          (int_x86_sse42_crc64_8 GR64:$src1,
3827                          (load addr:$src2)))]>,
3828                          REX_W;
3829   def CRC64r8  : SS42FI<0xF0, MRMSrcReg, (outs GR64:$dst),
3830                       (ins GR64:$src1, GR8:$src2),
3831                       "crc32{b} \t{$src2, $src1|$src1, $src2}",
3832                        [(set GR64:$dst,
3833                          (int_x86_sse42_crc64_8 GR64:$src1, GR8:$src2))]>,
3834                          REX_W;
3835   def CRC64m64  : SS42FI<0xF1, MRMSrcMem, (outs GR64:$dst),
3836                       (ins GR64:$src1, i64mem:$src2),
3837                       "crc32{q} \t{$src2, $src1|$src1, $src2}",
3838                        [(set GR64:$dst,
3839                          (int_x86_sse42_crc64_64 GR64:$src1,
3840                          (load addr:$src2)))]>,
3841                          REX_W;
3842   def CRC64r64  : SS42FI<0xF1, MRMSrcReg, (outs GR64:$dst),
3843                       (ins GR64:$src1, GR64:$src2),
3844                       "crc32{q} \t{$src2, $src1|$src1, $src2}",
3845                        [(set GR64:$dst,
3846                          (int_x86_sse42_crc64_64 GR64:$src1, GR64:$src2))]>,
3847                          REX_W;
3848 }
3849
3850 // String/text processing instructions.
3851 let Defs = [EFLAGS], usesCustomInserter = 1 in {
3852 def PCMPISTRM128REG : SS42AI<0, Pseudo, (outs VR128:$dst),
3853   (ins VR128:$src1, VR128:$src2, i8imm:$src3),
3854   "#PCMPISTRM128rr PSEUDO!",
3855   [(set VR128:$dst, (int_x86_sse42_pcmpistrm128 VR128:$src1, VR128:$src2,
3856                                                 imm:$src3))]>, OpSize;
3857 def PCMPISTRM128MEM : SS42AI<0, Pseudo, (outs VR128:$dst),
3858   (ins VR128:$src1, i128mem:$src2, i8imm:$src3),
3859   "#PCMPISTRM128rm PSEUDO!",
3860   [(set VR128:$dst, (int_x86_sse42_pcmpistrm128 VR128:$src1, (load addr:$src2),
3861                                                 imm:$src3))]>, OpSize;
3862 }
3863
3864 let Defs = [XMM0, EFLAGS] in {
3865 def PCMPISTRM128rr : SS42AI<0x62, MRMSrcReg, (outs),
3866   (ins VR128:$src1, VR128:$src2, i8imm:$src3),
3867    "pcmpistrm\t{$src3, $src2, $src1|$src1, $src2, $src3}", []>, OpSize;
3868 def PCMPISTRM128rm : SS42AI<0x62, MRMSrcMem, (outs),
3869   (ins VR128:$src1, i128mem:$src2, i8imm:$src3),
3870   "pcmpistrm\t{$src3, $src2, $src1|$src1, $src2, $src3}", []>, OpSize;
3871 }
3872
3873 let Defs = [EFLAGS], Uses = [EAX, EDX], usesCustomInserter = 1 in {
3874 def PCMPESTRM128REG : SS42AI<0, Pseudo, (outs VR128:$dst),
3875   (ins VR128:$src1, VR128:$src3, i8imm:$src5),
3876   "#PCMPESTRM128rr PSEUDO!",
3877   [(set VR128:$dst,
3878         (int_x86_sse42_pcmpestrm128
3879          VR128:$src1, EAX, VR128:$src3, EDX, imm:$src5))]>, OpSize;
3880
3881 def PCMPESTRM128MEM : SS42AI<0, Pseudo, (outs VR128:$dst),
3882   (ins VR128:$src1, i128mem:$src3, i8imm:$src5),
3883   "#PCMPESTRM128rm PSEUDO!",
3884   [(set VR128:$dst, (int_x86_sse42_pcmpestrm128
3885                      VR128:$src1, EAX, (load addr:$src3), EDX, imm:$src5))]>,
3886   OpSize;
3887 }
3888
3889 let Defs = [XMM0, EFLAGS], Uses = [EAX, EDX] in {
3890 def PCMPESTRM128rr : SS42AI<0x60, MRMSrcReg, (outs),
3891   (ins VR128:$src1, VR128:$src3, i8imm:$src5),
3892   "pcmpestrm\t{$src5, $src3, $src1|$src1, $src3, $src5}", []>, OpSize;
3893 def PCMPESTRM128rm : SS42AI<0x60, MRMSrcMem, (outs),
3894   (ins VR128:$src1, i128mem:$src3, i8imm:$src5),
3895   "pcmpestrm\t{$src5, $src3, $src1|$src1, $src3, $src5}", []>, OpSize;
3896 }
3897
3898 let Defs = [ECX, EFLAGS] in {
3899   multiclass SS42AI_pcmpistri<Intrinsic IntId128> {
3900     def rr : SS42AI<0x63, MRMSrcReg, (outs),
3901       (ins VR128:$src1, VR128:$src2, i8imm:$src3),
3902       "pcmpistri\t{$src3, $src2, $src1|$src1, $src2, $src3}",
3903       [(set ECX, (IntId128 VR128:$src1, VR128:$src2, imm:$src3)),
3904        (implicit EFLAGS)]>, OpSize;
3905     def rm : SS42AI<0x63, MRMSrcMem, (outs),
3906       (ins VR128:$src1, i128mem:$src2, i8imm:$src3),
3907       "pcmpistri\t{$src3, $src2, $src1|$src1, $src2, $src3}",
3908       [(set ECX, (IntId128 VR128:$src1, (load addr:$src2), imm:$src3)),
3909        (implicit EFLAGS)]>, OpSize;
3910   }
3911 }
3912
3913 defm PCMPISTRI  : SS42AI_pcmpistri<int_x86_sse42_pcmpistri128>;
3914 defm PCMPISTRIA : SS42AI_pcmpistri<int_x86_sse42_pcmpistria128>;
3915 defm PCMPISTRIC : SS42AI_pcmpistri<int_x86_sse42_pcmpistric128>;
3916 defm PCMPISTRIO : SS42AI_pcmpistri<int_x86_sse42_pcmpistrio128>;
3917 defm PCMPISTRIS : SS42AI_pcmpistri<int_x86_sse42_pcmpistris128>;
3918 defm PCMPISTRIZ : SS42AI_pcmpistri<int_x86_sse42_pcmpistriz128>;
3919
3920 let Defs = [ECX, EFLAGS] in {
3921 let Uses = [EAX, EDX] in {
3922   multiclass SS42AI_pcmpestri<Intrinsic IntId128> {
3923     def rr : SS42AI<0x61, MRMSrcReg, (outs),
3924       (ins VR128:$src1, VR128:$src3, i8imm:$src5),
3925       "pcmpestri\t{$src5, $src3, $src1|$src1, $src3, $src5}",
3926       [(set ECX, (IntId128 VR128:$src1, EAX, VR128:$src3, EDX, imm:$src5)),
3927        (implicit EFLAGS)]>, OpSize;
3928     def rm : SS42AI<0x61, MRMSrcMem, (outs),
3929       (ins VR128:$src1, i128mem:$src3, i8imm:$src5),
3930        "pcmpestri\t{$src5, $src3, $src1|$src1, $src3, $src5}",
3931        [(set ECX,
3932              (IntId128 VR128:$src1, EAX, (load addr:$src3), EDX, imm:$src5)),
3933         (implicit EFLAGS)]>, OpSize;
3934   }
3935 }
3936 }
3937
3938 defm PCMPESTRI  : SS42AI_pcmpestri<int_x86_sse42_pcmpestri128>;
3939 defm PCMPESTRIA : SS42AI_pcmpestri<int_x86_sse42_pcmpestria128>;
3940 defm PCMPESTRIC : SS42AI_pcmpestri<int_x86_sse42_pcmpestric128>;
3941 defm PCMPESTRIO : SS42AI_pcmpestri<int_x86_sse42_pcmpestrio128>;
3942 defm PCMPESTRIS : SS42AI_pcmpestri<int_x86_sse42_pcmpestris128>;
3943 defm PCMPESTRIZ : SS42AI_pcmpestri<int_x86_sse42_pcmpestriz128>;
3944
3945 //===----------------------------------------------------------------------===//
3946 // AES-NI Instructions
3947 //===----------------------------------------------------------------------===//
3948
3949 let Constraints = "$src1 = $dst" in {
3950   multiclass AESI_binop_rm_int<bits<8> opc, string OpcodeStr,
3951                                 Intrinsic IntId128, bit Commutable = 0> {
3952     def rr : AES8I<opc, MRMSrcReg, (outs VR128:$dst),
3953                    (ins VR128:$src1, VR128:$src2),
3954                    !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
3955                    [(set VR128:$dst, (IntId128 VR128:$src1, VR128:$src2))]>,
3956                    OpSize {
3957       let isCommutable = Commutable;
3958     }
3959     def rm : AES8I<opc, MRMSrcMem, (outs VR128:$dst),
3960                    (ins VR128:$src1, i128mem:$src2),
3961                    !strconcat(OpcodeStr, "\t{$src2, $dst|$dst, $src2}"),
3962                    [(set VR128:$dst,
3963                      (IntId128 VR128:$src1,
3964                       (bitconvert (memopv16i8 addr:$src2))))]>, OpSize;
3965   }
3966 }
3967
3968 defm AESENC          : AESI_binop_rm_int<0xDC, "aesenc",
3969                        int_x86_aesni_aesenc>;
3970 defm AESENCLAST      : AESI_binop_rm_int<0xDD, "aesenclast",
3971                        int_x86_aesni_aesenclast>;
3972 defm AESDEC          : AESI_binop_rm_int<0xDE, "aesdec",
3973                        int_x86_aesni_aesdec>;
3974 defm AESDECLAST      : AESI_binop_rm_int<0xDF, "aesdeclast",
3975                        int_x86_aesni_aesdeclast>;
3976
3977 def : Pat<(v2i64 (int_x86_aesni_aesenc VR128:$src1, VR128:$src2)),
3978           (AESENCrr VR128:$src1, VR128:$src2)>;
3979 def : Pat<(v2i64 (int_x86_aesni_aesenc VR128:$src1, (memop addr:$src2))),
3980           (AESENCrm VR128:$src1, addr:$src2)>;
3981 def : Pat<(v2i64 (int_x86_aesni_aesenclast VR128:$src1, VR128:$src2)),
3982           (AESENCLASTrr VR128:$src1, VR128:$src2)>;
3983 def : Pat<(v2i64 (int_x86_aesni_aesenclast VR128:$src1, (memop addr:$src2))),
3984           (AESENCLASTrm VR128:$src1, addr:$src2)>;
3985 def : Pat<(v2i64 (int_x86_aesni_aesdec VR128:$src1, VR128:$src2)),
3986           (AESDECrr VR128:$src1, VR128:$src2)>;
3987 def : Pat<(v2i64 (int_x86_aesni_aesdec VR128:$src1, (memop addr:$src2))),
3988           (AESDECrm VR128:$src1, addr:$src2)>;
3989 def : Pat<(v2i64 (int_x86_aesni_aesdeclast VR128:$src1, VR128:$src2)),
3990           (AESDECLASTrr VR128:$src1, VR128:$src2)>;
3991 def : Pat<(v2i64 (int_x86_aesni_aesdeclast VR128:$src1, (memop addr:$src2))),
3992           (AESDECLASTrm VR128:$src1, addr:$src2)>;
3993
3994 def AESIMCrr : AES8I<0xDB, MRMSrcReg, (outs VR128:$dst),
3995   (ins VR128:$src1),
3996   "aesimc\t{$src1, $dst|$dst, $src1}",
3997   [(set VR128:$dst,
3998     (int_x86_aesni_aesimc VR128:$src1))]>,
3999   OpSize;
4000
4001 def AESIMCrm : AES8I<0xDB, MRMSrcMem, (outs VR128:$dst),
4002   (ins i128mem:$src1),
4003   "aesimc\t{$src1, $dst|$dst, $src1}",
4004   [(set VR128:$dst,
4005     (int_x86_aesni_aesimc (bitconvert (memopv2i64 addr:$src1))))]>,
4006   OpSize;
4007
4008 def AESKEYGENASSIST128rr : AESAI<0xDF, MRMSrcReg, (outs VR128:$dst),
4009   (ins VR128:$src1, i8imm:$src2),
4010   "aeskeygenassist\t{$src2, $src1, $dst|$dst, $src1, $src2}",
4011   [(set VR128:$dst,
4012     (int_x86_aesni_aeskeygenassist VR128:$src1, imm:$src2))]>,
4013   OpSize;
4014 def AESKEYGENASSIST128rm : AESAI<0xDF, MRMSrcMem, (outs VR128:$dst),
4015   (ins i128mem:$src1, i8imm:$src2),
4016   "aeskeygenassist\t{$src2, $src1, $dst|$dst, $src1, $src2}",
4017   [(set VR128:$dst,
4018     (int_x86_aesni_aeskeygenassist (bitconvert (memopv2i64 addr:$src1)),
4019                                     imm:$src2))]>,
4020   OpSize;