Fix a typo in ChangeLog
[official-gcc.git] / gcc / config / i386 / mmx.md
blob4911cb296e2f45674b8f6d9cbd2df3b7d4198544
1 ;; GCC machine description for MMX and 3dNOW! instructions
2 ;; Copyright (C) 2005-2013 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])
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 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
63 ;; Move patterns
65 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
67 ;; All of these patterns are enabled for MMX as well as 3dNOW.
68 ;; This is essential for maintaining stable calling conventions.
70 (define_expand "mov<mode>"
71   [(set (match_operand:MMXMODE 0 "nonimmediate_operand")
72         (match_operand:MMXMODE 1 "nonimmediate_operand"))]
73   "TARGET_MMX"
75   ix86_expand_vector_move (<MODE>mode, operands);
76   DONE;
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,x,x,x,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,x,m,x,C ,*x,m ,*x,Yj,r ,*Yj,!Yn"))]
84   "TARGET_MMX
85    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
87   switch (get_attr_type (insn))
88     {
89     case TYPE_MULTI:
90       return "#";
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}";
98     case TYPE_MMX:
99       return "pxor\t%0, %0";
101     case TYPE_MMXMOV:
102 #ifndef HAVE_AS_IX86_INTERUNIT_MOVQ
103       /* Handle broken assemblers that require movd instead of movq.  */
104       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
105         return "movd\t{%1, %0|%0, %1}";
106 #endif
107       return "movq\t{%1, %0|%0, %1}";
109     case TYPE_SSECVT:
110       if (SSE_REG_P (operands[0]))
111         return "movq2dq\t{%1, %0|%0, %1}";
112       else
113         return "movdq2q\t{%1, %0|%0, %1}";
115     case TYPE_SSELOG1:
116       return standard_sse_constant_opcode (insn, operands[1]);
118     case TYPE_SSEMOV:
119       switch (get_attr_mode (insn))
120         {
121         case MODE_DI:
122 #ifndef HAVE_AS_IX86_INTERUNIT_MOVQ
123           /* Handle broken assemblers that require movd instead of movq.  */
124           if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
125             return "%vmovd\t{%1, %0|%0, %1}";
126 #endif
127           return "%vmovq\t{%1, %0|%0, %1}";
128         case MODE_TI:
129           return "%vmovdqa\t{%1, %0|%0, %1}";
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}";
138         default:
139           gcc_unreachable ();
140         }
142     default:
143       gcc_unreachable ();
144     }
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 [(match_test "<MODE>mode == V2SFmode")
186                        (const_string "V4SF")
187                      (ior (not (match_test "TARGET_SSE2"))
188                           (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
189                        (const_string "V4SF")
190                      (match_test "TARGET_AVX")
191                        (const_string "TI")
192                      (match_test "optimize_function_for_size_p (cfun)")
193                        (const_string "V4SF")
194                     ]
195                     (const_string "TI"))
197             (and (eq_attr "alternative" "13,14,17,18")
198                  (ior (match_test "<MODE>mode == V2SFmode")
199                       (not (match_test "TARGET_SSE2"))))
200               (const_string "V2SF")
201            ]
202            (const_string "DI")))])
204 (define_split
205   [(set (match_operand:MMXMODE 0 "nonimmediate_operand")
206         (match_operand:MMXMODE 1 "general_operand"))]
207   "!TARGET_64BIT && reload_completed
208    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
209    && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
210   [(const_int 0)]
211   "ix86_split_long_move (operands); DONE;")
213 (define_expand "push<mode>1"
214   [(match_operand:MMXMODE 0 "register_operand")]
215   "TARGET_MMX"
217   ix86_expand_push (<MODE>mode, operands[0]);
218   DONE;
221 (define_expand "movmisalign<mode>"
222   [(set (match_operand:MMXMODE 0 "nonimmediate_operand")
223         (match_operand:MMXMODE 1 "nonimmediate_operand"))]
224   "TARGET_MMX"
226   ix86_expand_vector_move (<MODE>mode, operands);
227   DONE;
230 (define_insn "sse_movntq"
231   [(set (match_operand:DI 0 "memory_operand" "=m")
232         (unspec:DI [(match_operand:DI 1 "register_operand" "y")]
233                    UNSPEC_MOVNTQ))]
234   "TARGET_SSE || TARGET_3DNOW_A"
235   "movntq\t{%1, %0|%0, %1}"
236   [(set_attr "type" "mmxmov")
237    (set_attr "mode" "DI")])
239 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
241 ;; Parallel single-precision floating point arithmetic
243 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
245 (define_expand "mmx_addv2sf3"
246   [(set (match_operand:V2SF 0 "register_operand")
247         (plus:V2SF
248           (match_operand:V2SF 1 "nonimmediate_operand")
249           (match_operand:V2SF 2 "nonimmediate_operand")))]
250   "TARGET_3DNOW"
251   "ix86_fixup_binary_operands_no_copy (PLUS, V2SFmode, operands);")
253 (define_insn "*mmx_addv2sf3"
254   [(set (match_operand:V2SF 0 "register_operand" "=y")
255         (plus:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "%0")
256                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
257   "TARGET_3DNOW && ix86_binary_operator_ok (PLUS, V2SFmode, operands)"
258   "pfadd\t{%2, %0|%0, %2}"
259   [(set_attr "type" "mmxadd")
260    (set_attr "prefix_extra" "1")
261    (set_attr "mode" "V2SF")])
263 (define_expand "mmx_subv2sf3"
264   [(set (match_operand:V2SF 0 "register_operand")
265         (minus:V2SF (match_operand:V2SF 1 "register_operand")
266                     (match_operand:V2SF 2 "nonimmediate_operand")))]
267   "TARGET_3DNOW")
269 (define_expand "mmx_subrv2sf3"
270   [(set (match_operand:V2SF 0 "register_operand")
271         (minus:V2SF (match_operand:V2SF 2 "register_operand")
272                     (match_operand:V2SF 1 "nonimmediate_operand")))]
273   "TARGET_3DNOW")
275 (define_insn "*mmx_subv2sf3"
276   [(set (match_operand:V2SF 0 "register_operand" "=y,y")
277         (minus:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "0,ym")
278                     (match_operand:V2SF 2 "nonimmediate_operand" "ym,0")))]
279   "TARGET_3DNOW && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
280   "@
281    pfsub\t{%2, %0|%0, %2}
282    pfsubr\t{%1, %0|%0, %1}"
283   [(set_attr "type" "mmxadd")
284    (set_attr "prefix_extra" "1")
285    (set_attr "mode" "V2SF")])
287 (define_expand "mmx_mulv2sf3"
288   [(set (match_operand:V2SF 0 "register_operand")
289         (mult:V2SF (match_operand:V2SF 1 "nonimmediate_operand")
290                    (match_operand:V2SF 2 "nonimmediate_operand")))]
291   "TARGET_3DNOW"
292   "ix86_fixup_binary_operands_no_copy (MULT, V2SFmode, operands);")
294 (define_insn "*mmx_mulv2sf3"
295   [(set (match_operand:V2SF 0 "register_operand" "=y")
296         (mult:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "%0")
297                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
298   "TARGET_3DNOW && ix86_binary_operator_ok (MULT, V2SFmode, operands)"
299   "pfmul\t{%2, %0|%0, %2}"
300   [(set_attr "type" "mmxmul")
301    (set_attr "prefix_extra" "1")
302    (set_attr "mode" "V2SF")])
304 ;; ??? For !flag_finite_math_only, the representation with SMIN/SMAX
305 ;; isn't really correct, as those rtl operators aren't defined when
306 ;; applied to NaNs.  Hopefully the optimizers won't get too smart on us.
308 (define_expand "mmx_<code>v2sf3"
309   [(set (match_operand:V2SF 0 "register_operand")
310         (smaxmin:V2SF
311           (match_operand:V2SF 1 "nonimmediate_operand")
312           (match_operand:V2SF 2 "nonimmediate_operand")))]
313   "TARGET_3DNOW"
315   if (!flag_finite_math_only)
316     operands[1] = force_reg (V2SFmode, operands[1]);
317   ix86_fixup_binary_operands_no_copy (<CODE>, V2SFmode, operands);
320 (define_insn "*mmx_<code>v2sf3_finite"
321   [(set (match_operand:V2SF 0 "register_operand" "=y")
322         (smaxmin:V2SF
323           (match_operand:V2SF 1 "nonimmediate_operand" "%0")
324           (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
325   "TARGET_3DNOW && flag_finite_math_only
326    && ix86_binary_operator_ok (<CODE>, V2SFmode, operands)"
327   "pf<maxmin_float>\t{%2, %0|%0, %2}"
328   [(set_attr "type" "mmxadd")
329    (set_attr "prefix_extra" "1")
330    (set_attr "mode" "V2SF")])
332 (define_insn "*mmx_<code>v2sf3"
333   [(set (match_operand:V2SF 0 "register_operand" "=y")
334         (smaxmin:V2SF
335           (match_operand:V2SF 1 "register_operand" "0")
336           (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
337   "TARGET_3DNOW"
338   "pf<maxmin_float>\t{%2, %0|%0, %2}"
339   [(set_attr "type" "mmxadd")
340    (set_attr "prefix_extra" "1")
341    (set_attr "mode" "V2SF")])
343 (define_insn "mmx_rcpv2sf2"
344   [(set (match_operand:V2SF 0 "register_operand" "=y")
345         (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
346                      UNSPEC_PFRCP))]
347   "TARGET_3DNOW"
348   "pfrcp\t{%1, %0|%0, %1}"
349   [(set_attr "type" "mmx")
350    (set_attr "prefix_extra" "1")
351    (set_attr "mode" "V2SF")])
353 (define_insn "mmx_rcpit1v2sf3"
354   [(set (match_operand:V2SF 0 "register_operand" "=y")
355         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
356                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
357                      UNSPEC_PFRCPIT1))]
358   "TARGET_3DNOW"
359   "pfrcpit1\t{%2, %0|%0, %2}"
360   [(set_attr "type" "mmx")
361    (set_attr "prefix_extra" "1")
362    (set_attr "mode" "V2SF")])
364 (define_insn "mmx_rcpit2v2sf3"
365   [(set (match_operand:V2SF 0 "register_operand" "=y")
366         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
367                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
368                      UNSPEC_PFRCPIT2))]
369   "TARGET_3DNOW"
370   "pfrcpit2\t{%2, %0|%0, %2}"
371   [(set_attr "type" "mmx")
372    (set_attr "prefix_extra" "1")
373    (set_attr "mode" "V2SF")])
375 (define_insn "mmx_rsqrtv2sf2"
376   [(set (match_operand:V2SF 0 "register_operand" "=y")
377         (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
378                      UNSPEC_PFRSQRT))]
379   "TARGET_3DNOW"
380   "pfrsqrt\t{%1, %0|%0, %1}"
381   [(set_attr "type" "mmx")
382    (set_attr "prefix_extra" "1")
383    (set_attr "mode" "V2SF")])
385 (define_insn "mmx_rsqit1v2sf3"
386   [(set (match_operand:V2SF 0 "register_operand" "=y")
387         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
388                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
389                      UNSPEC_PFRSQIT1))]
390   "TARGET_3DNOW"
391   "pfrsqit1\t{%2, %0|%0, %2}"
392   [(set_attr "type" "mmx")
393    (set_attr "prefix_extra" "1")
394    (set_attr "mode" "V2SF")])
396 (define_insn "mmx_haddv2sf3"
397   [(set (match_operand:V2SF 0 "register_operand" "=y")
398         (vec_concat:V2SF
399           (plus:SF
400             (vec_select:SF
401               (match_operand:V2SF 1 "register_operand" "0")
402               (parallel [(const_int  0)]))
403             (vec_select:SF (match_dup 1) (parallel [(const_int 1)])))
404           (plus:SF
405             (vec_select:SF
406               (match_operand:V2SF 2 "nonimmediate_operand" "ym")
407               (parallel [(const_int  0)]))
408             (vec_select:SF (match_dup 2) (parallel [(const_int 1)])))))]
409   "TARGET_3DNOW"
410   "pfacc\t{%2, %0|%0, %2}"
411   [(set_attr "type" "mmxadd")
412    (set_attr "prefix_extra" "1")
413    (set_attr "mode" "V2SF")])
415 (define_insn "mmx_hsubv2sf3"
416   [(set (match_operand:V2SF 0 "register_operand" "=y")
417         (vec_concat:V2SF
418           (minus:SF
419             (vec_select:SF
420               (match_operand:V2SF 1 "register_operand" "0")
421               (parallel [(const_int  0)]))
422             (vec_select:SF (match_dup 1) (parallel [(const_int 1)])))
423           (minus:SF
424             (vec_select:SF
425               (match_operand:V2SF 2 "nonimmediate_operand" "ym")
426               (parallel [(const_int  0)]))
427             (vec_select:SF (match_dup 2) (parallel [(const_int 1)])))))]
428   "TARGET_3DNOW_A"
429   "pfnacc\t{%2, %0|%0, %2}"
430   [(set_attr "type" "mmxadd")
431    (set_attr "prefix_extra" "1")
432    (set_attr "mode" "V2SF")])
434 (define_insn "mmx_addsubv2sf3"
435   [(set (match_operand:V2SF 0 "register_operand" "=y")
436         (vec_merge:V2SF
437           (plus:V2SF
438             (match_operand:V2SF 1 "register_operand" "0")
439             (match_operand:V2SF 2 "nonimmediate_operand" "ym"))
440           (minus:V2SF (match_dup 1) (match_dup 2))
441           (const_int 1)))]
442   "TARGET_3DNOW_A"
443   "pfpnacc\t{%2, %0|%0, %2}"
444   [(set_attr "type" "mmxadd")
445    (set_attr "prefix_extra" "1")
446    (set_attr "mode" "V2SF")])
448 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
450 ;; Parallel single-precision floating point comparisons
452 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
454 (define_expand "mmx_eqv2sf3"
455   [(set (match_operand:V2SI 0 "register_operand")
456         (eq:V2SI (match_operand:V2SF 1 "nonimmediate_operand")
457                  (match_operand:V2SF 2 "nonimmediate_operand")))]
458   "TARGET_3DNOW"
459   "ix86_fixup_binary_operands_no_copy (EQ, V2SFmode, operands);")
461 (define_insn "*mmx_eqv2sf3"
462   [(set (match_operand:V2SI 0 "register_operand" "=y")
463         (eq:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "%0")
464                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
465   "TARGET_3DNOW && ix86_binary_operator_ok (EQ, V2SFmode, operands)"
466   "pfcmpeq\t{%2, %0|%0, %2}"
467   [(set_attr "type" "mmxcmp")
468    (set_attr "prefix_extra" "1")
469    (set_attr "mode" "V2SF")])
471 (define_insn "mmx_gtv2sf3"
472   [(set (match_operand:V2SI 0 "register_operand" "=y")
473         (gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
474                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
475   "TARGET_3DNOW"
476   "pfcmpgt\t{%2, %0|%0, %2}"
477   [(set_attr "type" "mmxcmp")
478    (set_attr "prefix_extra" "1")
479    (set_attr "mode" "V2SF")])
481 (define_insn "mmx_gev2sf3"
482   [(set (match_operand:V2SI 0 "register_operand" "=y")
483         (ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
484                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
485   "TARGET_3DNOW"
486   "pfcmpge\t{%2, %0|%0, %2}"
487   [(set_attr "type" "mmxcmp")
488    (set_attr "prefix_extra" "1")
489    (set_attr "mode" "V2SF")])
491 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
493 ;; Parallel single-precision floating point conversion operations
495 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
497 (define_insn "mmx_pf2id"
498   [(set (match_operand:V2SI 0 "register_operand" "=y")
499         (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
500   "TARGET_3DNOW"
501   "pf2id\t{%1, %0|%0, %1}"
502   [(set_attr "type" "mmxcvt")
503    (set_attr "prefix_extra" "1")
504    (set_attr "mode" "V2SF")])
506 (define_insn "mmx_pf2iw"
507   [(set (match_operand:V2SI 0 "register_operand" "=y")
508         (sign_extend:V2SI
509           (ss_truncate:V2HI
510             (fix:V2SI
511               (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
512   "TARGET_3DNOW_A"
513   "pf2iw\t{%1, %0|%0, %1}"
514   [(set_attr "type" "mmxcvt")
515    (set_attr "prefix_extra" "1")
516    (set_attr "mode" "V2SF")])
518 (define_insn "mmx_pi2fw"
519   [(set (match_operand:V2SF 0 "register_operand" "=y")
520         (float:V2SF
521           (sign_extend:V2SI
522             (truncate:V2HI
523               (match_operand:V2SI 1 "nonimmediate_operand" "ym")))))]
524   "TARGET_3DNOW_A"
525   "pi2fw\t{%1, %0|%0, %1}"
526   [(set_attr "type" "mmxcvt")
527    (set_attr "prefix_extra" "1")
528    (set_attr "mode" "V2SF")])
530 (define_insn "mmx_floatv2si2"
531   [(set (match_operand:V2SF 0 "register_operand" "=y")
532         (float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
533   "TARGET_3DNOW"
534   "pi2fd\t{%1, %0|%0, %1}"
535   [(set_attr "type" "mmxcvt")
536    (set_attr "prefix_extra" "1")
537    (set_attr "mode" "V2SF")])
539 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
541 ;; Parallel single-precision floating point element swizzling
543 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
545 (define_insn "mmx_pswapdv2sf2"
546   [(set (match_operand:V2SF 0 "register_operand" "=y")
547         (vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym")
548                          (parallel [(const_int 1) (const_int 0)])))]
549   "TARGET_3DNOW_A"
550   "pswapd\t{%1, %0|%0, %1}"
551   [(set_attr "type" "mmxcvt")
552    (set_attr "prefix_extra" "1")
553    (set_attr "mode" "V2SF")])
555 (define_insn "*vec_dupv2sf"
556   [(set (match_operand:V2SF 0 "register_operand" "=y")
557         (vec_duplicate:V2SF
558           (match_operand:SF 1 "register_operand" "0")))]
559   "TARGET_MMX"
560   "punpckldq\t%0, %0"
561   [(set_attr "type" "mmxcvt")
562    (set_attr "mode" "DI")])
564 (define_insn "*mmx_concatv2sf"
565   [(set (match_operand:V2SF 0 "register_operand"     "=y,y")
566         (vec_concat:V2SF
567           (match_operand:SF 1 "nonimmediate_operand" " 0,rm")
568           (match_operand:SF 2 "vector_move_operand"  "ym,C")))]
569   "TARGET_MMX && !TARGET_SSE"
570   "@
571    punpckldq\t{%2, %0|%0, %2}
572    movd\t{%1, %0|%0, %1}"
573   [(set_attr "type" "mmxcvt,mmxmov")
574    (set_attr "mode" "DI")])
576 (define_expand "vec_setv2sf"
577   [(match_operand:V2SF 0 "register_operand")
578    (match_operand:SF 1 "register_operand")
579    (match_operand 2 "const_int_operand")]
580   "TARGET_MMX"
582   ix86_expand_vector_set (false, operands[0], operands[1],
583                           INTVAL (operands[2]));
584   DONE;
587 ;; Avoid combining registers from different units in a single alternative,
588 ;; see comment above inline_secondary_memory_needed function in i386.c
589 (define_insn_and_split "*vec_extractv2sf_0"
590   [(set (match_operand:SF 0 "nonimmediate_operand"     "=x, m,y ,m,f,r")
591         (vec_select:SF
592           (match_operand:V2SF 1 "nonimmediate_operand" " xm,x,ym,y,m,m")
593           (parallel [(const_int 0)])))]
594   "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
595   "#"
596   "&& reload_completed"
597   [(const_int 0)]
599   rtx op1 = operands[1];
600   if (REG_P (op1))
601     op1 = gen_rtx_REG (SFmode, REGNO (op1));
602   else
603     op1 = gen_lowpart (SFmode, op1);
604   emit_move_insn (operands[0], op1);
605   DONE;
608 ;; Avoid combining registers from different units in a single alternative,
609 ;; see comment above inline_secondary_memory_needed function in i386.c
610 (define_insn "*vec_extractv2sf_1"
611   [(set (match_operand:SF 0 "nonimmediate_operand"     "=y,x,y,x,f,r")
612         (vec_select:SF
613           (match_operand:V2SF 1 "nonimmediate_operand" " 0,0,o,o,o,o")
614           (parallel [(const_int 1)])))]
615   "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
616   "@
617    punpckhdq\t%0, %0
618    unpckhps\t%0, %0
619    #
620    #
621    #
622    #"
623   [(set_attr "type" "mmxcvt,sselog1,mmxmov,ssemov,fmov,imov")
624    (set_attr "mode" "DI,V4SF,SF,SF,SF,SF")])
626 (define_split
627   [(set (match_operand:SF 0 "register_operand")
628         (vec_select:SF
629           (match_operand:V2SF 1 "memory_operand")
630           (parallel [(const_int 1)])))]
631   "TARGET_MMX && reload_completed"
632   [(const_int 0)]
634   operands[1] = adjust_address (operands[1], SFmode, 4);
635   emit_move_insn (operands[0], operands[1]);
636   DONE;
639 (define_expand "vec_extractv2sf"
640   [(match_operand:SF 0 "register_operand")
641    (match_operand:V2SF 1 "register_operand")
642    (match_operand 2 "const_int_operand")]
643   "TARGET_MMX"
645   ix86_expand_vector_extract (false, operands[0], operands[1],
646                               INTVAL (operands[2]));
647   DONE;
650 (define_expand "vec_initv2sf"
651   [(match_operand:V2SF 0 "register_operand")
652    (match_operand 1)]
653   "TARGET_SSE"
655   ix86_expand_vector_init (false, operands[0], operands[1]);
656   DONE;
659 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
661 ;; Parallel integral arithmetic
663 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
665 (define_expand "mmx_<plusminus_insn><mode>3"
666   [(set (match_operand:MMXMODEI8 0 "register_operand")
667         (plusminus:MMXMODEI8
668           (match_operand:MMXMODEI8 1 "nonimmediate_operand")
669           (match_operand:MMXMODEI8 2 "nonimmediate_operand")))]
670   "TARGET_MMX || (TARGET_SSE2 && <MODE>mode == V1DImode)"
671   "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
673 (define_insn "*mmx_<plusminus_insn><mode>3"
674   [(set (match_operand:MMXMODEI8 0 "register_operand" "=y")
675         (plusminus:MMXMODEI8
676           (match_operand:MMXMODEI8 1 "nonimmediate_operand" "<comm>0")
677           (match_operand:MMXMODEI8 2 "nonimmediate_operand" "ym")))]
678   "(TARGET_MMX || (TARGET_SSE2 && <MODE>mode == V1DImode))
679    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
680   "p<plusminus_mnemonic><mmxvecsize>\t{%2, %0|%0, %2}"
681   [(set_attr "type" "mmxadd")
682    (set_attr "mode" "DI")])
684 (define_expand "mmx_<plusminus_insn><mode>3"
685   [(set (match_operand:MMXMODE12 0 "register_operand")
686         (sat_plusminus:MMXMODE12
687           (match_operand:MMXMODE12 1 "nonimmediate_operand")
688           (match_operand:MMXMODE12 2 "nonimmediate_operand")))]
689   "TARGET_MMX"
690   "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
692 (define_insn "*mmx_<plusminus_insn><mode>3"
693   [(set (match_operand:MMXMODE12 0 "register_operand" "=y")
694         (sat_plusminus:MMXMODE12
695           (match_operand:MMXMODE12 1 "nonimmediate_operand" "<comm>0")
696           (match_operand:MMXMODE12 2 "nonimmediate_operand" "ym")))]
697   "TARGET_MMX && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
698   "p<plusminus_mnemonic><mmxvecsize>\t{%2, %0|%0, %2}"
699   [(set_attr "type" "mmxadd")
700    (set_attr "mode" "DI")])
702 (define_expand "mmx_mulv4hi3"
703   [(set (match_operand:V4HI 0 "register_operand")
704         (mult:V4HI (match_operand:V4HI 1 "nonimmediate_operand")
705                    (match_operand:V4HI 2 "nonimmediate_operand")))]
706   "TARGET_MMX"
707   "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
709 (define_insn "*mmx_mulv4hi3"
710   [(set (match_operand:V4HI 0 "register_operand" "=y")
711         (mult:V4HI (match_operand:V4HI 1 "nonimmediate_operand" "%0")
712                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
713   "TARGET_MMX && ix86_binary_operator_ok (MULT, V4HImode, operands)"
714   "pmullw\t{%2, %0|%0, %2}"
715   [(set_attr "type" "mmxmul")
716    (set_attr "mode" "DI")])
718 (define_expand "mmx_smulv4hi3_highpart"
719   [(set (match_operand:V4HI 0 "register_operand")
720         (truncate:V4HI
721           (lshiftrt:V4SI
722             (mult:V4SI
723               (sign_extend:V4SI
724                 (match_operand:V4HI 1 "nonimmediate_operand"))
725               (sign_extend:V4SI
726                 (match_operand:V4HI 2 "nonimmediate_operand")))
727             (const_int 16))))]
728   "TARGET_MMX"
729   "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
731 (define_insn "*mmx_smulv4hi3_highpart"
732   [(set (match_operand:V4HI 0 "register_operand" "=y")
733         (truncate:V4HI
734           (lshiftrt:V4SI
735             (mult:V4SI
736               (sign_extend:V4SI
737                 (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
738               (sign_extend:V4SI
739                 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
740             (const_int 16))))]
741   "TARGET_MMX && ix86_binary_operator_ok (MULT, V4HImode, operands)"
742   "pmulhw\t{%2, %0|%0, %2}"
743   [(set_attr "type" "mmxmul")
744    (set_attr "mode" "DI")])
746 (define_expand "mmx_umulv4hi3_highpart"
747   [(set (match_operand:V4HI 0 "register_operand")
748         (truncate:V4HI
749           (lshiftrt:V4SI
750             (mult:V4SI
751               (zero_extend:V4SI
752                 (match_operand:V4HI 1 "nonimmediate_operand"))
753               (zero_extend:V4SI
754                 (match_operand:V4HI 2 "nonimmediate_operand")))
755             (const_int 16))))]
756   "TARGET_SSE || TARGET_3DNOW_A"
757   "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
759 (define_insn "*mmx_umulv4hi3_highpart"
760   [(set (match_operand:V4HI 0 "register_operand" "=y")
761         (truncate:V4HI
762           (lshiftrt:V4SI
763             (mult:V4SI
764               (zero_extend:V4SI
765                 (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
766               (zero_extend:V4SI
767                 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
768           (const_int 16))))]
769   "(TARGET_SSE || TARGET_3DNOW_A)
770    && ix86_binary_operator_ok (MULT, V4HImode, operands)"
771   "pmulhuw\t{%2, %0|%0, %2}"
772   [(set_attr "type" "mmxmul")
773    (set_attr "mode" "DI")])
775 (define_expand "mmx_pmaddwd"
776   [(set (match_operand:V2SI 0 "register_operand")
777         (plus:V2SI
778           (mult:V2SI
779             (sign_extend:V2SI
780               (vec_select:V2HI
781                 (match_operand:V4HI 1 "nonimmediate_operand")
782                 (parallel [(const_int 0) (const_int 2)])))
783             (sign_extend:V2SI
784               (vec_select:V2HI
785                 (match_operand:V4HI 2 "nonimmediate_operand")
786                 (parallel [(const_int 0) (const_int 2)]))))
787           (mult:V2SI
788             (sign_extend:V2SI
789               (vec_select:V2HI (match_dup 1)
790                 (parallel [(const_int 1) (const_int 3)])))
791             (sign_extend:V2SI
792               (vec_select:V2HI (match_dup 2)
793                 (parallel [(const_int 1) (const_int 3)]))))))]
794   "TARGET_MMX"
795   "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
797 (define_insn "*mmx_pmaddwd"
798   [(set (match_operand:V2SI 0 "register_operand" "=y")
799         (plus:V2SI
800           (mult:V2SI
801             (sign_extend:V2SI
802               (vec_select:V2HI
803                 (match_operand:V4HI 1 "nonimmediate_operand" "%0")
804                 (parallel [(const_int 0) (const_int 2)])))
805             (sign_extend:V2SI
806               (vec_select:V2HI
807                 (match_operand:V4HI 2 "nonimmediate_operand" "ym")
808                 (parallel [(const_int 0) (const_int 2)]))))
809           (mult:V2SI
810             (sign_extend:V2SI
811               (vec_select:V2HI (match_dup 1)
812                 (parallel [(const_int 1) (const_int 3)])))
813             (sign_extend:V2SI
814               (vec_select:V2HI (match_dup 2)
815                 (parallel [(const_int 1) (const_int 3)]))))))]
816   "TARGET_MMX && ix86_binary_operator_ok (MULT, V4HImode, operands)"
817   "pmaddwd\t{%2, %0|%0, %2}"
818   [(set_attr "type" "mmxmul")
819    (set_attr "mode" "DI")])
821 (define_expand "mmx_pmulhrwv4hi3"
822   [(set (match_operand:V4HI 0 "register_operand")
823         (truncate:V4HI
824           (lshiftrt:V4SI
825             (plus:V4SI
826               (mult:V4SI
827                 (sign_extend:V4SI
828                   (match_operand:V4HI 1 "nonimmediate_operand"))
829                 (sign_extend:V4SI
830                   (match_operand:V4HI 2 "nonimmediate_operand")))
831               (const_vector:V4SI [(const_int 32768) (const_int 32768)
832                                   (const_int 32768) (const_int 32768)]))
833             (const_int 16))))]
834   "TARGET_3DNOW"
835   "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
837 (define_insn "*mmx_pmulhrwv4hi3"
838   [(set (match_operand:V4HI 0 "register_operand" "=y")
839         (truncate:V4HI
840           (lshiftrt:V4SI
841             (plus:V4SI
842               (mult:V4SI
843                 (sign_extend:V4SI
844                   (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
845                 (sign_extend:V4SI
846                   (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
847               (const_vector:V4SI [(const_int 32768) (const_int 32768)
848                                   (const_int 32768) (const_int 32768)]))
849             (const_int 16))))]
850   "TARGET_3DNOW && ix86_binary_operator_ok (MULT, V4HImode, operands)"
851   "pmulhrw\t{%2, %0|%0, %2}"
852   [(set_attr "type" "mmxmul")
853    (set_attr "prefix_extra" "1")
854    (set_attr "mode" "DI")])
856 (define_expand "sse2_umulv1siv1di3"
857   [(set (match_operand:V1DI 0 "register_operand")
858         (mult:V1DI
859           (zero_extend:V1DI
860             (vec_select:V1SI
861               (match_operand:V2SI 1 "nonimmediate_operand")
862               (parallel [(const_int 0)])))
863           (zero_extend:V1DI
864             (vec_select:V1SI
865               (match_operand:V2SI 2 "nonimmediate_operand")
866               (parallel [(const_int 0)])))))]
867   "TARGET_SSE2"
868   "ix86_fixup_binary_operands_no_copy (MULT, V2SImode, operands);")
870 (define_insn "*sse2_umulv1siv1di3"
871   [(set (match_operand:V1DI 0 "register_operand" "=y")
872         (mult:V1DI
873           (zero_extend:V1DI
874             (vec_select:V1SI
875               (match_operand:V2SI 1 "nonimmediate_operand" "%0")
876               (parallel [(const_int 0)])))
877           (zero_extend:V1DI
878             (vec_select:V1SI
879               (match_operand:V2SI 2 "nonimmediate_operand" "ym")
880               (parallel [(const_int 0)])))))]
881   "TARGET_SSE2 && ix86_binary_operator_ok (MULT, V2SImode, operands)"
882   "pmuludq\t{%2, %0|%0, %2}"
883   [(set_attr "type" "mmxmul")
884    (set_attr "mode" "DI")])
886 (define_expand "mmx_<code>v4hi3"
887   [(set (match_operand:V4HI 0 "register_operand")
888         (smaxmin:V4HI
889           (match_operand:V4HI 1 "nonimmediate_operand")
890           (match_operand:V4HI 2 "nonimmediate_operand")))]
891   "TARGET_SSE || TARGET_3DNOW_A"
892   "ix86_fixup_binary_operands_no_copy (<CODE>, V4HImode, operands);")
894 (define_insn "*mmx_<code>v4hi3"
895   [(set (match_operand:V4HI 0 "register_operand" "=y")
896         (smaxmin:V4HI
897           (match_operand:V4HI 1 "nonimmediate_operand" "%0")
898           (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
899   "(TARGET_SSE || TARGET_3DNOW_A)
900    && ix86_binary_operator_ok (<CODE>, V4HImode, operands)"
901   "p<maxmin_int>w\t{%2, %0|%0, %2}"
902   [(set_attr "type" "mmxadd")
903    (set_attr "mode" "DI")])
905 (define_expand "mmx_<code>v8qi3"
906   [(set (match_operand:V8QI 0 "register_operand")
907         (umaxmin:V8QI
908           (match_operand:V8QI 1 "nonimmediate_operand")
909           (match_operand:V8QI 2 "nonimmediate_operand")))]
910   "TARGET_SSE || TARGET_3DNOW_A"
911   "ix86_fixup_binary_operands_no_copy (<CODE>, V8QImode, operands);")
913 (define_insn "*mmx_<code>v8qi3"
914   [(set (match_operand:V8QI 0 "register_operand" "=y")
915         (umaxmin:V8QI
916           (match_operand:V8QI 1 "nonimmediate_operand" "%0")
917           (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
918   "(TARGET_SSE || TARGET_3DNOW_A)
919    && ix86_binary_operator_ok (<CODE>, V8QImode, operands)"
920   "p<maxmin_int>b\t{%2, %0|%0, %2}"
921   [(set_attr "type" "mmxadd")
922    (set_attr "mode" "DI")])
924 (define_insn "mmx_ashr<mode>3"
925   [(set (match_operand:MMXMODE24 0 "register_operand" "=y")
926         (ashiftrt:MMXMODE24
927           (match_operand:MMXMODE24 1 "register_operand" "0")
928           (match_operand:SI 2 "nonmemory_operand" "yN")))]
929   "TARGET_MMX"
930   "psra<mmxvecsize>\t{%2, %0|%0, %2}"
931   [(set_attr "type" "mmxshft")
932    (set (attr "length_immediate")
933      (if_then_else (match_operand 2 "const_int_operand")
934        (const_string "1")
935        (const_string "0")))
936    (set_attr "mode" "DI")])
938 (define_insn "mmx_<shift_insn><mode>3"
939   [(set (match_operand:MMXMODE248 0 "register_operand" "=y")
940         (any_lshift:MMXMODE248
941           (match_operand:MMXMODE248 1 "register_operand" "0")
942           (match_operand:SI 2 "nonmemory_operand" "yN")))]
943   "TARGET_MMX"
944   "p<vshift><mmxvecsize>\t{%2, %0|%0, %2}"
945   [(set_attr "type" "mmxshft")
946    (set (attr "length_immediate")
947      (if_then_else (match_operand 2 "const_int_operand")
948        (const_string "1")
949        (const_string "0")))
950    (set_attr "mode" "DI")])
952 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
954 ;; Parallel integral comparisons
956 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
958 (define_expand "mmx_eq<mode>3"
959   [(set (match_operand:MMXMODEI 0 "register_operand")
960         (eq:MMXMODEI
961           (match_operand:MMXMODEI 1 "nonimmediate_operand")
962           (match_operand:MMXMODEI 2 "nonimmediate_operand")))]
963   "TARGET_MMX"
964   "ix86_fixup_binary_operands_no_copy (EQ, <MODE>mode, operands);")
966 (define_insn "*mmx_eq<mode>3"
967   [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
968         (eq:MMXMODEI
969           (match_operand:MMXMODEI 1 "nonimmediate_operand" "%0")
970           (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
971   "TARGET_MMX && ix86_binary_operator_ok (EQ, <MODE>mode, operands)"
972   "pcmpeq<mmxvecsize>\t{%2, %0|%0, %2}"
973   [(set_attr "type" "mmxcmp")
974    (set_attr "mode" "DI")])
976 (define_insn "mmx_gt<mode>3"
977   [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
978         (gt:MMXMODEI
979           (match_operand:MMXMODEI 1 "register_operand" "0")
980           (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
981   "TARGET_MMX"
982   "pcmpgt<mmxvecsize>\t{%2, %0|%0, %2}"
983   [(set_attr "type" "mmxcmp")
984    (set_attr "mode" "DI")])
986 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
988 ;; Parallel integral logical operations
990 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
992 (define_insn "mmx_andnot<mode>3"
993   [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
994         (and:MMXMODEI
995           (not:MMXMODEI (match_operand:MMXMODEI 1 "register_operand" "0"))
996           (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
997   "TARGET_MMX"
998   "pandn\t{%2, %0|%0, %2}"
999   [(set_attr "type" "mmxadd")
1000    (set_attr "mode" "DI")])
1002 (define_expand "mmx_<code><mode>3"
1003   [(set (match_operand:MMXMODEI 0 "register_operand")
1004         (any_logic:MMXMODEI
1005           (match_operand:MMXMODEI 1 "nonimmediate_operand")
1006           (match_operand:MMXMODEI 2 "nonimmediate_operand")))]
1007   "TARGET_MMX"
1008   "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
1010 (define_insn "*mmx_<code><mode>3"
1011   [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
1012         (any_logic:MMXMODEI
1013           (match_operand:MMXMODEI 1 "nonimmediate_operand" "%0")
1014           (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
1015   "TARGET_MMX && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
1016   "p<logic>\t{%2, %0|%0, %2}"
1017   [(set_attr "type" "mmxadd")
1018    (set_attr "mode" "DI")])
1020 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1022 ;; Parallel integral element swizzling
1024 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1026 (define_insn "mmx_packsswb"
1027   [(set (match_operand:V8QI 0 "register_operand" "=y")
1028         (vec_concat:V8QI
1029           (ss_truncate:V4QI
1030             (match_operand:V4HI 1 "register_operand" "0"))
1031           (ss_truncate:V4QI
1032             (match_operand:V4HI 2 "nonimmediate_operand" "ym"))))]
1033   "TARGET_MMX"
1034   "packsswb\t{%2, %0|%0, %2}"
1035   [(set_attr "type" "mmxshft")
1036    (set_attr "mode" "DI")])
1038 (define_insn "mmx_packssdw"
1039   [(set (match_operand:V4HI 0 "register_operand" "=y")
1040         (vec_concat:V4HI
1041           (ss_truncate:V2HI
1042             (match_operand:V2SI 1 "register_operand" "0"))
1043           (ss_truncate:V2HI
1044             (match_operand:V2SI 2 "nonimmediate_operand" "ym"))))]
1045   "TARGET_MMX"
1046   "packssdw\t{%2, %0|%0, %2}"
1047   [(set_attr "type" "mmxshft")
1048    (set_attr "mode" "DI")])
1050 (define_insn "mmx_packuswb"
1051   [(set (match_operand:V8QI 0 "register_operand" "=y")
1052         (vec_concat:V8QI
1053           (us_truncate:V4QI
1054             (match_operand:V4HI 1 "register_operand" "0"))
1055           (us_truncate:V4QI
1056             (match_operand:V4HI 2 "nonimmediate_operand" "ym"))))]
1057   "TARGET_MMX"
1058   "packuswb\t{%2, %0|%0, %2}"
1059   [(set_attr "type" "mmxshft")
1060    (set_attr "mode" "DI")])
1062 (define_insn "mmx_punpckhbw"
1063   [(set (match_operand:V8QI 0 "register_operand" "=y")
1064         (vec_select:V8QI
1065           (vec_concat:V16QI
1066             (match_operand:V8QI 1 "register_operand" "0")
1067             (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
1068           (parallel [(const_int 4) (const_int 12)
1069                      (const_int 5) (const_int 13)
1070                      (const_int 6) (const_int 14)
1071                      (const_int 7) (const_int 15)])))]
1072   "TARGET_MMX"
1073   "punpckhbw\t{%2, %0|%0, %2}"
1074   [(set_attr "type" "mmxcvt")
1075    (set_attr "mode" "DI")])
1077 (define_insn "mmx_punpcklbw"
1078   [(set (match_operand:V8QI 0 "register_operand" "=y")
1079         (vec_select:V8QI
1080           (vec_concat:V16QI
1081             (match_operand:V8QI 1 "register_operand" "0")
1082             (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
1083           (parallel [(const_int 0) (const_int 8)
1084                      (const_int 1) (const_int 9)
1085                      (const_int 2) (const_int 10)
1086                      (const_int 3) (const_int 11)])))]
1087   "TARGET_MMX"
1088   "punpcklbw\t{%2, %0|%0, %2}"
1089   [(set_attr "type" "mmxcvt")
1090    (set_attr "mode" "DI")])
1092 (define_insn "mmx_punpckhwd"
1093   [(set (match_operand:V4HI 0 "register_operand" "=y")
1094         (vec_select:V4HI
1095           (vec_concat:V8HI
1096             (match_operand:V4HI 1 "register_operand" "0")
1097             (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
1098           (parallel [(const_int 2) (const_int 6)
1099                      (const_int 3) (const_int 7)])))]
1100   "TARGET_MMX"
1101   "punpckhwd\t{%2, %0|%0, %2}"
1102   [(set_attr "type" "mmxcvt")
1103    (set_attr "mode" "DI")])
1105 (define_insn "mmx_punpcklwd"
1106   [(set (match_operand:V4HI 0 "register_operand" "=y")
1107         (vec_select:V4HI
1108           (vec_concat:V8HI
1109             (match_operand:V4HI 1 "register_operand" "0")
1110             (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
1111           (parallel [(const_int 0) (const_int 4)
1112                      (const_int 1) (const_int 5)])))]
1113   "TARGET_MMX"
1114   "punpcklwd\t{%2, %0|%0, %2}"
1115   [(set_attr "type" "mmxcvt")
1116    (set_attr "mode" "DI")])
1118 (define_insn "mmx_punpckhdq"
1119   [(set (match_operand:V2SI 0 "register_operand" "=y")
1120         (vec_select:V2SI
1121           (vec_concat:V4SI
1122             (match_operand:V2SI 1 "register_operand" "0")
1123             (match_operand:V2SI 2 "nonimmediate_operand" "ym"))
1124           (parallel [(const_int 1)
1125                      (const_int 3)])))]
1126   "TARGET_MMX"
1127   "punpckhdq\t{%2, %0|%0, %2}"
1128   [(set_attr "type" "mmxcvt")
1129    (set_attr "mode" "DI")])
1131 (define_insn "mmx_punpckldq"
1132   [(set (match_operand:V2SI 0 "register_operand" "=y")
1133         (vec_select:V2SI
1134           (vec_concat:V4SI
1135             (match_operand:V2SI 1 "register_operand" "0")
1136             (match_operand:V2SI 2 "nonimmediate_operand" "ym"))
1137           (parallel [(const_int 0)
1138                      (const_int 2)])))]
1139   "TARGET_MMX"
1140   "punpckldq\t{%2, %0|%0, %2}"
1141   [(set_attr "type" "mmxcvt")
1142    (set_attr "mode" "DI")])
1144 (define_expand "mmx_pinsrw"
1145   [(set (match_operand:V4HI 0 "register_operand")
1146         (vec_merge:V4HI
1147           (vec_duplicate:V4HI
1148             (match_operand:SI 2 "nonimmediate_operand"))
1149           (match_operand:V4HI 1 "register_operand")
1150           (match_operand:SI 3 "const_0_to_3_operand")))]
1151   "TARGET_SSE || TARGET_3DNOW_A"
1153   operands[2] = gen_lowpart (HImode, operands[2]);
1154   operands[3] = GEN_INT (1 << INTVAL (operands[3]));
1157 (define_insn "*mmx_pinsrw"
1158   [(set (match_operand:V4HI 0 "register_operand" "=y")
1159         (vec_merge:V4HI
1160           (vec_duplicate:V4HI
1161             (match_operand:HI 2 "nonimmediate_operand" "rm"))
1162           (match_operand:V4HI 1 "register_operand" "0")
1163           (match_operand:SI 3 "const_int_operand")))]
1164   "(TARGET_SSE || TARGET_3DNOW_A)
1165    && ((unsigned) exact_log2 (INTVAL (operands[3]))
1166        < GET_MODE_NUNITS (V4HImode))"
1168   operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])));
1169   if (MEM_P (operands[2]))
1170     return "pinsrw\t{%3, %2, %0|%0, %2, %3}";
1171   else
1172     return "pinsrw\t{%3, %k2, %0|%0, %k2, %3}";
1174   [(set_attr "type" "mmxcvt")
1175    (set_attr "length_immediate" "1")
1176    (set_attr "mode" "DI")])
1178 (define_insn "mmx_pextrw"
1179   [(set (match_operand:SI 0 "register_operand" "=r")
1180         (zero_extend:SI
1181           (vec_select:HI
1182             (match_operand:V4HI 1 "register_operand" "y")
1183             (parallel [(match_operand:SI 2 "const_0_to_3_operand" "n")]))))]
1184   "TARGET_SSE || TARGET_3DNOW_A"
1185   "pextrw\t{%2, %1, %0|%0, %1, %2}"
1186   [(set_attr "type" "mmxcvt")
1187    (set_attr "length_immediate" "1")
1188    (set_attr "mode" "DI")])
1190 (define_expand "mmx_pshufw"
1191   [(match_operand:V4HI 0 "register_operand")
1192    (match_operand:V4HI 1 "nonimmediate_operand")
1193    (match_operand:SI 2 "const_int_operand")]
1194   "TARGET_SSE || TARGET_3DNOW_A"
1196   int mask = INTVAL (operands[2]);
1197   emit_insn (gen_mmx_pshufw_1 (operands[0], operands[1],
1198                                GEN_INT ((mask >> 0) & 3),
1199                                GEN_INT ((mask >> 2) & 3),
1200                                GEN_INT ((mask >> 4) & 3),
1201                                GEN_INT ((mask >> 6) & 3)));
1202   DONE;
1205 (define_insn "mmx_pshufw_1"
1206   [(set (match_operand:V4HI 0 "register_operand" "=y")
1207         (vec_select:V4HI
1208           (match_operand:V4HI 1 "nonimmediate_operand" "ym")
1209           (parallel [(match_operand 2 "const_0_to_3_operand")
1210                      (match_operand 3 "const_0_to_3_operand")
1211                      (match_operand 4 "const_0_to_3_operand")
1212                      (match_operand 5 "const_0_to_3_operand")])))]
1213   "TARGET_SSE || TARGET_3DNOW_A"
1215   int mask = 0;
1216   mask |= INTVAL (operands[2]) << 0;
1217   mask |= INTVAL (operands[3]) << 2;
1218   mask |= INTVAL (operands[4]) << 4;
1219   mask |= INTVAL (operands[5]) << 6;
1220   operands[2] = GEN_INT (mask);
1222   return "pshufw\t{%2, %1, %0|%0, %1, %2}";
1224   [(set_attr "type" "mmxcvt")
1225    (set_attr "length_immediate" "1")
1226    (set_attr "mode" "DI")])
1228 (define_insn "mmx_pswapdv2si2"
1229   [(set (match_operand:V2SI 0 "register_operand" "=y")
1230         (vec_select:V2SI
1231           (match_operand:V2SI 1 "nonimmediate_operand" "ym")
1232           (parallel [(const_int 1) (const_int 0)])))]
1233   "TARGET_3DNOW_A"
1234   "pswapd\t{%1, %0|%0, %1}"
1235   [(set_attr "type" "mmxcvt")
1236    (set_attr "prefix_extra" "1")
1237    (set_attr "mode" "DI")])
1239 (define_insn "*vec_dupv4hi"
1240   [(set (match_operand:V4HI 0 "register_operand" "=y")
1241         (vec_duplicate:V4HI
1242           (truncate:HI
1243             (match_operand:SI 1 "register_operand" "0"))))]
1244   "TARGET_SSE || TARGET_3DNOW_A"
1245   "pshufw\t{$0, %0, %0|%0, %0, 0}"
1246   [(set_attr "type" "mmxcvt")
1247    (set_attr "length_immediate" "1")
1248    (set_attr "mode" "DI")])
1250 (define_insn "*vec_dupv2si"
1251   [(set (match_operand:V2SI 0 "register_operand" "=y")
1252         (vec_duplicate:V2SI
1253           (match_operand:SI 1 "register_operand" "0")))]
1254   "TARGET_MMX"
1255   "punpckldq\t%0, %0"
1256   [(set_attr "type" "mmxcvt")
1257    (set_attr "mode" "DI")])
1259 (define_insn "*mmx_concatv2si"
1260   [(set (match_operand:V2SI 0 "register_operand"     "=y,y")
1261         (vec_concat:V2SI
1262           (match_operand:SI 1 "nonimmediate_operand" " 0,rm")
1263           (match_operand:SI 2 "vector_move_operand"  "ym,C")))]
1264   "TARGET_MMX && !TARGET_SSE"
1265   "@
1266    punpckldq\t{%2, %0|%0, %2}
1267    movd\t{%1, %0|%0, %1}"
1268   [(set_attr "type" "mmxcvt,mmxmov")
1269    (set_attr "mode" "DI")])
1271 (define_expand "vec_setv2si"
1272   [(match_operand:V2SI 0 "register_operand")
1273    (match_operand:SI 1 "register_operand")
1274    (match_operand 2 "const_int_operand")]
1275   "TARGET_MMX"
1277   ix86_expand_vector_set (false, operands[0], operands[1],
1278                           INTVAL (operands[2]));
1279   DONE;
1282 ;; Avoid combining registers from different units in a single alternative,
1283 ;; see comment above inline_secondary_memory_needed function in i386.c
1284 (define_insn_and_split "*vec_extractv2si_0"
1285   [(set (match_operand:SI 0 "nonimmediate_operand"     "=x,m,y, m,r")
1286         (vec_select:SI
1287           (match_operand:V2SI 1 "nonimmediate_operand" "xm,x,ym,y,m")
1288           (parallel [(const_int 0)])))]
1289   "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1290   "#"
1291   "&& reload_completed"
1292   [(const_int 0)]
1294   rtx op1 = operands[1];
1295   if (REG_P (op1))
1296     op1 = gen_rtx_REG (SImode, REGNO (op1));
1297   else
1298     op1 = gen_lowpart (SImode, op1);
1299   emit_move_insn (operands[0], op1);
1300   DONE;
1303 ;; Avoid combining registers from different units in a single alternative,
1304 ;; see comment above inline_secondary_memory_needed function in i386.c
1305 (define_insn "*vec_extractv2si_1"
1306   [(set (match_operand:SI 0 "nonimmediate_operand"     "=y,x,x,x,y,x,r")
1307         (vec_select:SI
1308           (match_operand:V2SI 1 "nonimmediate_operand" " 0,0,x,0,o,o,o")
1309           (parallel [(const_int 1)])))]
1310   "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1311   "@
1312    punpckhdq\t%0, %0
1313    punpckhdq\t%0, %0
1314    pshufd\t{$85, %1, %0|%0, %1, 85}
1315    unpckhps\t%0, %0
1316    #
1317    #
1318    #"
1319   [(set (attr "isa")
1320      (if_then_else (eq_attr "alternative" "1,2")
1321        (const_string "sse2")
1322        (const_string "*")))
1323    (set_attr "type" "mmxcvt,sselog1,sselog1,sselog1,mmxmov,ssemov,imov")
1324    (set_attr "length_immediate" "*,*,1,*,*,*,*")
1325    (set_attr "mode" "DI,TI,TI,V4SF,SI,SI,SI")])
1327 (define_split
1328   [(set (match_operand:SI 0 "register_operand")
1329         (vec_select:SI
1330           (match_operand:V2SI 1 "memory_operand")
1331           (parallel [(const_int 1)])))]
1332   "TARGET_MMX && reload_completed"
1333   [(const_int 0)]
1335   operands[1] = adjust_address (operands[1], SImode, 4);
1336   emit_move_insn (operands[0], operands[1]);
1337   DONE;
1340 (define_expand "vec_extractv2si"
1341   [(match_operand:SI 0 "register_operand")
1342    (match_operand:V2SI 1 "register_operand")
1343    (match_operand 2 "const_int_operand")]
1344   "TARGET_MMX"
1346   ix86_expand_vector_extract (false, operands[0], operands[1],
1347                               INTVAL (operands[2]));
1348   DONE;
1351 (define_expand "vec_initv2si"
1352   [(match_operand:V2SI 0 "register_operand")
1353    (match_operand 1)]
1354   "TARGET_SSE"
1356   ix86_expand_vector_init (false, operands[0], operands[1]);
1357   DONE;
1360 (define_expand "vec_setv4hi"
1361   [(match_operand:V4HI 0 "register_operand")
1362    (match_operand:HI 1 "register_operand")
1363    (match_operand 2 "const_int_operand")]
1364   "TARGET_MMX"
1366   ix86_expand_vector_set (false, operands[0], operands[1],
1367                           INTVAL (operands[2]));
1368   DONE;
1371 (define_expand "vec_extractv4hi"
1372   [(match_operand:HI 0 "register_operand")
1373    (match_operand:V4HI 1 "register_operand")
1374    (match_operand 2 "const_int_operand")]
1375   "TARGET_MMX"
1377   ix86_expand_vector_extract (false, operands[0], operands[1],
1378                               INTVAL (operands[2]));
1379   DONE;
1382 (define_expand "vec_initv4hi"
1383   [(match_operand:V4HI 0 "register_operand")
1384    (match_operand 1)]
1385   "TARGET_SSE"
1387   ix86_expand_vector_init (false, operands[0], operands[1]);
1388   DONE;
1391 (define_expand "vec_setv8qi"
1392   [(match_operand:V8QI 0 "register_operand")
1393    (match_operand:QI 1 "register_operand")
1394    (match_operand 2 "const_int_operand")]
1395   "TARGET_MMX"
1397   ix86_expand_vector_set (false, operands[0], operands[1],
1398                           INTVAL (operands[2]));
1399   DONE;
1402 (define_expand "vec_extractv8qi"
1403   [(match_operand:QI 0 "register_operand")
1404    (match_operand:V8QI 1 "register_operand")
1405    (match_operand 2 "const_int_operand")]
1406   "TARGET_MMX"
1408   ix86_expand_vector_extract (false, operands[0], operands[1],
1409                               INTVAL (operands[2]));
1410   DONE;
1413 (define_expand "vec_initv8qi"
1414   [(match_operand:V8QI 0 "register_operand")
1415    (match_operand 1)]
1416   "TARGET_SSE"
1418   ix86_expand_vector_init (false, operands[0], operands[1]);
1419   DONE;
1422 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1424 ;; Miscellaneous
1426 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1428 (define_expand "mmx_uavgv8qi3"
1429   [(set (match_operand:V8QI 0 "register_operand")
1430         (truncate:V8QI
1431           (lshiftrt:V8HI
1432             (plus:V8HI
1433               (plus:V8HI
1434                 (zero_extend:V8HI
1435                   (match_operand:V8QI 1 "nonimmediate_operand"))
1436                 (zero_extend:V8HI
1437                   (match_operand:V8QI 2 "nonimmediate_operand")))
1438               (const_vector:V8HI [(const_int 1) (const_int 1)
1439                                   (const_int 1) (const_int 1)
1440                                   (const_int 1) (const_int 1)
1441                                   (const_int 1) (const_int 1)]))
1442             (const_int 1))))]
1443   "TARGET_SSE || TARGET_3DNOW"
1444   "ix86_fixup_binary_operands_no_copy (PLUS, V8QImode, operands);")
1446 (define_insn "*mmx_uavgv8qi3"
1447   [(set (match_operand:V8QI 0 "register_operand" "=y")
1448         (truncate:V8QI
1449           (lshiftrt:V8HI
1450             (plus:V8HI
1451               (plus:V8HI
1452                 (zero_extend:V8HI
1453                   (match_operand:V8QI 1 "nonimmediate_operand" "%0"))
1454                 (zero_extend:V8HI
1455                   (match_operand:V8QI 2 "nonimmediate_operand" "ym")))
1456               (const_vector:V8HI [(const_int 1) (const_int 1)
1457                                   (const_int 1) (const_int 1)
1458                                   (const_int 1) (const_int 1)
1459                                   (const_int 1) (const_int 1)]))
1460             (const_int 1))))]
1461   "(TARGET_SSE || TARGET_3DNOW)
1462    && ix86_binary_operator_ok (PLUS, V8QImode, operands)"
1464   /* These two instructions have the same operation, but their encoding
1465      is different.  Prefer the one that is de facto standard.  */
1466   if (TARGET_SSE || TARGET_3DNOW_A)
1467     return "pavgb\t{%2, %0|%0, %2}";
1468   else
1469     return "pavgusb\t{%2, %0|%0, %2}";
1471   [(set_attr "type" "mmxshft")
1472    (set (attr "prefix_extra")
1473      (if_then_else
1474        (not (ior (match_test "TARGET_SSE")
1475                  (match_test "TARGET_3DNOW_A")))
1476        (const_string "1")
1477        (const_string "*")))
1478    (set_attr "mode" "DI")])
1480 (define_expand "mmx_uavgv4hi3"
1481   [(set (match_operand:V4HI 0 "register_operand")
1482         (truncate:V4HI
1483           (lshiftrt:V4SI
1484             (plus:V4SI
1485               (plus:V4SI
1486                 (zero_extend:V4SI
1487                   (match_operand:V4HI 1 "nonimmediate_operand"))
1488                 (zero_extend:V4SI
1489                   (match_operand:V4HI 2 "nonimmediate_operand")))
1490               (const_vector:V4SI [(const_int 1) (const_int 1)
1491                                   (const_int 1) (const_int 1)]))
1492             (const_int 1))))]
1493   "TARGET_SSE || TARGET_3DNOW_A"
1494   "ix86_fixup_binary_operands_no_copy (PLUS, V4HImode, operands);")
1496 (define_insn "*mmx_uavgv4hi3"
1497   [(set (match_operand:V4HI 0 "register_operand" "=y")
1498         (truncate:V4HI
1499           (lshiftrt:V4SI
1500             (plus:V4SI
1501               (plus:V4SI
1502                 (zero_extend:V4SI
1503                   (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
1504                 (zero_extend:V4SI
1505                   (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
1506               (const_vector:V4SI [(const_int 1) (const_int 1)
1507                                   (const_int 1) (const_int 1)]))
1508             (const_int 1))))]
1509   "(TARGET_SSE || TARGET_3DNOW_A)
1510    && ix86_binary_operator_ok (PLUS, V4HImode, operands)"
1511   "pavgw\t{%2, %0|%0, %2}"
1512   [(set_attr "type" "mmxshft")
1513    (set_attr "mode" "DI")])
1515 (define_insn "mmx_psadbw"
1516   [(set (match_operand:V1DI 0 "register_operand" "=y")
1517         (unspec:V1DI [(match_operand:V8QI 1 "register_operand" "0")
1518                       (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
1519                      UNSPEC_PSADBW))]
1520   "TARGET_SSE || TARGET_3DNOW_A"
1521   "psadbw\t{%2, %0|%0, %2}"
1522   [(set_attr "type" "mmxshft")
1523    (set_attr "mode" "DI")])
1525 (define_insn "mmx_pmovmskb"
1526   [(set (match_operand:SI 0 "register_operand" "=r")
1527         (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")]
1528                    UNSPEC_MOVMSK))]
1529   "TARGET_SSE || TARGET_3DNOW_A"
1530   "pmovmskb\t{%1, %0|%0, %1}"
1531   [(set_attr "type" "mmxcvt")
1532    (set_attr "mode" "DI")])
1534 (define_expand "mmx_maskmovq"
1535   [(set (match_operand:V8QI 0 "memory_operand")
1536         (unspec:V8QI [(match_operand:V8QI 1 "register_operand")
1537                       (match_operand:V8QI 2 "register_operand")
1538                       (match_dup 0)]
1539                      UNSPEC_MASKMOV))]
1540   "TARGET_SSE || TARGET_3DNOW_A")
1542 (define_insn "*mmx_maskmovq"
1543   [(set (mem:V8QI (match_operand:P 0 "register_operand" "D"))
1544         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
1545                       (match_operand:V8QI 2 "register_operand" "y")
1546                       (mem:V8QI (match_dup 0))]
1547                      UNSPEC_MASKMOV))]
1548   "TARGET_SSE || TARGET_3DNOW_A"
1549   ;; @@@ check ordering of operands in intel/nonintel syntax
1550   "maskmovq\t{%2, %1|%1, %2}"
1551   [(set_attr "type" "mmxcvt")
1552    (set_attr "mode" "DI")])
1554 (define_expand "mmx_emms"
1555   [(match_par_dup 0 [(const_int 0)])]
1556   "TARGET_MMX"
1558   int regno;
1560   operands[0] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (17));
1562   XVECEXP (operands[0], 0, 0)
1563     = gen_rtx_UNSPEC_VOLATILE (VOIDmode, gen_rtvec (1, const0_rtx),
1564                                UNSPECV_EMMS);
1566   for (regno = 0; regno < 8; regno++)
1567     {
1568       XVECEXP (operands[0], 0, regno + 1)
1569         = gen_rtx_CLOBBER (VOIDmode,
1570                            gen_rtx_REG (XFmode, FIRST_STACK_REG + regno));
1572       XVECEXP (operands[0], 0, regno + 9)
1573         = gen_rtx_CLOBBER (VOIDmode,
1574                            gen_rtx_REG (DImode, FIRST_MMX_REG + regno));
1575     }
1578 (define_insn "*mmx_emms"
1579   [(match_parallel 0 "emms_operation"
1580     [(unspec_volatile [(const_int 0)] UNSPECV_EMMS)])]
1581   "TARGET_MMX"
1582   "emms"
1583   [(set_attr "type" "mmx")
1584    (set_attr "modrm" "0")
1585    (set_attr "memory" "none")])
1587 (define_expand "mmx_femms"
1588   [(match_par_dup 0 [(const_int 0)])]
1589   "TARGET_3DNOW"
1591   int regno;
1593   operands[0] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (17));
1595   XVECEXP (operands[0], 0, 0)
1596     = gen_rtx_UNSPEC_VOLATILE (VOIDmode, gen_rtvec (1, const0_rtx),
1597                                UNSPECV_FEMMS);
1599   for (regno = 0; regno < 8; regno++)
1600     {
1601       XVECEXP (operands[0], 0, regno + 1)
1602         = gen_rtx_CLOBBER (VOIDmode,
1603                            gen_rtx_REG (XFmode, FIRST_STACK_REG + regno));
1605       XVECEXP (operands[0], 0, regno + 9)
1606         = gen_rtx_CLOBBER (VOIDmode,
1607                            gen_rtx_REG (DImode, FIRST_MMX_REG + regno));
1608     }
1611 (define_insn "*mmx_femms"
1612   [(match_parallel 0 "emms_operation"
1613     [(unspec_volatile [(const_int 0)] UNSPECV_FEMMS)])]
1614   "TARGET_3DNOW"
1615   "femms"
1616   [(set_attr "type" "mmx")
1617    (set_attr "modrm" "0")
1618    (set_attr "memory" "none")])