Merge branch 'vendor/GCC50' - gcc 5.0 snapshot 1 FEB 2015
[dragonfly.git] / contrib / gcc-5.0 / gcc / config / i386 / mmx.md
1 ;; GCC machine description for MMX and 3dNOW! instructions
2 ;; Copyright (C) 2005-2015 Free Software Foundation, Inc.
3 ;;
4 ;; This file is part of GCC.
5 ;;
6 ;; GCC is free software; you can redistribute it and/or modify
7 ;; it under the terms of the GNU General Public License as published by
8 ;; the Free Software Foundation; either version 3, or (at your option)
9 ;; any later version.
10 ;;
11 ;; GCC is distributed in the hope that it will be useful,
12 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
13 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 ;; GNU General Public License for more details.
15 ;;
16 ;; You should have received a copy of the GNU General Public License
17 ;; along with GCC; see the file COPYING3.  If not see
18 ;; <http://www.gnu.org/licenses/>.
19
20 ;; The MMX and 3dNOW! patterns are in the same file because they use
21 ;; the same register file, and 3dNOW! adds a number of extensions to
22 ;; the base integer MMX isa.
23
24 ;; Note!  Except for the basic move instructions, *all* of these
25 ;; patterns are outside the normal optabs namespace.  This is because
26 ;; use of these registers requires the insertion of emms or femms
27 ;; instructions to return to normal fpu mode.  The compiler doesn't
28 ;; know how to do that itself, which means it's up to the user.  Which
29 ;; means that we should never use any of these patterns except at the
30 ;; direction of the user via a builtin.
31
32 (define_c_enum "unspec" [
33   UNSPEC_MOVNTQ
34   UNSPEC_PFRCP
35   UNSPEC_PFRCPIT1
36   UNSPEC_PFRCPIT2
37   UNSPEC_PFRSQRT
38   UNSPEC_PFRSQIT1
39 ])
40
41 (define_c_enum "unspecv" [
42   UNSPECV_EMMS
43   UNSPECV_FEMMS
44 ])
45
46 ;; 8 byte integral modes handled by MMX (and by extension, SSE)
47 (define_mode_iterator MMXMODEI [V8QI V4HI V2SI])
48 (define_mode_iterator MMXMODEI8 [V8QI V4HI V2SI V1DI])
49
50 ;; All 8-byte vector modes handled by MMX
51 (define_mode_iterator MMXMODE [V8QI V4HI V2SI V1DI V2SF])
52
53 ;; Mix-n-match
54 (define_mode_iterator MMXMODE12 [V8QI V4HI])
55 (define_mode_iterator MMXMODE24 [V4HI V2SI])
56 (define_mode_iterator MMXMODE248 [V4HI V2SI V1DI])
57
58 ;; Mapping from integer vector mode to mnemonic suffix
59 (define_mode_attr mmxvecsize [(V8QI "b") (V4HI "w") (V2SI "d") (V1DI "q")])
60
61 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
62 ;;
63 ;; Move patterns
64 ;;
65 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
66
67 ;; All of these patterns are enabled for MMX as well as 3dNOW.
68 ;; This is essential for maintaining stable calling conventions.
69
70 (define_expand "mov<mode>"
71   [(set (match_operand:MMXMODE 0 "nonimmediate_operand")
72         (match_operand:MMXMODE 1 "nonimmediate_operand"))]
73   "TARGET_MMX"
74 {
75   ix86_expand_vector_move (<MODE>mode, operands);
76   DONE;
77 })
78
79 (define_insn "*mov<mode>_internal"
80   [(set (match_operand:MMXMODE 0 "nonimmediate_operand"
81     "=r ,o ,r,r ,m ,?!y,!y,?!y,m  ,r   ,?!Ym,v,v,v,m,*x,*x,*x,m ,r ,Yi,!Ym,*Yi")
82         (match_operand:MMXMODE 1 "vector_move_operand"
83     "rCo,rC,C,rm,rC,C  ,!y,m  ,?!y,?!Yn,r   ,C,v,m,v,C ,*x,m ,*x,Yj,r ,*Yj,!Yn"))]
84   "TARGET_MMX
85    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
86 {
87   switch (get_attr_type (insn))
88     {
89     case TYPE_MULTI:
90       return "#";
91
92     case TYPE_IMOV:
93       if (get_attr_mode (insn) == MODE_SI)
94         return "mov{l}\t{%1, %k0|%k0, %1}";
95       else
96         return "mov{q}\t{%1, %0|%0, %1}";
97
98     case TYPE_MMX:
99       return "pxor\t%0, %0";
100
101     case TYPE_MMXMOV:
102       /* Handle broken assemblers that require movd instead of movq.  */
103       if (!HAVE_AS_IX86_INTERUNIT_MOVQ
104           && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
105         return "movd\t{%1, %0|%0, %1}";
106       return "movq\t{%1, %0|%0, %1}";
107
108     case TYPE_SSECVT:
109       if (SSE_REG_P (operands[0]))
110         return "movq2dq\t{%1, %0|%0, %1}";
111       else
112         return "movdq2q\t{%1, %0|%0, %1}";
113
114     case TYPE_SSELOG1:
115       return standard_sse_constant_opcode (insn, operands[1]);
116
117     case TYPE_SSEMOV:
118       switch (get_attr_mode (insn))
119         {
120         case MODE_DI:
121           /* Handle broken assemblers that require movd instead of movq.  */
122           if (!HAVE_AS_IX86_INTERUNIT_MOVQ
123               && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
124             return "%vmovd\t{%1, %0|%0, %1}";
125           return "%vmovq\t{%1, %0|%0, %1}";
126         case MODE_TI:
127           return "%vmovdqa\t{%1, %0|%0, %1}";
128         case MODE_XI:
129           return "vmovdqa64\t{%g1, %g0|%g0, %g1}";
130
131         case MODE_V2SF:
132           if (TARGET_AVX && REG_P (operands[0]))
133             return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
134           return "%vmovlps\t{%1, %0|%0, %1}";
135         case MODE_V4SF:
136           return "%vmovaps\t{%1, %0|%0, %1}";
137
138         default:
139           gcc_unreachable ();
140         }
141
142     default:
143       gcc_unreachable ();
144     }
145 }
146   [(set (attr "isa")
147      (cond [(eq_attr "alternative" "0,1")
148               (const_string "nox64")
149             (eq_attr "alternative" "2,3,4,9,10,11,12,13,14,19,20")
150               (const_string "x64")
151            ]
152            (const_string "*")))
153    (set (attr "type")
154      (cond [(eq_attr "alternative" "0,1")
155               (const_string "multi")
156             (eq_attr "alternative" "2,3,4")
157               (const_string "imov")
158             (eq_attr "alternative" "5")
159               (const_string "mmx")
160             (eq_attr "alternative" "6,7,8,9,10")
161               (const_string "mmxmov")
162             (eq_attr "alternative" "11,15")
163               (const_string "sselog1")
164             (eq_attr "alternative" "21,22")
165               (const_string "ssecvt")
166            ]
167            (const_string "ssemov")))
168    (set (attr "prefix_rex")
169      (if_then_else (eq_attr "alternative" "9,10,19,20")
170        (const_string "1")
171        (const_string "*")))
172    (set (attr "prefix")
173      (if_then_else (eq_attr "type" "sselog1,ssemov")
174        (const_string "maybe_vex")
175        (const_string "orig")))
176    (set (attr "prefix_data16")
177      (if_then_else
178        (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
179        (const_string "1")
180        (const_string "*")))
181    (set (attr "mode")
182      (cond [(eq_attr "alternative" "2")
183               (const_string "SI")
184             (eq_attr "alternative" "11,12,15,16")
185               (cond [(ior (match_operand 0 "ext_sse_reg_operand")
186                           (match_operand 1 "ext_sse_reg_operand"))
187                         (const_string "XI")
188                      (match_test "<MODE>mode == V2SFmode")
189                        (const_string "V4SF")
190                      (ior (not (match_test "TARGET_SSE2"))
191                           (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
192                        (const_string "V4SF")
193                      (match_test "TARGET_AVX")
194                        (const_string "TI")
195                      (match_test "optimize_function_for_size_p (cfun)")
196                        (const_string "V4SF")
197                     ]
198                     (const_string "TI"))
199
200             (and (eq_attr "alternative" "13,14,17,18")
201                  (ior (match_test "<MODE>mode == V2SFmode")
202                       (not (match_test "TARGET_SSE2"))))
203               (const_string "V2SF")
204            ]
205            (const_string "DI")))])
206
207 (define_split
208   [(set (match_operand:MMXMODE 0 "nonimmediate_operand")
209         (match_operand:MMXMODE 1 "general_operand"))]
210   "!TARGET_64BIT && reload_completed
211    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
212    && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
213   [(const_int 0)]
214   "ix86_split_long_move (operands); DONE;")
215
216 (define_expand "movmisalign<mode>"
217   [(set (match_operand:MMXMODE 0 "nonimmediate_operand")
218         (match_operand:MMXMODE 1 "nonimmediate_operand"))]
219   "TARGET_MMX"
220 {
221   ix86_expand_vector_move (<MODE>mode, operands);
222   DONE;
223 })
224
225 (define_insn "sse_movntq"
226   [(set (match_operand:DI 0 "memory_operand" "=m")
227         (unspec:DI [(match_operand:DI 1 "register_operand" "y")]
228                    UNSPEC_MOVNTQ))]
229   "TARGET_SSE || TARGET_3DNOW_A"
230   "movntq\t{%1, %0|%0, %1}"
231   [(set_attr "type" "mmxmov")
232    (set_attr "mode" "DI")])
233
234 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
235 ;;
236 ;; Parallel single-precision floating point arithmetic
237 ;;
238 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
239
240 (define_expand "mmx_addv2sf3"
241   [(set (match_operand:V2SF 0 "register_operand")
242         (plus:V2SF
243           (match_operand:V2SF 1 "nonimmediate_operand")
244           (match_operand:V2SF 2 "nonimmediate_operand")))]
245   "TARGET_3DNOW"
246   "ix86_fixup_binary_operands_no_copy (PLUS, V2SFmode, operands);")
247
248 (define_insn "*mmx_addv2sf3"
249   [(set (match_operand:V2SF 0 "register_operand" "=y")
250         (plus:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "%0")
251                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
252   "TARGET_3DNOW && ix86_binary_operator_ok (PLUS, V2SFmode, operands)"
253   "pfadd\t{%2, %0|%0, %2}"
254   [(set_attr "type" "mmxadd")
255    (set_attr "prefix_extra" "1")
256    (set_attr "mode" "V2SF")])
257
258 (define_expand "mmx_subv2sf3"
259   [(set (match_operand:V2SF 0 "register_operand")
260         (minus:V2SF (match_operand:V2SF 1 "register_operand")
261                     (match_operand:V2SF 2 "nonimmediate_operand")))]
262   "TARGET_3DNOW")
263
264 (define_expand "mmx_subrv2sf3"
265   [(set (match_operand:V2SF 0 "register_operand")
266         (minus:V2SF (match_operand:V2SF 2 "register_operand")
267                     (match_operand:V2SF 1 "nonimmediate_operand")))]
268   "TARGET_3DNOW")
269
270 (define_insn "*mmx_subv2sf3"
271   [(set (match_operand:V2SF 0 "register_operand" "=y,y")
272         (minus:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "0,ym")
273                     (match_operand:V2SF 2 "nonimmediate_operand" "ym,0")))]
274   "TARGET_3DNOW && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
275   "@
276    pfsub\t{%2, %0|%0, %2}
277    pfsubr\t{%1, %0|%0, %1}"
278   [(set_attr "type" "mmxadd")
279    (set_attr "prefix_extra" "1")
280    (set_attr "mode" "V2SF")])
281
282 (define_expand "mmx_mulv2sf3"
283   [(set (match_operand:V2SF 0 "register_operand")
284         (mult:V2SF (match_operand:V2SF 1 "nonimmediate_operand")
285                    (match_operand:V2SF 2 "nonimmediate_operand")))]
286   "TARGET_3DNOW"
287   "ix86_fixup_binary_operands_no_copy (MULT, V2SFmode, operands);")
288
289 (define_insn "*mmx_mulv2sf3"
290   [(set (match_operand:V2SF 0 "register_operand" "=y")
291         (mult:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "%0")
292                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
293   "TARGET_3DNOW && ix86_binary_operator_ok (MULT, V2SFmode, operands)"
294   "pfmul\t{%2, %0|%0, %2}"
295   [(set_attr "type" "mmxmul")
296    (set_attr "prefix_extra" "1")
297    (set_attr "mode" "V2SF")])
298
299 ;; ??? For !flag_finite_math_only, the representation with SMIN/SMAX
300 ;; isn't really correct, as those rtl operators aren't defined when
301 ;; applied to NaNs.  Hopefully the optimizers won't get too smart on us.
302
303 (define_expand "mmx_<code>v2sf3"
304   [(set (match_operand:V2SF 0 "register_operand")
305         (smaxmin:V2SF
306           (match_operand:V2SF 1 "nonimmediate_operand")
307           (match_operand:V2SF 2 "nonimmediate_operand")))]
308   "TARGET_3DNOW"
309 {
310   if (!flag_finite_math_only)
311     operands[1] = force_reg (V2SFmode, operands[1]);
312   ix86_fixup_binary_operands_no_copy (<CODE>, V2SFmode, operands);
313 })
314
315 (define_insn "*mmx_<code>v2sf3_finite"
316   [(set (match_operand:V2SF 0 "register_operand" "=y")
317         (smaxmin:V2SF
318           (match_operand:V2SF 1 "nonimmediate_operand" "%0")
319           (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
320   "TARGET_3DNOW && flag_finite_math_only
321    && ix86_binary_operator_ok (<CODE>, V2SFmode, operands)"
322   "pf<maxmin_float>\t{%2, %0|%0, %2}"
323   [(set_attr "type" "mmxadd")
324    (set_attr "prefix_extra" "1")
325    (set_attr "mode" "V2SF")])
326
327 (define_insn "*mmx_<code>v2sf3"
328   [(set (match_operand:V2SF 0 "register_operand" "=y")
329         (smaxmin:V2SF
330           (match_operand:V2SF 1 "register_operand" "0")
331           (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
332   "TARGET_3DNOW"
333   "pf<maxmin_float>\t{%2, %0|%0, %2}"
334   [(set_attr "type" "mmxadd")
335    (set_attr "prefix_extra" "1")
336    (set_attr "mode" "V2SF")])
337
338 (define_insn "mmx_rcpv2sf2"
339   [(set (match_operand:V2SF 0 "register_operand" "=y")
340         (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
341                      UNSPEC_PFRCP))]
342   "TARGET_3DNOW"
343   "pfrcp\t{%1, %0|%0, %1}"
344   [(set_attr "type" "mmx")
345    (set_attr "prefix_extra" "1")
346    (set_attr "mode" "V2SF")])
347
348 (define_insn "mmx_rcpit1v2sf3"
349   [(set (match_operand:V2SF 0 "register_operand" "=y")
350         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
351                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
352                      UNSPEC_PFRCPIT1))]
353   "TARGET_3DNOW"
354   "pfrcpit1\t{%2, %0|%0, %2}"
355   [(set_attr "type" "mmx")
356    (set_attr "prefix_extra" "1")
357    (set_attr "mode" "V2SF")])
358
359 (define_insn "mmx_rcpit2v2sf3"
360   [(set (match_operand:V2SF 0 "register_operand" "=y")
361         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
362                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
363                      UNSPEC_PFRCPIT2))]
364   "TARGET_3DNOW"
365   "pfrcpit2\t{%2, %0|%0, %2}"
366   [(set_attr "type" "mmx")
367    (set_attr "prefix_extra" "1")
368    (set_attr "mode" "V2SF")])
369
370 (define_insn "mmx_rsqrtv2sf2"
371   [(set (match_operand:V2SF 0 "register_operand" "=y")
372         (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
373                      UNSPEC_PFRSQRT))]
374   "TARGET_3DNOW"
375   "pfrsqrt\t{%1, %0|%0, %1}"
376   [(set_attr "type" "mmx")
377    (set_attr "prefix_extra" "1")
378    (set_attr "mode" "V2SF")])
379
380 (define_insn "mmx_rsqit1v2sf3"
381   [(set (match_operand:V2SF 0 "register_operand" "=y")
382         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
383                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
384                      UNSPEC_PFRSQIT1))]
385   "TARGET_3DNOW"
386   "pfrsqit1\t{%2, %0|%0, %2}"
387   [(set_attr "type" "mmx")
388    (set_attr "prefix_extra" "1")
389    (set_attr "mode" "V2SF")])
390
391 (define_insn "mmx_haddv2sf3"
392   [(set (match_operand:V2SF 0 "register_operand" "=y")
393         (vec_concat:V2SF
394           (plus:SF
395             (vec_select:SF
396               (match_operand:V2SF 1 "register_operand" "0")
397               (parallel [(const_int  0)]))
398             (vec_select:SF (match_dup 1) (parallel [(const_int 1)])))
399           (plus:SF
400             (vec_select:SF
401               (match_operand:V2SF 2 "nonimmediate_operand" "ym")
402               (parallel [(const_int  0)]))
403             (vec_select:SF (match_dup 2) (parallel [(const_int 1)])))))]
404   "TARGET_3DNOW"
405   "pfacc\t{%2, %0|%0, %2}"
406   [(set_attr "type" "mmxadd")
407    (set_attr "prefix_extra" "1")
408    (set_attr "mode" "V2SF")])
409
410 (define_insn "mmx_hsubv2sf3"
411   [(set (match_operand:V2SF 0 "register_operand" "=y")
412         (vec_concat:V2SF
413           (minus:SF
414             (vec_select:SF
415               (match_operand:V2SF 1 "register_operand" "0")
416               (parallel [(const_int  0)]))
417             (vec_select:SF (match_dup 1) (parallel [(const_int 1)])))
418           (minus:SF
419             (vec_select:SF
420               (match_operand:V2SF 2 "nonimmediate_operand" "ym")
421               (parallel [(const_int  0)]))
422             (vec_select:SF (match_dup 2) (parallel [(const_int 1)])))))]
423   "TARGET_3DNOW_A"
424   "pfnacc\t{%2, %0|%0, %2}"
425   [(set_attr "type" "mmxadd")
426    (set_attr "prefix_extra" "1")
427    (set_attr "mode" "V2SF")])
428
429 (define_insn "mmx_addsubv2sf3"
430   [(set (match_operand:V2SF 0 "register_operand" "=y")
431         (vec_merge:V2SF
432           (plus:V2SF
433             (match_operand:V2SF 1 "register_operand" "0")
434             (match_operand:V2SF 2 "nonimmediate_operand" "ym"))
435           (minus:V2SF (match_dup 1) (match_dup 2))
436           (const_int 1)))]
437   "TARGET_3DNOW_A"
438   "pfpnacc\t{%2, %0|%0, %2}"
439   [(set_attr "type" "mmxadd")
440    (set_attr "prefix_extra" "1")
441    (set_attr "mode" "V2SF")])
442
443 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
444 ;;
445 ;; Parallel single-precision floating point comparisons
446 ;;
447 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
448
449 (define_expand "mmx_eqv2sf3"
450   [(set (match_operand:V2SI 0 "register_operand")
451         (eq:V2SI (match_operand:V2SF 1 "nonimmediate_operand")
452                  (match_operand:V2SF 2 "nonimmediate_operand")))]
453   "TARGET_3DNOW"
454   "ix86_fixup_binary_operands_no_copy (EQ, V2SFmode, operands);")
455
456 (define_insn "*mmx_eqv2sf3"
457   [(set (match_operand:V2SI 0 "register_operand" "=y")
458         (eq:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "%0")
459                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
460   "TARGET_3DNOW && ix86_binary_operator_ok (EQ, V2SFmode, operands)"
461   "pfcmpeq\t{%2, %0|%0, %2}"
462   [(set_attr "type" "mmxcmp")
463    (set_attr "prefix_extra" "1")
464    (set_attr "mode" "V2SF")])
465
466 (define_insn "mmx_gtv2sf3"
467   [(set (match_operand:V2SI 0 "register_operand" "=y")
468         (gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
469                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
470   "TARGET_3DNOW"
471   "pfcmpgt\t{%2, %0|%0, %2}"
472   [(set_attr "type" "mmxcmp")
473    (set_attr "prefix_extra" "1")
474    (set_attr "mode" "V2SF")])
475
476 (define_insn "mmx_gev2sf3"
477   [(set (match_operand:V2SI 0 "register_operand" "=y")
478         (ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
479                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
480   "TARGET_3DNOW"
481   "pfcmpge\t{%2, %0|%0, %2}"
482   [(set_attr "type" "mmxcmp")
483    (set_attr "prefix_extra" "1")
484    (set_attr "mode" "V2SF")])
485
486 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
487 ;;
488 ;; Parallel single-precision floating point conversion operations
489 ;;
490 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
491
492 (define_insn "mmx_pf2id"
493   [(set (match_operand:V2SI 0 "register_operand" "=y")
494         (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
495   "TARGET_3DNOW"
496   "pf2id\t{%1, %0|%0, %1}"
497   [(set_attr "type" "mmxcvt")
498    (set_attr "prefix_extra" "1")
499    (set_attr "mode" "V2SF")])
500
501 (define_insn "mmx_pf2iw"
502   [(set (match_operand:V2SI 0 "register_operand" "=y")
503         (sign_extend:V2SI
504           (ss_truncate:V2HI
505             (fix:V2SI
506               (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
507   "TARGET_3DNOW_A"
508   "pf2iw\t{%1, %0|%0, %1}"
509   [(set_attr "type" "mmxcvt")
510    (set_attr "prefix_extra" "1")
511    (set_attr "mode" "V2SF")])
512
513 (define_insn "mmx_pi2fw"
514   [(set (match_operand:V2SF 0 "register_operand" "=y")
515         (float:V2SF
516           (sign_extend:V2SI
517             (truncate:V2HI
518               (match_operand:V2SI 1 "nonimmediate_operand" "ym")))))]
519   "TARGET_3DNOW_A"
520   "pi2fw\t{%1, %0|%0, %1}"
521   [(set_attr "type" "mmxcvt")
522    (set_attr "prefix_extra" "1")
523    (set_attr "mode" "V2SF")])
524
525 (define_insn "mmx_floatv2si2"
526   [(set (match_operand:V2SF 0 "register_operand" "=y")
527         (float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
528   "TARGET_3DNOW"
529   "pi2fd\t{%1, %0|%0, %1}"
530   [(set_attr "type" "mmxcvt")
531    (set_attr "prefix_extra" "1")
532    (set_attr "mode" "V2SF")])
533
534 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
535 ;;
536 ;; Parallel single-precision floating point element swizzling
537 ;;
538 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
539
540 (define_insn "mmx_pswapdv2sf2"
541   [(set (match_operand:V2SF 0 "register_operand" "=y")
542         (vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym")
543                          (parallel [(const_int 1) (const_int 0)])))]
544   "TARGET_3DNOW_A"
545   "pswapd\t{%1, %0|%0, %1}"
546   [(set_attr "type" "mmxcvt")
547    (set_attr "prefix_extra" "1")
548    (set_attr "mode" "V2SF")])
549
550 (define_insn "*vec_dupv2sf"
551   [(set (match_operand:V2SF 0 "register_operand" "=y")
552         (vec_duplicate:V2SF
553           (match_operand:SF 1 "register_operand" "0")))]
554   "TARGET_MMX"
555   "punpckldq\t%0, %0"
556   [(set_attr "type" "mmxcvt")
557    (set_attr "mode" "DI")])
558
559 (define_insn "*mmx_concatv2sf"
560   [(set (match_operand:V2SF 0 "register_operand"     "=y,y")
561         (vec_concat:V2SF
562           (match_operand:SF 1 "nonimmediate_operand" " 0,rm")
563           (match_operand:SF 2 "vector_move_operand"  "ym,C")))]
564   "TARGET_MMX && !TARGET_SSE"
565   "@
566    punpckldq\t{%2, %0|%0, %2}
567    movd\t{%1, %0|%0, %1}"
568   [(set_attr "type" "mmxcvt,mmxmov")
569    (set_attr "mode" "DI")])
570
571 (define_expand "vec_setv2sf"
572   [(match_operand:V2SF 0 "register_operand")
573    (match_operand:SF 1 "register_operand")
574    (match_operand 2 "const_int_operand")]
575   "TARGET_MMX"
576 {
577   ix86_expand_vector_set (false, operands[0], operands[1],
578                           INTVAL (operands[2]));
579   DONE;
580 })
581
582 ;; Avoid combining registers from different units in a single alternative,
583 ;; see comment above inline_secondary_memory_needed function in i386.c
584 (define_insn_and_split "*vec_extractv2sf_0"
585   [(set (match_operand:SF 0 "nonimmediate_operand"     "=x, m,y ,m,f,r")
586         (vec_select:SF
587           (match_operand:V2SF 1 "nonimmediate_operand" " xm,x,ym,y,m,m")
588           (parallel [(const_int 0)])))]
589   "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
590   "#"
591   "&& reload_completed"
592   [(set (match_dup 0) (match_dup 1))]
593 {
594   if (REG_P (operands[1]))
595     operands[1] = gen_rtx_REG (SFmode, REGNO (operands[1]));
596   else
597     operands[1] = adjust_address (operands[1], SFmode, 0);
598 })
599
600 ;; Avoid combining registers from different units in a single alternative,
601 ;; see comment above inline_secondary_memory_needed function in i386.c
602 (define_insn "*vec_extractv2sf_1"
603   [(set (match_operand:SF 0 "nonimmediate_operand"     "=y,x,x,y,x,f,r")
604         (vec_select:SF
605           (match_operand:V2SF 1 "nonimmediate_operand" " 0,x,x,o,o,o,o")
606           (parallel [(const_int 1)])))]
607   "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
608   "@
609    punpckhdq\t%0, %0
610    %vmovshdup\t{%1, %0|%0, %1}
611    shufps\t{$0xe5, %1, %0|%0, %1, 0xe5}
612    #
613    #
614    #
615    #"
616   [(set_attr "isa" "*,sse3,noavx,*,*,*,*")
617    (set_attr "type" "mmxcvt,sse,sseshuf1,mmxmov,ssemov,fmov,imov")
618    (set_attr "length_immediate" "*,*,1,*,*,*,*")
619    (set_attr "prefix_rep" "*,1,*,*,*,*,*")
620    (set_attr "prefix" "orig,maybe_vex,orig,orig,orig,orig,orig")
621    (set_attr "mode" "DI,V4SF,V4SF,SF,SF,SF,SF")])
622
623 (define_split
624   [(set (match_operand:SF 0 "register_operand")
625         (vec_select:SF
626           (match_operand:V2SF 1 "memory_operand")
627           (parallel [(const_int 1)])))]
628   "TARGET_MMX && reload_completed"
629   [(set (match_dup 0) (match_dup 1))]
630   "operands[1] = adjust_address (operands[1], SFmode, 4);")
631
632 (define_expand "vec_extractv2sf"
633   [(match_operand:SF 0 "register_operand")
634    (match_operand:V2SF 1 "register_operand")
635    (match_operand 2 "const_int_operand")]
636   "TARGET_MMX"
637 {
638   ix86_expand_vector_extract (false, operands[0], operands[1],
639                               INTVAL (operands[2]));
640   DONE;
641 })
642
643 (define_expand "vec_initv2sf"
644   [(match_operand:V2SF 0 "register_operand")
645    (match_operand 1)]
646   "TARGET_SSE"
647 {
648   ix86_expand_vector_init (false, operands[0], operands[1]);
649   DONE;
650 })
651
652 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
653 ;;
654 ;; Parallel integral arithmetic
655 ;;
656 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
657
658 (define_expand "mmx_<plusminus_insn><mode>3"
659   [(set (match_operand:MMXMODEI8 0 "register_operand")
660         (plusminus:MMXMODEI8
661           (match_operand:MMXMODEI8 1 "nonimmediate_operand")
662           (match_operand:MMXMODEI8 2 "nonimmediate_operand")))]
663   "TARGET_MMX || (TARGET_SSE2 && <MODE>mode == V1DImode)"
664   "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
665
666 (define_insn "*mmx_<plusminus_insn><mode>3"
667   [(set (match_operand:MMXMODEI8 0 "register_operand" "=y")
668         (plusminus:MMXMODEI8
669           (match_operand:MMXMODEI8 1 "nonimmediate_operand" "<comm>0")
670           (match_operand:MMXMODEI8 2 "nonimmediate_operand" "ym")))]
671   "(TARGET_MMX || (TARGET_SSE2 && <MODE>mode == V1DImode))
672    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
673   "p<plusminus_mnemonic><mmxvecsize>\t{%2, %0|%0, %2}"
674   [(set_attr "type" "mmxadd")
675    (set_attr "mode" "DI")])
676
677 (define_expand "mmx_<plusminus_insn><mode>3"
678   [(set (match_operand:MMXMODE12 0 "register_operand")
679         (sat_plusminus:MMXMODE12
680           (match_operand:MMXMODE12 1 "nonimmediate_operand")
681           (match_operand:MMXMODE12 2 "nonimmediate_operand")))]
682   "TARGET_MMX"
683   "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
684
685 (define_insn "*mmx_<plusminus_insn><mode>3"
686   [(set (match_operand:MMXMODE12 0 "register_operand" "=y")
687         (sat_plusminus:MMXMODE12
688           (match_operand:MMXMODE12 1 "nonimmediate_operand" "<comm>0")
689           (match_operand:MMXMODE12 2 "nonimmediate_operand" "ym")))]
690   "TARGET_MMX && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
691   "p<plusminus_mnemonic><mmxvecsize>\t{%2, %0|%0, %2}"
692   [(set_attr "type" "mmxadd")
693    (set_attr "mode" "DI")])
694
695 (define_expand "mmx_mulv4hi3"
696   [(set (match_operand:V4HI 0 "register_operand")
697         (mult:V4HI (match_operand:V4HI 1 "nonimmediate_operand")
698                    (match_operand:V4HI 2 "nonimmediate_operand")))]
699   "TARGET_MMX"
700   "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
701
702 (define_insn "*mmx_mulv4hi3"
703   [(set (match_operand:V4HI 0 "register_operand" "=y")
704         (mult:V4HI (match_operand:V4HI 1 "nonimmediate_operand" "%0")
705                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
706   "TARGET_MMX && ix86_binary_operator_ok (MULT, V4HImode, operands)"
707   "pmullw\t{%2, %0|%0, %2}"
708   [(set_attr "type" "mmxmul")
709    (set_attr "mode" "DI")])
710
711 (define_expand "mmx_smulv4hi3_highpart"
712   [(set (match_operand:V4HI 0 "register_operand")
713         (truncate:V4HI
714           (lshiftrt:V4SI
715             (mult:V4SI
716               (sign_extend:V4SI
717                 (match_operand:V4HI 1 "nonimmediate_operand"))
718               (sign_extend:V4SI
719                 (match_operand:V4HI 2 "nonimmediate_operand")))
720             (const_int 16))))]
721   "TARGET_MMX"
722   "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
723
724 (define_insn "*mmx_smulv4hi3_highpart"
725   [(set (match_operand:V4HI 0 "register_operand" "=y")
726         (truncate:V4HI
727           (lshiftrt:V4SI
728             (mult:V4SI
729               (sign_extend:V4SI
730                 (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
731               (sign_extend:V4SI
732                 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
733             (const_int 16))))]
734   "TARGET_MMX && ix86_binary_operator_ok (MULT, V4HImode, operands)"
735   "pmulhw\t{%2, %0|%0, %2}"
736   [(set_attr "type" "mmxmul")
737    (set_attr "mode" "DI")])
738
739 (define_expand "mmx_umulv4hi3_highpart"
740   [(set (match_operand:V4HI 0 "register_operand")
741         (truncate:V4HI
742           (lshiftrt:V4SI
743             (mult:V4SI
744               (zero_extend:V4SI
745                 (match_operand:V4HI 1 "nonimmediate_operand"))
746               (zero_extend:V4SI
747                 (match_operand:V4HI 2 "nonimmediate_operand")))
748             (const_int 16))))]
749   "TARGET_SSE || TARGET_3DNOW_A"
750   "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
751
752 (define_insn "*mmx_umulv4hi3_highpart"
753   [(set (match_operand:V4HI 0 "register_operand" "=y")
754         (truncate:V4HI
755           (lshiftrt:V4SI
756             (mult:V4SI
757               (zero_extend:V4SI
758                 (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
759               (zero_extend:V4SI
760                 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
761           (const_int 16))))]
762   "(TARGET_SSE || TARGET_3DNOW_A)
763    && ix86_binary_operator_ok (MULT, V4HImode, operands)"
764   "pmulhuw\t{%2, %0|%0, %2}"
765   [(set_attr "type" "mmxmul")
766    (set_attr "mode" "DI")])
767
768 (define_expand "mmx_pmaddwd"
769   [(set (match_operand:V2SI 0 "register_operand")
770         (plus:V2SI
771           (mult:V2SI
772             (sign_extend:V2SI
773               (vec_select:V2HI
774                 (match_operand:V4HI 1 "nonimmediate_operand")
775                 (parallel [(const_int 0) (const_int 2)])))
776             (sign_extend:V2SI
777               (vec_select:V2HI
778                 (match_operand:V4HI 2 "nonimmediate_operand")
779                 (parallel [(const_int 0) (const_int 2)]))))
780           (mult:V2SI
781             (sign_extend:V2SI
782               (vec_select:V2HI (match_dup 1)
783                 (parallel [(const_int 1) (const_int 3)])))
784             (sign_extend:V2SI
785               (vec_select:V2HI (match_dup 2)
786                 (parallel [(const_int 1) (const_int 3)]))))))]
787   "TARGET_MMX"
788   "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
789
790 (define_insn "*mmx_pmaddwd"
791   [(set (match_operand:V2SI 0 "register_operand" "=y")
792         (plus:V2SI
793           (mult:V2SI
794             (sign_extend:V2SI
795               (vec_select:V2HI
796                 (match_operand:V4HI 1 "nonimmediate_operand" "%0")
797                 (parallel [(const_int 0) (const_int 2)])))
798             (sign_extend:V2SI
799               (vec_select:V2HI
800                 (match_operand:V4HI 2 "nonimmediate_operand" "ym")
801                 (parallel [(const_int 0) (const_int 2)]))))
802           (mult:V2SI
803             (sign_extend:V2SI
804               (vec_select:V2HI (match_dup 1)
805                 (parallel [(const_int 1) (const_int 3)])))
806             (sign_extend:V2SI
807               (vec_select:V2HI (match_dup 2)
808                 (parallel [(const_int 1) (const_int 3)]))))))]
809   "TARGET_MMX && ix86_binary_operator_ok (MULT, V4HImode, operands)"
810   "pmaddwd\t{%2, %0|%0, %2}"
811   [(set_attr "type" "mmxmul")
812    (set_attr "mode" "DI")])
813
814 (define_expand "mmx_pmulhrwv4hi3"
815   [(set (match_operand:V4HI 0 "register_operand")
816         (truncate:V4HI
817           (lshiftrt:V4SI
818             (plus:V4SI
819               (mult:V4SI
820                 (sign_extend:V4SI
821                   (match_operand:V4HI 1 "nonimmediate_operand"))
822                 (sign_extend:V4SI
823                   (match_operand:V4HI 2 "nonimmediate_operand")))
824               (const_vector:V4SI [(const_int 32768) (const_int 32768)
825                                   (const_int 32768) (const_int 32768)]))
826             (const_int 16))))]
827   "TARGET_3DNOW"
828   "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
829
830 (define_insn "*mmx_pmulhrwv4hi3"
831   [(set (match_operand:V4HI 0 "register_operand" "=y")
832         (truncate:V4HI
833           (lshiftrt:V4SI
834             (plus:V4SI
835               (mult:V4SI
836                 (sign_extend:V4SI
837                   (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
838                 (sign_extend:V4SI
839                   (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
840               (const_vector:V4SI [(const_int 32768) (const_int 32768)
841                                   (const_int 32768) (const_int 32768)]))
842             (const_int 16))))]
843   "TARGET_3DNOW && ix86_binary_operator_ok (MULT, V4HImode, operands)"
844   "pmulhrw\t{%2, %0|%0, %2}"
845   [(set_attr "type" "mmxmul")
846    (set_attr "prefix_extra" "1")
847    (set_attr "mode" "DI")])
848
849 (define_expand "sse2_umulv1siv1di3"
850   [(set (match_operand:V1DI 0 "register_operand")
851         (mult:V1DI
852           (zero_extend:V1DI
853             (vec_select:V1SI
854               (match_operand:V2SI 1 "nonimmediate_operand")
855               (parallel [(const_int 0)])))
856           (zero_extend:V1DI
857             (vec_select:V1SI
858               (match_operand:V2SI 2 "nonimmediate_operand")
859               (parallel [(const_int 0)])))))]
860   "TARGET_SSE2"
861   "ix86_fixup_binary_operands_no_copy (MULT, V2SImode, operands);")
862
863 (define_insn "*sse2_umulv1siv1di3"
864   [(set (match_operand:V1DI 0 "register_operand" "=y")
865         (mult:V1DI
866           (zero_extend:V1DI
867             (vec_select:V1SI
868               (match_operand:V2SI 1 "nonimmediate_operand" "%0")
869               (parallel [(const_int 0)])))
870           (zero_extend:V1DI
871             (vec_select:V1SI
872               (match_operand:V2SI 2 "nonimmediate_operand" "ym")
873               (parallel [(const_int 0)])))))]
874   "TARGET_SSE2 && ix86_binary_operator_ok (MULT, V2SImode, operands)"
875   "pmuludq\t{%2, %0|%0, %2}"
876   [(set_attr "type" "mmxmul")
877    (set_attr "mode" "DI")])
878
879 (define_expand "mmx_<code>v4hi3"
880   [(set (match_operand:V4HI 0 "register_operand")
881         (smaxmin:V4HI
882           (match_operand:V4HI 1 "nonimmediate_operand")
883           (match_operand:V4HI 2 "nonimmediate_operand")))]
884   "TARGET_SSE || TARGET_3DNOW_A"
885   "ix86_fixup_binary_operands_no_copy (<CODE>, V4HImode, operands);")
886
887 (define_insn "*mmx_<code>v4hi3"
888   [(set (match_operand:V4HI 0 "register_operand" "=y")
889         (smaxmin:V4HI
890           (match_operand:V4HI 1 "nonimmediate_operand" "%0")
891           (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
892   "(TARGET_SSE || TARGET_3DNOW_A)
893    && ix86_binary_operator_ok (<CODE>, V4HImode, operands)"
894   "p<maxmin_int>w\t{%2, %0|%0, %2}"
895   [(set_attr "type" "mmxadd")
896    (set_attr "mode" "DI")])
897
898 (define_expand "mmx_<code>v8qi3"
899   [(set (match_operand:V8QI 0 "register_operand")
900         (umaxmin:V8QI
901           (match_operand:V8QI 1 "nonimmediate_operand")
902           (match_operand:V8QI 2 "nonimmediate_operand")))]
903   "TARGET_SSE || TARGET_3DNOW_A"
904   "ix86_fixup_binary_operands_no_copy (<CODE>, V8QImode, operands);")
905
906 (define_insn "*mmx_<code>v8qi3"
907   [(set (match_operand:V8QI 0 "register_operand" "=y")
908         (umaxmin:V8QI
909           (match_operand:V8QI 1 "nonimmediate_operand" "%0")
910           (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
911   "(TARGET_SSE || TARGET_3DNOW_A)
912    && ix86_binary_operator_ok (<CODE>, V8QImode, operands)"
913   "p<maxmin_int>b\t{%2, %0|%0, %2}"
914   [(set_attr "type" "mmxadd")
915    (set_attr "mode" "DI")])
916
917 (define_insn "mmx_ashr<mode>3"
918   [(set (match_operand:MMXMODE24 0 "register_operand" "=y")
919         (ashiftrt:MMXMODE24
920           (match_operand:MMXMODE24 1 "register_operand" "0")
921           (match_operand:SI 2 "nonmemory_operand" "yN")))]
922   "TARGET_MMX"
923   "psra<mmxvecsize>\t{%2, %0|%0, %2}"
924   [(set_attr "type" "mmxshft")
925    (set (attr "length_immediate")
926      (if_then_else (match_operand 2 "const_int_operand")
927        (const_string "1")
928        (const_string "0")))
929    (set_attr "mode" "DI")])
930
931 (define_insn "mmx_<shift_insn><mode>3"
932   [(set (match_operand:MMXMODE248 0 "register_operand" "=y")
933         (any_lshift:MMXMODE248
934           (match_operand:MMXMODE248 1 "register_operand" "0")
935           (match_operand:SI 2 "nonmemory_operand" "yN")))]
936   "TARGET_MMX"
937   "p<vshift><mmxvecsize>\t{%2, %0|%0, %2}"
938   [(set_attr "type" "mmxshft")
939    (set (attr "length_immediate")
940      (if_then_else (match_operand 2 "const_int_operand")
941        (const_string "1")
942        (const_string "0")))
943    (set_attr "mode" "DI")])
944
945 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
946 ;;
947 ;; Parallel integral comparisons
948 ;;
949 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
950
951 (define_expand "mmx_eq<mode>3"
952   [(set (match_operand:MMXMODEI 0 "register_operand")
953         (eq:MMXMODEI
954           (match_operand:MMXMODEI 1 "nonimmediate_operand")
955           (match_operand:MMXMODEI 2 "nonimmediate_operand")))]
956   "TARGET_MMX"
957   "ix86_fixup_binary_operands_no_copy (EQ, <MODE>mode, operands);")
958
959 (define_insn "*mmx_eq<mode>3"
960   [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
961         (eq:MMXMODEI
962           (match_operand:MMXMODEI 1 "nonimmediate_operand" "%0")
963           (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
964   "TARGET_MMX && ix86_binary_operator_ok (EQ, <MODE>mode, operands)"
965   "pcmpeq<mmxvecsize>\t{%2, %0|%0, %2}"
966   [(set_attr "type" "mmxcmp")
967    (set_attr "mode" "DI")])
968
969 (define_insn "mmx_gt<mode>3"
970   [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
971         (gt:MMXMODEI
972           (match_operand:MMXMODEI 1 "register_operand" "0")
973           (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
974   "TARGET_MMX"
975   "pcmpgt<mmxvecsize>\t{%2, %0|%0, %2}"
976   [(set_attr "type" "mmxcmp")
977    (set_attr "mode" "DI")])
978
979 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
980 ;;
981 ;; Parallel integral logical operations
982 ;;
983 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
984
985 (define_insn "mmx_andnot<mode>3"
986   [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
987         (and:MMXMODEI
988           (not:MMXMODEI (match_operand:MMXMODEI 1 "register_operand" "0"))
989           (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
990   "TARGET_MMX"
991   "pandn\t{%2, %0|%0, %2}"
992   [(set_attr "type" "mmxadd")
993    (set_attr "mode" "DI")])
994
995 (define_expand "mmx_<code><mode>3"
996   [(set (match_operand:MMXMODEI 0 "register_operand")
997         (any_logic:MMXMODEI
998           (match_operand:MMXMODEI 1 "nonimmediate_operand")
999           (match_operand:MMXMODEI 2 "nonimmediate_operand")))]
1000   "TARGET_MMX"
1001   "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
1002
1003 (define_insn "*mmx_<code><mode>3"
1004   [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
1005         (any_logic:MMXMODEI
1006           (match_operand:MMXMODEI 1 "nonimmediate_operand" "%0")
1007           (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
1008   "TARGET_MMX && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
1009   "p<logic>\t{%2, %0|%0, %2}"
1010   [(set_attr "type" "mmxadd")
1011    (set_attr "mode" "DI")])
1012
1013 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1014 ;;
1015 ;; Parallel integral element swizzling
1016 ;;
1017 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1018
1019 (define_insn "mmx_packsswb"
1020   [(set (match_operand:V8QI 0 "register_operand" "=y")
1021         (vec_concat:V8QI
1022           (ss_truncate:V4QI
1023             (match_operand:V4HI 1 "register_operand" "0"))
1024           (ss_truncate:V4QI
1025             (match_operand:V4HI 2 "nonimmediate_operand" "ym"))))]
1026   "TARGET_MMX"
1027   "packsswb\t{%2, %0|%0, %2}"
1028   [(set_attr "type" "mmxshft")
1029    (set_attr "mode" "DI")])
1030
1031 (define_insn "mmx_packssdw"
1032   [(set (match_operand:V4HI 0 "register_operand" "=y")
1033         (vec_concat:V4HI
1034           (ss_truncate:V2HI
1035             (match_operand:V2SI 1 "register_operand" "0"))
1036           (ss_truncate:V2HI
1037             (match_operand:V2SI 2 "nonimmediate_operand" "ym"))))]
1038   "TARGET_MMX"
1039   "packssdw\t{%2, %0|%0, %2}"
1040   [(set_attr "type" "mmxshft")
1041    (set_attr "mode" "DI")])
1042
1043 (define_insn "mmx_packuswb"
1044   [(set (match_operand:V8QI 0 "register_operand" "=y")
1045         (vec_concat:V8QI
1046           (us_truncate:V4QI
1047             (match_operand:V4HI 1 "register_operand" "0"))
1048           (us_truncate:V4QI
1049             (match_operand:V4HI 2 "nonimmediate_operand" "ym"))))]
1050   "TARGET_MMX"
1051   "packuswb\t{%2, %0|%0, %2}"
1052   [(set_attr "type" "mmxshft")
1053    (set_attr "mode" "DI")])
1054
1055 (define_insn "mmx_punpckhbw"
1056   [(set (match_operand:V8QI 0 "register_operand" "=y")
1057         (vec_select:V8QI
1058           (vec_concat:V16QI
1059             (match_operand:V8QI 1 "register_operand" "0")
1060             (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
1061           (parallel [(const_int 4) (const_int 12)
1062                      (const_int 5) (const_int 13)
1063                      (const_int 6) (const_int 14)
1064                      (const_int 7) (const_int 15)])))]
1065   "TARGET_MMX"
1066   "punpckhbw\t{%2, %0|%0, %2}"
1067   [(set_attr "type" "mmxcvt")
1068    (set_attr "mode" "DI")])
1069
1070 (define_insn "mmx_punpcklbw"
1071   [(set (match_operand:V8QI 0 "register_operand" "=y")
1072         (vec_select:V8QI
1073           (vec_concat:V16QI
1074             (match_operand:V8QI 1 "register_operand" "0")
1075             (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
1076           (parallel [(const_int 0) (const_int 8)
1077                      (const_int 1) (const_int 9)
1078                      (const_int 2) (const_int 10)
1079                      (const_int 3) (const_int 11)])))]
1080   "TARGET_MMX"
1081   "punpcklbw\t{%2, %0|%0, %k2}"
1082   [(set_attr "type" "mmxcvt")
1083    (set_attr "mode" "DI")])
1084
1085 (define_insn "mmx_punpckhwd"
1086   [(set (match_operand:V4HI 0 "register_operand" "=y")
1087         (vec_select:V4HI
1088           (vec_concat:V8HI
1089             (match_operand:V4HI 1 "register_operand" "0")
1090             (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
1091           (parallel [(const_int 2) (const_int 6)
1092                      (const_int 3) (const_int 7)])))]
1093   "TARGET_MMX"
1094   "punpckhwd\t{%2, %0|%0, %2}"
1095   [(set_attr "type" "mmxcvt")
1096    (set_attr "mode" "DI")])
1097
1098 (define_insn "mmx_punpcklwd"
1099   [(set (match_operand:V4HI 0 "register_operand" "=y")
1100         (vec_select:V4HI
1101           (vec_concat:V8HI
1102             (match_operand:V4HI 1 "register_operand" "0")
1103             (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
1104           (parallel [(const_int 0) (const_int 4)
1105                      (const_int 1) (const_int 5)])))]
1106   "TARGET_MMX"
1107   "punpcklwd\t{%2, %0|%0, %k2}"
1108   [(set_attr "type" "mmxcvt")
1109    (set_attr "mode" "DI")])
1110
1111 (define_insn "mmx_punpckhdq"
1112   [(set (match_operand:V2SI 0 "register_operand" "=y")
1113         (vec_select:V2SI
1114           (vec_concat:V4SI
1115             (match_operand:V2SI 1 "register_operand" "0")
1116             (match_operand:V2SI 2 "nonimmediate_operand" "ym"))
1117           (parallel [(const_int 1)
1118                      (const_int 3)])))]
1119   "TARGET_MMX"
1120   "punpckhdq\t{%2, %0|%0, %2}"
1121   [(set_attr "type" "mmxcvt")
1122    (set_attr "mode" "DI")])
1123
1124 (define_insn "mmx_punpckldq"
1125   [(set (match_operand:V2SI 0 "register_operand" "=y")
1126         (vec_select:V2SI
1127           (vec_concat:V4SI
1128             (match_operand:V2SI 1 "register_operand" "0")
1129             (match_operand:V2SI 2 "nonimmediate_operand" "ym"))
1130           (parallel [(const_int 0)
1131                      (const_int 2)])))]
1132   "TARGET_MMX"
1133   "punpckldq\t{%2, %0|%0, %k2}"
1134   [(set_attr "type" "mmxcvt")
1135    (set_attr "mode" "DI")])
1136
1137 (define_expand "mmx_pinsrw"
1138   [(set (match_operand:V4HI 0 "register_operand")
1139         (vec_merge:V4HI
1140           (vec_duplicate:V4HI
1141             (match_operand:SI 2 "nonimmediate_operand"))
1142           (match_operand:V4HI 1 "register_operand")
1143           (match_operand:SI 3 "const_0_to_3_operand")))]
1144   "TARGET_SSE || TARGET_3DNOW_A"
1145 {
1146   operands[2] = gen_lowpart (HImode, operands[2]);
1147   operands[3] = GEN_INT (1 << INTVAL (operands[3]));
1148 })
1149
1150 (define_insn "*mmx_pinsrw"
1151   [(set (match_operand:V4HI 0 "register_operand" "=y")
1152         (vec_merge:V4HI
1153           (vec_duplicate:V4HI
1154             (match_operand:HI 2 "nonimmediate_operand" "rm"))
1155           (match_operand:V4HI 1 "register_operand" "0")
1156           (match_operand:SI 3 "const_int_operand")))]
1157   "(TARGET_SSE || TARGET_3DNOW_A)
1158    && ((unsigned) exact_log2 (INTVAL (operands[3]))
1159        < GET_MODE_NUNITS (V4HImode))"
1160 {
1161   operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])));
1162   if (MEM_P (operands[2]))
1163     return "pinsrw\t{%3, %2, %0|%0, %2, %3}";
1164   else
1165     return "pinsrw\t{%3, %k2, %0|%0, %k2, %3}";
1166 }
1167   [(set_attr "type" "mmxcvt")
1168    (set_attr "length_immediate" "1")
1169    (set_attr "mode" "DI")])
1170
1171 (define_insn "mmx_pextrw"
1172   [(set (match_operand:SI 0 "register_operand" "=r")
1173         (zero_extend:SI
1174           (vec_select:HI
1175             (match_operand:V4HI 1 "register_operand" "y")
1176             (parallel [(match_operand:SI 2 "const_0_to_3_operand" "n")]))))]
1177   "TARGET_SSE || TARGET_3DNOW_A"
1178   "pextrw\t{%2, %1, %0|%0, %1, %2}"
1179   [(set_attr "type" "mmxcvt")
1180    (set_attr "length_immediate" "1")
1181    (set_attr "mode" "DI")])
1182
1183 (define_expand "mmx_pshufw"
1184   [(match_operand:V4HI 0 "register_operand")
1185    (match_operand:V4HI 1 "nonimmediate_operand")
1186    (match_operand:SI 2 "const_int_operand")]
1187   "TARGET_SSE || TARGET_3DNOW_A"
1188 {
1189   int mask = INTVAL (operands[2]);
1190   emit_insn (gen_mmx_pshufw_1 (operands[0], operands[1],
1191                                GEN_INT ((mask >> 0) & 3),
1192                                GEN_INT ((mask >> 2) & 3),
1193                                GEN_INT ((mask >> 4) & 3),
1194                                GEN_INT ((mask >> 6) & 3)));
1195   DONE;
1196 })
1197
1198 (define_insn "mmx_pshufw_1"
1199   [(set (match_operand:V4HI 0 "register_operand" "=y")
1200         (vec_select:V4HI
1201           (match_operand:V4HI 1 "nonimmediate_operand" "ym")
1202           (parallel [(match_operand 2 "const_0_to_3_operand")
1203                      (match_operand 3 "const_0_to_3_operand")
1204                      (match_operand 4 "const_0_to_3_operand")
1205                      (match_operand 5 "const_0_to_3_operand")])))]
1206   "TARGET_SSE || TARGET_3DNOW_A"
1207 {
1208   int mask = 0;
1209   mask |= INTVAL (operands[2]) << 0;
1210   mask |= INTVAL (operands[3]) << 2;
1211   mask |= INTVAL (operands[4]) << 4;
1212   mask |= INTVAL (operands[5]) << 6;
1213   operands[2] = GEN_INT (mask);
1214
1215   return "pshufw\t{%2, %1, %0|%0, %1, %2}";
1216 }
1217   [(set_attr "type" "mmxcvt")
1218    (set_attr "length_immediate" "1")
1219    (set_attr "mode" "DI")])
1220
1221 (define_insn "mmx_pswapdv2si2"
1222   [(set (match_operand:V2SI 0 "register_operand" "=y")
1223         (vec_select:V2SI
1224           (match_operand:V2SI 1 "nonimmediate_operand" "ym")
1225           (parallel [(const_int 1) (const_int 0)])))]
1226   "TARGET_3DNOW_A"
1227   "pswapd\t{%1, %0|%0, %1}"
1228   [(set_attr "type" "mmxcvt")
1229    (set_attr "prefix_extra" "1")
1230    (set_attr "mode" "DI")])
1231
1232 (define_insn "*vec_dupv4hi"
1233   [(set (match_operand:V4HI 0 "register_operand" "=y")
1234         (vec_duplicate:V4HI
1235           (truncate:HI
1236             (match_operand:SI 1 "register_operand" "0"))))]
1237   "TARGET_SSE || TARGET_3DNOW_A"
1238   "pshufw\t{$0, %0, %0|%0, %0, 0}"
1239   [(set_attr "type" "mmxcvt")
1240    (set_attr "length_immediate" "1")
1241    (set_attr "mode" "DI")])
1242
1243 (define_insn "*vec_dupv2si"
1244   [(set (match_operand:V2SI 0 "register_operand" "=y")
1245         (vec_duplicate:V2SI
1246           (match_operand:SI 1 "register_operand" "0")))]
1247   "TARGET_MMX"
1248   "punpckldq\t%0, %0"
1249   [(set_attr "type" "mmxcvt")
1250    (set_attr "mode" "DI")])
1251
1252 (define_insn "*mmx_concatv2si"
1253   [(set (match_operand:V2SI 0 "register_operand"     "=y,y")
1254         (vec_concat:V2SI
1255           (match_operand:SI 1 "nonimmediate_operand" " 0,rm")
1256           (match_operand:SI 2 "vector_move_operand"  "ym,C")))]
1257   "TARGET_MMX && !TARGET_SSE"
1258   "@
1259    punpckldq\t{%2, %0|%0, %2}
1260    movd\t{%1, %0|%0, %1}"
1261   [(set_attr "type" "mmxcvt,mmxmov")
1262    (set_attr "mode" "DI")])
1263
1264 (define_expand "vec_setv2si"
1265   [(match_operand:V2SI 0 "register_operand")
1266    (match_operand:SI 1 "register_operand")
1267    (match_operand 2 "const_int_operand")]
1268   "TARGET_MMX"
1269 {
1270   ix86_expand_vector_set (false, operands[0], operands[1],
1271                           INTVAL (operands[2]));
1272   DONE;
1273 })
1274
1275 ;; Avoid combining registers from different units in a single alternative,
1276 ;; see comment above inline_secondary_memory_needed function in i386.c
1277 (define_insn_and_split "*vec_extractv2si_0"
1278   [(set (match_operand:SI 0 "nonimmediate_operand"     "=x,m,y, m,r")
1279         (vec_select:SI
1280           (match_operand:V2SI 1 "nonimmediate_operand" "xm,x,ym,y,m")
1281           (parallel [(const_int 0)])))]
1282   "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1283   "#"
1284   "&& reload_completed"
1285   [(set (match_dup 0) (match_dup 1))]
1286 {
1287   if (REG_P (operands[1]))
1288     operands[1] = gen_rtx_REG (SImode, REGNO (operands[1]));
1289   else
1290     operands[1] = adjust_address (operands[1], SImode, 0);
1291 })
1292
1293 ;; Avoid combining registers from different units in a single alternative,
1294 ;; see comment above inline_secondary_memory_needed function in i386.c
1295 (define_insn "*vec_extractv2si_1"
1296   [(set (match_operand:SI 0 "nonimmediate_operand"     "=y,x,x,y,x,r")
1297         (vec_select:SI
1298           (match_operand:V2SI 1 "nonimmediate_operand" " 0,x,x,o,o,o")
1299           (parallel [(const_int 1)])))]
1300   "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1301   "@
1302    punpckhdq\t%0, %0
1303    %vpshufd\t{$0xe5, %1, %0|%0, %1, 0xe5}
1304    shufps\t{$0xe5, %1, %0|%0, %1, 0xe5}
1305    #
1306    #
1307    #"
1308   [(set_attr "isa" "*,sse2,noavx,*,*,*")
1309    (set_attr "type" "mmxcvt,sseshuf1,sseshuf1,mmxmov,ssemov,imov")
1310    (set_attr "length_immediate" "*,1,1,*,*,*")
1311    (set_attr "prefix" "orig,maybe_vex,orig,orig,orig,orig")
1312    (set_attr "mode" "DI,TI,V4SF,SI,SI,SI")])
1313
1314 (define_split
1315   [(set (match_operand:SI 0 "register_operand")
1316         (vec_select:SI
1317           (match_operand:V2SI 1 "memory_operand")
1318           (parallel [(const_int 1)])))]
1319   "TARGET_MMX && reload_completed"
1320   [(set (match_dup 0) (match_dup 1))]
1321   "operands[1] = adjust_address (operands[1], SImode, 4);")
1322
1323 (define_insn_and_split "*vec_extractv2si_zext_mem"
1324   [(set (match_operand:DI 0 "register_operand" "=y,x,r")
1325         (zero_extend:DI
1326           (vec_select:SI
1327             (match_operand:V2SI 1 "memory_operand" "o,o,o")
1328             (parallel [(match_operand:SI 2 "const_0_to_1_operand")]))))]
1329   "TARGET_64BIT && TARGET_MMX"
1330   "#"
1331   "&& reload_completed"
1332   [(set (match_dup 0) (zero_extend:DI (match_dup 1)))]
1333 {
1334   operands[1] = adjust_address (operands[1], SImode, INTVAL (operands[2]) * 4);
1335 })
1336
1337 (define_expand "vec_extractv2si"
1338   [(match_operand:SI 0 "register_operand")
1339    (match_operand:V2SI 1 "register_operand")
1340    (match_operand 2 "const_int_operand")]
1341   "TARGET_MMX"
1342 {
1343   ix86_expand_vector_extract (false, operands[0], operands[1],
1344                               INTVAL (operands[2]));
1345   DONE;
1346 })
1347
1348 (define_expand "vec_initv2si"
1349   [(match_operand:V2SI 0 "register_operand")
1350    (match_operand 1)]
1351   "TARGET_SSE"
1352 {
1353   ix86_expand_vector_init (false, operands[0], operands[1]);
1354   DONE;
1355 })
1356
1357 (define_expand "vec_setv4hi"
1358   [(match_operand:V4HI 0 "register_operand")
1359    (match_operand:HI 1 "register_operand")
1360    (match_operand 2 "const_int_operand")]
1361   "TARGET_MMX"
1362 {
1363   ix86_expand_vector_set (false, operands[0], operands[1],
1364                           INTVAL (operands[2]));
1365   DONE;
1366 })
1367
1368 (define_expand "vec_extractv4hi"
1369   [(match_operand:HI 0 "register_operand")
1370    (match_operand:V4HI 1 "register_operand")
1371    (match_operand 2 "const_int_operand")]
1372   "TARGET_MMX"
1373 {
1374   ix86_expand_vector_extract (false, operands[0], operands[1],
1375                               INTVAL (operands[2]));
1376   DONE;
1377 })
1378
1379 (define_expand "vec_initv4hi"
1380   [(match_operand:V4HI 0 "register_operand")
1381    (match_operand 1)]
1382   "TARGET_SSE"
1383 {
1384   ix86_expand_vector_init (false, operands[0], operands[1]);
1385   DONE;
1386 })
1387
1388 (define_expand "vec_setv8qi"
1389   [(match_operand:V8QI 0 "register_operand")
1390    (match_operand:QI 1 "register_operand")
1391    (match_operand 2 "const_int_operand")]
1392   "TARGET_MMX"
1393 {
1394   ix86_expand_vector_set (false, operands[0], operands[1],
1395                           INTVAL (operands[2]));
1396   DONE;
1397 })
1398
1399 (define_expand "vec_extractv8qi"
1400   [(match_operand:QI 0 "register_operand")
1401    (match_operand:V8QI 1 "register_operand")
1402    (match_operand 2 "const_int_operand")]
1403   "TARGET_MMX"
1404 {
1405   ix86_expand_vector_extract (false, operands[0], operands[1],
1406                               INTVAL (operands[2]));
1407   DONE;
1408 })
1409
1410 (define_expand "vec_initv8qi"
1411   [(match_operand:V8QI 0 "register_operand")
1412    (match_operand 1)]
1413   "TARGET_SSE"
1414 {
1415   ix86_expand_vector_init (false, operands[0], operands[1]);
1416   DONE;
1417 })
1418
1419 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1420 ;;
1421 ;; Miscellaneous
1422 ;;
1423 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1424
1425 (define_expand "mmx_uavgv8qi3"
1426   [(set (match_operand:V8QI 0 "register_operand")
1427         (truncate:V8QI
1428           (lshiftrt:V8HI
1429             (plus:V8HI
1430               (plus:V8HI
1431                 (zero_extend:V8HI
1432                   (match_operand:V8QI 1 "nonimmediate_operand"))
1433                 (zero_extend:V8HI
1434                   (match_operand:V8QI 2 "nonimmediate_operand")))
1435               (const_vector:V8HI [(const_int 1) (const_int 1)
1436                                   (const_int 1) (const_int 1)
1437                                   (const_int 1) (const_int 1)
1438                                   (const_int 1) (const_int 1)]))
1439             (const_int 1))))]
1440   "TARGET_SSE || TARGET_3DNOW"
1441   "ix86_fixup_binary_operands_no_copy (PLUS, V8QImode, operands);")
1442
1443 (define_insn "*mmx_uavgv8qi3"
1444   [(set (match_operand:V8QI 0 "register_operand" "=y")
1445         (truncate:V8QI
1446           (lshiftrt:V8HI
1447             (plus:V8HI
1448               (plus:V8HI
1449                 (zero_extend:V8HI
1450                   (match_operand:V8QI 1 "nonimmediate_operand" "%0"))
1451                 (zero_extend:V8HI
1452                   (match_operand:V8QI 2 "nonimmediate_operand" "ym")))
1453               (const_vector:V8HI [(const_int 1) (const_int 1)
1454                                   (const_int 1) (const_int 1)
1455                                   (const_int 1) (const_int 1)
1456                                   (const_int 1) (const_int 1)]))
1457             (const_int 1))))]
1458   "(TARGET_SSE || TARGET_3DNOW)
1459    && ix86_binary_operator_ok (PLUS, V8QImode, operands)"
1460 {
1461   /* These two instructions have the same operation, but their encoding
1462      is different.  Prefer the one that is de facto standard.  */
1463   if (TARGET_SSE || TARGET_3DNOW_A)
1464     return "pavgb\t{%2, %0|%0, %2}";
1465   else
1466     return "pavgusb\t{%2, %0|%0, %2}";
1467 }
1468   [(set_attr "type" "mmxshft")
1469    (set (attr "prefix_extra")
1470      (if_then_else
1471        (not (ior (match_test "TARGET_SSE")
1472                  (match_test "TARGET_3DNOW_A")))
1473        (const_string "1")
1474        (const_string "*")))
1475    (set_attr "mode" "DI")])
1476
1477 (define_expand "mmx_uavgv4hi3"
1478   [(set (match_operand:V4HI 0 "register_operand")
1479         (truncate:V4HI
1480           (lshiftrt:V4SI
1481             (plus:V4SI
1482               (plus:V4SI
1483                 (zero_extend:V4SI
1484                   (match_operand:V4HI 1 "nonimmediate_operand"))
1485                 (zero_extend:V4SI
1486                   (match_operand:V4HI 2 "nonimmediate_operand")))
1487               (const_vector:V4SI [(const_int 1) (const_int 1)
1488                                   (const_int 1) (const_int 1)]))
1489             (const_int 1))))]
1490   "TARGET_SSE || TARGET_3DNOW_A"
1491   "ix86_fixup_binary_operands_no_copy (PLUS, V4HImode, operands);")
1492
1493 (define_insn "*mmx_uavgv4hi3"
1494   [(set (match_operand:V4HI 0 "register_operand" "=y")
1495         (truncate:V4HI
1496           (lshiftrt:V4SI
1497             (plus:V4SI
1498               (plus:V4SI
1499                 (zero_extend:V4SI
1500                   (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
1501                 (zero_extend:V4SI
1502                   (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
1503               (const_vector:V4SI [(const_int 1) (const_int 1)
1504                                   (const_int 1) (const_int 1)]))
1505             (const_int 1))))]
1506   "(TARGET_SSE || TARGET_3DNOW_A)
1507    && ix86_binary_operator_ok (PLUS, V4HImode, operands)"
1508   "pavgw\t{%2, %0|%0, %2}"
1509   [(set_attr "type" "mmxshft")
1510    (set_attr "mode" "DI")])
1511
1512 (define_insn "mmx_psadbw"
1513   [(set (match_operand:V1DI 0 "register_operand" "=y")
1514         (unspec:V1DI [(match_operand:V8QI 1 "register_operand" "0")
1515                       (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
1516                      UNSPEC_PSADBW))]
1517   "TARGET_SSE || TARGET_3DNOW_A"
1518   "psadbw\t{%2, %0|%0, %2}"
1519   [(set_attr "type" "mmxshft")
1520    (set_attr "mode" "DI")])
1521
1522 (define_insn "mmx_pmovmskb"
1523   [(set (match_operand:SI 0 "register_operand" "=r")
1524         (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")]
1525                    UNSPEC_MOVMSK))]
1526   "TARGET_SSE || TARGET_3DNOW_A"
1527   "pmovmskb\t{%1, %0|%0, %1}"
1528   [(set_attr "type" "mmxcvt")
1529    (set_attr "mode" "DI")])
1530
1531 (define_expand "mmx_maskmovq"
1532   [(set (match_operand:V8QI 0 "memory_operand")
1533         (unspec:V8QI [(match_operand:V8QI 1 "register_operand")
1534                       (match_operand:V8QI 2 "register_operand")
1535                       (match_dup 0)]
1536                      UNSPEC_MASKMOV))]
1537   "TARGET_SSE || TARGET_3DNOW_A")
1538
1539 (define_insn "*mmx_maskmovq"
1540   [(set (mem:V8QI (match_operand:P 0 "register_operand" "D"))
1541         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
1542                       (match_operand:V8QI 2 "register_operand" "y")
1543                       (mem:V8QI (match_dup 0))]
1544                      UNSPEC_MASKMOV))]
1545   "TARGET_SSE || TARGET_3DNOW_A"
1546   ;; @@@ check ordering of operands in intel/nonintel syntax
1547   "maskmovq\t{%2, %1|%1, %2}"
1548   [(set_attr "type" "mmxcvt")
1549    (set_attr "mode" "DI")])
1550
1551 (define_expand "mmx_emms"
1552   [(match_par_dup 0 [(const_int 0)])]
1553   "TARGET_MMX"
1554 {
1555   int regno;
1556
1557   operands[0] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (17));
1558
1559   XVECEXP (operands[0], 0, 0)
1560     = gen_rtx_UNSPEC_VOLATILE (VOIDmode, gen_rtvec (1, const0_rtx),
1561                                UNSPECV_EMMS);
1562
1563   for (regno = 0; regno < 8; regno++)
1564     {
1565       XVECEXP (operands[0], 0, regno + 1)
1566         = gen_rtx_CLOBBER (VOIDmode,
1567                            gen_rtx_REG (XFmode, FIRST_STACK_REG + regno));
1568
1569       XVECEXP (operands[0], 0, regno + 9)
1570         = gen_rtx_CLOBBER (VOIDmode,
1571                            gen_rtx_REG (DImode, FIRST_MMX_REG + regno));
1572     }
1573 })
1574
1575 (define_insn "*mmx_emms"
1576   [(match_parallel 0 "emms_operation"
1577     [(unspec_volatile [(const_int 0)] UNSPECV_EMMS)])]
1578   "TARGET_MMX"
1579   "emms"
1580   [(set_attr "type" "mmx")
1581    (set_attr "modrm" "0")
1582    (set_attr "memory" "none")])
1583
1584 (define_expand "mmx_femms"
1585   [(match_par_dup 0 [(const_int 0)])]
1586   "TARGET_3DNOW"
1587 {
1588   int regno;
1589
1590   operands[0] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (17));
1591
1592   XVECEXP (operands[0], 0, 0)
1593     = gen_rtx_UNSPEC_VOLATILE (VOIDmode, gen_rtvec (1, const0_rtx),
1594                                UNSPECV_FEMMS);
1595
1596   for (regno = 0; regno < 8; regno++)
1597     {
1598       XVECEXP (operands[0], 0, regno + 1)
1599         = gen_rtx_CLOBBER (VOIDmode,
1600                            gen_rtx_REG (XFmode, FIRST_STACK_REG + regno));
1601
1602       XVECEXP (operands[0], 0, regno + 9)
1603         = gen_rtx_CLOBBER (VOIDmode,
1604                            gen_rtx_REG (DImode, FIRST_MMX_REG + regno));
1605     }
1606 })
1607
1608 (define_insn "*mmx_femms"
1609   [(match_parallel 0 "emms_operation"
1610     [(unspec_volatile [(const_int 0)] UNSPECV_FEMMS)])]
1611   "TARGET_3DNOW"
1612   "femms"
1613   [(set_attr "type" "mmx")
1614    (set_attr "modrm" "0")
1615    (set_attr "memory" "none")])