1;; GCC machine description for MMX and 3dNOW! instructions
2;; Copyright (C) 2005-2015 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.
10;;
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.
15;;
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/>.
19
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.
23
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.
31
32(define_c_enum "unspec" [
33  UNSPEC_MOVNTQ
34  UNSPEC_PFRCP
35  UNSPEC_PFRCPIT1
36  UNSPEC_PFRCPIT2
37  UNSPEC_PFRSQRT
38  UNSPEC_PFRSQIT1
39])
40
41(define_c_enum "unspecv" [
42  UNSPECV_EMMS
43  UNSPECV_FEMMS
44])
45
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])
49
50;; All 8-byte vector modes handled by MMX
51(define_mode_iterator MMXMODE [V8QI V4HI V2SI V1DI V2SF])
52
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])
57
58;; Mapping from integer vector mode to mnemonic suffix
59(define_mode_attr mmxvecsize [(V8QI "b") (V4HI "w") (V2SI "d") (V1DI "q")])
60
61;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
62;;
63;; Move patterns
64;;
65;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
66
67;; All of these patterns are enabled for MMX as well as 3dNOW.
68;; This is essential for maintaining stable calling conventions.
69
70(define_expand "mov<mode>"
71  [(set (match_operand:MMXMODE 0 "nonimmediate_operand")
72	(match_operand:MMXMODE 1 "nonimmediate_operand"))]
73  "TARGET_MMX"
74{
75  ix86_expand_vector_move (<MODE>mode, operands);
76  DONE;
77})
78
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]))"
86{
87  switch (get_attr_type (insn))
88    {
89    case TYPE_MULTI:
90      return "#";
91
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}";
97
98    case TYPE_MMX:
99      return "pxor\t%0, %0";
100
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}";
107
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}";
113
114    case TYPE_SSELOG1:
115      return standard_sse_constant_opcode (insn, operands[1]);
116
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}";
130
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}";
137
138	default:
139	  gcc_unreachable ();
140	}
141
142    default:
143      gcc_unreachable ();
144    }
145}
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"))
199
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")))])
206
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;")
215
216(define_expand "movmisalign<mode>"
217  [(set (match_operand:MMXMODE 0 "nonimmediate_operand")
218	(match_operand:MMXMODE 1 "nonimmediate_operand"))]
219  "TARGET_MMX"
220{
221  ix86_expand_vector_move (<MODE>mode, operands);
222  DONE;
223})
224
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")])
233
234;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
235;;
236;; Parallel single-precision floating point arithmetic
237;;
238;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
239
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);")
247
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")])
257
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")
263
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")
269
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")])
281
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);")
288
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")])
298
299;; ??? For !flag_finite_math_only, the representation with SMIN/SMAX
300;; isn't really correct, as those rtl operators aren't defined when
301;; applied to NaNs.  Hopefully the optimizers won't get too smart on us.
302
303(define_expand "mmx_<code>v2sf3"
304  [(set (match_operand:V2SF 0 "register_operand")
305        (smaxmin:V2SF
306	  (match_operand:V2SF 1 "nonimmediate_operand")
307	  (match_operand:V2SF 2 "nonimmediate_operand")))]
308  "TARGET_3DNOW"
309{
310  if (!flag_finite_math_only)
311    operands[1] = force_reg (V2SFmode, operands[1]);
312  ix86_fixup_binary_operands_no_copy (<CODE>, V2SFmode, operands);
313})
314
315(define_insn "*mmx_<code>v2sf3_finite"
316  [(set (match_operand:V2SF 0 "register_operand" "=y")
317        (smaxmin:V2SF
318	  (match_operand:V2SF 1 "nonimmediate_operand" "%0")
319	  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
320  "TARGET_3DNOW && flag_finite_math_only
321   && ix86_binary_operator_ok (<CODE>, V2SFmode, operands)"
322  "pf<maxmin_float>\t{%2, %0|%0, %2}"
323  [(set_attr "type" "mmxadd")
324   (set_attr "prefix_extra" "1")
325   (set_attr "mode" "V2SF")])
326
327(define_insn "*mmx_<code>v2sf3"
328  [(set (match_operand:V2SF 0 "register_operand" "=y")
329        (smaxmin:V2SF
330	  (match_operand:V2SF 1 "register_operand" "0")
331	  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
332  "TARGET_3DNOW"
333  "pf<maxmin_float>\t{%2, %0|%0, %2}"
334  [(set_attr "type" "mmxadd")
335   (set_attr "prefix_extra" "1")
336   (set_attr "mode" "V2SF")])
337
338(define_insn "mmx_rcpv2sf2"
339  [(set (match_operand:V2SF 0 "register_operand" "=y")
340        (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
341		     UNSPEC_PFRCP))]
342  "TARGET_3DNOW"
343  "pfrcp\t{%1, %0|%0, %1}"
344  [(set_attr "type" "mmx")
345   (set_attr "prefix_extra" "1")
346   (set_attr "mode" "V2SF")])
347
348(define_insn "mmx_rcpit1v2sf3"
349  [(set (match_operand:V2SF 0 "register_operand" "=y")
350	(unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
351		      (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
352		     UNSPEC_PFRCPIT1))]
353  "TARGET_3DNOW"
354  "pfrcpit1\t{%2, %0|%0, %2}"
355  [(set_attr "type" "mmx")
356   (set_attr "prefix_extra" "1")
357   (set_attr "mode" "V2SF")])
358
359(define_insn "mmx_rcpit2v2sf3"
360  [(set (match_operand:V2SF 0 "register_operand" "=y")
361	(unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
362		      (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
363		     UNSPEC_PFRCPIT2))]
364  "TARGET_3DNOW"
365  "pfrcpit2\t{%2, %0|%0, %2}"
366  [(set_attr "type" "mmx")
367   (set_attr "prefix_extra" "1")
368   (set_attr "mode" "V2SF")])
369
370(define_insn "mmx_rsqrtv2sf2"
371  [(set (match_operand:V2SF 0 "register_operand" "=y")
372	(unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
373		     UNSPEC_PFRSQRT))]
374  "TARGET_3DNOW"
375  "pfrsqrt\t{%1, %0|%0, %1}"
376  [(set_attr "type" "mmx")
377   (set_attr "prefix_extra" "1")
378   (set_attr "mode" "V2SF")])
379
380(define_insn "mmx_rsqit1v2sf3"
381  [(set (match_operand:V2SF 0 "register_operand" "=y")
382	(unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
383		      (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
384		     UNSPEC_PFRSQIT1))]
385  "TARGET_3DNOW"
386  "pfrsqit1\t{%2, %0|%0, %2}"
387  [(set_attr "type" "mmx")
388   (set_attr "prefix_extra" "1")
389   (set_attr "mode" "V2SF")])
390
391(define_insn "mmx_haddv2sf3"
392  [(set (match_operand:V2SF 0 "register_operand" "=y")
393	(vec_concat:V2SF
394	  (plus:SF
395	    (vec_select:SF
396	      (match_operand:V2SF 1 "register_operand" "0")
397	      (parallel [(const_int  0)]))
398	    (vec_select:SF (match_dup 1) (parallel [(const_int 1)])))
399	  (plus:SF
400            (vec_select:SF
401	      (match_operand:V2SF 2 "nonimmediate_operand" "ym")
402	      (parallel [(const_int  0)]))
403	    (vec_select:SF (match_dup 2) (parallel [(const_int 1)])))))]
404  "TARGET_3DNOW"
405  "pfacc\t{%2, %0|%0, %2}"
406  [(set_attr "type" "mmxadd")
407   (set_attr "prefix_extra" "1")
408   (set_attr "mode" "V2SF")])
409
410(define_insn "mmx_hsubv2sf3"
411  [(set (match_operand:V2SF 0 "register_operand" "=y")
412	(vec_concat:V2SF
413	  (minus:SF
414	    (vec_select:SF
415	      (match_operand:V2SF 1 "register_operand" "0")
416	      (parallel [(const_int  0)]))
417	    (vec_select:SF (match_dup 1) (parallel [(const_int 1)])))
418	  (minus:SF
419            (vec_select:SF
420	      (match_operand:V2SF 2 "nonimmediate_operand" "ym")
421	      (parallel [(const_int  0)]))
422	    (vec_select:SF (match_dup 2) (parallel [(const_int 1)])))))]
423  "TARGET_3DNOW_A"
424  "pfnacc\t{%2, %0|%0, %2}"
425  [(set_attr "type" "mmxadd")
426   (set_attr "prefix_extra" "1")
427   (set_attr "mode" "V2SF")])
428
429(define_insn "mmx_addsubv2sf3"
430  [(set (match_operand:V2SF 0 "register_operand" "=y")
431        (vec_merge:V2SF
432          (plus:V2SF
433            (match_operand:V2SF 1 "register_operand" "0")
434            (match_operand:V2SF 2 "nonimmediate_operand" "ym"))
435          (minus:V2SF (match_dup 1) (match_dup 2))
436          (const_int 1)))]
437  "TARGET_3DNOW_A"
438  "pfpnacc\t{%2, %0|%0, %2}"
439  [(set_attr "type" "mmxadd")
440   (set_attr "prefix_extra" "1")
441   (set_attr "mode" "V2SF")])
442
443;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
444;;
445;; Parallel single-precision floating point comparisons
446;;
447;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
448
449(define_expand "mmx_eqv2sf3"
450  [(set (match_operand:V2SI 0 "register_operand")
451	(eq:V2SI (match_operand:V2SF 1 "nonimmediate_operand")
452		 (match_operand:V2SF 2 "nonimmediate_operand")))]
453  "TARGET_3DNOW"
454  "ix86_fixup_binary_operands_no_copy (EQ, V2SFmode, operands);")
455
456(define_insn "*mmx_eqv2sf3"
457  [(set (match_operand:V2SI 0 "register_operand" "=y")
458	(eq:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "%0")
459		 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
460  "TARGET_3DNOW && ix86_binary_operator_ok (EQ, V2SFmode, operands)"
461  "pfcmpeq\t{%2, %0|%0, %2}"
462  [(set_attr "type" "mmxcmp")
463   (set_attr "prefix_extra" "1")
464   (set_attr "mode" "V2SF")])
465
466(define_insn "mmx_gtv2sf3"
467  [(set (match_operand:V2SI 0 "register_operand" "=y")
468	(gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
469		 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
470  "TARGET_3DNOW"
471  "pfcmpgt\t{%2, %0|%0, %2}"
472  [(set_attr "type" "mmxcmp")
473   (set_attr "prefix_extra" "1")
474   (set_attr "mode" "V2SF")])
475
476(define_insn "mmx_gev2sf3"
477  [(set (match_operand:V2SI 0 "register_operand" "=y")
478	(ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
479		 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
480  "TARGET_3DNOW"
481  "pfcmpge\t{%2, %0|%0, %2}"
482  [(set_attr "type" "mmxcmp")
483   (set_attr "prefix_extra" "1")
484   (set_attr "mode" "V2SF")])
485
486;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
487;;
488;; Parallel single-precision floating point conversion operations
489;;
490;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
491
492(define_insn "mmx_pf2id"
493  [(set (match_operand:V2SI 0 "register_operand" "=y")
494	(fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
495  "TARGET_3DNOW"
496  "pf2id\t{%1, %0|%0, %1}"
497  [(set_attr "type" "mmxcvt")
498   (set_attr "prefix_extra" "1")
499   (set_attr "mode" "V2SF")])
500
501(define_insn "mmx_pf2iw"
502  [(set (match_operand:V2SI 0 "register_operand" "=y")
503	(sign_extend:V2SI
504	  (ss_truncate:V2HI
505	    (fix:V2SI
506	      (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
507  "TARGET_3DNOW_A"
508  "pf2iw\t{%1, %0|%0, %1}"
509  [(set_attr "type" "mmxcvt")
510   (set_attr "prefix_extra" "1")
511   (set_attr "mode" "V2SF")])
512
513(define_insn "mmx_pi2fw"
514  [(set (match_operand:V2SF 0 "register_operand" "=y")
515	(float:V2SF
516	  (sign_extend:V2SI
517	    (truncate:V2HI
518	      (match_operand:V2SI 1 "nonimmediate_operand" "ym")))))]
519  "TARGET_3DNOW_A"
520  "pi2fw\t{%1, %0|%0, %1}"
521  [(set_attr "type" "mmxcvt")
522   (set_attr "prefix_extra" "1")
523   (set_attr "mode" "V2SF")])
524
525(define_insn "mmx_floatv2si2"
526  [(set (match_operand:V2SF 0 "register_operand" "=y")
527	(float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
528  "TARGET_3DNOW"
529  "pi2fd\t{%1, %0|%0, %1}"
530  [(set_attr "type" "mmxcvt")
531   (set_attr "prefix_extra" "1")
532   (set_attr "mode" "V2SF")])
533
534;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
535;;
536;; Parallel single-precision floating point element swizzling
537;;
538;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
539
540(define_insn "mmx_pswapdv2sf2"
541  [(set (match_operand:V2SF 0 "register_operand" "=y")
542	(vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym")
543			 (parallel [(const_int 1) (const_int 0)])))]
544  "TARGET_3DNOW_A"
545  "pswapd\t{%1, %0|%0, %1}"
546  [(set_attr "type" "mmxcvt")
547   (set_attr "prefix_extra" "1")
548   (set_attr "mode" "V2SF")])
549
550(define_insn "*vec_dupv2sf"
551  [(set (match_operand:V2SF 0 "register_operand" "=y")
552	(vec_duplicate:V2SF
553	  (match_operand:SF 1 "register_operand" "0")))]
554  "TARGET_MMX"
555  "punpckldq\t%0, %0"
556  [(set_attr "type" "mmxcvt")
557   (set_attr "mode" "DI")])
558
559(define_insn "*mmx_concatv2sf"
560  [(set (match_operand:V2SF 0 "register_operand"     "=y,y")
561	(vec_concat:V2SF
562	  (match_operand:SF 1 "nonimmediate_operand" " 0,rm")
563	  (match_operand:SF 2 "vector_move_operand"  "ym,C")))]
564  "TARGET_MMX && !TARGET_SSE"
565  "@
566   punpckldq\t{%2, %0|%0, %2}
567   movd\t{%1, %0|%0, %1}"
568  [(set_attr "type" "mmxcvt,mmxmov")
569   (set_attr "mode" "DI")])
570
571(define_expand "vec_setv2sf"
572  [(match_operand:V2SF 0 "register_operand")
573   (match_operand:SF 1 "register_operand")
574   (match_operand 2 "const_int_operand")]
575  "TARGET_MMX"
576{
577  ix86_expand_vector_set (false, operands[0], operands[1],
578			  INTVAL (operands[2]));
579  DONE;
580})
581
582;; Avoid combining registers from different units in a single alternative,
583;; see comment above inline_secondary_memory_needed function in i386.c
584(define_insn_and_split "*vec_extractv2sf_0"
585  [(set (match_operand:SF 0 "nonimmediate_operand"     "=x, m,y ,m,f,r")
586	(vec_select:SF
587	  (match_operand:V2SF 1 "nonimmediate_operand" " xm,x,ym,y,m,m")
588	  (parallel [(const_int 0)])))]
589  "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
590  "#"
591  "&& reload_completed"
592  [(set (match_dup 0) (match_dup 1))]
593{
594  if (REG_P (operands[1]))
595    operands[1] = gen_rtx_REG (SFmode, REGNO (operands[1]));
596  else
597    operands[1] = adjust_address (operands[1], SFmode, 0);
598})
599
600;; Avoid combining registers from different units in a single alternative,
601;; see comment above inline_secondary_memory_needed function in i386.c
602(define_insn "*vec_extractv2sf_1"
603  [(set (match_operand:SF 0 "nonimmediate_operand"     "=y,x,x,y,x,f,r")
604	(vec_select:SF
605	  (match_operand:V2SF 1 "nonimmediate_operand" " 0,x,x,o,o,o,o")
606	  (parallel [(const_int 1)])))]
607  "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
608  "@
609   punpckhdq\t%0, %0
610   %vmovshdup\t{%1, %0|%0, %1}
611   shufps\t{$0xe5, %1, %0|%0, %1, 0xe5}
612   #
613   #
614   #
615   #"
616  [(set_attr "isa" "*,sse3,noavx,*,*,*,*")
617   (set_attr "type" "mmxcvt,sse,sseshuf1,mmxmov,ssemov,fmov,imov")
618   (set_attr "length_immediate" "*,*,1,*,*,*,*")
619   (set_attr "prefix_rep" "*,1,*,*,*,*,*")
620   (set_attr "prefix" "orig,maybe_vex,orig,orig,orig,orig,orig")
621   (set_attr "mode" "DI,V4SF,V4SF,SF,SF,SF,SF")])
622
623(define_split
624  [(set (match_operand:SF 0 "register_operand")
625	(vec_select:SF
626	  (match_operand:V2SF 1 "memory_operand")
627	  (parallel [(const_int 1)])))]
628  "TARGET_MMX && reload_completed"
629  [(set (match_dup 0) (match_dup 1))]
630  "operands[1] = adjust_address (operands[1], SFmode, 4);")
631
632(define_expand "vec_extractv2sf"
633  [(match_operand:SF 0 "register_operand")
634   (match_operand:V2SF 1 "register_operand")
635   (match_operand 2 "const_int_operand")]
636  "TARGET_MMX"
637{
638  ix86_expand_vector_extract (false, operands[0], operands[1],
639			      INTVAL (operands[2]));
640  DONE;
641})
642
643(define_expand "vec_initv2sf"
644  [(match_operand:V2SF 0 "register_operand")
645   (match_operand 1)]
646  "TARGET_SSE"
647{
648  ix86_expand_vector_init (false, operands[0], operands[1]);
649  DONE;
650})
651
652;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
653;;
654;; Parallel integral arithmetic
655;;
656;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
657
658(define_expand "mmx_<plusminus_insn><mode>3"
659  [(set (match_operand:MMXMODEI8 0 "register_operand")
660	(plusminus:MMXMODEI8
661	  (match_operand:MMXMODEI8 1 "nonimmediate_operand")
662	  (match_operand:MMXMODEI8 2 "nonimmediate_operand")))]
663  "TARGET_MMX || (TARGET_SSE2 && <MODE>mode == V1DImode)"
664  "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
665
666(define_insn "*mmx_<plusminus_insn><mode>3"
667  [(set (match_operand:MMXMODEI8 0 "register_operand" "=y")
668        (plusminus:MMXMODEI8
669	  (match_operand:MMXMODEI8 1 "nonimmediate_operand" "<comm>0")
670	  (match_operand:MMXMODEI8 2 "nonimmediate_operand" "ym")))]
671  "(TARGET_MMX || (TARGET_SSE2 && <MODE>mode == V1DImode))
672   && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
673  "p<plusminus_mnemonic><mmxvecsize>\t{%2, %0|%0, %2}"
674  [(set_attr "type" "mmxadd")
675   (set_attr "mode" "DI")])
676
677(define_expand "mmx_<plusminus_insn><mode>3"
678  [(set (match_operand:MMXMODE12 0 "register_operand")
679	(sat_plusminus:MMXMODE12
680	  (match_operand:MMXMODE12 1 "nonimmediate_operand")
681	  (match_operand:MMXMODE12 2 "nonimmediate_operand")))]
682  "TARGET_MMX"
683  "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
684
685(define_insn "*mmx_<plusminus_insn><mode>3"
686  [(set (match_operand:MMXMODE12 0 "register_operand" "=y")
687        (sat_plusminus:MMXMODE12
688	  (match_operand:MMXMODE12 1 "nonimmediate_operand" "<comm>0")
689	  (match_operand:MMXMODE12 2 "nonimmediate_operand" "ym")))]
690  "TARGET_MMX && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
691  "p<plusminus_mnemonic><mmxvecsize>\t{%2, %0|%0, %2}"
692  [(set_attr "type" "mmxadd")
693   (set_attr "mode" "DI")])
694
695(define_expand "mmx_mulv4hi3"
696  [(set (match_operand:V4HI 0 "register_operand")
697        (mult:V4HI (match_operand:V4HI 1 "nonimmediate_operand")
698		   (match_operand:V4HI 2 "nonimmediate_operand")))]
699  "TARGET_MMX"
700  "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
701
702(define_insn "*mmx_mulv4hi3"
703  [(set (match_operand:V4HI 0 "register_operand" "=y")
704        (mult:V4HI (match_operand:V4HI 1 "nonimmediate_operand" "%0")
705		   (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
706  "TARGET_MMX && ix86_binary_operator_ok (MULT, V4HImode, operands)"
707  "pmullw\t{%2, %0|%0, %2}"
708  [(set_attr "type" "mmxmul")
709   (set_attr "mode" "DI")])
710
711(define_expand "mmx_smulv4hi3_highpart"
712  [(set (match_operand:V4HI 0 "register_operand")
713	(truncate:V4HI
714	  (lshiftrt:V4SI
715	    (mult:V4SI
716	      (sign_extend:V4SI
717		(match_operand:V4HI 1 "nonimmediate_operand"))
718	      (sign_extend:V4SI
719		(match_operand:V4HI 2 "nonimmediate_operand")))
720	    (const_int 16))))]
721  "TARGET_MMX"
722  "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
723
724(define_insn "*mmx_smulv4hi3_highpart"
725  [(set (match_operand:V4HI 0 "register_operand" "=y")
726	(truncate:V4HI
727	  (lshiftrt:V4SI
728	    (mult:V4SI
729	      (sign_extend:V4SI
730		(match_operand:V4HI 1 "nonimmediate_operand" "%0"))
731	      (sign_extend:V4SI
732		(match_operand:V4HI 2 "nonimmediate_operand" "ym")))
733	    (const_int 16))))]
734  "TARGET_MMX && ix86_binary_operator_ok (MULT, V4HImode, operands)"
735  "pmulhw\t{%2, %0|%0, %2}"
736  [(set_attr "type" "mmxmul")
737   (set_attr "mode" "DI")])
738
739(define_expand "mmx_umulv4hi3_highpart"
740  [(set (match_operand:V4HI 0 "register_operand")
741	(truncate:V4HI
742	  (lshiftrt:V4SI
743	    (mult:V4SI
744	      (zero_extend:V4SI
745		(match_operand:V4HI 1 "nonimmediate_operand"))
746	      (zero_extend:V4SI
747		(match_operand:V4HI 2 "nonimmediate_operand")))
748	    (const_int 16))))]
749  "TARGET_SSE || TARGET_3DNOW_A"
750  "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
751
752(define_insn "*mmx_umulv4hi3_highpart"
753  [(set (match_operand:V4HI 0 "register_operand" "=y")
754	(truncate:V4HI
755	  (lshiftrt:V4SI
756	    (mult:V4SI
757	      (zero_extend:V4SI
758		(match_operand:V4HI 1 "nonimmediate_operand" "%0"))
759	      (zero_extend:V4SI
760		(match_operand:V4HI 2 "nonimmediate_operand" "ym")))
761	  (const_int 16))))]
762  "(TARGET_SSE || TARGET_3DNOW_A)
763   && ix86_binary_operator_ok (MULT, V4HImode, operands)"
764  "pmulhuw\t{%2, %0|%0, %2}"
765  [(set_attr "type" "mmxmul")
766   (set_attr "mode" "DI")])
767
768(define_expand "mmx_pmaddwd"
769  [(set (match_operand:V2SI 0 "register_operand")
770        (plus:V2SI
771	  (mult:V2SI
772	    (sign_extend:V2SI
773	      (vec_select:V2HI
774		(match_operand:V4HI 1 "nonimmediate_operand")
775		(parallel [(const_int 0) (const_int 2)])))
776	    (sign_extend:V2SI
777	      (vec_select:V2HI
778		(match_operand:V4HI 2 "nonimmediate_operand")
779		(parallel [(const_int 0) (const_int 2)]))))
780	  (mult:V2SI
781	    (sign_extend:V2SI
782	      (vec_select:V2HI (match_dup 1)
783		(parallel [(const_int 1) (const_int 3)])))
784	    (sign_extend:V2SI
785	      (vec_select:V2HI (match_dup 2)
786		(parallel [(const_int 1) (const_int 3)]))))))]
787  "TARGET_MMX"
788  "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
789
790(define_insn "*mmx_pmaddwd"
791  [(set (match_operand:V2SI 0 "register_operand" "=y")
792        (plus:V2SI
793	  (mult:V2SI
794	    (sign_extend:V2SI
795	      (vec_select:V2HI
796		(match_operand:V4HI 1 "nonimmediate_operand" "%0")
797		(parallel [(const_int 0) (const_int 2)])))
798	    (sign_extend:V2SI
799	      (vec_select:V2HI
800		(match_operand:V4HI 2 "nonimmediate_operand" "ym")
801		(parallel [(const_int 0) (const_int 2)]))))
802	  (mult:V2SI
803	    (sign_extend:V2SI
804	      (vec_select:V2HI (match_dup 1)
805		(parallel [(const_int 1) (const_int 3)])))
806	    (sign_extend:V2SI
807	      (vec_select:V2HI (match_dup 2)
808		(parallel [(const_int 1) (const_int 3)]))))))]
809  "TARGET_MMX && ix86_binary_operator_ok (MULT, V4HImode, operands)"
810  "pmaddwd\t{%2, %0|%0, %2}"
811  [(set_attr "type" "mmxmul")
812   (set_attr "mode" "DI")])
813
814(define_expand "mmx_pmulhrwv4hi3"
815  [(set (match_operand:V4HI 0 "register_operand")
816	(truncate:V4HI
817	  (lshiftrt:V4SI
818	    (plus:V4SI
819	      (mult:V4SI
820	        (sign_extend:V4SI
821		  (match_operand:V4HI 1 "nonimmediate_operand"))
822	        (sign_extend:V4SI
823		  (match_operand:V4HI 2 "nonimmediate_operand")))
824	      (const_vector:V4SI [(const_int 32768) (const_int 32768)
825				  (const_int 32768) (const_int 32768)]))
826	    (const_int 16))))]
827  "TARGET_3DNOW"
828  "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
829
830(define_insn "*mmx_pmulhrwv4hi3"
831  [(set (match_operand:V4HI 0 "register_operand" "=y")
832	(truncate:V4HI
833	  (lshiftrt:V4SI
834	    (plus:V4SI
835	      (mult:V4SI
836	        (sign_extend:V4SI
837		  (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
838	        (sign_extend:V4SI
839		  (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
840	      (const_vector:V4SI [(const_int 32768) (const_int 32768)
841				  (const_int 32768) (const_int 32768)]))
842	    (const_int 16))))]
843  "TARGET_3DNOW && ix86_binary_operator_ok (MULT, V4HImode, operands)"
844  "pmulhrw\t{%2, %0|%0, %2}"
845  [(set_attr "type" "mmxmul")
846   (set_attr "prefix_extra" "1")
847   (set_attr "mode" "DI")])
848
849(define_expand "sse2_umulv1siv1di3"
850  [(set (match_operand:V1DI 0 "register_operand")
851        (mult:V1DI
852	  (zero_extend:V1DI
853	    (vec_select:V1SI
854	      (match_operand:V2SI 1 "nonimmediate_operand")
855	      (parallel [(const_int 0)])))
856	  (zero_extend:V1DI
857	    (vec_select:V1SI
858	      (match_operand:V2SI 2 "nonimmediate_operand")
859	      (parallel [(const_int 0)])))))]
860  "TARGET_SSE2"
861  "ix86_fixup_binary_operands_no_copy (MULT, V2SImode, operands);")
862
863(define_insn "*sse2_umulv1siv1di3"
864  [(set (match_operand:V1DI 0 "register_operand" "=y")
865        (mult:V1DI
866	  (zero_extend:V1DI
867	    (vec_select:V1SI
868	      (match_operand:V2SI 1 "nonimmediate_operand" "%0")
869	      (parallel [(const_int 0)])))
870	  (zero_extend:V1DI
871	    (vec_select:V1SI
872	      (match_operand:V2SI 2 "nonimmediate_operand" "ym")
873	      (parallel [(const_int 0)])))))]
874  "TARGET_SSE2 && ix86_binary_operator_ok (MULT, V2SImode, operands)"
875  "pmuludq\t{%2, %0|%0, %2}"
876  [(set_attr "type" "mmxmul")
877   (set_attr "mode" "DI")])
878
879(define_expand "mmx_<code>v4hi3"
880  [(set (match_operand:V4HI 0 "register_operand")
881        (smaxmin:V4HI
882	  (match_operand:V4HI 1 "nonimmediate_operand")
883	  (match_operand:V4HI 2 "nonimmediate_operand")))]
884  "TARGET_SSE || TARGET_3DNOW_A"
885  "ix86_fixup_binary_operands_no_copy (<CODE>, V4HImode, operands);")
886
887(define_insn "*mmx_<code>v4hi3"
888  [(set (match_operand:V4HI 0 "register_operand" "=y")
889        (smaxmin:V4HI
890	  (match_operand:V4HI 1 "nonimmediate_operand" "%0")
891	  (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
892  "(TARGET_SSE || TARGET_3DNOW_A)
893   && ix86_binary_operator_ok (<CODE>, V4HImode, operands)"
894  "p<maxmin_int>w\t{%2, %0|%0, %2}"
895  [(set_attr "type" "mmxadd")
896   (set_attr "mode" "DI")])
897
898(define_expand "mmx_<code>v8qi3"
899  [(set (match_operand:V8QI 0 "register_operand")
900        (umaxmin:V8QI
901	  (match_operand:V8QI 1 "nonimmediate_operand")
902	  (match_operand:V8QI 2 "nonimmediate_operand")))]
903  "TARGET_SSE || TARGET_3DNOW_A"
904  "ix86_fixup_binary_operands_no_copy (<CODE>, V8QImode, operands);")
905
906(define_insn "*mmx_<code>v8qi3"
907  [(set (match_operand:V8QI 0 "register_operand" "=y")
908        (umaxmin:V8QI
909	  (match_operand:V8QI 1 "nonimmediate_operand" "%0")
910	  (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
911  "(TARGET_SSE || TARGET_3DNOW_A)
912   && ix86_binary_operator_ok (<CODE>, V8QImode, operands)"
913  "p<maxmin_int>b\t{%2, %0|%0, %2}"
914  [(set_attr "type" "mmxadd")
915   (set_attr "mode" "DI")])
916
917(define_insn "mmx_ashr<mode>3"
918  [(set (match_operand:MMXMODE24 0 "register_operand" "=y")
919        (ashiftrt:MMXMODE24
920	  (match_operand:MMXMODE24 1 "register_operand" "0")
921	  (match_operand:SI 2 "nonmemory_operand" "yN")))]
922  "TARGET_MMX"
923  "psra<mmxvecsize>\t{%2, %0|%0, %2}"
924  [(set_attr "type" "mmxshft")
925   (set (attr "length_immediate")
926     (if_then_else (match_operand 2 "const_int_operand")
927       (const_string "1")
928       (const_string "0")))
929   (set_attr "mode" "DI")])
930
931(define_insn "mmx_<shift_insn><mode>3"
932  [(set (match_operand:MMXMODE248 0 "register_operand" "=y")
933        (any_lshift:MMXMODE248
934	  (match_operand:MMXMODE248 1 "register_operand" "0")
935	  (match_operand:SI 2 "nonmemory_operand" "yN")))]
936  "TARGET_MMX"
937  "p<vshift><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")])
944
945;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
946;;
947;; Parallel integral comparisons
948;;
949;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
950
951(define_expand "mmx_eq<mode>3"
952  [(set (match_operand:MMXMODEI 0 "register_operand")
953        (eq:MMXMODEI
954	  (match_operand:MMXMODEI 1 "nonimmediate_operand")
955	  (match_operand:MMXMODEI 2 "nonimmediate_operand")))]
956  "TARGET_MMX"
957  "ix86_fixup_binary_operands_no_copy (EQ, <MODE>mode, operands);")
958
959(define_insn "*mmx_eq<mode>3"
960  [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
961        (eq:MMXMODEI
962	  (match_operand:MMXMODEI 1 "nonimmediate_operand" "%0")
963	  (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
964  "TARGET_MMX && ix86_binary_operator_ok (EQ, <MODE>mode, operands)"
965  "pcmpeq<mmxvecsize>\t{%2, %0|%0, %2}"
966  [(set_attr "type" "mmxcmp")
967   (set_attr "mode" "DI")])
968
969(define_insn "mmx_gt<mode>3"
970  [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
971        (gt:MMXMODEI
972	  (match_operand:MMXMODEI 1 "register_operand" "0")
973	  (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
974  "TARGET_MMX"
975  "pcmpgt<mmxvecsize>\t{%2, %0|%0, %2}"
976  [(set_attr "type" "mmxcmp")
977   (set_attr "mode" "DI")])
978
979;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
980;;
981;; Parallel integral logical operations
982;;
983;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
984
985(define_insn "mmx_andnot<mode>3"
986  [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
987	(and:MMXMODEI
988	  (not:MMXMODEI (match_operand:MMXMODEI 1 "register_operand" "0"))
989	  (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
990  "TARGET_MMX"
991  "pandn\t{%2, %0|%0, %2}"
992  [(set_attr "type" "mmxadd")
993   (set_attr "mode" "DI")])
994
995(define_expand "mmx_<code><mode>3"
996  [(set (match_operand:MMXMODEI 0 "register_operand")
997	(any_logic:MMXMODEI
998	  (match_operand:MMXMODEI 1 "nonimmediate_operand")
999	  (match_operand:MMXMODEI 2 "nonimmediate_operand")))]
1000  "TARGET_MMX"
1001  "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
1002
1003(define_insn "*mmx_<code><mode>3"
1004  [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
1005        (any_logic:MMXMODEI
1006	  (match_operand:MMXMODEI 1 "nonimmediate_operand" "%0")
1007	  (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
1008  "TARGET_MMX && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
1009  "p<logic>\t{%2, %0|%0, %2}"
1010  [(set_attr "type" "mmxadd")
1011   (set_attr "mode" "DI")])
1012
1013;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1014;;
1015;; Parallel integral element swizzling
1016;;
1017;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1018
1019(define_insn "mmx_packsswb"
1020  [(set (match_operand:V8QI 0 "register_operand" "=y")
1021	(vec_concat:V8QI
1022	  (ss_truncate:V4QI
1023	    (match_operand:V4HI 1 "register_operand" "0"))
1024	  (ss_truncate:V4QI
1025	    (match_operand:V4HI 2 "nonimmediate_operand" "ym"))))]
1026  "TARGET_MMX"
1027  "packsswb\t{%2, %0|%0, %2}"
1028  [(set_attr "type" "mmxshft")
1029   (set_attr "mode" "DI")])
1030
1031(define_insn "mmx_packssdw"
1032  [(set (match_operand:V4HI 0 "register_operand" "=y")
1033	(vec_concat:V4HI
1034	  (ss_truncate:V2HI
1035	    (match_operand:V2SI 1 "register_operand" "0"))
1036	  (ss_truncate:V2HI
1037	    (match_operand:V2SI 2 "nonimmediate_operand" "ym"))))]
1038  "TARGET_MMX"
1039  "packssdw\t{%2, %0|%0, %2}"
1040  [(set_attr "type" "mmxshft")
1041   (set_attr "mode" "DI")])
1042
1043(define_insn "mmx_packuswb"
1044  [(set (match_operand:V8QI 0 "register_operand" "=y")
1045	(vec_concat:V8QI
1046	  (us_truncate:V4QI
1047	    (match_operand:V4HI 1 "register_operand" "0"))
1048	  (us_truncate:V4QI
1049	    (match_operand:V4HI 2 "nonimmediate_operand" "ym"))))]
1050  "TARGET_MMX"
1051  "packuswb\t{%2, %0|%0, %2}"
1052  [(set_attr "type" "mmxshft")
1053   (set_attr "mode" "DI")])
1054
1055(define_insn "mmx_punpckhbw"
1056  [(set (match_operand:V8QI 0 "register_operand" "=y")
1057	(vec_select:V8QI
1058	  (vec_concat:V16QI
1059	    (match_operand:V8QI 1 "register_operand" "0")
1060	    (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
1061          (parallel [(const_int 4) (const_int 12)
1062                     (const_int 5) (const_int 13)
1063                     (const_int 6) (const_int 14)
1064                     (const_int 7) (const_int 15)])))]
1065  "TARGET_MMX"
1066  "punpckhbw\t{%2, %0|%0, %2}"
1067  [(set_attr "type" "mmxcvt")
1068   (set_attr "mode" "DI")])
1069
1070(define_insn "mmx_punpcklbw"
1071  [(set (match_operand:V8QI 0 "register_operand" "=y")
1072	(vec_select:V8QI
1073	  (vec_concat:V16QI
1074	    (match_operand:V8QI 1 "register_operand" "0")
1075	    (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
1076          (parallel [(const_int 0) (const_int 8)
1077                     (const_int 1) (const_int 9)
1078                     (const_int 2) (const_int 10)
1079                     (const_int 3) (const_int 11)])))]
1080  "TARGET_MMX"
1081  "punpcklbw\t{%2, %0|%0, %k2}"
1082  [(set_attr "type" "mmxcvt")
1083   (set_attr "mode" "DI")])
1084
1085(define_insn "mmx_punpckhwd"
1086  [(set (match_operand:V4HI 0 "register_operand" "=y")
1087	(vec_select:V4HI
1088	  (vec_concat:V8HI
1089	    (match_operand:V4HI 1 "register_operand" "0")
1090	    (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
1091          (parallel [(const_int 2) (const_int 6)
1092                     (const_int 3) (const_int 7)])))]
1093  "TARGET_MMX"
1094  "punpckhwd\t{%2, %0|%0, %2}"
1095  [(set_attr "type" "mmxcvt")
1096   (set_attr "mode" "DI")])
1097
1098(define_insn "mmx_punpcklwd"
1099  [(set (match_operand:V4HI 0 "register_operand" "=y")
1100	(vec_select:V4HI
1101	  (vec_concat:V8HI
1102	    (match_operand:V4HI 1 "register_operand" "0")
1103	    (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
1104          (parallel [(const_int 0) (const_int 4)
1105                     (const_int 1) (const_int 5)])))]
1106  "TARGET_MMX"
1107  "punpcklwd\t{%2, %0|%0, %k2}"
1108  [(set_attr "type" "mmxcvt")
1109   (set_attr "mode" "DI")])
1110
1111(define_insn "mmx_punpckhdq"
1112  [(set (match_operand:V2SI 0 "register_operand" "=y")
1113	(vec_select:V2SI
1114	  (vec_concat:V4SI
1115	    (match_operand:V2SI 1 "register_operand" "0")
1116	    (match_operand:V2SI 2 "nonimmediate_operand" "ym"))
1117	  (parallel [(const_int 1)
1118		     (const_int 3)])))]
1119  "TARGET_MMX"
1120  "punpckhdq\t{%2, %0|%0, %2}"
1121  [(set_attr "type" "mmxcvt")
1122   (set_attr "mode" "DI")])
1123
1124(define_insn "mmx_punpckldq"
1125  [(set (match_operand:V2SI 0 "register_operand" "=y")
1126	(vec_select:V2SI
1127	  (vec_concat:V4SI
1128	    (match_operand:V2SI 1 "register_operand" "0")
1129	    (match_operand:V2SI 2 "nonimmediate_operand" "ym"))
1130	  (parallel [(const_int 0)
1131		     (const_int 2)])))]
1132  "TARGET_MMX"
1133  "punpckldq\t{%2, %0|%0, %k2}"
1134  [(set_attr "type" "mmxcvt")
1135   (set_attr "mode" "DI")])
1136
1137(define_expand "mmx_pinsrw"
1138  [(set (match_operand:V4HI 0 "register_operand")
1139        (vec_merge:V4HI
1140          (vec_duplicate:V4HI
1141            (match_operand:SI 2 "nonimmediate_operand"))
1142	  (match_operand:V4HI 1 "register_operand")
1143          (match_operand:SI 3 "const_0_to_3_operand")))]
1144  "TARGET_SSE || TARGET_3DNOW_A"
1145{
1146  operands[2] = gen_lowpart (HImode, operands[2]);
1147  operands[3] = GEN_INT (1 << INTVAL (operands[3]));
1148})
1149
1150(define_insn "*mmx_pinsrw"
1151  [(set (match_operand:V4HI 0 "register_operand" "=y")
1152        (vec_merge:V4HI
1153          (vec_duplicate:V4HI
1154            (match_operand:HI 2 "nonimmediate_operand" "rm"))
1155	  (match_operand:V4HI 1 "register_operand" "0")
1156          (match_operand:SI 3 "const_int_operand")))]
1157  "(TARGET_SSE || TARGET_3DNOW_A)
1158   && ((unsigned) exact_log2 (INTVAL (operands[3]))
1159       < GET_MODE_NUNITS (V4HImode))"
1160{
1161  operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])));
1162  if (MEM_P (operands[2]))
1163    return "pinsrw\t{%3, %2, %0|%0, %2, %3}";
1164  else
1165    return "pinsrw\t{%3, %k2, %0|%0, %k2, %3}";
1166}
1167  [(set_attr "type" "mmxcvt")
1168   (set_attr "length_immediate" "1")
1169   (set_attr "mode" "DI")])
1170
1171(define_insn "mmx_pextrw"
1172  [(set (match_operand:SI 0 "register_operand" "=r")
1173        (zero_extend:SI
1174	  (vec_select:HI
1175	    (match_operand:V4HI 1 "register_operand" "y")
1176	    (parallel [(match_operand:SI 2 "const_0_to_3_operand" "n")]))))]
1177  "TARGET_SSE || TARGET_3DNOW_A"
1178  "pextrw\t{%2, %1, %0|%0, %1, %2}"
1179  [(set_attr "type" "mmxcvt")
1180   (set_attr "length_immediate" "1")
1181   (set_attr "mode" "DI")])
1182
1183(define_expand "mmx_pshufw"
1184  [(match_operand:V4HI 0 "register_operand")
1185   (match_operand:V4HI 1 "nonimmediate_operand")
1186   (match_operand:SI 2 "const_int_operand")]
1187  "TARGET_SSE || TARGET_3DNOW_A"
1188{
1189  int mask = INTVAL (operands[2]);
1190  emit_insn (gen_mmx_pshufw_1 (operands[0], operands[1],
1191                               GEN_INT ((mask >> 0) & 3),
1192                               GEN_INT ((mask >> 2) & 3),
1193                               GEN_INT ((mask >> 4) & 3),
1194                               GEN_INT ((mask >> 6) & 3)));
1195  DONE;
1196})
1197
1198(define_insn "mmx_pshufw_1"
1199  [(set (match_operand:V4HI 0 "register_operand" "=y")
1200        (vec_select:V4HI
1201          (match_operand:V4HI 1 "nonimmediate_operand" "ym")
1202          (parallel [(match_operand 2 "const_0_to_3_operand")
1203                     (match_operand 3 "const_0_to_3_operand")
1204                     (match_operand 4 "const_0_to_3_operand")
1205                     (match_operand 5 "const_0_to_3_operand")])))]
1206  "TARGET_SSE || TARGET_3DNOW_A"
1207{
1208  int mask = 0;
1209  mask |= INTVAL (operands[2]) << 0;
1210  mask |= INTVAL (operands[3]) << 2;
1211  mask |= INTVAL (operands[4]) << 4;
1212  mask |= INTVAL (operands[5]) << 6;
1213  operands[2] = GEN_INT (mask);
1214
1215  return "pshufw\t{%2, %1, %0|%0, %1, %2}";
1216}
1217  [(set_attr "type" "mmxcvt")
1218   (set_attr "length_immediate" "1")
1219   (set_attr "mode" "DI")])
1220
1221(define_insn "mmx_pswapdv2si2"
1222  [(set (match_operand:V2SI 0 "register_operand" "=y")
1223	(vec_select:V2SI
1224	  (match_operand:V2SI 1 "nonimmediate_operand" "ym")
1225	  (parallel [(const_int 1) (const_int 0)])))]
1226  "TARGET_3DNOW_A"
1227  "pswapd\t{%1, %0|%0, %1}"
1228  [(set_attr "type" "mmxcvt")
1229   (set_attr "prefix_extra" "1")
1230   (set_attr "mode" "DI")])
1231
1232(define_insn "*vec_dupv4hi"
1233  [(set (match_operand:V4HI 0 "register_operand" "=y")
1234	(vec_duplicate:V4HI
1235	  (truncate:HI
1236	    (match_operand:SI 1 "register_operand" "0"))))]
1237  "TARGET_SSE || TARGET_3DNOW_A"
1238  "pshufw\t{$0, %0, %0|%0, %0, 0}"
1239  [(set_attr "type" "mmxcvt")
1240   (set_attr "length_immediate" "1")
1241   (set_attr "mode" "DI")])
1242
1243(define_insn "*vec_dupv2si"
1244  [(set (match_operand:V2SI 0 "register_operand" "=y")
1245	(vec_duplicate:V2SI
1246	  (match_operand:SI 1 "register_operand" "0")))]
1247  "TARGET_MMX"
1248  "punpckldq\t%0, %0"
1249  [(set_attr "type" "mmxcvt")
1250   (set_attr "mode" "DI")])
1251
1252(define_insn "*mmx_concatv2si"
1253  [(set (match_operand:V2SI 0 "register_operand"     "=y,y")
1254	(vec_concat:V2SI
1255	  (match_operand:SI 1 "nonimmediate_operand" " 0,rm")
1256	  (match_operand:SI 2 "vector_move_operand"  "ym,C")))]
1257  "TARGET_MMX && !TARGET_SSE"
1258  "@
1259   punpckldq\t{%2, %0|%0, %2}
1260   movd\t{%1, %0|%0, %1}"
1261  [(set_attr "type" "mmxcvt,mmxmov")
1262   (set_attr "mode" "DI")])
1263
1264(define_expand "vec_setv2si"
1265  [(match_operand:V2SI 0 "register_operand")
1266   (match_operand:SI 1 "register_operand")
1267   (match_operand 2 "const_int_operand")]
1268  "TARGET_MMX"
1269{
1270  ix86_expand_vector_set (false, operands[0], operands[1],
1271			  INTVAL (operands[2]));
1272  DONE;
1273})
1274
1275;; Avoid combining registers from different units in a single alternative,
1276;; see comment above inline_secondary_memory_needed function in i386.c
1277(define_insn_and_split "*vec_extractv2si_0"
1278  [(set (match_operand:SI 0 "nonimmediate_operand"     "=x,m,y, m,r")
1279	(vec_select:SI
1280	  (match_operand:V2SI 1 "nonimmediate_operand" "xm,x,ym,y,m")
1281	  (parallel [(const_int 0)])))]
1282  "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1283  "#"
1284  "&& reload_completed"
1285  [(set (match_dup 0) (match_dup 1))]
1286{
1287  if (REG_P (operands[1]))
1288    operands[1] = gen_rtx_REG (SImode, REGNO (operands[1]));
1289  else
1290    operands[1] = adjust_address (operands[1], SImode, 0);
1291})
1292
1293;; Avoid combining registers from different units in a single alternative,
1294;; see comment above inline_secondary_memory_needed function in i386.c
1295(define_insn "*vec_extractv2si_1"
1296  [(set (match_operand:SI 0 "nonimmediate_operand"     "=y,x,x,y,x,r")
1297	(vec_select:SI
1298	  (match_operand:V2SI 1 "nonimmediate_operand" " 0,x,x,o,o,o")
1299	  (parallel [(const_int 1)])))]
1300  "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1301  "@
1302   punpckhdq\t%0, %0
1303   %vpshufd\t{$0xe5, %1, %0|%0, %1, 0xe5}
1304   shufps\t{$0xe5, %1, %0|%0, %1, 0xe5}
1305   #
1306   #
1307   #"
1308  [(set_attr "isa" "*,sse2,noavx,*,*,*")
1309   (set_attr "type" "mmxcvt,sseshuf1,sseshuf1,mmxmov,ssemov,imov")
1310   (set_attr "length_immediate" "*,1,1,*,*,*")
1311   (set_attr "prefix" "orig,maybe_vex,orig,orig,orig,orig")
1312   (set_attr "mode" "DI,TI,V4SF,SI,SI,SI")])
1313
1314(define_split
1315  [(set (match_operand:SI 0 "register_operand")
1316	(vec_select:SI
1317	  (match_operand:V2SI 1 "memory_operand")
1318	  (parallel [(const_int 1)])))]
1319  "TARGET_MMX && reload_completed"
1320  [(set (match_dup 0) (match_dup 1))]
1321  "operands[1] = adjust_address (operands[1], SImode, 4);")
1322
1323(define_insn_and_split "*vec_extractv2si_zext_mem"
1324  [(set (match_operand:DI 0 "register_operand" "=y,x,r")
1325	(zero_extend:DI
1326	  (vec_select:SI
1327	    (match_operand:V2SI 1 "memory_operand" "o,o,o")
1328	    (parallel [(match_operand:SI 2 "const_0_to_1_operand")]))))]
1329  "TARGET_64BIT && TARGET_MMX"
1330  "#"
1331  "&& reload_completed"
1332  [(set (match_dup 0) (zero_extend:DI (match_dup 1)))]
1333{
1334  operands[1] = adjust_address (operands[1], SImode, INTVAL (operands[2]) * 4);
1335})
1336
1337(define_expand "vec_extractv2si"
1338  [(match_operand:SI 0 "register_operand")
1339   (match_operand:V2SI 1 "register_operand")
1340   (match_operand 2 "const_int_operand")]
1341  "TARGET_MMX"
1342{
1343  ix86_expand_vector_extract (false, operands[0], operands[1],
1344			      INTVAL (operands[2]));
1345  DONE;
1346})
1347
1348(define_expand "vec_initv2si"
1349  [(match_operand:V2SI 0 "register_operand")
1350   (match_operand 1)]
1351  "TARGET_SSE"
1352{
1353  ix86_expand_vector_init (false, operands[0], operands[1]);
1354  DONE;
1355})
1356
1357(define_expand "vec_setv4hi"
1358  [(match_operand:V4HI 0 "register_operand")
1359   (match_operand:HI 1 "register_operand")
1360   (match_operand 2 "const_int_operand")]
1361  "TARGET_MMX"
1362{
1363  ix86_expand_vector_set (false, operands[0], operands[1],
1364			  INTVAL (operands[2]));
1365  DONE;
1366})
1367
1368(define_expand "vec_extractv4hi"
1369  [(match_operand:HI 0 "register_operand")
1370   (match_operand:V4HI 1 "register_operand")
1371   (match_operand 2 "const_int_operand")]
1372  "TARGET_MMX"
1373{
1374  ix86_expand_vector_extract (false, operands[0], operands[1],
1375			      INTVAL (operands[2]));
1376  DONE;
1377})
1378
1379(define_expand "vec_initv4hi"
1380  [(match_operand:V4HI 0 "register_operand")
1381   (match_operand 1)]
1382  "TARGET_SSE"
1383{
1384  ix86_expand_vector_init (false, operands[0], operands[1]);
1385  DONE;
1386})
1387
1388(define_expand "vec_setv8qi"
1389  [(match_operand:V8QI 0 "register_operand")
1390   (match_operand:QI 1 "register_operand")
1391   (match_operand 2 "const_int_operand")]
1392  "TARGET_MMX"
1393{
1394  ix86_expand_vector_set (false, operands[0], operands[1],
1395			  INTVAL (operands[2]));
1396  DONE;
1397})
1398
1399(define_expand "vec_extractv8qi"
1400  [(match_operand:QI 0 "register_operand")
1401   (match_operand:V8QI 1 "register_operand")
1402   (match_operand 2 "const_int_operand")]
1403  "TARGET_MMX"
1404{
1405  ix86_expand_vector_extract (false, operands[0], operands[1],
1406			      INTVAL (operands[2]));
1407  DONE;
1408})
1409
1410(define_expand "vec_initv8qi"
1411  [(match_operand:V8QI 0 "register_operand")
1412   (match_operand 1)]
1413  "TARGET_SSE"
1414{
1415  ix86_expand_vector_init (false, operands[0], operands[1]);
1416  DONE;
1417})
1418
1419;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1420;;
1421;; Miscellaneous
1422;;
1423;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1424
1425(define_expand "mmx_uavgv8qi3"
1426  [(set (match_operand:V8QI 0 "register_operand")
1427	(truncate:V8QI
1428	  (lshiftrt:V8HI
1429	    (plus:V8HI
1430	      (plus:V8HI
1431		(zero_extend:V8HI
1432		  (match_operand:V8QI 1 "nonimmediate_operand"))
1433		(zero_extend:V8HI
1434		  (match_operand:V8QI 2 "nonimmediate_operand")))
1435	      (const_vector:V8HI [(const_int 1) (const_int 1)
1436				  (const_int 1) (const_int 1)
1437				  (const_int 1) (const_int 1)
1438				  (const_int 1) (const_int 1)]))
1439	    (const_int 1))))]
1440  "TARGET_SSE || TARGET_3DNOW"
1441  "ix86_fixup_binary_operands_no_copy (PLUS, V8QImode, operands);")
1442
1443(define_insn "*mmx_uavgv8qi3"
1444  [(set (match_operand:V8QI 0 "register_operand" "=y")
1445	(truncate:V8QI
1446	  (lshiftrt:V8HI
1447	    (plus:V8HI
1448	      (plus:V8HI
1449		(zero_extend:V8HI
1450		  (match_operand:V8QI 1 "nonimmediate_operand" "%0"))
1451		(zero_extend:V8HI
1452		  (match_operand:V8QI 2 "nonimmediate_operand" "ym")))
1453	      (const_vector:V8HI [(const_int 1) (const_int 1)
1454				  (const_int 1) (const_int 1)
1455				  (const_int 1) (const_int 1)
1456				  (const_int 1) (const_int 1)]))
1457	    (const_int 1))))]
1458  "(TARGET_SSE || TARGET_3DNOW)
1459   && ix86_binary_operator_ok (PLUS, V8QImode, operands)"
1460{
1461  /* These two instructions have the same operation, but their encoding
1462     is different.  Prefer the one that is de facto standard.  */
1463  if (TARGET_SSE || TARGET_3DNOW_A)
1464    return "pavgb\t{%2, %0|%0, %2}";
1465  else
1466    return "pavgusb\t{%2, %0|%0, %2}";
1467}
1468  [(set_attr "type" "mmxshft")
1469   (set (attr "prefix_extra")
1470     (if_then_else
1471       (not (ior (match_test "TARGET_SSE")
1472		 (match_test "TARGET_3DNOW_A")))
1473       (const_string "1")
1474       (const_string "*")))
1475   (set_attr "mode" "DI")])
1476
1477(define_expand "mmx_uavgv4hi3"
1478  [(set (match_operand:V4HI 0 "register_operand")
1479	(truncate:V4HI
1480	  (lshiftrt:V4SI
1481	    (plus:V4SI
1482	      (plus:V4SI
1483		(zero_extend:V4SI
1484		  (match_operand:V4HI 1 "nonimmediate_operand"))
1485		(zero_extend:V4SI
1486		  (match_operand:V4HI 2 "nonimmediate_operand")))
1487	      (const_vector:V4SI [(const_int 1) (const_int 1)
1488				  (const_int 1) (const_int 1)]))
1489	    (const_int 1))))]
1490  "TARGET_SSE || TARGET_3DNOW_A"
1491  "ix86_fixup_binary_operands_no_copy (PLUS, V4HImode, operands);")
1492
1493(define_insn "*mmx_uavgv4hi3"
1494  [(set (match_operand:V4HI 0 "register_operand" "=y")
1495	(truncate:V4HI
1496	  (lshiftrt:V4SI
1497	    (plus:V4SI
1498	      (plus:V4SI
1499		(zero_extend:V4SI
1500		  (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
1501		(zero_extend:V4SI
1502		  (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
1503	      (const_vector:V4SI [(const_int 1) (const_int 1)
1504				  (const_int 1) (const_int 1)]))
1505	    (const_int 1))))]
1506  "(TARGET_SSE || TARGET_3DNOW_A)
1507   && ix86_binary_operator_ok (PLUS, V4HImode, operands)"
1508  "pavgw\t{%2, %0|%0, %2}"
1509  [(set_attr "type" "mmxshft")
1510   (set_attr "mode" "DI")])
1511
1512(define_insn "mmx_psadbw"
1513  [(set (match_operand:V1DI 0 "register_operand" "=y")
1514        (unspec:V1DI [(match_operand:V8QI 1 "register_operand" "0")
1515		      (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
1516		     UNSPEC_PSADBW))]
1517  "TARGET_SSE || TARGET_3DNOW_A"
1518  "psadbw\t{%2, %0|%0, %2}"
1519  [(set_attr "type" "mmxshft")
1520   (set_attr "mode" "DI")])
1521
1522(define_insn "mmx_pmovmskb"
1523  [(set (match_operand:SI 0 "register_operand" "=r")
1524	(unspec:SI [(match_operand:V8QI 1 "register_operand" "y")]
1525		   UNSPEC_MOVMSK))]
1526  "TARGET_SSE || TARGET_3DNOW_A"
1527  "pmovmskb\t{%1, %0|%0, %1}"
1528  [(set_attr "type" "mmxcvt")
1529   (set_attr "mode" "DI")])
1530
1531(define_expand "mmx_maskmovq"
1532  [(set (match_operand:V8QI 0 "memory_operand")
1533	(unspec:V8QI [(match_operand:V8QI 1 "register_operand")
1534		      (match_operand:V8QI 2 "register_operand")
1535		      (match_dup 0)]
1536		     UNSPEC_MASKMOV))]
1537  "TARGET_SSE || TARGET_3DNOW_A")
1538
1539(define_insn "*mmx_maskmovq"
1540  [(set (mem:V8QI (match_operand:P 0 "register_operand" "D"))
1541	(unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
1542		      (match_operand:V8QI 2 "register_operand" "y")
1543		      (mem:V8QI (match_dup 0))]
1544		     UNSPEC_MASKMOV))]
1545  "TARGET_SSE || TARGET_3DNOW_A"
1546  ;; @@@ check ordering of operands in intel/nonintel syntax
1547  "maskmovq\t{%2, %1|%1, %2}"
1548  [(set_attr "type" "mmxcvt")
1549   (set_attr "mode" "DI")])
1550
1551(define_expand "mmx_emms"
1552  [(match_par_dup 0 [(const_int 0)])]
1553  "TARGET_MMX"
1554{
1555  int regno;
1556
1557  operands[0] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (17));
1558
1559  XVECEXP (operands[0], 0, 0)
1560    = gen_rtx_UNSPEC_VOLATILE (VOIDmode, gen_rtvec (1, const0_rtx),
1561			       UNSPECV_EMMS);
1562
1563  for (regno = 0; regno < 8; regno++)
1564    {
1565      XVECEXP (operands[0], 0, regno + 1)
1566	= gen_rtx_CLOBBER (VOIDmode,
1567			   gen_rtx_REG (XFmode, FIRST_STACK_REG + regno));
1568
1569      XVECEXP (operands[0], 0, regno + 9)
1570	= gen_rtx_CLOBBER (VOIDmode,
1571			   gen_rtx_REG (DImode, FIRST_MMX_REG + regno));
1572    }
1573})
1574
1575(define_insn "*mmx_emms"
1576  [(match_parallel 0 "emms_operation"
1577    [(unspec_volatile [(const_int 0)] UNSPECV_EMMS)])]
1578  "TARGET_MMX"
1579  "emms"
1580  [(set_attr "type" "mmx")
1581   (set_attr "modrm" "0")
1582   (set_attr "memory" "none")])
1583
1584(define_expand "mmx_femms"
1585  [(match_par_dup 0 [(const_int 0)])]
1586  "TARGET_3DNOW"
1587{
1588  int regno;
1589
1590  operands[0] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (17));
1591
1592  XVECEXP (operands[0], 0, 0)
1593    = gen_rtx_UNSPEC_VOLATILE (VOIDmode, gen_rtvec (1, const0_rtx),
1594			       UNSPECV_FEMMS);
1595
1596  for (regno = 0; regno < 8; regno++)
1597    {
1598      XVECEXP (operands[0], 0, regno + 1)
1599	= gen_rtx_CLOBBER (VOIDmode,
1600			   gen_rtx_REG (XFmode, FIRST_STACK_REG + regno));
1601
1602      XVECEXP (operands[0], 0, regno + 9)
1603	= gen_rtx_CLOBBER (VOIDmode,
1604			   gen_rtx_REG (DImode, FIRST_MMX_REG + regno));
1605    }
1606})
1607
1608(define_insn "*mmx_femms"
1609  [(match_parallel 0 "emms_operation"
1610    [(unspec_volatile [(const_int 0)] UNSPECV_FEMMS)])]
1611  "TARGET_3DNOW"
1612  "femms"
1613  [(set_attr "type" "mmx")
1614   (set_attr "modrm" "0")
1615   (set_attr "memory" "none")])
1616