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