1169689Skan;; GCC machine description for SSE instructions
2252080Spfg;; Copyright (C) 2005, 2006, 2007
3169689Skan;; Free Software Foundation, Inc.
4169689Skan;;
5169689Skan;; This file is part of GCC.
6169689Skan;;
7169689Skan;; GCC is free software; you can redistribute it and/or modify
8169689Skan;; it under the terms of the GNU General Public License as published by
9169689Skan;; the Free Software Foundation; either version 2, or (at your option)
10169689Skan;; any later version.
11169689Skan;;
12169689Skan;; GCC is distributed in the hope that it will be useful,
13169689Skan;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14169689Skan;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15169689Skan;; GNU General Public License for more details.
16169689Skan;;
17169689Skan;; You should have received a copy of the GNU General Public License
18169689Skan;; along with GCC; see the file COPYING.  If not, write to
19169689Skan;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
20169689Skan;; Boston, MA 02110-1301, USA.
21169689Skan
22169689Skan
23169689Skan;; 16 byte integral modes handled by SSE, minus TImode, which gets
24169689Skan;; special-cased for TARGET_64BIT.
25169689Skan(define_mode_macro SSEMODEI [V16QI V8HI V4SI V2DI])
26169689Skan
27169689Skan;; All 16-byte vector modes handled by SSE
28169689Skan(define_mode_macro SSEMODE [V16QI V8HI V4SI V2DI V4SF V2DF])
29169689Skan
30169689Skan;; Mix-n-match
31169689Skan(define_mode_macro SSEMODE12 [V16QI V8HI])
32169689Skan(define_mode_macro SSEMODE24 [V8HI V4SI])
33169689Skan(define_mode_macro SSEMODE14 [V16QI V4SI])
34169689Skan(define_mode_macro SSEMODE124 [V16QI V8HI V4SI])
35169689Skan(define_mode_macro SSEMODE248 [V8HI V4SI V2DI])
36169689Skan
37169689Skan;; Mapping from integer vector mode to mnemonic suffix
38169689Skan(define_mode_attr ssevecsize [(V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")])
39169689Skan
40169689Skan;; Patterns whose name begins with "sse{,2,3}_" are invoked by intrinsics.
41169689Skan
42169689Skan;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
43169689Skan;;
44169689Skan;; Move patterns
45169689Skan;;
46169689Skan;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
47169689Skan
48169689Skan;; All of these patterns are enabled for SSE1 as well as SSE2.
49169689Skan;; This is essential for maintaining stable calling conventions.
50169689Skan
51169689Skan(define_expand "mov<mode>"
52169689Skan  [(set (match_operand:SSEMODEI 0 "nonimmediate_operand" "")
53169689Skan	(match_operand:SSEMODEI 1 "nonimmediate_operand" ""))]
54169689Skan  "TARGET_SSE"
55169689Skan{
56169689Skan  ix86_expand_vector_move (<MODE>mode, operands);
57169689Skan  DONE;
58169689Skan})
59169689Skan
60169689Skan(define_insn "*mov<mode>_internal"
61169689Skan  [(set (match_operand:SSEMODEI 0 "nonimmediate_operand" "=x,x ,m")
62169689Skan	(match_operand:SSEMODEI 1 "nonimmediate_or_sse_const_operand"  "C ,xm,x"))]
63169689Skan  "TARGET_SSE && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
64169689Skan{
65169689Skan  switch (which_alternative)
66169689Skan    {
67169689Skan    case 0:
68169689Skan      return standard_sse_constant_opcode (insn, operands[1]);
69169689Skan    case 1:
70169689Skan    case 2:
71169689Skan      if (get_attr_mode (insn) == MODE_V4SF)
72169689Skan	return "movaps\t{%1, %0|%0, %1}";
73169689Skan      else
74169689Skan	return "movdqa\t{%1, %0|%0, %1}";
75169689Skan    default:
76169689Skan      gcc_unreachable ();
77169689Skan    }
78169689Skan}
79169689Skan  [(set_attr "type" "sselog1,ssemov,ssemov")
80169689Skan   (set (attr "mode")
81169689Skan	(if_then_else
82169689Skan	  (ior (ior (ne (symbol_ref "optimize_size") (const_int 0))
83169689Skan		    (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
84169689Skan	       (and (eq_attr "alternative" "2")
85169689Skan	  	    (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
86169689Skan		        (const_int 0))))
87169689Skan	  (const_string "V4SF")
88169689Skan	  (const_string "TI")))])
89169689Skan
90169689Skan(define_expand "movv4sf"
91169689Skan  [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
92169689Skan	(match_operand:V4SF 1 "nonimmediate_operand" ""))]
93169689Skan  "TARGET_SSE"
94169689Skan{
95169689Skan  ix86_expand_vector_move (V4SFmode, operands);
96169689Skan  DONE;
97169689Skan})
98169689Skan
99169689Skan(define_insn "*movv4sf_internal"
100169689Skan  [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,m")
101169689Skan	(match_operand:V4SF 1 "nonimmediate_or_sse_const_operand" "C,xm,x"))]
102169689Skan  "TARGET_SSE"
103169689Skan{
104169689Skan  switch (which_alternative)
105169689Skan    {
106169689Skan    case 0:
107169689Skan      return standard_sse_constant_opcode (insn, operands[1]);
108169689Skan    case 1:
109169689Skan    case 2:
110169689Skan      return "movaps\t{%1, %0|%0, %1}";
111169689Skan    default:
112169689Skan      abort();
113169689Skan    }
114169689Skan}
115169689Skan  [(set_attr "type" "sselog1,ssemov,ssemov")
116169689Skan   (set_attr "mode" "V4SF")])
117169689Skan
118169689Skan(define_split
119169689Skan  [(set (match_operand:V4SF 0 "register_operand" "")
120169689Skan	(match_operand:V4SF 1 "zero_extended_scalar_load_operand" ""))]
121169689Skan  "TARGET_SSE && reload_completed"
122169689Skan  [(set (match_dup 0)
123169689Skan	(vec_merge:V4SF
124169689Skan	  (vec_duplicate:V4SF (match_dup 1))
125169689Skan	  (match_dup 2)
126169689Skan	  (const_int 1)))]
127169689Skan{
128169689Skan  operands[1] = simplify_gen_subreg (SFmode, operands[1], V4SFmode, 0);
129169689Skan  operands[2] = CONST0_RTX (V4SFmode);
130169689Skan})
131169689Skan
132169689Skan(define_expand "movv2df"
133169689Skan  [(set (match_operand:V2DF 0 "nonimmediate_operand" "")
134169689Skan	(match_operand:V2DF 1 "nonimmediate_operand" ""))]
135169689Skan  "TARGET_SSE"
136169689Skan{
137169689Skan  ix86_expand_vector_move (V2DFmode, operands);
138169689Skan  DONE;
139169689Skan})
140169689Skan
141169689Skan(define_insn "*movv2df_internal"
142169689Skan  [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
143169689Skan	(match_operand:V2DF 1 "nonimmediate_or_sse_const_operand" "C,xm,x"))]
144169689Skan  "TARGET_SSE && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
145169689Skan{
146169689Skan  switch (which_alternative)
147169689Skan    {
148169689Skan    case 0:
149169689Skan      return standard_sse_constant_opcode (insn, operands[1]);
150169689Skan    case 1:
151169689Skan    case 2:
152169689Skan      if (get_attr_mode (insn) == MODE_V4SF)
153169689Skan	return "movaps\t{%1, %0|%0, %1}";
154169689Skan      else
155169689Skan	return "movapd\t{%1, %0|%0, %1}";
156169689Skan    default:
157169689Skan      gcc_unreachable ();
158169689Skan    }
159169689Skan}
160169689Skan  [(set_attr "type" "sselog1,ssemov,ssemov")
161169689Skan   (set (attr "mode")
162169689Skan	(if_then_else
163169689Skan	  (ior (ior (ne (symbol_ref "optimize_size") (const_int 0))
164169689Skan		    (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
165169689Skan	       (and (eq_attr "alternative" "2")
166169689Skan	  	    (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
167169689Skan		        (const_int 0))))
168169689Skan	  (const_string "V4SF")
169169689Skan	  (const_string "V2DF")))])
170169689Skan
171169689Skan(define_split
172169689Skan  [(set (match_operand:V2DF 0 "register_operand" "")
173169689Skan	(match_operand:V2DF 1 "zero_extended_scalar_load_operand" ""))]
174169689Skan  "TARGET_SSE2 && reload_completed"
175169689Skan  [(set (match_dup 0) (vec_concat:V2DF (match_dup 1) (match_dup 2)))]
176169689Skan{
177169689Skan  operands[1] = simplify_gen_subreg (DFmode, operands[1], V2DFmode, 0);
178169689Skan  operands[2] = CONST0_RTX (DFmode);
179169689Skan})
180169689Skan
181169689Skan(define_expand "push<mode>1"
182169689Skan  [(match_operand:SSEMODE 0 "register_operand" "")]
183169689Skan  "TARGET_SSE"
184169689Skan{
185169689Skan  ix86_expand_push (<MODE>mode, operands[0]);
186169689Skan  DONE;
187169689Skan})
188169689Skan
189169689Skan(define_expand "movmisalign<mode>"
190169689Skan  [(set (match_operand:SSEMODE 0 "nonimmediate_operand" "")
191169689Skan	(match_operand:SSEMODE 1 "nonimmediate_operand" ""))]
192169689Skan  "TARGET_SSE"
193169689Skan{
194169689Skan  ix86_expand_vector_move_misalign (<MODE>mode, operands);
195169689Skan  DONE;
196169689Skan})
197169689Skan
198169689Skan(define_insn "sse_movups"
199169689Skan  [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
200169689Skan	(unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
201169689Skan		     UNSPEC_MOVU))]
202169689Skan  "TARGET_SSE && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
203169689Skan  "movups\t{%1, %0|%0, %1}"
204169689Skan  [(set_attr "type" "ssemov")
205169689Skan   (set_attr "mode" "V2DF")])
206169689Skan
207169689Skan(define_insn "sse2_movupd"
208169689Skan  [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
209169689Skan	(unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
210169689Skan		     UNSPEC_MOVU))]
211169689Skan  "TARGET_SSE2 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
212169689Skan  "movupd\t{%1, %0|%0, %1}"
213169689Skan  [(set_attr "type" "ssemov")
214169689Skan   (set_attr "mode" "V2DF")])
215169689Skan
216169689Skan(define_insn "sse2_movdqu"
217169689Skan  [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
218169689Skan	(unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
219169689Skan		      UNSPEC_MOVU))]
220169689Skan  "TARGET_SSE2 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
221169689Skan  "movdqu\t{%1, %0|%0, %1}"
222169689Skan  [(set_attr "type" "ssemov")
223169689Skan   (set_attr "mode" "TI")])
224169689Skan
225169689Skan(define_insn "sse_movntv4sf"
226169689Skan  [(set (match_operand:V4SF 0 "memory_operand" "=m")
227169689Skan	(unspec:V4SF [(match_operand:V4SF 1 "register_operand" "x")]
228169689Skan		     UNSPEC_MOVNT))]
229169689Skan  "TARGET_SSE"
230169689Skan  "movntps\t{%1, %0|%0, %1}"
231169689Skan  [(set_attr "type" "ssemov")
232169689Skan   (set_attr "mode" "V4SF")])
233169689Skan
234169689Skan(define_insn "sse2_movntv2df"
235169689Skan  [(set (match_operand:V2DF 0 "memory_operand" "=m")
236169689Skan	(unspec:V2DF [(match_operand:V2DF 1 "register_operand" "x")]
237169689Skan		     UNSPEC_MOVNT))]
238169689Skan  "TARGET_SSE2"
239169689Skan  "movntpd\t{%1, %0|%0, %1}"
240169689Skan  [(set_attr "type" "ssecvt")
241169689Skan   (set_attr "mode" "V2DF")])
242169689Skan
243169689Skan(define_insn "sse2_movntv2di"
244169689Skan  [(set (match_operand:V2DI 0 "memory_operand" "=m")
245169689Skan	(unspec:V2DI [(match_operand:V2DI 1 "register_operand" "x")]
246169689Skan		     UNSPEC_MOVNT))]
247169689Skan  "TARGET_SSE2"
248169689Skan  "movntdq\t{%1, %0|%0, %1}"
249169689Skan  [(set_attr "type" "ssecvt")
250169689Skan   (set_attr "mode" "TI")])
251169689Skan
252169689Skan(define_insn "sse2_movntsi"
253169689Skan  [(set (match_operand:SI 0 "memory_operand" "=m")
254169689Skan	(unspec:SI [(match_operand:SI 1 "register_operand" "r")]
255169689Skan		   UNSPEC_MOVNT))]
256169689Skan  "TARGET_SSE2"
257169689Skan  "movnti\t{%1, %0|%0, %1}"
258169689Skan  [(set_attr "type" "ssecvt")
259169689Skan   (set_attr "mode" "V2DF")])
260169689Skan
261169689Skan(define_insn "sse3_lddqu"
262169689Skan  [(set (match_operand:V16QI 0 "register_operand" "=x")
263169689Skan	(unspec:V16QI [(match_operand:V16QI 1 "memory_operand" "m")]
264169689Skan		      UNSPEC_LDQQU))]
265169689Skan  "TARGET_SSE3"
266169689Skan  "lddqu\t{%1, %0|%0, %1}"
267169689Skan  [(set_attr "type" "ssecvt")
268169689Skan   (set_attr "mode" "TI")])
269169689Skan
270169689Skan;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
271169689Skan;;
272169689Skan;; Parallel single-precision floating point arithmetic
273169689Skan;;
274169689Skan;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
275169689Skan
276169689Skan(define_expand "negv4sf2"
277169689Skan  [(set (match_operand:V4SF 0 "register_operand" "")
278169689Skan	(neg:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "")))]
279169689Skan  "TARGET_SSE"
280169689Skan  "ix86_expand_fp_absneg_operator (NEG, V4SFmode, operands); DONE;")
281169689Skan
282169689Skan(define_expand "absv4sf2"
283169689Skan  [(set (match_operand:V4SF 0 "register_operand" "")
284169689Skan	(abs:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "")))]
285169689Skan  "TARGET_SSE"
286169689Skan  "ix86_expand_fp_absneg_operator (ABS, V4SFmode, operands); DONE;")
287169689Skan
288169689Skan(define_expand "addv4sf3"
289169689Skan  [(set (match_operand:V4SF 0 "register_operand" "")
290169689Skan	(plus:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "")
291169689Skan		   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
292169689Skan  "TARGET_SSE"
293169689Skan  "ix86_fixup_binary_operands_no_copy (PLUS, V4SFmode, operands);")
294169689Skan
295169689Skan(define_insn "*addv4sf3"
296169689Skan  [(set (match_operand:V4SF 0 "register_operand" "=x")
297169689Skan	(plus:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
298169689Skan		   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
299169689Skan  "TARGET_SSE && ix86_binary_operator_ok (PLUS, V4SFmode, operands)"
300169689Skan  "addps\t{%2, %0|%0, %2}"
301169689Skan  [(set_attr "type" "sseadd")
302169689Skan   (set_attr "mode" "V4SF")])
303169689Skan
304169689Skan(define_insn "sse_vmaddv4sf3"
305169689Skan  [(set (match_operand:V4SF 0 "register_operand" "=x")
306169689Skan	(vec_merge:V4SF
307169689Skan	  (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
308169689Skan		     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
309169689Skan	  (match_dup 1)
310169689Skan	  (const_int 1)))]
311169689Skan  "TARGET_SSE && ix86_binary_operator_ok (PLUS, V4SFmode, operands)"
312169689Skan  "addss\t{%2, %0|%0, %2}"
313169689Skan  [(set_attr "type" "sseadd")
314169689Skan   (set_attr "mode" "SF")])
315169689Skan
316169689Skan(define_expand "subv4sf3"
317169689Skan  [(set (match_operand:V4SF 0 "register_operand" "")
318169689Skan	(minus:V4SF (match_operand:V4SF 1 "register_operand" "")
319169689Skan		    (match_operand:V4SF 2 "nonimmediate_operand" "")))]
320169689Skan  "TARGET_SSE"
321169689Skan  "ix86_fixup_binary_operands_no_copy (MINUS, V4SFmode, operands);")
322169689Skan
323169689Skan(define_insn "*subv4sf3"
324169689Skan  [(set (match_operand:V4SF 0 "register_operand" "=x")
325169689Skan	(minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
326169689Skan		    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
327169689Skan  "TARGET_SSE"
328169689Skan  "subps\t{%2, %0|%0, %2}"
329169689Skan  [(set_attr "type" "sseadd")
330169689Skan   (set_attr "mode" "V4SF")])
331169689Skan
332169689Skan(define_insn "sse_vmsubv4sf3"
333169689Skan  [(set (match_operand:V4SF 0 "register_operand" "=x")
334169689Skan	(vec_merge:V4SF
335169689Skan	  (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
336169689Skan		      (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
337169689Skan	  (match_dup 1)
338169689Skan	  (const_int 1)))]
339169689Skan  "TARGET_SSE"
340169689Skan  "subss\t{%2, %0|%0, %2}"
341169689Skan  [(set_attr "type" "sseadd")
342169689Skan   (set_attr "mode" "SF")])
343169689Skan
344169689Skan(define_expand "mulv4sf3"
345169689Skan  [(set (match_operand:V4SF 0 "register_operand" "")
346169689Skan	(mult:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "")
347169689Skan		   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
348169689Skan  "TARGET_SSE"
349169689Skan  "ix86_fixup_binary_operands_no_copy (MULT, V4SFmode, operands);")
350169689Skan
351169689Skan(define_insn "*mulv4sf3"
352169689Skan  [(set (match_operand:V4SF 0 "register_operand" "=x")
353169689Skan	(mult:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
354169689Skan		   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
355169689Skan  "TARGET_SSE && ix86_binary_operator_ok (MULT, V4SFmode, operands)"
356169689Skan  "mulps\t{%2, %0|%0, %2}"
357169689Skan  [(set_attr "type" "ssemul")
358169689Skan   (set_attr "mode" "V4SF")])
359169689Skan
360169689Skan(define_insn "sse_vmmulv4sf3"
361169689Skan  [(set (match_operand:V4SF 0 "register_operand" "=x")
362169689Skan	(vec_merge:V4SF
363169689Skan	  (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
364169689Skan		     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
365169689Skan	  (match_dup 1)
366169689Skan	  (const_int 1)))]
367169689Skan  "TARGET_SSE && ix86_binary_operator_ok (MULT, V4SFmode, operands)"
368169689Skan  "mulss\t{%2, %0|%0, %2}"
369169689Skan  [(set_attr "type" "ssemul")
370169689Skan   (set_attr "mode" "SF")])
371169689Skan
372169689Skan(define_expand "divv4sf3"
373169689Skan  [(set (match_operand:V4SF 0 "register_operand" "")
374169689Skan	(div:V4SF (match_operand:V4SF 1 "register_operand" "")
375169689Skan		  (match_operand:V4SF 2 "nonimmediate_operand" "")))]
376169689Skan  "TARGET_SSE"
377169689Skan  "ix86_fixup_binary_operands_no_copy (DIV, V4SFmode, operands);")
378169689Skan
379169689Skan(define_insn "*divv4sf3"
380169689Skan  [(set (match_operand:V4SF 0 "register_operand" "=x")
381169689Skan	(div:V4SF (match_operand:V4SF 1 "register_operand" "0")
382169689Skan		  (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
383169689Skan  "TARGET_SSE"
384169689Skan  "divps\t{%2, %0|%0, %2}"
385169689Skan  [(set_attr "type" "ssediv")
386169689Skan   (set_attr "mode" "V4SF")])
387169689Skan
388169689Skan(define_insn "sse_vmdivv4sf3"
389169689Skan  [(set (match_operand:V4SF 0 "register_operand" "=x")
390169689Skan	(vec_merge:V4SF
391169689Skan	  (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
392169689Skan		    (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
393169689Skan	  (match_dup 1)
394169689Skan	  (const_int 1)))]
395169689Skan  "TARGET_SSE"
396169689Skan  "divss\t{%2, %0|%0, %2}"
397169689Skan  [(set_attr "type" "ssediv")
398169689Skan   (set_attr "mode" "SF")])
399169689Skan
400169689Skan(define_insn "sse_rcpv4sf2"
401169689Skan  [(set (match_operand:V4SF 0 "register_operand" "=x")
402169689Skan	(unspec:V4SF
403169689Skan	 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RCP))]
404169689Skan  "TARGET_SSE"
405169689Skan  "rcpps\t{%1, %0|%0, %1}"
406169689Skan  [(set_attr "type" "sse")
407169689Skan   (set_attr "mode" "V4SF")])
408169689Skan
409169689Skan(define_insn "sse_vmrcpv4sf2"
410169689Skan  [(set (match_operand:V4SF 0 "register_operand" "=x")
411169689Skan	(vec_merge:V4SF
412169689Skan	  (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
413169689Skan		       UNSPEC_RCP)
414169689Skan	  (match_operand:V4SF 2 "register_operand" "0")
415169689Skan	  (const_int 1)))]
416169689Skan  "TARGET_SSE"
417169689Skan  "rcpss\t{%1, %0|%0, %1}"
418169689Skan  [(set_attr "type" "sse")
419169689Skan   (set_attr "mode" "SF")])
420169689Skan
421169689Skan(define_insn "sse_rsqrtv4sf2"
422169689Skan  [(set (match_operand:V4SF 0 "register_operand" "=x")
423169689Skan	(unspec:V4SF
424169689Skan	  [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RSQRT))]
425169689Skan  "TARGET_SSE"
426169689Skan  "rsqrtps\t{%1, %0|%0, %1}"
427169689Skan  [(set_attr "type" "sse")
428169689Skan   (set_attr "mode" "V4SF")])
429169689Skan
430169689Skan(define_insn "sse_vmrsqrtv4sf2"
431169689Skan  [(set (match_operand:V4SF 0 "register_operand" "=x")
432169689Skan	(vec_merge:V4SF
433169689Skan	  (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
434169689Skan		       UNSPEC_RSQRT)
435169689Skan	  (match_operand:V4SF 2 "register_operand" "0")
436169689Skan	  (const_int 1)))]
437169689Skan  "TARGET_SSE"
438169689Skan  "rsqrtss\t{%1, %0|%0, %1}"
439169689Skan  [(set_attr "type" "sse")
440169689Skan   (set_attr "mode" "SF")])
441169689Skan
442169689Skan(define_insn "sqrtv4sf2"
443169689Skan  [(set (match_operand:V4SF 0 "register_operand" "=x")
444169689Skan	(sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
445169689Skan  "TARGET_SSE"
446169689Skan  "sqrtps\t{%1, %0|%0, %1}"
447169689Skan  [(set_attr "type" "sse")
448169689Skan   (set_attr "mode" "V4SF")])
449169689Skan
450169689Skan(define_insn "sse_vmsqrtv4sf2"
451169689Skan  [(set (match_operand:V4SF 0 "register_operand" "=x")
452169689Skan	(vec_merge:V4SF
453169689Skan	  (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
454169689Skan	  (match_operand:V4SF 2 "register_operand" "0")
455169689Skan	  (const_int 1)))]
456169689Skan  "TARGET_SSE"
457169689Skan  "sqrtss\t{%1, %0|%0, %1}"
458169689Skan  [(set_attr "type" "sse")
459169689Skan   (set_attr "mode" "SF")])
460169689Skan
461169689Skan;; ??? For !flag_finite_math_only, the representation with SMIN/SMAX
462169689Skan;; isn't really correct, as those rtl operators aren't defined when 
463169689Skan;; applied to NaNs.  Hopefully the optimizers won't get too smart on us.
464169689Skan
465169689Skan(define_expand "smaxv4sf3"
466169689Skan  [(set (match_operand:V4SF 0 "register_operand" "")
467169689Skan	(smax:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "")
468169689Skan		   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
469169689Skan  "TARGET_SSE"
470169689Skan{
471169689Skan  if (!flag_finite_math_only)
472169689Skan    operands[1] = force_reg (V4SFmode, operands[1]);
473169689Skan  ix86_fixup_binary_operands_no_copy (SMAX, V4SFmode, operands);
474169689Skan})
475169689Skan
476169689Skan(define_insn "*smaxv4sf3_finite"
477169689Skan  [(set (match_operand:V4SF 0 "register_operand" "=x")
478169689Skan	(smax:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
479169689Skan		   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
480169689Skan  "TARGET_SSE && flag_finite_math_only
481169689Skan   && ix86_binary_operator_ok (SMAX, V4SFmode, operands)"
482169689Skan  "maxps\t{%2, %0|%0, %2}"
483169689Skan  [(set_attr "type" "sse")
484169689Skan   (set_attr "mode" "V4SF")])
485169689Skan
486169689Skan(define_insn "*smaxv4sf3"
487169689Skan  [(set (match_operand:V4SF 0 "register_operand" "=x")
488169689Skan	(smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
489169689Skan		   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
490169689Skan  "TARGET_SSE"
491169689Skan  "maxps\t{%2, %0|%0, %2}"
492169689Skan  [(set_attr "type" "sse")
493169689Skan   (set_attr "mode" "V4SF")])
494169689Skan
495169689Skan(define_insn "sse_vmsmaxv4sf3"
496169689Skan  [(set (match_operand:V4SF 0 "register_operand" "=x")
497169689Skan	(vec_merge:V4SF
498169689Skan	 (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
499169689Skan		    (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
500169689Skan	 (match_dup 1)
501169689Skan	 (const_int 1)))]
502169689Skan  "TARGET_SSE"
503169689Skan  "maxss\t{%2, %0|%0, %2}"
504169689Skan  [(set_attr "type" "sse")
505169689Skan   (set_attr "mode" "SF")])
506169689Skan
507169689Skan(define_expand "sminv4sf3"
508169689Skan  [(set (match_operand:V4SF 0 "register_operand" "")
509169689Skan	(smin:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "")
510169689Skan		   (match_operand:V4SF 2 "nonimmediate_operand" "")))]
511169689Skan  "TARGET_SSE"
512169689Skan{
513169689Skan  if (!flag_finite_math_only)
514169689Skan    operands[1] = force_reg (V4SFmode, operands[1]);
515169689Skan  ix86_fixup_binary_operands_no_copy (SMIN, V4SFmode, operands);
516169689Skan})
517169689Skan
518169689Skan(define_insn "*sminv4sf3_finite"
519169689Skan  [(set (match_operand:V4SF 0 "register_operand" "=x")
520169689Skan	(smin:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
521169689Skan		   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
522169689Skan  "TARGET_SSE && flag_finite_math_only
523169689Skan   && ix86_binary_operator_ok (SMIN, V4SFmode, operands)"
524169689Skan  "minps\t{%2, %0|%0, %2}"
525169689Skan  [(set_attr "type" "sse")
526169689Skan   (set_attr "mode" "V4SF")])
527169689Skan
528169689Skan(define_insn "*sminv4sf3"
529169689Skan  [(set (match_operand:V4SF 0 "register_operand" "=x")
530169689Skan	(smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
531169689Skan		   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
532169689Skan  "TARGET_SSE"
533169689Skan  "minps\t{%2, %0|%0, %2}"
534169689Skan  [(set_attr "type" "sse")
535169689Skan   (set_attr "mode" "V4SF")])
536169689Skan
537169689Skan(define_insn "sse_vmsminv4sf3"
538169689Skan  [(set (match_operand:V4SF 0 "register_operand" "=x")
539169689Skan	(vec_merge:V4SF
540169689Skan	 (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
541169689Skan		    (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
542169689Skan	 (match_dup 1)
543169689Skan	 (const_int 1)))]
544169689Skan  "TARGET_SSE"
545169689Skan  "minss\t{%2, %0|%0, %2}"
546169689Skan  [(set_attr "type" "sse")
547169689Skan   (set_attr "mode" "SF")])
548169689Skan
549169689Skan;; These versions of the min/max patterns implement exactly the operations
550169689Skan;;   min = (op1 < op2 ? op1 : op2)
551169689Skan;;   max = (!(op1 < op2) ? op1 : op2)
552169689Skan;; Their operands are not commutative, and thus they may be used in the
553169689Skan;; presence of -0.0 and NaN.
554169689Skan
555169689Skan(define_insn "*ieee_sminv4sf3"
556169689Skan  [(set (match_operand:V4SF 0 "register_operand" "=x")
557169689Skan	(unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
558169689Skan		      (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
559169689Skan		     UNSPEC_IEEE_MIN))]
560169689Skan  "TARGET_SSE"
561169689Skan  "minps\t{%2, %0|%0, %2}"
562169689Skan  [(set_attr "type" "sseadd")
563169689Skan   (set_attr "mode" "V4SF")])
564169689Skan
565169689Skan(define_insn "*ieee_smaxv4sf3"
566169689Skan  [(set (match_operand:V4SF 0 "register_operand" "=x")
567169689Skan	(unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
568169689Skan		      (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
569169689Skan		     UNSPEC_IEEE_MAX))]
570169689Skan  "TARGET_SSE"
571169689Skan  "maxps\t{%2, %0|%0, %2}"
572169689Skan  [(set_attr "type" "sseadd")
573169689Skan   (set_attr "mode" "V4SF")])
574169689Skan
575169689Skan(define_insn "*ieee_sminv2df3"
576169689Skan  [(set (match_operand:V2DF 0 "register_operand" "=x")
577169689Skan	(unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
578169689Skan		      (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
579169689Skan		     UNSPEC_IEEE_MIN))]
580169689Skan  "TARGET_SSE2"
581169689Skan  "minpd\t{%2, %0|%0, %2}"
582169689Skan  [(set_attr "type" "sseadd")
583169689Skan   (set_attr "mode" "V2DF")])
584169689Skan
585169689Skan(define_insn "*ieee_smaxv2df3"
586169689Skan  [(set (match_operand:V2DF 0 "register_operand" "=x")
587169689Skan	(unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
588169689Skan		      (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
589169689Skan		     UNSPEC_IEEE_MAX))]
590169689Skan  "TARGET_SSE2"
591169689Skan  "maxpd\t{%2, %0|%0, %2}"
592169689Skan  [(set_attr "type" "sseadd")
593169689Skan   (set_attr "mode" "V2DF")])
594169689Skan
595169689Skan(define_insn "sse3_addsubv4sf3"
596169689Skan  [(set (match_operand:V4SF 0 "register_operand" "=x")
597169689Skan	(vec_merge:V4SF
598169689Skan	  (plus:V4SF
599169689Skan	    (match_operand:V4SF 1 "register_operand" "0")
600169689Skan	    (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
601169689Skan	  (minus:V4SF (match_dup 1) (match_dup 2))
602169689Skan	  (const_int 5)))]
603169689Skan  "TARGET_SSE3"
604169689Skan  "addsubps\t{%2, %0|%0, %2}"
605169689Skan  [(set_attr "type" "sseadd")
606169689Skan   (set_attr "mode" "V4SF")])
607169689Skan
608169689Skan(define_insn "sse3_haddv4sf3"
609169689Skan  [(set (match_operand:V4SF 0 "register_operand" "=x")
610169689Skan	(vec_concat:V4SF
611169689Skan	  (vec_concat:V2SF
612169689Skan	    (plus:SF
613169689Skan	      (vec_select:SF 
614169689Skan		(match_operand:V4SF 1 "register_operand" "0")
615169689Skan		(parallel [(const_int 0)]))
616169689Skan	      (vec_select:SF (match_dup 1) (parallel [(const_int 1)])))
617169689Skan	    (plus:SF
618169689Skan	      (vec_select:SF (match_dup 1) (parallel [(const_int 2)]))
619169689Skan	      (vec_select:SF (match_dup 1) (parallel [(const_int 3)]))))
620169689Skan	  (vec_concat:V2SF
621169689Skan	    (plus:SF
622169689Skan	      (vec_select:SF
623169689Skan		(match_operand:V4SF 2 "nonimmediate_operand" "xm")
624169689Skan		(parallel [(const_int 0)]))
625169689Skan	      (vec_select:SF (match_dup 2) (parallel [(const_int 1)])))
626169689Skan	    (plus:SF
627169689Skan	      (vec_select:SF (match_dup 2) (parallel [(const_int 2)]))
628169689Skan	      (vec_select:SF (match_dup 2) (parallel [(const_int 3)]))))))]
629169689Skan  "TARGET_SSE3"
630169689Skan  "haddps\t{%2, %0|%0, %2}"
631169689Skan  [(set_attr "type" "sseadd")
632169689Skan   (set_attr "mode" "V4SF")])
633169689Skan
634169689Skan(define_insn "sse3_hsubv4sf3"
635169689Skan  [(set (match_operand:V4SF 0 "register_operand" "=x")
636169689Skan	(vec_concat:V4SF
637169689Skan	  (vec_concat:V2SF
638169689Skan	    (minus:SF
639169689Skan	      (vec_select:SF 
640169689Skan		(match_operand:V4SF 1 "register_operand" "0")
641169689Skan		(parallel [(const_int 0)]))
642169689Skan	      (vec_select:SF (match_dup 1) (parallel [(const_int 1)])))
643169689Skan	    (minus:SF
644169689Skan	      (vec_select:SF (match_dup 1) (parallel [(const_int 2)]))
645169689Skan	      (vec_select:SF (match_dup 1) (parallel [(const_int 3)]))))
646169689Skan	  (vec_concat:V2SF
647169689Skan	    (minus:SF
648169689Skan	      (vec_select:SF
649169689Skan		(match_operand:V4SF 2 "nonimmediate_operand" "xm")
650169689Skan		(parallel [(const_int 0)]))
651169689Skan	      (vec_select:SF (match_dup 2) (parallel [(const_int 1)])))
652169689Skan	    (minus:SF
653169689Skan	      (vec_select:SF (match_dup 2) (parallel [(const_int 2)]))
654169689Skan	      (vec_select:SF (match_dup 2) (parallel [(const_int 3)]))))))]
655169689Skan  "TARGET_SSE3"
656169689Skan  "hsubps\t{%2, %0|%0, %2}"
657169689Skan  [(set_attr "type" "sseadd")
658169689Skan   (set_attr "mode" "V4SF")])
659169689Skan
660169689Skan(define_expand "reduc_splus_v4sf"
661169689Skan  [(match_operand:V4SF 0 "register_operand" "")
662169689Skan   (match_operand:V4SF 1 "register_operand" "")]
663169689Skan  "TARGET_SSE"
664169689Skan{
665169689Skan  if (TARGET_SSE3)
666169689Skan    {
667169689Skan      rtx tmp = gen_reg_rtx (V4SFmode);
668169689Skan      emit_insn (gen_sse3_haddv4sf3 (tmp, operands[1], operands[1]));
669169689Skan      emit_insn (gen_sse3_haddv4sf3 (operands[0], tmp, tmp));
670169689Skan    }
671169689Skan  else
672169689Skan    ix86_expand_reduc_v4sf (gen_addv4sf3, operands[0], operands[1]);
673169689Skan  DONE;
674169689Skan})
675169689Skan
676169689Skan(define_expand "reduc_smax_v4sf"
677169689Skan  [(match_operand:V4SF 0 "register_operand" "")
678169689Skan   (match_operand:V4SF 1 "register_operand" "")]
679169689Skan  "TARGET_SSE"
680169689Skan{
681169689Skan  ix86_expand_reduc_v4sf (gen_smaxv4sf3, operands[0], operands[1]);
682169689Skan  DONE;
683169689Skan})
684169689Skan
685169689Skan(define_expand "reduc_smin_v4sf"
686169689Skan  [(match_operand:V4SF 0 "register_operand" "")
687169689Skan   (match_operand:V4SF 1 "register_operand" "")]
688169689Skan  "TARGET_SSE"
689169689Skan{
690169689Skan  ix86_expand_reduc_v4sf (gen_sminv4sf3, operands[0], operands[1]);
691169689Skan  DONE;
692169689Skan})
693169689Skan
694169689Skan;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
695169689Skan;;
696169689Skan;; Parallel single-precision floating point comparisons
697169689Skan;;
698169689Skan;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
699169689Skan
700169689Skan(define_insn "sse_maskcmpv4sf3"
701169689Skan  [(set (match_operand:V4SF 0 "register_operand" "=x")
702169689Skan	(match_operator:V4SF 3 "sse_comparison_operator"
703169689Skan		[(match_operand:V4SF 1 "register_operand" "0")
704169689Skan		 (match_operand:V4SF 2 "nonimmediate_operand" "xm")]))]
705169689Skan  "TARGET_SSE"
706169689Skan  "cmp%D3ps\t{%2, %0|%0, %2}"
707169689Skan  [(set_attr "type" "ssecmp")
708169689Skan   (set_attr "mode" "V4SF")])
709169689Skan
710169689Skan(define_insn "sse_vmmaskcmpv4sf3"
711169689Skan  [(set (match_operand:V4SF 0 "register_operand" "=x")
712169689Skan	(vec_merge:V4SF
713169689Skan	 (match_operator:V4SF 3 "sse_comparison_operator"
714169689Skan		[(match_operand:V4SF 1 "register_operand" "0")
715169689Skan		 (match_operand:V4SF 2 "register_operand" "x")])
716169689Skan	 (match_dup 1)
717169689Skan	 (const_int 1)))]
718169689Skan  "TARGET_SSE"
719169689Skan  "cmp%D3ss\t{%2, %0|%0, %2}"
720169689Skan  [(set_attr "type" "ssecmp")
721169689Skan   (set_attr "mode" "SF")])
722169689Skan
723169689Skan(define_insn "sse_comi"
724169689Skan  [(set (reg:CCFP FLAGS_REG)
725169689Skan	(compare:CCFP
726169689Skan	  (vec_select:SF
727169689Skan	    (match_operand:V4SF 0 "register_operand" "x")
728169689Skan	    (parallel [(const_int 0)]))
729169689Skan	  (vec_select:SF
730169689Skan	    (match_operand:V4SF 1 "nonimmediate_operand" "xm")
731169689Skan	    (parallel [(const_int 0)]))))]
732169689Skan  "TARGET_SSE"
733169689Skan  "comiss\t{%1, %0|%0, %1}"
734169689Skan  [(set_attr "type" "ssecomi")
735169689Skan   (set_attr "mode" "SF")])
736169689Skan
737169689Skan(define_insn "sse_ucomi"
738169689Skan  [(set (reg:CCFPU FLAGS_REG)
739169689Skan	(compare:CCFPU
740169689Skan	  (vec_select:SF
741169689Skan	    (match_operand:V4SF 0 "register_operand" "x")
742169689Skan	    (parallel [(const_int 0)]))
743169689Skan	  (vec_select:SF
744169689Skan	    (match_operand:V4SF 1 "nonimmediate_operand" "xm")
745169689Skan	    (parallel [(const_int 0)]))))]
746169689Skan  "TARGET_SSE"
747169689Skan  "ucomiss\t{%1, %0|%0, %1}"
748169689Skan  [(set_attr "type" "ssecomi")
749169689Skan   (set_attr "mode" "SF")])
750169689Skan
751169689Skan(define_expand "vcondv4sf"
752169689Skan  [(set (match_operand:V4SF 0 "register_operand" "")
753169689Skan        (if_then_else:V4SF
754169689Skan          (match_operator 3 ""
755169689Skan            [(match_operand:V4SF 4 "nonimmediate_operand" "")
756169689Skan             (match_operand:V4SF 5 "nonimmediate_operand" "")])
757169689Skan          (match_operand:V4SF 1 "general_operand" "")
758169689Skan          (match_operand:V4SF 2 "general_operand" "")))]
759169689Skan  "TARGET_SSE"
760169689Skan{
761169689Skan  if (ix86_expand_fp_vcond (operands))
762169689Skan    DONE;
763169689Skan  else
764169689Skan    FAIL;
765169689Skan})
766169689Skan
767169689Skan;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
768169689Skan;;
769169689Skan;; Parallel single-precision floating point logical operations
770169689Skan;;
771169689Skan;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
772169689Skan
773169689Skan(define_expand "andv4sf3"
774169689Skan  [(set (match_operand:V4SF 0 "register_operand" "")
775169689Skan	(and:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "")
776169689Skan		  (match_operand:V4SF 2 "nonimmediate_operand" "")))]
777169689Skan  "TARGET_SSE"
778169689Skan  "ix86_fixup_binary_operands_no_copy (AND, V4SFmode, operands);")
779169689Skan
780169689Skan(define_insn "*andv4sf3"
781169689Skan  [(set (match_operand:V4SF 0 "register_operand" "=x")
782169689Skan	(and:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
783169689Skan		  (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
784169689Skan  "TARGET_SSE && ix86_binary_operator_ok (AND, V4SFmode, operands)"
785169689Skan  "andps\t{%2, %0|%0, %2}"
786169689Skan  [(set_attr "type" "sselog")
787169689Skan   (set_attr "mode" "V4SF")])
788169689Skan
789169689Skan(define_insn "sse_nandv4sf3"
790169689Skan  [(set (match_operand:V4SF 0 "register_operand" "=x")
791169689Skan	(and:V4SF (not:V4SF (match_operand:V4SF 1 "register_operand" "0"))
792169689Skan		  (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
793169689Skan  "TARGET_SSE"
794169689Skan  "andnps\t{%2, %0|%0, %2}"
795169689Skan  [(set_attr "type" "sselog")
796169689Skan   (set_attr "mode" "V4SF")])
797169689Skan
798169689Skan(define_expand "iorv4sf3"
799169689Skan  [(set (match_operand:V4SF 0 "register_operand" "")
800169689Skan	(ior:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "")
801169689Skan		  (match_operand:V4SF 2 "nonimmediate_operand" "")))]
802169689Skan  "TARGET_SSE"
803169689Skan  "ix86_fixup_binary_operands_no_copy (IOR, V4SFmode, operands);")
804169689Skan
805169689Skan(define_insn "*iorv4sf3"
806169689Skan  [(set (match_operand:V4SF 0 "register_operand" "=x")
807169689Skan	(ior:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
808169689Skan		  (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
809169689Skan  "TARGET_SSE && ix86_binary_operator_ok (IOR, V4SFmode, operands)"
810169689Skan  "orps\t{%2, %0|%0, %2}"
811169689Skan  [(set_attr "type" "sselog")
812169689Skan   (set_attr "mode" "V4SF")])
813169689Skan
814169689Skan(define_expand "xorv4sf3"
815169689Skan  [(set (match_operand:V4SF 0 "register_operand" "")
816169689Skan	(xor:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "")
817169689Skan		  (match_operand:V4SF 2 "nonimmediate_operand" "")))]
818169689Skan  "TARGET_SSE"
819169689Skan  "ix86_fixup_binary_operands_no_copy (XOR, V4SFmode, operands);")
820169689Skan
821169689Skan(define_insn "*xorv4sf3"
822169689Skan  [(set (match_operand:V4SF 0 "register_operand" "=x")
823169689Skan	(xor:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
824169689Skan		  (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
825169689Skan  "TARGET_SSE && ix86_binary_operator_ok (XOR, V4SFmode, operands)"
826169689Skan  "xorps\t{%2, %0|%0, %2}"
827169689Skan  [(set_attr "type" "sselog")
828169689Skan   (set_attr "mode" "V4SF")])
829169689Skan
830169689Skan;; Also define scalar versions.  These are used for abs, neg, and
831169689Skan;; conditional move.  Using subregs into vector modes causes register
832169689Skan;; allocation lossage.  These patterns do not allow memory operands
833169689Skan;; because the native instructions read the full 128-bits.
834169689Skan
835169689Skan(define_insn "*andsf3"
836169689Skan  [(set (match_operand:SF 0 "register_operand" "=x")
837169689Skan	(and:SF (match_operand:SF 1 "register_operand" "0")
838169689Skan		(match_operand:SF 2 "register_operand" "x")))]
839169689Skan  "TARGET_SSE"
840169689Skan  "andps\t{%2, %0|%0, %2}"
841169689Skan  [(set_attr "type" "sselog")
842169689Skan   (set_attr "mode" "V4SF")])
843169689Skan
844169689Skan(define_insn "*nandsf3"
845169689Skan  [(set (match_operand:SF 0 "register_operand" "=x")
846169689Skan	(and:SF (not:SF (match_operand:SF 1 "register_operand" "0"))
847169689Skan		(match_operand:SF 2 "register_operand" "x")))]
848169689Skan  "TARGET_SSE"
849169689Skan  "andnps\t{%2, %0|%0, %2}"
850169689Skan  [(set_attr "type" "sselog")
851169689Skan   (set_attr "mode" "V4SF")])
852169689Skan
853169689Skan(define_insn "*iorsf3"
854169689Skan  [(set (match_operand:SF 0 "register_operand" "=x")
855169689Skan	(ior:SF (match_operand:SF 1 "register_operand" "0")
856169689Skan		(match_operand:SF 2 "register_operand" "x")))]
857169689Skan  "TARGET_SSE"
858169689Skan  "orps\t{%2, %0|%0, %2}"
859169689Skan  [(set_attr "type" "sselog")
860169689Skan   (set_attr "mode" "V4SF")])
861169689Skan
862169689Skan(define_insn "*xorsf3"
863169689Skan  [(set (match_operand:SF 0 "register_operand" "=x")
864169689Skan	(xor:SF (match_operand:SF 1 "register_operand" "0")
865169689Skan		(match_operand:SF 2 "register_operand" "x")))]
866169689Skan  "TARGET_SSE"
867169689Skan  "xorps\t{%2, %0|%0, %2}"
868169689Skan  [(set_attr "type" "sselog")
869169689Skan   (set_attr "mode" "V4SF")])
870169689Skan
871169689Skan;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
872169689Skan;;
873169689Skan;; Parallel single-precision floating point conversion operations
874169689Skan;;
875169689Skan;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
876169689Skan
877169689Skan(define_insn "sse_cvtpi2ps"
878169689Skan  [(set (match_operand:V4SF 0 "register_operand" "=x")
879169689Skan	(vec_merge:V4SF
880169689Skan	  (vec_duplicate:V4SF
881169689Skan	    (float:V2SF (match_operand:V2SI 2 "nonimmediate_operand" "ym")))
882169689Skan	  (match_operand:V4SF 1 "register_operand" "0")
883169689Skan	  (const_int 3)))]
884169689Skan  "TARGET_SSE"
885169689Skan  "cvtpi2ps\t{%2, %0|%0, %2}"
886169689Skan  [(set_attr "type" "ssecvt")
887169689Skan   (set_attr "mode" "V4SF")])
888169689Skan
889169689Skan(define_insn "sse_cvtps2pi"
890169689Skan  [(set (match_operand:V2SI 0 "register_operand" "=y")
891169689Skan	(vec_select:V2SI
892169689Skan	  (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
893169689Skan		       UNSPEC_FIX_NOTRUNC)
894169689Skan	  (parallel [(const_int 0) (const_int 1)])))]
895169689Skan  "TARGET_SSE"
896169689Skan  "cvtps2pi\t{%1, %0|%0, %1}"
897169689Skan  [(set_attr "type" "ssecvt")
898169689Skan   (set_attr "unit" "mmx")
899169689Skan   (set_attr "mode" "DI")])
900169689Skan
901169689Skan(define_insn "sse_cvttps2pi"
902169689Skan  [(set (match_operand:V2SI 0 "register_operand" "=y")
903169689Skan	(vec_select:V2SI
904169689Skan	  (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
905169689Skan	  (parallel [(const_int 0) (const_int 1)])))]
906169689Skan  "TARGET_SSE"
907169689Skan  "cvttps2pi\t{%1, %0|%0, %1}"
908169689Skan  [(set_attr "type" "ssecvt")
909169689Skan   (set_attr "unit" "mmx")
910169689Skan   (set_attr "mode" "SF")])
911169689Skan
912169689Skan(define_insn "sse_cvtsi2ss"
913169689Skan  [(set (match_operand:V4SF 0 "register_operand" "=x,x")
914169689Skan	(vec_merge:V4SF
915169689Skan	  (vec_duplicate:V4SF
916169689Skan	    (float:SF (match_operand:SI 2 "nonimmediate_operand" "r,m")))
917169689Skan	  (match_operand:V4SF 1 "register_operand" "0,0")
918169689Skan	  (const_int 1)))]
919169689Skan  "TARGET_SSE"
920169689Skan  "cvtsi2ss\t{%2, %0|%0, %2}"
921169689Skan  [(set_attr "type" "sseicvt")
922169689Skan   (set_attr "athlon_decode" "vector,double")
923252080Spfg   (set_attr "amdfam10_decode" "vector,double")
924169689Skan   (set_attr "mode" "SF")])
925169689Skan
926169689Skan(define_insn "sse_cvtsi2ssq"
927169689Skan  [(set (match_operand:V4SF 0 "register_operand" "=x,x")
928169689Skan	(vec_merge:V4SF
929169689Skan	  (vec_duplicate:V4SF
930169689Skan	    (float:SF (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
931169689Skan	  (match_operand:V4SF 1 "register_operand" "0,0")
932169689Skan	  (const_int 1)))]
933169689Skan  "TARGET_SSE && TARGET_64BIT"
934169689Skan  "cvtsi2ssq\t{%2, %0|%0, %2}"
935169689Skan  [(set_attr "type" "sseicvt")
936169689Skan   (set_attr "athlon_decode" "vector,double")
937252080Spfg   (set_attr "amdfam10_decode" "vector,double")
938169689Skan   (set_attr "mode" "SF")])
939169689Skan
940169689Skan(define_insn "sse_cvtss2si"
941169689Skan  [(set (match_operand:SI 0 "register_operand" "=r,r")
942169689Skan	(unspec:SI
943169689Skan	  [(vec_select:SF
944169689Skan	     (match_operand:V4SF 1 "nonimmediate_operand" "x,m")
945169689Skan	     (parallel [(const_int 0)]))]
946169689Skan	  UNSPEC_FIX_NOTRUNC))]
947169689Skan  "TARGET_SSE"
948169689Skan  "cvtss2si\t{%1, %0|%0, %1}"
949169689Skan  [(set_attr "type" "sseicvt")
950169689Skan   (set_attr "athlon_decode" "double,vector")
951252080Spfg   (set_attr "amdfam10_decode" "double,double")
952169689Skan   (set_attr "mode" "SI")])
953169689Skan
954169689Skan(define_insn "sse_cvtss2siq"
955169689Skan  [(set (match_operand:DI 0 "register_operand" "=r,r")
956169689Skan	(unspec:DI
957169689Skan	  [(vec_select:SF
958169689Skan	     (match_operand:V4SF 1 "nonimmediate_operand" "x,m")
959169689Skan	     (parallel [(const_int 0)]))]
960169689Skan	  UNSPEC_FIX_NOTRUNC))]
961169689Skan  "TARGET_SSE && TARGET_64BIT"
962169689Skan  "cvtss2siq\t{%1, %0|%0, %1}"
963169689Skan  [(set_attr "type" "sseicvt")
964169689Skan   (set_attr "athlon_decode" "double,vector")
965252080Spfg   (set_attr "amdfam10_decode" "double,double")
966169689Skan   (set_attr "mode" "DI")])
967169689Skan
968169689Skan(define_insn "sse_cvttss2si"
969169689Skan  [(set (match_operand:SI 0 "register_operand" "=r,r")
970169689Skan	(fix:SI
971169689Skan	  (vec_select:SF
972169689Skan	    (match_operand:V4SF 1 "nonimmediate_operand" "x,m")
973169689Skan	    (parallel [(const_int 0)]))))]
974169689Skan  "TARGET_SSE"
975169689Skan  "cvttss2si\t{%1, %0|%0, %1}"
976169689Skan  [(set_attr "type" "sseicvt")
977169689Skan   (set_attr "athlon_decode" "double,vector")
978252080Spfg   (set_attr "amdfam10_decode" "double,double")
979169689Skan   (set_attr "mode" "SI")])
980169689Skan
981169689Skan(define_insn "sse_cvttss2siq"
982169689Skan  [(set (match_operand:DI 0 "register_operand" "=r,r")
983169689Skan	(fix:DI
984169689Skan	  (vec_select:SF
985169689Skan	    (match_operand:V4SF 1 "nonimmediate_operand" "x,m")
986169689Skan	    (parallel [(const_int 0)]))))]
987169689Skan  "TARGET_SSE && TARGET_64BIT"
988169689Skan  "cvttss2siq\t{%1, %0|%0, %1}"
989169689Skan  [(set_attr "type" "sseicvt")
990169689Skan   (set_attr "athlon_decode" "double,vector")
991252080Spfg   (set_attr "amdfam10_decode" "double,double")
992169689Skan   (set_attr "mode" "DI")])
993169689Skan
994169689Skan(define_insn "sse2_cvtdq2ps"
995169689Skan  [(set (match_operand:V4SF 0 "register_operand" "=x")
996169689Skan	(float:V4SF (match_operand:V4SI 1 "nonimmediate_operand" "xm")))]
997169689Skan  "TARGET_SSE2"
998169689Skan  "cvtdq2ps\t{%1, %0|%0, %1}"
999169689Skan  [(set_attr "type" "ssecvt")
1000169689Skan   (set_attr "mode" "V2DF")])
1001169689Skan
1002169689Skan(define_insn "sse2_cvtps2dq"
1003169689Skan  [(set (match_operand:V4SI 0 "register_operand" "=x")
1004169689Skan	(unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
1005169689Skan		     UNSPEC_FIX_NOTRUNC))]
1006169689Skan  "TARGET_SSE2"
1007169689Skan  "cvtps2dq\t{%1, %0|%0, %1}"
1008169689Skan  [(set_attr "type" "ssecvt")
1009169689Skan   (set_attr "mode" "TI")])
1010169689Skan
1011169689Skan(define_insn "sse2_cvttps2dq"
1012169689Skan  [(set (match_operand:V4SI 0 "register_operand" "=x")
1013169689Skan	(fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
1014169689Skan  "TARGET_SSE2"
1015169689Skan  "cvttps2dq\t{%1, %0|%0, %1}"
1016169689Skan  [(set_attr "type" "ssecvt")
1017169689Skan   (set_attr "mode" "TI")])
1018169689Skan
1019169689Skan;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1020169689Skan;;
1021169689Skan;; Parallel single-precision floating point element swizzling
1022169689Skan;;
1023169689Skan;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1024169689Skan
1025169689Skan(define_insn "sse_movhlps"
1026169689Skan  [(set (match_operand:V4SF 0 "nonimmediate_operand"     "=x,x,m")
1027169689Skan	(vec_select:V4SF
1028169689Skan	  (vec_concat:V8SF
1029169689Skan	    (match_operand:V4SF 1 "nonimmediate_operand" " 0,0,0")
1030169689Skan	    (match_operand:V4SF 2 "nonimmediate_operand" " x,o,x"))
1031169689Skan	  (parallel [(const_int 6)
1032169689Skan		     (const_int 7)
1033169689Skan		     (const_int 2)
1034169689Skan		     (const_int 3)])))]
1035169689Skan  "TARGET_SSE && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
1036169689Skan  "@
1037169689Skan   movhlps\t{%2, %0|%0, %2}
1038169689Skan   movlps\t{%H2, %0|%0, %H2}
1039169689Skan   movhps\t{%2, %0|%0, %2}"
1040169689Skan  [(set_attr "type" "ssemov")
1041169689Skan   (set_attr "mode" "V4SF,V2SF,V2SF")])
1042169689Skan
1043169689Skan(define_insn "sse_movlhps"
1044169689Skan  [(set (match_operand:V4SF 0 "nonimmediate_operand"     "=x,x,o")
1045169689Skan	(vec_select:V4SF
1046169689Skan	  (vec_concat:V8SF
1047169689Skan	    (match_operand:V4SF 1 "nonimmediate_operand" " 0,0,0")
1048169689Skan	    (match_operand:V4SF 2 "nonimmediate_operand" " x,m,x"))
1049169689Skan	  (parallel [(const_int 0)
1050169689Skan		     (const_int 1)
1051169689Skan		     (const_int 4)
1052169689Skan		     (const_int 5)])))]
1053169689Skan  "TARGET_SSE && ix86_binary_operator_ok (UNKNOWN, V4SFmode, operands)"
1054169689Skan  "@
1055169689Skan   movlhps\t{%2, %0|%0, %2}
1056169689Skan   movhps\t{%2, %0|%0, %2}
1057169689Skan   movlps\t{%2, %H0|%H0, %2}"
1058169689Skan  [(set_attr "type" "ssemov")
1059169689Skan   (set_attr "mode" "V4SF,V2SF,V2SF")])
1060169689Skan
1061169689Skan(define_insn "sse_unpckhps"
1062169689Skan  [(set (match_operand:V4SF 0 "register_operand" "=x")
1063169689Skan	(vec_select:V4SF
1064169689Skan	  (vec_concat:V8SF
1065169689Skan	    (match_operand:V4SF 1 "register_operand" "0")
1066169689Skan	    (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
1067169689Skan	  (parallel [(const_int 2) (const_int 6)
1068169689Skan		     (const_int 3) (const_int 7)])))]
1069169689Skan  "TARGET_SSE"
1070169689Skan  "unpckhps\t{%2, %0|%0, %2}"
1071169689Skan  [(set_attr "type" "sselog")
1072169689Skan   (set_attr "mode" "V4SF")])
1073169689Skan
1074169689Skan(define_insn "sse_unpcklps"
1075169689Skan  [(set (match_operand:V4SF 0 "register_operand" "=x")
1076169689Skan	(vec_select:V4SF
1077169689Skan	  (vec_concat:V8SF
1078169689Skan	    (match_operand:V4SF 1 "register_operand" "0")
1079169689Skan	    (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
1080169689Skan	  (parallel [(const_int 0) (const_int 4)
1081169689Skan		     (const_int 1) (const_int 5)])))]
1082169689Skan  "TARGET_SSE"
1083169689Skan  "unpcklps\t{%2, %0|%0, %2}"
1084169689Skan  [(set_attr "type" "sselog")
1085169689Skan   (set_attr "mode" "V4SF")])
1086169689Skan
1087169689Skan;; These are modeled with the same vec_concat as the others so that we
1088169689Skan;; capture users of shufps that can use the new instructions
1089169689Skan(define_insn "sse3_movshdup"
1090169689Skan  [(set (match_operand:V4SF 0 "register_operand" "=x")
1091169689Skan	(vec_select:V4SF
1092169689Skan	  (vec_concat:V8SF
1093169689Skan	    (match_operand:V4SF 1 "nonimmediate_operand" "xm")
1094169689Skan	    (match_dup 1))
1095169689Skan	  (parallel [(const_int 1)
1096169689Skan		     (const_int 1)
1097169689Skan		     (const_int 7)
1098169689Skan		     (const_int 7)])))]
1099169689Skan  "TARGET_SSE3"
1100169689Skan  "movshdup\t{%1, %0|%0, %1}"
1101169689Skan  [(set_attr "type" "sse")
1102169689Skan   (set_attr "mode" "V4SF")])
1103169689Skan
1104169689Skan(define_insn "sse3_movsldup"
1105169689Skan  [(set (match_operand:V4SF 0 "register_operand" "=x")
1106169689Skan	(vec_select:V4SF
1107169689Skan	  (vec_concat:V8SF
1108169689Skan	    (match_operand:V4SF 1 "nonimmediate_operand" "xm")
1109169689Skan	    (match_dup 1))
1110169689Skan	  (parallel [(const_int 0)
1111169689Skan		     (const_int 0)
1112169689Skan		     (const_int 6)
1113169689Skan		     (const_int 6)])))]
1114169689Skan  "TARGET_SSE3"
1115169689Skan  "movsldup\t{%1, %0|%0, %1}"
1116169689Skan  [(set_attr "type" "sse")
1117169689Skan   (set_attr "mode" "V4SF")])
1118169689Skan
1119169689Skan(define_expand "sse_shufps"
1120169689Skan  [(match_operand:V4SF 0 "register_operand" "")
1121169689Skan   (match_operand:V4SF 1 "register_operand" "")
1122169689Skan   (match_operand:V4SF 2 "nonimmediate_operand" "")
1123169689Skan   (match_operand:SI 3 "const_int_operand" "")]
1124169689Skan  "TARGET_SSE"
1125169689Skan{
1126169689Skan  int mask = INTVAL (operands[3]);
1127169689Skan  emit_insn (gen_sse_shufps_1 (operands[0], operands[1], operands[2],
1128169689Skan			       GEN_INT ((mask >> 0) & 3),
1129169689Skan			       GEN_INT ((mask >> 2) & 3),
1130169689Skan			       GEN_INT (((mask >> 4) & 3) + 4),
1131169689Skan			       GEN_INT (((mask >> 6) & 3) + 4)));
1132169689Skan  DONE;
1133169689Skan})
1134169689Skan
1135169689Skan(define_insn "sse_shufps_1"
1136169689Skan  [(set (match_operand:V4SF 0 "register_operand" "=x")
1137169689Skan	(vec_select:V4SF
1138169689Skan	  (vec_concat:V8SF
1139169689Skan	    (match_operand:V4SF 1 "register_operand" "0")
1140169689Skan	    (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
1141169689Skan	  (parallel [(match_operand 3 "const_0_to_3_operand" "")
1142169689Skan		     (match_operand 4 "const_0_to_3_operand" "")
1143169689Skan		     (match_operand 5 "const_4_to_7_operand" "")
1144169689Skan		     (match_operand 6 "const_4_to_7_operand" "")])))]
1145169689Skan  "TARGET_SSE"
1146169689Skan{
1147169689Skan  int mask = 0;
1148169689Skan  mask |= INTVAL (operands[3]) << 0;
1149169689Skan  mask |= INTVAL (operands[4]) << 2;
1150169689Skan  mask |= (INTVAL (operands[5]) - 4) << 4;
1151169689Skan  mask |= (INTVAL (operands[6]) - 4) << 6;
1152169689Skan  operands[3] = GEN_INT (mask);
1153169689Skan
1154169689Skan  return "shufps\t{%3, %2, %0|%0, %2, %3}";
1155169689Skan}
1156169689Skan  [(set_attr "type" "sselog")
1157169689Skan   (set_attr "mode" "V4SF")])
1158169689Skan
1159169689Skan(define_insn "sse_storehps"
1160169689Skan  [(set (match_operand:V2SF 0 "nonimmediate_operand" "=m,x,x")
1161169689Skan	(vec_select:V2SF
1162169689Skan	  (match_operand:V4SF 1 "nonimmediate_operand" "x,x,o")
1163169689Skan	  (parallel [(const_int 2) (const_int 3)])))]
1164169689Skan  "TARGET_SSE"
1165169689Skan  "@
1166169689Skan   movhps\t{%1, %0|%0, %1}
1167169689Skan   movhlps\t{%1, %0|%0, %1}
1168169689Skan   movlps\t{%H1, %0|%0, %H1}"
1169169689Skan  [(set_attr "type" "ssemov")
1170169689Skan   (set_attr "mode" "V2SF,V4SF,V2SF")])
1171169689Skan
1172169689Skan(define_insn "sse_loadhps"
1173169689Skan  [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,o")
1174169689Skan	(vec_concat:V4SF
1175169689Skan	  (vec_select:V2SF
1176169689Skan	    (match_operand:V4SF 1 "nonimmediate_operand" "0,0,0")
1177169689Skan	    (parallel [(const_int 0) (const_int 1)]))
1178169689Skan	  (match_operand:V2SF 2 "nonimmediate_operand" "m,x,x")))]
1179169689Skan  "TARGET_SSE"
1180169689Skan  "@
1181169689Skan   movhps\t{%2, %0|%0, %2}
1182169689Skan   movlhps\t{%2, %0|%0, %2}
1183169689Skan   movlps\t{%2, %H0|%H0, %2}"
1184169689Skan  [(set_attr "type" "ssemov")
1185169689Skan   (set_attr "mode" "V2SF,V4SF,V2SF")])
1186169689Skan
1187169689Skan(define_insn "sse_storelps"
1188169689Skan  [(set (match_operand:V2SF 0 "nonimmediate_operand" "=m,x,x")
1189169689Skan	(vec_select:V2SF
1190169689Skan	  (match_operand:V4SF 1 "nonimmediate_operand" "x,x,m")
1191169689Skan	  (parallel [(const_int 0) (const_int 1)])))]
1192169689Skan  "TARGET_SSE"
1193169689Skan  "@
1194169689Skan   movlps\t{%1, %0|%0, %1}
1195169689Skan   movaps\t{%1, %0|%0, %1}
1196169689Skan   movlps\t{%1, %0|%0, %1}"
1197169689Skan  [(set_attr "type" "ssemov")
1198169689Skan   (set_attr "mode" "V2SF,V4SF,V2SF")])
1199169689Skan
1200169689Skan(define_insn "sse_loadlps"
1201169689Skan  [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,m")
1202169689Skan	(vec_concat:V4SF
1203169689Skan	  (match_operand:V2SF 2 "nonimmediate_operand" "0,m,x")
1204169689Skan	  (vec_select:V2SF
1205169689Skan	    (match_operand:V4SF 1 "nonimmediate_operand" "x,0,0")
1206169689Skan	    (parallel [(const_int 2) (const_int 3)]))))]
1207169689Skan  "TARGET_SSE"
1208169689Skan  "@
1209169689Skan   shufps\t{$0xe4, %1, %0|%0, %1, 0xe4}
1210169689Skan   movlps\t{%2, %0|%0, %2}
1211169689Skan   movlps\t{%2, %0|%0, %2}"
1212169689Skan  [(set_attr "type" "sselog,ssemov,ssemov")
1213169689Skan   (set_attr "mode" "V4SF,V2SF,V2SF")])
1214169689Skan
1215169689Skan(define_insn "sse_movss"
1216169689Skan  [(set (match_operand:V4SF 0 "register_operand" "=x")
1217169689Skan	(vec_merge:V4SF
1218169689Skan	  (match_operand:V4SF 2 "register_operand" "x")
1219169689Skan	  (match_operand:V4SF 1 "register_operand" "0")
1220169689Skan	  (const_int 1)))]
1221169689Skan  "TARGET_SSE"
1222169689Skan  "movss\t{%2, %0|%0, %2}"
1223169689Skan  [(set_attr "type" "ssemov")
1224169689Skan   (set_attr "mode" "SF")])
1225169689Skan
1226169689Skan(define_insn "*vec_dupv4sf"
1227169689Skan  [(set (match_operand:V4SF 0 "register_operand" "=x")
1228169689Skan	(vec_duplicate:V4SF
1229169689Skan	  (match_operand:SF 1 "register_operand" "0")))]
1230169689Skan  "TARGET_SSE"
1231169689Skan  "shufps\t{$0, %0, %0|%0, %0, 0}"
1232169689Skan  [(set_attr "type" "sselog1")
1233169689Skan   (set_attr "mode" "V4SF")])
1234169689Skan
1235169689Skan;; ??? In theory we can match memory for the MMX alternative, but allowing
1236169689Skan;; nonimmediate_operand for operand 2 and *not* allowing memory for the SSE
1237169689Skan;; alternatives pretty much forces the MMX alternative to be chosen.
1238169689Skan(define_insn "*sse_concatv2sf"
1239169689Skan  [(set (match_operand:V2SF 0 "register_operand"     "=x,x,*y,*y")
1240169689Skan	(vec_concat:V2SF
1241169689Skan	  (match_operand:SF 1 "nonimmediate_operand" " 0,m, 0, m")
1242169689Skan	  (match_operand:SF 2 "reg_or_0_operand"     " x,C,*y, C")))]
1243169689Skan  "TARGET_SSE"
1244169689Skan  "@
1245169689Skan   unpcklps\t{%2, %0|%0, %2}
1246169689Skan   movss\t{%1, %0|%0, %1}
1247169689Skan   punpckldq\t{%2, %0|%0, %2}
1248169689Skan   movd\t{%1, %0|%0, %1}"
1249169689Skan  [(set_attr "type" "sselog,ssemov,mmxcvt,mmxmov")
1250169689Skan   (set_attr "mode" "V4SF,SF,DI,DI")])
1251169689Skan
1252169689Skan(define_insn "*sse_concatv4sf"
1253169689Skan  [(set (match_operand:V4SF 0 "register_operand"   "=x,x")
1254169689Skan	(vec_concat:V4SF
1255169689Skan	  (match_operand:V2SF 1 "register_operand" " 0,0")
1256169689Skan	  (match_operand:V2SF 2 "nonimmediate_operand" " x,m")))]
1257169689Skan  "TARGET_SSE"
1258169689Skan  "@
1259169689Skan   movlhps\t{%2, %0|%0, %2}
1260169689Skan   movhps\t{%2, %0|%0, %2}"
1261169689Skan  [(set_attr "type" "ssemov")
1262169689Skan   (set_attr "mode" "V4SF,V2SF")])
1263169689Skan
1264169689Skan(define_expand "vec_initv4sf"
1265169689Skan  [(match_operand:V4SF 0 "register_operand" "")
1266169689Skan   (match_operand 1 "" "")]
1267169689Skan  "TARGET_SSE"
1268169689Skan{
1269169689Skan  ix86_expand_vector_init (false, operands[0], operands[1]);
1270169689Skan  DONE;
1271169689Skan})
1272169689Skan
1273169689Skan(define_insn "*vec_setv4sf_0"
1274169689Skan  [(set (match_operand:V4SF 0 "nonimmediate_operand"  "=x,x,Y ,m")
1275169689Skan	(vec_merge:V4SF
1276169689Skan	  (vec_duplicate:V4SF
1277169689Skan	    (match_operand:SF 2 "general_operand"     " x,m,*r,x*rfF"))
1278169689Skan	  (match_operand:V4SF 1 "vector_move_operand" " 0,C,C ,0")
1279169689Skan	  (const_int 1)))]
1280169689Skan  "TARGET_SSE"
1281169689Skan  "@
1282169689Skan   movss\t{%2, %0|%0, %2}
1283169689Skan   movss\t{%2, %0|%0, %2}
1284169689Skan   movd\t{%2, %0|%0, %2}
1285169689Skan   #"
1286169689Skan  [(set_attr "type" "ssemov")
1287169689Skan   (set_attr "mode" "SF")])
1288169689Skan
1289169689Skan(define_split
1290169689Skan  [(set (match_operand:V4SF 0 "memory_operand" "")
1291169689Skan	(vec_merge:V4SF
1292169689Skan	  (vec_duplicate:V4SF
1293169689Skan	    (match_operand:SF 1 "nonmemory_operand" ""))
1294169689Skan	  (match_dup 0)
1295169689Skan	  (const_int 1)))]
1296169689Skan  "TARGET_SSE && reload_completed"
1297169689Skan  [(const_int 0)]
1298169689Skan{
1299169689Skan  emit_move_insn (adjust_address (operands[0], SFmode, 0), operands[1]);
1300169689Skan  DONE;
1301169689Skan})
1302169689Skan
1303169689Skan(define_expand "vec_setv4sf"
1304169689Skan  [(match_operand:V4SF 0 "register_operand" "")
1305169689Skan   (match_operand:SF 1 "register_operand" "")
1306169689Skan   (match_operand 2 "const_int_operand" "")]
1307169689Skan  "TARGET_SSE"
1308169689Skan{
1309169689Skan  ix86_expand_vector_set (false, operands[0], operands[1],
1310169689Skan			  INTVAL (operands[2]));
1311169689Skan  DONE;
1312169689Skan})
1313169689Skan
1314169689Skan(define_insn_and_split "*vec_extractv4sf_0"
1315169689Skan  [(set (match_operand:SF 0 "nonimmediate_operand" "=x,m,fr")
1316169689Skan	(vec_select:SF
1317169689Skan	  (match_operand:V4SF 1 "nonimmediate_operand" "xm,x,m")
1318169689Skan	  (parallel [(const_int 0)])))]
1319169689Skan  "TARGET_SSE && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1320169689Skan  "#"
1321169689Skan  "&& reload_completed"
1322169689Skan  [(const_int 0)]
1323169689Skan{
1324169689Skan  rtx op1 = operands[1];
1325169689Skan  if (REG_P (op1))
1326169689Skan    op1 = gen_rtx_REG (SFmode, REGNO (op1));
1327169689Skan  else
1328169689Skan    op1 = gen_lowpart (SFmode, op1);
1329169689Skan  emit_move_insn (operands[0], op1);
1330169689Skan  DONE;
1331169689Skan})
1332169689Skan
1333169689Skan(define_expand "vec_extractv4sf"
1334169689Skan  [(match_operand:SF 0 "register_operand" "")
1335169689Skan   (match_operand:V4SF 1 "register_operand" "")
1336169689Skan   (match_operand 2 "const_int_operand" "")]
1337169689Skan  "TARGET_SSE"
1338169689Skan{
1339169689Skan  ix86_expand_vector_extract (false, operands[0], operands[1],
1340169689Skan			      INTVAL (operands[2]));
1341169689Skan  DONE;
1342169689Skan})
1343169689Skan
1344169689Skan;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1345169689Skan;;
1346169689Skan;; Parallel double-precision floating point arithmetic
1347169689Skan;;
1348169689Skan;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1349169689Skan
1350169689Skan(define_expand "negv2df2"
1351169689Skan  [(set (match_operand:V2DF 0 "register_operand" "")
1352169689Skan	(neg:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "")))]
1353169689Skan  "TARGET_SSE2"
1354169689Skan  "ix86_expand_fp_absneg_operator (NEG, V2DFmode, operands); DONE;")
1355169689Skan
1356169689Skan(define_expand "absv2df2"
1357169689Skan  [(set (match_operand:V2DF 0 "register_operand" "")
1358169689Skan	(abs:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "")))]
1359169689Skan  "TARGET_SSE2"
1360169689Skan  "ix86_expand_fp_absneg_operator (ABS, V2DFmode, operands); DONE;")
1361169689Skan
1362169689Skan(define_expand "addv2df3"
1363169689Skan  [(set (match_operand:V2DF 0 "register_operand" "")
1364169689Skan	(plus:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "")
1365169689Skan		   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
1366169689Skan  "TARGET_SSE2"
1367169689Skan  "ix86_fixup_binary_operands_no_copy (PLUS, V2DFmode, operands);")
1368169689Skan
1369169689Skan(define_insn "*addv2df3"
1370169689Skan  [(set (match_operand:V2DF 0 "register_operand" "=x")
1371169689Skan	(plus:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
1372169689Skan		   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
1373169689Skan  "TARGET_SSE2 && ix86_binary_operator_ok (PLUS, V2DFmode, operands)"
1374169689Skan  "addpd\t{%2, %0|%0, %2}"
1375169689Skan  [(set_attr "type" "sseadd")
1376169689Skan   (set_attr "mode" "V2DF")])
1377169689Skan
1378169689Skan(define_insn "sse2_vmaddv2df3"
1379169689Skan  [(set (match_operand:V2DF 0 "register_operand" "=x")
1380169689Skan	(vec_merge:V2DF
1381169689Skan	  (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
1382169689Skan		     (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
1383169689Skan	  (match_dup 1)
1384169689Skan	  (const_int 1)))]
1385169689Skan  "TARGET_SSE2 && ix86_binary_operator_ok (PLUS, V4SFmode, operands)"
1386169689Skan  "addsd\t{%2, %0|%0, %2}"
1387169689Skan  [(set_attr "type" "sseadd")
1388169689Skan   (set_attr "mode" "DF")])
1389169689Skan
1390169689Skan(define_expand "subv2df3"
1391169689Skan  [(set (match_operand:V2DF 0 "register_operand" "")
1392169689Skan	(minus:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "")
1393169689Skan		    (match_operand:V2DF 2 "nonimmediate_operand" "")))]
1394169689Skan  "TARGET_SSE2"
1395169689Skan  "ix86_fixup_binary_operands_no_copy (MINUS, V2DFmode, operands);")
1396169689Skan
1397169689Skan(define_insn "*subv2df3"
1398169689Skan  [(set (match_operand:V2DF 0 "register_operand" "=x")
1399169689Skan	(minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
1400169689Skan		    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
1401169689Skan  "TARGET_SSE2"
1402169689Skan  "subpd\t{%2, %0|%0, %2}"
1403169689Skan  [(set_attr "type" "sseadd")
1404169689Skan   (set_attr "mode" "V2DF")])
1405169689Skan
1406169689Skan(define_insn "sse2_vmsubv2df3"
1407169689Skan  [(set (match_operand:V2DF 0 "register_operand" "=x")
1408169689Skan	(vec_merge:V2DF
1409169689Skan	  (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
1410169689Skan		      (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
1411169689Skan	  (match_dup 1)
1412169689Skan	  (const_int 1)))]
1413169689Skan  "TARGET_SSE2"
1414169689Skan  "subsd\t{%2, %0|%0, %2}"
1415169689Skan  [(set_attr "type" "sseadd")
1416169689Skan   (set_attr "mode" "DF")])
1417169689Skan
1418169689Skan(define_expand "mulv2df3"
1419169689Skan  [(set (match_operand:V2DF 0 "register_operand" "")
1420169689Skan	(mult:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "")
1421169689Skan		   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
1422169689Skan  "TARGET_SSE2"
1423169689Skan  "ix86_fixup_binary_operands_no_copy (MULT, V2DFmode, operands);")
1424169689Skan
1425169689Skan(define_insn "*mulv2df3"
1426169689Skan  [(set (match_operand:V2DF 0 "register_operand" "=x")
1427169689Skan	(mult:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
1428169689Skan		   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
1429169689Skan  "TARGET_SSE2 && ix86_binary_operator_ok (MULT, V2DFmode, operands)"
1430169689Skan  "mulpd\t{%2, %0|%0, %2}"
1431169689Skan  [(set_attr "type" "ssemul")
1432169689Skan   (set_attr "mode" "V2DF")])
1433169689Skan
1434169689Skan(define_insn "sse2_vmmulv2df3"
1435169689Skan  [(set (match_operand:V2DF 0 "register_operand" "=x")
1436169689Skan	(vec_merge:V2DF
1437169689Skan	  (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
1438169689Skan		     (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
1439169689Skan	  (match_dup 1)
1440169689Skan	  (const_int 1)))]
1441169689Skan  "TARGET_SSE2 && ix86_binary_operator_ok (MULT, V2DFmode, operands)"
1442169689Skan  "mulsd\t{%2, %0|%0, %2}"
1443169689Skan  [(set_attr "type" "ssemul")
1444169689Skan   (set_attr "mode" "DF")])
1445169689Skan
1446169689Skan(define_expand "divv2df3"
1447169689Skan  [(set (match_operand:V2DF 0 "register_operand" "")
1448169689Skan	(div:V2DF (match_operand:V2DF 1 "register_operand" "")
1449169689Skan		  (match_operand:V2DF 2 "nonimmediate_operand" "")))]
1450169689Skan  "TARGET_SSE2"
1451169689Skan  "ix86_fixup_binary_operands_no_copy (DIV, V2DFmode, operands);")
1452169689Skan
1453169689Skan(define_insn "*divv2df3"
1454169689Skan  [(set (match_operand:V2DF 0 "register_operand" "=x")
1455169689Skan	(div:V2DF (match_operand:V2DF 1 "register_operand" "0")
1456169689Skan		  (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
1457169689Skan  "TARGET_SSE2"
1458169689Skan  "divpd\t{%2, %0|%0, %2}"
1459169689Skan  [(set_attr "type" "ssediv")
1460169689Skan   (set_attr "mode" "V2DF")])
1461169689Skan
1462169689Skan(define_insn "sse2_vmdivv2df3"
1463169689Skan  [(set (match_operand:V2DF 0 "register_operand" "=x")
1464169689Skan	(vec_merge:V2DF
1465169689Skan	  (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
1466169689Skan		    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
1467169689Skan	  (match_dup 1)
1468169689Skan	  (const_int 1)))]
1469169689Skan  "TARGET_SSE2"
1470169689Skan  "divsd\t{%2, %0|%0, %2}"
1471169689Skan  [(set_attr "type" "ssediv")
1472169689Skan   (set_attr "mode" "DF")])
1473169689Skan
1474169689Skan(define_insn "sqrtv2df2"
1475169689Skan  [(set (match_operand:V2DF 0 "register_operand" "=x")
1476169689Skan	(sqrt:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "xm")))]
1477169689Skan  "TARGET_SSE2"
1478169689Skan  "sqrtpd\t{%1, %0|%0, %1}"
1479169689Skan  [(set_attr "type" "sse")
1480169689Skan   (set_attr "mode" "V2DF")])
1481169689Skan
1482169689Skan(define_insn "sse2_vmsqrtv2df2"
1483169689Skan  [(set (match_operand:V2DF 0 "register_operand" "=x")
1484169689Skan	(vec_merge:V2DF
1485169689Skan	  (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm"))
1486169689Skan	  (match_operand:V2DF 2 "register_operand" "0")
1487169689Skan	  (const_int 1)))]
1488169689Skan  "TARGET_SSE2"
1489169689Skan  "sqrtsd\t{%1, %0|%0, %1}"
1490169689Skan  [(set_attr "type" "sse")
1491169689Skan   (set_attr "mode" "DF")])
1492169689Skan
1493169689Skan;; ??? For !flag_finite_math_only, the representation with SMIN/SMAX
1494169689Skan;; isn't really correct, as those rtl operators aren't defined when 
1495169689Skan;; applied to NaNs.  Hopefully the optimizers won't get too smart on us.
1496169689Skan
1497169689Skan(define_expand "smaxv2df3"
1498169689Skan  [(set (match_operand:V2DF 0 "register_operand" "")
1499169689Skan	(smax:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "")
1500169689Skan		   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
1501169689Skan  "TARGET_SSE2"
1502169689Skan{
1503169689Skan  if (!flag_finite_math_only)
1504169689Skan    operands[1] = force_reg (V2DFmode, operands[1]);
1505169689Skan  ix86_fixup_binary_operands_no_copy (SMAX, V2DFmode, operands);
1506169689Skan})
1507169689Skan
1508169689Skan(define_insn "*smaxv2df3_finite"
1509169689Skan  [(set (match_operand:V2DF 0 "register_operand" "=x")
1510169689Skan	(smax:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
1511169689Skan		   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
1512169689Skan  "TARGET_SSE2 && flag_finite_math_only
1513169689Skan   && ix86_binary_operator_ok (SMAX, V2DFmode, operands)"
1514169689Skan  "maxpd\t{%2, %0|%0, %2}"
1515169689Skan  [(set_attr "type" "sseadd")
1516169689Skan   (set_attr "mode" "V2DF")])
1517169689Skan
1518169689Skan(define_insn "*smaxv2df3"
1519169689Skan  [(set (match_operand:V2DF 0 "register_operand" "=x")
1520169689Skan	(smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
1521169689Skan		   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
1522169689Skan  "TARGET_SSE2"
1523169689Skan  "maxpd\t{%2, %0|%0, %2}"
1524169689Skan  [(set_attr "type" "sseadd")
1525169689Skan   (set_attr "mode" "V2DF")])
1526169689Skan
1527169689Skan(define_insn "sse2_vmsmaxv2df3"
1528169689Skan  [(set (match_operand:V2DF 0 "register_operand" "=x")
1529169689Skan	(vec_merge:V2DF
1530169689Skan	  (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
1531169689Skan		     (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
1532169689Skan	  (match_dup 1)
1533169689Skan	  (const_int 1)))]
1534169689Skan  "TARGET_SSE2"
1535169689Skan  "maxsd\t{%2, %0|%0, %2}"
1536169689Skan  [(set_attr "type" "sseadd")
1537169689Skan   (set_attr "mode" "DF")])
1538169689Skan
1539169689Skan(define_expand "sminv2df3"
1540169689Skan  [(set (match_operand:V2DF 0 "register_operand" "")
1541169689Skan	(smin:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "")
1542169689Skan		   (match_operand:V2DF 2 "nonimmediate_operand" "")))]
1543169689Skan  "TARGET_SSE2"
1544169689Skan{
1545169689Skan  if (!flag_finite_math_only)
1546169689Skan    operands[1] = force_reg (V2DFmode, operands[1]);
1547169689Skan  ix86_fixup_binary_operands_no_copy (SMIN, V2DFmode, operands);
1548169689Skan})
1549169689Skan
1550169689Skan(define_insn "*sminv2df3_finite"
1551169689Skan  [(set (match_operand:V2DF 0 "register_operand" "=x")
1552169689Skan	(smin:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
1553169689Skan		   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
1554169689Skan  "TARGET_SSE2 && flag_finite_math_only
1555169689Skan   && ix86_binary_operator_ok (SMIN, V2DFmode, operands)"
1556169689Skan  "minpd\t{%2, %0|%0, %2}"
1557169689Skan  [(set_attr "type" "sseadd")
1558169689Skan   (set_attr "mode" "V2DF")])
1559169689Skan
1560169689Skan(define_insn "*sminv2df3"
1561169689Skan  [(set (match_operand:V2DF 0 "register_operand" "=x")
1562169689Skan	(smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
1563169689Skan		   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
1564169689Skan  "TARGET_SSE2"
1565169689Skan  "minpd\t{%2, %0|%0, %2}"
1566169689Skan  [(set_attr "type" "sseadd")
1567169689Skan   (set_attr "mode" "V2DF")])
1568169689Skan
1569169689Skan(define_insn "sse2_vmsminv2df3"
1570169689Skan  [(set (match_operand:V2DF 0 "register_operand" "=x")
1571169689Skan	(vec_merge:V2DF
1572169689Skan	  (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
1573169689Skan		     (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
1574169689Skan	  (match_dup 1)
1575169689Skan	  (const_int 1)))]
1576169689Skan  "TARGET_SSE2"
1577169689Skan  "minsd\t{%2, %0|%0, %2}"
1578169689Skan  [(set_attr "type" "sseadd")
1579169689Skan   (set_attr "mode" "DF")])
1580169689Skan
1581169689Skan(define_insn "sse3_addsubv2df3"
1582169689Skan  [(set (match_operand:V2DF 0 "register_operand" "=x")
1583169689Skan	(vec_merge:V2DF
1584169689Skan	  (plus:V2DF
1585169689Skan	    (match_operand:V2DF 1 "register_operand" "0")
1586169689Skan	    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
1587169689Skan	  (minus:V2DF (match_dup 1) (match_dup 2))
1588169689Skan	  (const_int 1)))]
1589169689Skan  "TARGET_SSE3"
1590169689Skan  "addsubpd\t{%2, %0|%0, %2}"
1591169689Skan  [(set_attr "type" "sseadd")
1592169689Skan   (set_attr "mode" "V2DF")])
1593169689Skan
1594169689Skan(define_insn "sse3_haddv2df3"
1595169689Skan  [(set (match_operand:V2DF 0 "register_operand" "=x")
1596169689Skan	(vec_concat:V2DF
1597169689Skan	  (plus:DF
1598169689Skan	    (vec_select:DF
1599169689Skan	      (match_operand:V2DF 1 "register_operand" "0")
1600169689Skan	      (parallel [(const_int 0)]))
1601169689Skan	    (vec_select:DF (match_dup 1) (parallel [(const_int 1)])))
1602169689Skan	  (plus:DF
1603169689Skan	    (vec_select:DF
1604169689Skan	      (match_operand:V2DF 2 "nonimmediate_operand" "xm")
1605169689Skan	      (parallel [(const_int 0)]))
1606169689Skan	    (vec_select:DF (match_dup 2) (parallel [(const_int 1)])))))]
1607169689Skan  "TARGET_SSE3"
1608169689Skan  "haddpd\t{%2, %0|%0, %2}"
1609169689Skan  [(set_attr "type" "sseadd")
1610169689Skan   (set_attr "mode" "V2DF")])
1611169689Skan
1612169689Skan(define_insn "sse3_hsubv2df3"
1613169689Skan  [(set (match_operand:V2DF 0 "register_operand" "=x")
1614169689Skan	(vec_concat:V2DF
1615169689Skan	  (minus:DF
1616169689Skan	    (vec_select:DF
1617169689Skan	      (match_operand:V2DF 1 "register_operand" "0")
1618169689Skan	      (parallel [(const_int 0)]))
1619169689Skan	    (vec_select:DF (match_dup 1) (parallel [(const_int 1)])))
1620169689Skan	  (minus:DF
1621169689Skan	    (vec_select:DF
1622169689Skan	      (match_operand:V2DF 2 "nonimmediate_operand" "xm")
1623169689Skan	      (parallel [(const_int 0)]))
1624169689Skan	    (vec_select:DF (match_dup 2) (parallel [(const_int 1)])))))]
1625169689Skan  "TARGET_SSE3"
1626169689Skan  "hsubpd\t{%2, %0|%0, %2}"
1627169689Skan  [(set_attr "type" "sseadd")
1628169689Skan   (set_attr "mode" "V2DF")])
1629169689Skan
1630169689Skan(define_expand "reduc_splus_v2df"
1631169689Skan  [(match_operand:V2DF 0 "register_operand" "")
1632169689Skan   (match_operand:V2DF 1 "register_operand" "")]
1633169689Skan  "TARGET_SSE3"
1634169689Skan{
1635169689Skan  emit_insn (gen_sse3_haddv2df3 (operands[0], operands[1], operands[1]));
1636169689Skan  DONE;
1637169689Skan})
1638169689Skan
1639169689Skan;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1640169689Skan;;
1641169689Skan;; Parallel double-precision floating point comparisons
1642169689Skan;;
1643169689Skan;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1644169689Skan
1645169689Skan(define_insn "sse2_maskcmpv2df3"
1646169689Skan  [(set (match_operand:V2DF 0 "register_operand" "=x")
1647169689Skan	(match_operator:V2DF 3 "sse_comparison_operator"
1648169689Skan		[(match_operand:V2DF 1 "register_operand" "0")
1649169689Skan		 (match_operand:V2DF 2 "nonimmediate_operand" "xm")]))]
1650169689Skan  "TARGET_SSE2"
1651169689Skan  "cmp%D3pd\t{%2, %0|%0, %2}"
1652169689Skan  [(set_attr "type" "ssecmp")
1653169689Skan   (set_attr "mode" "V2DF")])
1654169689Skan
1655169689Skan(define_insn "sse2_vmmaskcmpv2df3"
1656169689Skan  [(set (match_operand:V2DF 0 "register_operand" "=x")
1657169689Skan	(vec_merge:V2DF
1658169689Skan	  (match_operator:V2DF 3 "sse_comparison_operator"
1659169689Skan		[(match_operand:V2DF 1 "register_operand" "0")
1660169689Skan		 (match_operand:V2DF 2 "nonimmediate_operand" "xm")])
1661169689Skan	  (match_dup 1)
1662169689Skan	  (const_int 1)))]
1663169689Skan  "TARGET_SSE2"
1664169689Skan  "cmp%D3sd\t{%2, %0|%0, %2}"
1665169689Skan  [(set_attr "type" "ssecmp")
1666169689Skan   (set_attr "mode" "DF")])
1667169689Skan
1668169689Skan(define_insn "sse2_comi"
1669169689Skan  [(set (reg:CCFP FLAGS_REG)
1670169689Skan	(compare:CCFP
1671169689Skan	  (vec_select:DF
1672169689Skan	    (match_operand:V2DF 0 "register_operand" "x")
1673169689Skan	    (parallel [(const_int 0)]))
1674169689Skan	  (vec_select:DF
1675169689Skan	    (match_operand:V2DF 1 "nonimmediate_operand" "xm")
1676169689Skan	    (parallel [(const_int 0)]))))]
1677169689Skan  "TARGET_SSE2"
1678169689Skan  "comisd\t{%1, %0|%0, %1}"
1679169689Skan  [(set_attr "type" "ssecomi")
1680169689Skan   (set_attr "mode" "DF")])
1681169689Skan
1682169689Skan(define_insn "sse2_ucomi"
1683169689Skan  [(set (reg:CCFPU FLAGS_REG)
1684169689Skan	(compare:CCFPU
1685169689Skan	  (vec_select:DF
1686169689Skan	    (match_operand:V2DF 0 "register_operand" "x")
1687169689Skan	    (parallel [(const_int 0)]))
1688169689Skan	  (vec_select:DF
1689169689Skan	    (match_operand:V2DF 1 "nonimmediate_operand" "xm")
1690169689Skan	    (parallel [(const_int 0)]))))]
1691169689Skan  "TARGET_SSE2"
1692169689Skan  "ucomisd\t{%1, %0|%0, %1}"
1693169689Skan  [(set_attr "type" "ssecomi")
1694169689Skan   (set_attr "mode" "DF")])
1695169689Skan
1696169689Skan(define_expand "vcondv2df"
1697169689Skan  [(set (match_operand:V2DF 0 "register_operand" "")
1698169689Skan        (if_then_else:V2DF
1699169689Skan          (match_operator 3 ""
1700169689Skan            [(match_operand:V2DF 4 "nonimmediate_operand" "")
1701169689Skan             (match_operand:V2DF 5 "nonimmediate_operand" "")])
1702169689Skan          (match_operand:V2DF 1 "general_operand" "")
1703169689Skan          (match_operand:V2DF 2 "general_operand" "")))]
1704169689Skan  "TARGET_SSE2"
1705169689Skan{
1706169689Skan  if (ix86_expand_fp_vcond (operands))
1707169689Skan    DONE;
1708169689Skan  else
1709169689Skan    FAIL;
1710169689Skan})
1711169689Skan
1712169689Skan;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1713169689Skan;;
1714169689Skan;; Parallel double-precision floating point logical operations
1715169689Skan;;
1716169689Skan;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1717169689Skan
1718169689Skan(define_expand "andv2df3"
1719169689Skan  [(set (match_operand:V2DF 0 "register_operand" "")
1720169689Skan	(and:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "")
1721169689Skan		  (match_operand:V2DF 2 "nonimmediate_operand" "")))]
1722169689Skan  "TARGET_SSE2"
1723169689Skan  "ix86_fixup_binary_operands_no_copy (AND, V2DFmode, operands);")
1724169689Skan
1725169689Skan(define_insn "*andv2df3"
1726169689Skan  [(set (match_operand:V2DF 0 "register_operand" "=x")
1727169689Skan	(and:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
1728169689Skan		  (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
1729169689Skan  "TARGET_SSE2 && ix86_binary_operator_ok (AND, V2DFmode, operands)"
1730169689Skan  "andpd\t{%2, %0|%0, %2}"
1731169689Skan  [(set_attr "type" "sselog")
1732169689Skan   (set_attr "mode" "V2DF")])
1733169689Skan
1734169689Skan(define_insn "sse2_nandv2df3"
1735169689Skan  [(set (match_operand:V2DF 0 "register_operand" "=x")
1736169689Skan	(and:V2DF (not:V2DF (match_operand:V2DF 1 "register_operand" "0"))
1737169689Skan		  (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
1738169689Skan  "TARGET_SSE2"
1739169689Skan  "andnpd\t{%2, %0|%0, %2}"
1740169689Skan  [(set_attr "type" "sselog")
1741169689Skan   (set_attr "mode" "V2DF")])
1742169689Skan
1743169689Skan(define_expand "iorv2df3"
1744169689Skan  [(set (match_operand:V2DF 0 "register_operand" "")
1745169689Skan	(ior:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "")
1746169689Skan		  (match_operand:V2DF 2 "nonimmediate_operand" "")))]
1747169689Skan  "TARGET_SSE2"
1748169689Skan  "ix86_fixup_binary_operands_no_copy (IOR, V2DFmode, operands);")
1749169689Skan
1750169689Skan(define_insn "*iorv2df3"
1751169689Skan  [(set (match_operand:V2DF 0 "register_operand" "=x")
1752169689Skan	(ior:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
1753169689Skan		  (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
1754169689Skan  "TARGET_SSE2 && ix86_binary_operator_ok (IOR, V2DFmode, operands)"
1755169689Skan  "orpd\t{%2, %0|%0, %2}"
1756169689Skan  [(set_attr "type" "sselog")
1757169689Skan   (set_attr "mode" "V2DF")])
1758169689Skan
1759169689Skan(define_expand "xorv2df3"
1760169689Skan  [(set (match_operand:V2DF 0 "register_operand" "")
1761169689Skan	(xor:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "")
1762169689Skan		  (match_operand:V2DF 2 "nonimmediate_operand" "")))]
1763169689Skan  "TARGET_SSE2"
1764169689Skan  "ix86_fixup_binary_operands_no_copy (XOR, V2DFmode, operands);")
1765169689Skan
1766169689Skan(define_insn "*xorv2df3"
1767169689Skan  [(set (match_operand:V2DF 0 "register_operand" "=x")
1768169689Skan	(xor:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
1769169689Skan		  (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
1770169689Skan  "TARGET_SSE2 && ix86_binary_operator_ok (XOR, V2DFmode, operands)"
1771169689Skan  "xorpd\t{%2, %0|%0, %2}"
1772169689Skan  [(set_attr "type" "sselog")
1773169689Skan   (set_attr "mode" "V2DF")])
1774169689Skan
1775169689Skan;; Also define scalar versions.  These are used for abs, neg, and
1776169689Skan;; conditional move.  Using subregs into vector modes causes register
1777169689Skan;; allocation lossage.  These patterns do not allow memory operands
1778169689Skan;; because the native instructions read the full 128-bits.
1779169689Skan
1780169689Skan(define_insn "*anddf3"
1781169689Skan  [(set (match_operand:DF 0 "register_operand" "=x")
1782169689Skan	(and:DF (match_operand:DF 1 "register_operand" "0")
1783169689Skan		(match_operand:DF 2 "register_operand" "x")))]
1784169689Skan  "TARGET_SSE2"
1785169689Skan  "andpd\t{%2, %0|%0, %2}"
1786169689Skan  [(set_attr "type" "sselog")
1787169689Skan   (set_attr "mode" "V2DF")])
1788169689Skan
1789169689Skan(define_insn "*nanddf3"
1790169689Skan  [(set (match_operand:DF 0 "register_operand" "=x")
1791169689Skan	(and:DF (not:DF (match_operand:DF 1 "register_operand" "0"))
1792169689Skan		(match_operand:DF 2 "register_operand" "x")))]
1793169689Skan  "TARGET_SSE2"
1794169689Skan  "andnpd\t{%2, %0|%0, %2}"
1795169689Skan  [(set_attr "type" "sselog")
1796169689Skan   (set_attr "mode" "V2DF")])
1797169689Skan
1798169689Skan(define_insn "*iordf3"
1799169689Skan  [(set (match_operand:DF 0 "register_operand" "=x")
1800169689Skan	(ior:DF (match_operand:DF 1 "register_operand" "0")
1801169689Skan		(match_operand:DF 2 "register_operand" "x")))]
1802169689Skan  "TARGET_SSE2"
1803169689Skan  "orpd\t{%2, %0|%0, %2}"
1804169689Skan  [(set_attr "type" "sselog")
1805169689Skan   (set_attr "mode" "V2DF")])
1806169689Skan
1807169689Skan(define_insn "*xordf3"
1808169689Skan  [(set (match_operand:DF 0 "register_operand" "=x")
1809169689Skan	(xor:DF (match_operand:DF 1 "register_operand" "0")
1810169689Skan		(match_operand:DF 2 "register_operand" "x")))]
1811169689Skan  "TARGET_SSE2"
1812169689Skan  "xorpd\t{%2, %0|%0, %2}"
1813169689Skan  [(set_attr "type" "sselog")
1814169689Skan   (set_attr "mode" "V2DF")])
1815169689Skan
1816169689Skan;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1817169689Skan;;
1818169689Skan;; Parallel double-precision floating point conversion operations
1819169689Skan;;
1820169689Skan;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1821169689Skan
1822169689Skan(define_insn "sse2_cvtpi2pd"
1823169689Skan  [(set (match_operand:V2DF 0 "register_operand" "=x,x")
1824169689Skan	(float:V2DF (match_operand:V2SI 1 "nonimmediate_operand" "y,m")))]
1825169689Skan  "TARGET_SSE2"
1826169689Skan  "cvtpi2pd\t{%1, %0|%0, %1}"
1827169689Skan  [(set_attr "type" "ssecvt")
1828169689Skan   (set_attr "unit" "mmx,*")
1829169689Skan   (set_attr "mode" "V2DF")])
1830169689Skan
1831169689Skan(define_insn "sse2_cvtpd2pi"
1832169689Skan  [(set (match_operand:V2SI 0 "register_operand" "=y")
1833169689Skan	(unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
1834169689Skan		     UNSPEC_FIX_NOTRUNC))]
1835169689Skan  "TARGET_SSE2"
1836169689Skan  "cvtpd2pi\t{%1, %0|%0, %1}"
1837169689Skan  [(set_attr "type" "ssecvt")
1838169689Skan   (set_attr "unit" "mmx")
1839169689Skan   (set_attr "mode" "DI")])
1840169689Skan
1841169689Skan(define_insn "sse2_cvttpd2pi"
1842169689Skan  [(set (match_operand:V2SI 0 "register_operand" "=y")
1843169689Skan	(fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm")))]
1844169689Skan  "TARGET_SSE2"
1845169689Skan  "cvttpd2pi\t{%1, %0|%0, %1}"
1846169689Skan  [(set_attr "type" "ssecvt")
1847169689Skan   (set_attr "unit" "mmx")
1848169689Skan   (set_attr "mode" "TI")])
1849169689Skan
1850169689Skan(define_insn "sse2_cvtsi2sd"
1851169689Skan  [(set (match_operand:V2DF 0 "register_operand" "=x,x")
1852169689Skan	(vec_merge:V2DF
1853169689Skan	  (vec_duplicate:V2DF
1854169689Skan	    (float:DF (match_operand:SI 2 "nonimmediate_operand" "r,m")))
1855169689Skan	  (match_operand:V2DF 1 "register_operand" "0,0")
1856169689Skan	  (const_int 1)))]
1857169689Skan  "TARGET_SSE2"
1858169689Skan  "cvtsi2sd\t{%2, %0|%0, %2}"
1859169689Skan  [(set_attr "type" "sseicvt")
1860169689Skan   (set_attr "mode" "DF")
1861252080Spfg   (set_attr "athlon_decode" "double,direct")
1862252080Spfg   (set_attr "amdfam10_decode" "vector,double")])
1863169689Skan
1864169689Skan(define_insn "sse2_cvtsi2sdq"
1865169689Skan  [(set (match_operand:V2DF 0 "register_operand" "=x,x")
1866169689Skan	(vec_merge:V2DF
1867169689Skan	  (vec_duplicate:V2DF
1868169689Skan	    (float:DF (match_operand:DI 2 "nonimmediate_operand" "r,m")))
1869169689Skan	  (match_operand:V2DF 1 "register_operand" "0,0")
1870169689Skan	  (const_int 1)))]
1871169689Skan  "TARGET_SSE2 && TARGET_64BIT"
1872169689Skan  "cvtsi2sdq\t{%2, %0|%0, %2}"
1873169689Skan  [(set_attr "type" "sseicvt")
1874169689Skan   (set_attr "mode" "DF")
1875252080Spfg   (set_attr "athlon_decode" "double,direct")
1876252080Spfg   (set_attr "amdfam10_decode" "vector,double")])
1877169689Skan
1878169689Skan(define_insn "sse2_cvtsd2si"
1879169689Skan  [(set (match_operand:SI 0 "register_operand" "=r,r")
1880169689Skan	(unspec:SI
1881169689Skan	  [(vec_select:DF
1882169689Skan	     (match_operand:V2DF 1 "nonimmediate_operand" "x,m")
1883169689Skan	     (parallel [(const_int 0)]))]
1884169689Skan	  UNSPEC_FIX_NOTRUNC))]
1885169689Skan  "TARGET_SSE2"
1886169689Skan  "cvtsd2si\t{%1, %0|%0, %1}"
1887169689Skan  [(set_attr "type" "sseicvt")
1888169689Skan   (set_attr "athlon_decode" "double,vector")
1889252080Spfg   (set_attr "amdfam10_decode" "double,double")
1890169689Skan   (set_attr "mode" "SI")])
1891169689Skan
1892169689Skan(define_insn "sse2_cvtsd2siq"
1893169689Skan  [(set (match_operand:DI 0 "register_operand" "=r,r")
1894169689Skan	(unspec:DI
1895169689Skan	  [(vec_select:DF
1896169689Skan	     (match_operand:V2DF 1 "nonimmediate_operand" "x,m")
1897169689Skan	     (parallel [(const_int 0)]))]
1898169689Skan	  UNSPEC_FIX_NOTRUNC))]
1899169689Skan  "TARGET_SSE2 && TARGET_64BIT"
1900169689Skan  "cvtsd2siq\t{%1, %0|%0, %1}"
1901169689Skan  [(set_attr "type" "sseicvt")
1902169689Skan   (set_attr "athlon_decode" "double,vector")
1903252080Spfg   (set_attr "amdfam10_decode" "double,double")
1904169689Skan   (set_attr "mode" "DI")])
1905169689Skan
1906169689Skan(define_insn "sse2_cvttsd2si"
1907169689Skan  [(set (match_operand:SI 0 "register_operand" "=r,r")
1908169689Skan	(fix:SI
1909169689Skan	  (vec_select:DF
1910169689Skan	    (match_operand:V2DF 1 "nonimmediate_operand" "x,m")
1911169689Skan	    (parallel [(const_int 0)]))))]
1912169689Skan  "TARGET_SSE2"
1913169689Skan  "cvttsd2si\t{%1, %0|%0, %1}"
1914169689Skan  [(set_attr "type" "sseicvt")
1915169689Skan   (set_attr "mode" "SI")
1916252080Spfg   (set_attr "athlon_decode" "double,vector")
1917252080Spfg   (set_attr "amdfam10_decode" "double,double")])
1918169689Skan
1919169689Skan(define_insn "sse2_cvttsd2siq"
1920169689Skan  [(set (match_operand:DI 0 "register_operand" "=r,r")
1921169689Skan	(fix:DI
1922169689Skan	  (vec_select:DF
1923169689Skan	    (match_operand:V2DF 1 "nonimmediate_operand" "x,m")
1924169689Skan	    (parallel [(const_int 0)]))))]
1925169689Skan  "TARGET_SSE2 && TARGET_64BIT"
1926169689Skan  "cvttsd2siq\t{%1, %0|%0, %1}"
1927169689Skan  [(set_attr "type" "sseicvt")
1928169689Skan   (set_attr "mode" "DI")
1929252080Spfg   (set_attr "athlon_decode" "double,vector")
1930252080Spfg   (set_attr "amdfam10_decode" "double,double")])
1931169689Skan
1932169689Skan(define_insn "sse2_cvtdq2pd"
1933169689Skan  [(set (match_operand:V2DF 0 "register_operand" "=x")
1934169689Skan	(float:V2DF
1935169689Skan	  (vec_select:V2SI
1936169689Skan	    (match_operand:V4SI 1 "nonimmediate_operand" "xm")
1937169689Skan	    (parallel [(const_int 0) (const_int 1)]))))]
1938169689Skan  "TARGET_SSE2"
1939169689Skan  "cvtdq2pd\t{%1, %0|%0, %1}"
1940169689Skan  [(set_attr "type" "ssecvt")
1941169689Skan   (set_attr "mode" "V2DF")])
1942169689Skan
1943169689Skan(define_expand "sse2_cvtpd2dq"
1944169689Skan  [(set (match_operand:V4SI 0 "register_operand" "")
1945169689Skan	(vec_concat:V4SI
1946169689Skan	  (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "")]
1947169689Skan		       UNSPEC_FIX_NOTRUNC)
1948169689Skan	  (match_dup 2)))]
1949169689Skan  "TARGET_SSE2"
1950169689Skan  "operands[2] = CONST0_RTX (V2SImode);")
1951169689Skan
1952169689Skan(define_insn "*sse2_cvtpd2dq"
1953169689Skan  [(set (match_operand:V4SI 0 "register_operand" "=x")
1954169689Skan	(vec_concat:V4SI
1955169689Skan	  (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
1956169689Skan		       UNSPEC_FIX_NOTRUNC)
1957169689Skan	  (match_operand:V2SI 2 "const0_operand" "")))]
1958169689Skan  "TARGET_SSE2"
1959169689Skan  "cvtpd2dq\t{%1, %0|%0, %1}"
1960169689Skan  [(set_attr "type" "ssecvt")
1961252080Spfg   (set_attr "mode" "TI")
1962252080Spfg   (set_attr "amdfam10_decode" "double")])
1963169689Skan
1964169689Skan(define_expand "sse2_cvttpd2dq"
1965169689Skan  [(set (match_operand:V4SI 0 "register_operand" "")
1966169689Skan	(vec_concat:V4SI
1967169689Skan	  (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" ""))
1968169689Skan	  (match_dup 2)))]
1969169689Skan  "TARGET_SSE2"
1970169689Skan  "operands[2] = CONST0_RTX (V2SImode);")
1971169689Skan
1972169689Skan(define_insn "*sse2_cvttpd2dq"
1973169689Skan  [(set (match_operand:V4SI 0 "register_operand" "=x")
1974169689Skan	(vec_concat:V4SI
1975169689Skan	  (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm"))
1976169689Skan	  (match_operand:V2SI 2 "const0_operand" "")))]
1977169689Skan  "TARGET_SSE2"
1978169689Skan  "cvttpd2dq\t{%1, %0|%0, %1}"
1979169689Skan  [(set_attr "type" "ssecvt")
1980252080Spfg   (set_attr "mode" "TI")
1981252080Spfg   (set_attr "amdfam10_decode" "double")])
1982169689Skan
1983169689Skan(define_insn "sse2_cvtsd2ss"
1984169689Skan  [(set (match_operand:V4SF 0 "register_operand" "=x,x")
1985169689Skan	(vec_merge:V4SF
1986169689Skan	  (vec_duplicate:V4SF
1987169689Skan	    (float_truncate:V2SF
1988169689Skan	      (match_operand:V2DF 2 "nonimmediate_operand" "x,m")))
1989169689Skan	  (match_operand:V4SF 1 "register_operand" "0,0")
1990169689Skan	  (const_int 1)))]
1991169689Skan  "TARGET_SSE2"
1992169689Skan  "cvtsd2ss\t{%2, %0|%0, %2}"
1993169689Skan  [(set_attr "type" "ssecvt")
1994169689Skan   (set_attr "athlon_decode" "vector,double")
1995252080Spfg   (set_attr "amdfam10_decode" "vector,double")
1996169689Skan   (set_attr "mode" "SF")])
1997169689Skan
1998169689Skan(define_insn "sse2_cvtss2sd"
1999252080Spfg  [(set (match_operand:V2DF 0 "register_operand" "=x,x")
2000169689Skan	(vec_merge:V2DF
2001169689Skan	  (float_extend:V2DF
2002169689Skan	    (vec_select:V2SF
2003252080Spfg	      (match_operand:V4SF 2 "nonimmediate_operand" "x,m")
2004169689Skan	      (parallel [(const_int 0) (const_int 1)])))
2005252080Spfg	  (match_operand:V2DF 1 "register_operand" "0,0")
2006169689Skan	  (const_int 1)))]
2007169689Skan  "TARGET_SSE2"
2008169689Skan  "cvtss2sd\t{%2, %0|%0, %2}"
2009169689Skan  [(set_attr "type" "ssecvt")
2010252080Spfg   (set_attr "amdfam10_decode" "vector,double")
2011169689Skan   (set_attr "mode" "DF")])
2012169689Skan
2013169689Skan(define_expand "sse2_cvtpd2ps"
2014169689Skan  [(set (match_operand:V4SF 0 "register_operand" "")
2015169689Skan	(vec_concat:V4SF
2016169689Skan	  (float_truncate:V2SF
2017169689Skan	    (match_operand:V2DF 1 "nonimmediate_operand" "xm"))
2018169689Skan	  (match_dup 2)))]
2019169689Skan  "TARGET_SSE2"
2020169689Skan  "operands[2] = CONST0_RTX (V2SFmode);")
2021169689Skan
2022169689Skan(define_insn "*sse2_cvtpd2ps"
2023169689Skan  [(set (match_operand:V4SF 0 "register_operand" "=x")
2024169689Skan	(vec_concat:V4SF
2025169689Skan	  (float_truncate:V2SF
2026169689Skan	    (match_operand:V2DF 1 "nonimmediate_operand" "xm"))
2027169689Skan	  (match_operand:V2SF 2 "const0_operand" "")))]
2028169689Skan  "TARGET_SSE2"
2029169689Skan  "cvtpd2ps\t{%1, %0|%0, %1}"
2030169689Skan  [(set_attr "type" "ssecvt")
2031252080Spfg   (set_attr "mode" "V4SF")
2032252080Spfg   (set_attr "amdfam10_decode" "double")])
2033169689Skan
2034169689Skan(define_insn "sse2_cvtps2pd"
2035169689Skan  [(set (match_operand:V2DF 0 "register_operand" "=x")
2036169689Skan	(float_extend:V2DF
2037169689Skan	  (vec_select:V2SF
2038169689Skan	    (match_operand:V4SF 1 "nonimmediate_operand" "xm")
2039169689Skan	    (parallel [(const_int 0) (const_int 1)]))))]
2040169689Skan  "TARGET_SSE2"
2041169689Skan  "cvtps2pd\t{%1, %0|%0, %1}"
2042169689Skan  [(set_attr "type" "ssecvt")
2043252080Spfg   (set_attr "mode" "V2DF")
2044252080Spfg   (set_attr "amdfam10_decode" "direct")])
2045169689Skan
2046169689Skan;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2047169689Skan;;
2048169689Skan;; Parallel double-precision floating point element swizzling
2049169689Skan;;
2050169689Skan;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2051169689Skan
2052169689Skan(define_insn "sse2_unpckhpd"
2053169689Skan  [(set (match_operand:V2DF 0 "nonimmediate_operand"     "=x,x,m")
2054169689Skan	(vec_select:V2DF
2055169689Skan	  (vec_concat:V4DF
2056169689Skan	    (match_operand:V2DF 1 "nonimmediate_operand" " 0,o,x")
2057169689Skan	    (match_operand:V2DF 2 "nonimmediate_operand" " x,0,0"))
2058169689Skan	  (parallel [(const_int 1)
2059169689Skan		     (const_int 3)])))]
2060169689Skan  "TARGET_SSE2 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
2061169689Skan  "@
2062169689Skan   unpckhpd\t{%2, %0|%0, %2}
2063169689Skan   movlpd\t{%H1, %0|%0, %H1}
2064169689Skan   movhpd\t{%1, %0|%0, %1}"
2065169689Skan  [(set_attr "type" "sselog,ssemov,ssemov")
2066169689Skan   (set_attr "mode" "V2DF,V1DF,V1DF")])
2067169689Skan
2068169689Skan(define_insn "*sse3_movddup"
2069169689Skan  [(set (match_operand:V2DF 0 "nonimmediate_operand"     "=x,o")
2070169689Skan	(vec_select:V2DF
2071169689Skan	  (vec_concat:V4DF
2072169689Skan	    (match_operand:V2DF 1 "nonimmediate_operand" "xm,x")
2073169689Skan	    (match_dup 1))
2074169689Skan	  (parallel [(const_int 0)
2075169689Skan		     (const_int 2)])))]
2076171825Skan  "TARGET_SSE3 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2077169689Skan  "@
2078169689Skan   movddup\t{%1, %0|%0, %1}
2079169689Skan   #"
2080171825Skan  [(set_attr "type" "sselog1,ssemov")
2081169689Skan   (set_attr "mode" "V2DF")])
2082169689Skan
2083169689Skan(define_split
2084169689Skan  [(set (match_operand:V2DF 0 "memory_operand" "")
2085169689Skan	(vec_select:V2DF
2086169689Skan	  (vec_concat:V4DF
2087169689Skan	    (match_operand:V2DF 1 "register_operand" "")
2088169689Skan	    (match_dup 1))
2089169689Skan	  (parallel [(const_int 0)
2090169689Skan		     (const_int 2)])))]
2091169689Skan  "TARGET_SSE3 && reload_completed"
2092169689Skan  [(const_int 0)]
2093169689Skan{
2094169689Skan  rtx low = gen_rtx_REG (DFmode, REGNO (operands[1]));
2095169689Skan  emit_move_insn (adjust_address (operands[0], DFmode, 0), low);
2096169689Skan  emit_move_insn (adjust_address (operands[0], DFmode, 8), low);
2097169689Skan  DONE;
2098169689Skan})
2099169689Skan
2100169689Skan(define_insn "sse2_unpcklpd"
2101169689Skan  [(set (match_operand:V2DF 0 "nonimmediate_operand"     "=x,x,o")
2102169689Skan	(vec_select:V2DF
2103169689Skan	  (vec_concat:V4DF
2104169689Skan	    (match_operand:V2DF 1 "nonimmediate_operand" " 0,0,0")
2105169689Skan	    (match_operand:V2DF 2 "nonimmediate_operand" " x,m,x"))
2106169689Skan	  (parallel [(const_int 0)
2107169689Skan		     (const_int 2)])))]
2108169689Skan  "TARGET_SSE2 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
2109169689Skan  "@
2110169689Skan   unpcklpd\t{%2, %0|%0, %2}
2111169689Skan   movhpd\t{%2, %0|%0, %2}
2112169689Skan   movlpd\t{%2, %H0|%H0, %2}"
2113169689Skan  [(set_attr "type" "sselog,ssemov,ssemov")
2114169689Skan   (set_attr "mode" "V2DF,V1DF,V1DF")])
2115169689Skan
2116169689Skan(define_expand "sse2_shufpd"
2117169689Skan  [(match_operand:V2DF 0 "register_operand" "")
2118169689Skan   (match_operand:V2DF 1 "register_operand" "")
2119169689Skan   (match_operand:V2DF 2 "nonimmediate_operand" "")
2120169689Skan   (match_operand:SI 3 "const_int_operand" "")]
2121169689Skan  "TARGET_SSE2"
2122169689Skan{
2123169689Skan  int mask = INTVAL (operands[3]);
2124169689Skan  emit_insn (gen_sse2_shufpd_1 (operands[0], operands[1], operands[2],
2125169689Skan				GEN_INT (mask & 1),
2126169689Skan				GEN_INT (mask & 2 ? 3 : 2)));
2127169689Skan  DONE;
2128169689Skan})
2129169689Skan
2130169689Skan(define_insn "sse2_shufpd_1"
2131169689Skan  [(set (match_operand:V2DF 0 "register_operand" "=x")
2132169689Skan	(vec_select:V2DF
2133169689Skan	  (vec_concat:V4DF
2134169689Skan	    (match_operand:V2DF 1 "register_operand" "0")
2135169689Skan	    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
2136169689Skan	  (parallel [(match_operand 3 "const_0_to_1_operand" "")
2137169689Skan		     (match_operand 4 "const_2_to_3_operand" "")])))]
2138169689Skan  "TARGET_SSE2"
2139169689Skan{
2140169689Skan  int mask;
2141169689Skan  mask = INTVAL (operands[3]);
2142169689Skan  mask |= (INTVAL (operands[4]) - 2) << 1;
2143169689Skan  operands[3] = GEN_INT (mask);
2144169689Skan
2145169689Skan  return "shufpd\t{%3, %2, %0|%0, %2, %3}";
2146169689Skan}
2147169689Skan  [(set_attr "type" "sselog")
2148169689Skan   (set_attr "mode" "V2DF")])
2149169689Skan
2150169689Skan(define_insn "sse2_storehpd"
2151169689Skan  [(set (match_operand:DF 0 "nonimmediate_operand"     "=m,x,x*fr")
2152169689Skan	(vec_select:DF
2153169689Skan	  (match_operand:V2DF 1 "nonimmediate_operand" " x,0,o")
2154169689Skan	  (parallel [(const_int 1)])))]
2155169689Skan  "TARGET_SSE2 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2156169689Skan  "@
2157169689Skan   movhpd\t{%1, %0|%0, %1}
2158169689Skan   unpckhpd\t%0, %0
2159169689Skan   #"
2160169689Skan  [(set_attr "type" "ssemov,sselog1,ssemov")
2161169689Skan   (set_attr "mode" "V1DF,V2DF,DF")])
2162169689Skan
2163169689Skan(define_split
2164169689Skan  [(set (match_operand:DF 0 "register_operand" "")
2165169689Skan	(vec_select:DF
2166169689Skan	  (match_operand:V2DF 1 "memory_operand" "")
2167169689Skan	  (parallel [(const_int 1)])))]
2168169689Skan  "TARGET_SSE2 && reload_completed"
2169169689Skan  [(set (match_dup 0) (match_dup 1))]
2170169689Skan{
2171169689Skan  operands[1] = adjust_address (operands[1], DFmode, 8);
2172169689Skan})
2173169689Skan
2174169689Skan(define_insn "sse2_storelpd"
2175169689Skan  [(set (match_operand:DF 0 "nonimmediate_operand"     "=m,x,x*fr")
2176169689Skan	(vec_select:DF
2177169689Skan	  (match_operand:V2DF 1 "nonimmediate_operand" " x,x,m")
2178169689Skan	  (parallel [(const_int 0)])))]
2179169689Skan  "TARGET_SSE2 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2180169689Skan  "@
2181169689Skan   movlpd\t{%1, %0|%0, %1}
2182169689Skan   #
2183169689Skan   #"
2184169689Skan  [(set_attr "type" "ssemov")
2185169689Skan   (set_attr "mode" "V1DF,DF,DF")])
2186169689Skan
2187169689Skan(define_split
2188169689Skan  [(set (match_operand:DF 0 "register_operand" "")
2189169689Skan	(vec_select:DF
2190169689Skan	  (match_operand:V2DF 1 "nonimmediate_operand" "")
2191169689Skan	  (parallel [(const_int 0)])))]
2192169689Skan  "TARGET_SSE2 && reload_completed"
2193169689Skan  [(const_int 0)]
2194169689Skan{
2195169689Skan  rtx op1 = operands[1];
2196169689Skan  if (REG_P (op1))
2197169689Skan    op1 = gen_rtx_REG (DFmode, REGNO (op1));
2198169689Skan  else
2199169689Skan    op1 = gen_lowpart (DFmode, op1);
2200169689Skan  emit_move_insn (operands[0], op1);
2201169689Skan  DONE;
2202169689Skan})
2203169689Skan
2204169689Skan(define_insn "sse2_loadhpd"
2205169689Skan  [(set (match_operand:V2DF 0 "nonimmediate_operand"     "=x,x,x,o")
2206169689Skan	(vec_concat:V2DF
2207169689Skan	  (vec_select:DF
2208169689Skan	    (match_operand:V2DF 1 "nonimmediate_operand" " 0,0,x,0")
2209169689Skan	    (parallel [(const_int 0)]))
2210169689Skan	  (match_operand:DF 2 "nonimmediate_operand"     " m,x,0,x*fr")))]
2211169689Skan  "TARGET_SSE2 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
2212169689Skan  "@
2213169689Skan   movhpd\t{%2, %0|%0, %2}
2214169689Skan   unpcklpd\t{%2, %0|%0, %2}
2215169689Skan   shufpd\t{$1, %1, %0|%0, %1, 1}
2216169689Skan   #"
2217169689Skan  [(set_attr "type" "ssemov,sselog,sselog,other")
2218169689Skan   (set_attr "mode" "V1DF,V2DF,V2DF,DF")])
2219169689Skan
2220169689Skan(define_split
2221169689Skan  [(set (match_operand:V2DF 0 "memory_operand" "")
2222169689Skan	(vec_concat:V2DF
2223169689Skan	  (vec_select:DF (match_dup 0) (parallel [(const_int 0)]))
2224169689Skan	  (match_operand:DF 1 "register_operand" "")))]
2225169689Skan  "TARGET_SSE2 && reload_completed"
2226169689Skan  [(set (match_dup 0) (match_dup 1))]
2227169689Skan{
2228169689Skan  operands[0] = adjust_address (operands[0], DFmode, 8);
2229169689Skan})
2230169689Skan
2231169689Skan(define_insn "sse2_loadlpd"
2232169689Skan  [(set (match_operand:V2DF 0 "nonimmediate_operand"    "=x,x,x,x,x,m")
2233169689Skan	(vec_concat:V2DF
2234169689Skan	  (match_operand:DF 2 "nonimmediate_operand"    " m,m,x,0,0,x*fr")
2235169689Skan	  (vec_select:DF
2236169689Skan	    (match_operand:V2DF 1 "vector_move_operand" " C,0,0,x,o,0")
2237169689Skan	    (parallel [(const_int 1)]))))]
2238169689Skan  "TARGET_SSE2 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
2239169689Skan  "@
2240169689Skan   movsd\t{%2, %0|%0, %2}
2241169689Skan   movlpd\t{%2, %0|%0, %2}
2242169689Skan   movsd\t{%2, %0|%0, %2}
2243169689Skan   shufpd\t{$2, %2, %0|%0, %2, 2}
2244169689Skan   movhpd\t{%H1, %0|%0, %H1}
2245169689Skan   #"
2246169689Skan  [(set_attr "type" "ssemov,ssemov,ssemov,sselog,ssemov,other")
2247169689Skan   (set_attr "mode" "DF,V1DF,V1DF,V2DF,V1DF,DF")])
2248169689Skan
2249169689Skan(define_split
2250169689Skan  [(set (match_operand:V2DF 0 "memory_operand" "")
2251169689Skan	(vec_concat:V2DF
2252169689Skan	  (match_operand:DF 1 "register_operand" "")
2253169689Skan	  (vec_select:DF (match_dup 0) (parallel [(const_int 1)]))))]
2254169689Skan  "TARGET_SSE2 && reload_completed"
2255169689Skan  [(set (match_dup 0) (match_dup 1))]
2256169689Skan{
2257169689Skan  operands[0] = adjust_address (operands[0], DFmode, 8);
2258169689Skan})
2259169689Skan
2260169689Skan;; Not sure these two are ever used, but it doesn't hurt to have
2261169689Skan;; them. -aoliva
2262169689Skan(define_insn "*vec_extractv2df_1_sse"
2263169689Skan  [(set (match_operand:DF 0 "nonimmediate_operand" "=m,x,x")
2264169689Skan	(vec_select:DF
2265169689Skan	  (match_operand:V2DF 1 "nonimmediate_operand" "x,x,o")
2266169689Skan	  (parallel [(const_int 1)])))]
2267169689Skan  "!TARGET_SSE2 && TARGET_SSE
2268169689Skan   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2269169689Skan  "@
2270169689Skan   movhps\t{%1, %0|%0, %1}
2271169689Skan   movhlps\t{%1, %0|%0, %1}
2272169689Skan   movlps\t{%H1, %0|%0, %H1}"
2273169689Skan  [(set_attr "type" "ssemov")
2274169689Skan   (set_attr "mode" "V2SF,V4SF,V2SF")])
2275169689Skan
2276169689Skan(define_insn "*vec_extractv2df_0_sse"
2277169689Skan  [(set (match_operand:DF 0 "nonimmediate_operand" "=m,x,x")
2278169689Skan	(vec_select:DF
2279169689Skan	  (match_operand:V2DF 1 "nonimmediate_operand" "x,x,m")
2280169689Skan	  (parallel [(const_int 0)])))]
2281169689Skan  "!TARGET_SSE2 && TARGET_SSE
2282169689Skan   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2283169689Skan  "@
2284169689Skan   movlps\t{%1, %0|%0, %1}
2285169689Skan   movaps\t{%1, %0|%0, %1}
2286169689Skan   movlps\t{%1, %0|%0, %1}"
2287169689Skan  [(set_attr "type" "ssemov")
2288169689Skan   (set_attr "mode" "V2SF,V4SF,V2SF")])
2289169689Skan
2290169689Skan(define_insn "sse2_movsd"
2291169689Skan  [(set (match_operand:V2DF 0 "nonimmediate_operand"   "=x,x,m,x,x,o")
2292169689Skan	(vec_merge:V2DF
2293169689Skan	  (match_operand:V2DF 2 "nonimmediate_operand" " x,m,x,0,0,0")
2294169689Skan	  (match_operand:V2DF 1 "nonimmediate_operand" " 0,0,0,x,o,x")
2295169689Skan	  (const_int 1)))]
2296169689Skan  "TARGET_SSE2"
2297169689Skan  "@
2298169689Skan   movsd\t{%2, %0|%0, %2}
2299169689Skan   movlpd\t{%2, %0|%0, %2}
2300169689Skan   movlpd\t{%2, %0|%0, %2}
2301169689Skan   shufpd\t{$2, %2, %0|%0, %2, 2}
2302169689Skan   movhps\t{%H1, %0|%0, %H1}
2303169689Skan   movhps\t{%1, %H0|%H0, %1}"
2304169689Skan  [(set_attr "type" "ssemov,ssemov,ssemov,sselog,ssemov,ssemov")
2305169689Skan   (set_attr "mode" "DF,V1DF,V1DF,V2DF,V1DF,V1DF")])
2306169689Skan
2307169689Skan(define_insn "*vec_dupv2df_sse3"
2308169689Skan  [(set (match_operand:V2DF 0 "register_operand" "=x")
2309169689Skan	(vec_duplicate:V2DF
2310169689Skan	  (match_operand:DF 1 "nonimmediate_operand" "xm")))]
2311169689Skan  "TARGET_SSE3"
2312169689Skan  "movddup\t{%1, %0|%0, %1}"
2313169689Skan  [(set_attr "type" "sselog1")
2314169689Skan   (set_attr "mode" "DF")])
2315169689Skan
2316169689Skan(define_insn "*vec_dupv2df"
2317169689Skan  [(set (match_operand:V2DF 0 "register_operand" "=x")
2318169689Skan	(vec_duplicate:V2DF
2319169689Skan	  (match_operand:DF 1 "register_operand" "0")))]
2320169689Skan  "TARGET_SSE2"
2321169689Skan  "unpcklpd\t%0, %0"
2322169689Skan  [(set_attr "type" "sselog1")
2323169689Skan   (set_attr "mode" "V4SF")])
2324169689Skan
2325169689Skan(define_insn "*vec_concatv2df_sse3"
2326169689Skan  [(set (match_operand:V2DF 0 "register_operand" "=x")
2327169689Skan	(vec_concat:V2DF
2328169689Skan	  (match_operand:DF 1 "nonimmediate_operand" "xm")
2329169689Skan	  (match_dup 1)))]
2330169689Skan  "TARGET_SSE3"
2331169689Skan  "movddup\t{%1, %0|%0, %1}"
2332169689Skan  [(set_attr "type" "sselog1")
2333169689Skan   (set_attr "mode" "DF")])
2334169689Skan
2335169689Skan(define_insn "*vec_concatv2df"
2336169689Skan  [(set (match_operand:V2DF 0 "register_operand"     "=Y,Y,Y,x,x")
2337169689Skan	(vec_concat:V2DF
2338169689Skan	  (match_operand:DF 1 "nonimmediate_operand" " 0,0,m,0,0")
2339169689Skan	  (match_operand:DF 2 "vector_move_operand"  " Y,m,C,x,m")))]
2340169689Skan  "TARGET_SSE"
2341169689Skan  "@
2342169689Skan   unpcklpd\t{%2, %0|%0, %2}
2343169689Skan   movhpd\t{%2, %0|%0, %2}
2344169689Skan   movsd\t{%1, %0|%0, %1}
2345169689Skan   movlhps\t{%2, %0|%0, %2}
2346169689Skan   movhps\t{%2, %0|%0, %2}"
2347169689Skan  [(set_attr "type" "sselog,ssemov,ssemov,ssemov,ssemov")
2348169689Skan   (set_attr "mode" "V2DF,V1DF,DF,V4SF,V2SF")])
2349169689Skan
2350169689Skan(define_expand "vec_setv2df"
2351169689Skan  [(match_operand:V2DF 0 "register_operand" "")
2352169689Skan   (match_operand:DF 1 "register_operand" "")
2353169689Skan   (match_operand 2 "const_int_operand" "")]
2354169689Skan  "TARGET_SSE"
2355169689Skan{
2356169689Skan  ix86_expand_vector_set (false, operands[0], operands[1],
2357169689Skan			  INTVAL (operands[2]));
2358169689Skan  DONE;
2359169689Skan})
2360169689Skan
2361169689Skan(define_expand "vec_extractv2df"
2362169689Skan  [(match_operand:DF 0 "register_operand" "")
2363169689Skan   (match_operand:V2DF 1 "register_operand" "")
2364169689Skan   (match_operand 2 "const_int_operand" "")]
2365169689Skan  "TARGET_SSE"
2366169689Skan{
2367169689Skan  ix86_expand_vector_extract (false, operands[0], operands[1],
2368169689Skan			      INTVAL (operands[2]));
2369169689Skan  DONE;
2370169689Skan})
2371169689Skan
2372169689Skan(define_expand "vec_initv2df"
2373169689Skan  [(match_operand:V2DF 0 "register_operand" "")
2374169689Skan   (match_operand 1 "" "")]
2375169689Skan  "TARGET_SSE"
2376169689Skan{
2377169689Skan  ix86_expand_vector_init (false, operands[0], operands[1]);
2378169689Skan  DONE;
2379169689Skan})
2380169689Skan
2381169689Skan;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2382169689Skan;;
2383169689Skan;; Parallel integral arithmetic
2384169689Skan;;
2385169689Skan;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2386169689Skan
2387169689Skan(define_expand "neg<mode>2"
2388169689Skan  [(set (match_operand:SSEMODEI 0 "register_operand" "")
2389169689Skan	(minus:SSEMODEI
2390169689Skan	  (match_dup 2)
2391169689Skan	  (match_operand:SSEMODEI 1 "nonimmediate_operand" "")))]
2392169689Skan  "TARGET_SSE2"
2393169689Skan  "operands[2] = force_reg (<MODE>mode, CONST0_RTX (<MODE>mode));")
2394169689Skan
2395169689Skan(define_expand "add<mode>3"
2396169689Skan  [(set (match_operand:SSEMODEI 0 "register_operand" "")
2397169689Skan	(plus:SSEMODEI (match_operand:SSEMODEI 1 "nonimmediate_operand" "")
2398169689Skan		       (match_operand:SSEMODEI 2 "nonimmediate_operand" "")))]
2399169689Skan  "TARGET_SSE2"
2400169689Skan  "ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);")
2401169689Skan
2402169689Skan(define_insn "*add<mode>3"
2403169689Skan  [(set (match_operand:SSEMODEI 0 "register_operand" "=x")
2404169689Skan	(plus:SSEMODEI
2405169689Skan	  (match_operand:SSEMODEI 1 "nonimmediate_operand" "%0")
2406169689Skan	  (match_operand:SSEMODEI 2 "nonimmediate_operand" "xm")))]
2407169689Skan  "TARGET_SSE2 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
2408169689Skan  "padd<ssevecsize>\t{%2, %0|%0, %2}"
2409169689Skan  [(set_attr "type" "sseiadd")
2410169689Skan   (set_attr "mode" "TI")])
2411169689Skan
2412169689Skan(define_insn "sse2_ssadd<mode>3"
2413169689Skan  [(set (match_operand:SSEMODE12 0 "register_operand" "=x")
2414169689Skan	(ss_plus:SSEMODE12
2415169689Skan	  (match_operand:SSEMODE12 1 "nonimmediate_operand" "%0")
2416169689Skan	  (match_operand:SSEMODE12 2 "nonimmediate_operand" "xm")))]
2417169689Skan  "TARGET_SSE2 && ix86_binary_operator_ok (SS_PLUS, <MODE>mode, operands)"
2418169689Skan  "padds<ssevecsize>\t{%2, %0|%0, %2}"
2419169689Skan  [(set_attr "type" "sseiadd")
2420169689Skan   (set_attr "mode" "TI")])
2421169689Skan
2422169689Skan(define_insn "sse2_usadd<mode>3"
2423169689Skan  [(set (match_operand:SSEMODE12 0 "register_operand" "=x")
2424169689Skan	(us_plus:SSEMODE12
2425169689Skan	  (match_operand:SSEMODE12 1 "nonimmediate_operand" "%0")
2426169689Skan	  (match_operand:SSEMODE12 2 "nonimmediate_operand" "xm")))]
2427169689Skan  "TARGET_SSE2 && ix86_binary_operator_ok (US_PLUS, <MODE>mode, operands)"
2428169689Skan  "paddus<ssevecsize>\t{%2, %0|%0, %2}"
2429169689Skan  [(set_attr "type" "sseiadd")
2430169689Skan   (set_attr "mode" "TI")])
2431169689Skan
2432169689Skan(define_expand "sub<mode>3"
2433169689Skan  [(set (match_operand:SSEMODEI 0 "register_operand" "")
2434169689Skan	(minus:SSEMODEI (match_operand:SSEMODEI 1 "register_operand" "")
2435169689Skan			(match_operand:SSEMODEI 2 "nonimmediate_operand" "")))]
2436169689Skan  "TARGET_SSE2"
2437169689Skan  "ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);")
2438169689Skan
2439169689Skan(define_insn "*sub<mode>3"
2440169689Skan  [(set (match_operand:SSEMODEI 0 "register_operand" "=x")
2441169689Skan	(minus:SSEMODEI
2442169689Skan	  (match_operand:SSEMODEI 1 "register_operand" "0")
2443169689Skan	  (match_operand:SSEMODEI 2 "nonimmediate_operand" "xm")))]
2444169689Skan  "TARGET_SSE2"
2445169689Skan  "psub<ssevecsize>\t{%2, %0|%0, %2}"
2446169689Skan  [(set_attr "type" "sseiadd")
2447169689Skan   (set_attr "mode" "TI")])
2448169689Skan
2449169689Skan(define_insn "sse2_sssub<mode>3"
2450169689Skan  [(set (match_operand:SSEMODE12 0 "register_operand" "=x")
2451169689Skan	(ss_minus:SSEMODE12
2452169689Skan	  (match_operand:SSEMODE12 1 "register_operand" "0")
2453169689Skan	  (match_operand:SSEMODE12 2 "nonimmediate_operand" "xm")))]
2454169689Skan  "TARGET_SSE2"
2455169689Skan  "psubs<ssevecsize>\t{%2, %0|%0, %2}"
2456169689Skan  [(set_attr "type" "sseiadd")
2457169689Skan   (set_attr "mode" "TI")])
2458169689Skan
2459169689Skan(define_insn "sse2_ussub<mode>3"
2460169689Skan  [(set (match_operand:SSEMODE12 0 "register_operand" "=x")
2461169689Skan	(us_minus:SSEMODE12
2462169689Skan	  (match_operand:SSEMODE12 1 "register_operand" "0")
2463169689Skan	  (match_operand:SSEMODE12 2 "nonimmediate_operand" "xm")))]
2464169689Skan  "TARGET_SSE2"
2465169689Skan  "psubus<ssevecsize>\t{%2, %0|%0, %2}"
2466169689Skan  [(set_attr "type" "sseiadd")
2467169689Skan   (set_attr "mode" "TI")])
2468169689Skan
2469169689Skan(define_expand "mulv16qi3"
2470169689Skan  [(set (match_operand:V16QI 0 "register_operand" "")
2471169689Skan	(mult:V16QI (match_operand:V16QI 1 "register_operand" "")
2472169689Skan		    (match_operand:V16QI 2 "register_operand" "")))]
2473169689Skan  "TARGET_SSE2"
2474169689Skan{
2475169689Skan  rtx t[12], op0;
2476169689Skan  int i;
2477169689Skan
2478169689Skan  for (i = 0; i < 12; ++i)
2479169689Skan    t[i] = gen_reg_rtx (V16QImode);
2480169689Skan
2481169689Skan  /* Unpack data such that we've got a source byte in each low byte of
2482169689Skan     each word.  We don't care what goes into the high byte of each word.
2483169689Skan     Rather than trying to get zero in there, most convenient is to let
2484169689Skan     it be a copy of the low byte.  */
2485169689Skan  emit_insn (gen_sse2_punpckhbw (t[0], operands[1], operands[1]));
2486169689Skan  emit_insn (gen_sse2_punpckhbw (t[1], operands[2], operands[2]));
2487169689Skan  emit_insn (gen_sse2_punpcklbw (t[2], operands[1], operands[1]));
2488169689Skan  emit_insn (gen_sse2_punpcklbw (t[3], operands[2], operands[2]));
2489169689Skan
2490169689Skan  /* Multiply words.  The end-of-line annotations here give a picture of what
2491169689Skan     the output of that instruction looks like.  Dot means don't care; the 
2492169689Skan     letters are the bytes of the result with A being the most significant.  */
2493169689Skan  emit_insn (gen_mulv8hi3 (gen_lowpart (V8HImode, t[4]), /* .A.B.C.D.E.F.G.H */
2494169689Skan			   gen_lowpart (V8HImode, t[0]),
2495169689Skan			   gen_lowpart (V8HImode, t[1])));
2496169689Skan  emit_insn (gen_mulv8hi3 (gen_lowpart (V8HImode, t[5]), /* .I.J.K.L.M.N.O.P */
2497169689Skan			   gen_lowpart (V8HImode, t[2]),
2498169689Skan			   gen_lowpart (V8HImode, t[3])));
2499169689Skan
2500169689Skan  /* Extract the relevant bytes and merge them back together.  */
2501169689Skan  emit_insn (gen_sse2_punpckhbw (t[6], t[5], t[4]));	/* ..AI..BJ..CK..DL */
2502169689Skan  emit_insn (gen_sse2_punpcklbw (t[7], t[5], t[4]));	/* ..EM..FN..GO..HP */
2503169689Skan  emit_insn (gen_sse2_punpckhbw (t[8], t[7], t[6]));	/* ....AEIM....BFJN */
2504169689Skan  emit_insn (gen_sse2_punpcklbw (t[9], t[7], t[6]));	/* ....CGKO....DHLP */
2505169689Skan  emit_insn (gen_sse2_punpckhbw (t[10], t[9], t[8]));	/* ........ACEGIKMO */
2506169689Skan  emit_insn (gen_sse2_punpcklbw (t[11], t[9], t[8]));	/* ........BDFHJLNP */
2507169689Skan
2508169689Skan  op0 = operands[0];
2509169689Skan  emit_insn (gen_sse2_punpcklbw (op0, t[11], t[10]));	/* ABCDEFGHIJKLMNOP */
2510169689Skan  DONE;
2511169689Skan})
2512169689Skan
2513169689Skan(define_expand "mulv8hi3"
2514169689Skan  [(set (match_operand:V8HI 0 "register_operand" "")
2515169689Skan	(mult:V8HI (match_operand:V8HI 1 "nonimmediate_operand" "")
2516169689Skan		   (match_operand:V8HI 2 "nonimmediate_operand" "")))]
2517169689Skan  "TARGET_SSE2"
2518169689Skan  "ix86_fixup_binary_operands_no_copy (MULT, V8HImode, operands);")
2519169689Skan
2520169689Skan(define_insn "*mulv8hi3"
2521169689Skan  [(set (match_operand:V8HI 0 "register_operand" "=x")
2522169689Skan	(mult:V8HI (match_operand:V8HI 1 "nonimmediate_operand" "%0")
2523169689Skan		   (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
2524169689Skan  "TARGET_SSE2 && ix86_binary_operator_ok (MULT, V8HImode, operands)"
2525169689Skan  "pmullw\t{%2, %0|%0, %2}"
2526169689Skan  [(set_attr "type" "sseimul")
2527169689Skan   (set_attr "mode" "TI")])
2528169689Skan
2529169689Skan(define_insn "sse2_smulv8hi3_highpart"
2530169689Skan  [(set (match_operand:V8HI 0 "register_operand" "=x")
2531169689Skan	(truncate:V8HI
2532169689Skan	  (lshiftrt:V8SI
2533169689Skan	    (mult:V8SI
2534169689Skan	      (sign_extend:V8SI
2535169689Skan		(match_operand:V8HI 1 "nonimmediate_operand" "%0"))
2536169689Skan	      (sign_extend:V8SI
2537169689Skan		(match_operand:V8HI 2 "nonimmediate_operand" "xm")))
2538169689Skan	    (const_int 16))))]
2539169689Skan  "TARGET_SSE2 && ix86_binary_operator_ok (MULT, V8HImode, operands)"
2540169689Skan  "pmulhw\t{%2, %0|%0, %2}"
2541169689Skan  [(set_attr "type" "sseimul")
2542169689Skan   (set_attr "mode" "TI")])
2543169689Skan
2544169689Skan(define_insn "sse2_umulv8hi3_highpart"
2545169689Skan  [(set (match_operand:V8HI 0 "register_operand" "=x")
2546169689Skan	(truncate:V8HI
2547169689Skan	  (lshiftrt:V8SI
2548169689Skan	    (mult:V8SI
2549169689Skan	      (zero_extend:V8SI
2550169689Skan		(match_operand:V8HI 1 "nonimmediate_operand" "%0"))
2551169689Skan	      (zero_extend:V8SI
2552169689Skan		(match_operand:V8HI 2 "nonimmediate_operand" "xm")))
2553169689Skan	    (const_int 16))))]
2554169689Skan  "TARGET_SSE2 && ix86_binary_operator_ok (MULT, V8HImode, operands)"
2555169689Skan  "pmulhuw\t{%2, %0|%0, %2}"
2556169689Skan  [(set_attr "type" "sseimul")
2557169689Skan   (set_attr "mode" "TI")])
2558169689Skan
2559169689Skan(define_insn "sse2_umulv2siv2di3"
2560169689Skan  [(set (match_operand:V2DI 0 "register_operand" "=x")
2561169689Skan	(mult:V2DI
2562169689Skan	  (zero_extend:V2DI
2563169689Skan	    (vec_select:V2SI
2564169689Skan	      (match_operand:V4SI 1 "nonimmediate_operand" "%0")
2565169689Skan	      (parallel [(const_int 0) (const_int 2)])))
2566169689Skan	  (zero_extend:V2DI
2567169689Skan	    (vec_select:V2SI
2568169689Skan	      (match_operand:V4SI 2 "nonimmediate_operand" "xm")
2569169689Skan	      (parallel [(const_int 0) (const_int 2)])))))]
2570169689Skan  "TARGET_SSE2 && ix86_binary_operator_ok (MULT, V8HImode, operands)"
2571169689Skan  "pmuludq\t{%2, %0|%0, %2}"
2572169689Skan  [(set_attr "type" "sseimul")
2573169689Skan   (set_attr "mode" "TI")])
2574169689Skan
2575169689Skan(define_insn "sse2_pmaddwd"
2576169689Skan  [(set (match_operand:V4SI 0 "register_operand" "=x")
2577169689Skan	(plus:V4SI
2578169689Skan	  (mult:V4SI
2579169689Skan	    (sign_extend:V4SI
2580169689Skan	      (vec_select:V4HI
2581169689Skan		(match_operand:V8HI 1 "nonimmediate_operand" "%0")
2582169689Skan		(parallel [(const_int 0)
2583169689Skan			   (const_int 2)
2584169689Skan			   (const_int 4)
2585169689Skan			   (const_int 6)])))
2586169689Skan	    (sign_extend:V4SI
2587169689Skan	      (vec_select:V4HI
2588169689Skan		(match_operand:V8HI 2 "nonimmediate_operand" "xm")
2589169689Skan		(parallel [(const_int 0)
2590169689Skan			   (const_int 2)
2591169689Skan			   (const_int 4)
2592169689Skan			   (const_int 6)]))))
2593169689Skan	  (mult:V4SI
2594169689Skan	    (sign_extend:V4SI
2595169689Skan	      (vec_select:V4HI (match_dup 1)
2596169689Skan		(parallel [(const_int 1)
2597169689Skan			   (const_int 3)
2598169689Skan			   (const_int 5)
2599169689Skan			   (const_int 7)])))
2600169689Skan	    (sign_extend:V4SI
2601169689Skan	      (vec_select:V4HI (match_dup 2)
2602169689Skan		(parallel [(const_int 1)
2603169689Skan			   (const_int 3)
2604169689Skan			   (const_int 5)
2605169689Skan			   (const_int 7)]))))))]
2606169689Skan  "TARGET_SSE2"
2607169689Skan  "pmaddwd\t{%2, %0|%0, %2}"
2608169689Skan  [(set_attr "type" "sseiadd")
2609169689Skan   (set_attr "mode" "TI")])
2610169689Skan
2611169689Skan(define_expand "mulv4si3"
2612169689Skan  [(set (match_operand:V4SI 0 "register_operand" "")
2613169689Skan	(mult:V4SI (match_operand:V4SI 1 "register_operand" "")
2614169689Skan		   (match_operand:V4SI 2 "register_operand" "")))]
2615169689Skan  "TARGET_SSE2"
2616169689Skan{
2617169689Skan  rtx t1, t2, t3, t4, t5, t6, thirtytwo;
2618169689Skan  rtx op0, op1, op2;
2619169689Skan
2620169689Skan  op0 = operands[0];
2621169689Skan  op1 = operands[1];
2622169689Skan  op2 = operands[2];
2623169689Skan  t1 = gen_reg_rtx (V4SImode);
2624169689Skan  t2 = gen_reg_rtx (V4SImode);
2625169689Skan  t3 = gen_reg_rtx (V4SImode);
2626169689Skan  t4 = gen_reg_rtx (V4SImode);
2627169689Skan  t5 = gen_reg_rtx (V4SImode);
2628169689Skan  t6 = gen_reg_rtx (V4SImode);
2629169689Skan  thirtytwo = GEN_INT (32);
2630169689Skan
2631169689Skan  /* Multiply elements 2 and 0.  */
2632169689Skan  emit_insn (gen_sse2_umulv2siv2di3 (gen_lowpart (V2DImode, t1), op1, op2));
2633169689Skan
2634169689Skan  /* Shift both input vectors down one element, so that elements 3 and 1
2635169689Skan     are now in the slots for elements 2 and 0.  For K8, at least, this is
2636169689Skan     faster than using a shuffle.  */
2637169689Skan  emit_insn (gen_sse2_lshrti3 (gen_lowpart (TImode, t2),
2638169689Skan			       gen_lowpart (TImode, op1), thirtytwo));
2639169689Skan  emit_insn (gen_sse2_lshrti3 (gen_lowpart (TImode, t3),
2640169689Skan			       gen_lowpart (TImode, op2), thirtytwo));
2641169689Skan
2642169689Skan  /* Multiply elements 3 and 1.  */
2643169689Skan  emit_insn (gen_sse2_umulv2siv2di3 (gen_lowpart (V2DImode, t4), t2, t3));
2644169689Skan
2645169689Skan  /* Move the results in element 2 down to element 1; we don't care what
2646169689Skan     goes in elements 2 and 3.  */
2647169689Skan  emit_insn (gen_sse2_pshufd_1 (t5, t1, const0_rtx, const2_rtx,
2648169689Skan				const0_rtx, const0_rtx));
2649169689Skan  emit_insn (gen_sse2_pshufd_1 (t6, t4, const0_rtx, const2_rtx,
2650169689Skan				const0_rtx, const0_rtx));
2651169689Skan
2652169689Skan  /* Merge the parts back together.  */
2653169689Skan  emit_insn (gen_sse2_punpckldq (op0, t5, t6));
2654169689Skan  DONE;
2655169689Skan})
2656169689Skan
2657169689Skan(define_expand "mulv2di3"
2658169689Skan  [(set (match_operand:V2DI 0 "register_operand" "")
2659169689Skan	(mult:V2DI (match_operand:V2DI 1 "register_operand" "")
2660169689Skan		   (match_operand:V2DI 2 "register_operand" "")))]
2661169689Skan  "TARGET_SSE2"
2662169689Skan{
2663169689Skan  rtx t1, t2, t3, t4, t5, t6, thirtytwo;
2664169689Skan  rtx op0, op1, op2;
2665169689Skan
2666169689Skan  op0 = operands[0];
2667169689Skan  op1 = operands[1];
2668169689Skan  op2 = operands[2];
2669169689Skan  t1 = gen_reg_rtx (V2DImode);
2670169689Skan  t2 = gen_reg_rtx (V2DImode);
2671169689Skan  t3 = gen_reg_rtx (V2DImode);
2672169689Skan  t4 = gen_reg_rtx (V2DImode);
2673169689Skan  t5 = gen_reg_rtx (V2DImode);
2674169689Skan  t6 = gen_reg_rtx (V2DImode);
2675169689Skan  thirtytwo = GEN_INT (32);
2676169689Skan
2677169689Skan  /* Multiply low parts.  */
2678169689Skan  emit_insn (gen_sse2_umulv2siv2di3 (t1, gen_lowpart (V4SImode, op1),
2679169689Skan				     gen_lowpart (V4SImode, op2)));
2680169689Skan
2681169689Skan  /* Shift input vectors left 32 bits so we can multiply high parts.  */
2682169689Skan  emit_insn (gen_lshrv2di3 (t2, op1, thirtytwo));
2683169689Skan  emit_insn (gen_lshrv2di3 (t3, op2, thirtytwo));
2684169689Skan
2685169689Skan  /* Multiply high parts by low parts.  */
2686169689Skan  emit_insn (gen_sse2_umulv2siv2di3 (t4, gen_lowpart (V4SImode, op1),
2687169689Skan				     gen_lowpart (V4SImode, t3)));
2688169689Skan  emit_insn (gen_sse2_umulv2siv2di3 (t5, gen_lowpart (V4SImode, op2),
2689169689Skan				     gen_lowpart (V4SImode, t2)));
2690169689Skan
2691169689Skan  /* Shift them back.  */
2692169689Skan  emit_insn (gen_ashlv2di3 (t4, t4, thirtytwo));
2693169689Skan  emit_insn (gen_ashlv2di3 (t5, t5, thirtytwo));
2694169689Skan
2695169689Skan  /* Add the three parts together.  */
2696169689Skan  emit_insn (gen_addv2di3 (t6, t1, t4));
2697169689Skan  emit_insn (gen_addv2di3 (op0, t6, t5));
2698169689Skan  DONE;
2699169689Skan})
2700169689Skan
2701169689Skan(define_expand "sdot_prodv8hi"
2702169689Skan  [(match_operand:V4SI 0 "register_operand" "")
2703169689Skan   (match_operand:V8HI 1 "nonimmediate_operand" "")
2704169689Skan   (match_operand:V8HI 2 "nonimmediate_operand" "")
2705169689Skan   (match_operand:V4SI 3 "register_operand" "")]
2706169689Skan  "TARGET_SSE2"
2707169689Skan{
2708169689Skan  rtx t = gen_reg_rtx (V4SImode);
2709169689Skan  emit_insn (gen_sse2_pmaddwd (t, operands[1], operands[2]));
2710169689Skan  emit_insn (gen_addv4si3 (operands[0], operands[3], t));
2711169689Skan  DONE;
2712169689Skan})
2713169689Skan
2714169689Skan(define_expand "udot_prodv4si"
2715169689Skan  [(match_operand:V2DI 0 "register_operand" "") 
2716169689Skan   (match_operand:V4SI 1 "register_operand" "") 
2717169689Skan   (match_operand:V4SI 2 "register_operand" "")
2718169689Skan   (match_operand:V2DI 3 "register_operand" "")]
2719169689Skan  "TARGET_SSE2"
2720169689Skan{
2721169689Skan  rtx t1, t2, t3, t4;
2722169689Skan
2723169689Skan  t1 = gen_reg_rtx (V2DImode);
2724169689Skan  emit_insn (gen_sse2_umulv2siv2di3 (t1, operands[1], operands[2]));
2725169689Skan  emit_insn (gen_addv2di3 (t1, t1, operands[3]));
2726169689Skan
2727169689Skan  t2 = gen_reg_rtx (V4SImode);
2728169689Skan  t3 = gen_reg_rtx (V4SImode);
2729169689Skan  emit_insn (gen_sse2_lshrti3 (gen_lowpart (TImode, t2),
2730169689Skan                               gen_lowpart (TImode, operands[1]),
2731169689Skan                               GEN_INT (32)));
2732169689Skan  emit_insn (gen_sse2_lshrti3 (gen_lowpart (TImode, t3),
2733169689Skan                               gen_lowpart (TImode, operands[2]),
2734169689Skan                               GEN_INT (32)));
2735169689Skan
2736169689Skan  t4 = gen_reg_rtx (V2DImode);
2737169689Skan  emit_insn (gen_sse2_umulv2siv2di3 (t4, t2, t3));
2738169689Skan
2739169689Skan  emit_insn (gen_addv2di3 (operands[0], t1, t4));
2740169689Skan  DONE;
2741169689Skan})
2742169689Skan
2743169689Skan(define_insn "ashr<mode>3"
2744169689Skan  [(set (match_operand:SSEMODE24 0 "register_operand" "=x")
2745169689Skan	(ashiftrt:SSEMODE24
2746169689Skan	  (match_operand:SSEMODE24 1 "register_operand" "0")
2747169689Skan	  (match_operand:TI 2 "nonmemory_operand" "xn")))]
2748169689Skan  "TARGET_SSE2"
2749169689Skan  "psra<ssevecsize>\t{%2, %0|%0, %2}"
2750169689Skan  [(set_attr "type" "sseishft")
2751169689Skan   (set_attr "mode" "TI")])
2752169689Skan
2753169689Skan(define_insn "lshr<mode>3"
2754169689Skan  [(set (match_operand:SSEMODE248 0 "register_operand" "=x")
2755169689Skan	(lshiftrt:SSEMODE248
2756169689Skan	  (match_operand:SSEMODE248 1 "register_operand" "0")
2757169689Skan	  (match_operand:TI 2 "nonmemory_operand" "xn")))]
2758169689Skan  "TARGET_SSE2"
2759169689Skan  "psrl<ssevecsize>\t{%2, %0|%0, %2}"
2760169689Skan  [(set_attr "type" "sseishft")
2761169689Skan   (set_attr "mode" "TI")])
2762169689Skan
2763169689Skan(define_insn "ashl<mode>3"
2764169689Skan  [(set (match_operand:SSEMODE248 0 "register_operand" "=x")
2765169689Skan	(ashift:SSEMODE248
2766169689Skan	  (match_operand:SSEMODE248 1 "register_operand" "0")
2767169689Skan	  (match_operand:TI 2 "nonmemory_operand" "xn")))]
2768169689Skan  "TARGET_SSE2"
2769169689Skan  "psll<ssevecsize>\t{%2, %0|%0, %2}"
2770169689Skan  [(set_attr "type" "sseishft")
2771169689Skan   (set_attr "mode" "TI")])
2772169689Skan
2773169689Skan(define_insn "sse2_ashlti3"
2774169689Skan  [(set (match_operand:TI 0 "register_operand" "=x")
2775169689Skan	(ashift:TI (match_operand:TI 1 "register_operand" "0")
2776169689Skan		   (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
2777169689Skan  "TARGET_SSE2"
2778169689Skan{
2779169689Skan  operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
2780169689Skan  return "pslldq\t{%2, %0|%0, %2}";
2781169689Skan}
2782169689Skan  [(set_attr "type" "sseishft")
2783169689Skan   (set_attr "mode" "TI")])
2784169689Skan
2785169689Skan(define_expand "vec_shl_<mode>"
2786169689Skan  [(set (match_operand:SSEMODEI 0 "register_operand" "")
2787169689Skan        (ashift:TI (match_operand:SSEMODEI 1 "register_operand" "")
2788169689Skan		   (match_operand:SI 2 "general_operand" "")))]
2789169689Skan  "TARGET_SSE2"
2790169689Skan{
2791169689Skan  if (!const_0_to_255_mul_8_operand (operands[2], SImode))
2792169689Skan    FAIL;
2793169689Skan  operands[0] = gen_lowpart (TImode, operands[0]);
2794169689Skan  operands[1] = gen_lowpart (TImode, operands[1]);
2795169689Skan})
2796169689Skan
2797169689Skan(define_insn "sse2_lshrti3"
2798169689Skan  [(set (match_operand:TI 0 "register_operand" "=x")
2799169689Skan 	(lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
2800169689Skan		     (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
2801169689Skan  "TARGET_SSE2"
2802169689Skan{
2803169689Skan  operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
2804169689Skan  return "psrldq\t{%2, %0|%0, %2}";
2805169689Skan}
2806169689Skan  [(set_attr "type" "sseishft")
2807169689Skan   (set_attr "mode" "TI")])
2808169689Skan
2809169689Skan(define_expand "vec_shr_<mode>"
2810169689Skan  [(set (match_operand:SSEMODEI 0 "register_operand" "")
2811169689Skan        (lshiftrt:TI (match_operand:SSEMODEI 1 "register_operand" "")
2812169689Skan		     (match_operand:SI 2 "general_operand" "")))]
2813169689Skan  "TARGET_SSE2"
2814169689Skan{
2815169689Skan  if (!const_0_to_255_mul_8_operand (operands[2], SImode))
2816169689Skan    FAIL;
2817169689Skan  operands[0] = gen_lowpart (TImode, operands[0]);
2818169689Skan  operands[1] = gen_lowpart (TImode, operands[1]);
2819169689Skan})
2820169689Skan
2821169689Skan(define_expand "umaxv16qi3"
2822169689Skan  [(set (match_operand:V16QI 0 "register_operand" "")
2823169689Skan	(umax:V16QI (match_operand:V16QI 1 "nonimmediate_operand" "")
2824169689Skan		    (match_operand:V16QI 2 "nonimmediate_operand" "")))]
2825169689Skan  "TARGET_SSE2"
2826169689Skan  "ix86_fixup_binary_operands_no_copy (UMAX, V16QImode, operands);")
2827169689Skan
2828169689Skan(define_insn "*umaxv16qi3"
2829169689Skan  [(set (match_operand:V16QI 0 "register_operand" "=x")
2830169689Skan	(umax:V16QI (match_operand:V16QI 1 "nonimmediate_operand" "%0")
2831169689Skan		    (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
2832169689Skan  "TARGET_SSE2 && ix86_binary_operator_ok (UMAX, V16QImode, operands)"
2833169689Skan  "pmaxub\t{%2, %0|%0, %2}"
2834169689Skan  [(set_attr "type" "sseiadd")
2835169689Skan   (set_attr "mode" "TI")])
2836169689Skan
2837169689Skan(define_expand "smaxv8hi3"
2838169689Skan  [(set (match_operand:V8HI 0 "register_operand" "")
2839169689Skan	(smax:V8HI (match_operand:V8HI 1 "nonimmediate_operand" "")
2840169689Skan		   (match_operand:V8HI 2 "nonimmediate_operand" "")))]
2841169689Skan  "TARGET_SSE2"
2842169689Skan  "ix86_fixup_binary_operands_no_copy (SMAX, V8HImode, operands);")
2843169689Skan
2844169689Skan(define_insn "*smaxv8hi3"
2845169689Skan  [(set (match_operand:V8HI 0 "register_operand" "=x")
2846169689Skan	(smax:V8HI (match_operand:V8HI 1 "nonimmediate_operand" "%0")
2847169689Skan		   (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
2848169689Skan  "TARGET_SSE2 && ix86_binary_operator_ok (SMAX, V8HImode, operands)"
2849169689Skan  "pmaxsw\t{%2, %0|%0, %2}"
2850169689Skan  [(set_attr "type" "sseiadd")
2851169689Skan   (set_attr "mode" "TI")])
2852169689Skan
2853169689Skan(define_expand "umaxv8hi3"
2854169689Skan  [(set (match_operand:V8HI 0 "register_operand" "=x")
2855169689Skan	(us_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
2856169689Skan		       (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
2857169689Skan   (set (match_dup 3)
2858169689Skan	(plus:V8HI (match_dup 0) (match_dup 2)))]
2859169689Skan  "TARGET_SSE2"
2860169689Skan{
2861169689Skan  operands[3] = operands[0];
2862169689Skan  if (rtx_equal_p (operands[0], operands[2]))
2863169689Skan    operands[0] = gen_reg_rtx (V8HImode);
2864169689Skan})
2865169689Skan
2866169689Skan(define_expand "smax<mode>3"
2867169689Skan  [(set (match_operand:SSEMODE14 0 "register_operand" "")
2868169689Skan	(smax:SSEMODE14 (match_operand:SSEMODE14 1 "register_operand" "")
2869169689Skan			(match_operand:SSEMODE14 2 "register_operand" "")))]
2870169689Skan  "TARGET_SSE2"
2871169689Skan{
2872169689Skan  rtx xops[6];
2873169689Skan  bool ok;
2874169689Skan
2875169689Skan  xops[0] = operands[0];
2876169689Skan  xops[1] = operands[1];
2877169689Skan  xops[2] = operands[2];
2878169689Skan  xops[3] = gen_rtx_GT (VOIDmode, operands[1], operands[2]);
2879169689Skan  xops[4] = operands[1];
2880169689Skan  xops[5] = operands[2];
2881169689Skan  ok = ix86_expand_int_vcond (xops);
2882169689Skan  gcc_assert (ok);
2883169689Skan  DONE;
2884169689Skan})
2885169689Skan
2886169689Skan(define_expand "umaxv4si3"
2887169689Skan  [(set (match_operand:V4SI 0 "register_operand" "")
2888169689Skan	(umax:V4SI (match_operand:V4SI 1 "register_operand" "")
2889169689Skan		   (match_operand:V4SI 2 "register_operand" "")))]
2890169689Skan  "TARGET_SSE2"
2891169689Skan{
2892169689Skan  rtx xops[6];
2893169689Skan  bool ok;
2894169689Skan
2895169689Skan  xops[0] = operands[0];
2896169689Skan  xops[1] = operands[1];
2897169689Skan  xops[2] = operands[2];
2898169689Skan  xops[3] = gen_rtx_GTU (VOIDmode, operands[1], operands[2]);
2899169689Skan  xops[4] = operands[1];
2900169689Skan  xops[5] = operands[2];
2901169689Skan  ok = ix86_expand_int_vcond (xops);
2902169689Skan  gcc_assert (ok);
2903169689Skan  DONE;
2904169689Skan})
2905169689Skan
2906169689Skan(define_expand "uminv16qi3"
2907169689Skan  [(set (match_operand:V16QI 0 "register_operand" "")
2908169689Skan	(umin:V16QI (match_operand:V16QI 1 "nonimmediate_operand" "")
2909169689Skan		    (match_operand:V16QI 2 "nonimmediate_operand" "")))]
2910169689Skan  "TARGET_SSE2"
2911169689Skan  "ix86_fixup_binary_operands_no_copy (UMIN, V16QImode, operands);")
2912169689Skan
2913169689Skan(define_insn "*uminv16qi3"
2914169689Skan  [(set (match_operand:V16QI 0 "register_operand" "=x")
2915169689Skan	(umin:V16QI (match_operand:V16QI 1 "nonimmediate_operand" "%0")
2916169689Skan		    (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
2917169689Skan  "TARGET_SSE2 && ix86_binary_operator_ok (UMIN, V16QImode, operands)"
2918169689Skan  "pminub\t{%2, %0|%0, %2}"
2919169689Skan  [(set_attr "type" "sseiadd")
2920169689Skan   (set_attr "mode" "TI")])
2921169689Skan
2922169689Skan(define_expand "sminv8hi3"
2923169689Skan  [(set (match_operand:V8HI 0 "register_operand" "")
2924169689Skan	(smin:V8HI (match_operand:V8HI 1 "nonimmediate_operand" "")
2925169689Skan		   (match_operand:V8HI 2 "nonimmediate_operand" "")))]
2926169689Skan  "TARGET_SSE2"
2927169689Skan  "ix86_fixup_binary_operands_no_copy (SMIN, V8HImode, operands);")
2928169689Skan
2929169689Skan(define_insn "*sminv8hi3"
2930169689Skan  [(set (match_operand:V8HI 0 "register_operand" "=x")
2931169689Skan	(smin:V8HI (match_operand:V8HI 1 "nonimmediate_operand" "%0")
2932169689Skan		   (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
2933169689Skan  "TARGET_SSE2 && ix86_binary_operator_ok (SMIN, V8HImode, operands)"
2934169689Skan  "pminsw\t{%2, %0|%0, %2}"
2935169689Skan  [(set_attr "type" "sseiadd")
2936169689Skan   (set_attr "mode" "TI")])
2937169689Skan
2938169689Skan(define_expand "smin<mode>3"
2939169689Skan  [(set (match_operand:SSEMODE14 0 "register_operand" "")
2940169689Skan	(smin:SSEMODE14 (match_operand:SSEMODE14 1 "register_operand" "")
2941169689Skan			(match_operand:SSEMODE14 2 "register_operand" "")))]
2942169689Skan  "TARGET_SSE2"
2943169689Skan{
2944169689Skan  rtx xops[6];
2945169689Skan  bool ok;
2946169689Skan
2947169689Skan  xops[0] = operands[0];
2948169689Skan  xops[1] = operands[2];
2949169689Skan  xops[2] = operands[1];
2950169689Skan  xops[3] = gen_rtx_GT (VOIDmode, operands[1], operands[2]);
2951169689Skan  xops[4] = operands[1];
2952169689Skan  xops[5] = operands[2];
2953169689Skan  ok = ix86_expand_int_vcond (xops);
2954169689Skan  gcc_assert (ok);
2955169689Skan  DONE;
2956169689Skan})
2957169689Skan
2958169689Skan(define_expand "umin<mode>3"
2959169689Skan  [(set (match_operand:SSEMODE24 0 "register_operand" "")
2960169689Skan	(umin:SSEMODE24 (match_operand:SSEMODE24 1 "register_operand" "")
2961169689Skan			(match_operand:SSEMODE24 2 "register_operand" "")))]
2962169689Skan  "TARGET_SSE2"
2963169689Skan{
2964169689Skan  rtx xops[6];
2965169689Skan  bool ok;
2966169689Skan
2967169689Skan  xops[0] = operands[0];
2968169689Skan  xops[1] = operands[2];
2969169689Skan  xops[2] = operands[1];
2970169689Skan  xops[3] = gen_rtx_GTU (VOIDmode, operands[1], operands[2]);
2971169689Skan  xops[4] = operands[1];
2972169689Skan  xops[5] = operands[2];
2973169689Skan  ok = ix86_expand_int_vcond (xops);
2974169689Skan  gcc_assert (ok);
2975169689Skan  DONE;
2976169689Skan})
2977169689Skan
2978169689Skan;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2979169689Skan;;
2980169689Skan;; Parallel integral comparisons
2981169689Skan;;
2982169689Skan;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2983169689Skan
2984169689Skan(define_insn "sse2_eq<mode>3"
2985169689Skan  [(set (match_operand:SSEMODE124 0 "register_operand" "=x")
2986169689Skan	(eq:SSEMODE124
2987169689Skan	  (match_operand:SSEMODE124 1 "nonimmediate_operand" "%0")
2988169689Skan	  (match_operand:SSEMODE124 2 "nonimmediate_operand" "xm")))]
2989169689Skan  "TARGET_SSE2 && ix86_binary_operator_ok (EQ, <MODE>mode, operands)"
2990169689Skan  "pcmpeq<ssevecsize>\t{%2, %0|%0, %2}"
2991169689Skan  [(set_attr "type" "ssecmp")
2992169689Skan   (set_attr "mode" "TI")])
2993169689Skan
2994169689Skan(define_insn "sse2_gt<mode>3"
2995169689Skan  [(set (match_operand:SSEMODE124 0 "register_operand" "=x")
2996169689Skan	(gt:SSEMODE124
2997169689Skan	  (match_operand:SSEMODE124 1 "register_operand" "0")
2998169689Skan	  (match_operand:SSEMODE124 2 "nonimmediate_operand" "xm")))]
2999169689Skan  "TARGET_SSE2"
3000169689Skan  "pcmpgt<ssevecsize>\t{%2, %0|%0, %2}"
3001169689Skan  [(set_attr "type" "ssecmp")
3002169689Skan   (set_attr "mode" "TI")])
3003169689Skan
3004169689Skan(define_expand "vcond<mode>"
3005169689Skan  [(set (match_operand:SSEMODE124 0 "register_operand" "")
3006169689Skan        (if_then_else:SSEMODE124
3007169689Skan          (match_operator 3 ""
3008169689Skan            [(match_operand:SSEMODE124 4 "nonimmediate_operand" "")
3009169689Skan             (match_operand:SSEMODE124 5 "nonimmediate_operand" "")])
3010169689Skan          (match_operand:SSEMODE124 1 "general_operand" "")
3011169689Skan          (match_operand:SSEMODE124 2 "general_operand" "")))]
3012169689Skan  "TARGET_SSE2"
3013169689Skan{
3014169689Skan  if (ix86_expand_int_vcond (operands))
3015169689Skan    DONE;
3016169689Skan  else
3017169689Skan    FAIL;
3018169689Skan})
3019169689Skan
3020169689Skan(define_expand "vcondu<mode>"
3021169689Skan  [(set (match_operand:SSEMODE124 0 "register_operand" "")
3022169689Skan        (if_then_else:SSEMODE124
3023169689Skan          (match_operator 3 ""
3024169689Skan            [(match_operand:SSEMODE124 4 "nonimmediate_operand" "")
3025169689Skan             (match_operand:SSEMODE124 5 "nonimmediate_operand" "")])
3026169689Skan          (match_operand:SSEMODE124 1 "general_operand" "")
3027169689Skan          (match_operand:SSEMODE124 2 "general_operand" "")))]
3028169689Skan  "TARGET_SSE2"
3029169689Skan{
3030169689Skan  if (ix86_expand_int_vcond (operands))
3031169689Skan    DONE;
3032169689Skan  else
3033169689Skan    FAIL;
3034169689Skan})
3035169689Skan
3036169689Skan;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3037169689Skan;;
3038169689Skan;; Parallel integral logical operations
3039169689Skan;;
3040169689Skan;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3041169689Skan
3042169689Skan(define_expand "one_cmpl<mode>2"
3043169689Skan  [(set (match_operand:SSEMODEI 0 "register_operand" "")
3044169689Skan	(xor:SSEMODEI (match_operand:SSEMODEI 1 "nonimmediate_operand" "")
3045169689Skan		      (match_dup 2)))]
3046169689Skan  "TARGET_SSE2"
3047169689Skan{
3048169689Skan  int i, n = GET_MODE_NUNITS (<MODE>mode);
3049169689Skan  rtvec v = rtvec_alloc (n);
3050169689Skan
3051169689Skan  for (i = 0; i < n; ++i)
3052169689Skan    RTVEC_ELT (v, i) = constm1_rtx;
3053169689Skan
3054169689Skan  operands[2] = force_reg (<MODE>mode, gen_rtx_CONST_VECTOR (<MODE>mode, v));
3055169689Skan})
3056169689Skan
3057169689Skan(define_expand "and<mode>3"
3058169689Skan  [(set (match_operand:SSEMODEI 0 "register_operand" "")
3059169689Skan	(and:SSEMODEI (match_operand:SSEMODEI 1 "nonimmediate_operand" "")
3060169689Skan		      (match_operand:SSEMODEI 2 "nonimmediate_operand" "")))]
3061169689Skan  "TARGET_SSE2"
3062169689Skan  "ix86_fixup_binary_operands_no_copy (AND, <MODE>mode, operands);")
3063169689Skan
3064169689Skan(define_insn "*and<mode>3"
3065169689Skan  [(set (match_operand:SSEMODEI 0 "register_operand" "=x")
3066169689Skan	(and:SSEMODEI
3067169689Skan	  (match_operand:SSEMODEI 1 "nonimmediate_operand" "%0")
3068169689Skan	  (match_operand:SSEMODEI 2 "nonimmediate_operand" "xm")))]
3069169689Skan  "TARGET_SSE2 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
3070169689Skan  "pand\t{%2, %0|%0, %2}"
3071169689Skan  [(set_attr "type" "sselog")
3072169689Skan   (set_attr "mode" "TI")])
3073169689Skan
3074169689Skan(define_insn "sse2_nand<mode>3"
3075169689Skan  [(set (match_operand:SSEMODEI 0 "register_operand" "=x")
3076169689Skan	(and:SSEMODEI
3077169689Skan	  (not:SSEMODEI (match_operand:SSEMODEI 1 "register_operand" "0"))
3078169689Skan	  (match_operand:SSEMODEI 2 "nonimmediate_operand" "xm")))]
3079169689Skan  "TARGET_SSE2"
3080169689Skan  "pandn\t{%2, %0|%0, %2}"
3081169689Skan  [(set_attr "type" "sselog")
3082169689Skan   (set_attr "mode" "TI")])
3083169689Skan
3084169689Skan(define_expand "ior<mode>3"
3085169689Skan  [(set (match_operand:SSEMODEI 0 "register_operand" "")
3086169689Skan	(ior:SSEMODEI (match_operand:SSEMODEI 1 "nonimmediate_operand" "")
3087169689Skan		      (match_operand:SSEMODEI 2 "nonimmediate_operand" "")))]
3088169689Skan  "TARGET_SSE2"
3089169689Skan  "ix86_fixup_binary_operands_no_copy (IOR, <MODE>mode, operands);")
3090169689Skan
3091169689Skan(define_insn "*ior<mode>3"
3092169689Skan  [(set (match_operand:SSEMODEI 0 "register_operand" "=x")
3093169689Skan	(ior:SSEMODEI
3094169689Skan	  (match_operand:SSEMODEI 1 "nonimmediate_operand" "%0")
3095169689Skan	  (match_operand:SSEMODEI 2 "nonimmediate_operand" "xm")))]
3096169689Skan  "TARGET_SSE2 && ix86_binary_operator_ok (IOR, <MODE>mode, operands)"
3097169689Skan  "por\t{%2, %0|%0, %2}"
3098169689Skan  [(set_attr "type" "sselog")
3099169689Skan   (set_attr "mode" "TI")])
3100169689Skan
3101169689Skan(define_expand "xor<mode>3"
3102169689Skan  [(set (match_operand:SSEMODEI 0 "register_operand" "")
3103169689Skan	(xor:SSEMODEI (match_operand:SSEMODEI 1 "nonimmediate_operand" "")
3104169689Skan		      (match_operand:SSEMODEI 2 "nonimmediate_operand" "")))]
3105169689Skan  "TARGET_SSE2"
3106169689Skan  "ix86_fixup_binary_operands_no_copy (XOR, <MODE>mode, operands);")
3107169689Skan
3108169689Skan(define_insn "*xor<mode>3"
3109169689Skan  [(set (match_operand:SSEMODEI 0 "register_operand" "=x")
3110169689Skan	(xor:SSEMODEI
3111169689Skan	  (match_operand:SSEMODEI 1 "nonimmediate_operand" "%0")
3112169689Skan	  (match_operand:SSEMODEI 2 "nonimmediate_operand" "xm")))]
3113169689Skan  "TARGET_SSE2 && ix86_binary_operator_ok (XOR, <MODE>mode, operands)"
3114169689Skan  "pxor\t{%2, %0|%0, %2}"
3115169689Skan  [(set_attr "type" "sselog")
3116169689Skan   (set_attr "mode" "TI")])
3117169689Skan
3118169689Skan;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3119169689Skan;;
3120169689Skan;; Parallel integral element swizzling
3121169689Skan;;
3122169689Skan;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3123169689Skan
3124169689Skan(define_insn "sse2_packsswb"
3125169689Skan  [(set (match_operand:V16QI 0 "register_operand" "=x")
3126169689Skan	(vec_concat:V16QI
3127169689Skan	  (ss_truncate:V8QI
3128169689Skan	    (match_operand:V8HI 1 "register_operand" "0"))
3129169689Skan	  (ss_truncate:V8QI
3130169689Skan	    (match_operand:V8HI 2 "nonimmediate_operand" "xm"))))]
3131169689Skan  "TARGET_SSE2"
3132169689Skan  "packsswb\t{%2, %0|%0, %2}"
3133169689Skan  [(set_attr "type" "sselog")
3134169689Skan   (set_attr "mode" "TI")])
3135169689Skan
3136169689Skan(define_insn "sse2_packssdw"
3137169689Skan  [(set (match_operand:V8HI 0 "register_operand" "=x")
3138169689Skan	(vec_concat:V8HI
3139169689Skan	  (ss_truncate:V4HI
3140169689Skan	    (match_operand:V4SI 1 "register_operand" "0"))
3141169689Skan	  (ss_truncate:V4HI
3142169689Skan	    (match_operand:V4SI 2 "nonimmediate_operand" "xm"))))]
3143169689Skan  "TARGET_SSE2"
3144169689Skan  "packssdw\t{%2, %0|%0, %2}"
3145169689Skan  [(set_attr "type" "sselog")
3146169689Skan   (set_attr "mode" "TI")])
3147169689Skan
3148169689Skan(define_insn "sse2_packuswb"
3149169689Skan  [(set (match_operand:V16QI 0 "register_operand" "=x")
3150169689Skan	(vec_concat:V16QI
3151169689Skan	  (us_truncate:V8QI
3152169689Skan	    (match_operand:V8HI 1 "register_operand" "0"))
3153169689Skan	  (us_truncate:V8QI
3154169689Skan	    (match_operand:V8HI 2 "nonimmediate_operand" "xm"))))]
3155169689Skan  "TARGET_SSE2"
3156169689Skan  "packuswb\t{%2, %0|%0, %2}"
3157169689Skan  [(set_attr "type" "sselog")
3158169689Skan   (set_attr "mode" "TI")])
3159169689Skan
3160169689Skan(define_insn "sse2_punpckhbw"
3161169689Skan  [(set (match_operand:V16QI 0 "register_operand" "=x")
3162169689Skan	(vec_select:V16QI
3163169689Skan	  (vec_concat:V32QI
3164169689Skan	    (match_operand:V16QI 1 "register_operand" "0")
3165169689Skan	    (match_operand:V16QI 2 "nonimmediate_operand" "xm"))
3166169689Skan	  (parallel [(const_int 8)  (const_int 24)
3167169689Skan		     (const_int 9)  (const_int 25)
3168169689Skan		     (const_int 10) (const_int 26)
3169169689Skan		     (const_int 11) (const_int 27)
3170169689Skan		     (const_int 12) (const_int 28) 
3171169689Skan		     (const_int 13) (const_int 29)
3172169689Skan		     (const_int 14) (const_int 30)
3173169689Skan		     (const_int 15) (const_int 31)])))]
3174169689Skan  "TARGET_SSE2"
3175169689Skan  "punpckhbw\t{%2, %0|%0, %2}"
3176169689Skan  [(set_attr "type" "sselog")
3177169689Skan   (set_attr "mode" "TI")])
3178169689Skan
3179169689Skan(define_insn "sse2_punpcklbw"
3180169689Skan  [(set (match_operand:V16QI 0 "register_operand" "=x")
3181169689Skan	(vec_select:V16QI
3182169689Skan	  (vec_concat:V32QI
3183169689Skan	    (match_operand:V16QI 1 "register_operand" "0")
3184169689Skan	    (match_operand:V16QI 2 "nonimmediate_operand" "xm"))
3185169689Skan	  (parallel [(const_int 0) (const_int 16)
3186169689Skan		     (const_int 1) (const_int 17)
3187169689Skan		     (const_int 2) (const_int 18)
3188169689Skan		     (const_int 3) (const_int 19)
3189169689Skan		     (const_int 4) (const_int 20)
3190169689Skan		     (const_int 5) (const_int 21)
3191169689Skan		     (const_int 6) (const_int 22)
3192169689Skan		     (const_int 7) (const_int 23)])))]
3193169689Skan  "TARGET_SSE2"
3194169689Skan  "punpcklbw\t{%2, %0|%0, %2}"
3195169689Skan  [(set_attr "type" "sselog")
3196169689Skan   (set_attr "mode" "TI")])
3197169689Skan
3198169689Skan(define_insn "sse2_punpckhwd"
3199169689Skan  [(set (match_operand:V8HI 0 "register_operand" "=x")
3200169689Skan	(vec_select:V8HI
3201169689Skan	  (vec_concat:V16HI
3202169689Skan	    (match_operand:V8HI 1 "register_operand" "0")
3203169689Skan	    (match_operand:V8HI 2 "nonimmediate_operand" "xm"))
3204169689Skan	  (parallel [(const_int 4) (const_int 12)
3205169689Skan		     (const_int 5) (const_int 13)
3206169689Skan		     (const_int 6) (const_int 14)
3207169689Skan		     (const_int 7) (const_int 15)])))]
3208169689Skan  "TARGET_SSE2"
3209169689Skan  "punpckhwd\t{%2, %0|%0, %2}"
3210169689Skan  [(set_attr "type" "sselog")
3211169689Skan   (set_attr "mode" "TI")])
3212169689Skan
3213169689Skan(define_insn "sse2_punpcklwd"
3214169689Skan  [(set (match_operand:V8HI 0 "register_operand" "=x")
3215169689Skan	(vec_select:V8HI
3216169689Skan	  (vec_concat:V16HI
3217169689Skan	    (match_operand:V8HI 1 "register_operand" "0")
3218169689Skan	    (match_operand:V8HI 2 "nonimmediate_operand" "xm"))
3219169689Skan	  (parallel [(const_int 0) (const_int 8)
3220169689Skan		     (const_int 1) (const_int 9)
3221169689Skan		     (const_int 2) (const_int 10)
3222169689Skan		     (const_int 3) (const_int 11)])))]
3223169689Skan  "TARGET_SSE2"
3224169689Skan  "punpcklwd\t{%2, %0|%0, %2}"
3225169689Skan  [(set_attr "type" "sselog")
3226169689Skan   (set_attr "mode" "TI")])
3227169689Skan
3228169689Skan(define_insn "sse2_punpckhdq"
3229169689Skan  [(set (match_operand:V4SI 0 "register_operand" "=x")
3230169689Skan	(vec_select:V4SI
3231169689Skan	  (vec_concat:V8SI
3232169689Skan	    (match_operand:V4SI 1 "register_operand" "0")
3233169689Skan	    (match_operand:V4SI 2 "nonimmediate_operand" "xm"))
3234169689Skan	  (parallel [(const_int 2) (const_int 6)
3235169689Skan		     (const_int 3) (const_int 7)])))]
3236169689Skan  "TARGET_SSE2"
3237169689Skan  "punpckhdq\t{%2, %0|%0, %2}"
3238169689Skan  [(set_attr "type" "sselog")
3239169689Skan   (set_attr "mode" "TI")])
3240169689Skan
3241169689Skan(define_insn "sse2_punpckldq"
3242169689Skan  [(set (match_operand:V4SI 0 "register_operand" "=x")
3243169689Skan	(vec_select:V4SI
3244169689Skan	  (vec_concat:V8SI
3245169689Skan	    (match_operand:V4SI 1 "register_operand" "0")
3246169689Skan	    (match_operand:V4SI 2 "nonimmediate_operand" "xm"))
3247169689Skan	  (parallel [(const_int 0) (const_int 4)
3248169689Skan		     (const_int 1) (const_int 5)])))]
3249169689Skan  "TARGET_SSE2"
3250169689Skan  "punpckldq\t{%2, %0|%0, %2}"
3251169689Skan  [(set_attr "type" "sselog")
3252169689Skan   (set_attr "mode" "TI")])
3253169689Skan
3254169689Skan(define_insn "sse2_punpckhqdq"
3255169689Skan  [(set (match_operand:V2DI 0 "register_operand" "=x")
3256169689Skan	(vec_select:V2DI
3257169689Skan	  (vec_concat:V4DI
3258169689Skan	    (match_operand:V2DI 1 "register_operand" "0")
3259169689Skan	    (match_operand:V2DI 2 "nonimmediate_operand" "xm"))
3260169689Skan	  (parallel [(const_int 1)
3261169689Skan		     (const_int 3)])))]
3262169689Skan  "TARGET_SSE2"
3263169689Skan  "punpckhqdq\t{%2, %0|%0, %2}"
3264169689Skan  [(set_attr "type" "sselog")
3265169689Skan   (set_attr "mode" "TI")])
3266169689Skan
3267169689Skan(define_insn "sse2_punpcklqdq"
3268169689Skan  [(set (match_operand:V2DI 0 "register_operand" "=x")
3269169689Skan	(vec_select:V2DI
3270169689Skan	  (vec_concat:V4DI
3271169689Skan	    (match_operand:V2DI 1 "register_operand" "0")
3272169689Skan	    (match_operand:V2DI 2 "nonimmediate_operand" "xm"))
3273169689Skan	  (parallel [(const_int 0)
3274169689Skan		     (const_int 2)])))]
3275169689Skan  "TARGET_SSE2"
3276169689Skan  "punpcklqdq\t{%2, %0|%0, %2}"
3277169689Skan  [(set_attr "type" "sselog")
3278169689Skan   (set_attr "mode" "TI")])
3279169689Skan
3280169689Skan(define_expand "sse2_pinsrw"
3281169689Skan  [(set (match_operand:V8HI 0 "register_operand" "")
3282169689Skan	(vec_merge:V8HI
3283169689Skan	  (vec_duplicate:V8HI
3284169689Skan	    (match_operand:SI 2 "nonimmediate_operand" ""))
3285169689Skan	  (match_operand:V8HI 1 "register_operand" "")
3286169689Skan	  (match_operand:SI 3 "const_0_to_7_operand" "")))]
3287169689Skan  "TARGET_SSE2"
3288169689Skan{
3289169689Skan  operands[2] = gen_lowpart (HImode, operands[2]);
3290169689Skan  operands[3] = GEN_INT ((1 << INTVAL (operands[3])));
3291169689Skan})
3292169689Skan
3293169689Skan(define_insn "*sse2_pinsrw"
3294169689Skan  [(set (match_operand:V8HI 0 "register_operand" "=x")
3295169689Skan	(vec_merge:V8HI
3296169689Skan	  (vec_duplicate:V8HI
3297169689Skan	    (match_operand:HI 2 "nonimmediate_operand" "rm"))
3298169689Skan	  (match_operand:V8HI 1 "register_operand" "0")
3299169689Skan	  (match_operand:SI 3 "const_pow2_1_to_128_operand" "n")))]
3300169689Skan  "TARGET_SSE2"
3301169689Skan{
3302169689Skan  operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])));
3303169689Skan  return "pinsrw\t{%3, %k2, %0|%0, %k2, %3}";
3304169689Skan}
3305169689Skan  [(set_attr "type" "sselog")
3306169689Skan   (set_attr "mode" "TI")])
3307169689Skan
3308169689Skan(define_insn "sse2_pextrw"
3309169689Skan  [(set (match_operand:SI 0 "register_operand" "=r")
3310169689Skan	(zero_extend:SI
3311169689Skan	  (vec_select:HI
3312169689Skan	    (match_operand:V8HI 1 "register_operand" "x")
3313169689Skan	    (parallel [(match_operand:SI 2 "const_0_to_7_operand" "n")]))))]
3314169689Skan  "TARGET_SSE2"
3315169689Skan  "pextrw\t{%2, %1, %0|%0, %1, %2}"
3316169689Skan  [(set_attr "type" "sselog")
3317169689Skan   (set_attr "mode" "TI")])
3318169689Skan
3319169689Skan(define_expand "sse2_pshufd"
3320169689Skan  [(match_operand:V4SI 0 "register_operand" "")
3321169689Skan   (match_operand:V4SI 1 "nonimmediate_operand" "")
3322169689Skan   (match_operand:SI 2 "const_int_operand" "")]
3323169689Skan  "TARGET_SSE2"
3324169689Skan{
3325169689Skan  int mask = INTVAL (operands[2]);
3326169689Skan  emit_insn (gen_sse2_pshufd_1 (operands[0], operands[1],
3327169689Skan				GEN_INT ((mask >> 0) & 3),
3328169689Skan				GEN_INT ((mask >> 2) & 3),
3329169689Skan				GEN_INT ((mask >> 4) & 3),
3330169689Skan				GEN_INT ((mask >> 6) & 3)));
3331169689Skan  DONE;
3332169689Skan})
3333169689Skan
3334169689Skan(define_insn "sse2_pshufd_1"
3335169689Skan  [(set (match_operand:V4SI 0 "register_operand" "=x")
3336169689Skan	(vec_select:V4SI
3337169689Skan	  (match_operand:V4SI 1 "nonimmediate_operand" "xm")
3338169689Skan	  (parallel [(match_operand 2 "const_0_to_3_operand" "")
3339169689Skan		     (match_operand 3 "const_0_to_3_operand" "")
3340169689Skan		     (match_operand 4 "const_0_to_3_operand" "")
3341169689Skan		     (match_operand 5 "const_0_to_3_operand" "")])))]
3342169689Skan  "TARGET_SSE2"
3343169689Skan{
3344169689Skan  int mask = 0;
3345169689Skan  mask |= INTVAL (operands[2]) << 0;
3346169689Skan  mask |= INTVAL (operands[3]) << 2;
3347169689Skan  mask |= INTVAL (operands[4]) << 4;
3348169689Skan  mask |= INTVAL (operands[5]) << 6;
3349169689Skan  operands[2] = GEN_INT (mask);
3350169689Skan
3351169689Skan  return "pshufd\t{%2, %1, %0|%0, %1, %2}";
3352169689Skan}
3353169689Skan  [(set_attr "type" "sselog1")
3354169689Skan   (set_attr "mode" "TI")])
3355169689Skan
3356169689Skan(define_expand "sse2_pshuflw"
3357169689Skan  [(match_operand:V8HI 0 "register_operand" "")
3358169689Skan   (match_operand:V8HI 1 "nonimmediate_operand" "")
3359169689Skan   (match_operand:SI 2 "const_int_operand" "")]
3360169689Skan  "TARGET_SSE2"
3361169689Skan{
3362169689Skan  int mask = INTVAL (operands[2]);
3363169689Skan  emit_insn (gen_sse2_pshuflw_1 (operands[0], operands[1],
3364169689Skan				 GEN_INT ((mask >> 0) & 3),
3365169689Skan				 GEN_INT ((mask >> 2) & 3),
3366169689Skan				 GEN_INT ((mask >> 4) & 3),
3367169689Skan				 GEN_INT ((mask >> 6) & 3)));
3368169689Skan  DONE;
3369169689Skan})
3370169689Skan
3371169689Skan(define_insn "sse2_pshuflw_1"
3372169689Skan  [(set (match_operand:V8HI 0 "register_operand" "=x")
3373169689Skan	(vec_select:V8HI
3374169689Skan	  (match_operand:V8HI 1 "nonimmediate_operand" "xm")
3375169689Skan	  (parallel [(match_operand 2 "const_0_to_3_operand" "")
3376169689Skan		     (match_operand 3 "const_0_to_3_operand" "")
3377169689Skan		     (match_operand 4 "const_0_to_3_operand" "")
3378169689Skan		     (match_operand 5 "const_0_to_3_operand" "")
3379169689Skan		     (const_int 4)
3380169689Skan		     (const_int 5)
3381169689Skan		     (const_int 6)
3382169689Skan		     (const_int 7)])))]
3383169689Skan  "TARGET_SSE2"
3384169689Skan{
3385169689Skan  int mask = 0;
3386169689Skan  mask |= INTVAL (operands[2]) << 0;
3387169689Skan  mask |= INTVAL (operands[3]) << 2;
3388169689Skan  mask |= INTVAL (operands[4]) << 4;
3389169689Skan  mask |= INTVAL (operands[5]) << 6;
3390169689Skan  operands[2] = GEN_INT (mask);
3391169689Skan
3392169689Skan  return "pshuflw\t{%2, %1, %0|%0, %1, %2}";
3393169689Skan}
3394169689Skan  [(set_attr "type" "sselog")
3395169689Skan   (set_attr "mode" "TI")])
3396169689Skan
3397169689Skan(define_expand "sse2_pshufhw"
3398169689Skan  [(match_operand:V8HI 0 "register_operand" "")
3399169689Skan   (match_operand:V8HI 1 "nonimmediate_operand" "")
3400169689Skan   (match_operand:SI 2 "const_int_operand" "")]
3401169689Skan  "TARGET_SSE2"
3402169689Skan{
3403169689Skan  int mask = INTVAL (operands[2]);
3404169689Skan  emit_insn (gen_sse2_pshufhw_1 (operands[0], operands[1],
3405169689Skan				 GEN_INT (((mask >> 0) & 3) + 4),
3406169689Skan				 GEN_INT (((mask >> 2) & 3) + 4),
3407169689Skan				 GEN_INT (((mask >> 4) & 3) + 4),
3408169689Skan				 GEN_INT (((mask >> 6) & 3) + 4)));
3409169689Skan  DONE;
3410169689Skan})
3411169689Skan
3412169689Skan(define_insn "sse2_pshufhw_1"
3413169689Skan  [(set (match_operand:V8HI 0 "register_operand" "=x")
3414169689Skan	(vec_select:V8HI
3415169689Skan	  (match_operand:V8HI 1 "nonimmediate_operand" "xm")
3416169689Skan	  (parallel [(const_int 0)
3417169689Skan		     (const_int 1)
3418169689Skan		     (const_int 2)
3419169689Skan		     (const_int 3)
3420169689Skan		     (match_operand 2 "const_4_to_7_operand" "")
3421169689Skan		     (match_operand 3 "const_4_to_7_operand" "")
3422169689Skan		     (match_operand 4 "const_4_to_7_operand" "")
3423169689Skan		     (match_operand 5 "const_4_to_7_operand" "")])))]
3424169689Skan  "TARGET_SSE2"
3425169689Skan{
3426169689Skan  int mask = 0;
3427169689Skan  mask |= (INTVAL (operands[2]) - 4) << 0;
3428169689Skan  mask |= (INTVAL (operands[3]) - 4) << 2;
3429169689Skan  mask |= (INTVAL (operands[4]) - 4) << 4;
3430169689Skan  mask |= (INTVAL (operands[5]) - 4) << 6;
3431169689Skan  operands[2] = GEN_INT (mask);
3432169689Skan
3433169689Skan  return "pshufhw\t{%2, %1, %0|%0, %1, %2}";
3434169689Skan}
3435169689Skan  [(set_attr "type" "sselog")
3436169689Skan   (set_attr "mode" "TI")])
3437169689Skan
3438169689Skan(define_expand "sse2_loadd"
3439169689Skan  [(set (match_operand:V4SI 0 "register_operand" "")
3440169689Skan	(vec_merge:V4SI
3441169689Skan	  (vec_duplicate:V4SI
3442169689Skan	    (match_operand:SI 1 "nonimmediate_operand" ""))
3443169689Skan	  (match_dup 2)
3444169689Skan	  (const_int 1)))]
3445169689Skan  "TARGET_SSE"
3446169689Skan  "operands[2] = CONST0_RTX (V4SImode);")
3447169689Skan
3448169689Skan(define_insn "sse2_loadld"
3449169689Skan  [(set (match_operand:V4SI 0 "register_operand"       "=Y,x,x")
3450169689Skan	(vec_merge:V4SI
3451169689Skan	  (vec_duplicate:V4SI
3452169689Skan	    (match_operand:SI 2 "nonimmediate_operand" "mr,m,x"))
3453169689Skan	  (match_operand:V4SI 1 "reg_or_0_operand"     " C,C,0")
3454169689Skan	  (const_int 1)))]
3455169689Skan  "TARGET_SSE"
3456169689Skan  "@
3457169689Skan   movd\t{%2, %0|%0, %2}
3458169689Skan   movss\t{%2, %0|%0, %2}
3459169689Skan   movss\t{%2, %0|%0, %2}"
3460169689Skan  [(set_attr "type" "ssemov")
3461169689Skan   (set_attr "mode" "TI,V4SF,SF")])
3462169689Skan
3463169689Skan;; ??? The hardware supports more, but TARGET_INTER_UNIT_MOVES must
3464169689Skan;; be taken into account, and movdi isn't fully populated even without.
3465169689Skan(define_insn_and_split "sse2_stored"
3466169689Skan  [(set (match_operand:SI 0 "nonimmediate_operand" "=mx")
3467169689Skan	(vec_select:SI
3468169689Skan	  (match_operand:V4SI 1 "register_operand" "x")
3469169689Skan	  (parallel [(const_int 0)])))]
3470169689Skan  "TARGET_SSE"
3471169689Skan  "#"
3472169689Skan  "&& reload_completed"
3473169689Skan  [(set (match_dup 0) (match_dup 1))]
3474169689Skan{
3475169689Skan  operands[1] = gen_rtx_REG (SImode, REGNO (operands[1]));
3476169689Skan})
3477169689Skan
3478169689Skan(define_expand "sse_storeq"
3479169689Skan  [(set (match_operand:DI 0 "nonimmediate_operand" "")
3480169689Skan	(vec_select:DI
3481169689Skan	  (match_operand:V2DI 1 "register_operand" "")
3482169689Skan	  (parallel [(const_int 0)])))]
3483169689Skan  "TARGET_SSE"
3484169689Skan  "")
3485169689Skan
3486169689Skan;; ??? The hardware supports more, but TARGET_INTER_UNIT_MOVES must
3487169689Skan;; be taken into account, and movdi isn't fully populated even without.
3488169689Skan(define_insn "*sse2_storeq"
3489169689Skan  [(set (match_operand:DI 0 "nonimmediate_operand" "=mx")
3490169689Skan	(vec_select:DI
3491169689Skan	  (match_operand:V2DI 1 "register_operand" "x")
3492169689Skan	  (parallel [(const_int 0)])))]
3493169689Skan  "TARGET_SSE"
3494169689Skan  "#")
3495169689Skan
3496169689Skan(define_split
3497169689Skan  [(set (match_operand:DI 0 "nonimmediate_operand" "")
3498169689Skan	(vec_select:DI
3499169689Skan	  (match_operand:V2DI 1 "register_operand" "")
3500169689Skan	  (parallel [(const_int 0)])))]
3501169689Skan  "TARGET_SSE && reload_completed"
3502169689Skan  [(set (match_dup 0) (match_dup 1))]
3503169689Skan{
3504169689Skan  operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));
3505169689Skan})
3506169689Skan
3507169689Skan(define_insn "*vec_extractv2di_1_sse2"
3508169689Skan  [(set (match_operand:DI 0 "nonimmediate_operand" "=m,x,x")
3509169689Skan	(vec_select:DI
3510169689Skan	  (match_operand:V2DI 1 "nonimmediate_operand" "x,0,o")
3511169689Skan	  (parallel [(const_int 1)])))]
3512169689Skan  "TARGET_SSE2 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3513169689Skan  "@
3514169689Skan   movhps\t{%1, %0|%0, %1}
3515171825Skan   psrldq\t{$8, %0|%0, 8}
3516169689Skan   movq\t{%H1, %0|%0, %H1}"
3517169689Skan  [(set_attr "type" "ssemov,sseishft,ssemov")
3518171825Skan   (set_attr "memory" "*,none,*")
3519169689Skan   (set_attr "mode" "V2SF,TI,TI")])
3520169689Skan
3521169689Skan;; Not sure this is ever used, but it doesn't hurt to have it. -aoliva
3522169689Skan(define_insn "*vec_extractv2di_1_sse"
3523169689Skan  [(set (match_operand:DI 0 "nonimmediate_operand" "=m,x,x")
3524169689Skan	(vec_select:DI
3525169689Skan	  (match_operand:V2DI 1 "nonimmediate_operand" "x,x,o")
3526169689Skan	  (parallel [(const_int 1)])))]
3527169689Skan  "!TARGET_SSE2 && TARGET_SSE
3528169689Skan   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3529169689Skan  "@
3530169689Skan   movhps\t{%1, %0|%0, %1}
3531169689Skan   movhlps\t{%1, %0|%0, %1}
3532169689Skan   movlps\t{%H1, %0|%0, %H1}"
3533169689Skan  [(set_attr "type" "ssemov")
3534169689Skan   (set_attr "mode" "V2SF,V4SF,V2SF")])
3535169689Skan
3536169689Skan(define_insn "*vec_dupv4si"
3537169689Skan  [(set (match_operand:V4SI 0 "register_operand" "=Y,x")
3538169689Skan	(vec_duplicate:V4SI
3539169689Skan	  (match_operand:SI 1 "register_operand" " Y,0")))]
3540169689Skan  "TARGET_SSE"
3541169689Skan  "@
3542169689Skan   pshufd\t{$0, %1, %0|%0, %1, 0}
3543169689Skan   shufps\t{$0, %0, %0|%0, %0, 0}"
3544169689Skan  [(set_attr "type" "sselog1")
3545169689Skan   (set_attr "mode" "TI,V4SF")])
3546169689Skan
3547169689Skan(define_insn "*vec_dupv2di"
3548169689Skan  [(set (match_operand:V2DI 0 "register_operand" "=Y,x")
3549169689Skan	(vec_duplicate:V2DI
3550169689Skan	  (match_operand:DI 1 "register_operand" " 0,0")))]
3551169689Skan  "TARGET_SSE"
3552169689Skan  "@
3553169689Skan   punpcklqdq\t%0, %0
3554169689Skan   movlhps\t%0, %0"
3555169689Skan  [(set_attr "type" "sselog1,ssemov")
3556169689Skan   (set_attr "mode" "TI,V4SF")])
3557169689Skan
3558169689Skan;; ??? In theory we can match memory for the MMX alternative, but allowing
3559169689Skan;; nonimmediate_operand for operand 2 and *not* allowing memory for the SSE
3560169689Skan;; alternatives pretty much forces the MMX alternative to be chosen.
3561169689Skan(define_insn "*sse2_concatv2si"
3562169689Skan  [(set (match_operand:V2SI 0 "register_operand"     "=Y, Y,*y,*y")
3563169689Skan	(vec_concat:V2SI
3564169689Skan	  (match_operand:SI 1 "nonimmediate_operand" " 0,rm, 0,rm")
3565169689Skan	  (match_operand:SI 2 "reg_or_0_operand"     " Y, C,*y, C")))]
3566169689Skan  "TARGET_SSE2"
3567169689Skan  "@
3568169689Skan   punpckldq\t{%2, %0|%0, %2}
3569169689Skan   movd\t{%1, %0|%0, %1}
3570169689Skan   punpckldq\t{%2, %0|%0, %2}
3571169689Skan   movd\t{%1, %0|%0, %1}"
3572169689Skan  [(set_attr "type" "sselog,ssemov,mmxcvt,mmxmov")
3573169689Skan   (set_attr "mode" "TI,TI,DI,DI")])
3574169689Skan
3575169689Skan(define_insn "*sse1_concatv2si"
3576169689Skan  [(set (match_operand:V2SI 0 "register_operand"     "=x,x,*y,*y")
3577169689Skan	(vec_concat:V2SI
3578169689Skan	  (match_operand:SI 1 "nonimmediate_operand" " 0,m, 0,*rm")
3579169689Skan	  (match_operand:SI 2 "reg_or_0_operand"     " x,C,*y,C")))]
3580169689Skan  "TARGET_SSE"
3581169689Skan  "@
3582169689Skan   unpcklps\t{%2, %0|%0, %2}
3583169689Skan   movss\t{%1, %0|%0, %1}
3584169689Skan   punpckldq\t{%2, %0|%0, %2}
3585169689Skan   movd\t{%1, %0|%0, %1}"
3586169689Skan  [(set_attr "type" "sselog,ssemov,mmxcvt,mmxmov")
3587169689Skan   (set_attr "mode" "V4SF,V4SF,DI,DI")])
3588169689Skan
3589169689Skan(define_insn "*vec_concatv4si_1"
3590169689Skan  [(set (match_operand:V4SI 0 "register_operand"       "=Y,x,x")
3591169689Skan	(vec_concat:V4SI
3592169689Skan	  (match_operand:V2SI 1 "register_operand"     " 0,0,0")
3593169689Skan	  (match_operand:V2SI 2 "nonimmediate_operand" " Y,x,m")))]
3594169689Skan  "TARGET_SSE"
3595169689Skan  "@
3596169689Skan   punpcklqdq\t{%2, %0|%0, %2}
3597169689Skan   movlhps\t{%2, %0|%0, %2}
3598169689Skan   movhps\t{%2, %0|%0, %2}"
3599169689Skan  [(set_attr "type" "sselog,ssemov,ssemov")
3600169689Skan   (set_attr "mode" "TI,V4SF,V2SF")])
3601169689Skan
3602169689Skan(define_insn "*vec_concatv2di"
3603169689Skan  [(set (match_operand:V2DI 0 "register_operand"     "=Y,?Y,Y,x,x,x")
3604169689Skan	(vec_concat:V2DI
3605169689Skan	  (match_operand:DI 1 "nonimmediate_operand" " m,*y,0,0,0,m")
3606169689Skan	  (match_operand:DI 2 "vector_move_operand"  " C, C,Y,x,m,0")))]
3607169689Skan  "TARGET_SSE"
3608169689Skan  "@
3609169689Skan   movq\t{%1, %0|%0, %1}
3610169689Skan   movq2dq\t{%1, %0|%0, %1}
3611169689Skan   punpcklqdq\t{%2, %0|%0, %2}
3612169689Skan   movlhps\t{%2, %0|%0, %2}
3613169689Skan   movhps\t{%2, %0|%0, %2}
3614169689Skan   movlps\t{%1, %0|%0, %1}"
3615169689Skan  [(set_attr "type" "ssemov,ssemov,sselog,ssemov,ssemov,ssemov")
3616169689Skan   (set_attr "mode" "TI,TI,TI,V4SF,V2SF,V2SF")])
3617169689Skan
3618169689Skan(define_expand "vec_setv2di"
3619169689Skan  [(match_operand:V2DI 0 "register_operand" "")
3620169689Skan   (match_operand:DI 1 "register_operand" "")
3621169689Skan   (match_operand 2 "const_int_operand" "")]
3622169689Skan  "TARGET_SSE"
3623169689Skan{
3624169689Skan  ix86_expand_vector_set (false, operands[0], operands[1],
3625169689Skan			  INTVAL (operands[2]));
3626169689Skan  DONE;
3627169689Skan})
3628169689Skan
3629169689Skan(define_expand "vec_extractv2di"
3630169689Skan  [(match_operand:DI 0 "register_operand" "")
3631169689Skan   (match_operand:V2DI 1 "register_operand" "")
3632169689Skan   (match_operand 2 "const_int_operand" "")]
3633169689Skan  "TARGET_SSE"
3634169689Skan{
3635169689Skan  ix86_expand_vector_extract (false, operands[0], operands[1],
3636169689Skan			      INTVAL (operands[2]));
3637169689Skan  DONE;
3638169689Skan})
3639169689Skan
3640169689Skan(define_expand "vec_initv2di"
3641169689Skan  [(match_operand:V2DI 0 "register_operand" "")
3642169689Skan   (match_operand 1 "" "")]
3643169689Skan  "TARGET_SSE"
3644169689Skan{
3645169689Skan  ix86_expand_vector_init (false, operands[0], operands[1]);
3646169689Skan  DONE;
3647169689Skan})
3648169689Skan
3649169689Skan(define_expand "vec_setv4si"
3650169689Skan  [(match_operand:V4SI 0 "register_operand" "")
3651169689Skan   (match_operand:SI 1 "register_operand" "")
3652169689Skan   (match_operand 2 "const_int_operand" "")]
3653169689Skan  "TARGET_SSE"
3654169689Skan{
3655169689Skan  ix86_expand_vector_set (false, operands[0], operands[1],
3656169689Skan			  INTVAL (operands[2]));
3657169689Skan  DONE;
3658169689Skan})
3659169689Skan
3660169689Skan(define_expand "vec_extractv4si"
3661169689Skan  [(match_operand:SI 0 "register_operand" "")
3662169689Skan   (match_operand:V4SI 1 "register_operand" "")
3663169689Skan   (match_operand 2 "const_int_operand" "")]
3664169689Skan  "TARGET_SSE"
3665169689Skan{
3666169689Skan  ix86_expand_vector_extract (false, operands[0], operands[1],
3667169689Skan			      INTVAL (operands[2]));
3668169689Skan  DONE;
3669169689Skan})
3670169689Skan
3671169689Skan(define_expand "vec_initv4si"
3672169689Skan  [(match_operand:V4SI 0 "register_operand" "")
3673169689Skan   (match_operand 1 "" "")]
3674169689Skan  "TARGET_SSE"
3675169689Skan{
3676169689Skan  ix86_expand_vector_init (false, operands[0], operands[1]);
3677169689Skan  DONE;
3678169689Skan})
3679169689Skan
3680169689Skan(define_expand "vec_setv8hi"
3681169689Skan  [(match_operand:V8HI 0 "register_operand" "")
3682169689Skan   (match_operand:HI 1 "register_operand" "")
3683169689Skan   (match_operand 2 "const_int_operand" "")]
3684169689Skan  "TARGET_SSE"
3685169689Skan{
3686169689Skan  ix86_expand_vector_set (false, operands[0], operands[1],
3687169689Skan			  INTVAL (operands[2]));
3688169689Skan  DONE;
3689169689Skan})
3690169689Skan
3691169689Skan(define_expand "vec_extractv8hi"
3692169689Skan  [(match_operand:HI 0 "register_operand" "")
3693169689Skan   (match_operand:V8HI 1 "register_operand" "")
3694169689Skan   (match_operand 2 "const_int_operand" "")]
3695169689Skan  "TARGET_SSE"
3696169689Skan{
3697169689Skan  ix86_expand_vector_extract (false, operands[0], operands[1],
3698169689Skan			      INTVAL (operands[2]));
3699169689Skan  DONE;
3700169689Skan})
3701169689Skan
3702169689Skan(define_expand "vec_initv8hi"
3703169689Skan  [(match_operand:V8HI 0 "register_operand" "")
3704169689Skan   (match_operand 1 "" "")]
3705169689Skan  "TARGET_SSE"
3706169689Skan{
3707169689Skan  ix86_expand_vector_init (false, operands[0], operands[1]);
3708169689Skan  DONE;
3709169689Skan})
3710169689Skan
3711169689Skan(define_expand "vec_setv16qi"
3712169689Skan  [(match_operand:V16QI 0 "register_operand" "")
3713169689Skan   (match_operand:QI 1 "register_operand" "")
3714169689Skan   (match_operand 2 "const_int_operand" "")]
3715169689Skan  "TARGET_SSE"
3716169689Skan{
3717169689Skan  ix86_expand_vector_set (false, operands[0], operands[1],
3718169689Skan			  INTVAL (operands[2]));
3719169689Skan  DONE;
3720169689Skan})
3721169689Skan
3722169689Skan(define_expand "vec_extractv16qi"
3723169689Skan  [(match_operand:QI 0 "register_operand" "")
3724169689Skan   (match_operand:V16QI 1 "register_operand" "")
3725169689Skan   (match_operand 2 "const_int_operand" "")]
3726169689Skan  "TARGET_SSE"
3727169689Skan{
3728169689Skan  ix86_expand_vector_extract (false, operands[0], operands[1],
3729169689Skan			      INTVAL (operands[2]));
3730169689Skan  DONE;
3731169689Skan})
3732169689Skan
3733169689Skan(define_expand "vec_initv16qi"
3734169689Skan  [(match_operand:V16QI 0 "register_operand" "")
3735169689Skan   (match_operand 1 "" "")]
3736169689Skan  "TARGET_SSE"
3737169689Skan{
3738169689Skan  ix86_expand_vector_init (false, operands[0], operands[1]);
3739169689Skan  DONE;
3740169689Skan})
3741169689Skan
3742169689Skan;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3743169689Skan;;
3744169689Skan;; Miscellaneous
3745169689Skan;;
3746169689Skan;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3747169689Skan
3748169689Skan(define_insn "sse2_uavgv16qi3"
3749169689Skan  [(set (match_operand:V16QI 0 "register_operand" "=x")
3750169689Skan	(truncate:V16QI
3751169689Skan	  (lshiftrt:V16HI
3752169689Skan	    (plus:V16HI
3753169689Skan	      (plus:V16HI
3754169689Skan		(zero_extend:V16HI
3755169689Skan		  (match_operand:V16QI 1 "nonimmediate_operand" "%0"))
3756169689Skan		(zero_extend:V16HI
3757169689Skan		  (match_operand:V16QI 2 "nonimmediate_operand" "xm")))
3758169689Skan	      (const_vector:V16QI [(const_int 1) (const_int 1)
3759169689Skan				   (const_int 1) (const_int 1)
3760169689Skan				   (const_int 1) (const_int 1)
3761169689Skan				   (const_int 1) (const_int 1)
3762169689Skan				   (const_int 1) (const_int 1)
3763169689Skan				   (const_int 1) (const_int 1)
3764169689Skan				   (const_int 1) (const_int 1)
3765169689Skan				   (const_int 1) (const_int 1)]))
3766169689Skan	    (const_int 1))))]
3767169689Skan  "TARGET_SSE2 && ix86_binary_operator_ok (PLUS, V16QImode, operands)"
3768169689Skan  "pavgb\t{%2, %0|%0, %2}"
3769169689Skan  [(set_attr "type" "sseiadd")
3770169689Skan   (set_attr "mode" "TI")])
3771169689Skan
3772169689Skan(define_insn "sse2_uavgv8hi3"
3773169689Skan  [(set (match_operand:V8HI 0 "register_operand" "=x")
3774169689Skan	(truncate:V8HI
3775169689Skan	  (lshiftrt:V8SI
3776169689Skan	    (plus:V8SI
3777169689Skan	      (plus:V8SI
3778169689Skan		(zero_extend:V8SI
3779169689Skan		  (match_operand:V8HI 1 "nonimmediate_operand" "%0"))
3780169689Skan		(zero_extend:V8SI
3781169689Skan		  (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
3782169689Skan	      (const_vector:V8HI [(const_int 1) (const_int 1)
3783169689Skan				  (const_int 1) (const_int 1)
3784169689Skan				  (const_int 1) (const_int 1)
3785169689Skan				  (const_int 1) (const_int 1)]))
3786169689Skan	    (const_int 1))))]
3787169689Skan  "TARGET_SSE2 && ix86_binary_operator_ok (PLUS, V8HImode, operands)"
3788169689Skan  "pavgw\t{%2, %0|%0, %2}"
3789169689Skan  [(set_attr "type" "sseiadd")
3790169689Skan   (set_attr "mode" "TI")])
3791169689Skan
3792169689Skan;; The correct representation for this is absolutely enormous, and 
3793169689Skan;; surely not generally useful.
3794169689Skan(define_insn "sse2_psadbw"
3795169689Skan  [(set (match_operand:V2DI 0 "register_operand" "=x")
3796169689Skan	(unspec:V2DI [(match_operand:V16QI 1 "register_operand" "0")
3797169689Skan		      (match_operand:V16QI 2 "nonimmediate_operand" "xm")]
3798169689Skan		     UNSPEC_PSADBW))]
3799169689Skan  "TARGET_SSE2"
3800169689Skan  "psadbw\t{%2, %0|%0, %2}"
3801169689Skan  [(set_attr "type" "sseiadd")
3802169689Skan   (set_attr "mode" "TI")])
3803169689Skan
3804169689Skan(define_insn "sse_movmskps"
3805169689Skan  [(set (match_operand:SI 0 "register_operand" "=r")
3806169689Skan	(unspec:SI [(match_operand:V4SF 1 "register_operand" "x")]
3807169689Skan		   UNSPEC_MOVMSK))]
3808169689Skan  "TARGET_SSE"
3809169689Skan  "movmskps\t{%1, %0|%0, %1}"
3810169689Skan  [(set_attr "type" "ssecvt")
3811169689Skan   (set_attr "mode" "V4SF")])
3812169689Skan
3813169689Skan(define_insn "sse2_movmskpd"
3814169689Skan  [(set (match_operand:SI 0 "register_operand" "=r")
3815169689Skan	(unspec:SI [(match_operand:V2DF 1 "register_operand" "x")]
3816169689Skan		   UNSPEC_MOVMSK))]
3817169689Skan  "TARGET_SSE2"
3818169689Skan  "movmskpd\t{%1, %0|%0, %1}"
3819169689Skan  [(set_attr "type" "ssecvt")
3820169689Skan   (set_attr "mode" "V2DF")])
3821169689Skan
3822169689Skan(define_insn "sse2_pmovmskb"
3823169689Skan  [(set (match_operand:SI 0 "register_operand" "=r")
3824169689Skan	(unspec:SI [(match_operand:V16QI 1 "register_operand" "x")]
3825169689Skan		   UNSPEC_MOVMSK))]
3826169689Skan  "TARGET_SSE2"
3827169689Skan  "pmovmskb\t{%1, %0|%0, %1}"
3828169689Skan  [(set_attr "type" "ssecvt")
3829169689Skan   (set_attr "mode" "V2DF")])
3830169689Skan
3831169689Skan(define_expand "sse2_maskmovdqu"
3832169689Skan  [(set (match_operand:V16QI 0 "memory_operand" "")
3833169689Skan	(unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
3834169689Skan		       (match_operand:V16QI 2 "register_operand" "x")
3835169689Skan		       (match_dup 0)]
3836169689Skan		      UNSPEC_MASKMOV))]
3837169689Skan  "TARGET_SSE2"
3838169689Skan  "")
3839169689Skan
3840169689Skan(define_insn "*sse2_maskmovdqu"
3841169689Skan  [(set (mem:V16QI (match_operand:SI 0 "register_operand" "D"))
3842169689Skan	(unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
3843169689Skan		       (match_operand:V16QI 2 "register_operand" "x")
3844169689Skan		       (mem:V16QI (match_dup 0))]
3845169689Skan		      UNSPEC_MASKMOV))]
3846169689Skan  "TARGET_SSE2 && !TARGET_64BIT"
3847169689Skan  ;; @@@ check ordering of operands in intel/nonintel syntax
3848169689Skan  "maskmovdqu\t{%2, %1|%1, %2}"
3849169689Skan  [(set_attr "type" "ssecvt")
3850169689Skan   (set_attr "mode" "TI")])
3851169689Skan
3852169689Skan(define_insn "*sse2_maskmovdqu_rex64"
3853169689Skan  [(set (mem:V16QI (match_operand:DI 0 "register_operand" "D"))
3854169689Skan	(unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
3855169689Skan		       (match_operand:V16QI 2 "register_operand" "x")
3856169689Skan		       (mem:V16QI (match_dup 0))]
3857169689Skan		      UNSPEC_MASKMOV))]
3858169689Skan  "TARGET_SSE2 && TARGET_64BIT"
3859169689Skan  ;; @@@ check ordering of operands in intel/nonintel syntax
3860169689Skan  "maskmovdqu\t{%2, %1|%1, %2}"
3861169689Skan  [(set_attr "type" "ssecvt")
3862169689Skan   (set_attr "mode" "TI")])
3863169689Skan
3864169689Skan(define_insn "sse_ldmxcsr"
3865169689Skan  [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")]
3866169689Skan		    UNSPECV_LDMXCSR)]
3867169689Skan  "TARGET_SSE"
3868169689Skan  "ldmxcsr\t%0"
3869169689Skan  [(set_attr "type" "sse")
3870169689Skan   (set_attr "memory" "load")])
3871169689Skan
3872169689Skan(define_insn "sse_stmxcsr"
3873169689Skan  [(set (match_operand:SI 0 "memory_operand" "=m")
3874169689Skan	(unspec_volatile:SI [(const_int 0)] UNSPECV_STMXCSR))]
3875169689Skan  "TARGET_SSE"
3876169689Skan  "stmxcsr\t%0"
3877169689Skan  [(set_attr "type" "sse")
3878169689Skan   (set_attr "memory" "store")])
3879169689Skan
3880169689Skan(define_expand "sse_sfence"
3881169689Skan  [(set (match_dup 0)
3882169689Skan	(unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
3883169689Skan  "TARGET_SSE || TARGET_3DNOW_A"
3884169689Skan{
3885169689Skan  operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
3886169689Skan  MEM_VOLATILE_P (operands[0]) = 1;
3887169689Skan})
3888169689Skan
3889169689Skan(define_insn "*sse_sfence"
3890169689Skan  [(set (match_operand:BLK 0 "" "")
3891169689Skan	(unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
3892169689Skan  "TARGET_SSE || TARGET_3DNOW_A"
3893169689Skan  "sfence"
3894169689Skan  [(set_attr "type" "sse")
3895169689Skan   (set_attr "memory" "unknown")])
3896169689Skan
3897169689Skan(define_insn "sse2_clflush"
3898169689Skan  [(unspec_volatile [(match_operand 0 "address_operand" "p")]
3899169689Skan		    UNSPECV_CLFLUSH)]
3900169689Skan  "TARGET_SSE2"
3901169689Skan  "clflush\t%a0"
3902169689Skan  [(set_attr "type" "sse")
3903169689Skan   (set_attr "memory" "unknown")])
3904169689Skan
3905169689Skan(define_expand "sse2_mfence"
3906169689Skan  [(set (match_dup 0)
3907169689Skan	(unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
3908169689Skan  "TARGET_SSE2"
3909169689Skan{
3910169689Skan  operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
3911169689Skan  MEM_VOLATILE_P (operands[0]) = 1;
3912169689Skan})
3913169689Skan
3914169689Skan(define_insn "*sse2_mfence"
3915169689Skan  [(set (match_operand:BLK 0 "" "")
3916169689Skan	(unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
3917169689Skan  "TARGET_SSE2"
3918169689Skan  "mfence"
3919169689Skan  [(set_attr "type" "sse")
3920169689Skan   (set_attr "memory" "unknown")])
3921169689Skan
3922169689Skan(define_expand "sse2_lfence"
3923169689Skan  [(set (match_dup 0)
3924169689Skan	(unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
3925169689Skan  "TARGET_SSE2"
3926169689Skan{
3927169689Skan  operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
3928169689Skan  MEM_VOLATILE_P (operands[0]) = 1;
3929169689Skan})
3930169689Skan
3931169689Skan(define_insn "*sse2_lfence"
3932169689Skan  [(set (match_operand:BLK 0 "" "")
3933169689Skan	(unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
3934169689Skan  "TARGET_SSE2"
3935169689Skan  "lfence"
3936169689Skan  [(set_attr "type" "sse")
3937169689Skan   (set_attr "memory" "unknown")])
3938169689Skan
3939169689Skan(define_insn "sse3_mwait"
3940169689Skan  [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
3941169689Skan		     (match_operand:SI 1 "register_operand" "c")]
3942169689Skan		    UNSPECV_MWAIT)]
3943169689Skan  "TARGET_SSE3"
3944169689Skan;; 64bit version is "mwait %rax,%rcx". But only lower 32bits are used.
3945169689Skan;; Since 32bit register operands are implicitly zero extended to 64bit,
3946169689Skan;; we only need to set up 32bit registers.
3947169689Skan  "mwait"
3948169689Skan  [(set_attr "length" "3")])
3949169689Skan
3950169689Skan(define_insn "sse3_monitor"
3951169689Skan  [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
3952169689Skan		     (match_operand:SI 1 "register_operand" "c")
3953169689Skan		     (match_operand:SI 2 "register_operand" "d")]
3954169689Skan		    UNSPECV_MONITOR)]
3955169689Skan  "TARGET_SSE3 && !TARGET_64BIT"
3956169689Skan  "monitor\t%0, %1, %2"
3957169689Skan  [(set_attr "length" "3")])
3958169689Skan
3959169689Skan(define_insn "sse3_monitor64"
3960169689Skan  [(unspec_volatile [(match_operand:DI 0 "register_operand" "a")
3961169689Skan		     (match_operand:SI 1 "register_operand" "c")
3962169689Skan		     (match_operand:SI 2 "register_operand" "d")]
3963169689Skan		    UNSPECV_MONITOR)]
3964169689Skan  "TARGET_SSE3 && TARGET_64BIT"
3965169689Skan;; 64bit version is "monitor %rax,%rcx,%rdx". But only lower 32bits in
3966169689Skan;; RCX and RDX are used.  Since 32bit register operands are implicitly
3967169689Skan;; zero extended to 64bit, we only need to set up 32bit registers.
3968169689Skan  "monitor"
3969169689Skan  [(set_attr "length" "3")])
3970219639Smm
3971219639Smm;; SSSE3
3972219639Smm(define_insn "ssse3_phaddwv8hi3"
3973219639Smm  [(set (match_operand:V8HI 0 "register_operand" "=x")
3974219639Smm	(vec_concat:V8HI
3975219639Smm	  (vec_concat:V4HI
3976219639Smm	    (vec_concat:V2HI
3977219639Smm	      (plus:HI
3978219639Smm		(vec_select:HI
3979219639Smm		  (match_operand:V8HI 1 "register_operand" "0")
3980219639Smm		  (parallel [(const_int 0)]))
3981219639Smm		(vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
3982219639Smm	      (plus:HI
3983219639Smm		(vec_select:HI (match_dup 1) (parallel [(const_int 2)]))
3984219639Smm		(vec_select:HI (match_dup 1) (parallel [(const_int 3)]))))
3985219639Smm	    (vec_concat:V2HI
3986219639Smm	      (plus:HI
3987219639Smm		(vec_select:HI (match_dup 1) (parallel [(const_int 4)]))
3988219639Smm		(vec_select:HI (match_dup 1) (parallel [(const_int 5)])))
3989219639Smm	      (plus:HI
3990219639Smm		(vec_select:HI (match_dup 1) (parallel [(const_int 6)]))
3991219639Smm		(vec_select:HI (match_dup 1) (parallel [(const_int 7)])))))
3992219639Smm	  (vec_concat:V4HI
3993219639Smm	    (vec_concat:V2HI
3994219639Smm	      (plus:HI
3995219639Smm		(vec_select:HI
3996219639Smm		  (match_operand:V8HI 2 "nonimmediate_operand" "xm")
3997219639Smm		  (parallel [(const_int 0)]))
3998219639Smm		(vec_select:HI (match_dup 2) (parallel [(const_int 1)])))
3999219639Smm	      (plus:HI
4000219639Smm		(vec_select:HI (match_dup 2) (parallel [(const_int 2)]))
4001219639Smm		(vec_select:HI (match_dup 2) (parallel [(const_int 3)]))))
4002219639Smm	    (vec_concat:V2HI
4003219639Smm	      (plus:HI
4004219639Smm		(vec_select:HI (match_dup 2) (parallel [(const_int 4)]))
4005219639Smm		(vec_select:HI (match_dup 2) (parallel [(const_int 5)])))
4006219639Smm	      (plus:HI
4007219639Smm		(vec_select:HI (match_dup 2) (parallel [(const_int 6)]))
4008219639Smm		(vec_select:HI (match_dup 2) (parallel [(const_int 7)])))))))]
4009219639Smm  "TARGET_SSSE3"
4010219639Smm  "phaddw\t{%2, %0|%0, %2}"
4011219639Smm  [(set_attr "type" "sseiadd")
4012219639Smm   (set_attr "mode" "TI")])
4013219639Smm
4014219639Smm(define_insn "ssse3_phaddwv4hi3"
4015219639Smm  [(set (match_operand:V4HI 0 "register_operand" "=y")
4016219639Smm	(vec_concat:V4HI
4017219639Smm	  (vec_concat:V2HI
4018219639Smm	    (plus:HI
4019219639Smm	      (vec_select:HI
4020219639Smm		(match_operand:V4HI 1 "register_operand" "0")
4021219639Smm		(parallel [(const_int 0)]))
4022219639Smm	      (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
4023219639Smm	    (plus:HI
4024219639Smm	      (vec_select:HI (match_dup 1) (parallel [(const_int 2)]))
4025219639Smm	      (vec_select:HI (match_dup 1) (parallel [(const_int 3)]))))
4026219639Smm	  (vec_concat:V2HI
4027219639Smm	    (plus:HI
4028219639Smm	      (vec_select:HI
4029219639Smm		(match_operand:V4HI 2 "nonimmediate_operand" "ym")
4030219639Smm		(parallel [(const_int 0)]))
4031219639Smm	      (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))
4032219639Smm	    (plus:HI
4033219639Smm	      (vec_select:HI (match_dup 2) (parallel [(const_int 2)]))
4034219639Smm	      (vec_select:HI (match_dup 2) (parallel [(const_int 3)]))))))]
4035219639Smm  "TARGET_SSSE3"
4036219639Smm  "phaddw\t{%2, %0|%0, %2}"
4037219639Smm  [(set_attr "type" "sseiadd")
4038219639Smm   (set_attr "mode" "DI")])
4039219639Smm
4040219639Smm(define_insn "ssse3_phadddv4si3"
4041219639Smm  [(set (match_operand:V4SI 0 "register_operand" "=x")
4042219639Smm	(vec_concat:V4SI
4043219639Smm	  (vec_concat:V2SI
4044219639Smm	    (plus:SI
4045219639Smm	      (vec_select:SI
4046219639Smm		(match_operand:V4SI 1 "register_operand" "0")
4047219639Smm		(parallel [(const_int 0)]))
4048219639Smm	      (vec_select:SI (match_dup 1) (parallel [(const_int 1)])))
4049219639Smm	    (plus:SI
4050219639Smm	      (vec_select:SI (match_dup 1) (parallel [(const_int 2)]))
4051219639Smm	      (vec_select:SI (match_dup 1) (parallel [(const_int 3)]))))
4052219639Smm	  (vec_concat:V2SI
4053219639Smm	    (plus:SI
4054219639Smm	      (vec_select:SI
4055219639Smm		(match_operand:V4SI 2 "nonimmediate_operand" "xm")
4056219639Smm		(parallel [(const_int 0)]))
4057219639Smm	      (vec_select:SI (match_dup 2) (parallel [(const_int 1)])))
4058219639Smm	    (plus:SI
4059219639Smm	      (vec_select:SI (match_dup 2) (parallel [(const_int 2)]))
4060219639Smm	      (vec_select:SI (match_dup 2) (parallel [(const_int 3)]))))))]
4061219639Smm  "TARGET_SSSE3"
4062219639Smm  "phaddd\t{%2, %0|%0, %2}"
4063219639Smm  [(set_attr "type" "sseiadd")
4064219639Smm   (set_attr "mode" "TI")])
4065219639Smm
4066219639Smm(define_insn "ssse3_phadddv2si3"
4067219639Smm  [(set (match_operand:V2SI 0 "register_operand" "=y")
4068219639Smm	(vec_concat:V2SI
4069219639Smm	  (plus:SI
4070219639Smm	    (vec_select:SI
4071219639Smm	      (match_operand:V2SI 1 "register_operand" "0")
4072219639Smm	      (parallel [(const_int 0)]))
4073219639Smm	    (vec_select:SI (match_dup 1) (parallel [(const_int 1)])))
4074219639Smm	  (plus:SI
4075219639Smm	    (vec_select:SI
4076219639Smm	      (match_operand:V2SI 2 "nonimmediate_operand" "ym")
4077219639Smm	      (parallel [(const_int 0)]))
4078219639Smm	    (vec_select:SI (match_dup 2) (parallel [(const_int 1)])))))]
4079219639Smm  "TARGET_SSSE3"
4080219639Smm  "phaddd\t{%2, %0|%0, %2}"
4081219639Smm  [(set_attr "type" "sseiadd")
4082219639Smm   (set_attr "mode" "DI")])
4083219639Smm
4084219639Smm(define_insn "ssse3_phaddswv8hi3"
4085219639Smm  [(set (match_operand:V8HI 0 "register_operand" "=x")
4086219639Smm	(vec_concat:V8HI
4087219639Smm	  (vec_concat:V4HI
4088219639Smm	    (vec_concat:V2HI
4089219639Smm	      (ss_plus:HI
4090219639Smm		(vec_select:HI
4091219639Smm		  (match_operand:V8HI 1 "register_operand" "0")
4092219639Smm		  (parallel [(const_int 0)]))
4093219639Smm		(vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
4094219639Smm	      (ss_plus:HI
4095219639Smm		(vec_select:HI (match_dup 1) (parallel [(const_int 2)]))
4096219639Smm		(vec_select:HI (match_dup 1) (parallel [(const_int 3)]))))
4097219639Smm	    (vec_concat:V2HI
4098219639Smm	      (ss_plus:HI
4099219639Smm		(vec_select:HI (match_dup 1) (parallel [(const_int 4)]))
4100219639Smm		(vec_select:HI (match_dup 1) (parallel [(const_int 5)])))
4101219639Smm	      (ss_plus:HI
4102219639Smm		(vec_select:HI (match_dup 1) (parallel [(const_int 6)]))
4103219639Smm		(vec_select:HI (match_dup 1) (parallel [(const_int 7)])))))
4104219639Smm	  (vec_concat:V4HI
4105219639Smm	    (vec_concat:V2HI
4106219639Smm	      (ss_plus:HI
4107219639Smm		(vec_select:HI
4108219639Smm		  (match_operand:V8HI 2 "nonimmediate_operand" "xm")
4109219639Smm		  (parallel [(const_int 0)]))
4110219639Smm		(vec_select:HI (match_dup 2) (parallel [(const_int 1)])))
4111219639Smm	      (ss_plus:HI
4112219639Smm		(vec_select:HI (match_dup 2) (parallel [(const_int 2)]))
4113219639Smm		(vec_select:HI (match_dup 2) (parallel [(const_int 3)]))))
4114219639Smm	    (vec_concat:V2HI
4115219639Smm	      (ss_plus:HI
4116219639Smm		(vec_select:HI (match_dup 2) (parallel [(const_int 4)]))
4117219639Smm		(vec_select:HI (match_dup 2) (parallel [(const_int 5)])))
4118219639Smm	      (ss_plus:HI
4119219639Smm		(vec_select:HI (match_dup 2) (parallel [(const_int 6)]))
4120219639Smm		(vec_select:HI (match_dup 2) (parallel [(const_int 7)])))))))]
4121219639Smm  "TARGET_SSSE3"
4122219639Smm  "phaddsw\t{%2, %0|%0, %2}"
4123219639Smm  [(set_attr "type" "sseiadd")
4124219639Smm   (set_attr "mode" "TI")])
4125219639Smm
4126219639Smm(define_insn "ssse3_phaddswv4hi3"
4127219639Smm  [(set (match_operand:V4HI 0 "register_operand" "=y")
4128219639Smm	(vec_concat:V4HI
4129219639Smm	  (vec_concat:V2HI
4130219639Smm	    (ss_plus:HI
4131219639Smm	      (vec_select:HI
4132219639Smm		(match_operand:V4HI 1 "register_operand" "0")
4133219639Smm		(parallel [(const_int 0)]))
4134219639Smm	      (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
4135219639Smm	    (ss_plus:HI
4136219639Smm	      (vec_select:HI (match_dup 1) (parallel [(const_int 2)]))
4137219639Smm	      (vec_select:HI (match_dup 1) (parallel [(const_int 3)]))))
4138219639Smm	  (vec_concat:V2HI
4139219639Smm	    (ss_plus:HI
4140219639Smm	      (vec_select:HI
4141219639Smm		(match_operand:V4HI 2 "nonimmediate_operand" "ym")
4142219639Smm		(parallel [(const_int 0)]))
4143219639Smm	      (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))
4144219639Smm	    (ss_plus:HI
4145219639Smm	      (vec_select:HI (match_dup 2) (parallel [(const_int 2)]))
4146219639Smm	      (vec_select:HI (match_dup 2) (parallel [(const_int 3)]))))))]
4147219639Smm  "TARGET_SSSE3"
4148219639Smm  "phaddsw\t{%2, %0|%0, %2}"
4149219639Smm  [(set_attr "type" "sseiadd")
4150219639Smm   (set_attr "mode" "DI")])
4151219639Smm
4152219639Smm(define_insn "ssse3_phsubwv8hi3"
4153219639Smm  [(set (match_operand:V8HI 0 "register_operand" "=x")
4154219639Smm	(vec_concat:V8HI
4155219639Smm	  (vec_concat:V4HI
4156219639Smm	    (vec_concat:V2HI
4157219639Smm	      (minus:HI
4158219639Smm		(vec_select:HI
4159219639Smm		  (match_operand:V8HI 1 "register_operand" "0")
4160219639Smm		  (parallel [(const_int 0)]))
4161219639Smm		(vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
4162219639Smm	      (minus:HI
4163219639Smm		(vec_select:HI (match_dup 1) (parallel [(const_int 2)]))
4164219639Smm		(vec_select:HI (match_dup 1) (parallel [(const_int 3)]))))
4165219639Smm	    (vec_concat:V2HI
4166219639Smm	      (minus:HI
4167219639Smm		(vec_select:HI (match_dup 1) (parallel [(const_int 4)]))
4168219639Smm		(vec_select:HI (match_dup 1) (parallel [(const_int 5)])))
4169219639Smm	      (minus:HI
4170219639Smm		(vec_select:HI (match_dup 1) (parallel [(const_int 6)]))
4171219639Smm		(vec_select:HI (match_dup 1) (parallel [(const_int 7)])))))
4172219639Smm	  (vec_concat:V4HI
4173219639Smm	    (vec_concat:V2HI
4174219639Smm	      (minus:HI
4175219639Smm		(vec_select:HI
4176219639Smm		  (match_operand:V8HI 2 "nonimmediate_operand" "xm")
4177219639Smm		  (parallel [(const_int 0)]))
4178219639Smm		(vec_select:HI (match_dup 2) (parallel [(const_int 1)])))
4179219639Smm	      (minus:HI
4180219639Smm		(vec_select:HI (match_dup 2) (parallel [(const_int 2)]))
4181219639Smm		(vec_select:HI (match_dup 2) (parallel [(const_int 3)]))))
4182219639Smm	    (vec_concat:V2HI
4183219639Smm	      (minus:HI
4184219639Smm		(vec_select:HI (match_dup 2) (parallel [(const_int 4)]))
4185219639Smm		(vec_select:HI (match_dup 2) (parallel [(const_int 5)])))
4186219639Smm	      (minus:HI
4187219639Smm		(vec_select:HI (match_dup 2) (parallel [(const_int 6)]))
4188219639Smm		(vec_select:HI (match_dup 2) (parallel [(const_int 7)])))))))]
4189219639Smm  "TARGET_SSSE3"
4190219639Smm  "phsubw\t{%2, %0|%0, %2}"
4191219639Smm  [(set_attr "type" "sseiadd")
4192219639Smm   (set_attr "mode" "TI")])
4193219639Smm
4194219639Smm(define_insn "ssse3_phsubwv4hi3"
4195219639Smm  [(set (match_operand:V4HI 0 "register_operand" "=y")
4196219639Smm	(vec_concat:V4HI
4197219639Smm	  (vec_concat:V2HI
4198219639Smm	    (minus:HI
4199219639Smm	      (vec_select:HI
4200219639Smm		(match_operand:V4HI 1 "register_operand" "0")
4201219639Smm		(parallel [(const_int 0)]))
4202219639Smm	      (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
4203219639Smm	    (minus:HI
4204219639Smm	      (vec_select:HI (match_dup 1) (parallel [(const_int 2)]))
4205219639Smm	      (vec_select:HI (match_dup 1) (parallel [(const_int 3)]))))
4206219639Smm	  (vec_concat:V2HI
4207219639Smm	    (minus:HI
4208219639Smm	      (vec_select:HI
4209219639Smm		(match_operand:V4HI 2 "nonimmediate_operand" "ym")
4210219639Smm		(parallel [(const_int 0)]))
4211219639Smm	      (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))
4212219639Smm	    (minus:HI
4213219639Smm	      (vec_select:HI (match_dup 2) (parallel [(const_int 2)]))
4214219639Smm	      (vec_select:HI (match_dup 2) (parallel [(const_int 3)]))))))]
4215219639Smm  "TARGET_SSSE3"
4216219639Smm  "phsubw\t{%2, %0|%0, %2}"
4217219639Smm  [(set_attr "type" "sseiadd")
4218219639Smm   (set_attr "mode" "DI")])
4219219639Smm
4220219639Smm(define_insn "ssse3_phsubdv4si3"
4221219639Smm  [(set (match_operand:V4SI 0 "register_operand" "=x")
4222219639Smm	(vec_concat:V4SI
4223219639Smm	  (vec_concat:V2SI
4224219639Smm	    (minus:SI
4225219639Smm	      (vec_select:SI
4226219639Smm		(match_operand:V4SI 1 "register_operand" "0")
4227219639Smm		(parallel [(const_int 0)]))
4228219639Smm	      (vec_select:SI (match_dup 1) (parallel [(const_int 1)])))
4229219639Smm	    (minus:SI
4230219639Smm	      (vec_select:SI (match_dup 1) (parallel [(const_int 2)]))
4231219639Smm	      (vec_select:SI (match_dup 1) (parallel [(const_int 3)]))))
4232219639Smm	  (vec_concat:V2SI
4233219639Smm	    (minus:SI
4234219639Smm	      (vec_select:SI
4235219639Smm		(match_operand:V4SI 2 "nonimmediate_operand" "xm")
4236219639Smm		(parallel [(const_int 0)]))
4237219639Smm	      (vec_select:SI (match_dup 2) (parallel [(const_int 1)])))
4238219639Smm	    (minus:SI
4239219639Smm	      (vec_select:SI (match_dup 2) (parallel [(const_int 2)]))
4240219639Smm	      (vec_select:SI (match_dup 2) (parallel [(const_int 3)]))))))]
4241219639Smm  "TARGET_SSSE3"
4242219639Smm  "phsubd\t{%2, %0|%0, %2}"
4243219639Smm  [(set_attr "type" "sseiadd")
4244219639Smm   (set_attr "mode" "TI")])
4245219639Smm
4246219639Smm(define_insn "ssse3_phsubdv2si3"
4247219639Smm  [(set (match_operand:V2SI 0 "register_operand" "=y")
4248219639Smm	(vec_concat:V2SI
4249219639Smm	  (minus:SI
4250219639Smm	    (vec_select:SI
4251219639Smm	      (match_operand:V2SI 1 "register_operand" "0")
4252219639Smm	      (parallel [(const_int 0)]))
4253219639Smm	    (vec_select:SI (match_dup 1) (parallel [(const_int 1)])))
4254219639Smm	  (minus:SI
4255219639Smm	    (vec_select:SI
4256219639Smm	      (match_operand:V2SI 2 "nonimmediate_operand" "ym")
4257219639Smm	      (parallel [(const_int 0)]))
4258219639Smm	    (vec_select:SI (match_dup 2) (parallel [(const_int 1)])))))]
4259219639Smm  "TARGET_SSSE3"
4260219639Smm  "phsubd\t{%2, %0|%0, %2}"
4261219639Smm  [(set_attr "type" "sseiadd")
4262219639Smm   (set_attr "mode" "DI")])
4263219639Smm
4264219639Smm(define_insn "ssse3_phsubswv8hi3"
4265219639Smm  [(set (match_operand:V8HI 0 "register_operand" "=x")
4266219639Smm	(vec_concat:V8HI
4267219639Smm	  (vec_concat:V4HI
4268219639Smm	    (vec_concat:V2HI
4269219639Smm	      (ss_minus:HI
4270219639Smm		(vec_select:HI
4271219639Smm		  (match_operand:V8HI 1 "register_operand" "0")
4272219639Smm		  (parallel [(const_int 0)]))
4273219639Smm		(vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
4274219639Smm	      (ss_minus:HI
4275219639Smm		(vec_select:HI (match_dup 1) (parallel [(const_int 2)]))
4276219639Smm		(vec_select:HI (match_dup 1) (parallel [(const_int 3)]))))
4277219639Smm	    (vec_concat:V2HI
4278219639Smm	      (ss_minus:HI
4279219639Smm		(vec_select:HI (match_dup 1) (parallel [(const_int 4)]))
4280219639Smm		(vec_select:HI (match_dup 1) (parallel [(const_int 5)])))
4281219639Smm	      (ss_minus:HI
4282219639Smm		(vec_select:HI (match_dup 1) (parallel [(const_int 6)]))
4283219639Smm		(vec_select:HI (match_dup 1) (parallel [(const_int 7)])))))
4284219639Smm	  (vec_concat:V4HI
4285219639Smm	    (vec_concat:V2HI
4286219639Smm	      (ss_minus:HI
4287219639Smm		(vec_select:HI
4288219639Smm		  (match_operand:V8HI 2 "nonimmediate_operand" "xm")
4289219639Smm		  (parallel [(const_int 0)]))
4290219639Smm		(vec_select:HI (match_dup 2) (parallel [(const_int 1)])))
4291219639Smm	      (ss_minus:HI
4292219639Smm		(vec_select:HI (match_dup 2) (parallel [(const_int 2)]))
4293219639Smm		(vec_select:HI (match_dup 2) (parallel [(const_int 3)]))))
4294219639Smm	    (vec_concat:V2HI
4295219639Smm	      (ss_minus:HI
4296219639Smm		(vec_select:HI (match_dup 2) (parallel [(const_int 4)]))
4297219639Smm		(vec_select:HI (match_dup 2) (parallel [(const_int 5)])))
4298219639Smm	      (ss_minus:HI
4299219639Smm		(vec_select:HI (match_dup 2) (parallel [(const_int 6)]))
4300219639Smm		(vec_select:HI (match_dup 2) (parallel [(const_int 7)])))))))]
4301219639Smm  "TARGET_SSSE3"
4302219639Smm  "phsubsw\t{%2, %0|%0, %2}"
4303219639Smm  [(set_attr "type" "sseiadd")
4304219639Smm   (set_attr "mode" "TI")])
4305219639Smm
4306219639Smm(define_insn "ssse3_phsubswv4hi3"
4307219639Smm  [(set (match_operand:V4HI 0 "register_operand" "=y")
4308219639Smm	(vec_concat:V4HI
4309219639Smm	  (vec_concat:V2HI
4310219639Smm	    (ss_minus:HI
4311219639Smm	      (vec_select:HI
4312219639Smm		(match_operand:V4HI 1 "register_operand" "0")
4313219639Smm		(parallel [(const_int 0)]))
4314219639Smm	      (vec_select:HI (match_dup 1) (parallel [(const_int 1)])))
4315219639Smm	    (ss_minus:HI
4316219639Smm	      (vec_select:HI (match_dup 1) (parallel [(const_int 2)]))
4317219639Smm	      (vec_select:HI (match_dup 1) (parallel [(const_int 3)]))))
4318219639Smm	  (vec_concat:V2HI
4319219639Smm	    (ss_minus:HI
4320219639Smm	      (vec_select:HI
4321219639Smm		(match_operand:V4HI 2 "nonimmediate_operand" "ym")
4322219639Smm		(parallel [(const_int 0)]))
4323219639Smm	      (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))
4324219639Smm	    (ss_minus:HI
4325219639Smm	      (vec_select:HI (match_dup 2) (parallel [(const_int 2)]))
4326219639Smm	      (vec_select:HI (match_dup 2) (parallel [(const_int 3)]))))))]
4327219639Smm  "TARGET_SSSE3"
4328219639Smm  "phsubsw\t{%2, %0|%0, %2}"
4329219639Smm  [(set_attr "type" "sseiadd")
4330219639Smm   (set_attr "mode" "DI")])
4331219639Smm
4332219639Smm(define_insn "ssse3_pmaddubswv8hi3"
4333219639Smm  [(set (match_operand:V8HI 0 "register_operand" "=x")
4334219639Smm	(ss_plus:V8HI
4335219639Smm	  (mult:V8HI
4336219639Smm	    (zero_extend:V8HI
4337219639Smm	      (vec_select:V4QI
4338219639Smm		(match_operand:V16QI 1 "nonimmediate_operand" "%0")
4339219639Smm		(parallel [(const_int 0)
4340219639Smm			   (const_int 2)
4341219639Smm			   (const_int 4)
4342219639Smm			   (const_int 6)
4343219639Smm			   (const_int 8)
4344219639Smm			   (const_int 10)
4345219639Smm			   (const_int 12)
4346219639Smm			   (const_int 14)])))
4347219639Smm	    (sign_extend:V8HI
4348219639Smm	      (vec_select:V8QI
4349219639Smm		(match_operand:V16QI 2 "nonimmediate_operand" "xm")
4350219639Smm		(parallel [(const_int 0)
4351219639Smm			   (const_int 2)
4352219639Smm			   (const_int 4)
4353219639Smm			   (const_int 6)
4354219639Smm			   (const_int 8)
4355219639Smm			   (const_int 10)
4356219639Smm			   (const_int 12)
4357219639Smm			   (const_int 14)]))))
4358219639Smm	  (mult:V8HI
4359219639Smm	    (zero_extend:V8HI
4360219639Smm	      (vec_select:V16QI (match_dup 1)
4361219639Smm		(parallel [(const_int 1)
4362219639Smm			   (const_int 3)
4363219639Smm			   (const_int 5)
4364219639Smm			   (const_int 7)
4365219639Smm			   (const_int 9)
4366219639Smm			   (const_int 11)
4367219639Smm			   (const_int 13)
4368219639Smm			   (const_int 15)])))
4369219639Smm	    (sign_extend:V8HI
4370219639Smm	      (vec_select:V16QI (match_dup 2)
4371219639Smm		(parallel [(const_int 1)
4372219639Smm			   (const_int 3)
4373219639Smm			   (const_int 5)
4374219639Smm			   (const_int 7)
4375219639Smm			   (const_int 9)
4376219639Smm			   (const_int 11)
4377219639Smm			   (const_int 13)
4378219639Smm			   (const_int 15)]))))))]
4379219639Smm  "TARGET_SSSE3"
4380219639Smm  "pmaddubsw\t{%2, %0|%0, %2}"
4381219639Smm  [(set_attr "type" "sseiadd")
4382219639Smm   (set_attr "mode" "TI")])
4383219639Smm
4384219639Smm(define_insn "ssse3_pmaddubswv4hi3"
4385219639Smm  [(set (match_operand:V4HI 0 "register_operand" "=y")
4386219639Smm	(ss_plus:V4HI
4387219639Smm	  (mult:V4HI
4388219639Smm	    (zero_extend:V4HI
4389219639Smm	      (vec_select:V4QI
4390219639Smm		(match_operand:V8QI 1 "nonimmediate_operand" "%0")
4391219639Smm		(parallel [(const_int 0)
4392219639Smm			   (const_int 2)
4393219639Smm			   (const_int 4)
4394219639Smm			   (const_int 6)])))
4395219639Smm	    (sign_extend:V4HI
4396219639Smm	      (vec_select:V4QI
4397219639Smm		(match_operand:V8QI 2 "nonimmediate_operand" "ym")
4398219639Smm		(parallel [(const_int 0)
4399219639Smm			   (const_int 2)
4400219639Smm			   (const_int 4)
4401219639Smm			   (const_int 6)]))))
4402219639Smm	  (mult:V4HI
4403219639Smm	    (zero_extend:V4HI
4404219639Smm	      (vec_select:V8QI (match_dup 1)
4405219639Smm		(parallel [(const_int 1)
4406219639Smm			   (const_int 3)
4407219639Smm			   (const_int 5)
4408219639Smm			   (const_int 7)])))
4409219639Smm	    (sign_extend:V4HI
4410219639Smm	      (vec_select:V8QI (match_dup 2)
4411219639Smm		(parallel [(const_int 1)
4412219639Smm			   (const_int 3)
4413219639Smm			   (const_int 5)
4414219639Smm			   (const_int 7)]))))))]
4415219639Smm  "TARGET_SSSE3"
4416219639Smm  "pmaddubsw\t{%2, %0|%0, %2}"
4417219639Smm  [(set_attr "type" "sseiadd")
4418219639Smm   (set_attr "mode" "DI")])
4419219639Smm
4420219639Smm(define_insn "ssse3_pmulhrswv8hi3"
4421219639Smm  [(set (match_operand:V8HI 0 "register_operand" "=x")
4422219639Smm	(truncate:V8HI
4423219639Smm	  (lshiftrt:V8SI
4424219639Smm	    (plus:V8SI
4425219639Smm	      (lshiftrt:V8SI
4426219639Smm		(mult:V8SI
4427219639Smm		  (sign_extend:V8SI
4428219639Smm		    (match_operand:V8HI 1 "nonimmediate_operand" "%0"))
4429219639Smm		  (sign_extend:V8SI
4430219639Smm		    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
4431219639Smm		(const_int 14))
4432219639Smm	      (const_vector:V8HI [(const_int 1) (const_int 1)
4433219639Smm				  (const_int 1) (const_int 1)
4434219639Smm				  (const_int 1) (const_int 1)
4435219639Smm				  (const_int 1) (const_int 1)]))
4436219639Smm	    (const_int 1))))]
4437219639Smm  "TARGET_SSSE3 && ix86_binary_operator_ok (MULT, V8HImode, operands)"
4438219639Smm  "pmulhrsw\t{%2, %0|%0, %2}"
4439219639Smm  [(set_attr "type" "sseimul")
4440219639Smm   (set_attr "mode" "TI")])
4441219639Smm
4442219639Smm(define_insn "ssse3_pmulhrswv4hi3"
4443219639Smm  [(set (match_operand:V4HI 0 "register_operand" "=y")
4444219639Smm	(truncate:V4HI
4445219639Smm	  (lshiftrt:V4SI
4446219639Smm	    (plus:V4SI
4447219639Smm	      (lshiftrt:V4SI
4448219639Smm		(mult:V4SI
4449219639Smm		  (sign_extend:V4SI
4450219639Smm		    (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
4451219639Smm		  (sign_extend:V4SI
4452219639Smm		    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
4453219639Smm		(const_int 14))
4454219639Smm	      (const_vector:V4HI [(const_int 1) (const_int 1)
4455219639Smm				  (const_int 1) (const_int 1)]))
4456219639Smm	    (const_int 1))))]
4457219639Smm  "TARGET_SSSE3 && ix86_binary_operator_ok (MULT, V4HImode, operands)"
4458219639Smm  "pmulhrsw\t{%2, %0|%0, %2}"
4459219639Smm  [(set_attr "type" "sseimul")
4460219639Smm   (set_attr "mode" "DI")])
4461219639Smm
4462219639Smm(define_insn "ssse3_pshufbv16qi3"
4463219639Smm  [(set (match_operand:V16QI 0 "register_operand" "=x")
4464219639Smm	(unspec:V16QI [(match_operand:V16QI 1 "register_operand" "0")
4465219639Smm		       (match_operand:V16QI 2 "nonimmediate_operand" "xm")]
4466219639Smm		       UNSPEC_PSHUFB))]
4467219639Smm  "TARGET_SSSE3"
4468219639Smm  "pshufb\t{%2, %0|%0, %2}";
4469219639Smm  [(set_attr "type" "sselog1")
4470219639Smm   (set_attr "mode" "TI")])
4471219639Smm
4472219639Smm(define_insn "ssse3_pshufbv8qi3"
4473219639Smm  [(set (match_operand:V8QI 0 "register_operand" "=y")
4474219639Smm	(unspec:V8QI [(match_operand:V8QI 1 "register_operand" "0")
4475219639Smm		      (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
4476219639Smm		      UNSPEC_PSHUFB))]
4477219639Smm  "TARGET_SSSE3"
4478219639Smm  "pshufb\t{%2, %0|%0, %2}";
4479219639Smm  [(set_attr "type" "sselog1")
4480219639Smm   (set_attr "mode" "DI")])
4481219639Smm
4482219639Smm(define_insn "ssse3_psign<mode>3"
4483219639Smm  [(set (match_operand:SSEMODE124 0 "register_operand" "=x")
4484219639Smm	(unspec:SSEMODE124 [(match_operand:SSEMODE124 1 "register_operand" "0")
4485219639Smm			    (match_operand:SSEMODE124 2 "nonimmediate_operand" "xm")]
4486219639Smm			    UNSPEC_PSIGN))]
4487219639Smm  "TARGET_SSSE3"
4488219639Smm  "psign<ssevecsize>\t{%2, %0|%0, %2}";
4489219639Smm  [(set_attr "type" "sselog1")
4490219639Smm   (set_attr "mode" "TI")])
4491219639Smm
4492219639Smm(define_insn "ssse3_psign<mode>3"
4493219639Smm  [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
4494219639Smm	(unspec:MMXMODEI [(match_operand:MMXMODEI 1 "register_operand" "0")
4495219639Smm			  (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")]
4496219639Smm			  UNSPEC_PSIGN))]
4497219639Smm  "TARGET_SSSE3"
4498219639Smm  "psign<mmxvecsize>\t{%2, %0|%0, %2}";
4499219639Smm  [(set_attr "type" "sselog1")
4500219639Smm   (set_attr "mode" "DI")])
4501219639Smm
4502219639Smm(define_insn "ssse3_palignrti"
4503219639Smm  [(set (match_operand:TI 0 "register_operand" "=x")
4504219639Smm	(unspec:TI [(match_operand:TI 1 "register_operand" "0")
4505219639Smm		    (match_operand:TI 2 "nonimmediate_operand" "xm")
4506219639Smm		    (match_operand:SI 3 "const_0_to_255_mul_8_operand" "n")]
4507219639Smm		    UNSPEC_PALIGNR))]
4508219639Smm  "TARGET_SSSE3"
4509219639Smm{
4510219639Smm  operands[3] = GEN_INT (INTVAL (operands[3]) / 8);
4511219639Smm  return "palignr\t{%3, %2, %0|%0, %2, %3}";
4512219639Smm}
4513219639Smm  [(set_attr "type" "sseishft")
4514219639Smm   (set_attr "mode" "TI")])
4515219639Smm
4516219639Smm(define_insn "ssse3_palignrdi"
4517219639Smm  [(set (match_operand:DI 0 "register_operand" "=y")
4518219639Smm	(unspec:DI [(match_operand:DI 1 "register_operand" "0")
4519219639Smm		    (match_operand:DI 2 "nonimmediate_operand" "ym")
4520219639Smm		    (match_operand:SI 3 "const_0_to_255_mul_8_operand" "n")]
4521219639Smm		    UNSPEC_PALIGNR))]
4522219639Smm  "TARGET_SSSE3"
4523219639Smm{
4524219639Smm  operands[3] = GEN_INT (INTVAL (operands[3]) / 8);
4525219639Smm  return "palignr\t{%3, %2, %0|%0, %2, %3}";
4526219639Smm}
4527219639Smm  [(set_attr "type" "sseishft")
4528219639Smm   (set_attr "mode" "DI")])
4529219639Smm
4530219639Smm(define_insn "abs<mode>2"
4531219639Smm  [(set (match_operand:SSEMODE124 0 "register_operand" "=x")
4532219639Smm	(abs:SSEMODE124 (match_operand:SSEMODE124 1 "nonimmediate_operand" "xm")))]
4533219639Smm  "TARGET_SSSE3"
4534219639Smm  "pabs<ssevecsize>\t{%1, %0|%0, %1}";
4535219639Smm  [(set_attr "type" "sselog1")
4536219639Smm   (set_attr "mode" "TI")])
4537219639Smm
4538219639Smm(define_insn "abs<mode>2"
4539219639Smm  [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
4540219639Smm	(abs:MMXMODEI (match_operand:MMXMODEI 1 "nonimmediate_operand" "ym")))]
4541219639Smm  "TARGET_SSSE3"
4542219639Smm  "pabs<mmxvecsize>\t{%1, %0|%0, %1}";
4543219639Smm  [(set_attr "type" "sselog1")
4544219639Smm   (set_attr "mode" "DI")])
4545252080Spfg
4546252080Spfg;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4547252080Spfg;;
4548252080Spfg;; AMD SSE4A instructions
4549252080Spfg;;
4550252080Spfg;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4551252080Spfg
4552252080Spfg(define_insn "sse4a_vmmovntv2df"
4553252080Spfg  [(set (match_operand:DF 0 "memory_operand" "=m")
4554252080Spfg        (unspec:DF [(vec_select:DF 
4555252080Spfg                      (match_operand:V2DF 1 "register_operand" "x")
4556252080Spfg                      (parallel [(const_int 0)]))]
4557252080Spfg                   UNSPEC_MOVNT))]
4558252080Spfg  "TARGET_SSE4A"
4559252080Spfg  "movntsd\t{%1, %0|%0, %1}"
4560252080Spfg  [(set_attr "type" "ssemov")
4561252080Spfg   (set_attr "mode" "DF")])
4562252080Spfg
4563252080Spfg(define_insn "sse4a_movntdf"
4564252080Spfg  [(set (match_operand:DF 0 "memory_operand" "=m")
4565252080Spfg        (unspec:DF [(match_operand:DF 1 "register_operand" "x")]
4566252080Spfg                   UNSPEC_MOVNT))]
4567252080Spfg  "TARGET_SSE4A"
4568252080Spfg  "movntsd\t{%1, %0|%0, %1}"
4569252080Spfg  [(set_attr "type" "ssemov")
4570252080Spfg   (set_attr "mode" "DF")])
4571252080Spfg
4572252080Spfg(define_insn "sse4a_vmmovntv4sf"
4573252080Spfg  [(set (match_operand:SF 0 "memory_operand" "=m")
4574252080Spfg	(unspec:SF [(vec_select:SF 
4575252080Spfg	              (match_operand:V4SF 1 "register_operand" "x")
4576252080Spfg		      (parallel [(const_int 0)]))]
4577252080Spfg		   UNSPEC_MOVNT))]
4578252080Spfg  "TARGET_SSE4A"
4579252080Spfg  "movntss\t{%1, %0|%0, %1}"
4580252080Spfg  [(set_attr "type" "ssemov")
4581252080Spfg   (set_attr "mode" "SF")])
4582252080Spfg
4583252080Spfg(define_insn "sse4a_movntsf"
4584252080Spfg  [(set (match_operand:SF 0 "memory_operand" "=m")
4585252080Spfg	(unspec:SF [(match_operand:SF 1 "register_operand" "x")]
4586252080Spfg		   UNSPEC_MOVNT))]
4587252080Spfg  "TARGET_SSE4A"
4588252080Spfg  "movntss\t{%1, %0|%0, %1}"
4589252080Spfg  [(set_attr "type" "ssemov")
4590252080Spfg   (set_attr "mode" "SF")])
4591252080Spfg
4592252080Spfg(define_insn "sse4a_extrqi"
4593252080Spfg  [(set (match_operand:V2DI 0 "register_operand" "=x")
4594252080Spfg        (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "0")
4595252080Spfg                      (match_operand 2 "const_int_operand" "")
4596252080Spfg                      (match_operand 3 "const_int_operand" "")]
4597252080Spfg                     UNSPEC_EXTRQI))]
4598252080Spfg  "TARGET_SSE4A"
4599252080Spfg  "extrq\t{%3, %2, %0|%0, %2, %3}"
4600252080Spfg  [(set_attr "type" "sse")
4601252080Spfg   (set_attr "mode" "TI")])
4602252080Spfg
4603252080Spfg(define_insn "sse4a_extrq"
4604252080Spfg  [(set (match_operand:V2DI 0 "register_operand" "=x")
4605252080Spfg        (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "0")
4606252080Spfg                      (match_operand:V16QI 2 "register_operand" "x")]
4607252080Spfg                     UNSPEC_EXTRQ))]
4608252080Spfg  "TARGET_SSE4A"
4609252080Spfg  "extrq\t{%2, %0|%0, %2}"
4610252080Spfg  [(set_attr "type" "sse")
4611252080Spfg   (set_attr "mode" "TI")])
4612252080Spfg
4613252080Spfg(define_insn "sse4a_insertqi"
4614252080Spfg  [(set (match_operand:V2DI 0 "register_operand" "=x")
4615252080Spfg        (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "0")
4616252080Spfg        	      (match_operand:V2DI 2 "register_operand" "x")
4617252080Spfg                      (match_operand 3 "const_int_operand" "")
4618252080Spfg                      (match_operand 4 "const_int_operand" "")]
4619252080Spfg                     UNSPEC_INSERTQI))]
4620252080Spfg  "TARGET_SSE4A"
4621252080Spfg  "insertq\t{%4, %3, %2, %0|%0, %2, %3, %4}"
4622252080Spfg  [(set_attr "type" "sseins")
4623252080Spfg   (set_attr "mode" "TI")])
4624252080Spfg
4625252080Spfg(define_insn "sse4a_insertq"
4626252080Spfg  [(set (match_operand:V2DI 0 "register_operand" "=x")
4627252080Spfg        (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "0")
4628252080Spfg        	      (match_operand:V2DI 2 "register_operand" "x")]
4629252080Spfg        	     UNSPEC_INSERTQ))]
4630252080Spfg  "TARGET_SSE4A"
4631252080Spfg  "insertq\t{%2, %0|%0, %2}"
4632252080Spfg  [(set_attr "type" "sseins")
4633252080Spfg   (set_attr "mode" "TI")])
4634