can_implement_as_sibling_call_p REG_PARM_STACK_SPACE check
[official-gcc.git] / gcc / config / i386 / mmx.md
blob7c9640d4f9f56bd67903f1e8367448e5b562c8d8
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.
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.
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/>.
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.
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.
32 (define_c_enum "unspec" [
33   UNSPEC_MOVNTQ
34   UNSPEC_PFRCP
35   UNSPEC_PFRCPIT1
36   UNSPEC_PFRCPIT2
37   UNSPEC_PFRSQRT
38   UNSPEC_PFRSQIT1
41 (define_c_enum "unspecv" [
42   UNSPECV_EMMS
43   UNSPECV_FEMMS
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")])
50 ;; All 8-byte vector modes handled by MMX
51 (define_mode_iterator MMXMODE [V8QI V4HI V2SI V1DI V2SF])
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])
58 ;; Mapping from integer vector mode to mnemonic suffix
59 (define_mode_attr mmxvecsize [(V8QI "b") (V4HI "w") (V2SI "d") (V1DI "q")])
61 (define_mode_attr mmxdoublemode
62   [(V8QI "V8HI") (V4HI "V4SI")])
64 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
66 ;; Move patterns
68 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
70 ;; All of these patterns are enabled for MMX as well as 3dNOW.
71 ;; This is essential for maintaining stable calling conventions.
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"
78   ix86_expand_vector_move (<MODE>mode, operands);
79   DONE;
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]))"
90   switch (get_attr_type (insn))
91     {
92     case TYPE_MULTI:
93       return "#";
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}";
101     case TYPE_MMX:
102       return "pxor\t%0, %0";
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}";
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}";
117     case TYPE_SSELOG1:
118       return standard_sse_constant_opcode (insn, operands);
120     case TYPE_SSEMOV:
121       return ix86_output_ssemov (insn, operands);
123     default:
124       gcc_unreachable ();
125     }
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"))
178             (and (eq_attr "alternative" "13")
179                  (ior (and (match_test "<MODE>mode == V2SFmode")
180                            (not (match_test "TARGET_MMX_WITH_SSE")))
181                       (not (match_test "TARGET_SSE2"))))
182               (const_string "V2SF")
184             (and (eq_attr "alternative" "14")
185                  (ior (match_test "<MODE>mode == V2SFmode")
186                       (not (match_test "TARGET_SSE2"))))
187               (const_string "V2SF")
188            ]
189            (const_string "DI")))
190    (set (attr "preferred_for_speed")
191      (cond [(eq_attr "alternative" "9,15")
192               (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
193             (eq_attr "alternative" "10,16")
194               (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
195            ]
196            (symbol_ref "true")))])
198 (define_split
199   [(set (match_operand:MMXMODE 0 "nonimmediate_gr_operand")
200         (match_operand:MMXMODE 1 "nonimmediate_gr_operand"))]
201   "!TARGET_64BIT && reload_completed"
202   [(const_int 0)]
203   "ix86_split_long_move (operands); DONE;")
205 (define_split
206   [(set (match_operand:MMXMODE 0 "nonimmediate_gr_operand")
207         (match_operand:MMXMODE 1 "const0_operand"))]
208   "!TARGET_64BIT && reload_completed"
209   [(const_int 0)]
210   "ix86_split_long_move (operands); DONE;")
212 (define_expand "movmisalign<mode>"
213   [(set (match_operand:MMXMODE 0 "nonimmediate_operand")
214         (match_operand:MMXMODE 1 "nonimmediate_operand"))]
215   "TARGET_MMX || TARGET_MMX_WITH_SSE"
217   ix86_expand_vector_move (<MODE>mode, operands);
218   DONE;
221 (define_insn "sse_movntq"
222   [(set (match_operand:DI 0 "memory_operand" "=m,m")
223         (unspec:DI [(match_operand:DI 1 "register_operand" "y,r")]
224                    UNSPEC_MOVNTQ))]
225   "(TARGET_MMX || TARGET_MMX_WITH_SSE)
226    && (TARGET_SSE || TARGET_3DNOW_A)"
227   "@
228    movntq\t{%1, %0|%0, %1}
229    movnti\t{%1, %0|%0, %1}"
230   [(set_attr "isa" "*,x64")
231    (set_attr "mmx_isa" "native,*")
232    (set_attr "type" "mmxmov,ssemov")
233    (set_attr "mode" "DI")])
235 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
237 ;; Parallel single-precision floating point arithmetic
239 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
241 (define_expand "<code>v2sf2"
242   [(set (match_operand:V2SF 0 "register_operand")
243         (absneg:V2SF
244           (match_operand:V2SF 1 "register_operand")))]
245   "TARGET_MMX_WITH_SSE"
246   "ix86_expand_fp_absneg_operator (<CODE>, V2SFmode, operands); DONE;")
248 (define_insn_and_split "*mmx_<code>v2sf2"
249   [(set (match_operand:V2SF 0 "register_operand" "=x,x,x")
250         (absneg:V2SF
251           (match_operand:V2SF 1 "register_operand" "0,x,x")))
252    (use (match_operand:V2SF 2 "nonimmediate_operand" "x,0,x"))]
253   "TARGET_MMX_WITH_SSE"
254   "#"
255   "&& reload_completed"
256   [(set (match_dup 0)
257         (<absneg_op>:V2SF (match_dup 1) (match_dup 2)))]
259   if (!TARGET_AVX && operands_match_p (operands[0], operands[2]))
260     std::swap (operands[1], operands[2]);
262   [(set_attr "isa" "noavx,noavx,avx")])
264 (define_insn_and_split "*mmx_nabsv2sf2"
265   [(set (match_operand:V2SF 0 "register_operand" "=x,x,x")
266         (neg:V2SF
267           (abs:V2SF
268             (match_operand:V2SF 1 "register_operand" "0,x,x"))))
269    (use (match_operand:V2SF 2 "nonimmediate_operand" "x,0,x"))]
270   "TARGET_MMX_WITH_SSE"
271   "#"
272   "&& reload_completed"
273   [(set (match_dup 0)
274         (ior:V2SF (match_dup 1) (match_dup 2)))]
276   if (!TARGET_AVX && operands_match_p (operands[0], operands[2]))
277     std::swap (operands[1], operands[2]);
279   [(set_attr "isa" "noavx,noavx,avx")])
281 (define_expand "mmx_addv2sf3"
282   [(set (match_operand:V2SF 0 "register_operand")
283         (plus:V2SF
284           (match_operand:V2SF 1 "register_mmxmem_operand")
285           (match_operand:V2SF 2 "register_mmxmem_operand")))]
286   "TARGET_3DNOW"
287   "ix86_fixup_binary_operands_no_copy (PLUS, V2SFmode, operands);")
289 (define_expand "addv2sf3"
290   [(set (match_operand:V2SF 0 "register_operand")
291         (plus:V2SF
292           (match_operand:V2SF 1 "register_operand")
293           (match_operand:V2SF 2 "register_operand")))]
294   "TARGET_MMX_WITH_SSE"
295   "ix86_fixup_binary_operands_no_copy (PLUS, V2SFmode, operands);")
297 (define_insn "*mmx_addv2sf3"
298   [(set (match_operand:V2SF 0 "register_operand" "=y,x,v")
299         (plus:V2SF
300           (match_operand:V2SF 1 "register_mmxmem_operand" "%0,0,v")
301           (match_operand:V2SF 2 "register_mmxmem_operand" "ym,x,v")))]
302   "(TARGET_3DNOW || TARGET_MMX_WITH_SSE)
303    && ix86_binary_operator_ok (PLUS, V2SFmode, operands)"
304   "@
305    pfadd\t{%2, %0|%0, %2}
306    addps\t{%2, %0|%0, %2}
307    vaddps\t{%2, %1, %0|%0, %1, %2}"
308   [(set_attr "isa" "*,sse2_noavx,avx")
309    (set_attr "mmx_isa" "native,*,*")
310    (set_attr "type" "mmxadd,sseadd,sseadd")
311    (set_attr "prefix_extra" "1,*,*")
312    (set_attr "prefix" "*,orig,vex")
313    (set_attr "mode" "V2SF,V4SF,V4SF")])
315 (define_expand "mmx_subv2sf3"
316   [(set (match_operand:V2SF 0 "register_operand")
317         (minus:V2SF (match_operand:V2SF 1 "register_operand")
318                     (match_operand:V2SF 2 "register_mmxmem_operand")))]
319   "TARGET_3DNOW")
321 (define_expand "mmx_subrv2sf3"
322   [(set (match_operand:V2SF 0 "register_operand")
323         (minus:V2SF (match_operand:V2SF 2 "register_operand")
324                     (match_operand:V2SF 1 "register_mmxmem_operand")))]
325   "TARGET_3DNOW")
327 (define_expand "subv2sf3"
328   [(set (match_operand:V2SF 0 "register_operand")
329         (minus:V2SF
330           (match_operand:V2SF 1 "register_operand")
331           (match_operand:V2SF 2 "register_operand")))]
332   "TARGET_MMX_WITH_SSE"
333   "ix86_fixup_binary_operands_no_copy (MINUS, V2SFmode, operands);")
335 (define_insn "*mmx_subv2sf3"
336   [(set (match_operand:V2SF 0 "register_operand" "=y,y,x,v")
337         (minus:V2SF
338           (match_operand:V2SF 1 "register_mmxmem_operand" "0,ym,0,v")
339           (match_operand:V2SF 2 "register_mmxmem_operand" "ym,0,x,v")))]
340   "(TARGET_3DNOW || TARGET_MMX_WITH_SSE)
341    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
342   "@
343    pfsub\t{%2, %0|%0, %2}
344    pfsubr\t{%1, %0|%0, %1}
345    subps\t{%2, %0|%0, %2}
346    vsubps\t{%2, %1, %0|%0, %1, %2}"
347   [(set_attr "isa" "*,*,sse2_noavx,avx")
348    (set_attr "mmx_isa" "native,native,*,*")
349    (set_attr "type" "mmxadd,mmxadd,sseadd,sseadd")
350    (set_attr "prefix_extra" "1,1,*,*")
351    (set_attr "prefix" "*,*,orig,vex")
352    (set_attr "mode" "V2SF,V2SF,V4SF,V4SF")])
354 (define_expand "mmx_mulv2sf3"
355   [(set (match_operand:V2SF 0 "register_operand")
356         (mult:V2SF (match_operand:V2SF 1 "register_mmxmem_operand")
357                    (match_operand:V2SF 2 "register_mmxmem_operand")))]
358   "TARGET_3DNOW"
359   "ix86_fixup_binary_operands_no_copy (MULT, V2SFmode, operands);")
361 (define_expand "mulv2sf3"
362   [(set (match_operand:V2SF 0 "register_operand")
363         (mult:V2SF
364           (match_operand:V2SF 1 "register_operand")
365           (match_operand:V2SF 2 "register_operand")))]
366   "TARGET_MMX_WITH_SSE"
367   "ix86_fixup_binary_operands_no_copy (MULT, V2SFmode, operands);")
369 (define_insn "*mmx_mulv2sf3"
370   [(set (match_operand:V2SF 0 "register_operand" "=y,x,v")
371         (mult:V2SF
372           (match_operand:V2SF 1 "register_mmxmem_operand" "%0,0,v")
373           (match_operand:V2SF 2 "register_mmxmem_operand" "ym,x,v")))]
374   "(TARGET_3DNOW || TARGET_MMX_WITH_SSE)
375    && ix86_binary_operator_ok (MULT, V2SFmode, operands)"
376   "@
377    pfmul\t{%2, %0|%0, %2}
378    mulps\t{%2, %0|%0, %2}
379    vmulps\t{%2, %1, %0|%0, %1, %2}"
380   [(set_attr "isa" "*,sse2_noavx,avx")
381    (set_attr "mmx_isa" "native,*,*")
382    (set_attr "type" "mmxmul,ssemul,ssemul")
383    (set_attr "btver2_decode" "*,direct,double")
384    (set_attr "prefix_extra" "1,*,*")
385    (set_attr "prefix" "*,orig,vex")
386    (set_attr "mode" "V2SF,V4SF,V4SF")])
388 (define_expand "mmx_<code>v2sf3"
389   [(set (match_operand:V2SF 0 "register_operand")
390         (smaxmin:V2SF
391           (match_operand:V2SF 1 "register_mmxmem_operand")
392           (match_operand:V2SF 2 "register_mmxmem_operand")))]
393   "TARGET_3DNOW"
395   if (!flag_finite_math_only || flag_signed_zeros)
396     {
397       operands[1] = force_reg (V2SFmode, operands[1]);
398       emit_insn (gen_mmx_ieee_<maxmin_float>v2sf3
399                  (operands[0], operands[1], operands[2]));
400       DONE;
401     }
402   else
403     ix86_fixup_binary_operands_no_copy (<CODE>, V2SFmode, operands);
406 (define_expand "<code>v2sf3"
407   [(set (match_operand:V2SF 0 "register_operand")
408         (smaxmin:V2SF
409           (match_operand:V2SF 1 "register_operand")
410           (match_operand:V2SF 2 "register_operand")))]
411   "TARGET_MMX_WITH_SSE"
413   if (!flag_finite_math_only || flag_signed_zeros)
414     {
415       emit_insn (gen_mmx_ieee_<maxmin_float>v2sf3
416                  (operands[0], operands[1], operands[2]));
417       DONE;
418     }
419   else
420     ix86_fixup_binary_operands_no_copy (<CODE>, V2SFmode, operands);
423 ;; These versions of the min/max patterns are intentionally ignorant of
424 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
425 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
426 ;; are undefined in this condition, we're certain this is correct.
428 (define_insn "*mmx_<code>v2sf3"
429   [(set (match_operand:V2SF 0 "register_operand" "=y,x,v")
430         (smaxmin:V2SF
431           (match_operand:V2SF 1 "register_mmxmem_operand" "%0,0,v")
432           (match_operand:V2SF 2 "register_mmxmem_operand" "ym,x,v")))]
433   "(TARGET_3DNOW || TARGET_MMX_WITH_SSE)
434    && ix86_binary_operator_ok (<CODE>, V2SFmode, operands)"
435   "@
436    pf<maxmin_float>\t{%2, %0|%0, %2}
437    <maxmin_float>ps\t{%2, %0|%0, %2}
438    v<maxmin_float>ps\t{%2, %1, %0|%0, %1, %2}"
439   [(set_attr "isa" "*,sse2_noavx,avx")
440    (set_attr "mmx_isa" "native,*,*")
441    (set_attr "type" "mmxadd,sseadd,sseadd")
442    (set_attr "btver2_sse_attr" "*,maxmin,maxmin")
443    (set_attr "prefix_extra" "1,*,*")
444    (set_attr "prefix" "*,orig,vex")
445    (set_attr "mode" "V2SF,V4SF,V4SF")])
447 ;; These versions of the min/max patterns implement exactly the operations
448 ;;   min = (op1 < op2 ? op1 : op2)
449 ;;   max = (!(op1 < op2) ? op1 : op2)
450 ;; Their operands are not commutative, and thus they may be used in the
451 ;; presence of -0.0 and NaN.
453 (define_insn "mmx_ieee_<ieee_maxmin>v2sf3"
454   [(set (match_operand:V2SF 0 "register_operand" "=y,x,v")
455         (unspec:V2SF
456           [(match_operand:V2SF 1 "register_operand" "0,0,v")
457            (match_operand:V2SF 2 "register_mmxmem_operand" "ym,x,v")]
458           IEEE_MAXMIN))]
459   "TARGET_3DNOW || TARGET_MMX_WITH_SSE"
460   "@
461    pf<ieee_maxmin>\t{%2, %0|%0, %2}
462    <ieee_maxmin>ps\t{%2, %0|%0, %2}
463    v<ieee_maxmin>ps\t{%2, %1, %0|%0, %1, %2}"
464   [(set_attr "isa" "*,sse2_noavx,avx")
465    (set_attr "mmx_isa" "native,*,*")
466    (set_attr "type" "mmxadd,sseadd,sseadd")
467    (set_attr "btver2_sse_attr" "*,maxmin,maxmin")
468    (set_attr "prefix_extra" "1,*,*")
469    (set_attr "prefix" "*,orig,vex")
470    (set_attr "mode" "V2SF,V4SF,V4SF")])
472 (define_insn "mmx_rcpv2sf2"
473   [(set (match_operand:V2SF 0 "register_operand" "=y")
474         (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
475                      UNSPEC_PFRCP))]
476   "TARGET_3DNOW"
477   "pfrcp\t{%1, %0|%0, %1}"
478   [(set_attr "type" "mmx")
479    (set_attr "prefix_extra" "1")
480    (set_attr "mode" "V2SF")])
482 (define_insn "mmx_rcpit1v2sf3"
483   [(set (match_operand:V2SF 0 "register_operand" "=y")
484         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
485                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
486                      UNSPEC_PFRCPIT1))]
487   "TARGET_3DNOW"
488   "pfrcpit1\t{%2, %0|%0, %2}"
489   [(set_attr "type" "mmx")
490    (set_attr "prefix_extra" "1")
491    (set_attr "mode" "V2SF")])
493 (define_insn "mmx_rcpit2v2sf3"
494   [(set (match_operand:V2SF 0 "register_operand" "=y")
495         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
496                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
497                      UNSPEC_PFRCPIT2))]
498   "TARGET_3DNOW"
499   "pfrcpit2\t{%2, %0|%0, %2}"
500   [(set_attr "type" "mmx")
501    (set_attr "prefix_extra" "1")
502    (set_attr "mode" "V2SF")])
504 (define_insn "sqrtv2sf2"
505   [(set (match_operand:V2SF 0 "register_operand" "=x,v")
506         (sqrt:V2SF (match_operand:V2SF 1 "register_operand" "0,v")))]
507   "TARGET_MMX_WITH_SSE"
508   "@
509    sqrtps\t{%1, %0|%0, %1}
510    vsqrtps\t{%1, %0|%0, %1}"
511   [(set_attr "isa" "noavx,avx")
512    (set_attr "type" "sse")
513    (set_attr "atom_sse_attr" "sqrt")
514    (set_attr "btver2_sse_attr" "sqrt")
515    (set_attr "prefix" "orig,vex")
516    (set_attr "mode" "V4SF")])
518 (define_insn "mmx_rsqrtv2sf2"
519   [(set (match_operand:V2SF 0 "register_operand" "=y")
520         (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
521                      UNSPEC_PFRSQRT))]
522   "TARGET_3DNOW"
523   "pfrsqrt\t{%1, %0|%0, %1}"
524   [(set_attr "type" "mmx")
525    (set_attr "prefix_extra" "1")
526    (set_attr "mode" "V2SF")])
528 (define_insn "mmx_rsqit1v2sf3"
529   [(set (match_operand:V2SF 0 "register_operand" "=y")
530         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
531                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
532                      UNSPEC_PFRSQIT1))]
533   "TARGET_3DNOW"
534   "pfrsqit1\t{%2, %0|%0, %2}"
535   [(set_attr "type" "mmx")
536    (set_attr "prefix_extra" "1")
537    (set_attr "mode" "V2SF")])
539 (define_expand "mmx_haddv2sf3"
540   [(set (match_operand:V2SF 0 "register_operand")
541         (vec_concat:V2SF
542           (plus:SF
543             (vec_select:SF
544               (match_operand:V2SF 1 "register_operand")
545               (parallel [(const_int 0)]))
546             (vec_select:SF (match_dup 1) (parallel [(const_int 1)])))
547           (plus:SF
548             (vec_select:SF
549               (match_operand:V2SF 2 "nonimmediate_operand")
550               (parallel [(const_int 0)]))
551             (vec_select:SF (match_dup 2) (parallel [(const_int 1)])))))]
552   "TARGET_3DNOW")
554 (define_insn "*mmx_haddv2sf3"
555   [(set (match_operand:V2SF 0 "register_operand" "=y")
556         (vec_concat:V2SF
557           (plus:SF
558             (vec_select:SF
559               (match_operand:V2SF 1 "register_operand" "0")
560               (parallel [(match_operand:SI 3 "const_0_to_1_operand")]))
561             (vec_select:SF (match_dup 1)
562             (parallel [(match_operand:SI 4 "const_0_to_1_operand")])))
563           (plus:SF
564             (vec_select:SF
565               (match_operand:V2SF 2 "nonimmediate_operand" "ym")
566               (parallel [(match_operand:SI 5 "const_0_to_1_operand")]))
567             (vec_select:SF (match_dup 2)
568             (parallel [(match_operand:SI 6 "const_0_to_1_operand")])))))]
569   "TARGET_3DNOW
570    && INTVAL (operands[3]) != INTVAL (operands[4])
571    && INTVAL (operands[5]) != INTVAL (operands[6])"
572   "pfacc\t{%2, %0|%0, %2}"
573   [(set_attr "type" "mmxadd")
574    (set_attr "prefix_extra" "1")
575    (set_attr "mode" "V2SF")])
577 (define_insn "*mmx_haddv2sf3_low"
578   [(set (match_operand:SF 0 "register_operand" "=x,x")
579         (plus:SF
580           (vec_select:SF
581             (match_operand:V2SF 1 "register_operand" "0,x")
582             (parallel [(match_operand:SI 2 "const_0_to_1_operand")]))
583           (vec_select:SF
584             (match_dup 1)
585             (parallel [(match_operand:SI 3 "const_0_to_1_operand")]))))]
586   "TARGET_MMX_WITH_SSE && TARGET_SSE3
587    && INTVAL (operands[2]) != INTVAL (operands[3])"
588   "@
589    haddps\t{%0, %0|%0, %0}
590    vhaddps\t{%1, %1, %0|%0, %1, %1}"
591   [(set_attr "isa" "noavx,avx")
592    (set_attr "type" "sseadd1")
593    (set_attr "prefix" "orig,vex")
594    (set_attr "mode" "V4SF")])
596 (define_insn "mmx_hsubv2sf3"
597   [(set (match_operand:V2SF 0 "register_operand" "=y")
598         (vec_concat:V2SF
599           (minus:SF
600             (vec_select:SF
601               (match_operand:V2SF 1 "register_operand" "0")
602               (parallel [(const_int  0)]))
603             (vec_select:SF (match_dup 1) (parallel [(const_int 1)])))
604           (minus:SF
605             (vec_select:SF
606               (match_operand:V2SF 2 "nonimmediate_operand" "ym")
607               (parallel [(const_int  0)]))
608             (vec_select:SF (match_dup 2) (parallel [(const_int 1)])))))]
609   "TARGET_3DNOW_A"
610   "pfnacc\t{%2, %0|%0, %2}"
611   [(set_attr "type" "mmxadd")
612    (set_attr "prefix_extra" "1")
613    (set_attr "mode" "V2SF")])
615 (define_insn "*mmx_hsubv2sf3_low"
616   [(set (match_operand:SF 0 "register_operand" "=x,x")
617         (minus:SF
618           (vec_select:SF
619             (match_operand:V2SF 1 "register_operand" "0,x")
620             (parallel [(const_int 0)]))
621           (vec_select:SF
622             (match_dup 1)
623             (parallel [(const_int 1)]))))]
624   "TARGET_MMX_WITH_SSE && TARGET_SSE3"
625   "@
626    hsubps\t{%0, %0|%0, %0}
627    vhsubps\t{%1, %1, %0|%0, %1, %1}"
628   [(set_attr "isa" "noavx,avx")
629    (set_attr "type" "sseadd1")
630    (set_attr "prefix" "orig,vex")
631    (set_attr "mode" "V4SF")])
633 (define_expand "mmx_haddsubv2sf3"
634   [(set (match_operand:V2SF 0 "register_operand")
635         (vec_concat:V2SF
636           (minus:SF
637             (vec_select:SF
638               (match_operand:V2SF 1 "register_operand")
639               (parallel [(const_int 0)]))
640             (vec_select:SF (match_dup 1) (parallel [(const_int 1)])))
641           (plus:SF
642             (vec_select:SF
643               (match_operand:V2SF 2 "nonimmediate_operand")
644               (parallel [(const_int 0)]))
645             (vec_select:SF (match_dup 2) (parallel [(const_int 1)])))))]
646   "TARGET_3DNOW_A")
648 (define_insn "*mmx_haddsubv2sf3"
649   [(set (match_operand:V2SF 0 "register_operand" "=y")
650         (vec_concat:V2SF
651           (minus:SF
652             (vec_select:SF
653               (match_operand:V2SF 1 "register_operand" "0")
654               (parallel [(const_int  0)]))
655             (vec_select:SF (match_dup 1) (parallel [(const_int 1)])))
656           (plus:SF
657             (vec_select:SF
658               (match_operand:V2SF 2 "nonimmediate_operand" "ym")
659               (parallel [(match_operand:SI 3 "const_0_to_1_operand")]))
660             (vec_select:SF
661               (match_dup 2)
662               (parallel [(match_operand:SI 4 "const_0_to_1_operand")])))))]
663   "TARGET_3DNOW_A
664    && INTVAL (operands[3]) != INTVAL (operands[4])"
665   "pfpnacc\t{%2, %0|%0, %2}"
666   [(set_attr "type" "mmxadd")
667    (set_attr "prefix_extra" "1")
668    (set_attr "mode" "V2SF")])
670 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
672 ;; Parallel single-precision floating point comparisons
674 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
676 (define_expand "mmx_eqv2sf3"
677   [(set (match_operand:V2SI 0 "register_operand")
678         (eq:V2SI (match_operand:V2SF 1 "nonimmediate_operand")
679                  (match_operand:V2SF 2 "nonimmediate_operand")))]
680   "TARGET_3DNOW"
681   "ix86_fixup_binary_operands_no_copy (EQ, V2SFmode, operands);")
683 (define_insn "*mmx_eqv2sf3"
684   [(set (match_operand:V2SI 0 "register_operand" "=y")
685         (eq:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "%0")
686                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
687   "TARGET_3DNOW && ix86_binary_operator_ok (EQ, V2SFmode, operands)"
688   "pfcmpeq\t{%2, %0|%0, %2}"
689   [(set_attr "type" "mmxcmp")
690    (set_attr "prefix_extra" "1")
691    (set_attr "mode" "V2SF")])
693 (define_insn "mmx_gtv2sf3"
694   [(set (match_operand:V2SI 0 "register_operand" "=y")
695         (gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
696                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
697   "TARGET_3DNOW"
698   "pfcmpgt\t{%2, %0|%0, %2}"
699   [(set_attr "type" "mmxcmp")
700    (set_attr "prefix_extra" "1")
701    (set_attr "mode" "V2SF")])
703 (define_insn "mmx_gev2sf3"
704   [(set (match_operand:V2SI 0 "register_operand" "=y")
705         (ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
706                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
707   "TARGET_3DNOW"
708   "pfcmpge\t{%2, %0|%0, %2}"
709   [(set_attr "type" "mmxcmp")
710    (set_attr "prefix_extra" "1")
711    (set_attr "mode" "V2SF")])
713 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
715 ;; Parallel single-precision floating point logical operations
717 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
719 (define_insn "*mmx_andnotv2sf3"
720   [(set (match_operand:V2SF 0 "register_operand" "=x,x")
721         (and:V2SF
722           (not:V2SF
723             (match_operand:V2SF 1 "register_operand" "0,x"))
724           (match_operand:V2SF 2 "register_operand" "x,x")))]
725   "TARGET_MMX_WITH_SSE"
726   "@
727    andnps\t{%2, %0|%0, %2}
728    vandnps\t{%2, %1, %0|%0, %1, %2}"
729   [(set_attr "isa" "noavx,avx")
730    (set_attr "type" "sselog")
731    (set_attr "prefix" "orig,vex")
732    (set_attr "mode" "V4SF")])
734 (define_insn "*mmx_<code>v2sf3"
735   [(set (match_operand:V2SF 0 "register_operand" "=x,x")
736         (any_logic:V2SF
737           (match_operand:V2SF 1 "register_operand" "%0,x")
738           (match_operand:V2SF 2 "register_operand" "x,x")))]
739   "TARGET_MMX_WITH_SSE"
740   "@
741    <logic>ps\t{%2, %0|%0, %2}
742    v<logic>ps\t{%2, %1, %0|%0, %1, %2}"
743   [(set_attr "isa" "noavx,avx")
744    (set_attr "type" "sselog")
745    (set_attr "prefix" "orig,vex")
746    (set_attr "mode" "V4SF")])
748 (define_expand "copysignv2sf3"
749   [(set (match_dup 4)
750         (and:V2SF
751           (not:V2SF (match_dup 3))
752           (match_operand:V2SF 1 "register_operand")))
753    (set (match_dup 5)
754         (and:V2SF (match_dup 3)
755                   (match_operand:V2SF 2 "register_operand")))
756    (set (match_operand:V2SF 0 "register_operand")
757         (ior:V2SF (match_dup 4) (match_dup 5)))]
758   "TARGET_MMX_WITH_SSE"
760   operands[3] = ix86_build_signbit_mask (V2SFmode, true, false);
762   operands[4] = gen_reg_rtx (V2SFmode);
763   operands[5] = gen_reg_rtx (V2SFmode);
766 (define_expand "xorsignv2sf3"
767   [(set (match_dup 4)
768         (and:V2SF (match_dup 3)
769                   (match_operand:V2SF 2 "register_operand")))
770    (set (match_operand:V2SF 0 "register_operand")
771         (xor:V2SF (match_dup 4)
772                   (match_operand:V2SF 1 "register_operand")))]
773   "TARGET_MMX_WITH_SSE"
775   operands[3] = ix86_build_signbit_mask (V2SFmode, true, false);
777   operands[4] = gen_reg_rtx (V2SFmode);
780 (define_expand "signbitv2sf2"
781   [(set (match_operand:V2SI 0 "register_operand")
782         (lshiftrt:V2SI
783           (subreg:V2SI
784             (match_operand:V2SF 1 "register_operand") 0)
785           (match_dup 2)))]
786   "TARGET_MMX_WITH_SSE"
787   "operands[2] = GEN_INT (GET_MODE_UNIT_BITSIZE (V2SFmode)-1);")
789 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
791 ;; Parallel single-precision FMA multiply/accumulate instructions.
793 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
795 (define_insn "fmav2sf4"
796   [(set (match_operand:V2SF 0 "register_operand" "=v,v,x")
797         (fma:V2SF
798           (match_operand:V2SF 1 "register_operand" "%0,v,x")
799           (match_operand:V2SF 2 "register_operand" "v,v,x")
800           (match_operand:V2SF 3 "register_operand" "v,0,x")))]
801   "(TARGET_FMA || TARGET_FMA4) && TARGET_MMX_WITH_SSE"
802   "@
803    vfmadd132ps\t{%2, %3, %0|%0, %3, %2}
804    vfmadd231ps\t{%2, %1, %0|%0, %1, %2}
805    vfmaddps\t{%3, %2, %1, %0|%0, %1, %2, %3}"
806   [(set_attr "isa" "fma,fma,fma4")
807    (set_attr "type" "ssemuladd")
808    (set_attr "mode" "V4SF")])
810 (define_insn "fmsv2sf4"
811   [(set (match_operand:V2SF 0 "register_operand" "=v,v,x")
812         (fma:V2SF
813           (match_operand:V2SF   1 "register_operand" "%0,v,x")
814           (match_operand:V2SF   2 "register_operand" "v,v,x")
815           (neg:V2SF
816             (match_operand:V2SF 3 "register_operand" "v,0,x"))))]
817   "(TARGET_FMA || TARGET_FMA4) && TARGET_MMX_WITH_SSE"
818   "@
819    vfmsub132ps\t{%2, %3, %0|%0, %3, %2}
820    vfmsub231ps\t{%2, %1, %0|%0, %1, %2}
821    vfmsubps\t{%3, %2, %1, %0|%0, %1, %2, %3}"
822   [(set_attr "isa" "fma,fma,fma4")
823    (set_attr "type" "ssemuladd")
824    (set_attr "mode" "V4SF")])
826 (define_insn "fnmav2sf4"
827   [(set (match_operand:V2SF 0 "register_operand" "=v,v,x")
828         (fma:V2SF
829           (neg:V2SF
830             (match_operand:V2SF 1 "register_operand" "%0,v,x"))
831           (match_operand:V2SF   2 "register_operand" "v,v,x")
832           (match_operand:V2SF   3 "register_operand" "v,0,x")))]
833   "(TARGET_FMA || TARGET_FMA4) && TARGET_MMX_WITH_SSE"
834   "@
835    vfnmadd132ps\t{%2, %3, %0|%0, %3, %2}
836    vfnmadd231ps\t{%2, %1, %0|%0, %1, %2}
837    vfnmaddps\t{%3, %2, %1, %0|%0, %1, %2, %3}"
838   [(set_attr "isa" "fma,fma,fma4")
839    (set_attr "type" "ssemuladd")
840    (set_attr "mode" "V4SF")])
842 (define_insn "fnmsv2sf4"
843   [(set (match_operand:V2SF 0 "register_operand" "=v,v,x")
844         (fma:V2SF
845           (neg:V2SF
846             (match_operand:V2SF 1 "register_operand" "%0,v,x"))
847           (match_operand:V2SF   2 "register_operand" "v,v,x")
848           (neg:V2SF
849             (match_operand:V2SF 3 "register_operand" "v,0,x"))))]
850   "(TARGET_FMA || TARGET_FMA4) && TARGET_MMX_WITH_SSE"
851   "@
852    vfnmsub132ps\t{%2, %3, %0|%0, %3, %2}
853    vfnmsub231ps\t{%2, %1, %0|%0, %1, %2}
854    vfnmsubps\t{%3, %2, %1, %0|%0, %1, %2, %3}"
855   [(set_attr "isa" "fma,fma,fma4")
856    (set_attr "type" "ssemuladd")
857    (set_attr "mode" "V4SF")])
859 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
861 ;; Parallel single-precision floating point conversion operations
863 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
865 (define_insn "mmx_fix_truncv2sfv2si2"
866   [(set (match_operand:V2SI 0 "register_operand" "=y,Yv")
867         (fix:V2SI (match_operand:V2SF 1 "register_mmxmem_operand" "ym,Yv")))]
868   "TARGET_3DNOW || TARGET_MMX_WITH_SSE"
869   "@
870    pf2id\t{%1, %0|%0, %1}
871    %vcvttps2dq\t{%1, %0|%0, %1}"
872   [(set_attr "isa" "*,sse2")
873    (set_attr "mmx_isa" "native,*")
874    (set_attr "type" "mmxcvt,ssecvt")
875    (set_attr "prefix_extra" "1,*")
876    (set_attr "prefix_rep" "*,1")
877    (set_attr "prefix_data16" "*,0")
878    (set_attr "prefix" "*,maybe_vex")
879    (set_attr "mode" "V2SF,TI")])
881 (define_expand "fix_truncv2sfv2si2"
882   [(set (match_operand:V2SI 0 "register_operand")
883         (fix:V2SI (match_operand:V2SF 1 "register_operand")))]
884   "TARGET_MMX_WITH_SSE")
886 (define_insn "fixuns_truncv2sfv2si2"
887   [(set (match_operand:V2SI 0 "register_operand" "=v")
888         (unsigned_fix:V2SI (match_operand:V2SF 1 "register_operand" "v")))]
889   "TARGET_MMX_WITH_SSE && TARGET_AVX512VL"
890   "vcvttps2udq\t{%1, %0|%0, %1}"
891   [(set_attr "type" "ssecvt")
892    (set_attr "prefix" "evex")
893    (set_attr "mode" "TI")])
895 (define_insn "mmx_floatv2siv2sf2"
896   [(set (match_operand:V2SF 0 "register_operand" "=y,Yv")
897         (float:V2SF (match_operand:V2SI 1 "register_mmxmem_operand" "ym,Yv")))]
898   "TARGET_3DNOW || TARGET_MMX_WITH_SSE"
899   "@
900    pi2fd\t{%1, %0|%0, %1}
901    %vcvtdq2ps\t{%1, %0|%0, %1}"
902   [(set_attr "isa" "*,sse2")
903    (set_attr "mmx_isa" "native,*")
904    (set_attr "type" "mmxcvt,ssecvt")
905    (set_attr "prefix_extra" "1")
906    (set_attr "prefix" "*,maybe_vex")
907    (set_attr "mode" "V2SF,V4SF")])
909 (define_expand "floatv2siv2sf2"
910   [(set (match_operand:V2SF 0 "register_operand")
911         (float:V2SF (match_operand:V2SI 1 "register_operand")))]
912   "TARGET_MMX_WITH_SSE")
914 (define_insn "floatunsv2siv2sf2"
915   [(set (match_operand:V2SF 0 "register_operand" "=v")
916         (unsigned_float:V2SF (match_operand:V2SI 1 "register_operand" "v")))]
917   "TARGET_MMX_WITH_SSE && TARGET_AVX512VL"
918   "vcvtudq2ps\t{%1, %0|%0, %1}"
919   [(set_attr "type" "ssecvt")
920    (set_attr "prefix" "evex")
921    (set_attr "mode" "V4SF")])
923 (define_insn "mmx_pf2iw"
924   [(set (match_operand:V2SI 0 "register_operand" "=y")
925         (sign_extend:V2SI
926           (ss_truncate:V2HI
927             (fix:V2SI
928               (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
929   "TARGET_3DNOW_A"
930   "pf2iw\t{%1, %0|%0, %1}"
931   [(set_attr "type" "mmxcvt")
932    (set_attr "prefix_extra" "1")
933    (set_attr "mode" "V2SF")])
935 (define_insn "mmx_pi2fw"
936   [(set (match_operand:V2SF 0 "register_operand" "=y")
937         (float:V2SF
938           (sign_extend:V2SI
939             (truncate:V2HI
940               (match_operand:V2SI 1 "nonimmediate_operand" "ym")))))]
941   "TARGET_3DNOW_A"
942   "pi2fw\t{%1, %0|%0, %1}"
943   [(set_attr "type" "mmxcvt")
944    (set_attr "prefix_extra" "1")
945    (set_attr "mode" "V2SF")])
947 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
949 ;; Parallel single-precision floating point element swizzling
951 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
953 (define_insn "mmx_pswapdv2sf2"
954   [(set (match_operand:V2SF 0 "register_operand" "=y,x,Yv")
955         (vec_select:V2SF
956           (match_operand:V2SF 1 "register_mmxmem_operand" "ym,0,Yv")
957           (parallel [(const_int 1) (const_int 0)])))]
958   "TARGET_3DNOW_A || TARGET_MMX_WITH_SSE"
959   "@
960    pswapd\t{%1, %0|%0, %1}
961    shufps\t{$0xe1, %1, %0|%0, %1, 0xe1}
962    vshufps\t{$0xe1, %1, %1, %0|%0, %1, %1, 0xe1}"
963   [(set_attr "isa" "*,sse_noavx,avx")
964    (set_attr "mmx_isa" "native,*,*")
965    (set_attr "type" "mmxcvt,ssemov,ssemov")
966    (set_attr "prefix_extra" "1,*,*")
967    (set_attr "mode" "V2SF,V4SF,V4SF")])
969 (define_insn "*mmx_movshdup"
970   [(set (match_operand:V2SF 0 "register_operand" "=v,x")
971         (vec_select:V2SF
972           (match_operand:V2SF 1 "register_operand" "v,0")
973           (parallel [(const_int 1) (const_int 1)])))]
974   "TARGET_MMX_WITH_SSE"
975   "@
976    %vmovshdup\t{%1, %0|%0, %1}
977    shufps\t{$0xe5, %0, %0|%0, %0, 0xe5}"
978   [(set_attr "isa" "sse3,*")
979    (set_attr "type" "sse,sseshuf1")
980    (set_attr "length_immediate" "*,1")
981    (set_attr "prefix_rep" "1,*")
982    (set_attr "prefix" "maybe_vex,orig")
983    (set_attr "mode" "V4SF")])
985 (define_insn "*mmx_movsldup"
986   [(set (match_operand:V2SF 0 "register_operand" "=v,x")
987         (vec_select:V2SF
988           (match_operand:V2SF 1 "register_operand" "v,0")
989           (parallel [(const_int 0) (const_int 0)])))]
990   "TARGET_MMX_WITH_SSE"
991   "@
992    %vmovsldup\t{%1, %0|%0, %1}
993    shufps\t{$0xe0, %0, %0|%0, %0, 0xe0}"
994   [(set_attr "isa" "sse3,*")
995    (set_attr "type" "sse,sseshuf1")
996    (set_attr "length_immediate" "*,1")
997    (set_attr "prefix_rep" "1,*")
998    (set_attr "prefix" "maybe_vex,orig")
999    (set_attr "mode" "V4SF")])
1001 (define_insn "*vec_dupv2sf"
1002   [(set (match_operand:V2SF 0 "register_operand" "=y,Yv,x")
1003         (vec_duplicate:V2SF
1004           (match_operand:SF 1 "register_operand" "0,Yv,0")))]
1005   "TARGET_MMX || TARGET_MMX_WITH_SSE"
1006   "@
1007    punpckldq\t%0, %0
1008    %vmovsldup\t{%1, %0|%0, %1}
1009    shufps\t{$0xe0, %0, %0|%0, %0, 0xe0}"
1010   [(set_attr "isa" "*,sse3,sse_noavx")
1011    (set_attr "mmx_isa" "native,*,*")
1012    (set_attr "type" "mmxcvt,sse,sseshuf1")
1013    (set_attr "length_immediate" "*,*,1")
1014    (set_attr "prefix_rep" "*,1,*")
1015    (set_attr "prefix" "*,maybe_vex,orig")
1016    (set_attr "mode" "DI,V4SF,V4SF")])
1018 (define_insn "*mmx_movss"
1019   [(set (match_operand:V2SF 0 "register_operand"   "=x,v")
1020         (vec_merge:V2SF
1021           (match_operand:V2SF 2 "register_operand" " x,v")
1022           (match_operand:V2SF 1 "register_operand" " 0,v")
1023           (const_int 1)))]
1024   "TARGET_MMX_WITH_SSE"
1025   "@
1026    movss\t{%2, %0|%0, %2}
1027    vmovss\t{%2, %1, %0|%0, %1, %2}"
1028   [(set_attr "isa" "noavx,avx")
1029    (set_attr "type" "ssemov")
1030    (set_attr "prefix" "orig,maybe_evex")
1031    (set_attr "mode" "SF")])
1033 (define_insn "*mmx_concatv2sf"
1034   [(set (match_operand:V2SF 0 "register_operand"     "=y,y")
1035         (vec_concat:V2SF
1036           (match_operand:SF 1 "nonimmediate_operand" " 0,rm")
1037           (match_operand:SF 2 "nonimm_or_0_operand"  "ym,C")))]
1038   "TARGET_MMX && !TARGET_SSE"
1039   "@
1040    punpckldq\t{%2, %0|%0, %2}
1041    movd\t{%1, %0|%0, %1}"
1042   [(set_attr "type" "mmxcvt,mmxmov")
1043    (set_attr "mode" "DI")])
1045 (define_expand "vec_setv2sf"
1046   [(match_operand:V2SF 0 "register_operand")
1047    (match_operand:SF 1 "register_operand")
1048    (match_operand 2 "const_int_operand")]
1049   "TARGET_MMX || TARGET_MMX_WITH_SSE"
1051   ix86_expand_vector_set (TARGET_MMX_WITH_SSE, operands[0], operands[1],
1052                           INTVAL (operands[2]));
1053   DONE;
1056 ;; Avoid combining registers from different units in a single alternative,
1057 ;; see comment above inline_secondary_memory_needed function in i386.c
1058 (define_insn_and_split "*vec_extractv2sf_0"
1059   [(set (match_operand:SF 0 "nonimmediate_operand"     "=x, m,y ,m,f,r")
1060         (vec_select:SF
1061           (match_operand:V2SF 1 "nonimmediate_operand" " xm,x,ym,y,m,m")
1062           (parallel [(const_int 0)])))]
1063   "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1064    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1065   "#"
1066   "&& reload_completed"
1067   [(set (match_dup 0) (match_dup 1))]
1068   "operands[1] = gen_lowpart (SFmode, operands[1]);"
1069   [(set_attr "mmx_isa" "*,*,native,native,*,*")])
1071 ;; Avoid combining registers from different units in a single alternative,
1072 ;; see comment above inline_secondary_memory_needed function in i386.c
1073 (define_insn "*vec_extractv2sf_1"
1074   [(set (match_operand:SF 0 "nonimmediate_operand"     "=y,x,x,y,x,f,r")
1075         (vec_select:SF
1076           (match_operand:V2SF 1 "nonimmediate_operand" " 0,x,0,o,o,o,o")
1077           (parallel [(const_int 1)])))]
1078   "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1079    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1080   "@
1081    punpckhdq\t%0, %0
1082    %vmovshdup\t{%1, %0|%0, %1}
1083    shufps\t{$0xe5, %0, %0|%0, %0, 0xe5}
1084    #
1085    #
1086    #
1087    #"
1088   [(set_attr "isa" "*,sse3,noavx,*,*,*,*")
1089    (set_attr "mmx_isa" "native,*,*,native,*,*,*")
1090    (set_attr "type" "mmxcvt,sse,sseshuf1,mmxmov,ssemov,fmov,imov")
1091    (set (attr "length_immediate")
1092      (if_then_else (eq_attr "alternative" "2")
1093                    (const_string "1")
1094                    (const_string "*")))
1095    (set (attr "prefix_rep")
1096      (if_then_else (eq_attr "alternative" "1")
1097                    (const_string "1")
1098                    (const_string "*")))
1099    (set_attr "prefix" "orig,maybe_vex,orig,orig,orig,orig,orig")
1100    (set_attr "mode" "DI,V4SF,V4SF,SF,SF,SF,SF")])
1102 (define_split
1103   [(set (match_operand:SF 0 "register_operand")
1104         (vec_select:SF
1105           (match_operand:V2SF 1 "memory_operand")
1106           (parallel [(const_int 1)])))]
1107   "(TARGET_MMX || TARGET_MMX_WITH_SSE) && reload_completed"
1108   [(set (match_dup 0) (match_dup 1))]
1109   "operands[1] = adjust_address (operands[1], SFmode, 4);")
1111 (define_expand "vec_extractv2sfsf"
1112   [(match_operand:SF 0 "register_operand")
1113    (match_operand:V2SF 1 "register_operand")
1114    (match_operand 2 "const_int_operand")]
1115   "TARGET_MMX || TARGET_MMX_WITH_SSE"
1117   ix86_expand_vector_extract (TARGET_MMX_WITH_SSE, operands[0],
1118                               operands[1], INTVAL (operands[2]));
1119   DONE;
1122 (define_expand "vec_initv2sfsf"
1123   [(match_operand:V2SF 0 "register_operand")
1124    (match_operand 1)]
1125   "(TARGET_MMX || TARGET_MMX_WITH_SSE) && TARGET_SSE"
1127   ix86_expand_vector_init (TARGET_MMX_WITH_SSE, operands[0],
1128                            operands[1]);
1129   DONE;
1132 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1134 ;; Parallel integral arithmetic
1136 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1138 (define_expand "mmx_<plusminus_insn><mode>3"
1139   [(set (match_operand:MMXMODEI8 0 "register_operand")
1140         (plusminus:MMXMODEI8
1141           (match_operand:MMXMODEI8 1 "register_mmxmem_operand")
1142           (match_operand:MMXMODEI8 2 "register_mmxmem_operand")))]
1143   "TARGET_MMX || TARGET_MMX_WITH_SSE"
1144   "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
1146 (define_expand "<plusminus_insn><mode>3"
1147   [(set (match_operand:MMXMODEI 0 "register_operand")
1148         (plusminus:MMXMODEI
1149           (match_operand:MMXMODEI 1 "register_operand")
1150           (match_operand:MMXMODEI 2 "register_operand")))]
1151   "TARGET_MMX_WITH_SSE"
1152   "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
1154 (define_insn "*mmx_<plusminus_insn><mode>3"
1155   [(set (match_operand:MMXMODEI8 0 "register_operand" "=y,x,Yv")
1156         (plusminus:MMXMODEI8
1157           (match_operand:MMXMODEI8 1 "register_mmxmem_operand" "<comm>0,0,Yv")
1158           (match_operand:MMXMODEI8 2 "register_mmxmem_operand" "ym,x,Yv")))]
1159   "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1160    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
1161   "@
1162    p<plusminus_mnemonic><mmxvecsize>\t{%2, %0|%0, %2}
1163    p<plusminus_mnemonic><mmxvecsize>\t{%2, %0|%0, %2}
1164    vp<plusminus_mnemonic><mmxvecsize>\t{%2, %1, %0|%0, %1, %2}"
1165   [(set_attr "isa" "*,sse2_noavx,avx")
1166    (set_attr "mmx_isa" "native,*,*")
1167    (set_attr "type" "mmxadd,sseadd,sseadd")
1168    (set_attr "mode" "DI,TI,TI")])
1170 (define_expand "mmx_<plusminus_insn><mode>3"
1171   [(set (match_operand:MMXMODE12 0 "register_operand")
1172         (sat_plusminus:MMXMODE12
1173           (match_operand:MMXMODE12 1 "register_mmxmem_operand")
1174           (match_operand:MMXMODE12 2 "register_mmxmem_operand")))]
1175   "TARGET_MMX || TARGET_MMX_WITH_SSE"
1176   "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
1178 (define_insn "*mmx_<plusminus_insn><mode>3"
1179   [(set (match_operand:MMXMODE12 0 "register_operand" "=y,x,Yv")
1180         (sat_plusminus:MMXMODE12
1181           (match_operand:MMXMODE12 1 "register_mmxmem_operand" "<comm>0,0,Yv")
1182           (match_operand:MMXMODE12 2 "register_mmxmem_operand" "ym,x,Yv")))]
1183   "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1184    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
1185   "@
1186    p<plusminus_mnemonic><mmxvecsize>\t{%2, %0|%0, %2}
1187    p<plusminus_mnemonic><mmxvecsize>\t{%2, %0|%0, %2}
1188    vp<plusminus_mnemonic><mmxvecsize>\t{%2, %1, %0|%0, %1, %2}"
1189   [(set_attr "isa" "*,sse2_noavx,avx")
1190    (set_attr "mmx_isa" "native,*,*")
1191    (set_attr "type" "mmxadd,sseadd,sseadd")
1192    (set_attr "mode" "DI,TI,TI")])
1194 (define_expand "mmx_mulv4hi3"
1195   [(set (match_operand:V4HI 0 "register_operand")
1196         (mult:V4HI (match_operand:V4HI 1 "register_mmxmem_operand")
1197                    (match_operand:V4HI 2 "register_mmxmem_operand")))]
1198   "TARGET_MMX || TARGET_MMX_WITH_SSE"
1199   "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
1201 (define_expand "mulv4hi3"
1202   [(set (match_operand:V4HI 0 "register_operand")
1203         (mult:V4HI (match_operand:V4HI 1 "register_operand")
1204                    (match_operand:V4HI 2 "register_operand")))]
1205   "TARGET_MMX_WITH_SSE"
1206   "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
1208 (define_insn "*mmx_mulv4hi3"
1209   [(set (match_operand:V4HI 0 "register_operand" "=y,x,Yv")
1210         (mult:V4HI (match_operand:V4HI 1 "register_mmxmem_operand" "%0,0,Yv")
1211                    (match_operand:V4HI 2 "register_mmxmem_operand" "ym,x,Yv")))]
1212   "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1213    && ix86_binary_operator_ok (MULT, V4HImode, operands)"
1214   "@
1215    pmullw\t{%2, %0|%0, %2}
1216    pmullw\t{%2, %0|%0, %2}
1217    vpmullw\t{%2, %1, %0|%0, %1, %2}"
1218   [(set_attr "isa" "*,sse2_noavx,avx")
1219    (set_attr "mmx_isa" "native,*,*")
1220    (set_attr "type" "mmxmul,ssemul,ssemul")
1221    (set_attr "mode" "DI,TI,TI")])
1223 (define_expand "mmx_smulv4hi3_highpart"
1224   [(set (match_operand:V4HI 0 "register_operand")
1225         (truncate:V4HI
1226           (lshiftrt:V4SI
1227             (mult:V4SI
1228               (sign_extend:V4SI
1229                 (match_operand:V4HI 1 "register_mmxmem_operand"))
1230               (sign_extend:V4SI
1231                 (match_operand:V4HI 2 "register_mmxmem_operand")))
1232             (const_int 16))))]
1233   "TARGET_MMX || TARGET_MMX_WITH_SSE"
1234   "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
1236 (define_insn "*mmx_smulv4hi3_highpart"
1237   [(set (match_operand:V4HI 0 "register_operand" "=y,x,Yv")
1238         (truncate:V4HI
1239           (lshiftrt:V4SI
1240             (mult:V4SI
1241               (sign_extend:V4SI
1242                 (match_operand:V4HI 1 "register_mmxmem_operand" "%0,0,Yv"))
1243               (sign_extend:V4SI
1244                 (match_operand:V4HI 2 "register_mmxmem_operand" "ym,x,Yv")))
1245             (const_int 16))))]
1246   "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1247    && ix86_binary_operator_ok (MULT, V4HImode, operands)"
1248   "@
1249    pmulhw\t{%2, %0|%0, %2}
1250    pmulhw\t{%2, %0|%0, %2}
1251    vpmulhw\t{%2, %1, %0|%0, %1, %2}"
1252   [(set_attr "isa" "*,sse2_noavx,avx")
1253    (set_attr "mmx_isa" "native,*,*")
1254    (set_attr "type" "mmxmul,ssemul,ssemul")
1255    (set_attr "mode" "DI,TI,TI")])
1257 (define_expand "mmx_umulv4hi3_highpart"
1258   [(set (match_operand:V4HI 0 "register_operand")
1259         (truncate:V4HI
1260           (lshiftrt:V4SI
1261             (mult:V4SI
1262               (zero_extend:V4SI
1263                 (match_operand:V4HI 1 "register_mmxmem_operand"))
1264               (zero_extend:V4SI
1265                 (match_operand:V4HI 2 "register_mmxmem_operand")))
1266             (const_int 16))))]
1267   "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1268    && (TARGET_SSE || TARGET_3DNOW_A)"
1269   "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
1271 (define_insn "*mmx_umulv4hi3_highpart"
1272   [(set (match_operand:V4HI 0 "register_operand" "=y,x,Yv")
1273         (truncate:V4HI
1274           (lshiftrt:V4SI
1275             (mult:V4SI
1276               (zero_extend:V4SI
1277                 (match_operand:V4HI 1 "register_mmxmem_operand" "%0,0,Yv"))
1278               (zero_extend:V4SI
1279                 (match_operand:V4HI 2 "register_mmxmem_operand" "ym,x,Yv")))
1280           (const_int 16))))]
1281   "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1282    && (TARGET_SSE || TARGET_3DNOW_A)
1283    && ix86_binary_operator_ok (MULT, V4HImode, operands)"
1284   "@
1285    pmulhuw\t{%2, %0|%0, %2}
1286    pmulhuw\t{%2, %0|%0, %2}
1287    vpmulhuw\t{%2, %1, %0|%0, %1, %2}"
1288   [(set_attr "isa" "*,sse2_noavx,avx")
1289    (set_attr "mmx_isa" "native,*,*")
1290    (set_attr "type" "mmxmul,ssemul,ssemul")
1291    (set_attr "mode" "DI,TI,TI")])
1293 (define_expand "mmx_pmaddwd"
1294   [(set (match_operand:V2SI 0 "register_operand")
1295         (plus:V2SI
1296           (mult:V2SI
1297             (sign_extend:V2SI
1298               (vec_select:V2HI
1299                 (match_operand:V4HI 1 "register_mmxmem_operand")
1300                 (parallel [(const_int 0) (const_int 2)])))
1301             (sign_extend:V2SI
1302               (vec_select:V2HI
1303                 (match_operand:V4HI 2 "register_mmxmem_operand")
1304                 (parallel [(const_int 0) (const_int 2)]))))
1305           (mult:V2SI
1306             (sign_extend:V2SI
1307               (vec_select:V2HI (match_dup 1)
1308                 (parallel [(const_int 1) (const_int 3)])))
1309             (sign_extend:V2SI
1310               (vec_select:V2HI (match_dup 2)
1311                 (parallel [(const_int 1) (const_int 3)]))))))]
1312   "TARGET_MMX || TARGET_MMX_WITH_SSE"
1313   "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
1315 (define_insn "*mmx_pmaddwd"
1316   [(set (match_operand:V2SI 0 "register_operand" "=y,x,Yv")
1317         (plus:V2SI
1318           (mult:V2SI
1319             (sign_extend:V2SI
1320               (vec_select:V2HI
1321                 (match_operand:V4HI 1 "register_mmxmem_operand" "%0,0,Yv")
1322                 (parallel [(const_int 0) (const_int 2)])))
1323             (sign_extend:V2SI
1324               (vec_select:V2HI
1325                 (match_operand:V4HI 2 "register_mmxmem_operand" "ym,x,Yv")
1326                 (parallel [(const_int 0) (const_int 2)]))))
1327           (mult:V2SI
1328             (sign_extend:V2SI
1329               (vec_select:V2HI (match_dup 1)
1330                 (parallel [(const_int 1) (const_int 3)])))
1331             (sign_extend:V2SI
1332               (vec_select:V2HI (match_dup 2)
1333                 (parallel [(const_int 1) (const_int 3)]))))))]
1334   "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1335    && ix86_binary_operator_ok (MULT, V4HImode, operands)"
1336   "@
1337    pmaddwd\t{%2, %0|%0, %2}
1338    pmaddwd\t{%2, %0|%0, %2}
1339    vpmaddwd\t{%2, %1, %0|%0, %1, %2}"
1340   [(set_attr "isa" "*,sse2_noavx,avx")
1341    (set_attr "mmx_isa" "native,*,*")
1342    (set_attr "type" "mmxmul,sseiadd,sseiadd")
1343    (set_attr "mode" "DI,TI,TI")])
1345 (define_expand "mmx_pmulhrwv4hi3"
1346   [(set (match_operand:V4HI 0 "register_operand")
1347         (truncate:V4HI
1348           (lshiftrt:V4SI
1349             (plus:V4SI
1350               (mult:V4SI
1351                 (sign_extend:V4SI
1352                   (match_operand:V4HI 1 "nonimmediate_operand"))
1353                 (sign_extend:V4SI
1354                   (match_operand:V4HI 2 "nonimmediate_operand")))
1355               (const_vector:V4SI [(const_int 32768) (const_int 32768)
1356                                   (const_int 32768) (const_int 32768)]))
1357             (const_int 16))))]
1358   "TARGET_3DNOW"
1359   "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
1361 (define_insn "*mmx_pmulhrwv4hi3"
1362   [(set (match_operand:V4HI 0 "register_operand" "=y")
1363         (truncate:V4HI
1364           (lshiftrt:V4SI
1365             (plus:V4SI
1366               (mult:V4SI
1367                 (sign_extend:V4SI
1368                   (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
1369                 (sign_extend:V4SI
1370                   (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
1371               (const_vector:V4SI [(const_int 32768) (const_int 32768)
1372                                   (const_int 32768) (const_int 32768)]))
1373             (const_int 16))))]
1374   "TARGET_3DNOW && ix86_binary_operator_ok (MULT, V4HImode, operands)"
1375   "pmulhrw\t{%2, %0|%0, %2}"
1376   [(set_attr "type" "mmxmul")
1377    (set_attr "prefix_extra" "1")
1378    (set_attr "mode" "DI")])
1380 (define_expand "sse2_umulv1siv1di3"
1381   [(set (match_operand:V1DI 0 "register_operand")
1382         (mult:V1DI
1383           (zero_extend:V1DI
1384             (vec_select:V1SI
1385               (match_operand:V2SI 1 "register_mmxmem_operand")
1386               (parallel [(const_int 0)])))
1387           (zero_extend:V1DI
1388             (vec_select:V1SI
1389               (match_operand:V2SI 2 "register_mmxmem_operand")
1390               (parallel [(const_int 0)])))))]
1391   "(TARGET_MMX || TARGET_MMX_WITH_SSE) && TARGET_SSE2"
1392   "ix86_fixup_binary_operands_no_copy (MULT, V2SImode, operands);")
1394 (define_insn "*sse2_umulv1siv1di3"
1395   [(set (match_operand:V1DI 0 "register_operand" "=y,x,Yv")
1396         (mult:V1DI
1397           (zero_extend:V1DI
1398             (vec_select:V1SI
1399               (match_operand:V2SI 1 "register_mmxmem_operand" "%0,0,Yv")
1400               (parallel [(const_int 0)])))
1401           (zero_extend:V1DI
1402             (vec_select:V1SI
1403               (match_operand:V2SI 2 "register_mmxmem_operand" "ym,x,Yv")
1404               (parallel [(const_int 0)])))))]
1405   "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1406    && TARGET_SSE2
1407    && ix86_binary_operator_ok (MULT, V2SImode, operands)"
1408   "@
1409    pmuludq\t{%2, %0|%0, %2}
1410    pmuludq\t{%2, %0|%0, %2}
1411    vpmuludq\t{%2, %1, %0|%0, %1, %2}"
1412   [(set_attr "isa" "*,sse2_noavx,avx")
1413    (set_attr "mmx_isa" "native,*,*")
1414    (set_attr "type" "mmxmul,ssemul,ssemul")
1415    (set_attr "mode" "DI,TI,TI")])
1417 (define_expand "mmx_<code>v4hi3"
1418   [(set (match_operand:V4HI 0 "register_operand")
1419         (smaxmin:V4HI
1420           (match_operand:V4HI 1 "register_mmxmem_operand")
1421           (match_operand:V4HI 2 "register_mmxmem_operand")))]
1422   "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1423    && (TARGET_SSE || TARGET_3DNOW_A)"
1424   "ix86_fixup_binary_operands_no_copy (<CODE>, V4HImode, operands);")
1426 (define_expand "<code>v4hi3"
1427   [(set (match_operand:V4HI 0 "register_operand")
1428         (smaxmin:V4HI
1429           (match_operand:V4HI 1 "register_operand")
1430           (match_operand:V4HI 2 "register_operand")))]
1431   "TARGET_MMX_WITH_SSE"
1432   "ix86_fixup_binary_operands_no_copy (<CODE>, V4HImode, operands);")
1434 (define_insn "*mmx_<code>v4hi3"
1435   [(set (match_operand:V4HI 0 "register_operand" "=y,x,Yv")
1436         (smaxmin:V4HI
1437           (match_operand:V4HI 1 "register_mmxmem_operand" "%0,0,Yv")
1438           (match_operand:V4HI 2 "register_mmxmem_operand" "ym,x,Yv")))]
1439   "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1440    && (TARGET_SSE || TARGET_3DNOW_A)
1441    && ix86_binary_operator_ok (<CODE>, V4HImode, operands)"
1442   "@
1443    p<maxmin_int>w\t{%2, %0|%0, %2}
1444    p<maxmin_int>w\t{%2, %0|%0, %2}
1445    vp<maxmin_int>w\t{%2, %1, %0|%0, %1, %2}"
1446   [(set_attr "isa" "*,sse2_noavx,avx")
1447    (set_attr "mmx_isa" "native,*,*")
1448    (set_attr "type" "mmxadd,sseiadd,sseiadd")
1449    (set_attr "mode" "DI,TI,TI")])
1451 (define_expand "mmx_<code>v8qi3"
1452   [(set (match_operand:V8QI 0 "register_operand")
1453         (umaxmin:V8QI
1454           (match_operand:V8QI 1 "register_mmxmem_operand")
1455           (match_operand:V8QI 2 "register_mmxmem_operand")))]
1456   "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1457    && (TARGET_SSE || TARGET_3DNOW_A)"
1458   "ix86_fixup_binary_operands_no_copy (<CODE>, V8QImode, operands);")
1460 (define_expand "<code>v8qi3"
1461   [(set (match_operand:V8QI 0 "register_operand")
1462         (umaxmin:V8QI
1463           (match_operand:V8QI 1 "register_operand")
1464           (match_operand:V8QI 2 "register_operand")))]
1465   "TARGET_MMX_WITH_SSE"
1466   "ix86_fixup_binary_operands_no_copy (<CODE>, V8QImode, operands);")
1468 (define_insn "*mmx_<code>v8qi3"
1469   [(set (match_operand:V8QI 0 "register_operand" "=y,x,Yv")
1470         (umaxmin:V8QI
1471           (match_operand:V8QI 1 "register_mmxmem_operand" "%0,0,Yv")
1472           (match_operand:V8QI 2 "register_mmxmem_operand" "ym,x,Yv")))]
1473   "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1474    && (TARGET_SSE || TARGET_3DNOW_A)
1475    && ix86_binary_operator_ok (<CODE>, V8QImode, operands)"
1476   "@
1477    p<maxmin_int>b\t{%2, %0|%0, %2}
1478    p<maxmin_int>b\t{%2, %0|%0, %2}
1479    vp<maxmin_int>b\t{%2, %1, %0|%0, %1, %2}"
1480   [(set_attr "isa" "*,sse2_noavx,avx")
1481    (set_attr "mmx_isa" "native,*,*")
1482    (set_attr "type" "mmxadd,sseiadd,sseiadd")
1483    (set_attr "mode" "DI,TI,TI")])
1485 (define_insn "mmx_ashr<mode>3"
1486   [(set (match_operand:MMXMODE24 0 "register_operand" "=y,x,Yv")
1487         (ashiftrt:MMXMODE24
1488           (match_operand:MMXMODE24 1 "register_operand" "0,0,Yv")
1489           (match_operand:DI 2 "nonmemory_operand" "yN,xN,YvN")))]
1490   "TARGET_MMX || TARGET_MMX_WITH_SSE"
1491   "@
1492    psra<mmxvecsize>\t{%2, %0|%0, %2}
1493    psra<mmxvecsize>\t{%2, %0|%0, %2}
1494    vpsra<mmxvecsize>\t{%2, %1, %0|%0, %1, %2}"
1495   [(set_attr "isa" "*,sse2_noavx,avx")
1496    (set_attr "mmx_isa" "native,*,*")
1497    (set_attr "type" "mmxshft,sseishft,sseishft")
1498    (set (attr "length_immediate")
1499      (if_then_else (match_operand 2 "const_int_operand")
1500        (const_string "1")
1501        (const_string "0")))
1502    (set_attr "mode" "DI,TI,TI")])
1504 (define_expand "ashr<mode>3"
1505   [(set (match_operand:MMXMODE24 0 "register_operand")
1506         (ashiftrt:MMXMODE24
1507           (match_operand:MMXMODE24 1 "register_operand")
1508           (match_operand:DI 2 "nonmemory_operand")))]
1509   "TARGET_MMX_WITH_SSE")
1511 (define_insn "mmx_<shift_insn><mode>3"
1512   [(set (match_operand:MMXMODE248 0 "register_operand" "=y,x,Yv")
1513         (any_lshift:MMXMODE248
1514           (match_operand:MMXMODE248 1 "register_operand" "0,0,Yv")
1515           (match_operand:DI 2 "nonmemory_operand" "yN,xN,YvN")))]
1516   "TARGET_MMX || TARGET_MMX_WITH_SSE"
1517   "@
1518    p<vshift><mmxvecsize>\t{%2, %0|%0, %2}
1519    p<vshift><mmxvecsize>\t{%2, %0|%0, %2}
1520    vp<vshift><mmxvecsize>\t{%2, %1, %0|%0, %1, %2}"
1521   [(set_attr "isa" "*,sse2_noavx,avx")
1522    (set_attr "mmx_isa" "native,*,*")
1523    (set_attr "type" "mmxshft,sseishft,sseishft")
1524    (set (attr "length_immediate")
1525      (if_then_else (match_operand 2 "const_int_operand")
1526        (const_string "1")
1527        (const_string "0")))
1528    (set_attr "mode" "DI,TI,TI")])
1530 (define_expand "<shift_insn><mode>3"
1531   [(set (match_operand:MMXMODE248 0 "register_operand")
1532         (any_lshift:MMXMODE248
1533           (match_operand:MMXMODE248 1 "register_operand")
1534           (match_operand:DI 2 "nonmemory_operand")))]
1535   "TARGET_MMX_WITH_SSE")
1537 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1539 ;; Parallel integral comparisons
1541 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1543 (define_expand "mmx_eq<mode>3"
1544   [(set (match_operand:MMXMODEI 0 "register_operand")
1545         (eq:MMXMODEI
1546           (match_operand:MMXMODEI 1 "register_mmxmem_operand")
1547           (match_operand:MMXMODEI 2 "register_mmxmem_operand")))]
1548   "TARGET_MMX || TARGET_MMX_WITH_SSE"
1549   "ix86_fixup_binary_operands_no_copy (EQ, <MODE>mode, operands);")
1551 (define_insn "*mmx_eq<mode>3"
1552   [(set (match_operand:MMXMODEI 0 "register_operand" "=y,x,Yv")
1553         (eq:MMXMODEI
1554           (match_operand:MMXMODEI 1 "register_mmxmem_operand" "%0,0,Yv")
1555           (match_operand:MMXMODEI 2 "register_mmxmem_operand" "ym,x,Yv")))]
1556   "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1557    && ix86_binary_operator_ok (EQ, <MODE>mode, operands)"
1558   "@
1559    pcmpeq<mmxvecsize>\t{%2, %0|%0, %2}
1560    pcmpeq<mmxvecsize>\t{%2, %0|%0, %2}
1561    vpcmpeq<mmxvecsize>\t{%2, %1, %0|%0, %1, %2}"
1562   [(set_attr "isa" "*,sse2_noavx,avx")
1563    (set_attr "mmx_isa" "native,*,*")
1564    (set_attr "type" "mmxcmp,ssecmp,ssecmp")
1565    (set_attr "mode" "DI,TI,TI")])
1567 (define_insn "mmx_gt<mode>3"
1568   [(set (match_operand:MMXMODEI 0 "register_operand" "=y,x,Yv")
1569         (gt:MMXMODEI
1570           (match_operand:MMXMODEI 1 "register_operand" "0,0,Yv")
1571           (match_operand:MMXMODEI 2 "register_mmxmem_operand" "ym,x,Yv")))]
1572   "TARGET_MMX || TARGET_MMX_WITH_SSE"
1573   "@
1574    pcmpgt<mmxvecsize>\t{%2, %0|%0, %2}
1575    pcmpgt<mmxvecsize>\t{%2, %0|%0, %2}
1576    vpcmpgt<mmxvecsize>\t{%2, %1, %0|%0, %1, %2}"
1577   [(set_attr "isa" "*,sse2_noavx,avx")
1578    (set_attr "mmx_isa" "native,*,*")
1579    (set_attr "type" "mmxcmp,ssecmp,ssecmp")
1580    (set_attr "mode" "DI,TI,TI")])
1582 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1584 ;; Parallel integral logical operations
1586 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1588 (define_expand "one_cmpl<mode>2"
1589   [(set (match_operand:MMXMODEI 0 "register_operand")
1590         (xor:MMXMODEI
1591           (match_operand:MMXMODEI 1 "register_operand")
1592           (match_dup 2)))]
1593   "TARGET_MMX_WITH_SSE"
1594   "operands[2] = force_reg (<MODE>mode, CONSTM1_RTX (<MODE>mode));")
1596 (define_insn "mmx_andnot<mode>3"
1597   [(set (match_operand:MMXMODEI 0 "register_operand" "=y,x,Yv")
1598         (and:MMXMODEI
1599           (not:MMXMODEI (match_operand:MMXMODEI 1 "register_operand" "0,0,Yv"))
1600           (match_operand:MMXMODEI 2 "register_mmxmem_operand" "ym,x,Yv")))]
1601   "TARGET_MMX || TARGET_MMX_WITH_SSE"
1602   "@
1603    pandn\t{%2, %0|%0, %2}
1604    pandn\t{%2, %0|%0, %2}
1605    vpandn\t{%2, %1, %0|%0, %1, %2}"
1606   [(set_attr "isa" "*,sse2_noavx,avx")
1607    (set_attr "mmx_isa" "native,*,*")
1608    (set_attr "type" "mmxadd,sselog,sselog")
1609    (set_attr "mode" "DI,TI,TI")])
1611 (define_expand "mmx_<code><mode>3"
1612   [(set (match_operand:MMXMODEI 0 "register_operand")
1613         (any_logic:MMXMODEI
1614           (match_operand:MMXMODEI 1 "register_mmxmem_operand")
1615           (match_operand:MMXMODEI 2 "register_mmxmem_operand")))]
1616   "TARGET_MMX || TARGET_MMX_WITH_SSE"
1617   "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
1619 (define_expand "<code><mode>3"
1620   [(set (match_operand:MMXMODEI 0 "register_operand")
1621         (any_logic:MMXMODEI
1622           (match_operand:MMXMODEI 1 "register_operand")
1623           (match_operand:MMXMODEI 2 "register_operand")))]
1624   "TARGET_MMX_WITH_SSE"
1625   "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
1627 (define_insn "*mmx_<code><mode>3"
1628   [(set (match_operand:MMXMODEI 0 "register_operand" "=y,x,Yv")
1629         (any_logic:MMXMODEI
1630           (match_operand:MMXMODEI 1 "register_mmxmem_operand" "%0,0,Yv")
1631           (match_operand:MMXMODEI 2 "register_mmxmem_operand" "ym,x,Yv")))]
1632   "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1633    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
1634   "@
1635    p<logic>\t{%2, %0|%0, %2}
1636    p<logic>\t{%2, %0|%0, %2}
1637    vp<logic>\t{%2, %1, %0|%0, %1, %2}"
1638   [(set_attr "isa" "*,sse2_noavx,avx")
1639    (set_attr "mmx_isa" "native,*,*")
1640    (set_attr "type" "mmxadd,sselog,sselog")
1641    (set_attr "mode" "DI,TI,TI")])
1643 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1645 ;; Parallel integral element swizzling
1647 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1649 ;; Used in signed and unsigned truncations with saturation.
1650 (define_code_iterator any_s_truncate [ss_truncate us_truncate])
1651 ;; Instruction suffix for truncations with saturation.
1652 (define_code_attr s_trunsuffix [(ss_truncate "s") (us_truncate "u")])
1654 (define_insn_and_split "mmx_pack<s_trunsuffix>swb"
1655   [(set (match_operand:V8QI 0 "register_operand" "=y,x,Yv")
1656         (vec_concat:V8QI
1657           (any_s_truncate:V4QI
1658             (match_operand:V4HI 1 "register_operand" "0,0,Yv"))
1659           (any_s_truncate:V4QI
1660             (match_operand:V4HI 2 "register_mmxmem_operand" "ym,x,Yv"))))]
1661   "TARGET_MMX || TARGET_MMX_WITH_SSE"
1662   "@
1663    pack<s_trunsuffix>swb\t{%2, %0|%0, %2}
1664    #
1665    #"
1666   "TARGET_SSE2 && reload_completed
1667    && SSE_REGNO_P (REGNO (operands[0]))"
1668   [(const_int 0)]
1669   "ix86_split_mmx_pack (operands, <any_s_truncate:CODE>); DONE;"
1670   [(set_attr "mmx_isa" "native,sse_noavx,avx")
1671    (set_attr "type" "mmxshft,sselog,sselog")
1672    (set_attr "mode" "DI,TI,TI")])
1674 (define_insn_and_split "mmx_packssdw"
1675   [(set (match_operand:V4HI 0 "register_operand" "=y,x,Yv")
1676         (vec_concat:V4HI
1677           (ss_truncate:V2HI
1678             (match_operand:V2SI 1 "register_operand" "0,0,Yv"))
1679           (ss_truncate:V2HI
1680             (match_operand:V2SI 2 "register_mmxmem_operand" "ym,x,Yv"))))]
1681   "TARGET_MMX || TARGET_MMX_WITH_SSE"
1682   "@
1683    packssdw\t{%2, %0|%0, %2}
1684    #
1685    #"
1686   "TARGET_SSE2 && reload_completed
1687    && SSE_REGNO_P (REGNO (operands[0]))"
1688   [(const_int 0)]
1689   "ix86_split_mmx_pack (operands, SS_TRUNCATE); DONE;"
1690   [(set_attr "mmx_isa" "native,sse_noavx,avx")
1691    (set_attr "type" "mmxshft,sselog,sselog")
1692    (set_attr "mode" "DI,TI,TI")])
1694 (define_insn_and_split "mmx_punpckhbw"
1695   [(set (match_operand:V8QI 0 "register_operand" "=y,x,Yv")
1696         (vec_select:V8QI
1697           (vec_concat:V16QI
1698             (match_operand:V8QI 1 "register_operand" "0,0,Yv")
1699             (match_operand:V8QI 2 "register_mmxmem_operand" "ym,x,Yv"))
1700           (parallel [(const_int 4) (const_int 12)
1701                      (const_int 5) (const_int 13)
1702                      (const_int 6) (const_int 14)
1703                      (const_int 7) (const_int 15)])))]
1704   "TARGET_MMX || TARGET_MMX_WITH_SSE"
1705   "@
1706    punpckhbw\t{%2, %0|%0, %2}
1707    #
1708    #"
1709   "TARGET_SSE2 && reload_completed
1710    && SSE_REGNO_P (REGNO (operands[0]))"
1711   [(const_int 0)]
1712   "ix86_split_mmx_punpck (operands, true); DONE;"
1713   [(set_attr "mmx_isa" "native,sse_noavx,avx")
1714    (set_attr "type" "mmxcvt,sselog,sselog")
1715    (set_attr "mode" "DI,TI,TI")])
1717 (define_insn_and_split "mmx_punpcklbw"
1718   [(set (match_operand:V8QI 0 "register_operand" "=y,x,Yv")
1719         (vec_select:V8QI
1720           (vec_concat:V16QI
1721             (match_operand:V8QI 1 "register_operand" "0,0,Yv")
1722             (match_operand:V8QI 2 "register_mmxmem_operand" "ym,x,Yv"))
1723           (parallel [(const_int 0) (const_int 8)
1724                      (const_int 1) (const_int 9)
1725                      (const_int 2) (const_int 10)
1726                      (const_int 3) (const_int 11)])))]
1727   "TARGET_MMX || TARGET_MMX_WITH_SSE"
1728   "@
1729    punpcklbw\t{%2, %0|%0, %k2}
1730    #
1731    #"
1732   "TARGET_SSE2 && reload_completed
1733    && SSE_REGNO_P (REGNO (operands[0]))"
1734   [(const_int 0)]
1735   "ix86_split_mmx_punpck (operands, false); DONE;"
1736   [(set_attr "mmx_isa" "native,sse_noavx,avx")
1737    (set_attr "type" "mmxcvt,sselog,sselog")
1738    (set_attr "mode" "DI,TI,TI")])
1740 (define_insn_and_split "mmx_punpckhwd"
1741   [(set (match_operand:V4HI 0 "register_operand" "=y,x,Yv")
1742         (vec_select:V4HI
1743           (vec_concat:V8HI
1744             (match_operand:V4HI 1 "register_operand" "0,0,Yv")
1745             (match_operand:V4HI 2 "register_mmxmem_operand" "ym,x,Yv"))
1746           (parallel [(const_int 2) (const_int 6)
1747                      (const_int 3) (const_int 7)])))]
1748   "TARGET_MMX || TARGET_MMX_WITH_SSE"
1749   "@
1750    punpckhwd\t{%2, %0|%0, %2}
1751    #
1752    #"
1753   "TARGET_SSE2 && reload_completed
1754    && SSE_REGNO_P (REGNO (operands[0]))"
1755   [(const_int 0)]
1756   "ix86_split_mmx_punpck (operands, true); DONE;"
1757   [(set_attr "mmx_isa" "native,sse_noavx,avx")
1758    (set_attr "type" "mmxcvt,sselog,sselog")
1759    (set_attr "mode" "DI,TI,TI")])
1761 (define_insn_and_split "mmx_punpcklwd"
1762   [(set (match_operand:V4HI 0 "register_operand" "=y,x,Yv")
1763         (vec_select:V4HI
1764           (vec_concat:V8HI
1765             (match_operand:V4HI 1 "register_operand" "0,0,Yv")
1766             (match_operand:V4HI 2 "register_mmxmem_operand" "ym,x,Yv"))
1767           (parallel [(const_int 0) (const_int 4)
1768                      (const_int 1) (const_int 5)])))]
1769   "TARGET_MMX || TARGET_MMX_WITH_SSE"
1770   "@
1771    punpcklwd\t{%2, %0|%0, %k2}
1772    #
1773    #"
1774   "TARGET_SSE2 && reload_completed
1775    && SSE_REGNO_P (REGNO (operands[0]))"
1776   [(const_int 0)]
1777   "ix86_split_mmx_punpck (operands, false); DONE;"
1778   [(set_attr "mmx_isa" "native,sse_noavx,avx")
1779    (set_attr "type" "mmxcvt,sselog,sselog")
1780    (set_attr "mode" "DI,TI,TI")])
1782 (define_insn_and_split "mmx_punpckhdq"
1783   [(set (match_operand:V2SI 0 "register_operand" "=y,x,Yv")
1784         (vec_select:V2SI
1785           (vec_concat:V4SI
1786             (match_operand:V2SI 1 "register_operand" "0,0,Yv")
1787             (match_operand:V2SI 2 "register_mmxmem_operand" "ym,x,Yv"))
1788           (parallel [(const_int 1)
1789                      (const_int 3)])))]
1790   "TARGET_MMX || TARGET_MMX_WITH_SSE"
1791   "@
1792    punpckhdq\t{%2, %0|%0, %2}
1793    #
1794    #"
1795   "TARGET_SSE2 && reload_completed
1796    && SSE_REGNO_P (REGNO (operands[0]))"
1797   [(const_int 0)]
1798   "ix86_split_mmx_punpck (operands, true); DONE;"
1799   [(set_attr "mmx_isa" "native,sse_noavx,avx")
1800    (set_attr "type" "mmxcvt,sselog,sselog")
1801    (set_attr "mode" "DI,TI,TI")])
1803 (define_insn_and_split "mmx_punpckldq"
1804   [(set (match_operand:V2SI 0 "register_operand" "=y,x,Yv")
1805         (vec_select:V2SI
1806           (vec_concat:V4SI
1807             (match_operand:V2SI 1 "register_operand" "0,0,Yv")
1808             (match_operand:V2SI 2 "register_mmxmem_operand" "ym,x,Yv"))
1809           (parallel [(const_int 0)
1810                      (const_int 2)])))]
1811   "TARGET_MMX || TARGET_MMX_WITH_SSE"
1812   "@
1813    punpckldq\t{%2, %0|%0, %k2}
1814    #
1815    #"
1816   "TARGET_SSE2 && reload_completed
1817    && SSE_REGNO_P (REGNO (operands[0]))"
1818   [(const_int 0)]
1819   "ix86_split_mmx_punpck (operands, false); DONE;"
1820   [(set_attr "mmx_isa" "native,sse_noavx,avx")
1821    (set_attr "type" "mmxcvt,sselog,sselog")
1822    (set_attr "mode" "DI,TI,TI")])
1824 (define_insn "*mmx_pinsrd"
1825   [(set (match_operand:V2SI 0 "register_operand" "=x,Yv")
1826         (vec_merge:V2SI
1827           (vec_duplicate:V2SI
1828             (match_operand:SI 2 "nonimmediate_operand" "rm,rm"))
1829           (match_operand:V2SI 1 "register_operand" "0,Yv")
1830           (match_operand:SI 3 "const_int_operand")))]
1831   "TARGET_MMX_WITH_SSE && TARGET_SSE4_1
1832    && ((unsigned) exact_log2 (INTVAL (operands[3]))
1833        < GET_MODE_NUNITS (V2SImode))"
1835   operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])));
1836   switch (which_alternative)
1837     {
1838     case 1:
1839       return "vpinsrd\t{%3, %2, %1, %0|%0, %1, %2, %3}";
1840     case 0:
1841       return "pinsrd\t{%3, %2, %0|%0, %2, %3}";
1842     default:
1843       gcc_unreachable ();
1844     }
1846   [(set_attr "isa" "noavx,avx")
1847    (set_attr "prefix_data16" "1")
1848    (set_attr "prefix_extra" "1")
1849    (set_attr "type" "sselog")
1850    (set_attr "length_immediate" "1")
1851    (set_attr "prefix" "orig,vex")
1852    (set_attr "mode" "TI")])
1854 (define_expand "mmx_pinsrw"
1855   [(set (match_operand:V4HI 0 "register_operand")
1856         (vec_merge:V4HI
1857           (vec_duplicate:V4HI
1858             (match_operand:SI 2 "nonimmediate_operand"))
1859           (match_operand:V4HI 1 "register_operand")
1860           (match_operand:SI 3 "const_0_to_3_operand")))]
1861   "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1862    && (TARGET_SSE || TARGET_3DNOW_A)"
1864   operands[2] = gen_lowpart (HImode, operands[2]);
1865   operands[3] = GEN_INT (1 << INTVAL (operands[3]));
1868 (define_insn "*mmx_pinsrw"
1869   [(set (match_operand:V4HI 0 "register_operand" "=y,x,Yv")
1870         (vec_merge:V4HI
1871           (vec_duplicate:V4HI
1872             (match_operand:HI 2 "nonimmediate_operand" "rm,rm,rm"))
1873           (match_operand:V4HI 1 "register_operand" "0,0,Yv")
1874           (match_operand:SI 3 "const_int_operand")))]
1875   "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1876    && (TARGET_SSE || TARGET_3DNOW_A)
1877    && ((unsigned) exact_log2 (INTVAL (operands[3]))
1878        < GET_MODE_NUNITS (V4HImode))"
1880   operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])));
1881   switch (which_alternative)
1882     {
1883     case 2:
1884       if (MEM_P (operands[2]))
1885         return "vpinsrw\t{%3, %2, %1, %0|%0, %1, %2, %3}";
1886       else
1887         return "vpinsrw\t{%3, %k2, %1, %0|%0, %1, %k2, %3}";
1888     case 1:
1889     case 0:
1890       if (MEM_P (operands[2]))
1891         return "pinsrw\t{%3, %2, %0|%0, %2, %3}";
1892       else
1893         return "pinsrw\t{%3, %k2, %0|%0, %k2, %3}";
1894     default:
1895       gcc_unreachable ();
1896     }
1898   [(set_attr "isa" "*,sse2_noavx,avx")
1899    (set_attr "mmx_isa" "native,*,*")
1900    (set_attr "type" "mmxcvt,sselog,sselog")
1901    (set_attr "length_immediate" "1")
1902    (set_attr "mode" "DI,TI,TI")])
1904 (define_insn "*mmx_pinsrb"
1905   [(set (match_operand:V8QI 0 "register_operand" "=x,Yv")
1906         (vec_merge:V8QI
1907           (vec_duplicate:V8QI
1908             (match_operand:QI 2 "nonimmediate_operand" "rm,rm"))
1909           (match_operand:V8QI 1 "register_operand" "0,Yv")
1910           (match_operand:SI 3 "const_int_operand")))]
1911   "TARGET_MMX_WITH_SSE && TARGET_SSE4_1
1912    && ((unsigned) exact_log2 (INTVAL (operands[3]))
1913        < GET_MODE_NUNITS (V8QImode))"
1915   operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])));
1916   switch (which_alternative)
1917     {
1918     case 1:
1919       if (MEM_P (operands[2]))
1920         return "vpinsrb\t{%3, %2, %1, %0|%0, %1, %2, %3}";
1921       else
1922         return "vpinsrb\t{%3, %k2, %1, %0|%0, %1, %k2, %3}";
1923     case 0:
1924       if (MEM_P (operands[2]))
1925         return "pinsrb\t{%3, %2, %0|%0, %2, %3}";
1926       else
1927         return "pinsrb\t{%3, %k2, %0|%0, %k2, %3}";
1928     default:
1929       gcc_unreachable ();
1930     }
1932   [(set_attr "isa" "noavx,avx")
1933    (set_attr "type" "sselog")
1934    (set_attr "prefix_data16" "1")
1935    (set_attr "prefix_extra" "1")
1936    (set_attr "length_immediate" "1")
1937    (set_attr "prefix" "orig,vex")
1938    (set_attr "mode" "TI")])
1940 (define_insn "*mmx_pextrw"
1941   [(set (match_operand:HI 0 "register_sse4nonimm_operand" "=r,r,m")
1942         (vec_select:HI
1943           (match_operand:V4HI 1 "register_operand" "y,Yv,Yv")
1944           (parallel [(match_operand:SI 2 "const_0_to_3_operand" "n,n,n")])))]
1945   "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1946    && (TARGET_SSE || TARGET_3DNOW_A)"
1947   "@
1948    pextrw\t{%2, %1, %k0|%k0, %1, %2}
1949    %vpextrw\t{%2, %1, %k0|%k0, %1, %2}
1950    %vpextrw\t{%2, %1, %0|%0, %1, %2}"
1951   [(set_attr "isa" "*,sse2,sse4")
1952    (set_attr "mmx_isa" "native,*,*")
1953    (set_attr "type" "mmxcvt,sselog1,sselog1")
1954    (set_attr "length_immediate" "1")
1955    (set_attr "prefix" "orig,maybe_vex,maybe_vex")
1956    (set_attr "mode" "DI,TI,TI")])
1958 (define_insn "*mmx_pextrw_zext"
1959   [(set (match_operand:SWI48 0 "register_operand" "=r,r")
1960         (zero_extend:SWI48
1961           (vec_select:HI
1962             (match_operand:V4HI 1 "register_operand" "y,Yv")
1963             (parallel [(match_operand:SI 2 "const_0_to_3_operand" "n,n")]))))]
1964   "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1965    && (TARGET_SSE || TARGET_3DNOW_A)"
1966   "@
1967    pextrw\t{%2, %1, %k0|%k0, %1, %2}
1968    %vpextrw\t{%2, %1, %k0|%k0, %1, %2}"
1969   [(set_attr "isa" "*,sse2")
1970    (set_attr "mmx_isa" "native,*")
1971    (set_attr "type" "mmxcvt,sselog1")
1972    (set_attr "length_immediate" "1")
1973    (set_attr "prefix" "orig,maybe_vex")
1974    (set_attr "mode" "DI,TI")])
1976 (define_insn "*mmx_pextrb"
1977   [(set (match_operand:QI 0 "nonimmediate_operand" "=r,m")
1978         (vec_select:QI
1979           (match_operand:V8QI 1 "register_operand" "Yv,Yv")
1980           (parallel [(match_operand:SI 2 "const_0_to_7_operand" "n,n")])))]
1981   "TARGET_MMX_WITH_SSE && TARGET_SSE4_1"
1982   "@
1983    %vpextrb\t{%2, %1, %k0|%k0, %1, %2}
1984    %vpextrb\t{%2, %1, %0|%0, %1, %2}"
1985   [(set_attr "type" "sselog1")
1986    (set_attr "prefix_data16" "1")
1987    (set_attr "prefix_extra" "1")
1988    (set_attr "length_immediate" "1")
1989    (set_attr "prefix" "maybe_vex")
1990    (set_attr "mode" "TI")])
1992 (define_insn "*mmx_pextrb_zext"
1993   [(set (match_operand:SWI248 0 "register_operand" "=r")
1994         (zero_extend:SWI248
1995           (vec_select:QI
1996             (match_operand:V8QI 1 "register_operand" "Yv")
1997             (parallel [(match_operand:SI 2 "const_0_to_7_operand" "n")]))))]
1998   "TARGET_MMX_WITH_SSE && TARGET_SSE4_1"
1999   "%vpextrb\t{%2, %1, %k0|%k0, %1, %2}"
2000   [(set_attr "type" "sselog1")
2001    (set_attr "prefix_data16" "1")
2002    (set_attr "prefix_extra" "1")
2003    (set_attr "length_immediate" "1")
2004    (set_attr "prefix" "maybe_vex")
2005    (set_attr "mode" "TI")])
2007 (define_expand "mmx_pshufw"
2008   [(match_operand:V4HI 0 "register_operand")
2009    (match_operand:V4HI 1 "register_mmxmem_operand")
2010    (match_operand:SI 2 "const_int_operand")]
2011   "(TARGET_MMX || TARGET_MMX_WITH_SSE)
2012    && (TARGET_SSE || TARGET_3DNOW_A)"
2014   int mask = INTVAL (operands[2]);
2015   emit_insn (gen_mmx_pshufw_1 (operands[0], operands[1],
2016                                GEN_INT ((mask >> 0) & 3),
2017                                GEN_INT ((mask >> 2) & 3),
2018                                GEN_INT ((mask >> 4) & 3),
2019                                GEN_INT ((mask >> 6) & 3)));
2020   DONE;
2023 (define_insn "mmx_pshufw_1"
2024   [(set (match_operand:V4HI 0 "register_operand" "=y,xYw")
2025         (vec_select:V4HI
2026           (match_operand:V4HI 1 "register_mmxmem_operand" "ym,xYw")
2027           (parallel [(match_operand 2 "const_0_to_3_operand")
2028                      (match_operand 3 "const_0_to_3_operand")
2029                      (match_operand 4 "const_0_to_3_operand")
2030                      (match_operand 5 "const_0_to_3_operand")])))]
2031   "(TARGET_MMX || TARGET_MMX_WITH_SSE)
2032    && (TARGET_SSE || TARGET_3DNOW_A)"
2034   int mask = 0;
2035   mask |= INTVAL (operands[2]) << 0;
2036   mask |= INTVAL (operands[3]) << 2;
2037   mask |= INTVAL (operands[4]) << 4;
2038   mask |= INTVAL (operands[5]) << 6;
2039   operands[2] = GEN_INT (mask);
2041   switch (which_alternative)
2042     {
2043     case 0:
2044       return "pshufw\t{%2, %1, %0|%0, %1, %2}";
2045     case 1:
2046       return "%vpshuflw\t{%2, %1, %0|%0, %1, %2}";
2047     default:
2048       gcc_unreachable ();
2049     }
2051   [(set_attr "isa" "*,sse2")
2052    (set_attr "mmx_isa" "native,*")
2053    (set_attr "type" "mmxcvt,sselog1")
2054    (set_attr "length_immediate" "1")
2055    (set_attr "mode" "DI,TI")])
2057 (define_insn "*mmx_pshufd_1"
2058   [(set (match_operand:V2SI 0 "register_operand" "=Yv")
2059         (vec_select:V2SI
2060           (match_operand:V2SI 1 "register_operand" "Yv")
2061           (parallel [(match_operand 2 "const_0_to_1_operand")
2062                      (match_operand 3 "const_0_to_1_operand")])))]
2063   "TARGET_MMX_WITH_SSE"
2065   int mask = 0;
2066   mask |= INTVAL (operands[2]) << 0;
2067   mask |= INTVAL (operands[3]) << 2;
2068   mask |= 2 << 4;
2069   mask |= 3 << 6;
2070   operands[2] = GEN_INT (mask);
2072   return "%vpshufd\t{%2, %1, %0|%0, %1, %2}";
2074   [(set_attr "type" "sselog1")
2075    (set_attr "prefix_data16" "1")
2076    (set_attr "length_immediate" "1")
2077    (set_attr "mode" "TI")])
2079 (define_insn "mmx_pswapdv2si2"
2080   [(set (match_operand:V2SI 0 "register_operand" "=y,Yv")
2081         (vec_select:V2SI
2082           (match_operand:V2SI 1 "register_mmxmem_operand" "ym,Yv")
2083           (parallel [(const_int 1) (const_int 0)])))]
2084   "TARGET_3DNOW_A"
2085   "@
2086    pswapd\t{%1, %0|%0, %1}
2087    %vpshufd\t{$0xe1, %1, %0|%0, %1, 0xe1}";
2088   [(set_attr "isa" "*,sse2")
2089    (set_attr "mmx_isa" "native,*")
2090    (set_attr "type" "mmxcvt,sselog1")
2091    (set_attr "prefix_extra" "1,*")
2092    (set_attr "prefix_data16" "*,1")
2093    (set_attr "length_immediate" "*,1")
2094    (set_attr "mode" "DI,TI")])
2096 (define_insn "*vec_dupv4hi"
2097   [(set (match_operand:V4HI 0 "register_operand" "=y,xYw")
2098         (vec_duplicate:V4HI
2099           (truncate:HI
2100             (match_operand:SI 1 "register_operand" "0,xYw"))))]
2101   "(TARGET_MMX || TARGET_MMX_WITH_SSE)
2102    && (TARGET_SSE || TARGET_3DNOW_A)"
2103   "@
2104    pshufw\t{$0, %0, %0|%0, %0, 0}
2105    %vpshuflw\t{$0, %1, %0|%0, %1, 0}"
2106   [(set_attr "isa" "*,sse2")
2107    (set_attr "mmx_isa" "native,*")
2108    (set_attr "type" "mmxcvt,sselog1")
2109    (set_attr "length_immediate" "1")
2110    (set_attr "mode" "DI,TI")])
2113 (define_insn "*vec_dupv2si"
2114   [(set (match_operand:V2SI 0 "register_operand" "=y,Yv")
2115         (vec_duplicate:V2SI
2116           (match_operand:SI 1 "register_operand" "0,Yv")))]
2117   "TARGET_MMX || TARGET_MMX_WITH_SSE"
2118   "@
2119    punpckldq\t%0, %0
2120    %vpshufd\t{$0xe0, %1, %0|%0, %1, 0xe0}"
2121   [(set_attr "isa" "*,sse2")
2122    (set_attr "mmx_isa" "native,*")
2123    (set_attr "type" "mmxcvt,sselog1")
2124    (set_attr "prefix_data16" "*,1")
2125    (set_attr "length_immediate" "*,1")
2126    (set_attr "mode" "DI,TI")])
2128 (define_insn "*mmx_concatv2si"
2129   [(set (match_operand:V2SI 0 "register_operand"     "=y,y")
2130         (vec_concat:V2SI
2131           (match_operand:SI 1 "nonimmediate_operand" " 0,rm")
2132           (match_operand:SI 2 "nonimm_or_0_operand"  "ym,C")))]
2133   "TARGET_MMX && !TARGET_SSE"
2134   "@
2135    punpckldq\t{%2, %0|%0, %2}
2136    movd\t{%1, %0|%0, %1}"
2137   [(set_attr "type" "mmxcvt,mmxmov")
2138    (set_attr "mode" "DI")])
2140 (define_expand "vec_setv2si"
2141   [(match_operand:V2SI 0 "register_operand")
2142    (match_operand:SI 1 "register_operand")
2143    (match_operand 2 "const_int_operand")]
2144   "TARGET_MMX || TARGET_MMX_WITH_SSE"
2146   ix86_expand_vector_set (TARGET_MMX_WITH_SSE, operands[0], operands[1],
2147                           INTVAL (operands[2]));
2148   DONE;
2151 ;; Avoid combining registers from different units in a single alternative,
2152 ;; see comment above inline_secondary_memory_needed function in i386.c
2153 (define_insn_and_split "*vec_extractv2si_0"
2154   [(set (match_operand:SI 0 "nonimmediate_operand"     "=x,m,y, m,r,r")
2155         (vec_select:SI
2156           (match_operand:V2SI 1 "nonimmediate_operand" "xm,x,ym,y,m,x")
2157           (parallel [(const_int 0)])))]
2158   "(TARGET_MMX || TARGET_MMX_WITH_SSE)
2159    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2160   "#"
2161   "&& reload_completed"
2162   [(set (match_dup 0) (match_dup 1))]
2163   "operands[1] = gen_lowpart (SImode, operands[1]);"
2164   [(set_attr "isa" "*,*,*,*,*,sse2")
2165    (set_attr "mmx_isa" "*,*,native,native,*,*")
2166    (set (attr "preferred_for_speed")
2167      (cond [(eq_attr "alternative" "5")
2168               (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2169            ]
2170            (symbol_ref "true")))])
2172 (define_insn "*vec_extractv2si_0_zext_sse4"
2173   [(set (match_operand:DI 0 "register_operand" "=r,x")
2174         (zero_extend:DI
2175           (vec_select:SI
2176             (match_operand:V2SI 1 "register_operand" "x,x")
2177             (parallel [(const_int 0)]))))]
2178   "(TARGET_MMX || TARGET_MMX_WITH_SSE) && TARGET_SSE4_1"
2179   "#"
2180   [(set_attr "isa" "x64,*")
2181    (set (attr "preferred_for_speed")
2182      (cond [(eq_attr "alternative" "0")
2183               (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2184            ]
2185            (symbol_ref "true")))])
2187 (define_insn "*vec_extractv2si_0_zext"
2188   [(set (match_operand:DI 0 "register_operand" "=r")
2189         (zero_extend:DI
2190           (vec_select:SI
2191             (match_operand:V2SI 1 "register_operand" "x")
2192             (parallel [(const_int 0)]))))]
2193   "(TARGET_MMX || TARGET_MMX_WITH_SSE)
2194    && TARGET_64BIT && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_FROM_VEC"
2195   "#")
2197 (define_split
2198   [(set (match_operand:DI 0 "register_operand")
2199         (zero_extend:DI
2200           (vec_select:SI
2201             (match_operand:V2SI 1 "register_operand")
2202             (parallel [(const_int 0)]))))]
2203   "(TARGET_MMX || TARGET_MMX_WITH_SSE)
2204    && TARGET_SSE2 && reload_completed"
2205   [(set (match_dup 0) (zero_extend:DI (match_dup 1)))]
2206   "operands[1] = gen_lowpart (SImode, operands[1]);")
2208 ;; Avoid combining registers from different units in a single alternative,
2209 ;; see comment above inline_secondary_memory_needed function in i386.c
2210 (define_insn "*vec_extractv2si_1"
2211   [(set (match_operand:SI 0 "nonimmediate_operand"     "=y,rm,x,x,y,x,r")
2212         (vec_select:SI
2213           (match_operand:V2SI 1 "nonimmediate_operand" " 0,x ,x,0,o,o,o")
2214           (parallel [(const_int 1)])))]
2215   "(TARGET_MMX || TARGET_MMX_WITH_SSE)
2216    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2217   "@
2218    punpckhdq\t%0, %0
2219    %vpextrd\t{$1, %1, %0|%0, %1, 1}
2220    %vpshufd\t{$0xe5, %1, %0|%0, %1, 0xe5}
2221    shufps\t{$0xe5, %0, %0|%0, %0, 0xe5}
2222    #
2223    #
2224    #"
2225   [(set_attr "isa" "*,sse4,sse2,noavx,*,*,*")
2226    (set_attr "mmx_isa" "native,*,*,*,native,*,*")
2227    (set_attr "type" "mmxcvt,ssemov,sseshuf1,sseshuf1,mmxmov,ssemov,imov")
2228    (set (attr "length_immediate")
2229      (if_then_else (eq_attr "alternative" "1,2,3")
2230                    (const_string "1")
2231                    (const_string "*")))
2232    (set_attr "prefix" "orig,maybe_vex,maybe_vex,orig,orig,orig,orig")
2233    (set_attr "mode" "DI,TI,TI,V4SF,SI,SI,SI")])
2235 (define_split
2236   [(set (match_operand:SI 0 "register_operand")
2237         (vec_select:SI
2238           (match_operand:V2SI 1 "memory_operand")
2239           (parallel [(const_int 1)])))]
2240   "(TARGET_MMX || TARGET_MMX_WITH_SSE) && reload_completed"
2241   [(set (match_dup 0) (match_dup 1))]
2242   "operands[1] = adjust_address (operands[1], SImode, 4);")
2244 (define_insn "*vec_extractv2si_1_zext"
2245   [(set (match_operand:DI 0 "register_operand" "=r")
2246         (zero_extend:DI
2247           (vec_select:SI
2248             (match_operand:V2SI 1 "register_operand" "x")
2249             (parallel [(const_int 1)]))))]
2250   "(TARGET_MMX || TARGET_MMX_WITH_SSE)
2251    && TARGET_64BIT && TARGET_SSE4_1"
2252   "%vpextrd\t{$1, %1, %k0|%k0, %1, 1}"
2253   [(set_attr "type" "sselog1")
2254    (set_attr "prefix_extra" "1")
2255    (set_attr "length_immediate" "1")
2256    (set_attr "prefix" "maybe_vex")
2257    (set_attr "mode" "TI")])
2259 (define_insn_and_split "*vec_extractv2si_zext_mem"
2260   [(set (match_operand:DI 0 "register_operand" "=y,x,r")
2261         (zero_extend:DI
2262           (vec_select:SI
2263             (match_operand:V2SI 1 "memory_operand" "o,o,o")
2264             (parallel [(match_operand:SI 2 "const_0_to_1_operand")]))))]
2265   "(TARGET_MMX || TARGET_MMX_WITH_SSE) && TARGET_64BIT"
2266   "#"
2267   "&& reload_completed"
2268   [(set (match_dup 0) (zero_extend:DI (match_dup 1)))]
2270   operands[1] = adjust_address (operands[1], SImode, INTVAL (operands[2]) * 4);
2272   [(set_attr "isa" "*,sse2,*")
2273    (set_attr "mmx_isa" "native,*,*")])
2275 (define_expand "vec_extractv2sisi"
2276   [(match_operand:SI 0 "register_operand")
2277    (match_operand:V2SI 1 "register_operand")
2278    (match_operand 2 "const_int_operand")]
2279   "TARGET_MMX || TARGET_MMX_WITH_SSE"
2281   ix86_expand_vector_extract (TARGET_MMX_WITH_SSE, operands[0],
2282                               operands[1], INTVAL (operands[2]));
2283   DONE;
2286 (define_expand "vec_initv2sisi"
2287   [(match_operand:V2SI 0 "register_operand")
2288    (match_operand 1)]
2289   "(TARGET_MMX || TARGET_MMX_WITH_SSE) && TARGET_SSE"
2291   ix86_expand_vector_init (TARGET_MMX_WITH_SSE, operands[0],
2292                            operands[1]);
2293   DONE;
2296 (define_expand "vec_setv4hi"
2297   [(match_operand:V4HI 0 "register_operand")
2298    (match_operand:HI 1 "register_operand")
2299    (match_operand 2 "const_int_operand")]
2300   "TARGET_MMX || TARGET_MMX_WITH_SSE"
2302   ix86_expand_vector_set (TARGET_MMX_WITH_SSE, operands[0], operands[1],
2303                           INTVAL (operands[2]));
2304   DONE;
2307 (define_expand "vec_extractv4hihi"
2308   [(match_operand:HI 0 "register_operand")
2309    (match_operand:V4HI 1 "register_operand")
2310    (match_operand 2 "const_int_operand")]
2311   "TARGET_MMX || TARGET_MMX_WITH_SSE"
2313   ix86_expand_vector_extract (TARGET_MMX_WITH_SSE, operands[0],
2314                               operands[1], INTVAL (operands[2]));
2315   DONE;
2318 (define_expand "vec_initv4hihi"
2319   [(match_operand:V4HI 0 "register_operand")
2320    (match_operand 1)]
2321   "(TARGET_MMX || TARGET_MMX_WITH_SSE) && TARGET_SSE"
2323   ix86_expand_vector_init (TARGET_MMX_WITH_SSE, operands[0],
2324                            operands[1]);
2325   DONE;
2328 (define_expand "vec_setv8qi"
2329   [(match_operand:V8QI 0 "register_operand")
2330    (match_operand:QI 1 "register_operand")
2331    (match_operand 2 "const_int_operand")]
2332   "TARGET_MMX || TARGET_MMX_WITH_SSE"
2334   ix86_expand_vector_set (TARGET_MMX_WITH_SSE, operands[0], operands[1],
2335                           INTVAL (operands[2]));
2336   DONE;
2339 (define_expand "vec_extractv8qiqi"
2340   [(match_operand:QI 0 "register_operand")
2341    (match_operand:V8QI 1 "register_operand")
2342    (match_operand 2 "const_int_operand")]
2343   "TARGET_MMX || TARGET_MMX_WITH_SSE"
2345   ix86_expand_vector_extract (TARGET_MMX_WITH_SSE, operands[0],
2346                               operands[1], INTVAL (operands[2]));
2347   DONE;
2350 (define_expand "vec_initv8qiqi"
2351   [(match_operand:V8QI 0 "register_operand")
2352    (match_operand 1)]
2353   "(TARGET_MMX || TARGET_MMX_WITH_SSE) && TARGET_SSE"
2355   ix86_expand_vector_init (TARGET_MMX_WITH_SSE, operands[0],
2356                            operands[1]);
2357   DONE;
2360 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2362 ;; Miscellaneous
2364 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2366 (define_expand "mmx_uavg<mode>3"
2367   [(set (match_operand:MMXMODE12 0 "register_operand")
2368         (truncate:MMXMODE12
2369           (lshiftrt:<mmxdoublemode>
2370             (plus:<mmxdoublemode>
2371               (plus:<mmxdoublemode>
2372                 (zero_extend:<mmxdoublemode>
2373                   (match_operand:MMXMODE12 1 "register_mmxmem_operand"))
2374                 (zero_extend:<mmxdoublemode>
2375                   (match_operand:MMXMODE12 2 "register_mmxmem_operand")))
2376               (match_dup 3))
2377             (const_int 1))))]
2378   "(TARGET_MMX || TARGET_MMX_WITH_SSE)
2379    && (TARGET_SSE || TARGET_3DNOW)"
2381   operands[3] = CONST1_RTX(<mmxdoublemode>mode);
2382   ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
2385 (define_insn "*mmx_uavgv8qi3"
2386   [(set (match_operand:V8QI 0 "register_operand" "=y,x,Yv")
2387         (truncate:V8QI
2388           (lshiftrt:V8HI
2389             (plus:V8HI
2390               (plus:V8HI
2391                 (zero_extend:V8HI
2392                   (match_operand:V8QI 1 "register_mmxmem_operand" "%0,0,Yv"))
2393                 (zero_extend:V8HI
2394                   (match_operand:V8QI 2 "register_mmxmem_operand" "ym,x,Yv")))
2395               (const_vector:V8HI [(const_int 1) (const_int 1)
2396                                   (const_int 1) (const_int 1)
2397                                   (const_int 1) (const_int 1)
2398                                   (const_int 1) (const_int 1)]))
2399             (const_int 1))))]
2400   "(TARGET_MMX || TARGET_MMX_WITH_SSE)
2401    && (TARGET_SSE || TARGET_3DNOW)
2402    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
2404   switch (which_alternative)
2405     {
2406     case 2:
2407       return "vpavgb\t{%2, %1, %0|%0, %1, %2}";
2408     case 1:
2409     case 0:
2410       /* These two instructions have the same operation, but their encoding
2411          is different.  Prefer the one that is de facto standard.  */
2412       if (TARGET_SSE || TARGET_3DNOW_A)
2413         return "pavgb\t{%2, %0|%0, %2}";
2414       else
2415         return "pavgusb\t{%2, %0|%0, %2}";
2416       default:
2417         gcc_unreachable ();
2418     }
2420   [(set_attr "isa" "*,sse2_noavx,avx")
2421    (set_attr "mmx_isa" "native,*,*")
2422    (set_attr "type" "mmxshft,sseiadd,sseiadd")
2423    (set (attr "prefix_extra")
2424      (if_then_else
2425        (not (ior (match_test "TARGET_SSE")
2426                  (match_test "TARGET_3DNOW_A")))
2427        (const_string "1")
2428        (const_string "*")))
2429    (set_attr "mode" "DI,TI,TI")])
2431 (define_insn "*mmx_uavgv4hi3"
2432   [(set (match_operand:V4HI 0 "register_operand" "=y,x,Yv")
2433         (truncate:V4HI
2434           (lshiftrt:V4SI
2435             (plus:V4SI
2436               (plus:V4SI
2437                 (zero_extend:V4SI
2438                   (match_operand:V4HI 1 "register_mmxmem_operand" "%0,0,Yv"))
2439                 (zero_extend:V4SI
2440                   (match_operand:V4HI 2 "register_mmxmem_operand" "ym,x,Yv")))
2441               (const_vector:V4SI [(const_int 1) (const_int 1)
2442                                   (const_int 1) (const_int 1)]))
2443             (const_int 1))))]
2444   "(TARGET_MMX || TARGET_MMX_WITH_SSE)
2445    && (TARGET_SSE || TARGET_3DNOW_A)
2446    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
2447   "@
2448    pavgw\t{%2, %0|%0, %2}
2449    pavgw\t{%2, %0|%0, %2}
2450    vpavgw\t{%2, %1, %0|%0, %1, %2}"
2451   [(set_attr "isa" "*,sse2_noavx,avx")
2452    (set_attr "mmx_isa" "native,*,*")
2453    (set_attr "type" "mmxshft,sseiadd,sseiadd")
2454    (set_attr "mode" "DI,TI,TI")])
2456 (define_expand "uavg<mode>3_ceil"
2457   [(set (match_operand:MMXMODE12 0 "register_operand")
2458         (truncate:MMXMODE12
2459           (lshiftrt:<mmxdoublemode>
2460             (plus:<mmxdoublemode>
2461               (plus:<mmxdoublemode>
2462                 (zero_extend:<mmxdoublemode>
2463                   (match_operand:MMXMODE12 1 "register_operand"))
2464                 (zero_extend:<mmxdoublemode>
2465                   (match_operand:MMXMODE12 2 "register_operand")))
2466               (match_dup 3))
2467             (const_int 1))))]
2468   "TARGET_MMX_WITH_SSE"
2470   operands[3] = CONST1_RTX(<mmxdoublemode>mode);
2471   ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
2474 (define_insn "mmx_psadbw"
2475   [(set (match_operand:V1DI 0 "register_operand" "=y,x,Yv")
2476         (unspec:V1DI [(match_operand:V8QI 1 "register_operand" "0,0,Yv")
2477                       (match_operand:V8QI 2 "register_mmxmem_operand" "ym,x,Yv")]
2478                      UNSPEC_PSADBW))]
2479   "(TARGET_MMX || TARGET_MMX_WITH_SSE)
2480    && (TARGET_SSE || TARGET_3DNOW_A)"
2481   "@
2482    psadbw\t{%2, %0|%0, %2}
2483    psadbw\t{%2, %0|%0, %2}
2484    vpsadbw\t{%2, %1, %0|%0, %1, %2}"
2485   [(set_attr "isa" "*,sse2_noavx,avx")
2486    (set_attr "mmx_isa" "native,*,*")
2487    (set_attr "type" "mmxshft,sseiadd,sseiadd")
2488    (set_attr "mode" "DI,TI,TI")])
2490 (define_expand "reduc_plus_scal_v8qi"
2491  [(plus:V8QI
2492     (match_operand:QI 0 "register_operand")
2493     (match_operand:V8QI 1 "register_operand"))]
2494  "TARGET_MMX_WITH_SSE"
2496   rtx tmp = gen_reg_rtx (V8QImode);
2497   emit_move_insn (tmp, CONST0_RTX (V8QImode));
2498   rtx tmp2 = gen_reg_rtx (V1DImode);
2499   emit_insn (gen_mmx_psadbw (tmp2, operands[1], tmp));
2500   tmp2 = gen_lowpart (V8QImode, tmp2);
2501   emit_insn (gen_vec_extractv8qiqi (operands[0], tmp2, const0_rtx));
2502   DONE;
2505 (define_expand "usadv8qi"
2506   [(match_operand:V2SI 0 "register_operand")
2507    (match_operand:V8QI 1 "register_operand")
2508    (match_operand:V8QI 2 "register_operand")
2509    (match_operand:V2SI 3 "register_operand")]
2510   "TARGET_MMX_WITH_SSE"
2512   rtx t1 = gen_reg_rtx (V1DImode);
2513   rtx t2 = gen_reg_rtx (V2SImode);
2514   emit_insn (gen_mmx_psadbw (t1, operands[1], operands[2]));
2515   convert_move (t2, t1, 0);
2516   emit_insn (gen_addv2si3 (operands[0], t2, operands[3]));
2517   DONE;
2520 (define_insn_and_split "mmx_pmovmskb"
2521   [(set (match_operand:SI 0 "register_operand" "=r,r")
2522         (unspec:SI [(match_operand:V8QI 1 "register_operand" "y,x")]
2523                    UNSPEC_MOVMSK))]
2524   "(TARGET_MMX || TARGET_MMX_WITH_SSE)
2525    && (TARGET_SSE || TARGET_3DNOW_A)"
2526   "@
2527    pmovmskb\t{%1, %0|%0, %1}
2528    #"
2529   "TARGET_SSE2 && reload_completed
2530    && SSE_REGNO_P (REGNO (operands[1]))"
2531   [(set (match_dup 0)
2532         (unspec:SI [(match_dup 1)] UNSPEC_MOVMSK))
2533    (set (match_dup 0)
2534         (zero_extend:SI (match_dup 2)))]
2536   /* Generate SSE pmovmskb and zero-extend from QImode to SImode.  */
2537   operands[1] = lowpart_subreg (V16QImode, operands[1],
2538                                 GET_MODE (operands[1]));
2539   operands[2] = lowpart_subreg (QImode, operands[0],
2540                                 GET_MODE (operands[0]));
2542   [(set_attr "mmx_isa" "native,sse")
2543    (set_attr "type" "mmxcvt,ssemov")
2544    (set_attr "mode" "DI,TI")])
2546 (define_expand "mmx_maskmovq"
2547   [(set (match_operand:V8QI 0 "memory_operand")
2548         (unspec:V8QI [(match_operand:V8QI 1 "register_operand")
2549                       (match_operand:V8QI 2 "register_operand")
2550                       (match_dup 0)]
2551                      UNSPEC_MASKMOV))]
2552   "TARGET_SSE || TARGET_3DNOW_A")
2554 (define_insn "*mmx_maskmovq"
2555   [(set (mem:V8QI (match_operand:P 0 "register_operand" "D"))
2556         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
2557                       (match_operand:V8QI 2 "register_operand" "y")
2558                       (mem:V8QI (match_dup 0))]
2559                      UNSPEC_MASKMOV))]
2560   "TARGET_SSE || TARGET_3DNOW_A"
2561   ;; @@@ check ordering of operands in intel/nonintel syntax
2562   "maskmovq\t{%2, %1|%1, %2}"
2563   [(set_attr "type" "mmxcvt")
2564    (set_attr "znver1_decode" "vector")
2565    (set_attr "mode" "DI")])
2567 (define_int_iterator EMMS
2568   [(UNSPECV_EMMS "TARGET_MMX")
2569    (UNSPECV_FEMMS "TARGET_3DNOW")])
2571 (define_int_attr emms
2572   [(UNSPECV_EMMS "emms")
2573    (UNSPECV_FEMMS "femms")])
2575 (define_expand "mmx_<emms>"
2576   [(parallel
2577     [(unspec_volatile [(const_int 0)] EMMS)
2578       (clobber (reg:XF ST0_REG))
2579       (clobber (reg:XF ST1_REG))
2580       (clobber (reg:XF ST2_REG))
2581       (clobber (reg:XF ST3_REG))
2582       (clobber (reg:XF ST4_REG))
2583       (clobber (reg:XF ST5_REG))
2584       (clobber (reg:XF ST6_REG))
2585       (clobber (reg:XF ST7_REG))
2586       (clobber (reg:DI MM0_REG))
2587       (clobber (reg:DI MM1_REG))
2588       (clobber (reg:DI MM2_REG))
2589       (clobber (reg:DI MM3_REG))
2590       (clobber (reg:DI MM4_REG))
2591       (clobber (reg:DI MM5_REG))
2592       (clobber (reg:DI MM6_REG))
2593       (clobber (reg:DI MM7_REG))])]
2594   "TARGET_MMX || TARGET_MMX_WITH_SSE"
2596    if (!TARGET_MMX)
2597      {
2598        emit_insn (gen_nop ());
2599        DONE;
2600      }
2603 (define_insn "*mmx_<emms>"
2604   [(unspec_volatile [(const_int 0)] EMMS)
2605    (clobber (reg:XF ST0_REG))
2606    (clobber (reg:XF ST1_REG))
2607    (clobber (reg:XF ST2_REG))
2608    (clobber (reg:XF ST3_REG))
2609    (clobber (reg:XF ST4_REG))
2610    (clobber (reg:XF ST5_REG))
2611    (clobber (reg:XF ST6_REG))
2612    (clobber (reg:XF ST7_REG))
2613    (clobber (reg:DI MM0_REG))
2614    (clobber (reg:DI MM1_REG))
2615    (clobber (reg:DI MM2_REG))
2616    (clobber (reg:DI MM3_REG))
2617    (clobber (reg:DI MM4_REG))
2618    (clobber (reg:DI MM5_REG))
2619    (clobber (reg:DI MM6_REG))
2620    (clobber (reg:DI MM7_REG))]
2621   ""
2622   "<emms>"
2623   [(set_attr "type" "mmx")
2624    (set_attr "modrm" "0")
2625    (set_attr "memory" "none")])