]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/i386/mmx.md
i386: Implement V2SF shuffles
[thirdparty/gcc.git] / gcc / config / i386 / mmx.md
1 ;; GCC machine description for MMX and 3dNOW! instructions
2 ;; Copyright (C) 2005-2020 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])
52
53 ;; Mix-n-match
54 (define_mode_iterator MMXMODE12 [V8QI V4HI])
55 (define_mode_iterator MMXMODE24 [V4HI V2SI])
56 (define_mode_iterator MMXMODE248 [V4HI V2SI V1DI])
57
58 ;; Mapping from integer vector mode to mnemonic suffix
59 (define_mode_attr mmxvecsize [(V8QI "b") (V4HI "w") (V2SI "d") (V1DI "q")])
60
61 (define_mode_attr mmxdoublemode
62 [(V8QI "V8HI") (V4HI "V4SI")])
63
64 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
65 ;;
66 ;; Move patterns
67 ;;
68 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
69
70 ;; All of these patterns are enabled for MMX as well as 3dNOW.
71 ;; This is essential for maintaining stable calling conventions.
72
73 (define_expand "mov<mode>"
74 [(set (match_operand:MMXMODE 0 "nonimmediate_operand")
75 (match_operand:MMXMODE 1 "nonimmediate_operand"))]
76 "TARGET_MMX || TARGET_MMX_WITH_SSE"
77 {
78 ix86_expand_vector_move (<MODE>mode, operands);
79 DONE;
80 })
81
82 (define_insn "*mov<mode>_internal"
83 [(set (match_operand:MMXMODE 0 "nonimmediate_operand"
84 "=r ,o ,r,r ,m ,?!y,!y,?!y,m ,r ,?!y,v,v,v,m,r,v,!y,*x")
85 (match_operand:MMXMODE 1 "nonimm_or_0_operand"
86 "rCo,rC,C,rm,rC,C ,!y,m ,?!y,?!y,r ,C,v,m,v,v,r,*x,!y"))]
87 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
88 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
89 {
90 switch (get_attr_type (insn))
91 {
92 case TYPE_MULTI:
93 return "#";
94
95 case TYPE_IMOV:
96 if (get_attr_mode (insn) == MODE_SI)
97 return "mov{l}\t{%1, %k0|%k0, %1}";
98 else
99 return "mov{q}\t{%1, %0|%0, %1}";
100
101 case TYPE_MMX:
102 return "pxor\t%0, %0";
103
104 case TYPE_MMXMOV:
105 /* Handle broken assemblers that require movd instead of movq. */
106 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
107 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
108 return "movd\t{%1, %0|%0, %1}";
109 return "movq\t{%1, %0|%0, %1}";
110
111 case TYPE_SSECVT:
112 if (SSE_REG_P (operands[0]))
113 return "movq2dq\t{%1, %0|%0, %1}";
114 else
115 return "movdq2q\t{%1, %0|%0, %1}";
116
117 case TYPE_SSELOG1:
118 return standard_sse_constant_opcode (insn, operands);
119
120 case TYPE_SSEMOV:
121 return ix86_output_ssemov (insn, operands);
122
123 default:
124 gcc_unreachable ();
125 }
126 }
127 [(set (attr "isa")
128 (cond [(eq_attr "alternative" "0,1")
129 (const_string "nox64")
130 (eq_attr "alternative" "2,3,4,9,10")
131 (const_string "x64")
132 (eq_attr "alternative" "15,16")
133 (const_string "x64_sse2")
134 (eq_attr "alternative" "17,18")
135 (const_string "sse2")
136 ]
137 (const_string "*")))
138 (set (attr "type")
139 (cond [(eq_attr "alternative" "0,1")
140 (const_string "multi")
141 (eq_attr "alternative" "2,3,4")
142 (const_string "imov")
143 (eq_attr "alternative" "5")
144 (const_string "mmx")
145 (eq_attr "alternative" "6,7,8,9,10")
146 (const_string "mmxmov")
147 (eq_attr "alternative" "11")
148 (const_string "sselog1")
149 (eq_attr "alternative" "17,18")
150 (const_string "ssecvt")
151 ]
152 (const_string "ssemov")))
153 (set (attr "prefix_rex")
154 (if_then_else (eq_attr "alternative" "9,10,15,16")
155 (const_string "1")
156 (const_string "*")))
157 (set (attr "prefix")
158 (if_then_else (eq_attr "type" "sselog1,ssemov")
159 (const_string "maybe_vex")
160 (const_string "orig")))
161 (set (attr "prefix_data16")
162 (if_then_else
163 (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
164 (const_string "1")
165 (const_string "*")))
166 (set (attr "mode")
167 (cond [(eq_attr "alternative" "2")
168 (const_string "SI")
169 (eq_attr "alternative" "11,12")
170 (cond [(match_test "<MODE>mode == V2SFmode")
171 (const_string "V4SF")
172 (ior (not (match_test "TARGET_SSE2"))
173 (match_test "optimize_function_for_size_p (cfun)"))
174 (const_string "V4SF")
175 ]
176 (const_string "TI"))
177
178 (and (eq_attr "alternative" "13")
179 (ior (and (match_test "<MODE>mode == V2SFmode")
180 (not (match_test "TARGET_MMX_WITH_SSE")))
181 (not (match_test "TARGET_SSE2"))))
182 (const_string "V2SF")
183
184 (and (eq_attr "alternative" "14")
185 (ior (match_test "<MODE>mode == V2SFmode")
186 (not (match_test "TARGET_SSE2"))))
187 (const_string "V2SF")
188 ]
189 (const_string "DI")))
190 (set (attr "preferred_for_speed")
191 (cond [(eq_attr "alternative" "9,15")
192 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
193 (eq_attr "alternative" "10,16")
194 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
195 ]
196 (symbol_ref "true")))])
197
198 (define_split
199 [(set (match_operand:MMXMODE 0 "nonimmediate_gr_operand")
200 (match_operand:MMXMODE 1 "nonimmediate_gr_operand"))]
201 "!TARGET_64BIT && reload_completed"
202 [(const_int 0)]
203 "ix86_split_long_move (operands); DONE;")
204
205 (define_split
206 [(set (match_operand:MMXMODE 0 "nonimmediate_gr_operand")
207 (match_operand:MMXMODE 1 "const0_operand"))]
208 "!TARGET_64BIT && reload_completed"
209 [(const_int 0)]
210 "ix86_split_long_move (operands); DONE;")
211
212 (define_expand "movmisalign<mode>"
213 [(set (match_operand:MMXMODE 0 "nonimmediate_operand")
214 (match_operand:MMXMODE 1 "nonimmediate_operand"))]
215 "TARGET_MMX || TARGET_MMX_WITH_SSE"
216 {
217 ix86_expand_vector_move (<MODE>mode, operands);
218 DONE;
219 })
220
221 (define_insn "sse_movntq"
222 [(set (match_operand:DI 0 "memory_operand" "=m,m")
223 (unspec:DI [(match_operand:DI 1 "register_operand" "y,r")]
224 UNSPEC_MOVNTQ))]
225 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
226 && (TARGET_SSE || TARGET_3DNOW_A)"
227 "@
228 movntq\t{%1, %0|%0, %1}
229 movnti\t{%1, %0|%0, %1}"
230 [(set_attr "isa" "*,x64")
231 (set_attr "mmx_isa" "native,*")
232 (set_attr "type" "mmxmov,ssemov")
233 (set_attr "mode" "DI")])
234
235 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
236 ;;
237 ;; Parallel single-precision floating point arithmetic
238 ;;
239 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
240
241 (define_expand "<code>v2sf2"
242 [(set (match_operand:V2SF 0 "register_operand")
243 (absneg:V2SF
244 (match_operand:V2SF 1 "register_operand")))]
245 "TARGET_MMX_WITH_SSE"
246 "ix86_expand_fp_absneg_operator (<CODE>, V2SFmode, operands); DONE;")
247
248 (define_insn_and_split "*mmx_<code>v2sf2"
249 [(set (match_operand:V2SF 0 "register_operand" "=x,x,x")
250 (absneg:V2SF
251 (match_operand:V2SF 1 "register_operand" "0,x,x")))
252 (use (match_operand:V2SF 2 "nonimmediate_operand" "x,0,x"))]
253 "TARGET_MMX_WITH_SSE"
254 "#"
255 "&& reload_completed"
256 [(set (match_dup 0)
257 (<absneg_op>:V2SF (match_dup 1) (match_dup 2)))]
258 {
259 if (!TARGET_AVX && operands_match_p (operands[0], operands[2]))
260 std::swap (operands[1], operands[2]);
261 }
262 [(set_attr "isa" "noavx,noavx,avx")])
263
264 (define_insn_and_split "*mmx_nabsv2sf2"
265 [(set (match_operand:V2SF 0 "register_operand" "=x,x,x")
266 (neg:V2SF
267 (abs:V2SF
268 (match_operand:V2SF 1 "register_operand" "0,x,x"))))
269 (use (match_operand:V2SF 2 "nonimmediate_operand" "x,0,x"))]
270 "TARGET_MMX_WITH_SSE"
271 "#"
272 "&& reload_completed"
273 [(set (match_dup 0)
274 (ior:V2SF (match_dup 1) (match_dup 2)))]
275 {
276 if (!TARGET_AVX && operands_match_p (operands[0], operands[2]))
277 std::swap (operands[1], operands[2]);
278 }
279 [(set_attr "isa" "noavx,noavx,avx")])
280
281 (define_expand "mmx_addv2sf3"
282 [(set (match_operand:V2SF 0 "register_operand")
283 (plus:V2SF
284 (match_operand:V2SF 1 "register_mmxmem_operand")
285 (match_operand:V2SF 2 "register_mmxmem_operand")))]
286 "TARGET_3DNOW"
287 "ix86_fixup_binary_operands_no_copy (PLUS, V2SFmode, operands);")
288
289 (define_expand "addv2sf3"
290 [(set (match_operand:V2SF 0 "register_operand")
291 (plus:V2SF
292 (match_operand:V2SF 1 "register_operand")
293 (match_operand:V2SF 2 "register_operand")))]
294 "TARGET_MMX_WITH_SSE"
295 "ix86_fixup_binary_operands_no_copy (PLUS, V2SFmode, operands);")
296
297 (define_insn "*mmx_addv2sf3"
298 [(set (match_operand:V2SF 0 "register_operand" "=y,x,v")
299 (plus:V2SF
300 (match_operand:V2SF 1 "register_mmxmem_operand" "%0,0,v")
301 (match_operand:V2SF 2 "register_mmxmem_operand" "ym,x,v")))]
302 "(TARGET_3DNOW || TARGET_MMX_WITH_SSE)
303 && ix86_binary_operator_ok (PLUS, V2SFmode, operands)"
304 "@
305 pfadd\t{%2, %0|%0, %2}
306 addps\t{%2, %0|%0, %2}
307 vaddps\t{%2, %1, %0|%0, %1, %2}"
308 [(set_attr "isa" "*,sse2_noavx,avx")
309 (set_attr "mmx_isa" "native,*,*")
310 (set_attr "type" "mmxadd,sseadd,sseadd")
311 (set_attr "prefix_extra" "1,*,*")
312 (set_attr "prefix" "*,orig,vex")
313 (set_attr "mode" "V2SF,V4SF,V4SF")])
314
315 (define_expand "mmx_subv2sf3"
316 [(set (match_operand:V2SF 0 "register_operand")
317 (minus:V2SF (match_operand:V2SF 1 "register_operand")
318 (match_operand:V2SF 2 "register_mmxmem_operand")))]
319 "TARGET_3DNOW")
320
321 (define_expand "mmx_subrv2sf3"
322 [(set (match_operand:V2SF 0 "register_operand")
323 (minus:V2SF (match_operand:V2SF 2 "register_operand")
324 (match_operand:V2SF 1 "register_mmxmem_operand")))]
325 "TARGET_3DNOW")
326
327 (define_expand "subv2sf3"
328 [(set (match_operand:V2SF 0 "register_operand")
329 (minus:V2SF
330 (match_operand:V2SF 1 "register_operand")
331 (match_operand:V2SF 2 "register_operand")))]
332 "TARGET_MMX_WITH_SSE"
333 "ix86_fixup_binary_operands_no_copy (MINUS, V2SFmode, operands);")
334
335 (define_insn "*mmx_subv2sf3"
336 [(set (match_operand:V2SF 0 "register_operand" "=y,y,x,v")
337 (minus:V2SF
338 (match_operand:V2SF 1 "register_mmxmem_operand" "0,ym,0,v")
339 (match_operand:V2SF 2 "register_mmxmem_operand" "ym,0,x,v")))]
340 "(TARGET_3DNOW || TARGET_MMX_WITH_SSE)
341 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
342 "@
343 pfsub\t{%2, %0|%0, %2}
344 pfsubr\t{%1, %0|%0, %1}
345 subps\t{%2, %0|%0, %2}
346 vsubps\t{%2, %1, %0|%0, %1, %2}"
347 [(set_attr "isa" "*,*,sse2_noavx,avx")
348 (set_attr "mmx_isa" "native,native,*,*")
349 (set_attr "type" "mmxadd,mmxadd,sseadd,sseadd")
350 (set_attr "prefix_extra" "1,1,*,*")
351 (set_attr "prefix" "*,*,orig,vex")
352 (set_attr "mode" "V2SF,V2SF,V4SF,V4SF")])
353
354 (define_expand "mmx_mulv2sf3"
355 [(set (match_operand:V2SF 0 "register_operand")
356 (mult:V2SF (match_operand:V2SF 1 "register_mmxmem_operand")
357 (match_operand:V2SF 2 "register_mmxmem_operand")))]
358 "TARGET_3DNOW"
359 "ix86_fixup_binary_operands_no_copy (MULT, V2SFmode, operands);")
360
361 (define_expand "mulv2sf3"
362 [(set (match_operand:V2SF 0 "register_operand")
363 (mult:V2SF
364 (match_operand:V2SF 1 "register_operand")
365 (match_operand:V2SF 2 "register_operand")))]
366 "TARGET_MMX_WITH_SSE"
367 "ix86_fixup_binary_operands_no_copy (MULT, V2SFmode, operands);")
368
369 (define_insn "*mmx_mulv2sf3"
370 [(set (match_operand:V2SF 0 "register_operand" "=y,x,v")
371 (mult:V2SF
372 (match_operand:V2SF 1 "register_mmxmem_operand" "%0,0,v")
373 (match_operand:V2SF 2 "register_mmxmem_operand" "ym,x,v")))]
374 "(TARGET_3DNOW || TARGET_MMX_WITH_SSE)
375 && ix86_binary_operator_ok (MULT, V2SFmode, operands)"
376 "@
377 pfmul\t{%2, %0|%0, %2}
378 mulps\t{%2, %0|%0, %2}
379 vmulps\t{%2, %1, %0|%0, %1, %2}"
380 [(set_attr "isa" "*,sse2_noavx,avx")
381 (set_attr "mmx_isa" "native,*,*")
382 (set_attr "type" "mmxmul,ssemul,ssemul")
383 (set_attr "btver2_decode" "*,direct,double")
384 (set_attr "prefix_extra" "1,*,*")
385 (set_attr "prefix" "*,orig,vex")
386 (set_attr "mode" "V2SF,V4SF,V4SF")])
387
388 (define_expand "mmx_<code>v2sf3"
389 [(set (match_operand:V2SF 0 "register_operand")
390 (smaxmin:V2SF
391 (match_operand:V2SF 1 "register_mmxmem_operand")
392 (match_operand:V2SF 2 "register_mmxmem_operand")))]
393 "TARGET_3DNOW"
394 {
395 if (!flag_finite_math_only || flag_signed_zeros)
396 {
397 operands[1] = force_reg (V2SFmode, operands[1]);
398 emit_insn (gen_mmx_ieee_<maxmin_float>v2sf3
399 (operands[0], operands[1], operands[2]));
400 DONE;
401 }
402 else
403 ix86_fixup_binary_operands_no_copy (<CODE>, V2SFmode, operands);
404 })
405
406 (define_expand "<code>v2sf3"
407 [(set (match_operand:V2SF 0 "register_operand")
408 (smaxmin:V2SF
409 (match_operand:V2SF 1 "register_operand")
410 (match_operand:V2SF 2 "register_operand")))]
411 "TARGET_MMX_WITH_SSE"
412 {
413 if (!flag_finite_math_only || flag_signed_zeros)
414 {
415 emit_insn (gen_mmx_ieee_<maxmin_float>v2sf3
416 (operands[0], operands[1], operands[2]));
417 DONE;
418 }
419 else
420 ix86_fixup_binary_operands_no_copy (<CODE>, V2SFmode, operands);
421 })
422
423 ;; These versions of the min/max patterns are intentionally ignorant of
424 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
425 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
426 ;; are undefined in this condition, we're certain this is correct.
427
428 (define_insn "*mmx_<code>v2sf3"
429 [(set (match_operand:V2SF 0 "register_operand" "=y,x,v")
430 (smaxmin:V2SF
431 (match_operand:V2SF 1 "register_mmxmem_operand" "%0,0,v")
432 (match_operand:V2SF 2 "register_mmxmem_operand" "ym,x,v")))]
433 "(TARGET_3DNOW || TARGET_MMX_WITH_SSE)
434 && ix86_binary_operator_ok (<CODE>, V2SFmode, operands)"
435 "@
436 pf<maxmin_float>\t{%2, %0|%0, %2}
437 <maxmin_float>ps\t{%2, %0|%0, %2}
438 v<maxmin_float>ps\t{%2, %1, %0|%0, %1, %2}"
439 [(set_attr "isa" "*,sse2_noavx,avx")
440 (set_attr "mmx_isa" "native,*,*")
441 (set_attr "type" "mmxadd,sseadd,sseadd")
442 (set_attr "btver2_sse_attr" "*,maxmin,maxmin")
443 (set_attr "prefix_extra" "1,*,*")
444 (set_attr "prefix" "*,orig,vex")
445 (set_attr "mode" "V2SF,V4SF,V4SF")])
446
447 ;; These versions of the min/max patterns implement exactly the operations
448 ;; min = (op1 < op2 ? op1 : op2)
449 ;; max = (!(op1 < op2) ? op1 : op2)
450 ;; Their operands are not commutative, and thus they may be used in the
451 ;; presence of -0.0 and NaN.
452
453 (define_insn "mmx_ieee_<ieee_maxmin>v2sf3"
454 [(set (match_operand:V2SF 0 "register_operand" "=y,x,v")
455 (unspec:V2SF
456 [(match_operand:V2SF 1 "register_operand" "0,0,v")
457 (match_operand:V2SF 2 "register_mmxmem_operand" "ym,x,v")]
458 IEEE_MAXMIN))]
459 "TARGET_3DNOW || TARGET_MMX_WITH_SSE"
460 "@
461 pf<ieee_maxmin>\t{%2, %0|%0, %2}
462 <ieee_maxmin>ps\t{%2, %0|%0, %2}
463 v<ieee_maxmin>ps\t{%2, %1, %0|%0, %1, %2}"
464 [(set_attr "isa" "*,sse2_noavx,avx")
465 (set_attr "mmx_isa" "native,*,*")
466 (set_attr "type" "mmxadd,sseadd,sseadd")
467 (set_attr "btver2_sse_attr" "*,maxmin,maxmin")
468 (set_attr "prefix_extra" "1,*,*")
469 (set_attr "prefix" "*,orig,vex")
470 (set_attr "mode" "V2SF,V4SF,V4SF")])
471
472 (define_insn "mmx_rcpv2sf2"
473 [(set (match_operand:V2SF 0 "register_operand" "=y")
474 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
475 UNSPEC_PFRCP))]
476 "TARGET_3DNOW"
477 "pfrcp\t{%1, %0|%0, %1}"
478 [(set_attr "type" "mmx")
479 (set_attr "prefix_extra" "1")
480 (set_attr "mode" "V2SF")])
481
482 (define_insn "mmx_rcpit1v2sf3"
483 [(set (match_operand:V2SF 0 "register_operand" "=y")
484 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
485 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
486 UNSPEC_PFRCPIT1))]
487 "TARGET_3DNOW"
488 "pfrcpit1\t{%2, %0|%0, %2}"
489 [(set_attr "type" "mmx")
490 (set_attr "prefix_extra" "1")
491 (set_attr "mode" "V2SF")])
492
493 (define_insn "mmx_rcpit2v2sf3"
494 [(set (match_operand:V2SF 0 "register_operand" "=y")
495 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
496 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
497 UNSPEC_PFRCPIT2))]
498 "TARGET_3DNOW"
499 "pfrcpit2\t{%2, %0|%0, %2}"
500 [(set_attr "type" "mmx")
501 (set_attr "prefix_extra" "1")
502 (set_attr "mode" "V2SF")])
503
504 (define_insn "sqrtv2sf2"
505 [(set (match_operand:V2SF 0 "register_operand" "=x,v")
506 (sqrt:V2SF (match_operand:V2SF 1 "register_operand" "0,v")))]
507 "TARGET_MMX_WITH_SSE"
508 "@
509 sqrtps\t{%1, %0|%0, %1}
510 vsqrtps\t{%1, %0|%0, %1}"
511 [(set_attr "isa" "noavx,avx")
512 (set_attr "type" "sse")
513 (set_attr "atom_sse_attr" "sqrt")
514 (set_attr "btver2_sse_attr" "sqrt")
515 (set_attr "prefix" "orig,vex")
516 (set_attr "mode" "V4SF")])
517
518 (define_insn "mmx_rsqrtv2sf2"
519 [(set (match_operand:V2SF 0 "register_operand" "=y")
520 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
521 UNSPEC_PFRSQRT))]
522 "TARGET_3DNOW"
523 "pfrsqrt\t{%1, %0|%0, %1}"
524 [(set_attr "type" "mmx")
525 (set_attr "prefix_extra" "1")
526 (set_attr "mode" "V2SF")])
527
528 (define_insn "mmx_rsqit1v2sf3"
529 [(set (match_operand:V2SF 0 "register_operand" "=y")
530 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
531 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
532 UNSPEC_PFRSQIT1))]
533 "TARGET_3DNOW"
534 "pfrsqit1\t{%2, %0|%0, %2}"
535 [(set_attr "type" "mmx")
536 (set_attr "prefix_extra" "1")
537 (set_attr "mode" "V2SF")])
538
539 (define_expand "mmx_haddv2sf3"
540 [(set (match_operand:V2SF 0 "register_operand")
541 (vec_concat:V2SF
542 (plus:SF
543 (vec_select:SF
544 (match_operand:V2SF 1 "register_operand")
545 (parallel [(const_int 0)]))
546 (vec_select:SF (match_dup 1) (parallel [(const_int 1)])))
547 (plus:SF
548 (vec_select:SF
549 (match_operand:V2SF 2 "nonimmediate_operand")
550 (parallel [(const_int 0)]))
551 (vec_select:SF (match_dup 2) (parallel [(const_int 1)])))))]
552 "TARGET_3DNOW")
553
554 (define_insn "*mmx_haddv2sf3"
555 [(set (match_operand:V2SF 0 "register_operand" "=y,x,x")
556 (vec_concat:V2SF
557 (plus:SF
558 (vec_select:SF
559 (match_operand:V2SF 1 "register_operand" "0,0,x")
560 (parallel [(match_operand:SI 3 "const_0_to_1_operand")]))
561 (vec_select:SF (match_dup 1)
562 (parallel [(match_operand:SI 4 "const_0_to_1_operand")])))
563 (plus:SF
564 (vec_select:SF
565 (match_operand:V2SF 2 "nonimmediate_operand" "ym,x,x")
566 (parallel [(match_operand:SI 5 "const_0_to_1_operand")]))
567 (vec_select:SF (match_dup 2)
568 (parallel [(match_operand:SI 6 "const_0_to_1_operand")])))))]
569 "TARGET_3DNOW
570 && INTVAL (operands[3]) != INTVAL (operands[4])
571 && INTVAL (operands[5]) != INTVAL (operands[6])"
572 "@
573 pfacc\t{%2, %0|%0, %2}
574 haddps\t{%2, %0|%0, %2}
575 vhaddps\t{%2, %1, %0|%0, %1, %2}"
576 [(set_attr "isa" "*,sse3_noavx,avx")
577 (set_attr "type" "mmxadd,sseadd,sseadd")
578 (set_attr "prefix_extra" "1,*,*")
579 (set_attr "prefix" "*,orig,vex")
580 (set_attr "mode" "V2SF,V4SF,V4SF")])
581
582 (define_insn "*mmx_haddv2sf3_low"
583 [(set (match_operand:SF 0 "register_operand" "=x,x")
584 (plus:SF
585 (vec_select:SF
586 (match_operand:V2SF 1 "register_operand" "0,x")
587 (parallel [(match_operand:SI 2 "const_0_to_1_operand")]))
588 (vec_select:SF
589 (match_dup 1)
590 (parallel [(match_operand:SI 3 "const_0_to_1_operand")]))))]
591 "TARGET_MMX_WITH_SSE && TARGET_SSE3
592 && INTVAL (operands[2]) != INTVAL (operands[3])"
593 "@
594 haddps\t{%0, %0|%0, %0}
595 vhaddps\t{%1, %1, %0|%0, %1, %1}"
596 [(set_attr "isa" "noavx,avx")
597 (set_attr "type" "sseadd1")
598 (set_attr "prefix" "orig,vex")
599 (set_attr "mode" "V4SF")])
600
601 (define_insn "mmx_hsubv2sf3"
602 [(set (match_operand:V2SF 0 "register_operand" "=y,x,x")
603 (vec_concat:V2SF
604 (minus:SF
605 (vec_select:SF
606 (match_operand:V2SF 1 "register_operand" "0,0,x")
607 (parallel [(const_int 0)]))
608 (vec_select:SF (match_dup 1) (parallel [(const_int 1)])))
609 (minus:SF
610 (vec_select:SF
611 (match_operand:V2SF 2 "register_mmxmem_operand" "ym,x,x")
612 (parallel [(const_int 0)]))
613 (vec_select:SF (match_dup 2) (parallel [(const_int 1)])))))]
614 "TARGET_3DNOW_A"
615 "@
616 pfnacc\t{%2, %0|%0, %2}
617 hsubps\t{%2, %0|%0, %2}
618 vhsubps\t{%2, %1, %0|%0, %1, %2}"
619 [(set_attr "isa" "*,sse3_noavx,avx")
620 (set_attr "type" "mmxadd,sseadd,sseadd")
621 (set_attr "prefix_extra" "1,*,*")
622 (set_attr "prefix" "*,orig,vex")
623 (set_attr "mode" "V2SF,V4SF,V4SF")])
624
625 (define_insn "*mmx_hsubv2sf3_low"
626 [(set (match_operand:SF 0 "register_operand" "=x,x")
627 (minus:SF
628 (vec_select:SF
629 (match_operand:V2SF 1 "register_operand" "0,x")
630 (parallel [(const_int 0)]))
631 (vec_select:SF
632 (match_dup 1)
633 (parallel [(const_int 1)]))))]
634 "TARGET_MMX_WITH_SSE && TARGET_SSE3"
635 "@
636 hsubps\t{%0, %0|%0, %0}
637 vhsubps\t{%1, %1, %0|%0, %1, %1}"
638 [(set_attr "isa" "noavx,avx")
639 (set_attr "type" "sseadd1")
640 (set_attr "prefix" "orig,vex")
641 (set_attr "mode" "V4SF")])
642
643 (define_insn "mmx_addsubv2sf3"
644 [(set (match_operand:V2SF 0 "register_operand" "=y")
645 (vec_merge:V2SF
646 (plus:V2SF
647 (match_operand:V2SF 1 "register_operand" "0")
648 (match_operand:V2SF 2 "nonimmediate_operand" "ym"))
649 (minus:V2SF (match_dup 1) (match_dup 2))
650 (const_int 1)))]
651 "TARGET_3DNOW_A"
652 "pfpnacc\t{%2, %0|%0, %2}"
653 [(set_attr "type" "mmxadd")
654 (set_attr "prefix_extra" "1")
655 (set_attr "mode" "V2SF")])
656
657 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
658 ;;
659 ;; Parallel single-precision floating point comparisons
660 ;;
661 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
662
663 (define_expand "mmx_eqv2sf3"
664 [(set (match_operand:V2SI 0 "register_operand")
665 (eq:V2SI (match_operand:V2SF 1 "nonimmediate_operand")
666 (match_operand:V2SF 2 "nonimmediate_operand")))]
667 "TARGET_3DNOW"
668 "ix86_fixup_binary_operands_no_copy (EQ, V2SFmode, operands);")
669
670 (define_insn "*mmx_eqv2sf3"
671 [(set (match_operand:V2SI 0 "register_operand" "=y")
672 (eq:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "%0")
673 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
674 "TARGET_3DNOW && ix86_binary_operator_ok (EQ, V2SFmode, operands)"
675 "pfcmpeq\t{%2, %0|%0, %2}"
676 [(set_attr "type" "mmxcmp")
677 (set_attr "prefix_extra" "1")
678 (set_attr "mode" "V2SF")])
679
680 (define_insn "mmx_gtv2sf3"
681 [(set (match_operand:V2SI 0 "register_operand" "=y")
682 (gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
683 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
684 "TARGET_3DNOW"
685 "pfcmpgt\t{%2, %0|%0, %2}"
686 [(set_attr "type" "mmxcmp")
687 (set_attr "prefix_extra" "1")
688 (set_attr "mode" "V2SF")])
689
690 (define_insn "mmx_gev2sf3"
691 [(set (match_operand:V2SI 0 "register_operand" "=y")
692 (ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
693 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
694 "TARGET_3DNOW"
695 "pfcmpge\t{%2, %0|%0, %2}"
696 [(set_attr "type" "mmxcmp")
697 (set_attr "prefix_extra" "1")
698 (set_attr "mode" "V2SF")])
699
700 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
701 ;;
702 ;; Parallel single-precision floating point logical operations
703 ;;
704 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
705
706 (define_insn "*mmx_andnotv2sf3"
707 [(set (match_operand:V2SF 0 "register_operand" "=x,x")
708 (and:V2SF
709 (not:V2SF
710 (match_operand:V2SF 1 "register_operand" "0,x"))
711 (match_operand:V2SF 2 "register_operand" "x,x")))]
712 "TARGET_MMX_WITH_SSE"
713 "@
714 andnps\t{%2, %0|%0, %2}
715 vandnps\t{%2, %1, %0|%0, %1, %2}"
716 [(set_attr "isa" "noavx,avx")
717 (set_attr "type" "sselog")
718 (set_attr "prefix" "orig,vex")
719 (set_attr "mode" "V4SF")])
720
721 (define_insn "*mmx_<code>v2sf3"
722 [(set (match_operand:V2SF 0 "register_operand" "=x,x")
723 (any_logic:V2SF
724 (match_operand:V2SF 1 "register_operand" "%0,x")
725 (match_operand:V2SF 2 "register_operand" "x,x")))]
726 "TARGET_MMX_WITH_SSE"
727 "@
728 <logic>ps\t{%2, %0|%0, %2}
729 v<logic>ps\t{%2, %1, %0|%0, %1, %2}"
730 [(set_attr "isa" "noavx,avx")
731 (set_attr "type" "sselog")
732 (set_attr "prefix" "orig,vex")
733 (set_attr "mode" "V4SF")])
734
735 (define_expand "copysignv2sf3"
736 [(set (match_dup 4)
737 (and:V2SF
738 (not:V2SF (match_dup 3))
739 (match_operand:V2SF 1 "register_operand")))
740 (set (match_dup 5)
741 (and:V2SF (match_dup 3)
742 (match_operand:V2SF 2 "register_operand")))
743 (set (match_operand:V2SF 0 "register_operand")
744 (ior:V2SF (match_dup 4) (match_dup 5)))]
745 "TARGET_MMX_WITH_SSE"
746 {
747 operands[3] = ix86_build_signbit_mask (V2SFmode, true, false);
748
749 operands[4] = gen_reg_rtx (V2SFmode);
750 operands[5] = gen_reg_rtx (V2SFmode);
751 })
752
753 (define_expand "xorsignv2sf3"
754 [(set (match_dup 4)
755 (and:V2SF (match_dup 3)
756 (match_operand:V2SF 2 "register_operand")))
757 (set (match_operand:V2SF 0 "register_operand")
758 (xor:V2SF (match_dup 4)
759 (match_operand:V2SF 1 "register_operand")))]
760 "TARGET_MMX_WITH_SSE"
761 {
762 operands[3] = ix86_build_signbit_mask (V2SFmode, true, false);
763
764 operands[4] = gen_reg_rtx (V2SFmode);
765 })
766
767 (define_expand "signbitv2sf2"
768 [(set (match_operand:V2SI 0 "register_operand")
769 (lshiftrt:V2SI
770 (subreg:V2SI
771 (match_operand:V2SF 1 "register_operand") 0)
772 (match_dup 2)))]
773 "TARGET_MMX_WITH_SSE"
774 "operands[2] = GEN_INT (GET_MODE_UNIT_BITSIZE (V2SFmode)-1);")
775
776 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
777 ;;
778 ;; Parallel single-precision FMA multiply/accumulate instructions.
779 ;;
780 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
781
782 (define_insn "fmav2sf4"
783 [(set (match_operand:V2SF 0 "register_operand" "=v,v,x")
784 (fma:V2SF
785 (match_operand:V2SF 1 "register_operand" "%0,v,x")
786 (match_operand:V2SF 2 "register_operand" "v,v,x")
787 (match_operand:V2SF 3 "register_operand" "v,0,x")))]
788 "(TARGET_FMA || TARGET_FMA4) && TARGET_MMX_WITH_SSE"
789 "@
790 vfmadd132ps\t{%2, %3, %0|%0, %3, %2}
791 vfmadd231ps\t{%2, %1, %0|%0, %1, %2}
792 vfmaddps\t{%3, %2, %1, %0|%0, %1, %2, %3}"
793 [(set_attr "isa" "fma,fma,fma4")
794 (set_attr "type" "ssemuladd")
795 (set_attr "mode" "V4SF")])
796
797 (define_insn "fmsv2sf4"
798 [(set (match_operand:V2SF 0 "register_operand" "=v,v,x")
799 (fma:V2SF
800 (match_operand:V2SF 1 "register_operand" "%0,v,x")
801 (match_operand:V2SF 2 "register_operand" "v,v,x")
802 (neg:V2SF
803 (match_operand:V2SF 3 "register_operand" "v,0,x"))))]
804 "(TARGET_FMA || TARGET_FMA4) && TARGET_MMX_WITH_SSE"
805 "@
806 vfmsub132ps\t{%2, %3, %0|%0, %3, %2}
807 vfmsub231ps\t{%2, %1, %0|%0, %1, %2}
808 vfmsubps\t{%3, %2, %1, %0|%0, %1, %2, %3}"
809 [(set_attr "isa" "fma,fma,fma4")
810 (set_attr "type" "ssemuladd")
811 (set_attr "mode" "V4SF")])
812
813 (define_insn "fnmav2sf4"
814 [(set (match_operand:V2SF 0 "register_operand" "=v,v,x")
815 (fma:V2SF
816 (neg:V2SF
817 (match_operand:V2SF 1 "register_operand" "%0,v,x"))
818 (match_operand:V2SF 2 "register_operand" "v,v,x")
819 (match_operand:V2SF 3 "register_operand" "v,0,x")))]
820 "(TARGET_FMA || TARGET_FMA4) && TARGET_MMX_WITH_SSE"
821 "@
822 vfnmadd132ps\t{%2, %3, %0|%0, %3, %2}
823 vfnmadd231ps\t{%2, %1, %0|%0, %1, %2}
824 vfnmaddps\t{%3, %2, %1, %0|%0, %1, %2, %3}"
825 [(set_attr "isa" "fma,fma,fma4")
826 (set_attr "type" "ssemuladd")
827 (set_attr "mode" "V4SF")])
828
829 (define_insn "fnmsv2sf4"
830 [(set (match_operand:V2SF 0 "register_operand" "=v,v,x")
831 (fma:V2SF
832 (neg:V2SF
833 (match_operand:V2SF 1 "register_operand" "%0,v,x"))
834 (match_operand:V2SF 2 "register_operand" "v,v,x")
835 (neg:V2SF
836 (match_operand:V2SF 3 "register_operand" "v,0,x"))))]
837 "(TARGET_FMA || TARGET_FMA4) && TARGET_MMX_WITH_SSE"
838 "@
839 vfnmsub132ps\t{%2, %3, %0|%0, %3, %2}
840 vfnmsub231ps\t{%2, %1, %0|%0, %1, %2}
841 vfnmsubps\t{%3, %2, %1, %0|%0, %1, %2, %3}"
842 [(set_attr "isa" "fma,fma,fma4")
843 (set_attr "type" "ssemuladd")
844 (set_attr "mode" "V4SF")])
845
846 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
847 ;;
848 ;; Parallel single-precision floating point conversion operations
849 ;;
850 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
851
852 (define_insn "mmx_fix_truncv2sfv2si2"
853 [(set (match_operand:V2SI 0 "register_operand" "=y,Yv")
854 (fix:V2SI (match_operand:V2SF 1 "register_mmxmem_operand" "ym,Yv")))]
855 "TARGET_3DNOW || TARGET_MMX_WITH_SSE"
856 "@
857 pf2id\t{%1, %0|%0, %1}
858 %vcvttps2dq\t{%1, %0|%0, %1}"
859 [(set_attr "isa" "*,sse2")
860 (set_attr "mmx_isa" "native,*")
861 (set_attr "type" "mmxcvt,ssecvt")
862 (set_attr "prefix_extra" "1,*")
863 (set_attr "prefix_rep" "*,1")
864 (set_attr "prefix_data16" "*,0")
865 (set_attr "prefix" "*,maybe_vex")
866 (set_attr "mode" "V2SF,TI")])
867
868 (define_expand "fix_truncv2sfv2si2"
869 [(set (match_operand:V2SI 0 "register_operand")
870 (fix:V2SI (match_operand:V2SF 1 "register_operand")))]
871 "TARGET_MMX_WITH_SSE")
872
873 (define_insn "fixuns_truncv2sfv2si2"
874 [(set (match_operand:V2SI 0 "register_operand" "=v")
875 (unsigned_fix:V2SI (match_operand:V2SF 1 "register_operand" "v")))]
876 "TARGET_MMX_WITH_SSE && TARGET_AVX512VL"
877 "vcvttps2udq\t{%1, %0|%0, %1}"
878 [(set_attr "type" "ssecvt")
879 (set_attr "prefix" "evex")
880 (set_attr "mode" "TI")])
881
882 (define_insn "mmx_floatv2siv2sf2"
883 [(set (match_operand:V2SF 0 "register_operand" "=y,Yv")
884 (float:V2SF (match_operand:V2SI 1 "register_mmxmem_operand" "ym,Yv")))]
885 "TARGET_3DNOW || TARGET_MMX_WITH_SSE"
886 "@
887 pi2fd\t{%1, %0|%0, %1}
888 %vcvtdq2ps\t{%1, %0|%0, %1}"
889 [(set_attr "isa" "*,sse2")
890 (set_attr "mmx_isa" "native,*")
891 (set_attr "type" "mmxcvt,ssecvt")
892 (set_attr "prefix_extra" "1")
893 (set_attr "prefix" "*,maybe_vex")
894 (set_attr "mode" "V2SF,V4SF")])
895
896 (define_expand "floatv2siv2sf2"
897 [(set (match_operand:V2SF 0 "register_operand")
898 (float:V2SF (match_operand:V2SI 1 "register_operand")))]
899 "TARGET_MMX_WITH_SSE")
900
901 (define_insn "floatunsv2siv2sf2"
902 [(set (match_operand:V2SF 0 "register_operand" "=v")
903 (unsigned_float:V2SF (match_operand:V2SI 1 "register_operand" "v")))]
904 "TARGET_MMX_WITH_SSE && TARGET_AVX512VL"
905 "vcvtudq2ps\t{%1, %0|%0, %1}"
906 [(set_attr "type" "ssecvt")
907 (set_attr "prefix" "evex")
908 (set_attr "mode" "V4SF")])
909
910 (define_insn "mmx_pf2iw"
911 [(set (match_operand:V2SI 0 "register_operand" "=y")
912 (sign_extend:V2SI
913 (ss_truncate:V2HI
914 (fix:V2SI
915 (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
916 "TARGET_3DNOW_A"
917 "pf2iw\t{%1, %0|%0, %1}"
918 [(set_attr "type" "mmxcvt")
919 (set_attr "prefix_extra" "1")
920 (set_attr "mode" "V2SF")])
921
922 (define_insn "mmx_pi2fw"
923 [(set (match_operand:V2SF 0 "register_operand" "=y")
924 (float:V2SF
925 (sign_extend:V2SI
926 (truncate:V2HI
927 (match_operand:V2SI 1 "nonimmediate_operand" "ym")))))]
928 "TARGET_3DNOW_A"
929 "pi2fw\t{%1, %0|%0, %1}"
930 [(set_attr "type" "mmxcvt")
931 (set_attr "prefix_extra" "1")
932 (set_attr "mode" "V2SF")])
933
934 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
935 ;;
936 ;; Parallel single-precision floating point element swizzling
937 ;;
938 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
939
940 (define_insn "mmx_pswapdv2sf2"
941 [(set (match_operand:V2SF 0 "register_operand" "=y,x,Yv")
942 (vec_select:V2SF
943 (match_operand:V2SF 1 "register_mmxmem_operand" "ym,0,Yv")
944 (parallel [(const_int 1) (const_int 0)])))]
945 "TARGET_3DNOW_A || TARGET_MMX_WITH_SSE"
946 "@
947 pswapd\t{%1, %0|%0, %1}
948 shufps\t{$0xe1, %1, %0|%0, %1, 0xe1}
949 vshufps\t{$0xe1, %1, %1, %0|%0, %1, %1, 0xe1}"
950 [(set_attr "isa" "*,sse_noavx,avx")
951 (set_attr "mmx_isa" "native,*,*")
952 (set_attr "type" "mmxcvt,ssemov,ssemov")
953 (set_attr "prefix_extra" "1,*,*")
954 (set_attr "mode" "V2SF,V4SF,V4SF")])
955
956 (define_insn "*mmx_movshdup"
957 [(set (match_operand:V2SF 0 "register_operand" "=v,x")
958 (vec_select:V2SF
959 (match_operand:V2SF 1 "register_operand" "v,0")
960 (parallel [(const_int 1) (const_int 1)])))]
961 "TARGET_MMX_WITH_SSE"
962 "@
963 %vmovshdup\t{%1, %0|%0, %1}
964 shufps\t{$0xe5, %0, %0|%0, %0, 0xe5}"
965 [(set_attr "isa" "sse3,*")
966 (set_attr "type" "sse,sseshuf1")
967 (set_attr "length_immediate" "*,1")
968 (set_attr "prefix_rep" "1,*")
969 (set_attr "prefix" "maybe_vex,orig")
970 (set_attr "mode" "V4SF")])
971
972 (define_insn "*mmx_movsldup"
973 [(set (match_operand:V2SF 0 "register_operand" "=v,x")
974 (vec_select:V2SF
975 (match_operand:V2SF 1 "register_operand" "v,0")
976 (parallel [(const_int 0) (const_int 0)])))]
977 "TARGET_MMX_WITH_SSE"
978 "@
979 %vmovsldup\t{%1, %0|%0, %1}
980 shufps\t{$0xe0, %0, %0|%0, %0, 0xe0}"
981 [(set_attr "isa" "sse3,*")
982 (set_attr "type" "sse,sseshuf1")
983 (set_attr "length_immediate" "*,1")
984 (set_attr "prefix_rep" "1,*")
985 (set_attr "prefix" "maybe_vex,orig")
986 (set_attr "mode" "V4SF")])
987
988 (define_insn "*vec_dupv2sf"
989 [(set (match_operand:V2SF 0 "register_operand" "=y,Yv,x")
990 (vec_duplicate:V2SF
991 (match_operand:SF 1 "register_operand" "0,Yv,0")))]
992 "TARGET_MMX || TARGET_MMX_WITH_SSE"
993 "@
994 punpckldq\t%0, %0
995 %vmovsldup\t{%1, %0|%0, %1}
996 shufps\t{$0xe0, %0, %0|%0, %0, 0xe0}"
997 [(set_attr "isa" "*,sse3,sse_noavx")
998 (set_attr "mmx_isa" "native,*,*")
999 (set_attr "type" "mmxcvt,sse,sseshuf1")
1000 (set_attr "length_immediate" "*,*,1")
1001 (set_attr "prefix_rep" "*,1,*")
1002 (set_attr "prefix" "*,maybe_vex,orig")
1003 (set_attr "mode" "DI,V4SF,V4SF")])
1004
1005 (define_insn "*mmx_movss"
1006 [(set (match_operand:V2SF 0 "register_operand" "=x,v")
1007 (vec_merge:V2SF
1008 (match_operand:V2SF 2 "register_operand" " x,v")
1009 (match_operand:V2SF 1 "register_operand" " 0,v")
1010 (const_int 1)))]
1011 "TARGET_MMX_WITH_SSE"
1012 "@
1013 movss\t{%2, %0|%0, %2}
1014 vmovss\t{%2, %1, %0|%0, %1, %2}"
1015 [(set_attr "isa" "noavx,avx")
1016 (set_attr "type" "ssemov")
1017 (set_attr "prefix" "orig,maybe_evex")
1018 (set_attr "mode" "SF")])
1019
1020 (define_insn "*mmx_concatv2sf"
1021 [(set (match_operand:V2SF 0 "register_operand" "=y,y")
1022 (vec_concat:V2SF
1023 (match_operand:SF 1 "nonimmediate_operand" " 0,rm")
1024 (match_operand:SF 2 "nonimm_or_0_operand" "ym,C")))]
1025 "TARGET_MMX && !TARGET_SSE"
1026 "@
1027 punpckldq\t{%2, %0|%0, %2}
1028 movd\t{%1, %0|%0, %1}"
1029 [(set_attr "type" "mmxcvt,mmxmov")
1030 (set_attr "mode" "DI")])
1031
1032 (define_expand "vec_setv2sf"
1033 [(match_operand:V2SF 0 "register_operand")
1034 (match_operand:SF 1 "register_operand")
1035 (match_operand 2 "const_int_operand")]
1036 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1037 {
1038 ix86_expand_vector_set (TARGET_MMX_WITH_SSE, operands[0], operands[1],
1039 INTVAL (operands[2]));
1040 DONE;
1041 })
1042
1043 ;; Avoid combining registers from different units in a single alternative,
1044 ;; see comment above inline_secondary_memory_needed function in i386.c
1045 (define_insn_and_split "*vec_extractv2sf_0"
1046 [(set (match_operand:SF 0 "nonimmediate_operand" "=x, m,y ,m,f,r")
1047 (vec_select:SF
1048 (match_operand:V2SF 1 "nonimmediate_operand" " xm,x,ym,y,m,m")
1049 (parallel [(const_int 0)])))]
1050 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1051 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1052 "#"
1053 "&& reload_completed"
1054 [(set (match_dup 0) (match_dup 1))]
1055 "operands[1] = gen_lowpart (SFmode, operands[1]);"
1056 [(set_attr "mmx_isa" "*,*,native,native,*,*")])
1057
1058 ;; Avoid combining registers from different units in a single alternative,
1059 ;; see comment above inline_secondary_memory_needed function in i386.c
1060 (define_insn "*vec_extractv2sf_1"
1061 [(set (match_operand:SF 0 "nonimmediate_operand" "=y,x,x,y,x,f,r")
1062 (vec_select:SF
1063 (match_operand:V2SF 1 "nonimmediate_operand" " 0,x,0,o,o,o,o")
1064 (parallel [(const_int 1)])))]
1065 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1066 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1067 "@
1068 punpckhdq\t%0, %0
1069 %vmovshdup\t{%1, %0|%0, %1}
1070 shufps\t{$0xe5, %0, %0|%0, %0, 0xe5}
1071 #
1072 #
1073 #
1074 #"
1075 [(set_attr "isa" "*,sse3,noavx,*,*,*,*")
1076 (set_attr "mmx_isa" "native,*,*,native,*,*,*")
1077 (set_attr "type" "mmxcvt,sse,sseshuf1,mmxmov,ssemov,fmov,imov")
1078 (set (attr "length_immediate")
1079 (if_then_else (eq_attr "alternative" "2")
1080 (const_string "1")
1081 (const_string "*")))
1082 (set (attr "prefix_rep")
1083 (if_then_else (eq_attr "alternative" "1")
1084 (const_string "1")
1085 (const_string "*")))
1086 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig,orig,orig")
1087 (set_attr "mode" "DI,V4SF,V4SF,SF,SF,SF,SF")])
1088
1089 (define_split
1090 [(set (match_operand:SF 0 "register_operand")
1091 (vec_select:SF
1092 (match_operand:V2SF 1 "memory_operand")
1093 (parallel [(const_int 1)])))]
1094 "(TARGET_MMX || TARGET_MMX_WITH_SSE) && reload_completed"
1095 [(set (match_dup 0) (match_dup 1))]
1096 "operands[1] = adjust_address (operands[1], SFmode, 4);")
1097
1098 (define_expand "vec_extractv2sfsf"
1099 [(match_operand:SF 0 "register_operand")
1100 (match_operand:V2SF 1 "register_operand")
1101 (match_operand 2 "const_int_operand")]
1102 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1103 {
1104 ix86_expand_vector_extract (TARGET_MMX_WITH_SSE, operands[0],
1105 operands[1], INTVAL (operands[2]));
1106 DONE;
1107 })
1108
1109 (define_expand "vec_initv2sfsf"
1110 [(match_operand:V2SF 0 "register_operand")
1111 (match_operand 1)]
1112 "(TARGET_MMX || TARGET_MMX_WITH_SSE) && TARGET_SSE"
1113 {
1114 ix86_expand_vector_init (TARGET_MMX_WITH_SSE, operands[0],
1115 operands[1]);
1116 DONE;
1117 })
1118
1119 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1120 ;;
1121 ;; Parallel integral arithmetic
1122 ;;
1123 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1124
1125 (define_expand "mmx_<plusminus_insn><mode>3"
1126 [(set (match_operand:MMXMODEI8 0 "register_operand")
1127 (plusminus:MMXMODEI8
1128 (match_operand:MMXMODEI8 1 "register_mmxmem_operand")
1129 (match_operand:MMXMODEI8 2 "register_mmxmem_operand")))]
1130 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1131 "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
1132
1133 (define_expand "<plusminus_insn><mode>3"
1134 [(set (match_operand:MMXMODEI 0 "register_operand")
1135 (plusminus:MMXMODEI
1136 (match_operand:MMXMODEI 1 "register_operand")
1137 (match_operand:MMXMODEI 2 "register_operand")))]
1138 "TARGET_MMX_WITH_SSE"
1139 "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
1140
1141 (define_insn "*mmx_<plusminus_insn><mode>3"
1142 [(set (match_operand:MMXMODEI8 0 "register_operand" "=y,x,Yv")
1143 (plusminus:MMXMODEI8
1144 (match_operand:MMXMODEI8 1 "register_mmxmem_operand" "<comm>0,0,Yv")
1145 (match_operand:MMXMODEI8 2 "register_mmxmem_operand" "ym,x,Yv")))]
1146 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1147 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
1148 "@
1149 p<plusminus_mnemonic><mmxvecsize>\t{%2, %0|%0, %2}
1150 p<plusminus_mnemonic><mmxvecsize>\t{%2, %0|%0, %2}
1151 vp<plusminus_mnemonic><mmxvecsize>\t{%2, %1, %0|%0, %1, %2}"
1152 [(set_attr "isa" "*,sse2_noavx,avx")
1153 (set_attr "mmx_isa" "native,*,*")
1154 (set_attr "type" "mmxadd,sseadd,sseadd")
1155 (set_attr "mode" "DI,TI,TI")])
1156
1157 (define_expand "mmx_<plusminus_insn><mode>3"
1158 [(set (match_operand:MMXMODE12 0 "register_operand")
1159 (sat_plusminus:MMXMODE12
1160 (match_operand:MMXMODE12 1 "register_mmxmem_operand")
1161 (match_operand:MMXMODE12 2 "register_mmxmem_operand")))]
1162 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1163 "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
1164
1165 (define_insn "*mmx_<plusminus_insn><mode>3"
1166 [(set (match_operand:MMXMODE12 0 "register_operand" "=y,x,Yv")
1167 (sat_plusminus:MMXMODE12
1168 (match_operand:MMXMODE12 1 "register_mmxmem_operand" "<comm>0,0,Yv")
1169 (match_operand:MMXMODE12 2 "register_mmxmem_operand" "ym,x,Yv")))]
1170 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1171 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
1172 "@
1173 p<plusminus_mnemonic><mmxvecsize>\t{%2, %0|%0, %2}
1174 p<plusminus_mnemonic><mmxvecsize>\t{%2, %0|%0, %2}
1175 vp<plusminus_mnemonic><mmxvecsize>\t{%2, %1, %0|%0, %1, %2}"
1176 [(set_attr "isa" "*,sse2_noavx,avx")
1177 (set_attr "mmx_isa" "native,*,*")
1178 (set_attr "type" "mmxadd,sseadd,sseadd")
1179 (set_attr "mode" "DI,TI,TI")])
1180
1181 (define_expand "mmx_mulv4hi3"
1182 [(set (match_operand:V4HI 0 "register_operand")
1183 (mult:V4HI (match_operand:V4HI 1 "register_mmxmem_operand")
1184 (match_operand:V4HI 2 "register_mmxmem_operand")))]
1185 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1186 "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
1187
1188 (define_expand "mulv4hi3"
1189 [(set (match_operand:V4HI 0 "register_operand")
1190 (mult:V4HI (match_operand:V4HI 1 "register_operand")
1191 (match_operand:V4HI 2 "register_operand")))]
1192 "TARGET_MMX_WITH_SSE"
1193 "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
1194
1195 (define_insn "*mmx_mulv4hi3"
1196 [(set (match_operand:V4HI 0 "register_operand" "=y,x,Yv")
1197 (mult:V4HI (match_operand:V4HI 1 "register_mmxmem_operand" "%0,0,Yv")
1198 (match_operand:V4HI 2 "register_mmxmem_operand" "ym,x,Yv")))]
1199 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1200 && ix86_binary_operator_ok (MULT, V4HImode, operands)"
1201 "@
1202 pmullw\t{%2, %0|%0, %2}
1203 pmullw\t{%2, %0|%0, %2}
1204 vpmullw\t{%2, %1, %0|%0, %1, %2}"
1205 [(set_attr "isa" "*,sse2_noavx,avx")
1206 (set_attr "mmx_isa" "native,*,*")
1207 (set_attr "type" "mmxmul,ssemul,ssemul")
1208 (set_attr "mode" "DI,TI,TI")])
1209
1210 (define_expand "mmx_smulv4hi3_highpart"
1211 [(set (match_operand:V4HI 0 "register_operand")
1212 (truncate:V4HI
1213 (lshiftrt:V4SI
1214 (mult:V4SI
1215 (sign_extend:V4SI
1216 (match_operand:V4HI 1 "register_mmxmem_operand"))
1217 (sign_extend:V4SI
1218 (match_operand:V4HI 2 "register_mmxmem_operand")))
1219 (const_int 16))))]
1220 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1221 "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
1222
1223 (define_insn "*mmx_smulv4hi3_highpart"
1224 [(set (match_operand:V4HI 0 "register_operand" "=y,x,Yv")
1225 (truncate:V4HI
1226 (lshiftrt:V4SI
1227 (mult:V4SI
1228 (sign_extend:V4SI
1229 (match_operand:V4HI 1 "register_mmxmem_operand" "%0,0,Yv"))
1230 (sign_extend:V4SI
1231 (match_operand:V4HI 2 "register_mmxmem_operand" "ym,x,Yv")))
1232 (const_int 16))))]
1233 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1234 && ix86_binary_operator_ok (MULT, V4HImode, operands)"
1235 "@
1236 pmulhw\t{%2, %0|%0, %2}
1237 pmulhw\t{%2, %0|%0, %2}
1238 vpmulhw\t{%2, %1, %0|%0, %1, %2}"
1239 [(set_attr "isa" "*,sse2_noavx,avx")
1240 (set_attr "mmx_isa" "native,*,*")
1241 (set_attr "type" "mmxmul,ssemul,ssemul")
1242 (set_attr "mode" "DI,TI,TI")])
1243
1244 (define_expand "mmx_umulv4hi3_highpart"
1245 [(set (match_operand:V4HI 0 "register_operand")
1246 (truncate:V4HI
1247 (lshiftrt:V4SI
1248 (mult:V4SI
1249 (zero_extend:V4SI
1250 (match_operand:V4HI 1 "register_mmxmem_operand"))
1251 (zero_extend:V4SI
1252 (match_operand:V4HI 2 "register_mmxmem_operand")))
1253 (const_int 16))))]
1254 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1255 && (TARGET_SSE || TARGET_3DNOW_A)"
1256 "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
1257
1258 (define_insn "*mmx_umulv4hi3_highpart"
1259 [(set (match_operand:V4HI 0 "register_operand" "=y,x,Yv")
1260 (truncate:V4HI
1261 (lshiftrt:V4SI
1262 (mult:V4SI
1263 (zero_extend:V4SI
1264 (match_operand:V4HI 1 "register_mmxmem_operand" "%0,0,Yv"))
1265 (zero_extend:V4SI
1266 (match_operand:V4HI 2 "register_mmxmem_operand" "ym,x,Yv")))
1267 (const_int 16))))]
1268 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1269 && (TARGET_SSE || TARGET_3DNOW_A)
1270 && ix86_binary_operator_ok (MULT, V4HImode, operands)"
1271 "@
1272 pmulhuw\t{%2, %0|%0, %2}
1273 pmulhuw\t{%2, %0|%0, %2}
1274 vpmulhuw\t{%2, %1, %0|%0, %1, %2}"
1275 [(set_attr "isa" "*,sse2_noavx,avx")
1276 (set_attr "mmx_isa" "native,*,*")
1277 (set_attr "type" "mmxmul,ssemul,ssemul")
1278 (set_attr "mode" "DI,TI,TI")])
1279
1280 (define_expand "mmx_pmaddwd"
1281 [(set (match_operand:V2SI 0 "register_operand")
1282 (plus:V2SI
1283 (mult:V2SI
1284 (sign_extend:V2SI
1285 (vec_select:V2HI
1286 (match_operand:V4HI 1 "register_mmxmem_operand")
1287 (parallel [(const_int 0) (const_int 2)])))
1288 (sign_extend:V2SI
1289 (vec_select:V2HI
1290 (match_operand:V4HI 2 "register_mmxmem_operand")
1291 (parallel [(const_int 0) (const_int 2)]))))
1292 (mult:V2SI
1293 (sign_extend:V2SI
1294 (vec_select:V2HI (match_dup 1)
1295 (parallel [(const_int 1) (const_int 3)])))
1296 (sign_extend:V2SI
1297 (vec_select:V2HI (match_dup 2)
1298 (parallel [(const_int 1) (const_int 3)]))))))]
1299 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1300 "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
1301
1302 (define_insn "*mmx_pmaddwd"
1303 [(set (match_operand:V2SI 0 "register_operand" "=y,x,Yv")
1304 (plus:V2SI
1305 (mult:V2SI
1306 (sign_extend:V2SI
1307 (vec_select:V2HI
1308 (match_operand:V4HI 1 "register_mmxmem_operand" "%0,0,Yv")
1309 (parallel [(const_int 0) (const_int 2)])))
1310 (sign_extend:V2SI
1311 (vec_select:V2HI
1312 (match_operand:V4HI 2 "register_mmxmem_operand" "ym,x,Yv")
1313 (parallel [(const_int 0) (const_int 2)]))))
1314 (mult:V2SI
1315 (sign_extend:V2SI
1316 (vec_select:V2HI (match_dup 1)
1317 (parallel [(const_int 1) (const_int 3)])))
1318 (sign_extend:V2SI
1319 (vec_select:V2HI (match_dup 2)
1320 (parallel [(const_int 1) (const_int 3)]))))))]
1321 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1322 && ix86_binary_operator_ok (MULT, V4HImode, operands)"
1323 "@
1324 pmaddwd\t{%2, %0|%0, %2}
1325 pmaddwd\t{%2, %0|%0, %2}
1326 vpmaddwd\t{%2, %1, %0|%0, %1, %2}"
1327 [(set_attr "isa" "*,sse2_noavx,avx")
1328 (set_attr "mmx_isa" "native,*,*")
1329 (set_attr "type" "mmxmul,sseiadd,sseiadd")
1330 (set_attr "mode" "DI,TI,TI")])
1331
1332 (define_expand "mmx_pmulhrwv4hi3"
1333 [(set (match_operand:V4HI 0 "register_operand")
1334 (truncate:V4HI
1335 (lshiftrt:V4SI
1336 (plus:V4SI
1337 (mult:V4SI
1338 (sign_extend:V4SI
1339 (match_operand:V4HI 1 "nonimmediate_operand"))
1340 (sign_extend:V4SI
1341 (match_operand:V4HI 2 "nonimmediate_operand")))
1342 (const_vector:V4SI [(const_int 32768) (const_int 32768)
1343 (const_int 32768) (const_int 32768)]))
1344 (const_int 16))))]
1345 "TARGET_3DNOW"
1346 "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
1347
1348 (define_insn "*mmx_pmulhrwv4hi3"
1349 [(set (match_operand:V4HI 0 "register_operand" "=y")
1350 (truncate:V4HI
1351 (lshiftrt:V4SI
1352 (plus:V4SI
1353 (mult:V4SI
1354 (sign_extend:V4SI
1355 (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
1356 (sign_extend:V4SI
1357 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
1358 (const_vector:V4SI [(const_int 32768) (const_int 32768)
1359 (const_int 32768) (const_int 32768)]))
1360 (const_int 16))))]
1361 "TARGET_3DNOW && ix86_binary_operator_ok (MULT, V4HImode, operands)"
1362 "pmulhrw\t{%2, %0|%0, %2}"
1363 [(set_attr "type" "mmxmul")
1364 (set_attr "prefix_extra" "1")
1365 (set_attr "mode" "DI")])
1366
1367 (define_expand "sse2_umulv1siv1di3"
1368 [(set (match_operand:V1DI 0 "register_operand")
1369 (mult:V1DI
1370 (zero_extend:V1DI
1371 (vec_select:V1SI
1372 (match_operand:V2SI 1 "register_mmxmem_operand")
1373 (parallel [(const_int 0)])))
1374 (zero_extend:V1DI
1375 (vec_select:V1SI
1376 (match_operand:V2SI 2 "register_mmxmem_operand")
1377 (parallel [(const_int 0)])))))]
1378 "(TARGET_MMX || TARGET_MMX_WITH_SSE) && TARGET_SSE2"
1379 "ix86_fixup_binary_operands_no_copy (MULT, V2SImode, operands);")
1380
1381 (define_insn "*sse2_umulv1siv1di3"
1382 [(set (match_operand:V1DI 0 "register_operand" "=y,x,Yv")
1383 (mult:V1DI
1384 (zero_extend:V1DI
1385 (vec_select:V1SI
1386 (match_operand:V2SI 1 "register_mmxmem_operand" "%0,0,Yv")
1387 (parallel [(const_int 0)])))
1388 (zero_extend:V1DI
1389 (vec_select:V1SI
1390 (match_operand:V2SI 2 "register_mmxmem_operand" "ym,x,Yv")
1391 (parallel [(const_int 0)])))))]
1392 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1393 && TARGET_SSE2
1394 && ix86_binary_operator_ok (MULT, V2SImode, operands)"
1395 "@
1396 pmuludq\t{%2, %0|%0, %2}
1397 pmuludq\t{%2, %0|%0, %2}
1398 vpmuludq\t{%2, %1, %0|%0, %1, %2}"
1399 [(set_attr "isa" "*,sse2_noavx,avx")
1400 (set_attr "mmx_isa" "native,*,*")
1401 (set_attr "type" "mmxmul,ssemul,ssemul")
1402 (set_attr "mode" "DI,TI,TI")])
1403
1404 (define_expand "mmx_<code>v4hi3"
1405 [(set (match_operand:V4HI 0 "register_operand")
1406 (smaxmin:V4HI
1407 (match_operand:V4HI 1 "register_mmxmem_operand")
1408 (match_operand:V4HI 2 "register_mmxmem_operand")))]
1409 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1410 && (TARGET_SSE || TARGET_3DNOW_A)"
1411 "ix86_fixup_binary_operands_no_copy (<CODE>, V4HImode, operands);")
1412
1413 (define_expand "<code>v4hi3"
1414 [(set (match_operand:V4HI 0 "register_operand")
1415 (smaxmin:V4HI
1416 (match_operand:V4HI 1 "register_operand")
1417 (match_operand:V4HI 2 "register_operand")))]
1418 "TARGET_MMX_WITH_SSE"
1419 "ix86_fixup_binary_operands_no_copy (<CODE>, V4HImode, operands);")
1420
1421 (define_insn "*mmx_<code>v4hi3"
1422 [(set (match_operand:V4HI 0 "register_operand" "=y,x,Yv")
1423 (smaxmin:V4HI
1424 (match_operand:V4HI 1 "register_mmxmem_operand" "%0,0,Yv")
1425 (match_operand:V4HI 2 "register_mmxmem_operand" "ym,x,Yv")))]
1426 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1427 && (TARGET_SSE || TARGET_3DNOW_A)
1428 && ix86_binary_operator_ok (<CODE>, V4HImode, operands)"
1429 "@
1430 p<maxmin_int>w\t{%2, %0|%0, %2}
1431 p<maxmin_int>w\t{%2, %0|%0, %2}
1432 vp<maxmin_int>w\t{%2, %1, %0|%0, %1, %2}"
1433 [(set_attr "isa" "*,sse2_noavx,avx")
1434 (set_attr "mmx_isa" "native,*,*")
1435 (set_attr "type" "mmxadd,sseiadd,sseiadd")
1436 (set_attr "mode" "DI,TI,TI")])
1437
1438 (define_expand "mmx_<code>v8qi3"
1439 [(set (match_operand:V8QI 0 "register_operand")
1440 (umaxmin:V8QI
1441 (match_operand:V8QI 1 "register_mmxmem_operand")
1442 (match_operand:V8QI 2 "register_mmxmem_operand")))]
1443 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1444 && (TARGET_SSE || TARGET_3DNOW_A)"
1445 "ix86_fixup_binary_operands_no_copy (<CODE>, V8QImode, operands);")
1446
1447 (define_expand "<code>v8qi3"
1448 [(set (match_operand:V8QI 0 "register_operand")
1449 (umaxmin:V8QI
1450 (match_operand:V8QI 1 "register_operand")
1451 (match_operand:V8QI 2 "register_operand")))]
1452 "TARGET_MMX_WITH_SSE"
1453 "ix86_fixup_binary_operands_no_copy (<CODE>, V8QImode, operands);")
1454
1455 (define_insn "*mmx_<code>v8qi3"
1456 [(set (match_operand:V8QI 0 "register_operand" "=y,x,Yv")
1457 (umaxmin:V8QI
1458 (match_operand:V8QI 1 "register_mmxmem_operand" "%0,0,Yv")
1459 (match_operand:V8QI 2 "register_mmxmem_operand" "ym,x,Yv")))]
1460 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1461 && (TARGET_SSE || TARGET_3DNOW_A)
1462 && ix86_binary_operator_ok (<CODE>, V8QImode, operands)"
1463 "@
1464 p<maxmin_int>b\t{%2, %0|%0, %2}
1465 p<maxmin_int>b\t{%2, %0|%0, %2}
1466 vp<maxmin_int>b\t{%2, %1, %0|%0, %1, %2}"
1467 [(set_attr "isa" "*,sse2_noavx,avx")
1468 (set_attr "mmx_isa" "native,*,*")
1469 (set_attr "type" "mmxadd,sseiadd,sseiadd")
1470 (set_attr "mode" "DI,TI,TI")])
1471
1472 (define_insn "mmx_ashr<mode>3"
1473 [(set (match_operand:MMXMODE24 0 "register_operand" "=y,x,Yv")
1474 (ashiftrt:MMXMODE24
1475 (match_operand:MMXMODE24 1 "register_operand" "0,0,Yv")
1476 (match_operand:DI 2 "nonmemory_operand" "yN,xN,YvN")))]
1477 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1478 "@
1479 psra<mmxvecsize>\t{%2, %0|%0, %2}
1480 psra<mmxvecsize>\t{%2, %0|%0, %2}
1481 vpsra<mmxvecsize>\t{%2, %1, %0|%0, %1, %2}"
1482 [(set_attr "isa" "*,sse2_noavx,avx")
1483 (set_attr "mmx_isa" "native,*,*")
1484 (set_attr "type" "mmxshft,sseishft,sseishft")
1485 (set (attr "length_immediate")
1486 (if_then_else (match_operand 2 "const_int_operand")
1487 (const_string "1")
1488 (const_string "0")))
1489 (set_attr "mode" "DI,TI,TI")])
1490
1491 (define_expand "ashr<mode>3"
1492 [(set (match_operand:MMXMODE24 0 "register_operand")
1493 (ashiftrt:MMXMODE24
1494 (match_operand:MMXMODE24 1 "register_operand")
1495 (match_operand:DI 2 "nonmemory_operand")))]
1496 "TARGET_MMX_WITH_SSE")
1497
1498 (define_insn "mmx_<shift_insn><mode>3"
1499 [(set (match_operand:MMXMODE248 0 "register_operand" "=y,x,Yv")
1500 (any_lshift:MMXMODE248
1501 (match_operand:MMXMODE248 1 "register_operand" "0,0,Yv")
1502 (match_operand:DI 2 "nonmemory_operand" "yN,xN,YvN")))]
1503 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1504 "@
1505 p<vshift><mmxvecsize>\t{%2, %0|%0, %2}
1506 p<vshift><mmxvecsize>\t{%2, %0|%0, %2}
1507 vp<vshift><mmxvecsize>\t{%2, %1, %0|%0, %1, %2}"
1508 [(set_attr "isa" "*,sse2_noavx,avx")
1509 (set_attr "mmx_isa" "native,*,*")
1510 (set_attr "type" "mmxshft,sseishft,sseishft")
1511 (set (attr "length_immediate")
1512 (if_then_else (match_operand 2 "const_int_operand")
1513 (const_string "1")
1514 (const_string "0")))
1515 (set_attr "mode" "DI,TI,TI")])
1516
1517 (define_expand "<shift_insn><mode>3"
1518 [(set (match_operand:MMXMODE248 0 "register_operand")
1519 (any_lshift:MMXMODE248
1520 (match_operand:MMXMODE248 1 "register_operand")
1521 (match_operand:DI 2 "nonmemory_operand")))]
1522 "TARGET_MMX_WITH_SSE")
1523
1524 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1525 ;;
1526 ;; Parallel integral comparisons
1527 ;;
1528 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1529
1530 (define_expand "mmx_eq<mode>3"
1531 [(set (match_operand:MMXMODEI 0 "register_operand")
1532 (eq:MMXMODEI
1533 (match_operand:MMXMODEI 1 "register_mmxmem_operand")
1534 (match_operand:MMXMODEI 2 "register_mmxmem_operand")))]
1535 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1536 "ix86_fixup_binary_operands_no_copy (EQ, <MODE>mode, operands);")
1537
1538 (define_insn "*mmx_eq<mode>3"
1539 [(set (match_operand:MMXMODEI 0 "register_operand" "=y,x,Yv")
1540 (eq:MMXMODEI
1541 (match_operand:MMXMODEI 1 "register_mmxmem_operand" "%0,0,Yv")
1542 (match_operand:MMXMODEI 2 "register_mmxmem_operand" "ym,x,Yv")))]
1543 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1544 && ix86_binary_operator_ok (EQ, <MODE>mode, operands)"
1545 "@
1546 pcmpeq<mmxvecsize>\t{%2, %0|%0, %2}
1547 pcmpeq<mmxvecsize>\t{%2, %0|%0, %2}
1548 vpcmpeq<mmxvecsize>\t{%2, %1, %0|%0, %1, %2}"
1549 [(set_attr "isa" "*,sse2_noavx,avx")
1550 (set_attr "mmx_isa" "native,*,*")
1551 (set_attr "type" "mmxcmp,ssecmp,ssecmp")
1552 (set_attr "mode" "DI,TI,TI")])
1553
1554 (define_insn "mmx_gt<mode>3"
1555 [(set (match_operand:MMXMODEI 0 "register_operand" "=y,x,Yv")
1556 (gt:MMXMODEI
1557 (match_operand:MMXMODEI 1 "register_operand" "0,0,Yv")
1558 (match_operand:MMXMODEI 2 "register_mmxmem_operand" "ym,x,Yv")))]
1559 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1560 "@
1561 pcmpgt<mmxvecsize>\t{%2, %0|%0, %2}
1562 pcmpgt<mmxvecsize>\t{%2, %0|%0, %2}
1563 vpcmpgt<mmxvecsize>\t{%2, %1, %0|%0, %1, %2}"
1564 [(set_attr "isa" "*,sse2_noavx,avx")
1565 (set_attr "mmx_isa" "native,*,*")
1566 (set_attr "type" "mmxcmp,ssecmp,ssecmp")
1567 (set_attr "mode" "DI,TI,TI")])
1568
1569 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1570 ;;
1571 ;; Parallel integral logical operations
1572 ;;
1573 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1574
1575 (define_expand "one_cmpl<mode>2"
1576 [(set (match_operand:MMXMODEI 0 "register_operand")
1577 (xor:MMXMODEI
1578 (match_operand:MMXMODEI 1 "register_operand")
1579 (match_dup 2)))]
1580 "TARGET_MMX_WITH_SSE"
1581 "operands[2] = force_reg (<MODE>mode, CONSTM1_RTX (<MODE>mode));")
1582
1583 (define_insn "mmx_andnot<mode>3"
1584 [(set (match_operand:MMXMODEI 0 "register_operand" "=y,x,Yv")
1585 (and:MMXMODEI
1586 (not:MMXMODEI (match_operand:MMXMODEI 1 "register_operand" "0,0,Yv"))
1587 (match_operand:MMXMODEI 2 "register_mmxmem_operand" "ym,x,Yv")))]
1588 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1589 "@
1590 pandn\t{%2, %0|%0, %2}
1591 pandn\t{%2, %0|%0, %2}
1592 vpandn\t{%2, %1, %0|%0, %1, %2}"
1593 [(set_attr "isa" "*,sse2_noavx,avx")
1594 (set_attr "mmx_isa" "native,*,*")
1595 (set_attr "type" "mmxadd,sselog,sselog")
1596 (set_attr "mode" "DI,TI,TI")])
1597
1598 (define_expand "mmx_<code><mode>3"
1599 [(set (match_operand:MMXMODEI 0 "register_operand")
1600 (any_logic:MMXMODEI
1601 (match_operand:MMXMODEI 1 "register_mmxmem_operand")
1602 (match_operand:MMXMODEI 2 "register_mmxmem_operand")))]
1603 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1604 "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
1605
1606 (define_expand "<code><mode>3"
1607 [(set (match_operand:MMXMODEI 0 "register_operand")
1608 (any_logic:MMXMODEI
1609 (match_operand:MMXMODEI 1 "register_operand")
1610 (match_operand:MMXMODEI 2 "register_operand")))]
1611 "TARGET_MMX_WITH_SSE"
1612 "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
1613
1614 (define_insn "*mmx_<code><mode>3"
1615 [(set (match_operand:MMXMODEI 0 "register_operand" "=y,x,Yv")
1616 (any_logic:MMXMODEI
1617 (match_operand:MMXMODEI 1 "register_mmxmem_operand" "%0,0,Yv")
1618 (match_operand:MMXMODEI 2 "register_mmxmem_operand" "ym,x,Yv")))]
1619 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1620 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
1621 "@
1622 p<logic>\t{%2, %0|%0, %2}
1623 p<logic>\t{%2, %0|%0, %2}
1624 vp<logic>\t{%2, %1, %0|%0, %1, %2}"
1625 [(set_attr "isa" "*,sse2_noavx,avx")
1626 (set_attr "mmx_isa" "native,*,*")
1627 (set_attr "type" "mmxadd,sselog,sselog")
1628 (set_attr "mode" "DI,TI,TI")])
1629
1630 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1631 ;;
1632 ;; Parallel integral element swizzling
1633 ;;
1634 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1635
1636 ;; Used in signed and unsigned truncations with saturation.
1637 (define_code_iterator any_s_truncate [ss_truncate us_truncate])
1638 ;; Instruction suffix for truncations with saturation.
1639 (define_code_attr s_trunsuffix [(ss_truncate "s") (us_truncate "u")])
1640
1641 (define_insn_and_split "mmx_pack<s_trunsuffix>swb"
1642 [(set (match_operand:V8QI 0 "register_operand" "=y,x,Yv")
1643 (vec_concat:V8QI
1644 (any_s_truncate:V4QI
1645 (match_operand:V4HI 1 "register_operand" "0,0,Yv"))
1646 (any_s_truncate:V4QI
1647 (match_operand:V4HI 2 "register_mmxmem_operand" "ym,x,Yv"))))]
1648 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1649 "@
1650 pack<s_trunsuffix>swb\t{%2, %0|%0, %2}
1651 #
1652 #"
1653 "TARGET_SSE2 && reload_completed
1654 && SSE_REGNO_P (REGNO (operands[0]))"
1655 [(const_int 0)]
1656 "ix86_split_mmx_pack (operands, <any_s_truncate:CODE>); DONE;"
1657 [(set_attr "mmx_isa" "native,sse_noavx,avx")
1658 (set_attr "type" "mmxshft,sselog,sselog")
1659 (set_attr "mode" "DI,TI,TI")])
1660
1661 (define_insn_and_split "mmx_packssdw"
1662 [(set (match_operand:V4HI 0 "register_operand" "=y,x,Yv")
1663 (vec_concat:V4HI
1664 (ss_truncate:V2HI
1665 (match_operand:V2SI 1 "register_operand" "0,0,Yv"))
1666 (ss_truncate:V2HI
1667 (match_operand:V2SI 2 "register_mmxmem_operand" "ym,x,Yv"))))]
1668 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1669 "@
1670 packssdw\t{%2, %0|%0, %2}
1671 #
1672 #"
1673 "TARGET_SSE2 && reload_completed
1674 && SSE_REGNO_P (REGNO (operands[0]))"
1675 [(const_int 0)]
1676 "ix86_split_mmx_pack (operands, SS_TRUNCATE); DONE;"
1677 [(set_attr "mmx_isa" "native,sse_noavx,avx")
1678 (set_attr "type" "mmxshft,sselog,sselog")
1679 (set_attr "mode" "DI,TI,TI")])
1680
1681 (define_insn_and_split "mmx_punpckhbw"
1682 [(set (match_operand:V8QI 0 "register_operand" "=y,x,Yv")
1683 (vec_select:V8QI
1684 (vec_concat:V16QI
1685 (match_operand:V8QI 1 "register_operand" "0,0,Yv")
1686 (match_operand:V8QI 2 "register_mmxmem_operand" "ym,x,Yv"))
1687 (parallel [(const_int 4) (const_int 12)
1688 (const_int 5) (const_int 13)
1689 (const_int 6) (const_int 14)
1690 (const_int 7) (const_int 15)])))]
1691 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1692 "@
1693 punpckhbw\t{%2, %0|%0, %2}
1694 #
1695 #"
1696 "TARGET_SSE2 && reload_completed
1697 && SSE_REGNO_P (REGNO (operands[0]))"
1698 [(const_int 0)]
1699 "ix86_split_mmx_punpck (operands, true); DONE;"
1700 [(set_attr "mmx_isa" "native,sse_noavx,avx")
1701 (set_attr "type" "mmxcvt,sselog,sselog")
1702 (set_attr "mode" "DI,TI,TI")])
1703
1704 (define_insn_and_split "mmx_punpcklbw"
1705 [(set (match_operand:V8QI 0 "register_operand" "=y,x,Yv")
1706 (vec_select:V8QI
1707 (vec_concat:V16QI
1708 (match_operand:V8QI 1 "register_operand" "0,0,Yv")
1709 (match_operand:V8QI 2 "register_mmxmem_operand" "ym,x,Yv"))
1710 (parallel [(const_int 0) (const_int 8)
1711 (const_int 1) (const_int 9)
1712 (const_int 2) (const_int 10)
1713 (const_int 3) (const_int 11)])))]
1714 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1715 "@
1716 punpcklbw\t{%2, %0|%0, %k2}
1717 #
1718 #"
1719 "TARGET_SSE2 && reload_completed
1720 && SSE_REGNO_P (REGNO (operands[0]))"
1721 [(const_int 0)]
1722 "ix86_split_mmx_punpck (operands, false); DONE;"
1723 [(set_attr "mmx_isa" "native,sse_noavx,avx")
1724 (set_attr "type" "mmxcvt,sselog,sselog")
1725 (set_attr "mode" "DI,TI,TI")])
1726
1727 (define_insn_and_split "mmx_punpckhwd"
1728 [(set (match_operand:V4HI 0 "register_operand" "=y,x,Yv")
1729 (vec_select:V4HI
1730 (vec_concat:V8HI
1731 (match_operand:V4HI 1 "register_operand" "0,0,Yv")
1732 (match_operand:V4HI 2 "register_mmxmem_operand" "ym,x,Yv"))
1733 (parallel [(const_int 2) (const_int 6)
1734 (const_int 3) (const_int 7)])))]
1735 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1736 "@
1737 punpckhwd\t{%2, %0|%0, %2}
1738 #
1739 #"
1740 "TARGET_SSE2 && reload_completed
1741 && SSE_REGNO_P (REGNO (operands[0]))"
1742 [(const_int 0)]
1743 "ix86_split_mmx_punpck (operands, true); DONE;"
1744 [(set_attr "mmx_isa" "native,sse_noavx,avx")
1745 (set_attr "type" "mmxcvt,sselog,sselog")
1746 (set_attr "mode" "DI,TI,TI")])
1747
1748 (define_insn_and_split "mmx_punpcklwd"
1749 [(set (match_operand:V4HI 0 "register_operand" "=y,x,Yv")
1750 (vec_select:V4HI
1751 (vec_concat:V8HI
1752 (match_operand:V4HI 1 "register_operand" "0,0,Yv")
1753 (match_operand:V4HI 2 "register_mmxmem_operand" "ym,x,Yv"))
1754 (parallel [(const_int 0) (const_int 4)
1755 (const_int 1) (const_int 5)])))]
1756 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1757 "@
1758 punpcklwd\t{%2, %0|%0, %k2}
1759 #
1760 #"
1761 "TARGET_SSE2 && reload_completed
1762 && SSE_REGNO_P (REGNO (operands[0]))"
1763 [(const_int 0)]
1764 "ix86_split_mmx_punpck (operands, false); DONE;"
1765 [(set_attr "mmx_isa" "native,sse_noavx,avx")
1766 (set_attr "type" "mmxcvt,sselog,sselog")
1767 (set_attr "mode" "DI,TI,TI")])
1768
1769 (define_insn_and_split "mmx_punpckhdq"
1770 [(set (match_operand:V2SI 0 "register_operand" "=y,x,Yv")
1771 (vec_select:V2SI
1772 (vec_concat:V4SI
1773 (match_operand:V2SI 1 "register_operand" "0,0,Yv")
1774 (match_operand:V2SI 2 "register_mmxmem_operand" "ym,x,Yv"))
1775 (parallel [(const_int 1)
1776 (const_int 3)])))]
1777 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1778 "@
1779 punpckhdq\t{%2, %0|%0, %2}
1780 #
1781 #"
1782 "TARGET_SSE2 && reload_completed
1783 && SSE_REGNO_P (REGNO (operands[0]))"
1784 [(const_int 0)]
1785 "ix86_split_mmx_punpck (operands, true); DONE;"
1786 [(set_attr "mmx_isa" "native,sse_noavx,avx")
1787 (set_attr "type" "mmxcvt,sselog,sselog")
1788 (set_attr "mode" "DI,TI,TI")])
1789
1790 (define_insn_and_split "mmx_punpckldq"
1791 [(set (match_operand:V2SI 0 "register_operand" "=y,x,Yv")
1792 (vec_select:V2SI
1793 (vec_concat:V4SI
1794 (match_operand:V2SI 1 "register_operand" "0,0,Yv")
1795 (match_operand:V2SI 2 "register_mmxmem_operand" "ym,x,Yv"))
1796 (parallel [(const_int 0)
1797 (const_int 2)])))]
1798 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1799 "@
1800 punpckldq\t{%2, %0|%0, %k2}
1801 #
1802 #"
1803 "TARGET_SSE2 && reload_completed
1804 && SSE_REGNO_P (REGNO (operands[0]))"
1805 [(const_int 0)]
1806 "ix86_split_mmx_punpck (operands, false); DONE;"
1807 [(set_attr "mmx_isa" "native,sse_noavx,avx")
1808 (set_attr "type" "mmxcvt,sselog,sselog")
1809 (set_attr "mode" "DI,TI,TI")])
1810
1811 (define_insn "*mmx_pinsrd"
1812 [(set (match_operand:V2SI 0 "register_operand" "=x,Yv")
1813 (vec_merge:V2SI
1814 (vec_duplicate:V2SI
1815 (match_operand:SI 2 "nonimmediate_operand" "rm,rm"))
1816 (match_operand:V2SI 1 "register_operand" "0,Yv")
1817 (match_operand:SI 3 "const_int_operand")))]
1818 "TARGET_MMX_WITH_SSE && TARGET_SSE4_1
1819 && ((unsigned) exact_log2 (INTVAL (operands[3]))
1820 < GET_MODE_NUNITS (V2SImode))"
1821 {
1822 operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])));
1823 switch (which_alternative)
1824 {
1825 case 1:
1826 return "vpinsrd\t{%3, %2, %1, %0|%0, %1, %2, %3}";
1827 case 0:
1828 return "pinsrd\t{%3, %2, %0|%0, %2, %3}";
1829 default:
1830 gcc_unreachable ();
1831 }
1832 }
1833 [(set_attr "isa" "noavx,avx")
1834 (set_attr "prefix_data16" "1")
1835 (set_attr "prefix_extra" "1")
1836 (set_attr "type" "sselog")
1837 (set_attr "length_immediate" "1")
1838 (set_attr "prefix" "orig,vex")
1839 (set_attr "mode" "TI")])
1840
1841 (define_expand "mmx_pinsrw"
1842 [(set (match_operand:V4HI 0 "register_operand")
1843 (vec_merge:V4HI
1844 (vec_duplicate:V4HI
1845 (match_operand:SI 2 "nonimmediate_operand"))
1846 (match_operand:V4HI 1 "register_operand")
1847 (match_operand:SI 3 "const_0_to_3_operand")))]
1848 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1849 && (TARGET_SSE || TARGET_3DNOW_A)"
1850 {
1851 operands[2] = gen_lowpart (HImode, operands[2]);
1852 operands[3] = GEN_INT (1 << INTVAL (operands[3]));
1853 })
1854
1855 (define_insn "*mmx_pinsrw"
1856 [(set (match_operand:V4HI 0 "register_operand" "=y,x,Yv")
1857 (vec_merge:V4HI
1858 (vec_duplicate:V4HI
1859 (match_operand:HI 2 "nonimmediate_operand" "rm,rm,rm"))
1860 (match_operand:V4HI 1 "register_operand" "0,0,Yv")
1861 (match_operand:SI 3 "const_int_operand")))]
1862 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1863 && (TARGET_SSE || TARGET_3DNOW_A)
1864 && ((unsigned) exact_log2 (INTVAL (operands[3]))
1865 < GET_MODE_NUNITS (V4HImode))"
1866 {
1867 operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])));
1868 switch (which_alternative)
1869 {
1870 case 2:
1871 if (MEM_P (operands[2]))
1872 return "vpinsrw\t{%3, %2, %1, %0|%0, %1, %2, %3}";
1873 else
1874 return "vpinsrw\t{%3, %k2, %1, %0|%0, %1, %k2, %3}";
1875 case 1:
1876 case 0:
1877 if (MEM_P (operands[2]))
1878 return "pinsrw\t{%3, %2, %0|%0, %2, %3}";
1879 else
1880 return "pinsrw\t{%3, %k2, %0|%0, %k2, %3}";
1881 default:
1882 gcc_unreachable ();
1883 }
1884 }
1885 [(set_attr "isa" "*,sse2_noavx,avx")
1886 (set_attr "mmx_isa" "native,*,*")
1887 (set_attr "type" "mmxcvt,sselog,sselog")
1888 (set_attr "length_immediate" "1")
1889 (set_attr "mode" "DI,TI,TI")])
1890
1891 (define_insn "*mmx_pinsrb"
1892 [(set (match_operand:V8QI 0 "register_operand" "=x,Yv")
1893 (vec_merge:V8QI
1894 (vec_duplicate:V8QI
1895 (match_operand:QI 2 "nonimmediate_operand" "rm,rm"))
1896 (match_operand:V8QI 1 "register_operand" "0,Yv")
1897 (match_operand:SI 3 "const_int_operand")))]
1898 "TARGET_MMX_WITH_SSE && TARGET_SSE4_1
1899 && ((unsigned) exact_log2 (INTVAL (operands[3]))
1900 < GET_MODE_NUNITS (V8QImode))"
1901 {
1902 operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])));
1903 switch (which_alternative)
1904 {
1905 case 1:
1906 if (MEM_P (operands[2]))
1907 return "vpinsrb\t{%3, %2, %1, %0|%0, %1, %2, %3}";
1908 else
1909 return "vpinsrb\t{%3, %k2, %1, %0|%0, %1, %k2, %3}";
1910 case 0:
1911 if (MEM_P (operands[2]))
1912 return "pinsrb\t{%3, %2, %0|%0, %2, %3}";
1913 else
1914 return "pinsrb\t{%3, %k2, %0|%0, %k2, %3}";
1915 default:
1916 gcc_unreachable ();
1917 }
1918 }
1919 [(set_attr "isa" "noavx,avx")
1920 (set_attr "type" "sselog")
1921 (set_attr "prefix_data16" "1")
1922 (set_attr "prefix_extra" "1")
1923 (set_attr "length_immediate" "1")
1924 (set_attr "prefix" "orig,vex")
1925 (set_attr "mode" "TI")])
1926
1927 (define_insn "*mmx_pextrw"
1928 [(set (match_operand:HI 0 "register_sse4nonimm_operand" "=r,r,m")
1929 (vec_select:HI
1930 (match_operand:V4HI 1 "register_operand" "y,Yv,Yv")
1931 (parallel [(match_operand:SI 2 "const_0_to_3_operand" "n,n,n")])))]
1932 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1933 && (TARGET_SSE || TARGET_3DNOW_A)"
1934 "@
1935 pextrw\t{%2, %1, %k0|%k0, %1, %2}
1936 %vpextrw\t{%2, %1, %k0|%k0, %1, %2}
1937 %vpextrw\t{%2, %1, %0|%0, %1, %2}"
1938 [(set_attr "isa" "*,sse2,sse4")
1939 (set_attr "mmx_isa" "native,*,*")
1940 (set_attr "type" "mmxcvt,sselog1,sselog1")
1941 (set_attr "length_immediate" "1")
1942 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
1943 (set_attr "mode" "DI,TI,TI")])
1944
1945 (define_insn "*mmx_pextrw_zext"
1946 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
1947 (zero_extend:SWI48
1948 (vec_select:HI
1949 (match_operand:V4HI 1 "register_operand" "y,Yv")
1950 (parallel [(match_operand:SI 2 "const_0_to_3_operand" "n,n")]))))]
1951 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1952 && (TARGET_SSE || TARGET_3DNOW_A)"
1953 "@
1954 pextrw\t{%2, %1, %k0|%k0, %1, %2}
1955 %vpextrw\t{%2, %1, %k0|%k0, %1, %2}"
1956 [(set_attr "isa" "*,sse2")
1957 (set_attr "mmx_isa" "native,*")
1958 (set_attr "type" "mmxcvt,sselog1")
1959 (set_attr "length_immediate" "1")
1960 (set_attr "prefix" "orig,maybe_vex")
1961 (set_attr "mode" "DI,TI")])
1962
1963 (define_insn "*mmx_pextrb"
1964 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,m")
1965 (vec_select:QI
1966 (match_operand:V8QI 1 "register_operand" "Yv,Yv")
1967 (parallel [(match_operand:SI 2 "const_0_to_7_operand" "n,n")])))]
1968 "TARGET_MMX_WITH_SSE && TARGET_SSE4_1"
1969 "@
1970 %vpextrb\t{%2, %1, %k0|%k0, %1, %2}
1971 %vpextrb\t{%2, %1, %0|%0, %1, %2}"
1972 [(set_attr "type" "sselog1")
1973 (set_attr "prefix_data16" "1")
1974 (set_attr "prefix_extra" "1")
1975 (set_attr "length_immediate" "1")
1976 (set_attr "prefix" "maybe_vex")
1977 (set_attr "mode" "TI")])
1978
1979 (define_insn "*mmx_pextrb_zext"
1980 [(set (match_operand:SWI248 0 "register_operand" "=r")
1981 (zero_extend:SWI248
1982 (vec_select:QI
1983 (match_operand:V8QI 1 "register_operand" "Yv")
1984 (parallel [(match_operand:SI 2 "const_0_to_7_operand" "n")]))))]
1985 "TARGET_MMX_WITH_SSE && TARGET_SSE4_1"
1986 "%vpextrb\t{%2, %1, %k0|%k0, %1, %2}"
1987 [(set_attr "type" "sselog1")
1988 (set_attr "prefix_data16" "1")
1989 (set_attr "prefix_extra" "1")
1990 (set_attr "length_immediate" "1")
1991 (set_attr "prefix" "maybe_vex")
1992 (set_attr "mode" "TI")])
1993
1994 (define_expand "mmx_pshufw"
1995 [(match_operand:V4HI 0 "register_operand")
1996 (match_operand:V4HI 1 "register_mmxmem_operand")
1997 (match_operand:SI 2 "const_int_operand")]
1998 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1999 && (TARGET_SSE || TARGET_3DNOW_A)"
2000 {
2001 int mask = INTVAL (operands[2]);
2002 emit_insn (gen_mmx_pshufw_1 (operands[0], operands[1],
2003 GEN_INT ((mask >> 0) & 3),
2004 GEN_INT ((mask >> 2) & 3),
2005 GEN_INT ((mask >> 4) & 3),
2006 GEN_INT ((mask >> 6) & 3)));
2007 DONE;
2008 })
2009
2010 (define_insn "mmx_pshufw_1"
2011 [(set (match_operand:V4HI 0 "register_operand" "=y,xYw")
2012 (vec_select:V4HI
2013 (match_operand:V4HI 1 "register_mmxmem_operand" "ym,xYw")
2014 (parallel [(match_operand 2 "const_0_to_3_operand")
2015 (match_operand 3 "const_0_to_3_operand")
2016 (match_operand 4 "const_0_to_3_operand")
2017 (match_operand 5 "const_0_to_3_operand")])))]
2018 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
2019 && (TARGET_SSE || TARGET_3DNOW_A)"
2020 {
2021 int mask = 0;
2022 mask |= INTVAL (operands[2]) << 0;
2023 mask |= INTVAL (operands[3]) << 2;
2024 mask |= INTVAL (operands[4]) << 4;
2025 mask |= INTVAL (operands[5]) << 6;
2026 operands[2] = GEN_INT (mask);
2027
2028 switch (which_alternative)
2029 {
2030 case 0:
2031 return "pshufw\t{%2, %1, %0|%0, %1, %2}";
2032 case 1:
2033 return "%vpshuflw\t{%2, %1, %0|%0, %1, %2}";
2034 default:
2035 gcc_unreachable ();
2036 }
2037 }
2038 [(set_attr "isa" "*,sse2")
2039 (set_attr "mmx_isa" "native,*")
2040 (set_attr "type" "mmxcvt,sselog1")
2041 (set_attr "length_immediate" "1")
2042 (set_attr "mode" "DI,TI")])
2043
2044 (define_insn "*mmx_pshufd_1"
2045 [(set (match_operand:V2SI 0 "register_operand" "=Yv")
2046 (vec_select:V2SI
2047 (match_operand:V2SI 1 "register_operand" "Yv")
2048 (parallel [(match_operand 2 "const_0_to_1_operand")
2049 (match_operand 3 "const_0_to_1_operand")])))]
2050 "TARGET_MMX_WITH_SSE"
2051 {
2052 int mask = 0;
2053 mask |= INTVAL (operands[2]) << 0;
2054 mask |= INTVAL (operands[3]) << 2;
2055 mask |= 2 << 4;
2056 mask |= 3 << 6;
2057 operands[2] = GEN_INT (mask);
2058
2059 return "%vpshufd\t{%2, %1, %0|%0, %1, %2}";
2060 }
2061 [(set_attr "type" "sselog1")
2062 (set_attr "prefix_data16" "1")
2063 (set_attr "length_immediate" "1")
2064 (set_attr "mode" "TI")])
2065
2066 (define_insn "mmx_pswapdv2si2"
2067 [(set (match_operand:V2SI 0 "register_operand" "=y,Yv")
2068 (vec_select:V2SI
2069 (match_operand:V2SI 1 "register_mmxmem_operand" "ym,Yv")
2070 (parallel [(const_int 1) (const_int 0)])))]
2071 "TARGET_3DNOW_A"
2072 "@
2073 pswapd\t{%1, %0|%0, %1}
2074 %vpshufd\t{$0xe1, %1, %0|%0, %1, 0xe1}";
2075 [(set_attr "isa" "*,sse2")
2076 (set_attr "mmx_isa" "native,*")
2077 (set_attr "type" "mmxcvt,sselog1")
2078 (set_attr "prefix_extra" "1,*")
2079 (set_attr "prefix_data16" "*,1")
2080 (set_attr "length_immediate" "*,1")
2081 (set_attr "mode" "DI,TI")])
2082
2083 (define_insn "*vec_dupv4hi"
2084 [(set (match_operand:V4HI 0 "register_operand" "=y,xYw")
2085 (vec_duplicate:V4HI
2086 (truncate:HI
2087 (match_operand:SI 1 "register_operand" "0,xYw"))))]
2088 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
2089 && (TARGET_SSE || TARGET_3DNOW_A)"
2090 "@
2091 pshufw\t{$0, %0, %0|%0, %0, 0}
2092 %vpshuflw\t{$0, %1, %0|%0, %1, 0}"
2093 [(set_attr "isa" "*,sse2")
2094 (set_attr "mmx_isa" "native,*")
2095 (set_attr "type" "mmxcvt,sselog1")
2096 (set_attr "length_immediate" "1")
2097 (set_attr "mode" "DI,TI")])
2098
2099
2100 (define_insn "*vec_dupv2si"
2101 [(set (match_operand:V2SI 0 "register_operand" "=y,Yv")
2102 (vec_duplicate:V2SI
2103 (match_operand:SI 1 "register_operand" "0,Yv")))]
2104 "TARGET_MMX || TARGET_MMX_WITH_SSE"
2105 "@
2106 punpckldq\t%0, %0
2107 %vpshufd\t{$0xe0, %1, %0|%0, %1, 0xe0}"
2108 [(set_attr "isa" "*,sse2")
2109 (set_attr "mmx_isa" "native,*")
2110 (set_attr "type" "mmxcvt,sselog1")
2111 (set_attr "prefix_data16" "*,1")
2112 (set_attr "length_immediate" "*,1")
2113 (set_attr "mode" "DI,TI")])
2114
2115 (define_insn "*mmx_concatv2si"
2116 [(set (match_operand:V2SI 0 "register_operand" "=y,y")
2117 (vec_concat:V2SI
2118 (match_operand:SI 1 "nonimmediate_operand" " 0,rm")
2119 (match_operand:SI 2 "nonimm_or_0_operand" "ym,C")))]
2120 "TARGET_MMX && !TARGET_SSE"
2121 "@
2122 punpckldq\t{%2, %0|%0, %2}
2123 movd\t{%1, %0|%0, %1}"
2124 [(set_attr "type" "mmxcvt,mmxmov")
2125 (set_attr "mode" "DI")])
2126
2127 (define_expand "vec_setv2si"
2128 [(match_operand:V2SI 0 "register_operand")
2129 (match_operand:SI 1 "register_operand")
2130 (match_operand 2 "const_int_operand")]
2131 "TARGET_MMX || TARGET_MMX_WITH_SSE"
2132 {
2133 ix86_expand_vector_set (TARGET_MMX_WITH_SSE, operands[0], operands[1],
2134 INTVAL (operands[2]));
2135 DONE;
2136 })
2137
2138 ;; Avoid combining registers from different units in a single alternative,
2139 ;; see comment above inline_secondary_memory_needed function in i386.c
2140 (define_insn_and_split "*vec_extractv2si_0"
2141 [(set (match_operand:SI 0 "nonimmediate_operand" "=x,m,y, m,r,r")
2142 (vec_select:SI
2143 (match_operand:V2SI 1 "nonimmediate_operand" "xm,x,ym,y,m,x")
2144 (parallel [(const_int 0)])))]
2145 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
2146 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2147 "#"
2148 "&& reload_completed"
2149 [(set (match_dup 0) (match_dup 1))]
2150 "operands[1] = gen_lowpart (SImode, operands[1]);"
2151 [(set_attr "isa" "*,*,*,*,*,sse2")
2152 (set_attr "mmx_isa" "*,*,native,native,*,*")
2153 (set (attr "preferred_for_speed")
2154 (cond [(eq_attr "alternative" "5")
2155 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2156 ]
2157 (symbol_ref "true")))])
2158
2159 (define_insn "*vec_extractv2si_0_zext_sse4"
2160 [(set (match_operand:DI 0 "register_operand" "=r,x")
2161 (zero_extend:DI
2162 (vec_select:SI
2163 (match_operand:V2SI 1 "register_operand" "x,x")
2164 (parallel [(const_int 0)]))))]
2165 "(TARGET_MMX || TARGET_MMX_WITH_SSE) && TARGET_SSE4_1"
2166 "#"
2167 [(set_attr "isa" "x64,*")
2168 (set (attr "preferred_for_speed")
2169 (cond [(eq_attr "alternative" "0")
2170 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2171 ]
2172 (symbol_ref "true")))])
2173
2174 (define_insn "*vec_extractv2si_0_zext"
2175 [(set (match_operand:DI 0 "register_operand" "=r")
2176 (zero_extend:DI
2177 (vec_select:SI
2178 (match_operand:V2SI 1 "register_operand" "x")
2179 (parallel [(const_int 0)]))))]
2180 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
2181 && TARGET_64BIT && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_FROM_VEC"
2182 "#")
2183
2184 (define_split
2185 [(set (match_operand:DI 0 "register_operand")
2186 (zero_extend:DI
2187 (vec_select:SI
2188 (match_operand:V2SI 1 "register_operand")
2189 (parallel [(const_int 0)]))))]
2190 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
2191 && TARGET_SSE2 && reload_completed"
2192 [(set (match_dup 0) (zero_extend:DI (match_dup 1)))]
2193 "operands[1] = gen_lowpart (SImode, operands[1]);")
2194
2195 ;; Avoid combining registers from different units in a single alternative,
2196 ;; see comment above inline_secondary_memory_needed function in i386.c
2197 (define_insn "*vec_extractv2si_1"
2198 [(set (match_operand:SI 0 "nonimmediate_operand" "=y,rm,x,x,y,x,r")
2199 (vec_select:SI
2200 (match_operand:V2SI 1 "nonimmediate_operand" " 0,x ,x,0,o,o,o")
2201 (parallel [(const_int 1)])))]
2202 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
2203 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2204 "@
2205 punpckhdq\t%0, %0
2206 %vpextrd\t{$1, %1, %0|%0, %1, 1}
2207 %vpshufd\t{$0xe5, %1, %0|%0, %1, 0xe5}
2208 shufps\t{$0xe5, %0, %0|%0, %0, 0xe5}
2209 #
2210 #
2211 #"
2212 [(set_attr "isa" "*,sse4,sse2,noavx,*,*,*")
2213 (set_attr "mmx_isa" "native,*,*,*,native,*,*")
2214 (set_attr "type" "mmxcvt,ssemov,sseshuf1,sseshuf1,mmxmov,ssemov,imov")
2215 (set (attr "length_immediate")
2216 (if_then_else (eq_attr "alternative" "1,2,3")
2217 (const_string "1")
2218 (const_string "*")))
2219 (set_attr "prefix" "orig,maybe_vex,maybe_vex,orig,orig,orig,orig")
2220 (set_attr "mode" "DI,TI,TI,V4SF,SI,SI,SI")])
2221
2222 (define_split
2223 [(set (match_operand:SI 0 "register_operand")
2224 (vec_select:SI
2225 (match_operand:V2SI 1 "memory_operand")
2226 (parallel [(const_int 1)])))]
2227 "(TARGET_MMX || TARGET_MMX_WITH_SSE) && reload_completed"
2228 [(set (match_dup 0) (match_dup 1))]
2229 "operands[1] = adjust_address (operands[1], SImode, 4);")
2230
2231 (define_insn "*vec_extractv2si_1_zext"
2232 [(set (match_operand:DI 0 "register_operand" "=r")
2233 (zero_extend:DI
2234 (vec_select:SI
2235 (match_operand:V2SI 1 "register_operand" "x")
2236 (parallel [(const_int 1)]))))]
2237 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
2238 && TARGET_64BIT && TARGET_SSE4_1"
2239 "%vpextrd\t{$1, %1, %k0|%k0, %1, 1}"
2240 [(set_attr "type" "sselog1")
2241 (set_attr "prefix_extra" "1")
2242 (set_attr "length_immediate" "1")
2243 (set_attr "prefix" "maybe_vex")
2244 (set_attr "mode" "TI")])
2245
2246 (define_insn_and_split "*vec_extractv2si_zext_mem"
2247 [(set (match_operand:DI 0 "register_operand" "=y,x,r")
2248 (zero_extend:DI
2249 (vec_select:SI
2250 (match_operand:V2SI 1 "memory_operand" "o,o,o")
2251 (parallel [(match_operand:SI 2 "const_0_to_1_operand")]))))]
2252 "(TARGET_MMX || TARGET_MMX_WITH_SSE) && TARGET_64BIT"
2253 "#"
2254 "&& reload_completed"
2255 [(set (match_dup 0) (zero_extend:DI (match_dup 1)))]
2256 {
2257 operands[1] = adjust_address (operands[1], SImode, INTVAL (operands[2]) * 4);
2258 }
2259 [(set_attr "isa" "*,sse2,*")
2260 (set_attr "mmx_isa" "native,*,*")])
2261
2262 (define_expand "vec_extractv2sisi"
2263 [(match_operand:SI 0 "register_operand")
2264 (match_operand:V2SI 1 "register_operand")
2265 (match_operand 2 "const_int_operand")]
2266 "TARGET_MMX || TARGET_MMX_WITH_SSE"
2267 {
2268 ix86_expand_vector_extract (TARGET_MMX_WITH_SSE, operands[0],
2269 operands[1], INTVAL (operands[2]));
2270 DONE;
2271 })
2272
2273 (define_expand "vec_initv2sisi"
2274 [(match_operand:V2SI 0 "register_operand")
2275 (match_operand 1)]
2276 "(TARGET_MMX || TARGET_MMX_WITH_SSE) && TARGET_SSE"
2277 {
2278 ix86_expand_vector_init (TARGET_MMX_WITH_SSE, operands[0],
2279 operands[1]);
2280 DONE;
2281 })
2282
2283 (define_expand "vec_setv4hi"
2284 [(match_operand:V4HI 0 "register_operand")
2285 (match_operand:HI 1 "register_operand")
2286 (match_operand 2 "const_int_operand")]
2287 "TARGET_MMX || TARGET_MMX_WITH_SSE"
2288 {
2289 ix86_expand_vector_set (TARGET_MMX_WITH_SSE, operands[0], operands[1],
2290 INTVAL (operands[2]));
2291 DONE;
2292 })
2293
2294 (define_expand "vec_extractv4hihi"
2295 [(match_operand:HI 0 "register_operand")
2296 (match_operand:V4HI 1 "register_operand")
2297 (match_operand 2 "const_int_operand")]
2298 "TARGET_MMX || TARGET_MMX_WITH_SSE"
2299 {
2300 ix86_expand_vector_extract (TARGET_MMX_WITH_SSE, operands[0],
2301 operands[1], INTVAL (operands[2]));
2302 DONE;
2303 })
2304
2305 (define_expand "vec_initv4hihi"
2306 [(match_operand:V4HI 0 "register_operand")
2307 (match_operand 1)]
2308 "(TARGET_MMX || TARGET_MMX_WITH_SSE) && TARGET_SSE"
2309 {
2310 ix86_expand_vector_init (TARGET_MMX_WITH_SSE, operands[0],
2311 operands[1]);
2312 DONE;
2313 })
2314
2315 (define_expand "vec_setv8qi"
2316 [(match_operand:V8QI 0 "register_operand")
2317 (match_operand:QI 1 "register_operand")
2318 (match_operand 2 "const_int_operand")]
2319 "TARGET_MMX || TARGET_MMX_WITH_SSE"
2320 {
2321 ix86_expand_vector_set (TARGET_MMX_WITH_SSE, operands[0], operands[1],
2322 INTVAL (operands[2]));
2323 DONE;
2324 })
2325
2326 (define_expand "vec_extractv8qiqi"
2327 [(match_operand:QI 0 "register_operand")
2328 (match_operand:V8QI 1 "register_operand")
2329 (match_operand 2 "const_int_operand")]
2330 "TARGET_MMX || TARGET_MMX_WITH_SSE"
2331 {
2332 ix86_expand_vector_extract (TARGET_MMX_WITH_SSE, operands[0],
2333 operands[1], INTVAL (operands[2]));
2334 DONE;
2335 })
2336
2337 (define_expand "vec_initv8qiqi"
2338 [(match_operand:V8QI 0 "register_operand")
2339 (match_operand 1)]
2340 "(TARGET_MMX || TARGET_MMX_WITH_SSE) && TARGET_SSE"
2341 {
2342 ix86_expand_vector_init (TARGET_MMX_WITH_SSE, operands[0],
2343 operands[1]);
2344 DONE;
2345 })
2346
2347 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2348 ;;
2349 ;; Miscellaneous
2350 ;;
2351 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2352
2353 (define_expand "mmx_uavg<mode>3"
2354 [(set (match_operand:MMXMODE12 0 "register_operand")
2355 (truncate:MMXMODE12
2356 (lshiftrt:<mmxdoublemode>
2357 (plus:<mmxdoublemode>
2358 (plus:<mmxdoublemode>
2359 (zero_extend:<mmxdoublemode>
2360 (match_operand:MMXMODE12 1 "register_mmxmem_operand"))
2361 (zero_extend:<mmxdoublemode>
2362 (match_operand:MMXMODE12 2 "register_mmxmem_operand")))
2363 (match_dup 3))
2364 (const_int 1))))]
2365 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
2366 && (TARGET_SSE || TARGET_3DNOW)"
2367 {
2368 operands[3] = CONST1_RTX(<mmxdoublemode>mode);
2369 ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
2370 })
2371
2372 (define_insn "*mmx_uavgv8qi3"
2373 [(set (match_operand:V8QI 0 "register_operand" "=y,x,Yv")
2374 (truncate:V8QI
2375 (lshiftrt:V8HI
2376 (plus:V8HI
2377 (plus:V8HI
2378 (zero_extend:V8HI
2379 (match_operand:V8QI 1 "register_mmxmem_operand" "%0,0,Yv"))
2380 (zero_extend:V8HI
2381 (match_operand:V8QI 2 "register_mmxmem_operand" "ym,x,Yv")))
2382 (const_vector:V8HI [(const_int 1) (const_int 1)
2383 (const_int 1) (const_int 1)
2384 (const_int 1) (const_int 1)
2385 (const_int 1) (const_int 1)]))
2386 (const_int 1))))]
2387 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
2388 && (TARGET_SSE || TARGET_3DNOW)
2389 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
2390 {
2391 switch (which_alternative)
2392 {
2393 case 2:
2394 return "vpavgb\t{%2, %1, %0|%0, %1, %2}";
2395 case 1:
2396 case 0:
2397 /* These two instructions have the same operation, but their encoding
2398 is different. Prefer the one that is de facto standard. */
2399 if (TARGET_SSE || TARGET_3DNOW_A)
2400 return "pavgb\t{%2, %0|%0, %2}";
2401 else
2402 return "pavgusb\t{%2, %0|%0, %2}";
2403 default:
2404 gcc_unreachable ();
2405 }
2406 }
2407 [(set_attr "isa" "*,sse2_noavx,avx")
2408 (set_attr "mmx_isa" "native,*,*")
2409 (set_attr "type" "mmxshft,sseiadd,sseiadd")
2410 (set (attr "prefix_extra")
2411 (if_then_else
2412 (not (ior (match_test "TARGET_SSE")
2413 (match_test "TARGET_3DNOW_A")))
2414 (const_string "1")
2415 (const_string "*")))
2416 (set_attr "mode" "DI,TI,TI")])
2417
2418 (define_insn "*mmx_uavgv4hi3"
2419 [(set (match_operand:V4HI 0 "register_operand" "=y,x,Yv")
2420 (truncate:V4HI
2421 (lshiftrt:V4SI
2422 (plus:V4SI
2423 (plus:V4SI
2424 (zero_extend:V4SI
2425 (match_operand:V4HI 1 "register_mmxmem_operand" "%0,0,Yv"))
2426 (zero_extend:V4SI
2427 (match_operand:V4HI 2 "register_mmxmem_operand" "ym,x,Yv")))
2428 (const_vector:V4SI [(const_int 1) (const_int 1)
2429 (const_int 1) (const_int 1)]))
2430 (const_int 1))))]
2431 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
2432 && (TARGET_SSE || TARGET_3DNOW_A)
2433 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
2434 "@
2435 pavgw\t{%2, %0|%0, %2}
2436 pavgw\t{%2, %0|%0, %2}
2437 vpavgw\t{%2, %1, %0|%0, %1, %2}"
2438 [(set_attr "isa" "*,sse2_noavx,avx")
2439 (set_attr "mmx_isa" "native,*,*")
2440 (set_attr "type" "mmxshft,sseiadd,sseiadd")
2441 (set_attr "mode" "DI,TI,TI")])
2442
2443 (define_expand "uavg<mode>3_ceil"
2444 [(set (match_operand:MMXMODE12 0 "register_operand")
2445 (truncate:MMXMODE12
2446 (lshiftrt:<mmxdoublemode>
2447 (plus:<mmxdoublemode>
2448 (plus:<mmxdoublemode>
2449 (zero_extend:<mmxdoublemode>
2450 (match_operand:MMXMODE12 1 "register_operand"))
2451 (zero_extend:<mmxdoublemode>
2452 (match_operand:MMXMODE12 2 "register_operand")))
2453 (match_dup 3))
2454 (const_int 1))))]
2455 "TARGET_MMX_WITH_SSE"
2456 {
2457 operands[3] = CONST1_RTX(<mmxdoublemode>mode);
2458 ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
2459 })
2460
2461 (define_insn "mmx_psadbw"
2462 [(set (match_operand:V1DI 0 "register_operand" "=y,x,Yv")
2463 (unspec:V1DI [(match_operand:V8QI 1 "register_operand" "0,0,Yv")
2464 (match_operand:V8QI 2 "register_mmxmem_operand" "ym,x,Yv")]
2465 UNSPEC_PSADBW))]
2466 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
2467 && (TARGET_SSE || TARGET_3DNOW_A)"
2468 "@
2469 psadbw\t{%2, %0|%0, %2}
2470 psadbw\t{%2, %0|%0, %2}
2471 vpsadbw\t{%2, %1, %0|%0, %1, %2}"
2472 [(set_attr "isa" "*,sse2_noavx,avx")
2473 (set_attr "mmx_isa" "native,*,*")
2474 (set_attr "type" "mmxshft,sseiadd,sseiadd")
2475 (set_attr "mode" "DI,TI,TI")])
2476
2477 (define_expand "reduc_plus_scal_v8qi"
2478 [(plus:V8QI
2479 (match_operand:QI 0 "register_operand")
2480 (match_operand:V8QI 1 "register_operand"))]
2481 "TARGET_MMX_WITH_SSE"
2482 {
2483 rtx tmp = gen_reg_rtx (V8QImode);
2484 emit_move_insn (tmp, CONST0_RTX (V8QImode));
2485 rtx tmp2 = gen_reg_rtx (V1DImode);
2486 emit_insn (gen_mmx_psadbw (tmp2, operands[1], tmp));
2487 tmp2 = gen_lowpart (V8QImode, tmp2);
2488 emit_insn (gen_vec_extractv8qiqi (operands[0], tmp2, const0_rtx));
2489 DONE;
2490 })
2491
2492 (define_expand "usadv8qi"
2493 [(match_operand:V2SI 0 "register_operand")
2494 (match_operand:V8QI 1 "register_operand")
2495 (match_operand:V8QI 2 "register_operand")
2496 (match_operand:V2SI 3 "register_operand")]
2497 "TARGET_MMX_WITH_SSE"
2498 {
2499 rtx t1 = gen_reg_rtx (V1DImode);
2500 rtx t2 = gen_reg_rtx (V2SImode);
2501 emit_insn (gen_mmx_psadbw (t1, operands[1], operands[2]));
2502 convert_move (t2, t1, 0);
2503 emit_insn (gen_addv2si3 (operands[0], t2, operands[3]));
2504 DONE;
2505 })
2506
2507 (define_insn_and_split "mmx_pmovmskb"
2508 [(set (match_operand:SI 0 "register_operand" "=r,r")
2509 (unspec:SI [(match_operand:V8QI 1 "register_operand" "y,x")]
2510 UNSPEC_MOVMSK))]
2511 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
2512 && (TARGET_SSE || TARGET_3DNOW_A)"
2513 "@
2514 pmovmskb\t{%1, %0|%0, %1}
2515 #"
2516 "TARGET_SSE2 && reload_completed
2517 && SSE_REGNO_P (REGNO (operands[1]))"
2518 [(set (match_dup 0)
2519 (unspec:SI [(match_dup 1)] UNSPEC_MOVMSK))
2520 (set (match_dup 0)
2521 (zero_extend:SI (match_dup 2)))]
2522 {
2523 /* Generate SSE pmovmskb and zero-extend from QImode to SImode. */
2524 operands[1] = lowpart_subreg (V16QImode, operands[1],
2525 GET_MODE (operands[1]));
2526 operands[2] = lowpart_subreg (QImode, operands[0],
2527 GET_MODE (operands[0]));
2528 }
2529 [(set_attr "mmx_isa" "native,sse")
2530 (set_attr "type" "mmxcvt,ssemov")
2531 (set_attr "mode" "DI,TI")])
2532
2533 (define_expand "mmx_maskmovq"
2534 [(set (match_operand:V8QI 0 "memory_operand")
2535 (unspec:V8QI [(match_operand:V8QI 1 "register_operand")
2536 (match_operand:V8QI 2 "register_operand")
2537 (match_dup 0)]
2538 UNSPEC_MASKMOV))]
2539 "TARGET_SSE || TARGET_3DNOW_A")
2540
2541 (define_insn "*mmx_maskmovq"
2542 [(set (mem:V8QI (match_operand:P 0 "register_operand" "D"))
2543 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
2544 (match_operand:V8QI 2 "register_operand" "y")
2545 (mem:V8QI (match_dup 0))]
2546 UNSPEC_MASKMOV))]
2547 "TARGET_SSE || TARGET_3DNOW_A"
2548 ;; @@@ check ordering of operands in intel/nonintel syntax
2549 "maskmovq\t{%2, %1|%1, %2}"
2550 [(set_attr "type" "mmxcvt")
2551 (set_attr "znver1_decode" "vector")
2552 (set_attr "mode" "DI")])
2553
2554 (define_int_iterator EMMS
2555 [(UNSPECV_EMMS "TARGET_MMX")
2556 (UNSPECV_FEMMS "TARGET_3DNOW")])
2557
2558 (define_int_attr emms
2559 [(UNSPECV_EMMS "emms")
2560 (UNSPECV_FEMMS "femms")])
2561
2562 (define_expand "mmx_<emms>"
2563 [(parallel
2564 [(unspec_volatile [(const_int 0)] EMMS)
2565 (clobber (reg:XF ST0_REG))
2566 (clobber (reg:XF ST1_REG))
2567 (clobber (reg:XF ST2_REG))
2568 (clobber (reg:XF ST3_REG))
2569 (clobber (reg:XF ST4_REG))
2570 (clobber (reg:XF ST5_REG))
2571 (clobber (reg:XF ST6_REG))
2572 (clobber (reg:XF ST7_REG))
2573 (clobber (reg:DI MM0_REG))
2574 (clobber (reg:DI MM1_REG))
2575 (clobber (reg:DI MM2_REG))
2576 (clobber (reg:DI MM3_REG))
2577 (clobber (reg:DI MM4_REG))
2578 (clobber (reg:DI MM5_REG))
2579 (clobber (reg:DI MM6_REG))
2580 (clobber (reg:DI MM7_REG))])]
2581 "TARGET_MMX || TARGET_MMX_WITH_SSE"
2582 {
2583 if (!TARGET_MMX)
2584 {
2585 emit_insn (gen_nop ());
2586 DONE;
2587 }
2588 })
2589
2590 (define_insn "*mmx_<emms>"
2591 [(unspec_volatile [(const_int 0)] EMMS)
2592 (clobber (reg:XF ST0_REG))
2593 (clobber (reg:XF ST1_REG))
2594 (clobber (reg:XF ST2_REG))
2595 (clobber (reg:XF ST3_REG))
2596 (clobber (reg:XF ST4_REG))
2597 (clobber (reg:XF ST5_REG))
2598 (clobber (reg:XF ST6_REG))
2599 (clobber (reg:XF ST7_REG))
2600 (clobber (reg:DI MM0_REG))
2601 (clobber (reg:DI MM1_REG))
2602 (clobber (reg:DI MM2_REG))
2603 (clobber (reg:DI MM3_REG))
2604 (clobber (reg:DI MM4_REG))
2605 (clobber (reg:DI MM5_REG))
2606 (clobber (reg:DI MM6_REG))
2607 (clobber (reg:DI MM7_REG))]
2608 ""
2609 "<emms>"
2610 [(set_attr "type" "mmx")
2611 (set_attr "modrm" "0")
2612 (set_attr "memory" "none")])