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