1;; GCC machine description for MMX and 3dNOW! instructions
2;; Copyright (C) 2005-2020 Free Software Foundation, Inc.
3;;
4;; This file is part of GCC.
5;;
6;; GCC is free software; you can redistribute it and/or modify
7;; it under the terms of the GNU General Public License as published by
8;; the Free Software Foundation; either version 3, or (at your option)
9;; any later version.
10;;
11;; GCC is distributed in the hope that it will be useful,
12;; but WITHOUT ANY WARRANTY; without even the implied warranty of
13;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14;; GNU General Public License for more details.
15;;
16;; You should have received a copy of the GNU General Public License
17;; along with GCC; see the file COPYING3.  If not see
18;; <http://www.gnu.org/licenses/>.
19
20;; The MMX and 3dNOW! patterns are in the same file because they use
21;; the same register file, and 3dNOW! adds a number of extensions to
22;; the base integer MMX isa.
23
24;; Note!  Except for the basic move instructions, *all* of these
25;; patterns are outside the normal optabs namespace.  This is because
26;; use of these registers requires the insertion of emms or femms
27;; instructions to return to normal fpu mode.  The compiler doesn't
28;; know how to do that itself, which means it's up to the user.  Which
29;; means that we should never use any of these patterns except at the
30;; direction of the user via a builtin.
31
32(define_c_enum "unspec" [
33  UNSPEC_MOVNTQ
34  UNSPEC_PFRCP
35  UNSPEC_PFRCPIT1
36  UNSPEC_PFRCPIT2
37  UNSPEC_PFRSQRT
38  UNSPEC_PFRSQIT1
39])
40
41(define_c_enum "unspecv" [
42  UNSPECV_EMMS
43  UNSPECV_FEMMS
44])
45
46;; 8 byte integral modes handled by MMX (and by extension, SSE)
47(define_mode_iterator MMXMODEI [V8QI V4HI V2SI])
48(define_mode_iterator MMXMODEI8 [V8QI V4HI V2SI (V1DI "TARGET_SSE2")])
49
50;; All 8-byte vector modes handled by MMX
51(define_mode_iterator MMXMODE [V8QI V4HI V2SI V1DI V2SF])
52
53;; Mix-n-match
54(define_mode_iterator MMXMODE12 [V8QI V4HI])
55(define_mode_iterator MMXMODE24 [V4HI V2SI])
56(define_mode_iterator MMXMODE248 [V4HI V2SI V1DI])
57
58;; Mapping from integer vector mode to mnemonic suffix
59(define_mode_attr mmxvecsize [(V8QI "b") (V4HI "w") (V2SI "d") (V1DI "q")])
60
61(define_mode_attr mmxdoublemode
62  [(V8QI "V8HI") (V4HI "V4SI")])
63
64;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
65;;
66;; Move patterns
67;;
68;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
69
70;; All of these patterns are enabled for MMX as well as 3dNOW.
71;; This is essential for maintaining stable calling conventions.
72
73(define_expand "mov<mode>"
74  [(set (match_operand:MMXMODE 0 "nonimmediate_operand")
75	(match_operand:MMXMODE 1 "nonimmediate_operand"))]
76  "TARGET_MMX || TARGET_MMX_WITH_SSE"
77{
78  ix86_expand_vector_move (<MODE>mode, operands);
79  DONE;
80})
81
82(define_insn "*mov<mode>_internal"
83  [(set (match_operand:MMXMODE 0 "nonimmediate_operand"
84    "=r ,o ,r,r ,m ,?!y,!y,?!y,m  ,r  ,?!y,v,v,v,m,r,v,!y,*x")
85	(match_operand:MMXMODE 1 "nonimm_or_0_operand"
86    "rCo,rC,C,rm,rC,C  ,!y,m  ,?!y,?!y,r  ,C,v,m,v,v,r,*x,!y"))]
87  "(TARGET_MMX || TARGET_MMX_WITH_SSE)
88   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
89{
90  switch (get_attr_type (insn))
91    {
92    case TYPE_MULTI:
93      return "#";
94
95    case TYPE_IMOV:
96      if (get_attr_mode (insn) == MODE_SI)
97	return "mov{l}\t{%1, %k0|%k0, %1}";
98      else
99	return "mov{q}\t{%1, %0|%0, %1}";
100
101    case TYPE_MMX:
102      return "pxor\t%0, %0";
103
104    case TYPE_MMXMOV:
105      /* Handle broken assemblers that require movd instead of movq.  */
106      if (!HAVE_AS_IX86_INTERUNIT_MOVQ
107	  && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
108	return "movd\t{%1, %0|%0, %1}";
109      return "movq\t{%1, %0|%0, %1}";
110
111    case TYPE_SSECVT:
112      if (SSE_REG_P (operands[0]))
113	return "movq2dq\t{%1, %0|%0, %1}";
114      else
115	return "movdq2q\t{%1, %0|%0, %1}";
116
117    case TYPE_SSELOG1:
118      return standard_sse_constant_opcode (insn, operands);
119
120    case TYPE_SSEMOV:
121      return ix86_output_ssemov (insn, operands);
122
123    default:
124      gcc_unreachable ();
125    }
126}
127  [(set (attr "isa")
128     (cond [(eq_attr "alternative" "0,1")
129	      (const_string "nox64")
130	    (eq_attr "alternative" "2,3,4,9,10")
131	      (const_string "x64")
132	    (eq_attr "alternative" "15,16")
133	      (const_string "x64_sse2")
134	    (eq_attr "alternative" "17,18")
135	      (const_string "sse2")
136	   ]
137	   (const_string "*")))
138   (set (attr "type")
139     (cond [(eq_attr "alternative" "0,1")
140	      (const_string "multi")
141	    (eq_attr "alternative" "2,3,4")
142	      (const_string "imov")
143	    (eq_attr "alternative" "5")
144	      (const_string "mmx")
145	    (eq_attr "alternative" "6,7,8,9,10")
146	      (const_string "mmxmov")
147	    (eq_attr "alternative" "11")
148	      (const_string "sselog1")
149	    (eq_attr "alternative" "17,18")
150	      (const_string "ssecvt")
151	   ]
152	   (const_string "ssemov")))
153   (set (attr "prefix_rex")
154     (if_then_else (eq_attr "alternative" "9,10,15,16")
155       (const_string "1")
156       (const_string "*")))
157   (set (attr "prefix")
158     (if_then_else (eq_attr "type" "sselog1,ssemov")
159       (const_string "maybe_vex")
160       (const_string "orig")))
161   (set (attr "prefix_data16")
162     (if_then_else
163       (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
164       (const_string "1")
165       (const_string "*")))
166   (set (attr "mode")
167     (cond [(eq_attr "alternative" "2")
168	      (const_string "SI")
169	    (eq_attr "alternative" "11,12")
170	      (cond [(match_test "<MODE>mode == V2SFmode")
171		       (const_string "V4SF")
172		     (ior (not (match_test "TARGET_SSE2"))
173			  (match_test "optimize_function_for_size_p (cfun)"))
174		       (const_string "V4SF")
175		    ]
176		    (const_string "TI"))
177
178	    (and (eq_attr "alternative" "13,14")
179	    	 (ior (match_test "<MODE>mode == V2SFmode")
180		      (not (match_test "TARGET_SSE2"))))
181	      (const_string "V2SF")
182	   ]
183	   (const_string "DI")))
184   (set (attr "preferred_for_speed")
185     (cond [(eq_attr "alternative" "9,15")
186	      (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
187	    (eq_attr "alternative" "10,16")
188	      (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
189	   ]
190	   (symbol_ref "true")))])
191
192(define_split
193  [(set (match_operand:MMXMODE 0 "nonimmediate_gr_operand")
194        (match_operand:MMXMODE 1 "nonimmediate_gr_operand"))]
195  "!TARGET_64BIT && reload_completed"
196  [(const_int 0)]
197  "ix86_split_long_move (operands); DONE;")
198
199(define_split
200  [(set (match_operand:MMXMODE 0 "nonimmediate_gr_operand")
201        (match_operand:MMXMODE 1 "const0_operand"))]
202  "!TARGET_64BIT && reload_completed"
203  [(const_int 0)]
204  "ix86_split_long_move (operands); DONE;")
205
206(define_expand "movmisalign<mode>"
207  [(set (match_operand:MMXMODE 0 "nonimmediate_operand")
208	(match_operand:MMXMODE 1 "nonimmediate_operand"))]
209  "TARGET_MMX || TARGET_MMX_WITH_SSE"
210{
211  ix86_expand_vector_move (<MODE>mode, operands);
212  DONE;
213})
214
215(define_insn "sse_movntq"
216  [(set (match_operand:DI 0 "memory_operand" "=m,m")
217	(unspec:DI [(match_operand:DI 1 "register_operand" "y,r")]
218		   UNSPEC_MOVNTQ))]
219  "(TARGET_MMX || TARGET_MMX_WITH_SSE)
220   && (TARGET_SSE || TARGET_3DNOW_A)"
221  "@
222   movntq\t{%1, %0|%0, %1}
223   movnti\t{%1, %0|%0, %1}"
224  [(set_attr "isa" "*,x64")
225   (set_attr "mmx_isa" "native,*")
226   (set_attr "type" "mmxmov,ssemov")
227   (set_attr "mode" "DI")])
228
229;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
230;;
231;; Parallel single-precision floating point arithmetic
232;;
233;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
234
235(define_expand "mmx_addv2sf3"
236  [(set (match_operand:V2SF 0 "register_operand")
237	(plus:V2SF
238	  (match_operand:V2SF 1 "nonimmediate_operand")
239	  (match_operand:V2SF 2 "nonimmediate_operand")))]
240  "TARGET_3DNOW"
241  "ix86_fixup_binary_operands_no_copy (PLUS, V2SFmode, operands);")
242
243(define_insn "*mmx_addv2sf3"
244  [(set (match_operand:V2SF 0 "register_operand" "=y")
245	(plus:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "%0")
246		   (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
247  "TARGET_3DNOW && ix86_binary_operator_ok (PLUS, V2SFmode, operands)"
248  "pfadd\t{%2, %0|%0, %2}"
249  [(set_attr "type" "mmxadd")
250   (set_attr "prefix_extra" "1")
251   (set_attr "mode" "V2SF")])
252
253(define_expand "mmx_subv2sf3"
254  [(set (match_operand:V2SF 0 "register_operand")
255        (minus:V2SF (match_operand:V2SF 1 "register_operand")
256		    (match_operand:V2SF 2 "nonimmediate_operand")))]
257  "TARGET_3DNOW")
258
259(define_expand "mmx_subrv2sf3"
260  [(set (match_operand:V2SF 0 "register_operand")
261        (minus:V2SF (match_operand:V2SF 2 "register_operand")
262		    (match_operand:V2SF 1 "nonimmediate_operand")))]
263  "TARGET_3DNOW")
264
265(define_insn "*mmx_subv2sf3"
266  [(set (match_operand:V2SF 0 "register_operand" "=y,y")
267        (minus:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "0,ym")
268		    (match_operand:V2SF 2 "nonimmediate_operand" "ym,0")))]
269  "TARGET_3DNOW && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
270  "@
271   pfsub\t{%2, %0|%0, %2}
272   pfsubr\t{%1, %0|%0, %1}"
273  [(set_attr "type" "mmxadd")
274   (set_attr "prefix_extra" "1")
275   (set_attr "mode" "V2SF")])
276
277(define_expand "mmx_mulv2sf3"
278  [(set (match_operand:V2SF 0 "register_operand")
279	(mult:V2SF (match_operand:V2SF 1 "nonimmediate_operand")
280		   (match_operand:V2SF 2 "nonimmediate_operand")))]
281  "TARGET_3DNOW"
282  "ix86_fixup_binary_operands_no_copy (MULT, V2SFmode, operands);")
283
284(define_insn "*mmx_mulv2sf3"
285  [(set (match_operand:V2SF 0 "register_operand" "=y")
286	(mult:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "%0")
287		   (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
288  "TARGET_3DNOW && ix86_binary_operator_ok (MULT, V2SFmode, operands)"
289  "pfmul\t{%2, %0|%0, %2}"
290  [(set_attr "type" "mmxmul")
291   (set_attr "prefix_extra" "1")
292   (set_attr "mode" "V2SF")])
293
294(define_expand "mmx_<code>v2sf3"
295  [(set (match_operand:V2SF 0 "register_operand")
296        (smaxmin:V2SF
297	  (match_operand:V2SF 1 "nonimmediate_operand")
298	  (match_operand:V2SF 2 "nonimmediate_operand")))]
299  "TARGET_3DNOW"
300{
301  if (!flag_finite_math_only || flag_signed_zeros)
302    {
303      operands[1] = force_reg (V2SFmode, operands[1]);
304      emit_insn (gen_mmx_ieee_<maxmin_float>v2sf3
305		 (operands[0], operands[1], operands[2]));
306      DONE;
307    }
308  else
309    ix86_fixup_binary_operands_no_copy (<CODE>, V2SFmode, operands);
310})
311
312;; These versions of the min/max patterns are intentionally ignorant of
313;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
314;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
315;; are undefined in this condition, we're certain this is correct.
316
317(define_insn "*mmx_<code>v2sf3"
318  [(set (match_operand:V2SF 0 "register_operand" "=y")
319        (smaxmin:V2SF
320	  (match_operand:V2SF 1 "nonimmediate_operand" "%0")
321	  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
322  "TARGET_3DNOW && ix86_binary_operator_ok (<CODE>, V2SFmode, operands)"
323  "pf<maxmin_float>\t{%2, %0|%0, %2}"
324  [(set_attr "type" "mmxadd")
325   (set_attr "prefix_extra" "1")
326   (set_attr "mode" "V2SF")])
327
328;; These versions of the min/max patterns implement exactly the operations
329;;   min = (op1 < op2 ? op1 : op2)
330;;   max = (!(op1 < op2) ? op1 : op2)
331;; Their operands are not commutative, and thus they may be used in the
332;; presence of -0.0 and NaN.
333
334(define_insn "mmx_ieee_<ieee_maxmin>v2sf3"
335  [(set (match_operand:V2SF 0 "register_operand" "=y")
336        (unspec:V2SF
337	  [(match_operand:V2SF 1 "register_operand" "0")
338	   (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
339	  IEEE_MAXMIN))]
340  "TARGET_3DNOW"
341  "pf<ieee_maxmin>\t{%2, %0|%0, %2}"
342  [(set_attr "type" "mmxadd")
343   (set_attr "prefix_extra" "1")
344   (set_attr "mode" "V2SF")])
345
346(define_insn "mmx_rcpv2sf2"
347  [(set (match_operand:V2SF 0 "register_operand" "=y")
348        (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
349		     UNSPEC_PFRCP))]
350  "TARGET_3DNOW"
351  "pfrcp\t{%1, %0|%0, %1}"
352  [(set_attr "type" "mmx")
353   (set_attr "prefix_extra" "1")
354   (set_attr "mode" "V2SF")])
355
356(define_insn "mmx_rcpit1v2sf3"
357  [(set (match_operand:V2SF 0 "register_operand" "=y")
358	(unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
359		      (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
360		     UNSPEC_PFRCPIT1))]
361  "TARGET_3DNOW"
362  "pfrcpit1\t{%2, %0|%0, %2}"
363  [(set_attr "type" "mmx")
364   (set_attr "prefix_extra" "1")
365   (set_attr "mode" "V2SF")])
366
367(define_insn "mmx_rcpit2v2sf3"
368  [(set (match_operand:V2SF 0 "register_operand" "=y")
369	(unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
370		      (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
371		     UNSPEC_PFRCPIT2))]
372  "TARGET_3DNOW"
373  "pfrcpit2\t{%2, %0|%0, %2}"
374  [(set_attr "type" "mmx")
375   (set_attr "prefix_extra" "1")
376   (set_attr "mode" "V2SF")])
377
378(define_insn "mmx_rsqrtv2sf2"
379  [(set (match_operand:V2SF 0 "register_operand" "=y")
380	(unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
381		     UNSPEC_PFRSQRT))]
382  "TARGET_3DNOW"
383  "pfrsqrt\t{%1, %0|%0, %1}"
384  [(set_attr "type" "mmx")
385   (set_attr "prefix_extra" "1")
386   (set_attr "mode" "V2SF")])
387
388(define_insn "mmx_rsqit1v2sf3"
389  [(set (match_operand:V2SF 0 "register_operand" "=y")
390	(unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
391		      (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
392		     UNSPEC_PFRSQIT1))]
393  "TARGET_3DNOW"
394  "pfrsqit1\t{%2, %0|%0, %2}"
395  [(set_attr "type" "mmx")
396   (set_attr "prefix_extra" "1")
397   (set_attr "mode" "V2SF")])
398
399(define_insn "mmx_haddv2sf3"
400  [(set (match_operand:V2SF 0 "register_operand" "=y")
401	(vec_concat:V2SF
402	  (plus:SF
403	    (vec_select:SF
404	      (match_operand:V2SF 1 "register_operand" "0")
405	      (parallel [(const_int  0)]))
406	    (vec_select:SF (match_dup 1) (parallel [(const_int 1)])))
407	  (plus:SF
408            (vec_select:SF
409	      (match_operand:V2SF 2 "nonimmediate_operand" "ym")
410	      (parallel [(const_int  0)]))
411	    (vec_select:SF (match_dup 2) (parallel [(const_int 1)])))))]
412  "TARGET_3DNOW"
413  "pfacc\t{%2, %0|%0, %2}"
414  [(set_attr "type" "mmxadd")
415   (set_attr "prefix_extra" "1")
416   (set_attr "mode" "V2SF")])
417
418(define_insn "mmx_hsubv2sf3"
419  [(set (match_operand:V2SF 0 "register_operand" "=y")
420	(vec_concat:V2SF
421	  (minus:SF
422	    (vec_select:SF
423	      (match_operand:V2SF 1 "register_operand" "0")
424	      (parallel [(const_int  0)]))
425	    (vec_select:SF (match_dup 1) (parallel [(const_int 1)])))
426	  (minus:SF
427            (vec_select:SF
428	      (match_operand:V2SF 2 "nonimmediate_operand" "ym")
429	      (parallel [(const_int  0)]))
430	    (vec_select:SF (match_dup 2) (parallel [(const_int 1)])))))]
431  "TARGET_3DNOW_A"
432  "pfnacc\t{%2, %0|%0, %2}"
433  [(set_attr "type" "mmxadd")
434   (set_attr "prefix_extra" "1")
435   (set_attr "mode" "V2SF")])
436
437(define_insn "mmx_addsubv2sf3"
438  [(set (match_operand:V2SF 0 "register_operand" "=y")
439	(vec_concat:V2SF
440	  (minus:SF
441	    (vec_select:SF
442	      (match_operand:V2SF 1 "register_operand" "0")
443	      (parallel [(const_int  0)]))
444	    (vec_select:SF (match_dup 1) (parallel [(const_int 1)])))
445	  (plus:SF
446            (vec_select:SF
447	      (match_operand:V2SF 2 "nonimmediate_operand" "ym")
448	      (parallel [(const_int  0)]))
449	    (vec_select:SF (match_dup 2) (parallel [(const_int 1)])))))]
450  "TARGET_3DNOW_A"
451  "pfpnacc\t{%2, %0|%0, %2}"
452  [(set_attr "type" "mmxadd")
453   (set_attr "prefix_extra" "1")
454   (set_attr "mode" "V2SF")])
455
456;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
457;;
458;; Parallel single-precision floating point comparisons
459;;
460;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
461
462(define_expand "mmx_eqv2sf3"
463  [(set (match_operand:V2SI 0 "register_operand")
464	(eq:V2SI (match_operand:V2SF 1 "nonimmediate_operand")
465		 (match_operand:V2SF 2 "nonimmediate_operand")))]
466  "TARGET_3DNOW"
467  "ix86_fixup_binary_operands_no_copy (EQ, V2SFmode, operands);")
468
469(define_insn "*mmx_eqv2sf3"
470  [(set (match_operand:V2SI 0 "register_operand" "=y")
471	(eq:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "%0")
472		 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
473  "TARGET_3DNOW && ix86_binary_operator_ok (EQ, V2SFmode, operands)"
474  "pfcmpeq\t{%2, %0|%0, %2}"
475  [(set_attr "type" "mmxcmp")
476   (set_attr "prefix_extra" "1")
477   (set_attr "mode" "V2SF")])
478
479(define_insn "mmx_gtv2sf3"
480  [(set (match_operand:V2SI 0 "register_operand" "=y")
481	(gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
482		 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
483  "TARGET_3DNOW"
484  "pfcmpgt\t{%2, %0|%0, %2}"
485  [(set_attr "type" "mmxcmp")
486   (set_attr "prefix_extra" "1")
487   (set_attr "mode" "V2SF")])
488
489(define_insn "mmx_gev2sf3"
490  [(set (match_operand:V2SI 0 "register_operand" "=y")
491	(ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
492		 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
493  "TARGET_3DNOW"
494  "pfcmpge\t{%2, %0|%0, %2}"
495  [(set_attr "type" "mmxcmp")
496   (set_attr "prefix_extra" "1")
497   (set_attr "mode" "V2SF")])
498
499;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
500;;
501;; Parallel single-precision floating point conversion operations
502;;
503;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
504
505(define_insn "mmx_pf2id"
506  [(set (match_operand:V2SI 0 "register_operand" "=y")
507	(fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
508  "TARGET_3DNOW"
509  "pf2id\t{%1, %0|%0, %1}"
510  [(set_attr "type" "mmxcvt")
511   (set_attr "prefix_extra" "1")
512   (set_attr "mode" "V2SF")])
513
514(define_insn "mmx_pf2iw"
515  [(set (match_operand:V2SI 0 "register_operand" "=y")
516	(sign_extend:V2SI
517	  (ss_truncate:V2HI
518	    (fix:V2SI
519	      (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
520  "TARGET_3DNOW_A"
521  "pf2iw\t{%1, %0|%0, %1}"
522  [(set_attr "type" "mmxcvt")
523   (set_attr "prefix_extra" "1")
524   (set_attr "mode" "V2SF")])
525
526(define_insn "mmx_pi2fw"
527  [(set (match_operand:V2SF 0 "register_operand" "=y")
528	(float:V2SF
529	  (sign_extend:V2SI
530	    (truncate:V2HI
531	      (match_operand:V2SI 1 "nonimmediate_operand" "ym")))))]
532  "TARGET_3DNOW_A"
533  "pi2fw\t{%1, %0|%0, %1}"
534  [(set_attr "type" "mmxcvt")
535   (set_attr "prefix_extra" "1")
536   (set_attr "mode" "V2SF")])
537
538(define_insn "mmx_floatv2si2"
539  [(set (match_operand:V2SF 0 "register_operand" "=y")
540	(float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
541  "TARGET_3DNOW"
542  "pi2fd\t{%1, %0|%0, %1}"
543  [(set_attr "type" "mmxcvt")
544   (set_attr "prefix_extra" "1")
545   (set_attr "mode" "V2SF")])
546
547;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
548;;
549;; Parallel single-precision floating point element swizzling
550;;
551;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
552
553(define_insn "mmx_pswapdv2sf2"
554  [(set (match_operand:V2SF 0 "register_operand" "=y")
555	(vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym")
556			 (parallel [(const_int 1) (const_int 0)])))]
557  "TARGET_3DNOW_A"
558  "pswapd\t{%1, %0|%0, %1}"
559  [(set_attr "type" "mmxcvt")
560   (set_attr "prefix_extra" "1")
561   (set_attr "mode" "V2SF")])
562
563(define_insn_and_split "*vec_dupv2sf"
564  [(set (match_operand:V2SF 0 "register_operand" "=y,x,Yv")
565	(vec_duplicate:V2SF
566	  (match_operand:SF 1 "register_operand" "0,0,Yv")))]
567  "TARGET_MMX || TARGET_MMX_WITH_SSE"
568  "@
569   punpckldq\t%0, %0
570   #
571   #"
572  "TARGET_SSE && reload_completed
573   && SSE_REGNO_P (REGNO (operands[0]))"
574  [(set (match_dup 0)
575	(vec_duplicate:V4SF (match_dup 1)))]
576{
577  operands[0] = lowpart_subreg (V4SFmode, operands[0],
578				GET_MODE (operands[0]));
579}
580  [(set_attr "isa" "*,sse_noavx,avx")
581   (set_attr "mmx_isa" "native,*,*")
582   (set_attr "type" "mmxcvt,ssemov,ssemov")
583   (set_attr "mode" "DI,TI,TI")])
584
585(define_insn "*mmx_concatv2sf"
586  [(set (match_operand:V2SF 0 "register_operand"     "=y,y")
587	(vec_concat:V2SF
588	  (match_operand:SF 1 "nonimmediate_operand" " 0,rm")
589	  (match_operand:SF 2 "nonimm_or_0_operand"  "ym,C")))]
590  "TARGET_MMX && !TARGET_SSE"
591  "@
592   punpckldq\t{%2, %0|%0, %2}
593   movd\t{%1, %0|%0, %1}"
594  [(set_attr "type" "mmxcvt,mmxmov")
595   (set_attr "mode" "DI")])
596
597(define_expand "vec_setv2sf"
598  [(match_operand:V2SF 0 "register_operand")
599   (match_operand:SF 1 "register_operand")
600   (match_operand 2 "const_int_operand")]
601  "TARGET_MMX || TARGET_MMX_WITH_SSE"
602{
603  ix86_expand_vector_set (TARGET_MMX_WITH_SSE, operands[0], operands[1],
604			  INTVAL (operands[2]));
605  DONE;
606})
607
608;; Avoid combining registers from different units in a single alternative,
609;; see comment above inline_secondary_memory_needed function in i386.c
610(define_insn_and_split "*vec_extractv2sf_0"
611  [(set (match_operand:SF 0 "nonimmediate_operand"     "=x, m,y ,m,f,r")
612	(vec_select:SF
613	  (match_operand:V2SF 1 "nonimmediate_operand" " xm,x,ym,y,m,m")
614	  (parallel [(const_int 0)])))]
615  "(TARGET_MMX || TARGET_MMX_WITH_SSE)
616   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
617  "#"
618  "&& reload_completed"
619  [(set (match_dup 0) (match_dup 1))]
620  "operands[1] = gen_lowpart (SFmode, operands[1]);"
621  [(set_attr "mmx_isa" "*,*,native,native,*,*")])
622
623;; Avoid combining registers from different units in a single alternative,
624;; see comment above inline_secondary_memory_needed function in i386.c
625(define_insn "*vec_extractv2sf_1"
626  [(set (match_operand:SF 0 "nonimmediate_operand"     "=y,x,x,y,x,f,r")
627	(vec_select:SF
628	  (match_operand:V2SF 1 "nonimmediate_operand" " 0,x,0,o,o,o,o")
629	  (parallel [(const_int 1)])))]
630  "(TARGET_MMX || TARGET_MMX_WITH_SSE)
631   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
632  "@
633   punpckhdq\t%0, %0
634   %vmovshdup\t{%1, %0|%0, %1}
635   shufps\t{$0xe5, %0, %0|%0, %0, 0xe5}
636   #
637   #
638   #
639   #"
640  [(set_attr "isa" "*,sse3,noavx,*,*,*,*")
641   (set_attr "mmx_isa" "native,*,*,native,*,*,*")
642   (set_attr "type" "mmxcvt,sse,sseshuf1,mmxmov,ssemov,fmov,imov")
643   (set (attr "length_immediate")
644     (if_then_else (eq_attr "alternative" "2")
645		   (const_string "1")
646		   (const_string "*")))
647   (set (attr "prefix_rep")
648     (if_then_else (eq_attr "alternative" "1")
649		   (const_string "1")
650		   (const_string "*")))
651   (set_attr "prefix" "orig,maybe_vex,orig,orig,orig,orig,orig")
652   (set_attr "mode" "DI,V4SF,V4SF,SF,SF,SF,SF")])
653
654(define_split
655  [(set (match_operand:SF 0 "register_operand")
656	(vec_select:SF
657	  (match_operand:V2SF 1 "memory_operand")
658	  (parallel [(const_int 1)])))]
659  "(TARGET_MMX || TARGET_MMX_WITH_SSE) && reload_completed"
660  [(set (match_dup 0) (match_dup 1))]
661  "operands[1] = adjust_address (operands[1], SFmode, 4);")
662
663(define_expand "vec_extractv2sfsf"
664  [(match_operand:SF 0 "register_operand")
665   (match_operand:V2SF 1 "register_operand")
666   (match_operand 2 "const_int_operand")]
667  "TARGET_MMX || TARGET_MMX_WITH_SSE"
668{
669  ix86_expand_vector_extract (TARGET_MMX_WITH_SSE, operands[0],
670			      operands[1], INTVAL (operands[2]));
671  DONE;
672})
673
674(define_expand "vec_initv2sfsf"
675  [(match_operand:V2SF 0 "register_operand")
676   (match_operand 1)]
677  "(TARGET_MMX || TARGET_MMX_WITH_SSE) && TARGET_SSE"
678{
679  ix86_expand_vector_init (TARGET_MMX_WITH_SSE, operands[0],
680			   operands[1]);
681  DONE;
682})
683
684;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
685;;
686;; Parallel integral arithmetic
687;;
688;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
689
690(define_expand "mmx_<plusminus_insn><mode>3"
691  [(set (match_operand:MMXMODEI8 0 "register_operand")
692	(plusminus:MMXMODEI8
693	  (match_operand:MMXMODEI8 1 "register_mmxmem_operand")
694	  (match_operand:MMXMODEI8 2 "register_mmxmem_operand")))]
695  "TARGET_MMX || TARGET_MMX_WITH_SSE"
696  "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
697
698(define_expand "<plusminus_insn><mode>3"
699  [(set (match_operand:MMXMODEI 0 "register_operand")
700	(plusminus:MMXMODEI
701	  (match_operand:MMXMODEI 1 "register_operand")
702	  (match_operand:MMXMODEI 2 "register_operand")))]
703  "TARGET_MMX_WITH_SSE"
704  "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
705
706(define_insn "*mmx_<plusminus_insn><mode>3"
707  [(set (match_operand:MMXMODEI8 0 "register_operand" "=y,x,Yv")
708        (plusminus:MMXMODEI8
709	  (match_operand:MMXMODEI8 1 "register_mmxmem_operand" "<comm>0,0,Yv")
710	  (match_operand:MMXMODEI8 2 "register_mmxmem_operand" "ym,x,Yv")))]
711  "(TARGET_MMX || TARGET_MMX_WITH_SSE)
712   && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
713  "@
714   p<plusminus_mnemonic><mmxvecsize>\t{%2, %0|%0, %2}
715   p<plusminus_mnemonic><mmxvecsize>\t{%2, %0|%0, %2}
716   vp<plusminus_mnemonic><mmxvecsize>\t{%2, %1, %0|%0, %1, %2}"
717  [(set_attr "isa" "*,sse2_noavx,avx")
718   (set_attr "mmx_isa" "native,*,*")
719   (set_attr "type" "mmxadd,sseadd,sseadd")
720   (set_attr "mode" "DI,TI,TI")])
721
722(define_expand "mmx_<plusminus_insn><mode>3"
723  [(set (match_operand:MMXMODE12 0 "register_operand")
724	(sat_plusminus:MMXMODE12
725	  (match_operand:MMXMODE12 1 "register_mmxmem_operand")
726	  (match_operand:MMXMODE12 2 "register_mmxmem_operand")))]
727  "TARGET_MMX || TARGET_MMX_WITH_SSE"
728  "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
729
730(define_insn "*mmx_<plusminus_insn><mode>3"
731  [(set (match_operand:MMXMODE12 0 "register_operand" "=y,x,Yv")
732        (sat_plusminus:MMXMODE12
733	  (match_operand:MMXMODE12 1 "register_mmxmem_operand" "<comm>0,0,Yv")
734	  (match_operand:MMXMODE12 2 "register_mmxmem_operand" "ym,x,Yv")))]
735  "(TARGET_MMX || TARGET_MMX_WITH_SSE)
736   && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
737  "@
738   p<plusminus_mnemonic><mmxvecsize>\t{%2, %0|%0, %2}
739   p<plusminus_mnemonic><mmxvecsize>\t{%2, %0|%0, %2}
740   vp<plusminus_mnemonic><mmxvecsize>\t{%2, %1, %0|%0, %1, %2}"
741  [(set_attr "isa" "*,sse2_noavx,avx")
742   (set_attr "mmx_isa" "native,*,*")
743   (set_attr "type" "mmxadd,sseadd,sseadd")
744   (set_attr "mode" "DI,TI,TI")])
745
746(define_expand "mmx_mulv4hi3"
747  [(set (match_operand:V4HI 0 "register_operand")
748        (mult:V4HI (match_operand:V4HI 1 "register_mmxmem_operand")
749		   (match_operand:V4HI 2 "register_mmxmem_operand")))]
750  "TARGET_MMX || TARGET_MMX_WITH_SSE"
751  "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
752
753(define_expand "mulv4hi3"
754  [(set (match_operand:V4HI 0 "register_operand")
755        (mult:V4HI (match_operand:V4HI 1 "register_operand")
756		   (match_operand:V4HI 2 "register_operand")))]
757  "TARGET_MMX_WITH_SSE"
758  "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
759
760(define_insn "*mmx_mulv4hi3"
761  [(set (match_operand:V4HI 0 "register_operand" "=y,x,Yv")
762        (mult:V4HI (match_operand:V4HI 1 "register_mmxmem_operand" "%0,0,Yv")
763		   (match_operand:V4HI 2 "register_mmxmem_operand" "ym,x,Yv")))]
764  "(TARGET_MMX || TARGET_MMX_WITH_SSE)
765   && ix86_binary_operator_ok (MULT, V4HImode, operands)"
766  "@
767   pmullw\t{%2, %0|%0, %2}
768   pmullw\t{%2, %0|%0, %2}
769   vpmullw\t{%2, %1, %0|%0, %1, %2}"
770  [(set_attr "isa" "*,sse2_noavx,avx")
771   (set_attr "mmx_isa" "native,*,*")
772   (set_attr "type" "mmxmul,ssemul,ssemul")
773   (set_attr "mode" "DI,TI,TI")])
774
775(define_expand "mmx_smulv4hi3_highpart"
776  [(set (match_operand:V4HI 0 "register_operand")
777	(truncate:V4HI
778	  (lshiftrt:V4SI
779	    (mult:V4SI
780	      (sign_extend:V4SI
781		(match_operand:V4HI 1 "register_mmxmem_operand"))
782	      (sign_extend:V4SI
783		(match_operand:V4HI 2 "register_mmxmem_operand")))
784	    (const_int 16))))]
785  "TARGET_MMX || TARGET_MMX_WITH_SSE"
786  "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
787
788(define_insn "*mmx_smulv4hi3_highpart"
789  [(set (match_operand:V4HI 0 "register_operand" "=y,x,Yv")
790	(truncate:V4HI
791	  (lshiftrt:V4SI
792	    (mult:V4SI
793	      (sign_extend:V4SI
794		(match_operand:V4HI 1 "register_mmxmem_operand" "%0,0,Yv"))
795	      (sign_extend:V4SI
796		(match_operand:V4HI 2 "register_mmxmem_operand" "ym,x,Yv")))
797	    (const_int 16))))]
798  "(TARGET_MMX || TARGET_MMX_WITH_SSE)
799   && ix86_binary_operator_ok (MULT, V4HImode, operands)"
800  "@
801   pmulhw\t{%2, %0|%0, %2}
802   pmulhw\t{%2, %0|%0, %2}
803   vpmulhw\t{%2, %1, %0|%0, %1, %2}"
804  [(set_attr "isa" "*,sse2_noavx,avx")
805   (set_attr "mmx_isa" "native,*,*")
806   (set_attr "type" "mmxmul,ssemul,ssemul")
807   (set_attr "mode" "DI,TI,TI")])
808
809(define_expand "mmx_umulv4hi3_highpart"
810  [(set (match_operand:V4HI 0 "register_operand")
811	(truncate:V4HI
812	  (lshiftrt:V4SI
813	    (mult:V4SI
814	      (zero_extend:V4SI
815		(match_operand:V4HI 1 "register_mmxmem_operand"))
816	      (zero_extend:V4SI
817		(match_operand:V4HI 2 "register_mmxmem_operand")))
818	    (const_int 16))))]
819  "(TARGET_MMX || TARGET_MMX_WITH_SSE)
820   && (TARGET_SSE || TARGET_3DNOW_A)"
821  "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
822
823(define_insn "*mmx_umulv4hi3_highpart"
824  [(set (match_operand:V4HI 0 "register_operand" "=y,x,Yv")
825	(truncate:V4HI
826	  (lshiftrt:V4SI
827	    (mult:V4SI
828	      (zero_extend:V4SI
829		(match_operand:V4HI 1 "register_mmxmem_operand" "%0,0,Yv"))
830	      (zero_extend:V4SI
831		(match_operand:V4HI 2 "register_mmxmem_operand" "ym,x,Yv")))
832	  (const_int 16))))]
833  "(TARGET_MMX || TARGET_MMX_WITH_SSE)
834   && (TARGET_SSE || TARGET_3DNOW_A)
835   && ix86_binary_operator_ok (MULT, V4HImode, operands)"
836  "@
837   pmulhuw\t{%2, %0|%0, %2}
838   pmulhuw\t{%2, %0|%0, %2}
839   vpmulhuw\t{%2, %1, %0|%0, %1, %2}"
840  [(set_attr "isa" "*,sse2_noavx,avx")
841   (set_attr "mmx_isa" "native,*,*")
842   (set_attr "type" "mmxmul,ssemul,ssemul")
843   (set_attr "mode" "DI,TI,TI")])
844
845(define_expand "mmx_pmaddwd"
846  [(set (match_operand:V2SI 0 "register_operand")
847        (plus:V2SI
848	  (mult:V2SI
849	    (sign_extend:V2SI
850	      (vec_select:V2HI
851		(match_operand:V4HI 1 "register_mmxmem_operand")
852		(parallel [(const_int 0) (const_int 2)])))
853	    (sign_extend:V2SI
854	      (vec_select:V2HI
855		(match_operand:V4HI 2 "register_mmxmem_operand")
856		(parallel [(const_int 0) (const_int 2)]))))
857	  (mult:V2SI
858	    (sign_extend:V2SI
859	      (vec_select:V2HI (match_dup 1)
860		(parallel [(const_int 1) (const_int 3)])))
861	    (sign_extend:V2SI
862	      (vec_select:V2HI (match_dup 2)
863		(parallel [(const_int 1) (const_int 3)]))))))]
864  "TARGET_MMX || TARGET_MMX_WITH_SSE"
865  "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
866
867(define_insn "*mmx_pmaddwd"
868  [(set (match_operand:V2SI 0 "register_operand" "=y,x,Yv")
869        (plus:V2SI
870	  (mult:V2SI
871	    (sign_extend:V2SI
872	      (vec_select:V2HI
873		(match_operand:V4HI 1 "register_mmxmem_operand" "%0,0,Yv")
874		(parallel [(const_int 0) (const_int 2)])))
875	    (sign_extend:V2SI
876	      (vec_select:V2HI
877		(match_operand:V4HI 2 "register_mmxmem_operand" "ym,x,Yv")
878		(parallel [(const_int 0) (const_int 2)]))))
879	  (mult:V2SI
880	    (sign_extend:V2SI
881	      (vec_select:V2HI (match_dup 1)
882		(parallel [(const_int 1) (const_int 3)])))
883	    (sign_extend:V2SI
884	      (vec_select:V2HI (match_dup 2)
885		(parallel [(const_int 1) (const_int 3)]))))))]
886  "(TARGET_MMX || TARGET_MMX_WITH_SSE)
887   && ix86_binary_operator_ok (MULT, V4HImode, operands)"
888  "@
889   pmaddwd\t{%2, %0|%0, %2}
890   pmaddwd\t{%2, %0|%0, %2}
891   vpmaddwd\t{%2, %1, %0|%0, %1, %2}"
892  [(set_attr "isa" "*,sse2_noavx,avx")
893   (set_attr "mmx_isa" "native,*,*")
894   (set_attr "type" "mmxmul,sseiadd,sseiadd")
895   (set_attr "mode" "DI,TI,TI")])
896
897(define_expand "mmx_pmulhrwv4hi3"
898  [(set (match_operand:V4HI 0 "register_operand")
899	(truncate:V4HI
900	  (lshiftrt:V4SI
901	    (plus:V4SI
902	      (mult:V4SI
903	        (sign_extend:V4SI
904		  (match_operand:V4HI 1 "nonimmediate_operand"))
905	        (sign_extend:V4SI
906		  (match_operand:V4HI 2 "nonimmediate_operand")))
907	      (const_vector:V4SI [(const_int 32768) (const_int 32768)
908				  (const_int 32768) (const_int 32768)]))
909	    (const_int 16))))]
910  "TARGET_3DNOW"
911  "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
912
913(define_insn "*mmx_pmulhrwv4hi3"
914  [(set (match_operand:V4HI 0 "register_operand" "=y")
915	(truncate:V4HI
916	  (lshiftrt:V4SI
917	    (plus:V4SI
918	      (mult:V4SI
919	        (sign_extend:V4SI
920		  (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
921	        (sign_extend:V4SI
922		  (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
923	      (const_vector:V4SI [(const_int 32768) (const_int 32768)
924				  (const_int 32768) (const_int 32768)]))
925	    (const_int 16))))]
926  "TARGET_3DNOW && ix86_binary_operator_ok (MULT, V4HImode, operands)"
927  "pmulhrw\t{%2, %0|%0, %2}"
928  [(set_attr "type" "mmxmul")
929   (set_attr "prefix_extra" "1")
930   (set_attr "mode" "DI")])
931
932(define_expand "sse2_umulv1siv1di3"
933  [(set (match_operand:V1DI 0 "register_operand")
934        (mult:V1DI
935	  (zero_extend:V1DI
936	    (vec_select:V1SI
937	      (match_operand:V2SI 1 "register_mmxmem_operand")
938	      (parallel [(const_int 0)])))
939	  (zero_extend:V1DI
940	    (vec_select:V1SI
941	      (match_operand:V2SI 2 "register_mmxmem_operand")
942	      (parallel [(const_int 0)])))))]
943  "(TARGET_MMX || TARGET_MMX_WITH_SSE) && TARGET_SSE2"
944  "ix86_fixup_binary_operands_no_copy (MULT, V2SImode, operands);")
945
946(define_insn "*sse2_umulv1siv1di3"
947  [(set (match_operand:V1DI 0 "register_operand" "=y,x,Yv")
948        (mult:V1DI
949	  (zero_extend:V1DI
950	    (vec_select:V1SI
951	      (match_operand:V2SI 1 "register_mmxmem_operand" "%0,0,Yv")
952	      (parallel [(const_int 0)])))
953	  (zero_extend:V1DI
954	    (vec_select:V1SI
955	      (match_operand:V2SI 2 "register_mmxmem_operand" "ym,x,Yv")
956	      (parallel [(const_int 0)])))))]
957  "(TARGET_MMX || TARGET_MMX_WITH_SSE)
958   && TARGET_SSE2
959   && ix86_binary_operator_ok (MULT, V2SImode, operands)"
960  "@
961   pmuludq\t{%2, %0|%0, %2}
962   pmuludq\t{%2, %0|%0, %2}
963   vpmuludq\t{%2, %1, %0|%0, %1, %2}"
964  [(set_attr "isa" "*,sse2_noavx,avx")
965   (set_attr "mmx_isa" "native,*,*")
966   (set_attr "type" "mmxmul,ssemul,ssemul")
967   (set_attr "mode" "DI,TI,TI")])
968
969(define_expand "mmx_<code>v4hi3"
970  [(set (match_operand:V4HI 0 "register_operand")
971        (smaxmin:V4HI
972	  (match_operand:V4HI 1 "register_mmxmem_operand")
973	  (match_operand:V4HI 2 "register_mmxmem_operand")))]
974  "(TARGET_MMX || TARGET_MMX_WITH_SSE)
975   && (TARGET_SSE || TARGET_3DNOW_A)"
976  "ix86_fixup_binary_operands_no_copy (<CODE>, V4HImode, operands);")
977
978(define_expand "<code>v4hi3"
979  [(set (match_operand:V4HI 0 "register_operand")
980        (smaxmin:V4HI
981	  (match_operand:V4HI 1 "register_operand")
982	  (match_operand:V4HI 2 "register_operand")))]
983  "TARGET_MMX_WITH_SSE"
984  "ix86_fixup_binary_operands_no_copy (<CODE>, V4HImode, operands);")
985
986(define_insn "*mmx_<code>v4hi3"
987  [(set (match_operand:V4HI 0 "register_operand" "=y,x,Yv")
988        (smaxmin:V4HI
989	  (match_operand:V4HI 1 "register_mmxmem_operand" "%0,0,Yv")
990	  (match_operand:V4HI 2 "register_mmxmem_operand" "ym,x,Yv")))]
991  "(TARGET_MMX || TARGET_MMX_WITH_SSE)
992   && (TARGET_SSE || TARGET_3DNOW_A)
993   && ix86_binary_operator_ok (<CODE>, V4HImode, operands)"
994  "@
995   p<maxmin_int>w\t{%2, %0|%0, %2}
996   p<maxmin_int>w\t{%2, %0|%0, %2}
997   vp<maxmin_int>w\t{%2, %1, %0|%0, %1, %2}"
998  [(set_attr "isa" "*,sse2_noavx,avx")
999   (set_attr "mmx_isa" "native,*,*")
1000   (set_attr "type" "mmxadd,sseiadd,sseiadd")
1001   (set_attr "mode" "DI,TI,TI")])
1002
1003(define_expand "mmx_<code>v8qi3"
1004  [(set (match_operand:V8QI 0 "register_operand")
1005        (umaxmin:V8QI
1006	  (match_operand:V8QI 1 "register_mmxmem_operand")
1007	  (match_operand:V8QI 2 "register_mmxmem_operand")))]
1008  "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1009   && (TARGET_SSE || TARGET_3DNOW_A)"
1010  "ix86_fixup_binary_operands_no_copy (<CODE>, V8QImode, operands);")
1011
1012(define_expand "<code>v8qi3"
1013  [(set (match_operand:V8QI 0 "register_operand")
1014        (umaxmin:V8QI
1015	  (match_operand:V8QI 1 "register_operand")
1016	  (match_operand:V8QI 2 "register_operand")))]
1017  "TARGET_MMX_WITH_SSE"
1018  "ix86_fixup_binary_operands_no_copy (<CODE>, V8QImode, operands);")
1019
1020(define_insn "*mmx_<code>v8qi3"
1021  [(set (match_operand:V8QI 0 "register_operand" "=y,x,Yv")
1022        (umaxmin:V8QI
1023	  (match_operand:V8QI 1 "register_mmxmem_operand" "%0,0,Yv")
1024	  (match_operand:V8QI 2 "register_mmxmem_operand" "ym,x,Yv")))]
1025  "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1026   && (TARGET_SSE || TARGET_3DNOW_A)
1027   && ix86_binary_operator_ok (<CODE>, V8QImode, operands)"
1028  "@
1029   p<maxmin_int>b\t{%2, %0|%0, %2}
1030   p<maxmin_int>b\t{%2, %0|%0, %2}
1031   vp<maxmin_int>b\t{%2, %1, %0|%0, %1, %2}"
1032  [(set_attr "isa" "*,sse2_noavx,avx")
1033   (set_attr "mmx_isa" "native,*,*")
1034   (set_attr "type" "mmxadd,sseiadd,sseiadd")
1035   (set_attr "mode" "DI,TI,TI")])
1036
1037(define_insn "mmx_ashr<mode>3"
1038  [(set (match_operand:MMXMODE24 0 "register_operand" "=y,x,Yv")
1039        (ashiftrt:MMXMODE24
1040	  (match_operand:MMXMODE24 1 "register_operand" "0,0,Yv")
1041	  (match_operand:DI 2 "nonmemory_operand" "yN,xN,YvN")))]
1042  "TARGET_MMX || TARGET_MMX_WITH_SSE"
1043  "@
1044   psra<mmxvecsize>\t{%2, %0|%0, %2}
1045   psra<mmxvecsize>\t{%2, %0|%0, %2}
1046   vpsra<mmxvecsize>\t{%2, %1, %0|%0, %1, %2}"
1047  [(set_attr "isa" "*,sse2_noavx,avx")
1048   (set_attr "mmx_isa" "native,*,*")
1049   (set_attr "type" "mmxshft,sseishft,sseishft")
1050   (set (attr "length_immediate")
1051     (if_then_else (match_operand 2 "const_int_operand")
1052       (const_string "1")
1053       (const_string "0")))
1054   (set_attr "mode" "DI,TI,TI")])
1055
1056(define_expand "ashr<mode>3"
1057  [(set (match_operand:MMXMODE24 0 "register_operand")
1058        (ashiftrt:MMXMODE24
1059	  (match_operand:MMXMODE24 1 "register_operand")
1060	  (match_operand:DI 2 "nonmemory_operand")))]
1061  "TARGET_MMX_WITH_SSE")
1062
1063(define_insn "mmx_<shift_insn><mode>3"
1064  [(set (match_operand:MMXMODE248 0 "register_operand" "=y,x,Yv")
1065        (any_lshift:MMXMODE248
1066	  (match_operand:MMXMODE248 1 "register_operand" "0,0,Yv")
1067	  (match_operand:DI 2 "nonmemory_operand" "yN,xN,YvN")))]
1068  "TARGET_MMX || TARGET_MMX_WITH_SSE"
1069  "@
1070   p<vshift><mmxvecsize>\t{%2, %0|%0, %2}
1071   p<vshift><mmxvecsize>\t{%2, %0|%0, %2}
1072   vp<vshift><mmxvecsize>\t{%2, %1, %0|%0, %1, %2}"
1073  [(set_attr "isa" "*,sse2_noavx,avx")
1074   (set_attr "mmx_isa" "native,*,*")
1075   (set_attr "type" "mmxshft,sseishft,sseishft")
1076   (set (attr "length_immediate")
1077     (if_then_else (match_operand 2 "const_int_operand")
1078       (const_string "1")
1079       (const_string "0")))
1080   (set_attr "mode" "DI,TI,TI")])
1081
1082(define_expand "<shift_insn><mode>3"
1083  [(set (match_operand:MMXMODE24 0 "register_operand")
1084        (any_lshift:MMXMODE24
1085	  (match_operand:MMXMODE24 1 "register_operand")
1086	  (match_operand:DI 2 "nonmemory_operand")))]
1087  "TARGET_MMX_WITH_SSE")
1088
1089;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1090;;
1091;; Parallel integral comparisons
1092;;
1093;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1094
1095(define_expand "mmx_eq<mode>3"
1096  [(set (match_operand:MMXMODEI 0 "register_operand")
1097        (eq:MMXMODEI
1098	  (match_operand:MMXMODEI 1 "register_mmxmem_operand")
1099	  (match_operand:MMXMODEI 2 "register_mmxmem_operand")))]
1100  "TARGET_MMX || TARGET_MMX_WITH_SSE"
1101  "ix86_fixup_binary_operands_no_copy (EQ, <MODE>mode, operands);")
1102
1103(define_insn "*mmx_eq<mode>3"
1104  [(set (match_operand:MMXMODEI 0 "register_operand" "=y,x,Yv")
1105        (eq:MMXMODEI
1106	  (match_operand:MMXMODEI 1 "register_mmxmem_operand" "%0,0,Yv")
1107	  (match_operand:MMXMODEI 2 "register_mmxmem_operand" "ym,x,Yv")))]
1108  "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1109   && ix86_binary_operator_ok (EQ, <MODE>mode, operands)"
1110  "@
1111   pcmpeq<mmxvecsize>\t{%2, %0|%0, %2}
1112   pcmpeq<mmxvecsize>\t{%2, %0|%0, %2}
1113   vpcmpeq<mmxvecsize>\t{%2, %1, %0|%0, %1, %2}"
1114  [(set_attr "isa" "*,sse2_noavx,avx")
1115   (set_attr "mmx_isa" "native,*,*")
1116   (set_attr "type" "mmxcmp,ssecmp,ssecmp")
1117   (set_attr "mode" "DI,TI,TI")])
1118
1119(define_insn "mmx_gt<mode>3"
1120  [(set (match_operand:MMXMODEI 0 "register_operand" "=y,x,Yv")
1121        (gt:MMXMODEI
1122	  (match_operand:MMXMODEI 1 "register_operand" "0,0,Yv")
1123	  (match_operand:MMXMODEI 2 "register_mmxmem_operand" "ym,x,Yv")))]
1124  "TARGET_MMX || TARGET_MMX_WITH_SSE"
1125  "@
1126   pcmpgt<mmxvecsize>\t{%2, %0|%0, %2}
1127   pcmpgt<mmxvecsize>\t{%2, %0|%0, %2}
1128   vpcmpgt<mmxvecsize>\t{%2, %1, %0|%0, %1, %2}"
1129  [(set_attr "isa" "*,sse2_noavx,avx")
1130   (set_attr "mmx_isa" "native,*,*")
1131   (set_attr "type" "mmxcmp,ssecmp,ssecmp")
1132   (set_attr "mode" "DI,TI,TI")])
1133
1134;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1135;;
1136;; Parallel integral logical operations
1137;;
1138;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1139
1140(define_expand "one_cmpl<mode>2"
1141  [(set (match_operand:MMXMODEI 0 "register_operand")
1142	(xor:MMXMODEI
1143	  (match_operand:MMXMODEI 1 "register_operand")
1144	  (match_dup 2)))]
1145  "TARGET_MMX_WITH_SSE"
1146  "operands[2] = force_reg (<MODE>mode, CONSTM1_RTX (<MODE>mode));")
1147
1148(define_insn "mmx_andnot<mode>3"
1149  [(set (match_operand:MMXMODEI 0 "register_operand" "=y,x,Yv")
1150	(and:MMXMODEI
1151	  (not:MMXMODEI (match_operand:MMXMODEI 1 "register_operand" "0,0,Yv"))
1152	  (match_operand:MMXMODEI 2 "register_mmxmem_operand" "ym,x,Yv")))]
1153  "TARGET_MMX || TARGET_MMX_WITH_SSE"
1154  "@
1155   pandn\t{%2, %0|%0, %2}
1156   pandn\t{%2, %0|%0, %2}
1157   vpandn\t{%2, %1, %0|%0, %1, %2}"
1158  [(set_attr "isa" "*,sse2_noavx,avx")
1159   (set_attr "mmx_isa" "native,*,*")
1160   (set_attr "type" "mmxadd,sselog,sselog")
1161   (set_attr "mode" "DI,TI,TI")])
1162
1163(define_expand "mmx_<code><mode>3"
1164  [(set (match_operand:MMXMODEI 0 "register_operand")
1165	(any_logic:MMXMODEI
1166	  (match_operand:MMXMODEI 1 "register_mmxmem_operand")
1167	  (match_operand:MMXMODEI 2 "register_mmxmem_operand")))]
1168  "TARGET_MMX || TARGET_MMX_WITH_SSE"
1169  "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
1170
1171(define_expand "<code><mode>3"
1172  [(set (match_operand:MMXMODEI 0 "register_operand")
1173	(any_logic:MMXMODEI
1174	  (match_operand:MMXMODEI 1 "register_operand")
1175	  (match_operand:MMXMODEI 2 "register_operand")))]
1176  "TARGET_MMX_WITH_SSE"
1177  "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
1178
1179(define_insn "*mmx_<code><mode>3"
1180  [(set (match_operand:MMXMODEI 0 "register_operand" "=y,x,Yv")
1181        (any_logic:MMXMODEI
1182	  (match_operand:MMXMODEI 1 "register_mmxmem_operand" "%0,0,Yv")
1183	  (match_operand:MMXMODEI 2 "register_mmxmem_operand" "ym,x,Yv")))]
1184  "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1185   && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
1186  "@
1187   p<logic>\t{%2, %0|%0, %2}
1188   p<logic>\t{%2, %0|%0, %2}
1189   vp<logic>\t{%2, %1, %0|%0, %1, %2}"
1190  [(set_attr "isa" "*,sse2_noavx,avx")
1191   (set_attr "mmx_isa" "native,*,*")
1192   (set_attr "type" "mmxadd,sselog,sselog")
1193   (set_attr "mode" "DI,TI,TI")])
1194
1195;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1196;;
1197;; Parallel integral element swizzling
1198;;
1199;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1200
1201;; Used in signed and unsigned truncations with saturation.
1202(define_code_iterator any_s_truncate [ss_truncate us_truncate])
1203;; Instruction suffix for truncations with saturation.
1204(define_code_attr s_trunsuffix [(ss_truncate "s") (us_truncate "u")])
1205
1206(define_insn_and_split "mmx_pack<s_trunsuffix>swb"
1207  [(set (match_operand:V8QI 0 "register_operand" "=y,x,Yv")
1208	(vec_concat:V8QI
1209	  (any_s_truncate:V4QI
1210	    (match_operand:V4HI 1 "register_operand" "0,0,Yv"))
1211	  (any_s_truncate:V4QI
1212	    (match_operand:V4HI 2 "register_mmxmem_operand" "ym,x,Yv"))))]
1213  "TARGET_MMX || TARGET_MMX_WITH_SSE"
1214  "@
1215   pack<s_trunsuffix>swb\t{%2, %0|%0, %2}
1216   #
1217   #"
1218  "TARGET_SSE2 && reload_completed
1219   && SSE_REGNO_P (REGNO (operands[0]))"
1220  [(const_int 0)]
1221  "ix86_split_mmx_pack (operands, <any_s_truncate:CODE>); DONE;"
1222  [(set_attr "mmx_isa" "native,sse_noavx,avx")
1223   (set_attr "type" "mmxshft,sselog,sselog")
1224   (set_attr "mode" "DI,TI,TI")])
1225
1226(define_insn_and_split "mmx_packssdw"
1227  [(set (match_operand:V4HI 0 "register_operand" "=y,x,Yv")
1228	(vec_concat:V4HI
1229	  (ss_truncate:V2HI
1230	    (match_operand:V2SI 1 "register_operand" "0,0,Yv"))
1231	  (ss_truncate:V2HI
1232	    (match_operand:V2SI 2 "register_mmxmem_operand" "ym,x,Yv"))))]
1233  "TARGET_MMX || TARGET_MMX_WITH_SSE"
1234  "@
1235   packssdw\t{%2, %0|%0, %2}
1236   #
1237   #"
1238  "TARGET_SSE2 && reload_completed
1239   && SSE_REGNO_P (REGNO (operands[0]))"
1240  [(const_int 0)]
1241  "ix86_split_mmx_pack (operands, SS_TRUNCATE); DONE;"
1242  [(set_attr "mmx_isa" "native,sse_noavx,avx")
1243   (set_attr "type" "mmxshft,sselog,sselog")
1244   (set_attr "mode" "DI,TI,TI")])
1245
1246(define_insn_and_split "mmx_punpckhbw"
1247  [(set (match_operand:V8QI 0 "register_operand" "=y,x,Yv")
1248	(vec_select:V8QI
1249	  (vec_concat:V16QI
1250	    (match_operand:V8QI 1 "register_operand" "0,0,Yv")
1251	    (match_operand:V8QI 2 "register_mmxmem_operand" "ym,x,Yv"))
1252          (parallel [(const_int 4) (const_int 12)
1253                     (const_int 5) (const_int 13)
1254                     (const_int 6) (const_int 14)
1255                     (const_int 7) (const_int 15)])))]
1256  "TARGET_MMX || TARGET_MMX_WITH_SSE"
1257  "@
1258   punpckhbw\t{%2, %0|%0, %2}
1259   #
1260   #"
1261  "TARGET_SSE2 && reload_completed
1262   && SSE_REGNO_P (REGNO (operands[0]))"
1263  [(const_int 0)]
1264  "ix86_split_mmx_punpck (operands, true); DONE;"
1265  [(set_attr "mmx_isa" "native,sse_noavx,avx")
1266   (set_attr "type" "mmxcvt,sselog,sselog")
1267   (set_attr "mode" "DI,TI,TI")])
1268
1269(define_insn_and_split "mmx_punpcklbw"
1270  [(set (match_operand:V8QI 0 "register_operand" "=y,x,Yv")
1271	(vec_select:V8QI
1272	  (vec_concat:V16QI
1273	    (match_operand:V8QI 1 "register_operand" "0,0,Yv")
1274	    (match_operand:V8QI 2 "register_mmxmem_operand" "ym,x,Yv"))
1275          (parallel [(const_int 0) (const_int 8)
1276                     (const_int 1) (const_int 9)
1277                     (const_int 2) (const_int 10)
1278                     (const_int 3) (const_int 11)])))]
1279  "TARGET_MMX || TARGET_MMX_WITH_SSE"
1280  "@
1281   punpcklbw\t{%2, %0|%0, %k2}
1282   #
1283   #"
1284  "TARGET_SSE2 && reload_completed
1285   && SSE_REGNO_P (REGNO (operands[0]))"
1286  [(const_int 0)]
1287  "ix86_split_mmx_punpck (operands, false); DONE;"
1288  [(set_attr "mmx_isa" "native,sse_noavx,avx")
1289   (set_attr "type" "mmxcvt,sselog,sselog")
1290   (set_attr "mode" "DI,TI,TI")])
1291
1292(define_insn_and_split "mmx_punpckhwd"
1293  [(set (match_operand:V4HI 0 "register_operand" "=y,x,Yv")
1294	(vec_select:V4HI
1295	  (vec_concat:V8HI
1296	    (match_operand:V4HI 1 "register_operand" "0,0,Yv")
1297	    (match_operand:V4HI 2 "register_mmxmem_operand" "ym,x,Yv"))
1298          (parallel [(const_int 2) (const_int 6)
1299                     (const_int 3) (const_int 7)])))]
1300  "TARGET_MMX || TARGET_MMX_WITH_SSE"
1301  "@
1302   punpckhwd\t{%2, %0|%0, %2}
1303   #
1304   #"
1305  "TARGET_SSE2 && reload_completed
1306   && SSE_REGNO_P (REGNO (operands[0]))"
1307  [(const_int 0)]
1308  "ix86_split_mmx_punpck (operands, true); DONE;"
1309  [(set_attr "mmx_isa" "native,sse_noavx,avx")
1310   (set_attr "type" "mmxcvt,sselog,sselog")
1311   (set_attr "mode" "DI,TI,TI")])
1312
1313(define_insn_and_split "mmx_punpcklwd"
1314  [(set (match_operand:V4HI 0 "register_operand" "=y,x,Yv")
1315	(vec_select:V4HI
1316	  (vec_concat:V8HI
1317	    (match_operand:V4HI 1 "register_operand" "0,0,Yv")
1318	    (match_operand:V4HI 2 "register_mmxmem_operand" "ym,x,Yv"))
1319          (parallel [(const_int 0) (const_int 4)
1320                     (const_int 1) (const_int 5)])))]
1321  "TARGET_MMX || TARGET_MMX_WITH_SSE"
1322  "@
1323   punpcklwd\t{%2, %0|%0, %k2}
1324   #
1325   #"
1326  "TARGET_SSE2 && reload_completed
1327   && SSE_REGNO_P (REGNO (operands[0]))"
1328  [(const_int 0)]
1329  "ix86_split_mmx_punpck (operands, false); DONE;"
1330  [(set_attr "mmx_isa" "native,sse_noavx,avx")
1331   (set_attr "type" "mmxcvt,sselog,sselog")
1332   (set_attr "mode" "DI,TI,TI")])
1333
1334(define_insn_and_split "mmx_punpckhdq"
1335  [(set (match_operand:V2SI 0 "register_operand" "=y,x,Yv")
1336	(vec_select:V2SI
1337	  (vec_concat:V4SI
1338	    (match_operand:V2SI 1 "register_operand" "0,0,Yv")
1339	    (match_operand:V2SI 2 "register_mmxmem_operand" "ym,x,Yv"))
1340	  (parallel [(const_int 1)
1341		     (const_int 3)])))]
1342  "TARGET_MMX || TARGET_MMX_WITH_SSE"
1343  "@
1344   punpckhdq\t{%2, %0|%0, %2}
1345   #
1346   #"
1347  "TARGET_SSE2 && reload_completed
1348   && SSE_REGNO_P (REGNO (operands[0]))"
1349  [(const_int 0)]
1350  "ix86_split_mmx_punpck (operands, true); DONE;"
1351  [(set_attr "mmx_isa" "native,sse_noavx,avx")
1352   (set_attr "type" "mmxcvt,sselog,sselog")
1353   (set_attr "mode" "DI,TI,TI")])
1354
1355(define_insn_and_split "mmx_punpckldq"
1356  [(set (match_operand:V2SI 0 "register_operand" "=y,x,Yv")
1357	(vec_select:V2SI
1358	  (vec_concat:V4SI
1359	    (match_operand:V2SI 1 "register_operand" "0,0,Yv")
1360	    (match_operand:V2SI 2 "register_mmxmem_operand" "ym,x,Yv"))
1361	  (parallel [(const_int 0)
1362		     (const_int 2)])))]
1363  "TARGET_MMX || TARGET_MMX_WITH_SSE"
1364  "@
1365   punpckldq\t{%2, %0|%0, %k2}
1366   #
1367   #"
1368  "TARGET_SSE2 && reload_completed
1369   && SSE_REGNO_P (REGNO (operands[0]))"
1370  [(const_int 0)]
1371  "ix86_split_mmx_punpck (operands, false); DONE;"
1372  [(set_attr "mmx_isa" "native,sse_noavx,avx")
1373   (set_attr "type" "mmxcvt,sselog,sselog")
1374   (set_attr "mode" "DI,TI,TI")])
1375
1376(define_insn "*mmx_pinsrd"
1377  [(set (match_operand:V2SI 0 "register_operand" "=x,Yv")
1378        (vec_merge:V2SI
1379          (vec_duplicate:V2SI
1380            (match_operand:SI 2 "nonimmediate_operand" "rm,rm"))
1381	  (match_operand:V2SI 1 "register_operand" "0,Yv")
1382          (match_operand:SI 3 "const_int_operand")))]
1383  "TARGET_MMX_WITH_SSE && TARGET_SSE4_1
1384   && ((unsigned) exact_log2 (INTVAL (operands[3]))
1385       < GET_MODE_NUNITS (V2SImode))"
1386{
1387  operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])));
1388  switch (which_alternative)
1389    {
1390    case 1:
1391      return "vpinsrd\t{%3, %2, %1, %0|%0, %1, %2, %3}";
1392    case 0:
1393      return "pinsrd\t{%3, %2, %0|%0, %2, %3}";
1394    default:
1395      gcc_unreachable ();
1396    }
1397}
1398  [(set_attr "isa" "noavx,avx")
1399   (set_attr "prefix_data16" "1")
1400   (set_attr "prefix_extra" "1")
1401   (set_attr "type" "sselog")
1402   (set_attr "length_immediate" "1")
1403   (set_attr "prefix" "orig,vex")
1404   (set_attr "mode" "TI")])
1405
1406(define_expand "mmx_pinsrw"
1407  [(set (match_operand:V4HI 0 "register_operand")
1408        (vec_merge:V4HI
1409          (vec_duplicate:V4HI
1410            (match_operand:SI 2 "nonimmediate_operand"))
1411	  (match_operand:V4HI 1 "register_operand")
1412          (match_operand:SI 3 "const_0_to_3_operand")))]
1413  "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1414   && (TARGET_SSE || TARGET_3DNOW_A)"
1415{
1416  operands[2] = gen_lowpart (HImode, operands[2]);
1417  operands[3] = GEN_INT (1 << INTVAL (operands[3]));
1418})
1419
1420(define_insn "*mmx_pinsrw"
1421  [(set (match_operand:V4HI 0 "register_operand" "=y,x,Yv")
1422        (vec_merge:V4HI
1423          (vec_duplicate:V4HI
1424            (match_operand:HI 2 "nonimmediate_operand" "rm,rm,rm"))
1425	  (match_operand:V4HI 1 "register_operand" "0,0,Yv")
1426          (match_operand:SI 3 "const_int_operand")))]
1427  "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1428   && (TARGET_SSE || TARGET_3DNOW_A)
1429   && ((unsigned) exact_log2 (INTVAL (operands[3]))
1430       < GET_MODE_NUNITS (V4HImode))"
1431{
1432  operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])));
1433  switch (which_alternative)
1434    {
1435    case 2:
1436      if (MEM_P (operands[2]))
1437	return "vpinsrw\t{%3, %2, %1, %0|%0, %1, %2, %3}";
1438      else
1439	return "vpinsrw\t{%3, %k2, %1, %0|%0, %1, %k2, %3}";
1440    case 1:
1441    case 0:
1442      if (MEM_P (operands[2]))
1443	return "pinsrw\t{%3, %2, %0|%0, %2, %3}";
1444      else
1445	return "pinsrw\t{%3, %k2, %0|%0, %k2, %3}";
1446    default:
1447      gcc_unreachable ();
1448    }
1449}
1450  [(set_attr "isa" "*,sse2_noavx,avx")
1451   (set_attr "mmx_isa" "native,*,*")
1452   (set_attr "type" "mmxcvt,sselog,sselog")
1453   (set_attr "length_immediate" "1")
1454   (set_attr "mode" "DI,TI,TI")])
1455
1456(define_insn "*mmx_pinsrb"
1457  [(set (match_operand:V8QI 0 "register_operand" "=x,Yv")
1458        (vec_merge:V8QI
1459          (vec_duplicate:V8QI
1460            (match_operand:QI 2 "nonimmediate_operand" "rm,rm"))
1461	  (match_operand:V8QI 1 "register_operand" "0,Yv")
1462          (match_operand:SI 3 "const_int_operand")))]
1463  "TARGET_MMX_WITH_SSE && TARGET_SSE4_1
1464   && ((unsigned) exact_log2 (INTVAL (operands[3]))
1465       < GET_MODE_NUNITS (V8QImode))"
1466{
1467  operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])));
1468  switch (which_alternative)
1469    {
1470    case 1:
1471      if (MEM_P (operands[2]))
1472	return "vpinsrb\t{%3, %2, %1, %0|%0, %1, %2, %3}";
1473      else
1474	return "vpinsrb\t{%3, %k2, %1, %0|%0, %1, %k2, %3}";
1475    case 0:
1476      if (MEM_P (operands[2]))
1477	return "pinsrb\t{%3, %2, %0|%0, %2, %3}";
1478      else
1479	return "pinsrb\t{%3, %k2, %0|%0, %k2, %3}";
1480    default:
1481      gcc_unreachable ();
1482    }
1483}
1484  [(set_attr "isa" "noavx,avx")
1485   (set_attr "type" "sselog")
1486   (set_attr "prefix_data16" "1")
1487   (set_attr "prefix_extra" "1")
1488   (set_attr "length_immediate" "1")
1489   (set_attr "prefix" "orig,vex")
1490   (set_attr "mode" "TI")])
1491
1492(define_insn "*mmx_pextrw"
1493  [(set (match_operand:HI 0 "register_sse4nonimm_operand" "=r,r,m")
1494	(vec_select:HI
1495	  (match_operand:V4HI 1 "register_operand" "y,Yv,Yv")
1496	  (parallel [(match_operand:SI 2 "const_0_to_3_operand" "n,n,n")])))]
1497  "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1498   && (TARGET_SSE || TARGET_3DNOW_A)"
1499  "@
1500   pextrw\t{%2, %1, %k0|%k0, %1, %2}
1501   %vpextrw\t{%2, %1, %k0|%k0, %1, %2}
1502   %vpextrw\t{%2, %1, %0|%0, %1, %2}"
1503  [(set_attr "isa" "*,sse2,sse4")
1504   (set_attr "mmx_isa" "native,*,*")
1505   (set_attr "type" "mmxcvt,sselog1,sselog1")
1506   (set_attr "length_immediate" "1")
1507   (set_attr "prefix" "orig,maybe_vex,maybe_vex")
1508   (set_attr "mode" "DI,TI,TI")])
1509
1510(define_insn "*mmx_pextrw_zext"
1511  [(set (match_operand:SWI48 0 "register_operand" "=r,r")
1512	(zero_extend:SWI48
1513	  (vec_select:HI
1514	    (match_operand:V4HI 1 "register_operand" "y,Yv")
1515	    (parallel [(match_operand:SI 2 "const_0_to_3_operand" "n,n")]))))]
1516  "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1517   && (TARGET_SSE || TARGET_3DNOW_A)"
1518  "@
1519   pextrw\t{%2, %1, %k0|%k0, %1, %2}
1520   %vpextrw\t{%2, %1, %k0|%k0, %1, %2}"
1521  [(set_attr "isa" "*,sse2")
1522   (set_attr "mmx_isa" "native,*")
1523   (set_attr "type" "mmxcvt,sselog1")
1524   (set_attr "length_immediate" "1")
1525   (set_attr "prefix" "orig,maybe_vex")
1526   (set_attr "mode" "DI,TI")])
1527
1528(define_insn "*mmx_pextrb"
1529  [(set (match_operand:QI 0 "nonimmediate_operand" "=r,m")
1530	(vec_select:QI
1531	  (match_operand:V8QI 1 "register_operand" "Yv,Yv")
1532	  (parallel [(match_operand:SI 2 "const_0_to_7_operand" "n,n")])))]
1533  "TARGET_MMX_WITH_SSE && TARGET_SSE4_1"
1534  "@
1535   %vpextrb\t{%2, %1, %k0|%k0, %1, %2}
1536   %vpextrb\t{%2, %1, %0|%0, %1, %2}"
1537  [(set_attr "type" "sselog1")
1538   (set_attr "prefix_data16" "1")
1539   (set_attr "prefix_extra" "1")
1540   (set_attr "length_immediate" "1")
1541   (set_attr "prefix" "maybe_vex")
1542   (set_attr "mode" "TI")])
1543
1544(define_insn "*mmx_pextrb_zext"
1545  [(set (match_operand:SWI248 0 "register_operand" "=r")
1546	(zero_extend:SWI248
1547	  (vec_select:QI
1548	    (match_operand:V8QI 1 "register_operand" "Yv")
1549	    (parallel [(match_operand:SI 2 "const_0_to_7_operand" "n")]))))]
1550  "TARGET_MMX_WITH_SSE && TARGET_SSE4_1"
1551  "%vpextrb\t{%2, %1, %k0|%k0, %1, %2}"
1552  [(set_attr "type" "sselog1")
1553   (set_attr "prefix_data16" "1")
1554   (set_attr "prefix_extra" "1")
1555   (set_attr "length_immediate" "1")
1556   (set_attr "prefix" "maybe_vex")
1557   (set_attr "mode" "TI")])
1558
1559(define_expand "mmx_pshufw"
1560  [(match_operand:V4HI 0 "register_operand")
1561   (match_operand:V4HI 1 "register_mmxmem_operand")
1562   (match_operand:SI 2 "const_int_operand")]
1563  "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1564   && (TARGET_SSE || TARGET_3DNOW_A)"
1565{
1566  int mask = INTVAL (operands[2]);
1567  emit_insn (gen_mmx_pshufw_1 (operands[0], operands[1],
1568                               GEN_INT ((mask >> 0) & 3),
1569                               GEN_INT ((mask >> 2) & 3),
1570                               GEN_INT ((mask >> 4) & 3),
1571                               GEN_INT ((mask >> 6) & 3)));
1572  DONE;
1573})
1574
1575(define_insn "mmx_pshufw_1"
1576  [(set (match_operand:V4HI 0 "register_operand" "=y,Yv")
1577        (vec_select:V4HI
1578          (match_operand:V4HI 1 "register_mmxmem_operand" "ym,Yv")
1579          (parallel [(match_operand 2 "const_0_to_3_operand")
1580                     (match_operand 3 "const_0_to_3_operand")
1581                     (match_operand 4 "const_0_to_3_operand")
1582                     (match_operand 5 "const_0_to_3_operand")])))]
1583  "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1584   && (TARGET_SSE || TARGET_3DNOW_A)"
1585{
1586  int mask = 0;
1587  mask |= INTVAL (operands[2]) << 0;
1588  mask |= INTVAL (operands[3]) << 2;
1589  mask |= INTVAL (operands[4]) << 4;
1590  mask |= INTVAL (operands[5]) << 6;
1591  operands[2] = GEN_INT (mask);
1592
1593  switch (which_alternative)
1594    {
1595    case 0:
1596      return "pshufw\t{%2, %1, %0|%0, %1, %2}";
1597    case 1:
1598      return "%vpshuflw\t{%2, %1, %0|%0, %1, %2}";
1599    default:
1600      gcc_unreachable ();
1601    }
1602}
1603  [(set_attr "isa" "*,sse2")
1604   (set_attr "mmx_isa" "native,*")
1605   (set_attr "type" "mmxcvt,sselog")
1606   (set_attr "length_immediate" "1")
1607   (set_attr "mode" "DI,TI")])
1608
1609(define_insn "mmx_pswapdv2si2"
1610  [(set (match_operand:V2SI 0 "register_operand" "=y")
1611	(vec_select:V2SI
1612	  (match_operand:V2SI 1 "nonimmediate_operand" "ym")
1613	  (parallel [(const_int 1) (const_int 0)])))]
1614  "TARGET_3DNOW_A"
1615  "pswapd\t{%1, %0|%0, %1}"
1616  [(set_attr "type" "mmxcvt")
1617   (set_attr "prefix_extra" "1")
1618   (set_attr "mode" "DI")])
1619
1620(define_insn_and_split "*vec_dupv4hi"
1621  [(set (match_operand:V4HI 0 "register_operand" "=y,xYw,Yw")
1622	(vec_duplicate:V4HI
1623	  (truncate:HI
1624	    (match_operand:SI 1 "register_operand" "0,xYw,r"))))]
1625  "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1626   && (TARGET_SSE || TARGET_3DNOW_A)"
1627  "@
1628   pshufw\t{$0, %0, %0|%0, %0, 0}
1629   #
1630   #"
1631  "TARGET_SSE2 && reload_completed
1632   && SSE_REGNO_P (REGNO (operands[0]))"
1633  [(const_int 0)]
1634{
1635  rtx op;
1636  operands[0] = lowpart_subreg (V8HImode, operands[0],
1637				GET_MODE (operands[0]));
1638  if (TARGET_AVX2)
1639    {
1640      operands[1] = lowpart_subreg (HImode, operands[1],
1641				    GET_MODE (operands[1]));
1642      op = gen_rtx_VEC_DUPLICATE (V8HImode, operands[1]);
1643    }
1644  else
1645    {
1646      operands[1] = lowpart_subreg (V8HImode, operands[1],
1647				    GET_MODE (operands[1]));
1648      rtx mask = gen_rtx_PARALLEL (VOIDmode,
1649				   gen_rtvec (8,
1650					      GEN_INT (0),
1651					      GEN_INT (0),
1652					      GEN_INT (0),
1653					      GEN_INT (0),
1654					      GEN_INT (4),
1655					      GEN_INT (5),
1656					      GEN_INT (6),
1657					      GEN_INT (7)));
1658
1659      op = gen_rtx_VEC_SELECT (V8HImode, operands[1], mask);
1660    }
1661  emit_insn (gen_rtx_SET (operands[0], op));
1662  DONE;
1663}
1664  [(set_attr "mmx_isa" "native,sse,avx")
1665   (set_attr "type" "mmxcvt,sselog1,ssemov")
1666   (set_attr "length_immediate" "1,1,0")
1667   (set_attr "mode" "DI,TI,TI")])
1668
1669(define_insn_and_split "*vec_dupv2si"
1670  [(set (match_operand:V2SI 0 "register_operand" "=y,x,Yv,Yw")
1671	(vec_duplicate:V2SI
1672	  (match_operand:SI 1 "register_operand" "0,0,Yv,r")))]
1673  "TARGET_MMX || TARGET_MMX_WITH_SSE"
1674  "@
1675   punpckldq\t%0, %0
1676   #
1677   #
1678   #"
1679  "TARGET_SSE && reload_completed
1680   && SSE_REGNO_P (REGNO (operands[0]))"
1681  [(set (match_dup 0)
1682	(vec_duplicate:V4SI (match_dup 1)))]
1683{
1684  operands[0] = lowpart_subreg (V4SImode, operands[0],
1685				GET_MODE (operands[0]));
1686}
1687  [(set_attr "isa" "*,sse_noavx,avx,avx")
1688   (set_attr "mmx_isa" "native,*,*,*")
1689   (set_attr "type" "mmxcvt,ssemov,ssemov,ssemov")
1690   (set_attr "mode" "DI,TI,TI,TI")])
1691
1692(define_insn "*mmx_concatv2si"
1693  [(set (match_operand:V2SI 0 "register_operand"     "=y,y")
1694	(vec_concat:V2SI
1695	  (match_operand:SI 1 "nonimmediate_operand" " 0,rm")
1696	  (match_operand:SI 2 "nonimm_or_0_operand"  "ym,C")))]
1697  "TARGET_MMX && !TARGET_SSE"
1698  "@
1699   punpckldq\t{%2, %0|%0, %2}
1700   movd\t{%1, %0|%0, %1}"
1701  [(set_attr "type" "mmxcvt,mmxmov")
1702   (set_attr "mode" "DI")])
1703
1704(define_expand "vec_setv2si"
1705  [(match_operand:V2SI 0 "register_operand")
1706   (match_operand:SI 1 "register_operand")
1707   (match_operand 2 "const_int_operand")]
1708  "TARGET_MMX || TARGET_MMX_WITH_SSE"
1709{
1710  ix86_expand_vector_set (TARGET_MMX_WITH_SSE, operands[0], operands[1],
1711			  INTVAL (operands[2]));
1712  DONE;
1713})
1714
1715;; Avoid combining registers from different units in a single alternative,
1716;; see comment above inline_secondary_memory_needed function in i386.c
1717(define_insn_and_split "*vec_extractv2si_0"
1718  [(set (match_operand:SI 0 "nonimmediate_operand"     "=x,m,y, m,r,r")
1719	(vec_select:SI
1720	  (match_operand:V2SI 1 "nonimmediate_operand" "xm,x,ym,y,m,x")
1721	  (parallel [(const_int 0)])))]
1722  "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1723   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1724  "#"
1725  "&& reload_completed"
1726  [(set (match_dup 0) (match_dup 1))]
1727  "operands[1] = gen_lowpart (SImode, operands[1]);"
1728  [(set_attr "isa" "*,*,*,*,*,sse2")
1729   (set_attr "mmx_isa" "*,*,native,native,*,*")
1730   (set (attr "preferred_for_speed")
1731     (cond [(eq_attr "alternative" "5")
1732	      (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
1733	   ]
1734	   (symbol_ref "true")))])
1735
1736(define_insn "*vec_extractv2si_0_zext_sse4"
1737  [(set (match_operand:DI 0 "register_operand" "=r,x")
1738	(zero_extend:DI
1739	  (vec_select:SI
1740	    (match_operand:V2SI 1 "register_operand" "x,x")
1741	    (parallel [(const_int 0)]))))]
1742  "(TARGET_MMX || TARGET_MMX_WITH_SSE) && TARGET_SSE4_1"
1743  "#"
1744  [(set_attr "isa" "x64,*")
1745   (set (attr "preferred_for_speed")
1746     (cond [(eq_attr "alternative" "0")
1747	      (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
1748	   ]
1749	   (symbol_ref "true")))])
1750
1751(define_insn "*vec_extractv2si_0_zext"
1752  [(set (match_operand:DI 0 "register_operand" "=r")
1753	(zero_extend:DI
1754	  (vec_select:SI
1755	    (match_operand:V2SI 1 "register_operand" "x")
1756	    (parallel [(const_int 0)]))))]
1757  "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1758   && TARGET_64BIT && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_FROM_VEC"
1759  "#")
1760
1761(define_split
1762  [(set (match_operand:DI 0 "register_operand")
1763	(zero_extend:DI
1764	  (vec_select:SI
1765	    (match_operand:V2SI 1 "register_operand")
1766	    (parallel [(const_int 0)]))))]
1767  "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1768   && TARGET_SSE2 && reload_completed"
1769  [(set (match_dup 0) (zero_extend:DI (match_dup 1)))]
1770  "operands[1] = gen_lowpart (SImode, operands[1]);")
1771
1772;; Avoid combining registers from different units in a single alternative,
1773;; see comment above inline_secondary_memory_needed function in i386.c
1774(define_insn "*vec_extractv2si_1"
1775  [(set (match_operand:SI 0 "nonimmediate_operand"     "=y,rm,x,x,y,x,r")
1776	(vec_select:SI
1777	  (match_operand:V2SI 1 "nonimmediate_operand" " 0,x ,x,0,o,o,o")
1778	  (parallel [(const_int 1)])))]
1779  "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1780   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1781  "@
1782   punpckhdq\t%0, %0
1783   %vpextrd\t{$1, %1, %0|%0, %1, 1}
1784   %vpshufd\t{$0xe5, %1, %0|%0, %1, 0xe5}
1785   shufps\t{$0xe5, %0, %0|%0, %0, 0xe5}
1786   #
1787   #
1788   #"
1789  [(set_attr "isa" "*,sse4,sse2,noavx,*,*,*")
1790   (set_attr "mmx_isa" "native,*,*,*,native,*,*")
1791   (set_attr "type" "mmxcvt,ssemov,sseshuf1,sseshuf1,mmxmov,ssemov,imov")
1792   (set (attr "length_immediate")
1793     (if_then_else (eq_attr "alternative" "1,2,3")
1794		   (const_string "1")
1795		   (const_string "*")))
1796   (set_attr "prefix" "orig,maybe_vex,maybe_vex,orig,orig,orig,orig")
1797   (set_attr "mode" "DI,TI,TI,V4SF,SI,SI,SI")])
1798
1799(define_split
1800  [(set (match_operand:SI 0 "register_operand")
1801	(vec_select:SI
1802	  (match_operand:V2SI 1 "memory_operand")
1803	  (parallel [(const_int 1)])))]
1804  "(TARGET_MMX || TARGET_MMX_WITH_SSE) && reload_completed"
1805  [(set (match_dup 0) (match_dup 1))]
1806  "operands[1] = adjust_address (operands[1], SImode, 4);")
1807
1808(define_insn "*vec_extractv2si_1_zext"
1809  [(set (match_operand:DI 0 "register_operand" "=r")
1810	(zero_extend:DI
1811	  (vec_select:SI
1812	    (match_operand:V2SI 1 "register_operand" "x")
1813	    (parallel [(const_int 1)]))))]
1814  "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1815   && TARGET_64BIT && TARGET_SSE4_1"
1816  "%vpextrd\t{$1, %1, %k0|%k0, %1, 1}"
1817  [(set_attr "type" "sselog1")
1818   (set_attr "prefix_extra" "1")
1819   (set_attr "length_immediate" "1")
1820   (set_attr "prefix" "maybe_vex")
1821   (set_attr "mode" "TI")])
1822
1823(define_insn_and_split "*vec_extractv2si_zext_mem"
1824  [(set (match_operand:DI 0 "register_operand" "=y,x,r")
1825	(zero_extend:DI
1826	  (vec_select:SI
1827	    (match_operand:V2SI 1 "memory_operand" "o,o,o")
1828	    (parallel [(match_operand:SI 2 "const_0_to_1_operand")]))))]
1829  "(TARGET_MMX || TARGET_MMX_WITH_SSE) && TARGET_64BIT"
1830  "#"
1831  "&& reload_completed"
1832  [(set (match_dup 0) (zero_extend:DI (match_dup 1)))]
1833{
1834  operands[1] = adjust_address (operands[1], SImode, INTVAL (operands[2]) * 4);
1835}
1836  [(set_attr "isa" "*,sse2,*")
1837   (set_attr "mmx_isa" "native,*,*")])
1838
1839(define_expand "vec_extractv2sisi"
1840  [(match_operand:SI 0 "register_operand")
1841   (match_operand:V2SI 1 "register_operand")
1842   (match_operand 2 "const_int_operand")]
1843  "TARGET_MMX || TARGET_MMX_WITH_SSE"
1844{
1845  ix86_expand_vector_extract (TARGET_MMX_WITH_SSE, operands[0],
1846			      operands[1], INTVAL (operands[2]));
1847  DONE;
1848})
1849
1850(define_expand "vec_initv2sisi"
1851  [(match_operand:V2SI 0 "register_operand")
1852   (match_operand 1)]
1853  "(TARGET_MMX || TARGET_MMX_WITH_SSE) && TARGET_SSE"
1854{
1855  ix86_expand_vector_init (TARGET_MMX_WITH_SSE, operands[0],
1856			   operands[1]);
1857  DONE;
1858})
1859
1860(define_expand "vec_setv4hi"
1861  [(match_operand:V4HI 0 "register_operand")
1862   (match_operand:HI 1 "register_operand")
1863   (match_operand 2 "const_int_operand")]
1864  "TARGET_MMX || TARGET_MMX_WITH_SSE"
1865{
1866  ix86_expand_vector_set (TARGET_MMX_WITH_SSE, operands[0], operands[1],
1867			  INTVAL (operands[2]));
1868  DONE;
1869})
1870
1871(define_expand "vec_extractv4hihi"
1872  [(match_operand:HI 0 "register_operand")
1873   (match_operand:V4HI 1 "register_operand")
1874   (match_operand 2 "const_int_operand")]
1875  "TARGET_MMX || TARGET_MMX_WITH_SSE"
1876{
1877  ix86_expand_vector_extract (TARGET_MMX_WITH_SSE, operands[0],
1878			      operands[1], INTVAL (operands[2]));
1879  DONE;
1880})
1881
1882(define_expand "vec_initv4hihi"
1883  [(match_operand:V4HI 0 "register_operand")
1884   (match_operand 1)]
1885  "(TARGET_MMX || TARGET_MMX_WITH_SSE) && TARGET_SSE"
1886{
1887  ix86_expand_vector_init (TARGET_MMX_WITH_SSE, operands[0],
1888			   operands[1]);
1889  DONE;
1890})
1891
1892(define_expand "vec_setv8qi"
1893  [(match_operand:V8QI 0 "register_operand")
1894   (match_operand:QI 1 "register_operand")
1895   (match_operand 2 "const_int_operand")]
1896  "TARGET_MMX || TARGET_MMX_WITH_SSE"
1897{
1898  ix86_expand_vector_set (TARGET_MMX_WITH_SSE, operands[0], operands[1],
1899			  INTVAL (operands[2]));
1900  DONE;
1901})
1902
1903(define_expand "vec_extractv8qiqi"
1904  [(match_operand:QI 0 "register_operand")
1905   (match_operand:V8QI 1 "register_operand")
1906   (match_operand 2 "const_int_operand")]
1907  "TARGET_MMX || TARGET_MMX_WITH_SSE"
1908{
1909  ix86_expand_vector_extract (TARGET_MMX_WITH_SSE, operands[0],
1910			      operands[1], INTVAL (operands[2]));
1911  DONE;
1912})
1913
1914(define_expand "vec_initv8qiqi"
1915  [(match_operand:V8QI 0 "register_operand")
1916   (match_operand 1)]
1917  "(TARGET_MMX || TARGET_MMX_WITH_SSE) && TARGET_SSE"
1918{
1919  ix86_expand_vector_init (TARGET_MMX_WITH_SSE, operands[0],
1920			   operands[1]);
1921  DONE;
1922})
1923
1924;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1925;;
1926;; Miscellaneous
1927;;
1928;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1929
1930(define_expand "mmx_uavg<mode>3"
1931  [(set (match_operand:MMXMODE12 0 "register_operand")
1932	(truncate:MMXMODE12
1933	  (lshiftrt:<mmxdoublemode>
1934	    (plus:<mmxdoublemode>
1935	      (plus:<mmxdoublemode>
1936		(zero_extend:<mmxdoublemode>
1937		  (match_operand:MMXMODE12 1 "register_mmxmem_operand"))
1938		(zero_extend:<mmxdoublemode>
1939		  (match_operand:MMXMODE12 2 "register_mmxmem_operand")))
1940	      (match_dup 3))
1941	    (const_int 1))))]
1942  "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1943   && (TARGET_SSE || TARGET_3DNOW)"
1944{
1945  operands[3] = CONST1_RTX(<mmxdoublemode>mode);
1946  ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
1947})
1948
1949(define_insn "*mmx_uavgv8qi3"
1950  [(set (match_operand:V8QI 0 "register_operand" "=y,x,Yv")
1951	(truncate:V8QI
1952	  (lshiftrt:V8HI
1953	    (plus:V8HI
1954	      (plus:V8HI
1955		(zero_extend:V8HI
1956		  (match_operand:V8QI 1 "register_mmxmem_operand" "%0,0,Yv"))
1957		(zero_extend:V8HI
1958		  (match_operand:V8QI 2 "register_mmxmem_operand" "ym,x,Yv")))
1959	      (const_vector:V8HI [(const_int 1) (const_int 1)
1960				  (const_int 1) (const_int 1)
1961				  (const_int 1) (const_int 1)
1962				  (const_int 1) (const_int 1)]))
1963	    (const_int 1))))]
1964  "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1965   && (TARGET_SSE || TARGET_3DNOW)
1966   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
1967{
1968  switch (which_alternative)
1969    {
1970    case 2:
1971      return "vpavgb\t{%2, %1, %0|%0, %1, %2}";
1972    case 1:
1973    case 0:
1974      /* These two instructions have the same operation, but their encoding
1975	 is different.  Prefer the one that is de facto standard.  */
1976      if (TARGET_SSE || TARGET_3DNOW_A)
1977	return "pavgb\t{%2, %0|%0, %2}";
1978      else
1979	return "pavgusb\t{%2, %0|%0, %2}";
1980      default:
1981	gcc_unreachable ();
1982    }
1983}
1984  [(set_attr "isa" "*,sse2_noavx,avx")
1985   (set_attr "mmx_isa" "native,*,*")
1986   (set_attr "type" "mmxshft,sseiadd,sseiadd")
1987   (set (attr "prefix_extra")
1988     (if_then_else
1989       (not (ior (match_test "TARGET_SSE")
1990		 (match_test "TARGET_3DNOW_A")))
1991       (const_string "1")
1992       (const_string "*")))
1993   (set_attr "mode" "DI,TI,TI")])
1994
1995(define_insn "*mmx_uavgv4hi3"
1996  [(set (match_operand:V4HI 0 "register_operand" "=y,x,Yv")
1997	(truncate:V4HI
1998	  (lshiftrt:V4SI
1999	    (plus:V4SI
2000	      (plus:V4SI
2001		(zero_extend:V4SI
2002		  (match_operand:V4HI 1 "register_mmxmem_operand" "%0,0,Yv"))
2003		(zero_extend:V4SI
2004		  (match_operand:V4HI 2 "register_mmxmem_operand" "ym,x,Yv")))
2005	      (const_vector:V4SI [(const_int 1) (const_int 1)
2006				  (const_int 1) (const_int 1)]))
2007	    (const_int 1))))]
2008  "(TARGET_MMX || TARGET_MMX_WITH_SSE)
2009   && (TARGET_SSE || TARGET_3DNOW_A)
2010   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
2011  "@
2012   pavgw\t{%2, %0|%0, %2}
2013   pavgw\t{%2, %0|%0, %2}
2014   vpavgw\t{%2, %1, %0|%0, %1, %2}"
2015  [(set_attr "isa" "*,sse2_noavx,avx")
2016   (set_attr "mmx_isa" "native,*,*")
2017   (set_attr "type" "mmxshft,sseiadd,sseiadd")
2018   (set_attr "mode" "DI,TI,TI")])
2019
2020(define_expand "uavg<mode>3_ceil"
2021  [(set (match_operand:MMXMODE12 0 "register_operand")
2022	(truncate:MMXMODE12
2023	  (lshiftrt:<mmxdoublemode>
2024	    (plus:<mmxdoublemode>
2025	      (plus:<mmxdoublemode>
2026		(zero_extend:<mmxdoublemode>
2027		  (match_operand:MMXMODE12 1 "register_operand"))
2028		(zero_extend:<mmxdoublemode>
2029		  (match_operand:MMXMODE12 2 "register_operand")))
2030	      (match_dup 3))
2031	    (const_int 1))))]
2032  "TARGET_MMX_WITH_SSE"
2033{
2034  operands[3] = CONST1_RTX(<mmxdoublemode>mode);
2035  ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
2036})
2037
2038(define_insn "mmx_psadbw"
2039  [(set (match_operand:V1DI 0 "register_operand" "=y,x,Yv")
2040        (unspec:V1DI [(match_operand:V8QI 1 "register_operand" "0,0,Yv")
2041		      (match_operand:V8QI 2 "register_mmxmem_operand" "ym,x,Yv")]
2042		     UNSPEC_PSADBW))]
2043  "(TARGET_MMX || TARGET_MMX_WITH_SSE)
2044   && (TARGET_SSE || TARGET_3DNOW_A)"
2045  "@
2046   psadbw\t{%2, %0|%0, %2}
2047   psadbw\t{%2, %0|%0, %2}
2048   vpsadbw\t{%2, %1, %0|%0, %1, %2}"
2049  [(set_attr "isa" "*,sse2_noavx,avx")
2050   (set_attr "mmx_isa" "native,*,*")
2051   (set_attr "type" "mmxshft,sseiadd,sseiadd")
2052   (set_attr "mode" "DI,TI,TI")])
2053
2054(define_expand "reduc_plus_scal_v8qi"
2055 [(plus:V8QI
2056    (match_operand:QI 0 "register_operand")
2057    (match_operand:V8QI 1 "register_operand"))]
2058 "TARGET_MMX_WITH_SSE"
2059{
2060  rtx tmp = gen_reg_rtx (V8QImode);
2061  emit_move_insn (tmp, CONST0_RTX (V8QImode));
2062  rtx tmp2 = gen_reg_rtx (V1DImode);
2063  emit_insn (gen_mmx_psadbw (tmp2, operands[1], tmp));
2064  tmp2 = gen_lowpart (V8QImode, tmp2);
2065  emit_insn (gen_vec_extractv8qiqi (operands[0], tmp2, const0_rtx));
2066  DONE;
2067})
2068
2069(define_expand "usadv8qi"
2070  [(match_operand:V2SI 0 "register_operand")
2071   (match_operand:V8QI 1 "register_operand")
2072   (match_operand:V8QI 2 "register_operand")
2073   (match_operand:V2SI 3 "register_operand")]
2074  "TARGET_MMX_WITH_SSE"
2075{
2076  rtx t1 = gen_reg_rtx (V1DImode);
2077  rtx t2 = gen_reg_rtx (V2SImode);
2078  emit_insn (gen_mmx_psadbw (t1, operands[1], operands[2]));
2079  convert_move (t2, t1, 0);
2080  emit_insn (gen_addv2si3 (operands[0], t2, operands[3]));
2081  DONE;
2082})
2083
2084(define_insn_and_split "mmx_pmovmskb"
2085  [(set (match_operand:SI 0 "register_operand" "=r,r")
2086	(unspec:SI [(match_operand:V8QI 1 "register_operand" "y,x")]
2087		   UNSPEC_MOVMSK))]
2088  "(TARGET_MMX || TARGET_MMX_WITH_SSE)
2089   && (TARGET_SSE || TARGET_3DNOW_A)"
2090  "@
2091   pmovmskb\t{%1, %0|%0, %1}
2092   #"
2093  "TARGET_SSE2 && reload_completed
2094   && SSE_REGNO_P (REGNO (operands[1]))"
2095  [(set (match_dup 0)
2096        (unspec:SI [(match_dup 1)] UNSPEC_MOVMSK))
2097   (set (match_dup 0)
2098	(zero_extend:SI (match_dup 2)))]
2099{
2100  /* Generate SSE pmovmskb and zero-extend from QImode to SImode.  */
2101  operands[1] = lowpart_subreg (V16QImode, operands[1],
2102				GET_MODE (operands[1]));
2103  operands[2] = lowpart_subreg (QImode, operands[0],
2104				GET_MODE (operands[0]));
2105}
2106  [(set_attr "mmx_isa" "native,sse")
2107   (set_attr "type" "mmxcvt,ssemov")
2108   (set_attr "mode" "DI,TI")])
2109
2110(define_expand "mmx_maskmovq"
2111  [(set (match_operand:V8QI 0 "memory_operand")
2112	(unspec:V8QI [(match_operand:V8QI 1 "register_operand")
2113		      (match_operand:V8QI 2 "register_operand")
2114		      (match_dup 0)]
2115		     UNSPEC_MASKMOV))]
2116  "TARGET_SSE || TARGET_3DNOW_A")
2117
2118(define_insn "*mmx_maskmovq"
2119  [(set (mem:V8QI (match_operand:P 0 "register_operand" "D"))
2120	(unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
2121		      (match_operand:V8QI 2 "register_operand" "y")
2122		      (mem:V8QI (match_dup 0))]
2123		     UNSPEC_MASKMOV))]
2124  "TARGET_SSE || TARGET_3DNOW_A"
2125  ;; @@@ check ordering of operands in intel/nonintel syntax
2126  "maskmovq\t{%2, %1|%1, %2}"
2127  [(set_attr "type" "mmxcvt")
2128   (set_attr "znver1_decode" "vector")
2129   (set_attr "mode" "DI")])
2130
2131(define_int_iterator EMMS
2132  [(UNSPECV_EMMS "TARGET_MMX")
2133   (UNSPECV_FEMMS "TARGET_3DNOW")])
2134
2135(define_int_attr emms
2136  [(UNSPECV_EMMS "emms")
2137   (UNSPECV_FEMMS "femms")])
2138
2139(define_expand "mmx_<emms>"
2140  [(parallel
2141    [(unspec_volatile [(const_int 0)] EMMS)
2142      (clobber (reg:XF ST0_REG))
2143      (clobber (reg:XF ST1_REG))
2144      (clobber (reg:XF ST2_REG))
2145      (clobber (reg:XF ST3_REG))
2146      (clobber (reg:XF ST4_REG))
2147      (clobber (reg:XF ST5_REG))
2148      (clobber (reg:XF ST6_REG))
2149      (clobber (reg:XF ST7_REG))
2150      (clobber (reg:DI MM0_REG))
2151      (clobber (reg:DI MM1_REG))
2152      (clobber (reg:DI MM2_REG))
2153      (clobber (reg:DI MM3_REG))
2154      (clobber (reg:DI MM4_REG))
2155      (clobber (reg:DI MM5_REG))
2156      (clobber (reg:DI MM6_REG))
2157      (clobber (reg:DI MM7_REG))])]
2158  "TARGET_MMX || TARGET_MMX_WITH_SSE"
2159{
2160   if (!TARGET_MMX)
2161     {
2162       emit_insn (gen_nop ());
2163       DONE;
2164     }
2165})
2166
2167(define_insn "*mmx_<emms>"
2168  [(unspec_volatile [(const_int 0)] EMMS)
2169   (clobber (reg:XF ST0_REG))
2170   (clobber (reg:XF ST1_REG))
2171   (clobber (reg:XF ST2_REG))
2172   (clobber (reg:XF ST3_REG))
2173   (clobber (reg:XF ST4_REG))
2174   (clobber (reg:XF ST5_REG))
2175   (clobber (reg:XF ST6_REG))
2176   (clobber (reg:XF ST7_REG))
2177   (clobber (reg:DI MM0_REG))
2178   (clobber (reg:DI MM1_REG))
2179   (clobber (reg:DI MM2_REG))
2180   (clobber (reg:DI MM3_REG))
2181   (clobber (reg:DI MM4_REG))
2182   (clobber (reg:DI MM5_REG))
2183   (clobber (reg:DI MM6_REG))
2184   (clobber (reg:DI MM7_REG))]
2185  ""
2186  "<emms>"
2187  [(set_attr "type" "mmx")
2188   (set_attr "modrm" "0")
2189   (set_attr "memory" "none")])
2190