Allow target to override gnu-user.h crti and crtn
[official-gcc.git] / gcc / config / i386 / mmx.md
blobe60b2296ab6b102752434c9d649c0994953bce1b
1 ;; GCC machine description for MMX and 3dNOW! instructions
2 ;; Copyright (C) 2005-2018 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  ,?!y,v,v,v,m,r,v,!y,*x")
82         (match_operand:MMXMODE 1 "nonimm_or_0_operand"
83     "rCo,rC,C,rm,rC,C  ,!y,m  ,?!y,?!y,r  ,C,v,m,v,v,r,*x,!y"))]
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);
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")
150               (const_string "x64")
151             (eq_attr "alternative" "15,16")
152               (const_string "x64_sse2")
153             (eq_attr "alternative" "17,18")
154               (const_string "sse2")
155            ]
156            (const_string "*")))
157    (set (attr "type")
158      (cond [(eq_attr "alternative" "0,1")
159               (const_string "multi")
160             (eq_attr "alternative" "2,3,4")
161               (const_string "imov")
162             (eq_attr "alternative" "5")
163               (const_string "mmx")
164             (eq_attr "alternative" "6,7,8,9,10")
165               (const_string "mmxmov")
166             (eq_attr "alternative" "11")
167               (const_string "sselog1")
168             (eq_attr "alternative" "17,18")
169               (const_string "ssecvt")
170            ]
171            (const_string "ssemov")))
172    (set (attr "prefix_rex")
173      (if_then_else (eq_attr "alternative" "9,10,15,16")
174        (const_string "1")
175        (const_string "*")))
176    (set (attr "prefix")
177      (if_then_else (eq_attr "type" "sselog1,ssemov")
178        (const_string "maybe_vex")
179        (const_string "orig")))
180    (set (attr "prefix_data16")
181      (if_then_else
182        (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
183        (const_string "1")
184        (const_string "*")))
185    (set (attr "mode")
186      (cond [(eq_attr "alternative" "2")
187               (const_string "SI")
188             (eq_attr "alternative" "11,12")
189               (cond [(ior (match_operand 0 "ext_sse_reg_operand")
190                           (match_operand 1 "ext_sse_reg_operand"))
191                         (const_string "XI")
192                      (match_test "<MODE>mode == V2SFmode")
193                        (const_string "V4SF")
194                      (ior (not (match_test "TARGET_SSE2"))
195                           (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
196                        (const_string "V4SF")
197                      (match_test "TARGET_AVX")
198                        (const_string "TI")
199                      (match_test "optimize_function_for_size_p (cfun)")
200                        (const_string "V4SF")
201                     ]
202                     (const_string "TI"))
204             (and (eq_attr "alternative" "13,14")
205                  (ior (match_test "<MODE>mode == V2SFmode")
206                       (not (match_test "TARGET_SSE2"))))
207               (const_string "V2SF")
208            ]
209            (const_string "DI")))
210    (set (attr "preferred_for_speed")
211      (cond [(eq_attr "alternative" "10,15")
212               (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
213             (eq_attr "alternative" "11,16")
214               (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
215            ]
216            (symbol_ref "true")))])
218 (define_split
219   [(set (match_operand:MMXMODE 0 "nonimmediate_gr_operand")
220         (match_operand:MMXMODE 1 "nonimmediate_gr_operand"))]
221   "!TARGET_64BIT && reload_completed"
222   [(const_int 0)]
223   "ix86_split_long_move (operands); DONE;")
225 (define_split
226   [(set (match_operand:MMXMODE 0 "nonimmediate_gr_operand")
227         (match_operand:MMXMODE 1 "const0_operand"))]
228   "!TARGET_64BIT && reload_completed"
229   [(const_int 0)]
230   "ix86_split_long_move (operands); DONE;")
232 (define_expand "movmisalign<mode>"
233   [(set (match_operand:MMXMODE 0 "nonimmediate_operand")
234         (match_operand:MMXMODE 1 "nonimmediate_operand"))]
235   "TARGET_MMX"
237   ix86_expand_vector_move (<MODE>mode, operands);
238   DONE;
241 (define_insn "sse_movntq"
242   [(set (match_operand:DI 0 "memory_operand" "=m")
243         (unspec:DI [(match_operand:DI 1 "register_operand" "y")]
244                    UNSPEC_MOVNTQ))]
245   "TARGET_SSE || TARGET_3DNOW_A"
246   "movntq\t{%1, %0|%0, %1}"
247   [(set_attr "type" "mmxmov")
248    (set_attr "mode" "DI")])
250 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
252 ;; Parallel single-precision floating point arithmetic
254 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
256 (define_expand "mmx_addv2sf3"
257   [(set (match_operand:V2SF 0 "register_operand")
258         (plus:V2SF
259           (match_operand:V2SF 1 "nonimmediate_operand")
260           (match_operand:V2SF 2 "nonimmediate_operand")))]
261   "TARGET_3DNOW"
262   "ix86_fixup_binary_operands_no_copy (PLUS, V2SFmode, operands);")
264 (define_insn "*mmx_addv2sf3"
265   [(set (match_operand:V2SF 0 "register_operand" "=y")
266         (plus:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "%0")
267                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
268   "TARGET_3DNOW && ix86_binary_operator_ok (PLUS, V2SFmode, operands)"
269   "pfadd\t{%2, %0|%0, %2}"
270   [(set_attr "type" "mmxadd")
271    (set_attr "prefix_extra" "1")
272    (set_attr "mode" "V2SF")])
274 (define_expand "mmx_subv2sf3"
275   [(set (match_operand:V2SF 0 "register_operand")
276         (minus:V2SF (match_operand:V2SF 1 "register_operand")
277                     (match_operand:V2SF 2 "nonimmediate_operand")))]
278   "TARGET_3DNOW")
280 (define_expand "mmx_subrv2sf3"
281   [(set (match_operand:V2SF 0 "register_operand")
282         (minus:V2SF (match_operand:V2SF 2 "register_operand")
283                     (match_operand:V2SF 1 "nonimmediate_operand")))]
284   "TARGET_3DNOW")
286 (define_insn "*mmx_subv2sf3"
287   [(set (match_operand:V2SF 0 "register_operand" "=y,y")
288         (minus:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "0,ym")
289                     (match_operand:V2SF 2 "nonimmediate_operand" "ym,0")))]
290   "TARGET_3DNOW && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
291   "@
292    pfsub\t{%2, %0|%0, %2}
293    pfsubr\t{%1, %0|%0, %1}"
294   [(set_attr "type" "mmxadd")
295    (set_attr "prefix_extra" "1")
296    (set_attr "mode" "V2SF")])
298 (define_expand "mmx_mulv2sf3"
299   [(set (match_operand:V2SF 0 "register_operand")
300         (mult:V2SF (match_operand:V2SF 1 "nonimmediate_operand")
301                    (match_operand:V2SF 2 "nonimmediate_operand")))]
302   "TARGET_3DNOW"
303   "ix86_fixup_binary_operands_no_copy (MULT, V2SFmode, operands);")
305 (define_insn "*mmx_mulv2sf3"
306   [(set (match_operand:V2SF 0 "register_operand" "=y")
307         (mult:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "%0")
308                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
309   "TARGET_3DNOW && ix86_binary_operator_ok (MULT, V2SFmode, operands)"
310   "pfmul\t{%2, %0|%0, %2}"
311   [(set_attr "type" "mmxmul")
312    (set_attr "prefix_extra" "1")
313    (set_attr "mode" "V2SF")])
315 (define_expand "mmx_<code>v2sf3"
316   [(set (match_operand:V2SF 0 "register_operand")
317         (smaxmin:V2SF
318           (match_operand:V2SF 1 "nonimmediate_operand")
319           (match_operand:V2SF 2 "nonimmediate_operand")))]
320   "TARGET_3DNOW"
322   if (!flag_finite_math_only || flag_signed_zeros)
323     {
324       operands[1] = force_reg (V2SFmode, operands[1]);
325       emit_insn (gen_mmx_ieee_<maxmin_float>v2sf3
326                  (operands[0], operands[1], operands[2]));
327       DONE;
328     }
329   else
330     ix86_fixup_binary_operands_no_copy (<CODE>, V2SFmode, operands);
333 ;; These versions of the min/max patterns are intentionally ignorant of
334 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
335 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
336 ;; are undefined in this condition, we're certain this is correct.
338 (define_insn "*mmx_<code>v2sf3"
339   [(set (match_operand:V2SF 0 "register_operand" "=y")
340         (smaxmin:V2SF
341           (match_operand:V2SF 1 "nonimmediate_operand" "%0")
342           (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
343   "TARGET_3DNOW && ix86_binary_operator_ok (<CODE>, V2SFmode, operands)"
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 ;; These versions of the min/max patterns implement exactly the operations
350 ;;   min = (op1 < op2 ? op1 : op2)
351 ;;   max = (!(op1 < op2) ? op1 : op2)
352 ;; Their operands are not commutative, and thus they may be used in the
353 ;; presence of -0.0 and NaN.
355 (define_insn "mmx_ieee_<ieee_maxmin>v2sf3"
356   [(set (match_operand:V2SF 0 "register_operand" "=y")
357         (unspec:V2SF
358           [(match_operand:V2SF 1 "register_operand" "0")
359            (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
360           IEEE_MAXMIN))]
361   "TARGET_3DNOW"
362   "pf<ieee_maxmin>\t{%2, %0|%0, %2}"
363   [(set_attr "type" "mmxadd")
364    (set_attr "prefix_extra" "1")
365    (set_attr "mode" "V2SF")])
367 (define_insn "mmx_rcpv2sf2"
368   [(set (match_operand:V2SF 0 "register_operand" "=y")
369         (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
370                      UNSPEC_PFRCP))]
371   "TARGET_3DNOW"
372   "pfrcp\t{%1, %0|%0, %1}"
373   [(set_attr "type" "mmx")
374    (set_attr "prefix_extra" "1")
375    (set_attr "mode" "V2SF")])
377 (define_insn "mmx_rcpit1v2sf3"
378   [(set (match_operand:V2SF 0 "register_operand" "=y")
379         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
380                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
381                      UNSPEC_PFRCPIT1))]
382   "TARGET_3DNOW"
383   "pfrcpit1\t{%2, %0|%0, %2}"
384   [(set_attr "type" "mmx")
385    (set_attr "prefix_extra" "1")
386    (set_attr "mode" "V2SF")])
388 (define_insn "mmx_rcpit2v2sf3"
389   [(set (match_operand:V2SF 0 "register_operand" "=y")
390         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
391                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
392                      UNSPEC_PFRCPIT2))]
393   "TARGET_3DNOW"
394   "pfrcpit2\t{%2, %0|%0, %2}"
395   [(set_attr "type" "mmx")
396    (set_attr "prefix_extra" "1")
397    (set_attr "mode" "V2SF")])
399 (define_insn "mmx_rsqrtv2sf2"
400   [(set (match_operand:V2SF 0 "register_operand" "=y")
401         (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
402                      UNSPEC_PFRSQRT))]
403   "TARGET_3DNOW"
404   "pfrsqrt\t{%1, %0|%0, %1}"
405   [(set_attr "type" "mmx")
406    (set_attr "prefix_extra" "1")
407    (set_attr "mode" "V2SF")])
409 (define_insn "mmx_rsqit1v2sf3"
410   [(set (match_operand:V2SF 0 "register_operand" "=y")
411         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
412                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
413                      UNSPEC_PFRSQIT1))]
414   "TARGET_3DNOW"
415   "pfrsqit1\t{%2, %0|%0, %2}"
416   [(set_attr "type" "mmx")
417    (set_attr "prefix_extra" "1")
418    (set_attr "mode" "V2SF")])
420 (define_insn "mmx_haddv2sf3"
421   [(set (match_operand:V2SF 0 "register_operand" "=y")
422         (vec_concat:V2SF
423           (plus:SF
424             (vec_select:SF
425               (match_operand:V2SF 1 "register_operand" "0")
426               (parallel [(const_int  0)]))
427             (vec_select:SF (match_dup 1) (parallel [(const_int 1)])))
428           (plus:SF
429             (vec_select:SF
430               (match_operand:V2SF 2 "nonimmediate_operand" "ym")
431               (parallel [(const_int  0)]))
432             (vec_select:SF (match_dup 2) (parallel [(const_int 1)])))))]
433   "TARGET_3DNOW"
434   "pfacc\t{%2, %0|%0, %2}"
435   [(set_attr "type" "mmxadd")
436    (set_attr "prefix_extra" "1")
437    (set_attr "mode" "V2SF")])
439 (define_insn "mmx_hsubv2sf3"
440   [(set (match_operand:V2SF 0 "register_operand" "=y")
441         (vec_concat:V2SF
442           (minus:SF
443             (vec_select:SF
444               (match_operand:V2SF 1 "register_operand" "0")
445               (parallel [(const_int  0)]))
446             (vec_select:SF (match_dup 1) (parallel [(const_int 1)])))
447           (minus:SF
448             (vec_select:SF
449               (match_operand:V2SF 2 "nonimmediate_operand" "ym")
450               (parallel [(const_int  0)]))
451             (vec_select:SF (match_dup 2) (parallel [(const_int 1)])))))]
452   "TARGET_3DNOW_A"
453   "pfnacc\t{%2, %0|%0, %2}"
454   [(set_attr "type" "mmxadd")
455    (set_attr "prefix_extra" "1")
456    (set_attr "mode" "V2SF")])
458 (define_insn "mmx_addsubv2sf3"
459   [(set (match_operand:V2SF 0 "register_operand" "=y")
460         (vec_merge:V2SF
461           (plus:V2SF
462             (match_operand:V2SF 1 "register_operand" "0")
463             (match_operand:V2SF 2 "nonimmediate_operand" "ym"))
464           (minus:V2SF (match_dup 1) (match_dup 2))
465           (const_int 1)))]
466   "TARGET_3DNOW_A"
467   "pfpnacc\t{%2, %0|%0, %2}"
468   [(set_attr "type" "mmxadd")
469    (set_attr "prefix_extra" "1")
470    (set_attr "mode" "V2SF")])
472 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
474 ;; Parallel single-precision floating point comparisons
476 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
478 (define_expand "mmx_eqv2sf3"
479   [(set (match_operand:V2SI 0 "register_operand")
480         (eq:V2SI (match_operand:V2SF 1 "nonimmediate_operand")
481                  (match_operand:V2SF 2 "nonimmediate_operand")))]
482   "TARGET_3DNOW"
483   "ix86_fixup_binary_operands_no_copy (EQ, V2SFmode, operands);")
485 (define_insn "*mmx_eqv2sf3"
486   [(set (match_operand:V2SI 0 "register_operand" "=y")
487         (eq:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "%0")
488                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
489   "TARGET_3DNOW && ix86_binary_operator_ok (EQ, V2SFmode, operands)"
490   "pfcmpeq\t{%2, %0|%0, %2}"
491   [(set_attr "type" "mmxcmp")
492    (set_attr "prefix_extra" "1")
493    (set_attr "mode" "V2SF")])
495 (define_insn "mmx_gtv2sf3"
496   [(set (match_operand:V2SI 0 "register_operand" "=y")
497         (gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
498                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
499   "TARGET_3DNOW"
500   "pfcmpgt\t{%2, %0|%0, %2}"
501   [(set_attr "type" "mmxcmp")
502    (set_attr "prefix_extra" "1")
503    (set_attr "mode" "V2SF")])
505 (define_insn "mmx_gev2sf3"
506   [(set (match_operand:V2SI 0 "register_operand" "=y")
507         (ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
508                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
509   "TARGET_3DNOW"
510   "pfcmpge\t{%2, %0|%0, %2}"
511   [(set_attr "type" "mmxcmp")
512    (set_attr "prefix_extra" "1")
513    (set_attr "mode" "V2SF")])
515 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
517 ;; Parallel single-precision floating point conversion operations
519 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
521 (define_insn "mmx_pf2id"
522   [(set (match_operand:V2SI 0 "register_operand" "=y")
523         (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
524   "TARGET_3DNOW"
525   "pf2id\t{%1, %0|%0, %1}"
526   [(set_attr "type" "mmxcvt")
527    (set_attr "prefix_extra" "1")
528    (set_attr "mode" "V2SF")])
530 (define_insn "mmx_pf2iw"
531   [(set (match_operand:V2SI 0 "register_operand" "=y")
532         (sign_extend:V2SI
533           (ss_truncate:V2HI
534             (fix:V2SI
535               (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
536   "TARGET_3DNOW_A"
537   "pf2iw\t{%1, %0|%0, %1}"
538   [(set_attr "type" "mmxcvt")
539    (set_attr "prefix_extra" "1")
540    (set_attr "mode" "V2SF")])
542 (define_insn "mmx_pi2fw"
543   [(set (match_operand:V2SF 0 "register_operand" "=y")
544         (float:V2SF
545           (sign_extend:V2SI
546             (truncate:V2HI
547               (match_operand:V2SI 1 "nonimmediate_operand" "ym")))))]
548   "TARGET_3DNOW_A"
549   "pi2fw\t{%1, %0|%0, %1}"
550   [(set_attr "type" "mmxcvt")
551    (set_attr "prefix_extra" "1")
552    (set_attr "mode" "V2SF")])
554 (define_insn "mmx_floatv2si2"
555   [(set (match_operand:V2SF 0 "register_operand" "=y")
556         (float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
557   "TARGET_3DNOW"
558   "pi2fd\t{%1, %0|%0, %1}"
559   [(set_attr "type" "mmxcvt")
560    (set_attr "prefix_extra" "1")
561    (set_attr "mode" "V2SF")])
563 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
565 ;; Parallel single-precision floating point element swizzling
567 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
569 (define_insn "mmx_pswapdv2sf2"
570   [(set (match_operand:V2SF 0 "register_operand" "=y")
571         (vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym")
572                          (parallel [(const_int 1) (const_int 0)])))]
573   "TARGET_3DNOW_A"
574   "pswapd\t{%1, %0|%0, %1}"
575   [(set_attr "type" "mmxcvt")
576    (set_attr "prefix_extra" "1")
577    (set_attr "mode" "V2SF")])
579 (define_insn "*vec_dupv2sf"
580   [(set (match_operand:V2SF 0 "register_operand" "=y")
581         (vec_duplicate:V2SF
582           (match_operand:SF 1 "register_operand" "0")))]
583   "TARGET_MMX"
584   "punpckldq\t%0, %0"
585   [(set_attr "type" "mmxcvt")
586    (set_attr "mode" "DI")])
588 (define_insn "*mmx_concatv2sf"
589   [(set (match_operand:V2SF 0 "register_operand"     "=y,y")
590         (vec_concat:V2SF
591           (match_operand:SF 1 "nonimmediate_operand" " 0,rm")
592           (match_operand:SF 2 "nonimm_or_0_operand"  "ym,C")))]
593   "TARGET_MMX && !TARGET_SSE"
594   "@
595    punpckldq\t{%2, %0|%0, %2}
596    movd\t{%1, %0|%0, %1}"
597   [(set_attr "type" "mmxcvt,mmxmov")
598    (set_attr "mode" "DI")])
600 (define_expand "vec_setv2sf"
601   [(match_operand:V2SF 0 "register_operand")
602    (match_operand:SF 1 "register_operand")
603    (match_operand 2 "const_int_operand")]
604   "TARGET_MMX"
606   ix86_expand_vector_set (false, operands[0], operands[1],
607                           INTVAL (operands[2]));
608   DONE;
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_and_split "*vec_extractv2sf_0"
614   [(set (match_operand:SF 0 "nonimmediate_operand"     "=x, m,y ,m,f,r")
615         (vec_select:SF
616           (match_operand:V2SF 1 "nonimmediate_operand" " xm,x,ym,y,m,m")
617           (parallel [(const_int 0)])))]
618   "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
619   "#"
620   "&& reload_completed"
621   [(set (match_dup 0) (match_dup 1))]
622   "operands[1] = gen_lowpart (SFmode, operands[1]);")
624 ;; Avoid combining registers from different units in a single alternative,
625 ;; see comment above inline_secondary_memory_needed function in i386.c
626 (define_insn "*vec_extractv2sf_1"
627   [(set (match_operand:SF 0 "nonimmediate_operand"     "=y,x,x,y,x,f,r")
628         (vec_select:SF
629           (match_operand:V2SF 1 "nonimmediate_operand" " 0,x,x,o,o,o,o")
630           (parallel [(const_int 1)])))]
631   "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
632   "@
633    punpckhdq\t%0, %0
634    %vmovshdup\t{%1, %0|%0, %1}
635    shufps\t{$0xe5, %1, %0|%0, %1, 0xe5}
636    #
637    #
638    #
639    #"
640   [(set_attr "isa" "*,sse3,noavx,*,*,*,*")
641    (set_attr "type" "mmxcvt,sse,sseshuf1,mmxmov,ssemov,fmov,imov")
642    (set (attr "length_immediate")
643      (if_then_else (eq_attr "alternative" "2")
644                    (const_string "1")
645                    (const_string "*")))
646    (set (attr "prefix_rep")
647      (if_then_else (eq_attr "alternative" "1")
648                    (const_string "1")
649                    (const_string "*")))
650    (set_attr "prefix" "orig,maybe_vex,orig,orig,orig,orig,orig")
651    (set_attr "mode" "DI,V4SF,V4SF,SF,SF,SF,SF")])
653 (define_split
654   [(set (match_operand:SF 0 "register_operand")
655         (vec_select:SF
656           (match_operand:V2SF 1 "memory_operand")
657           (parallel [(const_int 1)])))]
658   "TARGET_MMX && reload_completed"
659   [(set (match_dup 0) (match_dup 1))]
660   "operands[1] = adjust_address (operands[1], SFmode, 4);")
662 (define_expand "vec_extractv2sfsf"
663   [(match_operand:SF 0 "register_operand")
664    (match_operand:V2SF 1 "register_operand")
665    (match_operand 2 "const_int_operand")]
666   "TARGET_MMX"
668   ix86_expand_vector_extract (false, operands[0], operands[1],
669                               INTVAL (operands[2]));
670   DONE;
673 (define_expand "vec_initv2sfsf"
674   [(match_operand:V2SF 0 "register_operand")
675    (match_operand 1)]
676   "TARGET_SSE"
678   ix86_expand_vector_init (false, operands[0], operands[1]);
679   DONE;
682 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
684 ;; Parallel integral arithmetic
686 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
688 (define_expand "mmx_<plusminus_insn><mode>3"
689   [(set (match_operand:MMXMODEI8 0 "register_operand")
690         (plusminus:MMXMODEI8
691           (match_operand:MMXMODEI8 1 "nonimmediate_operand")
692           (match_operand:MMXMODEI8 2 "nonimmediate_operand")))]
693   "TARGET_MMX || (TARGET_SSE2 && <MODE>mode == V1DImode)"
694   "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
696 (define_insn "*mmx_<plusminus_insn><mode>3"
697   [(set (match_operand:MMXMODEI8 0 "register_operand" "=y")
698         (plusminus:MMXMODEI8
699           (match_operand:MMXMODEI8 1 "nonimmediate_operand" "<comm>0")
700           (match_operand:MMXMODEI8 2 "nonimmediate_operand" "ym")))]
701   "(TARGET_MMX || (TARGET_SSE2 && <MODE>mode == V1DImode))
702    && 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_<plusminus_insn><mode>3"
708   [(set (match_operand:MMXMODE12 0 "register_operand")
709         (sat_plusminus:MMXMODE12
710           (match_operand:MMXMODE12 1 "nonimmediate_operand")
711           (match_operand:MMXMODE12 2 "nonimmediate_operand")))]
712   "TARGET_MMX"
713   "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
715 (define_insn "*mmx_<plusminus_insn><mode>3"
716   [(set (match_operand:MMXMODE12 0 "register_operand" "=y")
717         (sat_plusminus:MMXMODE12
718           (match_operand:MMXMODE12 1 "nonimmediate_operand" "<comm>0")
719           (match_operand:MMXMODE12 2 "nonimmediate_operand" "ym")))]
720   "TARGET_MMX && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
721   "p<plusminus_mnemonic><mmxvecsize>\t{%2, %0|%0, %2}"
722   [(set_attr "type" "mmxadd")
723    (set_attr "mode" "DI")])
725 (define_expand "mmx_mulv4hi3"
726   [(set (match_operand:V4HI 0 "register_operand")
727         (mult:V4HI (match_operand:V4HI 1 "nonimmediate_operand")
728                    (match_operand:V4HI 2 "nonimmediate_operand")))]
729   "TARGET_MMX"
730   "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
732 (define_insn "*mmx_mulv4hi3"
733   [(set (match_operand:V4HI 0 "register_operand" "=y")
734         (mult:V4HI (match_operand:V4HI 1 "nonimmediate_operand" "%0")
735                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
736   "TARGET_MMX && ix86_binary_operator_ok (MULT, V4HImode, operands)"
737   "pmullw\t{%2, %0|%0, %2}"
738   [(set_attr "type" "mmxmul")
739    (set_attr "mode" "DI")])
741 (define_expand "mmx_smulv4hi3_highpart"
742   [(set (match_operand:V4HI 0 "register_operand")
743         (truncate:V4HI
744           (lshiftrt:V4SI
745             (mult:V4SI
746               (sign_extend:V4SI
747                 (match_operand:V4HI 1 "nonimmediate_operand"))
748               (sign_extend:V4SI
749                 (match_operand:V4HI 2 "nonimmediate_operand")))
750             (const_int 16))))]
751   "TARGET_MMX"
752   "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
754 (define_insn "*mmx_smulv4hi3_highpart"
755   [(set (match_operand:V4HI 0 "register_operand" "=y")
756         (truncate:V4HI
757           (lshiftrt:V4SI
758             (mult:V4SI
759               (sign_extend:V4SI
760                 (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
761               (sign_extend:V4SI
762                 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
763             (const_int 16))))]
764   "TARGET_MMX && ix86_binary_operator_ok (MULT, V4HImode, operands)"
765   "pmulhw\t{%2, %0|%0, %2}"
766   [(set_attr "type" "mmxmul")
767    (set_attr "mode" "DI")])
769 (define_expand "mmx_umulv4hi3_highpart"
770   [(set (match_operand:V4HI 0 "register_operand")
771         (truncate:V4HI
772           (lshiftrt:V4SI
773             (mult:V4SI
774               (zero_extend:V4SI
775                 (match_operand:V4HI 1 "nonimmediate_operand"))
776               (zero_extend:V4SI
777                 (match_operand:V4HI 2 "nonimmediate_operand")))
778             (const_int 16))))]
779   "TARGET_SSE || TARGET_3DNOW_A"
780   "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
782 (define_insn "*mmx_umulv4hi3_highpart"
783   [(set (match_operand:V4HI 0 "register_operand" "=y")
784         (truncate:V4HI
785           (lshiftrt:V4SI
786             (mult:V4SI
787               (zero_extend:V4SI
788                 (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
789               (zero_extend:V4SI
790                 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
791           (const_int 16))))]
792   "(TARGET_SSE || TARGET_3DNOW_A)
793    && ix86_binary_operator_ok (MULT, V4HImode, operands)"
794   "pmulhuw\t{%2, %0|%0, %2}"
795   [(set_attr "type" "mmxmul")
796    (set_attr "mode" "DI")])
798 (define_expand "mmx_pmaddwd"
799   [(set (match_operand:V2SI 0 "register_operand")
800         (plus:V2SI
801           (mult:V2SI
802             (sign_extend:V2SI
803               (vec_select:V2HI
804                 (match_operand:V4HI 1 "nonimmediate_operand")
805                 (parallel [(const_int 0) (const_int 2)])))
806             (sign_extend:V2SI
807               (vec_select:V2HI
808                 (match_operand:V4HI 2 "nonimmediate_operand")
809                 (parallel [(const_int 0) (const_int 2)]))))
810           (mult:V2SI
811             (sign_extend:V2SI
812               (vec_select:V2HI (match_dup 1)
813                 (parallel [(const_int 1) (const_int 3)])))
814             (sign_extend:V2SI
815               (vec_select:V2HI (match_dup 2)
816                 (parallel [(const_int 1) (const_int 3)]))))))]
817   "TARGET_MMX"
818   "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
820 (define_insn "*mmx_pmaddwd"
821   [(set (match_operand:V2SI 0 "register_operand" "=y")
822         (plus:V2SI
823           (mult:V2SI
824             (sign_extend:V2SI
825               (vec_select:V2HI
826                 (match_operand:V4HI 1 "nonimmediate_operand" "%0")
827                 (parallel [(const_int 0) (const_int 2)])))
828             (sign_extend:V2SI
829               (vec_select:V2HI
830                 (match_operand:V4HI 2 "nonimmediate_operand" "ym")
831                 (parallel [(const_int 0) (const_int 2)]))))
832           (mult:V2SI
833             (sign_extend:V2SI
834               (vec_select:V2HI (match_dup 1)
835                 (parallel [(const_int 1) (const_int 3)])))
836             (sign_extend:V2SI
837               (vec_select:V2HI (match_dup 2)
838                 (parallel [(const_int 1) (const_int 3)]))))))]
839   "TARGET_MMX && ix86_binary_operator_ok (MULT, V4HImode, operands)"
840   "pmaddwd\t{%2, %0|%0, %2}"
841   [(set_attr "type" "mmxmul")
842    (set_attr "mode" "DI")])
844 (define_expand "mmx_pmulhrwv4hi3"
845   [(set (match_operand:V4HI 0 "register_operand")
846         (truncate:V4HI
847           (lshiftrt:V4SI
848             (plus:V4SI
849               (mult:V4SI
850                 (sign_extend:V4SI
851                   (match_operand:V4HI 1 "nonimmediate_operand"))
852                 (sign_extend:V4SI
853                   (match_operand:V4HI 2 "nonimmediate_operand")))
854               (const_vector:V4SI [(const_int 32768) (const_int 32768)
855                                   (const_int 32768) (const_int 32768)]))
856             (const_int 16))))]
857   "TARGET_3DNOW"
858   "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
860 (define_insn "*mmx_pmulhrwv4hi3"
861   [(set (match_operand:V4HI 0 "register_operand" "=y")
862         (truncate:V4HI
863           (lshiftrt:V4SI
864             (plus:V4SI
865               (mult:V4SI
866                 (sign_extend:V4SI
867                   (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
868                 (sign_extend:V4SI
869                   (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
870               (const_vector:V4SI [(const_int 32768) (const_int 32768)
871                                   (const_int 32768) (const_int 32768)]))
872             (const_int 16))))]
873   "TARGET_3DNOW && ix86_binary_operator_ok (MULT, V4HImode, operands)"
874   "pmulhrw\t{%2, %0|%0, %2}"
875   [(set_attr "type" "mmxmul")
876    (set_attr "prefix_extra" "1")
877    (set_attr "mode" "DI")])
879 (define_expand "sse2_umulv1siv1di3"
880   [(set (match_operand:V1DI 0 "register_operand")
881         (mult:V1DI
882           (zero_extend:V1DI
883             (vec_select:V1SI
884               (match_operand:V2SI 1 "nonimmediate_operand")
885               (parallel [(const_int 0)])))
886           (zero_extend:V1DI
887             (vec_select:V1SI
888               (match_operand:V2SI 2 "nonimmediate_operand")
889               (parallel [(const_int 0)])))))]
890   "TARGET_SSE2"
891   "ix86_fixup_binary_operands_no_copy (MULT, V2SImode, operands);")
893 (define_insn "*sse2_umulv1siv1di3"
894   [(set (match_operand:V1DI 0 "register_operand" "=y")
895         (mult:V1DI
896           (zero_extend:V1DI
897             (vec_select:V1SI
898               (match_operand:V2SI 1 "nonimmediate_operand" "%0")
899               (parallel [(const_int 0)])))
900           (zero_extend:V1DI
901             (vec_select:V1SI
902               (match_operand:V2SI 2 "nonimmediate_operand" "ym")
903               (parallel [(const_int 0)])))))]
904   "TARGET_SSE2 && ix86_binary_operator_ok (MULT, V2SImode, operands)"
905   "pmuludq\t{%2, %0|%0, %2}"
906   [(set_attr "type" "mmxmul")
907    (set_attr "mode" "DI")])
909 (define_expand "mmx_<code>v4hi3"
910   [(set (match_operand:V4HI 0 "register_operand")
911         (smaxmin:V4HI
912           (match_operand:V4HI 1 "nonimmediate_operand")
913           (match_operand:V4HI 2 "nonimmediate_operand")))]
914   "TARGET_SSE || TARGET_3DNOW_A"
915   "ix86_fixup_binary_operands_no_copy (<CODE>, V4HImode, operands);")
917 (define_insn "*mmx_<code>v4hi3"
918   [(set (match_operand:V4HI 0 "register_operand" "=y")
919         (smaxmin:V4HI
920           (match_operand:V4HI 1 "nonimmediate_operand" "%0")
921           (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
922   "(TARGET_SSE || TARGET_3DNOW_A)
923    && ix86_binary_operator_ok (<CODE>, V4HImode, operands)"
924   "p<maxmin_int>w\t{%2, %0|%0, %2}"
925   [(set_attr "type" "mmxadd")
926    (set_attr "mode" "DI")])
928 (define_expand "mmx_<code>v8qi3"
929   [(set (match_operand:V8QI 0 "register_operand")
930         (umaxmin:V8QI
931           (match_operand:V8QI 1 "nonimmediate_operand")
932           (match_operand:V8QI 2 "nonimmediate_operand")))]
933   "TARGET_SSE || TARGET_3DNOW_A"
934   "ix86_fixup_binary_operands_no_copy (<CODE>, V8QImode, operands);")
936 (define_insn "*mmx_<code>v8qi3"
937   [(set (match_operand:V8QI 0 "register_operand" "=y")
938         (umaxmin:V8QI
939           (match_operand:V8QI 1 "nonimmediate_operand" "%0")
940           (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
941   "(TARGET_SSE || TARGET_3DNOW_A)
942    && ix86_binary_operator_ok (<CODE>, V8QImode, operands)"
943   "p<maxmin_int>b\t{%2, %0|%0, %2}"
944   [(set_attr "type" "mmxadd")
945    (set_attr "mode" "DI")])
947 (define_insn "mmx_ashr<mode>3"
948   [(set (match_operand:MMXMODE24 0 "register_operand" "=y")
949         (ashiftrt:MMXMODE24
950           (match_operand:MMXMODE24 1 "register_operand" "0")
951           (match_operand:DI 2 "nonmemory_operand" "yN")))]
952   "TARGET_MMX"
953   "psra<mmxvecsize>\t{%2, %0|%0, %2}"
954   [(set_attr "type" "mmxshft")
955    (set (attr "length_immediate")
956      (if_then_else (match_operand 2 "const_int_operand")
957        (const_string "1")
958        (const_string "0")))
959    (set_attr "mode" "DI")])
961 (define_insn "mmx_<shift_insn><mode>3"
962   [(set (match_operand:MMXMODE248 0 "register_operand" "=y")
963         (any_lshift:MMXMODE248
964           (match_operand:MMXMODE248 1 "register_operand" "0")
965           (match_operand:DI 2 "nonmemory_operand" "yN")))]
966   "TARGET_MMX"
967   "p<vshift><mmxvecsize>\t{%2, %0|%0, %2}"
968   [(set_attr "type" "mmxshft")
969    (set (attr "length_immediate")
970      (if_then_else (match_operand 2 "const_int_operand")
971        (const_string "1")
972        (const_string "0")))
973    (set_attr "mode" "DI")])
975 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
977 ;; Parallel integral comparisons
979 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
981 (define_expand "mmx_eq<mode>3"
982   [(set (match_operand:MMXMODEI 0 "register_operand")
983         (eq:MMXMODEI
984           (match_operand:MMXMODEI 1 "nonimmediate_operand")
985           (match_operand:MMXMODEI 2 "nonimmediate_operand")))]
986   "TARGET_MMX"
987   "ix86_fixup_binary_operands_no_copy (EQ, <MODE>mode, operands);")
989 (define_insn "*mmx_eq<mode>3"
990   [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
991         (eq:MMXMODEI
992           (match_operand:MMXMODEI 1 "nonimmediate_operand" "%0")
993           (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
994   "TARGET_MMX && ix86_binary_operator_ok (EQ, <MODE>mode, operands)"
995   "pcmpeq<mmxvecsize>\t{%2, %0|%0, %2}"
996   [(set_attr "type" "mmxcmp")
997    (set_attr "mode" "DI")])
999 (define_insn "mmx_gt<mode>3"
1000   [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
1001         (gt:MMXMODEI
1002           (match_operand:MMXMODEI 1 "register_operand" "0")
1003           (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
1004   "TARGET_MMX"
1005   "pcmpgt<mmxvecsize>\t{%2, %0|%0, %2}"
1006   [(set_attr "type" "mmxcmp")
1007    (set_attr "mode" "DI")])
1009 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1011 ;; Parallel integral logical operations
1013 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1015 (define_insn "mmx_andnot<mode>3"
1016   [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
1017         (and:MMXMODEI
1018           (not:MMXMODEI (match_operand:MMXMODEI 1 "register_operand" "0"))
1019           (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
1020   "TARGET_MMX"
1021   "pandn\t{%2, %0|%0, %2}"
1022   [(set_attr "type" "mmxadd")
1023    (set_attr "mode" "DI")])
1025 (define_expand "mmx_<code><mode>3"
1026   [(set (match_operand:MMXMODEI 0 "register_operand")
1027         (any_logic:MMXMODEI
1028           (match_operand:MMXMODEI 1 "nonimmediate_operand")
1029           (match_operand:MMXMODEI 2 "nonimmediate_operand")))]
1030   "TARGET_MMX"
1031   "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
1033 (define_insn "*mmx_<code><mode>3"
1034   [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
1035         (any_logic:MMXMODEI
1036           (match_operand:MMXMODEI 1 "nonimmediate_operand" "%0")
1037           (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
1038   "TARGET_MMX && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
1039   "p<logic>\t{%2, %0|%0, %2}"
1040   [(set_attr "type" "mmxadd")
1041    (set_attr "mode" "DI")])
1043 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1045 ;; Parallel integral element swizzling
1047 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1049 (define_insn "mmx_packsswb"
1050   [(set (match_operand:V8QI 0 "register_operand" "=y")
1051         (vec_concat:V8QI
1052           (ss_truncate:V4QI
1053             (match_operand:V4HI 1 "register_operand" "0"))
1054           (ss_truncate:V4QI
1055             (match_operand:V4HI 2 "nonimmediate_operand" "ym"))))]
1056   "TARGET_MMX"
1057   "packsswb\t{%2, %0|%0, %2}"
1058   [(set_attr "type" "mmxshft")
1059    (set_attr "mode" "DI")])
1061 (define_insn "mmx_packssdw"
1062   [(set (match_operand:V4HI 0 "register_operand" "=y")
1063         (vec_concat:V4HI
1064           (ss_truncate:V2HI
1065             (match_operand:V2SI 1 "register_operand" "0"))
1066           (ss_truncate:V2HI
1067             (match_operand:V2SI 2 "nonimmediate_operand" "ym"))))]
1068   "TARGET_MMX"
1069   "packssdw\t{%2, %0|%0, %2}"
1070   [(set_attr "type" "mmxshft")
1071    (set_attr "mode" "DI")])
1073 (define_insn "mmx_packuswb"
1074   [(set (match_operand:V8QI 0 "register_operand" "=y")
1075         (vec_concat:V8QI
1076           (us_truncate:V4QI
1077             (match_operand:V4HI 1 "register_operand" "0"))
1078           (us_truncate:V4QI
1079             (match_operand:V4HI 2 "nonimmediate_operand" "ym"))))]
1080   "TARGET_MMX"
1081   "packuswb\t{%2, %0|%0, %2}"
1082   [(set_attr "type" "mmxshft")
1083    (set_attr "mode" "DI")])
1085 (define_insn "mmx_punpckhbw"
1086   [(set (match_operand:V8QI 0 "register_operand" "=y")
1087         (vec_select:V8QI
1088           (vec_concat:V16QI
1089             (match_operand:V8QI 1 "register_operand" "0")
1090             (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
1091           (parallel [(const_int 4) (const_int 12)
1092                      (const_int 5) (const_int 13)
1093                      (const_int 6) (const_int 14)
1094                      (const_int 7) (const_int 15)])))]
1095   "TARGET_MMX"
1096   "punpckhbw\t{%2, %0|%0, %2}"
1097   [(set_attr "type" "mmxcvt")
1098    (set_attr "mode" "DI")])
1100 (define_insn "mmx_punpcklbw"
1101   [(set (match_operand:V8QI 0 "register_operand" "=y")
1102         (vec_select:V8QI
1103           (vec_concat:V16QI
1104             (match_operand:V8QI 1 "register_operand" "0")
1105             (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
1106           (parallel [(const_int 0) (const_int 8)
1107                      (const_int 1) (const_int 9)
1108                      (const_int 2) (const_int 10)
1109                      (const_int 3) (const_int 11)])))]
1110   "TARGET_MMX"
1111   "punpcklbw\t{%2, %0|%0, %k2}"
1112   [(set_attr "type" "mmxcvt")
1113    (set_attr "mode" "DI")])
1115 (define_insn "mmx_punpckhwd"
1116   [(set (match_operand:V4HI 0 "register_operand" "=y")
1117         (vec_select:V4HI
1118           (vec_concat:V8HI
1119             (match_operand:V4HI 1 "register_operand" "0")
1120             (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
1121           (parallel [(const_int 2) (const_int 6)
1122                      (const_int 3) (const_int 7)])))]
1123   "TARGET_MMX"
1124   "punpckhwd\t{%2, %0|%0, %2}"
1125   [(set_attr "type" "mmxcvt")
1126    (set_attr "mode" "DI")])
1128 (define_insn "mmx_punpcklwd"
1129   [(set (match_operand:V4HI 0 "register_operand" "=y")
1130         (vec_select:V4HI
1131           (vec_concat:V8HI
1132             (match_operand:V4HI 1 "register_operand" "0")
1133             (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
1134           (parallel [(const_int 0) (const_int 4)
1135                      (const_int 1) (const_int 5)])))]
1136   "TARGET_MMX"
1137   "punpcklwd\t{%2, %0|%0, %k2}"
1138   [(set_attr "type" "mmxcvt")
1139    (set_attr "mode" "DI")])
1141 (define_insn "mmx_punpckhdq"
1142   [(set (match_operand:V2SI 0 "register_operand" "=y")
1143         (vec_select:V2SI
1144           (vec_concat:V4SI
1145             (match_operand:V2SI 1 "register_operand" "0")
1146             (match_operand:V2SI 2 "nonimmediate_operand" "ym"))
1147           (parallel [(const_int 1)
1148                      (const_int 3)])))]
1149   "TARGET_MMX"
1150   "punpckhdq\t{%2, %0|%0, %2}"
1151   [(set_attr "type" "mmxcvt")
1152    (set_attr "mode" "DI")])
1154 (define_insn "mmx_punpckldq"
1155   [(set (match_operand:V2SI 0 "register_operand" "=y")
1156         (vec_select:V2SI
1157           (vec_concat:V4SI
1158             (match_operand:V2SI 1 "register_operand" "0")
1159             (match_operand:V2SI 2 "nonimmediate_operand" "ym"))
1160           (parallel [(const_int 0)
1161                      (const_int 2)])))]
1162   "TARGET_MMX"
1163   "punpckldq\t{%2, %0|%0, %k2}"
1164   [(set_attr "type" "mmxcvt")
1165    (set_attr "mode" "DI")])
1167 (define_expand "mmx_pinsrw"
1168   [(set (match_operand:V4HI 0 "register_operand")
1169         (vec_merge:V4HI
1170           (vec_duplicate:V4HI
1171             (match_operand:SI 2 "nonimmediate_operand"))
1172           (match_operand:V4HI 1 "register_operand")
1173           (match_operand:SI 3 "const_0_to_3_operand")))]
1174   "TARGET_SSE || TARGET_3DNOW_A"
1176   operands[2] = gen_lowpart (HImode, operands[2]);
1177   operands[3] = GEN_INT (1 << INTVAL (operands[3]));
1180 (define_insn "*mmx_pinsrw"
1181   [(set (match_operand:V4HI 0 "register_operand" "=y")
1182         (vec_merge:V4HI
1183           (vec_duplicate:V4HI
1184             (match_operand:HI 2 "nonimmediate_operand" "rm"))
1185           (match_operand:V4HI 1 "register_operand" "0")
1186           (match_operand:SI 3 "const_int_operand")))]
1187   "(TARGET_SSE || TARGET_3DNOW_A)
1188    && ((unsigned) exact_log2 (INTVAL (operands[3]))
1189        < GET_MODE_NUNITS (V4HImode))"
1191   operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])));
1192   if (MEM_P (operands[2]))
1193     return "pinsrw\t{%3, %2, %0|%0, %2, %3}";
1194   else
1195     return "pinsrw\t{%3, %k2, %0|%0, %k2, %3}";
1197   [(set_attr "type" "mmxcvt")
1198    (set_attr "length_immediate" "1")
1199    (set_attr "mode" "DI")])
1201 (define_insn "mmx_pextrw"
1202   [(set (match_operand:SI 0 "register_operand" "=r")
1203         (zero_extend:SI
1204           (vec_select:HI
1205             (match_operand:V4HI 1 "register_operand" "y")
1206             (parallel [(match_operand:SI 2 "const_0_to_3_operand" "n")]))))]
1207   "TARGET_SSE || TARGET_3DNOW_A"
1208   "pextrw\t{%2, %1, %0|%0, %1, %2}"
1209   [(set_attr "type" "mmxcvt")
1210    (set_attr "length_immediate" "1")
1211    (set_attr "mode" "DI")])
1213 (define_expand "mmx_pshufw"
1214   [(match_operand:V4HI 0 "register_operand")
1215    (match_operand:V4HI 1 "nonimmediate_operand")
1216    (match_operand:SI 2 "const_int_operand")]
1217   "TARGET_SSE || TARGET_3DNOW_A"
1219   int mask = INTVAL (operands[2]);
1220   emit_insn (gen_mmx_pshufw_1 (operands[0], operands[1],
1221                                GEN_INT ((mask >> 0) & 3),
1222                                GEN_INT ((mask >> 2) & 3),
1223                                GEN_INT ((mask >> 4) & 3),
1224                                GEN_INT ((mask >> 6) & 3)));
1225   DONE;
1228 (define_insn "mmx_pshufw_1"
1229   [(set (match_operand:V4HI 0 "register_operand" "=y")
1230         (vec_select:V4HI
1231           (match_operand:V4HI 1 "nonimmediate_operand" "ym")
1232           (parallel [(match_operand 2 "const_0_to_3_operand")
1233                      (match_operand 3 "const_0_to_3_operand")
1234                      (match_operand 4 "const_0_to_3_operand")
1235                      (match_operand 5 "const_0_to_3_operand")])))]
1236   "TARGET_SSE || TARGET_3DNOW_A"
1238   int mask = 0;
1239   mask |= INTVAL (operands[2]) << 0;
1240   mask |= INTVAL (operands[3]) << 2;
1241   mask |= INTVAL (operands[4]) << 4;
1242   mask |= INTVAL (operands[5]) << 6;
1243   operands[2] = GEN_INT (mask);
1245   return "pshufw\t{%2, %1, %0|%0, %1, %2}";
1247   [(set_attr "type" "mmxcvt")
1248    (set_attr "length_immediate" "1")
1249    (set_attr "mode" "DI")])
1251 (define_insn "mmx_pswapdv2si2"
1252   [(set (match_operand:V2SI 0 "register_operand" "=y")
1253         (vec_select:V2SI
1254           (match_operand:V2SI 1 "nonimmediate_operand" "ym")
1255           (parallel [(const_int 1) (const_int 0)])))]
1256   "TARGET_3DNOW_A"
1257   "pswapd\t{%1, %0|%0, %1}"
1258   [(set_attr "type" "mmxcvt")
1259    (set_attr "prefix_extra" "1")
1260    (set_attr "mode" "DI")])
1262 (define_insn "*vec_dupv4hi"
1263   [(set (match_operand:V4HI 0 "register_operand" "=y")
1264         (vec_duplicate:V4HI
1265           (truncate:HI
1266             (match_operand:SI 1 "register_operand" "0"))))]
1267   "TARGET_SSE || TARGET_3DNOW_A"
1268   "pshufw\t{$0, %0, %0|%0, %0, 0}"
1269   [(set_attr "type" "mmxcvt")
1270    (set_attr "length_immediate" "1")
1271    (set_attr "mode" "DI")])
1273 (define_insn "*vec_dupv2si"
1274   [(set (match_operand:V2SI 0 "register_operand" "=y")
1275         (vec_duplicate:V2SI
1276           (match_operand:SI 1 "register_operand" "0")))]
1277   "TARGET_MMX"
1278   "punpckldq\t%0, %0"
1279   [(set_attr "type" "mmxcvt")
1280    (set_attr "mode" "DI")])
1282 (define_insn "*mmx_concatv2si"
1283   [(set (match_operand:V2SI 0 "register_operand"     "=y,y")
1284         (vec_concat:V2SI
1285           (match_operand:SI 1 "nonimmediate_operand" " 0,rm")
1286           (match_operand:SI 2 "nonimm_or_0_operand"  "ym,C")))]
1287   "TARGET_MMX && !TARGET_SSE"
1288   "@
1289    punpckldq\t{%2, %0|%0, %2}
1290    movd\t{%1, %0|%0, %1}"
1291   [(set_attr "type" "mmxcvt,mmxmov")
1292    (set_attr "mode" "DI")])
1294 (define_expand "vec_setv2si"
1295   [(match_operand:V2SI 0 "register_operand")
1296    (match_operand:SI 1 "register_operand")
1297    (match_operand 2 "const_int_operand")]
1298   "TARGET_MMX"
1300   ix86_expand_vector_set (false, operands[0], operands[1],
1301                           INTVAL (operands[2]));
1302   DONE;
1305 ;; Avoid combining registers from different units in a single alternative,
1306 ;; see comment above inline_secondary_memory_needed function in i386.c
1307 (define_insn_and_split "*vec_extractv2si_0"
1308   [(set (match_operand:SI 0 "nonimmediate_operand"     "=x,m,y, m,r")
1309         (vec_select:SI
1310           (match_operand:V2SI 1 "nonimmediate_operand" "xm,x,ym,y,m")
1311           (parallel [(const_int 0)])))]
1312   "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1313   "#"
1314   "&& reload_completed"
1315   [(set (match_dup 0) (match_dup 1))]
1316   "operands[1] = gen_lowpart (SImode, operands[1]);")
1318 ;; Avoid combining registers from different units in a single alternative,
1319 ;; see comment above inline_secondary_memory_needed function in i386.c
1320 (define_insn "*vec_extractv2si_1"
1321   [(set (match_operand:SI 0 "nonimmediate_operand"     "=y,x,x,y,x,r")
1322         (vec_select:SI
1323           (match_operand:V2SI 1 "nonimmediate_operand" " 0,x,x,o,o,o")
1324           (parallel [(const_int 1)])))]
1325   "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1326   "@
1327    punpckhdq\t%0, %0
1328    %vpshufd\t{$0xe5, %1, %0|%0, %1, 0xe5}
1329    shufps\t{$0xe5, %1, %0|%0, %1, 0xe5}
1330    #
1331    #
1332    #"
1333   [(set_attr "isa" "*,sse2,noavx,*,*,*")
1334    (set_attr "type" "mmxcvt,sseshuf1,sseshuf1,mmxmov,ssemov,imov")
1335    (set (attr "length_immediate")
1336      (if_then_else (eq_attr "alternative" "1,2")
1337                    (const_string "1")
1338                    (const_string "*")))
1339    (set_attr "prefix" "orig,maybe_vex,orig,orig,orig,orig")
1340    (set_attr "mode" "DI,TI,V4SF,SI,SI,SI")])
1342 (define_split
1343   [(set (match_operand:SI 0 "register_operand")
1344         (vec_select:SI
1345           (match_operand:V2SI 1 "memory_operand")
1346           (parallel [(const_int 1)])))]
1347   "TARGET_MMX && reload_completed"
1348   [(set (match_dup 0) (match_dup 1))]
1349   "operands[1] = adjust_address (operands[1], SImode, 4);")
1351 (define_insn_and_split "*vec_extractv2si_zext_mem"
1352   [(set (match_operand:DI 0 "register_operand" "=y,x,r")
1353         (zero_extend:DI
1354           (vec_select:SI
1355             (match_operand:V2SI 1 "memory_operand" "o,o,o")
1356             (parallel [(match_operand:SI 2 "const_0_to_1_operand")]))))]
1357   "TARGET_64BIT && TARGET_MMX"
1358   "#"
1359   "&& reload_completed"
1360   [(set (match_dup 0) (zero_extend:DI (match_dup 1)))]
1362   operands[1] = adjust_address (operands[1], SImode, INTVAL (operands[2]) * 4);
1365 (define_expand "vec_extractv2sisi"
1366   [(match_operand:SI 0 "register_operand")
1367    (match_operand:V2SI 1 "register_operand")
1368    (match_operand 2 "const_int_operand")]
1369   "TARGET_MMX"
1371   ix86_expand_vector_extract (false, operands[0], operands[1],
1372                               INTVAL (operands[2]));
1373   DONE;
1376 (define_expand "vec_initv2sisi"
1377   [(match_operand:V2SI 0 "register_operand")
1378    (match_operand 1)]
1379   "TARGET_SSE"
1381   ix86_expand_vector_init (false, operands[0], operands[1]);
1382   DONE;
1385 (define_expand "vec_setv4hi"
1386   [(match_operand:V4HI 0 "register_operand")
1387    (match_operand:HI 1 "register_operand")
1388    (match_operand 2 "const_int_operand")]
1389   "TARGET_MMX"
1391   ix86_expand_vector_set (false, operands[0], operands[1],
1392                           INTVAL (operands[2]));
1393   DONE;
1396 (define_expand "vec_extractv4hihi"
1397   [(match_operand:HI 0 "register_operand")
1398    (match_operand:V4HI 1 "register_operand")
1399    (match_operand 2 "const_int_operand")]
1400   "TARGET_MMX"
1402   ix86_expand_vector_extract (false, operands[0], operands[1],
1403                               INTVAL (operands[2]));
1404   DONE;
1407 (define_expand "vec_initv4hihi"
1408   [(match_operand:V4HI 0 "register_operand")
1409    (match_operand 1)]
1410   "TARGET_SSE"
1412   ix86_expand_vector_init (false, operands[0], operands[1]);
1413   DONE;
1416 (define_expand "vec_setv8qi"
1417   [(match_operand:V8QI 0 "register_operand")
1418    (match_operand:QI 1 "register_operand")
1419    (match_operand 2 "const_int_operand")]
1420   "TARGET_MMX"
1422   ix86_expand_vector_set (false, operands[0], operands[1],
1423                           INTVAL (operands[2]));
1424   DONE;
1427 (define_expand "vec_extractv8qiqi"
1428   [(match_operand:QI 0 "register_operand")
1429    (match_operand:V8QI 1 "register_operand")
1430    (match_operand 2 "const_int_operand")]
1431   "TARGET_MMX"
1433   ix86_expand_vector_extract (false, operands[0], operands[1],
1434                               INTVAL (operands[2]));
1435   DONE;
1438 (define_expand "vec_initv8qiqi"
1439   [(match_operand:V8QI 0 "register_operand")
1440    (match_operand 1)]
1441   "TARGET_SSE"
1443   ix86_expand_vector_init (false, operands[0], operands[1]);
1444   DONE;
1447 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1449 ;; Miscellaneous
1451 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1453 (define_expand "mmx_uavgv8qi3"
1454   [(set (match_operand:V8QI 0 "register_operand")
1455         (truncate:V8QI
1456           (lshiftrt:V8HI
1457             (plus:V8HI
1458               (plus:V8HI
1459                 (zero_extend:V8HI
1460                   (match_operand:V8QI 1 "nonimmediate_operand"))
1461                 (zero_extend:V8HI
1462                   (match_operand:V8QI 2 "nonimmediate_operand")))
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_fixup_binary_operands_no_copy (PLUS, V8QImode, operands);")
1471 (define_insn "*mmx_uavgv8qi3"
1472   [(set (match_operand:V8QI 0 "register_operand" "=y")
1473         (truncate:V8QI
1474           (lshiftrt:V8HI
1475             (plus:V8HI
1476               (plus:V8HI
1477                 (zero_extend:V8HI
1478                   (match_operand:V8QI 1 "nonimmediate_operand" "%0"))
1479                 (zero_extend:V8HI
1480                   (match_operand:V8QI 2 "nonimmediate_operand" "ym")))
1481               (const_vector:V8HI [(const_int 1) (const_int 1)
1482                                   (const_int 1) (const_int 1)
1483                                   (const_int 1) (const_int 1)
1484                                   (const_int 1) (const_int 1)]))
1485             (const_int 1))))]
1486   "(TARGET_SSE || TARGET_3DNOW)
1487    && ix86_binary_operator_ok (PLUS, V8QImode, operands)"
1489   /* These two instructions have the same operation, but their encoding
1490      is different.  Prefer the one that is de facto standard.  */
1491   if (TARGET_SSE || TARGET_3DNOW_A)
1492     return "pavgb\t{%2, %0|%0, %2}";
1493   else
1494     return "pavgusb\t{%2, %0|%0, %2}";
1496   [(set_attr "type" "mmxshft")
1497    (set (attr "prefix_extra")
1498      (if_then_else
1499        (not (ior (match_test "TARGET_SSE")
1500                  (match_test "TARGET_3DNOW_A")))
1501        (const_string "1")
1502        (const_string "*")))
1503    (set_attr "mode" "DI")])
1505 (define_expand "mmx_uavgv4hi3"
1506   [(set (match_operand:V4HI 0 "register_operand")
1507         (truncate:V4HI
1508           (lshiftrt:V4SI
1509             (plus:V4SI
1510               (plus:V4SI
1511                 (zero_extend:V4SI
1512                   (match_operand:V4HI 1 "nonimmediate_operand"))
1513                 (zero_extend:V4SI
1514                   (match_operand:V4HI 2 "nonimmediate_operand")))
1515               (const_vector:V4SI [(const_int 1) (const_int 1)
1516                                   (const_int 1) (const_int 1)]))
1517             (const_int 1))))]
1518   "TARGET_SSE || TARGET_3DNOW_A"
1519   "ix86_fixup_binary_operands_no_copy (PLUS, V4HImode, operands);")
1521 (define_insn "*mmx_uavgv4hi3"
1522   [(set (match_operand:V4HI 0 "register_operand" "=y")
1523         (truncate:V4HI
1524           (lshiftrt:V4SI
1525             (plus:V4SI
1526               (plus:V4SI
1527                 (zero_extend:V4SI
1528                   (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
1529                 (zero_extend:V4SI
1530                   (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
1531               (const_vector:V4SI [(const_int 1) (const_int 1)
1532                                   (const_int 1) (const_int 1)]))
1533             (const_int 1))))]
1534   "(TARGET_SSE || TARGET_3DNOW_A)
1535    && ix86_binary_operator_ok (PLUS, V4HImode, operands)"
1536   "pavgw\t{%2, %0|%0, %2}"
1537   [(set_attr "type" "mmxshft")
1538    (set_attr "mode" "DI")])
1540 (define_insn "mmx_psadbw"
1541   [(set (match_operand:V1DI 0 "register_operand" "=y")
1542         (unspec:V1DI [(match_operand:V8QI 1 "register_operand" "0")
1543                       (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
1544                      UNSPEC_PSADBW))]
1545   "TARGET_SSE || TARGET_3DNOW_A"
1546   "psadbw\t{%2, %0|%0, %2}"
1547   [(set_attr "type" "mmxshft")
1548    (set_attr "mode" "DI")])
1550 (define_insn "mmx_pmovmskb"
1551   [(set (match_operand:SI 0 "register_operand" "=r")
1552         (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")]
1553                    UNSPEC_MOVMSK))]
1554   "TARGET_SSE || TARGET_3DNOW_A"
1555   "pmovmskb\t{%1, %0|%0, %1}"
1556   [(set_attr "type" "mmxcvt")
1557    (set_attr "mode" "DI")])
1559 (define_expand "mmx_maskmovq"
1560   [(set (match_operand:V8QI 0 "memory_operand")
1561         (unspec:V8QI [(match_operand:V8QI 1 "register_operand")
1562                       (match_operand:V8QI 2 "register_operand")
1563                       (match_dup 0)]
1564                      UNSPEC_MASKMOV))]
1565   "TARGET_SSE || TARGET_3DNOW_A")
1567 (define_insn "*mmx_maskmovq"
1568   [(set (mem:V8QI (match_operand:P 0 "register_operand" "D"))
1569         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
1570                       (match_operand:V8QI 2 "register_operand" "y")
1571                       (mem:V8QI (match_dup 0))]
1572                      UNSPEC_MASKMOV))]
1573   "TARGET_SSE || TARGET_3DNOW_A"
1574   ;; @@@ check ordering of operands in intel/nonintel syntax
1575   "maskmovq\t{%2, %1|%1, %2}"
1576   [(set_attr "type" "mmxcvt")
1577    (set_attr "znver1_decode" "vector")
1578    (set_attr "mode" "DI")])
1580 (define_int_iterator EMMS
1581   [(UNSPECV_EMMS "TARGET_MMX")
1582    (UNSPECV_FEMMS "TARGET_3DNOW")])
1584 (define_int_attr emms
1585   [(UNSPECV_EMMS "emms")
1586    (UNSPECV_FEMMS "femms")])
1588 (define_insn "mmx_<emms>"
1589   [(unspec_volatile [(const_int 0)] EMMS)
1590    (clobber (reg:XF ST0_REG))
1591    (clobber (reg:XF ST1_REG))
1592    (clobber (reg:XF ST2_REG))
1593    (clobber (reg:XF ST3_REG))
1594    (clobber (reg:XF ST4_REG))
1595    (clobber (reg:XF ST5_REG))
1596    (clobber (reg:XF ST6_REG))
1597    (clobber (reg:XF ST7_REG))
1598    (clobber (reg:DI MM0_REG))
1599    (clobber (reg:DI MM1_REG))
1600    (clobber (reg:DI MM2_REG))
1601    (clobber (reg:DI MM3_REG))
1602    (clobber (reg:DI MM4_REG))
1603    (clobber (reg:DI MM5_REG))
1604    (clobber (reg:DI MM6_REG))
1605    (clobber (reg:DI MM7_REG))]
1606   ""
1607   "<emms>"
1608   [(set_attr "type" "mmx")
1609    (set_attr "modrm" "0")
1610    (set_attr "memory" "none")])