Turn HARD_REGNO_CALL_PART_CLOBBERED into a target hook
[official-gcc.git] / gcc / config / i386 / mmx.md
blobb3f3633e96449ac221a60baa054bb60f89723249
1 ;; GCC machine description for MMX and 3dNOW! instructions
2 ;; Copyright (C) 2005-2017 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,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,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       /* Handle broken assemblers that require movd instead of movq.  */
103       if (!HAVE_AS_IX86_INTERUNIT_MOVQ
104           && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
105         return "movd\t{%1, %0|%0, %1}";
106       return "movq\t{%1, %0|%0, %1}";
108     case TYPE_SSECVT:
109       if (SSE_REG_P (operands[0]))
110         return "movq2dq\t{%1, %0|%0, %1}";
111       else
112         return "movdq2q\t{%1, %0|%0, %1}";
114     case TYPE_SSELOG1:
115       return standard_sse_constant_opcode (insn, operands[1]);
117     case TYPE_SSEMOV:
118       switch (get_attr_mode (insn))
119         {
120         case MODE_DI:
121           /* Handle broken assemblers that require movd instead of movq.  */
122           if (!HAVE_AS_IX86_INTERUNIT_MOVQ
123               && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
124             return "%vmovd\t{%1, %0|%0, %1}";
125           return "%vmovq\t{%1, %0|%0, %1}";
126         case MODE_TI:
127           return "%vmovdqa\t{%1, %0|%0, %1}";
128         case MODE_XI:
129           return "vmovdqa64\t{%g1, %g0|%g0, %g1}";
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,15,16")
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")
163               (const_string "sselog1")
164             (eq_attr "alternative" "17,18")
165               (const_string "ssecvt")
166            ]
167            (const_string "ssemov")))
168    (set (attr "prefix_rex")
169      (if_then_else (eq_attr "alternative" "9,10,15,16")
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")
185               (cond [(ior (match_operand 0 "ext_sse_reg_operand")
186                           (match_operand 1 "ext_sse_reg_operand"))
187                         (const_string "XI")
188                      (match_test "<MODE>mode == V2SFmode")
189                        (const_string "V4SF")
190                      (ior (not (match_test "TARGET_SSE2"))
191                           (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
192                        (const_string "V4SF")
193                      (match_test "TARGET_AVX")
194                        (const_string "TI")
195                      (match_test "optimize_function_for_size_p (cfun)")
196                        (const_string "V4SF")
197                     ]
198                     (const_string "TI"))
200             (and (eq_attr "alternative" "13,14")
201                  (ior (match_test "<MODE>mode == V2SFmode")
202                       (not (match_test "TARGET_SSE2"))))
203               (const_string "V2SF")
204            ]
205            (const_string "DI")))])
207 (define_split
208   [(set (match_operand:MMXMODE 0 "nonimmediate_gr_operand")
209         (match_operand:MMXMODE 1 "general_gr_operand"))]
210   "!TARGET_64BIT && reload_completed"
211   [(const_int 0)]
212   "ix86_split_long_move (operands); DONE;")
214 (define_expand "movmisalign<mode>"
215   [(set (match_operand:MMXMODE 0 "nonimmediate_operand")
216         (match_operand:MMXMODE 1 "nonimmediate_operand"))]
217   "TARGET_MMX"
219   ix86_expand_vector_move (<MODE>mode, operands);
220   DONE;
223 (define_insn "sse_movntq"
224   [(set (match_operand:DI 0 "memory_operand" "=m")
225         (unspec:DI [(match_operand:DI 1 "register_operand" "y")]
226                    UNSPEC_MOVNTQ))]
227   "TARGET_SSE || TARGET_3DNOW_A"
228   "movntq\t{%1, %0|%0, %1}"
229   [(set_attr "type" "mmxmov")
230    (set_attr "mode" "DI")])
232 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
234 ;; Parallel single-precision floating point arithmetic
236 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
238 (define_expand "mmx_addv2sf3"
239   [(set (match_operand:V2SF 0 "register_operand")
240         (plus:V2SF
241           (match_operand:V2SF 1 "nonimmediate_operand")
242           (match_operand:V2SF 2 "nonimmediate_operand")))]
243   "TARGET_3DNOW"
244   "ix86_fixup_binary_operands_no_copy (PLUS, V2SFmode, operands);")
246 (define_insn "*mmx_addv2sf3"
247   [(set (match_operand:V2SF 0 "register_operand" "=y")
248         (plus:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "%0")
249                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
250   "TARGET_3DNOW && ix86_binary_operator_ok (PLUS, V2SFmode, operands)"
251   "pfadd\t{%2, %0|%0, %2}"
252   [(set_attr "type" "mmxadd")
253    (set_attr "prefix_extra" "1")
254    (set_attr "mode" "V2SF")])
256 (define_expand "mmx_subv2sf3"
257   [(set (match_operand:V2SF 0 "register_operand")
258         (minus:V2SF (match_operand:V2SF 1 "register_operand")
259                     (match_operand:V2SF 2 "nonimmediate_operand")))]
260   "TARGET_3DNOW")
262 (define_expand "mmx_subrv2sf3"
263   [(set (match_operand:V2SF 0 "register_operand")
264         (minus:V2SF (match_operand:V2SF 2 "register_operand")
265                     (match_operand:V2SF 1 "nonimmediate_operand")))]
266   "TARGET_3DNOW")
268 (define_insn "*mmx_subv2sf3"
269   [(set (match_operand:V2SF 0 "register_operand" "=y,y")
270         (minus:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "0,ym")
271                     (match_operand:V2SF 2 "nonimmediate_operand" "ym,0")))]
272   "TARGET_3DNOW && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
273   "@
274    pfsub\t{%2, %0|%0, %2}
275    pfsubr\t{%1, %0|%0, %1}"
276   [(set_attr "type" "mmxadd")
277    (set_attr "prefix_extra" "1")
278    (set_attr "mode" "V2SF")])
280 (define_expand "mmx_mulv2sf3"
281   [(set (match_operand:V2SF 0 "register_operand")
282         (mult:V2SF (match_operand:V2SF 1 "nonimmediate_operand")
283                    (match_operand:V2SF 2 "nonimmediate_operand")))]
284   "TARGET_3DNOW"
285   "ix86_fixup_binary_operands_no_copy (MULT, V2SFmode, operands);")
287 (define_insn "*mmx_mulv2sf3"
288   [(set (match_operand:V2SF 0 "register_operand" "=y")
289         (mult:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "%0")
290                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
291   "TARGET_3DNOW && ix86_binary_operator_ok (MULT, V2SFmode, operands)"
292   "pfmul\t{%2, %0|%0, %2}"
293   [(set_attr "type" "mmxmul")
294    (set_attr "prefix_extra" "1")
295    (set_attr "mode" "V2SF")])
297 (define_expand "mmx_<code>v2sf3"
298   [(set (match_operand:V2SF 0 "register_operand")
299         (smaxmin:V2SF
300           (match_operand:V2SF 1 "nonimmediate_operand")
301           (match_operand:V2SF 2 "nonimmediate_operand")))]
302   "TARGET_3DNOW"
304   if (!flag_finite_math_only || flag_signed_zeros)
305     {
306       operands[1] = force_reg (V2SFmode, operands[1]);
307       emit_insn (gen_mmx_ieee_<maxmin_float>v2sf3
308                  (operands[0], operands[1], operands[2]));
309       DONE;
310     }
311   else
312     ix86_fixup_binary_operands_no_copy (<CODE>, V2SFmode, operands);
315 ;; These versions of the min/max patterns are intentionally ignorant of
316 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
317 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
318 ;; are undefined in this condition, we're certain this is correct.
320 (define_insn "*mmx_<code>v2sf3"
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 && ix86_binary_operator_ok (<CODE>, V2SFmode, operands)"
326   "pf<maxmin_float>\t{%2, %0|%0, %2}"
327   [(set_attr "type" "mmxadd")
328    (set_attr "prefix_extra" "1")
329    (set_attr "mode" "V2SF")])
331 ;; These versions of the min/max patterns implement exactly the operations
332 ;;   min = (op1 < op2 ? op1 : op2)
333 ;;   max = (!(op1 < op2) ? op1 : op2)
334 ;; Their operands are not commutative, and thus they may be used in the
335 ;; presence of -0.0 and NaN.
337 (define_insn "mmx_ieee_<ieee_maxmin>v2sf3"
338   [(set (match_operand:V2SF 0 "register_operand" "=y")
339         (unspec:V2SF
340           [(match_operand:V2SF 1 "register_operand" "0")
341            (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
342           IEEE_MAXMIN))]
343   "TARGET_3DNOW"
344   "pf<ieee_maxmin>\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))]
604   "operands[1] = gen_lowpart (SFmode, operands[1]);")
606 ;; Avoid combining registers from different units in a single alternative,
607 ;; see comment above inline_secondary_memory_needed function in i386.c
608 (define_insn "*vec_extractv2sf_1"
609   [(set (match_operand:SF 0 "nonimmediate_operand"     "=y,x,x,y,x,f,r")
610         (vec_select:SF
611           (match_operand:V2SF 1 "nonimmediate_operand" " 0,x,x,o,o,o,o")
612           (parallel [(const_int 1)])))]
613   "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
614   "@
615    punpckhdq\t%0, %0
616    %vmovshdup\t{%1, %0|%0, %1}
617    shufps\t{$0xe5, %1, %0|%0, %1, 0xe5}
618    #
619    #
620    #
621    #"
622   [(set_attr "isa" "*,sse3,noavx,*,*,*,*")
623    (set_attr "type" "mmxcvt,sse,sseshuf1,mmxmov,ssemov,fmov,imov")
624    (set (attr "length_immediate")
625      (if_then_else (eq_attr "alternative" "2")
626                    (const_string "1")
627                    (const_string "*")))
628    (set (attr "prefix_rep")
629      (if_then_else (eq_attr "alternative" "1")
630                    (const_string "1")
631                    (const_string "*")))
632    (set_attr "prefix" "orig,maybe_vex,orig,orig,orig,orig,orig")
633    (set_attr "mode" "DI,V4SF,V4SF,SF,SF,SF,SF")])
635 (define_split
636   [(set (match_operand:SF 0 "register_operand")
637         (vec_select:SF
638           (match_operand:V2SF 1 "memory_operand")
639           (parallel [(const_int 1)])))]
640   "TARGET_MMX && reload_completed"
641   [(set (match_dup 0) (match_dup 1))]
642   "operands[1] = adjust_address (operands[1], SFmode, 4);")
644 (define_expand "vec_extractv2sfsf"
645   [(match_operand:SF 0 "register_operand")
646    (match_operand:V2SF 1 "register_operand")
647    (match_operand 2 "const_int_operand")]
648   "TARGET_MMX"
650   ix86_expand_vector_extract (false, operands[0], operands[1],
651                               INTVAL (operands[2]));
652   DONE;
655 (define_expand "vec_initv2sfsf"
656   [(match_operand:V2SF 0 "register_operand")
657    (match_operand 1)]
658   "TARGET_SSE"
660   ix86_expand_vector_init (false, operands[0], operands[1]);
661   DONE;
664 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
666 ;; Parallel integral arithmetic
668 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
670 (define_expand "mmx_<plusminus_insn><mode>3"
671   [(set (match_operand:MMXMODEI8 0 "register_operand")
672         (plusminus:MMXMODEI8
673           (match_operand:MMXMODEI8 1 "nonimmediate_operand")
674           (match_operand:MMXMODEI8 2 "nonimmediate_operand")))]
675   "TARGET_MMX || (TARGET_SSE2 && <MODE>mode == V1DImode)"
676   "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
678 (define_insn "*mmx_<plusminus_insn><mode>3"
679   [(set (match_operand:MMXMODEI8 0 "register_operand" "=y")
680         (plusminus:MMXMODEI8
681           (match_operand:MMXMODEI8 1 "nonimmediate_operand" "<comm>0")
682           (match_operand:MMXMODEI8 2 "nonimmediate_operand" "ym")))]
683   "(TARGET_MMX || (TARGET_SSE2 && <MODE>mode == V1DImode))
684    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
685   "p<plusminus_mnemonic><mmxvecsize>\t{%2, %0|%0, %2}"
686   [(set_attr "type" "mmxadd")
687    (set_attr "mode" "DI")])
689 (define_expand "mmx_<plusminus_insn><mode>3"
690   [(set (match_operand:MMXMODE12 0 "register_operand")
691         (sat_plusminus:MMXMODE12
692           (match_operand:MMXMODE12 1 "nonimmediate_operand")
693           (match_operand:MMXMODE12 2 "nonimmediate_operand")))]
694   "TARGET_MMX"
695   "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
697 (define_insn "*mmx_<plusminus_insn><mode>3"
698   [(set (match_operand:MMXMODE12 0 "register_operand" "=y")
699         (sat_plusminus:MMXMODE12
700           (match_operand:MMXMODE12 1 "nonimmediate_operand" "<comm>0")
701           (match_operand:MMXMODE12 2 "nonimmediate_operand" "ym")))]
702   "TARGET_MMX && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
703   "p<plusminus_mnemonic><mmxvecsize>\t{%2, %0|%0, %2}"
704   [(set_attr "type" "mmxadd")
705    (set_attr "mode" "DI")])
707 (define_expand "mmx_mulv4hi3"
708   [(set (match_operand:V4HI 0 "register_operand")
709         (mult:V4HI (match_operand:V4HI 1 "nonimmediate_operand")
710                    (match_operand:V4HI 2 "nonimmediate_operand")))]
711   "TARGET_MMX"
712   "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
714 (define_insn "*mmx_mulv4hi3"
715   [(set (match_operand:V4HI 0 "register_operand" "=y")
716         (mult:V4HI (match_operand:V4HI 1 "nonimmediate_operand" "%0")
717                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
718   "TARGET_MMX && ix86_binary_operator_ok (MULT, V4HImode, operands)"
719   "pmullw\t{%2, %0|%0, %2}"
720   [(set_attr "type" "mmxmul")
721    (set_attr "mode" "DI")])
723 (define_expand "mmx_smulv4hi3_highpart"
724   [(set (match_operand:V4HI 0 "register_operand")
725         (truncate:V4HI
726           (lshiftrt:V4SI
727             (mult:V4SI
728               (sign_extend:V4SI
729                 (match_operand:V4HI 1 "nonimmediate_operand"))
730               (sign_extend:V4SI
731                 (match_operand:V4HI 2 "nonimmediate_operand")))
732             (const_int 16))))]
733   "TARGET_MMX"
734   "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
736 (define_insn "*mmx_smulv4hi3_highpart"
737   [(set (match_operand:V4HI 0 "register_operand" "=y")
738         (truncate:V4HI
739           (lshiftrt:V4SI
740             (mult:V4SI
741               (sign_extend:V4SI
742                 (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
743               (sign_extend:V4SI
744                 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
745             (const_int 16))))]
746   "TARGET_MMX && ix86_binary_operator_ok (MULT, V4HImode, operands)"
747   "pmulhw\t{%2, %0|%0, %2}"
748   [(set_attr "type" "mmxmul")
749    (set_attr "mode" "DI")])
751 (define_expand "mmx_umulv4hi3_highpart"
752   [(set (match_operand:V4HI 0 "register_operand")
753         (truncate:V4HI
754           (lshiftrt:V4SI
755             (mult:V4SI
756               (zero_extend:V4SI
757                 (match_operand:V4HI 1 "nonimmediate_operand"))
758               (zero_extend:V4SI
759                 (match_operand:V4HI 2 "nonimmediate_operand")))
760             (const_int 16))))]
761   "TARGET_SSE || TARGET_3DNOW_A"
762   "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
764 (define_insn "*mmx_umulv4hi3_highpart"
765   [(set (match_operand:V4HI 0 "register_operand" "=y")
766         (truncate:V4HI
767           (lshiftrt:V4SI
768             (mult:V4SI
769               (zero_extend:V4SI
770                 (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
771               (zero_extend:V4SI
772                 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
773           (const_int 16))))]
774   "(TARGET_SSE || TARGET_3DNOW_A)
775    && ix86_binary_operator_ok (MULT, V4HImode, operands)"
776   "pmulhuw\t{%2, %0|%0, %2}"
777   [(set_attr "type" "mmxmul")
778    (set_attr "mode" "DI")])
780 (define_expand "mmx_pmaddwd"
781   [(set (match_operand:V2SI 0 "register_operand")
782         (plus:V2SI
783           (mult:V2SI
784             (sign_extend:V2SI
785               (vec_select:V2HI
786                 (match_operand:V4HI 1 "nonimmediate_operand")
787                 (parallel [(const_int 0) (const_int 2)])))
788             (sign_extend:V2SI
789               (vec_select:V2HI
790                 (match_operand:V4HI 2 "nonimmediate_operand")
791                 (parallel [(const_int 0) (const_int 2)]))))
792           (mult:V2SI
793             (sign_extend:V2SI
794               (vec_select:V2HI (match_dup 1)
795                 (parallel [(const_int 1) (const_int 3)])))
796             (sign_extend:V2SI
797               (vec_select:V2HI (match_dup 2)
798                 (parallel [(const_int 1) (const_int 3)]))))))]
799   "TARGET_MMX"
800   "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
802 (define_insn "*mmx_pmaddwd"
803   [(set (match_operand:V2SI 0 "register_operand" "=y")
804         (plus:V2SI
805           (mult:V2SI
806             (sign_extend:V2SI
807               (vec_select:V2HI
808                 (match_operand:V4HI 1 "nonimmediate_operand" "%0")
809                 (parallel [(const_int 0) (const_int 2)])))
810             (sign_extend:V2SI
811               (vec_select:V2HI
812                 (match_operand:V4HI 2 "nonimmediate_operand" "ym")
813                 (parallel [(const_int 0) (const_int 2)]))))
814           (mult:V2SI
815             (sign_extend:V2SI
816               (vec_select:V2HI (match_dup 1)
817                 (parallel [(const_int 1) (const_int 3)])))
818             (sign_extend:V2SI
819               (vec_select:V2HI (match_dup 2)
820                 (parallel [(const_int 1) (const_int 3)]))))))]
821   "TARGET_MMX && ix86_binary_operator_ok (MULT, V4HImode, operands)"
822   "pmaddwd\t{%2, %0|%0, %2}"
823   [(set_attr "type" "mmxmul")
824    (set_attr "mode" "DI")])
826 (define_expand "mmx_pmulhrwv4hi3"
827   [(set (match_operand:V4HI 0 "register_operand")
828         (truncate:V4HI
829           (lshiftrt:V4SI
830             (plus:V4SI
831               (mult:V4SI
832                 (sign_extend:V4SI
833                   (match_operand:V4HI 1 "nonimmediate_operand"))
834                 (sign_extend:V4SI
835                   (match_operand:V4HI 2 "nonimmediate_operand")))
836               (const_vector:V4SI [(const_int 32768) (const_int 32768)
837                                   (const_int 32768) (const_int 32768)]))
838             (const_int 16))))]
839   "TARGET_3DNOW"
840   "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
842 (define_insn "*mmx_pmulhrwv4hi3"
843   [(set (match_operand:V4HI 0 "register_operand" "=y")
844         (truncate:V4HI
845           (lshiftrt:V4SI
846             (plus:V4SI
847               (mult:V4SI
848                 (sign_extend:V4SI
849                   (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
850                 (sign_extend:V4SI
851                   (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
852               (const_vector:V4SI [(const_int 32768) (const_int 32768)
853                                   (const_int 32768) (const_int 32768)]))
854             (const_int 16))))]
855   "TARGET_3DNOW && ix86_binary_operator_ok (MULT, V4HImode, operands)"
856   "pmulhrw\t{%2, %0|%0, %2}"
857   [(set_attr "type" "mmxmul")
858    (set_attr "prefix_extra" "1")
859    (set_attr "mode" "DI")])
861 (define_expand "sse2_umulv1siv1di3"
862   [(set (match_operand:V1DI 0 "register_operand")
863         (mult:V1DI
864           (zero_extend:V1DI
865             (vec_select:V1SI
866               (match_operand:V2SI 1 "nonimmediate_operand")
867               (parallel [(const_int 0)])))
868           (zero_extend:V1DI
869             (vec_select:V1SI
870               (match_operand:V2SI 2 "nonimmediate_operand")
871               (parallel [(const_int 0)])))))]
872   "TARGET_SSE2"
873   "ix86_fixup_binary_operands_no_copy (MULT, V2SImode, operands);")
875 (define_insn "*sse2_umulv1siv1di3"
876   [(set (match_operand:V1DI 0 "register_operand" "=y")
877         (mult:V1DI
878           (zero_extend:V1DI
879             (vec_select:V1SI
880               (match_operand:V2SI 1 "nonimmediate_operand" "%0")
881               (parallel [(const_int 0)])))
882           (zero_extend:V1DI
883             (vec_select:V1SI
884               (match_operand:V2SI 2 "nonimmediate_operand" "ym")
885               (parallel [(const_int 0)])))))]
886   "TARGET_SSE2 && ix86_binary_operator_ok (MULT, V2SImode, operands)"
887   "pmuludq\t{%2, %0|%0, %2}"
888   [(set_attr "type" "mmxmul")
889    (set_attr "mode" "DI")])
891 (define_expand "mmx_<code>v4hi3"
892   [(set (match_operand:V4HI 0 "register_operand")
893         (smaxmin:V4HI
894           (match_operand:V4HI 1 "nonimmediate_operand")
895           (match_operand:V4HI 2 "nonimmediate_operand")))]
896   "TARGET_SSE || TARGET_3DNOW_A"
897   "ix86_fixup_binary_operands_no_copy (<CODE>, V4HImode, operands);")
899 (define_insn "*mmx_<code>v4hi3"
900   [(set (match_operand:V4HI 0 "register_operand" "=y")
901         (smaxmin:V4HI
902           (match_operand:V4HI 1 "nonimmediate_operand" "%0")
903           (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
904   "(TARGET_SSE || TARGET_3DNOW_A)
905    && ix86_binary_operator_ok (<CODE>, V4HImode, operands)"
906   "p<maxmin_int>w\t{%2, %0|%0, %2}"
907   [(set_attr "type" "mmxadd")
908    (set_attr "mode" "DI")])
910 (define_expand "mmx_<code>v8qi3"
911   [(set (match_operand:V8QI 0 "register_operand")
912         (umaxmin:V8QI
913           (match_operand:V8QI 1 "nonimmediate_operand")
914           (match_operand:V8QI 2 "nonimmediate_operand")))]
915   "TARGET_SSE || TARGET_3DNOW_A"
916   "ix86_fixup_binary_operands_no_copy (<CODE>, V8QImode, operands);")
918 (define_insn "*mmx_<code>v8qi3"
919   [(set (match_operand:V8QI 0 "register_operand" "=y")
920         (umaxmin:V8QI
921           (match_operand:V8QI 1 "nonimmediate_operand" "%0")
922           (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
923   "(TARGET_SSE || TARGET_3DNOW_A)
924    && ix86_binary_operator_ok (<CODE>, V8QImode, operands)"
925   "p<maxmin_int>b\t{%2, %0|%0, %2}"
926   [(set_attr "type" "mmxadd")
927    (set_attr "mode" "DI")])
929 (define_insn "mmx_ashr<mode>3"
930   [(set (match_operand:MMXMODE24 0 "register_operand" "=y")
931         (ashiftrt:MMXMODE24
932           (match_operand:MMXMODE24 1 "register_operand" "0")
933           (match_operand:DI 2 "nonmemory_operand" "yN")))]
934   "TARGET_MMX"
935   "psra<mmxvecsize>\t{%2, %0|%0, %2}"
936   [(set_attr "type" "mmxshft")
937    (set (attr "length_immediate")
938      (if_then_else (match_operand 2 "const_int_operand")
939        (const_string "1")
940        (const_string "0")))
941    (set_attr "mode" "DI")])
943 (define_insn "mmx_<shift_insn><mode>3"
944   [(set (match_operand:MMXMODE248 0 "register_operand" "=y")
945         (any_lshift:MMXMODE248
946           (match_operand:MMXMODE248 1 "register_operand" "0")
947           (match_operand:DI 2 "nonmemory_operand" "yN")))]
948   "TARGET_MMX"
949   "p<vshift><mmxvecsize>\t{%2, %0|%0, %2}"
950   [(set_attr "type" "mmxshft")
951    (set (attr "length_immediate")
952      (if_then_else (match_operand 2 "const_int_operand")
953        (const_string "1")
954        (const_string "0")))
955    (set_attr "mode" "DI")])
957 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
959 ;; Parallel integral comparisons
961 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
963 (define_expand "mmx_eq<mode>3"
964   [(set (match_operand:MMXMODEI 0 "register_operand")
965         (eq:MMXMODEI
966           (match_operand:MMXMODEI 1 "nonimmediate_operand")
967           (match_operand:MMXMODEI 2 "nonimmediate_operand")))]
968   "TARGET_MMX"
969   "ix86_fixup_binary_operands_no_copy (EQ, <MODE>mode, operands);")
971 (define_insn "*mmx_eq<mode>3"
972   [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
973         (eq:MMXMODEI
974           (match_operand:MMXMODEI 1 "nonimmediate_operand" "%0")
975           (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
976   "TARGET_MMX && ix86_binary_operator_ok (EQ, <MODE>mode, operands)"
977   "pcmpeq<mmxvecsize>\t{%2, %0|%0, %2}"
978   [(set_attr "type" "mmxcmp")
979    (set_attr "mode" "DI")])
981 (define_insn "mmx_gt<mode>3"
982   [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
983         (gt:MMXMODEI
984           (match_operand:MMXMODEI 1 "register_operand" "0")
985           (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
986   "TARGET_MMX"
987   "pcmpgt<mmxvecsize>\t{%2, %0|%0, %2}"
988   [(set_attr "type" "mmxcmp")
989    (set_attr "mode" "DI")])
991 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
993 ;; Parallel integral logical operations
995 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
997 (define_insn "mmx_andnot<mode>3"
998   [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
999         (and:MMXMODEI
1000           (not:MMXMODEI (match_operand:MMXMODEI 1 "register_operand" "0"))
1001           (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
1002   "TARGET_MMX"
1003   "pandn\t{%2, %0|%0, %2}"
1004   [(set_attr "type" "mmxadd")
1005    (set_attr "mode" "DI")])
1007 (define_expand "mmx_<code><mode>3"
1008   [(set (match_operand:MMXMODEI 0 "register_operand")
1009         (any_logic:MMXMODEI
1010           (match_operand:MMXMODEI 1 "nonimmediate_operand")
1011           (match_operand:MMXMODEI 2 "nonimmediate_operand")))]
1012   "TARGET_MMX"
1013   "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
1015 (define_insn "*mmx_<code><mode>3"
1016   [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
1017         (any_logic:MMXMODEI
1018           (match_operand:MMXMODEI 1 "nonimmediate_operand" "%0")
1019           (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
1020   "TARGET_MMX && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
1021   "p<logic>\t{%2, %0|%0, %2}"
1022   [(set_attr "type" "mmxadd")
1023    (set_attr "mode" "DI")])
1025 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1027 ;; Parallel integral element swizzling
1029 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1031 (define_insn "mmx_packsswb"
1032   [(set (match_operand:V8QI 0 "register_operand" "=y")
1033         (vec_concat:V8QI
1034           (ss_truncate:V4QI
1035             (match_operand:V4HI 1 "register_operand" "0"))
1036           (ss_truncate:V4QI
1037             (match_operand:V4HI 2 "nonimmediate_operand" "ym"))))]
1038   "TARGET_MMX"
1039   "packsswb\t{%2, %0|%0, %2}"
1040   [(set_attr "type" "mmxshft")
1041    (set_attr "mode" "DI")])
1043 (define_insn "mmx_packssdw"
1044   [(set (match_operand:V4HI 0 "register_operand" "=y")
1045         (vec_concat:V4HI
1046           (ss_truncate:V2HI
1047             (match_operand:V2SI 1 "register_operand" "0"))
1048           (ss_truncate:V2HI
1049             (match_operand:V2SI 2 "nonimmediate_operand" "ym"))))]
1050   "TARGET_MMX"
1051   "packssdw\t{%2, %0|%0, %2}"
1052   [(set_attr "type" "mmxshft")
1053    (set_attr "mode" "DI")])
1055 (define_insn "mmx_packuswb"
1056   [(set (match_operand:V8QI 0 "register_operand" "=y")
1057         (vec_concat:V8QI
1058           (us_truncate:V4QI
1059             (match_operand:V4HI 1 "register_operand" "0"))
1060           (us_truncate:V4QI
1061             (match_operand:V4HI 2 "nonimmediate_operand" "ym"))))]
1062   "TARGET_MMX"
1063   "packuswb\t{%2, %0|%0, %2}"
1064   [(set_attr "type" "mmxshft")
1065    (set_attr "mode" "DI")])
1067 (define_insn "mmx_punpckhbw"
1068   [(set (match_operand:V8QI 0 "register_operand" "=y")
1069         (vec_select:V8QI
1070           (vec_concat:V16QI
1071             (match_operand:V8QI 1 "register_operand" "0")
1072             (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
1073           (parallel [(const_int 4) (const_int 12)
1074                      (const_int 5) (const_int 13)
1075                      (const_int 6) (const_int 14)
1076                      (const_int 7) (const_int 15)])))]
1077   "TARGET_MMX"
1078   "punpckhbw\t{%2, %0|%0, %2}"
1079   [(set_attr "type" "mmxcvt")
1080    (set_attr "mode" "DI")])
1082 (define_insn "mmx_punpcklbw"
1083   [(set (match_operand:V8QI 0 "register_operand" "=y")
1084         (vec_select:V8QI
1085           (vec_concat:V16QI
1086             (match_operand:V8QI 1 "register_operand" "0")
1087             (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
1088           (parallel [(const_int 0) (const_int 8)
1089                      (const_int 1) (const_int 9)
1090                      (const_int 2) (const_int 10)
1091                      (const_int 3) (const_int 11)])))]
1092   "TARGET_MMX"
1093   "punpcklbw\t{%2, %0|%0, %k2}"
1094   [(set_attr "type" "mmxcvt")
1095    (set_attr "mode" "DI")])
1097 (define_insn "mmx_punpckhwd"
1098   [(set (match_operand:V4HI 0 "register_operand" "=y")
1099         (vec_select:V4HI
1100           (vec_concat:V8HI
1101             (match_operand:V4HI 1 "register_operand" "0")
1102             (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
1103           (parallel [(const_int 2) (const_int 6)
1104                      (const_int 3) (const_int 7)])))]
1105   "TARGET_MMX"
1106   "punpckhwd\t{%2, %0|%0, %2}"
1107   [(set_attr "type" "mmxcvt")
1108    (set_attr "mode" "DI")])
1110 (define_insn "mmx_punpcklwd"
1111   [(set (match_operand:V4HI 0 "register_operand" "=y")
1112         (vec_select:V4HI
1113           (vec_concat:V8HI
1114             (match_operand:V4HI 1 "register_operand" "0")
1115             (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
1116           (parallel [(const_int 0) (const_int 4)
1117                      (const_int 1) (const_int 5)])))]
1118   "TARGET_MMX"
1119   "punpcklwd\t{%2, %0|%0, %k2}"
1120   [(set_attr "type" "mmxcvt")
1121    (set_attr "mode" "DI")])
1123 (define_insn "mmx_punpckhdq"
1124   [(set (match_operand:V2SI 0 "register_operand" "=y")
1125         (vec_select:V2SI
1126           (vec_concat:V4SI
1127             (match_operand:V2SI 1 "register_operand" "0")
1128             (match_operand:V2SI 2 "nonimmediate_operand" "ym"))
1129           (parallel [(const_int 1)
1130                      (const_int 3)])))]
1131   "TARGET_MMX"
1132   "punpckhdq\t{%2, %0|%0, %2}"
1133   [(set_attr "type" "mmxcvt")
1134    (set_attr "mode" "DI")])
1136 (define_insn "mmx_punpckldq"
1137   [(set (match_operand:V2SI 0 "register_operand" "=y")
1138         (vec_select:V2SI
1139           (vec_concat:V4SI
1140             (match_operand:V2SI 1 "register_operand" "0")
1141             (match_operand:V2SI 2 "nonimmediate_operand" "ym"))
1142           (parallel [(const_int 0)
1143                      (const_int 2)])))]
1144   "TARGET_MMX"
1145   "punpckldq\t{%2, %0|%0, %k2}"
1146   [(set_attr "type" "mmxcvt")
1147    (set_attr "mode" "DI")])
1149 (define_expand "mmx_pinsrw"
1150   [(set (match_operand:V4HI 0 "register_operand")
1151         (vec_merge:V4HI
1152           (vec_duplicate:V4HI
1153             (match_operand:SI 2 "nonimmediate_operand"))
1154           (match_operand:V4HI 1 "register_operand")
1155           (match_operand:SI 3 "const_0_to_3_operand")))]
1156   "TARGET_SSE || TARGET_3DNOW_A"
1158   operands[2] = gen_lowpart (HImode, operands[2]);
1159   operands[3] = GEN_INT (1 << INTVAL (operands[3]));
1162 (define_insn "*mmx_pinsrw"
1163   [(set (match_operand:V4HI 0 "register_operand" "=y")
1164         (vec_merge:V4HI
1165           (vec_duplicate:V4HI
1166             (match_operand:HI 2 "nonimmediate_operand" "rm"))
1167           (match_operand:V4HI 1 "register_operand" "0")
1168           (match_operand:SI 3 "const_int_operand")))]
1169   "(TARGET_SSE || TARGET_3DNOW_A)
1170    && ((unsigned) exact_log2 (INTVAL (operands[3]))
1171        < GET_MODE_NUNITS (V4HImode))"
1173   operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])));
1174   if (MEM_P (operands[2]))
1175     return "pinsrw\t{%3, %2, %0|%0, %2, %3}";
1176   else
1177     return "pinsrw\t{%3, %k2, %0|%0, %k2, %3}";
1179   [(set_attr "type" "mmxcvt")
1180    (set_attr "length_immediate" "1")
1181    (set_attr "mode" "DI")])
1183 (define_insn "mmx_pextrw"
1184   [(set (match_operand:SI 0 "register_operand" "=r")
1185         (zero_extend:SI
1186           (vec_select:HI
1187             (match_operand:V4HI 1 "register_operand" "y")
1188             (parallel [(match_operand:SI 2 "const_0_to_3_operand" "n")]))))]
1189   "TARGET_SSE || TARGET_3DNOW_A"
1190   "pextrw\t{%2, %1, %0|%0, %1, %2}"
1191   [(set_attr "type" "mmxcvt")
1192    (set_attr "length_immediate" "1")
1193    (set_attr "mode" "DI")])
1195 (define_expand "mmx_pshufw"
1196   [(match_operand:V4HI 0 "register_operand")
1197    (match_operand:V4HI 1 "nonimmediate_operand")
1198    (match_operand:SI 2 "const_int_operand")]
1199   "TARGET_SSE || TARGET_3DNOW_A"
1201   int mask = INTVAL (operands[2]);
1202   emit_insn (gen_mmx_pshufw_1 (operands[0], operands[1],
1203                                GEN_INT ((mask >> 0) & 3),
1204                                GEN_INT ((mask >> 2) & 3),
1205                                GEN_INT ((mask >> 4) & 3),
1206                                GEN_INT ((mask >> 6) & 3)));
1207   DONE;
1210 (define_insn "mmx_pshufw_1"
1211   [(set (match_operand:V4HI 0 "register_operand" "=y")
1212         (vec_select:V4HI
1213           (match_operand:V4HI 1 "nonimmediate_operand" "ym")
1214           (parallel [(match_operand 2 "const_0_to_3_operand")
1215                      (match_operand 3 "const_0_to_3_operand")
1216                      (match_operand 4 "const_0_to_3_operand")
1217                      (match_operand 5 "const_0_to_3_operand")])))]
1218   "TARGET_SSE || TARGET_3DNOW_A"
1220   int mask = 0;
1221   mask |= INTVAL (operands[2]) << 0;
1222   mask |= INTVAL (operands[3]) << 2;
1223   mask |= INTVAL (operands[4]) << 4;
1224   mask |= INTVAL (operands[5]) << 6;
1225   operands[2] = GEN_INT (mask);
1227   return "pshufw\t{%2, %1, %0|%0, %1, %2}";
1229   [(set_attr "type" "mmxcvt")
1230    (set_attr "length_immediate" "1")
1231    (set_attr "mode" "DI")])
1233 (define_insn "mmx_pswapdv2si2"
1234   [(set (match_operand:V2SI 0 "register_operand" "=y")
1235         (vec_select:V2SI
1236           (match_operand:V2SI 1 "nonimmediate_operand" "ym")
1237           (parallel [(const_int 1) (const_int 0)])))]
1238   "TARGET_3DNOW_A"
1239   "pswapd\t{%1, %0|%0, %1}"
1240   [(set_attr "type" "mmxcvt")
1241    (set_attr "prefix_extra" "1")
1242    (set_attr "mode" "DI")])
1244 (define_insn "*vec_dupv4hi"
1245   [(set (match_operand:V4HI 0 "register_operand" "=y")
1246         (vec_duplicate:V4HI
1247           (truncate:HI
1248             (match_operand:SI 1 "register_operand" "0"))))]
1249   "TARGET_SSE || TARGET_3DNOW_A"
1250   "pshufw\t{$0, %0, %0|%0, %0, 0}"
1251   [(set_attr "type" "mmxcvt")
1252    (set_attr "length_immediate" "1")
1253    (set_attr "mode" "DI")])
1255 (define_insn "*vec_dupv2si"
1256   [(set (match_operand:V2SI 0 "register_operand" "=y")
1257         (vec_duplicate:V2SI
1258           (match_operand:SI 1 "register_operand" "0")))]
1259   "TARGET_MMX"
1260   "punpckldq\t%0, %0"
1261   [(set_attr "type" "mmxcvt")
1262    (set_attr "mode" "DI")])
1264 (define_insn "*mmx_concatv2si"
1265   [(set (match_operand:V2SI 0 "register_operand"     "=y,y")
1266         (vec_concat:V2SI
1267           (match_operand:SI 1 "nonimmediate_operand" " 0,rm")
1268           (match_operand:SI 2 "vector_move_operand"  "ym,C")))]
1269   "TARGET_MMX && !TARGET_SSE"
1270   "@
1271    punpckldq\t{%2, %0|%0, %2}
1272    movd\t{%1, %0|%0, %1}"
1273   [(set_attr "type" "mmxcvt,mmxmov")
1274    (set_attr "mode" "DI")])
1276 (define_expand "vec_setv2si"
1277   [(match_operand:V2SI 0 "register_operand")
1278    (match_operand:SI 1 "register_operand")
1279    (match_operand 2 "const_int_operand")]
1280   "TARGET_MMX"
1282   ix86_expand_vector_set (false, operands[0], operands[1],
1283                           INTVAL (operands[2]));
1284   DONE;
1287 ;; Avoid combining registers from different units in a single alternative,
1288 ;; see comment above inline_secondary_memory_needed function in i386.c
1289 (define_insn_and_split "*vec_extractv2si_0"
1290   [(set (match_operand:SI 0 "nonimmediate_operand"     "=x,m,y, m,r")
1291         (vec_select:SI
1292           (match_operand:V2SI 1 "nonimmediate_operand" "xm,x,ym,y,m")
1293           (parallel [(const_int 0)])))]
1294   "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1295   "#"
1296   "&& reload_completed"
1297   [(set (match_dup 0) (match_dup 1))]
1298   "operands[1] = gen_lowpart (SImode, operands[1]);")
1300 ;; Avoid combining registers from different units in a single alternative,
1301 ;; see comment above inline_secondary_memory_needed function in i386.c
1302 (define_insn "*vec_extractv2si_1"
1303   [(set (match_operand:SI 0 "nonimmediate_operand"     "=y,x,x,y,x,r")
1304         (vec_select:SI
1305           (match_operand:V2SI 1 "nonimmediate_operand" " 0,x,x,o,o,o")
1306           (parallel [(const_int 1)])))]
1307   "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1308   "@
1309    punpckhdq\t%0, %0
1310    %vpshufd\t{$0xe5, %1, %0|%0, %1, 0xe5}
1311    shufps\t{$0xe5, %1, %0|%0, %1, 0xe5}
1312    #
1313    #
1314    #"
1315   [(set_attr "isa" "*,sse2,noavx,*,*,*")
1316    (set_attr "type" "mmxcvt,sseshuf1,sseshuf1,mmxmov,ssemov,imov")
1317    (set (attr "length_immediate")
1318      (if_then_else (eq_attr "alternative" "1,2")
1319                    (const_string "1")
1320                    (const_string "*")))
1321    (set_attr "prefix" "orig,maybe_vex,orig,orig,orig,orig")
1322    (set_attr "mode" "DI,TI,V4SF,SI,SI,SI")])
1324 (define_split
1325   [(set (match_operand:SI 0 "register_operand")
1326         (vec_select:SI
1327           (match_operand:V2SI 1 "memory_operand")
1328           (parallel [(const_int 1)])))]
1329   "TARGET_MMX && reload_completed"
1330   [(set (match_dup 0) (match_dup 1))]
1331   "operands[1] = adjust_address (operands[1], SImode, 4);")
1333 (define_insn_and_split "*vec_extractv2si_zext_mem"
1334   [(set (match_operand:DI 0 "register_operand" "=y,x,r")
1335         (zero_extend:DI
1336           (vec_select:SI
1337             (match_operand:V2SI 1 "memory_operand" "o,o,o")
1338             (parallel [(match_operand:SI 2 "const_0_to_1_operand")]))))]
1339   "TARGET_64BIT && TARGET_MMX"
1340   "#"
1341   "&& reload_completed"
1342   [(set (match_dup 0) (zero_extend:DI (match_dup 1)))]
1344   operands[1] = adjust_address (operands[1], SImode, INTVAL (operands[2]) * 4);
1347 (define_expand "vec_extractv2sisi"
1348   [(match_operand:SI 0 "register_operand")
1349    (match_operand:V2SI 1 "register_operand")
1350    (match_operand 2 "const_int_operand")]
1351   "TARGET_MMX"
1353   ix86_expand_vector_extract (false, operands[0], operands[1],
1354                               INTVAL (operands[2]));
1355   DONE;
1358 (define_expand "vec_initv2sisi"
1359   [(match_operand:V2SI 0 "register_operand")
1360    (match_operand 1)]
1361   "TARGET_SSE"
1363   ix86_expand_vector_init (false, operands[0], operands[1]);
1364   DONE;
1367 (define_expand "vec_setv4hi"
1368   [(match_operand:V4HI 0 "register_operand")
1369    (match_operand:HI 1 "register_operand")
1370    (match_operand 2 "const_int_operand")]
1371   "TARGET_MMX"
1373   ix86_expand_vector_set (false, operands[0], operands[1],
1374                           INTVAL (operands[2]));
1375   DONE;
1378 (define_expand "vec_extractv4hihi"
1379   [(match_operand:HI 0 "register_operand")
1380    (match_operand:V4HI 1 "register_operand")
1381    (match_operand 2 "const_int_operand")]
1382   "TARGET_MMX"
1384   ix86_expand_vector_extract (false, operands[0], operands[1],
1385                               INTVAL (operands[2]));
1386   DONE;
1389 (define_expand "vec_initv4hihi"
1390   [(match_operand:V4HI 0 "register_operand")
1391    (match_operand 1)]
1392   "TARGET_SSE"
1394   ix86_expand_vector_init (false, operands[0], operands[1]);
1395   DONE;
1398 (define_expand "vec_setv8qi"
1399   [(match_operand:V8QI 0 "register_operand")
1400    (match_operand:QI 1 "register_operand")
1401    (match_operand 2 "const_int_operand")]
1402   "TARGET_MMX"
1404   ix86_expand_vector_set (false, operands[0], operands[1],
1405                           INTVAL (operands[2]));
1406   DONE;
1409 (define_expand "vec_extractv8qiqi"
1410   [(match_operand:QI 0 "register_operand")
1411    (match_operand:V8QI 1 "register_operand")
1412    (match_operand 2 "const_int_operand")]
1413   "TARGET_MMX"
1415   ix86_expand_vector_extract (false, operands[0], operands[1],
1416                               INTVAL (operands[2]));
1417   DONE;
1420 (define_expand "vec_initv8qiqi"
1421   [(match_operand:V8QI 0 "register_operand")
1422    (match_operand 1)]
1423   "TARGET_SSE"
1425   ix86_expand_vector_init (false, operands[0], operands[1]);
1426   DONE;
1429 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1431 ;; Miscellaneous
1433 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1435 (define_expand "mmx_uavgv8qi3"
1436   [(set (match_operand:V8QI 0 "register_operand")
1437         (truncate:V8QI
1438           (lshiftrt:V8HI
1439             (plus:V8HI
1440               (plus:V8HI
1441                 (zero_extend:V8HI
1442                   (match_operand:V8QI 1 "nonimmediate_operand"))
1443                 (zero_extend:V8HI
1444                   (match_operand:V8QI 2 "nonimmediate_operand")))
1445               (const_vector:V8HI [(const_int 1) (const_int 1)
1446                                   (const_int 1) (const_int 1)
1447                                   (const_int 1) (const_int 1)
1448                                   (const_int 1) (const_int 1)]))
1449             (const_int 1))))]
1450   "TARGET_SSE || TARGET_3DNOW"
1451   "ix86_fixup_binary_operands_no_copy (PLUS, V8QImode, operands);")
1453 (define_insn "*mmx_uavgv8qi3"
1454   [(set (match_operand:V8QI 0 "register_operand" "=y")
1455         (truncate:V8QI
1456           (lshiftrt:V8HI
1457             (plus:V8HI
1458               (plus:V8HI
1459                 (zero_extend:V8HI
1460                   (match_operand:V8QI 1 "nonimmediate_operand" "%0"))
1461                 (zero_extend:V8HI
1462                   (match_operand:V8QI 2 "nonimmediate_operand" "ym")))
1463               (const_vector:V8HI [(const_int 1) (const_int 1)
1464                                   (const_int 1) (const_int 1)
1465                                   (const_int 1) (const_int 1)
1466                                   (const_int 1) (const_int 1)]))
1467             (const_int 1))))]
1468   "(TARGET_SSE || TARGET_3DNOW)
1469    && ix86_binary_operator_ok (PLUS, V8QImode, operands)"
1471   /* These two instructions have the same operation, but their encoding
1472      is different.  Prefer the one that is de facto standard.  */
1473   if (TARGET_SSE || TARGET_3DNOW_A)
1474     return "pavgb\t{%2, %0|%0, %2}";
1475   else
1476     return "pavgusb\t{%2, %0|%0, %2}";
1478   [(set_attr "type" "mmxshft")
1479    (set (attr "prefix_extra")
1480      (if_then_else
1481        (not (ior (match_test "TARGET_SSE")
1482                  (match_test "TARGET_3DNOW_A")))
1483        (const_string "1")
1484        (const_string "*")))
1485    (set_attr "mode" "DI")])
1487 (define_expand "mmx_uavgv4hi3"
1488   [(set (match_operand:V4HI 0 "register_operand")
1489         (truncate:V4HI
1490           (lshiftrt:V4SI
1491             (plus:V4SI
1492               (plus:V4SI
1493                 (zero_extend:V4SI
1494                   (match_operand:V4HI 1 "nonimmediate_operand"))
1495                 (zero_extend:V4SI
1496                   (match_operand:V4HI 2 "nonimmediate_operand")))
1497               (const_vector:V4SI [(const_int 1) (const_int 1)
1498                                   (const_int 1) (const_int 1)]))
1499             (const_int 1))))]
1500   "TARGET_SSE || TARGET_3DNOW_A"
1501   "ix86_fixup_binary_operands_no_copy (PLUS, V4HImode, operands);")
1503 (define_insn "*mmx_uavgv4hi3"
1504   [(set (match_operand:V4HI 0 "register_operand" "=y")
1505         (truncate:V4HI
1506           (lshiftrt:V4SI
1507             (plus:V4SI
1508               (plus:V4SI
1509                 (zero_extend:V4SI
1510                   (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
1511                 (zero_extend:V4SI
1512                   (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
1513               (const_vector:V4SI [(const_int 1) (const_int 1)
1514                                   (const_int 1) (const_int 1)]))
1515             (const_int 1))))]
1516   "(TARGET_SSE || TARGET_3DNOW_A)
1517    && ix86_binary_operator_ok (PLUS, V4HImode, operands)"
1518   "pavgw\t{%2, %0|%0, %2}"
1519   [(set_attr "type" "mmxshft")
1520    (set_attr "mode" "DI")])
1522 (define_insn "mmx_psadbw"
1523   [(set (match_operand:V1DI 0 "register_operand" "=y")
1524         (unspec:V1DI [(match_operand:V8QI 1 "register_operand" "0")
1525                       (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
1526                      UNSPEC_PSADBW))]
1527   "TARGET_SSE || TARGET_3DNOW_A"
1528   "psadbw\t{%2, %0|%0, %2}"
1529   [(set_attr "type" "mmxshft")
1530    (set_attr "mode" "DI")])
1532 (define_insn "mmx_pmovmskb"
1533   [(set (match_operand:SI 0 "register_operand" "=r")
1534         (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")]
1535                    UNSPEC_MOVMSK))]
1536   "TARGET_SSE || TARGET_3DNOW_A"
1537   "pmovmskb\t{%1, %0|%0, %1}"
1538   [(set_attr "type" "mmxcvt")
1539    (set_attr "mode" "DI")])
1541 (define_expand "mmx_maskmovq"
1542   [(set (match_operand:V8QI 0 "memory_operand")
1543         (unspec:V8QI [(match_operand:V8QI 1 "register_operand")
1544                       (match_operand:V8QI 2 "register_operand")
1545                       (match_dup 0)]
1546                      UNSPEC_MASKMOV))]
1547   "TARGET_SSE || TARGET_3DNOW_A")
1549 (define_insn "*mmx_maskmovq"
1550   [(set (mem:V8QI (match_operand:P 0 "register_operand" "D"))
1551         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
1552                       (match_operand:V8QI 2 "register_operand" "y")
1553                       (mem:V8QI (match_dup 0))]
1554                      UNSPEC_MASKMOV))]
1555   "TARGET_SSE || TARGET_3DNOW_A"
1556   ;; @@@ check ordering of operands in intel/nonintel syntax
1557   "maskmovq\t{%2, %1|%1, %2}"
1558   [(set_attr "type" "mmxcvt")
1559    (set_attr "znver1_decode" "vector")
1560    (set_attr "mode" "DI")])
1562 (define_expand "mmx_emms"
1563   [(match_par_dup 0 [(const_int 0)])]
1564   "TARGET_MMX"
1566   int regno;
1568   operands[0] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (17));
1570   XVECEXP (operands[0], 0, 0)
1571     = gen_rtx_UNSPEC_VOLATILE (VOIDmode, gen_rtvec (1, const0_rtx),
1572                                UNSPECV_EMMS);
1574   for (regno = 0; regno < 8; regno++)
1575     {
1576       XVECEXP (operands[0], 0, regno + 1)
1577         = gen_rtx_CLOBBER (VOIDmode,
1578                            gen_rtx_REG (XFmode, FIRST_STACK_REG + regno));
1580       XVECEXP (operands[0], 0, regno + 9)
1581         = gen_rtx_CLOBBER (VOIDmode,
1582                            gen_rtx_REG (DImode, FIRST_MMX_REG + regno));
1583     }
1586 (define_insn "*mmx_emms"
1587   [(match_parallel 0 "emms_operation"
1588     [(unspec_volatile [(const_int 0)] UNSPECV_EMMS)])]
1589   "TARGET_MMX"
1590   "emms"
1591   [(set_attr "type" "mmx")
1592    (set_attr "modrm" "0")
1593    (set_attr "memory" "none")])
1595 (define_expand "mmx_femms"
1596   [(match_par_dup 0 [(const_int 0)])]
1597   "TARGET_3DNOW"
1599   int regno;
1601   operands[0] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (17));
1603   XVECEXP (operands[0], 0, 0)
1604     = gen_rtx_UNSPEC_VOLATILE (VOIDmode, gen_rtvec (1, const0_rtx),
1605                                UNSPECV_FEMMS);
1607   for (regno = 0; regno < 8; regno++)
1608     {
1609       XVECEXP (operands[0], 0, regno + 1)
1610         = gen_rtx_CLOBBER (VOIDmode,
1611                            gen_rtx_REG (XFmode, FIRST_STACK_REG + regno));
1613       XVECEXP (operands[0], 0, regno + 9)
1614         = gen_rtx_CLOBBER (VOIDmode,
1615                            gen_rtx_REG (DImode, FIRST_MMX_REG + regno));
1616     }
1619 (define_insn "*mmx_femms"
1620   [(match_parallel 0 "emms_operation"
1621     [(unspec_volatile [(const_int 0)] UNSPECV_FEMMS)])]
1622   "TARGET_3DNOW"
1623   "femms"
1624   [(set_attr "type" "mmx")
1625    (set_attr "modrm" "0")
1626    (set_attr "memory" "none")])