1;; GCC machine description for MMX and 3dNOW! instructions
2;; Copyright (C) 2005-2022 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 "TARGET_SSE2")])
49
50;; All 8-byte vector modes handled by MMX
51(define_mode_iterator MMXMODE [V8QI V4HI V2SI V1DI V2SF V4HF])
52(define_mode_iterator MMXMODE124 [V8QI V4HI V2SI V2SF])
53
54;; Mix-n-match
55(define_mode_iterator MMXMODE12 [V8QI V4HI])
56(define_mode_iterator MMXMODE14 [V8QI V2SI])
57(define_mode_iterator MMXMODE24 [V4HI V2SI])
58(define_mode_iterator MMXMODE248 [V4HI V2SI V1DI])
59
60;; All 4-byte integer/float16 vector modes
61(define_mode_iterator V_32 [V4QI V2HI V1SI V2HF])
62
63;; 4-byte integer vector modes
64(define_mode_iterator VI_32 [V4QI V2HI])
65
66;; 4-byte and 2-byte integer vector modes
67(define_mode_iterator VI_16_32 [V4QI V2QI V2HI])
68
69;; 4-byte and 2-byte QImode vector modes
70(define_mode_iterator VI1_16_32 [V4QI V2QI])
71
72;; V2S* modes
73(define_mode_iterator V2FI [V2SF V2SI])
74
75;; 4-byte and 8-byte float16 vector modes
76(define_mode_iterator VHF_32_64 [V4HF V2HF])
77
78;; Mapping from integer vector mode to mnemonic suffix
79(define_mode_attr mmxvecsize
80  [(V8QI "b") (V4QI "b") (V2QI "b")
81   (V4HI "w") (V2HI "w") (V2SI "d") (V1DI "q")])
82
83(define_mode_attr mmxdoublemode
84  [(V8QI "V8HI") (V4HI "V4SI")])
85
86;; Mapping of vector float modes to an integer mode of the same size
87(define_mode_attr mmxintvecmode
88  [(V2SF "V2SI") (V2SI "V2SI") (V4HI "V4HI") (V8QI "V8QI")])
89
90(define_mode_attr mmxintvecmodelower
91  [(V2SF "v2si") (V2SI "v2si") (V4HI "v4hi") (V8QI "v8qi")])
92
93(define_mode_attr Yv_Yw
94  [(V8QI "Yw") (V4HI "Yw") (V2SI "Yv") (V1DI "Yv") (V2SF "Yv")])
95
96;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
97;;
98;; Move patterns
99;;
100;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
101
102;; All of these patterns are enabled for MMX as well as 3dNOW.
103;; This is essential for maintaining stable calling conventions.
104
105(define_expand "mov<mode>"
106  [(set (match_operand:MMXMODE 0 "nonimmediate_operand")
107          (match_operand:MMXMODE 1 "nonimmediate_operand"))]
108  "TARGET_MMX || TARGET_MMX_WITH_SSE"
109{
110  ix86_expand_vector_move (<MODE>mode, operands);
111  DONE;
112})
113
114(define_insn "*mov<mode>_internal"
115  [(set (match_operand:MMXMODE 0 "nonimmediate_operand"
116    "=r ,o ,r,r ,m ,?!y,!y,?!y,m  ,r  ,?!y,v,v,v,m,r,v,!y,*x")
117          (match_operand:MMXMODE 1 "nonimm_or_0_operand"
118    "rCo,rC,C,rm,rC,C  ,!y,m  ,?!y,?!y,r  ,C,v,m,v,v,r,*x,!y"))]
119  "(TARGET_MMX || TARGET_MMX_WITH_SSE)
120   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
121{
122  switch (get_attr_type (insn))
123    {
124    case TYPE_MULTI:
125      return "#";
126
127    case TYPE_IMOV:
128      if (get_attr_mode (insn) == MODE_SI)
129          return "mov{l}\t{%1, %k0|%k0, %1}";
130      else
131          return "mov{q}\t{%1, %0|%0, %1}";
132
133    case TYPE_MMX:
134      return "pxor\t%0, %0";
135
136    case TYPE_MMXMOV:
137      /* Handle broken assemblers that require movd instead of movq.  */
138      if (!HAVE_AS_IX86_INTERUNIT_MOVQ
139            && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
140          return "movd\t{%1, %0|%0, %1}";
141      return "movq\t{%1, %0|%0, %1}";
142
143    case TYPE_SSECVT:
144      if (SSE_REG_P (operands[0]))
145          return "movq2dq\t{%1, %0|%0, %1}";
146      else
147          return "movdq2q\t{%1, %0|%0, %1}";
148
149    case TYPE_SSELOG1:
150      return standard_sse_constant_opcode (insn, operands);
151
152    case TYPE_SSEMOV:
153      return ix86_output_ssemov (insn, operands);
154
155    default:
156      gcc_unreachable ();
157    }
158}
159  [(set (attr "isa")
160     (cond [(eq_attr "alternative" "0,1")
161                (const_string "nox64")
162              (eq_attr "alternative" "2,3,4,9,10")
163                (const_string "x64")
164              (eq_attr "alternative" "15,16")
165                (const_string "x64_sse2")
166              (eq_attr "alternative" "17,18")
167                (const_string "sse2")
168             ]
169             (const_string "*")))
170   (set (attr "type")
171     (cond [(eq_attr "alternative" "0,1")
172                (const_string "multi")
173              (eq_attr "alternative" "2,3,4")
174                (const_string "imov")
175              (eq_attr "alternative" "5")
176                (const_string "mmx")
177              (eq_attr "alternative" "6,7,8,9,10")
178                (const_string "mmxmov")
179              (eq_attr "alternative" "11")
180                (const_string "sselog1")
181              (eq_attr "alternative" "17,18")
182                (const_string "ssecvt")
183             ]
184             (const_string "ssemov")))
185   (set (attr "prefix_rex")
186     (if_then_else (eq_attr "alternative" "9,10,15,16")
187       (const_string "1")
188       (const_string "*")))
189   (set (attr "prefix")
190     (if_then_else (eq_attr "type" "sselog1,ssemov")
191       (const_string "maybe_vex")
192       (const_string "orig")))
193   (set (attr "prefix_data16")
194     (if_then_else
195       (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
196       (const_string "1")
197       (const_string "*")))
198   (set (attr "mode")
199     (cond [(eq_attr "alternative" "2")
200                (const_string "SI")
201              (eq_attr "alternative" "11,12")
202                (cond [(match_test "<MODE>mode == V2SFmode")
203                           (const_string "V4SF")
204                         (match_test "<MODE>mode == V4HFmode")
205                           (const_string "V4SF")
206                         (ior (not (match_test "TARGET_SSE2"))
207                                (match_test "optimize_function_for_size_p (cfun)"))
208                           (const_string "V4SF")
209                        ]
210                        (const_string "TI"))
211
212              (and (eq_attr "alternative" "13")
213                     (ior (ior (and (match_test "<MODE>mode == V2SFmode")
214                                        (not (match_test "TARGET_MMX_WITH_SSE")))
215                                 (not (match_test "TARGET_SSE2")))
216                          (match_test "<MODE>mode == V4HFmode")))
217                (const_string "V2SF")
218
219              (and (eq_attr "alternative" "14")
220                     (ior (ior (match_test "<MODE>mode == V2SFmode")
221                                 (not (match_test "TARGET_SSE2")))
222                          (match_test "<MODE>mode == V4HFmode")))
223                (const_string "V2SF")
224             ]
225             (const_string "DI")))
226   (set (attr "preferred_for_speed")
227     (cond [(eq_attr "alternative" "9,15")
228                (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
229              (eq_attr "alternative" "10,16")
230                (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
231             ]
232             (symbol_ref "true")))])
233
234(define_split
235  [(set (match_operand:MMXMODE 0 "nonimmediate_gr_operand")
236        (match_operand:MMXMODE 1 "nonimmediate_gr_operand"))]
237  "!TARGET_64BIT && reload_completed"
238  [(const_int 0)]
239  "ix86_split_long_move (operands); DONE;")
240
241(define_split
242  [(set (match_operand:MMXMODE 0 "nonimmediate_gr_operand")
243        (match_operand:MMXMODE 1 "const0_operand"))]
244  "!TARGET_64BIT && reload_completed"
245  [(const_int 0)]
246  "ix86_split_long_move (operands); DONE;")
247
248(define_expand "movmisalign<mode>"
249  [(set (match_operand:MMXMODE 0 "nonimmediate_operand")
250          (match_operand:MMXMODE 1 "nonimmediate_operand"))]
251  "TARGET_MMX || TARGET_MMX_WITH_SSE"
252{
253  ix86_expand_vector_move (<MODE>mode, operands);
254  DONE;
255})
256
257(define_expand "mov<mode>"
258  [(set (match_operand:V_32 0 "nonimmediate_operand")
259          (match_operand:V_32 1 "nonimmediate_operand"))]
260  ""
261{
262  ix86_expand_vector_move (<MODE>mode, operands);
263  DONE;
264})
265
266(define_insn "*mov<mode>_internal"
267  [(set (match_operand:V_32 0 "nonimmediate_operand"
268    "=r ,m ,v,v,v,m,r,v")
269          (match_operand:V_32 1 "general_operand"
270    "rmC,rC,C,v,m,v,v,r"))]
271  "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
272{
273  switch (get_attr_type (insn))
274    {
275    case TYPE_IMOV:
276      return "mov{l}\t{%1, %0|%0, %1}";
277
278    case TYPE_SSELOG1:
279      return standard_sse_constant_opcode (insn, operands);
280
281    case TYPE_SSEMOV:
282      return ix86_output_ssemov (insn, operands);
283
284    default:
285      gcc_unreachable ();
286    }
287}
288  [(set (attr "isa")
289     (cond [(eq_attr "alternative" "6,7")
290                (const_string "sse2")
291             ]
292             (const_string "*")))
293   (set (attr "type")
294     (cond [(eq_attr "alternative" "2")
295                (const_string "sselog1")
296              (eq_attr "alternative" "3,4,5,6,7")
297                (const_string "ssemov")
298             ]
299             (const_string "imov")))
300   (set (attr "prefix")
301     (if_then_else (eq_attr "type" "sselog1,ssemov")
302       (const_string "maybe_vex")
303       (const_string "orig")))
304   (set (attr "prefix_data16")
305     (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
306       (const_string "1")
307       (const_string "*")))
308   (set (attr "mode")
309     (cond [(eq_attr "alternative" "2,3")
310                (cond [(match_test "<MODE>mode == V2HFmode")
311                           (const_string "V4SF")
312                         (match_test "TARGET_AVX")
313                           (const_string "TI")
314                         (ior (not (match_test "TARGET_SSE2"))
315                                (match_test "optimize_function_for_size_p (cfun)"))
316                           (const_string "V4SF")
317                        ]
318                        (const_string "TI"))
319
320              (and (eq_attr "alternative" "4,5")
321                     (ior (match_test "<MODE>mode == V2HFmode")
322                          (not (match_test "TARGET_SSE2"))))
323                (const_string "SF")
324             ]
325             (const_string "SI")))
326   (set (attr "preferred_for_speed")
327     (cond [(eq_attr "alternative" "6")
328                (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
329              (eq_attr "alternative" "7")
330                (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
331             ]
332             (symbol_ref "true")))])
333
334;; For TARGET_64BIT we always round up to 8 bytes.
335(define_insn "*push<mode>2_rex64"
336  [(set (match_operand:V_32 0 "push_operand" "=X,X")
337          (match_operand:V_32 1 "nonmemory_no_elim_operand" "rC,*v"))]
338  "TARGET_64BIT"
339  "@
340   push{q}\t%q1
341   #"
342  [(set_attr "type" "push,multi")
343   (set_attr "mode" "DI")])
344
345(define_split
346  [(set (match_operand:V_32 0 "push_operand")
347          (match_operand:V_32 1 "sse_reg_operand"))]
348  "TARGET_64BIT && TARGET_SSE && reload_completed"
349  [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
350   (set (match_dup 0) (match_dup 1))]
351{
352  operands[2] = GEN_INT (-PUSH_ROUNDING (GET_MODE_SIZE (<V_32:MODE>mode)));
353  /* Preserve memory attributes. */
354  operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
355})
356
357(define_expand "movmisalign<mode>"
358  [(set (match_operand:V_32 0 "nonimmediate_operand")
359          (match_operand:V_32 1 "nonimmediate_operand"))]
360  ""
361{
362  ix86_expand_vector_move (<MODE>mode, operands);
363  DONE;
364})
365
366(define_expand "movv2qi"
367  [(set (match_operand:V2QI 0 "nonimmediate_operand")
368          (match_operand:V2QI 1 "nonimmediate_operand"))]
369  ""
370{
371  ix86_expand_vector_move (V2QImode, operands);
372  DONE;
373})
374
375(define_insn "*movv2qi_internal"
376  [(set (match_operand:V2QI 0 "nonimmediate_operand"
377    "=r,r,r,m ,v,v,v,m,r,v")
378          (match_operand:V2QI 1 "general_operand"
379    "r ,C,m,rC,C,v,m,v,v,r"))]
380  "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
381{
382  switch (get_attr_type (insn))
383    {
384    case TYPE_IMOV:
385      if (get_attr_mode (insn) == MODE_SI)
386          return "mov{l}\t{%k1, %k0|%k0, %k1}";
387      else
388          return "mov{w}\t{%1, %0|%0, %1}";
389
390    case TYPE_IMOVX:
391      /* movzwl is faster than movw on p2 due to partial word stalls,
392           though not as fast as an aligned movl.  */
393      return "movz{wl|x}\t{%1, %k0|%k0, %1}";
394
395    case TYPE_SSELOG1:
396      if (satisfies_constraint_C (operands[1]))
397          return standard_sse_constant_opcode (insn, operands);
398
399      if (SSE_REG_P (operands[0]))
400          return "%vpinsrw\t{$0, %1, %d0|%d0, %1, 0}";
401      else
402          return "%vpextrw\t{$0, %1, %0|%0, %1, 0}";
403
404    case TYPE_SSEMOV:
405      return ix86_output_ssemov (insn, operands);
406
407    default:
408      gcc_unreachable ();
409    }
410}
411  [(set (attr "isa")
412          (cond [(eq_attr "alternative" "6,8,9")
413                      (const_string "sse2")
414                 (eq_attr "alternative" "7")
415                      (const_string "sse4")
416                 ]
417                 (const_string "*")))
418   (set (attr "type")
419     (cond [(eq_attr "alternative" "6,7")
420                (if_then_else (match_test "TARGET_AVX512FP16")
421                    (const_string "ssemov")
422                    (const_string "sselog1"))
423              (eq_attr "alternative" "4")
424                (const_string "sselog1")
425              (eq_attr "alternative" "5,8,9")
426                (const_string "ssemov")
427              (match_test "optimize_function_for_size_p (cfun)")
428                (const_string "imov")
429              (and (eq_attr "alternative" "0")
430                     (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
431                          (not (match_test "TARGET_HIMODE_MATH"))))
432                (const_string "imov")
433              (and (eq_attr "alternative" "1,2")
434                     (match_operand:V2QI 1 "aligned_operand"))
435                (const_string "imov")
436              (and (match_test "TARGET_MOVX")
437                     (eq_attr "alternative" "0,2"))
438                (const_string "imovx")
439             ]
440             (const_string "imov")))
441   (set (attr "prefix")
442          (cond [(eq_attr "alternative" "4,5,6,7,8,9")
443                     (const_string "maybe_evex")
444                ]
445                (const_string "orig")))
446   (set (attr "mode")
447     (cond [(eq_attr "alternative" "6,7")
448                (if_then_else (match_test "TARGET_AVX512FP16")
449                    (const_string "HI")
450                    (const_string "TI"))
451              (eq_attr "alternative" "8,9")
452                (if_then_else (match_test "TARGET_AVX512FP16")
453                    (const_string "HI")
454                    (const_string "SI"))
455              (eq_attr "alternative" "4")
456                (cond [(match_test "TARGET_AVX")
457                           (const_string "TI")
458                         (ior (not (match_test "TARGET_SSE2"))
459                                (match_test "optimize_function_for_size_p (cfun)"))
460                           (const_string "V4SF")
461                        ]
462                        (const_string "TI"))
463              (eq_attr "alternative" "5")
464                (cond [(match_test "TARGET_AVX512FP16")
465                           (const_string "HF")
466                         (match_test "TARGET_AVX")
467                           (const_string "TI")
468                         (ior (not (match_test "TARGET_SSE2"))
469                                (match_test "optimize_function_for_size_p (cfun)"))
470                           (const_string "V4SF")
471                        ]
472                        (const_string "TI"))
473              (eq_attr "type" "imovx")
474                (const_string "SI")
475              (and (eq_attr "alternative" "1,2")
476                     (match_operand:V2QI 1 "aligned_operand"))
477                (const_string "SI")
478              (and (eq_attr "alternative" "0")
479                     (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
480                          (not (match_test "TARGET_HIMODE_MATH"))))
481                (const_string "SI")
482              ]
483              (const_string "HI")))
484   (set (attr "preferred_for_speed")
485     (cond [(eq_attr "alternative" "8")
486                (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
487              (eq_attr "alternative" "9")
488                (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
489             ]
490             (symbol_ref "true")))])
491
492;; We always round up to UNITS_PER_WORD bytes.
493(define_insn "*pushv2qi2"
494  [(set (match_operand:V2QI 0 "push_operand" "=X,X")
495          (match_operand:V2QI 1 "nonmemory_no_elim_operand" "rC,v"))]
496  ""
497  "* return TARGET_64BIT ? \"push{q}\t%q1\" : \"push{l}\t%k1\";
498   #"
499  [(set_attr "isa" "*,sse4")
500   (set_attr "type" "push,multi")
501   (set (attr "mode")
502     (cond [(eq_attr "alternative" "0")
503                (if_then_else (match_test "TARGET_64BIT")
504                    (const_string "DI")
505                    (const_string "SI"))
506              (eq_attr "alternative" "1")
507                (if_then_else (match_test "TARGET_AVX512FP16")
508                    (const_string "HI")
509                    (const_string "TI"))
510             ]
511             (const_string "HI")))])
512
513(define_split
514  [(set (match_operand:V2QI 0 "push_operand")
515          (match_operand:V2QI 1 "sse_reg_operand"))]
516  "TARGET_SSE4_1 && reload_completed"
517  [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
518   (set (match_dup 0) (match_dup 1))]
519{
520  operands[2] = GEN_INT (-PUSH_ROUNDING (GET_MODE_SIZE (V2QImode)));
521  /* Preserve memory attributes. */
522  operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
523})
524
525(define_expand "movmisalignv2qi"
526  [(set (match_operand:V2QI 0 "nonimmediate_operand")
527          (match_operand:V2QI 1 "nonimmediate_operand"))]
528  ""
529{
530  ix86_expand_vector_move (V2QImode, operands);
531  DONE;
532})
533
534(define_insn "sse_movntq"
535  [(set (match_operand:DI 0 "memory_operand" "=m,m")
536          (unspec:DI [(match_operand:DI 1 "register_operand" "y,r")]
537                       UNSPEC_MOVNTQ))]
538  "(TARGET_MMX || TARGET_MMX_WITH_SSE)
539   && (TARGET_SSE || TARGET_3DNOW_A)"
540  "@
541   movntq\t{%1, %0|%0, %1}
542   movnti\t{%1, %0|%0, %1}"
543  [(set_attr "isa" "*,x64")
544   (set_attr "mmx_isa" "native,*")
545   (set_attr "type" "mmxmov,ssemov")
546   (set_attr "mode" "DI")])
547
548;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
549;;
550;; Parallel single-precision floating point arithmetic
551;;
552;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
553
554(define_expand "<code>v2sf2"
555  [(set (match_operand:V2SF 0 "register_operand")
556          (absneg:V2SF
557            (match_operand:V2SF 1 "register_operand")))]
558  "TARGET_MMX_WITH_SSE"
559  "ix86_expand_fp_absneg_operator (<CODE>, V2SFmode, operands); DONE;")
560
561(define_insn_and_split "*mmx_<code>v2sf2"
562  [(set (match_operand:V2SF 0 "register_operand" "=x,x,x")
563          (absneg:V2SF
564            (match_operand:V2SF 1 "register_operand" "0,x,x")))
565   (use (match_operand:V2SF 2 "nonimmediate_operand" "x,0,x"))]
566  "TARGET_MMX_WITH_SSE"
567  "#"
568  "&& reload_completed"
569  [(set (match_dup 0)
570          (<absneg_op>:V2SF (match_dup 1) (match_dup 2)))]
571{
572  if (!TARGET_AVX && operands_match_p (operands[0], operands[2]))
573    std::swap (operands[1], operands[2]);
574}
575  [(set_attr "isa" "noavx,noavx,avx")])
576
577(define_insn_and_split "*mmx_nabsv2sf2"
578  [(set (match_operand:V2SF 0 "register_operand" "=x,x,x")
579          (neg:V2SF
580            (abs:V2SF
581              (match_operand:V2SF 1 "register_operand" "0,x,x"))))
582   (use (match_operand:V2SF 2 "nonimmediate_operand" "x,0,x"))]
583  "TARGET_MMX_WITH_SSE"
584  "#"
585  "&& reload_completed"
586  [(set (match_dup 0)
587          (ior:V2SF (match_dup 1) (match_dup 2)))]
588{
589  if (!TARGET_AVX && operands_match_p (operands[0], operands[2]))
590    std::swap (operands[1], operands[2]);
591}
592  [(set_attr "isa" "noavx,noavx,avx")])
593
594(define_expand "mmx_addv2sf3"
595  [(set (match_operand:V2SF 0 "register_operand")
596          (plus:V2SF
597            (match_operand:V2SF 1 "register_mmxmem_operand")
598            (match_operand:V2SF 2 "register_mmxmem_operand")))]
599  "TARGET_3DNOW"
600  "ix86_fixup_binary_operands_no_copy (PLUS, V2SFmode, operands);")
601
602(define_expand "addv2sf3"
603  [(set (match_operand:V2SF 0 "register_operand")
604          (plus:V2SF
605            (match_operand:V2SF 1 "register_operand")
606            (match_operand:V2SF 2 "register_operand")))]
607  "TARGET_MMX_WITH_SSE")
608
609(define_insn "*mmx_addv2sf3"
610  [(set (match_operand:V2SF 0 "register_operand" "=y,x,v")
611          (plus:V2SF
612            (match_operand:V2SF 1 "register_mmxmem_operand" "%0,0,v")
613            (match_operand:V2SF 2 "register_mmxmem_operand" "ym,x,v")))]
614  "(TARGET_3DNOW || TARGET_MMX_WITH_SSE)
615   && ix86_binary_operator_ok (PLUS, V2SFmode, operands)"
616  "@
617   pfadd\t{%2, %0|%0, %2}
618   addps\t{%2, %0|%0, %2}
619   vaddps\t{%2, %1, %0|%0, %1, %2}"
620  [(set_attr "isa" "*,sse2_noavx,avx")
621   (set_attr "mmx_isa" "native,*,*")
622   (set_attr "type" "mmxadd,sseadd,sseadd")
623   (set_attr "prefix_extra" "1,*,*")
624   (set_attr "prefix" "*,orig,vex")
625   (set_attr "mode" "V2SF,V4SF,V4SF")])
626
627(define_expand "mmx_subv2sf3"
628  [(set (match_operand:V2SF 0 "register_operand")
629        (minus:V2SF (match_operand:V2SF 1 "register_operand")
630                        (match_operand:V2SF 2 "register_mmxmem_operand")))]
631  "TARGET_3DNOW")
632
633(define_expand "mmx_subrv2sf3"
634  [(set (match_operand:V2SF 0 "register_operand")
635        (minus:V2SF (match_operand:V2SF 2 "register_operand")
636                        (match_operand:V2SF 1 "register_mmxmem_operand")))]
637  "TARGET_3DNOW")
638
639(define_expand "subv2sf3"
640  [(set (match_operand:V2SF 0 "register_operand")
641          (minus:V2SF
642            (match_operand:V2SF 1 "register_operand")
643            (match_operand:V2SF 2 "register_operand")))]
644  "TARGET_MMX_WITH_SSE")
645
646(define_insn "*mmx_subv2sf3"
647  [(set (match_operand:V2SF 0 "register_operand" "=y,y,x,v")
648        (minus:V2SF
649            (match_operand:V2SF 1 "register_mmxmem_operand" "0,ym,0,v")
650            (match_operand:V2SF 2 "register_mmxmem_operand" "ym,0,x,v")))]
651  "(TARGET_3DNOW || TARGET_MMX_WITH_SSE)
652   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
653  "@
654   pfsub\t{%2, %0|%0, %2}
655   pfsubr\t{%1, %0|%0, %1}
656   subps\t{%2, %0|%0, %2}
657   vsubps\t{%2, %1, %0|%0, %1, %2}"
658  [(set_attr "isa" "*,*,sse2_noavx,avx")
659   (set_attr "mmx_isa" "native,native,*,*")
660   (set_attr "type" "mmxadd,mmxadd,sseadd,sseadd")
661   (set_attr "prefix_extra" "1,1,*,*")
662   (set_attr "prefix" "*,*,orig,vex")
663   (set_attr "mode" "V2SF,V2SF,V4SF,V4SF")])
664
665(define_expand "mmx_mulv2sf3"
666  [(set (match_operand:V2SF 0 "register_operand")
667          (mult:V2SF (match_operand:V2SF 1 "register_mmxmem_operand")
668                       (match_operand:V2SF 2 "register_mmxmem_operand")))]
669  "TARGET_3DNOW"
670  "ix86_fixup_binary_operands_no_copy (MULT, V2SFmode, operands);")
671
672(define_expand "mulv2sf3"
673  [(set (match_operand:V2SF 0 "register_operand")
674          (mult:V2SF
675            (match_operand:V2SF 1 "register_operand")
676            (match_operand:V2SF 2 "register_operand")))]
677  "TARGET_MMX_WITH_SSE")
678
679(define_insn "*mmx_mulv2sf3"
680  [(set (match_operand:V2SF 0 "register_operand" "=y,x,v")
681          (mult:V2SF
682            (match_operand:V2SF 1 "register_mmxmem_operand" "%0,0,v")
683            (match_operand:V2SF 2 "register_mmxmem_operand" "ym,x,v")))]
684  "(TARGET_3DNOW || TARGET_MMX_WITH_SSE)
685   && ix86_binary_operator_ok (MULT, V2SFmode, operands)"
686  "@
687   pfmul\t{%2, %0|%0, %2}
688   mulps\t{%2, %0|%0, %2}
689   vmulps\t{%2, %1, %0|%0, %1, %2}"
690  [(set_attr "isa" "*,sse2_noavx,avx")
691   (set_attr "mmx_isa" "native,*,*")
692   (set_attr "type" "mmxmul,ssemul,ssemul")
693   (set_attr "btver2_decode" "*,direct,double")
694   (set_attr "prefix_extra" "1,*,*")
695   (set_attr "prefix" "*,orig,vex")
696   (set_attr "mode" "V2SF,V4SF,V4SF")])
697
698(define_expand "divv2sf3"
699  [(set (match_operand:V2SF 0 "register_operand")
700          (div:V2SF (match_operand:V2SF 1 "register_operand")
701                      (match_operand:V2SF 2 "register_operand")))]
702  "TARGET_MMX_WITH_SSE"
703{
704  rtx op1 = lowpart_subreg (V4SFmode, force_reg (V2SFmode, operands[1]),
705                                  V2SFmode);
706  rtx op2 = gen_rtx_VEC_CONCAT (V4SFmode, operands[2],
707                                        force_reg (V2SFmode, CONST1_RTX (V2SFmode)));
708  rtx tmp = gen_reg_rtx (V4SFmode);
709
710  emit_insn (gen_rtx_SET (tmp, op2));
711
712  rtx op0 = gen_reg_rtx (V4SFmode);
713
714  emit_insn (gen_divv4sf3 (op0, op1, tmp));
715
716  emit_move_insn (operands[0], lowpart_subreg (V2SFmode, op0, V4SFmode));
717  DONE;
718})
719
720(define_expand "mmx_<code>v2sf3"
721  [(set (match_operand:V2SF 0 "register_operand")
722        (smaxmin:V2SF
723            (match_operand:V2SF 1 "register_mmxmem_operand")
724            (match_operand:V2SF 2 "register_mmxmem_operand")))]
725  "TARGET_3DNOW"
726{
727  if (!flag_finite_math_only || flag_signed_zeros)
728    {
729      operands[1] = force_reg (V2SFmode, operands[1]);
730      emit_insn (gen_mmx_ieee_<maxmin_float>v2sf3
731                     (operands[0], operands[1], operands[2]));
732      DONE;
733    }
734  else
735    ix86_fixup_binary_operands_no_copy (<CODE>, V2SFmode, operands);
736})
737
738(define_expand "<code>v2sf3"
739  [(set (match_operand:V2SF 0 "register_operand")
740        (smaxmin:V2SF
741            (match_operand:V2SF 1 "register_operand")
742            (match_operand:V2SF 2 "register_operand")))]
743  "TARGET_MMX_WITH_SSE"
744{
745  if (!flag_finite_math_only || flag_signed_zeros)
746    {
747      emit_insn (gen_mmx_ieee_<maxmin_float>v2sf3
748                     (operands[0], operands[1], operands[2]));
749      DONE;
750    }
751})
752
753;; These versions of the min/max patterns are intentionally ignorant of
754;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
755;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
756;; are undefined in this condition, we're certain this is correct.
757
758(define_insn "*mmx_<code>v2sf3"
759  [(set (match_operand:V2SF 0 "register_operand" "=y,x,v")
760        (smaxmin:V2SF
761            (match_operand:V2SF 1 "register_mmxmem_operand" "%0,0,v")
762            (match_operand:V2SF 2 "register_mmxmem_operand" "ym,x,v")))]
763  "(TARGET_3DNOW || TARGET_MMX_WITH_SSE)
764   && ix86_binary_operator_ok (<CODE>, V2SFmode, operands)"
765  "@
766   pf<maxmin_float>\t{%2, %0|%0, %2}
767   <maxmin_float>ps\t{%2, %0|%0, %2}
768   v<maxmin_float>ps\t{%2, %1, %0|%0, %1, %2}"
769  [(set_attr "isa" "*,sse2_noavx,avx")
770   (set_attr "mmx_isa" "native,*,*")
771   (set_attr "type" "mmxadd,sseadd,sseadd")
772   (set_attr "btver2_sse_attr" "*,maxmin,maxmin")
773   (set_attr "prefix_extra" "1,*,*")
774   (set_attr "prefix" "*,orig,vex")
775   (set_attr "mode" "V2SF,V4SF,V4SF")])
776
777;; These versions of the min/max patterns implement exactly the operations
778;;   min = (op1 < op2 ? op1 : op2)
779;;   max = (!(op1 < op2) ? op1 : op2)
780;; Their operands are not commutative, and thus they may be used in the
781;; presence of -0.0 and NaN.
782
783(define_insn "mmx_ieee_<ieee_maxmin>v2sf3"
784  [(set (match_operand:V2SF 0 "register_operand" "=y,x,v")
785        (unspec:V2SF
786            [(match_operand:V2SF 1 "register_operand" "0,0,v")
787             (match_operand:V2SF 2 "register_mmxmem_operand" "ym,x,v")]
788            IEEE_MAXMIN))]
789  "TARGET_3DNOW || TARGET_MMX_WITH_SSE"
790  "@
791   pf<ieee_maxmin>\t{%2, %0|%0, %2}
792   <ieee_maxmin>ps\t{%2, %0|%0, %2}
793   v<ieee_maxmin>ps\t{%2, %1, %0|%0, %1, %2}"
794  [(set_attr "isa" "*,sse2_noavx,avx")
795   (set_attr "mmx_isa" "native,*,*")
796   (set_attr "type" "mmxadd,sseadd,sseadd")
797   (set_attr "btver2_sse_attr" "*,maxmin,maxmin")
798   (set_attr "prefix_extra" "1,*,*")
799   (set_attr "prefix" "*,orig,vex")
800   (set_attr "mode" "V2SF,V4SF,V4SF")])
801
802(define_insn "mmx_rcpv2sf2"
803  [(set (match_operand:V2SF 0 "register_operand" "=y")
804        (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
805                         UNSPEC_PFRCP))]
806  "TARGET_3DNOW"
807  "pfrcp\t{%1, %0|%0, %1}"
808  [(set_attr "type" "mmx")
809   (set_attr "prefix_extra" "1")
810   (set_attr "mode" "V2SF")])
811
812(define_insn "mmx_rcpit1v2sf3"
813  [(set (match_operand:V2SF 0 "register_operand" "=y")
814          (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
815                          (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
816                         UNSPEC_PFRCPIT1))]
817  "TARGET_3DNOW"
818  "pfrcpit1\t{%2, %0|%0, %2}"
819  [(set_attr "type" "mmx")
820   (set_attr "prefix_extra" "1")
821   (set_attr "mode" "V2SF")])
822
823(define_insn "mmx_rcpit2v2sf3"
824  [(set (match_operand:V2SF 0 "register_operand" "=y")
825          (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
826                          (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
827                         UNSPEC_PFRCPIT2))]
828  "TARGET_3DNOW"
829  "pfrcpit2\t{%2, %0|%0, %2}"
830  [(set_attr "type" "mmx")
831   (set_attr "prefix_extra" "1")
832   (set_attr "mode" "V2SF")])
833
834(define_insn "sqrtv2sf2"
835  [(set (match_operand:V2SF 0 "register_operand" "=x,v")
836          (sqrt:V2SF (match_operand:V2SF 1 "register_operand" "0,v")))]
837  "TARGET_MMX_WITH_SSE"
838  "@
839   sqrtps\t{%1, %0|%0, %1}
840   vsqrtps\t{%1, %0|%0, %1}"
841  [(set_attr "isa" "noavx,avx")
842   (set_attr "type" "sse")
843   (set_attr "atom_sse_attr" "sqrt")
844   (set_attr "btver2_sse_attr" "sqrt")
845   (set_attr "prefix" "orig,vex")
846   (set_attr "mode" "V4SF")])
847
848(define_insn "mmx_rsqrtv2sf2"
849  [(set (match_operand:V2SF 0 "register_operand" "=y")
850          (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
851                         UNSPEC_PFRSQRT))]
852  "TARGET_3DNOW"
853  "pfrsqrt\t{%1, %0|%0, %1}"
854  [(set_attr "type" "mmx")
855   (set_attr "prefix_extra" "1")
856   (set_attr "mode" "V2SF")])
857
858(define_insn "mmx_rsqit1v2sf3"
859  [(set (match_operand:V2SF 0 "register_operand" "=y")
860          (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
861                          (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
862                         UNSPEC_PFRSQIT1))]
863  "TARGET_3DNOW"
864  "pfrsqit1\t{%2, %0|%0, %2}"
865  [(set_attr "type" "mmx")
866   (set_attr "prefix_extra" "1")
867   (set_attr "mode" "V2SF")])
868
869(define_expand "mmx_haddv2sf3"
870  [(set (match_operand:V2SF 0 "register_operand")
871          (vec_concat:V2SF
872            (plus:SF
873              (vec_select:SF
874                (match_operand:V2SF 1 "register_operand")
875                (parallel [(const_int 0)]))
876              (vec_select:SF (match_dup 1) (parallel [(const_int 1)])))
877            (plus:SF
878              (vec_select:SF
879                (match_operand:V2SF 2 "nonimmediate_operand")
880                (parallel [(const_int 0)]))
881              (vec_select:SF (match_dup 2) (parallel [(const_int 1)])))))]
882  "TARGET_3DNOW")
883
884(define_insn "*mmx_haddv2sf3"
885  [(set (match_operand:V2SF 0 "register_operand" "=y")
886          (vec_concat:V2SF
887            (plus:SF
888              (vec_select:SF
889                (match_operand:V2SF 1 "register_operand" "0")
890                (parallel [(match_operand:SI 3 "const_0_to_1_operand")]))
891              (vec_select:SF (match_dup 1)
892              (parallel [(match_operand:SI 4 "const_0_to_1_operand")])))
893            (plus:SF
894            (vec_select:SF
895                (match_operand:V2SF 2 "nonimmediate_operand" "ym")
896                (parallel [(match_operand:SI 5 "const_0_to_1_operand")]))
897              (vec_select:SF (match_dup 2)
898              (parallel [(match_operand:SI 6 "const_0_to_1_operand")])))))]
899  "TARGET_3DNOW
900   && INTVAL (operands[3]) != INTVAL (operands[4])
901   && INTVAL (operands[5]) != INTVAL (operands[6])"
902  "pfacc\t{%2, %0|%0, %2}"
903  [(set_attr "type" "mmxadd")
904   (set_attr "prefix_extra" "1")
905   (set_attr "mode" "V2SF")])
906
907(define_insn "*mmx_haddv2sf3_low"
908  [(set (match_operand:SF 0 "register_operand" "=x,x")
909          (plus:SF
910            (vec_select:SF
911              (match_operand:V2SF 1 "register_operand" "0,x")
912              (parallel [(match_operand:SI 2 "const_0_to_1_operand")]))
913            (vec_select:SF
914              (match_dup 1)
915              (parallel [(match_operand:SI 3 "const_0_to_1_operand")]))))]
916  "TARGET_SSE3 && TARGET_MMX_WITH_SSE
917   && INTVAL (operands[2]) != INTVAL (operands[3])"
918  "@
919   haddps\t{%0, %0|%0, %0}
920   vhaddps\t{%1, %1, %0|%0, %1, %1}"
921  [(set_attr "isa" "noavx,avx")
922   (set_attr "type" "sseadd1")
923   (set_attr "prefix" "orig,vex")
924   (set_attr "mode" "V4SF")])
925
926(define_insn "mmx_hsubv2sf3"
927  [(set (match_operand:V2SF 0 "register_operand" "=y")
928          (vec_concat:V2SF
929            (minus:SF
930              (vec_select:SF
931                (match_operand:V2SF 1 "register_operand" "0")
932                (parallel [(const_int  0)]))
933              (vec_select:SF (match_dup 1) (parallel [(const_int 1)])))
934            (minus:SF
935            (vec_select:SF
936                (match_operand:V2SF 2 "nonimmediate_operand" "ym")
937                (parallel [(const_int  0)]))
938              (vec_select:SF (match_dup 2) (parallel [(const_int 1)])))))]
939  "TARGET_3DNOW_A"
940  "pfnacc\t{%2, %0|%0, %2}"
941  [(set_attr "type" "mmxadd")
942   (set_attr "prefix_extra" "1")
943   (set_attr "mode" "V2SF")])
944
945(define_insn "*mmx_hsubv2sf3_low"
946  [(set (match_operand:SF 0 "register_operand" "=x,x")
947          (minus:SF
948            (vec_select:SF
949              (match_operand:V2SF 1 "register_operand" "0,x")
950              (parallel [(const_int 0)]))
951            (vec_select:SF
952              (match_dup 1)
953              (parallel [(const_int 1)]))))]
954  "TARGET_SSE3 && TARGET_MMX_WITH_SSE"
955  "@
956   hsubps\t{%0, %0|%0, %0}
957   vhsubps\t{%1, %1, %0|%0, %1, %1}"
958  [(set_attr "isa" "noavx,avx")
959   (set_attr "type" "sseadd1")
960   (set_attr "prefix" "orig,vex")
961   (set_attr "mode" "V4SF")])
962
963(define_expand "mmx_haddsubv2sf3"
964  [(set (match_operand:V2SF 0 "register_operand")
965          (vec_concat:V2SF
966            (minus:SF
967              (vec_select:SF
968                (match_operand:V2SF 1 "register_operand")
969                (parallel [(const_int 0)]))
970              (vec_select:SF (match_dup 1) (parallel [(const_int 1)])))
971            (plus:SF
972              (vec_select:SF
973                (match_operand:V2SF 2 "nonimmediate_operand")
974                (parallel [(const_int 0)]))
975              (vec_select:SF (match_dup 2) (parallel [(const_int 1)])))))]
976  "TARGET_3DNOW_A")
977
978(define_insn "*mmx_haddsubv2sf3"
979  [(set (match_operand:V2SF 0 "register_operand" "=y")
980          (vec_concat:V2SF
981            (minus:SF
982              (vec_select:SF
983                (match_operand:V2SF 1 "register_operand" "0")
984                (parallel [(const_int  0)]))
985              (vec_select:SF (match_dup 1) (parallel [(const_int 1)])))
986            (plus:SF
987            (vec_select:SF
988                (match_operand:V2SF 2 "nonimmediate_operand" "ym")
989                (parallel [(match_operand:SI 3 "const_0_to_1_operand")]))
990              (vec_select:SF
991                (match_dup 2)
992                (parallel [(match_operand:SI 4 "const_0_to_1_operand")])))))]
993  "TARGET_3DNOW_A
994   && INTVAL (operands[3]) != INTVAL (operands[4])"
995  "pfpnacc\t{%2, %0|%0, %2}"
996  [(set_attr "type" "mmxadd")
997   (set_attr "prefix_extra" "1")
998   (set_attr "mode" "V2SF")])
999
1000(define_insn "vec_addsubv2sf3"
1001  [(set (match_operand:V2SF 0 "register_operand" "=x,x")
1002          (vec_merge:V2SF
1003            (minus:V2SF
1004              (match_operand:V2SF 1 "register_operand" "0,x")
1005              (match_operand:V2SF 2 "register_operand" "x,x"))
1006            (plus:V2SF (match_dup 1) (match_dup 2))
1007            (const_int 1)))]
1008  "TARGET_SSE3 && TARGET_MMX_WITH_SSE"
1009  "@
1010   addsubps\t{%2, %0|%0, %2}
1011   vaddsubps\t{%2, %1, %0|%0, %1, %2}"
1012  [(set_attr "isa" "noavx,avx")
1013   (set_attr "type" "sseadd")
1014   (set_attr "prefix" "orig,vex")
1015   (set_attr "prefix_rep" "1,*")
1016   (set_attr "mode" "V4SF")])
1017
1018;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1019;;
1020;; Parallel single-precision floating point comparisons
1021;;
1022;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1023
1024(define_expand "mmx_eqv2sf3"
1025  [(set (match_operand:V2SI 0 "register_operand")
1026          (eq:V2SI (match_operand:V2SF 1 "nonimmediate_operand")
1027                     (match_operand:V2SF 2 "nonimmediate_operand")))]
1028  "TARGET_3DNOW"
1029  "ix86_fixup_binary_operands_no_copy (EQ, V2SFmode, operands);")
1030
1031(define_insn "*mmx_eqv2sf3"
1032  [(set (match_operand:V2SI 0 "register_operand" "=y")
1033          (eq:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "%0")
1034                     (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
1035  "TARGET_3DNOW && ix86_binary_operator_ok (EQ, V2SFmode, operands)"
1036  "pfcmpeq\t{%2, %0|%0, %2}"
1037  [(set_attr "type" "mmxcmp")
1038   (set_attr "prefix_extra" "1")
1039   (set_attr "mode" "V2SF")])
1040
1041(define_insn "mmx_gtv2sf3"
1042  [(set (match_operand:V2SI 0 "register_operand" "=y")
1043          (gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
1044                     (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
1045  "TARGET_3DNOW"
1046  "pfcmpgt\t{%2, %0|%0, %2}"
1047  [(set_attr "type" "mmxcmp")
1048   (set_attr "prefix_extra" "1")
1049   (set_attr "mode" "V2SF")])
1050
1051(define_insn "mmx_gev2sf3"
1052  [(set (match_operand:V2SI 0 "register_operand" "=y")
1053          (ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
1054                     (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
1055  "TARGET_3DNOW"
1056  "pfcmpge\t{%2, %0|%0, %2}"
1057  [(set_attr "type" "mmxcmp")
1058   (set_attr "prefix_extra" "1")
1059   (set_attr "mode" "V2SF")])
1060
1061(define_insn "*mmx_maskcmpv2sf3_comm"
1062  [(set (match_operand:V2SF 0 "register_operand" "=x,x")
1063          (match_operator:V2SF 3 "sse_comparison_operator"
1064            [(match_operand:V2SF 1 "register_operand" "%0,x")
1065             (match_operand:V2SF 2 "register_operand" "x,x")]))]
1066  "TARGET_MMX_WITH_SSE
1067   && GET_RTX_CLASS (GET_CODE (operands[3])) == RTX_COMM_COMPARE"
1068  "@
1069   cmp%D3ps\t{%2, %0|%0, %2}
1070   vcmp%D3ps\t{%2, %1, %0|%0, %1, %2}"
1071  [(set_attr "isa" "noavx,avx")
1072   (set_attr "type" "ssecmp")
1073   (set_attr "length_immediate" "1")
1074   (set_attr "prefix" "orig,vex")
1075   (set_attr "mode" "V4SF")])
1076
1077(define_insn "*mmx_maskcmpv2sf3"
1078  [(set (match_operand:V2SF 0 "register_operand" "=x,x")
1079          (match_operator:V2SF 3 "sse_comparison_operator"
1080            [(match_operand:V2SF 1 "register_operand" "0,x")
1081             (match_operand:V2SF 2 "register_operand" "x,x")]))]
1082  "TARGET_MMX_WITH_SSE"
1083  "@
1084   cmp%D3ps\t{%2, %0|%0, %2}
1085   vcmp%D3ps\t{%2, %1, %0|%0, %1, %2}"
1086  [(set_attr "isa" "noavx,avx")
1087   (set_attr "type" "ssecmp")
1088   (set_attr "length_immediate" "1")
1089   (set_attr "prefix" "orig,vex")
1090   (set_attr "mode" "V4SF")])
1091
1092(define_expand "vec_cmpv2sfv2si"
1093  [(set (match_operand:V2SI 0 "register_operand")
1094          (match_operator:V2SI 1 ""
1095            [(match_operand:V2SF 2 "register_operand")
1096             (match_operand:V2SF 3 "register_operand")]))]
1097  "TARGET_MMX_WITH_SSE"
1098{
1099  bool ok = ix86_expand_fp_vec_cmp (operands);
1100  gcc_assert (ok);
1101  DONE;
1102})
1103
1104(define_expand "vcond<mode>v2sf"
1105  [(set (match_operand:V2FI 0 "register_operand")
1106          (if_then_else:V2FI
1107            (match_operator 3 ""
1108              [(match_operand:V2SF 4 "register_operand")
1109               (match_operand:V2SF 5 "register_operand")])
1110            (match_operand:V2FI 1)
1111            (match_operand:V2FI 2)))]
1112  "TARGET_MMX_WITH_SSE"
1113{
1114  bool ok = ix86_expand_fp_vcond (operands);
1115  gcc_assert (ok);
1116  DONE;
1117})
1118
1119(define_insn "mmx_blendvps"
1120  [(set (match_operand:V2SF 0 "register_operand" "=Yr,*x,x")
1121          (unspec:V2SF
1122            [(match_operand:V2SF 1 "register_operand" "0,0,x")
1123             (match_operand:V2SF 2 "register_operand" "Yr,*x,x")
1124             (match_operand:V2SF 3 "register_operand" "Yz,Yz,x")]
1125            UNSPEC_BLENDV))]
1126  "TARGET_SSE4_1 && TARGET_MMX_WITH_SSE"
1127  "@
1128   blendvps\t{%3, %2, %0|%0, %2, %3}
1129   blendvps\t{%3, %2, %0|%0, %2, %3}
1130   vblendvps\t{%3, %2, %1, %0|%0, %1, %2, %3}"
1131  [(set_attr "isa" "noavx,noavx,avx")
1132   (set_attr "type" "ssemov")
1133   (set_attr "length_immediate" "1")
1134   (set_attr "prefix_data16" "1,1,*")
1135   (set_attr "prefix_extra" "1")
1136   (set_attr "prefix" "orig,orig,vex")
1137   (set_attr "btver2_decode" "vector")
1138   (set_attr "mode" "V4SF")])
1139
1140;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1141;;
1142;; Parallel single-precision floating point logical operations
1143;;
1144;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1145
1146(define_insn "*mmx_andnotv2sf3"
1147  [(set (match_operand:V2SF 0 "register_operand" "=x,x")
1148          (and:V2SF
1149            (not:V2SF
1150              (match_operand:V2SF 1 "register_operand" "0,x"))
1151            (match_operand:V2SF 2 "register_operand" "x,x")))]
1152  "TARGET_MMX_WITH_SSE"
1153  "@
1154   andnps\t{%2, %0|%0, %2}
1155   vandnps\t{%2, %1, %0|%0, %1, %2}"
1156  [(set_attr "isa" "noavx,avx")
1157   (set_attr "type" "sselog")
1158   (set_attr "prefix" "orig,vex")
1159   (set_attr "mode" "V4SF")])
1160
1161(define_insn "<code>v2sf3"
1162  [(set (match_operand:V2SF 0 "register_operand" "=x,x")
1163          (any_logic:V2SF
1164            (match_operand:V2SF 1 "register_operand" "%0,x")
1165            (match_operand:V2SF 2 "register_operand" "x,x")))]
1166  "TARGET_MMX_WITH_SSE"
1167  "@
1168   <logic>ps\t{%2, %0|%0, %2}
1169   v<logic>ps\t{%2, %1, %0|%0, %1, %2}"
1170  [(set_attr "isa" "noavx,avx")
1171   (set_attr "type" "sselog")
1172   (set_attr "prefix" "orig,vex")
1173   (set_attr "mode" "V4SF")])
1174
1175(define_expand "copysignv2sf3"
1176  [(set (match_dup 4)
1177          (and:V2SF
1178            (not:V2SF (match_dup 3))
1179            (match_operand:V2SF 1 "register_operand")))
1180   (set (match_dup 5)
1181          (and:V2SF (match_dup 3)
1182                      (match_operand:V2SF 2 "register_operand")))
1183   (set (match_operand:V2SF 0 "register_operand")
1184          (ior:V2SF (match_dup 4) (match_dup 5)))]
1185  "TARGET_MMX_WITH_SSE"
1186{
1187  operands[3] = ix86_build_signbit_mask (V2SFmode, true, false);
1188
1189  operands[4] = gen_reg_rtx (V2SFmode);
1190  operands[5] = gen_reg_rtx (V2SFmode);
1191})
1192
1193(define_expand "xorsignv2sf3"
1194  [(set (match_dup 4)
1195          (and:V2SF (match_dup 3)
1196                      (match_operand:V2SF 2 "register_operand")))
1197   (set (match_operand:V2SF 0 "register_operand")
1198          (xor:V2SF (match_dup 4)
1199                      (match_operand:V2SF 1 "register_operand")))]
1200  "TARGET_MMX_WITH_SSE"
1201{
1202  operands[3] = ix86_build_signbit_mask (V2SFmode, true, false);
1203
1204  operands[4] = gen_reg_rtx (V2SFmode);
1205})
1206
1207(define_expand "signbitv2sf2"
1208  [(set (match_operand:V2SI 0 "register_operand")
1209          (lshiftrt:V2SI
1210            (subreg:V2SI
1211              (match_operand:V2SF 1 "register_operand") 0)
1212            (match_dup 2)))]
1213  "TARGET_MMX_WITH_SSE"
1214{
1215  operands[1] = force_reg (V2SFmode, operands[1]);
1216  operands[2] = GEN_INT (GET_MODE_UNIT_BITSIZE (V2SFmode)-1);
1217})
1218
1219;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1220;;
1221;; Parallel single-precision FMA multiply/accumulate instructions.
1222;;
1223;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1224
1225(define_insn "fmav2sf4"
1226  [(set (match_operand:V2SF 0 "register_operand" "=v,v,x")
1227          (fma:V2SF
1228            (match_operand:V2SF 1 "register_operand" "%0,v,x")
1229            (match_operand:V2SF 2 "register_operand" "v,v,x")
1230            (match_operand:V2SF 3 "register_operand" "v,0,x")))]
1231  "(TARGET_FMA || TARGET_FMA4 || TARGET_AVX512VL)
1232   && TARGET_MMX_WITH_SSE"
1233  "@
1234   vfmadd132ps\t{%2, %3, %0|%0, %3, %2}
1235   vfmadd231ps\t{%2, %1, %0|%0, %1, %2}
1236   vfmaddps\t{%3, %2, %1, %0|%0, %1, %2, %3}"
1237  [(set_attr "isa" "fma_or_avx512vl,fma_or_avx512vl,fma4")
1238   (set_attr "type" "ssemuladd")
1239   (set_attr "mode" "V4SF")])
1240
1241(define_insn "fmsv2sf4"
1242  [(set (match_operand:V2SF 0 "register_operand" "=v,v,x")
1243          (fma:V2SF
1244            (match_operand:V2SF   1 "register_operand" "%0,v,x")
1245            (match_operand:V2SF   2 "register_operand" "v,v,x")
1246            (neg:V2SF
1247              (match_operand:V2SF 3 "register_operand" "v,0,x"))))]
1248  "(TARGET_FMA || TARGET_FMA4 || TARGET_AVX512VL)
1249   && TARGET_MMX_WITH_SSE"
1250  "@
1251   vfmsub132ps\t{%2, %3, %0|%0, %3, %2}
1252   vfmsub231ps\t{%2, %1, %0|%0, %1, %2}
1253   vfmsubps\t{%3, %2, %1, %0|%0, %1, %2, %3}"
1254  [(set_attr "isa" "fma_or_avx512vl,fma_or_avx512vl,fma4")
1255   (set_attr "type" "ssemuladd")
1256   (set_attr "mode" "V4SF")])
1257
1258(define_insn "fnmav2sf4"
1259  [(set (match_operand:V2SF 0 "register_operand" "=v,v,x")
1260          (fma:V2SF
1261            (neg:V2SF
1262              (match_operand:V2SF 1 "register_operand" "%0,v,x"))
1263            (match_operand:V2SF   2 "register_operand" "v,v,x")
1264            (match_operand:V2SF   3 "register_operand" "v,0,x")))]
1265  "(TARGET_FMA || TARGET_FMA4 || TARGET_AVX512VL)
1266   && TARGET_MMX_WITH_SSE"
1267  "@
1268   vfnmadd132ps\t{%2, %3, %0|%0, %3, %2}
1269   vfnmadd231ps\t{%2, %1, %0|%0, %1, %2}
1270   vfnmaddps\t{%3, %2, %1, %0|%0, %1, %2, %3}"
1271  [(set_attr "isa" "fma_or_avx512vl,fma_or_avx512vl,fma4")
1272   (set_attr "type" "ssemuladd")
1273   (set_attr "mode" "V4SF")])
1274
1275(define_insn "fnmsv2sf4"
1276  [(set (match_operand:V2SF 0 "register_operand" "=v,v,x")
1277          (fma:V2SF
1278            (neg:V2SF
1279              (match_operand:V2SF 1 "register_operand" "%0,v,x"))
1280            (match_operand:V2SF   2 "register_operand" "v,v,x")
1281            (neg:V2SF
1282              (match_operand:V2SF 3 "register_operand" "v,0,x"))))]
1283  "(TARGET_FMA || TARGET_FMA4 || TARGET_AVX512VL)
1284   && TARGET_MMX_WITH_SSE"
1285  "@
1286   vfnmsub132ps\t{%2, %3, %0|%0, %3, %2}
1287   vfnmsub231ps\t{%2, %1, %0|%0, %1, %2}
1288   vfnmsubps\t{%3, %2, %1, %0|%0, %1, %2, %3}"
1289  [(set_attr "isa" "fma_or_avx512vl,fma_or_avx512vl,fma4")
1290   (set_attr "type" "ssemuladd")
1291   (set_attr "mode" "V4SF")])
1292
1293;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1294;;
1295;; Parallel single-precision floating point conversion operations
1296;;
1297;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1298
1299(define_insn "mmx_fix_truncv2sfv2si2"
1300  [(set (match_operand:V2SI 0 "register_operand" "=y,Yv")
1301          (fix:V2SI (match_operand:V2SF 1 "register_mmxmem_operand" "ym,Yv")))]
1302  "TARGET_3DNOW || TARGET_MMX_WITH_SSE"
1303  "@
1304   pf2id\t{%1, %0|%0, %1}
1305   %vcvttps2dq\t{%1, %0|%0, %1}"
1306  [(set_attr "isa" "*,sse2")
1307   (set_attr "mmx_isa" "native,*")
1308   (set_attr "type" "mmxcvt,ssecvt")
1309   (set_attr "prefix_extra" "1,*")
1310   (set_attr "prefix_rep" "*,1")
1311   (set_attr "prefix_data16" "*,0")
1312   (set_attr "prefix" "*,maybe_vex")
1313   (set_attr "mode" "V2SF,TI")])
1314
1315(define_expand "fix_truncv2sfv2si2"
1316  [(set (match_operand:V2SI 0 "register_operand")
1317          (fix:V2SI (match_operand:V2SF 1 "register_operand")))]
1318  "TARGET_MMX_WITH_SSE")
1319
1320(define_insn "fixuns_truncv2sfv2si2"
1321  [(set (match_operand:V2SI 0 "register_operand" "=v")
1322          (unsigned_fix:V2SI (match_operand:V2SF 1 "register_operand" "v")))]
1323  "TARGET_AVX512VL && TARGET_MMX_WITH_SSE"
1324  "vcvttps2udq\t{%1, %0|%0, %1}"
1325  [(set_attr "type" "ssecvt")
1326   (set_attr "prefix" "evex")
1327   (set_attr "mode" "TI")])
1328
1329(define_insn "mmx_floatv2siv2sf2"
1330  [(set (match_operand:V2SF 0 "register_operand" "=y,Yv")
1331          (float:V2SF (match_operand:V2SI 1 "register_mmxmem_operand" "ym,Yv")))]
1332  "TARGET_3DNOW || TARGET_MMX_WITH_SSE"
1333  "@
1334   pi2fd\t{%1, %0|%0, %1}
1335   %vcvtdq2ps\t{%1, %0|%0, %1}"
1336  [(set_attr "isa" "*,sse2")
1337   (set_attr "mmx_isa" "native,*")
1338   (set_attr "type" "mmxcvt,ssecvt")
1339   (set_attr "prefix_extra" "1")
1340   (set_attr "prefix" "*,maybe_vex")
1341   (set_attr "mode" "V2SF,V4SF")])
1342
1343(define_expand "floatv2siv2sf2"
1344  [(set (match_operand:V2SF 0 "register_operand")
1345          (float:V2SF (match_operand:V2SI 1 "register_operand")))]
1346  "TARGET_MMX_WITH_SSE")
1347
1348(define_insn "floatunsv2siv2sf2"
1349  [(set (match_operand:V2SF 0 "register_operand" "=v")
1350          (unsigned_float:V2SF (match_operand:V2SI 1 "register_operand" "v")))]
1351  "TARGET_AVX512VL && TARGET_MMX_WITH_SSE"
1352  "vcvtudq2ps\t{%1, %0|%0, %1}"
1353  [(set_attr "type" "ssecvt")
1354   (set_attr "prefix" "evex")
1355   (set_attr "mode" "V4SF")])
1356
1357(define_insn "mmx_pf2iw"
1358  [(set (match_operand:V2SI 0 "register_operand" "=y")
1359          (sign_extend:V2SI
1360            (ss_truncate:V2HI
1361              (fix:V2SI
1362                (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
1363  "TARGET_3DNOW_A"
1364  "pf2iw\t{%1, %0|%0, %1}"
1365  [(set_attr "type" "mmxcvt")
1366   (set_attr "prefix_extra" "1")
1367   (set_attr "mode" "V2SF")])
1368
1369(define_insn "mmx_pi2fw"
1370  [(set (match_operand:V2SF 0 "register_operand" "=y")
1371          (float:V2SF
1372            (sign_extend:V2SI
1373              (truncate:V2HI
1374                (match_operand:V2SI 1 "nonimmediate_operand" "ym")))))]
1375  "TARGET_3DNOW_A"
1376  "pi2fw\t{%1, %0|%0, %1}"
1377  [(set_attr "type" "mmxcvt")
1378   (set_attr "prefix_extra" "1")
1379   (set_attr "mode" "V2SF")])
1380
1381;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1382;;
1383;; Parallel single-precision floating point element swizzling
1384;;
1385;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1386
1387(define_insn "mmx_pswapdv2sf2"
1388  [(set (match_operand:V2SF 0 "register_operand" "=y,x,Yv")
1389          (vec_select:V2SF
1390            (match_operand:V2SF 1 "register_mmxmem_operand" "ym,0,Yv")
1391            (parallel [(const_int 1) (const_int 0)])))]
1392  "TARGET_3DNOW_A || TARGET_MMX_WITH_SSE"
1393  "@
1394   pswapd\t{%1, %0|%0, %1}
1395   shufps\t{$0xe1, %1, %0|%0, %1, 0xe1}
1396   vshufps\t{$0xe1, %1, %1, %0|%0, %1, %1, 0xe1}"
1397  [(set_attr "isa" "*,sse_noavx,avx")
1398   (set_attr "mmx_isa" "native,*,*")
1399   (set_attr "type" "mmxcvt,ssemov,ssemov")
1400   (set_attr "prefix_extra" "1,*,*")
1401   (set_attr "mode" "V2SF,V4SF,V4SF")])
1402
1403(define_insn "*mmx_movshdup"
1404  [(set (match_operand:V2SF 0 "register_operand" "=v,x")
1405          (vec_select:V2SF
1406            (match_operand:V2SF 1 "register_operand" "v,0")
1407            (parallel [(const_int 1) (const_int 1)])))]
1408  "TARGET_MMX_WITH_SSE"
1409  "@
1410   %vmovshdup\t{%1, %0|%0, %1}
1411   shufps\t{$0xe5, %0, %0|%0, %0, 0xe5}"
1412  [(set_attr "isa" "sse3,*")
1413   (set_attr "type" "sse,sseshuf1")
1414   (set_attr "length_immediate" "*,1")
1415   (set_attr "prefix_rep" "1,*")
1416   (set_attr "prefix" "maybe_vex,orig")
1417   (set_attr "mode" "V4SF")])
1418
1419(define_insn "*mmx_movsldup"
1420  [(set (match_operand:V2SF 0 "register_operand" "=v,x")
1421          (vec_select:V2SF
1422            (match_operand:V2SF 1 "register_operand" "v,0")
1423            (parallel [(const_int 0) (const_int 0)])))]
1424  "TARGET_MMX_WITH_SSE"
1425  "@
1426   %vmovsldup\t{%1, %0|%0, %1}
1427   shufps\t{$0xe0, %0, %0|%0, %0, 0xe0}"
1428  [(set_attr "isa" "sse3,*")
1429   (set_attr "type" "sse,sseshuf1")
1430   (set_attr "length_immediate" "*,1")
1431   (set_attr "prefix_rep" "1,*")
1432   (set_attr "prefix" "maybe_vex,orig")
1433   (set_attr "mode" "V4SF")])
1434
1435(define_insn_and_split "*vec_interleave_lowv2sf"
1436  [(set (match_operand:V2SF 0 "register_operand" "=x,v")
1437          (vec_select:V2SF
1438            (vec_concat:V4SF
1439              (match_operand:V2SF 1 "register_operand" "0,v")
1440              (match_operand:V2SF 2 "register_operand" "x,v"))
1441            (parallel [(const_int 0) (const_int 2)])))]
1442  "TARGET_MMX_WITH_SSE"
1443  "#"
1444  "&& reload_completed"
1445  [(const_int 0)]
1446  "ix86_split_mmx_punpck (operands, false); DONE;"
1447  [(set_attr "isa" "noavx,avx")
1448   (set_attr "type" "sselog")
1449   (set_attr "prefix" "orig,maybe_evex")
1450   (set_attr "mode" "V4SF")])
1451
1452(define_insn_and_split "*vec_interleave_highv2sf"
1453  [(set (match_operand:V2SF 0 "register_operand" "=x,v")
1454          (vec_select:V2SF
1455            (vec_concat:V4SF
1456              (match_operand:V2SF 1 "register_operand" "0,v")
1457              (match_operand:V2SF 2 "register_operand" "x,v"))
1458            (parallel [(const_int 1) (const_int 3)])))]
1459  "TARGET_MMX_WITH_SSE"
1460  "#"
1461  "&& reload_completed"
1462  [(const_int 0)]
1463  "ix86_split_mmx_punpck (operands, true); DONE;"
1464  [(set_attr "isa" "noavx,avx")
1465   (set_attr "type" "sselog")
1466   (set_attr "prefix" "orig,vex")
1467   (set_attr "mode" "V4SF")])
1468
1469(define_insn "*vec_dupv2sf"
1470  [(set (match_operand:V2SF 0 "register_operand" "=y,Yv,x")
1471          (vec_duplicate:V2SF
1472            (match_operand:SF 1 "register_operand" "0,Yv,0")))]
1473  "TARGET_MMX || TARGET_MMX_WITH_SSE"
1474  "@
1475   punpckldq\t%0, %0
1476   %vmovsldup\t{%1, %0|%0, %1}
1477   shufps\t{$0xe0, %0, %0|%0, %0, 0xe0}"
1478  [(set_attr "isa" "*,sse3,sse_noavx")
1479   (set_attr "mmx_isa" "native,*,*")
1480   (set_attr "type" "mmxcvt,sse,sseshuf1")
1481   (set_attr "length_immediate" "*,*,1")
1482   (set_attr "prefix_rep" "*,1,*")
1483   (set_attr "prefix" "*,maybe_vex,orig")
1484   (set_attr "mode" "DI,V4SF,V4SF")])
1485
1486(define_insn "*mmx_movss"
1487  [(set (match_operand:V2SF 0 "register_operand"   "=x,v")
1488          (vec_merge:V2SF
1489            (match_operand:V2SF 2 "register_operand" " x,v")
1490            (match_operand:V2SF 1 "register_operand" " 0,v")
1491            (const_int 1)))]
1492  "TARGET_MMX_WITH_SSE"
1493  "@
1494   movss\t{%2, %0|%0, %2}
1495   vmovss\t{%2, %1, %0|%0, %1, %2}"
1496  [(set_attr "isa" "noavx,avx")
1497   (set_attr "type" "ssemov")
1498   (set_attr "prefix" "orig,maybe_evex")
1499   (set_attr "mode" "SF")])
1500
1501(define_insn "*mmx_concatv2sf"
1502  [(set (match_operand:V2SF 0 "register_operand"     "=y,y")
1503          (vec_concat:V2SF
1504            (match_operand:SF 1 "nonimmediate_operand" " 0,rm")
1505            (match_operand:SF 2 "nonimm_or_0_operand"  "ym,C")))]
1506  "TARGET_MMX && !TARGET_SSE"
1507  "@
1508   punpckldq\t{%2, %0|%0, %2}
1509   movd\t{%1, %0|%0, %1}"
1510  [(set_attr "type" "mmxcvt,mmxmov")
1511   (set_attr "mode" "DI")])
1512
1513(define_expand "vec_setv2sf"
1514  [(match_operand:V2SF 0 "register_operand")
1515   (match_operand:SF 1 "register_operand")
1516   (match_operand 2 "vec_setm_mmx_operand")]
1517  "TARGET_MMX || TARGET_MMX_WITH_SSE"
1518{
1519  if (CONST_INT_P (operands[2]))
1520    ix86_expand_vector_set (TARGET_MMX_WITH_SSE, operands[0], operands[1],
1521                                  INTVAL (operands[2]));
1522  else
1523    ix86_expand_vector_set_var (operands[0], operands[1], operands[2]);
1524  DONE;
1525})
1526
1527;; Avoid combining registers from different units in a single alternative,
1528;; see comment above inline_secondary_memory_needed function in i386.cc
1529(define_insn_and_split "*vec_extractv2sf_0"
1530  [(set (match_operand:SF 0 "nonimmediate_operand"     "=x, m,y ,m,f,r")
1531          (vec_select:SF
1532            (match_operand:V2SF 1 "nonimmediate_operand" " xm,x,ym,y,m,m")
1533            (parallel [(const_int 0)])))]
1534  "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1535   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1536  "#"
1537  "&& reload_completed"
1538  [(set (match_dup 0) (match_dup 1))]
1539  "operands[1] = gen_lowpart (SFmode, operands[1]);"
1540  [(set_attr "mmx_isa" "*,*,native,native,*,*")])
1541
1542;; Avoid combining registers from different units in a single alternative,
1543;; see comment above inline_secondary_memory_needed function in i386.cc
1544(define_insn "*vec_extractv2sf_1"
1545  [(set (match_operand:SF 0 "nonimmediate_operand"     "=y,x,x,y,x,f,r")
1546          (vec_select:SF
1547            (match_operand:V2SF 1 "nonimmediate_operand" " 0,x,0,o,o,o,o")
1548            (parallel [(const_int 1)])))]
1549  "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1550   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1551  "@
1552   punpckhdq\t%0, %0
1553   %vmovshdup\t{%1, %0|%0, %1}
1554   shufps\t{$0xe5, %0, %0|%0, %0, 0xe5}
1555   #
1556   #
1557   #
1558   #"
1559  [(set_attr "isa" "*,sse3,noavx,*,*,*,*")
1560   (set_attr "mmx_isa" "native,*,*,native,*,*,*")
1561   (set_attr "type" "mmxcvt,sse,sseshuf1,mmxmov,ssemov,fmov,imov")
1562   (set (attr "length_immediate")
1563     (if_then_else (eq_attr "alternative" "2")
1564                       (const_string "1")
1565                       (const_string "*")))
1566   (set (attr "prefix_rep")
1567     (if_then_else (eq_attr "alternative" "1")
1568                       (const_string "1")
1569                       (const_string "*")))
1570   (set_attr "prefix" "orig,maybe_vex,orig,orig,orig,orig,orig")
1571   (set_attr "mode" "DI,V4SF,V4SF,SF,SF,SF,SF")])
1572
1573(define_split
1574  [(set (match_operand:SF 0 "register_operand")
1575          (vec_select:SF
1576            (match_operand:V2SF 1 "memory_operand")
1577            (parallel [(const_int 1)])))]
1578  "(TARGET_MMX || TARGET_MMX_WITH_SSE) && reload_completed"
1579  [(set (match_dup 0) (match_dup 1))]
1580  "operands[1] = adjust_address (operands[1], SFmode, 4);")
1581
1582(define_expand "vec_extractv2sfsf"
1583  [(match_operand:SF 0 "register_operand")
1584   (match_operand:V2SF 1 "register_operand")
1585   (match_operand 2 "const_int_operand")]
1586  "TARGET_MMX || TARGET_MMX_WITH_SSE"
1587{
1588  ix86_expand_vector_extract (TARGET_MMX_WITH_SSE, operands[0],
1589                                    operands[1], INTVAL (operands[2]));
1590  DONE;
1591})
1592
1593(define_expand "vec_initv2sfsf"
1594  [(match_operand:V2SF 0 "register_operand")
1595   (match_operand 1)]
1596  "(TARGET_MMX || TARGET_MMX_WITH_SSE) && TARGET_SSE"
1597{
1598  ix86_expand_vector_init (TARGET_MMX_WITH_SSE, operands[0],
1599                                 operands[1]);
1600  DONE;
1601})
1602
1603;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1604;;
1605;; Parallel half-precision floating point arithmetic
1606;;
1607;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1608
1609(define_insn "<insn><mode>3"
1610  [(set (match_operand:VHF_32_64 0 "register_operand" "=v")
1611          (plusminusmultdiv:VHF_32_64
1612            (match_operand:VHF_32_64 1 "register_operand" "<comm>v")
1613            (match_operand:VHF_32_64 2 "register_operand" "v")))]
1614  "TARGET_AVX512FP16 && TARGET_AVX512VL"
1615  "v<insn>ph\t{%2, %1, %0|%0, %1, %2}"
1616  [(set (attr "type")
1617      (cond [(match_test "<CODE> == MULT")
1618                    (const_string "ssemul")
1619               (match_test "<CODE> == DIV")
1620                    (const_string "ssediv")]
1621               (const_string "sseadd")))
1622   (set_attr "prefix" "evex")
1623   (set_attr "mode" "V8HF")])
1624
1625;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1626;;
1627;; Parallel integral arithmetic
1628;;
1629;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1630
1631(define_expand "neg<mode>2"
1632  [(set (match_operand:MMXMODEI 0 "register_operand")
1633          (minus:MMXMODEI
1634            (match_dup 2)
1635            (match_operand:MMXMODEI 1 "register_operand")))]
1636  "TARGET_MMX_WITH_SSE"
1637  "operands[2] = force_reg (<MODE>mode, CONST0_RTX (<MODE>mode));")
1638
1639(define_expand "neg<mode>2"
1640  [(set (match_operand:VI_32 0 "register_operand")
1641          (minus:VI_32
1642            (match_dup 2)
1643            (match_operand:VI_32 1 "register_operand")))]
1644  "TARGET_SSE2"
1645  "operands[2] = force_reg (<MODE>mode, CONST0_RTX (<MODE>mode));")
1646
1647(define_insn "negv2qi2"
1648  [(set (match_operand:V2QI 0 "register_operand" "=?Q,&Yw")
1649        (neg:V2QI
1650            (match_operand:V2QI 1 "register_operand" "0,Yw")))
1651   (clobber (reg:CC FLAGS_REG))]
1652  "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
1653  "#"
1654  [(set_attr "isa" "*,sse2")
1655   (set_attr "type" "multi")
1656   (set_attr "mode" "QI,TI")])
1657
1658(define_split
1659  [(set (match_operand:V2QI 0 "general_reg_operand")
1660        (neg:V2QI
1661            (match_operand:V2QI 1 "general_reg_operand")))
1662   (clobber (reg:CC FLAGS_REG))]
1663  "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
1664   && reload_completed"
1665  [(parallel
1666     [(set (strict_low_part (match_dup 0))
1667             (neg:QI (match_dup 1)))
1668      (clobber (reg:CC FLAGS_REG))])
1669   (parallel
1670     [(set (zero_extract:HI (match_dup 2) (const_int 8) (const_int 8))
1671             (subreg:HI
1672               (neg:QI
1673                 (subreg:QI
1674                   (zero_extract:HI (match_dup 3)
1675                                        (const_int 8)
1676                                          (const_int 8)) 0)) 0))
1677      (clobber (reg:CC FLAGS_REG))])]
1678{
1679  operands[3] = lowpart_subreg (HImode, operands[1], V2QImode);
1680  operands[2] = lowpart_subreg (HImode, operands[0], V2QImode);
1681  operands[1] = lowpart_subreg (QImode, operands[1], V2QImode);
1682  operands[0] = lowpart_subreg (QImode, operands[0], V2QImode);
1683})
1684
1685(define_split
1686  [(set (match_operand:V2QI 0 "sse_reg_operand")
1687        (neg:V2QI
1688            (match_operand:V2QI 1 "sse_reg_operand")))
1689   (clobber (reg:CC FLAGS_REG))]
1690  "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
1691   && TARGET_SSE2 && reload_completed"
1692  [(set (match_dup 0) (match_dup 2))
1693   (set (match_dup 0)
1694          (minus:V16QI (match_dup 0) (match_dup 1)))]
1695{
1696  operands[2] = CONST0_RTX (V16QImode);
1697  operands[1] = lowpart_subreg (V16QImode, operands[1], V2QImode);
1698  operands[0] = lowpart_subreg (V16QImode, operands[0], V2QImode);
1699})
1700
1701(define_expand "mmx_<insn><mode>3"
1702  [(set (match_operand:MMXMODEI8 0 "register_operand")
1703          (plusminus:MMXMODEI8
1704            (match_operand:MMXMODEI8 1 "register_mmxmem_operand")
1705            (match_operand:MMXMODEI8 2 "register_mmxmem_operand")))]
1706  "TARGET_MMX || TARGET_MMX_WITH_SSE"
1707  "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
1708
1709(define_expand "<insn><mode>3"
1710  [(set (match_operand:MMXMODEI 0 "register_operand")
1711          (plusminus:MMXMODEI
1712            (match_operand:MMXMODEI 1 "register_operand")
1713            (match_operand:MMXMODEI 2 "register_operand")))]
1714  "TARGET_MMX_WITH_SSE")
1715
1716(define_insn "*mmx_<insn><mode>3"
1717  [(set (match_operand:MMXMODEI8 0 "register_operand" "=y,x,<Yv_Yw>")
1718        (plusminus:MMXMODEI8
1719            (match_operand:MMXMODEI8 1 "register_mmxmem_operand"
1720              "<comm>0,0,<Yv_Yw>")
1721            (match_operand:MMXMODEI8 2 "register_mmxmem_operand"
1722              "ym,x,<Yv_Yw>")))]
1723  "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1724   && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
1725  "@
1726   p<plusminus_mnemonic><mmxvecsize>\t{%2, %0|%0, %2}
1727   p<plusminus_mnemonic><mmxvecsize>\t{%2, %0|%0, %2}
1728   vp<plusminus_mnemonic><mmxvecsize>\t{%2, %1, %0|%0, %1, %2}"
1729  [(set_attr "isa" "*,sse2_noavx,avx")
1730   (set_attr "mmx_isa" "native,*,*")
1731   (set_attr "type" "mmxadd,sseadd,sseadd")
1732   (set_attr "mode" "DI,TI,TI")])
1733
1734(define_insn "<insn><mode>3"
1735  [(set (match_operand:VI_32 0 "register_operand" "=x,Yw")
1736        (plusminus:VI_32
1737            (match_operand:VI_32 1 "register_operand" "<comm>0,Yw")
1738            (match_operand:VI_32 2 "register_operand" "x,Yw")))]
1739  "TARGET_SSE2"
1740  "@
1741   p<plusminus_mnemonic><mmxvecsize>\t{%2, %0|%0, %2}
1742   vp<plusminus_mnemonic><mmxvecsize>\t{%2, %1, %0|%0, %1, %2}"
1743  [(set_attr "isa" "noavx,avx")
1744   (set_attr "type" "sseadd")
1745   (set_attr "mode" "TI")])
1746
1747(define_insn "<insn>v2qi3"
1748  [(set (match_operand:V2QI 0 "register_operand" "=?Q,x,Yw")
1749        (plusminus:V2QI
1750            (match_operand:V2QI 1 "register_operand" "<comm>0,0,Yw")
1751            (match_operand:V2QI 2 "register_operand" "Q,x,Yw")))
1752   (clobber (reg:CC FLAGS_REG))]
1753  "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
1754  "#"
1755  [(set_attr "isa" "*,sse2_noavx,avx")
1756   (set_attr "type" "multi,sseadd,sseadd")
1757   (set_attr "mode" "QI,TI,TI")])
1758
1759(define_split
1760  [(set (match_operand:V2QI 0 "general_reg_operand")
1761        (plusminus:V2QI
1762            (match_operand:V2QI 1 "general_reg_operand")
1763            (match_operand:V2QI 2 "general_reg_operand")))
1764   (clobber (reg:CC FLAGS_REG))]
1765  "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
1766   && reload_completed"
1767  [(parallel
1768     [(set (strict_low_part (match_dup 0))
1769             (plusminus:QI (match_dup 1) (match_dup 2)))
1770      (clobber (reg:CC FLAGS_REG))])
1771   (parallel
1772     [(set (zero_extract:HI (match_dup 3) (const_int 8) (const_int 8))
1773             (subreg:HI
1774               (plusminus:QI
1775                 (subreg:QI
1776                   (zero_extract:HI (match_dup 4)
1777                                        (const_int 8)
1778                                          (const_int 8)) 0)
1779                 (subreg:QI
1780                   (zero_extract:HI (match_dup 5)
1781                                          (const_int 8)
1782                                          (const_int 8)) 0)) 0))
1783      (clobber (reg:CC FLAGS_REG))])]
1784{
1785  operands[5] = lowpart_subreg (HImode, operands[2], V2QImode);
1786  operands[4] = lowpart_subreg (HImode, operands[1], V2QImode);
1787  operands[3] = lowpart_subreg (HImode, operands[0], V2QImode);
1788  operands[2] = lowpart_subreg (QImode, operands[2], V2QImode);
1789  operands[1] = lowpart_subreg (QImode, operands[1], V2QImode);
1790  operands[0] = lowpart_subreg (QImode, operands[0], V2QImode);
1791})
1792
1793(define_split
1794  [(set (match_operand:V2QI 0 "sse_reg_operand")
1795        (plusminus:V2QI
1796            (match_operand:V2QI 1 "sse_reg_operand")
1797            (match_operand:V2QI 2 "sse_reg_operand")))
1798   (clobber (reg:CC FLAGS_REG))]
1799  "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
1800   && TARGET_SSE2 && reload_completed"
1801  [(set (match_dup 0)
1802        (plusminus:V16QI (match_dup 1) (match_dup 2)))]
1803{
1804  operands[2] = lowpart_subreg (V16QImode, operands[2], V2QImode);
1805  operands[1] = lowpart_subreg (V16QImode, operands[1], V2QImode);
1806  operands[0] = lowpart_subreg (V16QImode, operands[0], V2QImode);
1807})
1808
1809(define_expand "mmx_<insn><mode>3"
1810  [(set (match_operand:MMXMODE12 0 "register_operand")
1811          (sat_plusminus:MMXMODE12
1812            (match_operand:MMXMODE12 1 "register_mmxmem_operand")
1813            (match_operand:MMXMODE12 2 "register_mmxmem_operand")))]
1814  "TARGET_MMX || TARGET_MMX_WITH_SSE"
1815  "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
1816
1817(define_insn "*mmx_<insn><mode>3"
1818  [(set (match_operand:MMXMODE12 0 "register_operand" "=y,x,Yw")
1819        (sat_plusminus:MMXMODE12
1820            (match_operand:MMXMODE12 1 "register_mmxmem_operand" "<comm>0,0,Yw")
1821            (match_operand:MMXMODE12 2 "register_mmxmem_operand" "ym,x,Yw")))]
1822  "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1823   && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
1824  "@
1825   p<plusminus_mnemonic><mmxvecsize>\t{%2, %0|%0, %2}
1826   p<plusminus_mnemonic><mmxvecsize>\t{%2, %0|%0, %2}
1827   vp<plusminus_mnemonic><mmxvecsize>\t{%2, %1, %0|%0, %1, %2}"
1828  [(set_attr "isa" "*,sse2_noavx,avx")
1829   (set_attr "mmx_isa" "native,*,*")
1830   (set_attr "type" "mmxadd,sseadd,sseadd")
1831   (set_attr "mode" "DI,TI,TI")])
1832
1833(define_insn "*<insn><mode>3"
1834  [(set (match_operand:VI_16_32 0 "register_operand" "=x,Yw")
1835        (sat_plusminus:VI_16_32
1836            (match_operand:VI_16_32 1 "register_operand" "<comm>0,Yw")
1837            (match_operand:VI_16_32 2 "register_operand" "x,Yw")))]
1838  "TARGET_SSE2"
1839  "@
1840   p<plusminus_mnemonic><mmxvecsize>\t{%2, %0|%0, %2}
1841   vp<plusminus_mnemonic><mmxvecsize>\t{%2, %1, %0|%0, %1, %2}"
1842  [(set_attr "isa" "noavx,avx")
1843   (set_attr "type" "sseadd")
1844   (set_attr "mode" "TI")])
1845
1846(define_expand "mmx_mulv4hi3"
1847  [(set (match_operand:V4HI 0 "register_operand")
1848        (mult:V4HI (match_operand:V4HI 1 "register_mmxmem_operand")
1849                       (match_operand:V4HI 2 "register_mmxmem_operand")))]
1850  "TARGET_MMX || TARGET_MMX_WITH_SSE"
1851  "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
1852
1853(define_expand "mulv4hi3"
1854  [(set (match_operand:V4HI 0 "register_operand")
1855        (mult:V4HI (match_operand:V4HI 1 "register_operand")
1856                       (match_operand:V4HI 2 "register_operand")))]
1857  "TARGET_MMX_WITH_SSE")
1858
1859(define_insn "*mmx_mulv4hi3"
1860  [(set (match_operand:V4HI 0 "register_operand" "=y,x,Yw")
1861        (mult:V4HI (match_operand:V4HI 1 "register_mmxmem_operand" "%0,0,Yw")
1862                       (match_operand:V4HI 2 "register_mmxmem_operand" "ym,x,Yw")))]
1863  "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1864   && ix86_binary_operator_ok (MULT, V4HImode, operands)"
1865  "@
1866   pmullw\t{%2, %0|%0, %2}
1867   pmullw\t{%2, %0|%0, %2}
1868   vpmullw\t{%2, %1, %0|%0, %1, %2}"
1869  [(set_attr "isa" "*,sse2_noavx,avx")
1870   (set_attr "mmx_isa" "native,*,*")
1871   (set_attr "type" "mmxmul,ssemul,ssemul")
1872   (set_attr "mode" "DI,TI,TI")])
1873
1874(define_insn "mulv2hi3"
1875  [(set (match_operand:V2HI 0 "register_operand" "=x,Yw")
1876        (mult:V2HI (match_operand:V2HI 1 "register_operand" "%0,Yw")
1877                       (match_operand:V2HI 2 "register_operand" "x,Yw")))]
1878  "TARGET_SSE2"
1879  "@
1880   pmullw\t{%2, %0|%0, %2}
1881   vpmullw\t{%2, %1, %0|%0, %1, %2}"
1882  [(set_attr "isa" "noavx,avx")
1883   (set_attr "type" "ssemul")
1884   (set_attr "mode" "TI")])
1885
1886(define_expand "mmx_smulv4hi3_highpart"
1887  [(set (match_operand:V4HI 0 "register_operand")
1888          (truncate:V4HI
1889            (lshiftrt:V4SI
1890              (mult:V4SI
1891                (sign_extend:V4SI
1892                    (match_operand:V4HI 1 "register_mmxmem_operand"))
1893                (sign_extend:V4SI
1894                    (match_operand:V4HI 2 "register_mmxmem_operand")))
1895              (const_int 16))))]
1896  "TARGET_MMX || TARGET_MMX_WITH_SSE"
1897  "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
1898
1899(define_insn "*mmx_smulv4hi3_highpart"
1900  [(set (match_operand:V4HI 0 "register_operand" "=y,x,Yw")
1901          (truncate:V4HI
1902            (lshiftrt:V4SI
1903              (mult:V4SI
1904                (sign_extend:V4SI
1905                    (match_operand:V4HI 1 "register_mmxmem_operand" "%0,0,Yw"))
1906                (sign_extend:V4SI
1907                    (match_operand:V4HI 2 "register_mmxmem_operand" "ym,x,Yw")))
1908              (const_int 16))))]
1909  "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1910   && ix86_binary_operator_ok (MULT, V4HImode, operands)"
1911  "@
1912   pmulhw\t{%2, %0|%0, %2}
1913   pmulhw\t{%2, %0|%0, %2}
1914   vpmulhw\t{%2, %1, %0|%0, %1, %2}"
1915  [(set_attr "isa" "*,sse2_noavx,avx")
1916   (set_attr "mmx_isa" "native,*,*")
1917   (set_attr "type" "mmxmul,ssemul,ssemul")
1918   (set_attr "mode" "DI,TI,TI")])
1919
1920(define_expand "mmx_umulv4hi3_highpart"
1921  [(set (match_operand:V4HI 0 "register_operand")
1922          (truncate:V4HI
1923            (lshiftrt:V4SI
1924              (mult:V4SI
1925                (zero_extend:V4SI
1926                    (match_operand:V4HI 1 "register_mmxmem_operand"))
1927                (zero_extend:V4SI
1928                    (match_operand:V4HI 2 "register_mmxmem_operand")))
1929              (const_int 16))))]
1930  "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1931   && (TARGET_SSE || TARGET_3DNOW_A)"
1932  "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
1933
1934(define_insn "*mmx_umulv4hi3_highpart"
1935  [(set (match_operand:V4HI 0 "register_operand" "=y,x,Yw")
1936          (truncate:V4HI
1937            (lshiftrt:V4SI
1938              (mult:V4SI
1939                (zero_extend:V4SI
1940                    (match_operand:V4HI 1 "register_mmxmem_operand" "%0,0,Yw"))
1941                (zero_extend:V4SI
1942                    (match_operand:V4HI 2 "register_mmxmem_operand" "ym,x,Yw")))
1943            (const_int 16))))]
1944  "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1945   && (TARGET_SSE || TARGET_3DNOW_A)
1946   && ix86_binary_operator_ok (MULT, V4HImode, operands)"
1947  "@
1948   pmulhuw\t{%2, %0|%0, %2}
1949   pmulhuw\t{%2, %0|%0, %2}
1950   vpmulhuw\t{%2, %1, %0|%0, %1, %2}"
1951  [(set_attr "isa" "*,sse2_noavx,avx")
1952   (set_attr "mmx_isa" "native,*,*")
1953   (set_attr "type" "mmxmul,ssemul,ssemul")
1954   (set_attr "mode" "DI,TI,TI")])
1955
1956(define_expand "<s>mulv4hi3_highpart"
1957  [(set (match_operand:V4HI 0 "register_operand")
1958          (truncate:V4HI
1959            (lshiftrt:V4SI
1960              (mult:V4SI
1961                (any_extend:V4SI
1962                    (match_operand:V4HI 1 "register_operand"))
1963                (any_extend:V4SI
1964                    (match_operand:V4HI 2 "register_operand")))
1965              (const_int 16))))]
1966  "TARGET_MMX_WITH_SSE")
1967
1968(define_insn "<s>mulv2hi3_highpart"
1969  [(set (match_operand:V2HI 0 "register_operand" "=x,Yw")
1970          (truncate:V2HI
1971            (lshiftrt:V2SI
1972              (mult:V2SI
1973                (any_extend:V2SI
1974                    (match_operand:V2HI 1 "register_operand" "%0,Yw"))
1975                (any_extend:V2SI
1976                    (match_operand:V2HI 2 "register_operand" "x,Yw")))
1977              (const_int 16))))]
1978  "TARGET_SSE2"
1979  "@
1980   pmulh<u>w\t{%2, %0|%0, %2}
1981   vpmulh<u>w\t{%2, %1, %0|%0, %1, %2}"
1982  [(set_attr "isa" "noavx,avx")
1983   (set_attr "type" "ssemul")
1984   (set_attr "mode" "TI")])
1985
1986(define_expand "mmx_pmaddwd"
1987  [(set (match_operand:V2SI 0 "register_operand")
1988        (plus:V2SI
1989            (mult:V2SI
1990              (sign_extend:V2SI
1991                (vec_select:V2HI
1992                    (match_operand:V4HI 1 "register_mmxmem_operand")
1993                    (parallel [(const_int 0) (const_int 2)])))
1994              (sign_extend:V2SI
1995                (vec_select:V2HI
1996                    (match_operand:V4HI 2 "register_mmxmem_operand")
1997                    (parallel [(const_int 0) (const_int 2)]))))
1998            (mult:V2SI
1999              (sign_extend:V2SI
2000                (vec_select:V2HI (match_dup 1)
2001                    (parallel [(const_int 1) (const_int 3)])))
2002              (sign_extend:V2SI
2003                (vec_select:V2HI (match_dup 2)
2004                    (parallel [(const_int 1) (const_int 3)]))))))]
2005  "TARGET_MMX || TARGET_MMX_WITH_SSE"
2006  "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
2007
2008(define_insn "*mmx_pmaddwd"
2009  [(set (match_operand:V2SI 0 "register_operand" "=y,x,Yw")
2010        (plus:V2SI
2011            (mult:V2SI
2012              (sign_extend:V2SI
2013                (vec_select:V2HI
2014                    (match_operand:V4HI 1 "register_mmxmem_operand" "%0,0,Yw")
2015                    (parallel [(const_int 0) (const_int 2)])))
2016              (sign_extend:V2SI
2017                (vec_select:V2HI
2018                    (match_operand:V4HI 2 "register_mmxmem_operand" "ym,x,Yw")
2019                    (parallel [(const_int 0) (const_int 2)]))))
2020            (mult:V2SI
2021              (sign_extend:V2SI
2022                (vec_select:V2HI (match_dup 1)
2023                    (parallel [(const_int 1) (const_int 3)])))
2024              (sign_extend:V2SI
2025                (vec_select:V2HI (match_dup 2)
2026                    (parallel [(const_int 1) (const_int 3)]))))))]
2027  "(TARGET_MMX || TARGET_MMX_WITH_SSE)
2028   && ix86_binary_operator_ok (MULT, V4HImode, operands)"
2029  "@
2030   pmaddwd\t{%2, %0|%0, %2}
2031   pmaddwd\t{%2, %0|%0, %2}
2032   vpmaddwd\t{%2, %1, %0|%0, %1, %2}"
2033  [(set_attr "isa" "*,sse2_noavx,avx")
2034   (set_attr "mmx_isa" "native,*,*")
2035   (set_attr "type" "mmxmul,sseiadd,sseiadd")
2036   (set_attr "mode" "DI,TI,TI")])
2037
2038(define_expand "mmx_pmulhrwv4hi3"
2039  [(set (match_operand:V4HI 0 "register_operand")
2040          (truncate:V4HI
2041            (lshiftrt:V4SI
2042              (plus:V4SI
2043                (mult:V4SI
2044                  (sign_extend:V4SI
2045                      (match_operand:V4HI 1 "nonimmediate_operand"))
2046                  (sign_extend:V4SI
2047                      (match_operand:V4HI 2 "nonimmediate_operand")))
2048                (const_vector:V4SI [(const_int 32768) (const_int 32768)
2049                                          (const_int 32768) (const_int 32768)]))
2050              (const_int 16))))]
2051  "TARGET_3DNOW"
2052  "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
2053
2054(define_insn "*mmx_pmulhrwv4hi3"
2055  [(set (match_operand:V4HI 0 "register_operand" "=y")
2056          (truncate:V4HI
2057            (lshiftrt:V4SI
2058              (plus:V4SI
2059                (mult:V4SI
2060                  (sign_extend:V4SI
2061                      (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
2062                  (sign_extend:V4SI
2063                      (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
2064                (const_vector:V4SI [(const_int 32768) (const_int 32768)
2065                                          (const_int 32768) (const_int 32768)]))
2066              (const_int 16))))]
2067  "TARGET_3DNOW && ix86_binary_operator_ok (MULT, V4HImode, operands)"
2068  "pmulhrw\t{%2, %0|%0, %2}"
2069  [(set_attr "type" "mmxmul")
2070   (set_attr "prefix_extra" "1")
2071   (set_attr "mode" "DI")])
2072
2073(define_expand "sse2_umulv1siv1di3"
2074  [(set (match_operand:V1DI 0 "register_operand")
2075        (mult:V1DI
2076            (zero_extend:V1DI
2077              (vec_select:V1SI
2078                (match_operand:V2SI 1 "register_mmxmem_operand")
2079                (parallel [(const_int 0)])))
2080            (zero_extend:V1DI
2081              (vec_select:V1SI
2082                (match_operand:V2SI 2 "register_mmxmem_operand")
2083                (parallel [(const_int 0)])))))]
2084  "(TARGET_MMX || TARGET_MMX_WITH_SSE) && TARGET_SSE2"
2085  "ix86_fixup_binary_operands_no_copy (MULT, V2SImode, operands);")
2086
2087(define_insn "*sse2_umulv1siv1di3"
2088  [(set (match_operand:V1DI 0 "register_operand" "=y,x,Yv")
2089        (mult:V1DI
2090            (zero_extend:V1DI
2091              (vec_select:V1SI
2092                (match_operand:V2SI 1 "register_mmxmem_operand" "%0,0,Yv")
2093                (parallel [(const_int 0)])))
2094            (zero_extend:V1DI
2095              (vec_select:V1SI
2096                (match_operand:V2SI 2 "register_mmxmem_operand" "ym,x,Yv")
2097                (parallel [(const_int 0)])))))]
2098  "(TARGET_MMX || TARGET_MMX_WITH_SSE)
2099   && TARGET_SSE2
2100   && ix86_binary_operator_ok (MULT, V2SImode, operands)"
2101  "@
2102   pmuludq\t{%2, %0|%0, %2}
2103   pmuludq\t{%2, %0|%0, %2}
2104   vpmuludq\t{%2, %1, %0|%0, %1, %2}"
2105  [(set_attr "isa" "*,sse2_noavx,avx")
2106   (set_attr "mmx_isa" "native,*,*")
2107   (set_attr "type" "mmxmul,ssemul,ssemul")
2108   (set_attr "mode" "DI,TI,TI")])
2109
2110;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2111;;
2112;; Parallel integral shifts
2113;;
2114;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2115
2116(define_insn "<code><mode>3"
2117  [(set (match_operand:MMXMODE14 0 "register_operand" "=Yr,*x,Yv")
2118          (smaxmin:MMXMODE14
2119            (match_operand:MMXMODE14 1 "register_operand" "%0,0,Yv")
2120            (match_operand:MMXMODE14 2 "register_operand" "Yr,*x,Yv")))]
2121  "TARGET_SSE4_1 && TARGET_MMX_WITH_SSE"
2122  "@
2123   p<maxmin_int><mmxvecsize>\t{%2, %0|%0, %2}
2124   p<maxmin_int><mmxvecsize>\t{%2, %0|%0, %2}
2125   vp<maxmin_int><mmxvecsize>\t{%2, %1, %0|%0, %1, %2}"
2126  [(set_attr "isa" "noavx,noavx,avx")
2127   (set_attr "type" "sseiadd")
2128   (set_attr "prefix_extra" "1,1,*")
2129   (set_attr "prefix" "orig,orig,vex")
2130   (set_attr "mode" "TI")])
2131
2132(define_expand "mmx_<code>v4hi3"
2133  [(set (match_operand:V4HI 0 "register_operand")
2134        (smaxmin:V4HI
2135            (match_operand:V4HI 1 "register_mmxmem_operand")
2136            (match_operand:V4HI 2 "register_mmxmem_operand")))]
2137  "(TARGET_MMX || TARGET_MMX_WITH_SSE)
2138   && (TARGET_SSE || TARGET_3DNOW_A)"
2139  "ix86_fixup_binary_operands_no_copy (<CODE>, V4HImode, operands);")
2140
2141(define_insn "*mmx_<code>v4hi3"
2142  [(set (match_operand:V4HI 0 "register_operand" "=y,x,Yw")
2143        (smaxmin:V4HI
2144            (match_operand:V4HI 1 "register_mmxmem_operand" "%0,0,Yw")
2145            (match_operand:V4HI 2 "register_mmxmem_operand" "ym,x,Yw")))]
2146  "(TARGET_MMX || TARGET_MMX_WITH_SSE)
2147   && (TARGET_SSE || TARGET_3DNOW_A)
2148   && ix86_binary_operator_ok (<CODE>, V4HImode, operands)"
2149  "@
2150   p<maxmin_int>w\t{%2, %0|%0, %2}
2151   p<maxmin_int>w\t{%2, %0|%0, %2}
2152   vp<maxmin_int>w\t{%2, %1, %0|%0, %1, %2}"
2153  [(set_attr "isa" "*,sse2_noavx,avx")
2154   (set_attr "mmx_isa" "native,*,*")
2155   (set_attr "type" "mmxadd,sseiadd,sseiadd")
2156   (set_attr "mode" "DI,TI,TI")])
2157
2158(define_expand "<code>v4hi3"
2159  [(set (match_operand:V4HI 0 "register_operand")
2160        (smaxmin:V4HI
2161            (match_operand:V4HI 1 "register_operand")
2162            (match_operand:V4HI 2 "register_operand")))]
2163  "TARGET_MMX_WITH_SSE")
2164
2165(define_insn "<code><mode>3"
2166  [(set (match_operand:VI1_16_32 0 "register_operand" "=Yr,*x,Yv")
2167          (smaxmin:VI1_16_32
2168            (match_operand:VI1_16_32 1 "register_operand" "%0,0,Yv")
2169            (match_operand:VI1_16_32 2 "register_operand" "Yr,*x,Yv")))]
2170  "TARGET_SSE4_1"
2171  "@
2172   p<maxmin_int>b\t{%2, %0|%0, %2}
2173   p<maxmin_int>b\t{%2, %0|%0, %2}
2174   vp<maxmin_int>b\t{%2, %1, %0|%0, %1, %2}"
2175  [(set_attr "isa" "noavx,noavx,avx")
2176   (set_attr "type" "sseiadd")
2177   (set_attr "prefix_extra" "1,1,*")
2178   (set_attr "prefix" "orig,orig,vex")
2179   (set_attr "mode" "TI")])
2180
2181(define_insn "<code>v2hi3"
2182  [(set (match_operand:V2HI 0 "register_operand" "=x,Yw")
2183        (smaxmin:V2HI
2184            (match_operand:V2HI 1 "register_operand" "%0,Yw")
2185            (match_operand:V2HI 2 "register_operand" "x,Yw")))]
2186  "TARGET_SSE2"
2187  "@
2188   p<maxmin_int>w\t{%2, %0|%0, %2}
2189   vp<maxmin_int>w\t{%2, %1, %0|%0, %1, %2}"
2190  [(set_attr "isa" "noavx,avx")
2191   (set_attr "type" "sseiadd")
2192   (set_attr "mode" "TI")])
2193
2194(define_insn "<code><mode>3"
2195  [(set (match_operand:MMXMODE24 0 "register_operand" "=Yr,*x,Yv")
2196          (umaxmin:MMXMODE24
2197            (match_operand:MMXMODE24 1 "register_operand" "%0,0,Yv")
2198            (match_operand:MMXMODE24 2 "register_operand" "Yr,*x,Yv")))]
2199  "TARGET_SSE4_1 && TARGET_MMX_WITH_SSE"
2200  "@
2201   p<maxmin_int><mmxvecsize>\t{%2, %0|%0, %2}
2202   p<maxmin_int><mmxvecsize>\t{%2, %0|%0, %2}
2203   vp<maxmin_int><mmxvecsize>\t{%2, %1, %0|%0, %1, %2}"
2204  [(set_attr "isa" "noavx,noavx,avx")
2205   (set_attr "type" "sseiadd")
2206   (set_attr "prefix_extra" "1,1,*")
2207   (set_attr "prefix" "orig,orig,vex")
2208   (set_attr "mode" "TI")])
2209
2210(define_expand "mmx_<code>v8qi3"
2211  [(set (match_operand:V8QI 0 "register_operand")
2212        (umaxmin:V8QI
2213            (match_operand:V8QI 1 "register_mmxmem_operand")
2214            (match_operand:V8QI 2 "register_mmxmem_operand")))]
2215  "(TARGET_MMX || TARGET_MMX_WITH_SSE)
2216   && (TARGET_SSE || TARGET_3DNOW_A)"
2217  "ix86_fixup_binary_operands_no_copy (<CODE>, V8QImode, operands);")
2218
2219(define_insn "*mmx_<code>v8qi3"
2220  [(set (match_operand:V8QI 0 "register_operand" "=y,x,Yw")
2221        (umaxmin:V8QI
2222            (match_operand:V8QI 1 "register_mmxmem_operand" "%0,0,Yw")
2223            (match_operand:V8QI 2 "register_mmxmem_operand" "ym,x,Yw")))]
2224  "(TARGET_MMX || TARGET_MMX_WITH_SSE)
2225   && (TARGET_SSE || TARGET_3DNOW_A)
2226   && ix86_binary_operator_ok (<CODE>, V8QImode, operands)"
2227  "@
2228   p<maxmin_int>b\t{%2, %0|%0, %2}
2229   p<maxmin_int>b\t{%2, %0|%0, %2}
2230   vp<maxmin_int>b\t{%2, %1, %0|%0, %1, %2}"
2231  [(set_attr "isa" "*,sse2_noavx,avx")
2232   (set_attr "mmx_isa" "native,*,*")
2233   (set_attr "type" "mmxadd,sseiadd,sseiadd")
2234   (set_attr "mode" "DI,TI,TI")])
2235
2236(define_expand "<code>v8qi3"
2237  [(set (match_operand:V8QI 0 "register_operand")
2238        (umaxmin:V8QI
2239            (match_operand:V8QI 1 "register_operand")
2240            (match_operand:V8QI 2 "register_operand")))]
2241  "TARGET_MMX_WITH_SSE")
2242
2243(define_insn "<code><mode>3"
2244  [(set (match_operand:VI1_16_32 0 "register_operand" "=x,Yw")
2245        (umaxmin:VI1_16_32
2246            (match_operand:VI1_16_32 1 "register_operand" "%0,Yw")
2247            (match_operand:VI1_16_32 2 "register_operand" "x,Yw")))]
2248  "TARGET_SSE2"
2249  "@
2250   p<maxmin_int>b\t{%2, %0|%0, %2}
2251   vp<maxmin_int>b\t{%2, %1, %0|%0, %1, %2}"
2252  [(set_attr "isa" "noavx,avx")
2253   (set_attr "type" "sseiadd")
2254   (set_attr "mode" "TI")])
2255
2256(define_insn "<code>v2hi3"
2257  [(set (match_operand:V2HI 0 "register_operand" "=Yr,*x,Yv")
2258          (umaxmin:V2HI
2259            (match_operand:V2HI 1 "register_operand" "%0,0,Yv")
2260            (match_operand:V2HI 2 "register_operand" "Yr,*x,Yv")))]
2261  "TARGET_SSE4_1"
2262  "@
2263   p<maxmin_int>w\t{%2, %0|%0, %2}
2264   p<maxmin_int>w\t{%2, %0|%0, %2}
2265   vp<maxmin_int>w\t{%2, %1, %0|%0, %1, %2}"
2266  [(set_attr "isa" "noavx,noavx,avx")
2267   (set_attr "type" "sseiadd")
2268   (set_attr "prefix_extra" "1,1,*")
2269   (set_attr "prefix" "orig,orig,vex")
2270   (set_attr "mode" "TI")])
2271
2272(define_insn "ssse3_abs<mode>2"
2273  [(set (match_operand:MMXMODEI 0 "register_operand" "=y,Yv")
2274          (abs:MMXMODEI
2275            (match_operand:MMXMODEI 1 "register_mmxmem_operand" "ym,Yv")))]
2276  "(TARGET_MMX || TARGET_MMX_WITH_SSE) && TARGET_SSSE3"
2277  "@
2278   pabs<mmxvecsize>\t{%1, %0|%0, %1}
2279   %vpabs<mmxvecsize>\t{%1, %0|%0, %1}"
2280  [(set_attr "mmx_isa" "native,*")
2281   (set_attr "type" "sselog1")
2282   (set_attr "prefix_rep" "0")
2283   (set_attr "prefix_extra" "1")
2284   (set (attr "prefix_rex") (symbol_ref "x86_extended_reg_mentioned_p (insn)"))
2285   (set_attr "mode" "DI,TI")])
2286
2287(define_expand "abs<mode>2"
2288  [(set (match_operand:MMXMODEI 0 "register_operand")
2289          (abs:MMXMODEI
2290            (match_operand:MMXMODEI 1 "register_operand")))]
2291  "TARGET_SSSE3 && TARGET_MMX_WITH_SSE")
2292
2293(define_insn "abs<mode>2"
2294  [(set (match_operand:VI_16_32 0 "register_operand" "=Yv")
2295          (abs:VI_16_32
2296            (match_operand:VI_16_32 1 "register_operand" "Yv")))]
2297  "TARGET_SSSE3"
2298  "%vpabs<mmxvecsize>\t{%1, %0|%0, %1}"
2299  [(set_attr "type" "sselog1")
2300   (set_attr "prefix_rep" "0")
2301   (set_attr "prefix_extra" "1")
2302   (set (attr "prefix_rex") (symbol_ref "x86_extended_reg_mentioned_p (insn)"))
2303   (set_attr "mode" "TI")])
2304
2305;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2306;;
2307;; Parallel integral shifts
2308;;
2309;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2310
2311(define_insn "mmx_ashr<mode>3"
2312  [(set (match_operand:MMXMODE24 0 "register_operand" "=y,x,<Yv_Yw>")
2313        (ashiftrt:MMXMODE24
2314            (match_operand:MMXMODE24 1 "register_operand" "0,0,<Yv_Yw>")
2315            (match_operand:DI 2 "nonmemory_operand" "yN,xN,<Yv_Yw>N")))]
2316  "TARGET_MMX || TARGET_MMX_WITH_SSE"
2317  "@
2318   psra<mmxvecsize>\t{%2, %0|%0, %2}
2319   psra<mmxvecsize>\t{%2, %0|%0, %2}
2320   vpsra<mmxvecsize>\t{%2, %1, %0|%0, %1, %2}"
2321  [(set_attr "isa" "*,sse2_noavx,avx")
2322   (set_attr "mmx_isa" "native,*,*")
2323   (set_attr "type" "mmxshft,sseishft,sseishft")
2324   (set (attr "length_immediate")
2325     (if_then_else (match_operand 2 "const_int_operand")
2326       (const_string "1")
2327       (const_string "0")))
2328   (set_attr "mode" "DI,TI,TI")])
2329
2330(define_expand "ashr<mode>3"
2331  [(set (match_operand:MMXMODE24 0 "register_operand")
2332        (ashiftrt:MMXMODE24
2333            (match_operand:MMXMODE24 1 "register_operand")
2334            (match_operand:DI 2 "nonmemory_operand")))]
2335  "TARGET_MMX_WITH_SSE")
2336
2337(define_insn "mmx_<insn><mode>3"
2338  [(set (match_operand:MMXMODE248 0 "register_operand" "=y,x,<Yv_Yw>")
2339        (any_lshift:MMXMODE248
2340            (match_operand:MMXMODE248 1 "register_operand" "0,0,<Yv_Yw>")
2341            (match_operand:DI 2 "nonmemory_operand" "yN,xN,<Yv_Yw>N")))]
2342  "TARGET_MMX || TARGET_MMX_WITH_SSE"
2343  "@
2344   p<vshift><mmxvecsize>\t{%2, %0|%0, %2}
2345   p<vshift><mmxvecsize>\t{%2, %0|%0, %2}
2346   vp<vshift><mmxvecsize>\t{%2, %1, %0|%0, %1, %2}"
2347  [(set_attr "isa" "*,sse2_noavx,avx")
2348   (set_attr "mmx_isa" "native,*,*")
2349   (set_attr "type" "mmxshft,sseishft,sseishft")
2350   (set (attr "length_immediate")
2351     (if_then_else (match_operand 2 "const_int_operand")
2352       (const_string "1")
2353       (const_string "0")))
2354   (set_attr "mode" "DI,TI,TI")])
2355
2356(define_expand "<insn><mode>3"
2357  [(set (match_operand:MMXMODE24 0 "register_operand")
2358        (any_lshift:MMXMODE24
2359            (match_operand:MMXMODE24 1 "register_operand")
2360            (match_operand:DI 2 "nonmemory_operand")))]
2361  "TARGET_MMX_WITH_SSE")
2362
2363(define_insn "mmx_<insn>v1si3"
2364  [(set (match_operand:V1SI 0 "register_operand" "=x,Yw")
2365        (any_lshift:V1SI
2366            (match_operand:V1SI 1 "register_operand" "0,Yw")
2367            (match_operand:DI 2 "nonmemory_operand" "xN,YwN")))]
2368  "TARGET_SSE2"
2369  "@
2370   p<vshift>d\t{%2, %0|%0, %2}
2371   vp<vshift>d\t{%2, %1, %0|%0, %1, %2}"
2372  [(set_attr "isa" "noavx,avx")
2373   (set_attr "type" "sseishft")
2374   (set (attr "length_immediate")
2375     (if_then_else (match_operand 2 "const_int_operand")
2376       (const_string "1")
2377       (const_string "0")))
2378   (set_attr "mode" "TI")])
2379
2380(define_insn "<insn>v2hi3"
2381  [(set (match_operand:V2HI 0 "register_operand" "=x,Yw")
2382        (any_shift:V2HI
2383            (match_operand:V2HI 1 "register_operand" "0,Yw")
2384            (match_operand:DI 2 "nonmemory_operand" "xN,YwN")))]
2385  "TARGET_SSE2"
2386  "@
2387   p<vshift>w\t{%2, %0|%0, %2}
2388   vp<vshift>w\t{%2, %1, %0|%0, %1, %2}"
2389  [(set_attr "isa" "noavx,avx")
2390   (set_attr "type" "sseishft")
2391   (set (attr "length_immediate")
2392     (if_then_else (match_operand 2 "const_int_operand")
2393       (const_string "1")
2394       (const_string "0")))
2395   (set_attr "mode" "TI")])
2396
2397(define_insn_and_split "<insn>v2qi3"
2398  [(set (match_operand:V2QI 0 "register_operand" "=Q")
2399        (any_shift:V2QI
2400            (match_operand:V2QI 1 "register_operand" "0")
2401            (match_operand:QI 2 "nonmemory_operand" "cI")))
2402   (clobber (reg:CC FLAGS_REG))]
2403  "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2404  "#"
2405  "&& reload_completed"
2406  [(parallel
2407     [(set (zero_extract:HI (match_dup 3) (const_int 8) (const_int 8))
2408             (subreg:HI
2409               (any_shift:QI
2410                 (subreg:QI
2411                   (zero_extract:HI (match_dup 4)
2412                                        (const_int 8)
2413                                          (const_int 8)) 0)
2414                 (match_dup 2)) 0))
2415      (clobber (reg:CC FLAGS_REG))])
2416   (parallel
2417     [(set (strict_low_part (match_dup 0))
2418             (any_shift:QI (match_dup 1) (match_dup 2)))
2419      (clobber (reg:CC FLAGS_REG))])]
2420{
2421  operands[4] = lowpart_subreg (HImode, operands[1], V2QImode);
2422  operands[3] = lowpart_subreg (HImode, operands[0], V2QImode);
2423  operands[1] = lowpart_subreg (QImode, operands[1], V2QImode);
2424  operands[0] = lowpart_subreg (QImode, operands[0], V2QImode);
2425}
2426  [(set_attr "type" "multi")
2427   (set_attr "mode" "QI")])
2428
2429;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2430;;
2431;; Parallel integral comparisons
2432;;
2433;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2434
2435(define_expand "mmx_eq<mode>3"
2436  [(set (match_operand:MMXMODEI 0 "register_operand")
2437        (eq:MMXMODEI
2438            (match_operand:MMXMODEI 1 "register_mmxmem_operand")
2439            (match_operand:MMXMODEI 2 "register_mmxmem_operand")))]
2440  "TARGET_MMX || TARGET_MMX_WITH_SSE"
2441  "ix86_fixup_binary_operands_no_copy (EQ, <MODE>mode, operands);")
2442
2443(define_insn "*mmx_eq<mode>3"
2444  [(set (match_operand:MMXMODEI 0 "register_operand" "=y,x,x")
2445        (eq:MMXMODEI
2446            (match_operand:MMXMODEI 1 "register_mmxmem_operand" "%0,0,x")
2447            (match_operand:MMXMODEI 2 "register_mmxmem_operand" "ym,x,x")))]
2448  "(TARGET_MMX || TARGET_MMX_WITH_SSE)
2449   && ix86_binary_operator_ok (EQ, <MODE>mode, operands)"
2450  "@
2451   pcmpeq<mmxvecsize>\t{%2, %0|%0, %2}
2452   pcmpeq<mmxvecsize>\t{%2, %0|%0, %2}
2453   vpcmpeq<mmxvecsize>\t{%2, %1, %0|%0, %1, %2}"
2454  [(set_attr "isa" "*,sse2_noavx,avx")
2455   (set_attr "mmx_isa" "native,*,*")
2456   (set_attr "type" "mmxcmp,ssecmp,ssecmp")
2457   (set_attr "mode" "DI,TI,TI")])
2458
2459(define_insn "*eq<mode>3"
2460  [(set (match_operand:VI_16_32 0 "register_operand" "=x,x")
2461        (eq:VI_16_32
2462            (match_operand:VI_16_32 1 "register_operand" "%0,x")
2463            (match_operand:VI_16_32 2 "register_operand" "x,x")))]
2464  "TARGET_SSE2"
2465  "@
2466   pcmpeq<mmxvecsize>\t{%2, %0|%0, %2}
2467   vpcmpeq<mmxvecsize>\t{%2, %1, %0|%0, %1, %2}"
2468  [(set_attr "isa" "noavx,avx")
2469   (set_attr "type" "ssecmp")
2470   (set_attr "mode" "TI")])
2471
2472(define_insn "mmx_gt<mode>3"
2473  [(set (match_operand:MMXMODEI 0 "register_operand" "=y,x,x")
2474        (gt:MMXMODEI
2475            (match_operand:MMXMODEI 1 "register_operand" "0,0,x")
2476            (match_operand:MMXMODEI 2 "register_mmxmem_operand" "ym,x,x")))]
2477  "TARGET_MMX || TARGET_MMX_WITH_SSE"
2478  "@
2479   pcmpgt<mmxvecsize>\t{%2, %0|%0, %2}
2480   pcmpgt<mmxvecsize>\t{%2, %0|%0, %2}
2481   vpcmpgt<mmxvecsize>\t{%2, %1, %0|%0, %1, %2}"
2482  [(set_attr "isa" "*,sse2_noavx,avx")
2483   (set_attr "mmx_isa" "native,*,*")
2484   (set_attr "type" "mmxcmp,ssecmp,ssecmp")
2485   (set_attr "mode" "DI,TI,TI")])
2486
2487(define_insn "*gt<mode>3"
2488  [(set (match_operand:VI_16_32 0 "register_operand" "=x,x")
2489        (gt:VI_16_32
2490            (match_operand:VI_16_32 1 "register_operand" "0,x")
2491            (match_operand:VI_16_32 2 "register_operand" "x,x")))]
2492  "TARGET_SSE2"
2493  "@
2494   pcmpgt<mmxvecsize>\t{%2, %0|%0, %2}
2495   vpcmpgt<mmxvecsize>\t{%2, %1, %0|%0, %1, %2}"
2496  [(set_attr "isa" "noavx,avx")
2497   (set_attr "type" "ssecmp")
2498   (set_attr "mode" "TI")])
2499
2500(define_insn "*xop_maskcmp<mode>3"
2501  [(set (match_operand:MMXMODEI 0 "register_operand" "=x")
2502          (match_operator:MMXMODEI 1 "ix86_comparison_int_operator"
2503           [(match_operand:MMXMODEI 2 "register_operand" "x")
2504            (match_operand:MMXMODEI 3 "register_operand" "x")]))]
2505  "TARGET_XOP"
2506  "vpcom%Y1<mmxvecsize>\t{%3, %2, %0|%0, %2, %3}"
2507  [(set_attr "type" "sse4arg")
2508   (set_attr "prefix_data16" "0")
2509   (set_attr "prefix_rep" "0")
2510   (set_attr "prefix_extra" "2")
2511   (set_attr "length_immediate" "1")
2512   (set_attr "mode" "TI")])
2513
2514(define_insn "*xop_maskcmp<mode>3"
2515  [(set (match_operand:VI_16_32 0 "register_operand" "=x")
2516          (match_operator:VI_16_32 1 "ix86_comparison_int_operator"
2517           [(match_operand:VI_16_32 2 "register_operand" "x")
2518            (match_operand:VI_16_32 3 "register_operand" "x")]))]
2519  "TARGET_XOP"
2520  "vpcom%Y1<mmxvecsize>\t{%3, %2, %0|%0, %2, %3}"
2521  [(set_attr "type" "sse4arg")
2522   (set_attr "prefix_data16" "0")
2523   (set_attr "prefix_rep" "0")
2524   (set_attr "prefix_extra" "2")
2525   (set_attr "length_immediate" "1")
2526   (set_attr "mode" "TI")])
2527
2528(define_insn "*xop_maskcmp_uns<mode>3"
2529  [(set (match_operand:MMXMODEI 0 "register_operand" "=x")
2530          (match_operator:MMXMODEI 1 "ix86_comparison_uns_operator"
2531           [(match_operand:MMXMODEI 2 "register_operand" "x")
2532            (match_operand:MMXMODEI 3 "register_operand" "x")]))]
2533  "TARGET_XOP"
2534  "vpcom%Y1u<mmxvecsize>\t{%3, %2, %0|%0, %2, %3}"
2535  [(set_attr "type" "ssecmp")
2536   (set_attr "prefix_data16" "0")
2537   (set_attr "prefix_rep" "0")
2538   (set_attr "prefix_extra" "2")
2539   (set_attr "length_immediate" "1")
2540   (set_attr "mode" "TI")])
2541
2542(define_insn "*xop_maskcmp_uns<mode>3"
2543  [(set (match_operand:VI_16_32 0 "register_operand" "=x")
2544          (match_operator:VI_16_32 1 "ix86_comparison_uns_operator"
2545           [(match_operand:VI_16_32 2 "register_operand" "x")
2546            (match_operand:VI_16_32 3 "register_operand" "x")]))]
2547  "TARGET_XOP"
2548  "vpcom%Y1u<mmxvecsize>\t{%3, %2, %0|%0, %2, %3}"
2549  [(set_attr "type" "ssecmp")
2550   (set_attr "prefix_data16" "0")
2551   (set_attr "prefix_rep" "0")
2552   (set_attr "prefix_extra" "2")
2553   (set_attr "length_immediate" "1")
2554   (set_attr "mode" "TI")])
2555
2556(define_expand "vec_cmp<mode><mode>"
2557  [(set (match_operand:MMXMODEI 0 "register_operand")
2558          (match_operator:MMXMODEI 1 ""
2559            [(match_operand:MMXMODEI 2 "register_operand")
2560             (match_operand:MMXMODEI 3 "register_operand")]))]
2561  "TARGET_MMX_WITH_SSE"
2562{
2563  bool ok = ix86_expand_int_vec_cmp (operands);
2564  gcc_assert (ok);
2565  DONE;
2566})
2567
2568(define_expand "vec_cmp<mode><mode>"
2569  [(set (match_operand:VI_16_32 0 "register_operand")
2570          (match_operator:VI_16_32 1 ""
2571            [(match_operand:VI_16_32 2 "register_operand")
2572             (match_operand:VI_16_32 3 "register_operand")]))]
2573  "TARGET_SSE2"
2574{
2575  bool ok = ix86_expand_int_vec_cmp (operands);
2576  gcc_assert (ok);
2577  DONE;
2578})
2579
2580(define_expand "vec_cmpu<mode><mode>"
2581  [(set (match_operand:MMXMODEI 0 "register_operand")
2582          (match_operator:MMXMODEI 1 ""
2583            [(match_operand:MMXMODEI 2 "register_operand")
2584             (match_operand:MMXMODEI 3 "register_operand")]))]
2585  "TARGET_MMX_WITH_SSE"
2586{
2587  bool ok = ix86_expand_int_vec_cmp (operands);
2588  gcc_assert (ok);
2589  DONE;
2590})
2591
2592(define_expand "vec_cmpu<mode><mode>"
2593  [(set (match_operand:VI_16_32 0 "register_operand")
2594          (match_operator:VI_16_32 1 ""
2595            [(match_operand:VI_16_32 2 "register_operand")
2596             (match_operand:VI_16_32 3 "register_operand")]))]
2597  "TARGET_SSE2"
2598{
2599  bool ok = ix86_expand_int_vec_cmp (operands);
2600  gcc_assert (ok);
2601  DONE;
2602})
2603
2604(define_expand "vcond<MMXMODE124:mode><MMXMODEI:mode>"
2605  [(set (match_operand:MMXMODE124 0 "register_operand")
2606          (if_then_else:MMXMODE124
2607            (match_operator 3 ""
2608              [(match_operand:MMXMODEI 4 "register_operand")
2609               (match_operand:MMXMODEI 5 "register_operand")])
2610            (match_operand:MMXMODE124 1)
2611            (match_operand:MMXMODE124 2)))]
2612  "TARGET_MMX_WITH_SSE
2613   && (GET_MODE_NUNITS (<MMXMODE124:MODE>mode)
2614       == GET_MODE_NUNITS (<MMXMODEI:MODE>mode))"
2615{
2616  bool ok = ix86_expand_int_vcond (operands);
2617  gcc_assert (ok);
2618  DONE;
2619})
2620
2621(define_expand "vcond<mode><mode>"
2622  [(set (match_operand:VI_16_32 0 "register_operand")
2623          (if_then_else:VI_16_32
2624            (match_operator 3 ""
2625              [(match_operand:VI_16_32 4 "register_operand")
2626               (match_operand:VI_16_32 5 "register_operand")])
2627            (match_operand:VI_16_32 1)
2628            (match_operand:VI_16_32 2)))]
2629  "TARGET_SSE2"
2630{
2631  bool ok = ix86_expand_int_vcond (operands);
2632  gcc_assert (ok);
2633  DONE;
2634})
2635
2636(define_expand "vcondu<MMXMODE124:mode><MMXMODEI:mode>"
2637  [(set (match_operand:MMXMODE124 0 "register_operand")
2638          (if_then_else:MMXMODE124
2639            (match_operator 3 ""
2640              [(match_operand:MMXMODEI 4 "register_operand")
2641               (match_operand:MMXMODEI 5 "register_operand")])
2642            (match_operand:MMXMODE124 1)
2643            (match_operand:MMXMODE124 2)))]
2644  "TARGET_MMX_WITH_SSE
2645   && (GET_MODE_NUNITS (<MMXMODE124:MODE>mode)
2646       == GET_MODE_NUNITS (<MMXMODEI:MODE>mode))"
2647{
2648  bool ok = ix86_expand_int_vcond (operands);
2649  gcc_assert (ok);
2650  DONE;
2651})
2652
2653(define_expand "vcondu<mode><mode>"
2654  [(set (match_operand:VI_16_32 0 "register_operand")
2655          (if_then_else:VI_16_32
2656            (match_operator 3 ""
2657              [(match_operand:VI_16_32 4 "register_operand")
2658               (match_operand:VI_16_32 5 "register_operand")])
2659            (match_operand:VI_16_32 1)
2660            (match_operand:VI_16_32 2)))]
2661  "TARGET_SSE2"
2662{
2663  bool ok = ix86_expand_int_vcond (operands);
2664  gcc_assert (ok);
2665  DONE;
2666})
2667
2668(define_expand "vcond_mask_<mode><mmxintvecmodelower>"
2669  [(set (match_operand:MMXMODE124 0 "register_operand")
2670          (vec_merge:MMXMODE124
2671            (match_operand:MMXMODE124 1 "register_operand")
2672            (match_operand:MMXMODE124 2 "register_operand")
2673            (match_operand:<mmxintvecmode> 3 "register_operand")))]
2674  "TARGET_MMX_WITH_SSE"
2675{
2676  ix86_expand_sse_movcc (operands[0], operands[3],
2677                               operands[1], operands[2]);
2678  DONE;
2679})
2680
2681(define_expand "vcond_mask_<mode><mode>"
2682  [(set (match_operand:VI_16_32 0 "register_operand")
2683          (vec_merge:VI_16_32
2684            (match_operand:VI_16_32 1 "register_operand")
2685            (match_operand:VI_16_32 2 "register_operand")
2686            (match_operand:VI_16_32 3 "register_operand")))]
2687  "TARGET_SSE2"
2688{
2689  ix86_expand_sse_movcc (operands[0], operands[3],
2690                               operands[1], operands[2]);
2691  DONE;
2692})
2693
2694(define_insn "mmx_pblendvb_v8qi"
2695  [(set (match_operand:V8QI 0 "register_operand" "=Yr,*x,x")
2696          (unspec:V8QI
2697            [(match_operand:V8QI 1 "register_operand" "0,0,x")
2698             (match_operand:V8QI 2 "register_operand" "Yr,*x,x")
2699             (match_operand:V8QI 3 "register_operand" "Yz,Yz,x")]
2700            UNSPEC_BLENDV))]
2701  "TARGET_SSE4_1 && TARGET_MMX_WITH_SSE"
2702  "@
2703   pblendvb\t{%3, %2, %0|%0, %2, %3}
2704   pblendvb\t{%3, %2, %0|%0, %2, %3}
2705   vpblendvb\t{%3, %2, %1, %0|%0, %1, %2, %3}"
2706  [(set_attr "isa" "noavx,noavx,avx")
2707   (set_attr "type" "ssemov")
2708   (set_attr "prefix_extra" "1")
2709   (set_attr "length_immediate" "*,*,1")
2710   (set_attr "prefix" "orig,orig,vex")
2711   (set_attr "btver2_decode" "vector")
2712   (set_attr "mode" "TI")])
2713
2714(define_insn "mmx_pblendvb_<mode>"
2715  [(set (match_operand:VI_16_32 0 "register_operand" "=Yr,*x,x")
2716          (unspec:VI_16_32
2717            [(match_operand:VI_16_32 1 "register_operand" "0,0,x")
2718             (match_operand:VI_16_32 2 "register_operand" "Yr,*x,x")
2719             (match_operand:VI_16_32 3 "register_operand" "Yz,Yz,x")]
2720            UNSPEC_BLENDV))]
2721  "TARGET_SSE4_1"
2722  "@
2723   pblendvb\t{%3, %2, %0|%0, %2, %3}
2724   pblendvb\t{%3, %2, %0|%0, %2, %3}
2725   vpblendvb\t{%3, %2, %1, %0|%0, %1, %2, %3}"
2726  [(set_attr "isa" "noavx,noavx,avx")
2727   (set_attr "type" "ssemov")
2728   (set_attr "prefix_extra" "1")
2729   (set_attr "length_immediate" "*,*,1")
2730   (set_attr "prefix" "orig,orig,vex")
2731   (set_attr "btver2_decode" "vector")
2732   (set_attr "mode" "TI")])
2733
2734;; XOP parallel XMM conditional moves
2735(define_insn "*xop_pcmov_<mode>"
2736  [(set (match_operand:MMXMODE124 0 "register_operand" "=x")
2737        (if_then_else:MMXMODE124
2738          (match_operand:MMXMODE124 3 "register_operand" "x")
2739          (match_operand:MMXMODE124 1 "register_operand" "x")
2740          (match_operand:MMXMODE124 2 "register_operand" "x")))]
2741  "TARGET_XOP && TARGET_MMX_WITH_SSE"
2742  "vpcmov\t{%3, %2, %1, %0|%0, %1, %2, %3}"
2743  [(set_attr "type" "sse4arg")])
2744
2745(define_insn "*xop_pcmov_<mode>"
2746  [(set (match_operand:VI_16_32 0 "register_operand" "=x")
2747        (if_then_else:VI_16_32
2748          (match_operand:VI_16_32 3 "register_operand" "x")
2749          (match_operand:VI_16_32 1 "register_operand" "x")
2750          (match_operand:VI_16_32 2 "register_operand" "x")))]
2751  "TARGET_XOP"
2752  "vpcmov\t{%3, %2, %1, %0|%0, %1, %2, %3}"
2753  [(set_attr "type" "sse4arg")])
2754
2755;; XOP permute instructions
2756(define_insn "mmx_ppermv64"
2757  [(set (match_operand:V8QI 0 "register_operand" "=x")
2758          (unspec:V8QI
2759            [(match_operand:V8QI 1 "register_operand" "x")
2760             (match_operand:V8QI 2 "register_operand" "x")
2761             (match_operand:V16QI 3 "nonimmediate_operand" "xm")]
2762            UNSPEC_XOP_PERMUTE))]
2763  "TARGET_XOP && TARGET_MMX_WITH_SSE"
2764  "vpperm\t{%3, %2, %1, %0|%0, %1, %2, %3}"
2765  [(set_attr "type" "sse4arg")
2766   (set_attr "mode" "TI")])
2767
2768(define_insn "mmx_ppermv32"
2769  [(set (match_operand:V4QI 0 "register_operand" "=x")
2770          (unspec:V4QI
2771            [(match_operand:V4QI 1 "register_operand" "x")
2772             (match_operand:V4QI 2 "register_operand" "x")
2773             (match_operand:V16QI 3 "nonimmediate_operand" "xm")]
2774            UNSPEC_XOP_PERMUTE))]
2775  "TARGET_XOP"
2776  "vpperm\t{%3, %2, %1, %0|%0, %1, %2, %3}"
2777  [(set_attr "type" "sse4arg")
2778   (set_attr "mode" "TI")])
2779
2780;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2781;;
2782;; Parallel integral logical operations
2783;;
2784;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2785
2786(define_expand "one_cmpl<mode>2"
2787  [(set (match_operand:MMXMODEI 0 "register_operand")
2788          (xor:MMXMODEI
2789            (match_operand:MMXMODEI 1 "register_operand")
2790            (match_dup 2)))]
2791  "TARGET_MMX_WITH_SSE"
2792  "operands[2] = force_reg (<MODE>mode, CONSTM1_RTX (<MODE>mode));")
2793
2794(define_insn "one_cmpl<mode>2"
2795  [(set (match_operand:VI_16_32 0 "register_operand" "=?r,&x,&v")
2796          (not:VI_16_32
2797            (match_operand:VI_16_32 1 "register_operand" "0,x,v")))]
2798  ""
2799  "#"
2800  [(set_attr "isa" "*,sse2,avx512vl")
2801   (set_attr "type" "negnot,sselog1,sselog1")
2802   (set_attr "mode" "SI,TI,TI")])
2803
2804(define_split
2805  [(set (match_operand:VI_16_32 0 "general_reg_operand")
2806          (not:VI_16_32
2807            (match_operand:VI_16_32 1 "general_reg_operand")))]
2808  "reload_completed"
2809  [(set (match_dup 0)
2810          (not:SI (match_dup 1)))]
2811{
2812  operands[1] = lowpart_subreg (SImode, operands[1], <MODE>mode);
2813  operands[0] = lowpart_subreg (SImode, operands[0], <MODE>mode);
2814})
2815
2816(define_split
2817  [(set (match_operand:VI_16_32 0 "sse_reg_operand")
2818          (not:VI_16_32
2819            (match_operand:VI_16_32 1 "sse_reg_operand")))]
2820  "TARGET_SSE2 && reload_completed"
2821  [(set (match_dup 0) (match_dup 2))
2822   (set (match_dup 0)
2823          (xor:V16QI
2824            (match_dup 0) (match_dup 1)))]
2825{
2826  operands[2] = CONSTM1_RTX (V16QImode);
2827  operands[1] = lowpart_subreg (V16QImode, operands[1], <MODE>mode);
2828  operands[0] = lowpart_subreg (V16QImode, operands[0], <MODE>mode);
2829})
2830
2831(define_insn "mmx_andnot<mode>3"
2832  [(set (match_operand:MMXMODEI 0 "register_operand" "=y,x,x,v")
2833          (and:MMXMODEI
2834            (not:MMXMODEI (match_operand:MMXMODEI 1 "register_operand" "0,0,x,v"))
2835            (match_operand:MMXMODEI 2 "register_mmxmem_operand" "ym,x,x,v")))]
2836  "TARGET_MMX || TARGET_MMX_WITH_SSE"
2837  "@
2838   pandn\t{%2, %0|%0, %2}
2839   pandn\t{%2, %0|%0, %2}
2840   vpandn\t{%2, %1, %0|%0, %1, %2}
2841   vpandnd\t{%2, %1, %0|%0, %1, %2}"
2842  [(set_attr "isa" "*,sse2_noavx,avx,avx512vl")
2843   (set_attr "mmx_isa" "native,*,*,*")
2844   (set_attr "type" "mmxadd,sselog,sselog,sselog")
2845   (set_attr "mode" "DI,TI,TI,TI")])
2846
2847(define_insn "*andnot<mode>3"
2848  [(set (match_operand:VI_16_32 0 "register_operand" "=?&r,?r,x,x,v")
2849        (and:VI_16_32
2850            (not:VI_16_32
2851              (match_operand:VI_16_32 1 "register_operand" "0,r,0,x,v"))
2852            (match_operand:VI_16_32 2 "register_operand" "r,r,x,x,v")))
2853   (clobber (reg:CC FLAGS_REG))]
2854  ""
2855  "#"
2856  [(set_attr "isa" "*,bmi,sse2_noavx,avx,avx512vl")
2857   (set_attr "type" "alu,bitmanip,sselog,sselog,sselog")
2858   (set_attr "mode" "SI,SI,TI,TI,TI")])
2859
2860(define_split
2861  [(set (match_operand:VI_16_32 0 "general_reg_operand")
2862        (and:VI_16_32
2863            (not:VI_16_32 (match_operand:VI_16_32 1 "general_reg_operand"))
2864            (match_operand:VI_16_32 2 "general_reg_operand")))
2865   (clobber (reg:CC FLAGS_REG))]
2866  "TARGET_BMI && reload_completed"
2867  [(parallel
2868     [(set (match_dup 0)
2869             (and:SI (not:SI (match_dup 1)) (match_dup 2)))
2870      (clobber (reg:CC FLAGS_REG))])]
2871{
2872  operands[2] = lowpart_subreg (SImode, operands[2], <MODE>mode);
2873  operands[1] = lowpart_subreg (SImode, operands[1], <MODE>mode);
2874  operands[0] = lowpart_subreg (SImode, operands[0], <MODE>mode);
2875})
2876
2877(define_split
2878  [(set (match_operand:VI_16_32 0 "general_reg_operand")
2879        (and:VI_16_32
2880            (not:VI_16_32 (match_operand:VI_16_32 1 "general_reg_operand"))
2881            (match_operand:VI_16_32 2 "general_reg_operand")))
2882   (clobber (reg:CC FLAGS_REG))]
2883  "!TARGET_BMI && reload_completed"
2884  [(set (match_dup 0)
2885        (not:SI (match_dup 1)))
2886   (parallel
2887     [(set (match_dup 0)
2888             (and:SI (match_dup 0) (match_dup 2)))
2889      (clobber (reg:CC FLAGS_REG))])]
2890{
2891  operands[2] = lowpart_subreg (SImode, operands[2], <MODE>mode);
2892  operands[1] = lowpart_subreg (SImode, operands[1], <MODE>mode);
2893  operands[0] = lowpart_subreg (SImode, operands[0], <MODE>mode);
2894})
2895
2896(define_split
2897  [(set (match_operand:VI_16_32 0 "sse_reg_operand")
2898        (and:VI_16_32
2899            (not:VI_16_32 (match_operand:VI_16_32 1 "sse_reg_operand"))
2900            (match_operand:VI_16_32 2 "sse_reg_operand")))
2901   (clobber (reg:CC FLAGS_REG))]
2902  "TARGET_SSE2 && reload_completed"
2903  [(set (match_dup 0)
2904          (and:V16QI (not:V16QI (match_dup 1)) (match_dup 2)))]
2905{
2906  operands[2] = lowpart_subreg (V16QImode, operands[2], <MODE>mode);
2907  operands[1] = lowpart_subreg (V16QImode, operands[1], <MODE>mode);
2908  operands[0] = lowpart_subreg (V16QImode, operands[0], <MODE>mode);
2909})
2910
2911(define_expand "mmx_<code><mode>3"
2912  [(set (match_operand:MMXMODEI 0 "register_operand")
2913          (any_logic:MMXMODEI
2914            (match_operand:MMXMODEI 1 "register_mmxmem_operand")
2915            (match_operand:MMXMODEI 2 "register_mmxmem_operand")))]
2916  "TARGET_MMX || TARGET_MMX_WITH_SSE"
2917  "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
2918
2919(define_expand "<code><mode>3"
2920  [(set (match_operand:MMXMODEI 0 "register_operand")
2921          (any_logic:MMXMODEI
2922            (match_operand:MMXMODEI 1 "register_operand")
2923            (match_operand:MMXMODEI 2 "register_operand")))]
2924  "TARGET_MMX_WITH_SSE")
2925
2926(define_insn "*mmx_<code><mode>3"
2927  [(set (match_operand:MMXMODEI 0 "register_operand" "=y,x,x,v")
2928        (any_logic:MMXMODEI
2929            (match_operand:MMXMODEI 1 "register_mmxmem_operand" "%0,0,x,v")
2930            (match_operand:MMXMODEI 2 "register_mmxmem_operand" "ym,x,x,v")))]
2931  "(TARGET_MMX || TARGET_MMX_WITH_SSE)
2932   && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
2933  "@
2934   p<logic>\t{%2, %0|%0, %2}
2935   p<logic>\t{%2, %0|%0, %2}
2936   vp<logic>\t{%2, %1, %0|%0, %1, %2}
2937   vp<logic>d\t{%2, %1, %0|%0, %1, %2}"
2938  [(set_attr "isa" "*,sse2_noavx,avx,avx512vl")
2939   (set_attr "mmx_isa" "native,*,*,*")
2940   (set_attr "type" "mmxadd,sselog,sselog,sselog")
2941   (set_attr "mode" "DI,TI,TI,TI")])
2942
2943(define_insn "<code><mode>3"
2944  [(set (match_operand:VI_16_32 0 "register_operand" "=?r,x,x,v")
2945        (any_logic:VI_16_32
2946            (match_operand:VI_16_32 1 "register_operand" "%0,0,x,v")
2947            (match_operand:VI_16_32 2 "register_operand" "r,x,x,v")))
2948   (clobber (reg:CC FLAGS_REG))]
2949  ""
2950  "#"
2951  [(set_attr "isa" "*,sse2_noavx,avx,avx512vl")
2952   (set_attr "type" "alu,sselog,sselog,sselog")
2953   (set_attr "mode" "SI,TI,TI,TI")])
2954
2955(define_split
2956  [(set (match_operand:VI_16_32 0 "general_reg_operand")
2957        (any_logic:VI_16_32
2958            (match_operand:VI_16_32 1 "general_reg_operand")
2959            (match_operand:VI_16_32 2 "general_reg_operand")))
2960   (clobber (reg:CC FLAGS_REG))]
2961  "reload_completed"
2962  [(parallel
2963     [(set (match_dup 0)
2964             (any_logic:SI (match_dup 1) (match_dup 2)))
2965      (clobber (reg:CC FLAGS_REG))])]
2966{
2967  operands[2] = lowpart_subreg (SImode, operands[2], <MODE>mode);
2968  operands[1] = lowpart_subreg (SImode, operands[1], <MODE>mode);
2969  operands[0] = lowpart_subreg (SImode, operands[0], <MODE>mode);
2970})
2971
2972(define_split
2973  [(set (match_operand:VI_16_32 0 "sse_reg_operand")
2974        (any_logic:VI_16_32
2975            (match_operand:VI_16_32 1 "sse_reg_operand")
2976            (match_operand:VI_16_32 2 "sse_reg_operand")))
2977   (clobber (reg:CC FLAGS_REG))]
2978  "TARGET_SSE2 && reload_completed"
2979  [(set (match_dup 0)
2980          (any_logic:V16QI (match_dup 1) (match_dup 2)))]
2981{
2982  operands[2] = lowpart_subreg (V16QImode, operands[2], <MODE>mode);
2983  operands[1] = lowpart_subreg (V16QImode, operands[1], <MODE>mode);
2984  operands[0] = lowpart_subreg (V16QImode, operands[0], <MODE>mode);
2985})
2986
2987;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2988;;
2989;; Parallel integral element swizzling
2990;;
2991;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2992
2993;; Used in signed and unsigned truncations with saturation.
2994(define_code_iterator any_s_truncate [ss_truncate us_truncate])
2995;; Instruction suffix for truncations with saturation.
2996(define_code_attr s_trunsuffix [(ss_truncate "s") (us_truncate "u")])
2997
2998(define_insn_and_split "mmx_pack<s_trunsuffix>swb"
2999  [(set (match_operand:V8QI 0 "register_operand" "=y,x,Yw")
3000          (vec_concat:V8QI
3001            (any_s_truncate:V4QI
3002              (match_operand:V4HI 1 "register_operand" "0,0,Yw"))
3003            (any_s_truncate:V4QI
3004              (match_operand:V4HI 2 "register_mmxmem_operand" "ym,x,Yw"))))]
3005  "TARGET_MMX || TARGET_MMX_WITH_SSE"
3006  "@
3007   pack<s_trunsuffix>swb\t{%2, %0|%0, %2}
3008   #
3009   #"
3010  "&& reload_completed
3011   && SSE_REGNO_P (REGNO (operands[0]))"
3012  [(const_int 0)]
3013  "ix86_split_mmx_pack (operands, <any_s_truncate:CODE>); DONE;"
3014  [(set_attr "mmx_isa" "native,sse_noavx,avx")
3015   (set_attr "type" "mmxshft,sselog,sselog")
3016   (set_attr "mode" "DI,TI,TI")])
3017
3018(define_insn_and_split "mmx_packssdw"
3019  [(set (match_operand:V4HI 0 "register_operand" "=y,x,Yw")
3020          (vec_concat:V4HI
3021            (ss_truncate:V2HI
3022              (match_operand:V2SI 1 "register_operand" "0,0,Yw"))
3023            (ss_truncate:V2HI
3024              (match_operand:V2SI 2 "register_mmxmem_operand" "ym,x,Yw"))))]
3025  "TARGET_MMX || TARGET_MMX_WITH_SSE"
3026  "@
3027   packssdw\t{%2, %0|%0, %2}
3028   #
3029   #"
3030  "&& reload_completed
3031   && SSE_REGNO_P (REGNO (operands[0]))"
3032  [(const_int 0)]
3033  "ix86_split_mmx_pack (operands, SS_TRUNCATE); DONE;"
3034  [(set_attr "mmx_isa" "native,sse_noavx,avx")
3035   (set_attr "type" "mmxshft,sselog,sselog")
3036   (set_attr "mode" "DI,TI,TI")])
3037
3038(define_insn_and_split "mmx_packusdw"
3039  [(set (match_operand:V4HI 0 "register_operand" "=Yr,*x,Yw")
3040          (vec_concat:V4HI
3041            (us_truncate:V2HI
3042              (match_operand:V2SI 1 "register_operand" "0,0,Yw"))
3043            (us_truncate:V2HI
3044              (match_operand:V2SI 2 "register_operand" "Yr,*x,Yw"))))]
3045  "TARGET_SSE4_1 && TARGET_MMX_WITH_SSE"
3046  "#"
3047  "&& reload_completed"
3048  [(const_int 0)]
3049  "ix86_split_mmx_pack (operands, US_TRUNCATE); DONE;"
3050  [(set_attr "isa" "noavx,noavx,avx")
3051   (set_attr "type" "sselog")
3052   (set_attr "mode" "TI")])
3053
3054(define_insn_and_split "mmx_punpckhbw"
3055  [(set (match_operand:V8QI 0 "register_operand" "=y,x,Yw")
3056          (vec_select:V8QI
3057            (vec_concat:V16QI
3058              (match_operand:V8QI 1 "register_operand" "0,0,Yw")
3059              (match_operand:V8QI 2 "register_mmxmem_operand" "ym,x,Yw"))
3060          (parallel [(const_int 4) (const_int 12)
3061                     (const_int 5) (const_int 13)
3062                     (const_int 6) (const_int 14)
3063                     (const_int 7) (const_int 15)])))]
3064  "TARGET_MMX || TARGET_MMX_WITH_SSE"
3065  "@
3066   punpckhbw\t{%2, %0|%0, %2}
3067   #
3068   #"
3069  "&& reload_completed
3070   && SSE_REGNO_P (REGNO (operands[0]))"
3071  [(const_int 0)]
3072  "ix86_split_mmx_punpck (operands, true); DONE;"
3073  [(set_attr "mmx_isa" "native,sse_noavx,avx")
3074   (set_attr "type" "mmxcvt,sselog,sselog")
3075   (set_attr "mode" "DI,TI,TI")])
3076
3077(define_insn_and_split "mmx_punpckhbw_low"
3078  [(set (match_operand:V4QI 0 "register_operand" "=x,Yw")
3079          (vec_select:V4QI
3080            (vec_concat:V8QI
3081              (match_operand:V4QI 1 "register_operand" "0,Yw")
3082              (match_operand:V4QI 2 "register_operand" "x,Yw"))
3083          (parallel [(const_int 2) (const_int 6)
3084                     (const_int 3) (const_int 7)])))]
3085  "TARGET_SSE2"
3086  "#"
3087  "&& reload_completed"
3088  [(const_int 0)]
3089  "ix86_split_mmx_punpck (operands, true); DONE;"
3090  [(set_attr "isa" "noavx,avx")
3091   (set_attr "type" "sselog")
3092   (set_attr "mode" "TI")])
3093
3094(define_insn_and_split "mmx_punpcklbw"
3095  [(set (match_operand:V8QI 0 "register_operand" "=y,x,Yw")
3096          (vec_select:V8QI
3097            (vec_concat:V16QI
3098              (match_operand:V8QI 1 "register_operand" "0,0,Yw")
3099              (match_operand:V8QI 2 "register_mmxmem_operand" "ym,x,Yw"))
3100          (parallel [(const_int 0) (const_int 8)
3101                     (const_int 1) (const_int 9)
3102                     (const_int 2) (const_int 10)
3103                     (const_int 3) (const_int 11)])))]
3104  "TARGET_MMX || TARGET_MMX_WITH_SSE"
3105  "@
3106   punpcklbw\t{%2, %0|%0, %k2}
3107   #
3108   #"
3109  "&& reload_completed
3110   && SSE_REGNO_P (REGNO (operands[0]))"
3111  [(const_int 0)]
3112  "ix86_split_mmx_punpck (operands, false); DONE;"
3113  [(set_attr "mmx_isa" "native,sse_noavx,avx")
3114   (set_attr "type" "mmxcvt,sselog,sselog")
3115   (set_attr "mode" "DI,TI,TI")])
3116
3117(define_insn_and_split "mmx_punpcklbw_low"
3118  [(set (match_operand:V4QI 0 "register_operand" "=x,Yw")
3119          (vec_select:V4QI
3120            (vec_concat:V8QI
3121              (match_operand:V4QI 1 "register_operand" "0,Yw")
3122              (match_operand:V4QI 2 "register_operand" "x,Yw"))
3123          (parallel [(const_int 0) (const_int 4)
3124                     (const_int 1) (const_int 5)])))]
3125  "TARGET_SSE2"
3126  "#"
3127  "&& reload_completed"
3128  [(const_int 0)]
3129  "ix86_split_mmx_punpck (operands, false); DONE;"
3130  [(set_attr "isa" "noavx,avx")
3131   (set_attr "type" "sselog")
3132   (set_attr "mode" "TI")])
3133
3134(define_insn_and_split "mmx_punpckhwd"
3135  [(set (match_operand:V4HI 0 "register_operand" "=y,x,Yw")
3136          (vec_select:V4HI
3137            (vec_concat:V8HI
3138              (match_operand:V4HI 1 "register_operand" "0,0,Yw")
3139              (match_operand:V4HI 2 "register_mmxmem_operand" "ym,x,Yw"))
3140          (parallel [(const_int 2) (const_int 6)
3141                     (const_int 3) (const_int 7)])))]
3142  "TARGET_MMX || TARGET_MMX_WITH_SSE"
3143  "@
3144   punpckhwd\t{%2, %0|%0, %2}
3145   #
3146   #"
3147  "&& reload_completed
3148   && SSE_REGNO_P (REGNO (operands[0]))"
3149  [(const_int 0)]
3150  "ix86_split_mmx_punpck (operands, true); DONE;"
3151  [(set_attr "mmx_isa" "native,sse_noavx,avx")
3152   (set_attr "type" "mmxcvt,sselog,sselog")
3153   (set_attr "mode" "DI,TI,TI")])
3154
3155(define_insn_and_split "mmx_punpcklwd"
3156  [(set (match_operand:V4HI 0 "register_operand" "=y,x,Yw")
3157          (vec_select:V4HI
3158            (vec_concat:V8HI
3159              (match_operand:V4HI 1 "register_operand" "0,0,Yw")
3160              (match_operand:V4HI 2 "register_mmxmem_operand" "ym,x,Yw"))
3161          (parallel [(const_int 0) (const_int 4)
3162                     (const_int 1) (const_int 5)])))]
3163  "TARGET_MMX || TARGET_MMX_WITH_SSE"
3164  "@
3165   punpcklwd\t{%2, %0|%0, %k2}
3166   #
3167   #"
3168  "&& reload_completed
3169   && SSE_REGNO_P (REGNO (operands[0]))"
3170  [(const_int 0)]
3171  "ix86_split_mmx_punpck (operands, false); DONE;"
3172  [(set_attr "mmx_isa" "native,sse_noavx,avx")
3173   (set_attr "type" "mmxcvt,sselog,sselog")
3174   (set_attr "mode" "DI,TI,TI")])
3175
3176(define_insn_and_split "mmx_punpckhdq"
3177  [(set (match_operand:V2SI 0 "register_operand" "=y,x,Yv")
3178          (vec_select:V2SI
3179            (vec_concat:V4SI
3180              (match_operand:V2SI 1 "register_operand" "0,0,Yv")
3181              (match_operand:V2SI 2 "register_mmxmem_operand" "ym,x,Yv"))
3182            (parallel [(const_int 1)
3183                         (const_int 3)])))]
3184  "TARGET_MMX || TARGET_MMX_WITH_SSE"
3185  "@
3186   punpckhdq\t{%2, %0|%0, %2}
3187   #
3188   #"
3189  "&& reload_completed
3190   && SSE_REGNO_P (REGNO (operands[0]))"
3191  [(const_int 0)]
3192  "ix86_split_mmx_punpck (operands, true); DONE;"
3193  [(set_attr "mmx_isa" "native,sse_noavx,avx")
3194   (set_attr "type" "mmxcvt,sselog,sselog")
3195   (set_attr "mode" "DI,TI,TI")])
3196
3197(define_insn_and_split "mmx_punpckldq"
3198  [(set (match_operand:V2SI 0 "register_operand" "=y,x,Yv")
3199          (vec_select:V2SI
3200            (vec_concat:V4SI
3201              (match_operand:V2SI 1 "register_operand" "0,0,Yv")
3202              (match_operand:V2SI 2 "register_mmxmem_operand" "ym,x,Yv"))
3203            (parallel [(const_int 0)
3204                         (const_int 2)])))]
3205  "TARGET_MMX || TARGET_MMX_WITH_SSE"
3206  "@
3207   punpckldq\t{%2, %0|%0, %k2}
3208   #
3209   #"
3210  "&& reload_completed
3211   && SSE_REGNO_P (REGNO (operands[0]))"
3212  [(const_int 0)]
3213  "ix86_split_mmx_punpck (operands, false); DONE;"
3214  [(set_attr "mmx_isa" "native,sse_noavx,avx")
3215   (set_attr "type" "mmxcvt,sselog,sselog")
3216   (set_attr "mode" "DI,TI,TI")])
3217
3218(define_insn "sse4_1_<code>v4qiv4hi2"
3219  [(set (match_operand:V4HI 0 "register_operand" "=Yr,*x,Yw")
3220          (any_extend:V4HI
3221            (vec_select:V4QI
3222              (match_operand:V8QI 1 "register_operand" "Yr,*x,Yw")
3223              (parallel [(const_int 0) (const_int 1)
3224                           (const_int 2) (const_int 3)]))))]
3225  "TARGET_SSE4_1 && TARGET_MMX_WITH_SSE"
3226  "%vpmov<extsuffix>bw\t{%1, %0|%0, %1}"
3227  [(set_attr "isa" "noavx,noavx,avx")
3228   (set_attr "type" "ssemov")
3229   (set_attr "prefix_extra" "1")
3230   (set_attr "prefix" "orig,orig,maybe_evex")
3231   (set_attr "mode" "TI")])
3232
3233(define_insn "sse4_1_<code>v2hiv2si2"
3234  [(set (match_operand:V2SI 0 "register_operand" "=Yr,*x,v")
3235          (any_extend:V2SI
3236            (vec_select:V2HI
3237              (match_operand:V4HI 1 "register_operand" "Yr,*x,v")
3238              (parallel [(const_int 0) (const_int 1)]))))]
3239  "TARGET_SSE4_1 && TARGET_MMX_WITH_SSE"
3240  "%vpmov<extsuffix>wd\t{%1, %0|%0, %1}"
3241  [(set_attr "isa" "noavx,noavx,avx")
3242   (set_attr "type" "ssemov")
3243   (set_attr "prefix_extra" "1")
3244   (set_attr "prefix" "orig,orig,maybe_evex")
3245   (set_attr "mode" "TI")])
3246
3247(define_insn "sse4_1_<code>v2qiv2hi2"
3248  [(set (match_operand:V2HI 0 "register_operand" "=Yr,*x,Yw")
3249          (any_extend:V2HI
3250            (vec_select:V2QI
3251              (match_operand:V4QI 1 "register_operand" "Yr,*x,Yw")
3252              (parallel [(const_int 0) (const_int 1)]))))]
3253  "TARGET_SSE4_1"
3254  "%vpmov<extsuffix>bw\t{%1, %0|%0, %1}"
3255  [(set_attr "isa" "noavx,noavx,avx")
3256   (set_attr "type" "ssemov")
3257   (set_attr "prefix_extra" "1")
3258   (set_attr "prefix" "orig,orig,maybe_evex")
3259   (set_attr "mode" "TI")])
3260
3261;; Pack/unpack vector modes
3262(define_mode_attr mmxpackmode
3263  [(V4HI "V8QI") (V2SI "V4HI")])
3264
3265(define_expand "vec_pack_trunc_<mode>"
3266  [(match_operand:<mmxpackmode> 0 "register_operand")
3267   (match_operand:MMXMODE24 1 "register_operand")
3268   (match_operand:MMXMODE24 2 "register_operand")]
3269  "TARGET_MMX_WITH_SSE"
3270{
3271  rtx op1 = gen_lowpart (<mmxpackmode>mode, operands[1]);
3272  rtx op2 = gen_lowpart (<mmxpackmode>mode, operands[2]);
3273  ix86_expand_vec_extract_even_odd (operands[0], op1, op2, 0);
3274  DONE;
3275})
3276
3277(define_expand "vec_pack_trunc_v2hi"
3278  [(match_operand:V4QI 0 "register_operand")
3279   (match_operand:V2HI 1 "register_operand")
3280   (match_operand:V2HI 2 "register_operand")]
3281  "TARGET_SSE2"
3282{
3283  rtx op1 = gen_lowpart (V4QImode, operands[1]);
3284  rtx op2 = gen_lowpart (V4QImode, operands[2]);
3285  ix86_expand_vec_extract_even_odd (operands[0], op1, op2, 0);
3286  DONE;
3287})
3288
3289(define_mode_attr mmxunpackmode
3290  [(V8QI "V4HI") (V4HI "V2SI")])
3291
3292(define_expand "vec_unpacks_lo_<mode>"
3293  [(match_operand:<mmxunpackmode> 0 "register_operand")
3294   (match_operand:MMXMODE12 1 "register_operand")]
3295  "TARGET_MMX_WITH_SSE"
3296  "ix86_expand_sse_unpack (operands[0], operands[1], false, false); DONE;")
3297
3298(define_expand "vec_unpacks_hi_<mode>"
3299  [(match_operand:<mmxunpackmode> 0 "register_operand")
3300   (match_operand:MMXMODE12 1 "register_operand")]
3301  "TARGET_MMX_WITH_SSE"
3302  "ix86_expand_sse_unpack (operands[0], operands[1], false, true); DONE;")
3303
3304(define_expand "vec_unpacku_lo_<mode>"
3305  [(match_operand:<mmxunpackmode> 0 "register_operand")
3306   (match_operand:MMXMODE12 1 "register_operand")]
3307  "TARGET_MMX_WITH_SSE"
3308  "ix86_expand_sse_unpack (operands[0], operands[1], true, false); DONE;")
3309
3310(define_expand "vec_unpacku_hi_<mode>"
3311  [(match_operand:<mmxunpackmode> 0 "register_operand")
3312   (match_operand:MMXMODE12 1 "register_operand")]
3313  "TARGET_MMX_WITH_SSE"
3314  "ix86_expand_sse_unpack (operands[0], operands[1], true, true); DONE;")
3315
3316(define_expand "vec_unpacks_lo_v4qi"
3317  [(match_operand:V2HI 0 "register_operand")
3318   (match_operand:V4QI 1 "register_operand")]
3319  "TARGET_SSE2"
3320  "ix86_expand_sse_unpack (operands[0], operands[1], false, false); DONE;")
3321
3322(define_expand "vec_unpacks_hi_v4qi"
3323  [(match_operand:V2HI 0 "register_operand")
3324   (match_operand:V4QI 1 "register_operand")]
3325  "TARGET_SSE2"
3326  "ix86_expand_sse_unpack (operands[0], operands[1], false, true); DONE;")
3327
3328(define_expand "vec_unpacku_lo_v4qi"
3329  [(match_operand:V2HI 0 "register_operand")
3330   (match_operand:V4QI 1 "register_operand")]
3331  "TARGET_SSE2"
3332  "ix86_expand_sse_unpack (operands[0], operands[1], true, false); DONE;")
3333
3334(define_expand "vec_unpacku_hi_v4qi"
3335  [(match_operand:V2HI 0 "register_operand")
3336   (match_operand:V4QI 1 "register_operand")]
3337  "TARGET_SSE2"
3338  "ix86_expand_sse_unpack (operands[0], operands[1], true, true); DONE;")
3339
3340(define_insn "*mmx_pinsrd"
3341  [(set (match_operand:V2SI 0 "register_operand" "=x,Yv")
3342        (vec_merge:V2SI
3343          (vec_duplicate:V2SI
3344            (match_operand:SI 2 "nonimmediate_operand" "rm,rm"))
3345            (match_operand:V2SI 1 "register_operand" "0,Yv")
3346          (match_operand:SI 3 "const_int_operand")))]
3347  "TARGET_SSE4_1 && TARGET_MMX_WITH_SSE
3348   && ((unsigned) exact_log2 (INTVAL (operands[3]))
3349       < GET_MODE_NUNITS (V2SImode))"
3350{
3351  operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])));
3352  switch (which_alternative)
3353    {
3354    case 1:
3355      return "vpinsrd\t{%3, %2, %1, %0|%0, %1, %2, %3}";
3356    case 0:
3357      return "pinsrd\t{%3, %2, %0|%0, %2, %3}";
3358    default:
3359      gcc_unreachable ();
3360    }
3361}
3362  [(set_attr "isa" "noavx,avx")
3363   (set_attr "prefix_data16" "1")
3364   (set_attr "prefix_extra" "1")
3365   (set_attr "type" "sselog")
3366   (set_attr "length_immediate" "1")
3367   (set_attr "prefix" "orig,vex")
3368   (set_attr "mode" "TI")])
3369
3370(define_expand "mmx_pinsrw"
3371  [(set (match_operand:V4HI 0 "register_operand")
3372        (vec_merge:V4HI
3373          (vec_duplicate:V4HI
3374            (match_operand:SI 2 "nonimmediate_operand"))
3375            (match_operand:V4HI 1 "register_operand")
3376          (match_operand:SI 3 "const_0_to_3_operand")))]
3377  "(TARGET_MMX || TARGET_MMX_WITH_SSE)
3378   && (TARGET_SSE || TARGET_3DNOW_A)"
3379{
3380  operands[2] = gen_lowpart (HImode, operands[2]);
3381  operands[3] = GEN_INT (1 << INTVAL (operands[3]));
3382})
3383
3384(define_insn "*mmx_pinsrw"
3385  [(set (match_operand:V4HI 0 "register_operand" "=y,x,YW")
3386        (vec_merge:V4HI
3387          (vec_duplicate:V4HI
3388            (match_operand:HI 2 "nonimmediate_operand" "rm,rm,rm"))
3389            (match_operand:V4HI 1 "register_operand" "0,0,YW")
3390          (match_operand:SI 3 "const_int_operand")))]
3391  "(TARGET_MMX || TARGET_MMX_WITH_SSE)
3392   && (TARGET_SSE || TARGET_3DNOW_A)
3393   && ((unsigned) exact_log2 (INTVAL (operands[3]))
3394       < GET_MODE_NUNITS (V4HImode))"
3395{
3396  operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])));
3397  switch (which_alternative)
3398    {
3399    case 2:
3400      if (MEM_P (operands[2]))
3401          return "vpinsrw\t{%3, %2, %1, %0|%0, %1, %2, %3}";
3402      else
3403          return "vpinsrw\t{%3, %k2, %1, %0|%0, %1, %k2, %3}";
3404    case 1:
3405    case 0:
3406      if (MEM_P (operands[2]))
3407          return "pinsrw\t{%3, %2, %0|%0, %2, %3}";
3408      else
3409          return "pinsrw\t{%3, %k2, %0|%0, %k2, %3}";
3410    default:
3411      gcc_unreachable ();
3412    }
3413}
3414  [(set_attr "isa" "*,sse2_noavx,avx")
3415   (set_attr "mmx_isa" "native,*,*")
3416   (set_attr "type" "mmxcvt,sselog,sselog")
3417   (set_attr "length_immediate" "1")
3418   (set_attr "mode" "DI,TI,TI")])
3419
3420(define_insn "*mmx_pinsrb"
3421  [(set (match_operand:V8QI 0 "register_operand" "=x,YW")
3422        (vec_merge:V8QI
3423          (vec_duplicate:V8QI
3424            (match_operand:QI 2 "nonimmediate_operand" "rm,rm"))
3425            (match_operand:V8QI 1 "register_operand" "0,YW")
3426          (match_operand:SI 3 "const_int_operand")))]
3427  "TARGET_SSE4_1 && TARGET_MMX_WITH_SSE
3428   && ((unsigned) exact_log2 (INTVAL (operands[3]))
3429       < GET_MODE_NUNITS (V8QImode))"
3430{
3431  operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])));
3432  switch (which_alternative)
3433    {
3434    case 1:
3435      if (MEM_P (operands[2]))
3436          return "vpinsrb\t{%3, %2, %1, %0|%0, %1, %2, %3}";
3437      else
3438          return "vpinsrb\t{%3, %k2, %1, %0|%0, %1, %k2, %3}";
3439    case 0:
3440      if (MEM_P (operands[2]))
3441          return "pinsrb\t{%3, %2, %0|%0, %2, %3}";
3442      else
3443          return "pinsrb\t{%3, %k2, %0|%0, %k2, %3}";
3444    default:
3445      gcc_unreachable ();
3446    }
3447}
3448  [(set_attr "isa" "noavx,avx")
3449   (set_attr "type" "sselog")
3450   (set_attr "prefix_data16" "1")
3451   (set_attr "prefix_extra" "1")
3452   (set_attr "length_immediate" "1")
3453   (set_attr "prefix" "orig,vex")
3454   (set_attr "mode" "TI")])
3455
3456(define_insn "*mmx_pextrw"
3457  [(set (match_operand:HI 0 "register_sse4nonimm_operand" "=r,r,m")
3458          (vec_select:HI
3459            (match_operand:V4HI 1 "register_operand" "y,YW,YW")
3460            (parallel [(match_operand:SI 2 "const_0_to_3_operand" "n,n,n")])))]
3461  "(TARGET_MMX || TARGET_MMX_WITH_SSE)
3462   && (TARGET_SSE || TARGET_3DNOW_A)"
3463  "@
3464   pextrw\t{%2, %1, %k0|%k0, %1, %2}
3465   %vpextrw\t{%2, %1, %k0|%k0, %1, %2}
3466   %vpextrw\t{%2, %1, %0|%0, %1, %2}"
3467  [(set_attr "isa" "*,sse2,sse4")
3468   (set_attr "mmx_isa" "native,*,*")
3469   (set_attr "type" "mmxcvt,sselog1,sselog1")
3470   (set_attr "length_immediate" "1")
3471   (set_attr "prefix" "orig,maybe_vex,maybe_vex")
3472   (set_attr "mode" "DI,TI,TI")])
3473
3474(define_insn "*mmx_pextrw_zext"
3475  [(set (match_operand:SWI48 0 "register_operand" "=r,r")
3476          (zero_extend:SWI48
3477            (vec_select:HI
3478              (match_operand:V4HI 1 "register_operand" "y,YW")
3479              (parallel [(match_operand:SI 2 "const_0_to_3_operand" "n,n")]))))]
3480  "(TARGET_MMX || TARGET_MMX_WITH_SSE)
3481   && (TARGET_SSE || TARGET_3DNOW_A)"
3482  "@
3483   pextrw\t{%2, %1, %k0|%k0, %1, %2}
3484   %vpextrw\t{%2, %1, %k0|%k0, %1, %2}"
3485  [(set_attr "isa" "*,sse2")
3486   (set_attr "mmx_isa" "native,*")
3487   (set_attr "type" "mmxcvt,sselog1")
3488   (set_attr "length_immediate" "1")
3489   (set_attr "prefix" "orig,maybe_vex")
3490   (set_attr "mode" "DI,TI")])
3491
3492(define_insn "*mmx_pextrb"
3493  [(set (match_operand:QI 0 "nonimmediate_operand" "=r,m")
3494          (vec_select:QI
3495            (match_operand:V8QI 1 "register_operand" "YW,YW")
3496            (parallel [(match_operand:SI 2 "const_0_to_7_operand" "n,n")])))]
3497  "TARGET_SSE4_1 && TARGET_MMX_WITH_SSE"
3498  "@
3499   %vpextrb\t{%2, %1, %k0|%k0, %1, %2}
3500   %vpextrb\t{%2, %1, %0|%0, %1, %2}"
3501  [(set_attr "type" "sselog1")
3502   (set_attr "prefix_data16" "1")
3503   (set_attr "prefix_extra" "1")
3504   (set_attr "length_immediate" "1")
3505   (set_attr "prefix" "maybe_vex")
3506   (set_attr "mode" "TI")])
3507
3508(define_insn "*mmx_pextrb_zext"
3509  [(set (match_operand:SWI248 0 "register_operand" "=r")
3510          (zero_extend:SWI248
3511            (vec_select:QI
3512              (match_operand:V8QI 1 "register_operand" "YW")
3513              (parallel [(match_operand:SI 2 "const_0_to_7_operand" "n")]))))]
3514  "TARGET_SSE4_1 && TARGET_MMX_WITH_SSE"
3515  "%vpextrb\t{%2, %1, %k0|%k0, %1, %2}"
3516  [(set_attr "type" "sselog1")
3517   (set_attr "prefix_data16" "1")
3518   (set_attr "prefix_extra" "1")
3519   (set_attr "length_immediate" "1")
3520   (set_attr "prefix" "maybe_vex")
3521   (set_attr "mode" "TI")])
3522
3523(define_insn "mmx_pshufbv8qi3"
3524  [(set (match_operand:V8QI 0 "register_operand" "=x,Yw")
3525          (unspec:V8QI
3526            [(match_operand:V8QI 1 "register_operand" "0,Yw")
3527             (match_operand:V16QI 2 "vector_operand" "xBm,Ywm")]
3528            UNSPEC_PSHUFB))]
3529  "TARGET_SSSE3 && TARGET_MMX_WITH_SSE"
3530  "@
3531   pshufb\t{%2, %0|%0, %2}
3532   vpshufb\t{%2, %1, %0|%0, %1, %2}"
3533  [(set_attr "isa" "noavx,avx")
3534   (set_attr "type" "sselog1")
3535   (set_attr "prefix_data16" "1,*")
3536   (set_attr "prefix_extra" "1")
3537   (set_attr "prefix" "orig,maybe_evex")
3538   (set_attr "btver2_decode" "vector")
3539   (set_attr "mode" "TI")])
3540
3541(define_insn "mmx_pshufbv4qi3"
3542  [(set (match_operand:V4QI 0 "register_operand" "=x,Yw")
3543          (unspec:V4QI
3544            [(match_operand:V4QI 1 "register_operand" "0,Yw")
3545             (match_operand:V16QI 2 "vector_operand" "xBm,Ywm")]
3546            UNSPEC_PSHUFB))]
3547  "TARGET_SSSE3"
3548  "@
3549   pshufb\t{%2, %0|%0, %2}
3550   vpshufb\t{%2, %1, %0|%0, %1, %2}"
3551  [(set_attr "isa" "noavx,avx")
3552   (set_attr "type" "sselog1")
3553   (set_attr "prefix_data16" "1,*")
3554   (set_attr "prefix_extra" "1")
3555   (set_attr "prefix" "orig,maybe_evex")
3556   (set_attr "btver2_decode" "vector")
3557   (set_attr "mode" "TI")])
3558
3559(define_expand "mmx_pshufw"
3560  [(match_operand:V4HI 0 "register_operand")
3561   (match_operand:V4HI 1 "register_mmxmem_operand")
3562   (match_operand:SI 2 "const_int_operand")]
3563  "(TARGET_MMX || TARGET_MMX_WITH_SSE)
3564   && (TARGET_SSE || TARGET_3DNOW_A)"
3565{
3566  int mask = INTVAL (operands[2]);
3567  emit_insn (gen_mmx_pshufw_1 (operands[0], operands[1],
3568                               GEN_INT ((mask >> 0) & 3),
3569                               GEN_INT ((mask >> 2) & 3),
3570                               GEN_INT ((mask >> 4) & 3),
3571                               GEN_INT ((mask >> 6) & 3)));
3572  DONE;
3573})
3574
3575(define_insn "mmx_pshufw_1"
3576  [(set (match_operand:V4HI 0 "register_operand" "=y,Yw")
3577        (vec_select:V4HI
3578            (match_operand:V4HI 1 "register_mmxmem_operand" "ym,Yw")
3579          (parallel [(match_operand 2 "const_0_to_3_operand")
3580                     (match_operand 3 "const_0_to_3_operand")
3581                     (match_operand 4 "const_0_to_3_operand")
3582                     (match_operand 5 "const_0_to_3_operand")])))]
3583  "(TARGET_MMX || TARGET_MMX_WITH_SSE)
3584   && (TARGET_SSE || TARGET_3DNOW_A)"
3585{
3586  int mask = 0;
3587  mask |= INTVAL (operands[2]) << 0;
3588  mask |= INTVAL (operands[3]) << 2;
3589  mask |= INTVAL (operands[4]) << 4;
3590  mask |= INTVAL (operands[5]) << 6;
3591  operands[2] = GEN_INT (mask);
3592
3593  switch (which_alternative)
3594    {
3595    case 0:
3596      return "pshufw\t{%2, %1, %0|%0, %1, %2}";
3597    case 1:
3598      return "%vpshuflw\t{%2, %1, %0|%0, %1, %2}";
3599    default:
3600      gcc_unreachable ();
3601    }
3602}
3603  [(set_attr "isa" "*,sse2")
3604   (set_attr "mmx_isa" "native,*")
3605   (set_attr "type" "mmxcvt,sselog1")
3606   (set_attr "length_immediate" "1")
3607   (set_attr "mode" "DI,TI")])
3608
3609(define_insn "*mmx_pshufd_1"
3610  [(set (match_operand:V2SI 0 "register_operand" "=Yv")
3611        (vec_select:V2SI
3612          (match_operand:V2SI 1 "register_operand" "Yv")
3613          (parallel [(match_operand 2 "const_0_to_1_operand")
3614                     (match_operand 3 "const_0_to_1_operand")])))]
3615  "TARGET_MMX_WITH_SSE"
3616{
3617  int mask = 0;
3618  mask |= INTVAL (operands[2]) << 0;
3619  mask |= INTVAL (operands[3]) << 2;
3620  mask |= 2 << 4;
3621  mask |= 3 << 6;
3622  operands[2] = GEN_INT (mask);
3623
3624  return "%vpshufd\t{%2, %1, %0|%0, %1, %2}";
3625}
3626  [(set_attr "type" "sselog1")
3627   (set_attr "prefix_data16" "1")
3628   (set_attr "length_immediate" "1")
3629   (set_attr "mode" "TI")])
3630
3631(define_insn "*mmx_pblendw64"
3632  [(set (match_operand:V4HI 0 "register_operand" "=Yr,*x,x")
3633          (vec_merge:V4HI
3634            (match_operand:V4HI 2 "register_operand" "Yr,*x,x")
3635            (match_operand:V4HI 1 "register_operand" "0,0,x")
3636            (match_operand:SI 3 "const_0_to_15_operand" "n,n,n")))]
3637  "TARGET_SSE4_1 && TARGET_MMX_WITH_SSE"
3638  "@
3639   pblendw\t{%3, %2, %0|%0, %2, %3}
3640   pblendw\t{%3, %2, %0|%0, %2, %3}
3641   vpblendw\t{%3, %2, %1, %0|%0, %1, %2, %3}"
3642  [(set_attr "isa" "noavx,noavx,avx")
3643   (set_attr "type" "ssemov")
3644   (set_attr "prefix_extra" "1")
3645   (set_attr "length_immediate" "1")
3646   (set_attr "prefix" "orig,orig,vex")
3647   (set_attr "mode" "TI")])
3648
3649(define_insn "*mmx_pblendw32"
3650  [(set (match_operand:V2HI 0 "register_operand" "=Yr,*x,x")
3651          (vec_merge:V2HI
3652            (match_operand:V2HI 2 "register_operand" "Yr,*x,x")
3653            (match_operand:V2HI 1 "register_operand" "0,0,x")
3654            (match_operand:SI 3 "const_0_to_7_operand" "n,n,n")))]
3655  "TARGET_SSE4_1"
3656  "@
3657   pblendw\t{%3, %2, %0|%0, %2, %3}
3658   pblendw\t{%3, %2, %0|%0, %2, %3}
3659   vpblendw\t{%3, %2, %1, %0|%0, %1, %2, %3}"
3660  [(set_attr "isa" "noavx,noavx,avx")
3661   (set_attr "type" "ssemov")
3662   (set_attr "prefix_extra" "1")
3663   (set_attr "length_immediate" "1")
3664   (set_attr "prefix" "orig,orig,vex")
3665   (set_attr "mode" "TI")])
3666
3667;; Optimize V2SImode load from memory, swapping the elements and
3668;; storing back into the memory into DImode rotate of the memory by 32.
3669(define_split
3670  [(set (match_operand:V2SI 0 "memory_operand")
3671          (vec_select:V2SI (match_dup 0)
3672            (parallel [(const_int 1) (const_int 0)])))]
3673  "TARGET_64BIT && (TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
3674  [(set (match_dup 0)
3675          (rotate:DI (match_dup 0) (const_int 32)))]
3676  "operands[0] = adjust_address (operands[0], DImode, 0);")
3677
3678(define_insn "mmx_pswapdv2si2"
3679  [(set (match_operand:V2SI 0 "register_operand" "=y,Yv")
3680          (vec_select:V2SI
3681            (match_operand:V2SI 1 "register_mmxmem_operand" "ym,Yv")
3682            (parallel [(const_int 1) (const_int 0)])))]
3683  "TARGET_3DNOW_A"
3684  "@
3685   pswapd\t{%1, %0|%0, %1}
3686   %vpshufd\t{$0xe1, %1, %0|%0, %1, 0xe1}";
3687  [(set_attr "isa" "*,sse2")
3688   (set_attr "mmx_isa" "native,*")
3689   (set_attr "type" "mmxcvt,sselog1")
3690   (set_attr "prefix_extra" "1,*")
3691   (set_attr "prefix_data16" "*,1")
3692   (set_attr "length_immediate" "*,1")
3693   (set_attr "mode" "DI,TI")])
3694
3695(define_insn "*vec_dupv4hi"
3696  [(set (match_operand:V4HI 0 "register_operand" "=y,Yw")
3697          (vec_duplicate:V4HI
3698            (truncate:HI
3699              (match_operand:SI 1 "register_operand" "0,Yw"))))]
3700  "(TARGET_MMX || TARGET_MMX_WITH_SSE)
3701   && (TARGET_SSE || TARGET_3DNOW_A)"
3702  "@
3703   pshufw\t{$0, %0, %0|%0, %0, 0}
3704   %vpshuflw\t{$0, %1, %0|%0, %1, 0}"
3705  [(set_attr "isa" "*,sse2")
3706   (set_attr "mmx_isa" "native,*")
3707   (set_attr "type" "mmxcvt,sselog1")
3708   (set_attr "length_immediate" "1")
3709   (set_attr "mode" "DI,TI")])
3710
3711
3712(define_insn "*vec_dupv2si"
3713  [(set (match_operand:V2SI 0 "register_operand" "=y,Yv")
3714          (vec_duplicate:V2SI
3715            (match_operand:SI 1 "register_operand" "0,Yv")))]
3716  "TARGET_MMX || TARGET_MMX_WITH_SSE"
3717  "@
3718   punpckldq\t%0, %0
3719   %vpshufd\t{$0xe0, %1, %0|%0, %1, 0xe0}"
3720  [(set_attr "isa" "*,sse2")
3721   (set_attr "mmx_isa" "native,*")
3722   (set_attr "type" "mmxcvt,sselog1")
3723   (set_attr "prefix_data16" "*,1")
3724   (set_attr "length_immediate" "*,1")
3725   (set_attr "mode" "DI,TI")])
3726
3727(define_insn "*mmx_concatv2si"
3728  [(set (match_operand:V2SI 0 "register_operand"     "=y,y")
3729          (vec_concat:V2SI
3730            (match_operand:SI 1 "nonimmediate_operand" " 0,rm")
3731            (match_operand:SI 2 "nonimm_or_0_operand"  "ym,C")))]
3732  "TARGET_MMX && !TARGET_SSE"
3733  "@
3734   punpckldq\t{%2, %0|%0, %2}
3735   movd\t{%1, %0|%0, %1}"
3736  [(set_attr "type" "mmxcvt,mmxmov")
3737   (set_attr "mode" "DI")])
3738
3739(define_expand "vec_setv2si"
3740  [(match_operand:V2SI 0 "register_operand")
3741   (match_operand:SI 1 "register_operand")
3742   (match_operand 2 "vec_setm_mmx_operand")]
3743  "TARGET_MMX || TARGET_MMX_WITH_SSE"
3744{
3745  if (CONST_INT_P (operands[2]))
3746    ix86_expand_vector_set (TARGET_MMX_WITH_SSE, operands[0], operands[1],
3747                                  INTVAL (operands[2]));
3748  else
3749    ix86_expand_vector_set_var (operands[0], operands[1], operands[2]);
3750  DONE;
3751})
3752
3753;; Avoid combining registers from different units in a single alternative,
3754;; see comment above inline_secondary_memory_needed function in i386.cc
3755(define_insn_and_split "*vec_extractv2si_0"
3756  [(set (match_operand:SI 0 "nonimmediate_operand"     "=x,m,y, m,r,r")
3757          (vec_select:SI
3758            (match_operand:V2SI 1 "nonimmediate_operand" "xm,x,ym,y,m,x")
3759            (parallel [(const_int 0)])))]
3760  "(TARGET_MMX || TARGET_MMX_WITH_SSE)
3761   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3762  "#"
3763  "&& reload_completed"
3764  [(set (match_dup 0) (match_dup 1))]
3765  "operands[1] = gen_lowpart (SImode, operands[1]);"
3766  [(set_attr "isa" "*,*,*,*,*,sse2")
3767   (set_attr "mmx_isa" "*,*,native,native,*,*")
3768   (set (attr "preferred_for_speed")
3769     (cond [(eq_attr "alternative" "5")
3770                (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
3771             ]
3772             (symbol_ref "true")))])
3773
3774(define_insn "*vec_extractv2si_0_zext_sse4"
3775  [(set (match_operand:DI 0 "register_operand" "=r,x")
3776          (zero_extend:DI
3777            (vec_select:SI
3778              (match_operand:V2SI 1 "register_operand" "x,x")
3779              (parallel [(const_int 0)]))))]
3780  "(TARGET_MMX || TARGET_MMX_WITH_SSE) && TARGET_SSE4_1"
3781  "#"
3782  [(set_attr "isa" "x64,*")
3783   (set (attr "preferred_for_speed")
3784     (cond [(eq_attr "alternative" "0")
3785                (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
3786             ]
3787             (symbol_ref "true")))])
3788
3789(define_insn "*vec_extractv2si_0_zext"
3790  [(set (match_operand:DI 0 "register_operand" "=r")
3791          (zero_extend:DI
3792            (vec_select:SI
3793              (match_operand:V2SI 1 "register_operand" "x")
3794              (parallel [(const_int 0)]))))]
3795  "(TARGET_MMX || TARGET_MMX_WITH_SSE)
3796   && TARGET_64BIT && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_FROM_VEC"
3797  "#")
3798
3799(define_split
3800  [(set (match_operand:DI 0 "register_operand")
3801          (zero_extend:DI
3802            (vec_select:SI
3803              (match_operand:V2SI 1 "register_operand")
3804              (parallel [(const_int 0)]))))]
3805  "(TARGET_MMX || TARGET_MMX_WITH_SSE)
3806   && TARGET_SSE2 && reload_completed"
3807  [(set (match_dup 0) (zero_extend:DI (match_dup 1)))]
3808  "operands[1] = gen_lowpart (SImode, operands[1]);")
3809
3810;; Avoid combining registers from different units in a single alternative,
3811;; see comment above inline_secondary_memory_needed function in i386.cc
3812(define_insn "*vec_extractv2si_1"
3813  [(set (match_operand:SI 0 "nonimmediate_operand"     "=y,rm,x,x,y,x,r")
3814          (vec_select:SI
3815            (match_operand:V2SI 1 "nonimmediate_operand" " 0,x ,x,0,o,o,o")
3816            (parallel [(const_int 1)])))]
3817  "(TARGET_MMX || TARGET_MMX_WITH_SSE)
3818   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3819  "@
3820   punpckhdq\t%0, %0
3821   %vpextrd\t{$1, %1, %0|%0, %1, 1}
3822   %vpshufd\t{$0xe5, %1, %0|%0, %1, 0xe5}
3823   shufps\t{$0xe5, %0, %0|%0, %0, 0xe5}
3824   #
3825   #
3826   #"
3827  [(set_attr "isa" "*,sse4,sse2,noavx,*,*,*")
3828   (set_attr "mmx_isa" "native,*,*,*,native,*,*")
3829   (set_attr "type" "mmxcvt,ssemov,sseshuf1,sseshuf1,mmxmov,ssemov,imov")
3830   (set (attr "length_immediate")
3831     (if_then_else (eq_attr "alternative" "1,2,3")
3832                       (const_string "1")
3833                       (const_string "*")))
3834   (set_attr "prefix" "orig,maybe_vex,maybe_vex,orig,orig,orig,orig")
3835   (set_attr "mode" "DI,TI,TI,V4SF,SI,SI,SI")])
3836
3837(define_split
3838  [(set (match_operand:SI 0 "register_operand")
3839          (vec_select:SI
3840            (match_operand:V2SI 1 "memory_operand")
3841            (parallel [(const_int 1)])))]
3842  "(TARGET_MMX || TARGET_MMX_WITH_SSE) && reload_completed"
3843  [(set (match_dup 0) (match_dup 1))]
3844  "operands[1] = adjust_address (operands[1], SImode, 4);")
3845
3846(define_insn "*vec_extractv2si_1_zext"
3847  [(set (match_operand:DI 0 "register_operand" "=r")
3848          (zero_extend:DI
3849            (vec_select:SI
3850              (match_operand:V2SI 1 "register_operand" "x")
3851              (parallel [(const_int 1)]))))]
3852  "(TARGET_MMX || TARGET_MMX_WITH_SSE)
3853   && TARGET_64BIT && TARGET_SSE4_1"
3854  "%vpextrd\t{$1, %1, %k0|%k0, %1, 1}"
3855  [(set_attr "type" "sselog1")
3856   (set_attr "prefix_extra" "1")
3857   (set_attr "length_immediate" "1")
3858   (set_attr "prefix" "maybe_vex")
3859   (set_attr "mode" "TI")])
3860
3861(define_insn_and_split "*vec_extractv2si_zext_mem"
3862  [(set (match_operand:DI 0 "register_operand" "=y,x,r")
3863          (zero_extend:DI
3864            (vec_select:SI
3865              (match_operand:V2SI 1 "memory_operand" "o,o,o")
3866              (parallel [(match_operand:SI 2 "const_0_to_1_operand")]))))]
3867  "(TARGET_MMX || TARGET_MMX_WITH_SSE) && TARGET_64BIT"
3868  "#"
3869  "&& reload_completed"
3870  [(set (match_dup 0) (zero_extend:DI (match_dup 1)))]
3871{
3872  operands[1] = adjust_address (operands[1], SImode, INTVAL (operands[2]) * 4);
3873}
3874  [(set_attr "isa" "*,sse2,*")
3875   (set_attr "mmx_isa" "native,*,*")])
3876
3877(define_expand "vec_extractv2sisi"
3878  [(match_operand:SI 0 "register_operand")
3879   (match_operand:V2SI 1 "register_operand")
3880   (match_operand 2 "const_int_operand")]
3881  "TARGET_MMX || TARGET_MMX_WITH_SSE"
3882{
3883  ix86_expand_vector_extract (TARGET_MMX_WITH_SSE, operands[0],
3884                                    operands[1], INTVAL (operands[2]));
3885  DONE;
3886})
3887
3888(define_expand "vec_initv2sisi"
3889  [(match_operand:V2SI 0 "register_operand")
3890   (match_operand 1)]
3891  "(TARGET_MMX || TARGET_MMX_WITH_SSE) && TARGET_SSE"
3892{
3893  ix86_expand_vector_init (TARGET_MMX_WITH_SSE, operands[0],
3894                                 operands[1]);
3895  DONE;
3896})
3897
3898(define_expand "vec_setv4hi"
3899  [(match_operand:V4HI 0 "register_operand")
3900   (match_operand:HI 1 "register_operand")
3901   (match_operand 2 "vec_setm_mmx_operand")]
3902  "TARGET_MMX || TARGET_MMX_WITH_SSE"
3903{
3904  if (CONST_INT_P (operands[2]))
3905    ix86_expand_vector_set (TARGET_MMX_WITH_SSE, operands[0], operands[1],
3906                                  INTVAL (operands[2]));
3907  else
3908    ix86_expand_vector_set_var (operands[0], operands[1], operands[2]);
3909  DONE;
3910})
3911
3912(define_expand "vec_extractv4hihi"
3913  [(match_operand:HI 0 "register_operand")
3914   (match_operand:V4HI 1 "register_operand")
3915   (match_operand 2 "const_int_operand")]
3916  "TARGET_MMX || TARGET_MMX_WITH_SSE"
3917{
3918  ix86_expand_vector_extract (TARGET_MMX_WITH_SSE, operands[0],
3919                                    operands[1], INTVAL (operands[2]));
3920  DONE;
3921})
3922
3923(define_expand "vec_initv4hihi"
3924  [(match_operand:V4HI 0 "register_operand")
3925   (match_operand 1)]
3926  "(TARGET_MMX || TARGET_MMX_WITH_SSE) && TARGET_SSE"
3927{
3928  ix86_expand_vector_init (TARGET_MMX_WITH_SSE, operands[0],
3929                                 operands[1]);
3930  DONE;
3931})
3932
3933(define_expand "vec_setv8qi"
3934  [(match_operand:V8QI 0 "register_operand")
3935   (match_operand:QI 1 "register_operand")
3936   (match_operand 2 "vec_setm_mmx_operand")]
3937  "TARGET_SSE4_1 && TARGET_MMX_WITH_SSE"
3938{
3939  if (CONST_INT_P (operands[2]))
3940    ix86_expand_vector_set (TARGET_MMX_WITH_SSE, operands[0], operands[1],
3941                                  INTVAL (operands[2]));
3942  else
3943    ix86_expand_vector_set_var (operands[0], operands[1], operands[2]);
3944  DONE;
3945})
3946
3947(define_expand "vec_extractv8qiqi"
3948  [(match_operand:QI 0 "register_operand")
3949   (match_operand:V8QI 1 "register_operand")
3950   (match_operand 2 "const_int_operand")]
3951  "TARGET_SSE4_1 && TARGET_MMX_WITH_SSE"
3952{
3953  ix86_expand_vector_extract (TARGET_MMX_WITH_SSE, operands[0],
3954                                    operands[1], INTVAL (operands[2]));
3955  DONE;
3956})
3957
3958(define_expand "vec_initv8qiqi"
3959  [(match_operand:V8QI 0 "register_operand")
3960   (match_operand 1)]
3961  "(TARGET_MMX || TARGET_MMX_WITH_SSE) && TARGET_SSE"
3962{
3963  ix86_expand_vector_init (TARGET_MMX_WITH_SSE, operands[0],
3964                                 operands[1]);
3965  DONE;
3966})
3967
3968(define_insn "*pinsrw"
3969  [(set (match_operand:V2HI 0 "register_operand" "=x,YW")
3970        (vec_merge:V2HI
3971          (vec_duplicate:V2HI
3972            (match_operand:HI 2 "nonimmediate_operand" "rm,rm"))
3973            (match_operand:V2HI 1 "register_operand" "0,YW")
3974          (match_operand:SI 3 "const_int_operand")))]
3975  "TARGET_SSE2
3976   && ((unsigned) exact_log2 (INTVAL (operands[3]))
3977       < GET_MODE_NUNITS (V2HImode))"
3978{
3979  operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])));
3980  switch (which_alternative)
3981    {
3982    case 1:
3983      if (MEM_P (operands[2]))
3984          return "vpinsrw\t{%3, %2, %1, %0|%0, %1, %2, %3}";
3985      else
3986          return "vpinsrw\t{%3, %k2, %1, %0|%0, %1, %k2, %3}";
3987    case 0:
3988      if (MEM_P (operands[2]))
3989          return "pinsrw\t{%3, %2, %0|%0, %2, %3}";
3990      else
3991          return "pinsrw\t{%3, %k2, %0|%0, %k2, %3}";
3992    default:
3993      gcc_unreachable ();
3994    }
3995}
3996  [(set_attr "isa" "noavx,avx")
3997   (set_attr "type" "sselog")
3998   (set_attr "length_immediate" "1")
3999   (set_attr "mode" "TI")])
4000
4001(define_insn "*pinsrb"
4002  [(set (match_operand:V4QI 0 "register_operand" "=x,YW")
4003        (vec_merge:V4QI
4004          (vec_duplicate:V4QI
4005            (match_operand:QI 2 "nonimmediate_operand" "rm,rm"))
4006            (match_operand:V4QI 1 "register_operand" "0,YW")
4007          (match_operand:SI 3 "const_int_operand")))]
4008  "TARGET_SSE4_1
4009   && ((unsigned) exact_log2 (INTVAL (operands[3]))
4010       < GET_MODE_NUNITS (V4QImode))"
4011{
4012  operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])));
4013  switch (which_alternative)
4014    {
4015    case 1:
4016      if (MEM_P (operands[2]))
4017          return "vpinsrb\t{%3, %2, %1, %0|%0, %1, %2, %3}";
4018      else
4019          return "vpinsrb\t{%3, %k2, %1, %0|%0, %1, %k2, %3}";
4020    case 0:
4021      if (MEM_P (operands[2]))
4022          return "pinsrb\t{%3, %2, %0|%0, %2, %3}";
4023      else
4024          return "pinsrb\t{%3, %k2, %0|%0, %k2, %3}";
4025    default:
4026      gcc_unreachable ();
4027    }
4028}
4029  [(set_attr "isa" "noavx,avx")
4030   (set_attr "type" "sselog")
4031   (set_attr "prefix_data16" "1")
4032   (set_attr "prefix_extra" "1")
4033   (set_attr "length_immediate" "1")
4034   (set_attr "prefix" "orig,vex")
4035   (set_attr "mode" "TI")])
4036
4037(define_insn "*pextrw"
4038  [(set (match_operand:HI 0 "register_sse4nonimm_operand" "=r,m")
4039          (vec_select:HI
4040            (match_operand:V2HI 1 "register_operand" "YW,YW")
4041            (parallel [(match_operand:SI 2 "const_0_to_1_operand" "n,n")])))]
4042  "TARGET_SSE2"
4043  "@
4044   %vpextrw\t{%2, %1, %k0|%k0, %1, %2}
4045   %vpextrw\t{%2, %1, %0|%0, %1, %2}"
4046  [(set_attr "isa" "*,sse4")
4047   (set_attr "type" "sselog1")
4048   (set_attr "length_immediate" "1")
4049   (set_attr "prefix" "maybe_vex")
4050   (set_attr "mode" "TI")])
4051
4052(define_insn "*pextrw_zext"
4053  [(set (match_operand:SWI48 0 "register_operand" "=r")
4054          (zero_extend:SWI48
4055            (vec_select:HI
4056              (match_operand:V2HI 1 "register_operand" "YW")
4057              (parallel [(match_operand:SI 2 "const_0_to_1_operand" "n")]))))]
4058  "TARGET_SSE2"
4059  "%vpextrw\t{%2, %1, %k0|%k0, %1, %2}"
4060  [(set_attr "type" "sselog1")
4061   (set_attr "length_immediate" "1")
4062   (set_attr "prefix" "maybe_vex")
4063   (set_attr "mode" "TI")])
4064
4065(define_insn "*pextrb"
4066  [(set (match_operand:QI 0 "nonimmediate_operand" "=r,m")
4067          (vec_select:QI
4068            (match_operand:V4QI 1 "register_operand" "YW,YW")
4069            (parallel [(match_operand:SI 2 "const_0_to_3_operand" "n,n")])))]
4070  "TARGET_SSE4_1"
4071  "@
4072   %vpextrb\t{%2, %1, %k0|%k0, %1, %2}
4073   %vpextrb\t{%2, %1, %0|%0, %1, %2}"
4074  [(set_attr "type" "sselog1")
4075   (set_attr "prefix_data16" "1")
4076   (set_attr "prefix_extra" "1")
4077   (set_attr "length_immediate" "1")
4078   (set_attr "prefix" "maybe_vex")
4079   (set_attr "mode" "TI")])
4080
4081(define_insn "*pextrb_zext"
4082  [(set (match_operand:SWI248 0 "register_operand" "=r")
4083          (zero_extend:SWI248
4084            (vec_select:QI
4085              (match_operand:V4QI 1 "register_operand" "YW")
4086              (parallel [(match_operand:SI 2 "const_0_to_3_operand" "n")]))))]
4087  "TARGET_SSE4_1"
4088  "%vpextrb\t{%2, %1, %k0|%k0, %1, %2}"
4089  [(set_attr "type" "sselog1")
4090   (set_attr "prefix_data16" "1")
4091   (set_attr "prefix_extra" "1")
4092   (set_attr "length_immediate" "1")
4093   (set_attr "prefix" "maybe_vex")
4094   (set_attr "mode" "TI")])
4095
4096(define_expand "vec_setv2hi"
4097  [(match_operand:V2HI 0 "register_operand")
4098   (match_operand:HI 1 "register_operand")
4099   (match_operand 2 "vec_setm_sse41_operand")]
4100  "TARGET_SSE2"
4101{
4102  if (CONST_INT_P (operands[2]))
4103    ix86_expand_vector_set (false, operands[0], operands[1],
4104                                  INTVAL (operands[2]));
4105  else
4106    ix86_expand_vector_set_var (operands[0], operands[1], operands[2]);
4107  DONE;
4108})
4109
4110(define_expand "vec_extractv2hihi"
4111  [(match_operand:HI 0 "register_operand")
4112   (match_operand:V2HI 1 "register_operand")
4113   (match_operand 2 "const_int_operand")]
4114  "TARGET_SSE2"
4115{
4116  ix86_expand_vector_extract (false, operands[0],
4117                                    operands[1], INTVAL (operands[2]));
4118  DONE;
4119})
4120
4121(define_expand "vec_setv4qi"
4122  [(match_operand:V4QI 0 "register_operand")
4123   (match_operand:QI 1 "register_operand")
4124   (match_operand 2 "vec_setm_mmx_operand")]
4125  "TARGET_SSE4_1"
4126{
4127  if (CONST_INT_P (operands[2]))
4128    ix86_expand_vector_set (false, operands[0], operands[1],
4129                                  INTVAL (operands[2]));
4130  else
4131    ix86_expand_vector_set_var (operands[0], operands[1], operands[2]);
4132  DONE;
4133})
4134
4135(define_expand "vec_extractv4qiqi"
4136  [(match_operand:QI 0 "register_operand")
4137   (match_operand:V4QI 1 "register_operand")
4138   (match_operand 2 "const_int_operand")]
4139  "TARGET_SSE4_1"
4140{
4141  ix86_expand_vector_extract (false, operands[0],
4142                                    operands[1], INTVAL (operands[2]));
4143  DONE;
4144})
4145
4146(define_insn_and_split "*punpckwd"
4147  [(set (match_operand:V2HI 0 "register_operand" "=x,Yw")
4148          (vec_select:V2HI
4149            (vec_concat:V4HI
4150              (match_operand:V2HI 1 "register_operand" "0,Yw")
4151              (match_operand:V2HI 2 "register_operand" "x,Yw"))
4152            (parallel [(match_operand 3 "const_0_to_3_operand")
4153                         (match_operand 4 "const_0_to_3_operand")])))]
4154  "TARGET_SSE2"
4155  "#"
4156  "&& reload_completed"
4157  [(set (match_dup 5)
4158          (vec_select:V8HI
4159            (match_dup 5)
4160          (parallel [(match_dup 3) (match_dup 4)
4161                     (const_int 2) (const_int 3)
4162                     (const_int 4) (const_int 5)
4163                     (const_int 6) (const_int 7)])))]
4164{
4165  rtx dest = lowpart_subreg (V8HImode, operands[0], V2HImode);
4166  rtx op1 = lowpart_subreg (V8HImode, operands[1], V2HImode);
4167  rtx op2 = lowpart_subreg (V8HImode, operands[2], V2HImode);
4168
4169  emit_insn (gen_vec_interleave_lowv8hi (dest, op1, op2));
4170
4171  static const int map[4] = { 0, 2, 1, 3 };
4172
4173  int sel0 = map[INTVAL (operands[3])];
4174  int sel1 = map[INTVAL (operands[4])];
4175
4176  if (sel0 == 0 && sel1 == 1)
4177    DONE;
4178
4179  operands[3] = GEN_INT (sel0);
4180  operands[4] = GEN_INT (sel1);
4181  operands[5] = dest;
4182}
4183  [(set_attr "isa" "noavx,avx")
4184   (set_attr "type" "sselog")
4185   (set_attr "mode" "TI")])
4186
4187(define_insn "*pshufw_1"
4188  [(set (match_operand:V2HI 0 "register_operand" "=Yw")
4189        (vec_select:V2HI
4190          (match_operand:V2HI 1 "register_operand" "Yw")
4191          (parallel [(match_operand 2 "const_0_to_1_operand")
4192                     (match_operand 3 "const_0_to_1_operand")])))]
4193  "TARGET_SSE2"
4194{
4195  int mask = 0;
4196  mask |= INTVAL (operands[2]) << 0;
4197  mask |= INTVAL (operands[3]) << 2;
4198  mask |= 2 << 4;
4199  mask |= 3 << 6;
4200  operands[2] = GEN_INT (mask);
4201
4202  return "%vpshuflw\t{%2, %1, %0|%0, %1, %2}";
4203}
4204  [(set_attr "type" "sselog1")
4205   (set_attr "length_immediate" "1")
4206   (set_attr "mode" "TI")])
4207
4208(define_insn "*vec_dupv2hi"
4209  [(set (match_operand:V2HI 0 "register_operand" "=Yw")
4210          (vec_duplicate:V2HI
4211            (truncate:HI
4212              (match_operand:SI 1 "register_operand" "Yw"))))]
4213  "TARGET_SSE2"
4214  "%vpshuflw\t{$0, %1, %0|%0, %1, 0}"
4215  [(set_attr "type" "sselog1")
4216   (set_attr "length_immediate" "1")
4217   (set_attr "mode" "TI")])
4218
4219(define_expand "vec_initv2hihi"
4220  [(match_operand:V2HI 0 "register_operand")
4221   (match_operand 1)]
4222  "TARGET_SSE2"
4223{
4224  ix86_expand_vector_init (TARGET_MMX_WITH_SSE, operands[0],
4225                                 operands[1]);
4226  DONE;
4227})
4228
4229(define_expand "vec_initv4qiqi"
4230  [(match_operand:V2HI 0 "register_operand")
4231   (match_operand 1)]
4232  "TARGET_SSE2"
4233{
4234  ix86_expand_vector_init (TARGET_MMX_WITH_SSE, operands[0],
4235                                 operands[1]);
4236  DONE;
4237})
4238
4239;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4240;;
4241;; Miscellaneous
4242;;
4243;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4244
4245(define_expand "mmx_uavg<mode>3"
4246  [(set (match_operand:MMXMODE12 0 "register_operand")
4247          (truncate:MMXMODE12
4248            (lshiftrt:<mmxdoublemode>
4249              (plus:<mmxdoublemode>
4250                (plus:<mmxdoublemode>
4251                    (zero_extend:<mmxdoublemode>
4252                      (match_operand:MMXMODE12 1 "register_mmxmem_operand"))
4253                    (zero_extend:<mmxdoublemode>
4254                      (match_operand:MMXMODE12 2 "register_mmxmem_operand")))
4255                (match_dup 3))
4256              (const_int 1))))]
4257  "(TARGET_MMX || TARGET_MMX_WITH_SSE)
4258   && (TARGET_SSE || TARGET_3DNOW)"
4259{
4260  operands[3] = CONST1_RTX(<mmxdoublemode>mode);
4261  ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
4262})
4263
4264(define_insn "*mmx_uavgv8qi3"
4265  [(set (match_operand:V8QI 0 "register_operand" "=y,x,Yw")
4266          (truncate:V8QI
4267            (lshiftrt:V8HI
4268              (plus:V8HI
4269                (plus:V8HI
4270                    (zero_extend:V8HI
4271                      (match_operand:V8QI 1 "register_mmxmem_operand" "%0,0,Yw"))
4272                    (zero_extend:V8HI
4273                      (match_operand:V8QI 2 "register_mmxmem_operand" "ym,x,Yw")))
4274                (const_vector:V8HI [(const_int 1) (const_int 1)
4275                                          (const_int 1) (const_int 1)
4276                                          (const_int 1) (const_int 1)
4277                                          (const_int 1) (const_int 1)]))
4278              (const_int 1))))]
4279  "(TARGET_MMX || TARGET_MMX_WITH_SSE)
4280   && (TARGET_SSE || TARGET_3DNOW)
4281   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
4282{
4283  switch (which_alternative)
4284    {
4285    case 2:
4286      return "vpavgb\t{%2, %1, %0|%0, %1, %2}";
4287    case 1:
4288    case 0:
4289      /* These two instructions have the same operation, but their encoding
4290           is different.  Prefer the one that is de facto standard.  */
4291      if (TARGET_SSE || TARGET_3DNOW_A)
4292          return "pavgb\t{%2, %0|%0, %2}";
4293      else
4294          return "pavgusb\t{%2, %0|%0, %2}";
4295      default:
4296          gcc_unreachable ();
4297    }
4298}
4299  [(set_attr "isa" "*,sse2_noavx,avx")
4300   (set_attr "mmx_isa" "native,*,*")
4301   (set_attr "type" "mmxshft,sseiadd,sseiadd")
4302   (set (attr "prefix_extra")
4303     (if_then_else
4304       (not (ior (match_test "TARGET_SSE")
4305                     (match_test "TARGET_3DNOW_A")))
4306       (const_string "1")
4307       (const_string "*")))
4308   (set_attr "mode" "DI,TI,TI")])
4309
4310(define_insn "*mmx_uavgv4hi3"
4311  [(set (match_operand:V4HI 0 "register_operand" "=y,x,Yw")
4312          (truncate:V4HI
4313            (lshiftrt:V4SI
4314              (plus:V4SI
4315                (plus:V4SI
4316                    (zero_extend:V4SI
4317                      (match_operand:V4HI 1 "register_mmxmem_operand" "%0,0,Yw"))
4318                    (zero_extend:V4SI
4319                      (match_operand:V4HI 2 "register_mmxmem_operand" "ym,x,Yw")))
4320                (const_vector:V4SI [(const_int 1) (const_int 1)
4321                                          (const_int 1) (const_int 1)]))
4322              (const_int 1))))]
4323  "(TARGET_MMX || TARGET_MMX_WITH_SSE)
4324   && (TARGET_SSE || TARGET_3DNOW_A)
4325   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
4326  "@
4327   pavgw\t{%2, %0|%0, %2}
4328   pavgw\t{%2, %0|%0, %2}
4329   vpavgw\t{%2, %1, %0|%0, %1, %2}"
4330  [(set_attr "isa" "*,sse2_noavx,avx")
4331   (set_attr "mmx_isa" "native,*,*")
4332   (set_attr "type" "mmxshft,sseiadd,sseiadd")
4333   (set_attr "mode" "DI,TI,TI")])
4334
4335(define_expand "uavg<mode>3_ceil"
4336  [(set (match_operand:MMXMODE12 0 "register_operand")
4337          (truncate:MMXMODE12
4338            (lshiftrt:<mmxdoublemode>
4339              (plus:<mmxdoublemode>
4340                (plus:<mmxdoublemode>
4341                    (zero_extend:<mmxdoublemode>
4342                      (match_operand:MMXMODE12 1 "register_operand"))
4343                    (zero_extend:<mmxdoublemode>
4344                      (match_operand:MMXMODE12 2 "register_operand")))
4345                (match_dup 3))
4346              (const_int 1))))]
4347  "TARGET_MMX_WITH_SSE"
4348  "operands[3] = CONST1_RTX(<mmxdoublemode>mode);")
4349
4350(define_insn "uavgv4qi3_ceil"
4351  [(set (match_operand:V4QI 0 "register_operand" "=x,Yw")
4352          (truncate:V4QI
4353            (lshiftrt:V4HI
4354              (plus:V4HI
4355                (plus:V4HI
4356                    (zero_extend:V4HI
4357                      (match_operand:V4QI 1 "register_operand" "%0,Yw"))
4358                    (zero_extend:V4HI
4359                      (match_operand:V4QI 2 "register_operand" "x,Yw")))
4360                (const_vector:V4HI [(const_int 1) (const_int 1)
4361                                          (const_int 1) (const_int 1)]))
4362              (const_int 1))))]
4363  "TARGET_SSE2"
4364  "@
4365   pavgb\t{%2, %0|%0, %2}
4366   vpavgb\t{%2, %1, %0|%0, %1, %2}"
4367  [(set_attr "isa" "noavx,avx")
4368   (set_attr "type" "sseiadd")
4369   (set_attr "mode" "TI")])
4370
4371(define_insn "uavgv2qi3_ceil"
4372  [(set (match_operand:V2QI 0 "register_operand" "=x,Yw")
4373          (truncate:V2QI
4374            (lshiftrt:V2HI
4375              (plus:V2HI
4376                (plus:V2HI
4377                    (zero_extend:V2HI
4378                      (match_operand:V2QI 1 "register_operand" "%0,Yw"))
4379                    (zero_extend:V2HI
4380                      (match_operand:V2QI 2 "register_operand" "x,Yw")))
4381                (const_vector:V2HI [(const_int 1) (const_int 1)]))
4382              (const_int 1))))]
4383  "TARGET_SSE2"
4384  "@
4385   pavgb\t{%2, %0|%0, %2}
4386   vpavgb\t{%2, %1, %0|%0, %1, %2}"
4387  [(set_attr "isa" "noavx,avx")
4388   (set_attr "type" "sseiadd")
4389   (set_attr "mode" "TI")])
4390
4391(define_insn "uavgv2hi3_ceil"
4392  [(set (match_operand:V2HI 0 "register_operand" "=x,Yw")
4393          (truncate:V2HI
4394            (lshiftrt:V2SI
4395              (plus:V2SI
4396                (plus:V2SI
4397                    (zero_extend:V2SI
4398                      (match_operand:V2HI 1 "register_operand" "%0,Yw"))
4399                    (zero_extend:V2SI
4400                      (match_operand:V2HI 2 "register_operand" "x,Yw")))
4401                (const_vector:V2SI [(const_int 1) (const_int 1)]))
4402              (const_int 1))))]
4403  "TARGET_SSE2"
4404  "@
4405   pavgw\t{%2, %0|%0, %2}
4406   vpavgw\t{%2, %1, %0|%0, %1, %2}"
4407  [(set_attr "isa" "noavx,avx")
4408   (set_attr "type" "sseiadd")
4409   (set_attr "mode" "TI")])
4410
4411(define_insn "mmx_psadbw"
4412  [(set (match_operand:V1DI 0 "register_operand" "=y,x,Yw")
4413        (unspec:V1DI [(match_operand:V8QI 1 "register_operand" "0,0,Yw")
4414                          (match_operand:V8QI 2 "register_mmxmem_operand" "ym,x,Yw")]
4415                         UNSPEC_PSADBW))]
4416  "(TARGET_MMX || TARGET_MMX_WITH_SSE)
4417   && (TARGET_SSE || TARGET_3DNOW_A)"
4418  "@
4419   psadbw\t{%2, %0|%0, %2}
4420   psadbw\t{%2, %0|%0, %2}
4421   vpsadbw\t{%2, %1, %0|%0, %1, %2}"
4422  [(set_attr "isa" "*,sse2_noavx,avx")
4423   (set_attr "mmx_isa" "native,*,*")
4424   (set_attr "type" "mmxshft,sseiadd,sseiadd")
4425   (set_attr "mode" "DI,TI,TI")])
4426
4427(define_expand "reduc_plus_scal_v8qi"
4428 [(plus:V8QI
4429    (match_operand:QI 0 "register_operand")
4430    (match_operand:V8QI 1 "register_operand"))]
4431 "TARGET_MMX_WITH_SSE"
4432{
4433  rtx tmp = gen_reg_rtx (V8QImode);
4434  emit_move_insn (tmp, CONST0_RTX (V8QImode));
4435  rtx tmp2 = gen_reg_rtx (V1DImode);
4436  emit_insn (gen_mmx_psadbw (tmp2, operands[1], tmp));
4437  tmp2 = gen_lowpart (V8QImode, tmp2);
4438  emit_insn (gen_vec_extractv8qiqi (operands[0], tmp2, const0_rtx));
4439  DONE;
4440})
4441
4442(define_expand "reduc_plus_scal_v4hi"
4443 [(plus:V4HI
4444    (match_operand:HI 0 "register_operand")
4445    (match_operand:V4HI 1 "register_operand"))]
4446 "TARGET_MMX_WITH_SSE"
4447{
4448  rtx tmp = gen_reg_rtx (V4HImode);
4449  ix86_expand_reduc (gen_addv4hi3, tmp, operands[1]);
4450  emit_insn (gen_vec_extractv4hihi (operands[0], tmp, const0_rtx));
4451  DONE;
4452})
4453
4454(define_expand "reduc_<code>_scal_v4hi"
4455  [(smaxmin:V4HI
4456     (match_operand:HI 0 "register_operand")
4457     (match_operand:V4HI 1 "register_operand"))]
4458  "TARGET_MMX_WITH_SSE"
4459{
4460  rtx tmp = gen_reg_rtx (V4HImode);
4461  ix86_expand_reduc (gen_<code>v4hi3, tmp, operands[1]);
4462  emit_insn (gen_vec_extractv4hihi (operands[0], tmp, const0_rtx));
4463  DONE;
4464})
4465
4466(define_expand "reduc_<code>_scal_v4qi"
4467  [(smaxmin:V4QI
4468     (match_operand:QI 0 "register_operand")
4469     (match_operand:V4QI 1 "register_operand"))]
4470  "TARGET_SSE4_1"
4471{
4472  rtx tmp = gen_reg_rtx (V4QImode);
4473  ix86_expand_reduc (gen_<code>v4qi3, tmp, operands[1]);
4474  emit_insn (gen_vec_extractv4qiqi (operands[0], tmp, const0_rtx));
4475  DONE;
4476})
4477
4478(define_expand "reduc_<code>_scal_v4hi"
4479  [(umaxmin:V4HI
4480     (match_operand:HI 0 "register_operand")
4481     (match_operand:V4HI 1 "register_operand"))]
4482  "TARGET_MMX_WITH_SSE && TARGET_SSE4_1"
4483{
4484  rtx tmp = gen_reg_rtx (V4HImode);
4485  ix86_expand_reduc (gen_<code>v4hi3, tmp, operands[1]);
4486  emit_insn (gen_vec_extractv4hihi (operands[0], tmp, const0_rtx));
4487  DONE;
4488})
4489
4490(define_expand "reduc_<code>_scal_v4qi"
4491  [(umaxmin:V4QI
4492     (match_operand:QI 0 "register_operand")
4493     (match_operand:V4QI 1 "register_operand"))]
4494  "TARGET_SSE4_1"
4495{
4496  rtx tmp = gen_reg_rtx (V4QImode);
4497  ix86_expand_reduc (gen_<code>v4qi3, tmp, operands[1]);
4498  emit_insn (gen_vec_extractv4qiqi (operands[0], tmp, const0_rtx));
4499  DONE;
4500})
4501
4502(define_expand "reduc_plus_scal_v4qi"
4503 [(plus:V4QI
4504    (match_operand:QI 0 "register_operand")
4505    (match_operand:V4QI 1 "register_operand"))]
4506 "TARGET_SSE2"
4507{
4508  rtx op1 = gen_reg_rtx (V16QImode);
4509  emit_insn (gen_vec_setv4si_0 (lowpart_subreg (V4SImode, op1, V16QImode),
4510                                        CONST0_RTX (V4SImode),
4511                                        lowpart_subreg (SImode,
4512                                                            operands[1],
4513                                                            V4QImode)));
4514  rtx tmp = gen_reg_rtx (V16QImode);
4515  emit_move_insn (tmp, CONST0_RTX (V16QImode));
4516  rtx tmp2 = gen_reg_rtx (V2DImode);
4517  emit_insn (gen_sse2_psadbw (tmp2, op1, tmp));
4518  tmp2 = gen_lowpart (V16QImode, tmp2);
4519  emit_insn (gen_vec_extractv16qiqi (operands[0], tmp2, const0_rtx));
4520  DONE;
4521})
4522
4523(define_expand "usadv8qi"
4524  [(match_operand:V2SI 0 "register_operand")
4525   (match_operand:V8QI 1 "register_operand")
4526   (match_operand:V8QI 2 "register_operand")
4527   (match_operand:V2SI 3 "register_operand")]
4528  "TARGET_MMX_WITH_SSE"
4529{
4530  rtx t1 = gen_reg_rtx (V1DImode);
4531  rtx t2 = gen_reg_rtx (V2SImode);
4532  emit_insn (gen_mmx_psadbw (t1, operands[1], operands[2]));
4533  convert_move (t2, t1, 0);
4534  emit_insn (gen_addv2si3 (operands[0], t2, operands[3]));
4535  DONE;
4536})
4537
4538(define_insn_and_split "mmx_pmovmskb"
4539  [(set (match_operand:SI 0 "register_operand" "=r,r")
4540          (unspec:SI [(match_operand:V8QI 1 "register_operand" "y,x")]
4541                       UNSPEC_MOVMSK))]
4542  "(TARGET_MMX || TARGET_MMX_WITH_SSE)
4543   && (TARGET_SSE || TARGET_3DNOW_A)"
4544  "@
4545   pmovmskb\t{%1, %0|%0, %1}
4546   #"
4547  "TARGET_SSE2 && reload_completed
4548   && SSE_REGNO_P (REGNO (operands[1]))"
4549  [(set (match_dup 0)
4550        (unspec:SI [(match_dup 1)] UNSPEC_MOVMSK))
4551   (set (match_dup 0)
4552          (zero_extend:SI (match_dup 2)))]
4553{
4554  /* Generate SSE pmovmskb and zero-extend from QImode to SImode.  */
4555  operands[1] = lowpart_subreg (V16QImode, operands[1],
4556                                        GET_MODE (operands[1]));
4557  operands[2] = lowpart_subreg (QImode, operands[0],
4558                                        GET_MODE (operands[0]));
4559}
4560  [(set_attr "mmx_isa" "native,sse")
4561   (set_attr "type" "mmxcvt,ssemov")
4562   (set_attr "mode" "DI,TI")])
4563
4564(define_expand "mmx_maskmovq"
4565  [(set (match_operand:V8QI 0 "memory_operand")
4566          (unspec:V8QI [(match_operand:V8QI 1 "register_operand")
4567                          (match_operand:V8QI 2 "register_operand")
4568                          (match_dup 0)]
4569                         UNSPEC_MASKMOV))]
4570  "TARGET_SSE || TARGET_3DNOW_A")
4571
4572(define_insn "*mmx_maskmovq"
4573  [(set (mem:V8QI (match_operand:P 0 "register_operand" "D"))
4574          (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
4575                          (match_operand:V8QI 2 "register_operand" "y")
4576                          (mem:V8QI (match_dup 0))]
4577                         UNSPEC_MASKMOV))]
4578  "TARGET_SSE || TARGET_3DNOW_A"
4579  ;; @@@ check ordering of operands in intel/nonintel syntax
4580  "maskmovq\t{%2, %1|%1, %2}"
4581  [(set_attr "type" "mmxcvt")
4582   (set_attr "znver1_decode" "vector")
4583   (set_attr "mode" "DI")])
4584
4585(define_int_iterator EMMS
4586  [(UNSPECV_EMMS "TARGET_MMX")
4587   (UNSPECV_FEMMS "TARGET_3DNOW")])
4588
4589(define_int_attr emms
4590  [(UNSPECV_EMMS "emms")
4591   (UNSPECV_FEMMS "femms")])
4592
4593(define_expand "mmx_<emms>"
4594  [(parallel
4595    [(unspec_volatile [(const_int 0)] EMMS)
4596      (clobber (reg:XF ST0_REG))
4597      (clobber (reg:XF ST1_REG))
4598      (clobber (reg:XF ST2_REG))
4599      (clobber (reg:XF ST3_REG))
4600      (clobber (reg:XF ST4_REG))
4601      (clobber (reg:XF ST5_REG))
4602      (clobber (reg:XF ST6_REG))
4603      (clobber (reg:XF ST7_REG))
4604      (clobber (reg:DI MM0_REG))
4605      (clobber (reg:DI MM1_REG))
4606      (clobber (reg:DI MM2_REG))
4607      (clobber (reg:DI MM3_REG))
4608      (clobber (reg:DI MM4_REG))
4609      (clobber (reg:DI MM5_REG))
4610      (clobber (reg:DI MM6_REG))
4611      (clobber (reg:DI MM7_REG))])]
4612  "TARGET_MMX || TARGET_MMX_WITH_SSE"
4613{
4614   if (!TARGET_MMX)
4615     {
4616       emit_insn (gen_nop ());
4617       DONE;
4618     }
4619})
4620
4621(define_insn "*mmx_<emms>"
4622  [(unspec_volatile [(const_int 0)] EMMS)
4623   (clobber (reg:XF ST0_REG))
4624   (clobber (reg:XF ST1_REG))
4625   (clobber (reg:XF ST2_REG))
4626   (clobber (reg:XF ST3_REG))
4627   (clobber (reg:XF ST4_REG))
4628   (clobber (reg:XF ST5_REG))
4629   (clobber (reg:XF ST6_REG))
4630   (clobber (reg:XF ST7_REG))
4631   (clobber (reg:DI MM0_REG))
4632   (clobber (reg:DI MM1_REG))
4633   (clobber (reg:DI MM2_REG))
4634   (clobber (reg:DI MM3_REG))
4635   (clobber (reg:DI MM4_REG))
4636   (clobber (reg:DI MM5_REG))
4637   (clobber (reg:DI MM6_REG))
4638   (clobber (reg:DI MM7_REG))]
4639  ""
4640  "<emms>"
4641  [(set_attr "type" "mmx")
4642   (set_attr "modrm" "0")
4643   (set_attr "memory" "none")])
4644