* i386.h (TARGET_MISALIGNED_MOVE_STRING_PROLOGUES_EPILOGUES): New tuning flag.
[official-gcc.git] / gcc / config / i386 / mmx.md
blob17e24999258cb3c55a399681e2410b4c0969e3c1
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,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]))"
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_XI:
132           return "vmovdqa64\t{%g1, %g0|%g0, %g1}";
134         case MODE_V2SF:
135           if (TARGET_AVX && REG_P (operands[0]))
136             return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
137           return "%vmovlps\t{%1, %0|%0, %1}";
138         case MODE_V4SF:
139           return "%vmovaps\t{%1, %0|%0, %1}";
141         default:
142           gcc_unreachable ();
143         }
145     default:
146       gcc_unreachable ();
147     }
149   [(set (attr "isa")
150      (cond [(eq_attr "alternative" "0,1")
151               (const_string "nox64")
152             (eq_attr "alternative" "2,3,4,9,10,11,12,13,14,19,20")
153               (const_string "x64")
154            ]
155            (const_string "*")))
156    (set (attr "type")
157      (cond [(eq_attr "alternative" "0,1")
158               (const_string "multi")
159             (eq_attr "alternative" "2,3,4")
160               (const_string "imov")
161             (eq_attr "alternative" "5")
162               (const_string "mmx")
163             (eq_attr "alternative" "6,7,8,9,10")
164               (const_string "mmxmov")
165             (eq_attr "alternative" "11,15")
166               (const_string "sselog1")
167             (eq_attr "alternative" "21,22")
168               (const_string "ssecvt")
169            ]
170            (const_string "ssemov")))
171    (set (attr "prefix_rex")
172      (if_then_else (eq_attr "alternative" "9,10,19,20")
173        (const_string "1")
174        (const_string "*")))
175    (set (attr "prefix")
176      (if_then_else (eq_attr "type" "sselog1,ssemov")
177        (const_string "maybe_vex")
178        (const_string "orig")))
179    (set (attr "prefix_data16")
180      (if_then_else
181        (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
182        (const_string "1")
183        (const_string "*")))
184    (set (attr "mode")
185      (cond [(eq_attr "alternative" "2")
186               (const_string "SI")
187             (eq_attr "alternative" "11,12,15,16")
188               (cond [(ior (match_operand 0 "ext_sse_reg_operand")
189                           (match_operand 1 "ext_sse_reg_operand"))
190                         (const_string "XI")
191                      (match_test "<MODE>mode == V2SFmode")
192                        (const_string "V4SF")
193                      (ior (not (match_test "TARGET_SSE2"))
194                           (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
195                        (const_string "V4SF")
196                      (match_test "TARGET_AVX")
197                        (const_string "TI")
198                      (match_test "optimize_function_for_size_p (cfun)")
199                        (const_string "V4SF")
200                     ]
201                     (const_string "TI"))
203             (and (eq_attr "alternative" "13,14,17,18")
204                  (ior (match_test "<MODE>mode == V2SFmode")
205                       (not (match_test "TARGET_SSE2"))))
206               (const_string "V2SF")
207            ]
208            (const_string "DI")))])
210 (define_split
211   [(set (match_operand:MMXMODE 0 "nonimmediate_operand")
212         (match_operand:MMXMODE 1 "general_operand"))]
213   "!TARGET_64BIT && reload_completed
214    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
215    && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
216   [(const_int 0)]
217   "ix86_split_long_move (operands); DONE;")
219 (define_expand "push<mode>1"
220   [(match_operand:MMXMODE 0 "register_operand")]
221   "TARGET_MMX"
223   ix86_expand_push (<MODE>mode, operands[0]);
224   DONE;
227 (define_expand "movmisalign<mode>"
228   [(set (match_operand:MMXMODE 0 "nonimmediate_operand")
229         (match_operand:MMXMODE 1 "nonimmediate_operand"))]
230   "TARGET_MMX"
232   ix86_expand_vector_move (<MODE>mode, operands);
233   DONE;
236 (define_insn "sse_movntq"
237   [(set (match_operand:DI 0 "memory_operand" "=m")
238         (unspec:DI [(match_operand:DI 1 "register_operand" "y")]
239                    UNSPEC_MOVNTQ))]
240   "TARGET_SSE || TARGET_3DNOW_A"
241   "movntq\t{%1, %0|%0, %1}"
242   [(set_attr "type" "mmxmov")
243    (set_attr "mode" "DI")])
245 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
247 ;; Parallel single-precision floating point arithmetic
249 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
251 (define_expand "mmx_addv2sf3"
252   [(set (match_operand:V2SF 0 "register_operand")
253         (plus:V2SF
254           (match_operand:V2SF 1 "nonimmediate_operand")
255           (match_operand:V2SF 2 "nonimmediate_operand")))]
256   "TARGET_3DNOW"
257   "ix86_fixup_binary_operands_no_copy (PLUS, V2SFmode, operands);")
259 (define_insn "*mmx_addv2sf3"
260   [(set (match_operand:V2SF 0 "register_operand" "=y")
261         (plus:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "%0")
262                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
263   "TARGET_3DNOW && ix86_binary_operator_ok (PLUS, V2SFmode, operands)"
264   "pfadd\t{%2, %0|%0, %2}"
265   [(set_attr "type" "mmxadd")
266    (set_attr "prefix_extra" "1")
267    (set_attr "mode" "V2SF")])
269 (define_expand "mmx_subv2sf3"
270   [(set (match_operand:V2SF 0 "register_operand")
271         (minus:V2SF (match_operand:V2SF 1 "register_operand")
272                     (match_operand:V2SF 2 "nonimmediate_operand")))]
273   "TARGET_3DNOW")
275 (define_expand "mmx_subrv2sf3"
276   [(set (match_operand:V2SF 0 "register_operand")
277         (minus:V2SF (match_operand:V2SF 2 "register_operand")
278                     (match_operand:V2SF 1 "nonimmediate_operand")))]
279   "TARGET_3DNOW")
281 (define_insn "*mmx_subv2sf3"
282   [(set (match_operand:V2SF 0 "register_operand" "=y,y")
283         (minus:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "0,ym")
284                     (match_operand:V2SF 2 "nonimmediate_operand" "ym,0")))]
285   "TARGET_3DNOW && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
286   "@
287    pfsub\t{%2, %0|%0, %2}
288    pfsubr\t{%1, %0|%0, %1}"
289   [(set_attr "type" "mmxadd")
290    (set_attr "prefix_extra" "1")
291    (set_attr "mode" "V2SF")])
293 (define_expand "mmx_mulv2sf3"
294   [(set (match_operand:V2SF 0 "register_operand")
295         (mult:V2SF (match_operand:V2SF 1 "nonimmediate_operand")
296                    (match_operand:V2SF 2 "nonimmediate_operand")))]
297   "TARGET_3DNOW"
298   "ix86_fixup_binary_operands_no_copy (MULT, V2SFmode, operands);")
300 (define_insn "*mmx_mulv2sf3"
301   [(set (match_operand:V2SF 0 "register_operand" "=y")
302         (mult:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "%0")
303                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
304   "TARGET_3DNOW && ix86_binary_operator_ok (MULT, V2SFmode, operands)"
305   "pfmul\t{%2, %0|%0, %2}"
306   [(set_attr "type" "mmxmul")
307    (set_attr "prefix_extra" "1")
308    (set_attr "mode" "V2SF")])
310 ;; ??? For !flag_finite_math_only, the representation with SMIN/SMAX
311 ;; isn't really correct, as those rtl operators aren't defined when
312 ;; applied to NaNs.  Hopefully the optimizers won't get too smart on us.
314 (define_expand "mmx_<code>v2sf3"
315   [(set (match_operand:V2SF 0 "register_operand")
316         (smaxmin:V2SF
317           (match_operand:V2SF 1 "nonimmediate_operand")
318           (match_operand:V2SF 2 "nonimmediate_operand")))]
319   "TARGET_3DNOW"
321   if (!flag_finite_math_only)
322     operands[1] = force_reg (V2SFmode, operands[1]);
323   ix86_fixup_binary_operands_no_copy (<CODE>, V2SFmode, operands);
326 (define_insn "*mmx_<code>v2sf3_finite"
327   [(set (match_operand:V2SF 0 "register_operand" "=y")
328         (smaxmin:V2SF
329           (match_operand:V2SF 1 "nonimmediate_operand" "%0")
330           (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
331   "TARGET_3DNOW && flag_finite_math_only
332    && ix86_binary_operator_ok (<CODE>, V2SFmode, operands)"
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")])
338 (define_insn "*mmx_<code>v2sf3"
339   [(set (match_operand:V2SF 0 "register_operand" "=y")
340         (smaxmin:V2SF
341           (match_operand:V2SF 1 "register_operand" "0")
342           (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
343   "TARGET_3DNOW"
344   "pf<maxmin_float>\t{%2, %0|%0, %2}"
345   [(set_attr "type" "mmxadd")
346    (set_attr "prefix_extra" "1")
347    (set_attr "mode" "V2SF")])
349 (define_insn "mmx_rcpv2sf2"
350   [(set (match_operand:V2SF 0 "register_operand" "=y")
351         (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
352                      UNSPEC_PFRCP))]
353   "TARGET_3DNOW"
354   "pfrcp\t{%1, %0|%0, %1}"
355   [(set_attr "type" "mmx")
356    (set_attr "prefix_extra" "1")
357    (set_attr "mode" "V2SF")])
359 (define_insn "mmx_rcpit1v2sf3"
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_PFRCPIT1))]
364   "TARGET_3DNOW"
365   "pfrcpit1\t{%2, %0|%0, %2}"
366   [(set_attr "type" "mmx")
367    (set_attr "prefix_extra" "1")
368    (set_attr "mode" "V2SF")])
370 (define_insn "mmx_rcpit2v2sf3"
371   [(set (match_operand:V2SF 0 "register_operand" "=y")
372         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
373                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
374                      UNSPEC_PFRCPIT2))]
375   "TARGET_3DNOW"
376   "pfrcpit2\t{%2, %0|%0, %2}"
377   [(set_attr "type" "mmx")
378    (set_attr "prefix_extra" "1")
379    (set_attr "mode" "V2SF")])
381 (define_insn "mmx_rsqrtv2sf2"
382   [(set (match_operand:V2SF 0 "register_operand" "=y")
383         (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
384                      UNSPEC_PFRSQRT))]
385   "TARGET_3DNOW"
386   "pfrsqrt\t{%1, %0|%0, %1}"
387   [(set_attr "type" "mmx")
388    (set_attr "prefix_extra" "1")
389    (set_attr "mode" "V2SF")])
391 (define_insn "mmx_rsqit1v2sf3"
392   [(set (match_operand:V2SF 0 "register_operand" "=y")
393         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
394                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
395                      UNSPEC_PFRSQIT1))]
396   "TARGET_3DNOW"
397   "pfrsqit1\t{%2, %0|%0, %2}"
398   [(set_attr "type" "mmx")
399    (set_attr "prefix_extra" "1")
400    (set_attr "mode" "V2SF")])
402 (define_insn "mmx_haddv2sf3"
403   [(set (match_operand:V2SF 0 "register_operand" "=y")
404         (vec_concat:V2SF
405           (plus:SF
406             (vec_select:SF
407               (match_operand:V2SF 1 "register_operand" "0")
408               (parallel [(const_int  0)]))
409             (vec_select:SF (match_dup 1) (parallel [(const_int 1)])))
410           (plus:SF
411             (vec_select:SF
412               (match_operand:V2SF 2 "nonimmediate_operand" "ym")
413               (parallel [(const_int  0)]))
414             (vec_select:SF (match_dup 2) (parallel [(const_int 1)])))))]
415   "TARGET_3DNOW"
416   "pfacc\t{%2, %0|%0, %2}"
417   [(set_attr "type" "mmxadd")
418    (set_attr "prefix_extra" "1")
419    (set_attr "mode" "V2SF")])
421 (define_insn "mmx_hsubv2sf3"
422   [(set (match_operand:V2SF 0 "register_operand" "=y")
423         (vec_concat:V2SF
424           (minus:SF
425             (vec_select:SF
426               (match_operand:V2SF 1 "register_operand" "0")
427               (parallel [(const_int  0)]))
428             (vec_select:SF (match_dup 1) (parallel [(const_int 1)])))
429           (minus:SF
430             (vec_select:SF
431               (match_operand:V2SF 2 "nonimmediate_operand" "ym")
432               (parallel [(const_int  0)]))
433             (vec_select:SF (match_dup 2) (parallel [(const_int 1)])))))]
434   "TARGET_3DNOW_A"
435   "pfnacc\t{%2, %0|%0, %2}"
436   [(set_attr "type" "mmxadd")
437    (set_attr "prefix_extra" "1")
438    (set_attr "mode" "V2SF")])
440 (define_insn "mmx_addsubv2sf3"
441   [(set (match_operand:V2SF 0 "register_operand" "=y")
442         (vec_merge:V2SF
443           (plus:V2SF
444             (match_operand:V2SF 1 "register_operand" "0")
445             (match_operand:V2SF 2 "nonimmediate_operand" "ym"))
446           (minus:V2SF (match_dup 1) (match_dup 2))
447           (const_int 1)))]
448   "TARGET_3DNOW_A"
449   "pfpnacc\t{%2, %0|%0, %2}"
450   [(set_attr "type" "mmxadd")
451    (set_attr "prefix_extra" "1")
452    (set_attr "mode" "V2SF")])
454 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
456 ;; Parallel single-precision floating point comparisons
458 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
460 (define_expand "mmx_eqv2sf3"
461   [(set (match_operand:V2SI 0 "register_operand")
462         (eq:V2SI (match_operand:V2SF 1 "nonimmediate_operand")
463                  (match_operand:V2SF 2 "nonimmediate_operand")))]
464   "TARGET_3DNOW"
465   "ix86_fixup_binary_operands_no_copy (EQ, V2SFmode, operands);")
467 (define_insn "*mmx_eqv2sf3"
468   [(set (match_operand:V2SI 0 "register_operand" "=y")
469         (eq:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "%0")
470                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
471   "TARGET_3DNOW && ix86_binary_operator_ok (EQ, V2SFmode, operands)"
472   "pfcmpeq\t{%2, %0|%0, %2}"
473   [(set_attr "type" "mmxcmp")
474    (set_attr "prefix_extra" "1")
475    (set_attr "mode" "V2SF")])
477 (define_insn "mmx_gtv2sf3"
478   [(set (match_operand:V2SI 0 "register_operand" "=y")
479         (gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
480                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
481   "TARGET_3DNOW"
482   "pfcmpgt\t{%2, %0|%0, %2}"
483   [(set_attr "type" "mmxcmp")
484    (set_attr "prefix_extra" "1")
485    (set_attr "mode" "V2SF")])
487 (define_insn "mmx_gev2sf3"
488   [(set (match_operand:V2SI 0 "register_operand" "=y")
489         (ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
490                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
491   "TARGET_3DNOW"
492   "pfcmpge\t{%2, %0|%0, %2}"
493   [(set_attr "type" "mmxcmp")
494    (set_attr "prefix_extra" "1")
495    (set_attr "mode" "V2SF")])
497 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
499 ;; Parallel single-precision floating point conversion operations
501 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
503 (define_insn "mmx_pf2id"
504   [(set (match_operand:V2SI 0 "register_operand" "=y")
505         (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
506   "TARGET_3DNOW"
507   "pf2id\t{%1, %0|%0, %1}"
508   [(set_attr "type" "mmxcvt")
509    (set_attr "prefix_extra" "1")
510    (set_attr "mode" "V2SF")])
512 (define_insn "mmx_pf2iw"
513   [(set (match_operand:V2SI 0 "register_operand" "=y")
514         (sign_extend:V2SI
515           (ss_truncate:V2HI
516             (fix:V2SI
517               (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
518   "TARGET_3DNOW_A"
519   "pf2iw\t{%1, %0|%0, %1}"
520   [(set_attr "type" "mmxcvt")
521    (set_attr "prefix_extra" "1")
522    (set_attr "mode" "V2SF")])
524 (define_insn "mmx_pi2fw"
525   [(set (match_operand:V2SF 0 "register_operand" "=y")
526         (float:V2SF
527           (sign_extend:V2SI
528             (truncate:V2HI
529               (match_operand:V2SI 1 "nonimmediate_operand" "ym")))))]
530   "TARGET_3DNOW_A"
531   "pi2fw\t{%1, %0|%0, %1}"
532   [(set_attr "type" "mmxcvt")
533    (set_attr "prefix_extra" "1")
534    (set_attr "mode" "V2SF")])
536 (define_insn "mmx_floatv2si2"
537   [(set (match_operand:V2SF 0 "register_operand" "=y")
538         (float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
539   "TARGET_3DNOW"
540   "pi2fd\t{%1, %0|%0, %1}"
541   [(set_attr "type" "mmxcvt")
542    (set_attr "prefix_extra" "1")
543    (set_attr "mode" "V2SF")])
545 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
547 ;; Parallel single-precision floating point element swizzling
549 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
551 (define_insn "mmx_pswapdv2sf2"
552   [(set (match_operand:V2SF 0 "register_operand" "=y")
553         (vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym")
554                          (parallel [(const_int 1) (const_int 0)])))]
555   "TARGET_3DNOW_A"
556   "pswapd\t{%1, %0|%0, %1}"
557   [(set_attr "type" "mmxcvt")
558    (set_attr "prefix_extra" "1")
559    (set_attr "mode" "V2SF")])
561 (define_insn "*vec_dupv2sf"
562   [(set (match_operand:V2SF 0 "register_operand" "=y")
563         (vec_duplicate:V2SF
564           (match_operand:SF 1 "register_operand" "0")))]
565   "TARGET_MMX"
566   "punpckldq\t%0, %0"
567   [(set_attr "type" "mmxcvt")
568    (set_attr "mode" "DI")])
570 (define_insn "*mmx_concatv2sf"
571   [(set (match_operand:V2SF 0 "register_operand"     "=y,y")
572         (vec_concat:V2SF
573           (match_operand:SF 1 "nonimmediate_operand" " 0,rm")
574           (match_operand:SF 2 "vector_move_operand"  "ym,C")))]
575   "TARGET_MMX && !TARGET_SSE"
576   "@
577    punpckldq\t{%2, %0|%0, %2}
578    movd\t{%1, %0|%0, %1}"
579   [(set_attr "type" "mmxcvt,mmxmov")
580    (set_attr "mode" "DI")])
582 (define_expand "vec_setv2sf"
583   [(match_operand:V2SF 0 "register_operand")
584    (match_operand:SF 1 "register_operand")
585    (match_operand 2 "const_int_operand")]
586   "TARGET_MMX"
588   ix86_expand_vector_set (false, operands[0], operands[1],
589                           INTVAL (operands[2]));
590   DONE;
593 ;; Avoid combining registers from different units in a single alternative,
594 ;; see comment above inline_secondary_memory_needed function in i386.c
595 (define_insn_and_split "*vec_extractv2sf_0"
596   [(set (match_operand:SF 0 "nonimmediate_operand"     "=x, m,y ,m,f,r")
597         (vec_select:SF
598           (match_operand:V2SF 1 "nonimmediate_operand" " xm,x,ym,y,m,m")
599           (parallel [(const_int 0)])))]
600   "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
601   "#"
602   "&& reload_completed"
603   [(set (match_dup 0) (match_dup 1))]
605   if (REG_P (operands[1]))
606     operands[1] = gen_rtx_REG (SFmode, REGNO (operands[1]));
607   else
608     operands[1] = adjust_address (operands[1], SFmode, 0);
611 ;; Avoid combining registers from different units in a single alternative,
612 ;; see comment above inline_secondary_memory_needed function in i386.c
613 (define_insn "*vec_extractv2sf_1"
614   [(set (match_operand:SF 0 "nonimmediate_operand"     "=y,x,y,x,f,r")
615         (vec_select:SF
616           (match_operand:V2SF 1 "nonimmediate_operand" " 0,0,o,o,o,o")
617           (parallel [(const_int 1)])))]
618   "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
619   "@
620    punpckhdq\t%0, %0
621    unpckhps\t%0, %0
622    #
623    #
624    #
625    #"
626   [(set_attr "type" "mmxcvt,sselog1,mmxmov,ssemov,fmov,imov")
627    (set_attr "mode" "DI,V4SF,SF,SF,SF,SF")])
629 (define_split
630   [(set (match_operand:SF 0 "register_operand")
631         (vec_select:SF
632           (match_operand:V2SF 1 "memory_operand")
633           (parallel [(const_int 1)])))]
634   "TARGET_MMX && reload_completed"
635   [(set (match_dup 0) (match_dup 1))]
636   "operands[1] = adjust_address (operands[1], SFmode, 4);")
638 (define_expand "vec_extractv2sf"
639   [(match_operand:SF 0 "register_operand")
640    (match_operand:V2SF 1 "register_operand")
641    (match_operand 2 "const_int_operand")]
642   "TARGET_MMX"
644   ix86_expand_vector_extract (false, operands[0], operands[1],
645                               INTVAL (operands[2]));
646   DONE;
649 (define_expand "vec_initv2sf"
650   [(match_operand:V2SF 0 "register_operand")
651    (match_operand 1)]
652   "TARGET_SSE"
654   ix86_expand_vector_init (false, operands[0], operands[1]);
655   DONE;
658 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
660 ;; Parallel integral arithmetic
662 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
664 (define_expand "mmx_<plusminus_insn><mode>3"
665   [(set (match_operand:MMXMODEI8 0 "register_operand")
666         (plusminus:MMXMODEI8
667           (match_operand:MMXMODEI8 1 "nonimmediate_operand")
668           (match_operand:MMXMODEI8 2 "nonimmediate_operand")))]
669   "TARGET_MMX || (TARGET_SSE2 && <MODE>mode == V1DImode)"
670   "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
672 (define_insn "*mmx_<plusminus_insn><mode>3"
673   [(set (match_operand:MMXMODEI8 0 "register_operand" "=y")
674         (plusminus:MMXMODEI8
675           (match_operand:MMXMODEI8 1 "nonimmediate_operand" "<comm>0")
676           (match_operand:MMXMODEI8 2 "nonimmediate_operand" "ym")))]
677   "(TARGET_MMX || (TARGET_SSE2 && <MODE>mode == V1DImode))
678    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
679   "p<plusminus_mnemonic><mmxvecsize>\t{%2, %0|%0, %2}"
680   [(set_attr "type" "mmxadd")
681    (set_attr "mode" "DI")])
683 (define_expand "mmx_<plusminus_insn><mode>3"
684   [(set (match_operand:MMXMODE12 0 "register_operand")
685         (sat_plusminus:MMXMODE12
686           (match_operand:MMXMODE12 1 "nonimmediate_operand")
687           (match_operand:MMXMODE12 2 "nonimmediate_operand")))]
688   "TARGET_MMX"
689   "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
691 (define_insn "*mmx_<plusminus_insn><mode>3"
692   [(set (match_operand:MMXMODE12 0 "register_operand" "=y")
693         (sat_plusminus:MMXMODE12
694           (match_operand:MMXMODE12 1 "nonimmediate_operand" "<comm>0")
695           (match_operand:MMXMODE12 2 "nonimmediate_operand" "ym")))]
696   "TARGET_MMX && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
697   "p<plusminus_mnemonic><mmxvecsize>\t{%2, %0|%0, %2}"
698   [(set_attr "type" "mmxadd")
699    (set_attr "mode" "DI")])
701 (define_expand "mmx_mulv4hi3"
702   [(set (match_operand:V4HI 0 "register_operand")
703         (mult:V4HI (match_operand:V4HI 1 "nonimmediate_operand")
704                    (match_operand:V4HI 2 "nonimmediate_operand")))]
705   "TARGET_MMX"
706   "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
708 (define_insn "*mmx_mulv4hi3"
709   [(set (match_operand:V4HI 0 "register_operand" "=y")
710         (mult:V4HI (match_operand:V4HI 1 "nonimmediate_operand" "%0")
711                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
712   "TARGET_MMX && ix86_binary_operator_ok (MULT, V4HImode, operands)"
713   "pmullw\t{%2, %0|%0, %2}"
714   [(set_attr "type" "mmxmul")
715    (set_attr "mode" "DI")])
717 (define_expand "mmx_smulv4hi3_highpart"
718   [(set (match_operand:V4HI 0 "register_operand")
719         (truncate:V4HI
720           (lshiftrt:V4SI
721             (mult:V4SI
722               (sign_extend:V4SI
723                 (match_operand:V4HI 1 "nonimmediate_operand"))
724               (sign_extend:V4SI
725                 (match_operand:V4HI 2 "nonimmediate_operand")))
726             (const_int 16))))]
727   "TARGET_MMX"
728   "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
730 (define_insn "*mmx_smulv4hi3_highpart"
731   [(set (match_operand:V4HI 0 "register_operand" "=y")
732         (truncate:V4HI
733           (lshiftrt:V4SI
734             (mult:V4SI
735               (sign_extend:V4SI
736                 (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
737               (sign_extend:V4SI
738                 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
739             (const_int 16))))]
740   "TARGET_MMX && ix86_binary_operator_ok (MULT, V4HImode, operands)"
741   "pmulhw\t{%2, %0|%0, %2}"
742   [(set_attr "type" "mmxmul")
743    (set_attr "mode" "DI")])
745 (define_expand "mmx_umulv4hi3_highpart"
746   [(set (match_operand:V4HI 0 "register_operand")
747         (truncate:V4HI
748           (lshiftrt:V4SI
749             (mult:V4SI
750               (zero_extend:V4SI
751                 (match_operand:V4HI 1 "nonimmediate_operand"))
752               (zero_extend:V4SI
753                 (match_operand:V4HI 2 "nonimmediate_operand")))
754             (const_int 16))))]
755   "TARGET_SSE || TARGET_3DNOW_A"
756   "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
758 (define_insn "*mmx_umulv4hi3_highpart"
759   [(set (match_operand:V4HI 0 "register_operand" "=y")
760         (truncate:V4HI
761           (lshiftrt:V4SI
762             (mult:V4SI
763               (zero_extend:V4SI
764                 (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
765               (zero_extend:V4SI
766                 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
767           (const_int 16))))]
768   "(TARGET_SSE || TARGET_3DNOW_A)
769    && ix86_binary_operator_ok (MULT, V4HImode, operands)"
770   "pmulhuw\t{%2, %0|%0, %2}"
771   [(set_attr "type" "mmxmul")
772    (set_attr "mode" "DI")])
774 (define_expand "mmx_pmaddwd"
775   [(set (match_operand:V2SI 0 "register_operand")
776         (plus:V2SI
777           (mult:V2SI
778             (sign_extend:V2SI
779               (vec_select:V2HI
780                 (match_operand:V4HI 1 "nonimmediate_operand")
781                 (parallel [(const_int 0) (const_int 2)])))
782             (sign_extend:V2SI
783               (vec_select:V2HI
784                 (match_operand:V4HI 2 "nonimmediate_operand")
785                 (parallel [(const_int 0) (const_int 2)]))))
786           (mult:V2SI
787             (sign_extend:V2SI
788               (vec_select:V2HI (match_dup 1)
789                 (parallel [(const_int 1) (const_int 3)])))
790             (sign_extend:V2SI
791               (vec_select:V2HI (match_dup 2)
792                 (parallel [(const_int 1) (const_int 3)]))))))]
793   "TARGET_MMX"
794   "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
796 (define_insn "*mmx_pmaddwd"
797   [(set (match_operand:V2SI 0 "register_operand" "=y")
798         (plus:V2SI
799           (mult:V2SI
800             (sign_extend:V2SI
801               (vec_select:V2HI
802                 (match_operand:V4HI 1 "nonimmediate_operand" "%0")
803                 (parallel [(const_int 0) (const_int 2)])))
804             (sign_extend:V2SI
805               (vec_select:V2HI
806                 (match_operand:V4HI 2 "nonimmediate_operand" "ym")
807                 (parallel [(const_int 0) (const_int 2)]))))
808           (mult:V2SI
809             (sign_extend:V2SI
810               (vec_select:V2HI (match_dup 1)
811                 (parallel [(const_int 1) (const_int 3)])))
812             (sign_extend:V2SI
813               (vec_select:V2HI (match_dup 2)
814                 (parallel [(const_int 1) (const_int 3)]))))))]
815   "TARGET_MMX && ix86_binary_operator_ok (MULT, V4HImode, operands)"
816   "pmaddwd\t{%2, %0|%0, %2}"
817   [(set_attr "type" "mmxmul")
818    (set_attr "mode" "DI")])
820 (define_expand "mmx_pmulhrwv4hi3"
821   [(set (match_operand:V4HI 0 "register_operand")
822         (truncate:V4HI
823           (lshiftrt:V4SI
824             (plus:V4SI
825               (mult:V4SI
826                 (sign_extend:V4SI
827                   (match_operand:V4HI 1 "nonimmediate_operand"))
828                 (sign_extend:V4SI
829                   (match_operand:V4HI 2 "nonimmediate_operand")))
830               (const_vector:V4SI [(const_int 32768) (const_int 32768)
831                                   (const_int 32768) (const_int 32768)]))
832             (const_int 16))))]
833   "TARGET_3DNOW"
834   "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
836 (define_insn "*mmx_pmulhrwv4hi3"
837   [(set (match_operand:V4HI 0 "register_operand" "=y")
838         (truncate:V4HI
839           (lshiftrt:V4SI
840             (plus:V4SI
841               (mult:V4SI
842                 (sign_extend:V4SI
843                   (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
844                 (sign_extend:V4SI
845                   (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
846               (const_vector:V4SI [(const_int 32768) (const_int 32768)
847                                   (const_int 32768) (const_int 32768)]))
848             (const_int 16))))]
849   "TARGET_3DNOW && ix86_binary_operator_ok (MULT, V4HImode, operands)"
850   "pmulhrw\t{%2, %0|%0, %2}"
851   [(set_attr "type" "mmxmul")
852    (set_attr "prefix_extra" "1")
853    (set_attr "mode" "DI")])
855 (define_expand "sse2_umulv1siv1di3"
856   [(set (match_operand:V1DI 0 "register_operand")
857         (mult:V1DI
858           (zero_extend:V1DI
859             (vec_select:V1SI
860               (match_operand:V2SI 1 "nonimmediate_operand")
861               (parallel [(const_int 0)])))
862           (zero_extend:V1DI
863             (vec_select:V1SI
864               (match_operand:V2SI 2 "nonimmediate_operand")
865               (parallel [(const_int 0)])))))]
866   "TARGET_SSE2"
867   "ix86_fixup_binary_operands_no_copy (MULT, V2SImode, operands);")
869 (define_insn "*sse2_umulv1siv1di3"
870   [(set (match_operand:V1DI 0 "register_operand" "=y")
871         (mult:V1DI
872           (zero_extend:V1DI
873             (vec_select:V1SI
874               (match_operand:V2SI 1 "nonimmediate_operand" "%0")
875               (parallel [(const_int 0)])))
876           (zero_extend:V1DI
877             (vec_select:V1SI
878               (match_operand:V2SI 2 "nonimmediate_operand" "ym")
879               (parallel [(const_int 0)])))))]
880   "TARGET_SSE2 && ix86_binary_operator_ok (MULT, V2SImode, operands)"
881   "pmuludq\t{%2, %0|%0, %2}"
882   [(set_attr "type" "mmxmul")
883    (set_attr "mode" "DI")])
885 (define_expand "mmx_<code>v4hi3"
886   [(set (match_operand:V4HI 0 "register_operand")
887         (smaxmin:V4HI
888           (match_operand:V4HI 1 "nonimmediate_operand")
889           (match_operand:V4HI 2 "nonimmediate_operand")))]
890   "TARGET_SSE || TARGET_3DNOW_A"
891   "ix86_fixup_binary_operands_no_copy (<CODE>, V4HImode, operands);")
893 (define_insn "*mmx_<code>v4hi3"
894   [(set (match_operand:V4HI 0 "register_operand" "=y")
895         (smaxmin:V4HI
896           (match_operand:V4HI 1 "nonimmediate_operand" "%0")
897           (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
898   "(TARGET_SSE || TARGET_3DNOW_A)
899    && ix86_binary_operator_ok (<CODE>, V4HImode, operands)"
900   "p<maxmin_int>w\t{%2, %0|%0, %2}"
901   [(set_attr "type" "mmxadd")
902    (set_attr "mode" "DI")])
904 (define_expand "mmx_<code>v8qi3"
905   [(set (match_operand:V8QI 0 "register_operand")
906         (umaxmin:V8QI
907           (match_operand:V8QI 1 "nonimmediate_operand")
908           (match_operand:V8QI 2 "nonimmediate_operand")))]
909   "TARGET_SSE || TARGET_3DNOW_A"
910   "ix86_fixup_binary_operands_no_copy (<CODE>, V8QImode, operands);")
912 (define_insn "*mmx_<code>v8qi3"
913   [(set (match_operand:V8QI 0 "register_operand" "=y")
914         (umaxmin:V8QI
915           (match_operand:V8QI 1 "nonimmediate_operand" "%0")
916           (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
917   "(TARGET_SSE || TARGET_3DNOW_A)
918    && ix86_binary_operator_ok (<CODE>, V8QImode, operands)"
919   "p<maxmin_int>b\t{%2, %0|%0, %2}"
920   [(set_attr "type" "mmxadd")
921    (set_attr "mode" "DI")])
923 (define_insn "mmx_ashr<mode>3"
924   [(set (match_operand:MMXMODE24 0 "register_operand" "=y")
925         (ashiftrt:MMXMODE24
926           (match_operand:MMXMODE24 1 "register_operand" "0")
927           (match_operand:SI 2 "nonmemory_operand" "yN")))]
928   "TARGET_MMX"
929   "psra<mmxvecsize>\t{%2, %0|%0, %2}"
930   [(set_attr "type" "mmxshft")
931    (set (attr "length_immediate")
932      (if_then_else (match_operand 2 "const_int_operand")
933        (const_string "1")
934        (const_string "0")))
935    (set_attr "mode" "DI")])
937 (define_insn "mmx_<shift_insn><mode>3"
938   [(set (match_operand:MMXMODE248 0 "register_operand" "=y")
939         (any_lshift:MMXMODE248
940           (match_operand:MMXMODE248 1 "register_operand" "0")
941           (match_operand:SI 2 "nonmemory_operand" "yN")))]
942   "TARGET_MMX"
943   "p<vshift><mmxvecsize>\t{%2, %0|%0, %2}"
944   [(set_attr "type" "mmxshft")
945    (set (attr "length_immediate")
946      (if_then_else (match_operand 2 "const_int_operand")
947        (const_string "1")
948        (const_string "0")))
949    (set_attr "mode" "DI")])
951 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
953 ;; Parallel integral comparisons
955 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
957 (define_expand "mmx_eq<mode>3"
958   [(set (match_operand:MMXMODEI 0 "register_operand")
959         (eq:MMXMODEI
960           (match_operand:MMXMODEI 1 "nonimmediate_operand")
961           (match_operand:MMXMODEI 2 "nonimmediate_operand")))]
962   "TARGET_MMX"
963   "ix86_fixup_binary_operands_no_copy (EQ, <MODE>mode, operands);")
965 (define_insn "*mmx_eq<mode>3"
966   [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
967         (eq:MMXMODEI
968           (match_operand:MMXMODEI 1 "nonimmediate_operand" "%0")
969           (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
970   "TARGET_MMX && ix86_binary_operator_ok (EQ, <MODE>mode, operands)"
971   "pcmpeq<mmxvecsize>\t{%2, %0|%0, %2}"
972   [(set_attr "type" "mmxcmp")
973    (set_attr "mode" "DI")])
975 (define_insn "mmx_gt<mode>3"
976   [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
977         (gt:MMXMODEI
978           (match_operand:MMXMODEI 1 "register_operand" "0")
979           (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
980   "TARGET_MMX"
981   "pcmpgt<mmxvecsize>\t{%2, %0|%0, %2}"
982   [(set_attr "type" "mmxcmp")
983    (set_attr "mode" "DI")])
985 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
987 ;; Parallel integral logical operations
989 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
991 (define_insn "mmx_andnot<mode>3"
992   [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
993         (and:MMXMODEI
994           (not:MMXMODEI (match_operand:MMXMODEI 1 "register_operand" "0"))
995           (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
996   "TARGET_MMX"
997   "pandn\t{%2, %0|%0, %2}"
998   [(set_attr "type" "mmxadd")
999    (set_attr "mode" "DI")])
1001 (define_expand "mmx_<code><mode>3"
1002   [(set (match_operand:MMXMODEI 0 "register_operand")
1003         (any_logic:MMXMODEI
1004           (match_operand:MMXMODEI 1 "nonimmediate_operand")
1005           (match_operand:MMXMODEI 2 "nonimmediate_operand")))]
1006   "TARGET_MMX"
1007   "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
1009 (define_insn "*mmx_<code><mode>3"
1010   [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
1011         (any_logic:MMXMODEI
1012           (match_operand:MMXMODEI 1 "nonimmediate_operand" "%0")
1013           (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
1014   "TARGET_MMX && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
1015   "p<logic>\t{%2, %0|%0, %2}"
1016   [(set_attr "type" "mmxadd")
1017    (set_attr "mode" "DI")])
1019 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1021 ;; Parallel integral element swizzling
1023 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1025 (define_insn "mmx_packsswb"
1026   [(set (match_operand:V8QI 0 "register_operand" "=y")
1027         (vec_concat:V8QI
1028           (ss_truncate:V4QI
1029             (match_operand:V4HI 1 "register_operand" "0"))
1030           (ss_truncate:V4QI
1031             (match_operand:V4HI 2 "nonimmediate_operand" "ym"))))]
1032   "TARGET_MMX"
1033   "packsswb\t{%2, %0|%0, %2}"
1034   [(set_attr "type" "mmxshft")
1035    (set_attr "mode" "DI")])
1037 (define_insn "mmx_packssdw"
1038   [(set (match_operand:V4HI 0 "register_operand" "=y")
1039         (vec_concat:V4HI
1040           (ss_truncate:V2HI
1041             (match_operand:V2SI 1 "register_operand" "0"))
1042           (ss_truncate:V2HI
1043             (match_operand:V2SI 2 "nonimmediate_operand" "ym"))))]
1044   "TARGET_MMX"
1045   "packssdw\t{%2, %0|%0, %2}"
1046   [(set_attr "type" "mmxshft")
1047    (set_attr "mode" "DI")])
1049 (define_insn "mmx_packuswb"
1050   [(set (match_operand:V8QI 0 "register_operand" "=y")
1051         (vec_concat:V8QI
1052           (us_truncate:V4QI
1053             (match_operand:V4HI 1 "register_operand" "0"))
1054           (us_truncate:V4QI
1055             (match_operand:V4HI 2 "nonimmediate_operand" "ym"))))]
1056   "TARGET_MMX"
1057   "packuswb\t{%2, %0|%0, %2}"
1058   [(set_attr "type" "mmxshft")
1059    (set_attr "mode" "DI")])
1061 (define_insn "mmx_punpckhbw"
1062   [(set (match_operand:V8QI 0 "register_operand" "=y")
1063         (vec_select:V8QI
1064           (vec_concat:V16QI
1065             (match_operand:V8QI 1 "register_operand" "0")
1066             (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
1067           (parallel [(const_int 4) (const_int 12)
1068                      (const_int 5) (const_int 13)
1069                      (const_int 6) (const_int 14)
1070                      (const_int 7) (const_int 15)])))]
1071   "TARGET_MMX"
1072   "punpckhbw\t{%2, %0|%0, %2}"
1073   [(set_attr "type" "mmxcvt")
1074    (set_attr "mode" "DI")])
1076 (define_insn "mmx_punpcklbw"
1077   [(set (match_operand:V8QI 0 "register_operand" "=y")
1078         (vec_select:V8QI
1079           (vec_concat:V16QI
1080             (match_operand:V8QI 1 "register_operand" "0")
1081             (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
1082           (parallel [(const_int 0) (const_int 8)
1083                      (const_int 1) (const_int 9)
1084                      (const_int 2) (const_int 10)
1085                      (const_int 3) (const_int 11)])))]
1086   "TARGET_MMX"
1087   "punpcklbw\t{%2, %0|%0, %k2}"
1088   [(set_attr "type" "mmxcvt")
1089    (set_attr "mode" "DI")])
1091 (define_insn "mmx_punpckhwd"
1092   [(set (match_operand:V4HI 0 "register_operand" "=y")
1093         (vec_select:V4HI
1094           (vec_concat:V8HI
1095             (match_operand:V4HI 1 "register_operand" "0")
1096             (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
1097           (parallel [(const_int 2) (const_int 6)
1098                      (const_int 3) (const_int 7)])))]
1099   "TARGET_MMX"
1100   "punpckhwd\t{%2, %0|%0, %2}"
1101   [(set_attr "type" "mmxcvt")
1102    (set_attr "mode" "DI")])
1104 (define_insn "mmx_punpcklwd"
1105   [(set (match_operand:V4HI 0 "register_operand" "=y")
1106         (vec_select:V4HI
1107           (vec_concat:V8HI
1108             (match_operand:V4HI 1 "register_operand" "0")
1109             (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
1110           (parallel [(const_int 0) (const_int 4)
1111                      (const_int 1) (const_int 5)])))]
1112   "TARGET_MMX"
1113   "punpcklwd\t{%2, %0|%0, %k2}"
1114   [(set_attr "type" "mmxcvt")
1115    (set_attr "mode" "DI")])
1117 (define_insn "mmx_punpckhdq"
1118   [(set (match_operand:V2SI 0 "register_operand" "=y")
1119         (vec_select:V2SI
1120           (vec_concat:V4SI
1121             (match_operand:V2SI 1 "register_operand" "0")
1122             (match_operand:V2SI 2 "nonimmediate_operand" "ym"))
1123           (parallel [(const_int 1)
1124                      (const_int 3)])))]
1125   "TARGET_MMX"
1126   "punpckhdq\t{%2, %0|%0, %2}"
1127   [(set_attr "type" "mmxcvt")
1128    (set_attr "mode" "DI")])
1130 (define_insn "mmx_punpckldq"
1131   [(set (match_operand:V2SI 0 "register_operand" "=y")
1132         (vec_select:V2SI
1133           (vec_concat:V4SI
1134             (match_operand:V2SI 1 "register_operand" "0")
1135             (match_operand:V2SI 2 "nonimmediate_operand" "ym"))
1136           (parallel [(const_int 0)
1137                      (const_int 2)])))]
1138   "TARGET_MMX"
1139   "punpckldq\t{%2, %0|%0, %k2}"
1140   [(set_attr "type" "mmxcvt")
1141    (set_attr "mode" "DI")])
1143 (define_expand "mmx_pinsrw"
1144   [(set (match_operand:V4HI 0 "register_operand")
1145         (vec_merge:V4HI
1146           (vec_duplicate:V4HI
1147             (match_operand:SI 2 "nonimmediate_operand"))
1148           (match_operand:V4HI 1 "register_operand")
1149           (match_operand:SI 3 "const_0_to_3_operand")))]
1150   "TARGET_SSE || TARGET_3DNOW_A"
1152   operands[2] = gen_lowpart (HImode, operands[2]);
1153   operands[3] = GEN_INT (1 << INTVAL (operands[3]));
1156 (define_insn "*mmx_pinsrw"
1157   [(set (match_operand:V4HI 0 "register_operand" "=y")
1158         (vec_merge:V4HI
1159           (vec_duplicate:V4HI
1160             (match_operand:HI 2 "nonimmediate_operand" "rm"))
1161           (match_operand:V4HI 1 "register_operand" "0")
1162           (match_operand:SI 3 "const_int_operand")))]
1163   "(TARGET_SSE || TARGET_3DNOW_A)
1164    && ((unsigned) exact_log2 (INTVAL (operands[3]))
1165        < GET_MODE_NUNITS (V4HImode))"
1167   operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])));
1168   if (MEM_P (operands[2]))
1169     return "pinsrw\t{%3, %2, %0|%0, %2, %3}";
1170   else
1171     return "pinsrw\t{%3, %k2, %0|%0, %k2, %3}";
1173   [(set_attr "type" "mmxcvt")
1174    (set_attr "length_immediate" "1")
1175    (set_attr "mode" "DI")])
1177 (define_insn "mmx_pextrw"
1178   [(set (match_operand:SI 0 "register_operand" "=r")
1179         (zero_extend:SI
1180           (vec_select:HI
1181             (match_operand:V4HI 1 "register_operand" "y")
1182             (parallel [(match_operand:SI 2 "const_0_to_3_operand" "n")]))))]
1183   "TARGET_SSE || TARGET_3DNOW_A"
1184   "pextrw\t{%2, %1, %0|%0, %1, %2}"
1185   [(set_attr "type" "mmxcvt")
1186    (set_attr "length_immediate" "1")
1187    (set_attr "mode" "DI")])
1189 (define_expand "mmx_pshufw"
1190   [(match_operand:V4HI 0 "register_operand")
1191    (match_operand:V4HI 1 "nonimmediate_operand")
1192    (match_operand:SI 2 "const_int_operand")]
1193   "TARGET_SSE || TARGET_3DNOW_A"
1195   int mask = INTVAL (operands[2]);
1196   emit_insn (gen_mmx_pshufw_1 (operands[0], operands[1],
1197                                GEN_INT ((mask >> 0) & 3),
1198                                GEN_INT ((mask >> 2) & 3),
1199                                GEN_INT ((mask >> 4) & 3),
1200                                GEN_INT ((mask >> 6) & 3)));
1201   DONE;
1204 (define_insn "mmx_pshufw_1"
1205   [(set (match_operand:V4HI 0 "register_operand" "=y")
1206         (vec_select:V4HI
1207           (match_operand:V4HI 1 "nonimmediate_operand" "ym")
1208           (parallel [(match_operand 2 "const_0_to_3_operand")
1209                      (match_operand 3 "const_0_to_3_operand")
1210                      (match_operand 4 "const_0_to_3_operand")
1211                      (match_operand 5 "const_0_to_3_operand")])))]
1212   "TARGET_SSE || TARGET_3DNOW_A"
1214   int mask = 0;
1215   mask |= INTVAL (operands[2]) << 0;
1216   mask |= INTVAL (operands[3]) << 2;
1217   mask |= INTVAL (operands[4]) << 4;
1218   mask |= INTVAL (operands[5]) << 6;
1219   operands[2] = GEN_INT (mask);
1221   return "pshufw\t{%2, %1, %0|%0, %1, %2}";
1223   [(set_attr "type" "mmxcvt")
1224    (set_attr "length_immediate" "1")
1225    (set_attr "mode" "DI")])
1227 (define_insn "mmx_pswapdv2si2"
1228   [(set (match_operand:V2SI 0 "register_operand" "=y")
1229         (vec_select:V2SI
1230           (match_operand:V2SI 1 "nonimmediate_operand" "ym")
1231           (parallel [(const_int 1) (const_int 0)])))]
1232   "TARGET_3DNOW_A"
1233   "pswapd\t{%1, %0|%0, %1}"
1234   [(set_attr "type" "mmxcvt")
1235    (set_attr "prefix_extra" "1")
1236    (set_attr "mode" "DI")])
1238 (define_insn "*vec_dupv4hi"
1239   [(set (match_operand:V4HI 0 "register_operand" "=y")
1240         (vec_duplicate:V4HI
1241           (truncate:HI
1242             (match_operand:SI 1 "register_operand" "0"))))]
1243   "TARGET_SSE || TARGET_3DNOW_A"
1244   "pshufw\t{$0, %0, %0|%0, %0, 0}"
1245   [(set_attr "type" "mmxcvt")
1246    (set_attr "length_immediate" "1")
1247    (set_attr "mode" "DI")])
1249 (define_insn "*vec_dupv2si"
1250   [(set (match_operand:V2SI 0 "register_operand" "=y")
1251         (vec_duplicate:V2SI
1252           (match_operand:SI 1 "register_operand" "0")))]
1253   "TARGET_MMX"
1254   "punpckldq\t%0, %0"
1255   [(set_attr "type" "mmxcvt")
1256    (set_attr "mode" "DI")])
1258 (define_insn "*mmx_concatv2si"
1259   [(set (match_operand:V2SI 0 "register_operand"     "=y,y")
1260         (vec_concat:V2SI
1261           (match_operand:SI 1 "nonimmediate_operand" " 0,rm")
1262           (match_operand:SI 2 "vector_move_operand"  "ym,C")))]
1263   "TARGET_MMX && !TARGET_SSE"
1264   "@
1265    punpckldq\t{%2, %0|%0, %2}
1266    movd\t{%1, %0|%0, %1}"
1267   [(set_attr "type" "mmxcvt,mmxmov")
1268    (set_attr "mode" "DI")])
1270 (define_expand "vec_setv2si"
1271   [(match_operand:V2SI 0 "register_operand")
1272    (match_operand:SI 1 "register_operand")
1273    (match_operand 2 "const_int_operand")]
1274   "TARGET_MMX"
1276   ix86_expand_vector_set (false, operands[0], operands[1],
1277                           INTVAL (operands[2]));
1278   DONE;
1281 ;; Avoid combining registers from different units in a single alternative,
1282 ;; see comment above inline_secondary_memory_needed function in i386.c
1283 (define_insn_and_split "*vec_extractv2si_0"
1284   [(set (match_operand:SI 0 "nonimmediate_operand"     "=x,m,y, m,r")
1285         (vec_select:SI
1286           (match_operand:V2SI 1 "nonimmediate_operand" "xm,x,ym,y,m")
1287           (parallel [(const_int 0)])))]
1288   "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1289   "#"
1290   "&& reload_completed"
1291   [(set (match_dup 0) (match_dup 1))]
1293   if (REG_P (operands[1]))
1294     operands[1] = gen_rtx_REG (SImode, REGNO (operands[1]));
1295   else
1296     operands[1] = adjust_address (operands[1], SImode, 0);
1299 ;; Avoid combining registers from different units in a single alternative,
1300 ;; see comment above inline_secondary_memory_needed function in i386.c
1301 (define_insn "*vec_extractv2si_1"
1302   [(set (match_operand:SI 0 "nonimmediate_operand"     "=y,x,x,x,y,x,r")
1303         (vec_select:SI
1304           (match_operand:V2SI 1 "nonimmediate_operand" " 0,0,x,0,o,o,o")
1305           (parallel [(const_int 1)])))]
1306   "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1307   "@
1308    punpckhdq\t%0, %0
1309    punpckhdq\t%0, %0
1310    pshufd\t{$85, %1, %0|%0, %1, 85}
1311    unpckhps\t%0, %0
1312    #
1313    #
1314    #"
1315   [(set (attr "isa")
1316      (if_then_else (eq_attr "alternative" "1,2")
1317        (const_string "sse2")
1318        (const_string "*")))
1319    (set_attr "type" "mmxcvt,sselog1,sselog1,sselog1,mmxmov,ssemov,imov")
1320    (set_attr "length_immediate" "*,*,1,*,*,*,*")
1321    (set_attr "mode" "DI,TI,TI,V4SF,SI,SI,SI")])
1323 (define_split
1324   [(set (match_operand:SI 0 "register_operand")
1325         (vec_select:SI
1326           (match_operand:V2SI 1 "memory_operand")
1327           (parallel [(const_int 1)])))]
1328   "TARGET_MMX && reload_completed"
1329   [(set (match_dup 0) (match_dup 1))]
1330   "operands[1] = adjust_address (operands[1], SImode, 4);")
1332 (define_insn_and_split "*vec_extractv2si_zext_mem"
1333   [(set (match_operand:DI 0 "register_operand" "=y,x,r")
1334         (zero_extend:DI
1335           (vec_select:SI
1336             (match_operand:V2SI 1 "memory_operand" "o,o,o")
1337             (parallel [(match_operand:SI 2 "const_0_to_1_operand")]))))]
1338   "TARGET_64BIT && TARGET_MMX"
1339   "#"
1340   "&& reload_completed"
1341   [(set (match_dup 0) (zero_extend:DI (match_dup 1)))]
1343   operands[1] = adjust_address (operands[1], SImode, INTVAL (operands[2]) * 4);
1346 (define_expand "vec_extractv2si"
1347   [(match_operand:SI 0 "register_operand")
1348    (match_operand:V2SI 1 "register_operand")
1349    (match_operand 2 "const_int_operand")]
1350   "TARGET_MMX"
1352   ix86_expand_vector_extract (false, operands[0], operands[1],
1353                               INTVAL (operands[2]));
1354   DONE;
1357 (define_expand "vec_initv2si"
1358   [(match_operand:V2SI 0 "register_operand")
1359    (match_operand 1)]
1360   "TARGET_SSE"
1362   ix86_expand_vector_init (false, operands[0], operands[1]);
1363   DONE;
1366 (define_expand "vec_setv4hi"
1367   [(match_operand:V4HI 0 "register_operand")
1368    (match_operand:HI 1 "register_operand")
1369    (match_operand 2 "const_int_operand")]
1370   "TARGET_MMX"
1372   ix86_expand_vector_set (false, operands[0], operands[1],
1373                           INTVAL (operands[2]));
1374   DONE;
1377 (define_expand "vec_extractv4hi"
1378   [(match_operand:HI 0 "register_operand")
1379    (match_operand:V4HI 1 "register_operand")
1380    (match_operand 2 "const_int_operand")]
1381   "TARGET_MMX"
1383   ix86_expand_vector_extract (false, operands[0], operands[1],
1384                               INTVAL (operands[2]));
1385   DONE;
1388 (define_expand "vec_initv4hi"
1389   [(match_operand:V4HI 0 "register_operand")
1390    (match_operand 1)]
1391   "TARGET_SSE"
1393   ix86_expand_vector_init (false, operands[0], operands[1]);
1394   DONE;
1397 (define_expand "vec_setv8qi"
1398   [(match_operand:V8QI 0 "register_operand")
1399    (match_operand:QI 1 "register_operand")
1400    (match_operand 2 "const_int_operand")]
1401   "TARGET_MMX"
1403   ix86_expand_vector_set (false, operands[0], operands[1],
1404                           INTVAL (operands[2]));
1405   DONE;
1408 (define_expand "vec_extractv8qi"
1409   [(match_operand:QI 0 "register_operand")
1410    (match_operand:V8QI 1 "register_operand")
1411    (match_operand 2 "const_int_operand")]
1412   "TARGET_MMX"
1414   ix86_expand_vector_extract (false, operands[0], operands[1],
1415                               INTVAL (operands[2]));
1416   DONE;
1419 (define_expand "vec_initv8qi"
1420   [(match_operand:V8QI 0 "register_operand")
1421    (match_operand 1)]
1422   "TARGET_SSE"
1424   ix86_expand_vector_init (false, operands[0], operands[1]);
1425   DONE;
1428 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1430 ;; Miscellaneous
1432 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1434 (define_expand "mmx_uavgv8qi3"
1435   [(set (match_operand:V8QI 0 "register_operand")
1436         (truncate:V8QI
1437           (lshiftrt:V8HI
1438             (plus:V8HI
1439               (plus:V8HI
1440                 (zero_extend:V8HI
1441                   (match_operand:V8QI 1 "nonimmediate_operand"))
1442                 (zero_extend:V8HI
1443                   (match_operand:V8QI 2 "nonimmediate_operand")))
1444               (const_vector:V8HI [(const_int 1) (const_int 1)
1445                                   (const_int 1) (const_int 1)
1446                                   (const_int 1) (const_int 1)
1447                                   (const_int 1) (const_int 1)]))
1448             (const_int 1))))]
1449   "TARGET_SSE || TARGET_3DNOW"
1450   "ix86_fixup_binary_operands_no_copy (PLUS, V8QImode, operands);")
1452 (define_insn "*mmx_uavgv8qi3"
1453   [(set (match_operand:V8QI 0 "register_operand" "=y")
1454         (truncate:V8QI
1455           (lshiftrt:V8HI
1456             (plus:V8HI
1457               (plus:V8HI
1458                 (zero_extend:V8HI
1459                   (match_operand:V8QI 1 "nonimmediate_operand" "%0"))
1460                 (zero_extend:V8HI
1461                   (match_operand:V8QI 2 "nonimmediate_operand" "ym")))
1462               (const_vector:V8HI [(const_int 1) (const_int 1)
1463                                   (const_int 1) (const_int 1)
1464                                   (const_int 1) (const_int 1)
1465                                   (const_int 1) (const_int 1)]))
1466             (const_int 1))))]
1467   "(TARGET_SSE || TARGET_3DNOW)
1468    && ix86_binary_operator_ok (PLUS, V8QImode, operands)"
1470   /* These two instructions have the same operation, but their encoding
1471      is different.  Prefer the one that is de facto standard.  */
1472   if (TARGET_SSE || TARGET_3DNOW_A)
1473     return "pavgb\t{%2, %0|%0, %2}";
1474   else
1475     return "pavgusb\t{%2, %0|%0, %2}";
1477   [(set_attr "type" "mmxshft")
1478    (set (attr "prefix_extra")
1479      (if_then_else
1480        (not (ior (match_test "TARGET_SSE")
1481                  (match_test "TARGET_3DNOW_A")))
1482        (const_string "1")
1483        (const_string "*")))
1484    (set_attr "mode" "DI")])
1486 (define_expand "mmx_uavgv4hi3"
1487   [(set (match_operand:V4HI 0 "register_operand")
1488         (truncate:V4HI
1489           (lshiftrt:V4SI
1490             (plus:V4SI
1491               (plus:V4SI
1492                 (zero_extend:V4SI
1493                   (match_operand:V4HI 1 "nonimmediate_operand"))
1494                 (zero_extend:V4SI
1495                   (match_operand:V4HI 2 "nonimmediate_operand")))
1496               (const_vector:V4SI [(const_int 1) (const_int 1)
1497                                   (const_int 1) (const_int 1)]))
1498             (const_int 1))))]
1499   "TARGET_SSE || TARGET_3DNOW_A"
1500   "ix86_fixup_binary_operands_no_copy (PLUS, V4HImode, operands);")
1502 (define_insn "*mmx_uavgv4hi3"
1503   [(set (match_operand:V4HI 0 "register_operand" "=y")
1504         (truncate:V4HI
1505           (lshiftrt:V4SI
1506             (plus:V4SI
1507               (plus:V4SI
1508                 (zero_extend:V4SI
1509                   (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
1510                 (zero_extend:V4SI
1511                   (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
1512               (const_vector:V4SI [(const_int 1) (const_int 1)
1513                                   (const_int 1) (const_int 1)]))
1514             (const_int 1))))]
1515   "(TARGET_SSE || TARGET_3DNOW_A)
1516    && ix86_binary_operator_ok (PLUS, V4HImode, operands)"
1517   "pavgw\t{%2, %0|%0, %2}"
1518   [(set_attr "type" "mmxshft")
1519    (set_attr "mode" "DI")])
1521 (define_insn "mmx_psadbw"
1522   [(set (match_operand:V1DI 0 "register_operand" "=y")
1523         (unspec:V1DI [(match_operand:V8QI 1 "register_operand" "0")
1524                       (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
1525                      UNSPEC_PSADBW))]
1526   "TARGET_SSE || TARGET_3DNOW_A"
1527   "psadbw\t{%2, %0|%0, %2}"
1528   [(set_attr "type" "mmxshft")
1529    (set_attr "mode" "DI")])
1531 (define_insn "mmx_pmovmskb"
1532   [(set (match_operand:SI 0 "register_operand" "=r")
1533         (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")]
1534                    UNSPEC_MOVMSK))]
1535   "TARGET_SSE || TARGET_3DNOW_A"
1536   "pmovmskb\t{%1, %0|%0, %1}"
1537   [(set_attr "type" "mmxcvt")
1538    (set_attr "mode" "DI")])
1540 (define_expand "mmx_maskmovq"
1541   [(set (match_operand:V8QI 0 "memory_operand")
1542         (unspec:V8QI [(match_operand:V8QI 1 "register_operand")
1543                       (match_operand:V8QI 2 "register_operand")
1544                       (match_dup 0)]
1545                      UNSPEC_MASKMOV))]
1546   "TARGET_SSE || TARGET_3DNOW_A")
1548 (define_insn "*mmx_maskmovq"
1549   [(set (mem:V8QI (match_operand:P 0 "register_operand" "D"))
1550         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
1551                       (match_operand:V8QI 2 "register_operand" "y")
1552                       (mem:V8QI (match_dup 0))]
1553                      UNSPEC_MASKMOV))]
1554   "TARGET_SSE || TARGET_3DNOW_A"
1555   ;; @@@ check ordering of operands in intel/nonintel syntax
1556   "maskmovq\t{%2, %1|%1, %2}"
1557   [(set_attr "type" "mmxcvt")
1558    (set_attr "mode" "DI")])
1560 (define_expand "mmx_emms"
1561   [(match_par_dup 0 [(const_int 0)])]
1562   "TARGET_MMX"
1564   int regno;
1566   operands[0] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (17));
1568   XVECEXP (operands[0], 0, 0)
1569     = gen_rtx_UNSPEC_VOLATILE (VOIDmode, gen_rtvec (1, const0_rtx),
1570                                UNSPECV_EMMS);
1572   for (regno = 0; regno < 8; regno++)
1573     {
1574       XVECEXP (operands[0], 0, regno + 1)
1575         = gen_rtx_CLOBBER (VOIDmode,
1576                            gen_rtx_REG (XFmode, FIRST_STACK_REG + regno));
1578       XVECEXP (operands[0], 0, regno + 9)
1579         = gen_rtx_CLOBBER (VOIDmode,
1580                            gen_rtx_REG (DImode, FIRST_MMX_REG + regno));
1581     }
1584 (define_insn "*mmx_emms"
1585   [(match_parallel 0 "emms_operation"
1586     [(unspec_volatile [(const_int 0)] UNSPECV_EMMS)])]
1587   "TARGET_MMX"
1588   "emms"
1589   [(set_attr "type" "mmx")
1590    (set_attr "modrm" "0")
1591    (set_attr "memory" "none")])
1593 (define_expand "mmx_femms"
1594   [(match_par_dup 0 [(const_int 0)])]
1595   "TARGET_3DNOW"
1597   int regno;
1599   operands[0] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (17));
1601   XVECEXP (operands[0], 0, 0)
1602     = gen_rtx_UNSPEC_VOLATILE (VOIDmode, gen_rtvec (1, const0_rtx),
1603                                UNSPECV_FEMMS);
1605   for (regno = 0; regno < 8; regno++)
1606     {
1607       XVECEXP (operands[0], 0, regno + 1)
1608         = gen_rtx_CLOBBER (VOIDmode,
1609                            gen_rtx_REG (XFmode, FIRST_STACK_REG + regno));
1611       XVECEXP (operands[0], 0, regno + 9)
1612         = gen_rtx_CLOBBER (VOIDmode,
1613                            gen_rtx_REG (DImode, FIRST_MMX_REG + regno));
1614     }
1617 (define_insn "*mmx_femms"
1618   [(match_parallel 0 "emms_operation"
1619     [(unspec_volatile [(const_int 0)] UNSPECV_FEMMS)])]
1620   "TARGET_3DNOW"
1621   "femms"
1622   [(set_attr "type" "mmx")
1623    (set_attr "modrm" "0")
1624    (set_attr "memory" "none")])